[Xquartz-changes] xserver: Branch 'master' - 23 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Thu Aug 12 23:27:29 PDT 2010


Rebased ref, commits from common ancestor:
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
commit 71af1f71c0492c365707c6b3810f94642ff39352
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Aug 12 23:01:59 2010 -0700

    Bump to version 1.8.99.906 (1.9 RC6)
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 23a0f10..1f4eb34 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,8 +26,8 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.8.99.905, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2010-07-14"
+AC_INIT([xorg-server], 1.8.99.906, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2010-08-12"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
commit 0af322858e86665ee43f065741318e69c2755510
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Aug 12 22:56:36 2010 -0700

    Silence GCC warning about uninitialized lastSlave variable
    
    Not an actual bug, but gcc can't tell that this variable cannot be
    used without being initialized
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 59c7fc5..8c75301 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1358,7 +1358,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int nu
     ScreenPtr           pScreen;
     EventListPtr        events;
     int                 nevents, i;
-    DeviceIntPtr        ptr, mpointer, lastSlave;
+    DeviceIntPtr        ptr, mpointer, lastSlave = NULL;
     Bool                saveWait;
 
     if (IsMaster(dev)) {
commit b5cf9c5090d15a50b105470900823f2d398d4bd2
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Aug 12 00:09:01 2010 -0700

    Stop checking or calling PtrCtrlProcs
    
    None of them do anything useful now that pointer acceleration is
    entirely handled in the server.   (Does not completely nuke yet,
    since that would be an API/ABI break.)
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index ac5806a..2e65a04 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2111,9 +2111,6 @@ ProcChangePointerControl(ClientPtr client)
     REQUEST(xChangePointerControlReq);
     REQUEST_SIZE_MATCH(xChangePointerControlReq);
 
-    if (!mouse->ptrfeed->CtrlProc)
-        return BadDevice;
-
     ctrl = mouse->ptrfeed->ctrl;
     if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
 	client->errorValue = stuff->doAccel;
@@ -2161,7 +2158,7 @@ ProcChangePointerControl(ClientPtr client)
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) &&
-            dev->ptrfeed && dev->ptrfeed->CtrlProc) {
+            dev->ptrfeed) {
 	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
 	    if (rc != Success)
 		return rc;
@@ -2170,9 +2167,8 @@ ProcChangePointerControl(ClientPtr client)
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) &&
-            dev->ptrfeed && dev->ptrfeed->CtrlProc) {
+            dev->ptrfeed) {
             dev->ptrfeed->ctrl = ctrl;
-            (*dev->ptrfeed->CtrlProc)(dev, &mouse->ptrfeed->ctrl);
         }
     }
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 76d2d00..bd77fe6 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -264,9 +264,6 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
         if (i >= 0)
             dev->ptrfeed->ctrl.threshold = i;
 
-        /* mostly a no-op anyway */
-        (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
-
         xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
                             local->name, ((float)dev->ptrfeed->ctrl.num)/
                                          ((float)dev->ptrfeed->ctrl.den));
commit bce12f2956f23c0ee53f7f6485dba631293a0931
Author: Jesse Adkins <jesserayadkins at gmail.com>
Date:   Wed Aug 4 23:39:14 2010 -0700

    xfree86: parser: Never use constant strings for driver names (fixes #17438)
    
    When the parser sees the "keyboard" driver, it automatically (and
     silently) replaces it with the constant string "kbd".
    Everybody else uses malloc'd memory for the driver name, so input
     device closure assumes it can use free.
    Free val.str, so this crash doesn't turn into a memory leak. Whew.
    
    Signed-off-by: Jesse Adkins <jesserayadkins at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/parser/Input.c b/hw/xfree86/parser/Input.c
index 50869d4..faff0f4 100644
--- a/hw/xfree86/parser/Input.c
+++ b/hw/xfree86/parser/Input.c
@@ -59,6 +59,7 @@
 #include <xorg-config.h>
 #endif
 
+#include "os.h"
 #include "xf86Parser.h"
 #include "xf86tokens.h"
 #include "Configint.h"
@@ -102,8 +103,10 @@ xf86parseInputSection (void)
 		case DRIVER:
 			if (xf86getSubToken (&(ptr->inp_comment)) != STRING)
 				Error (QUOTE_MSG, "Driver");
-                        if (strcmp(val.str, "keyboard") == 0)
-                            ptr->inp_driver = "kbd";
+                        if (strcmp(val.str, "keyboard") == 0) {
+                            ptr->inp_driver = strdup("kbd");
+                            free(val.str);
+                        }
                         else
 			    ptr->inp_driver = val.str;
 			break;
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index ce611d9..9f88e7e 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -111,8 +111,10 @@ xf86parseInputClassSection(void)
         case DRIVER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            if (strcmp(val.str, "keyboard") == 0)
-                ptr->driver = "kbd";
+            if (strcmp(val.str, "keyboard") == 0) {
+                ptr->driver = strdup("kbd");
+                free(val.str);
+            }
             else
                 ptr->driver = val.str;
             break;
commit 619ca32202cd22f2a408586cbc906b8bbaeb9358
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jul 28 15:08:27 2010 +1000

    Xi: reset the unused classes pointer after copying
    
    After copying the unused_classes into the device, reset the original
    pointer. Otherwise we have two pointers pointing to the same field and both
    get freed on device removal.
    
    Some classes already have this behaviour since 51c8fd69.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e990aeb..e19e207 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -223,6 +223,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->intfeed = classes->intfeed;
+            classes->intfeed = NULL;
         }
 
         i = &to->intfeed;
@@ -258,6 +259,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->stringfeed = classes->stringfeed;
+            classes->stringfeed = NULL;
         }
 
         s = &to->stringfeed;
@@ -293,6 +295,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->bell = classes->bell;
+            classes->bell = NULL;
         }
 
         b = &to->bell;
@@ -329,6 +332,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->leds = classes->leds;
+            classes->leds = NULL;
         }
 
         l = &to->leds;
@@ -379,6 +383,7 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
             to->kbdfeed = classes->kbdfeed;
             if (!to->kbdfeed)
                 InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+            classes->kbdfeed = NULL;
         }
 
         k = &to->kbdfeed;
@@ -506,6 +511,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->ptrfeed = classes->ptrfeed;
+            classes->ptrfeed = NULL;
         }
 
         p = &to->ptrfeed;
commit 1a172f3297369a72865232c382abfc14281102a4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 23 13:24:34 2010 +1000

    xkb: if the button isn't down, don't fake an event.
    
    If the button we're about to fake isn't down (or up), don't fake a release
    (or press) event for it. Behaviour is the same as before, this just saves
    a few cycles.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index c36dba0..59c7fc5 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1410,6 +1410,7 @@ void
 XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
 {
     DeviceIntPtr        ptr;
+    int                 down;
 
     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
      * post through the attached master pointer we'd get duplicate events.
@@ -1427,6 +1428,10 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
     else
         return;
 
+    down = button_is_down(ptr, button, BUTTON_PROCESSED);
+    if (press == down)
+        return;
+
     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
                            button, 0, 0, NULL);
 }
