Panning is at odds with CRTC cursor confinement. This disables CRTC cursor
confinement as long as panning is enabled.

Fixes regression introduced in 56c90e29f04727c903bd0f084d23bf44eb1a0a11.

Signed-off-by: Rui Matos <[email protected]>
---
 hw/xfree86/modes/xf86RandR12.c |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

v3: Although this approach isn't semantically equivalent to the previous since
    it completely disables CRTC cursor confinement while panning is enabled I
    prefer it because it's shorter, cleaner and contained in a single file.

    Anyway, panning still keeps working as it did, though not benefiting from
    CRTC cursor confinement as it could. But, people using panning (are there
    any?) surely know what they're doing.

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 57b3b0e..426d8f4 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -60,6 +60,9 @@ typedef struct _xf86RandR12Info {
      * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
      */
     xf86EnterVTProc *orig_EnterVT;
+
+    Bool                         panning;
+    ConstrainCursorHarderProcPtr orig_ConstrainCursorHarder;
 } XF86RandRInfoRec, *XF86RandRInfoPtr;
 
 #ifdef RANDR_12_INTERFACE
@@ -74,6 +77,9 @@ static DevPrivateKey xf86RandR12Key;
 #define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
     dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
 
+#define PANNING_ENABLED(crtc)                                           \
+    ((crtc)->panningTotalArea.x2 > (crtc)->panningTotalArea.x1 ||       \
+     (crtc)->panningTotalArea.y2 > (crtc)->panningTotalArea.y1)
 
 static int
 xf86RandR12ModeRefresh (DisplayModePtr mode)
@@ -687,6 +693,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
     xf86CrtcConfigPtr  config = XF86_CRTC_CONFIG_PTR(pScrn);
     WindowPtr          pRoot = pScreen->root;
     PixmapPtr          pScrnPix;
+    Bool                panning = FALSE;
     Bool               ret = FALSE;
     int                 c;
 
@@ -708,8 +715,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
     /* Update panning information */
     for (c = 0; c < config->num_crtc; c++) {
        xf86CrtcPtr crtc = config->crtc[c];
-       if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
-           crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+       if (PANNING_ENABLED (crtc)) {
            if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
                crtc->panningTotalArea.x2 += width  - pScreen->width;
            if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
@@ -720,9 +726,12 @@ xf86RandR12ScreenSetSize (ScreenPtr        pScreen,
                crtc->panningTrackingArea.y2 += height - pScreen->height;
            xf86RandR13VerifyPanningArea (crtc, width, height);
            xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+            panning = TRUE;
        }
     }
 
+    randrp->panning = panning;
+
     pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
     pScreen->width = pScrnPix->drawable.width = width;
     pScreen->height = pScrnPix->drawable.height = height;
@@ -925,6 +934,7 @@ xf86RandR12CloseScreen (ScreenPtr pScreen)
     randrp = XF86RANDRINFO(pScreen);
 #if RANDR_12_INTERFACE
     xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT;
+    pScreen->ConstrainCursorHarder = randrp->orig_ConstrainCursorHarder;
 #endif
 
     free(randrp);
@@ -1226,6 +1236,7 @@ xf86RandR12CrtcSet (ScreenPtr         pScreen,
            }
            xf86RandR13VerifyPanningArea (crtc, pScreen->width, 
pScreen->height);
            xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+            randrp->panning = PANNING_ENABLED (crtc);
            /*
             * Save the last successful setting for EnterVT
             */
@@ -1650,6 +1661,7 @@ xf86RandR13SetPanning (ScreenPtr           pScreen,
 {
     XF86RandRInfoPtr   randrp  = XF86RANDRINFO(pScreen);
     xf86CrtcPtr                crtc = randr_crtc->devPrivate;
+    Bool                oldPanning = randrp->panning;
     BoxRec             oldTotalArea;
     BoxRec             oldTrackingArea;
     INT16              oldBorder[4];
@@ -1671,12 +1683,14 @@ xf86RandR13SetPanning (ScreenPtr           pScreen,
 
     if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
        xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+        randrp->panning = PANNING_ENABLED (crtc);
        return TRUE;
     } else {
        /* Restore old settings */
        memcpy (&crtc->panningTotalArea,    &oldTotalArea,    sizeof(BoxRec));
        memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
        memcpy (crtc->panningBorder,         oldBorder,       4*sizeof(INT16));
+        randrp->panning = oldPanning;
        return FALSE;
     }
 }
@@ -1761,6 +1775,21 @@ xf86RandR12EnterVT (int screen_index, int flags)
     return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and 
notify clients about changes */
 }
 
+static void
+xf86RandR13ConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, 
int *x, int *y)
+{
+    XF86RandRInfoPtr randrp = XF86RANDRINFO(screen);
+
+    if (randrp->panning)
+        return;
+
+    if (randrp->orig_ConstrainCursorHarder) {
+        screen->ConstrainCursorHarder = randrp->orig_ConstrainCursorHarder;
+        screen->ConstrainCursorHarder(dev, screen, mode, x, y);
+        screen->ConstrainCursorHarder = xf86RandR13ConstrainCursorHarder;
+    }
+}
+
 static Bool
 xf86RandR12Init12 (ScreenPtr pScreen)
 {
@@ -1789,6 +1818,10 @@ xf86RandR12Init12 (ScreenPtr pScreen)
     randrp->orig_EnterVT = pScrn->EnterVT;
     pScrn->EnterVT = xf86RandR12EnterVT;
 
+    randrp->panning = FALSE;
+    randrp->orig_ConstrainCursorHarder = pScreen->ConstrainCursorHarder;
+    pScreen->ConstrainCursorHarder = xf86RandR13ConstrainCursorHarder;
+
     if (!xf86RandR12CreateObjects12 (pScreen))
        return FALSE;
 
-- 
1.7.6

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to