From 3a5816f87ea2954aa957c87974912fe0ca04b823 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 27 Dec 1994 14:11:53 +0000 Subject: [PATCH] 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. --- ANNOUNCE | 42 +++ COPYRIGHT | 3 - ChangeLog | 30 ++ Configure | 33 +- Imakefile | 41 +- README | 705 ++++++++-------------------------- Wine.tmpl | 8 +- controls/Imakefile | 2 +- controls/button.c | 1 + debugger/Imakefile | 16 +- debugger/opcodes/Imakefile | 2 +- debugger/readline/Imakefile | 2 +- etc/Imakefile | 9 - if1632/Imakefile | 34 +- if1632/relay.c | 1 - include/Imakefile | 36 -- include/bitmap.h | 16 +- include/color.h | 5 +- include/gdi.h | 3 +- include/prototypes.h | 4 - loader/Imakefile | 2 +- memory/Imakefile | 2 +- misc/Imakefile | 2 +- misc/main.c | 14 +- miscemu/Imakefile | 2 +- multimedia/Imakefile | 2 +- objects/Imakefile | 2 +- objects/bitblt.c | 892 +++++++++++++++++++++++++++++++++++++++++--- objects/bitmap.c | 2 +- objects/brush.c | 1 - objects/clipping.c | 28 +- objects/color.c | 100 +++-- objects/dc.c | 8 +- objects/dib.c | 66 ++-- objects/dither.c | 11 +- objects/gdiobj.c | 4 - objects/palette.c | 2 +- objects/region.c | 39 ++ rc/Imakefile | 4 +- test/Imakefile | 8 - toolkit/Imakefile | 2 +- windows/Imakefile | 2 +- windows/graphics.c | 16 +- windows/painting.c | 2 + 44 files changed, 1356 insertions(+), 850 deletions(-) create mode 100644 ANNOUNCE delete mode 100644 COPYRIGHT rewrite README (87%) delete mode 100644 etc/Imakefile delete mode 100644 include/Imakefile delete mode 100644 test/Imakefile diff --git a/ANNOUNCE b/ANNOUNCE new file mode 100644 index 00000000000..7212bee61f5 --- /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 45db164e368..00000000000 --- a/COPYRIGHT +++ /dev/null @@ -1,3 +0,0 @@ -/* - * Copyright Robert J. Amstadt, 1993 - */ diff --git a/ChangeLog b/ChangeLog index b5b9a04cf64..a2a0da435bb 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 d95d5082de0..d1b365091f3 100644 --- a/Configure +++ b/Configure @@ -56,10 +56,10 @@ then 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 @@ EOF 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 1f0b13b2ab4..ea60138f845 100644 --- a/Imakefile +++ b/Imakefile @@ -21,18 +21,15 @@ DEFINES = AutoDefines -DUSE_READLINE -DWINESTAT #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 @@ LIBSUBDIRS = \ 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 @@ DependSubdirs($(SUBDIRS)) 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:: 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 dissimilarity index 87% index 20e574889d9..d172aa95642 100644 --- a/README +++ b/README @@ -1,550 +1,155 @@ -0. LICENSE - -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. - -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. - -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. - -1. COMPILATION: - -You must have one of: - - Linux version 0.99.13 or above - NetBSD-current - FreeBSD-current or FreeBSD 1.1 - -To build Wine, first do a "./Configure" and then a "make" (or "gmake" -if you're running *BSD). The executable "wine" will be built. "wine" -will load and run 16-bit Windows' executables. - - - -2. 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. - -The formatstyle of this config file is just like a windows .ini file. - -Here's an explanation of each section: - -* [drives] - -format: = -default: none - -This section is used to specify the root directory of each `dos'drive -as windows' applications require a dos/mswindows based diskdrive & -directory scheme. - -If you mounted you dos-partition as /dos and installed microsoft windows -in c:\windows than you should specify c=/dos in the drives section. - -* [wine] - -format: windows = -default: c:\windows - -Used to specify an different windows directory. - -format: system = -default: c:\windows\system - -Used to specify an different system directory. - -format: temp = -default: c:\temp - -Used to specify a directory where windows applications can store temporary -files. - -format: path = -default: c:\windows;c:\windows\system - -Used to specify the path which will be used to find executables and DLL's. - -format: systemresources = -default: c:\temp - -Used to specify the name of sysres.dll, a dll which is used by wine itself. - -* [serialports] - -format: com[12345678] = -default: none - -Used to specify the devices which are used as com1 - com8. - -* [parallelports] - -format: lpt[12345678] = -default: none - -Used to specify the devices which are used as lpt1 - lpt8. - -* [spy] - -format: file = -default: none - -used to specify the file which will be used as logfile. - -format: exclude = -default: none - -Used to specify which messages will be excluded from the logfile. - -format: include = -default: none - -Used to specify which messages will be included in the logfile. - - - -3. RUNNING PROGRAMS - -When invoking wine, you must specify the entire path to the executable, -or a filename only. - -For example: to run Windows' solitaire: - - wine sol (using the searchpath to locate the file) - wine sol.exe - - wine c:\\windows\\sol.exe (using a dosfilename) - - wine /usr/windows/sol.exe (using a unixfilename) - -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. - - - -4. EXAMPLE CONFIGFILE - ----------------------------------------------------------------------------- -[drives] -a=/mnt/fd0 -c=/dos -d=~/Wine - -[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. +1. INTRODUCTION + +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. + +Wine is free software. See the file LICENSE for the details. +Basically, you can do anything with it, except claim that you wrote it. + +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. + + +2. COMPILATION + +You must have one of: + + Linux version 0.99.13 or above + NetBSD-current + FreeBSD-current or FreeBSD 1.1 + +To build Wine, first do a "./Configure" and then a "make" (or "gmake" +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". + + +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 home directory. + +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: + +* [drives] + +format: = +default: none + +This section is used to specify the root directory of each `dos'drive +as Windows' applications require a dos/mswindows based diskdrive & +directory scheme. + +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] + +format: windows = +default: c:\windows + +Used to specify an different windows directory. + +format: system = +default: c:\windows\system + +Used to specify an different system directory. + +format: temp = +default: c:\temp + +Used to specify a directory where Windows applications can store temporary +files. + +format: path = +default: c:\windows;c:\windows\system + +Used to specify the path which will be used to find executables and DLL's. + +format: systemresources = +default: c:\temp + +Used to specify the name of sysres.dll, a dll which is used by Wine itself. + +* [serialports] + +format: com[12345678] = +default: none + +Used to specify the devices which are used as com1 - com8. + +* [parallelports] + +format: lpt[12345678] = +default: none + +Used to specify the devices which are used as lpt1 - lpt8. + +* [spy] + +format: file = +default: none + +used to specify the file which will be used as logfile. + +format: exclude = +default: none + +Used to specify which messages will be excluded from the logfile. + +format: include = +default: none + +Used to specify which messages will be included in the logfile. + + +4. RUNNING PROGRAMS + +When invoking Wine, you must specify the entire path to the executable, +or a filename only. + +For example: to run Windows' solitaire: + + wine sol (using the searchpath to locate the file) + wine sol.exe + + wine c:\\windows\\sol.exe (using a dosfilename) + + wine /usr/windows/sol.exe (using a unixfilename) + +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, occasionally it may crash. + + +5. GETTING MORE INFORMATION + +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. + +If you add something, or fix a bug, please send a patch to +wine-new@amscons.com for inclusion in the next release. + +-- +Alexandre Julliard +julliard@lamisun.epfl.ch diff --git a/Wine.tmpl b/Wine.tmpl index 13a84cc54da..e1f7e0b6287 100644 --- a/Wine.tmpl +++ b/Wine.tmpl @@ -8,24 +8,24 @@ XCOMM First, dll description to files etc #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 374441d43a8..582965b3f38 100644 --- a/controls/Imakefile +++ b/controls/Imakefile @@ -15,7 +15,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/controls/button.c b/controls/button.c index 2e4ab5ec4a7..54c5df0955f 100644 --- a/controls/button.c +++ b/controls/button.c @@ -138,6 +138,7 @@ LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) 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 0eae52b6d8d..a6c260c5cb7 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 @@ SRCS = \ 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 fc12d018bcd..0d94d3f55f3 100644 --- a/debugger/opcodes/Imakefile +++ b/debugger/opcodes/Imakefile @@ -18,7 +18,7 @@ OBJS = $(SRCS:.c=.o) #undef xi386 #endif -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/debugger/readline/Imakefile b/debugger/readline/Imakefile index e50e7c53554..f780bd61a55 100644 --- a/debugger/readline/Imakefile +++ b/debugger/readline/Imakefile @@ -13,7 +13,7 @@ SRCS = \ 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 a81b367c592..00000000000 --- 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 9812c1d7c47..bd0bae2fe94 100644 --- a/if1632/Imakefile +++ b/if1632/Imakefile @@ -39,23 +39,23 @@ OBJS = $(CALLOBJS) $(DLLOBJS) $(SRCS:.c=.o) $(DLLOBJS:.o=_tab.o) $(DLLOBJS:dll_. /* * 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 @@ pop.h: $(TOP)/tools/build $(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 0118a12486f..5a5b6cb961a 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -15,7 +15,6 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include -#include #endif #include "neexe.h" diff --git a/include/Imakefile b/include/Imakefile deleted file mode 100644 index 48217568cb8..00000000000 --- 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 280946f3be4..7d730b7a86c 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 #include #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 faf9fd7ee71..543b4ff917c 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 6aae216d9ce..b176d424288 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -203,7 +203,8 @@ typedef struct /* 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 ebde9cdd910..5ba1e4fe97f 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -57,10 +57,6 @@ extern void SpyInit(void); 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 488f6e6e569..c8a7bed52d5 100644 --- a/loader/Imakefile +++ b/loader/Imakefile @@ -19,7 +19,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/memory/Imakefile b/memory/Imakefile index d6586b914bc..55448b0fbc8 100644 --- a/memory/Imakefile +++ b/memory/Imakefile @@ -9,7 +9,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/misc/Imakefile b/misc/Imakefile index 140fcc3a90f..a08699e711b 100644 --- a/misc/Imakefile +++ b/misc/Imakefile @@ -29,7 +29,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/misc/main.c b/misc/main.c index 74a87789b6e..9aa9111efdd 100644 --- a/misc/main.c +++ b/misc/main.c @@ -31,12 +31,14 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; 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 f44c8764aa8..be64a271711 100644 --- a/miscemu/Imakefile +++ b/miscemu/Imakefile @@ -20,7 +20,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/multimedia/Imakefile b/multimedia/Imakefile index daed8c23b74..c7db9346c4e 100644 --- a/multimedia/Imakefile +++ b/multimedia/Imakefile @@ -12,7 +12,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/objects/Imakefile b/objects/Imakefile index d4d24f72da3..60afdecb49b 100644 --- a/objects/Imakefile +++ b/objects/Imakefile @@ -24,7 +24,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/objects/bitblt.c b/objects/bitblt.c index e945faf5009..142c9a95d93 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 #include #include @@ -14,13 +13,503 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #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 char Copyright[] = "Copyright Alexandre Julliard, 1993"; 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 @@ static XImage *BITBLT_GetImage( HDC hdc, int x, int y, int width, int height ) /*********************************************************************** + * 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 @@ BOOL PatBlt( HDC hdc, short left, short top, /*********************************************************************** * 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; - dprintf_gdi(stddeb, "BitBlt: %04x %d,%d %dx%d %04x %d,%d %06lx\n", - hdcDest, xDest, yDest, width, height, hdcSrc, xSrc, ySrc, rop); + usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000)); + useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000)); + useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000)); - if (width == 0 || height == 0) return FALSE; - if ((rop & 0xcc0000) == ((rop & 0x330000) << 2)) - return PatBlt( hdcDest, xDest, yDest, width, height, rop ); + dprintf_gdi(stddeb, "BitBlt: %04x %d,%d %dx%d %04x %d,%d %06lx\n", + hdcDst, xDst, yDst, width, height, hdcSrc, xSrc, ySrc, rop); - rop >>= 16; + 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; - dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); - if (!dcDest) + + 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 */ { - 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; + 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; + } } - 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 ); + rop >>= 16; - if ((abs(xs2-xs1) != abs(xd2-xd1)) || (abs(ys2-ys1) != abs(yd2-yd1))) - return FALSE; /* Should call StretchBlt here */ - - DC_SetupGCForText( 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++) + { + 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; + } + } + 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 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, /* 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 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, XDestroyImage(bxi); /*DeleteDC(hdcBrush);*/ } +#endif return TRUE; } @@ -594,4 +1367,3 @@ BOOL StretchBlt( HDC hdcDest, short xDest, short yDest, short widthDest, short h return TRUE; } - diff --git a/objects/bitmap.c b/objects/bitmap.c index 7766826e47a..86c6e3bb74d 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -139,7 +139,7 @@ HBITMAP CreateBitmapIndirect( BITMAP * bmp ) 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 75de5d6842b..1bfed42ee42 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -8,7 +8,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #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 d0c3e134951..48717e6c286 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 #include "gdi.h" #include "metafile.h" #include "stddebug.h" /* #define DEBUG_CLIPPING */ -/* #undef DEBUG_CLIPPING */ #include "debug.h" /*********************************************************************** @@ -129,7 +127,7 @@ int OffsetClipRgn( HDC hdc, short x, short y ) 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 @@ static int CLIPPING_IntersectClipRect( DC * dc, short left, short top, 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 @@ static int CLIPPING_IntersectVisRect( DC * dc, short left, short top, 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 @@ BOOL RectVisible( HDC hdc, LPRECT rect ) 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 @@ BOOL RectVisible( HDC hdc, LPRECT rect ) */ 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 500eac22eb4..35238808d6c 100644 --- a/objects/color.c +++ b/objects/color.c @@ -48,10 +48,14 @@ static PALETTEENTRY COLOR_sysPaletteEntries[NB_RESERVED_COLORS] = }; 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 BOOL COLOR_BuildMap( Colormap map, int depth, int size ) */ static HPALETTE COLOR_InitPalette(void) { - int i, size; + int i, size, pixel; XColor color; HPALETTE hpalette; LOGPALETTE * palPtr; - WORD *colorTranslation; + WORD *colorTranslation, *revTranslation; + size = DefaultVisual( display, DefaultScreen(display) )->map_entries; + COLOR_ColormapSize = size; if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE, - sizeof(WORD)*NB_RESERVED_COLORS ))) return FALSE; + 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 ); - size = DefaultVisual( display, DefaultScreen(display) )->map_entries; + 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 @@ static HPALETTE COLOR_InitPalette(void) 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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color ) 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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color ) 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 @@ int COLOR_ToPhysical( DC *dc, COLORREF color ) * * 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 @@ void COLOR_SetMapping( DC *dc, HANDLE map, WORD size ) 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; + dc->u.x.pal.hRevMapping = map ? hRevSysColorTranslation : 0; } - else dc->u.x.pal.hMapping = map; dc->u.x.pal.mappingSize = size; } @@ -306,6 +341,7 @@ WORD RealizeDefaultPalette( HDC hdc ) 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 87d800645d1..df8e41395c5 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -136,7 +136,7 @@ int DC_SetupGCForBrush( DC * dc ) } 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 @@ HDC GetDCState( HDC hdc ) 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 @@ void SetDCState( HDC hdc, HDC hdcs ) 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 d841f01f8ca..fe2ae9d69b6 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 #include #include @@ -17,23 +16,32 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #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 @@ static XImage *DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) { 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 @@ static void DIB_SetImageBits_RLE8(WORD lines, 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 @@ static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits, { int *colorMapping; XImage *bmpImage; - void *bmpData; - int i, colors, widthBytes; + int i, colors; /* Build the color mapping table */ @@ -477,12 +484,7 @@ static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits, } /* 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 d90396dbe7f..79a1dcd12ec 100644 --- a/objects/dither.c +++ b/objects/dither.c @@ -85,12 +85,7 @@ static char *imageData = NULL; */ 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 @@ Pixmap DITHER_DitherColor( DC *dc, COLORREF color ) unsigned int x, y; Pixmap pixmap; -/* printf( "Dither: %x\n", color ); */ - if (color != prevColor) { int r = GetRValue( color ) * DITHER_LEVELS; @@ -113,8 +106,6 @@ Pixmap DITHER_DitherColor( DC *dc, COLORREF color ) 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 6e8fa39f88c..c418ec1b8a7 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -243,10 +243,6 @@ HANDLE GDI_AllocObject( WORD size, WORD magic ) 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 c28cb60d026..5ae01884757 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -178,7 +178,7 @@ HPALETTE GDISelectPalette( HDC hdc, HPALETTE hpal ) 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 5d1d1d9d419..f22183cf5dc 100644 --- a/objects/region.c +++ b/objects/region.c @@ -588,6 +588,45 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) 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 02e885f5441..79ca9b87539 100644 --- a/rc/Imakefile +++ b/rc/Imakefile @@ -8,7 +8,7 @@ MODULE = rc 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 @@ RCSRCS = sysres.rc sysresbm.rc 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 d45263d3c95..00000000000 --- a/test/Imakefile +++ /dev/null @@ -1,8 +0,0 @@ -all:: - -depend:: - -clean:: - -includes:: - diff --git a/toolkit/Imakefile b/toolkit/Imakefile index 0ecfb4fea6c..28bf583c61d 100644 --- a/toolkit/Imakefile +++ b/toolkit/Imakefile @@ -10,7 +10,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/windows/Imakefile b/windows/Imakefile index 237c777e3ad..e0306dc1ee2 100644 --- a/windows/Imakefile +++ b/windows/Imakefile @@ -31,7 +31,7 @@ SRCS = \ OBJS = $(SRCS:.c=.o) -WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() includes:: diff --git a/windows/graphics.c b/windows/graphics.c index 6f481482c99..421328223d6 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -484,7 +484,9 @@ COLORREF GetPixel( HDC hdc, short x, short y ) { PALETTEENTRY entry; XImage * image; - + WORD * mapping; + int pixel; + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; @@ -492,8 +494,11 @@ COLORREF GetPixel( HDC hdc, short x, short y ) 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 @@ COLORREF GetPixel( HDC hdc, short x, short y ) 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 0076881a902..16251ca1718 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -44,6 +44,7 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) 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 @@ void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush ) { RECT rect; GetClientRect( hwnd, &rect ); + DPtoLP( hdc, (LPPOINT)&rect, 2 ); PaintRect( hwndParent, hwnd, hdc, hbrush, &rect ); } -- 2.11.4.GIT