commit 651c36e95ec0ac60d3fb98966df4218712ae78c2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 23 11:46:30 2010 +1000

    xkb: post-fix PointerKeys button events with a DeviceChangedEvent.
    
    commit 14327858391ebe929b806efb53ad79e789361883
        xkb: release XTEST pointer buttons on physical releases. (#28808)
    revealed a bug with the XTEST/PointerKeys interaction.
    
    Events resulting from PointerKeys are injected into the event processing
    stream, not appended to the event queue. The events generated for the fake
    button press include a DeviceChangedEvent (DCE), a raw button event and the
    button event itself. The DCE causes the master to switch classes to the
    attached XTEST pointer device.
    
    Once the fake button is processed, normal event processing continues with
    events in the EQ. The master still contains the XTEST classes, causing some
    events to be dropped if e.g. the number of valuators of the event in the
    queue exceeds the XTEST device's number of valuators.
    
    Example: the EQ contains the following events, processed one-by-one, left to
    right.
    
    [DCE (dev)][Btn down][Btn up][Motion][Motion][...]
                      ^ XkbFakeDeviceButton injects [DCE (XTEST)][Btn up]
    
    Thus the event sequence processed looks like this:
    
    [DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][Motion][Motion][...]
    
    The first DCE causes the master to switch to the device. The button up event
    injects a DCE to the XTEST device, causing the following Motion events to be
    processed with the master still being on XTEST classes.
    
    This patch post-fixes the injected event sequence with a DCE to restore the
    classes of the original slave device, resulting in an event sequence like
    this:
    [DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][DCE (dev)][Motion][Motion]
    
    Note that this is a simplified description. The event sequence injected by
    the PointerKeys code is injected for the master device only and the matching
    slave device that caused the injection has already finished processing on
    the slave. Furthermore, the injection happens as part of the the XKB layer,
    before the unwrapping of the processInputProc takes us into the DIX where
    the DCE is actually handled.
    
    Bug reproducible with a device that reports more than 2 valuators. Simply
    cause button releases on the device and wait for a "too many valuators"
    warning message.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index a9b6e82..20bcf7e 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -652,8 +652,8 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
  *        events if a DCCE was generated.
  * @return The updated @events pointer.
  */
-static EventListPtr
-updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
+EventListPtr
+UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
 {
     DeviceIntPtr master;
 
@@ -929,7 +929,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     num_events = 1;
 
-    events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
 
     /* Handle core repeating, via press/release/press/release. */
     if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
@@ -1091,7 +1091,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         (type == MotionNotify && num_valuators <= 0))
         return 0;
 
-    events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     raw = (RawDeviceEvent*)events->event;
     events++;
@@ -1206,7 +1206,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         (num_valuators + first_valuator) > pDev->valuator->numAxes)
         return 0;
 
-    events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     event = (DeviceEvent *) events->event;
     init_event(pDev, event, GetTimeInMillis());
diff --git a/include/input.h b/include/input.h
index 55b1537..ffb1c33 100644
--- a/include/input.h
+++ b/include/input.h
@@ -439,6 +439,12 @@ extern void CreateClassesChangedEvent(EventListPtr event,
                                       DeviceIntPtr master,
                                       DeviceIntPtr slave,
                                       int type);
+extern EventListPtr UpdateFromMaster(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int *num_events);
+
 extern _X_EXPORT int GetPointerEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index eea3d4a..c36dba0 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1332,35 +1332,53 @@ xkbStateNotify	sn;
     return;
 }
 
+/*
+ * The event is injected into the event processing, not the EQ. Thus,
+ * ensure that we restore the master after the event sequence to the
+ * original set of classes. Otherwise, the master remains on the XTEST
+ * classes and drops events that don't fit into the XTEST layout (e.g.
+ * events with more than 2 valuators).
+ *
+ * FIXME: EQ injection in the processing stage is not designed for, so this
+ * is a rather awkward hack. The event list returned by GetPointerEvents()
+ * and friends is always prefixed with a DCE if the last _posted_ device was
+ * different. For normal events, this sequence then resets the master during
+ * the processing stage. Since we inject the PointerKey events in the
+ * processing stage though, we need to manually reset to restore the
+ * previous order, because the events already in the EQ must be sent for the
+ * right device.
+ * So we post-fix the event list we get from GPE with a DCE back to the
+ * previous slave device.
+ *
+ * First one on drinking island wins!
+ */
 static void
-XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
+InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators)
 {
+    ScreenPtr           pScreen;
     EventListPtr        events;
     int                 nevents, i;
-    DeviceIntPtr        ptr;
-    ScreenPtr           pScreen;
+    DeviceIntPtr        ptr, mpointer, lastSlave;
     Bool                saveWait;
-    int                 gpe_flags = 0;
 
-    if (IsMaster(dev))
-        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
-    else if (!dev->u.master)
+    if (IsMaster(dev)) {
+        mpointer = GetMaster(dev, MASTER_POINTER);
+        lastSlave = mpointer->u.lastSlave;
+        ptr = GetXTestDevice(mpointer);
+    } else if (!dev->u.master)
         ptr = dev;
     else
         return;
 
-    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
-        gpe_flags = POINTER_ABSOLUTE;
-    else
-        gpe_flags = POINTER_RELATIVE;
 
-    events = InitEventList(GetMaximumEventsNum());
+    events = InitEventList(GetMaximumEventsNum() + 1);
     OsBlockSignals();
     pScreen = miPointerGetScreen(ptr);
     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
-    nevents = GetPointerEvents(events, ptr,
-                               MotionNotify, 0,
-                               gpe_flags, 0, 2, (int[]){x, y});
+    nevents = GetPointerEvents(events, ptr, type, button, flags, 0,
+                               num_valuators, valuators);
+    if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
+        UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents);
     miPointerSetWaitForUpdate(pScreen, saveWait);
     OsReleaseSignals();
 
@@ -1368,13 +1386,29 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
         mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
 
     FreeEventList(events, GetMaximumEventsNum());
+
+}
+
+static void
+XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
+{
+    int                 gpe_flags = 0;
+
+    /* ignore attached SDs */
+    if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL)
+        return;
+
+    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
+        gpe_flags = POINTER_ABSOLUTE;
+    else
+        gpe_flags = POINTER_RELATIVE;
+
+    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y});
 }
 
 void
 XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
 {
-    EventListPtr        events;
-    int                 nevents, i;
     DeviceIntPtr        ptr;
 
     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
@@ -1385,24 +1419,14 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
      * if dev is a floating slave, post through the device itself.
      */
 
-    if (IsMaster(dev))
-        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
-    else if (!dev->u.master)
+    if (IsMaster(dev)) {
+        DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
+        ptr = GetXTestDevice(mpointer);
+    } else if (!dev->u.master)
         ptr = dev;
     else
         return;
 
-    events = InitEventList(GetMaximumEventsNum());
-    OsBlockSignals();
-    nevents = GetPointerEvents(events, ptr,
-                               press ? ButtonPress : ButtonRelease, button,
-                               0 /* flags */, 0 /* first */,
-                               0 /* num_val */, NULL);
-    OsReleaseSignals();
-
-
-    for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
-
-    FreeEventList(events, GetMaximumEventsNum());
+    InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
+                           button, 0, 0, NULL);
 }
