xserver: Branch 'master' - 14 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Jul 24 12:52:09 PDT 2013


 configure.ac                      |    6 +
 dix/Makefile.am                   |    3 
 dix/main.c                        |    6 -
 dix/stubmain.c                    |   35 +++++++
 hw/xwin/InitOutput.c              |   36 +++++++
 hw/xwin/Makefile.am               |    3 
 hw/xwin/glx/Makefile.am           |    4 
 hw/xwin/win.h                     |   29 +++---
 hw/xwin/winclipboard.h            |    1 
 hw/xwin/winclipboardthread.c      |   11 --
 hw/xwin/winfillsp.c               |    2 
 hw/xwin/winglobals.c              |    1 
 hw/xwin/winglobals.h              |    2 
 hw/xwin/winkeybd.c                |   62 ++++++++-----
 hw/xwin/winmessages.h             |    2 
 hw/xwin/winmouse.c                |   50 +++++-----
 hw/xwin/winmsgwindow.c            |  180 ++++++++++++++++++++++++++++++++++++++
 hw/xwin/winmultiwindowclass.c     |   21 ++--
 hw/xwin/winmultiwindowicons.c     |    4 
 hw/xwin/winmultiwindowwm.c        |   36 ++++---
 hw/xwin/winmultiwindowwndproc.c   |   16 ++-
 hw/xwin/winscrinit.c              |    2 
 hw/xwin/winwin32rootless.c        |   44 ++++-----
 hw/xwin/winwin32rootlesswindow.c  |    4 
 hw/xwin/winwin32rootlesswndproc.c |   27 +++--
 hw/xwin/winwindow.h               |    1 
 hw/xwin/winwindowswm.c            |    6 -
 hw/xwin/winwndproc.c              |   25 ++++-
 28 files changed, 473 insertions(+), 146 deletions(-)

New commits:
commit 43ac0491e36cdbb716b5c9d39c97d0aba3bebd75
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Apr 8 01:28:36 2013 +0100

    hw/xwin: Fix numerous 64-bit format/type cast issues with debug printing of pointers
    
    Numerous pieces of debug output cast a pointer to an int and then use a "%08x"
    printf format.
    
    Use "%p" format for 64-bit portability.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winfillsp.c b/hw/xwin/winfillsp.c
index f2432ed..bd0a15e 100644
--- a/hw/xwin/winfillsp.c
+++ b/hw/xwin/winfillsp.c
@@ -118,7 +118,7 @@ winFillSpansNativeGDI(DrawablePtr pDrawable,
         if (hbmpOrig == NULL)
             FatalError("winFillSpans - DRAWABLE_PIXMAP - "
                        "SelectObject () failed on\n\tpPixmapPriv->hBitmap: "
-                       "%08x\n", (unsigned int) pPixmapPriv->hBitmap);
+                       "%p\n", pPixmapPriv->hBitmap);
 
         /* Branch on the fill type */
         switch (pGC->fillStyle) {
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 5623b88..23152cb 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -703,7 +703,7 @@ winFinishScreenInitNativeGDI(int i,
     pScreenPriv->fEnabled = TRUE;
 
     ErrorF("winFinishScreenInitNativeGDI - Successful addition of "
-           "screen %08x\n", (unsigned int) pScreen);
+           "screen %p\n", pScreen);
 
     return TRUE;
 }
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 210fea3..724976a 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -312,8 +312,8 @@ winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
     }
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMCreateFrame - (%08x) %08x\n",
-             (int) pFrame->wid, (int) pRLWinPriv->hWnd);
+    winDebug("winMWExtWMCreateFrame - (%p) %p\n",
+             pFrame->wid, pRLWinPriv->hWnd);
 #if 0
     {
         WindowPtr pWin2 = NULL;
@@ -350,8 +350,8 @@ winMWExtWMDestroyFrame(RootlessFrameID wid)
     char pszClass[CLASS_NAME_LENGTH];
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMDestroyFrame (%08x) %08x\n",
-             (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
+    winDebug("winMWExtWMDestroyFrame (%p) %p\n",
+             pRLWinPriv, pRLWinPriv->hWnd);
 #if 0
     {
         WindowPtr pWin2 = NULL;
@@ -416,7 +416,7 @@ winMWExtWMMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int iNewX,
     int iX, iY, iWidth, iHeight;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX,
+    winDebug("winMWExtWMMoveFrame (%p) (%d %d)\n", pRLWinPriv, iNewX,
              iNewY);
 #endif
 
@@ -456,7 +456,7 @@ winMWExtWMMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int iNewX,
                  SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
     g_fNoConfigureWindow = FALSE;
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv);
+    winDebug("winMWExtWMMoveFrame (%p) done\n", pRLWinPriv);
 #endif
 }
 
@@ -474,8 +474,8 @@ winMWExtWMResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
     int iX, iY;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n",
-             (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
+    winDebug("winMWExtWMResizeFrame (%p) (%d %d)-(%d %d)\n",
+             pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
 #endif
 
     pRLWinPriv->fResized = TRUE;
@@ -526,7 +526,7 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
     Bool fNeedRestack = TRUE;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv);
+    winDebug("winMWExtWMRestackFrame (%p)\n", pRLWinPriv);
 #endif
 
     if (pScreenPriv && pScreenPriv->fRestacking)
@@ -612,7 +612,7 @@ winMWExtWMRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
                      0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
     }
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv);
+    winDebug("winMWExtWMRestackFrame - done (%p)\n", pRLWinPriv);
 #endif
 
     pRLWinPriv->fRestackingNow = FALSE;
@@ -626,7 +626,7 @@ winMWExtWMReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
     RECT rcWindow, rcClient;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv);
+    winDebug("winMWExtWMReshapeFrame (%p)\n", pRLWinPriv);
 #endif
 
     hRgn = winMWExtWMCreateRgnFromRegion(pShape);
@@ -655,7 +655,7 @@ winMWExtWMUnmapFrame(RootlessFrameID wid)
     win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv);
+    winDebug("winMWExtWMUnmapFrame (%p)\n", pRLWinPriv);
 #endif
 
     g_fNoConfigureWindow = TRUE;
@@ -680,7 +680,7 @@ winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
     HBITMAP hbmpNew;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv,
+    winDebug("winMWExtWMStartDrawing (%p) %08x\n", pRLWinPriv,
              pRLWinPriv->fDestroyed);
 #endif
 
@@ -692,8 +692,8 @@ winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
             pScreenInfo = pScreenPriv->pScreenInfo;
 
 #if CYGMULTIWINDOW_DEBUG
-        winDebug("\tpScreenPriv %08X\n", (int) pScreenPriv);
-        winDebug("\tpScreenInfo %08X\n", (int) pScreenInfo);
+        winDebug("\tpScreenPriv %p\n", pScreenPriv);
+        winDebug("\tpScreenInfo %p\n", pScreenInfo);
         winDebug("\t(%d, %d)\n", (int) pRLWinPriv->pFrame->width,
                  (int) pRLWinPriv->pFrame->height);
 #endif
