xserver: Branch 'master' - 6 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Aug 18 13:13:57 PDT 2010


 dix/getevents.c                 |   21 ++++++++++++++++-----
 dix/window.c                    |    2 ++
 hw/xquartz/X11Application.m     |   28 +++++++++++++++++++++-------
 hw/xquartz/darwinEvents.c       |    4 ++--
 hw/xquartz/quartz.c             |    4 +++-
 hw/xquartz/xpr/xprEvent.c       |    2 +-
 hw/xquartz/xpr/xprFrame.c       |   10 ++++++++--
 miext/rootless/rootless.h       |    4 ++--
 miext/rootless/rootlessWindow.c |   12 +++++++++---
 9 files changed, 64 insertions(+), 23 deletions(-)

New commits:
commit fc091936e2bddbbab9c9a501edc5a5f08388617e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Aug 16 14:18:45 2010 +1000

    dix: copy the valuators passed into GPE/GKVE/GProxE.
    
    GPE and friends modify the valuators array passed in. Which means any driver
    using e.g. xf86PostButtonEventP(..., valuators) twice to emulate a button
    click will provide garbage data on the second run.
    
    This is currently affecting the wacom driver, xf86PostButtonEventP() with
    valuators is required to have input events with device-specific axis values.
    Passing the same valuators in twice, once with press, once with release,
    will see the valuators modified in the first call and garbage submitted in
    the next one.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index 20bcf7e..e5134d3 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -912,17 +912,19 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code)
 int
 GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
                           int key_code, int first_valuator,
-                          int num_valuators, int *valuators) {
+                          int num_valuators, int *valuators_in) {
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
     RawDeviceEvent *raw;
+    int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
         return 0;
 
     if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
+        num_valuators > MAX_VALUATORS ||
        (type != KeyPress && type != KeyRelease) ||
        (key_code < 8 || key_code > 255))
         return 0;
@@ -947,6 +949,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     events++;
     num_events++;
 
+    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+
     init_raw(pDev, raw, ms, type, key_code);
     set_raw_valuators(raw, first_valuator, num_valuators, valuators,
                       raw->valuators.data_raw);
@@ -1067,7 +1071,7 @@ transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
 int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
                  int flags, int first_valuator, int num_valuators,
-                 int *valuators) {
+                 int *valuators_in) {
     int num_events = 1;
     CARD32 ms;
     DeviceEvent *event;
@@ -1076,6 +1080,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         cx, cy; /* only screen coordinates */
     float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
     ScreenPtr scr = miPointerGetScreen(pDev);
+    int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
@@ -1084,6 +1089,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     ms = GetTimeInMillis(); /* before pointer update to help precision */
 
     if (!scr || !pDev->valuator || first_valuator < 0 ||
+        num_valuators > MAX_VALUATORS ||
         ((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
         (type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
         (type != MotionNotify && !pDev->button) ||
@@ -1097,6 +1103,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     events++;
     num_events++;
 
+    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+
     init_raw(pDev, raw, ms, type, buttons);
     set_raw_valuators(raw, first_valuator, num_valuators, valuators,
                       raw->valuators.data_raw);
@@ -1183,10 +1191,11 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
  */
 int
 GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
-                   int first_valuator, int num_valuators, int *valuators)
+                   int first_valuator, int num_valuators, int *valuators_in)
 {
     int num_events = 1;
     DeviceEvent *event;
+    int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
@@ -1202,7 +1211,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         num_valuators = 0;
 
     /* You fail. */
-    if (first_valuator < 0 ||
+    if (first_valuator < 0 || num_valuators > MAX_VALUATORS ||
         (num_valuators + first_valuator) > pDev->valuator->numAxes)
         return 0;
 
@@ -1212,8 +1221,10 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     init_event(pDev, event, GetTimeInMillis());
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
-    if (num_valuators)
+    if (num_valuators) {
+        memcpy(valuators, valuators_in, num_valuators * sizeof(int));
         clipValuators(pDev, first_valuator, num_valuators, valuators);
+    }
 
     set_valuators(pDev, event, first_valuator, num_valuators, valuators);
 
commit 6e3e559e9fa63069a10eb834a6dab9a4cfc140ee
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Aug 15 20:53:20 2010 -0700

    dix: reset pScreen->root to NULL when root window is deleted.
    
    From: Dave Airlie <airlied at linux.ie>
    
    We were seeing a crash in the FreeAllResources codepath,
    running valgrind revealed this,
    
    ==12536== Invalid read of size 4
    ==12536==    at 0x810BCAB: DeliverPropertyEvent (rrproperty.c:33)
    ==12536==    by 0x80958A4: TraverseTree (window.c:227)
    ==12536==    by 0x809593E: WalkTree (window.c:255)
    ==12536==    by 0x810BC66: RRDeliverPropertyEvent (rrproperty.c:53)
    ==12536==    by 0x810BD5D: RRDeleteProperty.clone.0 (rrproperty.c:76)
    ==12536==    by 0x810BD98: RRDeleteAllOutputProperties (rrproperty.c:88)
    ==12536==    by 0x810A36E: RROutputDestroyResource (rroutput.c:407)
    ==12536==    by 0x808DF4E: FreeClientResources (resource.c:859)
    ==12536==    by 0x808E005: FreeAllResources (resource.c:876)
    ==12536==    by 0x8062300: main (main.c:305)
    ==12536==  Address 0x46ba8ac is 4 bytes inside a block of size 164 free'd
    ==12536==    at 0x40057F6: free (vg_replace_malloc.c:325)
    ==12536==    by 0x8087F1F: _dixFreeObjectWithPrivates (privates.c:357)
    ==12536==    by 0x809832A: DeleteWindow (window.c:926)
    ==12536==    by 0x808DF4E: FreeClientResources (resource.c:859)
    ==12536==    by 0x808E005: FreeAllResources (resource.c:876)
    ==12536==    by 0x8062300: main (main.c:305)
    
    Its a use after free on the root window, since we have already deleted it
    at this point. This patch checks if the window we are destroying is the root
    window and resets the pointer to NULL if it is.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    Tested-by: Dave Airlie <airlied at redhat.com>

diff --git a/dix/window.c b/dix/window.c
index 4a47dd5..1913030 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -921,6 +921,8 @@ DeleteWindow(pointer value, XID wid)
 	if (pWin->prevSib)
 	    pWin->prevSib->nextSib = pWin->nextSib;
     }
+    else
+	pWin->drawable.pScreen->root = NULL;
     dixFreeObjectWithPrivates(pWin, PRIVATE_WINDOW);
     return Success;
 }
commit 5d1d9d9ae39fab2ee2ac085f9776f82768828dc8
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Aug 1 11:41:58 2010 -0700

    XQuartz: xpr: Bail on errors during unlock and destroy
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c
index 9f5d8a6..42f06ef 100644
--- a/hw/xquartz/xpr/xprFrame.c
+++ b/hw/xquartz/xpr/xprFrame.c
@@ -206,13 +206,16 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
 static void
 xprDestroyFrame(RootlessFrameID wid)
 {
+    xp_error err;
     TA_SERVER();
     
     pthread_mutex_lock(&window_hash_mutex);
     x_hash_table_remove(window_hash, wid);
     pthread_mutex_unlock(&window_hash_mutex);
 
-    xp_destroy_window(x_cvt_vptr_to_uint(wid));
+    err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
+    if (err != Success)
+        FatalError("Could not destroy window %i.", (int)x_cvt_vptr_to_uint(wid));
 }
 
 
@@ -366,9 +369,12 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
 static void
 xprStopDrawing(RootlessFrameID wid, Bool flush)
 {
+    xp_error err;
     TA_SERVER();
     
-    xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);
+    err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);
+    if(err != Success)
+        FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid));
 }
 
 