commit 6dae7f3792611aace1df0cca63bf50c50d93de43
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Aug 10 19:30:20 2010 +0100

    xace: Invalid reference to out-of-scope data.
    
    The callback data passed by reference to the hook was allocated on stack
    within the scope of the case statement. The compiler is free to reuse
    any of that stack space whilst making the function call so we may end up
    passing garbage into the callback.
    
    References:
    
      Bug 18451 - Xorg server 1.5.2 SEGV during XFixesGetCursorImage()
      https://bugs.freedesktop.org/show_bug.cgi?id=18451
    
    v2: Drop the unrelated hunk that snuck in when ammending the commit
    message.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xace.c b/Xext/xace.c
index e10d837..c757cad 100644
--- a/Xext/xace.c
+++ b/Xext/xace.c
@@ -87,7 +87,18 @@ void XaceHookAuditEnd(ClientPtr ptr, int result)
  */
 int XaceHook(int hook, ...)
 {
-    pointer calldata;	/* data passed to callback */
+    union {
+	XaceResourceAccessRec res;
+	XaceDeviceAccessRec dev;
+	XaceSendAccessRec send;
+	XaceReceiveAccessRec recv;
+	XaceClientAccessRec client;
+	XaceExtAccessRec ext;
+	XaceServerAccessRec server;
+	XaceScreenAccessRec screen;
+	XaceAuthAvailRec auth;
+	XaceKeyAvailRec key;
+    } u;
     int *prv = NULL;	/* points to return value from callback */
     va_list ap;		/* argument list */
     va_start(ap, hook);
@@ -99,117 +110,86 @@ int XaceHook(int hook, ...)
      */
     switch (hook)
     {
-	case XACE_RESOURCE_ACCESS: {
-	    XaceResourceAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.id = va_arg(ap, XID);
-	    rec.rtype = va_arg(ap, RESTYPE);
-	    rec.res = va_arg(ap, pointer);
-	    rec.ptype = va_arg(ap, RESTYPE);
-	    rec.parent = va_arg(ap, pointer);
-	    rec.access_mode = va_arg(ap, Mask);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_RESOURCE_ACCESS:
+	    u.res.client = va_arg(ap, ClientPtr);
+	    u.res.id = va_arg(ap, XID);
+	    u.res.rtype = va_arg(ap, RESTYPE);
+	    u.res.res = va_arg(ap, pointer);
+	    u.res.ptype = va_arg(ap, RESTYPE);
+	    u.res.parent = va_arg(ap, pointer);
+	    u.res.access_mode = va_arg(ap, Mask);
+	    u.res.status = Success; /* default allow */
+	    prv = &u.res.status;
 	    break;
-	}
-	case XACE_DEVICE_ACCESS: {
-	    XaceDeviceAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.dev = va_arg(ap, DeviceIntPtr);
-	    rec.access_mode = va_arg(ap, Mask);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_DEVICE_ACCESS:
+	    u.dev.client = va_arg(ap, ClientPtr);
+	    u.dev.dev = va_arg(ap, DeviceIntPtr);
+	    u.dev.access_mode = va_arg(ap, Mask);
+	    u.dev.status = Success; /* default allow */
+	    prv = &u.dev.status;
 	    break;
-	}
-	case XACE_SEND_ACCESS: {
-	    XaceSendAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.dev = va_arg(ap, DeviceIntPtr);
-	    rec.pWin = va_arg(ap, WindowPtr);
-	    rec.events = va_arg(ap, xEventPtr);
-	    rec.count = va_arg(ap, int);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_SEND_ACCESS:
+	    u.send.client = va_arg(ap, ClientPtr);
+	    u.send.dev = va_arg(ap, DeviceIntPtr);
+	    u.send.pWin = va_arg(ap, WindowPtr);
+	    u.send.events = va_arg(ap, xEventPtr);
+	    u.send.count = va_arg(ap, int);
+	    u.send.status = Success; /* default allow */
+	    prv = &u.send.status;
 	    break;
-	}
-	case XACE_RECEIVE_ACCESS: {
-	    XaceReceiveAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.pWin = va_arg(ap, WindowPtr);
-	    rec.events = va_arg(ap, xEventPtr);
-	    rec.count = va_arg(ap, int);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_RECEIVE_ACCESS:
+	    u.recv.client = va_arg(ap, ClientPtr);
+	    u.recv.pWin = va_arg(ap, WindowPtr);
+	    u.recv.events = va_arg(ap, xEventPtr);
+	    u.recv.count = va_arg(ap, int);
+	    u.recv.status = Success; /* default allow */
+	    prv = &u.recv.status;
 	    break;
-	}
-	case XACE_CLIENT_ACCESS: {
-	    XaceClientAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.target = va_arg(ap, ClientPtr);
-	    rec.access_mode = va_arg(ap, Mask);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_CLIENT_ACCESS:
+	    u.client.client = va_arg(ap, ClientPtr);
+	    u.client.target = va_arg(ap, ClientPtr);
+	    u.client.access_mode = va_arg(ap, Mask);
+	    u.client.status = Success; /* default allow */
+	    prv = &u.client.status;
 	    break;
-	}
-	case XACE_EXT_ACCESS: {
-	    XaceExtAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.ext = va_arg(ap, ExtensionEntry*);
-	    rec.access_mode = DixGetAttrAccess;
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_EXT_ACCESS:
+	    u.ext.client = va_arg(ap, ClientPtr);
+	    u.ext.ext = va_arg(ap, ExtensionEntry*);
+	    u.ext.access_mode = DixGetAttrAccess;
+	    u.ext.status = Success; /* default allow */
+	    prv = &u.ext.status;
 	    break;
-	}
-	case XACE_SERVER_ACCESS: {
-	    XaceServerAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.access_mode = va_arg(ap, Mask);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_SERVER_ACCESS:
+	    u.server.client = va_arg(ap, ClientPtr);
+	    u.server.access_mode = va_arg(ap, Mask);
+	    u.server.status = Success; /* default allow */
+	    prv = &u.server.status;
 	    break;
-	}
 	case XACE_SCREEN_ACCESS:
-	case XACE_SCREENSAVER_ACCESS: {
-	    XaceScreenAccessRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.screen = va_arg(ap, ScreenPtr);
-	    rec.access_mode = va_arg(ap, Mask);
-	    rec.status = Success; /* default allow */
-	    calldata = &rec;
-	    prv = &rec.status;
+	case XACE_SCREENSAVER_ACCESS:
+	    u.screen.client = va_arg(ap, ClientPtr);
+	    u.screen.screen = va_arg(ap, ScreenPtr);
+	    u.screen.access_mode = va_arg(ap, Mask);
+	    u.screen.status = Success; /* default allow */
+	    prv = &u.screen.status;
 	    break;
-	}
-	case XACE_AUTH_AVAIL: {
-	    XaceAuthAvailRec rec;
-	    rec.client = va_arg(ap, ClientPtr);
-	    rec.authId = va_arg(ap, XID);
-	    calldata = &rec;
+	case XACE_AUTH_AVAIL:
+	    u.auth.client = va_arg(ap, ClientPtr);
+	    u.auth.authId = va_arg(ap, XID);
 	    break;
-	}
-	case XACE_KEY_AVAIL: {
-	    XaceKeyAvailRec rec;
-	    rec.event = va_arg(ap, xEventPtr);
-	    rec.keybd = va_arg(ap, DeviceIntPtr);
-	    rec.count = va_arg(ap, int);
-	    calldata = &rec;
+	case XACE_KEY_AVAIL:
+	    u.key.event = va_arg(ap, xEventPtr);
+	    u.key.keybd = va_arg(ap, DeviceIntPtr);
+	    u.key.count = va_arg(ap, int);
 	    break;
-	}
-	default: {
+	default:
 	    va_end(ap);
 	    return 0;	/* unimplemented hook number */
-	}
     }
     va_end(ap);
  
     /* call callbacks and return result, if any. */
-    CallCallbacks(&XaceHooks[hook], calldata);
+    CallCallbacks(&XaceHooks[hook], &u);
     return prv ? *prv : Success;
 }
 
