xserver: Branch 'xorg-server-1.5-apple' - 19 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Wed Oct 8 18:44:01 PDT 2008


 dix/getevents.c                     |    6 -
 dix/privates.c                      |  209 ++++++++++++++++++------------------
 hw/xfree86/dixmods/extmod/xf86dga.c |    7 -
 hw/xfree86/int10/helper_exec.c      |   15 --
 hw/xfree86/modes/xf86Crtc.c         |    3 
 hw/xquartz/GL/Makefile.am           |    8 +
 hw/xquartz/GL/capabilities.c        |  108 ++++++++++++++++++
 hw/xquartz/GL/capabilities.h        |   37 ++++++
 hw/xquartz/GL/visualConfigs.c       |  166 ++++++++++++++++++++++++++++
 hw/xquartz/GL/visualConfigs.h       |   28 ++++
 hw/xquartz/X11Application.h         |    1 
 hw/xquartz/X11Application.m         |   10 -
 hw/xquartz/X11Controller.m          |    6 -
 hw/xquartz/darwin.c                 |    8 +
 hw/xquartz/darwinEvents.c           |   11 -
 hw/xquartz/pbproxy/Makefile.am      |    2 
 hw/xquartz/quartz.c                 |  118 +++++++++++++++-----
 hw/xquartz/quartz.h                 |    3 
 hw/xquartz/quartzCommon.h           |    1 
 include/privates.h                  |    2 
 miext/rootless/rootlessCommon.h     |   12 +-
 miext/rootless/rootlessScreen.c     |   43 +++++++
 miext/rootless/rootlessWindow.c     |  102 +++++++++++++++++
 xkb/XKBMisc.c                       |   13 +-
 xkb/xkb.c                           |   17 --
 xkb/xkbUtils.c                      |   39 +++++-
 26 files changed, 781 insertions(+), 194 deletions(-)

New commits:
commit 42d14545072ab7c5fdef2abeba2b309a7a794210
Merge: d039c05... ca65981...
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Wed Oct 8 18:43:55 2008 -0700

    Merge branch 'server-1.5-branch' into xorg-server-1.5-apple

diff --cc dix/getevents.c
index 685cd8b,1e0edbf..61d727b
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@@ -427,10 -424,10 +424,13 @@@ GetKeyboardValuatorEvents(xEvent *event
  
      if (key_code < 8 || key_code > 255)
          return 0;
 +    
 +    map = pDev->key->curKeySyms.map;
 +    sym = map[key_code * pDev->key->curKeySyms.mapWidth];
  
+     sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
+               * pDev->key->curKeySyms.mapWidth];
+ 
      if (pDev->coreEvents)
          numEvents = 2;
      else
commit d039c05b1f1473e061abb8461292ae936900f286
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Wed Oct 8 18:39:41 2008 -0700

    XQuartz: Some motion made towards supporting fullscreen.
    (cherry picked from commit 99be3d68b64059caada739a373e5e01844c776e0)

diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h
index 0caaba8..4335abc 100644
--- a/hw/xquartz/X11Application.h
+++ b/hw/xquartz/X11Application.h
@@ -81,6 +81,7 @@ extern int quartzHasRoot, quartzEnableRootless;
 #define PREFS_FAKEBUTTONS           "enable_fake_buttons"
 #define PREFS_SYSBEEP               "enable_system_beep"
 #define PREFS_KEYEQUIVS             "enable_key_equivalents"
+#define PREFS_FULLSCREEN_HOTKEYS    "fullscreen_hotkeys"
 #define PREFS_SYNC_KEYMAP           "sync_keymap"
 #define PREFS_DEPTH                 "depth"
 #define PREFS_NO_AUTH               "no_auth"
diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index f120af0..2d3fa7c 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -625,16 +625,12 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
 	
     quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
                         default:quartzUseSysBeep];
-
-    // TODO: Add fullscreen support
-    //quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
-    //                    default:quartzEnableRootless];
-#ifdef DARWIN_DDX_MISSING
+#if 0
+    quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
+                        default:quartzEnableRootless];
     quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:
 					      @PREFS_FULLSCREEN_HOTKEYS default:
 					      !quartzFullscreenDisableHotkeys];
-    quartzXpluginOptions = [self prefs_get_integer:@PREFS_XP_OPTIONS
-                            default:quartzXpluginOptions];
 #endif
     darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
                          default:darwinFakeButtons];
diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index 2482c05..8513386 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -595,10 +595,8 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
 - (IBAction) enable_fullscreen_changed:sender
 {
   int value = ![enable_fullscreen intValue];
-	
-#ifdef DARWIN_DDX_MISSING
+
   DarwinSendDDXEvent(kXquartzSetRootless, 1, value);
-#endif
 	
   [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value];
   [NSApp prefs_synchronize];
@@ -606,9 +604,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
 
 - (IBAction) toggle_fullscreen:sender
 {
-#ifdef DARWIN_DDX_MISSING
   DarwinSendDDXEvent(kXquartzToggleFullscreen, 0);
-#endif
 }
 
 - (void) set_can_quit:(OSX_BOOL)state
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 9819618..9acc0cc 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -232,27 +232,20 @@ static void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, in
                 
             case kXquartzToggleFullscreen:
                 DEBUG_LOG("kXquartzToggleFullscreen\n");
-#ifdef DARWIN_DDX_MISSING
                 if (quartzEnableRootless) 
                     QuartzSetFullscreen(!quartzHasRoot);
                 else if (quartzHasRoot)
                     QuartzHide();
                 else
-                    QuartzShow();
-#else
-                //      ErrorF("kXquartzToggleFullscreen not implemented\n");               
-#endif
+                    QuartzShow(xe[i].u.keyButtonPointer.rootX,
+                               xe[i].u.keyButtonPointer.rootY);
                 break;
                 
             case kXquartzSetRootless:
                 DEBUG_LOG("kXquartzSetRootless\n");
-#ifdef DARWIN_DDX_MISSING
                 QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0);
                 if (!quartzEnableRootless && !quartzHasRoot)
                     QuartzHide();
-#else
-                //      ErrorF("kXquartzSetRootless not implemented\n");                    
-#endif
                 break;
                 
             case kXquartzSetRootClip:
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index 0635b48..a9c124a 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -61,6 +61,9 @@
 #include <fcntl.h>
 #include <IOKit/pwr_mgt/IOPMLib.h>
 
+#include <rootlessCommon.h>
+#include <Xplugin.h>
+
 #define FAKE_RANDR 1
 
 // Shared global variables for Quartz modes
@@ -75,6 +78,7 @@ DevPrivateKey           quartzScreenKey = &quartzScreenKey;
 int                     aquaMenuBarHeight = 0;
 QuartzModeProcsPtr      quartzProcs = NULL;
 const char             *quartzOpenGLBundle = NULL;
+int                     quartzFullscreenDisableHotkeys = TRUE;
 
 #if defined(RANDR) && !defined(FAKE_RANDR)
 Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
@@ -228,33 +232,27 @@ RREditConnectionInfo (ScreenPtr pScreen)
 }
 #endif
 
