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 );
}