commit fbd02046797185715e1a120d52e410ec78fc365f
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Aug 5 15:19:20 2010 +0100

    Cygwin/X: Fix glxWinCreateDrawable() for API change
    
    Commit 9de0e31746d5f0d9d39d11c94ec3cbc04a9935fc changed the signature
    of __GLXScreen's createDrawable method.
    
    Update the glxWinCreateDrawable() function in XWin's GLX provider
    appropriately.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Tested-by: Colin Harrison <colin.harrison at virgin.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 8ec40da..1cf82a7 100755
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -375,10 +375,12 @@ static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen);
 static __GLXcontext *glxWinCreateContext(__GLXscreen *screen,
                                         __GLXconfig *modes,
                                         __GLXcontext *baseShareContext);
-static __GLXdrawable *glxWinCreateDrawable(__GLXscreen *screen,
+static __GLXdrawable *glxWinCreateDrawable(ClientPtr client,
+                                          __GLXscreen *screen,
                                           DrawablePtr pDraw,
-                                          int type,
                                           XID drawId,
+                                          int type,
+                                          XID glxDrawId,
                                           __GLXconfig *conf);
 
 static Bool glxWinRealizeWindow(WindowPtr pWin);
@@ -901,10 +903,12 @@ glxWinDrawableDestroy(__GLXdrawable *base)
 }
 
 static __GLXdrawable *
-glxWinCreateDrawable(__GLXscreen *screen,
+glxWinCreateDrawable(ClientPtr client,
+                    __GLXscreen *screen,
                     DrawablePtr pDraw,
-                    int type,
                     XID drawId,
+                    int type,
+                    XID glxDrawId,
                     __GLXconfig *conf)
 {
   __GLXWinDrawable *glxPriv;
@@ -916,7 +920,7 @@ glxWinCreateDrawable(__GLXscreen *screen,
 
   memset(glxPriv, 0, sizeof *glxPriv);
 
-  if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, drawId, conf)) {
+  if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) {
     free(glxPriv);
     return NULL;
   }
commit ff70848e623920779d20f35d47e9e1f34157de47
Author: Keith Packard <keithp at keithp.com>
Date:   Fri May 21 09:01:43 2010 -0700

    Don't let alpha maps recurse in fb. Bug 23581.
    
    Recursive alpha maps (where one picture's alpha map is set to a
    picture with an external alpha map) would be all fine and dandy,
    except for the case where the client constructs a loop. Detecting this
    case when setting the alpha map values would be difficult as any time
    an alpha map is set, the server would have to check for the looping
    case.
    
    Instead, a far simpler fix is to simply disallow recursive alpha maps
    in the rendering code, the Render spec is ambiguous in this area and
    allows us to to ignore the recursive case.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/fb/fbpict.c b/fb/fbpict.c
index 26cdc0d..f7f1200 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -332,8 +332,11 @@ create_bits_picture (PicturePtr pict,
     return image;
 }
 
+static pixman_image_t *
+image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map);
+
 static void
-set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
 {
     pixman_repeat_t repeat;
     pixman_filter_t filter;
@@ -382,10 +385,13 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
     
     pixman_image_set_repeat (image, repeat);
     
-    if (pict->alphaMap)
+    /* Fetch alpha map unless 'pict' is being used
+     * as the alpha map for this operation
+     */
+    if (pict->alphaMap && !is_alpha_map)
     {
 	int alpha_xoff, alpha_yoff;
-	pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff);
+	pixman_image_t *alpha_map = image_from_pict_internal (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE);
 	
 	pixman_image_set_alpha_map (
 	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -417,8 +423,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
     pixman_image_set_source_clipping (image, TRUE);
 }
 
-pixman_image_t *
-image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+static pixman_image_t *
+image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
 {
     pixman_image_t *image = NULL;
 
@@ -452,11 +458,17 @@ image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
     }
     
     if (image)
-	set_image_properties (image, pict, has_clip, xoff, yoff);
+	set_image_properties (image, pict, has_clip, xoff, yoff, is_alpha_map);
     
     return image;
 }
 
