VirtualBox

Changeset 16980 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Feb 20, 2009 8:59:56 PM (16 years ago)
Author:
vboxsync
Message:

Additions/x11/vboxvideo: mouse pointer handling cleanup

Location:
trunk/src/VBox/Additions/x11/xgraphics
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/xgraphics/vboxutils.c

    r16701 r16980  
    133133**************************************************************************/
    134134
     135/* This is called by the X server every time it loads a new cursor to see
     136 * whether our "cursor hardware" can handle the cursor.  This provides us with
     137 * a mechanism (the only one!) to switch back from a software to a hardware
     138 * cursor. */
    135139static Bool
    136140vbox_host_uses_hwcursor(ScrnInfoPtr pScrn)
    137141{
    138     Bool rc = FALSE;
     142    Bool rc = TRUE;
    139143    uint32_t fFeatures = 0;
    140 
    141     TRACE_ENTRY();
    142     int vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
    143     if (RT_FAILURE(vrc))
    144         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    145                  "Unable to determine whether the virtual machine supports mouse pointer integration - request initialization failed with return code %d\n", vrc);
    146     else
    147     {
    148         if (   !(fFeatures & VBOXGUEST_MOUSE_HOST_CANNOT_HWPOINTER)
    149             && (fFeatures & VBOXGUEST_MOUSE_GUEST_CAN_ABSOLUTE)
    150             && (fFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE)
     144    VBOXPtr pVBox = pScrn->driverPrivate;
     145
     146    TRACE_ENTRY();
     147    /* We may want to force the use of a software cursor.  Currently this is
     148     * needed if the guest uses a large virtual resolution, as in this case
     149     * the host and guest tend to disagree about the pointer location. */
     150    if (pVBox->forceSWCursor)
     151        rc = FALSE;
     152    /* Query information about mouse integration from the host. */
     153    if (rc) {
     154        int vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
     155        if (RT_FAILURE(vrc)) {
     156            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
     157                     "Unable to determine whether the virtual machine supports mouse pointer integration - request initialization failed with return code %d\n", vrc);
     158            rc = FALSE;
     159        }
     160    }
     161    /* If we got the information from the host then make sure the host wants
     162     * to draw the pointer. */
     163    if (rc)
     164    {
     165        if (   (fFeatures & VBOXGUEST_MOUSE_HOST_CANNOT_HWPOINTER)
     166            || !(fFeatures & VBOXGUEST_MOUSE_GUEST_CAN_ABSOLUTE)
     167            ||!(fFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE)
    151168           )
    152             rc = TRUE;
     169            rc = FALSE;
    153170    }
    154171    TRACE_LOG("rc=%s\n", BOOL_STR(rc));
    155172    return rc;
    156 }
    157 
    158 /**
    159  * This function checks whether the X server agrees with us about whether
    160  * to use a host or a guest-drawn cursor and gives it a nudge if it doesn't.
    161  * Disabling and re-enabling framebuffer access was one of the few
    162  * reliable (although not particularly nice) methods I could find to
    163  * force the server to recheck whether to use a hardware or a software
    164  * cursor.
    165  */
    166 static void
    167 vboxRecheckHWCursor(ScrnInfoPtr pScrn)
    168 {
    169     int vrc;
    170     uint32_t fFeatures;
    171     VBOXPtr pVBox = pScrn->driverPrivate;
    172 
    173     TRACE_ENTRY();
    174     /* Check whether we are using the hardware cursor or not, and whether this
    175        has changed since the last time we checked. */
    176     vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
    177     if (!!(fFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE) != pVBox->usingHWCursor)
    178     {
    179         pVBox->usingHWCursor = !!(fFeatures & VBOXGUEST_MOUSE_HOST_CAN_ABSOLUTE);
    180         /* This triggers a cursor image reload */
    181         if (pVBox->accessEnabled)
    182         {
    183             pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
    184             pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
    185         }
    186     }
    187     TRACE_EXIT();
    188173}
    189174
     
    477462            pVBox->pCurs = NULL;
    478463            pVBox->pointerHeaderSize = size;
    479             pVBox->pointerOffscreen = FALSE;
    480464            pVBox->useVbva = vboxInitVbva(scrnIndex, pScreen, pVBox);
    481465            return TRUE;
     
    512496
    513497    TRACE_ENTRY();
    514     pVBox->reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE;
    515     rc = VbglR3SetPointerShapeReq(pVBox->reqp);
    516     if (RT_FAILURE(rc))
    517         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
     498    if (vbox_host_uses_hwcursor(pScrn)) {
     499        pVBox->reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE;
     500        rc = VbglR3SetPointerShapeReq(pVBox->reqp);
     501        if (RT_FAILURE(rc))
     502            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
     503    }
    518504}
    519505
     
    552538 * we only use this function to poll for whether we need to switch from a
    553539 * hardware to a software cursor (that is, whether the user has disabled
    554  * pointer integration).  Sadly we this doesn't work the other way round,
    555  * as the server updates the software cursor itself without calling us.
     540 * pointer integration).  Sadly this doesn't work the other way round,
     541 * as the server updates the software cursor itself without notifying us.
    556542 */
    557543static void
    558544vbox_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
    559545{
    560     vboxRecheckHWCursor(pScrn);
    561     /* don't disable the mouse cursor if we go out of our visible area
    562      * since the mouse cursor is drawn by the host anyway */
    563 #if 0
    564     if (   (x < 0 || x > pScrn->pScreen->width)
    565         || (y < 0 || y > pScrn->pScreen->height))
    566     {
    567         if (!pVBox->pointerOffscreen)
    568         {
    569             pVBox->pointerOffscreen = TRUE;
    570             vbox_vmm_hide_cursor(pScrn, pVBox);
    571         }
    572     }
    573     else
    574     {
    575         if (pVBox->pointerOffscreen)
    576         {
    577             pVBox->pointerOffscreen = FALSE;
    578             vbox_vmm_show_cursor(pScrn, pVBox);
    579         }
    580     }
    581 #endif
     546    VBOXPtr pVBox = pScrn->driverPrivate;
     547
     548    if (pVBox->accessEnabled && !vbox_host_uses_hwcursor(pScrn))
     549    {
     550        /* This triggers a cursor image reload, and before reloading, the X
     551         * server will check whether we can "handle" the new cursor "in
     552         * hardware".  We can use this check to force a switch to a software
     553         * cursor if we need to do so. */
     554        pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
     555        pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
     556    }
    582557}
    583558
     
    743718    reqp->xHot   = bitsp->xhot;
    744719    reqp->yHot   = bitsp->yhot;
    745     reqp->fFlags = VBOX_MOUSE_POINTER_SHAPE;
     720    reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
    746721    reqp->header.size = sizeRequest;
    747722
     
    824799    reqp->xHot   = bitsp->xhot;
    825800    reqp->yHot   = bitsp->yhot;
    826     reqp->fFlags = VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
     801    reqp->fFlags =   VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE
     802                   | VBOX_MOUSE_POINTER_ALPHA;
    827803    reqp->header.size = sizeRequest;
    828804
     
    876852    if (!pVBox->useDevice)
    877853        return FALSE;
    878     /* Initially assume we are using a hardware cursor, but this is
    879        updated every time the mouse moves anyway. */
    880     pVBox->usingHWCursor = TRUE;
    881854    pVBox->pCurs = pCurs = xf86CreateCursorInfoRec();
    882855    if (!pCurs)
     
    919892vboxEnableVbva(ScrnInfoPtr pScrn)
    920893{
    921     int rc;
     894    bool rc = TRUE;
    922895    int scrnIndex = pScrn->scrnIndex;
    923896    VBOXPtr pVBox = pScrn->driverPrivate;
     
    925898    TRACE_ENTRY();
    926899    if (pVBox->useVbva != TRUE)
    927         return FALSE;
    928     rc = VbglR3VideoAccelEnable(true);
    929     if (RT_FAILURE(rc))
    930     {
     900        rc = FALSE;
     901    if (rc && RT_FAILURE(VbglR3VideoAccelEnable(true)))
    931902        /* Request not accepted - disable for old hosts. */
    932903        xf86DrvMsg(scrnIndex, X_ERROR,
     
    934905                   "- the request to the virtual machine failed.  "
    935906                   "You may be running an old version of VirtualBox.\n");
    936         pVBox->useVbva = FALSE;
     907    pVBox->useVbva = rc;
     908    if (!rc)
    937909        VbglR3VideoAccelEnable(false);
    938         return FALSE;
    939     }
    940     return TRUE;
     910    return rc;
    941911}
    942912
  • trunk/src/VBox/Additions/x11/xgraphics/vboxutils_68.c

    r16701 r16980  
    484484        pVBox->pCurs = NULL;
    485485        pVBox->pointerHeaderSize = size;
    486         pVBox->pointerOffscreen = FALSE;
    487486        pVBox->useVbva = vboxInitVbva(scrnIndex, pScreen, pVBox);
    488487    } else {
     
    552551vbox_set_cursor_position (ScrnInfoPtr pScrn, int x, int y)
    553552{
    554     /* VBOXPtr pVBox = pScrn->driverPrivate; */
    555 
    556     /* TRACE_ENTRY (); */
    557 
    558     /* don't disable the mouse cursor if we go out of our visible area
    559      * since the mouse cursor is drawn by the host anyway */
    560 #if 0
    561     if (((x < 0) || (x > pScrn->pScreen->width))
    562         || ((y < 0) || (y > pScrn->pScreen->height))) {
    563         if (!pVBox->pointerOffscreen) {
    564             pVBox->pointerOffscreen = TRUE;
    565             vbox_vmm_hide_cursor (pScrn, pVBox);
    566         }
    567     }
    568     else {
    569         if (pVBox->pointerOffscreen) {
    570             pVBox->pointerOffscreen = FALSE;
    571             vbox_vmm_show_cursor (pScrn, pVBox);
    572         }
    573     }
    574 #endif
     553    (void) pScrn; (void) x; (void) y;
    575554}
    576555
  • trunk/src/VBox/Additions/x11/xgraphics/vboxvideo.h

    r16701 r16980  
    150150    size_t pointerHeaderSize;
    151151    size_t pointerSize;
    152     Bool pointerOffscreen;
    153     Bool usingHWCursor;
    154152    Bool useDevice;
     153    Bool forceSWCursor;
    155154    /** Are we currently switched to a virtual terminal?  If so, it is not
    156155     * safe to touch the hardware. */
  • trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_70.c

    r16973 r16980  
    863863VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
    864864{
    865     VBOXPtr pVBox;
    866 
    867865    int bpp = pScrn->depth == 24 ? 32 : 16;
    868866    int xRes = pMode->HDisplay;
     867    VBOXPtr pVBox = VBOXGetRec(pScrn);
     868
    869869    if (pScrn->virtualX * pScrn->virtualY * bpp / 8
    870870        >= pScrn->videoRam * 1024)
     
    884884        xRes = xRes - (xRes % 8);
    885885    }
    886     pVBox = VBOXGetRec(pScrn);
     886
     887    /* We force a software cursor if the guests virtual resolution is different
     888     * to it's actual resolution, as in this case host and guest will disagree
     889     * about the pointer position. */
     890    if (   (pScrn->virtualX - xRes >= 8)
     891        || (pScrn->virtualY - pMode->VDisplay >= 8))
     892        pVBox->forceSWCursor = TRUE;
     893    else
     894        pVBox->forceSWCursor = FALSE;
     895
    887896    pScrn->vtSema = TRUE;
    888897    /* Disable linear framebuffer mode before making changes to the resolution. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette