xserver: Branch 'master' - 17 commits

Keith Packard keithp at kemper.freedesktop.org
Tue Nov 27 15:00:29 PST 2012


 hw/xwin/InitOutput.c            |   11 +++-
 hw/xwin/Makefile.am             |    8 ++
 hw/xwin/glx/indirect.c          |   22 +++++---
 hw/xwin/man/XWin.man            |   12 ++--
 hw/xwin/propertystore.h         |   83 ++++++++++++++++++++++++++++++
 hw/xwin/win.h                   |    3 -
 hw/xwin/winSetAppUserModelID.c  |  109 ++++++++++++++++++++++++++++++++++++++++
 hw/xwin/winblock.c              |    9 +++
 hw/xwin/winclipboardxevents.c   |   36 ++++++-------
 hw/xwin/winengine.c             |    6 +-
 hw/xwin/winerror.c              |   32 +++++++++--
 hw/xwin/winglobals.c            |    2 
 hw/xwin/winkeybd.c              |   47 ++++++++++++-----
 hw/xwin/winmultiwindowwm.c      |   55 +++++++++++++++++---
 hw/xwin/winmultiwindowwndproc.c |    2 
 hw/xwin/winprocarg.c            |    6 +-
 hw/xwin/winshaddd.c             |   14 +----
 hw/xwin/winshadddnl.c           |   14 +----
 hw/xwin/winshadgdi.c            |   15 +----
 hw/xwin/wintaskbar.c            |   92 +++++++++++++++++++++++++++++++++
 hw/xwin/winwin32rootless.c      |    2 
 hw/xwin/winwindow.h             |   12 ++++
 hw/xwin/winwndproc.c            |    9 ++-
 23 files changed, 499 insertions(+), 102 deletions(-)

New commits:
commit 87b60efb859d86fd9e96306112bc5453a549fa69
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Sun Sep 2 22:39:32 2012 +0100

    hw/xwin: Don't spam MotionNotify events when the mouse hasn't moved
    
    Don't spam MotionNotify events when the mouse hasn't moved, when polling the
    mouse position outside any X window
    
    (Test with 'xev -root' after mouse polling has started.)
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index fe662b9..7ba0280 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -930,6 +930,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         case WIN_POLLING_MOUSE_TIMER_ID:
         {
+            static POINT last_point;
             POINT point;
             WPARAM wL, wM, wR, wShift, wCtrl;
             LPARAM lPos;
@@ -941,8 +942,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
             point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
 
-            /* Deliver absolute cursor position to X Server */
-            winEnqueueMotion(point.x, point.y);
+            /* If the mouse pointer has moved, deliver absolute cursor position to X Server */
+            if (last_point.x != point.x || last_point.y != point.y) {
+                winEnqueueMotion(point.x, point.y);
+                last_point.x = point.x;
+                last_point.y = point.y;
+            }
 
             /* Check if a button was released but we didn't see it */
             GetCursorPos(&point);
commit 886f4c389266bf759414f15a5e25e50b5935dc9d
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Jun 25 15:58:21 2012 +0100

    hw/xwin: Don't log all fbConfigs and GL/WGL extensions
    
    Don't log all fbConfigs and GL/WGL extensions, unless verbose logging
    is requested
    Log the number of pixelFormats which gave rise to the fbConfigs
    
    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/glx/indirect.c b/hw/xwin/glx/indirect.c
index c0069a2..22c5abc 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -86,6 +86,7 @@
 
 #include <winpriv.h>
 #include <wgl_ext_api.h>
+#include <winglobals.h>
 
 #define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
 
@@ -341,6 +342,10 @@ swap_method_name(int mthd)
 static void
 fbConfigsDump(unsigned int n, __GLXconfig * c)
 {
+    LogMessage(X_INFO, "%d fbConfigs\n", n);
+
+    if (g_iLogVerbose < 3)
+        return;
     ErrorF("%d fbConfigs\n", n);
     ErrorF
         ("pxf vis  fb                      render         Ste                     aux    accum        MS    drawable             Group/\n");
@@ -595,11 +600,14 @@ glxWinScreenProbe(ScreenPtr pScreen)
     gl_renderer = (const char *) glGetStringWrapperNonstatic(GL_RENDERER);
     ErrorF("GL_RENDERER:    %s\n", gl_renderer);
     gl_extensions = (const char *) glGetStringWrapperNonstatic(GL_EXTENSIONS);
-    glxLogExtensions("GL_EXTENSIONS:  ", gl_extensions);
     wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
     if (!wgl_extensions)
         wgl_extensions = "";
-    glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
+
+    if (g_iLogVerbose >= 3) {
+        glxLogExtensions("GL_EXTENSIONS:  ", gl_extensions);
+        glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
+    }
 
     if (strcasecmp(gl_renderer, "GDI Generic") == 0) {
         free(screen);
@@ -1835,8 +1843,8 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen)
     // get the number of pixelformats
     numConfigs =
         DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
-    GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats",
-                    numConfigs);
+    LogMessage(X_INFO, "%d pixel formats reported by DescribePixelFormat\n",
+               numConfigs);
 
     /* alloc */
     result = malloc(sizeof(GLXWinConfig) * numConfigs);
@@ -2083,9 +2091,9 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen)
         return;
     }
 
-    GLWIN_DEBUG_MSG
-        ("wglGetPixelFormatAttribivARB says %d possible pixel formats",
-         numConfigs);
+    LogMessage(X_INFO,
+               "%d pixel formats reported by wglGetPixelFormatAttribivARB\n",
+               numConfigs);
 
     /* alloc */
     result = malloc(sizeof(GLXWinConfig) * numConfigs);