+pixman_image_t *
+image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+{
+    return image_from_pict_internal (pict, has_clip, xoff, yoff, FALSE);
+}
+
 void
 free_pixman_pict (PicturePtr pict, pixman_image_t *image)
 {
commit 70a94c5b7a42adc0995bf774c44587a0778be0d0
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Aug 3 19:49:10 2010 +0100

    rootless: fix uninitialized private key assert in non-rootless modes in Cygwin/X
    
    IsFramedWindow() is called from miPaintWindow() if the server has
    been built with ROOTLESS defined, irrespective of if RootlessInit()
    has ever been called, or not.
    
    Add a check to IsFramedWindow() to check if rootlessWindowPrivateKey
    has been registered (as a proxy for checking if the rootless extension
    has been initialized) so we don't go on to try to use that key,
    triggering an assert.
    
    This bug exposes what appears to be a difference in opinion about
    the rootless extension between XQuartz and XWin.  XQuartz always
    initializes the rootless extension, whereas XWin offers several modes
    of operation, and the rootless extension is only used for one of them
    
    That probably means that the all code under compile time guard for
    ROOTLESS should be carefully checked that it doesn't also need to be
    under a run-time guard
    
    (I've reviewed the other ROOTLESS blocks in dix/events.c and
    dix/window.c and they look ok -- keithp)
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/miext/rootless/rootlessCommon.c b/miext/rootless/rootlessCommon.c
index 82fe0b9..f91cfb4 100644
--- a/miext/rootless/rootlessCommon.c
+++ b/miext/rootless/rootlessCommon.c
@@ -92,6 +92,9 @@ IsFramedWindow(WindowPtr pWin)
 {
     WindowPtr top;
 
+    if (!dixPrivateKeyRegistered(&rootlessWindowPrivateKeyRec))
+        return FALSE;
+
     if (!pWin->realized)
         return FALSE;
     top = TopLevelParent(pWin);
commit 3ab6cd31cbdf8095b2948034fce5fb645422d8da
Author: Adam Jackson <ajax at redhat.com>
Date:   Mon Aug 9 15:20:20 2010 -0400

    fonts: Fix refcounting for asynchronous font operations (#3040)
    
    When doing Xinerama, we'll dispatch font ops across all backend screens.
    If using a font server (such that some operations can sleep), we'll put
    the client to sleep once for each screen, but only wake up once, because
    we're trying to keep track of the sleep count in _each_ screen's
    closure.
    
    Instead, just ask the core whether the client is already asleep.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 4a8f113..e22eabe 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -321,10 +321,10 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 	    continue;
 	}
 	if (err == Suspended) {
-	    if (!c->slept) {
-		c->slept = TRUE;
-		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
-	    }
+	    if (!ClientIsAsleep(client))
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, c);
+	    else
+		goto xinerama_sleep;
 	    return TRUE;
 	}
 	break;
@@ -373,8 +373,8 @@ bail:
 	SendErrorToClient(c->client, X_OpenFont, 0,
 			  c->fontid, FontToXError(err));
     }
-    if (c->slept)
-	ClientWakeup(c->client);
+    ClientWakeup(c->client);
+xinerama_sleep:
     for (i = 0; i < c->num_fpes; i++) {
 	FreeFPE(c->fpe_list[i]);
     }
@@ -460,7 +460,6 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna
     c->current_fpe = 0;
     c->num_fpes = num_fpes;
     c->fnamelen = lenfname;
-    c->slept = FALSE;
     c->flags = flags;
     c->non_cachable_font = cached;
 
@@ -622,12 +621,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 		 c->names);
 
 	    if (err == Suspended) {
-		if (!c->slept) {
-		    c->slept = TRUE;
+		if (!ClientIsAsleep(client))
 		    ClientSleep(client,
-			(ClientSleepProcPtr)doListFontsAndAliases,
-			(pointer) c);
-		}
+				(ClientSleepProcPtr)doListFontsAndAliases,
+				c);
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 
@@ -650,12 +649,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 		     c->current.patlen, c->current.max_names - c->names->nnames,
 		     &c->current.private);
 		if (err == Suspended) {
-		    if (!c->slept) {
+		    if (!ClientIsAsleep(client))
 			ClientSleep(client,
 				    (ClientSleepProcPtr)doListFontsAndAliases,
-				    (pointer) c);
-			c->slept = TRUE;
-		    }
+				    c);
+		    else
+			goto xinerama_sleep;
 		    return TRUE;
 		}
 		if (err == Successful)
@@ -668,12 +667,12 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
 		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
 		     &resolvedlen, c->current.private);
 		if (err == Suspended) {
-		    if (!c->slept) {
+		    if (ClientIsAsleep(client))
 			ClientSleep(client,
 				    (ClientSleepProcPtr)doListFontsAndAliases,
-				    (pointer) c);
-			c->slept = TRUE;
-		    }
+				    c);
+		    else
+			goto xinerama_sleep;
 		    return TRUE;
 		}
 		if (err == FontNameAlias) {
@@ -822,8 +821,8 @@ finish:
     free(bufferStart);
 
 bail:
-    if (c->slept)
-	ClientWakeup(client);
+    ClientWakeup(client);
+xinerama_sleep:
     for (i = 0; i < c->num_fpes; i++)
 	FreeFPE(c->fpe_list[i]);
     free(c->fpe_list);
@@ -881,7 +880,6 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
     c->current.list_started = FALSE;
     c->current.private = 0;
     c->haveSaved = FALSE;
-    c->slept = FALSE;
     c->savedName = 0;
     doListFontsAndAliases(client, c);
     return Success;
@@ -928,11 +926,11 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
 		 c->current.max_names, &c->current.private);
 	    if (err == Suspended)
  	    {
-		if (!c->slept)
- 		{
-		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
-		    c->slept = TRUE;
-		}
+		if (!ClientIsAsleep(client))
+		    ClientSleep(client,
+				(ClientSleepProcPtr)doListFontsWithInfo, c);
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 	    if (err == Successful)
@@ -947,13 +945,11 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
 		 &numFonts, c->current.private);
 	    if (err == Suspended)
  	    {
-		if (!c->slept)
- 		{
+		if (!ClientIsAsleep(client))
 		    ClientSleep(client,
-		    	     (ClientSleepProcPtr)doListFontsWithInfo,
-			     c);
-		    c->slept = TRUE;
-		}
+				(ClientSleepProcPtr)doListFontsWithInfo, c);
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 	}
@@ -1098,8 +1094,8 @@ finish:
 		     - sizeof(xGenericReply));
     WriteSwappedDataToClient(client, length, &finalReply);
 bail:
-    if (c->slept)
-	ClientWakeup(client);
+    ClientWakeup(client);
+xinerama_sleep:
     for (i = 0; i < c->num_fpes; i++)
 	FreeFPE(c->fpe_list[i]);
     free(c->reply);
@@ -1154,7 +1150,6 @@ StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
     c->current.private = 0;
     c->savedNumFonts = 0;
     c->haveSaved = FALSE;
-    c->slept = FALSE;
     c->savedName = 0;
     doListFontsWithInfo(client, c);
     return Success;
@@ -1181,7 +1176,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 	fpe = c->pGC->font->fpe;
 	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
 
-	if (c->slept)
+	if (ClientIsAsleep(client))
 	{
 	    /* Client has died, but we cannot bail out right now.  We
 	       need to clean up after the work we did when going to
@@ -1198,7 +1193,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
     }
 
     /* Make sure our drawable hasn't disappeared while we slept. */
-    if (c->slept && c->pDraw)
+    if (ClientIsAsleep(client) && c->pDraw)
     {
 	DrawablePtr pDraw;
 	dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess);
@@ -1212,7 +1207,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 	}
     }
 