@@ -808,9 +808,9 @@ winMWExtWMStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
         ErrorF("winMWExtWMStartDrawing - Already window was destroyed \n");
     }
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n",
-             (int) pRLWinPriv,
-             (unsigned int) pRLWinPriv->pfb,
+    winDebug("winMWExtWMStartDrawing - done (%p) %p %d\n",
+             pRLWinPriv,
+             pRLWinPriv->pfb,
              (unsigned int) pRLWinPriv->dwWidthBytes);
 #endif
     *pixelData = pRLWinPriv->pfb;
@@ -924,8 +924,8 @@ winMWExtWMRootlessSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
     win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMRootlessSwitchWindow (%08x) %08x\n",
-             (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
+    winDebug("winMWExtWMRootlessSwitchWindow (%p) %p\n",
+             pRLWinPriv, pRLWinPriv->hWnd);
 #endif
     pRLWinPriv->pFrame = pFrame;
     pRLWinPriv->fResized = TRUE;
@@ -979,8 +979,8 @@ winMWExtWMCopyWindow(RootlessFrameID wid, int nDstRects,
     RECT rcDmg;
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n",
-             (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy);
+    winDebug("winMWExtWMCopyWindow (%p, %d, %p, %d, %d)\n",
+             pRLWinPriv, nDstRects, pDstRects, nDx, nDy);
 #endif
 
     for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) {
diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c
index ce615e6..1faa531 100644
--- a/hw/xwin/winwin32rootlesswindow.c
+++ b/hw/xwin/winwin32rootlesswindow.c
@@ -213,8 +213,8 @@ winMWExtWMUpdateWindowDecoration(win32RootlessWindowPtr pRLWinPriv,
 
     showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER;
 
-    winDebug("winMWExtWMUpdateWindowDecoration %08x %s\n",
-             (int) pRLWinPriv, fDecorate ? "Decorate" : "Bare");
+    winDebug("winMWExtWMUpdateWindowDecoration %p %s\n",
+             pRLWinPriv, fDecorate ? "Decorate" : "Bare");
 
     /* Get the extended window style information */
     dwExStyle = GetWindowLongPtr(pRLWinPriv->hWnd, GWL_EXSTYLE);
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index be29583..001d0d2 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -832,24 +832,24 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (!(pWinPos->flags & SWP_NOZORDER)) {
             if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking) {
 #if CYGMULTIWINDOW_DEBUG
-                winDebug("Win %08x is now restacking.\n",
-                         (unsigned int) pRLWinPriv);
+                winDebug("Win %p is now restacking.\n",
+                         pRLWinPriv);
 #endif
                 break;
             }
 
             if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick(pWin)) {
 #if CYGMULTIWINDOW_DEBUG
-                winDebug("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n",
-                         (unsigned int) pRLWinPriv);
+                winDebug("Win %p has WINDOWSWM_RAISE_ON_CLICK.\n",
+                         pRLWinPriv);
 #endif
                 break;
             }
 
 #if CYGMULTIWINDOW_DEBUG
-            winDebug("Win %08x forbid to change z order (%08x).\n",
-                     (unsigned int) pRLWinPriv,
-                     (unsigned int) pWinPos->hwndInsertAfter);
+            winDebug("Win %p forbid to change z order (%p).\n",
+                     pRLWinPriv,
+                     pWinPos->hwndInsertAfter);
 #endif
             pWinPos->flags |= SWP_NOZORDER;
         }
diff --git a/hw/xwin/winwindowswm.c b/hw/xwin/winwindowswm.c
index 6e9d63c..be43265 100644
--- a/hw/xwin/winwindowswm.c
+++ b/hw/xwin/winwindowswm.c
@@ -246,7 +246,7 @@ winWindowsWMSendEvent(int type, unsigned int mask, int which, int arg,
     for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
         client = pEvent->client;
 #if CYGMULTIWINDOW_DEBUG
-        ErrorF("winWindowsWMSendEvent - x%08x\n", (int) client);
+        ErrorF("winWindowsWMSendEvent - %p\n", client);
 #endif
         if ((pEvent->mask & mask) == 0) {
             continue;
@@ -381,8 +381,8 @@ ProcWindowsWMFrameDraw(ClientPtr client)
         return BadWindow;
 
 #if CYGMULTIWINDOW_DEBUG
-    ErrorF("ProcWindowsWMFrameDraw - HWND 0x%08x 0x%08x 0x%08x\n",
-           (int) pRLWinPriv->hWnd, (int) stuff->frame_style,
+    ErrorF("ProcWindowsWMFrameDraw - HWND %p 0x%08x 0x%08x\n",
+           pRLWinPriv->hWnd, (int) stuff->frame_style,
            (int) stuff->frame_style_ex);
     ErrorF("ProcWindowsWMFrameDraw - %d %d %d %d\n",
            stuff->ix, stuff->iy, stuff->iw, stuff->ih);
commit e95bb97073ca77193e4c51bd1504403fbe245533
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Tue Jun 25 21:34:43 2013 +0100

    hw/xwin: Fix possible crash in winMultiWindowGetClassHint
    
    Fix a possible crash in winMultiWindowGetClassHint() when an application doesn't
    null terminate the WM_CLASS property class name (which is an ICCCM conformance
    bug in the application)
    
    (Reported for running the contiki cooja simulator in multiwindow mode, although
    it seems that many Java clients may have this problem, see [1])
    
    Based on a patch by Marc Haesen.
    
    v2: Avoid using strnlen() which is missing on MinGW
    v3: Align with Xming patch
    
    [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6961123
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/winmultiwindowclass.c b/hw/xwin/winmultiwindowclass.c
index ced8f45..6787332 100644
--- a/hw/xwin/winmultiwindowclass.c
+++ b/hw/xwin/winmultiwindowclass.c
@@ -68,7 +68,12 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
     while (prop) {
         if (prop->propertyName == XA_WM_CLASS
             && prop->type == XA_STRING && prop->format == 8 && prop->data) {
+            /*
+              WM_CLASS property should consist of 2 null terminated strings, but we
+              must handle the cases when one or both is absent or not null terminated
+            */
             len_name = strlen((char *) prop->data);
+            if (len_name > prop->size) len_name = prop->size;
 
             (*res_name) = malloc(len_name + 1);
 
@@ -77,13 +82,13 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
                 return 0;
             }
 
-            /* Add one to len_name to allow copying of trailing 0 */
-            strncpy((*res_name), prop->data, len_name + 1);
+            /* Copy name and ensure null terminated */
+            strncpy((*res_name), prop->data, len_name);
+            (*res_name)[len_name] = '\0';
 
-            if (len_name == prop->size)
-                len_name--;
-
-            len_class = strlen(((char *) prop->data) + 1 + len_name);
+            /* Compute length of class name, it could be that it is absent or not null terminated */
+            len_class = (len_name >= prop->size) ? 0 : (strlen(((char *) prop->data) + 1 + len_name));
+            if (len_class > prop->size - 1 - len_name) len_class = prop->size - 1 - len_name;
 
             (*res_class) = malloc(len_class + 1);
 
@@ -95,7 +100,9 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
                 return 0;
             }
 
-            strcpy((*res_class), ((char *) prop->data) + 1 + len_name);
+            /* Copy class name and ensure null terminated */
+            strncpy((*res_class), ((char *) prop->data) + 1 + len_name, len_class);
+            (*res_class)[len_class] = '\0';
 
             return 1;
         }
commit 4bc375aa2f08bd092f60d3e358d345fc9a0d3637
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Jun 18 19:21:02 2013 +0100

    hw/xwin: Remove obsolete WIN_XEVENTS_SHUTDOWN
    
    Remove obsolete WIN_XEVENTS_SHUTDOWN.  This event is never generated.
    
    (I think the idea was to listen for WM_DELETE_WINDOW, but that's not a very
    useful thing to do for a hidden window.)
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h
index 2cd775d..aa7fd44 100644
--- a/hw/xwin/winclipboard.h
+++ b/hw/xwin/winclipboard.h
@@ -66,7 +66,6 @@
 #define WIN_JMP_ERROR_IO			2
 #define WIN_LOCAL_PROPERTY			"CYGX_CUT_BUFFER"
 #define WIN_XEVENTS_SUCCESS			0
-#define WIN_XEVENTS_SHUTDOWN			1
 #define WIN_XEVENTS_CONVERT			2
 #define WIN_XEVENTS_NOTIFY			3
 #define WIN_CLIPBOARD_RETRIES			40
diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c
index 69c654d..33595be 100644
--- a/hw/xwin/winclipboardthread.c
+++ b/hw/xwin/winclipboardthread.c
@@ -325,14 +325,7 @@ winClipboardProc(void *pvNotUsed)
         /* Branch on which descriptor became active */
         if (FD_ISSET(iConnectionNumber, &fdsRead)) {
             /* Process X events */
-            /* Exit when we see that server is shutting down */
-            iReturn = winClipboardFlushXEvents(hwnd,
-                                               iWindow, pDisplay, fUseUnicode);
-            if (WIN_XEVENTS_SHUTDOWN == iReturn) {
-                ErrorF("winClipboardProc - winClipboardFlushXEvents "
-                       "trapped shutdown event, exiting main loop.\n");
-                break;
-            }
+            winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);
         }
 
 #ifdef HAS_DEVWINDOWS
commit 2663203cd6994166e107e796c4724a4ed3b59370
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Jun 18 18:03:05 2013 +0100

    configure.ac: Check for python at configure time when building XWin with AIGLX
    
    Check for python at configure time when building XWin with AIGLX, it's used to
    generate the wrapper code for native GL functions.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/configure.ac b/configure.ac
index d0d0fd7..c6ecba4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1944,6 +1944,10 @@ if test "x$XWIN" = xyes; then
 
 dnl XWin with AIGLX requires OpenGL spec files in order to generate wrapper code for native GL functions
 	if [test "x$XWIN" = xyes && test "x$AIGLX" = xyes] ; then
+           AC_CHECK_PROG(PYTHON, python, python)
+           if test -z "$PYTHON"; then
+                AC_MSG_ERROR([python not found])
+           fi
            if test "x$KHRONOS_SPEC_DIR" = "xauto" ; then
 		PKG_CHECK_MODULES([KHRONOS_OPENGL_REGISTRY], [khronos-opengl-registry])
 		KHRONOS_SPEC_DIR=`pkg-config khronos-opengl-registry --variable=specdir`
diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am
index 59f6879..f969af2 100644
--- a/hw/xwin/glx/Makefile.am
+++ b/hw/xwin/glx/Makefile.am
@@ -33,10 +33,10 @@ AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
 if XWIN_GLX_WINDOWS
 
 generated_gl_wrappers.c: gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/gl.spec $(KHRONOS_SPEC_DIR)/gl.tm
-	$(AM_V_GEN)$(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/gl.spec --typemap=$(KHRONOS_SPEC_DIR)/gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c
+	$(AM_V_GEN)$(PYTHON) $(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/gl.spec --typemap=$(KHRONOS_SPEC_DIR)/gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c
 
 generated_wgl_wrappers.c: gen_gl_wrappers.py $(KHRONOS_SPEC_DIR)/wglext.spec $(KHRONOS_SPEC_DIR)/wgl.tm
-	$(AM_V_GEN)$(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/wglext.spec --typemap=$(KHRONOS_SPEC_DIR)/wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c
+	$(AM_V_GEN)$(PYTHON) $(srcdir)/gen_gl_wrappers.py --spec=$(KHRONOS_SPEC_DIR)/wglext.spec --typemap=$(KHRONOS_SPEC_DIR)/wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c
 endif
 
 BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c
commit 9fe360bf2be5c959fb21835955ef550098ccbbf0
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sun Jun 16 00:07:57 2013 +0100

    hw/xwin: Avoid a null dereference if CreateDIBSection() fails in NetWMToWinIconAlpha()
    
    Avoid a null dereference of DIB_pixels if CreateDIBSection() fails in
    NetWMToWinIconAlpha()
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c
index bcc5688..0531ad6 100644
--- a/hw/xwin/winmultiwindowicons.c
+++ b/hw/xwin/winmultiwindowicons.c
@@ -257,6 +257,10 @@ NetWMToWinIconAlpha(uint32_t * icon)
                                    DIB_RGB_COLORS, (void **) &DIB_pixels, NULL,
                                    0);
     ReleaseDC(NULL, hdc);
+
+    if (!ii.hbmColor)
+      return NULL;
+
     ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL);
     memcpy(DIB_pixels, pixels, height * width * 4);
 
commit 71b5f56302bbd8be62f63f0dd62cbcd33aab3ac5
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Feb 21 17:12:17 2013 +0000

    hw/xwin: Handle WM_MOUSEHWHEEL
    
    Handle WM_MOUSEHWHEEL tilt wheel messages, similarly to WM_MOUSEWHEEL scroll
    wheel messages, to generate X button 6 and 7 presses and releases.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 182e96b..ce89348 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -42,6 +42,11 @@
 #define YES					1
 #endif
 
+/* We can handle WM_MOUSEHWHEEL even though _WIN32_WINNT < 0x0600 */
+#ifndef WM_MOUSEHWHEEL
+#define WM_MOUSEHWHEEL 0x020E
+#endif
+
 /* Turn debug messages on or off */
 #ifndef CYGDEBUG
 #define CYGDEBUG				NO
@@ -449,6 +454,7 @@ typedef struct _winPrivScreenRec {
     Bool fBadDepth;
 
     int iDeltaZ;
+    int iDeltaV;
 
     int iConnectedClients;
 
@@ -975,7 +981,7 @@ int
  winMouseProc(DeviceIntPtr pDeviceInt, int iState);
 
 int
- winMouseWheel(ScreenPtr pScreen, int iDeltaZ);
+ winMouseWheel(int *iTotalDeltaZ, int iDeltaZ, int iButtonUp, int iButtonDown);
 
 void
  winMouseButtonsSendEvent(int iEventType, int iButton);
diff --git a/hw/xwin/winmessages.h b/hw/xwin/winmessages.h
index 3d3fab2..8282f8b 100644
--- a/hw/xwin/winmessages.h
+++ b/hw/xwin/winmessages.h
@@ -529,7 +529,7 @@ static const char *MESSAGE_NAMES[1024] = {
     "WM_XBUTTONDOWN",
     "WM_XBUTTONUP",
     "WM_XBUTTONDBLCLK",
-    "526",
+    "WM_MOUSEHWHEEL",
     "527",
     "WM_PARENTNOTIFY",
     "WM_ENTERMENULOOP",
diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index da067cd..bbe21cb 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -145,20 +145,16 @@ winMouseProc(DeviceIntPtr pDeviceInt, int iState)
 
 /* Handle the mouse wheel */
 int
-winMouseWheel(ScreenPtr pScreen, int iDeltaZ)
+winMouseWheel(int *iTotalDeltaZ, int iDeltaZ, int iButtonUp, int iButtonDown)
 {
-    winScreenPriv(pScreen);
-    int button;                 /* Button4 or Button5 */
-
-    /* Button4 = WheelUp */
-    /* Button5 = WheelDown */
+    int button;
 
     /* Do we have any previous delta stored? */
-    if ((pScreenPriv->iDeltaZ > 0 && iDeltaZ > 0)
-        || (pScreenPriv->iDeltaZ < 0 && iDeltaZ < 0)) {
+    if ((*iTotalDeltaZ > 0 && iDeltaZ > 0)
+        || (*iTotalDeltaZ < 0 && iDeltaZ < 0)) {
         /* Previous delta and of same sign as current delta */
-        iDeltaZ += pScreenPriv->iDeltaZ;
-        pScreenPriv->iDeltaZ = 0;
+        iDeltaZ += *iTotalDeltaZ;
+        *iTotalDeltaZ = 0;
     }
     else {
         /*
@@ -167,7 +163,7 @@ winMouseWheel(ScreenPtr pScreen, int iDeltaZ)
          * as blindly setting takes just as much time
          * as checking, then setting if necessary :)
          */
-        pScreenPriv->iDeltaZ = 0;
+        *iTotalDeltaZ = 0;
     }
 
     /*
@@ -175,7 +171,7 @@ winMouseWheel(ScreenPtr pScreen, int iDeltaZ)
      * WHEEL_DELTA
      */
     if (iDeltaZ >= WHEEL_DELTA || (-1 * iDeltaZ) >= WHEEL_DELTA) {
-        pScreenPriv->iDeltaZ = 0;
+        *iTotalDeltaZ = 0;
 
         /* Figure out how many whole deltas of the wheel we have */
         iDeltaZ /= WHEEL_DELTA;
@@ -186,16 +182,16 @@ winMouseWheel(ScreenPtr pScreen, int iDeltaZ)
          * we will store the wheel delta until the threshold
          * has been reached.
          */
-        pScreenPriv->iDeltaZ = iDeltaZ;
+        *iTotalDeltaZ = iDeltaZ;
         return 0;
     }
 
     /* Set the button to indicate up or down wheel delta */
     if (iDeltaZ > 0) {
-        button = Button4;
+        button = iButtonUp;
     }
     else {
-        button = Button5;
+        button = iButtonDown;
     }
 
     /*
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index da7914a..9292e73 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -684,6 +684,18 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         else
             break;
 
+    case WM_MOUSEHWHEEL:
+        if (SendMessage
+            (hwnd, WM_NCHITTEST, 0,
+             MAKELONG(GET_X_LPARAM(lParam),
+                      GET_Y_LPARAM(lParam))) == HTCLIENT) {
+            /* Pass the message to the root window */
+            SendMessage(hwndScreen, message, wParam, lParam);
+            return 0;
+        }
+        else
+            break;
+
     case WM_SETFOCUS:
         if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
             break;
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index 9c282ec..be29583 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -667,6 +667,15 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         SendMessage(hwndScreen, message, wParam, lParam);
         return 0;
 
+    case WM_MOUSEHWHEEL:
+#if CYGMULTIWINDOW_DEBUG
+        winDebug("winMWExtWMWindowProc - WM_MOUSEHWHEEL\n");
+#endif
+
+        /* Pass the message to the root window */
+        SendMessage(hwndScreen, message, wParam, lParam);
+        return 0;
+
     case WM_MOUSEACTIVATE:
 #if CYGMULTIWINDOW_DEBUG
         winDebug("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 7af222c..c73a75c 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -976,7 +976,20 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #if CYGDEBUG
         winDebug("winWindowProc - WM_MOUSEWHEEL\n");
 #endif
-        winMouseWheel(s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam));
+        /* Button4 = WheelUp */
+        /* Button5 = WheelDown */
+        winMouseWheel(&(s_pScreenPriv->iDeltaZ), GET_WHEEL_DELTA_WPARAM(wParam), Button4, Button5);
+        break;
+
+    case WM_MOUSEHWHEEL:
+        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+            break;
+#if CYGDEBUG
+        winDebug("winWindowProc - WM_MOUSEHWHEEL\n");
+#endif
+        /* Button7 = TiltRight */
+        /* Button6 = TiltLeft */
+        winMouseWheel(&(s_pScreenPriv->iDeltaV), GET_WHEEL_DELTA_WPARAM(wParam), 7, 6);
         break;
 
     case WM_SETFOCUS:
@@ -1147,6 +1160,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         /* Clear any lingering wheel delta */
         s_pScreenPriv->iDeltaZ = 0;
+        s_pScreenPriv->iDeltaV = 0;
 
         /* Reshow the Windows mouse cursor if we are being deactivated */
         if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE && !g_fCursor) {
commit cf9c777ee094d660e0c95559373fd23ee910362e
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Feb 21 17:10:45 2013 +0000

    hw/xwin: Map extra mouse buttons 1 and 2 to X buttons 8 and 9
    
    Map extra mouse buttons 1 and 2 to X buttons 8 and 9, as conventional, leaving X
    buttons 6 and 7 for tilt wheel.
    
    Also add button labels for buttons 6, 7, 8 and 9 and change btn_labels in from a
    dynamic allocation to a fixed one of the required size for all the labels we
    use.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index 9d896c9..da067cd 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -65,10 +65,10 @@ int
 winMouseProc(DeviceIntPtr pDeviceInt, int iState)
 {
     int lngMouseButtons, i;
-    int lngWheelEvents = 2;
+    int lngWheelEvents = 4;
     CARD8 *map;
     DevicePtr pDevice = (DevicePtr) pDeviceInt;
-    Atom *btn_labels;
+    Atom btn_labels[9];
     Atom axes_labels[2];
 
     switch (iState) {
@@ -80,15 +80,23 @@ winMouseProc(DeviceIntPtr pDeviceInt, int iState)
         /* Mapping of windows events to X events:
          * LEFT:1 MIDDLE:2 RIGHT:3
          * SCROLL_UP:4 SCROLL_DOWN:5
-         * XBUTTON 1:6 XBUTTON 2:7 ...
+         * TILT_LEFT:6 TILT_RIGHT:7
+         * XBUTTON 1:8 XBUTTON 2:9 (most commonly 'back' and 'forward')
+         * ...
          *
+         * The current Windows API only defines 2 extra buttons, so we don't
+         * expect more than 5 buttons to be reported, but more than that
+         * should be handled correctly
+         */
+
+        /*
          * To map scroll wheel correctly we need at least the 3 normal buttons
          */
         if (lngMouseButtons < 3)
             lngMouseButtons = 3;
 
-        /* allocate memory: 
-         * number of buttons + 2x mouse wheel event + 1 extra (offset for map) 
+        /* allocate memory:
+         * number of buttons + 4 x mouse wheel event + 1 extra (offset for map)
          */
         map = malloc(sizeof(CARD8) * (lngMouseButtons + lngWheelEvents + 1));
 
@@ -97,12 +105,15 @@ winMouseProc(DeviceIntPtr pDeviceInt, int iState)
         for (i = 1; i <= lngMouseButtons + lngWheelEvents; i++)
             map[i] = i;
 
-        btn_labels = calloc((lngMouseButtons + lngWheelEvents), sizeof(Atom));
         btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
         btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
         btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+        btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+        btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+        btn_labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_BACK);
+        btn_labels[8] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_FORWARD);
 
         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
@@ -114,7 +125,6 @@ winMouseProc(DeviceIntPtr pDeviceInt, int iState)
                                 winMouseCtrl,
                                 GetMotionHistorySize(), 2, axes_labels);
         free(map);
-        free(btn_labels);
 
         g_winMouseButtonMap = pDeviceInt->button->map;
         break;
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 3818187..da7914a 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -661,7 +661,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
             break;
         SetCapture(hwnd);
-        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 5,
+        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7,
                                      wParam);
 
     case WM_XBUTTONUP:
@@ -670,7 +670,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         ReleaseCapture();
         winStartMousePolling(s_pScreenPriv);
         return winMouseButtonsHandle(s_pScreen, ButtonRelease,
-                                     HIWORD(wParam) + 5, wParam);
+                                     HIWORD(wParam) + 7, wParam);
 
     case WM_MOUSEWHEEL:
         if (SendMessage
diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c
index 13df186..9c282ec 100644
--- a/hw/xwin/winwin32rootlesswndproc.c
+++ b/hw/xwin/winwin32rootlesswndproc.c
@@ -649,13 +649,13 @@ winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
             break;
         SetCapture(hwnd);
-        return winMouseButtonsHandle(pScreen, ButtonPress, HIWORD(wParam) + 5,
+        return winMouseButtonsHandle(pScreen, ButtonPress, HIWORD(wParam) + 7,
                                      wParam);
     case WM_XBUTTONUP:
         if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
             break;
         ReleaseCapture();
-        return winMouseButtonsHandle(pScreen, ButtonRelease, HIWORD(wParam) + 5,
+        return winMouseButtonsHandle(pScreen, ButtonRelease, HIWORD(wParam) + 7,
                                      wParam);
 
     case WM_MOUSEWHEEL:
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index f99afb5..7af222c 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -894,7 +894,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 #endif
             )
             SetCapture(hwnd);
-        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 5,
+        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 7,
                                      wParam);
     case WM_XBUTTONUP:
         if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
@@ -906,7 +906,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             )
             ReleaseCapture();
         return winMouseButtonsHandle(s_pScreen, ButtonRelease,
-                                     HIWORD(wParam) + 5, wParam);
+                                     HIWORD(wParam) + 7, wParam);
 
     case WM_TIMER:
         if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
commit c9d7b9516f4a04cb9012c6c1e9466491a468aa07
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Feb 19 14:38:40 2013 +0000

    hw/xwin: Remove unneeded WM_XBUTTON message defines
    
    Remove unneeded WM_XBUTTON message defines, they have been provided by w32api
    for a long time now.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index a663088..182e96b 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -47,17 +47,6 @@
 #define CYGDEBUG				NO
 #endif
 
-/* WM_XBUTTON Messages. They should go into w32api. */
-#ifndef WM_XBUTTONDOWN
-#define WM_XBUTTONDOWN 523
-#endif
-#ifndef WM_XBUTTONUP
-#define WM_XBUTTONUP 524
-#endif
-#ifndef WM_XBUTTONDBLCLK
-#define WM_XBUTTONDBLCLK 525
-#endif
-
 #define WIN_DEFAULT_BPP				0
 #define WIN_DEFAULT_WHITEPIXEL			255
 #define WIN_DEFAULT_BLACKPIXEL			0
commit 5dccfc63f9c7056e7cd30884e1d3ccea86a2f419
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Dec 17 22:38:00 2012 +0000

    hw/xwin: Change winTranslateKey() to return it's result as it's return value
    
    Change winTranslateKey() to return it's result as it's return value, and change
    it's uses as well.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index dd6ed02..a663088 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -921,8 +921,8 @@ void
  * winkeybd.c
  */
 
-void
- winTranslateKey(WPARAM wParam, LPARAM lParam, int *piScanCode);
+int
+ winTranslateKey(WPARAM wParam, LPARAM lParam);
 
 int
  winKeybdProc(DeviceIntPtr pDeviceInt, int iState);
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index 27432e1..9c5d4e9 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -65,13 +65,14 @@ static void
  * like AltGr on European keyboards.
  */
 
-void
-winTranslateKey(WPARAM wParam, LPARAM lParam, int *piScanCode)
+int
+winTranslateKey(WPARAM wParam, LPARAM lParam)
 {
     int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1];
     int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
     int iParam = HIWORD(lParam);
     int iParamScanCode = LOBYTE(iParam);
+    int iScanCode;
 
     winDebug("winTranslateKey: wParam %08x lParam %08x\n", wParam, lParam);
 
@@ -96,23 +97,25 @@ winTranslateKey(WPARAM wParam, LPARAM lParam, int *piScanCode)
 
     /* Branch on special extended, special non-extended, or normal key */
     if ((iParam & KF_EXTENDED) && iKeyFixupEx)
-        *piScanCode = iKeyFixupEx;
+        iScanCode = iKeyFixupEx;
     else if (iKeyFixup)
-        *piScanCode = iKeyFixup;
+        iScanCode = iKeyFixup;
     else if (wParam == 0 && iParamScanCode == 0x70)
-        *piScanCode = KEY_HKTG;
+        iScanCode = KEY_HKTG;
     else
         switch (iParamScanCode) {
         case 0x70:
-            *piScanCode = KEY_HKTG;
+            iScanCode = KEY_HKTG;
             break;
         case 0x73:
-            *piScanCode = KEY_BSlash2;
+            iScanCode = KEY_BSlash2;
             break;
         default:
-            *piScanCode = iParamScanCode;
+            iScanCode = iParamScanCode;
             break;
         }
+
+    return iScanCode;
 }
 
 /* Ring the keyboard bell (system speaker on PCs) */
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index f93072c..f99afb5 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1064,7 +1064,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         }
 
         /* Translate Windows key code to X scan code */
-        winTranslateKey(wParam, lParam, &iScanCode);
+        iScanCode = winTranslateKey(wParam, lParam);
 
         /* Ignore repeats for CapsLock */
         if (wParam == VK_CAPITAL)
@@ -1093,7 +1093,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             return 0;
 
         /* Enqueue a keyup event */
-        winTranslateKey(wParam, lParam, &iScanCode);
+        iScanCode = winTranslateKey(wParam, lParam);
         winSendKeyEvent(iScanCode, FALSE);
 
         /* Release all pressed shift keys */
commit 9b4cec76f1d7792d4bf64fa069ea6b64bc42da0d
Author: Oliver Schmidt <oschmidt-mailinglists at gmx.de>
Date:   Mon Nov 5 15:05:32 2012 +0000

    hw/xwin: Consider left and right modifier keys independently on gaining focus
    
    Handle left and right ctrl and shift keys independently
    
    Assume that all modifiers are cleared when all keys are released on focus lost,
    as internalKeyState doesn't record which modifier key was pressed.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index e412f23..27432e1 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -264,25 +264,38 @@ winRestoreModeKeyStates(void)
 
     /* Check if modifier keys are pressed, and if so, fake a press */
     {
-        BOOL ctrl = (GetAsyncKeyState(VK_CONTROL) < 0);
-        BOOL shift = (GetAsyncKeyState(VK_SHIFT) < 0);
+
+        BOOL lctrl = (GetAsyncKeyState(VK_LCONTROL) < 0);
+        BOOL rctrl = (GetAsyncKeyState(VK_RCONTROL) < 0);
+        BOOL lshift = (GetAsyncKeyState(VK_LSHIFT) < 0);
+        BOOL rshift = (GetAsyncKeyState(VK_RSHIFT) < 0);
         BOOL alt = (GetAsyncKeyState(VK_LMENU) < 0);
         BOOL altgr = (GetAsyncKeyState(VK_RMENU) < 0);
 
-        if (ctrl && altgr)
-            ctrl = FALSE;
+        /*
+           If AltGr and CtrlL appear to be pressed, assume the
+           CtrL is a fake one
+         */
+        if (lctrl && altgr)
+            lctrl = FALSE;
+
+        if (lctrl)
+            winSendKeyEvent(KEY_LCtrl, TRUE);
+
+        if (rctrl)
+            winSendKeyEvent(KEY_RCtrl, TRUE);
 
-        if (LOGICAL_XOR(internalKeyStates & ControlMask, ctrl))
-            winSendKeyEvent(KEY_LCtrl, ctrl);
+        if (lshift)
+            winSendKeyEvent(KEY_ShiftL, TRUE);
 
-        if (LOGICAL_XOR(internalKeyStates & ShiftMask, shift))
-            winSendKeyEvent(KEY_ShiftL, shift);
+        if (rshift)
+            winSendKeyEvent(KEY_ShiftL, TRUE);
 
-        if (LOGICAL_XOR(internalKeyStates & Mod1Mask, alt))
-            winSendKeyEvent(KEY_Alt, alt);
+        if (alt)
+            winSendKeyEvent(KEY_Alt, TRUE);
 
-        if (LOGICAL_XOR(internalKeyStates & Mod5Mask, altgr))
-            winSendKeyEvent(KEY_AltLang, altgr);
+        if (altgr)
+            winSendKeyEvent(KEY_AltLang, TRUE);
     }
 
     /*
@@ -313,6 +326,12 @@ winRestoreModeKeyStates(void)
         winSendKeyEvent(KEY_HKTG, TRUE);
         winSendKeyEvent(KEY_HKTG, FALSE);
     }
+
+    /*
+       For strict correctness, we should also press any non-modifier keys
+       which are already down when we gain focus, but nobody has complained
+       yet :-)
+     */
 }
 
 /*
commit 235149d0b4af9097e47b3af0ba56d4eb0179518c
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Apr 5 14:22:39 2010 +0100

    hw/xwin: Remove an extra '\n' from some log messages
    
    Remove an extra '\n' from internal client IOError log messages
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c
index 6da9f3b..69c654d 100644
--- a/hw/xwin/winclipboardthread.c
+++ b/hw/xwin/winclipboardthread.c
@@ -460,7 +460,7 @@ winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr)
 static int
 winClipboardIOErrorHandler(Display * pDisplay)
 {
-    ErrorF("winClipboardIOErrorHandler!\n\n");
+    ErrorF("winClipboardIOErrorHandler!\n");
 
     if (pthread_equal(pthread_self(), g_winClipboardProcThread)) {
         /* Restart at the main entry point */
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 7671bda..3c44f05 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1470,7 +1470,7 @@ winMultiWindowWMErrorHandler(Display * pDisplay, XErrorEvent * pErr)
 static int
 winMultiWindowWMIOErrorHandler(Display * pDisplay)
 {
-    ErrorF("winMultiWindowWMIOErrorHandler!\n\n");
+    ErrorF("winMultiWindowWMIOErrorHandler!\n");
 
     if (pthread_equal(pthread_self(), g_winMultiWindowWMThread)) {
         if (g_shutdown)
@@ -1510,7 +1510,7 @@ winMultiWindowXMsgProcErrorHandler(Display * pDisplay, XErrorEvent * pErr)
 static int
 winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay)
 {
-    ErrorF("winMultiWindowXMsgProcIOErrorHandler!\n\n");
+    ErrorF("winMultiWindowXMsgProcIOErrorHandler!\n");
 
     if (pthread_equal(pthread_self(), g_winMultiWindowXMsgProcThread)) {
         /* Restart at the main entry point */
commit c7aa9f7578e721b0c9e565e7a085b6aeb30bf2ac
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Feb 4 17:04:11 2012 +0000

    hw/xwin: _NET_WM_STATE is ATOM[] not ATOM
    
    _NET_WM_STATE is ATOM[] not ATOM, a list of window state hints, so check all of
    the atoms, not just the first one
    
    See EWMH specifcation, section "Application Window Properties"
    
    v2: Actually use [] on the returned atom data
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 4f6dec7..7671bda 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1626,23 +1626,27 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
     }
 
     if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
-                           1L, False, XA_ATOM, &type, &format,
+                           MAXINT, False, XA_ATOM, &type, &format,
                            &nitems, &left,
                            (unsigned char **) &pAtom) == Success) {
-        if (pAtom && nitems == 1) {
-            if (*pAtom == skiptaskbarState)
-                hint |= HINT_SKIPTASKBAR;
-            if (*pAtom == hiddenState)
-                maxmin |= HINT_MIN;
-            else if (*pAtom == fullscreenState)
-                maxmin |= HINT_MAX;
-            if (*pAtom == belowState)
-                *zstyle = HWND_BOTTOM;
-            else if (*pAtom == aboveState)
-                *zstyle = HWND_TOPMOST;
-        }
-        if (pAtom)
+        if (pAtom ) {
+            unsigned long i;
+
+            for (i = 0; i < nitems; i++) {
+                if (pAtom[i] == skiptaskbarState)
+                    hint |= HINT_SKIPTASKBAR;
+                if (pAtom[i] == hiddenState)
+                    maxmin |= HINT_MIN;
+                else if (pAtom[i] == fullscreenState)
+                    maxmin |= HINT_MAX;
+                if (pAtom[i] == belowState)
+                    *zstyle = HWND_BOTTOM;
+                else if (pAtom[i] == aboveState)
+                    *zstyle = HWND_TOPMOST;
+            }
+
             XFree(pAtom);
+        }
     }
 
     nitems = left = 0;