commit ee7fd8fc58d9fadfbb92302ddea224537f068538
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Aug 1 11:39:14 2010 -0700

    XQuartz: UpdateScreen at the end of SetRootless
    
    This will ensure that pRoot is unlocked after the miPaintWindow
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index bdaa262..eee6151 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -265,7 +265,6 @@ void QuartzUpdateScreens(void) {
     pScreen->height = height;
     
     DarwinAdjustScreenOrigins(&screenInfo);
-    quartzProcs->UpdateScreen(pScreen);
     
     /* DarwinAdjustScreenOrigins or UpdateScreen may change pScreen->x/y,
      * so use it rather than x/y
@@ -277,6 +276,7 @@ void QuartzUpdateScreens(void) {
     pRoot = pScreen->root;
     AppleWMSetScreenOrigin(pRoot);
     pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
+
     miPaintWindow(pRoot, &pRoot->borderClip,  PW_BACKGROUND);
 
     /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration
@@ -303,6 +303,8 @@ void QuartzUpdateScreens(void) {
     e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
     e.u.configureNotify.override = pRoot->overrideRedirect;
     DeliverEvents(pRoot, &e, 1, NullWindow);
+
+    quartzProcs->UpdateScreen(pScreen);
     
 #ifdef FAKE_RANDR
     RREditConnectionInfo(pScreen);
commit 4fc4cab98d454afbfd0d2f48548b5b481e8e7c82
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Jul 29 14:49:10 2010 -0700

    XQuartz: Make application switching work better for the no-spaces case
    
    We still have the issue with not raising the frontmost window for the case
    when spaces is enabled, and the AppleSpacesSwitchOnActivate preference is
    disabled.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 805ed99..36c39e5 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -337,7 +337,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
                 case NSApplicationActivatedEventType:
                     for_x = NO;
                     if ([self modalWindow] == nil) {
-                        BOOL switch_on_activate, ok;
+                        BOOL order_all_windows = YES, workspaces, ok;
                         for_appkit = NO;
                         
                         /* FIXME: hack to avoid having to pass the event to appkit,
@@ -347,13 +347,27 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
                         [self activateX:YES];
                         
                         /* Get the Spaces preference for SwitchOnActivate */
-                        (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences"));
-                        switch_on_activate = CFPreferencesGetAppBooleanValue(CFSTR("AppleSpacesSwitchOnActivate"), CFSTR(".GlobalPreferences"), &ok);
-                        if(!ok)
-                            switch_on_activate = YES;
+                        (void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock"));
+                        workspaces = CFPreferencesGetAppBooleanValue(CFSTR("workspaces"), CFSTR("com.apple.dock"), &ok);
+                        if (!ok)
+                            workspaces = NO;
+
+                        if (workspaces) {
+                            (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences"));
+                            order_all_windows = CFPreferencesGetAppBooleanValue(CFSTR("AppleSpacesSwitchOnActivate"), CFSTR(".GlobalPreferences"), &ok);
+                            if (!ok)
+                                order_all_windows = YES;
+                        }
                         
-                        if ([e data2] & 0x10 && switch_on_activate) // 0x10 is set when we use cmd-tab or the dock icon
-                            DarwinSendDDXEvent(kXquartzBringAllToFront, 0);
+                        /* TODO: In the workspaces && !AppleSpacesSwitchOnActivate case, the windows are ordered
+                         *       correctly, but we need to activate the top window on this space if there is
+                         *       none active.
+                         *
+                         *       If there are no active windows, and there are minimized windows, we should
+                         *       be restoring one of them.
+                         */
+                        if ([e data2] & 0x10) // 0x10 is set when we use cmd-tab or the dock icon
+                            DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows);
                     }
                     break;
                     
diff --git a/hw/xquartz/xpr/xprEvent.c b/hw/xquartz/xpr/xprEvent.c
index 6245cce..342b54c 100644
--- a/hw/xquartz/xpr/xprEvent.c
+++ b/hw/xquartz/xpr/xprEvent.c
@@ -73,7 +73,7 @@ Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) {
             
         case kXquartzBringAllToFront:
             DEBUG_LOG("kXquartzBringAllToFront\n");
-            RootlessOrderAllWindows();
+            RootlessOrderAllWindows(e->data[0]);
             return TRUE;
         default:
             return FALSE;
diff --git a/miext/rootless/rootless.h b/miext/rootless/rootless.h
index 00eac4e..dc4213f 100644
--- a/miext/rootless/rootless.h
+++ b/miext/rootless/rootless.h
@@ -444,7 +444,7 @@ void RootlessUpdateScreenPixmap(ScreenPtr pScreen);
 void RootlessRepositionWindows(ScreenPtr pScreen);
 
 /*
- * Bring all windows to the front of the Aqua stack
+ * Bring all windows to the front of the native stack
  */
-void RootlessOrderAllWindows (void);
+void RootlessOrderAllWindows (Bool include_unhitable);
 #endif /* _ROOTLESS_H */
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index bef8a2f..c1c6bdb 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -581,10 +581,15 @@ RootlessReorderWindow(WindowPtr pWin)
 
         RootlessStopDrawing(pWin, FALSE);
 
-        /* Find the next window above this one that has a mapped frame. */
+        /* Find the next window above this one that has a mapped frame. 
+         * Only include cases where the windows are in the same category of
+         * hittability to ensure offscreen windows dont get restacked
+         * relative to onscreen ones (but that the offscreen ones maintain
+         * their stacking order if they are explicitly asked to Reorder
+         */
 
         newPrevW = pWin->prevSib;
-        while (newPrevW && (WINREC(newPrevW) == NULL || !newPrevW->realized))
+        while (newPrevW && (WINREC(newPrevW) == NULL || !newPrevW->realized || newPrevW->rootlessUnhittable != pWin->rootlessUnhittable))
             newPrevW = newPrevW->prevSib;
 
         newPrev = newPrevW != NULL ? WINREC(newPrevW) : NULL;
@@ -1502,7 +1507,7 @@ RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width)
  * (i.e in front of Aqua windows) -- called when X11.app is given focus
  */
 void
-RootlessOrderAllWindows (void)
+RootlessOrderAllWindows (Bool include_unhitable)
 {
     int i;
     WindowPtr pWin;
@@ -1519,6 +1524,7 @@ RootlessOrderAllWindows (void)
       for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib) {
 	if (!pWin->realized) continue;
 	if (RootlessEnsureFrame(pWin) == NULL) continue;
+        if (!include_unhitable && pWin->rootlessUnhittable) continue;
 	RootlessReorderWindow (pWin);
       }
     }
commit e5bc62a03289f956c54c4699edf47f7ff237b5be
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Jul 25 22:29:11 2010 -0700

    XQuartz: Ignore kXquartzToggleFullscreen when rootless
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 147b32a..7b34b8a 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -238,8 +238,8 @@ static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr de
             
         case kXquartzToggleFullscreen:
             DEBUG_LOG("kXquartzToggleFullscreen\n");
-            if (quartzEnableRootless) 
-                QuartzSetFullscreen(!quartzHasRoot);
+            if(quartzEnableRootless) 
+                ErrorF("Ignoring kXquartzToggleFullscreen because of rootless mode.");
             else if (quartzHasRoot)
                 QuartzHide();
             else


More information about the xorg-commit mailing list