-/*
- * QuartzDisplayChangeHandler
- *  Adjust for screen arrangement changes.
- */
-void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents)
-{
+static void QuartzUpdateScreens(void) {
     ScreenPtr pScreen;
     WindowPtr pRoot;
     int x, y, width, height, sx, sy;
     xEvent e;
-
-    DEBUG_LOG("QuartzDisplayChangedHandler(): noPseudoramiXExtension=%d, screenInfo.numScreens=%d\n", noPseudoramiXExtension, screenInfo.numScreens);
+    
     if (noPseudoramiXExtension || screenInfo.numScreens != 1)
     {
         /* FIXME: if not using Xinerama, we have multiple screens, and
-           to do this properly may need to add or remove screens. Which
-           isn't possible. So don't do anything. Another reason why
-           we default to running with Xinerama. */
-
+         to do this properly may need to add or remove screens. Which
+         isn't possible. So don't do anything. Another reason why
+         we default to running with Xinerama. */
+        
         return;
     }
-
+    
     pScreen = screenInfo.screens[0];
-
+    
     PseudoramiXResetScreens();
     quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
-
+    
     dixScreenOrigins[pScreen->myNum].x = x;
     dixScreenOrigins[pScreen->myNum].y = y;
     pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
@@ -266,21 +264,20 @@ void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev,
     if(!QuartzRandRInit(pScreen))
         FatalError("Failed to init RandR extension.\n");
 #endif
-
+    
     DarwinAdjustScreenOrigins(&screenInfo);
     quartzProcs->UpdateScreen(pScreen);
-
+    
     sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
     sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
-
+    
     /* Adjust the root window. */
     pRoot = WindowTable[pScreen->myNum];
     AppleWMSetScreenOrigin(pRoot);
     pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
     miPaintWindow(pRoot, &pRoot->borderClip,  PW_BACKGROUND);
-//    QuartzIgnoreNextWarpCursor();
     DefineInitialRootWindow(pRoot);
-
+    
     /* Send an event for the root reconfigure */
     e.u.u.type = ConfigureNotify;
     e.u.configureNotify.window = pRoot->drawable.id;
@@ -292,12 +289,71 @@ void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev,
     e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
     e.u.configureNotify.override = pRoot->overrideRedirect;
     DeliverEvents(pRoot, &e, 1, NullWindow);
-
+    
 #ifdef FAKE_RANDR
     RREditConnectionInfo(pScreen);
-#endif
+#endif    
 }
 
+/*
+ * QuartzDisplayChangeHandler
+ *  Adjust for screen arrangement changes.
+ */
+void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
+    QuartzUpdateScreens();
+}
+
+void QuartzSetFullscreen(Bool state) {
+    if(quartzHasRoot == state)
+        return;
+    
+    quartzHasRoot = state;
+    
+    xp_disable_update ();
+    
+    if (!quartzHasRoot && !quartzEnableRootless)
+        RootlessHideAllWindows();
+    
+    RootlessUpdateRooted(quartzHasRoot);
+    
+    if (quartzHasRoot && !quartzEnableRootless)
+        RootlessShowAllWindows ();
+    
+    /* Only update screen info when something is visible. Avoids the wm
+     * moving the windows out from under the menubar when it shouldn't
+     */
+    if (quartzHasRoot || quartzEnableRootless)
+        QuartzUpdateScreens();
+    
+    /* Somehow the menubar manages to interfere with our event stream
+     * in fullscreen mode, even though it's not visible. 
+     */
+    
+    X11ApplicationShowHideMenubar(!quartzHasRoot);
+    
+    xp_reenable_update ();
+    
+    if (quartzFullscreenDisableHotkeys)
+        xp_disable_hot_keys(quartzHasRoot);
+}
+
+void QuartzSetRootless(Bool state) {
+    if(quartzEnableRootless == state)
+        return;
+    
+    quartzEnableRootless = state;
+    
+    if (!quartzEnableRootless && !quartzHasRoot) {
+        xp_disable_update();
+        RootlessHideAllWindows();
+        xp_reenable_update();
+    } else if (quartzEnableRootless && !quartzHasRoot) {
+        xp_disable_update();
+        RootlessShowAllWindows();
+        QuartzUpdateScreens();
+        xp_reenable_update();
+    }
+}
 
 /*
  * QuartzShow
@@ -311,14 +367,18 @@ void QuartzShow(
 {
     int i;
 
-    if (!quartzServerVisible) {
-        quartzServerVisible = TRUE;
-        for (i = 0; i < screenInfo.numScreens; i++) {
-            if (screenInfo.screens[i]) {
-                quartzProcs->ResumeScreen(screenInfo.screens[i], x, y);
-            }
+    if (quartzServerVisible)
+        return;
+    
+    quartzServerVisible = TRUE;
+    for (i = 0; i < screenInfo.numScreens; i++) {
+        if (screenInfo.screens[i]) {
+            quartzProcs->ResumeScreen(screenInfo.screens[i], x, y);
         }
     }
+    
+    if (!quartzEnableRootless)
+        QuartzSetFullscreen(TRUE);
 }
 
 
@@ -339,6 +399,8 @@ void QuartzHide(void)
             }
         }
     }
+    
+    QuartzSetFullscreen(FALSE);
     quartzServerVisible = FALSE;
 }
 
diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h
index 1b6d71f..8b04b79 100644
--- a/hw/xquartz/quartz.h
+++ b/hw/xquartz/quartz.h
@@ -137,4 +137,7 @@ void QuartzShow(int x, int y); // (x, y) = cursor loc
 void QuartzHide(void);
 void QuartzSetRootClip(BOOL enable);
 void QuartzSpaceChanged(uint32_t space_id);
+
+void QuartzSetFullscreen(Bool state);
+void QuartzSetRootless(Bool state);
 #endif
diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h
index e63c2b7..a17ebb2 100644
--- a/hw/xquartz/quartzCommon.h
+++ b/hw/xquartz/quartzCommon.h
@@ -60,6 +60,7 @@ extern int              quartzUseSysBeep;
 extern int              focusOnNewWindow;
 extern int              quartzUseAGL;
 extern int              quartzEnableKeyEquivalents;
+extern int              quartzFullscreenDisableHotkeys;
 
 // Other shared data
 extern int              quartzServerVisible;
diff --git a/miext/rootless/rootlessCommon.h b/miext/rootless/rootlessCommon.h
index 271441b..a8c2878 100644
--- a/miext/rootless/rootlessCommon.h
+++ b/miext/rootless/rootlessCommon.h
@@ -277,7 +277,8 @@ Bool RootlessResolveColormap (ScreenPtr pScreen, int first_color,
 void RootlessFlushWindowColormap (WindowPtr pWin);
 void RootlessFlushScreenColormaps (ScreenPtr pScreen);
 
-RootlessColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors);
+// xp_error
+int RootlessColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors);
 
 // Move a window to its proper location on the screen.
 void RootlessRepositionWindow(WindowPtr pWin);
@@ -285,4 +286,13 @@ void RootlessRepositionWindow(WindowPtr pWin);
 // Move the window to it's correct place in the physical stacking order.
 void RootlessReorderWindow(WindowPtr pWin);
 
+void RootlessScreenExpose (ScreenPtr pScreen);
+void RootlessHideAllWindows (void);
+void RootlessShowAllWindows (void);
+void RootlessUpdateRooted (Bool state);
+
+void RootlessEnableRoot (ScreenPtr pScreen);
+void RootlessDisableRoot (ScreenPtr pScreen);
+
+
 #endif /* _ROOTLESSCOMMON_H */
diff --git a/miext/rootless/rootlessScreen.c b/miext/rootless/rootlessScreen.c
index 5031858..2f536ed 100644
--- a/miext/rootless/rootlessScreen.c
+++ b/miext/rootless/rootlessScreen.c
@@ -471,6 +471,34 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
     return result;
 }
 
+expose_1 (WindowPtr pWin)
+{
+    WindowPtr pChild;
+    
+    if (!pWin->realized)
+        return;
+    
+    (*pWin->drawable.pScreen->PaintWindowBackground) (pWin, &pWin->borderClip,
+                                                      PW_BACKGROUND);
+    
+    /* FIXME: comments in windowstr.h indicate that borderClip doesn't
+     include subwindow visibility. But I'm not so sure.. so we may
+     be exposing too much.. */
+    
+    miSendExposures (pWin, &pWin->borderClip,
+                     pWin->drawable.x, pWin->drawable.y);
+    
+    for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
+        expose_1 (pChild);
+}
+
+void
+RootlessScreenExpose (ScreenPtr pScreen)
+{
+    expose_1 (WindowTable[pScreen->myNum]);
+}
+
+
 ColormapPtr
 RootlessGetColormap (ScreenPtr pScreen)
 {
@@ -716,3 +744,18 @@ Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
 
     return TRUE;
 }
+
+void RootlessUpdateRooted (Bool state) {
+    int i;
+    
+    if (!state)
+    {
+        for (i = 0; i < screenInfo.numScreens; i++)
+            RootlessDisableRoot (screenInfo.screens[i]);
+    }
+    else
+    {
+        for (i = 0; i < screenInfo.numScreens; i++)
+            RootlessEnableRoot (screenInfo.screens[i]);
+    }
+}
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index 6c25499..d91db0f 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -1589,3 +1589,105 @@ RootlessOrderAllWindows (void)
     }
     RL_DEBUG_MSG("RootlessOrderAllWindows() done");
 }