-    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+    client_state = ClientIsAsleep(client) ? SLEEPING : NEVER_SLEPT;
 
     while (c->endReq - c->pElt > TextEltHeader)
     {
@@ -1295,7 +1290,7 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 
 	    if (lgerr == Suspended)
 	    {
-		if (!c->slept) {
+		if (!ClientIsAsleep(client)) {
 		    int len;
 		    GC *pGC;
 		    PTclosurePtr new_closure;
@@ -1368,15 +1363,14 @@ doPolyText(ClientPtr client, PTclosurePtr c)
 		    c->pGC = pGC;
 		    ValidateGC(c->pDraw, c->pGC);
 		    
-		    c->slept = TRUE;
-		    ClientSleep(client,
-		    	     (ClientSleepProcPtr)doPolyText,
-			     (pointer) c);
+		    ClientSleep(client, (ClientSleepProcPtr)doPolyText, c);
 
 		    /* Set up to perform steps 3 and 4 */
 		    client_state = START_SLEEP;
 		    continue;	/* on to steps 3 and 4 */
 		}
+		else
+		    goto xinerama_sleep;
 		return TRUE;
 	    }
 	    else if (lgerr != Successful)
@@ -1419,9 +1413,10 @@ bail:
 #endif
 	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
     }
-    if (c->slept)
+    if (ClientIsAsleep(client))
     {
 	ClientWakeup(c->client);
+xinerama_sleep:
 	ChangeGC(NullClient, c->pGC, clearGCmask, clearGC);
 
 	/* Unreference the font from the scratch GC */
@@ -1460,7 +1455,6 @@ PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
     local_closure.pGC = pGC;
     local_closure.did = did;
     local_closure.err = Success;
-    local_closure.slept = FALSE;
 
     (void) doPolyText(client, &local_closure);
     return Success;
@@ -1485,7 +1479,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
     }
 
     /* Make sure our drawable hasn't disappeared while we slept. */
-    if (c->slept && c->pDraw)
+    if (ClientIsAsleep(client) && c->pDraw)
     {
 	DrawablePtr pDraw;
 	dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess);
@@ -1502,7 +1496,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
     lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
     if (lgerr == Suspended)
     {
-        if (!c->slept) {
+        if (!ClientIsAsleep(client)) {
 	    GC *pGC;
 	    unsigned char *data;
 	    ITclosurePtr new_closure;
@@ -1555,9 +1549,10 @@ doImageText(ClientPtr client, ITclosurePtr c)
 	    c->pGC = pGC;
 	    ValidateGC(c->pDraw, c->pGC);
 
-	    c->slept = TRUE;
-            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, c);
         }
+	else
+	    goto xinerama_sleep;
         return TRUE;
     }
     else if (lgerr != Successful)
@@ -1576,9 +1571,10 @@ bail:
     if (err != Success && c->client != serverClient) {
 	SendErrorToClient(c->client, c->reqType, 0, 0, err);
     }
-    if (c->slept)
+    if (ClientIsAsleep(client))
     {
 	ClientWakeup(c->client);
+xinerama_sleep:
 	ChangeGC(NullClient, c->pGC, clearGCmask, clearGC);
 
 	/* Unreference the font from the scratch GC */
@@ -1616,7 +1612,6 @@ ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
 	local_closure.itemSize = 2;
     }
     local_closure.did = did;
-    local_closure.slept = FALSE;
 
     (void) doImageText(client, &local_closure);
     return Success;
diff --git a/include/closestr.h b/include/closestr.h
index 2cd67b1..7ca2613 100644
--- a/include/closestr.h
+++ b/include/closestr.h
@@ -46,7 +46,6 @@ typedef struct _OFclosure {
     short       num_fpes;
     FontPathElementPtr *fpe_list;
     Mask        flags;
-    Bool        slept;
 
 /* XXX -- get these from request buffer instead? */
     char       *origFontName;
@@ -79,7 +78,6 @@ typedef struct _LFWIclosure {
     LFWIstateRec	saved;
     int			savedNumFonts;
     Bool		haveSaved;
-    Bool		slept;
     char		*savedName;
 } LFWIclosureRec;
 
@@ -93,7 +91,6 @@ typedef struct _LFclosure {
     LFWIstateRec current;
     LFWIstateRec saved;
     Bool        haveSaved;
-    Bool        slept;
     char	*savedName;
     int		savedNameLen;
 }	LFclosureRec;
@@ -124,7 +121,6 @@ typedef struct _PTclosure {
     int			itemSize;
     XID			did;
     int			err;
-    Bool		slept;
 } PTclosureRec;
 
 /* ImageText */
@@ -151,6 +147,5 @@ typedef struct _ITclosure {
     ImageTextPtr	imageText;
     int			itemSize;
     XID			did;
-    Bool		slept;
 } ITclosureRec;
 #endif				/* CLOSESTR_H */
commit 35c0dbe4b0a6ab790f4271325b8a0b16894daa8b
Author: Gaetan Nadon <memsize at videotron.ca>
Date:   Sun Aug 8 10:03:08 2010 -0400

    doc: add missing .gitignore for Xserver-DTrace
    
    The dtrace doc was recently added in commit
    9c171d4aee695ab66e6db1ab92539557bd368cfa
    
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/doc/xml/dtrace/.gitignore b/doc/xml/dtrace/.gitignore
new file mode 100644
index 0000000..a43c4e1
--- /dev/null
+++ b/doc/xml/dtrace/.gitignore
@@ -0,0 +1,4 @@
+Xserver-DTrace.html
+Xserver-DTrace.pdf
+Xserver-DTrace.txt
+xorg.css
commit 05c4fe83fdc20b838fd59658478278dc31a55eb9
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Jul 30 17:43:24 2010 -0700

    Check HAVE_XMLTO_TEXT before trying to use xmlto to make text files
    
    Reported-by: Matt Turner <mattst88 at gmail.com>
    Tested-by: Gaetan Nadon <memsize at videotron.ca>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/doc/xml/xmlrules.in b/doc/xml/xmlrules.in
index 0d094be..b7fda11 100644
--- a/doc/xml/xmlrules.in
+++ b/doc/xml/xmlrules.in
@@ -48,10 +48,12 @@ xorg.css: $(STYLESHEET_SRCDIR)/xorg.css
 endif
 
 if HAVE_XMLTO
+if HAVE_XMLTO_TEXT
 BUILT_DOC_FILES += $(TXT_FILES)
 .xml.txt:
 	@rm -f $@
 	$(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) txt $<
+endif
 
 BUILT_DOC_FILES += $(HTML_FILES)
 .xml.html:
commit a6fb7829ed9bf26c4c2a02c6ed075fb1b17f7b2a
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Mon Jul 26 19:55:27 2010 -0700

    Xserver-spec: Update ChangeGC prototype, add ChangeGCXIDs
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/doc/xml/Xserver-spec.xml b/doc/xml/Xserver-spec.xml
index c5fd191..563705f 100644
--- a/doc/xml/Xserver-spec.xml
+++ b/doc/xml/Xserver-spec.xml
@@ -3760,7 +3760,7 @@ Also included in each GC is support for dynamic devPrivates, which the
 DDX can use for any purpose (see <xref linkend="wrappers_and_privates"/> below).</para>
 <para>
 The DIX routines available for manipulating GCs are
-CreateGC, ChangeGC, CopyGC, SetClipRects, SetDashes, and FreeGC.
+CreateGC, ChangeGC, ChangeGCXIDs, CopyGC, SetClipRects, SetDashes, and FreeGC.
 <blockquote><programlisting>
 
 	GCPtr CreateGC(pDrawable, mask, pval, pStatus)
@@ -3769,10 +3769,17 @@ CreateGC, ChangeGC, CopyGC, SetClipRects, SetDashes, and FreeGC.
 	    XID *pval;
 	    int *pStatus;
 
-	int ChangeGC(pGC, mask, pval)
+	int ChangeGC(client, pGC, mask, pUnion)
+	    ClientPtr client;
 	    GCPtr pGC;
 	    BITS32 mask;
-	    XID *pval;
+	    ChangeGCValPtr pUnion;
+
+	int ChangeGCXIDs(client, pGC, mask, pC32)
+	    ClientPtr client;
+	    GCPtr pGC;
+	    BITS32 mask;
+	    CARD32 *pC32;
 
 	int CopyGC(pgcSrc, pgcDst, mask)
 	    GCPtr pgcSrc;
commit a817271d461e2f95dd7dc62cd1c7d123ce92f555
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Jul 22 23:57:57 2010 -0700

    Update Xserver-spec for new devPrivates API
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Patrick E. Kane <pekane52 at gmail.com>

diff --git a/doc/xml/Xserver-spec.xml b/doc/xml/Xserver-spec.xml
index 466b79d..c5fd191 100644
--- a/doc/xml/Xserver-spec.xml
+++ b/doc/xml/Xserver-spec.xml
@@ -92,6 +92,13 @@
 	<authorinitials>efw</authorinitials>
 	<revremark>Revised for devPrivates changes</revremark>
       </revision>
+      <revision>
+	<revnumber>3.5</revnumber>
+	<date>July 2010</date>
+	<authorinitials>ac</authorinitials>
+	<revremark>Revised for Xorg 1.9 devPrivates changes
+	  and 1.8 CreateNewResourceType changes</revremark>
+      </revision>
     </revhistory>
     <legalnotice>
       <para>Copyright &#xA9; 1994 X Consortium, Inc., 2004 X.org Foundation, Inc.</para>
@@ -4808,32 +4815,68 @@ Two new extensibility concepts have been developed for release 4, Wrappers
 and devPrivates.  These replace the R3 GCInterest queues, which were not a
 general enough mechanism for many extensions and only provided hooks into a
 single data structure.  devPrivates have been revised substantially for
-X.org X server relase 1.5.</para>
+X.Org X server release 1.5, and updated again for the 1.9 release.</para>
 <section>
   <title>devPrivates</title>
 <para>
 devPrivates provides a way to attach arbitrary private data to various server structures.
 Any structure which contains a <structfield>devPrivates</structfield> field of
-type <type>PrivateRec</type> supports this mechanism.  Private data can be allocated at
-any time during an object's life cycle and callbacks are available to initialize and clean
-up allocated space.</para>
+type <type>PrivateRec</type> supports this mechanism.  Some structures allow
+allocating space for private data after some objects have been created, others
+require all space allocations be registered before any objects of that type
+are created.  <filename class="headerfile">Xserver/include/privates.h</filename>
+lists which of these cases applies to each structure containing
+<structfield>devPrivates</structfield>.</para>
+
+<para>
+To request private space, use
+<blockquote><programlisting>
+	Bool dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
+</programlisting></blockquote>
+The first argument is a pointer to a <type>DevPrivateKeyRec</type> which
+will serve as the unique identifier for the private data.  Typically this is
+the address of a static <type>DevPrivateKeyRec</type> in your code.
+The second argument is the class of objects for which this key will apply.
+The third argument is the size of the space being requested, or
+<constant>0</constant> to only allocate a pointer that the caller will manage.
+If space is requested, this space will be automatically freed when the object
+is destroyed.  Note that a call to <function>dixSetPrivate</function>
+that changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
+The function returns <literal>TRUE</literal> unless memory allocation fails.
+If the function is called more than once on the same key, all calls must use
+the same value for <type>size</type> or the server will abort.</para>
+
+<para>
+To request private space and have the server manage the key, use
+<blockquote><programlisting>
+	DevPrivateKey dixCreatePrivateKey(DevPrivateType type, unsigned size);
+</programlisting></blockquote>
+The <parameter>type</parameter> and <parameter>size</parameter> arguments are
+the same as those to <function>dixRegisterPrivateKey</function> but this
+function allocates a <type>DevPrivateKeyRec</type> and returns a pointer to it
+instead of requiring the caller to pass a pointer to an existing structure.
+The server will free it automatically when the privates system is restarted
+at server reset time.</para>
+
 <para>
 To attach a piece of private data to an object, use:
 <blockquote><programlisting>
-	int dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
+	void dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
 </programlisting></blockquote>
-The first argument is the address of the <structfield>devPrivates</structfield> field
-in the target structure.  This field is managed privately by the DIX layer and
-should not be directly modified.  The second argument is some address value which
-will serve as the unique identifier for the private data.  Typically this is the address
-of some global variable in your code.  Only one piece of data with a given key can be attached to an object.  However, you
-can use the same key to store data in any object that supports the devPrivates mechanism.  The third
-argument is the value to store.</para>
+The first argument is the address of the <structfield>devPrivates</structfield>
+field in the target structure.  This field is managed privately by the DIX
+layer and should not be directly modified.  The second argument is a pointer
+to the <type>DevPrivateKeyRec</type> which you registered with
+<function>dixRegisterPrivateKey</function> or allocated with
+<function>dixCreatePrivateKey</function>.  Only one
+piece of data with a given key can be attached to an object, and in most cases
+each key is specific to the type of object it was registered for.   (An
+exception is the PRIVATE_XSELINUX class which applies to multiple object types.)
+The third argument is the value to store.</para>
 <para>
-If private data with the given key is already associated with the object, <function>dixSetPrivate</function> will
-overwrite the old value with the new one.  Otherwise, new space will be allocated to hold the pointer value.
-The function returns <literal>TRUE</literal> unless memory allocation fails, but note that since memory allocation only
-occurs on the first reference to the private data, all subsequent calls are guaranteed to succeed.</para>
+If private data with the given key is already associated with the object,
+<function>dixSetPrivate</function> will overwrite the old value with the
+new one.</para>
 
 <para>
 To look up a piece of private data, use one of:
@@ -4842,56 +4885,22 @@ To look up a piece of private data, use one of:
 	pointer *dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
 </programlisting></blockquote>
 The first argument is the address of the <structfield>devPrivates</structfield> field
-in the target structure.  The second argument is the key to look up.  If private data with the given key is already associated
-with the object, <function>dixLookupPrivate</function> will return the stored pointer value while <function>dixLookupPrivateAddr</function>
-will return the address of the stored pointer.  Otherwise, new space will be first allocated to hold the pointer value
-and it will be initialized to NULL.  Both functions return <literal>NULL</literal> if memory allocation fails, but note that
-since memory allocation only occurs on the first reference to the private data, all subsequent calls are guaranteed to succeed.</para>
-
-<para>
-To request pre-allocated private space, use
-<blockquote><programlisting>
-	int dixRequestPrivate(const DevPrivateKey key, unsigned size)
-</programlisting></blockquote>
-The first argument is the key for which space is being requested.  The second argument is the size of the space being requested.
-After this function has been called,
-future calls to <function>dixLookupPrivate</function> or <function>dixLookupPrivateAddr</function> that cause the private pointer
-to be initially allocated will also allocate <varname>size</varname> bytes of space cleared to zero and initialize the private pointer to point
-to this space instead of <literal>NULL</literal>.  This space will be automatically freed.  Note that a call to <function>dixSetPrivate</function>
-that changes the pointer value may cause the space to be unreachable by the caller, however it will still be automatically freed.
-The function returns <literal>TRUE</literal> unless memory allocation fails.  If the function is called more than once, the largest value
-of <type>size</type> is used.</para>
-
-<para>
-To set callbacks for initializing and cleaning up private space, use
-<blockquote><programlisting>
-	typedef struct {
-		DevPrivateKey key;
-		pointer *value;
-	} PrivateCallbackRec;
-
-	int dixRegisterPrivateInitFunc(const DevPrivateKey key,
-		CallbackProcPtr callback,
-		pointer userdata)
-	int dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
-		CallbackProcPtr callback,
-		pointer userdata)
-</programlisting></blockquote>
-The first argument is the key for which the callbacks are being registered.  The second argument is the callback function.  The third argument
-will be passed as the user data argument to the callback function when it is called.  The call data argument to the callback is a pointer to
-a structure of type <type>PrivateCallbackRec</type>.</para>
-<para>
-The init callback is called immediately after new private space has been allocated for the given key.  The delete callback is called immediately
-before the private space is freed when the object is being destroyed.  The <type>PrivateCallbackRec</type> structure contains the devPrivate key
-and the address of the private pointer.  The init callback may be used to initialize any pre-allocated space requested by
-<function>dixRequestPrivate</function>, while the delete callback may be used to free any data stored there.  However the callbacks are called even
-if no pre-allocated space was requested.</para>
-
-<para>
-When implementing new server resource objects that support devPrivates, there are three steps to perform:
-Declare a field of type <type>PrivateRec *</type> in your structure;
+in the target structure.  The second argument is the key to look up.
+If a non-zero size was given when the key was registered, or if private data
+with the given key is already associated with the object, then
+<function>dixLookupPrivate</function> will return the pointer value
+while <function>dixLookupPrivateAddr</function>
+will return the address of the pointer.</para>
+
+<para>
+When implementing new server resource objects that support devPrivates, there
+are four steps to perform:
+Add a type value to the <type>DevPrivateType</type> enum in
+<filename class="headerfile">Xserver/include/privates.h</filename>,
+declare a field of type <type>PrivateRec *</type> in your structure;
 initialize this field to <literal>NULL</literal> when creating any objects; and
-call the <function>dixFreePrivates</function> function, passing in the field value, when freeing any objects.</para>
+when freeing any objects call the <function>dixFreePrivates</function> or
+<function>dixFreeObjectWithPrivates</function> function.</para>
 </section>
 <section>
   <title>Wrappers</title>
commit 40d598a4f84091db743ceef4d60752bb910c3e56
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Jul 22 23:57:02 2010 -0700

    Correct function name in dixRegisterPrivateKey comments
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Patrick E. Kane <pekane52 at gmail.com>

diff --git a/include/privates.h b/include/privates.h
index 5ba9358..d3c0e13 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -81,10 +81,10 @@ typedef struct _DevPrivateKeyRec {
  * you can get the address of the extra space and store whatever data you like
  * there.
  *
- * You may call dixRegisterPrivate more than once on the same key, but the
+ * You may call dixRegisterPrivateKey more than once on the same key, but the
  * size and type must match or the server will abort.
  *
- * dixRegisterPrivateIndex returns FALSE if it fails to allocate memory
+ * dixRegisterPrivateKey returns FALSE if it fails to allocate memory
  * during its operation.
  */
 extern _X_EXPORT Bool
commit 8d7b7a0d71e0b89321b3341b781bc8845386def6
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu Jul 29 20:36:25 2010 -0400

    Set DamageSetReportAfterOp to true for the damage extension
    
    Change the damage extension reporter to queue up events after we chain
    to the wrapped functions.  Damage events are typically sent out after
    the rendering happens anyway, since we submit batch buffers from the
    flush callback chain and then flush client io buffers.  Compositing
    managers relie on this order, and there is no way we could reliably
    provide damage events to clients before the rendering happens anyway.
    
    By queueing up the damage events before the rendering happens, there's
    a risk that the client io buffer may overflow and send the damage
    events to the client before the driver has even seen the rendering
    request.  Reporting damage events after the rendering fixes this
    corner case and better corresponds with how we expect this to work.
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/damageext/damageext.c b/damageext/damageext.c
index f5265dd..b4bb478 100644
--- a/damageext/damageext.c
+++ b/damageext/damageext.c
@@ -217,6 +217,7 @@ ProcDamageCreate (ClientPtr client)
     if (!AddResource (stuff->damage, DamageExtType, (pointer) pDamageExt))
 	return BadAlloc;
 
+    DamageSetReportAfterOp (pDamageExt->pDamage, TRUE);
     DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage);
 
     if (pDrawable->type == DRAWABLE_WINDOW)
commit c65f610e12f9df168d5639534ed3c2bd40afffc8
Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu Jul 29 18:52:35 2010 -0400

    Always call the flush callback chain when we flush client buffers
    
    We were missing the callback in a couple of places.  Drivers may use
    the flush callback to submit batched up rendering before events (for
    example, damage events) are sent out, to ensure that the rendering
    has been queued when the client receives the event.
    
    Signed-off-by: Kristian Høgsberg <krh at bitplanet.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/os/connection.c b/os/connection.c
index c143fb6..77910be 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -1033,6 +1033,9 @@ CloseDownConnection(ClientPtr client)
 {
     OsCommPtr oc = (OsCommPtr)client->osPrivate;
 
+    if (FlushCallback)
+	CallCallbacks(&FlushCallback, NULL);
+
     if (oc->output && oc->output->count)
 	FlushClient(client, oc, (char *)NULL, 0);
 #ifdef XDMCP
diff --git a/os/io.c b/os/io.c
index b5f98b7..e2df2e3 100644
--- a/os/io.c
+++ b/os/io.c
@@ -819,6 +819,10 @@ WriteToClient (ClientPtr who, int count, const void *__buf)
 	  CriticalOutputPending = FALSE;
 	  NewOutputPending = FALSE;
 	}
+
+	if (FlushCallback)
+	    CallCallbacks(&FlushCallback, NULL);
+
 	return FlushClient(who, oc, buf, count);
     }
 


More information about the Xquartz-changes mailing list