xserver: Branch 'master'

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Sun Apr 20 08:35:55 PDT 2008


 .gitignore                                 |    1 
 configure.ac                               |   74 +
 hw/Makefile.am                             |    7 
 hw/xwin/ChangeLog                          |  683 +++++++++
 hw/xwin/InitInput.c                        |  177 ++
 hw/xwin/InitOutput.c                       | 1144 +++++++++++++++
 hw/xwin/Makefile.am                        |  197 ++
 hw/xwin/README                             |  141 +
 hw/xwin/X-boxed.ico                        |binary
 hw/xwin/X.ico                              |binary
 hw/xwin/XWin.man                           |  287 +++
 hw/xwin/XWin.rc                            |  109 +
 hw/xwin/XWinrc.man                         |  180 ++
 hw/xwin/_usr_X11R6_lib_X11_system.XWinrc   |  125 +
 hw/xwin/ddraw.h                            | 2106 +++++++++++++++++++++++++++++
 hw/xwin/win.h                              | 1453 ++++++++++++++++++++
 hw/xwin/winallpriv.c                       |  172 ++
 hw/xwin/winauth.c                          |  131 +
 hw/xwin/winblock.c                         |  106 +
 hw/xwin/winclip.c                          |   42 
 hw/xwin/winclipboard.h                     |  164 ++
 hw/xwin/winclipboardinit.c                 |  143 +
 hw/xwin/winclipboardtextconv.c             |  159 ++
 hw/xwin/winclipboardthread.c               |  477 ++++++
 hw/xwin/winclipboardunicode.c              |   69 
 hw/xwin/winclipboardwndproc.c              |  622 ++++++++
 hw/xwin/winclipboardwrappers.c             |  541 +++++++
 hw/xwin/winclipboardxevents.c              |  796 ++++++++++
 hw/xwin/wincmap.c                          |  674 +++++++++
 hw/xwin/winconfig.c                        | 1150 +++++++++++++++
 hw/xwin/winconfig.h                        |  343 ++++
 hw/xwin/wincreatewnd.c                     |  644 ++++++++
 hw/xwin/wincursor.c                        |  614 ++++++++
 hw/xwin/windialogs.c                       |  788 ++++++++++
 hw/xwin/winengine.c                        |  336 ++++
 hw/xwin/winerror.c                         |  143 +
 hw/xwin/winfillsp.c                        |  866 +++++++++++
 hw/xwin/winfont.c                          |   80 +
 hw/xwin/wingc.c                            |  256 +++
 hw/xwin/wingetsp.c                         |  192 ++
 hw/xwin/winglobals.c                       |  138 +
 hw/xwin/winkeybd.c                         |  637 ++++++++
 hw/xwin/winkeybd.h                         |  309 ++++
 hw/xwin/winkeyhook.c                       |  194 ++
 hw/xwin/winkeymap.h                        |  136 +
 hw/xwin/winkeynames.h                      |  202 ++
 hw/xwin/winlayouts.h                       |  257 +++
 hw/xwin/winmessages.h                      | 1030 ++++++++++++++
 hw/xwin/winmisc.c                          |  152 ++
 hw/xwin/winmouse.c                         |  341 ++++
 hw/xwin/winms.h                            |   46 
 hw/xwin/winmsg.c                           |  179 ++
 hw/xwin/winmsg.h                           |   50 
 hw/xwin/winmultiwindowclass.c              |  325 ++++
 hw/xwin/winmultiwindowclass.h              |  114 +
 hw/xwin/winmultiwindowicons.c              |  478 ++++++
 hw/xwin/winmultiwindowshape.c              |  211 ++
 hw/xwin/winmultiwindowwindow.c             | 1054 ++++++++++++++
 hw/xwin/winmultiwindowwm.c                 | 1440 +++++++++++++++++++
 hw/xwin/winmultiwindowwndproc.c            | 1049 ++++++++++++++
 hw/xwin/winnativegdi.c                     |  546 +++++++
 hw/xwin/winpfbdd.c                         |  684 +++++++++
 hw/xwin/winpixmap.c                        |  235 +++
 hw/xwin/winpolyline.c                      |   57 
 hw/xwin/winprefs.c                         |  822 +++++++++++
 hw/xwin/winprefs.h                         |  162 ++
 hw/xwin/winprefslex.l                      |  116 +
 hw/xwin/winprefsyacc.y                     |  353 ++++
 hw/xwin/winpriv.c                          |  134 +
 hw/xwin/winpriv.h                          |   15 
 hw/xwin/winprocarg.c                       | 1551 +++++++++++++++++++++
 hw/xwin/winpushpxl.c                       |  225 +++
 hw/xwin/winrandr.c                         |  141 +
 hw/xwin/winregistry.c                      |   71 
 hw/xwin/winresource.h                      |   55 
 hw/xwin/winrop.c                           |  144 +
 hw/xwin/winscrinit.c                       |  781 ++++++++++
 hw/xwin/winsetsp.c                         |  186 ++
 hw/xwin/winshaddd.c                        | 1442 +++++++++++++++++++
 hw/xwin/winshadddnl.c                      | 1454 ++++++++++++++++++++
 hw/xwin/winshadgdi.c                       | 1324 ++++++++++++++++++
 hw/xwin/wintrayicon.c                      |  210 ++
 hw/xwin/winvalargs.c                       |  188 ++
 hw/xwin/winvideo.c                         |  210 ++
 hw/xwin/winwakeup.c                        |   71 
 hw/xwin/winwin32rootless.c                 | 1092 +++++++++++++++
 hw/xwin/winwin32rootlesswindow.c           |  476 ++++++
 hw/xwin/winwin32rootlesswndproc.c          | 1325 ++++++++++++++++++
 hw/xwin/winwindow.c                        |  649 ++++++++
 hw/xwin/winwindow.h                        |  150 ++
 hw/xwin/winwindowswm.c                     |  663 +++++++++
 hw/xwin/winwndproc.c                       | 1288 +++++++++++++++++
 hw/xwin/xlaunch/COPYING                    |   25 
 hw/xwin/xlaunch/Makefile                   |   79 +
 hw/xwin/xlaunch/config.cc                  |  282 +++
 hw/xwin/xlaunch/config.h                   |   60 
 hw/xwin/xlaunch/main.cc                    |  700 +++++++++
 hw/xwin/xlaunch/resources/dialog.rc        |  118 +
 hw/xwin/xlaunch/resources/fullscreen.bmp   |binary
 hw/xwin/xlaunch/resources/images.rc        |   29 
 hw/xwin/xlaunch/resources/multiwindow.bmp  |binary
 hw/xwin/xlaunch/resources/nodecoration.bmp |binary
 hw/xwin/xlaunch/resources/resources.h      |   99 +
 hw/xwin/xlaunch/resources/resources.rc     |   30 
 hw/xwin/xlaunch/resources/strings.rc       |  108 +
 hw/xwin/xlaunch/resources/windowed.bmp     |binary
 hw/xwin/xlaunch/window/dialog.cc           |   86 +
 hw/xwin/xlaunch/window/dialog.h            |   54 
 hw/xwin/xlaunch/window/util.cc             | 1112 +++++++++++++++
 hw/xwin/xlaunch/window/util.h              |   53 
 hw/xwin/xlaunch/window/window.cc           |  284 +++
 hw/xwin/xlaunch/window/window.h            |  114 +
 hw/xwin/xlaunch/window/wizard.cc           |  244 +++
 hw/xwin/xlaunch/window/wizard.h            |   59 
 include/xwin-config.h.in                   |   24 
 115 files changed, 44913 insertions(+), 1 deletion(-)