+
+void
+RootlessEnableRoot (ScreenPtr pScreen)
+{
+    WindowPtr pRoot;
+    pRoot = WindowTable[pScreen->myNum];
+    
+    RootlessEnsureFrame (pRoot);
+    (*pScreen->ClearToBackground) (pRoot, 0, 0, 0, 0, TRUE);
+    RootlessReorderWindow (pRoot);
+}
+
+void
+RootlessDisableRoot (ScreenPtr pScreen)
+{
+    WindowPtr pRoot;
+    RootlessWindowRec *winRec;
+    
+    pRoot = WindowTable[pScreen->myNum];
+    winRec = WINREC (pRoot);
+    
+    if (winRec != NULL)
+    {
+        RootlessDestroyFrame (pRoot, winRec);
+        DeleteProperty (pRoot, xa_native_window_id ());
+    }
+}
+
+void
+RootlessHideAllWindows (void)
+{
+    int i;
+    ScreenPtr pScreen;
+    WindowPtr pWin;
+    RootlessWindowRec *winRec;
+    xp_window_changes wc;
+    
+    if (windows_hidden)
+        return;
+    
+    windows_hidden = TRUE;
+    
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+        pScreen = screenInfo.screens[i];
+        pWin = WindowTable[i];
+        if (pScreen == NULL || pWin == NULL)
+            continue;
+        
+        for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib)
+        {
+            if (!pWin->realized)
+                continue;
+            
+            RootlessStopDrawing (pWin, FALSE);
+            
+            winRec = WINREC (pWin);
+            if (winRec != NULL)
+            {
+                wc.stack_mode = XP_UNMAPPED;
+                wc.sibling = 0;
+                configure_window ((xp_window_id)winRec->wid, XP_STACKING, &wc);
+            }
+        }
+    }
+}
+
+void
+RootlessShowAllWindows (void)
+{
+    int i;
+    ScreenPtr pScreen;
+    WindowPtr pWin;
+    RootlessWindowRec *winRec;
+    
+    if (!windows_hidden)
+        return;
+    
+    windows_hidden = FALSE;
+    
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+        pScreen = screenInfo.screens[i];
+        pWin = WindowTable[i];
+        if (pScreen == NULL || pWin == NULL)
+            continue;
+        
+        for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib)
+        {
+            if (!pWin->realized)
+                continue;
+            
+            winRec = RootlessEnsureFrame (pWin);
+            if (winRec == NULL)
+                continue;
+            
+            RootlessReorderWindow (pWin);
+        }
+        
+        RootlessScreenExpose (pScreen);
+    }
+}
commit 4915d8885858be3c4a4c27c4700a1cd924364688
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Tue Oct 7 11:39:08 2008 -0700

    XQuartz: Fixed EXTRA_DIST for new GL files.
    (cherry picked from commit a11c9052030b44045f037050a5825256b539ed50)

diff --git a/hw/xquartz/GL/Makefile.am b/hw/xquartz/GL/Makefile.am
index c528d2a..8f4478f 100644
--- a/hw/xquartz/GL/Makefile.am
+++ b/hw/xquartz/GL/Makefile.am
@@ -13,3 +13,7 @@ libCGLCore_la_SOURCES = \
 	indirect.c \
 	capabilities.c \
 	visualConfigs.c
+
+EXTRA_DIST = \
+	capabilities.h \
+	visualConfigs.h
commit 1953956be88654508e38527b90c0c41a157460bc
Author: George Staplin <georgestaplin at george-staplins-mac-pro.local>
Date:   Tue Oct 7 12:12:38 2008 -0600

    XQuartz: GL: setVisualConfigs() copied the behavior of indirect.c which is wrong, with regard to the handling of xcalloc failure.
    
    Use ErrorF for an error message after an xcalloc failure, and return instead of falling through to GlxSetVisualConfigs, or abort()ing at the test branch.
    (cherry picked from commit 1056700971fd5c034396ed6dbea15e092f0c6332)

