summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xwin
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xwin')
-rw-r--r--xc/programs/Xserver/hw/xwin/Imakefile22
-rw-r--r--xc/programs/Xserver/hw/xwin/InitInput.c6
-rw-r--r--xc/programs/Xserver/hw/xwin/InitOutput.c111
-rw-r--r--xc/programs/Xserver/hw/xwin/win.h148
-rw-r--r--xc/programs/Xserver/hw/xwin/winallpriv.c11
-rw-r--r--xc/programs/Xserver/hw/xwin/winblock.c26
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboard.h158
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboardinit.c117
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboardtextconv.c153
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboardthread.c463
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboardunicode.c68
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboardwndproc.c86
-rw-r--r--xc/programs/Xserver/hw/xwin/winclipboardxevents.c722
-rw-r--r--xc/programs/Xserver/hw/xwin/wincreatewnd.c128
-rw-r--r--xc/programs/Xserver/hw/xwin/winengine.c13
-rw-r--r--xc/programs/Xserver/hw/xwin/winerror.c10
-rw-r--r--xc/programs/Xserver/hw/xwin/winlayer.c55
-rw-r--r--xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c1574
-rw-r--r--xc/programs/Xserver/hw/xwin/winmultiwindowwm.c907
-rw-r--r--xc/programs/Xserver/hw/xwin/winscrinit.c164
-rw-r--r--xc/programs/Xserver/hw/xwin/winshaddd.c39
-rw-r--r--xc/programs/Xserver/hw/xwin/winshadddnl.c48
-rw-r--r--xc/programs/Xserver/hw/xwin/winshadgdi.c76
-rw-r--r--xc/programs/Xserver/hw/xwin/winwindow.c207
-rw-r--r--xc/programs/Xserver/hw/xwin/winwindow.h118
-rw-r--r--xc/programs/Xserver/hw/xwin/winwndproc.c6
26 files changed, 5226 insertions, 210 deletions
diff --git a/xc/programs/Xserver/hw/xwin/Imakefile b/xc/programs/Xserver/hw/xwin/Imakefile
index 9d619501b..08699ab16 100644
--- a/xc/programs/Xserver/hw/xwin/Imakefile
+++ b/xc/programs/Xserver/hw/xwin/Imakefile
@@ -1,5 +1,5 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
-XCOMM $XFree86: xc/programs/Xserver/hw/xwin/Imakefile,v 1.14 2002/10/17 08:18:18 alanh Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/xwin/Imakefile,v 1.15 2003/02/12 15:01:38 alanh Exp $
#include <Server.tmpl>
@@ -44,7 +44,15 @@ SRCS = InitInput.c \
wincreatewnd.c \
winregistry.c \
winconfig.c \
- winmsg.c
+ winmsg.c \
+ winmultiwindowwindow.c \
+ winmultiwindowwm.c \
+ winclipboardinit.c \
+ winclipboardtextconv.c \
+ winclipboardthread.c \
+ winclipboardunicode.c \
+ winclipboardwndproc.c \
+ winclipboardxevents.c
/*
* NOTE: The windialogs.rc file is compiled into windialogs.res.
@@ -89,7 +97,15 @@ OBJS = InitInput.o \
wincreatewnd.o \
winregistry.o \
winconfig.o \
- winmsg.o
+ winmsg.o \
+ winmultiwindowwindow.o \
+ winmultiwindowwm.o \
+ winclipboardinit.o \
+ winclipboardtextconv.o \
+ winclipboardthread.o \
+ winclipboardunicode.o \
+ winclipboardwndproc.o \
+ winclipboardxevents.o
INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \
diff --git a/xc/programs/Xserver/hw/xwin/InitInput.c b/xc/programs/Xserver/hw/xwin/InitInput.c
index 17b2edee0..a9f69aad5 100644
--- a/xc/programs/Xserver/hw/xwin/InitInput.c
+++ b/xc/programs/Xserver/hw/xwin/InitInput.c
@@ -26,7 +26,7 @@
from The Open Group.
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/InitInput.c,v 1.11 2002/07/05 09:19:25 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/InitInput.c,v 1.12 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -57,14 +57,14 @@ LegalModifier (unsigned int uiKey, DevicePtr pDevice)
void
ProcessInputEvents (void)
{
-#if CYGDEBUG
+#if 0
ErrorF ("ProcessInputEvents\n");
#endif
mieqProcessInputEvents ();
miPointerUpdate ();
-#if CYGDEBUG
+#if 0
ErrorF ("ProcessInputEvents - returning\n");
#endif
}
diff --git a/xc/programs/Xserver/hw/xwin/InitOutput.c b/xc/programs/Xserver/hw/xwin/InitOutput.c
index 29db17790..c434e58d1 100644
--- a/xc/programs/Xserver/hw/xwin/InitOutput.c
+++ b/xc/programs/Xserver/hw/xwin/InitOutput.c
@@ -26,7 +26,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/InitOutput.c,v 1.30 2002/10/17 08:18:19 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/InitOutput.c,v 1.32 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
#include "winconfig.h"
@@ -44,12 +44,14 @@ int g_iScreenPrivateIndex = -1;
int g_iCmapPrivateIndex = -1;
int g_iGCPrivateIndex = -1;
int g_iPixmapPrivateIndex = -1;
+int g_iWindowPrivateIndex = -1;
unsigned long g_ulServerGeneration = 0;
Bool g_fInitializedDefaultScreens = FALSE;
FILE *g_pfLog = NULL;
DWORD g_dwEnginesSupported = 0;
HINSTANCE g_hInstance = 0;
HWND g_hDlgDepthChange = NULL;
+Bool g_fCalledSetLocale = FALSE;
/*
@@ -114,6 +116,10 @@ winInitializeDefaultScreens (void)
ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo));
/* Get default width and height */
+ /*
+ * NOTE: These defaults will cause the window to cover only
+ * the primary monitor in the case that we have multiple monitors.
+ */
dwWidth = GetSystemMetrics (SM_CXSCREEN);
dwHeight = GetSystemMetrics (SM_CYSCREEN);
@@ -128,6 +134,8 @@ winInitializeDefaultScreens (void)
g_ScreenInfo[i].dwScreen = i;
g_ScreenInfo[i].dwWidth = dwWidth;
g_ScreenInfo[i].dwHeight = dwHeight;
+ g_ScreenInfo[i].dwUserWidth = dwWidth;
+ g_ScreenInfo[i].dwUserHeight = dwHeight;
g_ScreenInfo[i].fUserGaveHeightAndWidth
= WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH;
g_ScreenInfo[i].dwBPP = WIN_DEFAULT_BPP;
@@ -138,6 +146,9 @@ winInitializeDefaultScreens (void)
g_ScreenInfo[i].fFullScreen = FALSE;
g_ScreenInfo[i].fDecoration = TRUE;
g_ScreenInfo[i].fRootless = FALSE;
+ g_ScreenInfo[i].fMultiWindow = FALSE;
+ g_ScreenInfo[i].fMultipleMonitors = FALSE;
+ g_ScreenInfo[i].fClipboard = FALSE;
g_ScreenInfo[i].fLessPointer = FALSE;
g_ScreenInfo[i].fScrollbars = FALSE;
g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF;
@@ -302,6 +313,16 @@ ddxUseMsg (void)
ErrorF ("-rootless\n"
"\tEXPERIMENTAL: Run the server in pseudo-rootless mode.\n");
+ ErrorF ("-multiwindow\n"
+ "\tEXPERIMENTAL: Run the server in multi-window mode.\n");
+
+ ErrorF ("-multiplemonitors\n"
+ "\tEXPERIMENTAL: Use the entire virtual screen if multiple\n"
+ "\tmonitors are present.\n");
+
+ ErrorF ("-clipboard\n"
+ "\tEXPERIMENTAL: Run the clipboard integration module.\n");
+
ErrorF ("-scrollbars\n"
"\tIn windowed mode, allow screens bigger than the Windows desktop.\n"
"\tMoreover, if the window has decorations, one can now resize\n"
@@ -436,6 +457,8 @@ ddxProcessArgument (int argc, char *argv[], int i)
g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
g_ScreenInfo[nScreenNum].dwWidth = iWidth;
g_ScreenInfo[nScreenNum].dwHeight = iHeight;
+ g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
+ g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
}
else if (i + 3 < argc
&& 1 == sscanf (argv[i + 2], "%d",
@@ -448,6 +471,8 @@ ddxProcessArgument (int argc, char *argv[], int i)
g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
g_ScreenInfo[nScreenNum].dwWidth = iWidth;
g_ScreenInfo[nScreenNum].dwHeight = iHeight;
+ g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
+ g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
}
else
{
@@ -652,6 +677,59 @@ ddxProcessArgument (int argc, char *argv[], int i)
}
/*
+ * Look for the '-multiwindow' argument
+ */
+ if (strcmp (argv[i], "-multiwindow") == 0)
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fMultiWindow = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fMultiWindow = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-multiplemonitors' argument
+ */
+ if (strcmp (argv[i], "-multiplemonitors") == 0
+ || strcmp (argv[i], "-multimonitors") == 0)
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fMultipleMonitors = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
* Look for the '-scrollbars' argument
*/
if (strcmp (argv[i], "-scrollbars") == 0)
@@ -684,6 +762,32 @@ ddxProcessArgument (int argc, char *argv[], int i)
}
/*
+ * Look for the '-clipboard' argument
+ */
+ if (strcmp (argv[i], "-clipboard") == 0)
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fClipboard = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fClipboard = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
* Look for the '-ignoreinput' argument
*/
if (strcmp (argv[i], "-ignoreinput") == 0)
@@ -1144,9 +1248,14 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
/* Initialize each screen */
for (i = 0; i < g_iNumScreens; i++)
{
+ /* Initialize the screen */
if (-1 == AddScreen (winScreenInit, argc, argv))
{
FatalError ("InitOutput - Couldn't add screen %d", i);
}
}
+
+#if CYGDEBUG || YES
+ ErrorF ("InitOutput - Returning.\n");
+#endif
}
diff --git a/xc/programs/Xserver/hw/xwin/win.h b/xc/programs/Xserver/hw/xwin/win.h
index 1883ebb0d..684e98cc1 100644
--- a/xc/programs/Xserver/hw/xwin/win.h
+++ b/xc/programs/Xserver/hw/xwin/win.h
@@ -29,39 +29,32 @@
* Suhaib M Siddiqi
* Peter Busch
* Harold L Hunt II
- * MATSUZAKI Kensuke
+ * Kensuke Matsuzaki
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/win.h,v 1.31 2002/10/17 08:18:21 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/win.h,v 1.34 2003/02/12 15:01:38 alanh Exp $ */
#ifndef _WIN_H_
#define _WIN_H_
#ifndef NO
-#define NO 0
+#define NO 0
#endif
#ifndef YES
-#define YES 1
+#define YES 1
#endif
/*
* Build toggles for experimental features
*/
-#define WIN_NATIVE_GDI_SUPPORT YES
-#define WIN_LAYER_SUPPORT NO
-#define WIN_NEW_KEYBOARD_SUPPORT NO
-#define WIN_EMULATE_PSEUDO_SUPPORT YES
-#define WIN_UPDATE_STATS NO
+#define WIN_NATIVE_GDI_SUPPORT YES
+#define WIN_LAYER_SUPPORT NO
+#define WIN_NEW_KEYBOARD_SUPPORT NO
+#define WIN_EMULATE_PSEUDO_SUPPORT YES
+#define WIN_UPDATE_STATS NO
/* Turn debug messages on or off */
-#define CYGDEBUG NO
-
-/* Constant strings */
-#define WINDOW_CLASS "cygwin/xfree86"
-#define WINDOW_TITLE "Cygwin/XFree86"
-#define WIN_SCR_PROP "cyg_screen_prop"
-#define WIN_MSG_QUEUE_FNAME "/dev/windows"
-#define WIN_LOG_FNAME "/tmp/XWin.log"
+#define CYGDEBUG NO
#define NEED_EVENTS
@@ -84,12 +77,12 @@
/*
* Windows only supports 256 color palettes
*/
-#define WIN_NUM_PALETTE_ENTRIES 256
+#define WIN_NUM_PALETTE_ENTRIES 256
/*
* Number of times to call Restore in an attempt to restore the primary surface
*/
-#define WIN_REGAIN_SURFACE_RETRIES 1
+#define WIN_REGAIN_SURFACE_RETRIES 1
/*
* Build a supported display depths mask by shifting one to the left
@@ -132,6 +125,7 @@
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
+#include <pthread.h>
#include <X11/XWDFile.h>
@@ -189,6 +183,13 @@
#include "winms.h"
+/*
+ * Multi-Window Window Manager header
+ */
+
+#include "winwindow.h"
+
+
/* Cygwin's winuser.h does not define VK_KANA as of 28Mar2001 */
/* NOTE: Cygwin's winuser.h was fixed shortly after 28Mar2001. */
#ifndef VK_KANA
@@ -286,16 +287,6 @@ typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr);
/*
- * Window privates
- */
-
-typedef struct
-{
- DWORD dwDummy;
-} winPrivWinRec, *winPrivWinPtr;
-
-
-/*
* GC (graphics context) privates
*/
@@ -342,7 +333,7 @@ typedef struct
{
DWORD dwXKeycodes[WIN_MAX_KEYS_PER_KEY];
DWORD dwReleaseModifiers;
-} winKeyEventsRec, winKeyEventsPtr;
+} winKeyEventsRec, *winKeyEventsPtr;
#endif /* WIN_NEW_KEYBOARD_SUPPORT */
@@ -359,7 +350,12 @@ typedef struct
Bool fUserGaveHeightAndWidth;
DWORD dwScreen;
+ DWORD dwUserWidth;
+ DWORD dwUserHeight;
DWORD dwWidth;
+ DWORD dwHeight;
+ DWORD dwWidth_mm;
+ DWORD dwHeight_mm;
DWORD dwPaddedWidth;
/*
@@ -368,9 +364,6 @@ typedef struct
* a rounding up of the width.
*/
DWORD dwStride;
- DWORD dwHeight;
- DWORD dwWidth_mm;
- DWORD dwHeight_mm;
/* Offset of the screen in the window when using scrollbars */
DWORD dwXOffset;
@@ -389,6 +382,9 @@ typedef struct
Bool fFullScreen;
Bool fDecoration;
Bool fRootless;
+ Bool fMultiWindow;
+ Bool fMultipleMonitors;
+ Bool fClipboard;
Bool fLessPointer;
Bool fScrollbars;
int iE3BTimeout;
@@ -406,7 +402,7 @@ typedef struct
* Screen privates
*/
-typedef struct
+typedef struct _winPrivScreenRec
{
winScreenInfoPtr pScreenInfo;
@@ -414,7 +410,7 @@ typedef struct
Bool fClosed;
Bool fActive;
Bool fBadDepth;
-
+
int iDeltaZ;
CloseScreenProcPtr CloseScreen;
@@ -427,9 +423,13 @@ typedef struct
DWORD dwModeKeyStates;
/* Clipboard support */
+ pthread_t ptClipboardProc;
+
+#if 0
HWND hwndNextViewer;
void *display;
int window;
+#endif
/* Last width, height, and depth of the Windows display */
DWORD dwLastWindowsWidth;
@@ -480,6 +480,14 @@ typedef struct
/* Privates used by both shadow fb DirectDraw servers */
LPDIRECTDRAWCLIPPER pddcPrimary;
+ /* Privates used by multi-window server */
+ pthread_t ptWMProc;
+ void *pWMInfo;
+
+ /* Privates used for any module running in a seperate thread */
+ pthread_mutex_t pmServerStarted;
+ Bool fServerStarted;
+
/* Engine specific functions */
winAllocateFBProcPtr pwinAllocateFB;
winShadowUpdateProcPtr pwinShadowUpdate;
@@ -516,7 +524,11 @@ typedef struct
ClearToBackgroundProcPtr ClearToBackground;
ClipNotifyProcPtr ClipNotify;
RestackWindowProcPtr RestackWindow;
-} winPrivScreenRec, *winPrivScreenPtr;
+ ReparentWindowProcPtr ReparentWindow;
+#ifdef SHAPE
+ SetShapeProcPtr SetShape;
+#endif
+} winPrivScreenRec;
/*
@@ -531,12 +543,14 @@ extern int g_iScreenPrivateIndex;
extern int g_iCmapPrivateIndex;
extern int g_iGCPrivateIndex;
extern int g_iPixmapPrivateIndex;
+extern int g_iWindowPrivateIndex;
extern unsigned long g_ulServerGeneration;
extern CARD32 g_c32LastInputEventTime;
extern DWORD g_dwEnginesSupported;
extern HINSTANCE g_hInstance;
extern HWND g_hDlgDepthChange;
+
/*
* Extern declares for dynamically loaded libraries and function pointers
*/
@@ -609,8 +623,14 @@ extern FARPROC g_fpTrackMouseEvent;
* Window privates macros
*/
-#define winGetWindowPrivate(_pWin) ((winPrivWin *)\
- (_pWin)->devPrivates[winWindowPrivateIndex].ptr)
+#define winGetWindowPriv(pWin) \
+ ((winPrivWinPtr) (pWin)->devPrivates[g_iWindowPrivateIndex].ptr)
+
+#define winSetWindowPriv(pWin,v) \
+ ((pWin)->devPrivates[g_iWindowPrivateIndex].ptr = (pointer) v)
+
+#define winWindowPriv(pWin) \
+ winPrivWinPtr pWinPriv = winGetWindowPriv(pWin)
/*
@@ -675,6 +695,16 @@ winPixmapToRegionNativeGDI (PixmapPtr pPix);
/*
+ * winclipboardinit.c
+ */
+
+Bool
+winInitClipboard (pthread_t *ptClipboardProc,
+ pthread_mutex_t *ppmServerStarted,
+ DWORD dwScreen);
+
+
+/*
* wincmap.c
*/
@@ -905,8 +935,7 @@ winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations);
Bool
winRandRSetConfig (ScreenPtr pScreen,
Rotation rotateKind,
- RRScreenSizePtr pSize,
- RRVisualGroupPtr pVisualGroup);
+ RRScreenSizePtr pSize);
Bool
winRandRInit (ScreenPtr pScreen);
@@ -1341,6 +1370,45 @@ winUnmapWindowPRootless (WindowPtr pWindow);
Bool
winMapWindowPRootless (WindowPtr pWindow);
+#ifdef SHAPE
+void
+winSetShapePRootless (WindowPtr pWindow);
+#endif
+
+
+/*
+ * winmultiwindowwindow.c
+ */
+
+Bool
+winCreateWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winDestroyWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y);
+
+Bool
+winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask);
+
+Bool
+winUnmapWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winMapWindowMultiWindow (WindowPtr pWindow);
+
+void
+winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent);
+
+void
+winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib);
+
+#ifdef SHAPE
+void
+winSetShapeMultiWindow (WindowPtr pWindow);
+#endif
+
/*
* winwndproc.c
diff --git a/xc/programs/Xserver/hw/xwin/winallpriv.c b/xc/programs/Xserver/hw/xwin/winallpriv.c
index fc32b9c86..a27309598 100644
--- a/xc/programs/Xserver/hw/xwin/winallpriv.c
+++ b/xc/programs/Xserver/hw/xwin/winallpriv.c
@@ -28,7 +28,7 @@
* Authors: Keith Packard, MIT X Consortium
* Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winallpriv.c,v 1.11 2002/10/17 08:18:21 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winallpriv.c,v 1.12 2002/10/31 23:04:39 alanh Exp $ */
#include "win.h"
@@ -60,6 +60,7 @@ winAllocatePrivates (ScreenPtr pScreen)
g_iScreenPrivateIndex = AllocateScreenPrivateIndex ();
g_iGCPrivateIndex = AllocateGCPrivateIndex ();
g_iPixmapPrivateIndex = AllocatePixmapPrivateIndex ();
+ g_iWindowPrivateIndex = AllocateWindowPrivateIndex ();
g_ulServerGeneration = serverGeneration;
}
@@ -97,6 +98,14 @@ winAllocatePrivates (ScreenPtr pScreen)
return FALSE;
}
+ /* Reserve Window memory for our privates */
+ if (!AllocateWindowPrivate (pScreen, g_iWindowPrivateIndex,
+ sizeof (winPrivWinRec)))
+ {
+ ErrorF ("winAllocatePrivates () - AllocateWindowPrivates () failed\n");
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/xc/programs/Xserver/hw/xwin/winblock.c b/xc/programs/Xserver/hw/xwin/winblock.c
index f10645662..45d509fea 100644
--- a/xc/programs/Xserver/hw/xwin/winblock.c
+++ b/xc/programs/Xserver/hw/xwin/winblock.c
@@ -27,7 +27,7 @@
*
* Authors: Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winblock.c,v 1.5 2002/10/17 08:18:22 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winblock.c,v 1.6 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -41,6 +41,30 @@ winBlockHandler (int nScreen,
winScreenPriv((ScreenPtr)pBlockData);
MSG msg;
+ /* Signal threaded modules to begin */
+ if (pScreenPriv != NULL && !pScreenPriv->fServerStarted)
+ {
+ int iReturn;
+
+ ErrorF ("winBlockHandler - Releasing pmServerStarted\n");
+
+ /* Flag that modules are to be started */
+ pScreenPriv->fServerStarted = TRUE;
+
+ /* Unlock the mutex for threaded modules */
+ iReturn = pthread_mutex_unlock (&pScreenPriv->pmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winBlockHandler - pthread_mutex_unlock () failed: %d\n",
+ iReturn);
+ goto winBlockHandler_ProcessMessages;
+ }
+
+ ErrorF ("winBlockHandler - pthread_mutex_unlock () returned\n");
+ }
+
+winBlockHandler_ProcessMessages:
+
/* Process all messages on our queue */
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
diff --git a/xc/programs/Xserver/hw/xwin/winclipboard.h b/xc/programs/Xserver/hw/xwin/winclipboard.h
new file mode 100644
index 000000000..6e6cf44a9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboard.h
@@ -0,0 +1,158 @@
+/*
+ *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.
+ *
+ * Authors: Harold Hunt
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboard.h,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+
+#ifndef _WINCLIPBOARD_H_
+#define _WINCLIPBOARD_H_
+
+/* Standard library headers */
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <pthread.h>
+
+/* X headers */
+#include "X.h"
+#include "Xatom.h"
+/* NOTE: For some unknown reason, including Xproto.h solves
+ * tons of problems with including windows.h. Unknowns reasons
+ * are usually bad, so someone should investigate this.
+ */
+#include "Xproto.h"
+#include "Xutil.h"
+#include "Xlocale.h"
+
+/* Fixups to prevent collisions between Windows and X headers */
+#define ATOM DWORD
+
+/* Windows headers */
+#include <windows.h>
+
+
+/* Clipboard module constants */
+#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip"
+#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip"
+#define WIN_MSG_QUEUE_FNAME "/dev/windows"
+#define WIN_CONNECT_RETRIES 3
+#define WIN_CONNECT_DELAY 4
+#define WIN_JMP_OKAY 0
+#define WIN_JMP_ERROR_IO 2
+
+/*
+ * Argument structure for Clipboard module main thread
+ */
+
+typedef struct _ClipboardProcArgRec {
+ DWORD dwScreen;
+ pthread_mutex_t *ppmServerStarted;
+} ClipboardProcArgRec, *ClipboardProcArgPtr;
+
+
+/*
+ * References to external symbols
+ */
+
+extern char *display;
+extern void ErrorF (const char* /*f*/, ...);
+
+
+/*
+ * winclipboardinit.c
+ */
+
+Bool
+winInitClipboard (pthread_t *ptClipboardProc,
+ pthread_mutex_t *ppmServerStarted,
+ DWORD dwScreen);
+
+HWND
+winClipboardCreateMessagingWindow ();
+
+
+/*
+ * winclipboardtextconv.c
+ */
+
+void
+winClipboardDOStoUNIX (char *pszData, int iLength);
+
+void
+winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength);
+
+
+/*
+ * winclipboardthread.c
+ */
+
+void *
+winClipboardProc (void *pArg);
+
+
+/*
+ * winclipboardunicode.c
+ */
+
+Bool
+winClipboardDetectUnicodeSupport ();
+
+
+/*
+ * winclipboardwndproc.c
+ */
+
+BOOL
+winClipboardFlushWindowsMessageQueue (HWND hwnd);
+
+LRESULT CALLBACK
+winClipboardWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+
+/*
+ * winclipboardxevents.c
+ */
+
+Bool
+winClipboardFlushXEvents (HWND hwnd,
+ Atom atomClipboard,
+ Atom atomLocalProperty,
+ Atom atomUTF8String,
+ Atom atomCompoundText,
+ Atom atomTargets,
+ Atom atomDeleteWindow,
+ int iWindow,
+ Display *pDisplay,
+ Bool fUnicodeSupport);
+#endif
diff --git a/xc/programs/Xserver/hw/xwin/winclipboardinit.c b/xc/programs/Xserver/hw/xwin/winclipboardinit.c
new file mode 100644
index 000000000..22c068c48
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboardinit.c
@@ -0,0 +1,117 @@
+/*
+ *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.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardinit.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "winclipboard.h"
+
+
+/*
+ * Intialize the Clipboard module
+ */
+
+Bool
+winInitClipboard (pthread_t *ptClipboardProc,
+ pthread_mutex_t *ppmServerStarted,
+ DWORD dwScreen)
+{
+ ClipboardProcArgPtr pArg;
+
+ ErrorF ("winInitClipboard ()\n");
+
+ /* Allocate the parameter structure */
+ pArg = (ClipboardProcArgPtr) malloc (sizeof (ClipboardProcArgRec));
+ if (pArg == NULL)
+ {
+ ErrorF ("winInitClipboard - malloc for ClipboardProcArgRec failed.\n");
+ return FALSE;
+ }
+
+ /* Setup the argument structure for the thread function */
+ pArg->dwScreen = dwScreen;
+ pArg->ppmServerStarted = ppmServerStarted;
+
+ /* Spawn a thread for the Clipboard module */
+ if (pthread_create (ptClipboardProc, NULL, winClipboardProc, pArg))
+ {
+ /* Bail if thread creation failed */
+ ErrorF ("winInitClipboard - pthread_create failed.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Create the Windows window that we use to recieve Windows messages
+ */
+
+HWND
+winClipboardCreateMessagingWindow ()
+{
+ WNDCLASS wc;
+ HWND hwnd;
+
+ /* Setup our window class */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = winClipboardWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle (NULL);
+ wc.hIcon = 0;
+ wc.hCursor = 0;
+ wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS;
+ RegisterClass (&wc);
+
+ /* Create the window */
+ hwnd = CreateWindowExA (0, /* Extended styles */
+ WIN_CLIPBOARD_WINDOW_CLASS,/* Class name */
+ WIN_CLIPBOARD_WINDOW_TITLE,/* Window name */
+ WS_OVERLAPPED, /* Not visible anyway */
+ CW_USEDEFAULT, /* Horizontal position */
+ CW_USEDEFAULT, /* Vertical position */
+ CW_USEDEFAULT, /* Right edge */
+ CW_USEDEFAULT, /* Bottom edge */
+ (HWND) NULL, /* No parent or owner window */
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle (NULL),/* Instance handle */
+ NULL); /* ScreenPrivates */
+ assert (hwnd != NULL);
+
+ /* I'm not sure, but we may need to call this to start message processing */
+ ShowWindow (hwnd, SW_HIDE);
+
+ /* Similarly, we may need a call to this even though we don't paint */
+ UpdateWindow (hwnd);
+
+ return hwnd;
+}
diff --git a/xc/programs/Xserver/hw/xwin/winclipboardtextconv.c b/xc/programs/Xserver/hw/xwin/winclipboardtextconv.c
new file mode 100644
index 000000000..f97681c5f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboardtextconv.c
@@ -0,0 +1,153 @@
+/*
+ *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.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardtextconv.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "win.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+ * Convert \r\n to \n
+ *
+ * NOTE: This was heavily inspired by, if not down right stolen from,
+ * Cygwin's winsup/cygwin/fhandler.cc/fhandler_base::read ()
+ */
+
+void
+winClipboardDOStoUNIX (char *pszSrc, int iLength)
+{
+ char *pszDest = pszSrc;
+ char *pszEnd = pszSrc + iLength;
+
+ /* Loop until the last character */
+ while (pszSrc < pszEnd)
+ {
+ /* Copy the current source character to current destination character */
+ *pszDest = *pszSrc;
+
+ /* Advance to the next source character */
+ pszSrc++;
+
+ /* Don't advance the destination character if we need to drop an \r */
+ if (*pszDest != '\r' || *pszSrc != '\n')
+ pszDest++;
+ }
+
+ /* Move the terminating null */
+ *pszDest = '\0';
+}
+
+
+/*
+ * Convert \n to \r\n
+ */
+
+void
+winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength)
+{
+ int iNewlineCount = 0;
+ unsigned char *pszSrc = *ppszData;
+ unsigned char *pszEnd = pszSrc + iLength;
+ unsigned char *pszDest = NULL, *pszDestBegin = NULL;
+
+#if 0
+ ErrorF ("UNIXtoDOS () - Original data:\n%s\n", *ppszData);
+#endif
+
+ /* Count \n characters without leading \r */
+ while (pszSrc < pszEnd)
+ {
+ /* Skip ahead two character if found set of \r\n */
+ if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
+ {
+ pszSrc += 2;
+ continue;
+ }
+
+ /* Increment the count if found naked \n */
+ if (*pszSrc == '\n')
+ {
+ iNewlineCount++;
+ }
+
+ pszSrc++;
+ }
+
+ /* Return if no naked \n's */
+ if (iNewlineCount == 0)
+ return;
+
+ /* Allocate a new string */
+ pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1);
+
+ /* Set source pointer to beginning of data string */
+ pszSrc = *ppszData;
+
+ /* Loop through all characters in source string */
+ while (pszSrc < pszEnd)
+ {
+ /* Copy line endings that are already valid */
+ if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
+ {
+ *pszDest = *pszSrc;
+ *(pszDest + 1) = *(pszSrc + 1);
+ pszDest += 2;
+ pszSrc += 2;
+ continue;
+ }
+
+ /* Add \r to naked \n's */
+ if (*pszSrc == '\n')
+ {
+ *pszDest = '\r';
+ *(pszDest + 1) = *pszSrc;
+ pszDest += 2;
+ pszSrc += 1;
+ continue;
+ }
+
+ /* Copy normal characters */
+ *pszDest = *pszSrc;
+ pszSrc++;
+ pszDest++;
+ }
+
+ /* Put terminating null at end of new string */
+ *pszDest = '\0';
+
+ /* Swap string pointers */
+ free (*ppszData);
+ *ppszData = pszDestBegin;
+
+#if 0
+ ErrorF ("UNIXtoDOS () - Final string:\n%s\n", pszDestBegin);
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xwin/winclipboardthread.c b/xc/programs/Xserver/hw/xwin/winclipboardthread.c
new file mode 100644
index 000000000..ce4590b98
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboardthread.c
@@ -0,0 +1,463 @@
+/*
+ *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.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardthread.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "winclipboard.h"
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fCalledSetLocale;
+
+
+/*
+ * Global variables
+ */
+
+static jmp_buf g_jmpEntry;
+
+
+/*
+ * Local function prototypes
+ */
+
+static int
+winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
+
+static int
+winClipboardIOErrorHandler (Display *pDisplay);
+
+
+/*
+ * Main thread function
+ */
+
+void *
+winClipboardProc (void *pArg)
+{
+ Atom atomClipboard, atomClipboardManager;
+ Atom atomLocalProperty, atomCompoundText;
+ Atom atomUTF8String, atomTargets;
+ int iReturn;
+ HWND hwnd = NULL;
+ int iConnectionNumber;
+ int fdMessageQueue;
+ fd_set fdsRead;
+ int iMaxDescriptor;
+ Display *pDisplay;
+ Window iWindow;
+ Atom atomDeleteWindow;
+ Bool fReturn;
+ int iRetries;
+ Bool fUnicodeSupport;
+ char szDisplay[512];
+ int i;
+ ClipboardProcArgPtr pProcArg = (ClipboardProcArgPtr) pArg;
+
+ ErrorF ("winClipboardProc - Hello\n");
+
+ /* Check that argument pointer is not invalid */
+ if (pArg == NULL)
+ {
+ ErrorF ("winClipboardProc - pArg is NULL, bailing.\n");
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winClipboardProc - Calling pthread_mutex_lock ()\n");
+
+ /* Grab our garbage mutex to satisfy pthread_cond_wait */
+ iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winClipboardProc - pthread_mutex_lock () failed: %d\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winClipboardProc - pthread_mutex_lock () returned.\n");
+
+ /* Do we have Unicode support? */
+ fUnicodeSupport = winClipboardDetectUnicodeSupport ();
+
+ /* Set the current locale? What does this do? */
+ if (fUnicodeSupport && !g_fCalledSetLocale)
+ {
+ ErrorF ("winClipboardProc - Calling setlocale ()\n");
+ if (!setlocale (LC_ALL, ""))
+ {
+ ErrorF ("winClipboardProc - setlocale () error\n");
+ pthread_exit (NULL);
+ }
+ ErrorF ("winClipboardProc - setlocale () returned\n");
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == False)
+ {
+ ErrorF ("winClipboardProc - Locale not supported by X\n");
+ pthread_exit (NULL);
+ }
+ }
+
+ /* Flag that we have called setlocale */
+ g_fCalledSetLocale = TRUE;
+
+ /* Release the garbage mutex */
+ pthread_mutex_unlock (pProcArg->ppmServerStarted);
+
+ ErrorF ("winClipboardProc - pthread_mutex_unlock () returned.\n");
+
+ /* Allow multiple threads to access Xlib */
+ if (XInitThreads () == 0)
+ {
+ ErrorF ("winClipboardProc - XInitThreads failed.\n");
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winClipboardProc - XInitThreads () returned.\n");
+
+ /* Set jump point for Error exits */
+ iReturn = setjmp (g_jmpEntry);
+
+ /* Check if we should continue operations */
+ if (iReturn != WIN_JMP_ERROR_IO
+ && iReturn != WIN_JMP_OKAY)
+ {
+ /* setjmp returned an unknown value, exit */
+ ErrorF ("winClipboardProc - setjmp returned: %d exiting\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+ else if (iReturn == WIN_JMP_ERROR_IO)
+ {
+ ErrorF ("winClipboardProc - setjmp returned and hwnd: %08x\n", hwnd);
+ }
+
+ /* Initialize retry count */
+ iRetries = 0;
+
+#if 0
+ /* Setup the display connection string x */
+ snprintf (szDisplay, 512, "127.0.0.1:%s.%d", display, pProcArg->dwScreen);
+#else
+ /* Setup the display connection string x */
+ snprintf (szDisplay, 512, ":%s.%d", display, pProcArg->dwScreen);
+#endif
+
+ /* Print the display connection string */
+ ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay);
+
+ /* Open the X display */
+ do
+ {
+ pDisplay = XOpenDisplay (szDisplay);
+ if (pDisplay == NULL)
+ {
+ ErrorF ("winClipboardProc - Could not open display, "
+ "try: %d, sleeping: %d\n",
+ iRetries + 1, WIN_CONNECT_DELAY);
+ ++iRetries;
+ sleep (WIN_CONNECT_DELAY);
+ continue;
+ }
+ else
+ break;
+ }
+ while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+
+ /* Make sure that the display opened */
+ if (pDisplay == NULL)
+ {
+ ErrorF ("winClipboardProc - Failed opening the display, giving up\n");
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winClipboardProc - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
+
+ /* Create Windows messaging window */
+ hwnd = winClipboardCreateMessagingWindow ();
+
+ /* Get our connection number */
+ iConnectionNumber = ConnectionNumber (pDisplay);
+
+ /* Open a file descriptor for the windows message queue */
+ fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY);
+ if (fdMessageQueue == -1)
+ {
+ ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
+ pthread_exit (NULL);
+ }
+
+ /* Find max of our file descriptors */
+ iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1;
+
+ /* Select event types to watch */
+ if (XSelectInput (pDisplay,
+ DefaultRootWindow (pDisplay),
+ SubstructureNotifyMask |
+ StructureNotifyMask |
+ PropertyChangeMask) == BadWindow)
+ ErrorF ("winClipboardProc - XSelectInput generated BadWindow "
+ "on RootWindow\n\n");
+
+ /* Create a messaging window */
+ iWindow = XCreateSimpleWindow (pDisplay,
+ DefaultRootWindow (pDisplay),
+ 1, 1,
+ 500, 500,
+ 0,
+ BlackPixel (pDisplay, 0),
+ BlackPixel (pDisplay, 0));
+ if (iWindow == 0)
+ {
+ ErrorF ("winClipboardProc - Could not create a window\n");
+ pthread_exit (NULL);
+ }
+
+ /* This looks like our only hope for getting a message before shutdown */
+ /* Register for WM_DELETE_WINDOW message from window manager */
+ atomDeleteWindow = XInternAtom (pDisplay, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols (pDisplay, iWindow, &atomDeleteWindow, 1);
+
+ /* Set error handler */
+ XSetErrorHandler (winClipboardErrorHandler);
+ XSetIOErrorHandler (winClipboardIOErrorHandler);
+
+ /* Create an atom for CLIPBOARD_MANAGER */
+ atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False);
+ if (atomClipboardManager == None)
+ {
+ ErrorF ("winClipboardProc - Could not create CLIPBOARD_MANAGER atom\n");
+ pthread_exit (NULL);
+ }
+
+ /* Assert ownership of CLIPBOARD_MANAGER */
+ iReturn = XSetSelectionOwner (pDisplay, atomClipboardManager,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardProc - Could not set CLIPBOARD_MANAGER owner\n");
+ pthread_exit (NULL);
+ }
+
+ /* Create an atom for CLIPBOARD */
+ atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False);
+ if (atomClipboard == None)
+ {
+ ErrorF ("winClipboardProc - Could not create CLIPBOARD atom\n");
+ pthread_exit (NULL);
+ }
+
+ /* Assert ownership of CLIPBOARD */
+ iReturn = XSetSelectionOwner (pDisplay, atomClipboard,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
+ pthread_exit (NULL);
+ }
+
+ /* Assert ownership of PRIMARY */
+ iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardProc - Could not set PRIMARY owner\n");
+ pthread_exit (NULL);
+ }
+
+ /* Local property to hold pasted data */
+ atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False);
+ if (atomLocalProperty == None)
+ {
+ ErrorF ("winClipboardProc - Could not create CYGX_CUT_BUFFER atom\n");
+ pthread_exit (NULL);
+ }
+
+ /* Create an atom for UTF8_STRING */
+ atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
+ if (atomUTF8String == None)
+ {
+ ErrorF ("winClipboardProc - Could not create UTF8_STRING atom\n");
+ pthread_exit (NULL);
+ }
+
+ /* Create an atom for COMPOUND_TEXT */
+ atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
+ if (atomCompoundText == None)
+ {
+ ErrorF ("winClipboardProc - Could not create COMPOUND_TEXT atom\n");
+ pthread_exit (NULL);
+ }
+
+ /* Create an atom for TARGETS */
+ atomTargets = XInternAtom (pDisplay, "TARGETS", False);
+ if (atomTargets == None)
+ {
+ ErrorF ("winClipboardProc - Could not create TARGETS atom\n");
+ pthread_exit (NULL);
+ }
+
+ /* Pre-flush X events */
+ /*
+ * NOTE: Apparently you'll freeze if you don't do this,
+ * because there may be events in local data structures
+ * already.
+ */
+ winClipboardFlushXEvents (hwnd,
+ atomClipboard,
+ atomLocalProperty,
+ atomUTF8String,
+ atomCompoundText,
+ atomTargets,
+ atomDeleteWindow,
+ iWindow,
+ pDisplay,
+ fUnicodeSupport);
+
+ /* Pre-flush Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue (hwnd))
+ return 0;
+
+ /* Loop for X events */
+ while (1)
+ {
+ /* Setup the file descriptor set */
+ /*
+ * NOTE: You have to do this before every call to select
+ * because select modifies the mask to indicate
+ * which descriptors are ready.
+ */
+ FD_ZERO (&fdsRead);
+ FD_SET (fdMessageQueue, &fdsRead);
+ FD_SET (iConnectionNumber, &fdsRead);
+
+ /* Wait for a Windows event or an X event */
+ iReturn = select (iMaxDescriptor, /* Highest fds number */
+ &fdsRead, /* Read mask */
+ NULL, /* No write mask */
+ NULL, /* No exception mask */
+ NULL); /* No timeout */
+ if (iReturn <= 0)
+ {
+ ErrorF ("winClipboardProc - Call to select () failed: %d. "
+ "Bailing.\n", iReturn);
+ break;
+ }
+
+ /* Branch on which descriptor became active */
+ if (FD_ISSET (iConnectionNumber, &fdsRead))
+ {
+ /* X event ready */
+#if 0
+ ErrorF ("winClipboardProc - X event ready\n");
+#endif
+
+ /* Process X events */
+ /* Exit when we see that server is shutting down */
+ fReturn = winClipboardFlushXEvents (hwnd,
+ atomClipboard,
+ atomLocalProperty,
+ atomUTF8String,
+ atomCompoundText,
+ atomTargets,
+ atomDeleteWindow,
+ iWindow,
+ pDisplay,
+ fUnicodeSupport);
+ if (!fReturn)
+ {
+ ErrorF ("winClipboardProc - Caught WM_DELETE_WINDOW - "
+ "shutting down\n");
+ break;
+ }
+ }
+
+ /* Check for Windows event ready */
+ if (FD_ISSET (fdMessageQueue, &fdsRead))
+ {
+ /* Windows event ready */
+#if 0
+ ErrorF ("winClipboardProc - Windows event ready\n");
+#endif
+
+ /* Process Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue (hwnd))
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * winClipboardErrorHandler - Our application specific error handler
+ */
+
+static int
+winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr)
+{
+ char pszErrorMsg[100];
+
+ XGetErrorText (pDisplay,
+ pErr->error_code,
+ pszErrorMsg,
+ sizeof (pszErrorMsg));
+ ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n", pszErrorMsg);
+
+ if (pErr->error_code==BadWindow
+ || pErr->error_code==BadMatch
+ || pErr->error_code==BadDrawable)
+ {
+ pthread_exit (NULL);
+ }
+
+ pthread_exit (NULL);
+
+ return 0;
+}
+
+
+/*
+ * winClipboardIOErrorHandler - Our application specific IO error handler
+ */
+
+static int
+winClipboardIOErrorHandler (Display *pDisplay)
+{
+ printf ("\nwinClipboardIOErrorHandler!\n\n");
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xwin/winclipboardunicode.c b/xc/programs/Xserver/hw/xwin/winclipboardunicode.c
new file mode 100644
index 000000000..fdbcb8e69
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboardunicode.c
@@ -0,0 +1,68 @@
+/*
+ *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.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardunicode.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "win.h"
+
+
+/*
+ * Determine whether we suport Unicode or not.
+ * NOTE: Currently, just check if we are on an NT-based platform or not.
+ */
+
+Bool
+winClipboardDetectUnicodeSupport ()
+{
+ Bool fReturn = FALSE;
+ OSVERSIONINFO osvi;
+
+ /* Get operating system version information */
+ ZeroMemory (&osvi, sizeof (osvi));
+ osvi.dwOSVersionInfoSize = sizeof (osvi);
+ GetVersionEx (&osvi);
+
+ /* Branch on platform ID */
+ switch (osvi.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32_NT:
+ /* Engine 4 is supported on NT only */
+ ErrorF ("DetectUnicodeSupport - Windows NT/2000/XP\n");
+ fReturn = TRUE;
+ break;
+
+ case VER_PLATFORM_WIN32_WINDOWS:
+ /* Engine 4 is supported on NT only */
+ ErrorF ("DetectUnicodeSupport - Windows 95/98/Me\n");
+ fReturn = FALSE;
+ break;
+ }
+
+ return fReturn;
+}
diff --git a/xc/programs/Xserver/hw/xwin/winclipboardwndproc.c b/xc/programs/Xserver/hw/xwin/winclipboardwndproc.c
new file mode 100644
index 000000000..d27bb4861
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboardwndproc.c
@@ -0,0 +1,86 @@
+/*
+ *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.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardwndproc.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "winclipboard.h"
+
+
+/*
+ * Process a given Windows message
+ */
+
+LRESULT CALLBACK
+winClipboardWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_DESTROY:
+ PostQuitMessage (0);
+ return 0;
+
+ case WM_CREATE:
+#if 0
+ ErrorF ("WindowProc - WM_CREATE\n");
+#endif
+ return 0;
+ }
+
+ /* Let Windows perform default processing for unhandled messages */
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+
+/*
+ * Process any pending Windows messages
+ */
+
+BOOL
+winClipboardFlushWindowsMessageQueue (HWND hwnd)
+{
+ MSG msg;
+
+ /* Flush the messaging window queue */
+ /* NOTE: Do not pass the hwnd of our messaging window to PeekMessage,
+ * as this will filter out many non-window-specific messages that
+ * are sent to our thread, such as WM_QUIT.
+ */
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ /* Dispatch the message if not WM_QUIT */
+ if (msg.message == WM_QUIT)
+ return FALSE;
+ else
+ DispatchMessage (&msg);
+ }
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xwin/winclipboardxevents.c b/xc/programs/Xserver/hw/xwin/winclipboardxevents.c
new file mode 100644
index 000000000..a09c7c185
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winclipboardxevents.c
@@ -0,0 +1,722 @@
+/*
+ *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.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardxevents.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "winclipboard.h"
+
+
+/*
+ * Process any pending X events
+ */
+
+Bool
+winClipboardFlushXEvents (HWND hwnd,
+ Atom atomClipboard,
+ Atom atomLocalProperty,
+ Atom atomUTF8String,
+ Atom atomCompoundText,
+ Atom atomTargets,
+ Atom atomDeleteWindow,
+ int iWindow,
+ Display *pDisplay,
+ Bool fUnicodeSupport)
+{
+ Atom atomReturnType;
+ int iReturnFormat;
+ unsigned long ulReturnItems;
+ XTextProperty xtpText;
+ XEvent event;
+ XSelectionEvent eventSelection;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+ char *pszGlobalData = NULL;
+ int iReturn;
+ HGLOBAL hGlobal;
+ Bool fReturn = TRUE;
+ XICCEncodingStyle xiccesStyle;
+ int iUTF8;
+ char *pszUTF8 = NULL;
+ char *pszTextList[2];
+ int iCount;
+ char **ppszTextList = NULL;
+ wchar_t *pwszUnicodeStr = NULL;
+ int iUnicodeLen = 0;
+
+ /* Process all pending events */
+ while (XPending (pDisplay))
+ {
+ /* Get the next event - will not block because one is ready */
+ XNextEvent (pDisplay, &event);
+
+ /* Branch on the event type */
+ switch (event.type)
+ {
+ case ClientMessage:
+ if (event.xclient.data.l[0] == atomDeleteWindow)
+ {
+ ErrorF ("\nReceived WM_DELETE_WINDOW\n\n");
+ fReturn = FALSE;
+ }
+ else
+ ErrorF ("\nUnknown ClientMessage\n\n");
+ break;
+
+ case SelectionClear:
+ /* Request the lost selection contents */
+ iReturn = XConvertSelection (pDisplay,
+ event.xselectionclear.selection,
+ atomCompoundText,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionClear - XConvertSelection () failed\n");
+ pthread_exit (NULL);
+ }
+ break;
+
+
+ /*
+ * SelectionRequest
+ */
+
+ case SelectionRequest:
+#if 0
+ char *pszAtomName = NULL
+
+ ErrorF ("SelectionRequest - target %d\n",
+ event.xselectionrequest.target);
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselectionrequest.target);
+ ErrorF ("SelectionRequest - Target atom name %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+#endif
+
+ /* Abort if invalid target type */
+ if (event.xselectionrequest.target != XA_STRING
+ && event.xselectionrequest.target != atomUTF8String
+ && event.xselectionrequest.target != atomCompoundText
+ && event.xselectionrequest.target != atomTargets)
+ {
+ /* Setup selection notify event */
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = pDisplay;
+ eventSelection.requestor = event.xselectionrequest.requestor;
+ eventSelection.selection = event.xselectionrequest.selection;
+ eventSelection.target = event.xselectionrequest.target;
+ eventSelection.property = None;
+ eventSelection.time = event.xselectionrequest.time;
+
+ /* Notify the requesting window that the operation is complete */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionRequest - XSendEvent () failed\n");
+ pthread_exit (NULL);
+ }
+
+ break;
+ }
+
+ /* Handle targets type of request */
+ if (event.xselectionrequest.target == atomTargets)
+ {
+ Atom atomTargetArr[4] = {atomTargets,
+ atomCompoundText,
+ atomUTF8String,
+ XA_STRING};
+
+ /* Try to change the property */
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ event.xselectionrequest.target,
+ 8,
+ PropModeReplace,
+ (char *) atomTargetArr,
+ sizeof (atomTargetArr));
+ if (iReturn == BadAlloc
+ || iReturn == BadAtom
+ || iReturn == BadMatch
+ || iReturn == BadValue
+ || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionRequest - XChangeProperty failed: %d\n",
+ iReturn);
+ }
+
+ /* Setup selection notify xevent */
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = pDisplay;
+ eventSelection.requestor = event.xselectionrequest.requestor;
+ eventSelection.selection = event.xselectionrequest.selection;
+ eventSelection.target = event.xselectionrequest.target;
+ eventSelection.property = event.xselectionrequest.property;
+ eventSelection.time = event.xselectionrequest.time;
+
+ /*
+ * Notify the requesting window that
+ * the operation has completed
+ */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionRequest - XSendEvent () failed\n");
+ }
+ break;
+ }
+
+ /* Access the clipboard */
+ if (!OpenClipboard (hwnd))
+ {
+ ErrorF ("SelectionRequest - OpenClipboard () failed: %08x\n",
+ GetLastError ());
+ pthread_exit (NULL);
+ }
+
+ /* Setup the string style */
+ if (event.xselectionrequest.target == XA_STRING)
+ xiccesStyle = XStringStyle;
+ else if (event.xselectionrequest.target == atomUTF8String)
+ xiccesStyle = XUTF8StringStyle;
+ else if (event.xselectionrequest.target == atomCompoundText)
+ xiccesStyle = XCompoundTextStyle;
+ else
+ xiccesStyle = XStringStyle;
+
+ /*
+ * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me
+ */
+
+ /* Get a pointer to the clipboard text */
+ if (fUnicodeSupport)
+ hGlobal = GetClipboardData (CF_UNICODETEXT);
+ else
+ hGlobal = GetClipboardData (CF_TEXT);
+ if (!hGlobal)
+ {
+ ErrorF ("SelectionRequest - GetClipboardData () failed: %08x\n",
+ GetLastError ());
+ pthread_exit (NULL);
+ }
+ pszGlobalData = (char *) GlobalLock (hGlobal);
+
+ /* Convert the Unicode string to UTF8 (MBCS) */
+ if (fUnicodeSupport)
+ {
+ iUTF8 = WideCharToMultiByte (CP_UTF8,
+ 0,
+ (LPCWSTR)pszGlobalData,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ pszUTF8 = (char *) malloc (iUTF8); /* Don't need +1 */
+ WideCharToMultiByte (CP_UTF8,
+ 0,
+ (LPCWSTR)pszGlobalData,
+ -1,
+ pszUTF8,
+ iUTF8,
+ NULL,
+ NULL);
+ }
+
+ /* Convert DOS string to UNIX string */
+ if (fUnicodeSupport)
+ {
+ winClipboardDOStoUNIX (pszUTF8, strlen (pszUTF8));
+
+ /* Setup our text list */
+ pszTextList[0] = pszUTF8;
+ pszTextList[1] = NULL;
+
+ /* Initialize the text property */
+ xtpText.value = NULL;
+
+ /* Create the text property from the text list */
+ iReturn = Xutf8TextListToTextProperty (pDisplay,
+ pszTextList,
+ 1,
+ xiccesStyle,
+ &xtpText);
+ if (iReturn == XNoMemory || iReturn == XLocaleNotSupported)
+ {
+ ErrorF ("SelectionRequest - Xutf8TextListToTextProperty "
+ "failed: %d\n",
+ iReturn);
+ exit(1);
+ }
+
+ /* Free the UTF8 string */
+ free (pszUTF8);
+ }
+ else
+ winClipboardDOStoUNIX (pszGlobalData, strlen (pszGlobalData));
+
+ /*
+ * FIXME: Pass pszGlobalData and strlen (pszGlobalData(
+ * on 1 byte, pass xtpText.value and xtpText.nitems
+ * on 2 byte.
+ */
+
+ /* Copy the clipboard text to the requesting window */
+ if (fUnicodeSupport)
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ event.xselectionrequest.target,
+ 8,
+ PropModeReplace,
+ xtpText.value,
+ xtpText.nitems);
+ else
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ event.xselectionrequest.target,
+ 8,
+ PropModeReplace,
+ pszGlobalData,
+ strlen (pszGlobalData));
+ if (iReturn == BadAlloc || iReturn == BadAtom
+ || iReturn == BadMatch || iReturn == BadValue
+ || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionRequest - XChangeProperty failed: %d\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+
+ /* Release the clipboard data */
+ GlobalUnlock (hGlobal);
+ pszGlobalData = NULL;
+ CloseClipboard ();
+
+ /* FIXME: Don't clean up on 1 byte. */
+ if (fUnicodeSupport)
+ {
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ }
+
+ /* Setup selection notify event */
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = pDisplay;
+ eventSelection.requestor = event.xselectionrequest.requestor;
+ eventSelection.selection = event.xselectionrequest.selection;
+ eventSelection.target = event.xselectionrequest.target;
+ eventSelection.property = event.xselectionrequest.property;
+ eventSelection.time = event.xselectionrequest.time;
+
+ /* Notify the requesting window that the operation has completed */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionRequest - XSendEvent () failed\n");
+ pthread_exit (NULL);
+ }
+ break;
+
+
+ /*
+ * SelectionNotify
+ */
+
+ case SelectionNotify:
+#if 0
+ ErrorF ("SelectionNotify\n");
+#endif
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+
+ ErrorF ("SelectionNotify - ATOM: %s\n",
+ pszAtomName);
+
+ XFree (pszAtomName);
+ }
+
+#if 0
+ /*
+ * TEMP: Bail if selection is anything other than CLIPBOARD
+ */
+
+ if (event.xselection.selection != atomClipboard)
+ break;
+#endif
+
+ /*
+ *
+ * What are we doing here?
+ *
+ */
+ if (fUnicodeSupport)
+ {
+ if (event.xselection.property == None)
+ {
+ if(event.xselection.target == XA_STRING)
+ {
+#if 0
+ ErrorF ("SelectionNotify XA_STRING\n");
+#endif
+ return fReturn;
+ }
+ else if (event.xselection.target == atomUTF8String)
+ {
+ ErrorF ("SelectionNotify UTF8\n");
+ iReturn = XConvertSelection (pDisplay,
+ event.xselection.selection,
+ XA_STRING,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionNotify - XConvertSelection () "
+ "failed\n");
+ pthread_exit (NULL);
+ }
+ return fReturn;
+ }
+ else if (event.xselection.target == atomCompoundText)
+ {
+ ErrorF ("SelectionNotify CompoundText\n");
+ iReturn = XConvertSelection (pDisplay,
+ event.xselection.selection,
+ atomUTF8String,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("SelectionNotify - XConvertSelection () "
+ "failed\n");
+ pthread_exit (NULL);
+ }
+ return fReturn;
+ }
+ else
+ {
+ ErrorF("Unknown format\n");
+ return fReturn;
+ }
+ }
+ }
+
+ /* Retrieve the size of the stored data */
+ if (fUnicodeSupport)
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ 0, /* Don't get data, just size */
+ False,
+ AnyPropertyType,
+ &xtpText.encoding,
+ &xtpText.format,
+ &xtpText.nitems,
+ &ulReturnBytesLeft,
+ &xtpText.value);
+ else
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ 0, /* Don't get data, just size */
+ False,
+ AnyPropertyType,
+ &atomReturnType,
+ &iReturnFormat,
+ &ulReturnItems,
+ &ulReturnBytesLeft,
+ &pszReturnData);
+ if (iReturn != Success)
+ {
+ ErrorF ("SelectionNotify - XGetWindowProperty () failed\n");
+ pthread_exit (NULL);
+ }
+
+#if 0
+ if (fUnicodeSupport)
+ ErrorF ("SelectionNotify - returned data %d left %d\n",
+ xtpText.nitems, ulReturnBytesLeft);
+ else
+ ErrorF ("SelectionNotify - returned data %d left %d\n",
+ ulReturnItems, ulReturnBytesLeft);
+#endif
+
+ /* Request the selection data */
+ if (fUnicodeSupport)
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ ulReturnBytesLeft,
+ False,
+ AnyPropertyType,
+ &xtpText.encoding,
+ &xtpText.format,
+ &xtpText.nitems,
+ &ulReturnBytesLeft,
+ &xtpText.value);
+ else
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ ulReturnBytesLeft,
+ False,
+ AnyPropertyType,
+ &atomReturnType,
+ &iReturnFormat,
+ &ulReturnItems,
+ &ulReturnBytesLeft,
+ &pszReturnData);
+ if (iReturn != Success)
+ {
+ ErrorF ("SelectionNotify - XGetWindowProperty () failed\n");
+ pthread_exit (NULL);
+ }
+
+ if (fUnicodeSupport)
+ {
+#if 0
+ char *pszAtomName = NULL;
+
+ ErrorF ("SelectionNotify - returned data %d left %d\n",
+ prop.nitems, ulReturnBytesLeft);
+
+ pszAtomName = XGetAtomName(pDisplay, prop.encoding);
+ ErrorF ("Notify atom name %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+#endif
+
+ /* Convert the text property to a text list */
+ Xutf8TextPropertyToTextList (pDisplay,
+ &xtpText,
+ &ppszTextList,
+ &iCount);
+ if (iCount > 0)
+ {
+ pszReturnData = malloc (strlen (ppszTextList[0]) + 1);
+ strcpy (pszReturnData, ppszTextList[0]);
+ }
+ else
+ {
+ pszReturnData = malloc (1);
+ pszReturnData[0] = 0;
+ }
+
+ /* Free the data returned from XGetWindowProperty */
+ XFreeStringList (ppszTextList);
+ XFree (xtpText.value);
+ }
+
+ /* Convert the X clipboard string to DOS format */
+ winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData));
+
+ if (fUnicodeSupport)
+ {
+ /* Find out how much space needed to convert MBCS to Unicode */
+ iUnicodeLen = MultiByteToWideChar (CP_UTF8,
+ 0,
+ pszReturnData,
+ -1,
+ NULL,
+ 0);
+
+ /* Allocate memory for the Unicode string */
+ pwszUnicodeStr
+ = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1));
+
+ /* Do the actual conversion */
+ MultiByteToWideChar (CP_UTF8,
+ 0,
+ pszReturnData,
+ -1,
+ pwszUnicodeStr,
+ iUnicodeLen);
+ }
+
+ /* Access the Windows clipboard */
+ if (!OpenClipboard (hwnd))
+ {
+ ErrorF ("OpenClipboard () failed: %08x\n", GetLastError ());
+ pthread_exit (NULL);
+ }
+
+ /* Take ownership of the Window clipboard */
+ if (!EmptyClipboard ())
+ {
+ ErrorF ("EmptyClipboard () failed: %08x\n", GetLastError ());
+ pthread_exit (NULL);
+ }
+
+ /* Allocate global memory for the X clipboard data */
+ if (fUnicodeSupport)
+ hGlobal = GlobalAlloc (GMEM_MOVEABLE,
+ sizeof (wchar_t) * (iUnicodeLen + 1));
+ else
+ hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen (pszReturnData) + 1);
+
+ /* Obtain a pointer to the global memory */
+ pszGlobalData = GlobalLock (hGlobal);
+ if (pszGlobalData == NULL)
+ {
+ ErrorF ("Could not lock global memory for clipboard transfer\n");
+ pthread_exit (NULL);
+ }
+
+ /* Copy the returned string into the global memory */
+ if (fUnicodeSupport)
+ memcpy (pszGlobalData,
+ pwszUnicodeStr,
+ sizeof (wchar_t) * (iUnicodeLen + 1));
+ else
+ strcpy (pszGlobalData, pszReturnData);
+
+ /* Free the data returned from XGetWindowProperty */
+ if (fUnicodeSupport)
+ {
+ free (pwszUnicodeStr);
+ pwszUnicodeStr = NULL;
+ }
+ else
+ {
+ XFree (pszReturnData);
+ pszReturnData = NULL;
+ }
+
+ /* Release the pointer to the global memory */
+ GlobalUnlock (hGlobal);
+ pszGlobalData = NULL;
+
+ /* Push the selection data to the Windows clipboard */
+ if (fUnicodeSupport)
+ SetClipboardData (CF_UNICODETEXT, hGlobal);
+ else
+ SetClipboardData (CF_TEXT, hGlobal);
+
+ /*
+ * NOTE: Do not try to free pszGlobalData, it is owned by
+ * Windows after the call to SetClipboardData ().
+ */
+
+ /* Release the clipboard */
+ if (!CloseClipboard ())
+ {
+ ErrorF ("CloseClipboard () failed: %08x\n", GetLastError ());
+ pthread_exit (NULL);
+ }
+
+ /* Reassert ownership of the selection */
+ iReturn = XSetSelectionOwner (pDisplay,
+ event.xselection.selection,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ char *pszAtomName = NULL;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+ ErrorF ("SelectionNotify - Could not reassert ownership "
+ "of selection ATOM: %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+ pthread_exit (NULL);
+ }
+ else
+ {
+#if 0
+ char *pszAtomName = NULL;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+ ErrorF ("SelectionNotify - Reasserted ownership of ATOM: %s\n",
+ pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+#endif
+ }
+#if 0
+ /* Reassert ownership of the CLIPBOARD */
+ iReturn = XSetSelectionOwner (pDisplay,
+ atomClipboard,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("Could not reassert ownership of selection\n");
+ pthread_exit (NULL);
+ }
+#endif
+ break;
+
+#if 0
+ case CreateNotify:
+ ErrorF ("FlushXEvents - CreateNotify parent: %ld\twindow: %ld\n",
+ event.xcreatewindow.parent, event.xcreatewindow.window);
+ break;
+
+ case DestroyNotify:
+ ErrorF ("FlushXEvents - DestroyNotify window: %ld\tevent: %ld\n",
+ event.xdestroywindow.window, event.xdestroywindow.event);
+ break;
+#endif
+
+ default:
+ break;
+ }
+ }
+
+ return fReturn;
+}
diff --git a/xc/programs/Xserver/hw/xwin/wincreatewnd.c b/xc/programs/Xserver/hw/xwin/wincreatewnd.c
index 300a8f447..3c725f248 100644
--- a/xc/programs/Xserver/hw/xwin/wincreatewnd.c
+++ b/xc/programs/Xserver/hw/xwin/wincreatewnd.c
@@ -27,7 +27,7 @@
*
* Authors: Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/wincreatewnd.c,v 1.4 2002/10/17 08:18:22 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/wincreatewnd.c,v 1.5 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
#include "shellapi.h"
@@ -38,6 +38,9 @@
*/
static Bool
+winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo);
+
+static Bool
winAdjustForAutoHide (RECT *prcWorkArea);
@@ -65,7 +68,7 @@ winCreateBoundingWindowFullScreen (ScreenPtr pScreen)
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInstance;
- wc.hIcon = LoadIcon (g_hInstance, IDI_XWIN);
+ wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
wc.hCursor = 0;
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
@@ -119,20 +122,25 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- int iWidth = pScreenInfo->dwWidth;
- int iHeight = pScreenInfo->dwHeight;
+ int iWidth = pScreenInfo->dwUserWidth;
+ int iHeight = pScreenInfo->dwUserHeight;
HWND *phwnd = &pScreenPriv->hwndScreen;
WNDCLASS wc;
RECT rcClient, rcWorkArea;
DWORD dwWindowStyle;
- ErrorF ("winCreateBoundingWindowWindowed - Initial w: %d h: %d\n",
- iWidth, iHeight);
+ ErrorF ("winCreateBoundingWindowWindowed - User w: %d h: %d\n",
+ pScreenInfo->dwUserWidth, pScreenInfo->dwUserHeight);
+ ErrorF ("winCreateBoundingWindowWindowed - Current w: %d h: %d\n",
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight);
+ /* Set the common window style flags */
dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
/* Decorated or undecorated window */
- if (pScreenInfo->fDecoration && !pScreenInfo->fRootless)
+ if (pScreenInfo->fDecoration
+ && !pScreenInfo->fRootless
+ && !pScreenInfo->fMultiWindow)
{
dwWindowStyle |= WS_CAPTION;
if (pScreenInfo->fScrollbars)
@@ -147,7 +155,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInstance;
- wc.hIcon = LoadIcon (g_hInstance, IDI_XWIN);
+ wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
@@ -155,7 +163,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
RegisterClass (&wc);
/* Get size of work area */
- SystemParametersInfo (SPI_GETWORKAREA, 0, &rcWorkArea, 0);
+ winGetWorkArea (&rcWorkArea, pScreenInfo);
/* Adjust for auto-hide taskbars */
winAdjustForAutoHide (&rcWorkArea);
@@ -170,7 +178,9 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
#endif
/* Adjust the window width and height for borders and title bar */
- if (pScreenInfo->fDecoration && !pScreenInfo->fRootless)
+ if (pScreenInfo->fDecoration
+ && !pScreenInfo->fRootless
+ && !pScreenInfo->fMultiWindow)
{
#if CYGDEBUG
ErrorF ("winCreateBoundingWindowWindowed - Window has decoration\n");
@@ -206,8 +216,16 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
* In this case we have to ignore the requested width and height
* and instead use the largest possible window that we can.
*/
- iWidth = GetSystemMetrics (SM_CXSCREEN);
- iHeight = GetSystemMetrics (SM_CYSCREEN);
+ if (pScreenInfo->fMultipleMonitors)
+ {
+ iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
+ else
+ {
+ iWidth = GetSystemMetrics (SM_CXSCREEN);
+ iHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
}
}
else
@@ -217,10 +235,18 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
ErrorF ("winCreateBoundingWindowWindowed - User did not give "
"height and width\n");
#endif
+ /* Defaults are wrong if we have multiple monitors */
+ if (pScreenInfo->fMultipleMonitors)
+ {
+ iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ }
}
/* Clean up the scrollbars flag, if necessary */
- if ((!pScreenInfo->fDecoration || pScreenInfo->fRootless)
+ if ((!pScreenInfo->fDecoration
+ || pScreenInfo->fRootless
+ || pScreenInfo->fMultiWindow)
&& pScreenInfo->fScrollbars)
{
/* We cannot have scrollbars if we do not have a window border */
@@ -342,7 +368,10 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
#endif
/* Show the window */
- ShowWindow (*phwnd, SW_SHOWNORMAL);
+ if (pScreenInfo->fMultiWindow)
+ ShowWindow (*phwnd, SW_SHOWMINNOACTIVE);
+ else
+ ShowWindow (*phwnd, SW_SHOWNORMAL);
if (!UpdateWindow (*phwnd))
{
ErrorF ("winCreateBoundingWindowWindowed - UpdateWindow () failed\n");
@@ -368,6 +397,77 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen)
/*
+ * Find the work area of all attached monitors
+ */
+
+static Bool
+winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo)
+{
+ int iPrimaryWidth, iPrimaryHeight;
+ int iWidth, iHeight;
+ int iLeft, iTop;
+ int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight;
+
+ /* SPI_GETWORKAREA only gets the work area of the primary screen. */
+ SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0);
+
+ /* Bail out here if we aren't using multiple monitors */
+ if (!pScreenInfo->fMultipleMonitors)
+ return TRUE;
+
+ ErrorF ("winGetWorkArea - Original WorkArea: %d %d %d %d\n",
+ prcWorkArea->top, prcWorkArea->left,
+ prcWorkArea->bottom, prcWorkArea->right);
+
+ /* Get size of full virtual screen */
+ iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+
+ ErrorF ("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight);
+
+ /* Get origin of full virtual screen */
+ iLeft = GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iTop = GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ ErrorF ("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop);
+
+ /* Get size of primary screen */
+ iPrimaryWidth = GetSystemMetrics (SM_CXSCREEN);
+ iPrimaryHeight = GetSystemMetrics (SM_CYSCREEN);
+
+ ErrorF ("winGetWorkArea - Primary screen is %d x %d\n",
+ iPrimaryWidth, iPrimaryHeight);
+
+ /* Work out how much of the primary screen we aren't using */
+ iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right -
+ prcWorkArea->left);
+ iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom
+ - prcWorkArea->top);
+
+ /* Update the rectangle to include all monitors */
+ if (iLeft < 0)
+ {
+ prcWorkArea->left = iLeft;
+ }
+ if (iTop < 0)
+ {
+ prcWorkArea->top = iTop;
+ }
+ prcWorkArea->right = prcWorkArea->left + iWidth -
+ iPrimaryNonWorkAreaWidth;
+ prcWorkArea->bottom = prcWorkArea->top + iHeight -
+ iPrimaryNonWorkAreaHeight;
+
+ ErrorF ("winGetWorkArea - Adjusted WorkArea for multiple "
+ "monitors: %d %d %d %d\n",
+ prcWorkArea->top, prcWorkArea->left,
+ prcWorkArea->bottom, prcWorkArea->right);
+
+ return TRUE;
+}
+
+
+/*
* Adjust the client area so that any auto-hide toolbars
* will work correctly.
*/
diff --git a/xc/programs/Xserver/hw/xwin/winengine.c b/xc/programs/Xserver/hw/xwin/winengine.c
index 6324c8fe2..aff90bdaf 100644
--- a/xc/programs/Xserver/hw/xwin/winengine.c
+++ b/xc/programs/Xserver/hw/xwin/winengine.c
@@ -27,7 +27,7 @@
*
* Authors: Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winengine.c,v 1.3 2002/07/05 09:19:26 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winengine.c,v 1.4 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -174,6 +174,17 @@ winSetEngine (ScreenPtr pScreen)
return TRUE;
}
+ /* ShadowGDI is the only engine that supports Multi Window Mode */
+ if (pScreenInfo->fMultiWindow)
+ {
+ ErrorF ("winSetEngine - Multi Window => ShadowGDI\n");
+ pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI;
+
+ /* Set engine function pointers */
+ winSetEngineFunctionsShadowGDI (pScreen);
+ return TRUE;
+ }
+
/* If the user's choice is supported, we'll use that */
if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred)
{
diff --git a/xc/programs/Xserver/hw/xwin/winerror.c b/xc/programs/Xserver/hw/xwin/winerror.c
index d9ae1918b..c18f10dde 100644
--- a/xc/programs/Xserver/hw/xwin/winerror.c
+++ b/xc/programs/Xserver/hw/xwin/winerror.c
@@ -27,7 +27,7 @@
*
* Authors: Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winerror.c,v 1.3 2001/10/23 22:22:47 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winerror.c,v 1.4 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -37,14 +37,22 @@ extern FILE *g_pfLog;
void
OsVendorVErrorF (const char *pszFormat, va_list va_args)
{
+ static pthread_mutex_t s_pmPrinting = PTHREAD_MUTEX_INITIALIZER;
+
/* Check we opened the log file first */
if (g_pfLog == NULL) return;
+ /* Lock the printing mutex */
+ pthread_mutex_lock (&s_pmPrinting);
+
/* Print the error message to a log file, could be stderr */
vfprintf (g_pfLog, pszFormat, va_args);
/* Flush after every write, to make updates show up quickly */
fflush (g_pfLog);
+
+ /* Unlock the printing mutex */
+ pthread_mutex_unlock (&s_pmPrinting);
}
#endif
diff --git a/xc/programs/Xserver/hw/xwin/winlayer.c b/xc/programs/Xserver/hw/xwin/winlayer.c
index f9c320651..9d03dbf74 100644
--- a/xc/programs/Xserver/hw/xwin/winlayer.c
+++ b/xc/programs/Xserver/hw/xwin/winlayer.c
@@ -27,7 +27,7 @@
*
* Authors: Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winlayer.c,v 1.8 2002/07/05 09:19:26 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winlayer.c,v 1.9 2002/10/31 23:04:39 alanh Exp $ */
#include "win.h"
@@ -109,8 +109,6 @@ winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
int n;
- RRVisualGroupPtr pVisualGroup;
- RRGroupOfVisualGroupPtr pGroupOfVisualGroup = NULL;
Rotation rotateKind;
RRScreenSizePtr pSize;
@@ -119,51 +117,14 @@ winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
/* Don't support rotations, yet */
*pRotations = RR_Rotate_0; /* | RR_Rotate_90 | RR_Rotate_180 | ... */
+#if 0
/* Check for something naughty. Don't know what exactly... */
for (n = 0; n < pScreen->numDepths; n++)
if (pScreen->allowedDepths[n].numVids)
break;
if (n == pScreen->numDepths)
return FALSE;
-
- /* Create an RandR visual group */
- pVisualGroup = RRCreateVisualGroup (pScreen);
- if (!pVisualGroup)
- return FALSE;
-
-
- /* Not sure what this does */
- if (!RRAddDepthToVisualGroup (pScreen,
- pVisualGroup,
- &pScreen->allowedDepths[n]))
- {
- RRDestroyVisualGroup (pScreen, pVisualGroup);
- return FALSE;
- }
-
- /* Register the RandR visual group */
- pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup);
- if (!pVisualGroup)
- return FALSE;
-
- pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen,
- pGroupOfVisualGroup);
-
- /* You have to be kidding */
- if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen,
- pGroupOfVisualGroup,
- pVisualGroup))
- {
- RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup);
- /* pVisualGroup left until screen closed */
- return FALSE;
- }
-
- /* I can't afford a clue */
- pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen,
- pGroupOfVisualGroup);
- if (!pGroupOfVisualGroup)
- return FALSE;
+#endif
/*
* Register supported sizes. This can be called many times, but
@@ -173,14 +134,13 @@ winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
pScreenInfo->dwWidth,
pScreenInfo->dwHeight,
pScreenInfo->dwWidth_mm,
- pScreenInfo->dwHeight_mm,
- pGroupOfVisualGroup);
+ pScreenInfo->dwHeight_mm);
/* Only one allowed rotation for now */
rotateKind = RR_Rotate_0;
-
+
/* Tell RandR what the current config is */
- RRSetCurrentConfig (pScreen, rotateKind, pSize, pVisualGroup);
+ RRSetCurrentConfig (pScreen, rotateKind, pSize);
return TRUE;
}
@@ -193,8 +153,7 @@ winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
Bool
winRandRSetConfig (ScreenPtr pScreen,
Rotation rotateKind,
- RRScreenSizePtr pSize,
- RRVisualGroupPtr pVisualGroup)
+ RRScreenSizePtr pSize)
{
ErrorF ("winRandRSetConfig ()\n");
diff --git a/xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c b/xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c
new file mode 100644
index 000000000..57d209e2a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c
@@ -0,0 +1,1574 @@
+/*
+ *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.
+ *
+ * Authors: Kensuke Matsuzaki
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowwindow.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+#include "win.h"
+#include "dixevents.h"
+
+
+/*
+ * Prototypes for local functions
+ */
+
+static void
+winCreateWindowsWindow (WindowPtr pWin);
+
+static void
+winDestroyWindowsWindow (WindowPtr pWin);
+
+static void
+winUpdateWindowsWindow (WindowPtr pWin);
+
+static XID
+winGetWindowID (WindowPtr pWin);
+
+static void
+SendConfigureNotify (WindowPtr pWin);
+
+static
+void
+winUpdateRgn (WindowPtr pWindow);
+
+#ifdef SHAPE
+static
+void
+winReshape (WindowPtr pWin);
+#endif
+
+
+/*
+ * Local globals
+ */
+
+static UINT s_nIDPollingMouse = 2;
+
+#if 0
+static BOOL s_fMoveByX = FALSE;
+#endif
+
+
+/*
+ * Constant defines
+ */
+
+
+#define MOUSE_POLLING_INTERVAL 500
+#define WIN_MULTIWINDOW_SHAPE YES
+
+/*
+ * Macros
+ */
+
+#define SubSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * CreateWindow - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winCreateWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winCreateWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped CreateWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow)
+ fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow (pWin);
+
+ /* Initialize some privates values */
+ pWinPriv->hRgn = NULL;
+ pWinPriv->hWnd = NULL;
+ pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
+ pWinPriv->fXKilled = FALSE;
+
+ return fResult;
+}
+
+
+/*
+ * DestroyWindow - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winDestroyWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winDestroyWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped DestroyWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow)
+ fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow (pWin);
+
+ /* Flag that the window has been destroyed */
+ pWinPriv->fXKilled = TRUE;
+
+ /* Kill the MS Windows window associated with this window */
+ winDestroyWindowsWindow (pWin);
+
+ return fResult;
+}
+
+
+/*
+ * PositionWindow - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
+{
+ Bool fResult = TRUE;
+ int iX, iY, iWidth, iHeight, iBorder;
+ winWindowPriv(pWin);
+ HWND hWnd = pWinPriv->hWnd;
+ RECT rcNew;
+ RECT rcOld;
+#if CYGMULTIWINDOW_DEBUG
+ RECT rcClient;
+ RECT *lpRc;
+#endif
+ DWORD dwExStyle;
+ DWORD dwStyle;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winPositionWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped PositionWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow)
+ fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow (pWin, x, y);
+
+ /* Bail out if the Windows window handle is bad */
+ if (!hWnd)
+ return fResult;
+
+ /* Get the Windows window style and extended style */
+ dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
+
+ /* Get the width of the X window border */
+ iBorder = wBorderWidth (pWin);
+
+ /* Get the X and Y location of the X window */
+ iX = pWin->drawable.x;
+ iY = pWin->drawable.y;
+
+ /* Get the height and width of the X window */
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Store the origin, height, and width in a rectangle structure */
+ SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
+
+#if CYGMULTIWINDOW_DEBUG
+ lpRc = &rcNew;
+ ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+#endif
+
+ /*
+ * Calculate the required size of the Windows window rectangle,
+ * given the size of the Windows window client area.
+ */
+ AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
+
+ /* Get a rectangle describing the old Windows window */
+ GetWindowRect (hWnd, &rcOld);
+
+#if CYGMULTIWINDOW_DEBUG
+ /* Get a rectangle describing the Windows window client area */
+ GetClientRect (hWnd, &rcClient);
+
+ lpRc = &rcNew;
+ ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+
+ lpRc = &rcOld;
+ ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+
+ lpRc = &rcClient;
+ ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+#endif
+
+ /* Check if the old rectangle and new rectangle are the same */
+ if (!EqualRect (&rcNew, &rcOld))
+ {
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winPositionWindowMultiWindow - Need to move\n");
+#endif
+
+ /* Change the position and dimensions of the Windows window */
+ MoveWindow (hWnd,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ TRUE);
+ }
+ else
+ {
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
+#endif
+ }
+
+ return fResult;
+}
+
+
+/*
+ * ChangeWindowAttributes - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
+{
+ Bool fResult = TRUE;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped ChangeWindowAttributes function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes)
+ fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes (pWin, mask);
+
+ /*
+ * NOTE: We do not currently need to do anything here.
+ */
+
+ return fResult;
+}
+
+
+/*
+ * UnmapWindow - See Porting Layer Definition - p. 37
+ * Also referred to as UnrealizeWindow
+ */
+
+Bool
+winUnmapWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped UnrealizeWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow)
+ fResult = winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow (pWin);
+
+ /* Flag that the window has been killed */
+ pWinPriv->fXKilled = TRUE;
+
+ /* Destroy the Windows window associated with this X window */
+ winDestroyWindowsWindow (pWin);
+
+ return fResult;
+}
+
+
+/*
+ * MapWindow - See Porting Layer Definition - p. 37
+ * Also referred to as RealizeWindow
+ */
+
+Bool
+winMapWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped RealizeWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow)
+ fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow (pWin);
+
+ /* Flag that this window has not been destroyed */
+ pWinPriv->fXKilled = FALSE;
+
+ /* Refresh/redisplay the Windows window associated with this X window */
+ winUpdateWindowsWindow (pWin);
+
+#if WIN_MULTIWINDOW_SHAPE
+ winReshape (pWin);
+ winUpdateRgn (pWin);
+#endif
+
+ return fResult;
+}
+
+
+/*
+ * ReparentWindow - See Porting Layer Definition - p. 42
+ */
+
+void
+winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
+{
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped ReparentWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow)
+ winGetScreenPriv(pWin->drawable.pScreen)->ReparentWindow (pWin,
+ pPriorParent);
+
+ /* Update the Windows window associated with this X window */
+ winUpdateWindowsWindow (pWin);
+}
+
+
+/*
+ * RestackWindow - Shuffle the z-order of a window
+ */
+
+void
+winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
+{
+ WindowPtr pPrevWin;
+ UINT uFlags;
+ HWND hInsertAfter;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winRestackMultiWindow - %08x\n", pWin);
+#endif
+
+ /* Call any wrapped RestackWindow function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow)
+ winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow (pWin,
+ pOldNextSib);
+
+ /* Bail out if no window privates or window handle is invalid */
+ if (!pWinPriv || !pWinPriv->hWnd)
+ return;
+
+ /* Get a pointer to our previous sibling window */
+ pPrevWin = pWin->prevSib;
+
+ /*
+ * Look for a sibling window with
+ * valid privates and window handle
+ */
+ while (pPrevWin
+ && !winGetWindowPriv(pPrevWin)
+ && !winGetWindowPriv(pPrevWin)->hWnd)
+ pPrevWin = pPrevWin->prevSib;
+
+ /* Check if we found a valid sibling */
+ if (pPrevWin)
+ {
+ /* Valid sibling - get handle to insert window after */
+ hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
+ uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+ }
+ else
+ {
+ /* No valid sibling - make this window the top window */
+ hInsertAfter = HWND_TOP;
+ uFlags = SWP_NOMOVE | SWP_NOSIZE;
+ }
+
+ /* Perform the restacking operation in Windows */
+ SetWindowPos (pWinPriv->hWnd,
+ hInsertAfter,
+ 0, 0,
+ 0, 0,
+ uFlags);
+}
+
+
+/*
+ * SetShape - See Porting Layer Definition - p. 42
+ */
+
+#ifdef SHAPE
+void
+winSetShapeMultiWindow (WindowPtr pWin)
+{
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ /* Call any wrapped SetShape function */
+ if (winGetScreenPriv(pWin->drawable.pScreen)->SetShape)
+ winGetScreenPriv(pWin->drawable.pScreen)->SetShape (pWin);
+
+ /*
+ * NOTE: We do not currently do anything here.
+ */
+
+#if WIN_MULTIWINDOW_SHAPE
+ winReshape (pWin);
+ winUpdateRgn (pWin);
+#endif
+
+ return;
+}
+#endif
+
+
+/*
+ * winUpdateRgn - Local function to update a Windows window region
+ */
+
+static
+void
+winUpdateRgn (WindowPtr pWin)
+{
+#if 1
+ SetWindowRgn (winGetWindowPriv(pWin)->hWnd,
+ winGetWindowPriv(pWin)->hRgn, TRUE);
+#endif
+}
+
+
+/*
+ * winReshape - Computes the composite clipping region for a window
+ */
+
+#ifdef SHAPE
+static
+void
+winReshape (WindowPtr pWin)
+{
+ int nRects;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RegionRec rrNewShape;
+ BoxPtr pShape, pRects, pEnd;
+ HRGN hRgn, hRgnRect;
+ winWindowPriv(pWin);
+
+#if CYGDEBUG
+ ErrorF ("winReshape ()\n");
+#endif
+
+ /* Bail if the window is the root window */
+ if (pWin->parent == NULL)
+ return;
+
+ /* Bail if the window is not top level */
+ if (pWin->parent->parent != NULL)
+ return;
+
+ /* Bail if Windows window handle is invalid */
+ if (pWinPriv->hWnd == NULL)
+ return;
+
+ /* Free any existing window region stored in the window privates */
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject (pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
+ /* Bail if the window has no bounding region defined */
+ if (!wBoundingShape (pWin))
+ return;
+
+ REGION_INIT(pScreen, &rrNewShape, NullBox, 0);
+ REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin));
+ REGION_TRANSLATE(pScreen,
+ &rrNewShape,
+ pWin->borderWidth,
+ pWin->borderWidth);
+
+ nRects = REGION_NUM_RECTS(&rrNewShape);
+ pShape = REGION_RECTS(&rrNewShape);
+
+ /* Don't do anything if there are no rectangles in the region */
+ if (nRects > 0)
+ {
+ RECT rcClient;
+ RECT rcWindow;
+ int iOffsetX, iOffsetY;
+
+ /* Get client rectangle */
+ if (!GetClientRect (pWinPriv->hWnd, &rcClient))
+ {
+ ErrorF ("winReshape - GetClientRect failed, bailing: %d\n",
+ GetLastError ());
+ return;
+ }
+
+ /* Translate client rectangle coords to screen coords */
+ /* NOTE: Only transforms top and left members */
+ ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient);
+
+ /* Get window rectangle */
+ if (!GetWindowRect (pWinPriv->hWnd, &rcWindow))
+ {
+ ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n",
+ GetLastError ());
+ return;
+ }
+
+ /* Calculate offset from window upper-left to client upper-left */
+ iOffsetX = rcClient.left - rcWindow.left;
+ iOffsetY = rcClient.top - rcWindow.top;
+
+ /* Create initial Windows region for title bar */
+ /* FIXME: Mean, nasty, ugly hack!!! */
+ hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY);
+ if (hRgn == NULL)
+ {
+ ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
+ "failed: %d\n",
+ 0, 0, rcWindow.right, iOffsetY, GetLastError ());
+ }
+
+ /* Loop through all rectangles in the X region */
+ for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++)
+ {
+ /* Create a Windows region for the X rectangle */
+ hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX - 1,
+ pRects->y1 + iOffsetY - 1,
+ pRects->x2 + iOffsetX - 1,
+ pRects->y2 + iOffsetY - 1);
+ if (hRgnRect == NULL)
+ {
+ ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
+ "failed: %d\n"
+ "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n",
+ pRects->x1 + iOffsetX - 1,
+ pRects->y1 + iOffsetY - 1,
+ pRects->x2 + iOffsetX - 1,
+ pRects->y2 + iOffsetY - 1,
+ GetLastError (),
+ pRects->x1, pRects->x2, iOffsetX,
+ pRects->y1, pRects->y2, iOffsetY);
+ }
+
+ /* Merge the Windows region with the accumulated region */
+ if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
+ {
+ ErrorF ("winReshape - CombineRgn () failed: %d\n",
+ GetLastError ());
+ }
+
+ /* Delete the temporary Windows region */
+ DeleteObject (hRgnRect);
+ }
+
+ /* Save a handle to the composite region in the window privates */
+ pWinPriv->hRgn = hRgn;
+ }
+
+ REGION_UNINIT(pScreen, &rrNewShape);
+
+ return;
+}
+#endif
+
+
+/*
+ * winTopLevelWindowProc - Window procedure for all top-level Windows windows.
+ */
+
+LRESULT CALLBACK
+winTopLevelWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ POINT ptMouse;
+ HDC hdcUpdate;
+ PAINTSTRUCT ps;
+ WindowPtr pWin = NULL;
+ winPrivWinPtr pWinPriv = NULL;
+ ScreenPtr s_pScreen = NULL;
+ winPrivScreenPtr s_pScreenPriv = NULL;
+ winScreenInfo *s_pScreenInfo = NULL;
+ HWND hwndScreen = NULL;
+ DrawablePtr pDraw = NULL;
+ int iX, iY, iWidth, iHeight, iBorder;
+ winWMMessageRec wmMsg;
+ static Bool s_fTracking = FALSE;
+ static Bool s_fCursor = TRUE;
+
+ /* Check if the Windows window property for our X window pointer is valid */
+ if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
+ {
+ /* Our X window pointer is valid */
+
+ /* Get pointers to the drawable and the screen */
+ pDraw = &pWin->drawable;
+ s_pScreen = pWin->drawable.pScreen;
+
+ /* Get a pointer to our window privates */
+ pWinPriv = winGetWindowPriv(pWin);
+
+ /* Get pointers to our screen privates and screen info */
+ s_pScreenPriv = pWinPriv->pScreenPriv;
+ s_pScreenInfo = s_pScreenPriv->pScreenInfo;
+
+ /* Get the handle for our screen-sized window */
+ /* NOTE: This will be going away at some point, right? Harold Hunt - 2003/01/15 */
+ hwndScreen = s_pScreenPriv->hwndScreen;
+
+ /* */
+ wmMsg.msg = 0;
+ wmMsg.hwndWindow = hwnd;
+ wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP);
+
+#if 1
+ wmMsg.iX = pWinPriv->iX;
+ wmMsg.iY = pWinPriv->iY;
+ wmMsg.iWidth = pWinPriv->iWidth;
+ wmMsg.iHeight = pWinPriv->iHeight;
+#else
+ wmMsg.iX = pDraw.x;
+ wmMsg.iY = pDraw.y;
+ wmMsg.iWidth = pDraw.width;
+ wmMsg.iHeight = pDraw.height;
+#endif
+
+
+#if 0
+ /*
+ * Print some debugging information
+ */
+
+ ErrorF ("hWnd %08X\n", hwnd);
+ ErrorF ("pWin %08X\n", pWin);
+ ErrorF ("pDraw %08X\n", pDraw);
+ ErrorF ("\ttype %08X\n", pWin->drawable.type);
+ ErrorF ("\tclass %08X\n", pWin->drawable.class);
+ ErrorF ("\tdepth %08X\n", pWin->drawable.depth);
+ ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel);
+ ErrorF ("\tid %08X\n", pWin->drawable.id);
+ ErrorF ("\tx %08X\n", pWin->drawable.x);
+ ErrorF ("\ty %08X\n", pWin->drawable.y);
+ ErrorF ("\twidth %08X\n", pWin->drawable.width);
+ ErrorF ("\thenght %08X\n", pWin->drawable.height);
+ ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen);
+ ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber);
+ ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex);
+ ErrorF ("pWinPriv %08X\n", pWinPriv);
+ ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv);
+ ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo);
+ ErrorF ("hwndScreen %08X\n", hwndScreen);
+#endif
+ }
+
+
+
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_CREATE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_CREATE\n");
+#endif
+
+ /* */
+ SetProp (hwnd,
+ WIN_WINDOW_PROP,
+ (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
+
+ /* */
+ SetProp (hwnd,
+ WIN_WID_PROP,
+ (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams));
+ return 0;
+
+ case WM_PAINT:
+ /* Only paint if our window handle is valid */
+ if (hwndScreen == NULL)
+ break;
+
+ /* BeginPaint gives us an hdc that clips to the invalidated region */
+ hdcUpdate = BeginPaint (hwnd, &ps);
+
+#if 0
+ /* NOTE: Doesn't appear to be used - Harold Hunt - 2003/01/15 */
+ /* Get the dimensions of the client area */
+ GetClientRect (hwnd, &rcClient);
+#endif
+
+ /* Get the position and dimensions of the window */
+ iBorder = wBorderWidth (pWin);
+ iX = pWin->drawable.x;
+ iY = pWin->drawable.y;
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Try to copy from the shadow buffer */
+ if (!BitBlt (hdcUpdate,
+ 0, 0,
+ iWidth, iHeight,
+ s_pScreenPriv->hdcShadow,
+ iX, iY,
+ SRCCOPY))
+ {
+ 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), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL);
+
+ ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n",
+ (LPSTR)lpMsgBuf);
+ LocalFree (lpMsgBuf);
+ }
+
+ /* EndPaint frees the DC */
+ EndPaint (hwndScreen, &ps);
+ return 0;
+
+
+#if 1
+ case WM_MOUSEMOVE:
+ /* Unpack the client area mouse coordinates */
+ ptMouse.x = GET_X_LPARAM(lParam);
+ ptMouse.y = GET_Y_LPARAM(lParam);
+
+ /* Translate the client area mouse coordinates to screen coordinates */
+ ClientToScreen (hwnd, &ptMouse);
+
+ /* We can't do anything without privates */
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+
+ /* Has the mouse pointer crossed screens? */
+ if (s_pScreen != miPointerCurrentScreen ())
+ miPointerSetNewScreen (s_pScreenInfo->dwScreen,
+ ptMouse.x - s_pScreenInfo->dwXOffset,
+ ptMouse.y - s_pScreenInfo->dwYOffset);
+
+ /* Are we tracking yet? */
+ if (!s_fTracking)
+ {
+ TRACKMOUSEEVENT tme;
+
+ /* Setup data structure */
+ ZeroMemory (&tme, sizeof (tme));
+ tme.cbSize = sizeof (tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+
+ /* Call the tracking function */
+ if (!(*g_fpTrackMouseEvent) (&tme))
+ ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n");
+
+ /* Flag that we are tracking now */
+ s_fTracking = TRUE;
+ }
+
+ /* Hide or show the Windows mouse cursor */
+ if (s_fCursor)
+ {
+ /* Hide Windows cursor */
+ s_fCursor = FALSE;
+ ShowCursor (FALSE);
+ KillTimer (hwnd, s_nIDPollingMouse);
+ }
+
+ /* Deliver absolute cursor position to X Server */
+ miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset,
+ ptMouse.y - s_pScreenInfo->dwYOffset,
+ g_c32LastInputEventTime = GetTickCount ());
+ return 0;
+
+ case WM_NCMOUSEMOVE:
+ /*
+ * We break instead of returning 0 since we need to call
+ * DefWindowProc to get the mouse cursor changes
+ * and min/max/close button highlighting in Windows XP.
+ * The Platform SDK says that you should return 0 if you
+ * process this message, but it fails to mention that you
+ * will give up any default functionality if you do return 0.
+ */
+
+ /* We can't do anything without privates */
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+
+ /* Non-client mouse movement, show Windows cursor */
+ if (!s_fCursor)
+ {
+ s_fCursor = TRUE;
+ ShowCursor (TRUE);
+ SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL);
+ }
+ break;
+
+ case WM_MOUSELEAVE:
+ /* Mouse has left our client area */
+
+ /* Flag that we are no longer tracking */
+ s_fTracking = FALSE;
+
+ /* Show the mouse cursor, if necessary */
+ if (!s_fCursor)
+ {
+ s_fCursor = TRUE;
+ ShowCursor (TRUE);
+ SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL);
+ }
+ return 0;
+
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+ return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam);
+
+ case WM_LBUTTONUP:
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+ return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam);
+
+ case WM_MBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+ return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam);
+
+ case WM_MBUTTONUP:
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+ return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam);
+
+ case WM_RBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+ return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam);
+
+ case WM_RBUTTONUP:
+ if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
+ break;
+ return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam);
+
+#else
+
+ case WM_MOUSEMOVE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_MOUSEMOVE*\n");
+#endif
+
+ /* Unpack the client area mouse coordinates */
+ ptMouse.x = GET_X_LPARAM(lParam);
+ ptMouse.y = GET_Y_LPARAM(lParam);
+
+ /* Translate the client area mouse coordinates to screen coordinates */
+ ClientToScreen (hwnd, &ptMouse);
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y));
+ return 0;
+
+ case WM_NCMOUSEMOVE:
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_MBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_MOUSELEAVE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_*BUTTON*\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage(hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y));
+ return 0;
+#endif
+
+ case WM_MOUSEWHEEL:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_MOUSEWHEEL\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage(hwndScreen, message, wParam, lParam);
+ return 0;
+
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSDEADCHAR:
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_DEADCHAR:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_*KEY*\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+
+ case WM_HOTKEY:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_HOTKEY\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+
+
+#if 1
+ case WM_ACTIVATE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_ACTIVATE\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+
+ /* Bail if inactivating */
+ if (LOWORD(wParam) == WA_INACTIVE)
+ return 0;
+
+ /* Check if the current window is the active window in Windows */
+ if (GetActiveWindow () == hwnd)
+ {
+ /* Tell our Window Manager thread to raise the window */
+ wmMsg.msg = WM_WM_RAISE;
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+ }
+
+ /* Tell our Window Manager thread to activate the window */
+ wmMsg.msg = WM_WM_ACTIVATE;
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+
+ return 0;
+
+ case WM_ACTIVATEAPP:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_ACTIVATEAPP\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+#endif
+
+
+ case WM_CLOSE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_CLOSE\n");
+#endif
+ /* Branch on if the window was killed in X already */
+ if (pWinPriv->fXKilled)
+ {
+ /* Window was killed, go ahead and destroy the window */
+ DestroyWindow (hwnd);
+ }
+ else
+ {
+ /* Tell our Window Manager thread to kill the window */
+ wmMsg.msg = WM_WM_KILL;
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+ }
+ return 0;
+
+ case WM_DESTROY:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_DESTROY\n");
+#endif
+
+ /* Branch on if the window was killed in X already */
+ if (pWinPriv && !pWinPriv->fXKilled)
+ {
+ ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n");
+
+ /* Tell our Window Manager thread to kill the window */
+ wmMsg.msg = WM_WM_KILL;
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_DESTROY\n");
+#endif
+ break;
+
+ case WM_MOVE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_MOVE - %d ms\n", GetTickCount ());
+#endif
+
+ /* Bail if Windows window is not actually moving */
+ if (pWinPriv->iX == (short) LOWORD(lParam)
+ && pWinPriv->iY == (short) HIWORD(lParam))
+ break;
+
+ /* Get new position */
+ pWinPriv->iX = (short) LOWORD(lParam);
+ pWinPriv->iY = (short) HIWORD(lParam);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\t(%d, %d)\n", pWinPriv->iX, pWinPriv->iY);
+#endif
+
+ /* Notify the X client that its window is moving */
+ if (SubStrSend(pWin, pWin->parent))
+ SendConfigureNotify (pWin);
+
+ /* Tell X that the window is moving */
+ (s_pScreen->MoveWindow) (pWin,
+ (int)(short) LOWORD(lParam) - wBorderWidth (pWin),
+ (int)(short) HIWORD(lParam) - wBorderWidth (pWin),
+ pWin->nextSib,
+ VTMove);
+ return 0;
+
+ case WM_SHOWWINDOW:
+ /* Bail out if the window is being hidden */
+ if (!wParam)
+ return 0;
+
+ /* Tell X to map the window */
+ MapWindow (pWin, wClient(pWin));
+
+ /* */
+ if (!pWin->overrideRedirect)
+ {
+ DWORD dwExStyle;
+ DWORD dwStyle;
+ RECT rcNew;
+ int iDx, iDy;
+
+ /* Flag that this window needs to be made active when clicked */
+ SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
+
+ /* Get the standard and extended window style information */
+ dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
+
+ /* */
+ if (dwExStyle != WS_EX_APPWINDOW)
+ {
+ /* Setup a rectangle with the X window position and size */
+ SetRect (&rcNew,
+ pWinPriv->iX,
+ pWinPriv->iY,
+ pWinPriv->iX + pWinPriv->iWidth,
+ pWinPriv->iY + pWinPriv->iHeight);
+
+#if 0
+ ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n",
+ rcNew.left, rcNew.top,
+ rcNew.right, rcNew.bottom);
+#endif
+
+ /* */
+ AdjustWindowRectEx (&rcNew,
+ WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW,
+ FALSE,
+ WS_EX_APPWINDOW);
+
+ /* Calculate position deltas */
+ iDx = pWinPriv->iX - rcNew.left;
+ iDy = pWinPriv->iY - rcNew.top;
+
+ /* Calculate new rectangle */
+ rcNew.left += iDx;
+ rcNew.right += iDx;
+ rcNew.top += iDy;
+ rcNew.bottom += iDy;
+
+#if 0
+ ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n",
+ rcNew.left, rcNew.top,
+ rcNew.right, rcNew.bottom);
+#endif
+
+ /* Set the window extended style flags */
+ SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
+
+ /* Set the window standard style flags */
+ SetWindowLongPtr (hwnd, GWL_STYLE, WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW);
+
+ /* Positon the Windows window */
+ SetWindowPos (hwnd, HWND_TOP,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ SWP_NOMOVE | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+
+ /* Bring the Window window to the foreground */
+ SetForegroundWindow (hwnd);
+ }
+ }
+
+ /* Setup the Window Manager message */
+ wmMsg.msg = WM_WM_MAP;
+ wmMsg.iWidth = pWinPriv->iWidth;
+ wmMsg.iHeight = pWinPriv->iHeight;
+
+ /* Tell our Window Manager thread to map the window */
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+
+ /* Setup the Window Manager message */
+ wmMsg.msg = WM_WM_RAISE;
+
+ /* Tell our Window Manager thread to raise the window */
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+ return 0;
+
+ case WM_SIZE:
+ /* see dix/window.c */
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_SIZE - %d ms\n", GetTickCount ());
+#endif
+
+ switch (wParam)
+ {
+ case SIZE_MINIMIZED:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tSIZE_MINIMIZED\n");
+#endif
+
+ wmMsg.msg = WM_WM_LOWER;
+
+ /* Tell our Window Manager thread to lower the window */
+ winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
+ break;
+
+ case SIZE_RESTORED:
+ case SIZE_MAXIMIZED:
+ if (pWinPriv->iWidth == (short) LOWORD(lParam)
+ && pWinPriv->iHeight == (short) HIWORD(lParam))
+ break;
+
+ /* Get the dimensions of the Windows window */
+ pWinPriv->iWidth = (short) LOWORD(lParam);
+ pWinPriv->iHeight = (short) HIWORD(lParam);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight);
+#endif
+
+ /* Check if resize events are redirected */
+ if ((pWin->eventMask | wOtherEventMasks (pWin)) & ResizeRedirectMask)
+ {
+ xEvent eventT;
+
+ /* Setup the X event structure */
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = pWinPriv->iWidth;
+ eventT.u.resizeRequest.height = pWinPriv->iHeight;
+
+ /* */
+ if (MaybeDeliverEventsToClient (pWin, &eventT, 1,
+ ResizeRedirectMask,
+ wClient(pWin)) == 1)
+ break;
+ }
+
+ /* Notify the X client that its window is being resized */
+ if (SubStrSend (pWin, pWin->parent))
+ SendConfigureNotify (pWin);
+
+ /* Tell the X server that the window is being resized */
+ (s_pScreen->ResizeWindow) (pWin,
+ pWinPriv->iX - wBorderWidth (pWin),
+ pWinPriv->iY - wBorderWidth (pWin),
+ pWinPriv->iWidth,
+ pWinPriv->iHeight,
+ pWin->nextSib);
+
+ /* Tell X to redraw the exposed portions of the window */
+ {
+ RegionRec temp;
+
+ /* Get the region describing the X window clip list */
+ REGION_INIT(s_pScreen, &temp, NullBox, 0);
+ REGION_COPY(s_pScreen, &temp, &pWin->clipList);
+
+ /* Expose the clipped region */
+ (*s_pScreen->WindowExposures) (pWin, &temp, NullRegion);
+
+ /* Free the region */
+ REGION_UNINIT(s_pScreen, &temp);
+ }
+ break;
+
+#if 0
+ case SIZE_MAXIMIZED:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tSIZE_MAXIMIZED\n");
+#endif
+
+ /* Get the dimensions of the window */
+ pWinPriv->iWidth = (int)(short) LOWORD(lParam);
+ pWinPriv->iHeight = (int)(short) HIWORD(lParam);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight);
+#endif
+
+ /* */
+ if ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask)
+ {
+ xEvent eventT;
+
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = pWinPriv->iWidth;
+ eventT.u.resizeRequest.height = pWinPriv->iHeight;
+ if (MaybeDeliverEventsToClient (pWin, &eventT, 1,
+ ResizeRedirectMask,
+ wClient(pWin)) == 1);
+ }
+
+
+ (s_pScreen->ResizeWindow) (pWin,
+ pWinPriv->iX - wBorderWidth (pWin),
+ pWinPriv->iY - wBorderWidth (pWin),
+ pWinPriv->iWidth,
+ pWinPriv->iHeight,
+ pWin->nextSib);
+ break;
+#endif
+
+ default:
+ break;
+ }
+ return 0;
+
+ case WM_MOUSEACTIVATE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE\n");
+#endif
+
+ /* Check if this window needs to be made active when clicked */
+ if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP))
+ {
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - MA_NOACTIVATE\n");
+#endif
+
+ /* */
+ return MA_NOACTIVATE;
+ }
+ break;
+
+ case WM_TIMER:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winTopLevelWindowProc - WM_TIMER - %d ms\n", GetTickCount ());
+#endif
+
+ /* Branch on the type of timer event that fired */
+ if (wParam == s_nIDPollingMouse)
+ {
+ POINT point;
+
+ /* Get the current position of the mouse cursor */
+ GetCursorPos (&point);
+
+ /* Deliver absolute cursor position to X Server */
+ miPointerAbsoluteCursor (point.x, point.y,
+ g_c32LastInputEventTime = GetTickCount ());
+ }
+ else
+ {
+ ErrorF ("winTopLevelWindowProc - Unknown WM_TIMER\n");
+ }
+ return 0;
+
+ default:
+ break;
+ }
+
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+
+/*
+ * winCreateWindowsWindow - Create a Windows window associated with an X window
+ */
+
+static void
+winCreateWindowsWindow (WindowPtr pWin)
+{
+ int iX, iY;
+ int iWidth;
+ int iHeight;
+ int iBorder;
+ HWND hWnd;
+ WNDCLASS wc;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
+#endif
+
+ iBorder = wBorderWidth (pWin);
+
+ iX = pWin->drawable.x;
+ iY = pWin->drawable.y;
+
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Setup our window class */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = winTopLevelWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = g_hInstance;
+ wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
+ wc.hCursor = 0;
+ wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = WINDOW_CLASS_X;
+ RegisterClass (&wc);
+
+ /* Create the window */
+ hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
+ WINDOW_CLASS_X, /* Class name */
+ WINDOW_TITLE_X, /* Window name */
+ WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+ iX, /* Horizontal position */
+ iY, /* Vertical position */
+ iWidth, /* Right edge */
+ iHeight, /* Bottom edge */
+ (HWND) NULL, /* No parent or owner window */
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle (NULL), /* Instance handle */
+ pWin); /* ScreenPrivates */
+ if (hWnd == NULL)
+ {
+ ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
+ GetLastError ());
+ }
+
+ pWinPriv->hWnd = hWnd;
+
+
+ SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
+
+ /* Flag that this Windows window handles its own activation */
+ SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
+}
+
+
+/*
+ * winDestroyWindowsWindow - Destroy a Windows window associated with an X window
+ */
+
+static void
+winDestroyWindowsWindow (WindowPtr pWin)
+{
+ MSG msg;
+ winWindowPriv(pWin);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winDestroyWindowsWindow\n");
+#endif
+
+
+ /* Bail out if the Windows window handle is invalid */
+ if (pWinPriv->hWnd == NULL)
+ return;
+
+
+ SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, 0);
+
+ DestroyWindow (pWinPriv->hWnd);
+
+ pWinPriv->hWnd = NULL;
+
+ /* Process all messages on our queue */
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
+ {
+ DispatchMessage (&msg);
+ }
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("-winDestroyWindowsWindow\n");
+#endif
+}
+
+
+/*
+ * winUpdateWindowsWindow - Redisplay/redraw a Windows window associated with an X window
+ */
+
+static void
+winUpdateWindowsWindow (WindowPtr pWin)
+{
+ winWindowPriv(pWin);
+ HWND hWnd = pWinPriv->hWnd;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winUpdateWindowsWindow\n");
+#endif
+
+ /* Check if the Windows window's parents have been destroyed */
+ if (pWin->parent != NULL
+ && pWin->parent->parent == NULL
+ && pWin->mapped)
+ {
+ /* Create the Windows window if it has been destroyed */
+ if (hWnd == NULL)
+ {
+ winCreateWindowsWindow (pWin);
+ assert (pWinPriv->hWnd != NULL);
+ }
+
+ /* Display the window without activating it */
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ /* Send first paint message */
+ UpdateWindow (pWinPriv->hWnd);
+ }
+ else if (hWnd != NULL)
+ {
+ /* Destroy the Windows window if its parents are destroyed */
+ winDestroyWindowsWindow (pWin);
+ assert (pWinPriv->hWnd == NULL);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("-winUpdateWindowsWindow\n");
+#endif
+}
+
+
+
+
+
+
+
+
+typedef struct {
+ pointer value;
+ XID id;
+} WindowIDPairRec, *WindowIDPairPtr;
+
+
+
+
+
+/*
+ * winFindWindow -
+ */
+
+static void
+winFindWindow (pointer value, XID id, pointer cdata)
+{
+ WindowIDPairPtr wi = (WindowIDPairPtr)cdata;
+
+ if (value == wi->value)
+ {
+ wi->id = id;
+ }
+}
+
+
+/*
+ * winGetWindowID -
+ */
+
+static XID
+winGetWindowID (WindowPtr pWin)
+{
+ WindowIDPairRec wi = {pWin, 0};
+ ClientPtr c = wClient(pWin);
+
+ /* */
+ FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
+#endif
+
+ return wi.id;
+}
+
+
+/*
+ * SendConfigureNotify -
+ */
+
+static void
+SendConfigureNotify(WindowPtr pWin)
+{
+ xEvent event;
+ winWindowPriv(pWin);
+
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+
+ if (pWin->nextSib)
+ event.u.configureNotify.aboveSibling = pWin->nextSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+
+ event.u.configureNotify.x = pWinPriv->iX - wBorderWidth (pWin);
+ event.u.configureNotify.y = pWinPriv->iY - wBorderWidth (pWin);
+
+ event.u.configureNotify.width = pWinPriv->iWidth;
+ event.u.configureNotify.height = pWinPriv->iHeight;
+
+ event.u.configureNotify.borderWidth = wBorderWidth (pWin);
+
+ event.u.configureNotify.override = pWin->overrideRedirect;
+
+ /* */
+ DeliverEvents (pWin, &event, 1, NullWindow);
+}
diff --git a/xc/programs/Xserver/hw/xwin/winmultiwindowwm.c b/xc/programs/Xserver/hw/xwin/winmultiwindowwm.c
new file mode 100644
index 000000000..ab4dd27f6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winmultiwindowwm.c
@@ -0,0 +1,907 @@
+/*
+ *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.
+ *
+ * Authors: Kensuke Matsuzaki
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowwm.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+/* X headers */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <pthread.h>
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xlocale.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
+
+/* Fixups to prevent collisions between Windows and X headers */
+#define ATOM DWORD
+
+/* Windows headers */
+#include <windows.h>
+
+/* Local headers */
+#include "winwindow.h"
+
+
+/*
+ * Constant defines
+ */
+
+#define WIN_CONNECT_RETRIES 5
+#define WIN_CONNECT_DELAY 5
+#define WIN_MSG_QUEUE_FNAME "/dev/windows"
+#define WM_WM_X_EVENT 1
+#define WIN_JMP_OKAY 0
+#define WIN_JMP_ERROR_IO 2
+
+
+/*
+ * Local structures
+ */
+
+typedef struct _WMMsgNodeRec {
+ winWMMessageRec msg;
+ struct _WMMsgNodeRec *pNext;
+} WMMsgNodeRec, *WMMsgNodePtr;
+
+typedef struct _WMMsgQueueRec {
+ struct _WMMsgNodeRec *pHead;
+ struct _WMMsgNodeRec *pTail;
+ pthread_mutex_t pmMutex;
+ pthread_cond_t pcNotEmpty;
+} WMMsgQueueRec, *WMMsgQueuePtr;
+
+typedef struct _WMInfo {
+ Display *pDisplay;
+ WMMsgQueueRec wmMsgQueue;
+ Atom atmWmProtos;
+ Atom atmWmDelete;
+} WMInfoRec, *WMInfoPtr;
+
+typedef struct _WMProcArgRec {
+ DWORD dwScreen;
+ WMInfoPtr pWMInfo;
+ pthread_mutex_t *ppmServerStarted;
+} WMProcArgRec, *WMProcArgPtr;
+
+
+/*
+ * References to external symbols
+ */
+
+extern char *display;
+extern void ErrorF (const char* /*f*/, ...);
+extern Bool g_fCalledSetLocale;
+
+
+/*
+ * Prototypes for local functions
+ */
+
+static void
+PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode);
+
+static WMMsgNodePtr
+PopMessage (WMMsgQueuePtr pQueue);
+
+static Bool
+InitQueue (WMMsgQueuePtr pQueue);
+
+static void
+GetWindowName (Display * pDpy, Window iWin, char **ppName);
+
+static int
+SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData);
+
+static void*
+winMultiWindowWMProc (void* pArg);
+
+static Bool
+FlushXEvents (WMInfoPtr pWMInfo);
+
+static int
+winMultiWindowWMErrorHandler (Display *pDisp, XErrorEvent *e);
+
+static void
+winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg);
+
+static int
+winMutliWindowWMIOErrorHandler (Display *pDisplay);
+
+
+/*
+ * Local globals
+ */
+
+static int g_nQueueSize;
+static jmp_buf g_jmpEntry;
+
+
+
+/*
+ * PushMessage - Push a message onto the queue
+ */
+
+static void
+PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
+{
+
+ /* Lock the queue mutex */
+ pthread_mutex_lock (&pQueue->pmMutex);
+
+ pNode->pNext = NULL;
+
+ if (pQueue->pTail != NULL)
+ {
+ pQueue->pTail->pNext = pNode;
+ }
+ pQueue->pTail = pNode;
+
+ if (pQueue->pHead == NULL)
+ {
+ pQueue->pHead = pNode;
+ }
+
+
+#if 0
+ switch (pNode->msg.msg)
+ {
+ case WM_WM_MOVE:
+ ErrorF ("\tWM_WM_MOVE\n");
+ break;
+ case WM_WM_RAISE:
+ ErrorF ("\tWM_WM_RAISE\n");
+ break;
+ case WM_WM_LOWER:
+ ErrorF ("\tWM_WM_RAISE\n");
+ break;
+ case WM_WM_MAP:
+ ErrorF ("\tWM_WM_MAP\n");
+ break;
+ case WM_WM_UNMAP:
+ ErrorF ("\tWM_WM_UNMAP\n");
+ break;
+ case WM_WM_KILL:
+ ErrorF ("\tWM_WM_KILL\n");
+ break;
+ default:
+ ErrorF ("Unknown Message.\n");
+ break;
+ }
+#endif
+
+ /* Increase the count of elements in the queue by one */
+ ++g_nQueueSize;
+
+ /* Release the queue mutex */
+ pthread_mutex_unlock (&pQueue->pmMutex);
+
+ /* Signal that the queue is not empty */
+ pthread_cond_signal (&pQueue->pcNotEmpty);
+}
+
+
+#if 0
+/*
+ * QueueSize - Return the size of the queue
+ */
+
+static int
+QueueSize (WMMsgQueuePtr pQueue)
+{
+ WMMsgNodePtr pNode;
+ int nSize = 0;
+
+ /* Loop through all elements in the queue */
+ for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
+ ++nSize;
+
+ return nSize;
+}
+#endif
+
+
+/*
+ * PopMessage -
+ */
+
+static WMMsgNodePtr
+PopMessage (WMMsgQueuePtr pQueue)
+{
+ WMMsgNodePtr pNode;
+
+ /* Lock the queue mutex */
+ pthread_mutex_lock (&pQueue->pmMutex);
+
+ /* Wait for --- */
+ while (pQueue->pHead == NULL)
+ {
+ pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex);
+ }
+
+ pNode = pQueue->pHead;
+ if (pQueue->pHead != NULL)
+ {
+ pQueue->pHead = pQueue->pHead->pNext;
+ }
+
+ if (pQueue->pTail == pNode)
+ {
+ pQueue->pTail = NULL;
+ }
+
+ /* Drop the number of elements in the queue by one */
+ --g_nQueueSize;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("Queue Size %d %d\n", g_nQueueSize, QueueSize(pQueue));
+#endif
+
+ /* Release the queue mutex */
+ pthread_mutex_unlock (&pQueue->pmMutex);
+
+ return pNode;
+}
+
+
+#if 0
+/*
+ * HaveMessage -
+ */
+
+static Bool
+HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow)
+{
+ WMMsgNodePtr pNode;
+
+ for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
+ {
+ if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow)
+ return True;
+ }
+
+ return False;
+}
+#endif
+
+
+/*
+ * InitQueue - Initialize the Window Manager message queue
+ */
+
+static
+Bool
+InitQueue (WMMsgQueuePtr pQueue)
+{
+ /* Check if the pQueue pointer is NULL */
+ if (pQueue == NULL)
+ {
+ ErrorF ("InitQueue - pQueue is NULL. Exiting.\n");
+ return FALSE;
+ }
+
+ /* Set the head and tail to NULL */
+ pQueue->pHead = NULL;
+ pQueue->pTail = NULL;
+
+ /* There are no elements initially */
+ g_nQueueSize = 0;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("InitQueue - Queue Size %d %d\n", g_nQueueSize, QueueSize(pQueue));
+#endif
+
+ ErrorF ("InitQueue - Calling pthread_mutex_init\n");
+
+ /* Create synchronization objects */
+ pthread_mutex_init (&pQueue->pmMutex, NULL);
+
+ ErrorF ("InitQueue - pthread_mutex_init returned\n");
+ ErrorF ("InitQueue - Calling pthread_cond_init\n");
+
+ pthread_cond_init (&pQueue->pcNotEmpty, NULL);
+
+ ErrorF ("InitQueue - pthread_cond_init returned\n");
+
+ return TRUE;
+}
+
+
+/*
+ * GetWindowName -
+ */
+
+static void
+GetWindowName (Display *pDisplay, Window iWin, char **ppName)
+{
+ int nResult, nNum;
+ char **ppList;
+ XTextProperty xtpName;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("GetWindowName\n");
+#endif
+
+ /* Intialize ppName to NULL */
+ *ppName = NULL;
+
+ /* Try to get --- */
+ nResult = XGetWMName (pDisplay, iWin, &xtpName);
+ if (!nResult || !xtpName.value || !xtpName.nitems)
+ {
+ ErrorF ("GetWindowName - XGetWMName failed. No name.\n");
+ return;
+ }
+
+ /* */
+ if (xtpName.encoding == XA_STRING)
+ {
+ /* */
+ if (xtpName.value)
+ {
+ *ppName = strdup ((char*)xtpName.value);
+ XFree (xtpName.value);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("XA_STRING %s\n", *ppName);
+#endif
+ }
+ else
+ {
+ XmbTextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum);
+
+ /* */
+ if (nNum && *ppList)
+ {
+ XFree (xtpName.value);
+ *ppName = strdup (*ppList);
+ XFreeStringList (ppList);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("%s %s\n", XGetAtomName (pDisplay, xtpName.encoding), *ppName);
+#endif
+ }
+
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("-GetWindowName\n");
+#endif
+}
+
+
+/*
+ * Send a message to the X server from the WM thread
+ */
+
+static int
+SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData)
+{
+ XEvent e;
+
+ /* Prepare the X event structure */
+ e.type = ClientMessage;
+ e.xclient.window = iWin;
+ e.xclient.message_type = atmType;
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = nData;
+ e.xclient.data.l[1] = CurrentTime;
+
+ /* Send the event to X */
+ return XSendEvent (pDisplay, iWin, False, NoEventMask, &e);
+}
+
+
+/*
+ * winMultiWindowWMProc
+ */
+
+static void *
+winMultiWindowWMProc (void *pArg)
+{
+ WMProcArgPtr pProcArg = (WMProcArgPtr)pArg;
+ WMInfoPtr pWMInfo = pProcArg->pWMInfo;
+
+ /* Initialize the Window Manager */
+ winInitMultiWindowWM (pWMInfo, pProcArg);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winMultiWindowWMProc ()\n");
+#endif
+
+ /* Loop until we explicity break out */
+ for (;;)
+ {
+ WMMsgNodePtr pNode;
+
+ /* Pop a message off of our queue */
+ pNode = PopMessage (&pWMInfo->wmMsgQueue);
+ if (pNode == NULL)
+ {
+ /* Bail if PopMessage returns without a message */
+ /* NOTE: Remember that PopMessage is a blocking function. */
+ ErrorF ("winMultiWindowWMProc - Queue is Empty?\n");
+ pthread_exit (NULL);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
+ GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID);
+#endif
+
+ /* Branch on the message type */
+ switch (pNode->msg.msg)
+ {
+#if 0
+ case WM_WM_MOVE:
+ ErrorF ("\tWM_WM_MOVE\n");
+ break;
+
+ case WM_WM_SIZE:
+ ErrorF ("\tWM_WM_SIZE\n");
+ break;
+#endif
+
+ case WM_WM_RAISE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tWM_WM_RAISE\n");
+#endif
+
+ /* Raise the window */
+ XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_LOWER:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tWM_WM_LOWER\n");
+#endif
+
+ /* Lower the window */
+ XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_MAP:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tWM_WM_MAP\n");
+#endif
+ {
+ XWindowAttributes attr;
+ char *pszName;
+#if 0
+ XWMHints *pHints;
+#endif
+
+ /* Get the window attributes */
+ XGetWindowAttributes (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ &attr);
+ if (!attr.override_redirect)
+ {
+ /* Set the Windows window name */
+ GetWindowName(pWMInfo->pDisplay, pNode->msg.iWindow, &pszName);
+ SetWindowText (pNode->msg.hwndWindow, pszName);
+ free (pszName);
+ }
+ }
+ break;
+
+ case WM_WM_UNMAP:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tWM_WM_UNMAP\n");
+#endif
+
+ /* Unmap the window */
+ XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_KILL:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tWM_WM_KILL\n");
+#endif
+ {
+ int i, n, found = 0;
+ Atom *protocols;
+
+ /* --- */
+ if (XGetWMProtocols (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ &protocols,
+ &n))
+ {
+ for (i = 0; i < n; ++i)
+ if (protocols[i] == pWMInfo->atmWmDelete)
+ ++found;
+
+ XFree (protocols);
+ }
+
+ /* --- */
+ if (found)
+ SendXMessage (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmWmProtos,
+ pWMInfo->atmWmDelete);
+ else
+ XKillClient (pWMInfo->pDisplay,
+ pNode->msg.iWindow);
+ }
+ break;
+
+ case WM_WM_ACTIVATE:
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("\tWM_WM_ACTIVATE\n");
+#endif
+
+ /* Set the input focus */
+ XSetInputFocus (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ RevertToPointerRoot,
+ CurrentTime);
+ break;
+
+ case WM_WM_X_EVENT:
+ /* Process all X events in the Window Manager event queue */
+ FlushXEvents (pWMInfo);
+ break;
+
+ default:
+ ErrorF ("winMultiWindowWMProc - Unknown Message.\n");
+ pthread_exit (NULL);
+ break;
+ }
+
+ /* Free the retrieved message */
+ free (pNode);
+
+ /* Flush any pending events on our display */
+ XFlush (pWMInfo->pDisplay);
+ }
+
+ /* Free the condition variable */
+ pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty);
+
+ /* Free the mutex variable */
+ pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex);
+
+ /* Free the passed-in argument */
+ free (pProcArg);
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF("-winMultiWindowWMProc ()\n");
+#endif
+}
+
+
+/*
+ * FlushXEvents - Process any pending X events
+ */
+
+static Bool
+FlushXEvents (WMInfoPtr pWMInfo)
+{
+ XEvent event;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("FlushXEvents ()\n");
+#endif
+
+ /* Process all pending events */
+ while (XPending (pWMInfo->pDisplay))
+ {
+ /* Get the next event - will not block because one is ready */
+ XNextEvent (pWMInfo->pDisplay, &event);
+
+#if 0
+ /* Branch on the event type */
+ switch (event.type)
+ {
+ }
+#endif
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("-FlushXEvents ()\n");
+#endif
+
+ return True;
+}
+
+
+/*
+ * winMultiWindowWMErrorHandler - Our application specific error handler
+ */
+
+static int
+winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr)
+{
+ char pszErrorMsg[100];
+
+ if (pErr->request_code == X_ChangeWindowAttributes
+ && pErr->error_code == BadAccess)
+ {
+ ErrorF ("ChangeWindowAttributes BadAccess.\n");
+ pthread_exit (NULL);
+ }
+
+ XGetErrorText (pDisplay,
+ pErr->error_code,
+ pszErrorMsg,
+ sizeof (pszErrorMsg));
+ ErrorF ("ERROR: %s\n", pszErrorMsg);
+
+ if (pErr->error_code==BadWindow
+ || pErr->error_code==BadMatch
+ || pErr->error_code==BadDrawable)
+ {
+ pthread_exit (NULL);
+ }
+
+ pthread_exit (NULL);
+ return 0;
+}
+
+
+/*
+ * winInitWM - Entry point for the X server to spawn
+ * the Window Manager thread. Called from
+ * winscrinit.c/winFinishScreenInitFB ().
+ */
+
+Bool
+winInitWM (void **ppWMInfo,
+ pthread_t *ptWMProc,
+ pthread_mutex_t *ppmServerStarted,
+ int dwScreen)
+{
+ WMProcArgPtr pArg = (WMProcArgPtr)malloc (sizeof(WMProcArgRec));
+ WMInfoPtr pWMInfo = (WMInfoPtr)malloc (sizeof(WMInfoRec));
+
+ /* Bail if the input parameters are bad */
+ if (pArg == NULL || pWMInfo == NULL)
+ {
+ ErrorF ("winInitWM - malloc fail.\n");
+ return FALSE;
+ }
+
+ /* Set a return pointer to the Window Manager info structure */
+ *ppWMInfo = pWMInfo;
+
+ /* Setup the argument structure for the thread function */
+ pArg->dwScreen = dwScreen;
+ pArg->pWMInfo = pWMInfo;
+ pArg->ppmServerStarted = ppmServerStarted;
+
+ /* Intialize the message queue */
+ if (!InitQueue (&pWMInfo->wmMsgQueue))
+ {
+ ErrorF ("winInitWM - InitQueue () failed.\n");
+ return FALSE;
+ }
+
+ /* Spawn a thread for the Window Manager */
+ if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg))
+ {
+ /* Bail if thread creation failed */
+ ErrorF ("winInitWM - pthread_create failed.\n");
+ return FALSE;
+ }
+
+#if CYGDEBUG || YES
+ ErrorF ("winInitWM - Returning.\n");
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * winInitMultiWindowWM -
+ */
+
+Bool
+winClipboardDetectUnicodeSupport ();
+
+static void
+winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
+{
+ int iRetries = 0;
+ char pszDisplay[512];
+ int iReturn;
+ Bool fUnicodeSupport;
+
+ ErrorF ("winInitMultiWindowWM - Hello\n");
+
+ /* Check that argument pointer is not invalid */
+ if (pProcArg == NULL)
+ {
+ ErrorF ("winInitMultiWindowWM - pProcArg is NULL, bailing.\n");
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
+
+ /* Grab our garbage mutex to satisfy pthread_cond_wait */
+ iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
+
+ /* Do we have Unicode support? */
+ fUnicodeSupport = winClipboardDetectUnicodeSupport ();
+
+ /* Set the current locale? What does this do? */
+ if (fUnicodeSupport && !g_fCalledSetLocale)
+ {
+ ErrorF ("winInitMultiWindowWM - Calling setlocale ()\n");
+ if (!setlocale (LC_ALL, ""))
+ {
+ ErrorF ("winInitMultiWindowWM - setlocale () error\n");
+ pthread_exit (NULL);
+ }
+ ErrorF ("winInitMultiWindowWM - setlocale () returned\n");
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == False)
+ {
+ ErrorF ("winInitMultiWindowWM - Locale not supported by X\n");
+ pthread_exit (NULL);
+ }
+ }
+
+ /* Flag that we have called setlocale */
+ g_fCalledSetLocale = TRUE;
+
+ /* Release the garbage mutex */
+ pthread_mutex_unlock (pProcArg->ppmServerStarted);
+
+ ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
+
+ /* Allow multiple threads to access Xlib */
+ if (XInitThreads () == 0)
+ {
+ ErrorF ("winInitMultiWindowWM - XInitThreads () failed.\n");
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winInitMultiWindowWM - XInitThreads () returned.\n");
+
+ /* Set jump point for Error exits */
+ iReturn = setjmp (g_jmpEntry);
+
+ /* Check if we should continue operations */
+ if (iReturn != WIN_JMP_ERROR_IO
+ && iReturn != WIN_JMP_OKAY)
+ {
+ /* setjmp returned an unknown value, exit */
+ ErrorF ("winInitMultiWindowWM - setjmp returned: %d exiting\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+ else if (iReturn == WIN_JMP_ERROR_IO)
+ {
+ ErrorF ("winInitMultiWindowWM - setjmp returned WIN_JMP_ERROR_IO\n");
+ }
+
+ /* Setup the display connection string x */
+ snprintf (pszDisplay, 512, "127.0.0.1:%s.%d", display, pProcArg->dwScreen);
+
+ /* Print the display connection string */
+ ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
+
+ /* Open the X display */
+ do
+ {
+ /* Try to open the display */
+ pWMInfo->pDisplay = XOpenDisplay (pszDisplay);
+ if (pWMInfo->pDisplay == NULL)
+ {
+ ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, "
+ "sleeping: %d\n\f",
+ iRetries + 1, WIN_CONNECT_DELAY);
+ ++iRetries;
+ sleep (WIN_CONNECT_DELAY);
+ continue;
+ }
+ else
+ break;
+ }
+ while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+
+ /* Make sure that the display opened */
+ if (pWMInfo->pDisplay == NULL)
+ {
+ ErrorF ("winInitMultiWindowWM - Failed opening the display, "
+ "giving up.\n\f");
+ pthread_exit (NULL);
+ }
+
+ ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
+
+ /* Install our error handler */
+ XSetErrorHandler (winMultiWindowWMErrorHandler);
+ XSetIOErrorHandler (winMutliWindowWMIOErrorHandler);
+
+ /* Create some atoms */
+ pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay,
+ "WM_PROTOCOLS",
+ False);
+ pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay,
+ "WM_DELETE_WINDOW",
+ False);
+}
+
+
+/*
+ * winSendMessageToWM - Send a message from the X thread to the WM thread
+ */
+
+void
+winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg)
+{
+ WMMsgNodePtr pNode;
+
+#if CYGMULTIWINDOW_DEBUG
+ ErrorF ("winSendMessageToWM ()\n");
+#endif
+
+ pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec));
+ if (pNode != NULL)
+ {
+ memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec));
+ PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode);
+ }
+}
+
+
+/*
+ * winMutliWindowWMIOErrorHandler - Our application specific IO error handler
+ */
+
+static int
+winMutliWindowWMIOErrorHandler (Display *pDisplay)
+{
+ printf ("\nwinMutliWindowWMIOErrorHandler!\n\n");
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xwin/winscrinit.c b/xc/programs/Xserver/hw/xwin/winscrinit.c
index 4b6aa689e..41811d253 100644
--- a/xc/programs/Xserver/hw/xwin/winscrinit.c
+++ b/xc/programs/Xserver/hw/xwin/winscrinit.c
@@ -29,9 +29,9 @@
* Suhaib M Siddiqi
* Peter Busch
* Harold L Hunt II
- * MATSUZAKI Kensuke
+ * Kensuke Matsuzaki
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winscrinit.c,v 1.24 2002/10/17 08:18:24 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winscrinit.c,v 1.26 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -50,13 +50,6 @@ winScreenInit (int index,
winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index];
winPrivScreenPtr pScreenPriv;
HDC hdc;
-#if 0
- DEBUG_FN_NAME("winScreenInit");
- DEBUGVARS;
- /*DEBUGPROC_MSG;*/
-
- DEBUG_MSG ("Hello");
-#endif
#if CYGDEBUG
ErrorF ("winScreenInit - dwWidth: %d dwHeight: %d\n",
@@ -113,6 +106,19 @@ winScreenInit (int index,
#endif
}
+ /*
+ * Check that all monitors have the same display depth if we are using
+ * multiple monitors
+ */
+ if (pScreenInfo->fMultipleMonitors
+ && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT))
+ {
+ ErrorF ("winScreenInit - Monitors do not all have same pixel format / "
+ "display depth.\n"
+ "Using primary display only.\n");
+ pScreenInfo->fMultipleMonitors = FALSE;
+ }
+
/* Create display window */
if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen))
{
@@ -121,12 +127,40 @@ winScreenInit (int index,
return FALSE;
}
- /* Store the initial height, width, and depth of the display */
+ /* Get a device context */
hdc = GetDC (pScreenPriv->hwndScreen);
- pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
- pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
- pScreenPriv->dwLastWindowsBitsPixel
- = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* Store the initial height, width, and depth of the display */
+ /* Are we using multiple monitors? */
+ if (pScreenInfo->fMultipleMonitors)
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+
+ /*
+ * In this case, some of the defaults set in
+ * winInitializeDefaultScreens () are not correct ...
+ */
+ if (!pScreenInfo->fUserGaveHeightAndWidth)
+ {
+ pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth /
+ WIN_DEFAULT_DPI) * 25.4;
+ pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight /
+ WIN_DEFAULT_DPI) * 25.4;
+ }
+ }
+ else
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
+
+ /* Save the original bits per pixel */
+ pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* Release the device context */
ReleaseDC (pScreenPriv->hwndScreen, hdc);
/* Clear the visuals list */
@@ -161,6 +195,7 @@ winFinishScreenInitFB (int index,
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
VisualPtr pVisual = NULL;
char *pbits = NULL;
+ int iReturn;
#if WIN_LAYER_SUPPORT
pScreenPriv->dwLayerKind = LAYER_SHADOW;
@@ -390,6 +425,9 @@ winFinishScreenInitFB (int index,
WRAP(UnrealizeWindow);
WRAP(PositionWindow);
WRAP(ChangeWindowAttributes);
+#ifdef SHAPE
+ WRAP(SetShape);
+#endif
/* Assign pseudo-rootless window procedures to be top level procedures */
pScreen->CreateWindow = winCreateWindowPRootless;
@@ -398,6 +436,50 @@ winFinishScreenInitFB (int index,
pScreen->ChangeWindowAttributes = winChangeWindowAttributesPRootless;
pScreen->RealizeWindow = winMapWindowPRootless;
pScreen->UnrealizeWindow = winUnmapWindowPRootless;
+#ifdef SHAPE
+ pScreen->SetShape = winSetShapePRootless;
+#endif
+
+ /* Undefine the WRAP macro, as it is not needed elsewhere */
+#undef WRAP
+ }
+ /* Handle multi window mode */
+ else if (pScreenInfo->fMultiWindow)
+ {
+ /* Define the WRAP macro temporarily for local use */
+#define WRAP(a) \
+ if (pScreen->a) { \
+ pScreenPriv->a = pScreen->a; \
+ } else { \
+ ErrorF("null screen fn " #a "\n"); \
+ pScreenPriv->a = NULL; \
+ }
+
+ /* Save a pointer to each lower-level window procedure */
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(PositionWindow);
+ WRAP(ChangeWindowAttributes);
+ WRAP(ReparentWindow);
+ WRAP(RestackWindow);
+#ifdef SHAPE
+ WRAP(SetShape);
+#endif
+
+ /* Assign multi-window window procedures to be top level procedures */
+ pScreen->CreateWindow = winCreateWindowMultiWindow;
+ pScreen->DestroyWindow = winDestroyWindowMultiWindow;
+ pScreen->PositionWindow = winPositionWindowMultiWindow;
+ pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;
+ pScreen->RealizeWindow = winMapWindowMultiWindow;
+ pScreen->UnrealizeWindow = winUnmapWindowMultiWindow;
+ pScreen->ReparentWindow = winReparentWindowMultiWindow;
+ pScreen->RestackWindow = winRestackWindowMultiWindow;
+#ifdef SHAPE
+ pScreen->SetShape = winSetShapeMultiWindow;
+#endif
/* Undefine the WRAP macro, as it is not needed elsewhere */
#undef WRAP
@@ -407,13 +489,65 @@ winFinishScreenInitFB (int index,
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
+ /* Create a mutex for modules in seperate threads to wait for */
+ iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL);
+ if (iReturn != 0)
+ {
+ ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n",
+ iReturn);
+ return FALSE;
+ }
+
+ /* Own the mutex for modules in seperate threads */
+ iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n",
+ iReturn);
+ return FALSE;
+ }
+
+ /* Set the ServerStarted flag to false */
+ pScreenPriv->fServerStarted = FALSE;
+
+#if CYGDEBUG || YES
+ if (pScreenInfo->fMultiWindow)
+ ErrorF ("winFinishScreenInitFB - Calling winInitWM.\n");
+#endif
+
+ /* Initialize multi window mode */
+ if (pScreenInfo->fMultiWindow
+ && !winInitWM (&pScreenPriv->pWMInfo,
+ &pScreenPriv->ptWMProc,
+ &pScreenPriv->pmServerStarted,
+ pScreenInfo->dwScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n");
+ return FALSE;
+ }
+
+#if CYGDEBUG || YES
+ if (pScreenInfo->fClipboard)
+ ErrorF ("winFinishScreenInitFB - Calling winInitClipboard.\n");
+#endif
+
+ /* Initialize the clipboard manager */
+ if (pScreenInfo->fClipboard
+ && !winInitClipboard (&pScreenPriv->ptClipboardProc,
+ &pScreenPriv->pmServerStarted,
+ pScreenInfo->dwScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - winClipboardInit () failed.\n");
+ return FALSE;
+ }
+
/* Tell the server that we are enabled */
pScreenPriv->fEnabled = TRUE;
/* Tell the server that we have a valid depth */
pScreenPriv->fBadDepth = FALSE;
-#if CYGDEBUG
+#if CYGDEBUG || YES
ErrorF ("winFinishScreenInitFB - returning\n");
#endif
diff --git a/xc/programs/Xserver/hw/xwin/winshaddd.c b/xc/programs/Xserver/hw/xwin/winshaddd.c
index 451d822aa..9c14ebf34 100644
--- a/xc/programs/Xserver/hw/xwin/winshaddd.c
+++ b/xc/programs/Xserver/hw/xwin/winshaddd.c
@@ -30,7 +30,7 @@
* Peter Busch
* Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winshaddd.c,v 1.22 2002/10/17 08:18:24 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winshaddd.c,v 1.23 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -124,18 +124,19 @@ winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen)
ErrorF ("winReleasePrimarySurfaceShadowDD - Hello\n");
- /*
- * Detach the clipper from the primary surface.
- * NOTE: We do this explicity for clarity. The Clipper is not released.
- */
- IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary,
- NULL);
-
- ErrorF ("winReleasePrimarySurfaceShadowDD - Detached clipper\n");
-
- /* Release the primary surface, if there is one */
+ /* Release the primary surface and clipper, if they exist */
if (pScreenPriv->pddsPrimary)
{
+ /*
+ * Detach the clipper from the primary surface.
+ * NOTE: We do this explicity for clarity. The Clipper is not released.
+ */
+ IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
+ NULL);
+
+ ErrorF ("winReleasePrimarySurfaceShadowDD - Detached clipper\n");
+
+ /* Release the primary surface */
IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
pScreenPriv->pddsPrimary = NULL;
}
@@ -289,10 +290,11 @@ winAllocateFBShadowDD (ScreenPtr pScreen)
}
/* Only change the video mode when different than current mode */
- if (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
- || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
- || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
- || pScreenInfo->dwRefreshRate != 0)
+ if (!pScreenInfo->fMultipleMonitors
+ && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
+ || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
+ || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
+ || pScreenInfo->dwRefreshRate != 0))
{
ErrorF ("winAllocateFBShadowDD - Changing video mode\n");
@@ -639,7 +641,7 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
if (pScreenPriv->pddcPrimary)
{
/* Detach the clipper */
- IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary,
+ IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
NULL);
/* Release the clipper object */
@@ -676,6 +678,9 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
pScreenPriv->hwndScreen = NULL;
}
+ /* Destroy the thread startup mutex */
+ pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
+
/* Kill our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
@@ -992,7 +997,7 @@ winBltExposedRegionsShadowDD (ScreenPtr pScreen)
/* Try to restore the surface, once */
ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
ErrorF ("winBltExposedRegionsShadowDDNL - "
- "IDirectDrawSurface4_Restore returned: ");
+ "IDirectDrawSurface2_Restore returned: ");
if (ddrval == DD_OK)
continue;
else if (ddrval == DDERR_WRONGMODE)
diff --git a/xc/programs/Xserver/hw/xwin/winshadddnl.c b/xc/programs/Xserver/hw/xwin/winshadddnl.c
index e1cbffeb7..69396a79b 100644
--- a/xc/programs/Xserver/hw/xwin/winshadddnl.c
+++ b/xc/programs/Xserver/hw/xwin/winshadddnl.c
@@ -30,7 +30,7 @@
* Peter Busch
* Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winshadddnl.c,v 1.23 2002/10/17 08:18:25 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winshadddnl.c,v 1.24 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -123,18 +123,19 @@ winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen)
ErrorF ("winReleasePrimarySurfaceShadowDDNL - Hello\n");
- /*
- * Detach the clipper from the primary surface.
- * NOTE: We do this explicity for clarity. The Clipper is not released.
- */
- IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
- NULL);
-
- ErrorF ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n");
-
- /* Release the primary surface, if there is one */
+ /* Release the primary surface and clipper, if they exist */
if (pScreenPriv->pddsPrimary4)
{
+ /*
+ * Detach the clipper from the primary surface.
+ * NOTE: We do this explicity for clarity. The Clipper is not released.
+ */
+ IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4,
+ NULL);
+
+ ErrorF ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n");
+
+ /* Release the primary surface */
IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4);
pScreenPriv->pddsPrimary4 = NULL;
}
@@ -307,10 +308,11 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
}
/* Only change the video mode when different than current mode */
- if (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
- || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
- || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
- || pScreenInfo->dwRefreshRate != 0)
+ if (!pScreenInfo->fMultipleMonitors
+ && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN)
+ || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN)
+ || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL)
+ || pScreenInfo->dwRefreshRate != 0))
{
ErrorF ("winAllocateFBShadowDDNL - Changing video mode\n");
@@ -418,7 +420,7 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
return FALSE;
}
-#if CYGDEBUG
+#if CYGDEBUG || YES
ErrorF ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n",
ddsdShadow.u1.lPitch);
#endif
@@ -427,6 +429,11 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen)
pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8)
/ pScreenInfo->dwBPP;
+#if CYGDEBUG || YES
+ ErrorF ("winAllocateFBShadowDDNL - Created shadow stride: %d\n",
+ pScreenInfo->dwStride);
+#endif
+
/* Save the pointer to our surface memory */
pScreenInfo->pfb = lpSurface;
@@ -541,9 +548,6 @@ winShadowUpdateDDNL (ScreenPtr pScreen,
ErrorF ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n",
pBoxExtents->x1, pBoxExtents->y1,
pBoxExtents->x2, pBoxExtents->y2);
- ErrorF ("winShadowUpdateDDNL - cl l %d t %d r %d b %d\n",
- rcClient.left, rcClient.top,
- rcClient.right, rcClient.bottom);
#endif
/* Calculating a bounding box for the source is easy */
@@ -653,9 +657,15 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen)
pScreenPriv->hwndScreen = NULL;
}
+ /* Destroy the thread startup mutex */
+ pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
+
/* Kill our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
+ /* Invalidate the ScreenInfo's fb pointer */
+ pScreenInfo->pfb = NULL;
+
/* Free the screen privates for this screen */
free ((pointer) pScreenPriv);
diff --git a/xc/programs/Xserver/hw/xwin/winshadgdi.c b/xc/programs/Xserver/hw/xwin/winshadgdi.c
index db90e8884..d2f72f20d 100644
--- a/xc/programs/Xserver/hw/xwin/winshadgdi.c
+++ b/xc/programs/Xserver/hw/xwin/winshadgdi.c
@@ -27,11 +27,19 @@
*
* Authors: Harold L Hunt II
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winshadgdi.c,v 1.21 2002/10/17 08:18:25 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winshadgdi.c,v 1.22 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
/*
+ * Local function prototypes
+ */
+
+BOOL CALLBACK
+winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam);
+
+
+/*
* Internal function to get the DIB format that is compatible with the screen
*/
@@ -198,6 +206,27 @@ winQueryRGBBitsAndMasks (ScreenPtr pScreen)
/*
+ * Redraw all ---?
+ */
+
+BOOL CALLBACK
+winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam)
+{
+ char strClassName[100];
+
+ if (GetClassName (hwnd, strClassName, 100))
+ {
+ if(strcmp (WINDOW_CLASS_X, strClassName) == 0)
+ {
+ InvalidateRect (hwnd, NULL, FALSE);
+ UpdateWindow (hwnd);
+ }
+ }
+ return TRUE;
+}
+
+
+/*
* Allocate a DIB for the shadow framebuffer GDI server
*/
@@ -207,9 +236,7 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
BITMAPINFOHEADER *pbmih = NULL;
-#if CYGDEBUG
DIBSECTION dibsection;
-#endif
Bool fReturn = TRUE;
/* Get device contexts for the screen and shadow bitmap */
@@ -232,6 +259,10 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
pbmih->biWidth = pScreenInfo->dwWidth;
pbmih->biHeight = -pScreenInfo->dwHeight;
+ ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
+ "depth: %d\n",
+ pbmih->biWidth, -pbmih->biHeight, pbmih->biBitCount);
+
/* Create a DI shadow bitmap with a bit pointer */
pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen,
(BITMAPINFO *) pbmih,
@@ -251,14 +282,18 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
#endif
}
-#if CYGDEBUG
/* Get information about the bitmap that was allocated */
- GetObject (pScreenPriv->hbmpShadow, sizeof (dibsection),
+ GetObject (pScreenPriv->hbmpShadow,
+ sizeof (dibsection),
&dibsection);
+#if CYGDEBUG || YES
/* Print information about bitmap allocated */
- ErrorF ("winAllocateFBShadowGDI - Dibsection width: %d height: %d\n",
- dibsection.dsBmih.biWidth, dibsection.dsBmih.biHeight);
+ ErrorF ("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
+ "depth: %d size image: %d\n",
+ dibsection.dsBmih.biWidth, dibsection.dsBmih.biHeight,
+ dibsection.dsBmih.biBitCount,
+ dibsection.dsBmih.biSizeImage);
#endif
/* Select the shadow bitmap into the shadow DC */
@@ -289,8 +324,14 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
}
/* Set screeninfo stride */
- pScreenInfo->dwStride = (pScreenInfo->dwPaddedWidth * 8)
- / pScreenInfo->dwBPP;
+ pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage
+ / dibsection.dsBmih.biHeight)
+ * 8) / pScreenInfo->dwBPP;
+
+#if CYGDEBUG || YES
+ ErrorF ("winAllocateFBShadowGDI - Created shadow stride: %d\n",
+ pScreenInfo->dwStride);
+#endif
/* See if the shadow bitmap will be larger than the DIB size limit */
if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP
@@ -311,6 +352,9 @@ winAllocateFBShadowGDI (ScreenPtr pScreen)
return FALSE;
}
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0);
+
return fReturn;
}
@@ -428,6 +472,9 @@ winShadowUpdateGDI (ScreenPtr pScreen,
/* Reset the clip region */
SelectClipRgn (pScreenPriv->hdcScreen, NULL);
}
+
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0);
}
@@ -475,6 +522,9 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen)
pScreenPriv->hwndScreen = NULL;
}
+ /* Destroy the thread startup mutex */
+ pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
+
/* Invalidate our screeninfo's pointer to the screen */
pScreenInfo->pScreen = NULL;
@@ -715,6 +765,9 @@ winBltExposedRegionsShadowGDI (ScreenPtr pScreen)
/* EndPaint frees the DC */
EndPaint (pScreenPriv->hwndScreen, &ps);
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0);
+
return TRUE;
}
@@ -782,6 +835,8 @@ winRedrawScreenShadowGDI (ScreenPtr pScreen)
0, 0,
SRCCOPY);
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0);
return TRUE;
}
@@ -886,6 +941,9 @@ winInstallColormapShadowGDI (ColormapPtr pColormap)
/* Save a pointer to the newly installed colormap */
pScreenPriv->pcmapInstalled = pColormap;
+ /* Redraw all windows */
+ if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadowGDI, 0);
+
return TRUE;
}
diff --git a/xc/programs/Xserver/hw/xwin/winwindow.c b/xc/programs/Xserver/hw/xwin/winwindow.c
index ae8643b32..b2469c30a 100644
--- a/xc/programs/Xserver/hw/xwin/winwindow.c
+++ b/xc/programs/Xserver/hw/xwin/winwindow.c
@@ -26,9 +26,9 @@
*from the XFree86 Project.
*
* Authors: Harold L Hunt II
- * MATSUZAKI Kensuke
+ * Kensuke Matsuzaki
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.3 2002/10/17 08:18:25 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.6 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
@@ -39,9 +39,15 @@
static int
winAddRgn (WindowPtr pWindow, pointer data);
-static void
+static
+void
winUpdateRgn (WindowPtr pWindow);
+#ifdef SHAPE
+static
+void
+winReshape (WindowPtr pWin);
+#endif
/* See Porting Layer Definition - p. 37 */
@@ -50,7 +56,7 @@ winUpdateRgn (WindowPtr pWindow);
Bool
winCreateWindowNativeGDI (WindowPtr pWin)
{
- ErrorF ("winCreateWindow()\n");
+ ErrorF ("winCreateWindowNativeGDI ()\n");
return TRUE;
}
@@ -61,7 +67,7 @@ winCreateWindowNativeGDI (WindowPtr pWin)
Bool
winDestroyWindowNativeGDI (WindowPtr pWin)
{
- ErrorF ("winDestroyWindow()\n");
+ ErrorF ("winDestroyWindowNativeGDI ()\n");
return TRUE;
}
@@ -72,7 +78,7 @@ winDestroyWindowNativeGDI (WindowPtr pWin)
Bool
winPositionWindowNativeGDI (WindowPtr pWin, int x, int y)
{
- ErrorF ("winPositionWindow()\n");
+ ErrorF ("winPositionWindowNativeGDI ()\n");
return TRUE;
}
@@ -85,7 +91,7 @@ winCopyWindowNativeGDI (WindowPtr pWin,
DDXPointRec ptOldOrg,
RegionPtr prgnSrc)
{
- ErrorF ("winCopyWindow()\n");
+ ErrorF ("winCopyWindowNativeGDI ()\n");
}
@@ -95,7 +101,7 @@ winCopyWindowNativeGDI (WindowPtr pWin,
Bool
winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask)
{
- ErrorF ("winChangeWindowAttributes()\n");
+ ErrorF ("winChangeWindowAttributesNativeGDI ()\n");
return TRUE;
}
@@ -107,7 +113,7 @@ winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask)
Bool
winUnmapWindowNativeGDI (WindowPtr pWindow)
{
- ErrorF ("winUnmapWindow()\n");
+ ErrorF ("winUnmapWindowNativeGDI ()\n");
/* This functions is empty in the CFB,
* we probably won't need to do anything
*/
@@ -122,7 +128,7 @@ winUnmapWindowNativeGDI (WindowPtr pWindow)
Bool
winMapWindowNativeGDI (WindowPtr pWindow)
{
- ErrorF ("winMapWindow()\n");
+ ErrorF ("winMapWindowNativeGDI ()\n");
/* This function is empty in the CFB,
* we probably won't need to do anything
*/
@@ -138,13 +144,15 @@ Bool
winCreateWindowPRootless (WindowPtr pWin)
{
Bool fResult = FALSE;
+ winWindowPriv(pWin);
#if CYGDEBUG
- ErrorF ("winCreateWindowPRootless()\n");
+ ErrorF ("winCreateWindowPRootless ()\n");
#endif
fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow(pWin);
+ pWinPriv->hRgn = NULL;
/*winUpdateRgn (pWin);*/
return fResult;
@@ -158,13 +166,20 @@ Bool
winDestroyWindowPRootless (WindowPtr pWin)
{
Bool fResult = FALSE;
+ winWindowPriv(pWin);
#if CYGDEBUG
- ErrorF ("winDestroyWindowPRootless()\n");
+ ErrorF ("winDestroyWindowPRootless ()\n");
#endif
fResult = winGetScreenPriv(pWin->drawable.pScreen)->DestroyWindow(pWin);
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject(pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
winUpdateRgn (pWin);
return fResult;
@@ -180,7 +195,7 @@ winPositionWindowPRootless (WindowPtr pWin, int x, int y)
Bool fResult = FALSE;
#if CYGDEBUG
- ErrorF ("winPositionWindowPRootless()\n");
+ ErrorF ("winPositionWindowPRootless ()\n");
#endif
fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow(pWin, x, y);
@@ -200,7 +215,7 @@ winChangeWindowAttributesPRootless (WindowPtr pWin, unsigned long mask)
Bool fResult = FALSE;
#if CYGDEBUG
- ErrorF ("winChangeWindowAttributesPRootless()\n");
+ ErrorF ("winChangeWindowAttributesPRootless ()\n");
#endif
fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes(pWin, mask);
@@ -219,13 +234,20 @@ Bool
winUnmapWindowPRootless (WindowPtr pWin)
{
Bool fResult = FALSE;
+ winWindowPriv(pWin);
#if CYGDEBUG
- ErrorF ("winUnmapWindowPRootless()\n");
+ ErrorF ("winUnmapWindowPRootless ()\n");
#endif
fResult = winGetScreenPriv(pWin->drawable.pScreen)->UnrealizeWindow(pWin);
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject(pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
winUpdateRgn (pWin);
return fResult;
@@ -242,57 +264,92 @@ winMapWindowPRootless (WindowPtr pWin)
Bool fResult = FALSE;
#if CYGDEBUG
- ErrorF ("winMapWindowPRootless()\n");
+ ErrorF ("winMapWindowPRootless ()\n");
#endif
fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow(pWin);
+ winReshape (pWin);
+
winUpdateRgn (pWin);
return fResult;
}
+#ifdef SHAPE
+void
+winSetShapePRootless (WindowPtr pWin)
+{
+#if CYGDEBUG
+ ErrorF ("winSetShapePRootless ()\n");
+#endif
+
+ winGetScreenPriv(pWin->drawable.pScreen)->SetShape(pWin);
+
+ winReshape (pWin);
+ winUpdateRgn (pWin);
+
+ return;
+}
+#endif
+
+
/*
* Local function for adding a region to the Windows window region
*/
static
int
-winAddRgn (WindowPtr pWindow, pointer data)
+winAddRgn (WindowPtr pWin, pointer data)
{
int iX, iY, iWidth, iHeight, iBorder;
HRGN hRgn = *(HRGN*)data;
HRGN hRgnWin;
+ winWindowPriv(pWin);
- /* If pWindow is not Root */
- if (pWindow->parent != NULL)
+ /* If pWin is not Root */
+ if (pWin->parent != NULL)
{
- ErrorF("winAddRgn()\n");
- if (pWindow->mapped)
+#if CYGDEBUG
+ ErrorF ("winAddRgn ()\n");
+#endif
+ if (pWin->mapped)
{
- iBorder = wBorderWidth (pWindow);
+ iBorder = wBorderWidth (pWin);
+
+ iX = pWin->drawable.x - iBorder;
+ iY = pWin->drawable.y - iBorder;
- iX = pWindow->drawable.x - iBorder;
- iY = pWindow->drawable.y - iBorder;
+ iWidth = pWin->drawable.width + iBorder * 2;
+ iHeight = pWin->drawable.height + iBorder * 2;
- iWidth = pWindow->drawable.width + iBorder * 2;
- iHeight = pWindow->drawable.height + iBorder * 2;
+ hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight);
- hRgnWin = CreateRectRgn (iX, iY, iX + iWidth, iY + iHeight);
if (hRgnWin == NULL)
{
- ErrorF ("winAddRgn - CreateRectRgn() failed\n");
+ ErrorF ("winAddRgn - CreateRectRgn () failed\n");
ErrorF (" Rect %d %d %d %d\n",
- iX, iY, iX + iWidth, iY + iHeight);
+ iX, iY, iX + iWidth, iY + iHeight);
+ }
+
+ if (pWinPriv->hRgn)
+ {
+ if (CombineRgn (hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND)
+ == ERROR)
+ {
+ ErrorF ("winAddRgn - CombineRgn () failed\n");
+ }
}
+
+ OffsetRgn (hRgnWin, iX, iY);
if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR)
{
- ErrorF("winAddRgn - CombineRgn() failed\n");
+ ErrorF ("winAddRgn - CombineRgn () failed\n");
}
- DeleteObject(hRgnWin);
+ DeleteObject (hRgnWin);
}
return WT_DONTWALKCHILDREN;
}
@@ -309,18 +366,98 @@ winAddRgn (WindowPtr pWindow, pointer data)
static
void
-winUpdateRgn (WindowPtr pWindow)
+winUpdateRgn (WindowPtr pWin)
{
HRGN hRgn = CreateRectRgn (0, 0, 0, 0);
if (hRgn != NULL)
{
- WalkTree (pWindow->drawable.pScreen, winAddRgn, &hRgn);
- SetWindowRgn (winGetScreenPriv(pWindow->drawable.pScreen)->hwndScreen,
+ WalkTree (pWin->drawable.pScreen, winAddRgn, &hRgn);
+ SetWindowRgn (winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen,
hRgn, TRUE);
}
else
{
- ErrorF ("winUpdateRgn fail to CreateRectRgn\n");
+ ErrorF ("winUpdateRgn - CreateRectRgn failed.\n");
}
}
+
+
+#ifdef SHAPE
+static
+void
+winReshape (WindowPtr pWin)
+{
+ int nRects;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RegionRec rrNewShape;
+ BoxPtr pShape, pRects, pEnd;
+ HRGN hRgn, hRgnRect;
+ winWindowPriv(pWin);
+
+#if CYGDEBUG
+ ErrorF ("winReshape ()\n");
+#endif
+
+ /* Bail if the window is the root window */
+ if (pWin->parent == NULL)
+ return;
+
+ /* Bail if the window is not top level */
+ if (pWin->parent->parent != NULL)
+ return;
+
+ /* Free any existing window region stored in the window privates */
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject (pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
+ /* Bail if the window has no bounding region defined */
+ if (!wBoundingShape (pWin))
+ return;
+
+ REGION_INIT(pScreen, &rrNewShape, NullBox, 0);
+ REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin));
+ REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth,
+ pWin->borderWidth);
+
+ nRects = REGION_NUM_RECTS(&rrNewShape);
+ pShape = REGION_RECTS(&rrNewShape);
+
+ if (nRects > 0)
+ {
+ /* Create initial empty Windows region */
+ hRgn = CreateRectRgn (0, 0, 0, 0);
+
+ /* Loop through all rectangles in the X region */
+ for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++)
+ {
+ /* Create a Windows region for the X rectangle */
+ hRgnRect = CreateRectRgn (pRects->x1, pRects->y1,
+ pRects->x2, pRects->y2);
+ if (hRgnRect == NULL)
+ {
+ ErrorF("winReshape - CreateRectRgn() failed\n");
+ }
+
+ /* Merge the Windows region with the accumulated region */
+ if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
+ {
+ ErrorF("winReshape - CombineRgn() failed\n");
+ }
+
+ /* Delete the temporary Windows region */
+ DeleteObject (hRgnRect);
+ }
+
+ /* Save a handle to the composite region in the window privates */
+ pWinPriv->hRgn = hRgn;
+ }
+
+ REGION_UNINIT(pScreen, &rrNewShape);
+
+ return;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xwin/winwindow.h b/xc/programs/Xserver/hw/xwin/winwindow.h
new file mode 100644
index 000000000..d828b4c70
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winwindow.h
@@ -0,0 +1,118 @@
+/*
+ *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.
+ *
+ * Authors: Kensuke Matsuzaki
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.h,v 1.1 2003/02/12 15:01:38 alanh Exp $ */
+
+
+#ifndef _WINWINDOW_H_
+#define _WINWINDOW_H_
+
+#ifndef NO
+#define NO 0
+#endif
+#ifndef YES
+#define YES 1
+#endif
+
+/* Constant strings */
+#define WINDOW_CLASS "cygwin/xfree86 rl"
+#define WINDOW_TITLE "Cygwin/XFree86 rl"
+#define WIN_SCR_PROP "cyg_screen_prop_rl"
+#define WINDOW_CLASS_X "cygwin/xfree86 X rl"
+#define WINDOW_TITLE_X "Cygwin/XFree86 X rl"
+#define WIN_WINDOW_PROP "cyg_window_prop_rl"
+#define WIN_MSG_QUEUE_FNAME "/dev/windows"
+#define WIN_LOG_FNAME "/tmp/XWinrl.log"
+#define WIN_WID_PROP "cyg_wid_prop_rl"
+#define WIN_NEEDMANAGE_PROP "cyg_override_redirect_prop_rl"
+#define CYGMULTIWINDOW_DEBUG NO
+
+typedef struct _winPrivScreenRec *winPrivScreenPtr;
+
+/*
+ * Window privates
+ */
+
+typedef struct
+{
+ DWORD dwDummy;
+ HRGN hRgn;
+ HWND hWnd;
+ winPrivScreenPtr pScreenPriv;
+ int iX;
+ int iY;
+ int iWidth;
+ int iHeight;
+ Bool fXKilled;
+} winPrivWinRec, *winPrivWinPtr;
+
+typedef struct _winWMMessageRec{
+ DWORD dwID;
+ DWORD msg;
+ int iWindow;
+ HWND hwndWindow;
+ int iX, iY;
+ int iWidth, iHeight;
+} winWMMessageRec, *winWMMessagePtr;
+
+/*
+ * winrootlesswm.c
+ */
+#define WM_WM_MOVE (WM_USER + 1)
+#define WM_WM_SIZE (WM_USER + 2)
+#define WM_WM_RAISE (WM_USER + 3)
+#define WM_WM_LOWER (WM_USER + 4)
+#define WM_WM_MAP (WM_USER + 5)
+#define WM_WM_UNMAP (WM_USER + 6)
+#define WM_WM_KILL (WM_USER + 7)
+#define WM_WM_ACTIVATE (WM_USER + 8)
+
+#define WMMSG_MSG 10
+
+
+/*
+ * winmultiwindowwm.c
+ */
+
+void
+winSendMessageToWM (void *pWMInfo, winWMMessagePtr msg);
+
+Bool
+winInitWM (void **ppWMInfo,
+ pthread_t *ptWMProc,
+#if 0
+ pthread_cond_t *ppcServerStarted,
+#endif
+ pthread_mutex_t *ppmServerStarted,
+#if 0
+ Bool *pfServerStarted,
+#endif
+ int dwScreen);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xwin/winwndproc.c b/xc/programs/Xserver/hw/xwin/winwndproc.c
index 5bdd18c82..6aa29316d 100644
--- a/xc/programs/Xserver/hw/xwin/winwndproc.c
+++ b/xc/programs/Xserver/hw/xwin/winwndproc.c
@@ -31,7 +31,7 @@
* Harold L Hunt II
* MATSUZAKI Kensuke
*/
-/* $XFree86: xc/programs/Xserver/hw/xwin/winwndproc.c,v 1.23 2002/10/17 08:18:25 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winwndproc.c,v 1.24 2003/02/12 15:01:38 alanh Exp $ */
#include "win.h"
#include <commctrl.h>
@@ -300,6 +300,7 @@ winWindowProc (HWND hwnd, UINT message,
if (!s_pScreenInfo->fScrollbars
|| !s_pScreenInfo->fDecoration
|| s_pScreenInfo->fRootless
+ || s_pScreenInfo->fMultiWindow
|| s_pScreenInfo->fFullScreen)
break;
@@ -569,7 +570,8 @@ winWindowProc (HWND hwnd, UINT message,
|| !s_pScreenInfo->fScrollbars
|| s_pScreenInfo->fFullScreen
|| !s_pScreenInfo->fDecoration
- || s_pScreenInfo->fRootless)
+ || s_pScreenInfo->fRootless
+ || s_pScreenInfo->fMultiWindow)
break;
/*