commit 9b10f20f472e6b0d6114fb61c88906e349e47f2b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Feb 10 13:36:46 2012 +0000

    hw/xwin: Use pre-computed extent of damage for creating GDI region
    
    When -clipupdates option is specified, use the pre-computed extent of damage,
    rather than computing a GDI region which combines all the individual boxes in
    the damage.
    
    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/winshaddd.c b/hw/xwin/winshaddd.c
index 3afc57c..aad3a02 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -489,7 +489,7 @@ winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
     POINT ptOrigin;
     DWORD dwBox = RegionNumRects(damage);
     BoxPtr pBox = RegionRects(damage);
-    HRGN hrgnTemp = NULL, hrgnCombined = NULL;
+    HRGN hrgnCombined = NULL;
 
     /*
      * Return immediately if the app is not active
@@ -551,15 +551,9 @@ winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
         BoxPtr pBoxExtents = RegionExtents(damage);
 
         /* Compute a GDI region from the damaged region */
-        hrgnCombined = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-        dwBox--;
-        pBox++;
-        while (dwBox--) {
-            hrgnTemp = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-            CombineRgn(hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
-            DeleteObject(hrgnTemp);
-            pBox++;
-        }
+        hrgnCombined =
+            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
+                          pBoxExtents->y2);
 
         /* Install the GDI region as a clipping region */
         SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index e730615..7668bd1 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -523,7 +523,7 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf)
     POINT ptOrigin;
     DWORD dwBox = RegionNumRects(damage);
     BoxPtr pBox = RegionRects(damage);
-    HRGN hrgnTemp = NULL, hrgnCombined = NULL;
+    HRGN hrgnCombined = NULL;
 
     /*
      * Return immediately if the app is not active
@@ -595,15 +595,9 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf)
         BoxPtr pBoxExtents = RegionExtents(damage);
 
         /* Compute a GDI region from the damaged region */
-        hrgnCombined = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-        dwBox--;
-        pBox++;
-        while (dwBox--) {
-            hrgnTemp = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-            CombineRgn(hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
-            DeleteObject(hrgnTemp);
-            pBox++;
-        }
+        hrgnCombined =
+            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
+                          pBoxExtents->y2);
 
         /* Install the GDI region as a clipping region */
         SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index cdbb46b..912f7e4 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -439,7 +439,7 @@ winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
     DWORD dwBox = RegionNumRects(damage);
     BoxPtr pBox = RegionRects(damage);
     int x, y, w, h;
-    HRGN hrgnTemp = NULL, hrgnCombined = NULL;
+    HRGN hrgnCombined = NULL;
 
 #ifdef XWIN_UPDATESTATS
     static DWORD s_dwNonUnitRegions = 0;
@@ -500,16 +500,11 @@ winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
         }
     }
     else if (!pScreenInfo->fMultiWindow) {
+
         /* Compute a GDI region from the damaged region */
-        hrgnCombined = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-        dwBox--;
-        pBox++;
-        while (dwBox--) {
-            hrgnTemp = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
-            CombineRgn(hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
-            DeleteObject(hrgnTemp);
-            pBox++;
-        }
+        hrgnCombined =
+            CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
+                          pBoxExtents->y2);
 
         /* Install the GDI region as a clipping region */
         SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
commit 3ab95a2a5c848e8ce4c39be243fd5e2ac6bb1c1a
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Feb 24 15:32:26 2012 +0000

    hw/xwin: Ensure we own the clipboard before checking the format of it's contents
    
    Ensure we own the clipboard before checking the format of it's contents, this
    prevents the contents from changing underneath us.
    
    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/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c
index ce533c5..5cae98c 100644
--- a/hw/xwin/winclipboardxevents.c
+++ b/hw/xwin/winclipboardxevents.c
@@ -165,6 +165,24 @@ winClipboardFlushXEvents(HWND hwnd,
                 break;
             }
 
+            /* Close clipboard if we have it open already */
+            if (GetOpenClipboardWindow() == hwnd) {
+                CloseClipboard();
+            }
+
+            /* Access the clipboard */
+            if (!OpenClipboard(hwnd)) {
+                ErrorF("winClipboardFlushXEvents - SelectionRequest - "
+                       "OpenClipboard () failed: %08lx\n", GetLastError());
+
+                /* Abort */
+                fAbort = TRUE;
+                goto winClipboardFlushXEvents_SelectionRequest_Done;
+            }
+
+            /* Indicate that clipboard was opened */
+            fCloseClipboard = TRUE;
+
             /* Check that clipboard format is available */
             if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
                 static int count;       /* Hack to stop acroread spamming the log */
@@ -192,24 +210,6 @@ winClipboardFlushXEvents(HWND hwnd,
                 goto winClipboardFlushXEvents_SelectionRequest_Done;
             }
 
-            /* Close clipboard if we have it open already */
-            if (GetOpenClipboardWindow() == hwnd) {
-                CloseClipboard();
-            }
-
-            /* Access the clipboard */
-            if (!OpenClipboard(hwnd)) {
-                ErrorF("winClipboardFlushXEvents - SelectionRequest - "
-                       "OpenClipboard () failed: %08lx\n", GetLastError());
-
-                /* Abort */
-                fAbort = TRUE;
-                goto winClipboardFlushXEvents_SelectionRequest_Done;
-            }
-
-            /* Indicate that clipboard was opened */
-            fCloseClipboard = TRUE;
-
             /* Setup the string style */
             if (event.xselectionrequest.target == XA_STRING)
                 xiccesStyle = XStringStyle;
commit a4f357c620ae9e2270316197a61fb8e1d5183a51
Author: Colin Harrison <colin.harrison at virgin.net>
Date:   Mon Apr 9 15:48:08 2012 +0100

    hw/xwin: Disable minimize button on window with skip-taskbar state
    
    If a window has had its taskbar button removed, disable its minimize
    button to prevent it becoming lost
    
    Signed-off-by: Colin Harrison <colin.harrison at virgin.net>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 7f7745f..773fc97 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1731,6 +1731,9 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
     if (hint & HINT_NOSYSMENU)
         style = style & ~WS_SYSMENU;
 
+    if (hint & HINT_SKIPTASKBAR)
+        style = style & ~WS_MINIMIZEBOX;        /* window will become lost if minimized */
+
     SetWindowLongPtr(hWnd, GWL_STYLE, style);
 
     exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
commit a2983452ee1e2051ab54cded7a3a7735be020db6
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Jul 8 17:48:03 2009 +0100

    hw/xwin: Process _NET_WM_STATE_SKIP_TASKBAR hint in multiwindow mode.
    
    Set WS_EX_TOOLWINDOW style to hide window from Alt-Tab switcher
    
    Use ITaskBarList interface to ensure that the taskbar notices if the window has
    changed it's style in a way which affects if the taskbar shows it or not
    
    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 fbf984d..7f7745f 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1503,6 +1503,7 @@ winDeinitMultiWindowWM(void)
 #define HINT_NOMAXIMIZE (1L<<4)
 #define HINT_NOMINIMIZE (1L<<5)
 #define HINT_NOSYSMENU  (1L<<6)
+#define HINT_SKIPTASKBAR (1L<<7)
 /* These two are used on their own */
 #define HINT_MAX	(1L<<0)
 #define HINT_MIN	(1L<<1)
@@ -1511,12 +1512,14 @@ static void
 winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
 {
     static Atom windowState, motif_wm_hints, windowType;
-    static Atom hiddenState, fullscreenState, belowState, aboveState;
+    static Atom hiddenState, fullscreenState, belowState, aboveState,
+        skiptaskbarState;
     static Atom dockWindow;
     static int generation;
     Atom type, *pAtom = NULL;
     int format;
-    unsigned long hint = 0, maxmin = 0, style, nitems = 0, left = 0;
+    unsigned long hint = 0, maxmin = 0, nitems = 0, left = 0;
+    unsigned long style, exStyle;
     MwmHints *mwm_hint = NULL;
 
     if (!hWnd)
@@ -1535,6 +1538,8 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
         belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
         aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
         dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
+        skiptaskbarState =
+            XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
     }
 
     if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
@@ -1542,6 +1547,8 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
                            &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)
@@ -1700,13 +1707,15 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
             HINT_NOFRAME;
 
     /* Now apply styles to window */
-    style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX;      /* Just in case */
+    style = GetWindowLongPtr(hWnd, GWL_STYLE);
     if (!style)
-        return;
+        return;                 /* GetWindowLongPointer returns 0 on failure, we hope this isn't a valid style */
+
+    style &= ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
 
-    if (!hint)                  /* All on */
+    if (!(hint & ~HINT_SKIPTASKBAR))    /* No hints, default */
         style = style | WS_CAPTION | WS_SIZEBOX;
-    else if (hint & HINT_NOFRAME)       /* All off */
+    else if (hint & HINT_NOFRAME)       /* No frame, no decorations */
         style = style & ~WS_CAPTION & ~WS_SIZEBOX;
     else
         style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) |
@@ -1723,6 +1732,17 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
         style = style & ~WS_SYSMENU;
 
     SetWindowLongPtr(hWnd, GWL_STYLE, style);
+
+    exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
+    if (hint & HINT_SKIPTASKBAR)
+        exStyle = (exStyle & ~WS_EX_APPWINDOW) | WS_EX_TOOLWINDOW;
+    else
+        exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+    SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle);
+
+    winDebug
+        ("winApplyHints: iWindow 0x%08x hints 0x%08x style 0x%08x exstyle 0x%08x\n",
+         iWindow, hint, style, exStyle);
 }
 
 void
commit de759cc38ccc8a7811923eb9620f01301aedc10e
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sun Feb 5 17:57:04 2012 +0000

    hw/xwin: Add a simple interface to the ITaskbarList COM interface
    
    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/Makefile.am b/hw/xwin/Makefile.am
index 2df1dbe..93ce570 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -102,6 +102,7 @@ SRCS =	InitInput.c \
 	winshaddd.c \
 	winshadddnl.c \
 	winshadgdi.c \
+	wintaskbar.c \
 	wintrayicon.c \
 	winvalargs.c \
 	winwakeup.c \
diff --git a/hw/xwin/wintaskbar.c b/hw/xwin/wintaskbar.c
new file mode 100644
index 0000000..7dd4ec3
--- /dev/null
+++ b/hw/xwin/wintaskbar.c
@@ -0,0 +1,92 @@
+/*
+  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.
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include "win.h"
+#include "winwindow.h"
+
+const GUID CLSID_TaskbarList = {0x56fdf344,0xfd6d,0x11d0,{0x95,0x8a,0x0,0x60,0x97,0xc9,0xa0,0x90}};
+const GUID IID_ITaskbarList =  {0x56fdf342,0xfd6d,0x11d0,{0x95,0x8a,0x0,0x60,0x97,0xc9,0xa0,0x90}};
+
+#ifdef INTERFACE
+#undef INTERFACE
+#endif
+
+#define INTERFACE ITaskbarList
+DECLARE_INTERFACE_(ITaskbarList, IUnknown)
+{
+  /* IUnknown methods */
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
+  STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+  STDMETHOD_(ULONG, Release) (THIS) PURE;
+
+  /* ITaskbarList methods */
+  STDMETHOD(HrInit) (THIS) PURE;
+  STDMETHOD(AddTab) (THIS_ HWND hWnd) PURE;
+  STDMETHOD(DeleteTab) (THIS_ HWND hWnd) PURE;
+  STDMETHOD(ActivateTab) (THIS_ HWND hWnd) PURE;
+  STDMETHOD(SetActiveAlt) (THIS_ HWND hWnd) PURE;
+};
+#undef INTERFACE
+
+/*
+   The stuff above needs to be in win32api headers, not defined here,
+   or at least generated from the MIDL :-)
+*/
+
+/*
+  This is unnecessarily heavyweight, we could just call CoInitialize() once at
+   startup and CoUninitialize() once at shutdown
+*/
+
+/*
+  The documentation for ITaskbarList::AddTab says that we are responsible for
+   deleting the tab ourselves when the window is deleted, but that doesn't actually
+   seem to be the case
+*/
+
+void winShowWindowOnTaskbar(HWND hWnd, BOOL show)
+{
+  ITaskbarList* pTaskbarList = NULL;
+
+  if (SUCCEEDED(CoInitialize(NULL)))
+    {
+      if (SUCCEEDED(CoCreateInstance((const CLSID *)&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, (const IID *)&IID_ITaskbarList, (void**)&pTaskbarList)))
+        {
+          if (SUCCEEDED(pTaskbarList->lpVtbl->HrInit(pTaskbarList)))
+            {
+              if (show)
+                {
+                  pTaskbarList->lpVtbl->AddTab(pTaskbarList,hWnd);
+                }
+              else
+                {
+                  pTaskbarList->lpVtbl->DeleteTab(pTaskbarList,hWnd);
+                }
+            }
+          pTaskbarList->lpVtbl->Release(pTaskbarList);
+        }
+      CoUninitialize();
+    }
+}
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 4540dd0..37b9752 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -157,5 +157,8 @@ void
 void
  winSetAppUserModelID(HWND hWnd, const char *AppID);
 