commit 682ccac90b18f293520f77db5b163fcb40328e2b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Aug 31 21:35:14 2011 +0100

    hw/xwin: Improve WM_ENDSESSION handling using separate messaging window thread
    
    Currently, WM_ENDSESSION just calls GiveUp() to set the DE_TERMINATE flag. But
    for the X server to exit cleanly, we also need the X server dispatch loop to be
    unblocked so it can notice that DE_TERMINATE has been set and exit, removing
    it's lock file and any unix domain socket.
    
    It appears that the system will terminate the process when the last UI thread in
    that process returns from processing WM_ENDSESSION for the last top-level
    window.
    
    Since WM_ENDSESSION appears to sent by the system via SendMessage()
    (synchronously) and the wndproc is called to process it in the message thread
    for that window (the X server thread), we can't easily terminate the X server
    dispatch loop from inside the WM_ENDSESSION message processing.
    
    So, create a messaging window, a hidden, top-level window, with a separate
    thread to catch this message, and process it by calling GiveUp() and then
    blocking on a mutex until the X server dispatch loop exits.
    
    Also, notice when this is a shutdown cancel WM_ENDSESSION message and take no
    action.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 04c17b7..d6b5e4f 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -186,6 +186,25 @@ ddxBeforeReset(void)
 }
 #endif
 
