diff options
author | dawes <dawes> | 2003-07-29 21:25:15 +0000 |
---|---|---|
committer | dawes <dawes> | 2003-07-29 21:25:15 +0000 |
commit | 2ebdba10ab69cb5327231a3cc5e18f24659de94d (patch) | |
tree | 4a5fc61f8ab7f30cc9a047284f45baa85128210a | |
parent | 58e2e70eadfbe5727a98484fe8b86fb11eb7a823 (diff) |
333. Resync with Cygwin/XFree86 changes up to Test92 (#5721, Harold Hunt and
the Cygwin/XFree86 project).
34 files changed, 3587 insertions, 1342 deletions
diff --git a/programs/Xserver/hw/xwin/Imakefile b/programs/Xserver/hw/xwin/Imakefile index 0ac2d7f14..f3799eab9 100644 --- a/programs/Xserver/hw/xwin/Imakefile +++ b/programs/Xserver/hw/xwin/Imakefile @@ -45,17 +45,24 @@ SRCS = InitInput.c \ winregistry.c \ winconfig.c \ winmsg.c \ + winmultiwindowclass.c \ + winmultiwindowicons.c \ + winmultiwindowshape.c \ winmultiwindowwindow.c \ winmultiwindowwm.c \ + winmultiwindowwndproc.c \ winclipboardinit.c \ winclipboardtextconv.c \ winclipboardthread.c \ winclipboardunicode.c \ winclipboardwndproc.c \ - winclipboardxevents.c + winclipboardxevents.c \ + winvideo.c \ + wintrayicon.c \ + windialogs.c /* - * NOTE: The windialogs.rc file is compiled into windialogs.res. + * NOTE: The XWin.rc file is compiled into XWin.res. * This compiled-resource file must be directly linked into XWin.exe * by the commands in xc/programs/Xserver/Imakefile; it cannot be * linked into libXwin.a because it will not be correctly positioned @@ -98,14 +105,21 @@ OBJS = InitInput.o \ winregistry.o \ winconfig.o \ winmsg.o \ + winmultiwindowclass.o \ + winmultiwindowicons.o \ + winmultiwindowshape.o \ winmultiwindowwindow.o \ winmultiwindowwm.o \ + winmultiwindowwndproc.o \ winclipboardinit.o \ winclipboardtextconv.o \ winclipboardthread.o \ winclipboardunicode.o \ winclipboardwndproc.o \ - winclipboardxevents.o + winclipboardxevents.o \ + winvideo.o \ + wintrayicon.o \ + windialogs.o INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \ -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \ @@ -125,7 +139,7 @@ SpecialCObjectRule(stubs,$(ICONFIGFILES),$(EXT_DEFINES)) * Build the Windows resource file (contains the program icon, etc.) */ -ResourceObjectRule(XWin,,) +ResourceObjectRule(XWin,X.ico,) NormalLibraryObjectRule() NormalLibraryTarget(Xwin,$(OBJS)) diff --git a/programs/Xserver/hw/xwin/InitInput.c b/programs/Xserver/hw/xwin/InitInput.c index c7540dca9..92fb5c3e5 100644 --- a/programs/Xserver/hw/xwin/InitInput.c +++ b/programs/Xserver/hw/xwin/InitInput.c @@ -29,6 +29,7 @@ /* $XFree86: xc/programs/Xserver/hw/xwin/InitInput.c,v 1.11 2002/07/05 09:19:25 alanh Exp $ */ #include "win.h" +#include "../../Xext/xf86miscproc.h" CARD32 g_c32LastInputEventTime = 0; @@ -117,6 +118,34 @@ InitInput (int argc, char *argv[]) AddEnabledDevice (g_fdMessageQueue); } +#if 0 + { + MiscExtReturn ret; + pointer kbd; + +#if 0 + if ((kbd = MiscExtCreateStruct(MISC_KEYBOARD)) == (pointer) 0) + return BadAlloc; +#else + kbd = MiscExtCreateStruct (MISC_KEYBOARD); +#endif + + MiscExtSetKbdValue(kbd, MISC_KBD_TYPE, 0); + MiscExtSetKbdValue(kbd, MISC_KBD_RATE, 0); + MiscExtSetKbdValue(kbd, MISC_KBD_DELAY, 0); + MiscExtSetKbdValue(kbd, MISC_KBD_SERVNUMLOCK, 0); + + switch ((ret = MiscExtApply (kbd, MISC_KEYBOARD))) + { + case MISC_RET_SUCCESS: break; + case MISC_RET_BADVAL: + case MISC_RET_BADKBDTYPE: + default: + ErrorF ("Unexpected return from MiscExtApply(KEYBOARD) = %d\n", ret); + } + } +#endif + #if CYGDEBUG ErrorF ("InitInput - returning\n"); #endif diff --git a/programs/Xserver/hw/xwin/InitOutput.c b/programs/Xserver/hw/xwin/InitOutput.c index 4ef1b73ed..18a1e8fea 100644 --- a/programs/Xserver/hw/xwin/InitOutput.c +++ b/programs/Xserver/hw/xwin/InitOutput.c @@ -51,7 +51,9 @@ FILE *g_pfLog = NULL; DWORD g_dwEnginesSupported = 0; HINSTANCE g_hInstance = 0; HWND g_hDlgDepthChange = NULL; +HWND g_hDlgExit = NULL; Bool g_fCalledSetLocale = FALSE; +Bool g_fCalledXInitThreads = FALSE; /* @@ -151,6 +153,7 @@ winInitializeDefaultScreens (void) g_ScreenInfo[i].fClipboard = FALSE; g_ScreenInfo[i].fLessPointer = FALSE; g_ScreenInfo[i].fScrollbars = FALSE; + g_ScreenInfo[i].fNoTrayIcon = FALSE; g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF; g_ScreenInfo[i].dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) * 25.4; @@ -328,6 +331,12 @@ ddxUseMsg (void) "\tMoreover, if the window has decorations, one can now resize\n" "\tit.\n"); + ErrorF ("-[no]trayicon\n" + "\tDo not create a tray icon. Default is to create one\n" + "\ticon per screen. You can globally disable tray icons with\n" + "\t-notrayicon, then enable it for specific screens with\n" + "\t-trayicon for those screens.\n"); + ErrorF ("-clipupdates num_boxes\n" "\tUse a clipping region to constrain shadow update blits to\n" "\tthe updated region when num_boxes, or more, are in the\n" @@ -761,6 +770,8 @@ ddxProcessArgument (int argc, char *argv[], int i) return 1; } + + /* * Look for the '-clipboard' argument */ @@ -1106,6 +1117,58 @@ ddxProcessArgument (int argc, char *argv[], int i) } /* + * Look for the '-notrayicon' argument + */ + if (strcmp (argv[i], "-notrayicon") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fNoTrayIcon = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fNoTrayIcon = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-trayicon' argument + */ + if (strcmp (argv[i], "-trayicon") == 0) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fNoTrayIcon = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fNoTrayIcon = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* * Look for the '-fp' argument */ if (IS_OPTION ("-fp")) diff --git a/programs/Xserver/hw/xwin/XWin.rc b/programs/Xserver/hw/xwin/XWin.rc index 4d20a03d1..c918304af 100644 --- a/programs/Xserver/hw/xwin/XWin.rc +++ b/programs/Xserver/hw/xwin/XWin.rc @@ -27,7 +27,7 @@ * * Authors: Harold L Hunt II */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/XWin.rc,v 1.1 2002/10/17 08:18:21 alanh Exp $ */ #include "resource.h" @@ -36,8 +36,10 @@ * Dialogs */ +/* Depth_Change */ + DEPTH_CHANGE_BOX DIALOG DISCARDABLE 32, 32, 180, 100 -STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_CENTER FONT 8, "MS Sans Serif" CAPTION "Cygwin/XFree86" BEGIN @@ -48,10 +50,35 @@ BEGIN END +/* Exit */ + +EXIT_DIALOG DIALOG DISCARDABLE 32, 32, 180, 70 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTER +FONT 8, "MS Sans Serif" +CAPTION "Cygwin/XFree86 - Exit?" +BEGIN + PUSHBUTTON "E&xit", IDOK, 55, 48, 30, 14 + DEFPUSHBUTTON "&Cancel", IDCANCEL, 95, 48, 30, 14 + CTEXT "Exiting will close all screens running on this display.", IDC_STATIC, 7, 12, 166, 8 + CTEXT "Proceed with shutdown of this display/server?", IDC_STATIC, 7, 24, 166, 8 +END + + /* * Menus */ +IDM_TRAYICON_MENU MENU DISCARDABLE +BEGIN + POPUP "TRAYICON_MENU" + BEGIN + MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT + MENUITEM "&Show Root Window", ID_APP_SHOW_ROOT + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END +END + /* * Icons diff --git a/programs/Xserver/hw/xwin/resource.h b/programs/Xserver/hw/xwin/resource.h index da3aba755..c1705c4d9 100644 --- a/programs/Xserver/hw/xwin/resource.h +++ b/programs/Xserver/hw/xwin/resource.h @@ -27,7 +27,7 @@ * * Authors: Harold L Hunt II */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/resource.h,v 1.1 2002/10/17 08:18:21 alanh Exp $ */ #include "winms.h" @@ -39,3 +39,8 @@ #define IDM_APP_ABOUT 40001 #define IDC_STATIC -1 #define IDI_XWIN 101 +#define IDM_TRAYICON_MENU 102 +#define ID_APP_EXIT 103 +#define ID_APP_HIDE_ROOT 104 +#define ID_APP_SHOW_ROOT 105 +#define ID_APP_ALWAYS_ON_TOP 106 diff --git a/programs/Xserver/hw/xwin/win.h b/programs/Xserver/hw/xwin/win.h index b4cf67363..50fdf5f06 100644 --- a/programs/Xserver/hw/xwin/win.h +++ b/programs/Xserver/hw/xwin/win.h @@ -93,8 +93,14 @@ | (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 WIN_E3B_OFF -1 -#define WIN_E3B_TIMER_ID 1 #define WIN_FD_INVALID -1 #define WIN_SERVER_NONE 0x0L /* 0 */ @@ -144,7 +150,6 @@ #include "pixmapstr.h" #include "pixmap.h" #include "region.h" -#include "regionstr.h" #include "gcstruct.h" #include "colormap.h" #include "colormapst.h" @@ -184,6 +189,15 @@ /* + * Define Windows constants + */ + +#define WM_TRAYICON (WM_USER + 1000) +#define WM_INIT_SYS_MENU (WM_USER + 1001) +#define WM_GIVEUP (WM_USER + 1002) + + +/* * Multi-Window Window Manager header */ @@ -222,7 +236,7 @@ if (fDebugProcMsg) \ #define DEBUG_MSG(str,...) #endif -#if CYGDEBUG || YES +#if CYGDEBUG #define DEBUG_FN_NAME(str) PTSTR szFunctionName = str #else #define DEBUG_FN_NAME(str) @@ -387,6 +401,7 @@ typedef struct Bool fClipboard; Bool fLessPointer; Bool fScrollbars; + Bool fNoTrayIcon; int iE3BTimeout; /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */ Bool fUseWinKillKey; @@ -422,6 +437,9 @@ typedef struct _winPrivScreenRec DWORD dwModeKeyStates; + /* Handle to icons that must be freed */ + HICON hiconNotifyIcon; + /* Clipboard support */ pthread_t ptClipboardProc; @@ -482,7 +500,11 @@ typedef struct _winPrivScreenRec /* Privates used by multi-window server */ pthread_t ptWMProc; + pthread_t ptXMsgProc; void *pWMInfo; + Bool fWindowOrderChanged; + Bool fRestacking; + Bool fRootWindowShown; /* Privates used for any module running in a seperate thread */ pthread_mutex_t pmServerStarted; @@ -531,6 +553,12 @@ typedef struct _winPrivScreenRec } winPrivScreenRec; +typedef struct { + pointer value; + XID id; +} WindowIDPairRec, *WindowIDPairPtr; + + /* * Extern declares for general global variables */ @@ -549,6 +577,7 @@ extern CARD32 g_c32LastInputEventTime; extern DWORD g_dwEnginesSupported; extern HINSTANCE g_hInstance; extern HWND g_hDlgDepthChange; +extern HWND g_hDlgExit; /* @@ -772,6 +801,18 @@ winCrossScreen (ScreenPtr pScreen, Bool fEntering); /* + * windialogs.c + */ + +void +winDisplayExitDialog (winPrivScreenPtr pScreenPriv); + + +void +winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv); + + +/* * winengine.c */ @@ -1377,6 +1418,33 @@ winSetShapePRootless (WindowPtr pWindow); /* + * winmultiwindowicons.c + */ + +HICON +winXIconToHICON (WindowPtr pWin); + +void +winUpdateIcon (Window id); + + +/* + * winmultiwindowshape.c + */ + +#ifdef SHAPE +void +winReshapeMultiWindow (WindowPtr pWin); + +void +winSetShapeMultiWindow (WindowPtr pWindow); + +void +winUpdateRgnMultiWindow (WindowPtr pWindow); +#endif + + +/* * winmultiwindowwindow.c */ @@ -1404,10 +1472,42 @@ winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent); void winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib); -#ifdef SHAPE void -winSetShapeMultiWindow (WindowPtr pWindow); -#endif +winReorderWindowsMultiWindow (ScreenPtr pScreen); + +void +winMoveXWindow (WindowPtr pWin, int x, int y); + +void +winResizeXWindow (WindowPtr pWin, int w, int h); + +XID +winGetWindowID (WindowPtr pWin); + + +/* + * winmultiwindowwndproc.c + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * wintrayicon.c + */ + +void +winInitNotifyIcon (winPrivScreenPtr pScreenPriv); + +void +winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv); + +LRESULT +winHandleIconMessage (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam, + winPrivScreenPtr pScreenPriv); /* diff --git a/programs/Xserver/hw/xwin/winblock.c b/programs/Xserver/hw/xwin/winblock.c index e4972e345..35463493b 100644 --- a/programs/Xserver/hw/xwin/winblock.c +++ b/programs/Xserver/hw/xwin/winblock.c @@ -68,9 +68,13 @@ winBlockHandler_ProcessMessages: /* Process all messages on our queue */ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + if ((g_hDlgDepthChange == 0 + || !IsDialogMessage (g_hDlgDepthChange, &msg)) + && (g_hDlgExit == 0 + || !IsDialogMessage (g_hDlgExit, &msg))) { DispatchMessage (&msg); } } + winReorderWindowsMultiWindow ((ScreenPtr)pBlockData); } diff --git a/programs/Xserver/hw/xwin/winclipboardthread.c b/programs/Xserver/hw/xwin/winclipboardthread.c index 7812bfebf..ebf588801 100644 --- a/programs/Xserver/hw/xwin/winclipboardthread.c +++ b/programs/Xserver/hw/xwin/winclipboardthread.c @@ -79,7 +79,6 @@ winClipboardProc (void *pArg) int iRetries; Bool fUnicodeSupport; char szDisplay[512]; - int i; ClipboardProcArgPtr pProcArg = (ClipboardProcArgPtr) pArg; ErrorF ("winClipboardProc - Hello\n"); @@ -93,7 +92,7 @@ winClipboardProc (void *pArg) ErrorF ("winClipboardProc - Calling pthread_mutex_lock ()\n"); - /* Grab our garbage mutex to satisfy pthread_cond_wait */ + /* Grab the server started mutex - pause until we get it */ iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); if (iReturn != 0) { @@ -129,11 +128,6 @@ winClipboardProc (void *pArg) /* Flag that we have called setlocale */ g_fCalledSetLocale = TRUE; - /* Release the garbage mutex */ - pthread_mutex_unlock (pProcArg->ppmServerStarted); - - ErrorF ("winClipboardProc - pthread_mutex_unlock () returned.\n"); - /* Allow multiple threads to access Xlib */ if (XInitThreads () == 0) { @@ -143,6 +137,11 @@ winClipboardProc (void *pArg) ErrorF ("winClipboardProc - XInitThreads () returned.\n"); + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winClipboardProc - pthread_mutex_unlock () returned.\n"); + /* Set jump point for Error exits */ iReturn = setjmp (g_jmpEntry); @@ -163,13 +162,12 @@ winClipboardProc (void *pArg) /* Initialize retry count */ iRetries = 0; -#if 0 - /* Setup the display connection string x */ - snprintf (szDisplay, 512, "127.0.0.1:%s.%d", display, pProcArg->dwScreen); -#else /* Setup the display connection string x */ - snprintf (szDisplay, 512, ":%s.%d", display, pProcArg->dwScreen); -#endif + snprintf (szDisplay, + 512, + "127.0.0.1:%s.%d", + display, + (int) pProcArg->dwScreen); /* Print the display connection string */ ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay); @@ -434,14 +432,18 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) sizeof (pszErrorMsg)); ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n", pszErrorMsg); - if (pErr->error_code==BadWindow - || pErr->error_code==BadMatch - || pErr->error_code==BadDrawable) + if (pErr->error_code == BadWindow + || pErr->error_code == BadMatch + || pErr->error_code == BadDrawable) { +#if 0 pthread_exit (NULL); +#endif } +#if 0 pthread_exit (NULL); +#endif return 0; } diff --git a/programs/Xserver/hw/xwin/winconfig.c b/programs/Xserver/hw/xwin/winconfig.c index 43c71240c..14a10f0a4 100644 --- a/programs/Xserver/hw/xwin/winconfig.c +++ b/programs/Xserver/hw/xwin/winconfig.c @@ -27,7 +27,7 @@ * * Authors: Alexander Gottwald */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winconfig.c,v 1.1 2002/10/17 08:18:22 alanh Exp $ */ #include "win.h" #include "winconfig.h" @@ -112,11 +112,10 @@ static Bool GetBoolValue (OptionInfoPtr p, const char *s); Bool winReadConfigfile () { - Bool retval = TRUE; - const char *filename; - - MessageType from = X_DEFAULT; - char *xf86ConfigFile = NULL; + Bool retval = TRUE; + const char *filename; + MessageType from = X_DEFAULT; + char *xf86ConfigFile = NULL; if (g_cmdline.configFile) { @@ -213,9 +212,41 @@ winReadConfigfile () /* Set the keyboard configuration */ +typedef struct { + int winlayout; + int winkbtype; + char *xkbmodel; + char *xkblayout; + char *xkbvariant; + char *xkboptions; + char *layoutname; +} WinKBLayoutRec, *WinKBLayoutPtr; + +WinKBLayoutRec winKBLayouts[] = { + { 0x405, 4, "pc105", "cz", NULL, NULL, "Czech"}, + { 0x406, 4, "pc105", "dk", NULL, NULL, "Danish"}, + { 0x407, 4, "pc105", "de", NULL, NULL, "German (Germany)"}, + { 0x807, 4, "pc105", "de_CH", NULL, NULL, "German (Switzerland)"}, + {0x20409, -1, "pc105", "us_intl", NULL, NULL, "English (USA, International)"}, + { 0x809, 4, "pc105", "gb", NULL, NULL, "English (United Kingdom)"}, + { 0x40a, 4, "pc105", "es", NULL, NULL, "Spanish (Spain, Traditional Sort)"}, + { 0x40b, 4, "pc105", "fi", NULL, NULL, "Finnish"}, + { 0x40c, 4, "pc105", "fr", NULL, NULL, "French (Standard)"}, + { 0x80c, 4, "pc105", "be", NULL, NULL, "French (Belgian)"}, + { 0x410, 4, "pc105", "it", NULL, NULL, "Italian"}, + { 0x416, 4, "pc105", "pt", NULL, NULL, "Portuguese (Brazil)"}, + { 0x816, 4, "pc105", "pt", NULL, NULL, "Portuguese (Portugal)"}, + { 0x41d, 4, "pc105", "se", NULL, NULL, "Swedish (Sweden)"}, + { -1, -1, NULL, NULL, NULL, NULL, NULL} +}; + + Bool winConfigKeyboard (DeviceIntPtr pDevice) { + char layoutName[KL_NAMELENGTH]; + int layoutNum; + int keyboardType; XF86ConfInputPtr kbd = NULL; XF86ConfInputPtr input_list = NULL; MessageType from = X_DEFAULT; @@ -237,6 +268,35 @@ winConfigKeyboard (DeviceIntPtr pDevice) g_winInfo.xkb.variant = NULL; g_winInfo.xkb.options = NULL; # endif /* PC98 */ + + + + keyboardType = GetKeyboardType (0); + if (keyboardType > 0 && GetKeyboardLayoutName (layoutName)) + { + WinKBLayoutPtr pLayout = winKBLayouts; + + layoutNum = strtol (layoutName, (char **)NULL, 16); + + for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) + { + if (pLayout->winlayout != layoutNum) + continue; + if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) + continue; + + winMsg (X_DEFAULT, + "Using preset keyboard for \"%s\" (%s), type \"%d\"\n", + pLayout->layoutname, layoutName, keyboardType); + + g_winInfo.xkb.model = pLayout->xkbmodel; + g_winInfo.xkb.layout = pLayout->xkblayout; + g_winInfo.xkb.variant = pLayout->xkbvariant; + g_winInfo.xkb.options = pLayout->xkboptions; + break; + } + } + g_winInfo.xkb.initialMap = NULL; g_winInfo.xkb.keymap = NULL; g_winInfo.xkb.types = NULL; @@ -265,7 +325,7 @@ winConfigKeyboard (DeviceIntPtr pDevice) { /* Check if device name matches requested name */ if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier, - g_cmdline.keyboard)) + g_cmdline.keyboard)) continue; kbd = input_list; } @@ -416,7 +476,7 @@ winConfigMouse (DeviceIntPtr pDevice) { /* Check if device name matches requested name */ if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier, - g_cmdline.mouse)) + g_cmdline.mouse)) continue; mouse = input_list; } diff --git a/programs/Xserver/hw/xwin/wincreatewnd.c b/programs/Xserver/hw/xwin/wincreatewnd.c index 774db51eb..12211c577 100644 --- a/programs/Xserver/hw/xwin/wincreatewnd.c +++ b/programs/Xserver/hw/xwin/wincreatewnd.c @@ -57,6 +57,7 @@ winCreateBoundingWindowFullScreen (ScreenPtr pScreen) int iHeight = pScreenInfo->dwHeight; HWND *phwnd = &pScreenPriv->hwndScreen; WNDCLASS wc; + char szTitle[256]; #if CYGDEBUG ErrorF ("winCreateBoundingWindowFullScreen\n"); @@ -75,10 +76,17 @@ winCreateBoundingWindowFullScreen (ScreenPtr pScreen) wc.lpszClassName = WINDOW_CLASS; RegisterClass (&wc); + /* Set display and screen-specific tooltip text */ + snprintf (szTitle, + sizeof (szTitle), + WINDOW_TITLE, + display, + (int) pScreenInfo->dwScreen); + /* Create the window */ *phwnd = CreateWindowExA (WS_EX_TOPMOST, /* Extended styles */ WINDOW_CLASS, /* Class name */ - WINDOW_TITLE, /* Window name */ + szTitle, /* Window name */ WS_POPUP, 0, /* Horizontal position */ 0, /* Vertical position */ @@ -102,7 +110,7 @@ winCreateBoundingWindowFullScreen (ScreenPtr pScreen) ShowWindow (*phwnd, SW_SHOWNORMAL); break; } - + /* Send first paint message */ UpdateWindow (*phwnd); @@ -128,6 +136,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) WNDCLASS wc; RECT rcClient, rcWorkArea; DWORD dwWindowStyle; + char szTitle[256]; ErrorF ("winCreateBoundingWindowWindowed - User w: %d h: %d\n", pScreenInfo->dwUserWidth, pScreenInfo->dwUserHeight); @@ -267,10 +276,17 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) iWidth, iHeight); #endif + /* Set display and screen-specific tooltip text */ + snprintf (szTitle, + sizeof (szTitle), + WINDOW_TITLE, + display, + (int) pScreenInfo->dwScreen); + /* Create the window */ *phwnd = CreateWindowExA (0, /* Extended styles */ WINDOW_CLASS, /* Class name */ - WINDOW_TITLE, /* Window name */ + szTitle, /* Window name */ dwWindowStyle, rcWorkArea.left, /* Horizontal position */ rcWorkArea.top, /* Vertical position */ @@ -369,7 +385,10 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) /* Show the window */ if (pScreenInfo->fMultiWindow) - ShowWindow (*phwnd, SW_SHOWMINNOACTIVE); + { + pScreenPriv->fRootWindowShown = FALSE; + ShowWindow (*phwnd, SW_HIDE); + } else ShowWindow (*phwnd, SW_SHOWNORMAL); if (!UpdateWindow (*phwnd)) diff --git a/programs/Xserver/hw/xwin/wincursor.c b/programs/Xserver/hw/xwin/wincursor.c index 53b73c1a2..9e053a7d2 100644 --- a/programs/Xserver/hw/xwin/wincursor.c +++ b/programs/Xserver/hw/xwin/wincursor.c @@ -30,7 +30,7 @@ * Peter Busch * Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/wincursor.c,v 1.3 2002/04/11 08:25:17 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wincursor.c,v 1.5 2002/07/05 09:19:26 alanh Exp $ */ #include "win.h" @@ -47,6 +47,21 @@ winPointerWarpCursor (ScreenPtr pScreen, int x, int y) { winScreenPriv(pScreen); RECT rcClient; + static Bool s_fInitialWarp = TRUE; + + /* Discard first warp call */ + if (s_fInitialWarp) + { + /* First warp moves mouse to center of window, just ignore it */ + + /* Don't ignore subsequent warps */ + s_fInitialWarp = FALSE; + + ErrorF ("winPointerWarpCursor - Discarding first warp: %d %d\n", + x, y); + + return; + } /* Only update the Windows cursor position if we are active */ if (pScreenPriv->hwndScreen == GetForegroundWindow ()) diff --git a/programs/Xserver/hw/xwin/wincutpaste.c b/programs/Xserver/hw/xwin/wincutpaste.c index a401d820d..2313b1d85 100644 --- a/programs/Xserver/hw/xwin/wincutpaste.c +++ b/programs/Xserver/hw/xwin/wincutpaste.c @@ -27,7 +27,7 @@ * * Authors: Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/wincutpaste.c,v 1.1 2001/06/25 08:12:33 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/wincutpaste.c,v 1.2 2001/09/07 08:41:54 alanh Exp $ */ #include <sys/types.h> #include <sys/stat.h> @@ -45,6 +45,7 @@ #include "X.h" #include "Xos.h" +#include "regionstr.h" #include "miscstruct.h" #include "keysym.h" #include <X11/Xlib.h> diff --git a/programs/Xserver/hw/xwin/windialogs.c b/programs/Xserver/hw/xwin/windialogs.c new file mode 100644 index 000000000..07db55075 --- /dev/null +++ b/programs/Xserver/hw/xwin/windialogs.c @@ -0,0 +1,320 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: $ */ + +#include "win.h" + +extern Bool g_fCursor; + +BOOL CALLBACK +winExitDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam); + +BOOL CALLBACK +winChangeDepthDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * Display the Exit dialog box + */ + +void +winDisplayExitDialog (winPrivScreenPtr pScreenPriv) +{ + /* Check if dialog already exists */ + if (g_hDlgExit != NULL) + { + /* Dialog box already exists, display it */ + ShowWindow (g_hDlgExit, SW_SHOWDEFAULT); + + /* User has lost the dialog. Show them where it is. */ + SetForegroundWindow (g_hDlgExit); + + return; + } + + /* Create dialog box */ + g_hDlgExit = CreateDialogParam (g_hInstance, + "EXIT_DIALOG", + pScreenPriv->hwndScreen, + winExitDlgProc, + (int) pScreenPriv); + + /* Drop minimize and maximize buttons */ + SetWindowLong (g_hDlgExit, GWL_STYLE, + GetWindowLong (g_hDlgExit, GWL_STYLE) + & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); + SetWindowLong (g_hDlgExit, GWL_EXSTYLE, + GetWindowLong (g_hDlgExit, GWL_EXSTYLE) & ~WS_EX_APPWINDOW ); + SetWindowPos (g_hDlgExit, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE); + + /* Show the dialog box */ + ShowWindow (g_hDlgExit, SW_SHOW); + + /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ + SetForegroundWindow (g_hDlgExit); + + /* Set focus to the Cancel buton */ + PostMessage (g_hDlgExit, WM_NEXTDLGCTL, + (int) GetDlgItem (g_hDlgExit, IDCANCEL), TRUE); +} + + +/* + * Exit dialog window procedure + */ + +BOOL CALLBACK +winExitDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + + /* Branch on message type */ + switch (message) + { + case WM_INITDIALOG: + /* Store pointers to private structures for future use */ + s_pScreenPriv = (winPrivScreenPtr) lParam; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + + /* Set icon to standard app icon */ + PostMessage (hDialog, + WM_SETICON, + ICON_SMALL, + (LPARAM) LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN))); + return TRUE; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDOK: + /* Send message to call the GiveUp function */ + PostMessage (s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + + case IDCANCEL: + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + } + break; + + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + /* Show the cursor if it is hidden */ + if (!g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + return TRUE; + + case WM_CLOSE: + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + } + + return FALSE; +} + + +/* + * Display the Depth Change dialog box + */ + +void +winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv) +{ + /* Check if dialog already exists */ + if (g_hDlgDepthChange != NULL) + { + /* Dialog box already exists, display it */ + ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); + + /* User has lost the dialog. Show them where it is. */ + SetForegroundWindow (g_hDlgDepthChange); + + return; + } + + /* + * Display a notification to the user that the visual + * will not be displayed until the Windows display depth + * is restored to the original value. + */ + g_hDlgDepthChange = CreateDialogParam (g_hInstance, + "DEPTH_CHANGE_BOX", + pScreenPriv->hwndScreen, + winChangeDepthDlgProc, + (int) pScreenPriv); + + /* Drop minimize and maximize buttons */ + SetWindowLong (g_hDlgDepthChange, GWL_STYLE, + GetWindowLong (g_hDlgDepthChange, GWL_STYLE) + & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); + SetWindowLong (g_hDlgDepthChange, GWL_EXSTYLE, + GetWindowLong (g_hDlgDepthChange, GWL_EXSTYLE) + & ~WS_EX_APPWINDOW ); + SetWindowPos (g_hDlgDepthChange, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE); + + /* Show the dialog box */ + ShowWindow (g_hDlgDepthChange, SW_SHOW); + + ErrorF ("winDisplayDepthChangeDialog - DialogBox returned: %d\n", + g_hDlgDepthChange); + ErrorF ("winDisplayDepthChangeDialog - GetLastError: %d\n", GetLastError ()); + + /* Minimize the display window */ + ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); +} + + +/* + * Process messages for the dialog that is displayed for + * disruptive screen depth changes. + */ + +BOOL CALLBACK +winChangeDepthDlgProc (HWND hwndDialog, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc\n"); +#endif + + /* Branch on message type */ + switch (message) + { + case WM_INITDIALOG: +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG\n"); +#endif + + /* Store pointers to private structures for future use */ + s_pScreenPriv = (winPrivScreenPtr) lParam; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_INITDIALG - s_pScreenPriv: %08x, " + "s_pScreenInfo: %08x, s_pScreen: %08x\n", + s_pScreenPriv, s_pScreenInfo, s_pScreen); +#endif + +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, " + "last bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel); +#endif + + /* Set icon to standard app icon */ + PostMessage (hwndDialog, + WM_SETICON, + ICON_SMALL, + (LPARAM) LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN))); + + return TRUE; + + case WM_DISPLAYCHANGE: +#if CYGDEBUG + ErrorF ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, " + "last bpp: %d, new bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel, + wParam); +#endif + + /* Dismiss the dialog if the display returns to the original depth */ + if (wParam == s_pScreenInfo->dwBPP) + { + ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n"); + + /* Depth has been restored, dismiss dialog */ + DestroyWindow (g_hDlgDepthChange); + g_hDlgDepthChange = NULL; + + /* Flag that we have a valid screen depth */ + s_pScreenPriv->fBadDepth = FALSE; + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDOK: + case IDCANCEL: + ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); + + /* + * User dismissed the dialog, hide it until the + * display mode is restored. + */ + ShowWindow (g_hDlgDepthChange, SW_HIDE); + return TRUE; + } + break; + + case WM_CLOSE: + ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n"); + + /* + * User dismissed the dialog, hide it until the + * display mode is restored. + */ + ShowWindow (g_hDlgDepthChange, SW_HIDE); + return TRUE; + } + + return FALSE; +} diff --git a/programs/Xserver/hw/xwin/winengine.c b/programs/Xserver/hw/xwin/winengine.c index f9ba3e5fc..c8c2ef40f 100644 --- a/programs/Xserver/hw/xwin/winengine.c +++ b/programs/Xserver/hw/xwin/winengine.c @@ -33,6 +33,13 @@ /* + * External global variables + */ + +extern const GUID _IID_IDirectDraw4; + + +/* * Detect engines supported by current Windows version * DirectDraw version and hardware */ diff --git a/programs/Xserver/hw/xwin/winkeybd.c b/programs/Xserver/hw/xwin/winkeybd.c index fdbc6f1b0..4228ad422 100644 --- a/programs/Xserver/hw/xwin/winkeybd.c +++ b/programs/Xserver/hw/xwin/winkeybd.c @@ -30,7 +30,7 @@ * Peter Busch * Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/winkeybd.c,v 1.11 2002/07/05 09:19:26 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winkeybd.c,v 1.12 2002/10/17 08:18:22 alanh Exp $ */ #include "win.h" @@ -649,31 +649,23 @@ void winKeybdReleaseKeys () { #if !WIN_NEW_KEYBOARD_SUPPORT -#if 0 /* Old function that just pops modifiers */ - /* Verify that the mi input system has been initialized */ - if (g_fdMessageQueue == WIN_FD_INVALID) - return; - - winSendKeyEvent (KEY_Alt, FALSE); - winSendKeyEvent (KEY_AltLang, FALSE); - winSendKeyEvent (KEY_LCtrl, FALSE); - winSendKeyEvent (KEY_RCtrl, FALSE); - winSendKeyEvent (KEY_ShiftL, FALSE); - winSendKeyEvent (KEY_ShiftR, FALSE); -#else /* New function that pops all keys */ int i; /* Verify that the mi input system has been initialized */ if (g_fdMessageQueue == WIN_FD_INVALID) return; - /* Pop any pressed keys */ + /* Loop through all keys */ for (i = 0; i < NUM_KEYCODES; ++i) { - if (g_winKeyState[i]) winSendKeyEvent (i, FALSE); + /* Pop key if pressed */ + if (g_winKeyState[i]) + winSendKeyEvent (i, FALSE); + + /* Reset pressed flag for keys */ + g_winKeyState[i] = FALSE; } #endif -#endif } diff --git a/programs/Xserver/hw/xwin/winmultiwindowclass.c b/programs/Xserver/hw/xwin/winmultiwindowclass.c new file mode 100644 index 000000000..42604c44a --- /dev/null +++ b/programs/Xserver/hw/xwin/winmultiwindowclass.c @@ -0,0 +1,193 @@ +/* + *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 + */ +/* $XFree86$ */ + +#include <Xatom.h> +#include "propertyst.h" +#include "windowstr.h" +#include "winmultiwindowclass.h" + +int +winMultiWindowGetClassHint (WindowPtr pWin, char **res_name, char **res_class) +{ + struct _Window *pwin; + struct _Property *prop; + int len_name, len_class; + + if (!pWin || !res_name || !res_class) + { + ErrorF ("winMultiWindowGetClassHint - pWin, res_name, or res_class was " + "NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + *res_name = *res_class = NULL; + + while (prop) + { + if (prop->propertyName == XA_WM_CLASS + && prop->type == XA_STRING + && prop->format == 8 + && prop->data) + { + len_name = strlen ((char *) prop->data); + + (*res_name) = malloc (len_name + 1); + + if (!*res_name) + { + ErrorF ("winMultiWindowGetClassHint - *res_name was NULL\n"); + return 0; + } + + strncpy ((*res_name), prop->data, len_name); + + if (len_name == prop->size) + len_name--; + + len_class = strlen (((char *)prop->data) + 1 + len_name); + + (*res_class) = malloc (len_class + 1); + + if (!*res_class) + { + ErrorF ("winMultiWindowGetClassHint - *res_class was NULL\n"); + + /* Free the previously allocated res_name */ + free (*res_name); + return 0; + } + + strcpy ((*res_class), ((char *)prop->data) + 1 + len_name); + + return 1; + } + else + prop = prop->next; + } + + return 0; +} + + +int +winMultiWindowGetWMHints (WindowPtr pWin, WinXWMHints *hints) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !hints) + { + ErrorF ("winMultiWindowGetWMHints - pWin or hints was NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + memset (hints, 0, sizeof (WinXWMHints)); + + while (prop) + { + if (prop->propertyName == XA_WM_HINTS + && prop->data) + { + memcpy (hints, prop->data, sizeof (WinXWMHints)); + return 1; + } + else + prop = prop->next; + } + + return 0; +} + + +int +winMultiWindowGetWindowRole (WindowPtr pWin, char **res_role) +{ + struct _Window *pwin; + struct _Property *prop; + int len_role; + static Atom atmWmWindowRole = 0; + + if (!pWin || !res_role) + return 0; + + /* Initialize the window role atom, not in XAtom.h */ + if (!atmWmWindowRole) + atmWmWindowRole = MakeAtom ("WM_WINDOW_ROLE", 14, 1); + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + *res_role = NULL; + while (prop) + { + if (prop->propertyName == atmWmWindowRole + && prop->type == XA_STRING + && prop->format == 8 + && prop->data) + { + len_role= strlen ((char *) prop->data); + + (*res_role) = malloc (len_role + 1); + + if (!*res_role) + { + ErrorF ("winMultiWindowGetWindowRole - *res_role was NULL\n"); + return 0; + } + + strcpy ((*res_role), prop->data); + + return 1; + } + else + prop = prop->next; + } + + return 0; +} diff --git a/programs/Xserver/hw/xwin/winmultiwindowclass.h b/programs/Xserver/hw/xwin/winmultiwindowclass.h new file mode 100644 index 000000000..79b3a1c5d --- /dev/null +++ b/programs/Xserver/hw/xwin/winmultiwindowclass.h @@ -0,0 +1,62 @@ +/* + *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 + */ +/* $XFree86$ */ + + +/* + * Structures + */ + +typedef struct { + long flags; /* marks which fields in this structure are defined */ + Bool input; /* does this application rely on the window manager to + get keyboard input? */ + int initial_state; /* see below */ + Pixmap icon_pixmap; /* pixmap to be used as icon */ + Window icon_window; /* window to be used as icon */ + int icon_x, icon_y; /* initial position of icon */ + Pixmap icon_mask; /* icon mask bitmap */ + XID window_group; /* id of related window group */ + /* this structure may be extended in the future */ +} WinXWMHints; + + +/* + * Function prototypes + */ + +int +winMultiWindowGetWMHints (WindowPtr pWin, WinXWMHints *hints); + +int +winMultiWindowGetClassHint (WindowPtr pWin, char **res_name, char **res_class); + +int +winMultiWindowGetWindowRole (WindowPtr pWin, char **res_role); diff --git a/programs/Xserver/hw/xwin/winmultiwindowicons.c b/programs/Xserver/hw/xwin/winmultiwindowicons.c new file mode 100644 index 000000000..62161bb01 --- /dev/null +++ b/programs/Xserver/hw/xwin/winmultiwindowicons.c @@ -0,0 +1,372 @@ +/* + *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 + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.5 2002/11/07 10:31:32 alanh Exp $ */ + +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" + + +/* + * External global variables + */ + +extern HICON g_hiconX; + + +/* + * 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; + unsigned char *iconData = 0; + int stride, xStride; + float factX, factY; + int posX, posY; + unsigned char *ptr; + unsigned int zero; + unsigned int color; + + + if (pixmap->drawable.bitsPerPixel == 15) + effXBPP = 16; + else + effXBPP = pixmap->drawable.bitsPerPixel; + + if (pixmap->drawable.depth == 15) + effXDepth = 16; + else + effXDepth = pixmap->drawable.depth; + + /* Need 32-bit aligned rows */ + stride = ((iconSize * effBPP + 31) & (~31)) / 8; + xStride = ((pixmap->drawable.width * effXBPP + 31) & (~31)) / 8; + + iconData = malloc (xStride * pixmap->drawable.height); + 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 = 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++) = 0; // resvd + 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); +} + + +/* + * Attempt to create a custom icon from the WM_HINTS bitmaps + */ + +HICON +winXIconToHICON (WindowPtr pWin) +{ + unsigned char *mask, *image, *imageMask; + unsigned char *dst, *src; + PixmapPtr iconPtr; + PixmapPtr maskPtr; + int iconSize, planes, bpp, effBPP, stride, maskStride, i; + HDC hDC; + ICONINFO ii; + WinXWMHints hints; + HICON hIcon; + + winMultiWindowGetWMHints (pWin, &hints); + if (!hints.icon_pixmap) return NULL; + + iconPtr = LookupIDByType (hints.icon_pixmap, RT_PIXMAP); + + if (!iconPtr) return NULL; + + iconSize = 32; + + hDC = GetDC (GetDesktopWindow ()); + planes = GetDeviceCaps (hDC, PLANES); + bpp = GetDeviceCaps (hDC, BITSPIXEL); + ReleaseDC (GetDesktopWindow (), hDC); + + /* 15 BPP is really 16BPP as far as we care */ + if (bpp == 15) + effBPP = 16; + else + effBPP = bpp; + + /* Need 32-bit aligned rows */ + stride = ((iconSize * effBPP + 31) & (~31)) / 8; + + /* Mask is 1-bit deep */ + maskStride = ((iconSize * 1 + 31) & (~31)) / 8; + + image = (unsigned char * ) malloc (stride * iconSize); + imageMask = (unsigned char *) malloc (stride * iconSize); + mask = (unsigned char *) malloc (maskStride * iconSize); + + /* Default to a completely black mask */ + memset (mask, 0, maskStride * iconSize); + + winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); + maskPtr = LookupIDByType (hints.icon_mask, RT_PIXMAP); + + 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 + */ + +void +winUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hiconOld; + + pWin = LookupIDByType (id, RT_WINDOW); + hIcon = winXIconToHICON (pWin); + + if (hIcon) + { + winWindowPriv(pWin); + + if (pWinPriv->hWnd) + { + hiconOld = (HICON) SetClassLong (pWinPriv->hWnd, + GCL_HICON, + (int) hIcon); + + /* Delete the icon if its not the default */ + if (hiconOld != g_hiconX) + DeleteObject (hiconOld); + } + } +} diff --git a/programs/Xserver/hw/xwin/winmultiwindowshape.c b/programs/Xserver/hw/xwin/winmultiwindowshape.c new file mode 100644 index 000000000..083527948 --- /dev/null +++ b/programs/Xserver/hw/xwin/winmultiwindowshape.c @@ -0,0 +1,212 @@ +/* + *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 + * Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.5 2002/11/07 10:31:32 alanh Exp $ */ + +#ifdef SHAPE + +#include "win.h" + + +/* + * External global variables + */ + +extern HICON g_hiconX; + + +/* + * winSetShapeMultiWindow - See Porting Layer Definition - p. 42 + */ + +void +winSetShapeMultiWindow (WindowPtr pWin) +{ +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin); +#endif + + /* Call any wrapped SetShape function */ + if (winGetScreenPriv(pWin->drawable.pScreen)->SetShape) + winGetScreenPriv(pWin->drawable.pScreen)->SetShape (pWin); + + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); + + return; +} + + +/* + * winUpdateRgnMultiWindow - Local function to update a Windows window region + */ + +void +winUpdateRgnMultiWindow (WindowPtr pWin) +{ + SetWindowRgn (winGetWindowPriv(pWin)->hWnd, + winGetWindowPriv(pWin)->hRgn, TRUE); +} + + +/* + * winReshapeMultiWindow - Computes the composite clipping region for a window + */ + +void +winReshapeMultiWindow (WindowPtr pWin) +{ + int nRects; + RegionRec rrNewShape; + BoxPtr pShape, pRects, pEnd; + HRGN hRgn, hRgnRect; + winWindowPriv(pWin); + +#if CYGDEBUG + ErrorF ("winReshape ()\n"); +#endif + + /* Bail if the window is the root window */ + if (pWin->parent == NULL) + return; + + /* Bail if the window is not top level */ + if (pWin->parent->parent != NULL) + return; + + /* Bail if Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + /* Free any existing window region stored in the window privates */ + if (pWinPriv->hRgn != NULL) + { + DeleteObject (pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + /* Bail if the window has no bounding region defined */ + if (!wBoundingShape (pWin)) + return; + + REGION_INIT(pScreen, &rrNewShape, NullBox, 0); + REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, + &rrNewShape, + pWin->borderWidth, + pWin->borderWidth); + + nRects = REGION_NUM_RECTS(&rrNewShape); + pShape = REGION_RECTS(&rrNewShape); + + /* Don't do anything if there are no rectangles in the region */ + if (nRects > 0) + { + RECT rcClient; + RECT rcWindow; + int iOffsetX, iOffsetY; + + /* Get client rectangle */ + if (!GetClientRect (pWinPriv->hWnd, &rcClient)) + { + ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", + GetLastError ()); + return; + } + + /* Translate client rectangle coords to screen coords */ + /* NOTE: Only transforms top and left members */ + ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); + + /* Get window rectangle */ + if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) + { + ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", + GetLastError ()); + return; + } + + /* Calculate offset from window upper-left to client upper-left */ + iOffsetX = rcClient.left - rcWindow.left; + iOffsetY = rcClient.top - rcWindow.top; + + /* Create initial Windows region for title bar */ + /* FIXME: Mean, nasty, ugly hack!!! */ + hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, rcWindow.right, iOffsetY, GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX - 1, + pRects->y1 + iOffsetY - 1, + pRects->x2 + iOffsetX - 1, + pRects->y2 + iOffsetY - 1); + if (hRgnRect == NULL) + { + ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n" + "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", + pRects->x1 + iOffsetX - 1, + pRects->y1 + iOffsetY - 1, + pRects->x2 + iOffsetX - 1, + pRects->y2 + iOffsetY - 1, + GetLastError (), + pRects->x1, pRects->x2, iOffsetX, + pRects->y1, pRects->y2, iOffsetY); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + /* Save a handle to the composite region in the window privates */ + pWinPriv->hRgn = hRgn; + } + + REGION_UNINIT(pScreen, &rrNewShape); + + return; +} +#endif diff --git a/programs/Xserver/hw/xwin/winmultiwindowwindow.c b/programs/Xserver/hw/xwin/winmultiwindowwindow.c index 622eb9764..bfb3bcbcf 100644 --- a/programs/Xserver/hw/xwin/winmultiwindowwindow.c +++ b/programs/Xserver/hw/xwin/winmultiwindowwindow.c @@ -26,11 +26,21 @@ *from the XFree86 Project. * * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II */ /* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.5 2002/11/07 10:31:32 alanh Exp $ */ #include "win.h" #include "dixevents.h" +#include "winmultiwindowclass.h" + + +/* + * External global variables + */ + +extern HICON g_hiconX; /* @@ -46,31 +56,12 @@ winDestroyWindowsWindow (WindowPtr pWin); static void winUpdateWindowsWindow (WindowPtr pWin); -static XID -winGetWindowID (WindowPtr pWin); - static void -SendConfigureNotify (WindowPtr pWin); - -static -void -winUpdateRgn (WindowPtr pWindow); - -#ifdef SHAPE -static -void -winReshape (WindowPtr pWin); -#endif - - -/* - * Local globals - */ - -static UINT s_nIDPollingMouse = 2; +winFindWindow (pointer value, XID id, pointer cdata); #if 0 -static BOOL s_fMoveByX = FALSE; +static void +winRestackXWindow (WindowPtr pWin, int smode); #endif @@ -78,9 +69,8 @@ static BOOL s_fMoveByX = FALSE; * Constant defines */ +#define MOUSE_POLLING_INTERVAL 500 -#define MOUSE_POLLING_INTERVAL 500 -#define WIN_MULTIWINDOW_SHAPE YES /* * Macros @@ -118,6 +108,7 @@ winCreateWindowMultiWindow (WindowPtr pWin) pWinPriv->hWnd = NULL; pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); pWinPriv->fXKilled = FALSE; + pWinPriv->fNeedRestore = FALSE; return fResult; } @@ -191,8 +182,8 @@ winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) iBorder = wBorderWidth (pWin); /* Get the X and Y location of the X window */ - iX = pWin->drawable.x; - iY = pWin->drawable.y; + 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; @@ -336,9 +327,10 @@ winMapWindowMultiWindow (WindowPtr pWin) /* Refresh/redisplay the Windows window associated with this X window */ winUpdateWindowsWindow (pWin); -#if WIN_MULTIWINDOW_SHAPE - winReshape (pWin); - winUpdateRgn (pWin); +#ifdef SHAPE + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); #endif return fResult; @@ -376,6 +368,7 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) WindowPtr pPrevWin; UINT uFlags; HWND hInsertAfter; + HWND hWnd = NULL; winWindowPriv(pWin); #if CYGMULTIWINDOW_DEBUG @@ -387,6 +380,9 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) winGetScreenPriv(pWin->drawable.pScreen)->RestackWindow (pWin, pOldNextSib); + if (winGetScreenPriv(pWin->drawable.pScreen)->fRestacking) + return; + /* Bail out if no window privates or window handle is invalid */ if (!pWinPriv || !pWinPriv->hWnd) return; @@ -409,6 +405,22 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) /* 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 { @@ -427,966 +439,108 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) /* - * SetShape - See Porting Layer Definition - p. 42 - */ - -#ifdef SHAPE -void -winSetShapeMultiWindow (WindowPtr pWin) -{ -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin); -#endif - - /* Call any wrapped SetShape function */ - if (winGetScreenPriv(pWin->drawable.pScreen)->SetShape) - winGetScreenPriv(pWin->drawable.pScreen)->SetShape (pWin); - - /* - * NOTE: We do not currently do anything here. - */ - -#if WIN_MULTIWINDOW_SHAPE - winReshape (pWin); - winUpdateRgn (pWin); -#endif - - return; -} -#endif - - -/* - * winUpdateRgn - Local function to update a Windows window region - */ - -static -void -winUpdateRgn (WindowPtr pWin) -{ -#if 1 - SetWindowRgn (winGetWindowPriv(pWin)->hWnd, - winGetWindowPriv(pWin)->hRgn, TRUE); -#endif -} - - -/* - * winReshape - Computes the composite clipping region for a window + * winCreateWindowsWindow - Create a Windows window associated with an X window */ -#ifdef SHAPE -static -void -winReshape (WindowPtr pWin) +static void +winCreateWindowsWindow (WindowPtr pWin) { - int nRects; - ScreenPtr pScreen = pWin->drawable.pScreen; - RegionRec rrNewShape; - BoxPtr pShape, pRects, pEnd; - HRGN hRgn, hRgnRect; + int iX, iY; + int iWidth; + int iHeight; + int iBorder; + HWND hWnd; + WNDCLASS wc; winWindowPriv(pWin); + HICON hIcon; +#define CLASS_NAME_LENGTH 512 + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; -#if CYGDEBUG - ErrorF ("winReshape ()\n"); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); #endif - - /* Bail if the window is the root window */ - if (pWin->parent == NULL) - return; - - /* Bail if the window is not top level */ - if (pWin->parent->parent != NULL) - return; - - /* Bail if Windows window handle is invalid */ - if (pWinPriv->hWnd == NULL) - return; - - /* Free any existing window region stored in the window privates */ - if (pWinPriv->hRgn != NULL) - { - DeleteObject (pWinPriv->hRgn); - pWinPriv->hRgn = NULL; - } - - /* Bail if the window has no bounding region defined */ - if (!wBoundingShape (pWin)) - return; - REGION_INIT(pScreen, &rrNewShape, NullBox, 0); - REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); - REGION_TRANSLATE(pScreen, - &rrNewShape, - pWin->borderWidth, - pWin->borderWidth); + iBorder = wBorderWidth (pWin); - nRects = REGION_NUM_RECTS(&rrNewShape); - pShape = REGION_RECTS(&rrNewShape); + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); - /* Don't do anything if there are no rectangles in the region */ - if (nRects > 0) - { - RECT rcClient; - RECT rcWindow; - int iOffsetX, iOffsetY; - - /* Get client rectangle */ - if (!GetClientRect (pWinPriv->hWnd, &rcClient)) - { - ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", - GetLastError ()); - return; - } - - /* Translate client rectangle coords to screen coords */ - /* NOTE: Only transforms top and left members */ - ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); - - /* Get window rectangle */ - if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) - { - ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", - GetLastError ()); - return; - } - - /* Calculate offset from window upper-left to client upper-left */ - iOffsetX = rcClient.left - rcWindow.left; - iOffsetY = rcClient.top - rcWindow.top; - - /* Create initial Windows region for title bar */ - /* FIXME: Mean, nasty, ugly hack!!! */ - hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); - if (hRgn == NULL) - { - ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n", - 0, 0, rcWindow.right, iOffsetY, GetLastError ()); - } - - /* Loop through all rectangles in the X region */ - for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) - { - /* Create a Windows region for the X rectangle */ - hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX - 1, - pRects->y1 + iOffsetY - 1, - pRects->x2 + iOffsetX - 1, - pRects->y2 + iOffsetY - 1); - if (hRgnRect == NULL) - { - ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " - "failed: %d\n" - "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", - pRects->x1 + iOffsetX - 1, - pRects->y1 + iOffsetY - 1, - pRects->x2 + iOffsetX - 1, - pRects->y2 + iOffsetY - 1, - GetLastError (), - pRects->x1, pRects->x2, iOffsetX, - pRects->y1, pRects->y2, iOffsetY); - } - - /* Merge the Windows region with the accumulated region */ - if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) - { - ErrorF ("winReshape - CombineRgn () failed: %d\n", - GetLastError ()); - } - - /* Delete the temporary Windows region */ - DeleteObject (hRgnRect); - } - - /* Save a handle to the composite region in the window privates */ - pWinPriv->hRgn = hRgn; - } + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; - REGION_UNINIT(pScreen, &rrNewShape); + /* Load default X icon in case it's not ready yet */ + if (!g_hiconX) + g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); - return; -} -#endif - - -/* - * winTopLevelWindowProc - Window procedure for all top-level Windows windows. - */ - -LRESULT CALLBACK -winTopLevelWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - POINT ptMouse; - HDC hdcUpdate; - PAINTSTRUCT ps; - WindowPtr pWin = NULL; - winPrivWinPtr pWinPriv = NULL; - ScreenPtr s_pScreen = NULL; - winPrivScreenPtr s_pScreenPriv = NULL; - winScreenInfo *s_pScreenInfo = NULL; - HWND hwndScreen = NULL; - DrawablePtr pDraw = NULL; - int iX, iY, iWidth, iHeight, iBorder; - winWMMessageRec wmMsg; - static Bool s_fTracking = FALSE; - static Bool s_fCursor = TRUE; + /* Try and get the icon from WM_HINTS */ + hIcon = winXIconToHICON (pWin); - /* Check if the Windows window property for our X window pointer is valid */ - if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) - { - /* Our X window pointer is valid */ - - /* Get pointers to the drawable and the screen */ - pDraw = &pWin->drawable; - s_pScreen = pWin->drawable.pScreen; - - /* Get a pointer to our window privates */ - pWinPriv = winGetWindowPriv(pWin); - - /* Get pointers to our screen privates and screen info */ - s_pScreenPriv = pWinPriv->pScreenPriv; - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - - /* Get the handle for our screen-sized window */ - /* NOTE: This will be going away at some point, right? Harold Hunt - 2003/01/15 */ - hwndScreen = s_pScreenPriv->hwndScreen; - - /* */ - wmMsg.msg = 0; - wmMsg.hwndWindow = hwnd; - wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); - -#if 1 - wmMsg.iX = pWinPriv->iX; - wmMsg.iY = pWinPriv->iY; - wmMsg.iWidth = pWinPriv->iWidth; - wmMsg.iHeight = pWinPriv->iHeight; -#else - wmMsg.iX = pDraw.x; - wmMsg.iY = pDraw.y; - wmMsg.iWidth = pDraw.width; - wmMsg.iHeight = pDraw.height; -#endif - - -#if 0 - /* - * Print some debugging information - */ - - ErrorF ("hWnd %08X\n", hwnd); - ErrorF ("pWin %08X\n", pWin); - ErrorF ("pDraw %08X\n", pDraw); - ErrorF ("\ttype %08X\n", pWin->drawable.type); - ErrorF ("\tclass %08X\n", pWin->drawable.class); - ErrorF ("\tdepth %08X\n", pWin->drawable.depth); - ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); - ErrorF ("\tid %08X\n", pWin->drawable.id); - ErrorF ("\tx %08X\n", pWin->drawable.x); - ErrorF ("\ty %08X\n", pWin->drawable.y); - ErrorF ("\twidth %08X\n", pWin->drawable.width); - ErrorF ("\thenght %08X\n", pWin->drawable.height); - ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); - ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); - ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex); - ErrorF ("pWinPriv %08X\n", pWinPriv); - ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); - ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); - ErrorF ("hwndScreen %08X\n", hwndScreen); -#endif - } + /* Use default X icon if no icon loaded from WM_HINTS */ + if (!hIcon) + hIcon = g_hiconX; + /* Set standard class name prefix so we can identify window easily */ + strncpy (pszClass, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X)); - - /* Branch on message type */ - switch (message) + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) { - case WM_CREATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_CREATE\n"); -#endif - - /* */ - SetProp (hwnd, - WIN_WINDOW_PROP, - (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); - - /* */ - SetProp (hwnd, - WIN_WID_PROP, - (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); - return 0; - - case WM_PAINT: - /* Only paint if our window handle is valid */ - if (hwndScreen == NULL) - break; - - /* BeginPaint gives us an hdc that clips to the invalidated region */ - hdcUpdate = BeginPaint (hwnd, &ps); - -#if 0 - /* NOTE: Doesn't appear to be used - Harold Hunt - 2003/01/15 */ - /* Get the dimensions of the client area */ - GetClientRect (hwnd, &rcClient); -#endif - - /* Get the position and dimensions of the window */ - iBorder = wBorderWidth (pWin); - iX = pWin->drawable.x; - iY = pWin->drawable.y; - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - - /* Try to copy from the shadow buffer */ - if (!BitBlt (hdcUpdate, - 0, 0, - iWidth, iHeight, - s_pScreenPriv->hdcShadow, - iX, iY, - SRCCOPY)) - { - LPVOID lpMsgBuf; - - /* Display a fancy error message */ - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError (), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, NULL); - - ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", - (LPSTR)lpMsgBuf); - LocalFree (lpMsgBuf); - } - - /* EndPaint frees the DC */ - EndPaint (hwndScreen, &ps); - return 0; - - -#if 1 - case WM_MOUSEMOVE: - /* Unpack the client area mouse coordinates */ - ptMouse.x = GET_X_LPARAM(lParam); - ptMouse.y = GET_Y_LPARAM(lParam); - - /* Translate the client area mouse coordinates to screen coordinates */ - ClientToScreen (hwnd, &ptMouse); - - /* We can't do anything without privates */ - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Has the mouse pointer crossed screens? */ - if (s_pScreen != miPointerCurrentScreen ()) - miPointerSetNewScreen (s_pScreenInfo->dwScreen, - ptMouse.x - s_pScreenInfo->dwXOffset, - ptMouse.y - s_pScreenInfo->dwYOffset); - - /* Are we tracking yet? */ - if (!s_fTracking) - { - TRACKMOUSEEVENT tme; - - /* Setup data structure */ - ZeroMemory (&tme, sizeof (tme)); - tme.cbSize = sizeof (tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwnd; - - /* Call the tracking function */ - if (!(*g_fpTrackMouseEvent) (&tme)) - ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); - - /* Flag that we are tracking now */ - s_fTracking = TRUE; - } - - /* Hide or show the Windows mouse cursor */ - if (s_fCursor) - { - /* Hide Windows cursor */ - s_fCursor = FALSE; - ShowCursor (FALSE); - KillTimer (hwnd, s_nIDPollingMouse); - } - - /* Deliver absolute cursor position to X Server */ - miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset, - ptMouse.y - s_pScreenInfo->dwYOffset, - g_c32LastInputEventTime = GetTickCount ()); - return 0; - - case WM_NCMOUSEMOVE: - /* - * We break instead of returning 0 since we need to call - * DefWindowProc to get the mouse cursor changes - * and min/max/close button highlighting in Windows XP. - * The Platform SDK says that you should return 0 if you - * process this message, but it fails to mention that you - * will give up any default functionality if you do return 0. - */ - - /* We can't do anything without privates */ - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Non-client mouse movement, show Windows cursor */ - if (!s_fCursor) - { - s_fCursor = TRUE; - ShowCursor (TRUE); - SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL); - } - break; - - case WM_MOUSELEAVE: - /* Mouse has left our client area */ - - /* Flag that we are no longer tracking */ - s_fTracking = FALSE; - - /* Show the mouse cursor, if necessary */ - if (!s_fCursor) - { - s_fCursor = TRUE; - ShowCursor (TRUE); - SetTimer (hwnd, s_nIDPollingMouse, MOUSE_POLLING_INTERVAL, NULL); - } - return 0; - - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); - - case WM_LBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); - - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); - - case WM_MBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); - - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); - - case WM_RBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); - -#else - - case WM_MOUSEMOVE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEMOVE*\n"); -#endif - - /* Unpack the client area mouse coordinates */ - ptMouse.x = GET_X_LPARAM(lParam); - ptMouse.y = GET_Y_LPARAM(lParam); - - /* Translate the client area mouse coordinates to screen coordinates */ - ClientToScreen (hwnd, &ptMouse); - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y)); - return 0; - - case WM_NCMOUSEMOVE: - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MOUSELEAVE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_*BUTTON*\n"); -#endif - - /* Pass the message to the root window */ - SendMessage(hwndScreen, message, wParam, MAKELONG(ptMouse.x, ptMouse.y)); - return 0; -#endif - - case WM_MOUSEWHEEL: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEWHEEL\n"); -#endif - - /* Pass the message to the root window */ - SendMessage(hwndScreen, message, wParam, lParam); - return 0; - - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - case WM_SYSDEADCHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_DEADCHAR: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_*KEY*\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - case WM_HOTKEY: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_HOTKEY\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - -#if 1 - case WM_ACTIVATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_ACTIVATE\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - - /* Bail if inactivating */ - if (LOWORD(wParam) == WA_INACTIVE) - return 0; - - /* Check if the current window is the active window in Windows */ - if (GetActiveWindow () == hwnd) - { - /* Tell our Window Manager thread to raise the window */ - wmMsg.msg = WM_WM_RAISE; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - } - - /* Tell our Window Manager thread to activate the window */ - wmMsg.msg = WM_WM_ACTIVATE; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - - return 0; - - case WM_ACTIVATEAPP: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_ACTIVATEAPP\n"); -#endif + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; -#endif - - - case WM_CLOSE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_CLOSE\n"); -#endif - /* Branch on if the window was killed in X already */ - if (pWinPriv->fXKilled) - { - /* Window was killed, go ahead and destroy the window */ - DestroyWindow (hwnd); - } - else + /* 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 (pWin, &res_role) ) { - /* Tell our Window Manager thread to kill the window */ - wmMsg.msg = WM_WM_KILL; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); } - return 0; - case WM_DESTROY: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); -#endif - - /* Branch on if the window was killed in X already */ - if (pWinPriv && !pWinPriv->fXKilled) - { - ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); - - /* Tell our Window Manager thread to kill the window */ - wmMsg.msg = WM_WM_KILL; - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - } - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); -#endif - break; - - case WM_MOVE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOVE - %d ms\n", GetTickCount ()); -#endif - - /* Bail if Windows window is not actually moving */ - if (pWinPriv->iX == (short) LOWORD(lParam) - && pWinPriv->iY == (short) HIWORD(lParam)) - break; - - /* Get new position */ - pWinPriv->iX = (short) LOWORD(lParam); - pWinPriv->iY = (short) HIWORD(lParam); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\t(%d, %d)\n", pWinPriv->iX, pWinPriv->iY); -#endif - - /* Notify the X client that its window is moving */ - if (SubStrSend(pWin, pWin->parent)) - SendConfigureNotify (pWin); - - /* Tell X that the window is moving */ - (s_pScreen->MoveWindow) (pWin, - (int)(short) LOWORD(lParam) - wBorderWidth (pWin), - (int)(short) HIWORD(lParam) - wBorderWidth (pWin), - pWin->nextSib, - VTMove); - return 0; - - case WM_SHOWWINDOW: - /* Bail out if the window is being hidden */ - if (!wParam) - return 0; - - /* Tell X to map the window */ - MapWindow (pWin, wClient(pWin)); - - /* */ - if (!pWin->overrideRedirect) - { - DWORD dwExStyle; - DWORD dwStyle; - RECT rcNew; - int iDx, iDy; - - /* Flag that this window needs to be made active when clicked */ - SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); - - /* Get the standard and extended window style information */ - dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); - - /* */ - if (dwExStyle != WS_EX_APPWINDOW) - { - /* Setup a rectangle with the X window position and size */ - SetRect (&rcNew, - pWinPriv->iX, - pWinPriv->iY, - pWinPriv->iX + pWinPriv->iWidth, - pWinPriv->iY + pWinPriv->iHeight); - -#if 0 - ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", - rcNew.left, rcNew.top, - rcNew.right, rcNew.bottom); -#endif - - /* */ - AdjustWindowRectEx (&rcNew, - WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, - FALSE, - WS_EX_APPWINDOW); - - /* Calculate position deltas */ - iDx = pWinPriv->iX - rcNew.left; - iDy = pWinPriv->iY - rcNew.top; - - /* Calculate new rectangle */ - rcNew.left += iDx; - rcNew.right += iDx; - rcNew.top += iDy; - rcNew.bottom += iDy; - -#if 0 - ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", - rcNew.left, rcNew.top, - rcNew.right, rcNew.bottom); -#endif - - /* Set the window extended style flags */ - SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); - - /* Set the window standard style flags */ - SetWindowLongPtr (hwnd, GWL_STYLE, WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); - - /* Positon the Windows window */ - SetWindowPos (hwnd, HWND_TOP, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - SWP_NOMOVE | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); - - /* Bring the Window window to the foreground */ - SetForegroundWindow (hwnd); - } - } - - /* Setup the Window Manager message */ - wmMsg.msg = WM_WM_MAP; - wmMsg.iWidth = pWinPriv->iWidth; - wmMsg.iHeight = pWinPriv->iHeight; - - /* Tell our Window Manager thread to map the window */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - - /* Setup the Window Manager message */ - wmMsg.msg = WM_WM_RAISE; - - /* Tell our Window Manager thread to raise the window */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - return 0; - - case WM_SIZE: - /* see dix/window.c */ - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_SIZE - %d ms\n", GetTickCount ()); -#endif - - switch (wParam) - { - case SIZE_MINIMIZED: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tSIZE_MINIMIZED\n"); -#endif - - wmMsg.msg = WM_WM_LOWER; - - /* Tell our Window Manager thread to lower the window */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - break; - - case SIZE_RESTORED: - case SIZE_MAXIMIZED: - if (pWinPriv->iWidth == (short) LOWORD(lParam) - && pWinPriv->iHeight == (short) HIWORD(lParam)) - break; - - /* Get the dimensions of the Windows window */ - pWinPriv->iWidth = (short) LOWORD(lParam); - pWinPriv->iHeight = (short) HIWORD(lParam); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); -#endif - - /* Check if resize events are redirected */ - if ((pWin->eventMask | wOtherEventMasks (pWin)) & ResizeRedirectMask) - { - xEvent eventT; - - /* Setup the X event structure */ - eventT.u.u.type = ResizeRequest; - eventT.u.resizeRequest.window = pWin->drawable.id; - eventT.u.resizeRequest.width = pWinPriv->iWidth; - eventT.u.resizeRequest.height = pWinPriv->iHeight; - - /* */ - if (MaybeDeliverEventsToClient (pWin, &eventT, 1, - ResizeRedirectMask, - wClient(pWin)) == 1) - break; - } - - /* Notify the X client that its window is being resized */ - if (SubStrSend (pWin, pWin->parent)) - SendConfigureNotify (pWin); - - /* Tell the X server that the window is being resized */ - (s_pScreen->ResizeWindow) (pWin, - pWinPriv->iX - wBorderWidth (pWin), - pWinPriv->iY - wBorderWidth (pWin), - pWinPriv->iWidth, - pWinPriv->iHeight, - pWin->nextSib); - - /* Tell X to redraw the exposed portions of the window */ - { - RegionRec temp; - - /* Get the region describing the X window clip list */ - REGION_INIT(s_pScreen, &temp, NullBox, 0); - REGION_COPY(s_pScreen, &temp, &pWin->clipList); - - /* Expose the clipped region */ - (*s_pScreen->WindowExposures) (pWin, &temp, NullRegion); - - /* Free the region */ - REGION_UNINIT(s_pScreen, &temp); - } - break; - -#if 0 - case SIZE_MAXIMIZED: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tSIZE_MAXIMIZED\n"); -#endif - - /* Get the dimensions of the window */ - pWinPriv->iWidth = (int)(short) LOWORD(lParam); - pWinPriv->iHeight = (int)(short) HIWORD(lParam); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); -#endif - - /* */ - if ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask) - { - xEvent eventT; - - eventT.u.u.type = ResizeRequest; - eventT.u.resizeRequest.window = pWin->drawable.id; - eventT.u.resizeRequest.width = pWinPriv->iWidth; - eventT.u.resizeRequest.height = pWinPriv->iHeight; - if (MaybeDeliverEventsToClient (pWin, &eventT, 1, - ResizeRedirectMask, - wClient(pWin)) == 1); - } - - - (s_pScreen->ResizeWindow) (pWin, - pWinPriv->iX - wBorderWidth (pWin), - pWinPriv->iY - wBorderWidth (pWin), - pWinPriv->iWidth, - pWinPriv->iHeight, - pWin->nextSib); - break; -#endif - - default: - break; - } - return 0; - - case WM_MOUSEACTIVATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE\n"); -#endif - - /* Check if this window needs to be made active when clicked */ - if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) - { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - MA_NOACTIVATE\n"); -#endif - - /* */ - return MA_NOACTIVATE; - } - break; - - case WM_TIMER: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_TIMER - %d ms\n", GetTickCount ()); -#endif - - /* Branch on the type of timer event that fired */ - if (wParam == s_nIDPollingMouse) - { - POINT point; - - /* Get the current position of the mouse cursor */ - GetCursorPos (&point); - - /* Deliver absolute cursor position to X Server */ - miPointerAbsoluteCursor (point.x, point.y, - g_c32LastInputEventTime = GetTickCount ()); - } - else - { - ErrorF ("winTopLevelWindowProc - Unknown WM_TIMER\n"); - } - return 0; - - default: - break; + free (res_name); + free (res_class); } - return DefWindowProc (hwnd, message, wParam, lParam); -} - - -/* - * winCreateWindowsWindow - Create a Windows window associated with an X window - */ - -static void -winCreateWindowsWindow (WindowPtr pWin) -{ - int iX, iY; - int iWidth; - int iHeight; - int iBorder; - HWND hWnd; - WNDCLASS wc; - winWindowPriv(pWin); + /* Add incrementing window ID to make unique class name */ + sprintf (pszWindowID, "-%x", s_iWindowID++); + strcat (pszClass, pszWindowID); #if CYGMULTIWINDOW_DEBUG - ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); + ErrorF ("winCreateWindowsWindow - Creating class: %s\n", classStr); #endif - iBorder = wBorderWidth (pWin); - - iX = pWin->drawable.x; - iY = pWin->drawable.y; - - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - /* Setup our window class */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = winTopLevelWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = g_hInstance; - wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hIcon = hIcon; wc.hCursor = 0; wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = WINDOW_CLASS_X; + wc.lpszClassName = pszClass; RegisterClass (&wc); /* Create the window */ - hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ - WINDOW_CLASS_X, /* Class name */ - WINDOW_TITLE_X, /* Window name */ + hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - iX, /* Horizontal position */ - iY, /* Vertical position */ - iWidth, /* Right edge */ - iHeight, /* Bottom edge */ - (HWND) NULL, /* No parent or owner window */ - (HMENU) NULL, /* No menu */ - GetModuleHandle (NULL), /* Instance handle */ - pWin); /* ScreenPrivates */ + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pWin); /* ScreenPrivates */ if (hWnd == NULL) { ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", @@ -1395,7 +549,9 @@ winCreateWindowsWindow (WindowPtr pWin) pWinPriv->hWnd = hWnd; - + /* Cause the "Always On Top" to be added in main WNDPROC */ + PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); + SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); /* Flag that this Windows window handles its own activation */ @@ -1404,7 +560,8 @@ winCreateWindowsWindow (WindowPtr pWin) /* - * winDestroyWindowsWindow - Destroy a Windows window associated with an X window + * winDestroyWindowsWindow - Destroy a Windows window associated + * with an X window */ static void @@ -1412,21 +569,30 @@ winDestroyWindowsWindow (WindowPtr pWin) { MSG msg; winWindowPriv(pWin); + HICON hiconClass; + HMODULE hInstance; + int iReturn; + char pszClass[512]; #if CYGMULTIWINDOW_DEBUG ErrorF ("winDestroyWindowsWindow\n"); #endif - /* Bail out if the Windows window handle is invalid */ if (pWinPriv->hWnd == NULL) return; - SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, 0); + + /* Store the info we need to destroy after this window is gone */ + hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE); + hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON); + iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512); + /* 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 */ @@ -1437,7 +603,29 @@ winDestroyWindowsWindow (WindowPtr pWin) DispatchMessage (&msg); } } - + + /* Only if we were able to get the name */ + if (iReturn) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass); +#endif + iReturn = UnregisterClass (pszClass, hInstance); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn); +#endif + + /* Only delete if it's not the default */ + if (hiconClass != g_hiconX) + { + iReturn = DestroyIcon (hiconClass); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - %d\n", iReturn); +#endif + } + } + #if CYGMULTIWINDOW_DEBUG ErrorF ("-winDestroyWindowsWindow\n"); #endif @@ -1445,7 +633,8 @@ winDestroyWindowsWindow (WindowPtr pWin) /* - * winUpdateWindowsWindow - Redisplay/redraw a Windows window associated with an X window + * winUpdateWindowsWindow - Redisplay/redraw a Windows window + * associated with an X window */ static void @@ -1489,19 +678,57 @@ winUpdateWindowsWindow (WindowPtr pWin) } +/* + * 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; +} +/* + * winMoveXWindow - + */ +void +winMoveXWindow (WindowPtr pWin, int x, int y) +{ + XID *vlist = malloc(sizeof(long)*2); + (CARD32*)vlist[0] = x; + (CARD32*)vlist[1] = y; + ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + free(vlist); +} -typedef struct { - pointer value; - XID id; -} WindowIDPairRec, *WindowIDPairPtr; +/* + * winResizeXWindow - + */ +void +winResizeXWindow (WindowPtr pWin, int w, int h) +{ + XID *vlist = malloc(sizeof(long)*2); + (CARD32*)vlist[0] = w; + (CARD32*)vlist[1] = h; + ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin)); + free(vlist); +} /* @@ -1520,55 +747,93 @@ winFindWindow (pointer value, XID id, pointer cdata) } +#if 0 /* - * winGetWindowID - + * winRestackXWindow - */ -static XID -winGetWindowID (WindowPtr pWin) +static void +winRestackXWindow (WindowPtr pWin, int smode) { - WindowIDPairRec wi = {pWin, 0}; - ClientPtr c = wClient(pWin); - - /* */ - FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); + XID *vlist = malloc(sizeof(unsigned long)); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); -#endif + if (vlist == NULL) + { + ErrorF ("winRestackXWindow - malloc () failed\n"); + return; + } - return wi.id; + if (pWin == NULL) + { + ErrorF ("winRestackXWindow - NULL window\n"); + free(vlist); + return; + } + + *((unsigned long*)vlist) = smode; + ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); + + free(vlist); } +#endif /* - * SendConfigureNotify - + * winReorderWindowsMultiWindow - */ -static void -SendConfigureNotify(WindowPtr pWin) +void +winReorderWindowsMultiWindow (ScreenPtr pScreen) { - xEvent event; - winWindowPriv(pWin); - - event.u.u.type = ConfigureNotify; - event.u.configureNotify.window = pWin->drawable.id; - - if (pWin->nextSib) - event.u.configureNotify.aboveSibling = pWin->nextSib->drawable.id; - else - event.u.configureNotify.aboveSibling = None; + winScreenPriv(pScreen); + HWND hwnd = NULL; + WindowPtr pWin = NULL; + WindowPtr pWinSib = NULL; - event.u.configureNotify.x = pWinPriv->iX - wBorderWidth (pWin); - event.u.configureNotify.y = pWinPriv->iY - wBorderWidth (pWin); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winOrderWindowsMultiWindow\n"); +#endif - event.u.configureNotify.width = pWinPriv->iWidth; - event.u.configureNotify.height = pWinPriv->iHeight; + pScreenPriv->fRestacking = TRUE; - event.u.configureNotify.borderWidth = wBorderWidth (pWin); + if (pScreenPriv->fWindowOrderChanged) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winOrderWindowsMultiWindow - Need to restack\n"); +#endif + hwnd = GetTopWindow (NULL); - event.u.configureNotify.override = pWin->overrideRedirect; + while (hwnd) + { + if (GetProp (hwnd, WIN_WINDOW_PROP)) + { + pWinSib = pWin; + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + if (pWinSib) + { + XID *vlist = malloc (sizeof(long) * 2); + + if (vlist == NULL) + { + ErrorF ("winOrderWindowsMultiWindow - malloc () " + "failed\n"); + return; + } + + ((long*)vlist)[0] = winGetWindowID (pWinSib); + ((long*)vlist)[1] = Below; + + ConfigureWindow (pWin, CWSibling | CWStackMode, + vlist, wClient(pWin)); + + free (vlist); + } + } + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); + } + } - /* */ - DeliverEvents (pWin, &event, 1, NullWindow); + pScreenPriv->fRestacking = FALSE; + pScreenPriv->fWindowOrderChanged = FALSE; } diff --git a/programs/Xserver/hw/xwin/winmultiwindowwm.c b/programs/Xserver/hw/xwin/winmultiwindowwm.c index 77eaa3352..91663c532 100644 --- a/programs/Xserver/hw/xwin/winmultiwindowwm.c +++ b/programs/Xserver/hw/xwin/winmultiwindowwm.c @@ -61,7 +61,6 @@ #define WIN_CONNECT_RETRIES 5 #define WIN_CONNECT_DELAY 5 #define WIN_MSG_QUEUE_FNAME "/dev/windows" -#define WM_WM_X_EVENT 1 #define WIN_JMP_OKAY 0 #define WIN_JMP_ERROR_IO 2 @@ -87,6 +86,7 @@ typedef struct _WMInfo { WMMsgQueueRec wmMsgQueue; Atom atmWmProtos; Atom atmWmDelete; + Atom atmPrivMap; } WMInfoRec, *WMInfoPtr; typedef struct _WMProcArgRec { @@ -95,6 +95,13 @@ typedef struct _WMProcArgRec { pthread_mutex_t *ppmServerStarted; } WMProcArgRec, *WMProcArgPtr; +typedef struct _XMsgProcArgRec { + Display *pDisplay; + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; +} XMsgProcArgRec, *XMsgProcArgPtr; + /* * References to external symbols @@ -103,6 +110,7 @@ typedef struct _WMProcArgRec { extern char *display; extern void ErrorF (const char* /*f*/, ...); extern Bool g_fCalledSetLocale; +extern Bool g_fCalledXInitThreads; /* @@ -113,7 +121,7 @@ static void PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode); static WMMsgNodePtr -PopMessage (WMMsgQueuePtr pQueue); +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo); static Bool InitQueue (WMMsgQueuePtr pQueue); @@ -124,15 +132,18 @@ GetWindowName (Display * pDpy, Window iWin, char **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 Bool -FlushXEvents (WMInfoPtr pWMInfo); - static int winMultiWindowWMErrorHandler (Display *pDisp, XErrorEvent *e); +static void * +winMultiWindowXMsgProc (void *pArg); + static void winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); @@ -212,7 +223,7 @@ PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) } -#if 0 +#if CYGMULTIWINDOW_DEBUG /* * QueueSize - Return the size of the queue */ @@ -233,11 +244,11 @@ QueueSize (WMMsgQueuePtr pQueue) /* - * PopMessage - + * PopMessage - Pop a message from the queue */ static WMMsgNodePtr -PopMessage (WMMsgQueuePtr pQueue) +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) { WMMsgNodePtr pNode; @@ -339,7 +350,7 @@ InitQueue (WMMsgQueuePtr pQueue) /* - * GetWindowName - + * GetWindowName - Retrieve the title of an X Window */ static void @@ -360,7 +371,9 @@ GetWindowName (Display *pDisplay, Window iWin, char **ppName) nResult = XGetWMName (pDisplay, iWin, &xtpName); if (!nResult || !xtpName.value || !xtpName.nitems) { +#if CYGMULTIWINDOW_DEBUG ErrorF ("GetWindowName - XGetWMName failed. No name.\n"); +#endif return; } @@ -375,7 +388,7 @@ GetWindowName (Display *pDisplay, Window iWin, char **ppName) } #if CYGMULTIWINDOW_DEBUG - ErrorF ("XA_STRING %s\n", *ppName); + ErrorF ("GetWindowName - XA_STRING %s\n", *ppName); #endif } else @@ -383,7 +396,7 @@ GetWindowName (Display *pDisplay, Window iWin, char **ppName) XmbTextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum); /* */ - if (nNum && *ppList) + if (nNum && ppList && *ppList) { XFree (xtpName.value); *ppName = strdup (*ppList); @@ -391,13 +404,14 @@ GetWindowName (Display *pDisplay, Window iWin, char **ppName) } #if CYGMULTIWINDOW_DEBUG - ErrorF ("%s %s\n", XGetAtomName (pDisplay, xtpName.encoding), *ppName); + ErrorF ("GetWindowName - %s %s\n", + XGetAtomName (pDisplay, xtpName.encoding), *ppName); #endif } #if CYGMULTIWINDOW_DEBUG - ErrorF ("-GetWindowName\n"); + ErrorF ("GetWindowName - Returning\n"); #endif } @@ -425,6 +439,62 @@ SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData) /* + * Updates the name of a HWND according to its X WM_NAME property + */ + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow) +{ + char *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, + 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) + SetWindowText (hWnd, pszName); + free (pszName); + } +} + + +/* * winMultiWindowWMProc */ @@ -447,7 +517,7 @@ winMultiWindowWMProc (void *pArg) WMMsgNodePtr pNode; /* Pop a message off of our queue */ - pNode = PopMessage (&pWMInfo->wmMsgQueue); + pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo); if (pNode == NULL) { /* Bail if PopMessage returns without a message */ @@ -496,25 +566,17 @@ winMultiWindowWMProc (void *pArg) #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_MAP\n"); #endif - { - XWindowAttributes attr; - char *pszName; -#if 0 - XWMHints *pHints; -#endif - - /* Get the window attributes */ - XGetWindowAttributes (pWMInfo->pDisplay, - pNode->msg.iWindow, - &attr); - if (!attr.override_redirect) - { - /* Set the Windows window name */ - GetWindowName(pWMInfo->pDisplay, pNode->msg.iWindow, &pszName); - SetWindowText (pNode->msg.hwndWindow, pszName); - free (pszName); - } - } + /* Put a note as to the HWND associated with this Window */ + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + UpdateName (pWMInfo, pNode->msg.iWindow); + winUpdateIcon (pNode->msg.iWindow); break; case WM_WM_UNMAP: @@ -571,9 +633,12 @@ winMultiWindowWMProc (void *pArg) CurrentTime); break; - case WM_WM_X_EVENT: - /* Process all X events in the Window Manager event queue */ - FlushXEvents (pWMInfo); + case WM_WM_NAME_EVENT: + UpdateName (pWMInfo, pNode->msg.iWindow); + break; + + case WM_WM_HINTS_EVENT: + winUpdateIcon (pNode->msg.iWindow); break; default: @@ -605,71 +670,210 @@ winMultiWindowWMProc (void *pArg) /* - * FlushXEvents - Process any pending X events + * winMultiWindowWMErrorHandler - Our application specific error handler */ -static Bool -FlushXEvents (WMInfoPtr pWMInfo) +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) { - XEvent event; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("FlushXEvents ()\n"); -#endif + char pszErrorMsg[100]; - /* Process all pending events */ - while (XPending (pWMInfo->pDisplay)) + if (pErr->request_code == X_ChangeWindowAttributes + && pErr->error_code == BadAccess) { - /* Get the next event - will not block because one is ready */ - XNextEvent (pWMInfo->pDisplay, &event); - + ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " + "BadAccess.\n"); #if 0 - /* Branch on the event type */ - switch (event.type) - { - } + pthread_exit (NULL); #endif + return 0; } + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("-FlushXEvents ()\n"); + if (pErr->error_code == BadWindow + || pErr->error_code == BadMatch + || pErr->error_code == BadDrawable) + { +#if 0 + pthread_exit (NULL); #endif + return 0; + } - return True; + pthread_exit (NULL); + return 0; } /* - * winMultiWindowWMErrorHandler - Our application specific error handler + * */ -static int -winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) +static void * +winMultiWindowXMsgProc (void *pArg) { - char pszErrorMsg[100]; + winWMMessageRec msg; + XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg; + char pszDisplay[512]; + int iRetries; + XEvent event; + Atom atmWmName; + Atom atmWmHints; + int iReturn; + XIconSize *xis; - if (pErr->request_code == X_ChangeWindowAttributes - && pErr->error_code == BadAccess) + ErrorF ("winMultiWindowXMsgProc - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL, bailing.\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 ("ChangeWindowAttributes BadAccess.\n"); + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d\n", + iReturn); pthread_exit (NULL); } + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n"); + + /* Only call XInitThreads once for the whole process */ + if (!g_fCalledXInitThreads) + { + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed.\n"); + pthread_exit (NULL); + } + + /* Flag that XInitThreads has been called */ + g_fCalledXInitThreads = TRUE; + + ErrorF ("winMultiWindowXMsgProc - XInitThreads () returned.\n"); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n"); + + /* 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); - XGetErrorText (pDisplay, - pErr->error_code, - pszErrorMsg, - sizeof (pszErrorMsg)); - ErrorF ("ERROR: %s\n", pszErrorMsg); + iRetries = 0; - if (pErr->error_code==BadWindow - || pErr->error_code==BadMatch - || pErr->error_code==BadDrawable) + /* 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\f", + 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 ("winMultiWindowXMsgProcwinInitMultiWindowWM - " + "Failed opening the display, giving up.\n\f"); pthread_exit (NULL); } - pthread_exit (NULL); - return 0; + ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowWMErrorHandler); + XSetIOErrorHandler (winMutliWindowWMIOErrorHandler); + + XSelectInput (pProcArg->pDisplay, + RootWindow(pProcArg->pDisplay, pProcArg->dwScreen), + SubstructureNotifyMask); + + /* 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); + + /* Loop until we explicitly break out */ + while (1) + { + /* Fetch next event */ + XNextEvent (pProcArg->pDisplay, &event); + + /* Branch on event type */ + if (event.type == CreateNotify) + { + XSelectInput (pProcArg->pDisplay, + event.xcreatewindow.window, + PropertyChangeMask); + } + 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); + } + } } @@ -682,12 +886,14 @@ winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) Bool winInitWM (void **ppWMInfo, pthread_t *ptWMProc, + pthread_t *ptXMsgProc, pthread_mutex_t *ppmServerStarted, int dwScreen) { - WMProcArgPtr pArg = (WMProcArgPtr)malloc (sizeof(WMProcArgRec)); - WMInfoPtr pWMInfo = (WMInfoPtr)malloc (sizeof(WMInfoRec)); - + 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) { @@ -714,7 +920,18 @@ winInitWM (void **ppWMInfo, if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg)) { /* Bail if thread creation failed */ - ErrorF ("winInitWM - pthread_create failed.\n"); + 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; + if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed on XMSG.\n"); return FALSE; } @@ -788,21 +1005,28 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) /* Flag that we have called setlocale */ g_fCalledSetLocale = TRUE; - /* Release the garbage mutex */ + /* Only call XInitThreads once for the whole process */ + if (!g_fCalledXInitThreads) + { + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winInitMultiWindowWM - XInitThreads () failed.\n"); + pthread_exit (NULL); + } + + /* Flag that XInitThreads has been called */ + g_fCalledXInitThreads = TRUE; + + ErrorF ("winInitMultiWindowWM - XInitThreads () returned.\n"); + } + + /* Release the server started mutex */ pthread_mutex_unlock (pProcArg->ppmServerStarted); ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winInitMultiWindowWM - XInitThreads () failed.\n"); - pthread_exit (NULL); - } - - ErrorF ("winInitMultiWindowWM - XInitThreads () returned.\n"); - - /* Set jump point for Error exits */ + /* Set jump point for IO Error exits */ iReturn = setjmp (g_jmpEntry); /* Check if we should continue operations */ @@ -820,7 +1044,11 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) } /* Setup the display connection string x */ - snprintf (pszDisplay, 512, "127.0.0.1:%s.%d", display, pProcArg->dwScreen); + snprintf (pszDisplay, + 512, + "127.0.0.1:%s.%d", + display, + (int) pProcArg->dwScreen); /* Print the display connection string */ ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay); @@ -866,6 +1094,9 @@ winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay, "WM_DELETE_WINDOW", False); + pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay, + WIN_HWND_CACHE, + False); } diff --git a/programs/Xserver/hw/xwin/winmultiwindowwndproc.c b/programs/Xserver/hw/xwin/winmultiwindowwndproc.c new file mode 100644 index 000000000..8e1882a15 --- /dev/null +++ b/programs/Xserver/hw/xwin/winmultiwindowwndproc.c @@ -0,0 +1,812 @@ +/* + *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 + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwindow.c,v 1.5 2002/11/07 10:31:32 alanh Exp $ */ + +#include "win.h" +#include "dixevents.h" + + +/* + * External global variables + */ + +extern Bool g_fCursor; + + +/* + * Global variables + */ + +HICON g_hiconX = NULL; + + +/* + * Local globals + */ + +static UINT_PTR g_uipMousePollingTimerID = 0; + + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 +#define WIN_MULTIWINDOW_SHAPE YES + + +/* + * winTopLevelWindowProc - Window procedure for all top-level Windows windows. + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + POINT ptMouse; + HDC hdcUpdate; + PAINTSTRUCT ps; + WindowPtr pWin = NULL; + winPrivWinPtr pWinPriv = NULL; + ScreenPtr s_pScreen = NULL; + winPrivScreenPtr s_pScreenPriv = NULL; + winScreenInfo *s_pScreenInfo = NULL; + HWND hwndScreen = NULL; + DrawablePtr pDraw = NULL; + int iX, iY, iWidth, iHeight, iBorder; + winWMMessageRec wmMsg; + Bool fWMMsgInitialized = FALSE; + static Bool s_fTracking = FALSE; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + /* Our X window pointer is valid */ + + /* Get pointers to the drawable and the screen */ + pDraw = &pWin->drawable; + s_pScreen = pWin->drawable.pScreen; + + /* Get a pointer to our window privates */ + pWinPriv = winGetWindowPriv(pWin); + + /* Get pointers to our screen privates and screen info */ + s_pScreenPriv = pWinPriv->pScreenPriv; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + + /* Get the handle for our screen-sized window */ + hwndScreen = s_pScreenPriv->hwndScreen; + + /* */ + wmMsg.msg = 0; + wmMsg.hwndWindow = hwnd; + wmMsg.iWindow = (Window)GetProp (hwnd, WIN_WID_PROP); + + wmMsg.iX = pWinPriv->iX; + wmMsg.iY = pWinPriv->iY; + wmMsg.iWidth = pWinPriv->iWidth; + wmMsg.iHeight = pWinPriv->iHeight; + + fWMMsgInitialized = TRUE; + +#if 0 + /* + * Print some debugging information + */ + + ErrorF ("hWnd %08X\n", hwnd); + ErrorF ("pWin %08X\n", pWin); + ErrorF ("pDraw %08X\n", pDraw); + ErrorF ("\ttype %08X\n", pWin->drawable.type); + ErrorF ("\tclass %08X\n", pWin->drawable.class); + ErrorF ("\tdepth %08X\n", pWin->drawable.depth); + ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); + ErrorF ("\tid %08X\n", pWin->drawable.id); + ErrorF ("\tx %08X\n", pWin->drawable.x); + ErrorF ("\ty %08X\n", pWin->drawable.y); + ErrorF ("\twidth %08X\n", pWin->drawable.width); + ErrorF ("\thenght %08X\n", pWin->drawable.height); + ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); + ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); + ErrorF ("g_iWindowPrivateIndex %d\n", g_iWindowPrivateIndex); + ErrorF ("pWinPriv %08X\n", pWinPriv); + ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); + ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); + ErrorF ("hwndScreen %08X\n", hwndScreen); +#endif + } + + /* Branch on message type */ + switch (message) + { + case WM_CREATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_CREATE\n"); +#endif + + /* */ + SetProp (hwnd, + WIN_WINDOW_PROP, + (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); + + /* */ + SetProp (hwnd, + WIN_WID_PROP, + (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); + + return 0; + + + case WM_INIT_SYS_MENU: + /* + * Add Always On Top command to system menu + */ + { + HMENU sys; + + sys = GetSystemMenu (hwnd, FALSE); + + AppendMenu (sys, MF_SEPARATOR, 0, NULL); + AppendMenu (sys, MF_STRING, ID_APP_ALWAYS_ON_TOP, "Always On Top"); + } + return 0; + + case WM_SYSCOMMAND: + /* + * Any window menu items go through here, presently only Always On Top + */ + if (LOWORD(wParam) == ID_APP_ALWAYS_ON_TOP) + { + DWORD dwExStyle; + + /* Get extended window style */ + dwExStyle = GetWindowLong (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); + + return 0; + } + break; + + case WM_INITMENU: + /* Checks/Unchecks any menu items before they are displayed */ + { + DWORD dwExStyle; + + /* Get extended window style */ + dwExStyle = GetWindowLong (hwnd, GWL_EXSTYLE); + + if (dwExStyle & WS_EX_TOPMOST) + CheckMenuItem ((HMENU)wParam, + ID_APP_ALWAYS_ON_TOP, + MF_BYCOMMAND | MF_CHECKED); + else + CheckMenuItem ((HMENU)wParam, + ID_APP_ALWAYS_ON_TOP, + MF_BYCOMMAND | MF_UNCHECKED); + } + return 0; + + case WM_PAINT: + /* Only paint if our window handle is valid */ + if (hwndScreen == NULL) + break; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (hwnd, &ps); + + /* Get the position and dimensions of the window */ + iBorder = wBorderWidth (pWin); + iX = pWin->drawable.x; + iY = pWin->drawable.y; + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Try to copy from the shadow buffer */ + if (!BitBlt (hdcUpdate, + 0, 0, + iWidth, iHeight, + s_pScreenPriv->hdcShadow, + iX, iY, + SRCCOPY)) + { + LPVOID lpMsgBuf; + + /* Display a fancy error message */ + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winTopLevelWindowProc - BitBlt failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } + + /* EndPaint frees the DC */ + EndPaint (hwndScreen, &ps); + return 0; + + case WM_MOUSEMOVE: + /* Unpack the client area mouse coordinates */ + ptMouse.x = GET_X_LPARAM(lParam); + ptMouse.y = GET_Y_LPARAM(lParam); + + /* Translate the client area mouse coordinates to screen coordinates */ + ClientToScreen (hwnd, &ptMouse); + + /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */ + ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); + ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Has the mouse pointer crossed screens? */ + if (s_pScreen != miPointerCurrentScreen ()) + miPointerSetNewScreen (s_pScreenInfo->dwScreen, + ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset); + + /* Are we tracking yet? */ + if (!s_fTracking) + { + TRACKMOUSEEVENT tme; + + /* Setup data structure */ + ZeroMemory (&tme, sizeof (tme)); + tme.cbSize = sizeof (tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + + /* Call the tracking function */ + if (!(*g_fpTrackMouseEvent) (&tme)) + ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Hide or show the Windows mouse cursor */ + if (g_fCursor) + { + /* Hide Windows cursor */ + g_fCursor = FALSE; + ShowCursor (FALSE); + } + + /* Kill the timer used to poll mouse events */ + if (g_uipMousePollingTimerID != 0) + { + KillTimer (s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); + g_uipMousePollingTimerID = 0; + } + + /* Deliver absolute cursor position to X Server */ + miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + return 0; + + case WM_NCMOUSEMOVE: + /* + * We break instead of returning 0 since we need to call + * DefWindowProc to get the mouse cursor changes + * and min/max/close button highlighting in Windows XP. + * The Platform SDK says that you should return 0 if you + * process this message, but it fails to mention that you + * will give up any default functionality if you do return 0. + */ + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Non-client mouse movement, show Windows cursor */ + if (!g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + break; + + case WM_MOUSELEAVE: + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* Show the mouse cursor, if necessary */ + if (!g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + + case WM_MOUSEWHEEL: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEWHEEL\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_KILLFOCUS: + /* Pop any pressed keys since we are losing keyboard focus */ + winKeybdReleaseKeys (); + return 0; + + case WM_SYSDEADCHAR: + case WM_DEADCHAR: + /* + * NOTE: We do nothing with WM_*CHAR messages, + * nor does the root window, so we can just toss these messages. + */ + return 0; + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_*KEYDOWN\n"); +#endif + + /* + * Don't pass Alt-F4 key combo to root window, + * let Windows translate to WM_CLOSE and close this top-level window. + * + * NOTE: We purposely don't check the fUseWinKillKey setting because + * it should only apply to the key handling for the root window, + * not for top-level window-manager windows. + * + * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window + * because that is a key combo that no X app should be expecting to + * receive, since it has historically been used to shutdown the X server. + * Passing Ctrl-Alt-Backspace to the root window preserves that + * behavior, assuming that -unixkill has been passed as a parameter. + */ + if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000)) + break; + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_SYSKEYUP: + case WM_KEYUP: + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_*KEYUP\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_HOTKEY: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_HOTKEY\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_ACTIVATE\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + + if (s_pScreenPriv != NULL) + s_pScreenPriv->fWindowOrderChanged = TRUE; + + if (LOWORD(wParam) != WA_INACTIVE) + { + /* Tell our Window Manager thread to activate the window */ + wmMsg.msg = WM_WM_ACTIVATE; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + return 0; + + case WM_ACTIVATEAPP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_ACTIVATEAPP\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_CLOSE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_CLOSE\n"); +#endif + /* Branch on if the window was killed in X already */ + if (pWinPriv->fXKilled) + { + /* Window was killed, go ahead and destroy the window */ + DestroyWindow (hwnd); + } + else + { + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + return 0; + + case WM_DESTROY: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); +#endif + + /* Branch on if the window was killed in X already */ + if (pWinPriv && !pWinPriv->fXKilled) + { + ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); + + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_DESTROY\n"); +#endif + break; + + case WM_MOVE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOVE - %d ms\n", GetTickCount ()); +#endif + + /* Bail if Windows window is not actually moving */ + if (pWinPriv->iX == (short) LOWORD(lParam) + && pWinPriv->iY == (short) HIWORD(lParam)) + break; + + /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */ + { + WINDOWPLACEMENT windPlace; + windPlace.length = sizeof(WINDOWPLACEMENT); + + /* Get current window placement */ + GetWindowPlacement(hwnd, &windPlace); + + /* Bail if maximizing */ + if (windPlace.showCmd == SW_MAXIMIZE + || windPlace.showCmd == SW_SHOWMAXIMIZED) + break; + } + + /* Get new position */ + pWinPriv->iX = (short) LOWORD(lParam); + pWinPriv->iY = (short) HIWORD(lParam); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d)\n", pWinPriv->iX, pWinPriv->iY); +#endif + + winMoveXWindow (pWin, + (LOWORD(lParam) - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN)), + (HIWORD(lParam) - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN))); + return 0; + + case WM_SHOWWINDOW: + /* Bail out if the window is being hidden */ + if (!wParam) + return 0; + + /* Tell X to map the window */ + MapWindow (pWin, wClient(pWin)); + + /* */ + if (!pWin->overrideRedirect) + { + DWORD dwExStyle; + DWORD dwStyle; + RECT rcNew; + int iDx, iDy; + + /* Flag that this window needs to be made active when clicked */ + SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); + + /* Get the standard and extended window style information */ + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); + + /* */ + if (dwExStyle != WS_EX_APPWINDOW) + { + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pWinPriv->iX, + pWinPriv->iY, + pWinPriv->iX + pWinPriv->iWidth, + pWinPriv->iY + pWinPriv->iHeight); + +#if 0 + ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + FALSE, + WS_EX_APPWINDOW); + + /* Calculate position deltas */ + iDx = pWinPriv->iX - rcNew.left; + iDy = pWinPriv->iY - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; + +#if 0 + ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* Set the window extended style flags */ + SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (hwnd, GWL_STYLE, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); + + /* Positon the Windows window */ + SetWindowPos (hwnd, HWND_TOP, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + SWP_NOMOVE | SWP_FRAMECHANGED + | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + /* Bring the Windows window to the foreground */ + SetForegroundWindow (hwnd); + } + } + + /* Setup the Window Manager message */ + wmMsg.msg = WM_WM_MAP; + wmMsg.iWidth = pWinPriv->iWidth; + wmMsg.iHeight = pWinPriv->iHeight; + + /* Tell our Window Manager thread to map the window */ + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + + if (s_pScreenPriv != NULL) + s_pScreenPriv->fWindowOrderChanged = TRUE; + return 0; + + case WM_SIZE: + /* see dix/window.c */ + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_SIZE - %d ms\n", GetTickCount ()); +#endif + + /* Branch on type of resizing occurring */ + switch (wParam) + { + case SIZE_MINIMIZED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tSIZE_MINIMIZED\n"); +#endif + if (s_pScreenPriv != NULL) + s_pScreenPriv->fWindowOrderChanged = TRUE; + break; + + case SIZE_RESTORED: + case SIZE_MAXIMIZED: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("SIZE_RESTORED || SIZE_MAXIMIZED\n"); +#endif + /* Break out if nothing to do */ + if (pWinPriv->iWidth == (short) LOWORD(lParam) + && pWinPriv->iHeight == (short) HIWORD(lParam)) + break; + + /* Get the dimensions of the resized Windows window */ + pWinPriv->iWidth = (short) LOWORD(lParam); + pWinPriv->iHeight = (short) HIWORD(lParam); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\t(%d, %d)\n", pWinPriv->iWidth, pWinPriv->iHeight); +#endif + + /* + * If we're maximizing the window has been moved to upper left + * of current screen. Now it is safe for X to know about this. + */ + if (wParam == SIZE_MAXIMIZED) + { + POINT ptHome; + + /* Flag that we are being maximized and store info for restore */ + pWinPriv->fNeedRestore = TRUE; + pWinPriv->ptRestore.x = pWinPriv->iX; + pWinPriv->ptRestore.y = pWinPriv->iY; + + /* Get screen location of window root */ + ptHome.x = 0; + ptHome.y = 0; + ClientToScreen (hwnd, &ptHome); + + /* Map from screen (-X,-Y) to (0,0) root coords */ + winMoveXWindow (pWin, + ptHome.x - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN), + ptHome.y - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN)); + } + else if (wParam == SIZE_RESTORED && pWinPriv->fNeedRestore) + { + /* If need restore and !maximized then move to cached position */ + WINDOWPLACEMENT windPlace; + + windPlace.length = sizeof (WINDOWPLACEMENT); + + GetWindowPlacement (hwnd, &windPlace); + + if (windPlace.showCmd != SW_MAXIMIZE + && windPlace.showCmd != SW_SHOWMAXIMIZED) + { + pWinPriv->fNeedRestore = FALSE; + winMoveXWindow (pWin, + pWinPriv->ptRestore.x - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN), + pWinPriv->ptRestore.y - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN)); + } + } + + /* Perform the resize and notify the X client */ + winResizeXWindow (pWin, + (short) LOWORD(lParam), + (short) HIWORD(lParam)); + break; + + default: + break; + } + return 0; + + case WM_MOUSEACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE\n"); +#endif + + /* Check if this window needs to be made active when clicked */ + if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " + "MA_NOACTIVATE\n"); +#endif + + /* */ + return MA_NOACTIVATE; + } + break; + + default: + break; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} diff --git a/programs/Xserver/hw/xwin/winnativegdi.c b/programs/Xserver/hw/xwin/winnativegdi.c index edda83541..0c21f1d33 100644 --- a/programs/Xserver/hw/xwin/winnativegdi.c +++ b/programs/Xserver/hw/xwin/winnativegdi.c @@ -27,7 +27,7 @@ * * Authors: Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/winnativegdi.c,v 1.12 2002/07/05 09:19:26 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winnativegdi.c,v 1.13 2002/10/17 08:18:22 alanh Exp $ */ #include "win.h" @@ -65,6 +65,17 @@ winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) ErrorF ("winCloseScreenNativeGDI - Destroying window\n"); + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + /* Kill our window */ if (pScreenPriv->hwndScreen) { diff --git a/programs/Xserver/hw/xwin/winpfbdd.c b/programs/Xserver/hw/xwin/winpfbdd.c index af50e9ff3..33cb42eb1 100644 --- a/programs/Xserver/hw/xwin/winpfbdd.c +++ b/programs/Xserver/hw/xwin/winpfbdd.c @@ -30,12 +30,19 @@ * Peter Busch * Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/winpfbdd.c,v 1.16 2002/07/05 09:19:26 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winpfbdd.c,v 1.17 2002/10/17 08:18:22 alanh Exp $ */ #include "win.h" /* + * External global variables + */ + +extern const GUID _IID_IDirectDraw2; + + +/* * Create a DirectDraw primary surface */ @@ -259,6 +266,17 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) pScreenPriv->pdd = NULL; } + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + /* Kill our window */ if (pScreenPriv->hwndScreen) { diff --git a/programs/Xserver/hw/xwin/winscrinit.c b/programs/Xserver/hw/xwin/winscrinit.c index aa4c9043a..1405e3152 100644 --- a/programs/Xserver/hw/xwin/winscrinit.c +++ b/programs/Xserver/hw/xwin/winscrinit.c @@ -510,6 +510,11 @@ winFinishScreenInitFB (int index, /* Set the ServerStarted flag to false */ pScreenPriv->fServerStarted = FALSE; + /* Set the WindowOrderChanged flag to false */ + pScreenPriv->fWindowOrderChanged = FALSE; + + pScreenPriv->fRestacking = FALSE; + #if CYGDEBUG || YES if (pScreenInfo->fMultiWindow) ErrorF ("winFinishScreenInitFB - Calling winInitWM.\n"); @@ -519,6 +524,7 @@ winFinishScreenInitFB (int index, if (pScreenInfo->fMultiWindow && !winInitWM (&pScreenPriv->pWMInfo, &pScreenPriv->ptWMProc, + &pScreenPriv->ptXMsgProc, &pScreenPriv->pmServerStarted, pScreenInfo->dwScreen)) { diff --git a/programs/Xserver/hw/xwin/winshaddd.c b/programs/Xserver/hw/xwin/winshaddd.c index a56d17749..2c202a01c 100644 --- a/programs/Xserver/hw/xwin/winshaddd.c +++ b/programs/Xserver/hw/xwin/winshaddd.c @@ -40,7 +40,7 @@ */ #ifdef DEFINE_GUID #undef DEFINE_GUID -#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #endif /* DEFINE_GUID */ @@ -671,6 +671,17 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) pScreenPriv->pdd = NULL; } + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + /* Kill our window */ if (pScreenPriv->hwndScreen) { diff --git a/programs/Xserver/hw/xwin/winshadddnl.c b/programs/Xserver/hw/xwin/winshadddnl.c index 060f8dae0..9c15d064d 100644 --- a/programs/Xserver/hw/xwin/winshadddnl.c +++ b/programs/Xserver/hw/xwin/winshadddnl.c @@ -40,7 +40,7 @@ */ #ifdef DEFINE_GUID #undef DEFINE_GUID -#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #endif /* DEFINE_GUID */ /* @@ -650,6 +650,17 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) pScreenPriv->pdd = NULL; } + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + /* Kill our window */ if (pScreenPriv->hwndScreen) { diff --git a/programs/Xserver/hw/xwin/winshadgdi.c b/programs/Xserver/hw/xwin/winshadgdi.c index 306b62103..29ce6761b 100644 --- a/programs/Xserver/hw/xwin/winshadgdi.c +++ b/programs/Xserver/hw/xwin/winshadgdi.c @@ -216,7 +216,7 @@ winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam) if (GetClassName (hwnd, strClassName, 100)) { - if(strcmp (WINDOW_CLASS_X, strClassName) == 0) + if (strncmp (WINDOW_CLASS_X, strClassName, strlen (WINDOW_CLASS_X)) == 0) { InvalidateRect (hwnd, NULL, FALSE); UpdateWindow (hwnd); @@ -323,6 +323,17 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) return FALSE; } + /* Look for height weirdness */ + if (dibsection.dsBmih.biHeight < 0) + { + /* FIXME: Figure out why biHeight is sometimes negative */ + ErrorF ("winAllocateFBShadowGDI - WEIRDNESS - biHeight " + "still negative: %d\n" + "winAllocateFBShadowGDI - WEIRDNESS - Flipping biHeight sign\n", + dibsection.dsBmih.biHeight); + dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; + } + /* Set screeninfo stride */ pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage / dibsection.dsBmih.biHeight) @@ -515,6 +526,17 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) /* Free the screen DC */ ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + /* Kill our window */ if (pScreenPriv->hwndScreen) { diff --git a/programs/Xserver/hw/xwin/wintrayicon.c b/programs/Xserver/hw/xwin/wintrayicon.c new file mode 100644 index 000000000..143466050 --- /dev/null +++ b/programs/Xserver/hw/xwin/wintrayicon.c @@ -0,0 +1,207 @@ +/* + *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: Early Ehlinger + * Harold L Hunt II + */ +/* $XFree86: $ */ + +#include "win.h" +#include <shellapi.h> + + +/* + * Initialize the tray icon + */ + +void +winInitNotifyIcon (winPrivScreenPtr pScreenPriv) +{ + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + NOTIFYICONDATA nid = {0}; + + nid.cbSize = sizeof (NOTIFYICONDATA); + nid.hWnd = pScreenPriv->hwndScreen; + nid.uID = pScreenInfo->dwScreen; + nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0); + + /* Save handle to the icon so it can be freed later */ + pScreenPriv->hiconNotifyIcon = nid.hIcon; + + /* Set display and screen-specific tooltip text */ + snprintf (nid.szTip, + sizeof (nid.szTip), + "Cygwin/XFree86 Server - %s:%d", + display, + (int) pScreenInfo->dwScreen); + + /* Add the tray icon */ + if (!Shell_NotifyIcon (NIM_ADD, &nid)) + ErrorF ("winInitNotifyIcon - Shell_NotifyIcon Failed\n"); +} + + +/* + * Delete the tray icon + */ + +void +winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv) +{ + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + NOTIFYICONDATA nid = {0}; + +#if 0 + ErrorF ("winDeleteNotifyIcon\n"); +#endif + + nid.cbSize = sizeof (NOTIFYICONDATA); + nid.hWnd = pScreenPriv->hwndScreen; + nid.uID = pScreenInfo->dwScreen; + + /* Delete the tray icon */ + if (!Shell_NotifyIcon (NIM_DELETE, &nid)) + { + ErrorF ("winDeleteNotifyIcon - Shell_NotifyIcon failed\n"); + return; + } + + /* Free the icon that was loaded */ + if (pScreenPriv->hiconNotifyIcon != NULL + && DestroyIcon (pScreenPriv->hiconNotifyIcon) == 0) + { + ErrorF ("winDeleteNotifyIcon - DestroyIcon failed\n"); + } + pScreenPriv->hiconNotifyIcon = NULL; +} + + +/* + * Process messages intended for the tray icon + */ + +LRESULT +winHandleIconMessage (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam, + winPrivScreenPtr pScreenPriv) +{ + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + switch (lParam) + { + case WM_LBUTTONDBLCLK: + /* Display Exit dialog box */ + winDisplayExitDialog (pScreenPriv); + break; + + case WM_RBUTTONUP: + { + POINT ptCursor; + HMENU hmenuPopup; + HMENU hmenuTray; + + /* Get cursor position */ + GetCursorPos (&ptCursor); + + /* Load tray icon menu resource */ + hmenuPopup = LoadMenu (g_hInstance, + MAKEINTRESOURCE(IDM_TRAYICON_MENU)); + if (!hmenuPopup) + ErrorF ("winHandleIconMessage - LoadMenu failed\n"); + + /* Get actual tray icon menu */ + hmenuTray = GetSubMenu (hmenuPopup, 0); + + /* Check for MultiWindow mode */ + if (pScreenInfo->fMultiWindow) + { + /* Check if root window is shown or hidden */ + if (pScreenPriv->fRootWindowShown) + { + /* Remove Show Root Window button */ + RemoveMenu (hmenuTray, + ID_APP_SHOW_ROOT, + MF_BYCOMMAND); + } + else + { + /* Remove Hide Root Window button */ + RemoveMenu (hmenuTray, + ID_APP_HIDE_ROOT, + MF_BYCOMMAND); + } + } + else + { + /* Remove Show Root Window button */ + RemoveMenu (hmenuTray, + ID_APP_SHOW_ROOT, + MF_BYCOMMAND); + + /* Remove Hide Root Window button */ + RemoveMenu (hmenuTray, + ID_APP_HIDE_ROOT, + MF_BYCOMMAND); + + /* Remove separator */ + RemoveMenu (hmenuTray, + 1, + MF_BYPOSITION); + } + + /* + * NOTE: This three-step procedure is required for + * proper popup menu operation. Without the + * call to SetForegroundWindow the + * popup menu will often not disappear when you click + * outside of it. Without the PostMessage the second + * time you display the popup menu it might immediately + * disappear. + */ + SetForegroundWindow (hwnd); + TrackPopupMenuEx (hmenuTray, + TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, + ptCursor.x, ptCursor.y, + hwnd, + NULL); + PostMessage (hwnd, WM_NULL, 0, 0); + + /* Free menu */ + DestroyMenu (hmenuPopup); + } + break; + } + + return 0; +} diff --git a/programs/Xserver/hw/xwin/winvideo.c b/programs/Xserver/hw/xwin/winvideo.c new file mode 100644 index 000000000..e1ae84987 --- /dev/null +++ b/programs/Xserver/hw/xwin/winvideo.c @@ -0,0 +1,206 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Harold L Hunt II + */ +/* $XFree86$ */ + +#include "win.h" +#include "Xv.h" +#include "Xvproto.h" + + +/* + * 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 "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 = xcalloc (1, sizeof(XF86VideoAdaptorRec)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "Cygwin/XFree86 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 */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); +#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/programs/Xserver/hw/xwin/winwakeup.c b/programs/Xserver/hw/xwin/winwakeup.c index f735c838f..55658ecac 100644 --- a/programs/Xserver/hw/xwin/winwakeup.c +++ b/programs/Xserver/hw/xwin/winwakeup.c @@ -30,7 +30,7 @@ * Peter Busch * Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/winwakeup.c,v 1.5 2001/11/21 08:51:24 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winwakeup.c,v 1.6 2002/10/17 08:18:25 alanh Exp $ */ #include "win.h" @@ -41,17 +41,23 @@ winWakeupHandler (int nScreen, unsigned long ulResult, pointer pReadmask) { +#if 0 winScreenPriv((ScreenPtr)pWakeupData); +#endif MSG msg; /* Process all messages on our queue */ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + if ((g_hDlgDepthChange == 0 + || !IsDialogMessage (g_hDlgDepthChange, &msg)) + && (g_hDlgExit == 0 + || !IsDialogMessage (g_hDlgExit, &msg))) { DispatchMessage (&msg); } } + winReorderWindowsMultiWindow ((ScreenPtr)pWakeupData); } diff --git a/programs/Xserver/hw/xwin/winwindow.c b/programs/Xserver/hw/xwin/winwindow.c index 0393746bd..e1fa96c40 100644 --- a/programs/Xserver/hw/xwin/winwindow.c +++ b/programs/Xserver/hw/xwin/winwindow.c @@ -41,12 +41,12 @@ winAddRgn (WindowPtr pWindow, pointer data); static void -winUpdateRgn (WindowPtr pWindow); +winUpdateRgnPRootless (WindowPtr pWindow); #ifdef SHAPE static void -winReshape (WindowPtr pWin); +winReshapePRootless (WindowPtr pWin); #endif @@ -153,7 +153,6 @@ winCreateWindowPRootless (WindowPtr pWin) fResult = winGetScreenPriv(pWin->drawable.pScreen)->CreateWindow(pWin); pWinPriv->hRgn = NULL; - /*winUpdateRgn (pWin);*/ return fResult; } @@ -180,7 +179,7 @@ winDestroyWindowPRootless (WindowPtr pWin) pWinPriv->hRgn = NULL; } - winUpdateRgn (pWin); + winUpdateRgnPRootless (pWin); return fResult; } @@ -200,7 +199,7 @@ winPositionWindowPRootless (WindowPtr pWin, int x, int y) fResult = winGetScreenPriv(pWin->drawable.pScreen)->PositionWindow(pWin, x, y); - winUpdateRgn (pWin); + winUpdateRgnPRootless (pWin); return fResult; } @@ -220,7 +219,7 @@ winChangeWindowAttributesPRootless (WindowPtr pWin, unsigned long mask) fResult = winGetScreenPriv(pWin->drawable.pScreen)->ChangeWindowAttributes(pWin, mask); - winUpdateRgn (pWin); + winUpdateRgnPRootless (pWin); return fResult; } @@ -248,7 +247,7 @@ winUnmapWindowPRootless (WindowPtr pWin) pWinPriv->hRgn = NULL; } - winUpdateRgn (pWin); + winUpdateRgnPRootless (pWin); return fResult; } @@ -269,9 +268,9 @@ winMapWindowPRootless (WindowPtr pWin) fResult = winGetScreenPriv(pWin->drawable.pScreen)->RealizeWindow(pWin); - winReshape (pWin); + winReshapePRootless (pWin); - winUpdateRgn (pWin); + winUpdateRgnPRootless (pWin); return fResult; } @@ -287,8 +286,8 @@ winSetShapePRootless (WindowPtr pWin) winGetScreenPriv(pWin->drawable.pScreen)->SetShape(pWin); - winReshape (pWin); - winUpdateRgn (pWin); + winReshapePRootless (pWin); + winUpdateRgnPRootless (pWin); return; } @@ -366,7 +365,7 @@ winAddRgn (WindowPtr pWin, pointer data) static void -winUpdateRgn (WindowPtr pWin) +winUpdateRgnPRootless (WindowPtr pWin) { HRGN hRgn = CreateRectRgn (0, 0, 0, 0); @@ -378,7 +377,7 @@ winUpdateRgn (WindowPtr pWin) } else { - ErrorF ("winUpdateRgn - CreateRectRgn failed.\n"); + ErrorF ("winUpdateRgnPRootless - CreateRectRgn failed.\n"); } } @@ -386,17 +385,19 @@ winUpdateRgn (WindowPtr pWin) #ifdef SHAPE static void -winReshape (WindowPtr pWin) +winReshapePRootless (WindowPtr pWin) { int nRects; +#if 0 ScreenPtr pScreen = pWin->drawable.pScreen; +#endif RegionRec rrNewShape; BoxPtr pShape, pRects, pEnd; HRGN hRgn, hRgnRect; winWindowPriv(pWin); #if CYGDEBUG - ErrorF ("winReshape ()\n"); + ErrorF ("winReshapePRootless ()\n"); #endif /* Bail if the window is the root window */ @@ -439,13 +440,13 @@ winReshape (WindowPtr pWin) pRects->x2, pRects->y2); if (hRgnRect == NULL) { - ErrorF("winReshape - CreateRectRgn() failed\n"); + ErrorF("winReshapePRootless - CreateRectRgn() failed\n"); } /* Merge the Windows region with the accumulated region */ if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) { - ErrorF("winReshape - CombineRgn() failed\n"); + ErrorF("winReshapePRootless - CombineRgn() failed\n"); } /* Delete the temporary Windows region */ diff --git a/programs/Xserver/hw/xwin/winwindow.h b/programs/Xserver/hw/xwin/winwindow.h index ea724ecb1..7551a76e5 100644 --- a/programs/Xserver/hw/xwin/winwindow.h +++ b/programs/Xserver/hw/xwin/winwindow.h @@ -41,20 +41,22 @@ #endif /* Constant strings */ -#define WINDOW_CLASS "cygwin/xfree86 rl" -#define WINDOW_TITLE "Cygwin/XFree86 rl" -#define WIN_SCR_PROP "cyg_screen_prop_rl" +#define WINDOW_CLASS "cygwin/xfree86" +#define WINDOW_TITLE "Cygwin/XFree86 - %s:%d" +#define WIN_SCR_PROP "cyg_screen_prop rl" #define WINDOW_CLASS_X "cygwin/xfree86 X rl" -#define WINDOW_TITLE_X "Cygwin/XFree86 X rl" +#define WINDOW_TITLE_X "Cygwin/XFree86 X" #define WIN_WINDOW_PROP "cyg_window_prop_rl" #define WIN_MSG_QUEUE_FNAME "/dev/windows" -#define WIN_LOG_FNAME "/tmp/XWinrl.log" +#define WIN_LOG_FNAME "/tmp/XWin.log" #define WIN_WID_PROP "cyg_wid_prop_rl" #define WIN_NEEDMANAGE_PROP "cyg_override_redirect_prop_rl" +#define WIN_HWND_CACHE "cyg_privmap_rl" #define CYGMULTIWINDOW_DEBUG NO typedef struct _winPrivScreenRec *winPrivScreenPtr; + /* * Window privates */ @@ -70,6 +72,8 @@ typedef struct int iWidth; int iHeight; Bool fXKilled; + Bool fNeedRestore; + POINT ptRestore; } winPrivWinRec, *winPrivWinPtr; typedef struct _winWMMessageRec{ @@ -81,19 +85,21 @@ typedef struct _winWMMessageRec{ int iWidth, iHeight; } winWMMessageRec, *winWMMessagePtr; + /* * winrootlesswm.c */ -#define WM_WM_MOVE (WM_USER + 1) -#define WM_WM_SIZE (WM_USER + 2) -#define WM_WM_RAISE (WM_USER + 3) -#define WM_WM_LOWER (WM_USER + 4) -#define WM_WM_MAP (WM_USER + 5) -#define WM_WM_UNMAP (WM_USER + 6) -#define WM_WM_KILL (WM_USER + 7) -#define WM_WM_ACTIVATE (WM_USER + 8) -#define WMMSG_MSG 10 +#define WM_WM_MOVE (WM_USER + 1) +#define WM_WM_SIZE (WM_USER + 2) +#define WM_WM_RAISE (WM_USER + 3) +#define WM_WM_LOWER (WM_USER + 4) +#define WM_WM_MAP (WM_USER + 5) +#define WM_WM_UNMAP (WM_USER + 6) +#define WM_WM_KILL (WM_USER + 7) +#define WM_WM_ACTIVATE (WM_USER + 8) +#define WM_WM_NAME_EVENT (WM_USER + 9) +#define WM_WM_HINTS_EVENT (WM_USER + 10) /* @@ -106,13 +112,15 @@ winSendMessageToWM (void *pWMInfo, winWMMessagePtr msg); Bool winInitWM (void **ppWMInfo, pthread_t *ptWMProc, -#if 0 - pthread_cond_t *ppcServerStarted, -#endif + pthread_t *ptXMsgProc, pthread_mutex_t *ppmServerStarted, -#if 0 - Bool *pfServerStarted, -#endif int dwScreen); +/* + * winmultiwindowicons.c + */ + +void +winUpdateIcon (Window id); + #endif diff --git a/programs/Xserver/hw/xwin/winwndproc.c b/programs/Xserver/hw/xwin/winwndproc.c index 8284ccdbc..6ff1c4429 100644 --- a/programs/Xserver/hw/xwin/winwndproc.c +++ b/programs/Xserver/hw/xwin/winwndproc.c @@ -36,9 +36,12 @@ #include "win.h" #include <commctrl.h> -BOOL CALLBACK -winChangeDepthDlgProc (HWND hDialog, UINT message, - WPARAM wParam, LPARAM lParam); +/* + * Global variables + */ + +Bool g_fCursor = TRUE; + /* @@ -55,7 +58,6 @@ winWindowProc (HWND hwnd, UINT message, static ScreenPtr s_pScreen = NULL; static HWND s_hwndLastPrivates = NULL; static HINSTANCE s_hInstance; - static Bool s_fCursor = TRUE; static Bool s_fTracking = FALSE; static unsigned long s_ulServerGeneration = 0; int iScanCode; @@ -90,6 +92,10 @@ winWindowProc (HWND hwnd, UINT message, /* Branch on message type */ switch (message) { + case WM_TRAYICON: + return winHandleIconMessage (hwnd, message, wParam, lParam, + s_pScreenPriv); + case WM_CREATE: #if CYGDEBUG ErrorF ("winWindowProc - WM_CREATE\n"); @@ -113,6 +119,23 @@ winWindowProc (HWND hwnd, UINT message, /* Store the mode key states so restore doesn't try to restore them */ winStoreModeKeyStates (s_pScreen); + + /* Setup tray icon */ + if (!s_pScreenInfo->fNoTrayIcon) + { + /* + * NOTE: The WM_CREATE message is processed before CreateWindowEx + * returns, so s_pScreenPriv->hwndScreen is invalid at this point. + * We go ahead and copy our hwnd parameter over top of the screen + * privates hwndScreen so that we have a valid value for + * that member. Otherwise, the tray icon will disappear + * the first time you move the mouse over top of it. + */ + + s_pScreenPriv->hwndScreen = hwnd; + + winInitNotifyIcon (s_pScreenPriv); + } return 0; case WM_DISPLAYCHANGE: @@ -161,7 +184,7 @@ winWindowProc (HWND hwnd, UINT message, * Shadow DirectDraw Non-Locking * Primary DirectDraw * - * TrueColor --> TrueColor depth changs are non-optimal for: + * TrueColor --> TrueColor depth changes are non-optimal for: * Windowed: * Shadow GDI * @@ -189,45 +212,14 @@ winWindowProc (HWND hwnd, UINT message, /* Cannot display the visual until the depth is restored */ ErrorF ("winWindowProc - Disruptive change in depth\n"); - /* Check if the dialog box already exists */ - if (g_hDlgDepthChange != NULL) - { - ErrorF ("winWindowProc - Dialog box already exists\n"); + /* Display Exit dialog */ + winDisplayDepthChangeDialog (s_pScreenPriv); - /* Dialog box already exists, just display it */ - ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); - } - else - { - /* - * Display a notification to the user that the visual - * will not be displayed until the Windows display depth - * is restored to the original value. - */ - g_hDlgDepthChange = CreateDialogParam (s_hInstance, - "DEPTH_CHANGE_BOX", - hwnd, - winChangeDepthDlgProc, - (int) s_pScreenPriv); - - /* Show the dialog box */ - ShowWindow (g_hDlgDepthChange, SW_SHOW); - - ErrorF ("winWindowProc - DialogBox returned: %d\n", - g_hDlgDepthChange); - ErrorF ("winWindowProc - GetLastError: %d\n", GetLastError ()); - - /* Minimize the display window */ - ShowWindow (hwnd, SW_MINIMIZE); - - /* Flag that we have an invalid screen depth */ - s_pScreenPriv->fBadDepth = TRUE; - - /* - * TODO: Redisplay the dialog box if it is not - * currently displayed. - */ - } + /* Flag that we have an invalid screen depth */ + s_pScreenPriv->fBadDepth = TRUE; + + /* Minimize the display window */ + ShowWindow (hwnd, SW_MINIMIZE); } else { @@ -693,17 +685,17 @@ winWindowProc (HWND hwnd, UINT message, } /* Hide or show the Windows mouse cursor */ - if (s_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) + if (g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) { /* Hide Windows cursor */ - s_fCursor = FALSE; + g_fCursor = FALSE; ShowCursor (FALSE); } - else if (!s_fCursor && !s_pScreenPriv->fActive + else if (!g_fCursor && !s_pScreenPriv->fActive && !s_pScreenInfo->fLessPointer) { /* Show Windows cursor */ - s_fCursor = TRUE; + g_fCursor = TRUE; ShowCursor (TRUE); } @@ -728,9 +720,9 @@ winWindowProc (HWND hwnd, UINT message, break; /* Non-client mouse movement, show Windows cursor */ - if (!s_fCursor) + if (!g_fCursor) { - s_fCursor = TRUE; + g_fCursor = TRUE; ShowCursor (TRUE); } break; @@ -742,9 +734,9 @@ winWindowProc (HWND hwnd, UINT message, s_fTracking = FALSE; /* Show the mouse cursor, if necessary */ - if (!s_fCursor) + if (!g_fCursor) { - s_fCursor = TRUE; + g_fCursor = TRUE; ShowCursor (TRUE); } return 0; @@ -806,6 +798,22 @@ winWindowProc (HWND hwnd, UINT message, /* Clear screen privates flags */ s_pScreenPriv->iE3BCachedPress = 0; break; + + case WIN_POLLING_MOUSE_TIMER_ID: + { + POINT point; + + /* Get the current position of the mouse cursor */ + GetCursorPos (&point); + + /* Map from screen (-X, -Y) to root (0, 0) */ + point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); + point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Deliver absolute cursor position to X Server */ + miPointerAbsoluteCursor (point.x, point.y, + g_c32LastInputEventTime = GetTickCount()); + } } return 0; @@ -880,7 +888,7 @@ winWindowProc (HWND hwnd, UINT message, && (GetKeyState (VK_MENU) & 0x8000)) || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK && (GetKeyState (VK_MENU) & 0x8000) - && (GetKeyState (VK_CONTROL) & 0x8000))) + && (GetKeyState (VK_CONTROL) & 0x8000))) { /* * Better leave this message here, just in case some unsuspecting @@ -889,8 +897,8 @@ winWindowProc (HWND hwnd, UINT message, */ ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); - /* Tell our message queue to give up */ - PostMessage (hwnd, WM_CLOSE, 0, 0); + /* Display Exit dialog */ + winDisplayExitDialog (s_pScreenPriv); return 0; } @@ -973,8 +981,6 @@ winWindowProc (HWND hwnd, UINT message, return 0; } - - #if CYGDEBUG ErrorF ("winWindowProc - WM_ACTIVATE\n"); #endif @@ -990,10 +996,10 @@ winWindowProc (HWND hwnd, UINT message, /* Reshow the Windows mouse cursor if we are being deactivated */ if (LOWORD(wParam) == WA_INACTIVE - && !s_fCursor) + && !g_fCursor) { /* Show Windows cursor */ - s_fCursor = TRUE; + g_fCursor = TRUE; ShowCursor (TRUE); } return 0; @@ -1012,10 +1018,10 @@ winWindowProc (HWND hwnd, UINT message, /* Reshow the Windows mouse cursor if we are being deactivated */ if (!s_pScreenPriv->fActive - && !s_fCursor) + && !g_fCursor) { /* Show Windows cursor */ - s_fCursor = TRUE; + g_fCursor = TRUE; ShowCursor (TRUE); } @@ -1023,109 +1029,36 @@ winWindowProc (HWND hwnd, UINT message, (*s_pScreenPriv->pwinActivateApp) (s_pScreen); return 0; - case WM_CLOSE: - /* Tell X that we are giving up */ - GiveUp (0); - return 0; - } - - return DefWindowProc (hwnd, message, wParam, lParam); -} - - -/* - * Process messages for the dialog that is displayed for - * disruptive screen depth changes. - */ - -BOOL CALLBACK -winChangeDepthDlgProc (HWND hwndDialog, UINT message, - WPARAM wParam, LPARAM lParam) -{ - static winPrivScreenPtr s_pScreenPriv = NULL; - static winScreenInfo *s_pScreenInfo = NULL; - static ScreenPtr s_pScreen = NULL; - -#if CYGDEBUG - ErrorF ("winChangeDepthDlgProc\n"); -#endif - - /* Branch on message type */ - switch (message) - { - case WM_INITDIALOG: -#if CYGDEBUG - ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG\n"); -#endif - - /* Store pointers to private structures for future use */ - s_pScreenPriv = (winPrivScreenPtr) lParam; - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - s_pScreen = s_pScreenInfo->pScreen; - -#if CYGDEBUG - ErrorF ("winChangeDepthDlgProc - WM_INITDIALG - s_pScreenPriv: %08x, " - "s_pScreenInfo: %08x, s_pScreen: %08x\n", - s_pScreenPriv, s_pScreenInfo, s_pScreen); -#endif - -#if CYGDEBUG - ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, " - "last bpp: %d\n", - s_pScreenInfo->dwBPP, - s_pScreenPriv->dwLastWindowsBitsPixel); -#endif - return TRUE; - - case WM_DISPLAYCHANGE: -#if CYGDEBUG - ErrorF ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, " - "last bpp: %d, new bpp: %d\n", - s_pScreenInfo->dwBPP, - s_pScreenPriv->dwLastWindowsBitsPixel, - wParam); -#endif - - /* Dismiss the dialog if the display returns to the original depth */ - if (wParam == s_pScreenInfo->dwBPP) - { - ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n"); - - /* Depth has been restored, dismiss dialog */ - DestroyWindow (g_hDlgDepthChange); - g_hDlgDepthChange = NULL; - - /* Flag that we have a valid screen depth */ - s_pScreenPriv->fBadDepth = FALSE; - } - return TRUE; - case WM_COMMAND: switch (LOWORD (wParam)) { - case IDOK: - case IDCANCEL: - ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); + case ID_APP_EXIT: + /* Display Exit dialog */ + winDisplayExitDialog (s_pScreenPriv); + return 0; - /* - * User dismissed the dialog, hide it until the - * display mode is restored. - */ - ShowWindow (g_hDlgDepthChange, SW_HIDE); - return TRUE; + case ID_APP_HIDE_ROOT: + ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE); + s_pScreenPriv->fRootWindowShown = FALSE; + return 0; + + case ID_APP_SHOW_ROOT: + ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW); + s_pScreenPriv->fRootWindowShown = TRUE; + return 0; } break; - case WM_CLOSE: - ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n"); + case WM_GIVEUP: + /* Tell X that we are giving up */ + GiveUp (0); + return 0; - /* - * User dismissed the dialog, hide it until the - * display mode is restored. - */ - ShowWindow (g_hDlgDepthChange, SW_HIDE); - return TRUE; + case WM_CLOSE: + /* Display Exit dialog */ + winDisplayExitDialog (s_pScreenPriv); + return 0; } - return FALSE; + return DefWindowProc (hwnd, message, wParam, lParam); } |