+void
+ winShowWindowOnTaskbar(HWND hWnd, BOOL show);
+
 #endif                          /* XWIN_MULTIWINDOW */
 #endif
commit 19d875187a113ca7772a770767ea2ceb2ade5a43
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Jan 4 17:40:14 2012 +0000

    hw/xwin: Enable RANDR resize by default
    
    Also fix erroneous use of '--resize' not '-resize', and document '-noresize' in man page
    
    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 b345107..78ff74f 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -807,7 +807,7 @@ winUseMsg(void)
     ErrorF("-resize=none|scrollbars|randr"
            "\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n"
            "\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n"
-           "\textension to resize the X screen.\n");
+           "\textension to resize the X screen.  'randr' is the default.\n");
 
     ErrorF("-rootless\n" "\tRun the server in rootless mode.\n");
 
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index fe173b1..18ee667 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -121,14 +121,16 @@ Alternative name for \fB\-resize=scrollbars\fP.
 .SH OPTIONS CONTROLLING RESIZE BEHAVIOUR
 .TP 8
 .B \-resize[=none|scrollbars|randr]
-Select the resize mode of an X screen.
+Select the resize mode of an X screen. The default is randr.
 
 .RS
 .IP \fB\-resize=none\fP 8
-(default). The screen is not resizable.
+The screen is not resizable.
 
 In windowed mode, if the window has decorations, a fixed frame is used.
 
+Alternative name is \fB\-noresize\fP.
+
 .IP \fB\-resize=scrollbars\fP 8
 The screen window is resizeable, but the screen is not resizable.
 
@@ -159,8 +161,8 @@ of the X screen using the RANDR extension is not permitted.
 
 The maximum dimensions of the screen are the dimensions of the \fIWindows\fP virtual desktop.
 
-.IP \fB\--resize\fP 8
-on its own is equivalent to \fB\--resize=randr\fP
+.IP \fB\-resize\fP 8
+on its own is equivalent to \fB\-resize=randr\fP
 .RE
 
 .SH OPTIONS CONTROLLING WINDOWS INTEGRATION
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 80d0937..858be4a 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -142,7 +142,7 @@ winInitializeScreenDefaults(void)
 #endif
     defaultScreenInfo.fMultipleMonitors = FALSE;
     defaultScreenInfo.fLessPointer = FALSE;
-    defaultScreenInfo.iResizeMode = notAllowed;
+    defaultScreenInfo.iResizeMode = resizeWithRandr;
     defaultScreenInfo.fNoTrayIcon = FALSE;
     defaultScreenInfo.iE3BTimeout = WIN_E3B_DEFAULT;
     defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
commit 444580673221bf3f89dfa3cbc518b5ed4ecabc23
Author: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
Date:   Sat Dec 31 22:11:18 2011 -0600

    hw/xwin: Enable AIGLX by default
    
    Signed-off-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>
    Reviewed-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 f4d4e90..b345107 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -840,7 +840,7 @@ winUseMsg(void)
 
 #ifdef XWIN_GLX_WINDOWS
     ErrorF("-[no]wgl\n"
-           "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
+           "\tEnable the GLX extension to use the native Windows WGL interface for hardware-accelerated OpenGL\n");
 #endif
 
     ErrorF("-[no]winkill\n" "\tAlt+F4 exits the X Server.\n");
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index dbadad6..fe173b1 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -211,7 +211,7 @@ is disabled by default.
 .TP 8
 .B \-[no]wgl
 Enable [disable] the GLX extension to use the native Windows WGL interface
-for hardware accelerated OpenGL (AIGLX). (Experimental)
+for hardware accelerated OpenGL (AIGLX). The default is enabled.
 .TP 8
 .B \-[no]winkill
 Enable or disable the \fIAlt-F4\fP key combination as a signal to exit the
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 4953bd0..b34d1a7 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -77,7 +77,7 @@ Bool g_fKeyboardHookLL = FALSE;
 Bool g_fNoHelpMessageBox = FALSE;
 Bool g_fSoftwareCursor = FALSE;
 Bool g_fSilentDupError = FALSE;