+int
+main(int argc, char *argv[], char *envp[])
+{
+    int iReturn;
+
+    /* Create & acquire the termination mutex */
+    iReturn = pthread_mutex_init(&g_pmTerminating, NULL);
+    if (iReturn != 0) {
+        ErrorF("ddxMain - pthread_mutex_init () failed: %d\n", iReturn);
+    }
+
+    iReturn = pthread_mutex_lock(&g_pmTerminating);
+    if (iReturn != 0) {
+        ErrorF("ddxMain - pthread_mutex_lock () failed: %d\n", iReturn);
+    }
+
+    return dix_main(argc, argv, envp);
+}
+
 /* See Porting Layer Definition - p. 57 */
 void
 ddxGiveUp(enum ExitCode error)
@@ -243,6 +262,19 @@ ddxGiveUp(enum ExitCode error)
 
     /* Tell Windows that we want to end the app */
     PostQuitMessage(0);
+
+    {
+        winDebug("ddxGiveUp - Releasing termination mutex\n");
+
+        int iReturn = pthread_mutex_unlock(&g_pmTerminating);
+
+        if (iReturn != 0) {
+            ErrorF("winMsgWindowProc - pthread_mutex_unlock () failed: %d\n",
+                   iReturn);
+        }
+    }
+
+    winDebug("ddxGiveUp - End\n");
 }
 
 /* See Porting Layer Definition - p. 57 */
