summaryrefslogtreecommitdiff
path: root/hw/xwin
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin')
-rw-r--r--hw/xwin/_usr_X11R6_lib_X11_system.XWinrc105
-rwxr-xr-xhw/xwin/windialogs.c320
-rwxr-xr-xhw/xwin/winmultiwindowclass.c284
-rwxr-xr-xhw/xwin/winmultiwindowclass.h110
-rwxr-xr-xhw/xwin/winmultiwindowicons.c378
-rwxr-xr-xhw/xwin/winmultiwindowshape.c212
-rwxr-xr-xhw/xwin/winmultiwindowwndproc.c1005
-rw-r--r--hw/xwin/winprefs.c661
-rw-r--r--hw/xwin/winprefs.h147
-rw-r--r--hw/xwin/winprefslex.l113
-rw-r--r--hw/xwin/winprefsyacc.y334
-rw-r--r--hw/xwin/winpushpxl.c226
-rw-r--r--hw/xwin/winrop.c139
-rwxr-xr-xhw/xwin/wintrayicon.c209
-rwxr-xr-xhw/xwin/winvideo.c206
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