-Bool g_fNativeGl = FALSE;
+Bool g_fNativeGl = TRUE;
 
 #ifdef XWIN_CLIPBOARD
 /*
commit 11bb32e561b3f1c657a99b3902f9beea786babbb
Author: Oliver Schmidt <oschmidt-mailinglists at gmx.de>
Date:   Sun Jan 8 20:30:02 2012 +0000

    hw/xwin: Restore non-latching modifier key state when an X window gains focus
    
    In multiwindow mode, the state of the modifier keys was lost when a window is
    created (or raised) and focus moved to that window.
    
    For example: In window A Ctrl + some key opens a window B, then in window B Ctrl
    + some other key triggers the next action. However after the opening of window B
    the Ctrl key has to be released and pressed again. If the user keeps the Ctrl
    key held down when the window B is opened, the next key press X will be
    interpreted as X and not as Ctrl+X.
    
    Extended the function winRestoreModeKeyStates in winkeybd.c to consider not only
    the latching modifier keys but also the modifiers Ctrl, Shift, Alt/AltGr by
    using the Windows function GetAsyncKeyState.
    
    A combined Ctrl+AltGr modifier state cannot be restored correctly, as Windows
    always fakes a Ctrl-L when AltGr is pressed.
    
    Signed-off-by: Oliver Schmidt <oschmidt-mailinglists at gmx.de>
    Reviewed-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 104ca58..a70cdcd 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -262,6 +262,28 @@ winRestoreModeKeyStates(void)
         XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
     winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);
 
+    /* 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 alt = (GetAsyncKeyState(VK_LMENU) < 0);
+        BOOL altgr = (GetAsyncKeyState(VK_RMENU) < 0);
+
+        if (ctrl && altgr)
+            ctrl = FALSE;
+
+        if (LOGICAL_XOR(internalKeyStates & ControlMask, ctrl))
+            winSendKeyEvent(KEY_LCtrl, ctrl);
+
+        if (LOGICAL_XOR(internalKeyStates & ShiftMask, shift))
+            winSendKeyEvent(KEY_ShiftL, shift);
+
+        if (LOGICAL_XOR(internalKeyStates & Mod1Mask, alt))
+            winSendKeyEvent(KEY_Alt, alt);
+
+        if (LOGICAL_XOR(internalKeyStates & Mod5Mask, altgr))
+            winSendKeyEvent(KEY_AltLang, altgr);
+    }
 
     /*
        Check if latching modifier key states have changed, and if so,
commit 47291d0b7d7bfee74156f83badae15a0818c68ad
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Nov 5 14:54:51 2012 +0000

    hw/xwin: Give our logical xor operator a more logical name
    
    Also, rather than a comment about why we need a logical operator, let's have a
    comment about what we are doing to the keyboard state...
    
    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 7b34e84..180695e 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -248,9 +248,6 @@ if (++PROFPT##point % thresh == 0)\
 ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\
 }
 
-/* We use xor this macro for detecting toggle key state changes */
-#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
-
 #define DEFINE_ATOM_HELPER(func,atom_name)			\
 static Atom func (void) {					\
     static int generation;					\
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index 2ffb9a9..104ca58 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -41,6 +41,9 @@
 
 #include "xkbsrv.h"
 
+/* C does not have a logical XOR operator, so we use a macro instead */
+#define LOGICAL_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
+
 static Bool g_winKeyState[NUM_KEYCODES];
 
 /*
@@ -259,36 +262,32 @@ winRestoreModeKeyStates(void)
         XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
     winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);
 
-    /* 
-     * NOTE: The C XOR operator, ^, will not work here because it is
-     * a bitwise operator, not a logical operator.  C does not
-     * have a logical XOR operator, so we use a macro instead.
-     */
 
-    /* Has the key state changed? */
+    /*
+       Check if latching modifier key states have changed, and if so,
+       fake a press and a release to toggle the modifier to the correct
+       state
+    */
     dwKeyState = GetKeyState(VK_NUMLOCK) & 0x0001;
-    if (WIN_XOR(internalKeyStates & NumLockMask, dwKeyState)) {
+    if (LOGICAL_XOR(internalKeyStates & NumLockMask, dwKeyState)) {
         winSendKeyEvent(KEY_NumLock, TRUE);
         winSendKeyEvent(KEY_NumLock, FALSE);
     }
 
-    /* Has the key state changed? */
     dwKeyState = GetKeyState(VK_CAPITAL) & 0x0001;
-    if (WIN_XOR(internalKeyStates & LockMask, dwKeyState)) {
+    if (LOGICAL_XOR(internalKeyStates & LockMask, dwKeyState)) {
         winSendKeyEvent(KEY_CapsLock, TRUE);
         winSendKeyEvent(KEY_CapsLock, FALSE);
     }
 
-    /* Has the key state changed? */
     dwKeyState = GetKeyState(VK_SCROLL) & 0x0001;
-    if (WIN_XOR(internalKeyStates & ScrollLockMask, dwKeyState)) {
+    if (LOGICAL_XOR(internalKeyStates & ScrollLockMask, dwKeyState)) {
         winSendKeyEvent(KEY_ScrollLock, TRUE);
         winSendKeyEvent(KEY_ScrollLock, FALSE);
     }
 
-    /* Has the key state changed? */
     dwKeyState = GetKeyState(VK_KANA) & 0x0001;
-    if (WIN_XOR(internalKeyStates & KanaMask, dwKeyState)) {
+    if (LOGICAL_XOR(internalKeyStates & KanaMask, dwKeyState)) {
         winSendKeyEvent(KEY_HKTG, TRUE);
         winSendKeyEvent(KEY_HKTG, FALSE);
     }
commit 8aa27ae82109e4fab0ff3ed86ad1d152438a2585
Author: Tobias Häußler <tobias.haeussler at gmx.de>
Date:   Mon Jul 18 14:48:23 2011 +0100

    hw/xwin: Add correct taskbar grouping of X windows on Windows 7
    
    I created a small patch for XWin that adds correct grouping of taskbar icons
    when 'Always combine, hide labels' is set in the taskbar properties. It uses the
    new taskbar APIs introduced in Windows 7 to set an application id for each
    window. The id is based on the X11 class hints.
    
    v2: Add file to _SOURCES to fix distcheck
    
    v3 : Fix compilation with mingw-w64 w32api headers
    Include propkey.h, propsys.h rather than defining necessary stuff ourselves
    
    v4: Fix up names taskbar->propertystore, AppID->AppUserModelID, etc.
    Link directly with ole32 for PropVariantClear(), prototyping it if neccessary.
    
    v5: Put winSetAppUserModelID()-related code in a separate file.
    Drop a superfluous assign to hr of ignored HRESULT of SetValue()
    
    Signed-off-by: Tobias Häußler <tobias.haeussler at gmx.de>
    Reviewed-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 4bcd3a0..f4d4e90 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -204,6 +204,9 @@ ddxGiveUp(enum ExitCode error)
     }
 
 #ifdef XWIN_MULTIWINDOW
+    /* Unload libraries for taskbar grouping */
+    winPropertyStoreDestroy();
+
     /* Notify the worker threads we're exiting */
     winDeinitMultiWindowWM();
 #endif
@@ -951,6 +954,10 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
 
     /* Detect supported engines */
     winDetectSupportedEngines();
+#ifdef XWIN_MULTIWINDOW
+    /* Load libraries for taskbar grouping */
+    winPropertyStoreInit();
+#endif
 
     /* Store the instance handle */
     g_hInstance = GetModuleHandle(NULL);
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index 3fcaf9d..2df1dbe 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -23,8 +23,11 @@ SRCS_MULTIWINDOW = \
 	winmultiwindowshape.c \
 	winmultiwindowwindow.c \
 	winmultiwindowwm.c \
-	winmultiwindowwndproc.c
+	winmultiwindowwndproc.c \
+	propertystore.h \
+	winSetAppUserModelID.c
 DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+MULTIWINDOW_LIBS = -lshlwapi -lole32
 endif
 
 if XWIN_MULTIWINDOWEXTWM
@@ -150,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_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_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
 
 .rc.o:
diff --git a/hw/xwin/propertystore.h b/hw/xwin/propertystore.h
new file mode 100644
index 0000000..6afc6c9
--- /dev/null
+++ b/hw/xwin/propertystore.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Tobias Häußler
+ *
+ * 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.
+ */
+
+#ifndef PROPERTYSTORE_H
+#define PROPERTYSTORE_H
+
+#include <windows.h>
+
+#ifdef __MINGW64_VERSION_MAJOR
+/* If we are using headers from mingw-w64 project, it provides the PSDK headers this needs ... */
+#include <propkey.h>
+#include <propsys.h>
+#else /*  !__MINGW64_VERSION_MAJOR */
+/* ... otherwise, we need to define all this stuff ourselves */
+
+typedef struct _tagpropertykey {
+    GUID fmtid;
+    DWORD pid;
+} PROPERTYKEY;
+
+#define REFPROPERTYKEY const PROPERTYKEY *
+#define REFPROPVARIANT const PROPVARIANT *
+
+WINOLEAPI PropVariantClear(PROPVARIANT *pvar);
+
+#ifdef INTERFACE
+#undef INTERFACE
+#endif
+
+#define INTERFACE IPropertyStore
+DECLARE_INTERFACE_(IPropertyStore, IUnknown)
+{
+    STDMETHOD(QueryInterface) (THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+    STDMETHOD_(ULONG, Release) (THIS) PURE;
+    STDMETHOD(GetCount) (THIS_ DWORD) PURE;
+    STDMETHOD(GetAt) (THIS_ DWORD, PROPERTYKEY) PURE;
+    STDMETHOD(GetValue) (THIS_ REFPROPERTYKEY, PROPVARIANT) PURE;
+    STDMETHOD(SetValue) (THIS_ REFPROPERTYKEY, REFPROPVARIANT) PURE;
+    STDMETHOD(Commit) (THIS) PURE;
+};
+
+#undef INTERFACE
+typedef IPropertyStore *LPPROPERTYSTORE;
+
+DEFINE_GUID(IID_IPropertyStore, 0x886d8eeb, 0x8cf2, 0x4446, 0x8d, 0x02, 0xcd,
+            0xba, 0x1d, 0xbd, 0xcf, 0x99);
+
+#ifdef INITGUID
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) GUID_EXT const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }, pid }
+#else
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) GUID_EXT const PROPERTYKEY name
+#endif
+
+DEFINE_PROPERTYKEY(PKEY_AppUserModel_ID, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0,
+                   0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 5);
+
+#endif /* !__MINGW64_VERSION_MAJOR */
+
+typedef HRESULT(__stdcall * SHGETPROPERTYSTOREFORWINDOWPROC) (HWND, REFIID,
+                                                              void **);
+
+#endif
diff --git a/hw/xwin/winSetAppUserModelID.c b/hw/xwin/winSetAppUserModelID.c
new file mode 100644
index 0000000..ce9da5e
--- /dev/null
+++ b/hw/xwin/winSetAppUserModelID.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011 Tobias Häußler
+ *
+ * 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.
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/Xwindows.h>
+#include "winwindow.h"
+#include "os.h"
+#include "winmsg.h"
+
+#include <shlwapi.h>
+
+#define INITGUID
+#include "initguid.h"
+#include "propertystore.h"
+#undef INITGUID
+
+static HMODULE g_hmodShell32Dll = NULL;
+static SHGETPROPERTYSTOREFORWINDOWPROC g_pSHGetPropertyStoreForWindow = NULL;
+
+void
+winPropertyStoreInit(void)
+{
+    /*
+       Load library and get function pointer to SHGetPropertyStoreForWindow()
+
+       SHGetPropertyStoreForWindow is only supported since Windows 7. On previous
+       versions the pointer will be NULL and taskbar grouping is not supported.
+       winSetAppUserModelID() will do nothing in this case.
+     */
+    g_hmodShell32Dll = LoadLibrary("shell32.dll");
+    if (g_hmodShell32Dll == NULL) {
+        ErrorF("winPropertyStoreInit - Could not load shell32.dll\n");
+        return;
+    }
+
+    g_pSHGetPropertyStoreForWindow =
+        (SHGETPROPERTYSTOREFORWINDOWPROC) GetProcAddress(g_hmodShell32Dll,
+                                                         "SHGetPropertyStoreForWindow");
+    if (g_pSHGetPropertyStoreForWindow == NULL) {
+        ErrorF
+            ("winPropertyStoreInit - Could not get SHGetPropertyStoreForWindow address\n");
+        return;
+    }
+}
+
+void
+winPropertyStoreDestroy(void)
+{
+    if (g_hmodShell32Dll != NULL) {
+        FreeLibrary(g_hmodShell32Dll);
+        g_hmodShell32Dll = NULL;
+        g_pSHGetPropertyStoreForWindow = NULL;
+    }
+}
+
+void
+winSetAppUserModelID(HWND hWnd, const char *AppID)
+{
+    PROPVARIANT pv;
+    IPropertyStore *pps = NULL;
+    HRESULT hr;
+
+    if (g_pSHGetPropertyStoreForWindow == NULL) {
+        return;
+    }
+
+    winDebug("winSetAppUserMOdelID - hwnd 0x%08x appid '%s'\n", hWnd, AppID);
+
+    hr = g_pSHGetPropertyStoreForWindow(hWnd, &IID_IPropertyStore,
+                                        (void **) &pps);
+    if (SUCCEEDED(hr) && pps) {
+        memset(&pv, 0, sizeof(PROPVARIANT));
+        if (AppID) {
+            pv.vt = VT_LPWSTR;
+            hr = SHStrDupA(AppID, &pv.pwszVal);
+        }
+
+        if (SUCCEEDED(hr)) {
+            pps->lpVtbl->SetValue(pps, &PKEY_AppUserModel_ID, &pv);
+            PropVariantClear(&pv);
+        }
+        pps->lpVtbl->Release(pps);
+    }
+}
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 42925e3..fbf984d 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -1630,10 +1630,14 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
         XFree(normal_hint);
     }
 
