diff options
Diffstat (limited to 'hw/xwin')
-rw-r--r-- | hw/xwin/_usr_X11R6_lib_X11_system.XWinrc | 105 | ||||
-rwxr-xr-x | hw/xwin/windialogs.c | 320 | ||||
-rwxr-xr-x | hw/xwin/winmultiwindowclass.c | 284 | ||||
-rwxr-xr-x | hw/xwin/winmultiwindowclass.h | 110 | ||||
-rwxr-xr-x | hw/xwin/winmultiwindowicons.c | 378 | ||||
-rwxr-xr-x | hw/xwin/winmultiwindowshape.c | 212 | ||||
-rwxr-xr-x | hw/xwin/winmultiwindowwndproc.c | 1005 | ||||
-rw-r--r-- | hw/xwin/winprefs.c | 661 | ||||
-rw-r--r-- | hw/xwin/winprefs.h | 147 | ||||
-rw-r--r-- | hw/xwin/winprefslex.l | 113 | ||||
-rw-r--r-- | hw/xwin/winprefsyacc.y | 334 | ||||
-rw-r--r-- | hw/xwin/winpushpxl.c | 226 | ||||
-rw-r--r-- | hw/xwin/winrop.c | 139 | ||||
-rwxr-xr-x | hw/xwin/wintrayicon.c | 209 | ||||
-rwxr-xr-x | hw/xwin/winvideo.c | 206 |
15 files changed, 4449 insertions, 0 deletions
diff --git a/hw/xwin/_usr_X11R6_lib_X11_system.XWinrc b/hw/xwin/_usr_X11R6_lib_X11_system.XWinrc new file mode 100644 index 000000000..dbd79f2bf --- /dev/null +++ b/hw/xwin/_usr_X11R6_lib_X11_system.XWinrc @@ -0,0 +1,105 @@ +# XWin Server Resource File - EXAMPLE +# Earle F. Philhower, III + +# Place in ~/.XWinrc or in /usr/X11R6/lib/X11/system.XWinrc + +# Keywords are case insensitive, comments legal pretty much anywhere +# you can have an end-of-line + +# Comments begin with "#" or "//" and go to the end-of-line + +# Paths to commands are **cygwin** based (i.e. /usr/local/bin/xcalc) + +# Paths to icons are **WINDOWS** based (i.e. c:\windows\icons) + +# Menus are defined as... +# MENU <name> { +# <Menu Text> EXEC <command> +# ^^ This command will have any "%display%" +# string replaced with the proper display +# variable (i.e. 127.0.0.1:<display>.0) +# or <Menu Text> MENU <name-of-some-prior-defined-menu> +# or <Menu Text> ALWAYSONTOP +# ^^ Sets the window to display above all others +# or <Menu Text> RELOAD +# ^^ Causes ~/.XWinrc or the system.XWinrc file +# to be reloaded and icons and menus regenerated +# or SEPARATOR +# ... +# } + +# Set the taskmar menu with +# ROOTMENU <name-of-some-prior-defined-menu> + +# If you want a menu to be applied to all popup window's system menu +# DEFAULTSYSMENU <name-of-some-prior-defined-menu> <atstart|atend> + +# To choose a specific menu for a specific WM_CLASS or WM_NAME use ... +# SYSMENU { +# <class-or-name-of-window> <name-of-prior-defined-menu> <atstart|atend> +# ... +# } + +# To define where ICO files live (** Windows path**) +# ICONDIRECTORY <windows-path i.e. c:\cygwin\usr\icons> + +# To define a replacement for the standard X icon for apps w/o specified icons +# DEFAULTICON <name-of-windows-ico-file-in-icondirectory> + +# To define substitute icons on a per-window basis use... +# ICONS { +# <class-or-name-of-window> <icon-file-name.ico> +# ... +# } +# In the case where multiple matches occur, the first listed in the ICONS +# section will be chosen. + +# DEBUG <string> prints out the string to the XWin.log file + +// Below are just some silly menus to demonstrate writing your +// own configuration file. + +// Make some menus... +menu apps { + xterm exec "xterm" + "Emacs" exec "emacs" + notepad exec notepad + xload exec "xload -display %display%" # Comment +} + +menu root { +// Comments fit here, too... + "Reload .XWinrc" RELOAD + "Applications" menu apps + SEParATOR +} + +menu aot { + Separator + "Always on Top" alwaysontop +} + +menu xtermspecial { + "Emacs" exec "emacs" + "Always on Top" alwaysontop + SepArAtor +} + +RootMenu root + +DefaultSysMenu aot atend + +SysMenu { + "xterm" xtermspecial atstart +} + +# IconDirectory "c:\winnt\" + +# DefaultIcon "reinstall.ico" + +# Icons { +# "xterm" "uninstall.ico" +# } + +DEBUG "Done parsing the configuration file..." + diff --git a/hw/xwin/windialogs.c b/hw/xwin/windialogs.c new file mode 100755 index 000000000..d905ad81c --- /dev/null +++ b/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: xc/programs/Xserver/hw/xwin/windialogs.c,v 1.1 2003/07/29 21:25:17 dawes Exp $ */ + +#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/hw/xwin/winmultiwindowclass.c b/hw/xwin/winmultiwindowclass.c new file mode 100755 index 000000000..21be64977 --- /dev/null +++ b/hw/xwin/winmultiwindowclass.c @@ -0,0 +1,284 @@ +/* + *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/winmultiwindowclass.c,v 1.2 2003/10/02 13:30:10 eich Exp $ */ + +#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; + } + + /* Add one to len_name to allow copying of trailing 0 */ + strncpy ((*res_name), prop->data, len_name + 1); + + 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; +} + + +int +winMultiWindowGetWMNormalHints (WindowPtr pWin, WinXSizeHints *hints) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !hints) + { + ErrorF ("winMultiWindowGetWMNormalHints - 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 (WinXSizeHints)); + + while (prop) + { + if (prop->propertyName == XA_WM_NORMAL_HINTS + && prop->data) + { + memcpy (hints, prop->data, sizeof (WinXSizeHints)); + return 1; + } + else + prop = prop->next; + } + + return 0; +} + + +int +winMultiWindowGetWMName (WindowPtr pWin, char **wmName) +{ + struct _Window *pwin; + struct _Property *prop; + int len_name; + + if (!pWin || !wmName) + { + 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; + + *wmName = NULL; + + while (prop) + { + if (prop->propertyName == XA_WM_NAME + && prop->type == XA_STRING + && prop->data) + { + len_name = strlen ((char *) prop->data); + + (*wmName) = malloc (len_name + 1); + + if (!*wmName) + { + ErrorF ("winMultiWindowGetWMName - *wmName was NULL\n"); + return 0; + } + + /* Add one to len_name to allow copying of trailing 0 */ + strncpy ((*wmName), prop->data, len_name+1); + + return 1; + } + else + prop = prop->next; + } + + return 0; +} + diff --git a/hw/xwin/winmultiwindowclass.h b/hw/xwin/winmultiwindowclass.h new file mode 100755 index 000000000..b6ad55d8b --- /dev/null +++ b/hw/xwin/winmultiwindowclass.h @@ -0,0 +1,110 @@ +/* + *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/winmultiwindowclass.h,v 1.2 2003/10/02 13:30:10 eich Exp $ */ + + +/* + * 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; + + +/* + * new version containing base_width, base_height, and win_gravity fields; + * used with WM_NORMAL_HINTS. + */ +typedef struct { + long flags; /* marks which fields in this structure are defined */ + int x, y; /* obsolete for new window mgrs, but clients */ + int width, height; /* should set so old wm's don't mess up */ + int min_width, min_height; + int max_width, max_height; + int width_inc, height_inc; + struct { + int x; /* numerator */ + int y; /* denominator */ + } min_aspect, max_aspect; + int base_width, base_height; /* added by ICCCM version 1 */ + int win_gravity; /* added by ICCCM version 1 */ +} WinXSizeHints; + +/* + * The next block of definitions are for window manager properties that + * clients and applications use for communication. + */ + +/* flags argument in size hints */ +#define USPosition (1L << 0) /* user specified x, y */ +#define USSize (1L << 1) /* user specified width, height */ + +#define PPosition (1L << 2) /* program specified position */ +#define PSize (1L << 3) /* program specified size */ +#define PMinSize (1L << 4) /* program specified minimum size */ +#define PMaxSize (1L << 5) /* program specified maximum size */ +#define PResizeInc (1L << 6) /* program specified resize increments */ +#define PAspect (1L << 7) /* program specified min and max aspect ratios */ +#define PBaseSize (1L << 8) /* program specified base for incrementing */ +#define PWinGravity (1L << 9) /* program specified window gravity */ + +/* obsolete */ +#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect) + + +/* + * 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); + +int +winMultiWindowGetWMNormalHints (WindowPtr pWin, WinXSizeHints *hints); + +int +winMultiWindowGetWMName (WindowPtr pWin, char **wmName); + diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c new file mode 100755 index 000000000..dd56db6d6 --- /dev/null +++ b/hw/xwin/winmultiwindowicons.c @@ -0,0 +1,378 @@ +/* + *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/winmultiwindowicons.c,v 1.2 2003/10/02 13:30:10 eich Exp $ */ + +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.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 = (HICON)winOverrideIcon ((unsigned long)pWin); + + if (!hIcon) + 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 && + !winIconIsOverride((unsigned long)hiconOld)) + DeleteObject (hiconOld); + } + } +} diff --git a/hw/xwin/winmultiwindowshape.c b/hw/xwin/winmultiwindowshape.c new file mode 100755 index 000000000..5c623d14e --- /dev/null +++ b/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/winmultiwindowshape.c,v 1.2 2003/11/10 18:22:44 tsi 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_NULL(pScreen, &rrNewShape); + 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/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c new file mode 100755 index 000000000..d90abb61f --- /dev/null +++ b/hw/xwin/winmultiwindowwndproc.c @@ -0,0 +1,1005 @@ +/* + *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/winmultiwindowwndproc.c,v 1.3 2003/10/08 11:13:03 eich Exp $ */ + +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.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 + + + +/* + * ConstrainSize - Taken from TWM sources - Respects hints for sizing + */ +#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) +static void +ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp) +{ + int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; + int baseWidth, baseHeight; + int dwidth = *widthp, dheight = *heightp; + + if (hints.flags & PMinSize) + { + minWidth = hints.min_width; + minHeight = hints.min_height; + } + else if (hints.flags & PBaseSize) + { + minWidth = hints.base_width; + minHeight = hints.base_height; + } + else + minWidth = minHeight = 1; + + if (hints.flags & PBaseSize) + { + baseWidth = hints.base_width; + baseHeight = hints.base_height; + } + else if (hints.flags & PMinSize) + { + baseWidth = hints.min_width; + baseHeight = hints.min_height; + } + else + baseWidth = baseHeight = 0; + + if (hints.flags & PMaxSize) + { + maxWidth = hints.max_width; + maxHeight = hints.max_height; + } + else + { + maxWidth = MAXINT; + maxHeight = MAXINT; + } + + if (hints.flags & PResizeInc) + { + xinc = hints.width_inc; + yinc = hints.height_inc; + } + else + xinc = yinc = 1; + + /* + * First, clamp to min and max values + */ + if (dwidth < minWidth) + dwidth = minWidth; + if (dheight < minHeight) + dheight = minHeight; + + if (dwidth > maxWidth) + dwidth = maxWidth; + if (dheight > maxHeight) + dheight = maxHeight; + + /* + * Second, fit to base + N * inc + */ + dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; + dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; + + /* + * Third, adjust for aspect ratio + */ + + /* + * The math looks like this: + * + * minAspectX dwidth maxAspectX + * ---------- <= ------- <= ---------- + * minAspectY dheight maxAspectY + * + * If that is multiplied out, then the width and height are + * invalid in the following situations: + * + * minAspectX * dheight > minAspectY * dwidth + * maxAspectX * dheight < maxAspectY * dwidth + * + */ + + if (hints.flags & PAspect) + { + if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) + { + delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc); + if (dwidth + delta <= maxWidth) + dwidth += delta; + else + { + delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc); + if (dheight - delta >= minHeight) + dheight -= delta; + } + } + + if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) + { + delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc); + if (dheight + delta <= maxHeight) + dheight += delta; + else + { + delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc); + if (dwidth - delta >= minWidth) + dwidth -= delta; + } + } + } + + /* Return computed values */ + *widthp = dwidth; + *heightp = dheight; +} +#undef makemult + + + +/* + * ValidateSizing - Ensures size request respects hints + */ +static int +ValidateSizing (HWND hwnd, WindowPtr pWin, + WPARAM wParam, LPARAM lParam) +{ + WinXSizeHints sizeHints; + RECT *rect; + int iWidth, iHeight, iTopBorder; + POINT pt; + + /* Invalid input checking */ + if (pWin==NULL || lParam==0) + return FALSE; + + /* No size hints, no checking */ + if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) + return FALSE; + + /* Avoid divide-by-zero */ + if (sizeHints.flags & PResizeInc) + { + if (sizeHints.width_inc == 0) sizeHints.width_inc = 1; + if (sizeHints.height_inc == 0) sizeHints.height_inc = 1; + } + + rect = (RECT*)lParam; + + iWidth = rect->right - rect->left; + iHeight = rect->bottom - rect->top; + + /* Get title bar height, there must be an easier way?! */ + pt.x = pt.y = 0; + ClientToScreen(hwnd, &pt); + iTopBorder = pt.y - rect->top; + + /* Now remove size of any borders */ + iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME); + iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder; + + /* Constrain the size to legal values */ + ConstrainSize (sizeHints, &iWidth, &iHeight); + + /* Add back the borders */ + iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME); + iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder; + + /* Adjust size according to where we're dragging from */ + switch(wParam) { + case WMSZ_TOP: + case WMSZ_TOPRIGHT: + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_RIGHT: + rect->right = rect->left + iWidth; + break; + default: + rect->left = rect->right - iWidth; + break; + } + switch(wParam) { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_BOTTOMLEFT: + case WMSZ_RIGHT: + case WMSZ_LEFT: + rect->bottom = rect->top + iHeight; + break; + default: + rect->top = rect->bottom - iHeight; + break; + } + return TRUE; +} + + +/* + * 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 whatever the setup file wants to for this window + */ + SetupSysMenu ((unsigned long)hwnd); + return 0; + + case WM_SYSCOMMAND: + /* + * Any window menu items go through here + */ + HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam)); + break; + + case WM_INITMENU: + /* Checks/Unchecks any menu items before they are displayed */ + HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam); + break; + + 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); + + /* Position 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_SIZING: + /* Need to legalize the size according to WM_NORMAL_HINTS */ + /* for applications like xterm */ + return ValidateSizing (hwnd, pWin, wParam, lParam); + + case WM_WINDOWPOSCHANGED: + { + LPWINDOWPOS pwindPos = (LPWINDOWPOS) lParam; + + /* Bail if window z order was not changed */ + if (pwindPos->flags & SWP_NOZORDER) + break; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - hwndInsertAfter: %p\n", + pwindPos->hwndInsertAfter); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + + 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/hw/xwin/winprefs.c b/hw/xwin/winprefs.c new file mode 100644 index 000000000..3bea60d3d --- /dev/null +++ b/hw/xwin/winprefs.c @@ -0,0 +1,661 @@ +/* + * 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/winprefs.c,v 1.1 2003/10/02 13:30:11 eich Exp $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/resource.h> +#include "win.h" + +/* Fixups to prevent collisions between Windows and X headers */ +#define ATOM DWORD +#include <windows.h> + +#include "winprefs.h" +#include "winmultiwindowclass.h" + +/* Where will the custom menu commands start counting from? */ +#define STARTMENUID WM_USER + +/* From winmultiwindowflex.l, the real parser */ +extern void parse_file (FILE *fp); + +/* From winmultiwindowyacc.y, the pref structure loaded by the parser */ +extern WINMULTIWINDOWPREFS pref; + +/* The global X default icon */ +extern HICON g_hiconX; + +/* Currently in use command ID, incremented each new menu item created */ +static int g_cmdid = STARTMENUID; + + +/* Defined in DIX */ +extern char *display; + +/* + * Creates or appends a menu from a MENUPARSED structure + */ +static HMENU +MakeMenu (char *name, + HMENU editMenu, + int editItem) +{ + int i; + int item; + MENUPARSED *m; + HMENU hmenu; + + for (i=0; i<pref.menuItems; i++) + { + if (!strcmp(name, pref.menu[i].menuName)) + break; + } + + /* Didn't find a match, bummer */ + if (i==pref.menuItems) + { + ErrorF("MakeMenu: Can't find menu %s\n", name); + return NULL; + } + + m = &(pref.menu[i]); + + if (editMenu) + { + hmenu = editMenu; + item = editItem; + } + else + { + hmenu = CreatePopupMenu(); + item = 0; + } + + /* Add the menu items */ + for (i=0; i<m->menuItems; i++) + { + /* Only assign IDs one time... */ + if ( m->menuItem[i].commandID == 0 ) + m->menuItem[i].commandID = g_cmdid++; + + switch (m->menuItem[i].cmd) + { + case CMD_EXEC: + case CMD_ALWAYSONTOP: + case CMD_RELOAD: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_ENABLED|MF_STRING, + m->menuItem[i].commandID, + m->menuItem[i].text); + break; + + case CMD_SEPARATOR: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_SEPARATOR, + 0, + NULL); + break; + + case CMD_MENU: + /* Recursive! */ + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING, + (UINT_PTR)MakeMenu (m->menuItem[i].param, 0, 0), + m->menuItem[i].text); + break; + } + + /* If item==-1 (means to add at end of menu) don't increment) */ + if (item>=0) + item++; + } + + return hmenu; +} + + +/* + * Callback routine that is executed once per window class. + * Removes or creates custom window settings depending on LPARAM + */ +static BOOL CALLBACK +ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam) +{ + char szClassName[1024]; + HICON hicon; + + if (!GetClassName (hwnd, szClassName, 1024)) + return TRUE; + + if (strncmp (szClassName, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X))) + /* Not one of our windows... */ + return TRUE; + + /* It's our baby, either clean or dirty it */ + if (lParam==FALSE) + { + hicon = (HICON)GetClassLong(hwnd, GCL_HICON); + + /* Unselect any icon in the class structure */ + SetClassLong (hwnd, GCL_HICON, (LONG)LoadIcon (NULL, IDI_APPLICATION)); + + /* If it's generated on-the-fly, get rid of it, will regen */ + if (!winIconIsOverride((unsigned long)hicon) && hicon!=g_hiconX) + DestroyIcon (hicon); + + /* Remove any menu additions, use bRevert flag */ + GetSystemMenu (hwnd, TRUE); + + /* This window is now clean of our taint */ + } + else + { + /* Make the icon default, dynamic, of from xwinrc */ + SetClassLong (hwnd, GCL_HICON, (LONG)g_hiconX); + winUpdateIcon ((Window)GetProp (hwnd, WIN_WID_PROP)); + /* Update the system menu for this window */ + SetupSysMenu ((unsigned long)hwnd); + + /* That was easy... */ + } + + return TRUE; +} + + +/* + * Removes any custom icons in classes, custom menus, etc. + * Frees all members in pref structure. + * Reloads the preferences file. + * Set custom icons and menus again. + */ +static void +ReloadPrefs () +{ + int i; + + /* First, iterate over all windows replacing their icon with system */ + /* default one and deleting any custom system menus */ + EnumWindows (ReloadEnumWindowsProc, FALSE); + + /* Now, free/clear all info from our prefs structure */ + for (i=0; i<pref.menuItems; i++) + free (pref.menu[i].menuItem); + free (pref.menu); + pref.menu = NULL; + pref.menuItems = 0; + + pref.rootMenuName[0] = 0; + + free (pref.sysMenu); + pref.sysMenuItems = 0; + + pref.defaultSysMenuName[0] = 0; + pref.defaultSysMenuPos = 0; + + pref.iconDirectory[0] = 0; + pref.defaultIconName[0] = 0; + + for (i=0; i<pref.iconItems; i++) + if (pref.icon[i].hicon) + DestroyIcon ((HICON)pref.icon[i].hicon); + free (pref.icon); + pref.icon = NULL; + pref.iconItems = 0; + + /* Free global default X icon */ + DestroyIcon (g_hiconX); + + /* Reset the custom command IDs */ + g_cmdid = STARTMENUID; + + /* Load the updated resource file */ + LoadPreferences(); + + /* Define global icon, load it */ + g_hiconX = (HICON)winOverrideDefaultIcon(); + if (!g_hiconX) + g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + + /* Rebuild the icons and menus */ + EnumWindows (ReloadEnumWindowsProc, TRUE); + + /* Whew, done */ +} + +/* + * Check/uncheck the ALWAYSONTOP items in this menu + */ +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn) +{ + HWND hwnd; + HMENU hmenu; + DWORD dwExStyle; + int i, j; + + hwnd = (HWND)hwndIn; + hmenu = (HMENU)hmenuIn; + if (!hwnd || !hmenu) + return; + + if (GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) + dwExStyle = MF_BYCOMMAND | MF_CHECKED; + else + dwExStyle = MF_BYCOMMAND | MF_UNCHECKED; + + for (i=0; i<pref.menuItems; i++) + for (j=0; j<pref.menu[i].menuItems; j++) + if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP) + CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle ); + +} + +/* + * Searches for the custom WM_COMMAND command ID and performs action + */ +int +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command) +{ + HWND hwnd; + int i, j; + MENUPARSED *m; + DWORD dwExStyle; + + hwnd = (HWND)hwndIn; + + if (!command) + return 0; + + for (i=0; i<pref.menuItems; i++) + { + m = &(pref.menu[i]); + for (j=0; j<m->menuItems; j++) + { + if (command==m->menuItem[j].commandID) + { + /* Match! */ + switch(m->menuItem[j].cmd) + { + case CMD_EXEC: + if (fork()==0) + { + struct rlimit rl; + unsigned long i; + + /* Close any open descriptors except for STD* */ + getrlimit (RLIMIT_NOFILE, &rl); + for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) + close(i); + + /* Disassociate any TTYs */ + setsid(); + + execl ("/bin/sh", + "/bin/sh", + "-c", + m->menuItem[j].param, + NULL); + exit (0); + } + else + return 0; + break; + + case CMD_ALWAYSONTOP: + if (!hwnd) + return 0; + + /* 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; + + case CMD_RELOAD: + ReloadPrefs(); + return 0; + + default: + return 0; + } + } /* match */ + } /* for j */ + } /* for i */ + + return 0; +} + + +/* + * Add the default or a custom menu depending on the class match + */ +void +SetupSysMenu (unsigned long hwndIn) +{ + HWND hwnd; + HMENU sys; + int i; + WindowPtr pWin; + char *res_name, *res_class; + + hwnd = (HWND)hwndIn; + if (!hwnd) + return; + + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + sys = GetSystemMenu (hwnd, FALSE); + if (!sys) + return; + + if (pWin) + { + /* First see if there's a class match... */ + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + { + for (i=0; i<pref.sysMenuItems; i++) + { + if (!strcmp(pref.sysMenu[i].match, res_name) || + !strcmp(pref.sysMenu[i].match, res_class) ) + { + free(res_name); + free(res_class); + + MakeMenu (pref.sysMenu[i].menuName, sys, + pref.sysMenu[i].menuPos==AT_START?0:-1); + return; + } + } + + /* No match, just free alloc'd strings */ + free(res_name); + free(res_class); + } /* Found wm_class */ + } /* if pwin */ + + /* Fallback to system default */ + if (pref.defaultSysMenuName[0]) + { + if (pref.defaultSysMenuPos==AT_START) + MakeMenu (pref.defaultSysMenuName, sys, 0); + else + MakeMenu (pref.defaultSysMenuName, sys, -1); + } +} + + +/* + * Possibly add a menu to the toolbar icon + */ +void +SetupRootMenu (unsigned long hmenuRoot) +{ + HMENU root; + + root = (HMENU)hmenuRoot; + if (!root) + return; + + if (pref.rootMenuName[0]) + { + MakeMenu(pref.rootMenuName, root, 0); + } +} + + +/* + * Check for and return an overridden default ICON specified in the prefs + */ +unsigned long +winOverrideDefaultIcon() +{ + HICON hicon; + char fname[PATH_MAX+NAME_MAX+2]; + + if (pref.defaultIconName[0]) + { + /* Make sure we have a dir with trailing backslash */ + /* Note we are using _Windows_ paths here, not cygwin */ + strcpy (fname, pref.iconDirectory); + if (pref.iconDirectory[0]) + if (fname[strlen(fname)-1]!='\\') + strcat (fname, "\\"); + strcat (fname, pref.defaultIconName); + + hicon = (HICON)LoadImage(NULL, + fname, + IMAGE_ICON, + 0, 0, + LR_DEFAULTSIZE|LR_LOADFROMFILE); + if (hicon==NULL) + ErrorF ("winOverrideDefaultIcon: LoadIcon(%s) failed\n", fname); + + return (unsigned long)hicon; + } + + return 0; +} + + +/* + * Check for a match of the window class to one specified in the + * ICONS{} section in the prefs file, and load the icon from a file + */ +unsigned long +winOverrideIcon (unsigned long longWin) +{ + WindowPtr pWin = (WindowPtr) longWin; + char *res_name, *res_class; + int i; + HICON hicon; + char fname[PATH_MAX+NAME_MAX+2]; + char *wmName; + + if (pWin==NULL) + return 0; + + /* If we can't find the class, we can't override from default! */ + if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + return 0; + + winMultiWindowGetWMName (pWin, &wmName); + + for (i=0; i<pref.iconItems; i++) { + if (!strcmp(pref.icon[i].match, res_name) || + !strcmp(pref.icon[i].match, res_class) || + (wmName && strstr(wmName, pref.icon[i].match))) + { + free (res_name); + free (res_class); + if (wmName) + free (wmName); + + if (pref.icon[i].hicon) + return pref.icon[i].hicon; + + /* Make sure we have a dir with trailing backslash */ + /* Note we are using _Windows_ paths here, not cygwin */ + strcpy (fname, pref.iconDirectory); + if (pref.iconDirectory[0]) + if (fname[strlen(fname)-1]!='\\') + strcat (fname, "\\"); + strcat (fname, pref.icon[i].iconFile); + + hicon = (HICON)LoadImage(NULL, + fname, + IMAGE_ICON, + 0, 0, + LR_DEFAULTSIZE|LR_LOADFROMFILE); + if (hicon==NULL) + ErrorF ("winOverrideIcon: LoadIcon(%s) failed\n", fname); + + pref.icon[i].hicon = (unsigned long)hicon; + return (unsigned long)hicon; + } + } + + /* Didn't find the icon, fail gracefully */ + free (res_name); + free (res_class); + if (wmName) + free (wmName); + + return 0; +} + + +/* + * Should we free this icon or leave it in memory (is it part of our + * ICONS{} overrides)? + */ +int +winIconIsOverride(unsigned hiconIn) +{ + HICON hicon; + int i; + + hicon = (HICON)hiconIn; + + if (!hicon) + return 0; + + for (i=0; i<pref.iconItems; i++) + if ((HICON)pref.icon[i].hicon == hicon) + return 1; + + return 0; +} + + + +/* + * Try and open ~/.XWinrc and /usr/X11R6/lib/X11/system.XWinrc + * Load it into prefs structure for use by other functions + */ +void +LoadPreferences () +{ + char *home; + char fname[PATH_MAX+NAME_MAX+2]; + FILE *prefFile; + char szDisplay[512]; + char *szEnvDisplay; + int i, j; + char param[PARAM_MAX+1]; + char *srcParam, *dstParam; + + /* First, clear all preference settings */ + memset (&pref, 0, sizeof(pref)); + prefFile = NULL; + + /* Now try and find a ~/.xwinrc file */ + home = getenv ("HOME"); + if (home) + { + strcpy (fname, home); + if (fname[strlen(fname)-1]!='/') + strcat (fname, "/"); + strcat (fname, ".XWinrc"); + + prefFile = fopen (fname, "r"); + } + + /* No home file found, check system default */ + if (!prefFile) + prefFile = fopen (PROJECTROOT"/lib/X11/system.XWinrc", "r"); + + /* If we could open it, then read the settings and close it */ + if (prefFile) + { + parse_file (prefFile); + fclose (prefFile); + } + + /* Setup a DISPLAY environment variable, need to allocate on heap */ + /* because putenv doesn't copy the argument... */ + snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display); + szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1)); + if (szEnvDisplay) + { + strcpy (szEnvDisplay, szDisplay); + putenv (szEnvDisplay); + } + + /* Replace any "%display%" in menu commands with display string */ + snprintf (szDisplay, 512, "127.0.0.1:%s.0", display); + for (i=0; i<pref.menuItems; i++) + { + for (j=0; j<pref.menu[i].menuItems; j++) + { + if (pref.menu[i].menuItem[j].cmd==CMD_EXEC) + { + srcParam = pref.menu[i].menuItem[j].param; + dstParam = param; + while (*srcParam) { + if (!strncmp(srcParam, "%display%", 9)) + { + memcpy (dstParam, szDisplay, strlen(szDisplay)); + dstParam += strlen(szDisplay); + srcParam += 9; + } + else + { + *dstParam = *srcParam; + dstParam++; + srcParam++; + } + } + *dstParam = 0; + strcpy (pref.menu[i].menuItem[j].param, param); + } /* cmd==cmd_exec */ + } /* for all menuitems */ + } /* for all menus */ + +} + diff --git a/hw/xwin/winprefs.h b/hw/xwin/winprefs.h new file mode 100644 index 000000000..ae1cb07d8 --- /dev/null +++ b/hw/xwin/winprefs.h @@ -0,0 +1,147 @@ +/* + * 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/winprefs.h,v 1.1 2003/10/02 13:30:11 eich Exp $ */ + +/* Need to know how long paths can be... */ +#include <limits.h> + +#ifndef NAME_MAX +#define NAME_MAX PATH_MAX +#endif +#define MENU_MAX 128 /* Maximum string length of a menu name or item */ +#define PARAM_MAX (4*PATH_MAX) /* Maximim length of a parameter to a MENU */ + + +/* Supported commands in a MENU {} statement */ +typedef enum MENUCOMMANDTYPE +{ + CMD_EXEC, /* /bin/sh -c the parameter */ + CMD_MENU, /* Display a popup menu named param */ + CMD_SEPARATOR, /* Menu separator */ + CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ + CMD_RELOAD /* Reparse the .XWINRC file */ +} MENUCOMMANDTYPE; + +/* Where to place a system menu */ +typedef enum MENUPOSITION +{ + AT_START, /* Place menu at the top of the system menu */ + AT_END /* Put it at the bottom of the menu (default) */ +} MENUPOSITION; + +/* Menu item definitions */ +typedef struct MENUITEM +{ + char text[MENU_MAX+1]; /* To be displayed in menu */ + MENUCOMMANDTYPE cmd; /* What should it do? */ + char param[PARAM_MAX+1]; /* Any parameters? */ + unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ +} MENUITEM; + +/* A completely read in menu... */ +typedef struct MENUPARSED +{ + char menuName[MENU_MAX+1]; /* What's it called in the text? */ + MENUITEM *menuItem; /* Array of items */ + int menuItems; /* How big's the array? */ +} MENUPARSED; + +/* To map between a window and a system menu to add for it */ +typedef struct SYSMENUITEM +{ + char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ + char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ + MENUPOSITION menuPos; /* Where to place it (ignored in root) */ +} SYSMENUITEM; + +/* To redefine icons for certain window types */ +typedef struct ICONITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ + unsigned long hicon; /* LoadImage() result */ +} ICONITEM; + +typedef struct WINMULTIWINDOWPREFS +{ + /* Menu information */ + MENUPARSED *menu; /* Array of created menus */ + int menuItems; /* How big? */ + + /* Taskbar menu settings */ + char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */ + + /* System menu addition menus */ + SYSMENUITEM *sysMenu; + int sysMenuItems; + + /* Which menu to add to unmatched windows? */ + char defaultSysMenuName[MENU_MAX+1]; + MENUPOSITION defaultSysMenuPos; /* Where to place it */ + + /* Icon information */ + char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */ + char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */ + + ICONITEM *icon; + int iconItems; + +} WINMULTIWINDOWPREFS; + + + + +/* Functions */ +void +LoadPreferences(); + +void +SetupRootMenu (unsigned long hmenuRoot); + +void +SetupSysMenu (unsigned long hwndIn); + +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn); + +int +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command); + +int +winIconIsOverride (unsigned hiconIn); + +unsigned long +winOverrideIcon (unsigned long longpWin); + +unsigned long +winOverrideDefaultIcon(); + diff --git a/hw/xwin/winprefslex.l b/hw/xwin/winprefslex.l new file mode 100644 index 000000000..8eda8e6c2 --- /dev/null +++ b/hw/xwin/winprefslex.l @@ -0,0 +1,113 @@ +%{ # -*- C -*- +/* + * 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/winprefslex.l,v 1.1 2003/10/02 13:30:11 eich Exp $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "winprefsyacc.h" + +extern YYSTYPE yylval; +extern char *yytext; +extern int yyparse(); + +extern void ErrorF (const char* /*f*/, ...); + +int yylineno; + +/* Copy the parsed string, must be free()d in yacc parser */ +static char *makestr(char *str) +{ + char *ptr; + ptr = (char*)malloc (strlen(str)+1); + if (!ptr) + { + ErrorF ("winMultiWindowLex:makestr() out of memory\n"); + exit (-1); + } + strcpy(ptr, str); + return ptr; +} + +%} + +%option yylineno + +%% +\#.*[\r\n] { /* comment */ return NEWLINE; } +\/\/.*[\r\n] { /* comment */ return NEWLINE; } +[\r\n] { return NEWLINE; } +[ \t]+ { /* ignore whitespace */ } +[mM][eE][nN][uU] { return MENU; } +[iI][cC][oO][nN][dD][iI][rR][eE][cC][tT][oO][rR][yY] { return ICONDIRECTORY; } +[dD][eE][fF][aA][uU][lL][tT][iI][cC][oO][nN] { return DEFAULTICON; } +[iI][cC][oO][nN][sS] { return ICONS; } +[rR][oO][oO][tT][mM][eE][nN][uU] { return ROOTMENU; } +[dD][eE][fF][aA][uU][lL][tT][sS][yY][sS][mM][eE][nN][uU] { return DEFAULTSYSMENU; } +[sS][yY][sS][mM][eE][nN][uU] { return SYSMENU; } +[sS][eE][pP][aA][rR][aA][tT][oO][rR] { return SEPARATOR; } +[aA][tT][sS][tT][aA][rR][tT] { return ATSTART; } +[aA][tT][eE][nN][dD] { return ATEND; } +[eE][xX][eE][cC] { return EXEC; } +[aA][lL][wW][aA][yY][sS][oO][nN][tT][oO][pP] { return ALWAYSONTOP; } +[dD][eE][bB][uU][gG] { return DEBUG; } +[rR][eE][lL][oO][aA][dD] { return RELOAD; } +"{" { return LB; } +"}" { return RB; } +"\""[^\"\r\n]+"\"" { yylval.sVal = makestr(yytext+1); \ + yylval.sVal[strlen(yylval.sVal)-1] = 0; \ + return STRING; } +[^ \t\r\n]+ { yylval.sVal = makestr(yytext); \ + return STRING; } +%% + +/* + * Run-of-the mill requirement for yacc + */ +int +yywrap () +{ + return 1; +} + +/* + * Run a file through the yacc parser + */ +void +parse_file (FILE *file) +{ + if (!file) + return; + + yylineno = 1; + yyin = file; + yyparse (); +} diff --git a/hw/xwin/winprefsyacc.y b/hw/xwin/winprefsyacc.y new file mode 100644 index 000000000..a6ffc7207 --- /dev/null +++ b/hw/xwin/winprefsyacc.y @@ -0,0 +1,334 @@ +%{ +/* + * 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/winprefsyacc.y,v 1.1 2003/10/02 13:30:11 eich Exp $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "winprefs.h" + +/* The following give better error messages in bison at the cost of a few KB */ +#define YYERROR_VERBOSE 1 + +/* The global pref settings */ +WINMULTIWINDOWPREFS pref; + +/* The working menu */ +static MENUPARSED menu; + +/* Functions for parsing the tokens into out structure */ +/* Defined at the end section of this file */ + +static void SetIconDirectory (char *path); +static void SetDefaultIcon (char *fname); +static void SetRootMenu (char *menu); +static void SetDefaultSysMenu (char *menu, int pos); + +static void OpenMenu(char *menuname); +static void AddMenuLine(char *name, MENUCOMMANDTYPE cmd, char *param); +static void CloseMenu(); + +static void OpenIcons(); +static void AddIconLine(char *matchstr, char *iconfile); +static void CloseIcons(); + +static void OpenSysMenu(); +static void AddSysMenuLine(char *matchstr, char *menuname, int pos); +static void CloseSysMenu(); + +static int yyerror (char *s); + +extern void ErrorF (const char* /*f*/, ...); +extern char *yytext; +extern int yylex(); + +%} + +%union { + char *sVal; + int iVal; +} + +%token NEWLINE MENU LB RB ICONDIRECTORY DEFAULTICON ICONS DEFAULTSYSMENU +%token SYSMENU ROOTMENU SEPARATOR ATSTART ATEND EXEC ALWAYSONTOP DEBUG +%token RELOAD + +%token <sVal> STRING +%type <iVal> atspot + +%% + +input: /* empty */ + | input line + ; + +line: NEWLINE + | command + ; + + +newline_or_nada: + | NEWLINE newline_or_nada + ; + +command: defaulticon + | icondirectory + | menu + | icons + | sysmenu + | rootmenu + | defaultsysmenu + | debug + ; + +rootmenu: ROOTMENU STRING NEWLINE { SetRootMenu($2); free($2); } + ; + +defaultsysmenu: DEFAULTSYSMENU STRING atspot NEWLINE { SetDefaultSysMenu($2, $3); free($2); } + ; + +defaulticon: DEFAULTICON STRING NEWLINE { SetDefaultIcon($2); free($2); } + ; + +icondirectory: ICONDIRECTORY STRING NEWLINE { SetIconDirectory($2); free($2); } + ; + +menuline: SEPARATOR NEWLINE newline_or_nada { AddMenuLine("-", CMD_SEPARATOR, ""); } + | STRING ALWAYSONTOP NEWLINE newline_or_nada { AddMenuLine($1, CMD_ALWAYSONTOP, ""); free($1); } + | STRING EXEC STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_EXEC, $3); free($1); free($3); } + | STRING MENU STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_MENU, $3); free($1); free($3); } + | STRING RELOAD NEWLINE newline_or_nada { AddMenuLine($1, CMD_RELOAD, ""); free($1); } + ; + +menulist: menuline + | menuline menulist + ; + +menu: MENU STRING LB { OpenMenu($2); free($2); } newline_or_nada menulist RB {CloseMenu();} + ; + +iconline: STRING STRING NEWLINE newline_or_nada { AddIconLine($1, $2); free($1); free($2); } + ; + +iconlist: iconline + | iconline iconlist + ; + +icons: ICONS LB {OpenIcons();} newline_or_nada iconlist RB {CloseIcons();} + ; + +atspot: { $$=AT_END; } + | ATSTART { $$=AT_START; } + | ATEND { $$=AT_END; } + ; + +sysmenuline: STRING STRING atspot NEWLINE newline_or_nada { AddSysMenuLine($1, $2, $3); free($1); free($2); } + ; + +sysmenulist: sysmenuline + | sysmenuline sysmenulist + ; + +sysmenu: SYSMENU LB NEWLINE {OpenSysMenu();} newline_or_nada sysmenulist RB {CloseSysMenu();} + ; + +debug: DEBUG STRING NEWLINE { ErrorF("LoadPreferences: %s\n", $2); free($2); } + ; + + +%% +/* + * Errors in parsing abort and print log messages + */ +static int +yyerror (char *s) +{ + extern int yylineno; /* Handled by flex internally */ + + ErrorF("LoadPreferences: %s line %d\n", s, yylineno); + return 1; +} + +/* Miscellaneous functions to store TOKENs into the structure */ +static void +SetIconDirectory (char *path) +{ + strncpy (pref.iconDirectory, path, PATH_MAX); + pref.iconDirectory[PATH_MAX] = 0; +} + +static void +SetDefaultIcon (char *fname) +{ + strncpy (pref.defaultIconName, fname, NAME_MAX); + pref.defaultIconName[NAME_MAX] = 0; +} + +static void +SetRootMenu (char *menu) +{ + strncpy (pref.rootMenuName, menu, MENU_MAX); + pref.rootMenuName[MENU_MAX] = 0; +} + +static void +SetDefaultSysMenu (char *menu, int pos) +{ + strncpy (pref.defaultSysMenuName, menu, MENU_MAX); + pref.defaultSysMenuName[MENU_MAX] = 0; + pref.defaultSysMenuPos = pos; +} + +static void +OpenMenu (char *menuname) +{ + if (menu.menuItem) free(menu.menuItem); + menu.menuItem = NULL; + strncpy(menu.menuName, menuname, MENU_MAX); + menu.menuName[MENU_MAX] = 0; + menu.menuItems = 0; +} + +static void +AddMenuLine (char *text, MENUCOMMANDTYPE cmd, char *param) +{ + if (menu.menuItem==NULL) + menu.menuItem = (MENUITEM*)malloc(sizeof(MENUITEM)); + else + menu.menuItem = (MENUITEM*) + realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1)); + + strncpy (menu.menuItem[menu.menuItems].text, text, MENU_MAX); + menu.menuItem[menu.menuItems].text[MENU_MAX] = 0; + + menu.menuItem[menu.menuItems].cmd = cmd; + + strncpy(menu.menuItem[menu.menuItems].param, param, PARAM_MAX); + menu.menuItem[menu.menuItems].param[PARAM_MAX] = 0; + + menu.menuItem[menu.menuItems].commandID = 0; + + menu.menuItems++; +} + +static void +CloseMenu () +{ + if (menu.menuItem==NULL || menu.menuItems==0) + { + ErrorF("LoadPreferences: Empty menu detected\n"); + return; + } + + if (pref.menuItems) + pref.menu = (MENUPARSED*) + realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED)); + else + pref.menu = (MENUPARSED*)malloc (sizeof(MENUPARSED)); + + memcpy (pref.menu+pref.menuItems, &menu, sizeof(MENUPARSED)); + pref.menuItems++; + + memset (&menu, 0, sizeof(MENUPARSED)); +} + +static void +OpenIcons () +{ + if (pref.icon != NULL) { + ErrorF("LoadPreferences: Redefining icon mappings\n"); + free(pref.icon); + pref.icon = NULL; + } + pref.iconItems = 0; +} + +static void +AddIconLine (char *matchstr, char *iconfile) +{ + if (pref.icon==NULL) + pref.icon = (ICONITEM*)malloc(sizeof(ICONITEM)); + else + pref.icon = (ICONITEM*) + realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1)); + + strncpy(pref.icon[pref.iconItems].match, matchstr, MENU_MAX); + pref.icon[pref.iconItems].match[MENU_MAX] = 0; + + strncpy(pref.icon[pref.iconItems].iconFile, iconfile, PATH_MAX+NAME_MAX+1); + pref.icon[pref.iconItems].iconFile[PATH_MAX+NAME_MAX+1] = 0; + + pref.icon[pref.iconItems].hicon = 0; + + pref.iconItems++; +} + +static void +CloseIcons () +{ +} + +static void +OpenSysMenu () +{ + if (pref.sysMenu != NULL) { + ErrorF("LoadPreferences: Redefining system menu\n"); + free(pref.sysMenu); + pref.sysMenu = NULL; + } + pref.sysMenuItems = 0; +} + +static void +AddSysMenuLine (char *matchstr, char *menuname, int pos) +{ + if (pref.sysMenu==NULL) + pref.sysMenu = (SYSMENUITEM*)malloc(sizeof(SYSMENUITEM)); + else + pref.sysMenu = (SYSMENUITEM*) + realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1)); + + strncpy (pref.sysMenu[pref.sysMenuItems].match, matchstr, MENU_MAX); + pref.sysMenu[pref.sysMenuItems].match[MENU_MAX] = 0; + + strncpy (pref.sysMenu[pref.sysMenuItems].menuName, menuname, MENU_MAX); + pref.sysMenu[pref.sysMenuItems].menuName[MENU_MAX] = 0; + + pref.sysMenu[pref.sysMenuItems].menuPos = pos; + + pref.sysMenuItems++; +} + +static void +CloseSysMenu () +{ +} + diff --git a/hw/xwin/winpushpxl.c b/hw/xwin/winpushpxl.c new file mode 100644 index 000000000..deb9629d7 --- /dev/null +++ b/hw/xwin/winpushpxl.c @@ -0,0 +1,226 @@ +/* $XFree86: xc/programs/Xserver/hw/xwin/winpushpxl.c,v 1.1 2003/08/07 23:47:58 alanh Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#include "X.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "miscstruct.h" +#include "../mfb/maskbits.h" +#include "mi.h" + +#define NPT 128 + +/* winPushPixels -- squeegees the fill style of pGC through pBitMap + * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may + * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit + * is set in the bitmap, the fill style is put onto the drawable using + * the GC's logical function. The drawable is not changed where the bitmap + * has a zero bit or outside the area covered by the stencil. + +WARNING: + this code works if the 1-bit deep pixmap format returned by GetSpans +is the same as the format defined by the mfb code (i.e. 32-bit padding +per scanline, scanline unit = 32 bits; later, this might mean +bitsizeof(int) padding and sacnline unit == bitsizeof(int).) + + */ + +/* + * in order to have both (MSB_FIRST and LSB_FIRST) versions of this + * in the server, we need to rename one of them + */ +void +winPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg) + GCPtr pGC; + PixmapPtr pBitMap; + DrawablePtr pDrawable; + int dx, dy, xOrg, yOrg; +{ + int h, dxDivPPW, ibEnd; + MiBits *pwLineStart; + register MiBits *pw, *pwEnd; + register MiBits msk; + register int ib, w; + register int ipt; /* index into above arrays */ + Bool fInBox; + DDXPointRec pt[NPT], ptThisLine; + int width[NPT]; + PixelType startmask; + + + startmask = (MiBits)(-1) ^ + LONG2CHARSDIFFORDER((MiBits)(-1) >> 1); + + pwLineStart = (MiBits *)xalloc(BitmapBytePad(dx)); + if (!pwLineStart) + return; + ipt = 0; + dxDivPPW = dx/PPW; + + for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0; + h < dy; + h++, ptThisLine.y++) + { + + (*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx, + &ptThisLine, &dx, 1, (char *)pwLineStart); + + pw = pwLineStart; + /* Process all words which are fully in the pixmap */ + + fInBox = FALSE; + pwEnd = pwLineStart + dxDivPPW; + while(pw < pwEnd) + { + w = *pw; +#ifdef XFree86Server + msk = startmask; +#else + msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1); +#endif + for(ib = 0; ib < PPW; ib++) + { + if(w & msk) + { + if(!fInBox) + { + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + /* start new box */ + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) + { + (*pGC->ops->FillSpans)(pDrawable, pGC, + NPT, pt, width, TRUE); + ipt = 0; + } + /* end box */ + fInBox = FALSE; + } + } +#ifdef XFree86Server + /* This is not quite right, but it'll do for now */ + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); +#else + msk = SCRRIGHT(msk, 1); +#endif + } + pw++; + } + ibEnd = dx & PIM; + if(ibEnd) + { + /* Process final partial word on line */ + w = *pw; +#ifdef XFree86Server + msk = startmask; +#else + msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1); +#endif + for(ib = 0; ib < ibEnd; ib++) + { + if(w & msk) + { + if(!fInBox) + { + /* start new box */ + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + /* end box */ + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) + { + (*pGC->ops->FillSpans)(pDrawable, + pGC, NPT, pt, width, TRUE); + ipt = 0; + } + fInBox = FALSE; + } + } +#ifdef XFree86Server + /* This is not quite right, but it'll do for now */ + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); +#else + msk = SCRRIGHT(msk, 1); +#endif + } + } + /* If scanline ended with last bit set, end the box */ + if(fInBox) + { + width[ipt] = dx + xOrg - pt[ipt].x; + if (++ipt >= NPT) + { + (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE); + ipt = 0; + } + } + } + xfree(pwLineStart); + /* Flush any remaining spans */ + if (ipt) + { + (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE); + } +} diff --git a/hw/xwin/winrop.c b/hw/xwin/winrop.c new file mode 100644 index 000000000..c5ec45de5 --- /dev/null +++ b/hw/xwin/winrop.c @@ -0,0 +1,139 @@ +/* + *Copyright (C) 1994-2002 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: Alan Hourihane <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winrop.c,v 1.1 2003/08/07 23:47:58 alanh Exp $ */ + +/* + * Raster operations used by Windows translated to X's 16 rop codes... + */ +#include "win.h" + +int g_copyROP[16] = { 0xFF0062, /* GXclear - 0 */ + 0x8800C6, /* GXand - S & D */ + 0x440328, /* GXandReverse - S & !D */ + 0xCC0020, /* GXcopy - S */ + 0x220326, /* GXandInverted - !S & D */ + 0xAA0029, /* GXnoop - D */ + 0x660046, /* GXxor - S ^ D */ + 0xEE0086, /* GXor - S | D */ + 0x1100A6, /* GXnor - !S & !D */ + 0x990126, /* GXequiv - !S ^ D */ + 0x550009, /* GXinvert - !D */ + 0xDD0228, /* GXorReverse - S | !D */ + 0x330008, /* GXcopyInverted - !S */ + 0xBB0226, /* GXorInverted - !S | D */ + 0x7700C6, /* GXnand - !S | !D */ + 0x000042 /* GXset - 1 */ +}; + +int g_patternROP[16] = {0xFF0062, /* GXclear - 0 */ + 0xA000C9, /* GXand - P & D */ + 0xF50225, /* GXandReverse - P & !D */ + 0xF00021, /* GXcopy - P */ + 0x5F00E9, /* GXandInverted - !P & D */ + 0xAA0029, /* GXnoop - D */ + 0xA50065, /* GXxor - P ^ D */ + 0xA000C9, /* GXor - P | D */ + 0x5F00E9, /* GXnor - !P & !D */ + 0x5A0049, /* GXequiv - !P ^ D */ + 0x550009, /* GXinvert - !D */ + 0x500325, /* GXorReverse - P | !D */ + 0x0F0001, /* GXcopyInverted - !P */ + 0x0A0329, /* GXorInverted - !P | D */ + 0x0500A9, /* GXnand - !P | !D */ + 0x000042 /* GXset - 1 */ +}; + + +void +ROP16 (HDC hdc, int rop) +{ + switch (rop) + { + case GXclear: + SetROP2 (hdc, R2_BLACK); + break; + + case GXand: + SetROP2 (hdc, R2_MASKPEN); + break; + + case GXandReverse: + SetROP2 (hdc, R2_MASKPENNOT); + break; + + case GXcopy: + SetROP2 (hdc, R2_COPYPEN); + break; + + case GXnoop: + SetROP2 (hdc, R2_NOP); + break; + + case GXxor: + SetROP2 (hdc, R2_XORPEN); + break; + + case GXor: + SetROP2 (hdc, R2_MERGEPEN); + break; + + case GXnor: + SetROP2 (hdc, R2_NOTMERGEPEN); + break; + + case GXequiv: + SetROP2 (hdc, R2_NOTXORPEN); + break; + + case GXinvert: + SetROP2 (hdc, R2_NOT); + break; + + case GXorReverse: + SetROP2 (hdc, R2_MERGEPENNOT); + break; + + case GXcopyInverted: + SetROP2 (hdc, R2_NOTCOPYPEN); + break; + + case GXorInverted: + SetROP2 (hdc, R2_MERGENOTPEN); + break; + + case GXnand: + SetROP2 (hdc, R2_NOTMASKPEN); + break; + + case GXset: + SetROP2 (hdc, R2_WHITE); + break; + } +} diff --git a/hw/xwin/wintrayicon.c b/hw/xwin/wintrayicon.c new file mode 100755 index 000000000..90c77b1c8 --- /dev/null +++ b/hw/xwin/wintrayicon.c @@ -0,0 +1,209 @@ +/* + *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: xc/programs/Xserver/hw/xwin/wintrayicon.c,v 1.2 2003/10/02 13:30:11 eich Exp $ */ + +#include "win.h" +#include <shellapi.h> +#include "winprefs.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, + 0, + MF_BYPOSITION); + } + + SetupRootMenu ((unsigned long)hmenuTray); + + /* + * 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/hw/xwin/winvideo.c b/hw/xwin/winvideo.c new file mode 100755 index 000000000..8bf12cd66 --- /dev/null +++ b/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: xc/programs/Xserver/hw/xwin/winvideo.c,v 1.2 2003/11/10 18:22:44 tsi Exp $ */ + +#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_NULL(pScreen, &pPriv->clip); +#endif + +#if 0 + pI810->adaptor = adapt; + + pI810->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = I810BlockHandler; +#endif + +#if 0 + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); +#endif + +#if 0 + I810ResetVideo(pScrn); +#endif + + return adapt; +} +#endif |