aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xwin/winmultiwindowwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xwin/winmultiwindowwm.c')
-rw-r--r--xorg-server/hw/xwin/winmultiwindowwm.c644
1 files changed, 391 insertions, 253 deletions
diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c
index 76b46837c..88109ceab 100644
--- a/xorg-server/hw/xwin/winmultiwindowwm.c
+++ b/xorg-server/hw/xwin/winmultiwindowwm.c
@@ -43,12 +43,14 @@
#include <fcntl.h>
#include <setjmp.h>
#define HANDLE void *
+#ifdef _MSC_VER
+typedef int pid_t;
+#endif
#include <pthread.h>
#undef HANDLE
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
-#include <X11/Xlocale.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
@@ -61,9 +63,15 @@
#include "winprefs.h"
#include "window.h"
#include "pixmapstr.h"
+#include "winmsg.h"
#include "windowstr.h"
+#include "winmultiwindowclass.h"
+
+#include <shlwapi.h>
+#include "taskbar.h"
#ifdef XWIN_MULTIWINDOWEXTWM
+#define _WINDOWSWM_SERVER_
#include <X11/extensions/windowswmstr.h>
#else
/* We need the native HWND atom for intWM, so for consistency use the
@@ -75,10 +83,6 @@ extern void winDebug(const char *format, ...);
extern void winReshapeMultiWindow(WindowPtr pWin);
extern void winUpdateRgnMultiWindow(WindowPtr pWin);
-#ifndef CYGDEBUG
-#define CYGDEBUG NO
-#endif
-
/*
* Constant defines
*/
@@ -105,7 +109,9 @@ typedef struct _WMMsgQueueRec {
struct _WMMsgNodeRec *pTail;
pthread_mutex_t pmMutex;
pthread_cond_t pcNotEmpty;
+#ifdef _DEBUG
int nQueueSize;
+#endif
} WMMsgQueueRec, *WMMsgQueuePtr;
typedef struct _WMInfo {
@@ -114,7 +120,9 @@ typedef struct _WMInfo {
Atom atmWmProtos;
Atom atmWmDelete;
Atom atmPrivMap;
+#ifdef XWIN_MULTIWINDOWINTWM
Bool fAllowOtherWM;
+#endif
} WMInfoRec, *WMInfoPtr;
typedef struct _WMProcArgRec {
@@ -151,7 +159,7 @@ static Bool
InitQueue(WMMsgQueuePtr pQueue);
static void
- GetWindowName(Display * pDpy, Window iWin, wchar_t ** ppName);
+ GetWindowName(Display * pDpy, Window iWin, char **ppWindowName);
static int
SendXMessage(Display * pDisplay, Window iWin, Atom atmType, long nData);
@@ -175,17 +183,15 @@ static int
static int
winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay);
+static void
+winMultiWindowThreadExit(void *arg);
+
static int
winRedirectErrorHandler(Display * pDisplay, XErrorEvent * pErr);
static void
winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg);
-#if 0
-static void
- PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction);
-#endif
-
static Bool
CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
@@ -210,6 +216,10 @@ static pthread_t g_winMultiWindowXMsgProcThread;
static Bool g_shutdown = FALSE;
static Bool redirectError = FALSE;
static Bool g_fAnotherWMRunning = FALSE;
+static HMODULE g_hmodShell32Dll = NULL;
+static HMODULE g_hmodOle32Dll = NULL;
+static SHGETPROPERTYSTOREFORWINDOWPROC g_pSHGetPropertyStoreForWindow = NULL;
+static PROPVARIANTCLEARPROC g_pPropVariantClear = NULL;
/*
* PushMessage - Push a message onto the queue
@@ -233,46 +243,10 @@ PushMessage(WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
pQueue->pHead = pNode;
}
-#if 0
- switch (pNode->msg.msg) {
- case WM_WM_MOVE:
- ErrorF("\tWM_WM_MOVE\n");
- break;
- case WM_WM_SIZE:
- ErrorF("\tWM_WM_SIZE\n");
- break;
- case WM_WM_RAISE:
- ErrorF("\tWM_WM_RAISE\n");
- break;
- case WM_WM_LOWER:
- ErrorF("\tWM_WM_LOWER\n");
- break;
- case WM_WM_MAP:
- ErrorF("\tWM_WM_MAP\n");
- break;
- case WM_WM_MAP2:
- ErrorF("\tWM_WM_MAP2\n");
- break;
- case WM_WM_MAP3:
- ErrorF("\tWM_WM_MAP3\n");
- break;
- case WM_WM_UNMAP:
- ErrorF("\tWM_WM_UNMAP\n");
- break;
- case WM_WM_KILL:
- ErrorF("\tWM_WM_KILL\n");
- break;
- case WM_WM_ACTIVATE:
- ErrorF("\tWM_WM_ACTIVATE\n");
- break;
- default:
- ErrorF("\tUnknown Message.\n");
- break;
- }
-#endif
-
+#ifdef _DEBUG
/* Increase the count of elements in the queue by one */
++(pQueue->nQueueSize);
+#endif
/* Release the queue mutex */
pthread_mutex_unlock(&pQueue->pmMutex);
@@ -281,7 +255,7 @@ PushMessage(WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
pthread_cond_signal(&pQueue->pcNotEmpty);
}
-#if CYGMULTIWINDOW_DEBUG
+#ifdef WINDBG
/*
* QueueSize - Return the size of the queue
*/
@@ -326,12 +300,12 @@ PopMessage(WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
pQueue->pTail = NULL;
}
+ #ifdef _DEBUG
/* Drop the number of elements in the queue by one */
--(pQueue->nQueueSize);
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue));
-#endif
+ winDebug ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue));
+ #endif
/* Release the queue mutex */
pthread_mutex_unlock(&pQueue->pmMutex);
@@ -377,60 +351,41 @@ InitQueue(WMMsgQueuePtr pQueue)
pQueue->pTail = NULL;
/* There are no elements initially */
+ #ifdef _DEBUG
pQueue->nQueueSize = 0;
-#if CYGMULTIWINDOW_DEBUG
winDebug("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize,
QueueSize(pQueue));
-#endif
+ #endif
- winDebug("InitQueue - Calling pthread_mutex_init\n");
+ winDebug ("InitQueue - Calling pthread_mutex_init\n");
/* Create synchronization objects */
pthread_mutex_init(&pQueue->pmMutex, NULL);
- winDebug("InitQueue - pthread_mutex_init returned\n");
- winDebug("InitQueue - Calling pthread_cond_init\n");
+ winDebug ("InitQueue - pthread_mutex_init returned\n");
+ winDebug ("InitQueue - Calling pthread_cond_init\n");
pthread_cond_init(&pQueue->pcNotEmpty, NULL);
- winDebug("InitQueue - pthread_cond_init returned\n");
+ winDebug ("InitQueue - pthread_cond_init returned\n");
return TRUE;
}
-/*
- * GetWindowName - Retrieve the title of an X Window
- */
-
-static void
-GetWindowName(Display * pDisplay, Window iWin, wchar_t ** ppName)
+static
+char *
+Xutf8TextPropertyToString(Display * pDisplay, XTextProperty * xtp)
{
- int nResult, nNum;
+ int nNum;
char **ppList;
char *pszReturnData;
- int iLen, i;
- XTextProperty xtpName;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("GetWindowName\n");
-#endif
- /* Intialize ppName to NULL */
- *ppName = NULL;
+ if (Xutf8TextPropertyToTextList(pDisplay, xtp, &ppList, &nNum) >= Success &&
+ nNum > 0 && *ppList) {
+ int i;
+ int iLen = 0;
- /* Try to get --- */
- nResult = XGetWMName(pDisplay, iWin, &xtpName);
- if (!nResult || !xtpName.value || !xtpName.nitems) {
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("GetWindowName - XGetWMName failed. No name.\n");
-#endif
- return;
- }
-
- if (Xutf8TextPropertyToTextList(pDisplay, &xtpName, &ppList, &nNum) >=
- Success && nNum > 0 && *ppList) {
- iLen = 0;
for (i = 0; i < nNum; i++)
iLen += strlen(ppList[i]);
pszReturnData = (char *) malloc(iLen + 1);
@@ -444,15 +399,36 @@ GetWindowName(Display * pDisplay, Window iWin, wchar_t ** ppName)
pszReturnData = (char *) malloc(1);
pszReturnData[0] = '\0';
}
- iLen = MultiByteToWideChar(CP_UTF8, 0, pszReturnData, -1, NULL, 0);
- *ppName = (wchar_t *) malloc(sizeof(wchar_t) * (iLen + 1));
- MultiByteToWideChar(CP_UTF8, 0, pszReturnData, -1, *ppName, iLen);
- XFree(xtpName.value);
- free(pszReturnData);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("GetWindowName - Returning\n");
-#endif
+
+ return pszReturnData;
+}
+
+/*
+ * GetWindowName - Retrieve the title of an X Window
+ */
+
+static void
+GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
+{
+ int nResult;
+ XTextProperty xtpWindowName;
+ char *pszWindowName;
+
+ winDebug ("GetWindowName\n");
+
+ /* Intialize ppWindowName to NULL */
+ *ppWindowName = NULL;
+
+ /* Try to get window name */
+ nResult = XGetWMName(pDisplay, iWin, &xtpWindowName);
+ if (!nResult || !xtpWindowName.value || !xtpWindowName.nitems) {
+ ErrorF("GetWindowName - XGetWMName failed. No name.\n");
+ return;
+ }
+
+ pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
+ XFree(xtpWindowName.value);
+ *ppWindowName = pszWindowName;
}
/*
@@ -528,18 +504,70 @@ UpdateName(WMInfoPtr pWMInfo, Window iWindow)
if (!hWnd)
return;
- /* Set the Windows window name */
- GetWindowName(pWMInfo->pDisplay, iWindow, &pszName);
- if (pszName) {
- /* Get the window attributes */
- XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
- if (!attr.override_redirect) {
- SetWindowTextW(hWnd, pszName);
- winUpdateIcon(iWindow);
+ /* If window isn't override-redirect */
+ XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
+ if (!attr.override_redirect) {
+ char *pszWindowName;
+
+ /* Get the X windows window name */
+ GetWindowName(pWMInfo->pDisplay, iWindow, &pszWindowName);
+
+ if (pszWindowName) {
+ /* Convert from UTF-8 to wide char */
+ int iLen =
+ MultiByteToWideChar(CP_UTF8, 0, pszWindowName, -1, NULL, 0);
+ wchar_t *pwszWideWindowName =
+ (wchar_t *) malloc(sizeof(wchar_t) * (iLen + 1));
+ MultiByteToWideChar(CP_UTF8, 0, pszWindowName, -1,
+ pwszWideWindowName, iLen);
+
+ /* Set the Windows window name */
+ SetWindowTextW(hWnd, pwszWideWindowName);
+
+ free(pwszWideWindowName);
+ free(pszWindowName);
}
+ }
+}
+
+/*
+ * Updates the icon of a HWND according to its X icon properties
+ */
+
+static void
+UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
+{
+ HWND hWnd;
+ HICON hIconNew = NULL;
+ XWindowAttributes attr;
+
+ hWnd = getHwnd(pWMInfo, iWindow);
+ if (!hWnd)
+ return;
+
+ /* If window isn't override-redirect */
+ XGetWindowAttributes(pWMInfo->pDisplay, iWindow, &attr);
+ if (!attr.override_redirect) {
+ XClassHint class_hint = { 0, 0 };
+ char *window_name = 0;
+
+ if (XGetClassHint(pWMInfo->pDisplay, iWindow, &class_hint)) {
+ XFetchName(pWMInfo->pDisplay, iWindow, &window_name);
+
+ hIconNew =
+ (HICON) winOverrideIcon(class_hint.res_name,
+ class_hint.res_class, window_name);
- free(pszName);
+ if (class_hint.res_name)
+ XFree(class_hint.res_name);
+ if (class_hint.res_class)
+ XFree(class_hint.res_class);
+ if (window_name)
+ XFree(window_name);
+ }
}
+
+ winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
}
#if 0
@@ -593,21 +621,23 @@ winMultiWindowWMProc(void *pArg)
WMProcArgPtr pProcArg = (WMProcArgPtr) pArg;
WMInfoPtr pWMInfo = pProcArg->pWMInfo;
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
/* Initialize the Window Manager */
winInitMultiWindowWM(pWMInfo, pProcArg);
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("winMultiWindowWMProc ()\n");
-#endif
+ winDebug ("winMultiWindowWMProc ()\n");
/* Loop until we explicitly break out */
for (;;) {
WMMsgNodePtr pNode;
+#ifdef XWIN_MULTIWINDOWINTWM
if (g_fAnotherWMRunning) { /* Another Window manager exists. */
Sleep(1000);
continue;
}
+#endif
/* Pop a message off of our queue */
pNode = PopMessage(&pWMInfo->wmMsgQueue, pWMInfo);
@@ -618,60 +648,43 @@ winMultiWindowWMProc(void *pArg)
pthread_exit(NULL);
}
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
- GetTickCount(), (int) pNode->msg.msg, (int) pNode->msg.dwID);
-#endif
+ winDebug ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
+ GetTickCount(), (int) pNode->msg.msg, (int) pNode->msg.dwID);
/* Branch on the message type */
switch (pNode->msg.msg) {
-#if 0
- case WM_WM_MOVE:
- ErrorF("\tWM_WM_MOVE\n");
- break;
-
- case WM_WM_SIZE:
- ErrorF("\tWM_WM_SIZE\n");
- break;
-#endif
-
case WM_WM_RAISE:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_RAISE\n");
-#endif
+ winDebug ("\tWM_WM_RAISE\n");
/* Raise the window */
XRaiseWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
-#if 0
- PreserveWin32Stack(pWMInfo, pNode->msg.iWindow, GW_HWNDPREV);
-#endif
break;
case WM_WM_LOWER:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_LOWER\n");
-#endif
+ winDebug ("\tWM_WM_LOWER\n");
/* Lower the window */
XLowerWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
break;
case WM_WM_MAP:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_MAP\n");
-#endif
+ winDebug ("\tWM_WM_MAP\n");
/* Put a note as to the HWND associated with this Window */
XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER, //pWMInfo->atmPrivMap,
32,
PropModeReplace,
(unsigned char *) &(pNode->msg.hwndWindow), 1);
UpdateName(pWMInfo, pNode->msg.iWindow);
- winUpdateIcon(pNode->msg.iWindow);
+ UpdateIcon(pWMInfo, pNode->msg.iWindow);
+ {
+ HWND zstyle = HWND_NOTOPMOST;
+ winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle);
+ winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle);
+ }
break;
case WM_WM_MAP2:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_MAP2\n");
-#endif
+ winDebug ("\tWM_WM_MAP2\n");
+
XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER, //pWMInfo->atmPrivMap,
32,
PropModeReplace,
@@ -679,16 +692,15 @@ winMultiWindowWMProc(void *pArg)
break;
case WM_WM_MAP3:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_MAP3\n");
-#endif
+ winDebug ("\tWM_WM_MAP3\n");
+
/* Put a note as to the HWND associated with this Window */
XChangeProperty(pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmPrivMap, XA_INTEGER, //pWMInfo->atmPrivMap,
32,
PropModeReplace,
(unsigned char *) &(pNode->msg.hwndWindow), 1);
UpdateName(pWMInfo, pNode->msg.iWindow);
- winUpdateIcon(pNode->msg.iWindow);
+ UpdateIcon(pWMInfo, pNode->msg.iWindow);
{
HWND zstyle = HWND_NOTOPMOST;
@@ -699,18 +711,14 @@ winMultiWindowWMProc(void *pArg)
break;
case WM_WM_UNMAP:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_UNMAP\n");
-#endif
+ winDebug ("\tWM_WM_UNMAP\n");
/* Unmap the window */
XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
break;
case WM_WM_KILL:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_KILL\n");
-#endif
+ winDebug ("\tWM_WM_KILL\n");
{
int i, n, found = 0;
Atom *protocols;
@@ -736,9 +744,7 @@ winMultiWindowWMProc(void *pArg)
break;
case WM_WM_ACTIVATE:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("\tWM_WM_ACTIVATE\n");
-#endif
+ winDebug ("\tWM_WM_ACTIVATE\n");
/* Set the input focus */
XSetInputFocus(pWMInfo->pDisplay,
@@ -750,8 +756,8 @@ winMultiWindowWMProc(void *pArg)
UpdateName(pWMInfo, pNode->msg.iWindow);
break;
- case WM_WM_HINTS_EVENT:
- winUpdateIcon(pNode->msg.iWindow);
+ case WM_WM_ICON_EVENT:
+ UpdateIcon(pWMInfo, pNode->msg.iWindow);
break;
case WM_WM_CHANGE_STATE:
@@ -781,9 +787,10 @@ winMultiWindowWMProc(void *pArg)
/* Free the passed-in argument */
free(pProcArg);
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("-winMultiWindowWMProc ()\n");
-#endif
+ winDebug("-winMultiWindowWMProc ()\n");
+
+ pthread_cleanup_pop(0);
+
return NULL;
}
@@ -802,9 +809,12 @@ winMultiWindowXMsgProc(void *pArg)
Atom atmWmName;
Atom atmWmHints;
Atom atmWmChange;
+ Atom atmNetWmIcon;
int iReturn;
XIconSize *xis;
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
winDebug("winMultiWindowXMsgProc - Hello\n");
/* Check that argument pointer is not invalid */
@@ -813,7 +823,7 @@ winMultiWindowXMsgProc(void *pArg)
pthread_exit(NULL);
}
- ErrorF("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
+ winDebug ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
/* Grab the server started mutex - pause until we get it */
iReturn = pthread_mutex_lock(pProcArg->ppmServerStarted);
@@ -823,23 +833,12 @@ winMultiWindowXMsgProc(void *pArg)
pthread_exit(NULL);
}
- ErrorF("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads() == 0) {
- ErrorF("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n");
- pthread_exit(NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale() == False) {
- ErrorF("winMultiWindowXMsgProc - Warning: locale not supported by X\n");
- }
+ winDebug ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
/* Release the server started mutex */
pthread_mutex_unlock(pProcArg->ppmServerStarted);
- ErrorF("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
+ winDebug ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
/* Install our error handler */
XSetErrorHandler(winMultiWindowXMsgProcErrorHandler);
@@ -863,11 +862,10 @@ winMultiWindowXMsgProc(void *pArg)
}
/* Setup the display connection string x */
- snprintf(pszDisplay,
- 512, "127.0.0.1:%s.%d", display, (int) pProcArg->dwScreen);
+ winGetDisplayName(pszDisplay, (int)pProcArg->dwScreen);
/* Print the display connection string */
- ErrorF("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay);
+ winDebug ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay);
/* Use our generated cookie for authentication */
winSetAuthorization();
@@ -880,8 +878,8 @@ winMultiWindowXMsgProc(void *pArg)
/* Try to open the display */
pProcArg->pDisplay = XOpenDisplay(pszDisplay);
if (pProcArg->pDisplay == NULL) {
- ErrorF("winMultiWindowXMsgProc - Could not open display, try: %d, "
- "sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY);
+ winDebug ("winMultiWindowXMsgProc - Could not open display, try: %d, "
+ "sleeping: %d\n", iRetries + 1, WIN_CONNECT_DELAY);
++iRetries;
sleep(WIN_CONNECT_DELAY);
continue;
@@ -898,15 +896,25 @@ winMultiWindowXMsgProc(void *pArg)
pthread_exit(NULL);
}
- ErrorF("winMultiWindowXMsgProc - XOpenDisplay () returned and "
- "successfully opened the display.\n");
+ winDebug ("winMultiWindowXMsgProc - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
/* Check if another window manager is already running */
+#ifdef XWIN_MULTIWINDOWINTWM
g_fAnotherWMRunning =
CheckAnotherWindowManager(pProcArg->pDisplay, pProcArg->dwScreen,
pProcArg->pWMInfo->fAllowOtherWM);
+#else
+ g_fAnotherWMRunning =
+ CheckAnotherWindowManager(pProcArg->pDisplay, pProcArg->dwScreen,
+ FALSE);
+#endif
- if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM) {
+ if (g_fAnotherWMRunning
+#ifdef XWIN_MULTIWINDOWINTWM
+ && !pProcArg->pWMInfo->fAllowOtherWM
+#endif
+ ) {
ErrorF("winMultiWindowXMsgProc - "
"another window manager is running. Exiting.\n");
pthread_exit(NULL);
@@ -927,6 +935,7 @@ winMultiWindowXMsgProc(void *pArg)
atmWmName = XInternAtom(pProcArg->pDisplay, "WM_NAME", False);
atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
+ atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
/*
iiimxcf had a bug until 2009-04-27, assuming that the
@@ -943,6 +952,7 @@ winMultiWindowXMsgProc(void *pArg)
if (g_shutdown)
break;
+#ifdef XWIN_MULTIWINDOWINTWM
if (pProcArg->pWMInfo->fAllowOtherWM && !XPending(pProcArg->pDisplay)) {
if (CheckAnotherWindowManager
(pProcArg->pDisplay, pProcArg->dwScreen, TRUE)) {
@@ -962,12 +972,13 @@ winMultiWindowXMsgProc(void *pArg)
Sleep(500);
continue;
}
+#endif
/* Fetch next event */
XNextEvent(pProcArg->pDisplay, &event);
/* Branch on event type */
- if (event.type == CreateNotify) {
+ if (event.type == MapNotify /* CreateNotify */) {
XWindowAttributes attr;
XSelectInput(pProcArg->pDisplay,
@@ -977,7 +988,7 @@ winMultiWindowXMsgProc(void *pArg)
XGetWindowAttributes(pProcArg->pDisplay,
event.xcreatewindow.window, &attr);
- if (!attr.override_redirect)
+ if (!attr.override_redirect && attr.class != InputOnly)
XSetWindowBorderWidth(pProcArg->pDisplay,
event.xcreatewindow.window, 0);
}
@@ -1025,6 +1036,7 @@ winMultiWindowXMsgProc(void *pArg)
event_send.xreparent.parent = parent;
event_send.xreparent.x = attr.x;
event_send.xreparent.y = attr.y;
+ event_send.xreparent.override_redirect = False;
XSendEvent(event.xmap.display,
event.xmap.window,
@@ -1054,30 +1066,30 @@ winMultiWindowXMsgProc(void *pArg)
True, StructureNotifyMask, &event_send);
}
}
- else if (event.type == PropertyNotify
- && event.xproperty.atom == atmWmName) {
- memset(&msg, 0, sizeof(msg));
+ else if (event.type == PropertyNotify) {
+ if (event.xproperty.atom == atmWmName) {
+ memset(&msg, 0, sizeof(msg));
- msg.msg = WM_WM_NAME_EVENT;
- msg.iWindow = event.xproperty.window;
+ msg.msg = WM_WM_NAME_EVENT;
+ msg.iWindow = event.xproperty.window;
- /* Other fields ignored */
- winSendMessageToWM(pProcArg->pWMInfo, &msg);
- }
- else if (event.type == PropertyNotify
- && event.xproperty.atom == atmWmHints) {
- memset(&msg, 0, sizeof(msg));
-
- msg.msg = WM_WM_HINTS_EVENT;
- msg.iWindow = event.xproperty.window;
-
- /* Other fields ignored */
- winSendMessageToWM(pProcArg->pWMInfo, &msg);
+ /* Other fields ignored */
+ winSendMessageToWM(pProcArg->pWMInfo, &msg);
+ }
+ else if ((event.xproperty.atom == atmWmHints) ||
+ (event.xproperty.atom == atmNetWmIcon)) {
+ memset(&msg, 0, sizeof(msg));
+ msg.msg = WM_WM_ICON_EVENT;
+ msg.iWindow = event.xproperty.window;
+
+ /* Other fields ignored */
+ winSendMessageToWM(pProcArg->pWMInfo, &msg);
+ }
}
else if (event.type == ClientMessage
&& event.xclient.message_type == atmWmChange
&& event.xclient.data.l[0] == IconicState) {
- ErrorF("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
+ winDebug ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
memset(&msg, 0, sizeof(msg));
@@ -1089,7 +1101,7 @@ winMultiWindowXMsgProc(void *pArg)
}
XCloseDisplay(pProcArg->pDisplay);
- pthread_exit(NULL);
+ pthread_cleanup_pop(0);
return NULL;
}
@@ -1126,7 +1138,9 @@ winInitWM(void **ppWMInfo,
/* Set a return pointer to the Window Manager info structure */
*ppWMInfo = pWMInfo;
+#ifdef XWIN_MULTIWINDOWINTWM
pWMInfo->fAllowOtherWM = allowOtherWM;
+#endif
/* Setup the argument structure for the thread function */
pArg->dwScreen = dwScreen;
@@ -1157,9 +1171,7 @@ winInitWM(void **ppWMInfo,
return FALSE;
}
-#if CYGDEBUG || YES
winDebug("winInitWM - Returning.\n");
-#endif
return TRUE;
}
@@ -1183,7 +1195,7 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
pthread_exit(NULL);
}
- ErrorF("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
+ winDebug ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
/* Grab our garbage mutex to satisfy pthread_cond_wait */
iReturn = pthread_mutex_lock(pProcArg->ppmServerStarted);
@@ -1193,23 +1205,12 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
pthread_exit(NULL);
}
- ErrorF("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads() == 0) {
- ErrorF("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n");
- pthread_exit(NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale() == False) {
- ErrorF("winInitMultiWindowWM - Warning: Locale not supported by X.\n");
- }
+ winDebug ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
/* Release the server started mutex */
pthread_mutex_unlock(pProcArg->ppmServerStarted);
- ErrorF("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
+ winDebug ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
/* Install our error handler */
XSetErrorHandler(winMultiWindowWMErrorHandler);
@@ -1233,11 +1234,10 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
}
/* Setup the display connection string x */
- snprintf(pszDisplay,
- 512, "127.0.0.1:%s.%d", display, (int) pProcArg->dwScreen);
+ winGetDisplayName(pszDisplay, (int)pProcArg->dwScreen);
/* Print the display connection string */
- ErrorF("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
+ winDebug ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
/* Use our generated cookie for authentication */
winSetAuthorization();
@@ -1265,8 +1265,8 @@ winInitMultiWindowWM(WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
pthread_exit(NULL);
}
- ErrorF("winInitMultiWindowWM - XOpenDisplay () returned and "
- "successfully opened the display.\n");
+ winDebug ("winInitMultiWindowWM - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
/* Create some atoms */
pWMInfo->atmWmProtos = XInternAtom(pWMInfo->pDisplay,
@@ -1297,9 +1297,7 @@ winSendMessageToWM(void *pWMInfo, winWMMessagePtr pMsg)
{
WMMsgNodePtr pNode;
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("winSendMessageToWM ()\n");
-#endif
+ winDebug ("winSendMessageToWM ()\n");
pNode = (WMMsgNodePtr) malloc(sizeof(WMMsgNodeRec));
if (pNode != NULL) {
@@ -1325,7 +1323,18 @@ winMultiWindowWMErrorHandler(Display * pDisplay, XErrorEvent * pErr)
}
XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
- ErrorF("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg);
+ ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n"
+ " errorCode %d\n"
+ " serial %d\n"
+ " resourceID 0x%x\n"
+ " majorCode %d\n"
+ " minorCode %d\n"
+ , pszErrorMsg
+ , pErr->error_code
+ , pErr->serial
+ , pErr->resourceid
+ , pErr->request_code
+ , pErr->minor_code);
return 0;
}
@@ -1363,9 +1372,18 @@ winMultiWindowXMsgProcErrorHandler(Display * pDisplay, XErrorEvent * pErr)
char pszErrorMsg[100];
XGetErrorText(pDisplay, pErr->error_code, pszErrorMsg, sizeof(pszErrorMsg));
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg);
-#endif
+ ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n"
+ " errorCode %d\n"
+ " serial %d\n"
+ " resourceID 0x%x\n"
+ " majorCode %d\n"
+ " minorCode %d\n"
+ , pszErrorMsg
+ , pErr->error_code
+ , pErr->serial
+ , pErr->resourceid
+ , pErr->request_code
+ , pErr->minor_code);
return 0;
}
@@ -1391,6 +1409,18 @@ winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay)
}
/*
+ * winMultiWindowThreadExit - Thread exit handler
+ */
+
+static void
+winMultiWindowThreadExit(void *arg)
+{
+ AbortDDX(EXIT_ERR_ABORT);
+
+ /* multiwindow client thread has exited, stop server as well */
+ TerminateProcess(GetCurrentProcess(),1);
+}
+/*
* Catch RedirectError to detect other window manager running
*/
@@ -1441,7 +1471,7 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
void
winDeinitMultiWindowWM(void)
{
- ErrorF("winDeinitMultiWindowWM - Noting shutdown in progress\n");
+ winDebug ("winDeinitMultiWindowWM - Noting shutdown in progress\n");
g_shutdown = TRUE;
}
@@ -1467,7 +1497,9 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
Atom type, *pAtom = NULL;
int format;
unsigned long hint = 0, maxmin = 0, style, nitems = 0, left = 0;
+ WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
MwmHints *mwm_hint = NULL;
+ WinXSizeHints SizeHints;
if (!hWnd)
return;
@@ -1583,21 +1615,32 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
/* Override hint settings from above with settings from config file */
{
XClassHint class_hint = { 0, 0 };
- char *window_name = 0;
if (XGetClassHint(pDisplay, iWindow, &class_hint)) {
+ char *window_name = 0;
+ char *application_id = 0;
XFetchName(pDisplay, iWindow, &window_name);
style =
winOverrideStyle(class_hint.res_name, class_hint.res_class,
window_name);
- if (class_hint.res_name)
- XFree(class_hint.res_name);
+#define APPLICATION_ID_FORMAT "%s.vcxsrv.%s"
+#define APPLICATION_ID_UNKNOWN "unknown"
if (class_hint.res_class)
- XFree(class_hint.res_class);
- if (window_name)
- XFree(window_name);
+ {
+ asprintf (&application_id, APPLICATION_ID_FORMAT, XVENDORNAME, class_hint.res_class);
+ }
+ else
+ {
+ asprintf (&application_id, APPLICATION_ID_FORMAT, XVENDORNAME, APPLICATION_ID_UNKNOWN);
+ }
+ winSetAppID (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);
}
else {
style = STYLE_NONE;
@@ -1624,20 +1667,15 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
HINT_SIZEBOX;
else if (style & STYLE_OUTLINE)
hint =
- (hint & ~HINT_NOFRAME & ~HINT_SIZEBOX & ~HINT_CAPTION) |
- HINT_BORDER;
+ (hint & ~HINT_NOFRAME & ~HINT_CAPTION) | HINT_BORDER;
else if (style & STYLE_NOFRAME)
hint =
- (hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) |
- HINT_NOFRAME;
+ (hint & ~HINT_BORDER & ~HINT_CAPTION) | HINT_NOFRAME;
/* Now apply styles to window */
style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
- if (!style)
- return;
-
- if (!hint) /* All on */
- style = style | WS_CAPTION | WS_SIZEBOX;
+ if (!hint) /* All on, but no resize of children is allowed */
+ style = style | WS_CAPTION;
else if (hint & HINT_NOFRAME) /* All off */
style = style & ~WS_CAPTION & ~WS_SIZEBOX;
else
@@ -1654,6 +1692,19 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
if (hint & HINT_NOSYSMENU)
style = style & ~WS_SYSMENU;
+ if (!IsWindow (hWnd))
+ {
+ ErrorF("Windows window 0x%x has become invalid, so returning without applying hints\n",hWnd);
+ return;
+ }
+
+ if (winMultiWindowGetWMNormalHints(pWin, &SizeHints))
+ {
+ if (!(SizeHints.max_width&&SizeHints.max_height&&(SizeHints.min_width == SizeHints.max_width)&&(SizeHints.min_height == SizeHints.max_height) ))
+ style|=WS_SIZEBOX;
+ }
+ else
+ style|=WS_SIZEBOX;
SetWindowLongPtr(hWnd, GWL_STYLE, style);
}
@@ -1683,13 +1734,8 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
/* Setup a rectangle with the X window position and size */
SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-#if 0
- ErrorF("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
-#endif
-
AdjustWindowRectEx(&rcNew, GetWindowLongPtr(hWnd, GWL_STYLE), FALSE,
- WS_EX_APPWINDOW);
+ GetWindowLongPtr(hWnd, GWL_EXSTYLE));
/* Don't allow window decoration to disappear off to top-left as a result of this adjustment */
if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) {
@@ -1704,11 +1750,6 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
rcNew.bottom += iDy;
}
-#if 0
- ErrorF("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom);
-#endif
-
/* Position the Windows window */
SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top,
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 0);
@@ -1718,3 +1759,100 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
winUpdateRgnMultiWindow(pWin);
}
}
+
+void
+winTaskbarInit (void)
+{
+ /*
+ Load libraries and get function pointers to SHGetPropertyStoreForWindow
+ and PropVariantClear for winSetAppID()
+ */
+
+ /*
+ SHGetPropertyStoreForWindow is only supported since Windows 7. On previous
+ versions the pointer will be NULL and taskbar grouping is not supported.
+ winSetAppID() will do nothing in this case.
+ */
+ g_hmodShell32Dll = LoadLibrary ("shell32.dll");
+ if (g_hmodShell32Dll == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not load shell32.dll\n");
+ return;
+ }
+
+ g_pSHGetPropertyStoreForWindow = (SHGETPROPERTYSTOREFORWINDOWPROC) GetProcAddress (g_hmodShell32Dll, "SHGetPropertyStoreForWindow");
+ if (g_pSHGetPropertyStoreForWindow == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not get SHGetPropertyStoreForWindow address\n");
+ return;
+ }
+
+ /*
+ PropVariantClear is supported since NT4, but we have no propidl.h to
+ provide a prototype for it
+ */
+ g_hmodOle32Dll = LoadLibrary ("ole32.dll");
+ if (g_hmodOle32Dll == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not load ole32.dll\n");
+ return;
+ }
+
+ g_pPropVariantClear = (PROPVARIANTCLEARPROC) GetProcAddress (g_hmodOle32Dll, "PropVariantClear");
+ if (g_pPropVariantClear == NULL)
+ {
+ ErrorF ("winTaskbarInit - Could not get g_pPropVariantClear address\n");
+ return;
+ }
+}
+
+void
+winTaskbarDestroy (void)
+{
+ if (g_hmodOle32Dll != NULL)
+ {
+ FreeLibrary (g_hmodOle32Dll);
+ g_hmodOle32Dll = NULL;
+ g_pPropVariantClear = NULL;
+ }
+ if (g_hmodShell32Dll != NULL)
+ {
+ FreeLibrary (g_hmodShell32Dll);
+ g_hmodShell32Dll = NULL;
+ g_pSHGetPropertyStoreForWindow = NULL;
+ }
+}
+
+void
+winSetAppID (HWND hWnd, const char* AppID)
+{
+ PROPVARIANT pv;
+ IPropertyStore *pps = NULL;
+ HRESULT hr;
+
+ if (g_pSHGetPropertyStoreForWindow == NULL ||
+ g_pPropVariantClear == NULL)
+ {
+ return;
+ }
+
+ winDebug ("winSetAppID - 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))
+ {
+ hr = pps->lpVtbl->SetValue(pps, &PKEY_AppUserModel_ID, &pv);
+ g_pPropVariantClear(&pv);
+ }
+ pps->lpVtbl->Release(pps);
+ }
+}