-    /* Override hint settings from above with settings from config file */
+    /*
+       Override hint settings from above with settings from config file and set
+       application id for grouping.
+     */
     {
         XClassHint class_hint = { 0, 0 };
         char *window_name = 0;
+        char *application_id = 0;
 
         if (XGetClassHint(pDisplay, iWindow, &class_hint)) {
             XFetchName(pDisplay, iWindow, &window_name);
@@ -1642,10 +1646,24 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
                 winOverrideStyle(class_hint.res_name, class_hint.res_class,
                                  window_name);
 
+#define APPLICATION_ID_FORMAT	"%s.xwin.%s"
+#define APPLICATION_ID_UNKNOWN "unknown"
+            if (class_hint.res_class) {
+                asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
+                         class_hint.res_class);
+            }
+            else {
+                asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
+                         APPLICATION_ID_UNKNOWN);
+            }
+            winSetAppUserModelID(hWnd, application_id);
+
             if (class_hint.res_name)
                 XFree(class_hint.res_name);
             if (class_hint.res_class)
                 XFree(class_hint.res_class);
+            if (application_id)
+                free(application_id);
             if (window_name)
                 XFree(window_name);
         }
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index af917d6..4180a3a 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -825,6 +825,8 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
         break;
 
     case WM_CLOSE:
