summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/common/Makefile.am3
-rw-r--r--hw/xquartz/Makefile.am1
-rw-r--r--hw/xquartz/pseudoramiX.c516
-rw-r--r--hw/xquartz/pseudoramiX.h10
-rw-r--r--hw/xwin/InitOutput.c231
-rw-r--r--hw/xwin/Makefile.am9
-rw-r--r--hw/xwin/ddraw.h4
-rw-r--r--hw/xwin/glx/indirect.c22
-rw-r--r--hw/xwin/glx/winpriv.c34
-rw-r--r--hw/xwin/man/XWin.man21
-rw-r--r--hw/xwin/man/XWinrc.man29
-rw-r--r--hw/xwin/system.XWinrc10
-rw-r--r--hw/xwin/taskbar.h88
-rw-r--r--hw/xwin/win.h14
-rw-r--r--hw/xwin/winblock.c41
-rw-r--r--hw/xwin/winclipboard.h1
-rw-r--r--hw/xwin/winclipboardtextconv.c11
-rw-r--r--hw/xwin/winclipboardthread.c56
-rw-r--r--hw/xwin/winclipboardwndproc.c42
-rw-r--r--hw/xwin/winclipboardwrappers.c14
-rw-r--r--hw/xwin/winclipboardxevents.c90
-rw-r--r--hw/xwin/winconfig.c1
-rw-r--r--hw/xwin/winconfig.h1
-rw-r--r--hw/xwin/windisplay.c52
-rw-r--r--hw/xwin/winengine.c6
-rw-r--r--hw/xwin/winerror.c42
-rw-r--r--hw/xwin/winglobals.c4
-rw-r--r--hw/xwin/winglobals.h3
-rw-r--r--hw/xwin/winkeybd.c56
-rw-r--r--hw/xwin/winmsgwindow.c180
-rw-r--r--hw/xwin/winmultiwindowclass.c22
-rw-r--r--hw/xwin/winmultiwindowwindow.c279
-rw-r--r--hw/xwin/winmultiwindowwm.c437
-rw-r--r--hw/xwin/winmultiwindowwndproc.c125
-rw-r--r--hw/xwin/winprefs.c152
-rw-r--r--hw/xwin/winprefslex.l6
-rw-r--r--hw/xwin/winprefsyacc.y91
-rw-r--r--hw/xwin/winprocarg.c129
-rw-r--r--hw/xwin/winscrinit.c20
-rw-r--r--hw/xwin/winshaddd.c30
-rw-r--r--hw/xwin/winshadddnl.c30
-rw-r--r--hw/xwin/winshadgdi.c13
-rw-r--r--hw/xwin/wintaskbar.c87
-rw-r--r--hw/xwin/winwakeup.c4
-rw-r--r--hw/xwin/winwin32rootless.c2
-rw-r--r--hw/xwin/winwindow.h12
-rw-r--r--hw/xwin/winwndproc.c10
47 files changed, 2070 insertions, 971 deletions
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index f8fcde956..532d87bbe 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -15,6 +15,7 @@ XVSDKINCS = xf86xv.h xf86xvmc.h xf86xvpriv.h
endif
if XF86VIDMODE
+XF86VMODESOURCES = xf86vmode.c
XF86VMODE_SDK = vidmodeproc.h
endif
@@ -47,7 +48,7 @@ libcommon_la_SOURCES = xf86Configure.c xf86Bus.c xf86Config.c \
xf86VidMode.c xf86fbman.c xf86cmap.c \
xf86Helper.c xf86PM.c xf86Xinput.c xisb.c \
xf86Mode.c xorgHelper.c xf86Extensions.h \
- xf86Extensions.c xf86vmode.c \
+ xf86Extensions.c $(XF86VMODESOURCES) \
$(XVSOURCES) $(BUSSOURCES) $(RANDRSOURCES)
nodist_libcommon_la_SOURCES = xf86DefModeSet.c xf86Build.h
libcommon_la_LIBADD = $(top_builddir)/config/libconfig.la
diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am
index a7cc012d9..57928005c 100644
--- a/hw/xquartz/Makefile.am
+++ b/hw/xquartz/Makefile.am
@@ -28,7 +28,6 @@ libXquartz_la_SOURCES = \
darwinEvents.c \
darwinXinput.c \
keysym2ucs.c \
- pseudoramiX.c \
quartz.c \
quartzCocoa.m \
quartzKeyboard.c \
diff --git a/hw/xquartz/pseudoramiX.c b/hw/xquartz/pseudoramiX.c
deleted file mode 100644
index 23dbc7328..000000000
--- a/hw/xquartz/pseudoramiX.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Minimal implementation of PanoramiX/Xinerama
- *
- * This is used in rootless mode where the underlying window server
- * already provides an abstracted view of multiple screens as one
- * large screen area.
- *
- * This code is largely based on panoramiX.c, which contains the
- * following copyright notice:
- */
-/*****************************************************************
- Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
- 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.
-
- 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
- DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
- BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
- shall not be used in advertising or otherwise to promote the sale, use or other
- dealings in this Software without prior written authorization from Digital
- Equipment Corporation.
- ******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "pseudoramiX.h"
-#include "extnsionst.h"
-#include "extinit.h"
-#include "dixstruct.h"
-#include "window.h"
-#include <X11/extensions/panoramiXproto.h>
-#include "globals.h"
-
-#define TRACE PseudoramiXTrace("TRACE " __FILE__ ":%s",__FUNCTION__)
-#define DEBUG_LOG PseudoramiXDebug
-
-Bool noPseudoramiXExtension = FALSE;
-
-extern int
-ProcPanoramiXQueryVersion(ClientPtr client);
-
-static void
-PseudoramiXResetProc(ExtensionEntry *extEntry);
-
-static int
-ProcPseudoramiXQueryVersion(ClientPtr client);
-static int
-ProcPseudoramiXGetState(ClientPtr client);
-static int
-ProcPseudoramiXGetScreenCount(ClientPtr client);
-static int
-ProcPseudoramiXGetScreenSize(ClientPtr client);
-static int
-ProcPseudoramiXIsActive(ClientPtr client);
-static int
-ProcPseudoramiXQueryScreens(ClientPtr client);
-static int
-ProcPseudoramiXDispatch(ClientPtr client);
-
-static int
-SProcPseudoramiXQueryVersion(ClientPtr client);
-static int
-SProcPseudoramiXGetState(ClientPtr client);
-static int
-SProcPseudoramiXGetScreenCount(ClientPtr client);
-static int
-SProcPseudoramiXGetScreenSize(ClientPtr client);
-static int
-SProcPseudoramiXIsActive(ClientPtr client);
-static int
-SProcPseudoramiXQueryScreens(ClientPtr client);
-static int
-SProcPseudoramiXDispatch(ClientPtr client);
-
-typedef struct {
- int x;
- int y;
- int w;
- int h;
-} PseudoramiXScreenRec;
-
-static PseudoramiXScreenRec *pseudoramiXScreens = NULL;
-static int pseudoramiXScreensAllocated = 0;
-static int pseudoramiXNumScreens = 0;
-static unsigned long pseudoramiXGeneration = 0;
-
-static void
-PseudoramiXTrace(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- LogVMessageVerb(X_NONE, 10, format, ap);
- va_end(ap);
-}
-
-static void
-PseudoramiXDebug(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- LogVMessageVerb(X_NONE, 3, format, ap);
- va_end(ap);
-}
-
-// Add a PseudoramiX screen.
-// The rest of the X server will know nothing about this screen.
-// Can be called before or after extension init.
-// Screens must be re-added once per generation.
-void
-PseudoramiXAddScreen(int x, int y, int w, int h)
-{
- PseudoramiXScreenRec *s;
-
- if (noPseudoramiXExtension) return;
-
- if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
- pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
- pseudoramiXScreens = realloc(pseudoramiXScreens,
- pseudoramiXScreensAllocated *
- sizeof(PseudoramiXScreenRec));
- }
-
- DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h);
-
- s = &pseudoramiXScreens[pseudoramiXNumScreens++];
- s->x = x;
- s->y = y;
- s->w = w;
- s->h = h;
-}
-
-// Initialize PseudoramiX.
-// Copied from PanoramiXExtensionInit
-void
-PseudoramiXExtensionInit(void)
-{
- Bool success = FALSE;
- ExtensionEntry *extEntry;
-
- if (noPseudoramiXExtension) return;
-
- TRACE;
-
- /* Even with only one screen we need to enable PseudoramiX to allow
- dynamic screen configuration changes. */
-#if 0
- if (pseudoramiXNumScreens == 1) {
- // Only one screen - disable Xinerama extension.
- noPseudoramiXExtension = TRUE;
- return;
- }
-#endif
-
- if (pseudoramiXGeneration != serverGeneration) {
- extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
- ProcPseudoramiXDispatch,
- SProcPseudoramiXDispatch,
- PseudoramiXResetProc,
- StandardMinorOpcode);
- if (!extEntry) {
- ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n");
- }
- else {
- pseudoramiXGeneration = serverGeneration;
- success = TRUE;
- }
- }
-
- if (!success) {
- ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
- PANORAMIX_PROTOCOL_NAME);
- return;
- }
-}
-
-void
-PseudoramiXResetScreens(void)
-{
- TRACE;
-
- pseudoramiXNumScreens = 0;
-}
-
-static void
-PseudoramiXResetProc(ExtensionEntry *extEntry)
-{
- TRACE;
-
- PseudoramiXResetScreens();
-}
-
-// was PanoramiX
-static int
-ProcPseudoramiXQueryVersion(ClientPtr client)
-{
- TRACE;
-
- return ProcPanoramiXQueryVersion(client);
-}
-
-// was PanoramiX
-static int
-ProcPseudoramiXGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
- WindowPtr pWin;
- xPanoramiXGetStateReply rep;
- register int rc;
-
- TRACE;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !noPseudoramiXExtension;
- rep.window = stuff->window;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.window);
- }
- WriteToClient(client, sizeof(xPanoramiXGetStateReply),&rep);
- return Success;
-}
-
-// was PanoramiX
-static int
-ProcPseudoramiXGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
- WindowPtr pWin;
- xPanoramiXGetScreenCountReply rep;
- register int rc;
-
- TRACE;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.ScreenCount = pseudoramiXNumScreens;
- rep.window = stuff->window;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.window);
- }
- WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply),&rep);
- return Success;
-}
-
-// was PanoramiX
-static int
-ProcPseudoramiXGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
- WindowPtr pWin;
- xPanoramiXGetScreenSizeReply rep;
- register int rc;
-
- TRACE;
-
- if (stuff->screen >= pseudoramiXNumScreens)
- return BadMatch;
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- /* screen dimensions */
- rep.width = pseudoramiXScreens[stuff->screen].w;
- // was screenInfo.screens[stuff->screen]->width;
- rep.height = pseudoramiXScreens[stuff->screen].h;
- // was screenInfo.screens[stuff->screen]->height;
- rep.window = stuff->window;
- rep.screen = stuff->screen;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.width);
- swapl(&rep.height);
- swapl(&rep.window);
- swapl(&rep.screen);
- }
- WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply),&rep);
- return Success;
-}
-
-// was Xinerama
-static int
-ProcPseudoramiXIsActive(ClientPtr client)
-{
- /* REQUEST(xXineramaIsActiveReq); */
- xXineramaIsActiveReply rep;
-
- TRACE;
-
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !noPseudoramiXExtension;
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.state);
- }
- WriteToClient(client, sizeof(xXineramaIsActiveReply),&rep);
- return Success;
-}
-
-// was Xinerama
-static int
-ProcPseudoramiXQueryScreens(ClientPtr client)
-{
- /* REQUEST(xXineramaQueryScreensReq); */
- xXineramaQueryScreensReply rep;
-
- DEBUG_LOG("noPseudoramiXExtension=%d, pseudoramiXNumScreens=%d\n",
- noPseudoramiXExtension,
- pseudoramiXNumScreens);
-
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens;
- rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
- if (client->swapped) {
- swaps(&rep.sequenceNumber);
- swapl(&rep.length);
- swapl(&rep.number);
- }
- WriteToClient(client, sizeof(xXineramaQueryScreensReply),&rep);
-
- if (!noPseudoramiXExtension) {
- xXineramaScreenInfo scratch;
- int i;
-
- for (i = 0; i < pseudoramiXNumScreens; i++) {
- scratch.x_org = pseudoramiXScreens[i].x;
- scratch.y_org = pseudoramiXScreens[i].y;
- scratch.width = pseudoramiXScreens[i].w;
- scratch.height = pseudoramiXScreens[i].h;
-
- if (client->swapped) {
- swaps(&scratch.x_org);
- swaps(&scratch.y_org);
- swaps(&scratch.width);
- swaps(&scratch.height);
- }
- WriteToClient(client, sz_XineramaScreenInfo,&scratch);
- }
- }
-
- return Success;
-}
-
-// was PanoramiX
-static int
-ProcPseudoramiXDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- TRACE;
- switch (stuff->data) {
- case X_PanoramiXQueryVersion:
- return ProcPseudoramiXQueryVersion(client);
-
- case X_PanoramiXGetState:
- return ProcPseudoramiXGetState(client);
-
- case X_PanoramiXGetScreenCount:
- return ProcPseudoramiXGetScreenCount(client);
-
- case X_PanoramiXGetScreenSize:
- return ProcPseudoramiXGetScreenSize(client);
-
- case X_XineramaIsActive:
- return ProcPseudoramiXIsActive(client);
-
- case X_XineramaQueryScreens:
- return ProcPseudoramiXQueryScreens(client);
- }
- return BadRequest;
-}
-
-static int
-SProcPseudoramiXQueryVersion(ClientPtr client)
-{
- REQUEST(xPanoramiXQueryVersionReq);
-
- TRACE;
-
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
- return ProcPseudoramiXQueryVersion(client);
-}
-
-static int
-SProcPseudoramiXGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
-
- TRACE;
-
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- return ProcPseudoramiXGetState(client);
-}
-
-static int
-SProcPseudoramiXGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
-
- TRACE;
-
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- return ProcPseudoramiXGetScreenCount(client);
-}
-
-static int
-SProcPseudoramiXGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
-
- TRACE;
-
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- return ProcPseudoramiXGetScreenSize(client);
-}
-
-static int
-SProcPseudoramiXIsActive(ClientPtr client)
-{
- REQUEST(xXineramaIsActiveReq);
-
- TRACE;
-
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
- return ProcPseudoramiXIsActive(client);
-}
-
-static int
-SProcPseudoramiXQueryScreens(ClientPtr client)
-{
- REQUEST(xXineramaQueryScreensReq);
-
- TRACE;
-
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
- return ProcPseudoramiXQueryScreens(client);
-}
-
-static int
-SProcPseudoramiXDispatch(ClientPtr client)
-{
- REQUEST(xReq);
-
- TRACE;
-
- switch (stuff->data) {
- case X_PanoramiXQueryVersion:
- return SProcPseudoramiXQueryVersion(client);
-
- case X_PanoramiXGetState:
- return SProcPseudoramiXGetState(client);
-
- case X_PanoramiXGetScreenCount:
- return SProcPseudoramiXGetScreenCount(client);
-
- case X_PanoramiXGetScreenSize:
- return SProcPseudoramiXGetScreenSize(client);
-
- case X_XineramaIsActive:
- return SProcPseudoramiXIsActive(client);
-
- case X_XineramaQueryScreens:
- return SProcPseudoramiXQueryScreens(client);
- }
- return BadRequest;
-}
diff --git a/hw/xquartz/pseudoramiX.h b/hw/xquartz/pseudoramiX.h
deleted file mode 100644
index f063919dd..000000000
--- a/hw/xquartz/pseudoramiX.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Minimal implementation of PanoramiX/Xinerama
- */
-
-extern int noPseudoramiXExtension;
-
-void
-PseudoramiXAddScreen(int x, int y, int w, int h);
-void
-PseudoramiXResetScreens(void);
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 37cd8b357..346b7556f 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
@@ -54,6 +52,8 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
HANDLE hToken,
DWORD dwFlags, LPTSTR pszPath);
#endif
+#include "winmonitors.h"
+#include "pseudoramiX/pseudoramiX.h"
#include "glx_extinit.h"
/*
@@ -68,6 +68,8 @@ extern HWND g_hwndClipboard;
extern Bool g_fClipboard;
#endif
+extern Bool noRRXineramaExtension;
+
/*
* Function prototypes
*/
@@ -82,8 +84,6 @@ void
OsVendorVErrorF(const char *pszFormat, va_list va_args);
#endif
-static Bool
- winCheckDisplayNumber(void);
void
winLogCommandLine(int argc, char *argv[]);
@@ -98,6 +98,8 @@ Bool
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
@@ -164,7 +166,7 @@ void XwinExtensionInit(void)
int i;
#ifdef XWIN_GLX_WINDOWS
- if ((g_fNativeGl) && (serverGeneration == 1)) {
+ if (g_fNativeGl) {
/* install the native GL provider */
glxWinPushNativeProvider();
}
@@ -191,6 +193,27 @@ ddxBeforeReset(void)
}
#endif
+int
+main(int argc, char *argv[], char *envp[])
+{
+ int iReturn;
+
+ /* Create & acquire the termination mutex */
+ iReturn = pthread_mutex_init(&g_pmTerminating, NULL);
+ if (iReturn != 0) {
+ ErrorF("ddxMain - pthread_mutex_init () failed: %d\n", iReturn);
+ }
+
+ iReturn = pthread_mutex_lock(&g_pmTerminating);
+ if (iReturn != 0) {
+ ErrorF("ddxMain - pthread_mutex_lock () failed: %d\n", iReturn);
+ }
+
+ winCheckMount();
+
+ return dix_main(argc, argv, envp);
+}
+
/* See Porting Layer Definition - p. 57 */
void
ddxGiveUp(enum ExitCode error)
@@ -209,6 +232,9 @@ ddxGiveUp(enum ExitCode error)
}
#ifdef XWIN_MULTIWINDOW
+ /* Unload libraries for taskbar grouping */
+ winTaskbarDestroy();
+
/* Notify the worker threads we're exiting */
winDeinitMultiWindowWM();
#endif
@@ -245,6 +271,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 */
@@ -258,6 +297,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)
@@ -282,6 +323,9 @@ winCheckMntOpt(const struct mntent *mnt, const char *opt)
return NULL;
}
+/*
+ Check mounts and issue warnings/activate workarounds as needed
+ */
static void
winCheckMount(void)
{
@@ -291,6 +335,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) {
@@ -329,6 +374,11 @@ winCheckMount(void)
binary = FALSE;
else
binary = TRUE;
+
+ if (strcmp(ent->mnt_type, "vfat") == 0)
+ fat = TRUE;
+ else
+ fat = FALSE;
}
if (endmntent(mnt) != 1) {
@@ -338,6 +388,12 @@ winCheckMount(void)
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
@@ -749,6 +805,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");
#ifdef XWIN_MULTIWINDOWEXTWM
@@ -809,7 +868,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");
@@ -842,7 +901,7 @@ winUseMsg(void)
#ifdef XWIN_GLX_WINDOWS
ErrorF("-[no]wgl\n"
- "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
+ "\tEnable the GLX extension to use the native Windows WGL interface for hardware-accelerated OpenGL\n");
#endif
ErrorF("-[no]winkill\n" "\tAlt+F4 exits the X Server.\n");
@@ -901,7 +960,8 @@ InitOutput(ScreenInfo * screenInfo, int argc, char *argv[])
{
int i;
- XwinExtensionInit();
+ if (serverGeneration == 1)
+ XwinExtensionInit();
/* Log the command line */
winLogCommandLine(argc, argv);
@@ -916,14 +976,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())
@@ -955,10 +1007,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) {
/* Initialize the screen */
@@ -967,6 +1027,61 @@ InitOutput(ScreenInfo * screenInfo, int argc, char *argv[])
}
}
+ /*
+ Unless full xinerama has been explicitly enabled, register all native screens with pseudoramiX
+ */
+ if (!noPanoramiXExtension)
+ noPseudoramiXExtension = TRUE;
+
+ if ((g_ScreenInfo[0].fMultipleMonitors) && !noPseudoramiXExtension)
+ {
+ int pass;
+
+ noRRXineramaExtension = TRUE;
+
+ PseudoramiXExtensionInit(argc, argv);
+
+ /* Add primary monitor on pass 0, other monitors on pass 1, to ensure
+ the primary monitor is first in XINERAMA list */
+ for (pass = 0; pass < 2; pass++)
+ {
+ int iMonitor;
+
+ for (iMonitor = 1; ; iMonitor++)
+ {
+ struct GetMonitorInfoData data;
+ QueryMonitor(iMonitor, &data);
+ if (data.bMonitorSpecifiedExists)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(MONITORINFO);
+
+ if (GetMonitorInfo(data.monitorHandle, &mi))
+ {
+ /* pass == 1 XOR primary monitor flags is set */
+ if ((!(pass == 1)) != (!(mi.dwFlags & MONITORINFOF_PRIMARY)))
+ {
+ /*
+ Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+ of the native virtual desktop area
+ */
+ data.monitorOffsetX = data.monitorOffsetX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ data.monitorOffsetY = data.monitorOffsetY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ winDebug ("InitOutput - screen %d added at virtual desktop coordinate (%d,%d) (pseudoramiX) \n",
+ iMonitor-1, data.monitorOffsetX, data.monitorOffsetY);
+
+ PseudoramiXAddScreen(data.monitorOffsetX, data.monitorOffsetY,
+ data.monitorWidth, data.monitorHeight);
+ }
+ }
+ }
+ else
+ break;
+ }
+ }
+ }
+
#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
/* Generate a cookie used by internal clients for authorization */
@@ -975,11 +1090,24 @@ 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
@@ -987,70 +1115,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 4c2f04ef0..33ab6e95c 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -25,6 +25,7 @@ SRCS_MULTIWINDOW = \
winmultiwindowwm.c \
winmultiwindowwndproc.c
DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
+MULTIWINDOW_LIBS = -lshlwapi -lole32
endif
if XWIN_MULTIWINDOWEXTWM
@@ -89,6 +90,7 @@ SRCS = InitInput.c \
winmonitors.c \
winmouse.c \
winmsg.c \
+ winmsgwindow.c \
winmultiwindowclass.c \
winmultiwindowicons.c \
winprefs.c \
@@ -100,6 +102,7 @@ SRCS = InitInput.c \
winshaddd.c \
winshadddnl.c \
winshadgdi.c \
+ wintaskbar.c \
wintrayicon.c \
winvalargs.c \
winwakeup.c \
@@ -119,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 \
@@ -145,8 +149,11 @@ XWin_SOURCES = $(SRCS)
INCLUDES = -I$(top_srcdir)/miext/rootless
+XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la
+XWIN_SYS_LIBS += -ldxguid
+
XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS)
-XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
+XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
XWin_LDFLAGS = -mwindows -static
.rc.o:
diff --git a/hw/xwin/ddraw.h b/hw/xwin/ddraw.h
index 9463049c8..fade7306e 100644
--- a/hw/xwin/ddraw.h
+++ b/hw/xwin/ddraw.h
@@ -3,7 +3,11 @@
#include <winnt.h>
#include <wingdi.h>
+#pragma push_macro("Status")
+#undef Status
+#define Status wStatus
#include <objbase.h>
+#pragma pop_macro("Status")
#if defined(NONAMELESSUNION) && !defined(DUMMYUNIONNAME1)
#define DUMMYUNIONNAME1 u1
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 97b6045b7..664bb5c90 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -86,6 +86,7 @@
#include <winpriv.h>
#include <wgl_ext_api.h>
+#include <winglobals.h>
#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
@@ -341,6 +342,10 @@ swap_method_name(int mthd)
static void
fbConfigsDump(unsigned int n, __GLXconfig * c)
{
+ LogMessage(X_INFO, "%d fbConfigs\n", n);
+
+ if (g_iLogVerbose < 3)
+ return;
ErrorF("%d fbConfigs\n", n);
ErrorF
("pxf vis fb render Ste aux accum MS drawable Group/\n");
@@ -595,11 +600,14 @@ glxWinScreenProbe(ScreenPtr pScreen)
gl_renderer = (const char *) glGetStringWrapperNonstatic(GL_RENDERER);
ErrorF("GL_RENDERER: %s\n", gl_renderer);
gl_extensions = (const char *) glGetStringWrapperNonstatic(GL_EXTENSIONS);
- glxLogExtensions("GL_EXTENSIONS: ", gl_extensions);
wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
if (!wgl_extensions)
wgl_extensions = "";
- glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
+
+ if (g_iLogVerbose >= 3) {
+ glxLogExtensions("GL_EXTENSIONS: ", gl_extensions);
+ glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
+ }
if (strcasecmp(gl_renderer, "GDI Generic") == 0) {
free(screen);
@@ -1835,8 +1843,8 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen)
// get the number of pixelformats
numConfigs =
DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
- GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats",
- numConfigs);
+ LogMessage(X_INFO, "%d pixel formats reported by DescribePixelFormat\n",
+ numConfigs);
/* alloc */
result = malloc(sizeof(GLXWinConfig) * numConfigs);
@@ -2083,9 +2091,9 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen)
return;
}
- GLWIN_DEBUG_MSG
- ("wglGetPixelFormatAttribivARB says %d possible pixel formats",
- numConfigs);
+ LogMessage(X_INFO,
+ "%d pixel formats reported by wglGetPixelFormatAttribivARB\n",
+ numConfigs);
/* alloc */
result = malloc(sizeof(GLXWinConfig) * numConfigs);
diff --git a/hw/xwin/glx/winpriv.c b/hw/xwin/glx/winpriv.c
index 4f6e4ffd5..11612f905 100644
--- a/hw/xwin/glx/winpriv.c
+++ b/hw/xwin/glx/winpriv.c
@@ -14,6 +14,36 @@
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.
@@ -50,8 +80,8 @@ 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 dbadad6f5..cf5324131 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -76,6 +76,9 @@ preceeding \fB\-screen\fP parameter.
.B \-[no]multimonitors or \-[no]multiplemonitors
Create a screen 0 that covers all monitors [the primary monitor] on a system with
multiple monitors.
+Fake XINERAMA data is created describing the individual monitors,
+(This is similar to the 'merged framebuffer' or 'pseudo-xinerama' mode provided by
+some drivers for the xorg X server).
This option is currently enabled by default in \fB\-multiwindow\fP mode.
.TP 8
.B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] "
@@ -121,14 +124,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 +164,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 +222,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/man/XWinrc.man b/hw/xwin/man/XWinrc.man
index 71d8dad23..0f641e92f 100644
--- a/hw/xwin/man/XWinrc.man
+++ b/hw/xwin/man/XWinrc.man
@@ -54,6 +54,35 @@ There are four kinds of instructions: miscellaneous, menu, icon and style.
.SH Miscellaneous instruction
.TP 8
+.B DPI \fIresolution\fP
+Sets the resolution for all screens, in dots per inch. To be used when
+the server cannot determine the screen size(s) from the hardware.
+
+.TP 8
+.B XKBLayout \fIlayout\fP
+.TP 8
+.B XKBModel \fImodel\fP
+.TP 8
+.B XKBOptions \fIoption\fP
+.TP 8
+.B XKBRules \fIrule\fP
+.TP 8
+.B XKBVariant \fIvariant\fp
+These options configure the xkeyboard extension to load a particular
+keyboard map as the X server starts. The behavior is similar to the
+\fIsetxkbmap\fP(1) program.
+
+See the \fIxkeyboard-config\fP(__miscmansuffix__) manual page for a list of
+keyboard configurations.
+
+Alternatively, you can use \fIsetxkbmap\fP(1) program after \fIXWin\fP
+is running.
+
+The default is to select a keyboard configuration matching your current
+layout as reported by \fIWindows\fP, if known, or the default X server
+configuration if no matching keyboard configuration was found.
+
+.TP 8
.B DEBUG \fIString\fP
The \fIString\fP is printed to the XWin log file.
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..11cbeb3f5
--- /dev/null
+++ b/hw/xwin/taskbar.h
@@ -0,0 +1,88 @@
+/*
+ *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>
+
+#ifdef __MINGW64_VERSION_MAJOR
+/* If we are using headers from mingw-w64 project, it provides the PSDK headers this needs ... */
+#include <propkey.h>
+#include <propsys.h>
+#else /* !__MINGW64_VERSION_MAJOR */
+/* ... otherwise, we need to define all this stuff ourselves */
+
+typedef struct _tagpropertykey {
+ GUID fmtid;
+ DWORD pid;
+} PROPERTYKEY;
+
+#define REFPROPERTYKEY const PROPERTYKEY *
+#define REFPROPVARIANT const PROPVARIANT *
+
+#ifdef INTERFACE
+#undef INTERFACE
+#endif
+
+#define INTERFACE IPropertyStore
+DECLARE_INTERFACE_(IPropertyStore, IUnknown)
+{
+ STDMETHOD(QueryInterface) (THIS_ REFIID, PVOID *) PURE;
+ STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG, Release) (THIS) PURE;
+ STDMETHOD(GetCount) (THIS_ DWORD) PURE;
+ STDMETHOD(GetAt) (THIS_ DWORD, PROPERTYKEY) PURE;
+ STDMETHOD(GetValue) (THIS_ REFPROPERTYKEY, PROPVARIANT) PURE;
+ STDMETHOD(SetValue) (THIS_ REFPROPERTYKEY, REFPROPVARIANT) PURE;
+ STDMETHOD(Commit) (THIS) PURE;
+};
+
+#undef INTERFACE
+typedef IPropertyStore *LPPROPERTYSTORE;
+
+DEFINE_GUID(IID_IPropertyStore, 0x886d8eeb, 0x8cf2, 0x4446, 0x8d, 0x02, 0xcd,
+ 0xba, 0x1d, 0xbd, 0xcf, 0x99);
+
+#ifdef INITGUID
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) GUID_EXT const PROPERTYKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
+#else
+#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) GUID_EXT const PROPERTYKEY name
+#endif
+
+DEFINE_PROPERTYKEY(PKEY_AppUserModel_ID, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0,
+ 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 5);
+
+#endif /* !__MINGW64_VERSION_MAJOR */
+
+typedef HRESULT(__stdcall * SHGETPROPERTYSTOREFORWINDOWPROC) (HWND, REFIID,
+ void **);
+typedef HRESULT(__stdcall * PROPVARIANTCLEARPROC) (PROPVARIANT *);
+
+
+#endif
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index 89e2a38c9..35eaf2028 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -1249,6 +1249,8 @@ int
LRESULT CALLBACK
winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK
+winChildWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
#endif
/*
@@ -1413,6 +1415,18 @@ void
winDoRandRScreenSetSize(ScreenPtr pScreen,
CARD16 width,
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 480e3bd48..1d375ca76 100644
--- a/hw/xwin/winblock.c
+++ b/hw/xwin/winblock.c
@@ -42,7 +42,6 @@ winBlockHandler(ScreenPtr pScreen,
#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
winScreenPriv(pScreen);
#endif
- MSG msg;
#ifndef HAS_DEVWINDOWS
struct timeval **tvp = pTimeout;
@@ -51,6 +50,23 @@ winBlockHandler(ScreenPtr pScreen,
(*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)
@@ -68,22 +84,17 @@ winBlockHandler(ScreenPtr pScreen,
if (iReturn != 0) {
ErrorF("winBlockHandler - pthread_mutex_unlock () failed: %d\n",
iReturn);
- goto winBlockHandler_ProcessMessages;
}
-
- winDebug("winBlockHandler - pthread_mutex_unlock () returned\n");
+ else {
+ 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))) {
- DispatchMessage(&msg);
- }
- }
+ /*
+ 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 27eb2f96f..b051832ba 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/winclipboardtextconv.c b/hw/xwin/winclipboardtextconv.c
index 74a351b17..78f7e36de 100644
--- a/hw/xwin/winclipboardtextconv.c
+++ b/hw/xwin/winclipboardtextconv.c
@@ -48,11 +48,14 @@ void
*/
void
-winClipboardDOStoUNIX(char *pszSrc, int iLength)
+winClipboardDOStoUNIX(char *pszData, int iLength)
{
+ char *pszSrc = pszData;
char *pszDest = pszSrc;
char *pszEnd = pszSrc + iLength;
+ winDebug("DOXtoUNIX() - Original data:'%s'\n", pszData);
+
/* Loop until the last character */
while (pszSrc < pszEnd) {
/* Copy the current source character to current destination character */
@@ -68,6 +71,8 @@ winClipboardDOStoUNIX(char *pszSrc, int iLength)
/* Move the terminating null */
*pszDest = '\0';
+
+ winDebug("DOStoUNIX() - Final string:'%s'\n", pszData);
}
/*
@@ -101,8 +106,10 @@ winClipboardUNIXtoDOS(unsigned char **ppszData, int iLength)
}
/* Return if no naked \n's */
- if (iNewlineCount == 0)
+ if (iNewlineCount == 0) {
+ winDebug("UNIXtoDOS () - no conversion necessary\n");
return;
+ }
/* Allocate a new string */
pszDestBegin = pszDest = malloc(iLength + iNewlineCount + 1);
diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c
index f2e8e6d6f..779f3e525 100644
--- a/hw/xwin/winclipboardthread.c
+++ b/hw/xwin/winclipboardthread.c
@@ -76,6 +76,9 @@ static int
static int
winClipboardIOErrorHandler(Display * pDisplay);
+static void
+winClipboardThreadExit(void *arg);
+
/*
* Main thread function
*/
@@ -102,6 +105,8 @@ winClipboardProc(void *pvNotUsed)
char szDisplay[512];
int iSelectError;
+ pthread_cleanup_push(&winClipboardThreadExit, NULL);
+
winDebug("winClipboardProc - Hello\n");
++clipboardRestarts;
@@ -111,16 +116,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);
@@ -140,7 +135,7 @@ 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);
+ goto winClipboardProc_Done;
}
/* Use our generated cookie for authentication */
@@ -157,7 +152,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);
@@ -183,7 +178,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 "
@@ -269,8 +264,10 @@ winClipboardProc(void *pvNotUsed)
winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);
/* Pre-flush Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd))
- return 0;
+ if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
+ ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
+ pthread_exit(NULL);
+ }
/* Signal that the clipboard client has started */
g_fClipboardStarted = TRUE;
@@ -292,6 +289,8 @@ winClipboardProc(void *pvNotUsed)
tvTimeout.tv_usec = 100;
#endif
+ winDebug("winClipboardProc - Waiting in select\n");
+
/* Wait for a Windows event or an X event */
iReturn = select(iMaxDescriptor, /* Highest fds number */
&fdsRead, /* Read mask */
@@ -323,8 +322,13 @@ winClipboardProc(void *pvNotUsed)
break;
}
+ winDebug("winClipboardProc - select returned %d\n", iReturn);
+
/* Branch on which descriptor became active */
if (FD_ISSET(iConnectionNumber, &fdsRead)) {
+ winDebug
+ ("winClipboardProc - X connection ready, pumping X event queue\n");
+
/* Process X events */
/* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd,
@@ -343,6 +347,9 @@ winClipboardProc(void *pvNotUsed)
if (1)
#endif
{
+ winDebug
+ ("winClipboardProc - /dev/windows ready, pumping Windows message queue\n");
+
/* Process Windows messages */
if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
ErrorF("winClipboardProc - "
@@ -351,6 +358,11 @@ winClipboardProc(void *pvNotUsed)
break;
}
}
+
+ if (!(FD_ISSET(iConnectionNumber, &fdsRead)) &&
+ !(FD_ISSET(fdMessageQueue, &fdsRead))) {
+ winDebug("winClipboardProc - Spurious wake\n");
+ }
}
winClipboardProc_Exit:
@@ -435,6 +447,7 @@ winClipboardProc(void *pvNotUsed)
kill(getpid(), SIGTERM);
}
+ pthread_cleanup_pop(0);
return NULL;
}
@@ -461,7 +474,7 @@ winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr)
static int
winClipboardIOErrorHandler(Display * pDisplay)
{
- ErrorF("winClipboardIOErrorHandler!\n\n");
+ ErrorF("winClipboardIOErrorHandler!\n");
if (pthread_equal(pthread_self(), g_winClipboardProcThread)) {
/* Restart at the main entry point */
@@ -473,3 +486,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/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c
index e19f678a7..077b9f0bf 100644
--- a/hw/xwin/winclipboardwndproc.c
+++ b/hw/xwin/winclipboardwndproc.c
@@ -151,6 +151,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static HWND s_hwndNextViewer;
static Bool s_fCBCInitialized;
+#if CYGDEBUG
+ winDebugWin32Message("winClipboardWindowProc", hwnd, message, wParam,
+ lParam);
+#endif
+
/* Branch on message type */
switch (message) {
case WM_DESTROY:
@@ -325,6 +330,29 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
"Clipboard does not contain CF_TEXT nor "
"CF_UNICODETEXT.\n");
+ winDebug("winClipboardWindowProc: %d formats\n",
+ CountClipboardFormats());
+ {
+ unsigned int format = 0;
+
+ do {
+ format = EnumClipboardFormats(format);
+ if (GetLastError() != ERROR_SUCCESS) {
+ winDebug
+ ("winClipboardWindowProc: EnumClipboardFormats failed %x\n",
+ GetLastError());
+ }
+ if (format > 0xc000) {
+ char buff[256];
+
+ GetClipboardFormatName(format, buff, 256);
+ winDebug("winClipboardWindowProc: %d %s\n", format,
+ buff);
+ }
+ else if (format > 0)
+ winDebug("winClipboardWindowProc: %d\n", format);
+ } while (format != 0);
+ }
/*
* We need to make sure that the X Server has processed
* previous XSetSelectionOwner messages.
@@ -337,24 +365,24 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
iReturn = XGetSelectionOwner(pDisplay, XA_PRIMARY);
if (iReturn == g_iClipboardWindow) {
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "PRIMARY selection is owned by us.\n");
+ "PRIMARY selection is owned by us, releasing\n");
XSetSelectionOwner(pDisplay, XA_PRIMARY, None, CurrentTime);
}
else if (BadWindow == iReturn || BadAtom == iReturn)
winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelection failed for PRIMARY: %d\n",
+ "XGetSelectionOwner failed for PRIMARY: %d\n",
iReturn);
/* Release CLIPBOARD selection if owned */
iReturn = XGetSelectionOwner(pDisplay, atomClipboard);
if (iReturn == g_iClipboardWindow) {
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "CLIPBOARD selection is owned by us.\n");
+ "CLIPBOARD selection is owned by us, releasing\n");
XSetSelectionOwner(pDisplay, atomClipboard, None, CurrentTime);
}
else if (BadWindow == iReturn || BadAtom == iReturn)
winErrorFVerb(1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - "
- "XGetSelection failed for CLIPBOARD: %d\n",
+ "XGetSelectionOwner failed for CLIPBOARD: %d\n",
iReturn);
winDebug("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
@@ -424,7 +452,11 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Window iWindow = g_iClipboardWindow;
Bool fConvertToUnicode;
- winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
+ if (message == WM_RENDERALLFORMATS)
+ winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n");
+ else
+ winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
+ wParam);
/* Flag whether to convert to Unicode or not */
if (message == WM_RENDERALLFORMATS)
diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c
index 1118f4ff8..c4a258100 100644
--- a/hw/xwin/winclipboardwrappers.c
+++ b/hw/xwin/winclipboardwrappers.c
@@ -199,7 +199,9 @@ winProcSetSelectionOwner(ClientPtr client)
REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
- winDebug("winProcSetSelectionOwner - Hello.\n");
+ winDebug
+ ("winProcSetSelectionOwner - Hello. atom 0x%08x window XID 0x%08x \n",
+ stuff->selection, stuff->window);
/* Watch for server reset */
if (s_ulServerGeneration != serverGeneration) {
@@ -250,8 +252,9 @@ winProcSetSelectionOwner(ClientPtr client)
/* Save new selection owner or None */
s_iOwners[CLIP_OWN_PRIMARY] = stuff->window;
- winDebug("winProcSetSelectionOwner - PRIMARY - Now owned by: %d\n",
- stuff->window);
+ winDebug
+ ("winProcSetSelectionOwner - PRIMARY - Now owned by XID 0x%08x\n",
+ stuff->window);
}
else if (MakeAtom("CLIPBOARD", 9, TRUE) == stuff->selection) {
/* Look for owned -> not owned transition */
@@ -271,8 +274,9 @@ winProcSetSelectionOwner(ClientPtr client)
/* Save new selection owner or None */
s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window;
- winDebug("winProcSetSelectionOwner - CLIPBOARD - Now owned by: %d\n",
- stuff->window);
+ winDebug
+ ("winProcSetSelectionOwner - CLIPBOARD - Now owned by XID 0x%08x\n",
+ stuff->window);
}
else
diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c
index ce533c59f..32b58540f 100644
--- a/hw/xwin/winclipboardxevents.c
+++ b/hw/xwin/winclipboardxevents.c
@@ -122,6 +122,7 @@ winClipboardFlushXEvents(HWND hwnd,
atomUTF8String,
XA_STRING
};
+ winDebug("SelectionRequest - populating targets\n");
/* Try to change the property */
iReturn = XChangeProperty(pDisplay,
@@ -165,6 +166,24 @@ winClipboardFlushXEvents(HWND hwnd,
break;
}
+ /* Close clipboard if we have it open already */
+ if (GetOpenClipboardWindow() == hwnd) {
+ CloseClipboard();
+ }
+
+ /* Access the clipboard */
+ if (!OpenClipboard(hwnd)) {
+ ErrorF("winClipboardFlushXEvents - SelectionRequest - "
+ "OpenClipboard () failed: %08lx\n", GetLastError());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Indicate that clipboard was opened */
+ fCloseClipboard = TRUE;
+
/* Check that clipboard format is available */
if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
static int count; /* Hack to stop acroread spamming the log */
@@ -192,24 +211,6 @@ winClipboardFlushXEvents(HWND hwnd,
goto winClipboardFlushXEvents_SelectionRequest_Done;
}
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow() == hwnd) {
- CloseClipboard();
- }
-
- /* Access the clipboard */
- if (!OpenClipboard(hwnd)) {
- ErrorF("winClipboardFlushXEvents - SelectionRequest - "
- "OpenClipboard () failed: %08lx\n", GetLastError());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Indicate that clipboard was opened */
- fCloseClipboard = TRUE;
-
/* Setup the string style */
if (event.xselectionrequest.target == XA_STRING)
xiccesStyle = XStringStyle;
@@ -367,6 +368,7 @@ winClipboardFlushXEvents(HWND hwnd,
* client when we abort.
*/
if (fAbort) {
+ winDebug("SelectionRequest - aborting\n");
/* Setup selection notify event */
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
@@ -463,6 +465,23 @@ winClipboardFlushXEvents(HWND hwnd,
}
}
+ case SelectionClear:
+ winDebug("SelectionClear - doing nothing\n");
+ break;
+
+ case PropertyNotify:
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName(pDisplay, event.xproperty.atom);
+ winDebug("winClipboardFlushXEvents - PropertyNotify - ATOM: %s\n",
+ pszAtomName);
+ XFree(pszAtomName);
+ }
+
+ if (event.xproperty.atom != atomLocalProperty)
+ break;
+
/* Retrieve the size of the stored data */
iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, 0, /* Don't get data, just size */
False,
@@ -472,12 +491,12 @@ winClipboardFlushXEvents(HWND hwnd,
&xtpText.nitems,
&ulReturnBytesLeft, &xtpText.value);
if (iReturn != Success) {
- ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ ErrorF("winClipboardFlushXEvents - PropertyNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
break;
}
- winDebug("SelectionNotify - returned data %d left %d\n",
+ winDebug("PropertyNotify - returned data %d left %d\n",
xtpText.nitems, ulReturnBytesLeft);
/* Request the selection data */
@@ -493,7 +512,7 @@ winClipboardFlushXEvents(HWND hwnd,
&xtpText.nitems,
&ulReturnBytesLeft, &xtpText.value);
if (iReturn != Success) {
- ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ ErrorF("winClipboardFlushXEvents - PropertyNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
break;
}
@@ -501,10 +520,11 @@ winClipboardFlushXEvents(HWND hwnd,
{
char *pszAtomName = NULL;
- winDebug("SelectionNotify - returned data %d left %d\n",
+ winDebug("PropertyNotify - returned data %d left %d\n",
xtpText.nitems, ulReturnBytesLeft);
pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
- winDebug("Notify atom name %s\n", pszAtomName);
+ winDebug("PropertyNotify - encoding atom name %s\n",
+ pszAtomName);
XFree(pszAtomName);
pszAtomName = NULL;
}
@@ -536,14 +556,14 @@ winClipboardFlushXEvents(HWND hwnd,
}
}
else {
- ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ ErrorF("winClipboardFlushXEvents - PropertyNotify - "
"X*TextPropertyToTextList list_return is NULL.\n");
pszReturnData = malloc(1);
pszReturnData[0] = '\0';
}
}
else {
- ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ ErrorF("winClipboardFlushXEvents - PropertyNotify - "
"X*TextPropertyToTextList returned: ");
switch (iReturn) {
case XNoMemory:
@@ -584,12 +604,12 @@ winClipboardFlushXEvents(HWND hwnd,
pwszUnicodeStr
= (wchar_t *) malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
if (!pwszUnicodeStr) {
- ErrorF("winClipboardFlushXEvents - SelectionNotify "
+ ErrorF("winClipboardFlushXEvents - PropertyNotify "
"malloc failed for pwszUnicodeStr, aborting.\n");
/* Abort */
fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
+ goto winClipboardFlushXEvents_PropertyNotify_Done;
}
/* Do the actual conversion */
@@ -614,12 +634,11 @@ winClipboardFlushXEvents(HWND hwnd,
/* Check that global memory was allocated */
if (!hGlobal) {
- ErrorF("winClipboardFlushXEvents - SelectionNotify "
+ ErrorF("winClipboardFlushXEvents - PropertyNotify "
"GlobalAlloc failed, aborting: %ld\n", GetLastError());
-
/* Abort */
fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
+ goto winClipboardFlushXEvents_PropertyNotify_Done;
}
/* Obtain a pointer to the global memory */
@@ -630,7 +649,7 @@ winClipboardFlushXEvents(HWND hwnd,
/* Abort */
fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
+ goto winClipboardFlushXEvents_PropertyNotify_Done;
}
/* Copy the returned string into the global memory */
@@ -664,7 +683,7 @@ winClipboardFlushXEvents(HWND hwnd,
* Windows after the call to SetClipboardData ().
*/
- winClipboardFlushXEvents_SelectionNotify_Done:
+ winClipboardFlushXEvents_PropertyNotify_Done:
/* Free allocated resources */
if (ppszTextList)
XFreeStringList(ppszTextList);
@@ -683,13 +702,6 @@ winClipboardFlushXEvents(HWND hwnd,
}
return WIN_XEVENTS_NOTIFY;
- case SelectionClear:
- winDebug("SelectionClear - doing nothing\n");
- break;
-
- case PropertyNotify:
- break;
-
case MappingNotify:
break;
diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index 313320f1a..8e6003993 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -70,6 +70,7 @@ WinCmdlineRec g_cmdline = {
#ifdef XWIN_XF86CONFIG
NULL, /* keyboard */
#endif
+ FALSE, /* customDPI */
NULL, /* xkbRules */
NULL, /* xkbModel */
NULL, /* xkbLayout */
diff --git a/hw/xwin/winconfig.h b/hw/xwin/winconfig.h
index 94571ff71..4f41a62ad 100644
--- a/hw/xwin/winconfig.h
+++ b/hw/xwin/winconfig.h
@@ -160,6 +160,7 @@ typedef struct {
#ifdef XWIN_XF86CONFIG
char *keyboard;
#endif
+ Bool customDPI;
char *xkbRules;
char *xkbModel;
char *xkbLayout;
diff --git a/hw/xwin/windisplay.c b/hw/xwin/windisplay.c
new file mode 100644
index 000000000..9fc4dac68
--- /dev/null
+++ b/hw/xwin/windisplay.c
@@ -0,0 +1,52 @@
+/*
+ * 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 67489598b..b2007d751 100644
--- a/hw/xwin/winengine.c
+++ b/hw/xwin/winengine.c
@@ -92,7 +92,7 @@ winDetectSupportedEngines(void)
else {
/* We have DirectDraw */
winErrorFVerb(2,
- "winDetectSupportedEngines - DirectDraw installed\n");
+ "winDetectSupportedEngines - DirectDraw installed, allowing ShadowDD\n");
g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD;
#ifdef XWIN_PRIMARYFB
@@ -100,7 +100,7 @@ winDetectSupportedEngines(void)
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD;
winErrorFVerb(2,
- "winDetectSupportedEngines - Allowing PrimaryDD\n");
+ "winDetectSupportedEngines - Windows NT, allowing PrimaryDD\n");
}
#endif
}
@@ -112,7 +112,7 @@ winDetectSupportedEngines(void)
if (SUCCEEDED(ddrval)) {
/* We have DirectDraw4 */
winErrorFVerb(2,
- "winDetectSupportedEngines - DirectDraw4 installed\n");
+ "winDetectSupportedEngines - DirectDraw4 installed, allowing ShadowDDNL\n");
g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL;
}
diff --git a/hw/xwin/winerror.c b/hw/xwin/winerror.c
index 56c1e34e7..2b4c430c1 100644
--- a/hw/xwin/winerror.c
+++ b/hw/xwin/winerror.c
@@ -52,6 +52,16 @@ 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;
+ }
+ }
+
/* Print the error message to a log file, could be stderr */
LogVWrite(0, pszFormat, va_args);
@@ -63,15 +73,16 @@ OsVendorVErrorF(const char *pszFormat, va_list va_args)
#endif
/*
- * os/util.c/FatalError () calls our vendor ErrorF, so the message
- * from a FatalError will be logged. Thus, the message for the
- * fatal error is not passed to this function.
+ * os/log.c:FatalError () calls our vendor ErrorF, so the message
+ * from a FatalError will be logged.
*
* Attempt to do last-ditch, safe, important cleanup here.
*/
void
OsVendorFatalError(const char *f, va_list args)
{
+ char errormsg[1024] = "";
+
/* Don't give duplicate warning if UseMsg was called */
if (g_fSilentFatalError)
return;
@@ -82,9 +93,28 @@ OsVendorFatalError(const char *f, va_list args)
}
LogClose(EXIT_ERR_ABORT);
- winMessageBoxF("A fatal error has occurred and " PROJECT_NAME
- " will now exit.\n" "Please open %s for more information.\n",
- MB_ICONERROR, (g_pszLogFile ? g_pszLogFile : "the logfile"));
+ /* Format the error message */
+ vsnprintf(errormsg, sizeof(errormsg), f, args);
+
+ /*
+ Sometimes the error message needs a bit of cosmetic cleaning
+ up for use in a dialog box...
+ */
+ {
+ char *s;
+
+ while ((s = strstr(errormsg, "\n\t")) != NULL) {
+ s[0] = ' ';
+ s[1] = '\n';
+ }
+ }
+
+ winMessageBoxF("A fatal error has occurred and " PROJECT_NAME " will now exit.\n\n"
+ "%s\n\n"
+ "Please open %s for more information.\n",
+ MB_ICONERROR,
+ errormsg,
+ (g_pszLogFile ? g_pszLogFile : "the logfile"));
}
/*
diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c
index 4953bd0cf..fd6c1b490 100644
--- a/hw/xwin/winglobals.c
+++ b/hw/xwin/winglobals.c
@@ -77,7 +77,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 2edf9571e..699f28246 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -48,6 +48,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;
@@ -86,4 +87,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 2ffb9a943..bfb1407b4 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -40,6 +40,7 @@
#include "winmsg.h"
#include "xkbsrv.h"
+#include "dixgrabs.h"
static Bool g_winKeyState[NUM_KEYCODES];
@@ -265,6 +266,30 @@ 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)) {
@@ -502,3 +527,34 @@ 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/winmsgwindow.c b/hw/xwin/winmsgwindow.c
new file mode 100644
index 000000000..8067c693c
--- /dev/null
+++ b/hw/xwin/winmsgwindow.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) Jon TURNEY 2011
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "win.h"
+
+/*
+ * This is the messaging window, a hidden top-level window. We never do anything
+ * with it, but other programs may send messages to it.
+ */
+
+/*
+ * winMsgWindowProc - Window procedure for msg window
+ */
+
+static
+LRESULT CALLBACK
+winMsgWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+#if CYGDEBUG
+ winDebugWin32Message("winMsgWindowProc", hwnd, message, wParam, lParam);
+#endif
+
+ switch (message) {
+ case WM_ENDSESSION:
+ if (!wParam)
+ return 0; /* shutdown is being cancelled */
+
+ /*
+ Send a WM_GIVEUP message to the X server thread so it wakes up if
+ blocked in select(), performs GiveUp(), and then notices that GiveUp()
+ has set the DE_TERMINATE flag so exits the msg dispatch loop.
+ */
+ {
+ ScreenPtr pScreen = screenInfo.screens[0];
+
+ winScreenPriv(pScreen);
+ PostMessage(pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
+ }
+
+ /*
+ This process will be terminated by the system almost immediately
+ after the last thread with a message queue returns from processing
+ WM_ENDSESSION, so we cannot rely on any code executing after this
+ message is processed and need to wait here until ddxGiveUp() is called
+ and releases the termination mutex to guarantee that the lock file and
+ unix domain sockets have been removed
+
+ ofc, Microsoft doesn't document this under WM_ENDSESSION, you are supposed
+ to read the source of CRSS to find out how it works :-)
+
+ http://blogs.msdn.com/b/michen/archive/2008/04/04/application-termination-when-user-logs-off.aspx
+ */
+ {
+ int iReturn = pthread_mutex_lock(&g_pmTerminating);
+
+ if (iReturn != 0) {
+ ErrorF("winMsgWindowProc - pthread_mutex_lock () failed: %d\n",
+ iReturn);
+ }
+ winDebug
+ ("winMsgWindowProc - WM_ENDSESSION termination lock acquired\n");
+ }
+
+ return 0;
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+static HWND
+winCreateMsgWindow(void)
+{
+ HWND hwndMsg;
+ wATOM winClass;
+
+ // register window class
+ {
+ WNDCLASSEX wcx;
+
+ wcx.cbSize = sizeof(WNDCLASSEX);
+ wcx.style = CS_HREDRAW | CS_VREDRAW;
+ wcx.lpfnWndProc = winMsgWindowProc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = 0;
+ wcx.hInstance = g_hInstance;
+ wcx.hIcon = NULL;
+ wcx.hCursor = 0;
+ wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WINDOW_CLASS_X_MSG;
+ wcx.hIconSm = NULL;
+ winClass = RegisterClassEx(&wcx);
+ }
+
+ // Create the msg window.
+ hwndMsg = CreateWindowEx(0, // no extended styles
+ WINDOW_CLASS_X_MSG, // class name
+ "XWin Msg Window", // window name
+ WS_OVERLAPPEDWINDOW, // overlapped window
+ CW_USEDEFAULT, // default horizontal position
+ CW_USEDEFAULT, // default vertical position
+ CW_USEDEFAULT, // default width
+ CW_USEDEFAULT, // default height
+ (HWND) NULL, // no parent or owner window
+ (HMENU) NULL, // class menu used
+ GetModuleHandle(NULL), // instance handle
+ NULL); // no window creation data
+
+ if (!hwndMsg) {
+ ErrorF("winCreateMsgWindow - Create msg window failed\n");
+ return NULL;
+ }
+
+ winDebug("winCreateMsgWindow - Created msg window hwnd 0x%x\n", hwndMsg);
+
+ return hwndMsg;
+}
+
+static void *
+winMsgWindowThreadProc(void *arg)
+{
+ HWND hwndMsg;
+
+ winDebug("winMsgWindowThreadProc - Hello\n");
+
+ hwndMsg = winCreateMsgWindow();
+ if (hwndMsg) {
+ MSG msg;
+
+ /* Pump the msg window message queue */
+ while (GetMessage(&msg, hwndMsg, 0, 0) > 0) {
+#if CYGDEBUG
+ winDebugWin32Message("winMsgWindowThread", msg.hwnd, msg.message,
+ msg.wParam, msg.lParam);
+#endif
+ DispatchMessage(&msg);
+ }
+ }
+
+ winDebug("winMsgWindowThreadProc - Exit\n");
+
+ return NULL;
+}
+
+Bool
+winCreateMsgWindowThread(void)
+{
+ pthread_t ptMsgWindowThreadProc;
+
+ /* Spawn a thread for the msg window */
+ if (pthread_create(&ptMsgWindowThreadProc,
+ NULL, winMsgWindowThreadProc, NULL)) {
+ /* Bail if thread creation failed */
+ ErrorF("winCreateMsgWindow - pthread_create failed.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/hw/xwin/winmultiwindowclass.c b/hw/xwin/winmultiwindowclass.c
index 1af104df9..9fc1be2a4 100644
--- a/hw/xwin/winmultiwindowclass.c
+++ b/hw/xwin/winmultiwindowclass.c
@@ -68,7 +68,7 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
while (prop) {
if (prop->propertyName == XA_WM_CLASS
&& prop->type == XA_STRING && prop->format == 8 && prop->data) {
- len_name = strlen((char *) prop->data);
+ len_name = strnlen((char *) prop->data, prop->size);
(*res_name) = malloc(len_name + 1);
@@ -77,13 +77,17 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
return 0;
}
- /* Add one to len_name to allow copying of trailing 0 */
- strncpy((*res_name), prop->data, len_name + 1);
+ /* Copy name and ensure null terminated */
+ memcpy((*res_name), prop->data, len_name);
+ (*res_name)[len_name] = '\0';
- if (len_name == prop->size)
- len_name--;
-
- len_class = strlen(((char *) prop->data) + 1 + len_name);
+ /* Compute length of class name, it could be that it is not null terminated */
+ if (len_name < prop->size - 1) {
+ len_class = strnlen(((char *) prop->data) + 1 + len_name, prop->size - 1 - len_name);
+ }
+ else {
+ len_class = 0;
+ }
(*res_class) = malloc(len_class + 1);
@@ -95,7 +99,9 @@ winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
return 0;
}
- strcpy((*res_class), ((char *) prop->data) + 1 + len_name);
+ /* Copy class name and ensure null terminated */
+ memcpy((*res_class), ((char *) prop->data) + 1 + len_name, len_class);
+ (*res_class)[len_class] = '\0';
return 1;
}
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index c0c7db2b7..66b0c1ae4 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -55,11 +55,27 @@ static void
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) {
@@ -83,11 +99,40 @@ winInitMultiWindowClass(void)
wcx.hIconSm = hIconSmall;
#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) {
+ HICON hIcon, hIconSmall;
+
+ /* Load the default icons */
+ winSelectIcons(&hIcon, &hIconSmall);
+
+ /* 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 = hIcon;
+ wcx.hCursor = 0;
+ wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WINDOW_CLASS_X_CHILD;
+ wcx.hIconSm = hIconSmall;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF("winInitMultiWindowClass - Creating class: %s\n",
+ WINDOW_CLASS_X_CHILD);
+#endif
+
+ atomXWinChildClass = RegisterClassEx(&wcx);
+ }
}
/*
@@ -202,6 +247,29 @@ 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);
@@ -470,12 +538,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;
@@ -513,8 +577,8 @@ 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)) {
if (pDaddy) {
@@ -534,7 +598,11 @@ 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;
@@ -572,11 +640,14 @@ winCreateWindowsWindow(WindowPtr pWin)
GetModuleHandle(NULL), /* Instance handle */
pWin); /* ScreenPrivates */
if (hWnd == NULL) {
- ErrorF("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
- (int) GetLastError());
+ ErrorF
+ ("winCreateWindowsTopLevelWindow - CreateWindowExA () failed: %d\n",
+ (int) GetLastError());
}
pWinPriv->hWnd = hWnd;
+ winDebug("winCreateWindowsTopLevelWindow - hwnd 0x%08x\n", hWnd);
+
/* Change style back to popup, already placed... */
SetWindowLongPtr(hWnd, GWL_STYLE,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
@@ -602,6 +673,107 @@ 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);
+
+ /* 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;
/*
@@ -617,6 +789,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);
@@ -631,21 +804,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)) {
if (g_hDlgDepthChange == 0 || !IsDialogMessage(g_hDlgDepthChange, &msg)) {
@@ -667,29 +839,58 @@ 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);
+ /* Ignore the root window */
+ if (pWin->parent == NULL)
+ return;
+
+ /* 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);
}
- /* Display the window without activating it */
- if (pWin->drawable.class != InputOnly)
- ShowWindow(pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+ /* 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);
+ /* Send first paint message */
+ UpdateWindow(pWinPriv->hWnd);
+ }
}
- else if (hWnd != NULL) {
- /* Destroy the Windows window if its parents are destroyed */
+ else if (pWinPriv->hWnd != NULL) {
+ /* If it's been reparented to an unmapped window when previously mapped, destroy the Windows window */
winDestroyWindowsWindow(pWin);
assert(pWinPriv->hWnd == NULL);
}
@@ -929,6 +1130,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
ErrorF("\timmediately return because the window is iconized\n");
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index ffb7c2d0f..b4bd71f62 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -30,6 +30,10 @@
* Colin Harrison
*/
+#ifndef WINVER
+#define WINVER 0x0500
+#endif
+
/* X headers */
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
@@ -48,7 +52,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 +65,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>
@@ -135,7 +146,6 @@ typedef struct _XMsgProcArgRec {
* References to external symbols
*/
-extern char *display;
extern void ErrorF(const char * /*f */ , ...);
/*
@@ -175,6 +185,9 @@ static int
static int
winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay);
+static void
+winMultiWindowThreadExit(void *arg);
+
static int
winRedirectErrorHandler(Display * pDisplay, XErrorEvent * pErr);
@@ -192,10 +205,13 @@ CheckAnotherWindowManager(Display * pDisplay, DWORD dwScreen,
Bool fAllowOtherWM);
static void
+ winApplyUrgency(Display * pDisplay, Window iWindow, HWND hWnd);
+
+static void
winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle);
void
- winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle);
+ winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
/*
* Local globals
@@ -210,6 +226,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
@@ -438,7 +458,10 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
{
int nResult;
XTextProperty xtpWindowName;
+ XTextProperty xtpClientMachine;
char *pszWindowName;
+ char *pszClientMachine;
+ char hostname[HOST_NAME_MAX + 1];
#if CYGMULTIWINDOW_DEBUG
ErrorF("GetWindowName\n");
@@ -458,6 +481,40 @@ GetWindowName(Display * pDisplay, Window iWin, char **ppWindowName)
pszWindowName = Xutf8TextPropertyToString(pDisplay, &xtpWindowName);
XFree(xtpWindowName.value);
+
+ 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;
}
@@ -526,7 +583,6 @@ getHwnd(WMInfoPtr pWMInfo, Window iWindow)
static void
UpdateName(WMInfoPtr pWMInfo, Window iWindow)
{
- wchar_t *pszName;
HWND hWnd;
XWindowAttributes attr;
@@ -600,6 +656,48 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
}
+/*
+ * Updates the style of a HWND according to its X style properties
+ */
+
+static void
+UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
+{
+ HWND hWnd;
+ HWND zstyle = HWND_NOTOPMOST;
+ UINT flags;
+ Bool onTaskbar;
+
+ hWnd = getHwnd(pWMInfo, iWindow);
+ if (!hWnd)
+ return;
+
+ /* Determine the Window style, which determines borders and clipping region... */
+ winApplyHints(pWMInfo->pDisplay, iWindow, hWnd, &zstyle);
+ winUpdateWindowPosition(hWnd, &zstyle);
+
+ /* Apply the updated window style, without changing it's show or activation state */
+ flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+ if (zstyle == HWND_NOTOPMOST)
+ flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
+ SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags);
+
+ /*
+ Use the WS_EX_TOOLWINDOW style to remove window from Alt-Tab window switcher
+
+ According to MSDN, this is supposed to remove the window from the taskbar as well,
+ if we SW_HIDE before changing the style followed by SW_SHOW afterwards.
+
+ But that doesn't seem to work reliably, so also use iTaskbarList interface to
+ tell the taskbar to show or hide this window.
+ */
+ onTaskbar = GetWindowLongPtr(hWnd, GWL_EXSTYLE) & WS_EX_APPWINDOW;
+ wintaskbar(hWnd, onTaskbar);
+
+ /* Check urgency hint */
+ winApplyUrgency(pWMInfo->pDisplay, iWindow, hWnd);
+}
+
#if 0
/*
* Fix up any differences between the X11 and Win32 window stacks
@@ -651,6 +749,8 @@ winMultiWindowWMProc(void *pArg)
WMProcArgPtr pProcArg = (WMProcArgPtr) pArg;
WMInfoPtr pWMInfo = pProcArg->pWMInfo;
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
/* Initialize the Window Manager */
winInitMultiWindowWM(pWMInfo, pProcArg);
@@ -747,13 +847,18 @@ winMultiWindowWMProc(void *pArg)
(unsigned char *) &(pNode->msg.hwndWindow), 1);
UpdateName(pWMInfo, pNode->msg.iWindow);
UpdateIcon(pWMInfo, pNode->msg.iWindow);
- {
- HWND zstyle = HWND_NOTOPMOST;
+ UpdateStyle(pWMInfo, pNode->msg.iWindow);
- winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
- pNode->msg.hwndWindow, &zstyle);
- winUpdateWindowPosition(pNode->msg.hwndWindow, TRUE, &zstyle);
+ /* Reshape */
+ {
+ WindowPtr pWin =
+ GetProp(pNode->msg.hwndWindow, WIN_WINDOW_PROP);
+ if (pWin) {
+ winReshapeMultiWindow(pWin);
+ winUpdateRgnMultiWindow(pWin);
+ }
}
+
break;
case WM_WM_UNMAP:
@@ -812,6 +917,19 @@ winMultiWindowWMProc(void *pArg)
UpdateIcon(pWMInfo, pNode->msg.iWindow);
break;
+ case WM_WM_HINTS_EVENT:
+ {
+ XWindowAttributes attr;
+
+ /* Don't do anything if this is an override-redirect window */
+ XGetWindowAttributes (pWMInfo->pDisplay, pNode->msg.iWindow, &attr);
+ if (attr.override_redirect)
+ break;
+
+ UpdateStyle(pWMInfo, pNode->msg.iWindow);
+ }
+ break;
+
case WM_WM_CHANGE_STATE:
/* Minimize the window in Windows */
winMinimizeWindow(pNode->msg.iWindow);
@@ -842,6 +960,9 @@ winMultiWindowWMProc(void *pArg)
#if CYGMULTIWINDOW_DEBUG
ErrorF("-winMultiWindowWMProc ()\n");
#endif
+
+ pthread_cleanup_pop(0);
+
return NULL;
}
@@ -861,9 +982,12 @@ winMultiWindowXMsgProc(void *pArg)
Atom atmWmHints;
Atom atmWmChange;
Atom atmNetWmIcon;
+ Atom atmWindowState, atmMotifWmHints, atmWindowType, atmNormalHints;
int iReturn;
XIconSize *xis;
+ pthread_cleanup_push(&winMultiWindowThreadExit, NULL);
+
winDebug("winMultiWindowXMsgProc - Hello\n");
/* Check that argument pointer is not invalid */
@@ -884,17 +1008,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);
@@ -922,8 +1035,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);
@@ -987,6 +1099,10 @@ winMultiWindowXMsgProc(void *pArg)
atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
+ atmWindowState = XInternAtom(pProcArg->pDisplay, "_NET_WM_STATE", False);
+ atmMotifWmHints = XInternAtom(pProcArg->pDisplay, "_MOTIF_WM_HINTS", False);
+ atmWindowType = XInternAtom(pProcArg->pDisplay, "_NET_WM_WINDOW_TYPE", False);
+ atmNormalHints = XInternAtom(pProcArg->pDisplay, "WM_NORMAL_HINTS", False);
/*
iiimxcf had a bug until 2009-04-27, assuming that the
@@ -1115,6 +1231,10 @@ winMultiWindowXMsgProc(void *pArg)
}
}
else if (event.type == PropertyNotify) {
+ char *atomName =
+ XGetAtomName(pProcArg->pDisplay, event.xproperty.atom);
+ winDebug("winMultiWindowXMsgProc: PropertyNotify %s\n", atomName);
+ XFree(atomName);
if (event.xproperty.atom == atmWmName) {
memset(&msg, 0, sizeof(msg));
@@ -1124,14 +1244,34 @@ winMultiWindowXMsgProc(void *pArg)
/* 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;
+ else {
+ /*
+ Several properties are considered for WM hints, check if this property change affects any of them...
+ (this list needs to be kept in sync with winApplyHints())
+ */
+ if ((event.xproperty.atom == atmWmHints) ||
+ (event.xproperty.atom == atmWindowState) ||
+ (event.xproperty.atom == atmMotifWmHints) ||
+ (event.xproperty.atom == atmWindowType) ||
+ (event.xproperty.atom == atmNormalHints)) {
+ 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);
+ /* Not an else as WM_HINTS affects both style and icon */
+ 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
@@ -1149,7 +1289,7 @@ winMultiWindowXMsgProc(void *pArg)
}
XCloseDisplay(pProcArg->pDisplay);
- pthread_exit(NULL);
+ pthread_cleanup_pop(0);
return NULL;
}
@@ -1255,17 +1395,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);
@@ -1293,8 +1422,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);
@@ -1397,7 +1525,7 @@ winMultiWindowWMErrorHandler(Display * pDisplay, XErrorEvent * pErr)
static int
winMultiWindowWMIOErrorHandler(Display * pDisplay)
{
- ErrorF("winMultiWindowWMIOErrorHandler!\n\n");
+ ErrorF("winMultiWindowWMIOErrorHandler!\n");
if (pthread_equal(pthread_self(), g_winMultiWindowWMThread)) {
if (g_shutdown)
@@ -1437,7 +1565,7 @@ winMultiWindowXMsgProcErrorHandler(Display * pDisplay, XErrorEvent * pErr)
static int
winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay)
{
- ErrorF("winMultiWindowXMsgProcIOErrorHandler!\n\n");
+ ErrorF("winMultiWindowXMsgProcIOErrorHandler!\n");
if (pthread_equal(pthread_self(), g_winMultiWindowXMsgProcThread)) {
/* Restart at the main entry point */
@@ -1451,6 +1579,17 @@ winMultiWindowXMsgProcIOErrorHandler(Display * pDisplay)
}
/*
+ * 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
*/
@@ -1505,6 +1644,40 @@ winDeinitMultiWindowWM(void)
g_shutdown = TRUE;
}
+static void
+winApplyUrgency(Display * pDisplay, Window iWindow, HWND hWnd)
+{
+ XWMHints *hints = XGetWMHints(pDisplay, iWindow);
+
+ if (hints) {
+ FLASHWINFO fwi;
+
+ fwi.cbSize = sizeof(FLASHWINFO);
+ fwi.hwnd = hWnd;
+
+ winDebug("winApplyUrgency: window 0x%08x has urgency hint %s\n",
+ iWindow, (hints->flags & XUrgencyHint) ? "on" : "off");
+
+ if (hints->flags & XUrgencyHint) {
+ DWORD count = 3;
+
+ SystemParametersInfo(SPI_GETFOREGROUNDFLASHCOUNT, 0, &count, 0);
+ fwi.dwFlags = FLASHW_TRAY;
+ fwi.uCount = count;
+ fwi.dwTimeout = 0;
+ }
+ else {
+ fwi.dwFlags = FLASHW_STOP;
+ fwi.uCount = 0;
+ fwi.dwTimeout = 0;
+ }
+
+ FlashWindowEx(&fwi);
+
+ XFree(hints);
+ }
+}
+
/* Windows window styles */
#define HINT_NOFRAME (1l<<0)
#define HINT_BORDER (1L<<1)
@@ -1513,6 +1686,7 @@ winDeinitMultiWindowWM(void)
#define HINT_NOMAXIMIZE (1L<<4)
#define HINT_NOMINIMIZE (1L<<5)
#define HINT_NOSYSMENU (1L<<6)
+#define HINT_SKIPTASKBAR (1L<<7)
/* These two are used on their own */
#define HINT_MAX (1L<<0)
#define HINT_MIN (1L<<1)
@@ -1521,12 +1695,14 @@ static void
winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
{
static Atom windowState, motif_wm_hints, windowType;
- static Atom hiddenState, fullscreenState, belowState, aboveState;
+ static Atom hiddenState, fullscreenState, belowState, aboveState,
+ skiptaskbarState;
static Atom dockWindow;
static int generation;
Atom type, *pAtom = NULL;
int format;
- unsigned long hint = 0, maxmin = 0, style, nitems = 0, left = 0;
+ unsigned long hint = 0, maxmin = 0, nitems = 0, left = 0;
+ unsigned long style, exStyle;
MwmHints *mwm_hint = NULL;
if (!hWnd)
@@ -1545,24 +1721,32 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
+ skiptaskbarState =
+ XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
}
if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
- 1L, False, XA_ATOM, &type, &format,
+ MAXINT, False, XA_ATOM, &type, &format,
&nitems, &left,
(unsigned char **) &pAtom) == Success) {
- if (pAtom && nitems == 1) {
- if (*pAtom == hiddenState)
- maxmin |= HINT_MIN;
- else if (*pAtom == fullscreenState)
- maxmin |= HINT_MAX;
- if (*pAtom == belowState)
- *zstyle = HWND_BOTTOM;
- else if (*pAtom == aboveState)
- *zstyle = HWND_TOPMOST;
- }
- if (pAtom)
+ if (pAtom) {
+ unsigned long i;
+
+ for (i = 0; i < nitems; i++) {
+ if (*pAtom == skiptaskbarState)
+ hint |= HINT_SKIPTASKBAR;
+ if (*pAtom == hiddenState)
+ maxmin |= HINT_MIN;
+ else if (*pAtom == fullscreenState)
+ maxmin |= HINT_MAX;
+ if (*pAtom == belowState)
+ *zstyle = HWND_BOTTOM;
+ else if (*pAtom == aboveState)
+ *zstyle = HWND_TOPMOST;
+ }
+
XFree(pAtom);
+ }
}
nitems = left = 0;
@@ -1640,10 +1824,14 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
XFree(normal_hint);
}
- /* Override hint settings from above with settings from config file */
+ /*
+ Override hint settings from above with settings from config file and set
+ application id for grouping.
+ */
{
XClassHint class_hint = { 0, 0 };
char *window_name = 0;
+ char *application_id = 0;
if (XGetClassHint(pDisplay, iWindow, &class_hint)) {
XFetchName(pDisplay, iWindow, &window_name);
@@ -1652,10 +1840,24 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
winOverrideStyle(class_hint.res_name, class_hint.res_class,
window_name);
+#define APPLICATION_ID_FORMAT "%s.xwin.%s"
+#define APPLICATION_ID_UNKNOWN "unknown"
+ if (class_hint.res_class) {
+ asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
+ class_hint.res_class);
+ }
+ else {
+ asprintf(&application_id, APPLICATION_ID_FORMAT, XVENDORNAME,
+ APPLICATION_ID_UNKNOWN);
+ }
+ 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);
}
@@ -1694,9 +1896,9 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
/* Now apply styles to window */
style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
if (!style)
- return;
+ return; /* GetWindowLongPointer returns 0 on failure, we hope this isn't a valid style */
- if (!hint) /* All on */
+ if (!(hint & ~HINT_SKIPTASKBAR)) /* All on */
style = style | WS_CAPTION | WS_SIZEBOX;
else if (hint & HINT_NOFRAME) /* All off */
style = style & ~WS_CAPTION & ~WS_SIZEBOX;
@@ -1714,11 +1916,26 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
if (hint & HINT_NOSYSMENU)
style = style & ~WS_SYSMENU;
+ if (hint & HINT_SKIPTASKBAR)
+ style = style & ~WS_MINIMIZEBOX; /* window will become lost if minimized */
+
SetWindowLongPtr(hWnd, GWL_STYLE, style);
+
+ /* now we have iTaskbar, use that as well */
+ exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
+ if (hint & HINT_SKIPTASKBAR)
+ exStyle = (exStyle & ~WS_EX_APPWINDOW) | WS_EX_TOOLWINDOW;
+ else
+ exStyle = (exStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW;
+ SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle);
+
+ winDebug
+ ("winApplyHints: iWindow 0x%08x hints 0x%08x style 0x%08x exstyle 0x%08x\n",
+ iWindow, hint, style, exStyle);
}
void
-winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
+winUpdateWindowPosition(HWND hWnd, HWND * zstyle)
{
int iX, iY, iWidth, iHeight;
int iDx, iDy;
@@ -1769,8 +1986,96 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top,
rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 0);
- if (reshape) {
- winReshapeMultiWindow(pWin);
- 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 af917d6fc..1afbbd0ce 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -42,7 +42,7 @@
#include "winmsg.h"
#include "inputstr.h"
-extern void winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle);
+extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
/*
* Local globals
@@ -316,6 +316,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static Bool s_fTracking = FALSE;
Bool needRestack = FALSE;
LRESULT ret;
+ static Bool hasEnteredSizeMove = FALSE;
#if CYGDEBUG
winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam,
@@ -825,6 +826,8 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_CLOSE:
+ /* Remove property AppUserModelID */
+ winSetAppID(hwnd, NULL);
/* Branch on if the window was killed in X already */
if (pWinPriv->fXKilled) {
/* Window was killed, go ahead and destroy the window */
@@ -858,7 +861,9 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
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:
@@ -868,41 +873,36 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* */
if (!pWin->overrideRedirect) {
+ HWND zstyle = HWND_NOTOPMOST;
+
/* Flag that this window needs to be made active when clicked */
SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
- if (!(GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) {
- HWND zstyle = HWND_NOTOPMOST;
-
- /* Set the window extended style flags */
- SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
- /* Set the transient style flags */
- if (GetParent(hwnd))
- SetWindowLongPtr(hwnd, GWL_STYLE,
- WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
- WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
- /* Set the window standard style flags */
- else
- SetWindowLongPtr(hwnd, GWL_STYLE,
- (WS_POPUP | WS_OVERLAPPEDWINDOW |
- WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
- & ~WS_CAPTION & ~WS_SIZEBOX);
-
- winUpdateWindowPosition(hwnd, FALSE, &zstyle);
-
- {
- WinXWMHints hints;
-
- if (winMultiWindowGetWMHints(pWin, &hints)) {
- /*
- Give the window focus, unless it has an InputHint
- which is FALSE (this is used by e.g. glean to
- avoid every test window grabbing the focus)
- */
- if (!((hints.flags & InputHint) && (!hints.input))) {
- SetForegroundWindow(hwnd);
- }
+ /* Set the transient style flags */
+ if (GetParent(hwnd))
+ SetWindowLongPtr(hwnd, GWL_STYLE,
+ WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ /* Set the window standard style flags */
+ else
+ SetWindowLongPtr(hwnd, GWL_STYLE,
+ (WS_POPUP | WS_OVERLAPPEDWINDOW |
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
+ & ~WS_CAPTION & ~WS_SIZEBOX);
+
+ winUpdateWindowPosition(hwnd, &zstyle);
+
+ {
+ WinXWMHints hints;
+
+ if (winMultiWindowGetWMHints(pWin, &hints)) {
+ /*
+ Give the window focus, unless it has an InputHint
+ which is FALSE (this is used by e.g. glean to
+ avoid every test window grabbing the focus)
+ */
+ if (!((hints.flags & InputHint) && (!hints.input))) {
+ SetForegroundWindow(hwnd);
}
}
}
@@ -996,6 +996,16 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
*/
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
@@ -1020,8 +1030,13 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
(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:
@@ -1131,3 +1146,41 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
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 faa97c351..d6ec63099 100644
--- a/hw/xwin/winprefs.c
+++ b/hw/xwin/winprefs.c
@@ -37,6 +37,8 @@
#include <stdlib.h>
#ifdef __CYGWIN__
#include <sys/resource.h>
+#include <sys/wait.h>
+#include <pthread.h>
#endif
#include "win.h"
@@ -57,9 +59,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);
@@ -303,6 +302,110 @@ HandleCustomWM_INITMENU(unsigned long hwndIn, unsigned long hmenuIn)
}
+#ifdef __CYGWIN__
+static void
+LogLineFromFd(int fd, const char *fdname, int pid)
+{
+#define BUFSIZE 512 /* must be less than internal buffer size used in LogVWrite */
+ char buf[BUFSIZE];
+ char *bufptr = buf;
+
+ /* read from fd until eof, newline or our buffer is full */
+ while ((read(fd, bufptr, 1) > 0) && (bufptr < &(buf[BUFSIZE - 1]))) {
+ if (*bufptr == '\n')
+ break;
+ bufptr++;
+ }
+
+ /* null terminate and log */
+ *bufptr = 0;
+ if (strlen(buf))
+ ErrorF("(pid %d %s) %s\n", pid, fdname, buf);
+}
+
+static void *
+ExecAndLogThread(void *cmd)
+{
+ int pid;
+ int stdout_filedes[2];
+ int stderr_filedes[2];
+ int status;
+
+ /* Create a pair of pipes */
+ pipe(stdout_filedes);
+ pipe(stderr_filedes);
+
+ switch (pid = fork()) {
+ case 0: /* child */
+ {
+ struct rlimit rl;
+ unsigned int fd;
+
+ /* dup write end of pipes onto stderr and stdout */
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+
+ dup2(stdout_filedes[1], STDOUT_FILENO);
+ dup2(stderr_filedes[1], STDERR_FILENO);
+
+ /* Close any open descriptors except for STD* */
+ getrlimit(RLIMIT_NOFILE, &rl);
+ for (fd = STDERR_FILENO + 1; fd < rl.rlim_cur; fd++)
+ close(fd);
+
+ /* Disassociate any TTYs */
+ setsid();
+
+ execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
+ perror("execl failed");
+ exit(127);
+ }
+ break;
+
+ default: /* parent */
+ {
+ close(stdout_filedes[1]);
+ close(stderr_filedes[1]);
+
+ ErrorF("executing '%s', pid %d\n", (char *) cmd, pid);
+
+ /* read from pipes, write to log, until both are closed */
+ while (TRUE) {
+ fd_set readfds, errorfds;
+ int nfds = max(stdout_filedes[0], stderr_filedes[0]) + 1;
+
+ FD_ZERO(&readfds);
+ FD_SET(stdout_filedes[0], &readfds);
+ FD_SET(stderr_filedes[0], &readfds);
+ errorfds = readfds;
+
+ if (select(nfds, &readfds, NULL, &errorfds, NULL) > 0) {
+ if (FD_ISSET(stdout_filedes[0], &readfds))
+ LogLineFromFd(stdout_filedes[0], "stdout", pid);
+ if (FD_ISSET(stderr_filedes[0], &readfds))
+ LogLineFromFd(stderr_filedes[0], "stderr", pid);
+
+ if (FD_ISSET(stdout_filedes[0], &errorfds) &&
+ FD_ISSET(stderr_filedes[0], &errorfds))
+ break;
+ }
+ else {
+ break;
+ }
+ }
+
+ waitpid(pid, &status, 0);
+ }
+ break;
+
+ case -1: /* error */
+ ErrorF("fork() to run command failed\n");
+ }
+
+ return (void *) status;
+}
+#endif
+
/*
* Searches for the custom WM_COMMAND command ID and performs action.
* Return TRUE if command is proccessed, FALSE otherwise.
@@ -328,24 +431,17 @@ HandleCustomWM_COMMAND(unsigned long hwndIn, int command)
switch (m->menuItem[j].cmd) {
#ifdef __CYGWIN__
case CMD_EXEC:
- if (fork() == 0) {
- struct rlimit rl;
- unsigned long i;
-
- /* Close any open descriptors except for STD* */
- getrlimit(RLIMIT_NOFILE, &rl);
- for (i = STDERR_FILENO + 1; i < rl.rlim_cur; i++)
- close(i);
-
- /* Disassociate any TTYs */
- setsid();
+ {
+ pthread_t t;
- execl("/bin/sh",
- "/bin/sh", "-c", m->menuItem[j].param, NULL);
- exit(0);
- }
+ if (!pthread_create
+ (&t, NULL, ExecAndLogThread, m->menuItem[j].param))
+ pthread_detach(t);
else
- return TRUE;
+ ErrorF
+ ("Creating command output logging thread failed\n");
+ }
+ return TRUE;
break;
#else
case CMD_EXEC:
@@ -653,11 +749,17 @@ winPrefsLoadPreferences(char *path)
"MENU rmenu {\n"
" \"How to customize this menu\" EXEC \"xterm +tb -e man XWinrc\"\n"
" \"Launch xterm\" EXEC xterm\n"
- " \"Load .XWinrc\" RELOAD\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"
+ " \"Reload .XWinrc\" RELOAD\n"
" SEPARATOR\n" "}\n" "\n" "ROOTMENU rmenu\n";
path = "built-in default";
prefFile = fmemopen(defaultPrefs, strlen(defaultPrefs), "r");
+
+
}
if (!prefFile) {
@@ -728,15 +830,17 @@ 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++) {
if (pref.menu[i].menuItem[j].cmd == CMD_EXEC) {
diff --git a/hw/xwin/winprefslex.l b/hw/xwin/winprefslex.l
index ba8aea696..f3d988c5b 100644
--- a/hw/xwin/winprefslex.l
+++ b/hw/xwin/winprefslex.l
@@ -92,6 +92,12 @@ DEBUG { return DEBUGOUTPUT; }
RELOAD { return RELOAD; }
TRAYICON { return TRAYICON; }
SILENTEXIT { return SILENTEXIT; }
+DPI { return DPI; }
+XKBLAYOUT { return XKBLAYOUT; }
+XKBMODEL { return XKBMODEL; }
+XKBOPTIONS { return XKBOPTIONS; }
+XKBRULES { return XKBRULES; }
+XKBVARIANT { return XKBVARIANT; }
"{" { return LB; }
"}" { return RB; }
"\""[^\"\r\n]+"\"" { yylval.sVal = makestr(yytext+1); \
diff --git a/hw/xwin/winprefsyacc.y b/hw/xwin/winprefsyacc.y
index 0acf160e4..f71969746 100644
--- a/hw/xwin/winprefsyacc.y
+++ b/hw/xwin/winprefsyacc.y
@@ -38,6 +38,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "globals.h"
+#include "winconfig.h"
#include "winprefs.h"
/* The following give better error messages in bison at the cost of a few KB */
@@ -56,6 +58,13 @@ static MENUPARSED menu;
/* Functions for parsing the tokens into out structure */
/* Defined at the end section of this file */
+static void SetDPI (char *dpi);
+static void SetXKBLayout (char *layout);
+static void SetXKBModel (char *model);
+static void SetXKBOptions (char *options);
+static void SetXKBRules (char *rules);
+static void SetXKBVariant (char *variant);
+
static void SetIconDirectory (char *path);
static void SetDefaultIcon (char *fname);
static void SetRootMenu (char *menu);
@@ -120,6 +129,12 @@ extern int yylex(void);
%token TRAYICON
%token FORCEEXIT
%token SILENTEXIT
+%token DPI
+%token XKBLAYOUT
+%token XKBMODEL
+%token XKBOPTIONS
+%token XKBRULES
+%token XKBVARIANT
%token <sVal> STRING
%type <uVal> group1
@@ -154,6 +169,30 @@ command: defaulticon
| trayicon
| forceexit
| silentexit
+ | dpi
+ | xkblayout
+ | xkbmodel
+ | xkboptions
+ | xkbrules
+ | xkbvariant
+ ;
+
+dpi: DPI STRING NEWLINE { SetDPI($2); free($2); }
+ ;
+
+xkblayout: XKBLAYOUT STRING NEWLINE { SetXKBLayout($2); }
+ ;
+
+xkbmodel: XKBMODEL STRING NEWLINE { SetXKBModel($2); }
+ ;
+
+xkboptions: XKBOPTIONS STRING NEWLINE { SetXKBOptions($2); }
+ ;
+
+xkbrules: XKBRULES STRING NEWLINE { SetXKBRules($2); }
+ ;
+
+xkbvariant: XKBVARIANT STRING NEWLINE { SetXKBVariant($2); }
;
trayicon: TRAYICON STRING NEWLINE { SetTrayIcon($2); free($2); }
@@ -260,6 +299,58 @@ yyerror (char *s)
return 1;
}
+static void
+SetDPI (char *dpi)
+{
+ if (!g_cmdline.customDPI)
+ monitorResolution = atoi (dpi);
+}
+
+static void
+SetXKBLayout (char *layout)
+{
+ if (!g_cmdline.xkbLayout)
+ g_cmdline.xkbLayout = layout;
+ else
+ free (layout);
+}
+
+static void
+SetXKBModel (char *model)
+{
+ if (!g_cmdline.xkbModel)
+ g_cmdline.xkbModel = model;
+ else
+ free (model);
+}
+
+static void
+SetXKBOptions (char *options)
+{
+ if (!g_cmdline.xkbOptions)
+ g_cmdline.xkbOptions = options;
+ else
+ free (options);
+}
+
+static void
+SetXKBRules (char *rules)
+{
+ if (!g_cmdline.xkbRules)
+ g_cmdline.xkbRules = rules;
+ else
+ free (rules);
+}
+
+static void
+SetXKBVariant (char *variant)
+{
+ if (!g_cmdline.xkbVariant)
+ g_cmdline.xkbVariant = variant;
+ else
+ free (variant);
+}
+
/* Miscellaneous functions to store TOKENs into the structure */
static void
SetIconDirectory (char *path)
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index a5b3c07bf..9684c9678 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -31,6 +31,10 @@ from The Open Group.
#include <xwin-config.h>
#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
#include <../xfree86/common/xorgVersion.h>
#include "win.h"
#include "winconfig.h"
@@ -146,7 +150,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;
@@ -942,6 +946,14 @@ ddxProcessArgument(int argc, char *argv[], int i)
}
/*
+ * Look for the '-dpi' argument
+ */
+ if (IS_OPTION("-dpi")) {
+ g_cmdline.customDPI = TRUE;
+ return 0; /* Let DIX parse this again */
+ }
+
+ /*
* Look for the '-config' argument
*/
if (IS_OPTION("-config")
@@ -1078,6 +1090,11 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 1;
}
+ if (IS_OPTION("-hostintitle")) {
+ g_fHostInTitle = TRUE;
+ return 1;
+ }
+
return 0;
}
@@ -1149,6 +1166,100 @@ winLogCommandLine(int argc, char *argv[])
}
/*
+ * 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
*/
@@ -1165,6 +1276,18 @@ winLogVersionInfo(void)
ErrorF("Vendor: %s\n", XVENDORNAME);
ErrorF("Release: %d.%d.%d.%d\n", XORG_VERSION_MAJOR,
XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP);
- ErrorF("%s\n\n", BUILDERSTRING);
- ErrorF("Contact: %s\n", BUILDERADDR);
+#ifdef HAVE_SYS_UTSNAME_H
+ {
+ struct utsname name;
+
+ if (uname(&name) >= 0) {
+ ErrorF("OS: %s %s %s %s %s\n", name.sysname, name.nodename,
+ name.release, name.version, name.machine);
+ }
+ }
+#endif
+ winOS();
+ if (strlen(BUILDERSTRING))
+ ErrorF("%s\n", BUILDERSTRING);
+ ErrorF("\n");
}
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index be25f12af..75bd100e2 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -216,15 +216,19 @@ winScreenInit(ScreenPtr pScreen, int argc, char **argv)
else
winErrorFVerb(2, "winScreenInit - Using software cursor\n");
- /*
- Note the screen origin in a normalized coordinate space where (0,0) is at the top left
- of the native virtual desktop area
- */
- pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
- pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+ if (!noPanoramiXExtension) {
+ /*
+ Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+ of the native virtual desktop area
+ */
+ pScreen->x =
+ pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ pScreen->y =
+ pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
- ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
- pScreen->myNum, pScreen->x, pScreen->y);
+ ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
+ pScreen->myNum, pScreen->x, pScreen->y);
+ }
#if CYGDEBUG || YES
winDebug("winScreenInit - returning\n");
diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c
index 4c77cc05c..2dab81a69 100644
--- a/hw/xwin/winshaddd.c
+++ b/hw/xwin/winshaddd.c
@@ -37,24 +37,6 @@
#include "win.h"
/*
- * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly,
- * so we have to redefine it here.
- */
-#ifdef DEFINE_GUID
-#undef DEFINE_GUID
-#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-#endif /* DEFINE_GUID */
-
-/*
- * FIXME: Headers are broken, IID_IDirectDraw2 has to be defined
- * here manually. Should be handled by ddraw.h
- */
-#ifndef IID_IDirectDraw2
-DEFINE_GUID(IID_IDirectDraw2, 0xB3A6F3E0, 0x2B43, 0x11CF, 0xA2, 0xDE, 0x00,
- 0xAA, 0x00, 0xB9, 0x33, 0x56);
-#endif /* IID_IDirectDraw2 */
-
-/*
* Local prototypes
*/
@@ -569,15 +551,9 @@ winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
BoxPtr pBoxExtents = RegionExtents(damage);
/* Compute a GDI region from the damaged region */
- hrgnCombined = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- dwBox--;
- pBox++;
- while (dwBox--) {
- hrgnTemp = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- CombineRgn(hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
- DeleteObject(hrgnTemp);
- pBox++;
- }
+ hrgnCombined =
+ CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
+ pBoxExtents->y2);
/* Install the GDI region as a clipping region */
SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c
index c0879752a..5a6fc8d07 100644
--- a/hw/xwin/winshadddnl.c
+++ b/hw/xwin/winshadddnl.c
@@ -36,24 +36,6 @@
#endif
#include "win.h"
-/*
- * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly,
- * so we have to redefine it here.
- */
-#ifdef DEFINE_GUID
-#undef DEFINE_GUID
-#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-#endif /* DEFINE_GUID */
-
-/*
- * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined
- * here manually. Should be handled by ddraw.h
- */
-#ifndef IID_IDirectDraw4
-DEFINE_GUID(IID_IDirectDraw4, 0x9c59509a, 0x39bd, 0x11d1, 0x8c, 0x4a, 0x00,
- 0xc0, 0x4f, 0xd9, 0x30, 0xc5);
-#endif /* IID_IDirectDraw4 */
-
#define FAIL_MSG_MAX_BLT 10
/*
@@ -657,15 +639,9 @@ winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf)
BoxPtr pBoxExtents = RegionExtents(damage);
/* Compute a GDI region from the damaged region */
- hrgnCombined = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- dwBox--;
- pBox++;
- while (dwBox--) {
- hrgnTemp = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- CombineRgn(hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
- DeleteObject(hrgnTemp);
- pBox++;
- }
+ hrgnCombined =
+ CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
+ pBoxExtents->y2);
/* Install the GDI region as a clipping region */
SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index cdbb46bf2..8309e779d 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -500,16 +500,11 @@ winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf)
}
}
else if (!pScreenInfo->fMultiWindow) {
+
/* Compute a GDI region from the damaged region */
- hrgnCombined = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- dwBox--;
- pBox++;
- while (dwBox--) {
- hrgnTemp = CreateRectRgn(pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- CombineRgn(hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
- DeleteObject(hrgnTemp);
- pBox++;
- }
+ hrgnCombined =
+ CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
+ pBoxExtents->y2);
/* Install the GDI region as a clipping region */
SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
diff --git a/hw/xwin/wintaskbar.c b/hw/xwin/wintaskbar.c
new file mode 100644
index 000000000..4c0aace25
--- /dev/null
+++ b/hw/xwin/wintaskbar.c
@@ -0,0 +1,87 @@
+/*
+ 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 <windows.h>
+
+const GUID CLSID_TaskbarList = {0x56fdf344,0xfd6d,0x11d0,{0x95,0x8a,0x0,0x60,0x97,0xc9,0xa0,0x90}};
+const GUID IID_ITaskbarList = {0x56fdf342,0xfd6d,0x11d0,{0x95,0x8a,0x0,0x60,0x97,0xc9,0xa0,0x90}};
+
+#ifdef INTERFACE
+#undef INTERFACE
+#endif
+
+#define INTERFACE ITaskbarList
+DECLARE_INTERFACE_(ITaskbarList, IUnknown)
+{
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
+ STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG, Release) (THIS) PURE;
+
+ /* ITaskbarList methods */
+ STDMETHOD(HrInit) (THIS) PURE;
+ STDMETHOD(AddTab) (THIS_ HWND hWnd) PURE;
+ STDMETHOD(DeleteTab) (THIS_ HWND hWnd) PURE;
+ STDMETHOD(ActivateTab) (THIS_ HWND hWnd) PURE;
+ STDMETHOD(SetActiveAlt) (THIS_ HWND hWnd) PURE;
+};
+#undef INTERFACE
+
+/*
+ The stuff above needs to be in win32api headers, not defined here,
+ or at least generated from the MIDL :-)
+*/
+
+/*
+ This is unnecessarily heavyweight, we could just call CoInitialize() once at
+ startup and CoUninitialize() once at shutdown
+*/
+
+/*
+ The documentation for ITaskbarList::AddTab says that we are responsible for
+ deleting the tab ourselves when the window is deleted, but that doesn't actually
+ seem to be the case
+*/
+
+void wintaskbar(HWND hWnd, BOOL show)
+{
+ ITaskbarList* pTaskbarList = NULL;
+
+ if (SUCCEEDED(CoInitialize(NULL)))
+ {
+ if (SUCCEEDED(CoCreateInstance((const CLSID *)&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, (const IID *)&IID_ITaskbarList, (void**)&pTaskbarList)))
+ {
+ if (SUCCEEDED(pTaskbarList->lpVtbl->HrInit(pTaskbarList)))
+ {
+ if (show)
+ {
+ pTaskbarList->lpVtbl->AddTab(pTaskbarList,hWnd);
+ }
+ else
+ {
+ pTaskbarList->lpVtbl->DeleteTab(pTaskbarList,hWnd);
+ }
+ }
+ pTaskbarList->lpVtbl->Release(pTaskbarList);
+ }
+ CoUninitialize();
+ }
+}
diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c
index 77c160533..795221a1a 100644
--- a/hw/xwin/winwakeup.c
+++ b/hw/xwin/winwakeup.c
@@ -43,8 +43,8 @@ winWakeupHandler(ScreenPtr pScreen,
{
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))
&& (g_hDlgExit == 0 || !IsDialogMessage(g_hDlgExit, &msg))
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 5bf710209..974309248 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -263,7 +263,7 @@ winMWExtWMCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
strcat(pszClass, pszWindowID);
#if CYGMULTIWINDOW_DEBUG
- winDebug("winCreateWindowsWindow - Creating class: %s\n", pszClass);
+ winDebug("winMWExtWMCreateFrame - Creating class: %s\n", pszClass);
#endif
/* Setup our window class */
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index a5919ee4d..ed0ea942a 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
@@ -119,6 +121,7 @@ typedef struct _winWMMessageRec {
#define WM_WM_CHANGE_STATE (WM_USER + 11)
#define WM_WM_MAP2 (WM_USER + 12)
#define WM_WM_MAP3 (WM_USER + 13)
+#define WM_WM_HINTS_EVENT (WM_USER + 14)
#define WM_MANAGE (WM_USER + 100)
#define WM_UNMANAGE (WM_USER + 102)
@@ -157,5 +160,14 @@ void
void
winMinimizeWindow(Window id);
+void
+ winTaskbarInit(void);
+
+void
+ winTaskbarDestroy(void);
+
+void
+ winSetAppID(HWND hWnd, const char *AppID);
+
#endif /* XWIN_MULTIWINDOW */
#endif
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index fe662b9ba..9aba46b98 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -930,6 +930,7 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WIN_POLLING_MOUSE_TIMER_ID:
{
+ static POINT last_point;
POINT point;
WPARAM wL, wM, wR, wShift, wCtrl;
LPARAM lPos;
@@ -941,8 +942,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
point.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
point.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);
- /* Deliver absolute cursor position to X Server */
- winEnqueueMotion(point.x, point.y);
+ /* If the mouse pointer has moved, deliver absolute cursor position to X Server */
+ if (last_point.x != point.x || last_point.y != point.y) {
+ winEnqueueMotion(point.x, point.y);
+ last_point.x = point.x;
+ last_point.y = point.y;
+ }
/* Check if a button was released but we didn't see it */
GetCursorPos(&point);
@@ -1218,7 +1223,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
- case WM_ENDSESSION:
case WM_GIVEUP:
/* Tell X that we are giving up */
#ifdef XWIN_MULTIWINDOW