summaryrefslogtreecommitdiff
path: root/hw/xwin
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin')
-rw-r--r--hw/xwin/InitOutput.c197
-rw-r--r--hw/xwin/Makefile.am5
-rwxr-xr-xhw/xwin/glx/gen_gl_wrappers.py14
-rw-r--r--hw/xwin/glx/indirect.c36
-rw-r--r--hw/xwin/glx/winpriv.c38
-rw-r--r--hw/xwin/man/XWin.man18
-rw-r--r--hw/xwin/system.XWinrc10
-rw-r--r--hw/xwin/taskbar.h72
-rw-r--r--hw/xwin/win.h17
-rw-r--r--hw/xwin/winblock.c52
-rw-r--r--hw/xwin/winclipboard.h1
-rw-r--r--hw/xwin/winclipboardinit.c2
-rw-r--r--hw/xwin/winclipboardthread.c51
-rw-r--r--hw/xwin/winclipboardwrappers.c2
-rw-r--r--hw/xwin/wincreatewnd.c92
-rw-r--r--hw/xwin/windisplay.c56
-rw-r--r--hw/xwin/winengine.c8
-rw-r--r--hw/xwin/winerror.c65
-rw-r--r--hw/xwin/winglobals.c5
-rw-r--r--hw/xwin/winglobals.h3
-rw-r--r--hw/xwin/winkeybd.c55
-rw-r--r--hw/xwin/winmonitors.c1
-rw-r--r--hw/xwin/winmonitors.h29
-rw-r--r--hw/xwin/winmsgwindow.c184
-rw-r--r--hw/xwin/winmultiwindowwindow.c278
-rw-r--r--hw/xwin/winmultiwindowwm.c352
-rw-r--r--hw/xwin/winmultiwindowwndproc.c65
-rw-r--r--hw/xwin/winprefs.c18
-rw-r--r--hw/xwin/winprocarg.c124
-rw-r--r--hw/xwin/winscrinit.c4
-rw-r--r--hw/xwin/winwakeup.c4
-rw-r--r--hw/xwin/winwin32rootless.c2
-rw-r--r--hw/xwin/winwindow.h10
-rw-r--r--hw/xwin/winwndproc.c7
34 files changed, 1498 insertions, 379 deletions
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 4a601b222..6e5c366aa 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -35,12 +35,10 @@ from The Open Group.
#include "winmsg.h"
#include "winconfig.h"
#include "winprefs.h"
-#ifdef XWIN_CLIPBOARD
-#include "X11/Xlocale.h"
-#endif
#ifdef DPMSExtension
#include "dpmsproc.h"
#endif
+#include <locale.h>
#ifdef __CYGWIN__
#include <mntent.h>
#endif
@@ -57,6 +55,7 @@ typedef WINAPI HRESULT (*SHGETFOLDERPATHPROC)(
LPTSTR pszPath
);
#endif
+#include "ddxhooks.h"
/*
* References to external symbols
@@ -84,8 +83,6 @@ void
OsVendorVErrorF (const char *pszFormat, va_list va_args);
#endif
-static Bool
-winCheckDisplayNumber (void);
void
winLogCommandLine (int argc, char *argv[]);
@@ -101,6 +98,8 @@ const char *
winGetBaseDir(void);
#endif
+static void winCheckMount(void);
+
/*
* For the depth 24 pixmap we default to 32 bits per pixel, but
* we change this pixmap format later if we detect that the display
@@ -165,13 +164,12 @@ ddxPushProviders(void)
#endif
}
-#if defined(DDXBEFORERESET)
/*
* Called right before KillAllClients when the server is going to reset,
* allows us to shutdown our seperate threads cleanly.
*/
-void
+static void
ddxBeforeReset (void)
{
winDebug ("ddxBeforeReset - Hello\n");
@@ -180,8 +178,31 @@ ddxBeforeReset (void)
winClipboardShutdown ();
#endif
}
-#endif
+void
+ddxMain(void)
+{
+ int iReturn;
+
+ /* Initialize DDX-specific hooks */
+ ddxHooks.ddxBeforeReset = ddxBeforeReset;
+ ddxHooks.ddxPushProviders = ddxPushProviders;
+
+ /* 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);
+ }
+
+ winCheckMount();
+}
/* See Porting Layer Definition - p. 57 */
void
@@ -202,6 +223,9 @@ ddxGiveUp (enum ExitCode error)
}
#ifdef XWIN_MULTIWINDOW
+ /* Unload libraries for taskbar grouping */
+ winTaskbarDestroy ();
+
/* Notify the worker threads we're exiting */
winDeinitMultiWindowWM ();
#endif
@@ -239,8 +263,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 */
void
@@ -253,6 +288,8 @@ AbortDDX (enum ExitCode error)
}
#ifdef __CYGWIN__
+extern Bool nolock;
+
/* hasmntopt is currently not implemented for cygwin */
static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt)
{
@@ -274,6 +311,9 @@ static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt)
return NULL;
}
+/*
+ Check mounts and issue warnings/activate workarounds as needed
+ */
static void
winCheckMount(void)
{
@@ -283,6 +323,7 @@ winCheckMount(void)
enum { none = 0, sys_root, user_root, sys_tmp, user_tmp }
level = none, curlevel;
BOOL binary = TRUE;
+ BOOL fat = TRUE;
mnt = setmntent("/etc/mtab", "r");
if (mnt == NULL)
@@ -325,20 +366,31 @@ winCheckMount(void)
binary = FALSE;
else
binary = TRUE;
+
+ if (strcmp(ent->mnt_type, "vfat") == 0)
+ fat = TRUE;
+ else
+ fat = FALSE;
}
-
+
if (endmntent(mnt) != 1)
{
ErrorF("endmntent failed");
return;
}
-
- if (!binary)
+
+ if (!binary)
winMsg(X_WARNING, "/tmp mounted in textmode\n");
+
+ if (fat)
+ {
+ winMsg(X_WARNING, "/tmp mounted on FAT filesystem, activating -nolock\n");
+ nolock = TRUE;
+ }
}
#else
static void
-winCheckMount(void)
+winCheckMount(void)
{
}
#endif
@@ -762,6 +814,9 @@ winUseMsg (void)
ErrorF ("-fullscreen\n"
"\tRun the server in fullscreen mode.\n");
+ ErrorF ("-hostintitle\n"
+ "\tIn multiwindow mode, add remote host names to window titles.\n");
+
ErrorF ("-ignoreinput\n"
"\tIgnore keyboard and mouse input.\n");
@@ -825,7 +880,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");
@@ -859,7 +914,8 @@ 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\n"
+ "\tfor hardware-accelerated OpenGL (AIGLX). Enabled by default.\n");
#endif
ErrorF ("-[no]winkill\n"
@@ -933,15 +989,6 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
"Exiting.\n");
}
- /* Check for duplicate invocation on same display number.*/
- if (serverGeneration == 1 && !winCheckDisplayNumber ())
- {
- if (g_fSilentDupError)
- g_fSilentFatalError = TRUE;
- FatalError ("InitOutput - Duplicate invocation on display "
- "number: %s. Exiting.\n", display);
- }
-
#ifdef XWIN_XF86CONFIG
/* Try to read the xorg.conf-style configuration file */
if (!winReadConfigfile ())
@@ -975,9 +1022,18 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
/* Detect supported engines */
winDetectSupportedEngines ();
+#ifdef XWIN_MULTIWINDOW
+ /* Load libraries for taskbar grouping */
+ winTaskbarInit ();
+#endif
+
/* 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)
{
@@ -997,11 +1053,27 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
/* Perform some one time initialization */
if (1 == serverGeneration)
{
+ /* Allow multiple threads to access Xlib */
+ if (XInitThreads () == 0)
+ {
+ ErrorF ("XInitThreads failed.\n");
+ }
+
/*
* setlocale applies to all threads in the current process.
* Apply locale specified in LANG environment variable.
*/
- setlocale (LC_ALL, "");
+ if (!setlocale (LC_ALL, ""))
+ {
+ ErrorF ("setlocale failed.\n");
+ }
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == FALSE)
+ {
+ ErrorF ("Warning: Locale not supported by X, falling back to 'C' locale.\n");
+ setlocale(LC_ALL, "C");
+ }
}
#endif
@@ -1009,78 +1081,3 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
winDebug ("InitOutput - Returning.\n");
#endif
}
-
-
-/*
- * winCheckDisplayNumber - Check if another instance of Cygwin/X is
- * already running on the same display number. If no one exists,
- * make a mutex to prevent new instances from running on the same display.
- *
- * return FALSE if the display number is already used.
- */
-
-static Bool
-winCheckDisplayNumber (void)
-{
- int nDisp;
- HANDLE mutex;
- char name[MAX_PATH];
- char * pszPrefix = '\0';
- OSVERSIONINFO osvi = {0};
-
- /* Check display range */
- nDisp = atoi (display);
- if (nDisp < 0 || nDisp > 65535)
- {
- ErrorF ("winCheckDisplayNumber - Bad display number: %d\n", nDisp);
- return FALSE;
- }
-
- /* Set first character of mutex name to null */
- name[0] = '\0';
-
- /* Get operating system version information */
- osvi.dwOSVersionInfoSize = sizeof (osvi);
- GetVersionEx (&osvi);
-
- /* Want a mutex shared among all terminals on NT > 4.0 */
- if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT
- && osvi.dwMajorVersion >= 5)
- {
- pszPrefix = "Global\\";
- }
-
- /* Setup Cygwin/X specific part of name */
- snprintf (name, sizeof(name), "%sCYGWINX_DISPLAY:%d", pszPrefix, nDisp);
-
- /* Windows automatically releases the mutex when this process exits */
- mutex = CreateMutex (NULL, FALSE, name);
- if (!mutex)
- {
- LPVOID lpMsgBuf;
-
- /* Display a fancy error message */
- FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError (),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
- ErrorF ("winCheckDisplayNumber - CreateMutex failed: %s\n",
- (LPSTR)lpMsgBuf);
- LocalFree (lpMsgBuf);
-
- return FALSE;
- }
- if (GetLastError () == ERROR_ALREADY_EXISTS)
- {
- ErrorF ("winCheckDisplayNumber - "
- PROJECT_NAME " is already running on display %d\n",
- nDisp);
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index c49016398..17a4adbb9 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -26,6 +26,7 @@ SRCS_MULTIWINDOW = \
winmultiwindowwm.c \
winmultiwindowwndproc.c
DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+MULTIWINDOW_LIBS = -lshlwapi
endif
if XWIN_MULTIWINDOWEXTWM
@@ -90,6 +91,7 @@ SRCS = InitInput.c \
winmonitors.c \
winmouse.c \
winmsg.c \
+ winmsgwindow.c \
winmultiwindowclass.c \
winmultiwindowicons.c \
winprefs.c \
@@ -120,6 +122,7 @@ SRCS = InitInput.c \
winprefs.h \
winresource.h \
winwindow.h \
+ windisplay.c \
XWin.rc \
$(top_srcdir)/Xext/dpmsstubs.c \
$(top_srcdir)/Xi/stubs.c \
@@ -147,7 +150,7 @@ XWin_SOURCES = $(SRCS)
INCLUDES = -I$(top_srcdir)/miext/rootless
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/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py
index e2d960ec6..79fbeefe8 100755
--- a/hw/xwin/glx/gen_gl_wrappers.py
+++ b/hw/xwin/glx/gen_gl_wrappers.py
@@ -67,7 +67,7 @@ if dispatchheader :
fh = open(dispatchheader)
dispatchh = fh.readlines()
- dispatch_regex = re.compile(r'#define\sSET_(\S*)\(')
+ dispatch_regex = re.compile(r'(?:#define|static\sinline\svoid)\sSET_(\S*)\(')
for line in dispatchh :
line = line.strip()
@@ -308,12 +308,20 @@ for w in sorted(wrappers.keys()) :
if dispatchheader :
print 'void glWinSetupDispatchTable(void)'
print '{'
- print ' struct _glapi_table *disp = _glapi_get_dispatch();'
+ print ' static struct _glapi_table *disp = NULL;'
+ print ''
+ print ' if (!disp)'
+ print ' {'
+ print ' disp = calloc(sizeof(void *), _glapi_get_dispatch_table_size());'
+ print ' assert(disp);'
for d in sorted(dispatch.keys()) :
if wrappers.has_key(d) :
- print ' SET_'+ d + '(disp, (void *)' + prefix + d + 'Wrapper);'
+ print ' SET_'+ d + '(disp, (void *)' + prefix + d + 'Wrapper);'
else :
print '#warning No wrapper for ' + prefix + d + ' !'
+ print ' }'
+ print ''
+ print ' _glapi_set_dispatch(disp);'
print '}'
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 86fef55d1..0873c5e4a 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -469,7 +469,7 @@ static void
glxLogExtensions(const char *prefix, const char *extensions)
{
int length = 0;
- char *strl;
+ const char *strl;
char *str = strdup(extensions);
if (str == NULL)
@@ -479,6 +479,7 @@ glxLogExtensions(const char *prefix, const char *extensions)
}
strl = strtok(str, " ");
+ if (strl == NULL) strl = "";
ErrorF("%s%s", prefix, strl);
length = strlen(prefix) + strlen(strl);
@@ -514,6 +515,7 @@ glxWinScreenProbe(ScreenPtr pScreen)
{
glxWinScreen *screen;
const char *gl_extensions;
+ const char *gl_renderer;
const char *wgl_extensions;
HWND hwnd;
HDC hdc;
@@ -537,14 +539,6 @@ glxWinScreenProbe(ScreenPtr pScreen)
if (NULL == screen)
return NULL;
- /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
- screen->RealizeWindow = pScreen->RealizeWindow;
- pScreen->RealizeWindow = glxWinRealizeWindow;
- screen->UnrealizeWindow = pScreen->UnrealizeWindow;
- pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
- screen->CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = glxWinCopyWindow;
-
/* Dump out some useful information about the native renderer */
// create window class
@@ -591,13 +585,21 @@ glxWinScreenProbe(ScreenPtr pScreen)
ErrorF("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION));
ErrorF("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
- ErrorF("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER));
+ 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 (strcasecmp(gl_renderer, "GDI Generic") == 0)
+ {
+ free(screen);
+ LogMessage(X_ERROR,"AIGLX: Won't use generic native renderer as it is not accelerated\n");
+ return NULL;
+ }
+
// Can you see the problem here? The extensions string is DC specific
// Different DCs for windows on a multimonitor system driven by multiple cards
// might have completely different capabilities. Of course, good luck getting
@@ -715,9 +717,6 @@ glxWinScreenProbe(ScreenPtr pScreen)
__glXScreenInit(&screen->base, pScreen);
- // dump out fbConfigs now fbConfigIds and visualIDs have been assigned
- fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
-
// Override the GL extensions string set by __glXScreenInit()
screen->base.GLextensions = strdup(gl_extensions);
@@ -761,6 +760,17 @@ glxWinScreenProbe(ScreenPtr pScreen)
ReleaseDC(hwnd, hdc);
DestroyWindow(hwnd);
+ // dump out fbConfigs now fbConfigIds and visualIDs have been assigned
+ fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
+
+ /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
+ screen->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = glxWinRealizeWindow;
+ screen->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+ screen->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = glxWinCopyWindow;
+
return &screen->base;
}
diff --git a/hw/xwin/glx/winpriv.c b/hw/xwin/glx/winpriv.c
index 460973730..72d65bc14 100644
--- a/hw/xwin/glx/winpriv.c
+++ b/hw/xwin/glx/winpriv.c
@@ -13,6 +13,40 @@
void
winCreateWindowsWindow (WindowPtr pWin);
+
+static
+void
+winCreateWindowsWindowHierarchy(WindowPtr pWin)
+{
+ winWindowPriv(pWin);
+
+ winDebug("winCreateWindowsWindowHierarchy - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ /* recursively ensure parent window exists if it's not the root window */
+ if (pWin->parent)
+ {
+ if (pWin->parent != pWin->drawable.pScreen->root)
+ winCreateWindowsWindowHierarchy(pWin->parent);
+ }
+
+ /* ensure this window exists */
+ if (pWinPriv->hWnd == NULL)
+ {
+ winCreateWindowsWindow(pWin);
+
+ /* ... and if it's already been mapped, make sure it's visible */
+ if (pWin->mapped)
+ {
+ /* Display the window without activating it */
+ if (pWin->drawable.class != InputOnly)
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ /* Send first paint message */
+ UpdateWindow (pWinPriv->hWnd);
+ }
+ }
+}
+
/**
* Return size and handles of a window.
* If pWin is NULL, then the information for the root window is requested.
@@ -53,8 +87,8 @@ HWND winGetWindowInfo(WindowPtr pWin)
if (pWinPriv->hWnd == NULL)
{
- winCreateWindowsWindow(pWin);
- ErrorF("winGetWindowInfo: forcing window to exist...\n");
+ ErrorF("winGetWindowInfo: forcing window to exist\n");
+ winCreateWindowsWindowHierarchy(pWin);
}
if (pWinPriv->hWnd != NULL)
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index d03a36521..67219e3f7 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,10 +161,16 @@ 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 FOR MULTIWINDOW MODE
+.TP 8
+.B \-hostintitle
+Add the host name to the window title for X applications which are running
+on remote hosts, when that information is available and it's useful to do so.
+
.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
.TP 8
.B \-[no]clipboard
@@ -211,7 +219,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/system.XWinrc b/hw/xwin/system.XWinrc
index f0771c610..5ff3abad6 100644
--- a/hw/xwin/system.XWinrc
+++ b/hw/xwin/system.XWinrc
@@ -89,9 +89,17 @@ menu apps {
}
menu root {
+ "Applications" menu apps
// Comments fit here, too...
+
+ SEPARATOR
+ FAQ EXEC "cygstart http://x.cygwin.com/docs/faq/cygwin-x-faq.html"
+ "User's Guide" EXEC "cygstart http://x.cygwin.com/docs/ug/cygwin-x-ug.html"
+ SEPARATOR
+ "View logfile" EXEC "xterm -e less +F $XWINLOGFILE"
+ SEPARATOR
+
"Reload .XWinrc" RELOAD
- "Applications" menu apps
SEParATOR
}
diff --git a/hw/xwin/taskbar.h b/hw/xwin/taskbar.h
new file mode 100644
index 000000000..bfe301d12
--- /dev/null
+++ b/hw/xwin/taskbar.h
@@ -0,0 +1,72 @@
+/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ *"Software"), to deal in the Software without restriction, including
+ *without limitation the rights to use, copy, modify, merge, publish,
+ *distribute, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT 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.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ */
+
+#ifndef _TASKBAR_H
+#define _TASKBAR_H
+
+#include <windows.h>
+
+typedef struct _tagpropertykey {
+ GUID fmtid;
+ DWORD pid;
+} PROPERTYKEY;
+#define REFPROPERTYKEY const PROPERTYKEY *
+#define REFPROPVARIANT const PROPVARIANT *
+
+#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);
+
+typedef HRESULT (__stdcall *SHGETPROPERTYSTOREFORWINDOWPROC)(HWND,REFIID,void**);
+typedef HRESULT (__stdcall *PROPVARIANTCLEARPROC)(PROPVARIANT*);
+
+#endif
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 583906442..a0631b3af 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -400,6 +400,8 @@ typedef struct
DWORD dwScreen;
int iMonitor;
+ HMONITOR hMonitor;
+
DWORD dwUserWidth;
DWORD dwUserHeight;
DWORD dwWidth;
@@ -1317,6 +1319,9 @@ winAdjustXWindow (WindowPtr pWin, HWND hwnd);
LRESULT CALLBACK
winTopLevelWindowProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK
+winChildWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
#endif
@@ -1482,6 +1487,18 @@ winDoRandRScreenSetSize (ScreenPtr pScreen,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight);
+/*
+ * windisplay.c
+ */
+
+void
+winGetDisplayName(char *szDisplay, unsigned int screen);
+
+/*
+ * winmsgwindow.c
+ */
+Bool
+winCreateMsgWindowThread(void);
/*
* END DDX and DIX Function Prototypes
diff --git a/hw/xwin/winblock.c b/hw/xwin/winblock.c
index e165d5488..b3bbc3dc8 100644
--- a/hw/xwin/winblock.c
+++ b/hw/xwin/winblock.c
@@ -44,7 +44,7 @@ winBlockHandler (int nScreen,
#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
winScreenPriv((ScreenPtr)pBlockData);
#endif
- MSG msg;
+
#ifndef HAS_DEVWINDOWS
struct timeval **tvp = pTimeout;
if (*tvp != NULL)
@@ -52,6 +52,24 @@ winBlockHandler (int nScreen,
(*tvp)->tv_sec = 0;
(*tvp)->tv_usec = 100;
}
+#else
+ /*
+ Sometimes, we have work to do on the Windows message queue,
+ but /dev/windows doesn't appear to be ready. At the moment,
+ I don't understand how that happens.
+
+ As a workaround, make sure select() just polls rather than
+ blocking if there are still messages to process...
+ */
+ if (GetQueueStatus(QS_ALLINPUT | QS_ALLPOSTMESSAGE) != 0)
+ {
+ struct timeval **tvp = pTimeout;
+ if (*tvp != NULL)
+ {
+ (*tvp)->tv_sec = 0;
+ (*tvp)->tv_usec = 0;
+ }
+ }
#endif
#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
@@ -59,8 +77,8 @@ winBlockHandler (int nScreen,
if (pScreenPriv != NULL && !pScreenPriv->fServerStarted)
{
int iReturn;
-
- winDebug ("winBlockHandler - Releasing pmServerStarted\n");
+
+ ErrorF ("winBlockHandler - pthread_mutex_unlock()\n");
/* Flag that modules are to be started */
pScreenPriv->fServerStarted = TRUE;
@@ -71,26 +89,18 @@ winBlockHandler (int nScreen,
{
ErrorF ("winBlockHandler - pthread_mutex_unlock () failed: %d\n",
iReturn);
- goto winBlockHandler_ProcessMessages;
}
-
- winDebug ("winBlockHandler - pthread_mutex_unlock () returned\n");
- }
-
-winBlockHandler_ProcessMessages:
-#endif
-
- /* Process all messages on our queue */
- while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
- {
- if ((g_hDlgDepthChange == 0
- || !IsDialogMessage (g_hDlgDepthChange, &msg))
- && (g_hDlgExit == 0
- || !IsDialogMessage (g_hDlgExit, &msg))
- && (g_hDlgAbout == 0
- || !IsDialogMessage (g_hDlgAbout, &msg)))
+ else
{
- DispatchMessage (&msg);
+ winDebug ("winBlockHandler - pthread_mutex_unlock () returned\n");
}
}
+#endif
+
+ /*
+ At least one X client has asked to suspend the screensaver, so
+ reset Windows' display idle timer
+ */
+ if (screenSaverSuspended)
+ SetThreadExecutionState(ES_DISPLAY_REQUIRED);
}
diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h
index b655f1623..bdec33f53 100644
--- a/hw/xwin/winclipboard.h
+++ b/hw/xwin/winclipboard.h
@@ -49,7 +49,6 @@
#include <X11/Xatom.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h>
-#include <X11/Xlocale.h>
/* Windows headers */
#include <X11/Xwindows.h>
diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c
index d74cd03e2..1cbc27a2b 100644
--- a/hw/xwin/winclipboardinit.c
+++ b/hw/xwin/winclipboardinit.c
@@ -61,7 +61,7 @@ extern HWND g_hwndClipboard;
Bool
winInitClipboard (void)
{
- ErrorF ("winInitClipboard ()\n");
+ winDebug ("winInitClipboard ()\n");
/* Wrap some internal server functions */
if (ProcVector[X_SetSelectionOwner] != winProcSetSelectionOwner)
diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c
index bc4bc3059..de6803436 100644
--- a/hw/xwin/winclipboardthread.c
+++ b/hw/xwin/winclipboardthread.c
@@ -80,6 +80,9 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
static int
winClipboardIOErrorHandler (Display *pDisplay);
+static void
+winClipboardThreadExit(void *arg);
+
/*
* Main thread function
*/
@@ -105,7 +108,9 @@ winClipboardProc (void *pvNotUsed)
char szDisplay[512];
int iSelectError;
- ErrorF ("winClipboardProc - Hello\n");
+ pthread_cleanup_push(&winClipboardThreadExit, NULL);
+
+ winDebug ("winClipboardProc - Hello\n");
++clipboardRestarts;
/* Do we have Unicode support? */
@@ -117,19 +122,6 @@ winClipboardProc (void *pvNotUsed)
/* Save the Unicode support flag in a global */
g_fUseUnicode = fUseUnicode;
- /* Allow multiple threads to access Xlib */
- if (XInitThreads () == 0)
- {
- ErrorF ("winClipboardProc - XInitThreads failed.\n");
- goto winClipboardProc_Exit;
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale () == False)
- {
- ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n");
- }
-
/* Set error handler */
XSetErrorHandler (winClipboardErrorHandler);
g_winClipboardProcThread = pthread_self();
@@ -149,9 +141,9 @@ winClipboardProc (void *pvNotUsed)
}
else if (iReturn == WIN_JMP_ERROR_IO)
{
- /* TODO: Cleanup the Win32 window and free any allocated memory */
- ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n");
- pthread_exit (NULL);
+ /* TODO: cleanup and free any allocated memory */
+ ErrorF("winClipboardProc - setjmp returned for IO Error Handler\n");
+ goto winClipboardProc_Done;
}
/* Use our generated cookie for authentication */
@@ -168,10 +160,7 @@ winClipboardProc (void *pvNotUsed)
* for all screens on the display. That is why there is only
* one clipboard client thread.
*/
- snprintf (szDisplay,
- 512,
- "127.0.0.1:%s.0",
- display);
+ winGetDisplayName(szDisplay, 0);
/* Print the display connection string */
ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay);
@@ -201,7 +190,7 @@ winClipboardProc (void *pvNotUsed)
goto winClipboardProc_Done;
}
- /* Save the display in the screen privates */
+ /* Save the display in a global used by the wndproc */
g_pClipboardDisplay = pDisplay;
ErrorF ("winClipboardProc - XOpenDisplay () returned and "
@@ -298,7 +287,10 @@ winClipboardProc (void *pvNotUsed)
/* Pre-flush Windows messages */
if (!winClipboardFlushWindowsMessageQueue (hwnd))
- return 0;
+ {
+ ErrorF ("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
+ pthread_exit (NULL);
+ }
/* Signal that the clipboard client has started */
g_fClipboardStarted = TRUE;
@@ -478,6 +470,8 @@ winClipboardProc_Done:
kill(getpid(), SIGTERM);
}
+ pthread_cleanup_pop(0);
+
return NULL;
}
@@ -525,3 +519,14 @@ winClipboardIOErrorHandler (Display *pDisplay)
return 0;
}
+
+/*
+ * winClipboardThreadExit - Thread exit handler
+ */
+
+static void
+winClipboardThreadExit(void *arg)
+{
+ /* clipboard thread has exited, stop server as well */
+ kill(getpid(), SIGTERM);
+}
diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c
index ec6e95a8a..7ffb6fc3d 100644
--- a/hw/xwin/winclipboardwrappers.c
+++ b/hw/xwin/winclipboardwrappers.c
@@ -92,7 +92,7 @@ winProcEstablishConnection (ClientPtr client)
static int s_iCallCount = 0;
static unsigned long s_ulServerGeneration = 0;
- if (s_iCallCount == 0) ErrorF ("winProcEstablishConnection - Hello\n");
+ if (s_iCallCount == 0) winDebug ("winProcEstablishConnection - Hello\n");
/* Do nothing if clipboard is not enabled */
if (!g_fClipboard)
diff --git a/hw/xwin/wincreatewnd.c b/hw/xwin/wincreatewnd.c
index 755373965..882725f54 100644
--- a/hw/xwin/wincreatewnd.c
+++ b/hw/xwin/wincreatewnd.c
@@ -34,10 +34,6 @@
#include "win.h"
#include "shellapi.h"
-#ifndef ABS_AUTOHIDE
-#define ABS_AUTOHIDE 1
-#endif
-
/*
* Local function prototypes
*/
@@ -46,7 +42,7 @@ static Bool
winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo);
static Bool
-winAdjustForAutoHide (RECT *prcWorkArea);
+winAdjustForAutoHide (RECT *prcWorkArea, winScreenInfo *pScreenInfo);
/*
@@ -219,7 +215,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
winGetWorkArea (&rcWorkArea, pScreenInfo);
/* Adjust for auto-hide taskbars */
- winAdjustForAutoHide (&rcWorkArea);
+ winAdjustForAutoHide (&rcWorkArea, pScreenInfo);
/* Did the user specify a position? */
if (pScreenInfo->fUserGavePosition)
@@ -523,14 +519,33 @@ winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
int iLeft, iTop;
int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
+ /* Use GetMonitorInfo to get work area for monitor */
+ if (!pScreenInfo->fMultipleMonitors)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+ if (GetMonitorInfo(pScreenInfo->hMonitor, &mi))
+ {
+ *prcWorkArea = mi.rcWork;
+
+ winDebug ("winGetWorkArea - Monitor %d WorkArea: %d %d %d %d\n",
+ pScreenInfo->iMonitor,
+ (int) prcWorkArea->top, (int) prcWorkArea->left,
+ (int) prcWorkArea->bottom, (int) prcWorkArea->right);
+ }
+ else
+ {
+ ErrorF ("winGetWorkArea - GetMonitorInfo() failed for monitor %d\n", pScreenInfo->iMonitor);
+ }
+
+ /* Bail out here if we aren't using multiple monitors */
+ return TRUE;
+ }
+
/* SPI_GETWORKAREA only gets the work area of the primary screen. */
SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0);
- /* Bail out here if we aren't using multiple monitors */
- if (!pScreenInfo->fMultipleMonitors)
- return TRUE;
-
- winDebug ("winGetWorkArea - Original WorkArea: %d %d %d %d\n",
+ winDebug ("winGetWorkArea - Primary Monitor WorkArea: %d %d %d %d\n",
(int) prcWorkArea->top, (int) prcWorkArea->left,
(int) prcWorkArea->bottom, (int) prcWorkArea->right);
@@ -581,6 +596,28 @@ winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
return TRUE;
}
+static Bool
+winTaskbarOnScreenEdge(unsigned int uEdge, winScreenInfo *pScreenInfo)
+{
+ APPBARDATA abd;
+ HWND hwndAutoHide;
+
+ ZeroMemory (&abd, sizeof (abd));
+ abd.cbSize = sizeof (abd);
+ abd.uEdge = uEdge;
+
+ hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
+ if (hwndAutoHide != NULL)
+ {
+ /*
+ Found an autohide taskbar on that edge, but is it on the
+ same monitor as the screen window?
+ */
+ if (pScreenInfo->fMultipleMonitors || (MonitorFromWindow(hwndAutoHide, MONITOR_DEFAULTTONULL) == pScreenInfo->hMonitor))
+ return TRUE;
+ }
+ return FALSE;
+}
/*
* Adjust the client area so that any auto-hide toolbars
@@ -588,10 +625,9 @@ winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
*/
static Bool
-winAdjustForAutoHide (RECT *prcWorkArea)
+winAdjustForAutoHide (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
{
APPBARDATA abd;
- HWND hwndAutoHide;
winDebug ("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n",
(int) prcWorkArea->top, (int) prcWorkArea->left,
@@ -603,37 +639,34 @@ winAdjustForAutoHide (RECT *prcWorkArea)
if (SHAppBarMessage (ABM_GETSTATE, &abd) & ABS_AUTOHIDE)
winDebug ("winAdjustForAutoHide - Taskbar is auto hide\n");
+ /*
+ Despite the forgoing, we are checking for any AppBar
+ hiding along a monitor edge, not just the Windows TaskBar.
+ */
+
/* Look for a TOP auto-hide taskbar */
- abd.uEdge = ABE_TOP;
- hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
- if (hwndAutoHide != NULL)
+ if (winTaskbarOnScreenEdge(ABE_TOP, pScreenInfo))
{
winDebug ("winAdjustForAutoHide - Found TOP auto-hide taskbar\n");
prcWorkArea->top += 1;
}
/* Look for a LEFT auto-hide taskbar */
- abd.uEdge = ABE_LEFT;
- hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
- if (hwndAutoHide != NULL)
+ if (winTaskbarOnScreenEdge(ABE_LEFT, pScreenInfo))
{
winDebug ("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n");
prcWorkArea->left += 1;
}
/* Look for a BOTTOM auto-hide taskbar */
- abd.uEdge = ABE_BOTTOM;
- hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
- if (hwndAutoHide != NULL)
+ if (winTaskbarOnScreenEdge(ABE_BOTTOM, pScreenInfo))
{
winDebug ("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n");
prcWorkArea->bottom -= 1;
}
/* Look for a RIGHT auto-hide taskbar */
- abd.uEdge = ABE_RIGHT;
- hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd);
- if (hwndAutoHide != NULL)
+ if (winTaskbarOnScreenEdge(ABE_RIGHT, pScreenInfo))
{
winDebug ("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n");
prcWorkArea->right -= 1;
@@ -642,15 +675,6 @@ winAdjustForAutoHide (RECT *prcWorkArea)
winDebug ("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n",
(int) prcWorkArea->top, (int) prcWorkArea->left,
(int) prcWorkArea->bottom, (int) prcWorkArea->right);
-
-#if 0
- /* Obtain the task bar window dimensions */
- abd.hWnd = hwndAutoHide;
- hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETTASKBARPOS, &abd);
- winDebug ("hwndAutoHide %08x abd.hWnd %08x %d %d %d %d\n",
- hwndAutoHide, abd.hWnd,
- abd.rc.top, abd.rc.left, abd.rc.bottom, abd.rc.right);
-#endif
return TRUE;
}
diff --git a/hw/xwin/windisplay.c b/hw/xwin/windisplay.c
new file mode 100644
index 000000000..10ac8f220
--- /dev/null
+++ b/hw/xwin/windisplay.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) Jon TURNEY 2009
+ *
+ * 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 <opaque.h> // for display
+#include "win.h"
+
+/*
+ Generate a display name string referring to the display of this server,
+ using a transport we know is enabled
+*/
+
+void
+winGetDisplayName(char *szDisplay, unsigned int screen)
+{
+ if (TransIsListening("local"))
+ {
+ snprintf(szDisplay, 512, ":%s.%d", display, screen);
+ }
+ else if (TransIsListening("inet"))
+ {
+ snprintf(szDisplay, 512, "127.0.0.1:%s.%d", display, screen);
+ }
+ else if (TransIsListening("inet6"))
+ {
+ snprintf(szDisplay, 512, "::1:%s.%d", display, screen);
+ }
+ else
+ {
+ // this can't happen!
+ ErrorF ("winGetDisplay: Don't know what to use for DISPLAY\n");
+ snprintf(szDisplay, 512, "localhost:%s.%d", display, screen);
+ }
+
+ winDebug("winGetDisplay: DISPLAY=%s\n", szDisplay);
+}
diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c
index bf5187bcd..5f706a6ed 100644
--- a/hw/xwin/winengine.c
+++ b/hw/xwin/winengine.c
@@ -96,7 +96,7 @@ winDetectSupportedEngines (void)
else
{
/* We have DirectDraw */
- winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw installed\n");
+ winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw installed, allowing ShadowDD\n");
g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
#ifdef XWIN_PRIMARYFB
@@ -104,11 +104,11 @@ winDetectSupportedEngines (void)
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD;
- winErrorFVerb (2, "winDetectSupportedEngines - Allowing PrimaryDD\n");
+ winErrorFVerb (2, "winDetectSupportedEngines - Windows NT, allowing PrimaryDD\n");
}
#endif
}
-
+
/* Try to query for DirectDraw4 interface */
ddrval = IDirectDraw_QueryInterface (lpdd,
&IID_IDirectDraw4,
@@ -116,7 +116,7 @@ winDetectSupportedEngines (void)
if (SUCCEEDED (ddrval))
{
/* We have DirectDraw4 */
- winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw4 installed\n");
+ winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw4 installed, allowing ShadowDDNL\n");
g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL;
}
diff --git a/hw/xwin/winerror.c b/hw/xwin/winerror.c
index 0440d13ff..ec3c2868f 100644
--- a/hw/xwin/winerror.c
+++ b/hw/xwin/winerror.c
@@ -35,6 +35,9 @@
#include <../xfree86/common/xorgVersion.h>
#include "win.h"
+/* Last error reported */
+static char lastError[1024] = "";
+
#ifdef DDXOSVERRORF
/* Prototype */
void
@@ -52,6 +55,32 @@ OsVendorVErrorF (const char *pszFormat, va_list va_args)
pthread_mutex_lock (&s_pmPrinting);
#endif
+ /* If we want to silence it,
+ * detect if we are going to abort due to duplication error */
+ if (g_fSilentDupError)
+ {
+ if ((strcmp(pszFormat,
+ "InitOutput - Duplicate invocation on display "
+ "number: %s. Exiting.\n") == 0)
+ || (strcmp(pszFormat,
+ "Server is already active for display %s\n%s %s\n%s\n") == 0)
+ || (strcmp(pszFormat,
+ "MakeAllCOTSServerListeners: server already running\n") == 0))
+ {
+ g_fSilentFatalError = TRUE;
+ }
+ }
+
+ /* Record the error, in case it's a fatal one... */
+ if ((strcmp(pszFormat,"\n") != 0) &&
+ (strcmp(pszFormat,"Server terminated %s (%d). Closing log file.\n") != 0))
+ {
+ va_list va_args_copy;
+ va_copy(va_args_copy, va_args);
+ vsnprintf(lastError, sizeof(lastError), pszFormat, va_args_copy);
+ va_end(va_args_copy);
+ }
+
/* Print the error message to a log file, could be stderr */
LogVWrite (0, pszFormat, va_args);
@@ -64,9 +93,12 @@ OsVendorVErrorF (const char *pszFormat, va_list va_args)
/*
- * 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.
+ *
+ * But the message for the fatal error is not passed to this
+ * function, so we stash the log string in lastError so we can
+ * also report it here
*
* Attempt to do last-ditch, safe, important cleanup here.
*/
@@ -83,10 +115,25 @@ OsVendorFatalError (void)
}
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"));
+ /*
+ Sometimes the error message we capture in lastError
+ needs some cosmetic cleaning up for use in a dialog box...
+ */
+ {
+ char *s;
+ while ((s = strstr(lastError, "\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,
+ lastError,
+ (g_pszLogFile ? g_pszLogFile : "the logfile"));
}
@@ -114,7 +161,7 @@ winMessageBoxF (const char *pszError, UINT uType, ...)
#define MESSAGEBOXF \
"%s\n" \
"Vendor: %s\n" \
- "Release: %d.%d.%d.%d (%d)\n" \
+ "Release: %d.%d.%d.%d\n" \
"Contact: %s\n" \
"%s\n\n" \
"XWin was started with the following command-line:\n\n" \
@@ -123,7 +170,7 @@ winMessageBoxF (const char *pszError, UINT uType, ...)
size = asprintf (&pszMsgBox, MESSAGEBOXF,
pszErrorF, XVENDORNAME,
XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH,
- XORG_VERSION_SNAP, XORG_VERSION_CURRENT,
+ XORG_VERSION_SNAP,
BUILDERADDR,
BUILDERSTRING,
g_pszCommandLine);
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 655cdb131..71cb283f3 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -76,8 +76,9 @@ Bool g_fKeyboardHookLL = FALSE;
Bool g_fNoHelpMessageBox = FALSE;
Bool g_fSoftwareCursor = FALSE;
Bool g_fSilentDupError = FALSE;
-Bool g_fNativeGl = FALSE;
-
+Bool g_fNativeGl = TRUE;
+Bool g_fHostInTitle = FALSE;
+pthread_mutex_t g_pmTerminating = PTHREAD_MUTEX_INITIALIZER;
#ifdef XWIN_CLIPBOARD
/*
diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h
index 89926796c..fe647f70b 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -47,6 +47,7 @@ extern Bool g_fXdmcpEnabled;
extern Bool g_fNoHelpMessageBox;
extern Bool g_fSilentDupError;
extern Bool g_fNativeGl;
+extern Bool g_fHostInTitle;
extern HWND g_hDlgDepthChange;
extern HWND g_hDlgExit;
@@ -85,4 +86,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/winkeybd.c b/hw/xwin/winkeybd.c
index 0496c40ab..f1add8912 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -41,6 +41,7 @@
#include "winmsg.h"
#include "xkbsrv.h"
+#include "dixgrabs.h"
static Bool g_winKeyState[NUM_KEYCODES];
@@ -282,6 +283,29 @@ winRestoreModeKeyStates (void)
* have a logical XOR operator, so we use a macro instead.
*/
+ {
+ /* consider modifer keys */
+
+ 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 (WIN_XOR (internalKeyStates & ControlMask, ctrl))
+ winSendKeyEvent (KEY_LCtrl, ctrl);
+
+ if (WIN_XOR (internalKeyStates & ShiftMask, shift))
+ winSendKeyEvent (KEY_ShiftL, shift);
+
+ if (WIN_XOR (internalKeyStates & Mod1Mask, alt))
+ winSendKeyEvent (KEY_Alt, alt);
+
+ if (WIN_XOR (internalKeyStates & Mod5Mask, altgr))
+ winSendKeyEvent (KEY_AltLang, altgr);
+ }
+
/* Has the key state changed? */
dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001;
if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState))
@@ -539,3 +563,34 @@ void winFixShiftKeys (int iScanCode)
if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL])
winSendKeyEvent (KEY_ShiftL, FALSE);
}
+
+/*
+ */
+int
+XkbDDXPrivate(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+{
+ XkbAnyAction *xf86act = &(act->any);
+ char msgbuf[XkbAnyActionDataSize+1];
+
+ if (xf86act->type == XkbSA_XFree86Private)
+ {
+ memcpy(msgbuf, xf86act->data, XkbAnyActionDataSize);
+ msgbuf[XkbAnyActionDataSize]= '\0';
+ if (strcasecmp(msgbuf, "prgrbs")==0) {
+ DeviceIntPtr tmp;
+ winMsg(X_INFO, "Printing all currently active device grabs:\n");
+ for (tmp = inputInfo.devices; tmp; tmp = tmp->next)
+ if (tmp->deviceGrab.grab)
+ PrintDeviceGrabInfo(tmp);
+ winMsg(X_INFO, "End list of active device grabs\n");
+ }
+ else if (strcasecmp(msgbuf, "ungrab")==0)
+ UngrabAllDevices(FALSE);
+ else if (strcasecmp(msgbuf, "clsgrb")==0)
+ UngrabAllDevices(TRUE);
+ else if (strcasecmp(msgbuf, "prwins")==0)
+ PrintWindowTree();
+ }
+
+ return 0;
+}
diff --git a/hw/xwin/winmonitors.c b/hw/xwin/winmonitors.c
index 967ae6d35..5484209a9 100644
--- a/hw/xwin/winmonitors.c
+++ b/hw/xwin/winmonitors.c
@@ -48,6 +48,7 @@ wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _d
data->monitorOffsetY = rect->top;
data->monitorHeight = rect->bottom - rect->top;
data->monitorWidth = rect->right - rect->left;
+ data->monitorHandle = hMonitor;
return FALSE;
}
return TRUE;
diff --git a/hw/xwin/winmonitors.h b/hw/xwin/winmonitors.h
index 180566b00..9445e90b2 100644
--- a/hw/xwin/winmonitors.h
+++ b/hw/xwin/winmonitors.h
@@ -1,3 +1,31 @@
+/*
+
+Copyright 1993, 1998 The Open Group
+Copyright (C) Colin Harrison 2005-2008
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
/* data returned for monitor information */
struct GetMonitorInfoData {
@@ -9,6 +37,7 @@ struct GetMonitorInfoData {
int monitorOffsetY;
int monitorHeight;
int monitorWidth;
+ HMONITOR monitorHandle;
};
Bool QueryMonitor(int index, struct GetMonitorInfoData *data);
diff --git a/hw/xwin/winmsgwindow.c b/hw/xwin/winmsgwindow.c
new file mode 100644
index 000000000..d8af1b5ff
--- /dev/null
+++ b/hw/xwin/winmsgwindow.c
@@ -0,0 +1,184 @@
+/*
+ * 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/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index aabde6b4a..3635931b2 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -55,10 +55,27 @@ winUpdateWindowsWindow (WindowPtr pWin);
static void
winFindWindow (pointer value, XID id, pointer cdata);
+static Bool
+isToplevelWindow(WindowPtr pWin)
+{
+ assert(pWin->parent); /* root window isn't expected here */
+
+ /* If the immediate parent is the root window, this is a top-level window */
+ if ((pWin->parent) && (pWin->parent->parent == NULL))
+ {
+ assert(pWin->parent == pWin->drawable.pScreen->root);
+ return TRUE;
+ }
+
+ /* otherwise, a child window */
+ return FALSE;
+}
+
static
void winInitMultiWindowClass(void)
{
static wATOM atomXWinClass=0;
+ static wATOM atomXWinChildClass = 0;
WNDCLASSEX wcx;
if (atomXWinClass==0)
@@ -78,11 +95,34 @@ void winInitMultiWindowClass(void)
wcx.hIconSm = g_hSmallIconX;
#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
+ ErrorF ("winInitMultiWindowClass - Creating class: %s\n", WINDOW_CLASS_X);
#endif
atomXWinClass = RegisterClassEx (&wcx);
}
+
+ if (atomXWinChildClass==0)
+ {
+ /* Setup our window class */
+ wcx.cbSize=sizeof(WNDCLASSEX);
+ wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
+ wcx.lpfnWndProc = winChildWindowProc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = 0;
+ wcx.hInstance = g_hInstance;
+ wcx.hIcon = g_hIconX;
+ wcx.hCursor = 0;
+ wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WINDOW_CLASS_X_CHILD;
+ wcx.hIconSm = g_hSmallIconX;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winInitMultiWindowClass - Creating class: %s\n", WINDOW_CLASS_X_CHILD);
+#endif
+
+ atomXWinChildClass = RegisterClassEx (&wcx);
+ }
}
/*
@@ -197,6 +237,30 @@ winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
return fResult;
}
+ if (!isToplevelWindow(pWin))
+ {
+ POINT parentOrigin;
+
+ /* Get the X and Y location of the X window */
+ iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* Get the height and width of the X window */
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Convert screen coordinates into client area co-ordinates of the parent */
+ parentOrigin.x = 0;
+ parentOrigin.y = 0;
+ ClientToScreen(GetParent(hWnd), &parentOrigin);
+
+ MoveWindow (hWnd,
+ iX - parentOrigin.x, iY - parentOrigin.y, iWidth, iHeight,
+ TRUE);
+
+ return fResult;
+ }
+
/* Get the Windows window style and extended style */
dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
@@ -476,13 +540,8 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
#endif
}
-
-/*
- * winCreateWindowsWindow - Create a Windows window associated with an X window
- */
-
-void
-winCreateWindowsWindow (WindowPtr pWin)
+static void
+winCreateWindowsTopLevelWindow (WindowPtr pWin)
{
int iX, iY;
int iWidth;
@@ -519,7 +578,7 @@ winCreateWindowsWindow (WindowPtr pWin)
iY = CW_USEDEFAULT;
}
- winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+ winDebug("winCreateWindowsTopLevelWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
if (winMultiWindowGetTransientFor (pWin, &pDaddy))
{
@@ -542,7 +601,10 @@ winCreateWindowsWindow (WindowPtr pWin)
}
}
- /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
+ winDebug("winCreateWindowsTopLevelWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+
+ /* Create the window */
+ /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
/* CW_USEDEFAULT, change back to popup after creation */
dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
dwExStyle = WS_EX_TOOLWINDOW;
@@ -578,11 +640,13 @@ winCreateWindowsWindow (WindowPtr pWin)
pWin); /* ScreenPrivates */
if (hWnd == NULL)
{
- ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
+ ErrorF ("winCreateWindowsTopLevelWindow - CreateWindowExA () failed: %d\n",
(int) GetLastError ());
}
pWinPriv->hWnd = hWnd;
+ winDebug("winCreateWindowsTopLevelWindow - hwnd 0x%08x\n", hWnd);
+
/* Set application or .XWinrc defined Icons */
winSelectIcons(pWin, &hIcon, &hIconSmall);
if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
@@ -611,6 +675,104 @@ winCreateWindowsWindow (WindowPtr pWin)
(*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
}
+static void
+winCreateWindowsChildWindow(WindowPtr pWin)
+{
+ int iX, iY, iWidth, iHeight;
+ HWND hWnd;
+ WindowPtr pParent = pWin->parent;
+ DWORD dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED;
+ DWORD dwExStyle = WS_EX_TRANSPARENT;
+ /*
+ WS_DISABLED means child window never gains the input focus, so only the
+ top-level window needs deal with passing input to the X server
+
+ WS_EX_TRANSPARENT ensures that the contents of the top-level
+ Windows window (which will contain all non-OpenGL drawing for the hierarchy)
+ can be seen through any intermediate child windows which have nothing
+ drawn to them
+ */
+ winPrivWinPtr pParentPriv, pWinPriv;
+
+ winDebug("winCreateWindowsChildWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ winInitMultiWindowClass();
+
+ assert(pParent);
+
+ pParentPriv = winGetWindowPriv(pParent);
+ pWinPriv = winGetWindowPriv(pWin);
+
+ iX = pWin->drawable.x - pParent->drawable.x;
+ iY = pWin->drawable.y - pParent->drawable.y;
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ winDebug("winCreateWindowsChildWindow - parent pWin:%08x XID:0x%08x hWnd:0x%08x\n", pParent, pParent->drawable.id, pParentPriv->hWnd);
+ winDebug("winCreateWindowsChildWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX, iY);
+
+ /* Create the window */
+ hWnd = CreateWindowExA (dwExStyle, /* Extended styles */
+ WINDOW_CLASS_X_CHILD, /* Class name */
+ WINDOW_TITLE_X, /* Window name */
+ dwStyle, /* Styles */
+ iX, /* Horizontal position */
+ iY, /* Vertical position */
+ iWidth, /* Right edge */
+ iHeight, /* Bottom edge */
+ pParentPriv->hWnd, /* parent window */
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle(NULL),/* Instance handle */
+ pWin); /* ScreenPrivates */
+ if (hWnd == NULL)
+ {
+ ErrorF ("winCreateWindowsChildWindow - CreateWindowExA () failed: %d\n",
+ (int) GetLastError ());
+ }
+ winDebug("winCreateWindowsChildWindow - hwnd 0x%08x\n", hWnd);
+ pWinPriv->hWnd = hWnd;
+
+ SetProp(hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
+}
+
+/*
+ * winCreateWindowsWindow - Create a Windows window associated with an X window
+ */
+
+void
+winCreateWindowsWindow (WindowPtr pWin)
+{
+ winDebug("winCreateWindowsWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ if (isToplevelWindow(pWin))
+ {
+ winCreateWindowsTopLevelWindow(pWin);
+ }
+ else
+ {
+ winCreateWindowsChildWindow(pWin);
+ }
+}
+
+static int
+winDestroyChildWindowsWindow(WindowPtr pWin, pointer data)
+{
+ winWindowPriv(pWin);
+
+ winDebug("winDestroyChildWindowsWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
+
+ SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
+
+ /* Null our handle to the Window so referencing it will cause an error */
+ pWinPriv->hWnd = NULL;
+
+#ifdef XWIN_GLX_WINDOWS
+ /* No longer note WGL used on this window */
+ pWinPriv->fWglUsed = FALSE;
+#endif
+
+ return WT_WALKCHILDREN; /* continue enumeration */
+}
Bool winInDestroyWindowsWindow = FALSE;
/*
@@ -625,6 +787,7 @@ winDestroyWindowsWindow (WindowPtr pWin)
BOOL oldstate = winInDestroyWindowsWindow;
HICON hIcon;
HICON hIconSm;
+ HWND hWnd;
winDebug("winDestroyWindowsWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id);
@@ -638,21 +801,20 @@ winDestroyWindowsWindow (WindowPtr pWin)
hIcon = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
hIconSm = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
- /* Destroy the Windows window */
- DestroyWindow (pWinPriv->hWnd);
+ hWnd = pWinPriv->hWnd;
- /* Null our handle to the Window so referencing it will cause an error */
- pWinPriv->hWnd = NULL;
+ /* DestroyWindow() implicitly destroys all child windows,
+ so first walk over the child tree of this window, clearing
+ any hWnds */
+ TraverseTree(pWin, winDestroyChildWindowsWindow, 0);
+
+ /* Destroy the Windows window */
+ DestroyWindow (hWnd);
/* Destroy any icons we created for this window */
winDestroyIcon(hIcon);
winDestroyIcon(hIconSm);
-#ifdef XWIN_GLX_WINDOWS
- /* No longer note WGL used on this window */
- pWinPriv->fWglUsed = FALSE;
-#endif
-
/* Process all messages on our queue */
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
@@ -677,36 +839,64 @@ static void
winUpdateWindowsWindow (WindowPtr pWin)
{
winWindowPriv(pWin);
- HWND hWnd = pWinPriv->hWnd;
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winUpdateWindowsWindow\n");
#endif
- /* Check if the Windows window's parents have been destroyed */
- if (pWin->parent != NULL
- && pWin->parent->parent == NULL
- && pWin->mapped)
- {
- /* Create the Windows window if it has been destroyed */
- if (hWnd == NULL)
- {
- winCreateWindowsWindow (pWin);
- assert (pWinPriv->hWnd != NULL);
- }
- /* Display the window without activating it */
- if (pWin->drawable.class != InputOnly)
- ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+ /* Ignore the root window */
+ if (pWin->parent == NULL)
+ return;
- /* Send first paint message */
- UpdateWindow (pWinPriv->hWnd);
+ /* If it's mapped */
+ if (pWin->mapped)
+ {
+ /* If it's a top-level window */
+ if (isToplevelWindow(pWin))
+ {
+ /* Create the Windows window if needed */
+ if (pWinPriv->hWnd == NULL)
+ {
+ winCreateWindowsWindow (pWin);
+ assert (pWinPriv->hWnd != NULL);
+ }
+
+ /* Display the window without activating it */
+ if (pWin->drawable.class != InputOnly)
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ }
+ /* It's not a top-level window, but we created a window for GLX */
+ else if (pWinPriv->hWnd)
+ {
+ winPrivWinPtr pParentPriv = winGetWindowPriv(pWin->parent);
+
+ /* XXX: This really belongs in winReparentWindow ??? */
+ /* XXX: this assumes parent window has been made to exist */
+ assert(pParentPriv->hWnd);
+
+ /* Ensure we have the correct parent and position if reparented */
+ SetParent(pWinPriv->hWnd, pParentPriv->hWnd);
+ SetWindowPos(pWinPriv->hWnd, NULL, pWin->drawable.x - pWin->parent->drawable.x, pWin->drawable.y - pWin->parent->drawable.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
+ }
+
+ /* If it's top level, or a GLX window which has already been created getting mapped, show it */
+ if (pWinPriv->hWnd != NULL)
+ {
+ /* Display the window without activating it */
+ if (pWin->drawable.class != InputOnly)
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ /* Send first paint message */
+ UpdateWindow (pWinPriv->hWnd);
+ }
}
- else if (hWnd != NULL)
+ else if (pWinPriv->hWnd != NULL)
{
- /* Destroy the Windows window if its parents are destroyed */
+ /* If it's been reparented to an unmapped window when previously mapped, destroy the Windows window */
winDestroyWindowsWindow (pWin);
- assert (pWinPriv->hWnd == NULL);
+ assert(pWinPriv->hWnd == NULL);
}
#if CYGMULTIWINDOW_DEBUG
@@ -954,6 +1144,14 @@ winAdjustXWindow (WindowPtr pWin, HWND hwnd)
ErrorF ("winAdjustXWindow\n");
#endif
+ if (!isToplevelWindow(pWin))
+ {
+#if 1
+ ErrorF ("winAdjustXWindow - immediately return because not a top-level window\n");
+#endif
+ return 0;
+ }
+
if (IsIconic (hwnd))
{
#if CYGWINDOWING_DEBUG
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 70f53854c..abe35efb5 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -48,7 +48,6 @@
#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>
@@ -62,6 +61,14 @@
#include "window.h"
#include "pixmapstr.h"
#include "windowstr.h"
+#include "winglobals.h"
+
+#include <shlwapi.h>
+
+#define INITGUID
+#include "initguid.h"
+#include "taskbar.h"
+#undef INITGUID
#ifdef XWIN_MULTIWINDOWEXTWM
#include <X11/extensions/windowswmstr.h>
@@ -136,7 +143,6 @@ typedef struct _XMsgProcArgRec {
* References to external symbols
*/
-extern char *display;
extern void ErrorF (const char* /*f*/, ...);
/*
@@ -153,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);
@@ -179,6 +185,9 @@ winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr);
static int
winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay);
+static void
+winMultiWindowThreadExit(void *arg);
+
static int
winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr);
@@ -212,6 +221,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
@@ -395,49 +408,78 @@ InitQueue (WMMsgQueuePtr pQueue)
pQueue->nQueueSize = 0;
#if CYGMULTIWINDOW_DEBUG
- ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize,
- QueueSize(pQueue));
+ winDebug ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue));
#endif
- ErrorF ("InitQueue - Calling pthread_mutex_init\n");
+ winDebug ("InitQueue - Calling pthread_mutex_init\n");
/* Create synchronization objects */
pthread_mutex_init (&pQueue->pmMutex, NULL);
- ErrorF ("InitQueue - pthread_mutex_init returned\n");
- ErrorF ("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);
- ErrorF ("InitQueue - pthread_cond_init returned\n");
+ winDebug ("InitQueue - pthread_cond_init returned\n");
return TRUE;
}
+static
+char *Xutf8TextPropertyToString(Display *pDisplay, XTextProperty *xtp)
+{
+ int nNum;
+ char **ppList;
+ char *pszReturnData;
+
+ if (Xutf8TextPropertyToTextList (pDisplay, xtp, &ppList, &nNum) >= Success && nNum > 0 && *ppList)
+ {
+ int i;
+ int iLen = 0;
+
+ for (i = 0; i < nNum; i++)
+ iLen += strlen(ppList[i]);
+ pszReturnData = (char *) malloc (iLen + 1);
+ pszReturnData[0] = '\0';
+ for (i = 0; i < nNum; i++)
+ strcat (pszReturnData, ppList[i]);
+ if (ppList)
+ XFreeStringList (ppList);
+ }
+ else
+ {
+ pszReturnData = (char *) malloc (1);
+ pszReturnData[0] = '\0';
+ }
+
+ return pszReturnData;
+}
/*
* GetWindowName - Retrieve the title of an X Window
*/
static void
-GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName)
+GetWindowName (Display *pDisplay, Window iWin, char **ppWindowName)
{
- int nResult, nNum;
- char **ppList;
- char *pszReturnData;
- int iLen, i;
- XTextProperty xtpName;
-
+ int nResult;
+ XTextProperty xtpWindowName;
+ XTextProperty xtpClientMachine;
+ char *pszWindowName;
+ char *pszClientMachine;
+ char hostname[HOST_NAME_MAX + 1];
+
#if CYGMULTIWINDOW_DEBUG
ErrorF ("GetWindowName\n");
#endif
- /* Intialize ppName to NULL */
- *ppName = NULL;
+ /* Intialize ppWindowName to NULL */
+ *ppWindowName = NULL;
- /* Try to get --- */
- nResult = XGetWMName (pDisplay, iWin, &xtpName);
- if (!nResult || !xtpName.value || !xtpName.nitems)
+ /* Try to get window name */
+ nResult = XGetWMName (pDisplay, iWin, &xtpWindowName);
+ if (!nResult || !xtpWindowName.value || !xtpWindowName.nitems)
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("GetWindowName - XGetWMName failed. No name.\n");
@@ -445,29 +487,43 @@ GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName)
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);
- pszReturnData[0] = '\0';
- for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]);
- if (ppList) XFreeStringList (ppList);
- }
- else
- {
- 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);
+ pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
+ XFree(xtpWindowName.value);
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("GetWindowName - Returning\n");
-#endif
+ if (g_fHostInTitle)
+ {
+ /* Try to get client machine name */
+ nResult = XGetWMClientMachine(pDisplay, iWin, &xtpClientMachine);
+ if (nResult && xtpClientMachine.value && xtpClientMachine.nitems)
+ {
+ pszClientMachine = Xutf8TextPropertyToString(pDisplay, &xtpClientMachine);
+ XFree(xtpClientMachine.value);
+
+ /*
+ If we have a client machine name
+ and it's not the local host name...
+ */
+ if (strlen(pszClientMachine) &&
+ !gethostname(hostname, HOST_NAME_MAX + 1) &&
+ strcmp (hostname, pszClientMachine))
+ {
+ /* ... add ' (on <clientmachine>)' to end of window name */
+ *ppWindowName = malloc(strlen(pszWindowName) + strlen(pszClientMachine) + 7);
+ strcpy(*ppWindowName, pszWindowName);
+ strcat(*ppWindowName, " (on ");
+ strcat(*ppWindowName, pszClientMachine);
+ strcat(*ppWindowName, ")");
+
+ free(pszWindowName);
+ free(pszClientMachine);
+
+ return;
+ }
+ }
+ }
+
+ /* otherwise just return the window name */
+ *ppWindowName = pszWindowName;
}
@@ -500,7 +556,6 @@ SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData)
static void
UpdateName (WMInfoPtr pWMInfo, Window iWindow)
{
- wchar_t *pszName;
Atom atmType;
int fmtRet;
unsigned long items, remain;
@@ -529,26 +584,33 @@ UpdateName (WMInfoPtr pWMInfo, Window iWindow)
XFree (retHwnd);
}
}
-
+
/* Some sanity checks */
if (!hWnd) return;
if (!IsWindow (hWnd)) return;
- /* Set the Windows window name */
- GetWindowName (pWMInfo->pDisplay, iWindow, &pszName);
- if (pszName)
+ /* If window isn't override-redirect */
+ XGetWindowAttributes (pWMInfo->pDisplay, iWindow, &attr);
+ if (!attr.override_redirect)
{
- /* Get the window attributes */
- XGetWindowAttributes (pWMInfo->pDisplay,
- iWindow,
- &attr);
- if (!attr.override_redirect)
- {
- SetWindowTextW (hWnd, pszName);
- winUpdateIcon (iWindow);
- }
+ 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);
- free (pszName);
+ /* Set the Windows window name */
+ SetWindowTextW (hWnd, pwszWideWindowName);
+ winUpdateIcon (iWindow);
+
+ free (pwszWideWindowName);
+ free (pszWindowName);
+ }
}
}
@@ -630,6 +692,8 @@ winMultiWindowWMProc (void *pArg)
{
WMProcArgPtr pProcArg = (WMProcArgPtr)pArg;
WMInfoPtr pWMInfo = pProcArg->pWMInfo;
+
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
/* Initialize the Window Manager */
winInitMultiWindowWM (pWMInfo, pProcArg);
@@ -842,6 +906,9 @@ winMultiWindowWMProc (void *pArg)
#if CYGMULTIWINDOW_DEBUG
ErrorF("-winMultiWindowWMProc ()\n");
#endif
+
+ pthread_cleanup_pop(0);
+
return NULL;
}
@@ -864,7 +931,9 @@ winMultiWindowXMsgProc (void *pArg)
int iReturn;
XIconSize *xis;
- ErrorF ("winMultiWindowXMsgProc - Hello\n");
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
+ winDebug ("winMultiWindowXMsgProc - Hello\n");
/* Check that argument pointer is not invalid */
if (pProcArg == NULL)
@@ -887,19 +956,6 @@ winMultiWindowXMsgProc (void *pArg)
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");
- }
-
/* Release the server started mutex */
pthread_mutex_unlock (pProcArg->ppmServerStarted);
@@ -929,8 +985,7 @@ 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);
@@ -1181,7 +1236,7 @@ winMultiWindowXMsgProc (void *pArg)
}
XCloseDisplay (pProcArg->pDisplay);
- pthread_exit (NULL);
+ pthread_cleanup_pop(0);
return NULL;
}
@@ -1274,7 +1329,7 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
char pszDisplay[512];
int iReturn;
- ErrorF ("winInitMultiWindowWM - Hello\n");
+ winDebug ("winInitMultiWindowWM - Hello\n");
/* Check that argument pointer is not invalid */
if (pProcArg == NULL)
@@ -1297,19 +1352,6 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
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");
- }
-
/* Release the server started mutex */
pthread_mutex_unlock (pProcArg->ppmServerStarted);
@@ -1339,11 +1381,7 @@ 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);
@@ -1522,6 +1560,16 @@ winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay)
return 0;
}
+/*
+ * winMultiWindowThreadExit - Thread exit handler
+ */
+
+static void
+winMultiWindowThreadExit(void *arg)
+{
+ /* multiwindow client thread has exited, stop server as well */
+ kill(getpid(), SIGTERM);
+}
/*
* Catch RedirectError to detect other window manager running
@@ -1699,10 +1747,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))
{
@@ -1710,8 +1762,21 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle)
style = 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);
+ }
+ 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
@@ -1823,3 +1888,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);
+ }
+}
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 19dad579c..3c0fc34cc 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -321,6 +321,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
static Bool s_fTracking = FALSE;
Bool needRestack = FALSE;
LRESULT ret;
+ static Bool hasEnteredSizeMove = FALSE;
#if CYGDEBUG
winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam);
@@ -834,6 +835,9 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
break;
case WM_CLOSE:
+ /* Remove property AppUserModelID */
+ winSetAppID (hwnd, NULL);
+
/* Branch on if the window was killed in X already */
if (pWinPriv->fXKilled)
{
@@ -870,7 +874,8 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
case WM_MOVE:
/* Adjust the X Window to the moved Windows window */
- winAdjustXWindow (pWin, hwnd);
+ if (!hasEnteredSizeMove) winAdjustXWindow (pWin, hwnd);
+ /* else: Wait for WM_EXITSIZEMOVE */
return 0;
case WM_SHOWWINDOW:
@@ -1011,6 +1016,16 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
*/
break;
+ case WM_ENTERSIZEMOVE:
+ hasEnteredSizeMove = TRUE;
+ return 0;
+
+ case WM_EXITSIZEMOVE:
+ /* Adjust the X Window to the moved Windows window */
+ hasEnteredSizeMove = FALSE;
+ winAdjustXWindow (pWin, hwnd);
+ return 0;
+
case WM_SIZE:
/* see dix/window.c */
#if CYGWINDOWING_DEBUG
@@ -1035,8 +1050,13 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
(int)(GetTickCount ()));
}
#endif
- /* Adjust the X Window to the moved Windows window */
- winAdjustXWindow (pWin, hwnd);
+ if (!hasEnteredSizeMove)
+ {
+ /* Adjust the X Window to the moved Windows window */
+ winAdjustXWindow (pWin, hwnd);
+ if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow();
+ }
+ /* else: wait for WM_EXITSIZEMOVE */
return 0; /* end of WM_SIZE handler */
case WM_STYLECHANGING:
@@ -1133,3 +1153,42 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
winReorderWindowsMultiWindow();
return ret;
}
+
+/*
+ * winChildWindowProc - Window procedure for all top-level Windows windows.
+ */
+
+LRESULT CALLBACK
+winChildWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+#if CYGDEBUG
+ winDebugWin32Message("winChildWindowProc", hwnd, message, wParam, lParam);
+#endif
+
+ switch (message)
+ {
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_PAINT:
+ /*
+ We don't have the bits to draw into the window, they went straight into the OpenGL
+ surface
+
+ XXX: For now, just leave it alone, but ideally we want to send an expose event to
+ the window so it really redraws the affected region...
+ */
+ {
+ PAINTSTRUCT ps;
+ HDC hdcUpdate;
+ hdcUpdate = BeginPaint(hwnd, &ps);
+ ValidateRect(hwnd, &(ps.rcPaint));
+ EndPaint(hwnd, &ps);
+ return 0;
+ }
+ /* XXX: this is exactly what DefWindowProc does? */
+ }
+
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c
index 76c30e9e3..7750e7c94 100644
--- a/hw/xwin/winprefs.c
+++ b/hw/xwin/winprefs.c
@@ -58,10 +58,6 @@ extern int parse_file (FILE *fp);
/* Currently in use command ID, incremented each new menu item created */
static int g_cmdid = STARTMENUID;
-
-/* Defined in DIX */
-extern char *display;
-
/* Local function to handle comma-ified icon names */
static HICON
LoadImageComma (char *fname, int sx, int sy, int flags);
@@ -726,6 +722,10 @@ winPrefsLoadPreferences (char *path)
"MENU rmenu {\n"
" \"How to customize this menu\" EXEC \"xterm +tb -e man XWinrc\"\n"
" \"Launch xterm\" EXEC xterm\n"
+ " SEPARATOR\n"
+ " FAQ EXEC \"cygstart http://x.cygwin.com/docs/faq/cygwin-x-faq.html\"\n"
+ " \"User's Guide\" EXEC \"cygstart http://x.cygwin.com/docs/ug/cygwin-x-ug.html\"\n"
+ " SEPARATOR\n"
" \"Load .XWinrc\" RELOAD\n"
" SEPARATOR\n"
"}\n"
@@ -809,16 +809,18 @@ LoadPreferences (void)
/* Setup a DISPLAY environment variable, need to allocate on heap */
/* because putenv doesn't copy the argument... */
- snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display);
- szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1));
+ winGetDisplayName(szDisplay, 0);
+ szEnvDisplay = (char *)(malloc(strlen(szDisplay)+strlen("DISPLAY=")+1));
if (szEnvDisplay)
{
- strcpy (szEnvDisplay, szDisplay);
+ snprintf(szEnvDisplay, 512, "DISPLAY=%s", szDisplay);
putenv (szEnvDisplay);
}
+ /* Setup XWINLOGFILE environment variable */
+ setenv("XWINLOGFILE", g_pszLogFile, TRUE);
+
/* Replace any "%display%" in menu commands with display string */
- snprintf (szDisplay, 512, "127.0.0.1:%s.0", display);
for (i=0; i<pref.menuItems; i++)
{
for (j=0; j<pref.menu[i].menuItems; j++)
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 9bec84141..674aa03db 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -111,6 +111,7 @@ winInitializeScreenDefaults(void)
}
defaultScreenInfo.iMonitor = 1;
+ defaultScreenInfo.hMonitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);
defaultScreenInfo.dwWidth = dwWidth;
defaultScreenInfo.dwHeight = dwHeight;
defaultScreenInfo.dwUserWidth = dwWidth;
@@ -139,7 +140,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;
@@ -154,7 +155,7 @@ winInitializeScreenDefaults(void)
static void
winInitializeScreen(int i)
{
- winErrorFVerb (2, "winInitializeScreen - %d\n",i);
+ winErrorFVerb (3, "winInitializeScreen - %d\n",i);
/* Initialize default screen values, if needed */
winInitializeScreenDefaults();
@@ -170,7 +171,7 @@ void
winInitializeScreens(int maxscreens)
{
int i;
- winErrorFVerb (2, "winInitializeScreens - %i\n", maxscreens);
+ winErrorFVerb (3, "winInitializeScreens - %i\n", maxscreens);
if (maxscreens > g_iNumScreens)
{
@@ -334,6 +335,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
+ g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth;
g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight;
g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth;
@@ -386,6 +388,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
} else if (data.bMonitorSpecifiedExists == TRUE)
{
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
+ g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX;
g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY;
}
@@ -415,6 +418,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
+ g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
}
@@ -1143,6 +1147,12 @@ ddxProcessArgument (int argc, char *argv[], int i)
return 1;
}
+ if (IS_OPTION("-hostintitle"))
+ {
+ g_fHostInTitle = TRUE;
+ return 1;
+ }
+
return 0;
}
@@ -1218,6 +1228,107 @@ winLogCommandLine (int argc, char *argv[])
"%s\n\n", g_pszCommandLine);
}
+/*
+ * Detect the OS
+ */
+
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+
+static void
+winOS(void)
+{
+ OSVERSIONINFOEX osvi = {0};
+ char *windowstype = "Unknown";
+ char *prodName = "Unknown";
+ char *isWow = "Unknown";
+ LPFN_ISWOW64PROCESS fnIsWow64Process;
+
+ /* Get operating system version information */
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx((LPOSVERSIONINFO)&osvi);
+
+ /* Branch on platform ID */
+ switch (osvi.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32_NT:
+ windowstype = "Windows NT";
+
+ if (osvi.dwMajorVersion <= 4)
+ prodName = "Windows NT";
+ else if (osvi.dwMajorVersion == 6)
+ {
+ if (osvi.dwMinorVersion == 2)
+ {
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ prodName = "Windows 8";
+ else
+ prodName = "Windows Server 2012";
+ }
+ else if (osvi.dwMinorVersion == 1)
+ {
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ prodName = "Windows 7";
+ else
+ prodName = "Windows Server 2008 R2";
+ }
+ else if (osvi.dwMinorVersion == 0)
+ {
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ prodName = "Windows Vista";
+ else
+ prodName = "Windows Server 2008";
+ }
+ } else if (osvi.dwMajorVersion == 5)
+ {
+ if (osvi.dwMinorVersion == 2)
+ {
+ if (GetSystemMetrics(SM_SERVERR2))
+ prodName = "Windows Server 2003 R2";
+ else
+ prodName = "Windows Server 2003";
+ }
+ else if (osvi.dwMinorVersion == 1)
+ prodName = "Windows XP";
+ else if (osvi.dwMinorVersion == 0)
+ {
+ prodName = "Windows 2000";
+ break;
+ }
+ }
+
+ break;
+
+ case VER_PLATFORM_WIN32_WINDOWS:
+ windowstype = "Windows";
+ break;
+ }
+
+ /* Check if we are running under WoW64 */
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process");
+ if (NULL != fnIsWow64Process)
+ {
+ wBOOL bIsWow64 = FALSE;
+ if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
+ {
+ isWow = bIsWow64 ? " (WoW64)" : " (Win32)";
+ }
+ else
+ {
+ /* IsWow64Process() failed */
+ isWow = " (WoWUnknown)";
+ }
+ }
+ else
+ {
+ /* OS doesn't support IsWow64Process() */
+ isWow = "";
+ }
+
+ ErrorF("OS: %s %s [%s %ld.%ld build %ld]%s\n",
+ prodName, osvi.szCSDVersion,
+ windowstype, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber,
+ isWow);
+}
/*
* winLogVersionInfo - Log version information
@@ -1234,7 +1345,8 @@ winLogVersionInfo (void)
ErrorF ("Welcome to the XWin X Server\n");
ErrorF ("Vendor: %s\n", XVENDORNAME);
- ErrorF ("Release: %d.%d.%d.%d (%d)\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT);
- ErrorF ("%s\n\n", BUILDERSTRING);
- ErrorF ("Contact: %s\n", BUILDERADDR);
+ ErrorF ("Release: %d.%d.%d.%d\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP);
+ winOS();
+ if (strlen(BUILDERSTRING)) ErrorF ("%s\n", BUILDERSTRING);
+ ErrorF("\n");
}
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 983ff5730..fa6838a78 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -467,7 +467,7 @@ winFinishScreenInitFB (int index,
if (pScreen->a) { \
pScreenPriv->a = pScreen->a; \
} else { \
- ErrorF("null screen fn " #a "\n"); \
+ winDebug("winScreenInit - null screen fn " #a "\n"); \
pScreenPriv->a = NULL; \
}
@@ -503,7 +503,7 @@ winFinishScreenInitFB (int index,
if (pScreen->a) { \
pScreenPriv->a = pScreen->a; \
} else { \
- ErrorF("null screen fn " #a "\n"); \
+ winDebug("null screen fn " #a "\n"); \
pScreenPriv->a = NULL; \
}
diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c
index b512b29e8..031a510f9 100644
--- a/hw/xwin/winwakeup.c
+++ b/hw/xwin/winwakeup.c
@@ -45,8 +45,8 @@ winWakeupHandler (int nScreen,
{
MSG msg;
- /* Process all messages on our queue */
- while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ /* Process one message from our queue */
+ if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if ((g_hDlgDepthChange == 0
|| !IsDialogMessage (g_hDlgDepthChange, &msg))
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 91399c248..734ac87d7 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -283,7 +283,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 */
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 229696ae4..769b890e8 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -49,6 +49,8 @@
#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_CHILD "cygwin/x X child"
+#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
@@ -160,6 +162,14 @@ winDeinitMultiWindowWM (void);
void
winMinimizeWindow (Window id);
+void
+winTaskbarInit (void);
+
+void
+winTaskbarDestroy (void);
+
+void
+winSetAppID (HWND hWnd, const char* AppID);
/*
* winmultiwindowicons.c
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 88b506891..e99697de8 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -438,6 +438,12 @@ winWindowProc (HWND hwnd, UINT message,
}
return 0;
+ case WM_SYSCOMMAND:
+ if (s_pScreenInfo->iResizeMode == resizeWithRandr &&
+ ((wParam & 0xfff0) == SC_MAXIMIZE || (wParam & 0xfff0) == SC_RESTORE))
+ PostMessage(hwnd, WM_EXITSIZEMOVE, 0, 0);
+ break;
+
case WM_ENTERSIZEMOVE:
ErrorF("winWindowProc - WM_ENTERSIZEMOVE\n");
break;
@@ -1257,7 +1263,6 @@ winWindowProc (HWND hwnd, UINT message,
}
break;
- case WM_ENDSESSION:
case WM_GIVEUP:
/* Tell X that we are giving up */
#ifdef XWIN_MULTIWINDOW