+        /* Removep AppUserModelID property */
+        winSetAppUserModelID(hwnd, NULL);
         /* Branch on if the window was killed in X already */
         if (pWinPriv->fXKilled) {
             /* Window was killed, go ahead and destroy the window */
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 49a720a..4540dd0 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -148,5 +148,14 @@ void
 void
  winMinimizeWindow(Window id);
 
+void
+ winPropertyStoreInit(void);
+
+void
+ winPropertyStoreDestroy(void);
+
+void
+ winSetAppUserModelID(HWND hWnd, const char *AppID);
+
 #endif                          /* XWIN_MULTIWINDOW */
 #endif
commit f3aef7f9561d2723da0d1438a8b276b77a1e672e
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sun Sep 2 16:04:25 2012 +0100

    hw/xwin: Fix function name in log message
    
    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/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 5bf7102..9743092 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -263,7 +263,7 @@ winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
     strcat(pszClass, pszWindowID);
 
 #if CYGMULTIWINDOW_DEBUG
-    winDebug("winCreateWindowsWindow - Creating class: %s\n", pszClass);
+    winDebug("winMWExtWMCreateFrame - Creating class: %s\n", pszClass);
 #endif
 
     /* Setup our window class */
commit 127a7068b75258d396776cc101aba0bef10a5cef
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Apr 14 23:10:23 2011 +0100

    hw/xwin: Allow XScreenSaverSuspend() to effect Windows screen saver or monitor power off
    
    Reset the idle timer in the block handler if screenSaverSuspended is set.
    
    This isn't quite a complete solution.  We should also set the block timeout to
    something less than the idle timer timeout to ensure we will reset the idle
    timer before it times out if we are blocking.
    
    The idle timer timeout is presumably the first one to expire of the screen saver
    activation or monitor low power or power down timeout, depending on
    configuration.
    
    Unfortunately this is probably not straightforward to do. Whilst
    SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT) is portable, apparently
    SPI_GETLOWPOWERTIMEOUT and SPI_GETPOWEROFFTIMEOUT are not supported by Windows
    versions 6.0 or later, and the interface for discovering equivalent value is
    complex.
    
    This doesn't matter in the case where a media player or similar application is
    the one making the XScreenSaverSuspend() requests, as it will be continuously
    drawing, causing the X server to become unblocked often.
    
    In the case where slide show presentation application or similar is the one
    making the XScreenSaverSuspend() request, this might be a problem.
    
    Since "Powerpoint is Evil" [1], I think we'll leave it like this till someone
    complains :-)
    
    [1] http://www.edwardtufte.com/tufte/books_pp
    
    v2: conditionalize on SCREENSAVER
    
    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/winblock.c b/hw/xwin/winblock.c