New commits:
commit 4bcfed2f9cf5dbf682d3bc98873ba97c4efdff44
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sun Apr 20 08:35:42 2008 -0700

    Revert "Removed XWin DDX"
    
    This reverts commit 6550078b0925f754e3eec3bbce94dbfe5de8c419.
    
    Doctor, I'm starting to get a pulse...

diff --git a/.gitignore b/.gitignore
index afd5415..548e784 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 ca16c5a..d3a2317 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 011a280..c2b9571 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 0000000..aca2ffc
--- /dev/null
+++ b/hw/xwin/ChangeLog
@@ -0,0 +1,683 @@
+2006-03-03  Alan Hourihane  <alanh at 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 at 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 at 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 at 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 at 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 0000000..6a850cd
--- /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 0000000..d215981
--- /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 at 2 ; 2nd monitor offset 100,100 size 800x600\n"
+      "\t -screen 0 1024x768 at 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 0000000..5ffba12
--- /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 0000000..219fd13
--- /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 at 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 at 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
new file mode 100755
index 0000000..0727042
Binary files /dev/null and b/hw/xwin/X-boxed.ico differ
diff --git a/hw/xwin/X.ico b/hw/xwin/X.ico
new file mode 100644
index 0000000..d47168f
Binary files /dev/null and b/hw/xwin/X.ico differ
diff --git a/hw/xwin/XWin.man b/hw/xwin/XWin.man
new file mode 100644
index 0000000..4e70c19
--- /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 0000000..749c0f5
--- /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 0000000..eba3fb6
--- /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 0000000..d9c2d42
--- /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 0000000..2eb7c26
--- /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 0000000..3ab3249
--- /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 0000000..21ccd9b
--- /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 0000000..b57a35a
--- /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 0000000..abea60e
--- /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 0000000..aab7d63
--- /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 0000000..445c01b
--- /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 0000000..6a0cbaf
--- /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 0000000..fd2e696
--- /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 0000000..081abd5
--- /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 0000000..ba86915
--- /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 0000000..802a740
--- /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 0000000..2cfe0ff
--- /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 0000000..d4c617b
--- /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 0000000..7ebe002
--- /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 0000000..38966bf
--- /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, &regkey) &&
+          !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 0000000..4b56d63
--- /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 0000000..796a085
--- /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 0000000..021b8b8
--- /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 0000000..ab06b0d
--- /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 0000000..f0bc671
--- /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 0000000..7d29213
--- /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 0000000..702f34f
--- /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 at 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 0000000..af3e90d
--- /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 0000000..107d87a
--- /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 0000000..03f7f10
--- /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 at 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 0000000..fddada3
--- /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 0000000..d574f20
--- /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 0000000..09eed14
--- /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 0000000..53d91e6
--- /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 0000000..3862f03
--- /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 0000000..7c16337
--- /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 0000000..cc07524
--- /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 0000000..ae50dc4
--- /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 0000000..8e66981
--- /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 0000000..1507dd3
--- /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 0000000..1ad30dc
--- /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 0000000..d0464f7
--- /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 0000000..611dd69
--- /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 0000000..5b47c39
--- /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 0000000..c635ab2
--- /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 0000000..45ed093
--- /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 0000000..33deae3
--- /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 0000000..037c881
--- /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 0000000..5401ecd
--- /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 0000000..20ff9f7
--- /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 0000000..48a467a
--- /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 0000000..13fc105
--- /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 0000000..050c71a
--- /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 0000000..db9dd34
--- /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 0000000..30e587d
--- /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 0000000..d9e09de
--- /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 0000000..a4c1abc
--- /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 0000000..2a54ff2
--- /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 0000000..29221cf
--- /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 0000000..d4505c8
--- /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 0000000..7139cba
--- /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 at 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 at 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 0000000..72ef2d5
--- /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 0000000..7b5b135
--- /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 0000000..3571b14
--- /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 0000000..5aa8840
--- /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 0000000..f481892
--- /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 at 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 0000000..9dc4c3d
--- /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 0000000..f894d6c
--- /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 at 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 0000000..a2c1dc9
--- /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 at 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 0000000..47cc382
--- /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 0000000..04cc2f7
--- /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 0000000..054a8e9
--- /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 0000000..038e097
--- /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 0000000..529ca76
--- /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 0000000..e1eece3
--- /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 0000000..6f4e2c9
--- /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 0000000..dedcd7a
--- /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 0000000..859aafd
--- /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 0000000..1600996
--- /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 0000000..9c49d64
--- /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 0000000..e1994de
--- /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 0000000..29ea81f
--- /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 0000000..c7fa844
--- /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 0000000..f7cf923
--- /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 0000000..b6bf65a
--- /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 0000000..f0aed3c
--- /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 0000000..2247d3a
--- /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 0000000..8b00df4
--- /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
new file mode 100755
index 0000000..0d051f0
Binary files /dev/null and b/hw/xwin/xlaunch/resources/fullscreen.bmp differ
diff --git a/hw/xwin/xlaunch/resources/images.rc b/hw/xwin/xlaunch/resources/images.rc
new file mode 100755
index 0000000..2eac53c
--- /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
new file mode 100755
index 0000000..0755c87
Binary files /dev/null and b/hw/xwin/xlaunch/resources/multiwindow.bmp differ
diff --git a/hw/xwin/xlaunch/resources/nodecoration.bmp b/hw/xwin/xlaunch/resources/nodecoration.bmp
new file mode 100755
index 0000000..e9e1ce6
Binary files /dev/null and b/hw/xwin/xlaunch/resources/nodecoration.bmp differ
diff --git a/hw/xwin/xlaunch/resources/resources.h b/hw/xwin/xlaunch/resources/resources.h
new file mode 100755
index 0000000..4700051
--- /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 0000000..07fd52f
--- /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 0000000..5a9cd28
--- /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
new file mode 100755
index 0000000..9eff2bf
Binary files /dev/null and b/hw/xwin/xlaunch/resources/windowed.bmp differ
diff --git a/hw/xwin/xlaunch/window/dialog.cc b/hw/xwin/xlaunch/window/dialog.cc
new file mode 100755
index 0000000..76e5c35
--- /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 0000000..073394b
--- /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 0000000..fb7e872
--- /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 0000000..cd21da6
--- /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 0000000..cca3a48
--- /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 0000000..baf4014
--- /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 0000000..9d6c711
--- /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 0000000..a2361c5
--- /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 0000000..c8de110
--- /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


More information about the xorg-commit mailing list