diff options
115 files changed, 44913 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore index afd5415b0..548e78423 100644 --- a/.gitignore +++ b/.gitignore @@ -284,6 +284,7 @@ include/xgl-config.h include/xkb-config.h include/xorg-config.h include/xorg-server.h +include/xwin-config.h mfb/mfbbltC.c mfb/mfbbltCI.c mfb/mfbbltG.c diff --git a/configure.ac b/configure.ac index ca16c5a06..d3a231705 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,8 @@ dnl xorg-config.h covers the Xorg DDX. AC_CONFIG_HEADERS(include/xorg-config.h) dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs. AC_CONFIG_HEADERS(include/xkb-config.h) +dnl xwin-config.h covers the XWin DDX. +AC_CONFIG_HEADERS(include/xwin-config.h) dnl kdrive-config.h covers the kdrive DDX AC_CONFIG_HEADERS(include/kdrive-config.h) @@ -564,6 +566,7 @@ AC_ARG_ENABLE(xquartz, AS_HELP_STRING([--enable-xquartz], [Build Xquartz AC_ARG_ENABLE(x11app, AS_HELP_STRING([--enable-x11app], [Build Apple's X11.app for Xquartz (default: auto)]), [X11APP=$enableval], [X11APP=auto]) AC_ARG_WITH(x11app-archs, AS_HELP_STRING([--with-x11app-archs=ARCHS], [Architectures to build X11.app for, space delimeted (default: "ppc i386")]), [X11APP_ARCHS=$enableval], [X11APP_ARCHS="ppc i386"]) AC_SUBST([X11APP_ARCHS]) +AC_ARG_ENABLE(xwin, AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto]) AC_ARG_ENABLE(xprint, AS_HELP_STRING([--enable-xprint], [Build Xprint extension and server (default: no)]), [XPRINT=$enableval], [XPRINT=no]) AC_ARG_ENABLE(xgl, AS_HELP_STRING([--enable-xgl], [Build Xgl server (default: no)]), [XGL=$enableval], [XGL=no]) AC_ARG_ENABLE(xglx, AS_HELP_STRING([--enable-xglx], [Build Xglx xgl module (default: no)]), [XGLX=$enableval], [XGLX=no]) @@ -1636,6 +1639,76 @@ if test "x$XPRINT" = xyes; then fi AM_CONDITIONAL(XP_USE_FREETYPE, [test "x$XPRINT" = xyes && test "x$XP_USE_FREETYPE" = xyes]) + +dnl XWin DDX + +AC_MSG_CHECKING([whether to build XWin DDX]) +if test "x$XWIN" = xauto; then + case $host_os in + cygwin*) XWIN="yes" ;; + mingw*) XWIN="yes" ;; + *) XWIN="no" ;; + esac + XWIN_LIBS="$FB_LIB $XEXT_LIB $CONFIG_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $LAYER_LIB $XPSTUBS_LIB $SHADOW_LIB" + AC_SUBST([XWIN_LIBS]) +fi +AC_MSG_RESULT([$XWIN]) + +if test "x$XWIN" = xyes; then + case $host_os in + cygwin*) + XWIN_SERVER_NAME=XWin + PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont]) + AC_DEFINE(HAS_DEVWINDOWS,1,[Cygwin has /dev/windows for signaling new win32 messages]) + AC_DEFINE(ROOTLESS,1,[Build Rootless code]) + CFLAGS="$CFLAGS -DFD_SETSIZE=256" + ;; + mingw*) + XWIN_SERVER_NAME=Xming + PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont]) + AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location]) + AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets]) + XWIN_SYS_LIBS=-lwinsock2 + ;; + esac + XWIN_SYS_LIBS="$XWIN_SYS_LIBS $(XWINMODULES_LIBS)" + AC_SUBST(XWIN_SERVER_NAME) + AC_SUBST(XWIN_SYS_LIBS) + + if test "x$DEBUGGING" = xyes; then + AC_DEFINE(CYGDEBUG, 1, [Simple debug messages]) + AC_DEFINE(CYGWINDOWING_DEBUG, 1, [Debug messages for window handling]) + AC_DEFINE(CYGMULTIWINDOW_DEBUG, 1, [Debug window manager]) + fi + + AC_DEFINE(DDXOSINIT, 1, [Use OsVendorInit]) + AC_DEFINE(DDXTIME, 1, [Use GetTimeInMillis]) + AC_DEFINE(DDXOSFATALERROR, 1, [Use OsVendorFatalError]) + AC_DEFINE(DDXOSVERRORF, 1, [Use OsVendorVErrorF]) + AC_DEFINE(DDXBEFORERESET, 1, [Use ddxBeforeReset ]) + if test "x$XF86VIDMODE" = xyes; then + AC_MSG_NOTICE([Disabling XF86VidMode extension]) + XF86VIDMODE=no + fi + if test "x$XF86MISC" = xyes; then + AC_MSG_NOTICE([Disabling XF86Misc extension]) + XF86MISC=no + fi + if test "x$COMPOSITE" = xyes; then + AC_MSG_NOTICE([Disabling Composite extension]) + COMPOSITE=no + fi +fi +AM_CONDITIONAL(XWIN, [test "x$XWIN" = xyes]) +AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes]) +AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && false]) +AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes]) +AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && false]) +AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes && false]) +AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes && false]) +AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes]) +AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes]) + dnl Darwin / OS X DDX if test "X$XQUARTZ" = Xauto; then AC_CACHE_CHECK([whether to build Xquartz],xorg_cv_Carbon_framework,[ @@ -2133,6 +2206,7 @@ hw/xgl/glx/module/Makefile hw/xgl/glxext/Makefile hw/xgl/glxext/module/Makefile hw/xnest/Makefile +hw/xwin/Makefile hw/xquartz/Makefile hw/xquartz/bundle/Makefile hw/xquartz/xpr/Makefile diff --git a/hw/Makefile.am b/hw/Makefile.am index 011a280ed..c2b9571b9 100644 --- a/hw/Makefile.am +++ b/hw/Makefile.am @@ -14,6 +14,10 @@ if XNEST XNEST_SUBDIRS = xnest endif +if XWIN +XWIN_SUBDIRS = xwin +endif + if XGL XGL_SUBDIRS = xgl endif @@ -33,6 +37,7 @@ endif SUBDIRS = \ $(XORG_SUBDIRS) \ $(XGL_SUBDIRS) \ + $(XWIN_SUBDIRS) \ $(XVFB_SUBDIRS) \ $(XNEST_SUBDIRS) \ $(DMX_SUBDIRS) \ @@ -40,7 +45,7 @@ SUBDIRS = \ $(XQUARTZ_SUBDIRS) \ $(XPRINT_SUBDIRS) -DIST_SUBDIRS = dmx xfree86 vfb xnest xquartz kdrive xgl xprint +DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xgl xprint relink: for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink ; done diff --git a/hw/xwin/ChangeLog b/hw/xwin/ChangeLog new file mode 100644 index 000000000..aca2ffcb1 --- /dev/null +++ b/hw/xwin/ChangeLog @@ -0,0 +1,683 @@ +2006-03-03 Alan Hourihane <alanh@fairlite.demon.co.uk> + + * winprefs.c: (HandleCustomWM_COMMAND): + https://bugs.freedesktop.org/show_bug.cgi?id=4341 + Make Xming error messages more meaningful. + +2006-03-03 Alan Hourihane <alanh@fairlite.demon.co.uk> + + * winmultiwindowwndproc.c: (winTopLevelWindowProc): + * winwndproc.c: (winWindowProc): + https://bugs.freedesktop.org/show_bug.cgi?id=4538 + Fix mouse button release on multiwindows scrolling. + +2006-03-03 Alan Hourihane <alanh@fairlite.demon.co.uk> + + * winmultiwindowicons.c: (winXIconToHICON), (winUpdateIcon): + * winwin32rootlesswindow.c: (winMWExtWMUpdateIcon): + https://bugs.freedesktop.org/show_bug.cgi?id=5138 + Check for NULL pointer + +2005-07-05 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwm.c: + Fix crash on server shutdown + +2005-07-05 Alexander Gottwald <ago at freedesktop dot org> + + * winkeybd.c: + * winkeybd.h: + * winwndproc.c: + Fix simultanious presses of Left and Right Control and Shift keys. + https://bugs.freedesktop.org/show_bug.cgi?id=3677 + +2005-07-05 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwm.c: + Fix typo which broke window titles + +2005-07-05 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + * winkeybd.c: + Fix problem with fake Control press on Alt-Gr + https://bugs.freedesktop.org/show_bug.cgi?id=3680 + https://bugs.freedesktop.org/show_bug.cgi?id=3497 + + * InitOutput.c: + Fix static declaration of winGetBaseDir + +2005-07-05 Alexander Gottwald <ago at freedesktop dot org> + + * winwindow.h: + * winmultiwindowwm.c: + * winscrinit.c: + External windowmanagers could connect in multiwindow mode which lead + to strange results with the internal windowmanager. + +2005-07-05 Alexander Gottwald <ago at freedesktop dot org> + + * *.c: + Include xwin-config.h if HAVE_XWIN_CONFIG is defined + Cleanup X11 includes handling + Warning fixes + +2005-06-30 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + Pass serverClient instead of NULL to ConfigureWindow. + This should fix a crash reported by Øyvind Harboe + +2005-06-08 Alexander Gottwald <ago at freedesktop dot org> + + * winlayouts.h: + Merge from CYGWIN + Added layout "French (Canada)" as ca_enhanced + Added Czech (QWERTY) layout + * winshaddnl.c: + Merge from CYGWIN + Print error code if winStoreColorsShadowDDNL fails + +2005-06-08 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwindow.c: + Fix crash reported by Øyvind Harboe + +2005-06-03 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + * winblock.c: + Backout last winRaiseWindow patch which caused stacking problems + +2005-05-25 Alexander Gottwald <ago at freedesktop dot org> + + * win.h: + * winmultiwindowwm.c: + Workaround bug in pthread.h + +2005-05-08 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + * winblock.c: + Only call ConfigureWindow from winRaiseWindow if the windows + message dispatch loop is running. + +2005-05-02 Alexander Gottwald <ago at freedesktop dot org> + + * winerror.c: + Print correct logfile in FatalError message + +2005-04-19 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + Prevent recursive calls to winRaiseWindow. + +2005-03-10 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + Force rebuilding of window stack if a window changes it's state from + minimized. + +2005-03-07 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + * winmultiwindowwindow.c: + Prevent winRaiseWindow from calling ConfigureWindow if the message + was sent from within winDestroyWindowsWindow + + DestroyWindow send a WM_WINDOWPOSCHANGED to another window causing + a restacking of all windows, even of the window which is just about + to destroyed and whose structures may not be intact anymore. + +2005-02-24 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + on WM_WINDOWPOSCHANGED raise window directly and in sync without + utilizing the async windowmanager thread. Fixes some restacking + problems occuring which were timing dependent + Do not raise the window on WM_ACTIVATE + Removed unused code for WM_WINDOWPOSCHANGING + ESC is debug key. Print status but do not abort processing the message + +2005-02-12 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwindow.c + * winmultiwindowwndproc.c + * winwin32rootlesswndproc.c: + Cleanup some message debugging + +2005-02-12 Alexander Gottwald <ago at freedesktop dot org> + + * win.h + * winfont.c + * winmultiwindowshape.c + * winmultiwindowwindow.c + * winpfbdd.c + * winshaddd.c + * winshadddnl.c + * winshadgdi.c + * winwindow.c: + Fix incorrect wrapping of functions. Ensure the pointers from pScreen + point to the called function even if wrapped functions changed it + + * winmultiwindowwindow.c: + Set the window properties to NULL to avoid referencing freed memory + because of timing problems after deleting a window + + * winscrinit.c: + Do not wrap ChangeWindowAttributes. All functions are noops currently + +2005-02-12 Alexander Gottwald <ago at freedesktop dot org> + + * winmsg.h: + * winmsg.c: + print window handle in message output + +2005-02-08 Alexander Gottwald <ago at freedesktop dot org> + + * winkeybd.c: + * winkeynames.h: + Updated fix for ABNT2 and HK_Toggle keys. + +2005-02-08 Alexander Gottwald <ago at freedesktop dot org> + + * winkeybd.h: + * winkeynames.h: + Backout ABNT2 and HK_Toggle fix since it broke keys F1 and F4. + +2005-02-07 Alexander Gottwald <ago at freedesktop dot org> + + * winlayouts.h: + * winconfig.c: + Moved keyboard layout table to external file. + +2005-02-02 Alexander Gottwald <ago at freedesktop dot org> + + * wincreatewnd.c: + Force ShowWindow if XWin was started via run.exe. Fixes mainwindow + not showing bug + +2005-01-31 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwindow.c + * winmultiwindowwndproc.c: + Create windows with SWP_NOACTIVATE flag (updated) (Kensuke Matsuzaki) + +2005-01-31 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwndproc.c: + Fixes for window ordering problem (updated) (Kensuke Matsuzaki) + +2005-01-31 Alexander Gottwald <ago at freedesktop dot org> + + * winconfig.c: + Added hungarian keyboard layout. + +2005-01-31 Alexander Gottwald <ago at freedesktop dot org> + + * winmessages.h + * winmsg.h + * winmsg.c + * winmultiwindowwndproc.c + * winwin32rootlesswndproc.c + * winwndproc.c: + Make logging of messages configurable with environment variables + +2005-01-31 Alexander Gottwald <ago at freedesktop dot org> + + * InitOutput.c: + resolve SHGetFolderPath dynamicly since it is not available on all Windows + systems. + +2005-01-12 Alexander Gottwald <ago at freedesktop dot org> + + * winmsg.c + * winmsg.h: + Introduce function winTrace which prints log message with verbosity 10 + * winmultiwindowwindow.c: + Use winTrace for 3 heavily called functions + +2005-01-11 Alexander Gottwald <ago at freedesktop dot org> + + * XWin.man: + Document the -silent-dup-error switch + +2005-01-11 Alexander Gottwald <ago at freedesktop dot org> + + * winkeyhook.c: + Do not grab ALT-TAB when window is in multiwindow mode + +2005-01-11 Alexander Gottwald <ago at freedesktop dot org> + + * winprefs.h: + Fix crash with not matching definitions of PATH_MAX + +2005-01-10 Alexander Gottwald <ago at freedesktop dot org> + + * winkeybd.h + * winkeynames.h: + Adjust keysyms for Hiragana_Katakana toggle and backslash/underscore + on Japanese and ABNT2 keyboards + +2005-01-10 Alexander Gottwald <ago at freedesktop dot org> + + * winkeybd.h + * winkeyhook.c + * winwndproc.c: + Make keyhook feature work in multiwindowmode too + Hook windows keys + +2005-01-08 Alexander Gottwald <ago at freedesktop dot org> + + * winblock.c: + Fix a possible null-pointer dereference (Keishi Suenaga) + +2005-01-06 Alexander Gottwald <ago at freedesktop dot org> + + * Imakefile + * InitOutput.c + * XWin.rc + * winerror.c + * wintrayicon.c + * winvideo.c + * winshaddd.c + * winwindow.h: + Set PROJECT_NAME in Imakefile to create alternative window titles + for Cygwin/X and Xming + +2005-01-06 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowclass.c: + * winmultiwindowwm.c: + Fix crash with non-nullterminated strings (reported by Øyvind Harboe) + +2004-12-14 Alexander Gottwald <ago at freedesktop dot org> + + * InitOutput.c: + * winprocarg.c: + EnumDisplayMonitors is not available on Window NT4 and 95. Resolve + the function dynamicly + +2004-12-08 Alexander Gottwald <ago at freedesktop dot org> + + * InitOutput.c: + * winprocarg.c: + Added support for placing the main window with the @<monitor#>. + Patch by Mark Fisher, small changes by Alexander Gottwald + +2004-12-06 Alexander Gottwald <ago at freedesktop dot org> + + * XWin.rc: + include windows.h + +2004-12-05 Alexander Gottwald <ago at freedesktop dot org> + + * ddraw.h: + redone ddraw.h to be able to mix it with w32api style COM header + files. + + * winmultiwindowwm.c: + * obj_base.h: + * ddraw.h: + obj_base.h is not needed anymore. Using <objbase.h> instead. + + * winms.h: + Use Xwindows.h instead of windows.h + + * winresource.h: + do not include win_ms.h + + * win.h: + remove extra definition of sleep() + + * InitOutput.c: + Set HOME to Documents and Settings/username if not set + + * winprefs.c: + Use Xming basedir instead of ProjectRoot for system.XWinrc + + * windialogs.c: + * winshadgdi.c: + * winprefs.c: + Fix callback functions to use wBOOL instead of BOOL + + * winmultiwindowwindow.c: + * winwin32rootless.c: + * winwin32rootlesswindow.c: + * winerror.c: + Fix compiler warnings. Added debug output. + + * winconfig.c: + Fix warning about undefined macro max + +2004-12-04 Earle Philhower + + * InitOutput.c: + * win.h: + * wincreatewnd.c: + * winprocarg.c: + Optional position -screen parameter (-screen n WxH+X+Y or + -screen n W H X Y) + +2004-12-03 Alexander Gottwald <ago at freedesktop dot org> + + * windialogs.c: + * win.h: + * Imakefile: + * winerror.c: + Removed scprintf, aprintf and snprintf stuff and use newXprintf + +2004-12-02 Alexander Gottwald <ago at freedesktop dot org> + + * winwin32rootless.c: + Adjust the width of the rootless backbuffer to match 32 bit alignment + + * winprocarg.c: + Make multiplemonitors default for -internalwm + +2004-12-01 Alexander Gottwald <ago at freedesktop dot org> + + * InitOutput.c: + Set XERRORDB environment variable to relocate the XErrorDB file + +2004-11-29 Kensuke Matsuzaki <zakki@peppermint.jp> + + * winmultiwindowwm.c: + Fixed windows.h include for cygwin. + + * winmultiwindowwindow.c: + Bugzilla #1945: Stop unnecessary reordering. + +2004-11-24 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwm.c: + Finally the multiwindow mode defines a default cursor + +2004-11-22 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowwm.c: + Fixes for building multiwindow and internalwm on mingw + * winwin32rootless.c: + Changed some debugging output + +2004-11-22 Alexander Gottwald <ago at freedesktop dot org> + + * InitOutput.c, winglobals.c, winprocarg.c: + Xming: Place logfile in users tempdir + +2004-11-15 Alexander Gottwald <ago at freedesktop dot org> + + * Imakefile: + Remove override of HasSnprintf + +2004-11-15 Alexander Gottwald <ago at freedesktop dot org> + + * Imakefile: + * InitInput.c: (InitInput): + * InitOutput.c: (winClipboardShutdown), (ddxGiveUp), + (winCheckMount), (winGetBaseDir), (winFixupPaths), (OsVendorInit), + (winCheckDisplayNumber): + * win.h: + * winblock.c: (winBlockHandler): + * winclipboard.h: + * winclipboardthread.c: (winClipboardProc): + * winclipboardwndproc.c: (winClipboardWindowProc): + * winconfig.c: (winConfigKeyboard), (winConfigFiles): + * wincreatewnd.c: (winCreateBoundingWindowWindowed): + * windialogs.c: (winDisplayExitDialog), (winExitDlgProc), + (winAboutDlgProc): + * winengine.c: (winSetEngine): + * winerror.c: (OsVendorVErrorF), (winMessageBoxF), (scprintf): + * winglobals.c: (winInitializeGlobals): + * winkeybd.c: (winKeybdReleaseKeys): + * winmultiwindowicons.c: + * winmultiwindowwindow.c: (winCreateWindowsWindow): + * winmultiwindowwm.c: + * winprefs.c: (ReloadPrefs), (HandleCustomWM_COMMAND): + * winprocarg.c: (ddxProcessArgument): + * winscrinit.c: (winFinishScreenInitFB): + * winshadddnl.c: + * wintrayicon.c: (winHandleIconMessage): + * winwakeup.c: (winWakeupHandler): + * winwin32rootless.c: (winMWExtWMCreateFrame): + * winwindow.c: (winReshapeRootless): + * winwindow.h: + * winwndproc.c: (winWindowProc): + Bufzilla #1802, http://freedesktop.org/bugzilla/show_bug.cgi?id=1802 + Added mingw (Win32) port + +2004-11-11 Alexander Gottwald <ago at freedesktop dot org> + + * winconfig.c: + added keyboard layout "French (Switzerland)" + +2004-11-06 Alexander Gottwald <ago at freedesktop dot org> + + * winwndproc.c, wintrayicon.c, winscrinit.c: + * winmultiwindowwindow.c: + Wrap all mwextwm and internalwm code with XWIN_MULTIWINDOWEXTWM + +2004-11-04 Kensuke Matsuzaki <zakki@peppermint.jp> + + * InitOutput.c: (winUseMsg): + * win.h: + * winmultiwindowwindow.c: (winMinimizeWindow): + * winmultiwindowwm.c: (PushMessage), (UpdateName), + (PreserveWin32Stack), (winMultiWindowWMProc), + (winMultiWindowXMsgProc), (winInitWM), (winInitMultiWindowWM), + (CheckAnotherWindowManager): + * winprocarg.c: (winInitializeDefaultScreens), + (ddxProcessArgument): + * winscrinit.c: (winFinishScreenInitFB): + * wintrayicon.c: (winHandleIconMessage): + * winwin32rootless.c: (InitWin32RootlessEngine), + (winMWExtWMResizeFrame), (winMWExtWMRestackFrame), + (winMWExtWMStartDrawing), (winMWExtWMRootlessSwitchWindow), + (winMWExtWMSetNativeProperty): + * winwin32rootlesswindow.c: (winMWExtWMReorderWindows), + (winMWExtWMDecorateWindow), (winMWExtWMUpdateWindowDecoration), + (winIsInternalWMRunning), (winMWExtWMRestackWindows): + * winwin32rootlesswndproc.c: (winMWExtWMWindowProc): + * winwindow.h: + * winwndproc.c: (winWindowProc): + Add internalwm mode. + +2004-10-28 Alexander Gottwald <ago at freedesktop dot org> + + * win.h: + add fRetryCreateSurface + * winshaddnl.c (winBltExposedRegionsShadowDDNL): + try to recreate the primary surface if it was lost + * winshaddnl.c (winCreatePrimarySurfaceShadowDDNL): + mark screen to retry creating the primary surface if it failed + +2004-10-23 Alexander Gottwald <ago at freedesktop dot org> + + * winconfig (winConfigFiles): + Simplify /etc/X11/font-dirs parsing + +2004-10-20 Alexander Gottwald <ago at freedesktop dot org> + + * XWin.rc, winresource.h, winwndproc.c: + Add ShowCursor entry to tray menu + +2004-10-20 Alexander Gottwald <ago at freedesktop dot org> + + * Imakefile: + Add ETCX11DIR to DEFINES + * InitOutput.c (InitOutput): + * winconfig.c (winConfigFiles) : + Add entries from /etc/X11/font-dirs to default fontpath + +2004-10-16 Alexander Gottwald <ago at freedesktop dot org> + + * winprocarg.c (winInitializeDefaultScreens, ddxProcessArgument): + * win.h: + Make multiple monitors default for -multiwindow and -mwextwm. + Added a flag to indicate if the user has overridden the multimonitor + settings. (Øyvind Harboe, Alexander Gottwald) + +2004-10-07 Torrey Lyons <torrey at freedesktop dot org> + + * winscrinit.c: + Add compatibility with the generic rootless layer's new + DoReorderWindow function. + +2004-10-05 Alexander Gottwald <ago at freedesktop dot org> + + * XWin.rc: + Set the dialogstyle to DS_CENTERMOUSE. Dialogs will now popup on the + monitor where the mouse is and not on the center of the whole desktop. + +2004-10-02 Alexander Gottwald <ago at freedesktop dot org> + + * winmouse.c (winMouseProc): + Make sure buttons 1-3 are mouse buttons and wheel events are 4-5 + Document code + Replace ErrorF with appropriate winMsg + use a symbolic name for the wheel event offset + +2004-10-01 Alexander Gottwald <ago at freedesktop dot org> + + * wincreatewnd.c (winCreateBoundingWindowWindowed): + Do not adjust workarea if native windowmanager is used + +2004-09-22 Kensuke Matsuzaki + + * winclipboardthread.c (winClipboardErrorHandler): + * winclipboardwndproc.c (winClipboardWindowProc): + * winclipboardxevents.c (winClipboardFlushXEvents): + Fix clipboard bug with unicode applications. + +2004-09-17 Torrey Lyons <torrey at freedesktop dot org> + + * winscrinit.c: (winFinishScreenInitFB): + Bugzilla #1032: Make rootless acceleration functions compatible with + Damage. + +2004-09-16 Alexander Gottwald <ago at freedesktop dot org> + + * wincreatewnd.c (winCreateBoundingWindowWindowed): + Remove code which prevented the use from specifying the window + size in nodecoration mode. + +2004-08-26 Chris B <news at sempermax dot com> + + * win.h, winmessages.h: + Add defines for WM_XBUTTON + * winmouse.c (winMouseProc): + Query number of mouse buttons from windows. + * winmultiwindowwndproc.c (winTopLevelWindowProc): + * winwin32rootlesswndproc.c (winMWExtWMWindowProc): + * winwndproc.c (winWindowProc): + Handle WM_XBUTTON messages. + +2004-08-02 Kensuke Matsuzaki + + * winclipboardthread.c winclipboardwndproc.c: + * winclipboardxevents.c winwin32rootlesswndproc.c: + Fix the bug that we can't copy & paste multi-byte string to + Unicode-base Windows application. Rename fUnicodeSupport to + fUseUnicode, because it don't mean wheather Windows support + Unicode or not. + +2004-07-31 Alexander Gottwald <ago at freedesktop dot org> + + * win.h: + adjust prototype for winInitCmapPrivates to match Egberts change. + +2004-07-30 Egbert Eich <eich at freedesktop dot org> + + * winallpriv.c: (winInitCmapPrivates): + test if colormap with index really exists in the list of + installed maps before using it. + +2004-07-09 Alexander Gottwald <ago at freedesktop dot org> + + * winconfig.c: Add entry for irish layout (ie) + * InitOutput.c, winerror.c, winglobals.c: rename g_fUseMsg to + g_fSilentFatalError + * InitOutput.c, winglobals.c, winprocarg.c: added commandline option + -silent-dup-error to allow silent termination if another instance of + XWin was found running + +2004-06-27 Alexander Gottwald <ago at freedesktop dot org> + + * winconfig.c: Add entry for us layout. This changes not much but + removes a strange error message about the unknown us layout. + +2004-06-24 Alexander Gottwald <ago at freedesktop dot org> + + * InitOutput.c: Check for textmode mounted /tmp and print a warning + +2004-06-15 Harold Hunt <huntharo at msu dot edu> + + * windialogs.c: Fix path to locally installed changelog for the About + dialog box. + +2004-05-27 Alexander Gottwald <ago at freedesktop dot org> + + * winpriv.c: Create win32 window if not already created + * winmultiwindowwindow.c: Export winCreateWindowWindow + +2004-05-27 Alexander Gottwald <ago at freedesktop dot org> + + * win.h: Allow CYGDEBUG to defined in the Makefile + * winwindow.h: Allow CYGWINDOWING_DEBUG to defined in the Makefile + +2004-05-19 Alexander Gottwald <ago at freedesktop dot org> + + * winmultiwindowicons.c (winInitGlobalIcons): Load the small default + icon too + * winprefs.h, winprefs.c (winOverrideDefaultIcon): Takes the iconsize + as parameter + +2004-05-19 Alexander Gottwald <ago at freedesktop dot org> + + * win.h, winmultiwindowicons.c (winXIconToHICON): Takes iconsize + as parameter + * winglobals.c, winmultiwindowicons.c: Rename g_hiconX to g_hIconX. + Added new variable g_hSmallIconX for 16x16 icon. + * winwindow.h, winmultiwindowicons.c (winInitGlobalIcons): Inits the + global g_hIconX handles. + * winwindow.h, winmultiwindowicons.c (winDestroyIcon): Free the icon + without messing with the global icon handle. + * winmultiwindowicons.c (winSelectIcons): Generate a custom icon from + window settigns or set them to globals. + * winmultiwindowshape.c, winmultiwindowwindow.c, winwin32rootless.c, + winwin32rootlesswindow.c, winwin32rootlesswndproc.c: Remove + declaration of g_hiconX; + * winmultiwindowwindow.c (winCreateWindowsWindow), + winwin32rootless.c (winMWExtWMCreateFrame): Use winSelectIcons + to get the window icons. Set the small icon too. + * winmultiwindowwindow.c (winDestroyWindowsWindow), + winmultiwindowicons.c (winUpdateIcon), + winprefs.c (ReloadEnumWindowsProc), + winwin32rootlesswindow.c (winMWExtWMUpdateIcon), + winwin32rootless.c (winMWExtWMDestroyFrame): Use winDestroyIcon + to free the icon without destroying the global icon. + +2004-05-17 Alexander Gottwald <ago at freedesktop dot org> + + * windialogs.c (winExitDlgProc, winAboutDlgProc), + winmultiwindowwndproc.c (winTopLevelWindowProc), + winwndproc.c (winWindowProc): Check if g_fSoftwareCursor is set + before calling ShowCursor. + +2004-05-09 Dan Wilks <Dan_Wilks at intuit dot com> + + * winclipboard.h: Add extern prototypes for winDebug, winErrorFVerb + copied from winmsg.h. + * winclipboardinit.c (winFixClipboardChain): Post rather than send the + reinit message to the clipboard window. Sending the message caused, + or possibly just exacerbated an existing, race condition that would + cause the X server to hang when coming back from a remote desktop + session. + * winclipboardwndproc.c (winProcessXEventsTimeout): switch to new + logging api's. + * winclipboardwindproc.c (winClipboardWindowProc): switch to new + logging api's. Add some additional debug logging. Make best effort + to prevent our window appearing twice in the clipboard chain. Also + detect loops when they occur and try to behave in a reasonable way. + +# vim:ts=8:noexpandtab:encoding=utf8 diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c new file mode 100644 index 000000000..6a850cd44 --- /dev/null +++ b/hw/xwin/InitInput.c @@ -0,0 +1,177 @@ +/* + + Copyright 1993, 1998 The Open Group + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of The Open Group shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from The Open Group. + +*/ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#ifdef XWIN_CLIPBOARD +# include "../../Xext/xf86miscproc.h" +#endif +#include "dixstruct.h" + + +/* + * Local function prototypes + */ + +#ifdef XWIN_CLIPBOARD +DISPATCH_PROC(winProcEstablishConnection); +DISPATCH_PROC(winProcQueryTree); +DISPATCH_PROC(winProcSetSelectionOwner); +#endif + + +/* + * Local global declarations + */ + +CARD32 g_c32LastInputEventTime = 0; + + +/* + * 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, + * so all of our keys can be used as modifiers. + * + * An example of a modifier is mapping the A key to the Control key. + * A has to be a legal modifier. I think. + */ + +Bool +LegalModifier (unsigned int uiKey, DeviceIntPtr pDevice) +{ + return TRUE; +} + + +/* Called from dix/dispatch.c */ +/* + * Run through the Windows message queue(s) one more time. + * Tell mi to dequeue the events that we have sent it. + */ +void +ProcessInputEvents (void) +{ +#if 0 + ErrorF ("ProcessInputEvents\n"); +#endif + + mieqProcessInputEvents (); + miPointerUpdate (); + +#if 0 + ErrorF ("ProcessInputEvents - returning\n"); +#endif +} + + +int +TimeSinceLastInputEvent () +{ + if (g_c32LastInputEventTime == 0) + g_c32LastInputEventTime = GetTickCount (); + return GetTickCount () - g_c32LastInputEventTime; +} + + +/* See Porting Layer Definition - p. 17 */ +void +InitInput (int argc, char *argv[]) +{ + DeviceIntPtr pMouse, pKeyboard; + +#if CYGDEBUG + winDebug ("InitInput\n"); +#endif + +#ifdef XWIN_CLIPBOARD + /* + * Wrap some functions at every generation of the server. + */ + if (InitialVector[2] != winProcEstablishConnection) + { + winProcEstablishConnectionOrig = InitialVector[2]; + InitialVector[2] = winProcEstablishConnection; + } + if (g_fXdmcpEnabled + && ProcVector[X_QueryTree] != winProcQueryTree) + { + winProcQueryTreeOrig = ProcVector[X_QueryTree]; + ProcVector[X_QueryTree] = winProcQueryTree; + } +#endif + + pMouse = AddInputDevice (winMouseProc, TRUE); + pKeyboard = AddInputDevice (winKeybdProc, TRUE); + + RegisterPointerDevice (pMouse); + RegisterKeyboardDevice (pKeyboard); + + miRegisterPointerDevice (screenInfo.screens[0], pMouse); + mieqInit ((DevicePtr)pKeyboard, (DevicePtr)pMouse); + + /* Initialize the mode key states */ + winInitializeModeKeyStates (); + +#ifdef HAS_DEVWINDOWS + /* Only open the windows message queue device once */ + if (g_fdMessageQueue == WIN_FD_INVALID) + { + /* Open a file descriptor for the Windows message queue */ + g_fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY); + + if (g_fdMessageQueue == -1) + { + FatalError ("InitInput - Failed opening %s\n", + WIN_MSG_QUEUE_FNAME); + } + + /* Add the message queue as a device to wait for in WaitForSomething */ + AddEnabledDevice (g_fdMessageQueue); + } +#endif + +#if CYGDEBUG + winDebug ("InitInput - returning\n"); +#endif +} diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c new file mode 100644 index 000000000..d2159813c --- /dev/null +++ b/hw/xwin/InitOutput.c @@ -0,0 +1,1144 @@ +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winmsg.h" +#include "winconfig.h" +#include "winprefs.h" +#ifdef XWIN_CLIPBOARD +#include "X11/Xlocale.h" +#endif +#ifdef DPMSExtension +#include "dpmsproc.h" +#endif +#ifdef __CYGWIN__ +#include <mntent.h> +#endif +#if defined(XKB) && defined(WIN32) +#include <xkbsrv.h> +#endif +#ifdef RELOCATE_PROJECTROOT +#include <shlobj.h> +typedef HRESULT (*SHGETFOLDERPATHPROC)( + HWND hwndOwner, + int nFolder, + HANDLE hToken, + DWORD dwFlags, + LPTSTR pszPath +); +#endif + + +/* + * References to external symbols + */ + +extern int g_iNumScreens; +extern winScreenInfo g_ScreenInfo[]; +extern int g_iLastScreen; +extern char * g_pszCommandLine; +extern Bool g_fSilentFatalError; + +extern char * g_pszLogFile; +extern Bool g_fLogFileChanged; +extern int g_iLogVerbose; +Bool g_fLogInited; + +extern Bool g_fXdmcpEnabled; +#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; +extern Bool g_fClipboardStarted; +extern pthread_t g_ptClipboardProc; +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; + + +/* + * Function prototypes + */ + +#ifdef XWIN_CLIPBOARD +static void +winClipboardShutdown (void); +#endif + +#if defined(DDXOSVERRORF) +void +OsVendorVErrorF (const char *pszFormat, va_list va_args); +#endif + +void +winInitializeDefaultScreens (void); + +static Bool +winCheckDisplayNumber (void); + +void +winLogCommandLine (int argc, char *argv[]); + +void +winLogVersionInfo (void); + +Bool +winValidateArgs (void); + +#ifdef RELOCATE_PROJECTROOT +const char * +winGetBaseDir(void); +#endif + +/* + * For the depth 24 pixmap we default to 32 bits per pixel, but + * we change this pixmap format later if we detect that the display + * is going to be running at 24 bits per pixel. + * + * FIXME: On second thought, don't DIBs only support 32 bits per pixel? + * DIBs are the underlying bitmap used for DirectDraw surfaces, so it + * seems that all pixmap formats with depth 24 would be 32 bits per pixel. + * Confirm whether depth 24 DIBs can have 24 bits per pixel, then remove/keep + * the bits per pixel adjustment and update this comment to reflect the + * situation. Harold Hunt - 2002/07/02 + */ + +static PixmapFormatRec g_PixmapFormats[] = { + { 1, 1, BITMAP_SCANLINE_PAD }, + { 4, 8, BITMAP_SCANLINE_PAD }, + { 8, 8, BITMAP_SCANLINE_PAD }, + { 15, 16, BITMAP_SCANLINE_PAD }, + { 16, 16, BITMAP_SCANLINE_PAD }, + { 24, 32, BITMAP_SCANLINE_PAD }, +#ifdef RENDER + { 32, 32, BITMAP_SCANLINE_PAD } +#endif +}; + +const int NUMFORMATS = sizeof (g_PixmapFormats) / sizeof (g_PixmapFormats[0]); + +#ifdef XWIN_CLIPBOARD +static void +winClipboardShutdown (void) +{ + /* Close down clipboard resources */ + if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) + { + /* Synchronously destroy the clipboard window */ + if (g_hwndClipboard != NULL) + { + SendMessage (g_hwndClipboard, WM_DESTROY, 0, 0); + /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */ + } + else + return; + + /* Wait for the clipboard thread to exit */ + pthread_join (g_ptClipboardProc, NULL); + + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + + winDebug ("winClipboardShutdown - Clipboard thread has exited.\n"); + } +} +#endif + + +#if defined(DDXBEFORERESET) +/* + * Called right before KillAllClients when the server is going to reset, + * allows us to shutdown our seperate threads cleanly. + */ + +void +ddxBeforeReset (void) +{ + winDebug ("ddxBeforeReset - Hello\n"); + +#ifdef XWIN_CLIPBOARD + winClipboardShutdown (); +#endif +} +#endif + + +/* See Porting Layer Definition - p. 57 */ +void +ddxGiveUp (void) +{ + int i; + +#if CYGDEBUG + winDebug ("ddxGiveUp\n"); +#endif + + /* Perform per-screen deinitialization */ + for (i = 0; i < g_iNumScreens; ++i) + { + /* Delete the tray icon */ + if (!g_ScreenInfo[i].fNoTrayIcon && g_ScreenInfo[i].pScreen) + winDeleteNotifyIcon (winGetScreenPriv (g_ScreenInfo[i].pScreen)); + } + +#ifdef XWIN_MULTIWINDOW + /* Notify the worker threads we're exiting */ + winDeinitMultiWindowWM (); +#endif + +#ifdef HAS_DEVWINDOWS + /* Close our handle to our message queue */ + if (g_fdMessageQueue != WIN_FD_INVALID) + { + /* Close /dev/windows */ + close (g_fdMessageQueue); + + /* Set the file handle to invalid */ + g_fdMessageQueue = WIN_FD_INVALID; + } +#endif + + if (!g_fLogInited) { + LogInit (g_pszLogFile, NULL); + g_fLogInited = TRUE; + } + LogClose (); + + /* + * 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; + } + + /* Unload our TrackMouseEvent funtion pointer */ + if (g_hmodCommonControls != NULL) + { + FreeLibrary (g_hmodCommonControls); + g_hmodCommonControls = NULL; + g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; + } + + /* Free concatenated command line */ + if (g_pszCommandLine) + { + free (g_pszCommandLine); + g_pszCommandLine = NULL; + } + + /* Remove our keyboard hook if it is installed */ + winRemoveKeyboardHookLL (); + + /* Tell Windows that we want to end the app */ + PostQuitMessage (0); +} + + +/* See Porting Layer Definition - p. 57 */ +void +AbortDDX (void) +{ +#if CYGDEBUG + winDebug ("AbortDDX\n"); +#endif + ddxGiveUp (); +} + +#ifdef __CYGWIN__ +/* hasmntopt is currently not implemented for cygwin */ +static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt) +{ + const char *s; + size_t len; + if (mnt == NULL) + return NULL; + if (opt == NULL) + return NULL; + if (mnt->mnt_opts == NULL) + return NULL; + + len = strlen(opt); + s = strstr(mnt->mnt_opts, opt); + if (s == NULL) + return NULL; + if ((s == mnt->mnt_opts || *(s-1) == ',') && (s[len] == 0 || s[len] == ',')) + return (char *)opt; + return NULL; +} + +static void +winCheckMount(void) +{ + FILE *mnt; + struct mntent *ent; + + enum { none = 0, sys_root, user_root, sys_tmp, user_tmp } + level = none, curlevel; + BOOL binary = TRUE; + + mnt = setmntent("/etc/mtab", "r"); + if (mnt == NULL) + { + ErrorF("setmntent failed"); + return; + } + + while ((ent = getmntent(mnt)) != NULL) + { + BOOL system = (strcmp(ent->mnt_type, "system") == 0); + BOOL root = (strcmp(ent->mnt_dir, "/") == 0); + BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0); + + if (system) + { + if (root) + curlevel = sys_root; + else if (tmp) + curlevel = sys_tmp; + else + continue; + } + else + { + if (root) + curlevel = user_root; + else if (tmp) + curlevel = user_tmp; + else + continue; + } + + if (curlevel <= level) + continue; + level = curlevel; + + if (winCheckMntOpt(ent, "binmode") == NULL) + binary = 0; + else + binary = 1; + } + + if (endmntent(mnt) != 1) + { + ErrorF("endmntent failed"); + return; + } + + if (!binary) + winMsg(X_WARNING, "/tmp mounted int textmode\n"); +} +#else +static void +winCheckMount(void) +{ +} +#endif + +#ifdef RELOCATE_PROJECTROOT +const char * +winGetBaseDir(void) +{ + static BOOL inited = FALSE; + static char buffer[MAX_PATH]; + if (!inited) + { + char *fendptr; + HMODULE module = GetModuleHandle(NULL); + DWORD size = GetModuleFileName(module, buffer, sizeof(buffer)); + if (sizeof(buffer) > 0) + buffer[sizeof(buffer)-1] = 0; + + fendptr = buffer + size; + while (fendptr > buffer) + { + if (*fendptr == '\\' || *fendptr == '/') + { + *fendptr = 0; + break; + } + fendptr--; + } + inited = TRUE; + } + return buffer; +} +#endif + +static void +winFixupPaths (void) +{ + BOOL changed_fontpath = FALSE; + MessageType font_from = X_DEFAULT; +#ifdef RELOCATE_PROJECTROOT + const char *basedir = winGetBaseDir(); + size_t basedirlen = strlen(basedir); +#endif + +#ifdef READ_FONTDIRS + { + /* Open fontpath configuration file */ + FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt"); + if (fontdirs != NULL) + { + char buffer[256]; + int needs_sep = TRUE; + int comment_block = FALSE; + + /* get defautl fontpath */ + char *fontpath = xstrdup(defaultFontPath); + size_t size = strlen(fontpath); + + /* read all lines */ + while (!feof(fontdirs)) + { + size_t blen; + char *hashchar; + char *str; + int has_eol = FALSE; + + /* read one line */ + str = fgets(buffer, sizeof(buffer), fontdirs); + if (str == NULL) /* stop on error or eof */ + break; + + if (strchr(str, '\n') != NULL) + has_eol = TRUE; + + /* check if block is continued comment */ + if (comment_block) + { + /* ignore all input */ + *str = 0; + blen = 0; + if (has_eol) /* check if line ended in this block */ + comment_block = FALSE; + } + else + { + /* find comment character. ignore all trailing input */ + hashchar = strchr(str, '#'); + if (hashchar != NULL) + { + *hashchar = 0; + if (!has_eol) /* mark next block as continued comment */ + comment_block = TRUE; + } + } + + /* strip whitespaces from beginning */ + while (*str == ' ' || *str == '\t') + str++; + + /* get size, strip whitespaces from end */ + blen = strlen(str); + while (blen > 0 && (str[blen-1] == ' ' || + str[blen-1] == '\t' || str[blen-1] == '\n')) + { + str[--blen] = 0; + } + + /* still something left to add? */ + if (blen > 0) + { + size_t newsize = size + blen; + /* reserve one character more for ',' */ + if (needs_sep) + newsize++; + + /* allocate memory */ + if (fontpath == NULL) + fontpath = malloc(newsize+1); + else + fontpath = realloc(fontpath, newsize+1); + + /* add separator */ + if (needs_sep) + { + fontpath[size] = ','; + size++; + needs_sep = FALSE; + } + + /* mark next line as new entry */ + if (has_eol) + needs_sep = TRUE; + + /* add block */ + strncpy(fontpath + size, str, blen); + fontpath[newsize] = 0; + size = newsize; + } + } + + /* cleanup */ + fclose(fontdirs); + defaultFontPath = xstrdup(fontpath); + free(fontpath); + changed_fontpath = TRUE; + font_from = X_CONFIG; + } + } +#endif /* READ_FONTDIRS */ +#ifdef RELOCATE_PROJECTROOT + { + const char *libx11dir = PROJECTROOT "/lib/X11"; + size_t libx11dir_len = strlen(libx11dir); + char *newfp = NULL; + size_t newfp_len = 0; + const char *endptr, *ptr, *oldptr = defaultFontPath; + + endptr = oldptr + strlen(oldptr); + ptr = strchr(oldptr, ','); + if (ptr == NULL) + ptr = endptr; + while (ptr != NULL) + { + size_t oldfp_len = (ptr - oldptr); + size_t newsize = oldfp_len; + char *newpath = malloc(newsize + 1); + strncpy(newpath, oldptr, newsize); + newpath[newsize] = 0; + + + if (strncmp(libx11dir, newpath, libx11dir_len) == 0) + { + char *compose; + newsize = newsize - libx11dir_len + basedirlen; + compose = malloc(newsize + 1); + strcpy(compose, basedir); + strncat(compose, newpath + libx11dir_len, newsize - basedirlen); + compose[newsize] = 0; + free(newpath); + newpath = compose; + } + + oldfp_len = newfp_len; + if (oldfp_len > 0) + newfp_len ++; /* space for separator */ + newfp_len += newsize; + + if (newfp == NULL) + newfp = malloc(newfp_len + 1); + else + newfp = realloc(newfp, newfp_len + 1); + + if (oldfp_len > 0) + { + strcpy(newfp + oldfp_len, ","); + oldfp_len++; + } + strcpy(newfp + oldfp_len, newpath); + + free(newpath); + + if (*ptr == 0) + { + oldptr = ptr; + ptr = NULL; + } else + { + oldptr = ptr + 1; + ptr = strchr(oldptr, ','); + if (ptr == NULL) + ptr = endptr; + } + } + + defaultFontPath = xstrdup(newfp); + free(newfp); + changed_fontpath = TRUE; + } +#endif /* RELOCATE_PROJECTROOT */ + if (changed_fontpath) + winMsg (font_from, "FontPath set to \"%s\"\n", defaultFontPath); + +#ifdef RELOCATE_PROJECTROOT + if (getenv("XKEYSYMDB") == NULL) + { + char buffer[MAX_PATH]; + snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB", + basedir); + buffer[sizeof(buffer)-1] = 0; + putenv(buffer); + } + if (getenv("XERRORDB") == NULL) + { + char buffer[MAX_PATH]; + snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB", + basedir); + buffer[sizeof(buffer)-1] = 0; + putenv(buffer); + } + if (getenv("XLOCALEDIR") == NULL) + { + char buffer[MAX_PATH]; + snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale", + basedir); + buffer[sizeof(buffer)-1] = 0; + putenv(buffer); + } + if (getenv("HOME") == NULL) + { + HMODULE shfolder; + SHGETFOLDERPATHPROC shgetfolderpath = NULL; + char buffer[MAX_PATH + 5]; + strncpy(buffer, "HOME=", 5); + + /* Try to load SHGetFolderPath from shfolder.dll and shell32.dll */ + + shfolder = LoadLibrary("shfolder.dll"); + /* fallback to shell32.dll */ + if (shfolder == NULL) + shfolder = LoadLibrary("shell32.dll"); + + /* resolve SHGetFolderPath */ + if (shfolder != NULL) + shgetfolderpath = (SHGETFOLDERPATHPROC)GetProcAddress(shfolder, "SHGetFolderPathA"); + + /* query appdata directory */ + if (shgetfolderpath && + shgetfolderpath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, + buffer + 5) == 0) + { + putenv(buffer); + } else + { + winMsg (X_ERROR, "Can not determine HOME directory\n"); + } + if (shfolder != NULL) + FreeLibrary(shfolder); + } + if (!g_fLogFileChanged) { + static char buffer[MAX_PATH]; + DWORD size = GetTempPath(sizeof(buffer), buffer); + if (size && size < sizeof(buffer)) + { + snprintf(buffer + size, sizeof(buffer) - size, + "XWin.%s.log", display); + buffer[sizeof(buffer)-1] = 0; + g_pszLogFile = buffer; + winMsg (X_DEFAULT, "Logfile set to \"%s\"\n", g_pszLogFile); + } + } +#ifdef XKB + { + static char xkbbasedir[MAX_PATH]; + + snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", basedir); + if (sizeof(xkbbasedir) > 0) + xkbbasedir[sizeof(xkbbasedir)-1] = 0; + XkbBaseDirectory = xkbbasedir; + XkbBinDirectory = basedir; + } +#endif /* XKB */ +#endif /* RELOCATE_PROJECTROOT */ +} + +void +OsVendorInit (void) +{ + /* Re-initialize global variables on server reset */ + winInitializeGlobals (); + + LogInit (NULL, NULL); + LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose); + + winFixupPaths(); + +#ifdef DDXOSVERRORF + if (!OsVendorVErrorFProc) + OsVendorVErrorFProc = OsVendorVErrorF; +#endif + + if (!g_fLogInited) { + /* keep this order. If LogInit fails it calls Abort which then calls + * ddxGiveUp where LogInit is called again and creates an infinite + * recursion. If we set g_fLogInited to TRUE before the init we + * avoid the second call + */ + g_fLogInited = TRUE; + LogInit (g_pszLogFile, NULL); + } + LogSetParameter (XLOG_FLUSH, 1); + LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose); + LogSetParameter (XLOG_FILE_VERBOSITY, 1); + + /* Log the version information */ + if (serverGeneration == 1) + winLogVersionInfo (); + + winCheckMount(); + + /* Add a default screen if no screens were specified */ + if (g_iNumScreens == 0) + { + winDebug ("OsVendorInit - Creating bogus screen 0\n"); + + /* + * We need to initialize default screens if no arguments + * were processed. Otherwise, the default screens would + * already have been initialized by ddxProcessArgument (). + */ + winInitializeDefaultScreens (); + + /* + * Add a screen 0 using the defaults set by + * winInitializeDefaultScreens () and any additional parameters + * processed by ddxProcessArgument (). + */ + g_iNumScreens = 1; + g_iLastScreen = 0; + + /* We have to flag this as an explicit screen, even though it isn't */ + g_ScreenInfo[0].fExplicitScreen = TRUE; + } +} + + +static void +winUseMsg (void) +{ + ErrorF ("-depth bits_per_pixel\n" + "\tSpecify an optional bitdepth to use in fullscreen mode\n" + "\twith a DirectDraw engine.\n"); + + ErrorF ("-emulate3buttons [timeout]\n" + "\tEmulate 3 button mouse with an optional timeout in\n" + "\tmilliseconds.\n"); + + ErrorF ("-engine engine_type_id\n" + "\tOverride the server's automatically selected engine type:\n" + "\t\t1 - Shadow GDI\n" + "\t\t2 - Shadow DirectDraw\n" + "\t\t4 - Shadow DirectDraw4 Non-Locking\n" +#ifdef XWIN_NATIVEGDI + "\t\t16 - Native GDI - experimental\n" +#endif + ); + + ErrorF ("-fullscreen\n" + "\tRun the server in fullscreen mode.\n"); + + ErrorF ("-refresh rate_in_Hz\n" + "\tSpecify an optional refresh rate to use in fullscreen mode\n" + "\twith a DirectDraw engine.\n"); + + ErrorF ("-screen scr_num [width height [x y] | [[WxH[+X+Y]][@m]] ]\n" + "\tEnable screen scr_num and optionally specify a width and\n" + "\theight and initial position for that screen. Additionally\n" + "\ta monitor number can be specified to start the server on,\n" + "\tat which point, all coordinates become relative to that\n" + "\tmonitor (Not for Windows NT4 and 95). Examples:\n" + "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n" + "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n" + "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n"); + + ErrorF ("-lesspointer\n" + "\tHide the windows mouse pointer when it is over an inactive\n" + "\t" PROJECT_NAME " window. This prevents ghost cursors appearing where\n" + "\tthe Windows cursor is drawn overtop of the X cursor\n"); + + ErrorF ("-nodecoration\n" + "\tDo not draw a window border, title bar, etc. Windowed\n" + "\tmode only.\n"); + +#ifdef XWIN_MULTIWINDOWEXTWM + ErrorF ("-mwextwm\n" + "\tRun the server in multi-window external window manager mode.\n"); + + ErrorF ("-internalwm\n" + "\tRun the internal window manager.\n"); +#endif + + ErrorF ("-rootless\n" + "\tRun the server in rootless mode.\n"); + +#ifdef XWIN_MULTIWINDOW + ErrorF ("-multiwindow\n" + "\tRun the server in multi-window mode.\n"); +#endif + + ErrorF ("-multiplemonitors\n" + "\tEXPERIMENTAL: Use the entire virtual screen if multiple\n" + "\tmonitors are present.\n"); + +#ifdef XWIN_CLIPBOARD + ErrorF ("-clipboard\n" + "\tRun the clipboard integration module.\n" + "\tDo not use at the same time as 'xwinclip'.\n"); + + ErrorF ("-nounicodeclipboard\n" + "\tDo not use Unicode clipboard even if NT-based platform.\n"); +#endif + + ErrorF ("-scrollbars\n" + "\tIn windowed mode, allow screens bigger than the Windows desktop.\n" + "\tMoreover, if the window has decorations, one can now resize\n" + "\tit.\n"); + + ErrorF ("-[no]trayicon\n" + "\tDo not create a tray icon. Default is to create one\n" + "\ticon per screen. You can globally disable tray icons with\n" + "\t-notrayicon, then enable it for specific screens with\n" + "\t-trayicon for those screens.\n"); + + ErrorF ("-clipupdates num_boxes\n" + "\tUse a clipping region to constrain shadow update blits to\n" + "\tthe updated region when num_boxes, or more, are in the\n" + "\tupdated region. Currently supported only by `-engine 1'.\n"); + +#ifdef XWIN_EMULATEPSEUDO + ErrorF ("-emulatepseudo\n" + "\tCreate a depth 8 PseudoColor visual when running in\n" + "\tdepths 15, 16, 24, or 32, collectively known as TrueColor\n" + "\tdepths. The PseudoColor visual does not have correct colors,\n" + "\tand it may crash, but it at least allows you to run your\n" + "\tapplication in TrueColor modes.\n"); +#endif + + ErrorF ("-[no]unixkill\n" + "\tCtrl+Alt+Backspace exits the X Server.\n"); + + ErrorF ("-[no]winkill\n" + "\tAlt+F4 exits the X Server.\n"); + +#ifdef XWIN_XF86CONFIG + ErrorF ("-config\n" + "\tSpecify a configuration file.\n"); + + ErrorF ("-keyboard\n" + "\tSpecify a keyboard device from the configuration file.\n"); +#endif + +#ifdef XKB + ErrorF ("-xkbrules XKBRules\n" + "\tEquivalent to XKBRules in XF86Config files.\n"); + + ErrorF ("-xkbmodel XKBModel\n" + "\tEquivalent to XKBModel in XF86Config files.\n"); + + ErrorF ("-xkblayout XKBLayout\n" + "\tEquivalent to XKBLayout in XF86Config files.\n" + "\tFor example: -xkblayout de\n"); + + ErrorF ("-xkbvariant XKBVariant\n" + "\tEquivalent to XKBVariant in XF86Config files.\n" + "\tFor example: -xkbvariant nodeadkeys\n"); + + ErrorF ("-xkboptions XKBOptions\n" + "\tEquivalent to XKBOptions in XF86Config files.\n"); +#endif + + ErrorF ("-logfile filename\n" + "\tWrite logmessages to <filename> instead of /tmp/Xwin.log.\n"); + + ErrorF ("-logverbose verbosity\n" + "\tSet the verbosity of logmessages. [NOTE: Only a few messages\n" + "\trespect the settings yet]\n" + "\t\t0 - only print fatal error.\n" + "\t\t1 - print additional configuration information.\n" + "\t\t2 - print additional runtime information [default].\n" + "\t\t3 - print debugging and tracing information.\n"); + + ErrorF ("-[no]keyhook\n" + "\tGrab special windows key combinations like Alt-Tab or the Menu " + "key.\n These keys are discarded by default.\n"); + + ErrorF ("-swcursor\n" + "\tDisable the usage of the windows cursor and use the X11 software " + "cursor instead\n"); +} + +/* See Porting Layer Definition - p. 57 */ +void +ddxUseMsg(void) +{ + /* Set a flag so that FatalError won't give duplicate warning message */ + g_fSilentFatalError = TRUE; + + winUseMsg(); + + /* Log file will not be opened for UseMsg unless we open it now */ + if (!g_fLogInited) { + LogInit (g_pszLogFile, NULL); + g_fLogInited = TRUE; + } + LogClose (); + + /* Notify user where UseMsg text can be found.*/ + if (!g_fNoHelpMessageBox) + winMessageBoxF ("The " PROJECT_NAME " help text has been printed to " + "/tmp/XWin.log.\n" + "Please open /tmp/XWin.log to read the help text.\n", + MB_ICONINFORMATION); +} + +/* ddxInitGlobals - called by |InitGlobals| from os/util.c */ +void ddxInitGlobals(void) +{ +} + +/* See Porting Layer Definition - p. 20 */ +/* + * Do any global initialization, then initialize each screen. + * + * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv + */ + +void +InitOutput (ScreenInfo *screenInfo, int argc, char *argv[]) +{ + int i; + + /* Log the command line */ + winLogCommandLine (argc, argv); + +#if CYGDEBUG + winDebug ("InitOutput\n"); +#endif + + /* Validate command-line arguments */ + if (serverGeneration == 1 && !winValidateArgs ()) + { + FatalError ("InitOutput - Invalid command-line arguments found. " + "Exiting.\n"); + } + + /* Check for duplicate invocation on same display number.*/ + if (serverGeneration == 1 && !winCheckDisplayNumber ()) + { + if (g_fSilentDupError) + g_fSilentFatalError = TRUE; + FatalError ("InitOutput - Duplicate invocation on display " + "number: %s. Exiting.\n", display); + } + +#ifdef XWIN_XF86CONFIG + /* Try to read the xorg.conf-style configuration file */ + if (!winReadConfigfile ()) + winErrorFVerb (1, "InitOutput - Error reading config file\n"); +#else + winMsg(X_INFO, "XF86Config is not supported\n"); + winMsg(X_INFO, "See http://x.cygwin.com/docs/faq/cygwin-x-faq.html " + "for more information\n"); + winConfigFiles (); +#endif + + /* Load preferences from XWinrc file */ + LoadPreferences(); + + /* Setup global screen info parameters */ + screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + screenInfo->numPixmapFormats = NUMFORMATS; + + /* Describe how we want common pixmap formats padded */ + for (i = 0; i < NUMFORMATS; i++) + { + screenInfo->formats[i] = g_PixmapFormats[i]; + } + + /* Load pointers to DirectDraw functions */ + winGetDDProcAddresses (); + + /* Detect supported engines */ + winDetectSupportedEngines (); + + /* Load common controls library */ + g_hmodCommonControls = LoadLibraryEx ("comctl32.dll", NULL, 0); + + /* Load TrackMouseEvent function pointer */ + g_fpTrackMouseEvent = GetProcAddress (g_hmodCommonControls, + "_TrackMouseEvent"); + if (g_fpTrackMouseEvent == NULL) + { + winErrorFVerb (1, "InitOutput - Could not get pointer to function\n" + "\t_TrackMouseEvent in comctl32.dll. Try installing\n" + "\tInternet Explorer 3.0 or greater if you have not\n" + "\talready.\n"); + + /* Free the library since we won't need it */ + FreeLibrary (g_hmodCommonControls); + g_hmodCommonControls = NULL; + + /* Set function pointer to point to no operation function */ + g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; + } + + /* Store the instance handle */ + g_hInstance = GetModuleHandle (NULL); + + /* Initialize each screen */ + for (i = 0; i < g_iNumScreens; ++i) + { + /* Initialize the screen */ + if (-1 == AddScreen (winScreenInit, argc, argv)) + { + FatalError ("InitOutput - Couldn't add screen %d", i); + } + } + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + +#if defined(XCSECURITY) + /* Generate a cookie used by internal clients for authorization */ + if (g_fXdmcpEnabled) + winGenerateAuthorization (); +#endif + + /* Perform some one time initialization */ + if (1 == serverGeneration) + { + /* + * setlocale applies to all threads in the current process. + * Apply locale specified in LANG environment variable. + */ + setlocale (LC_ALL, ""); + } +#endif + +#if CYGDEBUG || YES + winDebug ("InitOutput - Returning.\n"); +#endif +} + + +/* + * winCheckDisplayNumber - Check if another instance of Cygwin/X is + * already running on the same display number. If no one exists, + * make a mutex to prevent new instances from running on the same display. + * + * return FALSE if the display number is already used. + */ + +static Bool +winCheckDisplayNumber () +{ + int nDisp; + HANDLE mutex; + char name[MAX_PATH]; + char * pszPrefix = '\0'; + OSVERSIONINFO osvi = {0}; + + /* Check display range */ + nDisp = atoi (display); + if (nDisp < 0 || nDisp > 65535) + { + ErrorF ("winCheckDisplayNumber - Bad display number: %d\n", nDisp); + return FALSE; + } + + /* Set first character of mutex name to null */ + name[0] = '\0'; + + /* Get operating system version information */ + osvi.dwOSVersionInfoSize = sizeof (osvi); + GetVersionEx (&osvi); + + /* Want a mutex shared among all terminals on NT > 4.0 */ + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT + && osvi.dwMajorVersion >= 5) + { + pszPrefix = "Global\\"; + } + + /* Setup Cygwin/X specific part of name */ + snprintf (name, sizeof(name), "%sCYGWINX_DISPLAY:%d", pszPrefix, nDisp); + + /* Windows automatically releases the mutex when this process exits */ + mutex = CreateMutex (NULL, FALSE, name); + if (!mutex) + { + 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 ("winCheckDisplayNumber - CreateMutex failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + + return FALSE; + } + if (GetLastError () == ERROR_ALREADY_EXISTS) + { + ErrorF ("winCheckDisplayNumber - " + PROJECT_NAME " is already running on display %d\n", + nDisp); + return FALSE; + } + + return TRUE; +} + +#ifdef DPMSExtension +Bool DPMSSupported(void) +{ + return FALSE; +} + +void DPMSSet(int level) +{ + return; +} + +int DPMSGet(int *plevel) +{ + return 0; +} +#endif diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am new file mode 100644 index 000000000..5ffba1274 --- /dev/null +++ b/hw/xwin/Makefile.am @@ -0,0 +1,197 @@ +bin_PROGRAMS = XWin + +if XWIN_CLIPBOARD +SRCS_CLIPBOARD = \ + winclipboardinit.c \ + winclipboardtextconv.c \ + winclipboardthread.c \ + winclipboardunicode.c \ + winclipboardwndproc.c \ + winclipboardwrappers.c \ + winclipboardxevents.c +DEFS_CLIPBOARD = -DXWIN_CLIPBOARD +endif + +if XWIN_GLX_WINDOWS +SRCS_GLX_WINDOWS = \ + winpriv.c +DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS +endif + +if XWIN_MULTIWINDOW +SRCS_MULTIWINDOW = \ + winmultiwindowshape.c \ + winmultiwindowwindow.c \ + winmultiwindowwm.c \ + winmultiwindowwndproc.c +DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW +endif + +if XWIN_MULTIWINDOWEXTWM +SRCS_MULTIWINDOWEXTWM = \ + winwin32rootless.c \ + winwin32rootlesswindow.c \ + winwin32rootlesswndproc.c \ + winwindowswm.c +DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM +endif + +if XWIN_NATIVEGDI +SRCS_NATIVEGDI = \ + winclip.c \ + winfillsp.c \ + winfont.c \ + wingc.c \ + wingetsp.c \ + winnativegdi.c \ + winpixmap.c \ + winpolyline.c \ + winpushpxl.c \ + winrop.c \ + winsetsp.c +DEFS_NATIVEGDI = -DXWIN_NATIVEGDI +endif + +if XWIN_PRIMARYFB +SRCS_PRIMARYFB = \ + winpfbdd.c +DEFS_PRIMARYFB = -DXWIN_PRIMARYFB +endif + +if XWIN_RANDR +SRCS_RANDR = \ + winrandr.c +DEFS_RANDR = -DXWIN_RANDR +endif + +if XWIN_XV +SRCS_XV = \ + winvideo.c +DEFS_XV = -DXWIN_XV +endif + +SRCS = InitInput.c \ + InitOutput.c \ + winallpriv.c \ + winauth.c \ + winblock.c \ + wincmap.c \ + winconfig.c \ + wincreatewnd.c \ + wincursor.c \ + windialogs.c \ + winengine.c \ + winerror.c \ + winglobals.c \ + winkeybd.c \ + winkeyhook.c \ + winmisc.c \ + winmouse.c \ + winmsg.c \ + winmultiwindowclass.c \ + winmultiwindowicons.c \ + winprefs.c \ + winprefsyacc.y \ + winprefslex.l \ + winprocarg.c \ + winregistry.c \ + winscrinit.c \ + winshaddd.c \ + winshadddnl.c \ + winshadgdi.c \ + wintrayicon.c \ + winvalargs.c \ + winwakeup.c \ + winwindow.c \ + winwndproc.c \ + ddraw.h \ + winclipboard.h \ + winconfig.h \ + win.h \ + winkeybd.h \ + winkeymap.h \ + winkeynames.h \ + winlayouts.h \ + winmessages.h \ + winmsg.h \ + winms.h \ + winmultiwindowclass.h \ + winprefs.h \ + winpriv.h \ + winresource.h \ + winwindow.h \ + $(top_srcdir)/mi/miinitext.c \ + $(top_srcdir)/fb/fbcmap.c \ + $(SRCS_CLIPBOARD) \ + $(SRCS_GLX_WINDOWS) \ + $(SRCS_MULTIWINDOW) \ + $(SRCS_MULTIWINDOWEXTWM) \ + $(SRCS_NATIVEGDI) \ + $(SRCS_PRIMARYFB) \ + $(SRCS_RANDR) \ + $(SRCS_XV) + + DEFS = $(DEFS_CLIPBOARD) \ + $(DEFS_GLX_WINDOWS) \ + $(DEFS_MULTIWINDOW) \ + $(DEFS_MULTIWINDOWEXTWM) \ + $(DEFS_NATIVEGDI) \ + $(DEFS_PRIMARYFB) \ + $(DEFS_RANDR) \ + $(DEFS_XV) + +XWin_SOURCES = $(SRCS) + +INCLUDES = -I$(top_srcdir)/miext/rootless \ + -I$(top_srcdir)/miext/rootless/safeAlpha + +XWIN_LIBS = \ + $(top_builddir)/fb/libfb.la \ + $(XSERVER_LIBS) + +XWin_DEPENDENCIES = $(XWIN_LIBS) +XWin_LDADD = $(XWIN_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) + +XWin_LDFLAGS = -mwindows -static + +winprefsyacc.h: winprefsyacc.c +winprefslex.c: winprefslex.l winprefsyacc.c winprefsyacc.h + +BUILT_SOURCES = winprefsyacc.h winprefsyacc.c winprefslex.c +CLEANFILES = $(BUILT_SOURCES) + +AM_YFLAGS = -d +AM_LFLAGS = -i +AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ + $(XWINMODULES_CFLAGS) + +dist_man1_MANS = XWin.man XWinrc.man + +EXTRA_DIST = \ + _usr_X11R6_lib_X11_system.XWinrc \ + X-boxed.ico \ + X.ico \ + XWin.rc \ + xlaunch/config.cc \ + xlaunch/COPYING \ + xlaunch/main.cc \ + xlaunch/resources/dialog.rc \ + xlaunch/resources/fullscreen.bmp \ + xlaunch/resources/images.rc \ + xlaunch/resources/multiwindow.bmp \ + xlaunch/resources/nodecoration.bmp \ + xlaunch/resources/resources.h \ + xlaunch/resources/resources.rc \ + xlaunch/resources/strings.rc \ + xlaunch/resources/windowed.bmp \ + xlaunch/window/dialog.cc \ + xlaunch/window/dialog.h \ + xlaunch/window/util.cc \ + xlaunch/window/util.h \ + xlaunch/window/window.cc \ + xlaunch/window/window.h \ + xlaunch/window/wizard.cc \ + xlaunch/window/wizard.h + +relink: + rm -f XWin && $(MAKE) XWin diff --git a/hw/xwin/README b/hw/xwin/README new file mode 100644 index 000000000..219fd1337 --- /dev/null +++ b/hw/xwin/README @@ -0,0 +1,141 @@ +Cygwin/X Release Notes +====================== + +Release X11R6.7 +=============== + +Cygwin/X has continued its rapid pace of development that it has sustained +since Spring 2001 and this release shows it, we now have: a stable and fast +multi-window mode, seamless clipboard integration, a configurable tray menu +icon, popups on error messages pointing users to the log file and our mailing +list, the beginnings of indirect 3D acceleration for OpenGL applications, +improved non-US keyboard and clipboard support, and only a handful of bugs +that continue to be reported. + +Between the XFree86 4.3.0 release and the X.Org X11R6.7 release the Cyg- +win/XFree86 project broke away from The XFree86 Project, Inc. due to a lack +of support from the XFree86 project. As such, the Cygwin/XFree86 project was +renamed to the Cygwin/X project and the upstream source code tree that Cyg- +win/X pulls from and pushes to is now the tree managed by the X.Org Founda- +tion. The Cygwin/X project has seen a rush of development and interest in +the project since the split; one metric showing this is that the number of +CVS committers we have has gone from zero to six. + +The most outstanding features of this release are + + o Major multi-window mode improvements. (Takuma Murakami, Earle F. + Philhower III) + + o Initial work of accelerated OpenGL using the windows OpenGL drivers. + (Alexander Gottwald) + + o Massive rework of clipboard integration with windows. (Harold L Hunt II, + Kensuke Matsuzaki) + + o Improved Japanese clipboard and keyboard support. (Kensuke Matsuzaki, + Takuma Murakami, Alexander Gottwald) + + o Customizable tray menu icon allowing shortcuts to start programs, + etc.(Earle F. Philhower III) + + o New icons. (Jehan Bing, Michael Bax, Benjamin Rienfenstahl) + + o Fix some multi-monitor problems.(Takuma Murakami) + + o Fix repeated key strokes. (Ivan Pascal) + + o Automatic keyboard layouts for the most frequently used keyboard lay- + outs. (Alexander Gottwald) + + o Built in SHM support with detection of the SHM engine (cygserver). + (Ralf Habacker, Harold L Hunt II) + + o Merged in work on the NativeGDI engine. (Alan Hourihane) + +OpenGL with Cygwin/X +==================== + +Cygwin/X has supported GLX only with software rendering provided by the Mesa +library. Starting with X11R6.7 we add support for hardware accelerated OpenGL. + +This support is still under development and still has some bigger problems. +To provide both versions (the stable software rendering and the new hardware +accelerated) we ship to binaries. XWin.exe contains the software rendering +and XWin_GL.exe uses the hardware acceleration provided by the windows drivers. + +The known problems with hardware accelerated OpenGL are: + + o Only multiwindow mode is useful. In the other modes the OpenGL output + does not align with the X11 windows. + + o Using two programs which require different visuals will fail. For example + glxgears and glxinfo will not work without restarting XWin_GL.exe. + + o OpenGL extensions and functions from OpenGL 1.2 and later should work + but are not completely tested. + + o The standard Windows OpenGL driver will produce no output. Use the one + from your video adapter vendor. + +If you notice problems with some programs please send a message with the +logfile /tmp/XWin.log and a short error description to <cygwin-xfree@cygwin.com> + +The hardware accelerated OpenGL was tested using: + + o glxgears + o glxinfo + o blender + o tuxkart + o GLUT demos (some did fail) + o tuxracer (currently not working) + + +Release X11R6.8 +=============== + +Having reached a quite mature state in release X11R6.7 the development +has slowed down a little bit. Some of the former active developers have +retired or cut their work for the Cygwin/X project due to conflicts with +job, study and family. + +The X11R6.8 release now includes major improvements from the xserver project. +This includes the XFixes, Damage, Composite and XEVIE extension which is a +major step towards allowing Cygwin/X to have real transparency. + +But at the current state Composite is not working with Cygwin/X. Not all code +in the Cygwin/X Server has been updated to support the Composite feature and +using it will even crash the xserver. But as a second problem nearly all +functions required for compositing are lacking acceleration in Cygwin/X so +the feature would not be very useful if it would work. So it is disabled by +default. + +OpenGL with Cygwin/X +==================== + +The OpenGL support has lost some of it's limitations from the last release +and should be much more stable. But due to missing wide spread testing in +the community it is still available in a separate program. XWin still uses +the old software OpenGL which is known to be stable. + +The known problems with hardware accelerated OpenGL are: + + o Only multiwindow mode is useful. In the other modes the OpenGL output + does not align with the X11 windows. + + o OpenGL extensions and functions from OpenGL 1.2 and later should work + but are not completely tested. + + o The standard Windows OpenGL driver will produce no output. Use the one + from your video adapter vendor. + +If you notice problems with some programs please send a message with the +logfile /tmp/XWin.log and a short error description to <cygwin-xfree@cygwin.com> + +The hardware accelerated OpenGL was tested using: + + o glxgears + o glxinfo + o blender + o tuxkart + o GLUT demos (some did fail) + diff --git a/hw/xwin/X-boxed.ico b/hw/xwin/X-boxed.ico Binary files differnew file mode 100755 index 000000000..072704253 --- /dev/null +++ b/hw/xwin/X-boxed.ico diff --git a/hw/xwin/X.ico b/hw/xwin/X.ico Binary files differnew file mode 100644 index 000000000..d47168fca --- /dev/null +++ b/hw/xwin/X.ico diff --git a/hw/xwin/XWin.man b/hw/xwin/XWin.man new file mode 100644 index 000000000..4e70c19f5 --- /dev/null +++ b/hw/xwin/XWin.man @@ -0,0 +1,287 @@ +.TH XWIN 1 __vendorversion__ +.SH NAME +XWin \- X Server for the Cygwin environment on Microsoft Windows + + +.SH SYNOPSIS +.B XWin +[ options ] ... + + +.SH DESCRIPTION +.I XWin is an X Server for the X Window System on the Cygwin environment +running on Microsoft Windows. + + +.SH MODES +\fIXWin\fP can operate in five different and incompatible modes: +.br +* \fISingle Window\fP: This is the default option. The X server +appears as a single Windows window and all X windows are contained +within this window. This mode requires an external window manager. +.br +* \fINo Decoration\fP: This mode is like single window mode except +that the X server window does not have a title bar or border, thus +maximizing the amount of space available for X windows within the X +server window. This mode requires an external window manager. +.br +* \fIFull Screen\fP: This mode is like single window mode except that +the X server window takes the full screen, covering completely the +Windows desktop. This mode requires an external window manager. +.br +* \fIRootless\fP: The X server works on a window covering the whole +screen but the root window (traditionally covered with an X hatch +pattern) is hidden from view. This mode requires an external window +manager. +.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 Windows windows. +.PP +NOTE: \fIMulti-Window\fP mode will crash if an external window manager +such as \fItwm\fP or \fIfvwm\fP is launched since \fIMulti-Window\fP +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 LOG +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/tmp/XWin.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/usr/X11R6/lib/X11/system.XWinrc\fP. \fI.XWinrc\fP allows setting +preferences for the following: +.br +1- 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 +2- To include items in the menu which is associated with the Windows +window that \fIXWin -multiwindow\fP produces for each top-level X +window. That can be done both for the generic case and for particular +programs. +.br +3- To change the icon that is associated to the Windows window that +\fIXWin -multiwindow\fP produces for each top-level X-window. Again, +that can be done both for the generic case and for particular +programs. +.PP +The format of the \fI.XWinrc\fP file is given in the man page XWinrc(5). + + +.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: +.TP 8 +.B \-clipboard +Enables the integration +between the Cygwin/X clipboard and Windows clipboard. Do not use in +conjunction with the \fIxwinclip\fP program. +.TP 8 +.B "\-clipupdates \fInum_boxes\fP" +Specify an optional threshold, above which the boxes 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 parameter works in conjunction with engines 1, 2, and 4 (Shadow +GDI, Shadow DirectDraw, and Shadow DirectDraw Non-Locking, +respectively). +.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 \-emulatepseudo +Create a depth 8 PseudoColor visual when running in depths 15, 16, 24, +or 32, collectively known as TrueColor depths. + At this date (April 2004) this option is not still operative. +.TP 8 +.B "\-engine \fIengine_type_id\fP" +This option, which is intended for Cygwin/X developers, +overrides the server's automatically supported 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 DirectDraw4. +Additionally, there is a barely functional experimental engine type id +16 - Native GDI. +.TP 8 +.B "\-fullscreen [-depth \fIdepth\fP] [-refresh \fIrate_in_Hz\fP]" +Run the server in fullscreen mode, as opposed to the default windowed +mode. +.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. +.TP 8 +.B \-help +Write a help text to the console and to the log file. +.TP 8 +.B \-ignoreinput +Ignore keyboard and mouse input. This is usually only used for testing +and debugging purposes. +.TP 8 +.B \-[no]keyhook +Enable [disable] a low-level keyboard hook for catching +special key combinations like Alt+Tab and passing them to the X +Server instead of letting \fIWindows\fP handle them. +.TP 8 +.B \-lesspointer +Hide the Windows mouse cursor when the mouse is over any Cygwin/X +window (regardless of whether that window is active or inactive). This +prevents the Windows mouse cursor from being placed overtop of the X +cursor. +.TP 8 +.B "\-logfile \fIFile_Name\fP" +Change the log file from the default located at \fI/tmp/XWin.log\fP to +the one indicated by \fIFile_Name\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 (default) simple information about +configuration is also given, for \fIlevel\fP=2 a detailed log +information (including trace and debug output) is produced. Bigger +values will yield a still more detailed debug output. At this date +(April 2004) the option is still not fully operative; the default +value is 2 and the output is insensitive to the level value. +.TP 8 +.B \-multimonitors +Create a root window that covers all monitors on a system with +multiple monitors. +.TP 8 +.B \-multiwindow +Start the integrated \fIWindowsi\fP-based window manager, which launches each +top-level X window in its own \fIWindows\fP window. Not to be used together +with \fB\-rootless\fP nor \fB\-fullscreen\fP. +.TP 8 +.B \-nodecoration +Do not give the Cygwin/X window a Windows window border, title bar, +etc. This parameter only applies to windowed mode screens, i.e., this +parameter is ignored when the \fB\-fullscreen\fP parameter is specified. +.TP 8 +.B \-nounicodeclipboard +Do not use Unicode clipboard even if NT-based platform. +.TP 8 +.B \-rootless +Run the server in rootless mode. Not to be used with \fB\-multiwindow\fP +nor with \fB\-fullscreen\fP. +.TP 8 +.B "\-screen \fIscreen_number\fP \fIwidth\fP \fIheight\fP" +This parameter may be used to specify the +.I screen_number, +.I height, +and +.I width +of one or several Cygwin/X screens; each Cygwin/X screen will be +opened in its own window. When using multiple screens, be sure not to +duplicate any screen numbers. +.I XWin +default behavior is to create a single screen that is roughly +the size of the current Windows display area. +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 \-scrollbars +In windowed mode, allow screens bigger than the Windows desktop. +Moreover, if the window has decorations, one can now resize it. +.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 \-[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. +.TP 8 +.B \-swcursor +Disable the usage of the windows cursor and use the X11 software cursor instead. +.B \-silent-dup-error +If another instance of XWin is found running, exit silently and don't display +the error messge. +.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/usr/X11R6/lib/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" +.PP +Alternatively one may use the \fIsetxkbmap\fP program after XWin is +running or even the \fIxmodmap\fP program for loading the old-style +keyboard maps. + + +.SH "SEE ALSO" +X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1), XWinrc(1), 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 XWin software is developing rapidly; it is therefore likely that +this man page is not up to date. It is always prudent to +look also at the output of \fIXWin -help\fP and to the Cygwin/X User Guide +at /usr/share/doc/cygwin-x-doc-x.x.x/ug/cygwin-x-ug.xxx 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, Kensuke Matsuzaki, +Takuma Murakami, Earle F. Philhower III, Benjamin Riefenstahl, Suhaib +Siddiqi, Jack Tanner, and Nicholas Wourms. diff --git a/hw/xwin/XWin.rc b/hw/xwin/XWin.rc new file mode 100644 index 000000000..749c0f5f5 --- /dev/null +++ b/hw/xwin/XWin.rc @@ -0,0 +1,109 @@ +/* + *Copyright (C) 2002-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 + */ + +#include "windows.h" +#include "winresource.h" + +/* + * Dialogs + */ + +/* About */ +ABOUT_BOX DIALOG DISCARDABLE 32, 32, 240, 105 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTERMOUSE +CAPTION "About " PROJECT_NAME +FONT 8, "MS Sans Serif" +BEGIN + CONTROL PROJECT_NAME " Website", ID_ABOUT_WEBSITE, "Button", + BS_OWNERDRAW | WS_TABSTOP, 30, 45, 75, 15 + CONTROL "Change Log", ID_ABOUT_CHANGELOG, "Button", + BS_OWNERDRAW | WS_TABSTOP, 135, 45, 75, 15 + CONTROL "User's Guide", ID_ABOUT_UG, "Button", + BS_OWNERDRAW | WS_TABSTOP, 30, 65, 75, 15 + CONTROL "FAQ", ID_ABOUT_FAQ, "Button", + BS_OWNERDRAW | WS_TABSTOP, 135, 65, 75, 15 + + DEFPUSHBUTTON "Dismiss", IDOK, 95, 85, 50, 15 + + CTEXT "Welcome to the preliminary About box for the " PROJECT_NAME " X Server. This dialog was created on 2004/03/25 and will eventually be filled with more useful information. For now, use the links below to learn more about the " PROJECT_NAME " project.", IDC_STATIC, 5, 5, 230, 35 +END + + +/* Depth change */ + +DEPTH_CHANGE_BOX DIALOG DISCARDABLE 32, 32, 180, 100 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_CENTERMOUSE +FONT 8, "MS Sans Serif" +CAPTION PROJECT_NAME +BEGIN + DEFPUSHBUTTON "Dismiss", IDOK, 66, 80, 50, 14 + CTEXT PROJECT_NAME, IDC_STATIC, 40, 12, 100, 8 + CTEXT "Disruptive screen configuration change.", IDC_STATIC, 7, 40, 166, 8 + CTEXT "Restore previous resolution to use " PROJECT_NAME ".", IDC_STATIC, 7, 52, 166, 8 +END + + +/* Exit */ + +EXIT_DIALOG DIALOG DISCARDABLE 32, 32, 180, 78 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTERMOUSE +FONT 8, "MS Sans Serif" +CAPTION PROJECT_NAME " - Exit?" +BEGIN + PUSHBUTTON "E&xit", IDOK, 55, 56, 30, 14 + DEFPUSHBUTTON "&Cancel", IDCANCEL, 95, 56, 30, 14 + CTEXT "Exiting will close all screens running on this display.", IDC_STATIC, 7, 12, 166, 8 + CTEXT "No information about connected clients available.", IDC_CLIENTS_CONNECTED, 7, 24, 166, 8 + CTEXT "Proceed with shutdown of this display/server?", IDC_STATIC, 7, 36, 166, 8 +END + + +/* + * Menus + */ + +IDM_TRAYICON_MENU MENU DISCARDABLE +BEGIN + POPUP "TRAYICON_MENU" + BEGIN + MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT + MENUITEM "&About...", ID_APP_ABOUT + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END +END + + +/* + * Icons + */ + +IDI_XWIN ICON DISCARDABLE "X.ico" +IDI_XWIN_BOXED ICON DISCARDABLE "X-boxed.ico" diff --git a/hw/xwin/XWinrc.man b/hw/xwin/XWinrc.man new file mode 100755 index 000000000..eba3fb603 --- /dev/null +++ b/hw/xwin/XWinrc.man @@ -0,0 +1,180 @@ +.TH XWIN 5 __vendorversion__ + + +.SH NAME +XWinrc\- XWin Server Resource Configuration File. + + +.SH DESCRIPTION +The X Server for the X Window System on the Cygwin/X environment +running on Microsoft Windows, \fIXWin\fP can be optionally configured +with the \fIXWinrc\fP file. A system-wide configuration file should +be placed in \fI/usr/X11R6/lib/X11/system.XWinrc\fP, a per-user file +should be put at \fI$HOME/.XWinrc\fP. The \fIsystem.XWinrc\fP file is +read only if no \fI$HOME/.XWinrc\fP exist. +.PP +With the \fI.XWinrc\fP configuration file it is possible to do the +following: +.PP +1- To include items into the menu associated with the \fIXWin\fP icon +which is in the \fIWindows\fP system tray. This feature functions in +all XWin modes that have such tray icon. +.PP +2- To include items into the menu which is associated with the +\fIWindows\fP window that \fIXWin -multiwindow\fP produces for each +top-level X-window. That can be done both for the generic case and +for particular programs. +.PP +3- To change the icon that is associated to the \fIWindows\fP window +that \fIXWin -multiwindow\fP produces for each top-level X-window. +Again, that can be done both for the generic case and for particular +programs. The new icons associated should be \fIWindows\fP format +icons \fI.ico\fP. + + +.SH FILE FORMAT +.B Keywords +are case insensitive, but in this document they will be written +completely capitalized. +.PP +.B Comments +are legal pretty much anywhere you can have an end-of-line; they +begin with "#" or "//" and go to the end-of-line. +.PP +Quote marks in strings are optional unless the string has included spaces. +.PP +There are three kinds of instructions: miscellaneous, menu, and icon. + + +.SH Miscellaneous instruction +.TP 8 +.B DEBUG \fIString\fP +The \fIString\fP is printed to the XWin.log file. + +.TP 8 +.B TRAYICON \fIicon-specifier\fB +The \fBTRAYICON\fP keyword changes the icon \fIXWin\fP displays in the +system tray area. + +.TP 8 +.B SILENTEXIT +The \fBSILENTEXIT\fP keyword, which takes no parameters, disables the +exit confirmation dialog. + + +.SH Menu instructions +.TP 8 +.B MENU \fIMenu_Name\fP { +.br +.B \fIMenu_Item_Line\fP +.br +.B \fIMenu_Item_Line\fP +.br +.B \fI...\fP +.br +.B } +.br +This instruction defines a menu and asigns a \fIMenu_Name\fP to it. +\fIMenu_Item_Line\fP are lines of any of the following types: +.TP 8 +.B \t SEPARATOR +.TP 8 +.B \t \fIItem_Label\fP EXEC \fICommand\fP +.TP 8 +.B \t \fIItem_Label\fP MENU \fIpreviously-defined-menu-name\fP +.TP 8 +.B \t \fIItem_Label\fP ALWAYSONTOP +.TP 8 +.B \t \fIItem_Label\fP RELOAD +.br +The \fIItem_Label\fP is the string that is written in the menu item. +.br +\fICommand\fP is a string with the command that will be executed by /bin/sh. +Here paths should be \fICYGWIN\fP style (e.g. /usr/local/bin/myprogram). +A string "%display%" appearing in the \fICommand\fP will be replaced +with the proper display variable (i.e. 127.0.0.1:<display>.0). +.br +\fBALWAYSONTOP\fP sets the window to which the menu is associated to +display above all others. +.br +\fBRELOAD\fP causes the XWinrc file to be reloaded and icons and menus +regenerated. +.TP 8 +.B ROOTMENU \fIpreviously-defined-menu-name\fP +Includes the items in the indicated menu into the menu associated with +\fIXWin\fP that appears in the system tray. +.TP 8 +.B DEFAULTSYSMENU \fIpreviously-defined-menu-name\fP ATSTART|ATEND +Includes the items in the indicated menu into the menu associated with +generic top-level X-Windows in the \fIXWin\fP \fImultiwindow\fP mode. The +keywords \fBATSTART\fP and \fBATEND\fP indicate if such items should be +included at the start or at the end of the menu. +.TP 8 +.B SYSMENU { + \fIclass-or-name-of-window\fP \fIdefined-menu-name\fP \fBATSTART|ATEND\fP +.br + \fI...\fP +.br + \fB}\fP +.br +Associates a specific menu to a specific WM_CLASS or WM_NAME. + + +.SH Icon Instructions +When specifying an \fIicon-file\fP in the following commands several different formats are allowed: +.br +\fB"NAME.ICO"\fP\fI of an .ico format file\fP +.br +\t \t ("cygwin.ico", "apple.ico") +.br +\fB"NAME.DLL,nn"\fP\fI of a .DLL and icon index\fP +.br +\t \t ("c:\\windows\\system32\\shell32.dll,4" is the default folder icon) +.br +\fB",nn"\fP\fI index into XWin.EXE internal ICON resources\fP +.br +\t \t (",101" is the 1st icon inside \fIXWin.EXE\fP) +.TP 8 +.B ICONDIRECTORY \fIWindows-path-to-icon-directory\fP +Defines the default directory to search for \ficon-file\fP files. +It should be a \fIWindows\fP style path (e.g. C:\\cygwin\\usr\\local\\icons). +.TP 8 +.B DEFAULTICON \fIicon-file\fP +Defines a replacement for the standard X icon for applications without +specified icons. +.TP 8 +.B ICONS { +.br + \fIclass-or-name-of-window\fP \fIicon-file\fP +.br + \fI...\fP +.br + \fB}\fP +.br +Defines icon replacements windows matching the specified window class or names. +If multiple name or class matches occur for a window, only the first one +will be used. + + +.SH EXAMPLE +.TP 8 +This example adds an Xterm menu item to the system tray icon +\fBMENU systray { +.br +\t xterm EXEC "xterm -display %display% -sb -sl 999" +.br +\t SEPARATOR +.br +} +.br +ROOTMENU systray +\fP + + +.SH "SEE ALSO" + XWin(1) + + +.SH AUTHOR +The XWinrc feature of XWin was written primarily by Earle F. Philhower +III. diff --git a/hw/xwin/_usr_X11R6_lib_X11_system.XWinrc b/hw/xwin/_usr_X11R6_lib_X11_system.XWinrc new file mode 100644 index 000000000..d9c2d4210 --- /dev/null +++ b/hw/xwin/_usr_X11R6_lib_X11_system.XWinrc @@ -0,0 +1,125 @@ +# XWin Server Resource File - EXAMPLE +# Earle F. Philhower, III + +# Place in ~/.XWinrc or in /usr/X11R6/lib/X11/system.XWinrc + +# Keywords are case insensitive, comments legal pretty much anywhere +# you can have an end-of-line + +# Comments begin with "#" or "//" and go to the end-of-line + +# Paths to commands are **cygwin** based (i.e. /usr/local/bin/xcalc) + +# Paths to icons are **WINDOWS** based (i.e. c:\windows\icons) + +# Menus are defined as... +# MENU <name> { +# <Menu Text> EXEC <command> +# ^^ This command will have any "%display%" +# string replaced with the proper display +# variable (i.e. 127.0.0.1:<display>.0) +# or <Menu Text> MENU <name-of-some-prior-defined-menu> +# or <Menu Text> ALWAYSONTOP +# ^^ Sets the window to display above all others +# or <Menu Text> RELOAD +# ^^ Causes ~/.XWinrc or the system.XWinrc file +# to be reloaded and icons and menus regenerated +# or SEPARATOR +# ... +# } + +# Set the taskmar menu with +# ROOTMENU <name-of-some-prior-defined-menu> + +# If you want a menu to be applied to all popup window's system menu +# DEFAULTSYSMENU <name-of-some-prior-defined-menu> <atstart|atend> + +# To choose a specific menu for a specific WM_CLASS or WM_NAME use ... +# SYSMENU { +# <class-or-name-of-window> <name-of-prior-defined-menu> <atstart|atend> +# ... +# } + +# When specifying an ICONFILE in the following commands several different +# formats are allowed: +# 1. Name of a regular Windows .ico format file +# (ex: "cygwin.ico", "apple.ico") +# 2. Name and index into a Windows .DLL +# (ex: "c:\windows\system32\shell32.dll,4" gives the default folder icon +# "c:\windows\system32\shell32.dll,5" gives the floppy drive icon) +# 3. Index into XWin.EXE internal ICON resource +# (ex: ",101" is the 1st icon inside XWin.exe) + +# To define where ICO files live (** Windows path**) +# ICONDIRECTORY <windows-path i.e. c:\cygwin\usr\icons> +# NOTE: If you specify a fully qualified path to an ICON below +# (i.e. "c:\xxx" or "d:\xxxx") +# this ICONDIRECTORY will not be prepended + +# To change the taskbar icon use... +# TRAYICON <name-of-windows-ico-file-in-icondirectory> + +# To define a replacement for the standard X icon for apps w/o specified icons +# DEFAULTICON <name-of-windows-ico-file-in-icondirectory> + +# To define substitute icons on a per-window basis use... +# ICONS { +# <class-or-name-of-window> <icon-file-name.ico> +# ... +# } +# In the case where multiple matches occur, the first listed in the ICONS +# section will be chosen. + +# To disable exit confirmation dialog add the line containing SilentExit + +# DEBUG <string> prints out the string to the XWin.log file + +// Below are just some silly menus to demonstrate writing your +// own configuration file. + +// Make some menus... +menu apps { + xterm exec "xterm" + "Emacs" exec "emacs" + notepad exec notepad + xload exec "xload -display %display%" # Comment +} + +menu root { +// Comments fit here, too... + "Reload .XWinrc" RELOAD + "Applications" menu apps + SEParATOR +} + +menu aot { + Separator + "Always on Top" alwaysontop +} + +menu xtermspecial { + "Emacs" exec "emacs" + "Always on Top" alwaysontop + SepArAtor +} + +RootMenu root + +DefaultSysMenu aot atend + +SysMenu { + "xterm" xtermspecial atstart +} + +# IconDirectory "c:\winnt\" + +# DefaultIcon "reinstall.ico" + +# Icons { +# "xterm" "uninstall.ico" +# } + +# SilentExit + +DEBUG "Done parsing the configuration file..." + diff --git a/hw/xwin/ddraw.h b/hw/xwin/ddraw.h new file mode 100644 index 000000000..2eb7c2674 --- /dev/null +++ b/hw/xwin/ddraw.h @@ -0,0 +1,2106 @@ +#ifndef __XWIN_DDRAW_H +#define __XWIN_DDRAW_H + +#include <winnt.h> +#include <wingdi.h> +#include <objbase.h> + +#if defined(NONAMELESSUNION) && !defined(DUMMYUNIONNAME1) +#define DUMMYUNIONNAME1 u1 +#endif + +#define ICOM_CALL_( xfn, p, args) (p)->lpVtbl->xfn args + +# ifdef UNICODE +# define WINELIB_NAME_AW(func) func##W +# else +# define WINELIB_NAME_AW(func) func##A +# endif /* UNICODE */ +#define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#ifndef DIRECTDRAW_VERSION +#define DIRECTDRAW_VERSION 0x0700 +#endif /* DIRECTDRAW_VERSION */ + +/***************************************************************************** + * Predeclare the interfaces + */ +DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); +DEFINE_GUID( CLSID_DirectDraw7, 0x3C305196,0x50DB,0x11D3,0x9C,0xFE,0x00,0xC0,0x4F,0xD9,0x30,0xC5 ); +DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); +DEFINE_GUID( IID_IDirectDraw7, 0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); +DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); +DEFINE_GUID( IID_IDirectDrawSurface3, 0xDA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB ); +DEFINE_GUID( IID_IDirectDrawSurface4, 0x0B2B8630,0xAD35,0x11D0,0x8E,0xA6,0x00,0x60,0x97,0x97,0xEA,0x5B ); +DEFINE_GUID( IID_IDirectDrawSurface7, 0x06675a80,0x3b9b,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); +DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawColorControl,0x4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 ); +DEFINE_GUID( IID_IDirectDrawGammaControl,0x69C11C3E,0xB46B,0x11D1,0xAD,0x7A,0x00,0xC0,0x4F,0xC2,0x9B,0x4E ); + +typedef struct IDirectDraw *LPDIRECTDRAW; +typedef struct IDirectDraw2 *LPDIRECTDRAW2; +typedef struct IDirectDraw4 *LPDIRECTDRAW4; +typedef struct IDirectDraw7 *LPDIRECTDRAW7; +typedef struct IDirectDrawClipper *LPDIRECTDRAWCLIPPER; +typedef struct IDirectDrawPalette *LPDIRECTDRAWPALETTE; +typedef struct IDirectDrawSurface *LPDIRECTDRAWSURFACE; +typedef struct IDirectDrawSurface2 *LPDIRECTDRAWSURFACE2; +typedef struct IDirectDrawSurface3 *LPDIRECTDRAWSURFACE3; +typedef struct IDirectDrawSurface4 *LPDIRECTDRAWSURFACE4; +typedef struct IDirectDrawSurface7 *LPDIRECTDRAWSURFACE7; +typedef struct IDirectDrawColorControl *LPDIRECTDRAWCOLORCONTROL; +typedef struct IDirectDrawGammaControl *LPDIRECTDRAWGAMMACONTROL; + + +#define DDENUMRET_CANCEL 0 +#define DDENUMRET_OK 1 + +#define DD_OK 0 + + +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 ) +#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 ) +#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 ) +#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 ) +#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 ) +#define DDERR_GENERIC E_FAIL +#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 ) +#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 ) +#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 ) +#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 ) +#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 ) +#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 ) +#define DDERR_INVALIDPARAMS E_INVALIDARG +#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 ) +#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 ) +#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 ) +#define DDERR_NO3D MAKE_DDHRESULT( 170 ) +#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 ) +#define DDERR_NOSTEREOHARDWARE MAKE_DDHRESULT( 181 ) +#define DDERR_NOSURFACELEFT MAKE_DDHRESULT( 182 ) +#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 ) +#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 ) +#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 ) +#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 ) +#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 ) +#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 ) +#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 ) +#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 ) +#define DDERR_NOGDI MAKE_DDHRESULT( 240 ) +#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 ) +#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 ) +#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 ) +#define DDERR_OVERLAPPINGRECTS MAKE_DDHRESULT( 270 ) +#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 ) +#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 ) +#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 ) +#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 ) +#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 ) +#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 ) +#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 ) +#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 ) +#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 ) +#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 ) +#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 ) +#define DDERR_OUTOFMEMORY E_OUTOFMEMORY +#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 ) +#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 ) +#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 ) +#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 ) +#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 ) +#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 ) +#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 ) +#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 ) +#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 ) +#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 ) +#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 ) +#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 ) +#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 ) +#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 ) +#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 ) +#define DDERR_UNSUPPORTED E_NOTIMPL +#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 ) +#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 ) +#define DDERR_INVALIDSTREAM MAKE_DDHRESULT( 521 ) +#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 ) +#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 ) +#define DDERR_DDSCAPSCOMPLEXREQUIRED MAKE_DDHRESULT( 542 ) +#define DDERR_XALIGN MAKE_DDHRESULT( 560 ) +#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 ) +#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 ) +#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 ) +#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 ) +#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 ) +#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 ) +#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 ) +#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 ) +#define DDERR_NOHWND MAKE_DDHRESULT( 569 ) +#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 ) +#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 ) +#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 ) +#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 ) +#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 ) +#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 ) +#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 ) +#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 ) +#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 ) +#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 ) +#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 ) +#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 ) +#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 ) +#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 ) +#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 ) +#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 ) +#define DDERR_NODC MAKE_DDHRESULT( 586 ) +#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 ) +#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 ) +#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 ) +#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 ) +#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 ) +#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 ) +#define DDERR_NOOPTIMIZEHW MAKE_DDHRESULT( 600 ) +#define DDERR_NOTLOADED MAKE_DDHRESULT( 601 ) +#define DDERR_NOFOCUSWINDOW MAKE_DDHRESULT( 602 ) +#define DDERR_NOTONMIPMAPSUBLEVEL MAKE_DDHRESULT( 603 ) +#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 ) +#define DDERR_NONONLOCALVIDMEM MAKE_DDHRESULT( 630 ) +#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 ) +#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 ) +#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 ) +#define DDERR_MOREDATA MAKE_DDHRESULT( 690 ) +#define DDERR_EXPIRED MAKE_DDHRESULT( 691 ) +#define DDERR_TESTFINISHED MAKE_DDHRESULT( 692 ) +#define DDERR_NEWMODE MAKE_DDHRESULT( 693 ) +#define DDERR_D3DNOTINITIALIZED MAKE_DDHRESULT( 694 ) +#define DDERR_VIDEONOTACTIVE MAKE_DDHRESULT( 695 ) +#define DDERR_NOMONITORINFORMATION MAKE_DDHRESULT( 696 ) +#define DDERR_NODRIVERSUPPORT MAKE_DDHRESULT( 697 ) +#define DDERR_DEVICEDOESNTOWNSURFACE MAKE_DDHRESULT( 699 ) +#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED + +/* dwFlags for Blt* */ +#define DDBLT_ALPHADEST 0x00000001 +#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002 +#define DDBLT_ALPHADESTNEG 0x00000004 +#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008 +#define DDBLT_ALPHAEDGEBLEND 0x00000010 +#define DDBLT_ALPHASRC 0x00000020 +#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040 +#define DDBLT_ALPHASRCNEG 0x00000080 +#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100 +#define DDBLT_ASYNC 0x00000200 +#define DDBLT_COLORFILL 0x00000400 +#define DDBLT_DDFX 0x00000800 +#define DDBLT_DDROPS 0x00001000 +#define DDBLT_KEYDEST 0x00002000 +#define DDBLT_KEYDESTOVERRIDE 0x00004000 +#define DDBLT_KEYSRC 0x00008000 +#define DDBLT_KEYSRCOVERRIDE 0x00010000 +#define DDBLT_ROP 0x00020000 +#define DDBLT_ROTATIONANGLE 0x00040000 +#define DDBLT_ZBUFFER 0x00080000 +#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000 +#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000 +#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000 +#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000 +#define DDBLT_WAIT 0x01000000 +#define DDBLT_DEPTHFILL 0x02000000 +#define DDBLT_DONOTWAIT 0x08000000 + +/* dwTrans for BltFast */ +#define DDBLTFAST_NOCOLORKEY 0x00000000 +#define DDBLTFAST_SRCCOLORKEY 0x00000001 +#define DDBLTFAST_DESTCOLORKEY 0x00000002 +#define DDBLTFAST_WAIT 0x00000010 +#define DDBLTFAST_DONOTWAIT 0x00000020 + +/* dwFlags for Flip */ +#define DDFLIP_WAIT 0x00000001 +#define DDFLIP_EVEN 0x00000002 /* only valid for overlay */ +#define DDFLIP_ODD 0x00000004 /* only valid for overlay */ +#define DDFLIP_NOVSYNC 0x00000008 +#define DDFLIP_STEREO 0x00000010 +#define DDFLIP_DONOTWAIT 0x00000020 + +/* dwFlags for GetBltStatus */ +#define DDGBS_CANBLT 0x00000001 +#define DDGBS_ISBLTDONE 0x00000002 + +/* dwFlags for IDirectDrawSurface7::GetFlipStatus */ +#define DDGFS_CANFLIP 1L +#define DDGFS_ISFLIPDONE 2L + +/* dwFlags for IDirectDrawSurface7::SetPrivateData */ +#define DDSPD_IUNKNOWNPTR 1L +#define DDSPD_VOLATILE 2L + +/* DDSCAPS.dwCaps */ +/* reserved1, was 3d capable */ +#define DDSCAPS_RESERVED1 0x00000001 +/* surface contains alpha information */ +#define DDSCAPS_ALPHA 0x00000002 +/* this surface is a backbuffer */ +#define DDSCAPS_BACKBUFFER 0x00000004 +/* complex surface structure */ +#define DDSCAPS_COMPLEX 0x00000008 +/* part of surface flipping structure */ +#define DDSCAPS_FLIP 0x00000010 +/* this surface is the frontbuffer surface */ +#define DDSCAPS_FRONTBUFFER 0x00000020 +/* this is a plain offscreen surface */ +#define DDSCAPS_OFFSCREENPLAIN 0x00000040 +/* overlay */ +#define DDSCAPS_OVERLAY 0x00000080 +/* palette objects can be created and attached to us */ +#define DDSCAPS_PALETTE 0x00000100 +/* primary surface (the one the user looks at currently)(right eye)*/ +#define DDSCAPS_PRIMARYSURFACE 0x00000200 +/* primary surface for left eye */ +#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400 +/* surface exists in systemmemory */ +#define DDSCAPS_SYSTEMMEMORY 0x00000800 +/* surface can be used as a texture */ +#define DDSCAPS_TEXTURE 0x00001000 +/* surface may be destination for 3d rendering */ +#define DDSCAPS_3DDEVICE 0x00002000 +/* surface exists in videomemory */ +#define DDSCAPS_VIDEOMEMORY 0x00004000 +/* surface changes immediately visible */ +#define DDSCAPS_VISIBLE 0x00008000 +/* write only surface */ +#define DDSCAPS_WRITEONLY 0x00010000 +/* zbuffer surface */ +#define DDSCAPS_ZBUFFER 0x00020000 +/* has its own DC */ +#define DDSCAPS_OWNDC 0x00040000 +/* surface should be able to receive live video */ +#define DDSCAPS_LIVEVIDEO 0x00080000 +/* should be able to have a hw codec decompress stuff into it */ +#define DDSCAPS_HWCODEC 0x00100000 +/* mode X (320x200 or 320x240) surface */ +#define DDSCAPS_MODEX 0x00200000 +/* one mipmap surface (1 level) */ +#define DDSCAPS_MIPMAP 0x00400000 +#define DDSCAPS_RESERVED2 0x00800000 +/* memory allocation delayed until Load() */ +#define DDSCAPS_ALLOCONLOAD 0x04000000 +/* Indicates that the surface will receive data from a video port */ +#define DDSCAPS_VIDEOPORT 0x08000000 +/* surface is in local videomemory */ +#define DDSCAPS_LOCALVIDMEM 0x10000000 +/* surface is in nonlocal videomemory */ +#define DDSCAPS_NONLOCALVIDMEM 0x20000000 +/* surface is a standard VGA mode surface (NOT ModeX) */ +#define DDSCAPS_STANDARDVGAMODE 0x40000000 +/* optimized? surface */ +#define DDSCAPS_OPTIMIZED 0x80000000 + +typedef struct _DDSCAPS { + DWORD dwCaps; /* capabilities of surface wanted */ +} DDSCAPS,*LPDDSCAPS; + +/* DDSCAPS2.dwCaps2 */ +/* indicates the surface will receive data from a video port using + deinterlacing hardware. */ +#define DDSCAPS2_HARDWAREDEINTERLACE 0x00000002 +/* indicates the surface will be locked very frequently. */ +#define DDSCAPS2_HINTDYNAMIC 0x00000004 +/* indicates surface can be re-ordered or retiled on load() */ +#define DDSCAPS2_HINTSTATIC 0x00000008 +/* indicates surface to be managed by directdraw/direct3D */ +#define DDSCAPS2_TEXTUREMANAGE 0x00000010 +/* reserved bits */ +#define DDSCAPS2_RESERVED1 0x00000020 +#define DDSCAPS2_RESERVED2 0x00000040 +/* indicates surface will never be locked again */ +#define DDSCAPS2_OPAQUE 0x00000080 +/* set at CreateSurface() time to indicate antialising will be used */ +#define DDSCAPS2_HINTANTIALIASING 0x00000100 +/* set at CreateSurface() time to indicate cubic environment map */ +#define DDSCAPS2_CUBEMAP 0x00000200 +/* face flags for cube maps */ +#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400 +#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800 +#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000 +#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000 +#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000 +#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000 +/* specifies all faces of a cube for CreateSurface() */ +#define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX |\ + DDSCAPS2_CUBEMAP_NEGATIVEX |\ + DDSCAPS2_CUBEMAP_POSITIVEY |\ + DDSCAPS2_CUBEMAP_NEGATIVEY |\ + DDSCAPS2_CUBEMAP_POSITIVEZ |\ + DDSCAPS2_CUBEMAP_NEGATIVEZ ) +/* set for mipmap sublevels on DirectX7 and later. ignored by CreateSurface() */ +#define DDSCAPS2_MIPMAPSUBLEVEL 0x00010000 +/* indicates texture surface to be managed by Direct3D *only* */ +#define DDSCAPS2_D3DTEXTUREMANAGE 0x00020000 +/* indicates managed surface that can safely be lost */ +#define DDSCAPS2_DONOTPERSIST 0x00040000 +/* indicates surface is part of a stereo flipping chain */ +#define DDSCAPS2_STEREOSURFACELEFT 0x00080000 + +typedef struct _DDSCAPS2 { + DWORD dwCaps; /* capabilities of surface wanted */ + DWORD dwCaps2; /* additional capabilities */ + DWORD dwCaps3; /* reserved capabilities */ + DWORD dwCaps4; /* more reserved capabilities */ +} DDSCAPS2,*LPDDSCAPS2; + +#define DD_ROP_SPACE (256/32) /* space required to store ROP array */ + +typedef struct _DDCAPS_DX7 /* DirectX 7 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsOldCaps; /* old DDSCAPS - superceded for DirectX6+ */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ + DWORD dwCurrVideoPorts; /* current number of video ports used */ + DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ + DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ + DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ + DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ + DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ + DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ + DDSCAPS2 ddsCaps; /* surface capabilities */ +} DDCAPS_DX7,*LPDDCAPS_DX7; + +typedef struct _DDCAPS_DX6 /* DirectX 6 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsOldCaps; /* old DDSCAPS - superceded for DirectX6+ */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ + DWORD dwCurrVideoPorts; /* current number of video ports used */ + DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ + DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ + DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ + DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ + DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ + DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ + /* and one new member for DirectX 6 */ + DDSCAPS2 ddsCaps; /* surface capabilities */ +} DDCAPS_DX6,*LPDDCAPS_DX6; + +typedef struct _DDCAPS_DX5 /* DirectX5 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + /* the following are the new DirectX 5 members */ + DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ + DWORD dwCurrVideoPorts; /* current number of video ports used */ + DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ + DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ + DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ + DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ + DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ + DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ +} DDCAPS_DX5,*LPDDCAPS_DX5; + +typedef struct _DDCAPS_DX3 /* DirectX3 version of caps struct */ +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwReserved4; + DWORD dwReserved5; + DWORD dwReserved6; +} DDCAPS_DX3,*LPDDCAPS_DX3; + +/* set caps struct according to DIRECTDRAW_VERSION */ + +#if DIRECTDRAW_VERSION <= 0x300 +typedef DDCAPS_DX3 DDCAPS; +#elif DIRECTDRAW_VERSION <= 0x500 +typedef DDCAPS_DX5 DDCAPS; +#elif DIRECTDRAW_VERSION <= 0x600 +typedef DDCAPS_DX6 DDCAPS; +#else +typedef DDCAPS_DX7 DDCAPS; +#endif + +typedef DDCAPS *LPDDCAPS; + +/* DDCAPS.dwCaps */ +#define DDCAPS_3D 0x00000001 +#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002 +#define DDCAPS_ALIGNSIZEDEST 0x00000004 +#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008 +#define DDCAPS_ALIGNSIZESRC 0x00000010 +#define DDCAPS_ALIGNSTRIDE 0x00000020 +#define DDCAPS_BLT 0x00000040 +#define DDCAPS_BLTQUEUE 0x00000080 +#define DDCAPS_BLTFOURCC 0x00000100 +#define DDCAPS_BLTSTRETCH 0x00000200 +#define DDCAPS_GDI 0x00000400 +#define DDCAPS_OVERLAY 0x00000800 +#define DDCAPS_OVERLAYCANTCLIP 0x00001000 +#define DDCAPS_OVERLAYFOURCC 0x00002000 +#define DDCAPS_OVERLAYSTRETCH 0x00004000 +#define DDCAPS_PALETTE 0x00008000 +#define DDCAPS_PALETTEVSYNC 0x00010000 +#define DDCAPS_READSCANLINE 0x00020000 +#define DDCAPS_STEREOVIEW 0x00040000 +#define DDCAPS_VBI 0x00080000 +#define DDCAPS_ZBLTS 0x00100000 +#define DDCAPS_ZOVERLAYS 0x00200000 +#define DDCAPS_COLORKEY 0x00400000 +#define DDCAPS_ALPHA 0x00800000 +#define DDCAPS_COLORKEYHWASSIST 0x01000000 +#define DDCAPS_NOHARDWARE 0x02000000 +#define DDCAPS_BLTCOLORFILL 0x04000000 +#define DDCAPS_BANKSWITCHED 0x08000000 +#define DDCAPS_BLTDEPTHFILL 0x10000000 +#define DDCAPS_CANCLIP 0x20000000 +#define DDCAPS_CANCLIPSTRETCHED 0x40000000 +#define DDCAPS_CANBLTSYSMEM 0x80000000 + +/* DDCAPS.dwCaps2 */ +#define DDCAPS2_CERTIFIED 0x00000001 +#define DDCAPS2_NO2DDURING3DSCENE 0x00000002 +#define DDCAPS2_VIDEOPORT 0x00000004 +#define DDCAPS2_AUTOFLIPOVERLAY 0x00000008 +#define DDCAPS2_CANBOBINTERLEAVED 0x00000010 +#define DDCAPS2_CANBOBNONINTERLEAVED 0x00000020 +#define DDCAPS2_COLORCONTROLOVERLAY 0x00000040 +#define DDCAPS2_COLORCONTROLPRIMARY 0x00000080 +#define DDCAPS2_CANDROPZ16BIT 0x00000100 +#define DDCAPS2_NONLOCALVIDMEM 0x00000200 +#define DDCAPS2_NONLOCALVIDMEMCAPS 0x00000400 +#define DDCAPS2_NOPAGELOCKREQUIRED 0x00000800 +#define DDCAPS2_WIDESURFACES 0x00001000 +#define DDCAPS2_CANFLIPODDEVEN 0x00002000 +#define DDCAPS2_CANBOBHARDWARE 0x00004000 +#define DDCAPS2_COPYFOURCC 0x00008000 +#define DDCAPS2_PRIMARYGAMMA 0x00020000 +#define DDCAPS2_CANRENDERWINDOWED 0x00080000 +#define DDCAPS2_CANCALIBRATEGAMMA 0x00100000 +#define DDCAPS2_FLIPINTERVAL 0x00200000 +#define DDCAPS2_FLIPNOVSYNC 0x00400000 +#define DDCAPS2_CANMANAGETEXTURE 0x00800000 +#define DDCAPS2_TEXMANINNONLOCALVIDMEM 0x01000000 +#define DDCAPS2_STEREO 0x02000000 +#define DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL 0x04000000 + + +/* Set/Get Colour Key Flags */ +#define DDCKEY_COLORSPACE 0x00000001 /* Struct is single colour space */ +#define DDCKEY_DESTBLT 0x00000002 /* To be used as dest for blt */ +#define DDCKEY_DESTOVERLAY 0x00000004 /* To be used as dest for CK overlays */ +#define DDCKEY_SRCBLT 0x00000008 /* To be used as src for blt */ +#define DDCKEY_SRCOVERLAY 0x00000010 /* To be used as src for CK overlays */ + +typedef struct _DDCOLORKEY +{ + DWORD dwColorSpaceLowValue;/* low boundary of color space that is to + * be treated as Color Key, inclusive + */ + DWORD dwColorSpaceHighValue;/* high boundary of color space that is + * to be treated as Color Key, inclusive + */ +} DDCOLORKEY,*LPDDCOLORKEY; + +/* ddCKEYCAPS bits */ +#define DDCKEYCAPS_DESTBLT 0x00000001 +#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002 +#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004 +#define DDCKEYCAPS_DESTBLTYUV 0x00000008 +#define DDCKEYCAPS_DESTOVERLAY 0x00000010 +#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020 +#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040 +#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080 +#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100 +#define DDCKEYCAPS_SRCBLT 0x00000200 +#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400 +#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800 +#define DDCKEYCAPS_SRCBLTYUV 0x00001000 +#define DDCKEYCAPS_SRCOVERLAY 0x00002000 +#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000 +#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000 +#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000 +#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000 +#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000 + +typedef struct _DDPIXELFORMAT { + DWORD dwSize; /* 0: size of structure */ + DWORD dwFlags; /* 4: pixel format flags */ + DWORD dwFourCC; /* 8: (FOURCC code) */ + union { + DWORD dwRGBBitCount; /* C: how many bits per pixel */ + DWORD dwYUVBitCount; /* C: how many bits per pixel */ + DWORD dwZBufferBitDepth; /* C: how many bits for z buffers */ + DWORD dwAlphaBitDepth; /* C: how many bits for alpha channels*/ + DWORD dwLuminanceBitCount; + DWORD dwBumpBitCount; + } DUMMYUNIONNAME1; + union { + DWORD dwRBitMask; /* 10: mask for red bit*/ + DWORD dwYBitMask; /* 10: mask for Y bits*/ + DWORD dwStencilBitDepth; + DWORD dwLuminanceBitMask; + DWORD dwBumpDuBitMask; + } DUMMYUNIONNAME2; + union { + DWORD dwGBitMask; /* 14: mask for green bits*/ + DWORD dwUBitMask; /* 14: mask for U bits*/ + DWORD dwZBitMask; + DWORD dwBumpDvBitMask; + } DUMMYUNIONNAME3; + union { + DWORD dwBBitMask; /* 18: mask for blue bits*/ + DWORD dwVBitMask; /* 18: mask for V bits*/ + DWORD dwStencilBitMask; + DWORD dwBumpLuminanceBitMask; + } DUMMYUNIONNAME4; + union { + DWORD dwRGBAlphaBitMask; /* 1C: mask for alpha channel */ + DWORD dwYUVAlphaBitMask; /* 1C: mask for alpha channel */ + DWORD dwLuminanceAlphaBitMask; + DWORD dwRGBZBitMask; /* 1C: mask for Z channel */ + DWORD dwYUVZBitMask; /* 1C: mask for Z channel */ + } DUMMYUNIONNAME5; + /* 20: next structure */ +} DDPIXELFORMAT,*LPDDPIXELFORMAT; + +/* DDCAPS.dwFXCaps */ +#define DDFXCAPS_BLTALPHA 0x00000001 +#define DDFXCAPS_OVERLAYALPHA 0x00000004 +#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010 +#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020 +#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040 +#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080 +#define DDFXCAPS_BLTROTATION 0x00000100 +#define DDFXCAPS_BLTROTATION90 0x00000200 +#define DDFXCAPS_BLTSHRINKX 0x00000400 +#define DDFXCAPS_BLTSHRINKXN 0x00000800 +#define DDFXCAPS_BLTSHRINKY 0x00001000 +#define DDFXCAPS_BLTSHRINKYN 0x00002000 +#define DDFXCAPS_BLTSTRETCHX 0x00004000 +#define DDFXCAPS_BLTSTRETCHXN 0x00008000 +#define DDFXCAPS_BLTSTRETCHY 0x00010000 +#define DDFXCAPS_BLTSTRETCHYN 0x00020000 +#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000 +#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008 +#define DDFXCAPS_OVERLAYSHRINKX 0x00080000 +#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000 +#define DDFXCAPS_OVERLAYSHRINKY 0x00200000 +#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000 +#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000 +#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000 +#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000 +#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000 +#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000 +#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000 + +#define DDFXCAPS_OVERLAYFILTER DDFXCAPS_OVERLAYARITHSTRETCHY + +/* DDCAPS.dwFXAlphaCaps */ +#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001 +#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002 +#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004 +#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008 +#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010 +#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020 +#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040 +#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080 +#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100 +#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200 + +/* DDCAPS.dwPalCaps */ +#define DDPCAPS_4BIT 0x00000001 +#define DDPCAPS_8BITENTRIES 0x00000002 +#define DDPCAPS_8BIT 0x00000004 +#define DDPCAPS_INITIALIZE 0x00000008 +#define DDPCAPS_PRIMARYSURFACE 0x00000010 +#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020 +#define DDPCAPS_ALLOW256 0x00000040 +#define DDPCAPS_VSYNC 0x00000080 +#define DDPCAPS_1BIT 0x00000100 +#define DDPCAPS_2BIT 0x00000200 +#define DDPCAPS_ALPHA 0x00000400 + +/* DDCAPS.dwSVCaps */ +/* the first 4 of these are now obsolete */ +#if DIRECTDRAW_VERSION >= 0x700 /* FIXME: I'm not sure when this switch occured */ +#define DDSVCAPS_RESERVED1 0x00000001 +#define DDSVCAPS_RESERVED2 0x00000002 +#define DDSVCAPS_RESERVED3 0x00000004 +#define DDSVCAPS_RESERVED4 0x00000008 +#else +#define DDSVCAPS_ENIGMA 0x00000001 +#define DDSVCAPS_FLICKER 0x00000002 +#define DDSVCAPS_REDBLUE 0x00000004 +#define DDSVCAPS_SPLIT 0x00000008 +#endif +#define DDSVCAPS_STEREOSEQUENTIAL 0x00000010 + +/* BitDepths */ +#define DDBD_1 0x00004000 +#define DDBD_2 0x00002000 +#define DDBD_4 0x00001000 +#define DDBD_8 0x00000800 +#define DDBD_16 0x00000400 +#define DDBD_24 0x00000200 +#define DDBD_32 0x00000100 + +/* DDOVERLAYFX.dwDDFX */ +#define DDOVERFX_ARITHSTRETCHY 0x00000001 +#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002 +#define DDOVERFX_MIRRORUPDOWN 0x00000004 + +/* UpdateOverlay flags */ +#define DDOVER_ALPHADEST 0x00000001 +#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002 +#define DDOVER_ALPHADESTNEG 0x00000004 +#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008 +#define DDOVER_ALPHAEDGEBLEND 0x00000010 +#define DDOVER_ALPHASRC 0x00000020 +#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040 +#define DDOVER_ALPHASRCNEG 0x00000080 +#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100 +#define DDOVER_HIDE 0x00000200 +#define DDOVER_KEYDEST 0x00000400 +#define DDOVER_KEYDESTOVERRIDE 0x00000800 +#define DDOVER_KEYSRC 0x00001000 +#define DDOVER_KEYSRCOVERRIDE 0x00002000 +#define DDOVER_SHOW 0x00004000 +#define DDOVER_ADDDIRTYRECT 0x00008000 +#define DDOVER_REFRESHDIRTYRECTS 0x00010000 +#define DDOVER_REFRESHALL 0x00020000 +#define DDOVER_DDFX 0x00080000 +#define DDOVER_AUTOFLIP 0x00100000 +#define DDOVER_BOB 0x00200000 +#define DDOVER_OVERRIDEBOBWEAVE 0x00400000 +#define DDOVER_INTERLEAVED 0x00800000 + +/* DDCOLORKEY.dwFlags */ +#define DDPF_ALPHAPIXELS 0x00000001 +#define DDPF_ALPHA 0x00000002 +#define DDPF_FOURCC 0x00000004 +#define DDPF_PALETTEINDEXED4 0x00000008 +#define DDPF_PALETTEINDEXEDTO8 0x00000010 +#define DDPF_PALETTEINDEXED8 0x00000020 +#define DDPF_RGB 0x00000040 +#define DDPF_COMPRESSED 0x00000080 +#define DDPF_RGBTOYUV 0x00000100 +#define DDPF_YUV 0x00000200 +#define DDPF_ZBUFFER 0x00000400 +#define DDPF_PALETTEINDEXED1 0x00000800 +#define DDPF_PALETTEINDEXED2 0x00001000 +#define DDPF_ZPIXELS 0x00002000 +#define DDPF_STENCILBUFFER 0x00004000 +#define DDPF_ALPHAPREMULT 0x00008000 +#define DDPF_LUMINANCE 0x00020000 +#define DDPF_BUMPLUMINANCE 0x00040000 +#define DDPF_BUMPDUDV 0x00080000 + +/* SetCooperativeLevel dwFlags */ +#define DDSCL_FULLSCREEN 0x00000001 +#define DDSCL_ALLOWREBOOT 0x00000002 +#define DDSCL_NOWINDOWCHANGES 0x00000004 +#define DDSCL_NORMAL 0x00000008 +#define DDSCL_EXCLUSIVE 0x00000010 +#define DDSCL_ALLOWMODEX 0x00000040 +#define DDSCL_SETFOCUSWINDOW 0x00000080 +#define DDSCL_SETDEVICEWINDOW 0x00000100 +#define DDSCL_CREATEDEVICEWINDOW 0x00000200 +#define DDSCL_MULTITHREADED 0x00000400 +#define DDSCL_FPUSETUP 0x00000800 +#define DDSCL_FPUPRESERVE 0x00001000 + + +/* DDSURFACEDESC.dwFlags */ +#define DDSD_CAPS 0x00000001 +#define DDSD_HEIGHT 0x00000002 +#define DDSD_WIDTH 0x00000004 +#define DDSD_PITCH 0x00000008 +#define DDSD_BACKBUFFERCOUNT 0x00000020 +#define DDSD_ZBUFFERBITDEPTH 0x00000040 +#define DDSD_ALPHABITDEPTH 0x00000080 +#define DDSD_LPSURFACE 0x00000800 +#define DDSD_PIXELFORMAT 0x00001000 +#define DDSD_CKDESTOVERLAY 0x00002000 +#define DDSD_CKDESTBLT 0x00004000 +#define DDSD_CKSRCOVERLAY 0x00008000 +#define DDSD_CKSRCBLT 0x00010000 +#define DDSD_MIPMAPCOUNT 0x00020000 +#define DDSD_REFRESHRATE 0x00040000 +#define DDSD_LINEARSIZE 0x00080000 +#define DDSD_TEXTURESTAGE 0x00100000 +#define DDSD_FVF 0x00200000 +#define DDSD_SRCVBHANDLE 0x00400000 +#define DDSD_ALL 0x007ff9ee + +/* EnumSurfaces flags */ +#define DDENUMSURFACES_ALL 0x00000001 +#define DDENUMSURFACES_MATCH 0x00000002 +#define DDENUMSURFACES_NOMATCH 0x00000004 +#define DDENUMSURFACES_CANBECREATED 0x00000008 +#define DDENUMSURFACES_DOESEXIST 0x00000010 + +/* SetDisplayMode flags */ +#define DDSDM_STANDARDVGAMODE 0x00000001 + +/* EnumDisplayModes flags */ +#define DDEDM_REFRESHRATES 0x00000001 +#define DDEDM_STANDARDVGAMODES 0x00000002 + +/* WaitForVerticalDisplay flags */ + +#define DDWAITVB_BLOCKBEGIN 0x00000001 +#define DDWAITVB_BLOCKBEGINEVENT 0x00000002 +#define DDWAITVB_BLOCKEND 0x00000004 + +typedef struct _DDSURFACEDESC +{ + DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ + DWORD dwFlags; /* 4: determines what fields are valid*/ + DWORD dwHeight; /* 8: height of surface to be created*/ + DWORD dwWidth; /* C: width of input surface*/ + union { + LONG lPitch; /* 10: distance to start of next line (return value only)*/ + DWORD dwLinearSize; + } DUMMYUNIONNAME1; + DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ + union { + DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ + DWORD dwZBufferBitDepth;/*18: depth of Z buffer requested*/ + DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ + } DUMMYUNIONNAME2; + DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ + DWORD dwReserved; /* 20:reserved*/ + LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ + DDCOLORKEY ddckCKDestOverlay;/* 28: CK for dest overlay use*/ + DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ + DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ + DDSCAPS ddsCaps; /* 68: direct draw surface caps */ +} DDSURFACEDESC,*LPDDSURFACEDESC; + +typedef struct _DDSURFACEDESC2 +{ + DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ + DWORD dwFlags; /* 4: determines what fields are valid*/ + DWORD dwHeight; /* 8: height of surface to be created*/ + DWORD dwWidth; /* C: width of input surface*/ + union { + LONG lPitch; /*10: distance to start of next line (return value only)*/ + DWORD dwLinearSize; /*10: formless late-allocated optimized surface size */ + } DUMMYUNIONNAME1; + DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ + union { + DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ + DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ + DWORD dwSrcVBHandle;/* 18:source used in VB::Optimize */ + } DUMMYUNIONNAME2; + DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ + DWORD dwReserved; /* 20:reserved*/ + LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ + union { + DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/ + DWORD dwEmptyFaceColor; /* 28: color for empty cubemap faces */ + } DUMMYUNIONNAME3; + DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ + + union { + DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ + DWORD dwFVF; /* 48: vertex format description of vertex buffers */ + } DUMMYUNIONNAME4; + DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */ + DWORD dwTextureStage; /* 78: stage in multitexture cascade */ +} DDSURFACEDESC2,*LPDDSURFACEDESC2; + +/* DDCOLORCONTROL.dwFlags */ +#define DDCOLOR_BRIGHTNESS 0x00000001 +#define DDCOLOR_CONTRAST 0x00000002 +#define DDCOLOR_HUE 0x00000004 +#define DDCOLOR_SATURATION 0x00000008 +#define DDCOLOR_SHARPNESS 0x00000010 +#define DDCOLOR_GAMMA 0x00000020 +#define DDCOLOR_COLORENABLE 0x00000040 + +typedef struct { + DWORD dwSize; + DWORD dwFlags; + LONG lBrightness; + LONG lContrast; + LONG lHue; + LONG lSaturation; + LONG lSharpness; + LONG lGamma; + LONG lColorEnable; + DWORD dwReserved1; +} DDCOLORCONTROL,*LPDDCOLORCONTROL; + +typedef struct { + WORD red[256]; + WORD green[256]; + WORD blue[256]; +} DDGAMMARAMP,*LPDDGAMMARAMP; + +typedef BOOL CALLBACK (*LPDDENUMCALLBACKA)(GUID *, LPSTR, LPSTR, LPVOID); +typedef BOOL CALLBACK (*LPDDENUMCALLBACKW)(GUID *, LPWSTR, LPWSTR, LPVOID); +DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK) + +typedef HRESULT CALLBACK (*LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMMODESCALLBACK2)(LPDDSURFACEDESC2, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK2)(LPDIRECTDRAWSURFACE4, LPDDSURFACEDESC2, LPVOID); +typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK7)(LPDIRECTDRAWSURFACE7, LPDDSURFACEDESC2, LPVOID); + +typedef BOOL CALLBACK (*LPDDENUMCALLBACKEXA)(GUID *, LPSTR, LPSTR, LPVOID, HMONITOR); +typedef BOOL CALLBACK (*LPDDENUMCALLBACKEXW)(GUID *, LPWSTR, LPWSTR, LPVOID, HMONITOR); +DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACKEX) + +HRESULT WINAPI DirectDrawEnumerateExA( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags); +HRESULT WINAPI DirectDrawEnumerateExW( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags); +#define DirectDrawEnumerateEx WINELIB_NAME_AW(DirectDrawEnumerateEx) + +/* flags for DirectDrawEnumerateEx */ +#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001 +#define DDENUM_DETACHEDSECONDARYDEVICES 0x00000002 +#define DDENUM_NONDISPLAYDEVICES 0x00000004 + +/* flags for DirectDrawCreate or IDirectDraw::Initialize */ +#define DDCREATE_HARDWAREONLY 1L +#define DDCREATE_EMULATIONONLY 2L + +typedef struct _DDBLTFX +{ + DWORD dwSize; /* size of structure */ + DWORD dwDDFX; /* FX operations */ + DWORD dwROP; /* Win32 raster operations */ + DWORD dwDDROP; /* Raster operations new for DirectDraw */ + DWORD dwRotationAngle; /* Rotation angle for blt */ + DWORD dwZBufferOpCode; /* ZBuffer compares */ + DWORD dwZBufferLow; /* Low limit of Z buffer */ + DWORD dwZBufferHigh; /* High limit of Z buffer */ + DWORD dwZBufferBaseDest; /* Destination base value */ + DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */ + union + { + DWORD dwZDestConst; /* Constant to use as Z buffer for dest */ + LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */ + } DUMMYUNIONNAME1; + DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */ + union + { + DWORD dwZSrcConst; /* Constant to use as Z buffer for src */ + LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */ + } DUMMYUNIONNAME2; + DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ + DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */ + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ + union + { + DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */ + } DUMMYUNIONNAME3; + DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ + union + { + DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */ + } DUMMYUNIONNAME4; + union + { + DWORD dwFillColor; /* color in RGB or Palettized */ + DWORD dwFillDepth; /* depth value for z-buffer */ + DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */ + LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */ + } DUMMYUNIONNAME5; + DDCOLORKEY ddckDestColorkey; /* DestColorkey override */ + DDCOLORKEY ddckSrcColorkey; /* SrcColorkey override */ +} DDBLTFX,*LPDDBLTFX; + +/* dwDDFX */ +/* arithmetic stretching along y axis */ +#define DDBLTFX_ARITHSTRETCHY 0x00000001 +/* mirror on y axis */ +#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002 +/* mirror on x axis */ +#define DDBLTFX_MIRRORUPDOWN 0x00000004 +/* do not tear */ +#define DDBLTFX_NOTEARING 0x00000008 +/* 180 degrees clockwise rotation */ +#define DDBLTFX_ROTATE180 0x00000010 +/* 270 degrees clockwise rotation */ +#define DDBLTFX_ROTATE270 0x00000020 +/* 90 degrees clockwise rotation */ +#define DDBLTFX_ROTATE90 0x00000040 +/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */ +#define DDBLTFX_ZBUFFERRANGE 0x00000080 +/* add dwZBufferBaseDest to every source z value before compare */ +#define DDBLTFX_ZBUFFERBASEDEST 0x00000100 + +typedef struct _DDOVERLAYFX +{ + DWORD dwSize; /* size of structure */ + DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ + DWORD dwAlphaEdgeBlend; /* Constant to use as alpha for edge blend */ + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ + union + { + DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */ + } DUMMYUNIONNAME1; + DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ + union + { + DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */ + } DUMMYUNIONNAME2; + DDCOLORKEY dckDestColorkey; /* DestColorkey override */ + DDCOLORKEY dckSrcColorkey; /* DestColorkey override */ + DWORD dwDDFX; /* Overlay FX */ + DWORD dwFlags; /* flags */ +} DDOVERLAYFX,*LPDDOVERLAYFX; + +typedef struct _DDBLTBATCH +{ + LPRECT lprDest; + LPDIRECTDRAWSURFACE lpDDSSrc; + LPRECT lprSrc; + DWORD dwFlags; + LPDDBLTFX lpDDBltFx; +} DDBLTBATCH,*LPDDBLTBATCH; + +#define MAX_DDDEVICEID_STRING 512 + +typedef struct tagDDDEVICEIDENTIFIER { + char szDriver[MAX_DDDEVICEID_STRING]; + char szDescription[MAX_DDDEVICEID_STRING]; + LARGE_INTEGER liDriverVersion; + DWORD dwVendorId; + DWORD dwDeviceId; + DWORD dwSubSysId; + DWORD dwRevision; + GUID guidDeviceIdentifier; +} DDDEVICEIDENTIFIER, * LPDDDEVICEIDENTIFIER; + +typedef struct tagDDDEVICEIDENTIFIER2 { + char szDriver[MAX_DDDEVICEID_STRING]; /* user readable driver name */ + char szDescription[MAX_DDDEVICEID_STRING]; /* user readable description */ + LARGE_INTEGER liDriverVersion; /* driver version */ + DWORD dwVendorId; /* vendor ID, zero if unknown */ + DWORD dwDeviceId; /* chipset ID, zero if unknown */ + DWORD dwSubSysId; /* board ID, zero if unknown */ + DWORD dwRevision; /* chipset version, zero if unknown */ + GUID guidDeviceIdentifier; /* unique ID for this driver/chipset combination */ + DWORD dwWHQLLevel; /* Windows Hardware Quality Lab certification level */ +} DDDEVICEIDENTIFIER2, * LPDDDEVICEIDENTIFIER2; + +/***************************************************************************** + * IDirectDrawPalette interface + */ +#undef INTERFACE +#define INTERFACE IDirectDrawPalette +DECLARE_INTERFACE_(IDirectDrawPalette,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(GetCaps)(THIS_ LPDWORD lpdwCaps) PURE; + STDMETHOD(GetEntries)(THIS_ DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable) PURE; + STDMETHOD(SetEntries)(THIS_ DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawPalette_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawPalette_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawPalette_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDrawPalette methods ***/ +#define IDirectDrawPalette_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) +#define IDirectDrawPalette_GetEntries(p,a,b,c,d) ICOM_CALL_(GetEntries,p,(p,a,b,c,d)) +#define IDirectDrawPalette_Initialize(p,a,b,c) ICOM_CALL_(Initialize,p,(p,a,b,c)) +#define IDirectDrawPalette_SetEntries(p,a,b,c,d) ICOM_CALL_(SetEntries,p,(p,a,b,c,d)) + + +/***************************************************************************** + * IDirectDrawClipper interface + */ +#undef INTERFACE +#define INTERFACE IDirectDrawClipper +DECLARE_INTERFACE_(IDirectDrawClipper,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(GetClipList)(THIS_ LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize) PURE; + STDMETHOD(GetHWnd)(THIS_ HWND* lphWnd) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags) PURE; + STDMETHOD(IsClipListChanged)(THIS_ BOOL* lpbChanged) PURE; + STDMETHOD(SetClipList)(THIS_ LPRGNDATA lpClipList, DWORD dwFlags) PURE; + STDMETHOD(SetHWnd)(THIS_ DWORD dwFlags, HWND hWnd) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawClipper_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawClipper_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawClipper_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDrawClipper methods ***/ +#define IDirectDrawClipper_GetClipList(p,a,b,c) ICOM_CALL_(GetClipList,p,(p,a,b,c)) +#define IDirectDrawClipper_GetHWnd(p,a) ICOM_CALL_(GetHWnd,p,(p,a)) +#define IDirectDrawClipper_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) +#define IDirectDrawClipper_IsClipListChanged(p,a) ICOM_CALL_(IsClipListChanged,p,(p,a)) +#define IDirectDrawClipper_SetClipList(p,a,b) ICOM_CALL_(SetClipList,p,(p,a,b)) +#define IDirectDrawClipper_SetHWnd(p,a,b) ICOM_CALL_(SetHWnd,p,(p,a,b)) + + +/***************************************************************************** + * IDirectDraw interface + */ +#undef INTERFACE +#define INTERFACE IDirectDraw +DECLARE_INTERFACE_(IDirectDraw,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) PURE; + STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE* lplpDupDDSurface) PURE; + STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE* lplpGDIDDSurface) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; + STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD, DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDraw_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDraw_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDraw_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDraw methods ***/ +#define IDirectDraw_Compact(p) ICOM_CALL_(Compact,p,(p)) +#define IDirectDraw_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) +#define IDirectDraw_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) +#define IDirectDraw_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) +#define IDirectDraw_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) +#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) +#define IDirectDraw_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) +#define IDirectDraw_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) +#define IDirectDraw_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) +#define IDirectDraw_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) +#define IDirectDraw_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) +#define IDirectDraw_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) +#define IDirectDraw_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) +#define IDirectDraw_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) +#define IDirectDraw_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) +#define IDirectDraw_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) +#define IDirectDraw_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) +#define IDirectDraw_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) +#define IDirectDraw_SetDisplayMode(p,a,b,c) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c)) +#define IDirectDraw_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) + + +/* flags for Lock() */ +#define DDLOCK_SURFACEMEMORYPTR 0x00000000 +#define DDLOCK_WAIT 0x00000001 +#define DDLOCK_EVENT 0x00000002 +#define DDLOCK_READONLY 0x00000010 +#define DDLOCK_WRITEONLY 0x00000020 +#define DDLOCK_NOSYSLOCK 0x00000800 + + +/***************************************************************************** + * IDirectDraw2 interface + */ +/* Note: IDirectDraw2 cannot derive from IDirectDraw because the number of + * arguments of SetDisplayMode has changed ! + */ +#undef INTERFACE +#define INTERFACE IDirectDraw2 +DECLARE_INTERFACE_(IDirectDraw2,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE2* lplpDDSurface, IUnknown* pUnkOuter) PURE; + STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurface, LPDIRECTDRAWSURFACE2* lplpDupDDSurface) PURE; + STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE2* lplpGDIDDSurface) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; + STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; + + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDraw2_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDraw2_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDraw2_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDraw methods ***/ +#define IDirectDraw2_Compact(p) ICOM_CALL_(Compact,p,(p)) +#define IDirectDraw2_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) +#define IDirectDraw2_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) +#define IDirectDraw2_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) +#define IDirectDraw2_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) +#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) +#define IDirectDraw2_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) +#define IDirectDraw2_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) +#define IDirectDraw2_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) +#define IDirectDraw2_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) +#define IDirectDraw2_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) +#define IDirectDraw2_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) +#define IDirectDraw2_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) +#define IDirectDraw2_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) +#define IDirectDraw2_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) +#define IDirectDraw2_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) +#define IDirectDraw2_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) +#define IDirectDraw2_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) +#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c,d,e)) +#define IDirectDraw2_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) +/*** IDirectDraw2 methods ***/ +#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c)) + + +/***************************************************************************** + * IDirectDraw4 interface + */ +#undef INTERFACE +#define INTERFACE IDirectDraw4 +DECLARE_INTERFACE_(IDirectDraw4,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4* lplpDDSurface, IUnknown* pUnkOuter) PURE; + STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurface, LPDIRECTDRAWSURFACE4* lplpDupDDSurface) PURE; + STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK2 lpEnumSurfacesCallback) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE4* lplpGDIDDSurface) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; + STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; + + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; + + STDMETHOD(GetSurfaceFromDC)(THIS_ HDC , LPDIRECTDRAWSURFACE4* ) PURE; + STDMETHOD(RestoreAllSurfaces)(THIS) PURE; + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER , DWORD ) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDraw4_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDraw4_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDraw4_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDraw methods ***/ +#define IDirectDraw4_Compact(p) ICOM_CALL_(Compact,p,(p)) +#define IDirectDraw4_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) +#define IDirectDraw4_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) +#define IDirectDraw4_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) +#define IDirectDraw4_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) +#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) +#define IDirectDraw4_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) +#define IDirectDraw4_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) +#define IDirectDraw4_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) +#define IDirectDraw4_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) +#define IDirectDraw4_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) +#define IDirectDraw4_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) +#define IDirectDraw4_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) +#define IDirectDraw4_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) +#define IDirectDraw4_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) +#define IDirectDraw4_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) +#define IDirectDraw4_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) +#define IDirectDraw4_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) +#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c,d,e)) +#define IDirectDraw4_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) +/*** IDirectDraw2 methods ***/ +#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c)) +/*** IDirectDraw4 methods ***/ +#define IDirectDraw4_GetSurfaceFromDC(p,a,b) ICOM_CALL_(GetSurfaceFromDC,p,(p,a,b)) +#define IDirectDraw4_RestoreAllSurfaces(pc) ICOM_CALL_(RestoreAllSurfaces,p,(p)) +#define IDirectDraw4_TestCooperativeLevel(p) ICOM_CALL_(TestCooperativeLevel,p,(p)) +#define IDirectDraw4_GetDeviceIdentifier(p,a,b) ICOM_CALL_(GetDeviceIdentifier,p,(p,a,b)) + + +/***************************************************************************** + * IDirectDraw7 interface + */ +/* Note: IDirectDraw7 cannot derive from IDirectDraw4; it is even documented + * as not interchangeable with earlier DirectDraw interfaces. + */ +#undef INTERFACE +#define INTERFACE IDirectDraw7 +DECLARE_INTERFACE_(IDirectDraw7,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE7* lplpDDSurface, IUnknown* pUnkOuter) PURE; + STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurface, LPDIRECTDRAWSURFACE7* lplpDupDDSurface) PURE; + STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE7* lplpGDIDDSurface) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; + STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; + + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; + + STDMETHOD(GetSurfaceFromDC)(THIS_ HDC , LPDIRECTDRAWSURFACE7* ) PURE; + STDMETHOD(RestoreAllSurfaces)(THIS) PURE; + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER2 , DWORD ) PURE; + + STDMETHOD(StartModeTest)(THIS_ LPSIZE , DWORD , DWORD ) PURE; + STDMETHOD(EvaluateMode)(THIS_ DWORD , DWORD * ) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDraw7_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDraw7_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDraw7_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDraw methods ***/ +#define IDirectDraw7_Compact(p) ICOM_CALL_(Compact,p,(p)) +#define IDirectDraw7_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) +#define IDirectDraw7_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) +#define IDirectDraw7_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) +#define IDirectDraw7_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) +#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) +#define IDirectDraw7_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) +#define IDirectDraw7_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) +#define IDirectDraw7_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) +#define IDirectDraw7_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) +#define IDirectDraw7_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) +#define IDirectDraw7_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) +#define IDirectDraw7_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) +#define IDirectDraw7_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) +#define IDirectDraw7_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) +#define IDirectDraw7_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) +#define IDirectDraw7_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) +#define IDirectDraw7_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) +#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c,d,e)) +#define IDirectDraw7_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) +/*** added in IDirectDraw2 ***/ +#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c)) +/*** added in IDirectDraw4 ***/ +#define IDirectDraw7_GetSurfaceFromDC(p,a,b) ICOM_CALL_(GetSurfaceFromDC,p,(p,a,b)) +#define IDirectDraw7_RestoreAllSurfaces(p) ICOM_CALL_(RestoreAllSurfaces,p,(p)) +#define IDirectDraw7_TestCooperativeLevel(p) ICOM_CALL_(TestCooperativeLevel,p,(p)) +#define IDirectDraw7_GetDeviceIdentifier(p,a,b) ICOM_CALL_(GetDeviceIdentifier,p,(p,a,b)) +/*** added in IDirectDraw 7 ***/ +#define IDirectDraw7_StartModeTest(p,a,b,c) ICOM_CALL_(StartModeTest,p,(p,a,b,c)) +#define IDirectDraw7_EvaluateMode(p,a,b) ICOM_CALL_(EvaluateMode,p,(p,a,b)) + + +/***************************************************************************** + * IDirectDrawSurface interface + */ +#undef INTERFACE +#define INTERFACE IDirectDrawSurface +DECLARE_INTERFACE_(IDirectDrawSurface,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; + STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; + STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawSurface_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawSurface_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawSurface_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDrawSurface methods ***/ +#define IDirectDrawSurface_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) +#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) +#define IDirectDrawSurface_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) +#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) +#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) +#define IDirectDrawSurface_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) +#define IDirectDrawSurface_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) +#define IDirectDrawSurface_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) +#define IDirectDrawSurface_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) +#define IDirectDrawSurface_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) +#define IDirectDrawSurface_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) +#define IDirectDrawSurface_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) +#define IDirectDrawSurface_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) +#define IDirectDrawSurface_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) +#define IDirectDrawSurface_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) +#define IDirectDrawSurface_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) +#define IDirectDrawSurface_IsLost(p) ICOM_CALL_(IsLost,p,(p)) +#define IDirectDrawSurface_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) +#define IDirectDrawSurface_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) +#define IDirectDrawSurface_Restore(p) ICOM_CALL_(Restore,p,(p)) +#define IDirectDrawSurface_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) +#define IDirectDrawSurface_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) +#define IDirectDrawSurface_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) +#define IDirectDrawSurface_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) +#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) +#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) + + +/***************************************************************************** + * IDirectDrawSurface2 interface + */ +/* Cannot inherit from IDirectDrawSurface because the LPDIRECTDRAWSURFACE parameters + * have been converted to LPDIRECTDRAWSURFACE2. + */ +#undef INTERFACE +#define INTERFACE IDirectDrawSurface2 +DECLARE_INTERFACE_(IDirectDrawSurface2,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; + STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; + STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE2* lplpDDAttachedSurface) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE2 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSReference) PURE; + /* added in v2 */ + STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; + STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawSurface2_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawSurface2_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawSurface2_Release(p) ICOM_CALL_(Release,p,(p)) +/*** IDirectDrawSurface methods (almost) ***/ +#define IDirectDrawSurface2_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) +#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) +#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface2_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) +#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) +#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) +#define IDirectDrawSurface2_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) +#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface2_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) +#define IDirectDrawSurface2_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) +#define IDirectDrawSurface2_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) +#define IDirectDrawSurface2_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) +#define IDirectDrawSurface2_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) +#define IDirectDrawSurface2_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) +#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface2_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) +#define IDirectDrawSurface2_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) +#define IDirectDrawSurface2_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) +#define IDirectDrawSurface2_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) +#define IDirectDrawSurface2_IsLost(p) ICOM_CALL_(IsLost,p,(p)) +#define IDirectDrawSurface2_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) +#define IDirectDrawSurface2_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) +#define IDirectDrawSurface2_Restore(p) ICOM_CALL_(Restore,p,(p)) +#define IDirectDrawSurface2_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) +#define IDirectDrawSurface2_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) +#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface2_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) +#define IDirectDrawSurface2_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) +#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) +#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface2_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) +#define IDirectDrawSurface2_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) +#define IDirectDrawSurface2_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) + + +/***************************************************************************** + * IDirectDrawSurface3 interface + */ +/* Cannot inherit from IDirectDrawSurface2 because the LPDIRECTDRAWSURFACE2 parameters + * have been converted to LPDIRECTDRAWSURFACE3. + */ +#undef INTERFACE +#define INTERFACE IDirectDrawSurface3 +DECLARE_INTERFACE_(IDirectDrawSurface3,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; + STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; + STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE3* lplpDDAttachedSurface) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE3 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSReference) PURE; + /* added in v2 */ + STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; + STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; + /* added in v3 */ + STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSD, DWORD dwFlags) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawSurface3_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawSurface3_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawSurface3_Release(p) ICOM_CALL_(Release,p,(p)) +/*** IDirectDrawSurface methods (almost) ***/ +#define IDirectDrawSurface3_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) +#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) +#define IDirectDrawSurface3_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface3_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) +#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) +#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) +#define IDirectDrawSurface3_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) +#define IDirectDrawSurface3_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface3_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) +#define IDirectDrawSurface3_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) +#define IDirectDrawSurface3_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) +#define IDirectDrawSurface3_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) +#define IDirectDrawSurface3_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) +#define IDirectDrawSurface3_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) +#define IDirectDrawSurface3_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface3_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) +#define IDirectDrawSurface3_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) +#define IDirectDrawSurface3_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) +#define IDirectDrawSurface3_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) +#define IDirectDrawSurface3_IsLost(p) ICOM_CALL_(IsLost,p,(p)) +#define IDirectDrawSurface3_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) +#define IDirectDrawSurface3_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) +#define IDirectDrawSurface3_Restore(p) ICOM_CALL_(Restore,p,(p)) +#define IDirectDrawSurface3_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) +#define IDirectDrawSurface3_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) +#define IDirectDrawSurface3_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface3_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) +#define IDirectDrawSurface3_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) +#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) +#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface3_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) +#define IDirectDrawSurface3_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) +#define IDirectDrawSurface3_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) +/*** IDirectDrawSurface3 methods ***/ +#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) ICOM_CALL_(SetSurfaceDesc,p,(p,a,b)) + + +/***************************************************************************** + * IDirectDrawSurface4 interface + */ +/* Cannot inherit from IDirectDrawSurface2 because DDSCAPS changed to DDSCAPS2. + */ +#undef INTERFACE +#define INTERFACE IDirectDrawSurface4 +DECLARE_INTERFACE_(IDirectDrawSurface4,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; + STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; + STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE4* lplpDDAttachedSurface) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; + STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSReference) PURE; + /* added in v2 */ + STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; + STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; + /* added in v3 */ + STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSD, DWORD dwFlags) PURE; + /* added in v4 */ + STDMETHOD(SetPrivateData)(THIS_ REFGUID , LPVOID , DWORD , DWORD ) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID , LPVOID , LPDWORD ) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID ) PURE; + STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD ) PURE; + STDMETHOD(ChangeUniquenessValue)(THIS) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawSurface4_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawSurface4_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawSurface4_Release(p) ICOM_CALL_(Release,p,(p)) +/*** IDirectDrawSurface (almost) methods ***/ +#define IDirectDrawSurface4_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) +#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) +#define IDirectDrawSurface4_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface4_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) +#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) +#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) +#define IDirectDrawSurface4_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) +#define IDirectDrawSurface4_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface4_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) +#define IDirectDrawSurface4_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) +#define IDirectDrawSurface4_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) +#define IDirectDrawSurface4_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) +#define IDirectDrawSurface4_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) +#define IDirectDrawSurface4_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) +#define IDirectDrawSurface4_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface4_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) +#define IDirectDrawSurface4_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) +#define IDirectDrawSurface4_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) +#define IDirectDrawSurface4_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) +#define IDirectDrawSurface4_IsLost(p) ICOM_CALL_(IsLost,p,(p)) +#define IDirectDrawSurface4_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) +#define IDirectDrawSurface4_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) +#define IDirectDrawSurface4_Restore(p) ICOM_CALL_(Restore,p,(p)) +#define IDirectDrawSurface4_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) +#define IDirectDrawSurface4_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) +#define IDirectDrawSurface4_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface4_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) +#define IDirectDrawSurface4_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) +#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) +#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface4_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) +#define IDirectDrawSurface4_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) +#define IDirectDrawSurface4_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) +/*** IDirectDrawSurface3 methods ***/ +#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) ICOM_CALL_(SetSurfaceDesc,p,(p,a,b)) +/*** IDirectDrawSurface4 methods ***/ +#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) ICOM_CALL_(SetPrivateData,p,(p,a,b,c,d)) +#define IDirectDrawSurface4_GetPrivateData(p,a,b,c) ICOM_CALL_(GetPrivateData,p,(p,a,b,c)) +#define IDirectDrawSurface4_FreePrivateData(p,a) ICOM_CALL_(FreePrivateData,p,(p,a)) +#define IDirectDrawSurface4_GetUniquenessValue(p,a) ICOM_CALL_(GetUniquenessValue,p,(p,a)) +#define IDirectDrawSurface4_ChangeUniquenessValue(p) ICOM_CALL_(ChangeUniquenessValue,p,(p)) + + +/***************************************************************************** + * IDirectDrawSurface7 interface + */ +#undef INTERFACE +#define INTERFACE IDirectDrawSurface7 +DECLARE_INTERFACE_(IDirectDrawSurface7,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; + STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; + STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE; + STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpfnCallback) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE7* lplpDDAttachedSurface) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; + STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE7 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSReference) PURE; + /* added in v2 */ + STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; + STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; + /* added in v3 */ + STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags) PURE; + /* added in v4 */ + STDMETHOD(SetPrivateData)(THIS_ REFGUID , LPVOID , DWORD , DWORD ) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID , LPVOID , LPDWORD ) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID ) PURE; + STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD ) PURE; + STDMETHOD(ChangeUniquenessValue)(THIS) PURE; + /* added in v7 */ + STDMETHOD(SetPriority)(THIS_ DWORD prio) PURE; + STDMETHOD(GetPriority)(THIS_ LPDWORD prio) PURE; + STDMETHOD(SetLOD)(THIS_ DWORD lod) PURE; + STDMETHOD(GetLOD)(THIS_ LPDWORD lod) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawSurface7_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawSurface7_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawSurface7_Release(p) ICOM_CALL_(Release,p,(p)) +/*** IDirectDrawSurface (almost) methods ***/ +#define IDirectDrawSurface7_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) +#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) +#define IDirectDrawSurface7_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface7_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) +#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) +#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) +#define IDirectDrawSurface7_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) +#define IDirectDrawSurface7_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) +#define IDirectDrawSurface7_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) +#define IDirectDrawSurface7_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) +#define IDirectDrawSurface7_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) +#define IDirectDrawSurface7_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) +#define IDirectDrawSurface7_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) +#define IDirectDrawSurface7_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) +#define IDirectDrawSurface7_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface7_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) +#define IDirectDrawSurface7_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) +#define IDirectDrawSurface7_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) +#define IDirectDrawSurface7_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) +#define IDirectDrawSurface7_IsLost(p) ICOM_CALL_(IsLost,p,(p)) +#define IDirectDrawSurface7_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) +#define IDirectDrawSurface7_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) +#define IDirectDrawSurface7_Restore(p) ICOM_CALL_(Restore,p,(p)) +#define IDirectDrawSurface7_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) +#define IDirectDrawSurface7_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) +#define IDirectDrawSurface7_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) +#define IDirectDrawSurface7_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) +#define IDirectDrawSurface7_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) +#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) +#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) +#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) +/*** IDirectDrawSurface2 methods ***/ +#define IDirectDrawSurface7_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) +#define IDirectDrawSurface7_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) +#define IDirectDrawSurface7_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) +/*** IDirectDrawSurface3 methods ***/ +#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) ICOM_CALL_(SetSurfaceDesc,p,(p,a,b)) +/*** IDirectDrawSurface4 methods ***/ +#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) ICOM_CALL_(SetPrivateData,p,(p,a,b,c,d)) +#define IDirectDrawSurface7_GetPrivateData(p,a,b,c) ICOM_CALL_(GetPrivateData,p,(p,a,b,c)) +#define IDirectDrawSurface7_FreePrivateData(p,a) ICOM_CALL_(FreePrivateData,p,(p,a)) +#define IDirectDrawSurface7_GetUniquenessValue(p,a) ICOM_CALL_(GetUniquenessValue,p,(p,a)) +#define IDirectDrawSurface7_ChangeUniquenessValue(p) ICOM_CALL_(ChangeUniquenessValue,p,(p)) +/*** IDirectDrawSurface7 methods ***/ +#define IDirectDrawSurface7_SetPriority(p,a) ICOM_CALL_(SetPriority,p,(p,a)) +#define IDirectDrawSurface7_GetPriority(p,a) ICOM_CALL_(GetPriority,p,(p,a)) +#define IDirectDrawSurface7_SetLOD(p,a) ICOM_CALL_(SetLOD,p,(p,a)) +#define IDirectDrawSurface7_GetLOD(p,a) ICOM_CALL_(GetLOD,p,(p,a)) + +/***************************************************************************** + * IDirectDrawColorControl interface + */ +#undef INTERFACE +#define INTERFACE IDirectDrawColorControl +DECLARE_INTERFACE_(IDirectDrawColorControl,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE; + STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawColorControl_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawColorControl_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawColorControl_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDrawColorControl methods ***/ +#define IDirectDrawColorControl_GetColorControls(p,a) ICOM_CALL_(GetColorControls,p,(p,a)) +#define IDirectDrawColorControl_SetColorControls(p,a) ICOM_CALL_(SetColorControls,p,(p,a)) + +/***************************************************************************** + * IDirectDrawGammaControl interface + */ +#undef INTERFACE +#define INTERFACE IDirectDrawGammaControl +DECLARE_INTERFACE_(IDirectDrawGammaControl,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(GetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE; + STDMETHOD(SetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE; +}; + + /*** IUnknown methods ***/ +#define IDirectDrawGammaControl_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) +#define IDirectDrawGammaControl_AddRef(p) ICOM_CALL_(AddRef,p,(p)) +#define IDirectDrawGammaControl_Release(p) ICOM_CALL_(Release,p,(p)) + /*** IDirectDrawGammaControl methods ***/ +#define IDirectDrawGammaControl_GetGammaRamp(p,a,b) ICOM_CALL_(GetGammaRamp,p,(p,a,b)) +#define IDirectDrawGammaControl_SetGammaRamp(p,a,b) ICOM_CALL_(SetGammaRamp,p,(p,a,b)) + + +HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN); +HRESULT WINAPI DirectDrawCreateEx(LPGUID,LPVOID*,REFIID,LPUNKNOWN); +HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA,LPVOID); +HRESULT WINAPI DirectDrawEnumerateW(LPDDENUMCALLBACKW,LPVOID); +#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate) +HRESULT WINAPI DirectDrawCreateClipper(DWORD,LPDIRECTDRAWCLIPPER*,LPUNKNOWN); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* __XWIN_DDRAW_H */ diff --git a/hw/xwin/win.h b/hw/xwin/win.h new file mode 100644 index 000000000..3ab324931 --- /dev/null +++ b/hw/xwin/win.h @@ -0,0 +1,1453 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * Kensuke Matsuzaki + */ + +#ifndef _WIN_H_ +#define _WIN_H_ + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +/* Turn debug messages on or off */ +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif + +/* WM_XBUTTON Messages. They should go into w32api. */ +#ifndef WM_XBUTTONDOWN +# define WM_XBUTTONDOWN 523 +#endif +#ifndef WM_XBUTTONUP +# define WM_XBUTTONUP 524 +#endif +#ifndef WM_XBUTTONDBLCLK +# define WM_XBUTTONDBLCLK 525 +#endif + +#define NEED_EVENTS + +#define WIN_DEFAULT_BPP 0 +#define WIN_DEFAULT_WHITEPIXEL 255 +#define WIN_DEFAULT_BLACKPIXEL 0 +#define WIN_DEFAULT_LINEBIAS 0 +#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */ +#define WIN_DEFAULT_DPI 75 +#define WIN_DEFAULT_REFRESH 0 +#define WIN_DEFAULT_WIN_KILL TRUE +#define WIN_DEFAULT_UNIX_KILL FALSE +#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0 +#ifdef XWIN_EMULATEPSEUDO +#define WIN_DEFAULT_EMULATE_PSEUDO FALSE +#endif +#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE + +#define WIN_DIB_MAXIMUM_SIZE 0x08000000 /* 16 MB on Windows 95, 98, Me */ +#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024) + +/* + * Windows only supports 256 color palettes + */ +#define WIN_NUM_PALETTE_ENTRIES 256 + +/* + * Number of times to call Restore in an attempt to restore the primary surface + */ +#define WIN_REGAIN_SURFACE_RETRIES 1 + +/* + * Build a supported display depths mask by shifting one to the left + * by the number of bits in the supported depth. + */ +#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \ + | (1 << (16 - 1)) | (1 << (15 - 1)) \ + | (1 << ( 8 - 1))) +#define WIN_CHECK_DEPTH YES + +/* + * Timer IDs for WM_TIMER + */ +#define WIN_E3B_TIMER_ID 1 +#define WIN_POLLING_MOUSE_TIMER_ID 2 + + +#define WIN_E3B_OFF -1 +#define WIN_FD_INVALID -1 + +#define WIN_SERVER_NONE 0x0L /* 0 */ +#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */ +#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */ +#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */ +#ifdef XWIN_PRIMARYFB +#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */ +#endif +#ifdef XWIN_NATIVEGDI +# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */ +#endif + +#define AltMapIndex Mod1MapIndex +#define NumLockMapIndex Mod2MapIndex +#define AltLangMapIndex Mod3MapIndex +#define KanaMapIndex Mod4MapIndex +#define ScrollLockMapIndex Mod5MapIndex + +#define WIN_MOD_LALT 0x00000001 +#define WIN_MOD_RALT 0x00000002 +#define WIN_MOD_LCONTROL 0x00000004 +#define WIN_MOD_RCONTROL 0x00000008 + +#define WIN_24BPP_MASK_RED 0x00FF0000 +#define WIN_24BPP_MASK_GREEN 0x0000FF00 +#define WIN_24BPP_MASK_BLUE 0x000000FF + +#define WIN_MAX_KEYS_PER_KEY 4 + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> + +#include <errno.h> +#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) +#define HANDLE void * +#include <pthread.h> +#undef HANDLE +#endif + +#ifdef HAS_MMAP +#include <sys/mman.h> +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif /* MAP_FILE */ +#endif /* HAS_MMAP */ + +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/Xos.h> +#include <X11/Xprotostr.h> +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "pixmap.h" +#include "region.h" +#include "gcstruct.h" +#include "colormap.h" +#include "colormapst.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "mi.h" +#include "micmap.h" +#include "mifillarc.h" +#include "mifpoly.h" +#include "mibstore.h" +#include "input.h" +#include "mipointer.h" +#include "X11/keysym.h" +#include "mibstore.h" +#include "micoord.h" +#include "dix.h" +#include "miline.h" +#include "shadow.h" +#include "fb.h" +#include "rootless.h" + +#ifdef RENDER +#include "mipict.h" +#include "picturestr.h" +#endif + +#ifdef RANDR +#include "randrstr.h" +#endif + +/* + * Windows headers + */ +#include "winms.h" +#include "./winresource.h" + + +/* + * Define Windows constants + */ + +#define WM_TRAYICON (WM_USER + 1000) +#define WM_INIT_SYS_MENU (WM_USER + 1001) +#define WM_GIVEUP (WM_USER + 1002) + + +/* Local includes */ +#include "winwindow.h" +#include "winmsg.h" + + +/* + * Debugging macros + */ + +#if CYGDEBUG +#define DEBUG_MSG(str,...) \ +if (fDebugProcMsg) \ +{ \ + char *pszTemp; \ + int iLength; \ + pszTemp = Xprintf (str, ##__VA_ARGS__); \ + MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \ + xfree (pszTemp); \ +} +#else +#define DEBUG_MSG(str,...) +#endif + +#if CYGDEBUG +#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str +#else +#define DEBUG_FN_NAME(str) +#endif + +#if CYGDEBUG || YES +#define DEBUGVARS BOOL fDebugProcMsg = FALSE +#else +#define DEBUGVARS +#endif + +#if CYGDEBUG || YES +#define DEBUGPROC_MSG fDebugProcMsg = TRUE +#else +#define DEBUGPROC_MSG +#endif + +#define PROFILEPOINT(point,thresh)\ +{\ +static unsigned int PROFPT##point = 0;\ +if (++PROFPT##point % thresh == 0)\ +ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\ +} + + +/* We use xor this macro for detecting toggle key state changes */ +#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b))) + +#define DEFINE_ATOM_HELPER(func,atom_name) \ +static Atom func (void) { \ + static int generation; \ + static Atom atom; \ + if (generation != serverGeneration) { \ + generation = serverGeneration; \ + atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \ + } \ + return atom; \ +} + +/* + * Typedefs for engine dependent function pointers + */ + +typedef Bool (*winAllocateFBProcPtr)(ScreenPtr); + +typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr); + +typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr); + +typedef Bool (*winInitVisualsProcPtr)(ScreenPtr); + +typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr); + +typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr); + +typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **); + +typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr); + +typedef Bool (*winActivateAppProcPtr)(ScreenPtr); + +typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap, + int ndef, xColorItem *pdefs); + +typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr); + +typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin); + + +/* Typedef for DIX wrapper functions */ +typedef int (*winDispatchProcPtr) (ClientPtr); + + +/* + * GC (graphics context) privates + */ + +typedef struct +{ + HDC hdc; + HDC hdcMem; +} winPrivGCRec, *winPrivGCPtr; + + +/* + * Pixmap privates + */ + +typedef struct +{ + HDC hdcSelected; + HBITMAP hBitmap; + BYTE *pbBits; + DWORD dwScanlineBytes; + BITMAPINFOHEADER *pbmih; +} winPrivPixmapRec, *winPrivPixmapPtr; + + +/* + * Colormap privates + */ + +typedef struct +{ + HPALETTE hPalette; + LPDIRECTDRAWPALETTE lpDDPalette; + RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; + PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES]; +} winPrivCmapRec, *winPrivCmapPtr; + +/* + * Windows Cursor handling. + */ + +typedef struct { + /* from GetSystemMetrics */ + int sm_cx; + int sm_cy; + + BOOL visible; + HCURSOR handle; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} winCursorRec; + +/* + * Screen information structure that we need before privates are available + * in the server startup sequence. + */ + +typedef struct +{ + ScreenPtr pScreen; + + /* Did the user specify a height and width? */ + Bool fUserGaveHeightAndWidth; + + DWORD dwScreen; + DWORD dwUserWidth; + DWORD dwUserHeight; + DWORD dwWidth; + DWORD dwHeight; + DWORD dwWidth_mm; + DWORD dwHeight_mm; + DWORD dwPaddedWidth; + + /* Did the user specify a screen position? */ + Bool fUserGavePosition; + DWORD dwInitialX; + DWORD dwInitialY; + + /* + * dwStride is the number of whole pixels that occupy a scanline, + * including those pixels that are not displayed. This is basically + * a rounding up of the width. + */ + DWORD dwStride; + + /* Offset of the screen in the window when using scrollbars */ + DWORD dwXOffset; + DWORD dwYOffset; + + DWORD dwBPP; + DWORD dwDepth; + DWORD dwRefreshRate; + char *pfb; + DWORD dwEngine; + DWORD dwEnginePreferred; + DWORD dwClipUpdatesNBoxes; +#ifdef XWIN_EMULATEPSEUDO + Bool fEmulatePseudo; +#endif + Bool fFullScreen; + Bool fDecoration; +#ifdef XWIN_MULTIWINDOWEXTWM + Bool fMWExtWM; + Bool fInternalWM; + Bool fAnotherWMRunning; +#endif + Bool fRootless; +#ifdef XWIN_MULTIWINDOW + Bool fMultiWindow; +#endif +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + Bool fMultiMonitorOverride; +#endif + Bool fMultipleMonitors; + Bool fLessPointer; + Bool fScrollbars; + Bool fNoTrayIcon; + int iE3BTimeout; + /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */ + Bool fUseWinKillKey; + Bool fUseUnixKillKey; + Bool fIgnoreInput; + + /* Did the user explicitly set this screen? */ + Bool fExplicitScreen; +} winScreenInfo, *winScreenInfoPtr; + + +/* + * Screen privates + */ + +typedef struct _winPrivScreenRec +{ + winScreenInfoPtr pScreenInfo; + + Bool fEnabled; + Bool fClosed; + Bool fActive; + Bool fBadDepth; + + int iDeltaZ; + + int iConnectedClients; + + CloseScreenProcPtr CloseScreen; + + DWORD dwRedMask; + DWORD dwGreenMask; + DWORD dwBlueMask; + DWORD dwBitsPerRGB; + + DWORD dwModeKeyStates; + + /* Handle to icons that must be freed */ + HICON hiconNotifyIcon; + + /* Last width, height, and depth of the Windows display */ + DWORD dwLastWindowsWidth; + DWORD dwLastWindowsHeight; + DWORD dwLastWindowsBitsPixel; + + /* Palette management */ + ColormapPtr pcmapInstalled; + + /* Pointer to the root visual so we only have to look it up once */ + VisualPtr pRootVisual; + + /* 3 button emulation variables */ + int iE3BCachedPress; + Bool fE3BFakeButton2Sent; + + /* Privates used by shadow fb GDI server */ + HBITMAP hbmpShadow; + HDC hdcScreen; + HDC hdcShadow; + HWND hwndScreen; + + /* Privates used by shadow fb and primary fb DirectDraw servers */ + LPDIRECTDRAW pdd; + LPDIRECTDRAWSURFACE2 pddsPrimary; + LPDIRECTDRAW2 pdd2; + + /* Privates used by shadow fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsShadow; + LPDDSURFACEDESC pddsdShadow; + + /* Privates used by primary fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsOffscreen; + LPDDSURFACEDESC pddsdOffscreen; + LPDDSURFACEDESC pddsdPrimary; + + /* Privates used by shadow fb DirectDraw Nonlocking server */ + LPDIRECTDRAW4 pdd4; + LPDIRECTDRAWSURFACE4 pddsShadow4; + LPDIRECTDRAWSURFACE4 pddsPrimary4; + BOOL fRetryCreateSurface; + + /* Privates used by both shadow fb DirectDraw servers */ + LPDIRECTDRAWCLIPPER pddcPrimary; + +#ifdef XWIN_MULTIWINDOWEXTWM + /* Privates used by multi-window external window manager */ + RootlessFrameID widTop; + Bool fRestacking; +#endif + +#ifdef XWIN_MULTIWINDOW + /* Privates used by multi-window */ + pthread_t ptWMProc; + pthread_t ptXMsgProc; + void *pWMInfo; +#endif + +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + /* Privates used by both multi-window and rootless */ + Bool fRootWindowShown; +#endif + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Privates used for any module running in a seperate thread */ + pthread_mutex_t pmServerStarted; + Bool fServerStarted; +#endif + + /* Engine specific functions */ + winAllocateFBProcPtr pwinAllocateFB; + winShadowUpdateProcPtr pwinShadowUpdate; + winCloseScreenProcPtr pwinCloseScreen; + winInitVisualsProcPtr pwinInitVisuals; + winAdjustVideoModeProcPtr pwinAdjustVideoMode; + winCreateBoundingWindowProcPtr pwinCreateBoundingWindow; + winFinishScreenInitProcPtr pwinFinishScreenInit; + winBltExposedRegionsProcPtr pwinBltExposedRegions; + winActivateAppProcPtr pwinActivateApp; + winRedrawScreenProcPtr pwinRedrawScreen; + winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette; + winInstallColormapProcPtr pwinInstallColormap; + winStoreColorsProcPtr pwinStoreColors; + winCreateColormapProcPtr pwinCreateColormap; + winDestroyColormapProcPtr pwinDestroyColormap; + winHotKeyAltTabProcPtr pwinHotKeyAltTab; + winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface; + winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface; + +#ifdef XWIN_MULTIWINDOW + /* Window Procedures for MultiWindow mode */ + winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow; +#endif + + /* Window Procedures for Rootless mode */ + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + PositionWindowProcPtr PositionWindow; + ChangeWindowAttributesProcPtr ChangeWindowAttributes; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + ValidateTreeProcPtr ValidateTree; + PostValidateTreeProcPtr PostValidateTree; + WindowExposuresProcPtr WindowExposures; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + ClipNotifyProcPtr ClipNotify; + RestackWindowProcPtr RestackWindow; + ReparentWindowProcPtr ReparentWindow; + ResizeWindowProcPtr ResizeWindow; + MoveWindowProcPtr MoveWindow; +#ifdef SHAPE + SetShapeProcPtr SetShape; +#endif + + winCursorRec cursor; +} winPrivScreenRec; + + +#ifdef XWIN_MULTIWINDOWEXTWM +typedef struct { + RootlessWindowPtr pFrame; + HWND hWnd; + int dwWidthBytes; + BITMAPINFOHEADER *pbmihShadow; + HBITMAP hbmpShadow; + HDC hdcShadow; + HDC hdcScreen; + BOOL fResized; + BOOL fRestackingNow; + BOOL fClose; + BOOL fMovingOrSizing; + BOOL fDestroyed;//for debug + char *pfb; +} win32RootlessWindowRec, *win32RootlessWindowPtr; +#endif + + +typedef struct { + pointer value; + XID id; +} WindowIDPairRec, *WindowIDPairPtr; + + +/* + * Extern declares for general global variables + */ + +extern winScreenInfo g_ScreenInfo[]; +extern miPointerScreenFuncRec g_winPointerCursorFuncs; +extern DWORD g_dwEvents; +#ifdef HAS_DEVWINDOWS +extern int g_fdMessageQueue; +#endif +extern DevPrivateKey g_iScreenPrivateKey; +extern DevPrivateKey g_iCmapPrivateKey; +extern DevPrivateKey g_iGCPrivateKey; +extern DevPrivateKey g_iPixmapPrivateKey; +extern DevPrivateKey g_iWindowPrivateKey; +extern unsigned long g_ulServerGeneration; +extern CARD32 g_c32LastInputEventTime; +extern DWORD g_dwEnginesSupported; +extern HINSTANCE g_hInstance; +extern int g_copyROP[]; +extern int g_patternROP[]; +extern const char * g_pszQueryHost; + + +/* + * Extern declares for dynamically loaded libraries and function pointers + */ + +extern HMODULE g_hmodDirectDraw; +extern FARPROC g_fpDirectDrawCreate; +extern FARPROC g_fpDirectDrawCreateClipper; + +extern HMODULE g_hmodCommonControls; +extern FARPROC g_fpTrackMouseEvent; + + +/* + * Screen privates macros + */ + +#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey)) + +#define winSetScreenPriv(pScreen,v) \ + dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v) + +#define winScreenPriv(pScreen) \ + winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen) + + +/* + * Colormap privates macros + */ + +#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \ + dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey)) + +#define winSetCmapPriv(pCmap,v) \ + dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v) + +#define winCmapPriv(pCmap) \ + winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap) + + +/* + * GC privates macros + */ + +#define winGetGCPriv(pGC) ((winPrivGCPtr) \ + dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey)) + +#define winSetGCPriv(pGC,v) \ + dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v) + +#define winGCPriv(pGC) \ + winPrivGCPtr pGCPriv = winGetGCPriv(pGC) + + +/* + * Pixmap privates macros + */ + +#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \ + dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey)) + +#define winSetPixmapPriv(pPixmap,v) \ + dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v) + +#define winPixmapPriv(pPixmap) \ + winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap) + + +/* + * Window privates macros + */ + +#define winGetWindowPriv(pWin) ((winPrivWinPtr) \ + dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey)) + +#define winSetWindowPriv(pWin,v) \ + dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v) + +#define winWindowPriv(pWin) \ + winPrivWinPtr pWinPriv = winGetWindowPriv(pWin) + +/* + * wrapper macros + */ +#define _WIN_WRAP(priv, real, mem, func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define _WIN_UNWRAP(priv, real, mem) {\ + real->mem = priv->mem; \ +} + +#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func) + +#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem) + +/* + * BEGIN DDX and DIX Function Prototypes + */ + + +/* + * winallpriv.c + */ + +Bool +winAllocatePrivates (ScreenPtr pScreen); + +Bool +winInitCmapPrivates (ColormapPtr pCmap, int index); + +Bool +winAllocateCmapPrivates (ColormapPtr pCmap); + + +/* + * winauth.c + */ + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) +# if defined(XCSECURITY) +Bool +winGenerateAuthorization (void); +# endif +#endif + + +/* + * winblock.c + */ + +void +winBlockHandler (int nScreen, + pointer pBlockData, + pointer pTimeout, + pointer pReadMask); + + +#ifdef XWIN_NATIVEGDI +/* + * winclip.c + */ + +RegionPtr +winPixmapToRegionNativeGDI (PixmapPtr pPix); +#endif + + +#ifdef XWIN_CLIPBOARD +/* + * winclipboardinit.c + */ + +Bool +winInitClipboard (void); + +void +winFixClipboardChain (void); +#endif + + +/* + * wincmap.c + */ + +void +winSetColormapFunctions (ScreenPtr pScreen); + +Bool +winCreateDefColormap (ScreenPtr pScreen); + + +/* + * wincreatewnd.c + */ + +Bool +winCreateBoundingWindowFullScreen (ScreenPtr pScreen); + +Bool +winCreateBoundingWindowWindowed (ScreenPtr pScreen); + + +/* + * windialogs.c + */ + +void +winDisplayExitDialog (winPrivScreenPtr pScreenPriv); + +void +winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv); + +void +winDisplayAboutDialog (winPrivScreenPtr pScreenPriv); + + +/* + * winengine.c + */ + +void +winDetectSupportedEngines (void); + +Bool +winSetEngine (ScreenPtr pScreen); + +Bool +winGetDDProcAddresses (void); + + +/* + * winerror.c + */ + +#ifdef DDXOSVERRORF +void +OSVenderVErrorF (const char *pszFormat, va_list va_args); +#endif + +void +winMessageBoxF (const char *pszError, UINT uType, ...); + + +#ifdef XWIN_NATIVEGDI +/* + * winfillsp.c + */ + +void +winFillSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int nSpans, + DDXPointPtr pPoints, + int *pWidths, + int fSorted); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winfont.c + */ + +Bool +winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); + +Bool +winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * wingc.c + */ + +Bool +winCreateGCNativeGDI (GCPtr pGC); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * wingetsp.c + */ + +void +winGetSpansNativeGDI (DrawablePtr pDrawable, + int wMax, + DDXPointPtr pPoints, + int *pWidths, + int nSpans, + char *pDst); +#endif + + +/* + * winglobals.c + */ + +void +winInitializeGlobals (void); + + +/* + * winkeybd.c + */ + +void +winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode); + +int +winKeybdProc (DeviceIntPtr pDeviceInt, int iState); + +void +winInitializeModeKeyStates (void); + +void +winRestoreModeKeyStates (void); + +Bool +winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam); + +void +winKeybdReleaseKeys (void); + +void +winSendKeyEvent (DWORD dwKey, Bool fDown); + + +/* + * winkeyhook.c + */ + +Bool +winInstallKeyboardHookLL (void); + +void +winRemoveKeyboardHookLL (void); + + +/* + * winmisc.c + */ + +#ifdef XWIN_NATIVEGDI +void +winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen); +#endif + +CARD8 +winCountBits (DWORD dw); + +Bool +winUpdateFBPointer (ScreenPtr pScreen, void *pbits); + +#ifdef XWIN_NATIVEGDI +BOOL +winPaintBackground (HWND hwnd, COLORREF colorref); +#endif + + +/* + * winmouse.c + */ + +int +winMouseProc (DeviceIntPtr pDeviceInt, int iState); + +int +winMouseWheel (ScreenPtr pScreen, int iDeltaZ); + +void +winMouseButtonsSendEvent (int iEventType, int iButton); + +int +winMouseButtonsHandle (ScreenPtr pScreen, + int iEventType, int iButton, + WPARAM wParam); + +#ifdef XWIN_NATIVEGDI +/* + * winnativegdi.c + */ + +HBITMAP +winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, + BYTE **ppbBits, BITMAPINFO **ppbmi); + +Bool +winSetEngineFunctionsNativeGDI (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_PRIMARYFB +/* + * winpfbddd.c + */ + +Bool +winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winpixmap.c + */ + +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth, + unsigned usage_hint); + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap); + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData); +#endif + +#ifdef XWIN_NATIVEGDI +/* + * winpolyline.c + */ + +void +winPolyLineNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winpushpxl.c + */ + +void +winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, + int dx, int dy, int xOrg, int yOrg); +#endif + + +/* + * winscrinit.c + */ + +Bool +winScreenInit (int index, + ScreenPtr pScreen, + int argc, char **argv); + +Bool +winFinishScreenInitFB (int index, + ScreenPtr pScreen, + int argc, char **argv); + +#if defined(XWIN_NATIVEGDI) +Bool +winFinishScreenInitNativeGDI (int index, + ScreenPtr pScreen, + int argc, char **argv); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winsetsp.c + */ + +void +winSetSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + char *pSrc, + DDXPointPtr pPoints, + int *pWidth, + int nSpans, + int fSorted); +#endif + + +/* + * winshaddd.c + */ + +Bool +winSetEngineFunctionsShadowDD (ScreenPtr pScreen); + + +/* + * winshadddnl.c + */ + +Bool +winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen); + + +/* + * winshadgdi.c + */ + +Bool +winSetEngineFunctionsShadowGDI (ScreenPtr pScreen); + + +/* + * winwakeup.c + */ + +void +winWakeupHandler (int nScreen, + pointer pWakeupData, + unsigned long ulResult, + pointer pReadmask); + + +/* + * winwindow.c + */ + +#ifdef XWIN_NATIVEGDI +Bool +winCreateWindowNativeGDI (WindowPtr pWin); + +Bool +winDestroyWindowNativeGDI (WindowPtr pWin); + +Bool +winPositionWindowNativeGDI (WindowPtr pWin, int x, int y); + +void +winCopyWindowNativeGDI (WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +Bool +winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask); + +Bool +winUnmapWindowNativeGDI (WindowPtr pWindow); + +Bool +winMapWindowNativeGDI (WindowPtr pWindow); +#endif + +Bool +winCreateWindowRootless (WindowPtr pWindow); + +Bool +winDestroyWindowRootless (WindowPtr pWindow); + +Bool +winPositionWindowRootless (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowRootless (WindowPtr pWindow); + +Bool +winMapWindowRootless (WindowPtr pWindow); + +#ifdef SHAPE +void +winSetShapeRootless (WindowPtr pWindow); +#endif + + +/* + * winmultiwindowicons.c - Used by both multi-window and Win32Rootless + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize); + + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowshape.c + */ + +# ifdef SHAPE +void +winReshapeMultiWindow (WindowPtr pWin); + +void +winSetShapeMultiWindow (WindowPtr pWindow); + +void +winUpdateRgnMultiWindow (WindowPtr pWindow); +# endif +#endif + + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowwindow.c + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWindow); + +Bool +winDestroyWindowMultiWindow (WindowPtr pWindow); + +Bool +winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowMultiWindow (WindowPtr pWindow); + +Bool +winMapWindowMultiWindow (WindowPtr pWindow); + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent); + +void +winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib); + +void +winReorderWindowsMultiWindow (void); + +void +winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib); +void +winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, + WindowPtr pSib, VTKind kind); + +void +winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, + RegionPtr oldRegion); + +XID +winGetWindowID (WindowPtr pWin); + +int +winAdjustXWindow (WindowPtr pWin, HWND hwnd); +#endif + + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowwndproc.c + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +#endif + + +/* + * wintrayicon.c + */ + +void +winInitNotifyIcon (winPrivScreenPtr pScreenPriv); + +void +winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv); + +LRESULT +winHandleIconMessage (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam, + winPrivScreenPtr pScreenPriv); + + +/* + * winwndproc.c + */ + +LRESULT CALLBACK +winWindowProc (HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootless.c + */ + +Bool +winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape); + +void +winMWExtWMDestroyFrame (RootlessFrameID wid); + +void +winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); + +void +winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity); + +void +winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid); + +void +winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape); + +void +winMWExtWMUnmapFrame (RootlessFrameID wid); + +void +winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow); + +void +winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush); + +void +winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage); + +void +winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects, + int shift_x, int shift_y); + +void +winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin); + +void +winMWExtWMCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes); + +void +winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value, + void *dst, unsigned int dstRowBytes); + +int +winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function, + void *src[2], unsigned int srcRowBytes[2], + void *mask, unsigned int maskRowBytes, + void *dst[2], unsigned int dstRowBytes[2]); + +void +winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy); +#endif + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootlesswindow.c + */ + +void +winMWExtWMReorderWindows (ScreenPtr pScreen); + +void +winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y); + +void +winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h); + +void +winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h); + +void +winMWExtWMUpdateIcon (Window id); + +void +winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, + winScreenInfoPtr pScreenInfo); + +wBOOL CALLBACK +winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam); + +Bool +winIsInternalWMRunning (winScreenInfoPtr pScreenInfo); + +void +winMWExtWMRestackWindows (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootlesswndproc.c + */ + +LRESULT CALLBACK +winMWExtWMWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +#endif + + +/* + * winwindowswm.c + */ + +void +winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, + Window window, int x, int y, int w, int h); + +void +winWindowsWMExtensionInit (void); + +/* + * wincursor.c + */ + +Bool +winInitCursor (ScreenPtr pScreen); + +/* + * END DDX and DIX Function Prototypes + */ + +#endif /* _WIN_H_ */ + diff --git a/hw/xwin/winallpriv.c b/hw/xwin/winallpriv.c new file mode 100644 index 000000000..21ccd9b3b --- /dev/null +++ b/hw/xwin/winallpriv.c @@ -0,0 +1,172 @@ +/* + *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: Keith Packard, MIT X Consortium + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + + +/* See Porting Layer Definition - p. 58 */ +/* + * Allocate indexes for the privates that we use. + * Allocate memory directly for the screen privates. + * Reserve space in GCs and Pixmaps for our privates. + * Colormap privates are handled in winAllocateCmapPrivates () + */ + +Bool +winAllocatePrivates (ScreenPtr pScreen) +{ + winPrivScreenPtr pScreenPriv; + +#if CYGDEBUG + winDebug ("winAllocateScreenPrivates - g_ulServerGeneration: %d " + "serverGeneration: %d\n", + g_ulServerGeneration, serverGeneration); +#endif + + /* We need a new slot for our privates if the screen gen has changed */ + if (g_ulServerGeneration != serverGeneration) + { + g_ulServerGeneration = serverGeneration; + } + + /* Allocate memory for the screen private structure */ + pScreenPriv = (winPrivScreenPtr) malloc (sizeof (winPrivScreenRec)); + if (!pScreenPriv) + { + ErrorF ("winAllocateScreenPrivates - malloc () failed\n"); + return FALSE; + } + + /* Initialize the memory of the private structure */ + ZeroMemory (pScreenPriv, sizeof (winPrivScreenRec)); + + /* Intialize private structure members */ + pScreenPriv->fActive = TRUE; + + /* Save the screen private pointer */ + winSetScreenPriv (pScreen, pScreenPriv); + + /* Reserve GC memory for our privates */ + if (!dixRequestPrivate(g_iGCPrivateKey, sizeof (winPrivGCRec))) + { + ErrorF ("winAllocatePrivates - AllocateGCPrivate () failed\n"); + return FALSE; + } + + /* Reserve Pixmap memory for our privates */ + if (!dixRequestPrivate(g_iPixmapPrivateKey, sizeof (winPrivPixmapRec))) + { + ErrorF ("winAllocatePrivates - AllocatePixmapPrivates () failed\n"); + return FALSE; + } + + /* Reserve Window memory for our privates */ + if (!dixRequestPrivate(g_iWindowPrivateKey, sizeof (winPrivWinRec))) + { + ErrorF ("winAllocatePrivates () - AllocateWindowPrivates () failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap privates may be allocated after the default colormap has + * already been created for some screens. This initialization procedure + * is called for each default colormap that is found. + */ + +Bool +winInitCmapPrivates (ColormapPtr pcmap, int index) +{ +#if CYGDEBUG + winDebug ("winInitCmapPrivates\n"); +#endif + + /* + * I see no way that this function can do anything useful + * with only a ColormapPtr. We don't have the index for + * our dev privates yet, so we can't really initialize + * anything. Perhaps I am misunderstanding the purpose + * of this function. + */ + /* That's definitely true. + * I therefore changed the API and added the index as argument. + */ + return TRUE; +} + + +/* + * Allocate memory for our colormap privates + */ + +Bool +winAllocateCmapPrivates (ColormapPtr pCmap) +{ + winPrivCmapPtr pCmapPriv; + static unsigned long s_ulPrivateGeneration = 0; + +#if CYGDEBUG + winDebug ("winAllocateCmapPrivates\n"); +#endif + + /* Get a new privates index when the server generation changes */ + if (s_ulPrivateGeneration != serverGeneration) + { + /* Save the new server generation */ + s_ulPrivateGeneration = serverGeneration; + } + + /* Allocate memory for our private structure */ + pCmapPriv = (winPrivCmapPtr) malloc (sizeof (winPrivCmapRec)); + if (!pCmapPriv) + { + ErrorF ("winAllocateCmapPrivates - malloc () failed\n"); + return FALSE; + } + + /* Initialize the memory of the private structure */ + ZeroMemory (pCmapPriv, sizeof (winPrivCmapRec)); + + /* Save the cmap private pointer */ + winSetCmapPriv (pCmap, pCmapPriv); + +#if CYGDEBUG + winDebug ("winAllocateCmapPrivates - Returning\n"); +#endif + + return TRUE; +} diff --git a/hw/xwin/winauth.c b/hw/xwin/winauth.c new file mode 100644 index 000000000..b57a35abf --- /dev/null +++ b/hw/xwin/winauth.c @@ -0,0 +1,131 @@ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#if defined(XCSECURITY) +/* + *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 + */ + +#include "win.h" + +/* Includes for authorization */ +#include <X11/Xauth.h> +#include "securitysrv.h" +#include <X11/extensions/securstr.h> + + +/* + * Constants + */ + +#define AUTH_NAME "MIT-MAGIC-COOKIE-1" + + +/* + * Globals + */ + +XID g_authId = 0; +unsigned int g_uiAuthDataLen = 0; +char *g_pAuthData = NULL; + + +/* + * Generate authorization cookie for internal server clients + */ + +Bool +winGenerateAuthorization () +{ + Bool fFreeAuth = FALSE; + SecurityAuthorizationPtr pAuth = NULL; + + /* Call OS layer to generate authorization key */ + g_authId = GenerateAuthorization (strlen (AUTH_NAME), + AUTH_NAME, + 0, + NULL, + &g_uiAuthDataLen, + &g_pAuthData); + if ((XID) ~0L == g_authId) + { + ErrorF ("winGenerateAuthorization - GenerateAuthorization failed\n"); + goto auth_bailout; + } +#if 0 + else + { + ErrorF ("winGenerateAuthorization - GenerateAuthorization success!\n" + "AuthDataLen: %d AuthData: %s\n", + g_uiAuthDataLen, g_pAuthData); + } +#endif + + /* Allocate structure for additional auth information */ + pAuth = (SecurityAuthorizationPtr) + xalloc (sizeof (SecurityAuthorizationRec)); + if (!(pAuth)) + { + ErrorF ("winGenerateAuthorization - Failed allocating " + "SecurityAuthorizationPtr.\n"); + goto auth_bailout; + } + + /* Fill in the auth fields */ + pAuth->id = g_authId; + pAuth->timeout = 0; /* live for x seconds after refcnt == 0 */ + pAuth->group = None; + pAuth->trustLevel = XSecurityClientTrusted; + pAuth->refcnt = 1; /* this auth must stick around */ + pAuth->secondsRemaining = 0; + pAuth->timer = NULL; + pAuth->eventClients = NULL; + + /* Add the authorization to the server's auth list */ + if (!AddResource (g_authId, + SecurityAuthorizationResType, + pAuth)) + { + ErrorF ("winGenerateAuthorization - AddResource failed for auth.\n"); + fFreeAuth = TRUE; + goto auth_bailout; + } + + /* Don't free the auth data, since it is still used internally */ + pAuth = NULL; + + return TRUE; + + auth_bailout: + if (fFreeAuth) + xfree (pAuth); + + return FALSE; +} +#endif diff --git a/hw/xwin/winblock.c b/hw/xwin/winblock.c new file mode 100644 index 000000000..abea60e0f --- /dev/null +++ b/hw/xwin/winblock.c @@ -0,0 +1,106 @@ +/* + *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 <xwin-config.h> +#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); + } + } +} diff --git a/hw/xwin/winclip.c b/hw/xwin/winclip.c new file mode 100644 index 000000000..aab7d632d --- /dev/null +++ b/hw/xwin/winclip.c @@ -0,0 +1,42 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + +/* Look at mfb/mfbclip.c for sample implementation */ +RegionPtr +winPixmapToRegionNativeGDI (PixmapPtr pPix) +{ + ErrorF ("winPixmapToRegion()\n"); + return NULL; +} diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h new file mode 100644 index 000000000..445c01b27 --- /dev/null +++ b/hw/xwin/winclipboard.h @@ -0,0 +1,164 @@ +#ifndef _WINCLIPBOARD_H_ +#define _WINCLIPBOARD_H_ +/* + *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 + */ + +/* Standard library headers */ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef __CYGWIN__ +#include <sys/select.h> +#else +#include "Xwinsock.h" +#define HAS_WINSOCK +#endif +#include <fcntl.h> +#include <setjmp.h> +#include <pthread.h> + +/* X headers */ +#include <X11/X.h> +#include <X11/Xatom.h> +/* NOTE: For some unknown reason, including Xproto.h solves + * tons of problems with including windows.h. Unknowns reasons + * are usually bad, so someone should investigate this. + */ +#include <X11/Xproto.h> +#include "X11/Xutil.h" +#include "X11/Xlocale.h" + +/* Fixups to prevent collisions between Windows and X headers */ +#define ATOM DWORD + +#ifndef __CYGWIN__ +#define sleep(x) Sleep (1000 * (x)) +#endif + +/* Windows headers */ +#ifndef XFree86Server +#define XFree86Server +#endif +#include <windows.h> +#undef XFree86Server + + +/* Clipboard module constants */ +#define WIN_CLIPBOARD_WINDOW_CLASS "xwinclip" +#define WIN_CLIPBOARD_WINDOW_TITLE "xwinclip" +#ifdef HAS_DEVWINDOWS +# define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif +#define WIN_CONNECT_RETRIES 40 +#define WIN_CONNECT_DELAY 4 +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 +#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER" +#define WIN_XEVENTS_SUCCESS 0 +#define WIN_XEVENTS_SHUTDOWN 1 +#define WIN_XEVENTS_CONVERT 2 +#define WIN_XEVENTS_NOTIFY 3 + +#define WM_WM_REINIT (WM_USER + 1) + +/* + * References to external symbols + */ + +extern char *display; +extern void ErrorF (const char* /*f*/, ...); +extern void winDebug (const char *format, ...); +extern void winErrorFVerb (int verb, const char *format, ...); + + +/* + * winclipboardinit.c + */ + +Bool +winInitClipboard (void); + +HWND +winClipboardCreateMessagingWindow (void); + + +/* + * winclipboardtextconv.c + */ + +void +winClipboardDOStoUNIX (char *pszData, int iLength); + +void +winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength); + + +/* + * winclipboardthread.c + */ + +void * +winClipboardProc (void *); + +void +winDeinitClipboard (void); + + +/* + * winclipboardunicode.c + */ + +Bool +winClipboardDetectUnicodeSupport (void); + + +/* + * winclipboardwndproc.c + */ + +BOOL +winClipboardFlushWindowsMessageQueue (HWND hwnd); + +LRESULT CALLBACK +winClipboardWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +/* + * winclipboardxevents.c + */ + +int +winClipboardFlushXEvents (HWND hwnd, + int iWindow, + Display *pDisplay, + Bool fUnicodeSupport); +#endif diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c new file mode 100644 index 000000000..6a0cbaf2c --- /dev/null +++ b/hw/xwin/winclipboardinit.c @@ -0,0 +1,143 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "dixstruct.h" +#include "winclipboard.h" + + +/* + * Local typedefs + */ + +typedef int (*winDispatchProcPtr) (ClientPtr); + +DISPATCH_PROC(winProcSetSelectionOwner); + + +/* + * References to external symbols + */ + +extern pthread_t g_ptClipboardProc; +extern winDispatchProcPtr winProcSetSelectionOwnerOrig; +extern Bool g_fClipboard; +extern HWND g_hwndClipboard; + + +/* + * Intialize the Clipboard module + */ + +Bool +winInitClipboard () +{ + ErrorF ("winInitClipboard ()\n"); + + /* Wrap some internal server functions */ + if (ProcVector[X_SetSelectionOwner] != winProcSetSelectionOwner) + { + winProcSetSelectionOwnerOrig = ProcVector[X_SetSelectionOwner]; + ProcVector[X_SetSelectionOwner] = winProcSetSelectionOwner; + } + + /* Spawn a thread for the Clipboard module */ + if (pthread_create (&g_ptClipboardProc, + NULL, + winClipboardProc, + NULL)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitClipboard - pthread_create failed.\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Create the Windows window that we use to recieve Windows messages + */ + +HWND +winClipboardCreateMessagingWindow () +{ + WNDCLASS wc; + HWND hwnd; + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winClipboardWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle (NULL); + wc.hIcon = 0; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WIN_CLIPBOARD_WINDOW_CLASS; + RegisterClass (&wc); + + /* Create the window */ + hwnd = CreateWindowExA (0, /* Extended styles */ + WIN_CLIPBOARD_WINDOW_CLASS,/* Class name */ + WIN_CLIPBOARD_WINDOW_TITLE,/* Window name */ + WS_OVERLAPPED, /* Not visible anyway */ + CW_USEDEFAULT, /* Horizontal position */ + CW_USEDEFAULT, /* Vertical position */ + CW_USEDEFAULT, /* Right edge */ + CW_USEDEFAULT, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL),/* Instance handle */ + NULL); /* Creation data */ + assert (hwnd != NULL); + + /* I'm not sure, but we may need to call this to start message processing */ + ShowWindow (hwnd, SW_HIDE); + + /* Similarly, we may need a call to this even though we don't paint */ + UpdateWindow (hwnd); + + return hwnd; +} + +void +winFixClipboardChain (void) +{ + if (g_fClipboard + && g_hwndClipboard) + { + PostMessage (g_hwndClipboard, WM_WM_REINIT, 0, 0); + } +} diff --git a/hw/xwin/winclipboardtextconv.c b/hw/xwin/winclipboardtextconv.c new file mode 100644 index 000000000..fd2e696c3 --- /dev/null +++ b/hw/xwin/winclipboardtextconv.c @@ -0,0 +1,159 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <stdio.h> +#include <stdlib.h> + +void +winClipboardDOStoUNIX (char *pszSrc, int iLength); +void +winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength); + +/* + * Convert \r\n to \n + * + * NOTE: This was heavily inspired by, Cygwin's + * winsup/cygwin/fhandler.cc/fhandler_base::read () + */ + +void +winClipboardDOStoUNIX (char *pszSrc, int iLength) +{ + char *pszDest = pszSrc; + char *pszEnd = pszSrc + iLength; + + /* Loop until the last character */ + while (pszSrc < pszEnd) + { + /* Copy the current source character to current destination character */ + *pszDest = *pszSrc; + + /* Advance to the next source character */ + pszSrc++; + + /* Don't advance the destination character if we need to drop an \r */ + if (*pszDest != '\r' || *pszSrc != '\n') + pszDest++; + } + + /* Move the terminating null */ + *pszDest = '\0'; +} + + +/* + * Convert \n to \r\n + */ + +void +winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength) +{ + int iNewlineCount = 0; + unsigned char *pszSrc = *ppszData; + unsigned char *pszEnd = pszSrc + iLength; + unsigned char *pszDest = NULL, *pszDestBegin = NULL; + +#if 0 + ErrorF ("UNIXtoDOS () - Original data:\n%s\n", *ppszData); +#endif + + /* Count \n characters without leading \r */ + while (pszSrc < pszEnd) + { + /* Skip ahead two character if found set of \r\n */ + if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') + { + pszSrc += 2; + continue; + } + + /* Increment the count if found naked \n */ + if (*pszSrc == '\n') + { + iNewlineCount++; + } + + pszSrc++; + } + + /* Return if no naked \n's */ + if (iNewlineCount == 0) + return; + + /* Allocate a new string */ + pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1); + + /* Set source pointer to beginning of data string */ + pszSrc = *ppszData; + + /* Loop through all characters in source string */ + while (pszSrc < pszEnd) + { + /* Copy line endings that are already valid */ + if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') + { + *pszDest = *pszSrc; + *(pszDest + 1) = *(pszSrc + 1); + pszDest += 2; + pszSrc += 2; + continue; + } + + /* Add \r to naked \n's */ + if (*pszSrc == '\n') + { + *pszDest = '\r'; + *(pszDest + 1) = *pszSrc; + pszDest += 2; + pszSrc += 1; + continue; + } + + /* Copy normal characters */ + *pszDest = *pszSrc; + pszSrc++; + pszDest++; + } + + /* Put terminating null at end of new string */ + *pszDest = '\0'; + + /* Swap string pointers */ + free (*ppszData); + *ppszData = pszDestBegin; + +#if 0 + ErrorF ("UNIXtoDOS () - Final string:\n%s\n", pszDestBegin); +#endif +} diff --git a/hw/xwin/winclipboardthread.c b/hw/xwin/winclipboardthread.c new file mode 100644 index 000000000..081abd5e7 --- /dev/null +++ b/hw/xwin/winclipboardthread.c @@ -0,0 +1,477 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <sys/types.h> +#include "winclipboard.h" +#ifdef __CYGWIN__ +#include <errno.h> +#endif +#include "X11/Xauth.h" + + +/* + * Constants + */ + +#define AUTH_NAME "MIT-MAGIC-COOKIE-1" + + +/* + * References to external symbols + */ + +extern Bool g_fUnicodeClipboard; +extern unsigned long serverGeneration; +#if defined(XCSECURITY) +extern unsigned int g_uiAuthDataLen; +extern char *g_pAuthData; +#endif +extern Bool g_fClipboardStarted; +extern HWND g_hwndClipboard; +extern void *g_pClipboardDisplay; +extern Window g_iClipboardWindow; + + +/* + * Global variables + */ + +static jmp_buf g_jmpEntry; +Bool g_fUnicodeSupport = FALSE; +Bool g_fUseUnicode = FALSE; + + +/* + * Local function prototypes + */ + +static int +winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winClipboardIOErrorHandler (Display *pDisplay); + + +/* + * Main thread function + */ + +void * +winClipboardProc (void *pvNotUsed) +{ + Atom atomClipboard, atomClipboardManager; + int iReturn; + HWND hwnd = NULL; + int iConnectionNumber = 0; +#ifdef HAS_DEVWINDOWS + int fdMessageQueue = 0; +#else + struct timeval tvTimeout; +#endif + fd_set fdsRead; + int iMaxDescriptor; + Display *pDisplay = NULL; + Window iWindow = None; + int iRetries; + Bool fUseUnicode; + char szDisplay[512]; + int iSelectError; + + ErrorF ("winClipboardProc - Hello\n"); + + /* Do we have Unicode support? */ + g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); + + /* Do we use Unicode clipboard? */ + fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport; + + /* Save the Unicode support flag in a global */ + g_fUseUnicode = fUseUnicode; + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winClipboardProc - XInitThreads failed.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winClipboardProc - Locale not supported by X. Exiting.\n"); + pthread_exit (NULL); + } + + /* Set jump point for Error exits */ + iReturn = setjmp (g_jmpEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winClipboardProc - setjmp returned: %d exiting\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + /* TODO: Cleanup the Win32 window and free any allocated memory */ + ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n"); + pthread_exit (NULL); + } + +#if defined(XCSECURITY) + /* Use our generated cookie for authentication */ + XSetAuthorization (AUTH_NAME, + strlen (AUTH_NAME), + g_pAuthData, + g_uiAuthDataLen); +#endif + + /* Set error handler */ + XSetErrorHandler (winClipboardErrorHandler); + XSetIOErrorHandler (winClipboardIOErrorHandler); + + /* Initialize retry count */ + iRetries = 0; + + /* Setup the display connection string x */ + /* + * NOTE: Always connect to screen 0 since we require that screen + * numbers start at 0 and increase without gaps. We only need + * to connect to one screen on the display to get events + * for all screens on the display. That is why there is only + * one clipboard client thread. + */ + snprintf (szDisplay, + 512, + "127.0.0.1:%s.0", + display); + + /* Print the display connection string */ + ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay); + + /* Open the X display */ + do + { + pDisplay = XOpenDisplay (szDisplay); + if (pDisplay == NULL) + { + ErrorF ("winClipboardProc - Could not open display, " + "try: %d, sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pDisplay == NULL) + { + ErrorF ("winClipboardProc - Failed opening the display, giving up\n"); + pthread_exit (NULL); + } + + /* Save the display in the screen privates */ + g_pClipboardDisplay = pDisplay; + + ErrorF ("winClipboardProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Get our connection number */ + iConnectionNumber = ConnectionNumber (pDisplay); + +#ifdef HAS_DEVWINDOWS + /* Open a file descriptor for the windows message queue */ + fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY); + if (fdMessageQueue == -1) + { + ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); + pthread_exit (NULL); + } + + /* Find max of our file descriptors */ + iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1; +#else + iMaxDescriptor = iConnectionNumber + 1; +#endif + + /* Select event types to watch */ + if (XSelectInput (pDisplay, + DefaultRootWindow (pDisplay), + SubstructureNotifyMask | + StructureNotifyMask | + PropertyChangeMask) == BadWindow) + ErrorF ("winClipboardProc - XSelectInput generated BadWindow " + "on RootWindow\n\n"); + + /* Create atoms */ + atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False); + atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False); + + /* Create a messaging window */ + iWindow = XCreateSimpleWindow (pDisplay, + DefaultRootWindow (pDisplay), + 1, 1, + 500, 500, + 0, + BlackPixel (pDisplay, 0), + BlackPixel (pDisplay, 0)); + if (iWindow == 0) + { + ErrorF ("winClipboardProc - Could not create an X window.\n"); + pthread_exit (NULL); + } + + /* Save the window in the screen privates */ + g_iClipboardWindow = iWindow; + + /* Create Windows messaging window */ + hwnd = winClipboardCreateMessagingWindow (); + + /* Save copy of HWND in screen privates */ + g_hwndClipboard = hwnd; + + /* Assert ownership of selections if Win32 clipboard is owned */ + if (NULL != GetClipboardOwner ()) + { + /* PRIMARY */ + iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); + pthread_exit (NULL); + } + + /* CLIPBOARD */ + iReturn = XSetSelectionOwner (pDisplay, atomClipboard, + iWindow, CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); + pthread_exit (NULL); + } + } + + /* Pre-flush X events */ + /* + * NOTE: Apparently you'll freeze if you don't do this, + * because there may be events in local data structures + * already. + */ + winClipboardFlushXEvents (hwnd, + iWindow, + pDisplay, + fUseUnicode); + + /* Pre-flush Windows messages */ + if (!winClipboardFlushWindowsMessageQueue (hwnd)) + return 0; + + /* Signal that the clipboard client has started */ + g_fClipboardStarted = TRUE; + + /* Loop for X events */ + while (1) + { + /* Setup the file descriptor set */ + /* + * NOTE: You have to do this before every call to select + * because select modifies the mask to indicate + * which descriptors are ready. + */ + FD_ZERO (&fdsRead); + FD_SET (iConnectionNumber, &fdsRead); +#ifdef HAS_DEVWINDOWS + FD_SET (fdMessageQueue, &fdsRead); +#else + tvTimeout.tv_sec = 0; + tvTimeout.tv_usec = 100; +#endif + + /* Wait for a Windows event or an X event */ + iReturn = select (iMaxDescriptor, /* Highest fds number */ + &fdsRead, /* Read mask */ + NULL, /* No write mask */ + NULL, /* No exception mask */ +#ifdef HAS_DEVWINDOWS + NULL /* No timeout */ +#else + &tvTimeout /* Set timeout */ +#endif + ); + +#ifndef HAS_WINSOCK + iSelectError = errno; +#else + iSelectError = WSAGetLastError(); +#endif + + if (iReturn < 0) + { +#ifndef HAS_WINSOCK + if (iSelectError == EINTR) +#else + if (iSelectError == WSAEINTR) +#endif + continue; + + ErrorF ("winClipboardProc - Call to select () failed: %d. " + "Bailing.\n", iReturn); + break; + } + + /* Branch on which descriptor became active */ + if (FD_ISSET (iConnectionNumber, &fdsRead)) + { + /* Process X events */ + /* Exit when we see that server is shutting down */ + iReturn = winClipboardFlushXEvents (hwnd, + iWindow, + pDisplay, + fUseUnicode); + if (WIN_XEVENTS_SHUTDOWN == iReturn) + { + ErrorF ("winClipboardProc - winClipboardFlushXEvents " + "trapped shutdown event, exiting main loop.\n"); + break; + } + } + +#ifdef HAS_DEVWINDOWS + /* Check for Windows event ready */ + if (FD_ISSET (fdMessageQueue, &fdsRead)) +#else + if (1) +#endif + { + /* Process Windows messages */ + if (!winClipboardFlushWindowsMessageQueue (hwnd)) + { + ErrorF ("winClipboardProc - " + "winClipboardFlushWindowsMessageQueue trapped " + "WM_QUIT message, exiting main loop.\n"); + break; + } + } + } + + /* Close our X window */ + if (pDisplay && iWindow) + { + iReturn = XDestroyWindow (pDisplay, iWindow); + if (iReturn == BadWindow) + ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n"); + else + ErrorF ("winClipboardProc - XDestroyWindow succeeded.\n"); + } + + +#ifdef HAS_DEVWINDOWS + /* Close our Win32 message handle */ + if (fdMessageQueue) + close (fdMessageQueue); +#endif + +#if 0 + /* + * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The + * XSync and XSelectInput calls did not help. + */ + + /* Discard any remaining events */ + XSync (pDisplay, TRUE); + + /* Select event types to watch */ + XSelectInput (pDisplay, + DefaultRootWindow (pDisplay), + None); + + /* Close our X display */ + if (pDisplay) + { + XCloseDisplay (pDisplay); + } +#endif + + g_iClipboardWindow = None; + g_pClipboardDisplay = NULL; + g_hwndClipboard = NULL; + + return NULL; +} + + +/* + * winClipboardErrorHandler - Our application specific error handler + */ + +static int +winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n" + "\tSerial: %d, Request Code: %d, Minor Code: %d\n", + pszErrorMsg, + pErr->serial, + pErr->request_code, + pErr->minor_code); + return 0; +} + + +/* + * winClipboardIOErrorHandler - Our application specific IO error handler + */ + +static int +winClipboardIOErrorHandler (Display *pDisplay) +{ + ErrorF ("\nwinClipboardIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); + + return 0; +} diff --git a/hw/xwin/winclipboardunicode.c b/hw/xwin/winclipboardunicode.c new file mode 100644 index 000000000..ba86915a4 --- /dev/null +++ b/hw/xwin/winclipboardunicode.c @@ -0,0 +1,69 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "winclipboard.h" + + +/* + * Determine whether we suport Unicode or not. + * NOTE: Currently, just check if we are on an NT-based platform or not. + */ + +Bool +winClipboardDetectUnicodeSupport (void) +{ + Bool fReturn = FALSE; + 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: + /* Unicode supported on NT only */ + ErrorF ("DetectUnicodeSupport - Windows NT/2000/XP\n"); + fReturn = TRUE; + break; + + case VER_PLATFORM_WIN32_WINDOWS: + /* Unicode is not supported on non-NT */ + ErrorF ("DetectUnicodeSupport - Windows 95/98/Me\n"); + fReturn = FALSE; + break; + } + + return fReturn; +} diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c new file mode 100644 index 000000000..802a74035 --- /dev/null +++ b/hw/xwin/winclipboardwndproc.c @@ -0,0 +1,622 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <sys/types.h> +#include <sys/time.h> +#include "winclipboard.h" + +extern void winFixClipboardChain(); + + +/* + * Constants + */ + +#define WIN_CLIPBOARD_PROP "cyg_clipboard_prop" +#define WIN_POLL_TIMEOUT 1 + + +/* + * References to external symbols + */ + +extern Bool g_fUseUnicode; +extern Bool g_fUnicodeSupport; +extern void *g_pClipboardDisplay; +extern Window g_iClipboardWindow; +extern Atom g_atomLastOwnedSelection; + +/* BPS - g_hwndClipboard needed for X app->Windows paste fix */ +extern HWND g_hwndClipboard; + +/* + * Local function prototypes + */ + +static Bool +winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, + Bool fUseUnicode, int iTimeoutSec); + + +/* + * Process X events up to specified timeout + */ + +static int +winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, + Bool fUseUnicode, int iTimeoutSec) +{ + int iConnNumber; + struct timeval tv; + int iReturn; + DWORD dwStopTime = (GetTickCount () / 1000) + iTimeoutSec; + + /* We need to ensure that all pending events are processed */ + XSync (pDisplay, FALSE); + + /* Get our connection number */ + iConnNumber = ConnectionNumber (pDisplay); + + /* Loop for X events */ + while (1) + { + fd_set fdsRead; + + /* Setup the file descriptor set */ + FD_ZERO (&fdsRead); + FD_SET (iConnNumber, &fdsRead); + + /* Adjust timeout */ + tv.tv_sec = dwStopTime - (GetTickCount () / 1000); + tv.tv_usec = 0; + + /* Break out if no time left */ + if (tv.tv_sec < 0) + return WIN_XEVENTS_SUCCESS; + + /* Wait for a Windows event or an X event */ + iReturn = select (iConnNumber + 1,/* Highest fds number */ + &fdsRead, /* Read mask */ + NULL, /* No write mask */ + NULL, /* No exception mask */ + &tv); /* No timeout */ + if (iReturn <= 0) + { + ErrorF ("winProcessXEventsTimeout - Call to select () failed: %d. " + "Bailing.\n", iReturn); + break; + } + + /* Branch on which descriptor became active */ + if (FD_ISSET (iConnNumber, &fdsRead)) + { + /* Process X events */ + /* Exit when we see that server is shutting down */ + iReturn = winClipboardFlushXEvents (hwnd, + iWindow, + pDisplay, + fUseUnicode); + if (WIN_XEVENTS_NOTIFY == iReturn + || WIN_XEVENTS_CONVERT == iReturn) + { + /* Bail out if convert or notify processed */ + return iReturn; + } + } + } + + return WIN_XEVENTS_SUCCESS; +} + + +/* + * Process a given Windows message + */ + +/* BPS - Define our own message, which we'll post to ourselves to facilitate + * resetting the delayed rendering mechanism after each paste from X app to + * Windows app. TODO - Perhaps move to win.h with the other WM_USER messages. + */ +#define WM_USER_PASTE_COMPLETE (WM_USER + 1003) + +LRESULT CALLBACK +winClipboardWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static HWND s_hwndNextViewer; + static Bool s_fCBCInitialized; + + /* Branch on message type */ + switch (message) + { + case WM_DESTROY: + { + winDebug ("winClipboardWindowProc - WM_DESTROY\n"); + + /* Remove ourselves from the clipboard chain */ + ChangeClipboardChain (hwnd, s_hwndNextViewer); + + s_hwndNextViewer = NULL; + + PostQuitMessage (0); + } + return 0; + + + case WM_CREATE: + { + HWND first, next; + DWORD error_code = 0; + winDebug ("winClipboardWindowProc - WM_CREATE\n"); + + first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ + if (first == hwnd) return 0; /* Make sure it's not us! */ + /* Add ourselves to the clipboard viewer chain */ + next = SetClipboardViewer (hwnd); + error_code = GetLastError(); + if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */ + s_hwndNextViewer = next; /* it returned must have been the first window in the chain */ + else + s_fCBCInitialized = FALSE; + } + return 0; + + + case WM_CHANGECBCHAIN: + { + winDebug ("winClipboardWindowProc - WM_CHANGECBCHAIN: wParam(%x) " + "lParam(%x) s_hwndNextViewer(%x)\n", + wParam, lParam, s_hwndNextViewer); + + if ((HWND) wParam == s_hwndNextViewer) + { + s_hwndNextViewer = (HWND) lParam; + if (s_hwndNextViewer == hwnd) + { + s_hwndNextViewer = NULL; + winErrorFVerb (1, "winClipboardWindowProc - WM_CHANGECBCHAIN: " + "attempted to set next window to ourselves."); + } + } + else if (s_hwndNextViewer) + SendMessage (s_hwndNextViewer, message, + wParam, lParam); + + } + winDebug ("winClipboardWindowProc - WM_CHANGECBCHAIN: Exit\n"); + return 0; + + case WM_WM_REINIT: + { + /* Ensure that we're in the clipboard chain. Some apps, + * WinXP's remote desktop for one, don't play nice with the + * chain. This message is called whenever we receive a + * WM_ACTIVATEAPP message to ensure that we continue to + * receive clipboard messages. + * + * It might be possible to detect if we're still in the chain + * by calling SendMessage (GetClipboardViewer(), + * WM_DRAWCLIPBOARD, 0, 0); and then seeing if we get the + * WM_DRAWCLIPBOARD message. That, however, might be more + * expensive than just putting ourselves back into the chain. + */ + + HWND first, next; + DWORD error_code = 0; + winDebug ("winClipboardWindowProc - WM_WM_REINIT: Enter\n"); + + first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ + if (first == hwnd) return 0; /* Make sure it's not us! */ + winDebug (" WM_WM_REINIT: Replacing us(%x) with %x at head " + "of chain\n", hwnd, s_hwndNextViewer); + s_fCBCInitialized = FALSE; + ChangeClipboardChain (hwnd, s_hwndNextViewer); + s_hwndNextViewer = NULL; + s_fCBCInitialized = FALSE; + winDebug (" WM_WM_REINIT: Putting us back at head of chain.\n"); + first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ + if (first == hwnd) return 0; /* Make sure it's not us! */ + next = SetClipboardViewer (hwnd); + error_code = GetLastError(); + if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */ + s_hwndNextViewer = next; /* it returned must have been the first window in the chain */ + else + s_fCBCInitialized = FALSE; + } + winDebug ("winClipboardWindowProc - WM_WM_REINIT: Exit\n"); + return 0; + + + case WM_DRAWCLIPBOARD: + { + static Bool s_fProcessingDrawClipboard = FALSE; + Display *pDisplay = g_pClipboardDisplay; + Window iWindow = g_iClipboardWindow; + int iReturn; + + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n"); + + /* + * We've occasionally seen a loop in the clipboard chain. + * Try and fix it on the first hint of recursion. + */ + if (! s_fProcessingDrawClipboard) + { + s_fProcessingDrawClipboard = TRUE; + } + else + { + /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */ + s_fCBCInitialized = FALSE; + ChangeClipboardChain (hwnd, s_hwndNextViewer); + winFixClipboardChain(); + winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Nested calls detected. Re-initing.\n"); + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); + s_fProcessingDrawClipboard = FALSE; + return 0; + } + + /* Bail on first message */ + if (!s_fCBCInitialized) + { + s_fCBCInitialized = TRUE; + s_fProcessingDrawClipboard = FALSE; + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); + return 0; + } + + /* + * NOTE: We cannot bail out when NULL == GetClipboardOwner () + * because some applications deal with the clipboard in a manner + * that causes the clipboard owner to be NULL when they are in + * fact taking ownership. One example of this is the Win32 + * native compile of emacs. + */ + + /* Bail when we still own the clipboard */ + if (hwnd == GetClipboardOwner ()) + { + + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "We own the clipboard, returning.\n"); + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); + s_fProcessingDrawClipboard = FALSE; + if (s_hwndNextViewer) + SendMessage (s_hwndNextViewer, message, wParam, lParam); + return 0; + } + + /* + * Do not take ownership of the X11 selections when something + * other than CF_TEXT or CF_UNICODETEXT has been copied + * into the Win32 clipboard. + */ + if (!IsClipboardFormatAvailable (CF_TEXT) + && !IsClipboardFormatAvailable (CF_UNICODETEXT)) + { + + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Clipboard does not contain CF_TEXT nor " + "CF_UNICODETEXT.\n"); + + /* + * We need to make sure that the X Server has processed + * previous XSetSelectionOwner messages. + */ + XSync (pDisplay, FALSE); + + /* Release PRIMARY selection if owned */ + iReturn = XGetSelectionOwner (pDisplay, XA_PRIMARY); + if (iReturn == g_iClipboardWindow) + { + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "PRIMARY selection is owned by us.\n"); + XSetSelectionOwner (pDisplay, + XA_PRIMARY, + None, + CurrentTime); + } + else if (BadWindow == iReturn || BadAtom == iReturn) + winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "XGetSelection failed for PRIMARY: %d\n", iReturn); + + /* Release CLIPBOARD selection if owned */ + iReturn = XGetSelectionOwner (pDisplay, + XInternAtom (pDisplay, + "CLIPBOARD", + False)); + if (iReturn == g_iClipboardWindow) + { + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "CLIPBOARD selection is owned by us.\n"); + XSetSelectionOwner (pDisplay, + XInternAtom (pDisplay, + "CLIPBOARD", + False), + None, + CurrentTime); + } + else if (BadWindow == iReturn || BadAtom == iReturn) + winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "XGetSelection failed for CLIPBOARD: %d\n", iReturn); + + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); + s_fProcessingDrawClipboard = FALSE; + if (s_hwndNextViewer) + SendMessage (s_hwndNextViewer, message, wParam, lParam); + return 0; + } + + /* Reassert ownership of PRIMARY */ + iReturn = XSetSelectionOwner (pDisplay, + XA_PRIMARY, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Could not reassert ownership of PRIMARY\n"); + } + else + { + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Reasserted ownership of PRIMARY\n"); + } + + /* Reassert ownership of the CLIPBOARD */ + iReturn = XSetSelectionOwner (pDisplay, + XInternAtom (pDisplay, + "CLIPBOARD", + False), + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Could not reassert ownership of CLIPBOARD\n"); + } + else + { + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " + "Reasserted ownership of CLIPBOARD\n"); + } + + /* Flush the pending SetSelectionOwner event now */ + XFlush (pDisplay); + + s_fProcessingDrawClipboard = FALSE; + } + winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); + /* Pass the message on the next window in the clipboard viewer chain */ + if (s_hwndNextViewer) + SendMessage (s_hwndNextViewer, message, wParam, lParam); + return 0; + + + case WM_DESTROYCLIPBOARD: + /* + * NOTE: Intentionally do nothing. + * Changes in the Win32 clipboard are handled by WM_DRAWCLIPBOARD + * above. We only process this message to conform to the specs + * for delayed clipboard rendering in Win32. You might think + * that we need to release ownership of the X11 selections, but + * we do not, because a WM_DRAWCLIPBOARD message will closely + * follow this message and reassert ownership of the X11 + * selections, handling the issue for us. + */ + return 0; + + + case WM_RENDERFORMAT: + case WM_RENDERALLFORMATS: + { + int iReturn; + Display *pDisplay = g_pClipboardDisplay; + Window iWindow = g_iClipboardWindow; + Bool fConvertToUnicode; + + winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n"); + + /* Flag whether to convert to Unicode or not */ + if (message == WM_RENDERALLFORMATS) + fConvertToUnicode = FALSE; + else + fConvertToUnicode = g_fUnicodeSupport && (CF_UNICODETEXT == wParam); + + /* Request the selection contents */ + iReturn = XConvertSelection (pDisplay, + g_atomLastOwnedSelection, + XInternAtom (pDisplay, + "COMPOUND_TEXT", False), + XInternAtom (pDisplay, + "CYGX_CUT_BUFFER", False), + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMAT - " + "XConvertSelection () failed\n"); + break; + } + + /* Special handling for WM_RENDERALLFORMATS */ + if (message == WM_RENDERALLFORMATS) + { + /* We must open and empty the clipboard */ + + /* Close clipboard if we have it open already */ + if (GetOpenClipboardWindow () == hwnd) + { + CloseClipboard (); + } + + if (!OpenClipboard (hwnd)) + { + winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMATS - " + "OpenClipboard () failed: %08x\n", + GetLastError ()); + break; + } + + if (!EmptyClipboard ()) + { + winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMATS - " + "EmptyClipboard () failed: %08x\n", + GetLastError ()); + break; + } + } + + /* Process the SelectionNotify event */ + iReturn = winProcessXEventsTimeout (hwnd, + iWindow, + pDisplay, + fConvertToUnicode, + WIN_POLL_TIMEOUT); + if (WIN_XEVENTS_CONVERT == iReturn) + { + /* + * The selection was offered for conversion first, so we have + * to process a second SelectionNotify event to get the actual + * data in the selection. + */ + iReturn = winProcessXEventsTimeout (hwnd, + iWindow, + pDisplay, + fConvertToUnicode, + WIN_POLL_TIMEOUT); + } + + /* + * The last of the up-to two calls to winProcessXEventsTimeout + * from above had better have seen a notify event, or else we + * are dealing with a buggy or old X11 app. In these cases we + * have to paste some fake data to the Win32 clipboard to + * satisfy the requirement that we write something to it. + */ + if (WIN_XEVENTS_NOTIFY != iReturn) + { + /* Paste no data, to satisfy required call to SetClipboardData */ + if (g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + SetClipboardData (CF_TEXT, NULL); + } + + /* BPS - Post ourselves a user message whose handler will reset the + * delayed rendering mechanism after the paste is complete. This is + * necessary because calling SetClipboardData() with a NULL argument + * here will cause the data we just put on the clipboard to be lost! + */ + PostMessage(g_hwndClipboard, WM_USER_PASTE_COMPLETE, 0, 0); + + /* Special handling for WM_RENDERALLFORMATS */ + if (message == WM_RENDERALLFORMATS) + { + /* We must close the clipboard */ + + if (!CloseClipboard ()) + { + winErrorFVerb (1, "winClipboardWindowProc - WM_RENDERALLFORMATS - " + "CloseClipboard () failed: %08x\n", + GetLastError ()); + break; + } + } + + winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n"); + return 0; + } + /* BPS - This WM_USER message is posted by us. It gives us the opportunity + * to reset the delayed rendering mechanism after each and every paste + * from an X app to a Windows app. Without such a mechanism, subsequent + * changes of selection in the X app owning the selection are not + * reflected in pastes into Windows apps, since Windows won't send us the + * WM_RENDERFORMAT message unless someone has set changed data (or NULL) + * on the clipboard. */ + case WM_USER_PASTE_COMPLETE: + { + if (hwnd != GetClipboardOwner ()) + /* In case we've lost the selection since posting the message */ + return 0; + winDebug ("winClipboardWindowProc - WM_USER_PASTE_COMPLETE\n"); + + /* Set up for another delayed rendering callback */ + OpenClipboard (g_hwndClipboard); + + /* Take ownership of the Windows clipboard */ + EmptyClipboard (); + + /* Advertise Unicode if we support it */ + if (g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + + /* Always advertise regular text */ + SetClipboardData (CF_TEXT, NULL); + + /* Release the clipboard */ + CloseClipboard (); + } + return 0; + } + + /* Let Windows perform default processing for unhandled messages */ + return DefWindowProc (hwnd, message, wParam, lParam); +} + + +/* + * Process any pending Windows messages + */ + +BOOL +winClipboardFlushWindowsMessageQueue (HWND hwnd) +{ + MSG msg; + + /* Flush the messaging window queue */ + /* NOTE: Do not pass the hwnd of our messaging window to PeekMessage, + * as this will filter out many non-window-specific messages that + * are sent to our thread, such as WM_QUIT. + */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + /* Dispatch the message if not WM_QUIT */ + if (msg.message == WM_QUIT) + return FALSE; + else + DispatchMessage (&msg); + } + + return TRUE; +} diff --git a/hw/xwin/winclipboardwrappers.c b/hw/xwin/winclipboardwrappers.c new file mode 100755 index 000000000..2cfe0ffce --- /dev/null +++ b/hw/xwin/winclipboardwrappers.c @@ -0,0 +1,541 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixstruct.h" +#include <X11/Xatom.h> + + +/* + * Constants + */ + +#define CLIP_NUM_SELECTIONS 2 +#define CLIP_OWN_PRIMARY 0 +#define CLIP_OWN_CLIPBOARD 1 + + +/* + * Local function prototypes + */ + +DISPATCH_PROC(winProcEstablishConnection); +DISPATCH_PROC(winProcQueryTree); +DISPATCH_PROC(winProcSetSelectionOwner); + + +/* + * References to external symbols + */ + +extern Bool g_fUnicodeSupport; +extern int g_iNumScreens; +extern unsigned int g_uiAuthDataLen; +extern char *g_pAuthData; +extern Bool g_fXdmcpEnabled; +extern Bool g_fClipboardLaunched; +extern Bool g_fClipboardStarted; +extern Bool g_fClipboard; +extern Window g_iClipboardWindow; +extern Atom g_atomLastOwnedSelection; +extern HWND g_hwndClipboard; + +extern winDispatchProcPtr winProcEstablishConnectionOrig; +extern winDispatchProcPtr winProcQueryTreeOrig; +extern winDispatchProcPtr winProcSetSelectionOwnerOrig; + + +/* + * Wrapper for internal QueryTree function. + * Hides the clipboard client when it is the only client remaining. + */ + +int +winProcQueryTree (ClientPtr client) +{ + int iReturn; + + /* + * This procedure is only used for initialization. + * We can unwrap the original procedure at this point + * so that this function is no longer called until the + * server resets and the function is wrapped again. + */ + ProcVector[X_QueryTree] = winProcQueryTreeOrig; + + /* + * Call original function and bail if it fails. + * NOTE: We must do this first, since we need XdmcpOpenDisplay + * to be called before we initialize our clipboard client. + */ + iReturn = (*winProcQueryTreeOrig) (client); + if (iReturn != 0) + { + ErrorF ("winProcQueryTree - ProcQueryTree failed, bailing.\n"); + return iReturn; + } + + /* Make errors more obvious */ + winProcQueryTreeOrig = NULL; + + /* Do nothing if clipboard is not enabled */ + if (!g_fClipboard) + { + ErrorF ("winProcQueryTree - Clipboard is not enabled, " + "returning.\n"); + return iReturn; + } + + /* If the clipboard client has already been started, abort */ + if (g_fClipboardLaunched) + { + ErrorF ("winProcQueryTree - Clipboard client already " + "launched, returning.\n"); + return iReturn; + } + + /* Startup the clipboard client if clipboard mode is being used */ + if (g_fXdmcpEnabled && g_fClipboard) + { + /* + * NOTE: The clipboard client is started here for a reason: + * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%) + * 2) If the clipboard client attaches during X Server startup, + * then it becomes the "magic client" that causes the X Server + * to reset if it exits. + * 3) XDMCP calls KillAllClients when it starts up. + * 4) The clipboard client is a client, so it is killed. + * 5) The clipboard client is the "magic client", so the X Server + * resets itself. + * 6) This repeats ad infinitum. + * 7) We avoid this by waiting until at least one client (could + * be XDM, could be another client) connects, which makes it + * almost certain that the clipboard client will not connect + * until after XDM when using XDMCP. + * 8) Unfortunately, there is another problem. + * 9) XDM walks the list of windows with XQueryTree, + * killing any client it finds with a window. + * 10)Thus, when using XDMCP we wait until the first call + * to ProcQueryTree before we startup the clipboard client. + * This should prevent XDM from finding the clipboard client, + * since it has not yet created a window. + * 11)Startup when not using XDMCP is handled in + * winProcEstablishConnection. + */ + + /* Create the clipboard client thread */ + if (!winInitClipboard ()) + { + ErrorF ("winProcQueryTree - winClipboardInit " + "failed.\n"); + return iReturn; + } + + ErrorF ("winProcQueryTree - winInitClipboard returned.\n"); + } + + /* Flag that clipboard client has been launched */ + g_fClipboardLaunched = TRUE; + + return iReturn; +} + + +/* + * Wrapper for internal EstablishConnection function. + * Initializes internal clients that must not be started until + * an external client has connected. + */ + +int +winProcEstablishConnection (ClientPtr client) +{ + int iReturn; + static int s_iCallCount = 0; + static unsigned long s_ulServerGeneration = 0; + + ErrorF ("winProcEstablishConnection - Hello\n"); + + /* Do nothing if clipboard is not enabled */ + if (!g_fClipboard) + { + ErrorF ("winProcEstablishConnection - Clipboard is not enabled, " + "returning.\n"); + + /* Unwrap the original function, call it, and return */ + InitialVector[2] = winProcEstablishConnectionOrig; + iReturn = (*winProcEstablishConnectionOrig) (client); + winProcEstablishConnectionOrig = NULL; + return iReturn; + } + + /* Watch for server reset */ + if (s_ulServerGeneration != serverGeneration) + { + /* Save new generation number */ + s_ulServerGeneration = serverGeneration; + + /* Reset call count */ + s_iCallCount = 0; + } + + /* Increment call count */ + ++s_iCallCount; + + /* Wait for second call when Xdmcp is enabled */ + if (g_fXdmcpEnabled + && !g_fClipboardLaunched + && s_iCallCount < 4) + { + ErrorF ("winProcEstablishConnection - Xdmcp enabled, waiting to " + "start clipboard client until fourth call.\n"); + return (*winProcEstablishConnectionOrig) (client); + } + + /* + * This procedure is only used for initialization. + * We can unwrap the original procedure at this point + * so that this function is no longer called until the + * server resets and the function is wrapped again. + */ + InitialVector[2] = winProcEstablishConnectionOrig; + + /* + * Call original function and bail if it fails. + * NOTE: We must do this first, since we need XdmcpOpenDisplay + * to be called before we initialize our clipboard client. + */ + iReturn = (*winProcEstablishConnectionOrig) (client); + if (iReturn != 0) + { + ErrorF ("winProcEstablishConnection - ProcEstablishConnection " + "failed, bailing.\n"); + return iReturn; + } + + /* Clear original function pointer */ + winProcEstablishConnectionOrig = NULL; + + /* If the clipboard client has already been started, abort */ + if (g_fClipboardLaunched) + { + ErrorF ("winProcEstablishConnection - Clipboard client already " + "launched, returning.\n"); + return iReturn; + } + + /* Startup the clipboard client if clipboard mode is being used */ + if (g_fClipboard) + { + /* + * NOTE: The clipboard client is started here for a reason: + * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%) + * 2) If the clipboard client attaches during X Server startup, + * then it becomes the "magic client" that causes the X Server + * to reset if it exits. + * 3) XDMCP calls KillAllClients when it starts up. + * 4) The clipboard client is a client, so it is killed. + * 5) The clipboard client is the "magic client", so the X Server + * resets itself. + * 6) This repeats ad infinitum. + * 7) We avoid this by waiting until at least one client (could + * be XDM, could be another client) connects, which makes it + * almost certain that the clipboard client will not connect + * until after XDM when using XDMCP. + * 8) Unfortunately, there is another problem. + * 9) XDM walks the list of windows with XQueryTree, + * killing any client it finds with a window. + * 10)Thus, when using XDMCP we wait until the second call + * to ProcEstablishCeonnection before we startup the clipboard + * client. This should prevent XDM from finding the clipboard + * client, since it has not yet created a window. + */ + + /* Create the clipboard client thread */ + if (!winInitClipboard ()) + { + ErrorF ("winProcEstablishConnection - winClipboardInit " + "failed.\n"); + return iReturn; + } + + ErrorF ("winProcEstablishConnection - winInitClipboard returned.\n"); + } + + /* Flag that clipboard client has been launched */ + g_fClipboardLaunched = TRUE; + + return iReturn; +} + + +/* + * Wrapper for internal SetSelectionOwner function. + * Grabs ownership of Windows clipboard when X11 clipboard owner changes. + */ + +int +winProcSetSelectionOwner (ClientPtr client) +{ + int i; + DrawablePtr pDrawable; + WindowPtr pWindow = None; + Bool fOwnedToNotOwned = FALSE; + static Window s_iOwners[CLIP_NUM_SELECTIONS] = {None}; + static unsigned long s_ulServerGeneration = 0; + REQUEST(xSetSelectionOwnerReq); + + REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); + +#if 0 + ErrorF ("winProcSetSelectionOwner - Hello.\n"); +#endif + + /* Watch for server reset */ + if (s_ulServerGeneration != serverGeneration) + { + /* Save new generation number */ + s_ulServerGeneration = serverGeneration; + + /* Initialize static variables */ + for (i = 0; i < CLIP_NUM_SELECTIONS; ++i) + s_iOwners[i] = None; + } + + /* Abort if clipboard not completely initialized yet */ + if (!g_fClipboardStarted) + { + ErrorF ("winProcSetSelectionOwner - Clipboard not yet started, " + "aborting.\n"); + goto winProcSetSelectionOwner_Done; + } + + /* Grab window if we have one */ + if (None != stuff->window) + { + /* Grab the Window from the request */ + int rc = dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess); + if (rc != Success) { + ErrorF ("winProcSetSelectionOwner - Found BadWindow, aborting.\n"); + goto winProcSetSelectionOwner_Done; + } + } + + /* Now we either have a valid window or None */ + + /* Save selection owners for monitored selections, ignore other selections */ + if (XA_PRIMARY == stuff->selection) + { + /* Look for owned -> not owned transition */ + if (None == stuff->window + && None != s_iOwners[CLIP_OWN_PRIMARY]) + { + fOwnedToNotOwned = TRUE; + +#if 0 + ErrorF ("winProcSetSelectionOwner - PRIMARY - Going from " + "owned to not owned.\n"); +#endif + + /* Adjust last owned selection */ + if (None != s_iOwners[CLIP_OWN_CLIPBOARD]) + g_atomLastOwnedSelection = MakeAtom ("CLIPBOARD", 9, TRUE); + else + g_atomLastOwnedSelection = None; + } + + /* Save new selection owner or None */ + s_iOwners[CLIP_OWN_PRIMARY] = stuff->window; + +#if 0 + ErrorF ("winProcSetSelectionOwner - PRIMARY - Now owned by: %d\n", + stuff->window); +#endif + } + else if (MakeAtom ("CLIPBOARD", 9, TRUE) == stuff->selection) + { + /* Look for owned -> not owned transition */ + if (None == stuff->window + && None != s_iOwners[CLIP_OWN_CLIPBOARD]) + { + fOwnedToNotOwned = TRUE; + +#if 0 + ErrorF ("winProcSetSelectionOwner - CLIPBOARD - Going from " + "owned to not owned.\n"); +#endif + + /* Adjust last owned selection */ + if (None != s_iOwners[CLIP_OWN_PRIMARY]) + g_atomLastOwnedSelection = XA_PRIMARY; + else + g_atomLastOwnedSelection = None; + } + + /* Save new selection owner or None */ + s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window; + +#if 0 + ErrorF ("winProcSetSelectionOwner - CLIPBOARD - Now owned by: %d\n", + stuff->window); +#endif + } + else + goto winProcSetSelectionOwner_Done; + + /* + * At this point, if one of the selections is still owned by the + * clipboard manager then it should be marked as unowned since + * we will be taking ownership of the Win32 clipboard. + */ + if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY]) + s_iOwners[CLIP_OWN_PRIMARY] = None; + if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD]) + s_iOwners[CLIP_OWN_CLIPBOARD] = None; + + /* + * Handle case when selection is being disowned, + * WM_DRAWCLIPBOARD did not do the disowning, + * both monitored selections are no longer owned, + * an owned to not owned transition was detected, + * and we currently own the Win32 clipboard. + */ + if (None == stuff->window + && (None == s_iOwners[CLIP_OWN_PRIMARY] + || g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY]) + && (None == s_iOwners[CLIP_OWN_CLIPBOARD] + || g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD]) + && fOwnedToNotOwned + && g_hwndClipboard != NULL + && g_hwndClipboard == GetClipboardOwner ()) + { +#if 0 + ErrorF ("winProcSetSelectionOwner - We currently own the " + "clipboard and neither the PRIMARY nor the CLIPBOARD " + "selections are owned, releasing ownership of Win32 " + "clipboard.\n"); +#endif + + /* Release ownership of the Windows clipboard */ + OpenClipboard (NULL); + EmptyClipboard (); + CloseClipboard (); + + /* Clear X selection ownership (might still be marked as us owning) */ + s_iOwners[CLIP_OWN_PRIMARY] = None; + s_iOwners[CLIP_OWN_CLIPBOARD] = None; + + goto winProcSetSelectionOwner_Done; + } + + /* Abort if no window at this point */ + if (None == stuff->window) + { +#if 0 + ErrorF ("winProcSetSelectionOwner - No window, returning.\n"); +#endif + goto winProcSetSelectionOwner_Done; + } + + /* Abort if invalid selection */ + if (!ValidAtom (stuff->selection)) + { + ErrorF ("winProcSetSelectionOwner - Found BadAtom, aborting.\n"); + goto winProcSetSelectionOwner_Done; + } + + /* Cast Window to Drawable */ + pDrawable = (DrawablePtr) pWindow; + + /* Abort if clipboard manager is owning the selection */ + if (pDrawable->id == g_iClipboardWindow) + { +#if 0 + ErrorF ("winProcSetSelectionOwner - We changed ownership, " + "aborting.\n"); +#endif + goto winProcSetSelectionOwner_Done; + } + + /* Abort if root window is taking ownership */ + if (pDrawable->id == 0) + { + ErrorF ("winProcSetSelectionOwner - Root window taking ownership, " + "aborting\n"); + goto winProcSetSelectionOwner_Done; + } + + /* Close clipboard if we have it open already */ + if (GetOpenClipboardWindow () == g_hwndClipboard) + { + CloseClipboard (); + } + + /* Access the Windows clipboard */ + if (!OpenClipboard (g_hwndClipboard)) + { + ErrorF ("winProcSetSelectionOwner - OpenClipboard () failed: %08x\n", + (int) GetLastError ()); + goto winProcSetSelectionOwner_Done; + } + + /* Take ownership of the Windows clipboard */ + if (!EmptyClipboard ()) + { + ErrorF ("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n", + (int) GetLastError ()); + goto winProcSetSelectionOwner_Done; + } + + /* Advertise Unicode if we support it */ + if (g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + + /* Always advertise regular text */ + SetClipboardData (CF_TEXT, NULL); + + /* Save handle to last owned selection */ + g_atomLastOwnedSelection = stuff->selection; + + /* Release the clipboard */ + if (!CloseClipboard ()) + { + ErrorF ("winProcSetSelectionOwner - CloseClipboard () failed: " + "%08x\n", + (int) GetLastError ()); + goto winProcSetSelectionOwner_Done; + } + + winProcSetSelectionOwner_Done: + return (*winProcSetSelectionOwnerOrig) (client); +} diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c new file mode 100644 index 000000000..d4c617bec --- /dev/null +++ b/hw/xwin/winclipboardxevents.c @@ -0,0 +1,796 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "winclipboard.h" + + +/* + * References to external symbols + */ + +extern Bool g_fUnicodeSupport; + + +/* + * Process any pending X events + */ + +int +winClipboardFlushXEvents (HWND hwnd, + int iWindow, + Display *pDisplay, + Bool fUseUnicode) +{ + Atom atomLocalProperty = XInternAtom (pDisplay, + WIN_LOCAL_PROPERTY, + False); + Atom atomUTF8String = XInternAtom (pDisplay, + "UTF8_STRING", + False); + Atom atomCompoundText = XInternAtom (pDisplay, + "COMPOUND_TEXT", + False); + Atom atomTargets = XInternAtom (pDisplay, + "TARGETS", + False); + + /* Process all pending events */ + while (XPending (pDisplay)) + { + XTextProperty xtpText = {0}; + XEvent event; + XSelectionEvent eventSelection; + unsigned long ulReturnBytesLeft; + unsigned char *pszReturnData = NULL; + char *pszGlobalData = NULL; + int iReturn; + HGLOBAL hGlobal = NULL; + XICCEncodingStyle xiccesStyle; + int iConvertDataLen = 0; + char *pszConvertData = NULL; + char *pszTextList[2] = {NULL}; + int iCount; + char **ppszTextList = NULL; + wchar_t *pwszUnicodeStr = NULL; + int iUnicodeLen = 0; + int iReturnDataLen = 0; + int i; + Bool fAbort = FALSE; + Bool fCloseClipboard = FALSE; + Bool fSetClipboardData = TRUE; + + /* Get the next event - will not block because one is ready */ + XNextEvent (pDisplay, &event); + + /* Branch on the event type */ + switch (event.type) + { + /* + * SelectionRequest + */ + + case SelectionRequest: +#if 0 + { + char *pszAtomName = NULL; + + ErrorF ("SelectionRequest - target %d\n", + event.xselectionrequest.target); + + pszAtomName = XGetAtomName (pDisplay, + event.xselectionrequest.target); + ErrorF ("SelectionRequest - Target atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + } +#endif + + /* Abort if invalid target type */ + if (event.xselectionrequest.target != XA_STRING + && event.xselectionrequest.target != atomUTF8String + && event.xselectionrequest.target != atomCompoundText + && event.xselectionrequest.target != atomTargets) + { + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Handle targets type of request */ + if (event.xselectionrequest.target == atomTargets) + { + Atom atomTargetArr[] = {atomTargets, + atomCompoundText, + atomUTF8String, + XA_STRING}; + + /* Try to change the property */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char *) atomTargetArr, + (sizeof (atomTargetArr) + / sizeof (atomTargetArr[0]))); + if (iReturn == BadAlloc + || iReturn == BadAtom + || iReturn == BadMatch + || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XChangeProperty failed: %d\n", + iReturn); + } + + /* Setup selection notify xevent */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = event.xselectionrequest.property; + eventSelection.time = event.xselectionrequest.time; + + /* + * Notify the requesting window that + * the operation has completed + */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed\n"); + } + break; + } + + /* Check that clipboard format is available */ + if (fUseUnicode + && !IsClipboardFormatAvailable (CF_UNICODETEXT)) + { + ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " + "available from Win32 clipboard. Aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + else if (!fUseUnicode + && !IsClipboardFormatAvailable (CF_TEXT)) + { + ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " + "available from Win32 clipboard. Aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Close clipboard if we have it open already */ + if (GetOpenClipboardWindow () == hwnd) + { + CloseClipboard (); + } + + /* Access the clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "OpenClipboard () failed: %08x\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Indicate that clipboard was opened */ + fCloseClipboard = TRUE; + + /* Setup the string style */ + if (event.xselectionrequest.target == XA_STRING) + xiccesStyle = XStringStyle; +#ifdef X_HAVE_UTF8_STRING + else if (event.xselectionrequest.target == atomUTF8String) + xiccesStyle = XUTF8StringStyle; +#endif + else if (event.xselectionrequest.target == atomCompoundText) + xiccesStyle = XCompoundTextStyle; + else + xiccesStyle = XStringStyle; + + /* + * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me + */ + + /* Get a pointer to the clipboard text, in desired format */ + if (fUseUnicode) + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_UNICODETEXT); + } + else + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_TEXT); + } + if (!hGlobal) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "GetClipboardData () failed: %08x\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + pszGlobalData = (char *) GlobalLock (hGlobal); + + /* Convert the Unicode string to UTF8 (MBCS) */ + if (fUseUnicode) + { + iConvertDataLen = WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + NULL, + 0, + NULL, + NULL); + /* NOTE: iConvertDataLen includes space for null terminator */ + pszConvertData = (char *) malloc (iConvertDataLen); + WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + pszConvertData, + iConvertDataLen, + NULL, + NULL); + } + else + { + pszConvertData = strdup (pszGlobalData); + iConvertDataLen = strlen (pszConvertData) + 1; + } + + /* Convert DOS string to UNIX string */ + winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); + + /* Setup our text list */ + pszTextList[0] = pszConvertData; + pszTextList[1] = NULL; + + /* Initialize the text property */ + xtpText.value = NULL; + + /* Create the text property from the text list */ + if (fUseUnicode) + { +#ifdef X_HAVE_UTF8_STRING + iReturn = Xutf8TextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); +#endif + } + else + { + iReturn = XmbTextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); + } + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "X*TextListToTextProperty failed: %d\n", + iReturn); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Free the converted string */ + free (pszConvertData); + pszConvertData = NULL; + + /* Copy the clipboard text to the requesting window */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + xtpText.value, + xtpText.nitems); + if (iReturn == BadAlloc || iReturn == BadAtom + || iReturn == BadMatch || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XChangeProperty failed: %d\n", + iReturn); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Release the clipboard data */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + + /* Clean up */ + XFree (xtpText.value); + xtpText.value = NULL; + + /* Setup selection notify event */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = event.xselectionrequest.property; + eventSelection.time = event.xselectionrequest.time; + + /* Notify the requesting window that the operation has completed */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + winClipboardFlushXEvents_SelectionRequest_Done: + /* Free allocated resources */ + if (xtpText.value) + XFree (xtpText.value); + if (pszConvertData) + free (pszConvertData); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + + /* + * Send a SelectionNotify event to the requesting + * client when we abort. + */ + if (fAbort) + { + /* Setup selection notify event */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = None; + eventSelection.time = event.xselectionrequest.time; + + /* Notify the requesting window that the operation is complete */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + /* + * Should not be a problem if XSendEvent fails because + * the client may simply have exited. + */ + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed for abort event.\n"); + } + } + + /* Close clipboard if it was opened */ + if (fCloseClipboard) + CloseClipboard (); + break; + + + /* + * SelectionNotify + */ + + case SelectionNotify: +#if 0 + ErrorF ("winClipboardFlushXEvents - SelectionNotify\n"); + { + char *pszAtomName; + + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + + ErrorF ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", + pszAtomName); + + XFree (pszAtomName); + } +#endif + + + /* + * Request conversion of UTF8 and CompoundText targets. + */ + if (event.xselection.property == None) + { + if (event.xselection.target == XA_STRING) + { +#if 0 + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XA_STRING\n"); +#endif + return WIN_XEVENTS_CONVERT; + } + else if (event.xselection.target == atomUTF8String) + { +#if 0 + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "Requesting conversion of UTF8 target.\n"); +#endif + iReturn = XConvertSelection (pDisplay, + event.xselection.selection, + XA_STRING, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XConvertSelection () failed for UTF8String, " + "aborting: %d\n", + iReturn); + break; + } + + /* Process the ConvertSelection event */ + XFlush (pDisplay); + return WIN_XEVENTS_CONVERT; + } +#ifdef X_HAVE_UTF8_STRING + else if (event.xselection.target == atomCompoundText) + { +#if 0 + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "Requesting conversion of CompoundText target.\n"); +#endif + iReturn = XConvertSelection (pDisplay, + event.xselection.selection, + atomUTF8String, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XConvertSelection () failed for CompoundText, " + "aborting: %d\n", + iReturn); + break; + } + + /* Process the ConvertSelection event */ + XFlush (pDisplay); + return WIN_XEVENTS_CONVERT; + } +#endif + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "Unknown format. Cannot request conversion, " + "aborting.\n"); + break; + } + } + + /* Retrieve the size of the stored data */ + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + 0, /* Don't get data, just size */ + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; + } + +#if 0 + ErrorF ("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); +#endif + + /* Request the selection data */ + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + ulReturnBytesLeft, + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; + } + +#if 0 + { + char *pszAtomName = NULL; + + ErrorF ("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); + + pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); + ErrorF ("Notify atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + } +#endif + + if (fUseUnicode) + { +#ifdef X_HAVE_UTF8_STRING + /* Convert the text property to a text list */ + iReturn = Xutf8TextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); +#endif + } + else + { + iReturn = XmbTextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); + } + if (iReturn == Success || iReturn > 0) + { + /* Conversion succeeded or some unconvertible characters */ + if (ppszTextList != NULL) + { + for (i = 0; i < iCount; i++) + { + iReturnDataLen += strlen(ppszTextList[i]); + } + pszReturnData = malloc (iReturnDataLen + 1); + pszReturnData[0] = '\0'; + for (i = 0; i < iCount; i++) + { + strcat (pszReturnData, ppszTextList[i]); + } + } + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "X*TextPropertyToTextList list_return is NULL.\n"); + pszReturnData = malloc (1); + pszReturnData[0] = '\0'; + } + } + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "X*TextPropertyToTextList returned: "); + switch (iReturn) + { + case XNoMemory: + ErrorF ("XNoMemory\n"); + break; + case XConverterNotFound: + ErrorF ("XConverterNotFound\n"); + break; + default: + ErrorF ("%d", iReturn); + break; + } + pszReturnData = malloc (1); + pszReturnData[0] = '\0'; + } + + /* Free the data returned from XGetWindowProperty */ + if (ppszTextList) + XFreeStringList (ppszTextList); + ppszTextList = NULL; + XFree (xtpText.value); + xtpText.value = NULL; + + /* Convert the X clipboard string to DOS format */ + winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); + + if (fUseUnicode) + { + /* Find out how much space needed to convert MBCS to Unicode */ + iUnicodeLen = MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + NULL, + 0); + + /* Allocate memory for the Unicode string */ + pwszUnicodeStr + = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); + if (!pwszUnicodeStr) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "malloc failed for pwszUnicodeStr, aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Do the actual conversion */ + MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + pwszUnicodeStr, + iUnicodeLen); + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, + sizeof (wchar_t) * (iUnicodeLen + 1)); + } + else + { + pszConvertData = strdup (pszReturnData); + iConvertDataLen = strlen (pszConvertData) + 1; + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); + } + + /* Check that global memory was allocated */ + if (!hGlobal) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "GlobalAlloc failed, aborting: %ld\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Obtain a pointer to the global memory */ + pszGlobalData = GlobalLock (hGlobal); + if (pszGlobalData == NULL) + { + ErrorF ("winClipboardFlushXEvents - Could not lock global " + "memory for clipboard transfer\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Copy the returned string into the global memory */ + if (fUseUnicode) + { + memcpy (pszGlobalData, + pwszUnicodeStr, + sizeof (wchar_t) * (iUnicodeLen + 1)); + free (pwszUnicodeStr); + pwszUnicodeStr = NULL; + } + else + { + strcpy (pszGlobalData, pszConvertData); + free (pszConvertData); + pszConvertData = NULL; + } + + /* Release the pointer to the global memory */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + + /* Push the selection data to the Windows clipboard */ + if (fUseUnicode) + SetClipboardData (CF_UNICODETEXT, hGlobal); + else + SetClipboardData (CF_TEXT, hGlobal); + + /* Flag that SetClipboardData has been called */ + fSetClipboardData = FALSE; + + /* + * NOTE: Do not try to free pszGlobalData, it is owned by + * Windows after the call to SetClipboardData (). + */ + + winClipboardFlushXEvents_SelectionNotify_Done: + /* Free allocated resources */ + if (ppszTextList) + XFreeStringList (ppszTextList); + if (xtpText.value) + XFree (xtpText.value); + if (pszConvertData) + free (pszConvertData); + if (pwszUnicodeStr) + free (pwszUnicodeStr); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + if (fSetClipboardData && g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + if (fSetClipboardData) + SetClipboardData (CF_TEXT, NULL); + return WIN_XEVENTS_NOTIFY; + + default: + break; + } + } + + return WIN_XEVENTS_SUCCESS; +} diff --git a/hw/xwin/wincmap.c b/hw/xwin/wincmap.c new file mode 100644 index 000000000..7ebe00244 --- /dev/null +++ b/hw/xwin/wincmap.c @@ -0,0 +1,674 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + + +/* + * Local prototypes + */ + +static int +winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps); + +static void +winStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs); + +static void +winInstallColormap (ColormapPtr pmap); + +static void +winUninstallColormap (ColormapPtr pmap); + +static void +winResolveColor (unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual); + +static Bool +winCreateColormap (ColormapPtr pmap); + +static void +winDestroyColormap (ColormapPtr pmap); + +static Bool +winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap); + +static Bool +winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap); + + +/* + * Set screen functions for colormaps + */ + +void +winSetColormapFunctions (ScreenPtr pScreen) +{ + pScreen->CreateColormap = winCreateColormap; + pScreen->DestroyColormap = winDestroyColormap; + pScreen->InstallColormap = winInstallColormap; + pScreen->UninstallColormap = winUninstallColormap; + pScreen->ListInstalledColormaps = winListInstalledColormaps; + pScreen->StoreColors = winStoreColors; + pScreen->ResolveColor = winResolveColor; +} + + +/* See Porting Layer Definition - p. 30 */ +/* + * Walk the list of installed colormaps, filling the pmaps list + * with the resource ids of the installed maps, and return + * a count of the total number of installed maps. + */ +static int +winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps) +{ + winScreenPriv(pScreen); + + /* + * There will only be one installed colormap, so we only need + * to return one id, and the count of installed maps will always + * be one. + */ + *pmaps = pScreenPriv->pcmapInstalled->mid; + return 1; +} + + +/* See Porting Layer Definition - p. 30 */ +/* See Programming Windows - p. 663 */ +static void +winInstallColormap (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + ColormapPtr oldpmap = pScreenPriv->pcmapInstalled; + +#if CYGDEBUG + winDebug ("winInstallColormap\n"); +#endif + + /* Did the colormap actually change? */ + if (pColormap != oldpmap) + { +#if CYGDEBUG + winDebug ("winInstallColormap - Colormap has changed, attempt " + "to install.\n"); +#endif + + /* Was there a previous colormap? */ + if (oldpmap != (ColormapPtr) None) + { + /* There was a previous colormap; tell clients it is gone */ + WalkTree (pColormap->pScreen, TellLostMap, (char *)&oldpmap->mid); + } + + /* Install new colormap */ + pScreenPriv->pcmapInstalled = pColormap; + WalkTree (pColormap->pScreen, TellGainedMap, (char *)&pColormap->mid); + + /* Call the engine specific colormap install procedure */ + if (!((*pScreenPriv->pwinInstallColormap) (pColormap))) + { + winErrorFVerb (2, "winInstallColormap - Screen specific colormap install " + "procedure failed. Continuing, but colors may be " + "messed up from now on.\n"); + } + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; +} + + +/* See Porting Layer Definition - p. 30 */ +static void +winUninstallColormap (ColormapPtr pmap) +{ + winScreenPriv(pmap->pScreen); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + +#if CYGDEBUG + winDebug ("winUninstallColormap\n"); +#endif + + /* Is the colormap currently installed? */ + if (pmap != curpmap) + { + /* Colormap not installed, nothing to do */ + return; + } + + /* Clear the installed colormap flag */ + pScreenPriv->pcmapInstalled = NULL; + + /* + * NOTE: The default colormap does not get "uninstalled" before + * it is destroyed. + */ + + /* Install the default cmap in place of the cmap to be uninstalled */ + if (pmap->mid != pmap->pScreen->defColormap) + { + curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + (*pmap->pScreen->InstallColormap) (curpmap); + } +} + + +/* See Porting Layer Definition - p. 30 */ +static void +winStoreColors (ColormapPtr pmap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pmap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pmap); + int i; + unsigned short nRed, nGreen, nBlue; + +#if CYGDEBUG + if (ndef != 1) + winDebug ("winStoreColors - ndef: %d\n", + ndef); +#endif + + /* Save the new colors in the colormap privates */ + for (i = 0; i < ndef; ++i) + { + /* Adjust the colors from the X color spec to the Windows color spec */ + nRed = pdefs[i].red >> 8; + nGreen = pdefs[i].green >> 8; + nBlue = pdefs[i].blue >> 8; + + /* Copy the colors to a palette entry table */ + pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed; + pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen; + pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue; + + /* Copy the colors to a RGBQUAD table */ + pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed; + pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen; + pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue; + +#if CYGDEBUG + winDebug ("winStoreColors - nRed %d nGreen %d nBlue %d\n", + nRed, nGreen, nBlue); +#endif + } + + /* Call the engine specific store colors procedure */ + if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs))) + { + winErrorFVerb (2, "winStoreColors - Engine cpecific color storage procedure " + "failed. Continuing, but colors may be messed up from now " + "on.\n"); + } +} + + +/* See Porting Layer Definition - p. 30 */ +static void +winResolveColor (unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual) +{ +#if CYGDEBUG + winDebug ("winResolveColor ()\n"); +#endif + + miResolveColor (pred, pgreen, pblue, pVisual); +} + + +/* See Porting Layer Definition - p. 29 */ +static Bool +winCreateColormap (ColormapPtr pmap) +{ + winPrivCmapPtr pCmapPriv = NULL; + ScreenPtr pScreen = pmap->pScreen; + winScreenPriv(pScreen); + +#if CYGDEBUG + winDebug ("winCreateColormap\n"); +#endif + + /* Allocate colormap privates */ + if (!winAllocateCmapPrivates (pmap)) + { + ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n"); + return FALSE; + } + + /* Get a pointer to the newly allocated privates */ + pCmapPriv = winGetCmapPriv (pmap); + + /* + * FIXME: This is some evil hackery to help in handling some X clients + * that expect the top pixel to be white. This "help" only lasts until + * some client overwrites the top colormap entry. + * + * We don't want to actually allocate the top entry, as that causes + * problems with X clients that need 7 planes (128 colors) in the default + * colormap, such as Magic 7.1. + */ + pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255; + pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255; + pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255; + pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255; + pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255; + pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255; + + /* Call the engine specific colormap initialization procedure */ + if (!((*pScreenPriv->pwinCreateColormap) (pmap))) + { + ErrorF ("winCreateColormap - Engine specific colormap creation " + "procedure failed. Aborting.\n"); + return FALSE; + } + + return TRUE; +} + + +/* See Porting Layer Definition - p. 29, 30 */ +static void +winDestroyColormap (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + + /* Call the engine specific colormap destruction procedure */ + if (!((*pScreenPriv->pwinDestroyColormap) (pColormap))) + { + winErrorFVerb (2, "winDestroyColormap - Engine specific colormap destruction " + "procedure failed. Continuing, but it is possible that memory " + "was leaked, or that colors will be messed up from now on.\n"); + } + + /* Free the colormap privates */ + free (pCmapPriv); + winSetCmapPriv (pColormap, NULL); + +#if CYGDEBUG + winDebug ("winDestroyColormap - Returning\n"); +#endif +} + + +/* + * Internal function to load the palette used by the Shadow DIB + */ + +static Bool +winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap) +{ + winScreenPriv(pScreen); + int i; + Pixel pixel; /* Pixel == CARD32 */ + CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */ + UINT uiColorsRetrieved = 0; + RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; + + /* Get the color table for the screen */ + uiColorsRetrieved = GetDIBColorTable (pScreenPriv->hdcScreen, + 0, + WIN_NUM_PALETTE_ENTRIES, + rgbColors); + if (uiColorsRetrieved == 0) + { + ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winGetPaletteDIB - Retrieved %d colors from DIB\n", + uiColorsRetrieved); +#endif + + /* Set the DIB color table to the default screen palette */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + 0, + uiColorsRetrieved, + rgbColors) == 0) + { + ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n"); + return FALSE; + } + + /* Alloc each color in the DIB color table */ + for (i = 0; i < uiColorsRetrieved; ++i) + { + pixel = i; + + /* Extract the color values for current palette entry */ + nRed = rgbColors[i].rgbRed << 8; + nGreen = rgbColors[i].rgbGreen << 8; + nBlue = rgbColors[i].rgbBlue << 8; + +#if CYGDEBUG + winDebug ("winGetPaletteDIB - Allocating a color: %d; " + "%d %d %d\n", + pixel, nRed, nGreen, nBlue); +#endif + + /* Allocate a entry in the X colormap */ + if (AllocColor (pcmap, + &nRed, + &nGreen, + &nBlue, + &pixel, + 0) != Success) + { + ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n", + i); + return FALSE; + } + + if (i != pixel + || nRed != rgbColors[i].rgbRed + || nGreen != rgbColors[i].rgbGreen + || nBlue != rgbColors[i].rgbBlue) + { + winDebug ("winGetPaletteDIB - Got: %d; " + "%d %d %d\n", + (int) pixel, nRed, nGreen, nBlue); + } + + /* FIXME: Not sure that this bit is needed at all */ + pcmap->red[i].co.local.red = nRed; + pcmap->red[i].co.local.green = nGreen; + pcmap->red[i].co.local.blue = nBlue; + } + + /* System is using a colormap */ + /* Set the black and white pixel indices */ + pScreen->whitePixel = uiColorsRetrieved - 1; + pScreen->blackPixel = 0; + + return TRUE; +} + + +/* + * Internal function to load the standard system palette being used by DD + */ + +static Bool +winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap) +{ + int i; + Pixel pixel; /* Pixel == CARD32 */ + CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */ + UINT uiSystemPaletteEntries; + LPPALETTEENTRY ppeColors = NULL; + HDC hdc = NULL; + + /* Get a DC to obtain the default palette */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winGetPaletteDD - Couldn't get a DC\n"); + return FALSE; + } + + /* Get the number of entries in the system palette */ + uiSystemPaletteEntries = GetSystemPaletteEntries (hdc, + 0, 0, NULL); + if (uiSystemPaletteEntries == 0) + { + ErrorF ("winGetPaletteDD - Unable to determine number of " + "system palette entries\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winGetPaletteDD - uiSystemPaletteEntries %d\n", + uiSystemPaletteEntries); +#endif + + /* Allocate palette entries structure */ + ppeColors = malloc (uiSystemPaletteEntries * sizeof (PALETTEENTRY)); + if (ppeColors == NULL) + { + ErrorF ("winGetPaletteDD - malloc () for colormap failed\n"); + return FALSE; + } + + /* Get system palette entries */ + GetSystemPaletteEntries (hdc, + 0, uiSystemPaletteEntries, ppeColors); + + /* Allocate an X colormap entry for every system palette entry */ + for (i = 0; i < uiSystemPaletteEntries; ++i) + { + pixel = i; + + /* Extract the color values for current palette entry */ + nRed = ppeColors[i].peRed << 8; + nGreen = ppeColors[i].peGreen << 8; + nBlue = ppeColors[i].peBlue << 8; +#if CYGDEBUG + winDebug ("winGetPaletteDD - Allocating a color: %d; " + "%d %d %d\n", + pixel, nRed, nGreen, nBlue); +#endif + if (AllocColor (pcmap, + &nRed, + &nGreen, + &nBlue, + &pixel, + 0) != Success) + { + ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n", + i); + free (ppeColors); + ppeColors = NULL; + return FALSE; + } + + pcmap->red[i].co.local.red = nRed; + pcmap->red[i].co.local.green = nGreen; + pcmap->red[i].co.local.blue = nBlue; + } + + /* System is using a colormap */ + /* Set the black and white pixel indices */ + pScreen->whitePixel = uiSystemPaletteEntries - 1; + pScreen->blackPixel = 0; + + /* Free colormap */ + if (ppeColors != NULL) + { + free (ppeColors); + ppeColors = NULL; + } + + /* Free the DC */ + if (hdc != NULL) + { + ReleaseDC (NULL, hdc); + hdc = NULL; + } + + return TRUE; +} + + +/* + * Install the standard fb colormap, or the GDI colormap, + * depending on the current screen depth. + */ + +Bool +winCreateDefColormap (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + unsigned short zero = 0, ones = 0xFFFF; + VisualPtr pVisual = pScreenPriv->pRootVisual; + ColormapPtr pcmap = NULL; + Pixel wp, bp; + +#if CYGDEBUG + winDebug ("winCreateDefColormap\n"); +#endif + + /* Use standard fb colormaps for non palettized color modes */ + if (pScreenInfo->dwBPP > 8) + { + winDebug ("winCreateDefColormap - Deferring to " \ + "fbCreateDefColormap ()\n"); + return fbCreateDefColormap (pScreen); + } + + /* + * AllocAll for non-Dynamic visual classes, + * AllocNone for Dynamic visual classes. + */ + + /* + * Dynamic visual classes allow the colors of the color map + * to be changed by clients. + */ + +#if CYGDEBUG + winDebug ("winCreateDefColormap - defColormap: %d\n", + pScreen->defColormap); +#endif + + /* Allocate an X colormap, owned by client 0 */ + if (CreateColormap (pScreen->defColormap, + pScreen, + pVisual, + &pcmap, + (pVisual->class & DynamicClass) ? AllocNone : AllocAll, + 0) != Success) + { + ErrorF ("winCreateDefColormap - CreateColormap failed\n"); + return FALSE; + } + if (pcmap == NULL) + { + ErrorF ("winCreateDefColormap - Colormap could not be created\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winCreateDefColormap - Created a colormap\n"); +#endif + + /* Branch on the visual class */ + if (!(pVisual->class & DynamicClass)) + { + /* Branch on engine type */ + if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) + { + /* Load the colors being used by the Shadow DIB */ + if (!winGetPaletteDIB (pScreen, pcmap)) + { + ErrorF ("winCreateDefColormap - Couldn't get DIB colors\n"); + return FALSE; + } + } + else + { + /* Load the colors from the default system palette */ + if (!winGetPaletteDD (pScreen, pcmap)) + { + ErrorF ("winCreateDefColormap - Couldn't get colors " + "for DD\n"); + return FALSE; + } + } + } + else + { + wp = pScreen->whitePixel; + bp = pScreen->blackPixel; + + /* Allocate a black and white pixel */ + if ((AllocColor (pcmap, &ones, &ones, &ones, &wp, 0) != + Success) + || + (AllocColor (pcmap, &zero, &zero, &zero, &bp, 0) != + Success)) + { + ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n"); + return FALSE; + } + + pScreen->whitePixel = wp; + pScreen->blackPixel = bp; + +#if 0 + /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */ + if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI) + { + int k; + Pixel p; + + for (k = 1; k < 10; ++k) + { + p = k; + if (AllocColor (pcmap, &ones, &ones, &ones, &p, 0) != Success) + FatalError ("Foo!\n"); + } + + for (k = 245; k < 255; ++k) + { + p = k; + if (AllocColor (pcmap, &zero, &zero, &zero, &p, 0) != Success) + FatalError ("Baz!\n"); + } + } +#endif + } + + /* Install the created colormap */ + (*pScreen->InstallColormap)(pcmap); + +#if CYGDEBUG + winDebug ("winCreateDefColormap - Returning\n"); +#endif + + return TRUE; +} diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c new file mode 100644 index 000000000..38966bf96 --- /dev/null +++ b/hw/xwin/winconfig.c @@ -0,0 +1,1150 @@ +/* + *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: Alexander Gottwald + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winconfig.h" +#include "winmsg.h" +#include "globals.h" + +#ifdef XKB +#ifndef XKB_IN_SERVER +#define XKB_IN_SERVER +#endif +#include <xkbsrv.h> +#endif + +#ifdef XWIN_XF86CONFIG +#ifndef CONFIGPATH +#define CONFIGPATH "%A," "%R," \ + "/etc/X11/%R," "%P/etc/X11/%R," \ + "%E," "%F," \ + "/etc/X11/%F," "%P/etc/X11/%F," \ + "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ + "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ + "%P/etc/X11/%X," \ + "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ + "%P/lib/X11/%X" +#endif + +XF86ConfigPtr g_xf86configptr = NULL; +#endif + +WinCmdlineRec g_cmdline = { +#ifdef XWIN_XF86CONFIG + NULL, /* configFile */ +#endif + NULL, /* fontPath */ +#ifdef XWIN_XF86CONFIG + NULL, /* keyboard */ +#endif +#ifdef XKB + FALSE, /* noXkbExtension */ + NULL, /* xkbMap */ + NULL, /* xkbRules */ + NULL, /* xkbModel */ + NULL, /* xkbLayout */ + NULL, /* xkbVariant */ + NULL, /* xkbOptions */ +#endif + NULL, /* screenname */ + NULL, /* mousename */ + FALSE, /* emulate3Buttons */ + 0 /* emulate3Timeout */ +}; + +winInfoRec g_winInfo = { + { /* keyboard */ + 0, /* leds */ + 500, /* delay */ + 30 /* rate */ +#ifdef XKB + } + , + { /* xkb */ + FALSE, /* disable */ + NULL, /* rules */ + NULL, /* model */ + NULL, /* layout */ + NULL, /* variant */ + NULL, /* options */ + NULL, /* initialMap */ + NULL, /* keymap */ + NULL, /* types */ + NULL, /* compat */ + NULL, /* keycodes */ + NULL, /* symbols */ + NULL /* geometry */ +#endif + } + , + { + FALSE, + 50} +}; + +#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL) + +#ifdef XWIN_XF86CONFIG +serverLayoutRec g_winConfigLayout; + +static Bool ParseOptionValue (int scrnIndex, pointer options, + OptionInfoPtr p); +static Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *); +static Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr); +static Bool GetBoolValue (OptionInfoPtr p, const char *s); + + +Bool +winReadConfigfile () +{ + Bool retval = TRUE; + const char *filename; + MessageType from = X_DEFAULT; + char *xf86ConfigFile = NULL; + + if (g_cmdline.configFile) + { + from = X_CMDLINE; + xf86ConfigFile = g_cmdline.configFile; + } + + /* Parse config file into data structure */ + + filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT); + + /* Hack for backward compatibility */ + if (!filename && from == X_DEFAULT) + filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT); + + if (filename) + { + winMsg (from, "Using config file: \"%s\"\n", filename); + } + else + { + winMsg (X_ERROR, "Unable to locate/open config file"); + if (xf86ConfigFile) + ErrorF (": \"%s\"", xf86ConfigFile); + ErrorF ("\n"); + return FALSE; + } + if ((g_xf86configptr = xf86readConfigFile ()) == NULL) + { + winMsg (X_ERROR, "Problem parsing the config file\n"); + return FALSE; + } + xf86closeConfigFile (); + + LogPrintMarkers(); + + /* set options from data structure */ + + if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL) + { + if (g_cmdline.screenname == NULL) + { + winMsg (X_WARNING, + "No Layout section. Using the first Screen section.\n"); + } + if (!configImpliedLayout (&g_winConfigLayout, + g_xf86configptr->conf_screen_lst)) + { + winMsg (X_ERROR, "Unable to determine the screen layout\n"); + return FALSE; + } + } + else + { + /* Check if layout is given in the config file */ + if (g_xf86configptr->conf_flags != NULL) + { + char *dfltlayout = NULL; + pointer optlist = g_xf86configptr->conf_flags->flg_option_lst; + + if (optlist && winFindOption (optlist, "defaultserverlayout")) + dfltlayout = + winSetStrOption (optlist, "defaultserverlayout", NULL); + + if (!configLayout (&g_winConfigLayout, + g_xf86configptr->conf_layout_lst, + dfltlayout)) + { + winMsg (X_ERROR, "Unable to determine the screen layout\n"); + return FALSE; + } + } + else + { + if (!configLayout (&g_winConfigLayout, + g_xf86configptr->conf_layout_lst, + NULL)) + { + winMsg (X_ERROR, "Unable to determine the screen layout\n"); + return FALSE; + } + } + } + + /* setup special config files */ + winConfigFiles (); + return retval; +} +#endif + +/* load layout definitions */ +#include "winlayouts.h" + +/* Set the keyboard configuration */ +Bool +winConfigKeyboard (DeviceIntPtr pDevice) +{ +#ifdef XKB + char layoutName[KL_NAMELENGTH]; + static unsigned int layoutNum = 0; + int keyboardType; +#endif +#ifdef XWIN_XF86CONFIG + XF86ConfInputPtr kbd = NULL; + XF86ConfInputPtr input_list = NULL; + MessageType kbdfrom = X_CONFIG; +#endif + MessageType from = X_DEFAULT; + char *s = NULL; + + /* Setup defaults */ +#ifdef XKB + g_winInfo.xkb.disable = FALSE; +# ifdef PC98 /* japanese */ /* not implemented */ + g_winInfo.xkb.rules = "xfree98"; + g_winInfo.xkb.model = "pc98"; + g_winInfo.xkb.layout = "nex/jp"; + g_winInfo.xkb.variant = NULL; + g_winInfo.xkb.options = NULL; +# else + g_winInfo.xkb.rules = "xorg"; + g_winInfo.xkb.model = "pc101"; + g_winInfo.xkb.layout = "us"; + g_winInfo.xkb.variant = NULL; + g_winInfo.xkb.options = NULL; +# endif /* PC98 */ + + /* + * Query the windows autorepeat settings and change the xserver defaults. + * If XKB is disabled then windows handles the autorepeat and the special + * treatment is not needed + */ + { + int kbd_delay; + DWORD kbd_speed; + if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) && + SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) + { + switch (kbd_delay) + { + case 0: g_winInfo.keyboard.delay = 250; break; + case 1: g_winInfo.keyboard.delay = 500; break; + case 2: g_winInfo.keyboard.delay = 750; break; + default: + case 3: g_winInfo.keyboard.delay = 1000; break; + } + g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1; + winMsgVerb(X_PROBED, 1, "Setting autorepeat to delay=%d, rate=%d\n", + g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); + } + } + + + keyboardType = GetKeyboardType (0); + if (keyboardType > 0 && GetKeyboardLayoutName (layoutName)) + { + WinKBLayoutPtr pLayout; + Bool bfound = FALSE; + + if (! layoutNum) + layoutNum = strtoul (layoutName, (char **)NULL, 16); + if ((layoutNum & 0xffff) == 0x411) { + /* The japanese layouts know a lot of different IMEs which all have + different layout numbers set. Map them to a single entry. + Same might apply for chinese, korean and other symbol languages + too */ + layoutNum = (layoutNum & 0xffff); + if (keyboardType == 7) + { + /* Japanese layouts have problems with key event messages + such as the lack of WM_KEYUP for Caps Lock key. + Loading US layout fixes this problem. */ + if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL) + winMsg (X_INFO, "Loading US keyboard layout.\n"); + else + winMsg (X_ERROR, "LoadKeyboardLaout failed.\n"); + } + } + winMsg (X_PROBED, "winConfigKeyboard - Layout: \"%s\" (%08x) \n", + layoutName, layoutNum); + + for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) + { + if (pLayout->winlayout != layoutNum) + continue; + if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) + continue; + + bfound = TRUE; + winMsg (X_PROBED, + "Using preset keyboard for \"%s\" (%x), type \"%d\"\n", + pLayout->layoutname, pLayout->winlayout, keyboardType); + + g_winInfo.xkb.model = pLayout->xkbmodel; + g_winInfo.xkb.layout = pLayout->xkblayout; + g_winInfo.xkb.variant = pLayout->xkbvariant; + g_winInfo.xkb.options = pLayout->xkboptions; + break; + } + + if (!bfound) + { + HKEY regkey = NULL; + const char regtempl[] = + "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; + char *regpath; + char lname[256]; + DWORD namesize = sizeof(lname); + + regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1); + strcpy(regpath, regtempl); + strcat(regpath, layoutName); + + if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key) && + !RegQueryValueEx(regkey, "Layout Text", 0, NULL, lname, &namesize)) + { + winMsg (X_ERROR, + "Keyboardlayout \"%s\" (%s) is unknown\n", lname, layoutName); + } + + /* Close registry key */ + if (regkey) + RegCloseKey (regkey); + free(regpath); + } + } + + g_winInfo.xkb.initialMap = NULL; + g_winInfo.xkb.keymap = NULL; + g_winInfo.xkb.types = NULL; + g_winInfo.xkb.compat = NULL; + g_winInfo.xkb.keycodes = NULL; + g_winInfo.xkb.symbols = NULL; + g_winInfo.xkb.geometry = NULL; +#endif /* XKB */ + + /* parse the configuration */ +#ifdef XWIN_XF86CONFIG + if (g_cmdline.keyboard) + kbdfrom = X_CMDLINE; + + /* + * Until the layout code is finished, I search for the keyboard + * device and configure the server with it. + */ + + if (g_xf86configptr != NULL) + input_list = g_xf86configptr->conf_input_lst; + + while (input_list != NULL) + { + if (winNameCompare (input_list->inp_driver, "keyboard") == 0) + { + /* Check if device name matches requested name */ + if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier, + g_cmdline.keyboard)) + continue; + kbd = input_list; + } + input_list = input_list->list.next; + } + + if (kbd != NULL) + { + + if (kbd->inp_identifier) + winMsg (kbdfrom, "Using keyboard \"%s\" as primary keyboard\n", + kbd->inp_identifier); + + if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) + { + if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay, + &g_winInfo.keyboard.rate) != 2) || + (g_winInfo.keyboard.delay < 1) || + (g_winInfo.keyboard.rate == 0) || + (1000 / g_winInfo.keyboard.rate) < 1) + { + winErrorFVerb (2, "\"%s\" is not a valid AutoRepeat value", s); + xfree(s); + return FALSE; + } + xfree(s); + winMsg (X_CONFIG, "AutoRepeat: %ld %ld\n", + g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); + } +#endif + +#ifdef XKB + from = X_DEFAULT; + if (g_cmdline.noXkbExtension) + { + from = X_CMDLINE; + g_winInfo.xkb.disable = TRUE; + } +#ifdef XWIN_XF86CONFIG + else if (kbd->inp_option_lst) + { + int b = winSetBoolOption (kbd->inp_option_lst, "XkbDisable", FALSE); + if (b) + { + from = X_CONFIG; + g_winInfo.xkb.disable = TRUE; + } + } +#endif + if (g_winInfo.xkb.disable) + { + winMsg (from, "XkbExtension disabled\n"); + } + else + { + s = NULL; + if (g_cmdline.xkbRules) + { + s = g_cmdline.xkbRules; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.rules = NULL_IF_EMPTY (s); + winMsg (from, "XKB: rules: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbModel) + { + s = g_cmdline.xkbModel; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.model = NULL_IF_EMPTY (s); + winMsg (from, "XKB: model: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbLayout) + { + s = g_cmdline.xkbLayout; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.layout = NULL_IF_EMPTY (s); + winMsg (from, "XKB: layout: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbVariant) + { + s = g_cmdline.xkbVariant; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.variant = NULL_IF_EMPTY (s); + winMsg (from, "XKB: variant: \"%s\"\n", s); + } + + s = NULL; + if (g_cmdline.xkbOptions) + { + s = g_cmdline.xkbOptions; + from = X_CMDLINE; + } +#ifdef XWIN_XF86CONFIG + else + { + s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL); + from = X_CONFIG; + } +#endif + if (s) + { + g_winInfo.xkb.options = NULL_IF_EMPTY (s); + winMsg (from, "XKB: options: \"%s\"\n", s); + } + +#ifdef XWIN_XF86CONFIG + from = X_CMDLINE; + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbKeymap", NULL))) + { + g_winInfo.xkb.keymap = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: keymap: \"%s\" " + " (overrides other XKB settings)\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbCompat", NULL))) + { + g_winInfo.xkb.compat = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: compat: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbTypes", NULL))) + { + g_winInfo.xkb.types = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: types: \"%s\"\n", s); + } + + if ((s = + winSetStrOption (kbd->inp_option_lst, "XkbKeycodes", NULL))) + { + g_winInfo.xkb.keycodes = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: keycodes: \"%s\"\n", s); + } + + if ((s = + winSetStrOption (kbd->inp_option_lst, "XkbGeometry", NULL))) + { + g_winInfo.xkb.geometry = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: geometry: \"%s\"\n", s); + } + + if ((s = winSetStrOption (kbd->inp_option_lst, "XkbSymbols", NULL))) + { + g_winInfo.xkb.symbols = NULL_IF_EMPTY (s); + winMsg (X_CONFIG, "XKB: symbols: \"%s\"\n", s); + } +#endif +#endif + } +#ifdef XWIN_XF86CONFIG + } +#endif + + return TRUE; +} + + +#ifdef XWIN_XF86CONFIG +Bool +winConfigMouse (DeviceIntPtr pDevice) +{ + MessageType mousefrom = X_CONFIG; + + XF86ConfInputPtr mouse = NULL; + XF86ConfInputPtr input_list = NULL; + + if (g_cmdline.mouse) + mousefrom = X_CMDLINE; + + if (g_xf86configptr != NULL) + input_list = g_xf86configptr->conf_input_lst; + + while (input_list != NULL) + { + if (winNameCompare (input_list->inp_driver, "mouse") == 0) + { + /* Check if device name matches requested name */ + if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier, + g_cmdline.mouse)) + continue; + mouse = input_list; + } + input_list = input_list->list.next; + } + + if (mouse != NULL) + { + if (mouse->inp_identifier) + winMsg (mousefrom, "Using pointer \"%s\" as primary pointer\n", + mouse->inp_identifier); + + g_winInfo.pointer.emulate3Buttons = + winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE); + if (g_cmdline.emulate3buttons) + g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; + + g_winInfo.pointer.emulate3Timeout = + winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50); + if (g_cmdline.emulate3timeout) + g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; + } + else + { + winMsg (X_ERROR, "No primary pointer configured\n"); + winMsg (X_DEFAULT, "Using compiletime defaults for pointer\n"); + } + + return TRUE; +} + + +Bool +winConfigFiles () +{ + MessageType from; + XF86ConfFilesPtr filesptr = NULL; + + /* set some shortcuts */ + if (g_xf86configptr != NULL) + { + filesptr = g_xf86configptr->conf_files; + } + + + /* Fontpath */ + from = X_DEFAULT; + + if (g_cmdline.fontPath) + { + from = X_CMDLINE; + defaultFontPath = g_cmdline.fontPath; + } + else if (filesptr != NULL && filesptr->file_fontpath) + { + from = X_CONFIG; + defaultFontPath = xstrdup (filesptr->file_fontpath); + } + winMsg (from, "FontPath set to \"%s\"\n", defaultFontPath); + + return TRUE; +} +#else +Bool +winConfigFiles () +{ + MessageType from; + + /* Fontpath */ + if (g_cmdline.fontPath) + { + defaultFontPath = g_cmdline.fontPath; + winMsg (X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath); + } + + return TRUE; +} +#endif + + +Bool +winConfigOptions () +{ + return TRUE; +} + + +Bool +winConfigScreens () +{ + return TRUE; +} + + +#ifdef XWIN_XF86CONFIG +char * +winSetStrOption (pointer optlist, const char *name, char *deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_STRING; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.str; + if (deflt) + return xstrdup (deflt); + else + return NULL; +} + + +int +winSetBoolOption (pointer optlist, const char *name, int deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_BOOLEAN; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.bool; + return deflt; +} + + +int +winSetIntOption (pointer optlist, const char *name, int deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_INTEGER; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.num; + return deflt; +} + + +double +winSetRealOption (pointer optlist, const char *name, double deflt) +{ + OptionInfoRec o; + + o.name = name; + o.type = OPTV_REAL; + if (ParseOptionValue (-1, optlist, &o)) + deflt = o.value.realnum; + return deflt; +} +#endif + + +/* + * Compare two strings for equality. This is caseinsensitive and + * The characters '_', ' ' (space) and '\t' (tab) are treated as + * not existing. + */ + +int +winNameCompare (const char *s1, const char *s2) +{ + char c1, c2; + + if (!s1 || *s1 == 0) + { + if (!s2 || *s2 == 0) + return 0; + else + return 1; + } + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + + while (c1 == c2) + { + if (c1 == 0) + return 0; + s1++; + s2++; + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + } + return (c1 - c2); +} + + +#ifdef XWIN_XF86CONFIG +/* + * Find the named option in the list. + * @return the pointer to the option record, or NULL if not found. + */ + +XF86OptionPtr +winFindOption (XF86OptionPtr list, const char *name) +{ + while (list) + { + if (winNameCompare (list->opt_name, name) == 0) + return list; + list = list->list.next; + } + return NULL; +} + + +/* + * Find the Value of an named option. + * @return The option value or NULL if not found. + */ + +char * +winFindOptionValue (XF86OptionPtr list, const char *name) +{ + list = winFindOption (list, name); + if (list) + { + if (list->opt_val) + return (list->opt_val); + else + return ""; + } + return (NULL); +} + + +/* + * Parse the option. + */ + +static Bool +ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p) +{ + char *s, *end; + + if ((s = winFindOptionValue (options, p->name)) != NULL) + { + switch (p->type) + { + case OPTV_INTEGER: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + else + { + p->value.num = strtoul (s, &end, 0); + if (*end == '\0') + { + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires an integer value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_STRING: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires an string value\n", p->name); + p->found = FALSE; + } + else + { + p->value.str = s; + p->found = TRUE; + } + break; + case OPTV_ANYSTR: + p->value.str = s; + p->found = TRUE; + break; + case OPTV_REAL: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + else + { + p->value.realnum = strtod (s, &end); + if (*end == '\0') + { + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a floating point value\n", + p->name); + p->found = FALSE; + } + } + break; + case OPTV_BOOLEAN: + if (GetBoolValue (p, s)) + { + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", p->name); + p->found = FALSE; + } + break; + case OPTV_FREQ: + if (*s == '\0') + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + else + { + double freq = strtod (s, &end); + int units = 0; + + if (end != s) + { + p->found = TRUE; + if (!winNameCompare (end, "Hz")) + units = 1; + else if (!winNameCompare (end, "kHz") || + !winNameCompare (end, "k")) + units = 1000; + else if (!winNameCompare (end, "MHz") || + !winNameCompare (end, "M")) + units = 1000000; + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + freq *= (double) units; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a frequency value\n", + p->name); + p->found = FALSE; + } + if (p->found) + { + p->value.freq.freq = freq; + p->value.freq.units = units; + } + } + break; + case OPTV_NONE: + /* Should never get here */ + p->found = FALSE; + break; + } + if (p->found) + { + winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name); + if (!(p->type == OPTV_BOOLEAN && *s == 0)) + { + winErrorFVerb (2, " \"%s\"", s); + } + winErrorFVerb (2, "\n"); + } + } + else if (p->type == OPTV_BOOLEAN) + { + /* Look for matches with options with or without a "No" prefix. */ + char *n, *newn; + OptionInfoRec opt; + + n = winNormalizeName (p->name); + if (!n) + { + p->found = FALSE; + return FALSE; + } + if (strncmp (n, "no", 2) == 0) + { + newn = n + 2; + } + else + { + free (n); + n = malloc (strlen (p->name) + 2 + 1); + if (!n) + { + p->found = FALSE; + return FALSE; + } + strcpy (n, "No"); + strcat (n, p->name); + newn = n; + } + if ((s = winFindOptionValue (options, newn)) != NULL) + { + if (GetBoolValue (&opt, s)) + { + p->value.bool = !opt.value.bool; + p->found = TRUE; + } + else + { + winDrvMsg (scrnIndex, X_WARNING, + "Option \"%s\" requires a boolean value\n", newn); + p->found = FALSE; + } + } + else + { + p->found = FALSE; + } + if (p->found) + { + winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); + if (*s != 0) + { + winErrorFVerb (2, " \"%s\"", s); + } + winErrorFVerb (2, "\n"); + } + free (n); + } + else + { + p->found = FALSE; + } + return p->found; +} + + +static Bool +configLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, + char *default_layout) +{ +#if 0 +#pragma warn UNIMPLEMENTED +#endif + return TRUE; +} + + +static Bool +configImpliedLayout (serverLayoutPtr servlayoutp, + XF86ConfScreenPtr conf_screen) +{ +#if 0 +#pragma warn UNIMPLEMENTED +#endif + return TRUE; +} + + +static Bool +GetBoolValue (OptionInfoPtr p, const char *s) +{ + if (*s == 0) + { + p->value.bool = TRUE; + } + else + { + if (winNameCompare (s, "1") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "on") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "true") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "yes") == 0) + p->value.bool = TRUE; + else if (winNameCompare (s, "0") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "off") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "false") == 0) + p->value.bool = FALSE; + else if (winNameCompare (s, "no") == 0) + p->value.bool = FALSE; + } + return TRUE; +} +#endif + + +char * +winNormalizeName (const char *s) +{ + char *ret, *q; + const char *p; + + if (s == NULL) + return NULL; + + ret = malloc (strlen (s) + 1); + for (p = s, q = ret; *p != 0; p++) + { + switch (*p) + { + case '_': + case ' ': + case '\t': + continue; + default: + if (isupper (*p)) + *q++ = tolower (*p); + else + *q++ = *p; + } + } + *q = '\0'; + return ret; +} + diff --git a/hw/xwin/winconfig.h b/hw/xwin/winconfig.h new file mode 100644 index 000000000..4b56d639c --- /dev/null +++ b/hw/xwin/winconfig.h @@ -0,0 +1,343 @@ +#ifndef __WIN_CONFIG_H__ +#define __WIN_CONFIG_H__ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Alexander Gottwald + */ + +#include "win.h" +#ifdef XWIN_XF86CONFIG +#include "../xfree86/parser/xf86Parser.h" +#endif + + +/* These are taken from hw/xfree86/common/xf86str.h */ + +typedef struct +{ + CARD32 red, green, blue; +} +rgb; + + +typedef struct +{ + float red, green, blue; +} +Gamma; + + +typedef struct +{ + char *identifier; + char *vendor; + char *board; + char *chipset; + char *ramdac; + char *driver; + struct _confscreenrec *myScreenSection; + Bool claimed; + Bool active; + Bool inUse; + int videoRam; + int textClockFreq; + pointer options; + int screen; /* For multi-CRTC cards */ +} +GDevRec, *GDevPtr; + + +typedef struct +{ + char *identifier; + char *driver; + pointer commonOptions; + pointer extraOptions; +} +IDevRec, *IDevPtr; + + +typedef struct +{ + int frameX0; + int frameY0; + int virtualX; + int virtualY; + int depth; + int fbbpp; + rgb weight; + rgb blackColour; + rgb whiteColour; + int defaultVisual; + char **modes; + pointer options; +} +DispRec, *DispPtr; + + +typedef struct _confxvportrec +{ + char *identifier; + pointer options; +} +confXvPortRec, *confXvPortPtr; + + +typedef struct _confxvadaptrec +{ + char *identifier; + int numports; + confXvPortPtr ports; + pointer options; +} +confXvAdaptorRec, *confXvAdaptorPtr; + + +typedef struct _confscreenrec +{ + char *id; + int screennum; + int defaultdepth; + int defaultbpp; + int defaultfbbpp; + GDevPtr device; + int numdisplays; + DispPtr displays; + int numxvadaptors; + confXvAdaptorPtr xvadaptors; + pointer options; +} +confScreenRec, *confScreenPtr; + + +typedef enum +{ + PosObsolete = -1, + PosAbsolute = 0, + PosRightOf, + PosLeftOf, + PosAbove, + PosBelow, + PosRelative +} +PositionType; + + +typedef struct _screenlayoutrec +{ + confScreenPtr screen; + char *topname; + confScreenPtr top; + char *bottomname; + confScreenPtr bottom; + char *leftname; + confScreenPtr left; + char *rightname; + confScreenPtr right; + PositionType where; + int x; + int y; + char *refname; + confScreenPtr refscreen; +} +screenLayoutRec, *screenLayoutPtr; + + +typedef struct _serverlayoutrec +{ + char *id; + screenLayoutPtr screens; + GDevPtr inactives; + IDevPtr inputs; + pointer options; +} +serverLayoutRec, *serverLayoutPtr; + + +/* + * winconfig.c + */ + +typedef struct +{ + /* Files */ +#ifdef XWIN_XF86CONFIG + char *configFile; +#endif + char *fontPath; + /* input devices - keyboard */ +#ifdef XWIN_XF86CONFIG + char *keyboard; +#endif +#ifdef XKB + Bool noXkbExtension; + char *xkbMap; + char *xkbRules; + char *xkbModel; + char *xkbLayout; + char *xkbVariant; + char *xkbOptions; +#endif + /* layout */ + char *screenname; + /* mouse settings */ + char *mouse; + Bool emulate3buttons; + long emulate3timeout; +} +WinCmdlineRec, *WinCmdlinePtr; + + +extern WinCmdlineRec g_cmdline; +#ifdef XWIN_XF86CONFIG +extern XF86ConfigPtr g_xf86configptr; +#endif +extern serverLayoutRec g_winConfigLayout; + + +/* + * Function prototypes + */ + +Bool winReadConfigfile (void); +Bool winConfigFiles (void); +Bool winConfigOptions (void); +Bool winConfigScreens (void); +Bool winConfigKeyboard (DeviceIntPtr pDevice); +Bool winConfigMouse (DeviceIntPtr pDevice); + + +typedef struct +{ + double freq; + int units; +} +OptFrequency; + + +typedef union +{ + unsigned long num; + char *str; + double realnum; + Bool bool; + OptFrequency freq; +} +ValueUnion; + + +typedef enum +{ + OPTV_NONE = 0, + OPTV_INTEGER, + OPTV_STRING, /* a non-empty string */ + OPTV_ANYSTR, /* Any string, including an empty one */ + OPTV_REAL, + OPTV_BOOLEAN, + OPTV_FREQ +} +OptionValueType; + + +typedef enum +{ + OPTUNITS_HZ = 1, + OPTUNITS_KHZ, + OPTUNITS_MHZ +} +OptFreqUnits; + + +typedef struct +{ + int token; + const char *name; + OptionValueType type; + ValueUnion value; + Bool found; +} +OptionInfoRec, *OptionInfoPtr; + + +/* + * Function prototypes + */ + +char *winSetStrOption (pointer optlist, const char *name, char *deflt); +int winSetBoolOption (pointer optlist, const char *name, int deflt); +int winSetIntOption (pointer optlist, const char *name, int deflt); +double winSetRealOption (pointer optlist, const char *name, double deflt); +#ifdef XWIN_XF86CONFIG +XF86OptionPtr winFindOption (XF86OptionPtr list, const char *name); +char *winFindOptionValue (XF86OptionPtr list, const char *name); +#endif +int winNameCompare (const char *s1, const char *s2); +char *winNormalizeName (const char *s); + + +typedef struct +{ + struct + { + long leds; + long delay; + long rate; + } + keyboard; +#ifdef XKB + struct + { + Bool disable; + char *rules; + char *model; + char *layout; + char *variant; + char *options; + char *initialMap; + char *keymap; + char *types; + char *compat; + char *keycodes; + char *symbols; + char *geometry; + } + xkb; +#endif + struct + { + Bool emulate3Buttons; + long emulate3Timeout; + } + pointer; +} +winInfoRec, *winInfoPtr; + + +extern winInfoRec g_winInfo; + +#endif diff --git a/hw/xwin/wincreatewnd.c b/hw/xwin/wincreatewnd.c new file mode 100644 index 000000000..796a08593 --- /dev/null +++ b/hw/xwin/wincreatewnd.c @@ -0,0 +1,644 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include "shellapi.h" + +#ifndef ABS_AUTOHIDE +#define ABS_AUTOHIDE 1 +#endif + +/* + * Local function prototypes + */ + +static Bool +winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo); + +static Bool +winAdjustForAutoHide (RECT *prcWorkArea); + + +/* + * Create a full screen window + */ + +Bool +winCreateBoundingWindowFullScreen (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + int iX = pScreenInfo->dwInitialX; + int iY = pScreenInfo->dwInitialY; + int iWidth = pScreenInfo->dwWidth; + int iHeight = pScreenInfo->dwHeight; + HWND *phwnd = &pScreenPriv->hwndScreen; + WNDCLASS wc; + char szTitle[256]; + +#if CYGDEBUG + winDebug ("winCreateBoundingWindowFullScreen\n"); +#endif + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hCursor = 0; + wc.hbrBackground = 0; + wc.lpszMenuName = NULL; + wc.lpszClassName = WINDOW_CLASS; + RegisterClass (&wc); + + /* Set display and screen-specific tooltip text */ + if (g_pszQueryHost != NULL) + snprintf (szTitle, + sizeof (szTitle), + WINDOW_TITLE_XDMCP, + g_pszQueryHost); + else + snprintf (szTitle, + sizeof (szTitle), + WINDOW_TITLE, + display, + (int) pScreenInfo->dwScreen); + + /* Create the window */ + *phwnd = CreateWindowExA (0, /* Extended styles */ + WINDOW_CLASS, /* Class name */ + szTitle, /* Window name */ + WS_POPUP, + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL),/* Instance handle */ + pScreenPriv); /* ScreenPrivates */ + + /* Branch on the server engine */ + switch (pScreenInfo->dwEngine) + { +#ifdef XWIN_NATIVEGDI + case WIN_SERVER_SHADOW_GDI: + /* Show the window */ + ShowWindow (*phwnd, SW_SHOWMAXIMIZED); + break; +#endif + + default: + /* Hide the window */ + ShowWindow (*phwnd, SW_SHOWNORMAL); + break; + } + + /* Send first paint message */ + UpdateWindow (*phwnd); + + /* Attempt to bring our window to the top of the display */ + BringWindowToTop (*phwnd); + + return TRUE; +} + + +/* + * Create our primary Windows display window + */ + +Bool +winCreateBoundingWindowWindowed (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + int iWidth = pScreenInfo->dwUserWidth; + int iHeight = pScreenInfo->dwUserHeight; + int iPosX; + int iPosY; + HWND *phwnd = &pScreenPriv->hwndScreen; + WNDCLASS wc; + RECT rcClient, rcWorkArea; + DWORD dwWindowStyle; + BOOL fForceShowWindow = FALSE; + char szTitle[256]; + + winDebug ("winCreateBoundingWindowWindowed - User w: %d h: %d\n", + (int) pScreenInfo->dwUserWidth, (int) pScreenInfo->dwUserHeight); + winDebug ("winCreateBoundingWindowWindowed - Current w: %d h: %d\n", + (int) pScreenInfo->dwWidth, (int) pScreenInfo->dwHeight); + + /* Set the common window style flags */ + dwWindowStyle = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX; + + /* Decorated or undecorated window */ + if (pScreenInfo->fDecoration +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif + && !pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + && !pScreenInfo->fMultiWindow +#endif + ) + { + /* Try to handle startup via run.exe. run.exe instructs Windows to + * hide all created windows. Detect this case and make sure the + * window is shown nevertheless */ + STARTUPINFO startupInfo; + GetStartupInfo(&startupInfo); + if (startupInfo.dwFlags & STARTF_USESHOWWINDOW && + startupInfo.wShowWindow == SW_HIDE) + { + fForceShowWindow = TRUE; + } + dwWindowStyle |= WS_CAPTION; + if (pScreenInfo->fScrollbars) + dwWindowStyle |= WS_THICKFRAME | WS_MAXIMIZEBOX; + } + else + dwWindowStyle |= WS_POPUP; + + /* Setup our window class */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = WINDOW_CLASS; + RegisterClass (&wc); + + /* Get size of work area */ + winGetWorkArea (&rcWorkArea, pScreenInfo); + + /* Adjust for auto-hide taskbars */ + winAdjustForAutoHide (&rcWorkArea); + + /* Did the user specify a position? */ + if (pScreenInfo->fUserGavePosition) + { + iPosX = pScreenInfo->dwInitialX; + iPosY = pScreenInfo->dwInitialY; + } + else + { + iPosX = rcWorkArea.left; + iPosY = rcWorkArea.top; + } + + /* Did the user specify a height and width? */ + if (pScreenInfo->fUserGaveHeightAndWidth) + { + /* User gave a desired height and width, try to accomodate */ +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - User gave height " + "and width\n"); +#endif + + /* Adjust the window width and height for borders and title bar */ + if (pScreenInfo->fDecoration +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif + && !pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + && !pScreenInfo->fMultiWindow +#endif + ) + { +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - Window has decoration\n"); +#endif + /* Are we using scrollbars? */ + if (pScreenInfo->fScrollbars) + { +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - Window has " + "scrollbars\n"); +#endif + + iWidth += 2 * GetSystemMetrics (SM_CXSIZEFRAME); + iHeight += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + + GetSystemMetrics (SM_CYCAPTION); + } + else + { +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - Window does not have " + "scrollbars\n"); +#endif + + iWidth += 2 * GetSystemMetrics (SM_CXFIXEDFRAME); + iHeight += 2 * GetSystemMetrics (SM_CYFIXEDFRAME) + + GetSystemMetrics (SM_CYCAPTION); + } + } + } + else + { + /* By default, we are creating a window that is as large as possible */ +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - User did not give " + "height and width\n"); +#endif + /* Defaults are wrong if we have multiple monitors */ + if (pScreenInfo->fMultipleMonitors) + { + iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + } + } + + /* Clean up the scrollbars flag, if necessary */ + if ((!pScreenInfo->fDecoration +#ifdef XWIN_MULTIWINDOWEXTWM + || pScreenInfo->fMWExtWM +#endif + || pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + || pScreenInfo->fMultiWindow +#endif + ) + && pScreenInfo->fScrollbars) + { + /* We cannot have scrollbars if we do not have a window border */ + pScreenInfo->fScrollbars = FALSE; + } + + if (TRUE +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif +#ifdef XWIN_MULTIWINDOW + && !pScreenInfo->fMultiWindow +#endif + ) + { + /* Trim window width to fit work area */ + if (iWidth > (rcWorkArea.right - rcWorkArea.left)) + iWidth = rcWorkArea.right - rcWorkArea.left; + + /* Trim window height to fit work area */ + if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top)) + iHeight = rcWorkArea.bottom - rcWorkArea.top; + +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - Adjusted width: %d "\ + "height: %d\n", + iWidth, iHeight); +#endif + } + + /* Set display and screen-specific tooltip text */ + if (g_pszQueryHost != NULL) + snprintf (szTitle, + sizeof (szTitle), + WINDOW_TITLE_XDMCP, + g_pszQueryHost); + else + snprintf (szTitle, + sizeof (szTitle), + WINDOW_TITLE, + display, + (int) pScreenInfo->dwScreen); + + /* Create the window */ + *phwnd = CreateWindowExA (0, /* Extended styles */ + WINDOW_CLASS, /* Class name */ + szTitle, /* Window name */ + dwWindowStyle, + iPosX, /* Horizontal position */ + iPosY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL),/* Instance handle */ + pScreenPriv); /* ScreenPrivates */ + if (*phwnd == NULL) + { + ErrorF ("winCreateBoundingWindowWindowed - CreateWindowEx () failed\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n"); +#endif + + if (fForceShowWindow) + { + ErrorF("winCreateBoundingWindowWindowed - Setting normal windowstyle\n"); + ShowWindow(*phwnd, SW_SHOW); + } + + /* Get the client area coordinates */ + if (!GetClientRect (*phwnd, &rcClient)) + { + ErrorF ("winCreateBoundingWindowWindowed - GetClientRect () " + "failed\n"); + return FALSE; + } + + winDebug ("winCreateBoundingWindowWindowed - WindowClient " + "w %ld h %ld r %ld l %ld b %ld t %ld\n", + rcClient.right - rcClient.left, + rcClient.bottom - rcClient.top, + rcClient.right, rcClient.left, + rcClient.bottom, rcClient.top); + + /* We adjust the visual size if the user did not specify it */ + if (!(pScreenInfo->fScrollbars && pScreenInfo->fUserGaveHeightAndWidth)) + { + /* + * User did not give a height and width with scrollbars enabled, + * so we will resize the underlying visual to be as large as + * the initial view port (page size). This way scrollbars will + * not appear until the user shrinks the window, if they ever do. + * + * NOTE: We have to store the viewport size here because + * the user may have an autohide taskbar, which would + * cause the viewport size to be one less in one dimension + * than the viewport size that we calculated by subtracting + * the size of the borders and caption. + */ + pScreenInfo->dwWidth = rcClient.right - rcClient.left; + pScreenInfo->dwHeight = rcClient.bottom - rcClient.top; + } + +#if 0 + /* + * NOTE: For the uninitiated, the page size is the number of pixels + * that we can display in the x or y direction at a time and the + * range is the total number of pixels in the x or y direction that we + * have available to display. In other words, the page size is the + * size of the window area minus the space the caption, borders, and + * scrollbars (if any) occupy, and the range is the size of the + * underlying X visual. Notice that, contrary to what some of the + * MSDN Library arcticles lead you to believe, the windows + * ``client area'' size does not include the scrollbars. In other words, + * the whole client area size that is reported to you is drawable by + * you; you do not have to subtract the size of the scrollbars from + * the client area size, and if you did it would result in the size + * of the scrollbars being double counted. + */ + + /* Setup scrollbar page and range, if scrollbars are enabled */ + if (pScreenInfo->fScrollbars) + { + SCROLLINFO si; + + /* Initialize the scrollbar info structure */ + si.cbSize = sizeof (si); + si.fMask = SIF_RANGE | SIF_PAGE; + si.nMin = 0; + + /* Setup the width range and page size */ + si.nMax = pScreenInfo->dwWidth - 1; + si.nPage = rcClient.right - rcClient.left; + winDebug ("winCreateBoundingWindowWindowed - HORZ nMax: %d nPage :%d\n", + si.nMax, si.nPage); + SetScrollInfo (*phwnd, SB_HORZ, &si, TRUE); + + /* Setup the height range and page size */ + si.nMax = pScreenInfo->dwHeight - 1; + si.nPage = rcClient.bottom - rcClient.top; + winDebug ("winCreateBoundingWindowWindowed - VERT nMax: %d nPage :%d\n", + si.nMax, si.nPage); + SetScrollInfo (*phwnd, SB_VERT, &si, TRUE); + } +#endif + + /* Show the window */ + if (FALSE +#ifdef XWIN_MULTIWINDOWEXTWM + || pScreenInfo->fMWExtWM +#endif +#ifdef XWIN_MULTIWINDOW + || pScreenInfo->fMultiWindow +#endif + ) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + pScreenPriv->fRootWindowShown = FALSE; +#endif + ShowWindow (*phwnd, SW_HIDE); + } + else + ShowWindow (*phwnd, SW_SHOWNORMAL); + if (!UpdateWindow (*phwnd)) + { + ErrorF ("winCreateBoundingWindowWindowed - UpdateWindow () failed\n"); + return FALSE; + } + + /* Attempt to bring our window to the top of the display */ + if (TRUE +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif + && !pScreenInfo->fRootless +#ifdef XWIN_MULTIWINDOW + && !pScreenInfo->fMultiWindow +#endif + ) + { + if (!BringWindowToTop (*phwnd)) + { + ErrorF ("winCreateBoundingWindowWindowed - BringWindowToTop () " + "failed\n"); + return FALSE; + } + } + +#ifdef XWIN_NATIVEGDI + /* Paint window background blue */ + if (pScreenInfo->dwEngine == WIN_SERVER_NATIVE_GDI) + winPaintBackground (*phwnd, RGB (0x00, 0x00, 0xFF)); +#endif + + winDebug ("winCreateBoundingWindowWindowed - Returning\n"); + + return TRUE; +} + + +/* + * Find the work area of all attached monitors + */ + +static Bool +winGetWorkArea (RECT *prcWorkArea, winScreenInfo *pScreenInfo) +{ + int iPrimaryWidth, iPrimaryHeight; + int iWidth, iHeight; + int iLeft, iTop; + int iPrimaryNonWorkAreaWidth, iPrimaryNonWorkAreaHeight; + + /* SPI_GETWORKAREA only gets the work area of the primary screen. */ + SystemParametersInfo (SPI_GETWORKAREA, 0, prcWorkArea, 0); + + /* Bail out here if we aren't using multiple monitors */ + if (!pScreenInfo->fMultipleMonitors) + return TRUE; + + winDebug ("winGetWorkArea - Original WorkArea: %d %d %d %d\n", + (int) prcWorkArea->top, (int) prcWorkArea->left, + (int) prcWorkArea->bottom, (int) prcWorkArea->right); + + /* Get size of full virtual screen */ + iWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + iHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + + winDebug ("winGetWorkArea - Virtual screen is %d x %d\n", iWidth, iHeight); + + /* Get origin of full virtual screen */ + iLeft = GetSystemMetrics (SM_XVIRTUALSCREEN); + iTop = GetSystemMetrics (SM_YVIRTUALSCREEN); + + winDebug ("winGetWorkArea - Virtual screen origin is %d, %d\n", iLeft, iTop); + + /* Get size of primary screen */ + iPrimaryWidth = GetSystemMetrics (SM_CXSCREEN); + iPrimaryHeight = GetSystemMetrics (SM_CYSCREEN); + + winDebug ("winGetWorkArea - Primary screen is %d x %d\n", + iPrimaryWidth, iPrimaryHeight); + + /* Work out how much of the primary screen we aren't using */ + iPrimaryNonWorkAreaWidth = iPrimaryWidth - (prcWorkArea->right - + prcWorkArea->left); + iPrimaryNonWorkAreaHeight = iPrimaryHeight - (prcWorkArea->bottom + - prcWorkArea->top); + + /* Update the rectangle to include all monitors */ + if (iLeft < 0) + { + prcWorkArea->left = iLeft; + } + if (iTop < 0) + { + prcWorkArea->top = iTop; + } + prcWorkArea->right = prcWorkArea->left + iWidth - + iPrimaryNonWorkAreaWidth; + prcWorkArea->bottom = prcWorkArea->top + iHeight - + iPrimaryNonWorkAreaHeight; + + winDebug ("winGetWorkArea - Adjusted WorkArea for multiple " + "monitors: %d %d %d %d\n", + (int) prcWorkArea->top, (int) prcWorkArea->left, + (int) prcWorkArea->bottom, (int) prcWorkArea->right); + + return TRUE; +} + + +/* + * Adjust the client area so that any auto-hide toolbars + * will work correctly. + */ + +static Bool +winAdjustForAutoHide (RECT *prcWorkArea) +{ + APPBARDATA abd; + HWND hwndAutoHide; + + winDebug ("winAdjustForAutoHide - Original WorkArea: %d %d %d %d\n", + (int) prcWorkArea->top, (int) prcWorkArea->left, + (int) prcWorkArea->bottom, (int) prcWorkArea->right); + + /* Find out if the Windows taskbar is set to auto-hide */ + ZeroMemory (&abd, sizeof (abd)); + abd.cbSize = sizeof (abd); + if (SHAppBarMessage (ABM_GETSTATE, &abd) & ABS_AUTOHIDE) + winDebug ("winAdjustForAutoHide - Taskbar is auto hide\n"); + + /* Look for a TOP auto-hide taskbar */ + abd.uEdge = ABE_TOP; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + winDebug ("winAdjustForAutoHide - Found TOP auto-hide taskbar\n"); + prcWorkArea->top += 1; + } + + /* Look for a LEFT auto-hide taskbar */ + abd.uEdge = ABE_LEFT; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + winDebug ("winAdjustForAutoHide - Found LEFT auto-hide taskbar\n"); + prcWorkArea->left += 1; + } + + /* Look for a BOTTOM auto-hide taskbar */ + abd.uEdge = ABE_BOTTOM; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + winDebug ("winAdjustForAutoHide - Found BOTTOM auto-hide taskbar\n"); + prcWorkArea->bottom -= 1; + } + + /* Look for a RIGHT auto-hide taskbar */ + abd.uEdge = ABE_RIGHT; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETAUTOHIDEBAR, &abd); + if (hwndAutoHide != NULL) + { + winDebug ("winAdjustForAutoHide - Found RIGHT auto-hide taskbar\n"); + prcWorkArea->right -= 1; + } + + winDebug ("winAdjustForAutoHide - Adjusted WorkArea: %d %d %d %d\n", + (int) prcWorkArea->top, (int) prcWorkArea->left, + (int) prcWorkArea->bottom, (int) prcWorkArea->right); + +#if 0 + /* Obtain the task bar window dimensions */ + abd.hWnd = hwndAutoHide; + hwndAutoHide = (HWND) SHAppBarMessage (ABM_GETTASKBARPOS, &abd); + winDebug ("hwndAutoHide %08x abd.hWnd %08x %d %d %d %d\n", + hwndAutoHide, abd.hWnd, + abd.rc.top, abd.rc.left, abd.rc.bottom, abd.rc.right); +#endif + + return TRUE; +} diff --git a/hw/xwin/wincursor.c b/hw/xwin/wincursor.c new file mode 100644 index 000000000..021b8b82c --- /dev/null +++ b/hw/xwin/wincursor.c @@ -0,0 +1,614 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include "winmsg.h" +#include <cursorstr.h> +#include <mipointrst.h> +#include <servermd.h> + +extern Bool g_fSoftwareCursor; + + +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#define BYTE_COUNT(x) (((x) + 7) / 8) + +#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 (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 (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 we are active */ + if (pScreenPriv->hwndScreen == GetForegroundWindow ()) + { + /* 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 (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 (2, "winLoadCursor - Windows requires %dx%d cursor\n" + "\tbut 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 = BYTE_COUNT(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 = malloc (nBytes); + memset (pXor, 0x00, nBytes); + + /* Convert the X11 bitmap to a win32 bitmap + * The first is for an empty mask */ + if (pCursor->bits->emptyMask) + { + int x, y, xmax = BYTE_COUNT(nCX); + for (y = 0; y < nCY; ++y) + for (x = 0; x < xmax; ++x) + { + int nWinPix = BYTE_COUNT(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 = BYTE_COUNT(nCX); + for (y = 0; y < nCY; ++y) + for (x = 0; x < xmax; ++x) + { + int nWinPix = BYTE_COUNT(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; y<nCY; y++) + { + unsigned long *src, *dst; + src = &(pCursor->bits->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; y<pScreenPriv->cursor.sm_cy; y++) + { + for (x=0; x<pScreenPriv->cursor.sm_cx; x++) + { + if (x>=nCX || y>=nCY) /* Outside of X11 icon bounds */ + (*pCur++) = 0; + else /* Within X11 icon bounds */ + { + int nWinPix = BYTE_COUNT(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 (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(ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + + +/* + * winSetCursor + * Set the cursor sprite and position. + */ +static void +winSetCursor (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; + } + } +} + + +/* + * QuartzMoveCursor + * Move the cursor. This is a noop for us. + */ +static void +winMoveCursor (ScreenPtr pScreen, int x, int y) +{ +} + + +static miPointerSpriteFuncRec winSpriteFuncsRec = { + winRealizeCursor, + winUnrealizeCursor, + winSetCursor, + winMoveCursor +}; + + +/* +=========================================================================== + + 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/hw/xwin/windialogs.c b/hw/xwin/windialogs.c new file mode 100755 index 000000000..ab06b0d00 --- /dev/null +++ b/hw/xwin/windialogs.c @@ -0,0 +1,788 @@ +/* + *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 + * Earle F. Philhower III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#ifdef __CYGWIN__ +#include <sys/cygwin.h> +#endif +#include <shellapi.h> +#include "winprefs.h" + + +/* + * 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; + + +/* + * Local function prototypes + */ + +static wBOOL CALLBACK +winExitDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam); + +static wBOOL CALLBACK +winChangeDepthDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam); + +static wBOOL CALLBACK +winAboutDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam); + + +static void +winDrawURLWindow (LPARAM lParam); + +static LRESULT CALLBACK +winURLWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +static void +winOverrideURLButton (HWND hdlg, int id); + +static void +winUnoverrideURLButton (HWND hdlg, int id); + + +/* + * Owner-draw a button as a URL + */ + +static void +winDrawURLWindow (LPARAM lParam) +{ + DRAWITEMSTRUCT *draw; + char str[256]; + RECT rect; + HFONT font; + COLORREF crText; + + draw = (DRAWITEMSTRUCT *) lParam; + GetWindowText (draw->hwndItem, str, sizeof(str)); + str[255] = 0; + GetClientRect (draw->hwndItem, &rect); + + /* Color the button depending upon its state */ + if (draw->itemState & ODS_SELECTED) + crText = RGB(128+64,0,0); + else if (draw->itemState & ODS_FOCUS) + crText = RGB(0,128+64,0); + else + crText = RGB(0,0,128+64); + SetTextColor (draw->hDC, crText); + + /* Create underlined font 14 high, standard dialog font */ + font = CreateFont (-14, 0, 0, 0, FW_NORMAL, FALSE, TRUE, FALSE, + 0, 0, 0, 0, 0, "MS Sans Serif"); + if (!font) + { + ErrorF ("winDrawURLWindow: Unable to create URL font, bailing.\n"); + return; + } + /* Draw it */ + SetBkMode (draw->hDC, OPAQUE); + SelectObject (draw->hDC, font); + DrawText (draw->hDC, str, strlen (str),&rect,DT_CENTER | DT_VCENTER); + /* Delete the created font, replace it with stock font */ + DeleteObject (SelectObject (draw->hDC, GetStockObject (ANSI_VAR_FONT))); +} + + +/* + * WndProc for overridden buttons + */ + +static LRESULT CALLBACK +winURLWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC origCB = NULL; + HCURSOR cursor; + + /* If it's a SetCursor message, tell it to the hand */ + if (msg==WM_SETCURSOR) { + cursor = LoadCursor (NULL, IDC_HAND); + if (cursor) + SetCursor (cursor); + return TRUE; + } + origCB = (WNDPROC)GetWindowLong (hwnd, GWL_USERDATA); + /* Otherwise fall through to original WndProc */ + if (origCB) + return CallWindowProc (origCB, hwnd, msg, wParam, lParam); + else + return FALSE; +} + + +/* + * Register and unregister the custom WndProc + */ + +static void +winOverrideURLButton (HWND hwnd, int id) +{ + WNDPROC origCB; + origCB = (WNDPROC)SetWindowLong (GetDlgItem (hwnd, id), + GWL_WNDPROC, (LONG)winURLWndProc); + SetWindowLong (GetDlgItem (hwnd, id), GWL_USERDATA, (LONG)origCB); +} + +static void +winUnoverrideURLButton (HWND hwnd, int id) +{ + WNDPROC origCB; + origCB = (WNDPROC)SetWindowLong (GetDlgItem (hwnd, id), + GWL_USERDATA, 0); + if (origCB) + SetWindowLong (GetDlgItem (hwnd, id), GWL_WNDPROC, (LONG)origCB); +} + + +/* + * Center a dialog window in the desktop window + */ + +static void +winCenterDialog (HWND hwndDlg) +{ + HWND hwndDesk; + RECT rc, rcDlg, rcDesk; + + hwndDesk = GetParent (hwndDlg); + if (!hwndDesk || IsIconic (hwndDesk)) + hwndDesk = GetDesktopWindow (); + + GetWindowRect (hwndDesk, &rcDesk); + GetWindowRect (hwndDlg, &rcDlg); + CopyRect (&rc, &rcDesk); + + OffsetRect (&rcDlg, -rcDlg.left, -rcDlg.top); + OffsetRect (&rc, -rc.left, -rc.top); + OffsetRect (&rc, -rcDlg.right, -rcDlg.bottom); + + SetWindowPos (hwndDlg, + HWND_TOP, + rcDesk.left + (rc.right / 2), + rcDesk.top + (rc.bottom / 2), + 0, 0, + SWP_NOSIZE | SWP_NOZORDER); +} + + +/* + * Display the Exit dialog box + */ + +void +winDisplayExitDialog (winPrivScreenPtr pScreenPriv) +{ + int i; + int liveClients = 0; + + /* Count up running clinets (clients[0] is serverClient) */ + for (i = 1; i < currentMaxClients; i++) + if (clients[i] != NullClient) + liveClients++; +#if defined(XWIN_MULTIWINDOW) + /* Count down server internal clients */ + if (pScreenPriv->pScreenInfo->fMultiWindow) + liveClients -= 2; /* multiwindow window manager & XMsgProc */ +#endif +#if defined(XWIN_CLIPBOARD) + if (g_fClipboardStarted) + liveClients--; /* clipboard manager */ +#endif + + /* A user reported that this sometimes drops below zero. just eye-candy. */ + if (liveClients < 0) + liveClients = 0; + + /* Don't show the exit confirmation dialog if SilentExit is enabled */ + if (pref.fSilentExit && liveClients <= 0) + { + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + PostMessage (pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); + return; + } + + pScreenPriv->iConnectedClients = liveClients; + + /* Check if dialog already exists */ + if (g_hDlgExit != NULL) + { + /* Dialog box already exists, display it */ + ShowWindow (g_hDlgExit, SW_SHOWDEFAULT); + + /* User has lost the dialog. Show them where it is. */ + SetForegroundWindow (g_hDlgExit); + + return; + } + + /* Create dialog box */ + g_hDlgExit = CreateDialogParam (g_hInstance, + "EXIT_DIALOG", + pScreenPriv->hwndScreen, + winExitDlgProc, + (int) pScreenPriv); + + /* Drop minimize and maximize buttons */ + SetWindowLong (g_hDlgExit, GWL_STYLE, + GetWindowLong (g_hDlgExit, GWL_STYLE) + & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); + SetWindowLong (g_hDlgExit, GWL_EXSTYLE, + GetWindowLong (g_hDlgExit, GWL_EXSTYLE) & ~WS_EX_APPWINDOW ); + SetWindowPos (g_hDlgExit, HWND_TOPMOST, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); + + /* Show the dialog box */ + ShowWindow (g_hDlgExit, SW_SHOW); + + /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ + SetForegroundWindow (g_hDlgExit); + + /* Set focus to the Cancel button */ + PostMessage (g_hDlgExit, WM_NEXTDLGCTL, + (int) GetDlgItem (g_hDlgExit, IDCANCEL), TRUE); +} + +#define CONNECTED_CLIENTS_FORMAT "There are currently %d clients connected." + + +/* + * Exit dialog window procedure + */ + +static wBOOL CALLBACK +winExitDlgProc (HWND hDialog, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + + /* Branch on message type */ + switch (message) + { + case WM_INITDIALOG: + { + char *pszConnectedClients; + + /* Store pointers to private structures for future use */ + s_pScreenPriv = (winPrivScreenPtr) lParam; + + winCenterDialog (hDialog); + + /* Set icon to standard app icon */ + PostMessage (hDialog, + WM_SETICON, + ICON_SMALL, + (LPARAM) LoadIcon (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN))); + + /* Format the connected clients string */ + pszConnectedClients = Xprintf (CONNECTED_CLIENTS_FORMAT, + s_pScreenPriv->iConnectedClients); + if (!pszConnectedClients) + return TRUE; + + + + /* Set the number of connected clients */ + SetWindowText (GetDlgItem (hDialog, IDC_CLIENTS_CONNECTED), + pszConnectedClients); + xfree (pszConnectedClients); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDOK: + /* Send message to call the GiveUp function */ + PostMessage (s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + + case IDCANCEL: + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + } + break; + + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + /* Show the cursor if it is hidden */ + if (g_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + return TRUE; + + case WM_CLOSE: + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + } + + return FALSE; +} + + +/* + * Display the Depth Change dialog box + */ + +void +winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv) +{ + /* Check if dialog already exists */ + if (g_hDlgDepthChange != NULL) + { + /* Dialog box already exists, display it */ + ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); + + /* User has lost the dialog. Show them where it is. */ + SetForegroundWindow (g_hDlgDepthChange); + + return; + } + + /* + * Display a notification to the user that the visual + * will not be displayed until the Windows display depth + * is restored to the original value. + */ + g_hDlgDepthChange = CreateDialogParam (g_hInstance, + "DEPTH_CHANGE_BOX", + pScreenPriv->hwndScreen, + winChangeDepthDlgProc, + (int) pScreenPriv); + + /* Drop minimize and maximize buttons */ + SetWindowLong (g_hDlgDepthChange, GWL_STYLE, + GetWindowLong (g_hDlgDepthChange, GWL_STYLE) + & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); + SetWindowLong (g_hDlgDepthChange, GWL_EXSTYLE, + GetWindowLong (g_hDlgDepthChange, GWL_EXSTYLE) + & ~WS_EX_APPWINDOW ); + SetWindowPos (g_hDlgDepthChange, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE); + + /* Show the dialog box */ + ShowWindow (g_hDlgDepthChange, SW_SHOW); + + ErrorF ("winDisplayDepthChangeDialog - DialogBox returned: %d\n", + (int) g_hDlgDepthChange); + ErrorF ("winDisplayDepthChangeDialog - GetLastError: %d\n", + (int) GetLastError ()); + + /* Minimize the display window */ + ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); +} + + +/* + * Process messages for the dialog that is displayed for + * disruptive screen depth changes. + */ + +static wBOOL CALLBACK +winChangeDepthDlgProc (HWND hwndDialog, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + +#if CYGDEBUG + winDebug ("winChangeDepthDlgProc\n"); +#endif + + /* Branch on message type */ + switch (message) + { + case WM_INITDIALOG: +#if CYGDEBUG + winDebug ("winChangeDepthDlgProc - WM_INITDIALOG\n"); +#endif + + /* Store pointers to private structures for future use */ + s_pScreenPriv = (winPrivScreenPtr) lParam; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + +#if CYGDEBUG + winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - s_pScreenPriv: %08x, " + "s_pScreenInfo: %08x, s_pScreen: %08x\n", + s_pScreenPriv, s_pScreenInfo, s_pScreen); +#endif + +#if CYGDEBUG + winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, " + "last bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel); +#endif + + winCenterDialog( hwndDialog ); + + /* Set icon to standard app icon */ + PostMessage (hwndDialog, + WM_SETICON, + ICON_SMALL, + (LPARAM) LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN))); + + return TRUE; + + case WM_DISPLAYCHANGE: +#if CYGDEBUG + winDebug ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, " + "last bpp: %d, new bpp: %d\n", + s_pScreenInfo->dwBPP, + s_pScreenPriv->dwLastWindowsBitsPixel, + wParam); +#endif + + /* Dismiss the dialog if the display returns to the original depth */ + if (wParam == s_pScreenInfo->dwBPP) + { + ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n"); + + /* Depth has been restored, dismiss dialog */ + DestroyWindow (g_hDlgDepthChange); + g_hDlgDepthChange = NULL; + + /* Flag that we have a valid screen depth */ + s_pScreenPriv->fBadDepth = FALSE; + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDOK: + case IDCANCEL: + ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); + + /* + * User dismissed the dialog, hide it until the + * display mode is restored. + */ + ShowWindow (g_hDlgDepthChange, SW_HIDE); + return TRUE; + } + break; + + case WM_CLOSE: + ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n"); + + DestroyWindow (g_hDlgAbout); + g_hDlgAbout = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + return TRUE; + } + + return FALSE; +} + + +/* + * Display the About dialog box + */ + +void +winDisplayAboutDialog (winPrivScreenPtr pScreenPriv) +{ + /* Check if dialog already exists */ + if (g_hDlgAbout != NULL) + { + /* Dialog box already exists, display it */ + ShowWindow (g_hDlgAbout, SW_SHOWDEFAULT); + + /* User has lost the dialog. Show them where it is. */ + SetForegroundWindow (g_hDlgAbout); + + return; + } + + /* + * Display the about box + */ + g_hDlgAbout = CreateDialogParam (g_hInstance, + "ABOUT_BOX", + pScreenPriv->hwndScreen, + winAboutDlgProc, + (int) pScreenPriv); + + /* Drop minimize and maximize buttons */ + SetWindowLong (g_hDlgAbout, GWL_STYLE, + GetWindowLong (g_hDlgAbout, GWL_STYLE) + & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); + SetWindowLong (g_hDlgAbout, GWL_EXSTYLE, + GetWindowLong (g_hDlgAbout, GWL_EXSTYLE) & ~WS_EX_APPWINDOW); + SetWindowPos (g_hDlgAbout, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); + + /* Show the dialog box */ + ShowWindow (g_hDlgAbout, SW_SHOW); + + /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ + SetForegroundWindow (g_hDlgAbout); + + /* Set focus to the OK button */ + PostMessage (g_hDlgAbout, WM_NEXTDLGCTL, + (int) GetDlgItem (g_hDlgAbout, IDOK), TRUE); +} + + +/* + * Process messages for the about dialog. + */ + +static wBOOL CALLBACK +winAboutDlgProc (HWND hwndDialog, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static winPrivScreenPtr s_pScreenPriv = NULL; + static winScreenInfo *s_pScreenInfo = NULL; + static ScreenPtr s_pScreen = NULL; + +#if CYGDEBUG + winDebug ("winAboutDlgProc\n"); +#endif + + /* Branch on message type */ + switch (message) + { + case WM_INITDIALOG: +#if CYGDEBUG + winDebug ("winAboutDlgProc - WM_INITDIALOG\n"); +#endif + + /* Store pointers to private structures for future use */ + s_pScreenPriv = (winPrivScreenPtr) lParam; + s_pScreenInfo = s_pScreenPriv->pScreenInfo; + s_pScreen = s_pScreenInfo->pScreen; + + winCenterDialog (hwndDialog); + + /* Set icon to standard app icon */ + PostMessage (hwndDialog, + WM_SETICON, + ICON_SMALL, + (LPARAM) LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN))); + + /* Override the URL buttons */ + winOverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); + winOverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); + winOverrideURLButton (hwndDialog, ID_ABOUT_UG); + winOverrideURLButton (hwndDialog, ID_ABOUT_FAQ); + + return TRUE; + + case WM_DRAWITEM: + /* Draw the URL buttons as needed */ + winDrawURLWindow (lParam); + return TRUE; + + case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: + /* Show the cursor if it is hidden */ + if (g_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD (wParam)) + { + case IDOK: + case IDCANCEL: + ErrorF ("winAboutDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); + + DestroyWindow (g_hDlgAbout); + g_hDlgAbout = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + + /* Restore window procedures for URL buttons */ + winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); + winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); + winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG); + winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ); + + return TRUE; + + case ID_ABOUT_CHANGELOG: + { + int iReturn; +#ifdef __CYGWIN__ + const char * pszCygPath = "/usr/X11R6/share/doc/" + "xorg-x11-xwin/changelog.html"; + char pszWinPath[MAX_PATH + 1]; + + /* Convert the POSIX path to a Win32 path */ + cygwin_conv_to_win32_path (pszCygPath, pszWinPath); +#else + const char * pszWinPath = "http://x.cygwin.com/" + "devel/server/changelog.html"; +#endif + + iReturn = (int) ShellExecute (NULL, + "open", + pszWinPath, + NULL, + NULL, + SW_MAXIMIZE); + if (iReturn < 32) + { + ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_CHANGELOG - " + "ShellExecute failed: %d\n", + iReturn); + } + } + return TRUE; + + case ID_ABOUT_WEBSITE: + { + const char * pszPath = "http://x.cygwin.com/"; + int iReturn; + + iReturn = (int) ShellExecute (NULL, + "open", + pszPath, + NULL, + NULL, + SW_MAXIMIZE); + if (iReturn < 32) + { + ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_WEBSITE - " + "ShellExecute failed: %d\n", + iReturn); + } + } + return TRUE; + + case ID_ABOUT_UG: + { + const char * pszPath = "http://x.cygwin.com/docs/ug/"; + int iReturn; + + iReturn = (int) ShellExecute (NULL, + "open", + pszPath, + NULL, + NULL, + SW_MAXIMIZE); + if (iReturn < 32) + { + ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_UG - " + "ShellExecute failed: %d\n", + iReturn); + } + } + return TRUE; + + case ID_ABOUT_FAQ: + { + const char * pszPath = "http://x.cygwin.com/docs/faq/"; + int iReturn; + + iReturn = (int) ShellExecute (NULL, + "open", + pszPath, + NULL, + NULL, + SW_MAXIMIZE); + if (iReturn < 32) + { + ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_FAQ - " + "ShellExecute failed: %d\n", + iReturn); + } + } + return TRUE; + } + break; + + case WM_CLOSE: + ErrorF ("winAboutDlgProc - WM_CLOSE\n"); + + DestroyWindow (g_hDlgAbout); + g_hDlgAbout = NULL; + + /* Fix to make sure keyboard focus isn't trapped */ + PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); + + /* Restore window procedures for URL buttons */ + winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); + winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); + winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG); + winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ); + + return TRUE; + } + + return FALSE; +} diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c new file mode 100644 index 000000000..f0bc671e2 --- /dev/null +++ b/hw/xwin/winengine.c @@ -0,0 +1,336 @@ +/* + *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 <xwin-config.h> +#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 () +{ + 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 () +{ + 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; +} diff --git a/hw/xwin/winerror.c b/hw/xwin/winerror.c new file mode 100644 index 000000000..7d292134f --- /dev/null +++ b/hw/xwin/winerror.c @@ -0,0 +1,143 @@ +/* + *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 <xwin-config.h> +#endif +#ifdef XVENDORNAME +#define VENDOR_STRING XVENDORNAME +#define VERSION_STRING XORG_RELEASE +#define VENDOR_CONTACT BUILDERADDR +#endif + +#include "win.h" + +/* References to external symbols */ +extern char * g_pszCommandLine; +extern char * g_pszLogFile; +extern Bool g_fSilentFatalError; + + +#ifdef DDXOSVERRORF +/* Prototype */ +void +OsVendorVErrorF (const char *pszFormat, va_list va_args); + +void +OsVendorVErrorF (const char *pszFormat, va_list va_args) +{ +#if defined(XWIN_CLIPBOARD) || defined (XWIN_MULTIWINDOW) + /* make sure the clipboard and multiwindow threads do not interfere the + * main thread */ + static pthread_mutex_t s_pmPrinting = PTHREAD_MUTEX_INITIALIZER; + + /* Lock the printing mutex */ + pthread_mutex_lock (&s_pmPrinting); +#endif + + /* Print the error message to a log file, could be stderr */ + LogVWrite (0, pszFormat, va_args); + +#if defined(XWIN_CLIPBOARD) || defined (XWIN_MULTIWINDOW) + /* Unlock the printing mutex */ + pthread_mutex_unlock (&s_pmPrinting); +#endif +} +#endif + + +/* + * os/util.c/FatalError () calls our vendor ErrorF, so the message + * from a FatalError will be logged. Thus, the message for the + * fatal error is not passed to this function. + * + * Attempt to do last-ditch, safe, important cleanup here. + */ +#ifdef DDXOSFATALERROR +void +OsVendorFatalError (void) +{ + /* Don't give duplicate warning if UseMsg was called */ + if (g_fSilentFatalError) + return; + + winMessageBoxF ( + "A fatal error has occurred and " PROJECT_NAME " will now exit.\n" \ + "Please open %s for more information.\n", + MB_ICONERROR, (g_pszLogFile?g_pszLogFile:"the logfile")); +} +#endif + + +/* + * winMessageBoxF - Print a formatted error message in a useful + * message box. + */ + +void +winMessageBoxF (const char *pszError, UINT uType, ...) +{ + char * pszErrorF = NULL; + char * pszMsgBox = NULL; + va_list args; + + va_start(args, uType); + pszErrorF = Xvprintf(pszError, args); + va_end(args); + if (!pszErrorF) + goto winMessageBoxF_Cleanup; + +#define MESSAGEBOXF \ + "%s\n" \ + "Vendor: %s\n" \ + "Release: %s\n" \ + "Contact: %s\n" \ + "XWin was started with the following command-line:\n\n" \ + "%s\n" + + pszMsgBox = Xprintf (MESSAGEBOXF, + pszErrorF, VENDOR_STRING, VERSION_STRING, VENDOR_CONTACT, + g_pszCommandLine); + if (!pszMsgBox) + goto winMessageBoxF_Cleanup; + + /* Display the message box string */ + MessageBox (NULL, + pszMsgBox, + PROJECT_NAME, + MB_OK | uType); + + winMessageBoxF_Cleanup: + if (pszErrorF) + xfree (pszErrorF); + if (pszMsgBox) + xfree (pszMsgBox); +#undef MESSAGEBOXF +} diff --git a/hw/xwin/winfillsp.c b/hw/xwin/winfillsp.c new file mode 100644 index 000000000..702f34f96 --- /dev/null +++ b/hw/xwin/winfillsp.c @@ -0,0 +1,866 @@ +/* + *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 + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + + +extern void ROP16(HDC hdc, int rop); + +#define TRANSLATE_COLOR(color) \ +{ \ + if (pDrawable->depth == 15) \ + color = ((color & 0x1F) << 19) | ((color & 0x03E0) << 6) | \ + ((color & 0xF800) >> 8); \ + else if (pDrawable->depth == 16) \ + color = ((color & 0x1F) << 19) | ((color & 0x07E0) << 5) | \ + ((color & 0xF800) >> 8); \ + else if (pDrawable->depth == 24 || pDrawable->depth == 32) \ + color = ((color & 0xFF) << 16) | (color & 0xFF00) | \ + ((color & 0xFF0000) >> 16); \ +} + +/* See Porting Layer Definition - p. 54 */ +void +winFillSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int iSpans, + DDXPointPtr pPoints, + int *piWidths, + int fSorted) +{ + winGCPriv(pGC); + HBITMAP hbmpOrig = NULL, hbmpOrigStipple = NULL; + HBITMAP hPenOrig = NULL; + HBITMAP hBitmap = NULL; + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + PixmapPtr pStipple = NULL; + winPrivPixmapPtr pStipplePriv = NULL; + PixmapPtr pTile = NULL; + winPrivPixmapPtr pTilePriv = NULL; + HDC hdcStipple = NULL, hdcTile = NULL; + HPEN hPen = NULL; + int iX; + int fg, bg; + RegionPtr pClip = pGC->pCompositeClip; + BoxPtr pextent, pbox; + int nbox; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1; + HRGN hrgn = NULL, combined = NULL; + + nbox = REGION_NUM_RECTS (pClip); + pbox = REGION_RECTS (pClip); + + if (!nbox) return; + + combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); + nbox--; pbox++; + + while (nbox--) + { + hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); + CombineRgn (combined, combined, hrgn, RGN_OR); + DeleteObject (hrgn); + hrgn = NULL; + pbox++; + } + + pextent = REGION_EXTENTS (pGC->pScreen, pClip); + extentX1 = pextent->x1; + extentY1 = pextent->y1; + extentX2 = pextent->x2; + extentY2 = pextent->y2; + + /* Branch on the type of drawable we have */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: + + SelectClipRgn (pGCPriv->hdcMem, combined); + DeleteObject (combined); + combined = NULL; + + /* Get a pixmap pointer from the drawable pointer, and fetch privates */ + pPixmap = (PixmapPtr) pDrawable; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Select the drawable pixmap into memory hdc */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winFillSpans - DRAWABLE_PIXMAP - " + "SelectObject () failed on\n\tpPixmapPriv->hBitmap: " + "%08x\n", (unsigned int) pPixmapPriv->hBitmap); + + /* Branch on the fill type */ + switch (pGC->fillStyle) + { + case FillSolid: + + ROP16 (pGCPriv->hdcMem, pGC->alu); + + if (pDrawable->depth == 1) + { + if (pGC->fgPixel == 0) + hPenOrig = SelectObject (pGCPriv->hdcMem, + GetStockObject (BLACK_PEN)); + else + hPenOrig = SelectObject (pGCPriv->hdcMem, + GetStockObject (WHITE_PEN)); + } + else + { + fg = pGC->fgPixel; + TRANSLATE_COLOR (fg); + hPen = CreatePen (PS_SOLID, 0, fg); + hPenOrig = SelectObject (pGCPriv->hdcMem, hPen); + } + + while (iSpans--) + { + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + MoveToEx (pGCPriv->hdcMem, fullX1, fullY1, NULL); + LineTo (pGCPriv->hdcMem, fullX2, fullY1); + } + + SetROP2 (pGCPriv->hdcMem, R2_COPYPEN); + + /* Give back the Pen */ + SelectObject (pGCPriv->hdcMem, hPenOrig); + + if (pDrawable->depth != 1) + DeleteObject (hPen); + break; + + case FillOpaqueStippled: + + pStipple = pGC->stipple; + pStipplePriv = winGetPixmapPriv (pStipple); + + /* Create a device-dependent bitmap for the stipple */ + hBitmap = CreateDIBitmap (pGCPriv->hdcMem, + (BITMAPINFOHEADER *)pStipplePriv->pbmih, + CBM_INIT, + pStipplePriv->pbBits, + (BITMAPINFO *)pStipplePriv->pbmih, + DIB_RGB_COLORS); + + /* Create a memory DC to hold the stipple */ + hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem); + + /* Select the stipple bitmap into the stipple DC */ + hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); + if (hbmpOrigStipple == NULL) + FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " + "SelectObject () failed on hbmpOrigStipple\n"); + + /* Make a temporary copy of the foreground and background colors */ + bg = pGC->bgPixel; + fg = pGC->fgPixel; + + /* Translate the depth-dependent colors to Win32 COLORREFs */ + TRANSLATE_COLOR (fg); + TRANSLATE_COLOR (bg); + SetTextColor (pGCPriv->hdcMem, fg); + SetBkColor (pGCPriv->hdcMem, bg); + + while (iSpans--) + { + int width = pStipple->drawable.width; + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + for (iX = fullX1; iX < fullX2; iX += width) + { + int xoffset; + + if ((iX + pStipple->drawable.width) > fullX2) + width = fullX2 - iX; + else + width = pStipple->drawable.width; + + if (iX == fullX1) + xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; + else + xoffset = 0; + + if (xoffset + width > pStipple->drawable.width) + width = pStipple->drawable.width - xoffset; + + BitBlt (pGCPriv->hdcMem, + iX, fullY1, + width, 1, + hdcStipple, + xoffset, + (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, + g_copyROP[pGC->alu]); + } + } + + /* Clear the stipple HDC */ + SelectObject (hdcStipple, hbmpOrigStipple); + DeleteDC (hdcStipple); + + /* Delete the device dependent stipple bitmap */ + DeleteObject (hBitmap); + + break; + case FillStippled: + + pStipple = pGC->stipple; + pStipplePriv = winGetPixmapPriv (pStipple); + + /* Create a device-dependent bitmap for the stipple */ + hBitmap = CreateDIBitmap (pGCPriv->hdcMem, + (BITMAPINFOHEADER *)pStipplePriv->pbmih, + CBM_INIT, + pStipplePriv->pbBits, + (BITMAPINFO *)pStipplePriv->pbmih, + DIB_RGB_COLORS); + + /* Create a memory DC to hold the stipple */ + hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem); + + /* Select the stipple bitmap into the stipple DC */ + hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); + if (hbmpOrigStipple == NULL) + FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " + "SelectObject () failed on hbmpOrigStipple\n"); + + /* Make a temporary copy of the foreground and background colors */ + bg = pGC->bgPixel; + fg = pGC->fgPixel; + + /* Translate the depth-dependent colors to Win32 COLORREFs */ + TRANSLATE_COLOR (fg); + TRANSLATE_COLOR (bg); + + /* this is fudgy, we should only invert on the last one + * We need to get the black/white pixels right in the + * colormap. But yeah ! it's working.. + */ + if (pGC->bgPixel != -1 && pGC->fgPixel != -1) + { + SetTextColor (pGCPriv->hdcMem, fg); + SetBkColor (pGCPriv->hdcMem, bg); + BitBlt (hdcStipple, + 0, 0, + pStipple->drawable.width, pStipple->drawable.height, + hdcStipple, + 0, 0, + 0x330008); + } + else if (pGC->bgPixel == -1) + { + SetTextColor (pGCPriv->hdcMem, fg); + SetBkMode (pGCPriv->hdcMem, TRANSPARENT); + BitBlt (hdcStipple, + 0, 0, + pStipple->drawable.width, pStipple->drawable.height, + hdcStipple, + 0, 0, + 0x330008); + } + else if (pGC->fgPixel == -1) + { + SetTextColor (pGCPriv->hdcMem, bg); + SetBkMode (pGCPriv->hdcMem, TRANSPARENT); +#if 0 + BitBlt (hdcStipple, + 0, 0, + pStipple->drawable.width, pStipple->drawable.height, + hdcStipple, + 0, 0, + 0x330008); +#endif + } + + while (iSpans--) + { + int width = pStipple->drawable.width; + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + for (iX = fullX1; iX < fullX2; iX += width) + { + int xoffset; + + if ((iX + pStipple->drawable.width) > fullX2) + width = fullX2 - iX; + else + width = pStipple->drawable.width; + + if (iX == fullX1) + xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; + else + xoffset = 0; + + if (xoffset + width > pStipple->drawable.width) + width = pStipple->drawable.width - xoffset; + + BitBlt (pGCPriv->hdcMem, + iX, fullY1, + width, 1, + hdcStipple, + xoffset, + (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, + g_copyROP[pGC->alu]); + } + } + + /* Clear the stipple HDC */ + SelectObject (hdcStipple, hbmpOrigStipple); + DeleteDC (hdcStipple); + + /* Delete the device dependent stipple bitmap */ + DeleteObject (hBitmap); + + /* Restore the background mode */ + SetBkMode (pGCPriv->hdcMem, OPAQUE); + break; + + case FillTiled: + + /* Get a pixmap pointer from the tile pointer, and fetch privates */ + pTile = (PixmapPtr) pGC->tile.pixmap; + pTilePriv = winGetPixmapPriv (pTile); + + /* Create a memory DC to hold the tile */ + hdcTile = CreateCompatibleDC (pGCPriv->hdcMem); + + /* Select the tile into a DC */ + hbmpOrig = SelectObject (hdcTile, pTilePriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winFillSpans - DRAWABLE_PIXMAP - FillTiled - " + "SelectObject () failed on pTilePriv->hBitmap\n"); + + while (iSpans--) + { + int width = pTile->drawable.width; + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + for (iX = fullX1; iX < fullX2; iX += width) + { + int xoffset; + + if ((iX + pTile->drawable.width) > fullX2) + width = fullX2 - iX; + else + width = pTile->drawable.width; + + if (iX == fullX1) + xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width; + else + xoffset = 0; + + if (xoffset + width > pTile->drawable.width) + width = pTile->drawable.width - xoffset; + + BitBlt (pGCPriv->hdcMem, + iX, fullY1, + width, 1, + hdcTile, + xoffset, + (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height, + g_copyROP[pGC->alu]); + } + } + + /* Push the tile pixmap out of the memory HDC */ + SelectObject (hdcTile, hbmpOrig); + + /* Delete the tile */ + DeleteDC (hdcTile); + break; + + default: + ErrorF ("winFillSpans - DRAWABLE_PIXMAP - Unknown fillStyle\n"); + break; + } + + /* Reset clip region */ + SelectClipRgn (pGCPriv->hdcMem, NULL); + + /* Push the drawable pixmap out of the GC HDC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + break; + + case DRAWABLE_WINDOW: + + SelectClipRgn (pGCPriv->hdc, combined); + DeleteObject (combined); + combined = NULL; + + /* Branch on fill style */ + switch (pGC->fillStyle) + { + case FillSolid: + + ROP16 (pGCPriv->hdc, pGC->alu); + + if (pDrawable->depth == 1) + { + if (pGC->fgPixel == 0) + hPenOrig = SelectObject (pGCPriv->hdc, + GetStockObject (BLACK_PEN)); + else + hPenOrig = SelectObject (pGCPriv->hdc, + GetStockObject (WHITE_PEN)); + } + else + { + fg = pGC->fgPixel; + TRANSLATE_COLOR (fg); + hPen = CreatePen (PS_SOLID, 0, fg); + hPenOrig = SelectObject (pGCPriv->hdc, hPen); + } + + while (iSpans--) + { + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + MoveToEx (pGCPriv->hdc, fullX1, fullY1, NULL); + LineTo (pGCPriv->hdc, fullX2, fullY1); + } + + SetROP2 (pGCPriv->hdc, R2_COPYPEN); + + /* Give back the Brush */ + SelectObject (pGCPriv->hdc, hPenOrig); + + if (pDrawable->depth != 1) + DeleteObject (hPen); + break; + + case FillOpaqueStippled: + + pStipple = pGC->stipple; + pStipplePriv = winGetPixmapPriv (pStipple); + + /* Create a device-dependent bitmap for the stipple */ + hBitmap = CreateDIBitmap (pGCPriv->hdc, + (BITMAPINFOHEADER *)pStipplePriv->pbmih, + CBM_INIT, + pStipplePriv->pbBits, + (BITMAPINFO *)pStipplePriv->pbmih, + DIB_RGB_COLORS); + + /* Create a memory DC to hold the stipple */ + hdcStipple = CreateCompatibleDC (pGCPriv->hdc); + + /* Select the stipple bitmap into the stipple DC */ + hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); + if (hbmpOrigStipple == NULL) + FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " + "SelectObject () failed on hbmpOrigStipple\n"); + + /* Make a temporary copy of the foreground and background colors */ + bg = pGC->bgPixel; + fg = pGC->fgPixel; + + /* Translate the depth-dependent colors to Win32 COLORREFs */ + TRANSLATE_COLOR (fg); + TRANSLATE_COLOR (bg); + SetTextColor (pGCPriv->hdc, fg); + SetBkColor (pGCPriv->hdc, bg); + + while (iSpans--) + { + int width = pStipple->drawable.width; + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + for (iX = fullX1; iX < fullX2; iX += width) + { + int xoffset; + + if ((iX + pStipple->drawable.width) > fullX2) + width = fullX2 - iX; + else + width = pStipple->drawable.width; + + if (iX == fullX1) + xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; + else + xoffset = 0; + + if (xoffset + width > pStipple->drawable.width) + width = pStipple->drawable.width - xoffset; + + BitBlt (pGCPriv->hdc, + iX, fullY1, + width, 1, + hdcStipple, + xoffset, + (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, + g_copyROP[pGC->alu]); + } + } + + /* Clear the stipple HDC */ + SelectObject (hdcStipple, hbmpOrigStipple); + DeleteDC (hdcStipple); + + /* Delete the device dependent stipple bitmap */ + DeleteObject (hBitmap); + + break; + + case FillStippled: + pStipple = pGC->stipple; + pStipplePriv = winGetPixmapPriv (pStipple); + + /* Create a device-dependent bitmap for the stipple */ + hBitmap = CreateDIBitmap (pGCPriv->hdcMem, + (BITMAPINFOHEADER *)pStipplePriv->pbmih, + CBM_INIT, + pStipplePriv->pbBits, + (BITMAPINFO *)pStipplePriv->pbmih, + DIB_RGB_COLORS); + + /* Create a memory DC to hold the stipple */ + hdcStipple = CreateCompatibleDC (pGCPriv->hdc); + + /* Select the stipple bitmap into the stipple DC */ + hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); + if (hbmpOrigStipple == NULL) + FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " + "SelectObject () failed on hbmpOrigStipple\n"); + + /* Make a temporary copy of the foreground and background colors */ + bg = pGC->bgPixel; + fg = pGC->fgPixel; + + /* Translate the depth-dependent colors to Win32 COLORREFs */ + TRANSLATE_COLOR (fg); + TRANSLATE_COLOR (bg); + + /* this is fudgy, we should only invert on the last one + * We need to get the black/white pixels right in the + * colormap. But yeah ! it's working.. + */ + if (pGC->bgPixel != -1 && pGC->fgPixel != -1) + { + SetTextColor (pGCPriv->hdc, fg); + SetBkColor (pGCPriv->hdc, bg); + BitBlt (hdcStipple, + 0, 0, + pStipple->drawable.width, pStipple->drawable.height, + hdcStipple, + 0,0, + 0x330008); + } + else if (pGC->bgPixel == -1) + { + SetTextColor (pGCPriv->hdc, fg); + SetBkMode (pGCPriv->hdc, TRANSPARENT); + BitBlt (hdcStipple, + 0, 0, + pStipple->drawable.width, pStipple->drawable.height, + hdcStipple, + 0,0, + 0x330008); + } + else if (pGC->fgPixel == -1) + { + SetTextColor (pGCPriv->hdc, bg); + SetBkMode (pGCPriv->hdc, TRANSPARENT); +#if 0 + BitBlt (hdcStipple, + 0, 0, + pStipple->drawable.width, pStipple->drawable.height, + hdcStipple, + 0, 0, + 0x330008); +#endif + } + + while (iSpans--) + { + int width = pStipple->drawable.width; + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + for (iX = fullX1; iX < fullX2; iX += width) + { + int xoffset; + + if ((iX + pStipple->drawable.width) > fullX2) + width = fullX2 - iX; + else + width = pStipple->drawable.width; + + if (iX == fullX1) + xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; + else + xoffset = 0; + + if (xoffset + width > pStipple->drawable.width) + width = pStipple->drawable.width - xoffset; + + BitBlt (pGCPriv->hdc, + iX, fullY1, + width, 1, + hdcStipple, + xoffset, + (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, + g_copyROP[pGC->alu]); + } + } + + /* Clear the stipple HDC */ + SelectObject (hdcStipple, hbmpOrigStipple); + DeleteDC (hdcStipple); + + /* Delete the device dependent stipple bitmap */ + DeleteObject (hBitmap); + + /* Restore the background mode */ + SetBkMode (pGCPriv->hdc, OPAQUE); + break; + + case FillTiled: + + /* Get a pixmap pointer from the tile pointer, and fetch privates */ + pTile = (PixmapPtr) pGC->tile.pixmap; + pTilePriv = winGetPixmapPriv (pTile); + + /* Select the tile into a DC */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pTilePriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winFillSpans - DRAWABLE_WINDOW - FillTiled - " + "SelectObject () failed on pTilePriv->hBitmap\n"); + + while (iSpans--) + { + int width = pTile->drawable.width; + fullX1 = pPoints->x; + fullY1 = pPoints->y; + fullX2 = fullX1 + (int) *piWidths; + pPoints++; + piWidths++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + for (iX = fullX1; iX < fullX2; iX += width) + { + int xoffset; + + if ((iX + pTile->drawable.width) > fullX2) + width = fullX2 - iX; + else + width = pTile->drawable.width; + + if (iX == fullX1) + xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width; + else + xoffset = 0; + + if (xoffset + width > pTile->drawable.width) + width = pTile->drawable.width - xoffset; + + BitBlt (pGCPriv->hdc, + iX, fullY1, + width, 1, + pGCPriv->hdcMem, + xoffset, + (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height, + g_copyROP[pGC->alu]); + } + } + + /* Push the tile pixmap out of the memory HDC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + break; + + default: + ErrorF ("winFillSpans - DRAWABLE_WINDOW - Unknown fillStyle\n"); + break; + } + + /* Reset clip region */ + SelectClipRgn (pGCPriv->hdc, NULL); + break; + + case UNDRAWABLE_WINDOW: + /* UNDRAWABLE_WINDOW doesn't appear to get called when running xterm */ + switch (pGC->fillStyle) + { + case FillSolid: + ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillSolid - " + "Unimplemented\n"); + break; + + case FillStippled: + ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillStippled - " + "Unimplemented\n"); + break; + + case FillTiled: + ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - FillTiled - " + "Unimplemented\n"); + break; + + case FillOpaqueStippled: + ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - OpaqueStippled - " + "Unimplemented\n"); + break; + + default: + ErrorF ("winFillSpans - UNDRAWABLE_WINDOW - Unknown fillStyle\n"); + break; + } + break; + + case DRAWABLE_BUFFER: + /* DRAWABLE_BUFFER seems to be undocumented. */ + ErrorF ("winFillSpans - DRAWABLE_BUFFER - Unimplemented\n"); + break; + + default: + ErrorF ("winFillSpans - Unknown drawable type\n"); + break; + } +} diff --git a/hw/xwin/winfont.c b/hw/xwin/winfont.c new file mode 100644 index 000000000..af3e90da5 --- /dev/null +++ b/hw/xwin/winfont.c @@ -0,0 +1,80 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + +#ifdef XWIN_NATIVEGDI +/* See Porting Layer Definition - p. 32 */ +/* See mfb/mfbfont.c - mfbRealizeFont() - which is empty :) */ +Bool +winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) +{ + BOOL fResult = TRUE; + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winRealizeFont (%p, %p)\n", pScreen, pFont); +#endif + + WIN_UNWRAP(RealizeFont); + if (pScreen->RealizeFont) + fResult = (*pScreen->RealizeFont) (pScreen, pFont); + WIN_WRAP(RealizeFont, winRealizeFontNativeGDI); + + return fResult; +} + +/* See Porting Layer Definition - p. 32 */ +/* See mfb/mfbfont.c - mfbUnrealizeFont() - which is empty :) */ +Bool +winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) +{ + BOOL fResult = TRUE; + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winUnrealizeFont (%p, %p)\n", pScreen, pFont); +#endif + + WIN_UNWRAP(UnrealizeFont); + if (pScreen->UnrealizeFont) + fResult = (*pScreen->UnrealizeFont) (pScreen, pFont); + WIN_WRAP(UnrealizeFont, winUnrealizeFontNativeGDI); + + return fResult; +#if CYGDEBUG + winDebug ("winUnrealizeFont()\n"); +#endif + return TRUE; +} +#endif diff --git a/hw/xwin/wingc.c b/hw/xwin/wingc.c new file mode 100644 index 000000000..107d87aef --- /dev/null +++ b/hw/xwin/wingc.c @@ -0,0 +1,256 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + +void +winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg); + + +/* + * Local prototypes + */ + +#if 0 +static void +winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges); +#endif + +static void +winValidateGCNativeGDI (GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable); + +#if 0 +static void +winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst); +#endif + +static void +winDestroyGCNativeGDI (GCPtr pGC); + +#if 0 +static void +winChangeClipNativeGDI (GCPtr pGC, int nType, pointer pValue, int nRects); + +static void +winDestroyClipNativeGDI (GCPtr pGC); + +static void +winCopyClipNativeGDI (GCPtr pGCdst, GCPtr pGCsrc); +#endif + +#if 0 +/* GC Handling Routines */ +const GCFuncs winGCFuncs = { + winValidateGCNativeGDI, + winChangeGCNativeGDI, + winCopyGCNativeGDI, + winDestroyGCNativeGDI, + winChangeClipNativeGDI, + winDestroyClipNativeGDI, + winCopyClipNativeGDI, +}; +#else +const GCFuncs winGCFuncs = { + winValidateGCNativeGDI, + miChangeGC, + miCopyGC, + winDestroyGCNativeGDI, + miChangeClip, + miDestroyClip, + miCopyClip, +}; +#endif + +/* Drawing Primitives */ +const GCOps winGCOps = { + winFillSpansNativeGDI, + winSetSpansNativeGDI, + miPutImage, + miCopyArea, + miCopyPlane, + miPolyPoint, + winPolyLineNativeGDI, + miPolySegment, + miPolyRectangle, + miPolyArc, + miFillPolygon, + miPolyFillRect, + miPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, +#if 0 + winImageGlyphBltNativeGDI, + winPolyGlyphBltNativeGDI, +#else + miImageGlyphBlt, + miPolyGlyphBlt, +#endif + winPushPixels +}; + + +/* See Porting Layer Definition - p. 45 */ +/* See mfb/mfbgc.c - mfbCreateGC() */ +/* See Strategies for Porting - pp. 15, 16 */ +Bool +winCreateGCNativeGDI (GCPtr pGC) +{ + winPrivGCPtr pGCPriv = NULL; + winPrivScreenPtr pScreenPriv = NULL; + +#if 0 + ErrorF ("winCreateGCNativeGDI - depth: %d\n", + pGC->depth); +#endif + + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + pGC->freeCompClip = FALSE; + pGC->pCompositeClip = 0; + + pGC->ops = (GCOps *) &winGCOps; + pGC->funcs = (GCFuncs *) &winGCFuncs; + + /* We want all coordinates passed to spans functions to be screen relative */ + pGC->miTranslate = TRUE; + + /* Allocate privates for this GC */ + pGCPriv = winGetGCPriv (pGC); + if (pGCPriv == NULL) + { + ErrorF ("winCreateGCNativeGDI () - Privates pointer was NULL\n"); + return FALSE; + } + + /* Create a new screen DC for the display window */ + pScreenPriv = winGetScreenPriv (pGC->pScreen); + pGCPriv->hdc = GetDC (pScreenPriv->hwndScreen); + + /* Allocate a memory DC for the GC */ + pGCPriv->hdcMem = CreateCompatibleDC (pGCPriv->hdc); + + return TRUE; +} + + +#if 0 +/* See Porting Layer Definition - p. 45 */ +static void +winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges) +{ +#if 0 + ErrorF ("winChangeGCNativeGDI () - Doing nothing\n"); +#endif +} +#endif + + +static void +winValidateGCNativeGDI (GCPtr pGC, + unsigned long ulChanges, + DrawablePtr pDrawable) +{ + if ((ulChanges & (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) + || (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) + { + miComputeCompositeClip (pGC, pDrawable); + } +} + + +#if 0 +/* See Porting Layer Definition - p. 46 */ +static void +winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst) +{ + +} +#endif + + +/* See Porting Layer Definition - p. 46 */ +static void +winDestroyGCNativeGDI (GCPtr pGC) +{ + winGCPriv(pGC); + winScreenPriv(pGC->pScreen); + + if (pGC->freeCompClip) + REGION_DESTROY (pGC->pScreen, pGC->pCompositeClip); + + /* Free the memory DC */ + if (pGCPriv->hdcMem != NULL) + { + DeleteDC (pGCPriv->hdcMem); + pGCPriv->hdcMem = NULL; + } + + /* Release the screen DC for the display window */ + if (pGCPriv->hdc != NULL) + { + ReleaseDC (pScreenPriv->hwndScreen, pGCPriv->hdc); + pGCPriv->hdc = NULL; + } + + /* Invalidate the GC privates pointer */ + winSetGCPriv (pGC, NULL); +} + +#if 0 +/* See Porting Layer Definition - p. 46 */ +static void +winChangeClipNativeGDI (GCPtr pGC, int nType, pointer pValue, int nRects) +{ + +} + + +/* See Porting Layer Definition - p. 47 */ +static void +winDestroyClipNativeGDI (GCPtr pGC) +{ + +} + + +/* See Porting Layer Definition - p. 47 */ +static void +winCopyClipNativeGDI (GCPtr pGCdst, GCPtr pGCsrc) +{ + +} +#endif diff --git a/hw/xwin/wingetsp.c b/hw/xwin/wingetsp.c new file mode 100644 index 000000000..03f7f1012 --- /dev/null +++ b/hw/xwin/wingetsp.c @@ -0,0 +1,192 @@ +/* + *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 + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + +/* See Porting Layer Definition - p. 55 */ +void +winGetSpansNativeGDI (DrawablePtr pDrawable, + int nMax, + DDXPointPtr pPoints, + int *piWidths, + int iSpans, + char *pDsts) +{ + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + int iSpan; + DDXPointPtr pPoint = NULL; + int *piWidth = NULL; + char *pDst = pDsts; + HBITMAP hbmpWindow, hbmpOrig, hbmpOrig1; + BYTE *pbWindow = NULL; + HDC hdcMem, hdcMem1; + ScreenPtr pScreen = pDrawable->pScreen; + winScreenPriv(pScreen); + + /* Branch on the drawable type */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: +#if 0 + ErrorF ("winGetSpans - DRAWABLE_PIXMAP %08x\n", + pDrawable); +#endif + + pPixmap = (PixmapPtr) pDrawable; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Open a memory HDC */ + hdcMem1 = CreateCompatibleDC (NULL); + hdcMem = CreateCompatibleDC (NULL); + + /* Select the drawable pixmap into a DC */ + hbmpOrig1 = SelectObject (hdcMem1, pPixmapPriv->hBitmap); + + if (hbmpOrig1 == NULL) + FatalError ("winGetSpans - DRAWABLE_PIXMAP - SelectObject () " + "failed on pPixmapPriv->hBitmap\n"); + + /* Loop through spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + hbmpWindow = winCreateDIBNativeGDI (*piWidth, 1, + pDrawable->depth, + &pbWindow, + NULL); + + hbmpOrig = SelectObject (hdcMem, hbmpWindow); + + /* Transfer the window bits to the window bitmap */ + BitBlt (hdcMem, + 0, 0, + *piWidth, 1, + hdcMem1, + pPoint->x, pPoint->y, + SRCCOPY); + + memcpy (pDst, + (char*) pbWindow, + PixmapBytePad (*piWidth, pDrawable->depth)); + + /* Pop the window bitmap out of the HDC and delete the bitmap */ + SelectObject (hdcMem, hbmpOrig); + DeleteObject (hbmpWindow); + +#if 0 + ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, *piWidth); +#endif + + /* Calculate offset of next bit destination */ + pDst += PixmapBytePad (*piWidth, pDrawable->depth); + } + + /* Pop the pixmap's bitmap out of the HDC */ + SelectObject (hdcMem1, hbmpOrig1); + + /* Delete the HDCs */ + DeleteDC (hdcMem1); + DeleteDC (hdcMem); + break; + + case DRAWABLE_WINDOW: +#if 0 + ErrorF ("winGetSpans - DRAWABLE_WINDOW\n"); +#endif + + /* Open a memory HDC */ + hdcMem = CreateCompatibleDC (NULL); + + /* Loop through spans */ + for (iSpan = 0; iSpan < iSpans; ++iSpan) + { + pPoint = pPoints + iSpan; + piWidth = piWidths + iSpan; + + hbmpWindow = winCreateDIBNativeGDI (*piWidth, 1, + pDrawable->depth, + &pbWindow, + NULL); + + hbmpOrig = SelectObject (hdcMem, hbmpWindow); + + /* Transfer the window bits to the window bitmap */ + BitBlt (hdcMem, + 0, 0, + *piWidth, 1, + pScreenPriv->hdcScreen, + pPoint->x, pPoint->y, + SRCCOPY); + + memcpy (pDst, + (char*) pbWindow, + PixmapBytePad (*piWidth, pDrawable->depth)); + + /* Pop the window bitmap out of the HDC */ + SelectObject (hdcMem, hbmpOrig); + + DeleteObject (hbmpWindow); + +#if 0 + ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", + pDrawable->width, pDrawable->height, pDrawable->depth, + pPoint->x, pPoint->y, *piWidth); +#endif + + /* Calculate offset of next bit destination */ + pDst += PixmapBytePad (*piWidth, pDrawable->depth); + } + + /* Delete the window bitmap */ + DeleteDC (hdcMem); + break; + + case UNDRAWABLE_WINDOW: + FatalError ("winGetSpans - UNDRAWABLE_WINDOW\n"); + break; + + case DRAWABLE_BUFFER: + FatalError ("winGetSpans - DRAWABLE_BUFFER\n"); + break; + + default: + FatalError ("winGetSpans - Unknown drawable type\n"); + break; + } +} diff --git a/hw/xwin/winglobals.c b/hw/xwin/winglobals.c new file mode 100644 index 000000000..fddada39e --- /dev/null +++ b/hw/xwin/winglobals.c @@ -0,0 +1,138 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + + +/* + * General global variables + */ + +int g_iNumScreens = 0; +winScreenInfo g_ScreenInfo[MAXSCREENS]; +int g_iLastScreen = -1; +#ifdef HAS_DEVWINDOWS +int g_fdMessageQueue = WIN_FD_INVALID; +#endif +DevPrivateKey g_iScreenPrivateKey = &g_iScreenPrivateKey; +DevPrivateKey g_iCmapPrivateKey = &g_iCmapPrivateKey; +DevPrivateKey g_iGCPrivateKey = &g_iGCPrivateKey; +DevPrivateKey g_iPixmapPrivateKey = &g_iPixmapPrivateKey; +DevPrivateKey g_iWindowPrivateKey = &g_iWindowPrivateKey; +unsigned long g_ulServerGeneration = 0; +Bool g_fInitializedDefaultScreens = FALSE; +DWORD g_dwEnginesSupported = 0; +HINSTANCE g_hInstance = 0; +HWND g_hDlgDepthChange = NULL; +HWND g_hDlgExit = NULL; +HWND g_hDlgAbout = NULL; +const char * g_pszQueryHost = NULL; +Bool g_fXdmcpEnabled = FALSE; +HICON g_hIconX = NULL; +HICON g_hSmallIconX = NULL; +#ifndef RELOCATE_PROJECTROOT +char * g_pszLogFile = "/tmp/XWin.log"; +#else +char * g_pszLogFile = "XWin.log"; +Bool g_fLogFileChanged = FALSE; +#endif +int g_iLogVerbose = 2; +Bool g_fLogInited = FALSE; +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; + + +/* + * Global variables for dynamically loaded libraries and + * 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; + + +#ifdef XWIN_CLIPBOARD +/* + * Wrapped DIX functions + */ +winDispatchProcPtr winProcEstablishConnectionOrig = NULL; +winDispatchProcPtr winProcQueryTreeOrig = NULL; +winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL; + + +/* + * Clipboard variables + */ + +Bool g_fUnicodeClipboard = TRUE; +Bool g_fClipboard = FALSE; +Bool g_fClipboardLaunched = FALSE; +Bool g_fClipboardStarted = FALSE; +pthread_t g_ptClipboardProc; +HWND g_hwndClipboard = NULL; +void *g_pClipboardDisplay = NULL; +Window g_iClipboardWindow = None; +Atom g_atomLastOwnedSelection = None; +#endif + + +/* + * Re-initialize global variables that are invalidated + * by a server reset. + */ + +void +winInitializeGlobals (void) +{ + g_dwCurrentThreadID = GetCurrentThreadId (); + g_hwndKeyboardFocus = NULL; +#ifdef XWIN_CLIPBOARD + g_fClipboardLaunched = FALSE; + g_fClipboardStarted = FALSE; + g_iClipboardWindow = None; + g_pClipboardDisplay = NULL; + g_atomLastOwnedSelection = None; + g_hwndClipboard = NULL; +#endif +} diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c new file mode 100644 index 000000000..d574f2053 --- /dev/null +++ b/hw/xwin/winkeybd.c @@ -0,0 +1,637 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include "winkeybd.h" +#include "winconfig.h" +#include "winmsg.h" + +#ifdef XKB +#ifndef XKB_IN_SERVER +#define XKB_IN_SERVER +#endif +#include <xkbsrv.h> +#endif + +static Bool g_winKeyState[NUM_KEYCODES]; + +/* Stored to get internal mode key states. Must be read-only. */ +static unsigned short const *g_winInternalModeKeyStatesPtr = NULL; + + +/* + * Local prototypes + */ + +static void +winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap); + +static void +winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, + pointer pCtrl, int iClass); + +static void +winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl); + + +/* + * Translate a Windows WM_[SYS]KEY(UP/DOWN) message + * into an ASCII scan code. + * + * We do this ourselves, rather than letting Windows handle it, + * because Windows tends to munge the handling of special keys, + * like AltGr on European keyboards. + */ + +void +winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode) +{ + int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1]; + int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2]; + int iParamScanCode = LOBYTE (HIWORD (lParam)); + + /* Branch on special extended, special non-extended, or normal key */ + if ((HIWORD (lParam) & KF_EXTENDED) && iKeyFixupEx) + *piScanCode = iKeyFixupEx; + else if (iKeyFixup) + *piScanCode = iKeyFixup; + else if (wParam == 0 && iParamScanCode == 0x70) + *piScanCode = KEY_HKTG; + else + switch (iParamScanCode) + { + case 0x70: + *piScanCode = KEY_HKTG; + break; + case 0x73: + *piScanCode = KEY_BSlash2; + break; + default: + *piScanCode = iParamScanCode; + break; + } +} + + +/* + * We call this function from winKeybdProc when we are + * initializing the keyboard. + */ + +static void +winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap) +{ + int i; + KeySym *pMap = map; + KeySym *pKeySym; + + /* + * Initialize all key states to up... which may not be true + * but it is close enough. + */ + ZeroMemory (g_winKeyState, sizeof (g_winKeyState[0]) * NUM_KEYCODES); + + /* MAP_LENGTH is defined in Xserver/include/input.h to be 256 */ + for (i = 0; i < MAP_LENGTH; i++) + pModMap[i] = NoSymbol; /* make sure it is restored */ + + /* Loop through all valid entries in the key symbol table */ + for (pKeySym = pMap, i = MIN_KEYCODE; + i < (MIN_KEYCODE + NUM_KEYCODES); + i++, pKeySym += GLYPHS_PER_KEY) + { + switch (*pKeySym) + { + case XK_Shift_L: + case XK_Shift_R: + pModMap[i] = ShiftMask; + break; + + case XK_Control_L: + case XK_Control_R: + pModMap[i] = ControlMask; + break; + + case XK_Caps_Lock: + pModMap[i] = LockMask; + break; + + case XK_Alt_L: + case XK_Alt_R: + pModMap[i] = AltMask; + break; + + case XK_Num_Lock: + pModMap[i] = NumLockMask; + break; + + case XK_Scroll_Lock: + pModMap[i] = ScrollLockMask; + break; + +#if 0 + case XK_Super_L: + case XK_Super_R: + pModMap[i] = Mod4Mask; + break; +#else + /* Hirigana/Katakana toggle */ + case XK_Kana_Lock: + case XK_Kana_Shift: + pModMap[i] = KanaMask; + break; +#endif + + /* alternate toggle for multinational support */ + case XK_Mode_switch: + pModMap[i] = AltLangMask; + break; + } + } + + pKeySyms->map = (KeySym *) pMap; + pKeySyms->mapWidth = GLYPHS_PER_KEY; + pKeySyms->minKeyCode = MIN_KEYCODE; + pKeySyms->maxKeyCode = MAX_KEYCODE; +} + + +/* Ring the keyboard bell (system speaker on PCs) */ +static void +winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, + pointer pCtrl, int iClass) +{ + /* + * We can't use Beep () here because it uses the PC speaker + * on NT/2000. MessageBeep (MB_OK) will play the default system + * sound on systems with a sound card or it will beep the PC speaker + * on systems that do not have a sound card. + */ + MessageBeep (MB_OK); +} + + +/* Change some keyboard configuration parameters */ +static void +winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl) +{ + g_winInternalModeKeyStatesPtr = &(pDevice->key->state); +} + + +/* + * See Porting Layer Definition - p. 18 + * winKeybdProc is known as a DeviceProc. + */ + +int +winKeybdProc (DeviceIntPtr pDeviceInt, int iState) +{ + KeySymsRec keySyms; + CARD8 modMap[MAP_LENGTH]; + DevicePtr pDevice = (DevicePtr) pDeviceInt; +#ifdef XKB + XkbComponentNamesRec names; + XkbSrvInfoPtr xkbi; + XkbControlsPtr ctrl; +#endif + + switch (iState) + { + case DEVICE_INIT: + winConfigKeyboard (pDeviceInt); + + winGetKeyMappings (&keySyms, modMap); + +#ifdef XKB + /* FIXME: Maybe we should use winGetKbdLeds () here? */ + defaultKeyboardControl.leds = g_winInfo.keyboard.leds; +#else + defaultKeyboardControl.leds = g_winInfo.keyboard.leds; +#endif + +#ifdef XKB + if (g_winInfo.xkb.disable) + { +#endif + InitKeyboardDeviceStruct (pDevice, + &keySyms, + modMap, + winKeybdBell, + winKeybdCtrl); +#ifdef XKB + } + else + { + + names.keymap = g_winInfo.xkb.keymap; + names.keycodes = g_winInfo.xkb.keycodes; + names.types = g_winInfo.xkb.types; + names.compat = g_winInfo.xkb.compat; + names.symbols = g_winInfo.xkb.symbols; + names.geometry = g_winInfo.xkb.geometry; + + winErrorFVerb(2, "Rules = \"%s\" Model = \"%s\" Layout = \"%s\"" + " Variant = \"%s\" Options = \"%s\"\n", + g_winInfo.xkb.rules, g_winInfo.xkb.model, + g_winInfo.xkb.layout, g_winInfo.xkb.variant, + g_winInfo.xkb.options); + + XkbSetRulesDflts (g_winInfo.xkb.rules, g_winInfo.xkb.model, + g_winInfo.xkb.layout, g_winInfo.xkb.variant, + g_winInfo.xkb.options); + XkbInitKeyboardDeviceStruct (pDeviceInt, &names, &keySyms, + modMap, winKeybdBell, winKeybdCtrl); + } +#endif + +#ifdef XKB + if (!g_winInfo.xkb.disable) + { + xkbi = pDeviceInt->key->xkbInfo; + if (xkbi != NULL) + { + ctrl = xkbi->desc->ctrls; + ctrl->repeat_delay = g_winInfo.keyboard.delay; + ctrl->repeat_interval = 1000/g_winInfo.keyboard.rate; + } + else + { + winErrorFVerb (1, "winKeybdProc - Error initializing keyboard AutoRepeat (No XKB)\n"); + } + } +#endif + + g_winInternalModeKeyStatesPtr = &(pDeviceInt->key->state); + break; + + case DEVICE_ON: + pDevice->on = TRUE; + g_winInternalModeKeyStatesPtr = &(pDeviceInt->key->state); + break; + + case DEVICE_CLOSE: + case DEVICE_OFF: + pDevice->on = FALSE; + g_winInternalModeKeyStatesPtr = NULL; + break; + } + + return Success; +} + + +/* + * Detect current mode key states upon server startup. + * + * Simulate a press and release of any key that is currently + * toggled. + */ + +void +winInitializeModeKeyStates (void) +{ + /* Restore NumLock */ + if (GetKeyState (VK_NUMLOCK) & 0x0001) + { + winSendKeyEvent (KEY_NumLock, TRUE); + winSendKeyEvent (KEY_NumLock, FALSE); + } + + /* Restore CapsLock */ + if (GetKeyState (VK_CAPITAL) & 0x0001) + { + winSendKeyEvent (KEY_CapsLock, TRUE); + winSendKeyEvent (KEY_CapsLock, FALSE); + } + + /* Restore ScrollLock */ + if (GetKeyState (VK_SCROLL) & 0x0001) + { + winSendKeyEvent (KEY_ScrollLock, TRUE); + winSendKeyEvent (KEY_ScrollLock, FALSE); + } + + /* Restore KanaLock */ + if (GetKeyState (VK_KANA) & 0x0001) + { + winSendKeyEvent (KEY_HKTG, TRUE); + winSendKeyEvent (KEY_HKTG, FALSE); + } +} + + +/* + * Upon regaining the keyboard focus we must + * resynchronize our internal mode key states + * with the actual state of the keys. + */ + +void +winRestoreModeKeyStates () +{ + DWORD dwKeyState; + BOOL processEvents = TRUE; + unsigned short internalKeyStates; + + /* X server is being initialized */ + if (!g_winInternalModeKeyStatesPtr) + return; + + /* Only process events if the rootwindow is mapped. The keyboard events + * will cause segfaults otherwise */ + if (WindowTable && WindowTable[0] && WindowTable[0]->mapped == FALSE) + processEvents = FALSE; + + /* Force to process all pending events in the mi event queue */ + if (processEvents) + mieqProcessInputEvents (); + + /* Read the mode key states of our X server */ + internalKeyStates = *g_winInternalModeKeyStatesPtr; + + /* + * NOTE: The C XOR operator, ^, will not work here because it is + * a bitwise operator, not a logical operator. C does not + * have a logical XOR operator, so we use a macro instead. + */ + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; + if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState)) + { + winSendKeyEvent (KEY_NumLock, TRUE); + winSendKeyEvent (KEY_NumLock, FALSE); + } + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001; + if (WIN_XOR (internalKeyStates & LockMask, dwKeyState)) + { + winSendKeyEvent (KEY_CapsLock, TRUE); + winSendKeyEvent (KEY_CapsLock, FALSE); + } + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_SCROLL) & 0x0001; + if (WIN_XOR (internalKeyStates & ScrollLockMask, dwKeyState)) + { + winSendKeyEvent (KEY_ScrollLock, TRUE); + winSendKeyEvent (KEY_ScrollLock, FALSE); + } + + /* Has the key state changed? */ + dwKeyState = GetKeyState (VK_KANA) & 0x0001; + if (WIN_XOR (internalKeyStates & KanaMask, dwKeyState)) + { + winSendKeyEvent (KEY_HKTG, TRUE); + winSendKeyEvent (KEY_HKTG, FALSE); + } +} + + +/* + * Look for the lovely fake Control_L press/release generated by Windows + * when AltGr is pressed/released on a non-U.S. keyboard. + */ + +Bool +winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) +{ + MSG msgNext; + LONG lTime; + Bool fReturn; + + /* + * Fake Ctrl_L presses will be followed by an Alt_R keypress + * with the same timestamp as the Ctrl_L press. + */ + if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN) + && wParam == VK_CONTROL + && (HIWORD (lParam) & KF_EXTENDED) == 0) + { + /* Got a Ctrl_L press */ + + /* Get time of current message */ + lTime = GetMessageTime (); + + /* Look for fake Ctrl_L preceeding an Alt_R press. */ + fReturn = PeekMessage (&msgNext, NULL, + WM_KEYDOWN, WM_SYSKEYDOWN, + PM_NOREMOVE); + + /* + * Try again if the first call fails. + * NOTE: This usually happens when TweakUI is enabled. + */ + if (!fReturn) + { + /* Voodoo to make sure that the Alt_R message has posted */ + Sleep (0); + + /* Look for fake Ctrl_L preceeding an Alt_R press. */ + fReturn = PeekMessage (&msgNext, NULL, + WM_KEYDOWN, WM_SYSKEYDOWN, + PM_NOREMOVE); + } + if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) + fReturn = 0; + + /* Is next press an Alt_R with the same timestamp? */ + if (fReturn && msgNext.wParam == VK_MENU + && msgNext.time == lTime + && (HIWORD (msgNext.lParam) & KF_EXTENDED)) + { + /* + * Next key press is Alt_R with same timestamp as current + * Ctrl_L message. Therefore, this Ctrl_L press is a fake + * event, so discard it. + */ + return TRUE; + } + } + + /* + * Fake Ctrl_L releases will be followed by an Alt_R release + * with the same timestamp as the Ctrl_L release. + */ + if ((message == WM_KEYUP || message == WM_SYSKEYUP) + && wParam == VK_CONTROL + && (HIWORD (lParam) & KF_EXTENDED) == 0) + { + /* Got a Ctrl_L release */ + + /* Get time of current message */ + lTime = GetMessageTime (); + + /* Look for fake Ctrl_L release preceeding an Alt_R release. */ + fReturn = PeekMessage (&msgNext, NULL, + WM_KEYUP, WM_SYSKEYUP, + PM_NOREMOVE); + + /* + * Try again if the first call fails. + * NOTE: This usually happens when TweakUI is enabled. + */ + if (!fReturn) + { + /* Voodoo to make sure that the Alt_R message has posted */ + Sleep (0); + + /* Look for fake Ctrl_L release preceeding an Alt_R release. */ + fReturn = PeekMessage (&msgNext, NULL, + WM_KEYUP, WM_SYSKEYUP, + PM_NOREMOVE); + } + + if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP) + fReturn = 0; + + /* Is next press an Alt_R with the same timestamp? */ + if (fReturn + && (msgNext.message == WM_KEYUP + || msgNext.message == WM_SYSKEYUP) + && msgNext.wParam == VK_MENU + && msgNext.time == lTime + && (HIWORD (msgNext.lParam) & KF_EXTENDED)) + { + /* + * Next key release is Alt_R with same timestamp as current + * Ctrl_L message. Therefore, this Ctrl_L release is a fake + * event, so discard it. + */ + return TRUE; + } + } + + /* Not a fake control left press/release */ + return FALSE; +} + + +/* + * Lift any modifier keys that are pressed + */ + +void +winKeybdReleaseKeys () +{ + int i; + +#ifdef HAS_DEVWINDOWS + /* Verify that the mi input system has been initialized */ + if (g_fdMessageQueue == WIN_FD_INVALID) + return; +#endif + + /* Loop through all keys */ + for (i = 0; i < NUM_KEYCODES; ++i) + { + /* Pop key if pressed */ + if (g_winKeyState[i]) + winSendKeyEvent (i, FALSE); + + /* Reset pressed flag for keys */ + g_winKeyState[i] = FALSE; + } +} + + +/* + * Take a raw X key code and send an up or down event for it. + * + * Thanks to VNC for inspiration, though it is a simple function. + */ + +void +winSendKeyEvent (DWORD dwKey, Bool fDown) +{ + xEvent xCurrentEvent; + + /* + * When alt-tabing between screens we can get phantom key up messages + * Here we only pass them through it we think we should! + */ + if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return; + + /* Update the keyState map */ + g_winKeyState[dwKey] = fDown; + + ZeroMemory (&xCurrentEvent, sizeof (xCurrentEvent)); + + xCurrentEvent.u.u.type = fDown ? KeyPress : KeyRelease; + xCurrentEvent.u.keyButtonPointer.time = + g_c32LastInputEventTime = GetTickCount (); + xCurrentEvent.u.u.detail = dwKey + MIN_KEYCODE; + mieqEnqueue (&xCurrentEvent); +} + +BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam) +{ + switch (wParam) + { + case VK_CONTROL: + if ((lParam & 0x1ff0000) == 0x11d0000 && g_winKeyState[KEY_RCtrl]) + return TRUE; + if ((lParam & 0x1ff0000) == 0x01d0000 && g_winKeyState[KEY_LCtrl]) + return TRUE; + break; + case VK_SHIFT: + if ((lParam & 0x1ff0000) == 0x0360000 && g_winKeyState[KEY_ShiftR]) + return TRUE; + if ((lParam & 0x1ff0000) == 0x02a0000 && g_winKeyState[KEY_ShiftL]) + return TRUE; + break; + default: + return TRUE; + } + return FALSE; +} + +/* Only on shift release message is sent even if both are pressed. + * Fix this here + */ +void winFixShiftKeys (int iScanCode) +{ + if (GetKeyState (VK_SHIFT) & 0x8000) + return; + + if (iScanCode == KEY_ShiftL && g_winKeyState[KEY_ShiftR]) + winSendKeyEvent (KEY_ShiftR, FALSE); + if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL]) + winSendKeyEvent (KEY_ShiftL, FALSE); +} diff --git a/hw/xwin/winkeybd.h b/hw/xwin/winkeybd.h new file mode 100644 index 000000000..09eed1491 --- /dev/null +++ b/hw/xwin/winkeybd.h @@ -0,0 +1,309 @@ +#if !defined(WINKEYBD_H) +#define WINKEYBD_H +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Harold L Hunt II + */ + +/* + * We need symbols for the scan codes of keys. + */ +#include "winkeynames.h" + + +/* + * Include the standard ASCII keymap. + * + * This header declares a static KeySym array called 'map'. + */ +#include "winkeymap.h" + +#define WIN_KEYMAP_COLS 3 + +const int +g_iKeyMap [] = { + /* count Windows VK, ASCII, ASCII when extended VK */ + /* 0 */ 0, 0, 0, + /* 1 */ 0, 0, 0, + /* 2 */ 0, 0, 0, + /* 3 */ VK_CANCEL, 0, KEY_Break, + /* 4 */ 0, 0, 0, + /* 5 */ 0, 0, 0, + /* 6 */ 0, 0, 0, + /* 7 */ 0, 0, 0, + /* 8 */ 0, 0, 0, + /* 9 */ 0, 0, 0, + /* 10 */ 0, 0, 0, + /* 11 */ 0, 0, 0, + /* 12 */ 0, 0, 0, + /* 13 */ VK_RETURN, 0, KEY_KP_Enter, + /* 14 */ 0, 0, 0, + /* 15 */ 0, 0, 0, + /* 16 */ VK_SHIFT, 0, 0, + /* 17 */ VK_CONTROL, 0, KEY_RCtrl, + /* 18 */ VK_MENU, 0, KEY_AltLang, + /* 19 */ VK_PAUSE, KEY_Pause, 0, + /* 20 */ 0, 0, 0, + /* 21 */ 0, 0, 0, + /* 22 */ 0, 0, 0, + /* 23 */ 0, 0, 0, + /* 24 */ 0, 0, 0, + /* 25 */ 0, 0, 0, + /* 26 */ 0, 0, 0, + /* 27 */ 0, 0, 0, + /* 28 */ 0, 0, 0, + /* 29 */ 0, 0, 0, + /* 30 */ 0, 0, 0, + /* 31 */ 0, 0, 0, + /* 32 */ 0, 0, 0, + /* 33 */ VK_PRIOR, 0, KEY_PgUp, + /* 34 */ VK_NEXT, 0, KEY_PgDown, + /* 35 */ VK_END, 0, KEY_End, + /* 36 */ VK_HOME, 0, KEY_Home, + /* 37 */ VK_LEFT, 0, KEY_Left, + /* 38 */ VK_UP, 0, KEY_Up, + /* 39 */ VK_RIGHT, 0, KEY_Right, + /* 40 */ VK_DOWN, 0, KEY_Down, + /* 41 */ 0, 0, 0, + /* 42 */ 0, 0, 0, + /* 43 */ 0, 0, 0, + /* 44 */ VK_SNAPSHOT, 0, KEY_Print, + /* 45 */ VK_INSERT, 0, KEY_Insert, + /* 46 */ VK_DELETE, 0, KEY_Delete, + /* 47 */ 0, 0, 0, + /* 48 */ 0, 0, 0, + /* 49 */ 0, 0, 0, + /* 50 */ 0, 0, 0, + /* 51 */ 0, 0, 0, + /* 52 */ 0, 0, 0, + /* 53 */ 0, 0, 0, + /* 54 */ 0, 0, 0, + /* 55 */ 0, 0, 0, + /* 56 */ 0, 0, 0, + /* 57 */ 0, 0, 0, + /* 58 */ 0, 0, 0, + /* 59 */ 0, 0, 0, + /* 60 */ 0, 0, 0, + /* 61 */ 0, 0, 0, + /* 62 */ 0, 0, 0, + /* 63 */ 0, 0, 0, + /* 64 */ 0, 0, 0, + /* 65 */ 0, 0, 0, + /* 66 */ 0, 0, 0, + /* 67 */ 0, 0, 0, + /* 68 */ 0, 0, 0, + /* 69 */ 0, 0, 0, + /* 70 */ 0, 0, 0, + /* 71 */ 0, 0, 0, + /* 72 */ 0, 0, 0, + /* 73 */ 0, 0, 0, + /* 74 */ 0, 0, 0, + /* 75 */ 0, 0, 0, + /* 76 */ 0, 0, 0, + /* 77 */ 0, 0, 0, + /* 78 */ 0, 0, 0, + /* 79 */ 0, 0, 0, + /* 80 */ 0, 0, 0, + /* 81 */ 0, 0, 0, + /* 82 */ 0, 0, 0, + /* 83 */ 0, 0, 0, + /* 84 */ 0, 0, 0, + /* 85 */ 0, 0, 0, + /* 86 */ 0, 0, 0, + /* 87 */ 0, 0, 0, + /* 88 */ 0, 0, 0, + /* 89 */ 0, 0, 0, + /* 90 */ 0, 0, 0, + /* 91 */ VK_LWIN, KEY_LMeta, 0, + /* 92 */ VK_RWIN, KEY_RMeta, 0, + /* 93 */ VK_APPS, KEY_Menu, 0, + /* 94 */ 0, 0, 0, + /* 95 */ 0, 0, 0, + /* 96 */ 0, 0, 0, + /* 97 */ 0, 0, 0, + /* 98 */ 0, 0, 0, + /* 99 */ 0, 0, 0, + /* 100 */ 0, 0, 0, + /* 101 */ 0, 0, 0, + /* 102 */ 0, 0, 0, + /* 103 */ 0, 0, 0, + /* 104 */ 0, 0, 0, + /* 105 */ 0, 0, 0, + /* 106 */ 0, 0, 0, + /* 107 */ 0, 0, 0, + /* 108 */ 0, 0, 0, + /* 109 */ 0, 0, 0, + /* 110 */ 0, 0, 0, + /* 111 */ VK_DIVIDE, 0, KEY_KP_Divide, + /* 112 */ 0, 0, 0, + /* 113 */ 0, 0, 0, + /* 114 */ 0, 0, 0, + /* 115 */ 0, 0, 0, + /* 116 */ 0, 0, 0, + /* 117 */ 0, 0, 0, + /* 118 */ 0, 0, 0, + /* 119 */ 0, 0, 0, + /* 120 */ 0, 0, 0, + /* 121 */ 0, 0, 0, + /* 122 */ 0, 0, 0, + /* 123 */ 0, 0, 0, + /* 124 */ 0, 0, 0, + /* 125 */ 0, 0, 0, + /* 126 */ 0, 0, 0, + /* 127 */ 0, 0, 0, + /* 128 */ 0, 0, 0, + /* 129 */ 0, 0, 0, + /* 130 */ 0, 0, 0, + /* 131 */ 0, 0, 0, + /* 132 */ 0, 0, 0, + /* 133 */ 0, 0, 0, + /* 134 */ 0, 0, 0, + /* 135 */ 0, 0, 0, + /* 136 */ 0, 0, 0, + /* 137 */ 0, 0, 0, + /* 138 */ 0, 0, 0, + /* 139 */ 0, 0, 0, + /* 140 */ 0, 0, 0, + /* 141 */ 0, 0, 0, + /* 142 */ 0, 0, 0, + /* 143 */ 0, 0, 0, + /* 144 */ 0, 0, 0, + /* 145 */ 0, 0, 0, + /* 146 */ 0, 0, 0, + /* 147 */ 0, 0, 0, + /* 148 */ 0, 0, 0, + /* 149 */ 0, 0, 0, + /* 150 */ 0, 0, 0, + /* 151 */ 0, 0, 0, + /* 152 */ 0, 0, 0, + /* 153 */ 0, 0, 0, + /* 154 */ 0, 0, 0, + /* 155 */ 0, 0, 0, + /* 156 */ 0, 0, 0, + /* 157 */ 0, 0, 0, + /* 158 */ 0, 0, 0, + /* 159 */ 0, 0, 0, + /* 160 */ 0, 0, 0, + /* 161 */ 0, 0, 0, + /* 162 */ 0, 0, 0, + /* 163 */ 0, 0, 0, + /* 164 */ 0, 0, 0, + /* 165 */ 0, 0, 0, + /* 166 */ 0, 0, 0, + /* 167 */ 0, 0, 0, + /* 168 */ 0, 0, 0, + /* 169 */ 0, 0, 0, + /* 170 */ 0, 0, 0, + /* 171 */ 0, 0, 0, + /* 172 */ 0, 0, 0, + /* 173 */ 0, 0, 0, + /* 174 */ 0, 0, 0, + /* 175 */ 0, 0, 0, + /* 176 */ 0, 0, 0, + /* 177 */ 0, 0, 0, + /* 178 */ 0, 0, 0, + /* 179 */ 0, 0, 0, + /* 180 */ 0, 0, 0, + /* 181 */ 0, 0, 0, + /* 182 */ 0, 0, 0, + /* 183 */ 0, 0, 0, + /* 184 */ 0, 0, 0, + /* 185 */ 0, 0, 0, + /* 186 */ 0, 0, 0, + /* 187 */ 0, 0, 0, + /* 188 */ 0, 0, 0, + /* 189 */ 0, 0, 0, + /* 190 */ 0, 0, 0, + /* 191 */ 0, 0, 0, + /* 192 */ 0, 0, 0, + /* 193 */ 0, 0, 0, + /* 194 */ 0, 0, 0, + /* 195 */ 0, 0, 0, + /* 196 */ 0, 0, 0, + /* 197 */ 0, 0, 0, + /* 198 */ 0, 0, 0, + /* 199 */ 0, 0, 0, + /* 200 */ 0, 0, 0, + /* 201 */ 0, 0, 0, + /* 202 */ 0, 0, 0, + /* 203 */ 0, 0, 0, + /* 204 */ 0, 0, 0, + /* 205 */ 0, 0, 0, + /* 206 */ 0, 0, 0, + /* 207 */ 0, 0, 0, + /* 208 */ 0, 0, 0, + /* 209 */ 0, 0, 0, + /* 210 */ 0, 0, 0, + /* 211 */ 0, 0, 0, + /* 212 */ 0, 0, 0, + /* 213 */ 0, 0, 0, + /* 214 */ 0, 0, 0, + /* 215 */ 0, 0, 0, + /* 216 */ 0, 0, 0, + /* 217 */ 0, 0, 0, + /* 218 */ 0, 0, 0, + /* 219 */ 0, 0, 0, + /* 220 */ 0, 0, 0, + /* 221 */ 0, 0, 0, + /* 222 */ 0, 0, 0, + /* 223 */ 0, 0, 0, + /* 224 */ 0, 0, 0, + /* 225 */ 0, 0, 0, + /* 226 */ 0, 0, 0, + /* 227 */ 0, 0, 0, + /* 228 */ 0, 0, 0, + /* 229 */ 0, 0, 0, + /* 230 */ 0, 0, 0, + /* 231 */ 0, 0, 0, + /* 232 */ 0, 0, 0, + /* 233 */ 0, 0, 0, + /* 234 */ 0, 0, 0, + /* 235 */ 0, 0, 0, + /* 236 */ 0, 0, 0, + /* 237 */ 0, 0, 0, + /* 238 */ 0, 0, 0, + /* 239 */ 0, 0, 0, + /* 240 */ 0, 0, 0, + /* 241 */ 0, 0, 0, + /* 242 */ 0, 0, 0, + /* 243 */ 0, 0, 0, + /* 244 */ 0, 0, 0, + /* 245 */ 0, 0, 0, + /* 246 */ 0, 0, 0, + /* 247 */ 0, 0, 0, + /* 248 */ 0, 0, 0, + /* 249 */ 0, 0, 0, + /* 250 */ 0, 0, 0, + /* 251 */ 0, 0, 0, + /* 252 */ 0, 0, 0, + /* 253 */ 0, 0, 0, + /* 254 */ 0, 0, 0, + /* 255 */ 0, 0, 0 +}; + +#endif /* WINKEYBD_H */ diff --git a/hw/xwin/winkeyhook.c b/hw/xwin/winkeyhook.c new file mode 100755 index 000000000..53d91e6ee --- /dev/null +++ b/hw/xwin/winkeyhook.c @@ -0,0 +1,194 @@ +/* + *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 <xwin-config.h> +#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 () +{ + 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 () +{ + if (g_hhookKeyboardLL) + UnhookWindowsHookEx (g_hhookKeyboardLL); + g_hhookKeyboardLL = NULL; +} diff --git a/hw/xwin/winkeymap.h b/hw/xwin/winkeymap.h new file mode 100644 index 000000000..3862f0379 --- /dev/null +++ b/hw/xwin/winkeymap.h @@ -0,0 +1,136 @@ +/* + * + * For Scancodes see notes in winkeynames.h !!!! + * + */ + +static KeySym map[NUM_KEYCODES * GLYPHS_PER_KEY] = { + /* 0x00 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x01 */ XK_Escape, NoSymbol, NoSymbol, NoSymbol, + /* 0x02 */ XK_1, XK_exclam, NoSymbol, NoSymbol, + /* 0x03 */ XK_2, XK_at, NoSymbol, NoSymbol, + /* 0x04 */ XK_3, XK_numbersign, NoSymbol, NoSymbol, + /* 0x05 */ XK_4, XK_dollar, NoSymbol, NoSymbol, + /* 0x06 */ XK_5, XK_percent, NoSymbol, NoSymbol, + /* 0x07 */ XK_6, XK_asciicircum, NoSymbol, NoSymbol, + /* 0x08 */ XK_7, XK_ampersand, NoSymbol, NoSymbol, + /* 0x09 */ XK_8, XK_asterisk, NoSymbol, NoSymbol, + /* 0x0a */ XK_9, XK_parenleft, NoSymbol, NoSymbol, + /* 0x0b */ XK_0, XK_parenright, NoSymbol, NoSymbol, + /* 0x0c */ XK_minus, XK_underscore, NoSymbol, NoSymbol, + /* 0x0d */ XK_equal, XK_plus, NoSymbol, NoSymbol, + /* 0x0e */ XK_BackSpace, NoSymbol, NoSymbol, NoSymbol, + /* 0x0f */ XK_Tab, XK_ISO_Left_Tab,NoSymbol, NoSymbol, + /* 0x10 */ XK_Q, NoSymbol, NoSymbol, NoSymbol, + /* 0x11 */ XK_W, NoSymbol, NoSymbol, NoSymbol, + /* 0x12 */ XK_E, NoSymbol, NoSymbol, NoSymbol, + /* 0x13 */ XK_R, NoSymbol, NoSymbol, NoSymbol, + /* 0x14 */ XK_T, NoSymbol, NoSymbol, NoSymbol, + /* 0x15 */ XK_Y, NoSymbol, NoSymbol, NoSymbol, + /* 0x16 */ XK_U, NoSymbol, NoSymbol, NoSymbol, + /* 0x17 */ XK_I, NoSymbol, NoSymbol, NoSymbol, + /* 0x18 */ XK_O, NoSymbol, NoSymbol, NoSymbol, + /* 0x19 */ XK_P, NoSymbol, NoSymbol, NoSymbol, + /* 0x1a */ XK_bracketleft, XK_braceleft, NoSymbol, NoSymbol, + /* 0x1b */ XK_bracketright,XK_braceright, NoSymbol, NoSymbol, + /* 0x1c */ XK_Return, NoSymbol, NoSymbol, NoSymbol, + /* 0x1d */ XK_Control_L, NoSymbol, NoSymbol, NoSymbol, + /* 0x1e */ XK_A, NoSymbol, NoSymbol, NoSymbol, + /* 0x1f */ XK_S, NoSymbol, NoSymbol, NoSymbol, + /* 0x20 */ XK_D, NoSymbol, NoSymbol, NoSymbol, + /* 0x21 */ XK_F, NoSymbol, NoSymbol, NoSymbol, + /* 0x22 */ XK_G, NoSymbol, NoSymbol, NoSymbol, + /* 0x23 */ XK_H, NoSymbol, NoSymbol, NoSymbol, + /* 0x24 */ XK_J, NoSymbol, NoSymbol, NoSymbol, + /* 0x25 */ XK_K, NoSymbol, NoSymbol, NoSymbol, + /* 0x26 */ XK_L, NoSymbol, NoSymbol, NoSymbol, + /* 0x27 */ XK_semicolon, XK_colon, NoSymbol, NoSymbol, + /* 0x28 */ XK_quoteright, XK_quotedbl, NoSymbol, NoSymbol, + /* 0x29 */ XK_quoteleft, XK_asciitilde, NoSymbol, NoSymbol, + /* 0x2a */ XK_Shift_L, NoSymbol, NoSymbol, NoSymbol, + /* 0x2b */ XK_backslash, XK_bar, NoSymbol, NoSymbol, + /* 0x2c */ XK_Z, NoSymbol, NoSymbol, NoSymbol, + /* 0x2d */ XK_X, NoSymbol, NoSymbol, NoSymbol, + /* 0x2e */ XK_C, NoSymbol, NoSymbol, NoSymbol, + /* 0x2f */ XK_V, NoSymbol, NoSymbol, NoSymbol, + /* 0x30 */ XK_B, NoSymbol, NoSymbol, NoSymbol, + /* 0x31 */ XK_N, NoSymbol, NoSymbol, NoSymbol, + /* 0x32 */ XK_M, NoSymbol, NoSymbol, NoSymbol, + /* 0x33 */ XK_comma, XK_less, NoSymbol, NoSymbol, + /* 0x34 */ XK_period, XK_greater, NoSymbol, NoSymbol, + /* 0x35 */ XK_slash, XK_question, NoSymbol, NoSymbol, + /* 0x36 */ XK_Shift_R, NoSymbol, NoSymbol, NoSymbol, + /* 0x37 */ XK_KP_Multiply, NoSymbol, NoSymbol, NoSymbol, + /* 0x38 */ XK_Alt_L, XK_Meta_L, NoSymbol, NoSymbol, + /* 0x39 */ XK_space, NoSymbol, NoSymbol, NoSymbol, + /* 0x3a */ XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol, + /* 0x3b */ XK_F1, NoSymbol, NoSymbol, NoSymbol, + /* 0x3c */ XK_F2, NoSymbol, NoSymbol, NoSymbol, + /* 0x3d */ XK_F3, NoSymbol, NoSymbol, NoSymbol, + /* 0x3e */ XK_F4, NoSymbol, NoSymbol, NoSymbol, + /* 0x3f */ XK_F5, NoSymbol, NoSymbol, NoSymbol, + /* 0x40 */ XK_F6, NoSymbol, NoSymbol, NoSymbol, + /* 0x41 */ XK_F7, NoSymbol, NoSymbol, NoSymbol, + /* 0x42 */ XK_F8, NoSymbol, NoSymbol, NoSymbol, + /* 0x43 */ XK_F9, NoSymbol, NoSymbol, NoSymbol, + /* 0x44 */ XK_F10, NoSymbol, NoSymbol, NoSymbol, + /* 0x45 */ XK_Num_Lock, NoSymbol, NoSymbol, NoSymbol, + /* 0x46 */ XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol, + /* 0x47 */ XK_KP_Home, XK_KP_7, NoSymbol, NoSymbol, + /* 0x48 */ XK_KP_Up, XK_KP_8, NoSymbol, NoSymbol, + /* 0x49 */ XK_KP_Prior, XK_KP_9, NoSymbol, NoSymbol, + /* 0x4a */ XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol, + /* 0x4b */ XK_KP_Left, XK_KP_4, NoSymbol, NoSymbol, + /* 0x4c */ XK_KP_Begin, XK_KP_5, NoSymbol, NoSymbol, + /* 0x4d */ XK_KP_Right, XK_KP_6, NoSymbol, NoSymbol, + /* 0x4e */ XK_KP_Add, NoSymbol, NoSymbol, NoSymbol, + /* 0x4f */ XK_KP_End, XK_KP_1, NoSymbol, NoSymbol, + /* 0x50 */ XK_KP_Down, XK_KP_2, NoSymbol, NoSymbol, + /* 0x51 */ XK_KP_Next, XK_KP_3, NoSymbol, NoSymbol, + /* 0x52 */ XK_KP_Insert, XK_KP_0, NoSymbol, NoSymbol, + /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, NoSymbol, NoSymbol, + /* 0x54 */ XK_Sys_Req, NoSymbol, NoSymbol, NoSymbol, + /* 0x55 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x56 */ XK_less, XK_greater, NoSymbol, NoSymbol, + /* 0x57 */ XK_F11, NoSymbol, NoSymbol, NoSymbol, + /* 0x58 */ XK_F12, NoSymbol, NoSymbol, NoSymbol, + /* 0x59 */ XK_Home, NoSymbol, NoSymbol, NoSymbol, + /* 0x5a */ XK_Up, NoSymbol, NoSymbol, NoSymbol, + /* 0x5b */ XK_Prior, NoSymbol, NoSymbol, NoSymbol, + /* 0x5c */ XK_Left, NoSymbol, NoSymbol, NoSymbol, + /* 0x5d */ XK_Begin, NoSymbol, NoSymbol, NoSymbol, + /* 0x5e */ XK_Right, NoSymbol, NoSymbol, NoSymbol, + /* 0x5f */ XK_End, NoSymbol, NoSymbol, NoSymbol, + /* 0x60 */ XK_Down, NoSymbol, NoSymbol, NoSymbol, + /* 0x61 */ XK_Next, NoSymbol, NoSymbol, NoSymbol, + /* 0x62 */ XK_Insert, NoSymbol, NoSymbol, NoSymbol, + /* 0x63 */ XK_Delete, NoSymbol, NoSymbol, NoSymbol, + /* 0x64 */ XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol, + /* 0x65 */ XK_Control_R, NoSymbol, NoSymbol, NoSymbol, + /* 0x66 */ XK_Pause, NoSymbol, NoSymbol, NoSymbol, + /* 0x67 */ XK_Print, NoSymbol, NoSymbol, NoSymbol, + /* 0x68 */ XK_KP_Divide, NoSymbol, NoSymbol, NoSymbol, + /* 0x69 */ XK_Alt_R, XK_Meta_R, NoSymbol, NoSymbol, + /* 0x6a */ XK_Break, NoSymbol, NoSymbol, NoSymbol, + /* 0x6b */ XK_Meta_L, NoSymbol, NoSymbol, NoSymbol, + /* 0x6c */ XK_Meta_R, NoSymbol, NoSymbol, NoSymbol, + /* 0x6d */ XK_Menu, NoSymbol, NoSymbol, NoSymbol, + /* 0x6e */ XK_F13, NoSymbol, NoSymbol, NoSymbol, + /* 0x6f */ XK_F14, NoSymbol, NoSymbol, NoSymbol, + /* 0x70 */ XK_F15, NoSymbol, NoSymbol, NoSymbol, + /* 0x71 */ XK_F16, NoSymbol, NoSymbol, NoSymbol, + /* 0x72 */ XK_F17, NoSymbol, NoSymbol, NoSymbol, + /* 0x73 */ XK_backslash, XK_underscore, NoSymbol, NoSymbol, + /* 0x74 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x75 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x76 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x77 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x78 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x79 */ XK_Henkan, XK_Mode_switch, NoSymbol, NoSymbol, + /* 0x7a */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x7b */ XK_Muhenkan, NoSymbol, NoSymbol, NoSymbol, + /* 0x7c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x7d */ XK_backslash, XK_bar, NoSymbol, NoSymbol, + /* 0x7e */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, + /* 0x7f */ NoSymbol, NoSymbol, NoSymbol, NoSymbol, +}; diff --git a/hw/xwin/winkeynames.h b/hw/xwin/winkeynames.h new file mode 100644 index 000000000..7c16337de --- /dev/null +++ b/hw/xwin/winkeynames.h @@ -0,0 +1,202 @@ +#ifndef _WINKEYNAMES_H +#define _WINKEYNAMES_H +/* + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. + * + * 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, and that the name of Thomas Roell not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Roell makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + +#define XK_TECHNICAL +#define XK_KATAKANA +#include <X11/keysym.h> + +#define GLYPHS_PER_KEY 4 +#define NUM_KEYCODES 248 +#define MIN_KEYCODE 8 +#define MAX_KEYCODE (NUM_KEYCODES + MIN_KEYCODE - 1) + +#define AltMask Mod1Mask +#define NumLockMask Mod2Mask +#define AltLangMask Mod3Mask +#define KanaMask Mod4Mask +#define ScrollLockMask Mod5Mask + +#define KeyPressed(k) (keyc->down[k >> 3] & (1 << (k & 7))) +#define ModifierDown(k) ((keyc->state & (k)) == (k)) + +/* + * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three) + * sets of scancodes. Set3 can only be generated by a MF keyboard. + * Set2 sends a makecode for keypress, and the same code prefixed by a + * F0 for keyrelease. This is a little bit ugly to handle. Thus we use + * here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes. + * Bit 7 ist set if the key is released. The code E0 switches to a + * different meaning to add the new MF cursorkeys, while not breaking old + * applications. E1 is another special prefix. Since I assume that there + * will be further versions of PC/XT scancode compatible keyboards, we + * may be in trouble one day. + * + * IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3. + * 2) Use the keyboards native set and translate it to common keysyms. + */ + +/* + * definition of the AT84/MF101/MF102 Keyboard: + * ============================================================ + * Defined Key Cap Glyphs Pressed value + * Key Name Main Also (hex) (dec) + * ---------------- ---------- ------- ------ ------ + */ + +#define KEY_Escape /* Escape 0x01 */ 1 +#define KEY_1 /* 1 ! 0x02 */ 2 +#define KEY_2 /* 2 @ 0x03 */ 3 +#define KEY_3 /* 3 # 0x04 */ 4 +#define KEY_4 /* 4 $ 0x05 */ 5 +#define KEY_5 /* 5 % 0x06 */ 6 +#define KEY_6 /* 6 ^ 0x07 */ 7 +#define KEY_7 /* 7 & 0x08 */ 8 +#define KEY_8 /* 8 * 0x09 */ 9 +#define KEY_9 /* 9 ( 0x0a */ 10 +#define KEY_0 /* 0 ) 0x0b */ 11 +#define KEY_Minus /* - (Minus) _ (Under) 0x0c */ 12 +#define KEY_Equal /* = (Equal) + 0x0d */ 13 +#define KEY_BackSpace /* Back Space 0x0e */ 14 +#define KEY_Tab /* Tab 0x0f */ 15 +#define KEY_Q /* Q 0x10 */ 16 +#define KEY_W /* W 0x11 */ 17 +#define KEY_E /* E 0x12 */ 18 +#define KEY_R /* R 0x13 */ 19 +#define KEY_T /* T 0x14 */ 20 +#define KEY_Y /* Y 0x15 */ 21 +#define KEY_U /* U 0x16 */ 22 +#define KEY_I /* I 0x17 */ 23 +#define KEY_O /* O 0x18 */ 24 +#define KEY_P /* P 0x19 */ 25 +#define KEY_LBrace /* [ { 0x1a */ 26 +#define KEY_RBrace /* ] } 0x1b */ 27 +#define KEY_Enter /* Enter 0x1c */ 28 +#define KEY_LCtrl /* Ctrl(left) 0x1d */ 29 +#define KEY_A /* A 0x1e */ 30 +#define KEY_S /* S 0x1f */ 31 +#define KEY_D /* D 0x20 */ 32 +#define KEY_F /* F 0x21 */ 33 +#define KEY_G /* G 0x22 */ 34 +#define KEY_H /* H 0x23 */ 35 +#define KEY_J /* J 0x24 */ 36 +#define KEY_K /* K 0x25 */ 37 +#define KEY_L /* L 0x26 */ 38 +#define KEY_SemiColon /* ;(SemiColon) :(Colon) 0x27 */ 39 +#define KEY_Quote /* ' (Apostr) " (Quote) 0x28 */ 40 +#define KEY_Tilde /* ` (Accent) ~ (Tilde) 0x29 */ 41 +#define KEY_ShiftL /* Shift(left) 0x2a */ 42 +#define KEY_BSlash /* \(BckSlash) |(VertBar)0x2b */ 43 +#define KEY_Z /* Z 0x2c */ 44 +#define KEY_X /* X 0x2d */ 45 +#define KEY_C /* C 0x2e */ 46 +#define KEY_V /* V 0x2f */ 47 +#define KEY_B /* B 0x30 */ 48 +#define KEY_N /* N 0x31 */ 49 +#define KEY_M /* M 0x32 */ 50 +#define KEY_Comma /* , (Comma) < (Less) 0x33 */ 51 +#define KEY_Period /* . (Period) >(Greater)0x34 */ 52 +#define KEY_Slash /* / (Slash) ? 0x35 */ 53 +#define KEY_ShiftR /* Shift(right) 0x36 */ 54 +#define KEY_KP_Multiply /* * 0x37 */ 55 +#define KEY_Alt /* Alt(left) 0x38 */ 56 +#define KEY_Space /* (SpaceBar) 0x39 */ 57 +#define KEY_CapsLock /* CapsLock 0x3a */ 58 +#define KEY_F1 /* F1 0x3b */ 59 +#define KEY_F2 /* F2 0x3c */ 60 +#define KEY_F3 /* F3 0x3d */ 61 +#define KEY_F4 /* F4 0x3e */ 62 +#define KEY_F5 /* F5 0x3f */ 63 +#define KEY_F6 /* F6 0x40 */ 64 +#define KEY_F7 /* F7 0x41 */ 65 +#define KEY_F8 /* F8 0x42 */ 66 +#define KEY_F9 /* F9 0x43 */ 67 +#define KEY_F10 /* F10 0x44 */ 68 +#define KEY_NumLock /* NumLock 0x45 */ 69 +#define KEY_ScrollLock /* ScrollLock 0x46 */ 70 +#define KEY_KP_7 /* 7 Home 0x47 */ 71 +#define KEY_KP_8 /* 8 Up 0x48 */ 72 +#define KEY_KP_9 /* 9 PgUp 0x49 */ 73 +#define KEY_KP_Minus /* - (Minus) 0x4a */ 74 +#define KEY_KP_4 /* 4 Left 0x4b */ 75 +#define KEY_KP_5 /* 5 0x4c */ 76 +#define KEY_KP_6 /* 6 Right 0x4d */ 77 +#define KEY_KP_Plus /* + (Plus) 0x4e */ 78 +#define KEY_KP_1 /* 1 End 0x4f */ 79 +#define KEY_KP_2 /* 2 Down 0x50 */ 80 +#define KEY_KP_3 /* 3 PgDown 0x51 */ 81 +#define KEY_KP_0 /* 0 Insert 0x52 */ 82 +#define KEY_KP_Decimal /* . (Decimal) Delete 0x53 */ 83 +#define KEY_SysReqest /* SysReqest 0x54 */ 84 + /* NOTUSED 0x55 */ +#define KEY_Less /* < (Less) >(Greater) 0x56 */ 86 +#define KEY_F11 /* F11 0x57 */ 87 +#define KEY_F12 /* F12 0x58 */ 88 + +#define KEY_Prefix0 /* special 0x60 */ 96 +#define KEY_Prefix1 /* specail 0x61 */ 97 + +/* + * The 'scancodes' below are generated by the server, because the MF101/102 + * keyboard sends them as sequence of other scancodes + */ +#define KEY_Home /* Home 0x59 */ 89 +#define KEY_Up /* Up 0x5a */ 90 +#define KEY_PgUp /* PgUp 0x5b */ 91 +#define KEY_Left /* Left 0x5c */ 92 +#define KEY_Begin /* Begin 0x5d */ 93 +#define KEY_Right /* Right 0x5e */ 94 +#define KEY_End /* End 0x5f */ 95 +#define KEY_Down /* Down 0x60 */ 96 +#define KEY_PgDown /* PgDown 0x61 */ 97 +#define KEY_Insert /* Insert 0x62 */ 98 +#define KEY_Delete /* Delete 0x63 */ 99 +#define KEY_KP_Enter /* Enter 0x64 */ 100 +#define KEY_RCtrl /* Ctrl(right) 0x65 */ 101 +#define KEY_Pause /* Pause 0x66 */ 102 +#define KEY_Print /* Print 0x67 */ 103 +#define KEY_KP_Divide /* Divide 0x68 */ 104 +#define KEY_AltLang /* AtlLang(right) 0x69 */ 105 +#define KEY_Break /* Break 0x6a */ 106 +#define KEY_LMeta /* Left Meta 0x6b */ 107 +#define KEY_RMeta /* Right Meta 0x6c */ 108 +#define KEY_Menu /* Menu 0x6d */ 109 +#define KEY_F13 /* F13 0x6e */ 110 +#define KEY_F14 /* F14 0x6f */ 111 +#define KEY_F15 /* F15 0x70 */ 112 +#define KEY_F16 /* F16 0x71 */ 113 +#define KEY_F17 /* F17 0x72 */ 114 +#define KEY_KP_DEC /* KP_DEC 0x73 */ 115 +#define KEY_KP_Equal /* Equal (Keypad) 0x76 */ 118 +#define KEY_XFER /* Kanji Transfer 0x79 */ 121 +#define KEY_NFER /* No Kanji Transfer 0x7b */ 123 +#define KEY_Yen /* Yen 0x7d */ 125 +#define KEY_HKTG /* Hirugana/Katakana tog 0xc8 */ 200 +#define KEY_BSlash2 /* \ _ 0xcb */ 203 + +/* These are for "notused" and "unknown" entries in translation maps. */ +#define KEY_NOTUSED 0 +#define KEY_UNKNOWN 255 + +#endif /* _WINKEYNAMES_H */ diff --git a/hw/xwin/winlayouts.h b/hw/xwin/winlayouts.h new file mode 100644 index 000000000..cc0752430 --- /dev/null +++ b/hw/xwin/winlayouts.h @@ -0,0 +1,257 @@ +/* + * 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; + +WinKBLayoutRec winKBLayouts[] = +{ + { 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", "de_CH", NULL, 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)"}, + { 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_enhanced", NULL, NULL, "French (Canada)"}, + { 0x100c, -1, "pc105", "fr_CH", NULL, NULL, "French (Switzerland)"}, + { 0x40e, -1, "pc105", "hu", NULL, NULL, "Hungarian"}, + { 0x410, -1, "pc105", "it", NULL, NULL, "Italian"}, + { 0x411, 7, "jp106", "jp", NULL, NULL, "Japanese"}, + { 0x813, -1, "pc105", "be", NULL, NULL, "Dutch (Belgian)"}, + { 0x414, -1, "pc105", "no", NULL, NULL, "Norwegian"}, + { 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)"}, + { 0x41d, -1, "pc105", "se", NULL, NULL, "Swedish (Sweden)"}, + { -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) +*/ + + diff --git a/hw/xwin/winmessages.h b/hw/xwin/winmessages.h new file mode 100755 index 000000000..ae50dc474 --- /dev/null +++ b/hw/xwin/winmessages.h @@ -0,0 +1,1030 @@ +#ifndef __WINMESSAGES_H__ +#define __WINMESSAGES_H__ +static const unsigned MESSAGE_NAMES_LEN =1024; +static const char *MESSAGE_NAMES[1024] = { + "WM_NULL", + "WM_CREATE", + "WM_DESTROY", + "WM_MOVE", + "4", + "WM_SIZE", + "WM_ACTIVATE", + "WM_SETFOCUS", + "WM_KILLFOCUS", + "9", + "WM_ENABLE", + "WM_SETREDRAW", + "WM_SETTEXT", + "WM_GETTEXT", + "WM_GETTEXTLENGTH", + "WM_PAINT", + "WM_CLOSE", + "WM_QUERYENDSESSION", + "WM_QUIT", + "WM_QUERYOPEN", + "WM_ERASEBKGND", + "WM_SYSCOLORCHANGE", + "WM_ENDSESSION", + "23", + "WM_SHOWWINDOW", + "25", + "WM_WININICHANGE", + "WM_DEVMODECHANGE", + "WM_ACTIVATEAPP", + "WM_FONTCHANGE", + "WM_TIMECHANGE", + "WM_CANCELMODE", + NULL /* WM_SETCURSOR */, + "WM_MOUSEACTIVATE", + "WM_CHILDACTIVATE", + "WM_QUEUESYNC", + "WM_GETMINMAXINFO", + "37", + "WM_PAINTICON", + "WM_ICONERASEBKGND", + "WM_NEXTDLGCTL", + "41", + "WM_SPOOLERSTATUS", + "WM_DRAWITEM", + "WM_MEASUREITEM", + "WM_DELETEITEM", + "WM_VKEYTOITEM", + "WM_CHARTOITEM", + "WM_SETFONT", + "WM_GETFONT", + "WM_SETHOTKEY", + "WM_GETHOTKEY", + "52", + "53", + "54", + "WM_QUERYDRAGICON", + "56", + "WM_COMPAREITEM", + "58", + "59", + "60", + "61", + "62", + "63", + "64", + "WM_COMPACTING", + "66", + "67", + "WM_COMMNOTIFY", + "69", + "WM_WINDOWPOSCHANGING", + "WM_WINDOWPOSCHANGED", + "WM_POWER", + "73", + "WM_COPYDATA", + "WM_CANCELJOURNAL", + "76", + "77", + "WM_NOTIFY", + "79", + "WM_INPUTLANGCHANGEREQUEST", + "WM_INPUTLANGCHANGE", + "WM_TCARD", + "WM_HELP", + "WM_USERCHANGED", + "WM_NOTIFYFORMAT", + "86", + "87", + "88", + "89", + "90", + "91", + "92", + "93", + "94", + "95", + "96", + "97", + "98", + "99", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "WM_CONTEXTMENU", + "WM_STYLECHANGING", + "WM_STYLECHANGED", + "WM_DISPLAYCHANGE", + "WM_GETICON", + "WM_SETICON", + "WM_NCCREATE", + "WM_NCDESTROY", + "WM_NCCALCSIZE", + NULL /* WM_NCHITTEST */, + "WM_NCPAINT", + "WM_NCACTIVATE", + "WM_GETDLGCODE", + "WM_SYNCPAINT", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + NULL /* WM_NCMOUSEMOVE */, + "WM_NCLBUTTONDOWN", + "WM_NCLBUTTONUP", + "WM_NCLBUTTONDBLCLK", + "WM_NCRBUTTONDOWN", + "WM_NCRBUTTONUP", + "WM_NCRBUTTONDBLCLK", + "WM_NCMBUTTONDOWN", + "WM_NCMBUTTONUP", + "WM_NCMBUTTONDBLCLK", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "WM_KEYDOWN", + "WM_KEYUP", + "WM_CHAR", + "WM_DEADCHAR", + "WM_SYSKEYDOWN", + "WM_SYSKEYUP", + "WM_SYSCHAR", + "WM_SYSDEADCHAR", + "WM_CONVERTREQUESTEX", + "265", + "266", + "267", + "268", + "WM_IME_STARTCOMPOSITION", + "WM_IME_ENDCOMPOSITION", + "WM_IME_KEYLAST", + "WM_INITDIALOG", + "WM_COMMAND", + "WM_SYSCOMMAND", + NULL /* WM_TIMER */, + "WM_HSCROLL", + "WM_VSCROLL", + "WM_INITMENU", + "WM_INITMENUPOPUP", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "WM_MENUSELECT", + "WM_MENUCHAR", + "WM_ENTERIDLE", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "WM_CTLCOLORMSGBOX", + "WM_CTLCOLOREDIT", + "WM_CTLCOLORLISTBOX", + "WM_CTLCOLORBTN", + "WM_CTLCOLORDLG", + "WM_CTLCOLORSCROLLBAR", + "WM_CTLCOLORSTATIC", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + NULL /* WM_MOUSEMOVE */, + "WM_LBUTTONDOWN", + "WM_LBUTTONUP", + "WM_LBUTTONDBLCLK", + "WM_RBUTTONDOWN", + "WM_RBUTTONUP", + "WM_RBUTTONDBLCLK", + "WM_MBUTTONDOWN", + "WM_MBUTTONUP", + "WM_MBUTTONDBLCLK", + "WM_MOUSEWHEEL", + "WM_XBUTTONDOWN", + "WM_XBUTTONUP", + "WM_XBUTTONDBLCLK", + "526", + "527", + "WM_PARENTNOTIFY", + "WM_ENTERMENULOOP", + "WM_EXITMENULOOP", + "WM_NEXTMENU", + "WM_SIZING", + "WM_CAPTURECHANGED", + "WM_MOVING", + "535", + "WM_POWERBROADCAST", + "WM_DEVICECHANGE", + "538", + "539", + "540", + "541", + "542", + "543", + "WM_MDICREATE", + "WM_MDIDESTROY", + "WM_MDIACTIVATE", + "WM_MDIRESTORE", + "WM_MDINEXT", + "WM_MDIMAXIMIZE", + "WM_MDITILE", + "WM_MDICASCADE", + "WM_MDIICONARRANGE", + "WM_MDIGETACTIVE", + "554", + "555", + "556", + "557", + "558", + "559", + "WM_MDISETMENU", + "WM_ENTERSIZEMOVE", + "WM_EXITSIZEMOVE", + "WM_DROPFILES", + "WM_MDIREFRESHMENU", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "WM_IME_SETCONTEXT", + "WM_IME_NOTIFY", + "WM_IME_CONTROL", + "WM_IME_COMPOSITIONFULL", + "WM_IME_SELECT", + "WM_IME_CHAR", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "WM_IME_KEYDOWN", + "WM_IME_KEYUP", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "WM_MOUSEHOVER", + "674", + "WM_MOUSELEAVE", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "WM_CUT", + "WM_COPY", + "WM_PASTE", + "WM_CLEAR", + "WM_UNDO", + "WM_RENDERFORMAT", + "WM_RENDERALLFORMATS", + "WM_DESTROYCLIPBOARD", + "WM_DRAWCLIPBOARD", + "WM_PAINTCLIPBOARD", + "WM_VSCROLLCLIPBOARD", + "WM_SIZECLIPBOARD", + "WM_ASKCBFORMATNAME", + "WM_CHANGECBCHAIN", + "WM_HSCROLLCLIPBOARD", + "WM_QUERYNEWPALETTE", + "WM_PALETTEISCHANGING", + "WM_PALETTECHANGED", + "WM_HOTKEY", + "787", + "788", + "789", + "790", + "WM_PRINT", + "WM_PRINTCLIENT", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "1020", + "1021", + "1022", + "1023" +}; +#endif diff --git a/hw/xwin/winmisc.c b/hw/xwin/winmisc.c new file mode 100644 index 000000000..8e6698118 --- /dev/null +++ b/hw/xwin/winmisc.c @@ -0,0 +1,152 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + +#ifdef XWIN_NATIVEGDI +/* See Porting Layer Definition - p. 33 */ +/* + * Called by clients, returns the best size for a cursor, tile, or + * stipple, specified by class (sometimes called kind) + */ + +void +winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen) +{ + ErrorF ("winQueryBestSizeNativeGDI\n"); +} +#endif + + +/* + * Count the number of one bits in a color mask. + */ + +CARD8 +winCountBits (DWORD dw) +{ + DWORD dwBits = 0; + + while (dw) + { + dwBits += (dw & 1); + dw >>= 1; + } + + return dwBits; +} + + +/* + * Modify the screen pixmap to point to the new framebuffer address + */ + +Bool +winUpdateFBPointer (ScreenPtr pScreen, void *pbits) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Location of shadow framebuffer has changed */ + pScreenInfo->pfb = pbits; + + /* Update the screen pixmap */ + if (!(*pScreen->ModifyPixmapHeader) (pScreen->devPrivate, + pScreen->width, + pScreen->height, + pScreen->rootDepth, + BitsPerPixel (pScreen->rootDepth), + PixmapBytePad (pScreenInfo->dwStride, + pScreenInfo->dwBPP), + pScreenInfo->pfb)) + { + FatalError ("winUpdateFramebufferPointer - Failed modifying "\ + "screen pixmap\n"); + } + + return TRUE; +} + + +#ifdef XWIN_NATIVEGDI +/* + * Paint the window background with the specified color + */ + +BOOL +winPaintBackground (HWND hwnd, COLORREF colorref) +{ + HDC hdc; + HBRUSH hbrush; + RECT rect; + + /* Create an hdc */ + hdc = GetDC (hwnd); + if (hdc == NULL) + { + printf ("gdiWindowProc - GetDC failed\n"); + exit (1); + } + + /* Create and select blue brush */ + hbrush = CreateSolidBrush (colorref); + if (hbrush == NULL) + { + printf ("gdiWindowProc - CreateSolidBrush failed\n"); + exit (1); + } + + /* Get window extents */ + if (GetClientRect (hwnd, &rect) == FALSE) + { + printf ("gdiWindowProc - GetClientRect failed\n"); + exit (1); + } + + /* Fill window with blue brush */ + if (FillRect (hdc, &rect, hbrush) == 0) + { + printf ("gdiWindowProc - FillRect failed\n"); + exit (1); + } + + /* Delete blue brush */ + DeleteObject (hbrush); + + /* Release the hdc */ + ReleaseDC (hwnd, hdc); + + return TRUE; +} +#endif diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c new file mode 100644 index 000000000..1507dd34f --- /dev/null +++ b/hw/xwin/winmouse.c @@ -0,0 +1,341 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + +#if defined(XFree86Server) && defined(XINPUT) +#include "inputstr.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; + + 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; + InitPointerDeviceStruct (pDevice, + map, + lngMouseButtons + lngWheelEvents, + GetMotionHistory, + winMouseCtrl, + GetMotionHistorySize(), + 2); + free(map); + +#if defined(XFree86Server) && defined(XINPUT) + g_winMouseButtonMap = pDeviceInt->button->map; +#endif + break; + + case DEVICE_ON: + pDevice->on = TRUE; + break; + + case DEVICE_CLOSE: +#if defined(XFree86Server) && defined(XINPUT) + 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) +{ + xEvent xCurrentEvent; + + /* Load an xEvent and enqueue the event */ + xCurrentEvent.u.u.type = iEventType; +#if defined(XFree86Server) && defined(XINPUT) + if (g_winMouseButtonMap) + xCurrentEvent.u.u.detail = g_winMouseButtonMap[iButton]; + else +#endif + xCurrentEvent.u.u.detail = iButton; + xCurrentEvent.u.keyButtonPointer.time + = g_c32LastInputEventTime = GetTickCount (); + mieqEnqueue (&xCurrentEvent); +} + + +/* + * 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; +} diff --git a/hw/xwin/winms.h b/hw/xwin/winms.h new file mode 100644 index 000000000..1ad30dc0b --- /dev/null +++ b/hw/xwin/winms.h @@ -0,0 +1,46 @@ +#ifndef _WINMS_H_ +#define _WINMS_H_ +/* + *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 + */ + +#define NONAMELESSUNION +#define DIRECTDRAW_VERSION 0x0300 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include <X11/Xwindows.h> +#include <windowsx.h> + +#include "ddraw.h" + +#undef CreateWindow + +#endif /* _WINMS_H_ */ diff --git a/hw/xwin/winmsg.c b/hw/xwin/winmsg.c new file mode 100644 index 000000000..d0464f71b --- /dev/null +++ b/hw/xwin/winmsg.c @@ -0,0 +1,179 @@ +/* + *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: Alexander Gottwald + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winmsg.h" +#if CYGDEBUG +#include "winmessages.h" +#endif +#include <stdarg.h> + +void winVMsg (int, MessageType, int verb, const char *, va_list); + +void +winVMsg (int scrnIndex, MessageType type, int verb, const char *format, + va_list ap) +{ + LogVMessageVerb(type, verb, format, ap); +} + + +void +winDrvMsg (int scrnIndex, MessageType type, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(type, 0, format, ap); + va_end (ap); +} + + +void +winMsg (MessageType type, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(type, 1, format, ap); + va_end (ap); +} + + +void +winDrvMsgVerb (int scrnIndex, MessageType type, int verb, const char *format, + ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(type, verb, format, ap); + va_end (ap); +} + + +void +winMsgVerb (MessageType type, int verb, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(type, verb, format, ap); + va_end (ap); +} + + +void +winErrorFVerb (int verb, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(X_NONE, verb, format, ap); + va_end (ap); +} + +void +winDebug (const char *format, ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(X_NONE, 3, format, ap); + va_end (ap); +} + +void +winTrace (const char *format, ...) +{ + va_list ap; + va_start (ap, format); + LogVMessageVerb(X_NONE, 10, format, ap); + va_end (ap); +} + +void +winW32Error(int verb, const char *msg) +{ + winW32ErrorEx(verb, msg, GetLastError()); +} + +void +winW32ErrorEx(int verb, const char *msg, DWORD errorcode) +{ + LPVOID buffer; + if (!FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errorcode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buffer, + 0, + NULL )) + { + winErrorFVerb(verb, "Unknown error in FormatMessage!\n"); + } + else + { + winErrorFVerb(verb, "%s %s", msg, (char *)buffer); + LocalFree(buffer); + } +} + +#if CYGDEBUG +void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static int force = 0; + + if (message >= WM_USER) + { + if (force || getenv("WIN_DEBUG_MESSAGES") || getenv("WIN_DEBUG_WM_USER")) + { + winDebug("%s - Message WM_USER + %d\n", function, message - WM_USER); + winDebug("\thwnd 0x%x wParam 0x%x lParam 0x%x\n", hwnd, wParam, lParam); + } + } + else if (message < MESSAGE_NAMES_LEN && MESSAGE_NAMES[message]) + { + const char *msgname = MESSAGE_NAMES[message]; + char buffer[64]; + snprintf(buffer, sizeof(buffer), "WIN_DEBUG_%s", msgname); + buffer[63] = 0; + if (force || getenv("WIN_DEBUG_MESSAGES") || getenv(buffer)) + { + winDebug("%s - Message %s\n", function, MESSAGE_NAMES[message]); + winDebug("\thwnd 0x%x wParam 0x%x lParam 0x%x\n", hwnd, wParam, lParam); + } + } +} +#else +void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ +} +#endif diff --git a/hw/xwin/winmsg.h b/hw/xwin/winmsg.h new file mode 100644 index 000000000..611dd6962 --- /dev/null +++ b/hw/xwin/winmsg.h @@ -0,0 +1,50 @@ +#ifndef __WIN_MSG_H__ +#define __WIN_MSG_H__ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Alexander Gottwald + */ + +/* + * Function prototypes + */ + +void winDrvMsgVerb (int scrnIndex, + MessageType type, int verb, const char *format, ...); +void winDrvMsg (int scrnIndex, MessageType type, const char *format, ...); +void winMsgVerb (MessageType type, int verb, const char *format, ...); +void winMsg (MessageType type, const char *format, ...); +void winDebug (const char *format, ...); +void winTrace (const char *format, ...); + +void winErrorFVerb (int verb, const char *format, ...); +void winW32Error(int verb, const char *message); +void winW32ErrorEx(int verb, const char *message, DWORD errorcode); +void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#endif diff --git a/hw/xwin/winmultiwindowclass.c b/hw/xwin/winmultiwindowclass.c new file mode 100755 index 000000000..5b47c3976 --- /dev/null +++ b/hw/xwin/winmultiwindowclass.c @@ -0,0 +1,325 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <X11/Xatom.h> +#include "propertyst.h" +#include "windowstr.h" +#include "winmultiwindowclass.h" +#include "win.h" + +/* + * Local function + */ + +DEFINE_ATOM_HELPER(AtmWmWindowRole, "WM_WINDOW_ROLE") + + +int +winMultiWindowGetClassHint (WindowPtr pWin, char **res_name, char **res_class) +{ + struct _Window *pwin; + struct _Property *prop; + int len_name, len_class; + + if (!pWin || !res_name || !res_class) + { + ErrorF ("winMultiWindowGetClassHint - pWin, res_name, or res_class was " + "NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + *res_name = *res_class = NULL; + + while (prop) + { + if (prop->propertyName == XA_WM_CLASS + && prop->type == XA_STRING + && prop->format == 8 + && prop->data) + { + len_name = strlen ((char *) prop->data); + + (*res_name) = malloc (len_name + 1); + + if (!*res_name) + { + ErrorF ("winMultiWindowGetClassHint - *res_name was NULL\n"); + return 0; + } + + /* Add one to len_name to allow copying of trailing 0 */ + strncpy ((*res_name), prop->data, len_name + 1); + + if (len_name == prop->size) + len_name--; + + len_class = strlen (((char *)prop->data) + 1 + len_name); + + (*res_class) = malloc (len_class + 1); + + if (!*res_class) + { + ErrorF ("winMultiWindowGetClassHint - *res_class was NULL\n"); + + /* Free the previously allocated res_name */ + free (*res_name); + return 0; + } + + strcpy ((*res_class), ((char *)prop->data) + 1 + len_name); + + return 1; + } + else + prop = prop->next; + } + + return 0; +} + + +int +winMultiWindowGetWMHints (WindowPtr pWin, WinXWMHints *hints) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !hints) + { + ErrorF ("winMultiWindowGetWMHints - pWin or hints was NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + memset (hints, 0, sizeof (WinXWMHints)); + + while (prop) + { + if (prop->propertyName == XA_WM_HINTS + && prop->data) + { + memcpy (hints, prop->data, sizeof (WinXWMHints)); + return 1; + } + else + prop = prop->next; + } + + return 0; +} + + +int +winMultiWindowGetWindowRole (WindowPtr pWin, char **res_role) +{ + struct _Window *pwin; + struct _Property *prop; + int len_role; + + if (!pWin || !res_role) + return 0; + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + *res_role = NULL; + while (prop) + { + if (prop->propertyName == AtmWmWindowRole () + && prop->type == XA_STRING + && prop->format == 8 + && prop->data) + { + len_role= prop->size; + + (*res_role) = malloc (len_role + 1); + + if (!*res_role) + { + ErrorF ("winMultiWindowGetWindowRole - *res_role was NULL\n"); + return 0; + } + + strncpy ((*res_role), prop->data, len_role); + (*res_role)[len_role] = 0; + + return 1; + } + else + prop = prop->next; + } + + return 0; +} + + +int +winMultiWindowGetWMNormalHints (WindowPtr pWin, WinXSizeHints *hints) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !hints) + { + ErrorF ("winMultiWindowGetWMNormalHints - pWin or hints was NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + memset (hints, 0, sizeof (WinXSizeHints)); + + while (prop) + { + if (prop->propertyName == XA_WM_NORMAL_HINTS + && prop->data) + { + memcpy (hints, prop->data, sizeof (WinXSizeHints)); + return 1; + } + else + prop = prop->next; + } + + return 0; +} + +int +winMultiWindowGetTransientFor (WindowPtr pWin, WindowPtr *ppDaddy) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin) + { + ErrorF ("winMultiWindowGetTransientFor - pWin was NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + if (ppDaddy) + *ppDaddy = NULL; + + while (prop) + { + if (prop->propertyName == XA_WM_TRANSIENT_FOR) + { + if (ppDaddy) + memcpy (*ppDaddy, prop->data, sizeof (WindowPtr)); + return 1; + } + else + prop = prop->next; + } + + return 0; +} + +int +winMultiWindowGetWMName (WindowPtr pWin, char **wmName) +{ + struct _Window *pwin; + struct _Property *prop; + int len_name; + + if (!pWin || !wmName) + { + ErrorF ("winMultiWindowGetClassHint - pWin, res_name, or res_class was " + "NULL\n"); + return 0; + } + + pwin = (struct _Window*) pWin; + + if (pwin->optional) + prop = (struct _Property *) pwin->optional->userProps; + else + prop = NULL; + + *wmName = NULL; + + while (prop) + { + if (prop->propertyName == XA_WM_NAME + && prop->type == XA_STRING + && prop->data) + { + len_name = prop->size; + + (*wmName) = malloc (len_name + 1); + + if (!*wmName) + { + ErrorF ("winMultiWindowGetWMName - *wmName was NULL\n"); + return 0; + } + + strncpy ((*wmName), prop->data, len_name); + (*wmName)[len_name] = 0; + + return 1; + } + else + prop = prop->next; + } + + return 0; +} diff --git a/hw/xwin/winmultiwindowclass.h b/hw/xwin/winmultiwindowclass.h new file mode 100755 index 000000000..c635ab20b --- /dev/null +++ b/hw/xwin/winmultiwindowclass.h @@ -0,0 +1,114 @@ +#if !defined(WINMULTIWINDOWCLASS_H) +#define WINMULTIWINDOWCLASS_H +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +/* + * Structures + */ + +typedef struct { + long flags; /* marks which fields in this structure are defined */ + Bool input; /* does this application rely on the window manager to + get keyboard input? */ + int initial_state; /* see below */ + Pixmap icon_pixmap; /* pixmap to be used as icon */ + Window icon_window; /* window to be used as icon */ + int icon_x, icon_y; /* initial position of icon */ + Pixmap icon_mask; /* icon mask bitmap */ + XID window_group; /* id of related window group */ + /* this structure may be extended in the future */ +} WinXWMHints; + + +/* + * new version containing base_width, base_height, and win_gravity fields; + * used with WM_NORMAL_HINTS. + */ +typedef struct { + long flags; /* marks which fields in this structure are defined */ + int x, y; /* obsolete for new window mgrs, but clients */ + int width, height; /* should set so old wm's don't mess up */ + int min_width, min_height; + int max_width, max_height; + int width_inc, height_inc; + struct { + int x; /* numerator */ + int y; /* denominator */ + } min_aspect, max_aspect; + int base_width, base_height; /* added by ICCCM version 1 */ + int win_gravity; /* added by ICCCM version 1 */ +} WinXSizeHints; + +/* + * The next block of definitions are for window manager properties that + * clients and applications use for communication. + */ + +/* flags argument in size hints */ +#define USPosition (1L << 0) /* user specified x, y */ +#define USSize (1L << 1) /* user specified width, height */ + +#define PPosition (1L << 2) /* program specified position */ +#define PSize (1L << 3) /* program specified size */ +#define PMinSize (1L << 4) /* program specified minimum size */ +#define PMaxSize (1L << 5) /* program specified maximum size */ +#define PResizeInc (1L << 6) /* program specified resize increments */ +#define PAspect (1L << 7) /* program specified min and max aspect ratios */ +#define PBaseSize (1L << 8) /* program specified base for incrementing */ +#define PWinGravity (1L << 9) /* program specified window gravity */ + +/* obsolete */ +#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect) + + +/* + * Function prototypes + */ + +int +winMultiWindowGetWMHints (WindowPtr pWin, WinXWMHints *hints); + +int +winMultiWindowGetClassHint (WindowPtr pWin, char **res_name, char **res_class); + +int +winMultiWindowGetWindowRole (WindowPtr pWin, char **res_role); + +int +winMultiWindowGetWMNormalHints (WindowPtr pWin, WinXSizeHints *hints); + +int +winMultiWindowGetWMName (WindowPtr pWin, char **wmName); + +int +winMultiWindowGetTransientFor (WindowPtr pWin, WindowPtr *ppDaddy); + +#endif diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c new file mode 100644 index 000000000..45ed093ec --- /dev/null +++ b/hw/xwin/winmultiwindowicons.c @@ -0,0 +1,478 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + + +/* + * 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; + unsigned 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 32-bit aligned rows */ + stride = ((iconSize * effBPP + 31) & (~31)) / 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 = iconData + posY*xStride; + if (effXBPP == 1) + { + ptr += posX / 8; + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + + if ((*ptr) & (1 << (posX & 7))) + switch (effBPP) + { + case 32: + *(outPtr++) = 0; + case 24: + *(outPtr++) = 0; + case 16: + *(outPtr++) = 0; + case 8: + *(outPtr++) = 0; + break; + case 1: + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } + else + switch (effBPP) + { + case 32: + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 0; + break; + case 24: + *(outPtr++) = 255; + case 16: + *(outPtr++) = 255; + case 8: + *(outPtr++) = 255; + break; + case 1: + outPtr[column / 8] |= (1 << (7 - (column & 7))); + break; + } + } + else if (effXDepth == 24 || effXDepth == 32) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = (((*ptr) << 16) + + ((*(ptr + 1)) << 8) + + ((*(ptr + 2)) << 0)); + switch (effBPP) + { + case 32: + *(outPtr++) = *(ptr++); // b + *(outPtr++) = *(ptr++); // g + *(outPtr++) = *(ptr++); // r + *(outPtr++) = 0; // resvd + break; + case 24: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 16: + color = ((((*ptr) >> 2) << 10) + + (((*(ptr + 1)) >> 2) << 5) + + (((*(ptr + 2)) >> 2))); + *(outPtr++) = (color >> 8); + *(outPtr++) = (color & 255); + break; + case 8: + color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2)))); + color /= 3; + *(outPtr++) = color; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + } + } + else if (effXDepth == 16) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = ((*ptr) << 8) + (*(ptr + 1)); + switch (effBPP) + { + case 32: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + *(outPtr++) = 0; // resvd + break; + case 24: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + break; + case 16: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 8: + *(outPtr++) = (((color & 31) + + ((color >> 5) & 31) + + ((color >> 10) & 31)) / 3) << 2; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } /* end switch(effbpp) */ + } /* end if effxbpp==16) */ + } /* end for column */ + } /* end for row */ + free (iconData); +} + + +/* + * Attempt to create a custom icon from the WM_HINTS bitmaps + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize) +{ + unsigned char *mask, *image, *imageMask; + unsigned char *dst, *src; + PixmapPtr iconPtr; + PixmapPtr maskPtr; + int planes, bpp, effBPP, stride, maskStride, i; + HDC hDC; + ICONINFO ii; + WinXWMHints hints; + HICON hIcon; + + winMultiWindowGetWMHints (pWin, &hints); + if (!hints.icon_pixmap) return NULL; + + iconPtr = (PixmapPtr) LookupIDByType (hints.icon_pixmap, RT_PIXMAP); + + if (!iconPtr) return NULL; + + hDC = GetDC (GetDesktopWindow ()); + planes = GetDeviceCaps (hDC, PLANES); + bpp = GetDeviceCaps (hDC, BITSPIXEL); + ReleaseDC (GetDesktopWindow (), hDC); + + /* 15 BPP is really 16BPP as far as we care */ + if (bpp == 15) + effBPP = 16; + else + effBPP = bpp; + + /* Need 32-bit aligned rows */ + stride = ((iconSize * effBPP + 31) & (~31)) / 8; + + /* Mask is 1-bit deep */ + maskStride = ((iconSize * 1 + 31) & (~31)) / 8; + + image = (unsigned char * ) malloc (stride * iconSize); + imageMask = (unsigned char *) malloc (stride * iconSize); + mask = (unsigned char *) malloc (maskStride * iconSize); + + /* Default to a completely black mask */ + memset (mask, 0, maskStride * iconSize); + + winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); + maskPtr = (PixmapPtr) LookupIDByType (hints.icon_mask, RT_PIXMAP); + + if (maskPtr) + { + winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask); + + winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask); + + /* Now we need to set all bits of the icon which are not masked */ + /* on to 0 because Color is really an XOR, not an OR function */ + dst = image; + src = imageMask; + + for (i = 0; i < (stride * iconSize); i++) + if ((*(src++))) + *(dst++) = 0; + else + dst++; + } + + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ + + /* Create Win32 mask from pixmap shape */ + ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask); + + /* Create Win32 bitmap from pixmap */ + ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image); + + /* Merge Win32 mask and bitmap into icon */ + hIcon = CreateIconIndirect (&ii); + + /* Release Win32 mask and bitmap */ + DeleteObject (ii.hbmMask); + DeleteObject (ii.hbmColor); + + /* Free X mask and bitmap */ + free (mask); + free (image); + free (imageMask); + + return hIcon; +} + + + +/* + * Change the Windows window icon + */ + +#ifdef XWIN_MULTIWINDOW +void +winUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hiconOld; + + pWin = (WindowPtr) LookupIDByType (id, RT_WINDOW); + if (!pWin) return; + hIcon = (HICON)winOverrideIcon ((unsigned long)pWin); + + if (!hIcon) + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + + if (hIcon) + { + winWindowPriv(pWin); + + if (pWinPriv->hWnd) + { + hiconOld = (HICON) SetClassLong (pWinPriv->hWnd, + GCL_HICON, + (int) hIcon); + + /* Delete the icon if its not the default */ + winDestroyIcon(hiconOld); + } + } + + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + if (hIcon) + { + winWindowPriv(pWin); + + if (pWinPriv->hWnd) + { + hiconOld = (HICON) SetClassLong (pWinPriv->hWnd, + GCL_HICONSM, + (int) hIcon); + 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 = (HICON)winOverrideDefaultIcon(sm_cx); + g_hSmallIconX = (HICON)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/hw/xwin/winmultiwindowshape.c b/hw/xwin/winmultiwindowshape.c new file mode 100644 index 000000000..33deae337 --- /dev/null +++ b/hw/xwin/winmultiwindowshape.c @@ -0,0 +1,211 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#ifdef SHAPE + +#include "win.h" + + +/* + * winSetShapeMultiWindow - See Porting Layer Definition - p. 42 + */ + +void +winSetShapeMultiWindow (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(SetShape); + (*pScreen->SetShape)(pWin); + WIN_WRAP(SetShape, winSetShapeMultiWindow); + + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); + + return; +} + + +/* + * winUpdateRgnMultiWindow - Local function to update a Windows window region + */ + +void +winUpdateRgnMultiWindow (WindowPtr pWin) +{ + SetWindowRgn (winGetWindowPriv(pWin)->hWnd, + winGetWindowPriv(pWin)->hRgn, TRUE); +} + + +/* + * winReshapeMultiWindow - Computes the composite clipping region for a window + */ + +void +winReshapeMultiWindow (WindowPtr pWin) +{ + int nRects; + RegionRec rrNewShape; + BoxPtr pShape, pRects, pEnd; + HRGN hRgn, hRgnRect; + winWindowPriv(pWin); + +#if CYGDEBUG + winDebug ("winReshape ()\n"); +#endif + + /* Bail if the window is the root window */ + if (pWin->parent == NULL) + return; + + /* Bail if the window is not top level */ + if (pWin->parent->parent != NULL) + return; + + /* Bail if Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + /* Free any existing window region stored in the window privates */ + if (pWinPriv->hRgn != NULL) + { + DeleteObject (pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + /* Bail if the window has no bounding region defined */ + if (!wBoundingShape (pWin)) + return; + + REGION_NULL(pWin->drawable.pScreen, &rrNewShape); + REGION_COPY(pWin->drawable.pScreen, &rrNewShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pWin->drawable.pScreen, + &rrNewShape, + pWin->borderWidth, + pWin->borderWidth); + + nRects = REGION_NUM_RECTS(&rrNewShape); + pShape = REGION_RECTS(&rrNewShape); + + /* Don't do anything if there are no rectangles in the region */ + if (nRects > 0) + { + RECT rcClient; + RECT rcWindow; + int iOffsetX, iOffsetY; + + /* Get client rectangle */ + if (!GetClientRect (pWinPriv->hWnd, &rcClient)) + { + ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", + (int) GetLastError ()); + return; + } + + /* Translate client rectangle coords to screen coords */ + /* NOTE: Only transforms top and left members */ + ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); + + /* Get window rectangle */ + if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) + { + ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", + (int) GetLastError ()); + return; + } + + /* Calculate offset from window upper-left to client upper-left */ + iOffsetX = rcClient.left - rcWindow.left; + iOffsetY = rcClient.top - rcWindow.top; + + /* Create initial Windows region for title bar */ + /* FIXME: Mean, nasty, ugly hack!!! */ + hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX, + pRects->y1 + iOffsetY, + pRects->x2 + iOffsetX, + pRects->y2 + iOffsetY); + if (hRgnRect == NULL) + { + ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n" + "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", + pRects->x1 + iOffsetX, + pRects->y1 + iOffsetY, + pRects->x2 + iOffsetX, + pRects->y2 + iOffsetY, + (int) GetLastError (), + pRects->x1, pRects->x2, iOffsetX, + pRects->y1, pRects->y2, iOffsetY); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + (int) GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + /* Save a handle to the composite region in the window privates */ + pWinPriv->hRgn = hRgn; + } + + REGION_UNINIT(pWin->drawable.pScreen, &rrNewShape); + + return; +} +#endif diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c new file mode 100644 index 000000000..037c881b4 --- /dev/null +++ b/hw/xwin/winmultiwindowwindow.c @@ -0,0 +1,1054 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + +/* + * External global variables + */ + +extern HWND g_hDlgDepthChange; + +extern void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon); + +/* + * Prototypes for local functions + */ + +void +winCreateWindowsWindow (WindowPtr pWin); + +static void +winDestroyWindowsWindow (WindowPtr pWin); + +static void +winUpdateWindowsWindow (WindowPtr pWin); + +static void +winFindWindow (pointer value, XID id, pointer cdata); + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 + + +/* + * Macros + */ + +#define SubSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask) + +#define StrSend(pWin) \ + ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask) + +#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent)) + + +/* + * CreateWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(CreateWindow); + fResult = (*pScreen->CreateWindow) (pWin); + WIN_WRAP(CreateWindow, winCreateWindowMultiWindow); + + /* Initialize some privates values */ + pWinPriv->hRgn = NULL; + pWinPriv->hWnd = NULL; + pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); + pWinPriv->fXKilled = FALSE; + + return fResult; +} + + +/* + * DestroyWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winDestroyWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(DestroyWindow); + fResult = (*pScreen->DestroyWindow)(pWin); + WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow); + + /* Flag that the window has been destroyed */ + pWinPriv->fXKilled = TRUE; + + /* Kill the MS Windows window associated with this window */ + winDestroyWindowsWindow (pWin); + + return fResult; +} + + +/* + * PositionWindow - See Porting Layer Definition - p. 37 + * + * This function adjusts the position and size of Windows window + * with respect to the underlying X window. This is the inverse + * of winAdjustXWindow, which adjusts X window to Windows window. + */ + +Bool +winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) +{ + Bool fResult = TRUE; + int iX, iY, iWidth, iHeight; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + HWND hWnd = pWinPriv->hWnd; + RECT rcNew; + RECT rcOld; +#if CYGMULTIWINDOW_DEBUG + RECT rcClient; + RECT *lpRc; +#endif + DWORD dwExStyle; + DWORD dwStyle; + +#if CYGMULTIWINDOW_DEBUG + winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(PositionWindow); + fResult = (*pScreen->PositionWindow)(pWin, x, y); + WIN_WRAP(PositionWindow, winPositionWindowMultiWindow); + +#if CYGWINDOWING_DEBUG + ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", + x, y); +#endif + + /* Bail out if the Windows window handle is bad */ + if (!hWnd) + { +#if CYGWINDOWING_DEBUG + ErrorF ("\timmediately return since hWnd is NULL\n"); +#endif + return fResult; + } + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#if CYGMULTIWINDOW_DEBUG + lpRc = &rcNew; + ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); +#endif + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + /* Get a rectangle describing the old Windows window */ + GetWindowRect (hWnd, &rcOld); + +#if CYGMULTIWINDOW_DEBUG + /* Get a rectangle describing the Windows window client area */ + GetClientRect (hWnd, &rcClient); + + lpRc = &rcNew; + ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); + + lpRc = &rcOld; + ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); + + lpRc = &rcClient; + ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); +#endif + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - Need to move\n"); +#endif + +#if CYGWINDOWING_DEBUG + ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* Change the position and dimensions of the Windows window */ + MoveWindow (hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + } + else + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - Not need to move\n"); +#endif + } + + return fResult; +} + + +/* + * ChangeWindowAttributes - See Porting Layer Definition - p. 37 + */ + +Bool +winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(ChangeWindowAttributes); + fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); + WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow); + + /* + * NOTE: We do not currently need to do anything here. + */ + + return fResult; +} + + +/* + * UnmapWindow - See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(UnrealizeWindow); + fResult = (*pScreen->UnrealizeWindow)(pWin); + WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow); + + /* Flag that the window has been killed */ + pWinPriv->fXKilled = TRUE; + + /* Destroy the Windows window associated with this X window */ + winDestroyWindowsWindow (pWin); + + return fResult; +} + + +/* + * MapWindow - See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(RealizeWindow); + fResult = (*pScreen->RealizeWindow)(pWin); + WIN_WRAP(RealizeWindow, winMapWindowMultiWindow); + + /* Flag that this window has not been destroyed */ + pWinPriv->fXKilled = FALSE; + + /* Refresh/redisplay the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); + +#ifdef SHAPE + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); +#endif + + return fResult; +} + + +/* + * ReparentWindow - See Porting Layer Definition - p. 42 + */ + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(ReparentWindow); + if (pScreen->ReparentWindow) + (*pScreen->ReparentWindow)(pWin, pPriorParent); + WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow); + + /* Update the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); +} + + +/* + * RestackWindow - Shuffle the z-order of a window + */ + +void +winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) +{ + WindowPtr pPrevWin; + UINT uFlags; + HWND hInsertAfter; + HWND hWnd = NULL; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG + winTrace ("winRestackMultiWindow - %08x\n", pWin); +#endif + + WIN_UNWRAP(RestackWindow); + if (pScreen->RestackWindow) + (*pScreen->RestackWindow)(pWin, pOldNextSib); + WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); + +#if 1 + /* + * Calling winReorderWindowsMultiWindow here means our window manager + * (i.e. Windows Explorer) has initiative to determine Z order. + */ + if (pWin->nextSib != pOldNextSib) + winReorderWindowsMultiWindow (); +#else + /* Bail out if no window privates or window handle is invalid */ + if (!pWinPriv || !pWinPriv->hWnd) + return; + + /* Get a pointer to our previous sibling window */ + pPrevWin = pWin->prevSib; + + /* + * Look for a sibling window with + * valid privates and window handle + */ + while (pPrevWin + && !winGetWindowPriv(pPrevWin) + && !winGetWindowPriv(pPrevWin)->hWnd) + pPrevWin = pPrevWin->prevSib; + + /* Check if we found a valid sibling */ + if (pPrevWin) + { + /* Valid sibling - get handle to insert window after */ + hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd; + uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; + + hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV); + + do + { + if (GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) + { + uFlags |= SWP_NOZORDER; + } + break; + } + hWnd = GetNextWindow (hWnd, GW_HWNDPREV); + } + while (hWnd); + } + else + { + /* No valid sibling - make this window the top window */ + hInsertAfter = HWND_TOP; + uFlags = SWP_NOMOVE | SWP_NOSIZE; + } + + /* Perform the restacking operation in Windows */ + SetWindowPos (pWinPriv->hWnd, + hInsertAfter, + 0, 0, + 0, 0, + uFlags); +#endif +} + + +/* + * winCreateWindowsWindow - Create a Windows window associated with an X window + */ + +void +winCreateWindowsWindow (WindowPtr pWin) +{ + int iX, iY; + int iWidth; + int iHeight; + HWND hWnd; + WNDCLASSEX wc; + winWindowPriv(pWin); + HICON hIcon; + HICON hIconSmall; +#define CLASS_NAME_LENGTH 512 + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; + winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; + WinXSizeHints hints; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); +#endif + + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Default positions if none specified */ + if (!winMultiWindowGetWMNormalHints(pWin, &hints)) + hints.flags = 0; + if ( !(hints.flags & (USPosition|PPosition)) && + !winMultiWindowGetTransientFor (pWin, NULL) && + !pWin->overrideRedirect ) + { + iX = CW_USEDEFAULT; + iY = CW_USEDEFAULT; + } + + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + winSelectIcons(pWin, &hIcon, &hIconSmall); + + /* Set standard class name prefix so we can identify window easily */ + strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass)); + + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + { + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); + + /* Check if a window class is provided by the WM_WINDOW_ROLE property, + * if not use the WM_CLASS information. + * For further information see: + * http://tronche.com/gui/x/icccm/sec-5.html + */ + if (winMultiWindowGetWindowRole (pWin, &res_role) ) + { + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); + } + + free (res_name); + free (res_class); + } + + /* Add incrementing window ID to make unique class name */ + snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++); + pszWindowID[sizeof(pszWindowID)-1] = 0; + strcat (pszClass, pszWindowID); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass); +#endif + + /* Setup our window class */ + wc.cbSize = sizeof(wc); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winTopLevelWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = hIcon; + wc.hIconSm = hIconSmall; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = pszClass; + RegisterClassEx (&wc); + + /* Create the window */ + /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */ + /* CW_USEDEFAULT, change back to popup after creation */ + hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pWin); /* ScreenPrivates */ + if (hWnd == NULL) + { + ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + } + + /* Change style back to popup, already placed... */ + SetWindowLong (hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + SetWindowPos (hWnd, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + /* Make sure it gets the proper system menu for a WS_POPUP, too */ + GetSystemMenu (hWnd, TRUE); + + pWinPriv->hWnd = hWnd; + + /* Cause any .XWinrc menus to be added in main WNDPROC */ + PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); + + SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); + + /* Flag that this Windows window handles its own activation */ + SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); + + /* Call engine-specific create window procedure */ + (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin); +} + + +Bool winInDestroyWindowsWindow = FALSE; +/* + * winDestroyWindowsWindow - Destroy a Windows window associated + * with an X window + */ +static void +winDestroyWindowsWindow (WindowPtr pWin) +{ + MSG msg; + winWindowPriv(pWin); + HICON hiconClass; + HICON hiconSmClass; + HMODULE hInstance; + int iReturn; + char pszClass[512]; + BOOL oldstate = winInDestroyWindowsWindow; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow\n"); +#endif + + /* Bail out if the Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + winInDestroyWindowsWindow = TRUE; + + /* Store the info we need to destroy after this window is gone */ + hInstance = (HINSTANCE) GetClassLong (pWinPriv->hWnd, GCL_HMODULE); + hiconClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICON); + hiconSmClass = (HICON) GetClassLong (pWinPriv->hWnd, GCL_HICONSM); + iReturn = GetClassName (pWinPriv->hWnd, pszClass, 512); + + SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL); + /* Destroy the Windows window */ + DestroyWindow (pWinPriv->hWnd); + + /* Null our handle to the Window so referencing it will cause an error */ + pWinPriv->hWnd = NULL; + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + { + DispatchMessage (&msg); + } + } + + /* Only if we were able to get the name */ + if (iReturn) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - Unregistering %s: ", pszClass); +#endif + iReturn = UnregisterClass (pszClass, hInstance); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow - %d Deleting Icon: ", iReturn); +#endif + + winDestroyIcon(hiconClass); + winDestroyIcon(hiconSmClass); + } + + winInDestroyWindowsWindow = oldstate; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-winDestroyWindowsWindow\n"); +#endif +} + + +/* + * winUpdateWindowsWindow - Redisplay/redraw a Windows window + * associated with an X window + */ + +static void +winUpdateWindowsWindow (WindowPtr pWin) +{ + winWindowPriv(pWin); + HWND hWnd = pWinPriv->hWnd; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUpdateWindowsWindow\n"); +#endif + + /* Check if the Windows window's parents have been destroyed */ + if (pWin->parent != NULL + && pWin->parent->parent == NULL + && pWin->mapped) + { + /* Create the Windows window if it has been destroyed */ + if (hWnd == NULL) + { + winCreateWindowsWindow (pWin); + assert (pWinPriv->hWnd != NULL); + } + + /* Display the window without activating it */ + ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); + + /* Send first paint message */ + UpdateWindow (pWinPriv->hWnd); + } + else if (hWnd != NULL) + { + /* Destroy the Windows window if its parents are destroyed */ + winDestroyWindowsWindow (pWin); + assert (pWinPriv->hWnd == NULL); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-winUpdateWindowsWindow\n"); +#endif +} + + +/* + * winGetWindowID - + */ + +XID +winGetWindowID (WindowPtr pWin) +{ + WindowIDPairRec wi = {pWin, 0}; + ClientPtr c = wClient(pWin); + + /* */ + FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); +#endif + + return wi.id; +} + + +/* + * winFindWindow - + */ + +static void +winFindWindow (pointer value, XID id, pointer cdata) +{ + WindowIDPairPtr wi = (WindowIDPairPtr)cdata; + + if (value == wi->value) + { + wi->id = id; + } +} + + +/* + * winReorderWindowsMultiWindow - + */ + +void +winReorderWindowsMultiWindow (void) +{ + HWND hwnd = NULL; + WindowPtr pWin = NULL; + WindowPtr pWinSib = NULL; + XID vlist[2]; + static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + +#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG + winTrace ("winReorderWindowsMultiWindow\n"); +#endif + + if (fRestacking) + { + /* It is a recusive call so immediately exit */ +#if CYGWINDOWING_DEBUG + ErrorF ("winReorderWindowsMultiWindow - " + "exit because fRestacking == TRUE\n"); +#endif + return; + } + fRestacking = TRUE; + + /* Loop through top level Window windows, descending in Z order */ + for ( hwnd = GetTopWindow (NULL); + hwnd; + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) ) + { + /* Don't take care of other Cygwin/X process's windows */ + GetWindowThreadProcessId (hwnd, &dwWindowProcessID); + + if ( GetProp (hwnd, WIN_WINDOW_PROP) + && (dwWindowProcessID == dwCurrentProcessID) + && !IsIconic (hwnd) ) /* ignore minimized windows */ + { + pWinSib = pWin; + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + if (!pWinSib) + { /* 1st window - raise to the top */ + vlist[0] = Above; + + ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); + } + else + { /* 2nd or deeper windows - just below the previous one */ + vlist[0] = winGetWindowID (pWinSib); + vlist[1] = Below; + + ConfigureWindow (pWin, CWSibling | CWStackMode, + vlist, wClient(pWin)); + } + } + } + + fRestacking = FALSE; +} + + +/* + * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE + */ + +void +winMinimizeWindow (Window id) +{ + WindowPtr pWin; + winPrivWinPtr pWinPriv; +#ifdef XWIN_MULTIWINDOWEXTWM + win32RootlessWindowPtr pRLWinPriv; +#endif + HWND hWnd; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + +#if CYGWINDOWING_DEBUG + ErrorF ("winMinimizeWindow\n"); +#endif + + pWin = LookupIDByType (id, RT_WINDOW); + if (!pWin) + { + ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__); + return; + } + + pScreen = pWin->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#ifdef XWIN_MULTIWINDOWEXTWM + if (pScreenPriv && pScreenInfo->fInternalWM) + { + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + hWnd = pRLWinPriv->hWnd; + } + else +#else + if (pScreenPriv) +#endif + { + pWinPriv = winGetWindowPriv (pWin); + hWnd = pWinPriv->hWnd; + } + + ShowWindow (hWnd, SW_MINIMIZE); +} + + +/* + * CopyWindow - See Porting Layer Definition - p. 39 + */ +void +winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, + RegionPtr oldRegion) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("CopyWindowMultiWindow\n"); +#endif + WIN_UNWRAP(CopyWindow); + (*pScreen->CopyWindow)(pWin, oldpt, oldRegion); + WIN_WRAP(CopyWindow, winCopyWindowMultiWindow); +} + + +/* + * MoveWindow - See Porting Layer Definition - p. 42 + */ +void +winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, + WindowPtr pSib, VTKind kind) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y); +#endif + + WIN_UNWRAP(MoveWindow); + (*pScreen->MoveWindow)(pWin, x, y, pSib, kind); + WIN_WRAP(MoveWindow, winMoveWindowMultiWindow); +} + + +/* + * ResizeWindow - See Porting Layer Definition - p. 42 + */ +void +winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h); +#endif + WIN_UNWRAP(ResizeWindow); + (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); + WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow); +} + + +/* + * winAdjustXWindow + * + * Move and resize X window with respect to corresponding Windows window. + * This is called from WM_MOVE/WM_SIZE handlers when the user performs + * any windowing operation (move, resize, minimize, maximize, restore). + * + * The functionality is the inverse of winPositionWindowMultiWindow, which + * adjusts Windows window with respect to X window. + */ +int +winAdjustXWindow (WindowPtr pWin, HWND hwnd) +{ + RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */ + RECT rcWin; /* The source: WindowRect from hwnd */ + DrawablePtr pDraw; + XID vlist[4]; + LONG dX, dY, dW, dH, x, y; + DWORD dwStyle, dwExStyle; + +#define WIDTH(rc) (rc.right - rc.left) +#define HEIGHT(rc) (rc.bottom - rc.top) + +#if CYGWINDOWING_DEBUG + ErrorF ("winAdjustXWindow\n"); +#endif + + if (IsIconic (hwnd)) + { +#if CYGWINDOWING_DEBUG + ErrorF ("\timmediately return because the window is iconized\n"); +#endif + /* + * If the Windows window is minimized, its WindowRect has + * meaningless values so we don't adjust X window to it. + */ + vlist[0] = 0; + vlist[1] = 0; + return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + } + + pDraw = &pWin->drawable; + + /* Calculate the window rect from the drawable */ + x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN); + y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN); + SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n", + rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, + rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); +#endif + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle); +#endif + AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle); + + /* The source of adjust */ + GetWindowRect (hwnd, &rcWin); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", + rcWin.left, rcWin.top, rcWin.right, rcWin.bottom, + rcWin.right - rcWin.left, rcWin.bottom - rcWin.top); + winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n", + rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, + rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); +#endif + + if (EqualRect (&rcDraw, &rcWin)) { + /* Bail if no adjust is needed */ +#if CYGWINDOWING_DEBUG + ErrorF ("\treturn because already adjusted\n"); +#endif + return 0; + } + + /* Calculate delta values */ + dX = rcWin.left - rcDraw.left; + dY = rcWin.top - rcDraw.top; + dW = WIDTH(rcWin) - WIDTH(rcDraw); + dH = HEIGHT(rcWin) - HEIGHT(rcDraw); + + /* + * Adjust. + * We may only need to move (vlist[0] and [1]), or only resize + * ([2] and [3]) but currently we set all the parameters and leave + * the decision to ConfigureWindow. The reason is code simplicity. + */ + vlist[0] = pDraw->x + dX - wBorderWidth(pWin); + vlist[1] = pDraw->y + dY - wBorderWidth(pWin); + vlist[2] = pDraw->width + dW; + vlist[3] = pDraw->height + dH; +#if CYGWINDOWING_DEBUG + ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1], + vlist[2], vlist[3]); +#endif + return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, + vlist, wClient(pWin)); + +#undef WIDTH +#undef HEIGHT +} + diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c new file mode 100644 index 000000000..5401ecdee --- /dev/null +++ b/hw/xwin/winmultiwindowwm.c @@ -0,0 +1,1440 @@ +/* + *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 + */ + +/* X headers */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef __CYGWIN__ +#include <sys/select.h> +#endif +#include <fcntl.h> +#include <setjmp.h> +#define HANDLE void * +#include <pthread.h> +#undef HANDLE +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xlocale.h> +#include <X11/Xproto.h> +#include <X11/Xutil.h> +#include <X11/cursorfont.h> + +/* Windows headers */ +#ifdef __CYGWIN__ +/* Fixups to prevent collisions between Windows and X headers */ +#define ATOM DWORD + +#include <windows.h> +#else +#include <Xwindows.h> +#endif + +/* Local headers */ +#include "objbase.h" +#include "ddraw.h" +#include "winwindow.h" +#ifdef XWIN_MULTIWINDOWEXTWM +#include "windowswmstr.h" +#endif + +extern void winDebug(const char *format, ...); + +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif + +/* + * Constant defines + */ + +#define WIN_CONNECT_RETRIES 5 +#define WIN_CONNECT_DELAY 5 +#ifdef HAS_DEVWINDOWS +# define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 + + +/* + * Local structures + */ + +typedef struct _WMMsgNodeRec { + winWMMessageRec msg; + struct _WMMsgNodeRec *pNext; +} WMMsgNodeRec, *WMMsgNodePtr; + +typedef struct _WMMsgQueueRec { + struct _WMMsgNodeRec *pHead; + struct _WMMsgNodeRec *pTail; + pthread_mutex_t pmMutex; + pthread_cond_t pcNotEmpty; + int nQueueSize; +} WMMsgQueueRec, *WMMsgQueuePtr; + +typedef struct _WMInfo { + Display *pDisplay; + WMMsgQueueRec wmMsgQueue; + Atom atmWmProtos; + Atom atmWmDelete; + Atom atmPrivMap; + Bool fAllowOtherWM; +} WMInfoRec, *WMInfoPtr; + +typedef struct _WMProcArgRec { + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; +} WMProcArgRec, *WMProcArgPtr; + +typedef struct _XMsgProcArgRec { + Display *pDisplay; + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; + HWND hwndScreen; +} XMsgProcArgRec, *XMsgProcArgPtr; + + +/* + * References to external symbols + */ + +extern char *display; +extern void ErrorF (const char* /*f*/, ...); + + +/* + * Prototypes for local functions + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode); + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo); + +static Bool +InitQueue (WMMsgQueuePtr pQueue); + +static void +GetWindowName (Display * pDpy, Window iWin, char **ppName); + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData); + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow); + +static void* +winMultiWindowWMProc (void* pArg); + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay); + +static void * +winMultiWindowXMsgProc (void *pArg); + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay); + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); + +#if 0 +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction); +#endif + +static Bool +CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen); + + +/* + * Local globals + */ + +static jmp_buf g_jmpWMEntry; +static jmp_buf g_jmpXMsgProcEntry; +static Bool g_shutdown = FALSE; +static Bool redirectError = FALSE; +static Bool g_fAnotherWMRunnig = FALSE; + +/* + * PushMessage - Push a message onto the queue + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) +{ + + /* Lock the queue mutex */ + pthread_mutex_lock (&pQueue->pmMutex); + + pNode->pNext = NULL; + + if (pQueue->pTail != NULL) + { + pQueue->pTail->pNext = pNode; + } + pQueue->pTail = pNode; + + if (pQueue->pHead == NULL) + { + pQueue->pHead = pNode; + } + + +#if 0 + switch (pNode->msg.msg) + { + case WM_WM_MOVE: + ErrorF ("\tWM_WM_MOVE\n"); + break; + case WM_WM_SIZE: + ErrorF ("\tWM_WM_SIZE\n"); + break; + case WM_WM_RAISE: + ErrorF ("\tWM_WM_RAISE\n"); + break; + case WM_WM_LOWER: + ErrorF ("\tWM_WM_LOWER\n"); + break; + case WM_WM_MAP: + ErrorF ("\tWM_WM_MAP\n"); + break; + case WM_WM_UNMAP: + ErrorF ("\tWM_WM_UNMAP\n"); + break; + case WM_WM_KILL: + ErrorF ("\tWM_WM_KILL\n"); + break; + case WM_WM_ACTIVATE: + ErrorF ("\tWM_WM_ACTIVATE\n"); + break; + default: + ErrorF ("\tUnknown Message.\n"); + break; + } +#endif + + /* Increase the count of elements in the queue by one */ + ++(pQueue->nQueueSize); + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + /* Signal that the queue is not empty */ + pthread_cond_signal (&pQueue->pcNotEmpty); +} + + +#if CYGMULTIWINDOW_DEBUG +/* + * QueueSize - Return the size of the queue + */ + +static int +QueueSize (WMMsgQueuePtr pQueue) +{ + WMMsgNodePtr pNode; + int nSize = 0; + + /* Loop through all elements in the queue */ + for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) + ++nSize; + + return nSize; +} +#endif + + +/* + * PopMessage - Pop a message from the queue + */ + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) +{ + WMMsgNodePtr pNode; + + /* Lock the queue mutex */ + pthread_mutex_lock (&pQueue->pmMutex); + + /* Wait for --- */ + while (pQueue->pHead == NULL) + { + pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex); + } + + pNode = pQueue->pHead; + if (pQueue->pHead != NULL) + { + pQueue->pHead = pQueue->pHead->pNext; + } + + if (pQueue->pTail == pNode) + { + pQueue->pTail = NULL; + } + + /* Drop the number of elements in the queue by one */ + --(pQueue->nQueueSize); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue)); +#endif + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + return pNode; +} + + +#if 0 +/* + * HaveMessage - + */ + +static Bool +HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow) +{ + WMMsgNodePtr pNode; + + for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) + { + if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow) + return True; + } + + return False; +} +#endif + + +/* + * InitQueue - Initialize the Window Manager message queue + */ + +static +Bool +InitQueue (WMMsgQueuePtr pQueue) +{ + /* Check if the pQueue pointer is NULL */ + if (pQueue == NULL) + { + ErrorF ("InitQueue - pQueue is NULL. Exiting.\n"); + return FALSE; + } + + /* Set the head and tail to NULL */ + pQueue->pHead = NULL; + pQueue->pTail = NULL; + + /* There are no elements initially */ + pQueue->nQueueSize = 0; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize, + QueueSize(pQueue)); +#endif + + ErrorF ("InitQueue - Calling pthread_mutex_init\n"); + + /* Create synchronization objects */ + pthread_mutex_init (&pQueue->pmMutex, NULL); + + ErrorF ("InitQueue - pthread_mutex_init returned\n"); + ErrorF ("InitQueue - Calling pthread_cond_init\n"); + + pthread_cond_init (&pQueue->pcNotEmpty, NULL); + + ErrorF ("InitQueue - pthread_cond_init returned\n"); + + return TRUE; +} + + +/* + * GetWindowName - Retrieve the title of an X Window + */ + +static void +GetWindowName (Display *pDisplay, Window iWin, char **ppName) +{ + int nResult, nNum; + char **ppList; + XTextProperty xtpName; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName\n"); +#endif + + /* Intialize ppName to NULL */ + *ppName = NULL; + + /* Try to get --- */ + nResult = XGetWMName (pDisplay, iWin, &xtpName); + if (!nResult || !xtpName.value || !xtpName.nitems) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - XGetWMName failed. No name.\n"); +#endif + return; + } + + /* */ + if (xtpName.encoding == XA_STRING) + { + /* */ + if (xtpName.value) + { + int size = xtpName.nitems * (xtpName.format >> 3); + *ppName = malloc(size + 1); + strncpy(*ppName, xtpName.value, size); + (*ppName)[size] = 0; + XFree (xtpName.value); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - XA_STRING %s\n", *ppName); +#endif + } + else + { + if (XmbTextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList) + { + *ppName = strdup (*ppList); + XFreeStringList (ppList); + } + XFree (xtpName.value); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - %s %s\n", + XGetAtomName (pDisplay, xtpName.encoding), *ppName); +#endif + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - Returning\n"); +#endif +} + + +/* + * Send a message to the X server from the WM thread + */ + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData) +{ + XEvent e; + + /* Prepare the X event structure */ + e.type = ClientMessage; + e.xclient.window = iWin; + e.xclient.message_type = atmType; + e.xclient.format = 32; + e.xclient.data.l[0] = nData; + e.xclient.data.l[1] = CurrentTime; + + /* Send the event to X */ + return XSendEvent (pDisplay, iWin, False, NoEventMask, &e); +} + + +/* + * Updates the name of a HWND according to its X WM_NAME property + */ + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow) +{ + char *pszName; + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND *retHwnd, hWnd; + XWindowAttributes attr; + + hWnd = 0; + + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + XA_INTEGER,//pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + /* Some sanity checks */ + if (!hWnd) return; + if (!IsWindow (hWnd)) return; + + /* Set the Windows window name */ + GetWindowName (pWMInfo->pDisplay, iWindow, &pszName); + if (pszName) + { + /* Get the window attributes */ + XGetWindowAttributes (pWMInfo->pDisplay, + iWindow, + &attr); + if (!attr.override_redirect) + { + SetWindowText (hWnd, pszName); + winUpdateIcon (iWindow); + } + + free (pszName); + } +} + + +#if 0 +/* + * Fix up any differences between the X11 and Win32 window stacks + * starting at the window passed in + */ +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction) +{ + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND hWnd, *retHwnd; + DWORD myWinProcID, winProcID; + Window xWindow; + WINDOWPLACEMENT wndPlace; + + hWnd = NULL; + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + XA_INTEGER,//pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + if (!hWnd) return; + + GetWindowThreadProcessId (hWnd, &myWinProcID); + hWnd = GetNextWindow (hWnd, direction); + + while (hWnd) { + GetWindowThreadProcessId (hWnd, &winProcID); + if (winProcID == myWinProcID) + { + wndPlace.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement (hWnd, &wndPlace); + if ( !(wndPlace.showCmd==SW_HIDE || + wndPlace.showCmd==SW_MINIMIZE) ) + { + xWindow = (Window)GetProp (hWnd, WIN_WID_PROP); + if (xWindow) + { + if (direction==GW_HWNDPREV) + XRaiseWindow (pWMInfo->pDisplay, xWindow); + else + XLowerWindow (pWMInfo->pDisplay, xWindow); + } + } + } + hWnd = GetNextWindow(hWnd, direction); + } +} +#endif /* PreserveWin32Stack */ + + +/* + * winMultiWindowWMProc + */ + +static void * +winMultiWindowWMProc (void *pArg) +{ + WMProcArgPtr pProcArg = (WMProcArgPtr)pArg; + WMInfoPtr pWMInfo = pProcArg->pWMInfo; + + /* Initialize the Window Manager */ + winInitMultiWindowWM (pWMInfo, pProcArg); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowWMProc ()\n"); +#endif + + /* Loop until we explicity break out */ + for (;;) + { + WMMsgNodePtr pNode; + + if(g_fAnotherWMRunnig)/* Another Window manager exists. */ + { + Sleep (1000); + continue; + } + + /* Pop a message off of our queue */ + pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo); + if (pNode == NULL) + { + /* Bail if PopMessage returns without a message */ + /* NOTE: Remember that PopMessage is a blocking function. */ + ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\n"); + pthread_exit (NULL); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n", + GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID); +#endif + + /* Branch on the message type */ + switch (pNode->msg.msg) + { +#if 0 + case WM_WM_MOVE: + ErrorF ("\tWM_WM_MOVE\n"); + break; + + case WM_WM_SIZE: + ErrorF ("\tWM_WM_SIZE\n"); + break; +#endif + + case WM_WM_RAISE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_RAISE\n"); +#endif + /* Raise the window */ + XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow); +#if 0 + PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); +#endif + break; + + case WM_WM_LOWER: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_LOWER\n"); +#endif + + /* Lower the window */ + XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_MAP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP\n"); +#endif + /* Put a note as to the HWND associated with this Window */ + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + UpdateName (pWMInfo, pNode->msg.iWindow); + winUpdateIcon (pNode->msg.iWindow); +#if 0 + /* Handles the case where there are AOT windows above it in W32 */ + PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); +#endif + break; + + case WM_WM_UNMAP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_UNMAP\n"); +#endif + + /* Unmap the window */ + XUnmapWindow (pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_KILL: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_KILL\n"); +#endif + { + int i, n, found = 0; + Atom *protocols; + + /* --- */ + if (XGetWMProtocols (pWMInfo->pDisplay, + pNode->msg.iWindow, + &protocols, + &n)) + { + for (i = 0; i < n; ++i) + if (protocols[i] == pWMInfo->atmWmDelete) + ++found; + + XFree (protocols); + } + + /* --- */ + if (found) + SendXMessage (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmWmProtos, + pWMInfo->atmWmDelete); + else + XKillClient (pWMInfo->pDisplay, + pNode->msg.iWindow); + } + break; + + case WM_WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_ACTIVATE\n"); +#endif + + /* Set the input focus */ + XSetInputFocus (pWMInfo->pDisplay, + pNode->msg.iWindow, + RevertToPointerRoot, + CurrentTime); + break; + + case WM_WM_NAME_EVENT: + UpdateName (pWMInfo, pNode->msg.iWindow); + break; + + case WM_WM_HINTS_EVENT: + winUpdateIcon (pNode->msg.iWindow); + break; + + case WM_WM_CHANGE_STATE: + /* Minimize the window in Windows */ + winMinimizeWindow (pNode->msg.iWindow); + break; + + default: + ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\n"); + pthread_exit (NULL); + break; + } + + /* Free the retrieved message */ + free (pNode); + + /* Flush any pending events on our display */ + XFlush (pWMInfo->pDisplay); + } + + /* Free the condition variable */ + pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty); + + /* Free the mutex variable */ + pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex); + + /* Free the passed-in argument */ + free (pProcArg); + +#if CYGMULTIWINDOW_DEBUG + ErrorF("-winMultiWindowWMProc ()\n"); +#endif +} + + +/* + * X message procedure + */ + +static void * +winMultiWindowXMsgProc (void *pArg) +{ + winWMMessageRec msg; + XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg; + char pszDisplay[512]; + int iRetries; + XEvent event; + Atom atmWmName; + Atom atmWmHints; + Atom atmWmChange; + int iReturn; + XIconSize *xis; + + ErrorF ("winMultiWindowXMsgProc - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n"); + + /* Grab the server started mutex - pause until we get it */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. " + "Exiting.\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winMultiWindowXMsgProc - Locale not supported by X. " + "Exiting.\n"); + pthread_exit (NULL); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n"); + + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpXMsgProcEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler); + + /* Setup the display connection string x */ + snprintf (pszDisplay, + 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay); + + /* Initialize retry count */ + iRetries = 0; + + /* Open the X display */ + do + { + /* Try to open the display */ + pProcArg->pDisplay = XOpenDisplay (pszDisplay); + if (pProcArg->pDisplay == NULL) + { + ErrorF ("winMultiWindowXMsgProc - Could not open display, try: %d, " + "sleeping: %d\n\f", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pProcArg->pDisplay == NULL) + { + ErrorF ("winMultiWindowXMsgProc - Failed opening the display. " + "Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Check if another window manager is already running */ + if (pProcArg->pWMInfo->fAllowOtherWM) + { + g_fAnotherWMRunnig = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen); + } else { + redirectError = FALSE; + XSetErrorHandler (winRedirectErrorHandler); + XSelectInput(pProcArg->pDisplay, + RootWindow (pProcArg->pDisplay, pProcArg->dwScreen), + SubstructureNotifyMask | ButtonPressMask); + XSync (pProcArg->pDisplay, 0); + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + if (redirectError) + { + ErrorF ("winMultiWindowXMsgProc - " + "another window manager is running. Exiting.\n"); + pthread_exit (NULL); + } + g_fAnotherWMRunnig = FALSE; + } + + /* Set up the supported icon sizes */ + xis = XAllocIconSize (); + if (xis) + { + xis->min_width = xis->min_height = 16; + xis->max_width = xis->max_height = 48; + xis->width_inc = xis->height_inc = 16; + XSetIconSizes (pProcArg->pDisplay, + RootWindow (pProcArg->pDisplay, pProcArg->dwScreen), + xis, + 1); + XFree (xis); + } + + atmWmName = XInternAtom (pProcArg->pDisplay, + "WM_NAME", + False); + atmWmHints = XInternAtom (pProcArg->pDisplay, + "WM_HINTS", + False); + atmWmChange = XInternAtom (pProcArg->pDisplay, + "WM_CHANGE_STATE", + False); + + /* Loop until we explicitly break out */ + while (1) + { + if (g_shutdown) + break; + + if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay)) + { + if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen)) + { + if (!g_fAnotherWMRunnig) + { + g_fAnotherWMRunnig = TRUE; + SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0); + } + } + else + { + if (g_fAnotherWMRunnig) + { + g_fAnotherWMRunnig = FALSE; + SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0); + } + } + Sleep (500); + continue; + } + + /* Fetch next event */ + XNextEvent (pProcArg->pDisplay, &event); + + /* Branch on event type */ + if (event.type == CreateNotify) + { + XWindowAttributes attr; + + XSelectInput (pProcArg->pDisplay, + event.xcreatewindow.window, + PropertyChangeMask); + + /* Get the window attributes */ + XGetWindowAttributes (pProcArg->pDisplay, + event.xcreatewindow.window, + &attr); + + if (!attr.override_redirect) + XSetWindowBorderWidth(pProcArg->pDisplay, + event.xcreatewindow.window, + 0); + } + else if (event.type == PropertyNotify + && event.xproperty.atom == atmWmName) + { + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_NAME_EVENT; + msg.iWindow = event.xproperty.window; + + /* Other fields ignored */ + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + else if (event.type == PropertyNotify + && event.xproperty.atom == atmWmHints) + { + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_HINTS_EVENT; + msg.iWindow = event.xproperty.window; + + /* Other fields ignored */ + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + else if (event.type == ClientMessage + && event.xclient.message_type == atmWmChange + && event.xclient.data.l[0] == IconicState) + { + ErrorF ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n"); + + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_CHANGE_STATE; + msg.iWindow = event.xclient.window; + + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + } + + XCloseDisplay (pProcArg->pDisplay); + pthread_exit (NULL); + +} + + +/* + * winInitWM - Entry point for the X server to spawn + * the Window Manager thread. Called from + * winscrinit.c/winFinishScreenInitFB (). + */ + +Bool +winInitWM (void **ppWMInfo, + pthread_t *ptWMProc, + pthread_t *ptXMsgProc, + pthread_mutex_t *ppmServerStarted, + int dwScreen, + HWND hwndScreen, + BOOL allowOtherWM) +{ + WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec)); + WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec)); + XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec)); + + /* Bail if the input parameters are bad */ + if (pArg == NULL || pWMInfo == NULL) + { + ErrorF ("winInitWM - malloc failed.\n"); + return FALSE; + } + + /* Zero the allocated memory */ + ZeroMemory (pArg, sizeof (WMProcArgRec)); + ZeroMemory (pWMInfo, sizeof (WMInfoRec)); + ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec)); + + /* Set a return pointer to the Window Manager info structure */ + *ppWMInfo = pWMInfo; + pWMInfo->fAllowOtherWM = allowOtherWM; + + /* Setup the argument structure for the thread function */ + pArg->dwScreen = dwScreen; + pArg->pWMInfo = pWMInfo; + pArg->ppmServerStarted = ppmServerStarted; + + /* Intialize the message queue */ + if (!InitQueue (&pWMInfo->wmMsgQueue)) + { + ErrorF ("winInitWM - InitQueue () failed.\n"); + return FALSE; + } + + /* Spawn a thread for the Window Manager */ + if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed for Window Manager.\n"); + return FALSE; + } + + /* Spawn the XNextEvent thread, will send messages to WM */ + pXMsgArg->dwScreen = dwScreen; + pXMsgArg->pWMInfo = pWMInfo; + pXMsgArg->ppmServerStarted = ppmServerStarted; + pXMsgArg->hwndScreen = hwndScreen; + if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed on XMSG.\n"); + return FALSE; + } + +#if CYGDEBUG || YES + winDebug ("winInitWM - Returning.\n"); +#endif + + return TRUE; +} + + +/* + * Window manager thread - setup + */ + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) +{ + int iRetries = 0; + char pszDisplay[512]; + int iReturn; + + ErrorF ("winInitMultiWindowWM - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n"); + + /* Grab our garbage mutex to satisfy pthread_cond_wait */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d. " + "Exiting.\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winInitMultiWindowWM - Locale not supported by X. Exiting.\n"); + pthread_exit (NULL); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); + + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpWMEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winInitMultiWindowWM - setjmp returned: %d. Exiting.\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowWM - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowWMErrorHandler); + XSetIOErrorHandler (winMultiWindowWMIOErrorHandler); + + /* Setup the display connection string x */ + snprintf (pszDisplay, + 512, + "127.0.0.1:%s.%d", + display, + (int) pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay); + + /* Open the X display */ + do + { + /* Try to open the display */ + pWMInfo->pDisplay = XOpenDisplay (pszDisplay); + if (pWMInfo->pDisplay == NULL) + { + ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, " + "sleeping: %d\n\f", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pWMInfo->pDisplay == NULL) + { + ErrorF ("winInitMultiWindowWM - Failed opening the display. " + "Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + + /* Create some atoms */ + pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay, + "WM_PROTOCOLS", + False); + pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay, + "WM_DELETE_WINDOW", + False); +#ifdef XWIN_MULTIWINDOWEXTWM + pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay, + WINDOWSWM_NATIVE_HWND, + False); +#endif + + + if (1) { + Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr); + if (cursor) + { + XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor); + XFreeCursor (pWMInfo->pDisplay, cursor); + } + } +} + + +/* + * winSendMessageToWM - Send a message from the X thread to the WM thread + */ + +void +winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg) +{ + WMMsgNodePtr pNode; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winSendMessageToWM ()\n"); +#endif + + pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec)); + if (pNode != NULL) + { + memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec)); + PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode); + } +} + + +/* + * Window manager error handler + */ + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + if (pErr->request_code == X_ChangeWindowAttributes + && pErr->error_code == BadAccess) + { + ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " + "BadAccess.\n"); + return 0; + } + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); + + return 0; +} + + +/* + * Window manager IO error handler + */ + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay) +{ + ErrorF ("\nwinMultiWindowWMIOErrorHandler!\n\n"); + + if (g_shutdown) + pthread_exit(NULL); + + /* Restart at the main entry point */ + longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * X message procedure error handler + */ + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg); + + return 0; +} + + +/* + * X message procedure IO error handler + */ + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay) +{ + ErrorF ("\nwinMultiWindowXMsgProcIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * Catch RedirectError to detect other window manager running + */ + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + redirectError = TRUE; + return 0; +} + + +/* + * Check if another window manager is running + */ + +static Bool +CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen) +{ + redirectError = FALSE; + XSetErrorHandler (winRedirectErrorHandler); + XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), + // SubstructureNotifyMask | ButtonPressMask + ColormapChangeMask | EnterWindowMask | PropertyChangeMask | + SubstructureRedirectMask | KeyPressMask | + ButtonPressMask | ButtonReleaseMask); + XSync (pDisplay, 0); + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), + SubstructureNotifyMask); + XSync (pDisplay, 0); + if (redirectError) + { + //ErrorF ("CheckAnotherWindowManager() - another window manager is running. Exiting.\n"); + return TRUE; + } + else + { + return FALSE; + } +} + +/* + * Notify the MWM thread we're exiting and not to reconnect + */ + +void +winDeinitMultiWindowWM () +{ + ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n"); + g_shutdown = TRUE; +} diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c new file mode 100644 index 000000000..20ff9f7db --- /dev/null +++ b/hw/xwin/winmultiwindowwndproc.c @@ -0,0 +1,1049 @@ +/* + *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 <xwin-config.h> +#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]; + + +/* + * Local globals + */ + +static UINT_PTR g_uipMousePollingTimerID = 0; + + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 +#define WIN_MULTIWINDOW_SHAPE YES + + +/* + * ConstrainSize - Taken from TWM sources - Respects hints for sizing + */ +#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) +static void +ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp) +{ + int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; + int baseWidth, baseHeight; + int dwidth = *widthp, dheight = *heightp; + + if (hints.flags & PMinSize) + { + minWidth = hints.min_width; + minHeight = hints.min_height; + } + else if (hints.flags & PBaseSize) + { + minWidth = hints.base_width; + minHeight = hints.base_height; + } + else + minWidth = minHeight = 1; + + if (hints.flags & PBaseSize) + { + baseWidth = hints.base_width; + baseHeight = hints.base_height; + } + else if (hints.flags & PMinSize) + { + baseWidth = hints.min_width; + baseHeight = hints.min_height; + } + else + baseWidth = baseHeight = 0; + + if (hints.flags & PMaxSize) + { + maxWidth = hints.max_width; + maxHeight = hints.max_height; + } + else + { + maxWidth = MAXINT; + maxHeight = MAXINT; + } + + if (hints.flags & PResizeInc) + { + xinc = hints.width_inc; + yinc = hints.height_inc; + } + else + xinc = yinc = 1; + + /* + * First, clamp to min and max values + */ + if (dwidth < minWidth) + dwidth = minWidth; + if (dheight < minHeight) + dheight = minHeight; + + if (dwidth > maxWidth) + dwidth = maxWidth; + if (dheight > maxHeight) + dheight = maxHeight; + + /* + * Second, fit to base + N * inc + */ + dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; + dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; + + /* + * Third, adjust for aspect ratio + */ + + /* + * The math looks like this: + * + * minAspectX dwidth maxAspectX + * ---------- <= ------- <= ---------- + * minAspectY dheight maxAspectY + * + * If that is multiplied out, then the width and height are + * invalid in the following situations: + * + * minAspectX * dheight > minAspectY * dwidth + * maxAspectX * dheight < maxAspectY * dwidth + * + */ + + if (hints.flags & PAspect) + { + if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth) + { + delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc); + if (dwidth + delta <= maxWidth) + dwidth += delta; + else + { + delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc); + if (dheight - delta >= minHeight) + dheight -= delta; + } + } + + if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth) + { + delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc); + if (dheight + delta <= maxHeight) + dheight += delta; + else + { + delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc); + if (dwidth - delta >= minWidth) + dwidth -= delta; + } + } + } + + /* Return computed values */ + *widthp = dwidth; + *heightp = dheight; +} +#undef makemult + + + +/* + * ValidateSizing - Ensures size request respects hints + */ +static int +ValidateSizing (HWND hwnd, WindowPtr pWin, + WPARAM wParam, LPARAM lParam) +{ + WinXSizeHints sizeHints; + RECT *rect; + int iWidth, iHeight; + + /* 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 */ + iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME); + iHeight -= (GetSystemMetrics(SM_CYCAPTION) + + 2 * GetSystemMetrics(SM_CYSIZEFRAME)); + + + /* Constrain the size to legal values */ + ConstrainSize (sizeHints, &iWidth, &iHeight); + + /* Add back the borders */ + iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME); + iHeight += (GetSystemMetrics(SM_CYCAPTION) + + 2 * GetSystemMetrics(SM_CYSIZEFRAME)); + + /* 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; + winInRaiseWindow = TRUE; + /* Call configure window directly to make sure it gets processed + * in time + */ + XID vlist[1] = { 0 }; + ConfigureWindow(pWin, CWStackMode, vlist, serverClient); + winInRaiseWindow = oldstate; + } +} + + +/* + * 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); + + 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_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(inputInfo.pointer)) + miPointerSetScreen (inputInfo.pointer, 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 */ + miPointerAbsoluteCursor (ptMouse.x - s_pScreenInfo->dwXOffset, + ptMouse.y - s_pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + return 0; + + case WM_NCMOUSEMOVE: + /* + * We break instead of returning 0 since we need to call + * DefWindowProc to get the mouse cursor changes + * and min/max/close button highlighting in Windows XP. + * The Platform SDK says that you should return 0 if you + * process this message, but it fails to mention that you + * will give up any default functionality if you do return 0. + */ + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Non-client mouse movement, show Windows cursor */ + if (g_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + break; + + case WM_MOUSELEAVE: + /* Mouse has left our client area */ + + /* Flag that we are no longer tracking */ + s_fTracking = FALSE; + + /* Show the mouse cursor, if necessary */ + if (g_fSoftwareCursor && !g_fCursor) + { + g_fCursor = TRUE; + ShowCursor (TRUE); + } + + /* + * Timer to poll mouse events. This is needed to make + * programs like xeyes follow the mouse properly. + */ + if (g_uipMousePollingTimerID == 0) + g_uipMousePollingTimerID = SetTimer (s_pScreenPriv->hwndScreen, + WIN_POLLING_MOUSE_TIMER_ID, + MOUSE_POLLING_INTERVAL, + NULL); + return 0; + + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[0] = TRUE; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam); + + case WM_LBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[0] = FALSE; + 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; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam); + + case WM_MBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[1] = FALSE; + 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; + return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam); + + case WM_RBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + g_fButton[2] = FALSE; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam); + + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonPress, HIWORD(wParam) + 5, wParam); + case WM_XBUTTONUP: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + return winMouseButtonsHandle (s_pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam); + + case WM_MOUSEWHEEL: + + /* Pass the message to the root window */ + SendMessage (hwndScreen, message, wParam, lParam); + return 0; + + case WM_SETFOCUS: + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + 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 (); + 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); + } + 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; + + /* Tell X to map the window */ + MapWindow (pWin, wClient(pWin)); + + /* */ + if (!pWin->overrideRedirect) + { + DWORD dwExStyle; + DWORD dwStyle; + RECT rcNew; + int iDx, iDy; + + /* Flag that this window needs to be made active when clicked */ + SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1); + + /* Get the standard and extended window style information */ + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); + + /* */ + if (dwExStyle != WS_EX_APPWINDOW) + { + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pDraw->x, + pDraw->y, + pDraw->x + pDraw->width, + pDraw->y + pDraw->height); + +#if 0 + ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + FALSE, + WS_EX_APPWINDOW); + + /* Calculate position deltas */ + iDx = pDraw->x - rcNew.left; + iDy = pDraw->y - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; + +#if 0 + ErrorF ("winTopLevelWindowProc - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* Set the window extended style flags */ + SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (hwnd, GWL_STYLE, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); + + /* Position the Windows window */ + SetWindowPos (hwnd, HWND_TOP, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + SWP_NOMOVE | SWP_FRAMECHANGED + | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + /* Bring the Windows window to the foreground */ + SetForegroundWindow (hwnd); + } + } + else /* It is an overridden window so make it top of Z stack */ + { +#if CYGWINDOWING_DEBUG + ErrorF ("overridden window is shown\n"); +#endif + SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + + /* Setup the Window Manager message */ + wmMsg.msg = WM_WM_MAP; + wmMsg.iWidth = pDraw->width; + wmMsg.iHeight = pDraw->height; + + /* Tell our Window Manager thread to map the window */ + if (fWMMsgInitialized) + winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg); + + 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/hw/xwin/winnativegdi.c b/hw/xwin/winnativegdi.c new file mode 100644 index 000000000..48a467a2c --- /dev/null +++ b/hw/xwin/winnativegdi.c @@ -0,0 +1,546 @@ +/* + *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 <xwin-config.h> +#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; +} diff --git a/hw/xwin/winpfbdd.c b/hw/xwin/winpfbdd.c new file mode 100644 index 000000000..13fc1058d --- /dev/null +++ b/hw/xwin/winpfbdd.c @@ -0,0 +1,684 @@ +/* + *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 <xwin-config.h> +#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; +} diff --git a/hw/xwin/winpixmap.c b/hw/xwin/winpixmap.c new file mode 100644 index 000000000..050c71a7f --- /dev/null +++ b/hw/xwin/winpixmap.c @@ -0,0 +1,235 @@ +/* + *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: drewry, september 1986 + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + + +/* + * Local prototypes + */ + +#if 0 +static void +winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw); + +static void +winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh); + +static void +winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, + int xrot, int yrot); +#endif + + +/* See Porting Layer Definition - p. 34 */ +/* See mfb/mfbpixmap.c - mfbCreatePixmap() */ +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, + int iWidth, int iHeight, + int iDepth, unsigned usage_hint) +{ + winPrivPixmapPtr pPixmapPriv = NULL; + PixmapPtr pPixmap = NULL; + + /* Allocate pixmap memory */ + pPixmap = AllocatePixmap (pScreen, 0); + if (!pPixmap) + { + ErrorF ("winCreatePixmapNativeGDI () - Couldn't allocate a pixmap\n"); + return NullPixmap; + } + +#if CYGDEBUG + winDebug ("winCreatePixmap () - w %d h %d d %d uh %d bw %d\n", + iWidth, iHeight, iDepth, usage_hint, + PixmapBytePad (iWidth, iDepth)); +#endif + + /* Setup pixmap values */ + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = iDepth; + pPixmap->drawable.bitsPerPixel = BitsPerPixel (iDepth); + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = iWidth; + pPixmap->drawable.height = iHeight; + pPixmap->devKind = 0; + pPixmap->refcnt = 1; + pPixmap->devPrivate.ptr = NULL; + pPixmap->usage_hint = usage_hint; + + /* Pixmap privates are allocated by AllocatePixmap */ + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Initialize pixmap privates */ + pPixmapPriv->hBitmap = NULL; + pPixmapPriv->hdcSelected = NULL; + pPixmapPriv->pbBits = NULL; + pPixmapPriv->dwScanlineBytes = PixmapBytePad (iWidth, iDepth); + + /* Check for zero width or height pixmaps */ + if (iWidth == 0 || iHeight == 0) + { + /* Don't allocate a real pixmap, just set fields and return */ + return pPixmap; + } + + /* Create a DIB for the pixmap */ + pPixmapPriv->hBitmap = winCreateDIBNativeGDI (iWidth, iHeight, iDepth, + &pPixmapPriv->pbBits, + (BITMAPINFO **) &pPixmapPriv->pbmih); + +#if CYGDEBUG + winDebug ("winCreatePixmap () - Created a pixmap %08x, %dx%dx%d, for " \ + "screen: %08x\n", + pPixmapPriv->hBitmap, iWidth, iHeight, iDepth, pScreen); +#endif + + return pPixmap; +} + + +/* + * See Porting Layer Definition - p. 35 + * + * See mfb/mfbpixmap.c - mfbDestroyPixmap() + */ + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap) +{ + winPrivPixmapPtr pPixmapPriv = NULL; + +#if CYGDEBUG + winDebug ("winDestroyPixmapNativeGDI ()\n"); +#endif + + /* Bail early if there is not a pixmap to destroy */ + if (pPixmap == NULL) + { + ErrorF ("winDestroyPixmapNativeGDI () - No pixmap to destroy\n"); + return TRUE; + } + + /* Get a handle to the pixmap privates */ + pPixmapPriv = winGetPixmapPriv (pPixmap); + +#if CYGDEBUG + winDebug ("winDestroyPixmapNativeGDI - pPixmapPriv->hBitmap: %08x\n", + pPixmapPriv->hBitmap); +#endif + + /* Decrement reference count, return if nonzero */ + --pPixmap->refcnt; + if (pPixmap->refcnt != 0) + return TRUE; + + /* Free GDI bitmap */ + if (pPixmapPriv->hBitmap) DeleteObject (pPixmapPriv->hBitmap); + + /* Free the bitmap info header memory */ + if (pPixmapPriv->pbmih != NULL) + { + free (pPixmapPriv->pbmih); + pPixmapPriv->pbmih = NULL; + } + + /* Free the pixmap memory */ + free (pPixmap); + pPixmap = NULL; + + return TRUE; +} + + +/* + * Not used yet + */ + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData) +{ + FatalError ("winModifyPixmapHeaderNativeGDI ()\n"); + return TRUE; +} + + +#if 0 +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ + +static void +winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw) +{ + ErrorF ("winXRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ +static void +winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh) +{ + ErrorF ("winYRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ + +static void +winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, + int xrot, int yrot) +{ + ErrorF ("winCopyRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} +#endif diff --git a/hw/xwin/winpolyline.c b/hw/xwin/winpolyline.c new file mode 100644 index 000000000..db9dd345b --- /dev/null +++ b/hw/xwin/winpolyline.c @@ -0,0 +1,57 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + +/* See Porting Layer Definition - p. 50 */ +void +winPolyLineNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt) +{ + switch (pGC->lineStyle) + { + case LineSolid: + if (pGC->lineWidth == 0) + return miZeroLine (pDrawable, pGC, mode, npt, ppt); + else + miWideLine (pDrawable, pGC, mode, npt, ppt); + break; + case LineOnOffDash: + case LineDoubleDash: + miWideDash (pDrawable, pGC, mode, npt, ppt); + break; + } +} diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c new file mode 100644 index 000000000..30e587d4a --- /dev/null +++ b/hw/xwin/winprefs.c @@ -0,0 +1,822 @@ +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef __CYGWIN__ +#include <sys/resource.h> +#endif +#include "win.h" + +#include <X11/Xwindows.h> +#include <shellapi.h> + +#include "winprefs.h" +#include "winmultiwindowclass.h" + +/* Where will the custom menu commands start counting from? */ +#define STARTMENUID WM_USER + +/* 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; + + +/* Defined in DIX */ +extern char *display; + +/* Local function to handle comma-ified icon names */ +static HICON +LoadImageComma (char *fname, int sx, int sy, int flags); + + +/* + * Creates or appends a menu from a MENUPARSED structure + */ +static HMENU +MakeMenu (char *name, + HMENU editMenu, + int editItem) +{ + int i; + int item; + MENUPARSED *m; + HMENU hmenu, hsub; + + for (i=0; i<pref.menuItems; i++) + { + if (!strcmp(name, pref.menu[i].menuName)) + break; + } + + /* Didn't find a match, bummer */ + if (i==pref.menuItems) + { + ErrorF("MakeMenu: Can't find menu %s\n", name); + return NULL; + } + + m = &(pref.menu[i]); + + if (editMenu) + { + hmenu = editMenu; + item = editItem; + } + else + { + hmenu = CreatePopupMenu(); + if (!hmenu) + { + ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name); + return NULL; + } + item = 0; + } + + /* Add the menu items */ + for (i=0; i<m->menuItems; i++) + { + /* Only assign IDs one time... */ + if ( m->menuItem[i].commandID == 0 ) + m->menuItem[i].commandID = g_cmdid++; + + switch (m->menuItem[i].cmd) + { + case CMD_EXEC: + case CMD_ALWAYSONTOP: + case CMD_RELOAD: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_ENABLED|MF_STRING, + m->menuItem[i].commandID, + m->menuItem[i].text); + break; + + case CMD_SEPARATOR: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_SEPARATOR, + 0, + NULL); + break; + + case CMD_MENU: + /* Recursive! */ + hsub = MakeMenu (m->menuItem[i].param, 0, 0); + if (hsub) + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING, + (UINT_PTR)hsub, + m->menuItem[i].text); + break; + } + + /* If item==-1 (means to add at end of menu) don't increment) */ + if (item>=0) + item++; + } + + return hmenu; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Callback routine that is executed once per window class. + * Removes or creates custom window settings depending on LPARAM + */ +static wBOOL CALLBACK +ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam) +{ + HICON hicon; + Window wid; + + if (!hwnd) { + ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n"); + return FALSE; + } + + /* It's our baby, either clean or dirty it */ + if (lParam==FALSE) + { + hicon = (HICON)GetClassLong(hwnd, GCL_HICON); + + /* Unselect any icon in the class structure */ + SetClassLong (hwnd, GCL_HICON, (LONG)LoadIcon (NULL, IDI_APPLICATION)); + + /* If it's generated on-the-fly, get rid of it, will regen */ + winDestroyIcon (hicon); + + hicon = (HICON)GetClassLong(hwnd, GCL_HICONSM); + + /* Unselect any icon in the class structure */ + SetClassLong (hwnd, GCL_HICONSM, 0); + + /* If it's generated on-the-fly, get rid of it, will regen */ + winDestroyIcon (hicon); + + /* Remove any menu additions, use bRevert flag */ + GetSystemMenu (hwnd, TRUE); + + /* This window is now clean of our taint */ + } + else + { + /* Make the icon default, dynamic, or from xwinrc */ + SetClassLong (hwnd, GCL_HICON, (LONG)g_hIconX); + SetClassLong (hwnd, GCL_HICONSM, (LONG)g_hSmallIconX); + wid = (Window)GetProp (hwnd, WIN_WID_PROP); + if (wid) + winUpdateIcon (wid); + /* Update the system menu for this window */ + SetupSysMenu ((unsigned long)hwnd); + + /* That was easy... */ + } + + return TRUE; +} +#endif + + +/* + * Removes any custom icons in classes, custom menus, etc. + * Frees all members in pref structure. + * Reloads the preferences file. + * Set custom icons and menus again. + */ +static void +ReloadPrefs (void) +{ + int i; + +#ifdef XWIN_MULTIWINDOW + /* First, iterate over all windows replacing their icon with system */ + /* default one and deleting any custom system menus */ + EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE); +#endif + + /* Now, free/clear all info from our prefs structure */ + for (i=0; i<pref.menuItems; i++) + free (pref.menu[i].menuItem); + free (pref.menu); + pref.menu = NULL; + pref.menuItems = 0; + + pref.rootMenuName[0] = 0; + + free (pref.sysMenu); + pref.sysMenuItems = 0; + + pref.defaultSysMenuName[0] = 0; + pref.defaultSysMenuPos = 0; + + pref.iconDirectory[0] = 0; + pref.defaultIconName[0] = 0; + pref.trayIconName[0] = 0; + + for (i=0; i<pref.iconItems; i++) + if (pref.icon[i].hicon) + DestroyIcon ((HICON)pref.icon[i].hicon); + free (pref.icon); + pref.icon = NULL; + pref.iconItems = 0; + + /* Free global default X icon */ + if (g_hIconX) + DestroyIcon (g_hIconX); + if (g_hSmallIconX) + DestroyIcon (g_hSmallIconX); + + /* Reset the custom command IDs */ + g_cmdid = STARTMENUID; + + /* Load the updated resource file */ + LoadPreferences(); + + g_hIconX = NULL; + g_hSmallIconX = NULL; + +#ifdef XWIN_MULTIWINDOW + winInitGlobalIcons(); +#endif + +#ifdef XWIN_MULTIWINDOW + /* Rebuild the icons and menus */ + EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE); +#endif + + /* Whew, done */ +} + +/* + * Check/uncheck the ALWAYSONTOP items in this menu + */ +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn) +{ + HWND hwnd; + HMENU hmenu; + DWORD dwExStyle; + int i, j; + + hwnd = (HWND)hwndIn; + hmenu = (HMENU)hmenuIn; + if (!hwnd || !hmenu) + return; + + if (GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) + dwExStyle = MF_BYCOMMAND | MF_CHECKED; + else + dwExStyle = MF_BYCOMMAND | MF_UNCHECKED; + + for (i=0; i<pref.menuItems; i++) + for (j=0; j<pref.menu[i].menuItems; j++) + if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP) + CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle ); + +} + +/* + * Searches for the custom WM_COMMAND command ID and performs action. + * Return TRUE if command is proccessed, FALSE otherwise. + */ +Bool +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command) +{ + HWND hwnd; + int i, j; + MENUPARSED *m; + DWORD dwExStyle; + + hwnd = (HWND)hwndIn; + + if (!command) + return FALSE; + + for (i=0; i<pref.menuItems; i++) + { + m = &(pref.menu[i]); + for (j=0; j<m->menuItems; j++) + { + if (command==m->menuItem[j].commandID) + { + /* Match! */ + switch(m->menuItem[j].cmd) + { +#ifdef __CYGWIN__ + case CMD_EXEC: + if (fork()==0) + { + struct rlimit rl; + unsigned long i; + + /* Close any open descriptors except for STD* */ + getrlimit (RLIMIT_NOFILE, &rl); + for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) + close(i); + + /* Disassociate any TTYs */ + setsid(); + + execl ("/bin/sh", + "/bin/sh", + "-c", + m->menuItem[j].param, + NULL); + exit (0); + } + else + return TRUE; + break; +#else + case CMD_EXEC: + { + /* Start process without console window */ + STARTUPINFO start; + PROCESS_INFORMATION child; + + memset (&start, 0, sizeof (start)); + start.cb = sizeof (start); + start.dwFlags = STARTF_USESHOWWINDOW; + start.wShowWindow = SW_HIDE; + + memset (&child, 0, sizeof (child)); + + if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, + NULL, NULL, &start, &child)) + { + CloseHandle (child.hThread); + CloseHandle (child.hProcess); + } + else + MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); + } + return TRUE; +#endif + case CMD_ALWAYSONTOP: + if (!hwnd) + return FALSE; + + /* Get extended window style */ + dwExStyle = GetWindowLong (hwnd, GWL_EXSTYLE); + + /* Handle topmost windows */ + if (dwExStyle & WS_EX_TOPMOST) + SetWindowPos (hwnd, + HWND_NOTOPMOST, + 0, 0, + 0, 0, + SWP_NOSIZE | SWP_NOMOVE); + else + SetWindowPos (hwnd, + HWND_TOPMOST, + 0, 0, + 0, 0, + SWP_NOSIZE | SWP_NOMOVE); +#if XWIN_MULTIWINDOW + /* Reflect the changed Z order */ + winReorderWindowsMultiWindow (); +#endif + return TRUE; + + case CMD_RELOAD: + ReloadPrefs(); + return TRUE; + + default: + return FALSE; + } + } /* match */ + } /* for j */ + } /* for i */ + + return FALSE; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Add the default or a custom menu depending on the class match + */ +void +SetupSysMenu (unsigned long hwndIn) +{ + HWND hwnd; + HMENU sys; + int i; + WindowPtr pWin; + char *res_name, *res_class; + + hwnd = (HWND)hwndIn; + if (!hwnd) + return; + + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + sys = GetSystemMenu (hwnd, FALSE); + if (!sys) + return; + + if (pWin) + { + /* First see if there's a class match... */ + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + { + for (i=0; i<pref.sysMenuItems; i++) + { + if (!strcmp(pref.sysMenu[i].match, res_name) || + !strcmp(pref.sysMenu[i].match, res_class) ) + { + free(res_name); + free(res_class); + + MakeMenu (pref.sysMenu[i].menuName, sys, + pref.sysMenu[i].menuPos==AT_START?0:-1); + return; + } + } + + /* No match, just free alloc'd strings */ + free(res_name); + free(res_class); + } /* Found wm_class */ + } /* if pwin */ + + /* Fallback to system default */ + if (pref.defaultSysMenuName[0]) + { + if (pref.defaultSysMenuPos==AT_START) + MakeMenu (pref.defaultSysMenuName, sys, 0); + else + MakeMenu (pref.defaultSysMenuName, sys, -1); + } +} +#endif + + +/* + * Possibly add a menu to the toolbar icon + */ +void +SetupRootMenu (unsigned long hmenuRoot) +{ + HMENU root; + + root = (HMENU)hmenuRoot; + if (!root) + return; + + if (pref.rootMenuName[0]) + { + MakeMenu(pref.rootMenuName, root, 0); + } +} + + +/* + * Check for and return an overridden default ICON specified in the prefs + */ +unsigned long +winOverrideDefaultIcon(int size) +{ + HICON hicon; + + if (pref.defaultIconName[0]) + { + hicon = LoadImageComma (pref.defaultIconName, size, size, 0); + if (hicon==NULL) + ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n", + pref.defaultIconName); + + return (unsigned long)hicon; + } + + return 0; +} + + +/* + * Return the HICON to use in the taskbar notification area + */ +unsigned long +winTaskbarIcon(void) +{ + HICON hicon; + + hicon = 0; + /* First try and load an overridden, if success then return it */ + if (pref.trayIconName[0]) + { + hicon = LoadImageComma (pref.trayIconName, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0 ); + } + + /* Otherwise return the default */ + if (!hicon) + hicon = (HICON) LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0); + + return (unsigned long)hicon; +} + + +/* + * Parse a filename to extract an icon: + * If fname is exactly ",nnn" then extract icon from our resource + * else if it is "file,nnn" then extract icon nnn from that file + * else try to load it as an .ico file and if that fails return NULL + */ +static HICON +LoadImageComma (char *fname, int sx, int sy, int flags) +{ + HICON hicon; + int index; + char file[PATH_MAX+NAME_MAX+2]; + + /* Some input error checking */ + if (!fname || !fname[0]) + return NULL; + + index = 0; + hicon = NULL; + + if (fname[0]==',') + { + /* It's the XWIN.EXE resource they want */ + index = atoi (fname+1); + hicon = LoadImage (g_hInstance, + MAKEINTRESOURCE(index), + IMAGE_ICON, + sx, + sy, + flags); + } + else + { + file[0] = 0; + /* Prepend path if not given a "X:\" filename */ + if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') ) + { + strcpy (file, pref.iconDirectory); + if (pref.iconDirectory[0]) + if (fname[strlen(fname)-1]!='\\') + strcat (file, "\\"); + } + strcat (file, fname); + + if (strrchr (file, ',')) + { + /* Specified as <fname>,<index> */ + + *(strrchr (file, ',')) = 0; /* End string at comma */ + index = atoi (strrchr (fname, ',') + 1); + hicon = ExtractIcon (g_hInstance, file, index); + } + else + { + /* Just an .ico file... */ + + hicon = (HICON)LoadImage (NULL, + file, + IMAGE_ICON, + sx, + sy, + LR_LOADFROMFILE|flags); + } + } + return hicon; +} + +/* + * Check for a match of the window class to one specified in the + * ICONS{} section in the prefs file, and load the icon from a file + */ +unsigned long +winOverrideIcon (unsigned long longWin) +{ + WindowPtr pWin = (WindowPtr) longWin; + char *res_name, *res_class; + int i; + HICON hicon; + char *wmName; + + if (pWin==NULL) + return 0; + + /* If we can't find the class, we can't override from default! */ + if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + return 0; + + winMultiWindowGetWMName (pWin, &wmName); + + for (i=0; i<pref.iconItems; i++) { + if (!strcmp(pref.icon[i].match, res_name) || + !strcmp(pref.icon[i].match, res_class) || + (wmName && strstr(wmName, pref.icon[i].match))) + { + free (res_name); + free (res_class); + if (wmName) + free (wmName); + + if (pref.icon[i].hicon) + return pref.icon[i].hicon; + + hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE); + if (hicon==NULL) + ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n", + pref.icon[i].iconFile); + + pref.icon[i].hicon = (unsigned long)hicon; + return (unsigned long)hicon; + } + } + + /* Didn't find the icon, fail gracefully */ + free (res_name); + free (res_class); + if (wmName) + free (wmName); + + return 0; +} + + +/* + * Should we free this icon or leave it in memory (is it part of our + * ICONS{} overrides)? + */ +int +winIconIsOverride(unsigned hiconIn) +{ + HICON hicon; + int i; + + hicon = (HICON)hiconIn; + + if (!hicon) + return 0; + + for (i=0; i<pref.iconItems; i++) + if ((HICON)pref.icon[i].hicon == hicon) + return 1; + + return 0; +} + + + +/* + * Try and open ~/.XWinrc and /usr/X11R6/lib/X11/system.XWinrc + * Load it into prefs structure for use by other functions + */ +void +LoadPreferences () +{ + char *home; + char fname[PATH_MAX+NAME_MAX+2]; + FILE *prefFile; + char szDisplay[512]; + char *szEnvDisplay; + int i, j; + char param[PARAM_MAX+1]; + char *srcParam, *dstParam; + + /* First, clear all preference settings */ + memset (&pref, 0, sizeof(pref)); + prefFile = NULL; + + /* Now try and find a ~/.xwinrc file */ + home = getenv ("HOME"); + if (home) + { + strcpy (fname, home); + if (fname[strlen(fname)-1]!='/') + strcat (fname, "/"); + strcat (fname, ".XWinrc"); + + prefFile = fopen (fname, "r"); + if (prefFile) + ErrorF ("winPrefsLoadPreferences: %s\n", fname); + } + + /* No home file found, check system default */ + if (!prefFile) + { + char buffer[MAX_PATH]; +#ifdef RELOCATE_PROJECTROOT + snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir()); +#else + strncpy(buffer, PROJECTROOT"/lib/X11/system.XWinrc", sizeof(buffer)); +#endif + buffer[sizeof(buffer)-1] = 0; + prefFile = fopen (buffer, "r"); + if (prefFile) + ErrorF ("winPrefsLoadPreferences: %s\n", buffer); + } + + /* If we could open it, then read the settings and close it */ + if (prefFile) + { + parse_file (prefFile); + fclose (prefFile); + } + + /* Setup a DISPLAY environment variable, need to allocate on heap */ + /* because putenv doesn't copy the argument... */ + snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display); + szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1)); + if (szEnvDisplay) + { + strcpy (szEnvDisplay, szDisplay); + putenv (szEnvDisplay); + } + + /* Replace any "%display%" in menu commands with display string */ + snprintf (szDisplay, 512, "127.0.0.1:%s.0", display); + for (i=0; i<pref.menuItems; i++) + { + for (j=0; j<pref.menu[i].menuItems; j++) + { + if (pref.menu[i].menuItem[j].cmd==CMD_EXEC) + { + srcParam = pref.menu[i].menuItem[j].param; + dstParam = param; + while (*srcParam) { + if (!strncmp(srcParam, "%display%", 9)) + { + memcpy (dstParam, szDisplay, strlen(szDisplay)); + dstParam += strlen(szDisplay); + srcParam += 9; + } + else + { + *dstParam = *srcParam; + dstParam++; + srcParam++; + } + } + *dstParam = 0; + strcpy (pref.menu[i].menuItem[j].param, param); + } /* cmd==cmd_exec */ + } /* for all menuitems */ + } /* for all menus */ + +} diff --git a/hw/xwin/winprefs.h b/hw/xwin/winprefs.h new file mode 100644 index 000000000..d9e09deea --- /dev/null +++ b/hw/xwin/winprefs.h @@ -0,0 +1,162 @@ +#if !defined(WINPREFS_H) +#define WINPREFS_H +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +/* Need Bool */ +#include <X11/Xdefs.h> +/* Need TRUE */ +#include "misc.h" + +/* Need to know how long paths can be... */ +#include <limits.h> +/* Xwindows redefines PATH_MAX to at least 1024 */ +#include <X11/Xwindows.h> + +#ifndef NAME_MAX +#define NAME_MAX PATH_MAX +#endif +#define MENU_MAX 128 /* Maximum string length of a menu name or item */ +#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */ + + +/* Supported commands in a MENU {} statement */ +typedef enum MENUCOMMANDTYPE +{ + CMD_EXEC, /* /bin/sh -c the parameter */ + CMD_MENU, /* Display a popup menu named param */ + CMD_SEPARATOR, /* Menu separator */ + CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ + CMD_RELOAD /* Reparse the .XWINRC file */ +} MENUCOMMANDTYPE; + +/* Where to place a system menu */ +typedef enum MENUPOSITION +{ + AT_START, /* Place menu at the top of the system menu */ + AT_END /* Put it at the bottom of the menu (default) */ +} MENUPOSITION; + +/* Menu item definitions */ +typedef struct MENUITEM +{ + char text[MENU_MAX+1]; /* To be displayed in menu */ + MENUCOMMANDTYPE cmd; /* What should it do? */ + char param[PARAM_MAX+1]; /* Any parameters? */ + unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ +} MENUITEM; + +/* A completely read in menu... */ +typedef struct MENUPARSED +{ + char menuName[MENU_MAX+1]; /* What's it called in the text? */ + MENUITEM *menuItem; /* Array of items */ + int menuItems; /* How big's the array? */ +} MENUPARSED; + +/* To map between a window and a system menu to add for it */ +typedef struct SYSMENUITEM +{ + char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ + char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ + MENUPOSITION menuPos; /* Where to place it (ignored in root) */ +} SYSMENUITEM; + +/* To redefine icons for certain window types */ +typedef struct ICONITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ + unsigned long hicon; /* LoadImage() result */ +} ICONITEM; + +typedef struct 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; + + /* 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); + +unsigned long +winOverrideIcon (unsigned long longpWin); + +unsigned long +winTaskbarIcon(void); + +unsigned long +winOverrideDefaultIcon(int size); +#endif diff --git a/hw/xwin/winprefslex.l b/hw/xwin/winprefslex.l new file mode 100644 index 000000000..a4c1abc3d --- /dev/null +++ b/hw/xwin/winprefslex.l @@ -0,0 +1,116 @@ +%{ # -*- C -*- +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ +/* $XFree86: $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "winprefsyacc.h" + +extern YYSTYPE yylval; +extern char *yytext; +extern int yyparse(void); + +extern void ErrorF (const char* /*f*/, ...); + +int yylineno; + +/* Copy the parsed string, must be free()d in yacc parser */ +static char *makestr(char *str) +{ + char *ptr; + ptr = (char*)malloc (strlen(str)+1); + if (!ptr) + { + ErrorF ("winMultiWindowLex:makestr() out of memory\n"); + exit (-1); + } + strcpy(ptr, str); + return ptr; +} + +%} + +%option yylineno + +%% +\#.*[\r\n] { /* comment */ return NEWLINE; } +\/\/.*[\r\n] { /* comment */ return NEWLINE; } +[\r\n] { return NEWLINE; } +[ \t]+ { /* ignore whitespace */ } +MENU { return MENU; } +ICONDIRECTORY { return ICONDIRECTORY; } +DEFAULTICON { return DEFAULTICON; } +ICONS { return ICONS; } +ROOTMENU { return ROOTMENU; } +DEFAULTSYSMENU { return DEFAULTSYSMENU; } +SYSMENU { return SYSMENU; } +SEPARATOR { return SEPARATOR; } +ATSTART { return ATSTART; } +ATEND { return ATEND; } +EXEC { return EXEC; } +ALWAYSONTOP { return ALWAYSONTOP; } +DEBUG { return DEBUG; } +RELOAD { return RELOAD; } +TRAYICON { return TRAYICON; } +SILENTEXIT { return SILENTEXIT; } +"{" { return LB; } +"}" { return RB; } +"\""[^\"\r\n]+"\"" { yylval.sVal = makestr(yytext+1); \ + yylval.sVal[strlen(yylval.sVal)-1] = 0; \ + return STRING; } +[^ \t\r\n]+ { yylval.sVal = makestr(yytext); \ + return STRING; } +%% + +/* + * Run-of-the mill requirement for yacc + */ +int +yywrap () +{ + return 1; +} + +/* + * Run a file through the yacc parser + */ +void +parse_file (FILE *file) +{ + if (!file) + return; + + yylineno = 1; + yyin = file; + yyparse (); +} + diff --git a/hw/xwin/winprefsyacc.y b/hw/xwin/winprefsyacc.y new file mode 100644 index 000000000..2a54ff28f --- /dev/null +++ b/hw/xwin/winprefsyacc.y @@ -0,0 +1,353 @@ +%{ +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ +/* $XFree86: $ */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "winprefs.h" + +/* The following give better error messages in bison at the cost of a few KB */ +#define YYERROR_VERBOSE 1 + +/* The global pref settings */ +WINPREFS pref; + +/* The working menu */ +static MENUPARSED menu; + +/* Functions for parsing the tokens into out structure */ +/* Defined at the end section of this file */ + +static void SetIconDirectory (char *path); +static void SetDefaultIcon (char *fname); +static void SetRootMenu (char *menu); +static void SetDefaultSysMenu (char *menu, int pos); +static void SetTrayIcon (char *fname); + +static void OpenMenu(char *menuname); +static void AddMenuLine(char *name, MENUCOMMANDTYPE cmd, char *param); +static void CloseMenu(void); + +static void OpenIcons(void); +static void AddIconLine(char *matchstr, char *iconfile); +static void CloseIcons(void); + +static void OpenSysMenu(void); +static void AddSysMenuLine(char *matchstr, char *menuname, int pos); +static void CloseSysMenu(void); + +static int yyerror (char *s); + +extern void ErrorF (const char* /*f*/, ...); +extern char *yytext; +extern int yylex(void); + +%} + +%union { + char *sVal; + int iVal; +} + +%token NEWLINE MENU LB RB ICONDIRECTORY DEFAULTICON ICONS DEFAULTSYSMENU +%token SYSMENU ROOTMENU SEPARATOR ATSTART ATEND EXEC ALWAYSONTOP DEBUG +%token RELOAD TRAYICON SILENTEXIT + +%token <sVal> STRING +%type <iVal> atspot + +%% + +input: /* empty */ + | input line + ; + +line: NEWLINE + | command + ; + + +newline_or_nada: + | NEWLINE newline_or_nada + ; + +command: defaulticon + | icondirectory + | menu + | icons + | sysmenu + | rootmenu + | defaultsysmenu + | debug + | trayicon + | silentexit + ; + +trayicon: TRAYICON STRING NEWLINE { SetTrayIcon($2); free($2); } + ; + +rootmenu: ROOTMENU STRING NEWLINE { SetRootMenu($2); free($2); } + ; + +defaultsysmenu: DEFAULTSYSMENU STRING atspot NEWLINE { SetDefaultSysMenu($2, $3); free($2); } + ; + +defaulticon: DEFAULTICON STRING NEWLINE { SetDefaultIcon($2); free($2); } + ; + +icondirectory: ICONDIRECTORY STRING NEWLINE { SetIconDirectory($2); free($2); } + ; + +menuline: SEPARATOR NEWLINE newline_or_nada { AddMenuLine("-", CMD_SEPARATOR, ""); } + | STRING ALWAYSONTOP NEWLINE newline_or_nada { AddMenuLine($1, CMD_ALWAYSONTOP, ""); free($1); } + | STRING EXEC STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_EXEC, $3); free($1); free($3); } + | STRING MENU STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_MENU, $3); free($1); free($3); } + | STRING RELOAD NEWLINE newline_or_nada { AddMenuLine($1, CMD_RELOAD, ""); free($1); } + ; + +menulist: menuline + | menuline menulist + ; + +menu: MENU STRING LB { OpenMenu($2); free($2); } newline_or_nada menulist RB {CloseMenu();} + ; + +iconline: STRING STRING NEWLINE newline_or_nada { AddIconLine($1, $2); free($1); free($2); } + ; + +iconlist: iconline + | iconline iconlist + ; + +icons: ICONS LB {OpenIcons();} newline_or_nada iconlist RB {CloseIcons();} + ; + +atspot: { $$=AT_END; } + | ATSTART { $$=AT_START; } + | ATEND { $$=AT_END; } + ; + +sysmenuline: STRING STRING atspot NEWLINE newline_or_nada { AddSysMenuLine($1, $2, $3); free($1); free($2); } + ; + +sysmenulist: sysmenuline + | sysmenuline sysmenulist + ; + +sysmenu: SYSMENU LB NEWLINE {OpenSysMenu();} newline_or_nada sysmenulist RB {CloseSysMenu();} + ; + +silentexit: SILENTEXIT NEWLINE { pref.fSilentExit = TRUE; } + ; + +debug: DEBUG STRING NEWLINE { ErrorF("LoadPreferences: %s\n", $2); free($2); } + ; + + +%% +/* + * Errors in parsing abort and print log messages + */ +static int +yyerror (char *s) +{ + extern int yylineno; /* Handled by flex internally */ + + ErrorF("LoadPreferences: %s line %d\n", s, yylineno); + return 1; +} + +/* Miscellaneous functions to store TOKENs into the structure */ +static void +SetIconDirectory (char *path) +{ + strncpy (pref.iconDirectory, path, PATH_MAX); + pref.iconDirectory[PATH_MAX] = 0; +} + +static void +SetDefaultIcon (char *fname) +{ + strncpy (pref.defaultIconName, fname, NAME_MAX); + pref.defaultIconName[NAME_MAX] = 0; +} + +static void +SetTrayIcon (char *fname) +{ + strncpy (pref.trayIconName, fname, NAME_MAX); + pref.trayIconName[NAME_MAX] = 0; +} + +static void +SetRootMenu (char *menu) +{ + strncpy (pref.rootMenuName, menu, MENU_MAX); + pref.rootMenuName[MENU_MAX] = 0; +} + +static void +SetDefaultSysMenu (char *menu, int pos) +{ + strncpy (pref.defaultSysMenuName, menu, MENU_MAX); + pref.defaultSysMenuName[MENU_MAX] = 0; + pref.defaultSysMenuPos = pos; +} + +static void +OpenMenu (char *menuname) +{ + if (menu.menuItem) free(menu.menuItem); + menu.menuItem = NULL; + strncpy(menu.menuName, menuname, MENU_MAX); + menu.menuName[MENU_MAX] = 0; + menu.menuItems = 0; +} + +static void +AddMenuLine (char *text, MENUCOMMANDTYPE cmd, char *param) +{ + if (menu.menuItem==NULL) + menu.menuItem = (MENUITEM*)malloc(sizeof(MENUITEM)); + else + menu.menuItem = (MENUITEM*) + realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1)); + + strncpy (menu.menuItem[menu.menuItems].text, text, MENU_MAX); + menu.menuItem[menu.menuItems].text[MENU_MAX] = 0; + + menu.menuItem[menu.menuItems].cmd = cmd; + + strncpy(menu.menuItem[menu.menuItems].param, param, PARAM_MAX); + menu.menuItem[menu.menuItems].param[PARAM_MAX] = 0; + + menu.menuItem[menu.menuItems].commandID = 0; + + menu.menuItems++; +} + +static void +CloseMenu (void) +{ + if (menu.menuItem==NULL || menu.menuItems==0) + { + ErrorF("LoadPreferences: Empty menu detected\n"); + return; + } + + if (pref.menuItems) + pref.menu = (MENUPARSED*) + realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED)); + else + pref.menu = (MENUPARSED*)malloc (sizeof(MENUPARSED)); + + memcpy (pref.menu+pref.menuItems, &menu, sizeof(MENUPARSED)); + pref.menuItems++; + + memset (&menu, 0, sizeof(MENUPARSED)); +} + +static void +OpenIcons (void) +{ + if (pref.icon != NULL) { + ErrorF("LoadPreferences: Redefining icon mappings\n"); + free(pref.icon); + pref.icon = NULL; + } + pref.iconItems = 0; +} + +static void +AddIconLine (char *matchstr, char *iconfile) +{ + if (pref.icon==NULL) + pref.icon = (ICONITEM*)malloc(sizeof(ICONITEM)); + else + pref.icon = (ICONITEM*) + realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1)); + + strncpy(pref.icon[pref.iconItems].match, matchstr, MENU_MAX); + pref.icon[pref.iconItems].match[MENU_MAX] = 0; + + strncpy(pref.icon[pref.iconItems].iconFile, iconfile, PATH_MAX+NAME_MAX+1); + pref.icon[pref.iconItems].iconFile[PATH_MAX+NAME_MAX+1] = 0; + + pref.icon[pref.iconItems].hicon = 0; + + pref.iconItems++; +} + +static void +CloseIcons (void) +{ +} + +static void +OpenSysMenu (void) +{ + if (pref.sysMenu != NULL) { + ErrorF("LoadPreferences: Redefining system menu\n"); + free(pref.sysMenu); + pref.sysMenu = NULL; + } + pref.sysMenuItems = 0; +} + +static void +AddSysMenuLine (char *matchstr, char *menuname, int pos) +{ + if (pref.sysMenu==NULL) + pref.sysMenu = (SYSMENUITEM*)malloc(sizeof(SYSMENUITEM)); + else + pref.sysMenu = (SYSMENUITEM*) + realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1)); + + strncpy (pref.sysMenu[pref.sysMenuItems].match, matchstr, MENU_MAX); + pref.sysMenu[pref.sysMenuItems].match[MENU_MAX] = 0; + + strncpy (pref.sysMenu[pref.sysMenuItems].menuName, menuname, MENU_MAX); + pref.sysMenu[pref.sysMenuItems].menuName[MENU_MAX] = 0; + + pref.sysMenu[pref.sysMenuItems].menuPos = pos; + + pref.sysMenuItems++; +} + +static void +CloseSysMenu (void) +{ +} + diff --git a/hw/xwin/winpriv.c b/hw/xwin/winpriv.c new file mode 100644 index 000000000..29221cf2b --- /dev/null +++ b/hw/xwin/winpriv.c @@ -0,0 +1,134 @@ +/* + * Export window information for the Windows-OpenGL GLX implementation. + * + * Authors: Alexander Gottwald + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winpriv.h" +#include "winwindow.h" + +void +winCreateWindowsWindow (WindowPtr pWin); +/** + * Return size and handles of a window. + * If pWin is NULL, then the information for the root window is requested. + */ +extern void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo) +{ + /* Sanity check */ + if (pWinInfo == NULL) + return; + + winDebug("%s:%d pWin=%p\n", __FUNCTION__, __LINE__, pWin); + + /* a real window was requested */ + if (pWin != NULL) + { + /* Initialize the size information */ + RECT rect = { + pWin->drawable.x, + pWin->drawable.y, + pWin->drawable.x + pWin->drawable.width, + pWin->drawable.y + pWin->drawable.height + }, rect_extends; + /* Get the window and screen privates */ + ScreenPtr pScreen = pWin->drawable.pScreen; + winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); + winScreenInfoPtr pScreenInfo = NULL; + + rect_extends = rect; + OffsetRect(&rect_extends, -pWin->drawable.x, -pWin->drawable.y); + + if (pWinScreen == NULL) + { + ErrorF("winGetWindowInfo: screen has no privates\n"); + return; + } + + pWinInfo->hwnd = pWinScreen->hwndScreen; + pWinInfo->hrgn = NULL; + pWinInfo->rect = rect; + + + pScreenInfo = pWinScreen->pScreenInfo; +#ifdef XWIN_MULTIWINDOW + /* check for multiwindow mode */ + if (pScreenInfo->fMultiWindow) + { + winWindowPriv(pWin); + + if (pWinPriv == NULL) + { + ErrorF("winGetWindowInfo: window has no privates\n"); + return; + } + + if (pWinPriv->hWnd == NULL) + { + winCreateWindowsWindow(pWin); + } + if (pWinPriv->hWnd != NULL) { + + /* copy size and window handle */ + pWinInfo->rect = rect_extends; + pWinInfo->hwnd = pWinPriv->hWnd; + + /* Copy window region */ + if (pWinInfo->hrgn) + DeleteObject(pWinInfo->hrgn); + pWinInfo->hrgn = CreateRectRgn(0,0,0,0); + CombineRgn(pWinInfo->hrgn, pWinPriv->hRgn, pWinPriv->hRgn, + RGN_COPY); + } + + return; + } +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + /* check for multiwindow external wm mode */ + if (pScreenInfo->fMWExtWM) + { + win32RootlessWindowPtr pRLWinPriv + = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + + if (pRLWinPriv == NULL) { + ErrorF("winGetWindowInfo: window has no privates\n"); + return; + } + + if (pRLWinPriv->hWnd != NULL) + { + /* copy size and window handle */ + pWinInfo->rect = rect_extends; + pWinInfo->hwnd = pRLWinPriv->hWnd; + } + return; + } +#endif + } + else + { + RECT rect = {0, 0, 0, 0}; + ScreenPtr pScreen = g_ScreenInfo[0].pScreen; + winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); + + pWinInfo->hwnd = NULL; + pWinInfo->hrgn = NULL; + pWinInfo->rect = rect; + + if (pWinScreen == NULL) + { + ErrorF("winGetWindowInfo: screen has no privates\n"); + return; + } + + ErrorF("winGetWindowInfo: returning root window\n"); + + pWinInfo->hwnd = pWinScreen->hwndScreen; + } + return; +} diff --git a/hw/xwin/winpriv.h b/hw/xwin/winpriv.h new file mode 100644 index 000000000..d4505c83e --- /dev/null +++ b/hw/xwin/winpriv.h @@ -0,0 +1,15 @@ +/* + * Export window information for the Windows-OpenGL GLX implementation. + * + * Authors: Alexander Gottwald + */ +#include <windows.h> + +typedef struct +{ + HWND hwnd; + HRGN hrgn; + RECT rect; +} winWindowInfoRec, *winWindowInfoPtr; + +extern void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo); diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c new file mode 100755 index 000000000..7139cbaab --- /dev/null +++ b/hw/xwin/winprocarg.c @@ -0,0 +1,1551 @@ +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#ifdef XVENDORNAME +#define VENDOR_STRING XVENDORNAME +#define VERSION_STRING XORG_RELEASE +#define VENDOR_CONTACT BUILDERADDR +#endif +#include "win.h" +#include "winconfig.h" +#include "winprefs.h" +#include "winmsg.h" + +/* + * References to external symbols + */ + +extern int g_iNumScreens; +extern winScreenInfo g_ScreenInfo[]; +extern int g_iLastScreen; +extern Bool g_fInitializedDefaultScreens; +#ifdef XWIN_CLIPBOARD +extern Bool g_fUnicodeClipboard; +extern Bool g_fClipboard; +#endif +extern int g_iLogVerbose; +extern char * g_pszLogFile; +#ifdef RELOCATE_PROJECTROOT +extern Bool g_fLogFileChanged; +#endif +extern Bool g_fXdmcpEnabled; +extern char * g_pszCommandLine; +extern Bool g_fKeyboardHookLL; +extern Bool g_fNoHelpMessageBox; +extern Bool g_fSoftwareCursor; +extern Bool g_fSilentDupError; + +/* 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 + +void +winInitializeDefaultScreens (void); + +/* + * Process arguments on the command line + */ + +void +winInitializeDefaultScreens (void) +{ + int i; + DWORD dwWidth, dwHeight; + + /* Bail out early if default screens have already been initialized */ + if (g_fInitializedDefaultScreens) + return; + + /* Zero the memory used for storing the screen info */ + ZeroMemory (g_ScreenInfo, MAXSCREENS * 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, "winInitializeDefaultScreens - 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; + + for (i = 0; i < MAXSCREENS; ++i) + { + g_ScreenInfo[i].dwScreen = i; + g_ScreenInfo[i].dwWidth = dwWidth; + g_ScreenInfo[i].dwHeight = dwHeight; + g_ScreenInfo[i].dwUserWidth = dwWidth; + g_ScreenInfo[i].dwUserHeight = dwHeight; + g_ScreenInfo[i].fUserGaveHeightAndWidth + = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH; + g_ScreenInfo[i].fUserGavePosition = FALSE; + g_ScreenInfo[i].dwBPP = WIN_DEFAULT_BPP; + g_ScreenInfo[i].dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES; +#ifdef XWIN_EMULATEPSEUDO + g_ScreenInfo[i].fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO; +#endif + g_ScreenInfo[i].dwRefreshRate = WIN_DEFAULT_REFRESH; + g_ScreenInfo[i].pfb = NULL; + g_ScreenInfo[i].fFullScreen = FALSE; + g_ScreenInfo[i].fDecoration = TRUE; +#ifdef XWIN_MULTIWINDOWEXTWM + g_ScreenInfo[i].fMWExtWM = FALSE; + g_ScreenInfo[i].fInternalWM = FALSE; +#endif + g_ScreenInfo[i].fRootless = FALSE; +#ifdef XWIN_MULTIWINDOW + g_ScreenInfo[i].fMultiWindow = FALSE; +#endif +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + g_ScreenInfo[i].fMultiMonitorOverride = FALSE; +#endif + g_ScreenInfo[i].fMultipleMonitors = FALSE; + g_ScreenInfo[i].fLessPointer = FALSE; + g_ScreenInfo[i].fScrollbars = FALSE; + g_ScreenInfo[i].fNoTrayIcon = FALSE; + g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF; + g_ScreenInfo[i].dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) + * 25.4; + g_ScreenInfo[i].dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) + * 25.4; + g_ScreenInfo[i].fUseWinKillKey = WIN_DEFAULT_WIN_KILL; + g_ScreenInfo[i].fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL; + g_ScreenInfo[i].fIgnoreInput = FALSE; + g_ScreenInfo[i].fExplicitScreen = FALSE; + } + + /* Signal that the default screens have been initialized */ + g_fInitializedDefaultScreens = TRUE; + + winErrorFVerb (2, "winInitializeDefaultScreens - Returning\n"); +} + +/* 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; + + /* 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"); + winInitializeDefaultScreens (); + } + } + +#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 || nScreenNum >= MAXSCREENS) + { + ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n", + nScreenNum); + UseMsg (); + return 0; + } + + /* 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. + */ + g_iLastScreen = nScreenNum; + + /* Keep a count of the number of screens */ + ++g_iNumScreens; + + return iArgsProcessed; + } + + /* + * 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; + } + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwEnginePreferred = dwEngine; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].dwEnginePreferred = dwEngine; + } + + /* Indicate that we have processed the argument */ + return 2; + } + + /* + * Look for the '-fullscreen' argument + */ + if (IS_OPTION ("-fullscreen")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[j].fMultiMonitorOverride) + g_ScreenInfo[j].fMultipleMonitors = FALSE; +#endif + g_ScreenInfo[j].fFullScreen = TRUE; + } + } + else + { + /* Parameter is for a single screen */ +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; +#endif + g_ScreenInfo[g_iLastScreen].fFullScreen = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-lesspointer' argument + */ + if (IS_OPTION ("-lesspointer")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fLessPointer = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fLessPointer = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nodecoration' argument + */ + if (IS_OPTION ("-nodecoration")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[j].fMultiMonitorOverride) + g_ScreenInfo[j].fMultipleMonitors = FALSE; +#endif + g_ScreenInfo[j].fDecoration = FALSE; + } + } + else + { + /* Parameter is for a single screen */ +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; +#endif + g_ScreenInfo[g_iLastScreen].fDecoration = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + +#ifdef XWIN_MULTIWINDOWEXTWM + /* + * Look for the '-mwextwm' argument + */ + if (IS_OPTION ("-mwextwm")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + if (!g_ScreenInfo[j].fMultiMonitorOverride) + g_ScreenInfo[j].fMultipleMonitors = TRUE; + g_ScreenInfo[j].fMWExtWM = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; + g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + /* + * Look for the '-internalwm' argument + */ + if (IS_OPTION ("-internalwm")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + if (!g_ScreenInfo[j].fMultiMonitorOverride) + g_ScreenInfo[j].fMultipleMonitors = TRUE; + g_ScreenInfo[j].fMWExtWM = TRUE; + g_ScreenInfo[j].fInternalWM = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; + g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE; + g_ScreenInfo[g_iLastScreen].fInternalWM = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + /* + * Look for the '-rootless' argument + */ + if (IS_OPTION ("-rootless")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[j].fMultiMonitorOverride) + g_ScreenInfo[j].fMultipleMonitors = FALSE; +#endif + g_ScreenInfo[j].fRootless = TRUE; + } + } + else + { + /* Parameter is for a single screen */ +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; +#endif + g_ScreenInfo[g_iLastScreen].fRootless = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + +#ifdef XWIN_MULTIWINDOW + /* + * Look for the '-multiwindow' argument + */ + if (IS_OPTION ("-multiwindow")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[j].fMultiMonitorOverride) + g_ScreenInfo[j].fMultipleMonitors = TRUE; +#endif + g_ScreenInfo[j].fMultiWindow = TRUE; + } + } + else + { + /* Parameter is for a single screen */ +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; +#endif + g_ScreenInfo[g_iLastScreen].fMultiWindow = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + /* + * Look for the '-multiplemonitors' argument + */ + if (IS_OPTION ("-multiplemonitors") + || IS_OPTION ("-multimonitors")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + g_ScreenInfo[j].fMultiMonitorOverride = TRUE; +#endif + g_ScreenInfo[j].fMultipleMonitors = TRUE; + } + } + else + { + /* Parameter is for a single screen */ +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE; +#endif + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nomultiplemonitors' argument + */ + if (IS_OPTION ("-nomultiplemonitors") + || IS_OPTION ("-nomultimonitors")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + g_ScreenInfo[j].fMultiMonitorOverride = TRUE; +#endif + g_ScreenInfo[j].fMultipleMonitors = FALSE; + } + } + else + { + /* Parameter is for a single screen */ +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE; +#endif + g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + + /* + * Look for the '-scrollbars' argument + */ + if (IS_OPTION ("-scrollbars")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fScrollbars = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fScrollbars = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + +#ifdef XWIN_CLIPBOARD + /* + * Look for the '-clipboard' argument + */ + if (IS_OPTION ("-clipboard")) + { + g_fClipboard = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + + /* + * Look for the '-ignoreinput' argument + */ + if (IS_OPTION ("-ignoreinput")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fIgnoreInput = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].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; + } + + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].iE3BTimeout = iE3BTimeout; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].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]); + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwBPP = dwBPP; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].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]); + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwRefreshRate = dwRefreshRate; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].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]); + + /* Is this parameter attached to a screen or global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].dwClipUpdatesNBoxes = dwNumBoxes; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].dwClipUpdatesNBoxes = dwNumBoxes; + } + + /* Indicate that we have processed the argument */ + return 2; + } + +#ifdef XWIN_EMULATEPSEUDO + /* + * Look for the '-emulatepseudo' argument + */ + if (IS_OPTION ("-emulatepseudo")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fEmulatePseudo = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fEmulatePseudo = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } +#endif + + /* + * Look for the '-nowinkill' argument + */ + if (IS_OPTION ("-nowinkill")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseWinKillKey = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseWinKillKey = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-winkill' argument + */ + if (IS_OPTION ("-winkill")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseWinKillKey = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseWinKillKey = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-nounixkill' argument + */ + if (IS_OPTION ("-nounixkill")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseUnixKillKey = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-unixkill' argument + */ + if (IS_OPTION ("-unixkill")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fUseUnixKillKey = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-notrayicon' argument + */ + if (IS_OPTION ("-notrayicon")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fNoTrayIcon = TRUE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fNoTrayIcon = TRUE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-trayicon' argument + */ + if (IS_OPTION ("-trayicon")) + { + /* Is this parameter attached to a screen or is it global? */ + if (-1 == g_iLastScreen) + { + int j; + + /* Parameter is for all screens */ + for (j = 0; j < MAXSCREENS; j++) + { + g_ScreenInfo[j].fNoTrayIcon = FALSE; + } + } + else + { + /* Parameter is for a single screen */ + g_ScreenInfo[g_iLastScreen].fNoTrayIcon = FALSE; + } + + /* Indicate that we have processed this argument */ + return 1; + } + + /* + * Look for the '-fp' argument + */ + if (IS_OPTION ("-fp")) + { + 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 '-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 '-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 + +#ifdef XKB + /* + * Look for the '-kb' argument + */ + if (IS_OPTION ("-kb")) + { + g_cmdline.noXkbExtension = TRUE; + return 0; /* Let DIX parse this again */ + } + + 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; + } +#endif + + 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; + } + 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]) + { + /* 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; + ++iSize; + } + + /* 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: %s\n\n", VERSION_STRING); + ErrorF ("Contact: %s\n\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> + 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/hw/xwin/winpushpxl.c b/hw/xwin/winpushpxl.c new file mode 100644 index 000000000..72ef2d559 --- /dev/null +++ b/hw/xwin/winpushpxl.c @@ -0,0 +1,225 @@ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <X11/X.h> +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "miscstruct.h" +#include "../mfb/maskbits.h" +#include "mi.h" + +#define NPT 128 + +/* winPushPixels -- squeegees the fill style of pGC through pBitMap + * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may + * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit + * is set in the bitmap, the fill style is put onto the drawable using + * the GC's logical function. The drawable is not changed where the bitmap + * has a zero bit or outside the area covered by the stencil. + +WARNING: + this code works if the 1-bit deep pixmap format returned by GetSpans +is the same as the format defined by the mfb code (i.e. 32-bit padding +per scanline, scanline unit = 32 bits; later, this might mean +bitsizeof(int) padding and sacnline unit == bitsizeof(int).) + + */ + +/* + * in order to have both (MSB_FIRST and LSB_FIRST) versions of this + * in the server, we need to rename one of them + */ +void +winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, + int dx, int dy, int xOrg, int yOrg) +{ + int h, dxDivPPW, ibEnd; + MiBits *pwLineStart; + register MiBits *pw, *pwEnd; + register MiBits msk; + register int ib, w; + register int ipt; /* index into above arrays */ + Bool fInBox; + DDXPointRec pt[NPT], ptThisLine; + int width[NPT]; + PixelType startmask; + + + startmask = (MiBits)(-1) ^ + LONG2CHARSDIFFORDER((MiBits)(-1) >> 1); + + pwLineStart = (MiBits *)xalloc(BitmapBytePad(dx)); + if (!pwLineStart) + return; + ipt = 0; + dxDivPPW = dx/PPW; + + for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0; + h < dy; + h++, ptThisLine.y++) + { + + (*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx, + &ptThisLine, &dx, 1, (char *)pwLineStart); + + pw = pwLineStart; + /* Process all words which are fully in the pixmap */ + + fInBox = FALSE; + pwEnd = pwLineStart + dxDivPPW; + while(pw < pwEnd) + { + w = *pw; +#ifdef XFree86Server + msk = startmask; +#else + msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1); +#endif + for(ib = 0; ib < PPW; ib++) + { + if(w & msk) + { + if(!fInBox) + { + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + /* start new box */ + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) + { + (*pGC->ops->FillSpans)(pDrawable, pGC, + NPT, pt, width, TRUE); + ipt = 0; + } + /* end box */ + fInBox = FALSE; + } + } +#ifdef XFree86Server + /* This is not quite right, but it'll do for now */ + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); +#else + msk = SCRRIGHT(msk, 1); +#endif + } + pw++; + } + ibEnd = dx & PIM; + if(ibEnd) + { + /* Process final partial word on line */ + w = *pw; +#ifdef XFree86Server + msk = startmask; +#else + msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1); +#endif + for(ib = 0; ib < ibEnd; ib++) + { + if(w & msk) + { + if(!fInBox) + { + /* start new box */ + pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; + pt[ipt].y = h + yOrg; + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + /* end box */ + width[ipt] = ((pw - pwLineStart) << PWSH) + + ib + xOrg - pt[ipt].x; + if (++ipt >= NPT) + { + (*pGC->ops->FillSpans)(pDrawable, + pGC, NPT, pt, width, TRUE); + ipt = 0; + } + fInBox = FALSE; + } + } +#ifdef XFree86Server + /* This is not quite right, but it'll do for now */ + msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); +#else + msk = SCRRIGHT(msk, 1); +#endif + } + } + /* If scanline ended with last bit set, end the box */ + if(fInBox) + { + width[ipt] = dx + xOrg - pt[ipt].x; + if (++ipt >= NPT) + { + (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE); + ipt = 0; + } + } + } + xfree(pwLineStart); + /* Flush any remaining spans */ + if (ipt) + { + (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE); + } +} diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c new file mode 100755 index 000000000..7b5b1359c --- /dev/null +++ b/hw/xwin/winrandr.c @@ -0,0 +1,141 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + + +/* + * Local prototypes + */ + +static Bool +winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations); + +static Bool +winRandRSetConfig (ScreenPtr pScreen, + Rotation rotateKind, + int rate, + RRScreenSizePtr pSize); + +Bool +winRandRInit (ScreenPtr pScreen); + + +/* + * Answer queries about the RandR features supported. + */ + +static Bool +winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + int n; + Rotation rotateKind; + RRScreenSizePtr pSize; + + winDebug ("winRandRGetInfo ()\n"); + + /* Don't support rotations, yet */ + *pRotations = RR_Rotate_0; + + /* Bail if no depth has a visual associated with it */ + for (n = 0; n < pScreen->numDepths; n++) + if (pScreen->allowedDepths[n].numVids) + break; + if (n == pScreen->numDepths) + return FALSE; + + /* Only one allowed rotation for now */ + rotateKind = RR_Rotate_0; + + /* + * Register supported sizes. This can be called many times, but + * we only support one size for now. + */ + pSize = RRRegisterSize (pScreen, + pScreenInfo->dwWidth, + pScreenInfo->dwHeight, + pScreenInfo->dwWidth_mm, + pScreenInfo->dwHeight_mm); + + /* Tell RandR what the current config is */ + RRSetCurrentConfig (pScreen, + rotateKind, + 0, /* refresh rate, not needed */ + pSize); + + return TRUE; +} + + +/* + * Respond to resize/rotate request from either X Server or X client app + */ + +static Bool +winRandRSetConfig (ScreenPtr pScreen, + Rotation rotateKind, + int rate, + RRScreenSizePtr pSize) +{ + winDebug ("winRandRSetConfig ()\n"); + + return TRUE; +} + + +/* + * Initialize the RandR layer. + */ + +Bool +winRandRInit (ScreenPtr pScreen) +{ + rrScrPrivPtr pRRScrPriv; + + winDebug ("winRandRInit ()\n"); + + if (!RRScreenInit (pScreen)) + { + ErrorF ("winRandRInit () - RRScreenInit () failed\n"); + return FALSE; + } + + /* Set some RandR function pointers */ + pRRScrPriv = rrGetScrPriv (pScreen); + pRRScrPriv->rrGetInfo = winRandRGetInfo; + pRRScrPriv->rrSetConfig = winRandRSetConfig; + + return TRUE; +} diff --git a/hw/xwin/winregistry.c b/hw/xwin/winregistry.c new file mode 100644 index 000000000..3571b14d7 --- /dev/null +++ b/hw/xwin/winregistry.c @@ -0,0 +1,71 @@ +/* + *Copyright (C) 2002-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + +/* Prototypes */ +DWORD +winGetRegistryDWORD (HKEY hkey, char *pszRegistryKey); + +DWORD +winGetRegistryDWORD (HKEY hkey, char *pszRegistryKey) +{ + HKEY hkResult; + DWORD dwDisposition; + + RegCreateKeyEx (hkey, + pszRegistryKey, + 0, + '\0', + REG_OPTION_NON_VOLATILE, + KEY_READ, + NULL, + &hkResult, + &dwDisposition); + + if (dwDisposition == REG_CREATED_NEW_KEY) + { + ErrorF ("winGetRegistryDWORD - Created new key: %s\n", pszRegistryKey); + } + else if (dwDisposition == REG_OPENED_EXISTING_KEY) + { + ErrorF ("winGetRegistryDWORD - Opened existing key: %s\n", + pszRegistryKey); + } + + /* Free the registry key handle */ + RegCloseKey (hkResult); + hkResult = NULL; + + return 0; +} diff --git a/hw/xwin/winresource.h b/hw/xwin/winresource.h new file mode 100644 index 000000000..5aa884030 --- /dev/null +++ b/hw/xwin/winresource.h @@ -0,0 +1,55 @@ +#if !defined(WINRESOURCE_H) +#define WINRESOURCE_H +/* + *Copyright (C) 2002-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 + */ + + +/* + * Local defines + */ + +#define IDC_STATIC -1 +#define IDI_XWIN 101 +#define IDI_XWIN_BOXED 102 +#define IDM_TRAYICON_MENU 103 +#define IDC_CLIENTS_CONNECTED 104 + + +#define ID_APP_EXIT 200 +#define ID_APP_HIDE_ROOT 201 +#define ID_APP_ALWAYS_ON_TOP 202 +#define ID_APP_ABOUT 203 + +#define ID_ABOUT_UG 300 +#define ID_ABOUT_FAQ 301 +#define ID_ABOUT_CHANGELOG 302 +#define ID_ABOUT_WEBSITE 303 + +#endif diff --git a/hw/xwin/winrop.c b/hw/xwin/winrop.c new file mode 100644 index 000000000..f4818920a --- /dev/null +++ b/hw/xwin/winrop.c @@ -0,0 +1,144 @@ +/* + *Copyright (C) 1994-2002 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +/* + * Raster operations used by Windows translated to X's 16 rop codes... + */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + +void +ROP16 (HDC hdc, int rop); + +int g_copyROP[16] = { 0xFF0062, /* GXclear - 0 */ + 0x8800C6, /* GXand - S & D */ + 0x440328, /* GXandReverse - S & !D */ + 0xCC0020, /* GXcopy - S */ + 0x220326, /* GXandInverted - !S & D */ + 0xAA0029, /* GXnoop - D */ + 0x660046, /* GXxor - S ^ D */ + 0xEE0086, /* GXor - S | D */ + 0x1100A6, /* GXnor - !S & !D */ + 0x990126, /* GXequiv - !S ^ D */ + 0x550009, /* GXinvert - !D */ + 0xDD0228, /* GXorReverse - S | !D */ + 0x330008, /* GXcopyInverted - !S */ + 0xBB0226, /* GXorInverted - !S | D */ + 0x7700C6, /* GXnand - !S | !D */ + 0x000042 /* GXset - 1 */ +}; + +int g_patternROP[16] = {0xFF0062, /* GXclear - 0 */ + 0xA000C9, /* GXand - P & D */ + 0xF50225, /* GXandReverse - P & !D */ + 0xF00021, /* GXcopy - P */ + 0x5F00E9, /* GXandInverted - !P & D */ + 0xAA0029, /* GXnoop - D */ + 0xA50065, /* GXxor - P ^ D */ + 0xA000C9, /* GXor - P | D */ + 0x5F00E9, /* GXnor - !P & !D */ + 0x5A0049, /* GXequiv - !P ^ D */ + 0x550009, /* GXinvert - !D */ + 0x500325, /* GXorReverse - P | !D */ + 0x0F0001, /* GXcopyInverted - !P */ + 0x0A0329, /* GXorInverted - !P | D */ + 0x0500A9, /* GXnand - !P | !D */ + 0x000042 /* GXset - 1 */ +}; + + +void +ROP16 (HDC hdc, int rop) +{ + switch (rop) + { + case GXclear: + SetROP2 (hdc, R2_BLACK); + break; + + case GXand: + SetROP2 (hdc, R2_MASKPEN); + break; + + case GXandReverse: + SetROP2 (hdc, R2_MASKPENNOT); + break; + + case GXcopy: + SetROP2 (hdc, R2_COPYPEN); + break; + + case GXnoop: + SetROP2 (hdc, R2_NOP); + break; + + case GXxor: + SetROP2 (hdc, R2_XORPEN); + break; + + case GXor: + SetROP2 (hdc, R2_MERGEPEN); + break; + + case GXnor: + SetROP2 (hdc, R2_NOTMERGEPEN); + break; + + case GXequiv: + SetROP2 (hdc, R2_NOTXORPEN); + break; + + case GXinvert: + SetROP2 (hdc, R2_NOT); + break; + + case GXorReverse: + SetROP2 (hdc, R2_MERGEPENNOT); + break; + + case GXcopyInverted: + SetROP2 (hdc, R2_NOTCOPYPEN); + break; + + case GXorInverted: + SetROP2 (hdc, R2_MERGENOTPEN); + break; + + case GXnand: + SetROP2 (hdc, R2_NOTMASKPEN); + break; + + case GXset: + SetROP2 (hdc, R2_WHITE); + break; + } +} diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c new file mode 100644 index 000000000..9dc4c3da5 --- /dev/null +++ b/hw/xwin/winscrinit.c @@ -0,0 +1,781 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * Kensuke Matsuzaki + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winmsg.h" +#include "safeAlpha.h" + + +#ifdef XWIN_MULTIWINDOWEXTWM +static RootlessFrameProcsRec +winMWExtWMProcs = { + winMWExtWMCreateFrame, + winMWExtWMDestroyFrame, + + winMWExtWMMoveFrame, + winMWExtWMResizeFrame, + winMWExtWMRestackFrame, + winMWExtWMReshapeFrame, + winMWExtWMUnmapFrame, + + winMWExtWMStartDrawing, + winMWExtWMStopDrawing, + winMWExtWMUpdateRegion, +#ifndef ROOTLESS_TRACK_DAMAGE + winMWExtWMDamageRects, +#endif + winMWExtWMRootlessSwitchWindow, + NULL,//winWMExtWMDoReorderWindow, + + NULL,//winMWExtWMCopyBytes, + NULL,//winMWExtWMFillBytes, + NULL,//winMWExtWMCompositePixels, + winMWExtWMCopyWindow +}; +#endif + + +/* + * References to external symbols + */ + +extern Bool g_fSoftwareCursor; + + +/* + * Prototypes + */ + +Bool +winRandRInit (ScreenPtr pScreen); + + +/* + * Local functions + */ + +static Bool +winSaveScreen (ScreenPtr pScreen, int on); + + +/* + * Determine what type of screen we are initializing + * and call the appropriate procedure to intiailize + * that type of screen. + */ + +Bool +winScreenInit (int index, + ScreenPtr pScreen, + int argc, char **argv) +{ + winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; + winPrivScreenPtr pScreenPriv; + HDC hdc; + +#if CYGDEBUG || YES + winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n", + pScreenInfo->dwWidth, pScreenInfo->dwHeight); +#endif + + /* Allocate privates for this screen */ + if (!winAllocatePrivates (pScreen)) + { + ErrorF ("winScreenInit - Couldn't allocate screen privates\n"); + return FALSE; + } + + /* Get a pointer to the privates structure that was allocated */ + pScreenPriv = winGetScreenPriv (pScreen); + + /* Save a pointer to this screen in the screen info structure */ + pScreenInfo->pScreen = pScreen; + + /* Save a pointer to the screen info in the screen privates structure */ + /* This allows us to get back to the screen info from a screen pointer */ + pScreenPriv->pScreenInfo = pScreenInfo; + + /* + * Determine which engine to use. + * + * NOTE: This is done once per screen because each screen possibly has + * a preferred engine specified on the command line. + */ + if (!winSetEngine (pScreen)) + { + ErrorF ("winScreenInit - winSetEngine () failed\n"); + return FALSE; + } + + /* Adjust the video mode for our engine type */ + if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) + { + ErrorF ("winScreenInit - winAdjustVideoMode () failed\n"); + return FALSE; + } + + /* Check for supported display depth */ + if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) + { + ErrorF ("winScreenInit - Unsupported display depth: %d\n" \ + "Change your Windows display depth to 15, 16, 24, or 32 bits " + "per pixel.\n", + (int) pScreenInfo->dwBPP); + ErrorF ("winScreenInit - Supported depths: %08x\n", + WIN_SUPPORTED_BPPS); +#if WIN_CHECK_DEPTH + return FALSE; +#endif + } + + /* + * Check that all monitors have the same display depth if we are using + * multiple monitors + */ + if (pScreenInfo->fMultipleMonitors + && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT)) + { + ErrorF ("winScreenInit - Monitors do not all have same pixel format / " + "display depth.\n" + "Using primary display only.\n"); + pScreenInfo->fMultipleMonitors = FALSE; + } + + /* Create display window */ + if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) + { + ErrorF ("winScreenInit - pwinCreateBoundingWindow () " + "failed\n"); + return FALSE; + } + + /* Get a device context */ + hdc = GetDC (pScreenPriv->hwndScreen); + + /* Store the initial height, width, and depth of the display */ + /* Are we using multiple monitors? */ + if (pScreenInfo->fMultipleMonitors) + { + pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + + /* + * In this case, some of the defaults set in + * winInitializeDefaultScreens () are not correct ... + */ + if (!pScreenInfo->fUserGaveHeightAndWidth) + { + pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); + pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); + pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth / + WIN_DEFAULT_DPI) * 25.4; + pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight / + WIN_DEFAULT_DPI) * 25.4; + } + } + else + { + pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); + pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); + } + + /* Save the original bits per pixel */ + pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL); + + /* Release the device context */ + ReleaseDC (pScreenPriv->hwndScreen, hdc); + + /* Clear the visuals list */ + miClearVisualTypes (); + + /* Set the padded screen width */ + pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, + pScreenInfo->dwBPP); + + /* Call the engine dependent screen initialization procedure */ + if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) + { + ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); + return FALSE; + } + + if (!g_fSoftwareCursor) + winInitCursor(pScreen); + else + winErrorFVerb(2, "winScreenInit - Using software cursor\n"); + +#if CYGDEBUG || YES + winDebug ("winScreenInit - returning\n"); +#endif + + return TRUE; +} + + +/* See Porting Layer Definition - p. 20 */ +Bool +winFinishScreenInitFB (int index, + ScreenPtr pScreen, + int argc, char **argv) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + VisualPtr pVisual = NULL; + char *pbits = NULL; +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + int iReturn; +#endif + + /* Create framebuffer */ + if (!(*pScreenPriv->pwinAllocateFB) (pScreen)) + { + ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n"); + return FALSE; + } + + /* + * Grab the number of bits that are used to represent color in each pixel. + */ + if (pScreenInfo->dwBPP == 8) + pScreenInfo->dwDepth = 8; + else + pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask) + + winCountBits (pScreenPriv->dwGreenMask) + + winCountBits (pScreenPriv->dwBlueMask); + + winErrorFVerb (2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n", + (unsigned int) pScreenPriv->dwRedMask, + (unsigned int) pScreenPriv->dwGreenMask, + (unsigned int) pScreenPriv->dwBlueMask); + + /* Init visuals */ + if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) + { + ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n"); + return FALSE; + } + + /* Setup a local variable to point to the framebuffer */ + pbits = pScreenInfo->pfb; + + /* Apparently we need this for the render extension */ + miSetPixmapDepths (); + + /* Start fb initialization */ + if (!fbSetupScreen (pScreen, + pScreenInfo->pfb, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + monitorResolution, monitorResolution, + pScreenInfo->dwStride, + pScreenInfo->dwBPP)) + { + ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n"); + return FALSE; + } + + /* Override default colormap routines if visual class is dynamic */ + if (pScreenInfo->dwDepth == 8 + && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI + || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL + && pScreenInfo->fFullScreen) + || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + && pScreenInfo->fFullScreen))) + { + winSetColormapFunctions (pScreen); + + /* + * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its + * own colormap, as it cannot allocate 7 planes in the default + * colormap. Setting whitePixel to 1 allows Magic to get 7 + * planes in the default colormap, so it doesn't create its + * own colormap. This latter situation is highly desireable, + * as it keeps the Magic window viewable when switching to + * other X clients that use the default colormap. + */ + pScreen->blackPixel = 0; + pScreen->whitePixel = 1; + } + + /* Place our save screen function */ + pScreen->SaveScreen = winSaveScreen; + + /* Finish fb initialization */ + if (!fbFinishScreenInit (pScreen, + pScreenInfo->pfb, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + monitorResolution, monitorResolution, + pScreenInfo->dwStride, + pScreenInfo->dwBPP)) + { + ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n"); + return FALSE; + } + + /* Save a pointer to the root visual */ + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++); + pScreenPriv->pRootVisual = pVisual; + + /* + * Setup points to the block and wakeup handlers. Pass a pointer + * to the current screen as pWakeupdata. + */ + pScreen->BlockHandler = winBlockHandler; + pScreen->WakeupHandler = winWakeupHandler; + pScreen->blockData = pScreen; + pScreen->wakeupData = pScreen; + +#ifdef XWIN_MULTIWINDOWEXTWM + /* + * Setup acceleration for multi-window external window manager mode. + * To be compatible with the Damage extension, this must be done + * before calling miDCInitialize, which calls DamageSetup. + */ + if (pScreenInfo->fMWExtWM) + { + if (!RootlessAccelInit (pScreen)) + { + ErrorF ("winFinishScreenInitFB - RootlessAccelInit () failed\n"); + return FALSE; + } + } +#endif + +#ifdef RENDER + /* Render extension initialization, calls miPictureInit */ + if (!fbPictureInit (pScreen, NULL, 0)) + { + ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n"); + return FALSE; + } +#endif + +#ifdef RANDR + /* Initialize resize and rotate support */ + if (!winRandRInit (pScreen)) + { + ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n"); + return FALSE; + } +#endif + + /* + * Backing store support should reduce network traffic and increase + * performance. + */ + miInitializeBackingStore (pScreen); + + /* KDrive does miDCInitialize right after miInitializeBackingStore */ + /* Setup the cursor routines */ +#if CYGDEBUG + winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n"); +#endif + miDCInitialize (pScreen, &g_winPointerCursorFuncs); + + /* KDrive does winCreateDefColormap right after miDCInitialize */ + /* Create a default colormap */ +#if CYGDEBUG + winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n"); +#endif + if (!winCreateDefColormap (pScreen)) + { + ErrorF ("winFinishScreenInitFB - Could not create colormap\n"); + return FALSE; + } + + /* Initialize the shadow framebuffer layer */ + if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI + || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD + || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) +#ifdef XWIN_MULTIWINDOWEXTWM + && !pScreenInfo->fMWExtWM +#endif + ) + { +#if CYGDEBUG + winDebug ("winFinishScreenInitFB - Calling shadowInit ()\n"); +#endif + if (!shadowInit (pScreen, + pScreenPriv->pwinShadowUpdate, + NULL)) + { + ErrorF ("winFinishScreenInitFB - shadowInit () failed\n"); + return FALSE; + } + } + +#ifdef XWIN_MULTIWINDOWEXTWM + /* Handle multi-window external window manager mode */ + if (pScreenInfo->fMWExtWM) + { + winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n"); + + RootlessInit(pScreen, &winMWExtWMProcs); + + winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n"); + + rootless_CopyBytes_threshold = 0; + rootless_FillBytes_threshold = 0; + rootless_CompositePixels_threshold = 0; + /* FIXME: How many? Profiling needed? */ + rootless_CopyWindow_threshold = 1; + + winWindowsWMExtensionInit (); + } +#endif + + /* Handle rootless mode */ + if (pScreenInfo->fRootless) + { + /* Define the WRAP macro temporarily for local use */ +#define WRAP(a) \ + if (pScreen->a) { \ + pScreenPriv->a = pScreen->a; \ + } else { \ + ErrorF("null screen fn " #a "\n"); \ + pScreenPriv->a = NULL; \ + } + + /* Save a pointer to each lower-level window procedure */ + WRAP(CreateWindow); + WRAP(DestroyWindow); + WRAP(RealizeWindow); + WRAP(UnrealizeWindow); + WRAP(PositionWindow); + WRAP(ChangeWindowAttributes); +#ifdef SHAPE + WRAP(SetShape); +#endif + + /* Assign rootless window procedures to be top level procedures */ + pScreen->CreateWindow = winCreateWindowRootless; + pScreen->DestroyWindow = winDestroyWindowRootless; + pScreen->PositionWindow = winPositionWindowRootless; + /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/ + pScreen->RealizeWindow = winMapWindowRootless; + pScreen->UnrealizeWindow = winUnmapWindowRootless; +#ifdef SHAPE + pScreen->SetShape = winSetShapeRootless; +#endif + + /* Undefine the WRAP macro, as it is not needed elsewhere */ +#undef WRAP + } + + +#ifdef XWIN_MULTIWINDOW + /* Handle multi window mode */ + else if (pScreenInfo->fMultiWindow) + { + /* Define the WRAP macro temporarily for local use */ +#define WRAP(a) \ + if (pScreen->a) { \ + pScreenPriv->a = pScreen->a; \ + } else { \ + ErrorF("null screen fn " #a "\n"); \ + pScreenPriv->a = NULL; \ + } + + /* Save a pointer to each lower-level window procedure */ + WRAP(CreateWindow); + WRAP(DestroyWindow); + WRAP(RealizeWindow); + WRAP(UnrealizeWindow); + WRAP(PositionWindow); + WRAP(ChangeWindowAttributes); + WRAP(ReparentWindow); + WRAP(RestackWindow); + WRAP(ResizeWindow); + WRAP(MoveWindow); + WRAP(CopyWindow); +#ifdef SHAPE + WRAP(SetShape); +#endif + + /* Assign multi-window window procedures to be top level procedures */ + pScreen->CreateWindow = winCreateWindowMultiWindow; + pScreen->DestroyWindow = winDestroyWindowMultiWindow; + pScreen->PositionWindow = winPositionWindowMultiWindow; + /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/ + pScreen->RealizeWindow = winMapWindowMultiWindow; + pScreen->UnrealizeWindow = winUnmapWindowMultiWindow; + pScreen->ReparentWindow = winReparentWindowMultiWindow; + pScreen->RestackWindow = winRestackWindowMultiWindow; + pScreen->ResizeWindow = winResizeWindowMultiWindow; + pScreen->MoveWindow = winMoveWindowMultiWindow; + pScreen->CopyWindow = winCopyWindowMultiWindow; +#ifdef SHAPE + pScreen->SetShape = winSetShapeMultiWindow; +#endif + + /* Undefine the WRAP macro, as it is not needed elsewhere */ +#undef WRAP + } +#endif + + /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Create a mutex for modules in separate threads to wait for */ + iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL); + if (iReturn != 0) + { + ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n", + iReturn); + return FALSE; + } + + /* Own the mutex for modules in separate threads */ + iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted); + if (iReturn != 0) + { + ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n", + iReturn); + return FALSE; + } + + /* Set the ServerStarted flag to false */ + pScreenPriv->fServerStarted = FALSE; +#endif + +#ifdef XWIN_MULTIWINDOWEXTWM + pScreenPriv->fRestacking = FALSE; +#endif + +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + if (FALSE +#ifdef XWIN_MULTIWINDOW + || pScreenInfo->fMultiWindow +#endif +#ifdef XWIN_MULTIWINDOWEXTWM + || pScreenInfo->fInternalWM +#endif + ) + { +#if CYGDEBUG || YES + winDebug ("winFinishScreenInitFB - Calling winInitWM.\n"); +#endif + + /* Initialize multi window mode */ + if (!winInitWM (&pScreenPriv->pWMInfo, + &pScreenPriv->ptWMProc, + &pScreenPriv->ptXMsgProc, + &pScreenPriv->pmServerStarted, + pScreenInfo->dwScreen, + (HWND)&pScreenPriv->hwndScreen, +#ifdef XWIN_MULTIWINDOWEXTWM + pScreenInfo->fInternalWM || +#endif + FALSE)) + { + ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n"); + return FALSE; + } + } +#endif + + /* Tell the server that we are enabled */ + pScreenPriv->fEnabled = TRUE; + + /* Tell the server that we have a valid depth */ + pScreenPriv->fBadDepth = FALSE; + +#if CYGDEBUG || YES + winDebug ("winFinishScreenInitFB - returning\n"); +#endif + + return TRUE; +} + +#ifdef XWIN_NATIVEGDI +/* See Porting Layer Definition - p. 20 */ + +Bool +winFinishScreenInitNativeGDI (int index, + ScreenPtr pScreen, + int argc, char **argv) +{ + winScreenPriv(pScreen); + winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; + VisualPtr pVisuals = NULL; + DepthPtr pDepths = NULL; + VisualID rootVisual = 0; + int nVisuals = 0, nDepths = 0, nRootDepth = 0; + + /* Ignore user input (mouse, keyboard) */ + pScreenInfo->fIgnoreInput = FALSE; + + /* Get device contexts for the screen and shadow bitmap */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + if (pScreenPriv->hdcScreen == NULL) + FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n"); + + /* Init visuals */ + if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) + { + ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n"); + return FALSE; + } + + /* Initialize the mi visuals */ + if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth, + &rootVisual, + ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8, + TrueColor)) + { + ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n"); + return FALSE; + } + + /* Initialize the CloseScreen procedure pointer */ + pScreen->CloseScreen = NULL; + + /* Initialize the mi code */ + if (!miScreenInit (pScreen, + NULL, /* No framebuffer */ + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + monitorResolution, monitorResolution, + pScreenInfo->dwStride, + nRootDepth, nDepths, pDepths, rootVisual, + nVisuals, pVisuals)) + { + ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n"); + return FALSE; + } + + pScreen->defColormap = FakeClientID(0); + + /* + * Register our block and wakeup handlers; these procedures + * process messages in our Windows message queue; specifically, + * they process mouse and keyboard input. + */ + pScreen->BlockHandler = winBlockHandler; + pScreen->WakeupHandler = winWakeupHandler; + pScreen->blockData = pScreen; + pScreen->wakeupData = pScreen; + + /* Place our save screen function */ + pScreen->SaveScreen = winSaveScreen; + + /* Pixmaps */ + pScreen->CreatePixmap = winCreatePixmapNativeGDI; + pScreen->DestroyPixmap = winDestroyPixmapNativeGDI; + + /* Other Screen Routines */ + pScreen->QueryBestSize = winQueryBestSizeNativeGDI; + pScreen->SaveScreen = winSaveScreen; + pScreen->GetImage = miGetImage; + pScreen->GetSpans = winGetSpansNativeGDI; + + /* Window Procedures */ + pScreen->CreateWindow = winCreateWindowNativeGDI; + pScreen->DestroyWindow = winDestroyWindowNativeGDI; + pScreen->PositionWindow = winPositionWindowNativeGDI; + /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI;*/ + pScreen->RealizeWindow = winMapWindowNativeGDI; + pScreen->UnrealizeWindow = winUnmapWindowNativeGDI; + + /* Paint window */ + pScreen->CopyWindow = winCopyWindowNativeGDI; + + /* Fonts */ + pScreen->RealizeFont = winRealizeFontNativeGDI; + pScreen->UnrealizeFont = winUnrealizeFontNativeGDI; + + /* GC */ + pScreen->CreateGC = winCreateGCNativeGDI; + + /* Colormap Routines */ + pScreen->CreateColormap = miInitializeColormap; + pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)(void)) NoopDDA; + pScreen->InstallColormap = miInstallColormap; + pScreen->UninstallColormap = miUninstallColormap; + pScreen->ListInstalledColormaps = miListInstalledColormaps; + pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA; + pScreen->ResolveColor = miResolveColor; + + /* Bitmap */ + pScreen->BitmapToRegion = winPixmapToRegionNativeGDI; + + ErrorF ("winFinishScreenInitNativeGDI - calling miDCInitialize\n"); + + /* Set the default white and black pixel positions */ + pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0; + + /* Initialize the cursor */ + if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs)) + { + ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n"); + return FALSE; + } + + /* Create a default colormap */ + if (!miCreateDefColormap (pScreen)) + { + ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " + "failed\n"); + return FALSE; + } + + ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " + "returned\n"); + + /* mi doesn't use a CloseScreen procedure, so no need to wrap */ + pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; + + /* Tell the server that we are enabled */ + pScreenPriv->fEnabled = TRUE; + + ErrorF ("winFinishScreenInitNativeGDI - Successful addition of " + "screen %08x\n", + (unsigned int) pScreen); + + return TRUE; +} +#endif + + +/* See Porting Layer Definition - p. 33 */ +static Bool +winSaveScreen (ScreenPtr pScreen, int on) +{ + return TRUE; +} diff --git a/hw/xwin/winsetsp.c b/hw/xwin/winsetsp.c new file mode 100644 index 000000000..f894d6cda --- /dev/null +++ b/hw/xwin/winsetsp.c @@ -0,0 +1,186 @@ +/* + *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 + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + + +/* See Porting Layer Definition - p. 55 */ +void +winSetSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + char *pSrcs, + DDXPointPtr pPoints, + int *piWidths, + int iSpans, + int fSorted) +{ + winGCPriv(pGC); + PixmapPtr pPixmap = NULL; + winPrivPixmapPtr pPixmapPriv = NULL; + HBITMAP hbmpOrig = NULL; + BITMAPINFO bmi; + HRGN hrgn = NULL, combined = NULL; + int nbox; + BoxPtr pbox; + + nbox = REGION_NUM_RECTS (pGC->pCompositeClip); + pbox = REGION_RECTS (pGC->pCompositeClip); + + if (!nbox) return; + + combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); + nbox--; pbox++; + while (nbox--) + { + hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); + CombineRgn (combined, combined, hrgn, RGN_OR); + DeleteObject (hrgn); + hrgn = NULL; + pbox++; + } + + /* Branch on the drawable type */ + switch (pDrawable->type) + { + case DRAWABLE_PIXMAP: + + SelectClipRgn (pGCPriv->hdcMem, combined); + DeleteObject (combined); + combined = NULL; + + pPixmap = (PixmapPtr) pDrawable; + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Select the drawable pixmap into a DC */ + hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); + if (hbmpOrig == NULL) + FatalError ("winSetSpans - DRAWABLE_PIXMAP - SelectObject () " + "failed on pPixmapPriv->hBitmap\n"); + + while (iSpans--) + { + ZeroMemory (&bmi, sizeof (BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = *piWidths; + bmi.bmiHeader.biHeight = 1; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = pDrawable->depth; + bmi.bmiHeader.biCompression = BI_RGB; + + /* Setup color table for mono DIBs */ + if (pDrawable->depth == 1) + { + bmi.bmiColors[1].rgbBlue = 255; + bmi.bmiColors[1].rgbGreen = 255; + bmi.bmiColors[1].rgbRed = 255; + } + + StretchDIBits (pGCPriv->hdcMem, + pPoints->x, pPoints->y, + *piWidths, 1, + 0, 0, + *piWidths, 1, + pSrcs, + (BITMAPINFO *) &bmi, + DIB_RGB_COLORS, + g_copyROP[pGC->alu]); + + pSrcs += PixmapBytePad (*piWidths, pDrawable->depth); + pPoints++; + piWidths++; + } + + /* Reset the clip region */ + SelectClipRgn (pGCPriv->hdcMem, NULL); + + /* Push the drawable pixmap out of the GC HDC */ + SelectObject (pGCPriv->hdcMem, hbmpOrig); + break; + + case DRAWABLE_WINDOW: + + SelectClipRgn (pGCPriv->hdc, combined); + DeleteObject (combined); + combined = NULL; + + while (iSpans--) + { + ZeroMemory (&bmi, sizeof (BITMAPINFO)); + bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = *piWidths; + bmi.bmiHeader.biHeight = 1; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = pDrawable->depth; + bmi.bmiHeader.biCompression = BI_RGB; + + /* Setup color table for mono DIBs */ + if (pDrawable->depth == 1) + { + bmi.bmiColors[1].rgbBlue = 255; + bmi.bmiColors[1].rgbGreen = 255; + bmi.bmiColors[1].rgbRed = 255; + } + + StretchDIBits (pGCPriv->hdc, + pPoints->x, pPoints->y, + *piWidths, 1, + 0, 0, + *piWidths, 1, + pSrcs, + (BITMAPINFO *) &bmi, + DIB_RGB_COLORS, + g_copyROP[pGC->alu]); + + pSrcs += PixmapBytePad (*piWidths, pDrawable->depth); + pPoints++; + piWidths++; + } + + /* Reset the clip region */ + SelectClipRgn (pGCPriv->hdc, NULL); + break; + + case UNDRAWABLE_WINDOW: + FatalError ("\nwinSetSpansNativeGDI - UNDRAWABLE_WINDOW\n\n"); + break; + + case DRAWABLE_BUFFER: + FatalError ("\nwinSetSpansNativeGDI - DRAWABLE_BUFFER\n\n"); + break; + + default: + FatalError ("\nwinSetSpansNativeGDI - Unknown drawable type\n\n"); + break; + } +} diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c new file mode 100644 index 000000000..a2c1dc9b0 --- /dev/null +++ b/hw/xwin/winshaddd.c @@ -0,0 +1,1442 @@ +/* + *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 <xwin-config.h> +#endif +#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. + */ +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#endif /* DEFINE_GUID */ + + +/* + * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined + * here manually. Should be handled by ddraw.h + */ +#ifndef IID_IDirectDraw2 +DEFINE_GUID( IID_IDirectDraw2,0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +#endif /* IID_IDirectDraw2 */ + + +/* + * Local prototypes + */ + +static Bool +winAllocateFBShadowDD (ScreenPtr pScreen); + +static void +winShadowUpdateDD (ScreenPtr pScreen, + shadowBufPtr pBuf); + +static Bool +winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen); + +static Bool +winInitVisualsShadowDD (ScreenPtr pScreen); + +static Bool +winAdjustVideoModeShadowDD (ScreenPtr pScreen); + +static Bool +winBltExposedRegionsShadowDD (ScreenPtr pScreen); + +static Bool +winActivateAppShadowDD (ScreenPtr pScreen); + +static Bool +winRedrawScreenShadowDD (ScreenPtr pScreen); + +static Bool +winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen); + +static Bool +winInstallColormapShadowDD (ColormapPtr pColormap); + +static Bool +winStoreColorsShadowDD (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +static Bool +winCreateColormapShadowDD (ColormapPtr pColormap); + +static Bool +winDestroyColormapShadowDD (ColormapPtr pColormap); + +static Bool +winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen); + +static Bool +winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen); + + +/* + * Create the primary surface and attach the clipper. + * Used for both the initial surface creation and during + * WM_DISPLAYCHANGE messages. + */ + +static Bool +winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HRESULT ddrval = DD_OK; + DDSURFACEDESC ddsd; + + /* 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)) + { + ErrorF ("winCreatePrimarySurfaceShadowDD - Could not create primary " + "surface: %08x\n", (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winCreatePrimarySurfaceShadowDD - Created primary surface\n"); +#endif + + /* + * Attach a clipper to the primary surface that will clip our blits to our + * display window. + */ + ddrval = IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, + pScreenPriv->pddcPrimary); + if (FAILED (ddrval)) + { + ErrorF ("winCreatePrimarySurfaceShadowDD - Primary attach clipper " + "failed: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winCreatePrimarySurfaceShadowDD - Attached clipper to " + "primary surface\n"); +#endif + + /* Everything was correct */ + return TRUE; +} + + +/* + * Detach the clipper and release the primary surface. + * Called from WM_DISPLAYCHANGE. + */ + +static Bool +winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + ErrorF ("winReleasePrimarySurfaceShadowDD - Hello\n"); + + /* Release the primary surface and clipper, if they exist */ + if (pScreenPriv->pddsPrimary) + { + /* + * Detach the clipper from the primary surface. + * NOTE: We do this explicity for clarity. The Clipper is not released. + */ + IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, + NULL); + + ErrorF ("winReleasePrimarySurfaceShadowDD - Detached clipper\n"); + + /* Release the primary surface */ + IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); + pScreenPriv->pddsPrimary = NULL; + } + + ErrorF ("winReleasePrimarySurfaceShadowDD - Released primary surface\n"); + + return TRUE; +} + + +/* + * Create a DirectDraw surface for the shadow framebuffer; also create + * a primary surface object so we can blit to the display. + * + * Install a DirectDraw clipper on our primary surface object + * that clips our blits to the unobscured client area of our display window. + */ + +static Bool +winAllocateFBShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + DDSURFACEDESC ddsd; + DDSURFACEDESC *pddsdShadow = NULL; + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD\n"); +#endif + + /* Create a clipper */ + ddrval = (*g_fpDirectDrawCreateClipper) (0, + &pScreenPriv->pddcPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not create clipper: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD - Created a clipper\n"); +#endif + + /* Get a device context for the screen */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + + /* Attach the clipper to our display window */ + ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, + 0, + pScreenPriv->hwndScreen); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Clipper not attached to " + "window: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD - Attached clipper to window\n"); +#endif + + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n"); +#endif + + /* 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; + } + + /* Are we full screen? */ + if (pScreenInfo->fFullScreen) + { + DDSURFACEDESC ddsdCurrent; + DWORD dwRefreshRateCurrent = 0; + HDC hdc = NULL; + + /* Set the cooperative level to full screen */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_EXCLUSIVE + | DDSCL_FULLSCREEN); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not set " + "cooperative level: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + + /* + * We only need to get the current refresh rate for comparison + * if a refresh rate has been passed on the command line. + */ + if (pScreenInfo->dwRefreshRate != 0) + { + ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); + ddsdCurrent.dwSize = sizeof (ddsdCurrent); + + /* Get information about current display settings */ + ddrval = IDirectDraw2_GetDisplayMode (pScreenPriv->pdd2, + &ddsdCurrent); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not get current " + "refresh rate: %08x. Continuing.\n", + (unsigned int) ddrval); + dwRefreshRateCurrent = 0; + } + else + { + /* Grab the current refresh rate */ + dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; + } + } + + /* Clean up the refresh rate */ + if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) + { + /* + * Refresh rate is non-specified or equal to current. + */ + pScreenInfo->dwRefreshRate = 0; + } + + /* Grab a device context for the screen */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAllocateFBShadowDD - GetDC () failed\n"); + return FALSE; + } + + /* Only change the video mode when different than current mode */ + if (!pScreenInfo->fMultipleMonitors + && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) + || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) + || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) + || pScreenInfo->dwRefreshRate != 0)) + { + ErrorF ("winAllocateFBShadowDD - Changing video mode\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)) + { + ErrorF ("winAllocateFBShadowDD - Could not set "\ + "full screen display mode: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + } + else + { + ErrorF ("winAllocateFBShadowDD - Not changing video mode\n"); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + } + else + { + /* Set the cooperative level for windowed mode */ + ddrval = IDirectDraw2_SetCooperativeLevel (pScreenPriv->pdd2, + pScreenPriv->hwndScreen, + DDSCL_NORMAL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not set "\ + "cooperative level: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + } + + /* Create the primary surface */ + if (!winCreatePrimarySurfaceShadowDD (pScreen)) + { + ErrorF ("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD " + "failed\n"); + return FALSE; + } + + /* Describe the shadow 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->pddsShadow, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDD - Could not create shadow "\ + "surface: %08x\n", (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD - Created shadow\n"); +#endif + + /* Allocate a DD surface description for our screen privates */ + pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); + if (pddsdShadow == NULL) + { + ErrorF ("winAllocateFBShadowDD - Could not allocate surface "\ + "description memory\n"); + return FALSE; + } + ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); + pddsdShadow->dwSize = sizeof (*pddsdShadow); + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD - Locking shadow\n"); +#endif + + /* Lock the shadow surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pddsdShadow, + DDLOCK_WAIT, + NULL); + if (FAILED (ddrval) || pddsdShadow->lpSurface == NULL) + { + ErrorF ("winAllocateFBShadowDD - Could not lock shadow "\ + "surface: %08x\n", (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD - Locked shadow\n"); +#endif + + /* We don't know how to deal with anything other than RGB */ + if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) + { + ErrorF ("winAllocateFBShadowDD - Color format other than RGB\n"); + return FALSE; + } + + /* Grab the pitch from the surface desc */ + pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8) + / pScreenInfo->dwBPP; + + /* Save the pointer to our surface memory */ + pScreenInfo->pfb = pddsdShadow->lpSurface; + + /* Grab the color depth and masks from the surface description */ + pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask; + pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; + pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDD - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Transfer the damaged regions of the shadow framebuffer to the display. + */ + +static void +winShadowUpdateDD (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RegionPtr damage = &pBuf->damage; + HRESULT ddrval = DD_OK; + RECT rcDest, rcSrc; + POINT ptOrigin; + DWORD dwBox = REGION_NUM_RECTS (damage); + BoxPtr pBox = REGION_RECTS (damage); + HRGN hrgnTemp = NULL, hrgnCombined = NULL; + + /* + * Return immediately if the app is not active + * and we are fullscreen, or if we have a bad display depth + */ + if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) + || pScreenPriv->fBadDepth) return; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + + /* Unlock the shadow surface, so we can blit */ + ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); + if (FAILED (ddrval)) + { + ErrorF ("winShadowUpdateProcDD - Unlock failed\n"); + return; + } + + /* + * Handle small regions with multiple blits, + * handle large regions by creating a clipping region and + * doing a single blit constrained to that clipping region. + */ + if (pScreenInfo->dwClipUpdatesNBoxes == 0 + || dwBox < pScreenInfo->dwClipUpdatesNBoxes) + { + /* Loop through all boxes in the damaged region */ + while (dwBox--) + { + /* Assign damage box to source rectangle */ + rcSrc.left = pBox->x1; + rcSrc.top = pBox->y1; + rcSrc.right = pBox->x2; + rcSrc.bottom = pBox->y2; + + /* Calculate destination rectange */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Blit the damaged areas */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + + /* Get a pointer to the next box */ + ++pBox; + } + } + else + { + BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); + + /* Compute a GDI region from the damaged region */ + hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + dwBox--; + pBox++; + while (dwBox--) + { + hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); + DeleteObject (hrgnTemp); + pBox++; + } + + /* Install the GDI region as a clipping region */ + SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); + DeleteObject (hrgnCombined); + hrgnCombined = NULL; + + /* Calculating a bounding box for the source is easy */ + rcSrc.left = pBoxExtents->x1; + rcSrc.top = pBoxExtents->y1; + rcSrc.right = pBoxExtents->x2; + rcSrc.bottom = pBoxExtents->y2; + + /* Calculating a bounding box for the destination is trickier */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + + /* Reset the clip region */ + SelectClipRgn (pScreenPriv->hdcScreen, NULL); + } + + /* Relock the shadow surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pScreenPriv->pddsdShadow, + DDLOCK_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winShadowUpdateProcDD - Lock failed\n"); + return; + } + + /* Has our memory pointer changed? */ + if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) + { + ErrorF ("winShadowUpdateProcDD - Memory location of the shadow " + "surface has changed, trying to update the root window " + "pixmap header to point to the new address. If you get " + "this message and "PROJECT_NAME" freezes or crashes " + "after this message then send a problem report and your " + "/tmp/XWin.log file to cygwin-xfree@cygwin.com\n"); + + /* Location of shadow framebuffer has changed */ + pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface; + + /* Update the screen pixmap */ + if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate, + pScreen->width, + pScreen->height, + pScreen->rootDepth, + BitsPerPixel (pScreen->rootDepth), + PixmapBytePad (pScreenInfo->dwStride, + pScreenInfo->dwBPP), + pScreenInfo->pfb)) + { + ErrorF ("winShadowUpdateProcDD - Bits changed, could not " + "notify fb.\n"); + return; + } + } +} + + +/* + * Call the wrapped CloseScreen function. + * + * Free our resources and private structures. + */ + +static Bool +winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + +#if CYGDEBUG + winDebug ("winCloseScreenShadowDD - Freeing screen resources\n"); +#endif + + /* 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); + + /* Free the screen DC */ + ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the shadow surface, if there is one */ + if (pScreenPriv->pddsShadow) + { + IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); + IDirectDrawSurface2_Release (pScreenPriv->pddsShadow); + pScreenPriv->pddsShadow = NULL; + } + + /* Detach the clipper from the primary surface and release the clipper. */ + if (pScreenPriv->pddcPrimary) + { + /* Detach the clipper */ + IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, + NULL); + + /* Release the clipper object */ + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = NULL; + } + + /* Release the primary surface, if there is one */ + if (pScreenPriv->pddsPrimary) + { + IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); + pScreenPriv->pddsPrimary = NULL; + } + + /* Free the DirectDraw2 object, if there is one */ + if (pScreenPriv->pdd2) + { + IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2); + IDirectDraw2_Release (pScreenPriv->pdd2); + pScreenPriv->pdd2 = NULL; + } + + /* Free the DirectDraw object, if there is one */ + if (pScreenPriv->pdd) + { + IDirectDraw_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; + } + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Destroy the thread startup mutex */ + pthread_mutex_destroy (&pScreenPriv->pmServerStarted); +#endif + + /* 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 +winInitVisualsShadowDD (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 == 0 || dwGreenBits == 0 || dwBlueBits == 0) + pScreenPriv->dwBitsPerRGB = 8; + else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + ErrorF ("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d " + "bpp %d\n", + (unsigned int) pScreenPriv->dwRedMask, + (unsigned int) pScreenPriv->dwGreenMask, + (unsigned int) pScreenPriv->dwBlueMask, + (int) pScreenPriv->dwBitsPerRGB, + (int) pScreenInfo->dwDepth, + (int) pScreenInfo->dwBPP); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: +#if defined(XFree86Server) + /* Create the real visual */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + TrueColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#ifdef XWIN_EMULATEPSEUDO + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!miSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + -1, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + 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, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->fFullScreen + ? PseudoColor : StaticColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDD - miSetVisualTypesAndMasks " + "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: + ErrorF ("winInitVisualsShadowDD - Unknown screen depth\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winInitVisualsShadowDD - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Adjust the user proposed video mode + */ + +static Bool +winAdjustVideoModeShadowDD (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 ("winAdjustVideoModeShadowDD - 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 ("winAdjustVideoModeShadowDD - 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 ("winAdjustVideoModeShadowDD - FullScreen, using command line " + "bpp: %d\n", (int) pScreenInfo->dwBPP); + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Windowed, and GDI depth differs from -depth parameter */ + ErrorF ("winAdjustVideoModeShadowDD - Windowed, command line bpp: " + "%d, using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* See if the shadow bitmap will be larger than the DIB size limit */ + if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP + >= WIN_DIB_MAXIMUM_SIZE) + { + ErrorF ("winAdjustVideoModeShadowDD - Requested DirectDraw surface " + "will be larger than %d MB. The surface may fail to be " + "allocated on Windows 95, 98, or Me, due to a %d MB limit in " + "DIB size. This limit does not apply to Windows NT/2000, and " + "this message may be ignored on those platforms.\n", + WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + return TRUE; +} + + +/* + * Blt exposed regions to the screen + */ + +static Bool +winBltExposedRegionsShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcSrc, rcDest; + POINT ptOrigin; + HDC hdcUpdate = NULL; + PAINTSTRUCT ps; + HRESULT ddrval = DD_OK; + Bool fReturn = TRUE; + Bool fLocked = TRUE; + int i; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); + if (hdcUpdate == NULL) + { + ErrorF ("winBltExposedRegionsShadowDD - BeginPaint () returned " + "a NULL device context handle. Aborting blit attempt.\n"); + return FALSE; + } + + /* Unlock the shadow surface, so we can blit */ + ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); + if (FAILED (ddrval)) + { + fReturn = FALSE; + goto winBltExposedRegionsShadowDD_Exit; + } + else + { + /* Flag that we have unlocked the shadow surface */ + fLocked = FALSE; + } + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be enter shadow surface, as Blt should clip */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Try to regain the primary surface and blit again if we've lost it */ + for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) + { + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + if (ddrval == DDERR_SURFACELOST) + { + /* Surface was lost */ + ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " + "reported that the primary surface was lost, " + "trying to restore, retry: %d\n", i + 1); + + /* Try to restore the surface, once */ + ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + ErrorF ("winBltExposedRegionsShadowDD - " + "IDirectDrawSurface2_Restore returned: "); + if (ddrval == DD_OK) + ErrorF ("DD_OK\n"); + else if (ddrval == DDERR_WRONGMODE) + ErrorF ("DDERR_WRONGMODE\n"); + else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) + ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n"); + else if (ddrval == DDERR_UNSUPPORTED) + ErrorF ("DDERR_UNSUPPORTED\n"); + else if (ddrval == DDERR_INVALIDPARAMS) + ErrorF ("DDERR_INVALIDPARAMS\n"); + else if (ddrval == DDERR_INVALIDOBJECT) + ErrorF ("DDERR_INVALIDOBJECT\n"); + else + ErrorF ("unknown error: %08x\n", (unsigned int) ddrval); + + /* Loop around to try the blit one more time */ + continue; + } + else if (FAILED (ddrval)) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt " + "failed, but surface not lost: %08x %d\n", + (unsigned int) ddrval, (int) ddrval); + goto winBltExposedRegionsShadowDD_Exit; + } + else + { + /* Success, stop looping */ + break; + } + } + + /* Relock the shadow surface */ + ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pScreenPriv->pddsdShadow, + DDLOCK_WAIT, + NULL); + if (FAILED (ddrval)) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock " + "failed\n"); + goto winBltExposedRegionsShadowDD_Exit; + } + else + { + /* Indicate that we have relocked the shadow surface */ + fLocked = TRUE; + } + + /* Has our memory pointer changed? */ + if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdShadow->lpSurface); + + winBltExposedRegionsShadowDD_Exit: + /* EndPaint frees the DC */ + if (hdcUpdate != NULL) + EndPaint (pScreenPriv->hwndScreen, &ps); + + /* + * Relock the surface if it is not locked. We don't care if locking fails, + * as it will cause the server to shutdown within a few more operations. + */ + if (!fLocked) + { + IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, + NULL, + pScreenPriv->pddsdShadow, + DDLOCK_WAIT, + NULL); + + /* Has our memory pointer changed? */ + if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) + winUpdateFBPointer (pScreen, + pScreenPriv->pddsdShadow->lpSurface); + + fLocked = TRUE; + } + return fReturn; +} + + +/* + * Do any engine-specific appliation-activation processing + */ + +static Bool +winActivateAppShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + /* + * Do we have a surface? + * Are we active? + * Are we fullscreen? + */ + if (pScreenPriv != NULL + && pScreenPriv->pddsPrimary != NULL + && pScreenPriv->fActive) + { + /* Primary surface was lost, restore it */ + IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary); + } + + return TRUE; +} + + +/* + * Reblit the shadow framebuffer to the screen. + */ + +static Bool +winRedrawScreenShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + RECT rcSrc, rcDest; + POINT ptOrigin; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be entire shadow surface, as Blt should clip for us */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Redraw the whole window, to take account for the new colors */ + ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, + &rcDest, + pScreenPriv->pddsShadow, + &rcSrc, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () " + "failed: %08x\n", + (unsigned int) ddrval); + } + + return TRUE; +} + + +/* + * Realize the currently installed colormap + */ + +static Bool +winRealizeInstalledPaletteShadowDD (ScreenPtr pScreen) +{ + return TRUE; +} + + +/* + * Install the specified colormap + */ + +static Bool +winInstallColormapShadowDD (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* Install the DirectDraw palette on the primary surface */ + ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary, + pCmapPriv->lpDDPalette); + if (FAILED (ddrval)) + { + ErrorF ("winInstallColormapShadowDD - Failed installing the " + "DirectDraw palette.\n"); + return FALSE; + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; + + return TRUE; +} + + +/* + * Store the specified colors in the specified colormap + */ + +static Bool +winStoreColorsShadowDD (ColormapPtr pColormap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + HRESULT ddrval = DD_OK; + + /* Put the X colormap entries into the Windows logical palette */ + ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette, + 0, + pdefs[0].pixel, + ndef, + pCmapPriv->peColors + + pdefs[0].pixel); + if (FAILED (ddrval)) + { + ErrorF ("winStoreColorsShadowDD - SetEntries () failed\n"); + return FALSE; + } + + /* Don't install the DirectDraw palette if the colormap is not installed */ + if (pColormap != curpmap) + { + return TRUE; + } + + if (!winInstallColormapShadowDD (pColormap)) + { + ErrorF ("winStoreColorsShadowDD - Failed installing colormap\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap initialization procedure + */ + +static Bool +winCreateColormapShadowDD (ColormapPtr pColormap) +{ + HRESULT ddrval = DD_OK; + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + + /* Create a DirectDraw palette */ + ddrval = IDirectDraw2_CreatePalette (pScreenPriv->pdd, + DDPCAPS_8BIT | DDPCAPS_ALLOW256, + pCmapPriv->peColors, + &pCmapPriv->lpDDPalette, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winCreateColormapShadowDD - CreatePalette failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap destruction procedure + */ + +static Bool +winDestroyColormapShadowDD (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* + * Is colormap to be destroyed the default? + * + * Non-default colormaps should have had winUninstallColormap + * called on them before we get here. The default colormap + * will not have had winUninstallColormap called on it. Thus, + * we need to handle the default colormap in a special way. + */ + if (pColormap->flags & IsDefault) + { +#if CYGDEBUG + winDebug ("winDestroyColormapShadowDD - Destroying default " + "colormap\n"); +#endif + + /* + * FIXME: Walk the list of all screens, popping the default + * palette out of each screen device context. + */ + + /* Pop the palette out of the primary surface */ + ddrval = IDirectDrawSurface2_SetPalette (pScreenPriv->pddsPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winDestroyColormapShadowDD - Failed freeing the " + "default colormap DirectDraw palette.\n"); + return FALSE; + } + + /* Clear our private installed colormap pointer */ + pScreenPriv->pcmapInstalled = NULL; + } + + /* Release the palette */ + IDirectDrawPalette_Release (pCmapPriv->lpDDPalette); + + /* Invalidate the colormap privates */ + pCmapPriv->lpDDPalette = NULL; + + return TRUE; +} + + +/* + * Set engine specific functions + */ + +Bool +winSetEngineFunctionsShadowDD (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD; + pScreenPriv->pwinShadowUpdate = winShadowUpdateDD; + pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD; + pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD; + pScreenPriv->pwinActivateApp = winActivateAppShadowDD; + pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD; + pScreenPriv->pwinRealizeInstalledPalette + = winRealizeInstalledPaletteShadowDD; + pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD; + pScreenPriv->pwinStoreColors = winStoreColorsShadowDD; + pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD; + pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; + pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD; + pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD; +#ifdef XWIN_MULTIWINDOW + pScreenPriv->pwinFinishCreateWindowsWindow = + (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; +#endif + + return TRUE; +} diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c new file mode 100644 index 000000000..47cc382e9 --- /dev/null +++ b/hw/xwin/winshadddnl.c @@ -0,0 +1,1454 @@ +/* + *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 <xwin-config.h> +#endif +#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. + */ +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +#endif /* DEFINE_GUID */ + +/* + * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined + * here manually. Should be handled by ddraw.h + */ +#ifndef IID_IDirectDraw4 +DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); +#endif /* IID_IDirectDraw4 */ + +#define FAIL_MSG_MAX_BLT 10 + + +/* + * Local prototypes + */ + +static Bool +winAllocateFBShadowDDNL (ScreenPtr pScreen); + +static void +winShadowUpdateDDNL (ScreenPtr pScreen, + shadowBufPtr pBuf); + +static Bool +winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen); + +static Bool +winInitVisualsShadowDDNL (ScreenPtr pScreen); + +static Bool +winAdjustVideoModeShadowDDNL (ScreenPtr pScreen); + +static Bool +winBltExposedRegionsShadowDDNL (ScreenPtr pScreen); + +static Bool +winActivateAppShadowDDNL (ScreenPtr pScreen); + +static Bool +winRedrawScreenShadowDDNL (ScreenPtr pScreen); + +static Bool +winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen); + +static Bool +winInstallColormapShadowDDNL (ColormapPtr pColormap); + +static Bool +winStoreColorsShadowDDNL (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +static Bool +winCreateColormapShadowDDNL (ColormapPtr pColormap); + +static Bool +winDestroyColormapShadowDDNL (ColormapPtr pColormap); + +static Bool +winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen); + +static Bool +winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen); + + +/* + * Create the primary surface and attach the clipper. + * Used for both the initial surface creation and during + * WM_DISPLAYCHANGE messages. + */ + +static Bool +winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HRESULT ddrval = DD_OK; + DDSURFACEDESC2 ddsd; + + winDebug ("winCreatePrimarySurfaceShadowDDNL - Creating primary surface\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 = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, + &ddsd, + &pScreenPriv->pddsPrimary4, + NULL); + pScreenPriv->fRetryCreateSurface = FALSE; + if (FAILED (ddrval)) + { + if (ddrval == DDERR_NOEXCLUSIVEMODE) + { + /* Recreating the surface failed. Mark screen to retry later */ + pScreenPriv->fRetryCreateSurface = TRUE; + winDebug ("winCreatePrimarySurfaceShadowDDNL - Could not create " + "primary surface: DDERR_NOEXCLUSIVEMODE\n"); + } + else + { + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Could not create " + "primary surface: %08x\n", (unsigned int) ddrval); + } + return FALSE; + } + +#if 1 + winDebug ("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n"); +#endif + + /* Attach our clipper to our primary surface handle */ + ddrval = IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, + pScreenPriv->pddcPrimary); + if (FAILED (ddrval)) + { + ErrorF ("winCreatePrimarySurfaceShadowDDNL - Primary attach clipper " + "failed: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if 1 + winDebug ("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary " + "surface\n"); +#endif + + /* Everything was correct */ + return TRUE; +} + + +/* + * Detach the clipper and release the primary surface. + * Called from WM_DISPLAYCHANGE. + */ + +static Bool +winReleasePrimarySurfaceShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + winDebug ("winReleasePrimarySurfaceShadowDDNL - Hello\n"); + + /* Release the primary surface and clipper, if they exist */ + if (pScreenPriv->pddsPrimary4) + { + /* + * Detach the clipper from the primary surface. + * NOTE: We do this explicity for clarity. The Clipper is not released. + */ + IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, + NULL); + + winDebug ("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n"); + + /* Release the primary surface */ + IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4); + pScreenPriv->pddsPrimary4 = NULL; + } + + winDebug ("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n"); + + return TRUE; +} + + +/* + * Create a DirectDraw surface for the shadow framebuffer; also create + * a primary surface object so we can blit to the display. + * + * Install a DirectDraw clipper on our primary surface object + * that clips our blits to the unobscured client area of our display window. + */ + +Bool +winAllocateFBShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + DDSURFACEDESC2 ddsdShadow; + char *lpSurface = NULL; + DDPIXELFORMAT ddpfPrimary; + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n", + pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); +#endif + + /* Allocate memory for our shadow surface */ + lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + if (lpSurface == NULL) + { + ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); + return FALSE; + } + + /* + * Initialize the framebuffer memory so we don't get a + * strange display at startup + */ + ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); + + /* Create a clipper */ + ddrval = (*g_fpDirectDrawCreateClipper) (0, + &pScreenPriv->pddcPrimary, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDDNL - Created a clipper\n"); +#endif + + /* Get a device context for the screen */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + + /* Attach the clipper to our display window */ + ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, + 0, + pScreenPriv->hwndScreen); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Clipper not attached " + "to window: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n"); +#endif + + /* Create a DirectDraw object, store the address at lpdd */ + ddrval = (*g_fpDirectDrawCreate) (NULL, + (LPDIRECTDRAW*) &pScreenPriv->pdd, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not start " + "DirectDraw: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n"); +#endif + + /* Get a DirectDraw4 interface pointer */ + ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, + &IID_IDirectDraw4, + (LPVOID*) &pScreenPriv->pdd4); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + + /* Are we full screen? */ + if (pScreenInfo->fFullScreen) + { + DDSURFACEDESC2 ddsdCurrent; + DWORD dwRefreshRateCurrent = 0; + HDC hdc = NULL; + + /* Set the cooperative level to full screen */ + ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, + pScreenPriv->hwndScreen, + DDSCL_EXCLUSIVE + | DDSCL_FULLSCREEN); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not set " + "cooperative level: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + + /* + * We only need to get the current refresh rate for comparison + * if a refresh rate has been passed on the command line. + */ + if (pScreenInfo->dwRefreshRate != 0) + { + ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); + ddsdCurrent.dwSize = sizeof (ddsdCurrent); + + /* Get information about current display settings */ + ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4, + &ddsdCurrent); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not get current " + "refresh rate: %08x. Continuing.\n", + (unsigned int) ddrval); + dwRefreshRateCurrent = 0; + } + else + { + /* Grab the current refresh rate */ + dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; + } + } + + /* Clean up the refresh rate */ + if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) + { + /* + * Refresh rate is non-specified or equal to current. + */ + pScreenInfo->dwRefreshRate = 0; + } + + /* Grab a device context for the screen */ + hdc = GetDC (NULL); + if (hdc == NULL) + { + ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n"); + return FALSE; + } + + /* Only change the video mode when different than current mode */ + if (!pScreenInfo->fMultipleMonitors + && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) + || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) + || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) + || pScreenInfo->dwRefreshRate != 0)) + { + winDebug ("winAllocateFBShadowDDNL - Changing video mode\n"); + + /* Change the video mode to the mode requested */ + ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, + pScreenInfo->dwWidth, + pScreenInfo->dwHeight, + pScreenInfo->dwBPP, + pScreenInfo->dwRefreshRate, + 0); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not set " + "full screen display mode: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + } + else + { + winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n"); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + hdc = NULL; + } + else + { + /* Set the cooperative level for windowed mode */ + ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, + pScreenPriv->hwndScreen, + DDSCL_NORMAL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not set " + "cooperative level: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + } + + /* Create the primary surface */ + if (!winCreatePrimarySurfaceShadowDDNL (pScreen)) + { + ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL " + "failed\n"); + return FALSE; + } + + /* Get primary surface's pixel format */ + ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary)); + ddpfPrimary.dwSize = sizeof (ddpfPrimary); + ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4, + &ddpfPrimary); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not get primary " + "pixformat: %08x\n", + (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " + "dwRGBBitCount: %d\n", + ddpfPrimary.u2.dwRBitMask, + ddpfPrimary.u3.dwGBitMask, + ddpfPrimary.u4.dwBBitMask, + ddpfPrimary.u1.dwRGBBitCount); +#endif + + /* Describe the shadow 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 (&ddsdShadow, sizeof (ddsdShadow)); + ddsdShadow.dwSize = sizeof (ddsdShadow); + ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH + | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; + ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsdShadow.dwHeight = pScreenInfo->dwHeight; + ddsdShadow.dwWidth = pScreenInfo->dwWidth; + ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth; + ddsdShadow.lpSurface = lpSurface; + ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary; + + winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n", + (int) pScreenInfo->dwPaddedWidth); + + /* Create the shadow surface */ + ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, + &ddsdShadow, + &pScreenPriv->pddsShadow4, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winAllocateFBShadowDDNL - Could not create shadow " + "surface: %08x\n", (unsigned int) ddrval); + return FALSE; + } + +#if CYGDEBUG || YES + winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", + (int) ddsdShadow.u1.lPitch); +#endif + + /* Grab the pitch from the surface desc */ + pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) + / pScreenInfo->dwBPP; + +#if CYGDEBUG || YES + winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", + (int) pScreenInfo->dwStride); +#endif + + /* Save the pointer to our surface memory */ + pScreenInfo->pfb = lpSurface; + + /* Grab the masks from the surface description */ + pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask; + pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; + pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; + +#if CYGDEBUG + winDebug ("winAllocateFBShadowDDNL - Returning\n"); +#endif + + return TRUE; +} + + +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) +/* + * Create a DirectDraw surface for the new multi-window window + */ + +static +Bool +winFinishCreateWindowsWindowDDNL (WindowPtr pWin) +{ + winWindowPriv(pWin); + winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; + HRESULT ddrval = DD_OK; + DDSURFACEDESC2 ddsd; + int iWidth, iHeight; + int iX, iY; + + winDebug ("\nwinFinishCreateWindowsWindowDDNL!\n\n"); + + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Describe the primary surface */ + ZeroMemory (&ddsd, sizeof (ddsd)); + ddsd.dwSize = sizeof (ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + ddsd.dwHeight = iHeight; + ddsd.dwWidth = iWidth; + + /* Create the primary surface */ + ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, + &ddsd, + &pWinPriv->pddsPrimary4, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winFinishCreateWindowsWindowDDNL - Could not create primary " + "surface: %08x\n", + (unsigned int)ddrval); + return FALSE; + } + return TRUE; +} +#endif + + +/* + * Transfer the damaged regions of the shadow framebuffer to the display. + */ + +static void +winShadowUpdateDDNL (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RegionPtr damage = &pBuf->damage; + HRESULT ddrval = DD_OK; + RECT rcDest, rcSrc; + POINT ptOrigin; + DWORD dwBox = REGION_NUM_RECTS (damage); + BoxPtr pBox = REGION_RECTS (damage); + HRGN hrgnTemp = NULL, hrgnCombined = NULL; + + /* + * Return immediately if the app is not active + * and we are fullscreen, or if we have a bad display depth + */ + if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) + || pScreenPriv->fBadDepth) return; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + + /* + * Handle small regions with multiple blits, + * handle large regions by creating a clipping region and + * doing a single blit constrained to that clipping region. + */ + if (pScreenInfo->dwClipUpdatesNBoxes == 0 + || dwBox < pScreenInfo->dwClipUpdatesNBoxes) + { + /* Loop through all boxes in the damaged region */ + while (dwBox--) + { + /* Assign damage box to source rectangle */ + rcSrc.left = pBox->x1; + rcSrc.top = pBox->y1; + rcSrc.right = pBox->x2; + rcSrc.bottom = pBox->y2; + + /* Calculate destination rectangle */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Blit the damaged areas */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + { + static int s_iFailCount = 0; + + if (s_iFailCount < FAIL_MSG_MAX_BLT) + { + ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () " + "failed: %08x\n", + (unsigned int) ddrval); + + ++s_iFailCount; + + if (s_iFailCount == FAIL_MSG_MAX_BLT) + { + ErrorF ("winShadowUpdateDDNL - IDirectDrawSurface4_Blt " + "failure message maximum (%d) reached. No " + "more failure messages will be printed.\n", + FAIL_MSG_MAX_BLT); + } + } + } + + /* Get a pointer to the next box */ + ++pBox; + } + } + else + { + BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); + + /* Compute a GDI region from the damaged region */ + hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + dwBox--; + pBox++; + while (dwBox--) + { + hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); + DeleteObject (hrgnTemp); + pBox++; + } + + /* Install the GDI region as a clipping region */ + SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); + DeleteObject (hrgnCombined); + hrgnCombined = NULL; + +#if CYGDEBUG + winDebug ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n", + pBoxExtents->x1, pBoxExtents->y1, + pBoxExtents->x2, pBoxExtents->y2); +#endif + + /* Calculating a bounding box for the source is easy */ + rcSrc.left = pBoxExtents->x1; + rcSrc.top = pBoxExtents->y1; + rcSrc.right = pBoxExtents->x2; + rcSrc.bottom = pBoxExtents->y2; + + /* Calculating a bounding box for the destination is trickier */ + rcDest.left = ptOrigin.x + rcSrc.left; + rcDest.top = ptOrigin.y + rcSrc.top; + rcDest.right = ptOrigin.x + rcSrc.right; + rcDest.bottom = ptOrigin.y + rcSrc.bottom; + + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + + /* Reset the clip region */ + SelectClipRgn (pScreenPriv->hdcScreen, NULL); + } +} + + +/* + * Call the wrapped CloseScreen function. + * + * Free our resources and private structures. + */ + +static Bool +winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + +#if CYGDEBUG + winDebug ("winCloseScreenShadowDDNL - Freeing screen resources\n"); +#endif + + /* 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); + + /* Free the screen DC */ + ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + + /* Delete the window property */ + RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); + + /* Free the shadow surface, if there is one */ + if (pScreenPriv->pddsShadow4) + { + IDirectDrawSurface4_Release (pScreenPriv->pddsShadow4); + free (pScreenInfo->pfb); + pScreenInfo->pfb = NULL; + pScreenPriv->pddsShadow4 = NULL; + } + + /* Detach the clipper from the primary surface and release the clipper. */ + if (pScreenPriv->pddcPrimary) + { + /* Detach the clipper */ + IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, + NULL); + + /* Release the clipper object */ + IDirectDrawClipper_Release (pScreenPriv->pddcPrimary); + pScreenPriv->pddcPrimary = NULL; + } + + /* Release the primary surface, if there is one */ + if (pScreenPriv->pddsPrimary4) + { + IDirectDrawSurface4_Release (pScreenPriv->pddsPrimary4); + pScreenPriv->pddsPrimary4 = NULL; + } + + /* Free the DirectDraw4 object, if there is one */ + if (pScreenPriv->pdd4) + { + IDirectDraw4_RestoreDisplayMode (pScreenPriv->pdd4); + IDirectDraw4_Release (pScreenPriv->pdd4); + pScreenPriv->pdd4 = NULL; + } + + /* Free the DirectDraw object, if there is one */ + if (pScreenPriv->pdd) + { + IDirectDraw_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; + } + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Destroy the thread startup mutex */ + pthread_mutex_destroy (&pScreenPriv->pmServerStarted); +#endif + + /* 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 +winInitVisualsShadowDDNL (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 == 0 || dwGreenBits == 0 || dwBlueBits == 0) + pScreenPriv->dwBitsPerRGB = 8; + else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + winDebug ("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d " + "bpp %d\n", + (unsigned int) pScreenPriv->dwRedMask, + (unsigned int) pScreenPriv->dwGreenMask, + (unsigned int) pScreenPriv->dwBlueMask, + (int) pScreenPriv->dwBitsPerRGB, + (int) pScreenInfo->dwDepth, + (int) pScreenInfo->dwBPP); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: +#if defined(XFree86Server) + /* Setup the real visual */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + -1, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " + "failed for TrueColor\n"); + return FALSE; + } + +#ifdef XWIN_EMULATEPSEUDO + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!miSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + -1, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + 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, + pScreenPriv->dwBitsPerRGB, + pScreenInfo->fFullScreen + ? PseudoColor : StaticColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks " + "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: + ErrorF ("winInitVisualsShadowDDNL - Unknown screen depth\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winInitVisualsShadowDDNL - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Adjust the user proposed video mode + */ + +static Bool +winAdjustVideoModeShadowDDNL (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 ("winAdjustVideoModeShadowDDNL - 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 */ + winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - 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 */ + winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - FullScreen, using command " + "line bpp: %d\n", (int) pScreenInfo->dwBPP); + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Windowed, and GDI depth differs from -depth parameter */ + winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - Windowed, command line " + "bpp: %d, using bpp: %d\n", + (int) pScreenInfo->dwBPP, (int) dwBPP); + + /* We'll use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + + /* See if the shadow bitmap will be larger than the DIB size limit */ + if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP + >= WIN_DIB_MAXIMUM_SIZE) + { + winErrorFVerb (1, "winAdjustVideoModeShadowDDNL - Requested DirectDraw surface " + "will be larger than %d MB. The surface may fail to be " + "allocated on Windows 95, 98, or Me, due to a %d MB limit in " + "DIB size. This limit does not apply to Windows NT/2000, and " + "this message may be ignored on those platforms.\n", + WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); + } + + /* Release our DC */ + ReleaseDC (NULL, hdc); + + return TRUE; +} + + +/* + * Blt exposed regions to the screen + */ + +static Bool +winBltExposedRegionsShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RECT rcSrc, rcDest; + POINT ptOrigin; + HDC hdcUpdate; + PAINTSTRUCT ps; + HRESULT ddrval = DD_OK; + Bool fReturn = TRUE; + int i; + + /* Quite common case. The primary surface was lost (maybe because of depth + * change). Try to create a new primary surface. Bail out if this fails */ + if (pScreenPriv->pddsPrimary4 == NULL && pScreenPriv->fRetryCreateSurface && + !winCreatePrimarySurfaceShadowDDNL(pScreen)) + { + Sleep(100); + return FALSE; + } + if (pScreenPriv->pddsPrimary4 == NULL) + return FALSE; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); + if (hdcUpdate == NULL) + { + fReturn = FALSE; + ErrorF ("winBltExposedRegionsShadowDDNL - BeginPaint () returned " + "a NULL device context handle. Aborting blit attempt.\n"); + goto winBltExposedRegionsShadowDDNL_Exit; + } + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be entire shadow surface, as Blt should clip for us */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Try to regain the primary surface and blit again if we've lost it */ + for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) + { + /* Our Blt should be clipped to the invalidated region */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + if (ddrval == DDERR_SURFACELOST) + { + /* Surface was lost */ + winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - " + "IDirectDrawSurface4_Blt reported that the primary " + "surface was lost, trying to restore, retry: %d\n", i + 1); + + /* Try to restore the surface, once */ + + ddrval = IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4); + winDebug ("winBltExposedRegionsShadowDDNL - " + "IDirectDrawSurface4_Restore returned: "); + if (ddrval == DD_OK) + winDebug ("DD_OK\n"); + else if (ddrval == DDERR_WRONGMODE) + winDebug ("DDERR_WRONGMODE\n"); + else if (ddrval == DDERR_INCOMPATIBLEPRIMARY) + winDebug ("DDERR_INCOMPATIBLEPRIMARY\n"); + else if (ddrval == DDERR_UNSUPPORTED) + winDebug ("DDERR_UNSUPPORTED\n"); + else if (ddrval == DDERR_INVALIDPARAMS) + winDebug ("DDERR_INVALIDPARAMS\n"); + else if (ddrval == DDERR_INVALIDOBJECT) + winDebug ("DDERR_INVALIDOBJECT\n"); + else + winDebug ("unknown error: %08x\n", (unsigned int) ddrval); + + /* Loop around to try the blit one more time */ + continue; + } + else if (FAILED (ddrval)) + { + fReturn = FALSE; + winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - " + "IDirectDrawSurface4_Blt failed, but surface not " + "lost: %08x %d\n", + (unsigned int) ddrval, (int) ddrval); + goto winBltExposedRegionsShadowDDNL_Exit; + } + else + { + /* Success, stop looping */ + break; + } + } + + winBltExposedRegionsShadowDDNL_Exit: + /* EndPaint frees the DC */ + if (hdcUpdate != NULL) + EndPaint (pScreenPriv->hwndScreen, &ps); + return fReturn; +} + + +/* + * Do any engine-specific application-activation processing + */ + +static Bool +winActivateAppShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + + /* + * Do we have a surface? + * Are we active? + * Are we full screen? + */ + if (pScreenPriv != NULL + && pScreenPriv->pddsPrimary4 != NULL + && pScreenPriv->fActive) + { + /* Primary surface was lost, restore it */ + IDirectDrawSurface4_Restore (pScreenPriv->pddsPrimary4); + } + + return TRUE; +} + + +/* + * Reblit the shadow framebuffer to the screen. + */ + +static Bool +winRedrawScreenShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HRESULT ddrval = DD_OK; + RECT rcSrc, rcDest; + POINT ptOrigin; + + /* Get the origin of the window in the screen coords */ + ptOrigin.x = pScreenInfo->dwXOffset; + ptOrigin.y = pScreenInfo->dwYOffset; + MapWindowPoints (pScreenPriv->hwndScreen, + HWND_DESKTOP, + (LPPOINT)&ptOrigin, 1); + rcDest.left = ptOrigin.x; + rcDest.right = ptOrigin.x + pScreenInfo->dwWidth; + rcDest.top = ptOrigin.y; + rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight; + + /* Source can be entire shadow surface, as Blt should clip for us */ + rcSrc.left = 0; + rcSrc.top = 0; + rcSrc.right = pScreenInfo->dwWidth; + rcSrc.bottom = pScreenInfo->dwHeight; + + /* Redraw the whole window, to take account for the new colors */ + ddrval = IDirectDrawSurface4_Blt (pScreenPriv->pddsPrimary4, + &rcDest, + pScreenPriv->pddsShadow4, + &rcSrc, + DDBLT_WAIT, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () " + "failed: %08x\n", + (unsigned int) ddrval); + } + + return TRUE; +} + + +/* + * Realize the currently installed colormap + */ + +static Bool +winRealizeInstalledPaletteShadowDDNL (ScreenPtr pScreen) +{ + return TRUE; +} + + +/* + * Install the specified colormap + */ + +static Bool +winInstallColormapShadowDDNL (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* Install the DirectDraw palette on the primary surface */ + ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4, + pCmapPriv->lpDDPalette); + if (FAILED (ddrval)) + { + ErrorF ("winInstallColormapShadowDDNL - Failed installing the " + "DirectDraw palette.\n"); + return FALSE; + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; + + return TRUE; +} + + +/* + * Store the specified colors in the specified colormap + */ + +static Bool +winStoreColorsShadowDDNL (ColormapPtr pColormap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + HRESULT ddrval = DD_OK; + + /* Put the X colormap entries into the Windows logical palette */ + ddrval = IDirectDrawPalette_SetEntries (pCmapPriv->lpDDPalette, + 0, + pdefs[0].pixel, + ndef, + pCmapPriv->peColors + + pdefs[0].pixel); + if (FAILED (ddrval)) + { + ErrorF ("winStoreColorsShadowDDNL - SetEntries () failed: %08x\n", ddrval); + return FALSE; + } + + /* Don't install the DirectDraw palette if the colormap is not installed */ + if (pColormap != curpmap) + { + return TRUE; + } + + if (!winInstallColormapShadowDDNL (pColormap)) + { + ErrorF ("winStoreColorsShadowDDNL - Failed installing colormap\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap initialization procedure + */ + +static Bool +winCreateColormapShadowDDNL (ColormapPtr pColormap) +{ + HRESULT ddrval = DD_OK; + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + + /* Create a DirectDraw palette */ + ddrval = IDirectDraw4_CreatePalette (pScreenPriv->pdd4, + DDPCAPS_8BIT | DDPCAPS_ALLOW256, + pCmapPriv->peColors, + &pCmapPriv->lpDDPalette, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winCreateColormapShadowDDNL - CreatePalette failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Colormap destruction procedure + */ + +static Bool +winDestroyColormapShadowDDNL (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + HRESULT ddrval = DD_OK; + + /* + * Is colormap to be destroyed the default? + * + * Non-default colormaps should have had winUninstallColormap + * called on them before we get here. The default colormap + * will not have had winUninstallColormap called on it. Thus, + * we need to handle the default colormap in a special way. + */ + if (pColormap->flags & IsDefault) + { +#if CYGDEBUG + winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n"); +#endif + + /* + * FIXME: Walk the list of all screens, popping the default + * palette out of each screen device context. + */ + + /* Pop the palette out of the primary surface */ + ddrval = IDirectDrawSurface4_SetPalette (pScreenPriv->pddsPrimary4, + NULL); + if (FAILED (ddrval)) + { + ErrorF ("winDestroyColormapShadowDDNL - Failed freeing the " + "default colormap DirectDraw palette.\n"); + return FALSE; + } + + /* Clear our private installed colormap pointer */ + pScreenPriv->pcmapInstalled = NULL; + } + + /* Release the palette */ + IDirectDrawPalette_Release (pCmapPriv->lpDDPalette); + + /* Invalidate the colormap privates */ + pCmapPriv->lpDDPalette = NULL; + + return TRUE; +} + + +/* + * Set pointers to our engine specific functions + */ + +Bool +winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL; + pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL; + pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL; + pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL; + pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL; + pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL; + pScreenPriv->pwinRealizeInstalledPalette + = winRealizeInstalledPaletteShadowDDNL; + pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL; + pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL; + pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL; + pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; + pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL; + pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL; +#ifdef XWIN_MULTIWINDOW + pScreenPriv->pwinFinishCreateWindowsWindow + = winFinishCreateWindowsWindowDDNL; +#endif + + return TRUE; +} diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c new file mode 100644 index 000000000..04cc2f716 --- /dev/null +++ b/hw/xwin/winshadgdi.c @@ -0,0 +1,1324 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" + + +/* + * External symbols + */ + +#ifdef XWIN_MULTIWINDOW +extern DWORD g_dwCurrentThreadID; +#endif +extern HWND g_hDlgExit; + + +/* + * Local function prototypes + */ + +#ifdef XWIN_MULTIWINDOW +static wBOOL CALLBACK +winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam); + +static wBOOL CALLBACK +winRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam); +#endif + +static Bool +winAllocateFBShadowGDI (ScreenPtr pScreen); + +static void +winShadowUpdateGDI (ScreenPtr pScreen, + shadowBufPtr pBuf); + +static Bool +winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen); + +static Bool +winInitVisualsShadowGDI (ScreenPtr pScreen); + +static Bool +winAdjustVideoModeShadowGDI (ScreenPtr pScreen); + +static Bool +winBltExposedRegionsShadowGDI (ScreenPtr pScreen); + +static Bool +winActivateAppShadowGDI (ScreenPtr pScreen); + +static Bool +winRedrawScreenShadowGDI (ScreenPtr pScreen); + +static Bool +winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen); + +static Bool +winInstallColormapShadowGDI (ColormapPtr pColormap); + +static Bool +winStoreColorsShadowGDI (ColormapPtr pmap, + int ndef, + xColorItem *pdefs); + +static Bool +winCreateColormapShadowGDI (ColormapPtr pColormap); + +static Bool +winDestroyColormapShadowGDI (ColormapPtr pColormap); + + +/* + * Internal function to get the DIB format that is compatible with the screen + */ + +static +Bool +winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) +{ + winScreenPriv(pScreen); + HBITMAP hbmp; +#if CYGDEBUG + LPDWORD pdw = NULL; +#endif + + /* Create a memory bitmap compatible with the screen */ + hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1); + if (hbmp == NULL) + { + ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); + return FALSE; + } + + /* Initialize our bitmap info header */ + ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + pbmih->biSize = sizeof (BITMAPINFOHEADER); + + /* Get the biBitCount */ + if (!GetDIBits (pScreenPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*) pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); + DeleteObject (hbmp); + return FALSE; + } + +#if CYGDEBUG + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + + winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", + pdw[0], pdw[1], pdw[2]); +#endif + + /* Get optimal color table, or the optimal bitfields */ + if (!GetDIBits (pScreenPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*)pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits " + "failed\n"); + DeleteObject (hbmp); + return FALSE; + } + + /* Free memory */ + DeleteObject (hbmp); + + return TRUE; +} + + +/* + * Internal function to determine the GDI bits per rgb and bit masks + */ + +static +Bool +winQueryRGBBitsAndMasks (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + BITMAPINFOHEADER *pbmih = NULL; + Bool fReturn = TRUE; + LPDWORD pdw = NULL; + DWORD dwRedBits, dwGreenBits, dwBlueBits; + + /* Color masks for 8 bpp are standardized */ + if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) + { + /* + * RGB BPP for 8 bit palletes is always 8 + * and the color masks are always 0. + */ + pScreenPriv->dwBitsPerRGB = 8; + pScreenPriv->dwRedMask = 0x0L; + pScreenPriv->dwGreenMask = 0x0L; + pScreenPriv->dwBlueMask = 0x0L; + return TRUE; + } + + /* Color masks for 24 bpp are standardized */ + if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) + * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) + { + ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " + "returned 24 for the screen. Using default 24bpp masks.\n"); + + /* 8 bits per primary color */ + pScreenPriv->dwBitsPerRGB = 8; + + /* Set screen privates masks */ + pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; + pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; + pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; + + return TRUE; + } + + /* Allocate a bitmap header and color table */ + pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pbmih == NULL) + { + ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); + return FALSE; + } + + /* Get screen description */ + if (winQueryScreenDIBFormat (pScreen, pbmih)) + { + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + +#if CYGDEBUG + winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__, + pdw[0], pdw[1], pdw[2]); + winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, + pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes); + winDebug ("%s - Compression: %d %s\n", __FUNCTION__, + pbmih->biCompression, + (pbmih->biCompression == BI_RGB?"(BI_RGB)": + (pbmih->biCompression == BI_RLE8?"(BI_RLE8)": + (pbmih->biCompression == BI_RLE4?"(BI_RLE4)": + (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":"" + ))))); +#endif + + /* Handle BI_RGB case, which is returned by Wine */ + if (pbmih->biCompression == BI_RGB) + { + dwRedBits = 5; + dwGreenBits = 5; + dwBlueBits = 5; + + pScreenPriv->dwBitsPerRGB = 5; + + /* Set screen privates masks */ + pScreenPriv->dwRedMask = 0x7c00; + pScreenPriv->dwGreenMask = 0x03e0; + pScreenPriv->dwBlueMask = 0x001f; + } + else + { + /* Count the number of bits in each mask */ + dwRedBits = winCountBits (pdw[0]); + dwGreenBits = winCountBits (pdw[1]); + dwBlueBits = winCountBits (pdw[2]); + + /* Find maximum bits per red, green, blue */ + if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwRedBits; + else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) + pScreenPriv->dwBitsPerRGB = dwGreenBits; + else + pScreenPriv->dwBitsPerRGB = dwBlueBits; + + /* Set screen privates masks */ + pScreenPriv->dwRedMask = pdw[0]; + pScreenPriv->dwGreenMask = pdw[1]; + pScreenPriv->dwBlueMask = pdw[2]; + } + } + else + { + ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); + free (pbmih); + fReturn = FALSE; + } + + /* Free memory */ + free (pbmih); + + return fReturn; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Redraw all ---? + */ + +static wBOOL CALLBACK +winRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam) +{ + if (hwnd == (HWND)lParam) + return TRUE; + InvalidateRect (hwnd, NULL, FALSE); + UpdateWindow (hwnd); + return TRUE; +} + +static wBOOL CALLBACK +winRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam) +{ + BoxPtr pDamage = (BoxPtr)lParam; + RECT rcClient, rcDamage, rcRedraw; + POINT topLeft, bottomRight; + + if (IsIconic (hwnd)) + return TRUE; /* Don't care minimized windows */ + + /* Convert the damaged area from Screen coords to Client coords */ + topLeft.x = pDamage->x1; topLeft.y = pDamage->y1; + bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2; + topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN); + bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN); + topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN); + bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN); + ScreenToClient (hwnd, &topLeft); + ScreenToClient (hwnd, &bottomRight); + SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); + + GetClientRect (hwnd, &rcClient); + + if (IntersectRect (&rcRedraw, &rcClient, &rcDamage)) + { + InvalidateRect (hwnd, &rcRedraw, FALSE); + UpdateWindow (hwnd); + } + return TRUE; +} +#endif + + +/* + * Allocate a DIB for the shadow framebuffer GDI server + */ + +static Bool +winAllocateFBShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + BITMAPINFOHEADER *pbmih = NULL; + DIBSECTION dibsection; + Bool fReturn = TRUE; + + /* Get device contexts for the screen and shadow bitmap */ + pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); + pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen); + + /* Allocate bitmap info header */ + pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pbmih == NULL) + { + ErrorF ("winAllocateFBShadowGDI - malloc () failed\n"); + return FALSE; + } + + /* Query the screen format */ + fReturn = winQueryScreenDIBFormat (pScreen, pbmih); + + /* Describe shadow bitmap to be created */ + pbmih->biWidth = pScreenInfo->dwWidth; + pbmih->biHeight = -pScreenInfo->dwHeight; + + ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " + "depth: %d\n", + (int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount); + + /* Create a DI shadow bitmap with a bit pointer */ + pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen, + (BITMAPINFO *) pbmih, + DIB_RGB_COLORS, + (VOID**) &pScreenInfo->pfb, + NULL, + 0); + if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) + { + winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); + return FALSE; + } + else + { +#if CYGDEBUG + winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); +#endif + } + + /* Get information about the bitmap that was allocated */ + GetObject (pScreenPriv->hbmpShadow, + sizeof (dibsection), + &dibsection); + +#if CYGDEBUG || YES + /* Print information about bitmap allocated */ + winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " + "depth: %d size image: %d\n", + (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, + dibsection.dsBmih.biBitCount, + (int) dibsection.dsBmih.biSizeImage); +#endif + + /* Select the shadow bitmap into the shadow DC */ + SelectObject (pScreenPriv->hdcShadow, + pScreenPriv->hbmpShadow); + +#if CYGDEBUG + winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); +#endif + + /* Do a test blit from the shadow to the screen, I think */ + fReturn = BitBlt (pScreenPriv->hdcScreen, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + if (fReturn) + { +#if CYGDEBUG + winDebug ("winAllocateFBShadowGDI - Shadow blit success\n"); +#endif + } + else + { + winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n"); +#if 0 + return FALSE; +#else + /* ago: ignore this error. The blit fails with wine, but does not + * cause any problems later. */ + + fReturn = TRUE; +#endif + } + + /* Look for height weirdness */ + if (dibsection.dsBmih.biHeight < 0) + { + dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; + } + + /* Set screeninfo stride */ + pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage + / dibsection.dsBmih.biHeight) + * 8) / pScreenInfo->dwBPP; + +#if CYGDEBUG || YES + winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n", + (int) pScreenInfo->dwStride); +#endif + + /* See if the shadow bitmap will be larger than the DIB size limit */ + if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP + >= WIN_DIB_MAXIMUM_SIZE) + { + ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) " + "will be larger than %d MB. The surface may fail to be " + "allocated on Windows 95, 98, or Me, due to a %d MB limit in " + "DIB size. This limit does not apply to Windows NT/2000, and " + "this message may be ignored on those platforms.\n", + WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); + } + + /* Determine our color masks */ + if (!winQueryRGBBitsAndMasks (pScreen)) + { + ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n"); + return FALSE; + } + +#ifdef XWIN_MULTIWINDOW + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) + EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); +#endif + + return fReturn; +} + + +/* + * Blit the damaged regions of the shadow fb to the screen + */ + +static void +winShadowUpdateGDI (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + RegionPtr damage = &pBuf->damage; + DWORD dwBox = REGION_NUM_RECTS (damage); + BoxPtr pBox = REGION_RECTS (damage); + int x, y, w, h; + HRGN hrgnTemp = NULL, hrgnCombined = NULL; +#ifdef XWIN_UPDATESTATS + static DWORD s_dwNonUnitRegions = 0; + static DWORD s_dwTotalUpdates = 0; + static DWORD s_dwTotalBoxes = 0; +#endif + BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); + + /* + * Return immediately if the app is not active + * and we are fullscreen, or if we have a bad display depth + */ + if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) + || pScreenPriv->fBadDepth) return; + +#ifdef XWIN_UPDATESTATS + ++s_dwTotalUpdates; + s_dwTotalBoxes += dwBox; + + if (dwBox != 1) + { + ++s_dwNonUnitRegions; + ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox); + } + + if ((s_dwTotalUpdates % 100) == 0) + ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " + "nu: %d tu: %d\n", + (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, + s_dwTotalBoxes / s_dwTotalUpdates, + s_dwNonUnitRegions, s_dwTotalUpdates); +#endif /* XWIN_UPDATESTATS */ + + /* + * Handle small regions with multiple blits, + * handle large regions by creating a clipping region and + * doing a single blit constrained to that clipping region. + */ + if (!pScreenInfo->fMultiWindow && + (pScreenInfo->dwClipUpdatesNBoxes == 0 || + dwBox < pScreenInfo->dwClipUpdatesNBoxes)) + { + /* Loop through all boxes in the damaged region */ + while (dwBox--) + { + /* + * Calculate x offset, y offset, width, and height for + * current damage box + */ + x = pBox->x1; + y = pBox->y1; + w = pBox->x2 - pBox->x1; + h = pBox->y2 - pBox->y1; + + BitBlt (pScreenPriv->hdcScreen, + x, y, + w, h, + pScreenPriv->hdcShadow, + x, y, + SRCCOPY); + + /* Get a pointer to the next box */ + ++pBox; + } + } + else if (!pScreenInfo->fMultiWindow) + { + /* Compute a GDI region from the damaged region */ + hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + dwBox--; + pBox++; + while (dwBox--) + { + hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); + DeleteObject (hrgnTemp); + pBox++; + } + + /* Install the GDI region as a clipping region */ + SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); + DeleteObject (hrgnCombined); + hrgnCombined = NULL; + + /* + * Blit the shadow buffer to the screen, + * constrained to the clipping region. + */ + BitBlt (pScreenPriv->hdcScreen, + pBoxExtents->x1, pBoxExtents->y1, + pBoxExtents->x2 - pBoxExtents->x1, + pBoxExtents->y2 - pBoxExtents->y1, + pScreenPriv->hdcShadow, + pBoxExtents->x1, pBoxExtents->y1, + SRCCOPY); + + /* Reset the clip region */ + SelectClipRgn (pScreenPriv->hdcScreen, NULL); + } + +#ifdef XWIN_MULTIWINDOW + /* Redraw all multiwindow windows */ + if (pScreenInfo->fMultiWindow) + EnumThreadWindows (g_dwCurrentThreadID, + winRedrawDamagedWindowShadowGDI, + (LPARAM)pBoxExtents); +#endif +} + + +/* See Porting Layer Definition - p. 33 */ +/* + * We wrap whatever CloseScreen procedure was specified by fb; + * a pointer to said procedure is stored in our privates. + */ + +static Bool +winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + Bool fReturn; + +#if CYGDEBUG + winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n"); +#endif + + /* 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 shadow DC; which allows the bitmap to be freed */ + DeleteDC (pScreenPriv->hdcShadow); + + /* Free the shadow bitmap */ + DeleteObject (pScreenPriv->hbmpShadow); + + /* Free the screen DC */ + ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); + + /* Delete tray icon, if we have one */ + if (!pScreenInfo->fNoTrayIcon) + winDeleteNotifyIcon (pScreenPriv); + + /* Free the exit confirmation dialog box, if it exists */ + if (g_hDlgExit != NULL) + { + DestroyWindow (g_hDlgExit); + g_hDlgExit = NULL; + } + + /* Kill our window */ + if (pScreenPriv->hwndScreen) + { + DestroyWindow (pScreenPriv->hwndScreen); + pScreenPriv->hwndScreen = NULL; + } + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Destroy the thread startup mutex */ + pthread_mutex_destroy (&pScreenPriv->pmServerStarted); +#endif + + /* Invalidate 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 +winInitVisualsShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Display debugging information */ + ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " + "bpp %d\n", + (unsigned int) pScreenPriv->dwRedMask, + (unsigned int) pScreenPriv->dwGreenMask, + (unsigned int) pScreenPriv->dwBlueMask, + (int) pScreenPriv->dwBitsPerRGB, + (int) pScreenInfo->dwDepth, + (int) pScreenInfo->dwBPP); + + /* Create a single visual according to the Windows screen depth */ + switch (pScreenInfo->dwDepth) + { + case 24: + case 16: + case 15: +#if defined(XFree86Server) + /* Setup the real visual */ + if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, + TrueColorMask, + pScreenPriv->dwBitsPerRGB, + -1, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " + "failed\n"); + return FALSE; + } + +#ifdef XWIN_EMULATEPSEUDO + if (!pScreenInfo->fEmulatePseudo) + break; + + /* Setup a pseudocolor visual */ + if (!miSetVisualTypesAndMasks (8, + PseudoColorMask, + 8, + -1, + 0, + 0, + 0)) + { + ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " + "failed for PseudoColor\n"); + 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, + PseudoColor, + pScreenPriv->dwRedMask, + pScreenPriv->dwGreenMask, + pScreenPriv->dwBlueMask)) + { + ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " + "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: + ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n"); + return FALSE; + } + +#if CYGDEBUG + winDebug ("winInitVisualsShadowGDI - Returning\n"); +#endif + + return TRUE; +} + + +/* + * Adjust the proposed video mode + */ + +static Bool +winAdjustVideoModeShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + HDC hdc; + DWORD dwBPP; + + hdc = GetDC (NULL); + + /* We're in serious trouble if we can't get a DC */ + if (hdc == NULL) + { + ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n"); + return FALSE; + } + + /* Query GDI for current display depth */ + dwBPP = GetDeviceCaps (hdc, BITSPIXEL); + + /* 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 ("winAdjustVideoModeShadowGDI - Using Windows display " + "depth of %d bits per pixel\n", (int) dwBPP); + + /* Use GDI's depth */ + pScreenInfo->dwBPP = dwBPP; + } + else if (dwBPP != pScreenInfo->dwBPP) + { + /* Warn user if GDI depth is different than -depth parameter */ + ErrorF ("winAdjustVideoModeShadowGDI - 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); + hdc = NULL; + + return TRUE; +} + + +/* + * Blt exposed regions to the screen + */ + +static Bool +winBltExposedRegionsShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + winPrivCmapPtr pCmapPriv = NULL; + HDC hdcUpdate; + PAINTSTRUCT ps; + + /* BeginPaint gives us an hdc that clips to the invalidated region */ + hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); + + /* Realize the palette, if we have one */ + if (pScreenPriv->pcmapInstalled != NULL) + { + pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); + + SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE); + RealizePalette (hdcUpdate); + } + + /* Our BitBlt will be clipped to the invalidated region */ + BitBlt (hdcUpdate, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + + /* EndPaint frees the DC */ + EndPaint (pScreenPriv->hwndScreen, &ps); + +#ifdef XWIN_MULTIWINDOW + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) + EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, + (LPARAM)pScreenPriv->hwndScreen); +#endif + + return TRUE; +} + + +/* + * Do any engine-specific appliation-activation processing + */ + +static Bool +winActivateAppShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* + * 2004/04/12 - Harold - We perform the restoring or minimizing + * manually for ShadowGDI in fullscreen modes so that this engine + * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; + * if we do not do this then our fullscreen window will appear in the + * z-order when it is deactivated and it can be uncovered by resizing + * or minimizing another window that is on top of it, which is not how + * the DirectDraw engines work. Therefore we keep this code here to + * make sure that all engines work the same in fullscreen mode. + */ + + /* + * Are we active? + * Are we fullscreen? + */ + if (pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Activating, attempt to bring our window + * to the top of the display + */ + ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); + } + else if (!pScreenPriv->fActive + && pScreenInfo->fFullScreen) + { + /* + * Deactivating, stuff our window onto the + * task bar. + */ + ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); + } + + return TRUE; +} + + +/* + * Reblit the shadow framebuffer to the screen. + */ + +static Bool +winRedrawScreenShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Redraw the whole window, to take account for the new colors */ + BitBlt (pScreenPriv->hdcScreen, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + +#ifdef XWIN_MULTIWINDOW + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) + EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); +#endif + + return TRUE; +} + + + +/* + * Realize the currently installed colormap + */ + +static Bool +winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winPrivCmapPtr pCmapPriv = NULL; + +#if CYGDEBUG + winDebug ("winRealizeInstalledPaletteShadowGDI\n"); +#endif + + /* Don't do anything if there is not a colormap */ + if (pScreenPriv->pcmapInstalled == NULL) + { +#if CYGDEBUG + winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap " + "installed\n"); +#endif + return TRUE; + } + + pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); + + /* Realize our palette for the screen */ + if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR) + { + ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () " + "failed\n"); + return FALSE; + } + + /* Set the DIB color table */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + 0, + WIN_NUM_PALETTE_ENTRIES, + pCmapPriv->rgbColors) == 0) + { + ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " + "failed\n"); + return FALSE; + } + + return TRUE; +} + + +/* + * Install the specified colormap + */ + +static Bool +winInstallColormapShadowGDI (ColormapPtr pColormap) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + winCmapPriv(pColormap); + + /* + * Tell Windows to install the new colormap + */ + if (SelectPalette (pScreenPriv->hdcScreen, + pCmapPriv->hPalette, + FALSE) == NULL) + { + ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n"); + return FALSE; + } + + /* Realize the palette */ + if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen)) + { + ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n"); + return FALSE; + } + + /* Set the DIB color table */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + 0, + WIN_NUM_PALETTE_ENTRIES, + pCmapPriv->rgbColors) == 0) + { + ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); + return FALSE; + } + + /* Redraw the whole window, to take account for the new colors */ + BitBlt (pScreenPriv->hdcScreen, + 0, 0, + pScreenInfo->dwWidth, pScreenInfo->dwHeight, + pScreenPriv->hdcShadow, + 0, 0, + SRCCOPY); + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; + +#ifdef XWIN_MULTIWINDOW + /* Redraw all windows */ + if (pScreenInfo->fMultiWindow) + EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); +#endif + + return TRUE; +} + + +/* + * Store the specified colors in the specified colormap + */ + +static Bool +winStoreColorsShadowGDI (ColormapPtr pColormap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pColormap->pScreen; + winScreenPriv(pScreen); + winCmapPriv(pColormap); + ColormapPtr curpmap = pScreenPriv->pcmapInstalled; + + /* Put the X colormap entries into the Windows logical palette */ + if (SetPaletteEntries (pCmapPriv->hPalette, + pdefs[0].pixel, + ndef, + pCmapPriv->peColors + pdefs[0].pixel) == 0) + { + ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); + return FALSE; + } + + /* Don't install the Windows palette if the colormap is not installed */ + if (pColormap != curpmap) + { + return TRUE; + } + + /* Try to install the newly modified colormap */ + if (!winInstallColormapShadowGDI (pColormap)) + { + ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI " + "failed\n"); + return FALSE; + } + +#if 0 + /* Tell Windows that the palette has changed */ + RealizePalette (pScreenPriv->hdcScreen); + + /* Set the DIB color table */ + if (SetDIBColorTable (pScreenPriv->hdcShadow, + pdefs[0].pixel, + ndef, + pCmapPriv->rgbColors + pdefs[0].pixel) == 0) + { + ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); + return FALSE; + } + + /* Save a pointer to the newly installed colormap */ + pScreenPriv->pcmapInstalled = pColormap; +#endif + + return TRUE; +} + + +/* + * Colormap initialization procedure + */ + +static Bool +winCreateColormapShadowGDI (ColormapPtr pColormap) +{ + LPLOGPALETTE lpPaletteNew = NULL; + DWORD dwEntriesMax; + VisualPtr pVisual; + HPALETTE hpalNew = NULL; + winCmapPriv(pColormap); + + /* Get a pointer to the visual that the colormap belongs to */ + pVisual = pColormap->pVisual; + + /* Get the maximum number of palette entries for this visual */ + dwEntriesMax = pVisual->ColormapEntries; + + /* Allocate a Windows logical color palette with max entries */ + lpPaletteNew = malloc (sizeof (LOGPALETTE) + + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); + if (lpPaletteNew == NULL) + { + ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette " + "with %d entries\n", + (int) dwEntriesMax); + return FALSE; + } + + /* Zero out the colormap */ + ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE) + + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); + + /* Set the logical palette structure */ + lpPaletteNew->palVersion = 0x0300; + lpPaletteNew->palNumEntries = dwEntriesMax; + + /* Tell Windows to create the palette */ + hpalNew = CreatePalette (lpPaletteNew); + if (hpalNew == NULL) + { + ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n"); + free (lpPaletteNew); + return FALSE; + } + + /* Save the Windows logical palette handle in the X colormaps' privates */ + pCmapPriv->hPalette = hpalNew; + + /* Free the palette initialization memory */ + free (lpPaletteNew); + + return TRUE; +} + + +/* + * Colormap destruction procedure + */ + +static Bool +winDestroyColormapShadowGDI (ColormapPtr pColormap) +{ + winScreenPriv(pColormap->pScreen); + winCmapPriv(pColormap); + + /* + * Is colormap to be destroyed the default? + * + * Non-default colormaps should have had winUninstallColormap + * called on them before we get here. The default colormap + * will not have had winUninstallColormap called on it. Thus, + * we need to handle the default colormap in a special way. + */ + if (pColormap->flags & IsDefault) + { +#if CYGDEBUG + winDebug ("winDestroyColormapShadowGDI - Destroying default " + "colormap\n"); +#endif + + /* + * FIXME: Walk the list of all screens, popping the default + * palette out of each screen device context. + */ + + /* Pop the palette out of the device context */ + SelectPalette (pScreenPriv->hdcScreen, + GetStockObject (DEFAULT_PALETTE), + FALSE); + + /* Clear our private installed colormap pointer */ + pScreenPriv->pcmapInstalled = NULL; + } + + /* Try to delete the logical palette */ + if (DeleteObject (pCmapPriv->hPalette) == 0) + { + ErrorF ("winDestroyColormap - DeleteObject () failed\n"); + return FALSE; + } + + /* Invalidate the colormap privates */ + pCmapPriv->hPalette = NULL; + + return TRUE; +} + + +/* + * Set engine specific funtions + */ + +Bool +winSetEngineFunctionsShadowGDI (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + /* Set our pointers */ + pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; + pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; + pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; + pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; + pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; + if (pScreenInfo->fFullScreen) + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; + else + pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; + pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; + pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; + pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; + pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; + pScreenPriv->pwinRealizeInstalledPalette = + winRealizeInstalledPaletteShadowGDI; + pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; + pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; + pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; + pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; + pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; + pScreenPriv->pwinCreatePrimarySurface + = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; + pScreenPriv->pwinReleasePrimarySurface + = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; +#ifdef XWIN_MULTIWINDOW + pScreenPriv->pwinFinishCreateWindowsWindow = + (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; +#endif + + return TRUE; +} diff --git a/hw/xwin/wintrayicon.c b/hw/xwin/wintrayicon.c new file mode 100755 index 000000000..054a8e956 --- /dev/null +++ b/hw/xwin/wintrayicon.c @@ -0,0 +1,210 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Early Ehlinger + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <shellapi.h> +#include "winprefs.h" + +/* + * Initialize the tray icon + */ + +void +winInitNotifyIcon (winPrivScreenPtr pScreenPriv) +{ + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + NOTIFYICONDATA nid = {0}; + + nid.cbSize = sizeof (NOTIFYICONDATA); + nid.hWnd = pScreenPriv->hwndScreen; + nid.uID = pScreenInfo->dwScreen; + nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = (HICON)winTaskbarIcon (); + + /* Save handle to the icon so it can be freed later */ + pScreenPriv->hiconNotifyIcon = nid.hIcon; + + /* Set display and screen-specific tooltip text */ + snprintf (nid.szTip, + sizeof (nid.szTip), + PROJECT_NAME " Server - %s:%d", + display, + (int) pScreenInfo->dwScreen); + + /* Add the tray icon */ + if (!Shell_NotifyIcon (NIM_ADD, &nid)) + ErrorF ("winInitNotifyIcon - Shell_NotifyIcon Failed\n"); +} + + +/* + * Delete the tray icon + */ + +void +winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv) +{ + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + NOTIFYICONDATA nid = {0}; + +#if 0 + ErrorF ("winDeleteNotifyIcon\n"); +#endif + + nid.cbSize = sizeof (NOTIFYICONDATA); + nid.hWnd = pScreenPriv->hwndScreen; + nid.uID = pScreenInfo->dwScreen; + + /* Delete the tray icon */ + if (!Shell_NotifyIcon (NIM_DELETE, &nid)) + { + ErrorF ("winDeleteNotifyIcon - Shell_NotifyIcon failed\n"); + return; + } + + /* Free the icon that was loaded */ + if (pScreenPriv->hiconNotifyIcon != NULL + && DestroyIcon (pScreenPriv->hiconNotifyIcon) == 0) + { + ErrorF ("winDeleteNotifyIcon - DestroyIcon failed\n"); + } + pScreenPriv->hiconNotifyIcon = NULL; +} + + +/* + * Process messages intended for the tray icon + */ + +LRESULT +winHandleIconMessage (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam, + winPrivScreenPtr pScreenPriv) +{ +#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_MULTIWINDOW) + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; +#endif + + switch (lParam) + { + case WM_LBUTTONUP: + /* Restack and bring all windows to top */ + SetForegroundWindow (hwnd); + +#ifdef XWIN_MULTIWINDOWEXTWM + if (pScreenInfo->fMWExtWM) + winMWExtWMRestackWindows (pScreenInfo->pScreen); +#endif + break; + + case WM_LBUTTONDBLCLK: + /* Display Exit dialog box */ + winDisplayExitDialog (pScreenPriv); + break; + + case WM_RBUTTONUP: + { + POINT ptCursor; + HMENU hmenuPopup; + HMENU hmenuTray; + + /* Get cursor position */ + GetCursorPos (&ptCursor); + + /* Load tray icon menu resource */ + hmenuPopup = LoadMenu (g_hInstance, + MAKEINTRESOURCE(IDM_TRAYICON_MENU)); + if (!hmenuPopup) + ErrorF ("winHandleIconMessage - LoadMenu failed\n"); + + /* Get actual tray icon menu */ + hmenuTray = GetSubMenu (hmenuPopup, 0); + +#ifdef XWIN_MULTIWINDOW + /* Check for MultiWindow mode */ + if (pScreenInfo->fMultiWindow) + { + MENUITEMINFO mii = {0}; + + /* Root is shown, remove the check box */ + + /* Setup menu item info structure */ + mii.cbSize = sizeof (MENUITEMINFO); + mii.fMask = MIIM_STATE; + mii.fState = MFS_CHECKED; + + /* Unheck box if root is shown */ + if (pScreenPriv->fRootWindowShown) + mii.fState = MFS_UNCHECKED; + + /* Set menu state */ + SetMenuItemInfo (hmenuTray, ID_APP_HIDE_ROOT, FALSE, &mii); + } + else +#endif + { + /* Remove Hide Root Window button */ + RemoveMenu (hmenuTray, + ID_APP_HIDE_ROOT, + MF_BYCOMMAND); + } + + SetupRootMenu ((unsigned long)hmenuTray); + + /* + * NOTE: This three-step procedure is required for + * proper popup menu operation. Without the + * call to SetForegroundWindow the + * popup menu will often not disappear when you click + * outside of it. Without the PostMessage the second + * time you display the popup menu it might immediately + * disappear. + */ + SetForegroundWindow (hwnd); + TrackPopupMenuEx (hmenuTray, + TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, + ptCursor.x, ptCursor.y, + hwnd, + NULL); + PostMessage (hwnd, WM_NULL, 0, 0); + + /* Free menu */ + DestroyMenu (hmenuPopup); + } + break; + } + + return 0; +} diff --git a/hw/xwin/winvalargs.c b/hw/xwin/winvalargs.c new file mode 100755 index 000000000..038e097a5 --- /dev/null +++ b/hw/xwin/winvalargs.c @@ -0,0 +1,188 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "winmsg.h" + + +/* + * References to external symbols + */ + +extern int g_iNumScreens; +extern winScreenInfo g_ScreenInfo[]; +extern Bool g_fXdmcpEnabled; + + +/* + * Prototypes + */ + +Bool +winValidateArgs (void); + + +/* + * winValidateArgs - Look for invalid argument combinations + */ + +Bool +winValidateArgs (void) +{ + int i; + int iMaxConsecutiveScreen = 0; + BOOL fHasNormalScreen0 = 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 + */ + for (i = 0; i < MAXSCREENS; i++) + { + if (g_ScreenInfo[i].fExplicitScreen) + iMaxConsecutiveScreen = i + 1; + } + winErrorFVerb (2, "winValidateArgs - g_iNumScreens: %d " + "iMaxConsecutiveScreen: %d\n", + g_iNumScreens, iMaxConsecutiveScreen); + if (g_iNumScreens < iMaxConsecutiveScreen) + { + 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. Of " + "you can specify as many screens as you want from 0 up to " + "%d.\n", MAXSCREENS - 1); + 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/hw/xwin/winvideo.c b/hw/xwin/winvideo.c new file mode 100755 index 000000000..529ca76d3 --- /dev/null +++ b/hw/xwin/winvideo.c @@ -0,0 +1,210 @@ +/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> + +void +winInitVideo (ScreenPtr pScreen); + +/* + * winInitVideo - Initialize support for the X Video (Xv) Extension. + */ + +void +winInitVideo (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + if (pScreenInfo->dwBPP > 8) + { + + } + + +} + + + + + + + +#if 0 +#include "../xfree86/common/xf86.h" +#include "../Xext/xvdix.h" +#include "../xfree86/common/xf86xv.h" +#include <X11/extensions/Xv.h> +#endif + +#include "win.h" + + + +#if 0 +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 3 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} +}; + +#define NUM_IMAGES 4 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + XVIMAGE_UYVY +}; + + + +/* + * winInitVideo - Initialize support for the X Video (Xv) Extension. + */ + +void +winInitVideo (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + XF86VideoAdaptorPtr newAdaptor = NULL; + + if (pScreenInfo->dwBPP > 8) + { + newAdaptor = I810SetupImageVideo (pScreen); + I810InitOffscreenImages (pScreen); + } + + xf86XVScreenInit (pScreen, adaptors, 1); +} + + +static XF86VideoAdaptorPtr +winSetupImageVideo (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#if 0 + I810Ptr pI810 = I810PTR(pScrn); +#endif + XF86VideoAdaptorPtr adapt; + + if (!(adapt = xcalloc (1, sizeof(XF86VideoAdaptorRec)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = PROJECT_NAME " Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = NULL; + + adapt->pPortPrivates[0].ptr = NULL; + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; +#if 0 + adapt->StopVideo = I810StopVideo; + adapt->SetPortAttribute = I810SetPortAttribute; + adapt->GetPortAttribute = I810GetPortAttribute; + adapt->QueryBestSize = I810QueryBestSize; + adapt->PutImage = I810PutImage; + adapt->QueryImageAttributes = I810QueryImageAttributes; +#endif + +#if 0 + pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1); +#endif + pPriv->videoStatus = 0; + pPriv->brightness = 0; + pPriv->contrast = 64; + pPriv->linear = NULL; + pPriv->currentBuf = 0; + +#if 0 + /* gotta uninit this someplace */ + REGION_NULL(pScreen, &pPriv->clip); +#endif + +#if 0 + pI810->adaptor = adapt; + + pI810->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = I810BlockHandler; +#endif + +#if 0 + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); +#endif + +#if 0 + I810ResetVideo(pScrn); +#endif + + return adapt; +} +#endif diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c new file mode 100644 index 000000000..e1eece34a --- /dev/null +++ b/hw/xwin/winwakeup.c @@ -0,0 +1,71 @@ +/* + *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 <xwin-config.h> +#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); + } + } +} diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c new file mode 100755 index 000000000..6f4e2c97e --- /dev/null +++ b/hw/xwin/winwin32rootless.c @@ -0,0 +1,1092 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II + */ +/* + * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c + */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <winuser.h> +#define _WINDOWSWM_SERVER_ +#include "windowswmstr.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" +#include <X11/Xatom.h> + + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 + +#define ULW_COLORKEY 0x00000001 +#define ULW_ALPHA 0x00000002 +#define ULW_OPAQUE 0x00000004 +#define AC_SRC_ALPHA 0x01 + +/* + * Local function + */ + +DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND) +static void +winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame); + +/* + * Global variables + */ + +Bool g_fNoConfigureWindow = FALSE; + + +extern void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon); + +/* + * Internal function to get the DIB format that is compatible with the screen + * Fixme: Share code with winshadgdi.c + */ + +static +Bool +winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih) +{ + HBITMAP hbmp; +#if CYGMULTIWINDOW_DEBUG + LPDWORD pdw = NULL; +#endif + + /* Create a memory bitmap compatible with the screen */ + hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1); + if (hbmp == NULL) + { + ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n"); + return FALSE; + } + + /* Initialize our bitmap info header */ + ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + pbmih->biSize = sizeof (BITMAPINFOHEADER); + + /* Get the biBitCount */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*) pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n"); + DeleteObject (hbmp); + return FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + + winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n", + (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); +#endif + + /* Get optimal color table, or the optimal bitfields */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*)pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits " + "failed\n"); + DeleteObject (hbmp); + return FALSE; + } + + /* Free memory */ + DeleteObject (hbmp); + + return TRUE; +} + +static HRGN +winMWExtWMCreateRgnFromRegion (RegionPtr pShape) +{ + int nRects; + BoxPtr pRects, pEnd; + HRGN hRgn, hRgnRect; + + if (pShape == NULL) return NULL; + + nRects = REGION_NUM_RECTS(pShape); + pRects = REGION_RECTS(pShape); + + hRgn = CreateRectRgn (0, 0, 0, 0); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, 0, 0, (int) GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pEnd = pRects + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2); + if (hRgnRect == NULL) + { + ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2, + (int) GetLastError ()); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + (int) GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + return hRgn; +} + +static void +InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv) +{ + pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd); + pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen); + pRLWinPriv->hbmpShadow = NULL; + + /* Allocate bitmap info header */ + pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pRLWinPriv->pbmihShadow == NULL) + { + ErrorF ("InitWin32RootlessEngine - malloc () failed\n"); + return; + } + + /* Query the screen format */ + winMWExtWMQueryDIBFormat (pRLWinPriv, + pRLWinPriv->pbmihShadow); +} + +Bool +winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape) +{ +#define CLASS_NAME_LENGTH 512 + Bool fResult = TRUE; + win32RootlessWindowPtr pRLWinPriv; + WNDCLASSEX wc; + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + HICON hIcon; + HICON hIconSmall; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n", + newX, newY, pFrame->width, pFrame->height); +#endif + + pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec)); + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->pfb = NULL; + pRLWinPriv->hbmpShadow = NULL; + pRLWinPriv->hdcShadow = NULL; + pRLWinPriv->hdcScreen = NULL; + pRLWinPriv->pbmihShadow = NULL; + pRLWinPriv->fResized = TRUE; + pRLWinPriv->fClose = FALSE; + pRLWinPriv->fRestackingNow = FALSE; + pRLWinPriv->fDestroyed = FALSE; + pRLWinPriv->fMovingOrSizing = FALSE; + + // Store the implementation private frame ID + pFrame->wid = (RootlessFrameID) pRLWinPriv; + + winSelectIcons(pFrame->win, &hIcon, &hIconSmall); + + /* Set standard class name prefix so we can identify window easily */ + strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass)); + + if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class)) + { + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); + + /* Check if a window class is provided by the WM_WINDOW_ROLE property, + * if not use the WM_CLASS information. + * For further information see: + * http://tronche.com/gui/x/icccm/sec-5.html + */ + if (winMultiWindowGetWindowRole (pFrame->win, &res_role) ) + { + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); + } + + free (res_name); + free (res_class); + } + + /* Add incrementing window ID to make unique class name */ + snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++); + pszWindowID[sizeof(pszWindowID)-1] = 0; + strcat (pszClass, pszWindowID); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass); +#endif + + /* Setup our window class */ + wc.cbSize = sizeof(wc); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winMWExtWMWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = hIcon; + wc.hIconSm = hIconSmall; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = pszClass; + RegisterClassEx (&wc); + + /* Create the window */ + g_fNoConfigureWindow = TRUE; + pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_POPUP | WS_CLIPCHILDREN, + newX, /* Horizontal position */ + newY, /* Vertical position */ + pFrame->width, /* Right edge */ + pFrame->height, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pRLWinPriv); /* ScreenPrivates */ + if (pRLWinPriv->hWnd == NULL) + { + ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + fResult = FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame - ShowWindow\n"); +#endif + + //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + g_fNoConfigureWindow = FALSE; + + if (pShape != NULL) + { + winMWExtWMReshapeFrame (pFrame->wid, pShape); + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n", + (int) pFrame->wid, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + } + } +#endif +#endif + + winMWExtWMSetNativeProperty (pFrame); + + return fResult; +} + +void +winMWExtWMDestroyFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HICON hiconClass; + HICON hiconSmClass; + HMODULE hInstance; + int iReturn; + char pszClass[CLASS_NAME_LENGTH]; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + *(int*)0 = 1;//raise exseption + } + } +#endif +#endif + + /* Store the info we need to destroy after this window is gone */ + hInstance = (HINSTANCE) GetClassLong (pRLWinPriv->hWnd, GCL_HMODULE); + hiconClass = (HICON) GetClassLong (pRLWinPriv->hWnd, GCL_HICON); + hiconSmClass = (HICON) GetClassLong (pRLWinPriv->hWnd, GCL_HICONSM); + iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH); + + pRLWinPriv->fClose = TRUE; + pRLWinPriv->fDestroyed = TRUE; + + /* Destroy the Windows window */ + DestroyWindow (pRLWinPriv->hWnd); + + /* Only if we were able to get the name */ + if (iReturn) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass); +#endif + iReturn = UnregisterClass (pszClass, hInstance); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn); +#endif + + winDestroyIcon(hiconClass); + winDestroyIcon(hiconSmClass); + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame - done\n"); +#endif +} + +void +winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY, iWidth, iHeight; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY); +#endif + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pRLWinPriv->pFrame->width; + iHeight = pRLWinPriv->pFrame->height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + g_fNoConfigureWindow = TRUE; + SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); + g_fNoConfigureWindow = FALSE; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv); +#endif +} + +void +winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int iNewX, int iNewY, + unsigned int uiNewWidth, unsigned int uiNewHeight, + unsigned int uiGravity) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + RECT rcOld; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n", + (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight); +#endif + + pRLWinPriv->fResized = TRUE; + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight); + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + /* Get a rectangle describing the old Windows window */ + GetWindowRect (pRLWinPriv->hWnd, &rcOld); + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { + + g_fNoConfigureWindow = TRUE; + MoveWindow (pRLWinPriv->hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + g_fNoConfigureWindow = FALSE; + } +} + +void +winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid; + winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen); + winScreenInfo *pScreenInfo = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + HWND hWnd; + Bool fFirst = TRUE; + Bool fNeedRestack = TRUE; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv); +#endif + + if (pScreenPriv->fRestacking) return; + + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + + pRLWinPriv->fRestackingNow = TRUE; + + /* Show window */ + if(!IsWindowVisible (pRLWinPriv->hWnd)) + ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + + if (pRLNextWinPriv == NULL) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is top\n", pRLWinPriv); +#endif + pScreenPriv->widTop = wid; + SetWindowPos (pRLWinPriv->hWnd, HWND_TOP, + 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else if (winIsInternalWMRunning(pScreenInfo)) + { + /* using mulwinidow wm */ +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is not top\n", pRLWinPriv); +#endif + for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV); + fNeedRestack && hWnd != NULL; + hWnd = GetNextWindow (hWnd, GW_HWNDPREV)) + { + GetWindowThreadProcessId (hWnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == pRLNextWinPriv->hWnd) + { + /* Enable interleave X window and Windows window */ + if (!fFirst) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv); +#endif + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("No change\n"); +#endif + } + fNeedRestack = FALSE; + break; + } + if (fFirst) fFirst = FALSE; + } + } + + for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT); + fNeedRestack && hWnd != NULL; + hWnd = GetNextWindow (hWnd, GW_HWNDNEXT)) + { + GetWindowThreadProcessId (hWnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == pRLNextWinPriv->hWnd) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv); +#endif + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + fNeedRestack = FALSE; + break; + } + } + } + } + else + { + /* using general wm like twm, wmaker etc. + Interleave X window and Windows window will cause problem. */ + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); +#if 0 +#endif + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv); +#endif + + pRLWinPriv->fRestackingNow = FALSE; +} + +void +winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HRGN hRgn, hRgnWindow, hRgnClient; + RECT rcWindow, rcClient; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv); +#endif + + hRgn = winMWExtWMCreateRgnFromRegion (pShape); + + /* Create region for non-client area */ + GetWindowRect (pRLWinPriv->hWnd, &rcWindow); + GetClientRect (pRLWinPriv->hWnd, &rcClient); + MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); + OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top); + OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top); + OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top); + hRgnWindow = CreateRectRgnIndirect (&rcWindow); + hRgnClient = CreateRectRgnIndirect (&rcClient); + CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF); + CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR); + + + SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE); + + DeleteObject (hRgnWindow); + DeleteObject (hRgnClient); +} + +void +winMWExtWMUnmapFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv); +#endif + + g_fNoConfigureWindow = TRUE; + //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE); + ShowWindow (pRLWinPriv->hWnd, SW_HIDE); + g_fNoConfigureWindow = FALSE; +} + +/* + * Fixme: Code sharing with winshadgdi.c and other engine support + */ +void +winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + ScreenPtr pScreen = NULL; + DIBSECTION dibsection; + Bool fReturn = TRUE; + HDC hdcNew; + HBITMAP hbmpNew; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed); +#endif + + if (!pRLWinPriv->fDestroyed) + { + pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv); + winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo); + winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width, + (int) pRLWinPriv->pFrame->height); +#endif + if (pRLWinPriv->hdcScreen == NULL) + { + InitWin32RootlessEngine (pRLWinPriv); + } + + if (pRLWinPriv->fResized) + { + /* width * bpp must be multiple of 4 to match 32bit alignment */ + int stridesize; + int misalignment; + + pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width; + pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height; + + stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3); + misalignment = stridesize & 3; + if (misalignment != 0) + { + stridesize += 4 - misalignment; + pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3); + winDebug("\tresizing to %d (was %d)\n", + pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width); + } + + hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen); + /* Create a DI shadow bitmap with a bit pointer */ + hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen, + (BITMAPINFO *) pRLWinPriv->pbmihShadow, + DIB_RGB_COLORS, + (VOID**) &pRLWinPriv->pfb, + NULL, + 0); + if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) + { + ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n"); + //return FALSE; + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n"); +#endif + } + + /* Get information about the bitmap that was allocated */ + GetObject (hbmpNew, sizeof (dibsection), &dibsection); + +#if CYGMULTIWINDOW_DEBUG + /* Print information about bitmap allocated */ + winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d " + "depth: %d size image: %d\n", + (unsigned int)dibsection.dsBmih.biWidth, + (unsigned int)dibsection.dsBmih.biHeight, + (unsigned int)dibsection.dsBmih.biBitCount, + (unsigned int)dibsection.dsBmih.biSizeImage); +#endif + + /* Select the shadow bitmap into the shadow DC */ + SelectObject (hdcNew, hbmpNew); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n"); +#endif + + /* Blit from the old shadow to the new shadow */ + fReturn = BitBlt (hdcNew, + 0, 0, + pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height, + pRLWinPriv->hdcShadow, + 0, 0, + SRCCOPY); + if (fReturn) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Shadow blit success\n"); +#endif + } + else + { + ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n"); + } + + /* Look for height weirdness */ + if (dibsection.dsBmih.biHeight < 0) + { + /* FIXME: Figure out why biHeight is sometimes negative */ + ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " + "biHeight still negative: %d\n", + (int) dibsection.dsBmih.biHeight); + ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " + "Flipping biHeight sign\n"); + dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; + } + + pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n", + (unsigned int)dibsection.dsBm.bmWidthBytes); +#endif + + /* Free the old shadow bitmap */ + DeleteObject (pRLWinPriv->hdcShadow); + DeleteObject (pRLWinPriv->hbmpShadow); + + pRLWinPriv->hdcShadow = hdcNew; + pRLWinPriv->hbmpShadow = hbmpNew; + + pRLWinPriv->fResized = FALSE; +#if CYGMULTIWINDOW_DEBUG && FALSE + winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n", + (unsigned int)pRLWinPriv->pfb, + (unsigned int)dibsection.dsBm.bmWidthBytes); +#endif + } + } + else + { + ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n"); + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n", + (int) pRLWinPriv, + (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes); +#endif + *pixelData = pRLWinPriv->pfb; + *bytesPerRow = pRLWinPriv->dwWidthBytes; +} + +void +winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush) +{ +#if 0 + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#if CYGMULTIWINDOW_DEBUG || TRUE + winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv); +#endif + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n"); + } +#endif +} + +void +winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if 0 + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#endif +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv); +#endif +#if 0 + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + LPVOID lpMsgBuf; + + /* Display a fancy error message */ + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } +#endif + if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); +} + +void +winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, + int shift_x, int shift_y) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n", + pRLWinPriv, nCount, pRects, shift_x, shift_y); +#endif + + for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { + RECT rcDmg; + rcDmg.left = pRects->x1 + shift_x; + rcDmg.top = pRects->y1 + shift_y; + rcDmg.right = pRects->x2 + shift_x; + rcDmg.bottom = pRects->y2 + shift_y; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +} + +void +winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#endif + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->fResized = TRUE; + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_CLIPCHILDREN); + + DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ()); + winMWExtWMSetNativeProperty (pFrame); +#if CYGMULTIWINDOW_DEBUG +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + } + } +#endif +#endif +} + +void +winMWExtWMCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes) +{ +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyBytes - Not implemented\n"); +#endif +} + +void +winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value, + void *dst, unsigned int dstRowBytes) +{ +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMFillBytes - Not implemented\n"); +#endif +} + +int +winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function, + void *src[2], unsigned int srcRowBytes[2], + void *mask, unsigned int maskRowBytes, + void *dst[2], unsigned int dstRowBytes[2]) +{ +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCompositePixels - Not implemented\n"); +#endif + return 0; +} + + +void +winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects, + int nDx, int nDy) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; + RECT rcDmg; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n", + (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); +#endif + + for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pDstRects->x1 + nDx, + pDstRects->y1 + nDy); +#endif + + if (!BitBlt (pRLWinPriv->hdcShadow, + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pRLWinPriv->hdcShadow, + pDstRects->x1 + nDx, pDstRects->y1 + nDy, + SRCCOPY)) + { + ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n"); + } + + rcDmg.left = pDstRects->x1; + rcDmg.top = pDstRects->y1; + rcDmg.right = pDstRects->x2; + rcDmg.bottom = pDstRects->y2; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyWindow - done\n"); +#endif +} + + +/* + * winMWExtWMSetNativeProperty + */ + +static void +winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; + long lData; + + /* FIXME: move this to WindowsWM extension */ + + lData = (long) pRLWinPriv->hWnd; + dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(), + XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); +} diff --git a/hw/xwin/winwin32rootlesswindow.c b/hw/xwin/winwin32rootlesswindow.c new file mode 100755 index 000000000..dedcd7a76 --- /dev/null +++ b/hw/xwin/winwin32rootlesswindow.c @@ -0,0 +1,476 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include "winprefs.h" + +#if 0 +/* + * winMWExtWMReorderWindows + */ + +void +winMWExtWMReorderWindows (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + HWND hwnd = NULL; + win32RootlessWindowPtr pRLWin = NULL; + win32RootlessWindowPtr pRLWinSib = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + XID vlist[2]; + +#if CYGMULTIWINDOW_DEBUG && FALSE + winDebug ("winMWExtWMReorderWindows\n"); +#endif + + pScreenPriv->fRestacking = TRUE; + + if (pScreenPriv->fWindowOrderChanged) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMReorderWindows - Need to restack\n"); +#endif + hwnd = GetTopWindow (NULL); + + while (hwnd) + { + GetWindowThreadProcessId (hwnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hwnd, WIN_WINDOW_PROP)) + { + pRLWinSib = pRLWin; + pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP); + + if (pRLWinSib) + { + vlist[0] = pRLWinSib->pFrame->win->drawable.id; + vlist[1] = Below; + + ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode, + vlist, wClient(pRLWin->pFrame->win)); + } + else + { + /* 1st window - raise to the top */ + vlist[0] = Above; + + ConfigureWindow (pRLWin->pFrame->win, CWStackMode, + vlist, wClient(pRLWin->pFrame->win)); + } + } + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); + } + } + + pScreenPriv->fRestacking = FALSE; + pScreenPriv->fWindowOrderChanged = FALSE; +} +#endif + + +/* + * winMWExtWMMoveXWindow + */ + +void +winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y) +{ + CARD32 *vlist = malloc(sizeof(CARD32)*2); + + vlist[0] = x; + vlist[1] = y; + ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + free(vlist); +} + + +/* + * winMWExtWMResizeXWindow + */ + +void +winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h) +{ + CARD32 *vlist = malloc(sizeof(CARD32)*2); + + vlist[0] = w; + vlist[1] = h; + ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin)); + free(vlist); +} + + +/* + * winMWExtWMMoveResizeXWindow + */ + +void +winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h) +{ + CARD32 *vlist = malloc(sizeof(long)*4); + + vlist[0] = x; + vlist[1] = y; + vlist[2] = w; + vlist[3] = h; + + ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin)); + free(vlist); +} + + +/* + * winMWExtWMUpdateIcon + * Change the Windows window icon + */ + +void +winMWExtWMUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hiconOld; + + pWin = (WindowPtr) LookupIDByType (id, RT_WINDOW); + hIcon = (HICON)winOverrideIcon ((unsigned long)pWin); + + if (!hIcon) + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + + if (hIcon) + { + win32RootlessWindowPtr pRLWinPriv + = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + + if (pRLWinPriv->hWnd) + { + hiconOld = (HICON) SetClassLong (pRLWinPriv->hWnd, + GCL_HICON, + (int) hIcon); + + winDestroyIcon(hiconOld); + } + } +} + + +/* + * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows. + */ + +wBOOL CALLBACK +winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam) +{ + win32RootlessWindowPtr pRLWinPriv = NULL; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) + { + pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo); + } + return TRUE; +} + + +/* + * winMWExtWMUpdateWindowDecoration - Update window style. + */ + +void +winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, + winScreenInfoPtr pScreenInfo) +{ + Bool fDecorate = FALSE; + DWORD dwExStyle = 0; + DWORD dwStyle = 0; + WINDOWPLACEMENT wndPlace; + UINT showCmd = 0; + + wndPlace.length = sizeof (WINDOWPLACEMENT); + + /* Get current window placement */ + GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace); + + if (winIsInternalWMRunning(pScreenInfo)) + { + if (!pRLWinPriv->pFrame->win->overrideRedirect) + fDecorate = TRUE; + } +#if 0 + if (wndPlace.showCmd == SW_HIDE) + return;//showCmd = SWP_HIDEWINDOW; + else + showCmd = SWP_SHOWWINDOW; +#else + if (wndPlace.showCmd == SW_HIDE) + return; + + if (IsWindowVisible (pRLWinPriv->hWnd)) + showCmd = SWP_SHOWWINDOW; +#endif + + showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER; + + winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n", + (int)pRLWinPriv, fDecorate?"Decorate":"Bare"); + + /* Get the standard and extended window style information */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + if (fDecorate) + { + RECT rcNew; + int iDx, iDy; + winWMMessageRec wmMsg; + winScreenPriv(pScreenInfo->pScreen); + + /* */ + if (!(dwExStyle & WS_EX_APPWINDOW)) + { + winDebug ("\tBare=>Decorate\n"); + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pRLWinPriv->pFrame->x, + pRLWinPriv->pFrame->y, + pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, + pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + FALSE, + WS_EX_APPWINDOW); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* Calculate position deltas */ + iDx = pRLWinPriv->pFrame->x - rcNew.left; + iDy = pRLWinPriv->pFrame->y - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindowStyle: %08x %08x\n", + WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, + WS_EX_APPWINDOW); +#endif + /* Position the Windows window */ +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + SetWindowPos (pRLWinPriv->hWnd, NULL, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + showCmd); + + + wmMsg.hwndWindow = pRLWinPriv->hWnd; + wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id; + wmMsg.msg = WM_WM_NAME_EVENT; + winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); + + winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , + wBoundingShape(pRLWinPriv->pFrame->win)); + } + } + else + { + RECT rcNew; + + /* */ + if (dwExStyle & WS_EX_APPWINDOW) + { + winDebug ("\tDecorate=>Bare\n"); + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, + pRLWinPriv->pFrame->x, + pRLWinPriv->pFrame->y, + pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, + pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); +#if 0 + /* */ + AdjustWindowRectEx (&rcNew, + WS_POPUP | WS_CLIPCHILDREN, + FALSE, + WS_EX_TOOLWINDOW); + + /* Calculate position deltas */ + iDx = pRLWinPriv->pFrame->x - rcNew.left; + iDy = pRLWinPriv->pFrame->y - rcNew.top; + + /* Calculate new rectangle */ + rcNew.left += iDx; + rcNew.right += iDx; + rcNew.top += iDy; + rcNew.bottom += iDy; +#endif + + /* Hide window temporary to remove from taskbar. */ + ShowWindow( pRLWinPriv->hWnd, SW_HIDE ); + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_CLIPCHILDREN); + + /* Position the Windows window */ + SetWindowPos (pRLWinPriv->hWnd, NULL, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + showCmd); + + winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , + wBoundingShape(pRLWinPriv->pFrame->win)); + } + } +} + + +/* + * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) + */ +Bool +winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) +{ + return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning; +} + + +/* + * winMWExtWMRestackWindows + */ + +void +winMWExtWMRestackWindows (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + WindowPtr pRoot = WindowTable[pScreen->myNum]; + WindowPtr pWin = NULL; + WindowPtr pWinPrev = NULL; + win32RootlessWindowPtr pRLWin = NULL; + win32RootlessWindowPtr pRLWinPrev = NULL; + int nWindow = 0; + HDWP hWinPosInfo = NULL; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackWindows\n"); +#endif + + pScreenPriv->fRestacking = TRUE; + + if (pRoot != NULL) + { + for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) + nWindow ++; + + hWinPosInfo = BeginDeferWindowPos(nWindow); + + for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) + { + if (pWin->realized) + { + UINT uFlags; + + pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + if (pRLWin == NULL) continue; + + if (pWinPrev) + pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE); + + uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW; + if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n", + pRLWin->hWnd, + pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP); +#endif + hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd, + pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP, + 0, 0, 0, 0, + uFlags); + if (hWinPosInfo == NULL) + { + ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n", + (int) GetLastError ()); + return; + } + pWinPrev = pWin; + } + } + if (!EndDeferWindowPos (hWinPosInfo)) + { + ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n", + (int) GetLastError ()); + return; + } + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackWindows - done\n"); +#endif + pScreenPriv->fRestacking = FALSE; +} diff --git a/hw/xwin/winwin32rootlesswndproc.c b/hw/xwin/winwin32rootlesswndproc.c new file mode 100755 index 000000000..859aafd29 --- /dev/null +++ b/hw/xwin/winwin32rootlesswndproc.c @@ -0,0 +1,1325 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include <winuser.h> +#define _WINDOWSWM_SERVER_ +#include "windowswmstr.h" +#include "dixevents.h" +#include "propertyst.h" +#include <X11/Xatom.h> +#include "winmultiwindowclass.h" +#include "winmsg.h" +#include "inputstr.h" + + +/* + * Constant defines + */ + +#define MOUSE_POLLING_INTERVAL 500 +#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; + WindowPtr pRoot = GetCurrentRootWindow (); + + 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; + WindowPtr pRoot = GetCurrentRootWindow (); + + 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 */ + miPointerAbsoluteCursor (ptMouse.x - pScreenInfo->dwXOffset, + ptMouse.y - pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + 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_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/hw/xwin/winwindow.c b/hw/xwin/winwindow.c new file mode 100644 index 000000000..1600996df --- /dev/null +++ b/hw/xwin/winwindow.c @@ -0,0 +1,649 @@ +/* + *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 + * Kensuke Matsuzaki + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + + +/* + * Prototypes for local functions + */ + +static int +winAddRgn (WindowPtr pWindow, pointer data); + +static +void +winUpdateRgnRootless (WindowPtr pWindow); + +#ifdef SHAPE +static +void +winReshapeRootless (WindowPtr pWin); +#endif + + +#ifdef XWIN_NATIVEGDI +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbCreateWindow() */ + +Bool +winCreateWindowNativeGDI (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winCreateWindowNativeGDI (%p)\n", pWin); +#endif + + WIN_UNWRAP(CreateWindow); + fResult = (*pScreen->CreateWindow) (pWin); + WIN_WRAP(CreateWindow, winCreateWindowNativeGDI); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbDestroyWindow() */ + +Bool +winDestroyWindowNativeGDI (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winDestroyWindowNativeGDI (%p)\n", pWin); +#endif + + WIN_UNWRAP(DestroyWindow); + fResult = (*pScreen->DestroyWindow)(pWin); + WIN_WRAP(DestroyWindow, winDestroyWindowNativeGDI); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbPositionWindow() */ + +Bool +winPositionWindowNativeGDI (WindowPtr pWin, int x, int y) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winPositionWindowNativeGDI (%p)\n", pWin); +#endif + + WIN_UNWRAP(PositionWindow); + fResult = (*pScreen->PositionWindow)(pWin, x, y); + WIN_WRAP(PositionWindow, winPositionWindowNativeGDI); + + return fResult; +} + + +/* See Porting Layer Definition - p. 39 */ +/* See mfb/mfbwindow.c - mfbCopyWindow() */ + +void +winCopyWindowNativeGDI (WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ + DDXPointPtr pptSrc; + DDXPointPtr ppt; + RegionPtr prgnDst; + BoxPtr pBox; + int dx, dy; + int i, nbox; + WindowPtr pwinRoot; + BoxPtr pBoxDst; + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if 0 + ErrorF ("winCopyWindow\n"); +#endif + + /* Get a pointer to the root window */ + pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; + + /* Create a region for the destination */ + prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1); + + /* Calculate the shift from the source to the destination */ + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + + /* Translate the region from the destination to the source? */ + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); + REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip, + prgnSrc); + + /* Get a pointer to the first box in the region to be copied */ + pBox = REGION_RECTS(prgnDst); + + /* Get the number of boxes in the region */ + nbox = REGION_NUM_RECTS(prgnDst); + + /* Allocate source points for each box */ + if(!(pptSrc = (DDXPointPtr )xalloc(nbox * sizeof(DDXPointRec)))) + return; + + /* Set an iterator pointer */ + ppt = pptSrc; + + /* Calculate the source point of each box? */ + for (i = nbox; --i >= 0; ppt++, pBox++) + { + ppt->x = pBox->x1 + dx; + ppt->y = pBox->y1 + dy; + } + + /* Setup loop pointers again */ + pBoxDst = REGION_RECTS(prgnDst); + ppt = pptSrc; + +#if 0 + ErrorF ("winCopyWindow - x1\tx2\ty1\ty2\tx\ty\n"); +#endif + + /* BitBlt each source to the destination point */ + for (i = nbox; --i >= 0; pBoxDst++, ppt++) + { +#if 0 + ErrorF ("winCopyWindow - %d\t%d\t%d\t%d\t%d\t%d\n", + pBoxDst->x1, pBoxDst->x2, pBoxDst->y1, pBoxDst->y2, + ppt->x, ppt->y); +#endif + + BitBlt (pScreenPriv->hdcScreen, + pBoxDst->x1, pBoxDst->y1, + pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1, + pScreenPriv->hdcScreen, + ppt->x, ppt->y, + SRCCOPY); + } + + /* Cleanup the regions, etc. */ + xfree(pptSrc); + REGION_DESTROY(pWin->drawable.pScreen, prgnDst); +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */ + +Bool +winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winChangeWindowAttributesNativeGDI (%p)\n", pWin); +#endif + + WIN_UNWRAP(ChangeWindowAttributes); + fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); + WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesNativeGDI); + + /* + * NOTE: We do not currently need to do anything here. + */ + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowNativeGDI (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winUnmapWindowNativeGDI (%p)\n", pWin); +#endif + + WIN_UNWRAP(UnrealizeWindow); + fResult = (*pScreen->UnrealizeWindow)(pWin); + WIN_WRAP(UnrealizeWindow, winUnmapWindowNativeGDI); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowNativeGDI (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winMapWindowNativeGDI (%p)\n", pWin); +#endif + + WIN_UNWRAP(RealizeWindow); + fResult = (*pScreen->RealizeWindow)(pWin); + WIN_WRAP(RealizeWindow, winMapWindowMultiWindow); + + return fResult; + +} +#endif + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbCreateWindow() */ + +Bool +winCreateWindowRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winCreateWindowRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(CreateWindow); + fResult = (*pScreen->CreateWindow) (pWin); + WIN_WRAP(CreateWindow, winCreateWindowRootless); + + pWinPriv->hRgn = NULL; + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbDestroyWindow() */ + +Bool +winDestroyWindowRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winDestroyWindowRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(DestroyWindow); + fResult = (*pScreen->DestroyWindow)(pWin); + WIN_WRAP(DestroyWindow, winDestroyWindowRootless); + + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + winUpdateRgnRootless (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbPositionWindow() */ + +Bool +winPositionWindowRootless (WindowPtr pWin, int x, int y) +{ + Bool fResult = FALSE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + +#if CYGDEBUG + winTrace ("winPositionWindowRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(PositionWindow); + fResult = (*pScreen->PositionWindow)(pWin, x, y); + WIN_WRAP(PositionWindow, winPositionWindowRootless); + + winUpdateRgnRootless (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 */ +/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */ + +Bool +winChangeWindowAttributesRootless (WindowPtr pWin, unsigned long mask) +{ + Bool fResult = FALSE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winChangeWindowAttributesRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(ChangeWindowAttributes); + fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); + WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless); + + winUpdateRgnRootless (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winUnmapWindowRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(UnrealizeWindow); + fResult = (*pScreen->UnrealizeWindow)(pWin); + WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless); + + if (pWinPriv->hRgn != NULL) + { + DeleteObject(pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + winUpdateRgnRootless (pWin); + + return fResult; +} + + +/* See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowRootless (WindowPtr pWin) +{ + Bool fResult = FALSE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winMapWindowRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(RealizeWindow); + fResult = (*pScreen->RealizeWindow)(pWin); + WIN_WRAP(RealizeWindow, winMapWindowRootless); + +#ifdef SHAPE + winReshapeRootless (pWin); +#endif + + winUpdateRgnRootless (pWin); + + return fResult; +} + + +#ifdef SHAPE +void +winSetShapeRootless (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGDEBUG + winTrace ("winSetShapeRootless (%p)\n", pWin); +#endif + + WIN_UNWRAP(SetShape); + (*pScreen->SetShape)(pWin); + WIN_WRAP(SetShape, winSetShapeRootless); + + winReshapeRootless (pWin); + winUpdateRgnRootless (pWin); + + return; +} +#endif + + +/* + * Local function for adding a region to the Windows window region + */ + +static +int +winAddRgn (WindowPtr pWin, pointer data) +{ + int iX, iY, iWidth, iHeight, iBorder; + HRGN hRgn = *(HRGN*)data; + HRGN hRgnWin; + winWindowPriv(pWin); + + /* If pWin is not Root */ + if (pWin->parent != NULL) + { +#if CYGDEBUG + winDebug ("winAddRgn ()\n"); +#endif + if (pWin->mapped) + { + iBorder = wBorderWidth (pWin); + + iX = pWin->drawable.x - iBorder; + iY = pWin->drawable.y - iBorder; + + iWidth = pWin->drawable.width + iBorder * 2; + iHeight = pWin->drawable.height + iBorder * 2; + + hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight); + + if (hRgnWin == NULL) + { + ErrorF ("winAddRgn - CreateRectRgn () failed\n"); + ErrorF (" Rect %d %d %d %d\n", + iX, iY, iX + iWidth, iY + iHeight); + } + + if (pWinPriv->hRgn) + { + if (CombineRgn (hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND) + == ERROR) + { + ErrorF ("winAddRgn - CombineRgn () failed\n"); + } + } + + OffsetRgn (hRgnWin, iX, iY); + + if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) + { + ErrorF ("winAddRgn - CombineRgn () failed\n"); + } + + DeleteObject (hRgnWin); + } + return WT_DONTWALKCHILDREN; + } + else + { + return WT_WALKCHILDREN; + } +} + + +/* + * Local function to update the Windows window's region + */ + +static +void +winUpdateRgnRootless (WindowPtr pWin) +{ + HRGN hRgn = CreateRectRgn (0, 0, 0, 0); + + if (hRgn != NULL) + { + WalkTree (pWin->drawable.pScreen, winAddRgn, &hRgn); + SetWindowRgn (winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen, + hRgn, TRUE); + } + else + { + ErrorF ("winUpdateRgnRootless - CreateRectRgn failed.\n"); + } +} + + +#ifdef SHAPE +static +void +winReshapeRootless (WindowPtr pWin) +{ + int nRects; + /* ScreenPtr pScreen = pWin->drawable.pScreen;*/ + RegionRec rrNewShape; + BoxPtr pShape, pRects, pEnd; + HRGN hRgn, hRgnRect; + winWindowPriv(pWin); + +#if CYGDEBUG + winDebug ("winReshapeRootless ()\n"); +#endif + + /* Bail if the window is the root window */ + if (pWin->parent == NULL) + return; + + /* Bail if the window is not top level */ + if (pWin->parent->parent != NULL) + return; + + /* Free any existing window region stored in the window privates */ + if (pWinPriv->hRgn != NULL) + { + DeleteObject (pWinPriv->hRgn); + pWinPriv->hRgn = NULL; + } + + /* Bail if the window has no bounding region defined */ + if (!wBoundingShape (pWin)) + return; + + REGION_NULL(pScreen, &rrNewShape); + REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth, + pWin->borderWidth); + + nRects = REGION_NUM_RECTS(&rrNewShape); + pShape = REGION_RECTS(&rrNewShape); + + if (nRects > 0) + { + /* Create initial empty Windows region */ + hRgn = CreateRectRgn (0, 0, 0, 0); + + /* Loop through all rectangles in the X region */ + for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1, pRects->y1, + pRects->x2, pRects->y2); + if (hRgnRect == NULL) + { + ErrorF("winReshapeRootless - CreateRectRgn() failed\n"); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF("winReshapeRootless - CombineRgn() failed\n"); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + /* Save a handle to the composite region in the window privates */ + pWinPriv->hRgn = hRgn; + } + + REGION_UNINIT(pScreen, &rrNewShape); + + return; +} +#endif diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h new file mode 100644 index 000000000..9c49d6482 --- /dev/null +++ b/hw/xwin/winwindow.h @@ -0,0 +1,150 @@ +#if !defined(_WINWINDOW_H_) +#define _WINWINDOW_H_ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + */ + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +/* Constant strings */ +#ifndef PROJECT_NAME +# define PROJECT_NAME "Cygwin/X" +#endif +#define WINDOW_CLASS "cygwin/x" +#define WINDOW_TITLE PROJECT_NAME " - %s:%d" +#define WINDOW_TITLE_XDMCP PROJECT_NAME " - %s" +#define WIN_SCR_PROP "cyg_screen_prop rl" +#define WINDOW_CLASS_X "cygwin/x X rl" +#define WINDOW_TITLE_X PROJECT_NAME " X" +#define WIN_WINDOW_PROP "cyg_window_prop_rl" +#ifdef HAS_DEVWINDOWS +# define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif +#define WIN_WID_PROP "cyg_wid_prop_rl" +#define WIN_NEEDMANAGE_PROP "cyg_override_redirect_prop_rl" +#ifndef CYGMULTIWINDOW_DEBUG +#define CYGMULTIWINDOW_DEBUG NO +#endif +#ifndef CYGWINDOWING_DEBUG +#define CYGWINDOWING_DEBUG NO +#endif + +typedef struct _winPrivScreenRec *winPrivScreenPtr; + + +/* + * Window privates + */ + +typedef struct +{ + DWORD dwDummy; + HRGN hRgn; + HWND hWnd; + winPrivScreenPtr pScreenPriv; + Bool fXKilled; + + /* Privates used by primary fb DirectDraw server */ + LPDDSURFACEDESC pddsdPrimary; + + /* Privates used by shadow fb DirectDraw Nonlocking server */ + LPDIRECTDRAWSURFACE4 pddsPrimary4; + + /* Privates used by both shadow fb DirectDraw servers */ + LPDIRECTDRAWCLIPPER pddcPrimary; +} winPrivWinRec, *winPrivWinPtr; + +#ifdef XWIN_MULTIWINDOW +typedef struct _winWMMessageRec{ + DWORD dwID; + DWORD msg; + int iWindow; + HWND hwndWindow; + int iX, iY; + int iWidth, iHeight; +} winWMMessageRec, *winWMMessagePtr; + + +/* + * winmultiwindowwm.c + */ + +#define WM_WM_MOVE (WM_USER + 1) +#define WM_WM_SIZE (WM_USER + 2) +#define WM_WM_RAISE (WM_USER + 3) +#define WM_WM_LOWER (WM_USER + 4) +#define WM_WM_MAP (WM_USER + 5) +#define WM_WM_UNMAP (WM_USER + 6) +#define WM_WM_KILL (WM_USER + 7) +#define WM_WM_ACTIVATE (WM_USER + 8) +#define WM_WM_NAME_EVENT (WM_USER + 9) +#define WM_WM_HINTS_EVENT (WM_USER + 10) +#define WM_WM_CHANGE_STATE (WM_USER + 11) +#define WM_MANAGE (WM_USER + 100) +#define WM_UNMANAGE (WM_USER + 102) + +void +winSendMessageToWM (void *pWMInfo, winWMMessagePtr msg); + +Bool +winInitWM (void **ppWMInfo, + pthread_t *ptWMProc, + pthread_t *ptXMsgProc, + pthread_mutex_t *ppmServerStarted, + int dwScreen, + HWND hwndScreen, + BOOL allowOtherWM); + +void +winDeinitMultiWindowWM (void); + +void +winMinimizeWindow (Window id); + + +/* + * winmultiwindowicons.c + */ + +void +winUpdateIcon (Window id); + +void +winInitGlobalIcons (void); + +void +winDestroyIcon(HICON hIcon); + +#endif /* XWIN_MULTIWINDOW */ +#endif diff --git a/hw/xwin/winwindowswm.c b/hw/xwin/winwindowswm.c new file mode 100755 index 000000000..e1994de84 --- /dev/null +++ b/hw/xwin/winwindowswm.c @@ -0,0 +1,663 @@ +/* WindowsWM extension is based on AppleWM extension */ +/************************************************************************** + +Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved. +Copyright (c) 2003 Torrey T. Lyons. 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, sub license, 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + +#define NEED_REPLIES +#define NEED_EVENTS +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#include "swaprep.h" +#define _WINDOWSWM_SERVER_ +#include "windowswmstr.h" + +static int WMErrorBase; + +static DISPATCH_PROC(ProcWindowsWMDispatch); +static DISPATCH_PROC(SProcWindowsWMDispatch); + +static void WindowsWMResetProc(ExtensionEntry* extEntry); + +static unsigned char WMReqCode = 0; +static int WMEventBase = 0; + +static RESTYPE ClientType, EventType; /* resource types for event masks */ +static XID eventResource; + +/* Currently selected events */ +static unsigned int eventMask = 0; + +static int WMFreeClient (pointer data, XID id); +static int WMFreeEvents (pointer data, XID id); +static void SNotifyEvent(xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to); + +typedef struct _WMEvent *WMEventPtr; +typedef struct _WMEvent { + WMEventPtr next; + ClientPtr client; + XID clientResource; + unsigned int mask; +} WMEventRec; + +static inline BoxRec +make_box (int x, int y, int w, int h) +{ + BoxRec r; + r.x1 = x; + r.y1 = y; + r.x2 = x + w; + r.y2 = y + h; + return r; +} + +void +winWindowsWMExtensionInit () +{ + ExtensionEntry* extEntry; + + ClientType = CreateNewResourceType(WMFreeClient); + EventType = CreateNewResourceType(WMFreeEvents); + eventResource = FakeClientID(0); + + if (ClientType && EventType && + (extEntry = AddExtension(WINDOWSWMNAME, + WindowsWMNumberEvents, + WindowsWMNumberErrors, + ProcWindowsWMDispatch, + SProcWindowsWMDispatch, + WindowsWMResetProc, + StandardMinorOpcode))) + { + WMReqCode = (unsigned char)extEntry->base; + WMErrorBase = extEntry->errorBase; + WMEventBase = extEntry->eventBase; + EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent; + } +} + +/*ARGSUSED*/ +static void +WindowsWMResetProc (ExtensionEntry* extEntry) +{ +} + +static int +ProcWindowsWMQueryVersion(register ClientPtr client) +{ + xWindowsWMQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = WINDOWS_WM_MAJOR_VERSION; + rep.minorVersion = WINDOWS_WM_MINOR_VERSION; + rep.patchVersion = WINDOWS_WM_PATCH_VERSION; + if (client->swapped) + { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + + +/* events */ + +static inline void +updateEventMask (WMEventPtr *pHead) +{ + WMEventPtr pCur; + + eventMask = 0; + for (pCur = *pHead; pCur != NULL; pCur = pCur->next) + eventMask |= pCur->mask; +} + +/*ARGSUSED*/ +static int +WMFreeClient (pointer data, XID id) +{ + WMEventPtr pEvent; + WMEventPtr *pHead, pCur, pPrev; + + pEvent = (WMEventPtr) data; + pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType); + if (pHead) + { + pPrev = 0; + for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next) + pPrev = pCur; + if (pCur) + { + if (pPrev) + pPrev->next = pEvent->next; + else + *pHead = pEvent->next; + } + updateEventMask (pHead); + } + xfree ((pointer) pEvent); + return 1; +} + +/*ARGSUSED*/ +static int +WMFreeEvents (pointer data, XID id) +{ + WMEventPtr *pHead, pCur, pNext; + + pHead = (WMEventPtr *) data; + for (pCur = *pHead; pCur; pCur = pNext) + { + pNext = pCur->next; + FreeResource (pCur->clientResource, ClientType); + xfree ((pointer) pCur); + } + xfree ((pointer) pHead); + eventMask = 0; + return 1; +} + +static int +ProcWindowsWMSelectInput (register ClientPtr client) +{ + REQUEST(xWindowsWMSelectInputReq); + WMEventPtr pEvent, pNewEvent, *pHead; + XID clientResource; + + REQUEST_SIZE_MATCH (xWindowsWMSelectInputReq); + pHead = (WMEventPtr *)SecurityLookupIDByType(client, eventResource, + EventType, DixWriteAccess); + if (stuff->mask != 0) + { + if (pHead) + { + /* check for existing entry. */ + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + if (pEvent->client == client) + { + pEvent->mask = stuff->mask; + updateEventMask (pHead); + return Success; + } + } + } + + /* build the entry */ + pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec)); + if (!pNewEvent) + return BadAlloc; + pNewEvent->next = 0; + pNewEvent->client = client; + pNewEvent->mask = stuff->mask; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pNewEvent->clientResource = clientResource; + if (!AddResource (clientResource, ClientType, (pointer)pNewEvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (!pHead) + { + pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr)); + if (!pHead || + !AddResource (eventResource, EventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pNewEvent->next = *pHead; + *pHead = pNewEvent; + updateEventMask (pHead); + } + else if (stuff->mask == 0) + { + /* delete the interest */ + if (pHead) + { + pNewEvent = 0; + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + if (pEvent->client == client) + break; + pNewEvent = pEvent; + } + if (pEvent) + { + FreeResource (pEvent->clientResource, ClientType); + if (pNewEvent) + pNewEvent->next = pEvent->next; + else + *pHead = pEvent->next; + xfree (pEvent); + updateEventMask (pHead); + } + } + } + else + { + client->errorValue = stuff->mask; + return BadValue; + } + return Success; +} + +/* + * deliver the event + */ + +void +winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, + Window window, int x, int y, int w, int h) +{ + WMEventPtr *pHead, pEvent; + ClientPtr client; + xWindowsWMNotifyEvent se; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWindowsWMSendEvent %d %d %d %d, %d %d - %d %d\n", + type, mask, which, arg, x, y, w, h); +#endif + pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType); + if (!pHead) + return; + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + client = pEvent->client; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWindowsWMSendEvent - x%08x\n", (int) client); +#endif + if ((pEvent->mask & mask) == 0 + || client == serverClient || client->clientGone) + { + continue; + } +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winWindowsWMSendEvent - send\n"); +#endif + se.type = type + WMEventBase; + se.kind = which; + se.window = window; + se.arg = arg; + se.x = x; + se.y = y; + se.w = w; + se.h = h; + se.sequenceNumber = client->sequence; + se.time = currentTime.milliseconds; + WriteEventsToClient (client, 1, (xEvent *) &se); + } +} + +/* Safe to call from any thread. */ +unsigned int +WindowsWMSelectedEvents (void) +{ + return eventMask; +} + + +/* general utility functions */ + +static int +ProcWindowsWMDisableUpdate (register ClientPtr client) +{ + REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq); + + //winDisableUpdate(); + + return (client->noClientException); +} + +static int +ProcWindowsWMReenableUpdate (register ClientPtr client) +{ + REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq); + + //winEnableUpdate(); + + return (client->noClientException); +} + + +/* window functions */ + +static int +ProcWindowsWMSetFrontProcess (register ClientPtr client) +{ + REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq); + + //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0); + + return (client->noClientException); +} + + +/* frame functions */ + +static int +ProcWindowsWMFrameGetRect (register ClientPtr client) +{ + xWindowsWMFrameGetRectReply rep; + BoxRec ir; + RECT rcNew; + REQUEST(xWindowsWMFrameGetRectReq); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameGetRect %d %d\n", + (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len); +#endif + + REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); + + if (stuff->frame_rect != 0) + { + ErrorF ("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n"); + return BadValue; + } + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, stuff->ix, stuff->iy, + stuff->ix + stuff->iw, stuff->iy + stuff->ih); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n", + stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih); +#endif + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); + rep.x = rcNew.left; + rep.y = rcNew.top; + rep.w = rcNew.right - rcNew.left; + rep.h = rcNew.bottom - rcNew.top; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n", + rep.x, rep.y, rep.w, rep.h); +#endif + + WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), (char *)&rep); + return (client->noClientException); +} + + +static int +ProcWindowsWMFrameDraw (register ClientPtr client) +{ + REQUEST(xWindowsWMFrameDrawReq); + WindowPtr pWin; + win32RootlessWindowPtr pRLWinPriv; + RECT rcNew; + int nCmdShow, rc; + RegionRec newShape; + ScreenPtr pScreen; + + REQUEST_SIZE_MATCH (xWindowsWMFrameDrawReq); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameDraw\n"); +#endif + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (rc != Success) + return rc; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameDraw - Window found\n"); +#endif + + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, TRUE); + if (pRLWinPriv == 0) return BadWindow; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameDraw - HWND 0x%08x 0x%08x 0x%08x\n", + (int) pRLWinPriv->hWnd, (int) stuff->frame_style, + (int) stuff->frame_style_ex); + ErrorF ("ProcWindowsWMFrameDraw - %d %d %d %d\n", + stuff->ix, stuff->iy, stuff->iw, stuff->ih); +#endif + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, stuff->ix, stuff->iy, + stuff->ix + stuff->iw, stuff->iy + stuff->ih); + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); + + /* Set the window extended style flags */ + if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex)) + { + return BadValue; + } + + /* Set the window standard style flags */ + if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style)) + { + return BadValue; + } + + /* Flush the window style */ + if (!SetWindowPos (pRLWinPriv->hWnd, NULL, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE)) + { + return BadValue; + } + if (!IsWindowVisible(pRLWinPriv->hWnd)) + nCmdShow = SW_HIDE; + else + nCmdShow = SW_SHOWNA; + + ShowWindow (pRLWinPriv->hWnd, nCmdShow); + + winMWExtWMUpdateIcon (pWin->drawable.id); + + if (wBoundingShape(pWin) != NULL) + { + pScreen = pWin->drawable.pScreen; + /* wBoundingShape is relative to *inner* origin of window. + Translate by borderWidth to get the outside-relative position. */ + + REGION_NULL(pScreen, &newShape); + REGION_COPY(pScreen, &newShape, wBoundingShape(pWin)); + REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth, pWin->borderWidth); + winMWExtWMReshapeFrame (pRLWinPriv, &newShape); + REGION_UNINIT(pScreen, &newShape); + } +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameDraw - done\n"); +#endif + + return (client->noClientException); +} + +static int +ProcWindowsWMFrameSetTitle( + register ClientPtr client + ) +{ + unsigned int title_length, title_max; + unsigned char *title_bytes; + REQUEST(xWindowsWMFrameSetTitleReq); + WindowPtr pWin; + win32RootlessWindowPtr pRLWinPriv; + int rc; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameSetTitle\n"); +#endif + + REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq); + + rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); + if (rc != Success) + return rc; +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameSetTitle - Window found\n"); +#endif + + title_length = stuff->title_length; + title_max = (stuff->length << 2) - sizeof(xWindowsWMFrameSetTitleReq); + + if (title_max < title_length) + return BadValue; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameSetTitle - length is valid\n"); +#endif + + title_bytes = malloc (title_length+1); + strncpy (title_bytes, (unsigned char *) &stuff[1], title_length); + title_bytes[title_length] = '\0'; + + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + + if (pRLWinPriv == 0) + { + free (title_bytes); + return BadWindow; + } + + /* Flush the window style */ + SetWindowText (pRLWinPriv->hWnd, title_bytes); + + free (title_bytes); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("ProcWindowsWMFrameSetTitle - done\n"); +#endif + + return (client->noClientException); +} + + +/* dispatch */ + +static int +ProcWindowsWMDispatch (register ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) + { + case X_WindowsWMQueryVersion: + return ProcWindowsWMQueryVersion(client); + } + + if (!LocalClient(client)) + return WMErrorBase + WindowsWMClientNotLocal; + + switch (stuff->data) + { + case X_WindowsWMSelectInput: + return ProcWindowsWMSelectInput(client); + case X_WindowsWMDisableUpdate: + return ProcWindowsWMDisableUpdate(client); + case X_WindowsWMReenableUpdate: + return ProcWindowsWMReenableUpdate(client); + case X_WindowsWMSetFrontProcess: + return ProcWindowsWMSetFrontProcess(client); + case X_WindowsWMFrameGetRect: + return ProcWindowsWMFrameGetRect(client); + case X_WindowsWMFrameDraw: + return ProcWindowsWMFrameDraw(client); + case X_WindowsWMFrameSetTitle: + return ProcWindowsWMFrameSetTitle(client); + default: + return BadRequest; + } +} + +static void +SNotifyEvent (xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to) +{ + to->type = from->type; + to->kind = from->kind; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->window, to->window); + cpswapl (from->time, to->time); + cpswapl (from->arg, to->arg); +} + +static int +SProcWindowsWMQueryVersion (register ClientPtr client) +{ + register int n; + REQUEST(xWindowsWMQueryVersionReq); + swaps(&stuff->length, n); + return ProcWindowsWMQueryVersion(client); +} + +static int +SProcWindowsWMDispatch (register ClientPtr client) +{ + REQUEST(xReq); + + /* It is bound to be non-local when there is byte swapping */ + if (!LocalClient(client)) + return WMErrorBase + WindowsWMClientNotLocal; + + /* only local clients are allowed WM access */ + switch (stuff->data) + { + case X_WindowsWMQueryVersion: + return SProcWindowsWMQueryVersion(client); + default: + return BadRequest; + } +} diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c new file mode 100644 index 000000000..29ea81fc1 --- /dev/null +++ b/hw/xwin/winwndproc.c @@ -0,0 +1,1288 @@ +/* + *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 <xwin-config.h> +#endif +#include "win.h" +#include <commctrl.h> +#include "winprefs.h" +#include "winconfig.h" +#include "winmsg.h" +#include "inputstr.h" + +#ifdef XKB +extern BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam); +#endif +extern void winFixShiftKeys (int iScanCode); + + +/* + * 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; + + /* Has the mouse pointer crossed screens? */ + if (s_pScreen != miPointerGetScreen(inputInfo.pointer)) + miPointerSetScreen (inputInfo.pointer, 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 */ + miPointerAbsoluteCursor (GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset, + GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset, + g_c32LastInputEventTime = GetTickCount ()); + return 0; + + case WM_NCMOUSEMOVE: + /* + * We break instead of returning 0 since we need to call + * DefWindowProc to get the mouse cursor changes + * and min/max/close button highlighting in Windows XP. + * The Platform SDK says that you should return 0 if you + * process this message, but it fails to mention that you + * will give up any default functionality if you do return 0. + */ + + /* We can't do anything without privates */ + if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) + break; + + /* Non-client mouse movement, show Windows cursor */ + if (g_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 */ + miPointerAbsoluteCursor (point.x, point.y, + g_c32LastInputEventTime = GetTickCount()); + + /* 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; + +#ifdef XKB + /* + * Discard presses generated from Windows auto-repeat + * ago: Only discard them if XKB is not disabled + */ + if (!g_winInfo.xkb.disable && (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; + } + } +#endif + + /* 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); +} diff --git a/hw/xwin/xlaunch/COPYING b/hw/xwin/xlaunch/COPYING new file mode 100755 index 000000000..c7fa84400 --- /dev/null +++ b/hw/xwin/xlaunch/COPYING @@ -0,0 +1,25 @@ + + 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. + diff --git a/hw/xwin/xlaunch/Makefile b/hw/xwin/xlaunch/Makefile new file mode 100755 index 000000000..f7cf923df --- /dev/null +++ b/hw/xwin/xlaunch/Makefile @@ -0,0 +1,79 @@ +# +# 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. +# +WINDRES=windres + +TARGET=mingw +#DEBUG_FLAGS=-D_DEBUG + +OS_FLAGS_mingw=-mno-cygwin +OS_FLAGS=$(OS_FLAGS_$(TARGET)) $(DEBUG_FLAGS) + +X11_DIR_$(TARGET)=/usr/X11R6 +X11_DIR_mingw=../../../../../exports +X11_DIR=$(X11_DIR_$(TARGET)) +X11_INCLUDE=-I$(X11_DIR)/include +X11_LIBDIR=-L$(X11_DIR)/lib +X11_LIBS_$(TARGET)=-lX11 +X11_LIBS_mingw=-lX11 -lwsock32 +X11_LIBS=$(X11_LIBS_$(TARGET)) + +PROGRAMFILES:=$(shell cygpath -u $(PROGRAMFILES)) +#MSXML_DIR=$(PROGRAMFILES)/MSXML 4.0 +MSXML_DIR=$(PROGRAMFILES)/Microsoft XML Parser SDK +MSXML_INCLUDE="-I$(MSXML_DIR)/inc" +MSXML_LIBDIR="-L$(MSXML_DIR)/lib" +MSXML_LIBS= + + +CXXFLAGS=-g $(OS_FLAGS) $(X11_INCLUDE) $(MSXML_INCLUDE) +LDFLAGS=-mwindows $(X11_LIBDIR) $(MSXML_LIBDIR) +LIBS=-lcomctl32 -lole32 -loleaut32 $(X11_LIBS) $(MSXML_LIBS) +all:xlaunch.exe +%.res: %.rc + $(WINDRES) -O coff -o $@ $< + +WINDOW_PARTS=window util dialog wizard +WINDOW_OBJECTS=$(foreach file,$(WINDOW_PARTS),window/$(file).o) + +RESOURCES_IMAGES=resources/multiwindow.bmp resources/fullscreen.bmp \ + resources/windowed.bmp resources/nodecoration.bmp + +resources/resources.res: resources/resources.rc resources/resources.h \ + resources/images.rc resources/dialog.rc resources/strings.rc \ + $(RESOURCES_IMAGES) +xlaunch.exe: $(WINDOW_OBJECTS) main.o config.o resources/resources.res + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + + +window/dialog.o: window/dialog.cc window/dialog.h window/window.h window/util.h +window/frame.o: window/frame.cc window/frame.h window/window.h +window/util.o: window/util.cc window/util.h +window/window.o: window/window.cc window/window.h window/util.h +window/wizard.o: window/wizard.cc window/wizard.h window/dialog.h \ + window/window.h window/util.h +main.o: main.cc window/util.h window/wizard.h window/dialog.h \ + window/window.h resources/resources.h config.h +config.o: config.cc config.h diff --git a/hw/xwin/xlaunch/config.cc b/hw/xwin/xlaunch/config.cc new file mode 100644 index 000000000..b6bf65ae3 --- /dev/null +++ b/hw/xwin/xlaunch/config.cc @@ -0,0 +1,282 @@ +/* + * 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. + */ +#include "config.h" +#include "window/util.h" +#include <msxml2.h> +#include <stdexcept> + +const CLSID CLSID_DOMDocument40 = {0x88d969c0,0xf192,0x11d4,0xa6,0x5f,0x00,0x40,0x96,0x32,0x51,0xe5}; +const CLSID CLSID_DOMDocument30 = {0xf5078f32,0xc551,0x11d3,0x89,0xb9,0x00,0x00,0xf8,0x1f,0xe2,0x21}; +const IID IID_IXMLDOMDocument2 = {0x2933BF95,0x7B36,0x11d2,0xB2,0x0E,0x00,0xC0,0x4F,0x98,0x3E,0x60}; + +#define HRCALL(x, msg) if (FAILED(x)) { throw std::runtime_error("OLE Error:" msg " failed"); }; + +char *wcconvert(const wchar_t *wstr) +{ + int chars = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + if (chars == 0) + throw win32_error("WideCharToMultiByte"); + char *mbstr = new char[chars]; + chars = WideCharToMultiByte(CP_ACP, 0, wstr, -1, mbstr, chars, NULL, NULL); + if (chars == 0) + throw win32_error("WideCharToMultiByte"); + return mbstr; +} + +wchar_t *mbconvert(const char *mbstr) +{ + int chars = MultiByteToWideChar(CP_ACP, 0, mbstr, -1, NULL, 0); + if (chars == 0) + throw win32_error("MultiByteToWideChar"); + wchar_t *wstr = new wchar_t[chars]; + chars = MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wstr, chars); + if (chars == 0) + throw win32_error("MultiByteToWideChar"); + return wstr; +} + +VARIANT VariantString(const char *filename) +{ + + wchar_t *str = mbconvert(filename); + + VARIANT var; + VariantInit(&var); + V_BSTR(&var) = SysAllocString(str); + V_VT(&var) = VT_BSTR; + + delete [] str; + return var; +} + +VARIANT VariantString(const wchar_t *str) +{ + VARIANT var; + VariantInit(&var); + V_BSTR(&var) = SysAllocString(str); + V_VT(&var) = VT_BSTR; + return var; +} + +IXMLDOMDocument2 *CreateDocument() +{ + IXMLDOMDocument2 *doc = NULL; + + CoInitialize(NULL); + + HRCALL(CoCreateInstance(CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER, + IID_IXMLDOMDocument2, (void**)&doc), "CoCreateInstance"); + + try { + HRCALL(doc->put_async(VARIANT_FALSE), "put_async"); + HRCALL(doc->put_validateOnParse(VARIANT_FALSE), "put_validateOnParse"); + HRCALL(doc->put_resolveExternals(VARIANT_FALSE), "put_resolveExternals"); + + IXMLDOMProcessingInstruction *pi = NULL; + IXMLDOMElement *root = NULL; + BSTR xml = SysAllocString(L"xml"); + BSTR ver = SysAllocString(L"version='1.0'"); + HRCALL(doc->createProcessingInstruction(xml,ver, &pi), + "createProcessingInstruction"); + HRCALL(doc->appendChild(pi, NULL), + "appendChild"); + pi->Release(); + SysFreeString(xml); + SysFreeString(ver); + + BSTR elemname = SysAllocString(L"XLaunch"); + HRCALL(doc->createElement(elemname, &root), "createElement"); + HRCALL(doc->appendChild(root, NULL), "appendChild"); + SysFreeString(elemname); + } catch (...) + { + doc->Release(); + throw; + } + return doc; +} + +void setAttribute(IXMLDOMElement *elem, const wchar_t *name, const wchar_t *value) +{ + BSTR str = SysAllocString(name); + VARIANT var = VariantString(value); + HRCALL(elem->setAttribute(str, var), "setAttribute"); + VariantClear(&var); + SysFreeString(str); +} + +void setAttribute(IXMLDOMElement *elem, const wchar_t *name, const char *value) +{ + wchar_t *wstr = mbconvert(value); + setAttribute(elem, name, wstr); + delete [] wstr; + return; +} + +void CConfig::Save(const char *filename) +{ + IXMLDOMDocument2 *doc = CreateDocument(); + IXMLDOMElement *root = NULL; + + HRCALL(doc->get_documentElement(&root), "get_documentElement"); + + switch (window) + { + case MultiWindow: + setAttribute(root, L"WindowMode", L"MultiWindow"); + break; + case Fullscreen: + setAttribute(root, L"WindowMode", L"Fullscreen"); + break; + default: + case Windowed: + setAttribute(root, L"WindowMode", L"Windowed"); + break; + case Nodecoration: + setAttribute(root, L"WindowMode", L"Nodecoration"); + break; + } + switch (client) + { + default: + case NoClient: + setAttribute(root, L"ClientMode", L"NoClient"); + break; + case StartProgram: + setAttribute(root, L"ClientMode", L"StartProgram"); + break; + case XDMCP: + setAttribute(root, L"ClientMode", L"XDMCP"); + break; + } + setAttribute(root, L"LocalClient", local?L"True":L"False"); + setAttribute(root, L"Display", display.c_str()); + setAttribute(root, L"Program", program.c_str()); + setAttribute(root, L"RemoteProtocol", protocol.c_str()); + setAttribute(root, L"RemoteHost", host.c_str()); + setAttribute(root, L"RemoteUser", user.c_str()); + setAttribute(root, L"XDMCPHost", xdmcp_host.c_str()); + setAttribute(root, L"XDMCPBroadcast", broadcast?L"True":L"False"); + setAttribute(root, L"XDMCPIndirect", indirect?L"True":L"False"); + setAttribute(root, L"Clipboard", clipboard?L"True":L"False"); + setAttribute(root, L"ExtraParams", extra_params.c_str()); + + VARIANT var = VariantString(filename); + HRCALL(doc->save(var), "save"); + VariantClear(&var); + + + root->Release(); + doc->Release(); +} + +BOOL getAttribute(IXMLDOMElement *elem, const wchar_t *name, std::string &ret) +{ + VARIANT var; + HRCALL(elem->getAttribute((OLECHAR*)name, &var), "getAttribute"); + if (V_VT(&var) != VT_NULL && V_VT(&var) == VT_BSTR) + { + char *str = wcconvert(V_BSTR(&var)); + ret = str; + delete [] str; + return true; + } + return false; +} + +BOOL getAttributeBool(IXMLDOMElement *elem, const wchar_t *name, bool &ret) +{ + std::string str; + if (getAttribute(elem, name, str)) + { + if (str == "True") + ret = true; + else + ret = false; + return true; + } + return false; +} + + +void CConfig::Load(const char *filename) +{ + IXMLDOMDocument2 *doc = CreateDocument(); + IXMLDOMElement *root = NULL; + + VARIANT var = VariantString(filename); + VARIANT_BOOL status; + HRCALL(doc->load(var, &status), "load"); + VariantClear(&var); + + if (status == VARIANT_FALSE) + { + doc->Release(); + return; + } + + HRCALL(doc->get_documentElement(&root), "get_documentElement"); + + std::string windowMode; + std::string clientMode; + + if (getAttribute(root, L"WindowMode", windowMode)) + { + if (windowMode == "MultiWindow") + window = MultiWindow; + else if (windowMode == "Fullscreen") + window = Fullscreen; + else if (windowMode == "Windowed") + window = Windowed; + else if (windowMode == "Nodecoration") + window = Nodecoration; + } + if (getAttribute(root, L"ClientMode", clientMode)) + { + if (clientMode == "NoClient") + client = NoClient; + else if (clientMode == "StartProgram") + client = StartProgram; + else if (clientMode == "XDMCP") + client = XDMCP; + } + + getAttributeBool(root, L"LocalClient", local); + getAttribute(root, L"Display", display); + getAttribute(root, L"Program", program); + getAttribute(root, L"RemoteProtocol", protocol); + getAttribute(root, L"RemoteHost", host); + getAttribute(root, L"RemoteUser", user); + getAttribute(root, L"XDMCPHost", xdmcp_host); + getAttributeBool(root, L"XDMCPBroadcast", broadcast); + getAttributeBool(root, L"XDMCPIndirect", indirect); + getAttributeBool(root, L"Clipboard", clipboard); + getAttribute(root, L"ExtraParams", extra_params); + + + doc->Release(); +} + diff --git a/hw/xwin/xlaunch/config.h b/hw/xwin/xlaunch/config.h new file mode 100644 index 000000000..f0aed3cf1 --- /dev/null +++ b/hw/xwin/xlaunch/config.h @@ -0,0 +1,60 @@ +/* + * 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. + */ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#include <string> +struct CConfig +{ + enum {MultiWindow, Fullscreen, Windowed, Nodecoration} window; + enum {NoClient, StartProgram, XDMCP} client; + bool local; + std::string display; + std::string protocol; + std::string program; + std::string host; + std::string user; + bool broadcast; + bool indirect; + std::string xdmcp_host; + bool clipboard; + std::string extra_params; +#ifdef _DEBUG + CConfig() : window(MultiWindow), client(StartProgram), local(false), display("1"), + protocol("Putty"), program("xterm"), host("lupus"), user("ago"), + broadcast(false), indirect(false), xdmcp_host("lupus"), + clipboard(true), extra_params() {}; +#else + CConfig() : window(MultiWindow), client(StartProgram), local(false), display("0"), + protocol("Putty"), program("xterm"), host(""), user(""), + broadcast(true), indirect(false), xdmcp_host(""), + clipboard(true), extra_params() {}; +#endif + void Load(const char* filename); + void Save(const char* filename); +}; + +#endif diff --git a/hw/xwin/xlaunch/main.cc b/hw/xwin/xlaunch/main.cc new file mode 100755 index 000000000..2247d3aaf --- /dev/null +++ b/hw/xwin/xlaunch/main.cc @@ -0,0 +1,700 @@ +/* + * 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. + */ +#include "window/util.h" +#include "window/wizard.h" +#include "resources/resources.h" +#include "config.h" +#include <prsht.h> +#include <commctrl.h> + +#include <stdexcept> + +#include <X11/Xlib.h> + +/// @brief Send WM_ENDSESSION to all program windows. +/// This will shutdown the started xserver +BOOL CALLBACK KillWindowsProc(HWND hwnd, LPARAM lParam) +{ + SendMessage(hwnd, WM_ENDSESSION, 0, 0); + return TRUE; +} + +/// @brief Actual wizard implementation. +/// This is based on generic CWizard but handles the special dialogs +class CMyWizard : public CWizard +{ + public: + private: + CConfig config; /// Storage for config options. + public: + /// @brief Constructor. + /// Set wizard pages. + CMyWizard() : CWizard() + { + AddPage(IDD_DISPLAY, IDS_DISPLAY_TITLE, IDS_DISPLAY_SUBTITLE); + AddPage(IDD_CLIENTS, IDS_CLIENTS_TITLE, IDS_CLIENTS_SUBTITLE); + AddPage(IDD_PROGRAM, IDS_PROGRAM_TITLE, IDS_PROGRAM_SUBTITLE); + AddPage(IDD_XDMCP, IDS_XDMCP_TITLE, IDS_XDMCP_SUBTITLE); + //AddPage(IDD_FONTPATH, IDS_FONTPATH_TITLE, IDS_FONTPATH_SUBTITLE); + AddPage(IDD_CLIPBOARD, IDS_CLIPBOARD_TITLE, IDS_CLIPBOARD_SUBTITLE); + AddPage(IDD_FINISH, IDS_FINISH_TITLE, IDS_FINISH_SUBTITLE); + } + + virtual void LoadConfig(const char *filename) + { + try { + config.Load(filename); + } catch (std::runtime_error &e) + { + printf("Fehler: %s\n", e.what()); + } + } + + /// @brief Handle the PSN_WIZNEXT message. + /// @param hwndDlg Handle to active page dialog. + /// @param index Index of current page. + /// @return TRUE if the message was handled. FALSE otherwise. + virtual BOOL WizardNext(HWND hwndDlg, unsigned index) + { +#ifdef _DEBUG + printf("%s %d\n", __FUNCTION__, index); +#endif + switch (PageID(index)) + { + case IDD_DISPLAY: + // Check for select window mode + if (IsDlgButtonChecked(hwndDlg, IDC_MULTIWINDOW)) + config.window = CConfig::MultiWindow; + else if (IsDlgButtonChecked(hwndDlg, IDC_FULLSCREEN)) + config.window = CConfig::Fullscreen; + else if (IsDlgButtonChecked(hwndDlg, IDC_WINDOWED)) + config.window = CConfig::Windowed; + else if (IsDlgButtonChecked(hwndDlg, IDC_NODECORATION)) + config.window = CConfig::Nodecoration; + else + { + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + return TRUE; + } + // Get selected display number + { + char buffer[512]; + GetDlgItemText(hwndDlg, IDC_DISPLAY, buffer, 512); + buffer[511] = 0; + config.display = buffer; + } + // Check for valid input + if (config.display.empty()) + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + else + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIENTS); + return TRUE; + case IDD_CLIENTS: + // Check for select client startup method + if (IsDlgButtonChecked(hwndDlg, IDC_CLIENT)) + { + config.client = CConfig::StartProgram; + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_PROGRAM); + } else if (IsDlgButtonChecked(hwndDlg, IDC_XDMCP)) + { + config.client = CConfig::XDMCP; + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_XDMCP); + } else if (IsDlgButtonChecked(hwndDlg, IDC_CLIENT_NONE)) + { + config.client = CConfig::NoClient; + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIPBOARD); + } else + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + return TRUE; + case IDD_PROGRAM: + // Check wether local or remote client should be started + if (IsDlgButtonChecked(hwndDlg, IDC_CLIENT_LOCAL)) + config.local = true; + else if (IsDlgButtonChecked(hwndDlg, IDC_CLIENT_REMOTE)) + config.local = false; + else + { + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + return TRUE; + } + // Read program, user and host name + { + char buffer[512]; + GetDlgItemText(hwndDlg, IDC_CLIENT_USER, buffer, 512); + buffer[511] = 0; + config.user = buffer; + GetDlgItemText(hwndDlg, IDC_CLIENT_HOST, buffer, 512); + buffer[511] = 0; + config.host = buffer; + GetDlgItemText(hwndDlg, IDC_CLIENT_PROGRAM, buffer, 512); + buffer[511] = 0; + config.program = buffer; + } + // Check for valid input + if (!config.local && (config.host.empty() || config.program.empty())) + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + else + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIPBOARD); + return TRUE; + case IDD_XDMCP: + // Check for broadcast + if (IsDlgButtonChecked(hwndDlg, IDC_XDMCP_BROADCAST)) + config.broadcast = true; + else if (IsDlgButtonChecked(hwndDlg, IDC_XDMCP_QUERY)) + config.broadcast = false; + else + { + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + return TRUE; + } + // Check for indirect mode + if (IsDlgButtonChecked(hwndDlg, IDC_XDMCP_INDIRECT)) + config.indirect = true; + else + config.indirect = false; + // Read hostname + { + char buffer[512]; + GetDlgItemText(hwndDlg, IDC_XDMCP_HOST, buffer, 512); + buffer[511] = 0; + config.xdmcp_host = buffer; + } + // Check for valid input + if (!config.broadcast && config.xdmcp_host.empty()) + SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + else + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIPBOARD); + return TRUE; + case IDD_CLIPBOARD: + // check for clipboard + if (IsDlgButtonChecked(hwndDlg, IDC_CLIPBOARD)) + config.clipboard = true; + else + config.clipboard = false; + // read parameters + { + char buffer[512]; + GetDlgItemText(hwndDlg, IDC_EXTRA_PARAMS, buffer, 512); + buffer[511] = 0; + config.extra_params = buffer; + } + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_FINISH); + return TRUE; + default: + break; + } + return FALSE; + } + /// @brief Handle PSN_WIZFINISH message. + /// @param hwndDlg Handle to active page dialog. + /// @param index Index of current page. + /// @return TRUE if the message was handled. FALSE otherwise. + virtual BOOL WizardFinish(HWND hwndDlg, unsigned index) + { +#ifdef _DEBUG + printf("finish %d\n", index); +#endif + return FALSE; + } + /// @brief Handle PSN_WIZBACK message. + /// Basicly handles switching to proper page (skipping XDMCP or program page + /// if required). + /// @param hwndDlg Handle to active page dialog. + /// @param index Index of current page. + /// @return TRUE if the message was handled. FALSE otherwise. + virtual BOOL WizardBack(HWND hwndDlg, unsigned index) + { + switch (PageID(index)) + { + case IDD_PROGRAM: + case IDD_XDMCP: + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIENTS); + return TRUE; + case IDD_FONTPATH: + case IDD_CLIPBOARD: // temporary. fontpath is disabled + switch (config.client) + { + case CConfig::NoClient: + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIENTS); + return TRUE; + case CConfig::StartProgram: + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_PROGRAM); + return TRUE; + case CConfig::XDMCP: + SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_XDMCP); + return TRUE; + } + break; + } + return FALSE; + } + /// @brief Handle PSN_SETACTIVE message. + /// @param hwndDlg Handle to active page dialog. + /// @param index Index of current page. + /// @return TRUE if the message was handled. FALSE otherwise. + virtual BOOL WizardActivate(HWND hwndDlg, unsigned index) + { +#ifdef _DEBUG + printf("%s %d\n", __FUNCTION__, index); +#endif + switch (PageID(index)) + { + case IDD_CLIENTS: + // Enable or disable XDMCP radiobutton and text + EnableWindow(GetDlgItem(hwndDlg, IDC_XDMCP), config.window != CConfig::MultiWindow); + EnableWindow(GetDlgItem(hwndDlg, IDC_XDMCP_DESC), config.window != CConfig::MultiWindow); + break; + } + return FALSE; + } + protected: + /// @brief Enable or disable the control for remote clients. + /// @param hwndDlg Handle to active page dialog. + /// @param state State of control group. + void EnableRemoteProgramGroup(HWND hwndDlg, BOOL state) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_PROTOCOL), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_HOST), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_USER), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_PROTOCOL_DESC), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_HOST_DESC), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_USER_DESC), state); + } + /// @brief Enable or disable the control for XDMCP connection. + /// @param hwndDlg Handle to active page dialog. + /// @param state State of control group. + void EnableXDMCPQueryGroup(HWND hwndDlg, BOOL state) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_XDMCP_HOST), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_XDMCP_INDIRECT), state); + } + /// @brief Fill program box with default values. + /// @param hwndDlg Handle to active page dialog. + void FillProgramBox(HWND hwndDlg) + { + HWND cbwnd = GetDlgItem(hwndDlg, IDC_CLIENT_PROGRAM); + if (cbwnd == NULL) + return; + SendMessage(cbwnd, CB_RESETCONTENT, 0, 0); + SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) "xterm"); + SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) "startkde"); + SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) "gnome-session"); + SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) ".xinitrc"); + SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) "wmaker"); + SendMessage(cbwnd, CB_SETCURSEL, 0, 0); + } + /// @brief Fill protocol box with default values. + /// @param hwndDlg Handle to active page dialog. + void FillProtocolBox(HWND hwndDlg) + { + HWND cbwnd = GetDlgItem(hwndDlg, IDC_CLIENT_PROTOCOL); + if (cbwnd == NULL) + return; + SendMessage(cbwnd, CB_RESETCONTENT, 0, 0); + SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) "Putty"); + //SendMessage(cbwnd, CB_ADDSTRING, 0, (LPARAM) "OpenSSH"); + SendMessage(cbwnd, CB_SETCURSEL, 0, 0); + } + void ShowSaveDialog(HWND parent) + { + char szTitle[512]; + char szFilter[512]; + char szFileTitle[512]; + char szFile[MAX_PATH]; + HINSTANCE hInst = GetModuleHandle(NULL); + + LoadString(hInst, IDS_SAVE_TITLE, szTitle, sizeof(szTitle)); + LoadString(hInst, IDS_SAVE_FILETITLE, szFileTitle, sizeof(szFileTitle)); + LoadString(hInst, IDS_SAVE_FILTER, szFilter, sizeof(szFilter)); + for (unsigned i=0; szFilter[i]; i++) + if (szFilter[i] == '%') + szFilter[i] = '\0'; + + strcpy(szFile, "config.xlaunch"); + + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = parent; + ofn.lpstrFilter = szFilter; + ofn.lpstrFile= szFile; + ofn.nMaxFile = sizeof(szFile)/ sizeof(*szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = (LPSTR)NULL; + ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT; + ofn.lpstrTitle = szTitle; + + if (GetSaveFileName(&ofn)) + { + try { + config.Save(ofn.lpstrFile); + } catch (std::runtime_error &e) + { + printf("Fehler: %s\n", e.what()); + } + } + } + public: + + /// @brief Handle messages fo the dialog pages. + /// @param hwndDlg Handle of active dialog. + /// @param uMsg Message code. + /// @param wParam Message parameter. + /// @param lParam Message parameter. + /// @param psp Handle to sheet paramters. + virtual INT_PTR PageDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, PROPSHEETPAGE *psp) + { + HWND hwnd; + switch (uMsg) + { + case WM_INITDIALOG: + switch (PageID(PageIndex(psp))) + { + case IDD_DISPLAY: + // Init display dialog. Enable correct check buttons + switch (config.window) + { + default: + case CConfig::MultiWindow: + CheckRadioButton(hwndDlg, IDC_MULTIWINDOW, IDC_NODECORATION, IDC_MULTIWINDOW); + break; + case CConfig::Fullscreen: + CheckRadioButton(hwndDlg, IDC_MULTIWINDOW, IDC_NODECORATION, IDC_FULLSCREEN); + break; + case CConfig::Windowed: + CheckRadioButton(hwndDlg, IDC_MULTIWINDOW, IDC_NODECORATION, IDC_WINDOWED); + break; + case CConfig::Nodecoration: + CheckRadioButton(hwndDlg, IDC_MULTIWINDOW, IDC_NODECORATION, IDC_NODECORATION); + break; + } + // Set display number + SetDlgItemText(hwndDlg, IDC_DISPLAY, config.display.c_str()); + break; + case IDD_CLIENTS: + // Init client dialog. Enable correct check buttons + switch (config.client) + { + default: + case CConfig::NoClient: + CheckRadioButton(hwndDlg, IDC_CLIENT_NONE, IDC_CLIENT, IDC_CLIENT_NONE); + break; + case CConfig::StartProgram: + CheckRadioButton(hwndDlg, IDC_CLIENT_NONE, IDC_CLIENT, IDC_CLIENT); + break; + case CConfig::XDMCP: + CheckRadioButton(hwndDlg, IDC_CLIENT_NONE, IDC_CLIENT, IDC_XDMCP); + break; + } + break; + case IDD_PROGRAM: + // Init program dialog. Check local and remote buttons + CheckRadioButton(hwndDlg, IDC_CLIENT_LOCAL, IDC_CLIENT_REMOTE, config.local?IDC_CLIENT_LOCAL:IDC_CLIENT_REMOTE); + EnableRemoteProgramGroup(hwndDlg, config.local?FALSE:TRUE); + // Fill combo boxes + FillProgramBox(hwndDlg); + FillProtocolBox(hwndDlg); + // Set edit fields + if (!config.program.empty()) + SetDlgItemText(hwndDlg, IDC_CLIENT_PROGRAM, config.program.c_str()); + SetDlgItemText(hwndDlg, IDC_CLIENT_USER, config.user.c_str()); + SetDlgItemText(hwndDlg, IDC_CLIENT_HOST, config.host.c_str()); + break; + case IDD_XDMCP: + // Init XDMCP dialog. Check broadcast and indirect button + CheckRadioButton(hwndDlg, IDC_XDMCP_QUERY, IDC_XDMCP_BROADCAST, config.broadcast?IDC_XDMCP_BROADCAST:IDC_XDMCP_QUERY); + CheckDlgButton(hwndDlg, IDC_XDMCP_INDIRECT, config.indirect?BST_CHECKED:BST_UNCHECKED); + EnableXDMCPQueryGroup(hwndDlg, config.broadcast?FALSE:TRUE); + // Set hostname + SetDlgItemText(hwndDlg, IDC_XDMCP_HOST, config.xdmcp_host.c_str()); + break; + case IDD_CLIPBOARD: + CheckDlgButton(hwndDlg, IDC_CLIPBOARD, config.clipboard?BST_CHECKED:BST_UNCHECKED); + SetDlgItemText(hwndDlg, IDC_EXTRA_PARAMS, config.extra_params.c_str()); + break; + + } + case WM_COMMAND: + // Handle control messages + switch (LOWORD(wParam)) + { + // Handle clicks on images. Check proper radiobutton + case IDC_MULTIWINDOW_IMG: + case IDC_FULLSCREEN_IMG: + case IDC_WINDOWED_IMG: + case IDC_NODECORATION_IMG: + CheckRadioButton(hwndDlg, IDC_MULTIWINDOW, IDC_NODECORATION, LOWORD(wParam)-4); + SetFocus(GetDlgItem(hwndDlg, LOWORD(wParam)-4)); + break; + // Disable unavailable controls + case IDC_CLIENT_REMOTE: + case IDC_CLIENT_LOCAL: + EnableRemoteProgramGroup(hwndDlg, LOWORD(wParam) == IDC_CLIENT_REMOTE); + break; + case IDC_XDMCP_QUERY: + case IDC_XDMCP_BROADCAST: + EnableXDMCPQueryGroup(hwndDlg, LOWORD(wParam) == IDC_XDMCP_QUERY); + break; + case IDC_FINISH_SAVE: + ShowSaveDialog(hwndDlg); + break; + } + } + // pass messages to parent + return CWizard::PageDispatch(hwndDlg, uMsg, wParam, lParam, psp); + } + + /// @brief Try to connect to server. + /// Repeat until successful, server died or maximum number of retries + /// reached. + Display *WaitForServer(HANDLE serverProcess) + { + int ncycles = 120; /* # of cycles to wait */ + int cycles; /* Wait cycle count */ + Display *xd; + + for (cycles = 0; cycles < ncycles; cycles++) { + if ((xd = XOpenDisplay(NULL))) { + return xd; + } + else { + if (WaitForSingleObject(serverProcess, 1000) == WAIT_TIMEOUT) + continue; + } + } + return NULL; + } + + /// @brief Do the actual start of Xming and clients + void StartUp() + { + std::string buffer; + std::string client; + + // Construct display strings + std::string display_id = ":" + config.display; + std::string display = "localhost" + display_id + ":0"; + +#ifdef _DEBUG + // Debug only: Switch to Xming installation directory + SetCurrentDirectory("C:\\Programme\\Xming"); +#endif + + // Build Xming commandline + buffer = "Xming " + display_id + " "; + switch (config.window) + { + case CConfig::MultiWindow: + buffer += "-multiwindow "; + break; + case CConfig::Fullscreen: + buffer += "-fullscreen "; + break; + case CConfig::Nodecoration: + buffer += "-nodecoration "; + break; + default: + break; + } + // Add XDMCP parameter + if (config.client == CConfig::XDMCP) + { + if (config.broadcast) + buffer += "-broadcast "; + else + { + if (config.indirect) + buffer += "-indirect "; + else + buffer += "-query "; + buffer += config.xdmcp_host; + buffer += " "; + } + } + if (config.clipboard) + buffer += "-clipboard "; + if (!config.extra_params.empty()) + { + buffer += config.extra_params; + buffer += " "; + } + + // Construct client commandline + if (config.client == CConfig::StartProgram) + { + if (!config.local) + { + char cmdline[512]; + std::string host = config.host; + if (!config.user.empty()) + host = config.user + "@" + config.host; + if (config.protocol == "Putty") + snprintf(cmdline,512,"plink -X %s %s", + host.c_str(),config.program.c_str()); + else + snprintf(cmdline,512,"ssh -Y %s %s", + host.c_str(),config.program.c_str()); + client += cmdline; + } else + client += config.program.c_str(); + } + + // Prepare program startup + STARTUPINFO si, sic; + PROCESS_INFORMATION pi, pic; + HANDLE handles[2]; + DWORD hcount = 0; + Display *dpy = NULL; + + ZeroMemory( &si, sizeof(si) ); + si.cb = sizeof(si); + ZeroMemory( &pi, sizeof(pi) ); + ZeroMemory( &sic, sizeof(sic) ); + sic.cb = sizeof(sic); + ZeroMemory( &pic, sizeof(pic) ); + + // Start Xming process. +#ifdef _DEBUG + printf("%s\n", buffer.c_str()); +#endif + if( !CreateProcess( NULL, (CHAR*)buffer.c_str(), NULL, NULL, + FALSE, 0, NULL, NULL, &si, &pi )) + throw win32_error("CreateProcess failed"); + handles[hcount++] = pi.hProcess; + + if (!client.empty()) + { + // Set DISPLAY variable + SetEnvironmentVariable("DISPLAY",display.c_str()); + + // Wait for server to startup + dpy = WaitForServer(pi.hProcess); + if (dpy == NULL) + { + while (hcount--) + TerminateProcess(handles[hcount], (DWORD)-1); + throw std::runtime_error("Connection to server failed"); + } + +#ifdef _DEBUG + printf("%s\n", client.c_str()); +#endif + + // Hide a console window + // FIXME: This may make it impossible to enter the password + sic.dwFlags = STARTF_USESHOWWINDOW; + sic.wShowWindow = SW_HIDE; + + // Start the child process. + if( !CreateProcess( NULL, (CHAR*)client.c_str(), NULL, NULL, + FALSE, 0, NULL, NULL, &sic, &pic )) + { + DWORD err = GetLastError(); + while (hcount--) + TerminateProcess(handles[hcount], (DWORD)-1); + throw win32_error("CreateProcess failed", err); + } + handles[hcount++] = pic.hProcess; + } + + // Wait until any child process exits. + DWORD ret = WaitForMultipleObjects(hcount, handles, FALSE, INFINITE ); + +#ifdef _DEBUG + printf("killing process!\n"); +#endif + // Check if Xming is still running + DWORD exitcode; + GetExitCodeProcess(pi.hProcess, &exitcode); + unsigned counter = 0; + while (exitcode == STILL_ACTIVE) + { + if (++counter > 10) + TerminateProcess(pi.hProcess, (DWORD)-1); + else + // Shutdown Xming (the soft way!) + EnumThreadWindows(pi.dwThreadId, KillWindowsProc, 0); + Sleep(500); + GetExitCodeProcess(pi.hProcess, &exitcode); + } + // Kill the client + TerminateProcess(pic.hProcess, (DWORD)-1); + + // Close process and thread handles. + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + CloseHandle( pic.hProcess ); + CloseHandle( pic.hThread ); + } +}; + +int main(int argc, char **argv) +{ + try { + InitCommonControls(); + CMyWizard dialog; + + bool skip_wizard = false; + + for (int i = 1; i < argc; i++) + { + if (argv[i] == NULL) + continue; + + std::string arg(argv[i]); + if (arg == "-load" && i + 1 < argc) + { + i++; + dialog.LoadConfig(argv[i]); + continue; + } + if (arg == "-run" && i + 1 < argc) + { + i++; + dialog.LoadConfig(argv[i]); + skip_wizard = true; + continue; + } + } + + int ret = 0; + if (skip_wizard || (ret =dialog.ShowModal()) != 0) + dialog.StartUp(); +#ifdef _DEBUG + printf("return %d\n", ret); +#endif + return 0; + } catch (std::runtime_error &e) + { + printf("Fehler: %s\n", e.what()); + return -1; + } +} + + + + diff --git a/hw/xwin/xlaunch/resources/dialog.rc b/hw/xwin/xlaunch/resources/dialog.rc new file mode 100755 index 000000000..8b00df4ef --- /dev/null +++ b/hw/xwin/xlaunch/resources/dialog.rc @@ -0,0 +1,118 @@ +/* + * 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. + */ +#include <windows.h> +#include "resources.h" + +#ifndef STR_CAPTION_DISPLAY +#include "strings.rc" +#endif + +IDD_DISPLAY DIALOGEX 0, 0, 317, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTERMOUSE +CAPTION STR_CAPTION_DISPLAY +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + AUTORADIOBUTTON STR_MULTIWINDOW,IDC_MULTIWINDOW,7,25,70,24,BS_MULTILINE|BS_TOP + AUTORADIOBUTTON STR_FULLSCREEN,IDC_FULLSCREEN,157,25,70,24,BS_MULTILINE|BS_TOP + AUTORADIOBUTTON STR_WINDOWED,IDC_WINDOWED,7,75,70,24,BS_MULTILINE|BS_TOP + AUTORADIOBUTTON STR_NODECORATION,IDC_NODECORATION,157,75,70,24,BS_MULTILINE|BS_TOP + + CONTROL "IMG_MULTIWINDOW",IDC_MULTIWINDOW_IMG,"Static",SS_BITMAP | SS_NOTIFY,80,10,0,0 + CONTROL "IMG_FULLSCREEN",IDC_FULLSCREEN_IMG,"Static",SS_BITMAP | SS_NOTIFY,230,10,0,0 + CONTROL "IMG_WINDOWED",IDC_WINDOWED_IMG,"Static",SS_BITMAP | SS_NOTIFY,80,60,0,0 + CONTROL "IMG_NODECORATION",IDC_NODECORATION_IMG,"Static",SS_BITMAP | SS_NOTIFY,230,60,0,0 + + LTEXT STR_DISPLAY_DESC,IDC_DISPLAY_DESC,7,120,64,12 + EDITTEXT IDC_DISPLAY,80,118,67,12,ES_NUMBER +END + +IDD_CLIENTS DIALOGEX 0, 0, 317, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTERMOUSE +CAPTION STR_CAPTION_CLIENTS +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + AUTORADIOBUTTON STR_CLIENT_NONE,IDC_CLIENT_NONE,7,14,300,10 + AUTORADIOBUTTON STR_CLIENT,IDC_CLIENT,7,56,300,10 + AUTORADIOBUTTON STR_XDMCP,IDC_XDMCP,7,98,300,10 + + LTEXT STR_CLIENT_NONE_DESC,IDC_CLIENT_NONE_DESC,19,28,280,27 + LTEXT STR_CLIENT_DESC,IDC_CLIENT_DESC,19,70,280,27 + LTEXT STR_XDMCP_DESC,IDC_XDMCP_DESC,19,112,280,27 +END + +IDD_PROGRAM DIALOGEX 0, 0, 317, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTERMOUSE +CAPTION STR_CAPTION_PROGRAM +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT STR_CLIENT_PROGRAM_DESC,IDC_CLIENT_PROGRAM_DESC,7,14,64,10 + COMBOBOX IDC_CLIENT_PROGRAM,70,12,64,54,CBS_DROPDOWN | WS_VSCROLL + + AUTORADIOBUTTON STR_CLIENT_LOCAL,IDC_CLIENT_LOCAL,7,28,300,10 + AUTORADIOBUTTON STR_CLIENT_REMOTE,IDC_CLIENT_REMOTE,7,42,300,10 + + LTEXT STR_CLIENT_PROTOCOL_DESC,IDC_CLIENT_PROTOCOL_DESC,19,56,70,10 + COMBOBOX IDC_CLIENT_PROTOCOL,100,54,64,54,CBS_DROPDOWNLIST | WS_VSCROLL + + LTEXT STR_CLIENT_HOST_DESC,IDC_CLIENT_HOST_DESC,19,70,70,10 + LTEXT STR_CLIENT_USER_DESC,IDC_CLIENT_USER_DESC,19,84,70,10 + EDITTEXT IDC_CLIENT_HOST,100,68,64,12 + EDITTEXT IDC_CLIENT_USER,100,82,64,12 +END + +IDD_XDMCP DIALOGEX 0, 0, 317, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTERMOUSE +CAPTION STR_CAPTION_XDMCP +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + AUTORADIOBUTTON STR_XDMCP_QUERY, IDC_XDMCP_QUERY,7,14,64,10 + EDITTEXT IDC_XDMCP_HOST,78,12,64,12 + AUTOCHECKBOX STR_XDMCP_INDIRECT,IDC_XDMCP_INDIRECT,19,28,280,10 + AUTORADIOBUTTON STR_XDMCP_BROADCAST, IDC_XDMCP_BROADCAST,7,42,300,10 + LTEXT STR_XDMCP_QUERY_DESC,IDC_XDMCP_QUERY_DESC,7,56,300,42 +END + +IDD_CLIPBOARD DIALOGEX 0, 0, 317, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTERMOUSE +CAPTION STR_CAPTION_CLIPBOARD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + AUTOCHECKBOX STR_CLIPBOARD,IDC_CLIPBOARD,7,14,300,10 + LTEXT STR_CLIPBOARD_DESC,IDC_CLIPBOARD_DESC,19,28,280,27 + + LTEXT STR_EXTRA_PARAMS_DESC,IDC_EXTRA_PARAMS_DESC,7,56,280,10 + EDITTEXT IDC_EXTRA_PARAMS,7,70,128,12 +END + +IDD_FINISH DIALOGEX 0, 0, 317, 143 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTERMOUSE +CAPTION STR_CAPTION_FINISH +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT STR_FINISH_DESC,IDC_FINISH_DESC,7,14,300,28 + LTEXT STR_FINISH_SAVE_DESC,IDC_FINISH_SAVE_DESC,7,56,300,12 + PUSHBUTTON STR_FINISH_SAVE,IDC_FINISH_SAVE,7,68,75,14 +END diff --git a/hw/xwin/xlaunch/resources/fullscreen.bmp b/hw/xwin/xlaunch/resources/fullscreen.bmp Binary files differnew file mode 100755 index 000000000..0d051f0b4 --- /dev/null +++ b/hw/xwin/xlaunch/resources/fullscreen.bmp diff --git a/hw/xwin/xlaunch/resources/images.rc b/hw/xwin/xlaunch/resources/images.rc new file mode 100755 index 000000000..2eac53c93 --- /dev/null +++ b/hw/xwin/xlaunch/resources/images.rc @@ -0,0 +1,29 @@ +/*
+ * 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.
+ */
+IMG_MULTIWINDOW BITMAP "resources\\multiwindow.bmp"
+IMG_WINDOWED BITMAP "resources\\windowed.bmp"
+IMG_FULLSCREEN BITMAP "resources\\fullscreen.bmp"
+IMG_NODECORATION BITMAP "resources\\nodecoration.bmp"
diff --git a/hw/xwin/xlaunch/resources/multiwindow.bmp b/hw/xwin/xlaunch/resources/multiwindow.bmp Binary files differnew file mode 100755 index 000000000..0755c87b4 --- /dev/null +++ b/hw/xwin/xlaunch/resources/multiwindow.bmp diff --git a/hw/xwin/xlaunch/resources/nodecoration.bmp b/hw/xwin/xlaunch/resources/nodecoration.bmp Binary files differnew file mode 100755 index 000000000..e9e1ce690 --- /dev/null +++ b/hw/xwin/xlaunch/resources/nodecoration.bmp diff --git a/hw/xwin/xlaunch/resources/resources.h b/hw/xwin/xlaunch/resources/resources.h new file mode 100755 index 000000000..470005192 --- /dev/null +++ b/hw/xwin/xlaunch/resources/resources.h @@ -0,0 +1,99 @@ +/*
+ * 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.
+ */
+
+#define IDC_STATIC -1
+
+#define IDD_WELCOME 100
+#define IDD_FINISH 101
+#define IDD_DISPLAY 102
+#define IDD_CLIENTS 103
+#define IDD_PROGRAM 104
+#define IDD_XDMCP 105
+#define IDD_FONTPATH 106
+#define IDD_CLIPBOARD 107
+
+#define IDS_DISPLAY_TITLE 300
+#define IDS_DISPLAY_SUBTITLE 301
+#define IDS_CLIENTS_TITLE 302
+#define IDS_CLIENTS_SUBTITLE 303
+#define IDS_PROGRAM_TITLE 304
+#define IDS_PROGRAM_SUBTITLE 305
+#define IDS_XDMCP_TITLE 306
+#define IDS_XDMCP_SUBTITLE 307
+#define IDS_FONTPATH_TITLE 308
+#define IDS_FONTPATH_SUBTITLE 309
+#define IDS_FINISH_TITLE 310
+#define IDS_FINISH_SUBTITLE 311
+#define IDS_CLIPBOARD_TITLE 312
+#define IDS_CLIPBOARD_SUBTITLE 313
+#define IDS_SAVE_TITLE 320
+#define IDS_SAVE_FILETITLE 321
+#define IDS_SAVE_FILTER 322
+
+#define IDC_MULTIWINDOW 200
+#define IDC_WINDOWED 201
+#define IDC_FULLSCREEN 202
+#define IDC_NODECORATION 203
+#define IDC_MULTIWINDOW_IMG 204
+#define IDC_WINDOWED_IMG 205
+#define IDC_FULLSCREEN_IMG 206
+#define IDC_NODECORATION_IMG 207
+#define IDC_DISPLAY 208
+#define IDC_DISPLAY_DESC 209
+
+#define IDC_CLIENT_NONE 210
+#define IDC_XDMCP 211
+#define IDC_CLIENT 212
+#define IDC_CLIENT_LOCAL 213
+#define IDC_CLIENT_REMOTE 214
+#define IDC_CLIENT_HOST 215
+#define IDC_CLIENT_USER 216
+#define IDC_CLIENT_PROTOCOL 217
+#define IDC_CLIENT_CONFIGURE 218
+#define IDC_CLIENT_PROGRAM 219
+#define IDC_XDMCP_QUERY 220
+#define IDC_XDMCP_BROADCAST 221
+#define IDC_XDMCP_INDIRECT 222
+#define IDC_XDMCP_HOST 223
+#define IDC_CLIENT_NONE_DESC 224
+#define IDC_XDMCP_DESC 225
+#define IDC_CLIENT_DESC 226
+#define IDC_XDMCP_QUERY_DESC 227
+#define IDC_CLIENT_PROGRAM_DESC 228
+#define IDC_CLIENT_HOST_DESC 229
+#define IDC_CLIENT_USER_DESC 230
+#define IDC_CLIENT_PROTOCOL_DESC 231
+
+#define IDC_FONTPATH_DESC 240
+
+#define IDC_FINISH_DESC 250
+#define IDC_FINISH_SAVE 251
+#define IDC_FINISH_SAVE_DESC 252
+
+#define IDC_CLIPBOARD 260
+#define IDC_CLIPBOARD_DESC 261
+#define IDC_EXTRA_PARAMS 262
+#define IDC_EXTRA_PARAMS_DESC 263
diff --git a/hw/xwin/xlaunch/resources/resources.rc b/hw/xwin/xlaunch/resources/resources.rc new file mode 100755 index 000000000..07fd52f32 --- /dev/null +++ b/hw/xwin/xlaunch/resources/resources.rc @@ -0,0 +1,30 @@ +/* + * 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. + */ +#include <windows.h> + +#include "resources.h" +#include "images.rc" +#include "dialog.rc" diff --git a/hw/xwin/xlaunch/resources/strings.rc b/hw/xwin/xlaunch/resources/strings.rc new file mode 100644 index 000000000..5a9cd281b --- /dev/null +++ b/hw/xwin/xlaunch/resources/strings.rc @@ -0,0 +1,108 @@ +/* + * 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. + */ + +#define STR_CAPTION_DISPLAY "Display settings" +#define STR_MULTIWINDOW "Multiple windows" +#define STR_FULLSCREEN "Fullscreen" +#define STR_WINDOWED "One large window" +#define STR_NODECORATION "One window without titlebar" +#define STR_DISPLAY_DESC "Display number" + +#define STR_CAPTION_CLIENTS "Client startup" +#define STR_CLIENT_NONE "Start no client" +#define STR_CLIENT_NONE_DESC "This will just start the xserver. You will be able to start local clients later." +#define STR_CLIENT "Start a program" +#define STR_CLIENT_DESC "This will start a local or remote program which will connect to the xserver. You will be able to start local clients later too. Remote programs are started using SSH." +#define STR_XDMCP "Open session via XDMCP" +#define STR_XDMCP_DESC "This will start a remote XDMCP session. Starting local clients later is limited. This option is not available with the ""Multiple windows"" mode." + +#define STR_CAPTION_PROGRAM "Start program" +#define STR_CLIENT_PROGRAM_DESC "Start program" +#define STR_CLIENT_LOCAL "Start program on this computer" +#define STR_CLIENT_REMOTE "Start program on remote computer" +#define STR_CLIENT_PROTOCOL_DESC "Connect using" +#define STR_CLIENT_HOST_DESC "Connect to computer" +#define STR_CLIENT_USER_DESC "Login as user" + + +#define STR_CAPTION_XDMCP "XDMCP settings" +#define STR_XDMCP_QUERY "Connect to host" +#define STR_XDMCP_INDIRECT "Use indirect connect" +#define STR_XDMCP_BROADCAST "Search for hosts (broadcast)" +#define STR_XDMCP_QUERY_DESC "Some XDMCP servers must be configured to allow remote connections. Please check the documentation about configuring XDMCP servers." + + +#define STR_CAPTION_FONTPATH "Fontpath settings" + +#define STR_CAPTION_CLIPBOARD "Clipboard settings" +#define STR_CLIPBOARD "Clipboard" +#define STR_CLIPBOARD_DESC "Start the integrated clipboard manager" +#define STR_EXTRA_PARAMS_DESC "Additional parameters for Xming" + +#define STR_CAPTION_FINISH "Finish configuration" +#define STR_FINISH_DESC "Configuration is complete. Clish Finish to start Xming." +#define STR_FINISH_SAVE_DESC "You may also save the configuration for later use." +#define STR_FINISH_SAVE "Save configuration" + +#define STR_DISPLAY_TITLE "Select display settings" +#define STR_DISPLAY_SUBTITLE "Choose how Xming display programs" +#define STR_CLIENTS_TITLE "Select how to start clients" +#define STR_CLIENTS_SUBTITLE "" +#define STR_PROGRAM_TITLE "Specify the program to start" +#define STR_PROGRAM_SUBTITLE "" +#define STR_XDMCP_TITLE "Configure a remote XDMCP connection" +#define STR_XDMCP_SUBTITLE "" +#define STR_FONTPATH_TITLE "Define font locations" +#define STR_FONTPATH_SUBTITLE "" +#define STR_FINISH_TITLE "Configuration complete" +#define STR_FINISH_SUBTITLE "" +#define STR_CLIPBOARD_TITLE "Clipboard settings" +#define STR_CLIPBOARD_SUBTITLE "" + +#define STR_SAVE_TITLE "Save configuration" +#define STR_SAVE_FILETITLE "Filename" +#define STR_SAVE_FILTER "Xlaunch Files (*.xlaunch)%*.xlaunch%%" + +STRINGTABLE +BEGIN + IDS_DISPLAY_TITLE STR_DISPLAY_TITLE + IDS_DISPLAY_SUBTITLE STR_DISPLAY_SUBTITLE + IDS_CLIENTS_TITLE STR_CLIENTS_TITLE + IDS_CLIENTS_SUBTITLE STR_CLIENTS_SUBTITLE + IDS_PROGRAM_TITLE STR_PROGRAM_TITLE + IDS_PROGRAM_SUBTITLE STR_PROGRAM_SUBTITLE + IDS_XDMCP_TITLE STR_XDMCP_TITLE + IDS_XDMCP_SUBTITLE STR_XDMCP_SUBTITLE + IDS_FONTPATH_TITLE STR_FONTPATH_TITLE + IDS_FONTPATH_SUBTITLE STR_FONTPATH_SUBTITLE + IDS_FINISH_TITLE STR_FINISH_TITLE + IDS_FINISH_SUBTITLE STR_FINISH_SUBTITLE + IDS_CLIPBOARD_TITLE STR_CLIPBOARD_TITLE + IDS_CLIPBOARD_SUBTITLE STR_CLIPBOARD_SUBTITLE + IDS_SAVE_TITLE STR_SAVE_TITLE + IDS_SAVE_FILETITLE STR_SAVE_FILETITLE + IDS_SAVE_FILTER STR_SAVE_FILTER +END diff --git a/hw/xwin/xlaunch/resources/windowed.bmp b/hw/xwin/xlaunch/resources/windowed.bmp Binary files differnew file mode 100755 index 000000000..9eff2bff9 --- /dev/null +++ b/hw/xwin/xlaunch/resources/windowed.bmp diff --git a/hw/xwin/xlaunch/window/dialog.cc b/hw/xwin/xlaunch/window/dialog.cc new file mode 100755 index 000000000..76e5c35ac --- /dev/null +++ b/hw/xwin/xlaunch/window/dialog.cc @@ -0,0 +1,86 @@ +/* + * 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. + */ +#include <stdio.h> +#include "dialog.h" +#include "util.h" + +CBaseDialog::CBaseDialog() : CWindow(""), result(0) +{ +} + +CDialog::CDialog(const char *res) : CBaseDialog(), resourcename(res) +{ +} + +HWND CDialog::CreateWindowHandle() +{ + HWND ret = CreateDialog( + GetModuleHandle(NULL), + resourcename.c_str(), + NULL, + DialogProc); + if (ret == NULL) + throw win32_error("CreateDialog failed"); + return ret; +} + +INT_PTR CALLBACK CBaseDialog::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MessageDebug::debug(hwndDlg, uMsg, wParam, lParam, __FUNCTION__); + CBaseDialog* dialog = (CDialog*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (dialog != NULL) + return dialog->DlgDispatch(hwndDlg, uMsg, wParam, lParam); + return FALSE; +} + +INT_PTR CBaseDialog::DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + result = wParam; + EndDialog(hwndDlg, wParam); + DestroyWindow(hwndDlg); + return TRUE; + } + break; + } + return FALSE; +} + +INT_PTR CDialog::DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return CBaseDialog::DlgDispatch(hwndDlg, uMsg, wParam, lParam); +} + +int CBaseDialog::Execute() +{ + return CWindow::ShowModal(); +} diff --git a/hw/xwin/xlaunch/window/dialog.h b/hw/xwin/xlaunch/window/dialog.h new file mode 100755 index 000000000..073394bb2 --- /dev/null +++ b/hw/xwin/xlaunch/window/dialog.h @@ -0,0 +1,54 @@ +/* + * 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. + */ +#ifndef __DIALOG_H__ +#define __DIALOG_H__ + +#include "window.h" +class CBaseDialog : public CWindow +{ + private: + int result; + protected: + static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual INT_PTR DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + public: + CBaseDialog(); + int Execute(); +}; + +class CDialog : public CBaseDialog +{ + private: + std::string resourcename; + protected: + virtual INT_PTR DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual HWND CreateWindowHandle(); + public: + CDialog(const char *res); +}; + + +#endif diff --git a/hw/xwin/xlaunch/window/util.cc b/hw/xwin/xlaunch/window/util.cc new file mode 100644 index 000000000..fb7e87297 --- /dev/null +++ b/hw/xwin/xlaunch/window/util.cc @@ -0,0 +1,1112 @@ +/* + * 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. + */ +#include "util.h" + +std::string win32_error::message(DWORD errorcode) +{ + LPVOID lpMsgBuf; + if (!FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errorcode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL )) + { + return "Unknown error in FormatMessage"; + } + + std::string ret((LPCTSTR)lpMsgBuf); + LocalFree( lpMsgBuf ); + return ret; +} + +void MessageDebug::debug(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, const char *prefix) +{ +#ifdef _DEBUG + static const char *psn_notify[] = { + "PSN_SETACTIVE", + "PSN_KILLACTIVE", + "PSN_APPLY", + "PSN_RESET", + NULL, + "PSN_HELP", + "PSN_WIZBACK", + "PSN_WIZNEXT", + "PSN_WIZFINISH", + "PSN_QUERYCANCEL" }; + if (uMsg == WM_NOTIFY) + { + LPNMHDR pnmh = (LPNMHDR)lParam; + int psn_index = -(int)pnmh->code - 200; + if (psn_index >= 0 && psn_index < 10 && psn_notify[psn_index]) + printf("%s: %08x %04x WM_NOTIFY (%s)\n", prefix, hwnd, wParam, psn_notify[psn_index]); + else if (pnmh->code < NOTIFY_NAMES_LEN && notify_names[pnmh->code]) + printf("%s: %08x %04x WM_NOTIFY (%s)\n", prefix, hwnd, wParam, notify_names[pnmh->code]); + else + printf("%s: %08x %04x WM_NOTIFY (%u)\n", prefix, hwnd, wParam, pnmh->code); + } + else if (uMsg >= MESSAGE_NAMES_LEN) + if (uMsg >= WM_USER) + printf("%s: %08x %04x %08x WM_USER + %d\n", prefix, hwnd, wParam, lParam, uMsg - WM_USER); + else + printf("%s: %08x %04x %08x %d\n", prefix, hwnd, wParam, lParam, uMsg); + else if (uMsg >= 0 && uMsg < MESSAGE_NAMES_LEN && message_names[uMsg]) + printf("%s: %08x %04x %08x %s\n", prefix, hwnd, wParam, lParam, message_names[uMsg]); +#endif +} + + +const char * MessageDebug::message_names[MESSAGE_NAMES_LEN] = { + "WM_NULL", + "WM_CREATE", + "WM_DESTROY", + "WM_MOVE", + "4", + "WM_SIZE", + "WM_ACTIVATE", + "WM_SETFOCUS", + "WM_KILLFOCUS", + "9", + "WM_ENABLE", + "WM_SETREDRAW", + "WM_SETTEXT", + "WM_GETTEXT", + "WM_GETTEXTLENGTH", + "WM_PAINT", + "WM_CLOSE", + "WM_QUERYENDSESSION", + "WM_QUIT", + "WM_QUERYOPEN", + "WM_ERASEBKGND", + "WM_SYSCOLORCHANGE", + "WM_ENDSESSION", + "23", + "WM_SHOWWINDOW", + "25", + "WM_WININICHANGE", + "WM_DEVMODECHANGE", + "WM_ACTIVATEAPP", + "WM_FONTCHANGE", + "WM_TIMECHANGE", + "WM_CANCELMODE", + NULL /* WM_SETCURSOR */, + "WM_MOUSEACTIVATE", + "WM_CHILDACTIVATE", + "WM_QUEUESYNC", + "WM_GETMINMAXINFO", + "37", + "WM_PAINTICON", + "WM_ICONERASEBKGND", + "WM_NEXTDLGCTL", + "41", + "WM_SPOOLERSTATUS", + "WM_DRAWITEM", + "WM_MEASUREITEM", + "WM_DELETEITEM", + "WM_VKEYTOITEM", + "WM_CHARTOITEM", + "WM_SETFONT", + "WM_GETFONT", + "WM_SETHOTKEY", + "WM_GETHOTKEY", + "52", + "53", + "54", + "WM_QUERYDRAGICON", + "56", + "WM_COMPAREITEM", + "58", + "59", + "60", + "61", + "62", + "63", + "64", + "WM_COMPACTING", + "66", + "67", + "WM_COMMNOTIFY", + "69", + "WM_WINDOWPOSCHANGING", + "WM_WINDOWPOSCHANGED", + "WM_POWER", + "73", + "WM_COPYDATA", + "WM_CANCELJOURNAL", + "76", + "77", + "WM_NOTIFY", + "79", + "WM_INPUTLANGCHANGEREQUEST", + "WM_INPUTLANGCHANGE", + "WM_TCARD", + "WM_HELP", + "WM_USERCHANGED", + "WM_NOTIFYFORMAT", + "86", + "87", + "88", + "89", + "90", + "91", + "92", + "93", + "94", + "95", + "96", + "97", + "98", + "99", + "100", + "101", + "102", + "103", + "104", + "105", + "106", + "107", + "108", + "109", + "110", + "111", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "119", + "120", + "121", + "122", + "WM_CONTEXTMENU", + "WM_STYLECHANGING", + "WM_STYLECHANGED", + "WM_DISPLAYCHANGE", + "WM_GETICON", + "WM_SETICON", + "WM_NCCREATE", + "WM_NCDESTROY", + "WM_NCCALCSIZE", + NULL /* WM_NCHITTEST */, + "WM_NCPAINT", + "WM_NCACTIVATE", + "WM_GETDLGCODE", + "WM_SYNCPAINT", + "137", + "138", + "139", + "140", + "141", + "142", + "143", + "144", + "145", + "146", + "147", + "148", + "149", + "150", + "151", + "152", + "153", + "154", + "155", + "156", + "157", + "158", + "159", + NULL /* WM_NCMOUSEMOVE */, + "WM_NCLBUTTONDOWN", + "WM_NCLBUTTONUP", + "WM_NCLBUTTONDBLCLK", + "WM_NCRBUTTONDOWN", + "WM_NCRBUTTONUP", + "WM_NCRBUTTONDBLCLK", + "WM_NCMBUTTONDOWN", + "WM_NCMBUTTONUP", + "WM_NCMBUTTONDBLCLK", + "170", + "171", + "172", + "173", + "174", + "175", + "176", + "177", + "178", + "179", + "180", + "181", + "182", + "183", + "184", + "185", + "186", + "187", + "188", + "189", + "190", + "191", + "192", + "193", + "194", + "195", + "196", + "197", + "198", + "199", + "200", + "201", + "202", + "203", + "204", + "205", + "206", + "207", + "208", + "209", + "210", + "211", + "212", + "213", + "214", + "215", + "216", + "217", + "218", + "219", + "220", + "221", + "222", + "223", + "224", + "225", + "226", + "227", + "228", + "229", + "230", + "231", + "232", + "233", + "234", + "235", + "236", + "237", + "238", + "239", + "240", + "241", + "242", + "243", + "244", + "245", + "246", + "247", + "248", + "249", + "250", + "251", + "252", + "253", + "254", + "255", + "WM_KEYDOWN", + "WM_KEYUP", + "WM_CHAR", + "WM_DEADCHAR", + "WM_SYSKEYDOWN", + "WM_SYSKEYUP", + "WM_SYSCHAR", + "WM_SYSDEADCHAR", + "WM_CONVERTREQUESTEX", + "265", + "266", + "267", + "268", + "WM_IME_STARTCOMPOSITION", + "WM_IME_ENDCOMPOSITION", + "WM_IME_KEYLAST", + "WM_INITDIALOG", + "WM_COMMAND", + "WM_SYSCOMMAND", + NULL /* WM_TIMER */, + "WM_HSCROLL", + "WM_VSCROLL", + "WM_INITMENU", + "WM_INITMENUPOPUP", + "280", + "281", + "282", + "283", + "284", + "285", + "286", + "WM_MENUSELECT", + "WM_MENUCHAR", + "WM_ENTERIDLE", + "290", + "291", + "292", + "293", + "294", + "295", + "296", + "297", + "298", + "299", + "300", + "301", + "302", + "303", + "304", + "305", + "WM_CTLCOLORMSGBOX", + "WM_CTLCOLOREDIT", + "WM_CTLCOLORLISTBOX", + "WM_CTLCOLORBTN", + "WM_CTLCOLORDLG", + "WM_CTLCOLORSCROLLBAR", + "WM_CTLCOLORSTATIC", + "313", + "314", + "315", + "316", + "317", + "318", + "319", + "320", + "321", + "322", + "323", + "324", + "325", + "326", + "327", + "328", + "329", + "330", + "331", + "332", + "333", + "334", + "335", + "336", + "337", + "338", + "339", + "340", + "341", + "342", + "343", + "344", + "345", + "346", + "347", + "348", + "349", + "350", + "351", + "352", + "353", + "354", + "355", + "356", + "357", + "358", + "359", + "360", + "361", + "362", + "363", + "364", + "365", + "366", + "367", + "368", + "369", + "370", + "371", + "372", + "373", + "374", + "375", + "376", + "377", + "378", + "379", + "380", + "381", + "382", + "383", + "384", + "385", + "386", + "387", + "388", + "389", + "390", + "391", + "392", + "393", + "394", + "395", + "396", + "397", + "398", + "399", + "400", + "401", + "402", + "403", + "404", + "405", + "406", + "407", + "408", + "409", + "410", + "411", + "412", + "413", + "414", + "415", + "416", + "417", + "418", + "419", + "420", + "421", + "422", + "423", + "424", + "425", + "426", + "427", + "428", + "429", + "430", + "431", + "432", + "433", + "434", + "435", + "436", + "437", + "438", + "439", + "440", + "441", + "442", + "443", + "444", + "445", + "446", + "447", + "448", + "449", + "450", + "451", + "452", + "453", + "454", + "455", + "456", + "457", + "458", + "459", + "460", + "461", + "462", + "463", + "464", + "465", + "466", + "467", + "468", + "469", + "470", + "471", + "472", + "473", + "474", + "475", + "476", + "477", + "478", + "479", + "480", + "481", + "482", + "483", + "484", + "485", + "486", + "487", + "488", + "489", + "490", + "491", + "492", + "493", + "494", + "495", + "496", + "497", + "498", + "499", + "500", + "501", + "502", + "503", + "504", + "505", + "506", + "507", + "508", + "509", + "510", + "511", + NULL /* WM_MOUSEMOVE */, + "WM_LBUTTONDOWN", + "WM_LBUTTONUP", + "WM_LBUTTONDBLCLK", + "WM_RBUTTONDOWN", + "WM_RBUTTONUP", + "WM_RBUTTONDBLCLK", + "WM_MBUTTONDOWN", + "WM_MBUTTONUP", + "WM_MBUTTONDBLCLK", + "WM_MOUSEWHEEL", + "WM_XBUTTONDOWN", + "WM_XBUTTONUP", + "WM_XBUTTONDBLCLK", + "526", + "527", + "WM_PARENTNOTIFY", + "WM_ENTERMENULOOP", + "WM_EXITMENULOOP", + "WM_NEXTMENU", + "WM_SIZING", + "WM_CAPTURECHANGED", + "WM_MOVING", + "535", + "WM_POWERBROADCAST", + "WM_DEVICECHANGE", + "538", + "539", + "540", + "541", + "542", + "543", + "WM_MDICREATE", + "WM_MDIDESTROY", + "WM_MDIACTIVATE", + "WM_MDIRESTORE", + "WM_MDINEXT", + "WM_MDIMAXIMIZE", + "WM_MDITILE", + "WM_MDICASCADE", + "WM_MDIICONARRANGE", + "WM_MDIGETACTIVE", + "554", + "555", + "556", + "557", + "558", + "559", + "WM_MDISETMENU", + "WM_ENTERSIZEMOVE", + "WM_EXITSIZEMOVE", + "WM_DROPFILES", + "WM_MDIREFRESHMENU", + "565", + "566", + "567", + "568", + "569", + "570", + "571", + "572", + "573", + "574", + "575", + "576", + "577", + "578", + "579", + "580", + "581", + "582", + "583", + "584", + "585", + "586", + "587", + "588", + "589", + "590", + "591", + "592", + "593", + "594", + "595", + "596", + "597", + "598", + "599", + "600", + "601", + "602", + "603", + "604", + "605", + "606", + "607", + "608", + "609", + "610", + "611", + "612", + "613", + "614", + "615", + "616", + "617", + "618", + "619", + "620", + "621", + "622", + "623", + "624", + "625", + "626", + "627", + "628", + "629", + "630", + "631", + "632", + "633", + "634", + "635", + "636", + "637", + "638", + "639", + "640", + "WM_IME_SETCONTEXT", + "WM_IME_NOTIFY", + "WM_IME_CONTROL", + "WM_IME_COMPOSITIONFULL", + "WM_IME_SELECT", + "WM_IME_CHAR", + "647", + "648", + "649", + "650", + "651", + "652", + "653", + "654", + "655", + "WM_IME_KEYDOWN", + "WM_IME_KEYUP", + "658", + "659", + "660", + "661", + "662", + "663", + "664", + "665", + "666", + "667", + "668", + "669", + "670", + "671", + "672", + "WM_MOUSEHOVER", + "674", + "WM_MOUSELEAVE", + "676", + "677", + "678", + "679", + "680", + "681", + "682", + "683", + "684", + "685", + "686", + "687", + "688", + "689", + "690", + "691", + "692", + "693", + "694", + "695", + "696", + "697", + "698", + "699", + "700", + "701", + "702", + "703", + "704", + "705", + "706", + "707", + "708", + "709", + "710", + "711", + "712", + "713", + "714", + "715", + "716", + "717", + "718", + "719", + "720", + "721", + "722", + "723", + "724", + "725", + "726", + "727", + "728", + "729", + "730", + "731", + "732", + "733", + "734", + "735", + "736", + "737", + "738", + "739", + "740", + "741", + "742", + "743", + "744", + "745", + "746", + "747", + "748", + "749", + "750", + "751", + "752", + "753", + "754", + "755", + "756", + "757", + "758", + "759", + "760", + "761", + "762", + "763", + "764", + "765", + "766", + "767", + "WM_CUT", + "WM_COPY", + "WM_PASTE", + "WM_CLEAR", + "WM_UNDO", + "WM_RENDERFORMAT", + "WM_RENDERALLFORMATS", + "WM_DESTROYCLIPBOARD", + "WM_DRAWCLIPBOARD", + "WM_PAINTCLIPBOARD", + "WM_VSCROLLCLIPBOARD", + "WM_SIZECLIPBOARD", + "WM_ASKCBFORMATNAME", + "WM_CHANGECBCHAIN", + "WM_HSCROLLCLIPBOARD", + "WM_QUERYNEWPALETTE", + "WM_PALETTEISCHANGING", + "WM_PALETTECHANGED", + "WM_HOTKEY", + "787", + "788", + "789", + "790", + "WM_PRINT", + "WM_PRINTCLIENT", + "793", + "794", + "795", + "796", + "797", + "798", + "799", + "800", + "801", + "802", + "803", + "804", + "805", + "806", + "807", + "808", + "809", + "810", + "811", + "812", + "813", + "814", + "815", + "816", + "817", + "818", + "819", + "820", + "821", + "822", + "823", + "824", + "825", + "826", + "827", + "828", + "829", + "830", + "831", + "832", + "833", + "834", + "835", + "836", + "837", + "838", + "839", + "840", + "841", + "842", + "843", + "844", + "845", + "846", + "847", + "848", + "849", + "850", + "851", + "852", + "853", + "854", + "855", + "856", + "857", + "858", + "859", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "867", + "868", + "869", + "870", + "871", + "872", + "873", + "874", + "875", + "876", + "877", + "878", + "879", + "880", + "881", + "882", + "883", + "884", + "885", + "886", + "887", + "888", + "889", + "890", + "891", + "892", + "893", + "894", + "895", + "896", + "897", + "898", + "899", + "900", + "901", + "902", + "903", + "904", + "905", + "906", + "907", + "908", + "909", + "910", + "911", + "912", + "913", + "914", + "915", + "916", + "917", + "918", + "919", + "920", + "921", + "922", + "923", + "924", + "925", + "926", + "927", + "928", + "929", + "930", + "931", + "932", + "933", + "934", + "935", + "936", + "937", + "938", + "939", + "940", + "941", + "942", + "943", + "944", + "945", + "946", + "947", + "948", + "949", + "950", + "951", + "952", + "953", + "954", + "955", + "956", + "957", + "958", + "959", + "960", + "961", + "962", + "963", + "964", + "965", + "966", + "967", + "968", + "969", + "970", + "971", + "972", + "973", + "974", + "975", + "976", + "977", + "978", + "979", + "980", + "981", + "982", + "983", + "984", + "985", + "986", + "987", + "988", + "989", + "990", + "991", + "992", + "993", + "994", + "995", + "996", + "997", + "998", + "999", + "1000", + "1001", + "1002", + "1003", + "1004", + "1005", + "1006", + "1007", + "1008", + "1009", + "1010", + "1011", + "1012", + "1013", + "1014", + "1015", + "1016", + "1017", + "1018", + "1019", + "1020", + "1021", + "1022", + "1023" +}; + diff --git a/hw/xwin/xlaunch/window/util.h b/hw/xwin/xlaunch/window/util.h new file mode 100644 index 000000000..cd21da657 --- /dev/null +++ b/hw/xwin/xlaunch/window/util.h @@ -0,0 +1,53 @@ +/* + * 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. + */ +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include <windows.h> +#include <stdexcept> + + +class win32_error : public std::runtime_error +{ + public: + static std::string message(DWORD code); + DWORD errorcode; + win32_error(const std::string &msg,DWORD code = GetLastError()) : std::runtime_error(msg + ":" + message(code)), errorcode(code) {}; +}; + +#define MESSAGE_NAMES_LEN 1024 +#define NOTIFY_NAMES_LEN 0 +class MessageDebug +{ + protected: + static const char * message_names[MESSAGE_NAMES_LEN]; + static const char * notify_names[NOTIFY_NAMES_LEN]; + public: + static void debug(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam, const char *prefix); +}; + + +#endif diff --git a/hw/xwin/xlaunch/window/window.cc b/hw/xwin/xlaunch/window/window.cc new file mode 100755 index 000000000..cca3a485a --- /dev/null +++ b/hw/xwin/xlaunch/window/window.cc @@ -0,0 +1,284 @@ +/* + * 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. + */ + +#include "window.h" +#include "util.h" +#include <stdio.h> +#include <stdexcept> + +CWindow::CWindowClass CWindow::windowClass("CWINDOWCLASS", DefWindowProc); + +CWindow::CWindowClass::CWindowClass(const char *_name, WNDPROC _wndproc) : + wndproc(_wndproc), atom(0), classname(_name) +{ + Register(); +} + +CWindow::CWindowClass::~CWindowClass() +{ + UnregisterClass(classname.c_str(), GetModuleHandle(NULL)); +} + +void CWindow::CWindowClass::Register() +{ + WNDCLASSEX wndclass; + memset(&wndclass, 0, sizeof(wndclass)); + wndclass.cbSize = sizeof(wndclass); + wndclass.style = 0; + wndclass.lpfnWndProc = wndproc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = GetModuleHandle(NULL); + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = classname.c_str(); + wndclass.hIconSm = NULL; + atom = RegisterClassEx(&wndclass); + if (atom == 0) + throw win32_error("RegisterClassEx failed"); +} + +CWindow::CWindow(const char *_title) : title(_title), hwnd(NULL), parent(NULL), bounds(), owndproc(NULL), showing(FALSE) +{ + style = WS_CHILD; + exstyle = 0; +} + +HWND CWindow::CreateWindowHandle() +{ + HWND ret = CreateWindowEx( + exstyle, + GetClassName(), + title.c_str(), + style, + bounds.left, + bounds.top, + bounds.width, + bounds.height, + parent, + NULL, + GetModuleHandle(NULL), + 0 + ); + if (ret == NULL) + throw win32_error("CreateWindowEx failed"); + return ret; +} + +void CWindow::Create() +{ + if (hwnd != NULL) + return; + hwnd = CreateWindowHandle(); + if (hwnd == NULL) + throw win32_error("Could not create window"); + + // Reset the error code + DWORD err = 0; + SetLastError(err); + + // Attach the object reference to the window handle + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); + err = GetLastError(); + if (err != 0) + throw win32_error("SetWindowLongPtr failed",err); + + // Set the window proc + owndproc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WindowProc); + err = GetLastError(); + if (err != 0) + throw win32_error("SetWindowLongPtr failed",err); +} + +const char *CWindow::GetClassName() +{ + return windowClass.GetClassName(); +} + +LRESULT CALLBACK CWindow::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + MessageDebug::debug(hwnd, uMsg, wParam, lParam, __FUNCTION__); + CWindow* window = (CWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (window != NULL) + return window->Dispatch(hwnd, uMsg, wParam, lParam); + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +LRESULT CWindow::Dispatch(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_SIZE: + bounds.width = LOWORD(lParam); + bounds.height = LOWORD(lParam); + break; + case WM_MOVE: + bounds.left = LOWORD(lParam); + bounds.top = LOWORD(lParam); + break; + case WM_DESTROY: + showing = FALSE; + break; + } + if (owndproc) + return CallWindowProc(owndproc, hwnd, uMsg, wParam, lParam); + else + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +void CWindow::Show() +{ + if (hwnd == NULL) + Create(); + ShowWindow(hwnd, SW_SHOWNORMAL); +} + +int CWindow::ShowModal() +{ + MSG msg; + BOOL bRet; + showing = TRUE; + Show(); + + while( showing && (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) + { + if (bRet == -1) + { + // handle the error and possibly exit + } + else + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return 0; +} + +void CWindow::SetLeft(int left) +{ + bounds.left = left; + if (hwnd) + if (!SetWindowPos(hwnd, NULL, + bounds.left, bounds.top, + 0, 0, + SWP_NOZORDER | SWP_NOSIZE)) + throw win32_error("SetWindowPos failed"); +} + +void CWindow::SetTop(int top) +{ + bounds.top = top; + if (hwnd) + if (!SetWindowPos(hwnd, NULL, + bounds.left, bounds.top, + 0, 0, + SWP_NOZORDER | SWP_NOSIZE)) + throw win32_error("SetWindowPos failed"); +} + +void CWindow::SetWidth(int width) +{ + bounds.width = width; + if (hwnd) + if (!SetWindowPos(hwnd, NULL, + 0, 0, + bounds.width, bounds.height, + SWP_NOZORDER | SWP_NOMOVE)) + throw win32_error("SetWindowPos failed"); +} +void CWindow::SetHeight(int height) +{ + bounds.height = height; + if (hwnd) + if (!SetWindowPos(hwnd, NULL, + 0, 0, + bounds.width, bounds.height, + SWP_NOZORDER | SWP_NOMOVE)) + throw win32_error("SetWindowPos failed"); +} + +void CWindow::SetBounds(int left, int top, int width, int height) +{ + bounds = CBoundary(left, top, width, height); + if (hwnd) + if (!SetWindowPos(hwnd, NULL, + bounds.left, bounds.top, + bounds.width, bounds.height, + SWP_NOZORDER)) + throw win32_error("SetWindowPos failed"); +} + +void CWindow::SetBounds(const RECT &rect) +{ + bounds = rect; + if (hwnd) + if (!SetWindowPos(hwnd, NULL, + bounds.left, bounds.top, + bounds.width, bounds.height, + SWP_NOZORDER)) + throw win32_error("SetWindowPos failed"); +} + +HWND CWindow::GetHandle() +{ + if (hwnd == NULL) + Create(); + return hwnd; +} + +void CWindow::SetParent(CWindow *window) +{ + parent = window->GetHandle(); + if (hwnd != NULL) + if (::SetParent(hwnd, parent) == NULL) + throw win32_error("SetParent failed"); + +} + +void CWindow::SetStyle(DWORD style) +{ + this->style = style; + SetLastError(0); + if (hwnd) + SetWindowLong(hwnd, GWL_STYLE, style); + int err = GetLastError(); + if (err != 0) + throw win32_error("SetWindowLong failed", err); +} + +void CWindow::SetExStyle(DWORD exstyle) +{ + this->exstyle = exstyle; + SetLastError(0); + if (hwnd) + SetWindowLong(hwnd, GWL_EXSTYLE, exstyle); + int err = GetLastError(); + if (err != 0) + throw win32_error("SetWindowWLong failed", err); +} diff --git a/hw/xwin/xlaunch/window/window.h b/hw/xwin/xlaunch/window/window.h new file mode 100755 index 000000000..baf401405 --- /dev/null +++ b/hw/xwin/xlaunch/window/window.h @@ -0,0 +1,114 @@ +/* + * 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. + */ +#ifndef __WINDOW_H__ +#define __WINDOW_H__ + +#include <windows.h> +#include <string> + +class CDialog; +class CWindow +{ + friend class CDialog; + public: + struct CBoundary + { + int left; + int top; + int width; + int height; + CBoundary() : + left(0), top(0), width(0), height(0) {}; + CBoundary(int x, int y, int w, int h) : + left(x), top(y), width(w), height(h) {}; + CBoundary(const RECT &r) : + left(r.left), top(r.top), width(r.right-r.left), height(r.bottom-r.top) {}; + }; + class CWindowClass + { + private: + WNDPROC wndproc; + ATOM atom; + std::string classname; + protected: + void Register(); + public: + CWindowClass(const char *name, WNDPROC wndproc); + ~CWindowClass(); + const char *GetClassName() { return classname.c_str(); }; + }; + private: + static CWindowClass windowClass; + + std::string title; + DWORD exstyle; + DWORD style; + CBoundary bounds; + HWND hwnd; + HWND parent; + WNDPROC owndproc; + + BOOL showing; + + protected: + + virtual const char *GetClassName(); + virtual HWND CreateWindowHandle(); + static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + public: + CWindow(const char *title); + virtual void Create(); + + virtual int ShowModal(); + + void Show(); + void Hide(); + + void SetWidth(int width); + void SetHeight(int height); + void SetLeft(int left); + void SetTop(int top); + int GetWidth() { return bounds.width; }; + int GetHeight() { return bounds.height; }; + int GetLeft() { return bounds.left; }; + int GetTop() { return bounds.top; }; + + void SetBounds(int left, int top, int width, int height); + void SetBounds(const RECT &rect); + + void SetStyle(DWORD style); + DWORD GetStyle() { return style; }; + + void SetExStyle(DWORD exstyle); + DWORD GetExStyle() { return exstyle; }; + + HWND GetHandle(); + void SetParent(CWindow *window); + + virtual LRESULT Dispatch(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +}; + +#endif diff --git a/hw/xwin/xlaunch/window/wizard.cc b/hw/xwin/xlaunch/window/wizard.cc new file mode 100755 index 000000000..9d6c71193 --- /dev/null +++ b/hw/xwin/xlaunch/window/wizard.cc @@ -0,0 +1,244 @@ +/*
+ * 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.
+ */
+#include "wizard.h"
+#include "util.h"
+
+CWizard::CWizard() : pages()
+{
+};
+
+void CWizard::AddPage(const PROPSHEETPAGE &page)
+{
+ pages.push_back(page);
+}
+
+void CWizard::AddPage(const char *page, HINSTANCE instance)
+{
+ PROPSHEETPAGE psp;
+ if (instance == NULL)
+ instance = GetModuleHandle(NULL);
+
+ memset(&psp, 0, sizeof(psp));
+ psp.dwSize = sizeof(PROPSHEETPAGE);
+ psp.dwFlags = PSP_DEFAULT;
+ psp.hInstance = instance;
+ psp.pszTemplate = page;
+ psp.pfnDlgProc = WizardDialogProc;
+ psp.lParam = (LPARAM)this;
+
+ AddPage(psp);
+}
+
+void CWizard::AddPage(DWORD id, DWORD title, DWORD subtitle, HINSTANCE instance)
+{
+ PROPSHEETPAGE psp;
+ if (instance == NULL)
+ instance = GetModuleHandle(NULL);
+
+ memset(&psp, 0, sizeof(psp));
+ psp.dwSize = sizeof(PROPSHEETPAGE);
+ psp.dwFlags = PSP_DEFAULT;
+#if _WIN32_IE >= 0x0500
+ if (title != 0)
+ {
+ psp.dwFlags |= PSP_USEHEADERTITLE;
+ psp.pszHeaderTitle = MAKEINTRESOURCE(title);
+ }
+ if (subtitle != 0)
+ {
+ psp.dwFlags |= PSP_USEHEADERSUBTITLE;
+ psp.pszHeaderSubTitle = MAKEINTRESOURCE(subtitle);
+ }
+#endif
+
+ psp.hInstance = instance;
+ psp.pszTemplate = MAKEINTRESOURCE(id);
+ psp.pfnDlgProc = WizardDialogProc;
+ psp.lParam = (LPARAM)this;
+
+ AddPage(psp);
+}
+
+HWND CWizard::CreateWindowHandle()
+{
+ PROPSHEETHEADER psh;
+ HWND ret;
+
+ PrepareSheetHeader(psh, FALSE);
+ ret = (HWND)PropertySheet(&psh);
+ free(psh.phpage);
+ if (ret == NULL)
+ throw win32_error("PropertySheet failed");
+ return ret;
+}
+
+int CWizard::ShowModal()
+{
+ PROPSHEETHEADER psh;
+ int ret;
+
+ PrepareSheetHeader(psh, TRUE);
+ ret = PropertySheet(&psh);
+ free(psh.phpage);
+ return ret;
+}
+
+void CWizard::PrepareSheetHeader(PROPSHEETHEADER &psh, BOOL modal)
+{
+ HPROPSHEETPAGE *phpage = (HPROPSHEETPAGE*)malloc(pages.size() * sizeof(HPROPSHEETPAGE));
+ DWORD modeflag;
+
+ if (modal)
+ modeflag = 0;
+ else
+ modeflag = PSH_MODELESS;
+
+ for (unsigned i = 0; i < pages.size(); i++)
+ {
+ phpage[i] = CreatePropertySheetPage(&pages[i]);
+ if (phpage[i] == NULL)
+ {
+ DWORD err = GetLastError();
+ free(phpage);
+ throw win32_error("CreatePropertySheetPage failed", err);
+ }
+ }
+
+ memset(&psh, 0, sizeof(psh));
+ psh.dwSize = sizeof(PROPSHEETHEADER);
+#if _WIN32_IE >= 0x0500
+ psh.dwFlags = PSH_WIZARD97 | modeflag;
+#else
+ psh.dwFlags = PSH_WIZARD | modeflag;
+#endif
+ psh.hwndParent = NULL;
+ psh.hInstance = GetModuleHandle(NULL);
+ psh.pszIcon = NULL;
+ psh.pszCaption = (LPSTR) "Cell Properties";
+ psh.nPages = pages.size();
+ psh.nStartPage = 0;
+ psh.phpage = phpage;
+ psh.pfnCallback = NULL;
+}
+
+DWORD CWizard::PageID(unsigned index)
+{
+ if (index < pages.size() && IS_INTRESOURCE(pages[index].pszTemplate))
+ return (DWORD)pages[index].pszTemplate;
+ return (DWORD)-1;
+}
+
+unsigned CWizard::PageIndex(PROPSHEETPAGE *psp)
+{
+ for (unsigned i = 0; i < pages.size(); i++)
+ {
+ if (IS_INTRESOURCE(psp->pszTemplate) || IS_INTRESOURCE(pages[i].pszTemplate ))
+ {
+ if (psp->pszTemplate == pages[i].pszTemplate)
+ return i;
+ }
+ else if (psp->pszTemplate && pages[i].pszTemplate)
+ {
+ if (strcmp(psp->pszTemplate, pages[i].pszTemplate) == 0)
+ return i;
+ }
+ }
+ return (unsigned)-1;
+}
+
+INT_PTR CWizard::DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ return CBaseDialog::DlgDispatch(hwndDlg, uMsg, wParam, lParam);
+}
+
+INT_PTR CWizard::PageDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, PROPSHEETPAGE *psp)
+{
+ LPNMHDR pnmh = (LPNMHDR)lParam;
+ DWORD flags;
+ unsigned pageindex;
+ switch (uMsg)
+ {
+ case WM_NOTIFY:
+ switch (pnmh->code)
+ {
+ case PSN_SETACTIVE:
+#ifdef _DEBUG
+ printf("PSN_SETACTIVE %d\n", PageIndex(psp));
+#endif
+ pageindex = PageIndex(psp);
+ if (pageindex != (unsigned)-1)
+ {
+ flags = 0;
+ if (pageindex > 0)
+ flags |= PSWIZB_BACK;
+ if ((unsigned)pageindex + 1 == pages.size())
+ flags |= PSWIZB_FINISH;
+ if ((unsigned)pageindex + 1 < pages.size())
+ flags |= PSWIZB_NEXT;
+ PropSheet_SetWizButtons(GetParent(hwndDlg), flags);
+ }
+ WizardActivate(hwndDlg, pageindex);
+ break;
+ case PSN_WIZNEXT:
+ if (WizardNext(hwndDlg, PageIndex(psp)))
+ return TRUE;
+ break;
+ case PSN_WIZBACK:
+ if (WizardBack(hwndDlg, PageIndex(psp)))
+ return TRUE;
+ break;
+ case PSN_WIZFINISH:
+ if (WizardFinish(hwndDlg, PageIndex(psp)))
+ return TRUE;
+ DestroyWindow(GetParent(hwndDlg));
+ case PSN_RESET:
+ if (WizardReset(hwndDlg, PageIndex(psp)))
+ return TRUE;
+ DestroyWindow(GetParent(hwndDlg));
+ break;
+ }
+ }
+ return DlgDispatch(hwndDlg, uMsg, wParam, lParam);
+}
+
+
+INT_PTR CALLBACK CWizard::WizardDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ MessageDebug::debug(hwndDlg, uMsg, wParam, lParam, __FUNCTION__);
+ PROPSHEETPAGE *psp = (PROPSHEETPAGE*)lParam;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)psp);
+ break;
+ }
+ psp = (PROPSHEETPAGE*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ CWizard* wizard = psp?(CWizard*)psp->lParam:NULL;
+ if (wizard != NULL)
+ return wizard->PageDispatch(hwndDlg, uMsg, wParam, lParam, psp);
+ return FALSE;
+}
+
diff --git a/hw/xwin/xlaunch/window/wizard.h b/hw/xwin/xlaunch/window/wizard.h new file mode 100755 index 000000000..a2361c51c --- /dev/null +++ b/hw/xwin/xlaunch/window/wizard.h @@ -0,0 +1,59 @@ +/*
+ * 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.
+ */
+#ifndef __WIZARD_H__
+#define __WIZARD_H__
+
+#include "dialog.h"
+#include <vector>
+
+#define _WIN32_IE 0x0500
+#include <prsht.h>
+
+class CWizard : public CBaseDialog
+{
+ private:
+ std::vector<PROPSHEETPAGE> pages;
+ void PrepareSheetHeader(PROPSHEETHEADER &psh, BOOL modal);
+ protected:
+ virtual HWND CreateWindowHandle();
+ static INT_PTR CALLBACK WizardDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual INT_PTR DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual INT_PTR PageDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, PROPSHEETPAGE *psp);
+ virtual unsigned PageIndex(PROPSHEETPAGE *psp);
+ virtual DWORD PageID(unsigned index);
+ virtual BOOL WizardNext(HWND hwndDlg, unsigned index) { return FALSE; }
+ virtual BOOL WizardBack(HWND hwndDlg, unsigned index) { return FALSE; }
+ virtual BOOL WizardFinish(HWND hwndDlg, unsigned index) { return FALSE; }
+ virtual BOOL WizardReset(HWND hwndDlg, unsigned index) { return FALSE; }
+ virtual BOOL WizardActivate(HWND hwndDlg, unsigned index) { return FALSE; }
+ public:
+ CWizard();
+ void AddPage(const PROPSHEETPAGE &page);
+ void AddPage(const char *page, HINSTANCE instance = NULL);
+ void AddPage(DWORD id, DWORD title, DWORD subtitle, HINSTANCE instance = NULL);
+ virtual int ShowModal();
+};
+#endif
diff --git a/include/xwin-config.h.in b/include/xwin-config.h.in new file mode 100644 index 000000000..c8de11073 --- /dev/null +++ b/include/xwin-config.h.in @@ -0,0 +1,24 @@ +/* + * xwin-config.h.in + * + * This file has all defines used in the xwin ddx + * + */ +#include <dix-config.h> + +/* Winsock networking */ +#undef HAS_WINSOCK + +/* Cygwin has /dev/windows for signaling new win32 messages */ +#undef HAS_DEVWINDOWS + +/* Switch on debug messages */ +#undef CYGDEBUG +#undef CYGWINDOWING_DEBUG +#undef CYGMULTIWINDOW_DEBUG + +/* Define to 1 if unsigned long is 64 bits. */ +#undef _XSERVER64 + +/* Do we require our own snprintf? */ +#undef NEED_SNPRINTF |