index 480e3bd..a4ae866 100644
--- a/hw/xwin/winblock.c
+++ b/hw/xwin/winblock.c
@@ -86,4 +86,13 @@ winBlockHandler(ScreenPtr pScreen,
             DispatchMessage(&msg);
         }
     }
+
+  /*
+    At least one X client has asked to suspend the screensaver, so
+    reset Windows' display idle timer
+  */
+#ifdef SCREENSAVER
+  if (screenSaverSuspended)
+    SetThreadExecutionState(ES_DISPLAY_REQUIRED);
+#endif
 }
commit 190f165317c4a58adf38e3e32acfe7cf04850e91
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Nov 5 13:02:46 2012 +0000

    hw/xwin: Avoid logging an extra blank line if BUILDERSTRING is empty
    
    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/winprocarg.c b/hw/xwin/winprocarg.c
index 14056fa..80d0937 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -1161,6 +1161,8 @@ winLogVersionInfo(void)
     ErrorF("Vendor: %s\n", XVENDORNAME);
     ErrorF("Release: %d.%d.%d.%d\n", XORG_VERSION_MAJOR,
            XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP);
-    ErrorF("%s\n\n", BUILDERSTRING);
+    if (strlen(BUILDERSTRING))
+        ErrorF("%s\n", BUILDERSTRING);
     ErrorF("Contact: %s\n", BUILDERADDR);
+    ErrorF("\n");
 }
commit ef9dbea24f5ce7e1e400463ab2a333076d98a28e
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Aug 31 20:57:05 2011 +0100

    hw/xwin: Report which drawing engines are being enabled when checking for support
    
    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/winengine.c b/hw/xwin/winengine.c
index 6748959..b2007d7 100644
--- a/hw/xwin/winengine.c
+++ b/hw/xwin/winengine.c
@@ -92,7 +92,7 @@ winDetectSupportedEngines(void)
         else {
             /* We have DirectDraw */
             winErrorFVerb(2,
-                          "winDetectSupportedEngines - DirectDraw installed\n");
+                          "winDetectSupportedEngines - DirectDraw installed, allowing ShadowDD\n");
             g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
 
 #ifdef XWIN_PRIMARYFB
@@ -100,7 +100,7 @@ winDetectSupportedEngines(void)
             if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
                 g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD;
                 winErrorFVerb(2,
-                              "winDetectSupportedEngines - Allowing PrimaryDD\n");
+                              "winDetectSupportedEngines - Windows NT, allowing PrimaryDD\n");
             }
 #endif
         }
@@ -112,7 +112,7 @@ winDetectSupportedEngines(void)
         if (SUCCEEDED(ddrval)) {
             /* We have DirectDraw4 */
             winErrorFVerb(2,
-                          "winDetectSupportedEngines - DirectDraw4 installed\n");
+                          "winDetectSupportedEngines - DirectDraw4 installed, allowing ShadowDDNL\n");
             g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL;
         }
 
commit 5824166256c8e96c91e225f4ccb2b094b8fb045b
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Fri Mar 12 14:38:51 2010 +0000

    hw/xwin: Show any fatal error message
    
    Report the fatal error message in the dialog we pop up, rather than just
    referring the user to the logfile.
    
    v2: Do this a better way since the "Pass the FatalError message to
    OsVendorFatalError" patch has landed, and OsVendorFatalError() now gets passed
    the fatal error message
    
    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/winerror.c b/hw/xwin/winerror.c
index 6645469..1318b0f 100644
--- a/hw/xwin/winerror.c
+++ b/hw/xwin/winerror.c
@@ -59,15 +59,16 @@ OsVendorVErrorF(const char *pszFormat, va_list va_args)
 #endif
 
 /*
- * os/util.c/FatalError () calls our vendor ErrorF, so the message
- * from a FatalError will be logged.  Thus, the message for the
- * fatal error is not passed to this function.
+ * os/log.c:FatalError () calls our vendor ErrorF, so the message
+ * from a FatalError will be logged.
  *
  * Attempt to do last-ditch, safe, important cleanup here.
  */
 void
 OsVendorFatalError(const char *f, va_list args)
 {
+    char errormsg[1024] = "";
+
     /* Don't give duplicate warning if UseMsg was called */
     if (g_fSilentFatalError)
         return;
@@ -78,9 +79,28 @@ OsVendorFatalError(const char *f, va_list args)
     }
     LogClose(EXIT_ERR_ABORT);
 
-    winMessageBoxF("A fatal error has occurred and " PROJECT_NAME
-                   " will now exit.\n" "Please open %s for more information.\n",
-                   MB_ICONERROR, (g_pszLogFile ? g_pszLogFile : "the logfile"));
+    /* Format the error message */
+    vsnprintf(errormsg, sizeof(errormsg), f, args);
+
+    /*
+       Sometimes the error message needs a bit of cosmetic cleaning
+       up for use in a dialog box...
+     */
+    {
+        char *s;
+
+        while ((s = strstr(errormsg, "\n\t")) != NULL) {
+            s[0] = ' ';
+            s[1] = '\n';
+        }
+    }
+
+    winMessageBoxF("A fatal error has occurred and " PROJECT_NAME " will now exit.\n\n"
+                   "%s\n\n"
+                   "Please open %s for more information.\n",
+                   MB_ICONERROR,
+                   errormsg,
+                   (g_pszLogFile ? g_pszLogFile : "the logfile"));
 }
 
 /*


More information about the xorg-commit mailing list