From 6ab3babba7b1b74528c2194a495fa1e2e67faa55 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 19 Oct 2010 19:56:00 +0000 Subject: xserver update 19/10/2010 --- xorg-server/hw/xwin/InitInput.c | 15 - xorg-server/hw/xwin/InitOutput.c | 48 +- xorg-server/hw/xwin/Makefile.am | 4 +- xorg-server/hw/xwin/XWin.man.pre | 692 +++---- xorg-server/hw/xwin/win.h | 14 +- xorg-server/hw/xwin/winblock.c | 202 +- xorg-server/hw/xwin/winclipboardthread.c | 2 +- xorg-server/hw/xwin/winclipboardxevents.c | 6 +- xorg-server/hw/xwin/winconfig.c | 12 +- xorg-server/hw/xwin/wincursor.c | 1256 ++++++------ xorg-server/hw/xwin/windialogs.c | 26 +- xorg-server/hw/xwin/winengine.c | 688 +++---- xorg-server/hw/xwin/winerror.c | 18 +- xorg-server/hw/xwin/winglobals.c | 8 - xorg-server/hw/xwin/winglobals.h | 88 + xorg-server/hw/xwin/winkeybd.c | 2 +- xorg-server/hw/xwin/winkeyhook.c | 382 ++-- xorg-server/hw/xwin/winlayouts.h | 366 +--- xorg-server/hw/xwin/winmouse.c | 769 ++++--- xorg-server/hw/xwin/winmultiwindowicons.c | 1291 ++++++------ xorg-server/hw/xwin/winmultiwindowwindow.c | 10 - xorg-server/hw/xwin/winmultiwindowwm.c | 4 +- xorg-server/hw/xwin/winmultiwindowwndproc.c | 2101 ++++++++++--------- xorg-server/hw/xwin/winnativegdi.c | 1085 +++++----- xorg-server/hw/xwin/winpfbdd.c | 1360 +++++++------ xorg-server/hw/xwin/winprefs.c | 11 - xorg-server/hw/xwin/winprefs.h | 379 ++-- xorg-server/hw/xwin/winprocarg.c | 2532 ++++++++++++----------- xorg-server/hw/xwin/winscrinit.c | 8 - xorg-server/hw/xwin/winshaddd.c | 57 +- xorg-server/hw/xwin/winshadddnl.c | 55 - xorg-server/hw/xwin/winshadgdi.c | 57 - xorg-server/hw/xwin/winvalargs.c | 367 ++-- xorg-server/hw/xwin/winwakeup.c | 132 +- xorg-server/hw/xwin/winwin32rootless.c | 1 - xorg-server/hw/xwin/winwin32rootlesswndproc.c | 2670 ++++++++++++------------- xorg-server/hw/xwin/winwindowswm.c | 30 +- xorg-server/hw/xwin/winwndproc.c | 2544 ++++++++++++----------- 38 files changed, 9411 insertions(+), 9881 deletions(-) create mode 100644 xorg-server/hw/xwin/winglobals.h (limited to 'xorg-server/hw/xwin') diff --git a/xorg-server/hw/xwin/InitInput.c b/xorg-server/hw/xwin/InitInput.c index bd5ec0845..c09610c62 100644 --- a/xorg-server/hw/xwin/InitInput.c +++ b/xorg-server/hw/xwin/InitInput.c @@ -52,21 +52,6 @@ int winProcSetSelectionOwner(ClientPtr /* client */); DeviceIntPtr g_pwinPointer; DeviceIntPtr g_pwinKeyboard; - -/* - * References to external symbols - */ - -#ifdef HAS_DEVWINDOWS -extern int g_fdMessageQueue; -#endif -extern Bool g_fXdmcpEnabled; -#ifdef XWIN_CLIPBOARD -extern winDispatchProcPtr winProcEstablishConnectionOrig; -extern winDispatchProcPtr winProcQueryTreeOrig; -#endif - - /* Called from dix/devices.c */ /* * All of our keys generate up and down transition notifications, diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index f674a08f1..fea4a34f9 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -58,29 +58,9 @@ typedef HRESULT (*SHGETFOLDERPATHPROC)( ); #endif - /* * References to external symbols */ - -extern int g_iNumScreens; -extern winScreenInfo * g_ScreenInfo; -extern char * g_pszCommandLine; -extern Bool g_fSilentFatalError; - -extern const char * g_pszLogFile; -extern Bool g_fLogFileChanged; -extern int g_iLogVerbose; -Bool g_fLogInited; - -extern Bool g_fXdmcpEnabled; -extern Bool g_fAuthEnabled; -#ifdef HAS_DEVWINDOWS -extern int g_fdMessageQueue; -#endif -extern const char * g_pszQueryHost; -extern HINSTANCE g_hInstance; - #ifdef XWIN_CLIPBOARD extern Bool g_fUnicodeClipboard; extern Bool g_fClipboardLaunched; @@ -90,15 +70,11 @@ extern HWND g_hwndClipboard; extern Bool g_fClipboard; #endif -extern HMODULE g_hmodDirectDraw; -extern FARPROC g_fpDirectDrawCreate; -extern FARPROC g_fpDirectDrawCreateClipper; - -extern HMODULE g_hmodCommonControls; -extern FARPROC g_fpTrackMouseEvent; -extern Bool g_fNoHelpMessageBox; -extern Bool g_fSilentDupError; -extern Bool g_fNativeGl; + +/* + module handle for dynamically loaded comctl32 library +*/ +static HMODULE g_hmodCommonControls = NULL; /* * Function prototypes @@ -258,15 +234,9 @@ ddxGiveUp (void) * At this point we aren't creating any new screens, so * we are guaranteed to not need the DirectDraw functions. */ - if (g_hmodDirectDraw != NULL) - { - FreeLibrary (g_hmodDirectDraw); - g_hmodDirectDraw = NULL; - g_fpDirectDrawCreate = NULL; - g_fpDirectDrawCreateClipper = NULL; - } + winReleaseDDProcAddresses(); - /* Unload our TrackMouseEvent funtion pointer */ + /* Unload our TrackMouseEvent function pointer */ if (g_hmodCommonControls != NULL) { FreeLibrary (g_hmodCommonControls); @@ -437,7 +407,7 @@ winFixupPaths (void) int needs_sep = TRUE; int comment_block = FALSE; - /* get defautl fontpath */ + /* get default fontpath */ char *fontpath = strdup(defaultFontPath); size_t size = strlen(fontpath); @@ -873,7 +843,7 @@ winUseMsg (void) ErrorF ("-silent-dup-error\n" "\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n" - "\texit silently and don’t display any error message.\n"); + "\texit silently and don't display any error message.\n"); ErrorF ("-swcursor\n" "\tDisable the usage of the Windows cursor and use the X11 software\n" diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am index a5425d4a7..6eed2bf16 100644 --- a/xorg-server/hw/xwin/Makefile.am +++ b/xorg-server/hw/xwin/Makefile.am @@ -162,8 +162,8 @@ AM_YFLAGS = -d AM_LFLAGS = -i AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ $(XWINMODULES_CFLAGS) \ - -DXFree86Server \ - -I$(top_srcdir) + -I$(top_srcdir) \ + -Wno-bad-function-cast MAN_SRCS = XWin.man.pre XWinrc.man.pre diff --git a/xorg-server/hw/xwin/XWin.man.pre b/xorg-server/hw/xwin/XWin.man.pre index 6b28b51d4..356eb625d 100644 --- a/xorg-server/hw/xwin/XWin.man.pre +++ b/xorg-server/hw/xwin/XWin.man.pre @@ -1,346 +1,346 @@ -.TH XWIN 1 __vendorversion__ -.SH NAME -XWin \- X Server for the Cygwin environment on Microsoft Windows - - -.SH SYNOPSIS -.B XWin -[ options ] ... - - -.SH DESCRIPTION -\fIXWin\fP is an X Server for the X Window System on the Cygwin environment -running on Microsoft Windows. - - -.SH MODES -\fIXWin\fP can operate in 3 different modes: -.br -* \fISingle Window\fP: This is the default mode. Each X screen -appears as a single \fIWindows\fP window and all X windows are contained -within this window. -(In X terminology, the \fIWindows\fP window contains the root window for -the screen) -.br -* \fIMulti-Window\fP: In this mode \fIXWin\fP uses its own integrated -window manager in order to handle the top-level X windows, in such a -way that they appear as normal \fIWindows\fP windows. -.br -* \fIRootless\fP: In this mode the X server works in a window -containing the whole screen but this root window (traditionally covered with an X hatch -pattern) is hidden from view, so only top-level X windows are seen. - -.SH OPTIONS -In addition to the normal server options described in the \fIXserver(1)\fP -manual page, \fIXWin\fP accepts the following command line switches, -\fIall\fP of which are optional: - -.SH OPTIONS CONTROLLING WINDOWING MODE -Only one of these options may be specified. -.TP 8 -.B (default) -Windowed or rooted mode. -Each X screen appears as a single \fIWindows\fP window and all X windows are -contained within those windows. -.TP 8 -.B \-multiwindow -Each top-level X window appears in its own \fIWindows\fP window. -Also start the integrated \fIWindows\fP-based window manager. -.TP 8 -.B \-rootless -Run the server in rootless mode. -The X server works on a window covering the whole screen but the root window -is hidden from view. -.TP 8 -.B \-mwextwm -Experimental. -The mode combines \fB\-rootless\fP mode drawing with native \fIWindows\fP -window frames managed by the experimental external window manager \fIxwinwm\fP. -.PP -\fBNOTE:\fP \fI-multiwindow\fP mode uses its own internal window manager. -All other modes require an external window manager in order to move, resize, and perform other -operations on the individual X windows. - -.SH OPTIONS FOR SPECIFYING X SCREENS -An X display may be composed of multiple screens. -The default behaviour is to create a single screen 0 that is roughly the -size of useful area of the primary monitor (allowing for any window -decorations and the task-bar). - -Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a -default to all screens by placing those screen specific parameters -before any \fB\-screen\fP parameter. Screen specific parameters placed after -the first \fB\-screen\fP parameter will apply only to the immediately -preceeding \fB\-screen\fP parameter. -.TP 8 -.B \-[no]multimonitors or \-[no]multiplemonitors -Create a screen 0 that covers all monitors [the primary monitor] on a system with -multiple monitors. -This option is currently enabled by default in \fB\-multiwindow\fP mode. -.TP 8 -.B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] " -Create screen number -.I screen_number -and optionally specify it's -.I height, -.I width -and -.I initial position. -Additionally a -.I -monitor number -(which count from 1) can be specified to place the screen on, -at which point, all coordinates become relative to that monitor. -Screen numbers must be contiguous starting from zero and cannot be duplicated. - -Examples: - -.I " -screen 0 @1 ; on 1st monitor using its full resolution (the default)" - -.I " -screen 0 800x600+100+100@2 ; on 2nd monitor offset 100,100 size 800x600" - -.I " -screen 0 1024x768@3 ; on 3rd monitor size 1024x768" - -.SH OPTIONS CONTROLLING THE APPEARANCE OF THE X SCREEN WINDOWS -These parameters only apply to windowed mode screens i.e. not -in \fB-multwindow\fP or \fB-rootless\fP mode -.TP 8 -.B "\-fullscreen" -The X server window takes the full screen, covering completely the -\fIWindows\fP desktop. -.TP 8 -.B \-nodecoration -Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, -etc. -This parameter is ignored when the \fB\-fullscreen\fP parameter is specified. -.TP 8 -.B \-scrollbars -In windowed mode, allow screens bigger than the \fIWindows\fP desktop. -Moreover, if the window has decorations, one can now resize it. -This parameter is ignored when the \fB\-fullscreen\fP parameter is specified. - - -.SH OPTIONS CONTROLLING WINDOWS INTEGRATION -.TP 8 -.B \-[no]clipboard -Enables [disables] the integration between the Cygwin/X clipboard and -\fIWindows\fP clipboard. The default is enabled. -.TP 8 -.B "\-emulate3buttons [\fItimeout\fP]" -Emulate a three button mouse; pressing both buttons within -.I timeout -milliseconds causes an emulated middle button press. The default -.I timeout -is 50 milliseconds. Note that most mice with scroll wheel have middle -button functionality, usually you will need this option only if you have -a two button mouse without scroll wheel. -.TP 8 -.B \-[no]keyhook -Enable [disable] a low-level keyboard hook for catching -special keypresses like Menu and Alt+Tab and passing them to the X -Server instead of letting \fIWindows\fP handle them. -.TP 8 -.B \-lesspointer -Normally the \fIWindows\fP mouse cursor is hidden when the mouse is -over an active Cygwin/X window. This option causes the mouse cursor -also to be hidden when it is over an inactive Cygwin/X window. This -prevents the \fIWindows\fP mouse cursor from being drawn on top of the X -cursor. -This parameter has no effect unless \fB-swcursor\fP is also specified. -.TP 8 -.B \-swcursor -Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead. -.TP 8 -.B \-[no]trayicon -Do not create a tray icon. Default is to create one -icon per screen. You can globally disable tray icons with -\fB\-notrayicon\fP, then enable it for specific screens with -\fB\-trayicon\fP for those screens. -.TP 8 -.B \-nounicodeclipboard -Do not use Unicode clipboard even if on a NT-based platform. -.TP 8 -.B \-[no]unixkill -Enable or disable the \fICtrl-Alt-Backspace\fP key combination as a -signal to exit the X Server. The \fICtrl-Alt-Backspace\fP key combination -is disabled by default. -.TP 8 -.B \-[no]winkill -Enable or disable the \fIAlt-F4\fP key combination as a signal to exit the -X Server. -The \fIAlt-F4\fP key combination is enabled by default. - -.SH DRAWING ENGINE OPTIONS -.TP 8 -.B "\-clipupdates \fInum_boxes\fP" -Specify an optional threshold, above which the regions in a shadow -update operation will be collected into a GDI clipping region. The -clipping region is then used to do a single bit block transfer that is -constrained to the updated area by the clipping region. There is some -overhead involved in creating, installing, destroying, and removing -the clipping region, thus there may not be much benefit for a small -number of boxes (less than 10). It is even possible that this -functionality does not provide a benefit at any number of boxes; we -can only determine the usefulness of this feature through testing. -This option probably has limited effect on current \fIWindows\fP versions -as they already perform GDI batching. -This parameter works in conjunction with engines 1, 2, and 4 (Shadow -GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking, -respectively). -.TP 8 -.B "\-engine \fIengine_type_id\fP" -This option, which is intended for Cygwin/X developers, -overrides the server's automatically selected engine type. This -parameter will be ignored if the specified engine type is not -supported on the current system. The supported engine type ids are 1 -- Shadow GDI, 2 - Shadow DirectDraw, and 4 - Shadow DirectDraw Non-Locking. -Additionally, there are engines with type ids -8 - Primary DirectDraw (obsolete) and 16 - Native GDI (experimental and barely functional). -Default behavior is to determine the engine with optimum performance that -supports the specified depth and window configuration. - -.SH FULLSCREEN OPTIONS -.TP 8 -.B "\-depth \fIdepth\fP" -Specify the color depth, in bits per pixel, to use when running in -fullscreen with a DirectDraw engine. This parameter is ignored if -\fB\-fullscreen\fP is not specified. -.TP 8 -.B "\-refresh \fIrate_in_Hz\fP" -Specify an optional refresh rate to use when running in -fullscreen with a DirectDraw engine. This parameter is ignored if -\fB\-fullscreen\fP is not specified. - -.SH MISCELLANEOUS OPTIONS -See also the normal server options described in the \fIXserver(1)\fP -manual page - -.TP 8 -.B \-help -Write a help text listing supported command line options and their description to the console. -.TP 8 -.B \-ignoreinput -Ignore keyboard and mouse input. This is usually only used for testing -and debugging purposes. -.TP 8 -.B "\-logfile \fIfilename\fP" -Change the server log file from the default of \fI -__logdir__/XWin.n.log\fP, -where \fIn\fP is the display number of the XWin server, to \fIfilename\fP. -.TP 8 -.B "\-logverbose \fIlevel\fP" -Control the degree of verbosity of the log messages with the integer -parameter \fIlevel\fP. For \fIlevel\fP=0 only fatal errors are -reported, for \fIlevel\fP=1 simple information about -configuration is also given, for \fIlevel\fP=2 (default) -additional runtime information is recorded -and for \fIlevel\fP=3 detailed log -information (including trace and debug output) is produced. Bigger -values will yield a still more detailed debug output. -.TP 8 -.B \-silent-dup-error -If another instance of \fIXWin\fP with the same display number is found running, -exit silently and don't display any error message. -.TP 8 -.B "\-xkblayout \fIlayout\fP" -.TP 8 -.B "\-xkbmodel \fImodel\fP" -.TP 8 -.B "\-xkboptions \fIoption\fP" -.TP 8 -.B "\-xkbrules \fIrule\fP" -.TP 8 -.B "\-xkbvariant \fIvariant\fp" -These options implement the xkeyboard extension for loading -a particular keyboard map as the X server starts. The behavior is similar -to the \fIsetxkbmap\fP program. The layout data is located at \fI -__datadir__/X11/xkb/\fP. Additional information is found in the -README files therein and in the man page of \fIsetxkbmap\fP. For example -in order to load a German layout for a pc105 keyboard one uses -the options: -.br -.I " \-xkblayout de \-xkbmodel pc105" - -Alternatively one may use the \fIsetxkbmap\fP program after \fIXWin\fP is -running. - -The default is to select a layout matching your current layout as -reported by \fIWindows\fP if known, or the default X server layout -if no matching keyboard layout was found. - -.SH UNDOCUMENTED OPTIONS -These options are undocumented. Do not use them. - -.TP 8 -.B \-emulatepseudo -Create a depth 8 PseudoColor visual when running in depths 15, 16, 24, -or 32, collectively known as TrueColor depths. -Color map manipulation is not supported, so the PseudoColor visual will -not have the correct colors. -This option is intended to allow applications which only work with a depth 8 -visual to operate in TrueColor modes. -.TP 8 -.B \-internalwm -Run the internal window manager. - -.SH LOG FILE -As it runs \fIXWin\fP writes messages indicating the most relevant events -to the console -from which it was called and to a log file that by default is located at \fI -__logdir__/XWin.0.log\fP. This file is mainly for debugging purposes. - - -.SH PREFERENCES FILE -On startup \fIXWin\fP looks for the file \fI$HOME/.XWinrc\fP or, if -the previous file does not exist, \fI -__sysconfdir__/X11/system.XWinrc\fP. \fI.XWinrc\fP allows setting -preferences for the following: -.br -* To include items into the menu associated with the \fIXWin\fP icon -which is in the \fIWindows\fP system tray. This functions in all -modes that have a tray icon. -.br -* To include items in the system menu which is associated with the \fIWindows\fP -window that \fIXWin -multiwindow\fP produces for each top-level X -window, in both the generic case and for particular programs. -.br -* To change the icon that is associated to the \fIWindows\fP window that -\fIXWin -multiwindow\fP produces for each top-level X-window. -.br -* To change the style that is associated to the \fIWindows\fP window that -\fXWin I-multiwindow\fP produces for each top-level X window. -.PP -The format of the \fI.XWinrc\fP file is given in the man page XWinrc(5). - -.SH EXAMPLES -Need some examples - - -.SH "SEE ALSO" -X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), setxkbmap(1) - - -.SH BUGS -.I XWin -and this man page still have many limitations. Some of the more obvious -ones are: -.br -- The display mode can not be changed once the X server has started. -.br -- The \fIXWin\fP software is continuously developing; it is therefore possible that -this man page is not up to date. It is always prudent to -look also at the output of \fIXWin -help\fP in order to -check the options that are operative. - - -.SH AUTHORS -This list is by no means complete, but direct contributors to the -Cygwin/X project include (in alphabetical order by last name): Stuart -Adamson, Michael Bax, Jehan Bing, Lev Bishop, Dr. Peter Busch, Biju G -C, Robert Collins, Nick Crabtree, Early Ehlinger, Christopher Faylor, -John Fortin, Brian Genisio, Fabrizio Gennari, Alexander Gottwald, Ralf -Habacker, Colin Harrison, Matthieu Herrb, Alan Hourihane, Pierre A -Humblet, Harold L Hunt II, Dakshinamurthy Karra, Joe Krahn, -Paul Loewenstein, Kensuke Matsuzaki, -Takuma Murakami, Earle F. Philhower III, Benjamin Riefenstahl, Yaakov Selkowitz, -Suhaib Siddiqi, Jack Tanner, Jon Turney and Nicholas Wourms. +.TH XWIN 1 __vendorversion__ +.SH NAME +XWin \- X Server for the Cygwin environment on Microsoft Windows + + +.SH SYNOPSIS +.B XWin +[ options ] ... + + +.SH DESCRIPTION +\fIXWin\fP is an X Server for the X Window System on the Cygwin environment +running on Microsoft Windows. + + +.SH MODES +\fIXWin\fP can operate in 3 different modes: +.br +* \fISingle Window\fP: This is the default mode. Each X screen +appears as a single \fIWindows\fP window and all X windows are contained +within this window. +(In X terminology, the \fIWindows\fP window contains the root window for +the screen) +.br +* \fIMulti-Window\fP: In this mode \fIXWin\fP uses its own integrated +window manager in order to handle the top-level X windows, in such a +way that they appear as normal \fIWindows\fP windows. +.br +* \fIRootless\fP: In this mode the X server works in a window +containing the whole screen but this root window (traditionally covered with an X hatch +pattern) is hidden from view, so only top-level X windows are seen. + +.SH OPTIONS +In addition to the normal server options described in the \fIXserver(1)\fP +manual page, \fIXWin\fP accepts the following command line switches, +\fIall\fP of which are optional: + +.SH OPTIONS CONTROLLING WINDOWING MODE +Only one of these options may be specified. +.TP 8 +.B (default) +Windowed or rooted mode. +Each X screen appears as a single \fIWindows\fP window and all X windows are +contained within those windows. +.TP 8 +.B \-multiwindow +Each top-level X window appears in its own \fIWindows\fP window. +Also start the integrated \fIWindows\fP-based window manager. +.TP 8 +.B \-rootless +Run the server in rootless mode. +The X server works on a window covering the whole screen but the root window +is hidden from view. +.TP 8 +.B \-mwextwm +Experimental. +The mode combines \fB\-rootless\fP mode drawing with native \fIWindows\fP +window frames managed by the experimental external window manager \fIxwinwm\fP. +.PP +\fBNOTE:\fP \fI-multiwindow\fP mode uses its own internal window manager. +All other modes require an external window manager in order to move, resize, and perform other +operations on the individual X windows. + +.SH OPTIONS FOR SPECIFYING X SCREENS +An X display may be composed of multiple screens. +The default behaviour is to create a single screen 0 that is roughly the +size of useful area of the primary monitor (allowing for any window +decorations and the task-bar). + +Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a +default to all screens by placing those screen specific parameters +before any \fB\-screen\fP parameter. Screen specific parameters placed after +the first \fB\-screen\fP parameter will apply only to the immediately +preceeding \fB\-screen\fP parameter. +.TP 8 +.B \-[no]multimonitors or \-[no]multiplemonitors +Create a screen 0 that covers all monitors [the primary monitor] on a system with +multiple monitors. +This option is currently enabled by default in \fB\-multiwindow\fP mode. +.TP 8 +.B "\-screen \fIscreen_number\fP [\fIW\fP \fIH\fP [\fIX\fP \fIY\fP] | [[\fIW\fPx\fIH\fP[+\fIX\fP+\fIY\fP]][@\fIM\fP]] ] " +Create screen number +.I screen_number +and optionally specify it's +.I height, +.I width +and +.I initial position. +Additionally a +.I +monitor number +(which count from 1) can be specified to place the screen on, +at which point, all coordinates become relative to that monitor. +Screen numbers must be contiguous starting from zero and cannot be duplicated. + +Examples: + +.I " -screen 0 @1 ; on 1st monitor using its full resolution (the default)" + +.I " -screen 0 800x600+100+100@2 ; on 2nd monitor offset 100,100 size 800x600" + +.I " -screen 0 1024x768@3 ; on 3rd monitor size 1024x768" + +.SH OPTIONS CONTROLLING THE APPEARANCE OF THE X SCREEN WINDOWS +These parameters only apply to windowed mode screens i.e. not +in \fB-multwindow\fP or \fB-rootless\fP mode +.TP 8 +.B "\-fullscreen" +The X server window takes the full screen, covering completely the +\fIWindows\fP desktop. +.TP 8 +.B \-nodecoration +Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, +etc. +This parameter is ignored when the \fB\-fullscreen\fP parameter is specified. +.TP 8 +.B \-scrollbars +In windowed mode, allow screens bigger than the \fIWindows\fP desktop. +Moreover, if the window has decorations, one can now resize it. +This parameter is ignored when the \fB\-fullscreen\fP parameter is specified. + + +.SH OPTIONS CONTROLLING WINDOWS INTEGRATION +.TP 8 +.B \-[no]clipboard +Enables [disables] the integration between the Cygwin/X clipboard and +\fIWindows\fP clipboard. The default is enabled. +.TP 8 +.B "\-emulate3buttons [\fItimeout\fP]" +Emulate a three button mouse; pressing both buttons within +.I timeout +milliseconds causes an emulated middle button press. The default +.I timeout +is 50 milliseconds. Note that most mice with scroll wheel have middle +button functionality, usually you will need this option only if you have +a two button mouse without scroll wheel. +.TP 8 +.B \-[no]keyhook +Enable [disable] a low-level keyboard hook for catching +special keypresses like Menu and Alt+Tab and passing them to the X +Server instead of letting \fIWindows\fP handle them. +.TP 8 +.B \-lesspointer +Normally the \fIWindows\fP mouse cursor is hidden when the mouse is +over an active Cygwin/X window. This option causes the mouse cursor +also to be hidden when it is over an inactive Cygwin/X window. This +prevents the \fIWindows\fP mouse cursor from being drawn on top of the X +cursor. +This parameter has no effect unless \fB-swcursor\fP is also specified. +.TP 8 +.B \-swcursor +Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead. +.TP 8 +.B \-[no]trayicon +Do not create a tray icon. Default is to create one +icon per screen. You can globally disable tray icons with +\fB\-notrayicon\fP, then enable it for specific screens with +\fB\-trayicon\fP for those screens. +.TP 8 +.B \-nounicodeclipboard +Do not use Unicode clipboard even if on a NT-based platform. +.TP 8 +.B \-[no]unixkill +Enable or disable the \fICtrl-Alt-Backspace\fP key combination as a +signal to exit the X Server. The \fICtrl-Alt-Backspace\fP key combination +is disabled by default. +.TP 8 +.B \-[no]winkill +Enable or disable the \fIAlt-F4\fP key combination as a signal to exit the +X Server. +The \fIAlt-F4\fP key combination is enabled by default. + +.SH DRAWING ENGINE OPTIONS +.TP 8 +.B "\-clipupdates \fInum_boxes\fP" +Specify an optional threshold, above which the regions in a shadow +update operation will be collected into a GDI clipping region. The +clipping region is then used to do a single bit block transfer that is +constrained to the updated area by the clipping region. There is some +overhead involved in creating, installing, destroying, and removing +the clipping region, thus there may not be much benefit for a small +number of boxes (less than 10). It is even possible that this +functionality does not provide a benefit at any number of boxes; we +can only determine the usefulness of this feature through testing. +This option probably has limited effect on current \fIWindows\fP versions +as they already perform GDI batching. +This parameter works in conjunction with engines 1, 2, and 4 (Shadow +GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking, +respectively). +.TP 8 +.B "\-engine \fIengine_type_id\fP" +This option, which is intended for Cygwin/X developers, +overrides the server's automatically selected engine type. This +parameter will be ignored if the specified engine type is not +supported on the current system. The supported engine type ids are 1 +- Shadow GDI, 2 - Shadow DirectDraw, and 4 - Shadow DirectDraw Non-Locking. +Additionally, there are engines with type ids +8 - Primary DirectDraw (obsolete) and 16 - Native GDI (experimental and barely functional). +Default behavior is to determine the engine with optimum performance that +supports the specified depth and window configuration. + +.SH FULLSCREEN OPTIONS +.TP 8 +.B "\-depth \fIdepth\fP" +Specify the color depth, in bits per pixel, to use when running in +fullscreen with a DirectDraw engine. This parameter is ignored if +\fB\-fullscreen\fP is not specified. +.TP 8 +.B "\-refresh \fIrate_in_Hz\fP" +Specify an optional refresh rate to use when running in +fullscreen with a DirectDraw engine. This parameter is ignored if +\fB\-fullscreen\fP is not specified. + +.SH MISCELLANEOUS OPTIONS +See also the normal server options described in the \fIXserver(1)\fP +manual page + +.TP 8 +.B \-help +Write a help text listing supported command line options and their description to the console. +.TP 8 +.B \-ignoreinput +Ignore keyboard and mouse input. This is usually only used for testing +and debugging purposes. +.TP 8 +.B "\-logfile \fIfilename\fP" +Change the server log file from the default of \fI +__logdir__/XWin.n.log\fP, +where \fIn\fP is the display number of the XWin server, to \fIfilename\fP. +.TP 8 +.B "\-logverbose \fIlevel\fP" +Control the degree of verbosity of the log messages with the integer +parameter \fIlevel\fP. For \fIlevel\fP=0 only fatal errors are +reported, for \fIlevel\fP=1 simple information about +configuration is also given, for \fIlevel\fP=2 (default) +additional runtime information is recorded +and for \fIlevel\fP=3 detailed log +information (including trace and debug output) is produced. Bigger +values will yield a still more detailed debug output. +.TP 8 +.B \-silent-dup-error +If another instance of \fIXWin\fP with the same display number is found running, +exit silently and don't display any error message. +.TP 8 +.B "\-xkblayout \fIlayout\fP" +.TP 8 +.B "\-xkbmodel \fImodel\fP" +.TP 8 +.B "\-xkboptions \fIoption\fP" +.TP 8 +.B "\-xkbrules \fIrule\fP" +.TP 8 +.B "\-xkbvariant \fIvariant\fp" +These options configure the xkeyboard extension to load +a particular keyboard map as the X server starts. The behavior is similar +to the \fIsetxkbmap\fP program. The layout data is located at \fI +__datadir__/X11/xkb/\fP. Additional information is found in the +README files therein and in the man page of \fIsetxkbmap\fP. For example +in order to load a German layout for a pc105 keyboard one uses +the options: +.br +.I " \-xkblayout de \-xkbmodel pc105" + +Alternatively one may use the \fIsetxkbmap\fP program after \fIXWin\fP is +running. + +The default is to select a configuration matching your current layout as +reported by \fIWindows\fP, if known, or the default X server configuration +if no matching keyboard configuration was found. + +.SH UNDOCUMENTED OPTIONS +These options are undocumented. Do not use them. + +.TP 8 +.B \-emulatepseudo +Create a depth 8 PseudoColor visual when running in depths 15, 16, 24, +or 32, collectively known as TrueColor depths. +Color map manipulation is not supported, so the PseudoColor visual will +not have the correct colors. +This option is intended to allow applications which only work with a depth 8 +visual to operate in TrueColor modes. +.TP 8 +.B \-internalwm +Run the internal window manager. + +.SH LOG FILE +As it runs \fIXWin\fP writes messages indicating the most relevant events +to the console +from which it was called and to a log file that by default is located at \fI +__logdir__/XWin.0.log\fP. This file is mainly for debugging purposes. + + +.SH PREFERENCES FILE +On startup \fIXWin\fP looks for the file \fI$HOME/.XWinrc\fP or, if +the previous file does not exist, \fI +__sysconfdir__/X11/system.XWinrc\fP. \fI.XWinrc\fP allows setting +preferences for the following: +.br +* To include items into the menu associated with the \fIXWin\fP icon +which is in the \fIWindows\fP system tray. This functions in all +modes that have a tray icon. +.br +* To include items in the system menu which is associated with the \fIWindows\fP +window that \fIXWin -multiwindow\fP produces for each top-level X +window, in both the generic case and for particular programs. +.br +* To change the icon that is associated to the \fIWindows\fP window that +\fIXWin -multiwindow\fP produces for each top-level X-window. +.br +* To change the style that is associated to the \fIWindows\fP window that +\fXWin I-multiwindow\fP produces for each top-level X window. +.PP +The format of the \fI.XWinrc\fP file is given in the man page XWinrc(5). + +.SH EXAMPLES +Need some examples + + +.SH "SEE ALSO" +X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(__filemansuffix__), setxkbmap(1) + + +.SH BUGS +.I XWin +and this man page still have many limitations. Some of the more obvious +ones are: +.br +- The display mode can not be changed once the X server has started. +.br +- The \fIXWin\fP software is continuously developing; it is therefore possible that +this man page is not up to date. It is always prudent to +look also at the output of \fIXWin -help\fP in order to +check the options that are operative. + + +.SH AUTHORS +This list is by no means complete, but direct contributors to the +Cygwin/X project include (in alphabetical order by last name): Stuart +Adamson, Michael Bax, Jehan Bing, Lev Bishop, Dr. Peter Busch, Biju G +C, Robert Collins, Nick Crabtree, Early Ehlinger, Christopher Faylor, +John Fortin, Brian Genisio, Fabrizio Gennari, Alexander Gottwald, Ralf +Habacker, Colin Harrison, Matthieu Herrb, Alan Hourihane, Pierre A +Humblet, Harold L Hunt II, Dakshinamurthy Karra, Joe Krahn, +Paul Loewenstein, Kensuke Matsuzaki, +Takuma Murakami, Earle F. Philhower III, Benjamin Riefenstahl, Yaakov Selkowitz, +Suhaib Siddiqi, Jack Tanner, Jon Turney and Nicholas Wourms. diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h index 5cc4dbc69..253f194e0 100644 --- a/xorg-server/hw/xwin/win.h +++ b/xorg-server/hw/xwin/win.h @@ -314,9 +314,6 @@ typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin); typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr); -/* Typedef for DIX wrapper functions */ -typedef int (*winDispatchProcPtr) (ClientPtr); - /* * GC (graphics context) privates @@ -622,6 +619,8 @@ typedef struct { * Extern declares for general global variables */ +#include "winglobals.h" + extern winScreenInfo * g_ScreenInfo; extern miPointerScreenFuncRec g_winPointerCursorFuncs; extern DWORD g_dwEvents; @@ -648,16 +647,12 @@ extern const char * g_pszQueryHost; extern DeviceIntPtr g_pwinPointer; extern DeviceIntPtr g_pwinKeyboard; - /* - * Extern declares for dynamically loaded libraries and function pointers + * Extern declares for dynamically loaded library function pointers */ -extern HMODULE g_hmodDirectDraw; extern FARPROC g_fpDirectDrawCreate; extern FARPROC g_fpDirectDrawCreateClipper; - -extern HMODULE g_hmodCommonControls; extern FARPROC g_fpTrackMouseEvent; @@ -859,6 +854,9 @@ winSetEngine (ScreenPtr pScreen); Bool winGetDDProcAddresses (void); +void +winReleaseDDProcAddresses(void); + /* * winerror.c diff --git a/xorg-server/hw/xwin/winblock.c b/xorg-server/hw/xwin/winblock.c index abea60e0f..a70d7a42a 100644 --- a/xorg-server/hw/xwin/winblock.c +++ b/xorg-server/hw/xwin/winblock.c @@ -1,106 +1,96 @@ -/* - *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include "winmsg.h" - - -/* - * References to external symbols - */ - -extern HWND g_hDlgDepthChange; -extern HWND g_hDlgExit; -extern HWND g_hDlgAbout; - - -/* See Porting Layer Definition - p. 6 */ -void -winBlockHandler (int nScreen, - pointer pBlockData, - pointer pTimeout, - pointer pReadMask) -{ -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - winScreenPriv((ScreenPtr)pBlockData); -#endif - MSG msg; -#ifndef HAS_DEVWINDOWS - struct timeval **tvp = pTimeout; - if (*tvp != NULL) - { - (*tvp)->tv_sec = 0; - (*tvp)->tv_usec = 100; - } -#endif - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - /* Signal threaded modules to begin */ - if (pScreenPriv != NULL && !pScreenPriv->fServerStarted) - { - int iReturn; - - winDebug ("winBlockHandler - Releasing pmServerStarted\n"); - - /* Flag that modules are to be started */ - pScreenPriv->fServerStarted = TRUE; - - /* Unlock the mutex for threaded modules */ - iReturn = pthread_mutex_unlock (&pScreenPriv->pmServerStarted); - if (iReturn != 0) - { - ErrorF ("winBlockHandler - pthread_mutex_unlock () failed: %d\n", - iReturn); - goto winBlockHandler_ProcessMessages; - } - - winDebug ("winBlockHandler - pthread_mutex_unlock () returned\n"); - } - -winBlockHandler_ProcessMessages: -#endif - - /* Process all messages on our queue */ - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) - { - if ((g_hDlgDepthChange == 0 - || !IsDialogMessage (g_hDlgDepthChange, &msg)) - && (g_hDlgExit == 0 - || !IsDialogMessage (g_hDlgExit, &msg)) - && (g_hDlgAbout == 0 - || !IsDialogMessage (g_hDlgAbout, &msg))) - { - DispatchMessage (&msg); - } - } -} +/* + *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include "winmsg.h" + +/* See Porting Layer Definition - p. 6 */ +void +winBlockHandler (int nScreen, + pointer pBlockData, + pointer pTimeout, + pointer pReadMask) +{ +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + winScreenPriv((ScreenPtr)pBlockData); +#endif + MSG msg; +#ifndef HAS_DEVWINDOWS + struct timeval **tvp = pTimeout; + if (*tvp != NULL) + { + (*tvp)->tv_sec = 0; + (*tvp)->tv_usec = 100; + } +#endif + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Signal threaded modules to begin */ + if (pScreenPriv != NULL && !pScreenPriv->fServerStarted) + { + int iReturn; + + winDebug ("winBlockHandler - Releasing pmServerStarted\n"); + + /* Flag that modules are to be started */ + pScreenPriv->fServerStarted = TRUE; + + /* Unlock the mutex for threaded modules */ + iReturn = pthread_mutex_unlock (&pScreenPriv->pmServerStarted); + if (iReturn != 0) + { + ErrorF ("winBlockHandler - pthread_mutex_unlock () failed: %d\n", + iReturn); + goto winBlockHandler_ProcessMessages; + } + + winDebug ("winBlockHandler - pthread_mutex_unlock () returned\n"); + } + +winBlockHandler_ProcessMessages: +#endif + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if ((g_hDlgDepthChange == 0 + || !IsDialogMessage (g_hDlgDepthChange, &msg)) + && (g_hDlgExit == 0 + || !IsDialogMessage (g_hDlgExit, &msg)) + && (g_hDlgAbout == 0 + || !IsDialogMessage (g_hDlgAbout, &msg))) + { + DispatchMessage (&msg); + } + } +} diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c index 01f288047..34a963ce8 100644 --- a/xorg-server/hw/xwin/winclipboardthread.c +++ b/xorg-server/hw/xwin/winclipboardthread.c @@ -437,7 +437,7 @@ winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) pszErrorMsg, sizeof (pszErrorMsg)); ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n" - "\tSerial: %d, Request Code: %d, Minor Code: %d\n", + "\tSerial: %lu, Request Code: %d, Minor Code: %d\n", pszErrorMsg, pErr->serial, pErr->request_code, diff --git a/xorg-server/hw/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c index 4dfcca406..c331f402e 100644 --- a/xorg-server/hw/xwin/winclipboardxevents.c +++ b/xorg-server/hw/xwin/winclipboardxevents.c @@ -76,7 +76,7 @@ winClipboardFlushXEvents (HWND hwnd, XEvent event; XSelectionEvent eventSelection; unsigned long ulReturnBytesLeft; - unsigned char *pszReturnData = NULL; + char *pszReturnData = NULL; char *pszGlobalData = NULL; int iReturn; HGLOBAL hGlobal = NULL; @@ -221,7 +221,7 @@ winClipboardFlushXEvents (HWND hwnd, if (!OpenClipboard (hwnd)) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "OpenClipboard () failed: %08x\n", + "OpenClipboard () failed: %08lx\n", GetLastError ()); /* Abort */ @@ -262,7 +262,7 @@ winClipboardFlushXEvents (HWND hwnd, if (!hGlobal) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "GetClipboardData () failed: %08x\n", + "GetClipboardData () failed: %08lx\n", GetLastError ()); /* Abort */ diff --git a/xorg-server/hw/xwin/winconfig.c b/xorg-server/hw/xwin/winconfig.c index 744273ed8..2503bcb1a 100644 --- a/xorg-server/hw/xwin/winconfig.c +++ b/xorg-server/hw/xwin/winconfig.c @@ -712,8 +712,8 @@ winNameCompare (const char *s1, const char *s2) while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; - c1 = (isupper (*s1) ? tolower (*s1) : *s1); - c2 = (isupper (*s2) ? tolower (*s2) : *s2); + c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1); + c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2); while (c1 == c2) { @@ -727,8 +727,8 @@ winNameCompare (const char *s1, const char *s2) while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; - c1 = (isupper (*s1) ? tolower (*s1) : *s1); - c2 = (isupper (*s2) ? tolower (*s2) : *s2); + c1 = (isupper ((int)*s1) ? tolower ((int)*s1) : *s1); + c2 = (isupper ((int)*s2) ? tolower ((int)*s2) : *s2); } return c1 - c2; } @@ -1089,8 +1089,8 @@ winNormalizeName (const char *s) case '\t': continue; default: - if (isupper (*p)) - *q++ = tolower (*p); + if (isupper ((int)*p)) + *q++ = tolower ((int)*p); else *q++ = *p; } diff --git a/xorg-server/hw/xwin/wincursor.c b/xorg-server/hw/xwin/wincursor.c index 7f1935a5d..9f669bcf8 100644 --- a/xorg-server/hw/xwin/wincursor.c +++ b/xorg-server/hw/xwin/wincursor.c @@ -1,629 +1,627 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include "winmsg.h" -#include -#include -#include -#include "misc.h" - -extern Bool g_fSoftwareCursor; - -#define BRIGHTNESS(x) (x##Red * 0.299 + x##Green * 0.587 + x##Blue * 0.114) - -#if 0 -# define WIN_DEBUG_MSG winDebug -#else -# define WIN_DEBUG_MSG(...) -#endif - -/* - * Local function prototypes - */ - -static void -winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); - -static Bool -winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y); - -static void -winCrossScreen (ScreenPtr pScreen, Bool fEntering); - -miPointerScreenFuncRec g_winPointerCursorFuncs = -{ - winCursorOffScreen, - winCrossScreen, - winPointerWarpCursor -}; - - -static void -winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - winScreenPriv(pScreen); - RECT rcClient; - static Bool s_fInitialWarp = TRUE; - - /* Discard first warp call */ - if (s_fInitialWarp) - { - /* First warp moves mouse to center of window, just ignore it */ - - /* Don't ignore subsequent warps */ - s_fInitialWarp = FALSE; - - winErrorFVerb (2, "winPointerWarpCursor - Discarding first warp: %d %d\n", - x, y); - - return; - } - - /* - Only update the Windows cursor position if root window is active, - or we are in a rootless mode - */ - if ((pScreenPriv->hwndScreen == GetForegroundWindow ()) - || pScreenPriv->pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOW - || pScreenPriv->pScreenInfo->fMultiWindow -#endif - ) - { - /* Get the client area coordinates */ - GetClientRect (pScreenPriv->hwndScreen, &rcClient); - - /* Translate the client area coords to screen coords */ - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&rcClient, - 2); - - /* - * Update the Windows cursor position so that we don't - * immediately warp back to the current position. - */ - SetCursorPos (rcClient.left + x, rcClient.top + y); - } - - /* Call the mi warp procedure to do the actual warping in X. */ - miPointerWarpCursor (pDev, pScreen, x, y); -} - -static Bool -winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y) -{ - return FALSE; -} - -static void -winCrossScreen (ScreenPtr pScreen, Bool fEntering) -{ -} - -static unsigned char -reverse(unsigned char c) -{ - int i; - unsigned char ret = 0; - for (i = 0; i < 8; ++i) - { - ret |= ((c >> i)&1) << (7 - i); - } - return ret; -} - -/* - * Convert X cursor to Windows cursor - * FIXME: Perhaps there are more smart code - */ -static HCURSOR -winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) -{ - winScreenPriv(pScreen); - HCURSOR hCursor = NULL; - unsigned char *pAnd; - unsigned char *pXor; - int nCX, nCY; - int nBytes; - double dForeY, dBackY; - BOOL fReverse; - HBITMAP hAnd, hXor; - ICONINFO ii; - unsigned char *pCur; - int x, y; - unsigned char bit; - HDC hDC; - BITMAPV4HEADER bi; - BITMAPINFO *pbmi; - unsigned long *lpBits; - - WIN_DEBUG_MSG("winLoadCursor: Win32: %dx%d X11: %dx%d hotspot: %d,%d\n", - pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, - pCursor->bits->width, pCursor->bits->height, - pCursor->bits->xhot, pCursor->bits->yhot - ); - - /* We can use only White and Black, so calc brightness of color - * Also check if the cursor is inverted */ - dForeY = BRIGHTNESS(pCursor->fore); - dBackY = BRIGHTNESS(pCursor->back); - fReverse = dForeY < dBackY; - - /* Check wether the X11 cursor is bigger than the win32 cursor */ - if (pScreenPriv->cursor.sm_cx < pCursor->bits->width || - pScreenPriv->cursor.sm_cy < pCursor->bits->height) - { - winErrorFVerb (3, "winLoadCursor - Windows requires %dx%d cursor but X requires %dx%d\n", - pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, - pCursor->bits->width, pCursor->bits->height); - } - - /* Get the number of bytes required to store the whole cursor image - * This is roughly (sm_cx * sm_cy) / 8 - * round up to 8 pixel boundary so we can convert whole bytes */ - nBytes = bits_to_bytes(pScreenPriv->cursor.sm_cx) * pScreenPriv->cursor.sm_cy; - - /* Get the effective width and height */ - nCX = min(pScreenPriv->cursor.sm_cx, pCursor->bits->width); - nCY = min(pScreenPriv->cursor.sm_cy, pCursor->bits->height); - - /* Allocate memory for the bitmaps */ - pAnd = malloc (nBytes); - memset (pAnd, 0xFF, nBytes); - pXor = calloc (1, nBytes); - - /* Convert the X11 bitmap to a win32 bitmap - * The first is for an empty mask */ - if (pCursor->bits->emptyMask) - { - int x, y, xmax = bits_to_bytes(nCX); - for (y = 0; y < nCY; ++y) - for (x = 0; x < xmax; ++x) - { - int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x; - int nXPix = BitmapBytePad(pCursor->bits->width) * y + x; - - pAnd[nWinPix] = 0; - if (fReverse) - pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix]); - else - pXor[nWinPix] = reverse (pCursor->bits->source[nXPix]); - } - } - else - { - int x, y, xmax = bits_to_bytes(nCX); - for (y = 0; y < nCY; ++y) - for (x = 0; x < xmax; ++x) - { - int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x; - int nXPix = BitmapBytePad(pCursor->bits->width) * y + x; - - unsigned char mask = pCursor->bits->mask[nXPix]; - pAnd[nWinPix] = reverse (~mask); - if (fReverse) - pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix] & mask); - else - pXor[nWinPix] = reverse (pCursor->bits->source[nXPix] & mask); - } - } - - /* prepare the pointers */ - hCursor = NULL; - lpBits = NULL; - - /* We have a truecolor alpha-blended cursor and can use it! */ - if (pCursor->bits->argb) - { - WIN_DEBUG_MSG("winLoadCursor: Trying truecolor alphablended cursor\n"); - memset (&bi, 0, sizeof (BITMAPV4HEADER)); - bi.bV4Size = sizeof(BITMAPV4HEADER); - bi.bV4Width = pScreenPriv->cursor.sm_cx; - bi.bV4Height = -(pScreenPriv->cursor.sm_cy); /* right-side up */ - bi.bV4Planes = 1; - bi.bV4BitCount = 32; - bi.bV4V4Compression = BI_BITFIELDS; - bi.bV4RedMask = 0x00FF0000; - bi.bV4GreenMask = 0x0000FF00; - bi.bV4BlueMask = 0x000000FF; - bi.bV4AlphaMask = 0xFF000000; - - lpBits = (unsigned long *) calloc (pScreenPriv->cursor.sm_cx*pScreenPriv->cursor.sm_cy, - sizeof (unsigned long)); - - if (lpBits) - { - for (y=0; ybits->argb[y * pCursor->bits->width]); - dst = &(lpBits[y * pScreenPriv->cursor.sm_cx]); - memcpy (dst, src, 4*nCX); - } - } - } /* End if-truecolor-icon */ - - if (!lpBits) - { - /* Bicolor, use a palettized DIB */ - WIN_DEBUG_MSG("winLoadCursor: Trying two color cursor\n"); - pbmi = (BITMAPINFO*)&bi; - memset (pbmi, 0, sizeof (BITMAPINFOHEADER)); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = pScreenPriv->cursor.sm_cx; - pbmi->bmiHeader.biHeight = -abs(pScreenPriv->cursor.sm_cy); /* right-side up */ - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = 8; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biClrUsed = 3; - pbmi->bmiHeader.biClrImportant = 3; - pbmi->bmiColors[0].rgbRed = 0; /* Empty */ - pbmi->bmiColors[0].rgbGreen = 0; - pbmi->bmiColors[0].rgbBlue = 0; - pbmi->bmiColors[0].rgbReserved = 0; - pbmi->bmiColors[1].rgbRed = pCursor->backRed>>8; /* Background */ - pbmi->bmiColors[1].rgbGreen = pCursor->backGreen>>8; - pbmi->bmiColors[1].rgbBlue = pCursor->backBlue>>8; - pbmi->bmiColors[1].rgbReserved = 0; - pbmi->bmiColors[2].rgbRed = pCursor->foreRed>>8; /* Foreground */ - pbmi->bmiColors[2].rgbGreen = pCursor->foreGreen>>8; - pbmi->bmiColors[2].rgbBlue = pCursor->foreBlue>>8; - pbmi->bmiColors[2].rgbReserved = 0; - - lpBits = (unsigned long *) calloc (pScreenPriv->cursor.sm_cx*pScreenPriv->cursor.sm_cy, - sizeof (char)); - - pCur = (unsigned char *)lpBits; - if (lpBits) - { - for (y=0; ycursor.sm_cy; y++) - { - for (x=0; xcursor.sm_cx; x++) - { - if (x>=nCX || y>=nCY) /* Outside of X11 icon bounds */ - (*pCur++) = 0; - else /* Within X11 icon bounds */ - { - int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + (x/8); - - bit = pAnd[nWinPix]; - bit = bit & (1<<(7-(x&7))); - if (!bit) /* Within the cursor mask? */ - { - int nXPix = BitmapBytePad(pCursor->bits->width) * y + (x/8); - bit = ~reverse(~pCursor->bits->source[nXPix] & pCursor->bits->mask[nXPix]); - bit = bit & (1<<(7-(x&7))); - if (bit) /* Draw foreground */ - (*pCur++) = 2; - else /* Draw background */ - (*pCur++) = 1; - } - else /* Outside the cursor mask */ - (*pCur++) = 0; - } - } /* end for (x) */ - } /* end for (y) */ - } /* end if (lpbits) */ - } - - /* If one of the previous two methods gave us the bitmap we need, make a cursor */ - if (lpBits) - { - WIN_DEBUG_MSG("winLoadCursor: Creating bitmap cursor: hotspot %d,%d\n", - pCursor->bits->xhot, pCursor->bits->yhot); - - hAnd = NULL; - hXor = NULL; - - hAnd = CreateBitmap (pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, 1, 1, pAnd); - - hDC = GetDC (NULL); - if (hDC) - { - hXor = CreateCompatibleBitmap (hDC, pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy); - SetDIBits (hDC, hXor, 0, pScreenPriv->cursor.sm_cy, lpBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS); - ReleaseDC (NULL, hDC); - } - free (lpBits); - - - if (hAnd && hXor) - { - ii.fIcon = FALSE; - ii.xHotspot = pCursor->bits->xhot; - ii.yHotspot = pCursor->bits->yhot; - ii.hbmMask = hAnd; - ii.hbmColor = hXor; - hCursor = (HCURSOR) CreateIconIndirect( &ii ); - - if (hCursor == NULL) - winW32Error(2, "winLoadCursor - CreateIconIndirect failed:"); - else - { - if (GetIconInfo(hCursor, &ii)) - { - if (ii.fIcon) - { - WIN_DEBUG_MSG("winLoadCursor: CreateIconIndirect returned no cursor. Trying again.\n"); - - DestroyCursor(hCursor); - - ii.fIcon = FALSE; - ii.xHotspot = pCursor->bits->xhot; - ii.yHotspot = pCursor->bits->yhot; - hCursor = (HCURSOR) CreateIconIndirect( &ii ); - - if (hCursor == NULL) - winW32Error(2, "winLoadCursor - CreateIconIndirect failed:"); - } - /* GetIconInfo creates new bitmaps. Destroy them again */ - if (ii.hbmMask) - DeleteObject(ii.hbmMask); - if (ii.hbmColor) - DeleteObject(ii.hbmColor); - } - } - } - - if (hAnd) - DeleteObject (hAnd); - if (hXor) - DeleteObject (hXor); - } - - if (!hCursor) - { - /* We couldn't make a color cursor for this screen, use - black and white instead */ - hCursor = CreateCursor (g_hInstance, - pCursor->bits->xhot, pCursor->bits->yhot, - pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, - pAnd, pXor); - if (hCursor == NULL) - winW32Error(2, "winLoadCursor - CreateCursor failed:"); - } - free (pAnd); - free (pXor); - - return hCursor; -} - -/* -=========================================================================== - - Pointer sprite functions - -=========================================================================== -*/ - -/* - * winRealizeCursor - * Convert the X cursor representation to native format if possible. - */ -static Bool -winRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - if(pCursor == NULL || pCursor->bits == NULL) - return FALSE; - - /* FIXME: cache ARGB8888 representation? */ - - return TRUE; -} - - -/* - * winUnrealizeCursor - * Free the storage space associated with a realized cursor. - */ -static Bool -winUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - return TRUE; -} - - -/* - * winSetCursor - * Set the cursor sprite and position. - */ -static void -winSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) -{ - POINT ptCurPos, ptTemp; - HWND hwnd; - RECT rcClient; - BOOL bInhibit; - winScreenPriv(pScreen); - WIN_DEBUG_MSG("winSetCursor: cursor=%p\n", pCursor); - - /* Inhibit changing the cursor if the mouse is not in a client area */ - bInhibit = FALSE; - if (GetCursorPos (&ptCurPos)) - { - hwnd = WindowFromPoint (ptCurPos); - if (hwnd) - { - if (GetClientRect (hwnd, &rcClient)) - { - ptTemp.x = rcClient.left; - ptTemp.y = rcClient.top; - if (ClientToScreen (hwnd, &ptTemp)) - { - rcClient.left = ptTemp.x; - rcClient.top = ptTemp.y; - ptTemp.x = rcClient.right; - ptTemp.y = rcClient.bottom; - if (ClientToScreen (hwnd, &ptTemp)) - { - rcClient.right = ptTemp.x; - rcClient.bottom = ptTemp.y; - if (!PtInRect (&rcClient, ptCurPos)) - bInhibit = TRUE; - } - } - } - } - } - - if (pCursor == NULL) - { - if (pScreenPriv->cursor.visible) - { - if (!bInhibit && g_fSoftwareCursor) - ShowCursor (FALSE); - pScreenPriv->cursor.visible = FALSE; - } - } - else - { - if (pScreenPriv->cursor.handle) - { - if (!bInhibit) - SetCursor (NULL); - DestroyCursor (pScreenPriv->cursor.handle); - pScreenPriv->cursor.handle = NULL; - } - pScreenPriv->cursor.handle = - winLoadCursor (pScreen, pCursor, pScreen->myNum); - WIN_DEBUG_MSG("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle); - - if (!bInhibit) - SetCursor (pScreenPriv->cursor.handle); - - if (!pScreenPriv->cursor.visible) - { - if (!bInhibit && g_fSoftwareCursor) - ShowCursor (TRUE); - pScreenPriv->cursor.visible = TRUE; - } - } -} - - -/* - * winMoveCursor - * Move the cursor. This is a noop for us. - */ -static void -winMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ -} - -static Bool -winDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) -{ - winScreenPriv(pScr); - return pScreenPriv->cursor.spriteFuncs->DeviceCursorInitialize(pDev, pScr); -} - -static void -winDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) -{ - winScreenPriv(pScr); - return pScreenPriv->cursor.spriteFuncs->DeviceCursorCleanup(pDev, pScr); -} - -static miPointerSpriteFuncRec winSpriteFuncsRec = { - winRealizeCursor, - winUnrealizeCursor, - winSetCursor, - winMoveCursor, - winDeviceCursorInitialize, - winDeviceCursorCleanup -}; - - -/* -=========================================================================== - - Other screen functions - -=========================================================================== -*/ - -/* - * winCursorQueryBestSize - * Handle queries for best cursor size - */ -static void -winCursorQueryBestSize (int class, unsigned short *width, - unsigned short *height, ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - - if (class == CursorShape) - { - *width = pScreenPriv->cursor.sm_cx; - *height = pScreenPriv->cursor.sm_cy; - } - else - { - if (pScreenPriv->cursor.QueryBestSize) - (*pScreenPriv->cursor.QueryBestSize)(class, width, height, pScreen); - } -} - -/* - * winInitCursor - * Initialize cursor support - */ -Bool -winInitCursor (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - miPointerScreenPtr pPointPriv; - /* override some screen procedures */ - pScreenPriv->cursor.QueryBestSize = pScreen->QueryBestSize; - pScreen->QueryBestSize = winCursorQueryBestSize; - - pPointPriv = (miPointerScreenPtr) - dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - - pScreenPriv->cursor.spriteFuncs = pPointPriv->spriteFuncs; - pPointPriv->spriteFuncs = &winSpriteFuncsRec; - - pScreenPriv->cursor.handle = NULL; - pScreenPriv->cursor.visible = FALSE; - - pScreenPriv->cursor.sm_cx = GetSystemMetrics (SM_CXCURSOR); - pScreenPriv->cursor.sm_cy = GetSystemMetrics (SM_CYCURSOR); - - return TRUE; -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include "winmsg.h" +#include +#include +#include +#include "misc.h" + +#define BRIGHTNESS(x) (x##Red * 0.299 + x##Green * 0.587 + x##Blue * 0.114) + +#if 0 +# define WIN_DEBUG_MSG winDebug +#else +# define WIN_DEBUG_MSG(...) +#endif + +/* + * Local function prototypes + */ + +static void +winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); + +static Bool +winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y); + +static void +winCrossScreen (ScreenPtr pScreen, Bool fEntering); + +miPointerScreenFuncRec g_winPointerCursorFuncs = +{ + winCursorOffScreen, + winCrossScreen, + winPointerWarpCursor +}; + + +static void +winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ + winScreenPriv(pScreen); + RECT rcClient; + static Bool s_fInitialWarp = TRUE; + + /* Discard first warp call */ + if (s_fInitialWarp) + { + /* First warp moves mouse to center of window, just ignore it */ + + /* Don't ignore subsequent warps */ + s_fInitialWarp = FALSE; + + winErrorFVerb (2, "winPointerWarpCursor - Discarding first warp: %d %d\n", + x, y); + + return; + } + + /* + Only update the Windows cursor position if root window is active, + or we are in a rootless mode + */ + if ((pScreenPriv->hwndScreen == GetForegroundWindow ()) + || pScreenPriv->pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || pScreenPriv->pScreenInfo->fMultiWindow +#endif + ) + { + /* Get the client area coordinates */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + + /* Translate the client area coords to screen coords */ + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, + 2); + + /* + * Update the Windows cursor position so that we don't + * immediately warp back to the current position. + */ + SetCursorPos (rcClient.left + x, rcClient.top + y); + } + + /* Call the mi warp procedure to do the actual warping in X. */ + miPointerWarpCursor (pDev, pScreen, x, y); +} + +static Bool +winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y) +{ + return FALSE; +} + +static void +winCrossScreen (ScreenPtr pScreen, Bool fEntering) +{ +} + +static unsigned char +reverse(unsigned char c) +{ + int i; + unsigned char ret = 0; + for (i = 0; i < 8; ++i) + { + ret |= ((c >> i)&1) << (7 - i); + } + return ret; +} + +/* + * Convert X cursor to Windows cursor + * FIXME: Perhaps there are more smart code + */ +static HCURSOR +winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) +{ + winScreenPriv(pScreen); + HCURSOR hCursor = NULL; + unsigned char *pAnd; + unsigned char *pXor; + int nCX, nCY; + int nBytes; + double dForeY, dBackY; + BOOL fReverse; + HBITMAP hAnd, hXor; + ICONINFO ii; + unsigned char *pCur; + int x, y; + unsigned char bit; + HDC hDC; + BITMAPV4HEADER bi; + BITMAPINFO *pbmi; + unsigned long *lpBits; + + WIN_DEBUG_MSG("winLoadCursor: Win32: %dx%d X11: %dx%d hotspot: %d,%d\n", + pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, + pCursor->bits->width, pCursor->bits->height, + pCursor->bits->xhot, pCursor->bits->yhot + ); + + /* We can use only White and Black, so calc brightness of color + * Also check if the cursor is inverted */ + dForeY = BRIGHTNESS(pCursor->fore); + dBackY = BRIGHTNESS(pCursor->back); + fReverse = dForeY < dBackY; + + /* Check wether the X11 cursor is bigger than the win32 cursor */ + if (pScreenPriv->cursor.sm_cx < pCursor->bits->width || + pScreenPriv->cursor.sm_cy < pCursor->bits->height) + { + winErrorFVerb (3, "winLoadCursor - Windows requires %dx%d cursor but X requires %dx%d\n", + pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, + pCursor->bits->width, pCursor->bits->height); + } + + /* Get the number of bytes required to store the whole cursor image + * This is roughly (sm_cx * sm_cy) / 8 + * round up to 8 pixel boundary so we can convert whole bytes */ + nBytes = bits_to_bytes(pScreenPriv->cursor.sm_cx) * pScreenPriv->cursor.sm_cy; + + /* Get the effective width and height */ + nCX = min(pScreenPriv->cursor.sm_cx, pCursor->bits->width); + nCY = min(pScreenPriv->cursor.sm_cy, pCursor->bits->height); + + /* Allocate memory for the bitmaps */ + pAnd = malloc (nBytes); + memset (pAnd, 0xFF, nBytes); + pXor = calloc (1, nBytes); + + /* Convert the X11 bitmap to a win32 bitmap + * The first is for an empty mask */ + if (pCursor->bits->emptyMask) + { + int x, y, xmax = bits_to_bytes(nCX); + for (y = 0; y < nCY; ++y) + for (x = 0; x < xmax; ++x) + { + int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x; + int nXPix = BitmapBytePad(pCursor->bits->width) * y + x; + + pAnd[nWinPix] = 0; + if (fReverse) + pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix]); + else + pXor[nWinPix] = reverse (pCursor->bits->source[nXPix]); + } + } + else + { + int x, y, xmax = bits_to_bytes(nCX); + for (y = 0; y < nCY; ++y) + for (x = 0; x < xmax; ++x) + { + int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x; + int nXPix = BitmapBytePad(pCursor->bits->width) * y + x; + + unsigned char mask = pCursor->bits->mask[nXPix]; + pAnd[nWinPix] = reverse (~mask); + if (fReverse) + pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix] & mask); + else + pXor[nWinPix] = reverse (pCursor->bits->source[nXPix] & mask); + } + } + + /* prepare the pointers */ + hCursor = NULL; + lpBits = NULL; + + /* We have a truecolor alpha-blended cursor and can use it! */ + if (pCursor->bits->argb) + { + WIN_DEBUG_MSG("winLoadCursor: Trying truecolor alphablended cursor\n"); + memset (&bi, 0, sizeof (BITMAPV4HEADER)); + bi.bV4Size = sizeof(BITMAPV4HEADER); + bi.bV4Width = pScreenPriv->cursor.sm_cx; + bi.bV4Height = -(pScreenPriv->cursor.sm_cy); /* right-side up */ + bi.bV4Planes = 1; + bi.bV4BitCount = 32; + bi.bV4V4Compression = BI_BITFIELDS; + bi.bV4RedMask = 0x00FF0000; + bi.bV4GreenMask = 0x0000FF00; + bi.bV4BlueMask = 0x000000FF; + bi.bV4AlphaMask = 0xFF000000; + + lpBits = (unsigned long *) calloc (pScreenPriv->cursor.sm_cx*pScreenPriv->cursor.sm_cy, + sizeof (unsigned long)); + + if (lpBits) + { + for (y=0; ybits->argb[y * pCursor->bits->width]); + dst = &(lpBits[y * pScreenPriv->cursor.sm_cx]); + memcpy (dst, src, 4*nCX); + } + } + } /* End if-truecolor-icon */ + + if (!lpBits) + { + /* Bicolor, use a palettized DIB */ + WIN_DEBUG_MSG("winLoadCursor: Trying two color cursor\n"); + pbmi = (BITMAPINFO*)&bi; + memset (pbmi, 0, sizeof (BITMAPINFOHEADER)); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pScreenPriv->cursor.sm_cx; + pbmi->bmiHeader.biHeight = -abs(pScreenPriv->cursor.sm_cy); /* right-side up */ + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = 8; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biClrUsed = 3; + pbmi->bmiHeader.biClrImportant = 3; + pbmi->bmiColors[0].rgbRed = 0; /* Empty */ + pbmi->bmiColors[0].rgbGreen = 0; + pbmi->bmiColors[0].rgbBlue = 0; + pbmi->bmiColors[0].rgbReserved = 0; + pbmi->bmiColors[1].rgbRed = pCursor->backRed>>8; /* Background */ + pbmi->bmiColors[1].rgbGreen = pCursor->backGreen>>8; + pbmi->bmiColors[1].rgbBlue = pCursor->backBlue>>8; + pbmi->bmiColors[1].rgbReserved = 0; + pbmi->bmiColors[2].rgbRed = pCursor->foreRed>>8; /* Foreground */ + pbmi->bmiColors[2].rgbGreen = pCursor->foreGreen>>8; + pbmi->bmiColors[2].rgbBlue = pCursor->foreBlue>>8; + pbmi->bmiColors[2].rgbReserved = 0; + + lpBits = (unsigned long *) calloc (pScreenPriv->cursor.sm_cx*pScreenPriv->cursor.sm_cy, + sizeof (char)); + + pCur = (unsigned char *)lpBits; + if (lpBits) + { + for (y=0; ycursor.sm_cy; y++) + { + for (x=0; xcursor.sm_cx; x++) + { + if (x>=nCX || y>=nCY) /* Outside of X11 icon bounds */ + (*pCur++) = 0; + else /* Within X11 icon bounds */ + { + int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + (x/8); + + bit = pAnd[nWinPix]; + bit = bit & (1<<(7-(x&7))); + if (!bit) /* Within the cursor mask? */ + { + int nXPix = BitmapBytePad(pCursor->bits->width) * y + (x/8); + bit = ~reverse(~pCursor->bits->source[nXPix] & pCursor->bits->mask[nXPix]); + bit = bit & (1<<(7-(x&7))); + if (bit) /* Draw foreground */ + (*pCur++) = 2; + else /* Draw background */ + (*pCur++) = 1; + } + else /* Outside the cursor mask */ + (*pCur++) = 0; + } + } /* end for (x) */ + } /* end for (y) */ + } /* end if (lpbits) */ + } + + /* If one of the previous two methods gave us the bitmap we need, make a cursor */ + if (lpBits) + { + WIN_DEBUG_MSG("winLoadCursor: Creating bitmap cursor: hotspot %d,%d\n", + pCursor->bits->xhot, pCursor->bits->yhot); + + hAnd = NULL; + hXor = NULL; + + hAnd = CreateBitmap (pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, 1, 1, pAnd); + + hDC = GetDC (NULL); + if (hDC) + { + hXor = CreateCompatibleBitmap (hDC, pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy); + SetDIBits (hDC, hXor, 0, pScreenPriv->cursor.sm_cy, lpBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS); + ReleaseDC (NULL, hDC); + } + free (lpBits); + + + if (hAnd && hXor) + { + ii.fIcon = FALSE; + ii.xHotspot = pCursor->bits->xhot; + ii.yHotspot = pCursor->bits->yhot; + ii.hbmMask = hAnd; + ii.hbmColor = hXor; + hCursor = (HCURSOR) CreateIconIndirect( &ii ); + + if (hCursor == NULL) + winW32Error(2, "winLoadCursor - CreateIconIndirect failed:"); + else + { + if (GetIconInfo(hCursor, &ii)) + { + if (ii.fIcon) + { + WIN_DEBUG_MSG("winLoadCursor: CreateIconIndirect returned no cursor. Trying again.\n"); + + DestroyCursor(hCursor); + + ii.fIcon = FALSE; + ii.xHotspot = pCursor->bits->xhot; + ii.yHotspot = pCursor->bits->yhot; + hCursor = (HCURSOR) CreateIconIndirect( &ii ); + + if (hCursor == NULL) + winW32Error(2, "winLoadCursor - CreateIconIndirect failed:"); + } + /* GetIconInfo creates new bitmaps. Destroy them again */ + if (ii.hbmMask) + DeleteObject(ii.hbmMask); + if (ii.hbmColor) + DeleteObject(ii.hbmColor); + } + } + } + + if (hAnd) + DeleteObject (hAnd); + if (hXor) + DeleteObject (hXor); + } + + if (!hCursor) + { + /* We couldn't make a color cursor for this screen, use + black and white instead */ + hCursor = CreateCursor (g_hInstance, + pCursor->bits->xhot, pCursor->bits->yhot, + pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, + pAnd, pXor); + if (hCursor == NULL) + winW32Error(2, "winLoadCursor - CreateCursor failed:"); + } + free (pAnd); + free (pXor); + + return hCursor; +} + +/* +=========================================================================== + + Pointer sprite functions + +=========================================================================== +*/ + +/* + * winRealizeCursor + * Convert the X cursor representation to native format if possible. + */ +static Bool +winRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + if(pCursor == NULL || pCursor->bits == NULL) + return FALSE; + + /* FIXME: cache ARGB8888 representation? */ + + return TRUE; +} + + +/* + * winUnrealizeCursor + * Free the storage space associated with a realized cursor. + */ +static Bool +winUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + + +/* + * winSetCursor + * Set the cursor sprite and position. + */ +static void +winSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + POINT ptCurPos, ptTemp; + HWND hwnd; + RECT rcClient; + BOOL bInhibit; + winScreenPriv(pScreen); + WIN_DEBUG_MSG("winSetCursor: cursor=%p\n", pCursor); + + /* Inhibit changing the cursor if the mouse is not in a client area */ + bInhibit = FALSE; + if (GetCursorPos (&ptCurPos)) + { + hwnd = WindowFromPoint (ptCurPos); + if (hwnd) + { + if (GetClientRect (hwnd, &rcClient)) + { + ptTemp.x = rcClient.left; + ptTemp.y = rcClient.top; + if (ClientToScreen (hwnd, &ptTemp)) + { + rcClient.left = ptTemp.x; + rcClient.top = ptTemp.y; + ptTemp.x = rcClient.right; + ptTemp.y = rcClient.bottom; + if (ClientToScreen (hwnd, &ptTemp)) + { + rcClient.right = ptTemp.x; + rcClient.bottom = ptTemp.y; + if (!PtInRect (&rcClient, ptCurPos)) + bInhibit = TRUE; + } + } + } + } + } + + if (pCursor == NULL) + { + if (pScreenPriv->cursor.visible) + { + if (!bInhibit && g_fSoftwareCursor) + ShowCursor (FALSE); + pScreenPriv->cursor.visible = FALSE; + } + } + else + { + if (pScreenPriv->cursor.handle) + { + if (!bInhibit) + SetCursor (NULL); + DestroyCursor (pScreenPriv->cursor.handle); + pScreenPriv->cursor.handle = NULL; + } + pScreenPriv->cursor.handle = + winLoadCursor (pScreen, pCursor, pScreen->myNum); + WIN_DEBUG_MSG("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle); + + if (!bInhibit) + SetCursor (pScreenPriv->cursor.handle); + + if (!pScreenPriv->cursor.visible) + { + if (!bInhibit && g_fSoftwareCursor) + ShowCursor (TRUE); + pScreenPriv->cursor.visible = TRUE; + } + } +} + + +/* + * winMoveCursor + * Move the cursor. This is a noop for us. + */ +static void +winMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ +} + +static Bool +winDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) +{ + winScreenPriv(pScr); + return pScreenPriv->cursor.spriteFuncs->DeviceCursorInitialize(pDev, pScr); +} + +static void +winDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) +{ + winScreenPriv(pScr); + pScreenPriv->cursor.spriteFuncs->DeviceCursorCleanup(pDev, pScr); +} + +static miPointerSpriteFuncRec winSpriteFuncsRec = { + winRealizeCursor, + winUnrealizeCursor, + winSetCursor, + winMoveCursor, + winDeviceCursorInitialize, + winDeviceCursorCleanup +}; + + +/* +=========================================================================== + + Other screen functions + +=========================================================================== +*/ + +/* + * winCursorQueryBestSize + * Handle queries for best cursor size + */ +static void +winCursorQueryBestSize (int class, unsigned short *width, + unsigned short *height, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + if (class == CursorShape) + { + *width = pScreenPriv->cursor.sm_cx; + *height = pScreenPriv->cursor.sm_cy; + } + else + { + if (pScreenPriv->cursor.QueryBestSize) + (*pScreenPriv->cursor.QueryBestSize)(class, width, height, pScreen); + } +} + +/* + * winInitCursor + * Initialize cursor support + */ +Bool +winInitCursor (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + miPointerScreenPtr pPointPriv; + /* override some screen procedures */ + pScreenPriv->cursor.QueryBestSize = pScreen->QueryBestSize; + pScreen->QueryBestSize = winCursorQueryBestSize; + + pPointPriv = (miPointerScreenPtr) + dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + pScreenPriv->cursor.spriteFuncs = pPointPriv->spriteFuncs; + pPointPriv->spriteFuncs = &winSpriteFuncsRec; + + pScreenPriv->cursor.handle = NULL; + pScreenPriv->cursor.visible = FALSE; + + pScreenPriv->cursor.sm_cx = GetSystemMetrics (SM_CXCURSOR); + pScreenPriv->cursor.sm_cy = GetSystemMetrics (SM_CYCURSOR); + + return TRUE; +} diff --git a/xorg-server/hw/xwin/windialogs.c b/xorg-server/hw/xwin/windialogs.c index a1e2e1709..d040af59a 100644 --- a/xorg-server/hw/xwin/windialogs.c +++ b/xorg-server/hw/xwin/windialogs.c @@ -44,21 +44,9 @@ * References to external globals */ -extern Bool g_fCursor; -extern HWND g_hDlgDepthChange; -extern HWND g_hDlgExit; -extern HWND g_hDlgAbout; -extern WINPREFS pref; #ifdef XWIN_CLIPBOARD extern Bool g_fClipboardStarted; #endif -extern Bool g_fSoftwareCursor; - -#if defined(XWIN_MULTIWINDOW) -extern HICON g_hIconX; -extern HICON g_hSmallIconX; -#endif - /* * Local function prototypes */ @@ -324,7 +312,7 @@ winDisplayExitDialog (winPrivScreenPtr pScreenPriv) /* Set focus to the Cancel button */ PostMessage (g_hDlgExit, WM_NEXTDLGCTL, - GetDlgItem (g_hDlgExit, IDCANCEL), TRUE); + (WPARAM)GetDlgItem (g_hDlgExit, IDCANCEL), TRUE); } #define CONNECTED_CLIENTS_FORMAT "There %s currently %d client%s connected." @@ -594,7 +582,7 @@ winDisplayAboutDialog (winPrivScreenPtr pScreenPriv) /* Set focus to the OK button */ PostMessage (g_hDlgAbout, WM_NEXTDLGCTL, - GetDlgItem (g_hDlgAbout, IDOK), TRUE); + (WPARAM)GetDlgItem (g_hDlgAbout, IDOK), TRUE); } @@ -675,7 +663,7 @@ winAboutDlgProc (HWND hwndDialog, UINT message, case ID_ABOUT_CHANGELOG: { - HINSTANCE iReturn; + int iReturn; #ifdef __CYGWIN__ const char * pszCygPath = "/usr/X11R6/share/doc/" "xorg-x11-xwin/changelog.html"; @@ -688,7 +676,7 @@ winAboutDlgProc (HWND hwndDialog, UINT message, "devel/server/changelog.html"; #endif - iReturn = ShellExecute (NULL, + iReturn = (int)ShellExecute (NULL, "open", pszWinPath, NULL, @@ -708,7 +696,7 @@ winAboutDlgProc (HWND hwndDialog, UINT message, const char * pszPath = __VENDORDWEBSUPPORT__; int iReturn; - iReturn = ShellExecute (NULL, + iReturn = (int)ShellExecute (NULL, "open", pszPath, NULL, @@ -728,7 +716,7 @@ winAboutDlgProc (HWND hwndDialog, UINT message, const char * pszPath = "http://x.cygwin.com/docs/ug/"; int iReturn; - iReturn = ShellExecute (NULL, + iReturn = (int)ShellExecute (NULL, "open", pszPath, NULL, @@ -748,7 +736,7 @@ winAboutDlgProc (HWND hwndDialog, UINT message, const char * pszPath = "http://x.cygwin.com/docs/faq/"; int iReturn; - iReturn = ShellExecute (NULL, + iReturn = (int)ShellExecute (NULL, "open", pszPath, NULL, diff --git a/xorg-server/hw/xwin/winengine.c b/xorg-server/hw/xwin/winengine.c index fb9aed8a0..1e3ee2bef 100644 --- a/xorg-server/hw/xwin/winengine.c +++ b/xorg-server/hw/xwin/winengine.c @@ -1,336 +1,352 @@ -/* - *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include "winmsg.h" - - -/* - * External global variables - */ - -extern const GUID _IID_IDirectDraw4; - - -/* - * Detect engines supported by current Windows version - * DirectDraw version and hardware - */ - -void -winDetectSupportedEngines (void) -{ - OSVERSIONINFO osvi; - - /* Initialize the engine support flags */ - g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI; - -#ifdef XWIN_NATIVEGDI - g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI; -#endif - - /* Get operating system version information */ - ZeroMemory (&osvi, sizeof (osvi)); - osvi.dwOSVersionInfoSize = sizeof (osvi); - GetVersionEx (&osvi); - - /* Branch on platform ID */ - switch (osvi.dwPlatformId) - { - case VER_PLATFORM_WIN32_NT: - /* Engine 4 is supported on NT only */ - winErrorFVerb (2, "winDetectSupportedEngines - Windows NT/2000/XP\n"); - break; - - case VER_PLATFORM_WIN32_WINDOWS: - /* Engine 4 is supported on NT only */ - winErrorFVerb (2, "winDetectSupportedEngines - Windows 95/98/Me\n"); - break; - } - - /* Do we have DirectDraw? */ - if (g_hmodDirectDraw != NULL) - { - LPDIRECTDRAW lpdd = NULL; - LPDIRECTDRAW4 lpdd4 = NULL; - HRESULT ddrval; - - /* Was the DirectDrawCreate function found? */ - if (g_fpDirectDrawCreate == NULL) - { - /* No DirectDraw support */ - return; - } - - /* DirectDrawCreate exists, try to call it */ - /* Create a DirectDraw object, store the address at lpdd */ - ddrval = (*g_fpDirectDrawCreate) (NULL, - (void**) &lpdd, - NULL); - if (FAILED (ddrval)) - { - /* No DirectDraw support */ - winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw not installed\n"); - return; - } - else - { - /* We have DirectDraw */ - winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw installed\n"); - g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD; - -#ifdef XWIN_PRIMARYFB - /* Allow PrimaryDD engine if NT */ - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD; - winErrorFVerb (2, "winDetectSupportedEngines - Allowing PrimaryDD\n"); - } -#endif - } - - /* Try to query for DirectDraw4 interface */ - ddrval = IDirectDraw_QueryInterface (lpdd, - &IID_IDirectDraw4, - (LPVOID*) &lpdd4); - if (SUCCEEDED (ddrval)) - { - /* We have DirectDraw4 */ - winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw4 installed\n"); - g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; - } - - /* Cleanup DirectDraw interfaces */ - if (lpdd4 != NULL) - IDirectDraw_Release (lpdd4); - if (lpdd != NULL) - IDirectDraw_Release (lpdd); - } - - winErrorFVerb (2, "winDetectSupportedEngines - Returning, supported engines %08x\n", - (unsigned int) g_dwEnginesSupported); -} - - -/* - * Set the engine type, depending on the engines - * supported for this screen, and whether the user - * suggested an engine type - */ - -Bool -winSetEngine (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HDC hdc; - DWORD dwBPP; - - /* Get a DC */ - hdc = GetDC (NULL); - if (hdc == NULL) - { - ErrorF ("winSetEngine - Couldn't get an HDC\n"); - return FALSE; - } - - /* - * pScreenInfo->dwBPP may be 0 to indicate that the current screen - * depth is to be used. Thus, we must query for the current display - * depth here. - */ - dwBPP = GetDeviceCaps (hdc, BITSPIXEL); - - /* Release the DC */ - ReleaseDC (NULL, hdc); - hdc = NULL; - - /* ShadowGDI is the only engine that supports windowed PseudoColor */ - if (dwBPP == 8 && !pScreenInfo->fFullScreen) - { - winErrorFVerb (2, "winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); - pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; - - /* Set engine function pointers */ - winSetEngineFunctionsShadowGDI (pScreen); - return TRUE; - } - - /* ShadowGDI is the only engine that supports Multi Window Mode */ - if ( -#ifdef XWIN_MULTIWINDOWEXTWM - pScreenInfo->fMWExtWM -#else - FALSE -#endif -#ifdef XWIN_MULTIWINDOW - || pScreenInfo->fMultiWindow -#else - || FALSE -#endif - ) - { - winErrorFVerb (2, "winSetEngine - Multi Window or Rootless => ShadowGDI\n"); - pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; - - /* Set engine function pointers */ - winSetEngineFunctionsShadowGDI (pScreen); - return TRUE; - } - - /* If the user's choice is supported, we'll use that */ - if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) - { - winErrorFVerb (2, "winSetEngine - Using user's preference: %d\n", - (int) pScreenInfo->dwEnginePreferred); - pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; - - /* Setup engine function pointers */ - switch (pScreenInfo->dwEngine) - { - case WIN_SERVER_SHADOW_GDI: - winSetEngineFunctionsShadowGDI (pScreen); - break; - case WIN_SERVER_SHADOW_DD: - winSetEngineFunctionsShadowDD (pScreen); - break; - case WIN_SERVER_SHADOW_DDNL: - winSetEngineFunctionsShadowDDNL (pScreen); - break; -#ifdef XWIN_PRIMARYFB - case WIN_SERVER_PRIMARY_DD: - winSetEngineFunctionsPrimaryDD (pScreen); - break; -#endif -#ifdef XWIN_NATIVEGDI - case WIN_SERVER_NATIVE_GDI: - winSetEngineFunctionsNativeGDI (pScreen); - break; -#endif - default: - FatalError ("winSetEngine - Invalid engine type\n"); - } - return TRUE; - } - - /* ShadowDDNL has good performance, so why not */ - if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) - { - winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw NonLocking\n"); - pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; - - /* Set engine function pointers */ - winSetEngineFunctionsShadowDDNL (pScreen); - return TRUE; - } - - /* ShadowDD is next in line */ - if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) - { - winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw\n"); - pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD; - - /* Set engine function pointers */ - winSetEngineFunctionsShadowDD (pScreen); - return TRUE; - } - - /* ShadowGDI is next in line */ - if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) - { - winErrorFVerb (2, "winSetEngine - Using Shadow GDI DIB\n"); - pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; - - /* Set engine function pointers */ - winSetEngineFunctionsShadowGDI (pScreen); - return TRUE; - } - - return TRUE; -} - - -/* - * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper - */ - -Bool -winGetDDProcAddresses (void) -{ - Bool fReturn = TRUE; - - /* Load the DirectDraw library */ - g_hmodDirectDraw = LoadLibraryEx ("ddraw.dll", NULL, 0); - if (g_hmodDirectDraw == NULL) - { - ErrorF ("winGetDDProcAddresses - Could not load ddraw.dll\n"); - fReturn = TRUE; - goto winGetDDProcAddresses_Exit; - } - - /* Try to get the DirectDrawCreate address */ - g_fpDirectDrawCreate = GetProcAddress (g_hmodDirectDraw, - "DirectDrawCreate"); - if (g_fpDirectDrawCreate == NULL) - { - ErrorF ("winGetDDProcAddresses - Could not get DirectDrawCreate " - "address\n"); - fReturn = TRUE; - goto winGetDDProcAddresses_Exit; - } - - /* Try to get the DirectDrawCreateClipper address */ - g_fpDirectDrawCreateClipper = GetProcAddress (g_hmodDirectDraw, - "DirectDrawCreateClipper"); - if (g_fpDirectDrawCreateClipper == NULL) - { - ErrorF ("winGetDDProcAddresses - Could not get " - "DirectDrawCreateClipper address\n"); - fReturn = FALSE; - goto winGetDDProcAddresses_Exit; - } - - /* - * Note: Do not unload ddraw.dll here. Do it in GiveUp - */ - - winGetDDProcAddresses_Exit: - /* Unload the DirectDraw library if we failed to initialize */ - if (!fReturn && g_hmodDirectDraw != NULL) - { - FreeLibrary (g_hmodDirectDraw); - g_hmodDirectDraw = NULL; - } - - return fReturn; -} +/* + *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include "winmsg.h" + +/* + * Global variables for function pointers into + * dynamically loaded libraries + */ +FARPROC g_fpDirectDrawCreate = NULL; +FARPROC g_fpDirectDrawCreateClipper = NULL; + +/* + module handle for dynamically loaded directdraw library +*/ +static HMODULE g_hmodDirectDraw = NULL; + +/* + * Detect engines supported by current Windows version + * DirectDraw version and hardware + */ + +void +winDetectSupportedEngines (void) +{ + OSVERSIONINFO osvi; + + /* Initialize the engine support flags */ + g_dwEnginesSupported = WIN_SERVER_SHADOW_GDI; + +#ifdef XWIN_NATIVEGDI + g_dwEnginesSupported |= WIN_SERVER_NATIVE_GDI; +#endif + + /* Get operating system version information */ + ZeroMemory (&osvi, sizeof (osvi)); + osvi.dwOSVersionInfoSize = sizeof (osvi); + GetVersionEx (&osvi); + + /* Branch on platform ID */ + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + /* Engine 4 is supported on NT only */ + winErrorFVerb (2, "winDetectSupportedEngines - Windows NT/2000/XP\n"); + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Engine 4 is supported on NT only */ + winErrorFVerb (2, "winDetectSupportedEngines - Windows 95/98/Me\n"); + break; + } + + /* Do we have DirectDraw? */ + if (g_hmodDirectDraw != NULL) + { + LPDIRECTDRAW lpdd = NULL; + LPDIRECTDRAW4 lpdd4 = NULL; + HRESULT ddrval; + + /* Was the DirectDrawCreate function found? */ + if (g_fpDirectDrawCreate == NULL) + { + /* No DirectDraw support */ + return; + } + + /* DirectDrawCreate exists, try to call it */ + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, + (void**) &lpdd, + NULL); + if (FAILED (ddrval)) + { + /* No DirectDraw support */ + winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw not installed\n"); + return; + } + else + { + /* We have DirectDraw */ + winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw installed\n"); + g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD; + +#ifdef XWIN_PRIMARYFB + /* Allow PrimaryDD engine if NT */ + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD; + winErrorFVerb (2, "winDetectSupportedEngines - Allowing PrimaryDD\n"); + } +#endif + } + + /* Try to query for DirectDraw4 interface */ + ddrval = IDirectDraw_QueryInterface (lpdd, + &IID_IDirectDraw4, + (LPVOID*) &lpdd4); + if (SUCCEEDED (ddrval)) + { + /* We have DirectDraw4 */ + winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw4 installed\n"); + g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; + } + + /* Cleanup DirectDraw interfaces */ + if (lpdd4 != NULL) + IDirectDraw_Release (lpdd4); + if (lpdd != NULL) + IDirectDraw_Release (lpdd); + } + + winErrorFVerb (2, "winDetectSupportedEngines - Returning, supported engines %08x\n", + (unsigned int) g_dwEnginesSupported); +} + + +/* + * Set the engine type, depending on the engines + * supported for this screen, and whether the user + * suggested an engine type + */ + +Bool +winSetEngine (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc; + DWORD dwBPP; + + /* Get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winSetEngine - Couldn't get an HDC\n"); + return FALSE; + } + + /* + * pScreenInfo->dwBPP may be 0 to indicate that the current screen + * depth is to be used. Thus, we must query for the current display + * depth here. + */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* Release the DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + + /* ShadowGDI is the only engine that supports windowed PseudoColor */ + if (dwBPP == 8 && !pScreenInfo->fFullScreen) + { + winErrorFVerb (2, "winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + /* ShadowGDI is the only engine that supports Multi Window Mode */ + if ( +#ifdef XWIN_MULTIWINDOWEXTWM + pScreenInfo->fMWExtWM +#else + FALSE +#endif +#ifdef XWIN_MULTIWINDOW + || pScreenInfo->fMultiWindow +#else + || FALSE +#endif + ) + { + winErrorFVerb (2, "winSetEngine - Multi Window or Rootless => ShadowGDI\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + /* If the user's choice is supported, we'll use that */ + if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) + { + winErrorFVerb (2, "winSetEngine - Using user's preference: %d\n", + (int) pScreenInfo->dwEnginePreferred); + pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; + + /* Setup engine function pointers */ + switch (pScreenInfo->dwEngine) + { + case WIN_SERVER_SHADOW_GDI: + winSetEngineFunctionsShadowGDI (pScreen); + break; + case WIN_SERVER_SHADOW_DD: + winSetEngineFunctionsShadowDD (pScreen); + break; + case WIN_SERVER_SHADOW_DDNL: + winSetEngineFunctionsShadowDDNL (pScreen); + break; +#ifdef XWIN_PRIMARYFB + case WIN_SERVER_PRIMARY_DD: + winSetEngineFunctionsPrimaryDD (pScreen); + break; +#endif +#ifdef XWIN_NATIVEGDI + case WIN_SERVER_NATIVE_GDI: + winSetEngineFunctionsNativeGDI (pScreen); + break; +#endif + default: + FatalError ("winSetEngine - Invalid engine type\n"); + } + return TRUE; + } + + /* ShadowDDNL has good performance, so why not */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) + { + winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw NonLocking\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowDDNL (pScreen); + return TRUE; + } + + /* ShadowDD is next in line */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) + { + winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowDD (pScreen); + return TRUE; + } + + /* ShadowGDI is next in line */ + if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) + { + winErrorFVerb (2, "winSetEngine - Using Shadow GDI DIB\n"); + pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; + + /* Set engine function pointers */ + winSetEngineFunctionsShadowGDI (pScreen); + return TRUE; + } + + return TRUE; +} + + +/* + * Get procedure addresses for DirectDrawCreate and DirectDrawCreateClipper + */ + +Bool +winGetDDProcAddresses (void) +{ + Bool fReturn = TRUE; + + /* Load the DirectDraw library */ + g_hmodDirectDraw = LoadLibraryEx ("ddraw.dll", NULL, 0); + if (g_hmodDirectDraw == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not load ddraw.dll\n"); + fReturn = TRUE; + goto winGetDDProcAddresses_Exit; + } + + /* Try to get the DirectDrawCreate address */ + g_fpDirectDrawCreate = GetProcAddress (g_hmodDirectDraw, + "DirectDrawCreate"); + if (g_fpDirectDrawCreate == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not get DirectDrawCreate " + "address\n"); + fReturn = TRUE; + goto winGetDDProcAddresses_Exit; + } + + /* Try to get the DirectDrawCreateClipper address */ + g_fpDirectDrawCreateClipper = GetProcAddress (g_hmodDirectDraw, + "DirectDrawCreateClipper"); + if (g_fpDirectDrawCreateClipper == NULL) + { + ErrorF ("winGetDDProcAddresses - Could not get " + "DirectDrawCreateClipper address\n"); + fReturn = FALSE; + goto winGetDDProcAddresses_Exit; + } + + /* + * Note: Do not unload ddraw.dll here. Do it in GiveUp + */ + + winGetDDProcAddresses_Exit: + /* Unload the DirectDraw library if we failed to initialize */ + if (!fReturn && g_hmodDirectDraw != NULL) + { + FreeLibrary (g_hmodDirectDraw); + g_hmodDirectDraw = NULL; + } + + return fReturn; +} + +void +winReleaseDDProcAddresses(void) +{ + if (g_hmodDirectDraw != NULL) + { + FreeLibrary (g_hmodDirectDraw); + g_hmodDirectDraw = NULL; + g_fpDirectDrawCreate = NULL; + g_fpDirectDrawCreateClipper = NULL; + } +} diff --git a/xorg-server/hw/xwin/winerror.c b/xorg-server/hw/xwin/winerror.c index 07a5fc660..1ee8c572f 100644 --- a/xorg-server/hw/xwin/winerror.c +++ b/xorg-server/hw/xwin/winerror.c @@ -31,21 +31,10 @@ #ifdef HAVE_XWIN_CONFIG_H #include #endif -#ifdef XVENDORNAME -#define VENDOR_STRING XVENDORNAME -#define VENDOR_CONTACT BUILDERADDR -#endif #include <../xfree86/common/xorgVersion.h> #include "win.h" -/* References to external symbols */ -extern char * g_pszCommandLine; -extern const char * g_pszLogFile; -extern Bool g_fSilentFatalError; -extern Bool g_fLogInited; - - #ifdef DDXOSVERRORF /* Prototype */ void @@ -129,11 +118,12 @@ winMessageBoxF (const char *pszError, UINT uType, ...) "%s\n" pszMsgBox = Xprintf (MESSAGEBOXF, - pszErrorF, VENDOR_STRING, + pszErrorF, XVENDORNAME, XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT, - VENDOR_CONTACT, + BUILDERADDR, BUILDERSTRING, - g_pszCommandLine); + g_pszCommandLine); + if (!pszMsgBox) goto winMessageBoxF_Cleanup; diff --git a/xorg-server/hw/xwin/winglobals.c b/xorg-server/hw/xwin/winglobals.c index 9370808ca..80d946c5d 100644 --- a/xorg-server/hw/xwin/winglobals.c +++ b/xorg-server/hw/xwin/winglobals.c @@ -73,8 +73,6 @@ char * g_pszCommandLine = NULL; Bool g_fSilentFatalError = FALSE; DWORD g_dwCurrentThreadID = 0; Bool g_fKeyboardHookLL = FALSE; -HHOOK g_hhookKeyboardLL = NULL; -HWND g_hwndKeyboardFocus = NULL; Bool g_fNoHelpMessageBox = FALSE; Bool g_fSoftwareCursor = FALSE; Bool g_fSilentDupError = FALSE; @@ -85,11 +83,6 @@ Bool g_fNativeGl = FALSE; * their function pointers */ -HMODULE g_hmodDirectDraw = NULL; -FARPROC g_fpDirectDrawCreate = NULL; -FARPROC g_fpDirectDrawCreateClipper = NULL; - -HMODULE g_hmodCommonControls = NULL; FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; @@ -127,7 +120,6 @@ void winInitializeGlobals (void) { g_dwCurrentThreadID = GetCurrentThreadId (); - g_hwndKeyboardFocus = NULL; #ifdef XWIN_CLIPBOARD g_fClipboardLaunched = FALSE; g_fClipboardStarted = FALSE; diff --git a/xorg-server/hw/xwin/winglobals.h b/xorg-server/hw/xwin/winglobals.h new file mode 100644 index 000000000..898b9388a --- /dev/null +++ b/xorg-server/hw/xwin/winglobals.h @@ -0,0 +1,88 @@ +/* + File: winglobals.h + Purpose: declarations for global variables + + 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 (including the next + paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + +*/ + +#ifndef WINGLOBALS_H +#define WINGLOBALS_H + +/* + * References to external symbols + */ + +extern int g_iNumScreens; +extern int g_iLastScreen; +extern char * g_pszCommandLine; +extern Bool g_fSilentFatalError; +extern const char * g_pszLogFile; +#ifdef RELOCATE_PROJECTROOT +extern Bool g_fLogFileChanged; +#endif +extern int g_iLogVerbose; +extern Bool g_fLogInited; + +extern Bool g_fAuthEnabled; +extern Bool g_fXdmcpEnabled; + +extern Bool g_fNoHelpMessageBox; +extern Bool g_fSilentDupError; +extern Bool g_fNativeGl; + +extern HWND g_hDlgDepthChange; +extern HWND g_hDlgExit; +extern HWND g_hDlgAbout; + +extern Bool g_fSoftwareCursor; +extern Bool g_fCursor; + +#ifdef XWIN_CLIPBOARD + +/* Typedef for DIX wrapper functions */ +typedef int (*winDispatchProcPtr) (ClientPtr); + +/* + * Wrapped DIX functions + */ +extern winDispatchProcPtr winProcEstablishConnectionOrig; +extern winDispatchProcPtr winProcQueryTreeOrig; +extern winDispatchProcPtr winProcSetSelectionOwnerOrig; +#endif + +/* The global X default icons */ +#if defined(XWIN_MULTIWINDOW) +extern HICON g_hIconX; +extern HICON g_hSmallIconX; +#endif + +#ifdef XWIN_MULTIWINDOW +extern DWORD g_dwCurrentThreadID; +#endif + +extern Bool g_fKeyboardHookLL; +extern Bool g_fButton[3]; + +#ifdef XWIN_MULTIWINDOWEXTWM +extern Bool g_fNoConfigureWindow; +#endif + +#endif /* WINGLOBALS_H */ diff --git a/xorg-server/hw/xwin/winkeybd.c b/xorg-server/hw/xwin/winkeybd.c index a2f749a71..1a44695c6 100644 --- a/xorg-server/hw/xwin/winkeybd.c +++ b/xorg-server/hw/xwin/winkeybd.c @@ -486,7 +486,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown) nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE); for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinKeyboard, events[i].event); + mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event); #if CYGDEBUG ErrorF("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n", diff --git a/xorg-server/hw/xwin/winkeyhook.c b/xorg-server/hw/xwin/winkeyhook.c index 2d6ed18b7..fcf222fd4 100644 --- a/xorg-server/hw/xwin/winkeyhook.c +++ b/xorg-server/hw/xwin/winkeyhook.c @@ -1,194 +1,188 @@ -/* - *Copyright (C) 2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" - - -/* - * References to external symbols - */ - -extern HHOOK g_hhookKeyboardLL; -extern DWORD g_dwCurrentThreadID; -extern HWND g_hwndKeyboardFocus; - - -/* - * Function prototypes - */ - -static LRESULT CALLBACK -winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam); - - -#ifndef LLKHF_EXTENDED -# define LLKHF_EXTENDED 0x00000001 -#endif -#ifndef LLKHF_UP -# define LLKHF_UP 0x00000080 -#endif - - -/* - * KeyboardMessageHook - */ - -static LRESULT CALLBACK -winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam) -{ - BOOL fPassKeystroke = FALSE; - BOOL fPassAltTab = TRUE; - PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; - HWND hwnd = GetActiveWindow(); -#ifdef XWIN_MULTIWINDOW - WindowPtr pWin = NULL; - winPrivWinPtr pWinPriv = NULL; - winPrivScreenPtr pScreenPriv = NULL; - winScreenInfo *pScreenInfo = NULL; - - /* Check if the Windows window property for our X window pointer is valid */ - if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) - { - /* Get a pointer to our window privates */ - pWinPriv = winGetWindowPriv(pWin); - - /* Get pointers to our screen privates and screen info */ - pScreenPriv = pWinPriv->pScreenPriv; - pScreenInfo = pScreenPriv->pScreenInfo; - - if (pScreenInfo->fMultiWindow) - fPassAltTab = FALSE; - } -#endif - - /* Pass keystrokes on to our main message loop */ - if (iCode == HC_ACTION) - { -#if 0 - ErrorF ("vkCode: %08x\tscanCode: %08x\n", p->vkCode, p->scanCode); -#endif - - switch (wParam) - { - case WM_KEYDOWN: case WM_SYSKEYDOWN: - case WM_KEYUP: case WM_SYSKEYUP: - fPassKeystroke = - (fPassAltTab && - (p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) - || (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN) - ; - break; - } - } - - /* - * Pass message on to our main message loop. - * We process this immediately with SendMessage so that the keystroke - * appears in, hopefully, the correct order. - */ - if (fPassKeystroke) - { - LPARAM lParamKey = 0x0; - - /* Construct the lParam from KBDLLHOOKSTRUCT */ - lParamKey = lParamKey | (0x0000FFFF & 0x00000001); /* Repeat count */ - lParamKey = lParamKey | (0x00FF0000 & (p->scanCode << 16)); - lParamKey = lParamKey - | (0x01000000 & ((p->flags & LLKHF_EXTENDED) << 23)); - lParamKey = lParamKey - | (0x20000000 - & ((p->flags & LLKHF_ALTDOWN) << 24)); - lParamKey = lParamKey | (0x80000000 & ((p->flags & LLKHF_UP) << 24)); - - /* Send message to our main window that has the keyboard focus */ - PostMessage (hwnd, - (UINT) wParam, - (WPARAM) p->vkCode, - lParamKey); - - return 1; - } - - /* Call next hook */ - return CallNextHookEx (NULL, iCode, wParam, lParam); -} - - -/* - * Attempt to install the keyboard hook, return FALSE if it was not installed - */ - -Bool -winInstallKeyboardHookLL (void) -{ - OSVERSIONINFO osvi = {0}; - - /* Get operating system version information */ - osvi.dwOSVersionInfoSize = sizeof (osvi); - GetVersionEx (&osvi); - - /* Branch on platform ID */ - switch (osvi.dwPlatformId) - { - case VER_PLATFORM_WIN32_NT: - /* Low-level is supported on NT 4.0 SP3+ only */ - /* TODO: Return FALSE on NT 4.0 with no SP, SP1, or SP2 */ - break; - - case VER_PLATFORM_WIN32_WINDOWS: - /* Low-level hook is not supported on non-NT */ - return FALSE; - } - - /* Install the hook only once */ - if (!g_hhookKeyboardLL) - g_hhookKeyboardLL = SetWindowsHookEx (WH_KEYBOARD_LL, - winKeyboardMessageHookLL, - g_hInstance, - 0); - - return TRUE; -} - - -/* - * Remove the keyboard hook if it is installed - */ - -void -winRemoveKeyboardHookLL (void) -{ - if (g_hhookKeyboardLL) - UnhookWindowsHookEx (g_hhookKeyboardLL); - g_hhookKeyboardLL = NULL; -} +/* + *Copyright (C) 2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + + +static HHOOK g_hhookKeyboardLL = NULL; + + +/* + * Function prototypes + */ + +static LRESULT CALLBACK +winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam); + + +#ifndef LLKHF_EXTENDED +# define LLKHF_EXTENDED 0x00000001 +#endif +#ifndef LLKHF_UP +# define LLKHF_UP 0x00000080 +#endif + + +/* + * KeyboardMessageHook + */ + +static LRESULT CALLBACK +winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam) +{ + BOOL fPassKeystroke = FALSE; + BOOL fPassAltTab = TRUE; + PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; + HWND hwnd = GetActiveWindow(); +#ifdef XWIN_MULTIWINDOW + WindowPtr pWin = NULL; + winPrivWinPtr pWinPriv = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + /* Get a pointer to our window privates */ + pWinPriv = winGetWindowPriv(pWin); + + /* Get pointers to our screen privates and screen info */ + pScreenPriv = pWinPriv->pScreenPriv; + pScreenInfo = pScreenPriv->pScreenInfo; + + if (pScreenInfo->fMultiWindow) + fPassAltTab = FALSE; + } +#endif + + /* Pass keystrokes on to our main message loop */ + if (iCode == HC_ACTION) + { +#if 0 + ErrorF ("vkCode: %08x\tscanCode: %08x\n", p->vkCode, p->scanCode); +#endif + + switch (wParam) + { + case WM_KEYDOWN: case WM_SYSKEYDOWN: + case WM_KEYUP: case WM_SYSKEYUP: + fPassKeystroke = + (fPassAltTab && + (p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0)) + || (p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN) + ; + break; + } + } + + /* + * Pass message on to our main message loop. + * We process this immediately with SendMessage so that the keystroke + * appears in, hopefully, the correct order. + */ + if (fPassKeystroke) + { + LPARAM lParamKey = 0x0; + + /* Construct the lParam from KBDLLHOOKSTRUCT */ + lParamKey = lParamKey | (0x0000FFFF & 0x00000001); /* Repeat count */ + lParamKey = lParamKey | (0x00FF0000 & (p->scanCode << 16)); + lParamKey = lParamKey + | (0x01000000 & ((p->flags & LLKHF_EXTENDED) << 23)); + lParamKey = lParamKey + | (0x20000000 + & ((p->flags & LLKHF_ALTDOWN) << 24)); + lParamKey = lParamKey | (0x80000000 & ((p->flags & LLKHF_UP) << 24)); + + /* Send message to our main window that has the keyboard focus */ + PostMessage (hwnd, + (UINT) wParam, + (WPARAM) p->vkCode, + lParamKey); + + return 1; + } + + /* Call next hook */ + return CallNextHookEx (NULL, iCode, wParam, lParam); +} + + +/* + * Attempt to install the keyboard hook, return FALSE if it was not installed + */ + +Bool +winInstallKeyboardHookLL (void) +{ + OSVERSIONINFO osvi = {0}; + + /* Get operating system version information */ + osvi.dwOSVersionInfoSize = sizeof (osvi); + GetVersionEx (&osvi); + + /* Branch on platform ID */ + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + /* Low-level is supported on NT 4.0 SP3+ only */ + /* TODO: Return FALSE on NT 4.0 with no SP, SP1, or SP2 */ + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Low-level hook is not supported on non-NT */ + return FALSE; + } + + /* Install the hook only once */ + if (!g_hhookKeyboardLL) + g_hhookKeyboardLL = SetWindowsHookEx (WH_KEYBOARD_LL, + winKeyboardMessageHookLL, + g_hInstance, + 0); + + return TRUE; +} + + +/* + * Remove the keyboard hook if it is installed + */ + +void +winRemoveKeyboardHookLL (void) +{ + if (g_hhookKeyboardLL) + UnhookWindowsHookEx (g_hhookKeyboardLL); + g_hhookKeyboardLL = NULL; +} diff --git a/xorg-server/hw/xwin/winlayouts.h b/xorg-server/hw/xwin/winlayouts.h index d1d21a12d..3cbc91244 100644 --- a/xorg-server/hw/xwin/winlayouts.h +++ b/xorg-server/hw/xwin/winlayouts.h @@ -1,273 +1,93 @@ -/* - * Copyright (c) 2005 Alexander Gottwald - * - * 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 ABOVE LISTED COPYRIGHT HOLDER(S) 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(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ -/* Definitions for various keyboard layouts from windows and their - * XKB settings. - */ - -typedef struct -{ - unsigned int winlayout; - int winkbtype; - char *xkbmodel; - char *xkblayout; - char *xkbvariant; - char *xkboptions; - char *layoutname; -} WinKBLayoutRec, *WinKBLayoutPtr; - -/* - This table is sorted by low byte of winlayout, then by next byte, etc. -*/ - -WinKBLayoutRec winKBLayouts[] = -{ - { 0x404, -1, "pc105", "zh_TW", NULL, NULL, "Chinese (Taiwan)"}, - { 0x405, -1, "pc105", "cz", NULL, NULL, "Czech"}, - {0x10405, -1, "pc105", "cz_qwerty", NULL, NULL, "Czech (QWERTY)"}, - { 0x406, -1, "pc105", "dk", NULL, NULL, "Danish"}, - { 0x407, -1, "pc105", "de", NULL, NULL, "German (Germany)"}, - {0x10407, -1, "pc105", "de", NULL, NULL, "German (Germany, IBM)"}, - { 0x807, -1, "pc105", "ch", "de", NULL, "German (Switzerland)"}, - { 0x409, -1, "pc105", "us", NULL, NULL, "English (USA)"}, - {0x10409, -1, "pc105", "dvorak", NULL, NULL, "English (USA, Dvorak)"}, - {0x20409, -1, "pc105", "us_intl", NULL, NULL, "English (USA, International)"}, - { 0x809, -1, "pc105", "gb", NULL, NULL, "English (United Kingdom)"}, - { 0x1809, -1, "pc105", "ie", NULL, NULL, "Irish"}, - { 0x40a, -1, "pc105", "es", NULL, NULL, "Spanish (Spain, Traditional Sort)"}, - { 0x80a, -1, "pc105", "latam", NULL, NULL, "Latin American"}, - { 0x40b, -1, "pc105", "fi", NULL, NULL, "Finnish"}, - { 0x40c, -1, "pc105", "fr", NULL, NULL, "French (Standard)"}, - { 0x80c, -1, "pc105", "be", NULL, NULL, "French (Belgian)"}, - { 0xc0c, -1, "pc105", "ca", "fr", NULL, "French (Canada)"}, - { 0x100c, -1, "pc105", "ch", "fr", NULL, "French (Switzerland)"}, - { 0x40d, -1, "pc105", "il", NULL, NULL, "Hebrew"}, - { 0x40e, -1, "pc105", "hu", NULL, NULL, "Hungarian"}, - { 0x40f, -1, "pc105", "is", NULL, NULL, "Icelandic"}, - { 0x410, -1, "pc105", "it", NULL, NULL, "Italian"}, - {0x10410, -1, "pc105", "it", NULL, NULL, "Italian (142)"}, - {0xa0000410,-1, "macbook79","it", "mac",NULL, "Italiano (Apple)"}, - { 0x411, 7, "jp106", "jp", NULL, NULL, "Japanese"}, - { 0x413, -1, "pc105", "nl", NULL, NULL, "Dutch"}, - { 0x813, -1, "pc105", "be", NULL, NULL, "Dutch (Belgian)"}, - { 0x414, -1, "pc105", "no", NULL, NULL, "Norwegian"}, - { 0x415, -1, "pc105", "pl", NULL, NULL, "Polish (Programmers)"}, - { 0x416, -1, "pc105", "br", NULL, NULL, "Portuguese (Brazil, ABNT)"}, - {0x10416, -1, "abnt2", "br", NULL, NULL, "Portuguese (Brazil, ABNT2)"}, - { 0x816, -1, "pc105", "pt", NULL, NULL, "Portuguese (Portugal)"}, - { 0x41a, -1, "pc105", "hr", NULL, NULL, "Croatian"}, - { 0x41d, -1, "pc105", "se", NULL, NULL, "Swedish (Sweden)"}, - { 0x424, -1, "pc105", "si", NULL, NULL, "Slovenian"}, - { 0x425, -1, "pc105", "ee", NULL, NULL, "Estonian"}, - { 0x452, -1, "pc105", "gb", "intl", NULL, "United Kingdom (Extended)"}, - { -1, -1, NULL, NULL, NULL, NULL, NULL} -}; - -/* Listing of language codes from MSDN */ -/* -Support ID XKB Language -==================================================================== - ? 0x0000 Language Neutral - ? 0x0400 Process or User Default Language - ? 0x0800 System Default Language - 0x0401 Arabic (Saudi Arabia) - 0x0801 Arabic (Iraq) - 0x0c01 Arabic (Egypt) - 0x1001 Arabic (Libya) - 0x1401 Arabic (Algeria) - 0x1801 Arabic (Morocco) - 0x1c01 Arabic (Tunisia) - 0x2001 Arabic (Oman) - 0x2401 Arabic (Yemen) - 0x2801 Arabic (Syria) - 0x2c01 Arabic (Jordan) - 0x3001 Arabic (Lebanon) - 0x3401 Arabic (Kuwait) - 0x3801 Arabic (U.A.E.) - 0x3c01 Arabic (Bahrain) - 0x4001 Arabic (Qatar) - Arabic (102) AZERTY - 0x0402 Bulgarian - 0x0403 Catalan - 0x0404 Chinese (Taiwan) - 0x0804 Chinese (PRC) - 0x0c04 Chinese (Hong Kong SAR, PRC) - 0x1004 Chinese (Singapore) - 0x1404 Chinese (Macao SAR) (98/ME,2K/XP) - X 0x0405 cz Czech - X cz_qwerty Czech (QWERTY) - Czech (Programmers) - X 0x0406 dk Danish - X 0x0407 de German (Standard) - X 0x0807 de_CH German (Switzerland) - 0x0c07 German (Austria) - 0x1007 German (Luxembourg) - 0x1407 German (Liechtenstein) - 0x0408 Greek - X 0x0409 us English (United States) - X 0x0809 gb English (United Kingdom) - 0x0c09 English (Australian) - 0x1009 English (Canadian) - 0x1409 English (New Zealand) - X 0x1809 ie English (Ireland) - 0x1c09 English (South Africa) - 0x2009 English (Jamaica) - 0x2409 English (Caribbean) - 0x2809 English (Belize) - 0x2c09 English (Trinidad) - 0x3009 English (Zimbabwe) (98/ME,2K/XP) - 0x3409 English (Philippines) (98/ME,2K/XP) - X 0x040a es Spanish (Spain, Traditional Sort) - 0x080a Spanish (Mexican) - 0x0c0a Spanish (Spain, Modern Sort) - 0x100a Spanish (Guatemala) - 0x140a Spanish (Costa Rica) - 0x180a Spanish (Panama) - 0x1c0a Spanish (Dominican Republic) - 0x200a Spanish (Venezuela) - 0x240a Spanish (Colombia) - 0x280a Spanish (Peru) - 0x2c0a Spanish (Argentina) - 0x300a Spanish (Ecuador) - 0x340a Spanish (Chile) - 0x380a Spanish (Uruguay) - 0x3c0a Spanish (Paraguay) - 0x400a Spanish (Bolivia) - 0x440a Spanish (El Salvador) - 0x480a Spanish (Honduras) - 0x4c0a Spanish (Nicaragua) - 0x500a Spanish (Puerto Rico) - X 0x040b fi Finnish - Finnish (with Sami) - X 0x040c fr French (Standard) - X 0x080c be French (Belgian) - . 0x0c0c French (Canadian) - French (Canadian, Legacy) - Canadian (Multilingual) - X 0x100c fr_CH French (Switzerland) - 0x140c French (Luxembourg) - 0x180c French (Monaco) (98/ME,2K/XP) - 0x040d Hebrew - X 0x040e hu Hungarian - . 0x040f Icelandic - X 0x0410 it Italian (Standard) - 0x0810 Italian (Switzerland) - X 0x0411 jp Japanese - 0x0412 Korean - 0x0812 Korean (Johab) (95,NT) - . 0x0413 Dutch (Netherlands) - X 0x0813 be Dutch (Belgium) - X 0x0414 no Norwegian (Bokmal) - 0x0814 Norwegian (Nynorsk) - . 0x0415 Polish - X 0x0416 br Portuguese (Brazil) - X 0x0816 pt Portuguese (Portugal) - . 0x0418 Romanian - 0x0419 Russian - . 0x041a Croatian - . 0x081a Serbian (Latin) - . 0x0c1a Serbian (Cyrillic) - 0x101a Croatian (Bosnia and Herzegovina) - 0x141a Bosnian (Bosnia and Herzegovina) - 0x181a Serbian (Latin, Bosnia, and Herzegovina) - 0x1c1a Serbian (Cyrillic, Bosnia, and Herzegovina) - . 0x041b Slovak - . 0x041c Albanian - X 0x041d se Swedish - 0x081d Swedish (Finland) - 0x041e Thai - 0x041f Turkish - 0x0420 Urdu (Pakistan) (98/ME,2K/XP) - 0x0820 Urdu (India) - 0x0421 Indonesian - 0x0422 Ukrainian - 0x0423 Belarusian - . 0x0424 Slovenian - 0x0425 Estonian - 0x0426 Latvian - 0x0427 Lithuanian - 0x0827 Lithuanian (Classic) (98) - 0x0429 Farsi - 0x042a Vietnamese (98/ME,NT,2K/XP) - 0x042b Armenian. This is Unicode only. (2K/XP) - Armenian Eastern - Armenian Western - 0x042c Azeri (Latin) - 0x082c Azeri (Cyrillic) - 0x042d Basque - 0x042f Macedonian (FYROM) - 0x0430 Sutu - 0x0432 Setswana/Tswana (South Africa) - 0x0434 isiXhosa/Xhosa (South Africa) - 0x0435 isiZulu/Zulu (South Africa) - 0x0436 Afrikaans - 0x0437 Georgian. This is Unicode only. (2K/XP) - . 0x0438 Faeroese - 0x0439 Hindi. This is Unicode only. (2K/XP) - 0x043a Maltese (Malta) - 0x043b Sami, Northern (Norway) - 0x083b Sami, Northern (Sweden) - 0x0c3b Sami, Northern (Finland) - 0x103b Sami, Lule (Norway) - 0x143b Sami, Lule (Sweden) - 0x183b Sami, Southern (Norway) - 0x1c3b Sami, Southern (Sweden) - 0x203b Sami, Skolt (Finland) - 0x243b Sami, Inari (Finland) - 0x043e Malay (Malaysian) - 0x083e Malay (Brunei Darussalam) - 0x0440 Kyrgyz. (XP) - 0x0441 Swahili (Kenya) - 0x0443 Uzbek (Latin) - 0x0843 Uzbek (Cyrillic) - 0x0444 Tatar (Tatarstan) - 0x0445 Bengali (India) - Bengali (Inscript) - 0x0446 Punjabi. This is Unicode only. (XP) - 0x0447 Gujarati. This is Unicode only. (XP) - 0x0449 Tamil. This is Unicode only. (2K/XP) - 0x044a Telugu. This is Unicode only. (XP) - 0x044b Kannada. This is Unicode only. (XP) - 0x044c Malayalam (India) - 0x044e Marathi. This is Unicode only. (2K/XP) - 0x044f Sanskrit. This is Unicode only. (2K/XP) - 0x0450 Mongolian (XP) - 0x0452 Welsh (United Kingdom) - 0x0455 Burmese - 0x0456 Galician (XP) - 0x0457 Konkani. This is Unicode only. (2K/XP) - 0x045a Syriac. This is Unicode only. (XP) - 0x0465 Divehi. This is Unicode only. (XP) - Divehi (Phonetic) - Divehi (Typewriter) - 0x046b Quechua (Bolivia) - 0x086b Quechua (Ecuador) - 0x0c6b Quechua (Peru) - 0x046c Sesotho sa Leboa/Northern Sotho (South Africa) - 0x007f LOCALE_INVARIANT. See MAKELCID. - 0x0481 Maori (New Zealand) -*/ - - +/* + * Copyright (c) 2005 Alexander Gottwald + * + * 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 ABOVE LISTED COPYRIGHT HOLDER(S) 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(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ +/* Definitions for various keyboard layouts from windows and their + * XKB settings. + */ + +typedef struct +{ + unsigned int winlayout; + int winkbtype; + char *xkbmodel; + char *xkblayout; + char *xkbvariant; + char *xkboptions; + char *layoutname; +} WinKBLayoutRec, *WinKBLayoutPtr; + +/* + This table is sorted by low byte of winlayout, then by next byte, etc. +*/ + +WinKBLayoutRec winKBLayouts[] = +{ + { 0x00000404, -1, "pc105", "zh_TW", NULL, NULL, "Chinese (Taiwan)"}, + { 0x00000405, -1, "pc105", "cz", NULL, NULL, "Czech"}, + { 0x00010405, -1, "pc105", "cz_qwerty", NULL, NULL, "Czech (QWERTY)"}, + { 0x00000406, -1, "pc105", "dk", NULL, NULL, "Danish"}, + { 0x00000407, -1, "pc105", "de", NULL, NULL, "German (Germany)"}, + { 0x00010407, -1, "pc105", "de", NULL, NULL, "German (Germany,IBM)"}, + { 0x00000807, -1, "pc105", "ch", "de", NULL, "German (Switzerland)"}, + { 0x00000409, -1, "pc105", "us", NULL, NULL, "English (USA)"}, + { 0x00010409, -1, "pc105", "dvorak", NULL, NULL, "English (USA,Dvorak)"}, + { 0x00020409, -1, "pc105", "us_intl", NULL, NULL, "English (USA,International)"}, + { 0x00000809, -1, "pc105", "gb", NULL, NULL, "English (United Kingdom)"}, + { 0x00001809, -1, "pc105", "ie", NULL, NULL, "Irish"}, + { 0x0000040a, -1, "pc105", "es", NULL, NULL, "Spanish (Spain,Traditional Sort)"}, + { 0x0000080a, -1, "pc105", "latam", NULL, NULL, "Latin American"}, + { 0x0000040b, -1, "pc105", "fi", NULL, NULL, "Finnish"}, + { 0x0000040c, -1, "pc105", "fr", NULL, NULL, "French (Standard)"}, + { 0x0000080c, -1, "pc105", "be", NULL, NULL, "French (Belgian)"}, + { 0x00000c0c, -1, "pc105", "ca", "fr", NULL, "French (Canada)"}, + { 0x0000100c, -1, "pc105", "ch", "fr", NULL, "French (Switzerland)"}, + { 0x0000040d, -1, "pc105", "il", NULL, NULL, "Hebrew"}, + { 0x0000040e, -1, "pc105", "hu", NULL, NULL, "Hungarian"}, + { 0x0000040f, -1, "pc105", "is", NULL, NULL, "Icelandic"}, + { 0x00000410, -1, "pc105", "it", NULL, NULL, "Italian"}, + { 0x00010410, -1, "pc105", "it", NULL, NULL, "Italian (142)"}, + { 0xa0000410, -1, "macbook79", "it", "mac", NULL, "Italiano (Apple)"}, + { 0x00000411, 7, "jp106", "jp", NULL, NULL, "Japanese"}, + { 0x00000413, -1, "pc105", "nl", NULL, NULL, "Dutch"}, + { 0x00000813, -1, "pc105", "be", NULL, NULL, "Dutch (Belgian)"}, + { 0x00000414, -1, "pc105", "no", NULL, NULL, "Norwegian"}, + { 0x00000415, -1, "pc105", "pl", NULL, NULL, "Polish (Programmers)"}, + { 0x00000416, -1, "pc105", "br", NULL, NULL, "Portuguese (Brazil,ABNT)"}, + { 0x00010416, -1, "abnt2", "br", NULL, NULL, "Portuguese (Brazil,ABNT2)"}, + { 0x00000816, -1, "pc105", "pt", NULL, NULL, "Portuguese (Portugal)"}, + { 0x0000041a, -1, "pc105", "hr", NULL, NULL, "Croatian"}, + { 0x0000041d, -1, "pc105", "se", NULL, NULL, "Swedish (Sweden)"}, + { 0x00000424, -1, "pc105", "si", NULL, NULL, "Slovenian"}, + { 0x00000425, -1, "pc105", "ee", NULL, NULL, "Estonian"}, + { 0x00000452, -1, "pc105", "gb", "intl", NULL, "United Kingdom (Extended)"}, + { -1, -1, NULL, NULL, NULL, NULL, NULL} +}; + +/* + See http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx + for a listing of input locale (keyboard layout) codes +*/ + + diff --git a/xorg-server/hw/xwin/winmouse.c b/xorg-server/hw/xwin/winmouse.c index 342f20d56..d6cb109ea 100644 --- a/xorg-server/hw/xwin/winmouse.c +++ b/xorg-server/hw/xwin/winmouse.c @@ -1,388 +1,381 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" - -#if defined(XFree86Server) -#include "inputstr.h" -#include "exevents.h" /* for button/axes labels */ -#include "xserver-properties.h" - -/* Peek the internal button mapping */ -static CARD8 const *g_winMouseButtonMap = NULL; -#endif - - -/* - * Local prototypes - */ - -static void -winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl); - - -static void -winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl) -{ -} - - -/* - * See Porting Layer Definition - p. 18 - * This is known as a DeviceProc - */ - -int -winMouseProc (DeviceIntPtr pDeviceInt, int iState) -{ - int lngMouseButtons, i; - int lngWheelEvents = 2; - CARD8 *map; - DevicePtr pDevice = (DevicePtr) pDeviceInt; - Atom *btn_labels; - Atom axes_labels[2]; - - switch (iState) - { - case DEVICE_INIT: - /* Get number of mouse buttons */ - lngMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); - - /* Mapping of windows events to X events: - * LEFT:1 MIDDLE:2 RIGHT:3 - * SCROLL_UP:4 SCROLL_DOWN:5 - * XBUTTON 1:6 XBUTTON 2:7 ... - * - * To map scroll wheel correctly we need at least the 3 normal buttons - */ - if (lngMouseButtons < 3) - lngMouseButtons = 3; - winMsg(X_PROBED, "%d mouse buttons found\n", lngMouseButtons); - - /* allocate memory: - * number of buttons + 2x mouse wheel event + 1 extra (offset for map) - */ - map = malloc(sizeof(CARD8) * (lngMouseButtons + lngWheelEvents + 1)); - - /* initalize button map */ - map[0] = 0; - for (i=1; i <= lngMouseButtons + lngWheelEvents; i++) - map[i] = i; - - btn_labels = calloc((lngMouseButtons + lngWheelEvents), sizeof(Atom)); - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - - InitPointerDeviceStruct (pDevice, - map, - lngMouseButtons + lngWheelEvents, - btn_labels, - winMouseCtrl, - GetMotionHistorySize(), - 2, - axes_labels); - free(map); - free(btn_labels); - -#if defined(XFree86Server) - g_winMouseButtonMap = pDeviceInt->button->map; -#endif - break; - - case DEVICE_ON: - pDevice->on = TRUE; - break; - - case DEVICE_CLOSE: -#if defined(XFree86Server) - g_winMouseButtonMap = NULL; -#endif - case DEVICE_OFF: - pDevice->on = FALSE; - break; - } - return Success; -} - - -/* Handle the mouse wheel */ -int -winMouseWheel (ScreenPtr pScreen, int iDeltaZ) -{ - winScreenPriv(pScreen); - int button; /* Button4 or Button5 */ - - /* Button4 = WheelUp */ - /* Button5 = WheelDown */ - - /* Do we have any previous delta stored? */ - if ((pScreenPriv->iDeltaZ > 0 - && iDeltaZ > 0) - || (pScreenPriv->iDeltaZ < 0 - && iDeltaZ < 0)) - { - /* Previous delta and of same sign as current delta */ - iDeltaZ += pScreenPriv->iDeltaZ; - pScreenPriv->iDeltaZ = 0; - } - else - { - /* - * Previous delta of different sign, or zero. - * We will set it to zero for either case, - * as blindly setting takes just as much time - * as checking, then setting if necessary :) - */ - pScreenPriv->iDeltaZ = 0; - } - - /* - * Only process this message if the wheel has moved further than - * WHEEL_DELTA - */ - if (iDeltaZ >= WHEEL_DELTA || (-1 * iDeltaZ) >= WHEEL_DELTA) - { - pScreenPriv->iDeltaZ = 0; - - /* Figure out how many whole deltas of the wheel we have */ - iDeltaZ /= WHEEL_DELTA; - } - else - { - /* - * Wheel has not moved past WHEEL_DELTA threshold; - * we will store the wheel delta until the threshold - * has been reached. - */ - pScreenPriv->iDeltaZ = iDeltaZ; - return 0; - } - - /* Set the button to indicate up or down wheel delta */ - if (iDeltaZ > 0) - { - button = Button4; - } - else - { - button = Button5; - } - - /* - * Flip iDeltaZ to positive, if negative, - * because always need to generate a *positive* number of - * button clicks for the Z axis. - */ - if (iDeltaZ < 0) - { - iDeltaZ *= -1; - } - - /* Generate X input messages for each wheel delta we have seen */ - while (iDeltaZ--) - { - /* Push the wheel button */ - winMouseButtonsSendEvent (ButtonPress, button); - - /* Release the wheel button */ - winMouseButtonsSendEvent (ButtonRelease, button); - } - - return 0; -} - - -/* - * Enqueue a mouse button event - */ - -void -winMouseButtonsSendEvent (int iEventType, int iButton) -{ - EventListPtr events; - int i, nevents; - -#if defined(XFree86Server) - if (g_winMouseButtonMap) - iButton = g_winMouseButtonMap[iButton]; -#endif - - GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton, - POINTER_RELATIVE, 0, 0, NULL); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, events[i].event); - -#if CYGDEBUG - ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n", - iEventType, iButton, nevents); -#endif -} - - -/* - * Decide what to do with a Windows mouse message - */ - -int -winMouseButtonsHandle (ScreenPtr pScreen, - int iEventType, int iButton, - WPARAM wParam) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Send button events right away if emulate 3 buttons is off */ - if (pScreenInfo->iE3BTimeout == WIN_E3B_OFF) - { - /* Emulate 3 buttons is off, send the button event */ - winMouseButtonsSendEvent (iEventType, iButton); - return 0; - } - - /* Emulate 3 buttons is on, let the fun begin */ - if (iEventType == ButtonPress - && pScreenPriv->iE3BCachedPress == 0 - && !pScreenPriv->fE3BFakeButton2Sent) - { - /* - * Button was pressed, no press is cached, - * and there is no fake button 2 release pending. - */ - - /* Store button press type */ - pScreenPriv->iE3BCachedPress = iButton; - - /* - * Set a timer to send this button press if the other button - * is not pressed within the timeout time. - */ - SetTimer (pScreenPriv->hwndScreen, - WIN_E3B_TIMER_ID, - pScreenInfo->iE3BTimeout, - NULL); - } - else if (iEventType == ButtonPress - && pScreenPriv->iE3BCachedPress != 0 - && pScreenPriv->iE3BCachedPress != iButton - && !pScreenPriv->fE3BFakeButton2Sent) - { - /* - * Button press is cached, other button was pressed, - * and there is no fake button 2 release pending. - */ - - /* Mouse button was cached and other button was pressed */ - KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); - pScreenPriv->iE3BCachedPress = 0; - - /* Send fake middle button */ - winMouseButtonsSendEvent (ButtonPress, Button2); - - /* Indicate that a fake middle button event was sent */ - pScreenPriv->fE3BFakeButton2Sent = TRUE; - } - else if (iEventType == ButtonRelease - && pScreenPriv->iE3BCachedPress == iButton) - { - /* - * Cached button was released before timer ran out, - * and before the other mouse button was pressed. - */ - KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); - pScreenPriv->iE3BCachedPress = 0; - - /* Send cached press, then send release */ - winMouseButtonsSendEvent (ButtonPress, iButton); - winMouseButtonsSendEvent (ButtonRelease, iButton); - } - else if (iEventType == ButtonRelease - && pScreenPriv->fE3BFakeButton2Sent - && !(wParam & MK_LBUTTON) - && !(wParam & MK_RBUTTON)) - { - /* - * Fake button 2 was sent and both mouse buttons have now been released - */ - pScreenPriv->fE3BFakeButton2Sent = FALSE; - - /* Send middle mouse button release */ - winMouseButtonsSendEvent (ButtonRelease, Button2); - } - else if (iEventType == ButtonRelease - && pScreenPriv->iE3BCachedPress == 0 - && !pScreenPriv->fE3BFakeButton2Sent) - { - /* - * Button was release, no button is cached, - * and there is no fake button 2 release is pending. - */ - winMouseButtonsSendEvent (ButtonRelease, iButton); - } - - return 0; -} - -/** - * Enqueue a motion event. - * - * XXX: miPointerMove does exactly this, but is static :-( (and uses a static buffer) - * - */ -void winEnqueueMotion(int x, int y) -{ - int i, nevents; - int valuators[2]; - EventListPtr events; - - miPointerSetPosition(g_pwinPointer, &x, &y); - valuators[0] = x; - valuators[1] = y; - - GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0, - POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, events[i].event); -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + +#include "inputstr.h" +#include "exevents.h" /* for button/axes labels */ +#include "xserver-properties.h" + +/* Peek the internal button mapping */ +static CARD8 const *g_winMouseButtonMap = NULL; + + +/* + * Local prototypes + */ + +static void +winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl); + + +static void +winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl) +{ +} + + +/* + * See Porting Layer Definition - p. 18 + * This is known as a DeviceProc + */ + +int +winMouseProc (DeviceIntPtr pDeviceInt, int iState) +{ + int lngMouseButtons, i; + int lngWheelEvents = 2; + CARD8 *map; + DevicePtr pDevice = (DevicePtr) pDeviceInt; + Atom *btn_labels; + Atom axes_labels[2]; + + switch (iState) + { + case DEVICE_INIT: + /* Get number of mouse buttons */ + lngMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); + + /* Mapping of windows events to X events: + * LEFT:1 MIDDLE:2 RIGHT:3 + * SCROLL_UP:4 SCROLL_DOWN:5 + * XBUTTON 1:6 XBUTTON 2:7 ... + * + * To map scroll wheel correctly we need at least the 3 normal buttons + */ + if (lngMouseButtons < 3) + lngMouseButtons = 3; + winMsg(X_PROBED, "%d mouse buttons found\n", lngMouseButtons); + + /* allocate memory: + * number of buttons + 2x mouse wheel event + 1 extra (offset for map) + */ + map = malloc(sizeof(CARD8) * (lngMouseButtons + lngWheelEvents + 1)); + + /* initalize button map */ + map[0] = 0; + for (i=1; i <= lngMouseButtons + lngWheelEvents; i++) + map[i] = i; + + btn_labels = calloc((lngMouseButtons + lngWheelEvents), sizeof(Atom)); + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + + InitPointerDeviceStruct (pDevice, + map, + lngMouseButtons + lngWheelEvents, + btn_labels, + winMouseCtrl, + GetMotionHistorySize(), + 2, + axes_labels); + free(map); + free(btn_labels); + + g_winMouseButtonMap = pDeviceInt->button->map; + break; + + case DEVICE_ON: + pDevice->on = TRUE; + break; + + case DEVICE_CLOSE: + g_winMouseButtonMap = NULL; + + case DEVICE_OFF: + pDevice->on = FALSE; + break; + } + return Success; +} + + +/* Handle the mouse wheel */ +int +winMouseWheel (ScreenPtr pScreen, int iDeltaZ) +{ + winScreenPriv(pScreen); + int button; /* Button4 or Button5 */ + + /* Button4 = WheelUp */ + /* Button5 = WheelDown */ + + /* Do we have any previous delta stored? */ + if ((pScreenPriv->iDeltaZ > 0 + && iDeltaZ > 0) + || (pScreenPriv->iDeltaZ < 0 + && iDeltaZ < 0)) + { + /* Previous delta and of same sign as current delta */ + iDeltaZ += pScreenPriv->iDeltaZ; + pScreenPriv->iDeltaZ = 0; + } + else + { + /* + * Previous delta of different sign, or zero. + * We will set it to zero for either case, + * as blindly setting takes just as much time + * as checking, then setting if necessary :) + */ + pScreenPriv->iDeltaZ = 0; + } + + /* + * Only process this message if the wheel has moved further than + * WHEEL_DELTA + */ + if (iDeltaZ >= WHEEL_DELTA || (-1 * iDeltaZ) >= WHEEL_DELTA) + { + pScreenPriv->iDeltaZ = 0; + + /* Figure out how many whole deltas of the wheel we have */ + iDeltaZ /= WHEEL_DELTA; + } + else + { + /* + * Wheel has not moved past WHEEL_DELTA threshold; + * we will store the wheel delta until the threshold + * has been reached. + */ + pScreenPriv->iDeltaZ = iDeltaZ; + return 0; + } + + /* Set the button to indicate up or down wheel delta */ + if (iDeltaZ > 0) + { + button = Button4; + } + else + { + button = Button5; + } + + /* + * Flip iDeltaZ to positive, if negative, + * because always need to generate a *positive* number of + * button clicks for the Z axis. + */ + if (iDeltaZ < 0) + { + iDeltaZ *= -1; + } + + /* Generate X input messages for each wheel delta we have seen */ + while (iDeltaZ--) + { + /* Push the wheel button */ + winMouseButtonsSendEvent (ButtonPress, button); + + /* Release the wheel button */ + winMouseButtonsSendEvent (ButtonRelease, button); + } + + return 0; +} + + +/* + * Enqueue a mouse button event + */ + +void +winMouseButtonsSendEvent (int iEventType, int iButton) +{ + EventListPtr events; + int i, nevents; + + if (g_winMouseButtonMap) + iButton = g_winMouseButtonMap[iButton]; + + GetEventList(&events); + nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton, + POINTER_RELATIVE, 0, 0, NULL); + + for (i = 0; i < nevents; i++) + mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event); + +#if CYGDEBUG + ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n", + iEventType, iButton, nevents); +#endif +} + + +/* + * Decide what to do with a Windows mouse message + */ + +int +winMouseButtonsHandle (ScreenPtr pScreen, + int iEventType, int iButton, + WPARAM wParam) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Send button events right away if emulate 3 buttons is off */ + if (pScreenInfo->iE3BTimeout == WIN_E3B_OFF) + { + /* Emulate 3 buttons is off, send the button event */ + winMouseButtonsSendEvent (iEventType, iButton); + return 0; + } + + /* Emulate 3 buttons is on, let the fun begin */ + if (iEventType == ButtonPress + && pScreenPriv->iE3BCachedPress == 0 + && !pScreenPriv->fE3BFakeButton2Sent) + { + /* + * Button was pressed, no press is cached, + * and there is no fake button 2 release pending. + */ + + /* Store button press type */ + pScreenPriv->iE3BCachedPress = iButton; + + /* + * Set a timer to send this button press if the other button + * is not pressed within the timeout time. + */ + SetTimer (pScreenPriv->hwndScreen, + WIN_E3B_TIMER_ID, + pScreenInfo->iE3BTimeout, + NULL); + } + else if (iEventType == ButtonPress + && pScreenPriv->iE3BCachedPress != 0 + && pScreenPriv->iE3BCachedPress != iButton + && !pScreenPriv->fE3BFakeButton2Sent) + { + /* + * Button press is cached, other button was pressed, + * and there is no fake button 2 release pending. + */ + + /* Mouse button was cached and other button was pressed */ + KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); + pScreenPriv->iE3BCachedPress = 0; + + /* Send fake middle button */ + winMouseButtonsSendEvent (ButtonPress, Button2); + + /* Indicate that a fake middle button event was sent */ + pScreenPriv->fE3BFakeButton2Sent = TRUE; + } + else if (iEventType == ButtonRelease + && pScreenPriv->iE3BCachedPress == iButton) + { + /* + * Cached button was released before timer ran out, + * and before the other mouse button was pressed. + */ + KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); + pScreenPriv->iE3BCachedPress = 0; + + /* Send cached press, then send release */ + winMouseButtonsSendEvent (ButtonPress, iButton); + winMouseButtonsSendEvent (ButtonRelease, iButton); + } + else if (iEventType == ButtonRelease + && pScreenPriv->fE3BFakeButton2Sent + && !(wParam & MK_LBUTTON) + && !(wParam & MK_RBUTTON)) + { + /* + * Fake button 2 was sent and both mouse buttons have now been released + */ + pScreenPriv->fE3BFakeButton2Sent = FALSE; + + /* Send middle mouse button release */ + winMouseButtonsSendEvent (ButtonRelease, Button2); + } + else if (iEventType == ButtonRelease + && pScreenPriv->iE3BCachedPress == 0 + && !pScreenPriv->fE3BFakeButton2Sent) + { + /* + * Button was release, no button is cached, + * and there is no fake button 2 release is pending. + */ + winMouseButtonsSendEvent (ButtonRelease, iButton); + } + + return 0; +} + +/** + * Enqueue a motion event. + * + * XXX: miPointerMove does exactly this, but is static :-( (and uses a static buffer) + * + */ +void winEnqueueMotion(int x, int y) +{ + int i, nevents; + int valuators[2]; + EventListPtr events; + + miPointerSetPosition(g_pwinPointer, &x, &y); + valuators[0] = x; + valuators[1] = y; + + GetEventList(&events); + nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators); + + for (i = 0; i < nevents; i++) + mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event); +} diff --git a/xorg-server/hw/xwin/winmultiwindowicons.c b/xorg-server/hw/xwin/winmultiwindowicons.c index cb27d2fe3..6af9636ea 100644 --- a/xorg-server/hw/xwin/winmultiwindowicons.c +++ b/xorg-server/hw/xwin/winmultiwindowicons.c @@ -1,649 +1,642 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Earle F. Philhower, III - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include "dixevents.h" -#include "winmultiwindowclass.h" -#include "winprefs.h" - -#include "propertyst.h" - -#include "propertyst.h" -#include "windowstr.h" - -/* - * External global variables - */ - -extern HICON g_hIconX; -extern HICON g_hSmallIconX; - - -/* - * Prototypes for local functions - */ - -static void -winScaleXBitmapToWindows (int iconSize, int effBPP, - PixmapPtr pixmap, unsigned char *image); - - -/* - * Scale an X icon bitmap into a Windoze icon bitmap - */ - -static void -winScaleXBitmapToWindows (int iconSize, - int effBPP, - PixmapPtr pixmap, - unsigned char *image) -{ - int row, column, effXBPP, effXDepth; - unsigned char *outPtr; - char *iconData = 0; - int stride, xStride; - float factX, factY; - int posX, posY; - unsigned char *ptr; - unsigned int zero; - unsigned int color; - - effXBPP = BitsPerPixel(pixmap->drawable.depth); - effXDepth = pixmap->drawable.depth; - - if (pixmap->drawable.bitsPerPixel == 15) - effXBPP = 16; - - if (pixmap->drawable.depth == 15) - effXDepth = 16; - - /* Need 16-bit aligned rows for DDBitmaps */ - stride = ((iconSize * effBPP + 15) & (~15)) / 8; - xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth); - if (stride == 0 || xStride == 0) - { - ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. " - "Bailing.\n"); - return; - } - - /* Allocate memory for icon data */ - iconData = malloc (xStride * pixmap->drawable.height); - if (!iconData) - { - ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. " - "Bailing.\n"); - return; - } - - /* Get icon data */ - miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0, - pixmap->drawable.width, pixmap->drawable.height, - ZPixmap, 0xffffffff, iconData); - - /* Keep aspect ratio */ - factX = ((float)pixmap->drawable.width) / ((float)iconSize); - factY = ((float)pixmap->drawable.height) / ((float)iconSize); - if (factX > factY) - factY = factX; - else - factX = factY; - - /* Out-of-bounds, fill icon with zero */ - zero = 0; - - for (row = 0; row < iconSize; row++) - { - outPtr = image + stride * row; - for (column = 0; column < iconSize; column++) - { - posX = factX * column; - posY = factY * row; - - ptr = (unsigned char*) iconData + posY*xStride; - if (effXBPP == 1) - { - ptr += posX / 8; - - /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) - ptr = (unsigned char *) &zero; - - if ((*ptr) & (1 << (posX & 7))) - switch (effBPP) - { - case 32: - *(outPtr++) = 0; - case 24: - *(outPtr++) = 0; - case 16: - *(outPtr++) = 0; - case 8: - *(outPtr++) = 0; - break; - case 1: - outPtr[column / 8] &= ~(1 << (7 - (column & 7))); - break; - } - else - switch (effBPP) - { - case 32: - *(outPtr++) = 255; - *(outPtr++) = 255; - *(outPtr++) = 255; - *(outPtr++) = 0; - break; - case 24: - *(outPtr++) = 255; - case 16: - *(outPtr++) = 255; - case 8: - *(outPtr++) = 255; - break; - case 1: - outPtr[column / 8] |= (1 << (7 - (column & 7))); - break; - } - } - else if (effXDepth == 24 || effXDepth == 32) - { - ptr += posX * (effXBPP / 8); - - /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) - ptr = (unsigned char *) &zero; - color = (((*ptr) << 16) - + ((*(ptr + 1)) << 8) - + ((*(ptr + 2)) << 0)); - switch (effBPP) - { - case 32: - *(outPtr++) = *(ptr++); /* b */ - *(outPtr++) = *(ptr++); /* g */ - *(outPtr++) = *(ptr++); /* r */ - *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */ - break; - case 24: - *(outPtr++) = *(ptr++); - *(outPtr++) = *(ptr++); - *(outPtr++) = *(ptr++); - break; - case 16: - color = ((((*ptr) >> 2) << 10) - + (((*(ptr + 1)) >> 2) << 5) - + (((*(ptr + 2)) >> 2))); - *(outPtr++) = (color >> 8); - *(outPtr++) = (color & 255); - break; - case 8: - color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2)))); - color /= 3; - *(outPtr++) = color; - break; - case 1: - if (color) - outPtr[column / 8] |= (1 << (7 - (column & 7))); - else - outPtr[column / 8] &= ~(1 << (7 - (column & 7))); - } - } - else if (effXDepth == 16) - { - ptr += posX * (effXBPP / 8); - - /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) - ptr = (unsigned char *) &zero; - color = ((*ptr) << 8) + (*(ptr + 1)); - switch (effBPP) - { - case 32: - *(outPtr++) = (color & 31) << 2; - *(outPtr++) = ((color >> 5) & 31) << 2; - *(outPtr++) = ((color >> 10) & 31) << 2; - *(outPtr++) = 0; /* resvd */ - break; - case 24: - *(outPtr++) = (color & 31) << 2; - *(outPtr++) = ((color >> 5) & 31) << 2; - *(outPtr++) = ((color >> 10) & 31) << 2; - break; - case 16: - *(outPtr++) = *(ptr++); - *(outPtr++) = *(ptr++); - break; - case 8: - *(outPtr++) = (((color & 31) - + ((color >> 5) & 31) - + ((color >> 10) & 31)) / 3) << 2; - break; - case 1: - if (color) - outPtr[column / 8] |= (1 << (7 - (column & 7))); - else - outPtr[column / 8] &= ~(1 << (7 - (column & 7))); - break; - } /* end switch(effbpp) */ - } /* end if effxbpp==16) */ - } /* end for column */ - } /* end for row */ - free (iconData); -} - -static HICON -NetWMToWinIconAlpha(uint32_t *icon) -{ - int width = icon[0]; - int height = icon[1]; - uint32_t *pixels = &icon[2]; - HICON result; - HDC hdc = GetDC(NULL); - uint32_t *DIB_pixels; - ICONINFO ii = {TRUE}; - BITMAPV4HEADER bmh = {sizeof(bmh)}; - - /* Define an ARGB pixel format used for Color+Alpha icons */ - bmh.bV4Width = width; - bmh.bV4Height = -height; /* Invert the image */ - bmh.bV4Planes = 1; - bmh.bV4BitCount = 32; - bmh.bV4V4Compression = BI_BITFIELDS; - bmh.bV4AlphaMask = 0xFF000000; - bmh.bV4RedMask = 0x00FF0000; - bmh.bV4GreenMask = 0x0000FF00; - bmh.bV4BlueMask = 0x000000FF; - - ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, - DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0); - ReleaseDC(NULL, hdc); - ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL); - memcpy(DIB_pixels, pixels, height*width*4); - - /* CreateIconIndirect() traditionally required DDBitmaps */ - /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */ - /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */ - result = CreateIconIndirect(&ii); - - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask); - - winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result); - return result; -} - -static HICON -NetWMToWinIconThreshold(uint32_t *icon) -{ - int width = icon[0]; - int height = icon[1]; - uint32_t *pixels = &icon[2]; - int row, col; - HICON result; - ICONINFO ii = {TRUE}; - - HDC hdc = GetDC(NULL); - HDC xorDC = CreateCompatibleDC(hdc); - HDC andDC = CreateCompatibleDC(hdc); - ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); - ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); - ReleaseDC(NULL, hdc); - SelectObject(xorDC, ii.hbmColor); - SelectObject(andDC, ii.hbmMask); - - for (row = 0; row < height; row++) { - for (col = 0; col < width; col++) { - if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */ - SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1], - ((char*)pixels)[0])); - SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */ - } - else { - SetPixelV(xorDC, col, row, RGB(0, 0, 0)); - SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */ - } - pixels++; - } - } - DeleteDC(xorDC); - DeleteDC(andDC); - - result = CreateIconIndirect(&ii); - - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask ); - - winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result); - return result; -} - -static HICON -NetWMToWinIcon(int bpp, uint32_t *icon) -{ - static Bool hasIconAlphaChannel = FALSE; - static BOOL versionChecked = FALSE; - - if (!versionChecked) - { - OSVERSIONINFOEX osvi = {0}; - ULONGLONG dwlConditionMask = 0; - - osvi.dwOSVersionInfoSize = sizeof (osvi); - osvi.dwMajorVersion = 5; - osvi.dwMinorVersion = 1; - - /* Windows versions later than XP have icon alpha channel suport, 2000 does not */ - VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); - hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); - versionChecked = TRUE; - - ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no"); - } - - if (hasIconAlphaChannel && (bpp==32)) - return NetWMToWinIconAlpha(icon); - else - return NetWMToWinIconThreshold(icon); -} - -static pointer -GetWindowProp(WindowPtr pWin, Atom name, long int *size_return) -{ - struct _Window *pwin; - struct _Property *prop; - - if (!pWin || !name) { - ErrorF ("GetWindowProp - pWin or name was NULL\n"); - return 0; - } - pwin = (struct _Window*) pWin; - if (!pwin->optional) return NULL; - for (prop = (struct _Property *) pwin->optional->userProps; - prop; - prop=prop->next){ - if (prop->propertyName == name) { - *size_return=prop->size; - return prop->data; - } - } - return NULL; -} - -/* - * Attempt to create a custom icon from the WM_HINTS bitmaps - */ - -HICON -winXIconToHICON (WindowPtr pWin, int iconSize) -{ - unsigned char *mask, *image, *imageMask; - unsigned char *dst, *src; - PixmapPtr iconPtr; - PixmapPtr maskPtr; - int planes, bpp, effBPP, stride, maskStride, i; - int biggest_size = 0; - HDC hDC; - ICONINFO ii; - WinXWMHints hints; - HICON hIcon = NULL; - uint32_t *biggest_icon = NULL; - - /* Try to get _NET_WM_ICON icons first */ - static Atom _XA_NET_WM_ICON; - static int generation; - uint32_t *icon, *icon_data = NULL; - long int size=0; - - hDC = GetDC (GetDesktopWindow ()); - planes = GetDeviceCaps (hDC, PLANES); - bpp = GetDeviceCaps (hDC, BITSPIXEL); - ReleaseDC (GetDesktopWindow (), hDC); - - if (generation != serverGeneration) { - generation = serverGeneration; - _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE); - } - - if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); - if (icon_data) - { - for(icon = icon_data; - icon < &icon_data[size] && *icon; - icon = &icon[icon[0]*icon[1]+2]) - { - if (icon[0]==iconSize && icon[1]==iconSize) - return NetWMToWinIcon(bpp, icon); - /* Find the biggest icon and let Windows scale the size */ - else if (biggest_size < icon[0]) - { - biggest_icon = icon; - biggest_size = icon[0]; - } - } - if (biggest_icon) - return NetWMToWinIcon(bpp, biggest_icon); - } - winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize); - - winMultiWindowGetWMHints (pWin, &hints); - if (!hints.icon_pixmap) return NULL; - - dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, - NullClient, DixUnknownAccess); - - if (!iconPtr) return NULL; - - /* 15 BPP is really 16BPP as far as we care */ - if (bpp == 15) - effBPP = 16; - else - effBPP = bpp; - - /* Need 16-bit aligned rows for DDBitmaps */ - stride = ((iconSize * effBPP + 15) & (~15)) / 8; - - /* Mask is 1-bit deep */ - maskStride = ((iconSize * 1 + 15) & (~15)) / 8; - - image = malloc (stride * iconSize); - imageMask = malloc (stride * iconSize); - /* Default to a completely black mask */ - mask = calloc (maskStride, iconSize); - - winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); - dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP, - NullClient, DixUnknownAccess); - - if (maskPtr) - { - winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask); - - winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask); - - /* Now we need to set all bits of the icon which are not masked */ - /* on to 0 because Color is really an XOR, not an OR function */ - dst = image; - src = imageMask; - - for (i = 0; i < (stride * iconSize); i++) - if ((*(src++))) - *(dst++) = 0; - else - dst++; - } - - ii.fIcon = TRUE; - ii.xHotspot = 0; /* ignored */ - ii.yHotspot = 0; /* ignored */ - - /* Create Win32 mask from pixmap shape */ - ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask); - - /* Create Win32 bitmap from pixmap */ - ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image); - - /* Merge Win32 mask and bitmap into icon */ - hIcon = CreateIconIndirect (&ii); - - /* Release Win32 mask and bitmap */ - DeleteObject (ii.hbmMask); - DeleteObject (ii.hbmColor); - - /* Free X mask and bitmap */ - free (mask); - free (image); - free (imageMask); - - return hIcon; -} - - - -/* - * Change the Windows window icon - */ - -#ifdef XWIN_MULTIWINDOW -void -winUpdateIcon (Window id) -{ - WindowPtr pWin; - HICON hIcon, hIconSmall=NULL, hIconOld; - - dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); - if (pWin) - { - winWindowPriv(pWin); - if (pWinPriv->hWnd) { - hIcon = winOverrideIcon ((unsigned long)pWin); - if (!hIcon) { - hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); - if (!hIcon) { - hIcon = g_hIconX; - hIconSmall = g_hSmallIconX; - } else { - /* Leave undefined if not found */ - hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); - } - } - - /* Set the large icon */ - hIconOld = (HICON) SendMessage (pWinPriv->hWnd, - WM_SETICON, ICON_BIG, (LPARAM) hIcon); - - /* Delete the icon if its not the default */ - winDestroyIcon(hIconOld); - - /* Same for the small icon */ - hIconOld = (HICON) SendMessage (pWinPriv->hWnd, - WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); - winDestroyIcon(hIconOld); - } - } -} - -void winInitGlobalIcons (void) -{ - int sm_cx = GetSystemMetrics(SM_CXICON); - int sm_cxsm = GetSystemMetrics(SM_CXSMICON); - /* Load default X icon in case it's not ready yet */ - if (!g_hIconX) - { - g_hIconX = winOverrideDefaultIcon(sm_cx); - g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm); - } - - if (!g_hIconX) - { - g_hIconX = (HICON)LoadImage (g_hInstance, - MAKEINTRESOURCE(IDI_XWIN), - IMAGE_ICON, - GetSystemMetrics(SM_CXICON), - GetSystemMetrics(SM_CYICON), - 0); - g_hSmallIconX = (HICON)LoadImage (g_hInstance, - MAKEINTRESOURCE(IDI_XWIN), - IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - LR_DEFAULTSIZE); - } -} - -void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) -{ - HICON hIcon, hSmallIcon; - - winInitGlobalIcons(); - - /* Try and get the icon from WM_HINTS */ - hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); - hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); - - /* If we got the small, but not the large one swap them */ - if (!hIcon && hSmallIcon) - { - hIcon = hSmallIcon; - hSmallIcon = NULL; - } - - /* Use default X icon if no icon loaded from WM_HINTS */ - if (!hIcon) { - hIcon = g_hIconX; - hSmallIcon = g_hSmallIconX; - } - - if (pIcon) - *pIcon = hIcon; - else - winDestroyIcon(hIcon); - if (pSmallIcon) - *pSmallIcon = hSmallIcon; - else - winDestroyIcon(hSmallIcon); -} - -void winDestroyIcon(HICON hIcon) -{ - /* Delete the icon if its not the default */ - if (hIcon && - hIcon != g_hIconX && - hIcon != g_hSmallIconX && - !winIconIsOverride((unsigned long)hIcon)) - DestroyIcon (hIcon); -} -#endif +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + +#include "propertyst.h" + +#include "propertyst.h" +#include "windowstr.h" + + +/* + * Prototypes for local functions + */ + +static void +winScaleXBitmapToWindows (int iconSize, int effBPP, + PixmapPtr pixmap, unsigned char *image); + + +/* + * Scale an X icon bitmap into a Windoze icon bitmap + */ + +static void +winScaleXBitmapToWindows (int iconSize, + int effBPP, + PixmapPtr pixmap, + unsigned char *image) +{ + int row, column, effXBPP, effXDepth; + unsigned char *outPtr; + char *iconData = 0; + int stride, xStride; + float factX, factY; + int posX, posY; + unsigned char *ptr; + unsigned int zero; + unsigned int color; + + effXBPP = BitsPerPixel(pixmap->drawable.depth); + effXDepth = pixmap->drawable.depth; + + if (pixmap->drawable.bitsPerPixel == 15) + effXBPP = 16; + + if (pixmap->drawable.depth == 15) + effXDepth = 16; + + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; + xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth); + if (stride == 0 || xStride == 0) + { + ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. " + "Bailing.\n"); + return; + } + + /* Allocate memory for icon data */ + iconData = malloc (xStride * pixmap->drawable.height); + if (!iconData) + { + ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. " + "Bailing.\n"); + return; + } + + /* Get icon data */ + miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0, + pixmap->drawable.width, pixmap->drawable.height, + ZPixmap, 0xffffffff, iconData); + + /* Keep aspect ratio */ + factX = ((float)pixmap->drawable.width) / ((float)iconSize); + factY = ((float)pixmap->drawable.height) / ((float)iconSize); + if (factX > factY) + factY = factX; + else + factX = factY; + + /* Out-of-bounds, fill icon with zero */ + zero = 0; + + for (row = 0; row < iconSize; row++) + { + outPtr = image + stride * row; + for (column = 0; column < iconSize; column++) + { + posX = factX * column; + posY = factY * row; + + ptr = (unsigned char*) iconData + posY*xStride; + if (effXBPP == 1) + { + ptr += posX / 8; + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + + if ((*ptr) & (1 << (posX & 7))) + switch (effBPP) + { + case 32: + *(outPtr++) = 0; + case 24: + *(outPtr++) = 0; + case 16: + *(outPtr++) = 0; + case 8: + *(outPtr++) = 0; + break; + case 1: + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } + else + switch (effBPP) + { + case 32: + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 0; + break; + case 24: + *(outPtr++) = 255; + case 16: + *(outPtr++) = 255; + case 8: + *(outPtr++) = 255; + break; + case 1: + outPtr[column / 8] |= (1 << (7 - (column & 7))); + break; + } + } + else if (effXDepth == 24 || effXDepth == 32) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = (((*ptr) << 16) + + ((*(ptr + 1)) << 8) + + ((*(ptr + 2)) << 0)); + switch (effBPP) + { + case 32: + *(outPtr++) = *(ptr++); /* b */ + *(outPtr++) = *(ptr++); /* g */ + *(outPtr++) = *(ptr++); /* r */ + *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */ + break; + case 24: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 16: + color = ((((*ptr) >> 2) << 10) + + (((*(ptr + 1)) >> 2) << 5) + + (((*(ptr + 2)) >> 2))); + *(outPtr++) = (color >> 8); + *(outPtr++) = (color & 255); + break; + case 8: + color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2)))); + color /= 3; + *(outPtr++) = color; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + } + } + else if (effXDepth == 16) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = ((*ptr) << 8) + (*(ptr + 1)); + switch (effBPP) + { + case 32: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + *(outPtr++) = 0; /* resvd */ + break; + case 24: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + break; + case 16: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 8: + *(outPtr++) = (((color & 31) + + ((color >> 5) & 31) + + ((color >> 10) & 31)) / 3) << 2; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } /* end switch(effbpp) */ + } /* end if effxbpp==16) */ + } /* end for column */ + } /* end for row */ + free (iconData); +} + +static HICON +NetWMToWinIconAlpha(uint32_t *icon) +{ + int width = icon[0]; + int height = icon[1]; + uint32_t *pixels = &icon[2]; + HICON result; + HDC hdc = GetDC(NULL); + uint32_t *DIB_pixels; + ICONINFO ii = {TRUE}; + BITMAPV4HEADER bmh = {sizeof(bmh)}; + + /* Define an ARGB pixel format used for Color+Alpha icons */ + bmh.bV4Width = width; + bmh.bV4Height = -height; /* Invert the image */ + bmh.bV4Planes = 1; + bmh.bV4BitCount = 32; + bmh.bV4V4Compression = BI_BITFIELDS; + bmh.bV4AlphaMask = 0xFF000000; + bmh.bV4RedMask = 0x00FF0000; + bmh.bV4GreenMask = 0x0000FF00; + bmh.bV4BlueMask = 0x000000FF; + + ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, + DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0); + ReleaseDC(NULL, hdc); + ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL); + memcpy(DIB_pixels, pixels, height*width*4); + + /* CreateIconIndirect() traditionally required DDBitmaps */ + /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */ + /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */ + result = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask); + + winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result); + return result; +} + +static HICON +NetWMToWinIconThreshold(uint32_t *icon) +{ + int width = icon[0]; + int height = icon[1]; + uint32_t *pixels = &icon[2]; + int row, col; + HICON result; + ICONINFO ii = {TRUE}; + + HDC hdc = GetDC(NULL); + HDC xorDC = CreateCompatibleDC(hdc); + HDC andDC = CreateCompatibleDC(hdc); + ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); + ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); + ReleaseDC(NULL, hdc); + SelectObject(xorDC, ii.hbmColor); + SelectObject(andDC, ii.hbmMask); + + for (row = 0; row < height; row++) { + for (col = 0; col < width; col++) { + if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */ + SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1], + ((char*)pixels)[0])); + SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */ + } + else { + SetPixelV(xorDC, col, row, RGB(0, 0, 0)); + SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */ + } + pixels++; + } + } + DeleteDC(xorDC); + DeleteDC(andDC); + + result = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask ); + + winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result); + return result; +} + +static HICON +NetWMToWinIcon(int bpp, uint32_t *icon) +{ + static Bool hasIconAlphaChannel = FALSE; + static BOOL versionChecked = FALSE; + + if (!versionChecked) + { + OSVERSIONINFOEX osvi = {0}; + ULONGLONG dwlConditionMask = 0; + + osvi.dwOSVersionInfoSize = sizeof (osvi); + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 1; + + /* Windows versions later than XP have icon alpha channel suport, 2000 does not */ + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); + versionChecked = TRUE; + + ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no"); + } + + if (hasIconAlphaChannel && (bpp==32)) + return NetWMToWinIconAlpha(icon); + else + return NetWMToWinIconThreshold(icon); +} + +static pointer +GetWindowProp(WindowPtr pWin, Atom name, long int *size_return) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !name) { + ErrorF ("GetWindowProp - pWin or name was NULL\n"); + return 0; + } + pwin = (struct _Window*) pWin; + if (!pwin->optional) return NULL; + for (prop = (struct _Property *) pwin->optional->userProps; + prop; + prop=prop->next){ + if (prop->propertyName == name) { + *size_return=prop->size; + return prop->data; + } + } + return NULL; +} + +/* + * Attempt to create a custom icon from the WM_HINTS bitmaps + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize) +{ + unsigned char *mask, *image, *imageMask; + unsigned char *dst, *src; + PixmapPtr iconPtr; + PixmapPtr maskPtr; + int planes, bpp, effBPP, stride, maskStride, i; + int biggest_size = 0; + HDC hDC; + ICONINFO ii; + WinXWMHints hints; + HICON hIcon = NULL; + uint32_t *biggest_icon = NULL; + + /* Try to get _NET_WM_ICON icons first */ + static Atom _XA_NET_WM_ICON; + static int generation; + uint32_t *icon, *icon_data = NULL; + long int size=0; + + hDC = GetDC (GetDesktopWindow ()); + planes = GetDeviceCaps (hDC, PLANES); + bpp = GetDeviceCaps (hDC, BITSPIXEL); + ReleaseDC (GetDesktopWindow (), hDC); + + if (generation != serverGeneration) { + generation = serverGeneration; + _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE); + } + + if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); + if (icon_data) + { + for(icon = icon_data; + icon < &icon_data[size] && *icon; + icon = &icon[icon[0]*icon[1]+2]) + { + if (icon[0]==iconSize && icon[1]==iconSize) + return NetWMToWinIcon(bpp, icon); + /* Find the biggest icon and let Windows scale the size */ + else if (biggest_size < icon[0]) + { + biggest_icon = icon; + biggest_size = icon[0]; + } + } + if (biggest_icon) + return NetWMToWinIcon(bpp, biggest_icon); + } + winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize); + + winMultiWindowGetWMHints (pWin, &hints); + if (!hints.icon_pixmap) return NULL; + + dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, + NullClient, DixUnknownAccess); + + if (!iconPtr) return NULL; + + /* 15 BPP is really 16BPP as far as we care */ + if (bpp == 15) + effBPP = 16; + else + effBPP = bpp; + + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; + + /* Mask is 1-bit deep */ + maskStride = ((iconSize * 1 + 15) & (~15)) / 8; + + image = malloc (stride * iconSize); + imageMask = malloc (stride * iconSize); + /* Default to a completely black mask */ + mask = calloc (maskStride, iconSize); + + winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); + dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP, + NullClient, DixUnknownAccess); + + if (maskPtr) + { + winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask); + + winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask); + + /* Now we need to set all bits of the icon which are not masked */ + /* on to 0 because Color is really an XOR, not an OR function */ + dst = image; + src = imageMask; + + for (i = 0; i < (stride * iconSize); i++) + if ((*(src++))) + *(dst++) = 0; + else + dst++; + } + + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ + + /* Create Win32 mask from pixmap shape */ + ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask); + + /* Create Win32 bitmap from pixmap */ + ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image); + + /* Merge Win32 mask and bitmap into icon */ + hIcon = CreateIconIndirect (&ii); + + /* Release Win32 mask and bitmap */ + DeleteObject (ii.hbmMask); + DeleteObject (ii.hbmColor); + + /* Free X mask and bitmap */ + free (mask); + free (image); + free (imageMask); + + return hIcon; +} + + + +/* + * Change the Windows window icon + */ + +#ifdef XWIN_MULTIWINDOW +void +winUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hIconSmall=NULL, hIconOld; + + dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); + if (pWin) + { + winWindowPriv(pWin); + if (pWinPriv->hWnd) { + hIcon = winOverrideIcon ((unsigned long)pWin); + if (!hIcon) { + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + if (!hIcon) { + hIcon = g_hIconX; + hIconSmall = g_hSmallIconX; + } else { + /* Leave undefined if not found */ + hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + } + } + + /* Set the large icon */ + hIconOld = (HICON) SendMessage (pWinPriv->hWnd, + WM_SETICON, ICON_BIG, (LPARAM) hIcon); + + /* Delete the icon if its not the default */ + winDestroyIcon(hIconOld); + + /* Same for the small icon */ + hIconOld = (HICON) SendMessage (pWinPriv->hWnd, + WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); + winDestroyIcon(hIconOld); + } + } +} + +void winInitGlobalIcons (void) +{ + int sm_cx = GetSystemMetrics(SM_CXICON); + int sm_cxsm = GetSystemMetrics(SM_CXSMICON); + /* Load default X icon in case it's not ready yet */ + if (!g_hIconX) + { + g_hIconX = winOverrideDefaultIcon(sm_cx); + g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm); + } + + if (!g_hIconX) + { + g_hIconX = (HICON)LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), + 0); + g_hSmallIconX = (HICON)LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTSIZE); + } +} + +void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) +{ + HICON hIcon, hSmallIcon; + + winInitGlobalIcons(); + + /* Try and get the icon from WM_HINTS */ + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + + /* If we got the small, but not the large one swap them */ + if (!hIcon && hSmallIcon) + { + hIcon = hSmallIcon; + hSmallIcon = NULL; + } + + /* Use default X icon if no icon loaded from WM_HINTS */ + if (!hIcon) { + hIcon = g_hIconX; + hSmallIcon = g_hSmallIconX; + } + + if (pIcon) + *pIcon = hIcon; + else + winDestroyIcon(hIcon); + if (pSmallIcon) + *pSmallIcon = hSmallIcon; + else + winDestroyIcon(hSmallIcon); +} + +void winDestroyIcon(HICON hIcon) +{ + /* Delete the icon if its not the default */ + if (hIcon && + hIcon != g_hIconX && + hIcon != g_hSmallIconX && + !winIconIsOverride((unsigned long)hIcon)) + DestroyIcon (hIcon); +} +#endif diff --git a/xorg-server/hw/xwin/winmultiwindowwindow.c b/xorg-server/hw/xwin/winmultiwindowwindow.c index 038f9497f..93434fceb 100644 --- a/xorg-server/hw/xwin/winmultiwindowwindow.c +++ b/xorg-server/hw/xwin/winmultiwindowwindow.c @@ -38,16 +38,6 @@ #include "win.h" #include "dixevents.h" #include "winmultiwindowclass.h" -#include "winprefs.h" - -/* - * External global variables - */ - -extern HICON g_hIconX; -extern HICON g_hSmallIconX; -extern HWND g_hDlgDepthChange; -extern Bool g_fNativeGl; /* * Prototypes for local functions diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c index 0749f5df6..28685a729 100644 --- a/xorg-server/hw/xwin/winmultiwindowwm.c +++ b/xorg-server/hw/xwin/winmultiwindowwm.c @@ -634,7 +634,7 @@ winMultiWindowWMProc (void *pArg) ErrorF ("winMultiWindowWMProc ()\n"); #endif - /* Loop until we explicity break out */ + /* Loop until we explicitly break out */ for (;;) { WMMsgNodePtr pNode; @@ -1553,6 +1553,7 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) int format; unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0; WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP); + MwmHints *mwm_hint = NULL; if (!hWnd) return; if (!IsWindow (hWnd)) return; @@ -1584,7 +1585,6 @@ winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) } nitems = left = 0; - MwmHints *mwm_hint = NULL; if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L, PropMwmHintsElements, False, motif_wm_hints, &type, &format, &nitems, &left, (unsigned char **)&mwm_hint) == Success) diff --git a/xorg-server/hw/xwin/winmultiwindowwndproc.c b/xorg-server/hw/xwin/winmultiwindowwndproc.c index d14ceee9c..10123c63a 100644 --- a/xorg-server/hw/xwin/winmultiwindowwndproc.c +++ b/xorg-server/hw/xwin/winmultiwindowwndproc.c @@ -1,1055 +1,1046 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Kensuke Matsuzaki - * Earle F. Philhower, III - * Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include "dixevents.h" -#include "winmultiwindowclass.h" -#include "winprefs.h" -#include "winmsg.h" -#include "inputstr.h" - -/* - * External global variables - */ - -extern Bool g_fCursor; -extern Bool g_fKeyboardHookLL; -extern Bool g_fSoftwareCursor; -extern Bool g_fButton[3]; - -extern void winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); - - -/* - * Local globals - */ - -static UINT_PTR g_uipMousePollingTimerID = 0; - - -/* - * Constant defines - */ - -#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; - RECT rcClient, rcWindow; - int iBorderWidthX, iBorderWidthY; - - /* 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; - - /* Now remove size of any borders and title bar */ - GetClientRect(hwnd, &rcClient); - GetWindowRect(hwnd, &rcWindow); - iBorderWidthX = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left); - iBorderWidthY = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top); - iWidth -= iBorderWidthX; - iHeight -= iBorderWidthY; - - /* Constrain the size to legal values */ - ConstrainSize (sizeHints, &iWidth, &iHeight); - - /* Add back the size of borders and title bar */ - iWidth += iBorderWidthX; - iHeight += iBorderWidthY; - - /* 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; -} - -extern Bool winInDestroyWindowsWindow; -static Bool winInRaiseWindow = FALSE; -static void winRaiseWindow(WindowPtr pWin) -{ - if (!winInDestroyWindowsWindow && !winInRaiseWindow) - { - BOOL oldstate = winInRaiseWindow; - XID vlist[1] = { 0 }; - winInRaiseWindow = TRUE; - /* Call configure window directly to make sure it gets processed - * in time - */ - ConfigureWindow(pWin, CWStackMode, vlist, serverClient); - winInRaiseWindow = oldstate; - } -} - -static -void winStartMousePolling(winPrivScreenPtr s_pScreenPriv) -{ - /* - * Timer to poll mouse position. This is needed to make - * programs like xeyes follow the mouse properly when the - * mouse pointer is outside of any X window. - */ - if (g_uipMousePollingTimerID == 0) - g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, - WIN_POLLING_MOUSE_TIMER_ID, - MOUSE_POLLING_INTERVAL, - NULL); -} - -/* - * 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; - winWMMessageRec wmMsg; - Bool fWMMsgInitialized = FALSE; - static Bool s_fTracking = FALSE; - Bool needRestack = FALSE; - LRESULT ret; - -#if CYGDEBUG - winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); -#endif - - /* 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 = pDraw->x; - wmMsg.iY = pDraw->y; - wmMsg.iWidth = pDraw->width; - wmMsg.iHeight = pDraw->height; - - 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_iWindowPrivateKey %p\n", g_iWindowPrivateKey); - 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: - - /* */ - SetProp (hwnd, - WIN_WINDOW_PROP, - (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); - - /* */ - SetProp (hwnd, - WIN_WID_PROP, - (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); - - /* - * Make X windows' Z orders sync with Windows windows because - * there can be AlwaysOnTop windows overlapped on the window - * currently being created. - */ - winReorderWindowsMultiWindow (); - - /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */ - { - RECT rWindow; - HRGN hRgnWindow; - GetWindowRect(hwnd, &rWindow); - hRgnWindow = CreateRectRgnIndirect(&rWindow); - SetWindowRgn (hwnd, hRgnWindow, TRUE); - DeleteObject(hRgnWindow); - } - - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE); - - 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 - */ - if (HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam))) - { - /* Don't pass customized menus to DefWindowProc */ - return 0; - } - if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) - { - WINDOWPLACEMENT wndpl; - wndpl.length = sizeof(wndpl); - if (GetWindowPlacement(hwnd, &wndpl) && wndpl.showCmd == SW_SHOWMINIMIZED) - needRestack = TRUE; - } - break; - - case WM_INITMENU: - /* Checks/Unchecks any menu items before they are displayed */ - HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam); - break; - - case WM_ERASEBKGND: - /* - * Pretend that we did erase the background but we don't care, - * since we repaint the entire region anyhow - * This avoids some flickering when resizing. - */ - return TRUE; - - 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); - /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */ - if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0) - { - EndPaint (hwnd, &ps); - return 0; - } - - /* Try to copy from the shadow buffer */ - if (!BitBlt (hdcUpdate, - ps.rcPaint.left, ps.rcPaint.top, - ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, - s_pScreenPriv->hdcShadow, - ps.rcPaint.left + pWin->drawable.x, ps.rcPaint.top + pWin->drawable.y, - 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 (hwnd, &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 != miPointerGetScreen(g_pwinPointer)) - miPointerSetScreen (g_pwinPointer, 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_fSoftwareCursor && 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 */ - winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset, - ptMouse.y - s_pScreenInfo->dwYOffset); - - 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_fSoftwareCursor && !g_fCursor) - { - g_fCursor = TRUE; - ShowCursor (TRUE); - } - - winStartMousePolling(s_pScreenPriv); - - 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_fSoftwareCursor && !g_fCursor) - { - g_fCursor = TRUE; - ShowCursor (TRUE); - } - - winStartMousePolling(s_pScreenPriv); - - return 0; - - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - g_fButton[0] = TRUE; - SetCapture(hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); - - case WM_LBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - g_fButton[0] = FALSE; - ReleaseCapture(); - winStartMousePolling(s_pScreenPriv); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); - - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - g_fButton[1] = TRUE; - SetCapture(hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); - - case WM_MBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - g_fButton[1] = FALSE; - ReleaseCapture(); - winStartMousePolling(s_pScreenPriv); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); - - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - g_fButton[2] = TRUE; - SetCapture(hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); - - case WM_RBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - g_fButton[2] = FALSE; - ReleaseCapture(); - winStartMousePolling(s_pScreenPriv); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); - - case WM_XBUTTONDBLCLK: - case WM_XBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - SetCapture(hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); - - case WM_XBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - ReleaseCapture(); - winStartMousePolling(s_pScreenPriv); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); - - case WM_MOUSEWHEEL: - if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) == HTCLIENT) - { - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - } - else break; - - case WM_SETFOCUS: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - { - /* Get the parent window for transient handling */ - HWND hParent = GetParent(hwnd); - if (hParent && IsIconic(hParent)) ShowWindow (hParent, SW_RESTORE); - } - - winRestoreModeKeyStates (); - - /* Add the keyboard hook if possible */ - if (g_fKeyboardHookLL) - g_fKeyboardHookLL = winInstallKeyboardHookLL (); - return 0; - - case WM_KILLFOCUS: - /* Pop any pressed keys since we are losing keyboard focus */ - winKeybdReleaseKeys (); - - /* Remove our keyboard hook if it is installed */ - winRemoveKeyboardHookLL (); - if (!wParam) - /* Revert the X focus as well, but only if the Windows focus is going to another window */ - DeleteWindowFromAnyEvents(pWin, FALSE); - 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: - - /* - * 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; - -#if CYGWINDOWING_DEBUG - if (wParam == VK_ESCAPE) - { - /* Place for debug: put any tests and dumps here */ - WINDOWPLACEMENT windPlace; - RECT rc; - LPRECT pRect; - - windPlace.length = sizeof (WINDOWPLACEMENT); - GetWindowPlacement (hwnd, &windPlace); - pRect = &windPlace.rcNormalPosition; - ErrorF ("\nCYGWINDOWING Dump:\n" - "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, - pDraw->y, pDraw->width, pDraw->height); - ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, - pRect->top, pRect->right - pRect->left, - pRect->bottom - pRect->top); - if (GetClientRect (hwnd, &rc)) - { - pRect = &rc; - ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, - pRect->top, pRect->right - pRect->left, - pRect->bottom - pRect->top); - } - if (GetWindowRect (hwnd, &rc)) - { - pRect = &rc; - ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, - pRect->top, pRect->right - pRect->left, - pRect->bottom - pRect->top); - } - ErrorF ("\n"); - } -#endif - - /* Pass the message to the root window */ - return winWindowProc(hwndScreen, message, wParam, lParam); - - case WM_SYSKEYUP: - case WM_KEYUP: - - - /* Pass the message to the root window */ - return winWindowProc(hwndScreen, message, wParam, lParam); - - case WM_HOTKEY: - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - case WM_ACTIVATE: - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - - if (LOWORD(wParam) != WA_INACTIVE) - { - /* Raise the window to the top in Z order */ - /* ago: Activate does not mean putting it to front! */ - /* - wmMsg.msg = WM_WM_RAISE; - if (fWMMsgInitialized) - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - */ - - /* Tell our Window Manager thread to activate the window */ - wmMsg.msg = WM_WM_ACTIVATE; - if (fWMMsgInitialized) - if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - } - /* Prevent the mouse wheel from stalling when another window is minimized */ - if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE && - (HWND)lParam != NULL && (HWND)lParam != (HWND)GetParent(hwnd)) - SetFocus(hwnd); - return 0; - - case WM_ACTIVATEAPP: - /* - * This message is also sent to the root window - * so we do nothing for individual multiwindow windows - */ - break; - - case WM_CLOSE: - /* 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: - - /* 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); - } - - RemoveProp (hwnd, WIN_WINDOW_PROP); - RemoveProp (hwnd, WIN_WID_PROP); - RemoveProp (hwnd, WIN_NEEDMANAGE_PROP); - - break; - - case WM_MOVE: - /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); - return 0; - - case WM_SHOWWINDOW: - /* Bail out if the window is being hidden */ - if (!wParam) - return 0; - - /* */ - if (!pWin->overrideRedirect) - { - /* Flag that this window needs to be made active when clicked */ - SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); - - if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) - { - HWND zstyle = HWND_NOTOPMOST; - - /* Set the window extended style flags */ - SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); - - /* Set the transient style flags */ - if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE, - WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - /* Set the window standard style flags */ - else SetWindowLongPtr (hwnd, GWL_STYLE, - (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) - & ~WS_CAPTION & ~WS_SIZEBOX); - - winUpdateWindowPosition (hwnd, FALSE, &zstyle); - SetForegroundWindow (hwnd); - } - wmMsg.msg = WM_WM_MAP3; - } - else /* It is an overridden window so make it top of Z stack */ - { - HWND forHwnd = GetForegroundWindow(); -#if CYGWINDOWING_DEBUG - ErrorF ("overridden window is shown\n"); -#endif - if (forHwnd != NULL) - { - if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE) - { - if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) - SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - else - SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } - } - wmMsg.msg = WM_WM_MAP2; - } - - /* Tell our Window Manager thread to map the window */ - if (fWMMsgInitialized) - winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); - - winStartMousePolling(s_pScreenPriv); - - 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 pWinPos = (LPWINDOWPOS) lParam; - - if (!(pWinPos->flags & SWP_NOZORDER)) - { -#if CYGWINDOWING_DEBUG - winDebug ("\twindow z order was changed\n"); -#endif - if (pWinPos->hwndInsertAfter == HWND_TOP - ||pWinPos->hwndInsertAfter == HWND_TOPMOST - ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) - { -#if CYGWINDOWING_DEBUG - winDebug ("\traise to top\n"); -#endif - /* Raise the window to the top in Z order */ - winRaiseWindow(pWin); - } - else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) - { - } - else - { - /* Check if this window is top of X windows. */ - HWND hWndAbove = NULL; - DWORD dwCurrentProcessID = GetCurrentProcessId (); - DWORD dwWindowProcessID = 0; - - for (hWndAbove = pWinPos->hwndInsertAfter; - hWndAbove != NULL; - hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) - { - /* Ignore other XWin process's window */ - GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); - - if ((dwWindowProcessID == dwCurrentProcessID) - && GetProp (hWndAbove, WIN_WINDOW_PROP) - && !IsWindowVisible (hWndAbove) - && !IsIconic (hWndAbove) ) /* ignore minimized windows */ - break; - } - /* If this is top of X windows in Windows stack, - raise it in X stack. */ - if (hWndAbove == NULL) - { -#if CYGWINDOWING_DEBUG - winDebug ("\traise to top\n"); -#endif - winRaiseWindow(pWin); - } - } - } - } - /* - * Pass the message to DefWindowProc to let the function - * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE. - */ - break; - - case WM_SIZE: - /* see dix/window.c */ -#if CYGWINDOWING_DEBUG - { - char buf[64]; - switch (wParam) - { - case SIZE_MINIMIZED: - strcpy(buf, "SIZE_MINIMIZED"); - break; - case SIZE_MAXIMIZED: - strcpy(buf, "SIZE_MAXIMIZED"); - break; - case SIZE_RESTORED: - strcpy(buf, "SIZE_RESTORED"); - break; - default: - strcpy(buf, "UNKNOWN_FLAG"); - } - ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", - (int)LOWORD(lParam), (int)HIWORD(lParam), buf, - (int)(GetTickCount ())); - } -#endif - /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); - return 0; /* end of WM_SIZE handler */ - - case WM_MOUSEACTIVATE: - - /* Check if this window needs to be made active when clicked */ - if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) - { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " - "MA_NOACTIVATE\n"); -#endif - - /* */ - return MA_NOACTIVATE; - } - break; - - case WM_SETCURSOR: - if (LOWORD(lParam) == HTCLIENT) - { - if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); - return TRUE; - } - break; - - default: - break; - } - - ret = DefWindowProc (hwnd, message, wParam, lParam); - /* - * If the window was minized we get the stack change before the window is restored - * and so it gets lost. Ensure there stacking order is correct. - */ - if (needRestack) - winReorderWindowsMultiWindow(); - return ret; -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" +#include "winmsg.h" +#include "inputstr.h" + +extern void winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); + + +/* + * Local globals + */ + +static UINT_PTR g_uipMousePollingTimerID = 0; + + +/* + * Constant defines + */ + +#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; + RECT rcClient, rcWindow; + int iBorderWidthX, iBorderWidthY; + + /* 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; + + /* Now remove size of any borders and title bar */ + GetClientRect(hwnd, &rcClient); + GetWindowRect(hwnd, &rcWindow); + iBorderWidthX = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left); + iBorderWidthY = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top); + iWidth -= iBorderWidthX; + iHeight -= iBorderWidthY; + + /* Constrain the size to legal values */ + ConstrainSize (sizeHints, &iWidth, &iHeight); + + /* Add back the size of borders and title bar */ + iWidth += iBorderWidthX; + iHeight += iBorderWidthY; + + /* 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; +} + +extern Bool winInDestroyWindowsWindow; +static Bool winInRaiseWindow = FALSE; +static void winRaiseWindow(WindowPtr pWin) +{ + if (!winInDestroyWindowsWindow && !winInRaiseWindow) + { + BOOL oldstate = winInRaiseWindow; + XID vlist[1] = { 0 }; + winInRaiseWindow = TRUE; + /* Call configure window directly to make sure it gets processed + * in time + */ + ConfigureWindow(pWin, CWStackMode, vlist, serverClient); + winInRaiseWindow = oldstate; + } +} + +static +void winStartMousePolling(winPrivScreenPtr s_pScreenPriv) +{ + /* + * Timer to poll mouse position. This is needed to make + * programs like xeyes follow the mouse properly when the + * mouse pointer is outside of any X window. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); +} + +/* + * 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; + winWMMessageRec wmMsg; + Bool fWMMsgInitialized = FALSE; + static Bool s_fTracking = FALSE; + Bool needRestack = FALSE; + LRESULT ret; + +#if CYGDEBUG + winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); +#endif + + /* 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 = pDraw->x; + wmMsg.iY = pDraw->y; + wmMsg.iWidth = pDraw->width; + wmMsg.iHeight = pDraw->height; + + 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_iWindowPrivateKey %p\n", g_iWindowPrivateKey); + 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: + + /* */ + SetProp (hwnd, + WIN_WINDOW_PROP, + (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); + + /* */ + SetProp (hwnd, + WIN_WID_PROP, + (HANDLE)winGetWindowID (((LPCREATESTRUCT) lParam)->lpCreateParams)); + + /* + * Make X windows' Z orders sync with Windows windows because + * there can be AlwaysOnTop windows overlapped on the window + * currently being created. + */ + winReorderWindowsMultiWindow (); + + /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */ + { + RECT rWindow; + HRGN hRgnWindow; + GetWindowRect(hwnd, &rWindow); + hRgnWindow = CreateRectRgnIndirect(&rWindow); + SetWindowRgn (hwnd, hRgnWindow, TRUE); + DeleteObject(hRgnWindow); + } + + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE); + + 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 + */ + if (HandleCustomWM_COMMAND ((unsigned long)hwnd, LOWORD(wParam))) + { + /* Don't pass customized menus to DefWindowProc */ + return 0; + } + if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) + { + WINDOWPLACEMENT wndpl; + wndpl.length = sizeof(wndpl); + if (GetWindowPlacement(hwnd, &wndpl) && wndpl.showCmd == SW_SHOWMINIMIZED) + needRestack = TRUE; + } + break; + + case WM_INITMENU: + /* Checks/Unchecks any menu items before they are displayed */ + HandleCustomWM_INITMENU ((unsigned long)hwnd, wParam); + break; + + case WM_ERASEBKGND: + /* + * Pretend that we did erase the background but we don't care, + * since we repaint the entire region anyhow + * This avoids some flickering when resizing. + */ + return TRUE; + + 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); + /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */ + if (ps.rcPaint.right==0 && ps.rcPaint.bottom==0 && ps.rcPaint.left==0 && ps.rcPaint.top==0) + { + EndPaint (hwnd, &ps); + return 0; + } + + /* Try to copy from the shadow buffer */ + if (!BitBlt (hdcUpdate, + ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, + s_pScreenPriv->hdcShadow, + ps.rcPaint.left + pWin->drawable.x, ps.rcPaint.top + pWin->drawable.y, + 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 (hwnd, &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 != miPointerGetScreen(g_pwinPointer)) + miPointerSetScreen (g_pwinPointer, 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_fSoftwareCursor && 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 */ + winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset); + + 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_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + winStartMousePolling(s_pScreenPriv); + + 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_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + winStartMousePolling(s_pScreenPriv); + + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[0] = TRUE; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[0] = FALSE; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[1] = TRUE; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[1] = FALSE; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[2] = TRUE; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[2] = FALSE; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + SetCapture(hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); + + case WM_XBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + ReleaseCapture(); + winStartMousePolling(s_pScreenPriv); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); + + case WM_MOUSEWHEEL: + if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) == HTCLIENT) + { + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + } + else break; + + case WM_SETFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + { + /* Get the parent window for transient handling */ + HWND hParent = GetParent(hwnd); + if (hParent && IsIconic(hParent)) ShowWindow (hParent, SW_RESTORE); + } + + winRestoreModeKeyStates (); + + /* Add the keyboard hook if possible */ + if (g_fKeyboardHookLL) + g_fKeyboardHookLL = winInstallKeyboardHookLL (); + return 0; + + case WM_KILLFOCUS: + /* Pop any pressed keys since we are losing keyboard focus */ + winKeybdReleaseKeys (); + + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); + if (!wParam) + /* Revert the X focus as well, but only if the Windows focus is going to another window */ + DeleteWindowFromAnyEvents(pWin, FALSE); + 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: + + /* + * 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; + +#if CYGWINDOWING_DEBUG + if (wParam == VK_ESCAPE) + { + /* Place for debug: put any tests and dumps here */ + WINDOWPLACEMENT windPlace; + RECT rc; + LPRECT pRect; + + windPlace.length = sizeof (WINDOWPLACEMENT); + GetWindowPlacement (hwnd, &windPlace); + pRect = &windPlace.rcNormalPosition; + ErrorF ("\nCYGWINDOWING Dump:\n" + "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, + pDraw->y, pDraw->width, pDraw->height); + ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, + pRect->top, pRect->right - pRect->left, + pRect->bottom - pRect->top); + if (GetClientRect (hwnd, &rc)) + { + pRect = &rc; + ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, + pRect->top, pRect->right - pRect->left, + pRect->bottom - pRect->top); + } + if (GetWindowRect (hwnd, &rc)) + { + pRect = &rc; + ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, + pRect->top, pRect->right - pRect->left, + pRect->bottom - pRect->top); + } + ErrorF ("\n"); + } +#endif + + /* Pass the message to the root window */ + return winWindowProc(hwndScreen, message, wParam, lParam); + + case WM_SYSKEYUP: + case WM_KEYUP: + + + /* Pass the message to the root window */ + return winWindowProc(hwndScreen, message, wParam, lParam); + + case WM_HOTKEY: + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_ACTIVATE: + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + + if (LOWORD(wParam) != WA_INACTIVE) + { + /* Raise the window to the top in Z order */ + /* ago: Activate does not mean putting it to front! */ + /* + wmMsg.msg = WM_WM_RAISE; + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + */ + + /* Tell our Window Manager thread to activate the window */ + wmMsg.msg = WM_WM_ACTIVATE; + if (fWMMsgInitialized) + if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + } + /* Prevent the mouse wheel from stalling when another window is minimized */ + if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE && + (HWND)lParam != NULL && (HWND)lParam != (HWND)GetParent(hwnd)) + SetFocus(hwnd); + return 0; + + case WM_ACTIVATEAPP: + /* + * This message is also sent to the root window + * so we do nothing for individual multiwindow windows + */ + break; + + case WM_CLOSE: + /* 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: + + /* 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); + } + + RemoveProp (hwnd, WIN_WINDOW_PROP); + RemoveProp (hwnd, WIN_WID_PROP); + RemoveProp (hwnd, WIN_NEEDMANAGE_PROP); + + break; + + case WM_MOVE: + /* Adjust the X Window to the moved Windows window */ + winAdjustXWindow (pWin, hwnd); + return 0; + + case WM_SHOWWINDOW: + /* Bail out if the window is being hidden */ + if (!wParam) + return 0; + + /* */ + if (!pWin->overrideRedirect) + { + /* Flag that this window needs to be made active when clicked */ + SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); + + if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) + { + HWND zstyle = HWND_NOTOPMOST; + + /* Set the window extended style flags */ + SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the transient style flags */ + if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE, + WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + /* Set the window standard style flags */ + else SetWindowLongPtr (hwnd, GWL_STYLE, + (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) + & ~WS_CAPTION & ~WS_SIZEBOX); + + winUpdateWindowPosition (hwnd, FALSE, &zstyle); + SetForegroundWindow (hwnd); + } + wmMsg.msg = WM_WM_MAP3; + } + else /* It is an overridden window so make it top of Z stack */ + { + HWND forHwnd = GetForegroundWindow(); +#if CYGWINDOWING_DEBUG + ErrorF ("overridden window is shown\n"); +#endif + if (forHwnd != NULL) + { + if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE) + { + if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) + SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + else + SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + } + wmMsg.msg = WM_WM_MAP2; + } + + /* Tell our Window Manager thread to map the window */ + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + + winStartMousePolling(s_pScreenPriv); + + 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 pWinPos = (LPWINDOWPOS) lParam; + + if (!(pWinPos->flags & SWP_NOZORDER)) + { +#if CYGWINDOWING_DEBUG + winDebug ("\twindow z order was changed\n"); +#endif + if (pWinPos->hwndInsertAfter == HWND_TOP + ||pWinPos->hwndInsertAfter == HWND_TOPMOST + ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) + { +#if CYGWINDOWING_DEBUG + winDebug ("\traise to top\n"); +#endif + /* Raise the window to the top in Z order */ + winRaiseWindow(pWin); + } + else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) + { + } + else + { + /* Check if this window is top of X windows. */ + HWND hWndAbove = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + + for (hWndAbove = pWinPos->hwndInsertAfter; + hWndAbove != NULL; + hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) + { + /* Ignore other XWin process's window */ + GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWndAbove, WIN_WINDOW_PROP) + && !IsWindowVisible (hWndAbove) + && !IsIconic (hWndAbove) ) /* ignore minimized windows */ + break; + } + /* If this is top of X windows in Windows stack, + raise it in X stack. */ + if (hWndAbove == NULL) + { +#if CYGWINDOWING_DEBUG + winDebug ("\traise to top\n"); +#endif + winRaiseWindow(pWin); + } + } + } + } + /* + * Pass the message to DefWindowProc to let the function + * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE. + */ + break; + + case WM_SIZE: + /* see dix/window.c */ +#if CYGWINDOWING_DEBUG + { + char buf[64]; + switch (wParam) + { + case SIZE_MINIMIZED: + strcpy(buf, "SIZE_MINIMIZED"); + break; + case SIZE_MAXIMIZED: + strcpy(buf, "SIZE_MAXIMIZED"); + break; + case SIZE_RESTORED: + strcpy(buf, "SIZE_RESTORED"); + break; + default: + strcpy(buf, "UNKNOWN_FLAG"); + } + ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", + (int)LOWORD(lParam), (int)HIWORD(lParam), buf, + (int)(GetTickCount ())); + } +#endif + /* Adjust the X Window to the moved Windows window */ + winAdjustXWindow (pWin, hwnd); + return 0; /* end of WM_SIZE handler */ + + case WM_MOUSEACTIVATE: + + /* Check if this window needs to be made active when clicked */ + if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " + "MA_NOACTIVATE\n"); +#endif + + /* */ + return MA_NOACTIVATE; + } + break; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); + return TRUE; + } + break; + + default: + break; + } + + ret = DefWindowProc (hwnd, message, wParam, lParam); + /* + * If the window was minized we get the stack change before the window is restored + * and so it gets lost. Ensure there stacking order is correct. + */ + if (needRestack) + winReorderWindowsMultiWindow(); + return ret; +} diff --git a/xorg-server/hw/xwin/winnativegdi.c b/xorg-server/hw/xwin/winnativegdi.c index 48a467a2c..1a41bb484 100644 --- a/xorg-server/hw/xwin/winnativegdi.c +++ b/xorg-server/hw/xwin/winnativegdi.c @@ -1,546 +1,539 @@ -/* - *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 - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" - - -/* - * External symbols - */ - -extern HWND g_hDlgExit; - - -/* - * Local function prototypes - */ - -static Bool -winAllocateFBNativeGDI (ScreenPtr pScreen); - -static void -winShadowUpdateNativeGDI (ScreenPtr pScreen, - shadowBufPtr pBuf); - -static Bool -winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen); - -static Bool -winInitVisualsNativeGDI (ScreenPtr pScreen); - -static Bool -winAdjustVideoModeNativeGDI (ScreenPtr pScreen); - -#if 0 -static Bool -winBltExposedRegionsNativeGDI (ScreenPtr pScreen); -#endif - -static Bool -winActivateAppNativeGDI (ScreenPtr pScreen); - -static Bool -winRedrawScreenNativeGDI (ScreenPtr pScreen); - -static Bool -winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen); - -static Bool -winInstallColormapNativeGDI (ColormapPtr pColormap); - -static Bool -winStoreColorsNativeGDI (ColormapPtr pmap, - int ndef, - xColorItem *pdefs); - -static Bool -winCreateColormapNativeGDI (ColormapPtr pColormap); - -static Bool -winDestroyColormapNativeGDI (ColormapPtr pColormap); - - - -static Bool -winAllocateFBNativeGDI (ScreenPtr pScreen) -{ - FatalError ("winAllocateFBNativeGDI\n"); - - return TRUE; -} - - -/* - * We wrap whatever CloseScreen procedure was specified by fb; - * a pointer to said procedure is stored in our privates. - */ - -static Bool -winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - ErrorF ("winCloseScreenNativeGDI - Freeing screen resources\n"); - - /* Flag that the screen is closed */ - pScreenPriv->fClosed = TRUE; - pScreenPriv->fActive = FALSE; - - /* - * NOTE: mi doesn't use a CloseScreen procedure, so we do not - * need to call a wrapped procedure here. - */ - - /* Delete the window property */ - RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); - - ErrorF ("winCloseScreenNativeGDI - Destroying window\n"); - - /* Delete tray icon, if we have one */ - if (!pScreenInfo->fNoTrayIcon) - winDeleteNotifyIcon (pScreenPriv); - - /* Free the exit confirmation dialog box, if it exists */ - if (g_hDlgExit != NULL) - { - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - } - - /* Kill our window */ - if (pScreenPriv->hwndScreen) - { - DestroyWindow (pScreenPriv->hwndScreen); - pScreenPriv->hwndScreen = NULL; - } - - /* Invalidate our screeninfo's pointer to the screen */ - pScreenInfo->pScreen = NULL; - - /* Free the screen privates for this screen */ - free (pScreenPriv); - - ErrorF ("winCloseScreenNativeGDI - Returning\n"); - - return TRUE; -} - - -static void -winShadowUpdateNativeGDI (ScreenPtr pScreen, - shadowBufPtr pBuf) -{ - FatalError ("winShadowUpdateNativeGDI\n"); - return; -} - - -static Bool -winInitVisualsNativeGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Set the bitsPerRGB and bit masks */ - switch (pScreenInfo->dwDepth) - { - case 24: - pScreenPriv->dwBitsPerRGB = 8; - pScreenPriv->dwRedMask = 0x00FF0000; - pScreenPriv->dwGreenMask = 0x0000FF00; - pScreenPriv->dwBlueMask = 0x000000FF; - break; - - case 16: - pScreenPriv->dwBitsPerRGB = 6; - pScreenPriv->dwRedMask = 0xF800; - pScreenPriv->dwGreenMask = 0x07E0; - pScreenPriv->dwBlueMask = 0x001F; - break; - - case 15: - pScreenPriv->dwBitsPerRGB = 5; - pScreenPriv->dwRedMask = 0x7C00; - pScreenPriv->dwGreenMask = 0x03E0; - pScreenPriv->dwBlueMask = 0x001F; - break; - - case 8: - pScreenPriv->dwBitsPerRGB = 8; - pScreenPriv->dwRedMask = 0; - pScreenPriv->dwGreenMask = 0; - pScreenPriv->dwBlueMask = 0; - break; - - default: - ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n"); - return FALSE; - break; - } - - /* Tell the user how many bits per RGB we are using */ - ErrorF ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n", - (int) pScreenPriv->dwBitsPerRGB); - - /* Create a single visual according to the Windows screen depth */ - switch (pScreenInfo->dwDepth) - { - case 24: - case 16: - case 15: - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - TrueColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n"); - return FALSE; - } - break; - - case 8: - ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - StaticColorMask, - pScreenPriv->dwBitsPerRGB, - StaticColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n"); - return FALSE; - } - break; - - default: - ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n"); - return FALSE; - } - -#if 1 - ErrorF ("winInitVisualsNativeGDI - Returning\n"); -#endif - - return TRUE; -} - - -/* Adjust the video mode */ -static Bool -winAdjustVideoModeNativeGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HDC hdc = NULL; - DWORD dwBPP; - - hdc = GetDC (NULL); - - /* We're in serious trouble if we can't get a DC */ - if (hdc == NULL) - { - ErrorF ("winAdjustVideoModeNativeGDI - GetDC () failed\n"); - return FALSE; - } - - /* Query GDI for current display depth */ - dwBPP = GetDeviceCaps (hdc, BITSPIXEL); - pScreenInfo->dwDepth = GetDeviceCaps (hdc, PLANES); - - switch (pScreenInfo->dwDepth) { - case 24: - case 16: - case 15: - case 8: - break; - default: - if (dwBPP == 32) - pScreenInfo->dwDepth = 24; - else - pScreenInfo->dwDepth = dwBPP; - break; - } - - /* GDI cannot change the screen depth */ - if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) - { - /* No -depth parameter passed, let the user know the depth being used */ - ErrorF ("winAdjustVideoModeNativeGDI - Using Windows display " - "depth of %d bits per pixel, %d depth\n", - (int) dwBPP, (int) pScreenInfo->dwDepth); - - /* Use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - else if (dwBPP != pScreenInfo->dwBPP) - { - /* Warn user if GDI depth is different than -depth parameter */ - ErrorF ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\ - "using bpp: %d\n", - (int) pScreenInfo->dwBPP, (int) dwBPP); - - /* We'll use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - - /* Release our DC */ - ReleaseDC (NULL, hdc); - - return TRUE; -} - - -static Bool -winActivateAppNativeGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* - * Are we active? - * Are we fullscreen? - */ - if (pScreenPriv != NULL - && pScreenPriv->fActive - && pScreenInfo->fFullScreen) - { - /* - * Activating, attempt to bring our window - * to the top of the display - */ - ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); - } - - /* - * Are we inactive? - * Are we fullscreen? - */ - if (pScreenPriv != NULL - && !pScreenPriv->fActive - && pScreenInfo->fFullScreen) - { - /* - * Deactivating, stuff our window onto the - * task bar. - */ - ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); - } - - return TRUE; -} - - -HBITMAP -winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, - BYTE **ppbBits, BITMAPINFO **ppbmi) -{ - BITMAPINFOHEADER *pbmih = NULL; - HBITMAP hBitmap = NULL; - BITMAPINFO *pbmi = NULL; - - /* Don't create an invalid bitmap */ - if (iWidth == 0 - || iHeight == 0 - || iDepth == 0) - { - ErrorF ("\nwinCreateDIBNativeGDI - Invalid specs w %d h %d d %d\n\n", - iWidth, iHeight, iDepth); - return NULL; - } - - /* Allocate bitmap info header */ - pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) - + 256 * sizeof (RGBQUAD)); - if (pbmih == NULL) - { - ErrorF ("winCreateDIBNativeGDI - malloc () failed\n"); - return FALSE; - } - ZeroMemory (pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); - - /* Describe bitmap to be created */ - pbmih->biSize = sizeof (BITMAPINFOHEADER); - pbmih->biWidth = iWidth; - pbmih->biHeight = -iHeight; - pbmih->biPlanes = 1; - pbmih->biBitCount = iDepth; - pbmih->biCompression = BI_RGB; - pbmih->biSizeImage = 0; - pbmih->biXPelsPerMeter = 0; - pbmih->biYPelsPerMeter = 0; - pbmih->biClrUsed = 0; - pbmih->biClrImportant = 0; - - /* Setup color table for mono DIBs */ - if (iDepth == 1) - { - pbmi = (BITMAPINFO*) pbmih; - pbmi->bmiColors[1].rgbBlue = 255; - pbmi->bmiColors[1].rgbGreen = 255; - pbmi->bmiColors[1].rgbRed = 255; - } - - /* Create a DIB with a bit pointer */ - hBitmap = CreateDIBSection (NULL, - (BITMAPINFO *) pbmih, - DIB_RGB_COLORS, - (void **) ppbBits, - NULL, - 0); - if (hBitmap == NULL) - { - ErrorF ("winCreateDIBNativeGDI - CreateDIBSection () failed\n"); - return NULL; - } - - /* Free the bitmap info header memory */ - if (ppbmi != NULL) - { - /* Store the address of the BMIH in the ppbmih parameter */ - *ppbmi = (BITMAPINFO *) pbmih; - } - else - { - free (pbmih); - pbmih = NULL; - } - - return hBitmap; -} - - -#if 0 -static Bool -winBltExposedRegionsNativeGDI (ScreenPtr pScreen) -{ - - return TRUE; -} -#endif - - -static Bool -winRedrawScreenNativeGDI (ScreenPtr pScreen) -{ - FatalError ("winRedrawScreenNativeGDI\n"); - return TRUE; -} - - -static Bool -winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen) -{ - FatalError ("winRealizeInstalledPaletteNativeGDI\n"); - return TRUE; -} - - -static Bool -winInstallColormapNativeGDI (ColormapPtr pColormap) -{ - FatalError ("winInstallColormapNativeGDI\n"); - return TRUE; -} - - -static Bool -winStoreColorsNativeGDI (ColormapPtr pmap, - int ndef, - xColorItem *pdefs) -{ - FatalError ("winStoreColorsNativeGDI\n"); - return TRUE; -} - - -static Bool -winCreateColormapNativeGDI (ColormapPtr pColormap) -{ - FatalError ("winCreateColormapNativeGDI\n"); - return TRUE; -} - - -static Bool -winDestroyColormapNativeGDI (ColormapPtr pColormap) -{ - FatalError ("winDestroyColormapNativeGDI\n"); - return TRUE; -} - - -/* Set engine specific funtions */ -Bool -winSetEngineFunctionsNativeGDI (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Set our pointers */ - pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI; - pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI; - pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI; - pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI; - pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI; - if (pScreenInfo->fFullScreen) - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; - else - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; - pScreenPriv->pwinFinishScreenInit = winFinishScreenInitNativeGDI; - /* - * WARNING: Do not set the BltExposedRegions procedure pointer to anything - * other than NULL until a working painting procedure is in place. - * Else, winWindowProc will get stuck in an infinite loop because - * Windows expects the BeginPaint and EndPaint functions to be called - * before a WM_PAINT message can be removed from the queue. We are - * using NULL here as a signal for winWindowProc that it should - * not signal that the WM_PAINT message has been processed. - */ - pScreenPriv->pwinBltExposedRegions = NULL; - pScreenPriv->pwinActivateApp = winActivateAppNativeGDI; - pScreenPriv->pwinRedrawScreen = winRedrawScreenNativeGDI; - pScreenPriv->pwinRealizeInstalledPalette = - winRealizeInstalledPaletteNativeGDI; - pScreenPriv->pwinInstallColormap = winInstallColormapNativeGDI; - pScreenPriv->pwinStoreColors = winStoreColorsNativeGDI; - pScreenPriv->pwinCreateColormap = winCreateColormapNativeGDI; - pScreenPriv->pwinDestroyColormap = winDestroyColormapNativeGDI; - pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; - - return TRUE; -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + + +/* + * Local function prototypes + */ + +static Bool +winAllocateFBNativeGDI (ScreenPtr pScreen); + +static void +winShadowUpdateNativeGDI (ScreenPtr pScreen, + shadowBufPtr pBuf); + +static Bool +winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen); + +static Bool +winInitVisualsNativeGDI (ScreenPtr pScreen); + +static Bool +winAdjustVideoModeNativeGDI (ScreenPtr pScreen); + +#if 0 +static Bool +winBltExposedRegionsNativeGDI (ScreenPtr pScreen); +#endif + +static Bool +winActivateAppNativeGDI (ScreenPtr pScreen); + +static Bool +winRedrawScreenNativeGDI (ScreenPtr pScreen); + +static Bool +winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen); + +static Bool +winInstallColormapNativeGDI (ColormapPtr pColormap); + +static Bool +winStoreColorsNativeGDI (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +static Bool +winCreateColormapNativeGDI (ColormapPtr pColormap); + +static Bool +winDestroyColormapNativeGDI (ColormapPtr pColormap); + + + +static Bool +winAllocateFBNativeGDI (ScreenPtr pScreen) +{ + FatalError ("winAllocateFBNativeGDI\n"); + + return TRUE; +} + + +/* + * We wrap whatever CloseScreen procedure was specified by fb; + * a pointer to said procedure is stored in our privates. + */ + +static Bool +winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + ErrorF ("winCloseScreenNativeGDI - Freeing screen resources\n"); + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* + * NOTE: mi doesn't use a CloseScreen procedure, so we do not + * need to call a wrapped procedure here. + */ + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + ErrorF ("winCloseScreenNativeGDI - Destroying window\n"); + + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Invalidate our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Free the screen privates for this screen */ + free (pScreenPriv); + + ErrorF ("winCloseScreenNativeGDI - Returning\n"); + + return TRUE; +} + + +static void +winShadowUpdateNativeGDI (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + FatalError ("winShadowUpdateNativeGDI\n"); + return; +} + + +static Bool +winInitVisualsNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set the bitsPerRGB and bit masks */ + switch (pScreenInfo->dwDepth) + { + case 24: + pScreenPriv->dwBitsPerRGB = 8; + pScreenPriv->dwRedMask = 0x00FF0000; + pScreenPriv->dwGreenMask = 0x0000FF00; + pScreenPriv->dwBlueMask = 0x000000FF; + break; + + case 16: + pScreenPriv->dwBitsPerRGB = 6; + pScreenPriv->dwRedMask = 0xF800; + pScreenPriv->dwGreenMask = 0x07E0; + pScreenPriv->dwBlueMask = 0x001F; + break; + + case 15: + pScreenPriv->dwBitsPerRGB = 5; + pScreenPriv->dwRedMask = 0x7C00; + pScreenPriv->dwGreenMask = 0x03E0; + pScreenPriv->dwBlueMask = 0x001F; + break; + + case 8: + pScreenPriv->dwBitsPerRGB = 8; + pScreenPriv->dwRedMask = 0; + pScreenPriv->dwGreenMask = 0; + pScreenPriv->dwBlueMask = 0; + break; + + default: + ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n"); + return FALSE; + break; + } + + /* Tell the user how many bits per RGB we are using */ + ErrorF ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n", + (int) pScreenPriv->dwBitsPerRGB); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + TrueColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n"); + return FALSE; + } + break; + + case 8: + ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + StaticColorMask, + pScreenPriv->dwBitsPerRGB, + StaticColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n"); + return FALSE; + } + break; + + default: + ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n"); + return FALSE; + } + +#if 1 + ErrorF ("winInitVisualsNativeGDI - Returning\n"); +#endif + + return TRUE; +} + + +/* Adjust the video mode */ +static Bool +winAdjustVideoModeNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc = NULL; + DWORD dwBPP; + + hdc = GetDC (NULL); + + /* We're in serious trouble if we can't get a DC */ + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModeNativeGDI - GetDC () failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + pScreenInfo->dwDepth = GetDeviceCaps (hdc, PLANES); + + switch (pScreenInfo->dwDepth) { + case 24: + case 16: + case 15: + case 8: + break; + default: + if (dwBPP == 32) + pScreenInfo->dwDepth = 24; + else + pScreenInfo->dwDepth = dwBPP; + break; + } + + /* GDI cannot change the screen depth */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModeNativeGDI - Using Windows display " + "depth of %d bits per pixel, %d depth\n", + (int) dwBPP, (int) pScreenInfo->dwDepth); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Warn user if GDI depth is different than -depth parameter */ + ErrorF ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\ + "using bpp: %d\n", + (int) pScreenInfo->dwBPP, (int) dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + + return TRUE; +} + + +static Bool +winActivateAppNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* + * Are we active? + * Are we fullscreen? + */ + if (pScreenPriv != NULL + && pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Activating, attempt to bring our window + * to the top of the display + */ + ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); + } + + /* + * Are we inactive? + * Are we fullscreen? + */ + if (pScreenPriv != NULL + && !pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Deactivating, stuff our window onto the + * task bar. + */ + ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); + } + + return TRUE; +} + + +HBITMAP +winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, + BYTE **ppbBits, BITMAPINFO **ppbmi) +{ + BITMAPINFOHEADER *pbmih = NULL; + HBITMAP hBitmap = NULL; + BITMAPINFO *pbmi = NULL; + + /* Don't create an invalid bitmap */ + if (iWidth == 0 + || iHeight == 0 + || iDepth == 0) + { + ErrorF ("\nwinCreateDIBNativeGDI - Invalid specs w %d h %d d %d\n\n", + iWidth, iHeight, iDepth); + return NULL; + } + + /* Allocate bitmap info header */ + pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pbmih == NULL) + { + ErrorF ("winCreateDIBNativeGDI - malloc () failed\n"); + return FALSE; + } + ZeroMemory (pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + + /* Describe bitmap to be created */ + pbmih->biSize = sizeof (BITMAPINFOHEADER); + pbmih->biWidth = iWidth; + pbmih->biHeight = -iHeight; + pbmih->biPlanes = 1; + pbmih->biBitCount = iDepth; + pbmih->biCompression = BI_RGB; + pbmih->biSizeImage = 0; + pbmih->biXPelsPerMeter = 0; + pbmih->biYPelsPerMeter = 0; + pbmih->biClrUsed = 0; + pbmih->biClrImportant = 0; + + /* Setup color table for mono DIBs */ + if (iDepth == 1) + { + pbmi = (BITMAPINFO*) pbmih; + pbmi->bmiColors[1].rgbBlue = 255; + pbmi->bmiColors[1].rgbGreen = 255; + pbmi->bmiColors[1].rgbRed = 255; + } + + /* Create a DIB with a bit pointer */ + hBitmap = CreateDIBSection (NULL, + (BITMAPINFO *) pbmih, + DIB_RGB_COLORS, + (void **) ppbBits, + NULL, + 0); + if (hBitmap == NULL) + { + ErrorF ("winCreateDIBNativeGDI - CreateDIBSection () failed\n"); + return NULL; + } + + /* Free the bitmap info header memory */ + if (ppbmi != NULL) + { + /* Store the address of the BMIH in the ppbmih parameter */ + *ppbmi = (BITMAPINFO *) pbmih; + } + else + { + free (pbmih); + pbmih = NULL; + } + + return hBitmap; +} + + +#if 0 +static Bool +winBltExposedRegionsNativeGDI (ScreenPtr pScreen) +{ + + return TRUE; +} +#endif + + +static Bool +winRedrawScreenNativeGDI (ScreenPtr pScreen) +{ + FatalError ("winRedrawScreenNativeGDI\n"); + return TRUE; +} + + +static Bool +winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen) +{ + FatalError ("winRealizeInstalledPaletteNativeGDI\n"); + return TRUE; +} + + +static Bool +winInstallColormapNativeGDI (ColormapPtr pColormap) +{ + FatalError ("winInstallColormapNativeGDI\n"); + return TRUE; +} + + +static Bool +winStoreColorsNativeGDI (ColormapPtr pmap, + int ndef, + xColorItem *pdefs) +{ + FatalError ("winStoreColorsNativeGDI\n"); + return TRUE; +} + + +static Bool +winCreateColormapNativeGDI (ColormapPtr pColormap) +{ + FatalError ("winCreateColormapNativeGDI\n"); + return TRUE; +} + + +static Bool +winDestroyColormapNativeGDI (ColormapPtr pColormap) +{ + FatalError ("winDestroyColormapNativeGDI\n"); + return TRUE; +} + + +/* Set engine specific funtions */ +Bool +winSetEngineFunctionsNativeGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI; + pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI; + pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI; + pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitNativeGDI; + /* + * WARNING: Do not set the BltExposedRegions procedure pointer to anything + * other than NULL until a working painting procedure is in place. + * Else, winWindowProc will get stuck in an infinite loop because + * Windows expects the BeginPaint and EndPaint functions to be called + * before a WM_PAINT message can be removed from the queue. We are + * using NULL here as a signal for winWindowProc that it should + * not signal that the WM_PAINT message has been processed. + */ + pScreenPriv->pwinBltExposedRegions = NULL; + pScreenPriv->pwinActivateApp = winActivateAppNativeGDI; + pScreenPriv->pwinRedrawScreen = winRedrawScreenNativeGDI; + pScreenPriv->pwinRealizeInstalledPalette = + winRealizeInstalledPaletteNativeGDI; + pScreenPriv->pwinInstallColormap = winInstallColormapNativeGDI; + pScreenPriv->pwinStoreColors = winStoreColorsNativeGDI; + pScreenPriv->pwinCreateColormap = winCreateColormapNativeGDI; + pScreenPriv->pwinDestroyColormap = winDestroyColormapNativeGDI; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; + + return TRUE; +} diff --git a/xorg-server/hw/xwin/winpfbdd.c b/xorg-server/hw/xwin/winpfbdd.c index 13fc1058d..840a839f0 100644 --- a/xorg-server/hw/xwin/winpfbdd.c +++ b/xorg-server/hw/xwin/winpfbdd.c @@ -1,684 +1,676 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" - - -/* - * External symbols - */ - -extern const GUID _IID_IDirectDraw2; -extern HWND g_hDlgExit; - - -/* - * Local function prototypes - */ - -static Bool -winAllocateFBPrimaryDD (ScreenPtr pScreen); - -static Bool -winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen); - -static Bool -winInitVisualsPrimaryDD (ScreenPtr pScreen); - -static Bool -winAdjustVideoModePrimaryDD (ScreenPtr pScreen); - -static Bool -winActivateAppPrimaryDD (ScreenPtr pScreen); - -static Bool -winHotKeyAltTabPrimaryDD (ScreenPtr pScreen); - - -/* - * Create a DirectDraw primary surface - */ - -static Bool -winAllocateFBPrimaryDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HRESULT ddrval = DD_OK; - DDSURFACEDESC ddsd; - DDSURFACEDESC *pddsdPrimary = NULL; - DDSURFACEDESC *pddsdOffscreen = NULL; - RECT rcClient; - - ErrorF ("winAllocateFBPrimaryDD\n"); - - /* Get client area location in screen coords */ - GetClientRect (pScreenPriv->hwndScreen, &rcClient); - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&rcClient, 2); - - /* Create a DirectDraw object, store the address at lpdd */ - ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); - if (ddrval != DD_OK) - FatalError ("winAllocateFBPrimaryDD - Could not start DirectDraw\n"); - - /* Get a DirectDraw2 interface pointer */ - ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, - &IID_IDirectDraw2, - (LPVOID*) &pScreenPriv->pdd2); - if (FAILED (ddrval)) - { - ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", - (unsigned int) ddrval); - return FALSE; - } - - - ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n"); - - /* Are we windowed or fullscreen? */ - if (pScreenInfo->fFullScreen) - { - /* Full screen mode */ - ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, - pScreenPriv->hwndScreen, - DDSCL_FULLSCREEN - | DDSCL_EXCLUSIVE); - if (FAILED (ddrval)) - FatalError ("winAllocateFBPrimaryDD - Could not set " - "cooperative level\n"); - - /* Change the video mode to the mode requested */ - ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, - pScreenInfo->dwWidth, - pScreenInfo->dwHeight, - pScreenInfo->dwBPP, - pScreenInfo->dwRefreshRate, - 0); - if (FAILED (ddrval)) - FatalError ("winAllocateFBPrimaryDD - Could not set " - "full screen display mode\n"); - } - else - { - /* Windowed mode */ - ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, - pScreenPriv->hwndScreen, - DDSCL_NORMAL); - if (FAILED (ddrval)) - FatalError ("winAllocateFBPrimaryDD - Could not set " - "cooperative level\n"); - } - - /* Describe the primary surface */ - ZeroMemory (&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - - /* Create the primary surface */ - ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, - &ddsd, - &pScreenPriv->pddsPrimary, - NULL); - if (FAILED (ddrval)) - FatalError ("winAllocateFBPrimaryDD - Could not create primary " - "surface %08x\n", (unsigned int) ddrval); - - ErrorF ("winAllocateFBPrimaryDD - Created primary\n"); - - /* Allocate a DD surface description for our screen privates */ - pddsdPrimary = pScreenPriv->pddsdPrimary - = malloc (sizeof (DDSURFACEDESC)); - if (pddsdPrimary == NULL) - FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " - "description memory\n"); - ZeroMemory (pddsdPrimary, sizeof (*pddsdPrimary)); - pddsdPrimary->dwSize = sizeof (*pddsdPrimary); - - /* Describe the offscreen surface to be created */ - /* - * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, - * as drawing, locking, and unlocking take forever - * with video memory surfaces. In addition, - * video memory is a somewhat scarce resource, - * so you shouldn't be allocating video memory when - * you have the option of using system memory instead. - */ - ZeroMemory (&ddsd, sizeof (ddsd)); - ddsd.dwSize = sizeof (ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - ddsd.dwHeight = pScreenInfo->dwHeight; - ddsd.dwWidth = pScreenInfo->dwWidth; - - /* Create the shadow surface */ - ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, - &ddsd, - &pScreenPriv->pddsOffscreen, - NULL); - if (ddrval != DD_OK) - FatalError ("winAllocateFBPrimaryDD - Could not create shadow " - "surface\n"); - - ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n"); - - /* Allocate a DD surface description for our screen privates */ - pddsdOffscreen = pScreenPriv->pddsdOffscreen - = malloc (sizeof (DDSURFACEDESC)); - if (pddsdOffscreen == NULL) - FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " - "description memory\n"); - ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen)); - pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen); - - ErrorF ("winAllocateFBPrimaryDD - Locking primary\n"); - - /* Lock the primary surface */ - ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, - pScreenInfo->fFullScreen ? NULL:&rcClient, - pddsdPrimary, - DDLOCK_WAIT, - NULL); - if (ddrval != DD_OK || pddsdPrimary->lpSurface == NULL) - FatalError ("winAllocateFBPrimaryDD - Could not lock " - "primary surface\n"); - - ErrorF ("winAllocateFBPrimaryDD - Locked primary\n"); - - /* We don't know how to deal with anything other than RGB */ - if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB)) - FatalError ("winAllocateFBPrimaryDD - Color format other than RGB\n"); - - /* Grab the pitch from the surface desc */ - pScreenInfo->dwStride = (pddsdPrimary->u1.lPitch * 8) - / pScreenInfo->dwBPP; - - /* Save the pointer to our surface memory */ - pScreenInfo->pfb = pddsdPrimary->lpSurface; - - /* Grab the color depth and masks from the surface description */ - pScreenPriv->dwRedMask = pddsdPrimary->ddpfPixelFormat.u2.dwRBitMask; - pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask; - pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask; - - ErrorF ("winAllocateFBPrimaryDD - Returning\n"); - - return TRUE; -} - - -/* - * Call the wrapped CloseScreen function. - * - * Free our resources and private structures. - */ - -static Bool -winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - Bool fReturn; - - ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n"); - - /* Flag that the screen is closed */ - pScreenPriv->fClosed = TRUE; - pScreenPriv->fActive = FALSE; - - /* Call the wrapped CloseScreen procedure */ - WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); - - /* Delete the window property */ - RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); - - /* Free the offscreen surface, if there is one */ - if (pScreenPriv->pddsOffscreen) - { - IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL); - IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen); - pScreenPriv->pddsOffscreen = NULL; - } - - /* Release the primary surface, if there is one */ - if (pScreenPriv->pddsPrimary) - { - IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL); - IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); - pScreenPriv->pddsPrimary = NULL; - } - - /* Free the DirectDraw object, if there is one */ - if (pScreenPriv->pdd) - { - IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd); - IDirectDraw2_Release (pScreenPriv->pdd); - pScreenPriv->pdd = NULL; - } - - /* Delete tray icon, if we have one */ - if (!pScreenInfo->fNoTrayIcon) - winDeleteNotifyIcon (pScreenPriv); - - /* Free the exit confirmation dialog box, if it exists */ - if (g_hDlgExit != NULL) - { - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - } - - /* Kill our window */ - if (pScreenPriv->hwndScreen) - { - DestroyWindow (pScreenPriv->hwndScreen); - pScreenPriv->hwndScreen = NULL; - } - - /* Kill our screeninfo's pointer to the screen */ - pScreenInfo->pScreen = NULL; - - /* Invalidate the ScreenInfo's fb pointer */ - pScreenInfo->pfb = NULL; - - /* Free the screen privates for this screen */ - free ((pointer) pScreenPriv); - - return fReturn; -} - - -/* - * Tell mi what sort of visuals we need. - * - * Generally we only need one visual, as our screen can only - * handle one format at a time, I believe. You may want - * to verify that last sentence. - */ - -static Bool -winInitVisualsPrimaryDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - DWORD dwRedBits, dwGreenBits, dwBlueBits; - - /* Count the number of ones in each color mask */ - dwRedBits = winCountBits (pScreenPriv->dwRedMask); - dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); - dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); - - /* Store the maximum number of ones in a color mask as the bitsPerRGB */ - if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) - pScreenPriv->dwBitsPerRGB = dwRedBits; - else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) - pScreenPriv->dwBitsPerRGB = dwGreenBits; - else - pScreenPriv->dwBitsPerRGB = dwBlueBits; - - ErrorF ("winInitVisualsPrimaryDD - Masks: %08x %08x %08x bpRGB: %d\n", - (unsigned int) pScreenPriv->dwRedMask, - (unsigned int) pScreenPriv->dwGreenMask, - (unsigned int) pScreenPriv->dwBlueMask, - (int) pScreenPriv->dwBitsPerRGB); - - /* Create a single visual according to the Windows screen depth */ - switch (pScreenInfo->dwDepth) - { - case 24: - case 16: - case 15: - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - TrueColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsPrimaryDD - " - "miSetVisualTypesAndMasks failed\n"); - return FALSE; - } - break; - - case 8: -#if CYGDEBUG - winDebug ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); -#endif /* CYGDEBUG */ - if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, - PseudoColorMask, - pScreenPriv->dwBitsPerRGB, - PseudoColor, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsPrimaryDD - " - "miSetVisualTypesAndMasks failed\n"); - return FALSE; - } -#if CYGDEBUG - winDebug ("winInitVisualsPrimaryDD - Returned from " - "miSetVisualTypesAndMasks\n"); -#endif /* CYGDEBUG */ - break; - - default: - ErrorF ("winInitVisualsPrimaryDD - Unknown screen depth\n"); - return FALSE; - } - - ErrorF ("winInitVisualsPrimaryDD - Returning\n"); - - return TRUE; -} - - -static Bool -winAdjustVideoModePrimaryDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - HDC hdc = NULL; - DWORD dwBPP; - - /* We're in serious trouble if we can't get a DC */ - hdc = GetDC (NULL); - if (hdc == NULL) - { - ErrorF ("winAdjustVideoModePrimaryDD - GetDC failed\n"); - return FALSE; - } - - /* Query GDI for current display depth */ - dwBPP = GetDeviceCaps (hdc, BITSPIXEL); - - /* DirectDraw can only change the depth in fullscreen mode */ - if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) - { - /* No -depth parameter passed, let the user know the depth being used */ - ErrorF ("winAdjustVideoModePrimaryDD - Using Windows display " - "depth of %d bits per pixel\n", (int) dwBPP); - - /* Use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - else if (pScreenInfo->fFullScreen - && pScreenInfo->dwBPP != dwBPP) - { - /* FullScreen, and GDI depth differs from -depth parameter */ - ErrorF ("winAdjustVideoModePrimaryDD - FullScreen, using command " - "line depth: %d\n", (int) pScreenInfo->dwBPP); - } - else if (dwBPP != pScreenInfo->dwBPP) - { - /* Windowed, and GDI depth differs from -depth parameter */ - ErrorF ("winAdjustVideoModePrimaryDD - Windowed, command line " - "depth: %d, using depth: %d\n", - (int) pScreenInfo->dwBPP, (int) dwBPP); - - /* We'll use GDI's depth */ - pScreenInfo->dwBPP = dwBPP; - } - - /* Release our DC */ - ReleaseDC (NULL, hdc); - - return TRUE; -} - - -/* - * We need to blit our offscreen fb to - * the screen when we are activated, and we need to point - * the fb code back to the primary surface memory. - */ - -static Bool -winActivateAppPrimaryDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - RECT rcSrc, rcClient; - HRESULT ddrval = DD_OK; - - /* Check for errors */ - if (pScreenPriv == NULL - || pScreenPriv->pddsPrimary == NULL - || pScreenPriv->pddsOffscreen == NULL) - return FALSE; - - /* Check for do-nothing */ - if (!pScreenPriv->fActive) - return TRUE; - - /* We are activating */ - ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsOffscreen); - if (ddrval == DD_OK) - { - IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, - NULL); - /* - * We don't check for an error from Unlock, because it - * doesn't matter if the Unlock failed. - */ - } - - /* Restore both surfaces, just cause I like it that way */ - IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); - IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); - - /* Get client area in screen coords */ - GetClientRect (pScreenPriv->hwndScreen, &rcClient); - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&rcClient, 2); - - /* Setup a source rectangle */ - rcSrc.left = 0; - rcSrc.top = 0; - rcSrc.right = pScreenInfo->dwWidth; - rcSrc.bottom = pScreenInfo->dwHeight; - - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, - &rcClient, - pScreenPriv->pddsOffscreen, - &rcSrc, - DDBLT_WAIT, - NULL); - if (ddrval != DD_OK) - FatalError ("winActivateAppPrimaryDD () - Failed blitting offscreen " - "surface to primary surface %08x\n", (unsigned int) ddrval); - - /* Lock the primary surface */ - ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, - &rcClient, - pScreenPriv->pddsdPrimary, - DDLOCK_WAIT, - NULL); - if (ddrval != DD_OK - || pScreenPriv->pddsdPrimary->lpSurface == NULL) - FatalError ("winActivateAppPrimaryDD () - Could not lock " - "primary surface\n"); - - /* Notify FB of the new memory pointer */ - winUpdateFBPointer (pScreen, - pScreenPriv->pddsdPrimary->lpSurface); - - /* - * Register the Alt-Tab combo as a hotkey so we can copy - * the primary framebuffer before the display mode changes - */ - RegisterHotKey (pScreenPriv->hwndScreen, 1, MOD_ALT, 9); - - return TRUE; -} - - -/* - * Handle the Alt+Tab hotkey. - * - * We need to save the primary fb to an offscreen fb when - * we get deactivated, and point the fb code at the offscreen - * fb for the duration of the deactivation. - */ - -static Bool -winHotKeyAltTabPrimaryDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - RECT rcClient, rcSrc; - HRESULT ddrval = DD_OK; - - ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n"); - - /* Alt+Tab was pressed, we will lose focus very soon */ - pScreenPriv->fActive = FALSE; - - /* Check for error conditions */ - if (pScreenPriv->pddsPrimary == NULL - || pScreenPriv->pddsOffscreen == NULL) - return FALSE; - - /* Get client area in screen coords */ - GetClientRect (pScreenPriv->hwndScreen, &rcClient); - MapWindowPoints (pScreenPriv->hwndScreen, - HWND_DESKTOP, - (LPPOINT)&rcClient, 2); - - /* Did we loose the primary surface? */ - ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsPrimary); - if (ddrval == DD_OK) - { - ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, - NULL); - if (FAILED (ddrval)) - FatalError ("winHotKeyAltTabPrimaryDD - Failed unlocking primary " - "surface\n"); - } - - /* Setup a source rectangle */ - rcSrc.left = 0; - rcSrc.top = 0; - rcSrc.right = pScreenInfo->dwWidth; - rcSrc.bottom = pScreenInfo->dwHeight; - - /* Blit the primary surface to the offscreen surface */ - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, - NULL, /* should be rcDest */ - pScreenPriv->pddsPrimary, - NULL, - DDBLT_WAIT, - NULL); - if (ddrval == DDERR_SURFACELOST) - { - IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); - IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); - - /* Blit the primary surface to the offscreen surface */ - ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, - NULL, - pScreenPriv->pddsPrimary, - NULL, - DDBLT_WAIT, - NULL); - if (FAILED (ddrval)) - FatalError ("winHotKeyAltTabPrimaryDD - Failed blitting primary " - "surface to offscreen surface: %08x\n", - (unsigned int) ddrval); - } - else - { - FatalError ("winHotKeyAltTabPrimaryDD - Unknown error from " - "Blt: %08dx\n", (unsigned int) ddrval); - } - - /* Lock the offscreen surface */ - ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsOffscreen, - NULL, - pScreenPriv->pddsdOffscreen, - DDLOCK_WAIT, - NULL); - if (ddrval != DD_OK - || pScreenPriv->pddsdPrimary->lpSurface == NULL) - FatalError ("winHotKeyAltTabPrimaryDD - Could not lock " - "offscreen surface\n"); - - /* Notify FB of the new memory pointer */ - winUpdateFBPointer (pScreen, - pScreenPriv->pddsdOffscreen->lpSurface); - - /* Unregister our hotkey */ - UnregisterHotKey (pScreenPriv->hwndScreen, 1); - - return TRUE; -} - - -/* Set engine specific functions */ -Bool -winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Set our pointers */ - pScreenPriv->pwinAllocateFB = winAllocateFBPrimaryDD; - pScreenPriv->pwinShadowUpdate - = (winShadowUpdateProcPtr) (void (*)(void))NoopDDA; - pScreenPriv->pwinCloseScreen = winCloseScreenPrimaryDD; - pScreenPriv->pwinInitVisuals = winInitVisualsPrimaryDD; - pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModePrimaryDD; - if (pScreenInfo->fFullScreen) - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; - else - pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; - pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; - pScreenPriv->pwinBltExposedRegions - = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA; - pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD; - pScreenPriv->pwinHotKeyAltTab = winHotKeyAltTabPrimaryDD; -#ifdef XWIN_MULTIWINDOW - pScreenPriv->pwinFinishCreateWindowsWindow = - (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; -#endif - - return TRUE; -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + + +/* + * Local function prototypes + */ + +static Bool +winAllocateFBPrimaryDD (ScreenPtr pScreen); + +static Bool +winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen); + +static Bool +winInitVisualsPrimaryDD (ScreenPtr pScreen); + +static Bool +winAdjustVideoModePrimaryDD (ScreenPtr pScreen); + +static Bool +winActivateAppPrimaryDD (ScreenPtr pScreen); + +static Bool +winHotKeyAltTabPrimaryDD (ScreenPtr pScreen); + + +/* + * Create a DirectDraw primary surface + */ + +static Bool +winAllocateFBPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + DDSURFACEDESC ddsd; + DDSURFACEDESC *pddsdPrimary = NULL; + DDSURFACEDESC *pddsdOffscreen = NULL; + RECT rcClient; + + ErrorF ("winAllocateFBPrimaryDD\n"); + + /* Get client area location in screen coords */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, 2); + + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); + if (ddrval != DD_OK) + FatalError ("winAllocateFBPrimaryDD - Could not start DirectDraw\n"); + + /* Get a DirectDraw2 interface pointer */ + ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, + &IID_IDirectDraw2, + (LPVOID*) &pScreenPriv->pdd2); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Failed DD2 query: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + + + ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n"); + + /* Are we windowed or fullscreen? */ + if (pScreenInfo->fFullScreen) + { + /* Full screen mode */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_FULLSCREEN + | DDSCL_EXCLUSIVE); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not set " + "cooperative level\n"); + + /* Change the video mode to the mode requested */ + ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, + pScreenInfo->dwWidth, + pScreenInfo->dwHeight, + pScreenInfo->dwBPP, + pScreenInfo->dwRefreshRate, + 0); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not set " + "full screen display mode\n"); + } + else + { + /* Windowed mode */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_NORMAL); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not set " + "cooperative level\n"); + } + + /* Describe the primary surface */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + /* Create the primary surface */ + ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, + &ddsd, + &pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + FatalError ("winAllocateFBPrimaryDD - Could not create primary " + "surface %08x\n", (unsigned int) ddrval); + + ErrorF ("winAllocateFBPrimaryDD - Created primary\n"); + + /* Allocate a DD surface description for our screen privates */ + pddsdPrimary = pScreenPriv->pddsdPrimary + = malloc (sizeof (DDSURFACEDESC)); + if (pddsdPrimary == NULL) + FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " + "description memory\n"); + ZeroMemory (pddsdPrimary, sizeof (*pddsdPrimary)); + pddsdPrimary->dwSize = sizeof (*pddsdPrimary); + + /* Describe the offscreen surface to be created */ + /* + * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, + * as drawing, locking, and unlocking take forever + * with video memory surfaces. In addition, + * video memory is a somewhat scarce resource, + * so you shouldn't be allocating video memory when + * you have the option of using system memory instead. + */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwHeight = pScreenInfo->dwHeight; + ddsd.dwWidth = pScreenInfo->dwWidth; + + /* Create the shadow surface */ + ddrval = IDirectDraw2_CreateSurface (pScreenPriv->pdd2, + &ddsd, + &pScreenPriv->pddsOffscreen, + NULL); + if (ddrval != DD_OK) + FatalError ("winAllocateFBPrimaryDD - Could not create shadow " + "surface\n"); + + ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n"); + + /* Allocate a DD surface description for our screen privates */ + pddsdOffscreen = pScreenPriv->pddsdOffscreen + = malloc (sizeof (DDSURFACEDESC)); + if (pddsdOffscreen == NULL) + FatalError ("winAllocateFBPrimaryDD - Could not allocate surface " + "description memory\n"); + ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen)); + pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen); + + ErrorF ("winAllocateFBPrimaryDD - Locking primary\n"); + + /* Lock the primary surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, + pScreenInfo->fFullScreen ? NULL:&rcClient, + pddsdPrimary, + DDLOCK_WAIT, + NULL); + if (ddrval != DD_OK || pddsdPrimary->lpSurface == NULL) + FatalError ("winAllocateFBPrimaryDD - Could not lock " + "primary surface\n"); + + ErrorF ("winAllocateFBPrimaryDD - Locked primary\n"); + + /* We don't know how to deal with anything other than RGB */ + if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB)) + FatalError ("winAllocateFBPrimaryDD - Color format other than RGB\n"); + + /* Grab the pitch from the surface desc */ + pScreenInfo->dwStride = (pddsdPrimary->u1.lPitch * 8) + / pScreenInfo->dwBPP; + + /* Save the pointer to our surface memory */ + pScreenInfo->pfb = pddsdPrimary->lpSurface; + + /* Grab the color depth and masks from the surface description */ + pScreenPriv->dwRedMask = pddsdPrimary->ddpfPixelFormat.u2.dwRBitMask; + pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask; + pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask; + + ErrorF ("winAllocateFBPrimaryDD - Returning\n"); + + return TRUE; +} + + +/* + * Call the wrapped CloseScreen function. + * + * Free our resources and private structures. + */ + +static Bool +winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + + ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n"); + + /* Flag that the screen is closed */ + pScreenPriv->fClosed = TRUE; + pScreenPriv->fActive = FALSE; + + /* Call the wrapped CloseScreen procedure */ + WIN_UNWRAP(CloseScreen); + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the offscreen surface, if there is one */ + if (pScreenPriv->pddsOffscreen) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL); + IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen); + pScreenPriv->pddsOffscreen = NULL; + } + + /* Release the primary surface, if there is one */ + if (pScreenPriv->pddsPrimary) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL); + IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); + pScreenPriv->pddsPrimary = NULL; + } + + /* Free the DirectDraw object, if there is one */ + if (pScreenPriv->pdd) + { + IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd); + IDirectDraw2_Release (pScreenPriv->pdd); + pScreenPriv->pdd = NULL; + } + + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + + /* Kill our screeninfo's pointer to the screen */ + pScreenInfo->pScreen = NULL; + + /* Invalidate the ScreenInfo's fb pointer */ + pScreenInfo->pfb = NULL; + + /* Free the screen privates for this screen */ + free ((pointer) pScreenPriv); + + return fReturn; +} + + +/* + * Tell mi what sort of visuals we need. + * + * Generally we only need one visual, as our screen can only + * handle one format at a time, I believe. You may want + * to verify that last sentence. + */ + +static Bool +winInitVisualsPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + DWORD dwRedBits, dwGreenBits, dwBlueBits; + + /* Count the number of ones in each color mask */ + dwRedBits = winCountBits (pScreenPriv->dwRedMask); + dwGreenBits = winCountBits (pScreenPriv->dwGreenMask); + dwBlueBits = winCountBits (pScreenPriv->dwBlueMask); + + /* Store the maximum number of ones in a color mask as the bitsPerRGB */ + if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + ErrorF ("winInitVisualsPrimaryDD - Masks: %08x %08x %08x bpRGB: %d\n", + (unsigned int) pScreenPriv->dwRedMask, + (unsigned int) pScreenPriv->dwGreenMask, + (unsigned int) pScreenPriv->dwBlueMask, + (int) pScreenPriv->dwBitsPerRGB); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + TrueColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsPrimaryDD - " + "miSetVisualTypesAndMasks failed\n"); + return FALSE; + } + break; + + case 8: +#if CYGDEBUG + winDebug ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); +#endif /* CYGDEBUG */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + PseudoColorMask, + pScreenPriv->dwBitsPerRGB, + PseudoColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsPrimaryDD - " + "miSetVisualTypesAndMasks failed\n"); + return FALSE; + } +#if CYGDEBUG + winDebug ("winInitVisualsPrimaryDD - Returned from " + "miSetVisualTypesAndMasks\n"); +#endif /* CYGDEBUG */ + break; + + default: + ErrorF ("winInitVisualsPrimaryDD - Unknown screen depth\n"); + return FALSE; + } + + ErrorF ("winInitVisualsPrimaryDD - Returning\n"); + + return TRUE; +} + + +static Bool +winAdjustVideoModePrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc = NULL; + DWORD dwBPP; + + /* We're in serious trouble if we can't get a DC */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModePrimaryDD - GetDC failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* DirectDraw can only change the depth in fullscreen mode */ + if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) + { + /* No -depth parameter passed, let the user know the depth being used */ + ErrorF ("winAdjustVideoModePrimaryDD - Using Windows display " + "depth of %d bits per pixel\n", (int) dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (pScreenInfo->fFullScreen + && pScreenInfo->dwBPP != dwBPP) + { + /* FullScreen, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModePrimaryDD - FullScreen, using command " + "line depth: %d\n", (int) pScreenInfo->dwBPP); + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Windowed, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModePrimaryDD - Windowed, command line " + "depth: %d, using depth: %d\n", + (int) pScreenInfo->dwBPP, (int) dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + + return TRUE; +} + + +/* + * We need to blit our offscreen fb to + * the screen when we are activated, and we need to point + * the fb code back to the primary surface memory. + */ + +static Bool +winActivateAppPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcSrc, rcClient; + HRESULT ddrval = DD_OK; + + /* Check for errors */ + if (pScreenPriv == NULL + || pScreenPriv->pddsPrimary == NULL + || pScreenPriv->pddsOffscreen == NULL) + return FALSE; + + /* Check for do-nothing */ + if (!pScreenPriv->fActive) + return TRUE; + + /* We are activating */ + ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsOffscreen); + if (ddrval == DD_OK) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, + NULL); + /* + * We don't check for an error from Unlock, because it + * doesn't matter if the Unlock failed. + */ + } + + /* Restore both surfaces, just cause I like it that way */ + IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); + IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + + /* Get client area in screen coords */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, 2); + + /* Setup a source rectangle */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcClient, + pScreenPriv->pddsOffscreen, + &rcSrc, + DDBLT_WAIT, + NULL); + if (ddrval != DD_OK) + FatalError ("winActivateAppPrimaryDD () - Failed blitting offscreen " + "surface to primary surface %08x\n", (unsigned int) ddrval); + + /* Lock the primary surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, + &rcClient, + pScreenPriv->pddsdPrimary, + DDLOCK_WAIT, + NULL); + if (ddrval != DD_OK + || pScreenPriv->pddsdPrimary->lpSurface == NULL) + FatalError ("winActivateAppPrimaryDD () - Could not lock " + "primary surface\n"); + + /* Notify FB of the new memory pointer */ + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdPrimary->lpSurface); + + /* + * Register the Alt-Tab combo as a hotkey so we can copy + * the primary framebuffer before the display mode changes + */ + RegisterHotKey (pScreenPriv->hwndScreen, 1, MOD_ALT, 9); + + return TRUE; +} + + +/* + * Handle the Alt+Tab hotkey. + * + * We need to save the primary fb to an offscreen fb when + * we get deactivated, and point the fb code at the offscreen + * fb for the duration of the deactivation. + */ + +static Bool +winHotKeyAltTabPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcClient, rcSrc; + HRESULT ddrval = DD_OK; + + ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n"); + + /* Alt+Tab was pressed, we will lose focus very soon */ + pScreenPriv->fActive = FALSE; + + /* Check for error conditions */ + if (pScreenPriv->pddsPrimary == NULL + || pScreenPriv->pddsOffscreen == NULL) + return FALSE; + + /* Get client area in screen coords */ + GetClientRect (pScreenPriv->hwndScreen, &rcClient); + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&rcClient, 2); + + /* Did we loose the primary surface? */ + ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsPrimary); + if (ddrval == DD_OK) + { + ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + FatalError ("winHotKeyAltTabPrimaryDD - Failed unlocking primary " + "surface\n"); + } + + /* Setup a source rectangle */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Blit the primary surface to the offscreen surface */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, + NULL, /* should be rcDest */ + pScreenPriv->pddsPrimary, + NULL, + DDBLT_WAIT, + NULL); + if (ddrval == DDERR_SURFACELOST) + { + IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen); + IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + + /* Blit the primary surface to the offscreen surface */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen, + NULL, + pScreenPriv->pddsPrimary, + NULL, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + FatalError ("winHotKeyAltTabPrimaryDD - Failed blitting primary " + "surface to offscreen surface: %08x\n", + (unsigned int) ddrval); + } + else + { + FatalError ("winHotKeyAltTabPrimaryDD - Unknown error from " + "Blt: %08dx\n", (unsigned int) ddrval); + } + + /* Lock the offscreen surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsOffscreen, + NULL, + pScreenPriv->pddsdOffscreen, + DDLOCK_WAIT, + NULL); + if (ddrval != DD_OK + || pScreenPriv->pddsdPrimary->lpSurface == NULL) + FatalError ("winHotKeyAltTabPrimaryDD - Could not lock " + "offscreen surface\n"); + + /* Notify FB of the new memory pointer */ + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdOffscreen->lpSurface); + + /* Unregister our hotkey */ + UnregisterHotKey (pScreenPriv->hwndScreen, 1); + + return TRUE; +} + + +/* Set engine specific functions */ +Bool +winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBPrimaryDD; + pScreenPriv->pwinShadowUpdate + = (winShadowUpdateProcPtr) (void (*)(void))NoopDDA; + pScreenPriv->pwinCloseScreen = winCloseScreenPrimaryDD; + pScreenPriv->pwinInitVisuals = winInitVisualsPrimaryDD; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModePrimaryDD; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions + = (winBltExposedRegionsProcPtr) (void (*)(void))NoopDDA; + pScreenPriv->pwinActivateApp = winActivateAppPrimaryDD; + pScreenPriv->pwinHotKeyAltTab = winHotKeyAltTabPrimaryDD; +#ifdef XWIN_MULTIWINDOW + pScreenPriv->pwinFinishCreateWindowsWindow = + (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; +#endif + + return TRUE; +} diff --git a/xorg-server/hw/xwin/winprefs.c b/xorg-server/hw/xwin/winprefs.c index c3b194560..073c9ec62 100644 --- a/xorg-server/hw/xwin/winprefs.c +++ b/xorg-server/hw/xwin/winprefs.c @@ -49,22 +49,11 @@ /* Where will the custom menu commands start counting from? */ #define STARTMENUID WM_USER -/* External global variables */ -#ifdef XWIN_MULTIWINDOW -extern DWORD g_dwCurrentThreadID; -#endif - extern const char *winGetBaseDir(void); /* From winmultiwindowflex.l, the real parser */ extern void parse_file (FILE *fp); -/* From winprefyacc.y, the pref structure loaded by the parser */ -extern WINPREFS pref; - -/* The global X default icon */ -extern HICON g_hIconX; -extern HICON g_hSmallIconX; /* Currently in use command ID, incremented each new menu item created */ static int g_cmdid = STARTMENUID; diff --git a/xorg-server/hw/xwin/winprefs.h b/xorg-server/hw/xwin/winprefs.h index 4daf47401..276b9724d 100644 --- a/xorg-server/hw/xwin/winprefs.h +++ b/xorg-server/hw/xwin/winprefs.h @@ -1,189 +1,190 @@ -#if !defined(WINPREFS_H) -#define WINPREFS_H -/* - * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * Copyright (C) Colin Harrison 2005-2008 - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the XFree86 Project - * shall not be used in advertising or otherwise to promote the sale, use - * or other dealings in this Software without prior written authorization - * from the XFree86 Project. - * - * Authors: Earle F. Philhower, III - * Colin Harrison - */ - -/* Need Bool */ -#include -/* Need TRUE */ -#include "misc.h" - -/* Need to know how long paths can be... */ -#include -/* Xwindows redefines PATH_MAX to at least 1024 */ -#include - -#ifndef NAME_MAX -#define NAME_MAX PATH_MAX -#endif -#define MENU_MAX 128 /* Maximum string length of a menu name or item */ -#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */ - - -/* Supported commands in a MENU {} statement */ -typedef enum MENUCOMMANDTYPE -{ - CMD_EXEC, /* /bin/sh -c the parameter */ - CMD_MENU, /* Display a popup menu named param */ - CMD_SEPARATOR, /* Menu separator */ - CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ - CMD_RELOAD /* Reparse the .XWINRC file */ -} MENUCOMMANDTYPE; - -#define STYLE_NONE (0L) /* Dummy the first entry */ -#define STYLE_NOTITLE (1L) /* Force window style no titlebar */ -#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */ -#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */ -#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */ -#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */ -#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */ -#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */ - -/* Where to place a system menu */ -typedef enum MENUPOSITION -{ - AT_START, /* Place menu at the top of the system menu */ - AT_END /* Put it at the bottom of the menu (default) */ -} MENUPOSITION; - -/* Menu item definitions */ -typedef struct MENUITEM -{ - char text[MENU_MAX+1]; /* To be displayed in menu */ - MENUCOMMANDTYPE cmd; /* What should it do? */ - char param[PARAM_MAX+1]; /* Any parameters? */ - unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ -} MENUITEM; - -/* A completely read in menu... */ -typedef struct MENUPARSED -{ - char menuName[MENU_MAX+1]; /* What's it called in the text? */ - MENUITEM *menuItem; /* Array of items */ - int menuItems; /* How big's the array? */ -} MENUPARSED; - -/* To map between a window and a system menu to add for it */ -typedef struct SYSMENUITEM -{ - char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ - char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ - MENUPOSITION menuPos; /* Where to place it (ignored in root) */ -} SYSMENUITEM; - -/* To redefine icons for certain window types */ -typedef struct ICONITEM -{ - char match[MENU_MAX+1]; /* What string to search for? */ - char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ - HICON hicon; /* LoadImage() result */ -} ICONITEM; - -/* To redefine styles for certain window types */ -typedef struct STYLEITEM -{ - char match[MENU_MAX+1]; /* What string to search for? */ - unsigned long type; /* What should it do? */ -} STYLEITEM; - -typedef struct WINPREFS -{ - /* Menu information */ - MENUPARSED *menu; /* Array of created menus */ - int menuItems; /* How big? */ - - /* Taskbar menu settings */ - char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */ - - /* System menu addition menus */ - SYSMENUITEM *sysMenu; - int sysMenuItems; - - /* Which menu to add to unmatched windows? */ - char defaultSysMenuName[MENU_MAX+1]; - MENUPOSITION defaultSysMenuPos; /* Where to place it */ - - /* Icon information */ - char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */ - char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */ - char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */ - - ICONITEM *icon; - int iconItems; - - STYLEITEM *style; - int styleItems; - - /* Force exit flag */ - Bool fForceExit; - - /* Silent exit flag */ - Bool fSilentExit; - -} WINPREFS; - - - - -/* Functions */ -void -LoadPreferences(void); - -void -SetupRootMenu (unsigned long hmenuRoot); - -void -SetupSysMenu (unsigned long hwndIn); - -void -HandleCustomWM_INITMENU(unsigned long hwndIn, - unsigned long hmenuIn); - -Bool -HandleCustomWM_COMMAND (unsigned long hwndIn, - int command); - -int -winIconIsOverride (unsigned hiconIn); - -HICON -winOverrideIcon (unsigned long longpWin); - -unsigned long -winOverrideStyle (unsigned long longpWin); - -HICON -winTaskbarIcon(void); - -HICON -winOverrideDefaultIcon(int size); -#endif +#if !defined(WINPREFS_H) +#define WINPREFS_H +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * Copyright (C) Colin Harrison 2005-2008 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + * Colin Harrison + */ + +/* Need Bool */ +#include +/* Need TRUE */ +#include "misc.h" + +/* Need to know how long paths can be... */ +#include +/* Xwindows redefines PATH_MAX to at least 1024 */ +#include + +#ifndef NAME_MAX +#define NAME_MAX PATH_MAX +#endif +#define MENU_MAX 128 /* Maximum string length of a menu name or item */ +#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */ + + +/* Supported commands in a MENU {} statement */ +typedef enum MENUCOMMANDTYPE +{ + CMD_EXEC, /* /bin/sh -c the parameter */ + CMD_MENU, /* Display a popup menu named param */ + CMD_SEPARATOR, /* Menu separator */ + CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ + CMD_RELOAD /* Reparse the .XWINRC file */ +} MENUCOMMANDTYPE; + +#define STYLE_NONE (0L) /* Dummy the first entry */ +#define STYLE_NOTITLE (1L) /* Force window style no titlebar */ +#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */ +#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */ +#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */ +#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */ +#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */ +#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */ + +/* Where to place a system menu */ +typedef enum MENUPOSITION +{ + AT_START, /* Place menu at the top of the system menu */ + AT_END /* Put it at the bottom of the menu (default) */ +} MENUPOSITION; + +/* Menu item definitions */ +typedef struct MENUITEM +{ + char text[MENU_MAX+1]; /* To be displayed in menu */ + MENUCOMMANDTYPE cmd; /* What should it do? */ + char param[PARAM_MAX+1]; /* Any parameters? */ + unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ +} MENUITEM; + +/* A completely read in menu... */ +typedef struct MENUPARSED +{ + char menuName[MENU_MAX+1]; /* What's it called in the text? */ + MENUITEM *menuItem; /* Array of items */ + int menuItems; /* How big's the array? */ +} MENUPARSED; + +/* To map between a window and a system menu to add for it */ +typedef struct SYSMENUITEM +{ + char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ + char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ + MENUPOSITION menuPos; /* Where to place it (ignored in root) */ +} SYSMENUITEM; + +/* To redefine icons for certain window types */ +typedef struct ICONITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ + HICON hicon; /* LoadImage() result */ +} ICONITEM; + +/* To redefine styles for certain window types */ +typedef struct STYLEITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + unsigned long type; /* What should it do? */ +} STYLEITEM; + +typedef struct WINPREFS +{ + /* Menu information */ + MENUPARSED *menu; /* Array of created menus */ + int menuItems; /* How big? */ + + /* Taskbar menu settings */ + char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */ + + /* System menu addition menus */ + SYSMENUITEM *sysMenu; + int sysMenuItems; + + /* Which menu to add to unmatched windows? */ + char defaultSysMenuName[MENU_MAX+1]; + MENUPOSITION defaultSysMenuPos; /* Where to place it */ + + /* Icon information */ + char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */ + char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */ + char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */ + + ICONITEM *icon; + int iconItems; + + STYLEITEM *style; + int styleItems; + + /* Force exit flag */ + Bool fForceExit; + + /* Silent exit flag */ + Bool fSilentExit; + +} WINPREFS; + +/* The global pref settings structure loaded by the winprefyacc.y parser */ +extern WINPREFS pref; + + +/* Functions */ +void +LoadPreferences(void); + +void +SetupRootMenu (unsigned long hmenuRoot); + +void +SetupSysMenu (unsigned long hwndIn); + +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn); + +Bool +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command); + +int +winIconIsOverride (unsigned hiconIn); + +HICON +winOverrideIcon (unsigned long longpWin); + +unsigned long +winOverrideStyle (unsigned long longpWin); + +HICON +winTaskbarIcon(void); + +HICON +winOverrideDefaultIcon(int size); +#endif diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c index 66a0503f2..39f0ee3e5 100644 --- a/xorg-server/hw/xwin/winprocarg.c +++ b/xorg-server/hw/xwin/winprocarg.c @@ -1,1276 +1,1256 @@ -/* - -Copyright 1993, 1998 The Open Group -Copyright (C) Colin Harrison 2005-2008 - -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. - -*/ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#ifdef XVENDORNAME -#define VENDOR_STRING XVENDORNAME -#define VENDOR_CONTACT BUILDERADDR -#endif -#include <../xfree86/common/xorgVersion.h> -#include "win.h" -#include "winconfig.h" -#include "winprefs.h" -#include "winmsg.h" - -/* - * References to external symbols - */ - -extern int g_iNumScreens; -extern winScreenInfo * g_ScreenInfo; -#ifdef XWIN_CLIPBOARD -extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboard; -#endif -extern int g_iLogVerbose; -extern const char * g_pszLogFile; -#ifdef RELOCATE_PROJECTROOT -extern Bool g_fLogFileChanged; -#endif -extern Bool g_fXdmcpEnabled; -extern Bool g_fAuthEnabled; -extern char * g_pszCommandLine; -extern Bool g_fKeyboardHookLL; -extern Bool g_fNoHelpMessageBox; -extern Bool g_fSoftwareCursor; -extern Bool g_fSilentDupError; -extern Bool g_fNativeGl; - -/* globals required by callback function for monitor information */ -struct GetMonitorInfoData { - int requestedMonitor; - int monitorNum; - Bool bUserSpecifiedMonitor; - Bool bMonitorSpecifiedExists; - int monitorOffsetX; - int monitorOffsetY; - int monitorHeight; - int monitorWidth; -}; - -typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); -ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors; - -wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data); - -static Bool QueryMonitor(int index, struct GetMonitorInfoData *data) -{ - /* Load EnumDisplayMonitors from DLL */ - HMODULE user32; - FARPROC func; - user32 = LoadLibrary("user32.dll"); - if (user32 == NULL) - { - winW32Error(2, "Could not open user32.dll"); - return FALSE; - } - func = GetProcAddress(user32, "EnumDisplayMonitors"); - if (func == NULL) - { - winW32Error(2, "Could not resolve EnumDisplayMonitors: "); - return FALSE; - } - _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func; - - /* prepare data */ - if (data == NULL) - return FALSE; - memset(data, 0, sizeof(*data)); - data->requestedMonitor = index; - - /* query information */ - _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data); - - /* cleanup */ - FreeLibrary(user32); - return TRUE; -} - -/* - * Function prototypes - */ - -void -winLogCommandLine (int argc, char *argv[]); - -void -winLogVersionInfo (void); - -#ifdef DDXOSVERRORF -void OsVendorVErrorF (const char *pszFormat, va_list va_args); -#endif - -/* - * Process arguments on the command line - */ - -static int iLastScreen = -1; -static winScreenInfo defaultScreenInfo; - -static void -winInitializeScreenDefaults(void) -{ - DWORD dwWidth, dwHeight; - static Bool fInitializedScreenDefaults = FALSE; - - /* Bail out early if default screen has already been initialized */ - if (fInitializedScreenDefaults) - return; - - /* Zero the memory used for storing the screen info */ - memset(&defaultScreenInfo, 0, sizeof(winScreenInfo)); - - /* Get default width and height */ - /* - * NOTE: These defaults will cause the window to cover only - * the primary monitor in the case that we have multiple monitors. - */ - dwWidth = GetSystemMetrics (SM_CXSCREEN); - dwHeight = GetSystemMetrics (SM_CYSCREEN); - - winErrorFVerb (2, "winInitializeScreenDefaults - w %d h %d\n", - (int) dwWidth, (int) dwHeight); - - /* Set a default DPI, if no parameter was passed */ - if (monitorResolution == 0) - monitorResolution = WIN_DEFAULT_DPI; - - defaultScreenInfo.dwWidth = dwWidth; - defaultScreenInfo.dwHeight = dwHeight; - defaultScreenInfo.dwUserWidth = dwWidth; - defaultScreenInfo.dwUserHeight = dwHeight; - defaultScreenInfo.fUserGaveHeightAndWidth = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH; - defaultScreenInfo.fUserGavePosition = FALSE; - defaultScreenInfo.dwBPP = WIN_DEFAULT_BPP; - defaultScreenInfo.dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES; -#ifdef XWIN_EMULATEPSEUDO - defaultScreenInfo.fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO; -#endif - defaultScreenInfo.dwRefreshRate = WIN_DEFAULT_REFRESH; - defaultScreenInfo.pfb = NULL; - defaultScreenInfo.fFullScreen = FALSE; - defaultScreenInfo.fDecoration = TRUE; -#ifdef XWIN_MULTIWINDOWEXTWM - defaultScreenInfo.fMWExtWM = FALSE; - defaultScreenInfo.fInternalWM = FALSE; -#endif - defaultScreenInfo.fRootless = FALSE; -#ifdef XWIN_MULTIWINDOW - defaultScreenInfo.fMultiWindow = FALSE; -#endif -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - defaultScreenInfo.fMultiMonitorOverride = FALSE; -#endif - defaultScreenInfo.fMultipleMonitors = FALSE; - defaultScreenInfo.fLessPointer = FALSE; - defaultScreenInfo.fScrollbars = FALSE; - defaultScreenInfo.fNoTrayIcon = FALSE; - defaultScreenInfo.iE3BTimeout = WIN_E3B_OFF; - defaultScreenInfo.dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) * 25.4; - defaultScreenInfo.dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) * 25.4; - defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL; - defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL; - defaultScreenInfo.fIgnoreInput = FALSE; - defaultScreenInfo.fExplicitScreen = FALSE; - - /* Note that the default screen has been initialized */ - fInitializedScreenDefaults = TRUE; -} - -static void -winInitializeScreen(int i) -{ - winErrorFVerb (2, "winInitializeScreen - %d\n",i); - - /* Initialize default screen values, if needed */ - winInitializeScreenDefaults(); - - /* Copy the default screen info */ - g_ScreenInfo[i] = defaultScreenInfo; - - /* Set the screen number */ - g_ScreenInfo[i].dwScreen = i; -} - -void -winInitializeScreens(int maxscreens) -{ - int i; - winErrorFVerb (2, "winInitializeScreens - %i\n", maxscreens); - - if (maxscreens > g_iNumScreens) - { - /* Reallocate the memory for DDX-specific screen info */ - g_ScreenInfo = realloc(g_ScreenInfo, maxscreens * sizeof (winScreenInfo)); - - /* Set default values for any new screens */ - for (i = g_iNumScreens; i < maxscreens ; i++) - winInitializeScreen(i); - - /* Keep a count of the number of screens */ - g_iNumScreens = maxscreens; - } -} - -/* See Porting Layer Definition - p. 57 */ -/* - * INPUT - * argv: pointer to an array of null-terminated strings, one for - * each token in the X Server command line; the first token - * is 'XWin.exe', or similar. - * argc: a count of the number of tokens stored in argv. - * i: a zero-based index into argv indicating the current token being - * processed. - * - * OUTPUT - * return: return the number of tokens processed correctly. - * - * NOTE - * When looking for n tokens, check that i + n is less than argc. Or, - * you may check if i is greater than or equal to argc, in which case - * you should display the UseMsg () and return 0. - */ - -/* Check if enough arguments are given for the option */ -#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; } - -/* Compare the current option with the string. */ -#define IS_OPTION(name) (strcmp (argv[i], name) == 0) - -int -ddxProcessArgument (int argc, char *argv[], int i) -{ - static Bool s_fBeenHere = FALSE; - winScreenInfo *screenInfoPtr = NULL; - - /* Initialize once */ - if (!s_fBeenHere) - { -#ifdef DDXOSVERRORF - /* - * This initialises our hook into VErrorF () for catching log messages - * that are generated before OsInit () is called. - */ - OsVendorVErrorFProc = OsVendorVErrorF; -#endif - - s_fBeenHere = TRUE; - - /* Initialize only if option is not -help */ - if (!IS_OPTION("-help") && !IS_OPTION("-h") && !IS_OPTION("--help") && - !IS_OPTION("-version") && !IS_OPTION("--version")) - { - - /* Log the version information */ - winLogVersionInfo (); - - /* Log the command line */ - winLogCommandLine (argc, argv); - - /* - * Initialize default screen settings. We have to do this before - * OsVendorInit () gets called, otherwise we will overwrite - * settings changed by parameters such as -fullscreen, etc. - */ - winErrorFVerb (2, "ddxProcessArgument - Initializing default " - "screens\n"); - winInitializeScreenDefaults(); - } - } - -#if CYGDEBUG - winDebug ("ddxProcessArgument - arg: %s\n", argv[i]); -#endif - - /* - * Look for the '-help' and similar options - */ - if (IS_OPTION ("-help") || IS_OPTION("-h") || IS_OPTION("--help")) - { - /* Reset logfile. We don't need that helpmessage in the logfile */ - g_pszLogFile = NULL; - g_fNoHelpMessageBox = TRUE; - UseMsg(); - exit (0); - return 1; - } - - if (IS_OPTION ("-version") || IS_OPTION("--version")) - { - /* Reset logfile. We don't need that versioninfo in the logfile */ - g_pszLogFile = NULL; - winLogVersionInfo (); - exit (0); - return 1; - } - - /* - * Look for the '-screen scr_num [width height]' argument - */ - if (IS_OPTION ("-screen")) - { - int iArgsProcessed = 1; - int nScreenNum; - int iWidth, iHeight, iX, iY; - int iMonitor; - -#if CYGDEBUG - winDebug ("ddxProcessArgument - screen - argc: %d i: %d\n", - argc, i); -#endif - - /* Display the usage message if the argument is malformed */ - if (i + 1 >= argc) - { - return 0; - } - - /* Grab screen number */ - nScreenNum = atoi (argv[i + 1]); - - /* Validate the specified screen number */ - if (nScreenNum < 0) - { - ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n", - nScreenNum); - UseMsg (); - return 0; - } - - /* - Initialize default values for any new screens - - Note that default values can't change after a -screen option is - seen, so it's safe to do this for each screen as it is introduced - */ - winInitializeScreens(nScreenNum+1); - - /* look for @m where m is monitor number */ - if (i + 2 < argc - && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor)) - { - struct GetMonitorInfoData data; - if (!QueryMonitor(iMonitor, &data)) - { - ErrorF ("ddxProcessArgument - screen - " - "Querying monitors is not supported on NT4 and Win95\n"); - } else if (data.bMonitorSpecifiedExists == TRUE) - { - winErrorFVerb(2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); - iArgsProcessed = 3; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth; - g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight; - g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth; - g_ScreenInfo[nScreenNum].dwUserHeight = data.monitorHeight; - g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; - g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; - } - else - { - /* monitor does not exist, error out */ - ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", - iMonitor); - UseMsg (); - exit (0); - return 0; - } - } - - /* Look for 'WxD' or 'W D' */ - else if (i + 2 < argc - && 2 == sscanf (argv[i + 2], "%dx%d", - (int *) &iWidth, - (int *) &iHeight)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``WxD'' arg\n"); - iArgsProcessed = 3; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; - g_ScreenInfo[nScreenNum].dwWidth = iWidth; - g_ScreenInfo[nScreenNum].dwHeight = iHeight; - g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; - g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; - /* Look for WxD+X+Y */ - if (2 == sscanf (argv[i + 2], "%*dx%*d+%d+%d", - (int *) &iX, - (int *) &iY)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X+Y'' arg\n"); - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwInitialX = iX; - g_ScreenInfo[nScreenNum].dwInitialY = iY; - - /* look for WxD+X+Y@m where m is monitor number. take X,Y to be offsets from monitor's root position */ - if (1 == sscanf (argv[i + 2], "%*dx%*d+%*d+%*d@%d", - (int *) &iMonitor)) - { - struct GetMonitorInfoData data; - if (!QueryMonitor(iMonitor, &data)) - { - ErrorF ("ddxProcessArgument - screen - " - "Querying monitors is not supported on NT4 and Win95\n"); - } else if (data.bMonitorSpecifiedExists == TRUE) - { - g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX; - g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY; - } - else - { - /* monitor does not exist, error out */ - ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", - iMonitor); - UseMsg (); - exit (0); - return 0; - } - - } - } - - /* look for WxD@m where m is monitor number */ - else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d", - (int *) &iMonitor)) - { - struct GetMonitorInfoData data; - if (!QueryMonitor(iMonitor, &data)) - { - ErrorF ("ddxProcessArgument - screen - " - "Querying monitors is not supported on NT4 and Win95\n"); - } else if (data.bMonitorSpecifiedExists == TRUE) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; - g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; - } - else - { - /* monitor does not exist, error out */ - ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", - iMonitor); - UseMsg (); - exit (0); - return 0; - } - - } - } - else if (i + 3 < argc - && 1 == sscanf (argv[i + 2], "%d", - (int *) &iWidth) - && 1 == sscanf (argv[i + 3], "%d", - (int *) &iHeight)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``W D'' arg\n"); - iArgsProcessed = 4; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; - g_ScreenInfo[nScreenNum].dwWidth = iWidth; - g_ScreenInfo[nScreenNum].dwHeight = iHeight; - g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; - g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; - if (i + 5 < argc - && 1 == sscanf (argv[i + 4], "%d", - (int *) &iX) - && 1 == sscanf (argv[i + 5], "%d", - (int *) &iY)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X Y'' arg\n"); - iArgsProcessed = 6; - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwInitialX = iX; - g_ScreenInfo[nScreenNum].dwInitialY = iY; - } - } - else - { - winErrorFVerb (2, "ddxProcessArgument - screen - Did not find size arg. " - "dwWidth: %d dwHeight: %d\n", - (int) g_ScreenInfo[nScreenNum].dwWidth, - (int) g_ScreenInfo[nScreenNum].dwHeight); - iArgsProcessed = 2; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; - } - - /* Calculate the screen width and height in millimeters */ - if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth) - { - g_ScreenInfo[nScreenNum].dwWidth_mm - = (g_ScreenInfo[nScreenNum].dwWidth - / monitorResolution) * 25.4; - g_ScreenInfo[nScreenNum].dwHeight_mm - = (g_ScreenInfo[nScreenNum].dwHeight - / monitorResolution) * 25.4; - } - - /* Flag that this screen was explicity specified by the user */ - g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE; - - /* - * Keep track of the last screen number seen, as parameters seen - * before a screen number apply to all screens, whereas parameters - * seen after a screen number apply to that screen number only. - */ - iLastScreen = nScreenNum; - - return iArgsProcessed; - } - - - /* - * Is this parameter attached to a screen or global? - * - * If the parameter is for all screens (appears before - * any -screen option), store it in the default screen - * info - * - * If the parameter is for a single screen (appears - * after a -screen option), store it in the screen info - * for that screen - * - */ - if (iLastScreen == -1) - { - screenInfoPtr = &defaultScreenInfo; - } - else - { - screenInfoPtr = &(g_ScreenInfo[iLastScreen]); - } - - /* - * Look for the '-engine n' argument - */ - if (IS_OPTION ("-engine")) - { - DWORD dwEngine = 0; - CARD8 c8OnBits = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwEngine = atoi (argv[i]); - - /* Count the one bits in the engine argument */ - c8OnBits = winCountBits (dwEngine); - - /* Argument should only have a single bit on */ - if (c8OnBits != 1) - { - UseMsg (); - return 0; - } - - screenInfoPtr->dwEnginePreferred = dwEngine; - - /* Indicate that we have processed the argument */ - return 2; - } - - /* - * Look for the '-fullscreen' argument - */ - if (IS_OPTION ("-fullscreen")) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!screenInfoPtr->fMultiMonitorOverride) - screenInfoPtr->fMultipleMonitors = FALSE; -#endif - screenInfoPtr->fFullScreen = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-lesspointer' argument - */ - if (IS_OPTION ("-lesspointer")) - { - screenInfoPtr->fLessPointer = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-nodecoration' argument - */ - if (IS_OPTION ("-nodecoration")) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!screenInfoPtr->fMultiMonitorOverride) - screenInfoPtr->fMultipleMonitors = FALSE; -#endif - screenInfoPtr->fDecoration = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } - -#ifdef XWIN_MULTIWINDOWEXTWM - /* - * Look for the '-mwextwm' argument - */ - if (IS_OPTION ("-mwextwm")) - { - if (!screenInfoPtr->fMultiMonitorOverride) - screenInfoPtr->fMultipleMonitors = TRUE; - screenInfoPtr->fMWExtWM = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - /* - * Look for the '-internalwm' argument - */ - if (IS_OPTION ("-internalwm")) - { - if (!screenInfoPtr->fMultiMonitorOverride) - screenInfoPtr->fMultipleMonitors = TRUE; - screenInfoPtr->fMWExtWM = TRUE; - screenInfoPtr->fInternalWM = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - /* - * Look for the '-rootless' argument - */ - if (IS_OPTION ("-rootless")) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!screenInfoPtr->fMultiMonitorOverride) - screenInfoPtr->fMultipleMonitors = FALSE; -#endif - screenInfoPtr->fRootless = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - -#ifdef XWIN_MULTIWINDOW - /* - * Look for the '-multiwindow' argument - */ - if (IS_OPTION ("-multiwindow")) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!screenInfoPtr->fMultiMonitorOverride) - screenInfoPtr->fMultipleMonitors = TRUE; -#endif - screenInfoPtr->fMultiWindow = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - /* - * Look for the '-multiplemonitors' argument - */ - if (IS_OPTION ("-multiplemonitors") - || IS_OPTION ("-multimonitors")) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - screenInfoPtr->fMultiMonitorOverride = TRUE; -#endif - screenInfoPtr->fMultipleMonitors = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-nomultiplemonitors' argument - */ - if (IS_OPTION ("-nomultiplemonitors") - || IS_OPTION ("-nomultimonitors")) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - screenInfoPtr->fMultiMonitorOverride = TRUE; -#endif - screenInfoPtr->fMultipleMonitors = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } - - - /* - * Look for the '-scrollbars' argument - */ - if (IS_OPTION ("-scrollbars")) - { - screenInfoPtr->fScrollbars = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - -#ifdef XWIN_CLIPBOARD - /* - * Look for the '-clipboard' argument - */ - if (IS_OPTION ("-clipboard")) - { - /* Now the default, we still accept the arg for backwards compatibility */ - g_fClipboard = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-noclipboard' argument - */ - if (IS_OPTION ("-noclipboard")) - { - g_fClipboard = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - - /* - * Look for the '-ignoreinput' argument - */ - if (IS_OPTION ("-ignoreinput")) - { - screenInfoPtr->fIgnoreInput = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-emulate3buttons' argument - */ - if (IS_OPTION ("-emulate3buttons")) - { - int iArgsProcessed = 1; - int iE3BTimeout = WIN_DEFAULT_E3B_TIME; - - /* Grab the optional timeout value */ - if (i + 1 < argc - && 1 == sscanf (argv[i + 1], "%d", - &iE3BTimeout)) - { - /* Indicate that we have processed the next argument */ - iArgsProcessed++; - } - else - { - /* - * sscanf () won't modify iE3BTimeout if it doesn't find - * the specified format; however, I want to be explicit - * about setting the default timeout in such cases to - * prevent some programs (me) from getting confused. - */ - iE3BTimeout = WIN_DEFAULT_E3B_TIME; - } - - screenInfoPtr->iE3BTimeout = iE3BTimeout; - - /* Indicate that we have processed this argument */ - return iArgsProcessed; - } - - /* - * Look for the '-depth n' argument - */ - if (IS_OPTION ("-depth")) - { - DWORD dwBPP = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwBPP = atoi (argv[i]); - - screenInfoPtr->dwBPP = dwBPP; - - /* Indicate that we have processed the argument */ - return 2; - } - - /* - * Look for the '-refresh n' argument - */ - if (IS_OPTION ("-refresh")) - { - DWORD dwRefreshRate = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwRefreshRate = atoi (argv[i]); - - screenInfoPtr->dwRefreshRate = dwRefreshRate; - - /* Indicate that we have processed the argument */ - return 2; - } - - /* - * Look for the '-clipupdates num_boxes' argument - */ - if (IS_OPTION ("-clipupdates")) - { - DWORD dwNumBoxes = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwNumBoxes = atoi (argv[i]); - - screenInfoPtr->dwClipUpdatesNBoxes = dwNumBoxes; - - /* Indicate that we have processed the argument */ - return 2; - } - -#ifdef XWIN_EMULATEPSEUDO - /* - * Look for the '-emulatepseudo' argument - */ - if (IS_OPTION ("-emulatepseudo")) - { - screenInfoPtr->fEmulatePseudo = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - /* - * Look for the '-nowinkill' argument - */ - if (IS_OPTION ("-nowinkill")) - { - screenInfoPtr->fUseWinKillKey = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-winkill' argument - */ - if (IS_OPTION ("-winkill")) - { - screenInfoPtr->fUseWinKillKey = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-nounixkill' argument - */ - if (IS_OPTION ("-nounixkill")) - { - screenInfoPtr->fUseUnixKillKey = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-unixkill' argument - */ - if (IS_OPTION ("-unixkill")) - { - screenInfoPtr->fUseUnixKillKey = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-notrayicon' argument - */ - if (IS_OPTION ("-notrayicon")) - { - screenInfoPtr->fNoTrayIcon = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-trayicon' argument - */ - if (IS_OPTION ("-trayicon")) - { - screenInfoPtr->fNoTrayIcon = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-fp' argument - */ - if (IS_OPTION ("-fp")) - { - CHECK_ARGS (1); - g_cmdline.fontPath = argv[++i]; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-query' argument - */ - if (IS_OPTION ("-query")) - { - CHECK_ARGS (1); - g_fXdmcpEnabled = TRUE; - g_pszQueryHost = argv[++i]; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-auth' argument - */ - if (IS_OPTION ("-auth")) - { - g_fAuthEnabled = TRUE; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-indirect' or '-broadcast' arguments - */ - if (IS_OPTION ("-indirect") - || IS_OPTION ("-broadcast")) - { - g_fXdmcpEnabled = TRUE; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-config' argument - */ - if (IS_OPTION ("-config") - || IS_OPTION ("-xf86config")) - { - CHECK_ARGS (1); -#ifdef XWIN_XF86CONFIG - g_cmdline.configFile = argv[++i]; -#else - winMessageBoxF ("The %s option is not supported in this " - "release.\n" - "Ignoring this option and continuing.\n", - MB_ICONINFORMATION, - argv[i]); -#endif - return 2; - } - - /* - * Look for the '-configdir' argument - */ - if (IS_OPTION ("-configdir")) - { - CHECK_ARGS (1); -#ifdef XWIN_XF86CONFIG - g_cmdline.configDir = argv[++i]; -#else - winMessageBoxF ("The %s option is not supported in this " - "release.\n" - "Ignoring this option and continuing.\n", - MB_ICONINFORMATION, - argv[i]); -#endif - return 2; - } - - /* - * Look for the '-keyboard' argument - */ - if (IS_OPTION ("-keyboard")) - { -#ifdef XWIN_XF86CONFIG - CHECK_ARGS (1); - g_cmdline.keyboard = argv[++i]; -#else - winMessageBoxF ("The -keyboard option is not supported in this " - "release.\n" - "Ignoring this option and continuing.\n", - MB_ICONINFORMATION); -#endif - return 2; - } - - /* - * Look for the '-logfile' argument - */ - if (IS_OPTION ("-logfile")) - { - CHECK_ARGS (1); - g_pszLogFile = argv[++i]; -#ifdef RELOCATE_PROJECTROOT - g_fLogFileChanged = TRUE; -#endif - return 2; - } - - /* - * Look for the '-logverbose' argument - */ - if (IS_OPTION ("-logverbose")) - { - CHECK_ARGS (1); - g_iLogVerbose = atoi(argv[++i]); - return 2; - } - -#ifdef XWIN_CLIPBOARD - /* - * Look for the '-nounicodeclipboard' argument - */ - if (IS_OPTION ("-nounicodeclipboard")) - { - g_fUnicodeClipboard = FALSE; - /* Indicate that we have processed the argument */ - return 1; - } -#endif - - if (IS_OPTION ("-xkbrules")) - { - CHECK_ARGS (1); - g_cmdline.xkbRules = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkbmodel")) - { - CHECK_ARGS (1); - g_cmdline.xkbModel = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkblayout")) - { - CHECK_ARGS (1); - g_cmdline.xkbLayout = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkbvariant")) - { - CHECK_ARGS (1); - g_cmdline.xkbVariant = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkboptions")) - { - CHECK_ARGS (1); - g_cmdline.xkbOptions = argv[++i]; - return 2; - } - - if (IS_OPTION ("-keyhook")) - { - g_fKeyboardHookLL = TRUE; - return 1; - } - - if (IS_OPTION ("-nokeyhook")) - { - g_fKeyboardHookLL = FALSE; - return 1; - } - - if (IS_OPTION ("-swcursor")) - { - g_fSoftwareCursor = TRUE; - return 1; - } - - if (IS_OPTION ("-silent-dup-error")) - { - g_fSilentDupError = TRUE; - return 1; - } - - if (IS_OPTION("-wgl")) - { - g_fNativeGl = TRUE; - return 1; - } - - if (IS_OPTION("-nowgl")) - { - g_fNativeGl = FALSE; - return 1; - } - - return 0; -} - - -/* - * winLogCommandLine - Write entire command line to the log file - */ - -void -winLogCommandLine (int argc, char *argv[]) -{ - int i; - int iSize = 0; - int iCurrLen = 0; - -#define CHARS_PER_LINE 60 - - /* Bail if command line has already been logged */ - if (g_pszCommandLine) - return; - - /* Count how much memory is needed for concatenated command line */ - for (i = 0, iCurrLen = 0; i < argc; ++i) - if (argv[i]) - { - /* Adds two characters for lines that overflow */ - if ((strlen (argv[i]) < CHARS_PER_LINE - && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE) - || strlen (argv[i]) > CHARS_PER_LINE) - { - iCurrLen = 0; - iSize += 2; - } - - /* Add space for item and trailing space */ - iSize += strlen (argv[i]) + 1; - - /* Update current line length */ - iCurrLen += strlen (argv[i]); - } - - /* Allocate memory for concatenated command line */ - g_pszCommandLine = malloc (iSize + 1); - if (!g_pszCommandLine) - FatalError ("winLogCommandLine - Could not allocate memory for " - "command line string. Exiting.\n"); - - /* Set first character to concatenated command line to null */ - g_pszCommandLine[0] = '\0'; - - /* Loop through all args */ - for (i = 0, iCurrLen = 0; i < argc; ++i) - { - /* Add a character for lines that overflow */ - if ((strlen (argv[i]) < CHARS_PER_LINE - && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE) - || strlen (argv[i]) > CHARS_PER_LINE) - { - iCurrLen = 0; - - /* Add line break if it fits */ - strncat (g_pszCommandLine, "\n ", iSize - strlen (g_pszCommandLine)); - } - - strncat (g_pszCommandLine, argv[i], iSize - strlen (g_pszCommandLine)); - strncat (g_pszCommandLine, " ", iSize - strlen (g_pszCommandLine)); - - /* Save new line length */ - iCurrLen += strlen (argv[i]); - } - - ErrorF ("XWin was started with the following command line:\n\n" - "%s\n\n", g_pszCommandLine); -} - - -/* - * winLogVersionInfo - Log Cygwin/X version information - */ - -void -winLogVersionInfo (void) -{ - static Bool s_fBeenHere = FALSE; - - if (s_fBeenHere) - return; - s_fBeenHere = TRUE; - - ErrorF ("Welcome to the XWin X Server\n"); - ErrorF ("Vendor: %s\n", VENDOR_STRING); - ErrorF ("Release: %d.%d.%d.%d (%d)\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT); - ErrorF ("%s\n\n", BUILDERSTRING); - ErrorF ("Contact: %s\n", VENDOR_CONTACT); -} - -/* - * getMonitorInfo - callback function used to return information from the enumeration of monitors attached - */ - -wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data) -{ - struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data; - // only get data for monitor number specified in - data->monitorNum++; - if (data->monitorNum == data->requestedMonitor) - { - data->bMonitorSpecifiedExists = TRUE; - data->monitorOffsetX = rect->left; - data->monitorOffsetY = rect->top; - data->monitorHeight = rect->bottom - rect->top; - data->monitorWidth = rect->right - rect->left; - return FALSE; - } - return TRUE; -} +/* + +Copyright 1993, 1998 The Open Group +Copyright (C) Colin Harrison 2005-2008 + +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. + +*/ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif + +#include <../xfree86/common/xorgVersion.h> +#include "win.h" +#include "winconfig.h" +#include "winmsg.h" + +/* + * References to external symbols + */ + +#ifdef XWIN_CLIPBOARD +extern Bool g_fUnicodeClipboard; +extern Bool g_fClipboard; +#endif +/* globals required by callback function for monitor information */ +struct GetMonitorInfoData { + int requestedMonitor; + int monitorNum; + Bool bUserSpecifiedMonitor; + Bool bMonitorSpecifiedExists; + int monitorOffsetX; + int monitorOffsetY; + int monitorHeight; + int monitorWidth; +}; + +typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); +ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors; + +wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data); + +static Bool QueryMonitor(int index, struct GetMonitorInfoData *data) +{ + /* Load EnumDisplayMonitors from DLL */ + HMODULE user32; + FARPROC func; + user32 = LoadLibrary("user32.dll"); + if (user32 == NULL) + { + winW32Error(2, "Could not open user32.dll"); + return FALSE; + } + func = GetProcAddress(user32, "EnumDisplayMonitors"); + if (func == NULL) + { + winW32Error(2, "Could not resolve EnumDisplayMonitors: "); + return FALSE; + } + _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func; + + /* prepare data */ + if (data == NULL) + return FALSE; + memset(data, 0, sizeof(*data)); + data->requestedMonitor = index; + + /* query information */ + _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data); + + /* cleanup */ + FreeLibrary(user32); + return TRUE; +} + +/* + * Function prototypes + */ + +void +winLogCommandLine (int argc, char *argv[]); + +void +winLogVersionInfo (void); + +#ifdef DDXOSVERRORF +void OsVendorVErrorF (const char *pszFormat, va_list va_args); +#endif + +/* + * Process arguments on the command line + */ + +static int iLastScreen = -1; +static winScreenInfo defaultScreenInfo; + +static void +winInitializeScreenDefaults(void) +{ + DWORD dwWidth, dwHeight; + static Bool fInitializedScreenDefaults = FALSE; + + /* Bail out early if default screen has already been initialized */ + if (fInitializedScreenDefaults) + return; + + /* Zero the memory used for storing the screen info */ + memset(&defaultScreenInfo, 0, sizeof(winScreenInfo)); + + /* Get default width and height */ + /* + * NOTE: These defaults will cause the window to cover only + * the primary monitor in the case that we have multiple monitors. + */ + dwWidth = GetSystemMetrics (SM_CXSCREEN); + dwHeight = GetSystemMetrics (SM_CYSCREEN); + + winErrorFVerb (2, "winInitializeScreenDefaults - w %d h %d\n", + (int) dwWidth, (int) dwHeight); + + /* Set a default DPI, if no parameter was passed */ + if (monitorResolution == 0) + monitorResolution = WIN_DEFAULT_DPI; + + defaultScreenInfo.dwWidth = dwWidth; + defaultScreenInfo.dwHeight = dwHeight; + defaultScreenInfo.dwUserWidth = dwWidth; + defaultScreenInfo.dwUserHeight = dwHeight; + defaultScreenInfo.fUserGaveHeightAndWidth = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH; + defaultScreenInfo.fUserGavePosition = FALSE; + defaultScreenInfo.dwBPP = WIN_DEFAULT_BPP; + defaultScreenInfo.dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES; +#ifdef XWIN_EMULATEPSEUDO + defaultScreenInfo.fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO; +#endif + defaultScreenInfo.dwRefreshRate = WIN_DEFAULT_REFRESH; + defaultScreenInfo.pfb = NULL; + defaultScreenInfo.fFullScreen = FALSE; + defaultScreenInfo.fDecoration = TRUE; +#ifdef XWIN_MULTIWINDOWEXTWM + defaultScreenInfo.fMWExtWM = FALSE; + defaultScreenInfo.fInternalWM = FALSE; +#endif + defaultScreenInfo.fRootless = FALSE; +#ifdef XWIN_MULTIWINDOW + defaultScreenInfo.fMultiWindow = FALSE; +#endif +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + defaultScreenInfo.fMultiMonitorOverride = FALSE; +#endif + defaultScreenInfo.fMultipleMonitors = FALSE; + defaultScreenInfo.fLessPointer = FALSE; + defaultScreenInfo.fScrollbars = FALSE; + defaultScreenInfo.fNoTrayIcon = FALSE; + defaultScreenInfo.iE3BTimeout = WIN_E3B_OFF; + defaultScreenInfo.dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) * 25.4; + defaultScreenInfo.dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) * 25.4; + defaultScreenInfo.fUseWinKillKey = WIN_DEFAULT_WIN_KILL; + defaultScreenInfo.fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL; + defaultScreenInfo.fIgnoreInput = FALSE; + defaultScreenInfo.fExplicitScreen = FALSE; + + /* Note that the default screen has been initialized */ + fInitializedScreenDefaults = TRUE; +} + +static void +winInitializeScreen(int i) +{ + winErrorFVerb (2, "winInitializeScreen - %d\n",i); + + /* Initialize default screen values, if needed */ + winInitializeScreenDefaults(); + + /* Copy the default screen info */ + g_ScreenInfo[i] = defaultScreenInfo; + + /* Set the screen number */ + g_ScreenInfo[i].dwScreen = i; +} + +void +winInitializeScreens(int maxscreens) +{ + int i; + winErrorFVerb (2, "winInitializeScreens - %i\n", maxscreens); + + if (maxscreens > g_iNumScreens) + { + /* Reallocate the memory for DDX-specific screen info */ + g_ScreenInfo = realloc(g_ScreenInfo, maxscreens * sizeof (winScreenInfo)); + + /* Set default values for any new screens */ + for (i = g_iNumScreens; i < maxscreens ; i++) + winInitializeScreen(i); + + /* Keep a count of the number of screens */ + g_iNumScreens = maxscreens; + } +} + +/* See Porting Layer Definition - p. 57 */ +/* + * INPUT + * argv: pointer to an array of null-terminated strings, one for + * each token in the X Server command line; the first token + * is 'XWin.exe', or similar. + * argc: a count of the number of tokens stored in argv. + * i: a zero-based index into argv indicating the current token being + * processed. + * + * OUTPUT + * return: return the number of tokens processed correctly. + * + * NOTE + * When looking for n tokens, check that i + n is less than argc. Or, + * you may check if i is greater than or equal to argc, in which case + * you should display the UseMsg () and return 0. + */ + +/* Check if enough arguments are given for the option */ +#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; } + +/* Compare the current option with the string. */ +#define IS_OPTION(name) (strcmp (argv[i], name) == 0) + +int +ddxProcessArgument (int argc, char *argv[], int i) +{ + static Bool s_fBeenHere = FALSE; + winScreenInfo *screenInfoPtr = NULL; + + /* Initialize once */ + if (!s_fBeenHere) + { +#ifdef DDXOSVERRORF + /* + * This initialises our hook into VErrorF () for catching log messages + * that are generated before OsInit () is called. + */ + OsVendorVErrorFProc = OsVendorVErrorF; +#endif + + s_fBeenHere = TRUE; + + /* Initialize only if option is not -help */ + if (!IS_OPTION("-help") && !IS_OPTION("-h") && !IS_OPTION("--help") && + !IS_OPTION("-version") && !IS_OPTION("--version")) + { + + /* Log the version information */ + winLogVersionInfo (); + + /* Log the command line */ + winLogCommandLine (argc, argv); + + /* + * Initialize default screen settings. We have to do this before + * OsVendorInit () gets called, otherwise we will overwrite + * settings changed by parameters such as -fullscreen, etc. + */ + winErrorFVerb (2, "ddxProcessArgument - Initializing default " + "screens\n"); + winInitializeScreenDefaults(); + } + } + +#if CYGDEBUG + winDebug ("ddxProcessArgument - arg: %s\n", argv[i]); +#endif + + /* + * Look for the '-help' and similar options + */ + if (IS_OPTION ("-help") || IS_OPTION("-h") || IS_OPTION("--help")) + { + /* Reset logfile. We don't need that helpmessage in the logfile */ + g_pszLogFile = NULL; + g_fNoHelpMessageBox = TRUE; + UseMsg(); + exit (0); + return 1; + } + + if (IS_OPTION ("-version") || IS_OPTION("--version")) + { + /* Reset logfile. We don't need that versioninfo in the logfile */ + g_pszLogFile = NULL; + winLogVersionInfo (); + exit (0); + return 1; + } + + /* + * Look for the '-screen scr_num [width height]' argument + */ + if (IS_OPTION ("-screen")) + { + int iArgsProcessed = 1; + int nScreenNum; + int iWidth, iHeight, iX, iY; + int iMonitor; + +#if CYGDEBUG + winDebug ("ddxProcessArgument - screen - argc: %d i: %d\n", + argc, i); +#endif + + /* Display the usage message if the argument is malformed */ + if (i + 1 >= argc) + { + return 0; + } + + /* Grab screen number */ + nScreenNum = atoi (argv[i + 1]); + + /* Validate the specified screen number */ + if (nScreenNum < 0) + { + ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n", + nScreenNum); + UseMsg (); + return 0; + } + + /* + Initialize default values for any new screens + + Note that default values can't change after a -screen option is + seen, so it's safe to do this for each screen as it is introduced + */ + winInitializeScreens(nScreenNum+1); + + /* look for @m where m is monitor number */ + if (i + 2 < argc + && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor)) + { + struct GetMonitorInfoData data; + if (!QueryMonitor(iMonitor, &data)) + { + ErrorF ("ddxProcessArgument - screen - " + "Querying monitors is not supported on NT4 and Win95\n"); + } else if (data.bMonitorSpecifiedExists == TRUE) + { + winErrorFVerb(2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); + iArgsProcessed = 3; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; + g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; + g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth; + g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight; + g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth; + g_ScreenInfo[nScreenNum].dwUserHeight = data.monitorHeight; + g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; + g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; + } + else + { + /* monitor does not exist, error out */ + ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", + iMonitor); + UseMsg (); + exit (0); + return 0; + } + } + + /* Look for 'WxD' or 'W D' */ + else if (i + 2 < argc + && 2 == sscanf (argv[i + 2], "%dx%d", + (int *) &iWidth, + (int *) &iHeight)) + { + winErrorFVerb (2, "ddxProcessArgument - screen - Found ``WxD'' arg\n"); + iArgsProcessed = 3; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; + g_ScreenInfo[nScreenNum].dwWidth = iWidth; + g_ScreenInfo[nScreenNum].dwHeight = iHeight; + g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; + g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; + /* Look for WxD+X+Y */ + if (2 == sscanf (argv[i + 2], "%*dx%*d+%d+%d", + (int *) &iX, + (int *) &iY)) + { + winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X+Y'' arg\n"); + g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; + g_ScreenInfo[nScreenNum].dwInitialX = iX; + g_ScreenInfo[nScreenNum].dwInitialY = iY; + + /* look for WxD+X+Y@m where m is monitor number. take X,Y to be offsets from monitor's root position */ + if (1 == sscanf (argv[i + 2], "%*dx%*d+%*d+%*d@%d", + (int *) &iMonitor)) + { + struct GetMonitorInfoData data; + if (!QueryMonitor(iMonitor, &data)) + { + ErrorF ("ddxProcessArgument - screen - " + "Querying monitors is not supported on NT4 and Win95\n"); + } else if (data.bMonitorSpecifiedExists == TRUE) + { + g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX; + g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY; + } + else + { + /* monitor does not exist, error out */ + ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", + iMonitor); + UseMsg (); + exit (0); + return 0; + } + + } + } + + /* look for WxD@m where m is monitor number */ + else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d", + (int *) &iMonitor)) + { + struct GetMonitorInfoData data; + if (!QueryMonitor(iMonitor, &data)) + { + ErrorF ("ddxProcessArgument - screen - " + "Querying monitors is not supported on NT4 and Win95\n"); + } else if (data.bMonitorSpecifiedExists == TRUE) + { + winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); + g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; + g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; + g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; + } + else + { + /* monitor does not exist, error out */ + ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", + iMonitor); + UseMsg (); + exit (0); + return 0; + } + + } + } + else if (i + 3 < argc + && 1 == sscanf (argv[i + 2], "%d", + (int *) &iWidth) + && 1 == sscanf (argv[i + 3], "%d", + (int *) &iHeight)) + { + winErrorFVerb (2, "ddxProcessArgument - screen - Found ``W D'' arg\n"); + iArgsProcessed = 4; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; + g_ScreenInfo[nScreenNum].dwWidth = iWidth; + g_ScreenInfo[nScreenNum].dwHeight = iHeight; + g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; + g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; + if (i + 5 < argc + && 1 == sscanf (argv[i + 4], "%d", + (int *) &iX) + && 1 == sscanf (argv[i + 5], "%d", + (int *) &iY)) + { + winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X Y'' arg\n"); + iArgsProcessed = 6; + g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; + g_ScreenInfo[nScreenNum].dwInitialX = iX; + g_ScreenInfo[nScreenNum].dwInitialY = iY; + } + } + else + { + winErrorFVerb (2, "ddxProcessArgument - screen - Did not find size arg. " + "dwWidth: %d dwHeight: %d\n", + (int) g_ScreenInfo[nScreenNum].dwWidth, + (int) g_ScreenInfo[nScreenNum].dwHeight); + iArgsProcessed = 2; + g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; + } + + /* Calculate the screen width and height in millimeters */ + if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth) + { + g_ScreenInfo[nScreenNum].dwWidth_mm + = (g_ScreenInfo[nScreenNum].dwWidth + / monitorResolution) * 25.4; + g_ScreenInfo[nScreenNum].dwHeight_mm + = (g_ScreenInfo[nScreenNum].dwHeight + / monitorResolution) * 25.4; + } + + /* Flag that this screen was explicity specified by the user */ + g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE; + + /* + * Keep track of the last screen number seen, as parameters seen + * before a screen number apply to all screens, whereas parameters + * seen after a screen number apply to that screen number only. + */ + iLastScreen = nScreenNum; + + return iArgsProcessed; + } + + + /* + * Is this parameter attached to a screen or global? + * + * If the parameter is for all screens (appears before + * any -screen option), store it in the default screen + * info + * + * If the parameter is for a single screen (appears + * after a -screen option), store it in the screen info + * for that screen + * + */ + if (iLastScreen == -1) + { + screenInfoPtr = &defaultScreenInfo; + } + else + { + screenInfoPtr = &(g_ScreenInfo[iLastScreen]); + } + + /* + * Look for the '-engine n' argument + */ + if (IS_OPTION ("-engine")) + { + DWORD dwEngine = 0; + CARD8 c8OnBits = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwEngine = atoi (argv[i]); + + /* Count the one bits in the engine argument */ + c8OnBits = winCountBits (dwEngine); + + /* Argument should only have a single bit on */ + if (c8OnBits != 1) + { + UseMsg (); + return 0; + } + + screenInfoPtr->dwEnginePreferred = dwEngine; + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-fullscreen' argument + */ + if (IS_OPTION ("-fullscreen")) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!screenInfoPtr->fMultiMonitorOverride) + screenInfoPtr->fMultipleMonitors = FALSE; +#endif + screenInfoPtr->fFullScreen = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-lesspointer' argument + */ + if (IS_OPTION ("-lesspointer")) + { + screenInfoPtr->fLessPointer = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nodecoration' argument + */ + if (IS_OPTION ("-nodecoration")) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!screenInfoPtr->fMultiMonitorOverride) + screenInfoPtr->fMultipleMonitors = FALSE; +#endif + screenInfoPtr->fDecoration = FALSE; + + /* Indicate that we have processed this argument */ + return 1; + } + +#ifdef XWIN_MULTIWINDOWEXTWM + /* + * Look for the '-mwextwm' argument + */ + if (IS_OPTION ("-mwextwm")) + { + if (!screenInfoPtr->fMultiMonitorOverride) + screenInfoPtr->fMultipleMonitors = TRUE; + screenInfoPtr->fMWExtWM = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + /* + * Look for the '-internalwm' argument + */ + if (IS_OPTION ("-internalwm")) + { + if (!screenInfoPtr->fMultiMonitorOverride) + screenInfoPtr->fMultipleMonitors = TRUE; + screenInfoPtr->fMWExtWM = TRUE; + screenInfoPtr->fInternalWM = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + /* + * Look for the '-rootless' argument + */ + if (IS_OPTION ("-rootless")) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!screenInfoPtr->fMultiMonitorOverride) + screenInfoPtr->fMultipleMonitors = FALSE; +#endif + screenInfoPtr->fRootless = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + +#ifdef XWIN_MULTIWINDOW + /* + * Look for the '-multiwindow' argument + */ + if (IS_OPTION ("-multiwindow")) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!screenInfoPtr->fMultiMonitorOverride) + screenInfoPtr->fMultipleMonitors = TRUE; +#endif + screenInfoPtr->fMultiWindow = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + /* + * Look for the '-multiplemonitors' argument + */ + if (IS_OPTION ("-multiplemonitors") + || IS_OPTION ("-multimonitors")) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + screenInfoPtr->fMultiMonitorOverride = TRUE; +#endif + screenInfoPtr->fMultipleMonitors = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nomultiplemonitors' argument + */ + if (IS_OPTION ("-nomultiplemonitors") + || IS_OPTION ("-nomultimonitors")) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + screenInfoPtr->fMultiMonitorOverride = TRUE; +#endif + screenInfoPtr->fMultipleMonitors = FALSE; + + /* Indicate that we have processed this argument */ + return 1; + } + + + /* + * Look for the '-scrollbars' argument + */ + if (IS_OPTION ("-scrollbars")) + { + screenInfoPtr->fScrollbars = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + +#ifdef XWIN_CLIPBOARD + /* + * Look for the '-clipboard' argument + */ + if (IS_OPTION ("-clipboard")) + { + /* Now the default, we still accept the arg for backwards compatibility */ + g_fClipboard = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-noclipboard' argument + */ + if (IS_OPTION ("-noclipboard")) + { + g_fClipboard = FALSE; + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + + /* + * Look for the '-ignoreinput' argument + */ + if (IS_OPTION ("-ignoreinput")) + { + screenInfoPtr->fIgnoreInput = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-emulate3buttons' argument + */ + if (IS_OPTION ("-emulate3buttons")) + { + int iArgsProcessed = 1; + int iE3BTimeout = WIN_DEFAULT_E3B_TIME; + + /* Grab the optional timeout value */ + if (i + 1 < argc + && 1 == sscanf (argv[i + 1], "%d", + &iE3BTimeout)) + { + /* Indicate that we have processed the next argument */ + iArgsProcessed++; + } + else + { + /* + * sscanf () won't modify iE3BTimeout if it doesn't find + * the specified format; however, I want to be explicit + * about setting the default timeout in such cases to + * prevent some programs (me) from getting confused. + */ + iE3BTimeout = WIN_DEFAULT_E3B_TIME; + } + + screenInfoPtr->iE3BTimeout = iE3BTimeout; + + /* Indicate that we have processed this argument */ + return iArgsProcessed; + } + + /* + * Look for the '-depth n' argument + */ + if (IS_OPTION ("-depth")) + { + DWORD dwBPP = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwBPP = atoi (argv[i]); + + screenInfoPtr->dwBPP = dwBPP; + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-refresh n' argument + */ + if (IS_OPTION ("-refresh")) + { + DWORD dwRefreshRate = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwRefreshRate = atoi (argv[i]); + + screenInfoPtr->dwRefreshRate = dwRefreshRate; + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-clipupdates num_boxes' argument + */ + if (IS_OPTION ("-clipupdates")) + { + DWORD dwNumBoxes = 0; + + /* Display the usage message if the argument is malformed */ + if (++i >= argc) + { + UseMsg (); + return 0; + } + + /* Grab the argument */ + dwNumBoxes = atoi (argv[i]); + + screenInfoPtr->dwClipUpdatesNBoxes = dwNumBoxes; + + /* Indicate that we have processed the argument */ + return 2; + } + +#ifdef XWIN_EMULATEPSEUDO + /* + * Look for the '-emulatepseudo' argument + */ + if (IS_OPTION ("-emulatepseudo")) + { + screenInfoPtr->fEmulatePseudo = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + /* + * Look for the '-nowinkill' argument + */ + if (IS_OPTION ("-nowinkill")) + { + screenInfoPtr->fUseWinKillKey = FALSE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-winkill' argument + */ + if (IS_OPTION ("-winkill")) + { + screenInfoPtr->fUseWinKillKey = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nounixkill' argument + */ + if (IS_OPTION ("-nounixkill")) + { + screenInfoPtr->fUseUnixKillKey = FALSE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-unixkill' argument + */ + if (IS_OPTION ("-unixkill")) + { + screenInfoPtr->fUseUnixKillKey = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-notrayicon' argument + */ + if (IS_OPTION ("-notrayicon")) + { + screenInfoPtr->fNoTrayIcon = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-trayicon' argument + */ + if (IS_OPTION ("-trayicon")) + { + screenInfoPtr->fNoTrayIcon = FALSE; + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-fp' argument + */ + if (IS_OPTION ("-fp")) + { + CHECK_ARGS (1); + g_cmdline.fontPath = argv[++i]; + return 0; /* Let DIX parse this again */ + } + + /* + * Look for the '-query' argument + */ + if (IS_OPTION ("-query")) + { + CHECK_ARGS (1); + g_fXdmcpEnabled = TRUE; + g_pszQueryHost = argv[++i]; + return 0; /* Let DIX parse this again */ + } + + /* + * Look for the '-auth' argument + */ + if (IS_OPTION ("-auth")) + { + g_fAuthEnabled = TRUE; + return 0; /* Let DIX parse this again */ + } + + /* + * Look for the '-indirect' or '-broadcast' arguments + */ + if (IS_OPTION ("-indirect") + || IS_OPTION ("-broadcast")) + { + g_fXdmcpEnabled = TRUE; + return 0; /* Let DIX parse this again */ + } + + /* + * Look for the '-config' argument + */ + if (IS_OPTION ("-config") + || IS_OPTION ("-xf86config")) + { + CHECK_ARGS (1); +#ifdef XWIN_XF86CONFIG + g_cmdline.configFile = argv[++i]; +#else + winMessageBoxF ("The %s option is not supported in this " + "release.\n" + "Ignoring this option and continuing.\n", + MB_ICONINFORMATION, + argv[i]); +#endif + return 2; + } + + /* + * Look for the '-configdir' argument + */ + if (IS_OPTION ("-configdir")) + { + CHECK_ARGS (1); +#ifdef XWIN_XF86CONFIG + g_cmdline.configDir = argv[++i]; +#else + winMessageBoxF ("The %s option is not supported in this " + "release.\n" + "Ignoring this option and continuing.\n", + MB_ICONINFORMATION, + argv[i]); +#endif + return 2; + } + + /* + * Look for the '-keyboard' argument + */ + if (IS_OPTION ("-keyboard")) + { +#ifdef XWIN_XF86CONFIG + CHECK_ARGS (1); + g_cmdline.keyboard = argv[++i]; +#else + winMessageBoxF ("The -keyboard option is not supported in this " + "release.\n" + "Ignoring this option and continuing.\n", + MB_ICONINFORMATION); +#endif + return 2; + } + + /* + * Look for the '-logfile' argument + */ + if (IS_OPTION ("-logfile")) + { + CHECK_ARGS (1); + g_pszLogFile = argv[++i]; +#ifdef RELOCATE_PROJECTROOT + g_fLogFileChanged = TRUE; +#endif + return 2; + } + + /* + * Look for the '-logverbose' argument + */ + if (IS_OPTION ("-logverbose")) + { + CHECK_ARGS (1); + g_iLogVerbose = atoi(argv[++i]); + return 2; + } + +#ifdef XWIN_CLIPBOARD + /* + * Look for the '-nounicodeclipboard' argument + */ + if (IS_OPTION ("-nounicodeclipboard")) + { + g_fUnicodeClipboard = FALSE; + /* Indicate that we have processed the argument */ + return 1; + } +#endif + + if (IS_OPTION ("-xkbrules")) + { + CHECK_ARGS (1); + g_cmdline.xkbRules = argv[++i]; + return 2; + } + if (IS_OPTION ("-xkbmodel")) + { + CHECK_ARGS (1); + g_cmdline.xkbModel = argv[++i]; + return 2; + } + if (IS_OPTION ("-xkblayout")) + { + CHECK_ARGS (1); + g_cmdline.xkbLayout = argv[++i]; + return 2; + } + if (IS_OPTION ("-xkbvariant")) + { + CHECK_ARGS (1); + g_cmdline.xkbVariant = argv[++i]; + return 2; + } + if (IS_OPTION ("-xkboptions")) + { + CHECK_ARGS (1); + g_cmdline.xkbOptions = argv[++i]; + return 2; + } + + if (IS_OPTION ("-keyhook")) + { + g_fKeyboardHookLL = TRUE; + return 1; + } + + if (IS_OPTION ("-nokeyhook")) + { + g_fKeyboardHookLL = FALSE; + return 1; + } + + if (IS_OPTION ("-swcursor")) + { + g_fSoftwareCursor = TRUE; + return 1; + } + + if (IS_OPTION ("-silent-dup-error")) + { + g_fSilentDupError = TRUE; + return 1; + } + + if (IS_OPTION("-wgl")) + { + g_fNativeGl = TRUE; + return 1; + } + + if (IS_OPTION("-nowgl")) + { + g_fNativeGl = FALSE; + return 1; + } + + return 0; +} + + +/* + * winLogCommandLine - Write entire command line to the log file + */ + +void +winLogCommandLine (int argc, char *argv[]) +{ + int i; + int iSize = 0; + int iCurrLen = 0; + +#define CHARS_PER_LINE 60 + + /* Bail if command line has already been logged */ + if (g_pszCommandLine) + return; + + /* Count how much memory is needed for concatenated command line */ + for (i = 0, iCurrLen = 0; i < argc; ++i) + if (argv[i]) + { + /* Adds two characters for lines that overflow */ + if ((strlen (argv[i]) < CHARS_PER_LINE + && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE) + || strlen (argv[i]) > CHARS_PER_LINE) + { + iCurrLen = 0; + iSize += 2; + } + + /* Add space for item and trailing space */ + iSize += strlen (argv[i]) + 1; + + /* Update current line length */ + iCurrLen += strlen (argv[i]); + } + + /* Allocate memory for concatenated command line */ + g_pszCommandLine = malloc (iSize + 1); + if (!g_pszCommandLine) + FatalError ("winLogCommandLine - Could not allocate memory for " + "command line string. Exiting.\n"); + + /* Set first character to concatenated command line to null */ + g_pszCommandLine[0] = '\0'; + + /* Loop through all args */ + for (i = 0, iCurrLen = 0; i < argc; ++i) + { + /* Add a character for lines that overflow */ + if ((strlen (argv[i]) < CHARS_PER_LINE + && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE) + || strlen (argv[i]) > CHARS_PER_LINE) + { + iCurrLen = 0; + + /* Add line break if it fits */ + strncat (g_pszCommandLine, "\n ", iSize - strlen (g_pszCommandLine)); + } + + strncat (g_pszCommandLine, argv[i], iSize - strlen (g_pszCommandLine)); + strncat (g_pszCommandLine, " ", iSize - strlen (g_pszCommandLine)); + + /* Save new line length */ + iCurrLen += strlen (argv[i]); + } + + ErrorF ("XWin was started with the following command line:\n\n" + "%s\n\n", g_pszCommandLine); +} + + +/* + * winLogVersionInfo - Log Cygwin/X version information + */ + +void +winLogVersionInfo (void) +{ + static Bool s_fBeenHere = FALSE; + + if (s_fBeenHere) + return; + s_fBeenHere = TRUE; + + ErrorF ("Welcome to the XWin X Server\n"); + ErrorF ("Vendor: %s\n", XVENDORNAME); + ErrorF ("Release: %d.%d.%d.%d (%d)\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT); + ErrorF ("%s\n\n", BUILDERSTRING); + ErrorF ("Contact: %s\n", BUILDERADDR); +} + +/* + * getMonitorInfo - callback function used to return information from the enumeration of monitors attached + */ + +wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data) +{ + struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data; + // only get data for monitor number specified in + data->monitorNum++; + if (data->monitorNum == data->requestedMonitor) + { + data->bMonitorSpecifiedExists = TRUE; + data->monitorOffsetX = rect->left; + data->monitorOffsetY = rect->top; + data->monitorHeight = rect->bottom - rect->top; + data->monitorWidth = rect->right - rect->left; + return FALSE; + } + return TRUE; +} diff --git a/xorg-server/hw/xwin/winscrinit.c b/xorg-server/hw/xwin/winscrinit.c index 03d7c6014..ec46abfe2 100644 --- a/xorg-server/hw/xwin/winscrinit.c +++ b/xorg-server/hw/xwin/winscrinit.c @@ -65,14 +65,6 @@ winMWExtWMProcs = { }; #endif - -/* - * References to external symbols - */ - -extern Bool g_fSoftwareCursor; - - /* * Prototypes */ diff --git a/xorg-server/hw/xwin/winshaddd.c b/xorg-server/hw/xwin/winshaddd.c index 89122b177..ae49d5a3d 100644 --- a/xorg-server/hw/xwin/winshaddd.c +++ b/xorg-server/hw/xwin/winshaddd.c @@ -37,13 +37,6 @@ #include "win.h" -/* - * External symbols - */ - -extern HWND g_hDlgExit; -extern const char *g_pszLogFile; - /* * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, * so we have to redefine it here. @@ -55,7 +48,7 @@ extern const char *g_pszLogFile; /* - * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined + * FIXME: Headers are broken, IID_IDirectDraw2 has to be defined * here manually. Should be handled by ddraw.h */ #ifndef IID_IDirectDraw2 @@ -828,7 +821,6 @@ winInitVisualsShadowDD (ScreenPtr pScreen) case 24: case 16: case 15: -#if defined(XFree86Server) /* Create the real visual */ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, TrueColorMask, @@ -861,42 +853,9 @@ winInitVisualsShadowDD (ScreenPtr pScreen) return FALSE; } #endif -#else /* XFree86Server */ - /* Create the real visual */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " - "failed for TrueColor\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!fbSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#endif /* XFree86Server */ break; case 8: -#if defined(XFree86Server) if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, pScreenInfo->fFullScreen ? PseudoColorMask : StaticColorMask, @@ -911,20 +870,6 @@ winInitVisualsShadowDD (ScreenPtr pScreen) "failed\n"); return FALSE; } -#else /* XFree86Server */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - pScreenInfo->fFullScreen - ? PseudoColorMask : StaticColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDD - fbSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#endif /* XFree86Server */ break; default: diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index d9f0b3824..0ce5d8d85 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -37,13 +37,6 @@ #include "win.h" -/* - * External symbols - */ - -extern HWND g_hDlgExit; - - /* * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, * so we have to redefine it here. @@ -883,7 +876,6 @@ winInitVisualsShadowDDNL (ScreenPtr pScreen) case 24: case 16: case 15: -#if defined(XFree86Server) /* Setup the real visual */ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, TrueColorMask, @@ -916,42 +908,9 @@ winInitVisualsShadowDDNL (ScreenPtr pScreen) return FALSE; } #endif -#else /* XFree86Server */ - /* Setup the real visual */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDDNL - fbSetVisualTypesAndMasks " - "failed for TrueColor\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!fbSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowDDNL - fbSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#endif /* XFree86Server */ break; case 8: -#if defined(XFree86Server) if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, pScreenInfo->fFullScreen ? PseudoColorMask : StaticColorMask, @@ -966,20 +925,6 @@ winInitVisualsShadowDDNL (ScreenPtr pScreen) "failed\n"); return FALSE; } -#else /* XFree86Server */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - pScreenInfo->fFullScreen - ? PseudoColorMask : StaticColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowDDNL - fbSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#endif /* XFree86Server */ break; default: diff --git a/xorg-server/hw/xwin/winshadgdi.c b/xorg-server/hw/xwin/winshadgdi.c index d35a53909..4f36547f9 100644 --- a/xorg-server/hw/xwin/winshadgdi.c +++ b/xorg-server/hw/xwin/winshadgdi.c @@ -34,16 +34,6 @@ #include "win.h" -/* - * External symbols - */ - -#ifdef XWIN_MULTIWINDOW -extern DWORD g_dwCurrentThreadID; -#endif -extern HWND g_hDlgExit; - - /* * Local function prototypes */ @@ -715,7 +705,6 @@ winInitVisualsShadowGDI (ScreenPtr pScreen) case 24: case 16: case 15: -#if defined(XFree86Server) /* Setup the real visual */ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, TrueColorMask, @@ -748,42 +737,9 @@ winInitVisualsShadowGDI (ScreenPtr pScreen) return FALSE; } #endif -#else /* XFree86Server */ - /* Setup the real visual */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - TrueColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " - "failed for TrueColor\n"); - return FALSE; - } - -#ifdef XWIN_EMULATEPSEUDO - if (!pScreenInfo->fEmulatePseudo) - break; - - /* Setup a pseudocolor visual */ - if (!fbSetVisualTypesAndMasks (8, - PseudoColorMask, - 8, - 0, - 0, - 0)) - { - ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " - "failed for PseudoColor\n"); - return FALSE; - } -#endif -#endif /* XFree86Server */ break; case 8: -#if defined(XFree86Server) if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, PseudoColorMask, pScreenPriv->dwBitsPerRGB, @@ -796,19 +752,6 @@ winInitVisualsShadowGDI (ScreenPtr pScreen) "failed\n"); return FALSE; } -#else /* XFree86Server */ - if (!fbSetVisualTypesAndMasks (pScreenInfo->dwDepth, - PseudoColorMask, - pScreenPriv->dwBitsPerRGB, - pScreenPriv->dwRedMask, - pScreenPriv->dwGreenMask, - pScreenPriv->dwBlueMask)) - { - ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks " - "failed\n"); - return FALSE; - } -#endif break; default: diff --git a/xorg-server/hw/xwin/winvalargs.c b/xorg-server/hw/xwin/winvalargs.c index 6f8d1c994..f97bce610 100644 --- a/xorg-server/hw/xwin/winvalargs.c +++ b/xorg-server/hw/xwin/winvalargs.c @@ -1,187 +1,180 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include "winmsg.h" - - -/* - * References to external symbols - */ - -extern int g_iNumScreens; -extern winScreenInfo * g_ScreenInfo; -extern Bool g_fXdmcpEnabled; - - -/* - * Verify all screens have been explicitly specified - */ -static BOOL -isEveryScreenExplicit(void) -{ - int i; - - for (i = 0; i < g_iNumScreens; i++) - if (!g_ScreenInfo[i].fExplicitScreen) - return FALSE; - - return TRUE; -} - -/* - * winValidateArgs - Look for invalid argument combinations - */ - -Bool -winValidateArgs (void) -{ - int i; - int iMaxConsecutiveScreen = 0; - BOOL fHasNormalScreen0 = FALSE; - BOOL fImplicitScreenFound = FALSE; - - /* - * Check for a malformed set of -screen parameters. - * Examples of malformed parameters: - * XWin -screen 1 - * XWin -screen 0 -screen 2 - * XWin -screen 1 -screen 2 - */ - if (!isEveryScreenExplicit()) - { - ErrorF ("winValidateArgs - Malformed set of screen parameter(s). " - "Screens must be specified consecutively starting with " - "screen 0. That is, you cannot have only a screen 1, nor " - "could you have screen 0 and screen 2. You instead must " - "have screen 0, or screen 0 and screen 1, respectively. " - "You can specify as many screens as you want.\n"); - return FALSE; - } - - /* Loop through all screens */ - for (i = 0; i < g_iNumScreens; ++i) - { - /* - * Check for any combination of - * -multiwindow, -mwextwm, and -rootless. - */ - { - int iCount = 0; - - /* Count conflicting options */ -#ifdef XWIN_MULTIWINDOW - if (g_ScreenInfo[i].fMultiWindow) - ++iCount; -#endif -#ifdef XWIN_MULTIWINDOWEXTWM - if (g_ScreenInfo[i].fMWExtWM) - ++iCount; -#endif - if (g_ScreenInfo[i].fRootless) - ++iCount; - - /* Check if the first screen is without rootless and multiwindow */ - if (iCount == 0 && i == 0) - fHasNormalScreen0 = TRUE; - - /* Fail if two or more conflicting options */ - if (iCount > 1) - { - ErrorF ("winValidateArgs - Only one of -multiwindow, -mwextwm, " - "and -rootless can be specific at a time.\n"); - return FALSE; - } - } - - /* Check for -multiwindow or -mwextwm and Xdmcp */ - /* allow xdmcp if screen 0 is normal. */ - if (g_fXdmcpEnabled && !fHasNormalScreen0 - && (FALSE -#ifdef XWIN_MULTIWINDOW - || g_ScreenInfo[i].fMultiWindow -#endif -#ifdef XWIN_MULTIWINDOWEXTWM - || g_ScreenInfo[i].fMWExtWM -#endif - ) - ) - { - ErrorF ("winValidateArgs - Xdmcp (-query, -broadcast, or -indirect) " - "is invalid with -multiwindow or -mwextwm.\n"); - return FALSE; - } - - /* Check for -multiwindow, -mwextwm, or -rootless and fullscreen */ - if (g_ScreenInfo[i].fFullScreen - && (FALSE -#ifdef XWIN_MULTIWINDOW - || g_ScreenInfo[i].fMultiWindow -#endif -#ifdef XWIN_MULTIWINDOWEXTWM - || g_ScreenInfo[i].fMWExtWM -#endif - || g_ScreenInfo[i].fRootless) - ) - { - ErrorF ("winValidateArgs - -fullscreen is invalid with " - "-multiwindow, -mwextwm, or -rootless.\n"); - return FALSE; - } - - /* Check for !fullscreen and any fullscreen-only parameters */ - if (!g_ScreenInfo[i].fFullScreen - && (g_ScreenInfo[i].dwRefreshRate != WIN_DEFAULT_BPP - || g_ScreenInfo[i].dwBPP != WIN_DEFAULT_REFRESH)) - { - ErrorF ("winValidateArgs - -refresh and -depth are only valid " - "with -fullscreen.\n"); - return FALSE; - } - - /* Check for fullscreen and any non-fullscreen parameters */ - if (g_ScreenInfo[i].fFullScreen - && (g_ScreenInfo[i].fScrollbars - || !g_ScreenInfo[i].fDecoration - || g_ScreenInfo[i].fLessPointer)) - { - ErrorF ("winValidateArgs - -fullscreen is invalid with " - "-scrollbars, -nodecoration, or -lesspointer.\n"); - return FALSE; - } - } - - winDebug ("winValidateArgs - Returning.\n"); - - return TRUE; -} +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include "winmsg.h" + + + + +/* + * Verify all screens have been explicitly specified + */ +static BOOL +isEveryScreenExplicit(void) +{ + int i; + + for (i = 0; i < g_iNumScreens; i++) + if (!g_ScreenInfo[i].fExplicitScreen) + return FALSE; + + return TRUE; +} + +/* + * winValidateArgs - Look for invalid argument combinations + */ + +Bool +winValidateArgs (void) +{ + int i; + int iMaxConsecutiveScreen = 0; + BOOL fHasNormalScreen0 = FALSE; + BOOL fImplicitScreenFound = FALSE; + + /* + * Check for a malformed set of -screen parameters. + * Examples of malformed parameters: + * XWin -screen 1 + * XWin -screen 0 -screen 2 + * XWin -screen 1 -screen 2 + */ + if (!isEveryScreenExplicit()) + { + ErrorF ("winValidateArgs - Malformed set of screen parameter(s). " + "Screens must be specified consecutively starting with " + "screen 0. That is, you cannot have only a screen 1, nor " + "could you have screen 0 and screen 2. You instead must " + "have screen 0, or screen 0 and screen 1, respectively. " + "You can specify as many screens as you want.\n"); + return FALSE; + } + + /* Loop through all screens */ + for (i = 0; i < g_iNumScreens; ++i) + { + /* + * Check for any combination of + * -multiwindow, -mwextwm, and -rootless. + */ + { + int iCount = 0; + + /* Count conflicting options */ +#ifdef XWIN_MULTIWINDOW + if (g_ScreenInfo[i].fMultiWindow) + ++iCount; +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + if (g_ScreenInfo[i].fMWExtWM) + ++iCount; +#endif + if (g_ScreenInfo[i].fRootless) + ++iCount; + + /* Check if the first screen is without rootless and multiwindow */ + if (iCount == 0 && i == 0) + fHasNormalScreen0 = TRUE; + + /* Fail if two or more conflicting options */ + if (iCount > 1) + { + ErrorF ("winValidateArgs - Only one of -multiwindow, -mwextwm, " + "and -rootless can be specific at a time.\n"); + return FALSE; + } + } + + /* Check for -multiwindow or -mwextwm and Xdmcp */ + /* allow xdmcp if screen 0 is normal. */ + if (g_fXdmcpEnabled && !fHasNormalScreen0 + && (FALSE +#ifdef XWIN_MULTIWINDOW + || g_ScreenInfo[i].fMultiWindow +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + || g_ScreenInfo[i].fMWExtWM +#endif + ) + ) + { + ErrorF ("winValidateArgs - Xdmcp (-query, -broadcast, or -indirect) " + "is invalid with -multiwindow or -mwextwm.\n"); + return FALSE; + } + + /* Check for -multiwindow, -mwextwm, or -rootless and fullscreen */ + if (g_ScreenInfo[i].fFullScreen + && (FALSE +#ifdef XWIN_MULTIWINDOW + || g_ScreenInfo[i].fMultiWindow +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + || g_ScreenInfo[i].fMWExtWM +#endif + || g_ScreenInfo[i].fRootless) + ) + { + ErrorF ("winValidateArgs - -fullscreen is invalid with " + "-multiwindow, -mwextwm, or -rootless.\n"); + return FALSE; + } + + /* Check for !fullscreen and any fullscreen-only parameters */ + if (!g_ScreenInfo[i].fFullScreen + && (g_ScreenInfo[i].dwRefreshRate != WIN_DEFAULT_BPP + || g_ScreenInfo[i].dwBPP != WIN_DEFAULT_REFRESH)) + { + ErrorF ("winValidateArgs - -refresh and -depth are only valid " + "with -fullscreen.\n"); + return FALSE; + } + + /* Check for fullscreen and any non-fullscreen parameters */ + if (g_ScreenInfo[i].fFullScreen + && (g_ScreenInfo[i].fScrollbars + || !g_ScreenInfo[i].fDecoration + || g_ScreenInfo[i].fLessPointer)) + { + ErrorF ("winValidateArgs - -fullscreen is invalid with " + "-scrollbars, -nodecoration, or -lesspointer.\n"); + return FALSE; + } + } + + winDebug ("winValidateArgs - Returning.\n"); + + return TRUE; +} diff --git a/xorg-server/hw/xwin/winwakeup.c b/xorg-server/hw/xwin/winwakeup.c index e1eece34a..64c202fed 100644 --- a/xorg-server/hw/xwin/winwakeup.c +++ b/xorg-server/hw/xwin/winwakeup.c @@ -1,71 +1,61 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" - - -/* - * References to external symbols - */ - -extern HWND g_hDlgDepthChange; -extern HWND g_hDlgExit; -extern HWND g_hDlgAbout; - - -/* See Porting Layer Definition - p. 7 */ -void -winWakeupHandler (int nScreen, - pointer pWakeupData, - unsigned long ulResult, - pointer pReadmask) -{ - MSG msg; - - /* Process all messages on our queue */ - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) - { - if ((g_hDlgDepthChange == 0 - || !IsDialogMessage (g_hDlgDepthChange, &msg)) - && (g_hDlgExit == 0 - || !IsDialogMessage (g_hDlgExit, &msg)) - && (g_hDlgAbout == 0 - || !IsDialogMessage (g_hDlgAbout, &msg))) - { - DispatchMessage (&msg); - } - } -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + +/* See Porting Layer Definition - p. 7 */ +void +winWakeupHandler (int nScreen, + pointer pWakeupData, + unsigned long ulResult, + pointer pReadmask) +{ + MSG msg; + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if ((g_hDlgDepthChange == 0 + || !IsDialogMessage (g_hDlgDepthChange, &msg)) + && (g_hDlgExit == 0 + || !IsDialogMessage (g_hDlgExit, &msg)) + && (g_hDlgAbout == 0 + || !IsDialogMessage (g_hDlgAbout, &msg))) + { + DispatchMessage (&msg); + } + } +} diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index 92c7ca500..5049e40b5 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -41,7 +41,6 @@ #include #include "dixevents.h" #include "winmultiwindowclass.h" -#include "winprefs.h" #include diff --git a/xorg-server/hw/xwin/winwin32rootlesswndproc.c b/xorg-server/hw/xwin/winwin32rootlesswndproc.c index 4d7afee42..47a1abe73 100644 --- a/xorg-server/hw/xwin/winwin32rootlesswndproc.c +++ b/xorg-server/hw/xwin/winwin32rootlesswndproc.c @@ -1,1339 +1,1331 @@ -/* - *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 - */ -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include -#define _WINDOWSWM_SERVER_ -#include -#include "dixevents.h" -#include "propertyst.h" -#include -#include "winmultiwindowclass.h" -#include "winmsg.h" -#include "inputstr.h" - - -/* - * Constant defines - */ - -#define MOUSE_ACTIVATE_DEFAULT TRUE -#define RAISE_ON_CLICK_DEFAULT FALSE - - -/* - * Global variables - */ - -extern Bool g_fNoConfigureWindow; -extern Bool g_fSoftwareCursor; - - -/* - * Local globals - */ - -static UINT_PTR g_uipMousePollingTimerID = 0; - - -/* - * Local function - */ - -DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK) -DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE) -/* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */ - -/* - * 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) - { - ErrorF ("Invalid input checking\n"); - return FALSE; - } - - /* No size hints, no checking */ - if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) - { - ErrorF ("No size hints, no checking\n"); - 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; -} - - -/* - * IsRaiseOnClick - */ - -static Bool -IsRaiseOnClick (WindowPtr pWin) -{ - - struct _Window *pwin; - struct _Property *prop; - /* XXX We're getting inputInfo.poniter here, but this might be really wrong. - * Which pointer's current window do we want? */ - WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer); - - if (!pWin) - { - ErrorF ("IsRaiseOnClick - no prop use default value:%d\n", - RAISE_ON_CLICK_DEFAULT); - return RAISE_ON_CLICK_DEFAULT; - } - - pwin = (struct _Window*) pWin; - - if (pwin->optional) - prop = (struct _Property *) pwin->optional->userProps; - else - prop = NULL; - - while (prop) - { - if (prop->propertyName == AtmWindowsWmRaiseOnClick () - && prop->type == XA_INTEGER - && prop->format == 32) - { - return *(int*)prop->data; - } - else - prop = prop->next; - } - - if (pWin != pRoot) - { - return IsRaiseOnClick (pRoot); - } - else - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("IsRaiseOnClick - no prop use default value:%d\n", - RAISE_ON_CLICK_DEFAULT); -#endif - return RAISE_ON_CLICK_DEFAULT; - } -} - - -/* - * IsMouseActive - */ - -static Bool -IsMouseActive (WindowPtr pWin) -{ - - struct _Window *pwin; - struct _Property *prop; - /* XXX We're getting inputInfo.poniter here, but this might be really wrong. - * Which pointer's current window do we want? */ - WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer); - - if (!pWin) - { - ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n", - MOUSE_ACTIVATE_DEFAULT); - return MOUSE_ACTIVATE_DEFAULT; - } - - pwin = (struct _Window*) pWin; - - if (pwin->optional) - prop = (struct _Property *) pwin->optional->userProps; - else - prop = NULL; - - while (prop) - { - if (prop->propertyName == AtmWindowsWMMouseActivate () - && prop->type == XA_INTEGER - && prop->format == 32) - { - return *(int*)prop->data; - } - else - prop = prop->next; - } - - if (pWin != pRoot) - { - return IsMouseActive (pRoot); - } - else - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("IsMouseActive - no prop use default value:%d\n", - MOUSE_ACTIVATE_DEFAULT); -#endif - return MOUSE_ACTIVATE_DEFAULT; - } -} - - -/* - * winMWExtWMWindowProc - Window procedure - */ - -LRESULT CALLBACK -winMWExtWMWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - WindowPtr pWin = NULL; - win32RootlessWindowPtr pRLWinPriv = NULL; - ScreenPtr pScreen = NULL; - winPrivScreenPtr pScreenPriv = NULL; - winScreenInfo *pScreenInfo = NULL; - HWND hwndScreen = NULL; - POINT ptMouse; - static Bool s_fTracking = FALSE; - HDC hdcUpdate; - PAINTSTRUCT ps; - LPWINDOWPOS pWinPos = NULL; - RECT rcClient; - winWMMessageRec wmMsg; - Bool fWMMsgInitialized = FALSE; - - /* Check if the Windows window property for our X window pointer is valid */ - if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) - { - pWin = pRLWinPriv->pFrame->win; - pScreen = pWin->drawable.pScreen; - if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); - if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; - if (pScreenPriv) hwndScreen = pScreenPriv->hwndScreen; - - wmMsg.msg = 0; - wmMsg.hwndWindow = hwnd; - wmMsg.iWindow = (Window)pWin->drawable.id; - - wmMsg.iX = pRLWinPriv->pFrame->x; - wmMsg.iY = pRLWinPriv->pFrame->y; - wmMsg.iWidth = pRLWinPriv->pFrame->width; - wmMsg.iHeight = pRLWinPriv->pFrame->height; - - fWMMsgInitialized = TRUE; -#if CYGDEBUG - winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam); - - winDebug ("\thWnd %08X\n", hwnd); - winDebug ("\tpScreenPriv %08X\n", pScreenPriv); - winDebug ("\tpScreenInfo %08X\n", pScreenInfo); - winDebug ("\thwndScreen %08X\n", hwndScreen); - winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n", - pRLWinPriv, message, wParam, lParam); -#endif - } - /* Branch on message type */ - switch (message) - { - case WM_CREATE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_CREATE\n"); -#endif - /* */ - SetProp (hwnd, - WIN_WINDOW_PROP, - (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); - return 0; - - case WM_CLOSE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose); -#endif - /* Tell window-manager to close window */ - if (pRLWinPriv->fClose) - { - DestroyWindow (hwnd); - } - else - { - if (winIsInternalWMRunning(pScreenInfo)) - { - /* Tell our Window Manager thread to kill the window */ - wmMsg.msg = WM_WM_KILL; - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMCloseWindow, - pWin->drawable.id, - 0, 0, 0, 0); - } - return 0; - - case WM_DESTROY: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_DESTROY\n"); -#endif - /* Free the shaodw DC; which allows the bitmap to be freed */ - DeleteDC (pRLWinPriv->hdcShadow); - pRLWinPriv->hdcShadow = NULL; - - /* Free the shadow bitmap */ - DeleteObject (pRLWinPriv->hbmpShadow); - pRLWinPriv->hbmpShadow = NULL; - - /* Free the screen DC */ - ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen); - pRLWinPriv->hdcScreen = NULL; - - /* Free shadow buffer info header */ - free (pRLWinPriv->pbmihShadow); - pRLWinPriv->pbmihShadow = NULL; - - pRLWinPriv->fResized = FALSE; - pRLWinPriv->pfb = NULL; - free (pRLWinPriv); - RemoveProp (hwnd, WIN_WINDOW_PROP); - break; - - case WM_MOUSEMOVE: -#if CYGMULTIWINDOW_DEBUG && 0 - winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n"); -#endif - /* Unpack the client area mouse coordinates */ - ptMouse.x = GET_X_LPARAM(lParam); - ptMouse.y = GET_Y_LPARAM(lParam); - - /* Translate the client area mouse coordinates to screen coordinates */ - ClientToScreen (hwnd, &ptMouse); - - /* 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 (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - - /* Has the mouse pointer crossed screens? */ - if (pScreen != miPointerGetScreen(inputInfo.pointer)) - miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen, - ptMouse.x - pScreenInfo->dwXOffset, - ptMouse.y - 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 ("winMWExtWMWindowProc - _TrackMouseEvent failed\n"); - - /* Flag that we are tracking now */ - s_fTracking = TRUE; - } - - /* Kill the timer used to poll mouse events */ - if (g_uipMousePollingTimerID != 0) - { - KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); - g_uipMousePollingTimerID = 0; - } - - /* Deliver absolute cursor position to X Server */ - winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset, - ptMouse.y - pScreenInfo->dwYOffset); - - return 0; - - case WM_NCMOUSEMOVE: -#if CYGMULTIWINDOW_DEBUG && 0 - winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n"); -#endif - /* - * 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 (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - - /* - * Timer to poll mouse events. This is needed to make - * programs like xeyes follow the mouse properly. - */ - if (g_uipMousePollingTimerID == 0) - g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen, - WIN_POLLING_MOUSE_TIMER_ID, - MOUSE_POLLING_INTERVAL, - NULL); - break; - - case WM_MOUSELEAVE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n"); -#endif - /* Mouse has left our client area */ - - /* Flag that we are no longer tracking */ - s_fTracking = FALSE; - - /* - * Timer to poll mouse events. This is needed to make - * programs like xeyes follow the mouse properly. - */ - if (g_uipMousePollingTimerID == 0) - g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen, - WIN_POLLING_MOUSE_TIMER_ID, - MOUSE_POLLING_INTERVAL, - NULL); - return 0; - - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n"); -#endif - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - SetCapture (hwnd); - return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam); - - case WM_LBUTTONUP: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n"); -#endif - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - ReleaseCapture (); - return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam); - - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n"); -#endif - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - SetCapture (hwnd); - return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam); - - case WM_MBUTTONUP: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n"); -#endif - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - ReleaseCapture (); - return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam); - - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n"); -#endif - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - SetCapture (hwnd); - return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam); - - case WM_RBUTTONUP: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n"); -#endif - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - ReleaseCapture (); - return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam); - - case WM_XBUTTONDBLCLK: - case WM_XBUTTONDOWN: - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - SetCapture (hwnd); - return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); - case WM_XBUTTONUP: - if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) - break; - ReleaseCapture (); - return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); - - case WM_MOUSEWHEEL: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - case WM_MOUSEACTIVATE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n"); -#endif -#if 1 - /* Check if this window needs to be made active when clicked */ - if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - " - "MA_NOACTIVATE\n"); -#endif - - /* */ - return MA_NOACTIVATE; - } -#endif - if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin)) - return MA_NOACTIVATE; - - break; - - 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 - winDebug ("winMWExtWMWindowProc - 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 - winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - case WM_HOTKEY: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n"); -#endif - - /* Pass the message to the root window */ - SendMessage (hwndScreen, message, wParam, lParam); - return 0; - - case WM_ERASEBKGND: -#if CYGDEBUG - winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n"); -#endif - /* - * Pretend that we did erase the background but we don't care, - * since we repaint the entire region anyhow - * This avoids some flickering when resizing. - */ - return TRUE; - - case WM_PAINT: - - /* BeginPaint gives us an hdc that clips to the invalidated region */ - hdcUpdate = BeginPaint (hwnd, &ps); - - /* Try to copy from the shadow buffer */ - if (!BitBlt (hdcUpdate, - ps.rcPaint.left, ps.rcPaint.top, - ps.rcPaint.right - ps.rcPaint.left, - ps.rcPaint.bottom - ps.rcPaint.top, - pRLWinPriv->hdcShadow, - ps.rcPaint.left, ps.rcPaint.top, - 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 ("winMWExtWMWindowProc - BitBlt failed: %s\n", - (LPSTR)lpMsgBuf); - LocalFree (lpMsgBuf); - } - - /* EndPaint frees the DC */ - EndPaint (hwnd, &ps); - break; - - case WM_ACTIVATE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n"); -#endif - if (LOWORD(wParam) != WA_INACTIVE) - { - if (winIsInternalWMRunning(pScreenInfo)) - { -#if 0 - /* Raise the window to the top in Z order */ - wmMsg.msg = WM_WM_RAISE; - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); -#endif - /* Tell our Window Manager thread to activate the window */ - wmMsg.msg = WM_WM_ACTIVATE; - if (fWMMsgInitialized) - if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMActivateWindow, - pWin->drawable.id, - 0, 0, - 0, 0); - } - return 0; - -#if 1 - case WM_WINDOWPOSCHANGING: - pWinPos = (LPWINDOWPOS)lParam; - if (!(pWinPos->flags & SWP_NOZORDER)) - { - if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv); -#endif - break; - } - - if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin)) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv); -#endif - break; - } - -#if CYGMULTIWINDOW_DEBUG - winDebug ("Win %08x forbid to change z order (%08x).\n", - (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter); -#endif - pWinPos->flags |= SWP_NOZORDER; - } - break; -#endif - - case WM_MOVE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n", - (unsigned int)GetTickCount ()); -#endif - if (g_fNoConfigureWindow) break; -#if 0 - /* Bail if Windows window is not actually moving */ - if (pRLWinPriv->dwX == (short) LOWORD(lParam) - && pRLWinPriv->dwY == (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; - } -#endif - -#if CYGMULTIWINDOW_DEBUG - winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam)); -#endif - if (!pRLWinPriv->fMovingOrSizing) - { - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMMoveXWindow (pWin, - (LOWORD(lParam) - wBorderWidth (pWin) - - GetSystemMetrics (SM_XVIRTUALSCREEN)), - (HIWORD(lParam) - wBorderWidth (pWin) - - GetSystemMetrics (SM_YVIRTUALSCREEN))); - } - return 0; - - case WM_SHOWWINDOW: -#if CYGMULTIWINDOW_DEBUG || TRUE - winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n", - (unsigned int)GetTickCount ()); -#endif - /* Bail out if the window is being hidden */ - if (!wParam) - return 0; - - if (!pScreenInfo->fInternalWM)//XXXX - return 0; - - winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo); - - if (winIsInternalWMRunning(pScreenInfo)) - { -#if CYGMULTIWINDOW_DEBUG || TRUE - winDebug ("\tMapWindow\n"); -#endif - /* Tell X to map the window */ - MapWindow (pWin, wClient(pWin)); - - if (!pRLWinPriv->pFrame->win->overrideRedirect) - /* Bring the Windows window to the foreground */ - SetForegroundWindow (hwnd); - - /* Setup the Window Manager message */ - wmMsg.msg = WM_WM_MAP; - wmMsg.iWidth = pRLWinPriv->pFrame->width; - wmMsg.iHeight = pRLWinPriv->pFrame->height; - - /* Tell our Window Manager thread to map the window */ - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } - break; - - 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: - { - pWinPos = (LPWINDOWPOS) lParam; -#if CYGMULTIWINDOW_DEBUG - winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n"); - winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n", - (pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"", - (pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"", - (pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"", - (pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"", - (pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"", - (pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"", - (pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"", - (pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"", - (pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"", - (pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"", - (pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"", - (pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":""); - winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No")); - winDebug("\textend: (%d, %d, %d, %d)\n", - pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy); - -#endif - if (pWinPos->flags & SWP_HIDEWINDOW) break; - - /* Reorder if window z order was changed */ - if ((pScreenPriv != NULL) - && !(pWinPos->flags & SWP_NOZORDER) - && !(pWinPos->flags & SWP_SHOWWINDOW) - && winIsInternalWMRunning(pScreenInfo)) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\twindow z order was changed\n"); -#endif - if (pWinPos->hwndInsertAfter == HWND_TOP - ||pWinPos->hwndInsertAfter == HWND_TOPMOST - ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\traise to top\n"); -#endif - /* Raise the window to the top in Z order */ - wmMsg.msg = WM_WM_RAISE; - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } -#if 1 - else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) - { - } - else - { - /* Check if this window is top of X windows. */ - HWND hWndAbove = NULL; - DWORD dwCurrentProcessID = GetCurrentProcessId (); - DWORD dwWindowProcessID = 0; - - for (hWndAbove = pWinPos->hwndInsertAfter; - hWndAbove != NULL; - hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) - { - /* Ignore other XWin process's window */ - GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); - - if ((dwWindowProcessID == dwCurrentProcessID) - && GetProp (hWndAbove, WIN_WINDOW_PROP) - && !IsWindowVisible (hWndAbove) - && !IsIconic (hWndAbove) ) /* ignore minimized windows */ - break; - } - /* If this is top of X windows in Windows stack, - raise it in X stack. */ - if (hWndAbove == NULL) - { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\traise to top\n"); -#endif - /* Raise the window to the top in Z order */ - wmMsg.msg = WM_WM_RAISE; - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } - } -#endif - } - - if (!(pWinPos->flags & SWP_NOSIZE)) { - if (IsIconic(hwnd)){ -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tIconic -> MINIMIZED\n"); -#endif - if (winIsInternalWMRunning(pScreenInfo)) - { - /* Raise the window to the top in Z order */ - wmMsg.msg = WM_WM_LOWER; - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMMinimizeWindow, - pWin->drawable.id, - 0, 0, 0, 0); - } else if (IsZoomed(hwnd)){ -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tZoomed -> MAXIMIZED\n"); -#endif - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMMaximizeWindow, - pWin->drawable.id, - 0, 0, 0, 0); - } else { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tnone -> RESTORED\n"); -#endif - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMRestoreWindow, - pWin->drawable.id, - 0, 0, 0, 0); - } - } - if (!g_fNoConfigureWindow ) { - - if (!pRLWinPriv->fMovingOrSizing - /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) { - GetClientRect (hwnd, &rcClient); - MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); - - if (!(pWinPos->flags & SWP_NOMOVE) - &&!(pWinPos->flags & SWP_NOSIZE)) { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tmove & resize\n"); -#endif - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMMoveResizeXWindow (pWin, - rcClient.left - wBorderWidth (pWin) - - GetSystemMetrics (SM_XVIRTUALSCREEN), - rcClient.top - wBorderWidth (pWin) - - GetSystemMetrics (SM_YVIRTUALSCREEN), - rcClient.right - rcClient.left - - wBorderWidth (pWin)*2, - rcClient.bottom - rcClient.top - - wBorderWidth (pWin)*2); - } else if (!(pWinPos->flags & SWP_NOMOVE)) { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tmove\n"); -#endif - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMMoveResizeXWindow (pWin, - rcClient.left - wBorderWidth (pWin) - - GetSystemMetrics (SM_XVIRTUALSCREEN), - rcClient.top - wBorderWidth (pWin) - - GetSystemMetrics (SM_YVIRTUALSCREEN), - rcClient.right - rcClient.left - - wBorderWidth (pWin)*2, - rcClient.bottom - rcClient.top - - wBorderWidth (pWin)*2); - } else if (!(pWinPos->flags & SWP_NOMOVE)) { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tmove\n"); -#endif - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMMoveXWindow (pWin, - rcClient.left - wBorderWidth (pWin) - - GetSystemMetrics (SM_XVIRTUALSCREEN), - rcClient.top - wBorderWidth (pWin) - - GetSystemMetrics (SM_YVIRTUALSCREEN)); - } else if (!(pWinPos->flags & SWP_NOSIZE)) { -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tresize\n"); -#endif - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMResizeXWindow (pWin, - rcClient.right - rcClient.left - - wBorderWidth (pWin)*2, - rcClient.bottom - rcClient.top - - wBorderWidth (pWin)*2); - } - } - } - } -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n"); -#endif - return 0; - - case WM_SIZE: - /* see dix/window.c */ - /* FIXME: Maximize/Restore? */ -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n", - (unsigned int)GetTickCount ()); -#endif -#if CYGMULTIWINDOW_DEBUG - winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow); -#endif - if (g_fNoConfigureWindow) break; - - /* Branch on type of resizing occurring */ - switch (wParam) - { - case SIZE_MINIMIZED: -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tSIZE_MINIMIZED\n"); -#endif - if (winIsInternalWMRunning(pScreenInfo)) - { - /* Raise the window to the top in Z order */ - wmMsg.msg = WM_WM_LOWER; - if (fWMMsgInitialized) - winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); - } - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMMinimizeWindow, - pWin->drawable.id, - 0, 0, - LOWORD(lParam), HIWORD(lParam)); - break; - - case SIZE_RESTORED: -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tSIZE_RESTORED\n"); -#endif - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMRestoreWindow, - pWin->drawable.id, - 0, 0, - LOWORD(lParam), HIWORD(lParam)); - break; - - case SIZE_MAXIMIZED: -#if CYGMULTIWINDOW_DEBUG - winDebug ("\tSIZE_MAXIMIZED\n"); -#endif - winWindowsWMSendEvent(WindowsWMControllerNotify, - WindowsWMControllerNotifyMask, - 1, - WindowsWMMaximizeWindow, - pWin->drawable.id, - 0, 0, - LOWORD(lParam), HIWORD(lParam)); - break; - } - - /* Perform the resize and notify the X client */ - if (!pRLWinPriv->fMovingOrSizing) - { - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMResizeXWindow (pWin, - (short) LOWORD(lParam) - - wBorderWidth (pWin)*2, - (short) HIWORD(lParam) - - wBorderWidth (pWin)*2); - } - break; - - case WM_ACTIVATEAPP: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n", - (unsigned int)GetTickCount ()); -#endif - if (wParam) - { - if (winIsInternalWMRunning(pScreenInfo)) - { - } - else - { - } - winWindowsWMSendEvent(WindowsWMActivationNotify, - WindowsWMActivationNotifyMask, - 1, - WindowsWMIsActive, - pWin->drawable.id, - 0, 0, - 0, 0); - } - else - { - winWindowsWMSendEvent(WindowsWMActivationNotify, - WindowsWMActivationNotifyMask, - 1, - WindowsWMIsInactive, - pWin->drawable.id, - 0, 0, - 0, 0); - } - break; - - case WM_SETCURSOR: - if (LOWORD(lParam) == HTCLIENT) - { - if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle); - return TRUE; - } - break; - - case WM_ENTERSIZEMOVE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n", - (unsigned int)GetTickCount ()); -#endif - pRLWinPriv->fMovingOrSizing = TRUE; - break; - - case WM_EXITSIZEMOVE: -#if CYGMULTIWINDOW_DEBUG - winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n", - (unsigned int)GetTickCount ()); -#endif - pRLWinPriv->fMovingOrSizing = FALSE; - - GetClientRect (hwnd, &rcClient); - - MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); - - if (winIsInternalWMRunning(pScreenInfo)) - winAdjustXWindow (pWin, hwnd); - - winMWExtWMMoveResizeXWindow (pWin, - rcClient.left - wBorderWidth (pWin) - - GetSystemMetrics (SM_XVIRTUALSCREEN), - rcClient.top - wBorderWidth (pWin) - - GetSystemMetrics (SM_YVIRTUALSCREEN), - rcClient.right - rcClient.left - - wBorderWidth (pWin)*2, - rcClient.bottom - rcClient.top - - wBorderWidth (pWin)*2); - break; - - case WM_MANAGE: - ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n"); - break; - - case WM_UNMANAGE: - ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n"); - break; - - default: - break; - } - - return DefWindowProc (hwnd, message, wParam, lParam); -} +/* + *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 + */ +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include +#define _WINDOWSWM_SERVER_ +#include +#include "dixevents.h" +#include "propertyst.h" +#include +#include "winmultiwindowclass.h" +#include "winmsg.h" +#include "inputstr.h" + + +/* + * Constant defines + */ + +#define MOUSE_ACTIVATE_DEFAULT TRUE +#define RAISE_ON_CLICK_DEFAULT FALSE + + +/* + * Local globals + */ + +static UINT_PTR g_uipMousePollingTimerID = 0; + + +/* + * Local function + */ + +DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK) +DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE) +/* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */ + +/* + * 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) + { + ErrorF ("Invalid input checking\n"); + return FALSE; + } + + /* No size hints, no checking */ + if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints)) + { + ErrorF ("No size hints, no checking\n"); + 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; +} + + +/* + * IsRaiseOnClick + */ + +static Bool +IsRaiseOnClick (WindowPtr pWin) +{ + + struct _Window *pwin; + struct _Property *prop; + /* XXX We're getting inputInfo.poniter here, but this might be really wrong. + * Which pointer's current window do we want? */ + WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer); + + if (!pWin) + { + ErrorF ("IsRaiseOnClick - no prop use default value:%d\n", + RAISE_ON_CLICK_DEFAULT); + return RAISE_ON_CLICK_DEFAULT; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + while (prop) + { + if (prop->propertyName == AtmWindowsWmRaiseOnClick () + && prop->type == XA_INTEGER + && prop->format == 32) + { + return *(int*)prop->data; + } + else + prop = prop->next; + } + + if (pWin != pRoot) + { + return IsRaiseOnClick (pRoot); + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("IsRaiseOnClick - no prop use default value:%d\n", + RAISE_ON_CLICK_DEFAULT); +#endif + return RAISE_ON_CLICK_DEFAULT; + } +} + + +/* + * IsMouseActive + */ + +static Bool +IsMouseActive (WindowPtr pWin) +{ + + struct _Window *pwin; + struct _Property *prop; + /* XXX We're getting inputInfo.poniter here, but this might be really wrong. + * Which pointer's current window do we want? */ + WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer); + + if (!pWin) + { + ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n", + MOUSE_ACTIVATE_DEFAULT); + return MOUSE_ACTIVATE_DEFAULT; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + while (prop) + { + if (prop->propertyName == AtmWindowsWMMouseActivate () + && prop->type == XA_INTEGER + && prop->format == 32) + { + return *(int*)prop->data; + } + else + prop = prop->next; + } + + if (pWin != pRoot) + { + return IsMouseActive (pRoot); + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("IsMouseActive - no prop use default value:%d\n", + MOUSE_ACTIVATE_DEFAULT); +#endif + return MOUSE_ACTIVATE_DEFAULT; + } +} + + +/* + * winMWExtWMWindowProc - Window procedure + */ + +LRESULT CALLBACK +winMWExtWMWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + WindowPtr pWin = NULL; + win32RootlessWindowPtr pRLWinPriv = NULL; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + HWND hwndScreen = NULL; + POINT ptMouse; + static Bool s_fTracking = FALSE; + HDC hdcUpdate; + PAINTSTRUCT ps; + LPWINDOWPOS pWinPos = NULL; + RECT rcClient; + winWMMessageRec wmMsg; + Bool fWMMsgInitialized = FALSE; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + pWin = pRLWinPriv->pFrame->win; + pScreen = pWin->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + if (pScreenPriv) hwndScreen = pScreenPriv->hwndScreen; + + wmMsg.msg = 0; + wmMsg.hwndWindow = hwnd; + wmMsg.iWindow = (Window)pWin->drawable.id; + + wmMsg.iX = pRLWinPriv->pFrame->x; + wmMsg.iY = pRLWinPriv->pFrame->y; + wmMsg.iWidth = pRLWinPriv->pFrame->width; + wmMsg.iHeight = pRLWinPriv->pFrame->height; + + fWMMsgInitialized = TRUE; +#if CYGDEBUG + winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam); + + winDebug ("\thWnd %08X\n", hwnd); + winDebug ("\tpScreenPriv %08X\n", pScreenPriv); + winDebug ("\tpScreenInfo %08X\n", pScreenInfo); + winDebug ("\thwndScreen %08X\n", hwndScreen); + winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n", + pRLWinPriv, message, wParam, lParam); +#endif + } + /* Branch on message type */ + switch (message) + { + case WM_CREATE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_CREATE\n"); +#endif + /* */ + SetProp (hwnd, + WIN_WINDOW_PROP, + (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams); + return 0; + + case WM_CLOSE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose); +#endif + /* Tell window-manager to close window */ + if (pRLWinPriv->fClose) + { + DestroyWindow (hwnd); + } + else + { + if (winIsInternalWMRunning(pScreenInfo)) + { + /* Tell our Window Manager thread to kill the window */ + wmMsg.msg = WM_WM_KILL; + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMCloseWindow, + pWin->drawable.id, + 0, 0, 0, 0); + } + return 0; + + case WM_DESTROY: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_DESTROY\n"); +#endif + /* Free the shaodw DC; which allows the bitmap to be freed */ + DeleteDC (pRLWinPriv->hdcShadow); + pRLWinPriv->hdcShadow = NULL; + + /* Free the shadow bitmap */ + DeleteObject (pRLWinPriv->hbmpShadow); + pRLWinPriv->hbmpShadow = NULL; + + /* Free the screen DC */ + ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen); + pRLWinPriv->hdcScreen = NULL; + + /* Free shadow buffer info header */ + free (pRLWinPriv->pbmihShadow); + pRLWinPriv->pbmihShadow = NULL; + + pRLWinPriv->fResized = FALSE; + pRLWinPriv->pfb = NULL; + free (pRLWinPriv); + RemoveProp (hwnd, WIN_WINDOW_PROP); + break; + + case WM_MOUSEMOVE: +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n"); +#endif + /* Unpack the client area mouse coordinates */ + ptMouse.x = GET_X_LPARAM(lParam); + ptMouse.y = GET_Y_LPARAM(lParam); + + /* Translate the client area mouse coordinates to screen coordinates */ + ClientToScreen (hwnd, &ptMouse); + + /* 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 (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + + /* Has the mouse pointer crossed screens? */ + if (pScreen != miPointerGetScreen(inputInfo.pointer)) + miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen, + ptMouse.x - pScreenInfo->dwXOffset, + ptMouse.y - 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 ("winMWExtWMWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Kill the timer used to poll mouse events */ + if (g_uipMousePollingTimerID != 0) + { + KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID); + g_uipMousePollingTimerID = 0; + } + + /* Deliver absolute cursor position to X Server */ + winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset, + ptMouse.y - pScreenInfo->dwYOffset); + + return 0; + + case WM_NCMOUSEMOVE: +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n"); +#endif + /* + * 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 (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + break; + + case WM_MOUSELEAVE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n"); +#endif + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n"); +#endif + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam); + + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + SetCapture (hwnd); + return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); + case WM_XBUTTONUP: + if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput) + break; + ReleaseCapture (); + return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); + + case WM_MOUSEWHEEL: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_MOUSEACTIVATE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n"); +#endif +#if 1 + /* Check if this window needs to be made active when clicked */ + if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - " + "MA_NOACTIVATE\n"); +#endif + + /* */ + return MA_NOACTIVATE; + } +#endif + if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin)) + return MA_NOACTIVATE; + + break; + + 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 + winDebug ("winMWExtWMWindowProc - 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 + winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_HOTKEY: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n"); +#endif + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_ERASEBKGND: +#if CYGDEBUG + winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n"); +#endif + /* + * Pretend that we did erase the background but we don't care, + * since we repaint the entire region anyhow + * This avoids some flickering when resizing. + */ + return TRUE; + + case WM_PAINT: + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (hwnd, &ps); + + /* Try to copy from the shadow buffer */ + if (!BitBlt (hdcUpdate, + ps.rcPaint.left, ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top, + pRLWinPriv->hdcShadow, + ps.rcPaint.left, ps.rcPaint.top, + 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 ("winMWExtWMWindowProc - BitBlt failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } + + /* EndPaint frees the DC */ + EndPaint (hwnd, &ps); + break; + + case WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n"); +#endif + if (LOWORD(wParam) != WA_INACTIVE) + { + if (winIsInternalWMRunning(pScreenInfo)) + { +#if 0 + /* Raise the window to the top in Z order */ + wmMsg.msg = WM_WM_RAISE; + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); +#endif + /* Tell our Window Manager thread to activate the window */ + wmMsg.msg = WM_WM_ACTIVATE; + if (fWMMsgInitialized) + if (!pWin || !pWin->overrideRedirect) /* for OOo menus */ + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMActivateWindow, + pWin->drawable.id, + 0, 0, + 0, 0); + } + return 0; + +#if 1 + case WM_WINDOWPOSCHANGING: + pWinPos = (LPWINDOWPOS)lParam; + if (!(pWinPos->flags & SWP_NOZORDER)) + { + if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv); +#endif + break; + } + + if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin)) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv); +#endif + break; + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x forbid to change z order (%08x).\n", + (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter); +#endif + pWinPos->flags |= SWP_NOZORDER; + } + break; +#endif + + case WM_MOVE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n", + (unsigned int)GetTickCount ()); +#endif + if (g_fNoConfigureWindow) break; +#if 0 + /* Bail if Windows window is not actually moving */ + if (pRLWinPriv->dwX == (short) LOWORD(lParam) + && pRLWinPriv->dwY == (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; + } +#endif + +#if CYGMULTIWINDOW_DEBUG + winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam)); +#endif + if (!pRLWinPriv->fMovingOrSizing) + { + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMMoveXWindow (pWin, + (LOWORD(lParam) - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN)), + (HIWORD(lParam) - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN))); + } + return 0; + + case WM_SHOWWINDOW: +#if CYGMULTIWINDOW_DEBUG || TRUE + winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n", + (unsigned int)GetTickCount ()); +#endif + /* Bail out if the window is being hidden */ + if (!wParam) + return 0; + + if (!pScreenInfo->fInternalWM)//XXXX + return 0; + + winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo); + + if (winIsInternalWMRunning(pScreenInfo)) + { +#if CYGMULTIWINDOW_DEBUG || TRUE + winDebug ("\tMapWindow\n"); +#endif + /* Tell X to map the window */ + MapWindow (pWin, wClient(pWin)); + + if (!pRLWinPriv->pFrame->win->overrideRedirect) + /* Bring the Windows window to the foreground */ + SetForegroundWindow (hwnd); + + /* Setup the Window Manager message */ + wmMsg.msg = WM_WM_MAP; + wmMsg.iWidth = pRLWinPriv->pFrame->width; + wmMsg.iHeight = pRLWinPriv->pFrame->height; + + /* Tell our Window Manager thread to map the window */ + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } + break; + + 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: + { + pWinPos = (LPWINDOWPOS) lParam; +#if CYGMULTIWINDOW_DEBUG + winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n"); + winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n", + (pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"", + (pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"", + (pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"", + (pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"", + (pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"", + (pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"", + (pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"", + (pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"", + (pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"", + (pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"", + (pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"", + (pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":""); + winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No")); + winDebug("\textend: (%d, %d, %d, %d)\n", + pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy); + +#endif + if (pWinPos->flags & SWP_HIDEWINDOW) break; + + /* Reorder if window z order was changed */ + if ((pScreenPriv != NULL) + && !(pWinPos->flags & SWP_NOZORDER) + && !(pWinPos->flags & SWP_SHOWWINDOW) + && winIsInternalWMRunning(pScreenInfo)) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\twindow z order was changed\n"); +#endif + if (pWinPos->hwndInsertAfter == HWND_TOP + ||pWinPos->hwndInsertAfter == HWND_TOPMOST + ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\traise to top\n"); +#endif + /* Raise the window to the top in Z order */ + wmMsg.msg = WM_WM_RAISE; + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } +#if 1 + else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) + { + } + else + { + /* Check if this window is top of X windows. */ + HWND hWndAbove = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + + for (hWndAbove = pWinPos->hwndInsertAfter; + hWndAbove != NULL; + hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV)) + { + /* Ignore other XWin process's window */ + GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWndAbove, WIN_WINDOW_PROP) + && !IsWindowVisible (hWndAbove) + && !IsIconic (hWndAbove) ) /* ignore minimized windows */ + break; + } + /* If this is top of X windows in Windows stack, + raise it in X stack. */ + if (hWndAbove == NULL) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\traise to top\n"); +#endif + /* Raise the window to the top in Z order */ + wmMsg.msg = WM_WM_RAISE; + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } + } +#endif + } + + if (!(pWinPos->flags & SWP_NOSIZE)) { + if (IsIconic(hwnd)){ +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tIconic -> MINIMIZED\n"); +#endif + if (winIsInternalWMRunning(pScreenInfo)) + { + /* Raise the window to the top in Z order */ + wmMsg.msg = WM_WM_LOWER; + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMinimizeWindow, + pWin->drawable.id, + 0, 0, 0, 0); + } else if (IsZoomed(hwnd)){ +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tZoomed -> MAXIMIZED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMaximizeWindow, + pWin->drawable.id, + 0, 0, 0, 0); + } else { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tnone -> RESTORED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMRestoreWindow, + pWin->drawable.id, + 0, 0, 0, 0); + } + } + if (!g_fNoConfigureWindow ) { + + if (!pRLWinPriv->fMovingOrSizing + /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) { + GetClientRect (hwnd, &rcClient); + MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); + + if (!(pWinPos->flags & SWP_NOMOVE) + &&!(pWinPos->flags & SWP_NOSIZE)) { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tmove & resize\n"); +#endif + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMMoveResizeXWindow (pWin, + rcClient.left - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN), + rcClient.top - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN), + rcClient.right - rcClient.left + - wBorderWidth (pWin)*2, + rcClient.bottom - rcClient.top + - wBorderWidth (pWin)*2); + } else if (!(pWinPos->flags & SWP_NOMOVE)) { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tmove\n"); +#endif + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMMoveResizeXWindow (pWin, + rcClient.left - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN), + rcClient.top - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN), + rcClient.right - rcClient.left + - wBorderWidth (pWin)*2, + rcClient.bottom - rcClient.top + - wBorderWidth (pWin)*2); + } else if (!(pWinPos->flags & SWP_NOMOVE)) { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tmove\n"); +#endif + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMMoveXWindow (pWin, + rcClient.left - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN), + rcClient.top - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN)); + } else if (!(pWinPos->flags & SWP_NOSIZE)) { +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tresize\n"); +#endif + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMResizeXWindow (pWin, + rcClient.right - rcClient.left + - wBorderWidth (pWin)*2, + rcClient.bottom - rcClient.top + - wBorderWidth (pWin)*2); + } + } + } + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n"); +#endif + return 0; + + case WM_SIZE: + /* see dix/window.c */ + /* FIXME: Maximize/Restore? */ +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n", + (unsigned int)GetTickCount ()); +#endif +#if CYGMULTIWINDOW_DEBUG + winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow); +#endif + if (g_fNoConfigureWindow) break; + + /* Branch on type of resizing occurring */ + switch (wParam) + { + case SIZE_MINIMIZED: +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tSIZE_MINIMIZED\n"); +#endif + if (winIsInternalWMRunning(pScreenInfo)) + { + /* Raise the window to the top in Z order */ + wmMsg.msg = WM_WM_LOWER; + if (fWMMsgInitialized) + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + } + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMinimizeWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); + break; + + case SIZE_RESTORED: +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tSIZE_RESTORED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMRestoreWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); + break; + + case SIZE_MAXIMIZED: +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tSIZE_MAXIMIZED\n"); +#endif + winWindowsWMSendEvent(WindowsWMControllerNotify, + WindowsWMControllerNotifyMask, + 1, + WindowsWMMaximizeWindow, + pWin->drawable.id, + 0, 0, + LOWORD(lParam), HIWORD(lParam)); + break; + } + + /* Perform the resize and notify the X client */ + if (!pRLWinPriv->fMovingOrSizing) + { + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMResizeXWindow (pWin, + (short) LOWORD(lParam) + - wBorderWidth (pWin)*2, + (short) HIWORD(lParam) + - wBorderWidth (pWin)*2); + } + break; + + case WM_ACTIVATEAPP: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n", + (unsigned int)GetTickCount ()); +#endif + if (wParam) + { + if (winIsInternalWMRunning(pScreenInfo)) + { + } + else + { + } + winWindowsWMSendEvent(WindowsWMActivationNotify, + WindowsWMActivationNotifyMask, + 1, + WindowsWMIsActive, + pWin->drawable.id, + 0, 0, + 0, 0); + } + else + { + winWindowsWMSendEvent(WindowsWMActivationNotify, + WindowsWMActivationNotifyMask, + 1, + WindowsWMIsInactive, + pWin->drawable.id, + 0, 0, + 0, 0); + } + break; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle); + return TRUE; + } + break; + + case WM_ENTERSIZEMOVE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n", + (unsigned int)GetTickCount ()); +#endif + pRLWinPriv->fMovingOrSizing = TRUE; + break; + + case WM_EXITSIZEMOVE: +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n", + (unsigned int)GetTickCount ()); +#endif + pRLWinPriv->fMovingOrSizing = FALSE; + + GetClientRect (hwnd, &rcClient); + + MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); + + if (winIsInternalWMRunning(pScreenInfo)) + winAdjustXWindow (pWin, hwnd); + + winMWExtWMMoveResizeXWindow (pWin, + rcClient.left - wBorderWidth (pWin) + - GetSystemMetrics (SM_XVIRTUALSCREEN), + rcClient.top - wBorderWidth (pWin) + - GetSystemMetrics (SM_YVIRTUALSCREEN), + rcClient.right - rcClient.left + - wBorderWidth (pWin)*2, + rcClient.bottom - rcClient.top + - wBorderWidth (pWin)*2); + break; + + case WM_MANAGE: + ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n"); + break; + + case WM_UNMANAGE: + ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n"); + break; + + default: + break; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c index 864a2fa96..966732a5a 100644 --- a/xorg-server/hw/xwin/winwindowswm.c +++ b/xorg-server/hw/xwin/winwindowswm.c @@ -77,10 +77,10 @@ make_box (int x, int y, int w, int h) } static int -ProcWindowsWMQueryVersion(register ClientPtr client) +ProcWindowsWMQueryVersion(ClientPtr client) { xWindowsWMQueryVersionReply rep; - register int n; + int n; REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq); rep.type = X_Reply; @@ -158,7 +158,7 @@ WMFreeEvents (pointer data, XID id) } static int -ProcWindowsWMSelectInput (register ClientPtr client) +ProcWindowsWMSelectInput (ClientPtr client) { REQUEST(xWindowsWMSelectInputReq); WMEventPtr pEvent, pNewEvent, *pHead; @@ -298,7 +298,7 @@ winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, /* general utility functions */ static int -ProcWindowsWMDisableUpdate (register ClientPtr client) +ProcWindowsWMDisableUpdate (ClientPtr client) { REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq); @@ -308,7 +308,7 @@ ProcWindowsWMDisableUpdate (register ClientPtr client) } static int -ProcWindowsWMReenableUpdate (register ClientPtr client) +ProcWindowsWMReenableUpdate (ClientPtr client) { REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq); @@ -321,7 +321,7 @@ ProcWindowsWMReenableUpdate (register ClientPtr client) /* window functions */ static int -ProcWindowsWMSetFrontProcess (register ClientPtr client) +ProcWindowsWMSetFrontProcess (ClientPtr client) { REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq); @@ -334,7 +334,7 @@ ProcWindowsWMSetFrontProcess (register ClientPtr client) /* frame functions */ static int -ProcWindowsWMFrameGetRect (register ClientPtr client) +ProcWindowsWMFrameGetRect (ClientPtr client) { xWindowsWMFrameGetRectReply rep; BoxRec ir; @@ -388,7 +388,7 @@ ProcWindowsWMFrameGetRect (register ClientPtr client) static int -ProcWindowsWMFrameDraw (register ClientPtr client) +ProcWindowsWMFrameDraw (ClientPtr client) { REQUEST(xWindowsWMFrameDrawReq); WindowPtr pWin; @@ -478,12 +478,10 @@ ProcWindowsWMFrameDraw (register ClientPtr client) } static int -ProcWindowsWMFrameSetTitle( - register ClientPtr client - ) +ProcWindowsWMFrameSetTitle(ClientPtr client) { unsigned int title_length, title_max; - unsigned char *title_bytes; + char *title_bytes; REQUEST(xWindowsWMFrameSetTitleReq); WindowPtr pWin; win32RootlessWindowPtr pRLWinPriv; @@ -540,7 +538,7 @@ ProcWindowsWMFrameSetTitle( /* dispatch */ static int -ProcWindowsWMDispatch (register ClientPtr client) +ProcWindowsWMDispatch (ClientPtr client) { REQUEST(xReq); @@ -586,16 +584,16 @@ SNotifyEvent (xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to) } static int -SProcWindowsWMQueryVersion (register ClientPtr client) +SProcWindowsWMQueryVersion (ClientPtr client) { - register int n; + int n; REQUEST(xWindowsWMQueryVersionReq); swaps(&stuff->length, n); return ProcWindowsWMQueryVersion(client); } static int -SProcWindowsWMDispatch (register ClientPtr client) +SProcWindowsWMDispatch (ClientPtr client) { REQUEST(xReq); diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c index 5e8451082..6d03de174 100644 --- a/xorg-server/hw/xwin/winwndproc.c +++ b/xorg-server/hw/xwin/winwndproc.c @@ -1,1281 +1,1263 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - * MATSUZAKI Kensuke - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" -#include -#include "winprefs.h" -#include "winconfig.h" -#include "winmsg.h" -#include "inputstr.h" - -/* - * Global variables - */ - -Bool g_fCursor = TRUE; -Bool g_fButton[3] = { FALSE, FALSE, FALSE }; - - -/* - * References to external symbols - */ - -extern Bool g_fClipboard; -extern HWND g_hDlgDepthChange; -extern Bool g_fKeyboardHookLL; -extern HWND g_hwndKeyboardFocus; -extern Bool g_fSoftwareCursor; -extern DWORD g_dwCurrentThreadID; - - -/* - * Called by winWakeupHandler - * Processes current Windows message - */ - -LRESULT CALLBACK -winWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - static winPrivScreenPtr s_pScreenPriv = NULL; - static winScreenInfo *s_pScreenInfo = NULL; - static ScreenPtr s_pScreen = NULL; - static HWND s_hwndLastPrivates = NULL; - static HINSTANCE s_hInstance; - static Bool s_fTracking = FALSE; - static unsigned long s_ulServerGeneration = 0; - static UINT s_uTaskbarRestart = 0; - int iScanCode; - int i; - -#if CYGDEBUG - winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam); -#endif - - /* Watch for server regeneration */ - if (g_ulServerGeneration != s_ulServerGeneration) - { - /* Store new server generation */ - s_ulServerGeneration = g_ulServerGeneration; - } - - /* Only retrieve new privates pointers if window handle is null or changed */ - if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) - && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL) - { -#if CYGDEBUG - winDebug ("winWindowProc - Setting privates handle\n"); -#endif - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - s_pScreen = s_pScreenInfo->pScreen; - s_hwndLastPrivates = hwnd; - } - else if (s_pScreenPriv == NULL) - { - /* For safety, handle case that should never happen */ - s_pScreenInfo = NULL; - s_pScreen = NULL; - s_hwndLastPrivates = NULL; - } - - /* Branch on message type */ - switch (message) - { - case WM_TRAYICON: - return winHandleIconMessage (hwnd, message, wParam, lParam, - s_pScreenPriv); - - case WM_CREATE: -#if CYGDEBUG - winDebug ("winWindowProc - WM_CREATE\n"); -#endif - - /* - * Add a property to our display window that references - * this screens' privates. - * - * This allows the window procedure to refer to the - * appropriate window DC and shadow DC for the window that - * it is processing. We use this to repaint exposed - * areas of our display window. - */ - s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams; - s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance; - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - s_pScreen = s_pScreenInfo->pScreen; - s_hwndLastPrivates = hwnd; - s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); - SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv); - - /* Setup tray icon */ - if (!s_pScreenInfo->fNoTrayIcon) - { - /* - * NOTE: The WM_CREATE message is processed before CreateWindowEx - * returns, so s_pScreenPriv->hwndScreen is invalid at this point. - * We go ahead and copy our hwnd parameter over top of the screen - * privates hwndScreen so that we have a valid value for - * that member. Otherwise, the tray icon will disappear - * the first time you move the mouse over top of it. - */ - - s_pScreenPriv->hwndScreen = hwnd; - - winInitNotifyIcon (s_pScreenPriv); - } - return 0; - - case WM_DISPLAYCHANGE: - /* We cannot handle a display mode change during initialization */ - if (s_pScreenInfo == NULL) - FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display " - "mode changed while we were intializing. This is " - "very bad and unexpected. Exiting.\n"); - - /* - * We do not care about display changes with - * fullscreen DirectDraw engines, because those engines set - * their own mode when they become active. - */ - if (s_pScreenInfo->fFullScreen - && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL -#ifdef XWIN_PRIMARYFB - || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD -#endif - )) - { - /* - * Store the new display dimensions and depth. - * We do this here for future compatibility in case we - * ever allow switching from fullscreen to windowed mode. - */ - s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); - s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); - s_pScreenPriv->dwLastWindowsBitsPixel - = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); - break; - } - - ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, " - "new bpp: %d\n", - (int) s_pScreenInfo->dwBPP, - (int) s_pScreenPriv->dwLastWindowsBitsPixel, - wParam); - - ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " - "new height: %d\n", - LOWORD (lParam), HIWORD (lParam)); - - /* - * TrueColor --> TrueColor depth changes are disruptive for: - * Windowed: - * Shadow DirectDraw - * Shadow DirectDraw Non-Locking - * Primary DirectDraw - * - * TrueColor --> TrueColor depth changes are non-optimal for: - * Windowed: - * Shadow GDI - * - * FullScreen: - * Shadow GDI - * - * TrueColor --> PseudoColor or vice versa are disruptive for: - * Windowed: - * Shadow DirectDraw - * Shadow DirectDraw Non-Locking - * Primary DirectDraw - * Shadow GDI - */ - - /* - * Check for a disruptive change in depth. - * We can only display a message for a disruptive depth change, - * we cannot do anything to correct the situation. - */ - if ((s_pScreenInfo->dwBPP != wParam) - && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL -#ifdef XWIN_PRIMARYFB - || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD -#endif - )) - { - /* Cannot display the visual until the depth is restored */ - ErrorF ("winWindowProc - Disruptive change in depth\n"); - - /* Display Exit dialog */ - winDisplayDepthChangeDialog (s_pScreenPriv); - - /* Flag that we have an invalid screen depth */ - s_pScreenPriv->fBadDepth = TRUE; - - /* Minimize the display window */ - ShowWindow (hwnd, SW_MINIMIZE); - } - else - { - /* Flag that we have a valid screen depth */ - s_pScreenPriv->fBadDepth = FALSE; - } - - /* - * Check for a change in display dimensions. - * We can simply recreate the same-sized primary surface when - * the display dimensions change. - */ - if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam) - || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam)) - { - /* - * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface - * and CreatePrimarySurface function pointers to point - * to the no operation function, NoopDDA. This allows us - * to blindly call these functions, even if they are not - * relevant to the current engine (e.g., Shadow GDI). - */ - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); -#endif - - /* Release the old primary surface */ - (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released " - "primary surface\n"); -#endif - - /* Create the new primary surface */ - (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); - -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " - "primary surface\n"); -#endif - -#if 0 - /* Multi-Window mode uses RandR for resizes */ - if (s_pScreenInfo->fMultiWindow) - { - RRSetScreenConfig (); - } -#endif - } - else - { -#if CYGDEBUG - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not " - "change\n"); -#endif - } - - /* Store the new display dimensions and depth */ - if (s_pScreenInfo->fMultipleMonitors) - { - s_pScreenPriv->dwLastWindowsWidth - = GetSystemMetrics (SM_CXVIRTUALSCREEN); - s_pScreenPriv->dwLastWindowsHeight - = GetSystemMetrics (SM_CYVIRTUALSCREEN); - } - else - { - s_pScreenPriv->dwLastWindowsWidth - = GetSystemMetrics (SM_CXSCREEN); - s_pScreenPriv->dwLastWindowsHeight - = GetSystemMetrics (SM_CYSCREEN); - } - s_pScreenPriv->dwLastWindowsBitsPixel - = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); - break; - - case WM_SIZE: - { - SCROLLINFO si; - RECT rcWindow; - int iWidth, iHeight; - -#if CYGDEBUG - winDebug ("winWindowProc - WM_SIZE\n"); -#endif - - /* Break if we do not use scrollbars */ - if (!s_pScreenInfo->fScrollbars - || !s_pScreenInfo->fDecoration -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - || s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOW - || s_pScreenInfo->fMultiWindow -#endif - || s_pScreenInfo->fFullScreen) - break; - - /* No need to resize if we get minimized */ - if (wParam == SIZE_MINIMIZED) - return 0; - - /* - * Get the size of the whole window, including client area, - * scrollbars, and non-client area decorations (caption, borders). - * We do this because we need to check if the client area - * without scrollbars is large enough to display the whole visual. - * The new client area size passed by lParam already subtracts - * the size of the scrollbars if they are currently displayed. - * So checking is LOWORD(lParam) == visual_width and - * HIWORD(lParam) == visual_height will never tell us to hide - * the scrollbars because the client area would always be too small. - * GetClientRect returns the same sizes given by lParam, so we - * cannot use GetClientRect either. - */ - GetWindowRect (hwnd, &rcWindow); - iWidth = rcWindow.right - rcWindow.left; - iHeight = rcWindow.bottom - rcWindow.top; - - ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, " - "new client area w: %d h: %d\n", - iWidth, iHeight, LOWORD (lParam), HIWORD (lParam)); - - /* Subtract the frame size from the window size. */ - iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME); - iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME) - + GetSystemMetrics (SM_CYCAPTION)); - - /* - * Update scrollbar page sizes. - * NOTE: If page size == range, then the scrollbar is - * automatically hidden. - */ - - /* Is the naked client area large enough to show the whole visual? */ - if (iWidth < s_pScreenInfo->dwWidth - || iHeight < s_pScreenInfo->dwHeight) - { - /* Client area too small to display visual, use scrollbars */ - iWidth -= GetSystemMetrics (SM_CXVSCROLL); - iHeight -= GetSystemMetrics (SM_CYHSCROLL); - } - - /* Set the horizontal scrollbar page size */ - si.cbSize = sizeof (si); - si.fMask = SIF_PAGE | SIF_RANGE; - si.nMin = 0; - si.nMax = s_pScreenInfo->dwWidth - 1; - si.nPage = iWidth; - SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); - - /* Set the vertical scrollbar page size */ - si.cbSize = sizeof (si); - si.fMask = SIF_PAGE | SIF_RANGE; - si.nMin = 0; - si.nMax = s_pScreenInfo->dwHeight - 1; - si.nPage = iHeight; - SetScrollInfo (hwnd, SB_VERT, &si, TRUE); - - /* - * NOTE: Scrollbars may have moved if they were at the - * far right/bottom, so we query their current position. - */ - - /* Get the horizontal scrollbar position and set the offset */ - si.cbSize = sizeof (si); - si.fMask = SIF_POS; - GetScrollInfo (hwnd, SB_HORZ, &si); - s_pScreenInfo->dwXOffset = -si.nPos; - - /* Get the vertical scrollbar position and set the offset */ - si.cbSize = sizeof (si); - si.fMask = SIF_POS; - GetScrollInfo (hwnd, SB_VERT, &si); - s_pScreenInfo->dwYOffset = -si.nPos; - } - return 0; - - case WM_VSCROLL: - { - SCROLLINFO si; - int iVertPos; - -#if CYGDEBUG - winDebug ("winWindowProc - WM_VSCROLL\n"); -#endif - - /* Get vertical scroll bar info */ - si.cbSize = sizeof (si); - si.fMask = SIF_ALL; - GetScrollInfo (hwnd, SB_VERT, &si); - - /* Save the vertical position for comparison later */ - iVertPos = si.nPos; - - /* - * Don't forget: - * moving the scrollbar to the DOWN, scroll the content UP - */ - switch (LOWORD(wParam)) - { - case SB_TOP: - si.nPos = si.nMin; - break; - - case SB_BOTTOM: - si.nPos = si.nMax - si.nPage + 1; - break; - - case SB_LINEUP: - si.nPos -= 1; - break; - - case SB_LINEDOWN: - si.nPos += 1; - break; - - case SB_PAGEUP: - si.nPos -= si.nPage; - break; - - case SB_PAGEDOWN: - si.nPos += si.nPage; - break; - - case SB_THUMBTRACK: - si.nPos = si.nTrackPos; - break; - - default: - break; - } - - /* - * We retrieve the position after setting it, - * because Windows may adjust it. - */ - si.fMask = SIF_POS; - SetScrollInfo (hwnd, SB_VERT, &si, TRUE); - GetScrollInfo (hwnd, SB_VERT, &si); - - /* Scroll the window if the position has changed */ - if (si.nPos != iVertPos) - { - /* Save the new offset for bit block transfers, etc. */ - s_pScreenInfo->dwYOffset = -si.nPos; - - /* Change displayed region in the window */ - ScrollWindowEx (hwnd, - 0, - iVertPos - si.nPos, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); - - /* Redraw the window contents */ - UpdateWindow (hwnd); - } - } - return 0; - - case WM_HSCROLL: - { - SCROLLINFO si; - int iHorzPos; - -#if CYGDEBUG - winDebug ("winWindowProc - WM_HSCROLL\n"); -#endif - - /* Get horizontal scroll bar info */ - si.cbSize = sizeof (si); - si.fMask = SIF_ALL; - GetScrollInfo (hwnd, SB_HORZ, &si); - - /* Save the horizontal position for comparison later */ - iHorzPos = si.nPos; - - /* - * Don't forget: - * moving the scrollbar to the RIGHT, scroll the content LEFT - */ - switch (LOWORD(wParam)) - { - case SB_LEFT: - si.nPos = si.nMin; - break; - - case SB_RIGHT: - si.nPos = si.nMax - si.nPage + 1; - break; - - case SB_LINELEFT: - si.nPos -= 1; - break; - - case SB_LINERIGHT: - si.nPos += 1; - break; - - case SB_PAGELEFT: - si.nPos -= si.nPage; - break; - - case SB_PAGERIGHT: - si.nPos += si.nPage; - break; - - case SB_THUMBTRACK: - si.nPos = si.nTrackPos; - break; - - default: - break; - } - - /* - * We retrieve the position after setting it, - * because Windows may adjust it. - */ - si.fMask = SIF_POS; - SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); - GetScrollInfo (hwnd, SB_HORZ, &si); - - /* Scroll the window if the position has changed */ - if (si.nPos != iHorzPos) - { - /* Save the new offset for bit block transfers, etc. */ - s_pScreenInfo->dwXOffset = -si.nPos; - - /* Change displayed region in the window */ - ScrollWindowEx (hwnd, - iHorzPos - si.nPos, - 0, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE); - - /* Redraw the window contents */ - UpdateWindow (hwnd); - } - } - return 0; - - case WM_GETMINMAXINFO: - { - MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam; - int iCaptionHeight; - int iBorderHeight, iBorderWidth; - -#if CYGDEBUG - winDebug ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n", - s_pScreenInfo); -#endif - - /* Can't do anything without screen info */ - if (s_pScreenInfo == NULL - || !s_pScreenInfo->fScrollbars - || s_pScreenInfo->fFullScreen - || !s_pScreenInfo->fDecoration -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - || s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOW - || s_pScreenInfo->fMultiWindow -#endif - ) - break; - - /* - * Here we can override the maximum tracking size, which - * is the largest size that can be assigned to our window - * via the sizing border. - */ - - /* - * FIXME: Do we only need to do this once, since our visual size - * does not change? Does Windows store this value statically - * once we have set it once? - */ - - /* Get the border and caption sizes */ - iCaptionHeight = GetSystemMetrics (SM_CYCAPTION); - iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME); - iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME); - - /* Allow the full visual to be displayed */ - pMinMaxInfo->ptMaxTrackSize.x - = s_pScreenInfo->dwWidth + iBorderWidth; - pMinMaxInfo->ptMaxTrackSize.y - = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight; - } - return 0; - - case WM_ERASEBKGND: -#if CYGDEBUG - winDebug ("winWindowProc - WM_ERASEBKGND\n"); -#endif - /* - * Pretend that we did erase the background but we don't care, - * the application uses the full window estate. This avoids some - * flickering when resizing. - */ - return TRUE; - - case WM_PAINT: -#if CYGDEBUG - winDebug ("winWindowProc - WM_PAINT\n"); -#endif - /* Only paint if we have privates and the server is enabled */ - if (s_pScreenPriv == NULL - || !s_pScreenPriv->fEnabled - || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive) - || s_pScreenPriv->fBadDepth) - { - /* We don't want to paint */ - break; - } - - /* Break out here if we don't have a valid paint routine */ - if (s_pScreenPriv->pwinBltExposedRegions == NULL) - break; - - /* Call the engine dependent repainter */ - (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen); - return 0; - - case WM_PALETTECHANGED: - { -#if CYGDEBUG - winDebug ("winWindowProc - WM_PALETTECHANGED\n"); -#endif - /* - * Don't process if we don't have privates or a colormap, - * or if we have an invalid depth. - */ - if (s_pScreenPriv == NULL - || s_pScreenPriv->pcmapInstalled == NULL - || s_pScreenPriv->fBadDepth) - break; - - /* Return if we caused the palette to change */ - if ((HWND) wParam == hwnd) - { - /* Redraw the screen */ - (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); - return 0; - } - - /* Reinstall the windows palette */ - (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen); - - /* Redraw the screen */ - (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); - return 0; - } - - case WM_MOUSEMOVE: - /* We can't do anything without privates */ - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* We can't do anything without g_pwinPointer */ - if (g_pwinPointer == NULL) - break; - - /* Has the mouse pointer crossed screens? */ - if (s_pScreen != miPointerGetScreen(g_pwinPointer)) - miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen, - GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, - GET_Y_LPARAM(lParam)-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 ("winWindowProc - _TrackMouseEvent failed\n"); - - /* Flag that we are tracking now */ - s_fTracking = TRUE; - } - - /* Hide or show the Windows mouse cursor */ - if (g_fSoftwareCursor && g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) - { - /* Hide Windows cursor */ - g_fCursor = FALSE; - ShowCursor (FALSE); - } - else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive - && !s_pScreenInfo->fLessPointer) - { - /* Show Windows cursor */ - g_fCursor = TRUE; - ShowCursor (TRUE); - } - - /* Deliver absolute cursor position to X Server */ - winEnqueueMotion(GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, - GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset); - 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_fSoftwareCursor && !g_fCursor) - { - g_fCursor = TRUE; - ShowCursor (TRUE); - } - 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_fSoftwareCursor && !g_fCursor) - { - g_fCursor = TRUE; - ShowCursor (TRUE); - } - return 0; - - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - SetCapture (hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); - - case WM_LBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - ReleaseCapture (); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); - - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - SetCapture (hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); - - case WM_MBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - ReleaseCapture (); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); - - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - SetCapture (hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); - - case WM_RBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - ReleaseCapture (); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); - - case WM_XBUTTONDBLCLK: - case WM_XBUTTONDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - SetCapture (hwnd); - return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); - case WM_XBUTTONUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - if (s_pScreenInfo->fRootless -#ifdef XWIN_MULTIWINDOWEXTWM - || s_pScreenInfo->fMWExtWM -#endif - ) - ReleaseCapture (); - return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); - - case WM_TIMER: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Branch on the timer id */ - switch (wParam) - { - case WIN_E3B_TIMER_ID: - /* Send delayed button press */ - winMouseButtonsSendEvent (ButtonPress, - s_pScreenPriv->iE3BCachedPress); - - /* Kill this timer */ - KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); - - /* Clear screen privates flags */ - s_pScreenPriv->iE3BCachedPress = 0; - break; - - case WIN_POLLING_MOUSE_TIMER_ID: - { - POINT point; - WPARAM wL, wM, wR, wShift, wCtrl; - LPARAM lPos; - - /* Get the current position of the mouse cursor */ - GetCursorPos (&point); - - /* Map from screen (-X, -Y) to root (0, 0) */ - point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); - point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); - - /* Deliver absolute cursor position to X Server */ - winEnqueueMotion(point.x , point.y); - - /* Check if a button was released but we didn't see it */ - GetCursorPos (&point); - wL = (GetKeyState (VK_LBUTTON) & 0x8000)?MK_LBUTTON:0; - wM = (GetKeyState (VK_MBUTTON) & 0x8000)?MK_MBUTTON:0; - wR = (GetKeyState (VK_RBUTTON) & 0x8000)?MK_RBUTTON:0; - wShift = (GetKeyState (VK_SHIFT) & 0x8000)?MK_SHIFT:0; - wCtrl = (GetKeyState (VK_CONTROL) & 0x8000)?MK_CONTROL:0; - lPos = MAKELPARAM(point.x, point.y); - if (g_fButton[0] & !wL) - PostMessage (hwnd, WM_LBUTTONUP, wCtrl|wM|wR|wShift, lPos); - if (g_fButton[1] & !wM) - PostMessage (hwnd, WM_MBUTTONUP, wCtrl|wL|wR|wShift, lPos); - if (g_fButton[2] & !wR) - PostMessage (hwnd, WM_RBUTTONUP, wCtrl|wL|wM|wShift, lPos); - } - } - return 0; - - case WM_CTLCOLORSCROLLBAR: - FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not " - "supposed to get this message. Exiting.\n"); - return 0; - - case WM_MOUSEWHEEL: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; -#if CYGDEBUG - winDebug ("winWindowProc - WM_MOUSEWHEEL\n"); -#endif - winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam)); - break; - - case WM_SETFOCUS: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Save handle of our main window that last received focus */ - g_hwndKeyboardFocus = hwnd; - - /* Restore the state of all mode keys */ - winRestoreModeKeyStates (); - - /* Add the keyboard hook if possible */ - if (g_fKeyboardHookLL) - g_fKeyboardHookLL = winInstallKeyboardHookLL (); - return 0; - - case WM_KILLFOCUS: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* Clear handle of our main window that last received focus */ - g_hwndKeyboardFocus = NULL; - - /* Release any pressed keys */ - winKeybdReleaseKeys (); - - /* Remove our keyboard hook if it is installed */ - winRemoveKeyboardHookLL (); - return 0; - - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* - * FIXME: Catching Alt-F4 like this is really terrible. This should - * be generalized to handle other Windows keyboard signals. Actually, - * the list keys to catch and the actions to perform when caught should - * be configurable; that way user's can customize the keys that they - * need to have passed through to their window manager or apps, or they - * can remap certain actions to new key codes that do not conflict - * with the X apps that they are using. Yeah, that'll take awhile. - */ - if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4 - && (GetKeyState (VK_MENU) & 0x8000)) - || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK - && (GetKeyState (VK_MENU) & 0x8000) - && (GetKeyState (VK_CONTROL) & 0x8000))) - { - /* - * Better leave this message here, just in case some unsuspecting - * user enters Alt + F4 and is surprised when the application - * quits. - */ - ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); - - /* Display Exit dialog */ - winDisplayExitDialog (s_pScreenPriv); - return 0; - } - - /* - * Don't do anything for the Windows keys, as focus will soon - * be returned to Windows. We may be able to trap the Windows keys, - * but we should determine if that is desirable before doing so. - */ - if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) - break; - - /* - * Discard presses generated from Windows auto-repeat - */ - if (lParam & (1<<30)) - { - switch (wParam) - { - /* ago: Pressing LControl while RControl is pressed is - * Indicated as repeat. Fix this! - */ - case VK_CONTROL: - case VK_SHIFT: - if (winCheckKeyPressed(wParam, lParam)) - return 0; - break; - default: - return 0; - } - } - - /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ - if (winIsFakeCtrl_L (message, wParam, lParam)) - return 0; - - /* Translate Windows key code to X scan code */ - winTranslateKey (wParam, lParam, &iScanCode); - - /* Ignore repeats for CapsLock */ - if (wParam == VK_CAPITAL) - lParam = 1; - - /* Send the key event(s) */ - for (i = 0; i < LOWORD(lParam); ++i) - winSendKeyEvent (iScanCode, TRUE); - return 0; - - case WM_SYSKEYUP: - case WM_KEYUP: - if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) - break; - - /* - * Don't do anything for the Windows keys, as focus will soon - * be returned to Windows. We may be able to trap the Windows keys, - * but we should determine if that is desirable before doing so. - */ - if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) - break; - - /* Ignore the fake Ctrl_L that follows an AltGr release */ - if (winIsFakeCtrl_L (message, wParam, lParam)) - return 0; - - /* Enqueue a keyup event */ - winTranslateKey (wParam, lParam, &iScanCode); - winSendKeyEvent (iScanCode, FALSE); - - /* Release all pressed shift keys */ - if (wParam == VK_SHIFT) - winFixShiftKeys (iScanCode); - return 0; - - case WM_HOTKEY: - if (s_pScreenPriv == NULL) - break; - - /* Call the engine-specific hot key handler */ - (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen); - return 0; - - case WM_ACTIVATE: - if (s_pScreenPriv == NULL - || s_pScreenInfo->fIgnoreInput) - break; - - /* TODO: Override display of window when we have a bad depth */ - if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) - { - ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying " - "to override window activation\n"); - - /* Minimize the window */ - ShowWindow (hwnd, SW_MINIMIZE); - - /* Display dialog box */ - if (g_hDlgDepthChange != NULL) - { - /* Make the existing dialog box active */ - SetActiveWindow (g_hDlgDepthChange); - } - else - { - /* TODO: Recreate the dialog box and bring to the top */ - ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); - } - - /* Don't do any other processing of this message */ - return 0; - } - -#if CYGDEBUG - winDebug ("winWindowProc - WM_ACTIVATE\n"); -#endif - - /* - * Focus is being changed to another window. - * The other window may or may not belong to - * our process. - */ - - /* Clear any lingering wheel delta */ - s_pScreenPriv->iDeltaZ = 0; - - /* Reshow the Windows mouse cursor if we are being deactivated */ - if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE - && !g_fCursor) - { - /* Show Windows cursor */ - g_fCursor = TRUE; - ShowCursor (TRUE); - } - return 0; - - case WM_ACTIVATEAPP: - if (s_pScreenPriv == NULL - || s_pScreenInfo->fIgnoreInput) - break; - -#if CYGDEBUG || TRUE - winDebug ("winWindowProc - WM_ACTIVATEAPP\n"); -#endif - - /* Activate or deactivate */ - s_pScreenPriv->fActive = wParam; - - /* Reshow the Windows mouse cursor if we are being deactivated */ - if (g_fSoftwareCursor && !s_pScreenPriv->fActive - && !g_fCursor) - { - /* Show Windows cursor */ - g_fCursor = TRUE; - ShowCursor (TRUE); - } - -#ifdef XWIN_CLIPBOARD - /* Make sure the clipboard chain is ok. */ - winFixClipboardChain (); -#endif - - /* Call engine specific screen activation/deactivation function */ - (*s_pScreenPriv->pwinActivateApp) (s_pScreen); - -#ifdef XWIN_MULTIWINDOWEXTWM - if (s_pScreenPriv->fActive) - { - /* Restack all window unless using built-in wm. */ - if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning) - winMWExtWMRestackWindows (s_pScreen); - } -#endif - - return 0; - - case WM_COMMAND: - switch (LOWORD (wParam)) - { - case ID_APP_EXIT: - /* Display Exit dialog */ - winDisplayExitDialog (s_pScreenPriv); - return 0; - -#ifdef XWIN_MULTIWINDOW - case ID_APP_HIDE_ROOT: - if (s_pScreenPriv->fRootWindowShown) - ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE); - else - ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW); - s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown; - return 0; -#endif - - case ID_APP_ABOUT: - /* Display the About box */ - winDisplayAboutDialog (s_pScreenPriv); - return 0; - - default: - /* It's probably one of the custom menus... */ - if (HandleCustomWM_COMMAND (0, LOWORD (wParam))) - return 0; - } - break; - - case WM_ENDSESSION: - case WM_GIVEUP: - /* Tell X that we are giving up */ -#ifdef XWIN_MULTIWINDOW - if (s_pScreenInfo->fMultiWindow) - winDeinitMultiWindowWM (); -#endif - GiveUp (0); - return 0; - - case WM_CLOSE: - /* Display Exit dialog */ - winDisplayExitDialog (s_pScreenPriv); - return 0; - - case WM_SETCURSOR: - if (LOWORD(lParam) == HTCLIENT) - { - if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); - return TRUE; - } - break; - -#ifdef XWIN_MULTIWINDOWEXTWM - case WM_MANAGE: - ErrorF ("winWindowProc - WM_MANAGE\n"); - s_pScreenInfo->fAnotherWMRunning = FALSE; - - if (s_pScreenInfo->fInternalWM) - { - EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); - //RootlessRepositionWindows (s_pScreen); - } - break; - - case WM_UNMANAGE: - ErrorF ("winWindowProc - WM_UNMANAGE\n"); - s_pScreenInfo->fAnotherWMRunning = TRUE; - - if (s_pScreenInfo->fInternalWM) - { - EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); - winMWExtWMRestackWindows (s_pScreen); - } - break; -#endif - - default: - if(message == s_uTaskbarRestart) - { - winInitNotifyIcon (s_pScreenPriv); - } - break; - } - - return DefWindowProc (hwnd, message, wParam, lParam); -} +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * MATSUZAKI Kensuke + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" +#include +#include "winprefs.h" +#include "winconfig.h" +#include "winmsg.h" +#include "inputstr.h" + +/* + * Global variables + */ + +Bool g_fCursor = TRUE; +Bool g_fButton[3] = { FALSE, FALSE, FALSE }; + + +/* + * Called by winWakeupHandler + * Processes current Windows message + */ + +LRESULT CALLBACK +winWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + static HWND s_hwndLastPrivates = NULL; + static HINSTANCE s_hInstance; + static Bool s_fTracking = FALSE; + static unsigned long s_ulServerGeneration = 0; + static UINT s_uTaskbarRestart = 0; + int iScanCode; + int i; + +#if CYGDEBUG + winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam); +#endif + + /* Watch for server regeneration */ + if (g_ulServerGeneration != s_ulServerGeneration) + { + /* Store new server generation */ + s_ulServerGeneration = g_ulServerGeneration; + } + + /* Only retrieve new privates pointers if window handle is null or changed */ + if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) + && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL) + { +#if CYGDEBUG + winDebug ("winWindowProc - Setting privates handle\n"); +#endif + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + s_hwndLastPrivates = hwnd; + } + else if (s_pScreenPriv == NULL) + { + /* For safety, handle case that should never happen */ + s_pScreenInfo = NULL; + s_pScreen = NULL; + s_hwndLastPrivates = NULL; + } + + /* Branch on message type */ + switch (message) + { + case WM_TRAYICON: + return winHandleIconMessage (hwnd, message, wParam, lParam, + s_pScreenPriv); + + case WM_CREATE: +#if CYGDEBUG + winDebug ("winWindowProc - WM_CREATE\n"); +#endif + + /* + * Add a property to our display window that references + * this screens' privates. + * + * This allows the window procedure to refer to the + * appropriate window DC and shadow DC for the window that + * it is processing. We use this to repaint exposed + * areas of our display window. + */ + s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams; + s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + s_hwndLastPrivates = hwnd; + s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); + SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv); + + /* Setup tray icon */ + if (!s_pScreenInfo->fNoTrayIcon) + { + /* + * NOTE: The WM_CREATE message is processed before CreateWindowEx + * returns, so s_pScreenPriv->hwndScreen is invalid at this point. + * We go ahead and copy our hwnd parameter over top of the screen + * privates hwndScreen so that we have a valid value for + * that member. Otherwise, the tray icon will disappear + * the first time you move the mouse over top of it. + */ + + s_pScreenPriv->hwndScreen = hwnd; + + winInitNotifyIcon (s_pScreenPriv); + } + return 0; + + case WM_DISPLAYCHANGE: + /* We cannot handle a display mode change during initialization */ + if (s_pScreenInfo == NULL) + FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display " + "mode changed while we were intializing. This is " + "very bad and unexpected. Exiting.\n"); + + /* + * We do not care about display changes with + * fullscreen DirectDraw engines, because those engines set + * their own mode when they become active. + */ + if (s_pScreenInfo->fFullScreen + && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL +#ifdef XWIN_PRIMARYFB + || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD +#endif + )) + { + /* + * Store the new display dimensions and depth. + * We do this here for future compatibility in case we + * ever allow switching from fullscreen to windowed mode. + */ + s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); + s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); + s_pScreenPriv->dwLastWindowsBitsPixel + = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); + break; + } + + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, " + "new bpp: %d\n", + (int) s_pScreenInfo->dwBPP, + (int) s_pScreenPriv->dwLastWindowsBitsPixel, + wParam); + + ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " + "new height: %d\n", + LOWORD (lParam), HIWORD (lParam)); + + /* + * TrueColor --> TrueColor depth changes are disruptive for: + * Windowed: + * Shadow DirectDraw + * Shadow DirectDraw Non-Locking + * Primary DirectDraw + * + * TrueColor --> TrueColor depth changes are non-optimal for: + * Windowed: + * Shadow GDI + * + * FullScreen: + * Shadow GDI + * + * TrueColor --> PseudoColor or vice versa are disruptive for: + * Windowed: + * Shadow DirectDraw + * Shadow DirectDraw Non-Locking + * Primary DirectDraw + * Shadow GDI + */ + + /* + * Check for a disruptive change in depth. + * We can only display a message for a disruptive depth change, + * we cannot do anything to correct the situation. + */ + if ((s_pScreenInfo->dwBPP != wParam) + && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL +#ifdef XWIN_PRIMARYFB + || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD +#endif + )) + { + /* Cannot display the visual until the depth is restored */ + ErrorF ("winWindowProc - Disruptive change in depth\n"); + + /* Display Exit dialog */ + winDisplayDepthChangeDialog (s_pScreenPriv); + + /* Flag that we have an invalid screen depth */ + s_pScreenPriv->fBadDepth = TRUE; + + /* Minimize the display window */ + ShowWindow (hwnd, SW_MINIMIZE); + } + else + { + /* Flag that we have a valid screen depth */ + s_pScreenPriv->fBadDepth = FALSE; + } + + /* + * Check for a change in display dimensions. + * We can simply recreate the same-sized primary surface when + * the display dimensions change. + */ + if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam) + || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam)) + { + /* + * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface + * and CreatePrimarySurface function pointers to point + * to the no operation function, NoopDDA. This allows us + * to blindly call these functions, even if they are not + * relevant to the current engine (e.g., Shadow GDI). + */ + +#if CYGDEBUG + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); +#endif + + /* Release the old primary surface */ + (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); + +#if CYGDEBUG + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released " + "primary surface\n"); +#endif + + /* Create the new primary surface */ + (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); + +#if CYGDEBUG + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " + "primary surface\n"); +#endif + +#if 0 + /* Multi-Window mode uses RandR for resizes */ + if (s_pScreenInfo->fMultiWindow) + { + RRSetScreenConfig (); + } +#endif + } + else + { +#if CYGDEBUG + winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not " + "change\n"); +#endif + } + + /* Store the new display dimensions and depth */ + if (s_pScreenInfo->fMultipleMonitors) + { + s_pScreenPriv->dwLastWindowsWidth + = GetSystemMetrics (SM_CXVIRTUALSCREEN); + s_pScreenPriv->dwLastWindowsHeight + = GetSystemMetrics (SM_CYVIRTUALSCREEN); + } + else + { + s_pScreenPriv->dwLastWindowsWidth + = GetSystemMetrics (SM_CXSCREEN); + s_pScreenPriv->dwLastWindowsHeight + = GetSystemMetrics (SM_CYSCREEN); + } + s_pScreenPriv->dwLastWindowsBitsPixel + = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL); + break; + + case WM_SIZE: + { + SCROLLINFO si; + RECT rcWindow; + int iWidth, iHeight; + +#if CYGDEBUG + winDebug ("winWindowProc - WM_SIZE\n"); +#endif + + /* Break if we do not use scrollbars */ + if (!s_pScreenInfo->fScrollbars + || !s_pScreenInfo->fDecoration +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + || s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || s_pScreenInfo->fMultiWindow +#endif + || s_pScreenInfo->fFullScreen) + break; + + /* No need to resize if we get minimized */ + if (wParam == SIZE_MINIMIZED) + return 0; + + /* + * Get the size of the whole window, including client area, + * scrollbars, and non-client area decorations (caption, borders). + * We do this because we need to check if the client area + * without scrollbars is large enough to display the whole visual. + * The new client area size passed by lParam already subtracts + * the size of the scrollbars if they are currently displayed. + * So checking is LOWORD(lParam) == visual_width and + * HIWORD(lParam) == visual_height will never tell us to hide + * the scrollbars because the client area would always be too small. + * GetClientRect returns the same sizes given by lParam, so we + * cannot use GetClientRect either. + */ + GetWindowRect (hwnd, &rcWindow); + iWidth = rcWindow.right - rcWindow.left; + iHeight = rcWindow.bottom - rcWindow.top; + + ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, " + "new client area w: %d h: %d\n", + iWidth, iHeight, LOWORD (lParam), HIWORD (lParam)); + + /* Subtract the frame size from the window size. */ + iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME); + iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME) + + GetSystemMetrics (SM_CYCAPTION)); + + /* + * Update scrollbar page sizes. + * NOTE: If page size == range, then the scrollbar is + * automatically hidden. + */ + + /* Is the naked client area large enough to show the whole visual? */ + if (iWidth < s_pScreenInfo->dwWidth + || iHeight < s_pScreenInfo->dwHeight) + { + /* Client area too small to display visual, use scrollbars */ + iWidth -= GetSystemMetrics (SM_CXVSCROLL); + iHeight -= GetSystemMetrics (SM_CYHSCROLL); + } + + /* Set the horizontal scrollbar page size */ + si.cbSize = sizeof (si); + si.fMask = SIF_PAGE | SIF_RANGE; + si.nMin = 0; + si.nMax = s_pScreenInfo->dwWidth - 1; + si.nPage = iWidth; + SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); + + /* Set the vertical scrollbar page size */ + si.cbSize = sizeof (si); + si.fMask = SIF_PAGE | SIF_RANGE; + si.nMin = 0; + si.nMax = s_pScreenInfo->dwHeight - 1; + si.nPage = iHeight; + SetScrollInfo (hwnd, SB_VERT, &si, TRUE); + + /* + * NOTE: Scrollbars may have moved if they were at the + * far right/bottom, so we query their current position. + */ + + /* Get the horizontal scrollbar position and set the offset */ + si.cbSize = sizeof (si); + si.fMask = SIF_POS; + GetScrollInfo (hwnd, SB_HORZ, &si); + s_pScreenInfo->dwXOffset = -si.nPos; + + /* Get the vertical scrollbar position and set the offset */ + si.cbSize = sizeof (si); + si.fMask = SIF_POS; + GetScrollInfo (hwnd, SB_VERT, &si); + s_pScreenInfo->dwYOffset = -si.nPos; + } + return 0; + + case WM_VSCROLL: + { + SCROLLINFO si; + int iVertPos; + +#if CYGDEBUG + winDebug ("winWindowProc - WM_VSCROLL\n"); +#endif + + /* Get vertical scroll bar info */ + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo (hwnd, SB_VERT, &si); + + /* Save the vertical position for comparison later */ + iVertPos = si.nPos; + + /* + * Don't forget: + * moving the scrollbar to the DOWN, scroll the content UP + */ + switch (LOWORD(wParam)) + { + case SB_TOP: + si.nPos = si.nMin; + break; + + case SB_BOTTOM: + si.nPos = si.nMax - si.nPage + 1; + break; + + case SB_LINEUP: + si.nPos -= 1; + break; + + case SB_LINEDOWN: + si.nPos += 1; + break; + + case SB_PAGEUP: + si.nPos -= si.nPage; + break; + + case SB_PAGEDOWN: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + /* + * We retrieve the position after setting it, + * because Windows may adjust it. + */ + si.fMask = SIF_POS; + SetScrollInfo (hwnd, SB_VERT, &si, TRUE); + GetScrollInfo (hwnd, SB_VERT, &si); + + /* Scroll the window if the position has changed */ + if (si.nPos != iVertPos) + { + /* Save the new offset for bit block transfers, etc. */ + s_pScreenInfo->dwYOffset = -si.nPos; + + /* Change displayed region in the window */ + ScrollWindowEx (hwnd, + 0, + iVertPos - si.nPos, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + + /* Redraw the window contents */ + UpdateWindow (hwnd); + } + } + return 0; + + case WM_HSCROLL: + { + SCROLLINFO si; + int iHorzPos; + +#if CYGDEBUG + winDebug ("winWindowProc - WM_HSCROLL\n"); +#endif + + /* Get horizontal scroll bar info */ + si.cbSize = sizeof (si); + si.fMask = SIF_ALL; + GetScrollInfo (hwnd, SB_HORZ, &si); + + /* Save the horizontal position for comparison later */ + iHorzPos = si.nPos; + + /* + * Don't forget: + * moving the scrollbar to the RIGHT, scroll the content LEFT + */ + switch (LOWORD(wParam)) + { + case SB_LEFT: + si.nPos = si.nMin; + break; + + case SB_RIGHT: + si.nPos = si.nMax - si.nPage + 1; + break; + + case SB_LINELEFT: + si.nPos -= 1; + break; + + case SB_LINERIGHT: + si.nPos += 1; + break; + + case SB_PAGELEFT: + si.nPos -= si.nPage; + break; + + case SB_PAGERIGHT: + si.nPos += si.nPage; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + /* + * We retrieve the position after setting it, + * because Windows may adjust it. + */ + si.fMask = SIF_POS; + SetScrollInfo (hwnd, SB_HORZ, &si, TRUE); + GetScrollInfo (hwnd, SB_HORZ, &si); + + /* Scroll the window if the position has changed */ + if (si.nPos != iHorzPos) + { + /* Save the new offset for bit block transfers, etc. */ + s_pScreenInfo->dwXOffset = -si.nPos; + + /* Change displayed region in the window */ + ScrollWindowEx (hwnd, + iHorzPos - si.nPos, + 0, + NULL, + NULL, + NULL, + NULL, + SW_INVALIDATE); + + /* Redraw the window contents */ + UpdateWindow (hwnd); + } + } + return 0; + + case WM_GETMINMAXINFO: + { + MINMAXINFO *pMinMaxInfo = (MINMAXINFO *) lParam; + int iCaptionHeight; + int iBorderHeight, iBorderWidth; + +#if CYGDEBUG + winDebug ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n", + s_pScreenInfo); +#endif + + /* Can't do anything without screen info */ + if (s_pScreenInfo == NULL + || !s_pScreenInfo->fScrollbars + || s_pScreenInfo->fFullScreen + || !s_pScreenInfo->fDecoration +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + || s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || s_pScreenInfo->fMultiWindow +#endif + ) + break; + + /* + * Here we can override the maximum tracking size, which + * is the largest size that can be assigned to our window + * via the sizing border. + */ + + /* + * FIXME: Do we only need to do this once, since our visual size + * does not change? Does Windows store this value statically + * once we have set it once? + */ + + /* Get the border and caption sizes */ + iCaptionHeight = GetSystemMetrics (SM_CYCAPTION); + iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME); + iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME); + + /* Allow the full visual to be displayed */ + pMinMaxInfo->ptMaxTrackSize.x + = s_pScreenInfo->dwWidth + iBorderWidth; + pMinMaxInfo->ptMaxTrackSize.y + = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight; + } + return 0; + + case WM_ERASEBKGND: +#if CYGDEBUG + winDebug ("winWindowProc - WM_ERASEBKGND\n"); +#endif + /* + * Pretend that we did erase the background but we don't care, + * the application uses the full window estate. This avoids some + * flickering when resizing. + */ + return TRUE; + + case WM_PAINT: +#if CYGDEBUG + winDebug ("winWindowProc - WM_PAINT\n"); +#endif + /* Only paint if we have privates and the server is enabled */ + if (s_pScreenPriv == NULL + || !s_pScreenPriv->fEnabled + || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive) + || s_pScreenPriv->fBadDepth) + { + /* We don't want to paint */ + break; + } + + /* Break out here if we don't have a valid paint routine */ + if (s_pScreenPriv->pwinBltExposedRegions == NULL) + break; + + /* Call the engine dependent repainter */ + (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen); + return 0; + + case WM_PALETTECHANGED: + { +#if CYGDEBUG + winDebug ("winWindowProc - WM_PALETTECHANGED\n"); +#endif + /* + * Don't process if we don't have privates or a colormap, + * or if we have an invalid depth. + */ + if (s_pScreenPriv == NULL + || s_pScreenPriv->pcmapInstalled == NULL + || s_pScreenPriv->fBadDepth) + break; + + /* Return if we caused the palette to change */ + if ((HWND) wParam == hwnd) + { + /* Redraw the screen */ + (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); + return 0; + } + + /* Reinstall the windows palette */ + (*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen); + + /* Redraw the screen */ + (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen); + return 0; + } + + case WM_MOUSEMOVE: + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* We can't do anything without g_pwinPointer */ + if (g_pwinPointer == NULL) + break; + + /* Has the mouse pointer crossed screens? */ + if (s_pScreen != miPointerGetScreen(g_pwinPointer)) + miPointerSetScreen (g_pwinPointer, s_pScreenInfo->dwScreen, + GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, + GET_Y_LPARAM(lParam)-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 ("winWindowProc - _TrackMouseEvent failed\n"); + + /* Flag that we are tracking now */ + s_fTracking = TRUE; + } + + /* Hide or show the Windows mouse cursor */ + if (g_fSoftwareCursor && g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer)) + { + /* Hide Windows cursor */ + g_fCursor = FALSE; + ShowCursor (FALSE); + } + else if (g_fSoftwareCursor && !g_fCursor && !s_pScreenPriv->fActive + && !s_pScreenInfo->fLessPointer) + { + /* Show Windows cursor */ + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* Deliver absolute cursor position to X Server */ + winEnqueueMotion(GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, + GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset); + 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_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + 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_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam); + + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam); + + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + SetCapture (hwnd); + return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); + case WM_XBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + if (s_pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOWEXTWM + || s_pScreenInfo->fMWExtWM +#endif + ) + ReleaseCapture (); + return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); + + case WM_TIMER: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Branch on the timer id */ + switch (wParam) + { + case WIN_E3B_TIMER_ID: + /* Send delayed button press */ + winMouseButtonsSendEvent (ButtonPress, + s_pScreenPriv->iE3BCachedPress); + + /* Kill this timer */ + KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); + + /* Clear screen privates flags */ + s_pScreenPriv->iE3BCachedPress = 0; + break; + + case WIN_POLLING_MOUSE_TIMER_ID: + { + POINT point; + WPARAM wL, wM, wR, wShift, wCtrl; + LPARAM lPos; + + /* Get the current position of the mouse cursor */ + GetCursorPos (&point); + + /* Map from screen (-X, -Y) to root (0, 0) */ + point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN); + point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Deliver absolute cursor position to X Server */ + winEnqueueMotion(point.x , point.y); + + /* Check if a button was released but we didn't see it */ + GetCursorPos (&point); + wL = (GetKeyState (VK_LBUTTON) & 0x8000)?MK_LBUTTON:0; + wM = (GetKeyState (VK_MBUTTON) & 0x8000)?MK_MBUTTON:0; + wR = (GetKeyState (VK_RBUTTON) & 0x8000)?MK_RBUTTON:0; + wShift = (GetKeyState (VK_SHIFT) & 0x8000)?MK_SHIFT:0; + wCtrl = (GetKeyState (VK_CONTROL) & 0x8000)?MK_CONTROL:0; + lPos = MAKELPARAM(point.x, point.y); + if (g_fButton[0] & !wL) + PostMessage (hwnd, WM_LBUTTONUP, wCtrl|wM|wR|wShift, lPos); + if (g_fButton[1] & !wM) + PostMessage (hwnd, WM_MBUTTONUP, wCtrl|wL|wR|wShift, lPos); + if (g_fButton[2] & !wR) + PostMessage (hwnd, WM_RBUTTONUP, wCtrl|wL|wM|wShift, lPos); + } + } + return 0; + + case WM_CTLCOLORSCROLLBAR: + FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not " + "supposed to get this message. Exiting.\n"); + return 0; + + case WM_MOUSEWHEEL: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; +#if CYGDEBUG + winDebug ("winWindowProc - WM_MOUSEWHEEL\n"); +#endif + winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam)); + break; + + case WM_SETFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Restore the state of all mode keys */ + winRestoreModeKeyStates (); + + /* Add the keyboard hook if possible */ + if (g_fKeyboardHookLL) + g_fKeyboardHookLL = winInstallKeyboardHookLL (); + return 0; + + case WM_KILLFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Release any pressed keys */ + winKeybdReleaseKeys (); + + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); + return 0; + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* + * FIXME: Catching Alt-F4 like this is really terrible. This should + * be generalized to handle other Windows keyboard signals. Actually, + * the list keys to catch and the actions to perform when caught should + * be configurable; that way user's can customize the keys that they + * need to have passed through to their window manager or apps, or they + * can remap certain actions to new key codes that do not conflict + * with the X apps that they are using. Yeah, that'll take awhile. + */ + if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4 + && (GetKeyState (VK_MENU) & 0x8000)) + || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK + && (GetKeyState (VK_MENU) & 0x8000) + && (GetKeyState (VK_CONTROL) & 0x8000))) + { + /* + * Better leave this message here, just in case some unsuspecting + * user enters Alt + F4 and is surprised when the application + * quits. + */ + ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); + + /* Display Exit dialog */ + winDisplayExitDialog (s_pScreenPriv); + return 0; + } + + /* + * Don't do anything for the Windows keys, as focus will soon + * be returned to Windows. We may be able to trap the Windows keys, + * but we should determine if that is desirable before doing so. + */ + if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) + break; + + /* + * Discard presses generated from Windows auto-repeat + */ + if (lParam & (1<<30)) + { + switch (wParam) + { + /* ago: Pressing LControl while RControl is pressed is + * Indicated as repeat. Fix this! + */ + case VK_CONTROL: + case VK_SHIFT: + if (winCheckKeyPressed(wParam, lParam)) + return 0; + break; + default: + return 0; + } + } + + /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ + if (winIsFakeCtrl_L (message, wParam, lParam)) + return 0; + + /* Translate Windows key code to X scan code */ + winTranslateKey (wParam, lParam, &iScanCode); + + /* Ignore repeats for CapsLock */ + if (wParam == VK_CAPITAL) + lParam = 1; + + /* Send the key event(s) */ + for (i = 0; i < LOWORD(lParam); ++i) + winSendKeyEvent (iScanCode, TRUE); + return 0; + + case WM_SYSKEYUP: + case WM_KEYUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* + * Don't do anything for the Windows keys, as focus will soon + * be returned to Windows. We may be able to trap the Windows keys, + * but we should determine if that is desirable before doing so. + */ + if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) + break; + + /* Ignore the fake Ctrl_L that follows an AltGr release */ + if (winIsFakeCtrl_L (message, wParam, lParam)) + return 0; + + /* Enqueue a keyup event */ + winTranslateKey (wParam, lParam, &iScanCode); + winSendKeyEvent (iScanCode, FALSE); + + /* Release all pressed shift keys */ + if (wParam == VK_SHIFT) + winFixShiftKeys (iScanCode); + return 0; + + case WM_HOTKEY: + if (s_pScreenPriv == NULL) + break; + + /* Call the engine-specific hot key handler */ + (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen); + return 0; + + case WM_ACTIVATE: + if (s_pScreenPriv == NULL + || s_pScreenInfo->fIgnoreInput) + break; + + /* TODO: Override display of window when we have a bad depth */ + if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) + { + ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying " + "to override window activation\n"); + + /* Minimize the window */ + ShowWindow (hwnd, SW_MINIMIZE); + + /* Display dialog box */ + if (g_hDlgDepthChange != NULL) + { + /* Make the existing dialog box active */ + SetActiveWindow (g_hDlgDepthChange); + } + else + { + /* TODO: Recreate the dialog box and bring to the top */ + ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); + } + + /* Don't do any other processing of this message */ + return 0; + } + +#if CYGDEBUG + winDebug ("winWindowProc - WM_ACTIVATE\n"); +#endif + + /* + * Focus is being changed to another window. + * The other window may or may not belong to + * our process. + */ + + /* Clear any lingering wheel delta */ + s_pScreenPriv->iDeltaZ = 0; + + /* Reshow the Windows mouse cursor if we are being deactivated */ + if (g_fSoftwareCursor && LOWORD(wParam) == WA_INACTIVE + && !g_fCursor) + { + /* Show Windows cursor */ + g_fCursor = TRUE; + ShowCursor (TRUE); + } + return 0; + + case WM_ACTIVATEAPP: + if (s_pScreenPriv == NULL + || s_pScreenInfo->fIgnoreInput) + break; + +#if CYGDEBUG || TRUE + winDebug ("winWindowProc - WM_ACTIVATEAPP\n"); +#endif + + /* Activate or deactivate */ + s_pScreenPriv->fActive = wParam; + + /* Reshow the Windows mouse cursor if we are being deactivated */ + if (g_fSoftwareCursor && !s_pScreenPriv->fActive + && !g_fCursor) + { + /* Show Windows cursor */ + g_fCursor = TRUE; + ShowCursor (TRUE); + } + +#ifdef XWIN_CLIPBOARD + /* Make sure the clipboard chain is ok. */ + winFixClipboardChain (); +#endif + + /* Call engine specific screen activation/deactivation function */ + (*s_pScreenPriv->pwinActivateApp) (s_pScreen); + +#ifdef XWIN_MULTIWINDOWEXTWM + if (s_pScreenPriv->fActive) + { + /* Restack all window unless using built-in wm. */ + if (s_pScreenInfo->fInternalWM && s_pScreenInfo->fAnotherWMRunning) + winMWExtWMRestackWindows (s_pScreen); + } +#endif + + return 0; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case ID_APP_EXIT: + /* Display Exit dialog */ + winDisplayExitDialog (s_pScreenPriv); + return 0; + +#ifdef XWIN_MULTIWINDOW + case ID_APP_HIDE_ROOT: + if (s_pScreenPriv->fRootWindowShown) + ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE); + else + ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW); + s_pScreenPriv->fRootWindowShown = !s_pScreenPriv->fRootWindowShown; + return 0; +#endif + + case ID_APP_ABOUT: + /* Display the About box */ + winDisplayAboutDialog (s_pScreenPriv); + return 0; + + default: + /* It's probably one of the custom menus... */ + if (HandleCustomWM_COMMAND (0, LOWORD (wParam))) + return 0; + } + break; + + case WM_ENDSESSION: + case WM_GIVEUP: + /* Tell X that we are giving up */ +#ifdef XWIN_MULTIWINDOW + if (s_pScreenInfo->fMultiWindow) + winDeinitMultiWindowWM (); +#endif + GiveUp (0); + return 0; + + case WM_CLOSE: + /* Display Exit dialog */ + winDisplayExitDialog (s_pScreenPriv); + return 0; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + if (!g_fSoftwareCursor) SetCursor (s_pScreenPriv->cursor.handle); + return TRUE; + } + break; + +#ifdef XWIN_MULTIWINDOWEXTWM + case WM_MANAGE: + ErrorF ("winWindowProc - WM_MANAGE\n"); + s_pScreenInfo->fAnotherWMRunning = FALSE; + + if (s_pScreenInfo->fInternalWM) + { + EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); + //RootlessRepositionWindows (s_pScreen); + } + break; + + case WM_UNMANAGE: + ErrorF ("winWindowProc - WM_UNMANAGE\n"); + s_pScreenInfo->fAnotherWMRunning = TRUE; + + if (s_pScreenInfo->fInternalWM) + { + EnumThreadWindows (g_dwCurrentThreadID, winMWExtWMDecorateWindow, 0); + winMWExtWMRestackWindows (s_pScreen); + } + break; +#endif + + default: + if(message == s_uTaskbarRestart) + { + winInitNotifyIcon (s_pScreenPriv); + } + break; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} -- cgit v1.2.3