Release 941227

Tue Dec 27 13:35:16 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [*/Imakefile]
	All objects files are now kept in their respective directory.

	* [README]
	Rewrote most of it.

	* [objects/bitblt.c]
	Rewrote BitBlt() to look right in every case, while minimizing
	the impact on performance. Not really finished yet.

	* [objects/bitmap.c] [objects/dc.c]
	Fixed bug with pattern brushes.

	* [objects/clipping.c] [windows/painting.c]
	Fixes for logical coordinates.

	* [objects/color.c] [windows/graphics.c]
	Fixed GetPixel() to return the correct color, and made it faster.

	* [objects/region.c]
	Fixed bug in CombineRgn() when one of the region is empty.

Fri Dec 22 01:42:57 MET 1994		  Dag Asheim (dash@ifi.uio.no)

	* [Configure]
	Don't assume that expr handles '==', use '=' instead.
	Give a (hopefully informative) message if imake fails.
diff --git a/ANNOUNCE b/ANNOUNCE
new file mode 100644
index 0000000..7212bee
--- /dev/null
+++ b/ANNOUNCE
@@ -0,0 +1,42 @@
+This is release 941227 of Wine the MS Windows emulator.  This is still a
+developer's only release.  There are many bugs and many unimplemented API
+features.  Most applications still do not work.
+
+Patches should be submitted to "wine-new@amscons.com".  Please don't forget
+to include a ChangeLog entry.  I'll try to make a new release every Sunday.
+
+WHAT'S NEW with Wine-941227: (see ChangeLog for details)
+	- Better BitBlt()
+	- Lots of bug fixes
+
+See the README file in the distribution for installation instructions.
+
+Because of lags created by using mirror, this message may reach you before
+the release is available at the ftp sites.  The sources will be available
+from the following locations:
+
+	sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-941227.tar.gz
+	aris.com:/pub/linux/ALPHA/Wine/development/Wine-941227.tar.gz
+	tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-941227.tar.gz
+	ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-941227.tar.gz
+	ftp.wonderland.org:/Wine/Wine-941227.tar.gz
+
+If you submitted a patch, please check to make sure it has been
+included in the new release.
+
+New developers should read the info files available from the ftp sites.
+The files NEWBIE-PROJECTS, DEVELOPERS-HINTS and Wine.FAQ are required
+reading for new developers.
+
+Wine is available thanks to the work of Bob Amstadt, Dag Asheim,
+Martin Ayotte, Erik Bos, John Brezak, Andrew Bulhak, John Burton,
+Paul Falstad, Peter Galbavy, Jeffrey Hsu, Miguel de Icaza,
+Alexandre Julliard, Jon Konrath, Scott A. Laird, Martin von Loewis,
+Kenneth MacDonald, Peter MacDonald, David Metcalfe, Michael Patra,
+John Richardson, Johannes Ruscheinski, Yngvi Sigurjonsson,
+Rick Sladkey, William Smith, Jon Tombs, Linus Torvalds, Carl Williams,
+Karl Guenter Wuensch, and Eric Youngdale.
+
+--
+Alexandre Julliard
+julliard@lamisun.epfl.ch
diff --git a/COPYRIGHT b/COPYRIGHT
deleted file mode 100644
index 45db164..0000000
--- a/COPYRIGHT
+++ /dev/null
@@ -1,3 +0,0 @@
-/*
- * Copyright  Robert J. Amstadt, 1993
- */
diff --git a/ChangeLog b/ChangeLog
index b5b9a04..a2a0da4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+Tue Dec 27 13:35:16 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)
+
+	* [*/Imakefile]
+	All objects files are now kept in their respective directory.
+
+	* [README]
+	Rewrote most of it.
+
+	* [objects/bitblt.c]
+	Rewrote BitBlt() to look right in every case, while minimizing
+	the impact on performance. Not really finished yet.
+
+	* [objects/bitmap.c] [objects/dc.c]
+	Fixed bug with pattern brushes.
+
+	* [objects/clipping.c] [windows/painting.c]
+	Fixes for logical coordinates.
+
+	* [objects/color.c] [windows/graphics.c]
+	Fixed GetPixel() to return the correct color, and made it faster.
+
+	* [objects/region.c]
+	Fixed bug in CombineRgn() when one of the region is empty.
+
+Fri Dec 22 01:42:57 MET 1994		  Dag Asheim (dash@ifi.uio.no)
+
+	* [Configure]
+	Don't assume that expr handles '==', use '=' instead.
+	Give a (hopefully informative) message if imake fails.
+
 ----------------------------------------------------------------------
 Wed Dec  7 14:52:25 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)
 
diff --git a/Configure b/Configure
index d95d508..d1b3650 100644
--- a/Configure
+++ b/Configure
@@ -56,10 +56,10 @@
 fi
 
 LANGS=`echo En rc/sysres_*.rc | sed -e 's/rc\/sysres_//g' -e 's/\.rc//g' -e 's/ /\//g;'`
-while	expr "$LANGS" : ".*$LANG" == 0 > /dev/null
+while	expr "$LANGS" : ".*$LANG" = 0 > /dev/null
 do
 	prompt "Language ($LANGS)" LANG En
-	if	expr "$LANGS" : ".*$LANG" == 0 > /dev/null
+	if	expr "$LANGS" : ".*$LANG" = 0 > /dev/null
 	then
 		echo "\"$LANG\" is not a supported language."
 	fi
@@ -209,22 +209,37 @@
 
 echo
 echo "Creating Makefiles.  This may take a while."
-xmkmf -a
+if xmkmf -a
+then :
+else	cat << EOF
+
+WARNING:  The exit status of the command 'xmkmf -a' indicates an error.
+Maybe the Wine directory is incomplete, or Imake (see 'man xmkmf imake')
+is incorrectly configured?  In the latter case, it might be easiest to
+reinstall X11 to get a new copy of Imake.
+EOF
+fi
 
 if [ 0 -lt `find . -name "*.rej" -print | wc -l` ]
 then
 	cat << EOF
 
-WARNING:  You have some files named "*.rej".  Rejected patch files?
-Maybe you tried to upgrade Wine by diff-files, and that patch failed.
-If something doesn't work, this might be the reason.  See "man patch".
+WARNING:  You have some files named '*.rej', which usually indicates
+rejected patch files.  Maybe you tried to upgrade Wine with 'patch',
+and that some of the patches failed?  If something doesn't work, this
+might be the reason.  See 'man patch' (especially the '-p' option).
 
 List of "*.rej" files:
 
 EOF
 	find . -name "*.rej" -print
-	exit 1
 fi
 
-echo
-echo "Configure finished.  Do 'make' to compile Wine."
+if [ -f ./Makefile ]
+then
+	echo
+	echo "Configure finished.  Do 'make' to compile Wine."
+else
+	echo
+	echo "*** There was a problem with 'imake': the main Makefile has not be created."
+fi
diff --git a/Imakefile b/Imakefile
index 1f0b13b..ea60138 100644
--- a/Imakefile
+++ b/Imakefile
@@ -21,18 +21,15 @@
 
 #define IHaveSubdirs
 #define	PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' 'MAKE=$(MAKE)'\
-			'DEFINES=$(DEFINES)'
+			'DEFINES=$(DEFINES)' 'LD=$(LD)'
 
 COMMONSUBDIRS = \
 	controls \
-	etc \
-	include \
 	rc \
 	loader \
 	misc \
 	multimedia \
 	objects \
-	test \
 	windows
 
 EMUSUBDIRS = \
@@ -48,35 +45,33 @@
 WINEDIR = $(LIBDIR)/wine
 
 COMMONOBJS = \
-	controls.o \
-	loader.o \
-	misc.o \
-	multimedia.o \
-	objects.o \
-	rc.o \
-	windows.o
+	controls/controls.o \
+	loader/loader.o \
+	misc/misc.o \
+	multimedia/multimedia.o \
+	objects/objects.o \
+	rc/rc.o \
+	windows/windows.o
 
 /*
  * WARNING: if1632.o must be the first object file because its code must be
  *          linked at the lowest possible addresses.
  */
 EMUOBJS = \
-	if1632.o \
-	debugger.o \
-	memory.o \
-	miscemu.o \
-	opcodes.o \
-	readline.o
+	if1632/if1632.o \
+	debugger/debugger.o \
+	memory/memory.o \
+	miscemu/miscemu.o
 
 LIBOBJS = \
-	toolkit.o
+	toolkit/toolkit.o
 
 #ifndef WINELIB
 SUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS)
-OBJS = $(COMMONOBJS) $(EMUOBJS)
+OBJS = $(EMUOBJS) $(COMMONOBJS)
 #else
 SUBDIRS = $(COMMONSUBDIRS) $(LIBSUBDIRS)
-OBJS = $(COMMONOBJS) $(LIBOBJS)
+OBJS = $(LIBOBJS) $(COMMONOBJS)
 #endif
 
 #ifdef i386BsdArchitecture
@@ -100,9 +95,9 @@
 AllTarget(wine.sym)
 
 #ifndef WINELIB
-NormalProgramTarget(wine,$(EMUOBJS) $(COMMONOBJS),$(DEPXLIB),$(XPM_LIB) $(XLIB),$(SYSLIBS))
+NormalProgramTarget(wine,$(OBJS),$(DEPXLIB),$(XPM_LIB) $(XLIB),$(SYSLIBS))
 #else
-NormalLibraryTarget(wine,$(LIBOBJS) $(COMMONOBJS))
+NormalLibraryTarget(wine,$(OBJS))
 #endif
 
 wine.sym: wine
@@ -119,6 +114,6 @@
 	etags `find . -name '*.[chS]' -print`
 
 distclean: clean
-	$(RM) `find . -name Makefile -print`
 	echo "/* autoconf.h generated automatically.  Run Configure */" >autoconf.h
 	echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
+	$(RM) `find . -name Makefile -print`
diff --git a/README b/README
index 20e5748..d172aa9 100644
--- a/README
+++ b/README
@@ -1,36 +1,20 @@
-0. LICENSE
+1. INTRODUCTION
 
-You may without charge, royalty or other payment, copy and
-distribute copies of this work and derivative works of this work
-in source or binary form provided that: (1) 
-you appropriately publish on each copy an appropriate copyright
-notice; (2) faithfully reproduce all prior copyright notices
-included in the original work (you may also add your own
-copyright notice); and (3) agree to indemnify and hold all prior
-authors, copyright holders and licensors of the work harmless
-from and against all damages arising from use of the work.
+Wine is a program that allows running MS-Windows programs under X11.
+It consists of a program loader, that loads and executes an
+MS-Windows binary, and of an emulation library that translates Windows
+API calls to their Unix/X11 equivalent.
 