@@ -962,6 +994,10 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
     /* Store the instance handle */
     g_hInstance = GetModuleHandle(NULL);
 
+    /* Create the messaging window */
+    if (serverGeneration == 1)
+        winCreateMsgWindowThread();
+
     /* Initialize each screen */
     for (i = 0; i < g_iNumScreens; ++i) {
         /* Initialize the screen */
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index 90812ab..74a4243 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -92,6 +92,7 @@ SRCS =	InitInput.c \
 	winmonitors.c \
 	winmouse.c \
 	winmsg.c \
+	winmsgwindow.c \
 	winmultiwindowclass.c \
 	winmultiwindowicons.c \
 	winprefs.c \
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index fa774bc..dd6ed02 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1403,6 +1403,12 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
                         CARD16 height, CARD32 mmWidth, CARD32 mmHeight);
 
 /*
+ * winmsgwindow.c
+ */
+Bool
+winCreateMsgWindowThread(void);
+
+/*
  * END DDX and DIX Function Prototypes
  */
 
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index b34d1a7..b3ca295 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -78,6 +78,7 @@ Bool g_fNoHelpMessageBox = FALSE;
 Bool g_fSoftwareCursor = FALSE;
 Bool g_fSilentDupError = FALSE;
 Bool g_fNativeGl = TRUE;
+pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
 
 #ifdef XWIN_CLIPBOARD
 /*
diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h
index d2e2ba2..e7e2f7e 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -90,4 +90,6 @@ extern Bool g_fButton[3];
 extern Bool g_fNoConfigureWindow;
 #endif
 
+extern pthread_mutex_t g_pmTerminating;
+
 #endif                          /* WINGLOBALS_H */
diff --git a/hw/xwin/winmsgwindow.c b/hw/xwin/winmsgwindow.c
new file mode 100644
index 0000000..8067c69
--- /dev/null
+++ b/hw/xwin/winmsgwindow.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) Jon TURNEY 2011
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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 "win.h"
+
+/*
+ * This is the messaging window, a hidden top-level window. We never do anything
+ * with it, but other programs may send messages to it.
+ */
+
+/*
+ * winMsgWindowProc - Window procedure for msg window
+ */
+
+static
+LRESULT CALLBACK
+winMsgWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+#if CYGDEBUG
+    winDebugWin32Message("winMsgWindowProc", hwnd, message, wParam, lParam);
+#endif
+
+    switch (message) {
+    case WM_ENDSESSION:
+        if (!wParam)
+            return 0;           /* shutdown is being cancelled */
+
+        /*
+           Send a WM_GIVEUP message to the X server thread so it wakes up if
+           blocked in select(), performs GiveUp(), and then notices that GiveUp()
+           has set the DE_TERMINATE flag so exits the msg dispatch loop.
+         */
+        {
+            ScreenPtr pScreen = screenInfo.screens[0];
+
+            winScreenPriv(pScreen);
+            PostMessage(pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
+        }
+
+        /*
+           This process will be terminated by the system almost immediately
+           after the last thread with a message queue returns from processing
+           WM_ENDSESSION, so we cannot rely on any code executing after this
+           message is processed and need to wait here until ddxGiveUp() is called
+           and releases the termination mutex to guarantee that the lock file and
+           unix domain sockets have been removed
+
+           ofc, Microsoft doesn't document this under WM_ENDSESSION, you are supposed
+           to read the source of CRSS to find out how it works :-)
+
+           http://blogs.msdn.com/b/michen/archive/2008/04/04/application-termination-when-user-logs-off.aspx
+         */
+        {
+            int iReturn = pthread_mutex_lock(&g_pmTerminating);
+
+            if (iReturn != 0) {
+                ErrorF("winMsgWindowProc - pthread_mutex_lock () failed: %d\n",
+                       iReturn);
+            }
+            winDebug
+                ("winMsgWindowProc - WM_ENDSESSION termination lock acquired\n");
+        }
+
+        return 0;
+    }
+
+    return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+static HWND
+winCreateMsgWindow(void)
+{
+    HWND hwndMsg;
+    wATOM winClass;
+
+    // register window class
+    {
+        WNDCLASSEX wcx;
+
+        wcx.cbSize = sizeof(WNDCLASSEX);
+        wcx.style = CS_HREDRAW | CS_VREDRAW;
+        wcx.lpfnWndProc = winMsgWindowProc;
+        wcx.cbClsExtra = 0;
+        wcx.cbWndExtra = 0;
+        wcx.hInstance = g_hInstance;
+        wcx.hIcon = NULL;
+        wcx.hCursor = 0;
+        wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+        wcx.lpszMenuName = NULL;
+        wcx.lpszClassName = WINDOW_CLASS_X_MSG;
+        wcx.hIconSm = NULL;
+        winClass = RegisterClassEx(&wcx);
+    }
+
+    // Create the msg window.
+    hwndMsg = CreateWindowEx(0, // no extended styles
+                             WINDOW_CLASS_X_MSG,        // class name
+                             "XWin Msg Window", // window name
+                             WS_OVERLAPPEDWINDOW,       // overlapped window
+                             CW_USEDEFAULT,     // default horizontal position
+                             CW_USEDEFAULT,     // default vertical position
+                             CW_USEDEFAULT,     // default width
+                             CW_USEDEFAULT,     // default height
+                             (HWND) NULL,       // no parent or owner window
+                             (HMENU) NULL,      // class menu used
+                             GetModuleHandle(NULL),     // instance handle
+                             NULL);     // no window creation data
+
+    if (!hwndMsg) {
+        ErrorF("winCreateMsgWindow - Create msg window failed\n");
+        return NULL;
+    }
+
+    winDebug("winCreateMsgWindow - Created msg window hwnd 0x%x\n", hwndMsg);
+
+    return hwndMsg;
+}
+
+static void *
+winMsgWindowThreadProc(void *arg)
+{
+    HWND hwndMsg;
+
+    winDebug("winMsgWindowThreadProc - Hello\n");
+
+    hwndMsg = winCreateMsgWindow();
+    if (hwndMsg) {
+        MSG msg;
+
+        /* Pump the msg window message queue */
+        while (GetMessage(&msg, hwndMsg, 0, 0) > 0) {
+#if CYGDEBUG
+            winDebugWin32Message("winMsgWindowThread", msg.hwnd, msg.message,
+                                 msg.wParam, msg.lParam);
+#endif
+            DispatchMessage(&msg);
+        }
+    }
+
+    winDebug("winMsgWindowThreadProc - Exit\n");
+
+    return NULL;
+}
+
+Bool
+winCreateMsgWindowThread(void)
+{
+    pthread_t ptMsgWindowThreadProc;
+
+    /* Spawn a thread for the msg window  */
+    if (pthread_create(&ptMsgWindowThreadProc,
+                       NULL, winMsgWindowThreadProc, NULL)) {
+        /* Bail if thread creation failed */
+        ErrorF("winCreateMsgWindow - pthread_create failed.\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 25826ec..7e6bd56 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -49,6 +49,7 @@
 #define WINDOW_TITLE_XDMCP	"%s:%s.%d"
 #define WIN_SCR_PROP		"cyg_screen_prop rl"
 #define WINDOW_CLASS_X		"cygwin/x X rl"
+#define WINDOW_CLASS_X_MSG      "cygwin/x X msg"
 #define WINDOW_TITLE_X		PROJECT_NAME " X"
 #define WIN_WINDOW_PROP		"cyg_window_prop_rl"
 #ifdef HAS_DEVWINDOWS
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index c7509ea..f93072c 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1221,7 +1221,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         }
         break;
 
-    case WM_ENDSESSION:
     case WM_GIVEUP:
         /* Tell X that we are giving up */
 #ifdef XWIN_MULTIWINDOW
commit 15febb05d77cc7e7185c942f35459838f75cfdc0
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Sep 3 15:19:43 2012 +0100

    Allow DDX to provide a main()
    
    XQuartz already conditionally renames main() as dix_main() so it can provide
    it's own main().  This isn't the ideal way of doing this, as it prevents libdix
    built this way from being useful with any other DDX.
    
    So instead, always name that function dix_main(), and also provide a stub main()
    which just calls dix_main(), which can be overriden in the DDX.
    
    Add a main() to XWin (XQuartz already has one, of course).
    
    It's no longer neccessary to link XWin and XQuartz with libmain.
    
    v2: Remove unneeded stub main hw/xwin/InitOutput.c
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/configure.ac b/configure.ac
index 75281f0..d0d0fd7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1967,7 +1967,7 @@ if test "x$XQUARTZ" = xyes; then
 	AC_DEFINE(XQUARTZ,1,[Have Quartz])
 	AC_DEFINE(ROOTLESS,1,[Build Rootless code])
 
-	XQUARTZ_LIBS="$MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
+	XQUARTZ_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
 	AC_SUBST([XQUARTZ_LIBS])
 
 	AC_CHECK_LIB([Xplugin],[xp_init],[:])
diff --git a/dix/Makefile.am b/dix/Makefile.am
index b7358aa..e7ca236 100644
--- a/dix/Makefile.am
+++ b/dix/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
 AM_CFLAGS = $(DIX_CFLAGS)
 
 libmain_la_SOURCES =    \
-	main.c
+	stubmain.c
 
 libdix_la_SOURCES = 	\
 	atom.c		\
@@ -14,6 +14,7 @@ libdix_la_SOURCES = 	\
 	dispatch.c	\
 	dispatch.h	\
 	dixfonts.c	\
+	main.c		\
 	dixutils.c	\
 	enterleave.c	\
 	enterleave.h	\
diff --git a/dix/main.c b/dix/main.c
index e69cd93..05dcbed 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -125,14 +125,10 @@ BOOL serverRunning = FALSE;
 pthread_mutex_t serverRunningMutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t serverRunningCond = PTHREAD_COND_INITIALIZER;
 
-int dix_main(int argc, char *argv[], char *envp[]);
+#endif
 
 int
 dix_main(int argc, char *argv[], char *envp[])
-#else
-int
-main(int argc, char *argv[], char *envp[])
-#endif
 {
     int i;
     HWEventQueueType alwaysCheckForInput[2];
diff --git a/dix/stubmain.c b/dix/stubmain.c
new file mode 100644
index 0000000..7efb4b8
--- /dev/null
+++ b/dix/stubmain.c
@@ -0,0 +1,35 @@
+/***********************************************************
+
+Copyright 2012 Jon TURNEY
+
+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 (including the next
+paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+
+******************************************************************/
+
+int dix_main(int argc, char *argv[], char *envp[]);
+
+/*
+  A default implementation of main, which can be overridden by the DDX
+ */
+int
+main(int argc, char *argv[], char *envp[])
+{
+    return dix_main(argc, argv, envp);
+}
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index f131975..90812ab 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -153,7 +153,7 @@ INCLUDES = -I$(top_srcdir)/miext/rootless
 
 XWIN_SYS_LIBS += -ldxguid
 
-XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS)
+XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS)
 XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
 XWin_LDFLAGS = -mwindows -static
 


More information about the xorg-commit mailing list