diff --git a/hw/xquartz/GL/visualConfigs.c b/hw/xquartz/GL/visualConfigs.c
index 821fad2..e46d628 100644
--- a/hw/xquartz/GL/visualConfigs.c
+++ b/hw/xquartz/GL/visualConfigs.c
@@ -86,65 +86,75 @@ void setVisualConfigs(void) {
 
       2 iterations for accum (on and off (with an accum color size of 16)).
      */
-    
 
     numConfigs = ((enable_stereo && caps->stereo) ? 2 : 1) * 2 * 
 	(caps->aux_buffers ? 2 : 1) * (caps->buffers) * 2 * 2;
 
     visualConfigs = xcalloc(sizeof(*visualConfigs), numConfigs);
+
+    if(NULL == visualConfigs) {
+	ErrorF("xcalloc failure when allocating visualConfigs\n");
+	return;
+    }
+    
     visualPrivates = xcalloc(sizeof(void *), numConfigs);
 
-    if (NULL != visualConfigs) {
-        i = 0; /* current buffer */
-        for (stereo = 0; stereo < ((enable_stereo && caps->stereo) ? 2 : 1); ++stereo) {
-	    for (depth = 0; depth < 2; ++depth) {
-		for (aux = 0; aux < (caps->aux_buffers ? 2 : 1); ++aux) {
-		    for (buffers = 0; buffers < caps->buffers; ++buffers) {
-			for (stencil = 0; stencil < 2; ++stencil) {
-			    for (accum = 0; accum < 2; ++accum) {
-				visualConfigs[i].vid = -1;
-				visualConfigs[i].class = -1;
-				visualConfigs[i].rgba = TRUE;
-				visualConfigs[i].redSize = -1;
-				visualConfigs[i].greenSize = -1;
-				visualConfigs[i].blueSize = -1;
-				visualConfigs[i].redMask = -1;
-				visualConfigs[i].greenMask = -1;
-				visualConfigs[i].blueMask = -1;
-				visualConfigs[i].alphaMask = 0;
-				if (accum) {
-				    visualConfigs[i].accumRedSize = 16;
-				    visualConfigs[i].accumGreenSize = 16;
-				    visualConfigs[i].accumBlueSize = 16;
-				    visualConfigs[i].accumAlphaSize = 16;
-				} else {
-				    visualConfigs[i].accumRedSize = 0;
-				    visualConfigs[i].accumGreenSize = 0;
-				    visualConfigs[i].accumBlueSize = 0;
-				    visualConfigs[i].accumAlphaSize = 0;
-				}
-				visualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE;
-				visualConfigs[i].stereo = stereo ? TRUE : FALSE;
-				visualConfigs[i].bufferSize = -1;
-                    
-				visualConfigs[i].depthSize = depth ? 24 : 0;
-				visualConfigs[i].stencilSize = stencil ? 8 : 0;
-				visualConfigs[i].auxBuffers = aux ? caps->aux_buffers : 0;
-				visualConfigs[i].level = 0;
-				visualConfigs[i].visualRating = GLX_NONE_EXT;
-				visualConfigs[i].transparentPixel = 0;
-				visualConfigs[i].transparentRed = 0;
-				visualConfigs[i].transparentGreen = 0;
-				visualConfigs[i].transparentBlue = 0;
-				visualConfigs[i].transparentAlpha = 0;
-				visualConfigs[i].transparentIndex = 0;
-				++i;
+    if(NULL == visualPrivates) {
+	ErrorF("xcalloc failure when allocating visualPrivates");
+	xfree(visualConfigs);
+	return;
+    }
+
+ 
+    i = 0; /* current buffer */
+    for (stereo = 0; stereo < ((enable_stereo && caps->stereo) ? 2 : 1); ++stereo) {
+	for (depth = 0; depth < 2; ++depth) {
+	    for (aux = 0; aux < (caps->aux_buffers ? 2 : 1); ++aux) {
+		for (buffers = 0; buffers < caps->buffers; ++buffers) {
+		    for (stencil = 0; stencil < 2; ++stencil) {
+			for (accum = 0; accum < 2; ++accum) {
+			    visualConfigs[i].vid = -1;
+			    visualConfigs[i].class = -1;
+			    visualConfigs[i].rgba = TRUE;
+			    visualConfigs[i].redSize = -1;
+			    visualConfigs[i].greenSize = -1;
+			    visualConfigs[i].blueSize = -1;
+			    visualConfigs[i].redMask = -1;
+			    visualConfigs[i].greenMask = -1;
+			    visualConfigs[i].blueMask = -1;
+			    visualConfigs[i].alphaMask = 0;
+			    if (accum) {
+				visualConfigs[i].accumRedSize = 16;
+				visualConfigs[i].accumGreenSize = 16;
+				visualConfigs[i].accumBlueSize = 16;
+				visualConfigs[i].accumAlphaSize = 16;
+			    } else {
+				visualConfigs[i].accumRedSize = 0;
+				visualConfigs[i].accumGreenSize = 0;
+				visualConfigs[i].accumBlueSize = 0;
+				visualConfigs[i].accumAlphaSize = 0;
 			    }
+			    visualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE;
+			    visualConfigs[i].stereo = stereo ? TRUE : FALSE;
+			    visualConfigs[i].bufferSize = -1;
+			    
+			    visualConfigs[i].depthSize = depth ? 24 : 0;
+			    visualConfigs[i].stencilSize = stencil ? 8 : 0;
+			    visualConfigs[i].auxBuffers = aux ? caps->aux_buffers : 0;
+			    visualConfigs[i].level = 0;
+			    visualConfigs[i].visualRating = GLX_NONE_EXT;
+			    visualConfigs[i].transparentPixel = 0;
+			    visualConfigs[i].transparentRed = 0;
+			    visualConfigs[i].transparentGreen = 0;
+			    visualConfigs[i].transparentBlue = 0;
+			    visualConfigs[i].transparentAlpha = 0;
+			    visualConfigs[i].transparentIndex = 0;
+			    ++i;
 			}
 		    }
 		}
 	    }
-        }
+	}
     }
 
     if (i != numConfigs) {
commit 3ea371c9e50b1f101ab4eae0f99b4d4d7bcd33c2
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Wed Oct 8 18:43:10 2008 -0700

    XQuartz: Call setVisualConfigs in InitOutput, and only when GLXEXT is defined.
    (cherry picked from commit 97173d4eda142c73bb975cc05225b791778f85af)

diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index ad5a543..2b318d3 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -229,8 +229,6 @@ static Bool DarwinAddScreen(int index, ScreenPtr pScreen, int argc, char **argv)
 
     miSetPixmapDepths();
 
-    setVisualConfigs();
-
     // machine independent screen init
     // setup _Screen structure in pScreen
     if (monitorResolution)
@@ -595,6 +593,10 @@ void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
     for (i = 0; i < NUMFORMATS; i++)
         pScreenInfo->formats[i] = formats[i];
 
+#ifdef GLXEXT
+    setVisualConfigs();    
+#endif
+
     // Discover screens and do mode specific initialization
     QuartzInitOutput(argc, argv);
 
commit e2655ab18895950b1c936af339284b94c6597cb5
Author: George Staplin <georgestaplin at george-staplins-mac-pro.local>
Date:   Tue Oct 7 11:31:48 2008 -0600

    XQuartz: GL: Add the proper license information to the new files, and add more commentary to setVisualConfigs().
    (cherry picked from commit 190a3d5e5de9915931928fb8e6da88bb9644cda4)

diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
index 3a54025..479fc93 100644
--- a/hw/xquartz/GL/capabilities.c
+++ b/hw/xquartz/GL/capabilities.c
@@ -1,3 +1,25 @@
+/*
+ * Copyright (c) 2008 Apple Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <OpenGL/OpenGL.h>
diff --git a/hw/xquartz/GL/capabilities.h b/hw/xquartz/GL/capabilities.h
index 74487be..6a026cf 100644
--- a/hw/xquartz/GL/capabilities.h
+++ b/hw/xquartz/GL/capabilities.h
@@ -1,3 +1,25 @@
+/*
+ * Copyright (c) 2008 Apple Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifndef CAPABILITIES_H
 #define CAPABILITIES_H
 
diff --git a/hw/xquartz/GL/visualConfigs.c b/hw/xquartz/GL/visualConfigs.c
index 05dfa19..821fad2 100644
--- a/hw/xquartz/GL/visualConfigs.c
+++ b/hw/xquartz/GL/visualConfigs.c
@@ -1,3 +1,33 @@
+/*
+ * Copyright (c) 2007, 2008 Apple Inc.
+ * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
+ * Copyright (c) 2002 Greg Parker. All Rights Reserved.
+ *
+ * Portions of this file are copied from Mesa's xf86glx.c,
+ * which contains the following copyright:
+ *
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
 #endif
@@ -28,6 +58,7 @@
 
 extern BOOL enable_stereo;
 
+/* Based originally on code from indirect.c which was based on code from i830_dri.c. */
 void setVisualConfigs(void) {
     int numConfigs = 0;
     __GLXvisualConfig *visualConfigs = NULL;
@@ -41,14 +72,21 @@ void setVisualConfigs(void) {
 	return;
     }
     
-    /* count num configs:
-        2 stereo (on, off) (optional)
-        2 Z buffer (0, 24 bit)
-        2 AUX buffer (0, 2)
-        2 buffers (single, double)
-        2 stencil (0, 8 bit)
-        2 accum (0, 64 bit)
-        = 64 configs with stereo, or 32 without */
+    /*
+      caps->stereo is 0 or 1, but we need at least 1 iteration of the loop, so we treat
+      a true caps->stereo as 2.
+
+      The depth size is 0 or 24.  Thus we do 2 iterations for that.
+
+      caps->aux_buffers (when available/non-zero) result in 2 iterations instead of 1.
+
+      caps->buffers indicates whether we have single or double buffering.
+      
+      2 iterations for stencil (on and off (with a stencil size of 8)).
+
+      2 iterations for accum (on and off (with an accum color size of 16)).
+     */
+    
 
     numConfigs = ((enable_stereo && caps->stereo) ? 2 : 1) * 2 * 
 	(caps->aux_buffers ? 2 : 1) * (caps->buffers) * 2 * 2;
@@ -89,7 +127,7 @@ void setVisualConfigs(void) {
 				visualConfigs[i].stereo = stereo ? TRUE : FALSE;
 				visualConfigs[i].bufferSize = -1;
                     
-				visualConfigs[i].depthSize = depth? 24 : 0;
+				visualConfigs[i].depthSize = depth ? 24 : 0;
 				visualConfigs[i].stencilSize = stencil ? 8 : 0;
 				visualConfigs[i].auxBuffers = aux ? caps->aux_buffers : 0;
 				visualConfigs[i].level = 0;
diff --git a/hw/xquartz/GL/visualConfigs.h b/hw/xquartz/GL/visualConfigs.h
index f9cd886..b9e6ae7 100644
--- a/hw/xquartz/GL/visualConfigs.h
+++ b/hw/xquartz/GL/visualConfigs.h
@@ -1,3 +1,25 @@
+/*
+ * Copyright (c) 2008 Apple Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifndef VISUAL_CONFIGS_H
 #define VISUAL_CONFIGS_H
 
commit cb19d0faecade75252974fa6c1fe18de45486e06
Author: George Staplin <georgestaplin at george-staplins-mac-pro.local>
Date:   Mon Oct 6 18:05:12 2008 -0600

    XQuartz: GL: Add the new C code to the Makefile.am.
    
    Commit the darwin.c changes I missed in the last commit, for calling
    setVisualConfigs().
    (cherry picked from commit eb3c014e1710bf0b93bda10ddb9b795cd150d02d)

diff --git a/hw/xquartz/GL/Makefile.am b/hw/xquartz/GL/Makefile.am
index 450ee5c..c528d2a 100644
--- a/hw/xquartz/GL/Makefile.am
+++ b/hw/xquartz/GL/Makefile.am
@@ -10,4 +10,6 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/miext/damage
 
 libCGLCore_la_SOURCES = \
-	indirect.c
+	indirect.c \
+	capabilities.c \
+	visualConfigs.c
diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index fcb74e5..ad5a543 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -77,6 +77,9 @@
 #include "quartz.h"
 //#include "darwinClut8.h"
 
+#include "GL/visualConfigs.h"
+
+
 #ifdef ENABLE_DEBUG_LOG
 FILE *debug_log_fp = NULL;
 #endif
@@ -180,7 +183,6 @@ static Bool DarwinSaveScreen(ScreenPtr pScreen, int on)
     return TRUE;
 }
 
-
 /*
  * DarwinAddScreen
  *  This is a callback from dix during AddScreen() from InitOutput().
@@ -227,6 +229,8 @@ static Bool DarwinAddScreen(int index, ScreenPtr pScreen, int argc, char **argv)
 
     miSetPixmapDepths();
 
+    setVisualConfigs();
+
     // machine independent screen init
     // setup _Screen structure in pScreen
     if (monitorResolution)
commit b6eddd80a4a83f3937ff406a655febb9373bdc71
Author: George Staplin <georgestaplin at george-staplins-mac-pro.local>
Date:   Mon Oct 6 18:01:23 2008 -0600

    XQuartz: GL: Provide code for getting the capabilities of the underlying system's CGL.
    
    Add a setVisualConfigs that is called before the fbScreenInit, to setup the __GLXvisualConfigs.
    (cherry picked from commit fc86f9e4482043eca76d9d7a96e166be1aabf674)

diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
new file mode 100644
index 0000000..3a54025
--- /dev/null
+++ b/hw/xquartz/GL/capabilities.c
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#include <OpenGL/glext.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "capabilities.h"
+
+//#define DIAGNOSTIC 0
+
+static void handleBufferModes(struct glCapabilities *cap, GLint bufferModes) {
+    if(bufferModes & kCGLStereoscopicBit) {
+	cap->stereo = true;
+    }
+
+    if(bufferModes & kCGLDoubleBufferBit) {
+	cap->buffers = 2;
+    } else {
+	cap->buffers = 1;
+    }
+}
+
+static void initCapabilities(struct glCapabilities *cap) {
+    cap->stereo = cap->buffers = cap->aux_buffers = 0;
+}
+
+enum {
+    MAX_DISPLAYS = 32
+};
+
+/*Return true if an error occured. */
+bool getGlCapabilities(struct glCapabilities *cap) {
+    CGDirectDisplayID dspys[MAX_DISPLAYS];
+    CGDisplayErr err;
+    CGOpenGLDisplayMask displayMask;
+    CGDisplayCount i, displayCount = 0;
+
+    initCapabilities(cap);
+    
+    err = CGGetActiveDisplayList(MAX_DISPLAYS, dspys, &displayCount);
+    if(err) {
+#ifdef DIAGNOSTIC
+	fprintf(stderr, "CGGetActiveDisplayList %s\n", CGLErrorString (err));
+#endif
+	return true;
+    }
+ 
+    for(i = 0; i < displayCount; ++i) {
+        displayMask = CGDisplayIDToOpenGLDisplayMask(dspys[i]);
+       
+	CGLRendererInfoObj info;
+	GLint numRenderers = 0, r, accelerated = 0, flags = 0, aux = 0;
+    
+	err = CGLQueryRendererInfo (displayMask, &info, &numRenderers);
+        if(!err) {
+            CGLDescribeRenderer (info, 0, kCGLRPRendererCount, &numRenderers);
+            for(r = 0; r < numRenderers; ++r) {
+                // find accelerated renderer (assume only one)
+                CGLDescribeRenderer (info, r, kCGLRPAccelerated, &accelerated);
+                if(accelerated) {
+                    err = CGLDescribeRenderer(info, r, kCGLRPBufferModes, &flags);
+		    if(err) {
+			CGLDestroyRendererInfo(info);
+			return true;
+		    }
+
+		    handleBufferModes(cap, flags);
+
+		    err = CGLDescribeRenderer(info, r, kCGLRPMaxAuxBuffers, &aux);
+		    if(err) {
+			CGLDestroyRendererInfo(info);
+			return true;
+		    }
+
+		    cap->aux_buffers = aux;
+                }
+            }
+	    CGLDestroyRendererInfo(info);
+	}
+    }
+
+    /* No error occured.  We are done. */
+    return false;
+}
diff --git a/hw/xquartz/GL/capabilities.h b/hw/xquartz/GL/capabilities.h
new file mode 100644
index 0000000..74487be
--- /dev/null
+++ b/hw/xquartz/GL/capabilities.h
@@ -0,0 +1,15 @@
+#ifndef CAPABILITIES_H
+#define CAPABILITIES_H
+
+#include <stdbool.h>
+
+struct glCapabilities {
+    int stereo;
+    int aux_buffers;
+    int buffers;
+    /*TODO handle STENCIL and ACCUM*/
+};
+
+bool getGlCapabilities(struct glCapabilities *cap);
+
+#endif
diff --git a/hw/xquartz/GL/visualConfigs.c b/hw/xquartz/GL/visualConfigs.c
new file mode 100644
index 0000000..05dfa19
--- /dev/null
+++ b/hw/xquartz/GL/visualConfigs.c
@@ -0,0 +1,118 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "dri.h"
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/CGLContext.h>
+
+#include <GL/gl.h>
+#include <GL/glxproto.h>
+#include <windowstr.h>
+#include <resource.h>
+#include <GL/glxint.h>
+#include <GL/glxtokens.h>
+#include <scrnintstr.h>
+#include <glxserver.h>
+#include <glxscreens.h>
+#include <glxdrawable.h>
+#include <glxcontext.h>
+#include <glxext.h>
+#include <glxutil.h>
+#include <glxscreens.h>
+#include <GL/internal/glcore.h>
+
+#include "capabilities.h"
+#include "visualConfigs.h"
+
+extern BOOL enable_stereo;
+
+void setVisualConfigs(void) {
+    int numConfigs = 0;
+    __GLXvisualConfig *visualConfigs = NULL;
+    void **visualPrivates = NULL;
+    struct glCapabilities caps[1];
+    int stereo, depth, aux, buffers, stencil, accum;
+    int i = 0; 
+
+    if(getGlCapabilities(caps)) {
+	ErrorF("error from getGlCapabilities()!\n");
+	return;
+    }
+    
+    /* count num configs:
+        2 stereo (on, off) (optional)
+        2 Z buffer (0, 24 bit)
+        2 AUX buffer (0, 2)
+        2 buffers (single, double)
+        2 stencil (0, 8 bit)
+        2 accum (0, 64 bit)
+        = 64 configs with stereo, or 32 without */
+
+    numConfigs = ((enable_stereo && caps->stereo) ? 2 : 1) * 2 * 
+	(caps->aux_buffers ? 2 : 1) * (caps->buffers) * 2 * 2;
+
+    visualConfigs = xcalloc(sizeof(*visualConfigs), numConfigs);
+    visualPrivates = xcalloc(sizeof(void *), numConfigs);
+
+    if (NULL != visualConfigs) {
+        i = 0; /* current buffer */
+        for (stereo = 0; stereo < ((enable_stereo && caps->stereo) ? 2 : 1); ++stereo) {
+	    for (depth = 0; depth < 2; ++depth) {
+		for (aux = 0; aux < (caps->aux_buffers ? 2 : 1); ++aux) {
+		    for (buffers = 0; buffers < caps->buffers; ++buffers) {
+			for (stencil = 0; stencil < 2; ++stencil) {
+			    for (accum = 0; accum < 2; ++accum) {
+				visualConfigs[i].vid = -1;
+				visualConfigs[i].class = -1;
+				visualConfigs[i].rgba = TRUE;
+				visualConfigs[i].redSize = -1;
+				visualConfigs[i].greenSize = -1;
+				visualConfigs[i].blueSize = -1;
+				visualConfigs[i].redMask = -1;
+				visualConfigs[i].greenMask = -1;
+				visualConfigs[i].blueMask = -1;
+				visualConfigs[i].alphaMask = 0;
+				if (accum) {
+				    visualConfigs[i].accumRedSize = 16;
+				    visualConfigs[i].accumGreenSize = 16;
+				    visualConfigs[i].accumBlueSize = 16;
+				    visualConfigs[i].accumAlphaSize = 16;
+				} else {
+				    visualConfigs[i].accumRedSize = 0;
+				    visualConfigs[i].accumGreenSize = 0;
+				    visualConfigs[i].accumBlueSize = 0;
+				    visualConfigs[i].accumAlphaSize = 0;
+				}
+				visualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE;
+				visualConfigs[i].stereo = stereo ? TRUE : FALSE;
+				visualConfigs[i].bufferSize = -1;
+                    
+				visualConfigs[i].depthSize = depth? 24 : 0;
+				visualConfigs[i].stencilSize = stencil ? 8 : 0;
+				visualConfigs[i].auxBuffers = aux ? caps->aux_buffers : 0;
+				visualConfigs[i].level = 0;
+				visualConfigs[i].visualRating = GLX_NONE_EXT;
+				visualConfigs[i].transparentPixel = 0;
+				visualConfigs[i].transparentRed = 0;
+				visualConfigs[i].transparentGreen = 0;
+				visualConfigs[i].transparentBlue = 0;
+				visualConfigs[i].transparentAlpha = 0;
+				visualConfigs[i].transparentIndex = 0;
+				++i;
+			    }
+			}
+		    }
+		}
+	    }
+        }
+    }
+
+    if (i != numConfigs) {
+	ErrorF("numConfigs calculation error in setVisualConfigs!\n");
+	abort();
+    }
+
+    GlxSetVisualConfigs(numConfigs, visualConfigs, visualPrivates);
+}
diff --git a/hw/xquartz/GL/visualConfigs.h b/hw/xquartz/GL/visualConfigs.h
new file mode 100644
index 0000000..f9cd886
--- /dev/null
+++ b/hw/xquartz/GL/visualConfigs.h
@@ -0,0 +1,6 @@
+#ifndef VISUAL_CONFIGS_H
+#define VISUAL_CONFIGS_H
+
+void setVisualConfigs(void);
+
+#endif
commit 3dd6d78fd59be73d0805de13f49a6182b8fc3198
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Oct 4 21:25:50 2008 -0700

    Xquartz: Fix parallel builds
    (cherry picked from commit 1fe7298a3b9a2ed82c612292f9e547cf78f99ae5)

diff --git a/hw/xquartz/pbproxy/Makefile.am b/hw/xquartz/pbproxy/Makefile.am
index 43f7386..fd93ce1 100644
--- a/hw/xquartz/pbproxy/Makefile.am
+++ b/hw/xquartz/pbproxy/Makefile.am
@@ -14,7 +14,7 @@ if !INTEGRATED_XPBPROXY
 
 bin_PROGRAMS = xpbproxy
 xpbproxy_SOURCES = app-main.m
-xpbproxy_LDADD = $(top_builddir)/hw/xquartz/pbproxy/libxpbproxy.la
+xpbproxy_LDADD = libxpbproxy.la
 
 endif
 
commit ca659813a81074cae55ffec51f923c658480b618
Author: Julien Cristau <jcristau at debian.org>
Date:   Wed Oct 8 19:46:50 2008 +0200

    Fix GKVE with key_code > 255
    
    Move the keycode validation checks before use.

diff --git a/dix/getevents.c b/dix/getevents.c
index fbead11..1e0edbf 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -411,9 +411,6 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
     KeySym sym;
     deviceKeyButtonPointer *kbp = NULL;
 
-    sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
-              * pDev->key->curKeySyms.mapWidth];
-
     if (!events)
         return 0;
 
@@ -428,6 +425,9 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
     if (key_code < 8 || key_code > 255)
         return 0;
 
+    sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
+              * pDev->key->curKeySyms.mapWidth];
+
     if (pDev->coreEvents)
         numEvents = 2;
     else
commit 8337c9aa3d2009eea801a84b3a65272e03e65e1a
Author: Luc Verhaegen <libv at skynet.be>
Date:   Wed Oct 8 14:55:29 2008 +0200

    DGA: Fix ProcXF86DGASetViewPort for missing support in driver.
    
    Fixes a segfault when trying to activate a DGA mode without checking
    whether DGA modesetting is at all possible.
    (cherry picked from commit 1feb69eb63e6739ff5db255ad529e84adf941a10)

diff --git a/hw/xfree86/dixmods/extmod/xf86dga.c b/hw/xfree86/dixmods/extmod/xf86dga.c
index 0736167..c66bca2 100644
--- a/hw/xfree86/dixmods/extmod/xf86dga.c
+++ b/hw/xfree86/dixmods/extmod/xf86dga.c
@@ -93,7 +93,7 @@ ProcXF86DGADirectVideo(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
 
-    if (!DGAAvailable(stuff->screen)) 
+    if (!DGAAvailable(stuff->screen))
 	return DGAErrorBase + XF86DGANoDirectVideoMode;
 
     if (stuff->enable & XF86DGADirectGraphics) {
@@ -128,7 +128,7 @@ ProcXF86DGAGetViewPortSize(ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    if (!DGAAvailable(stuff->screen)) 
+    if (!DGAAvailable(stuff->screen))
 	return (DGAErrorBase + XF86DGANoDirectVideoMode);
 
     if(!(num = DGAGetOldDGAMode(stuff->screen)))
@@ -153,6 +153,9 @@ ProcXF86DGASetViewPort(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
 
+    if (!DGAAvailable(stuff->screen))
+	return (DGAErrorBase + XF86DGANoDirectVideoMode);
+
     if (!DGAActive(stuff->screen))
     {
 	int num;
commit 4e6cbd323854709ae00c44108c93ab6596151de2
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Wed Oct 8 13:33:55 2008 +0800

    Check nextEnabledOutput()'s return in bestModeForAspect()
    
    In case no enabled outputs, we will reference wrong index of
    output array.
    (cherry picked from commit 56c615368c5a8e7acb0398434c2c68578626aa38)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 2080b23..1facf86 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1903,7 +1903,8 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
     int o = -1, p;
     DisplayModePtr mode = NULL, test = NULL, match = NULL;
 
-    nextEnabledOutput(config, enabled, &o);
+    if (!nextEnabledOutput(config, enabled, &o))
+	return NULL;
     while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
 	test = mode;
 	for (p = o; nextEnabledOutput(config, enabled, &p); ) {
commit 43e3af9cac2e9fd613a61a870bfe00f4782a368d
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Oct 7 13:41:25 2008 -0400

    int10: Fix a nasty memory leak.
    (cherry picked from commit 94919480d8bb66e1807b4fe87b8f326ef6e012c6)

diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c
index 4e5f6d3..15eba49 100644
--- a/hw/xfree86/int10/helper_exec.c
+++ b/hw/xfree86/int10/helper_exec.c
@@ -482,6 +482,8 @@ pci_device_for_cfg_address (CARD32 addr)
 	if (iter)
 		dev = pci_device_next(iter);
 
+	pci_iterator_destroy(iter);
+
 	return dev;
 }
 
commit 00ac80a0c408106158bf258b6da8350611fbfe84
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Oct 7 13:39:10 2008 -0400

    int10: Don't warn when scanning for devices we don't have.
    
    Some BIOSes (hi XGI!) will attempt to enumerate the PCI bus by asking
    for the config space of every possible device number.  This despite
    perfectly functional BIOS methods to enumerate the bus exactly.
    (cherry picked from commit a57b2f172c1291f22f7ba2780c1b2f55e353c3e9)

diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c
index ff8143f..4e5f6d3 100644
--- a/hw/xfree86/int10/helper_exec.c
+++ b/hw/xfree86/int10/helper_exec.c
@@ -478,15 +478,9 @@ pci_device_for_cfg_address (CARD32 addr)
 
 	struct pci_device_iterator *iter =
 	    pci_slot_match_iterator_create (&slot_match);
+
 	if (iter)
 		dev = pci_device_next(iter);
-	if (!dev) {
-		char buf[128]; /* enough to store "%u@%u" */
-		xf86FormatPciBusNumber(tag >> 16, buf);
-		ErrorF("Failed to find device matching %s:%u:%u\n",
-				buf, slot_match.dev, slot_match.func);
-		return NULL;
-	}
 
 	return dev;
 }
commit c6ce2f6b3fe12e65b0e8a75cc1bc0a21875e14e3
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Oct 7 13:38:12 2008 -0400

    int10: Remove useless check.
    
    If you have more than one PCI device with the same d/b/d/f, you're
    already in trouble.
    (cherry picked from commit a65e36a873cd1ba9896cd0f9a3e94dd933666005)

diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c
index c3af5bc..ff8143f 100644
--- a/hw/xfree86/int10/helper_exec.c
+++ b/hw/xfree86/int10/helper_exec.c
@@ -488,13 +488,6 @@ pci_device_for_cfg_address (CARD32 addr)
 		return NULL;
 	}
 
-	if (pci_device_next(iter)) {
-		char buf[128]; /* enough to store "%u@%u" */
-		xf86FormatPciBusNumber(tag >> 16, buf);
-		ErrorF("Multiple devices matching %s:%u:%u\n",
-				buf, slot_match.dev, slot_match.func);
-	}
-
 	return dev;
 }
 
commit 8ef37c194fa08d3911095299413a42a01162b078
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date:   Fri Sep 12 19:11:53 2008 -0400

    Array-index based devPrivates implementation.
    
    Note: DevPrivateKey is now pointer-to-int, which means
    each key now needs to point to some global storage of
    size at least sizeof(int).
    
    (cherry picked from commit b6ab114212c0e4c3346ceb5b207f14c526ab81e7)

diff --git a/dix/privates.c b/dix/privates.c
index efb3204..ca03317 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -40,9 +40,8 @@ from The Open Group.
 #include "inputstr.h"
 
 struct _Private {
-    DevPrivateKey      key;
-    pointer            value;
-    struct _Private    *next;
+    int state;
+    pointer value;
 };
 
 typedef struct _PrivateDesc {
@@ -50,22 +49,36 @@ typedef struct _PrivateDesc {
     unsigned size;
     CallbackListPtr initfuncs;
     CallbackListPtr deletefuncs;
-    struct _PrivateDesc *next;
 } PrivateDescRec;
 
+#define PRIV_MAX 256
+#define PRIV_STEP 16
+
 /* list of all allocated privates */
-static PrivateDescRec *items = NULL;
+static PrivateDescRec items[PRIV_MAX];
+static int nextPriv;
 
-static _X_INLINE PrivateDescRec *
+static PrivateDescRec *
 findItem(const DevPrivateKey key)
 {
-    PrivateDescRec *item = items;
-    while (item) {
-	if (item->key == key)
-	    return item;
-	item = item->next;
+    if (!*key) {
+	if (nextPriv >= PRIV_MAX)
+	    return NULL;
+
+	items[nextPriv].key = key;
+	*key = nextPriv;
+	nextPriv++;
     }
-    return NULL;
+
+    return items + *key;
+}
+
+static _X_INLINE int
+privateExists(PrivateRec **privates, const DevPrivateKey key)
+{
+    return *key && *privates &&
+	(*privates)[0].state > *key &&
+	(*privates)[*key].state;
 }
 
 /*
@@ -75,21 +88,10 @@ _X_EXPORT int
 dixRequestPrivate(const DevPrivateKey key, unsigned size)
 {
     PrivateDescRec *item = findItem(key);
-    if (item) {
-	if (size > item->size)
-	    item->size = size;
-    } else {
-	item = (PrivateDescRec *)xalloc(sizeof(PrivateDescRec));
-	if (!item)
-	    return FALSE;
-	memset(item, 0, sizeof(PrivateDescRec));
-
-	/* add privates descriptor */
-	item->key = key;
+    if (!item)
+	return FALSE;
+    if (size > item->size)
 	item->size = size;
-	item->next = items;
-	items = item;
-    }
     return TRUE;
 }
 
@@ -100,25 +102,52 @@ _X_EXPORT pointer *
 dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
 {
     PrivateDescRec *item = findItem(key);
+    PrivateCallbackRec calldata;
     PrivateRec *ptr;
-    unsigned size = sizeof(PrivateRec);
-    
-    if (item)
-	size += item->size;
+    pointer value;
+    int oldsize, newsize;
+
+    newsize = (*key / PRIV_STEP + 1) * PRIV_STEP;
 
-    ptr = (PrivateRec *)xcalloc(size, 1);
-    if (!ptr)
+    /* resize or init privates array */
+    if (!item)
 	return NULL;
-    ptr->key = key;
-    ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL;
-    ptr->next = *privates;
-    *privates = ptr;
-
-    /* call any init funcs and return */
-    if (item) {
-	PrivateCallbackRec calldata = { key, &ptr->value };
-	CallCallbacks(&item->initfuncs, &calldata);
+
+    /* initialize privates array if necessary */
+    if (!*privates) {
+	ptr = xcalloc(newsize, sizeof(*ptr));
+	if (!ptr)
+	    return NULL;
+	*privates = ptr;
+	(*privates)[0].state = newsize;
+    }
+
+    oldsize = (*privates)[0].state;
+
+    /* resize privates array if necessary */
+    if (*key >= oldsize) {
+	ptr = xrealloc(*privates, newsize * sizeof(*ptr));
+	if (!ptr)
+	    return NULL;
+	memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr));
+	*privates = ptr;
+	(*privates)[0].state = newsize;
+    }
+
+    /* initialize slot */
+    ptr = *privates + *key;
+    ptr->state = 1;
+    if (item->size) {
+	value = xcalloc(item->size, 1);
+	if (!value)
+	    return NULL;
+	ptr->value = value;
     }
+
+    calldata.key = key;
+    calldata.value = &ptr->value;
+    CallCallbacks(&item->initfuncs, &calldata);
+
     return &ptr->value;
 }
 
@@ -128,14 +157,10 @@ dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
 _X_EXPORT pointer
 dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
 {
-    PrivateRec *rec = *privates;
     pointer *ptr;
 
-    while (rec) {
-	if (rec->key == key)
-	    return rec->value;
-	rec = rec->next;
-    }
+    if (privateExists(privates, key))
+	return (*privates)[*key].value;
 
     ptr = dixAllocatePrivate(privates, key);
     return ptr ? *ptr : NULL;
@@ -147,13 +172,8 @@ dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
 _X_EXPORT pointer *
 dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
 {
-    PrivateRec *rec = *privates;
-
-    while (rec) {
-	if (rec->key == key)
-	    return &rec->value;
-	rec = rec->next;
-    }
+    if (privateExists(privates, key))
+	return &(*privates)[*key].value;
 
     return dixAllocatePrivate(privates, key);
 }
@@ -164,16 +184,10 @@ dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
 _X_EXPORT int
 dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
 {
-    PrivateRec *rec;
-
  top:
-    rec = *privates;
-    while (rec) {
-	if (rec->key == key) {
-	    rec->value = val;
-	    return TRUE;
-	}
-	rec = rec->next;
+    if (privateExists(privates, key)) {
+	(*privates)[*key].value = val;
+	return TRUE;
     }
 
     if (!dixAllocatePrivate(privates, key))
@@ -187,27 +201,23 @@ dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
 _X_EXPORT void
 dixFreePrivates(PrivateRec *privates)
 {
-    PrivateRec *ptr, *next;
-    PrivateDescRec *item;
+    int i;
     PrivateCallbackRec calldata;
 
-    /* first pass calls the delete callbacks */
-    for (ptr = privates; ptr; ptr = ptr->next) {
-	item = findItem(ptr->key);
-	if (item) {
-	    calldata.key = ptr->key;
-	    calldata.value = &ptr->value;
-	    CallCallbacks(&item->deletefuncs, &calldata);
-	}
-    }
-	
-    /* second pass frees the memory */
-    ptr = privates;
-    while (ptr) {
-	next = ptr->next;
-	xfree(ptr);
-	ptr = next;
-    }
+    if (privates)
+	for (i = 1; i < privates->state; i++)
+	    if (privates[i].state) {
+		/* call the delete callbacks */
+		calldata.key = items[i].key;
+		calldata.value = &privates[i].value;
+		CallCallbacks(&items[i].deletefuncs, &calldata);
+
+		/* free pre-allocated memory */
+		if (items[i].size)
+		    xfree(privates[i].value);
+	    }
+
+    xfree(privates);
 }
 
 /*
@@ -218,11 +228,9 @@ dixRegisterPrivateInitFunc(const DevPrivateKey key,
 			   CallbackProcPtr callback, pointer data)
 {
     PrivateDescRec *item = findItem(key);
-    if (!item) {
-	if (!dixRequestPrivate(key, 0))
-	    return FALSE;
-	item = findItem(key);
-    }
+    if (!item)
+	return FALSE;
+
     return AddCallback(&item->initfuncs, callback, data);
 }
 
@@ -231,11 +239,9 @@ dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
 			     CallbackProcPtr callback, pointer data)
 {
     PrivateDescRec *item = findItem(key);
-    if (!item) {
-	if (!dixRequestPrivate(key, 0))
-	    return FALSE;
-	item = findItem(key);
-    }
+    if (!item)
+	return FALSE;
+
     return AddCallback(&item->deletefuncs, callback, data);
 }
 
@@ -292,16 +298,17 @@ dixLookupPrivateOffset(RESTYPE type)
 int
 dixResetPrivates(void)
 {
-    PrivateDescRec *next;
-
-    /* reset internal structures */
-    while (items) {
-	next = items->next;
-	DeleteCallbackList(&items->initfuncs);
-	DeleteCallbackList(&items->deletefuncs);
-	xfree(items);
-	items = next;
+    int i;
+
+    /* reset private descriptors */
+    for (i = 1; i < nextPriv; i++) {
+	*items[i].key = 0;
+	DeleteCallbackList(&items[i].initfuncs);
+	DeleteCallbackList(&items[i].deletefuncs);
     }
+    nextPriv = 1;
+
+    /* reset offsets */
     if (offsets)
 	xfree(offsets);
     offsetsSize = sizeof(offsetDefaults);
diff --git a/include/privates.h b/include/privates.h
index 98d893c..e3fa83c 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -19,7 +19,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * STUFF FOR PRIVATES
  *****************************************************************/
 
-typedef void *DevPrivateKey;
+typedef int *DevPrivateKey;
 struct _Private;
 typedef struct _Private PrivateRec;
 
commit e88df87851232d6b6c8da5fff802b33f5275b050
Author: Peter Hutterer <peter.hutterer at redhat.com>
Date:   Mon Sep 22 11:10:46 2008 +0930

    xkb: squash canonical types into explicit ones on core reconstruction.
    
    If we update key types from core, and groups 2 - n have a canonical type but
    the same symbols as the explicit type of group 1, assume that it was a core
    sym duplication according to Section 12.4 of the XKB Protocol Spec.
    Ignore the canonical types and pretend there's only one group for the key -
    with the explicit key type.
    
    The protocol spec does not cover this case, so we have to guess here.
    (cherry picked from commit 30c3c13f1030268aaa6a3598d538fafd0592d77a)

diff --git a/xkb/XKBMisc.c b/xkb/XKBMisc.c
index 85415a4..ac81395 100644
--- a/xkb/XKBMisc.c
+++ b/xkb/XKBMisc.c
@@ -178,16 +178,23 @@ int		nGroups,tmp,groupsWidth;
 	}
     }
 
-    /* step 7: check for all groups identical or all width 1 */
+    /* step 7: check for all groups identical or all width 1
+     *
+     * Special feature: if group 1 has an explicit type and all other groups
+     * have canonical types with same symbols, we assume it's info lost from
+     * the core replication.
+     */
     if (nGroups>1) {
-	Bool sameType,allOneLevel;
+	Bool sameType,allOneLevel, canonical = True;
 	allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
 	for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) {
 	    sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
 	    if (allOneLevel)
 		allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
+	    if (types_inout[i] > XkbLastRequiredType)
+		canonical = False;
 	}
-	if ((sameType)&&
+	if (((sameType) || canonical)&&
 	    (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
 	    register int s;
 	    Bool	identical;
commit be3b3cb970d040f0db4bead018c338012547334f
Author: Peter Hutterer <peter.hutterer at redhat.com>
Date:   Fri Sep 19 18:27:24 2008 +0930

    xkb: fix core keyboard map generation. #14373
    
    According to Section 12.4 of the XKB Protocol Spec, if a key only has a single
    group but the keyboard has multiple groups defined, the core description of
    the key is a duplication of the single group across all symbols. i.e.
    G1L1 G1L2 G1L1 G1L2 G1L3 G1L4 G1L3 G1L4
    
    The previous code generated G1L1 G1L2 G1L3 G1L4 G1L3 G1L4, leading to
    "invented" groups when the process is reversed.
    
    Note that this creates wrong key types on reconstruction from core to xkb,
    i.e. any single-group key with a key type that is not one of the canonical
    four (Sec 12.2.3), will get the assigned type on group 1, and a canonical type
    for the other gruops.
    
    X.Org Bug 14373 <http://bugs.freedesktop.org/show_bug.cgi?id=14373>
    (cherry picked from commit ae986d1c73d2f720bd0309d8c33328d14e8eed25)

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 8339cef..b5c0ac2 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -486,6 +486,40 @@ CARD8			keysPerMod[XkbNumModifiers];
 		if (groupWidth>2)
 		    nOut= groupWidth;
 	    }
+
+	    /* See XKB Protocol Sec, Section 12.4.
+	       A 1-group key with ABCDE on a 2 group keyboard must be
+	       duplicated across all groups as ABABCDECDE.
+	     */
+	    if (nGroups == 1)
+	    {
+		int idx;
+
+		groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index);
+
+		/* AB..CDE... -> ABABCDE... */
+		if (groupWidth > 0 && maxSymsPerKey >= 3)
+		    pCore[2] = pCore[0];
+		if (groupWidth > 1 && maxSymsPerKey >= 4)
+		    pCore[3] = pCore[1];
+
+		/* ABABCDE... -> ABABCDECDE */
+		idx = 2 + groupWidth;
+		while (groupWidth > 2 &&
+			idx < maxSymsPerKey &&
+			idx < groupWidth * 2)
+		{
+		    pCore[idx] = pCore[idx - groupWidth + 2];
+		    idx++;
+		}
+		idx = 2 * groupWidth;
+		if (idx < 4)
+		    idx = 4;
+		/* 3 or more groups: ABABCDECDEABCDEABCDE */
+		for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++)
+		    pCore[idx++] = pXKB[n];
+	    }
+
 	    pXKB+= XkbKeyGroupsWidth(xkb,key);
 	    nOut+= 2;
 	    if (nGroups>1) {
@@ -507,11 +541,6 @@ CARD8			keysPerMod[XkbNumModifiers];
 		}
 		pXKB+= XkbKeyGroupsWidth(xkb,key);
 	    }
-	    if (!pCore[2] && !pCore[3] && maxSymsPerKey >= 6 &&
-                (pCore[4] || pCore[5])) {
-                pCore[2] = pCore[4];
-                pCore[3] = pCore[5];
-	    }
 	}
 	if (keyc->modifierMap[key]!=0) {
 	    register unsigned bit,i,mask;
commit 3bf826f59013ec14fbcf19b85a03e2967a821661
Author: Kim Woelders <kim at woelders.dk>
Date:   Mon Sep 22 08:37:29 2008 +0930

    xkb: fix use of uninitialized variable.
    
    And some cosmetic changes to use stuff->change consistently.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at redhat.com>
    (cherry picked from commit 8c46505d7d91e0644b19cccc4b342fceb6f86cab)

diff --git a/xkb/xkb.c b/xkb/xkb.c
index be34334..7c569d4 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -6423,13 +6423,10 @@ static int
 _XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
                   xkbSetDeviceInfoReq *stuff)
 {
-    unsigned                    change;
     char                       *wire;
 
-    change = stuff->change;
-
     wire= (char *)&stuff[1];
-    if (change&XkbXI_ButtonActionsMask) {
+    if (stuff->change&XkbXI_ButtonActionsMask) {
 	if (!dev->button) {
 	    client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
 	    return XkbKeyboardErrorCode;
@@ -6458,14 +6455,13 @@ static int
 _XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
                        xkbSetDeviceInfoReq *stuff)
 {
-    unsigned                    change;
     char                       *wire;
     xkbExtensionDeviceNotify    ed;
 
     bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
     ed.deviceID=	dev->id;
     wire= (char *)&stuff[1];
-    if (change&XkbXI_ButtonActionsMask) {
+    if (stuff->change&XkbXI_ButtonActionsMask) {
 	int			nBtns,sz,i;
 	XkbAction *		acts;
 	DeviceIntPtr		kbd;
@@ -6495,8 +6491,8 @@ _XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
     }
     if (stuff->change&XkbXI_IndicatorsMask) {
 	int status= Success;
-	wire= SetDeviceIndicators(wire,dev,change,stuff->nDeviceLedFBs,
-							&status,client,&ed);
+	wire= SetDeviceIndicators(wire,dev,stuff->change,
+				  stuff->nDeviceLedFBs, &status,client,&ed);
 	if (status!=Success)
 	    return status;
     }
@@ -6508,7 +6504,6 @@ _XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
 int
 ProcXkbSetDeviceInfo(ClientPtr client)
 {
-    unsigned int        change;
     DeviceIntPtr        dev;
     int                 rc;
 
@@ -6518,10 +6513,8 @@ ProcXkbSetDeviceInfo(ClientPtr client)
     if (!(client->xkbClientFlags&_XkbClientInitialized))
 	return BadAccess;
 
-    change = stuff->change;
-
     CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
-    CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask);
+    CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask);
 
     rc = _XkbSetDeviceInfoCheck(client, dev, stuff);
 


More information about the xorg-commit mailing list