-You may distribute sources of derivative works of the work
-provided that (1) (a) all source files of the original work that
-have been modified, (b) all source files of the derivative work
-that contain any party of the original work, and (c) all source
-files of the derivative work that are necessary to compile, link
-and run the derivative work without unresolved external calls and
-with the same functionality of the original work ("Necessary
-Sources") carry a prominent notice explaining the nature and date
-of the modification and/or creation.  You are encouraged to make
-the Necessary Sources available under this license in order to
-further the development and acceptance of the work.
+Wine is free software. See the file LICENSE for the details.
+Basically, you can do anything with it, except claim that you wrote it.
 
-EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED
-WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING
-BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A
-PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE.  EXCEPT AS
-OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR
-LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+Important note: current versions of Wine include a built-in debugger
+for 16-bit code, that is based on code from gdb. This means that if
+you redistribute a version of Wine that includes this debugger, you
+must follow the terms of the GNU General Public License.
 
-1. COMPILATION:
+
+2. COMPILATION
 
 You must have one of:
 
@@ -42,15 +26,25 @@
 if you're running *BSD).  The executable "wine" will be built.  "wine"
 will load and run 16-bit Windows' executables. 
 
+To upgrade to a new release by using a patch file, first cd to the
+top-level directory of the release (the one containing this README
+file). Then do a "make clean", and patch the release with:
+
+    gunzip -c patch-file | patch -p1
+
+where "patch-file" is the name of the patch file (something like
+Wine-yymmdd.diff.gz). You can then re-run "./Configure", and then
+run "make". 
 
 
-2. SETUP:
+3. SETUP
 
 Wine requires you to have a file /usr/local/etc/wine.conf (you can
 supply a different name when configuring wine) or a file called .winerc
-in your homedirectory.
+in your home directory.
 
-The formatstyle of this config file is just like a windows .ini file.
+The format of this config file is just like a Windows .ini file.
+The file wine.ini contains a config file example.
 
 Here's an explanation of each section:
 
@@ -60,10 +54,10 @@
 default: none
 
 This section is used to specify the root directory of each `dos'drive 
-as windows' applications require a dos/mswindows based diskdrive & 
+as Windows' applications require a dos/mswindows based diskdrive & 
 directory scheme. 
 
-If you mounted you dos-partition as /dos and installed microsoft windows 
+If you mounted your dos-partition as /dos and installed Microsoft Windows 
 in c:\windows than you should specify c=/dos in the drives section.
 
 * [wine]
@@ -81,7 +75,7 @@
 format: temp = <directory>
 default: c:\temp
 
-Used to specify a directory where windows applications can store temporary
+Used to specify a directory where Windows applications can store temporary
 files.
 
 format: path = <directories separated by semi-colons>
@@ -92,7 +86,7 @@
 format: systemresources = <filename>
 default: c:\temp
 
-Used to specify the name of sysres.dll, a dll which is used by wine itself.
+Used to specify the name of sysres.dll, a dll which is used by Wine itself.
 
 * [serialports]
 
@@ -126,10 +120,9 @@
 Used to specify which messages will be included in the logfile.
 
 
+4. RUNNING PROGRAMS
 
-3. RUNNING PROGRAMS
-
-When invoking wine, you must specify the entire path to the executable,
+When invoking Wine, you must specify the entire path to the executable,
 or a filename only.
 
 For example: to run Windows' solitaire:
@@ -141,410 +134,22 @@
 
 	wine /usr/windows/sol.exe  (using a unixfilename)
 
-note: the path of the file will also be added to the path when
+Note: the path of the file will also be added to the path when
       a full name is supplied on the commandline.
 
 Have a nice game of solitaire, but be careful.  Emulation isn't perfect.
-So, occassionally it will crash.
+So, occasionally it may crash.
 
 
+5. GETTING MORE INFORMATION
 
-4. EXAMPLE CONFIGFILE
+The best place to get help or to report bugs is the Usenet newsgroup
+comp.emulators.ms-windows.wine. The Wine FAQ is posted there every
+month.
 
-----------------------------------------------------------------------------
-[drives]
-a=/mnt/fd0
-c=/dos
-d=~/Wine
+If you add something, or fix a bug, please send a patch to
+wine-new@amscons.com for inclusion in the next release.
 
-[wine]
-windows=c:\windows
-system=c:\windows\system
-temp=c:\temp
-path=c:\windows;c:\windows\system;c:\winapps\word\;c:\winapps\pctools
-systemresources=./sysres.dll
-
-[serialports]
-com1=/dev/cua1
-com2=/dev/cua1
-
-[parallelports]
-lpt1=/dev/lp0
-
-[spy]
-;File=CON
-;File=spy.log
-Exclude=WM_TIMER;WM_SETCURSOR;WM_MOUSEMOVE;WM_NCHITTEST;WM_NCACTIVATE;WM_GETDLGCODE;
-Include=WM_COMMAND;
-
-----------------------------------------------------------------------------
-
-
-5. BUILD:
-
-    The documentation for the build program is in the file build-spec.txt
-
-
-6. FINALE:
-
-Good luck,
-
-	If you successfully add anything, please send me a copy.
-
-Bob Amstadt
-bob@amscons.com
-
-
-7. WHAT'S NEW
-
-WHAT'S NEW with Wine-940602: (see ChangeLog for details)
-	- CLOCK.EXE runs.
-	- ABORT command added to debugger.
-	- Windows environment is now imported from the UNIX environment.
-	- Use of save unders and backing store are now the default.  Resource
-	  and command line options have been added to disable these things.
-	- Assorted new driver functions
-	- GetAsyncKeyState()
-	- More metafile support
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940524: (see ChangeLog for details)
-	- New menu functions
-	- EnumObjects()
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940518: (see ChangeLog for details)
-	- debugger improvements
-	- bug fixes to get some dialog boxes working.
-	- skeleton for passing MCI functions.
-	- beginnings of metafile support.
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940510: (see ChangeLog for details)
-	- debugger improvements
-	- mmsystem
-	- ShellAbout() and AboutDlgProc()
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940505: (see ChangeLog for details)
-	- faster color_stretch()
-	- SetSysMenu(), GetCursor(), GetDesktopWindow()
-	- WSAGetXbyY() now non-blocking	
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940420: (see ChangeLog for details)
-	- new property functions
-	- new listbox and combo box functions
-	- GrayString() and CallGrayStringProc()
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940412: (see ChangeLog for details)
-	- menuing improvements
-	- drawing performance improvements
-	- beginnings of hooks
-	- MDI maximizing and tiling
-	- improvements in winsock implementation
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940405: (see ChangeLog for details)
-	- Mouse activation of menus working again
-	- GetprocAddress()
-	- SetDIBitsToDevice()
-	- FindWindow()
-	- int 10hm 25h and 26h
-	- in, inb, out, outb emulation
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940329: (see ChangeLog for details)
-	- MDI: child windows can be created, activated and cascaded.
-	- -depth option
-	- support for dithered brushes
-	- GetNearestColor(), RealizeDefaultPalette(), 
-	  GetSystemPaletteEntries(), and SelectPalette()
-	- System colors read from WIN.INI
-	- Keyboard menu manipulation (mouse is temporarily broken)
-	- GetFreeSystemResources()
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940322: (see ChangeLog for details)
-	- Speed improvements in bitmaps and mouse messages
-	- More MDI support.  More to come next week...
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940315: (see ChangeLog for details)
-	- Beginnings of MDI support.  More to come next week...
-	- Stress DLL
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940309: (see ChangeLog for details)
-	- New "exclude" and "include" filters for spy feature.  See sample
-	  wine.ini for details.
-	- -desktop and -name options (see ChangeLog)
-	- GetFreeSpace() and CreateIcon()
-	- and many many bug fixes!
-
-WHAT'S NEW with Wine-940301: (see ChangeLog for details)
-	- NEW Configure script to set compile time options!
-	- Support for filesystems with short (less than 14 chars) filenames.
-	- Clipboard functions!
-	- and more...
-
-WHAT'S NEW with Wine-940223: (see ChangeLog for details)
-	- FreeBSD support
-	- FloodFill()
-	- Desktop window support
-	- Menu fixes
-	- and more...
-
-WHAT'S NEW with Wine-940216: (see ChangeLog for details)
-	- Many many bug fixes
-	- Switched to using Imakefile's instead of Makefile's.
-	- Lot's of changes for libwine.a
-
-WHAT'S NEW with Wine-940209: (see ChangeLog for details)
-	- Many many bug fixes
-	- Minor directory structure reorganization
-	- New GetModule*() functions.
-	- WINSOCK DLL
-	- First stab at Wine as a library
-
-WHAT'S NEW with Wine-940201: (see ChangeLog for details)
-	- Support for huge data structures.
-	- FreeBSD support.
-	- Many many bug fixes
-
-WHAT'S NEW with version 0.8: (see ChangeLog for details)
-	- Eliminated Xt-dependent code.  Thanks to Alexandre and Martin.
-	- EnumWindows() and EnumChildWindows()
-	- Activating and deactivating of windows.
-	- More work on system menus.
-
-WHAT'S NEW with version 0.7: (see ChangeLog for details)
-	- Eliminated Xt-dependent code.  Thanks to Alexandre and Martin.
-	- Other bug fixes.
-	- IsWIndowEnabled() and EnableWindow() now implemented.
-	- New command line options.
-
-WHAT'S NEW with version 0.6: (see ChangeLog for details)
-	- Working towards elimination of Xt-dependent code.  Thanks to
-	  Alexandre and Martin.
-	- Other bug fixes.
-	- I added a rudimentary spy facility which can be turned
- 	  on from the wine.ini file.  See the sample wine.ini
-	  for details
-
-WHAT'S NEW with version 0.5: (see ChangeLog for details)
-	- Working towards elimination of Xt-dependent code.
-	- StretchBlt()
-	- GetClassName() & GetClassInfo()
-	- Implemented loader relocation types 5 and 6.
-
-WHAT'S NEW with version 0.4.14: (see ChangeLog for details)
-	- Bug fixes and enhancements
-	- Comm functions
-	- Text caret functions
-
-WHAT'S NEW with version 0.4.13: (see ChangeLog for details)
-	- Bug fixes
-	- GetCapture()
-	- More keyboard handling
-	- Polyline() and Polygon()
-
-WHAT'S NEW with version 0.4.12: (see ChangeLog for details)
-	- Bug fixes
-	- New DOS file functions
-	- Experimental Imakefiles
-
-WHAT'S NEW with version 0.4.11: (see ChangeLog for details)
-	- Bug fixes
-	- New cursor functions
-	- New file system handling
-	- Atoms
-
-WHAT'S NEW with version 0.4.10: (see ChangeLog for details)
-	- Bug fixes
-	- More scroll bar functions
-	- More icon and cursor handling
-
-WHAT'S NEW with version 0.4.9: (see ChangeLog for details)
-	- Bug fixes
-	- real MessageBox()
-	- New resource functions
-	- Icon functions
-	- Selector manipulation functions
-	- Catch()/Throw()
-
-WHAT'S NEW with version 0.4.7: (see ChangeLog for details)
-	- More dialog box functions
-	- More DOS interrupts
-	- NetBSD compatibility patches
-
-WHAT'S NEW with version 0.4.5: (see ChangeLog for details)
-	- Bug fixes
-	- focus routines
-	- dialog box functions
-	- improvements to control windows
-
-WHAT'S NEW with version 0.4.4: (see ChangeLog for details)
-	- Bug fixes
-	- New static control class
-	- Preliminary listbox, combobox and scrollbar controls
-	- System initialization file is now called "wine.ini", and
-	  may be located in the user's current directory, the
-	  user's home directory or any directory specified by
-	  the WINEPATH environment variable.
-	- The loader now searches the directories specified by the
-	  WINEPATH environment variable for programs and DLLs.
-	- Internal debugger now works on 386BSD.
-
-WHAT'S NEW with version 0.4.3: (see ChangeLog for details)
-	- Bug fixes
-	- Resource loading now able to load DLL resources
-	- Button control now based on GDI calls
-	- Preliminary system color support
-	- Miscellaneous window functions
-	- Limited debugging facility (sometimes hangs)
-
-WHAT'S NEW with version 0.4.2: (see ChangeLog for details)
-	- Bug fixes
-	- 32-bit callback functions allowed
-	- .INI file handling
-	- lstr* functions and ANSI<->OEM conversion functions.
-
-WHAT'S NEW with version 0.4.1: (see ChangeLog for details)
-	- Bug fixes
-	- Memory usage changes.
-
-WHAT'S NEW with version 0.4.0: (see ChangeLog for details)
-	- Wine now compiles and runs under NetBSD.  Patches are
-	  required for NetBSD.
-	- Wine stat patches included.  Add "-DWINESTAT" to the definition
-	  of COPTS in the main Makefile to activate.
-	- Preliminary keyboard handling.
-	- Button control window implemented.
-	- many other new functions added.
-
-WHAT'S NEW with version 0.3.1: (see ChangeLog for details)
-	- LineDDA() completed
-	- numerous bug fixes
-	- INT 1Ah implemented
-	- SOUND DLL implemented
-	- More of WIN87EM DLL implemented
-	- OpenFile() and friends implemented
-
-WHAT'S NEW with version 0.3.0: (see ChangeLog for details)
-	- Mouse capture
-	- Text justification and underlining
-	- Clipping
-	- LoadBitmap() completed
-	- Code generated by the Borland compiler should now work
-
-WHAT'S NEW with version 0.2.8: (see ChangeLog for details)
-	- Text functions from Alexandre
-	- INT 21h from Eric
-	- Menu improvements from David
-	- Bug fixes and GetProcAddress() stub from me
-
-WHAT'S NEW with version 0.2.7: (see ChangeLog for details)
-    - sol.exe gets further.  I did some debugging and now solitaire
-      stops when it tries to call GetTextExtent().  Any volunteers?
-    - Many DC updates from Alexandre.
-    - Menu updates to support underlining characters from David Metcalfe.
-
-WHAT'S NEW with version 0.2.6: (see ChangeLog for details)
-    - More region updates from Alexandre
-
-WHAT'S NEW with version 0.2.5: (see ChangeLog for details)
-    - Regions implemented by Alexandre
-    - More menuing code from me
-
-WHAT'S NEW with version 0.2.4: (see ChangeLog for details)
-    - Many improvements to GDI from Alexandre
-    - Many improvements to menu handling by me.
-
-WHAT'S NEW with version 0.2.3: (see ChangeLog for details)
-    - Bug fixes with SendMessage() and PostMessage()
-    - Preliminary menu support
-
-WHAT'S NEW with version 0.2.2: (see ChangeLog for details)
-    - Misc bug fixes
-    - More bitmap code
-    - Timers
-    - Memory DC's
-
-WHAT'S NEW with version 0.2.1:
-    - I have placed things into sub-directories.  The organization is
-      not finalized.  I imagine that the directory structure will
-      change as is necessary.  Files in the ./misc directory need
-      to be split apart and placed in apropriate directories.
-    - Tons of code from Alexandre.  He has constructed the framework
-      for handling GDI objects.  He has also provided code for DCEs.
-    - Local heap functions have been completed.
-    - Bug fixes in global.c and win.c
-    - New function GlobalQuickAlloc() combines GlobalAlloc() and
-      GlobalLock() into a single function call.
-    - New patch kit for Linux 0.99 pl11 kernel.  Thanks to Linus
-      who has graciously included our patches into the ALPHA patch
-      release cycle.
-
-WHAT'S NEW with version 0.2.0:
-    - Alexandre Julliard has provided a replacement for the Tcl code.
-      The new code uses Xlib and Xt directly with no intervening
-      interpretted language.  This should reduce the learning
-      curve for casual hackers.
-    - I changed all GLOBAL_ names to Global.
-
-WHAT'S NEW with version 0.1.1:
-    - I have completed global memory allocation, but I don't like it.
-      It is not 100% compatible with Windows.  I need some more kernel
-      modifications for 100% compatibility.
-    - Alexandre Julliard has provided written better emulation for
-      the Windows message queue.
-
-WHAT'S NEW with version 0.1.0:
-    - Latest patches from Alexandre Julliard.
-    - minor bug fix in if1632.S
-
-WHAT'S NEW with version 0.0.5:
-    - Patches from Alexandre Julliard.  Some integration with Tcl.
-    - Generic interface for callback procedures.  This will allow
-      callbacks into DLLs.
-    - MakeProcInstance() has been implemented but untested.
-
-WHAT'S NEW with version 0.0.4:
-    - Eric Youngdale modified wine.c and selector.c to allow loading
-      of Windows DLLs.
-    - Added global memory allocation routines (GlobalAlloc, GlobalFree,
-      and GlobalLock)
-    - Bitmap resource loading into global memory.
-
-WHAT'S NEW with version 0.0.3:
-    - Fixed bug with sector sizes.
-    - Registers at program startup are now set correctly.
-    - Segment fixups for relocatable-segment internal entry points.
-    - Fixed bug in DOS PSP structure.
-    - Some resource loading is done.
-    - Added "return" ordinal type to build program.
-    - Added comment capability to build program.
-
-WHAT'S NEW with version 0.0.2:
-
-    - Again thanks to Eric Youngdale for some very useful comments.
-    - The Windows startup code created by Micrsoft C 7.0 now runs 
-      to completion.
-    - Added a new patch to the kernel to increase the usable size of
-      the ldt to the full 32 entries currently allowed.
-    - Imported name relocations are now supported.
-    - Source code for my infamous test program is now included.
-    - A handful of basic Windows functions are now emulated.  See
-      "kernel.spec" for examples of how to use the build program.
-
-WHAT'S NEW with version 0.0.1:
-
-    - Eric Youngdale contributed countless improvements in memory
-      efficiency, bug fixes, and relocation.
-    - The build program has been completed.  It now lets you specify
-      how the main DLL entry point should interface to your emulation
-      library routines.  A brief description of how to build these
-      specifications is included in the file "build-spec.txt".
-    - The code to dispatch builtin DLL calls is complete, but untested.
+--
+Alexandre Julliard
+julliard@lamisun.epfl.ch
diff --git a/Wine.tmpl b/Wine.tmpl
index 13a84cc..e1f7e0b 100644
--- a/Wine.tmpl
+++ b/Wine.tmpl
@@ -8,24 +8,24 @@
 #ifndef MakeDllFromSpec
 #ifndef NewBuild
 #ifndef ShortNames
-#define MakeDllFromSpec(name,objfile)					@@\
+#define MakeDllFromSpec(name)						@@\
 Concat(dll_,name.S) Concat3(dll_,name,_tab.c): name.spec $(TOP)/tools/build  @@\
 	$(TOP)/tools/build name.spec					@@\
 
 #else /* ShortNames */
-#define MakeDllFromSpec(name,objfile)					@@\
+#define MakeDllFromSpec(name)						@@\
 Concat(dll_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/build   @@\
 	$(TOP)/tools/build name.spec					@@\
 
 #endif /* ShortNames */
 #else /* NewBuild */
 #ifndef ShortNames
-#define MakeDllFromSpec(name,objfile)					@@\
+#define MakeDllFromSpec(name)						@@\
 Concat(dll_,name.S) Concat(rly_,name.S) Concat3(dll_,name,_tab.c): name.spec $(TOP)/tools/newbuild  @@\
 	$(TOP)/tools/newbuild name.spec					@@\
 
 #else /* ShortNames */
-#define MakeDllFromSpec(name,objfile)					@@\
+#define MakeDllFromSpec(name)						@@\
 Concat(dll_,name.S) Concat(rly_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/newbuild   @@\
 	$(TOP)/tools/newbuild name.spec					@@\
 
diff --git a/controls/Imakefile b/controls/Imakefile
index 374441d..582965b 100644
--- a/controls/Imakefile
+++ b/controls/Imakefile
@@ -15,7 +15,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/controls/button.c b/controls/button.c
index 2e4ab5e..54c5df0 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -138,6 +138,7 @@
 		break;
 
 	case WM_LBUTTONUP:
+                if (GetCapture() != hWnd) break;
                 ReleaseCapture();
                 SendMessage( hWnd, BM_SETSTATE, FALSE, 0 );
                 GetClientRect( hWnd, &rect );
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 0eae52b..a6c260c 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -1,7 +1,8 @@
 #include "../Wine.tmpl"
 
-#define IHavSubDirs
-#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' 'MAKE=$(MAKE)'
+#define IHaveSubdirs
+#define	PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' 'MAKE=$(MAKE)'\
+			'LD=$(LD)'
 
 MODULE = debugger
 
@@ -16,21 +17,22 @@
 	lex.yy.c \
 	info.c
 
-OBJS = $(SRCS:.c=.o)
+SUBDIRS_OBJS = \
+	opcodes/opcodes.o \
+	readline/readline.o
+
+OBJS = $(SRCS:.c=.o) $(SUBDIRS_OBJS)
 
 /*
  * All the SUBDIR stuff
  */
 MakeSubdirs($(SUBDIRS))
-MakefileSubdirs($(SUBDIRS))
 DependSubdirs($(SUBDIRS))
-CleanSubdirs($(SUBDIRS))
-IncludesSubdirs($(SUBDIRS))
 
 /*
  * The main act
  */
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 
 depend:: dbg.tab.c dbg.tab.h lex.yy.c
 
diff --git a/debugger/opcodes/Imakefile b/debugger/opcodes/Imakefile
index fc12d01..0d94d3f 100644
--- a/debugger/opcodes/Imakefile
+++ b/debugger/opcodes/Imakefile
@@ -18,7 +18,7 @@
 #undef xi386
 #endif
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/debugger/readline/Imakefile b/debugger/readline/Imakefile
index e50e7c5..f780bd6 100644
--- a/debugger/readline/Imakefile
+++ b/debugger/readline/Imakefile
@@ -13,7 +13,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/etc/Imakefile b/etc/Imakefile
deleted file mode 100644
index a81b367..0000000
--- a/etc/Imakefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "../Wine.tmpl"
-
-MODULE = etc
-
-AllTarget()
-
-depend::
-
-includes::
diff --git a/if1632/Imakefile b/if1632/Imakefile
index 9812c1d..bd0bae2 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -39,23 +39,23 @@
 /*
  * If you add a new spec file, copy one of these lines
  */
-MakeDllFromSpec(commdlg,$(TOP)/$(MODULE))
-MakeDllFromSpec(gdi,$(TOP)/$(MODULE))
-MakeDllFromSpec(kernel,$(TOP)/$(MODULE))
-MakeDllFromSpec(keyboard,$(TOP)/$(MODULE))
-MakeDllFromSpec(shell,$(TOP)/$(MODULE))
-MakeDllFromSpec(mmsystem,$(TOP)/$(MODULE))
-MakeDllFromSpec(mouse,$(TOP)/$(MODULE))
-MakeDllFromSpec(sound,$(TOP)/$(MODULE))
-MakeDllFromSpec(stress,$(TOP)/$(MODULE))
-MakeDllFromSpec(system,$(TOP)/$(MODULE))
-MakeDllFromSpec(toolhelp,$(TOP)/$(MODULE))
-MakeDllFromSpec(unixlib,$(TOP)/$(MODULE))
-MakeDllFromSpec(user,$(TOP)/$(MODULE))
-MakeDllFromSpec(win87em,$(TOP)/$(MODULE))
-MakeDllFromSpec(winsock,$(TOP)/$(MODULE))
+MakeDllFromSpec(commdlg)
+MakeDllFromSpec(gdi)
+MakeDllFromSpec(kernel)
+MakeDllFromSpec(keyboard)
+MakeDllFromSpec(shell)
+MakeDllFromSpec(mmsystem)
+MakeDllFromSpec(mouse)
+MakeDllFromSpec(sound)
+MakeDllFromSpec(stress)
+MakeDllFromSpec(system)
+MakeDllFromSpec(toolhelp)
+MakeDllFromSpec(unixlib)
+MakeDllFromSpec(user)
+MakeDllFromSpec(win87em)
+MakeDllFromSpec(winsock)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 #ifndef WINELIB
@@ -63,7 +63,7 @@
 	$(TOP)/tools/build -p
 
 call.o: call.S pop.h
-	gcc -I. -c -o call.o call.S
+	$(CC) -I. -c -o call.o call.S
 #endif
 
 includes::
diff --git a/if1632/relay.c b/if1632/relay.c
index 0118a12..5a5b6cb 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -15,7 +15,6 @@
 #include <linux/unistd.h>
 #include <linux/head.h>
 #include <linux/ldt.h>
-#include <linux/segment.h>
 #endif
 
 #include "neexe.h"
diff --git a/include/Imakefile b/include/Imakefile
deleted file mode 100644
index 4821756..0000000
--- a/include/Imakefile
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "../Wine.tmpl"
-
-MODULE = include
-
-HEADERS = \
-	atom.h \
-	callback.h \
-	class.h \
-	combo.h \
-	cursor.h \
-	dce.h \
-	dialog.h \
-	dlls.h \
-	files.h \
-	gdi.h \
-	heap.h \
-	icon.h \
-	int21.h \
-	listbox.h \
-	menu.h \
-	message.h \
-	neexe.h \
-	prototypes.h \
-	regfunc.h \
-	scroll.h \
-	segmem.h \
-	user.h \
-	win.h \
-	windows.h \
-	wine.h
-
-AllTarget()
-
-depend::
-
-includes::
diff --git a/include/bitmap.h b/include/bitmap.h
index 280946f..7d730b7 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -1,21 +1,35 @@
 /*
  * GDI bitmap definitions
  *
- * Copyright 1993 Alexandre Julliard
+ * Copyright 1993, 1994  Alexandre Julliard
  */
 
 #ifndef BITMAP_H
 #define BITMAP_H
 
+#include <stdlib.h>
 #include <X11/Xlib.h>
 #include "windows.h"
 
+  /* objects/bitmap.c */
 extern BOOL BITMAP_Init(void);
 
+  /* objects/dib.c */
+extern int DIB_GetImageWidthBytes( int width, int depth );
+extern int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse );
+
   /* GCs used for B&W and color bitmap operations */
 extern GC BITMAP_monoGC, BITMAP_colorGC;
 
 #define BITMAP_GC(bmp) \
   (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC)
 
+#define XCREATEIMAGE(image,width,height,bpp) \
+{ \
+    int width_bytes = DIB_GetImageWidthBytes( (width), (bpp) ); \
+    (image) = XCreateImage(display, DefaultVisualOfScreen(screen), \
+                           (bpp), ZPixmap, 0, malloc( (height)*width_bytes ), \
+                           (width), (height), 32, width_bytes ); \
+}
+
 #endif  /* BITMAP_H */
diff --git a/include/color.h b/include/color.h
index faf9fd7..543b4ff 100644
--- a/include/color.h
+++ b/include/color.h
@@ -5,10 +5,13 @@
 
 extern HPALETTE COLOR_Init(void);
 extern int COLOR_ToPhysical( DC *dc, COLORREF color );
-extern void COLOR_SetMapping( DC *dc, HANDLE, WORD );
+extern void COLOR_SetMapping( DC *dc, HANDLE map, HANDLE revMap, WORD size );
 extern BOOL COLOR_IsSolid( COLORREF color );
 
 extern Colormap COLOR_WinColormap;
 extern int COLOR_mapEGAPixel[16];
+extern int* COLOR_PaletteToPixel;
+extern int* COLOR_PixelToPalette;
+extern int COLOR_ColormapSize;
 
 #endif /* __WINE_COLOR_H */
diff --git a/include/gdi.h b/include/gdi.h
index 6aae216..b176d42 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -203,7 +203,8 @@
   /* X physical palette information */
 typedef struct
 {
-    HANDLE    hMapping;
+    HANDLE    hMapping;     /* Color mapping table (or 0 for identity) */
+    HANDLE    hRevMapping;  /* Reverse color mapping table */
     WORD      mappingSize;
 } X_PHYSPALETTE;
 
diff --git a/include/prototypes.h b/include/prototypes.h
index ebde9cd..5ba1e4f 100644
--- a/include/prototypes.h
+++ b/include/prototypes.h
@@ -57,10 +57,6 @@
 
 extern BOOL WIDGETS_Init(void);
 
-/* objects/dib.c */
-
-extern int DIB_BitmapInfoSize(BITMAPINFO *info, WORD coloruse);
-
 /* objects/palette.c */
 
 extern BOOL PALETTE_Init(void);
diff --git a/loader/Imakefile b/loader/Imakefile
index 488f6e6..c8a7bed 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -19,7 +19,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/memory/Imakefile b/memory/Imakefile
index d6586b9..55448b0 100644
--- a/memory/Imakefile
+++ b/memory/Imakefile
@@ -9,7 +9,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/misc/Imakefile b/misc/Imakefile
index 140fcc3..a08699e 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -29,7 +29,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/misc/main.c b/misc/main.c
index 74a8778..9aa9111 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -31,12 +31,14 @@
 
 extern ButtonTexts ButtonText;
 
-static char people[] = "People who have generously donated time to the Wine " \
-"project include Bob Amstadt, Martin Ayotte, Erik Bos, John Brezak, "\
-"Andrew Bulhak, John Burton, Peter Galbavy, Jeffery Hsu, Miguel de Icaza, " \
-"Alexandre Julliard, Scott A. Laird, Peter MacDonald, David Metcalfe, " \
-"John Richardson, Johannes Ruscheinski, Yngvi Sigurjonsson, Linus Torvalds, " \
-"Carl Williams, Karl Guenter Wuensch, and Eric Youngdale. ";
+static const char people[] = "Wine is available thanks to the work of "\
+"Bob Amstadt, Dag Asheim, Martin Ayotte, Erik Bos, John Brezak, "\
+"Andrew Bulhak, John Burton, Paul Falstad, Peter Galbavy, Jeffrey Hsu, "\
+"Miguel de Icaza, Alexandre Julliard, Jon Konrath, Scott A. Laird, "\
+"Martin von Loewis, Kenneth MacDonald, Peter MacDonald, David Metcalfe, "\
+"Michael Patra, John Richardson, Johannes Ruscheinski, Yngvi Sigurjonsson, "\
+"Rick Sladkey, William Smith, Jon Tombs, Linus Torvalds, Carl Williams, "\
+"Karl Guenter Wuensch, and Eric Youngdale.";
 
 #define WINE_CLASS    "Wine"    /* Class name for resources */
 
diff --git a/miscemu/Imakefile b/miscemu/Imakefile
index f44c876..be64a27 100644
--- a/miscemu/Imakefile
+++ b/miscemu/Imakefile
@@ -20,7 +20,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/multimedia/Imakefile b/multimedia/Imakefile
index daed8c2..c7db934 100644
--- a/multimedia/Imakefile
+++ b/multimedia/Imakefile
@@ -12,7 +12,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/objects/Imakefile b/objects/Imakefile
index d4d24f7..60afdec 100644
--- a/objects/Imakefile
+++ b/objects/Imakefile
@@ -24,7 +24,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/objects/bitblt.c b/objects/bitblt.c
index e945faf..142c9a9 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -1,10 +1,9 @@
 /*
  * GDI bit-blit operations
  *
- * Copyright 1993 Alexandre Julliard
- *
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ * Copyright 1993, 1994  Alexandre Julliard
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <X11/Xlib.h>
@@ -14,13 +13,503 @@
 #include "gdi.h"
 #include "color.h"
 #include "metafile.h"
+#include "bitmap.h"
 #include "options.h"
 #include "stddebug.h"
 /* #define DEBUG_GDI */
 #include "debug.h"
 
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+#define TMP 0   /* Temporary drawable */
+#define DST 1   /* Destination drawable */
+#define SRC 2   /* Source drawable */
+#define PAT 3   /* Pattern (brush) in destination DC */
+
+  /* Build the ROP arguments */
+#define OP_ARGS(src,dst)  (((src) << 2) | (dst))
+
+  /* Build the ROP code */
+#define OP(src,dst,rop)   (OP_ARGS(src,dst) << 4 | (rop))
+
+#define MAX_OP_LEN 6
+
+static const unsigned char BITBLT_Opcodes[256][MAX_OP_LEN] =
+{
+    { OP(PAT,DST,GXclear) },                         /* 0x00  0              */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXnor) },         /* 0x01  ~(D|(P|S))     */
+    { OP(PAT,SRC,GXnor), OP(SRC,DST,GXand) },        /* 0x02  D&~(P|S)       */
+    { OP(PAT,SRC,GXnor) },                           /* 0x03  ~(P|S)         */
+    { OP(PAT,DST,GXnor), OP(SRC,DST,GXand) },        /* 0x04  S&~(D|P)       */
+    { OP(PAT,DST,GXnor) },                           /* 0x05  ~(D|P)         */
+    { OP(SRC,DST,GXequiv), OP(PAT,DST,GXnor), },     /* 0x06  ~(P|~(D^S))    */
+    { OP(SRC,DST,GXand), OP(PAT,DST,GXnor) },        /* 0x07  ~(P|(D&S))     */
+    { OP(PAT,DST,GXandInverted), OP(SRC,DST,GXand) },/* 0x08  S&D&~P         */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXnor) },        /* 0x09  ~(P|(D^S))     */
+    { OP(PAT,DST,GXandInverted) },                   /* 0x0a  D&~P           */
+    { OP(SRC,DST,GXandReverse), OP(PAT,DST,GXnor) }, /* 0x0b  ~(P|(S&~D))    */
+    { OP(PAT,SRC,GXandInverted) },                   /* 0x0c  S&~P           */
+    { OP(SRC,DST,GXandInverted), OP(PAT,DST,GXnor) },/* 0x0d  ~(P|(D&~S))    */
+    { OP(SRC,DST,GXnor), OP(PAT,DST,GXnor) },        /* 0x0e  ~(P|~(D|S))    */
+    { OP(PAT,DST,GXcopyInverted) },                  /* 0x0f  ~P             */
+    { OP(SRC,DST,GXnor), OP(PAT,DST,GXand) },        /* 0x10  P&~(S|D)       */
+    { OP(SRC,DST,GXnor) },                           /* 0x11  ~(D|S)         */
+    { OP(PAT,DST,GXequiv), OP(SRC,DST,GXnor) },      /* 0x12  ~(S|~(D^P))    */
+    { OP(PAT,DST,GXand), OP(SRC,DST,GXnor) },        /* 0x13  ~(S|(D&P))     */
+    { OP(PAT,SRC,GXequiv), OP(SRC,DST,GXnor) },      /* 0x14  ~(D|~(P^S))    */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXnor) },        /* 0x15  ~(D|(P&S))     */
+    { OP(SRC,TMP,GXcopy), OP(PAT,TMP,GXnand),
+      OP(TMP,DST,GXand), OP(SRC,DST,GXxor),
+      OP(PAT,DST,GXxor) },                           /* 0x16  P^S^(D&~(P&S)  */
+    { OP(SRC,TMP,GXcopy), OP(SRC,DST,GXxor),
+      OP(PAT,SRC,GXxor), OP(SRC,DST,GXand),
+      OP(TMP,DST,GXequiv) },                         /* 0x17 ~S^((S^P)&(S^D))*/
+    { OP(PAT,SRC,GXxor), OP(PAT,DST,GXxor),
+        OP(SRC,DST,GXand) },                         /* 0x18  (S^P)&(D^P)    */
+    { OP(SRC,TMP,GXcopy), OP(PAT,TMP,GXnand),
+      OP(TMP,DST,GXand), OP(SRC,DST,GXequiv) },      /* 0x19  ~S^(D&~(P&S))  */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXxor) },                           /* 0x1a  P^(D|(S&P))    */
+    { OP(SRC,TMP,GXcopy), OP(PAT,TMP,GXxor),
+      OP(TMP,DST,GXand), OP(SRC,DST,GXequiv) },      /* 0x1b  ~S^(D&(P^S))   */
+    { OP(PAT,DST,GXand), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXxor) },                           /* 0x1c  P^(S|(D&P))    */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXequiv) },      /* 0x1d  ~D^(S&(D^P))   */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXxor) },         /* 0x1e  P^(D|S)        */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXnand) },        /* 0x1f  ~(P&(D|S))     */
+    { OP(PAT,SRC,GXandReverse), OP(SRC,DST,GXand) }, /* 0x20  D&(P&~S)       */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXnor) },        /* 0x21  ~(S|(D^P))     */
+    { OP(SRC,DST,GXandInverted) },                   /* 0x22  ~S&D           */
+    { OP(PAT,DST,GXandReverse), OP(SRC,DST,GXnor) }, /* 0x23  ~(S|(P&~D))    */
+    { OP(SRC,DST,GXxor), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXand) },                           /* 0x24   (S^P)&(S^D)   */
+    { OP(PAT,SRC,GXnand), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXequiv) },                         /* 0x25  ~P^(D&~(S&P))  */
+    { OP(SRC,TMP,GXcopy), OP(PAT,TMP,GXand),
+      OP(TMP,DST,GXor), OP(SRC,DST,GXxor) },         /* 0x26  S^(D|(S&P))    */
+    { OP(SRC,TMP,GXcopy), OP(PAT,TMP,GXequiv),
+      OP(TMP,DST,GXor), OP(SRC,DST,GXxor) },         /* 0x27  S^(D|~(P^S))   */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXand) },        /* 0x28  D&(P^S)        */
+    { OP(SRC,TMP,GXcopy), OP(PAT,TMP,GXand),
+      OP(TMP,DST,GXor), OP(SRC,DST,GXxor),
+      OP(PAT,DST,GXequiv) },                         /* 0x29  ~P^S^(D|(P&S)) */
+    { OP(PAT,SRC,GXnand), OP(SRC,DST,GXand) },       /* 0x2a  D&~(P&S)       */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXxor),
+      OP(PAT,DST,GXxor), OP(SRC,DST,GXand),
+      OP(TMP,DST,GXequiv) },                         /* 0x2b ~S^((P^S)&(P^D))*/
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0x2c  S^(P&(S|D))    */
+    { OP(SRC,DST,GXorReverse), OP(PAT,DST,GXxor) },  /* 0x2d  P^(S|~D)       */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXxor) },                           /* 0x2e  P^(S|(D^P))    */
+    { OP(SRC,DST,GXorReverse), OP(PAT,DST,GXnand) }, /* 0x2f  ~(P&(S|~D))    */
+    { OP(PAT,SRC,GXandReverse) },                    /* 0x30  P&~S           */
+    { OP(PAT,DST,GXandInverted), OP(SRC,DST,GXnor) },/* 0x31  ~(S|(D&~P))    */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x32  S^(D|P|S)      */
+    { OP(SRC,DST,GXcopyInverted) },                  /* 0x33  ~S             */
+    { OP(SRC,DST,GXand), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x34  S^(P|(D&S))    */
+    { OP(SRC,DST,GXequiv), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x35  S^(P|~(D^S))   */
+    { OP(PAT,DST,GXor), OP(SRC,DST,GXxor) },         /* 0x36  S^(D|P)        */
+    { OP(PAT,DST,GXor), OP(SRC,DST,GXnand) },        /* 0x37  ~(S&(D|P))     */
+    { OP(PAT,DST,GXor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXxor) },                           /* 0x38  P^(S&(D|P))    */
+    { OP(PAT,DST,GXorReverse), OP(SRC,DST,GXxor) },  /* 0x39  S^(P|~D)       */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x3a  S^(P|(D^S))    */
+    { OP(PAT,DST,GXorReverse), OP(SRC,DST,GXnand) }, /* 0x3b  ~(S&(P|~D))    */
+    { OP(PAT,SRC,GXxor) },                           /* 0x3c  P^S            */
+    { OP(SRC,DST,GXnor), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x3d  S^(P|~(D|S))   */
+    { OP(SRC,DST,GXandInverted), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x3e  S^(P|(D&~S))   */
+    { OP(PAT,SRC,GXnand) },                          /* 0x3f  ~(P&S)         */
+    { OP(SRC,DST,GXandReverse), OP(PAT,DST,GXand) }, /* 0x40  P&S&~D         */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXnor) },        /* 0x41  ~(D|(P^S))     */
+    { OP(DST,SRC,GXxor), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXand) },                           /* 0x42  (S^D)&(P^D)    */
+    { OP(SRC,DST,GXnand), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXequiv) },                         /* 0x43  ~S^(P&~(D&S))  */
+    { OP(SRC,DST,GXandReverse) },                    /* 0x44  S&~D           */
+    { OP(PAT,SRC,GXandReverse), OP(SRC,DST,GXnor) }, /* 0x45  ~(D|(P&~S))    */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXxor) },         /* 0x46  D^(S|(P&D))    */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXequiv) },                         /* 0x47  ~P^(S&(D^P))   */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXand) },        /* 0x48  S&(P^D)        */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXxor),
+      OP(PAT,DST,GXequiv) },                         /* 0x49  ~P^D^(S|(P&D)) */
+    { OP(DST,SRC,GXor), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0x4a  D^(P&(S|D))    */
+    { OP(SRC,DST,GXorInverted), OP(PAT,DST,GXxor) }, /* 0x4b  P^(D|~S)       */
+    { OP(PAT,DST,GXnand), OP(SRC,DST,GXand) },       /* 0x4c  S&~(D&P)       */
+    { OP(SRC,TMP,GXcopy), OP(SRC,DST,GXxor),
+      OP(PAT,SRC,GXxor), OP(SRC,DST,GXor),
+      OP(TMP,DST,GXequiv) },                         /* 0x4d ~S^((S^P)|(S^D))*/
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXxor) },                           /* 0x4e  P^(D|(S^P))    */
+    { OP(SRC,DST,GXorInverted), OP(PAT,DST,GXnand) },/* 0x4f  ~(P&(D|~S))    */
+    { OP(PAT,DST,GXandReverse) },                    /* 0x50  P&~D           */
+    { OP(PAT,SRC,GXandInverted), OP(SRC,DST,GXnor) },/* 0x51  ~(D|(S&~P))    */
+    { OP(DST,SRC,GXand), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x52  D^(P|(S&D))    */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXequiv) },                         /* 0x53  ~S^(P&(D^S))   */
+    { OP(PAT,SRC,GXnor), OP(SRC,DST,GXnor) },        /* 0x54  ~(D|~(P|S))    */
+    { OP(PAT,DST,GXinvert) },                        /* 0x55  ~D             */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXxor) },         /* 0x56  D^(P|S)        */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXnand) },        /* 0x57  ~(D&(P|S))     */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXxor) },                           /* 0x58  P^(D&(P|S))    */
+    { OP(PAT,SRC,GXorReverse), OP(SRC,DST,GXxor) },  /* 0x59  D^(P|~S)       */
+    { OP(PAT,DST,GXxor) },                           /* 0x5a  D^P            */
+    { OP(DST,SRC,GXnor), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x5b  D^(P|~(S|D))   */
+    { OP(DST,SRC,GXxor), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x5c  D^(P|(S^D))    */
+    { OP(PAT,SRC,GXorReverse), OP(SRC,DST,GXnand) }, /* 0x5d  ~(D&(P|~S))    */
+    { OP(DST,SRC,GXandInverted), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXxor) },                           /* 0x5e  D^(P|(S&~D))   */
+    { OP(PAT,DST,GXnand) },                          /* 0x5f  ~(D&P)         */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXand) },        /* 0x60  P&(D^S)        */
+    { OP(DST,TMP,GXcopy), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXor), OP(SRC,DST,GXxor),
+      OP(TMP,DST,GXequiv) },                         /* 0x61  ~D^S^(P|(D&S)) */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor) },        /* 0x62  D^(S&(P|D))    */
+    { OP(PAT,DST,GXorInverted), OP(SRC,DST,GXxor) }, /* 0x63  S^(D|~P)       */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor) },        /* 0x64  S^(D&(P|S))    */
+    { OP(PAT,SRC,GXorInverted), OP(SRC,DST,GXxor) }, /* 0x65  D^(S|~P)       */
+    { OP(SRC,DST,GXxor) },                           /* 0x66  S^D            */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXnor),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXxor) },         /* 0x67  S^(D|~(S|P)    */
+    { OP(DST,TMP,GXcopy), OP(SRC,DST,GXnor),
+      OP(PAT,DST,GXor), OP(SRC,DST,GXxor),
+      OP(TMP,DST,GXequiv) },                         /* 0x68  ~D^S^(P|~(D|S))*/
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXequiv) },      /* 0x69  ~P^(D^S)       */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXxor) },        /* 0x6a  D^(P&S)        */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor),
+      OP(PAT,DST,GXequiv) },                         /* 0x6b  ~P^S^(D&(P|S)) */
+    { OP(PAT,DST,GXand), OP(SRC,DST,GXxor) },        /* 0x6c  S^(D&P)        */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor),
+      OP(PAT,DST,GXequiv) },                         /* 0x6d  ~P^D^(S&(P|D)) */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXorReverse),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor) },        /* 0x6e  S^(D&(P|~S))   */
+    { OP(SRC,DST,GXequiv), OP(PAT,DST,GXnand) },     /* 0x6f  ~(P&~(S^D))    */
+    { OP(SRC,DST,GXnand), OP(PAT,DST,GXand) },       /* 0x70  P&~(D&S)       */
+    { OP(SRC,TMP,GXcopy), OP(DST,SRC,GXxor),
+      OP(PAT,DST,GXxor), OP(SRC,DST,GXand),
+      OP(TMP,DST,GXequiv) },                         /* 0x71 ~S^((S^D)&(P^D))*/
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXxor) },         /* 0x72  S^(D|(P^S))    */
+    { OP(PAT,DST,GXorInverted), OP(SRC,DST,GXnand) },/* 0x73  ~(S&(D|~P))    */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXxor) },         /* 0x74   D^(S|(P^D))   */
+    { OP(PAT,SRC,GXorInverted), OP(SRC,DST,GXnand) },/* 0x75  ~(D&(S|~P))    */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXandReverse),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXxor) },         /* 0x76  S^(D|(P&~S))   */
+    { OP(SRC,DST,GXnand) },                          /* 0x77  ~(S&D)         */
+    { OP(SRC,DST,GXand), OP(PAT,DST,GXxor) },        /* 0x78  P^(D&S)        */
+    { OP(DST,TMP,GXcopy), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXand), OP(SRC,DST,GXxor),
+      OP(TMP,DST,GXequiv) },                         /* 0x79  ~D^S^(P&(D|S)) */
+    { OP(DST,SRC,GXorInverted), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0x7a  D^(P&(S|~D))   */
+    { OP(PAT,DST,GXequiv), OP(SRC,DST,GXnand) },     /* 0x7b  ~(S&~(D^P))    */
+    { OP(SRC,DST,GXorInverted), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0x7c  S^(P&(D|~S))   */
+    { OP(PAT,SRC,GXequiv), OP(SRC,DST,GXnand) },     /* 0x7d  ~(D&~(P^S))    */
+    { OP(SRC,DST,GXxor), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXor) },                            /* 0x7e  (S^P)|(S^D)    */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXnand) },       /* 0x7f  ~(D&P&S)       */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXand) },        /* 0x80  D&P&S          */
+    { OP(SRC,DST,GXxor), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXnor) },                           /* 0x81  ~((S^P)|(S^D)) */
+    { OP(PAT,SRC,GXequiv), OP(SRC,DST,GXand) },      /* 0x82  D&~(P^S)       */
+    { OP(SRC,DST,GXorInverted), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXequiv) },                         /* 0x83  ~S^(P&(D|~S))  */
+    { OP(PAT,DST,GXequiv), OP(SRC,DST,GXand) },      /* 0x84  S&~(D^P)       */
+    { OP(PAT,SRC,GXorInverted), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXequiv) },                         /* 0x85  ~P^(D&(S|~P))  */
+    { OP(DST,TMP,GXcopy), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXand), OP(SRC,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0x86  D^S^(P&(D|S))  */
+    { OP(SRC,DST,GXand), OP(PAT,DST,GXequiv) },      /* 0x87  ~P^(D&S)       */
+    { OP(SRC,DST,GXand) },                           /* 0x88  S&D            */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXandReverse),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXequiv) },       /* 0x89  ~S^(D|(P&~S))  */
+    { OP(PAT,SRC,GXorInverted), OP(SRC,DST,GXand) }, /* 0x8a  D&(S|~P)       */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXequiv) },       /* 0x8b  ~D^(S|(P^D))   */
+    { OP(PAT,DST,GXorInverted), OP(SRC,DST,GXand) }, /* 0x8c  S&(D|~P)       */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXequiv) },       /* 0x8d  ~S^(D|(P^S))   */
+    { OP(SRC,TMP,GXcopy), OP(DST,SRC,GXxor),
+      OP(PAT,DST,GXxor), OP(SRC,DST,GXand),
+      OP(TMP,DST,GXxor) },                           /* 0x8e  S^((S^D)&(P^D))*/
+    { OP(SRC,DST,GXnand), OP(PAT,DST,GXnand) },      /* 0x8f  ~(P&~(D&S))    */
+    { OP(SRC,DST,GXequiv), OP(PAT,DST,GXand) },      /* 0x90  P&~(D^S)       */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXorReverse),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXequiv) },      /* 0x91  ~S^(D&(P|~S))  */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXand), OP(PAT,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0x92  D^P^(S&(D|P))  */
+    { OP(PAT,DST,GXand), OP(SRC,DST,GXequiv) },      /* 0x93  ~S^(P&D)       */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXand), OP(PAT,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0x94  S^P^(D&(P|S))  */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXequiv) },      /* 0x95  ~D^(P&S)       */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXxor) },        /* 0x96  D^P^S          */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXnor),
+      OP(SRC,DST,GXor), OP(PAT,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0x97  S^P^(D|~(P|S)) */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXnor),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXequiv) },       /* 0x98  ~S^(D|~(P|S))  */
+    { OP(SRC,DST,GXequiv) },                         /* 0x99  ~S^D           */
+    { OP(PAT,SRC,GXandReverse), OP(SRC,DST,GXxor) }, /* 0x9a  D^(P&~S)       */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXequiv) },      /* 0x9b  ~S^(D&(P|S))   */
+    { OP(PAT,DST,GXandReverse), OP(SRC,DST,GXxor) }, /* 0x9c  S^(P&~D)       */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXequiv) },      /* 0x9d  ~D^(S&(P|D))   */
+    { OP(DST,TMP,GXcopy), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXor), OP(SRC,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0x9e  D^S^(P|(D&S))  */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXnand) },       /* 0x9f  ~(P&(D^S))     */
+    { OP(PAT,DST,GXand) },                           /* 0xa0  D&P            */
+    { OP(PAT,SRC,GXandInverted), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXequiv) },                         /* 0xa1  ~P^(D|(S&~P))  */
+    { OP(PAT,SRC,GXorReverse), OP(SRC,DST,GXand) },  /* 0xa2  D&(P|~S)       */
+    { OP(DST,SRC,GXxor), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXequiv) },                         /* 0xa3  ~D^(P|(S^D))   */
+    { OP(PAT,SRC,GXnor), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXequiv) },                         /* 0xa4  ~P^(D|~(S|P))  */
+    { OP(PAT,DST,GXequiv) },                         /* 0xa5  ~P^D           */
+    { OP(PAT,SRC,GXandInverted), OP(SRC,DST,GXxor) },/* 0xa6  D^(S&~P)       */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXequiv) },                         /* 0xa7  ~P^(D&(S|P))   */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXand) },         /* 0xa8  D&(P|S)        */
+    { OP(PAT,SRC,GXor), OP(SRC,DST,GXequiv) },       /* 0xa9  ~D^(P|S)       */
+    { OP(SRC,DST,GXnoop) },                          /* 0xaa  D              */
+    { OP(PAT,SRC,GXnor), OP(SRC,DST,GXor) },         /* 0xab  D|~(P|S)       */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0xac  S^(P&(D^S))    */
+    { OP(DST,SRC,GXand), OP(PAT,SRC,GXor),
+      OP(SRC,DST,GXequiv) },                         /* 0xad  ~D^(P|(S&D))   */
+    { OP(PAT,SRC,GXandInverted), OP(SRC,DST,GXor) }, /* 0xae  D|(S&~P)       */
+    { OP(PAT,DST,GXorInverted) },                    /* 0xaf  D|~P           */
+    { OP(SRC,DST,GXorInverted), OP(PAT,DST,GXand) }, /* 0xb0  P&(D|~S)       */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXequiv) },                         /* 0xb1  ~P^(D|(S^P))   */
+    { OP(SRC,TMP,GXcopy), OP(SRC,DST,GXxor),
+      OP(PAT,SRC,GXxor), OP(SRC,DST,GXor),
+      OP(TMP,DST,GXxor) },                           /* 0xb2  S^((S^P)|(S^D))*/
+    { OP(PAT,DST,GXnand), OP(SRC,DST,GXnand) },      /* 0xb3  ~(S&~(D&P))    */
+    { OP(SRC,DST,GXandReverse), OP(PAT,DST,GXxor) }, /* 0xb4  P^(S&~D)       */
+    { OP(DST,SRC,GXor), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXequiv) },                         /* 0xb5  ~D^(P&(S|D))   */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXor), OP(PAT,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0xb6  D^P^(S|(D&P))  */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXnand) },       /* 0xb7  ~(S&(D^P))     */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXxor) },                           /* 0xb8  P^(S&(D^P))    */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXequiv) },       /* 0xb9  ~D^(S|(P&D))   */
+    { OP(PAT,SRC,GXandReverse), OP(SRC,DST,GXor) },  /* 0xba  D|(P&~S)       */
+    { OP(SRC,DST,GXorInverted) },                    /* 0xbb  ~S|D           */
+    { OP(SRC,DST,GXnand), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0xbc  S^(P&~(D&S))   */
+    { OP(DST,SRC,GXxor), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXnand) },                          /* 0xbd  ~((S^D)&(P^D)) */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXor) },         /* 0xbe  D|(P^S)        */
+    { OP(PAT,SRC,GXnand), OP(SRC,DST,GXor) },        /* 0xbf  D|~(P&S)       */
+    { OP(PAT,SRC,GXand) },                           /* 0xc0  P&S            */
+    { OP(SRC,DST,GXandInverted), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXequiv) },                         /* 0xc1  ~S^(P|(D&~S))  */
+    { OP(SRC,DST,GXnor), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXequiv) },                         /* 0xc2  ~S^(P|~(D|S))  */
+    { OP(PAT,SRC,GXequiv) },                         /* 0xc3  ~P^S           */
+    { OP(PAT,DST,GXorReverse), OP(SRC,DST,GXand) },  /* 0xc4  S&(P|~D)       */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXequiv) },                         /* 0xc5  ~S^(P|(D^S))   */
+    { OP(PAT,DST,GXandInverted), OP(SRC,DST,GXxor) },/* 0xc6  S^(D&~P)       */
+    { OP(PAT,DST,GXor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXequiv) },                         /* 0xc7  ~P^(S&(D|P))   */
+    { OP(PAT,DST,GXor), OP(SRC,DST,GXand) },         /* 0xc8  S&(D|P)        */
+    { OP(PAT,DST,GXor), OP(SRC,DST,GXequiv) },       /* 0xc9  ~S^(P|D)       */
+    { OP(DST,SRC,GXxor), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0xca  D^(P&(S^D))    */
+    { OP(SRC,DST,GXand), OP(PAT,DST,GXor),
+      OP(SRC,DST,GXequiv) },                         /* 0xcb  ~S^(P|(D&S))   */
+    { OP(SRC,DST,GXcopy) },                          /* 0xcc  S              */
+    { OP(PAT,DST,GXnor), OP(SRC,DST,GXor) },         /* 0xcd  S|~(D|P)       */
+    { OP(PAT,DST,GXandInverted), OP(SRC,DST,GXor) }, /* 0xce  S|(D&~P)       */
+    { OP(PAT,SRC,GXorInverted) },                    /* 0xcf  S|~P           */
+    { OP(SRC,DST,GXorReverse), OP(PAT,DST,GXand) },  /* 0xd0  P&(S|~D)       */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXequiv) },                         /* 0xd1  ~P^(S|(D^P))   */
+    { OP(SRC,DST,GXandInverted), OP(PAT,DST,GXxor) },/* 0xd2  P^(D&~S)       */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXand),
+      OP(SRC,DST,GXequiv) },                         /* 0xd3  ~S^(P&(D|S))   */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXxor),
+      OP(PAT,DST,GXxor), OP(SRC,DST,GXand),
+      OP(TMP,DST,GXxor) },                           /* 0xd4  S^((S^P)&(D^P))*/
+    { OP(PAT,SRC,GXnand), OP(SRC,DST,GXnand) },      /* 0xd5  ~(D&~(P&S))    */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXor), OP(PAT,DST,GXxor),
+      OP(TMP,DST,GXxor) },                           /* 0xd6  S^P^(D|(P&S))  */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXnand) },       /* 0xd7  ~(D&(P^S))     */
+    { OP(PAT,SRC,GXxor), OP(SRC,DST,GXand),
+      OP(PAT,DST,GXxor) },                           /* 0xd8  P^(D&(S^P))    */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXor), OP(TMP,DST,GXequiv) },       /* 0xd9  ~S^(D|(P&S))   */
+    { OP(DST,SRC,GXnand), OP(PAT,SRC,GXand),
+      OP(SRC,DST,GXxor) },                           /* 0xda  D^(P&~(S&D))   */
+    { OP(SRC,DST,GXxor), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXnand) },                          /* 0xdb  ~((S^P)&(S^D)) */
+    { OP(PAT,DST,GXandReverse), OP(SRC,DST,GXor) },  /* 0xdc  S|(P&~D)       */
+    { OP(SRC,DST,GXorReverse) },                     /* 0xdd  S|~D           */
+    { OP(PAT,DST,GXxor), OP(SRC,DST,GXor) },         /* 0xde  S|(D^P)        */
+    { OP(PAT,DST,GXnand), OP(SRC,DST,GXor) },        /* 0xdf  S|~(D&P)       */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXand) },         /* 0xe0  P&(D|S)        */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXequiv) },       /* 0xe1  ~P^(D|S)       */
+    { OP(DST,TMP,GXcopy), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor) },        /* 0xe2  D^(S&(P^D))    */
+    { OP(PAT,DST,GXand), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXequiv) },                         /* 0xe3  ~P^(S|(D&P))   */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXxor),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor) },        /* 0xe4  S^(D&(P^S))    */
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXor),
+      OP(PAT,DST,GXequiv) },                         /* 0xe5  ~P^(D|(S&P))   */
+    { OP(SRC,TMP,GXcopy), OP(PAT,SRC,GXnand),
+      OP(SRC,DST,GXand), OP(TMP,DST,GXxor) },        /* 0xe6  S^(D&~(P&S))   */
+    { OP(PAT,SRC,GXxor), OP(PAT,DST,GXxor),
+      OP(SRC,DST,GXnand) },                          /* 0xe7  ~((S^P)&(D^P)) */
+    { OP(SRC,TMP,GXcopy), OP(SRC,DST,GXxor),
+      OP(PAT,SRC,GXxor), OP(SRC,DST,GXand),
+      OP(TMP,DST,GXxor) },                           /* 0xe8  S^((S^P)&(S^D))*/
+    { OP(DST,TMP,GXcopy), OP(SRC,DST,GXnand),
+      OP(PAT,DST,GXand), OP(SRC,DST,GXxor),
+      OP(TMP,DST,GXequiv) },                         /* 0xe9  ~D^S^(P&~(S&D))*/
+    { OP(PAT,SRC,GXand), OP(SRC,DST,GXor) },         /* 0xea  D|(P&S)        */
+    { OP(PAT,SRC,GXequiv), OP(SRC,DST,GXor) },       /* 0xeb  D|~(P^S)       */
+    { OP(PAT,DST,GXand), OP(SRC,DST,GXor) },         /* 0xec  S|(D&P)        */
+    { OP(PAT,DST,GXequiv), OP(SRC,DST,GXor) },       /* 0xed  S|~(D^P)       */
+    { OP(SRC,DST,GXor) },                            /* 0xee  S|D            */
+    { OP(PAT,DST,GXorInverted), OP(SRC,DST,GXor) },  /* 0xef  S|D|~P         */
+    { OP(PAT,DST,GXcopy) },                          /* 0xf0  P              */
+    { OP(SRC,DST,GXnor), OP(PAT,DST,GXor) },         /* 0xf1  P|~(D|S)       */
+    { OP(SRC,DST,GXandInverted), OP(PAT,DST,GXor) }, /* 0xf2  P|(D&~S)       */
+    { OP(PAT,SRC,GXorReverse) },                     /* 0xf3  P|~S           */
+    { OP(SRC,DST,GXandReverse), OP(PAT,DST,GXor) },  /* 0xf4  P|(S&~D)       */
+    { OP(PAT,DST,GXorReverse) },                     /* 0xf5  P|~D           */
+    { OP(SRC,DST,GXxor), OP(PAT,DST,GXor) },         /* 0xf6  P|(D^S)        */
+    { OP(SRC,DST,GXnand), OP(PAT,DST,GXor) },        /* 0xf7  P|~(S&D)       */
+    { OP(SRC,DST,GXand), OP(PAT,DST,GXor) },         /* 0xf8  P|(D&S)        */
+    { OP(SRC,DST,GXequiv), OP(PAT,DST,GXor) },       /* 0xf9  P|~(D^S)       */
+    { OP(PAT,DST,GXor) },                            /* 0xfa  D|P            */
+    { OP(PAT,SRC,GXorReverse), OP(SRC,DST,GXor) },   /* 0xfb  D|P|~S         */
+    { OP(PAT,SRC,GXor) },                            /* 0xfc  P|S            */
+    { OP(SRC,DST,GXorReverse), OP(PAT,DST,GXor) },   /* 0xfd  P|S|~D         */
+    { OP(SRC,DST,GXor), OP(PAT,DST,GXor) },          /* 0xfe  P|D|S          */
+    { OP(PAT,DST,GXset) }                            /* 0xff  1              */
+};
+
+
+#ifdef BITBLT_TEST  /* Opcodes test */
+
+static int do_bitop( int s, int d, int rop )
+{
+    int res;
+    switch(rop)
+    {
+    case GXclear:        res = 0; break;
+    case GXand:          res = s & d; break;
+    case GXandReverse:   res = s & ~d; break;
+    case GXcopy:         res = s; break;
+    case GXandInverted:  res = ~s & d; break;
+    case GXnoop:         res = d; break;
+    case GXxor:          res = s ^ d; break;
+    case GXor:           res = s | d; break;
+    case GXnor:          res = ~(s | d); break;
+    case GXequiv:        res = ~s ^ d; break;
+    case GXinvert:       res = ~d; break;
+    case GXorReverse:    res = s | ~d; break;
+    case GXcopyInverted: res = ~s; break;
+    case GXorInverted:   res = ~s | d; break;
+    case GXnand:         res = ~(s & d); break;
+    case GXset:          res = 1; break;
+    }
+    return res & 1;
+}
+
+main()
+{
+    int rop, i, res, src, dst, pat, tmp, dstUsed;
+    const BYTE *opcode;
+
+    for (rop = 0; rop < 256; rop++)
+    {
+        res = dstUsed = 0;
+        for (i = 0; i < 8; i++)
+        {
+            pat = (i >> 2) & 1;
+            src = (i >> 1) & 1;
+            dst = i & 1;
+            for (opcode = BITBLT_Opcodes[rop]; *opcode; opcode++)
+            {
+                switch(*opcode >> 4)
+                {
+                case OP_ARGS(DST,TMP):
+                    tmp = do_bitop( dst, tmp, *opcode & 0xf );
+                    break;
+                case OP_ARGS(DST,SRC):
+                    src = do_bitop( dst, src, *opcode & 0xf );
+                    break;
+                case OP_ARGS(SRC,TMP):
+                    tmp = do_bitop( src, tmp, *opcode & 0xf );
+                    break;
+                case OP_ARGS(SRC,DST):
+                    dst = do_bitop( src, dst, *opcode & 0xf );
+                    dstUsed = 1;
+                    break;
+                case OP_ARGS(PAT,TMP):
+                    tmp = do_bitop( pat, tmp, *opcode & 0xf );
+                    break;
+                case OP_ARGS(PAT,DST):
+                    dst = do_bitop( pat, dst, *opcode & 0xf );
+                    dstUsed = 1;
+                    break;
+                case OP_ARGS(PAT,SRC):
+                    src = do_bitop( pat, src, *opcode & 0xf );
+                    break;
+                case OP_ARGS(TMP,DST):
+                    dst = do_bitop( tmp, dst, *opcode & 0xf );
+                    dstUsed = 1;
+                    break;
+                case OP_ARGS(TMP,SRC):
+                    src = do_bitop( tmp, src, *opcode & 0xf );
+                    break;
+                default:
+                    printf( "Invalid opcode %x\n", *opcode );
+                }
+            }
+            if (!dstUsed) dst = src;
+            if (dst) res |= 1 << i;
+        }
+        if (res != rop) printf( "%02x: ERROR, res=%02x\n", rop, res );
+    }
+}
+
+#endif  /* BITBLT_TEST */
+
 
 /***********************************************************************
  *           BITBLT_GetImage
@@ -28,35 +517,26 @@
 static XImage *BITBLT_GetImage( HDC hdc, int x, int y, int width, int height )
 {
     XImage *image;
-    RECT rect;
+    RECT rect, tmpRect, clipRect;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
 
-    GetClipBox( hdc, &rect );
-    OffsetRect( &rect, dc->w.DCOrgX, dc->w.DCOrgY );
-    if ((x >= rect.left) && (y >= rect.top)
-        && (x+width < rect.right) && (y+height < rect.bottom))
+    GetClipBox( hdc, &clipRect );
+    OffsetRect( &clipRect, dc->w.DCOrgX, dc->w.DCOrgY );
+    SetRect( &tmpRect, x, y, x+width, y+height );
+    IntersectRect( &rect, &tmpRect, &clipRect );
+    if (EqualRect(&rect,&tmpRect))
     {
         image = XGetImage( display, dc->u.x.drawable, x, y, width, height,
                            AllPlanes, ZPixmap );
     }
     else  /* Get only the visible sub-image */
     {
-        int width_bytes = ((dc->w.bitsPerPixel == 24 ? 32 : dc->w.bitsPerPixel)
-                           * width + 31) / 32 * 4;
-        char *data = malloc( height * width_bytes );
-        image = XCreateImage( display, DefaultVisualOfScreen(screen),
-                              dc->w.bitsPerPixel, ZPixmap, 0, data,
-                              width, height, 32, width_bytes );
+        XCREATEIMAGE( image, width, height, dc->w.bitsPerPixel );
         if (image && !IsRectEmpty(&rect))
         {
-            int x1, y1, x2, y2;
-            x1 = max( x, rect.left );
-            y1 = max( y, rect.top );
-            x2 = min( x + width, rect.right );
-            y2 = min( y + height, rect.bottom );
-            if ((x1 < x2) && (y1 < y2))
-                XGetSubImage( display, dc->u.x.drawable, x1, y1, x2-x1, y2-y1,
-                              AllPlanes, ZPixmap, image, x1-x, y1-y );
+            XGetSubImage( display, dc->u.x.drawable, rect.left, rect.top,
+                          rect.right-rect.left, rect.bottom-rect.top,
+                          AllPlanes, ZPixmap, image, rect.left-x, rect.top-y );
         }
     }
     return image;
@@ -64,6 +544,165 @@
 
 
 /***********************************************************************
+ *           BITBLT_GetArea
+ *
+ * Retrieve an area of the source DC. If necessary, the area is
+ * mapped to colormap-independent colors.
+ */
+static void BITBLT_GetArea( HDC hdcSrc, HDC hdcDst, Pixmap pixmap, GC gc,
+                            int x, int y, int width, int height )
+{
+    XImage *srcImage, *dstImage;
+    DC * dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    DC * dcDst = (DC *) GDI_GetObjPtr( hdcDst, DC_MAGIC );
+
+    if ((dcSrc->w.bitsPerPixel == dcDst->w.bitsPerPixel) &&
+        (!COLOR_PixelToPalette || (dcDst->w.bitsPerPixel == 1)))
+    {
+        XCopyArea( display, dcSrc->u.x.drawable, pixmap, gc,
+                   x, y, width, height, 0, 0 );
+        return;
+    }
+    if ((dcSrc->w.bitsPerPixel == 1) && (dcDst->w.bitsPerPixel != 1))
+    {
+        XSetBackground( display, gc, COLOR_PixelToPalette ?
+                        COLOR_PixelToPalette[dcDst->w.textPixel] :
+                        dcDst->w.textPixel );
+        XSetForeground( display, gc, COLOR_PixelToPalette ?
+                        COLOR_PixelToPalette[dcDst->w.backgroundPixel] :
+                        dcDst->w.backgroundPixel );
+        XCopyPlane( display, dcSrc->u.x.drawable, pixmap, gc,
+                    x, y, width, height, 0, 0, 1);
+        return;
+    }
+
+    srcImage = BITBLT_GetImage( hdcSrc, x, y, width, height );
+    if (dcSrc->w.bitsPerPixel != dcDst->w.bitsPerPixel)
+    {
+        XCREATEIMAGE( dstImage, width, height, dcDst->w.bitsPerPixel );
+        for (y = 0; y < height; y++)
+            for (x = 0; x < width; x++)
+            {
+                XPutPixel( dstImage, x, y, (XGetPixel( srcImage, x, y ) ==
+                                            dcSrc->w.backgroundPixel) );
+            }
+        XDestroyImage( srcImage );
+    }
+    else
+    {
+        for (y = 0; y < height; y++)
+            for (x = 0; x < width; x++)
+            {
+                XPutPixel( srcImage, x, y,
+                          COLOR_PixelToPalette[XGetPixel( srcImage, x, y)] );
+            }
+        dstImage = srcImage;
+    }
+    XPutImage( display, pixmap, gc, dstImage, 0, 0, 0, 0, width, height );
+    XDestroyImage( dstImage );
+}
+
+
+/***********************************************************************
+ *           BITBLT_PutArea
+ *
+ * Put an area back into an hdc, possibly applying a mapping
+ * to every pixel in the process.
+ */
+static void BITBLT_PutArea( HDC hdc, Pixmap pixmap, GC gc,
+                            int x, int y, int width, int height )
+{
+    XImage *image;
+    int x1, y1;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+    if (!COLOR_PaletteToPixel)
+    {
+        XCopyArea( display, pixmap, dc->u.x.drawable, gc,
+                  0, 0, width, height, x, y );
+    }
+    else
+    {
+        image = XGetImage( display, pixmap, 0, 0, width, height,
+                           AllPlanes, ZPixmap );
+        for (y1 = 0; y1 < height; y1++)
+            for (x1 = 0; x1 < width; x1++)
+            {
+                XPutPixel( image, x1, y1,
+                           COLOR_PaletteToPixel[XGetPixel( image, x1, y1)] );
+            }
+        XPutImage( display, dc->u.x.drawable, gc, image,
+                   0, 0, x, y, width, height );
+        XDestroyImage( image );
+    }
+}
+
+
+/***********************************************************************
+ *           BITBLT_SelectBrush
+ *
+ * Select the brush into a GC.
+ */
+static BOOL BITBLT_SelectBrush( DC * dc, GC gc )
+{
+    XGCValues val;
+    XImage *image;
+    Pixmap pixmap = 0;
+    int x, y, mask = 0;
+    
+    if (dc->u.x.brush.style == BS_NULL) return FALSE;
+    if (dc->u.x.brush.pixel == -1)
+    {
+        val.foreground = dc->w.backgroundPixel;
+        val.background = dc->w.textPixel;
+    }
+    else
+    {
+        val.foreground = dc->u.x.brush.pixel;
+        val.background = dc->w.backgroundPixel;
+    }
+    if (COLOR_PixelToPalette)
+    {
+        val.foreground = COLOR_PixelToPalette[val.foreground];
+        val.background = COLOR_PixelToPalette[val.background];
+    }
+    val.fill_style = dc->u.x.brush.fillStyle;
+    if ((val.fill_style==FillStippled) || (val.fill_style==FillOpaqueStippled))
+    {
+        if (dc->w.backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled;
+        val.stipple = dc->u.x.brush.pixmap;
+        mask = GCStipple;
+    }
+    else if (val.fill_style == FillTiled)
+    {
+        if (COLOR_PixelToPalette)
+        {
+            pixmap = XCreatePixmap( display, rootWindow, 8, 8, screenDepth );
+            image = XGetImage( display, dc->u.x.brush.pixmap, 0, 0, 8, 8,
+                               AllPlanes, ZPixmap );
+            for (y = 0; y < 8; y++)
+                for (x = 0; x < 8; x++)
+                    XPutPixel( image, x, y,
+                               COLOR_PixelToPalette[XGetPixel( image, x, y)] );
+            XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
+            XDestroyImage( image );
+            val.tile = pixmap;
+        }
+        else val.tile = dc->u.x.brush.pixmap;
+        mask = GCTile;
+    }
+    val.ts_x_origin = dc->w.DCOrgX + dc->w.brushOrgX;
+    val.ts_y_origin = dc->w.DCOrgY + dc->w.brushOrgY;
+    XChangeGC( display, gc,
+              GCForeground | GCBackground | GCFillStyle |
+              GCTileStipXOrigin | GCTileStipYOrigin | mask,
+              &val );
+    if (pixmap) XFreePixmap( display, pixmap );
+    return TRUE;
+}
+
+
+/***********************************************************************
  *           PatBlt    (GDI.29)
  */
 BOOL PatBlt( HDC hdc, short left, short top,
@@ -122,56 +761,189 @@
 /***********************************************************************
  *           BitBlt    (GDI.34)
  */
-BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height,
+BOOL BitBlt( HDC hdcDst, short xDst, short yDst, short width, short height,
 	     HDC hdcSrc, short xSrc, short ySrc, DWORD rop )
 {
-    int xs1, xs2, ys1, ys2;
-    int xd1, xd2, yd1, yd2;
-    DWORD saverop = rop;
-    DC *dcDest, *dcSrc;
+    DC *dcDst, *dcSrc;
+    BOOL usePat, useSrc, useDst, destUsed;
+    RECT dstRect, tmpRect, clipRect;
+    const BYTE *opcode;
+    Pixmap srcPixmap = 0, dstPixmap = 0, tmpPixmap = 0;
+    GC tmpGC = 0;
+
+    usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
+    useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
+    useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
 
     dprintf_gdi(stddeb, "BitBlt: %04x %d,%d %dx%d %04x %d,%d %06lx\n",
-                hdcDest, xDest, yDest, width, height, hdcSrc, xSrc, ySrc, rop);
+                hdcDst, xDst, yDst, width, height, hdcSrc, xSrc, ySrc, rop);
 
-    if (width == 0 || height == 0) return FALSE;
-    if ((rop & 0xcc0000) == ((rop & 0x330000) << 2))
-	return PatBlt( hdcDest, xDest, yDest, width, height, rop );
+    if (!useSrc)
+	return PatBlt( hdcDst, xDst, yDst, width, height, rop );
+
+    dcDst = (DC *) GDI_GetObjPtr( hdcDst, DC_MAGIC );
+    if (!dcDst) 
+    {
+	dcDst = (DC *)GDI_GetObjPtr(hdcDst, METAFILE_DC_MAGIC);
+	if (!dcDst) return FALSE;
+	MF_BitBlt(dcDst, xDst, yDst, width, height,
+		  hdcSrc, xSrc, ySrc, rop);
+	return TRUE;
+    }
+    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    if (!dcSrc) return FALSE;
+
+    if ((width * dcSrc->w.VportExtX / dcSrc->w.WndExtX !=
+         width * dcDst->w.VportExtX / dcDst->w.WndExtX) ||
+        (height * dcSrc->w.VportExtY / dcSrc->w.WndExtY !=
+         height * dcDst->w.VportExtY / dcDst->w.WndExtY))
+	return StretchBlt( hdcDst, xDst, yDst, width, height,
+                           hdcSrc, xSrc, ySrc, width, height, rop );
+
+    xSrc = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
+    ySrc = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
+    xDst = dcDst->w.DCOrgX + XLPTODP( dcDst, xDst );
+    yDst = dcDst->w.DCOrgY + YLPTODP( dcDst, yDst );
+    width  = width * dcDst->w.VportExtX / dcDst->w.WndExtX;
+    height = height * dcDst->w.VportExtY / dcDst->w.WndExtY;
+
+    tmpRect.left   = min( xDst, xDst + width );
+    tmpRect.top    = min( yDst, yDst + height );
+    tmpRect.right  = max( xDst, xDst + width );
+    tmpRect.bottom = max( yDst, yDst + height );
+
+    GetClipBox( hdcDst, &clipRect );
+    OffsetRect( &clipRect, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
+    if (!IntersectRect( &dstRect, &tmpRect, &clipRect )) return TRUE;
+
+    xSrc  += dstRect.left - xDst;
+    ySrc  += dstRect.top - yDst;
+    xDst   = dstRect.left;
+    yDst   = dstRect.top;
+    width  = dstRect.right - dstRect.left;
+    height = dstRect.bottom - dstRect.top;
+
+    if (rop == SRCCOPY)  /* Optimisation for SRCCOPY */
+    {
+        DC_SetupGCForText( dcDst );
+        if (dcSrc->w.bitsPerPixel == dcDst->w.bitsPerPixel)
+        {
+	    XCopyArea( display, dcSrc->u.x.drawable, dcDst->u.x.drawable,
+                       dcDst->u.x.gc, xSrc, ySrc, width, height, xDst, yDst );
+            return TRUE;
+        }
+        if (dcSrc->w.bitsPerPixel == 1)
+        {
+	    XCopyPlane( display, dcSrc->u.x.drawable,
+                        dcDst->u.x.drawable, dcDst->u.x.gc,
+                        xSrc, ySrc, width, height, xDst, yDst, 1);
+            return TRUE;
+        }
+    }
 
     rop >>= 16;
 
-    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
-    if (!dcSrc) return FALSE;
-    dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC );
-    if (!dcDest) 
+    /* printf( "BitBlt: applying rop %lx\n", rop ); */
+    tmpGC = XCreateGC( display, rootWindow, 0, NULL );
+    srcPixmap = XCreatePixmap( display, rootWindow, width, height,
+                               dcDst->w.bitsPerPixel );
+    dstPixmap = XCreatePixmap( display, rootWindow, width, height,
+                               dcDst->w.bitsPerPixel );
+    if (useSrc)
+        BITBLT_GetArea( hdcSrc, hdcDst, srcPixmap, tmpGC,
+                        xSrc, ySrc, width, height );
+    if (useDst)
+        BITBLT_GetArea( hdcDst, hdcDst, dstPixmap, tmpGC,
+                        xDst, yDst, width, height );
+    if (usePat)
+        BITBLT_SelectBrush( dcDst, tmpGC );
+    destUsed = FALSE;
+
+    for (opcode = BITBLT_Opcodes[rop & 0xff]; *opcode; opcode++)
     {
-	dcDest = (DC *)GDI_GetObjPtr(hdcDest, METAFILE_DC_MAGIC);
-	if (!dcDest) return FALSE;
-	MF_BitBlt(dcDest, xDest, yDest, width, height,
-		  hdcSrc, xSrc, ySrc, saverop);
-	return TRUE;
+        switch(*opcode >> 4)
+        {
+        case OP_ARGS(DST,TMP):
+            if (!tmpPixmap) tmpPixmap = XCreatePixmap( display, rootWindow,
+                                                       width, height,
+                                                       dcDst->w.bitsPerPixel );
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XCopyArea( display, dstPixmap, tmpPixmap, tmpGC,
+                       0, 0, width, height, 0, 0 );
+            break;
+
+        case OP_ARGS(DST,SRC):
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XCopyArea( display, dstPixmap, srcPixmap, tmpGC,
+                       0, 0, width, height, 0, 0 );
+            break;
+
+        case OP_ARGS(SRC,TMP):
+            if (!tmpPixmap) tmpPixmap = XCreatePixmap( display, rootWindow,
+                                                       width, height,
+                                                       dcDst->w.bitsPerPixel );
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XCopyArea( display, srcPixmap, tmpPixmap, tmpGC,
+                       0, 0, width, height, 0, 0 );
+            break;
+
+        case OP_ARGS(SRC,DST):
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XCopyArea( display, srcPixmap, dstPixmap, tmpGC,
+                       0, 0, width, height, 0, 0 );
+            destUsed = TRUE;
+            break;
+
+        case OP_ARGS(PAT,TMP):
+            if (!tmpPixmap) tmpPixmap = XCreatePixmap( display, rootWindow,
+                                                       width, height,
+                                                       dcDst->w.bitsPerPixel );
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XFillRectangle( display, tmpPixmap, tmpGC, 0, 0, width, height );
+            break;
+
+        case OP_ARGS(PAT,DST):
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XFillRectangle( display, dstPixmap, tmpGC, 0, 0, width, height );
+            destUsed = TRUE;
+            break;
+
+        case OP_ARGS(PAT,SRC):
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XFillRectangle( display, srcPixmap, tmpGC, 0, 0, width, height );
+            break;
+
+        case OP_ARGS(TMP,SRC):
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XCopyArea( display, tmpPixmap, srcPixmap, tmpGC,
+                       0, 0, width, height, 0, 0 );
+            break;
+
+        case OP_ARGS(TMP,DST):
+            XSetFunction( display, tmpGC, *opcode & 0x0f );
+            XCopyArea( display, tmpPixmap, dstPixmap, tmpGC,
+                       0, 0, width, height, 0, 0 );
+            destUsed = TRUE;
+            break;
+        }
     }
-
-    xs1 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
-    xs2 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc + width );
-    ys1 = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
-    ys2 = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc + height );
-    xd1 = dcDest->w.DCOrgX + XLPTODP( dcDest, xDest );
-    xd2 = dcDest->w.DCOrgX + XLPTODP( dcDest, xDest + width );
-    yd1 = dcDest->w.DCOrgY + YLPTODP( dcDest, yDest );
-    yd2 = dcDest->w.DCOrgY + YLPTODP( dcDest, yDest + height );
-
-    if ((abs(xs2-xs1) != abs(xd2-xd1)) || (abs(ys2-ys1) != abs(yd2-yd1)))
-	return FALSE;  /* Should call StretchBlt here */
-    
-    DC_SetupGCForText( dcDest );
+    XSetFunction( display, dcDst->u.x.gc, GXcopy );
+    BITBLT_PutArea( hdcDst, destUsed ? dstPixmap : srcPixmap,
+                    dcDst->u.x.gc, xDst, yDst, width, height );
+    XFreePixmap( display, dstPixmap );
+    XFreePixmap( display, srcPixmap );
+    if (tmpPixmap) XFreePixmap( display, tmpPixmap );
+    XFreeGC( display, tmpGC );
+    return TRUE;
+#if 0
     if (((rop & 0x0f) == (rop >> 4))&&(rop!=0xbb))
 	/* FIXME: Test, whether more than just 0xbb has to be excluded */
       {
-        XSetFunction( display, dcDest->u.x.gc, DC_XROPfunction[rop & 0x0f] );
-        if (dcSrc->w.bitsPerPixel == dcDest->w.bitsPerPixel)
+        XSetFunction( display, dcDst->u.x.gc, DC_XROPfunction[rop & 0x0f] );
+        if (dcSrc->w.bitsPerPixel == dcDst->w.bitsPerPixel)
         {
 	    XCopyArea( display, dcSrc->u.x.drawable,
-	    	       dcDest->u.x.drawable, dcDest->u.x.gc,
+	    	       dcDst->u.x.drawable, dcDst->u.x.gc,
 		       min(xs1,xs2), min(ys1,ys2), abs(xs2-xs1), abs(ys2-ys1),
 		       min(xd1,xd2), min(yd1,yd2) );
         }
@@ -194,7 +966,7 @@
 	/* HDC hdcBrush = CreateCompatibleDC(hdcDest);
 	DC *dcBrush;*/
 	RECT r = {min(xDest,xDest+width), min(yDest,yDest+height), 
-		  MAX(xDest,xDest+width), MAX(yDest,yDest+height)};
+		  max(xDest,xDest+width), max(yDest,yDest+height)};
 	HBRUSH cur_brush=SelectObject(hdcDest, GetStockObject(BLACK_BRUSH));
 	SelectObject(hdcDest, cur_brush);
         /* FillRect(hdcBrush, &r, cur_brush);*/
@@ -286,6 +1058,7 @@
 	XDestroyImage(bxi);
 	/*DeleteDC(hdcBrush);*/
       }
+#endif
     return TRUE;
 }
 
@@ -594,4 +1367,3 @@
 
     return TRUE;
 }
-
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 7766826..86c6e3b 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -139,7 +139,7 @@
 	hbitmap = 0;
     }
     else if (bmp->bmBits)  /* Set bitmap bits */
-	SetBitmapBits( hbitmap, bmp->bmHeight*bmp->bmWidthBytes, bmp->bmBits );
+	SetBitmapBits( hbitmap, bmpObjPtr->bitmap.bmHeight*bmpObjPtr->bitmap.bmWidthBytes, bmp->bmBits );
     return hbitmap;
 }
 
diff --git a/objects/brush.c b/objects/brush.c
index 75de5d6..1bfed42 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -8,7 +8,6 @@
 
 #include "gdi.h"
 #include "bitmap.h"
-#include "prototypes.h"
 #include "metafile.h"
 #include "stddebug.h"
 #include "color.h"
diff --git a/objects/clipping.c b/objects/clipping.c
index d0c3e13..48717e6 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -2,15 +2,13 @@
  * DC clipping functions
  *
  * Copyright 1993 Alexandre Julliard
- *
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ */
+
 #include <stdio.h>
 #include "gdi.h"
 #include "metafile.h"
 #include "stddebug.h"
 /* #define DEBUG_CLIPPING */
-/* #undef  DEBUG_CLIPPING */
 #include "debug.h"
 
 /***********************************************************************
@@ -129,7 +127,7 @@
 
     if (dc->w.hClipRgn)
     {
-	int retval = OffsetRgn( dc->w.hClipRgn, x, y );
+	int retval = OffsetRgn( dc->w.hClipRgn, XLPTODP(dc,x), YLPTODP(dc,y) );
 	CLIPPING_UpdateGCRegion( dc );
 	return retval;
     }
@@ -163,6 +161,11 @@
     HRGN tempRgn, newRgn;
     int ret;
 
+    left   = XLPTODP( dc, left );
+    right  = XLPTODP( dc, right );
+    top    = YLPTODP( dc, top );
+    bottom = YLPTODP( dc, bottom );
+
     if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
     if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
     {
@@ -237,6 +240,11 @@
     HRGN tempRgn, newRgn;
     int ret;
 
+    left   = XLPTODP( dc, left );
+    right  = XLPTODP( dc, right );
+    top    = YLPTODP( dc, top );
+    bottom = YLPTODP( dc, bottom );
+
     if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
     if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
     {
@@ -312,10 +320,7 @@
     if (!dc) return FALSE;
     dprintf_clipping(stddeb,"RectVisible: %d %p\n", hdc, rect );
     if (!dc->w.hGCClipRgn) return FALSE;
-    tmpRect.left   = XLPTODP(dc, rect->left);
-    tmpRect.top    = YLPTODP(dc, rect->top);
-    tmpRect.right  = XLPTODP(dc, rect->right);
-    tmpRect.bottom = YLPTODP(dc, rect->bottom);
+    LPtoDP( hdc, (LPPOINT)rect, 2 );
     return RectInRegion( dc->w.hGCClipRgn, &tmpRect );
 }
 
@@ -325,10 +330,13 @@
  */
 int GetClipBox( HDC hdc, LPRECT rect )
 {
+    int ret;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return ERROR;    
     dprintf_clipping(stddeb, "GetClipBox: %d %p\n", hdc, rect );
-    return GetRgnBox( dc->w.hGCClipRgn, rect );
+    ret = GetRgnBox( dc->w.hGCClipRgn, rect );
+    DPtoLP( hdc, (LPPOINT)rect, 2 );
+    return ret;
 }
 
 
diff --git a/objects/color.c b/objects/color.c
index 500eac2..3523880 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -48,10 +48,14 @@
 };
 
 static HANDLE hSysColorTranslation = 0;
+static HANDLE hRevSysColorTranslation = 0;
 
    /* Map an EGA index (0..15) to a pixel value. Used for dithering. */
 int COLOR_mapEGAPixel[16];
 
+int* COLOR_PaletteToPixel = NULL;
+int* COLOR_PixelToPalette = NULL;
+int COLOR_ColormapSize = 0;
 
 /***********************************************************************
  *           COLOR_BuildMap
@@ -93,16 +97,29 @@
  */
 static HPALETTE COLOR_InitPalette(void)
 {
-    int i, size;
+    int i, size, pixel;
     XColor color;
     HPALETTE hpalette;
     LOGPALETTE * palPtr;
-    WORD *colorTranslation;
+    WORD *colorTranslation, *revTranslation;
 
-    if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
-				   sizeof(WORD)*NB_RESERVED_COLORS ))) return FALSE;
-    colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
     size = DefaultVisual( display, DefaultScreen(display) )->map_entries;
+    COLOR_ColormapSize = size;
+    if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
+				            sizeof(WORD)*NB_RESERVED_COLORS )))
+        return FALSE;
+    if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
+                                                    sizeof(WORD)*size )))
+        return FALSE;
+    colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
+    revTranslation   = (WORD *) GDI_HEAP_ADDR( hRevSysColorTranslation );
+
+    if (COLOR_WinColormap == DefaultColormapOfScreen(screen))
+    {
+        COLOR_PaletteToPixel = (int *)malloc( sizeof(int) * size );
+        COLOR_PixelToPalette = (int *)malloc( sizeof(int) * size );
+    }
+
     for (i = 0; i < NB_RESERVED_COLORS; i++)
     {
 	color.red   = COLOR_sysPaletteEntries[i].peRed * 65535 / 255;
@@ -110,34 +127,38 @@
 	color.blue  = COLOR_sysPaletteEntries[i].peBlue * 65535 / 255;
 	color.flags = DoRed | DoGreen | DoBlue;
 
+        if (i < NB_RESERVED_COLORS/2)
+        {
+            /* Bottom half of the colormap */
+            pixel = i;
+            if (pixel >= size/2) continue;
+        }
+        else
+        {
+            /* Top half of the colormap */
+            pixel = size - NB_RESERVED_COLORS + i;
+            if (pixel < size/2) continue;
+        }
 	if (COLOR_WinColormap != DefaultColormapOfScreen(screen))
 	{
-	    if (i < NB_RESERVED_COLORS/2)
-	    {
-		  /* Bottom half of the colormap */
-		color.pixel = i;
-		if (color.pixel >= size/2) continue;
-	    }
-	    else
-	    {
-		  /* Top half of the colormap */
-		color.pixel = size - NB_RESERVED_COLORS + i;
-		if (color.pixel < size/2) continue;
-	    }
+            color.pixel = pixel;
 	    XStoreColor( display, COLOR_WinColormap, &color );
 	}
-	else if (!XAllocColor( display, COLOR_WinColormap, &color ))
-	{
-	    fprintf(stderr, "Warning: Not enough free colors. Try using the -privatemap option.\n" );
-	    color.pixel = color.red = color.green = color.blue = 0;
-	}
+	else
+        {
+            if (!XAllocColor( display, COLOR_WinColormap, &color ))
+            {
+                fprintf(stderr, "Warning: Not enough free colors. Try using the -privatemap option.\n" );
+                color.pixel = color.red = color.green = color.blue = 0;
+            }
+            else
+            {
+                COLOR_PaletteToPixel[pixel] = color.pixel;
+                COLOR_PixelToPalette[color.pixel] = pixel;
+            }
+        }
 	colorTranslation[i] = color.pixel;
-#if 0
-	  /* Put the allocated colors back in the list */
-	COLOR_sysPaletteEntries[i].peRed   = color.red >> 8;
-	COLOR_sysPaletteEntries[i].peGreen = color.green >> 8;
-	COLOR_sysPaletteEntries[i].peBlue  = color.blue >> 8;
-#endif
+        revTranslation[color.pixel] = i;
 	  /* Set EGA mapping if color in the first or last eight */
 	if (i < 8)
 	    COLOR_mapEGAPixel[i] = color.pixel;
@@ -232,7 +253,7 @@
     WORD index = 0;
     WORD *mapping;
 
-    if (dc && !dc->u.x.pal.hMapping) return 0;
+    if (screenDepth > 8) return color;
     switch(color >> 24)
     {
     case 0:  /* RGB */
@@ -256,7 +277,8 @@
         if (index >= NB_RESERVED_COLORS) return 0;
         mapping = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
     }
-    return mapping[index];
+    if (mapping) return mapping[index];
+    else return index;  /* Identity mapping */
 }
 
 
@@ -265,12 +287,16 @@
  *
  * Set the color-mapping table in a DC.
  */
-void COLOR_SetMapping( DC *dc, HANDLE map, WORD size )
+void COLOR_SetMapping( DC *dc, HANDLE map, HANDLE revMap, WORD size )
 {
     WORD *pmap, *pnewmap;
+    WORD i;
 
     if (dc->u.x.pal.hMapping && (dc->u.x.pal.hMapping != hSysColorTranslation))
 	GDI_HEAP_FREE( dc->u.x.pal.hMapping );
+    if (dc->u.x.pal.hRevMapping &&
+        (dc->u.x.pal.hRevMapping != hRevSysColorTranslation))
+	GDI_HEAP_FREE( dc->u.x.pal.hRevMapping );
     if (map && (map != hSysColorTranslation))
     {
 	  /* Copy mapping table */
@@ -278,8 +304,17 @@
 	pmap = (WORD *) GDI_HEAP_ADDR( map );
 	pnewmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping );
 	memcpy( pnewmap, pmap, sizeof(WORD)*size );
+          /* Build reverse table */
+        dc->u.x.pal.hRevMapping = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
+                                             sizeof(WORD)*COLOR_ColormapSize );
+        pmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hRevMapping );
+        for (i = 0; i < size; i++) pmap[pnewmap[i]] = i;
     }
-    else dc->u.x.pal.hMapping = map;
+    else
+    {
+        dc->u.x.pal.hMapping = map;
+        dc->u.x.pal.hRevMapping = map ? hRevSysColorTranslation : 0;
+    }
     dc->u.x.pal.mappingSize = size;
 }
 
@@ -306,6 +341,7 @@
     DC *dc;
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     dc->w.hPalette = STOCK_DEFAULT_PALETTE;
-    COLOR_SetMapping( dc, hSysColorTranslation, NB_RESERVED_COLORS );
+    COLOR_SetMapping( dc, hSysColorTranslation,
+                      hRevSysColorTranslation, NB_RESERVED_COLORS );
     return NB_RESERVED_COLORS;
 }
diff --git a/objects/dc.c b/objects/dc.c
index 87d8006..df8e413 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -136,7 +136,7 @@
     }
     val.function = DC_XROPfunction[dc->w.ROPmode-1];
     val.fill_style = dc->u.x.brush.fillStyle;
-    if (val.fill_style == FillStippled)
+    if ((val.fill_style==FillStippled) || (val.fill_style==FillOpaqueStippled))
     {
 	if (dc->w.backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled;
 	val.stipple = dc->u.x.brush.pixmap;
@@ -244,7 +244,8 @@
 	newdc->w.hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
 	CombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
     }
-    COLOR_SetMapping( newdc, dc->u.x.pal.hMapping, dc->u.x.pal.mappingSize );
+    COLOR_SetMapping( newdc, dc->u.x.pal.hMapping,
+                      dc->u.x.pal.hRevMapping, dc->u.x.pal.mappingSize );
     return handle;
 }
 
@@ -279,7 +280,8 @@
 
     SelectObject( hdc, dcs->w.hBrush );
     SelectObject( hdc, dcs->w.hFont );
-    COLOR_SetMapping( dc, dcs->u.x.pal.hMapping, dcs->u.x.pal.mappingSize );
+    COLOR_SetMapping( dc, dcs->u.x.pal.hMapping,
+                      dcs->u.x.pal.hRevMapping, dcs->u.x.pal.mappingSize );
 }
 
 
diff --git a/objects/dib.c b/objects/dib.c
index d841f01..fe2ae9d 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -1,10 +1,9 @@
 /*
- * GDI device independent bitmaps
+ * GDI device-independent bitmaps
  *
- * Copyright 1993 Alexandre Julliard
- *
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-*/
+ * Copyright 1993,1994  Alexandre Julliard
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <X11/Xlib.h>
@@ -17,23 +16,32 @@
 #include "color.h"
 #include "debug.h"
 
-static int get_bpp(int depth)
+
+/***********************************************************************
+ *           DIB_GetImageWidthBytes
+ *
+ * Return the width of an X image in bytes
+ */
+int DIB_GetImageWidthBytes( int width, int depth )
 {
-	switch(depth) {
-		case 4:
-		case 8:	
-			return 1;
-		case 15:
-		case 16:
-			return 2;
-		case 24:
-			return 4;
-		default:
-			fprintf(stderr, "DIB: unsupported depth %d!\n", depth);
-			exit(1);
-	}		
+    int words;
+
+    switch(depth)
+    {
+    case 1:  words = (width + 31) / 32; break;
+    case 4:  words = (width + 7) / 8; break;
+    case 8:  words = (width + 3) / 4; break;
+    case 15:
+    case 16: words = (width + 1) / 2; break;
+    case 24: words = width; break;
+    default:
+        fprintf(stderr, "DIB: unsupported depth %d.\n", depth );
+        exit(1);
+    }
+    return 4 * words;
 }
 
+
 /***********************************************************************
  *           DIB_BitmapInfoSize
  *
@@ -61,11 +69,11 @@
 {
     extern void _XInitImageFuncPtrs( XImage* );
     XImage * image;
-    int bytesPerLine = bmp->biWidth * get_bpp(bmp->biBitCount);
 
-    image = XCreateImage( display, DefaultVisualOfScreen( screen ),
-			  bmp->biBitCount, ZPixmap, 0, bmpData,
-			  bmp->biWidth, bmp->biHeight, 32, bytesPerLine );
+    image = XCreateImage(display, DefaultVisualOfScreen( screen ),
+                         bmp->biBitCount, ZPixmap, 0, bmpData,
+                         bmp->biWidth, bmp->biHeight, 32,
+                         DIB_GetImageWidthBytes(bmp->biWidth,bmp->biBitCount));
     if (!image) return 0;
     image->byte_order = MSBFirst;
     image->bitmap_bit_order = MSBFirst;
@@ -359,7 +367,7 @@
 			      dprintf_bitmap(stddeb, 
 					     "DIB_SetImageBits_RLE8(): "
 					     "Delta to last line of bitmap "
-					     "(wrongly??) causes loop exit\n");
+					     "(wrongly?) causes loop exit\n");
 			    }
 			  break;
 		      }
@@ -448,8 +456,7 @@
 {
     int *colorMapping;
     XImage *bmpImage;
-    void *bmpData;
-    int i, colors, widthBytes;
+    int i, colors;
 
       /* Build the color mapping table */
 
@@ -477,12 +484,7 @@
     }
 
       /* Transfer the pixels */
-    widthBytes = info->bmiHeader.biWidth * get_bpp(depth);
-
-    bmpData  = malloc( lines * widthBytes );
-    bmpImage = XCreateImage( display, DefaultVisualOfScreen(screen),
-			     depth, ZPixmap, 0, bmpData,
-			     info->bmiHeader.biWidth, lines, 32, widthBytes );
+    XCREATEIMAGE(bmpImage, info->bmiHeader.biWidth, lines, depth );
 
     switch(info->bmiHeader.biBitCount)
     {
diff --git a/objects/dither.c b/objects/dither.c
index d90396d..79a1dcd 100644
--- a/objects/dither.c
+++ b/objects/dither.c
@@ -85,12 +85,7 @@
  */
 BOOL DITHER_Init(void)
 {
-    int bytes_per_line = (screenDepth * MATRIX_SIZE + 7) / 8;
-    if (!(imageData = (char *) malloc( bytes_per_line * MATRIX_SIZE )))
-	return FALSE;
-    ditherImage = XCreateImage( display, DefaultVisualOfScreen(screen),
-			        screenDepth, ZPixmap, 0, imageData,
-			        MATRIX_SIZE, MATRIX_SIZE, 8, bytes_per_line );
+    XCREATEIMAGE( ditherImage, MATRIX_SIZE, MATRIX_SIZE, screenDepth );
     return (ditherImage != NULL);
 }
 
@@ -104,8 +99,6 @@
     unsigned int x, y;
     Pixmap pixmap;
 
-/*    printf( "Dither: %x\n", color ); */
-
     if (color != prevColor)
     {
 	int r = GetRValue( color ) * DITHER_LEVELS;
@@ -113,8 +106,6 @@
 	int b = GetBValue( color ) * DITHER_LEVELS;
 	const int *pmatrix = dither_matrix;
 
-/*	WORD *mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping );*/
-
 	for (y = 0; y < MATRIX_SIZE; y++)
 	{
 	    for (x = 0; x < MATRIX_SIZE; x++)
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 6e8fa39..c418ec1 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -243,10 +243,6 @@
     HANDLE handle = GDI_HEAP_ALLOC( GMEM_MOVEABLE, size );
     if (!handle) return 0;
     obj = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
-    if (obj == NULL) {
-    	fprintf(stderr,"GDI_AllocObject // Error trying to get GDI_HEAD_ADDR !\n");
-    	return 0;
-    	}
     obj->hNext   = 0;
     obj->wMagic  = magic;
     obj->dwCount = ++count;
diff --git a/objects/palette.c b/objects/palette.c
index c28cb60..5ae0188 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -178,7 +178,7 @@
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     prev = dc->w.hPalette;
     dc->w.hPalette = hpal;
-    if (hpal != STOCK_DEFAULT_PALETTE) COLOR_SetMapping( dc, 0, 0 );
+    if (hpal != STOCK_DEFAULT_PALETTE) COLOR_SetMapping( dc, 0, 0, 0 );
     else RealizeDefaultPalette( hdc );  /* Always realize default palette */
     return prev;
 }
diff --git a/objects/region.c b/objects/region.c
index 5d1d1d9..f22183c 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -588,6 +588,45 @@
         return ERROR;
     region = &destObj->region;
 
+      /* Some optimizations for null regions */
+
+    if (src1Obj->region.type == NULLREGION)
+    {
+        switch(mode)
+        {
+        case RGN_AND:
+        case RGN_DIFF:
+            if (region->xrgn) XDestroyRegion( region->xrgn );
+            if (region->pixmap) XFreePixmap( display, region->pixmap );
+	    region->type = NULLREGION;
+	    region->xrgn = 0;
+	    return NULLREGION;
+        case RGN_OR:
+        case RGN_XOR:
+            return REGION_CopyRegion( src2Obj, destObj );
+	default:
+	    return ERROR;
+        }
+    }
+    else if (src2Obj->region.type == NULLREGION)
+    {
+        switch(mode)
+        {
+        case RGN_AND:
+            if (region->xrgn) XDestroyRegion( region->xrgn );
+            if (region->pixmap) XFreePixmap( display, region->pixmap );
+	    region->type = NULLREGION;
+	    region->xrgn = 0;
+	    return NULLREGION;
+        case RGN_OR:
+        case RGN_XOR:
+        case RGN_DIFF:
+            return REGION_CopyRegion( src1Obj, destObj );
+	default:
+	    return ERROR;
+        }
+    }
+
     if (src1Obj->region.xrgn && src2Obj->region.xrgn)
     {
 	/* Perform the operation with X regions */
diff --git a/rc/Imakefile b/rc/Imakefile
index 02e885f..79ca9b8 100644
--- a/rc/Imakefile
+++ b/rc/Imakefile
@@ -8,7 +8,7 @@
 	echo "#include \"windows.h\"" >$*.rct
 	echo WINDOWS_H_ENDS_HERE >>$*.rct
 	cat $< >>$*.rct
-	gcc -E -x c -P $(CFLAGS) $*.rct | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o $* -v -p $*
+	$(CC) -E -x c -P $(CFLAGS) $*.rct | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o $* -v -p $*
 	$(RM) $*.rct
 
 XCOMM This would be nicer, but it breaks gcc (2.5.8 on Linux)  --AJ
@@ -18,7 +18,7 @@
 
 RCOBJS = $(RCSRCS:.rc=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(RCOBJS))
+WineRelocatableTarget($(MODULE),,$(RCOBJS))
 
 $(RCOBJS): winerc $(TOP)/include/windows.h
 
diff --git a/test/Imakefile b/test/Imakefile
deleted file mode 100644
index d45263d..0000000
--- a/test/Imakefile
+++ /dev/null
@@ -1,8 +0,0 @@
-all::
-
-depend::
-
-clean::
-
-includes::
-
diff --git a/toolkit/Imakefile b/toolkit/Imakefile
index 0ecfb4f..28bf583 100644
--- a/toolkit/Imakefile
+++ b/toolkit/Imakefile
@@ -10,7 +10,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/windows/Imakefile b/windows/Imakefile
index 237c777..e0306dc 100644
--- a/windows/Imakefile
+++ b/windows/Imakefile
@@ -31,7 +31,7 @@
 
 OBJS = $(SRCS:.c=.o)
 
-WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS))
+WineRelocatableTarget($(MODULE),,$(OBJS))
 DependTarget()
 
 includes::
diff --git a/windows/graphics.c b/windows/graphics.c
index 6f48148..4213282 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -484,7 +484,9 @@
 {
     PALETTEENTRY entry;
     XImage * image;
-    
+    WORD * mapping;
+    int pixel;
+
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return 0;
 
@@ -492,8 +494,11 @@
     return 0;
 #endif
 
+    if (!PtVisible( hdc, x, y )) return 0;
+
     x = dc->w.DCOrgX + XLPTODP( dc, x );
     y = dc->w.DCOrgY + YLPTODP( dc, y );
+#if 0
     if ((x < 0) || (y < 0)) return 0;
     
     if (!(dc->w.flags & DC_MEMORY))
@@ -505,11 +510,16 @@
 	if (win_attr.map_state != IsViewable) return 0;
 	if ((x >= win_attr.width) || (y >= win_attr.height)) return 0;
     }
-    
+#endif
     image = XGetImage( display, dc->u.x.drawable, x, y,
 		       1, 1, AllPlanes, ZPixmap );
-    GetPaletteEntries( dc->w.hPalette, XGetPixel( image, 0, 0 ), 1, &entry );
+    pixel = XGetPixel( image, 0, 0 );
     XDestroyImage( image );
+    
+    if (screenDepth > 8) return pixel;
+    mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hRevMapping );
+    if (mapping) pixel = mapping[pixel];
+    GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
     return RGB( entry.peRed, entry.peGreen, entry.peBlue );
 }
 
diff --git a/windows/painting.c b/windows/painting.c
index 0076881..16251ca 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -44,6 +44,7 @@
         return 0;
     }
     GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint );
+    DPtoLP( lps->hdc, (LPPOINT)&lps->rcPaint, 2 );
 
     SendMessage( hwnd, WM_NCPAINT, hrgnUpdate, 0 );
     DeleteObject( hrgnUpdate );
@@ -71,6 +72,7 @@
 {
     RECT rect;
     GetClientRect( hwnd, &rect );
+    DPtoLP( hdc, (LPPOINT)&rect, 2 );
     PaintRect( hwndParent, hwnd, hdc, hbrush, &rect );
 }