diff options
Diffstat (limited to 'xorg-server/hw/xwin')
-rw-r--r-- | xorg-server/hw/xwin/InitOutput.c | 2 | ||||
-rw-r--r-- | xorg-server/hw/xwin/man/XWin.man | 3 | ||||
-rw-r--r-- | xorg-server/hw/xwin/win.h | 2981 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winclipboardxevents.c | 1607 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winmonitors.c | 2 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winmultiwindowicons.c | 1283 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winmultiwindowwindow.c | 2000 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winmultiwindowwm.c | 3532 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winpfbdd.c | 3 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winprefs.c | 1684 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winprefs.h | 380 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winscrinit.c | 4 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winshaddd.c | 3 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winshadddnl.c | 3 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winshadgdi.c | 3 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winvideo.c | 418 | ||||
-rw-r--r-- | xorg-server/hw/xwin/winwin32rootless.c | 2140 |
17 files changed, 8047 insertions, 8001 deletions
diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index 7faed0170..22ef8da76 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -49,7 +49,7 @@ from The Open Group. #endif #ifdef RELOCATE_PROJECTROOT #include <shlobj.h> -typedef HRESULT (*SHGETFOLDERPATHPROC)( +typedef WINAPI HRESULT (*SHGETFOLDERPATHPROC)( HWND hwndOwner, int nFolder, HANDLE hToken, diff --git a/xorg-server/hw/xwin/man/XWin.man b/xorg-server/hw/xwin/man/XWin.man index e7933c9c8..aad29cf25 100644 --- a/xorg-server/hw/xwin/man/XWin.man +++ b/xorg-server/hw/xwin/man/XWin.man @@ -67,7 +67,7 @@ The default behaviour is to create a single screen 0 that is roughly the size of useful area of the primary monitor (allowing for any window decorations and the task-bar). -Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a +Screen specific parameters can be applied as a default to all screens by placing those screen specific parameters before any \fB\-screen\fP parameter. Screen specific parameters placed after the first \fB\-screen\fP parameter will apply only to the immediately @@ -108,6 +108,7 @@ in \fB-multiwindow\fP or \fB-rootless\fP mode. .B "\-fullscreen" The X server window takes the full screen, covering completely the \fIWindows\fP desktop. +Currently \fB\-fullscreen\fP may only be applied to one X screen. .TP 8 .B \-nodecoration Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h index e57cb4fa2..9bee9b64f 100644 --- a/xorg-server/hw/xwin/win.h +++ b/xorg-server/hw/xwin/win.h @@ -1,1491 +1,1490 @@ -/*
- *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: Dakshinamurthy Karra
- * Suhaib M Siddiqi
- * Peter Busch
- * Harold L Hunt II
- * Kensuke Matsuzaki
- */
-
-#ifndef _WIN_H_
-#define _WIN_H_
-
-#ifndef NO
-#define NO 0
-#endif
-#ifndef YES
-#define YES 1
-#endif
-
-/* Turn debug messages on or off */
-#ifndef CYGDEBUG
-#define CYGDEBUG NO
-#endif
-
-/* WM_XBUTTON Messages. They should go into w32api. */
-#ifndef WM_XBUTTONDOWN
-# define WM_XBUTTONDOWN 523
-#endif
-#ifndef WM_XBUTTONUP
-# define WM_XBUTTONUP 524
-#endif
-#ifndef WM_XBUTTONDBLCLK
-# define WM_XBUTTONDBLCLK 525
-#endif
-
-
-#define WIN_DEFAULT_BPP 0
-#define WIN_DEFAULT_WHITEPIXEL 255
-#define WIN_DEFAULT_BLACKPIXEL 0
-#define WIN_DEFAULT_LINEBIAS 0
-#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */
-#define WIN_DEFAULT_DPI 75
-#define WIN_DEFAULT_REFRESH 0
-#define WIN_DEFAULT_WIN_KILL TRUE
-#define WIN_DEFAULT_UNIX_KILL FALSE
-#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0
-#ifdef XWIN_EMULATEPSEUDO
-#define WIN_DEFAULT_EMULATE_PSEUDO FALSE
-#endif
-#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE
-
-/*
- * Windows only supports 256 color palettes
- */
-#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
-
-/*
- * Build a supported display depths mask by shifting one to the left
- * by the number of bits in the supported depth.
- */
-#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \
- | (1 << (16 - 1)) | (1 << (15 - 1)) \
- | (1 << ( 8 - 1)))
-#define WIN_CHECK_DEPTH YES
-
-/*
- * Timer IDs for WM_TIMER
- */
-#define WIN_E3B_TIMER_ID 1
-#define WIN_POLLING_MOUSE_TIMER_ID 2
-
-#define MOUSE_POLLING_INTERVAL 50
-
-#define WIN_E3B_OFF -1
-#define WIN_FD_INVALID -1
-
-#define WIN_SERVER_NONE 0x0L /* 0 */
-#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */
-#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */
-#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */
-#ifdef XWIN_PRIMARYFB
-#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */
-#endif
-#ifdef XWIN_NATIVEGDI
-# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */
-#endif
-
-#define AltMapIndex Mod1MapIndex
-#define NumLockMapIndex Mod2MapIndex
-#define AltLangMapIndex Mod3MapIndex
-#define KanaMapIndex Mod4MapIndex
-#define ScrollLockMapIndex Mod5MapIndex
-
-#define WIN_MOD_LALT 0x00000001
-#define WIN_MOD_RALT 0x00000002
-#define WIN_MOD_LCONTROL 0x00000004
-#define WIN_MOD_RCONTROL 0x00000008
-
-#define WIN_24BPP_MASK_RED 0x00FF0000
-#define WIN_24BPP_MASK_GREEN 0x0000FF00
-#define WIN_24BPP_MASK_BLUE 0x000000FF
-
-#define WIN_MAX_KEYS_PER_KEY 4
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
-#include <errno.h>
-#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-#define HANDLE void *
-#include <pthread.h>
-#undef HANDLE
-#endif
-
-#ifdef HAS_MMAP
-#include <sys/mman.h>
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif /* MAP_FILE */
-#endif /* HAS_MMAP */
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xos.h>
-#include <X11/Xprotostr.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "pixmap.h"
-#include "region.h"
-#include "gcstruct.h"
-#include "colormap.h"
-#include "colormapst.h"
-#include "miscstruct.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "micmap.h"
-#include "mifillarc.h"
-#include "mifpoly.h"
-#include "mibstore.h"
-#include "input.h"
-#include "mipointer.h"
-#include "X11/keysym.h"
-#include "mibstore.h"
-#include "micoord.h"
-#include "dix.h"
-#include "miline.h"
-#include "shadow.h"
-#include "fb.h"
-#include "rootless.h"
-
-#include "mipict.h"
-#include "picturestr.h"
-
-#ifdef RANDR
-#include "randrstr.h"
-#endif
-
-/*
- * Windows headers
- */
-#include "winms.h"
-#include "winresource.h"
-
-
-/*
- * Define Windows constants
- */
-
-#define WM_TRAYICON (WM_USER + 1000)
-#define WM_INIT_SYS_MENU (WM_USER + 1001)
-#define WM_GIVEUP (WM_USER + 1002)
-
-
-/* Local includes */
-#include "winwindow.h"
-#include "winmsg.h"
-
-
-/*
- * Debugging macros
- */
-
-#if CYGDEBUG
-#define DEBUG_MSG(str,...) \
-if (fDebugProcMsg) \
-{ \
- char *pszTemp; \
- int iLength; \
- if (asprintf (&pszTemp, str, ##__VA_ARGS__) != -1) { \
- MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \
- free (pszTemp); \
- } \
-}
-#else
-#define DEBUG_MSG(str,...)
-#endif
-
-#if CYGDEBUG
-#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str
-#else
-#define DEBUG_FN_NAME(str)
-#endif
-
-#if CYGDEBUG || YES
-#define DEBUGVARS BOOL fDebugProcMsg = FALSE
-#else
-#define DEBUGVARS
-#endif
-
-#if CYGDEBUG || YES
-#define DEBUGPROC_MSG fDebugProcMsg = TRUE
-#else
-#define DEBUGPROC_MSG
-#endif
-
-#define PROFILEPOINT(point,thresh)\
-{\
-static unsigned int PROFPT##point = 0;\
-if (++PROFPT##point % thresh == 0)\
-ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\
-}
-
-
-/* We use xor this macro for detecting toggle key state changes */
-#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
-
-#define DEFINE_ATOM_HELPER(func,atom_name) \
-static Atom func (void) { \
- static int generation; \
- static Atom atom; \
- if (generation != serverGeneration) { \
- generation = serverGeneration; \
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
- } \
- return atom; \
-}
-
-/*
- * Typedefs for engine dependent function pointers
- */
-
-typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
-
-typedef void (*winFreeFBProcPtr)(ScreenPtr);
-
-typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
-
-typedef Bool (*winInitScreenProcPtr)(ScreenPtr);
-
-typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
-
-typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
-
-typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr);
-
-typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr);
-
-typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **);
-
-typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr);
-
-typedef Bool (*winActivateAppProcPtr)(ScreenPtr);
-
-typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen);
-
-typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen);
-
-typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap,
- int ndef, xColorItem *pdefs);
-
-typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr);
-
-typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr);
-
-typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr);
-
-typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin);
-
-typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr);
-
-#ifdef XWIN_NATIVEGDI
-/* Typedefs for native GDI wrappers */
-typedef Bool (*RealizeFontPtr) (ScreenPtr pScreen, FontPtr pFont);
-typedef Bool (*UnrealizeFontPtr)(ScreenPtr pScreen, FontPtr pFont);
-#endif
-
-
-/*
- * GC (graphics context) privates
- */
-
-typedef struct
-{
- HDC hdc;
- HDC hdcMem;
-} winPrivGCRec, *winPrivGCPtr;
-
-
-/*
- * Pixmap privates
- */
-
-typedef struct
-{
- HDC hdcSelected;
- HBITMAP hBitmap;
- BYTE *pbBits;
- DWORD dwScanlineBytes;
- BITMAPINFOHEADER *pbmih;
-} winPrivPixmapRec, *winPrivPixmapPtr;
-
-
-/*
- * Colormap privates
- */
-
-typedef struct
-{
- HPALETTE hPalette;
- LPDIRECTDRAWPALETTE lpDDPalette;
- RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
- PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
-} winPrivCmapRec, *winPrivCmapPtr;
-
-/*
- * Windows Cursor handling.
- */
-
-typedef struct {
- /* from GetSystemMetrics */
- int sm_cx;
- int sm_cy;
-
- BOOL visible;
- HCURSOR handle;
- QueryBestSizeProcPtr QueryBestSize;
- miPointerSpriteFuncPtr spriteFuncs;
-} winCursorRec;
-
-/*
- * Resize modes
- */
-typedef enum {
- notAllowed,
- resizeWithScrollbars,
- resizeWithRandr
-} winResizeMode;
-
-/*
- * Screen information structure that we need before privates are available
- * in the server startup sequence.
- */
-
-typedef struct
-{
- ScreenPtr pScreen;
-
- /* Did the user specify a height and width? */
- Bool fUserGaveHeightAndWidth;
-
- DWORD dwScreen;
-
- int iMonitor;
- DWORD dwUserWidth;
- DWORD dwUserHeight;
- DWORD dwWidth;
- DWORD dwHeight;
- DWORD dwPaddedWidth;
-
- /* Did the user specify a screen position? */
- Bool fUserGavePosition;
- DWORD dwInitialX;
- DWORD dwInitialY;
-
- /*
- * dwStride is the number of whole pixels that occupy a scanline,
- * including those pixels that are not displayed. This is basically
- * a rounding up of the width.
- */
- DWORD dwStride;
-
- /* Offset of the screen in the window when using scrollbars */
- DWORD dwXOffset;
- DWORD dwYOffset;
-
- DWORD dwBPP;
- DWORD dwDepth;
- DWORD dwRefreshRate;
- char *pfb;
- DWORD dwEngine;
- DWORD dwEnginePreferred;
- DWORD dwClipUpdatesNBoxes;
-#ifdef XWIN_EMULATEPSEUDO
- Bool fEmulatePseudo;
-#endif
- Bool fFullScreen;
- Bool fDecoration;
-#ifdef XWIN_MULTIWINDOWEXTWM
- Bool fMWExtWM;
- Bool fInternalWM;
- Bool fAnotherWMRunning;
-#endif
- Bool fRootless;
-#ifdef XWIN_MULTIWINDOW
- Bool fMultiWindow;
-#endif
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
- Bool fMultiMonitorOverride;
-#endif
- Bool fMultipleMonitors;
- Bool fLessPointer;
- winResizeMode iResizeMode;
- Bool fNoTrayIcon;
- int iE3BTimeout;
- /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */
- Bool fUseWinKillKey;
- Bool fUseUnixKillKey;
- Bool fIgnoreInput;
-
- /* Did the user explicitly set this screen? */
- Bool fExplicitScreen;
-} winScreenInfo, *winScreenInfoPtr;
-
-
-/*
- * Screen privates
- */
-
-typedef struct _winPrivScreenRec
-{
- winScreenInfoPtr pScreenInfo;
-
- Bool fEnabled;
- Bool fClosed;
- Bool fActive;
- Bool fBadDepth;
-
- int iDeltaZ;
-
- int iConnectedClients;
-
- CloseScreenProcPtr CloseScreen;
-
- DWORD dwRedMask;
- DWORD dwGreenMask;
- DWORD dwBlueMask;
- DWORD dwBitsPerRGB;
-
- DWORD dwModeKeyStates;
-
- /* Handle to icons that must be freed */
- HICON hiconNotifyIcon;
-
- /* Palette management */
- ColormapPtr pcmapInstalled;
-
- /* Pointer to the root visual so we only have to look it up once */
- VisualPtr pRootVisual;
-
- /* 3 button emulation variables */
- int iE3BCachedPress;
- Bool fE3BFakeButton2Sent;
-
- /* Privates used by shadow fb GDI server */
- HBITMAP hbmpShadow;
- HDC hdcScreen;
- HDC hdcShadow;
- HWND hwndScreen;
- BITMAPINFOHEADER *pbmih;
-
- /* Privates used by shadow fb and primary fb DirectDraw servers */
- LPDIRECTDRAW pdd;
- LPDIRECTDRAWSURFACE2 pddsPrimary;
- LPDIRECTDRAW2 pdd2;
-
- /* Privates used by shadow fb DirectDraw server */
- LPDIRECTDRAWSURFACE2 pddsShadow;
- LPDDSURFACEDESC pddsdShadow;
-
- /* Privates used by primary fb DirectDraw server */
- LPDIRECTDRAWSURFACE2 pddsOffscreen;
- LPDDSURFACEDESC pddsdOffscreen;
- LPDDSURFACEDESC pddsdPrimary;
-
- /* Privates used by shadow fb DirectDraw Nonlocking server */
- LPDIRECTDRAW4 pdd4;
- LPDIRECTDRAWSURFACE4 pddsShadow4;
- LPDIRECTDRAWSURFACE4 pddsPrimary4;
- BOOL fRetryCreateSurface;
-
- /* Privates used by both shadow fb DirectDraw servers */
- LPDIRECTDRAWCLIPPER pddcPrimary;
-
-#ifdef XWIN_MULTIWINDOWEXTWM
- /* Privates used by multi-window external window manager */
- RootlessFrameID widTop;
- Bool fRestacking;
-#endif
-
-#ifdef XWIN_MULTIWINDOW
- /* Privates used by multi-window */
- pthread_t ptWMProc;
- pthread_t ptXMsgProc;
- void *pWMInfo;
-#endif
-
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
- /* Privates used by both multi-window and rootless */
- Bool fRootWindowShown;
-#endif
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
- /* Privates used for any module running in a seperate thread */
- pthread_mutex_t pmServerStarted;
- Bool fServerStarted;
-#endif
-
- /* Engine specific functions */
- winAllocateFBProcPtr pwinAllocateFB;
- winFreeFBProcPtr pwinFreeFB;
- winShadowUpdateProcPtr pwinShadowUpdate;
- winInitScreenProcPtr pwinInitScreen;
- winCloseScreenProcPtr pwinCloseScreen;
- winInitVisualsProcPtr pwinInitVisuals;
- winAdjustVideoModeProcPtr pwinAdjustVideoMode;
- winCreateBoundingWindowProcPtr pwinCreateBoundingWindow;
- winFinishScreenInitProcPtr pwinFinishScreenInit;
- winBltExposedRegionsProcPtr pwinBltExposedRegions;
- winActivateAppProcPtr pwinActivateApp;
- winRedrawScreenProcPtr pwinRedrawScreen;
- winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette;
- winInstallColormapProcPtr pwinInstallColormap;
- winStoreColorsProcPtr pwinStoreColors;
- winCreateColormapProcPtr pwinCreateColormap;
- winDestroyColormapProcPtr pwinDestroyColormap;
- winHotKeyAltTabProcPtr pwinHotKeyAltTab;
- winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
- winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
-
- winCreateScreenResourcesProc pwinCreateScreenResources;
-
-#ifdef XWIN_MULTIWINDOW
- /* Window Procedures for MultiWindow mode */
- winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow;
-#endif
-
- /* Window Procedures for Rootless mode */
- CreateWindowProcPtr CreateWindow;
- DestroyWindowProcPtr DestroyWindow;
- PositionWindowProcPtr PositionWindow;
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- ValidateTreeProcPtr ValidateTree;
- PostValidateTreeProcPtr PostValidateTree;
- WindowExposuresProcPtr WindowExposures;
- CopyWindowProcPtr CopyWindow;
- ClearToBackgroundProcPtr ClearToBackground;
- ClipNotifyProcPtr ClipNotify;
- RestackWindowProcPtr RestackWindow;
- ReparentWindowProcPtr ReparentWindow;
- ResizeWindowProcPtr ResizeWindow;
- MoveWindowProcPtr MoveWindow;
- SetShapeProcPtr SetShape;
-
- winCursorRec cursor;
-
-#ifdef XWIN_NATIVEGDI
- RealizeFontPtr RealizeFont;
- UnrealizeFontPtr UnrealizeFont;
-#endif
-
-} winPrivScreenRec;
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-typedef struct {
- RootlessWindowPtr pFrame;
- HWND hWnd;
- int dwWidthBytes;
- BITMAPINFOHEADER *pbmihShadow;
- HBITMAP hbmpShadow;
- HDC hdcShadow;
- HDC hdcScreen;
- BOOL fResized;
- BOOL fRestackingNow;
- BOOL fClose;
- BOOL fMovingOrSizing;
- BOOL fDestroyed;//for debug
- char *pfb;
-} win32RootlessWindowRec, *win32RootlessWindowPtr;
-#endif
-
-
-typedef struct {
- pointer value;
- XID id;
-} WindowIDPairRec, *WindowIDPairPtr;
-
-
-/*
- * Extern declares for general global variables
- */
-
-#include "winglobals.h"
-
-extern winScreenInfo * g_ScreenInfo;
-extern miPointerScreenFuncRec g_winPointerCursorFuncs;
-extern DWORD g_dwEvents;
-#ifdef HAS_DEVWINDOWS
-extern int g_fdMessageQueue;
-#endif
-extern DevPrivateKeyRec g_iScreenPrivateKeyRec;
-#define g_iScreenPrivateKey (&g_iScreenPrivateKeyRec)
-extern DevPrivateKeyRec g_iCmapPrivateKeyRec;
-#define g_iCmapPrivateKey (&g_iCmapPrivateKeyRec)
-extern DevPrivateKeyRec g_iGCPrivateKeyRec;
-#define g_iGCPrivateKey (&g_iGCPrivateKeyRec)
-extern DevPrivateKeyRec g_iPixmapPrivateKeyRec;
-#define g_iPixmapPrivateKey (&g_iPixmapPrivateKeyRec)
-extern DevPrivateKeyRec g_iWindowPrivateKeyRec;
-#define g_iWindowPrivateKey (&g_iWindowPrivateKeyRec)
-
-extern unsigned long g_ulServerGeneration;
-extern DWORD g_dwEnginesSupported;
-extern HINSTANCE g_hInstance;
-extern int g_copyROP[];
-extern int g_patternROP[];
-extern const char * g_pszQueryHost;
-extern DeviceIntPtr g_pwinPointer;
-extern DeviceIntPtr g_pwinKeyboard;
-
-/*
- * Extern declares for dynamically loaded library function pointers
- */
-
-extern FARPROC g_fpDirectDrawCreate;
-extern FARPROC g_fpDirectDrawCreateClipper;
-extern FARPROC g_fpTrackMouseEvent;
-
-
-/*
- * Screen privates macros
- */
-
-#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey))
-
-#define winSetScreenPriv(pScreen,v) \
- dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v)
-
-#define winScreenPriv(pScreen) \
- winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen)
-
-
-/*
- * Colormap privates macros
- */
-
-#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \
- dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey))
-
-#define winSetCmapPriv(pCmap,v) \
- dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v)
-
-#define winCmapPriv(pCmap) \
- winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap)
-
-
-/*
- * GC privates macros
- */
-
-#define winGetGCPriv(pGC) ((winPrivGCPtr) \
- dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey))
-
-#define winSetGCPriv(pGC,v) \
- dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v)
-
-#define winGCPriv(pGC) \
- winPrivGCPtr pGCPriv = winGetGCPriv(pGC)
-
-
-/*
- * Pixmap privates macros
- */
-
-#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \
- dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey))
-
-#define winSetPixmapPriv(pPixmap,v) \
- dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v)
-
-#define winPixmapPriv(pPixmap) \
- winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap)
-
-
-/*
- * Window privates macros
- */
-
-#define winGetWindowPriv(pWin) ((winPrivWinPtr) \
- dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey))
-
-#define winSetWindowPriv(pWin,v) \
- dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v)
-
-#define winWindowPriv(pWin) \
- winPrivWinPtr pWinPriv = winGetWindowPriv(pWin)
-
-/*
- * wrapper macros
- */
-#define _WIN_WRAP(priv, real, mem, func) {\
- priv->mem = real->mem; \
- real->mem = func; \
-}
-
-#define _WIN_UNWRAP(priv, real, mem) {\
- real->mem = priv->mem; \
-}
-
-#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func)
-
-#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem)
-
-/*
- * BEGIN DDX and DIX Function Prototypes
- */
-
-
-/*
- * winallpriv.c
- */
-
-Bool
-winAllocatePrivates (ScreenPtr pScreen);
-
-Bool
-winInitCmapPrivates (ColormapPtr pCmap, int index);
-
-Bool
-winAllocateCmapPrivates (ColormapPtr pCmap);
-
-
-/*
- * winauth.c
- */
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-Bool
-winGenerateAuthorization (void);
-void winSetAuthorization(void);
-#endif
-
-
-/*
- * winblock.c
- */
-
-void
-winBlockHandler (int nScreen,
- pointer pBlockData,
- pointer pTimeout,
- pointer pReadMask);
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winclip.c
- */
-
-RegionPtr
-winPixmapToRegionNativeGDI (PixmapPtr pPix);
-#endif
-
-
-#ifdef XWIN_CLIPBOARD
-/*
- * winclipboardinit.c
- */
-
-Bool
-winInitClipboard (void);
-
-void
-winFixClipboardChain (void);
-#endif
-
-
-/*
- * wincmap.c
- */
-
-void
-winSetColormapFunctions (ScreenPtr pScreen);
-
-Bool
-winCreateDefColormap (ScreenPtr pScreen);
-
-
-/*
- * wincreatewnd.c
- */
-
-Bool
-winCreateBoundingWindowFullScreen (ScreenPtr pScreen);
-
-Bool
-winCreateBoundingWindowWindowed (ScreenPtr pScreen);
-
-
-/*
- * windialogs.c
- */
-
-void
-winDisplayExitDialog (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayAboutDialog (winPrivScreenPtr pScreenPriv);
-
-
-/*
- * winengine.c
- */
-
-void
-winDetectSupportedEngines (void);
-
-Bool
-winSetEngine (ScreenPtr pScreen);
-
-Bool
-winGetDDProcAddresses (void);
-
-void
-winReleaseDDProcAddresses(void);
-
-
-/*
- * winerror.c
- */
-
-#ifdef DDXOSVERRORF
-void
-OSVenderVErrorF (const char *pszFormat, va_list va_args);
-#endif
-
-void
-winMessageBoxF (const char *pszError, UINT uType, ...);
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winfillsp.c
- */
-
-void
-winFillSpansNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- int nSpans,
- DDXPointPtr pPoints,
- int *pWidths,
- int fSorted);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winfont.c
- */
-
-Bool
-winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
-
-Bool
-winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * wingc.c
- */
-
-Bool
-winCreateGCNativeGDI (GCPtr pGC);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * wingetsp.c
- */
-
-void
-winGetSpansNativeGDI (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr pPoints,
- int *pWidths,
- int nSpans,
- char *pDst);
-#endif
-
-
-/*
- * winglobals.c
- */
-
-void
-winInitializeGlobals (void);
-
-
-/*
- * winkeybd.c
- */
-
-void
-winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode);
-
-int
-winKeybdProc (DeviceIntPtr pDeviceInt, int iState);
-
-void
-winInitializeModeKeyStates (void);
-
-void
-winRestoreModeKeyStates (void);
-
-Bool
-winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam);
-
-void
-winKeybdReleaseKeys (void);
-
-void
-winSendKeyEvent (DWORD dwKey, Bool fDown);
-
-BOOL
-winCheckKeyPressed(WPARAM wParam, LPARAM lParam);
-
-void
-winFixShiftKeys (int iScanCode);
-
-/*
- * winkeyhook.c
- */
-
-Bool
-winInstallKeyboardHookLL (void);
-
-void
-winRemoveKeyboardHookLL (void);
-
-
-/*
- * winmisc.c
- */
-
-#ifdef XWIN_NATIVEGDI
-void
-winQueryBestSizeNativeGDI (int class, unsigned short *pWidth,
- unsigned short *pHeight, ScreenPtr pScreen);
-#endif
-
-CARD8
-winCountBits (DWORD dw);
-
-Bool
-winUpdateFBPointer (ScreenPtr pScreen, void *pbits);
-
-#ifdef XWIN_NATIVEGDI
-BOOL
-winPaintBackground (HWND hwnd, COLORREF colorref);
-#endif
-
-
-/*
- * winmouse.c
- */
-
-int
-winMouseProc (DeviceIntPtr pDeviceInt, int iState);
-
-int
-winMouseWheel (ScreenPtr pScreen, int iDeltaZ);
-
-void
-winMouseButtonsSendEvent (int iEventType, int iButton);
-
-int
-winMouseButtonsHandle (ScreenPtr pScreen,
- int iEventType, int iButton,
- WPARAM wParam);
-
-void
-winEnqueueMotion(int x, int y);
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winnativegdi.c
- */
-
-HBITMAP
-winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
- BYTE **ppbBits, BITMAPINFO **ppbmi);
-
-Bool
-winSetEngineFunctionsNativeGDI (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_PRIMARYFB
-/*
- * winpfbddd.c
- */
-
-Bool
-winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpixmap.c
- */
-
-PixmapPtr
-winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint);
-
-Bool
-winDestroyPixmapNativeGDI (PixmapPtr pPixmap);
-
-Bool
-winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap,
- int iWidth, int iHeight,
- int iDepth,
- int iBitsPerPixel,
- int devKind,
- pointer pPixData);
-#endif
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpolyline.c
- */
-
-void
-winPolyLineNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr ppt);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpushpxl.c
- */
-
-void
-winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
- int dx, int dy, int xOrg, int yOrg);
-#endif
-
-
-/*
- * winscrinit.c
- */
-
-Bool
-winScreenInit (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-
-Bool
-winFinishScreenInitFB (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-
-#if defined(XWIN_NATIVEGDI)
-Bool
-winFinishScreenInitNativeGDI (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winsetsp.c
- */
-
-void
-winSetSpansNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- char *pSrc,
- DDXPointPtr pPoints,
- int *pWidth,
- int nSpans,
- int fSorted);
-#endif
-
-
-/*
- * winshaddd.c
- */
-
-Bool
-winSetEngineFunctionsShadowDD (ScreenPtr pScreen);
-
-
-/*
- * winshadddnl.c
- */
-
-Bool
-winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen);
-
-
-/*
- * winshadgdi.c
- */
-
-Bool
-winSetEngineFunctionsShadowGDI (ScreenPtr pScreen);
-
-
-/*
- * winwakeup.c
- */
-
-void
-winWakeupHandler (int nScreen,
- pointer pWakeupData,
- unsigned long ulResult,
- pointer pReadmask);
-
-
-/*
- * winwindow.c
- */
-
-#ifdef XWIN_NATIVEGDI
-Bool
-winCreateWindowNativeGDI (WindowPtr pWin);
-
-Bool
-winDestroyWindowNativeGDI (WindowPtr pWin);
-
-Bool
-winPositionWindowNativeGDI (WindowPtr pWin, int x, int y);
-
-void
-winCopyWindowNativeGDI (WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc);
-
-Bool
-winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask);
-
-Bool
-winUnmapWindowNativeGDI (WindowPtr pWindow);
-
-Bool
-winMapWindowNativeGDI (WindowPtr pWindow);
-#endif
-
-Bool
-winCreateWindowRootless (WindowPtr pWindow);
-
-Bool
-winDestroyWindowRootless (WindowPtr pWindow);
-
-Bool
-winPositionWindowRootless (WindowPtr pWindow, int x, int y);
-
-Bool
-winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask);
-
-Bool
-winUnmapWindowRootless (WindowPtr pWindow);
-
-Bool
-winMapWindowRootless (WindowPtr pWindow);
-
-void
-winSetShapeRootless (WindowPtr pWindow, int kind);
-
-
-/*
- * winmultiwindowicons.c - Used by both multi-window and Win32Rootless
- */
-
-HICON
-winXIconToHICON (WindowPtr pWin, int iconSize);
-
-void
-winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowshape.c
- */
-
-void
-winReshapeMultiWindow (WindowPtr pWin);
-
-void
-winSetShapeMultiWindow (WindowPtr pWindow, int kind);
-
-void
-winUpdateRgnMultiWindow (WindowPtr pWindow);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * 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);
-
-void
-winReorderWindowsMultiWindow (void);
-
-void
-winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
- unsigned int h, WindowPtr pSib);
-void
-winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
- WindowPtr pSib, VTKind kind);
-
-void
-winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
- RegionPtr oldRegion);
-
-XID
-winGetWindowID (WindowPtr pWin);
-
-int
-winAdjustXWindow (WindowPtr pWin, HWND hwnd);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowwndproc.c
- */
-
-LRESULT CALLBACK
-winTopLevelWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-#endif
-
-
-/*
- * wintrayicon.c
- */
-
-void
-winInitNotifyIcon (winPrivScreenPtr pScreenPriv);
-
-void
-winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv);
-
-LRESULT
-winHandleIconMessage (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam,
- winPrivScreenPtr pScreenPriv);
-
-
-/*
- * winwndproc.c
- */
-
-LRESULT CALLBACK
-winWindowProc (HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootless.c
- */
-
-Bool
-winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape);
-
-void
-winMWExtWMDestroyFrame (RootlessFrameID wid);
-
-void
-winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
-
-void
-winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int gravity);
-
-void
-winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid);
-
-void
-winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape);
-
-void
-winMWExtWMUnmapFrame (RootlessFrameID wid);
-
-void
-winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
-
-void
-winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush);
-
-void
-winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage);
-
-void
-winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects,
- int shift_x, int shift_y);
-
-void
-winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin);
-
-void
-winMWExtWMCopyBytes (unsigned int width, unsigned int height,
- const void *src, unsigned int srcRowBytes,
- void *dst, unsigned int dstRowBytes);
-
-void
-winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
- int dx, int dy);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootlesswindow.c
- */
-
-void
-winMWExtWMReorderWindows (ScreenPtr pScreen);
-
-void
-winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y);
-
-void
-winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h);
-
-void
-winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h);
-
-void
-winMWExtWMUpdateIcon (Window id);
-
-void
-winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
- winScreenInfoPtr pScreenInfo);
-
-wBOOL CALLBACK
-winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam);
-
-Bool
-winIsInternalWMRunning (winScreenInfoPtr pScreenInfo);
-
-void
-winMWExtWMRestackWindows (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootlesswndproc.c
- */
-
-LRESULT CALLBACK
-winMWExtWMWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-#endif
-
-
-/*
- * winwindowswm.c
- */
-
-void
-winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
- Window window, int x, int y, int w, int h);
-
-void
-winWindowsWMExtensionInit (void);
-
-/*
- * wincursor.c
- */
-
-Bool
-winInitCursor (ScreenPtr pScreen);
-
-/*
- * winprocarg.c
- */
-void
-winInitializeScreens(int maxscreens);
-
-/*
- * winrandr.c
- */
-Bool
-winRandRInit (ScreenPtr pScreen);
-void
-winDoRandRScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight);
-
-/*
- * END DDX and DIX Function Prototypes
- */
-
-#endif /* _WIN_H_ */
-
+/* + *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: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * Kensuke Matsuzaki + */ + +#ifndef _WIN_H_ +#define _WIN_H_ + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +/* Turn debug messages on or off */ +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif + +/* WM_XBUTTON Messages. They should go into w32api. */ +#ifndef WM_XBUTTONDOWN +# define WM_XBUTTONDOWN 523 +#endif +#ifndef WM_XBUTTONUP +# define WM_XBUTTONUP 524 +#endif +#ifndef WM_XBUTTONDBLCLK +# define WM_XBUTTONDBLCLK 525 +#endif + + +#define WIN_DEFAULT_BPP 0 +#define WIN_DEFAULT_WHITEPIXEL 255 +#define WIN_DEFAULT_BLACKPIXEL 0 +#define WIN_DEFAULT_LINEBIAS 0 +#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */ +#define WIN_DEFAULT_DPI 75 +#define WIN_DEFAULT_REFRESH 0 +#define WIN_DEFAULT_WIN_KILL TRUE +#define WIN_DEFAULT_UNIX_KILL FALSE +#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0 +#ifdef XWIN_EMULATEPSEUDO +#define WIN_DEFAULT_EMULATE_PSEUDO FALSE +#endif +#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE + +/* + * Windows only supports 256 color palettes + */ +#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 + +/* + * Build a supported display depths mask by shifting one to the left + * by the number of bits in the supported depth. + */ +#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \ + | (1 << (16 - 1)) | (1 << (15 - 1)) \ + | (1 << ( 8 - 1))) +#define WIN_CHECK_DEPTH YES + +/* + * Timer IDs for WM_TIMER + */ +#define WIN_E3B_TIMER_ID 1 +#define WIN_POLLING_MOUSE_TIMER_ID 2 + +#define MOUSE_POLLING_INTERVAL 50 + +#define WIN_E3B_OFF -1 +#define WIN_FD_INVALID -1 + +#define WIN_SERVER_NONE 0x0L /* 0 */ +#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */ +#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */ +#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */ +#ifdef XWIN_PRIMARYFB +#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */ +#endif +#ifdef XWIN_NATIVEGDI +# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */ +#endif + +#define AltMapIndex Mod1MapIndex +#define NumLockMapIndex Mod2MapIndex +#define AltLangMapIndex Mod3MapIndex +#define KanaMapIndex Mod4MapIndex +#define ScrollLockMapIndex Mod5MapIndex + +#define WIN_MOD_LALT 0x00000001 +#define WIN_MOD_RALT 0x00000002 +#define WIN_MOD_LCONTROL 0x00000004 +#define WIN_MOD_RCONTROL 0x00000008 + +#define WIN_24BPP_MASK_RED 0x00FF0000 +#define WIN_24BPP_MASK_GREEN 0x0000FF00 +#define WIN_24BPP_MASK_BLUE 0x000000FF + +#define WIN_MAX_KEYS_PER_KEY 4 + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> + +#include <errno.h> +#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) +#define HANDLE void * +#include <pthread.h> +#undef HANDLE +#endif + +#ifdef HAS_MMAP +#include <sys/mman.h> +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif /* MAP_FILE */ +#endif /* HAS_MMAP */ + +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/Xos.h> +#include <X11/Xprotostr.h> +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "pixmap.h" +#include "region.h" +#include "gcstruct.h" +#include "colormap.h" +#include "colormapst.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "mi.h" +#include "micmap.h" +#include "mifillarc.h" +#include "mifpoly.h" +#include "mibstore.h" +#include "input.h" +#include "mipointer.h" +#include "X11/keysym.h" +#include "micoord.h" +#include "dix.h" +#include "miline.h" +#include "shadow.h" +#include "fb.h" +#include "rootless.h" + +#include "mipict.h" +#include "picturestr.h" + +#ifdef RANDR +#include "randrstr.h" +#endif + +/* + * Windows headers + */ +#include "winms.h" +#include "winresource.h" + + +/* + * Define Windows constants + */ + +#define WM_TRAYICON (WM_USER + 1000) +#define WM_INIT_SYS_MENU (WM_USER + 1001) +#define WM_GIVEUP (WM_USER + 1002) + + +/* Local includes */ +#include "winwindow.h" +#include "winmsg.h" + + +/* + * Debugging macros + */ + +#if CYGDEBUG +#define DEBUG_MSG(str,...) \ +if (fDebugProcMsg) \ +{ \ + char *pszTemp; \ + int iLength; \ + if (asprintf (&pszTemp, str, ##__VA_ARGS__) != -1) { \ + MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \ + free (pszTemp); \ + } \ +} +#else +#define DEBUG_MSG(str,...) +#endif + +#if CYGDEBUG +#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str +#else +#define DEBUG_FN_NAME(str) +#endif + +#if CYGDEBUG || YES +#define DEBUGVARS BOOL fDebugProcMsg = FALSE +#else +#define DEBUGVARS +#endif + +#if CYGDEBUG || YES +#define DEBUGPROC_MSG fDebugProcMsg = TRUE +#else +#define DEBUGPROC_MSG +#endif + +#define PROFILEPOINT(point,thresh)\ +{\ +static unsigned int PROFPT##point = 0;\ +if (++PROFPT##point % thresh == 0)\ +ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\ +} + + +/* We use xor this macro for detecting toggle key state changes */ +#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b))) + +#define DEFINE_ATOM_HELPER(func,atom_name) \ +static Atom func (void) { \ + static int generation; \ + static Atom atom; \ + if (generation != serverGeneration) { \ + generation = serverGeneration; \ + atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \ + } \ + return atom; \ +} + +/* + * Typedefs for engine dependent function pointers + */ + +typedef Bool (*winAllocateFBProcPtr)(ScreenPtr); + +typedef void (*winFreeFBProcPtr)(ScreenPtr); + +typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr); + +typedef Bool (*winInitScreenProcPtr)(ScreenPtr); + +typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr); + +typedef Bool (*winInitVisualsProcPtr)(ScreenPtr); + +typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr); + +typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr); + +typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **); + +typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr); + +typedef Bool (*winActivateAppProcPtr)(ScreenPtr); + +typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap, + int ndef, xColorItem *pdefs); + +typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr); + +typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin); + +typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr); + +#ifdef XWIN_NATIVEGDI +/* Typedefs for native GDI wrappers */ +typedef Bool (*RealizeFontPtr) (ScreenPtr pScreen, FontPtr pFont); +typedef Bool (*UnrealizeFontPtr)(ScreenPtr pScreen, FontPtr pFont); +#endif + + +/* + * GC (graphics context) privates + */ + +typedef struct +{ + HDC hdc; + HDC hdcMem; +} winPrivGCRec, *winPrivGCPtr; + + +/* + * Pixmap privates + */ + +typedef struct +{ + HDC hdcSelected; + HBITMAP hBitmap; + BYTE *pbBits; + DWORD dwScanlineBytes; + BITMAPINFOHEADER *pbmih; +} winPrivPixmapRec, *winPrivPixmapPtr; + + +/* + * Colormap privates + */ + +typedef struct +{ + HPALETTE hPalette; + LPDIRECTDRAWPALETTE lpDDPalette; + RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; + PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES]; +} winPrivCmapRec, *winPrivCmapPtr; + +/* + * Windows Cursor handling. + */ + +typedef struct { + /* from GetSystemMetrics */ + int sm_cx; + int sm_cy; + + BOOL visible; + HCURSOR handle; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} winCursorRec; + +/* + * Resize modes + */ +typedef enum { + notAllowed, + resizeWithScrollbars, + resizeWithRandr +} winResizeMode; + +/* + * Screen information structure that we need before privates are available + * in the server startup sequence. + */ + +typedef struct +{ + ScreenPtr pScreen; + + /* Did the user specify a height and width? */ + Bool fUserGaveHeightAndWidth; + + DWORD dwScreen; + + int iMonitor; + DWORD dwUserWidth; + DWORD dwUserHeight; + DWORD dwWidth; + DWORD dwHeight; + DWORD dwPaddedWidth; + + /* Did the user specify a screen position? */ + Bool fUserGavePosition; + DWORD dwInitialX; + DWORD dwInitialY; + + /* + * dwStride is the number of whole pixels that occupy a scanline, + * including those pixels that are not displayed. This is basically + * a rounding up of the width. + */ + DWORD dwStride; + + /* Offset of the screen in the window when using scrollbars */ + DWORD dwXOffset; + DWORD dwYOffset; + + DWORD dwBPP; + DWORD dwDepth; + DWORD dwRefreshRate; + char *pfb; + DWORD dwEngine; + DWORD dwEnginePreferred; + DWORD dwClipUpdatesNBoxes; +#ifdef XWIN_EMULATEPSEUDO + Bool fEmulatePseudo; +#endif + Bool fFullScreen; + Bool fDecoration; +#ifdef XWIN_MULTIWINDOWEXTWM + Bool fMWExtWM; + Bool fInternalWM; + Bool fAnotherWMRunning; +#endif + Bool fRootless; +#ifdef XWIN_MULTIWINDOW + Bool fMultiWindow; +#endif +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + Bool fMultiMonitorOverride; +#endif + Bool fMultipleMonitors; + Bool fLessPointer; + winResizeMode iResizeMode; + Bool fNoTrayIcon; + int iE3BTimeout; + /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */ + Bool fUseWinKillKey; + Bool fUseUnixKillKey; + Bool fIgnoreInput; + + /* Did the user explicitly set this screen? */ + Bool fExplicitScreen; +} winScreenInfo, *winScreenInfoPtr; + + +/* + * Screen privates + */ + +typedef struct _winPrivScreenRec +{ + winScreenInfoPtr pScreenInfo; + + Bool fEnabled; + Bool fClosed; + Bool fActive; + Bool fBadDepth; + + int iDeltaZ; + + int iConnectedClients; + + CloseScreenProcPtr CloseScreen; + + DWORD dwRedMask; + DWORD dwGreenMask; + DWORD dwBlueMask; + DWORD dwBitsPerRGB; + + DWORD dwModeKeyStates; + + /* Handle to icons that must be freed */ + HICON hiconNotifyIcon; + + /* Palette management */ + ColormapPtr pcmapInstalled; + + /* Pointer to the root visual so we only have to look it up once */ + VisualPtr pRootVisual; + + /* 3 button emulation variables */ + int iE3BCachedPress; + Bool fE3BFakeButton2Sent; + + /* Privates used by shadow fb GDI server */ + HBITMAP hbmpShadow; + HDC hdcScreen; + HDC hdcShadow; + HWND hwndScreen; + BITMAPINFOHEADER *pbmih; + + /* Privates used by shadow fb and primary fb DirectDraw servers */ + LPDIRECTDRAW pdd; + LPDIRECTDRAWSURFACE2 pddsPrimary; + LPDIRECTDRAW2 pdd2; + + /* Privates used by shadow fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsShadow; + LPDDSURFACEDESC pddsdShadow; + + /* Privates used by primary fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsOffscreen; + LPDDSURFACEDESC pddsdOffscreen; + LPDDSURFACEDESC pddsdPrimary; + + /* Privates used by shadow fb DirectDraw Nonlocking server */ + LPDIRECTDRAW4 pdd4; + LPDIRECTDRAWSURFACE4 pddsShadow4; + LPDIRECTDRAWSURFACE4 pddsPrimary4; + BOOL fRetryCreateSurface; + + /* Privates used by both shadow fb DirectDraw servers */ + LPDIRECTDRAWCLIPPER pddcPrimary; + +#ifdef XWIN_MULTIWINDOWEXTWM + /* Privates used by multi-window external window manager */ + RootlessFrameID widTop; + Bool fRestacking; +#endif + +#ifdef XWIN_MULTIWINDOW + /* Privates used by multi-window */ + pthread_t ptWMProc; + pthread_t ptXMsgProc; + void *pWMInfo; +#endif + +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + /* Privates used by both multi-window and rootless */ + Bool fRootWindowShown; +#endif + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Privates used for any module running in a seperate thread */ + pthread_mutex_t pmServerStarted; + Bool fServerStarted; +#endif + + /* Engine specific functions */ + winAllocateFBProcPtr pwinAllocateFB; + winFreeFBProcPtr pwinFreeFB; + winShadowUpdateProcPtr pwinShadowUpdate; + winInitScreenProcPtr pwinInitScreen; + winCloseScreenProcPtr pwinCloseScreen; + winInitVisualsProcPtr pwinInitVisuals; + winAdjustVideoModeProcPtr pwinAdjustVideoMode; + winCreateBoundingWindowProcPtr pwinCreateBoundingWindow; + winFinishScreenInitProcPtr pwinFinishScreenInit; + winBltExposedRegionsProcPtr pwinBltExposedRegions; + winActivateAppProcPtr pwinActivateApp; + winRedrawScreenProcPtr pwinRedrawScreen; + winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette; + winInstallColormapProcPtr pwinInstallColormap; + winStoreColorsProcPtr pwinStoreColors; + winCreateColormapProcPtr pwinCreateColormap; + winDestroyColormapProcPtr pwinDestroyColormap; + winHotKeyAltTabProcPtr pwinHotKeyAltTab; + winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface; + winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface; + + winCreateScreenResourcesProc pwinCreateScreenResources; + +#ifdef XWIN_MULTIWINDOW + /* Window Procedures for MultiWindow mode */ + winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow; +#endif + + /* Window Procedures for Rootless mode */ + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + PositionWindowProcPtr PositionWindow; + ChangeWindowAttributesProcPtr ChangeWindowAttributes; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + ValidateTreeProcPtr ValidateTree; + PostValidateTreeProcPtr PostValidateTree; + WindowExposuresProcPtr WindowExposures; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + ClipNotifyProcPtr ClipNotify; + RestackWindowProcPtr RestackWindow; + ReparentWindowProcPtr ReparentWindow; + ResizeWindowProcPtr ResizeWindow; + MoveWindowProcPtr MoveWindow; + SetShapeProcPtr SetShape; + + winCursorRec cursor; + +#ifdef XWIN_NATIVEGDI + RealizeFontPtr RealizeFont; + UnrealizeFontPtr UnrealizeFont; +#endif + +} winPrivScreenRec; + + +#ifdef XWIN_MULTIWINDOWEXTWM +typedef struct { + RootlessWindowPtr pFrame; + HWND hWnd; + int dwWidthBytes; + BITMAPINFOHEADER *pbmihShadow; + HBITMAP hbmpShadow; + HDC hdcShadow; + HDC hdcScreen; + BOOL fResized; + BOOL fRestackingNow; + BOOL fClose; + BOOL fMovingOrSizing; + BOOL fDestroyed;//for debug + char *pfb; +} win32RootlessWindowRec, *win32RootlessWindowPtr; +#endif + + +typedef struct { + pointer value; + XID id; +} WindowIDPairRec, *WindowIDPairPtr; + + +/* + * Extern declares for general global variables + */ + +#include "winglobals.h" + +extern winScreenInfo * g_ScreenInfo; +extern miPointerScreenFuncRec g_winPointerCursorFuncs; +extern DWORD g_dwEvents; +#ifdef HAS_DEVWINDOWS +extern int g_fdMessageQueue; +#endif +extern DevPrivateKeyRec g_iScreenPrivateKeyRec; +#define g_iScreenPrivateKey (&g_iScreenPrivateKeyRec) +extern DevPrivateKeyRec g_iCmapPrivateKeyRec; +#define g_iCmapPrivateKey (&g_iCmapPrivateKeyRec) +extern DevPrivateKeyRec g_iGCPrivateKeyRec; +#define g_iGCPrivateKey (&g_iGCPrivateKeyRec) +extern DevPrivateKeyRec g_iPixmapPrivateKeyRec; +#define g_iPixmapPrivateKey (&g_iPixmapPrivateKeyRec) +extern DevPrivateKeyRec g_iWindowPrivateKeyRec; +#define g_iWindowPrivateKey (&g_iWindowPrivateKeyRec) + +extern unsigned long g_ulServerGeneration; +extern DWORD g_dwEnginesSupported; +extern HINSTANCE g_hInstance; +extern int g_copyROP[]; +extern int g_patternROP[]; +extern const char * g_pszQueryHost; +extern DeviceIntPtr g_pwinPointer; +extern DeviceIntPtr g_pwinKeyboard; + +/* + * Extern declares for dynamically loaded library function pointers + */ + +extern FARPROC g_fpDirectDrawCreate; +extern FARPROC g_fpDirectDrawCreateClipper; +extern FARPROC g_fpTrackMouseEvent; + + +/* + * Screen privates macros + */ + +#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey)) + +#define winSetScreenPriv(pScreen,v) \ + dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v) + +#define winScreenPriv(pScreen) \ + winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen) + + +/* + * Colormap privates macros + */ + +#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \ + dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey)) + +#define winSetCmapPriv(pCmap,v) \ + dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v) + +#define winCmapPriv(pCmap) \ + winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap) + + +/* + * GC privates macros + */ + +#define winGetGCPriv(pGC) ((winPrivGCPtr) \ + dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey)) + +#define winSetGCPriv(pGC,v) \ + dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v) + +#define winGCPriv(pGC) \ + winPrivGCPtr pGCPriv = winGetGCPriv(pGC) + + +/* + * Pixmap privates macros + */ + +#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \ + dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey)) + +#define winSetPixmapPriv(pPixmap,v) \ + dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v) + +#define winPixmapPriv(pPixmap) \ + winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap) + + +/* + * Window privates macros + */ + +#define winGetWindowPriv(pWin) ((winPrivWinPtr) \ + dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey)) + +#define winSetWindowPriv(pWin,v) \ + dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v) + +#define winWindowPriv(pWin) \ + winPrivWinPtr pWinPriv = winGetWindowPriv(pWin) + +/* + * wrapper macros + */ +#define _WIN_WRAP(priv, real, mem, func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define _WIN_UNWRAP(priv, real, mem) {\ + real->mem = priv->mem; \ +} + +#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func) + +#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem) + +/* + * BEGIN DDX and DIX Function Prototypes + */ + + +/* + * winallpriv.c + */ + +Bool +winAllocatePrivates (ScreenPtr pScreen); + +Bool +winInitCmapPrivates (ColormapPtr pCmap, int index); + +Bool +winAllocateCmapPrivates (ColormapPtr pCmap); + + +/* + * winauth.c + */ + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) +Bool +winGenerateAuthorization (void); +void winSetAuthorization(void); +#endif + + +/* + * winblock.c + */ + +void +winBlockHandler (int nScreen, + pointer pBlockData, + pointer pTimeout, + pointer pReadMask); + + +#ifdef XWIN_NATIVEGDI +/* + * winclip.c + */ + +RegionPtr +winPixmapToRegionNativeGDI (PixmapPtr pPix); +#endif + + +#ifdef XWIN_CLIPBOARD +/* + * winclipboardinit.c + */ + +Bool +winInitClipboard (void); + +void +winFixClipboardChain (void); +#endif + + +/* + * wincmap.c + */ + +void +winSetColormapFunctions (ScreenPtr pScreen); + +Bool +winCreateDefColormap (ScreenPtr pScreen); + + +/* + * wincreatewnd.c + */ + +Bool +winCreateBoundingWindowFullScreen (ScreenPtr pScreen); + +Bool +winCreateBoundingWindowWindowed (ScreenPtr pScreen); + + +/* + * windialogs.c + */ + +void +winDisplayExitDialog (winPrivScreenPtr pScreenPriv); + +void +winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv); + +void +winDisplayAboutDialog (winPrivScreenPtr pScreenPriv); + + +/* + * winengine.c + */ + +void +winDetectSupportedEngines (void); + +Bool +winSetEngine (ScreenPtr pScreen); + +Bool +winGetDDProcAddresses (void); + +void +winReleaseDDProcAddresses(void); + + +/* + * winerror.c + */ + +#ifdef DDXOSVERRORF +void +OSVenderVErrorF (const char *pszFormat, va_list va_args); +#endif + +void +winMessageBoxF (const char *pszError, UINT uType, ...); + + +#ifdef XWIN_NATIVEGDI +/* + * winfillsp.c + */ + +void +winFillSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int nSpans, + DDXPointPtr pPoints, + int *pWidths, + int fSorted); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winfont.c + */ + +Bool +winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); + +Bool +winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * wingc.c + */ + +Bool +winCreateGCNativeGDI (GCPtr pGC); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * wingetsp.c + */ + +void +winGetSpansNativeGDI (DrawablePtr pDrawable, + int wMax, + DDXPointPtr pPoints, + int *pWidths, + int nSpans, + char *pDst); +#endif + + +/* + * winglobals.c + */ + +void +winInitializeGlobals (void); + + +/* + * winkeybd.c + */ + +void +winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode); + +int +winKeybdProc (DeviceIntPtr pDeviceInt, int iState); + +void +winInitializeModeKeyStates (void); + +void +winRestoreModeKeyStates (void); + +Bool +winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam); + +void +winKeybdReleaseKeys (void); + +void +winSendKeyEvent (DWORD dwKey, Bool fDown); + +BOOL +winCheckKeyPressed(WPARAM wParam, LPARAM lParam); + +void +winFixShiftKeys (int iScanCode); + +/* + * winkeyhook.c + */ + +Bool +winInstallKeyboardHookLL (void); + +void +winRemoveKeyboardHookLL (void); + + +/* + * winmisc.c + */ + +#ifdef XWIN_NATIVEGDI +void +winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen); +#endif + +CARD8 +winCountBits (DWORD dw); + +Bool +winUpdateFBPointer (ScreenPtr pScreen, void *pbits); + +#ifdef XWIN_NATIVEGDI +BOOL +winPaintBackground (HWND hwnd, COLORREF colorref); +#endif + + +/* + * winmouse.c + */ + +int +winMouseProc (DeviceIntPtr pDeviceInt, int iState); + +int +winMouseWheel (ScreenPtr pScreen, int iDeltaZ); + +void +winMouseButtonsSendEvent (int iEventType, int iButton); + +int +winMouseButtonsHandle (ScreenPtr pScreen, + int iEventType, int iButton, + WPARAM wParam); + +void +winEnqueueMotion(int x, int y); + +#ifdef XWIN_NATIVEGDI +/* + * winnativegdi.c + */ + +HBITMAP +winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, + BYTE **ppbBits, BITMAPINFO **ppbmi); + +Bool +winSetEngineFunctionsNativeGDI (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_PRIMARYFB +/* + * winpfbddd.c + */ + +Bool +winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winpixmap.c + */ + +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth, + unsigned usage_hint); + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap); + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData); +#endif + +#ifdef XWIN_NATIVEGDI +/* + * winpolyline.c + */ + +void +winPolyLineNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winpushpxl.c + */ + +void +winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, + int dx, int dy, int xOrg, int yOrg); +#endif + + +/* + * winscrinit.c + */ + +Bool +winScreenInit (int index, + ScreenPtr pScreen, + int argc, char **argv); + +Bool +winFinishScreenInitFB (int index, + ScreenPtr pScreen, + int argc, char **argv); + +#if defined(XWIN_NATIVEGDI) +Bool +winFinishScreenInitNativeGDI (int index, + ScreenPtr pScreen, + int argc, char **argv); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winsetsp.c + */ + +void +winSetSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + char *pSrc, + DDXPointPtr pPoints, + int *pWidth, + int nSpans, + int fSorted); +#endif + + +/* + * winshaddd.c + */ + +Bool +winSetEngineFunctionsShadowDD (ScreenPtr pScreen); + + +/* + * winshadddnl.c + */ + +Bool +winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen); + + +/* + * winshadgdi.c + */ + +Bool +winSetEngineFunctionsShadowGDI (ScreenPtr pScreen); + + +/* + * winwakeup.c + */ + +void +winWakeupHandler (int nScreen, + pointer pWakeupData, + unsigned long ulResult, + pointer pReadmask); + + +/* + * winwindow.c + */ + +#ifdef XWIN_NATIVEGDI +Bool +winCreateWindowNativeGDI (WindowPtr pWin); + +Bool +winDestroyWindowNativeGDI (WindowPtr pWin); + +Bool +winPositionWindowNativeGDI (WindowPtr pWin, int x, int y); + +void +winCopyWindowNativeGDI (WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +Bool +winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask); + +Bool +winUnmapWindowNativeGDI (WindowPtr pWindow); + +Bool +winMapWindowNativeGDI (WindowPtr pWindow); +#endif + +Bool +winCreateWindowRootless (WindowPtr pWindow); + +Bool +winDestroyWindowRootless (WindowPtr pWindow); + +Bool +winPositionWindowRootless (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowRootless (WindowPtr pWindow); + +Bool +winMapWindowRootless (WindowPtr pWindow); + +void +winSetShapeRootless (WindowPtr pWindow, int kind); + + +/* + * winmultiwindowicons.c - Used by both multi-window and Win32Rootless + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize); + +void +winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon); + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowshape.c + */ + +void +winReshapeMultiWindow (WindowPtr pWin); + +void +winSetShapeMultiWindow (WindowPtr pWindow, int kind); + +void +winUpdateRgnMultiWindow (WindowPtr pWindow); +#endif + + +#ifdef XWIN_MULTIWINDOW +/* + * 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); + +void +winReorderWindowsMultiWindow (void); + +void +winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib); +void +winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, + WindowPtr pSib, VTKind kind); + +void +winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, + RegionPtr oldRegion); + +XID +winGetWindowID (WindowPtr pWin); + +int +winAdjustXWindow (WindowPtr pWin, HWND hwnd); +#endif + + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowwndproc.c + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +#endif + + +/* + * wintrayicon.c + */ + +void +winInitNotifyIcon (winPrivScreenPtr pScreenPriv); + +void +winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv); + +LRESULT +winHandleIconMessage (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam, + winPrivScreenPtr pScreenPriv); + + +/* + * winwndproc.c + */ + +LRESULT CALLBACK +winWindowProc (HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootless.c + */ + +Bool +winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape); + +void +winMWExtWMDestroyFrame (RootlessFrameID wid); + +void +winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); + +void +winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity); + +void +winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid); + +void +winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape); + +void +winMWExtWMUnmapFrame (RootlessFrameID wid); + +void +winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow); + +void +winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush); + +void +winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage); + +void +winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects, + int shift_x, int shift_y); + +void +winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin); + +void +winMWExtWMCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes); + +void +winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy); +#endif + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootlesswindow.c + */ + +void +winMWExtWMReorderWindows (ScreenPtr pScreen); + +void +winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y); + +void +winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h); + +void +winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h); + +void +winMWExtWMUpdateIcon (Window id); + +void +winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, + winScreenInfoPtr pScreenInfo); + +wBOOL CALLBACK +winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam); + +Bool +winIsInternalWMRunning (winScreenInfoPtr pScreenInfo); + +void +winMWExtWMRestackWindows (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootlesswndproc.c + */ + +LRESULT CALLBACK +winMWExtWMWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +#endif + + +/* + * winwindowswm.c + */ + +void +winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, + Window window, int x, int y, int w, int h); + +void +winWindowsWMExtensionInit (void); + +/* + * wincursor.c + */ + +Bool +winInitCursor (ScreenPtr pScreen); + +/* + * winprocarg.c + */ +void +winInitializeScreens(int maxscreens); + +/* + * winrandr.c + */ +Bool +winRandRInit (ScreenPtr pScreen); +void +winDoRandRScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +/* + * END DDX and DIX Function Prototypes + */ + +#endif /* _WIN_H_ */ + diff --git a/xorg-server/hw/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c index e65717008..b0006a01f 100644 --- a/xorg-server/hw/xwin/winclipboardxevents.c +++ b/xorg-server/hw/xwin/winclipboardxevents.c @@ -1,802 +1,805 @@ -/*
- *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2008
- *
- *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 HAROLD L HUNT II 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 copyright holder(s)
- *and author(s) 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 copyright holder(s) and author(s).
- *
- * Authors: Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "winclipboard.h"
-#include "misc.h"
-
-
-/*
- * References to external symbols
- */
-
-extern Bool g_fUnicodeSupport;
-
-
-/*
- * Process any pending X events
- */
-
-int
-winClipboardFlushXEvents (HWND hwnd,
- int iWindow,
- Display *pDisplay,
- Bool fUseUnicode)
-{
- static Atom atomLocalProperty;
- static Atom atomCompoundText;
- static Atom atomUTF8String;
- static Atom atomTargets;
- static int generation;
-
- if (generation != serverGeneration)
- {
- generation = serverGeneration;
- atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
- atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
- atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
- atomTargets = XInternAtom (pDisplay, "TARGETS", False);
- }
-
- /* Process all pending events */
- while (XPending (pDisplay))
- {
- XTextProperty xtpText = {0};
- XEvent event;
- XSelectionEvent eventSelection;
- unsigned long ulReturnBytesLeft;
- char *pszReturnData = NULL;
- char *pszGlobalData = NULL;
- int iReturn;
- HGLOBAL hGlobal = NULL;
- XICCEncodingStyle xiccesStyle;
- int iConvertDataLen = 0;
- char *pszConvertData = NULL;
- char *pszTextList[2] = {NULL};
- int iCount;
- char **ppszTextList = NULL;
- wchar_t *pwszUnicodeStr = NULL;
- int iUnicodeLen = 0;
- int iReturnDataLen = 0;
- int i;
- Bool fAbort = FALSE;
- Bool fCloseClipboard = FALSE;
- Bool fSetClipboardData = TRUE;
-
- /* Get the next event - will not block because one is ready */
- XNextEvent (pDisplay, &event);
-
- /* Branch on the event type */
- switch (event.type)
- {
- /*
- * SelectionRequest
- */
-
- case SelectionRequest:
- {
- char *pszAtomName = NULL;
- winDebug("SelectionRequest - target %d\n",
- event.xselectionrequest.target);
-
- pszAtomName = XGetAtomName (pDisplay,
- event.xselectionrequest.target);
- winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
- XFree (pszAtomName);
- pszAtomName = NULL;
- }
-
- /* Abort if invalid target type */
- if (event.xselectionrequest.target != XA_STRING
- && event.xselectionrequest.target != atomUTF8String
- && event.xselectionrequest.target != atomCompoundText
- && event.xselectionrequest.target != atomTargets)
- {
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Handle targets type of request */
- if (event.xselectionrequest.target == atomTargets)
- {
- Atom atomTargetArr[] = {atomTargets,
- atomCompoundText,
- atomUTF8String,
- XA_STRING};
-
- /* Try to change the property */
- iReturn = XChangeProperty (pDisplay,
- event.xselectionrequest.requestor,
- event.xselectionrequest.property,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char *) atomTargetArr,
- (sizeof (atomTargetArr)
- / sizeof (atomTargetArr[0])));
- if (iReturn == BadAlloc
- || iReturn == BadAtom
- || iReturn == BadMatch
- || iReturn == BadValue
- || iReturn == BadWindow)
- {
- ErrorF ("winClipboardFlushXEvents - 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 ("winClipboardFlushXEvents - SelectionRequest - "
- "XSendEvent () failed\n");
- }
- break;
- }
-
- /* Check that clipboard format is available */
- if (fUseUnicode
- && !IsClipboardFormatAvailable (CF_UNICODETEXT))
- {
- static int count; /* Hack to stop acroread spamming the log */
- static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */
- if (hwnd != lasthwnd) count = 0;
- count++;
- if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not "
- "available from Win32 clipboard. Aborting %d.\n", count);
- lasthwnd = hwnd;
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
- else if (!fUseUnicode
- && !IsClipboardFormatAvailable (CF_TEXT))
- {
- ErrorF ("winClipboardFlushXEvents - CF_TEXT is not "
- "available from Win32 clipboard. Aborting.\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow () == hwnd)
- {
- CloseClipboard ();
- }
-
- /* Access the clipboard */
- if (!OpenClipboard (hwnd))
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "OpenClipboard () failed: %08lx\n",
- GetLastError ());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Indicate that clipboard was opened */
- fCloseClipboard = TRUE;
-
- /* Setup the string style */
- if (event.xselectionrequest.target == XA_STRING)
- xiccesStyle = XStringStyle;
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselectionrequest.target == atomUTF8String)
- xiccesStyle = XUTF8StringStyle;
-#endif
- 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, in desired format */
- if (fUseUnicode)
- {
- /* Retrieve clipboard data */
- hGlobal = GetClipboardData (CF_UNICODETEXT);
- }
- else
- {
- /* Retrieve clipboard data */
- hGlobal = GetClipboardData (CF_TEXT);
- }
- if (!hGlobal)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "GetClipboardData () failed: %08lx\n",
- GetLastError ());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
- pszGlobalData = (char *) GlobalLock (hGlobal);
-
- /* Convert the Unicode string to UTF8 (MBCS) */
- if (fUseUnicode)
- {
- iConvertDataLen = WideCharToMultiByte (CP_UTF8,
- 0,
- (LPCWSTR)pszGlobalData,
- -1,
- NULL,
- 0,
- NULL,
- NULL);
- /* NOTE: iConvertDataLen includes space for null terminator */
- pszConvertData = (char *) malloc (iConvertDataLen);
- WideCharToMultiByte (CP_UTF8,
- 0,
- (LPCWSTR)pszGlobalData,
- -1,
- pszConvertData,
- iConvertDataLen,
- NULL,
- NULL);
- }
- else
- {
- pszConvertData = strdup (pszGlobalData);
- iConvertDataLen = strlen (pszConvertData) + 1;
- }
-
- /* Convert DOS string to UNIX string */
- winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData));
-
- /* Setup our text list */
- pszTextList[0] = pszConvertData;
- pszTextList[1] = NULL;
-
- /* Initialize the text property */
- xtpText.value = NULL;
- xtpText.nitems = 0;
-
- /* Create the text property from the text list */
- if (fUseUnicode)
- {
-#ifdef X_HAVE_UTF8_STRING
- iReturn = Xutf8TextListToTextProperty (pDisplay,
- pszTextList,
- 1,
- xiccesStyle,
- &xtpText);
-#endif
- }
- else
- {
- iReturn = XmbTextListToTextProperty (pDisplay,
- pszTextList,
- 1,
- xiccesStyle,
- &xtpText);
- }
- if (iReturn == XNoMemory || iReturn == XLocaleNotSupported)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "X*TextListToTextProperty failed: %d\n",
- iReturn);
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Free the converted string */
- free (pszConvertData);
- pszConvertData = NULL;
-
- /* Copy the clipboard text to the requesting window */
- iReturn = XChangeProperty (pDisplay,
- event.xselectionrequest.requestor,
- event.xselectionrequest.property,
- event.xselectionrequest.target,
- 8,
- PropModeReplace,
- xtpText.value,
- xtpText.nitems);
- if (iReturn == BadAlloc || iReturn == BadAtom
- || iReturn == BadMatch || iReturn == BadValue
- || iReturn == BadWindow)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XChangeProperty failed: %d\n",
- iReturn);
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Release the clipboard data */
- GlobalUnlock (hGlobal);
- pszGlobalData = NULL;
- fCloseClipboard = FALSE;
- CloseClipboard ();
-
- /* Clean up */
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
-
- /* 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 ("winClipboardFlushXEvents - SelectionRequest - "
- "XSendEvent () failed\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- winClipboardFlushXEvents_SelectionRequest_Done:
- /* Free allocated resources */
- if (xtpText.value)
- {
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
- }
- free(pszConvertData);
- if (hGlobal && pszGlobalData)
- GlobalUnlock (hGlobal);
-
- /*
- * Send a SelectionNotify event to the requesting
- * client when we abort.
- */
- if (fAbort)
- {
- /* 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)
- {
- /*
- * Should not be a problem if XSendEvent fails because
- * the client may simply have exited.
- */
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XSendEvent () failed for abort event.\n");
- }
- }
-
- /* Close clipboard if it was opened */
- if (fCloseClipboard)
- {
- fCloseClipboard = FALSE;
- CloseClipboard ();
- }
- break;
-
-
- /*
- * SelectionNotify
- */
-
- case SelectionNotify:
-
- winDebug ("winClipboardFlushXEvents - SelectionNotify\n");
- {
- char *pszAtomName;
- pszAtomName = XGetAtomName (pDisplay,
- event.xselection.selection);
-
- winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
- pszAtomName);
- XFree (pszAtomName);
- }
-
- /*
- * Request conversion of UTF8 and CompoundText targets.
- */
- if (event.xselection.property == None)
- {
- if (event.xselection.target == XA_STRING)
- {
- winDebug ("winClipboardFlushXEvents - SelectionNotify - "
- "XA_STRING\n");
-
- return WIN_XEVENTS_CONVERT;
- }
- else if (event.xselection.target == atomUTF8String)
- {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of UTF8 target.\n");
-
- XConvertSelection (pDisplay,
- event.xselection.selection,
- XA_STRING,
- atomLocalProperty,
- iWindow,
- CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush (pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselection.target == atomCompoundText)
- {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of CompoundText target.\n");
-
- XConvertSelection (pDisplay,
- event.xselection.selection,
- atomUTF8String,
- atomLocalProperty,
- iWindow,
- CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush (pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#endif
- else
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "Unknown format. Cannot request conversion, "
- "aborting.\n");
- break;
- }
- }
-
- /* Retrieve the size of the stored data */
- iReturn = XGetWindowProperty (pDisplay,
- iWindow,
- atomLocalProperty,
- 0,
- 0, /* Don't get data, just size */
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft,
- &xtpText.value);
- if (iReturn != Success)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "XGetWindowProperty () failed, aborting: %d\n",
- iReturn);
- break;
- }
-
- winDebug("SelectionNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
-
- /* Request the selection data */
- iReturn = XGetWindowProperty (pDisplay,
- iWindow,
- atomLocalProperty,
- 0,
- ulReturnBytesLeft,
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft,
- &xtpText.value);
- if (iReturn != Success)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "XGetWindowProperty () failed, aborting: %d\n",
- iReturn);
- break;
- }
-
- {
- char *pszAtomName = NULL;
-
- winDebug("SelectionNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
- pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
- winDebug("Notify atom name %s\n", pszAtomName);
- XFree (pszAtomName);
- pszAtomName = NULL;
- }
-
- if (fUseUnicode)
- {
-#ifdef X_HAVE_UTF8_STRING
- /* Convert the text property to a text list */
- iReturn = Xutf8TextPropertyToTextList (pDisplay,
- &xtpText,
- &ppszTextList,
- &iCount);
-#endif
- }
- else
- {
- iReturn = XmbTextPropertyToTextList (pDisplay,
- &xtpText,
- &ppszTextList,
- &iCount);
- }
- if (iReturn == Success || iReturn > 0)
- {
- /* Conversion succeeded or some unconvertible characters */
- if (ppszTextList != NULL)
- {
- iReturnDataLen = 0;
- for (i = 0; i < iCount; i++)
- {
- iReturnDataLen += strlen(ppszTextList[i]);
- }
- pszReturnData = malloc (iReturnDataLen + 1);
- pszReturnData[0] = '\0';
- for (i = 0; i < iCount; i++)
- {
- strcat (pszReturnData, ppszTextList[i]);
- }
- }
- else
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "X*TextPropertyToTextList list_return is NULL.\n");
- pszReturnData = malloc (1);
- pszReturnData[0] = '\0';
- }
- }
- else
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "X*TextPropertyToTextList returned: ");
- switch (iReturn)
- {
- case XNoMemory:
- ErrorF ("XNoMemory\n");
- break;
- case XConverterNotFound:
- ErrorF ("XConverterNotFound\n");
- break;
- default:
- ErrorF ("%d", iReturn);
- break;
- }
- pszReturnData = malloc (1);
- pszReturnData[0] = '\0';
- }
-
- /* Free the data returned from XGetWindowProperty */
- if (ppszTextList)
- XFreeStringList (ppszTextList);
- ppszTextList = NULL;
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
-
- /* Convert the X clipboard string to DOS format */
- winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData));
-
- if (fUseUnicode)
- {
- /* 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));
- if (!pwszUnicodeStr)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify "
- "malloc failed for pwszUnicodeStr, aborting.\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
- }
-
- /* Do the actual conversion */
- MultiByteToWideChar (CP_UTF8,
- 0,
- pszReturnData,
- -1,
- pwszUnicodeStr,
- iUnicodeLen);
-
- /* Allocate global memory for the X clipboard data */
- hGlobal = GlobalAlloc (GMEM_MOVEABLE,
- sizeof (wchar_t) * (iUnicodeLen + 1));
- }
- else
- {
- pszConvertData = strdup (pszReturnData);
- iConvertDataLen = strlen (pszConvertData) + 1;
-
- /* Allocate global memory for the X clipboard data */
- hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen);
- }
-
- free (pszReturnData);
-
- /* Check that global memory was allocated */
- if (!hGlobal)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify "
- "GlobalAlloc failed, aborting: %ld\n",
- GetLastError ());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
- }
-
- /* Obtain a pointer to the global memory */
- pszGlobalData = GlobalLock (hGlobal);
- if (pszGlobalData == NULL)
- {
- ErrorF ("winClipboardFlushXEvents - Could not lock global "
- "memory for clipboard transfer\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
- }
-
- /* Copy the returned string into the global memory */
- if (fUseUnicode)
- {
- memcpy (pszGlobalData,
- pwszUnicodeStr,
- sizeof (wchar_t) * (iUnicodeLen + 1));
- free (pwszUnicodeStr);
- pwszUnicodeStr = NULL;
- }
- else
- {
- strcpy (pszGlobalData, pszConvertData);
- free (pszConvertData);
- pszConvertData = NULL;
- }
-
- /* Release the pointer to the global memory */
- GlobalUnlock (hGlobal);
- pszGlobalData = NULL;
-
- /* Push the selection data to the Windows clipboard */
- if (fUseUnicode)
- SetClipboardData (CF_UNICODETEXT, hGlobal);
- else
- SetClipboardData (CF_TEXT, hGlobal);
-
- /* Flag that SetClipboardData has been called */
- fSetClipboardData = FALSE;
-
- /*
- * NOTE: Do not try to free pszGlobalData, it is owned by
- * Windows after the call to SetClipboardData ().
- */
-
- winClipboardFlushXEvents_SelectionNotify_Done:
- /* Free allocated resources */
- if (ppszTextList)
- XFreeStringList (ppszTextList);
- if (xtpText.value)
- {
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
- }
- free(pszConvertData);
- free(pwszUnicodeStr);
- if (hGlobal && pszGlobalData)
- GlobalUnlock (hGlobal);
- if (fSetClipboardData && g_fUnicodeSupport)
- SetClipboardData (CF_UNICODETEXT, NULL);
- if (fSetClipboardData)
- SetClipboardData (CF_TEXT, NULL);
- return WIN_XEVENTS_NOTIFY;
-
- case SelectionClear:
- winDebug("SelectionClear - doing nothing\n");
- break;
-
- case PropertyNotify:
- break;
-
- case MappingNotify:
- break;
-
- default:
- ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type);
- break;
- }
- }
-
- return WIN_XEVENTS_SUCCESS;
-}
+/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *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 HAROLD L HUNT II 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 copyright holder(s) + *and author(s) 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 copyright holder(s) and author(s). + * + * Authors: Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "winclipboard.h" +#include "misc.h" + + +/* + * References to external symbols + */ + +extern Bool g_fUnicodeSupport; + + +/* + * Process any pending X events + */ + +int +winClipboardFlushXEvents (HWND hwnd, + int iWindow, + Display *pDisplay, + Bool fUseUnicode) +{ + static Atom atomLocalProperty; + static Atom atomCompoundText; + static Atom atomUTF8String; + static Atom atomTargets; + static int generation; + + if (generation != serverGeneration) + { + generation = serverGeneration; + atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); + atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); + atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); + atomTargets = XInternAtom (pDisplay, "TARGETS", False); + } + + /* Process all pending events */ + while (XPending (pDisplay)) + { + XTextProperty xtpText = {0}; + XEvent event; + XSelectionEvent eventSelection; + unsigned long ulReturnBytesLeft; + char *pszReturnData = NULL; + char *pszGlobalData = NULL; + int iReturn; + HGLOBAL hGlobal = NULL; + XICCEncodingStyle xiccesStyle; + int iConvertDataLen = 0; + char *pszConvertData = NULL; + char *pszTextList[2] = {NULL}; + int iCount; + char **ppszTextList = NULL; + wchar_t *pwszUnicodeStr = NULL; + int iUnicodeLen = 0; + int iReturnDataLen = 0; + int i; + Bool fAbort = FALSE; + Bool fCloseClipboard = FALSE; + Bool fSetClipboardData = TRUE; + + /* Get the next event - will not block because one is ready */ + XNextEvent (pDisplay, &event); + + /* Branch on the event type */ + switch (event.type) + { + /* + * SelectionRequest + */ + + case SelectionRequest: + { + char *pszAtomName = NULL; + winDebug("SelectionRequest - target %d\n", + event.xselectionrequest.target); + + pszAtomName = XGetAtomName (pDisplay, + event.xselectionrequest.target); + winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + } + + /* Abort if invalid target type */ + if (event.xselectionrequest.target != XA_STRING + && event.xselectionrequest.target != atomUTF8String + && event.xselectionrequest.target != atomCompoundText + && event.xselectionrequest.target != atomTargets) + { + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Handle targets type of request */ + if (event.xselectionrequest.target == atomTargets) + { + Atom atomTargetArr[] = {atomTargets, + atomCompoundText, + atomUTF8String, + XA_STRING}; + + /* Try to change the property */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char *) atomTargetArr, + (sizeof (atomTargetArr) + / sizeof (atomTargetArr[0]))); + if (iReturn == BadAlloc + || iReturn == BadAtom + || iReturn == BadMatch + || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - 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 ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed\n"); + } + break; + } + + /* Check that clipboard format is available */ + if (fUseUnicode + && !IsClipboardFormatAvailable (CF_UNICODETEXT)) + { + static int count; /* Hack to stop acroread spamming the log */ + static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ + if (hwnd != lasthwnd) count = 0; + count++; + if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " + "available from Win32 clipboard. Aborting %d.\n", count); + lasthwnd = hwnd; + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + else if (!fUseUnicode + && !IsClipboardFormatAvailable (CF_TEXT)) + { + ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " + "available from Win32 clipboard. Aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Close clipboard if we have it open already */ + if (GetOpenClipboardWindow () == hwnd) + { + CloseClipboard (); + } + + /* Access the clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "OpenClipboard () failed: %08lx\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Indicate that clipboard was opened */ + fCloseClipboard = TRUE; + + /* Setup the string style */ + if (event.xselectionrequest.target == XA_STRING) + xiccesStyle = XStringStyle; +#ifdef X_HAVE_UTF8_STRING + else if (event.xselectionrequest.target == atomUTF8String) + xiccesStyle = XUTF8StringStyle; +#endif + 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, in desired format */ + if (fUseUnicode) + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_UNICODETEXT); + } + else + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_TEXT); + } + if (!hGlobal) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "GetClipboardData () failed: %08lx\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + pszGlobalData = (char *) GlobalLock (hGlobal); + + /* Convert the Unicode string to UTF8 (MBCS) */ + if (fUseUnicode) + { + iConvertDataLen = WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + NULL, + 0, + NULL, + NULL); + /* NOTE: iConvertDataLen includes space for null terminator */ + pszConvertData = (char *) malloc (iConvertDataLen); + WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + pszConvertData, + iConvertDataLen, + NULL, + NULL); + } + else + { + pszConvertData = strdup (pszGlobalData); + iConvertDataLen = strlen (pszConvertData) + 1; + } + + /* Convert DOS string to UNIX string */ + winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); + + /* Setup our text list */ + pszTextList[0] = pszConvertData; + pszTextList[1] = NULL; + + /* Initialize the text property */ + xtpText.value = NULL; + xtpText.nitems = 0; + + /* Create the text property from the text list */ + if (fUseUnicode) + { +#ifdef X_HAVE_UTF8_STRING + iReturn = Xutf8TextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); +#endif + } + else + { + iReturn = XmbTextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); + } + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "X*TextListToTextProperty failed: %d\n", + iReturn); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Free the converted string */ + free (pszConvertData); + pszConvertData = NULL; + + /* Copy the clipboard text to the requesting window */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + xtpText.value, + xtpText.nitems); + if (iReturn == BadAlloc || iReturn == BadAtom + || iReturn == BadMatch || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XChangeProperty failed: %d\n", + iReturn); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Release the clipboard data */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + fCloseClipboard = FALSE; + CloseClipboard (); + + /* Clean up */ + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + + /* 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 ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + winClipboardFlushXEvents_SelectionRequest_Done: + /* Free allocated resources */ + if (xtpText.value) + { + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + } + free(pszConvertData); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + + /* + * Send a SelectionNotify event to the requesting + * client when we abort. + */ + if (fAbort) + { + /* 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) + { + /* + * Should not be a problem if XSendEvent fails because + * the client may simply have exited. + */ + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed for abort event.\n"); + } + } + + /* Close clipboard if it was opened */ + if (fCloseClipboard) + { + fCloseClipboard = FALSE; + CloseClipboard (); + } + break; + + + /* + * SelectionNotify + */ + + case SelectionNotify: + + winDebug ("winClipboardFlushXEvents - SelectionNotify\n"); + { + char *pszAtomName; + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + + winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", + pszAtomName); + XFree (pszAtomName); + } + + /* + * Request conversion of UTF8 and CompoundText targets. + */ + if (event.xselection.property == None) + { + if (event.xselection.target == XA_STRING) + { + winDebug ("winClipboardFlushXEvents - SelectionNotify - " + "XA_STRING\n"); + + return WIN_XEVENTS_CONVERT; + } + else if (event.xselection.target == atomUTF8String) + { + winDebug("winClipboardFlushXEvents - SelectionNotify - " + "Requesting conversion of UTF8 target.\n"); + + XConvertSelection (pDisplay, + event.xselection.selection, + XA_STRING, + atomLocalProperty, + iWindow, + CurrentTime); + + /* Process the ConvertSelection event */ + XFlush (pDisplay); + return WIN_XEVENTS_CONVERT; + } +#ifdef X_HAVE_UTF8_STRING + else if (event.xselection.target == atomCompoundText) + { + winDebug("winClipboardFlushXEvents - SelectionNotify - " + "Requesting conversion of CompoundText target.\n"); + + XConvertSelection (pDisplay, + event.xselection.selection, + atomUTF8String, + atomLocalProperty, + iWindow, + CurrentTime); + + /* Process the ConvertSelection event */ + XFlush (pDisplay); + return WIN_XEVENTS_CONVERT; + } +#endif + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "Unknown format. Cannot request conversion, " + "aborting.\n"); + break; + } + } + + /* Retrieve the size of the stored data */ + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + 0, /* Don't get data, just size */ + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; + } + + winDebug("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); + + /* Request the selection data */ + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + ulReturnBytesLeft, + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; + } + + { + char *pszAtomName = NULL; + + winDebug("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); + pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); + winDebug("Notify atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + } + + if (fUseUnicode) + { +#ifdef X_HAVE_UTF8_STRING + /* Convert the text property to a text list */ + iReturn = Xutf8TextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); +#endif + } + else + { + iReturn = XmbTextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); + } + if (iReturn == Success || iReturn > 0) + { + /* Conversion succeeded or some unconvertible characters */ + if (ppszTextList != NULL) + { + iReturnDataLen = 0; + for (i = 0; i < iCount; i++) + { + iReturnDataLen += strlen(ppszTextList[i]); + } + pszReturnData = malloc (iReturnDataLen + 1); + pszReturnData[0] = '\0'; + for (i = 0; i < iCount; i++) + { + strcat (pszReturnData, ppszTextList[i]); + } + } + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "X*TextPropertyToTextList list_return is NULL.\n"); + pszReturnData = malloc (1); + pszReturnData[0] = '\0'; + } + } + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "X*TextPropertyToTextList returned: "); + switch (iReturn) + { + case XNoMemory: + ErrorF ("XNoMemory\n"); + break; + case XLocaleNotSupported: + ErrorF ("XLocaleNotSupported\n"); + break; + case XConverterNotFound: + ErrorF ("XConverterNotFound\n"); + break; + default: + ErrorF ("%d\n", iReturn); + break; + } + pszReturnData = malloc (1); + pszReturnData[0] = '\0'; + } + + /* Free the data returned from XGetWindowProperty */ + if (ppszTextList) + XFreeStringList (ppszTextList); + ppszTextList = NULL; + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + + /* Convert the X clipboard string to DOS format */ + winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); + + if (fUseUnicode) + { + /* 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)); + if (!pwszUnicodeStr) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "malloc failed for pwszUnicodeStr, aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Do the actual conversion */ + MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + pwszUnicodeStr, + iUnicodeLen); + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, + sizeof (wchar_t) * (iUnicodeLen + 1)); + } + else + { + pszConvertData = strdup (pszReturnData); + iConvertDataLen = strlen (pszConvertData) + 1; + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); + } + + free (pszReturnData); + + /* Check that global memory was allocated */ + if (!hGlobal) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "GlobalAlloc failed, aborting: %ld\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Obtain a pointer to the global memory */ + pszGlobalData = GlobalLock (hGlobal); + if (pszGlobalData == NULL) + { + ErrorF ("winClipboardFlushXEvents - Could not lock global " + "memory for clipboard transfer\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Copy the returned string into the global memory */ + if (fUseUnicode) + { + memcpy (pszGlobalData, + pwszUnicodeStr, + sizeof (wchar_t) * (iUnicodeLen + 1)); + free (pwszUnicodeStr); + pwszUnicodeStr = NULL; + } + else + { + strcpy (pszGlobalData, pszConvertData); + free (pszConvertData); + pszConvertData = NULL; + } + + /* Release the pointer to the global memory */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + + /* Push the selection data to the Windows clipboard */ + if (fUseUnicode) + SetClipboardData (CF_UNICODETEXT, hGlobal); + else + SetClipboardData (CF_TEXT, hGlobal); + + /* Flag that SetClipboardData has been called */ + fSetClipboardData = FALSE; + + /* + * NOTE: Do not try to free pszGlobalData, it is owned by + * Windows after the call to SetClipboardData (). + */ + + winClipboardFlushXEvents_SelectionNotify_Done: + /* Free allocated resources */ + if (ppszTextList) + XFreeStringList (ppszTextList); + if (xtpText.value) + { + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + } + free(pszConvertData); + free(pwszUnicodeStr); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + if (fSetClipboardData && g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + if (fSetClipboardData) + SetClipboardData (CF_TEXT, NULL); + return WIN_XEVENTS_NOTIFY; + + case SelectionClear: + winDebug("SelectionClear - doing nothing\n"); + break; + + case PropertyNotify: + break; + + case MappingNotify: + break; + + default: + ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type); + break; + } + } + + return WIN_XEVENTS_SUCCESS; +} diff --git a/xorg-server/hw/xwin/winmonitors.c b/xorg-server/hw/xwin/winmonitors.c index 63af803d0..a9d46f90e 100644 --- a/xorg-server/hw/xwin/winmonitors.c +++ b/xorg-server/hw/xwin/winmonitors.c @@ -53,7 +53,7 @@ wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _d return TRUE; } -typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); +typedef WINAPI wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors; wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data); diff --git a/xorg-server/hw/xwin/winmultiwindowicons.c b/xorg-server/hw/xwin/winmultiwindowicons.c index 6af9636ea..763cb7e08 100644 --- a/xorg-server/hw/xwin/winmultiwindowicons.c +++ b/xorg-server/hw/xwin/winmultiwindowicons.c @@ -1,642 +1,641 @@ -/*
- *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: Earle F. Philhower, III
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-#include "winprefs.h"
-
-#include "propertyst.h"
-
-#include "propertyst.h"
-#include "windowstr.h"
-
-
-/*
- * Prototypes for local functions
- */
-
-static void
-winScaleXBitmapToWindows (int iconSize, int effBPP,
- PixmapPtr pixmap, unsigned char *image);
-
-
-/*
- * Scale an X icon bitmap into a Windoze icon bitmap
- */
-
-static void
-winScaleXBitmapToWindows (int iconSize,
- int effBPP,
- PixmapPtr pixmap,
- unsigned char *image)
-{
- int row, column, effXBPP, effXDepth;
- unsigned char *outPtr;
- char *iconData = 0;
- int stride, xStride;
- float factX, factY;
- int posX, posY;
- unsigned char *ptr;
- unsigned int zero;
- unsigned int color;
-
- effXBPP = BitsPerPixel(pixmap->drawable.depth);
- effXDepth = pixmap->drawable.depth;
-
- if (pixmap->drawable.bitsPerPixel == 15)
- effXBPP = 16;
-
- if (pixmap->drawable.depth == 15)
- effXDepth = 16;
-
- /* Need 16-bit aligned rows for DDBitmaps */
- stride = ((iconSize * effBPP + 15) & (~15)) / 8;
- xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth);
- if (stride == 0 || xStride == 0)
- {
- ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. "
- "Bailing.\n");
- return;
- }
-
- /* Allocate memory for icon data */
- iconData = malloc (xStride * pixmap->drawable.height);
- if (!iconData)
- {
- ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. "
- "Bailing.\n");
- return;
- }
-
- /* Get icon data */
- miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0,
- pixmap->drawable.width, pixmap->drawable.height,
- ZPixmap, 0xffffffff, iconData);
-
- /* Keep aspect ratio */
- factX = ((float)pixmap->drawable.width) / ((float)iconSize);
- factY = ((float)pixmap->drawable.height) / ((float)iconSize);
- if (factX > factY)
- factY = factX;
- else
- factX = factY;
-
- /* Out-of-bounds, fill icon with zero */
- zero = 0;
-
- for (row = 0; row < iconSize; row++)
- {
- outPtr = image + stride * row;
- for (column = 0; column < iconSize; column++)
- {
- posX = factX * column;
- posY = factY * row;
-
- ptr = (unsigned char*) iconData + posY*xStride;
- if (effXBPP == 1)
- {
- ptr += posX / 8;
-
- /* Out of X icon bounds, leave space blank */
- if (posX >= pixmap->drawable.width
- || posY >= pixmap->drawable.height)
- ptr = (unsigned char *) &zero;
-
- if ((*ptr) & (1 << (posX & 7)))
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = 0;
- case 24:
- *(outPtr++) = 0;
- case 16:
- *(outPtr++) = 0;
- case 8:
- *(outPtr++) = 0;
- break;
- case 1:
- outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
- break;
- }
- else
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = 255;
- *(outPtr++) = 255;
- *(outPtr++) = 255;
- *(outPtr++) = 0;
- break;
- case 24:
- *(outPtr++) = 255;
- case 16:
- *(outPtr++) = 255;
- case 8:
- *(outPtr++) = 255;
- break;
- case 1:
- outPtr[column / 8] |= (1 << (7 - (column & 7)));
- break;
- }
- }
- else if (effXDepth == 24 || effXDepth == 32)
- {
- ptr += posX * (effXBPP / 8);
-
- /* Out of X icon bounds, leave space blank */
- if (posX >= pixmap->drawable.width
- || posY >= pixmap->drawable.height)
- ptr = (unsigned char *) &zero;
- color = (((*ptr) << 16)
- + ((*(ptr + 1)) << 8)
- + ((*(ptr + 2)) << 0));
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = *(ptr++); /* b */
- *(outPtr++) = *(ptr++); /* g */
- *(outPtr++) = *(ptr++); /* r */
- *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */
- break;
- case 24:
- *(outPtr++) = *(ptr++);
- *(outPtr++) = *(ptr++);
- *(outPtr++) = *(ptr++);
- break;
- case 16:
- color = ((((*ptr) >> 2) << 10)
- + (((*(ptr + 1)) >> 2) << 5)
- + (((*(ptr + 2)) >> 2)));
- *(outPtr++) = (color >> 8);
- *(outPtr++) = (color & 255);
- break;
- case 8:
- color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2))));
- color /= 3;
- *(outPtr++) = color;
- break;
- case 1:
- if (color)
- outPtr[column / 8] |= (1 << (7 - (column & 7)));
- else
- outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
- }
- }
- else if (effXDepth == 16)
- {
- ptr += posX * (effXBPP / 8);
-
- /* Out of X icon bounds, leave space blank */
- if (posX >= pixmap->drawable.width
- || posY >= pixmap->drawable.height)
- ptr = (unsigned char *) &zero;
- color = ((*ptr) << 8) + (*(ptr + 1));
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = (color & 31) << 2;
- *(outPtr++) = ((color >> 5) & 31) << 2;
- *(outPtr++) = ((color >> 10) & 31) << 2;
- *(outPtr++) = 0; /* resvd */
- break;
- case 24:
- *(outPtr++) = (color & 31) << 2;
- *(outPtr++) = ((color >> 5) & 31) << 2;
- *(outPtr++) = ((color >> 10) & 31) << 2;
- break;
- case 16:
- *(outPtr++) = *(ptr++);
- *(outPtr++) = *(ptr++);
- break;
- case 8:
- *(outPtr++) = (((color & 31)
- + ((color >> 5) & 31)
- + ((color >> 10) & 31)) / 3) << 2;
- break;
- case 1:
- if (color)
- outPtr[column / 8] |= (1 << (7 - (column & 7)));
- else
- outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
- break;
- } /* end switch(effbpp) */
- } /* end if effxbpp==16) */
- } /* end for column */
- } /* end for row */
- free (iconData);
-}
-
-static HICON
-NetWMToWinIconAlpha(uint32_t *icon)
-{
- int width = icon[0];
- int height = icon[1];
- uint32_t *pixels = &icon[2];
- HICON result;
- HDC hdc = GetDC(NULL);
- uint32_t *DIB_pixels;
- ICONINFO ii = {TRUE};
- BITMAPV4HEADER bmh = {sizeof(bmh)};
-
- /* Define an ARGB pixel format used for Color+Alpha icons */
- bmh.bV4Width = width;
- bmh.bV4Height = -height; /* Invert the image */
- bmh.bV4Planes = 1;
- bmh.bV4BitCount = 32;
- bmh.bV4V4Compression = BI_BITFIELDS;
- bmh.bV4AlphaMask = 0xFF000000;
- bmh.bV4RedMask = 0x00FF0000;
- bmh.bV4GreenMask = 0x0000FF00;
- bmh.bV4BlueMask = 0x000000FF;
-
- ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh,
- DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0);
- ReleaseDC(NULL, hdc);
- ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL);
- memcpy(DIB_pixels, pixels, height*width*4);
-
- /* CreateIconIndirect() traditionally required DDBitmaps */
- /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */
- /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */
- result = CreateIconIndirect(&ii);
-
- DeleteObject(ii.hbmColor);
- DeleteObject(ii.hbmMask);
-
- winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result);
- return result;
-}
-
-static HICON
-NetWMToWinIconThreshold(uint32_t *icon)
-{
- int width = icon[0];
- int height = icon[1];
- uint32_t *pixels = &icon[2];
- int row, col;
- HICON result;
- ICONINFO ii = {TRUE};
-
- HDC hdc = GetDC(NULL);
- HDC xorDC = CreateCompatibleDC(hdc);
- HDC andDC = CreateCompatibleDC(hdc);
- ii.hbmColor = CreateCompatibleBitmap(hdc, width, height);
- ii.hbmMask = CreateCompatibleBitmap(hdc, width, height);
- ReleaseDC(NULL, hdc);
- SelectObject(xorDC, ii.hbmColor);
- SelectObject(andDC, ii.hbmMask);
-
- for (row = 0; row < height; row++) {
- for (col = 0; col < width; col++) {
- if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */
- SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1],
- ((char*)pixels)[0]));
- SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */
- }
- else {
- SetPixelV(xorDC, col, row, RGB(0, 0, 0));
- SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */
- }
- pixels++;
- }
- }
- DeleteDC(xorDC);
- DeleteDC(andDC);
-
- result = CreateIconIndirect(&ii);
-
- DeleteObject(ii.hbmColor);
- DeleteObject(ii.hbmMask );
-
- winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result);
- return result;
-}
-
-static HICON
-NetWMToWinIcon(int bpp, uint32_t *icon)
-{
- static Bool hasIconAlphaChannel = FALSE;
- static BOOL versionChecked = FALSE;
-
- if (!versionChecked)
- {
- OSVERSIONINFOEX osvi = {0};
- ULONGLONG dwlConditionMask = 0;
-
- osvi.dwOSVersionInfoSize = sizeof (osvi);
- osvi.dwMajorVersion = 5;
- osvi.dwMinorVersion = 1;
-
- /* Windows versions later than XP have icon alpha channel suport, 2000 does not */
- VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
- VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
- hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask);
- versionChecked = TRUE;
-
- ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no");
- }
-
- if (hasIconAlphaChannel && (bpp==32))
- return NetWMToWinIconAlpha(icon);
- else
- return NetWMToWinIconThreshold(icon);
-}
-
-static pointer
-GetWindowProp(WindowPtr pWin, Atom name, long int *size_return)
-{
- struct _Window *pwin;
- struct _Property *prop;
-
- if (!pWin || !name) {
- ErrorF ("GetWindowProp - pWin or name was NULL\n");
- return 0;
- }
- pwin = (struct _Window*) pWin;
- if (!pwin->optional) return NULL;
- for (prop = (struct _Property *) pwin->optional->userProps;
- prop;
- prop=prop->next){
- if (prop->propertyName == name) {
- *size_return=prop->size;
- return prop->data;
- }
- }
- return NULL;
-}
-
-/*
- * Attempt to create a custom icon from the WM_HINTS bitmaps
- */
-
-HICON
-winXIconToHICON (WindowPtr pWin, int iconSize)
-{
- unsigned char *mask, *image, *imageMask;
- unsigned char *dst, *src;
- PixmapPtr iconPtr;
- PixmapPtr maskPtr;
- int planes, bpp, effBPP, stride, maskStride, i;
- int biggest_size = 0;
- HDC hDC;
- ICONINFO ii;
- WinXWMHints hints;
- HICON hIcon = NULL;
- uint32_t *biggest_icon = NULL;
-
- /* Try to get _NET_WM_ICON icons first */
- static Atom _XA_NET_WM_ICON;
- static int generation;
- uint32_t *icon, *icon_data = NULL;
- long int size=0;
-
- hDC = GetDC (GetDesktopWindow ());
- planes = GetDeviceCaps (hDC, PLANES);
- bpp = GetDeviceCaps (hDC, BITSPIXEL);
- ReleaseDC (GetDesktopWindow (), hDC);
-
- if (generation != serverGeneration) {
- generation = serverGeneration;
- _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE);
- }
-
- if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size);
- if (icon_data)
- {
- for(icon = icon_data;
- icon < &icon_data[size] && *icon;
- icon = &icon[icon[0]*icon[1]+2])
- {
- if (icon[0]==iconSize && icon[1]==iconSize)
- return NetWMToWinIcon(bpp, icon);
- /* Find the biggest icon and let Windows scale the size */
- else if (biggest_size < icon[0])
- {
- biggest_icon = icon;
- biggest_size = icon[0];
- }
- }
- if (biggest_icon)
- return NetWMToWinIcon(bpp, biggest_icon);
- }
- winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize);
-
- winMultiWindowGetWMHints (pWin, &hints);
- if (!hints.icon_pixmap) return NULL;
-
- dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP,
- NullClient, DixUnknownAccess);
-
- if (!iconPtr) return NULL;
-
- /* 15 BPP is really 16BPP as far as we care */
- if (bpp == 15)
- effBPP = 16;
- else
- effBPP = bpp;
-
- /* Need 16-bit aligned rows for DDBitmaps */
- stride = ((iconSize * effBPP + 15) & (~15)) / 8;
-
- /* Mask is 1-bit deep */
- maskStride = ((iconSize * 1 + 15) & (~15)) / 8;
-
- image = malloc (stride * iconSize);
- imageMask = malloc (stride * iconSize);
- /* Default to a completely black mask */
- mask = calloc (maskStride, iconSize);
-
- winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image);
- dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP,
- NullClient, DixUnknownAccess);
-
- if (maskPtr)
- {
- winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask);
-
- winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask);
-
- /* Now we need to set all bits of the icon which are not masked */
- /* on to 0 because Color is really an XOR, not an OR function */
- dst = image;
- src = imageMask;
-
- for (i = 0; i < (stride * iconSize); i++)
- if ((*(src++)))
- *(dst++) = 0;
- else
- dst++;
- }
-
- ii.fIcon = TRUE;
- ii.xHotspot = 0; /* ignored */
- ii.yHotspot = 0; /* ignored */
-
- /* Create Win32 mask from pixmap shape */
- ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask);
-
- /* Create Win32 bitmap from pixmap */
- ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image);
-
- /* Merge Win32 mask and bitmap into icon */
- hIcon = CreateIconIndirect (&ii);
-
- /* Release Win32 mask and bitmap */
- DeleteObject (ii.hbmMask);
- DeleteObject (ii.hbmColor);
-
- /* Free X mask and bitmap */
- free (mask);
- free (image);
- free (imageMask);
-
- return hIcon;
-}
-
-
-
-/*
- * Change the Windows window icon
- */
-
-#ifdef XWIN_MULTIWINDOW
-void
-winUpdateIcon (Window id)
-{
- WindowPtr pWin;
- HICON hIcon, hIconSmall=NULL, hIconOld;
-
- dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
- if (pWin)
- {
- winWindowPriv(pWin);
- if (pWinPriv->hWnd) {
- hIcon = winOverrideIcon ((unsigned long)pWin);
- if (!hIcon) {
- hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
- if (!hIcon) {
- hIcon = g_hIconX;
- hIconSmall = g_hSmallIconX;
- } else {
- /* Leave undefined if not found */
- hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
- }
- }
-
- /* Set the large icon */
- hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
- WM_SETICON, ICON_BIG, (LPARAM) hIcon);
-
- /* Delete the icon if its not the default */
- winDestroyIcon(hIconOld);
-
- /* Same for the small icon */
- hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
- WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
- winDestroyIcon(hIconOld);
- }
- }
-}
-
-void winInitGlobalIcons (void)
-{
- int sm_cx = GetSystemMetrics(SM_CXICON);
- int sm_cxsm = GetSystemMetrics(SM_CXSMICON);
- /* Load default X icon in case it's not ready yet */
- if (!g_hIconX)
- {
- g_hIconX = winOverrideDefaultIcon(sm_cx);
- g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm);
- }
-
- if (!g_hIconX)
- {
- g_hIconX = (HICON)LoadImage (g_hInstance,
- MAKEINTRESOURCE(IDI_XWIN),
- IMAGE_ICON,
- GetSystemMetrics(SM_CXICON),
- GetSystemMetrics(SM_CYICON),
- 0);
- g_hSmallIconX = (HICON)LoadImage (g_hInstance,
- MAKEINTRESOURCE(IDI_XWIN),
- IMAGE_ICON,
- GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON),
- LR_DEFAULTSIZE);
- }
-}
-
-void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon)
-{
- HICON hIcon, hSmallIcon;
-
- winInitGlobalIcons();
-
- /* Try and get the icon from WM_HINTS */
- hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
- hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
-
- /* If we got the small, but not the large one swap them */
- if (!hIcon && hSmallIcon)
- {
- hIcon = hSmallIcon;
- hSmallIcon = NULL;
- }
-
- /* Use default X icon if no icon loaded from WM_HINTS */
- if (!hIcon) {
- hIcon = g_hIconX;
- hSmallIcon = g_hSmallIconX;
- }
-
- if (pIcon)
- *pIcon = hIcon;
- else
- winDestroyIcon(hIcon);
- if (pSmallIcon)
- *pSmallIcon = hSmallIcon;
- else
- winDestroyIcon(hSmallIcon);
-}
-
-void winDestroyIcon(HICON hIcon)
-{
- /* Delete the icon if its not the default */
- if (hIcon &&
- hIcon != g_hIconX &&
- hIcon != g_hSmallIconX &&
- !winIconIsOverride((unsigned long)hIcon))
- DestroyIcon (hIcon);
-}
-#endif
+/* + *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: Earle F. Philhower, III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + +#include "propertyst.h" +#include "windowstr.h" + + +/* + * Prototypes for local functions + */ + +static void +winScaleXBitmapToWindows (int iconSize, int effBPP, + PixmapPtr pixmap, unsigned char *image); + + +/* + * Scale an X icon bitmap into a Windoze icon bitmap + */ + +static void +winScaleXBitmapToWindows (int iconSize, + int effBPP, + PixmapPtr pixmap, + unsigned char *image) +{ + int row, column, effXBPP, effXDepth; + unsigned char *outPtr; + char *iconData = 0; + int stride, xStride; + float factX, factY; + int posX, posY; + unsigned char *ptr; + unsigned int zero; + unsigned int color; + + effXBPP = BitsPerPixel(pixmap->drawable.depth); + effXDepth = pixmap->drawable.depth; + + if (pixmap->drawable.bitsPerPixel == 15) + effXBPP = 16; + + if (pixmap->drawable.depth == 15) + effXDepth = 16; + + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; + xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth); + if (stride == 0 || xStride == 0) + { + ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. " + "Bailing.\n"); + return; + } + + /* Allocate memory for icon data */ + iconData = malloc (xStride * pixmap->drawable.height); + if (!iconData) + { + ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. " + "Bailing.\n"); + return; + } + + /* Get icon data */ + miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0, + pixmap->drawable.width, pixmap->drawable.height, + ZPixmap, 0xffffffff, iconData); + + /* Keep aspect ratio */ + factX = ((float)pixmap->drawable.width) / ((float)iconSize); + factY = ((float)pixmap->drawable.height) / ((float)iconSize); + if (factX > factY) + factY = factX; + else + factX = factY; + + /* Out-of-bounds, fill icon with zero */ + zero = 0; + + for (row = 0; row < iconSize; row++) + { + outPtr = image + stride * row; + for (column = 0; column < iconSize; column++) + { + posX = factX * column; + posY = factY * row; + + ptr = (unsigned char*) iconData + posY*xStride; + if (effXBPP == 1) + { + ptr += posX / 8; + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + + if ((*ptr) & (1 << (posX & 7))) + switch (effBPP) + { + case 32: + *(outPtr++) = 0; + case 24: + *(outPtr++) = 0; + case 16: + *(outPtr++) = 0; + case 8: + *(outPtr++) = 0; + break; + case 1: + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } + else + switch (effBPP) + { + case 32: + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 0; + break; + case 24: + *(outPtr++) = 255; + case 16: + *(outPtr++) = 255; + case 8: + *(outPtr++) = 255; + break; + case 1: + outPtr[column / 8] |= (1 << (7 - (column & 7))); + break; + } + } + else if (effXDepth == 24 || effXDepth == 32) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = (((*ptr) << 16) + + ((*(ptr + 1)) << 8) + + ((*(ptr + 2)) << 0)); + switch (effBPP) + { + case 32: + *(outPtr++) = *(ptr++); /* b */ + *(outPtr++) = *(ptr++); /* g */ + *(outPtr++) = *(ptr++); /* r */ + *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */ + break; + case 24: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 16: + color = ((((*ptr) >> 2) << 10) + + (((*(ptr + 1)) >> 2) << 5) + + (((*(ptr + 2)) >> 2))); + *(outPtr++) = (color >> 8); + *(outPtr++) = (color & 255); + break; + case 8: + color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2)))); + color /= 3; + *(outPtr++) = color; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + } + } + else if (effXDepth == 16) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = ((*ptr) << 8) + (*(ptr + 1)); + switch (effBPP) + { + case 32: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + *(outPtr++) = 0; /* resvd */ + break; + case 24: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + break; + case 16: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 8: + *(outPtr++) = (((color & 31) + + ((color >> 5) & 31) + + ((color >> 10) & 31)) / 3) << 2; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } /* end switch(effbpp) */ + } /* end if effxbpp==16) */ + } /* end for column */ + } /* end for row */ + free (iconData); +} + +static HICON +NetWMToWinIconAlpha(uint32_t *icon) +{ + int width = icon[0]; + int height = icon[1]; + uint32_t *pixels = &icon[2]; + HICON result; + HDC hdc = GetDC(NULL); + uint32_t *DIB_pixels; + ICONINFO ii = {TRUE}; + BITMAPV4HEADER bmh = {sizeof(bmh)}; + + /* Define an ARGB pixel format used for Color+Alpha icons */ + bmh.bV4Width = width; + bmh.bV4Height = -height; /* Invert the image */ + bmh.bV4Planes = 1; + bmh.bV4BitCount = 32; + bmh.bV4V4Compression = BI_BITFIELDS; + bmh.bV4AlphaMask = 0xFF000000; + bmh.bV4RedMask = 0x00FF0000; + bmh.bV4GreenMask = 0x0000FF00; + bmh.bV4BlueMask = 0x000000FF; + + ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, + DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0); + ReleaseDC(NULL, hdc); + ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL); + memcpy(DIB_pixels, pixels, height*width*4); + + /* CreateIconIndirect() traditionally required DDBitmaps */ + /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */ + /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */ + result = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask); + + winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result); + return result; +} + +static HICON +NetWMToWinIconThreshold(uint32_t *icon) +{ + int width = icon[0]; + int height = icon[1]; + uint32_t *pixels = &icon[2]; + int row, col; + HICON result; + ICONINFO ii = {TRUE}; + + HDC hdc = GetDC(NULL); + HDC xorDC = CreateCompatibleDC(hdc); + HDC andDC = CreateCompatibleDC(hdc); + ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); + ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); + ReleaseDC(NULL, hdc); + SelectObject(xorDC, ii.hbmColor); + SelectObject(andDC, ii.hbmMask); + + for (row = 0; row < height; row++) { + for (col = 0; col < width; col++) { + if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */ + SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1], + ((char*)pixels)[0])); + SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */ + } + else { + SetPixelV(xorDC, col, row, RGB(0, 0, 0)); + SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */ + } + pixels++; + } + } + DeleteDC(xorDC); + DeleteDC(andDC); + + result = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask ); + + winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result); + return result; +} + +static HICON +NetWMToWinIcon(int bpp, uint32_t *icon) +{ + static Bool hasIconAlphaChannel = FALSE; + static BOOL versionChecked = FALSE; + + if (!versionChecked) + { + OSVERSIONINFOEX osvi = {0}; + ULONGLONG dwlConditionMask = 0; + + osvi.dwOSVersionInfoSize = sizeof (osvi); + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 1; + + /* Windows versions later than XP have icon alpha channel suport, 2000 does not */ + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); + versionChecked = TRUE; + + ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no"); + } + + if (hasIconAlphaChannel && (bpp==32)) + return NetWMToWinIconAlpha(icon); + else + return NetWMToWinIconThreshold(icon); +} + +static pointer +GetWindowProp(WindowPtr pWin, Atom name, long int *size_return) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !name) { + ErrorF ("GetWindowProp - pWin or name was NULL\n"); + return 0; + } + pwin = (struct _Window*) pWin; + if (!pwin->optional) return NULL; + for (prop = (struct _Property *) pwin->optional->userProps; + prop; + prop=prop->next){ + if (prop->propertyName == name) { + *size_return=prop->size; + return prop->data; + } + } + return NULL; +} + +/* + * Attempt to create a custom icon from the WM_HINTS bitmaps + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize) +{ + unsigned char *mask, *image, *imageMask; + unsigned char *dst, *src; + PixmapPtr iconPtr; + PixmapPtr maskPtr; + int planes, bpp, effBPP, stride, maskStride, i; + int biggest_size = 0; + HDC hDC; + ICONINFO ii; + WinXWMHints hints; + HICON hIcon = NULL; + uint32_t *biggest_icon = NULL; + + /* Try to get _NET_WM_ICON icons first */ + static Atom _XA_NET_WM_ICON; + static int generation; + uint32_t *icon, *icon_data = NULL; + long int size=0; + + hDC = GetDC (GetDesktopWindow ()); + planes = GetDeviceCaps (hDC, PLANES); + bpp = GetDeviceCaps (hDC, BITSPIXEL); + ReleaseDC (GetDesktopWindow (), hDC); + + if (generation != serverGeneration) { + generation = serverGeneration; + _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE); + } + + if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); + if (icon_data) + { + for(icon = icon_data; + icon < &icon_data[size] && *icon; + icon = &icon[icon[0]*icon[1]+2]) + { + if (icon[0]==iconSize && icon[1]==iconSize) + return NetWMToWinIcon(bpp, icon); + /* Find the biggest icon and let Windows scale the size */ + else if (biggest_size < icon[0]) + { + biggest_icon = icon; + biggest_size = icon[0]; + } + } + if (biggest_icon) + return NetWMToWinIcon(bpp, biggest_icon); + } + winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize); + + winMultiWindowGetWMHints (pWin, &hints); + if (!hints.icon_pixmap) return NULL; + + dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, + NullClient, DixUnknownAccess); + + if (!iconPtr) return NULL; + + /* 15 BPP is really 16BPP as far as we care */ + if (bpp == 15) + effBPP = 16; + else + effBPP = bpp; + + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; + + /* Mask is 1-bit deep */ + maskStride = ((iconSize * 1 + 15) & (~15)) / 8; + + image = malloc (stride * iconSize); + imageMask = malloc (stride * iconSize); + /* Default to a completely black mask */ + mask = calloc (maskStride, iconSize); + + winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); + dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP, + NullClient, DixUnknownAccess); + + if (maskPtr) + { + winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask); + + winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask); + + /* Now we need to set all bits of the icon which are not masked */ + /* on to 0 because Color is really an XOR, not an OR function */ + dst = image; + src = imageMask; + + for (i = 0; i < (stride * iconSize); i++) + if ((*(src++))) + *(dst++) = 0; + else + dst++; + } + + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ + + /* Create Win32 mask from pixmap shape */ + ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask); + + /* Create Win32 bitmap from pixmap */ + ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image); + + /* Merge Win32 mask and bitmap into icon */ + hIcon = CreateIconIndirect (&ii); + + /* Release Win32 mask and bitmap */ + DeleteObject (ii.hbmMask); + DeleteObject (ii.hbmColor); + + /* Free X mask and bitmap */ + free (mask); + free (image); + free (imageMask); + + return hIcon; +} + + + +/* + * Change the Windows window icon + */ + +#ifdef XWIN_MULTIWINDOW +void +winUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hIconSmall=NULL, hIconOld; + + dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); + if (pWin) + { + winWindowPriv(pWin); + if (pWinPriv->hWnd) { + hIcon = winOverrideIcon ((unsigned long)pWin); + if (!hIcon) { + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + if (!hIcon) { + hIcon = g_hIconX; + hIconSmall = g_hSmallIconX; + } else { + /* Leave undefined if not found */ + hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + } + } + + /* Set the large icon */ + hIconOld = (HICON) SendMessage (pWinPriv->hWnd, + WM_SETICON, ICON_BIG, (LPARAM) hIcon); + + /* Delete the icon if its not the default */ + winDestroyIcon(hIconOld); + + /* Same for the small icon */ + hIconOld = (HICON) SendMessage (pWinPriv->hWnd, + WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); + winDestroyIcon(hIconOld); + } + } +} + +void winInitGlobalIcons (void) +{ + int sm_cx = GetSystemMetrics(SM_CXICON); + int sm_cxsm = GetSystemMetrics(SM_CXSMICON); + /* Load default X icon in case it's not ready yet */ + if (!g_hIconX) + { + g_hIconX = winOverrideDefaultIcon(sm_cx); + g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm); + } + + if (!g_hIconX) + { + g_hIconX = (HICON)LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), + 0); + g_hSmallIconX = (HICON)LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTSIZE); + } +} + +void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) +{ + HICON hIcon, hSmallIcon; + + winInitGlobalIcons(); + + /* Try and get the icon from WM_HINTS */ + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + + /* If we got the small, but not the large one swap them */ + if (!hIcon && hSmallIcon) + { + hIcon = hSmallIcon; + hSmallIcon = NULL; + } + + /* Use default X icon if no icon loaded from WM_HINTS */ + if (!hIcon) { + hIcon = g_hIconX; + hSmallIcon = g_hSmallIconX; + } + + if (pIcon) + *pIcon = hIcon; + else + winDestroyIcon(hIcon); + + if (pSmallIcon) + *pSmallIcon = hSmallIcon; + else + winDestroyIcon(hSmallIcon); +} + +void winDestroyIcon(HICON hIcon) +{ + /* Delete the icon if its not one of the application defaults or an override */ + if (hIcon && + hIcon != g_hIconX && + hIcon != g_hSmallIconX && + !winIconIsOverride((unsigned long)hIcon)) + DestroyIcon (hIcon); +} +#endif diff --git a/xorg-server/hw/xwin/winmultiwindowwindow.c b/xorg-server/hw/xwin/winmultiwindowwindow.c index 93434fceb..21b818b89 100644 --- a/xorg-server/hw/xwin/winmultiwindowwindow.c +++ b/xorg-server/hw/xwin/winmultiwindowwindow.c @@ -1,992 +1,1008 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2008
- *
- *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
- * Earle F. Philhower, III
- * Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-
-/*
- * Prototypes for local functions
- */
-
-void
-winCreateWindowsWindow (WindowPtr pWin);
-
-static void
-winDestroyWindowsWindow (WindowPtr pWin);
-
-static void
-winUpdateWindowsWindow (WindowPtr pWin);
-
-static void
-winFindWindow (pointer value, XID id, pointer cdata);
-
-static
-void winInitMultiWindowClass(void)
-{
- static wATOM atomXWinClass=0;
- WNDCLASSEX wcx;
-
- if (atomXWinClass==0)
- {
- /* Setup our window class */
- wcx.cbSize=sizeof(WNDCLASSEX);
- wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
- wcx.lpfnWndProc = winTopLevelWindowProc;
- wcx.cbClsExtra = 0;
- wcx.cbWndExtra = 0;
- wcx.hInstance = g_hInstance;
- wcx.hIcon = g_hIconX;
- wcx.hCursor = 0;
- wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
- wcx.lpszMenuName = NULL;
- wcx.lpszClassName = WINDOW_CLASS_X;
- wcx.hIconSm = g_hSmallIconX;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
-#endif
-
- atomXWinClass = RegisterClassEx (&wcx);
- }
-}
-
-/*
- * CreateWindow - See Porting Layer Definition - p. 37
- */
-
-Bool
-winCreateWindowMultiWindow (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin);
-#endif
-
- WIN_UNWRAP(CreateWindow);
- fResult = (*pScreen->CreateWindow) (pWin);
- WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
-
- /* 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;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
-#endif
-
- WIN_UNWRAP(DestroyWindow);
- fResult = (*pScreen->DestroyWindow)(pWin);
- WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
-
- /* 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
- *
- * This function adjusts the position and size of Windows window
- * with respect to the underlying X window. This is the inverse
- * of winAdjustXWindow, which adjusts X window to Windows window.
- */
-
-Bool
-winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
-{
- Bool fResult = TRUE;
- int iX, iY, iWidth, iHeight;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- HWND hWnd = pWinPriv->hWnd;
- RECT rcNew;
- RECT rcOld;
-#if CYGMULTIWINDOW_DEBUG
- RECT rcClient;
- RECT *lpRc;
-#endif
- DWORD dwExStyle;
- DWORD dwStyle;
-
-#if CYGMULTIWINDOW_DEBUG
- winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin);
-#endif
-
- WIN_UNWRAP(PositionWindow);
- fResult = (*pScreen->PositionWindow)(pWin, x, y);
- WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
- x, y);
-#endif
-
- /* Bail out if the Windows window handle is bad */
- if (!hWnd)
- {
-#if CYGWINDOWING_DEBUG
- ErrorF ("\timmediately return since hWnd is NULL\n");
-#endif
- return fResult;
- }
-
- /* Get the Windows window style and extended style */
- dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
-
- /* Get the X and Y location of the X window */
- iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* 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
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#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;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(ChangeWindowAttributes);
- fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
- WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
-
- /*
- * 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;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(UnrealizeWindow);
- fResult = (*pScreen->UnrealizeWindow)(pWin);
- WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
-
- /* 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;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(RealizeWindow);
- fResult = (*pScreen->RealizeWindow)(pWin);
- WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
-
- /* Flag that this window has not been destroyed */
- pWinPriv->fXKilled = FALSE;
-
- /* Refresh/redisplay the Windows window associated with this X window */
- winUpdateWindowsWindow (pWin);
-
- /* Update the Windows window's shape */
- winReshapeMultiWindow (pWin);
- winUpdateRgnMultiWindow (pWin);
-
- return fResult;
-}
-
-
-/*
- * ReparentWindow - See Porting Layer Definition - p. 42
- */
-
-void
-winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(ReparentWindow);
- if (pScreen->ReparentWindow)
- (*pScreen->ReparentWindow)(pWin, pPriorParent);
- WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
-
- /* 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)
-{
-#if 0
- WindowPtr pPrevWin;
- UINT uFlags;
- HWND hInsertAfter;
- HWND hWnd = NULL;
-#endif
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
- winTrace ("winRestackMultiWindow - %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(RestackWindow);
- if (pScreen->RestackWindow)
- (*pScreen->RestackWindow)(pWin, pOldNextSib);
- WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
-
-#if 1
- /*
- * Calling winReorderWindowsMultiWindow here means our window manager
- * (i.e. Windows Explorer) has initiative to determine Z order.
- */
- if (pWin->nextSib != pOldNextSib)
- winReorderWindowsMultiWindow ();
-#else
- /* 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;
-
- hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
-
- do
- {
- if (GetProp (hWnd, WIN_WINDOW_PROP))
- {
- if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
- {
- uFlags |= SWP_NOZORDER;
- }
- break;
- }
- hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
- }
- while (hWnd);
- }
- 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);
-#endif
-}
-
-
-/*
- * winCreateWindowsWindow - Create a Windows window associated with an X window
- */
-
-void
-winCreateWindowsWindow (WindowPtr pWin)
-{
- int iX, iY;
- int iWidth;
- int iHeight;
- HWND hWnd;
- HWND hFore = NULL;
- winWindowPriv(pWin);
- HICON hIcon;
- HICON hIconSmall;
- winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
- WinXSizeHints hints;
- WindowPtr pDaddy;
-
- winInitMultiWindowClass();
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
-#endif
-
- iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* ensure window actually ends up somewhere visible */
- if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))
- iX = CW_USEDEFAULT;
-
- if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))
- iY = CW_USEDEFAULT;
-
- if (winMultiWindowGetTransientFor (pWin, &pDaddy))
- {
- if (pDaddy)
- {
- hFore = GetForegroundWindow();
- if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL;
- }
- }
- else
- {
- /* Default positions if none specified */
- if (!winMultiWindowGetWMNormalHints(pWin, &hints))
- hints.flags = 0;
- if (!(hints.flags & (USPosition|PPosition)) &&
- !pWin->overrideRedirect)
- {
- iX = CW_USEDEFAULT;
- iY = CW_USEDEFAULT;
- }
- }
-
- /* Create the window */
- /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
- /* CW_USEDEFAULT, change back to popup after creation */
- hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
- WINDOW_CLASS_X, /* Class name */
- WINDOW_TITLE_X, /* Window name */
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
- iX, /* Horizontal position */
- iY, /* Vertical position */
- iWidth, /* Right edge */
- iHeight, /* Bottom edge */
- hFore, /* Null or Parent window if transient*/
- (HMENU) NULL, /* No menu */
- GetModuleHandle (NULL), /* Instance handle */
- pWin); /* ScreenPrivates */
- if (hWnd == NULL)
- {
- ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
- (int) GetLastError ());
- }
- pWinPriv->hWnd = hWnd;
-
- /* Set application or .XWinrc defined Icons */
- winSelectIcons(pWin, &hIcon, &hIconSmall);
- if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
- if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
-
- /* Change style back to popup, already placed... */
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
- SetWindowPos (hWnd, 0, 0, 0, 0, 0,
- SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- /* Make sure it gets the proper system menu for a WS_POPUP, too */
- GetSystemMenu (hWnd, TRUE);
-
- /* Cause any .XWinrc menus to be added in main WNDPROC */
- PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
-
- SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
-
- /* Flag that this Windows window handles its own activation */
- SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
-
- /* Call engine-specific create window procedure */
- (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
-}
-
-
-Bool winInDestroyWindowsWindow = FALSE;
-/*
- * winDestroyWindowsWindow - Destroy a Windows window associated
- * with an X window
- */
-static void
-winDestroyWindowsWindow (WindowPtr pWin)
-{
- MSG msg;
- winWindowPriv(pWin);
- BOOL oldstate = winInDestroyWindowsWindow;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winDestroyWindowsWindow\n");
-#endif
-
- /* Bail out if the Windows window handle is invalid */
- if (pWinPriv->hWnd == NULL)
- return;
-
- winInDestroyWindowsWindow = TRUE;
-
- SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
- /* Destroy the Windows window */
- DestroyWindow (pWinPriv->hWnd);
-
- /* Null our handle to the Window so referencing it will cause an error */
- 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);
- }
- }
-
- winInDestroyWindowsWindow = oldstate;
-
-#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
-}
-
-
-/*
- * winGetWindowID -
- */
-
-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;
-}
-
-
-/*
- * winFindWindow -
- */
-
-static void
-winFindWindow (pointer value, XID id, pointer cdata)
-{
- WindowIDPairPtr wi = (WindowIDPairPtr)cdata;
-
- if (value == wi->value)
- {
- wi->id = id;
- }
-}
-
-
-/*
- * winReorderWindowsMultiWindow -
- */
-
-void
-winReorderWindowsMultiWindow (void)
-{
- HWND hwnd = NULL;
- WindowPtr pWin = NULL;
- WindowPtr pWinSib = NULL;
- XID vlist[2];
- static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
-
-#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
- winTrace ("winReorderWindowsMultiWindow\n");
-#endif
-
- if (fRestacking)
- {
- /* It is a recusive call so immediately exit */
-#if CYGWINDOWING_DEBUG
- ErrorF ("winReorderWindowsMultiWindow - "
- "exit because fRestacking == TRUE\n");
-#endif
- return;
- }
- fRestacking = TRUE;
-
- /* Loop through top level Window windows, descending in Z order */
- for ( hwnd = GetTopWindow (NULL);
- hwnd;
- hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) )
- {
- /* Don't take care of other Cygwin/X process's windows */
- GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
-
- if ( GetProp (hwnd, WIN_WINDOW_PROP)
- && (dwWindowProcessID == dwCurrentProcessID)
- && !IsIconic (hwnd) ) /* ignore minimized windows */
- {
- pWinSib = pWin;
- pWin = GetProp (hwnd, WIN_WINDOW_PROP);
-
- if (!pWinSib)
- { /* 1st window - raise to the top */
- vlist[0] = Above;
-
- ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
- }
- else
- { /* 2nd or deeper windows - just below the previous one */
- vlist[0] = winGetWindowID (pWinSib);
- vlist[1] = Below;
-
- ConfigureWindow (pWin, CWSibling | CWStackMode,
- vlist, wClient(pWin));
- }
- }
- }
-
- fRestacking = FALSE;
-}
-
-
-/*
- * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
- */
-
-void
-winMinimizeWindow (Window id)
-{
- WindowPtr pWin;
- winPrivWinPtr pWinPriv;
-#ifdef XWIN_MULTIWINDOWEXTWM
- win32RootlessWindowPtr pRLWinPriv;
-#endif
- HWND hWnd;
- ScreenPtr pScreen = NULL;
- winPrivScreenPtr pScreenPriv = NULL;
- winScreenInfo *pScreenInfo = NULL;
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("winMinimizeWindow\n");
-#endif
-
- dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
- if (!pWin)
- {
- ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
- return;
- }
-
- pScreen = pWin->drawable.pScreen;
- if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
-
-#ifdef XWIN_MULTIWINDOWEXTWM
- if (pScreenPriv && pScreenInfo->fInternalWM)
- {
- pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
- hWnd = pRLWinPriv->hWnd;
- }
- else
-#else
- if (pScreenPriv)
-#endif
- {
- pWinPriv = winGetWindowPriv (pWin);
- hWnd = pWinPriv->hWnd;
- }
-
- ShowWindow (hWnd, SW_MINIMIZE);
-}
-
-
-/*
- * CopyWindow - See Porting Layer Definition - p. 39
- */
-void
-winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
- RegionPtr oldRegion)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("CopyWindowMultiWindow\n");
-#endif
- WIN_UNWRAP(CopyWindow);
- (*pScreen->CopyWindow)(pWin, oldpt, oldRegion);
- WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
-}
-
-
-/*
- * MoveWindow - See Porting Layer Definition - p. 42
- */
-void
-winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
- WindowPtr pSib, VTKind kind)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y);
-#endif
-
- WIN_UNWRAP(MoveWindow);
- (*pScreen->MoveWindow)(pWin, x, y, pSib, kind);
- WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
-}
-
-
-/*
- * ResizeWindow - See Porting Layer Definition - p. 42
- */
-void
-winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
- unsigned int h, WindowPtr pSib)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
-#endif
- WIN_UNWRAP(ResizeWindow);
- (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
- WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
-}
-
-
-/*
- * winAdjustXWindow
- *
- * Move and resize X window with respect to corresponding Windows window.
- * This is called from WM_MOVE/WM_SIZE handlers when the user performs
- * any windowing operation (move, resize, minimize, maximize, restore).
- *
- * The functionality is the inverse of winPositionWindowMultiWindow, which
- * adjusts Windows window with respect to X window.
- */
-int
-winAdjustXWindow (WindowPtr pWin, HWND hwnd)
-{
- RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
- RECT rcWin; /* The source: WindowRect from hwnd */
- DrawablePtr pDraw;
- XID vlist[4];
- LONG dX, dY, dW, dH, x, y;
- DWORD dwStyle, dwExStyle;
-
-#define WIDTH(rc) (rc.right - rc.left)
-#define HEIGHT(rc) (rc.bottom - rc.top)
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("winAdjustXWindow\n");
-#endif
-
- if (IsIconic (hwnd))
- {
-#if CYGWINDOWING_DEBUG
- ErrorF ("\timmediately return because the window is iconized\n");
-#endif
- /*
- * If the Windows window is minimized, its WindowRect has
- * meaningless values so we don't adjust X window to it.
- */
- vlist[0] = 0;
- vlist[1] = 0;
- return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
- }
-
- pDraw = &pWin->drawable;
-
- /* Calculate the window rect from the drawable */
- x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
- SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
- rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
-#endif
- dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
-#endif
- AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);
-
- /* The source of adjust */
- GetWindowRect (hwnd, &rcWin);
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
- rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
- winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
- rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
-#endif
-
- if (EqualRect (&rcDraw, &rcWin)) {
- /* Bail if no adjust is needed */
-#if CYGWINDOWING_DEBUG
- ErrorF ("\treturn because already adjusted\n");
-#endif
- return 0;
- }
-
- /* Calculate delta values */
- dX = rcWin.left - rcDraw.left;
- dY = rcWin.top - rcDraw.top;
- dW = WIDTH(rcWin) - WIDTH(rcDraw);
- dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
-
- /*
- * Adjust.
- * We may only need to move (vlist[0] and [1]), or only resize
- * ([2] and [3]) but currently we set all the parameters and leave
- * the decision to ConfigureWindow. The reason is code simplicity.
- */
- vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
- vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
- vlist[2] = pDraw->width + dW;
- vlist[3] = pDraw->height + dH;
-#if CYGWINDOWING_DEBUG
- ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
- vlist[2], vlist[3]);
-#endif
- return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
- vlist, wClient(pWin));
-
-#undef WIDTH
-#undef HEIGHT
-}
-
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *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 + * Earle F. Philhower, III + * Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" + +/* + * Prototypes for local functions + */ + +void +winCreateWindowsWindow (WindowPtr pWin); + +static void +winDestroyWindowsWindow (WindowPtr pWin); + +static void +winUpdateWindowsWindow (WindowPtr pWin); + +static void +winFindWindow (pointer value, XID id, pointer cdata); + +static +void winInitMultiWindowClass(void) +{ + static wATOM atomXWinClass=0; + WNDCLASSEX wcx; + + if (atomXWinClass==0) + { + /* Setup our window class */ + wcx.cbSize=sizeof(WNDCLASSEX); + wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0); + wcx.lpfnWndProc = winTopLevelWindowProc; + wcx.cbClsExtra = 0; + wcx.cbWndExtra = 0; + wcx.hInstance = g_hInstance; + wcx.hIcon = g_hIconX; + wcx.hCursor = 0; + wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wcx.lpszMenuName = NULL; + wcx.lpszClassName = WINDOW_CLASS_X; + wcx.hIconSm = g_hSmallIconX; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X); +#endif + + atomXWinClass = RegisterClassEx (&wcx); + } +} + +/* + * CreateWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(CreateWindow); + fResult = (*pScreen->CreateWindow) (pWin); + WIN_WRAP(CreateWindow, winCreateWindowMultiWindow); + + /* 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; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(DestroyWindow); + fResult = (*pScreen->DestroyWindow)(pWin); + WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow); + + /* 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 + * + * This function adjusts the position and size of Windows window + * with respect to the underlying X window. This is the inverse + * of winAdjustXWindow, which adjusts X window to Windows window. + */ + +Bool +winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) +{ + Bool fResult = TRUE; + int iX, iY, iWidth, iHeight; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + HWND hWnd = pWinPriv->hWnd; + RECT rcNew; + RECT rcOld; +#if CYGMULTIWINDOW_DEBUG + RECT rcClient; + RECT *lpRc; +#endif + DWORD dwExStyle; + DWORD dwStyle; + +#if CYGMULTIWINDOW_DEBUG + winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(PositionWindow); + fResult = (*pScreen->PositionWindow)(pWin, x, y); + WIN_WRAP(PositionWindow, winPositionWindowMultiWindow); + +#if CYGWINDOWING_DEBUG + ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", + x, y); +#endif + + /* Bail out if the Windows window handle is bad */ + if (!hWnd) + { +#if CYGWINDOWING_DEBUG + ErrorF ("\timmediately return since hWnd is NULL\n"); +#endif + return fResult; + } + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* 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 + +#if CYGWINDOWING_DEBUG + ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#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; + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(ChangeWindowAttributes); + fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); + WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow); + + /* + * 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; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(UnrealizeWindow); + fResult = (*pScreen->UnrealizeWindow)(pWin); + WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow); + + /* 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; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(RealizeWindow); + fResult = (*pScreen->RealizeWindow)(pWin); + WIN_WRAP(RealizeWindow, winMapWindowMultiWindow); + + /* Flag that this window has not been destroyed */ + pWinPriv->fXKilled = FALSE; + + /* Refresh/redisplay the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); + + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); + + return fResult; +} + + +/* + * ReparentWindow - See Porting Layer Definition - p. 42 + */ + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(ReparentWindow); + if (pScreen->ReparentWindow) + (*pScreen->ReparentWindow)(pWin, pPriorParent); + WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow); + + /* 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) +{ +#if 0 + WindowPtr pPrevWin; + UINT uFlags; + HWND hInsertAfter; + HWND hWnd = NULL; +#endif + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG + winTrace ("winRestackMultiWindow - %08x\n", pWin); +#endif + + WIN_UNWRAP(RestackWindow); + if (pScreen->RestackWindow) + (*pScreen->RestackWindow)(pWin, pOldNextSib); + WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); + +#if 1 + /* + * Calling winReorderWindowsMultiWindow here means our window manager + * (i.e. Windows Explorer) has initiative to determine Z order. + */ + if (pWin->nextSib != pOldNextSib) + winReorderWindowsMultiWindow (); +#else + /* 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; + + hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV); + + do + { + if (GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) + { + uFlags |= SWP_NOZORDER; + } + break; + } + hWnd = GetNextWindow (hWnd, GW_HWNDPREV); + } + while (hWnd); + } + 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); +#endif +} + + +/* + * winCreateWindowsWindow - Create a Windows window associated with an X window + */ + +void +winCreateWindowsWindow (WindowPtr pWin) +{ + int iX, iY; + int iWidth; + int iHeight; + HWND hWnd; + HWND hFore = NULL; + winWindowPriv(pWin); + HICON hIcon; + HICON hIconSmall; + winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; + WinXSizeHints hints; + WindowPtr pDaddy; + + winInitMultiWindowClass(); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); +#endif + + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* If it's an InputOutput window, and so is going to end up being made visible, + make sure the window actually ends up somewhere where it will be visible */ + if (pWin->drawable.class != InputOnly) + { + if ((iX < GetSystemMetrics (SM_XVIRTUALSCREEN)) || (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))) + iX = CW_USEDEFAULT; + + if ((iY < GetSystemMetrics (SM_YVIRTUALSCREEN)) || (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))) + iY = CW_USEDEFAULT; + } + + if (winMultiWindowGetTransientFor (pWin, &pDaddy)) + { + if (pDaddy) + { + hFore = GetForegroundWindow(); + if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL; + } + } + else + { + /* Default positions if none specified */ + if (!winMultiWindowGetWMNormalHints(pWin, &hints)) + hints.flags = 0; + if (!(hints.flags & (USPosition|PPosition)) && + !pWin->overrideRedirect) + { + iX = CW_USEDEFAULT; + iY = CW_USEDEFAULT; + } + } + + /* Create the window */ + /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */ + /* CW_USEDEFAULT, change back to popup after creation */ + hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + WINDOW_CLASS_X, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + hFore, /* Null or Parent window if transient*/ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pWin); /* ScreenPrivates */ + if (hWnd == NULL) + { + ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + } + pWinPriv->hWnd = hWnd; + + /* Set application or .XWinrc defined Icons */ + winSelectIcons(pWin, &hIcon, &hIconSmall); + if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); + if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); + + /* Change style back to popup, already placed... */ + SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + SetWindowPos (hWnd, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + /* Make sure it gets the proper system menu for a WS_POPUP, too */ + GetSystemMenu (hWnd, TRUE); + + /* Cause any .XWinrc menus to be added in main WNDPROC */ + PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); + + SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); + + /* Flag that this Windows window handles its own activation */ + SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); + + /* Call engine-specific create window procedure */ + (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin); +} + + +Bool winInDestroyWindowsWindow = FALSE; +/* + * winDestroyWindowsWindow - Destroy a Windows window associated + * with an X window + */ +static void +winDestroyWindowsWindow (WindowPtr pWin) +{ + MSG msg; + winWindowPriv(pWin); + BOOL oldstate = winInDestroyWindowsWindow; + HICON hIcon; + HICON hIconSm; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow\n"); +#endif + + /* Bail out if the Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + winInDestroyWindowsWindow = TRUE; + + /* Store the info we need to destroy after this window is gone */ + hIcon = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0); + + SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL); + + /* Destroy the Windows window */ + DestroyWindow (pWinPriv->hWnd); + + /* Null our handle to the Window so referencing it will cause an error */ + pWinPriv->hWnd = NULL; + + /* Destroy any icons we created for this window */ + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + { + DispatchMessage (&msg); + } + } + + winInDestroyWindowsWindow = oldstate; + +#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 */ + if (pWin->drawable.class != InputOnly) + 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 +} + + +/* + * winGetWindowID - + */ + +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; +} + + +/* + * winFindWindow - + */ + +static void +winFindWindow (pointer value, XID id, pointer cdata) +{ + WindowIDPairPtr wi = (WindowIDPairPtr)cdata; + + if (value == wi->value) + { + wi->id = id; + } +} + + +/* + * winReorderWindowsMultiWindow - + */ + +void +winReorderWindowsMultiWindow (void) +{ + HWND hwnd = NULL; + WindowPtr pWin = NULL; + WindowPtr pWinSib = NULL; + XID vlist[2]; + static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + +#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG + winTrace ("winReorderWindowsMultiWindow\n"); +#endif + + if (fRestacking) + { + /* It is a recusive call so immediately exit */ +#if CYGWINDOWING_DEBUG + ErrorF ("winReorderWindowsMultiWindow - " + "exit because fRestacking == TRUE\n"); +#endif + return; + } + fRestacking = TRUE; + + /* Loop through top level Window windows, descending in Z order */ + for ( hwnd = GetTopWindow (NULL); + hwnd; + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) ) + { + /* Don't take care of other Cygwin/X process's windows */ + GetWindowThreadProcessId (hwnd, &dwWindowProcessID); + + if ( GetProp (hwnd, WIN_WINDOW_PROP) + && (dwWindowProcessID == dwCurrentProcessID) + && !IsIconic (hwnd) ) /* ignore minimized windows */ + { + pWinSib = pWin; + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + if (!pWinSib) + { /* 1st window - raise to the top */ + vlist[0] = Above; + + ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); + } + else + { /* 2nd or deeper windows - just below the previous one */ + vlist[0] = winGetWindowID (pWinSib); + vlist[1] = Below; + + ConfigureWindow (pWin, CWSibling | CWStackMode, + vlist, wClient(pWin)); + } + } + } + + fRestacking = FALSE; +} + + +/* + * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE + */ + +void +winMinimizeWindow (Window id) +{ + WindowPtr pWin; + winPrivWinPtr pWinPriv; +#ifdef XWIN_MULTIWINDOWEXTWM + win32RootlessWindowPtr pRLWinPriv; +#endif + HWND hWnd; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + +#if CYGWINDOWING_DEBUG + ErrorF ("winMinimizeWindow\n"); +#endif + + dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); + if (!pWin) + { + ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__); + return; + } + + pScreen = pWin->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#ifdef XWIN_MULTIWINDOWEXTWM + if (pScreenPriv && pScreenInfo->fInternalWM) + { + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + hWnd = pRLWinPriv->hWnd; + } + else +#else + if (pScreenPriv) +#endif + { + pWinPriv = winGetWindowPriv (pWin); + hWnd = pWinPriv->hWnd; + } + + ShowWindow (hWnd, SW_MINIMIZE); +} + + +/* + * CopyWindow - See Porting Layer Definition - p. 39 + */ +void +winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, + RegionPtr oldRegion) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("CopyWindowMultiWindow\n"); +#endif + WIN_UNWRAP(CopyWindow); + (*pScreen->CopyWindow)(pWin, oldpt, oldRegion); + WIN_WRAP(CopyWindow, winCopyWindowMultiWindow); +} + + +/* + * MoveWindow - See Porting Layer Definition - p. 42 + */ +void +winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, + WindowPtr pSib, VTKind kind) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y); +#endif + + WIN_UNWRAP(MoveWindow); + (*pScreen->MoveWindow)(pWin, x, y, pSib, kind); + WIN_WRAP(MoveWindow, winMoveWindowMultiWindow); +} + + +/* + * ResizeWindow - See Porting Layer Definition - p. 42 + */ +void +winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h); +#endif + WIN_UNWRAP(ResizeWindow); + (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); + WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow); +} + + +/* + * winAdjustXWindow + * + * Move and resize X window with respect to corresponding Windows window. + * This is called from WM_MOVE/WM_SIZE handlers when the user performs + * any windowing operation (move, resize, minimize, maximize, restore). + * + * The functionality is the inverse of winPositionWindowMultiWindow, which + * adjusts Windows window with respect to X window. + */ +int +winAdjustXWindow (WindowPtr pWin, HWND hwnd) +{ + RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */ + RECT rcWin; /* The source: WindowRect from hwnd */ + DrawablePtr pDraw; + XID vlist[4]; + LONG dX, dY, dW, dH, x, y; + DWORD dwStyle, dwExStyle; + +#define WIDTH(rc) (rc.right - rc.left) +#define HEIGHT(rc) (rc.bottom - rc.top) + +#if CYGWINDOWING_DEBUG + ErrorF ("winAdjustXWindow\n"); +#endif + + if (IsIconic (hwnd)) + { +#if CYGWINDOWING_DEBUG + ErrorF ("\timmediately return because the window is iconized\n"); +#endif + /* + * If the Windows window is minimized, its WindowRect has + * meaningless values so we don't adjust X window to it. + */ + vlist[0] = 0; + vlist[1] = 0; + return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + } + + pDraw = &pWin->drawable; + + /* Calculate the window rect from the drawable */ + x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN); + y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN); + SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n", + rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, + rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); +#endif + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle); +#endif + AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle); + + /* The source of adjust */ + GetWindowRect (hwnd, &rcWin); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", + rcWin.left, rcWin.top, rcWin.right, rcWin.bottom, + rcWin.right - rcWin.left, rcWin.bottom - rcWin.top); + winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n", + rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, + rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); +#endif + + if (EqualRect (&rcDraw, &rcWin)) { + /* Bail if no adjust is needed */ +#if CYGWINDOWING_DEBUG + ErrorF ("\treturn because already adjusted\n"); +#endif + return 0; + } + + /* Calculate delta values */ + dX = rcWin.left - rcDraw.left; + dY = rcWin.top - rcDraw.top; + dW = WIDTH(rcWin) - WIDTH(rcDraw); + dH = HEIGHT(rcWin) - HEIGHT(rcDraw); + + /* + * Adjust. + * We may only need to move (vlist[0] and [1]), or only resize + * ([2] and [3]) but currently we set all the parameters and leave + * the decision to ConfigureWindow. The reason is code simplicity. + */ + vlist[0] = pDraw->x + dX - wBorderWidth(pWin); + vlist[1] = pDraw->y + dY - wBorderWidth(pWin); + vlist[2] = pDraw->width + dW; + vlist[3] = pDraw->height + dH; +#if CYGWINDOWING_DEBUG + ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1], + vlist[2], vlist[3]); +#endif + return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, + vlist, wClient(pWin)); + +#undef WIDTH +#undef HEIGHT +} + diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c index 28685a729..67a58a076 100644 --- a/xorg-server/hw/xwin/winmultiwindowwm.c +++ b/xorg-server/hw/xwin/winmultiwindowwm.c @@ -1,1745 +1,1787 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2009
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice 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
- * Colin Harrison
- */
-
-/* X headers */
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#ifdef __CYGWIN__
-#include <sys/select.h>
-#endif
-#include <fcntl.h>
-#include <setjmp.h>
-#define HANDLE void *
-#include <pthread.h>
-#undef HANDLE
-#include <X11/X.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xlocale.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
-#include <X11/Xwindows.h>
-
-/* Local headers */
-#include "objbase.h"
-#include "ddraw.h"
-#include "winwindow.h"
-#include "winprefs.h"
-#include "window.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-#include <X11/extensions/windowswmstr.h>
-#else
-/* We need the native HWND atom for intWM, so for consistency use the
- same name as extWM would if we were building with enabled... */
-#define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND"
-#endif
-
-extern void winDebug(const char *format, ...);
-extern void winReshapeMultiWindow(WindowPtr pWin);
-extern void winUpdateRgnMultiWindow(WindowPtr pWin);
-
-#ifndef CYGDEBUG
-#define CYGDEBUG NO
-#endif
-
-/*
- * Constant defines
- */
-
-#define WIN_CONNECT_RETRIES 5
-#define WIN_CONNECT_DELAY 5
-#ifdef HAS_DEVWINDOWS
-# define WIN_MSG_QUEUE_FNAME "/dev/windows"
-#endif
-#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;
- int nQueueSize;
-} WMMsgQueueRec, *WMMsgQueuePtr;
-
-typedef struct _WMInfo {
- Display *pDisplay;
- WMMsgQueueRec wmMsgQueue;
- Atom atmWmProtos;
- Atom atmWmDelete;
- Atom atmPrivMap;
- Bool fAllowOtherWM;
-} WMInfoRec, *WMInfoPtr;
-
-typedef struct _WMProcArgRec {
- DWORD dwScreen;
- WMInfoPtr pWMInfo;
- pthread_mutex_t *ppmServerStarted;
-} WMProcArgRec, *WMProcArgPtr;
-
-typedef struct _XMsgProcArgRec {
- Display *pDisplay;
- DWORD dwScreen;
- WMInfoPtr pWMInfo;
- pthread_mutex_t *ppmServerStarted;
- HWND hwndScreen;
-} XMsgProcArgRec, *XMsgProcArgPtr;
-
-
-/*
- * References to external symbols
- */
-
-extern char *display;
-extern void ErrorF (const char* /*f*/, ...);
-
-/*
- * Prototypes for local functions
- */
-
-static void
-PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode);
-
-static WMMsgNodePtr
-PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo);
-
-static Bool
-InitQueue (WMMsgQueuePtr pQueue);
-
-static void
-GetWindowName (Display * pDpy, Window iWin, wchar_t **ppName);
-
-static int
-SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData);
-
-static void
-UpdateName (WMInfoPtr pWMInfo, Window iWindow);
-
-static void*
-winMultiWindowWMProc (void* pArg);
-
-static int
-winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static int
-winMultiWindowWMIOErrorHandler (Display *pDisplay);
-
-static void *
-winMultiWindowXMsgProc (void *pArg);
-
-static int
-winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static int
-winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay);
-
-static int
-winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static void
-winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg);
-
-#if 0
-static void
-PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction);
-#endif
-
-static Bool
-CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM);
-
-static void
-winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle);
-
-void
-winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
-
-/*
- * Local globals
- */
-
-static jmp_buf g_jmpWMEntry;
-static jmp_buf g_jmpXMsgProcEntry;
-static Bool g_shutdown = FALSE;
-static Bool redirectError = FALSE;
-static Bool g_fAnotherWMRunning = FALSE;
-
-/*
- * 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_SIZE:
- ErrorF ("\tWM_WM_SIZE\n");
- break;
- case WM_WM_RAISE:
- ErrorF ("\tWM_WM_RAISE\n");
- break;
- case WM_WM_LOWER:
- ErrorF ("\tWM_WM_LOWER\n");
- break;
- case WM_WM_MAP:
- ErrorF ("\tWM_WM_MAP\n");
- break;
- case WM_WM_MAP2:
- ErrorF ("\tWM_WM_MAP2\n");
- break;
- case WM_WM_MAP3:
- ErrorF ("\tWM_WM_MAP3\n");
- break;
- case WM_WM_UNMAP:
- ErrorF ("\tWM_WM_UNMAP\n");
- break;
- case WM_WM_KILL:
- ErrorF ("\tWM_WM_KILL\n");
- break;
- case WM_WM_ACTIVATE:
- ErrorF ("\tWM_WM_ACTIVATE\n");
- break;
- default:
- ErrorF ("\tUnknown Message.\n");
- break;
- }
-#endif
-
- /* Increase the count of elements in the queue by one */
- ++(pQueue->nQueueSize);
-
- /* Release the queue mutex */
- pthread_mutex_unlock (&pQueue->pmMutex);
-
- /* Signal that the queue is not empty */
- pthread_cond_signal (&pQueue->pcNotEmpty);
-}
-
-
-#if CYGMULTIWINDOW_DEBUG
-/*
- * 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 - Pop a message from the queue
- */
-
-static WMMsgNodePtr
-PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
-{
- 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 */
- --(pQueue->nQueueSize);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("Queue Size %d %d\n", pQueue->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 */
- pQueue->nQueueSize = 0;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->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 - Retrieve the title of an X Window
- */
-
-static void
-GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName)
-{
- int nResult, nNum;
- char **ppList;
- char *pszReturnData;
- int iLen, i;
- 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)
- {
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("GetWindowName - XGetWMName failed. No name.\n");
-#endif
- return;
- }
-
- if (Xutf8TextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList)
- {
- iLen = 0;
- for (i = 0; i < nNum; i++) iLen += strlen(ppList[i]);
- pszReturnData = (char *) malloc (iLen + 1);
- pszReturnData[0] = '\0';
- for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]);
- if (ppList) XFreeStringList (ppList);
- }
- else
- {
- pszReturnData = (char *) malloc (1);
- pszReturnData[0] = '\0';
- }
- iLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0);
- *ppName = (wchar_t*)malloc(sizeof(wchar_t)*(iLen + 1));
- MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, *ppName, iLen);
- XFree (xtpName.value);
- free (pszReturnData);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("GetWindowName - Returning\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);
-}
-
-
-/*
- * Updates the name of a HWND according to its X WM_NAME property
- */
-
-static void
-UpdateName (WMInfoPtr pWMInfo, Window iWindow)
-{
- wchar_t *pszName;
- Atom atmType;
- int fmtRet;
- unsigned long items, remain;
- HWND *retHwnd, hWnd;
- XWindowAttributes attr;
-
- hWnd = 0;
-
- /* See if we can get the cached HWND for this window... */
- if (XGetWindowProperty (pWMInfo->pDisplay,
- iWindow,
- pWMInfo->atmPrivMap,
- 0,
- 1,
- False,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- &atmType,
- &fmtRet,
- &items,
- &remain,
- (unsigned char **) &retHwnd) == Success)
- {
- if (retHwnd)
- {
- hWnd = *retHwnd;
- XFree (retHwnd);
- }
- }
-
- /* Some sanity checks */
- if (!hWnd) return;
- if (!IsWindow (hWnd)) return;
-
- /* Set the Windows window name */
- GetWindowName (pWMInfo->pDisplay, iWindow, &pszName);
- if (pszName)
- {
- /* Get the window attributes */
- XGetWindowAttributes (pWMInfo->pDisplay,
- iWindow,
- &attr);
- if (!attr.override_redirect)
- {
- SetWindowTextW (hWnd, pszName);
- winUpdateIcon (iWindow);
- }
-
- free (pszName);
- }
-}
-
-
-#if 0
-/*
- * Fix up any differences between the X11 and Win32 window stacks
- * starting at the window passed in
- */
-static void
-PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction)
-{
- Atom atmType;
- int fmtRet;
- unsigned long items, remain;
- HWND hWnd, *retHwnd;
- DWORD myWinProcID, winProcID;
- Window xWindow;
- WINDOWPLACEMENT wndPlace;
-
- hWnd = NULL;
- /* See if we can get the cached HWND for this window... */
- if (XGetWindowProperty (pWMInfo->pDisplay,
- iWindow,
- pWMInfo->atmPrivMap,
- 0,
- 1,
- False,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- &atmType,
- &fmtRet,
- &items,
- &remain,
- (unsigned char **) &retHwnd) == Success)
- {
- if (retHwnd)
- {
- hWnd = *retHwnd;
- XFree (retHwnd);
- }
- }
-
- if (!hWnd) return;
-
- GetWindowThreadProcessId (hWnd, &myWinProcID);
- hWnd = GetNextWindow (hWnd, direction);
-
- while (hWnd) {
- GetWindowThreadProcessId (hWnd, &winProcID);
- if (winProcID == myWinProcID)
- {
- wndPlace.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement (hWnd, &wndPlace);
- if ( !(wndPlace.showCmd==SW_HIDE ||
- wndPlace.showCmd==SW_MINIMIZE) )
- {
- xWindow = (Window)GetProp (hWnd, WIN_WID_PROP);
- if (xWindow)
- {
- if (direction==GW_HWNDPREV)
- XRaiseWindow (pWMInfo->pDisplay, xWindow);
- else
- XLowerWindow (pWMInfo->pDisplay, xWindow);
- }
- }
- }
- hWnd = GetNextWindow(hWnd, direction);
- }
-}
-#endif /* PreserveWin32Stack */
-
-
-/*
- * 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 explicitly break out */
- for (;;)
- {
- WMMsgNodePtr pNode;
-
- if(g_fAnotherWMRunning)/* Another Window manager exists. */
- {
- Sleep (1000);
- continue;
- }
-
- /* Pop a message off of our queue */
- pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo);
- if (pNode == NULL)
- {
- /* Bail if PopMessage returns without a message */
- /* NOTE: Remember that PopMessage is a blocking function. */
- ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\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);
-#if 0
- PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV);
-#endif
- 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
- /* Put a note as to the HWND associated with this Window */
- XChangeProperty (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmPrivMap,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- 32,
- PropModeReplace,
- (unsigned char *) &(pNode->msg.hwndWindow),
- 1);
- UpdateName (pWMInfo, pNode->msg.iWindow);
- winUpdateIcon (pNode->msg.iWindow);
- break;
-
- case WM_WM_MAP2:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_MAP2\n");
-#endif
- XChangeProperty (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmPrivMap,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- 32,
- PropModeReplace,
- (unsigned char *) &(pNode->msg.hwndWindow),
- 1);
- break;
-
- case WM_WM_MAP3:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_MAP3\n");
-#endif
- /* Put a note as to the HWND associated with this Window */
- XChangeProperty (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmPrivMap,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- 32,
- PropModeReplace,
- (unsigned char *) &(pNode->msg.hwndWindow),
- 1);
- UpdateName (pWMInfo, pNode->msg.iWindow);
- winUpdateIcon (pNode->msg.iWindow);
- {
- HWND zstyle = HWND_NOTOPMOST;
- winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle);
- winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle);
- }
- 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_NAME_EVENT:
- UpdateName (pWMInfo, pNode->msg.iWindow);
- break;
-
- case WM_WM_HINTS_EVENT:
- winUpdateIcon (pNode->msg.iWindow);
- break;
-
- case WM_WM_CHANGE_STATE:
- /* Minimize the window in Windows */
- winMinimizeWindow (pNode->msg.iWindow);
- break;
-
- default:
- ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\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
- return NULL;
-}
-
-
-/*
- * X message procedure
- */
-
-static void *
-winMultiWindowXMsgProc (void *pArg)
-{
- winWMMessageRec msg;
- XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg;
- char pszDisplay[512];
- int iRetries;
- XEvent event;
- Atom atmWmName;
- Atom atmWmHints;
- Atom atmWmChange;
- int iReturn;
- XIconSize *xis;
-
- ErrorF ("winMultiWindowXMsgProc - Hello\n");
-
- /* Check that argument pointer is not invalid */
- if (pProcArg == NULL)
- {
- ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
-
- /* Grab the server started mutex - pause until we get it */
- iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
- if (iReturn != 0)
- {
- ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. "
- "Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
-
- ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads () == 0)
- {
- ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale () == False)
- {
- ErrorF ("winMultiWindowXMsgProc - Warning: locale not supported by X\n");
- }
-
- /* Release the server started mutex */
- pthread_mutex_unlock (pProcArg->ppmServerStarted);
-
- ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
-
- /* Set jump point for IO Error exits */
- iReturn = setjmp (g_jmpXMsgProcEntry);
-
- /* Check if we should continue operations */
- if (iReturn != WIN_JMP_ERROR_IO
- && iReturn != WIN_JMP_OKAY)
- {
- /* setjmp returned an unknown value, exit */
- ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
- else if (iReturn == WIN_JMP_ERROR_IO)
- {
- ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* Install our error handler */
- XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
- XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
-
- /* Setup the display connection string x */
- snprintf (pszDisplay,
- 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen);
-
- /* Print the display connection string */
- ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay);
-
- /* Use our generated cookie for authentication */
- winSetAuthorization();
-
- /* Initialize retry count */
- iRetries = 0;
-
- /* Open the X display */
- do
- {
- /* Try to open the display */
- pProcArg->pDisplay = XOpenDisplay (pszDisplay);
- if (pProcArg->pDisplay == NULL)
- {
- ErrorF ("winMultiWindowXMsgProc - Could not open display, try: %d, "
- "sleeping: %d\n",
- iRetries + 1, WIN_CONNECT_DELAY);
- ++iRetries;
- sleep (WIN_CONNECT_DELAY);
- continue;
- }
- else
- break;
- }
- while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
-
- /* Make sure that the display opened */
- if (pProcArg->pDisplay == NULL)
- {
- ErrorF ("winMultiWindowXMsgProc - Failed opening the display. "
- "Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and "
- "successfully opened the display.\n");
-
- /* Check if another window manager is already running */
- g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, pProcArg->pWMInfo->fAllowOtherWM);
-
- if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM)
- {
- ErrorF ("winMultiWindowXMsgProc - "
- "another window manager is running. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* Set up the supported icon sizes */
- xis = XAllocIconSize ();
- if (xis)
- {
- xis->min_width = xis->min_height = 16;
- xis->max_width = xis->max_height = 48;
- xis->width_inc = xis->height_inc = 16;
- XSetIconSizes (pProcArg->pDisplay,
- RootWindow (pProcArg->pDisplay, pProcArg->dwScreen),
- xis,
- 1);
- XFree (xis);
- }
-
- atmWmName = XInternAtom (pProcArg->pDisplay,
- "WM_NAME",
- False);
- atmWmHints = XInternAtom (pProcArg->pDisplay,
- "WM_HINTS",
- False);
- atmWmChange = XInternAtom (pProcArg->pDisplay,
- "WM_CHANGE_STATE",
- False);
-
- /*
- iiimxcf had a bug until 2009-04-27, assuming that the
- WM_STATE atom exists, causing clients to fail with
- a BadAtom X error if it doesn't.
-
- Since this is on in the default Solaris 10 install,
- workaround this by making sure it does exist...
- */
- XInternAtom(pProcArg->pDisplay, "WM_STATE", 0);
-
- /* Loop until we explicitly break out */
- while (1)
- {
- if (g_shutdown)
- break;
-
- if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay))
- {
- if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, TRUE))
- {
- if (!g_fAnotherWMRunning)
- {
- g_fAnotherWMRunning = TRUE;
- SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0);
- }
- }
- else
- {
- if (g_fAnotherWMRunning)
- {
- g_fAnotherWMRunning = FALSE;
- SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0);
- }
- }
- Sleep (500);
- continue;
- }
-
- /* Fetch next event */
- XNextEvent (pProcArg->pDisplay, &event);
-
- /* Branch on event type */
- if (event.type == CreateNotify)
- {
- XWindowAttributes attr;
-
- XSelectInput (pProcArg->pDisplay,
- event.xcreatewindow.window,
- PropertyChangeMask);
-
- /* Get the window attributes */
- XGetWindowAttributes (pProcArg->pDisplay,
- event.xcreatewindow.window,
- &attr);
-
- if (!attr.override_redirect)
- XSetWindowBorderWidth(pProcArg->pDisplay,
- event.xcreatewindow.window,
- 0);
- }
- else if (event.type == MapNotify)
- {
- /* Fake a reparentNotify event as SWT/Motif expects a
- Window Manager to reparent a top-level window when
- it is mapped and waits until they do.
-
- We don't actually need to reparent, as the frame is
- a native window, not an X window
-
- We do this on MapNotify, not MapRequest like a real
- Window Manager would, so we don't have do get involved
- in actually mapping the window via it's (non-existent)
- parent...
-
- See sourceware bugzilla #9848
- */
-
- XWindowAttributes attr;
- Window root;
- Window parent;
- Window *children;
- unsigned int nchildren;
-
- if (XGetWindowAttributes(event.xmap.display,
- event.xmap.window,
- &attr) &&
- XQueryTree(event.xmap.display,
- event.xmap.window,
- &root, &parent, &children, &nchildren))
- {
- if (children) XFree(children);
-
- /*
- It's a top-level window if the parent window is a root window
- Only non-override_redirect windows can get reparented
- */
- if ((attr.root == parent) && !event.xmap.override_redirect)
- {
- XEvent event_send;
-
- event_send.type = ReparentNotify;
- event_send.xreparent.event = event.xmap.window;
- event_send.xreparent.window = event.xmap.window;
- event_send.xreparent.parent = parent;
- event_send.xreparent.x = attr.x;
- event_send.xreparent.y = attr.y;
-
- XSendEvent(event.xmap.display,
- event.xmap.window,
- True, StructureNotifyMask,
- &event_send);
- }
- }
- }
- else if (event.type == PropertyNotify
- && event.xproperty.atom == atmWmName)
- {
- memset (&msg, 0, sizeof (msg));
-
- msg.msg = WM_WM_NAME_EVENT;
- msg.iWindow = event.xproperty.window;
-
- /* Other fields ignored */
- winSendMessageToWM (pProcArg->pWMInfo, &msg);
- }
- else if (event.type == PropertyNotify
- && event.xproperty.atom == atmWmHints)
- {
- memset (&msg, 0, sizeof (msg));
-
- msg.msg = WM_WM_HINTS_EVENT;
- msg.iWindow = event.xproperty.window;
-
- /* Other fields ignored */
- winSendMessageToWM (pProcArg->pWMInfo, &msg);
- }
- else if (event.type == ClientMessage
- && event.xclient.message_type == atmWmChange
- && event.xclient.data.l[0] == IconicState)
- {
- ErrorF ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
-
- memset (&msg, 0, sizeof (msg));
-
- msg.msg = WM_WM_CHANGE_STATE;
- msg.iWindow = event.xclient.window;
-
- winSendMessageToWM (pProcArg->pWMInfo, &msg);
- }
- }
-
- XCloseDisplay (pProcArg->pDisplay);
- pthread_exit (NULL);
- return NULL;
-}
-
-
-/*
- * 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_t *ptXMsgProc,
- pthread_mutex_t *ppmServerStarted,
- int dwScreen,
- HWND hwndScreen,
- BOOL allowOtherWM)
-{
- WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec));
- WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec));
- XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec));
-
- /* Bail if the input parameters are bad */
- if (pArg == NULL || pWMInfo == NULL)
- {
- ErrorF ("winInitWM - malloc failed.\n");
- return FALSE;
- }
-
- /* Zero the allocated memory */
- ZeroMemory (pArg, sizeof (WMProcArgRec));
- ZeroMemory (pWMInfo, sizeof (WMInfoRec));
- ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec));
-
- /* Set a return pointer to the Window Manager info structure */
- *ppWMInfo = pWMInfo;
- pWMInfo->fAllowOtherWM = allowOtherWM;
-
- /* 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 for Window Manager.\n");
- return FALSE;
- }
-
- /* Spawn the XNextEvent thread, will send messages to WM */
- pXMsgArg->dwScreen = dwScreen;
- pXMsgArg->pWMInfo = pWMInfo;
- pXMsgArg->ppmServerStarted = ppmServerStarted;
- pXMsgArg->hwndScreen = hwndScreen;
- if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg))
- {
- /* Bail if thread creation failed */
- ErrorF ("winInitWM - pthread_create failed on XMSG.\n");
- return FALSE;
- }
-
-#if CYGDEBUG || YES
- winDebug ("winInitWM - Returning.\n");
-#endif
-
- return TRUE;
-}
-
-
-/*
- * Window manager thread - setup
- */
-
-static void
-winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
-{
- int iRetries = 0;
- char pszDisplay[512];
- int iReturn;
-
- ErrorF ("winInitMultiWindowWM - Hello\n");
-
- /* Check that argument pointer is not invalid */
- if (pProcArg == NULL)
- {
- ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\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. "
- "Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
-
- ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads () == 0)
- {
- ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale () == False)
- {
- ErrorF ("winInitMultiWindowWM - Warning: Locale not supported by X.\n");
- }
-
- /* Release the server started mutex */
- pthread_mutex_unlock (pProcArg->ppmServerStarted);
-
- ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
-
- /* Set jump point for IO Error exits */
- iReturn = setjmp (g_jmpWMEntry);
-
- /* 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 - Caught IO Error. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* Install our error handler */
- XSetErrorHandler (winMultiWindowWMErrorHandler);
- XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
-
- /* Setup the display connection string x */
- snprintf (pszDisplay,
- 512,
- "127.0.0.1:%s.%d",
- display,
- (int) pProcArg->dwScreen);
-
- /* Print the display connection string */
- ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
-
- /* Use our generated cookie for authentication */
- winSetAuthorization();
-
- /* 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",
- 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. "
- "Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and "
- "successfully opened the display.\n");
-
-
- /* Create some atoms */
- pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay,
- "WM_PROTOCOLS",
- False);
- pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay,
- "WM_DELETE_WINDOW",
- False);
-
- pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay,
- WINDOWSWM_NATIVE_HWND,
- False);
-
-
- if (1) {
- Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr);
- if (cursor)
- {
- XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor);
- XFreeCursor (pWMInfo->pDisplay, cursor);
- }
- }
-}
-
-
-/*
- * 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);
- }
-}
-
-
-/*
- * Window manager error handler
- */
-
-static int
-winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- char pszErrorMsg[100];
-
- if (pErr->request_code == X_ChangeWindowAttributes
- && pErr->error_code == BadAccess)
- {
- ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes "
- "BadAccess.\n");
- return 0;
- }
-
- XGetErrorText (pDisplay,
- pErr->error_code,
- pszErrorMsg,
- sizeof (pszErrorMsg));
- ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg);
-
- return 0;
-}
-
-
-/*
- * Window manager IO error handler
- */
-
-static int
-winMultiWindowWMIOErrorHandler (Display *pDisplay)
-{
- ErrorF ("winMultiWindowWMIOErrorHandler!\n\n");
-
- if (g_shutdown)
- pthread_exit(NULL);
-
- /* Restart at the main entry point */
- longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
-
- return 0;
-}
-
-
-/*
- * X message procedure error handler
- */
-
-static int
-winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- char pszErrorMsg[100];
-
- XGetErrorText (pDisplay,
- pErr->error_code,
- pszErrorMsg,
- sizeof (pszErrorMsg));
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg);
-#endif
-
- return 0;
-}
-
-
-/*
- * X message procedure IO error handler
- */
-
-static int
-winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay)
-{
- ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n");
-
- /* Restart at the main entry point */
- longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
-
- return 0;
-}
-
-
-/*
- * Catch RedirectError to detect other window manager running
- */
-
-static int
-winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- redirectError = TRUE;
- return 0;
-}
-
-
-/*
- * Check if another window manager is running
- */
-
-static Bool
-CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM)
-{
- /*
- Try to select the events which only one client at a time is allowed to select.
- If this causes an error, another window manager is already running...
- */
- redirectError = FALSE;
- XSetErrorHandler (winRedirectErrorHandler);
- XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
- ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask);
- XSync (pDisplay, 0);
- XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
-
- /*
- Side effect: select the events we are actually interested in...
-
- If other WMs are not allowed, also select one of the events which only one client
- at a time is allowed to select, so other window managers won't start...
- */
- XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
- SubstructureNotifyMask | ( !fAllowOtherWM ? ButtonPressMask : 0));
- XSync (pDisplay, 0);
- return redirectError;
-}
-
-/*
- * Notify the MWM thread we're exiting and not to reconnect
- */
-
-void
-winDeinitMultiWindowWM (void)
-{
- ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n");
- g_shutdown = TRUE;
-}
-
-/* Windows window styles */
-#define HINT_NOFRAME (1l<<0)
-#define HINT_BORDER (1L<<1)
-#define HINT_SIZEBOX (1l<<2)
-#define HINT_CAPTION (1l<<3)
-#define HINT_NOMAXIMIZE (1L<<4)
-/* These two are used on their own */
-#define HINT_MAX (1L<<0)
-#define HINT_MIN (1L<<1)
-
-static void
-winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle)
-{
- static Atom windowState, motif_wm_hints, windowType;
- static Atom hiddenState, fullscreenState, belowState, aboveState;
- static Atom dockWindow;
- static int generation;
- Atom type, *pAtom = NULL;
- int format;
- unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0;
- WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
- MwmHints *mwm_hint = NULL;
-
- if (!hWnd) return;
- if (!IsWindow (hWnd)) return;
-
- if (generation != serverGeneration) {
- generation = serverGeneration;
- windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False);
- motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False);
- windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False);
- hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False);
- fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False);
- belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
- aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
- dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
- }
-
- if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
- 1L, False, XA_ATOM, &type, &format,
- &nitems, &left, (unsigned char **)&pAtom) == Success)
- {
- if (pAtom && nitems == 1)
- {
- if (*pAtom == hiddenState) maxmin |= HINT_MIN;
- else if (*pAtom == fullscreenState) maxmin |= HINT_MAX;
- if (*pAtom == belowState) *zstyle = HWND_BOTTOM;
- else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST;
- }
- if (pAtom) XFree(pAtom);
- }
-
- nitems = left = 0;
- if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L,
- PropMwmHintsElements, False, motif_wm_hints, &type, &format,
- &nitems, &left, (unsigned char **)&mwm_hint) == Success)
- {
- if (mwm_hint && nitems == PropMwmHintsElements && (mwm_hint->flags & MwmHintsDecorations))
- {
- if (!mwm_hint->decorations) hint |= HINT_NOFRAME;
- else if (!(mwm_hint->decorations & MwmDecorAll))
- {
- if (mwm_hint->decorations & MwmDecorBorder) hint |= HINT_BORDER;
- if (mwm_hint->decorations & MwmDecorHandle) hint |= HINT_SIZEBOX;
- if (mwm_hint->decorations & MwmDecorTitle) hint |= HINT_CAPTION;
- }
- }
- if (mwm_hint) XFree(mwm_hint);
- }
-
- nitems = left = 0;
- pAtom = NULL;
- if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L,
- 1L, False, XA_ATOM, &type, &format,
- &nitems, &left, (unsigned char **)&pAtom) == Success)
- {
- if (pAtom && nitems == 1)
- {
- if (*pAtom == dockWindow)
- {
- hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */
- *zstyle = HWND_TOPMOST;
- }
- }
- if (pAtom) XFree(pAtom);
- }
-
- {
- XSizeHints *normal_hint = XAllocSizeHints();
- long supplied;
- if (normal_hint && (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) == Success))
- {
- if (normal_hint->flags & PMaxSize)
- {
- /* Not maximizable if a maximum size is specified */
- hint |= HINT_NOMAXIMIZE;
-
- if (normal_hint->flags & PMinSize)
- {
- /*
- If both minimum size and maximum size are specified and are the same,
- don't bother with a resizing frame
- */
- if ((normal_hint->min_width == normal_hint->max_width)
- && (normal_hint->min_height == normal_hint->max_height))
- hint = (hint & ~HINT_SIZEBOX);
- }
- }
- }
- XFree(normal_hint);
- }
-
- /* Override hint settings from above with settings from config file */
- style = winOverrideStyle((unsigned long)pWin);
- if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST;
- else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX;
- else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN;
- else if (style & STYLE_BOTTOM) *zstyle = HWND_BOTTOM;
-
- if (maxmin & HINT_MAX) SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
- else if (maxmin & HINT_MIN) SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
-
- if (style & STYLE_NOTITLE)
- hint = (hint & ~HINT_NOFRAME & ~HINT_BORDER & ~HINT_CAPTION) | HINT_SIZEBOX;
- else if (style & STYLE_OUTLINE)
- hint = (hint & ~HINT_NOFRAME & ~HINT_SIZEBOX & ~HINT_CAPTION) | HINT_BORDER;
- else if (style & STYLE_NOFRAME)
- hint = (hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) | HINT_NOFRAME;
-
- /* Now apply styles to window */
- style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
- if (!style) return;
-
- if (!hint) /* All on */
- style = style | WS_CAPTION | WS_SIZEBOX;
- else if (hint & HINT_NOFRAME) /* All off */
- style = style & ~WS_CAPTION & ~WS_SIZEBOX;
- else style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) |
- ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) |
- ((hint & HINT_CAPTION) ? WS_CAPTION : 0);
-
- if (hint & HINT_NOMAXIMIZE)
- style = style & ~WS_MAXIMIZEBOX;
-
- SetWindowLongPtr (hWnd, GWL_STYLE, style);
-}
-
-void
-winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle)
-{
- int iX, iY, iWidth, iHeight;
- int iDx, iDy;
- RECT rcNew;
- WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
- DrawablePtr pDraw = NULL;
-
- if (!pWin) return;
- pDraw = &pWin->drawable;
- if (!pDraw) return;
-
- /* Get the X and Y location of the X window */
- iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* Setup a rectangle with the X window position and size */
- SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-
-#if 0
- ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top,
- rcNew.right, rcNew.bottom);
-#endif
-
- AdjustWindowRectEx (&rcNew, GetWindowLongPtr (hWnd, GWL_STYLE), FALSE, WS_EX_APPWINDOW);
-
- /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */
- if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN))
- {
- iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left;
- rcNew.left += iDx;
- rcNew.right += iDx;
- }
-
- if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN))
- {
- iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top;
- rcNew.top += iDy;
- rcNew.bottom += iDy;
- }
-
-#if 0
- ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top,
- rcNew.right, rcNew.bottom);
-#endif
-
- /* Position the Windows window */
- SetWindowPos (hWnd, *zstyle, rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- 0);
-
- if (reshape)
- {
- winReshapeMultiWindow(pWin);
- winUpdateRgnMultiWindow(pWin);
- }
-}
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2009 + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice 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 + * Colin Harrison + */ + +/* X headers */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef __CYGWIN__ +#include <sys/select.h> +#endif +#include <fcntl.h> +#include <setjmp.h> +#define HANDLE void * +#include <pthread.h> +#undef HANDLE +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xlocale.h> +#include <X11/Xproto.h> +#include <X11/Xutil.h> +#include <X11/cursorfont.h> +#include <X11/Xwindows.h> + +/* Local headers */ +#include "objbase.h" +#include "ddraw.h" +#include "winwindow.h" +#include "winprefs.h" +#include "window.h" +#include "pixmapstr.h" +#include "windowstr.h" + +#ifdef XWIN_MULTIWINDOWEXTWM +#include <X11/extensions/windowswmstr.h> +#else +/* We need the native HWND atom for intWM, so for consistency use the + same name as extWM would if we were building with enabled... */ +#define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND" +#endif + +extern void winDebug(const char *format, ...); +extern void winReshapeMultiWindow(WindowPtr pWin); +extern void winUpdateRgnMultiWindow(WindowPtr pWin); + +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif + +/* + * Constant defines + */ + +#define WIN_CONNECT_RETRIES 5 +#define WIN_CONNECT_DELAY 5 +#ifdef HAS_DEVWINDOWS +# define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif +#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; + int nQueueSize; +} WMMsgQueueRec, *WMMsgQueuePtr; + +typedef struct _WMInfo { + Display *pDisplay; + WMMsgQueueRec wmMsgQueue; + Atom atmWmProtos; + Atom atmWmDelete; + Atom atmPrivMap; + Bool fAllowOtherWM; +} WMInfoRec, *WMInfoPtr; + +typedef struct _WMProcArgRec { + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; +} WMProcArgRec, *WMProcArgPtr; + +typedef struct _XMsgProcArgRec { + Display *pDisplay; + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; + HWND hwndScreen; +} XMsgProcArgRec, *XMsgProcArgPtr; + + +/* + * References to external symbols + */ + +extern char *display; +extern void ErrorF (const char* /*f*/, ...); + +/* + * Prototypes for local functions + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode); + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo); + +static Bool +InitQueue (WMMsgQueuePtr pQueue); + +static void +GetWindowName (Display * pDpy, Window iWin, wchar_t **ppName); + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData); + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow); + +static void* +winMultiWindowWMProc (void* pArg); + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay); + +static void * +winMultiWindowXMsgProc (void *pArg); + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay); + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); + +#if 0 +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction); +#endif + +static Bool +CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM); + +static void +winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle); + +void +winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); + +/* + * Local globals + */ + +static jmp_buf g_jmpWMEntry; +static jmp_buf g_jmpXMsgProcEntry; +static Bool g_shutdown = FALSE; +static Bool redirectError = FALSE; +static Bool g_fAnotherWMRunning = FALSE; + +/* + * 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_SIZE: + ErrorF ("\tWM_WM_SIZE\n"); + break; + case WM_WM_RAISE: + ErrorF ("\tWM_WM_RAISE\n"); + break; + case WM_WM_LOWER: + ErrorF ("\tWM_WM_LOWER\n"); + break; + case WM_WM_MAP: + ErrorF ("\tWM_WM_MAP\n"); + break; + case WM_WM_MAP2: + ErrorF ("\tWM_WM_MAP2\n"); + break; + case WM_WM_MAP3: + ErrorF ("\tWM_WM_MAP3\n"); + break; + case WM_WM_UNMAP: + ErrorF ("\tWM_WM_UNMAP\n"); + break; + case WM_WM_KILL: + ErrorF ("\tWM_WM_KILL\n"); + break; + case WM_WM_ACTIVATE: + ErrorF ("\tWM_WM_ACTIVATE\n"); + break; + default: + ErrorF ("\tUnknown Message.\n"); + break; + } +#endif + + /* Increase the count of elements in the queue by one */ + ++(pQueue->nQueueSize); + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + /* Signal that the queue is not empty */ + pthread_cond_signal (&pQueue->pcNotEmpty); +} + + +#if CYGMULTIWINDOW_DEBUG +/* + * 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 - Pop a message from the queue + */ + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) +{ + 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 */ + --(pQueue->nQueueSize); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("Queue Size %d %d\n", pQueue->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 */ + pQueue->nQueueSize = 0; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->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 - Retrieve the title of an X Window + */ + +static void +GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName) +{ + int nResult, nNum; + char **ppList; + char *pszReturnData; + int iLen, i; + 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) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - XGetWMName failed. No name.\n"); +#endif + return; + } + + if (Xutf8TextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList) + { + iLen = 0; + for (i = 0; i < nNum; i++) iLen += strlen(ppList[i]); + pszReturnData = (char *) malloc (iLen + 1); + pszReturnData[0] = '\0'; + for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]); + if (ppList) XFreeStringList (ppList); + } + else + { + pszReturnData = (char *) malloc (1); + pszReturnData[0] = '\0'; + } + iLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0); + *ppName = (wchar_t*)malloc(sizeof(wchar_t)*(iLen + 1)); + MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, *ppName, iLen); + XFree (xtpName.value); + free (pszReturnData); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - Returning\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); +} + + +/* + * Updates the name of a HWND according to its X WM_NAME property + */ + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow) +{ + wchar_t *pszName; + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND *retHwnd, hWnd; + XWindowAttributes attr; + + hWnd = 0; + + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + XA_INTEGER,//pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + /* Some sanity checks */ + if (!hWnd) return; + if (!IsWindow (hWnd)) return; + + /* Set the Windows window name */ + GetWindowName (pWMInfo->pDisplay, iWindow, &pszName); + if (pszName) + { + /* Get the window attributes */ + XGetWindowAttributes (pWMInfo->pDisplay, + iWindow, + &attr); + if (!attr.override_redirect) + { + SetWindowTextW (hWnd, pszName); + winUpdateIcon (iWindow); + } + + free (pszName); + } +} + + +#if 0 +/* + * Fix up any differences between the X11 and Win32 window stacks + * starting at the window passed in + */ +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction) +{ + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND hWnd, *retHwnd; + DWORD myWinProcID, winProcID; + Window xWindow; + WINDOWPLACEMENT wndPlace; + + hWnd = NULL; + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + XA_INTEGER,//pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + if (!hWnd) return; + + GetWindowThreadProcessId (hWnd, &myWinProcID); + hWnd = GetNextWindow (hWnd, direction); + + while (hWnd) { + GetWindowThreadProcessId (hWnd, &winProcID); + if (winProcID == myWinProcID) + { + wndPlace.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement (hWnd, &wndPlace); + if ( !(wndPlace.showCmd==SW_HIDE || + wndPlace.showCmd==SW_MINIMIZE) ) + { + xWindow = (Window)GetProp (hWnd, WIN_WID_PROP); + if (xWindow) + { + if (direction==GW_HWNDPREV) + XRaiseWindow (pWMInfo->pDisplay, xWindow); + else + XLowerWindow (pWMInfo->pDisplay, xWindow); + } + } + } + hWnd = GetNextWindow(hWnd, direction); + } +} +#endif /* PreserveWin32Stack */ + + +/* + * 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 explicitly break out */ + for (;;) + { + WMMsgNodePtr pNode; + + if(g_fAnotherWMRunning)/* Another Window manager exists. */ + { + Sleep (1000); + continue; + } + + /* Pop a message off of our queue */ + pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo); + if (pNode == NULL) + { + /* Bail if PopMessage returns without a message */ + /* NOTE: Remember that PopMessage is a blocking function. */ + ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\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); +#if 0 + PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); +#endif + 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 + /* Put a note as to the HWND associated with this Window */ + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + UpdateName (pWMInfo, pNode->msg.iWindow); + winUpdateIcon (pNode->msg.iWindow); + break; + + case WM_WM_MAP2: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP2\n"); +#endif + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + break; + + case WM_WM_MAP3: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP3\n"); +#endif + /* Put a note as to the HWND associated with this Window */ + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + UpdateName (pWMInfo, pNode->msg.iWindow); + winUpdateIcon (pNode->msg.iWindow); + { + HWND zstyle = HWND_NOTOPMOST; + winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle); + winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle); + } + 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_NAME_EVENT: + UpdateName (pWMInfo, pNode->msg.iWindow); + break; + + case WM_WM_HINTS_EVENT: + winUpdateIcon (pNode->msg.iWindow); + break; + + case WM_WM_CHANGE_STATE: + /* Minimize the window in Windows */ + winMinimizeWindow (pNode->msg.iWindow); + break; + + default: + ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\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 + return NULL; +} + + +/* + * X message procedure + */ + +static void * +winMultiWindowXMsgProc (void *pArg) +{ + winWMMessageRec msg; + XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg; + char pszDisplay[512]; + int iRetries; + XEvent event; + Atom atmWmName; + Atom atmWmHints; + Atom atmWmChange; + int iReturn; + XIconSize *xis; + + ErrorF ("winMultiWindowXMsgProc - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n"); + + /* Grab the server started mutex - pause until we get it */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. " + "Exiting.\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winMultiWindowXMsgProc - Warning: locale not supported by X\n"); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n"); + + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpXMsgProcEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler); + + /* Setup the display connection string x */ + snprintf (pszDisplay, + 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay); + + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* Initialize retry count */ + iRetries = 0; + + /* Open the X display */ + do + { + /* Try to open the display */ + pProcArg->pDisplay = XOpenDisplay (pszDisplay); + if (pProcArg->pDisplay == NULL) + { + ErrorF ("winMultiWindowXMsgProc - Could not open display, try: %d, " + "sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pProcArg->pDisplay == NULL) + { + ErrorF ("winMultiWindowXMsgProc - Failed opening the display. " + "Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Check if another window manager is already running */ + g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, pProcArg->pWMInfo->fAllowOtherWM); + + if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM) + { + ErrorF ("winMultiWindowXMsgProc - " + "another window manager is running. Exiting.\n"); + pthread_exit (NULL); + } + + /* Set up the supported icon sizes */ + xis = XAllocIconSize (); + if (xis) + { + xis->min_width = xis->min_height = 16; + xis->max_width = xis->max_height = 48; + xis->width_inc = xis->height_inc = 16; + XSetIconSizes (pProcArg->pDisplay, + RootWindow (pProcArg->pDisplay, pProcArg->dwScreen), + xis, + 1); + XFree (xis); + } + + atmWmName = XInternAtom (pProcArg->pDisplay, + "WM_NAME", + False); + atmWmHints = XInternAtom (pProcArg->pDisplay, + "WM_HINTS", + False); + atmWmChange = XInternAtom (pProcArg->pDisplay, + "WM_CHANGE_STATE", + False); + + /* + iiimxcf had a bug until 2009-04-27, assuming that the + WM_STATE atom exists, causing clients to fail with + a BadAtom X error if it doesn't. + + Since this is on in the default Solaris 10 install, + workaround this by making sure it does exist... + */ + XInternAtom(pProcArg->pDisplay, "WM_STATE", 0); + + /* Loop until we explicitly break out */ + while (1) + { + if (g_shutdown) + break; + + if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay)) + { + if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, TRUE)) + { + if (!g_fAnotherWMRunning) + { + g_fAnotherWMRunning = TRUE; + SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0); + } + } + else + { + if (g_fAnotherWMRunning) + { + g_fAnotherWMRunning = FALSE; + SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0); + } + } + Sleep (500); + continue; + } + + /* Fetch next event */ + XNextEvent (pProcArg->pDisplay, &event); + + /* Branch on event type */ + if (event.type == CreateNotify) + { + XWindowAttributes attr; + + XSelectInput (pProcArg->pDisplay, + event.xcreatewindow.window, + PropertyChangeMask); + + /* Get the window attributes */ + XGetWindowAttributes (pProcArg->pDisplay, + event.xcreatewindow.window, + &attr); + + if (!attr.override_redirect) + XSetWindowBorderWidth(pProcArg->pDisplay, + event.xcreatewindow.window, + 0); + } + else if (event.type == MapNotify) + { + /* Fake a reparentNotify event as SWT/Motif expects a + Window Manager to reparent a top-level window when + it is mapped and waits until they do. + + We don't actually need to reparent, as the frame is + a native window, not an X window + + We do this on MapNotify, not MapRequest like a real + Window Manager would, so we don't have do get involved + in actually mapping the window via it's (non-existent) + parent... + + See sourceware bugzilla #9848 + */ + + XWindowAttributes attr; + Window root; + Window parent; + Window *children; + unsigned int nchildren; + + if (XGetWindowAttributes(event.xmap.display, + event.xmap.window, + &attr) && + XQueryTree(event.xmap.display, + event.xmap.window, + &root, &parent, &children, &nchildren)) + { + if (children) XFree(children); + + /* + It's a top-level window if the parent window is a root window + Only non-override_redirect windows can get reparented + */ + if ((attr.root == parent) && !event.xmap.override_redirect) + { + XEvent event_send; + + event_send.type = ReparentNotify; + event_send.xreparent.event = event.xmap.window; + event_send.xreparent.window = event.xmap.window; + event_send.xreparent.parent = parent; + event_send.xreparent.x = attr.x; + event_send.xreparent.y = attr.y; + + XSendEvent(event.xmap.display, + event.xmap.window, + True, StructureNotifyMask, + &event_send); + } + } + } + else if (event.type == ConfigureNotify) + { + if (!event.xconfigure.send_event) + { + /* + Java applications using AWT on JRE 1.6.0 break with non-reparenting WMs AWT + doesn't explicitly know about (See sun bug #6434227) + + XDecoratedPeer.handleConfigureNotifyEvent() only processes non-synthetic + ConfigureNotify events to update window location if it's identified the + WM as a non-reparenting WM it knows about (compiz or lookingglass) + + Rather than tell all sorts of lies to get XWM to recognize us as one of + those, simply send a synthetic ConfigureNotify for every non-synthetic one + */ + XEvent event_send = event; + event_send.xconfigure.send_event = TRUE; + event_send.xconfigure.event = event.xconfigure.window; + XSendEvent(event.xconfigure.display, + event.xconfigure.window, + True, StructureNotifyMask, + &event_send); + } + } + else if (event.type == PropertyNotify + && event.xproperty.atom == atmWmName) + { + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_NAME_EVENT; + msg.iWindow = event.xproperty.window; + + /* Other fields ignored */ + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + else if (event.type == PropertyNotify + && event.xproperty.atom == atmWmHints) + { + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_HINTS_EVENT; + msg.iWindow = event.xproperty.window; + + /* Other fields ignored */ + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + else if (event.type == ClientMessage + && event.xclient.message_type == atmWmChange + && event.xclient.data.l[0] == IconicState) + { + ErrorF ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n"); + + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_CHANGE_STATE; + msg.iWindow = event.xclient.window; + + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + } + + XCloseDisplay (pProcArg->pDisplay); + pthread_exit (NULL); + return NULL; +} + + +/* + * 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_t *ptXMsgProc, + pthread_mutex_t *ppmServerStarted, + int dwScreen, + HWND hwndScreen, + BOOL allowOtherWM) +{ + WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec)); + WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec)); + XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec)); + + /* Bail if the input parameters are bad */ + if (pArg == NULL || pWMInfo == NULL) + { + ErrorF ("winInitWM - malloc failed.\n"); + return FALSE; + } + + /* Zero the allocated memory */ + ZeroMemory (pArg, sizeof (WMProcArgRec)); + ZeroMemory (pWMInfo, sizeof (WMInfoRec)); + ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec)); + + /* Set a return pointer to the Window Manager info structure */ + *ppWMInfo = pWMInfo; + pWMInfo->fAllowOtherWM = allowOtherWM; + + /* 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 for Window Manager.\n"); + return FALSE; + } + + /* Spawn the XNextEvent thread, will send messages to WM */ + pXMsgArg->dwScreen = dwScreen; + pXMsgArg->pWMInfo = pWMInfo; + pXMsgArg->ppmServerStarted = ppmServerStarted; + pXMsgArg->hwndScreen = hwndScreen; + if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed on XMSG.\n"); + return FALSE; + } + +#if CYGDEBUG || YES + winDebug ("winInitWM - Returning.\n"); +#endif + + return TRUE; +} + + +/* + * Window manager thread - setup + */ + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) +{ + int iRetries = 0; + char pszDisplay[512]; + int iReturn; + + ErrorF ("winInitMultiWindowWM - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\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. " + "Exiting.\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winInitMultiWindowWM - Warning: Locale not supported by X.\n"); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); + + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpWMEntry); + + /* 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 - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowWMErrorHandler); + XSetIOErrorHandler (winMultiWindowWMIOErrorHandler); + + /* Setup the display connection string x */ + snprintf (pszDisplay, + 512, + "127.0.0.1:%s.%d", + display, + (int) pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay); + + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* 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", + 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. " + "Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + + /* Create some atoms */ + pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay, + "WM_PROTOCOLS", + False); + pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay, + "WM_DELETE_WINDOW", + False); + + pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay, + WINDOWSWM_NATIVE_HWND, + False); + + + if (1) { + Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr); + if (cursor) + { + XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor); + XFreeCursor (pWMInfo->pDisplay, cursor); + } + } +} + + +/* + * 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); + } +} + + +/* + * Window manager error handler + */ + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + if (pErr->request_code == X_ChangeWindowAttributes + && pErr->error_code == BadAccess) + { + ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " + "BadAccess.\n"); + return 0; + } + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); + + return 0; +} + + +/* + * Window manager IO error handler + */ + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay) +{ + ErrorF ("winMultiWindowWMIOErrorHandler!\n\n"); + + if (g_shutdown) + pthread_exit(NULL); + + /* Restart at the main entry point */ + longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * X message procedure error handler + */ + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg); +#endif + + return 0; +} + + +/* + * X message procedure IO error handler + */ + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay) +{ + ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * Catch RedirectError to detect other window manager running + */ + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + redirectError = TRUE; + return 0; +} + + +/* + * Check if another window manager is running + */ + +static Bool +CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM) +{ + /* + Try to select the events which only one client at a time is allowed to select. + If this causes an error, another window manager is already running... + */ + redirectError = FALSE; + XSetErrorHandler (winRedirectErrorHandler); + XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), + ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask); + XSync (pDisplay, 0); + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + + /* + Side effect: select the events we are actually interested in... + + If other WMs are not allowed, also select one of the events which only one client + at a time is allowed to select, so other window managers won't start... + */ + XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), + SubstructureNotifyMask | ( !fAllowOtherWM ? ButtonPressMask : 0)); + XSync (pDisplay, 0); + return redirectError; +} + +/* + * Notify the MWM thread we're exiting and not to reconnect + */ + +void +winDeinitMultiWindowWM (void) +{ + ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n"); + g_shutdown = TRUE; +} + +/* Windows window styles */ +#define HINT_NOFRAME (1l<<0) +#define HINT_BORDER (1L<<1) +#define HINT_SIZEBOX (1l<<2) +#define HINT_CAPTION (1l<<3) +#define HINT_NOMAXIMIZE (1L<<4) +/* These two are used on their own */ +#define HINT_MAX (1L<<0) +#define HINT_MIN (1L<<1) + +static void +winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) +{ + static Atom windowState, motif_wm_hints, windowType; + static Atom hiddenState, fullscreenState, belowState, aboveState; + static Atom dockWindow; + static int generation; + Atom type, *pAtom = NULL; + int format; + unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0; + MwmHints *mwm_hint = NULL; + + if (!hWnd) return; + if (!IsWindow (hWnd)) return; + + if (generation != serverGeneration) { + generation = serverGeneration; + windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False); + motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False); + windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False); + hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False); + fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False); + belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False); + aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False); + dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False); + } + + if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L, + 1L, False, XA_ATOM, &type, &format, + &nitems, &left, (unsigned char **)&pAtom) == Success) + { + if (pAtom && nitems == 1) + { + if (*pAtom == hiddenState) maxmin |= HINT_MIN; + else if (*pAtom == fullscreenState) maxmin |= HINT_MAX; + if (*pAtom == belowState) *zstyle = HWND_BOTTOM; + else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST; + } + if (pAtom) XFree(pAtom); + } + + nitems = left = 0; + if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L, + PropMwmHintsElements, False, motif_wm_hints, &type, &format, + &nitems, &left, (unsigned char **)&mwm_hint) == Success) + { + if (mwm_hint && nitems == PropMwmHintsElements && (mwm_hint->flags & MwmHintsDecorations)) + { + if (!mwm_hint->decorations) hint |= HINT_NOFRAME; + else if (!(mwm_hint->decorations & MwmDecorAll)) + { + if (mwm_hint->decorations & MwmDecorBorder) hint |= HINT_BORDER; + if (mwm_hint->decorations & MwmDecorHandle) hint |= HINT_SIZEBOX; + if (mwm_hint->decorations & MwmDecorTitle) hint |= HINT_CAPTION; + } + } + if (mwm_hint) XFree(mwm_hint); + } + + nitems = left = 0; + pAtom = NULL; + if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L, + 1L, False, XA_ATOM, &type, &format, + &nitems, &left, (unsigned char **)&pAtom) == Success) + { + if (pAtom && nitems == 1) + { + if (*pAtom == dockWindow) + { + hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */ + *zstyle = HWND_TOPMOST; + } + } + if (pAtom) XFree(pAtom); + } + + { + XSizeHints *normal_hint = XAllocSizeHints(); + long supplied; + if (normal_hint && (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) == Success)) + { + if (normal_hint->flags & PMaxSize) + { + /* Not maximizable if a maximum size is specified */ + hint |= HINT_NOMAXIMIZE; + + if (normal_hint->flags & PMinSize) + { + /* + If both minimum size and maximum size are specified and are the same, + don't bother with a resizing frame + */ + if ((normal_hint->min_width == normal_hint->max_width) + && (normal_hint->min_height == normal_hint->max_height)) + hint = (hint & ~HINT_SIZEBOX); + } + } + } + XFree(normal_hint); + } + + /* Override hint settings from above with settings from config file */ + { + XClassHint class_hint = {0,0}; + char *window_name = 0; + + if (XGetClassHint(pDisplay, iWindow, &class_hint)) + { + XFetchName(pDisplay, iWindow, &window_name); + + style = winOverrideStyle(class_hint.res_name, class_hint.res_class, window_name); + + if (class_hint.res_name) XFree(class_hint.res_name); + if (class_hint.res_class) XFree(class_hint.res_class); + if (window_name) XFree(window_name); + } + else + { + style = STYLE_NONE; + } + } + + if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST; + else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX; + else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN; + else if (style & STYLE_BOTTOM) *zstyle = HWND_BOTTOM; + + if (maxmin & HINT_MAX) SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + else if (maxmin & HINT_MIN) SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); + + if (style & STYLE_NOTITLE) + hint = (hint & ~HINT_NOFRAME & ~HINT_BORDER & ~HINT_CAPTION) | HINT_SIZEBOX; + else if (style & STYLE_OUTLINE) + hint = (hint & ~HINT_NOFRAME & ~HINT_SIZEBOX & ~HINT_CAPTION) | HINT_BORDER; + else if (style & STYLE_NOFRAME) + hint = (hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) | HINT_NOFRAME; + + /* Now apply styles to window */ + style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */ + if (!style) return; + + if (!hint) /* All on */ + style = style | WS_CAPTION | WS_SIZEBOX; + else if (hint & HINT_NOFRAME) /* All off */ + style = style & ~WS_CAPTION & ~WS_SIZEBOX; + else style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) | + ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) | + ((hint & HINT_CAPTION) ? WS_CAPTION : 0); + + if (hint & HINT_NOMAXIMIZE) + style = style & ~WS_MAXIMIZEBOX; + + SetWindowLongPtr (hWnd, GWL_STYLE, style); +} + +void +winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle) +{ + int iX, iY, iWidth, iHeight; + int iDx, iDy; + RECT rcNew; + WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP); + DrawablePtr pDraw = NULL; + + if (!pWin) return; + pDraw = &pWin->drawable; + if (!pDraw) return; + + /* Get the X and Y location of the X window */ + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#if 0 + ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + AdjustWindowRectEx (&rcNew, GetWindowLongPtr (hWnd, GWL_STYLE), FALSE, WS_EX_APPWINDOW); + + /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */ + if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) + { + iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left; + rcNew.left += iDx; + rcNew.right += iDx; + } + + if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN)) + { + iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top; + rcNew.top += iDy; + rcNew.bottom += iDy; + } + +#if 0 + ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* Position the Windows window */ + SetWindowPos (hWnd, *zstyle, rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + 0); + + if (reshape) + { + winReshapeMultiWindow(pWin); + winUpdateRgnMultiWindow(pWin); + } +} diff --git a/xorg-server/hw/xwin/winpfbdd.c b/xorg-server/hw/xwin/winpfbdd.c index c0bca71e3..a3990208d 100644 --- a/xorg-server/hw/xwin/winpfbdd.c +++ b/xorg-server/hw/xwin/winpfbdd.c @@ -294,7 +294,8 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); diff --git a/xorg-server/hw/xwin/winprefs.c b/xorg-server/hw/xwin/winprefs.c index 073c9ec62..d941c5169 100644 --- a/xorg-server/hw/xwin/winprefs.c +++ b/xorg-server/hw/xwin/winprefs.c @@ -1,852 +1,832 @@ -/*
- * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- * Copyright (C) Colin Harrison 2005-2008
- *
- * 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: Earle F. Philhower, III
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef __CYGWIN__
-#include <sys/resource.h>
-#endif
-#include "win.h"
-
-#include <X11/Xwindows.h>
-#include <shellapi.h>
-
-#include "winprefs.h"
-#include "winmultiwindowclass.h"
-
-/* Where will the custom menu commands start counting from? */
-#define STARTMENUID WM_USER
-
-extern const char *winGetBaseDir(void);
-
-/* From winmultiwindowflex.l, the real parser */
-extern void parse_file (FILE *fp);
-
-
-/* Currently in use command ID, incremented each new menu item created */
-static int g_cmdid = STARTMENUID;
-
-
-/* Defined in DIX */
-extern char *display;
-
-/* Local function to handle comma-ified icon names */
-static HICON
-LoadImageComma (char *fname, int sx, int sy, int flags);
-
-
-/*
- * Creates or appends a menu from a MENUPARSED structure
- */
-static HMENU
-MakeMenu (char *name,
- HMENU editMenu,
- int editItem)
-{
- int i;
- int item;
- MENUPARSED *m;
- HMENU hmenu, hsub;
-
- for (i=0; i<pref.menuItems; i++)
- {
- if (!strcmp(name, pref.menu[i].menuName))
- break;
- }
-
- /* Didn't find a match, bummer */
- if (i==pref.menuItems)
- {
- ErrorF("MakeMenu: Can't find menu %s\n", name);
- return NULL;
- }
-
- m = &(pref.menu[i]);
-
- if (editMenu)
- {
- hmenu = editMenu;
- item = editItem;
- }
- else
- {
- hmenu = CreatePopupMenu();
- if (!hmenu)
- {
- ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name);
- return NULL;
- }
- item = 0;
- }
-
- /* Add the menu items */
- for (i=0; i<m->menuItems; i++)
- {
- /* Only assign IDs one time... */
- if ( m->menuItem[i].commandID == 0 )
- m->menuItem[i].commandID = g_cmdid++;
-
- switch (m->menuItem[i].cmd)
- {
- case CMD_EXEC:
- case CMD_ALWAYSONTOP:
- case CMD_RELOAD:
- InsertMenu (hmenu,
- item,
- MF_BYPOSITION|MF_ENABLED|MF_STRING,
- m->menuItem[i].commandID,
- m->menuItem[i].text);
- break;
-
- case CMD_SEPARATOR:
- InsertMenu (hmenu,
- item,
- MF_BYPOSITION|MF_SEPARATOR,
- 0,
- NULL);
- break;
-
- case CMD_MENU:
- /* Recursive! */
- hsub = MakeMenu (m->menuItem[i].param, 0, 0);
- if (hsub)
- InsertMenu (hmenu,
- item,
- MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING,
- (UINT_PTR)hsub,
- m->menuItem[i].text);
- break;
- }
-
- /* If item==-1 (means to add at end of menu) don't increment) */
- if (item>=0)
- item++;
- }
-
- return hmenu;
-}
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * Callback routine that is executed once per window class.
- * Removes or creates custom window settings depending on LPARAM
- */
-static wBOOL CALLBACK
-ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam)
-{
- HICON hicon;
- Window wid;
-
- if (!hwnd) {
- ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n");
- return FALSE;
- }
-
- /* It's our baby, either clean or dirty it */
- if (lParam==FALSE)
- {
- /* Reset the window's icon to undefined. */
- hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0);
-
- /* If the old icon is generated on-the-fly, get rid of it, will regen */
- winDestroyIcon (hicon);
-
- /* Same for the small icon */
- hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0);
- winDestroyIcon (hicon);
-
- /* Remove any menu additions; bRevert=TRUE destroys any modified menus */
- GetSystemMenu (hwnd, TRUE);
-
- /* This window is now clean of our taint (but with undefined icons) */
- }
- else
- {
- /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */
- wid = (Window)GetProp (hwnd, WIN_WID_PROP);
- if (wid)
- winUpdateIcon (wid);
-
- /* Update the system menu for this window */
- SetupSysMenu ((unsigned long)hwnd);
-
- /* That was easy... */
- }
-
- return TRUE;
-}
-#endif
-
-
-/*
- * Removes any custom icons in classes, custom menus, etc.
- * Frees all members in pref structure.
- * Reloads the preferences file.
- * Set custom icons and menus again.
- */
-static void
-ReloadPrefs (void)
-{
- int i;
-
-#ifdef XWIN_MULTIWINDOW
- /* First, iterate over all windows, deleting their icons and custom menus.
- * This is really only needed because winDestroyIcon() will try to
- * destroy the old global icons, which will have changed.
- * It is probably better to set a windows USER_DATA to flag locally defined
- * icons, and use that to accurately know when to destroy old icons.
- */
- EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
-#endif
-
- /* Now, free/clear all info from our prefs structure */
- for (i=0; i<pref.menuItems; i++)
- free (pref.menu[i].menuItem);
- free (pref.menu);
- pref.menu = NULL;
- pref.menuItems = 0;
-
- pref.rootMenuName[0] = 0;
-
- free (pref.sysMenu);
- pref.sysMenuItems = 0;
-
- pref.defaultSysMenuName[0] = 0;
- pref.defaultSysMenuPos = 0;
-
- pref.iconDirectory[0] = 0;
- pref.defaultIconName[0] = 0;
- pref.trayIconName[0] = 0;
-
- for (i=0; i<pref.iconItems; i++)
- if (pref.icon[i].hicon)
- DestroyIcon ((HICON)pref.icon[i].hicon);
- free (pref.icon);
- pref.icon = NULL;
- pref.iconItems = 0;
-
- /* Free global default X icon */
- if (g_hIconX)
- DestroyIcon (g_hIconX);
- if (g_hSmallIconX)
- DestroyIcon (g_hSmallIconX);
-
- /* Reset the custom command IDs */
- g_cmdid = STARTMENUID;
-
- /* Load the updated resource file */
- LoadPreferences();
-
- g_hIconX = NULL;
- g_hSmallIconX = NULL;
-
-#ifdef XWIN_MULTIWINDOW
- winInitGlobalIcons();
-#endif
-
-#ifdef XWIN_MULTIWINDOW
- /* Rebuild the icons and menus */
- EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE);
-#endif
-
- /* Whew, done */
-}
-
-/*
- * Check/uncheck the ALWAYSONTOP items in this menu
- */
-void
-HandleCustomWM_INITMENU(unsigned long hwndIn,
- unsigned long hmenuIn)
-{
- HWND hwnd;
- HMENU hmenu;
- DWORD dwExStyle;
- int i, j;
-
- hwnd = (HWND)hwndIn;
- hmenu = (HMENU)hmenuIn;
- if (!hwnd || !hmenu)
- return;
-
- if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
- dwExStyle = MF_BYCOMMAND | MF_CHECKED;
- else
- dwExStyle = MF_BYCOMMAND | MF_UNCHECKED;
-
- for (i=0; i<pref.menuItems; i++)
- for (j=0; j<pref.menu[i].menuItems; j++)
- if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP)
- CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle );
-
-}
-
-/*
- * Searches for the custom WM_COMMAND command ID and performs action.
- * Return TRUE if command is proccessed, FALSE otherwise.
- */
-Bool
-HandleCustomWM_COMMAND (unsigned long hwndIn,
- int command)
-{
- HWND hwnd;
- int i, j;
- MENUPARSED *m;
- DWORD dwExStyle;
-
- hwnd = (HWND)hwndIn;
-
- if (!command)
- return FALSE;
-
- for (i=0; i<pref.menuItems; i++)
- {
- m = &(pref.menu[i]);
- for (j=0; j<m->menuItems; j++)
- {
- if (command==m->menuItem[j].commandID)
- {
- /* Match! */
- switch(m->menuItem[j].cmd)
- {
-#ifdef __CYGWIN__
- case CMD_EXEC:
- if (fork()==0)
- {
- struct rlimit rl;
- unsigned long i;
-
- /* Close any open descriptors except for STD* */
- getrlimit (RLIMIT_NOFILE, &rl);
- for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++)
- close(i);
-
- /* Disassociate any TTYs */
- setsid();
-
- execl ("/bin/sh",
- "/bin/sh",
- "-c",
- m->menuItem[j].param,
- NULL);
- exit (0);
- }
- else
- return TRUE;
- break;
-#else
- case CMD_EXEC:
- {
- /* Start process without console window */
- STARTUPINFO start;
- PROCESS_INFORMATION child;
-
- memset (&start, 0, sizeof (start));
- start.cb = sizeof (start);
- start.dwFlags = STARTF_USESHOWWINDOW;
- start.wShowWindow = SW_HIDE;
-
- memset (&child, 0, sizeof (child));
-
- if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0,
- NULL, NULL, &start, &child))
- {
- CloseHandle (child.hThread);
- CloseHandle (child.hProcess);
- }
- else
- MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION);
- }
- return TRUE;
-#endif
- case CMD_ALWAYSONTOP:
- if (!hwnd)
- return FALSE;
-
- /* Get extended window style */
- dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
-
- /* Handle topmost windows */
- if (dwExStyle & WS_EX_TOPMOST)
- SetWindowPos (hwnd,
- HWND_NOTOPMOST,
- 0, 0,
- 0, 0,
- SWP_NOSIZE | SWP_NOMOVE);
- else
- SetWindowPos (hwnd,
- HWND_TOPMOST,
- 0, 0,
- 0, 0,
- SWP_NOSIZE | SWP_NOMOVE);
-#if XWIN_MULTIWINDOW
- /* Reflect the changed Z order */
- winReorderWindowsMultiWindow ();
-#endif
- return TRUE;
-
- case CMD_RELOAD:
- ReloadPrefs();
- return TRUE;
-
- default:
- return FALSE;
- }
- } /* match */
- } /* for j */
- } /* for i */
-
- return FALSE;
-}
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * Add the default or a custom menu depending on the class match
- */
-void
-SetupSysMenu (unsigned long hwndIn)
-{
- HWND hwnd;
- HMENU sys;
- int i;
- WindowPtr pWin;
- char *res_name, *res_class;
-
- hwnd = (HWND)hwndIn;
- if (!hwnd)
- return;
-
- pWin = GetProp (hwnd, WIN_WINDOW_PROP);
-
- sys = GetSystemMenu (hwnd, FALSE);
- if (!sys)
- return;
-
- if (pWin)
- {
- /* First see if there's a class match... */
- if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
- {
- for (i=0; i<pref.sysMenuItems; i++)
- {
- if (!strcmp(pref.sysMenu[i].match, res_name) ||
- !strcmp(pref.sysMenu[i].match, res_class) )
- {
- free(res_name);
- free(res_class);
-
- MakeMenu (pref.sysMenu[i].menuName, sys,
- pref.sysMenu[i].menuPos==AT_START?0:-1);
- return;
- }
- }
-
- /* No match, just free alloc'd strings */
- free(res_name);
- free(res_class);
- } /* Found wm_class */
- } /* if pwin */
-
- /* Fallback to system default */
- if (pref.defaultSysMenuName[0])
- {
- if (pref.defaultSysMenuPos==AT_START)
- MakeMenu (pref.defaultSysMenuName, sys, 0);
- else
- MakeMenu (pref.defaultSysMenuName, sys, -1);
- }
-}
-#endif
-
-
-/*
- * Possibly add a menu to the toolbar icon
- */
-void
-SetupRootMenu (unsigned long hmenuRoot)
-{
- HMENU root;
-
- root = (HMENU)hmenuRoot;
- if (!root)
- return;
-
- if (pref.rootMenuName[0])
- {
- MakeMenu(pref.rootMenuName, root, 0);
- }
-}
-
-
-/*
- * Check for and return an overridden default ICON specified in the prefs
- */
-HICON
-winOverrideDefaultIcon(int size)
-{
- HICON hicon;
-
- if (pref.defaultIconName[0])
- {
- hicon = LoadImageComma (pref.defaultIconName, size, size, 0);
- if (hicon==NULL)
- ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n",
- pref.defaultIconName);
-
- return hicon;
- }
-
- return 0;
-}
-
-
-/*
- * Return the HICON to use in the taskbar notification area
- */
-HICON
-winTaskbarIcon(void)
-{
- HICON hicon;
-
- hicon = 0;
- /* First try and load an overridden, if success then return it */
- if (pref.trayIconName[0])
- {
- hicon = LoadImageComma (pref.trayIconName,
- GetSystemMetrics (SM_CXSMICON),
- GetSystemMetrics (SM_CYSMICON),
- 0 );
- }
-
- /* Otherwise return the default */
- if (!hicon)
- hicon = (HICON) LoadImage (g_hInstance,
- MAKEINTRESOURCE(IDI_XWIN),
- IMAGE_ICON,
- GetSystemMetrics (SM_CXSMICON),
- GetSystemMetrics (SM_CYSMICON),
- 0);
-
- return hicon;
-}
-
-
-/*
- * Parse a filename to extract an icon:
- * If fname is exactly ",nnn" then extract icon from our resource
- * else if it is "file,nnn" then extract icon nnn from that file
- * else try to load it as an .ico file and if that fails return NULL
- */
-static HICON
-LoadImageComma (char *fname, int sx, int sy, int flags)
-{
- HICON hicon;
- int index;
- char file[PATH_MAX+NAME_MAX+2];
-
- /* Some input error checking */
- if (!fname || !fname[0])
- return NULL;
-
- index = 0;
- hicon = NULL;
-
- if (fname[0]==',')
- {
- /* It's the XWIN.EXE resource they want */
- index = atoi (fname+1);
- hicon = LoadImage (g_hInstance,
- MAKEINTRESOURCE(index),
- IMAGE_ICON,
- sx,
- sy,
- flags);
- }
- else
- {
- file[0] = 0;
- /* Prepend path if not given a "X:\" filename */
- if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') )
- {
- strcpy (file, pref.iconDirectory);
- if (pref.iconDirectory[0])
- if (fname[strlen(fname)-1]!='\\')
- strcat (file, "\\");
- }
- strcat (file, fname);
-
- if (strrchr (file, ','))
- {
- /* Specified as <fname>,<index> */
-
- *(strrchr (file, ',')) = 0; /* End string at comma */
- index = atoi (strrchr (fname, ',') + 1);
- hicon = ExtractIcon (g_hInstance, file, index);
- }
- else
- {
- /* Just an .ico file... */
-
- hicon = (HICON)LoadImage (NULL,
- file,
- IMAGE_ICON,
- sx,
- sy,
- LR_LOADFROMFILE|flags);
- }
- }
- return hicon;
-}
-
-/*
- * Check for a match of the window class to one specified in the
- * ICONS{} section in the prefs file, and load the icon from a file
- */
-HICON
-winOverrideIcon (unsigned long longWin)
-{
- WindowPtr pWin = (WindowPtr) longWin;
- char *res_name, *res_class;
- int i;
- HICON hicon;
- char *wmName;
-
- if (pWin==NULL)
- return 0;
-
- /* If we can't find the class, we can't override from default! */
- if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
- return 0;
-
- winMultiWindowGetWMName (pWin, &wmName);
-
- for (i=0; i<pref.iconItems; i++) {
- if (!strcmp(pref.icon[i].match, res_name) ||
- !strcmp(pref.icon[i].match, res_class) ||
- (wmName && strstr(wmName, pref.icon[i].match)))
- {
- free (res_name);
- free (res_class);
- free(wmName);
-
- if (pref.icon[i].hicon)
- return pref.icon[i].hicon;
-
- hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE);
- if (hicon==NULL)
- ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n",
- pref.icon[i].iconFile);
-
- pref.icon[i].hicon = hicon;
- return hicon;
- }
- }
-
- /* Didn't find the icon, fail gracefully */
- free (res_name);
- free (res_class);
- free(wmName);
-
- return 0;
-}
-
-
-/*
- * Should we free this icon or leave it in memory (is it part of our
- * ICONS{} overrides)?
- */
-int
-winIconIsOverride(unsigned hiconIn)
-{
- HICON hicon;
- int i;
-
- hicon = (HICON)hiconIn;
-
- if (!hicon)
- return 0;
-
- for (i=0; i<pref.iconItems; i++)
- if ((HICON)pref.icon[i].hicon == hicon)
- return 1;
-
- return 0;
-}
-
-
-
-/*
- * Try and open ~/.XWinrc and system.XWinrc
- * Load it into prefs structure for use by other functions
- */
-void
-LoadPreferences (void)
-{
- char *home;
- char fname[PATH_MAX+NAME_MAX+2];
- FILE *prefFile;
- char szDisplay[512];
- char *szEnvDisplay;
- int i, j;
- char param[PARAM_MAX+1];
- char *srcParam, *dstParam;
-
- /* First, clear all preference settings */
- memset (&pref, 0, sizeof(pref));
- prefFile = NULL;
-
- /* Now try and find a ~/.xwinrc file */
- home = getenv ("HOME");
- if (home)
- {
- strcpy (fname, home);
- if (fname[strlen(fname)-1]!='/')
- strcat (fname, "/");
- strcat (fname, ".XWinrc");
-
- prefFile = fopen (fname, "r");
- if (prefFile)
- ErrorF ("winPrefsLoadPreferences: %s\n", fname);
- }
-
- /* No home file found, check system default */
- if (!prefFile)
- {
- char buffer[MAX_PATH];
-#ifdef RELOCATE_PROJECTROOT
- snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir());
-#else
- strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer));
-#endif
- buffer[sizeof(buffer)-1] = 0;
- prefFile = fopen (buffer, "r");
- if (prefFile)
- ErrorF ("winPrefsLoadPreferences: %s\n", buffer);
- }
-
- /* If we could open it, then read the settings and close it */
- if (prefFile)
- {
- parse_file (prefFile);
- fclose (prefFile);
- }
-
- /* Setup a DISPLAY environment variable, need to allocate on heap */
- /* because putenv doesn't copy the argument... */
- snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display);
- szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1));
- if (szEnvDisplay)
- {
- strcpy (szEnvDisplay, szDisplay);
- putenv (szEnvDisplay);
- }
-
- /* Replace any "%display%" in menu commands with display string */
- snprintf (szDisplay, 512, "127.0.0.1:%s.0", display);
- for (i=0; i<pref.menuItems; i++)
- {
- for (j=0; j<pref.menu[i].menuItems; j++)
- {
- if (pref.menu[i].menuItem[j].cmd==CMD_EXEC)
- {
- srcParam = pref.menu[i].menuItem[j].param;
- dstParam = param;
- while (*srcParam) {
- if (!strncmp(srcParam, "%display%", 9))
- {
- memcpy (dstParam, szDisplay, strlen(szDisplay));
- dstParam += strlen(szDisplay);
- srcParam += 9;
- }
- else
- {
- *dstParam = *srcParam;
- dstParam++;
- srcParam++;
- }
- }
- *dstParam = 0;
- strcpy (pref.menu[i].menuItem[j].param, param);
- } /* cmd==cmd_exec */
- } /* for all menuitems */
- } /* for all menus */
-
-}
-
-
-/*
- * Check for a match of the window class to one specified in the
- * STYLES{} section in the prefs file, and return the style type
- */
-unsigned long
-winOverrideStyle (unsigned long longpWin)
-{
- WindowPtr pWin = (WindowPtr) longpWin;
- char *res_name, *res_class;
- int i;
- char *wmName;
-
- if (pWin==NULL)
- return STYLE_NONE;
-
- /* If we can't find the class, we can't override from default! */
- if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
- return STYLE_NONE;
-
- winMultiWindowGetWMName (pWin, &wmName);
-
- for (i=0; i<pref.styleItems; i++) {
- if (!strcmp(pref.style[i].match, res_name) ||
- !strcmp(pref.style[i].match, res_class) ||
- (wmName && strstr(wmName, pref.style[i].match)))
- {
- free (res_name);
- free (res_class);
- free(wmName);
-
- if (pref.style[i].type)
- return pref.style[i].type;
- }
- }
-
- /* Didn't find the style, fail gracefully */
- free (res_name);
- free (res_class);
- free(wmName);
-
- return STYLE_NONE;
-}
+/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * Copyright (C) Colin Harrison 2005-2008 + * + * 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: Earle F. Philhower, III + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef __CYGWIN__ +#include <sys/resource.h> +#endif +#include "win.h" + +#include <X11/Xwindows.h> +#include <shellapi.h> + +#include "winprefs.h" +#include "winmultiwindowclass.h" + +/* Where will the custom menu commands start counting from? */ +#define STARTMENUID WM_USER + +extern const char *winGetBaseDir(void); + +/* From winmultiwindowflex.l, the real parser */ +extern void parse_file (FILE *fp); + + +/* Currently in use command ID, incremented each new menu item created */ +static int g_cmdid = STARTMENUID; + + +/* Defined in DIX */ +extern char *display; + +/* Local function to handle comma-ified icon names */ +static HICON +LoadImageComma (char *fname, int sx, int sy, int flags); + + +/* + * Creates or appends a menu from a MENUPARSED structure + */ +static HMENU +MakeMenu (char *name, + HMENU editMenu, + int editItem) +{ + int i; + int item; + MENUPARSED *m; + HMENU hmenu, hsub; + + for (i=0; i<pref.menuItems; i++) + { + if (!strcmp(name, pref.menu[i].menuName)) + break; + } + + /* Didn't find a match, bummer */ + if (i==pref.menuItems) + { + ErrorF("MakeMenu: Can't find menu %s\n", name); + return NULL; + } + + m = &(pref.menu[i]); + + if (editMenu) + { + hmenu = editMenu; + item = editItem; + } + else + { + hmenu = CreatePopupMenu(); + if (!hmenu) + { + ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name); + return NULL; + } + item = 0; + } + + /* Add the menu items */ + for (i=0; i<m->menuItems; i++) + { + /* Only assign IDs one time... */ + if ( m->menuItem[i].commandID == 0 ) + m->menuItem[i].commandID = g_cmdid++; + + switch (m->menuItem[i].cmd) + { + case CMD_EXEC: + case CMD_ALWAYSONTOP: + case CMD_RELOAD: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_ENABLED|MF_STRING, + m->menuItem[i].commandID, + m->menuItem[i].text); + break; + + case CMD_SEPARATOR: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_SEPARATOR, + 0, + NULL); + break; + + case CMD_MENU: + /* Recursive! */ + hsub = MakeMenu (m->menuItem[i].param, 0, 0); + if (hsub) + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING, + (UINT_PTR)hsub, + m->menuItem[i].text); + break; + } + + /* If item==-1 (means to add at end of menu) don't increment) */ + if (item>=0) + item++; + } + + return hmenu; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Callback routine that is executed once per window class. + * Removes or creates custom window settings depending on LPARAM + */ +static wBOOL CALLBACK +ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam) +{ + HICON hicon; + Window wid; + + if (!hwnd) { + ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n"); + return FALSE; + } + + /* It's our baby, either clean or dirty it */ + if (lParam==FALSE) + { + /* Reset the window's icon to undefined. */ + hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0); + + /* If the old icon is generated on-the-fly, get rid of it, will regen */ + winDestroyIcon (hicon); + + /* Same for the small icon */ + hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0); + winDestroyIcon (hicon); + + /* Remove any menu additions; bRevert=TRUE destroys any modified menus */ + GetSystemMenu (hwnd, TRUE); + + /* This window is now clean of our taint (but with undefined icons) */ + } + else + { + /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */ + wid = (Window)GetProp (hwnd, WIN_WID_PROP); + if (wid) + winUpdateIcon (wid); + + /* Update the system menu for this window */ + SetupSysMenu ((unsigned long)hwnd); + + /* That was easy... */ + } + + return TRUE; +} +#endif + + +/* + * Removes any custom icons in classes, custom menus, etc. + * Frees all members in pref structure. + * Reloads the preferences file. + * Set custom icons and menus again. + */ +static void +ReloadPrefs (void) +{ + int i; + +#ifdef XWIN_MULTIWINDOW + /* First, iterate over all windows, deleting their icons and custom menus. + * This is really only needed because winDestroyIcon() will try to + * destroy the old global icons, which will have changed. + * It is probably better to set a windows USER_DATA to flag locally defined + * icons, and use that to accurately know when to destroy old icons. + */ + EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE); +#endif + + /* Now, free/clear all info from our prefs structure */ + for (i=0; i<pref.menuItems; i++) + free (pref.menu[i].menuItem); + free (pref.menu); + pref.menu = NULL; + pref.menuItems = 0; + + pref.rootMenuName[0] = 0; + + free (pref.sysMenu); + pref.sysMenuItems = 0; + + pref.defaultSysMenuName[0] = 0; + pref.defaultSysMenuPos = 0; + + pref.iconDirectory[0] = 0; + pref.defaultIconName[0] = 0; + pref.trayIconName[0] = 0; + + for (i=0; i<pref.iconItems; i++) + if (pref.icon[i].hicon) + DestroyIcon ((HICON)pref.icon[i].hicon); + free (pref.icon); + pref.icon = NULL; + pref.iconItems = 0; + + /* Free global default X icon */ + if (g_hIconX) + DestroyIcon (g_hIconX); + if (g_hSmallIconX) + DestroyIcon (g_hSmallIconX); + + /* Reset the custom command IDs */ + g_cmdid = STARTMENUID; + + /* Load the updated resource file */ + LoadPreferences(); + + g_hIconX = NULL; + g_hSmallIconX = NULL; + +#ifdef XWIN_MULTIWINDOW + winInitGlobalIcons(); +#endif + +#ifdef XWIN_MULTIWINDOW + /* Rebuild the icons and menus */ + EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE); +#endif + + /* Whew, done */ +} + +/* + * Check/uncheck the ALWAYSONTOP items in this menu + */ +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn) +{ + HWND hwnd; + HMENU hmenu; + DWORD dwExStyle; + int i, j; + + hwnd = (HWND)hwndIn; + hmenu = (HMENU)hmenuIn; + if (!hwnd || !hmenu) + return; + + if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) + dwExStyle = MF_BYCOMMAND | MF_CHECKED; + else + dwExStyle = MF_BYCOMMAND | MF_UNCHECKED; + + for (i=0; i<pref.menuItems; i++) + for (j=0; j<pref.menu[i].menuItems; j++) + if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP) + CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle ); + +} + +/* + * Searches for the custom WM_COMMAND command ID and performs action. + * Return TRUE if command is proccessed, FALSE otherwise. + */ +Bool +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command) +{ + HWND hwnd; + int i, j; + MENUPARSED *m; + DWORD dwExStyle; + + hwnd = (HWND)hwndIn; + + if (!command) + return FALSE; + + for (i=0; i<pref.menuItems; i++) + { + m = &(pref.menu[i]); + for (j=0; j<m->menuItems; j++) + { + if (command==m->menuItem[j].commandID) + { + /* Match! */ + switch(m->menuItem[j].cmd) + { +#ifdef __CYGWIN__ + case CMD_EXEC: + if (fork()==0) + { + struct rlimit rl; + unsigned long i; + + /* Close any open descriptors except for STD* */ + getrlimit (RLIMIT_NOFILE, &rl); + for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) + close(i); + + /* Disassociate any TTYs */ + setsid(); + + execl ("/bin/sh", + "/bin/sh", + "-c", + m->menuItem[j].param, + NULL); + exit (0); + } + else + return TRUE; + break; +#else + case CMD_EXEC: + { + /* Start process without console window */ + STARTUPINFO start; + PROCESS_INFORMATION child; + + memset (&start, 0, sizeof (start)); + start.cb = sizeof (start); + start.dwFlags = STARTF_USESHOWWINDOW; + start.wShowWindow = SW_HIDE; + + memset (&child, 0, sizeof (child)); + + if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, + NULL, NULL, &start, &child)) + { + CloseHandle (child.hThread); + CloseHandle (child.hProcess); + } + else + MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); + } + return TRUE; +#endif + case CMD_ALWAYSONTOP: + if (!hwnd) + return FALSE; + + /* Get extended window style */ + dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); + + /* Handle topmost windows */ + if (dwExStyle & WS_EX_TOPMOST) + SetWindowPos (hwnd, + HWND_NOTOPMOST, + 0, 0, + 0, 0, + SWP_NOSIZE | SWP_NOMOVE); + else + SetWindowPos (hwnd, + HWND_TOPMOST, + 0, 0, + 0, 0, + SWP_NOSIZE | SWP_NOMOVE); +#if XWIN_MULTIWINDOW + /* Reflect the changed Z order */ + winReorderWindowsMultiWindow (); +#endif + return TRUE; + + case CMD_RELOAD: + ReloadPrefs(); + return TRUE; + + default: + return FALSE; + } + } /* match */ + } /* for j */ + } /* for i */ + + return FALSE; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Add the default or a custom menu depending on the class match + */ +void +SetupSysMenu (unsigned long hwndIn) +{ + HWND hwnd; + HMENU sys; + int i; + WindowPtr pWin; + char *res_name, *res_class; + + hwnd = (HWND)hwndIn; + if (!hwnd) + return; + + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + sys = GetSystemMenu (hwnd, FALSE); + if (!sys) + return; + + if (pWin) + { + /* First see if there's a class match... */ + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + { + for (i=0; i<pref.sysMenuItems; i++) + { + if (!strcmp(pref.sysMenu[i].match, res_name) || + !strcmp(pref.sysMenu[i].match, res_class) ) + { + free(res_name); + free(res_class); + + MakeMenu (pref.sysMenu[i].menuName, sys, + pref.sysMenu[i].menuPos==AT_START?0:-1); + return; + } + } + + /* No match, just free alloc'd strings */ + free(res_name); + free(res_class); + } /* Found wm_class */ + } /* if pwin */ + + /* Fallback to system default */ + if (pref.defaultSysMenuName[0]) + { + if (pref.defaultSysMenuPos==AT_START) + MakeMenu (pref.defaultSysMenuName, sys, 0); + else + MakeMenu (pref.defaultSysMenuName, sys, -1); + } +} +#endif + + +/* + * Possibly add a menu to the toolbar icon + */ +void +SetupRootMenu (unsigned long hmenuRoot) +{ + HMENU root; + + root = (HMENU)hmenuRoot; + if (!root) + return; + + if (pref.rootMenuName[0]) + { + MakeMenu(pref.rootMenuName, root, 0); + } +} + + +/* + * Check for and return an overridden default ICON specified in the prefs + */ +HICON +winOverrideDefaultIcon(int size) +{ + HICON hicon; + + if (pref.defaultIconName[0]) + { + hicon = LoadImageComma (pref.defaultIconName, size, size, 0); + if (hicon==NULL) + ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n", + pref.defaultIconName); + + return hicon; + } + + return 0; +} + + +/* + * Return the HICON to use in the taskbar notification area + */ +HICON +winTaskbarIcon(void) +{ + HICON hicon; + + hicon = 0; + /* First try and load an overridden, if success then return it */ + if (pref.trayIconName[0]) + { + hicon = LoadImageComma (pref.trayIconName, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0 ); + } + + /* Otherwise return the default */ + if (!hicon) + hicon = (HICON) LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0); + + return hicon; +} + + +/* + * Parse a filename to extract an icon: + * If fname is exactly ",nnn" then extract icon from our resource + * else if it is "file,nnn" then extract icon nnn from that file + * else try to load it as an .ico file and if that fails return NULL + */ +static HICON +LoadImageComma (char *fname, int sx, int sy, int flags) +{ + HICON hicon; + int index; + char file[PATH_MAX+NAME_MAX+2]; + + /* Some input error checking */ + if (!fname || !fname[0]) + return NULL; + + index = 0; + hicon = NULL; + + if (fname[0]==',') + { + /* It's the XWIN.EXE resource they want */ + index = atoi (fname+1); + hicon = LoadImage (g_hInstance, + MAKEINTRESOURCE(index), + IMAGE_ICON, + sx, + sy, + flags); + } + else + { + file[0] = 0; + /* Prepend path if not given a "X:\" filename */ + if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') ) + { + strcpy (file, pref.iconDirectory); + if (pref.iconDirectory[0]) + if (fname[strlen(fname)-1]!='\\') + strcat (file, "\\"); + } + strcat (file, fname); + + if (strrchr (file, ',')) + { + /* Specified as <fname>,<index> */ + + *(strrchr (file, ',')) = 0; /* End string at comma */ + index = atoi (strrchr (fname, ',') + 1); + hicon = ExtractIcon (g_hInstance, file, index); + } + else + { + /* Just an .ico file... */ + + hicon = (HICON)LoadImage (NULL, + file, + IMAGE_ICON, + sx, + sy, + LR_LOADFROMFILE|flags); + } + } + return hicon; +} + +/* + * Check for a match of the window class to one specified in the + * ICONS{} section in the prefs file, and load the icon from a file + */ +HICON +winOverrideIcon (unsigned long longWin) +{ + WindowPtr pWin = (WindowPtr) longWin; + char *res_name, *res_class; + int i; + HICON hicon; + char *wmName; + + if (pWin==NULL) + return 0; + + /* If we can't find the class, we can't override from default! */ + if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + return 0; + + winMultiWindowGetWMName (pWin, &wmName); + + for (i=0; i<pref.iconItems; i++) { + if (!strcmp(pref.icon[i].match, res_name) || + !strcmp(pref.icon[i].match, res_class) || + (wmName && strstr(wmName, pref.icon[i].match))) + { + free (res_name); + free (res_class); + free(wmName); + + if (pref.icon[i].hicon) + return pref.icon[i].hicon; + + hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE); + if (hicon==NULL) + ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n", + pref.icon[i].iconFile); + + pref.icon[i].hicon = hicon; + return hicon; + } + } + + /* Didn't find the icon, fail gracefully */ + free (res_name); + free (res_class); + free(wmName); + + return 0; +} + + +/* + * Should we free this icon or leave it in memory (is it part of our + * ICONS{} overrides)? + */ +int +winIconIsOverride(unsigned hiconIn) +{ + HICON hicon; + int i; + + hicon = (HICON)hiconIn; + + if (!hicon) + return 0; + + for (i=0; i<pref.iconItems; i++) + if ((HICON)pref.icon[i].hicon == hicon) + return 1; + + return 0; +} + + + +/* + * Try and open ~/.XWinrc and system.XWinrc + * Load it into prefs structure for use by other functions + */ +void +LoadPreferences (void) +{ + char *home; + char fname[PATH_MAX+NAME_MAX+2]; + FILE *prefFile; + char szDisplay[512]; + char *szEnvDisplay; + int i, j; + char param[PARAM_MAX+1]; + char *srcParam, *dstParam; + + /* First, clear all preference settings */ + memset (&pref, 0, sizeof(pref)); + prefFile = NULL; + + /* Now try and find a ~/.xwinrc file */ + home = getenv ("HOME"); + if (home) + { + strcpy (fname, home); + if (fname[strlen(fname)-1]!='/') + strcat (fname, "/"); + strcat (fname, ".XWinrc"); + + prefFile = fopen (fname, "r"); + if (prefFile) + ErrorF ("winPrefsLoadPreferences: %s\n", fname); + } + + /* No home file found, check system default */ + if (!prefFile) + { + char buffer[MAX_PATH]; +#ifdef RELOCATE_PROJECTROOT + snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir()); +#else + strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer)); +#endif + buffer[sizeof(buffer)-1] = 0; + prefFile = fopen (buffer, "r"); + if (prefFile) + ErrorF ("winPrefsLoadPreferences: %s\n", buffer); + } + + /* If we could open it, then read the settings and close it */ + if (prefFile) + { + parse_file (prefFile); + fclose (prefFile); + } + + /* Setup a DISPLAY environment variable, need to allocate on heap */ + /* because putenv doesn't copy the argument... */ + snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display); + szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1)); + if (szEnvDisplay) + { + strcpy (szEnvDisplay, szDisplay); + putenv (szEnvDisplay); + } + + /* Replace any "%display%" in menu commands with display string */ + snprintf (szDisplay, 512, "127.0.0.1:%s.0", display); + for (i=0; i<pref.menuItems; i++) + { + for (j=0; j<pref.menu[i].menuItems; j++) + { + if (pref.menu[i].menuItem[j].cmd==CMD_EXEC) + { + srcParam = pref.menu[i].menuItem[j].param; + dstParam = param; + while (*srcParam) { + if (!strncmp(srcParam, "%display%", 9)) + { + memcpy (dstParam, szDisplay, strlen(szDisplay)); + dstParam += strlen(szDisplay); + srcParam += 9; + } + else + { + *dstParam = *srcParam; + dstParam++; + srcParam++; + } + } + *dstParam = 0; + strcpy (pref.menu[i].menuItem[j].param, param); + } /* cmd==cmd_exec */ + } /* for all menuitems */ + } /* for all menus */ + +} + + +/* + * Check for a match of the window class to one specified in the + * STYLES{} section in the prefs file, and return the style type + */ +unsigned long +winOverrideStyle (char *res_name, char *res_class, char *wmName) +{ + int i; + + for (i=0; i<pref.styleItems; i++) { + if ((res_name && !strcmp(pref.style[i].match, res_name)) || + (res_class && !strcmp(pref.style[i].match, res_class)) || + (wmName && strstr(wmName, pref.style[i].match))) + { + if (pref.style[i].type) + return pref.style[i].type; + } + } + + /* Didn't find the style, fail gracefully */ + return STYLE_NONE; +} diff --git a/xorg-server/hw/xwin/winprefs.h b/xorg-server/hw/xwin/winprefs.h index 276b9724d..ecd0a3fbd 100644 --- a/xorg-server/hw/xwin/winprefs.h +++ b/xorg-server/hw/xwin/winprefs.h @@ -1,190 +1,190 @@ -#if !defined(WINPREFS_H)
-#define WINPREFS_H
-/*
- * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- * Copyright (C) Colin Harrison 2005-2008
- *
- * 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: Earle F. Philhower, III
- * Colin Harrison
- */
-
-/* Need Bool */
-#include <X11/Xdefs.h>
-/* Need TRUE */
-#include "misc.h"
-
-/* Need to know how long paths can be... */
-#include <limits.h>
-/* Xwindows redefines PATH_MAX to at least 1024 */
-#include <X11/Xwindows.h>
-
-#ifndef NAME_MAX
-#define NAME_MAX PATH_MAX
-#endif
-#define MENU_MAX 128 /* Maximum string length of a menu name or item */
-#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */
-
-
-/* Supported commands in a MENU {} statement */
-typedef enum MENUCOMMANDTYPE
-{
- CMD_EXEC, /* /bin/sh -c the parameter */
- CMD_MENU, /* Display a popup menu named param */
- CMD_SEPARATOR, /* Menu separator */
- CMD_ALWAYSONTOP, /* Toggle always-on-top mode */
- CMD_RELOAD /* Reparse the .XWINRC file */
-} MENUCOMMANDTYPE;
-
-#define STYLE_NONE (0L) /* Dummy the first entry */
-#define STYLE_NOTITLE (1L) /* Force window style no titlebar */
-#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */
-#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */
-#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */
-#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */
-#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */
-#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */
-
-/* Where to place a system menu */
-typedef enum MENUPOSITION
-{
- AT_START, /* Place menu at the top of the system menu */
- AT_END /* Put it at the bottom of the menu (default) */
-} MENUPOSITION;
-
-/* Menu item definitions */
-typedef struct MENUITEM
-{
- char text[MENU_MAX+1]; /* To be displayed in menu */
- MENUCOMMANDTYPE cmd; /* What should it do? */
- char param[PARAM_MAX+1]; /* Any parameters? */
- unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */
-} MENUITEM;
-
-/* A completely read in menu... */
-typedef struct MENUPARSED
-{
- char menuName[MENU_MAX+1]; /* What's it called in the text? */
- MENUITEM *menuItem; /* Array of items */
- int menuItems; /* How big's the array? */
-} MENUPARSED;
-
-/* To map between a window and a system menu to add for it */
-typedef struct SYSMENUITEM
-{
- char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */
- char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */
- MENUPOSITION menuPos; /* Where to place it (ignored in root) */
-} SYSMENUITEM;
-
-/* To redefine icons for certain window types */
-typedef struct ICONITEM
-{
- char match[MENU_MAX+1]; /* What string to search for? */
- char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */
- HICON hicon; /* LoadImage() result */
-} ICONITEM;
-
-/* To redefine styles for certain window types */
-typedef struct STYLEITEM
-{
- char match[MENU_MAX+1]; /* What string to search for? */
- unsigned long type; /* What should it do? */
-} STYLEITEM;
-
-typedef struct WINPREFS
-{
- /* Menu information */
- MENUPARSED *menu; /* Array of created menus */
- int menuItems; /* How big? */
-
- /* Taskbar menu settings */
- char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */
-
- /* System menu addition menus */
- SYSMENUITEM *sysMenu;
- int sysMenuItems;
-
- /* Which menu to add to unmatched windows? */
- char defaultSysMenuName[MENU_MAX+1];
- MENUPOSITION defaultSysMenuPos; /* Where to place it */
-
- /* Icon information */
- char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */
- char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */
- char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */
-
- ICONITEM *icon;
- int iconItems;
-
- STYLEITEM *style;
- int styleItems;
-
- /* Force exit flag */
- Bool fForceExit;
-
- /* Silent exit flag */
- Bool fSilentExit;
-
-} WINPREFS;
-
-/* The global pref settings structure loaded by the winprefyacc.y parser */
-extern WINPREFS pref;
-
-
-/* Functions */
-void
-LoadPreferences(void);
-
-void
-SetupRootMenu (unsigned long hmenuRoot);
-
-void
-SetupSysMenu (unsigned long hwndIn);
-
-void
-HandleCustomWM_INITMENU(unsigned long hwndIn,
- unsigned long hmenuIn);
-
-Bool
-HandleCustomWM_COMMAND (unsigned long hwndIn,
- int command);
-
-int
-winIconIsOverride (unsigned hiconIn);
-
-HICON
-winOverrideIcon (unsigned long longpWin);
-
-unsigned long
-winOverrideStyle (unsigned long longpWin);
-
-HICON
-winTaskbarIcon(void);
-
-HICON
-winOverrideDefaultIcon(int size);
-#endif
+#if !defined(WINPREFS_H) +#define WINPREFS_H +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * Copyright (C) Colin Harrison 2005-2008 + * + * 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: Earle F. Philhower, III + * Colin Harrison + */ + +/* Need Bool */ +#include <X11/Xdefs.h> +/* Need TRUE */ +#include "misc.h" + +/* Need to know how long paths can be... */ +#include <limits.h> +/* Xwindows redefines PATH_MAX to at least 1024 */ +#include <X11/Xwindows.h> + +#ifndef NAME_MAX +#define NAME_MAX PATH_MAX +#endif +#define MENU_MAX 128 /* Maximum string length of a menu name or item */ +#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */ + + +/* Supported commands in a MENU {} statement */ +typedef enum MENUCOMMANDTYPE +{ + CMD_EXEC, /* /bin/sh -c the parameter */ + CMD_MENU, /* Display a popup menu named param */ + CMD_SEPARATOR, /* Menu separator */ + CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ + CMD_RELOAD /* Reparse the .XWINRC file */ +} MENUCOMMANDTYPE; + +#define STYLE_NONE (0L) /* Dummy the first entry */ +#define STYLE_NOTITLE (1L) /* Force window style no titlebar */ +#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */ +#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */ +#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */ +#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */ +#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */ +#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */ + +/* Where to place a system menu */ +typedef enum MENUPOSITION +{ + AT_START, /* Place menu at the top of the system menu */ + AT_END /* Put it at the bottom of the menu (default) */ +} MENUPOSITION; + +/* Menu item definitions */ +typedef struct MENUITEM +{ + char text[MENU_MAX+1]; /* To be displayed in menu */ + MENUCOMMANDTYPE cmd; /* What should it do? */ + char param[PARAM_MAX+1]; /* Any parameters? */ + unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ +} MENUITEM; + +/* A completely read in menu... */ +typedef struct MENUPARSED +{ + char menuName[MENU_MAX+1]; /* What's it called in the text? */ + MENUITEM *menuItem; /* Array of items */ + int menuItems; /* How big's the array? */ +} MENUPARSED; + +/* To map between a window and a system menu to add for it */ +typedef struct SYSMENUITEM +{ + char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ + char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ + MENUPOSITION menuPos; /* Where to place it (ignored in root) */ +} SYSMENUITEM; + +/* To redefine icons for certain window types */ +typedef struct ICONITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ + HICON hicon; /* LoadImage() result */ +} ICONITEM; + +/* To redefine styles for certain window types */ +typedef struct STYLEITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + unsigned long type; /* What should it do? */ +} STYLEITEM; + +typedef struct WINPREFS +{ + /* Menu information */ + MENUPARSED *menu; /* Array of created menus */ + int menuItems; /* How big? */ + + /* Taskbar menu settings */ + char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */ + + /* System menu addition menus */ + SYSMENUITEM *sysMenu; + int sysMenuItems; + + /* Which menu to add to unmatched windows? */ + char defaultSysMenuName[MENU_MAX+1]; + MENUPOSITION defaultSysMenuPos; /* Where to place it */ + + /* Icon information */ + char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */ + char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */ + char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */ + + ICONITEM *icon; + int iconItems; + + STYLEITEM *style; + int styleItems; + + /* Force exit flag */ + Bool fForceExit; + + /* Silent exit flag */ + Bool fSilentExit; + +} WINPREFS; + +/* The global pref settings structure loaded by the winprefyacc.y parser */ +extern WINPREFS pref; + + +/* Functions */ +void +LoadPreferences(void); + +void +SetupRootMenu (unsigned long hmenuRoot); + +void +SetupSysMenu (unsigned long hwndIn); + +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn); + +Bool +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command); + +int +winIconIsOverride (unsigned hiconIn); + +HICON +winOverrideIcon (unsigned long longpWin); + +unsigned long +winOverrideStyle (char *res_name, char *res_class, char *wmName); + +HICON +winTaskbarIcon(void); + +HICON +winOverrideDefaultIcon(int size); +#endif diff --git a/xorg-server/hw/xwin/winscrinit.c b/xorg-server/hw/xwin/winscrinit.c index 691237e6f..983ff5730 100644 --- a/xorg-server/hw/xwin/winscrinit.c +++ b/xorg-server/hw/xwin/winscrinit.c @@ -220,6 +220,10 @@ winScreenInit (int index, if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) { ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); + + /* call the engine dependent screen close procedure to clean up from a failure */ + pScreenPriv->pwinCloseScreen(index, pScreen); + return FALSE; } diff --git a/xorg-server/hw/xwin/winshaddd.c b/xorg-server/hw/xwin/winshaddd.c index 00d7a379f..6dad2782f 100644 --- a/xorg-server/hw/xwin/winshaddd.c +++ b/xorg-server/hw/xwin/winshaddd.c @@ -728,7 +728,8 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); winFreeFBShadowDD(pScreen); diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index 0a0b4ae13..63d48adb6 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -802,7 +802,8 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); winFreeFBShadowDDNL(pScreen); diff --git a/xorg-server/hw/xwin/winshadgdi.c b/xorg-server/hw/xwin/winshadgdi.c index 499037656..1e7cb006c 100644 --- a/xorg-server/hw/xwin/winshadgdi.c +++ b/xorg-server/hw/xwin/winshadgdi.c @@ -636,7 +636,8 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); diff --git a/xorg-server/hw/xwin/winvideo.c b/xorg-server/hw/xwin/winvideo.c index 998a3face..ed205448d 100644 --- a/xorg-server/hw/xwin/winvideo.c +++ b/xorg-server/hw/xwin/winvideo.c @@ -1,210 +1,208 @@ -/*
- *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from Harold L Hunt II.
- *
- * Authors: Harold L Hunt II
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-
-void
-winInitVideo (ScreenPtr pScreen);
-
-/*
- * winInitVideo - Initialize support for the X Video (Xv) Extension.
- */
-
-void
-winInitVideo (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
- if (pScreenInfo->dwBPP > 8)
- {
-
- }
-
-
-}
-
-
-
-
-
-
-
-#if 0
-#include "../xfree86/common/xf86.h"
-#include "../Xext/xvdix.h"
-#include "../xfree86/common/xf86xv.h"
-#include <X11/extensions/Xv.h>
-#endif
-
-#include "win.h"
-
-
-
-#if 0
-/* client libraries expect an encoding */
-static XF86VideoEncodingRec DummyEncoding[1] =
-{
- {
- 0,
- "XV_IMAGE",
- IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
- {1, 1}
- }
-};
-
-#define NUM_FORMATS 3
-
-static XF86VideoFormatRec Formats[NUM_FORMATS] =
-{
- {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
-};
-
-#define NUM_ATTRIBUTES 3
-
-static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
-{
- {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
- {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
-};
-
-#define NUM_IMAGES 4
-
-static XF86ImageRec Images[NUM_IMAGES] =
-{
- XVIMAGE_YUY2,
- XVIMAGE_YV12,
- XVIMAGE_I420,
- XVIMAGE_UYVY
-};
-
-
-
-/*
- * winInitVideo - Initialize support for the X Video (Xv) Extension.
- */
-
-void
-winInitVideo (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- XF86VideoAdaptorPtr newAdaptor = NULL;
-
- if (pScreenInfo->dwBPP > 8)
- {
- newAdaptor = I810SetupImageVideo (pScreen);
- I810InitOffscreenImages (pScreen);
- }
-
- xf86XVScreenInit (pScreen, adaptors, 1);
-}
-
-
-static XF86VideoAdaptorPtr
-winSetupImageVideo (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-#if 0
- I810Ptr pI810 = I810PTR(pScrn);
-#endif
- XF86VideoAdaptorPtr adapt;
-
- if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec))))
- return NULL;
-
- adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- adapt->name = PROJECT_NAME " Video Overlay";
- adapt->nEncodings = 1;
- adapt->pEncodings = DummyEncoding;
- adapt->nFormats = NUM_FORMATS;
- adapt->pFormats = Formats;
- adapt->nPorts = 1;
- adapt->pPortPrivates = NULL;
-
- adapt->pPortPrivates[0].ptr = NULL;
- adapt->pAttributes = Attributes;
- adapt->nImages = NUM_IMAGES;
- adapt->nAttributes = NUM_ATTRIBUTES;
- adapt->pImages = Images;
- adapt->PutVideo = NULL;
- adapt->PutStill = NULL;
- adapt->GetVideo = NULL;
- adapt->GetStill = NULL;
-#if 0
- adapt->StopVideo = I810StopVideo;
- adapt->SetPortAttribute = I810SetPortAttribute;
- adapt->GetPortAttribute = I810GetPortAttribute;
- adapt->QueryBestSize = I810QueryBestSize;
- adapt->PutImage = I810PutImage;
- adapt->QueryImageAttributes = I810QueryImageAttributes;
-#endif
-
-#if 0
- pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1);
-#endif
- pPriv->videoStatus = 0;
- pPriv->brightness = 0;
- pPriv->contrast = 64;
- pPriv->linear = NULL;
- pPriv->currentBuf = 0;
-
-#if 0
- /* gotta uninit this someplace */
- RegionNull(&pPriv->clip);
-#endif
-
-#if 0
- pI810->adaptor = adapt;
-
- pI810->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = I810BlockHandler;
-#endif
-
-#if 0
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
-#endif
-
-#if 0
- I810ResetVideo(pScrn);
-#endif
-
- return adapt;
-}
-#endif
+/* + *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> + +void +winInitVideo (ScreenPtr pScreen); + +/* + * winInitVideo - Initialize support for the X Video (Xv) Extension. + */ + +void +winInitVideo (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + if (pScreenInfo->dwBPP > 8) + { + + } + + +} + + + + + + + +#if 0 +#include "../xfree86/common/xf86.h" +#include "../Xext/xvdix.h" +#include "../xfree86/common/xf86xv.h" +#include <X11/extensions/Xv.h> +#endif + + + +#if 0 +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 3 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} +}; + +#define NUM_IMAGES 4 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + XVIMAGE_UYVY +}; + + + +/* + * winInitVideo - Initialize support for the X Video (Xv) Extension. + */ + +void +winInitVideo (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + XF86VideoAdaptorPtr newAdaptor = NULL; + + if (pScreenInfo->dwBPP > 8) + { + newAdaptor = I810SetupImageVideo (pScreen); + I810InitOffscreenImages (pScreen); + } + + xf86XVScreenInit (pScreen, adaptors, 1); +} + + +static XF86VideoAdaptorPtr +winSetupImageVideo (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#if 0 + I810Ptr pI810 = I810PTR(pScrn); +#endif + XF86VideoAdaptorPtr adapt; + + if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = PROJECT_NAME " Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = NULL; + + adapt->pPortPrivates[0].ptr = NULL; + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; +#if 0 + adapt->StopVideo = I810StopVideo; + adapt->SetPortAttribute = I810SetPortAttribute; + adapt->GetPortAttribute = I810GetPortAttribute; + adapt->QueryBestSize = I810QueryBestSize; + adapt->PutImage = I810PutImage; + adapt->QueryImageAttributes = I810QueryImageAttributes; +#endif + +#if 0 + pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1); +#endif + pPriv->videoStatus = 0; + pPriv->brightness = 0; + pPriv->contrast = 64; + pPriv->linear = NULL; + pPriv->currentBuf = 0; + +#if 0 + /* gotta uninit this someplace */ + RegionNull(&pPriv->clip); +#endif + +#if 0 + pI810->adaptor = adapt; + + pI810->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = I810BlockHandler; +#endif + +#if 0 + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); +#endif + +#if 0 + I810ResetVideo(pScrn); +#endif + + return adapt; +} +#endif diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index 5049e40b5..8f9917a7b 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -1,1070 +1,1070 @@ -/*
- *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
- * Earle F. Philhower, III
- * Harold L Hunt II
- */
-/*
- * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c
- */
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include <winuser.h>
-#define _WINDOWSWM_SERVER_
-#include <X11/extensions/windowswmstr.h>
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-#include <X11/Xatom.h>
-
-
-/*
- * Constant defines
- */
-
-#ifndef ULW_COLORKEY
-#define ULW_COLORKEY 0x00000001
-#endif
-#ifndef ULW_ALPHA
-#define ULW_ALPHA 0x00000002
-#endif
-#ifndef ULW_OPAQUE
-#define ULW_OPAQUE 0x00000004
-#endif
-#define AC_SRC_ALPHA 0x01
-
-/*
- * Local function
- */
-
-DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND)
-static void
-winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame);
-
-/*
- * Global variables
- */
-
-Bool g_fNoConfigureWindow = FALSE;
-
-/*
- * Internal function to get the DIB format that is compatible with the screen
- * Fixme: Share code with winshadgdi.c
- */
-
-static
-Bool
-winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih)
-{
- HBITMAP hbmp;
-#if CYGMULTIWINDOW_DEBUG
- LPDWORD pdw = NULL;
-#endif
-
- /* Create a memory bitmap compatible with the screen */
- hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1);
- if (hbmp == NULL)
- {
- ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n");
- return FALSE;
- }
-
- /* Initialize our bitmap info header */
- ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
- pbmih->biSize = sizeof (BITMAPINFOHEADER);
-
- /* Get the biBitCount */
- if (!GetDIBits (pRLWinPriv->hdcScreen,
- hbmp,
- 0, 1,
- NULL,
- (BITMAPINFO*) pbmih,
- DIB_RGB_COLORS))
- {
- ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n");
- DeleteObject (hbmp);
- return FALSE;
- }
-
-#if CYGMULTIWINDOW_DEBUG
- /* Get a pointer to bitfields */
- pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
-
- winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n",
- (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
-#endif
-
- /* Get optimal color table, or the optimal bitfields */
- if (!GetDIBits (pRLWinPriv->hdcScreen,
- hbmp,
- 0, 1,
- NULL,
- (BITMAPINFO*)pbmih,
- DIB_RGB_COLORS))
- {
- ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits "
- "failed\n");
- DeleteObject (hbmp);
- return FALSE;
- }
-
- /* Free memory */
- DeleteObject (hbmp);
-
- return TRUE;
-}
-
-static HRGN
-winMWExtWMCreateRgnFromRegion (RegionPtr pShape)
-{
- int nRects;
- BoxPtr pRects, pEnd;
- HRGN hRgn, hRgnRect;
-
- if (pShape == NULL) return NULL;
-
- nRects = RegionNumRects(pShape);
- pRects = RegionRects(pShape);
-
- hRgn = CreateRectRgn (0, 0, 0, 0);
- if (hRgn == NULL)
- {
- ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
- "failed: %d\n",
- 0, 0, 0, 0, (int) GetLastError ());
- }
-
- /* Loop through all rectangles in the X region */
- for (pEnd = pRects + 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 - Loop CreateRectRgn (%d, %d, %d, %d) "
- "failed: %d\n",
- pRects->x1,
- pRects->y1,
- pRects->x2,
- pRects->y2,
- (int) GetLastError ());
- }
-
- /* Merge the Windows region with the accumulated region */
- if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
- {
- ErrorF ("winReshape - CombineRgn () failed: %d\n",
- (int) GetLastError ());
- }
-
- /* Delete the temporary Windows region */
- DeleteObject (hRgnRect);
- }
-
- return hRgn;
-}
-
-static void
-InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv)
-{
- pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd);
- pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen);
- pRLWinPriv->hbmpShadow = NULL;
-
- /* Allocate bitmap info header */
- pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
- + 256 * sizeof (RGBQUAD));
- if (pRLWinPriv->pbmihShadow == NULL)
- {
- ErrorF ("InitWin32RootlessEngine - malloc () failed\n");
- return;
- }
-
- /* Query the screen format */
- winMWExtWMQueryDIBFormat (pRLWinPriv,
- pRLWinPriv->pbmihShadow);
-}
-
-Bool
-winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape)
-{
-#define CLASS_NAME_LENGTH 512
- Bool fResult = TRUE;
- win32RootlessWindowPtr pRLWinPriv;
- WNDCLASSEX wc;
- char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
- HICON hIcon;
- HICON hIconSmall;
- char *res_name, *res_class, *res_role;
- static int s_iWindowID = 0;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n",
- newX, newY, pFrame->width, pFrame->height);
-#endif
-
- pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec));
- pRLWinPriv->pFrame = pFrame;
- pRLWinPriv->pfb = NULL;
- pRLWinPriv->hbmpShadow = NULL;
- pRLWinPriv->hdcShadow = NULL;
- pRLWinPriv->hdcScreen = NULL;
- pRLWinPriv->pbmihShadow = NULL;
- pRLWinPriv->fResized = TRUE;
- pRLWinPriv->fClose = FALSE;
- pRLWinPriv->fRestackingNow = FALSE;
- pRLWinPriv->fDestroyed = FALSE;
- pRLWinPriv->fMovingOrSizing = FALSE;
-
- // Store the implementation private frame ID
- pFrame->wid = (RootlessFrameID) pRLWinPriv;
-
- winSelectIcons(pFrame->win, &hIcon, &hIconSmall);
-
- /* Set standard class name prefix so we can identify window easily */
- strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass));
-
- if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class))
- {
- strncat (pszClass, "-", 1);
- strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
- strncat (pszClass, "-", 1);
- strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
-
- /* Check if a window class is provided by the WM_WINDOW_ROLE property,
- * if not use the WM_CLASS information.
- * For further information see:
- * http://tronche.com/gui/x/icccm/sec-5.html
- */
- if (winMultiWindowGetWindowRole (pFrame->win, &res_role) )
- {
- strcat (pszClass, "-");
- strcat (pszClass, res_role);
- free (res_role);
- }
-
- free (res_name);
- free (res_class);
- }
-
- /* Add incrementing window ID to make unique class name */
- snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
- pszWindowID[sizeof(pszWindowID)-1] = 0;
- strcat (pszClass, pszWindowID);
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
-#endif
-
- /* Setup our window class */
- wc.cbSize = sizeof(wc);
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = winMWExtWMWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = g_hInstance;
- wc.hIcon = hIcon;
- wc.hIconSm = hIconSmall;
- wc.hCursor = 0;
- wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = pszClass;
- RegisterClassEx (&wc);
-
- /* Create the window */
- g_fNoConfigureWindow = TRUE;
- pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
- pszClass, /* Class name */
- WINDOW_TITLE_X, /* Window name */
- WS_POPUP | WS_CLIPCHILDREN,
- newX, /* Horizontal position */
- newY, /* Vertical position */
- pFrame->width, /* Right edge */
- pFrame->height, /* Bottom edge */
- (HWND) NULL, /* No parent or owner window */
- (HMENU) NULL, /* No menu */
- GetModuleHandle (NULL), /* Instance handle */
- pRLWinPriv); /* ScreenPrivates */
- if (pRLWinPriv->hWnd == NULL)
- {
- ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n",
- (int) GetLastError ());
- fResult = FALSE;
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCreateFrame - ShowWindow\n");
-#endif
-
- //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
- g_fNoConfigureWindow = FALSE;
-
- if (pShape != NULL)
- {
- winMWExtWMReshapeFrame (pFrame->wid, pShape);
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n",
- (int) pFrame->wid, (int) pRLWinPriv->hWnd);
-#if 0
- {
- WindowPtr pWin2 = NULL;
- win32RootlessWindowPtr pRLWinPriv2 = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
- {
- pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
- }
- winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n",
- pRLWinPriv2, pRLWinPriv2->hWnd);
- if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
- {
- winDebug ("Error param missmatch\n");
- }
- }
-#endif
-#endif
-
- winMWExtWMSetNativeProperty (pFrame);
-
- return fResult;
-}
-
-void
-winMWExtWMDestroyFrame (RootlessFrameID wid)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- HICON hiconClass;
- HICON hiconSmClass;
- HMODULE hInstance;
- int iReturn;
- char pszClass[CLASS_NAME_LENGTH];
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n",
- (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
-#if 0
- {
- WindowPtr pWin2 = NULL;
- win32RootlessWindowPtr pRLWinPriv2 = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
- {
- pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
- }
- winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n",
- pRLWinPriv2, pRLWinPriv2->hWnd);
- if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
- {
- winDebug ("Error param missmatch\n");
- *(int*)0 = 1;//raise exseption
- }
- }
-#endif
-#endif
-
- /* Store the info we need to destroy after this window is gone */
- hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE);
- hiconClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICON);
- hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICONSM);
- iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH);
-
- pRLWinPriv->fClose = TRUE;
- pRLWinPriv->fDestroyed = TRUE;
-
- /* Destroy the Windows window */
- DestroyWindow (pRLWinPriv->hWnd);
-
- /* Only if we were able to get the name */
- if (iReturn)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass);
-#endif
- iReturn = UnregisterClass (pszClass, hInstance);
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn);
-#endif
-
- winDestroyIcon(hiconClass);
- winDestroyIcon(hiconSmClass);
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFrame - done\n");
-#endif
-}
-
-void
-winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- RECT rcNew;
- DWORD dwExStyle;
- DWORD dwStyle;
- int iX, iY, iWidth, iHeight;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY);
-#endif
-
- /* Get the Windows window style and extended style */
- dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
-
- /* Get the X and Y location of the X window */
- iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pRLWinPriv->pFrame->width;
- iHeight = pRLWinPriv->pFrame->height;
-
- /* Store the origin, height, and width in a rectangle structure */
- SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- /*
- * Calculate the required size of the Windows window rectangle,
- * given the size of the Windows window client area.
- */
- AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- g_fNoConfigureWindow = TRUE;
- SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
- g_fNoConfigureWindow = FALSE;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv);
-#endif
-}
-
-void
-winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
- int iNewX, int iNewY,
- unsigned int uiNewWidth, unsigned int uiNewHeight,
- unsigned int uiGravity)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- RECT rcNew;
- RECT rcOld;
- DWORD dwExStyle;
- DWORD dwStyle;
- int iX, iY;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n",
- (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
-#endif
-
- pRLWinPriv->fResized = TRUE;
-
- /* Get the Windows window style and extended style */
- dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
-
- /* Get the X and Y location of the X window */
- iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Store the origin, height, and width in a rectangle structure */
- SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight);
-
- /*
- * 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 (pRLWinPriv->hWnd, &rcOld);
-
- /* Check if the old rectangle and new rectangle are the same */
- if (!EqualRect (&rcNew, &rcOld))
- {
-
- g_fNoConfigureWindow = TRUE;
- MoveWindow (pRLWinPriv->hWnd,
- rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- TRUE);
- g_fNoConfigureWindow = FALSE;
- }
-}
-
-void
-winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
- winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
- winScreenInfo *pScreenInfo = NULL;
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
- HWND hWnd;
- Bool fFirst = TRUE;
- Bool fNeedRestack = TRUE;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv);
-#endif
-
- if (pScreenPriv->fRestacking) return;
-
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
-
- pRLWinPriv->fRestackingNow = TRUE;
-
- /* Show window */
- if(!IsWindowVisible (pRLWinPriv->hWnd))
- ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
-
- if (pRLNextWinPriv == NULL)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x is top\n", pRLWinPriv);
-#endif
- pScreenPriv->widTop = wid;
- SetWindowPos (pRLWinPriv->hWnd, HWND_TOP,
- 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- }
- else if (winIsInternalWMRunning(pScreenInfo))
- {
- /* using mulwinidow wm */
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x is not top\n", pRLWinPriv);
-#endif
- for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV);
- fNeedRestack && hWnd != NULL;
- hWnd = GetNextWindow (hWnd, GW_HWNDPREV))
- {
- GetWindowThreadProcessId (hWnd, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hWnd, WIN_WINDOW_PROP))
- {
- if (hWnd == pRLNextWinPriv->hWnd)
- {
- /* Enable interleave X window and Windows window */
- if (!fFirst)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv);
-#endif
- SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
- 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("No change\n");
-#endif
- }
- fNeedRestack = FALSE;
- break;
- }
- if (fFirst) fFirst = FALSE;
- }
- }
-
- for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT);
- fNeedRestack && hWnd != NULL;
- hWnd = GetNextWindow (hWnd, GW_HWNDNEXT))
- {
- GetWindowThreadProcessId (hWnd, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hWnd, WIN_WINDOW_PROP))
- {
- if (hWnd == pRLNextWinPriv->hWnd)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv);
-#endif
- SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
- 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- fNeedRestack = FALSE;
- break;
- }
- }
- }
- }
- else
- {
- /* using general wm like twm, wmaker etc.
- Interleave X window and Windows window will cause problem. */
- SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
- 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
-#if 0
-#endif
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv);
-#endif
-
- pRLWinPriv->fRestackingNow = FALSE;
-}
-
-void
-winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- HRGN hRgn, hRgnWindow, hRgnClient;
- RECT rcWindow, rcClient;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv);
-#endif
-
- hRgn = winMWExtWMCreateRgnFromRegion (pShape);
-
- /* Create region for non-client area */
- GetWindowRect (pRLWinPriv->hWnd, &rcWindow);
- GetClientRect (pRLWinPriv->hWnd, &rcClient);
- MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
- OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top);
- OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top);
- OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
- hRgnWindow = CreateRectRgnIndirect (&rcWindow);
- hRgnClient = CreateRectRgnIndirect (&rcClient);
- CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF);
- CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR);
-
-
- SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE);
-
- DeleteObject (hRgnWindow);
- DeleteObject (hRgnClient);
-}
-
-void
-winMWExtWMUnmapFrame (RootlessFrameID wid)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv);
-#endif
-
- g_fNoConfigureWindow = TRUE;
- //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
- ShowWindow (pRLWinPriv->hWnd, SW_HIDE);
- g_fNoConfigureWindow = FALSE;
-}
-
-/*
- * Fixme: Code sharing with winshadgdi.c and other engine support
- */
-void
-winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- winPrivScreenPtr pScreenPriv = NULL;
- winScreenInfo *pScreenInfo = NULL;
- ScreenPtr pScreen = NULL;
- DIBSECTION dibsection;
- Bool fReturn = TRUE;
- HDC hdcNew;
- HBITMAP hbmpNew;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed);
-#endif
-
- if (!pRLWinPriv->fDestroyed)
- {
- pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
- if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv);
- winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo);
- winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width,
- (int) pRLWinPriv->pFrame->height);
-#endif
- if (pRLWinPriv->hdcScreen == NULL)
- {
- InitWin32RootlessEngine (pRLWinPriv);
- }
-
- if (pRLWinPriv->fResized)
- {
- /* width * bpp must be multiple of 4 to match 32bit alignment */
- int stridesize;
- int misalignment;
-
- pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;
- pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;
-
- stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3);
- misalignment = stridesize & 3;
- if (misalignment != 0)
- {
- stridesize += 4 - misalignment;
- pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3);
- winDebug("\tresizing to %d (was %d)\n",
- pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width);
- }
-
- hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen);
- /* Create a DI shadow bitmap with a bit pointer */
- hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen,
- (BITMAPINFO *) pRLWinPriv->pbmihShadow,
- DIB_RGB_COLORS,
- (VOID**) &pRLWinPriv->pfb,
- NULL,
- 0);
- if (hbmpNew == NULL || pRLWinPriv->pfb == NULL)
- {
- ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n");
- //return FALSE;
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n");
-#endif
- }
-
- /* Get information about the bitmap that was allocated */
- GetObject (hbmpNew, sizeof (dibsection), &dibsection);
-
-#if CYGMULTIWINDOW_DEBUG
- /* Print information about bitmap allocated */
- winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d "
- "depth: %d size image: %d\n",
- (unsigned int)dibsection.dsBmih.biWidth,
- (unsigned int)dibsection.dsBmih.biHeight,
- (unsigned int)dibsection.dsBmih.biBitCount,
- (unsigned int)dibsection.dsBmih.biSizeImage);
-#endif
-
- /* Select the shadow bitmap into the shadow DC */
- SelectObject (hdcNew, hbmpNew);
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n");
-#endif
-
- /* Blit from the old shadow to the new shadow */
- fReturn = BitBlt (hdcNew,
- 0, 0,
- pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height,
- pRLWinPriv->hdcShadow,
- 0, 0,
- SRCCOPY);
- if (fReturn)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - Shadow blit success\n");
-#endif
- }
- else
- {
- ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n");
- }
-
- /* Look for height weirdness */
- if (dibsection.dsBmih.biHeight < 0)
- {
- /* FIXME: Figure out why biHeight is sometimes negative */
- ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - "
- "biHeight still negative: %d\n",
- (int) dibsection.dsBmih.biHeight);
- ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - "
- "Flipping biHeight sign\n");
- dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
- }
-
- pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n",
- (unsigned int)dibsection.dsBm.bmWidthBytes);
-#endif
-
- /* Free the old shadow bitmap */
- DeleteObject (pRLWinPriv->hdcShadow);
- DeleteObject (pRLWinPriv->hbmpShadow);
-
- pRLWinPriv->hdcShadow = hdcNew;
- pRLWinPriv->hbmpShadow = hbmpNew;
-
- pRLWinPriv->fResized = FALSE;
-#if CYGMULTIWINDOW_DEBUG && FALSE
- winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n",
- (unsigned int)pRLWinPriv->pfb,
- (unsigned int)dibsection.dsBm.bmWidthBytes);
-#endif
- }
- }
- else
- {
- ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n");
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n",
- (int) pRLWinPriv,
- (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes);
-#endif
- *pixelData = pRLWinPriv->pfb;
- *bytesPerRow = pRLWinPriv->dwWidthBytes;
-}
-
-void
-winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush)
-{
-#if 0
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- BLENDFUNCTION bfBlend;
- SIZE szWin;
- POINT ptSrc;
-#if CYGMULTIWINDOW_DEBUG || TRUE
- winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv);
-#endif
- szWin.cx = pRLWinPriv->dwWidth;
- szWin.cy = pRLWinPriv->dwHeight;
- ptSrc.x = 0;
- ptSrc.y = 0;
- bfBlend.BlendOp = AC_SRC_OVER;
- bfBlend.BlendFlags = 0;
- bfBlend.SourceConstantAlpha = 255;
- bfBlend.AlphaFormat = AC_SRC_ALPHA;
-
- if (!UpdateLayeredWindow (pRLWinPriv->hWnd,
- NULL, NULL, &szWin,
- pRLWinPriv->hdcShadow, &ptSrc,
- 0, &bfBlend, ULW_ALPHA))
- {
- ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
- }
-#endif
-}
-
-void
-winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
-#if 0
- BLENDFUNCTION bfBlend;
- SIZE szWin;
- POINT ptSrc;
-#endif
-#if CYGMULTIWINDOW_DEBUG && 0
- winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv);
-#endif
-#if 0
- szWin.cx = pRLWinPriv->dwWidth;
- szWin.cy = pRLWinPriv->dwHeight;
- ptSrc.x = 0;
- ptSrc.y = 0;
- bfBlend.BlendOp = AC_SRC_OVER;
- bfBlend.BlendFlags = 0;
- bfBlend.SourceConstantAlpha = 255;
- bfBlend.AlphaFormat = AC_SRC_ALPHA;
-
- if (!UpdateLayeredWindow (pRLWinPriv->hWnd,
- NULL, NULL, &szWin,
- pRLWinPriv->hdcShadow, &ptSrc,
- 0, &bfBlend, ULW_ALPHA))
- {
- LPVOID lpMsgBuf;
-
- /* Display a fancy error message */
- FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError (),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
-
- ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
- (LPSTR)lpMsgBuf);
- LocalFree (lpMsgBuf);
- }
-#endif
- if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd);
-}
-
-void
-winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects,
- int shift_x, int shift_y)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- const BoxRec *pEnd;
-#if CYGMULTIWINDOW_DEBUG && 0
- winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
- pRLWinPriv, nCount, pRects, shift_x, shift_y);
-#endif
-
- for (pEnd = pRects + nCount; pRects < pEnd; pRects++) {
- RECT rcDmg;
- rcDmg.left = pRects->x1 + shift_x;
- rcDmg.top = pRects->y1 + shift_y;
- rcDmg.right = pRects->x2 + shift_x;
- rcDmg.bottom = pRects->y2 + shift_y;
-
- InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE);
- }
-}
-
-void
-winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n",
- (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
-#endif
- pRLWinPriv->pFrame = pFrame;
- pRLWinPriv->fResized = TRUE;
-
- /* Set the window extended style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
-
- /* Set the window standard style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
- WS_POPUP | WS_CLIPCHILDREN);
-
- DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ());
- winMWExtWMSetNativeProperty (pFrame);
-#if CYGMULTIWINDOW_DEBUG
-#if 0
- {
- WindowPtr pWin2 = NULL;
- win32RootlessWindowPtr pRLWinPriv2 = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
- {
- pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
- }
- winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n",
- pRLWinPriv2, pRLWinPriv2->hWnd);
- if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
- {
- winDebug ("Error param missmatch\n");
- }
- }
-#endif
-#endif
-}
-
-void
-winMWExtWMCopyBytes (unsigned int width, unsigned int height,
- const void *src, unsigned int srcRowBytes,
- void *dst, unsigned int dstRowBytes)
-{
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCopyBytes - Not implemented\n");
-#endif
-}
-
-void
-winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects,
- int nDx, int nDy)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- const BoxRec *pEnd;
- RECT rcDmg;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n",
- (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy);
-#endif
-
- for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n",
- pDstRects->x1, pDstRects->y1,
- pDstRects->x2 - pDstRects->x1,
- pDstRects->y2 - pDstRects->y1,
- pDstRects->x1 + nDx,
- pDstRects->y1 + nDy);
-#endif
-
- if (!BitBlt (pRLWinPriv->hdcShadow,
- pDstRects->x1, pDstRects->y1,
- pDstRects->x2 - pDstRects->x1,
- pDstRects->y2 - pDstRects->y1,
- pRLWinPriv->hdcShadow,
- pDstRects->x1 + nDx, pDstRects->y1 + nDy,
- SRCCOPY))
- {
- ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n");
- }
-
- rcDmg.left = pDstRects->x1;
- rcDmg.top = pDstRects->y1;
- rcDmg.right = pDstRects->x2;
- rcDmg.bottom = pDstRects->y2;
-
- InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE);
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCopyWindow - done\n");
-#endif
-}
-
-
-/*
- * winMWExtWMSetNativeProperty
- */
-
-static void
-winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
- long lData;
-
- /* FIXME: move this to WindowsWM extension */
-
- lData = (long) pRLWinPriv->hWnd;
- dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
- XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
-}
+/* + *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 + * Earle F. Philhower, III + * Harold L Hunt II + */ +/* + * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c + */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <winuser.h> +#define _WINDOWSWM_SERVER_ +#include <X11/extensions/windowswmstr.h> +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include <X11/Xatom.h> + + +/* + * Constant defines + */ + +#ifndef ULW_COLORKEY +#define ULW_COLORKEY 0x00000001 +#endif +#ifndef ULW_ALPHA +#define ULW_ALPHA 0x00000002 +#endif +#ifndef ULW_OPAQUE +#define ULW_OPAQUE 0x00000004 +#endif +#define AC_SRC_ALPHA 0x01 + +/* + * Local function + */ + +DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND) +static void +winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame); + +/* + * Global variables + */ + +Bool g_fNoConfigureWindow = FALSE; + +/* + * Internal function to get the DIB format that is compatible with the screen + * Fixme: Share code with winshadgdi.c + */ + +static +Bool +winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih) +{ + HBITMAP hbmp; +#if CYGMULTIWINDOW_DEBUG + LPDWORD pdw = NULL; +#endif + + /* Create a memory bitmap compatible with the screen */ + hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1); + if (hbmp == NULL) + { + ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n"); + return FALSE; + } + + /* Initialize our bitmap info header */ + ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + pbmih->biSize = sizeof (BITMAPINFOHEADER); + + /* Get the biBitCount */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*) pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n"); + DeleteObject (hbmp); + return FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + + winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n", + (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); +#endif + + /* Get optimal color table, or the optimal bitfields */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*)pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits " + "failed\n"); + DeleteObject (hbmp); + return FALSE; + } + + /* Free memory */ + DeleteObject (hbmp); + + return TRUE; +} + +static HRGN +winMWExtWMCreateRgnFromRegion (RegionPtr pShape) +{ + int nRects; + BoxPtr pRects, pEnd; + HRGN hRgn, hRgnRect; + + if (pShape == NULL) return NULL; + + nRects = RegionNumRects(pShape); + pRects = RegionRects(pShape); + + hRgn = CreateRectRgn (0, 0, 0, 0); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, 0, 0, (int) GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pEnd = pRects + 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 - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2, + (int) GetLastError ()); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + (int) GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + return hRgn; +} + +static void +InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv) +{ + pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd); + pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen); + pRLWinPriv->hbmpShadow = NULL; + + /* Allocate bitmap info header */ + pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pRLWinPriv->pbmihShadow == NULL) + { + ErrorF ("InitWin32RootlessEngine - malloc () failed\n"); + return; + } + + /* Query the screen format */ + winMWExtWMQueryDIBFormat (pRLWinPriv, + pRLWinPriv->pbmihShadow); +} + +Bool +winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape) +{ +#define CLASS_NAME_LENGTH 512 + Bool fResult = TRUE; + win32RootlessWindowPtr pRLWinPriv; + WNDCLASSEX wc; + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + HICON hIcon; + HICON hIconSmall; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n", + newX, newY, pFrame->width, pFrame->height); +#endif + + pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec)); + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->pfb = NULL; + pRLWinPriv->hbmpShadow = NULL; + pRLWinPriv->hdcShadow = NULL; + pRLWinPriv->hdcScreen = NULL; + pRLWinPriv->pbmihShadow = NULL; + pRLWinPriv->fResized = TRUE; + pRLWinPriv->fClose = FALSE; + pRLWinPriv->fRestackingNow = FALSE; + pRLWinPriv->fDestroyed = FALSE; + pRLWinPriv->fMovingOrSizing = FALSE; + + // Store the implementation private frame ID + pFrame->wid = (RootlessFrameID) pRLWinPriv; + + winSelectIcons(pFrame->win, &hIcon, &hIconSmall); + + /* Set standard class name prefix so we can identify window easily */ + strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass)); + + if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class)) + { + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); + + /* Check if a window class is provided by the WM_WINDOW_ROLE property, + * if not use the WM_CLASS information. + * For further information see: + * http://tronche.com/gui/x/icccm/sec-5.html + */ + if (winMultiWindowGetWindowRole (pFrame->win, &res_role) ) + { + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); + } + + free (res_name); + free (res_class); + } + + /* Add incrementing window ID to make unique class name */ + snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++); + pszWindowID[sizeof(pszWindowID)-1] = 0; + strcat (pszClass, pszWindowID); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass); +#endif + + /* Setup our window class */ + wc.cbSize = sizeof(wc); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winMWExtWMWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = hIcon; + wc.hIconSm = hIconSmall; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = pszClass; + RegisterClassEx (&wc); + + /* Create the window */ + g_fNoConfigureWindow = TRUE; + pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_POPUP | WS_CLIPCHILDREN, + newX, /* Horizontal position */ + newY, /* Vertical position */ + pFrame->width, /* Right edge */ + pFrame->height, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pRLWinPriv); /* ScreenPrivates */ + if (pRLWinPriv->hWnd == NULL) + { + ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + fResult = FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame - ShowWindow\n"); +#endif + + //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + g_fNoConfigureWindow = FALSE; + + if (pShape != NULL) + { + winMWExtWMReshapeFrame (pFrame->wid, pShape); + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n", + (int) pFrame->wid, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + } + } +#endif +#endif + + winMWExtWMSetNativeProperty (pFrame); + + return fResult; +} + +void +winMWExtWMDestroyFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HICON hIcon; + HICON hIconSm; + HMODULE hInstance; + int iReturn; + char pszClass[CLASS_NAME_LENGTH]; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + *(int*)0 = 1;//raise exseption + } + } +#endif +#endif + + /* Store the info we need to destroy after this window is gone */ + hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE); + hIcon = (HICON)SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0); + iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH); + + pRLWinPriv->fClose = TRUE; + pRLWinPriv->fDestroyed = TRUE; + + /* Destroy the Windows window */ + DestroyWindow (pRLWinPriv->hWnd); + + /* Only if we were able to get the name */ + if (iReturn) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass); +#endif + iReturn = UnregisterClass (pszClass, hInstance); + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFramew - Deleting Icon\n"); +#endif + + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame - done\n"); +#endif +} + +void +winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY, iWidth, iHeight; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY); +#endif + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pRLWinPriv->pFrame->width; + iHeight = pRLWinPriv->pFrame->height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + g_fNoConfigureWindow = TRUE; + SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); + g_fNoConfigureWindow = FALSE; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv); +#endif +} + +void +winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int iNewX, int iNewY, + unsigned int uiNewWidth, unsigned int uiNewHeight, + unsigned int uiGravity) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + RECT rcOld; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n", + (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight); +#endif + + pRLWinPriv->fResized = TRUE; + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight); + + /* + * 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 (pRLWinPriv->hWnd, &rcOld); + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { + + g_fNoConfigureWindow = TRUE; + MoveWindow (pRLWinPriv->hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + g_fNoConfigureWindow = FALSE; + } +} + +void +winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid; + winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen); + winScreenInfo *pScreenInfo = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + HWND hWnd; + Bool fFirst = TRUE; + Bool fNeedRestack = TRUE; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv); +#endif + + if (pScreenPriv->fRestacking) return; + + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + + pRLWinPriv->fRestackingNow = TRUE; + + /* Show window */ + if(!IsWindowVisible (pRLWinPriv->hWnd)) + ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + + if (pRLNextWinPriv == NULL) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is top\n", pRLWinPriv); +#endif + pScreenPriv->widTop = wid; + SetWindowPos (pRLWinPriv->hWnd, HWND_TOP, + 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else if (winIsInternalWMRunning(pScreenInfo)) + { + /* using mulwinidow wm */ +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is not top\n", pRLWinPriv); +#endif + for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV); + fNeedRestack && hWnd != NULL; + hWnd = GetNextWindow (hWnd, GW_HWNDPREV)) + { + GetWindowThreadProcessId (hWnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == pRLNextWinPriv->hWnd) + { + /* Enable interleave X window and Windows window */ + if (!fFirst) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv); +#endif + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("No change\n"); +#endif + } + fNeedRestack = FALSE; + break; + } + if (fFirst) fFirst = FALSE; + } + } + + for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT); + fNeedRestack && hWnd != NULL; + hWnd = GetNextWindow (hWnd, GW_HWNDNEXT)) + { + GetWindowThreadProcessId (hWnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == pRLNextWinPriv->hWnd) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv); +#endif + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + fNeedRestack = FALSE; + break; + } + } + } + } + else + { + /* using general wm like twm, wmaker etc. + Interleave X window and Windows window will cause problem. */ + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); +#if 0 +#endif + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv); +#endif + + pRLWinPriv->fRestackingNow = FALSE; +} + +void +winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HRGN hRgn, hRgnWindow, hRgnClient; + RECT rcWindow, rcClient; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv); +#endif + + hRgn = winMWExtWMCreateRgnFromRegion (pShape); + + /* Create region for non-client area */ + GetWindowRect (pRLWinPriv->hWnd, &rcWindow); + GetClientRect (pRLWinPriv->hWnd, &rcClient); + MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); + OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top); + OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top); + OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top); + hRgnWindow = CreateRectRgnIndirect (&rcWindow); + hRgnClient = CreateRectRgnIndirect (&rcClient); + CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF); + CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR); + + + SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE); + + DeleteObject (hRgnWindow); + DeleteObject (hRgnClient); +} + +void +winMWExtWMUnmapFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv); +#endif + + g_fNoConfigureWindow = TRUE; + //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE); + ShowWindow (pRLWinPriv->hWnd, SW_HIDE); + g_fNoConfigureWindow = FALSE; +} + +/* + * Fixme: Code sharing with winshadgdi.c and other engine support + */ +void +winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + ScreenPtr pScreen = NULL; + DIBSECTION dibsection; + Bool fReturn = TRUE; + HDC hdcNew; + HBITMAP hbmpNew; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed); +#endif + + if (!pRLWinPriv->fDestroyed) + { + pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv); + winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo); + winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width, + (int) pRLWinPriv->pFrame->height); +#endif + if (pRLWinPriv->hdcScreen == NULL) + { + InitWin32RootlessEngine (pRLWinPriv); + } + + if (pRLWinPriv->fResized) + { + /* width * bpp must be multiple of 4 to match 32bit alignment */ + int stridesize; + int misalignment; + + pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width; + pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height; + + stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3); + misalignment = stridesize & 3; + if (misalignment != 0) + { + stridesize += 4 - misalignment; + pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3); + winDebug("\tresizing to %d (was %d)\n", + pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width); + } + + hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen); + /* Create a DI shadow bitmap with a bit pointer */ + hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen, + (BITMAPINFO *) pRLWinPriv->pbmihShadow, + DIB_RGB_COLORS, + (VOID**) &pRLWinPriv->pfb, + NULL, + 0); + if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) + { + ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n"); + //return FALSE; + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n"); +#endif + } + + /* Get information about the bitmap that was allocated */ + GetObject (hbmpNew, sizeof (dibsection), &dibsection); + +#if CYGMULTIWINDOW_DEBUG + /* Print information about bitmap allocated */ + winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d " + "depth: %d size image: %d\n", + (unsigned int)dibsection.dsBmih.biWidth, + (unsigned int)dibsection.dsBmih.biHeight, + (unsigned int)dibsection.dsBmih.biBitCount, + (unsigned int)dibsection.dsBmih.biSizeImage); +#endif + + /* Select the shadow bitmap into the shadow DC */ + SelectObject (hdcNew, hbmpNew); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n"); +#endif + + /* Blit from the old shadow to the new shadow */ + fReturn = BitBlt (hdcNew, + 0, 0, + pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height, + pRLWinPriv->hdcShadow, + 0, 0, + SRCCOPY); + if (fReturn) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Shadow blit success\n"); +#endif + } + else + { + ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n"); + } + + /* Look for height weirdness */ + if (dibsection.dsBmih.biHeight < 0) + { + /* FIXME: Figure out why biHeight is sometimes negative */ + ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " + "biHeight still negative: %d\n", + (int) dibsection.dsBmih.biHeight); + ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " + "Flipping biHeight sign\n"); + dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; + } + + pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n", + (unsigned int)dibsection.dsBm.bmWidthBytes); +#endif + + /* Free the old shadow bitmap */ + DeleteObject (pRLWinPriv->hdcShadow); + DeleteObject (pRLWinPriv->hbmpShadow); + + pRLWinPriv->hdcShadow = hdcNew; + pRLWinPriv->hbmpShadow = hbmpNew; + + pRLWinPriv->fResized = FALSE; +#if CYGMULTIWINDOW_DEBUG && FALSE + winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n", + (unsigned int)pRLWinPriv->pfb, + (unsigned int)dibsection.dsBm.bmWidthBytes); +#endif + } + } + else + { + ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n"); + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n", + (int) pRLWinPriv, + (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes); +#endif + *pixelData = pRLWinPriv->pfb; + *bytesPerRow = pRLWinPriv->dwWidthBytes; +} + +void +winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush) +{ +#if 0 + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#if CYGMULTIWINDOW_DEBUG || TRUE + winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv); +#endif + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n"); + } +#endif +} + +void +winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if 0 + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#endif +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv); +#endif +#if 0 + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + LPVOID lpMsgBuf; + + /* Display a fancy error message */ + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } +#endif + if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); +} + +void +winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, + int shift_x, int shift_y) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n", + pRLWinPriv, nCount, pRects, shift_x, shift_y); +#endif + + for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { + RECT rcDmg; + rcDmg.left = pRects->x1 + shift_x; + rcDmg.top = pRects->y1 + shift_y; + rcDmg.right = pRects->x2 + shift_x; + rcDmg.bottom = pRects->y2 + shift_y; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +} + +void +winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#endif + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->fResized = TRUE; + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_CLIPCHILDREN); + + DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ()); + winMWExtWMSetNativeProperty (pFrame); +#if CYGMULTIWINDOW_DEBUG +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + } + } +#endif +#endif +} + +void +winMWExtWMCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes) +{ +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyBytes - Not implemented\n"); +#endif +} + +void +winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects, + int nDx, int nDy) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; + RECT rcDmg; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n", + (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); +#endif + + for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pDstRects->x1 + nDx, + pDstRects->y1 + nDy); +#endif + + if (!BitBlt (pRLWinPriv->hdcShadow, + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pRLWinPriv->hdcShadow, + pDstRects->x1 + nDx, pDstRects->y1 + nDy, + SRCCOPY)) + { + ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n"); + } + + rcDmg.left = pDstRects->x1; + rcDmg.top = pDstRects->y1; + rcDmg.right = pDstRects->x2; + rcDmg.bottom = pDstRects->y2; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyWindow - done\n"); +#endif +} + + +/* + * winMWExtWMSetNativeProperty + */ + +static void +winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; + long lData; + + /* FIXME: move this to WindowsWM extension */ + + lData = (long) pRLWinPriv->hWnd; + dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(), + XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); +} |