diff --git a/BUGS b/BUGS index 1e43469f75e..d005f852b85 100644 --- a/BUGS +++ b/BUGS @@ -1 +1,5 @@ - EBP and ESP are sometimes corrupted while running 16-bit code. +- Dialog Boxes created by WM_CREATE handler aren't visible +- RegisterClass() with hbrBackground = COLOR_APPWORKSPACE+1 does not work. +- MDI client area needs to resize when frame does +- Need to generate WM_CHILDACTIVATE \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index 5533bfc1dad..c69135a14a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,452 @@ +---------------------------------------------------------------------- +Tue Apr 5 14:36:59 1994 Bob Amstadt (bob@pooh) + + * [include/mdi.h] [windows/mdi.c] + Use WM_PARENTNOTIFY messages to activate children. + Generate WM_CHILDACTIVATE messages. + Beginnings handler for maxmized child window. + Clean up when children are destroyed. + + * [windows/message.c] [windows/nonclient.c] [windows/winpos.c] + Removed code add 94/03/26. + +Apr 4, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [control/menu.c] + Make mouse menu navigation working again. :-)) + (be carefull, clicking outside menus (ie.: clientrect) + not resolved yet) + + * [windows/nonclient.c] [controls/scroll.c] + Bugs fix in NCTrackScrollBars(). + + * [misc/dos_fs.c] + Bug fix in 'ToDos()' in conversion for '/', + (example: '/window/' was translated to 'WINDOWs'). + + * [miscemu/int21.c] + Function ChangeDir() extract possible drive before DOS_ChangeDir(). + + * [loader/library.c] [loader/wine.c] + Playing around moving function GetProcAddress() and put some code in. + +Mon Apr 4 21:39:07 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) + + * [misc/main.c] + Better explanation of command-line options. + + * [objects/dib.c] + Implemented SetDIBitsToDevice(). + + * [windows/dc.c] + Bug fix in SetDCState(). + + * [windows/event.c] + Removed WS_DISABLED handling (now done in message.c). + + * [windows/message.c] + Added sending a WM_PARENTNOTIFY message in MSG_TranslateMouseMsg(). + Use WindowFromPoint() to find the window for mouse events, taking + into account disabled windows. + + * [windows/painting.c] + Bug fix in BeginPaint() to allow calling it at other times than + on WM_PAINT (Solitaire needs it...) + + * [windows/win.c] + Implemented FindWindow(). + Rewritten EnableWindow() to behave more like Windows. + + * [windows/winpos.c] + Rewritten WindowFromPoint() to also search child windows. + +Mon Apr 4 17:36:32 1994 Erik Bos (erik@trashcan.hacktic.nl) + + * [include/int21.h] -> [msdos.h] + renamed. + + * [miscemu/int10.h] [miscemu/int25.h] [miscemu/int26.h] + new, added for int 10, 25 and 26. + + * [miscemu/ioports.c] + new, added to allow win apps to use ioports. + + * [loader/signal.c] + Added support for in, inb, out, outb instructions. + +---------------------------------------------------------------------- +Sun Mar 27 13:40:25 1994 Bob Amstadt (bob@pooh) + + * controls/menu.c (InsertMenu): Changed to use FindMenuItem(). + +Sat Mar 26 21:23:55 1994 Bob Amstadt (bob@pooh) + + * [windows/mdi.c] + Window list properly updated. + + * [windows/message.c] + Call WINPOS_ChildActivate() when mouse pressed. + + * [windows/nonclient.c] + Use WINPOS_IsAnActiveWindow() instead of GetActiveWindow() in + NC_HandleNCPaint(). + + * [windows/winpos.c] + Created functions WINPOS_IsAnActiveWindow() and WINPOS_ActivateChild() + +Thu Mar 24 14:49:17 1994 Bob Amstadt (bob@pooh) + + * controls/menu.c (DeleteMenu): Changed to use FindMenuItem + (DeleteMenu): Many bug fixes. + + * [controls/menu.c] + Created function FindMenuItem(). + +Thu Mar 24 14:17:24 1994 Bob Amstadt (bob@pooh) + + * [windows/win.c] + Removed incorrect MDI handling code from CreateWindowEx(). + + * [controls/menu.c] + MF_STRING items needed to allocate a private copy of string. + + * [controls/menu.c] + Fixed buggy calls to GlobalFree(). + + * [memory/global.c] + Eliminated some redundant code with function call. + +Wed Mar 23 1994 Pentti Moilanen (pentti.moilanen@ntc.nokia.com) + + * [windows/timer.c] + timer list pointers looped in InsertTimer + +Tue Mar 29 13:32:08 MET DST 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [misc/cursor.c] + A few changes for desktop window support. + + * [misc/main.c] + Added -depth option. + + * [misc/rect.c] + Yet another bug fix in SubtractRect(). + + * [objects/bitmap.c] + Changes to use only one depth (specified with -depth) + for color bitmaps. + + * [objects/brush.c] + Added support for dithered solid brushes. + + * [objects/color.c] + Use the same 20 system colors as in Windows. + System palette initialisation now done in COLOR_InitPalette(). + Added support for a color mapping table to map logical color + indexes to X colormap entries. + Implemented GetNearestColor() and RealizeDefaultPalette(). + + * [objects/dib.c] + Added support for color mapping table. + + * [objects/dither.c] (New file) + Implemented solid color dithering. + + * [objects/palette.c] + Implemented GetSystemPaletteEntries() and SelectPalette(). + + * [windows/class.c] + Make a copy of the menu name in RegisterClass(). + + * [windows/dc.c] + Fixed device caps when using a desktop window. + Added support for the color mapping table in DCs. + + * [windows/event.c] + Added ConfigureNotify handler on desktop window. + + * [windows/message.c] + Removed call to XTranslateCoordinates() on every mouse motion + New function MSG_Synchronize() to synchronize with the X server. + + * [windows/syscolor.c] + Rewritten SYSCOLOR_Init() to read the system colors from WIN.INI. + + * [windows/winpos.c] + Added synchronization on window mapping. Solves the double redraw + problem when starting Solitaire. + +Mar 27, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [control/menu.c] * [windows/defwnd.c] + Make keyboard navigation working with menubar, + but temporarely inserted a bug in menubar mouse handling ... :-(( + (it will be fix next week !) + + * [windows/defwnd.c] + Connect VK_MENU to menubar navigation. + + * [loader/library.c] + GetModuleHandle() return 'fictive 0xF000+ handles' for built-in DLLs. + +Sun Mar 20 22:32:13 1994 Erik Bos (erik@trashcan.hacktic.nl) + + * [misc/main.c] + Added Copy(). Added a check for `-h' to show usage. + + * [misc/dos_fs.c] + Fixed bug in FindFile(), to load directories as dlls. + + * [misc/dos_fs.c] + Fixed ToUnix() and ToDos() again, as my previous patch + didn't make it. + + * [misc/dos_fs.c] [miscemu/int21.c] + Bug fixes, should be able to handle all winfile and progman int21 + requests now except for a few small things. + +Tue Mar 29 06:25:54 1994 crw@harris.mlb.semi.harris.com (Carl Williams) + + * [memory/heap.c] + Implemented GetFreeSystemResources(). + +---------------------------------------------------------------------- +Mon Mar 21 17:32:25 1994 Bob Amstadt (bob@pooh) + + * controls/menu.c (GetSubMenu): Function did not return correct value + + * [windows/mdi.c] + Beginnings of menu handling. + +Thu Mar 10 11:32:06 1994 Stefan (SAM) Muenzel (muenzel@tat.physik.uni-tuebingen.de) + + * [objects/font.c] + if font.width equals zero use asterix instead. + +Mon Mar 21 17:23:37 MET 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [objects/bitmap.c] + Rewritten bitmap code to use exclusively X pixmaps; *much* faster. + + * [objects/brush.c] + Some changes with pattern brushes because of the new bitmap code. + + * [objects/color.c] + Added function COLOR_ToPhysical for better color mapping. + + * [objects/dib.c] + Heavily optimized SetDIBits(). + + * [windows/dc.c] + Opimized SetDCState() and DC_SetupGC*() functions. + Added stub for CreateIC(). + +Mar 20, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [misc/message.c] + Call SetFocus() after closing box to give back focus to previous owner. + + * [misc/files.c] + Small bug fix in GetTempFilename() : replace a '\' to '\\'. + + * [control/scroll.c] + Calls to BitBlt() replace by StretchBlt(). + + * [control/menu.c] + Call SetFocus() to previous owner after closing Popups. + Fill stub DeleteMenu(). + + * [control/listbox.c] + * [control/combo.c] + Use SetFocus() in WM_LBUTTONDOWN. + Close ComboBox List upon WM_KILLFOCUS. + Early development of WM_MEASUREITEM mecanism. + + * [windows/defwnd.c] + Early development of WM_MEASUREITEM mecanism. + +Tue Mar 22 10:44:57 1994 Miguel de Icaza (miguel@xochitl) + + * [misc/atom.c] + Fixed sintaxis problem when building the library. + +---------------------------------------------------------------------- +Tue Mar 15 13:11:56 1994 Bob Amstadt (bob@pooh) + + * [include/windows.h] + Added message types and structures for MDI + + * [include/mdi.h] + Created internal structures for handling MDI + + * [windows/mdi.c] + Began creating MDI support + +Thu Mar 10 16:51:46 1994 Bob Amstadt (bob@pooh) + + * [loader/wine.c] [include/wine.h] + Added new field to "struct w_files" to hold the "name table" + resource for Windows 3.0 programs + + * [loader/resource.c] + Added code to handle programs with a "name table" resource. + LoadResourceByName() modified to check for the existence of + this resource. + +Mon Mar 14 22:31:42 MET 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [objects/color.c] + Added installing the private colormap on the desktop window. + + * [windows/event.c] + Cleaned up focus event handling (see focus.c). + Use GetFocus() to direct key events to the correct window. + + * [windows/focus.c] + Rewritten SetFocus() to: + - only set X focus on top-level windows + - send WM_SETFOCUS and WM_KILLFOCUS messages (was done in event.c) + - prevent setting focus to disabled windows + - install private colormap so -privatemap option works again + + * [windows/message.c] [windows/timer.c] + Changed timer management to no longer use PostMessage(), but + to generate timer messages on the fly. Also fixed a related bug + in GetMessage() which could cause busy-waiting. + + * [windows/win.c] + Only select focus events on top-level windows. + + * [windows/winpos.c] + Added some sanity checks for desktop window. + +Fri Mar 4 20:42:01 1994 Erik Bos (erik@trashcan.hacktic.nl) + + * [misc/dos_fs.c] + bug fixes in ToUnix(), WinIniFileName(), GetUnixFileName(). + Support for tilde symbol added for rootdirectories in [drives] + section of wine's configfile. + + * [misc/file.c] + hread(), hwrite() added. + + * [misc/main.c] + hmemcpy() added. + + * [if1632/stress.spec] [include/stress.h] [misc/stress.c] + Added STRESS.DLL, an useless dll used to stress a windows system. + + * [*/*] + Added missing #includes, fixed prototypes for prototype checking. + + * [include/prototypes.h] + + Added prototypes for loader/*c, if1632/*c. + +---------------------------------------------------------------------- +Tue Mar 8 09:54:34 1994 Bob Amstadt (bob@pooh) + + * [Configure] + Added reminder to set WINEPATH, if it is not set. + + * [Imakefile] + Removed #elif's + + * [controls/button.c] + Added BN_CLICKED notification for owner-draw buttons. + + * [if1632/kernel.spec] [memory/heap.c] + Changed Local* functions to WIN16_Local* to prevent unconcious use + of these functions. + + * [if1632/relay.c] + Push old Stack16Frame on stack before setting. + + * [include/atom.h] [misc/atom.c] [include/heap.h] [memory/local.c] + Added multiple local heap handling in Atom* functions. + + * [include/regfunc.h] [miscemu/int21.c] + Rewrote DOS3Call() use context frame that is already on the stack. + + * [misc/profile.c] + Fixed to allow leading ";" to mark comments. + + * [misc/spy.c] + Fixed bugs and added support for "include" and "exclude" filters. + + * [misc/user.c] + Rearranged calls in InitApp(). + + * [misc/font.c] + Fixed font handling to create system fonts, if they are used. + + * [windows/dc.c] + If text drawn on window with no font specified, then default the + font to the system font. + +Mon Mar 7 20:32:09 MET 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [controls/desktop.c] + Added handling of WM_NCCREATE and WM_ERASEBKGND functions. + Implemented SetDeskPattern(). + + * [misc/main.c] + Added -desktop option to get a large desktop window with + everything inside it. + Added -name option. + + * [misc/rect.c] + Bug fix in SubtractRect(). + + * [objects/*.c] + Replaced the DefaultRootWindow() macro by the rootWindow variable. + + * [windows/event.c] [windows/message.c] + [windows/nonclient.c] [windows/win.c] + A few changes to accomodate the new desktop window. + + Tue Mar 8 11:13:03 1994 Miguel de Icaza (miguel@xochitl.nuclecu.unam.mx) + + * [toolkit/arch.c] --New file-- + Routines for converting little endian data structures to + big-endian data structures, currently only BITMAP structures are + converted. + + * [misc/atom.c] + When used as part of the WineLib, the code is much simpler. + Doesn't depend on alignement. + + * [loader/wine.c] + Ifdefed Emulator dependent code if compiling WineLib. + + * [loader/resource.c] + Moved misc/resource.c to loader/resource.c. + + * [loader/dump.c,ldt.c,ldtlib.c,library,c,selector.c,signal.c] + Ifdefed whole code if compiling WINELIB. + + * [include/winsock.h] + Added compilation define to allow compilation on SunOS. + + * [include/wine.h] + Removed load_typeinfo and load_nameinfo prototypes, they belong + to neexe.h + + * [include/neexe.h] + Added load_typeinfo and load_nameinfo prototypes. + + * [include/arch.h] + Fixed some bugs in the conversion routines. + Added macros for Bitmap loading. + +Tue Mar 8 12:52:05 1994 crw@maniac.mlb.semi.harris.com (Carl Williams) + + * [if1632/kernel.spec] [memory/global.c] + Implemented GetFreeSpace() + + * [if1632/user.spec] [loader/resource.c] + Implemented CreateIcon() + ---------------------------------------------------------------------- Tue Mar 1 11:30:21 1994 Bob Amstadt (bob@pooh) diff --git a/Configure b/Configure index c6bf0978802..15c7c31eca9 100755 --- a/Configure +++ b/Configure @@ -2,12 +2,13 @@ ALLDEFINES='' +echo echo -n 'Build Wine as emulator or library (E/L) [E]? ' read input if [ "$input" = 'l' -o "$input" = 'L' ] then - WINELIB='#define WineLib -DWINELIB' - ALLDEFINES=$ALLDEFINES -DWINELIB + WINELIB='#define WINELIB -DWINELIB' + ALLDEFINES="$ALLDEFINES -DWINELIB" else WINELIB='' fi @@ -17,14 +18,40 @@ read input if [ "$input" = 'y' -o "$input" = 'Y' ] then SHORTNAMES='#define ShortNames -DSHORTNAMES' - ALLDEFINES=$ALLDEFINES -DSHORTNAMES + ALLDEFINES="$ALLDEFINES -DSHORTNAMES" else SHORTNAMES='' fi +echo -n 'Global configfile name [/usr/local/etc/wine.conf]? ' +read input +if [ "$input" = '' ] +then + WINE_INI_GLOBAL='#define WINE_INI_GLOBAL "/usr/local/etc/wine.conf"' +else + WINE_INI_GLOBAL='#define WINE_INI_GLOBAL "'$input'"' +fi + +if [ "`(domainname)`" = 'amscons.com' ] +then + echo -n 'New build program (Y/N) [N]? ' + read input + if [ "$input" = 'y' -o "$input" = 'Y' ] + then + NEWBUILD='#define NewBuild -DNEWBUILD' + ALLDEFINES="$ALLDEFINES -DNEWBUILD" + else + NEWBUILD='' + fi +else + NEWBUILD='' +fi + echo '/* autoconf.h generated automatically. Run Configure. */' > autoconf.h echo $WINELIB >> autoconf.h echo $SHORTNAMES >> autoconf.h +echo $NEWBUILD >> autoconf.h +echo $WINE_INI_GLOBAL >> autoconf.h echo "#define AutoDefines $ALLDEFINES" >> autoconf.h xmkmf -a diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS index 3321aa9d06f..da8a5987f6b 100644 --- a/DEVELOPERS-HINTS +++ b/DEVELOPERS-HINTS @@ -12,8 +12,9 @@ SUBMITTING YOUR WORK: Submissions of code for inclussion into Wine should be sent to bob@amscons.com (Bob Amstadt). You MUST provide a suitable ChangeLog entry for any work that you submit. I prefer new code -to be submitted as diffs off of the latest release. Releases are -every Tuesday evening (approximately 19:00 PST or Wednesday 03:00 GMT). +to be submitted as unified diffs (diff -u) off of the latest release. +Releases are every Tuesday evening (approximately 17:00 PST or +Wednesday 01:00 GMT). MEMORY AND SEGMENTS: @@ -78,4 +79,11 @@ the "build" program to create dll_*.s and dll_tab_*.c. The dll_*.s files contain the entry point code for each API call, and the dll_tab_*.s files contain tables used by relay.c to translate arguments and transfer control to the proper handler. The format of the *.spec files is -documented in the file "tools/build-spec.txt". \ No newline at end of file +documented in the file "tools/build-spec.txt". + +REGISTER FUNCTIONS: + +Some functions are defined as type "register" in the DLL specification files. +Inorder to return values in the registers to the WIN16 program, the handler +function must exit by calling ReturnFromRegisterFunc(). Look at the function +DOS3Call() for an example of how this works. diff --git a/Imakefile b/Imakefile index e0662aab8ab..89039f0cbed 100644 --- a/Imakefile +++ b/Imakefile @@ -27,6 +27,7 @@ COMMONSUBDIRS = \ controls \ etc \ include \ + loader \ misc \ objects \ test \ @@ -36,7 +37,6 @@ EMUSUBDIRS = \ tools \ debugger \ if1632 \ - loader \ memory \ miscemu @@ -47,6 +47,7 @@ WINEDIR = $(LIBDIR)/wine COMMONOBJS = \ controls.o \ + loader.o \ misc.o \ objects.o \ windows.o @@ -58,7 +59,6 @@ COMMONOBJS = \ EMUOBJS = \ if1632.o \ debugger.o \ - loader.o \ memory.o \ miscemu.o \ readline.o @@ -74,11 +74,13 @@ SUBDIRS = $(COMMONSUBDIRS) $(LIBSUBDIRS) OBJS = $(COMMONOBJS) $(LIBOBJS) #endif -#if defined(i386BsdArchitecture) +#ifdef i386BsdArchitecture SYSLIBS = -ll -lm -li386 -lgnumalloc -#elif defined(i386FreeBsd) +#endif +#ifdef i386FreeBsd SYSLIBS = -ll -lm -lgnumalloc -#elif defined(LinuxArchitecture) +#endif +#ifdef LinuxArchitecture SYSLIBS = -lm -lg #endif diff --git a/README b/README index c7ff6b43c82..abc84a9a3b4 100644 --- a/README +++ b/README @@ -2,7 +2,9 @@ Copyright Robert J. Amstadt, 1993. All code is provided without warranty. All code is covered by the license contained in the file LICENSE unless explicitly stated in the individual source file. -INSTALLATION: + + +1. COMPILATION: You must have one of: @@ -11,21 +13,103 @@ You must have one of: FreeBSD-current or FreeBSD 1.1 To build Wine, first do a "./Configure" and then a "make". The -executable "wine" will be built. "wine" will load and run Windows' -executables. You must have a file "wine.ini" in the current directory, -your home directory, or in the path specified by the environment -variable WINEPATH. Multiple directories in WINEPATH should be seperated -by semi-colons and NOT by colons! +executable "wine" will be built. "wine" will load and run 16-bit +Windows' executables. -You must specify the entire path to the executable, or a filename only -(using the path= statement in wine.ini as the search path) + + +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: - export WINEPATH=/etc;/usr/windows - - wine sol (using the path= statement in wine.ini - wine sol.exe as the search path) + wine sol (using the searchpath to locate the file) + wine sol.exe wine c:\\windows\\sol.exe (using a dosfilename) @@ -34,6 +118,93 @@ For example: to run Windows' solitaire: 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-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. @@ -299,27 +470,3 @@ WHAT'S NEW with version 0.0.1: 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. - -TODO: - - - Segment fixup code completion. - - Trap and handle DOS and DPMI calls. - - GlobalAlloc of code segments. - - Rewrite global memory support including kernel mods to allow - application to mess with page map. - - Handle self-loading applications. - - Resource loading - - Lots and lots of API fiunctions. - -BUILD: - - The documentation for the build program is in the file build-spec.txt - -FINALE: - -Good luck, - - If you successfully add anything, please send me a copy. - -Bob Amstadt -bob@amscons.com diff --git a/Wine.tmpl b/Wine.tmpl index 7740d326afd..13a84cc54da 100644 --- a/Wine.tmpl +++ b/Wine.tmpl @@ -1,26 +1,36 @@ XCOMM $Id$ -INCLUDES = -I$(TOP)/include +INCLUDES = -I$(TOP)/include -I$(TOP) XCOMM Imake rules go here XCOMM First, dll description to files etc #ifndef MakeDllFromSpec +#ifndef NewBuild #ifndef ShortNames #define MakeDllFromSpec(name,objfile) @@\ -objfile.o: Concat(dll_,name.o) Concat3(dll_,name,_tab.o) @@\ - @@\ Concat(dll_,name.S) Concat3(dll_,name,_tab.c): name.spec $(TOP)/tools/build @@\ $(TOP)/tools/build name.spec @@\ -#else +#else /* ShortNames */ #define MakeDllFromSpec(name,objfile) @@\ -objfile.o: Concat(dll_,name.o) Concat(dtb_,name.o) @@\ - @@\ -Concat(dll_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/build @@\ +Concat(dll_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/build @@\ $(TOP)/tools/build name.spec @@\ -#endif /* SHORTNAMES */ +#endif /* ShortNames */ +#else /* NewBuild */ +#ifndef ShortNames +#define MakeDllFromSpec(name,objfile) @@\ +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) @@\ +Concat(dll_,name.S) Concat(rly_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/newbuild @@\ + $(TOP)/tools/newbuild name.spec @@\ + +#endif /* ShortNames */ +#endif /* NewBuild */ #endif /* MakeDllFromSpec */ /* diff --git a/controls/button.c b/controls/button.c index 7ecd9db1808..f58057b261e 100644 --- a/controls/button.c +++ b/controls/button.c @@ -963,7 +963,10 @@ static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam) ReleaseCapture(); GetClientRect(hWnd, &rc); if (PtInRect(&rc, MAKEPOINT(lParam))) + { + NOTIFY_PARENT(hWnd, BN_CLICKED); NOTIFY_PARENT(hWnd, BN_UNHILITE); + } InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); } diff --git a/controls/combo.c b/controls/combo.c index 61b5e20ee60..ae1860173c4 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -11,13 +11,16 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; +#include +#include +#include +#include + #include "windows.h" #include "combo.h" #include "heap.h" #include "win.h" -#include -#include -#include +#include "prototypes.h" HBITMAP hComboBit = 0; @@ -45,275 +48,290 @@ LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) switch(message) { case WM_CREATE: - wndPtr = WIN_FindWndPtr(hwnd); - if (wndPtr == NULL) return 0; + wndPtr = WIN_FindWndPtr(hwnd); + if (wndPtr == NULL) return 0; #ifdef DEBUG_COMBO - printf("Combo WM_CREATE %lX !\n", lphc); + printf("Combo WM_CREATE %lX !\n", lphc); #endif - if (hComboBit == (HBITMAP)NULL) - hComboBit = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_COMBO)); - GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm); - wndPtr->dwStyle &= 0xFFFFFFFFL ^ (WS_VSCROLL | WS_HSCROLL); - GetWindowRect(hwnd, &rect); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight, + if (hComboBit == (HBITMAP)NULL) + hComboBit = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_COMBO)); + GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm); + wndPtr->dwStyle &= 0xFFFFFFFFL ^ (WS_VSCROLL | WS_HSCROLL); + GetWindowRect(hwnd, &rect); + width = rect.right - rect.left; + height = rect.bottom - rect.top; + SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight, SWP_NOMOVE | SWP_NOZORDER); - CreateComboStruct(hwnd); - lphc = ComboGetStorageHeader(hwnd); - if (lphc == NULL) return 0; - if (wndPtr->dwStyle & CBS_SIMPLE) -/* lphc->hWndEdit = CreateWindow("EDIT", "", */ - lphc->hWndEdit = CreateWindow("STATIC", "", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, - 0, 0, width - bm.bmHeight, bm.bmHeight, - hwnd, 1, wndPtr->hInstance, 0L); - else - lphc->hWndEdit = CreateWindow("STATIC", "", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, - 0, 0, width - bm.bmHeight, bm.bmHeight, - hwnd, 1, wndPtr->hInstance, 0L); - lphc->hWndLBox = CreateWindow("LISTBOX", "", - WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, - wndPtr->rectClient.left, wndPtr->rectClient.top + bm.bmHeight, - width, height, wndPtr->hwndParent, 1, - wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd)); - ShowWindow(lphc->hWndLBox, SW_HIDE); + CreateComboStruct(hwnd); + lphc = ComboGetStorageHeader(hwnd); + if (lphc == NULL) return 0; + if (wndPtr->dwStyle & CBS_SIMPLE) +/* lphc->hWndEdit = CreateWindow("EDIT", "", */ + lphc->hWndEdit = CreateWindow("STATIC", "", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, + 0, 0, width - bm.bmHeight, bm.bmHeight, + hwnd, 1, wndPtr->hInstance, 0L); + else + lphc->hWndEdit = CreateWindow("STATIC", "", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, + 0, 0, width - bm.bmHeight, bm.bmHeight, + hwnd, 1, wndPtr->hInstance, 0L); + lphc->hWndLBox = CreateWindow("LISTBOX", "", + WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, + wndPtr->rectClient.left, wndPtr->rectClient.top + bm.bmHeight, + width, height, wndPtr->hwndParent, 1, + wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd)); + ShowWindow(lphc->hWndLBox, SW_HIDE); #ifdef DEBUG_COMBO - printf("Combo Creation LBox=%X!\n", lphc->hWndLBox); + printf("Combo Creation LBox=%X!\n", lphc->hWndLBox); #endif - return 0; + return 0; case WM_DESTROY: - lphc = ComboGetStorageHeader(hwnd); - if (lphc == 0) return 0; + lphc = ComboGetStorageHeader(hwnd); + if (lphc == 0) return 0; /* - DestroyWindow(lphc->hWndEdit); + DestroyWindow(lphc->hWndEdit); */ - DestroyWindow(lphc->hWndLBox); - free(lphc); + DestroyWindow(lphc->hWndLBox); + free(lphc); /* - *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; - printf("Combo WM_DESTROY after clearing wExtra !\n"); + *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; + printf("Combo WM_DESTROY after clearing wExtra !\n"); */ #ifdef DEBUG_COMBO - printf("Combo WM_DESTROY %lX !\n", lphc); + printf("Combo WM_DESTROY %lX !\n", lphc); #endif - return DefWindowProc( hwnd, message, wParam, lParam ); + return DefWindowProc( hwnd, message, wParam, lParam ); case WM_COMMAND: - wndPtr = WIN_FindWndPtr(hwnd); - lphc = ComboGetStorageHeader(hwnd); - if (lphc == NULL) return 0; - if (LOWORD(lParam) == lphc->hWndLBox) { - switch(HIWORD(lParam)) - { - case LBN_SELCHANGE: - lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL); - ShowWindow(lphc->hWndLBox, SW_HIDE); - y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); - if (y != LB_ERR) { - SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); - SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); - } - SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, CBN_SELCHANGE)); - break; - case LBN_DBLCLK: - SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, CBN_DBLCLK)); - break; - } + wndPtr = WIN_FindWndPtr(hwnd); + lphc = ComboGetStorageHeader(hwnd); + if (lphc == NULL) return 0; + if (LOWORD(lParam) == lphc->hWndLBox) { + switch(HIWORD(lParam)) { + case LBN_SELCHANGE: + lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL); + ShowWindow(lphc->hWndLBox, SW_HIDE); + y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } + SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, CBN_SELCHANGE)); + break; + case LBN_DBLCLK: + SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, CBN_DBLCLK)); + break; + } } - break; + break; case WM_LBUTTONDOWN: - printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam); - GetClientRect(hwnd, &rect); - rect.left = rect.right - (rect.bottom - rect.top); - hDC = GetDC(hwnd); - InflateRect(&rect, -1, -1); - DrawReliefRect(hDC, rect, 1, 1); - ReleaseDC(hwnd, hDC); - wndPtr = WIN_FindWndPtr(hwnd); - lphc = ComboGetStorageHeader(hwnd); - lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; - if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) - ShowWindow(lphc->hWndLBox, SW_SHOW); - else { -/* - SetFocus(lphc->hWndEdit); -*/ - ShowWindow(lphc->hWndLBox, SW_HIDE); - y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); - if (y != LB_ERR) { - SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); - SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); - } + printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam); + GetClientRect(hwnd, &rect); + rect.left = rect.right - (rect.bottom - rect.top); + hDC = GetDC(hwnd); + InflateRect(&rect, -1, -1); + DrawReliefRect(hDC, rect, 1, 1); + ReleaseDC(hwnd, hDC); + wndPtr = WIN_FindWndPtr(hwnd); + lphc = ComboGetStorageHeader(hwnd); + lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { + ShowWindow(lphc->hWndLBox, SW_SHOW); + SetFocus(lphc->hWndLBox); + } + else { + SetFocus(lphc->hWndEdit); + ShowWindow(lphc->hWndLBox, SW_HIDE); + y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } } - break; + break; case WM_LBUTTONUP: - printf("Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam); - GetClientRect(hwnd, &rect); - rect.left = rect.right - (rect.bottom - rect.top); - hDC = GetDC(hwnd); - InflateRect(&rect, -1, -1); - DrawReliefRect(hDC, rect, 1, 0); - ReleaseDC(hwnd, hDC); - break; + printf("Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam); + GetClientRect(hwnd, &rect); + rect.left = rect.right - (rect.bottom - rect.top); + hDC = GetDC(hwnd); + InflateRect(&rect, -1, -1); + DrawReliefRect(hDC, rect, 1, 0); + ReleaseDC(hwnd, hDC); + break; case WM_KEYDOWN: - wndPtr = WIN_FindWndPtr(hwnd); - lphc = ComboGetStorageHeader(hwnd); - y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); - count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L); - printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU)); - if (GetKeyState(VK_MENU) < 0) { - lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; - if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { - ShowWindow(lphc->hWndLBox, SW_SHOW); - } - else { - ShowWindow(lphc->hWndLBox, SW_HIDE); + wndPtr = WIN_FindWndPtr(hwnd); + lphc = ComboGetStorageHeader(hwnd); y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); - if (y != LB_ERR) { - SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); - SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L); + printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU)); + if (GetKeyState(VK_MENU) < 0) { + lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { + ShowWindow(lphc->hWndLBox, SW_SHOW); + SetFocus(lphc->hWndLBox); + } + else { + ShowWindow(lphc->hWndLBox, SW_HIDE); + y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } + } } - } - } - else - { - switch(wParam) { - case VK_HOME: - y = 0; - break; - case VK_END: - y = count - 1; - break; - case VK_UP: - y--; - break; - case VK_DOWN: - y++; - break; - } - if (y < 0) y = 0; - if (y >= count) y = count - 1; - SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L); - SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); - SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); - SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, CBN_SELCHANGE)); - } - break; + else { + switch(wParam) { + case VK_HOME: + y = 0; + break; + case VK_END: + y = count - 1; + break; + case VK_UP: + y--; + break; + case VK_DOWN: + y++; + break; + } + if (y < 0) y = 0; + if (y >= count) y = count - 1; + SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L); + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, CBN_SELCHANGE)); + } + break; + case WM_MEASUREITEM: + printf("ComboBoxWndProc WM_MEASUREITEM !\n"); + return(SendMessage(GetParent(hwnd), WM_MEASUREITEM, wParam, lParam)); case WM_CTLCOLOR: return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam)); case WM_PAINT: - GetClientRect(hwnd, &rect); - hDC = BeginPaint(hwnd, &paintstruct); - hMemDC = CreateCompatibleDC(hDC); - GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hComboBit); - BitBlt(hDC, rect.right - bm.bmWidth, 0, + GetClientRect(hwnd, &rect); + hDC = BeginPaint(hwnd, &paintstruct); + hMemDC = CreateCompatibleDC(hDC); + GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm); + SelectObject(hMemDC, hComboBit); + BitBlt(hDC, rect.right - bm.bmWidth, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - EndPaint(hwnd, &paintstruct); - lphc = ComboGetStorageHeader(hwnd); - InvalidateRect(lphc->hWndEdit, NULL, TRUE); - UpdateWindow(lphc->hWndEdit); - if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { - InvalidateRect(lphc->hWndLBox, NULL, TRUE); - UpdateWindow(lphc->hWndLBox); - } - break; - case CB_ADDSTRING: + DeleteDC(hMemDC); + EndPaint(hwnd, &paintstruct); + lphc = ComboGetStorageHeader(hwnd); + InvalidateRect(lphc->hWndEdit, NULL, TRUE); + UpdateWindow(lphc->hWndEdit); + if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) { + InvalidateRect(lphc->hWndLBox, NULL, TRUE); + UpdateWindow(lphc->hWndLBox); + } + break; + case WM_SETFOCUS: + lphc = ComboGetStorageHeader(hwnd); + SetFocus(lphc->hWndEdit); + break; + case WM_KILLFOCUS: + lphc = ComboGetStorageHeader(hwnd); + ShowWindow(lphc->hWndLBox, SW_HIDE); + y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); + if (y != LB_ERR) { + SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str); + SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); + } + break; + case CB_ADDSTRING: #ifdef DEBUG_COMBO - printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam); + printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam); #endif - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam)); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam)); case CB_GETLBTEXT: - printf("CB_GETLBTEXT #%u !\n", wParam); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam)); + printf("CB_GETLBTEXT #%u !\n", wParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam)); case CB_GETLBTEXTLEN: - printf("CB_GETLBTEXTLEN !\n"); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam)); + printf("CB_GETLBTEXTLEN !\n"); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam)); case CB_INSERTSTRING: - printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam)); - case CB_DELETESTRING: - printf("CB_DELETESTRING #%u !\n", wParam); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L)); - case CB_RESETCONTENT: - printf("CB_RESETCONTENT !\n"); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L)); + printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam)); + case CB_DELETESTRING: + printf("CB_DELETESTRING #%u !\n", wParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L)); + case CB_RESETCONTENT: + printf("CB_RESETCONTENT !\n"); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L)); case CB_DIR: - printf("ComboBox CB_DIR !\n"); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam)); - case CB_FINDSTRING: - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam)); - case CB_GETCOUNT: - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L)); - case CB_GETCURSEL: - printf("ComboBox CB_GETCURSEL !\n"); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L)); + printf("ComboBox CB_DIR !\n"); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam)); + case CB_FINDSTRING: + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam)); + case CB_GETCOUNT: + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L)); + case CB_GETCURSEL: + printf("ComboBox CB_GETCURSEL !\n"); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L)); case CB_SETCURSEL: - printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L)); - case CB_GETEDITSEL: - printf("ComboBox CB_GETEDITSEL !\n"); - lphc = ComboGetStorageHeader(hwnd); + printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L)); + case CB_GETEDITSEL: + printf("ComboBox CB_GETEDITSEL !\n"); + lphc = ComboGetStorageHeader(hwnd); /* return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */ - break; - case CB_SETEDITSEL: - printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam); - lphc = ComboGetStorageHeader(hwnd); + break; + case CB_SETEDITSEL: + printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam); + lphc = ComboGetStorageHeader(hwnd); /* return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */ - break; - case CB_SELECTSTRING: - printf("ComboBox CB_SELECTSTRING !\n"); - lphc = ComboGetStorageHeader(hwnd); - break; - case CB_SHOWDROPDOWN: - printf("ComboBox CB_SHOWDROPDOWN !\n"); - lphc = ComboGetStorageHeader(hwnd); - lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN; - if (wParam != 0) { - ShowWindow(lphc->hWndLBox, SW_SHOW); - } - else { - lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; - ShowWindow(lphc->hWndLBox, SW_HIDE); - SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, CBN_DROPDOWN)); - } - break; + break; + case CB_SELECTSTRING: + printf("ComboBox CB_SELECTSTRING !\n"); + lphc = ComboGetStorageHeader(hwnd); + break; + case CB_SHOWDROPDOWN: + printf("ComboBox CB_SHOWDROPDOWN !\n"); + lphc = ComboGetStorageHeader(hwnd); + lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN; + if (wParam != 0) { + ShowWindow(lphc->hWndLBox, SW_SHOW); + } + else { + lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN; + ShowWindow(lphc->hWndLBox, SW_HIDE); + SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, CBN_DROPDOWN)); + } + break; case CB_GETITEMDATA: - printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L)); + printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L)); break; case CB_SETITEMDATA: - printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam); - lphc = ComboGetStorageHeader(hwnd); - return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam)); + printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam); + lphc = ComboGetStorageHeader(hwnd); + return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam)); break; case CB_LIMITTEXT: - printf("ComboBox CB_LIMITTEXT !\n"); - lphc = ComboGetStorageHeader(hwnd); + printf("ComboBox CB_LIMITTEXT !\n"); + lphc = ComboGetStorageHeader(hwnd); /* return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */ break; - + default: - return DefWindowProc( hwnd, message, wParam, lParam ); + return DefWindowProc( hwnd, message, wParam, lParam ); } return 0; } diff --git a/controls/desktop.c b/controls/desktop.c index 14bf3c56659..183b2a2597a 100644 --- a/controls/desktop.c +++ b/controls/desktop.c @@ -6,16 +6,108 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; -#include "windows.h" +#include +#include +#include "win.h" +#include "desktop.h" + +/*********************************************************************** + * DESKTOP_DoEraseBkgnd + * + * Handle the WM_ERASEBKGND message. + */ +static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr ) +{ + RECT rect; + + /* Set colors in case pattern is a monochrome bitmap */ + SetBkColor( hdc, RGB(0,0,0) ); + SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) ); + GetClientRect( hwnd, &rect ); + FillRect( hdc, &rect, infoPtr->hbrushPattern ); + return 1; +} + + +/*********************************************************************** + * DesktopWndProc + * + * Window procedure for the desktop window. + */ LONG DesktopWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { + WND *wndPtr = WIN_FindWndPtr( hwnd ); + DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra; + /* Most messages are ignored (we DON'T call DefWindowProc) */ switch(message) { + /* Warning: this message is sent directly by */ + /* WIN_CreateDesktopWindow() and does not contain a valid lParam */ + case WM_NCCREATE: + infoPtr->hbrushPattern = 0; + infoPtr->hbitmapWallPaper = 0; + SetDeskPattern(); + break; + + case WM_ERASEBKGND: + if (rootWindow == DefaultRootWindow(display)) return 1; + return DESKTOP_DoEraseBkgnd( hwnd, (HDC)wParam, infoPtr ); } return 0; } + +/*********************************************************************** + * SetDeskPattern (USER.279) + */ +BOOL SetDeskPattern() +{ + char buffer[100]; + GetProfileString( "desktop", "Pattern", "(None)", buffer, 100 ); + return DESKTOP_SetPattern( buffer ); +} + + +/*********************************************************************** + * SetDeskWallPaper (USER.285) + */ +BOOL SetDeskWallPaper( LPSTR filename ) +{ + return TRUE; +} + + +/*********************************************************************** + * DESKTOP_SetPattern + * + * Set the desktop pattern. + */ +BOOL DESKTOP_SetPattern(char *pattern ) +{ + WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() ); + DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra; + int pat[8]; + + if (infoPtr->hbrushPattern) DeleteObject( infoPtr->hbrushPattern ); + memset( pat, 0, sizeof(pat) ); + if (pattern && sscanf( pattern, " %d %d %d %d %d %d %d %d", + &pat[0], &pat[1], &pat[2], &pat[3], + &pat[4], &pat[5], &pat[6], &pat[7] )) + { + WORD pattern[8]; + HBITMAP hbitmap; + int i; + + for (i = 0; i < 8; i++) pattern[i] = pat[i] & 0xffff; + hbitmap = CreateBitmap( 8, 8, 1, 1, pattern ); + infoPtr->hbrushPattern = CreatePatternBrush( hbitmap ); + DeleteObject( hbitmap ); + } + else infoPtr->hbrushPattern = CreateSolidBrush( GetSysColor(COLOR_BACKGROUND) ); + return TRUE; +} + diff --git a/controls/listbox.c b/controls/listbox.c index 76a3ecdf7f4..a20eea90138 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -12,17 +12,17 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include +#include #include #include -#include #include "windows.h" #include "user.h" #include "heap.h" #include "win.h" +#include "msdos.h" #include "wine.h" #include "listbox.h" #include "scroll.h" -#include "int21.h" #include "prototypes.h" #define GMEM_ZEROINIT 0x0040 @@ -34,6 +34,7 @@ void StdDrawListBox(HWND hwnd); void OwnerDrawListBox(HWND hwnd); int ListBoxFindMouse(HWND hwnd, int X, int Y); int CreateListBoxStruct(HWND hwnd); +void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls); int ListBoxAddString(HWND hwnd, LPSTR newstr); int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr); int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr); @@ -56,378 +57,411 @@ int ListBoxFindNextMatch(HWND hwnd, WORD wChar); */ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { - WND *wndPtr; - LPHEADLIST lphl; - WORD wRet; - RECT rect; - int y; - CREATESTRUCT *createStruct; - static RECT rectsel; - switch(message) - { - case WM_CREATE: - CreateListBoxStruct(hwnd); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + WND *wndPtr; + LPHEADLIST lphl; + HWND hWndCtl; + WORD wRet; + RECT rect; + int y; + CREATESTRUCT *createStruct; + static RECT rectsel; + switch(message) { + case WM_CREATE: + CreateListBoxStruct(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); #ifdef DEBUG_LISTBOX - printf("ListBox WM_CREATE %lX !\n", lphl); + printf("ListBox WM_CREATE %lX !\n", lphl); #endif - createStruct = (CREATESTRUCT *)lParam; - if (HIWORD(createStruct->lpCreateParams) != 0) - lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); - else - lphl->hWndLogicParent = GetParent(hwnd); - lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; - if (wndPtr->dwStyle & WS_VSCROLL) { - SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); - ShowScrollBar(hwnd, SB_VERT, FALSE); - } - if (wndPtr->dwStyle & WS_HSCROLL) { - SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); - ShowScrollBar(hwnd, SB_HORZ, FALSE); - } - return 0; - case WM_DESTROY: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == 0) return 0; - ListBoxResetContent(hwnd); - free(lphl); - *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; + createStruct = (CREATESTRUCT *)lParam; + if (HIWORD(createStruct->lpCreateParams) != 0) + lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); + else + lphl->hWndLogicParent = GetParent(hwnd); + lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; + if (wndPtr->dwStyle & WS_VSCROLL) { + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + ShowScrollBar(hwnd, SB_VERT, FALSE); + } + if (wndPtr->dwStyle & WS_HSCROLL) { + SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } + if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { + } + return 0; + case WM_DESTROY: + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == 0) return 0; + ListBoxResetContent(hwnd); + free(lphl); + *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; #ifdef DEBUG_LISTBOX - printf("ListBox WM_DESTROY %lX !\n", lphl); + printf("ListBox WM_DESTROY %lX !\n", lphl); #endif - return 0; + return 0; - case WM_VSCROLL: - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return 0; - y = lphl->FirstVisible; - switch(wParam) { - case SB_LINEUP: - if (lphl->FirstVisible > 1) - lphl->FirstVisible--; - break; - case SB_LINEDOWN: - if (lphl->FirstVisible < lphl->ItemsCount) - lphl->FirstVisible++; - break; - case SB_PAGEUP: - if (lphl->FirstVisible > 1) - lphl->FirstVisible -= lphl->ItemsVisible; - break; - case SB_PAGEDOWN: - if (lphl->FirstVisible < lphl->ItemsCount) - lphl->FirstVisible += lphl->ItemsVisible; - break; - case SB_THUMBTRACK: - lphl->FirstVisible = LOWORD(lParam); - break; - } - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if (lphl->FirstVisible > lphl->ItemsCount) - lphl->FirstVisible = lphl->ItemsCount; - if (y != lphl->FirstVisible) { - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - return 0; + case WM_VSCROLL: +#ifdef DEBUG_LISTBOX + printf("ListBox WM_VSCROLL w=%04X l=%08X !\n", wParam, lParam); +#endif + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return 0; + y = lphl->FirstVisible; + switch(wParam) { + case SB_LINEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible--; + break; + case SB_LINEDOWN: + if (lphl->FirstVisible < lphl->ItemsCount) + lphl->FirstVisible++; + break; + case SB_PAGEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible -= lphl->ItemsVisible; + break; + case SB_PAGEDOWN: + if (lphl->FirstVisible < lphl->ItemsCount) + lphl->FirstVisible += lphl->ItemsVisible; + break; + case SB_THUMBTRACK: + lphl->FirstVisible = LOWORD(lParam); + break; + } + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if (lphl->FirstVisible > lphl->ItemsCount) + lphl->FirstVisible = lphl->ItemsCount; + if (y != lphl->FirstVisible) { + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + return 0; - case WM_HSCROLL: - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return 0; - y = lphl->FirstVisible; - switch(wParam) { - case SB_LINEUP: - if (lphl->FirstVisible > 1) - lphl->FirstVisible -= lphl->ItemsPerColumn; - break; - case SB_LINEDOWN: - if (lphl->FirstVisible < lphl->ItemsCount) - lphl->FirstVisible += lphl->ItemsPerColumn; - break; - case SB_PAGEUP: - if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0) - lphl->FirstVisible -= lphl->ItemsVisible / - lphl->ItemsPerColumn * lphl->ItemsPerColumn; - break; - case SB_PAGEDOWN: - if (lphl->FirstVisible < lphl->ItemsCount && - lphl->ItemsPerColumn != 0) - lphl->FirstVisible += lphl->ItemsVisible / - lphl->ItemsPerColumn * lphl->ItemsPerColumn; - break; - case SB_THUMBTRACK: - lphl->FirstVisible = lphl->ItemsPerColumn * - (LOWORD(lParam) - 1) + 1; - break; - } - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if (lphl->FirstVisible > lphl->ItemsCount) - lphl->FirstVisible = lphl->ItemsCount; - if (lphl->ItemsPerColumn != 0) { - lphl->FirstVisible = lphl->FirstVisible / - lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1; - if (y != lphl->FirstVisible) { - SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / - lphl->ItemsPerColumn + 1, TRUE); + case WM_HSCROLL: +#ifdef DEBUG_LISTBOX + printf("ListBox WM_HSCROLL w=%04X l=%08X !\n", wParam, lParam); +#endif + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return 0; + y = lphl->FirstVisible; + switch(wParam) { + case SB_LINEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible -= lphl->ItemsPerColumn; + break; + case SB_LINEDOWN: + if (lphl->FirstVisible < lphl->ItemsCount) + lphl->FirstVisible += lphl->ItemsPerColumn; + break; + case SB_PAGEUP: + if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0) + lphl->FirstVisible -= lphl->ItemsVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn; + break; + case SB_PAGEDOWN: + if (lphl->FirstVisible < lphl->ItemsCount && + lphl->ItemsPerColumn != 0) + lphl->FirstVisible += lphl->ItemsVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn; + break; + case SB_THUMBTRACK: + lphl->FirstVisible = lphl->ItemsPerColumn * + (LOWORD(lParam) - 1) + 1; + break; + } + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if (lphl->FirstVisible > lphl->ItemsCount) + lphl->FirstVisible = lphl->ItemsCount; + if (lphl->ItemsPerColumn != 0) { + lphl->FirstVisible = lphl->FirstVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1; + if (y != lphl->FirstVisible) { + SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / + lphl->ItemsPerColumn + 1, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + } + return 0; + + case WM_LBUTTONDOWN: + SetFocus(hwnd); + SetCapture(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + lphl->PrevFocused = lphl->ItemFocused; + y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = y; + wRet = ListBoxGetSel(hwnd, y); + ListBoxSetSel(hwnd, y, !wRet); + } + else { + ListBoxSetCurSel(hwnd, y); + } + ListBoxGetItemRect(hwnd, y, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); - } - } - return 0; - - case WM_LBUTTONDOWN: -/* - SetFocus(hwnd); -*/ - SetCapture(hwnd); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - lphl->PrevFocused = lphl->ItemFocused; - y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { - lphl->ItemFocused = y; - wRet = ListBoxGetSel(hwnd, y); - ListBoxSetSel(hwnd, y, !wRet); - } - else { - ListBoxSetCurSel(hwnd, y); - } - ListBoxGetItemRect(hwnd, y, &rectsel); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return 0; - case WM_LBUTTONUP: - ReleaseCapture(); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - if (lphl->PrevFocused != lphl->ItemFocused) - SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, LBN_SELCHANGE)); - return 0; - case WM_RBUTTONUP: - case WM_LBUTTONDBLCLK: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, LBN_DBLCLK)); - printf("ListBox Send LBN_DBLCLK !\n"); - return 0; - case WM_MOUSEMOVE: - if ((wParam & MK_LBUTTON) != 0) { - y = HIWORD(lParam); - if (y < 4) { - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl->FirstVisible > 1) { - lphl->FirstVisible--; - if (wndPtr->dwStyle & WS_VSCROLL) - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - } - GetClientRect(hwnd, &rect); - if (y > (rect.bottom - 4)) { - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl->FirstVisible < lphl->ItemsCount) { - lphl->FirstVisible++; - if (wndPtr->dwStyle & WS_VSCROLL) - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - } - if ((y > 0) && (y < (rect.bottom - 4))) { - if ((y < rectsel.top) || (y > rectsel.bottom)) { - wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { - lphl->ItemFocused = wRet; - } - else { - ListBoxSetCurSel(hwnd, wRet); - } - ListBoxGetItemRect(hwnd, wRet, &rectsel); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - - } - } - break; - case WM_KEYDOWN: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - switch(wParam) { - case VK_HOME: - lphl->ItemFocused = 0; - break; - case VK_END: - lphl->ItemFocused = lphl->ItemsCount - 1; - break; - case VK_LEFT: - if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { - lphl->ItemFocused -= lphl->ItemsPerColumn; - break; - } - case VK_UP: - lphl->ItemFocused--; - break; - case VK_RIGHT: - if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { - lphl->ItemFocused += lphl->ItemsPerColumn; - break; - } - case VK_DOWN: - lphl->ItemFocused++; - break; - case VK_PRIOR: - lphl->ItemFocused -= lphl->ItemsVisible; - break; - case VK_NEXT: - lphl->ItemFocused += lphl->ItemsVisible; - break; - case VK_SPACE: - wRet = ListBoxGetSel(hwnd, lphl->ItemFocused); - ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet); - break; - default: - ListBoxFindNextMatch(hwnd, wParam); return 0; - } - if (lphl->ItemFocused < 0) lphl->ItemFocused = 0; - if (lphl->ItemFocused >= lphl->ItemsCount) - lphl->ItemFocused = lphl->ItemsCount - 1; - lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * - lphl->ItemsVisible + 1; - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { - ListBoxSetCurSel(hwnd, lphl->ItemFocused); - } - if (wndPtr->dwStyle & WS_VSCROLL) - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - case WM_PAINT: - wndPtr = WIN_FindWndPtr(hwnd); - if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { - OwnerDrawListBox(hwnd); - break; - } - if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) { - OwnerDrawListBox(hwnd); - break; - } - StdDrawListBox(hwnd); - break; + case WM_LBUTTONUP: + ReleaseCapture(); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + if (lphl->PrevFocused != lphl->ItemFocused) + SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, LBN_SELCHANGE)); + return 0; + case WM_RBUTTONUP: + case WM_LBUTTONDBLCLK: + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, LBN_DBLCLK)); + printf("ListBox Send LBN_DBLCLK !\n"); + return 0; + case WM_MOUSEMOVE: + if ((wParam & MK_LBUTTON) != 0) { + y = HIWORD(lParam); + if (y < 4) { + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl->FirstVisible > 1) { + lphl->FirstVisible--; + if (wndPtr->dwStyle & WS_VSCROLL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; + } + } + GetClientRect(hwnd, &rect); + if (y > (rect.bottom - 4)) { + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl->FirstVisible < lphl->ItemsCount) { + lphl->FirstVisible++; + if (wndPtr->dwStyle & WS_VSCROLL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; + } + } + if ((y > 0) && (y < (rect.bottom - 4))) { + if ((y < rectsel.top) || (y > rectsel.bottom)) { + wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = wRet; + } + else { + ListBoxSetCurSel(hwnd, wRet); + } + ListBoxGetItemRect(hwnd, wRet, &rectsel); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + } + } + break; + case WM_KEYDOWN: + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + switch(wParam) { + case VK_TAB: + hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent, + hwnd, !(GetKeyState(VK_SHIFT) < 0)); + SetFocus(hWndCtl); + if ((GetKeyState(VK_SHIFT) < 0)) + printf("ListBox PreviousDlgTabItem %04X !\n", hWndCtl); + else + printf("ListBox NextDlgTabItem %04X !\n", hWndCtl); + break; + case VK_HOME: + lphl->ItemFocused = 0; + break; + case VK_END: + lphl->ItemFocused = lphl->ItemsCount - 1; + break; + case VK_LEFT: + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemFocused -= lphl->ItemsPerColumn; + } + break; + case VK_UP: + lphl->ItemFocused--; + break; + case VK_RIGHT: + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemFocused += lphl->ItemsPerColumn; + } + break; + case VK_DOWN: + lphl->ItemFocused++; + break; + case VK_PRIOR: + lphl->ItemFocused -= lphl->ItemsVisible; + break; + case VK_NEXT: + lphl->ItemFocused += lphl->ItemsVisible; + break; + case VK_SPACE: + wRet = ListBoxGetSel(hwnd, lphl->ItemFocused); + ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet); + break; + default: + ListBoxFindNextMatch(hwnd, wParam); + return 0; + } + if (lphl->ItemFocused < 0) lphl->ItemFocused = 0; + if (lphl->ItemFocused >= lphl->ItemsCount) + lphl->ItemFocused = lphl->ItemsCount - 1; + lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * + lphl->ItemsVisible + 1; + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { + ListBoxSetCurSel(hwnd, lphl->ItemFocused); + } + if (wndPtr->dwStyle & WS_VSCROLL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; + case WM_PAINT: + wndPtr = WIN_FindWndPtr(hwnd); + if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { + OwnerDrawListBox(hwnd); + break; + } + if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) { + OwnerDrawListBox(hwnd); + break; + } + StdDrawListBox(hwnd); + break; + case WM_SETFOCUS: +#ifdef DEBUG_LISTBOX + printf("ListBox WM_SETFOCUS !\n"); +#endif + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + break; + case WM_KILLFOCUS: +#ifdef DEBUG_LISTBOX + printf("ListBox WM_KILLFOCUS !\n"); +#endif + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; case LB_RESETCONTENT: - printf("ListBox LB_RESETCONTENT !\n"); - ListBoxResetContent(hwnd); - return 0; +#ifdef DEBUG_LISTBOX + printf("ListBox LB_RESETCONTENT !\n"); +#endif + ListBoxResetContent(hwnd); + return 0; case LB_DIR: - printf("ListBox LB_DIR !\n"); - wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return wRet; - case LB_ADDSTRING: - wRet = ListBoxAddString(hwnd, (LPSTR)lParam); - return wRet; - case LB_GETTEXT: - wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam); #ifdef DEBUG_LISTBOX - printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam); + printf("ListBox LB_DIR !\n"); #endif - return wRet; - case LB_INSERTSTRING: - wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam); - return wRet; - case LB_DELETESTRING: - printf("ListBox LB_DELETESTRING #%u !\n", wParam); - wRet = ListBoxDeleteString(hwnd, wParam); - return wRet; - case LB_FINDSTRING: - wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam); - return wRet; - case LB_GETCARETINDEX: - return wRet; - case LB_GETCOUNT: - lphl = ListBoxGetStorageHeader(hwnd); - return lphl->ItemsCount; - case LB_GETCURSEL: - lphl = ListBoxGetStorageHeader(hwnd); - printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); - return lphl->ItemFocused; - case LB_GETHORIZONTALEXTENT: - return wRet; - case LB_GETITEMDATA: - return wRet; - case LB_GETITEMHEIGHT: - return wRet; - case LB_GETITEMRECT: - return wRet; - case LB_GETSEL: - wRet = ListBoxGetSel(hwnd, wParam); - return wRet; - case LB_GETSELCOUNT: - return wRet; - case LB_GETSELITEMS: - return wRet; - case LB_GETTEXTLEN: - return wRet; - case LB_GETTOPINDEX: - return wRet; - case LB_SELECTSTRING: - return wRet; - case LB_SELITEMRANGE: - return wRet; - case LB_SETCARETINDEX: - return wRet; - case LB_SETCOLUMNWIDTH: - lphl = ListBoxGetStorageHeader(hwnd); - lphl->ColumnsWidth = wParam; - break; - case LB_SETHORIZONTALEXTENT: - return wRet; - case LB_SETITEMDATA: - return wRet; - case LB_SETTABSTOPS: - return wRet; - case LB_SETCURSEL: + wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return wRet; + case LB_ADDSTRING: + wRet = ListBoxAddString(hwnd, (LPSTR)lParam); + return wRet; + case LB_GETTEXT: + wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam); #ifdef DEBUG_LISTBOX - printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam); + printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam); #endif - wRet = ListBoxSetCurSel(hwnd, wParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return wRet; - case LB_SETSEL: - printf("ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); - wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return wRet; - case LB_SETTOPINDEX: - printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); - lphl = ListBoxGetStorageHeader(hwnd); - lphl->FirstVisible = wParam; - if (wndPtr->dwStyle & WS_VSCROLL) - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - case LB_SETITEMHEIGHT: + return wRet; + case LB_INSERTSTRING: + wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam); + return wRet; + case LB_DELETESTRING: + printf("ListBox LB_DELETESTRING #%u !\n", wParam); + wRet = ListBoxDeleteString(hwnd, wParam); + return wRet; + case LB_FINDSTRING: + wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam); + return wRet; + case LB_GETCARETINDEX: + return wRet; + case LB_GETCOUNT: + lphl = ListBoxGetStorageHeader(hwnd); + return lphl->ItemsCount; + case LB_GETCURSEL: + lphl = ListBoxGetStorageHeader(hwnd); #ifdef DEBUG_LISTBOX - printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); + printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); #endif - wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); - return wRet; - - default: - return DefWindowProc( hwnd, message, wParam, lParam ); + return lphl->ItemFocused; + case LB_GETHORIZONTALEXTENT: + return wRet; + case LB_GETITEMDATA: + return wRet; + case LB_GETITEMHEIGHT: + return wRet; + case LB_GETITEMRECT: + return wRet; + case LB_GETSEL: + wRet = ListBoxGetSel(hwnd, wParam); + return wRet; + case LB_GETSELCOUNT: + return wRet; + case LB_GETSELITEMS: + return wRet; + case LB_GETTEXTLEN: + return wRet; + case LB_GETTOPINDEX: + return wRet; + case LB_SELECTSTRING: + return wRet; + case LB_SELITEMRANGE: + return wRet; + case LB_SETCARETINDEX: + return wRet; + case LB_SETCOLUMNWIDTH: + lphl = ListBoxGetStorageHeader(hwnd); + lphl->ColumnsWidth = wParam; + break; + case LB_SETHORIZONTALEXTENT: + return wRet; + case LB_SETITEMDATA: + return wRet; + case LB_SETTABSTOPS: + return wRet; + case LB_SETCURSEL: +#ifdef DEBUG_LISTBOX + printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam); +#endif + wRet = ListBoxSetCurSel(hwnd, wParam); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return wRet; + case LB_SETSEL: + printf("ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); + wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return wRet; + case LB_SETTOPINDEX: + printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); + lphl = ListBoxGetStorageHeader(hwnd); + lphl->FirstVisible = wParam; + if (wndPtr->dwStyle & WS_VSCROLL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + break; + case LB_SETITEMHEIGHT: +#ifdef DEBUG_LISTBOX + printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); +#endif + wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); + return wRet; + + default: + return DefWindowProc( hwnd, message, wParam, lParam ); } return 0; } @@ -459,11 +493,13 @@ void StdDrawListBox(HWND hwnd) LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; - HBRUSH hBrush; + HBRUSH hBrush; + int OldBkMode; + DWORD dwOldTextColor; HWND hWndParent; - HDC hdc; - RECT rect; - UINT i, h, h2, maxwidth, ipc; + HDC hdc; + RECT rect; + UINT i, h, h2, maxwidth, ipc; char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); @@ -509,12 +545,18 @@ void StdDrawListBox(HWND hwnd) lpls->dis.rcItem.bottom = h + h2; lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; + OldBkMode = SetBkMode(hdc, TRANSPARENT); + if (lpls->dis.itemState != 0) { + dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL); + FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH)); + } TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->dis.itemData, strlen((char *)lpls->dis.itemData)); if (lpls->dis.itemState != 0) { - InvertRect(hdc, &lpls->dis.rcItem); + SetTextColor(hdc, dwOldTextColor); } - if (lphl->ItemFocused == i - 1) { + SetBkMode(hdc, OldBkMode); + if ((lphl->ItemFocused == i - 1) && GetFocus() == hwnd) { DrawFocusRect(hdc, &lpls->dis.rcItem); } h += h2; @@ -675,6 +717,25 @@ int CreateListBoxStruct(HWND hwnd) } +void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls) +{ + MEASUREITEMSTRUCT *measure; + HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT)); + measure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp); + if (measure == NULL) return; + measure->CtlType = ODT_LISTBOX; + measure->CtlID = wndPtr->wIDmenu; + measure->itemID = lpls->dis.itemID; + measure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left; + measure->itemHeight = 0; + measure->itemData = lpls->dis.itemData; + SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, (DWORD)measure); + lpls->dis.rcItem.right = lpls->dis.rcItem.left + measure->itemWidth; + lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + measure->itemHeight; + USER_HEAP_FREE(hTemp); +} + + int ListBoxAddString(HWND hwnd, LPSTR newstr) { WND *wndPtr; @@ -708,6 +769,9 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) if (str == NULL) return LB_ERRSPACE; strcpy(str, newstr); newstr = str; +#ifdef DEBUG_LISTBOX + printf("ListBoxAddString// after strcpy '%s'\n", str); +#endif } } ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); @@ -716,6 +780,8 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; + if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) + ListBoxAskMeasure(wndPtr, lphl, lplsnew); if (wndPtr->dwStyle & WS_VSCROLL) SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, (lphl->FirstVisible != 1)); @@ -738,62 +804,62 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lplsnew; - HANDLE hTemp; - LPSTR str; - UINT Count; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if (uIndex >= lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - if (uIndex > lphl->ItemsCount) return LB_ERR; - for(Count = 1; Count < uIndex; Count++) { - if (lpls->lpNext == NULL) return LB_ERR; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } - hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT)); - lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp); - ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); - lplsnew->hMem = hTemp; - lpls->lpNext = lplsnew; - lphl->ItemsCount++; - hTemp = 0; - if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { - if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && - ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) { - hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1); - str = (LPSTR)USER_HEAP_ADDR(hTemp); - if (str == NULL) return LB_ERRSPACE; - strcpy(str, newstr); - newstr = str; - } - } - lplsnew->lpNext = NULL; - lplsnew->dis.itemID = lphl->ItemsCount; - lplsnew->dis.itemData = (DWORD)newstr; - lplsnew->hData = hTemp; - if (wndPtr->dwStyle & WS_VSCROLL) - SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, - (lphl->FirstVisible != 1)); - if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) - SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / - lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); - if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && - (lphl->ItemsVisible != 0)) { + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls, lplsnew; + HANDLE hTemp; + LPSTR str; + UINT Count; + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + if (uIndex >= lphl->ItemsCount) return LB_ERR; + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + if (uIndex > lphl->ItemsCount) return LB_ERR; + for(Count = 1; Count < uIndex; Count++) { + if (lpls->lpNext == NULL) return LB_ERR; + lpls = (LPLISTSTRUCT)lpls->lpNext; + } + hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT)); + lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp); + ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); + lplsnew->hMem = hTemp; + lpls->lpNext = lplsnew; + lphl->ItemsCount++; + hTemp = 0; + if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { + if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && + ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) { + hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1); + str = (LPSTR)USER_HEAP_ADDR(hTemp); + if (str == NULL) return LB_ERRSPACE; + strcpy(str, newstr); + newstr = str; + } + } + lplsnew->lpNext = NULL; + lplsnew->dis.itemID = lphl->ItemsCount; + lplsnew->dis.itemData = (DWORD)newstr; + lplsnew->hData = hTemp; + if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) + ListBoxAskMeasure(wndPtr, lphl, lplsnew); if (wndPtr->dwStyle & WS_VSCROLL) - ShowScrollBar(hwnd, SB_VERT, TRUE); - if (wndPtr->dwStyle & WS_HSCROLL) - ShowScrollBar(hwnd, SB_HORZ, TRUE); - } - if ((lphl->FirstVisible <= uIndex) && - ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - return lphl->ItemsCount; + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); + if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); + if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && + (lphl->ItemsVisible != 0)) { + if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, TRUE); + if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, TRUE); + } + if ((lphl->FirstVisible <= uIndex) && + ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + return lphl->ItemsCount; } @@ -1015,25 +1081,20 @@ int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) struct stat st; int x, wRet; char temp[256]; - +#ifdef DEBUG_LISTBOX fprintf(stderr,"ListBoxDirectory: %s, %4x\n",filespec,attrib); - - - if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) - return 0; - - while (1) - { +#endif + if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0; + while (1) { dp = (struct dosdirent *)DOS_readdir(dp); - if (!dp->inuse) - break; - - if (dp->attribute & 0x08) - { + if (!dp->inuse) break; +#ifdef DEBUG_LISTBOX + printf("ListBoxDirectory %08X '%s' !\n", dp->filename, dp->filename); +#endif + if (dp->attribute & FA_DIREC) { if (attrib & DDL_DIRECTORY) { sprintf(temp, "[%s]", dp->filename); - if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) - break; + if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break; } } else if (attrib & DDL_EXCLUSIVE) { @@ -1059,7 +1120,9 @@ int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) } } } - +#ifdef DEBUG_LISTBOX + printf("End of ListBoxDirectory !\n"); +#endif return wRet; } diff --git a/controls/menu.c b/controls/menu.c index 53d9f0ddf98..9ab0366b600 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -6,35 +6,44 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; /* #define DEBUG_MENU -#define DEBUG_SYSMENU */ +#include +#include #include "windows.h" #include "sysmetrics.h" +#include "prototypes.h" #include "menu.h" #include "heap.h" #include "win.h" -#define SC_ABOUTWINE SC_SCREENSAVE+1 -#define SC_SYSMENU SC_SCREENSAVE+2 -#define SC_ABOUTWINEDLG SC_SCREENSAVE+3 +#define SC_ABOUTWINE SC_SCREENSAVE+1 +#define SC_SYSMENU SC_SCREENSAVE+2 +#define SC_ABOUTWINEDLG SC_SCREENSAVE+3 extern HINSTANCE hSysRes; HMENU hSysMenu = 0; HBITMAP hStdCheck = 0; HBITMAP hStdMnArrow = 0; +static BOOL MenuHasFocus = FALSE; LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd); LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr); void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop); -void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y); +BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y); void StdDrawPopupMenu(HWND hwnd); +void ResetHiliteFlags(LPPOPUPMENU lppop); +BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop); +void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex); LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet); LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet); +BOOL ActivateMenuFocus(HWND hWnd); +BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu); void PopupMenuCalcSize(HWND hwnd); void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop); +LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags); LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos); WORD GetSelectionKey(LPSTR str); LPSTR GetShortCutString(LPSTR str); @@ -51,491 +60,538 @@ BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam); */ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { - CREATESTRUCT *createStruct; - WORD wRet; - short x, y; - WND *wndPtr; - LPPOPUPMENU lppop, lppop2; - LPMENUITEM lpitem, lpitem2; - HMENU hSubMenu; - RECT rect; - HDC hDC; - PAINTSTRUCT ps; - switch(message) - { - case WM_CREATE: + CREATESTRUCT *createStruct; + WORD wRet; + short x, y; + WND *wndPtr; + LPPOPUPMENU lppop, lppop2; + LPMENUITEM lpitem, lpitem2; + HMENU hSubMenu; + RECT rect; + HDC hDC; + PAINTSTRUCT ps; + switch(message) { + case WM_CREATE: #ifdef DEBUG_MENU - printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); + printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); #endif - createStruct = (CREATESTRUCT *)lParam; - lppop = (LPPOPUPMENU)createStruct->lpCreateParams; - if (lppop == NULL) break; - wndPtr = WIN_FindWndPtr(hwnd); - *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; + createStruct = (CREATESTRUCT *)lParam; + lppop = (LPPOPUPMENU)createStruct->lpCreateParams; + if (lppop == NULL) break; + wndPtr = WIN_FindWndPtr(hwnd); + *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; #ifdef DEBUG_MENU - printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); + printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); #endif - if (hStdCheck == (HBITMAP)NULL) - hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK); - if (hStdMnArrow == (HBITMAP)NULL) - hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW); - return 0; - case WM_DESTROY: - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (hStdCheck == (HBITMAP)NULL) + hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK); + if (hStdMnArrow == (HBITMAP)NULL) + hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW); + return 0; + case WM_DESTROY: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); #ifdef DEBUG_MENU - printf("PopupMenu WM_DESTROY %lX !\n", lppop); + printf("PopupMenu WM_DESTROY %lX !\n", lppop); #endif - return 0; - case WM_COMMAND: - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (lppop->hWndParent != (HWND)NULL) { - SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam); + return 0; + case WM_COMMAND: #ifdef DEBUG_MENU - printf("PopupMenu // push to lower parent WM_COMMAND !\n"); + printf("PopupMenuWndProc // WM_COMMAND received !\n"); #endif - } - else { - if (lppop->SysFlag == 0) { - SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; +/* if (!lppop->BarFlag) ShowWindow(hwnd, SW_HIDE); */ + if (lppop->SysFlag) { + MenuHasFocus = FALSE; + if (wParam == SC_ABOUTWINE) { + printf("SysMenu // Show 'About Wine ...' !\n"); +/* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */ + DialogBox(hSysRes, MAKEINTRESOURCE(2), + GetParent(hwnd), (FARPROC)AboutWine_Proc); + } + else #ifdef DEBUG_MENU - printf("PopupMenu // push to Owner WM_COMMAND !\n"); + printf("PopupMenuWndProc // push to Owner WM_SYSCOMMAND !\n"); #endif - } - else { -#ifdef DEBUG_SYSMENU - printf("PopupMenu // push to Owner WM_SYSCOMMAND !\n"); -#endif - SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam); - } - } - if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE); - break; - case WM_SHOWWINDOW: - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (wParam == 0 && lParam == 0L) { - HideAllSubPopupMenu(lppop); -#ifdef DEBUG_MENU - printf("PopupMenu WM_SHOWWINDOW -> HIDE!\n"); -#endif -/* - UpdateWindow(lppop->ownerWnd); -*/ - break; - } - lppop->FocusedItem = (WORD)-1; - if (lppop->BarFlags == 0) { - PopupMenuCalcSize(hwnd); -#ifdef DEBUG_MENU - printf("PopupMenu WM_SHOWWINDOW Width=%d Height=%d !\n", - lppop->Width, lppop->Height); -#endif - SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, - SWP_NOZORDER | SWP_NOMOVE); - } - break; - case WM_LBUTTONDOWN: - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - SetCapture(hwnd); - MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); - break; - case WM_LBUTTONUP: - lppop = PopupMenuGetStorageHeader(hwnd); - ReleaseCapture(); - MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); - break; - case WM_MOUSEMOVE: - lppop = PopupMenuGetStorageHeader(hwnd); - MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam)); - break; - - case WM_KEYDOWN: - case WM_KEYUP: - if (lParam < 0L) break; - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (lppop->FocusedItem == (WORD)-1) { - if (wParam == VK_UP || wParam == VK_DOWN || - wParam == VK_LEFT || wParam == VK_RIGHT) { - hDC = GetDC(hwnd); - lppop->FocusedItem = 0; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - ReleaseDC(hwnd, hDC); - } - break; - } - switch(wParam) { - case VK_UP: - if (lppop->BarFlags != 0) break; - if (lppop->FocusedItem < 1) break; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) - HideAllSubPopupMenu(lppop); - hDC = GetDC(hwnd); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - lppop->FocusedItem--; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - ReleaseDC(hwnd, hDC); - break; - case VK_DOWN: - if (lppop->BarFlags != 0) goto ProceedSPACE; - if (lppop->FocusedItem >= lppop->nItems - 1) break; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) - HideAllSubPopupMenu(lppop); - hDC = GetDC(hwnd); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - lppop->FocusedItem++; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - ReleaseDC(hwnd, hDC); - break; - case VK_LEFT: - if (lppop->BarFlags == 0) { - if (lppop->hWndParent != 0) - SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); - break; - } - if (lppop->FocusedItem < 1) break; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) - HideAllSubPopupMenu(lppop); - hDC = GetDC(hwnd); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - lppop->FocusedItem--; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - ReleaseDC(hwnd, hDC); - break; - case VK_RIGHT: - if (lppop->BarFlags == 0) { - if (lppop->hWndParent != 0) - SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); - break; - } - if (lppop->FocusedItem >= lppop->nItems - 1) break; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) - HideAllSubPopupMenu(lppop); - hDC = GetDC(hwnd); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - lppop->FocusedItem++; - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - ReleaseDC(hwnd, hDC); - break; - case VK_RETURN: - case VK_SPACE: -ProceedSPACE: - printf("PopupMenu VK_SPACE !\n"); - lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - hSubMenu = (HMENU)lpitem->item_id; - lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); - if (lppop2 == NULL) break; - lppop2->hWndParent = hwnd; - GetClientRect(hwnd, &rect); - if (lppop->BarFlags != 0) { - y = rect.bottom - rect.top; - TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - lpitem->rect.left, 0, - 0, lppop->ownerWnd, (LPRECT)NULL); + PostMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam); +/* PostMessage(lppop->hWndParent, WM_SYSCOMMAND, wParam, lParam); */ + break; } - else { - x = rect.right; - GetWindowRect(hwnd, &rect); - x += rect.left; - TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - x, lpitem->rect.top, - 0, lppop->ownerWnd, (LPRECT)NULL); - } - GlobalUnlock(hSubMenu); - break; - } - if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { - ShowWindow(lppop->hWnd, SW_HIDE); - if (lppop->hWndParent != (HWND)NULL) - SendMessage(lppop->hWndParent, WM_COMMAND, - lpitem->item_id, 0L); - else - SendMessage(lppop->ownerWnd, WM_COMMAND, - lpitem->item_id, 0L); #ifdef DEBUG_MENU - printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", - lpitem->item_id); + printf("PopupMenuWndProc // push to Owner WM_COMMAND !\n"); #endif - } + MenuHasFocus = FALSE; + PostMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam); +/* PostMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); */ break; - } - break; - case WM_CHAR: - if (lParam < 0L) break; - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (wParam == VK_ESCAPE) { - if (lppop->hWndParent != 0) { - lppop2 = PopupMenuGetWindowAndStorage( - lppop->hWndParent, &wndPtr); - HideAllSubPopupMenu(lppop2); - break; - } - if (lppop->FocusedItem != (WORD)-1) { - lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); - hDC = GetDC(hwnd); - if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem2->rect); - } - ReleaseDC(hwnd, hDC); + case WM_SHOWWINDOW: +#ifdef DEBUG_MENU + printf("PopupMenuWndProc // WM_SHOWWINDOW received !\n"); +#endif + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + if (wParam == 0 && lParam == 0L) { + HideAllSubPopupMenu(lppop); +#ifdef DEBUG_MENU + printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW -> HIDE!\n", hwnd); +#endif + if (lppop->SysFlag) MenuHasFocus = FALSE; + SetFocus(lppop->hWndPrev); + break; + } lppop->FocusedItem = (WORD)-1; - } - } - if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A'; - lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet); - if (lpitem != NULL) { - printf("Found wRet=%d !\n", wRet); - if (lppop->FocusedItem != (WORD)-1) { - lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); - if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) - HideAllSubPopupMenu(lppop); - hDC = GetDC(hwnd); - if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem2->rect); - } - ReleaseDC(hwnd, hDC); - } - lppop->FocusedItem = wRet; - goto ProceedSPACE; - } - break; - case WM_PAINT: - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (lppop->BarFlags == 0) { - PopupMenuCalcSize(hwnd); - StdDrawPopupMenu(hwnd); - } - break; - default: - return DefWindowProc( hwnd, message, wParam, lParam ); + if (!lppop->BarFlag) { + PopupMenuCalcSize(hwnd); + ResetHiliteFlags(lppop); +#ifdef DEBUG_MENU + printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW Width=%d Height=%d !\n", + hwnd, lppop->Width, lppop->Height); +#endif + SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, + SWP_NOZORDER | SWP_NOMOVE); +#ifdef DEBUG_MENU + printf("PopupMenuWndProc // End of WM_SHOWWINDOW !\n"); +#endif + } + break; + case WM_LBUTTONDOWN: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + SetCapture(hwnd); + MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); + break; + case WM_LBUTTONUP: + lppop = PopupMenuGetStorageHeader(hwnd); + if (lppop == NULL) break; + ReleaseCapture(); + MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam)); + break; + case WM_MOUSEMOVE: + lppop = PopupMenuGetStorageHeader(hwnd); + if (lppop == NULL) break; + MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam)); + break; + + case WM_KEYUP: +#ifdef DEBUG_MENU + printf("PopupMenuWndProc hWnd=%04X WM_KEYUP w=%04X l=%08X !\n", + hwnd, wParam, lParam); +#endif + break; + case WM_KEYDOWN: +#ifdef DEBUG_MENU + printf("PopupMenuWndProc hWnd=%04X WM_KEYDOWN w=%04X l=%08X !\n", + hwnd, wParam, lParam); +#endif + if (lParam < 0L) break; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + switch(wParam) { + case VK_HOME: + if (lppop->FocusedItem == 0) break; + MenuItemSelect(hwnd, lppop, 0); + break; + case VK_UP: + if (lppop->BarFlag) break; + if (lppop->FocusedItem < 1) break; + MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1); + break; + case VK_DOWN: + if (lppop->BarFlag) goto ProceedSPACE; + if (lppop->FocusedItem == (WORD)-1) { + MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); + break; + } + if (lppop->FocusedItem >= lppop->nItems - 1) break; + MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); + break; + case VK_LEFT: + if (lppop->SysFlag != 0) { + ShowWindow(hwnd, SW_HIDE); + hwnd = lppop->hWndParent; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + MenuItemSelect(hwnd, lppop, lppop->nItems - 1); + break; + } + if (lppop->BarFlag) { + if (lppop->FocusedItem < 1) { + MenuItemSelect(hwnd, lppop, -1); + NC_TrackSysMenu(hwnd); + break; + } + if (HideAllSubPopupMenu(lppop)) { + MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1); + goto ProceedSPACE; + } + } + if (lppop->hWndParent != 0) { + PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); + break; + } + MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1); + break; + case VK_RIGHT: + if (lppop->SysFlag != 0) { + ShowWindow(hwnd, SW_HIDE); + hwnd = lppop->hWndParent; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + MenuItemSelect(hwnd, lppop, 0); + break; + } + if (lppop->BarFlag) { + if (lppop->FocusedItem >= lppop->nItems - 1) { + MenuItemSelect(hwnd, lppop, -1); + NC_TrackSysMenu(hwnd); + break; + } + if (HideAllSubPopupMenu(lppop)) { + MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); + goto ProceedSPACE; + } + } + if (lppop->hWndParent != 0) { + PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam); + break; + } + MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1); + break; + case VK_RETURN: + case VK_SPACE: +ProceedSPACE: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + ExecFocusedMenuItem(hwnd, lppop); + break; + default: + break; + } + break; + case WM_CHAR: +#ifdef DEBUG_MENU + printf("PopupMenuWndProc hWnd=%04X WM_CHAR wParam=%04X !\n", hwnd, wParam); +#endif + if (lParam < 0L) break; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + if (wParam == VK_ESCAPE) { + if (lppop->BarFlag) { +#ifdef DEBUG_MENU + printf("VK_ESCAPE // Unselect all MenuBar's Items !\n"); +#endif + if (lppop->FocusedItem != (WORD)-1) + MenuItemSelect(hwnd, lppop, -1); + } + if (lppop->SysFlag) { +#ifdef DEBUG_MENU + printf("VK_ESCAPE // SysMenu !\n"); +#endif + ShowWindow(hwnd, SW_HIDE); + break; + } + if (lppop->hWndParent != 0) { +#ifdef DEBUG_MENU + printf("VK_ESCAPE // Hide only SubPopup !\n"); +#endif + lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr); + if (lppop2 == NULL) break; + HideAllSubPopupMenu(lppop2); + break; + } + else { +#ifdef DEBUG_MENU + printf("VK_ESCAPE // Hide Root Popup !\n"); +#endif + ShowWindow(hwnd, SW_HIDE); + MenuHasFocus = FALSE; + } + break; + } + if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A'; + lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet); + if (lpitem != NULL) { + printf("Found wRet=%d !\n", wRet); + MenuItemSelect(hwnd, lppop, wRet); + lppop->FocusedItem = wRet; + goto ProceedSPACE; + } + if (lppop->hWndParent != (HWND)NULL) + SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam, + MAKELONG(0, 0)); + else + SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam, + MAKELONG(0, 0)); + break; + case WM_PAINT: +#ifdef DEBUG_MENU + printf("PopupMenuWndProc // WM_PAINT received !\n"); +#endif + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) break; + if (!lppop->BarFlag) { + PopupMenuCalcSize(hwnd); + StdDrawPopupMenu(hwnd); + } + break; + default: + return DefWindowProc(hwnd, message, wParam, lParam); } -return(0); +return 0; } -void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y) +BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop) { - HDC hDC; - LPMENUITEM lpitem, lpitem2; - RECT rect; - HMENU hSubMenu; - WORD wRet; - LPPOPUPMENU lppop2; - lpitem = MenuFindItem(lppop, x, y, &wRet); -#ifdef DEBUG_MENU - printf("MenuButtonDown // x=%d y=%d // wRet=%d lpitem=%08X !\n", - x, y, wRet, lpitem); -#endif - if (lpitem != NULL) { - if (lppop->FocusedItem != (WORD)-1) { - HideAllSubPopupMenu(lppop); - lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - hDC = GetWindowDC(hWnd); - InvertRect(hDC, &lpitem2->rect); - ReleaseDC(hWnd, hDC); - } - } - lppop->FocusedItem = wRet; - if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - hDC = GetWindowDC(hWnd); - InvertRect(hDC, &lpitem->rect); - ReleaseDC(hWnd, hDC); - } + short x, y; + LPPOPUPMENU lppop2; + LPMENUITEM lpitem; + HMENU hSubMenu; + RECT rect; + lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem); if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - hSubMenu = (HMENU)lpitem->item_id; - lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); - if (lppop2 == NULL) return; - lppop2->hWndParent = hWnd; - if (lppop->BarFlags != 0) { - GetWindowRect(hWnd, &rect); -/* y = rect.top + lppop->Height; */ - y = rect.top + lppop->rect.bottom; - TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - rect.left + lpitem->rect.left, - y, 0, lppop->ownerWnd, (LPRECT)NULL); + hSubMenu = (HMENU)lpitem->item_id; + lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); + if (lppop2 == NULL) return FALSE; + lppop2->hWndParent = hWnd; + lppop2->hWndPrev = GetFocus(); + GetClientRect(hWnd, &rect); + if (lppop->BarFlag) { + GetWindowRect(hWnd, &rect); + y = rect.top + lppop->rect.bottom; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + rect.left + lpitem->rect.left, + y, 0, lppop->ownerWnd, (LPRECT)NULL); + } + else { + x = lppop->rect.right; + GetWindowRect(hWnd, &rect); + x += rect.left; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + x, rect.top + lpitem->rect.top, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + GlobalUnlock(hSubMenu); + return TRUE; } - else { - x = lppop->rect.right; - GetWindowRect(hWnd, &rect); - x += rect.left; - TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - x, rect.top + lpitem->rect.top, - 0, lppop->ownerWnd, (LPRECT)NULL); + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { + MenuHasFocus = FALSE; + if (lppop->BarFlag) { + PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); + } + else { + ShowWindow(lppop->hWnd, SW_HIDE); + SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L); + } } - GlobalUnlock(hSubMenu); - } - } + return TRUE; +} + + + +BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y) +{ + HDC hDC; + LPMENUITEM lpitem, lpitem2; + RECT rect; + HMENU hSubMenu; + WORD wRet; + LPPOPUPMENU lppop2; + if (lppop == NULL) return; + lpitem = MenuFindItem(lppop, x, y, &wRet); +#ifdef DEBUG_MENU + printf("MenuButtonDown // x=%d y=%d // wRet=%d lpitem=%08X !\n", + x, y, wRet, lpitem); +#endif + if (lpitem != NULL) { + MenuItemSelect(hWnd, lppop, wRet); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + hSubMenu = (HMENU)lpitem->item_id; + lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); + if (lppop2 == NULL) return; + lppop2->hWndParent = hWnd; + lppop2->hWndPrev = GetFocus(); + if (lppop->BarFlag) { + GetWindowRect(hWnd, &rect); + y = rect.top + lppop->rect.bottom; + ReleaseCapture(); + if (MenuHasFocus) { + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + rect.left + lpitem->rect.left, + y, 0, lppop->ownerWnd, (LPRECT)NULL); + } + else { + MenuHasFocus = TRUE; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + rect.left + lpitem->rect.left, + y, 0, lppop->ownerWnd, (LPRECT)NULL); + MenuHasFocus = FALSE; + MenuFocusLoop(hWnd, lppop); + return TRUE; + } + } + else { + x = lppop->rect.right; + GetWindowRect(hWnd, &rect); + x += rect.left; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + x, rect.top + lpitem->rect.top, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + GlobalUnlock(hSubMenu); + } + return TRUE; + } + printf("MenuButtonDown // x=%d y=%d // Not Found !\n", x, y); + MenuHasFocus = FALSE; + ShowWindow(lppop->hWnd, SW_HIDE); + return FALSE; } void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y) { - HDC hDC; - LPMENUITEM lpitem, lpitem2; - RECT rect; - HMENU hSubMenu; - WORD wRet; - LPPOPUPMENU lppop2; - lpitem = MenuFindItem(lppop, x, y, &wRet); + HDC hDC; + LPMENUITEM lpitem, lpitem2; + RECT rect; + HMENU hSubMenu; + WORD wRet; + LPPOPUPMENU lppop2; + if (lppop == NULL) return; + lpitem = MenuFindItem(lppop, x, y, &wRet); #ifdef DEBUG_MENU - printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n", - x, y, wRet, lpitem); + printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n", + x, y, wRet, lpitem); #endif - if (lpitem != NULL) { - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - return; - } - if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { - ShowWindow(lppop->hWnd, SW_HIDE); - if (lppop->hWndParent != (HWND)NULL) { - SendMessage(lppop->hWndParent, WM_COMMAND, - lpitem->item_id, 0L); -#ifdef DEBUG_MENU - printf("MenuButtonUp // WM_COMMAND to ParentMenu wParam=%d !\n", - lpitem->item_id); -#endif - } - else { - if (lppop->SysFlag == 0) { -#ifdef DEBUG_MENU - printf("PopupMenu // WM_COMMAND wParam=%d !\n", - lpitem->item_id); -#endif - SendMessage(lppop->ownerWnd, WM_COMMAND, - lpitem->item_id, 0L); - } - else { - if (lpitem->item_id == SC_ABOUTWINE) { - printf("SysMenu // Show 'About Wine ...' !\n"); -/* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */ - DialogBox(hSysRes, MAKEINTRESOURCE(2), - GetParent(hWnd), (FARPROC)AboutWine_Proc); + if (lpitem != NULL) { + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + return; } - else { - SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, - lpitem->item_id, 0L); -#ifdef DEBUG_SYSMENU - printf("MenuButtonUp // WM_SYSCOMMAND wParam=%04X !\n", - lpitem->item_id); -#endif + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { + MenuHasFocus = FALSE; + if (lppop->BarFlag) { + PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); + } + else { + ShowWindow(lppop->hWnd, SW_HIDE); + SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L); + } + return; } - } } -#ifdef DEBUG_MENU - printf("MenuButtonUp // SendMessage WM_COMMAND wParam=%d !\n", - lpitem->item_id); -#endif - return; - } - } - if (lppop->FocusedItem != (WORD)-1) { - HideAllSubPopupMenu(lppop); - lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); - if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - hDC = GetWindowDC(hWnd); - InvertRect(hDC, &lpitem2->rect); - ReleaseDC(hWnd, hDC); - } - } + if (lppop->FocusedItem != (WORD)-1) { + MenuItemSelect(hWnd, lppop, lppop->FocusedItem); + } } void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y) { - HDC hDC; - LPMENUITEM lpitem, lpitem2; - RECT rect; - HMENU hSubMenu; - WORD wRet; - LPPOPUPMENU lppop2; - if ((wParam & MK_LBUTTON) != 0) { - lpitem = MenuFindItem(lppop, x, y, &wRet); + HDC hDC; + RECT rect; + HMENU hSubMenu; + LPMENUITEM lpitem, lpitem2; + LPPOPUPMENU lppop2; + WORD wRet; + if ((wParam & MK_LBUTTON) != 0) { + lpitem = MenuFindItem(lppop, x, y, &wRet); #ifdef DEBUG_MENU - printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n", - x, y, wRet, lpitem); + printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n", + x, y, wRet, lpitem); #endif - if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { - lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); - hDC = GetWindowDC(hWnd); - if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem2->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem2->rect); + if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + hDC = GetWindowDC(hWnd); + if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) { + HideAllSubPopupMenu(lppop); + } + MenuItemSelect(hWnd, lppop, wRet); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + hSubMenu = (HMENU)lpitem->item_id; + lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); + if (lppop2 == NULL) { + ReleaseDC(hWnd, hDC); + return; + } + if (lppop->BarFlag) { + lppop2->hWndParent = hWnd; + lppop2->hWndPrev = GetFocus(); + GetWindowRect(hWnd, &rect); + rect.top += lppop->rect.bottom; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + rect.left + lpitem->rect.left, rect.top, + 0, lppop->ownerWnd, (LPRECT)NULL); + } + GlobalUnlock(hSubMenu); + } + ReleaseDC(hWnd, hDC); + } } - if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) { - HideAllSubPopupMenu(lppop); - } - lppop->FocusedItem = wRet; - if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) || - ((lpitem->item_flags & MF_STRING) == MF_STRING)) { - InvertRect(hDC, &lpitem->rect); - } - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - hSubMenu = (HMENU)lpitem->item_id; - lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu); - if (lppop2 == NULL) { - ReleaseDC(hWnd, hDC); - return; - } - if (lppop->BarFlags != 0) { - lppop2->hWndParent = hWnd; - GetWindowRect(hWnd, &rect); - rect.top += lppop->rect.bottom; - TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - rect.left + lpitem->rect.left, rect.top, - 0, lppop->ownerWnd, (LPRECT)NULL); - } - GlobalUnlock(hSubMenu); - } - ReleaseDC(hWnd, hDC); - } - } } +void ResetHiliteFlags(LPPOPUPMENU lppop) +{ + HDC hDC; + LPMENUITEM lpitem; + int i; + if (lppop == NULL) return; + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) return; + lpitem->item_flags &= MF_HILITE ^ 0xFFFF; + lpitem = (LPMENUITEM)lpitem->next; + } +} + + +void MenuItemSelect0(HWND hWnd, LPPOPUPMENU lppop, + LPMENUITEM lpitem, WORD wIndex) +{ + LPMENUITEM lpprev; + if (lppop == NULL) return; + if (lppop->FocusedItem != (WORD)-1) { + lpprev = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (lpprev != NULL) { + lpprev->item_flags &= MF_HILITE ^ 0xFFFF; + if ((lpprev->item_flags & MF_POPUP) == MF_POPUP) + HideAllSubPopupMenu(lppop); + if (lppop->BarFlag) + DrawMenuBar(hWnd); + else { + InvalidateRect(hWnd, &lpprev->rect, TRUE); + UpdateWindow(hWnd); + } + } + } + lppop->FocusedItem = wIndex; + if (lpitem == NULL || wIndex == (WORD)-1) { + ResetHiliteFlags(lppop); + if (lppop->BarFlag) DrawMenuBar(hWnd); + } + else { + lpitem->item_flags |= MF_HILITE; + if (lppop->BarFlag) + DrawMenuBar(hWnd); + else { + InvalidateRect(hWnd, &lpitem->rect, TRUE); + UpdateWindow(hWnd); + } + } + SendMessage(hWnd, WM_MENUSELECT, lpitem->item_id, + MAKELONG(0, lpitem->item_flags)); +} + + +void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex) +{ + LPMENUITEM lpitem; + lpitem = GetMenuItemPtr(lppop, wIndex); + MenuItemSelect0(hWnd, lppop, lpitem, wIndex); +} + LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr) { @@ -543,10 +599,17 @@ LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr) LPPOPUPMENU lppop; *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); if (Ptr == 0) { - printf("Bad Window handle on PopupMenu !\n"); - return 0; + printf("PopupMenuGetWindowAndStorage // Bad Window handle !\n"); + return NULL; } lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); + if (lppop == NULL) { + lppop = (LPPOPUPMENU) GlobalLock(Ptr->wIDmenu); + if (lppop == NULL) { + printf("PopupMenuGetWindowAndStorage // Bad Menu Handle !\n"); + return NULL; + } + } return lppop; } @@ -576,397 +639,446 @@ void SetMenuLogicalParent(HMENU hMenu, HWND hWnd) void StdDrawPopupMenu(HWND hwnd) { - WND *wndPtr; - LPPOPUPMENU lppop; - LPMENUITEM lpitem; - PAINTSTRUCT ps; - HBRUSH hBrush; - HPEN hOldPen; - HWND hWndParent; - HDC hDC, hMemDC; - RECT rect, rect2, rect3; - DWORD OldTextColor; - HFONT hOldFont; - HBITMAP hBitMap; - BITMAP bm; - UINT i, x; - hDC = BeginPaint( hwnd, &ps ); - if (!IsWindowVisible(hwnd)) { - EndPaint( hwnd, &ps ); - return; - } - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (lppop == NULL) goto EndOfPaint; - hBrush = GetStockObject(WHITE_BRUSH); - GetClientRect(hwnd, &rect); - GetClientRect(hwnd, &rect2); - FillRect(hDC, &rect, hBrush); - FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); - if (lppop->nItems == 0) goto EndOfPaint; - lpitem = lppop->firstItem; - if (lpitem == NULL) goto EndOfPaint; - for(i = 0; i < lppop->nItems; i++) { + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + PAINTSTRUCT ps; + HBRUSH hBrush; + HPEN hOldPen; + HWND hWndParent; + HDC hDC, hMemDC; + RECT rect, rect2, rect3; + DWORD OldTextColor; + int OldBkMode; + HFONT hOldFont; + HBITMAP hBitMap; + BITMAP bm; + UINT i, x; + hDC = BeginPaint(hwnd, &ps); + if (!IsWindowVisible(hwnd)) { + EndPaint(hwnd, &ps); + return; + } + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) goto EndOfPaint; + hBrush = GetStockObject(WHITE_BRUSH); + GetClientRect(hwnd, &rect); + GetClientRect(hwnd, &rect2); + FillRect(hDC, &rect, hBrush); + FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); + if (lppop->nItems == 0) goto EndOfPaint; + lpitem = lppop->firstItem; + if (lpitem == NULL) goto EndOfPaint; + for(i = 0; i < lppop->nItems; i++) { CopyRect(&rect2, &lpitem->rect); if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { - hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); - MoveTo(hDC, rect2.left, rect2.top + 1); - LineTo(hDC, rect2.right, rect2.top + 1); - SelectObject(hDC, hOldPen); - } + hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); + MoveTo(hDC, rect2.left, rect2.top + 1); + LineTo(hDC, rect2.right, rect2.top + 1); + SelectObject(hDC, hOldPen); + } if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { - hMemDC = CreateCompatibleDC(hDC); - if (lpitem->hCheckBit == 0) { - SelectObject(hMemDC, hStdCheck); - GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); - } - else { - SelectObject(hMemDC, lpitem->hCheckBit); - GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); - } - BitBlt(hDC, rect2.left, rect2.top + 1, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - } - else { - if (lpitem->hUnCheckBit != 0) { hMemDC = CreateCompatibleDC(hDC); - SelectObject(hMemDC, lpitem->hUnCheckBit); - GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); + if (lpitem->hCheckBit == 0) { + SelectObject(hMemDC, hStdCheck); + GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); + } + else { + SelectObject(hMemDC, lpitem->hCheckBit); + GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); + } BitBlt(hDC, rect2.left, rect2.top + 1, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); DeleteDC(hMemDC); } - } + else { + if (lpitem->hUnCheckBit != 0) { + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, lpitem->hUnCheckBit); + GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect2.left, rect2.top + 1, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } + } if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { - hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); - rect2.left += lppop->CheckWidth; - hMemDC = CreateCompatibleDC(hDC); - SelectObject(hMemDC, hBitMap); - GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); - BitBlt(hDC, rect2.left, rect2.top, + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + rect2.left += lppop->CheckWidth; + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitMap); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect2.left, rect2.top, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - } + DeleteDC(hMemDC); + if ((lpitem->item_flags & MF_HILITE) == MF_HILITE) + InvertRect(hDC, &lpitem->rect); + } if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && - ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); - if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) - OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + OldBkMode = SetBkMode(hDC, TRANSPARENT); + if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) + OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); + else { + if ((lpitem->item_flags & MF_HILITE) == MF_HILITE) + OldTextColor = SetTextColor(hDC, 0x00FFFFFFL); + else + OldTextColor = SetTextColor(hDC, 0x00000000L); + } + CopyRect(&rect3, &lpitem->rect); + if ((lpitem->item_flags & MF_HILITE) == MF_HILITE) + FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH)); + InflateRect(&rect3, 0, -2); + rect3.left += lppop->CheckWidth; + if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) { + DrawText(hDC, lpitem->item_text, x, &rect3, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); + DrawText(hDC, &lpitem->item_text[x], -1, &rect3, + DT_RIGHT | DT_VCENTER | DT_SINGLELINE); + } else - OldTextColor = SetTextColor(hDC, 0x00000000L); - CopyRect(&rect3, &lpitem->rect); - InflateRect(&rect3, 0, -2); - rect3.left += lppop->CheckWidth; - if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) { - DrawText(hDC, lpitem->item_text, x, &rect3, - DT_LEFT | DT_VCENTER | DT_SINGLELINE); - DrawText(hDC, &lpitem->item_text[x], -1, &rect3, - DT_RIGHT | DT_VCENTER | DT_SINGLELINE); - } - else - DrawText(hDC, lpitem->item_text, -1, &rect3, - DT_LEFT | DT_VCENTER | DT_SINGLELINE); - SetTextColor(hDC, OldTextColor); - SelectObject(hDC, hOldFont); - CopyRect(&rect2, &lpitem->rect); - } + DrawText(hDC, lpitem->item_text, -1, &rect3, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); + SetTextColor(hDC, OldTextColor); + SetBkMode(hDC, OldBkMode); + SelectObject(hDC, hOldFont); + CopyRect(&rect2, &lpitem->rect); + } if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - CopyRect(&rect3, &lpitem->rect); - rect3.left = rect3.right - lppop->PopWidth; - hMemDC = CreateCompatibleDC(hDC); - SelectObject(hMemDC, hStdMnArrow); - GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); - BitBlt(hDC, rect3.left, rect3.top + 1, + CopyRect(&rect3, &lpitem->rect); + rect3.left = rect3.right - lppop->PopWidth; + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hStdMnArrow); + GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect3.left, rect3.top + 1, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - } + DeleteDC(hMemDC); + } if (lpitem->next == NULL) goto EndOfPaint; lpitem = (LPMENUITEM)lpitem->next; - } + } EndOfPaint: - EndPaint( hwnd, &ps ); + EndPaint( hwnd, &ps ); } void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop) { - LPMENUITEM lpitem; - HBRUSH hBrush; - HPEN hOldPen; - HDC hMemDC; - RECT rect, rect2, rect3; - HFONT hOldFont; - DWORD OldTextColor; - HBITMAP hBitMap; - BITMAP bm; - UINT i, textwidth; - if (lppop == NULL || lprect == NULL) return; + LPMENUITEM lpitem; + HBRUSH hBrush; + HPEN hOldPen; + HDC hMemDC; + RECT rect, rect2, rect3; + HFONT hOldFont; + DWORD OldTextColor; + int OldBkMode; + HBITMAP hBitMap; + BITMAP bm; + UINT i, textwidth; + if (lppop == NULL || lprect == NULL) return; #ifdef DEBUG_MENU - printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop); + printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop); #endif - MenuBarCalcSize(hDC, lprect, lppop); - hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); - hBrush = GetStockObject(WHITE_BRUSH); - CopyRect(&rect, lprect); - FillRect(hDC, &rect, hBrush); - FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); - if (lppop->nItems == 0) goto EndOfPaint; - lpitem = lppop->firstItem; - if (lpitem == NULL) goto EndOfPaint; - for(i = 0; i < lppop->nItems; i++) { - CopyRect(&rect2, &lpitem->rect); - if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { - hMemDC = CreateCompatibleDC(hDC); - if (lpitem->hCheckBit == 0) { - SelectObject(hMemDC, hStdCheck); - GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); - } - else { - SelectObject(hMemDC, lpitem->hCheckBit); - GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); - } - BitBlt(hDC, rect2.left, rect2.top + 1, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - } - else { - if (lpitem->hUnCheckBit != 0) { - hMemDC = CreateCompatibleDC(hDC); - SelectObject(hMemDC, lpitem->hUnCheckBit); - GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); - BitBlt(hDC, rect2.left, rect2.top + 1, + MenuBarCalcSize(hDC, lprect, lppop); + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + hBrush = GetStockObject(WHITE_BRUSH); + CopyRect(&rect, lprect); + FillRect(hDC, &rect, hBrush); + FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); + if (lppop->nItems == 0) goto EndOfPaint; + lpitem = lppop->firstItem; + if (lpitem == NULL) goto EndOfPaint; + for(i = 0; i < lppop->nItems; i++) { + CopyRect(&rect2, &lpitem->rect); + if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { + hMemDC = CreateCompatibleDC(hDC); + if (lpitem->hCheckBit == 0) { + SelectObject(hMemDC, hStdCheck); + GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); + } + else { + SelectObject(hMemDC, lpitem->hCheckBit); + GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); + } + BitBlt(hDC, rect2.left, rect2.top + 1, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); + DeleteDC(hMemDC); + } + else { + if (lpitem->hUnCheckBit != 0) { + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, lpitem->hUnCheckBit); + GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect2.left, rect2.top + 1, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + hMemDC = CreateCompatibleDC(hDC); + SelectObject(hMemDC, hBitMap); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + BitBlt(hDC, rect2.left, rect2.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + OldBkMode = SetBkMode(hDC, TRANSPARENT); + if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) + OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); + else { + if ((lpitem->item_flags & MF_HILITE) == MF_HILITE) + OldTextColor = SetTextColor(hDC, 0x00FFFFFFL); + else + OldTextColor = SetTextColor(hDC, 0x00000000L); + } + if ((lpitem->item_flags & MF_HILITE) == MF_HILITE) + FillRect(hDC, &rect2, GetStockObject(BLACK_BRUSH)); + DrawText(hDC, lpitem->item_text, -1, &rect2, + DT_LEFT | DT_VCENTER | DT_SINGLELINE); + SetTextColor(hDC, OldTextColor); + SetBkMode(hDC, OldBkMode); + SelectObject(hDC, hOldFont); + } + if (lpitem->next == NULL) goto EndOfPaint; + lpitem = (LPMENUITEM)lpitem->next; } - } - if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { - hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); - hMemDC = CreateCompatibleDC(hDC); - SelectObject(hMemDC, hBitMap); - GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); - BitBlt(hDC, rect2.left, rect2.top, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - DeleteDC(hMemDC); - } - if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && - ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); - if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED) - OldTextColor = SetTextColor(hDC, 0x00C0C0C0L); - else - OldTextColor = SetTextColor(hDC, 0x00000000L); - DrawText(hDC, lpitem->item_text, -1, &rect2, - DT_LEFT | DT_VCENTER | DT_SINGLELINE); - SetTextColor(hDC, OldTextColor); - SelectObject(hDC, hOldFont); - } - if (lpitem->next == NULL) goto EndOfPaint; - lpitem = (LPMENUITEM)lpitem->next; - } EndOfPaint: - SelectObject(hDC, hOldFont); + SelectObject(hDC, hOldFont); } LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet) { - LPMENUITEM lpitem; - UINT i; - if (lpRet != NULL) *lpRet = 0; - if (lppop == NULL) return NULL; - if (lppop->nItems == 0) return NULL; - lpitem = lppop->firstItem; - for(i = 0; i < lppop->nItems; i++) { - if (lpitem == NULL) return NULL; + LPMENUITEM lpitem; + UINT i; + if (lpRet != NULL) *lpRet = 0; + if (lppop == NULL) return NULL; + if (lppop->nItems == 0) return NULL; + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) return NULL; #ifdef DEBUG_MENUFINDITEM - printf("FindItem // left=%d top=%d right=%d bottom=%d\n", + printf("FindItem // left=%d top=%d right=%d bottom=%d\n", lpitem->rect.left, lpitem->rect.top, lpitem->rect.right, lpitem->rect.bottom); #endif - if (x > lpitem->rect.left && x < lpitem->rect.right && - y > lpitem->rect.top && y < lpitem->rect.bottom) { - if (lpRet != NULL) *lpRet = i; - return lpitem; - } - lpitem = (LPMENUITEM)lpitem->next; - } - return NULL; + if (x > lpitem->rect.left && x < lpitem->rect.right && + y > lpitem->rect.top && y < lpitem->rect.bottom) { + if (lpRet != NULL) *lpRet = i; + return lpitem; + } + lpitem = (LPMENUITEM)lpitem->next; + } + return NULL; } LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet) { - LPMENUITEM lpitem; - UINT i; - if (lppop == NULL) return NULL; - if (lppop->nItems == 0) return NULL; - lpitem = lppop->firstItem; - for(i = 0; i < lppop->nItems; i++) { - if (lpitem == NULL) return NULL; + LPMENUITEM lpitem; + UINT i; + if (lppop == NULL) return NULL; + if (lppop->nItems == 0) return NULL; + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) return NULL; #ifdef DEBUG_MENUFINDITEM - printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n", - key, lpitem->sel_key); + printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n", + key, lpitem->sel_key); #endif - if (key == lpitem->sel_key) { - if (lpRet != NULL) *lpRet = i; - return lpitem; - } - lpitem = (LPMENUITEM)lpitem->next; - } - return NULL; + if (key == lpitem->sel_key) { + if (lpRet != NULL) *lpRet = i; + return lpitem; + } + lpitem = (LPMENUITEM)lpitem->next; + } + return NULL; } void PopupMenuCalcSize(HWND hwnd) { - WND *wndPtr; - LPPOPUPMENU lppop; - LPMENUITEM lpitem; - HDC hDC; - RECT rect; - HBITMAP hBitMap; - BITMAP bm; - HFONT hOldFont; - UINT i, OldWidth, TempWidth; - DWORD dwRet; + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + HDC hDC; + RECT rect; + HBITMAP hBitMap; + BITMAP bm; + HFONT hOldFont; + UINT i, OldWidth, TempWidth; + DWORD dwRet; #ifdef DEBUG_MENUCALC printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd); #endif - lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); - if (lppop == NULL) return; - if (lppop->nItems == 0) return; - hDC = GetDC(hwnd); - lppop->Width = 20; - lppop->CheckWidth = lppop->PopWidth = 0; - hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return; + if (lppop->nItems == 0) return; + hDC = GetDC(hwnd); + lppop->Width = 20; + lppop->CheckWidth = lppop->PopWidth = 0; + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); CalcAGAIN: - OldWidth = lppop->Width; - SetRect(&rect, 1, 1, OldWidth, 0); - lpitem = lppop->firstItem; - for(i = 0; i < lppop->nItems; i++) { - if (lpitem == NULL) break; + OldWidth = lppop->Width; + SetRect(&rect, 1, 1, OldWidth, 0); + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) break; #ifdef DEBUG_MENUCALC - printf("PopupMenuCalcSize item #%d !\n", i); + printf("PopupMenuCalcSize item #%d !\n", i); #endif - rect.right = rect.left + lppop->Width; - if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { - if (lpitem->hCheckBit != 0) - GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); - else - GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); - lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth); - } - else { - if (lpitem->hUnCheckBit != 0) { - GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); - lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth); + rect.right = rect.left + lppop->Width; + if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { + if (lpitem->hCheckBit != 0) + GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm); + else + GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm); + lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth); + } + else { + if (lpitem->hUnCheckBit != 0) { + GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm); + lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth); + } + } + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); + lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth); + } + if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { + rect.bottom = rect.top + 3; + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + rect.bottom = rect.top + bm.bmHeight; + lppop->Width = max(lppop->Width, bm.bmWidth); + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, + strlen((char *)lpitem->item_text)); + rect.bottom = rect.top + HIWORD(dwRet); + InflateRect(&rect, 0, 2); + TempWidth = LOWORD(dwRet); + if (GetShortCutPos(lpitem->item_text) != (WORD)-1) + TempWidth += 15; + TempWidth += lppop->CheckWidth; + TempWidth += lppop->PopWidth; + lppop->Width = max(lppop->Width, TempWidth); + } + CopyRect(&lpitem->rect, &rect); + rect.top = rect.bottom; + lpitem = (LPMENUITEM)lpitem->next; } - } - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm); - lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth); - } - if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { - rect.bottom = rect.top + 3; - } - if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { - hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); - GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); - rect.bottom = rect.top + bm.bmHeight; - lppop->Width = max(lppop->Width, bm.bmWidth); - } - if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && - ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, - strlen((char *)lpitem->item_text)); - rect.bottom = rect.top + HIWORD(dwRet); - InflateRect(&rect, 0, 2); - TempWidth = LOWORD(dwRet); - if (GetShortCutPos(lpitem->item_text) != (WORD)-1) - TempWidth += 15; - TempWidth += lppop->CheckWidth; - TempWidth += lppop->PopWidth; - lppop->Width = max(lppop->Width, TempWidth); - } - CopyRect(&lpitem->rect, &rect); - rect.top = rect.bottom; - lpitem = (LPMENUITEM)lpitem->next; - } - if (OldWidth < lppop->Width) goto CalcAGAIN; - lppop->Height = rect.bottom; - SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height); + if (OldWidth < lppop->Width) goto CalcAGAIN; + lppop->Height = rect.bottom; + SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height); #ifdef DEBUG_MENUCALC - printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height); + printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height); #endif - SelectObject(hDC, hOldFont); - ReleaseDC(hwnd, hDC); + SelectObject(hDC, hOldFont); + ReleaseDC(hwnd, hDC); } void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop) { - LPMENUITEM lpitem; - RECT rect; - HBITMAP hBitMap; - BITMAP bm; - HFONT hOldFont; - UINT i, OldHeight; - DWORD dwRet; - if (lppop == NULL) return; - if (lppop->nItems == 0) return; + LPMENUITEM lpitem; + RECT rect; + HBITMAP hBitMap; + BITMAP bm; + HFONT hOldFont; + UINT i, OldHeight; + DWORD dwRet; + if (lppop == NULL) return; + if (lppop->nItems == 0) return; #ifdef DEBUG_MENUCALC - printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", - lprect->left, lprect->top, lprect->right, lprect->bottom); + printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", + lprect->left, lprect->top, lprect->right, lprect->bottom); #endif - hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); - lppop->Height = lprect->bottom - lprect->top; + hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + lppop->Height = lprect->bottom - lprect->top; CalcAGAIN: - OldHeight = lppop->Height; - SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + OldHeight); - lpitem = lppop->firstItem; - for(i = 0; i < lppop->nItems; i++) { - if (lpitem == NULL) break; - rect.bottom = lprect->top + lppop->Height; - if (rect.right > lprect->right) - SetRect(&rect, lprect->left, rect.bottom, - 0, rect.bottom + SYSMETRICS_CYMENU); - if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { - hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); - GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); - rect.right = rect.left + bm.bmWidth; - lppop->Height = max(lppop->Height, bm.bmHeight); - } - if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && - ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && - ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { - dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, - strlen((char *)lpitem->item_text)); - rect.right = rect.left + LOWORD(dwRet) + 10; - lppop->Height = max(lppop->Height, HIWORD(dwRet) + 10); - } - CopyRect(&lpitem->rect, &rect); - rect.left = rect.right; - lpitem = (LPMENUITEM)lpitem->next; - } - if (OldHeight < lppop->Height) goto CalcAGAIN; - lppop->Width = rect.right; - lprect->bottom = lprect->top + lppop->Height; - CopyRect(&lppop->rect, lprect); + OldHeight = lppop->Height; + SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + OldHeight); + lpitem = lppop->firstItem; + for(i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) break; + rect.bottom = lprect->top + lppop->Height; + if (rect.right > lprect->right) + SetRect(&rect, lprect->left, rect.bottom, + 0, rect.bottom + SYSMETRICS_CYMENU); + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + rect.right = rect.left + bm.bmWidth; + lppop->Height = max(lppop->Height, bm.bmHeight); + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, + strlen((char *)lpitem->item_text)); + rect.right = rect.left + LOWORD(dwRet) + 10; + dwRet = max(SYSMETRICS_CYMENU, (HIWORD(dwRet) + 6)); + lppop->Height = max(lppop->Height, (WORD)dwRet); + } + CopyRect(&lpitem->rect, &rect); + rect.left = rect.right; + lpitem = (LPMENUITEM)lpitem->next; + } + if (OldHeight < lppop->Height) goto CalcAGAIN; + lppop->Width = rect.right; + lprect->bottom = lprect->top + lppop->Height; + CopyRect(&lppop->rect, lprect); #ifdef DEBUG_MENUCALC - printf("MenuBarCalcSize w=%d h=%d !\n", - lppop->Width, lppop->Height); + printf("MenuBarCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height); #endif - SelectObject(hDC, hOldFont); + SelectObject(hDC, hOldFont); } +/*********************************************************************** + * FindMenuItem + */ +LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags) +{ + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) { + GlobalUnlock(hMenu); + return FALSE; + } + lpitem = menu->firstItem; + if (wFlags & MF_BYPOSITION) { + for (i = 0; i < nPos; i++, lpitem = lpitem->next) + if (lpitem == NULL) return NULL; + } + else { + for (i = 0; i < menu->nItems && lpitem != NULL; i++) { + if (lpitem->item_id == nPos) return lpitem; + lpitem = lpitem->next; + } + return NULL; + } + return lpitem; +} + + LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) { LPMENUITEM lpitem; @@ -984,92 +1096,89 @@ LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) WORD GetSelectionKey(LPSTR str) { - int i; - WORD sel_key; - for (i = 0; i < strlen(str); i++) { - if (str[i] == '&' && str[i + 1] != '&') - { - sel_key = str[i + 1]; - if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A'; + int i; + WORD sel_key; + for (i = 0; i < strlen(str); i++) { + if (str[i] == '&' && str[i + 1] != '&') { + sel_key = str[i + 1]; + if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A'; #ifdef DEBUG_MENU - printf("GetSelectionKey // %04X\n", sel_key); + printf("GetSelectionKey // %04X\n", sel_key); #endif - return sel_key; - } - } + return sel_key; + } + } #ifdef DEBUG_MENU - printf("GetSelectionKey NULL \n"); + printf("GetSelectionKey NULL \n"); #endif - return 0; + return 0; } LPSTR GetShortCutString(LPSTR str) { - int i; - LPSTR str2; - for (i = 0; i < strlen(str); i++) { - if (str[i] == '\t' && str[i + 1] != '\t') - { - str2 = &str[i + 1]; + int i; + LPSTR str2; + for (i = 0; i < strlen(str); i++) { + if (str[i] == '\t' && str[i + 1] != '\t') { + str2 = &str[i + 1]; #ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutString // '%s' \n", str2); + printf("GetShortCutString // '%s' \n", str2); #endif - return str2; - } - } + return str2; + } + } #ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutString NULL \n"); + printf("GetShortCutString NULL \n"); #endif - return NULL; + return NULL; } WORD GetShortCutPos(LPSTR str) { - int i; - for (i = 0; i < strlen(str); i++) { - if (str[i] == '\t' && str[i + 1] != '\t') - { + int i; + for (i = 0; i < strlen(str); i++) { + if (str[i] == '\t' && str[i + 1] != '\t') { #ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutPos = %d \n", i); + printf("GetShortCutPos = %d \n", i); #endif - return i; - } - } + return i; + } + } #ifdef DEBUG_MENUSHORTCUT - printf("GetShortCutString NULL \n"); + printf("GetShortCutString NULL \n"); #endif - return -1; + return -1; } BOOL HideAllSubPopupMenu(LPPOPUPMENU menu) { - LPPOPUPMENU submenu; - LPMENUITEM lpitem; - BOOL someClosed = FALSE; - int i; - if (menu == NULL) return; - lpitem = menu->firstItem; - for (i = 0; i < menu->nItems; i++) { - if (lpitem == NULL) return; - if (lpitem->item_flags & MF_POPUP) { - submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id); - if (submenu != NULL) { - if (IsWindowVisible(submenu->hWnd)) { - ShowWindow(submenu->hWnd, SW_HIDE); - someClosed = TRUE; - } - GlobalUnlock((HMENU)lpitem->item_id); - } - } - lpitem = (LPMENUITEM)lpitem->next; - } - return someClosed; + LPPOPUPMENU submenu; + LPMENUITEM lpitem; + BOOL someClosed = FALSE; + int i; + if (menu == NULL) return; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) return; + if (lpitem->item_flags & MF_POPUP) { + submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id); + if (submenu != NULL) { + if (IsWindowVisible(submenu->hWnd)) { + ShowWindow(submenu->hWnd, SW_HIDE); + someClosed = TRUE; + } + GlobalUnlock((HMENU)lpitem->item_id); + } + } + lpitem = (LPMENUITEM)lpitem->next; + } + return someClosed; } @@ -1081,22 +1190,17 @@ BOOL HideAllSubPopupMenu(LPPOPUPMENU menu) BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, WORD wItemID, WORD wFlags) { - if (wFlags & MF_APPEND) { - return AppendMenu(hMenu, wFlags, wItemID, lpNewItem); - } - if (wFlags & MF_DELETE) { - return DeleteMenu(hMenu, wItemID, wFlags); - } - if (wFlags & MF_INSERT) { - return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); - } - if (wFlags & MF_CHANGE) { - return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); - } - if (wFlags & MF_REMOVE) { - return RemoveMenu(hMenu, wItemID, wFlags); - } - return FALSE; + if (wFlags & MF_APPEND) + return AppendMenu(hMenu, wFlags, wItemID, lpNewItem); + if (wFlags & MF_DELETE) + return DeleteMenu(hMenu, wItemID, wFlags); + if (wFlags & MF_INSERT) + return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); + if (wFlags & MF_CHANGE) + return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); + if (wFlags & MF_REMOVE) + return RemoveMenu(hMenu, wItemID, wFlags); + return FALSE; } @@ -1105,30 +1209,30 @@ BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, */ BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) { - WND *wndPtr; - LPPOPUPMENU menu; - LPMENUITEM lpitem; - int i; + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU - printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); + printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); #endif - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) return FALSE; - lpitem = menu->firstItem; - for (i = 0; i < menu->nItems; i++) { - if (lpitem == NULL) break; - if (i == wItemID) { - if (wFlags && MF_CHECKED) - lpitem->item_flags |= MF_CHECKED; - else - lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED); - GlobalUnlock(hMenu); - return(TRUE); - } - lpitem = (LPMENUITEM)lpitem->next; - } - GlobalUnlock(hMenu); - return FALSE; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == wItemID) { + if (wFlags && MF_CHECKED) + lpitem->item_flags |= MF_CHECKED; + else + lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED); + GlobalUnlock(hMenu); + return(TRUE); + } + lpitem = (LPMENUITEM)lpitem->next; + } + GlobalUnlock(hMenu); + return FALSE; } @@ -1137,30 +1241,30 @@ BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) */ BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) { - WND *wndPtr; - LPPOPUPMENU menu; - LPMENUITEM lpitem; - int i; + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU - printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); + printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags); #endif - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) return FALSE; - lpitem = menu->firstItem; - for (i = 0; i < menu->nItems; i++) { - if (lpitem == NULL) break; - if (i == wItemID) { - if (wFlags && MF_DISABLED) - lpitem->item_flags |= MF_DISABLED; - else - lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED); - GlobalUnlock(hMenu); - return(TRUE); - } - lpitem = (LPMENUITEM)lpitem->next; - } - GlobalUnlock(hMenu); - return FALSE; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == wItemID) { + if (wFlags && MF_DISABLED) + lpitem->item_flags |= MF_DISABLED; + else + lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED); + GlobalUnlock(hMenu); + return(TRUE); + } + lpitem = (LPMENUITEM)lpitem->next; + } + GlobalUnlock(hMenu); + return FALSE; } @@ -1169,61 +1273,56 @@ BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) */ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) { - WND *wndPtr; - LPPOPUPMENU menu; - HANDLE hNewItem; - LPMENUITEM lpitem, lpitem2; - int i; + WND *wndPtr; + LPPOPUPMENU menu; + HANDLE hNewItem; + LPMENUITEM lpitem, lpitem2; + int i; #ifdef DEBUG_MENU - if (wFlags & MF_STRING) - printf("InsertMenu (%04X, %04X, %04X, '%s') !\n", - hMenu, wFlags, wItemID, lpNewItem); - else - printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n", - hMenu, nPos, wFlags, wItemID, lpNewItem); + if (wFlags & MF_STRING) + printf("InsertMenu (%04X, %04X, %04X, '%s') !\n", + hMenu, wFlags, wItemID, lpNewItem); + else + printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n", + hMenu, nPos, wFlags, wItemID, lpNewItem); #endif - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) return FALSE; - lpitem = menu->firstItem; - for (i = 0; i < menu->nItems; i++) { - if (lpitem == NULL) break; - if (i == nPos) break; - lpitem = (LPMENUITEM)lpitem->next; - printf("InsertMenu // during loop items !\n"); - } - printf("InsertMenu // after loop items !\n"); - hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); - if (hNewItem == 0) { + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = FindMenuItem(hMenu, nPos, wFlags); + hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hNewItem == 0) { + GlobalUnlock(hMenu); + return FALSE; + } + lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); + if (lpitem2 == NULL) { + GlobalFree(hNewItem); + GlobalUnlock(hMenu); + return FALSE; + } + lpitem2->item_flags = wFlags; + lpitem2->item_id = wItemID; + if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | + MF_MENUBREAK | MF_SEPARATOR))) { + lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); + strcpy(lpitem2->item_text, lpNewItem); + lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); + } + else { + lpitem2->item_text = lpNewItem; + } + + lpitem2->prev = lpitem; + if (lpitem->next != NULL) + lpitem2->next = lpitem->next; + else + lpitem2->next = NULL; + lpitem->next = lpitem2; + lpitem2->child = NULL; + lpitem2->parent = NULL; + menu->nItems++; GlobalUnlock(hMenu); - return FALSE; - } - lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); - if (lpitem2 == NULL) { - GlobalFree(hNewItem); - GlobalUnlock(hMenu); - return FALSE; - } - lpitem2->item_flags = wFlags; - lpitem2->item_id = wItemID; - if (((wFlags & MF_BITMAP) != MF_BITMAP) && - ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) && - ((wFlags & MF_STRING) != MF_SEPARATOR)) { - lpitem2->item_text = lpNewItem; - lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); - } - else - lpitem2->item_text = lpNewItem; - lpitem2->prev = lpitem; - if (lpitem->next != NULL) - lpitem2->next = lpitem->next; - else - lpitem2->next = NULL; - lpitem->next = lpitem2; - lpitem2->child = NULL; - lpitem2->parent = NULL; - menu->nItems++; - GlobalUnlock(hMenu); - return TRUE; + return TRUE; } @@ -1232,61 +1331,62 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt */ BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) { - WND *wndPtr; - LPPOPUPMENU menu; - HANDLE hNewItem; - LPMENUITEM lpitem, lpitem2; + WND *wndPtr; + LPPOPUPMENU menu; + HANDLE hNewItem; + LPMENUITEM lpitem, lpitem2; #ifdef DEBUG_MENU - if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0) - printf("AppendMenu (%04X, %04X, %04X, '%s') !\n", - hMenu, wFlags, wItemID, lpNewItem); - else - printf("AppendMenu (%04X, %04X, %04X, %08X) !\n", - hMenu, wFlags, wItemID, lpNewItem); + if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0) + printf("AppendMenu (%04X, %04X, %04X, '%s') !\n", + hMenu, wFlags, wItemID, lpNewItem); + else + printf("AppendMenu (%04X, %04X, %04X, %08X) !\n", + hMenu, wFlags, wItemID, lpNewItem); #endif - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) return FALSE; - lpitem = menu->firstItem; - if (lpitem != NULL) { - while (lpitem->next != NULL) { - lpitem = (LPMENUITEM)lpitem->next; - } - } - hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); - if (hNewItem == 0) { + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + if (lpitem != NULL) { + while (lpitem->next != NULL) { + lpitem = (LPMENUITEM)lpitem->next; + } + } + hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hNewItem == 0) { + GlobalUnlock(hMenu); + return FALSE; + } + lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); + if (lpitem2 == NULL) { + GlobalFree(hNewItem); + GlobalUnlock(hMenu); + return FALSE; + } + lpitem2->item_flags = wFlags; + lpitem2->item_id = wItemID; + if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | + MF_MENUBREAK | MF_SEPARATOR))) { + lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); + strcpy(lpitem2->item_text, lpNewItem); + lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); + } + else { + lpitem2->item_text = lpNewItem; + } + + if (lpitem == NULL) + menu->firstItem = lpitem2; + else + lpitem->next = lpitem2; + lpitem2->prev = lpitem; + lpitem2->next = NULL; + lpitem2->child = NULL; + lpitem2->parent = NULL; + lpitem2->hCheckBit = (HBITMAP)NULL; + lpitem2->hUnCheckBit = (HBITMAP)NULL; + menu->nItems++; GlobalUnlock(hMenu); - return FALSE; - } - lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); - if (lpitem2 == NULL) { - GlobalFree(hNewItem); - GlobalUnlock(hMenu); - return FALSE; - } - lpitem2->item_flags = wFlags; - lpitem2->item_id = wItemID; - if (((wFlags & MF_BITMAP) != MF_BITMAP) && - ((wFlags & MF_MENUBREAK) != MF_MENUBREAK) && - ((wFlags & MF_STRING) != MF_SEPARATOR)) { - lpitem2->item_text = lpNewItem; - lpitem2->sel_key = GetSelectionKey(lpitem2->item_text); - lpitem2->shortcut = GetShortCutString(lpitem2->item_text); - } - else - lpitem2->item_text = lpNewItem; - if (lpitem == NULL) - menu->firstItem = lpitem2; - else - lpitem->next = lpitem2; - lpitem2->prev = lpitem; - lpitem2->next = NULL; - lpitem2->child = NULL; - lpitem2->parent = NULL; - lpitem2->hCheckBit = (HBITMAP)NULL; - lpitem2->hUnCheckBit = (HBITMAP)NULL; - menu->nItems++; - GlobalUnlock(hMenu); - return TRUE; + return TRUE; } @@ -1295,31 +1395,36 @@ BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) */ BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) { - WND *wndPtr; - LPPOPUPMENU menu; - LPMENUITEM lpitem; - int i; + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU - printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); + printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); #endif - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) return FALSE; - lpitem = menu->firstItem; - for (i = 0; i < menu->nItems; i++) { - if (lpitem == NULL) break; - if (i == nPos) { - lpitem->prev->next = lpitem->next; - lpitem->next->prev = lpitem->prev; - GlobalFree(HIWORD(lpitem)); - GlobalUnlock(hMenu); - return(TRUE); - } - lpitem = (LPMENUITEM)lpitem->next; - printf("RemoveMenu // during loop items !\n"); - } - printf("RemoveMenu // after loop items !\n"); - GlobalUnlock(hMenu); - return FALSE; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == nPos) { + lpitem->prev->next = lpitem->next; + lpitem->next->prev = lpitem->prev; + if (!(lpitem->item_flags & + (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | + MF_MENUBREAK | MF_SEPARATOR))) { + GlobalFree(lpitem->item_text); + } + GlobalFree(lpitem); + GlobalUnlock(hMenu); + return TRUE; + } + lpitem = (LPMENUITEM)lpitem->next; + printf("RemoveMenu // during loop items !\n"); + } + printf("RemoveMenu // after loop items !\n"); + GlobalUnlock(hMenu); + return FALSE; } @@ -1328,10 +1433,42 @@ BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) */ BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags) { + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); #endif - return TRUE; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) + { + GlobalUnlock(hMenu); + return FALSE; + } + + lpitem = FindMenuItem(hMenu, nPos, wFlags); + if (lpitem != NULL) + { + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) + DestroyMenu((HMENU)lpitem->item_id); + + if (!(lpitem->item_flags & + (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | + MF_MENUBREAK | MF_SEPARATOR))) + { + GlobalFree(lpitem->item_text); + } + if (lpitem->prev) + lpitem->prev->next = lpitem->next; + if (lpitem->next) + lpitem->next->prev = lpitem->prev; + GlobalFree(lpitem); + GlobalUnlock(hMenu); + return TRUE; + } + + GlobalUnlock(hMenu); + return FALSE; } @@ -1356,7 +1493,16 @@ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt if (i == nPos) { lpitem->item_flags = wFlags; lpitem->item_id = wItemID; - lpitem->item_text = lpNewItem; + if (!(lpitem->item_flags & + (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | + MF_MENUBREAK | MF_SEPARATOR))) { + lpitem->item_text = GlobalReAlloc(lpitem->item_text, + strlen(lpNewItem) + 1, + GLOBAL_FLAGS_MOVEABLE); + strcpy(lpitem->item_text, lpNewItem); + } + else + lpitem->item_text = lpNewItem; GlobalUnlock(hMenu); return(TRUE); } @@ -1372,30 +1518,32 @@ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt */ HMENU CreatePopupMenu() { - HANDLE hItem; - HMENU hMenu; - LPPOPUPMENU menu; + HANDLE hItem; + HMENU hMenu; + LPPOPUPMENU menu; #ifdef DEBUG_MENU - printf("CreatePopupMenu !\n"); + printf("CreatePopupMenu !\n"); #endif - hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) { - GlobalFree(hMenu); - return 0; - } - menu->nItems = 0; - menu->firstItem = NULL; - menu->ownerWnd = 0; - menu->hWnd = 0; - menu->hWndParent = 0; - menu->MouseFlags = 0; - menu->BarFlags = 0; - menu->SysFlag = FALSE; - menu->Width = 100; - menu->Height = 0; - GlobalUnlock(hMenu); - return hMenu; + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) { + GlobalFree(hMenu); + return 0; + } + menu->nItems = 0; + menu->firstItem = NULL; + menu->ownerWnd = 0; + menu->hWndPrev = 0; + menu->hWnd = 0; + menu->hWndParent = 0; + menu->MouseFlags = 0; + menu->BarFlag = FALSE; + menu->SysFlag = FALSE; + menu->ChildFlag = TRUE; + menu->Width = 100; + menu->Height = 0; + GlobalUnlock(hMenu); + return hMenu; } @@ -1405,36 +1553,112 @@ HMENU CreatePopupMenu() BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, short nReserved, HWND hWnd, LPRECT lpRect) { - WND *wndPtr; - LPPOPUPMENU lppop; - RECT rect; + WND *wndPtr; + LPPOPUPMENU lppop; + RECT rect; #ifdef DEBUG_MENU - printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", - hMenu, wFlags, x, y, nReserved, hWnd, lpRect); + printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", + hMenu, wFlags, x, y, nReserved, hWnd, lpRect); #endif - lppop = (LPPOPUPMENU) GlobalLock(hMenu); - if (lppop == NULL) return FALSE; + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + if (lppop == NULL) return FALSE; + wndPtr = WIN_FindWndPtr(hWnd); + lppop->ownerWnd = hWnd; + if (lppop->hWnd == (HWND)NULL) { + lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE, + x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, + wndPtr->hInstance, (LPSTR)lppop); + } + else { + ShowWindow(lppop->hWnd, SW_SHOW); + } + if (!lppop->BarFlag) { + PopupMenuCalcSize(lppop->hWnd); +#ifdef DEBUG_MENU + printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", + x, y, lppop->Width, lppop->Height); +#endif + SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, + SWP_NOZORDER); + } + if (!MenuHasFocus) { +#ifdef DEBUG_MENU + printf("TrackPopupMenu // before MenuFocusLoop !\n"); +#endif + MenuFocusLoop(hWnd, NULL); +/* ActivateMenuFocus(hWnd); */ +#ifdef DEBUG_MENU + printf("TrackPopupMenu // after MenuFocusLoop !\n"); +#endif + } + GlobalUnlock(hMenu); + return TRUE; +} + + +BOOL ActivateMenuFocus(HWND hWnd) +{ + WND *wndPtr; + LPPOPUPMENU lpmenu; + BOOL bRet; + MSG msg; + if (MenuHasFocus) return FALSE; wndPtr = WIN_FindWndPtr(hWnd); - lppop->ownerWnd = hWnd; - if (lppop->hWnd == (HWND)NULL) { - lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE, - x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, - wndPtr->hInstance, (LPSTR)lppop); - } - else { - ShowWindow(lppop->hWnd, SW_SHOW); - } - if (lppop->BarFlags == 0) { - PopupMenuCalcSize(lppop->hWnd); + if (wndPtr == NULL) return FALSE; #ifdef DEBUG_MENU - printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", - x, y, lppop->Width, lppop->Height); + printf("ActivateMenuFocus (%04X) !\n", hWnd); #endif - SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, - SWP_NOZORDER); - } - GlobalUnlock(hMenu); - return TRUE; + if ((wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) { + lpmenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu); + MenuItemSelect(hWnd, lpmenu, 0); + bRet = MenuFocusLoop(hWnd, lpmenu); + if (lpmenu != NULL) GlobalUnlock(wndPtr->wIDmenu); + return bRet; + } + return FALSE; +} + + +BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu) +{ + WND *wndPtr; + MSG msg; +#ifdef DEBUG_MENU + printf("Enter in Menu Focus Loop !\n"); +#endif + MenuHasFocus = TRUE; + while(TRUE) { + if (!MenuHasFocus) break; + if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; + TranslateMessage(&msg); + if (hWnd == msg.hwnd && lpmenu != NULL) { + if ((msg.message == WM_SYSKEYDOWN && msg.wParam == VK_MENU) || + (msg.message == WM_CHAR && msg.wParam == VK_ESCAPE)) { + HideAllSubPopupMenu(lpmenu); + break; + } + switch(msg.message) { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MOUSEMOVE: + PopupMenuWndProc(hWnd, msg.message, msg.wParam, msg.lParam); + default: + DispatchMessage(&msg); + } + } + else + DispatchMessage(&msg); + } +EndOfFocus: + MenuHasFocus = FALSE; + if (lpmenu != NULL) MenuItemSelect(hWnd, lpmenu, -1); +#ifdef DEBUG_MENU + printf("End of Menu Focus Loop !\n"); +#endif + return TRUE; } @@ -1443,36 +1667,56 @@ BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, */ void NC_TrackSysMenu(HWND hWnd) { - RECT rect; - LPPOPUPMENU lpsys; - WND *wndPtr = WIN_FindWndPtr(hWnd); + RECT rect; + LPPOPUPMENU lpsys; + WND *wndPtr = WIN_FindWndPtr(hWnd); #ifdef DEBUG_MENU - printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd); + printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd); #endif - if (!wndPtr) return; - lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu); + if (!wndPtr) return; + lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu); #ifdef DEBUG_MENU - printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); + printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); #endif - if (lpsys == NULL) return; + if (lpsys == NULL) return; #ifdef DEBUG_MENU - printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); + printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu); #endif - lpsys->BarFlags = FALSE; - lpsys->SysFlag = TRUE; - if (!IsWindowVisible(lpsys->hWnd)) { - GetWindowRect(hWnd, &rect); + lpsys->BarFlag = FALSE; + lpsys->SysFlag = TRUE; + lpsys->ChildFlag = FALSE; + lpsys->hWndParent = hWnd; + if (!IsWindowVisible(lpsys->hWnd)) { + GetWindowRect(hWnd, &rect); + lpsys->hWndPrev = GetFocus(); #ifdef DEBUG_MENU - printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd); + printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd); #endif - TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, - rect.left, rect.top + SYSMETRICS_CYSIZE, - 0, hWnd, (LPRECT)NULL); - } - else { - ShowWindow(lpsys->hWnd, SW_HIDE); - } - GlobalUnlock(wndPtr->hSysMenu); + if (MenuHasFocus) { + TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, + rect.left, rect.top + SYSMETRICS_CYSIZE, + 0, hWnd, (LPRECT)NULL); + } + else { + MenuHasFocus = TRUE; + TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, + rect.left, rect.top + SYSMETRICS_CYSIZE, + 0, hWnd, (LPRECT)NULL); + MenuHasFocus = FALSE; +#ifdef DEBUG_MENU + printf("NC_TrackSysMenu // before MenuFocusLoop !\n"); +#endif + MenuFocusLoop(hWnd, NULL); +/* ActivateMenuFocus(hWnd); */ +#ifdef DEBUG_MENU + printf("NC_TrackSysMenu // after MenuFocusLoop !\n"); +#endif + } + } + else { + ShowWindow(lpsys->hWnd, SW_HIDE); + } + GlobalUnlock(wndPtr->hSysMenu); } @@ -1495,29 +1739,29 @@ DWORD GetMenuCheckMarkDimensions() BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags, HBITMAP hNewCheck, HBITMAP hNewUnCheck) { - WND *wndPtr; - LPPOPUPMENU menu; - LPMENUITEM lpitem; - int i; + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU - printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n", - hMenu, nPos, wFlags, hNewCheck, hNewUnCheck); + printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n", + hMenu, nPos, wFlags, hNewCheck, hNewUnCheck); #endif - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) return FALSE; - lpitem = menu->firstItem; - for (i = 0; i < menu->nItems; i++) { - if (lpitem == NULL) break; - if (i == nPos) { - lpitem->hCheckBit = hNewCheck; - lpitem->hUnCheckBit = hNewUnCheck; - GlobalUnlock(hMenu); - return TRUE; - } - lpitem = (LPMENUITEM)lpitem->next; - } - GlobalUnlock(hMenu); - return FALSE; + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem == NULL) break; + if (i == nPos) { + lpitem->hCheckBit = hNewCheck; + lpitem->hUnCheckBit = hNewUnCheck; + GlobalUnlock(hMenu); + return TRUE; + } + lpitem = (LPMENUITEM)lpitem->next; + } + GlobalUnlock(hMenu); + return FALSE; } @@ -1526,30 +1770,32 @@ BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags, */ HMENU CreateMenu() { - HANDLE hItem; - HMENU hMenu; - LPPOPUPMENU menu; + HANDLE hItem; + HMENU hMenu; + LPPOPUPMENU menu; #ifdef DEBUG_MENU - printf("CreatePopupMenu !\n"); + printf("CreatePopupMenu !\n"); #endif - hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); - menu = (LPPOPUPMENU) GlobalLock(hMenu); - if (menu == NULL) { - GlobalFree(hMenu); - return 0; - } - menu->nItems = 0; - menu->firstItem = NULL; - menu->ownerWnd = 0; - menu->hWnd = 0; - menu->hWndParent = 0; - menu->MouseFlags = 0; - menu->BarFlags = TRUE; - menu->SysFlag = FALSE; - menu->Width = 100; - menu->Height = 0; - GlobalUnlock(hMenu); - return hMenu; + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) { + GlobalFree(hMenu); + return 0; + } + menu->nItems = 0; + menu->firstItem = NULL; + menu->hWndPrev = 0; + menu->ownerWnd = 0; + menu->hWnd = 0; + menu->hWndParent = 0; + menu->MouseFlags = 0; + menu->BarFlag = TRUE; + menu->SysFlag = FALSE; + menu->ChildFlag = TRUE; + menu->Width = 100; + menu->Height = 0; + GlobalUnlock(hMenu); + return hMenu; } @@ -1558,31 +1804,31 @@ HMENU CreateMenu() */ BOOL DestroyMenu(HMENU hMenu) { - LPPOPUPMENU lppop; - LPMENUITEM lpitem, lpitem2; + LPPOPUPMENU lppop; + LPMENUITEM lpitem, lpitem2; #ifdef DEBUG_MENU - printf("DestroyMenu (%04X) !\n", hMenu); + printf("DestroyMenu (%04X) !\n", hMenu); #endif - if (hMenu == 0) return FALSE; - lppop = (LPPOPUPMENU) GlobalLock(hMenu); - if (lppop == NULL) return FALSE; - if (lppop->hWnd) DestroyWindow (lppop->hWnd); - lpitem = lppop->firstItem; - while (lpitem != NULL) { + if (hMenu == 0) return FALSE; + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + if (lppop == NULL) return FALSE; + if (lppop->hWnd) DestroyWindow (lppop->hWnd); + lpitem = lppop->firstItem; + while (lpitem != NULL) { #ifdef DEBUG_MENU - printf("DestroyMenu (%04X) // during loop items !\n", hMenu); + printf("DestroyMenu (%04X) // during loop items !\n", hMenu); #endif - if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { - DestroyMenu((HMENU)lpitem->item_id); - } - lpitem = (LPMENUITEM)lpitem->next; - } - GlobalUnlock(hMenu); - GlobalFree(hMenu); + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + DestroyMenu((HMENU)lpitem->item_id); + } + lpitem = (LPMENUITEM)lpitem->next; + } + GlobalUnlock(hMenu); + GlobalFree(hMenu); #ifdef DEBUG_MENU - printf("DestroyMenu (%04X) // End !\n", hMenu); + printf("DestroyMenu (%04X) // End !\n", hMenu); #endif - return TRUE; + return TRUE; } @@ -1591,29 +1837,23 @@ BOOL DestroyMenu(HMENU hMenu) */ HMENU LoadMenu(HINSTANCE instance, char *menu_name) { - HMENU hMenu; - HANDLE hMenu_desc; - MENU_HEADER *menu_desc; + HMENU hMenu; + HANDLE hMenu_desc; + MENU_HEADER *menu_desc; #ifdef DEBUG_MENU - if ((LONG)menu_name & 0xFFFF0000L) - printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name); - else - printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name); + if ((LONG)menu_name & 0xFFFF0000L) + printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name); + else + printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name); #endif - if (instance == (HANDLE)NULL) instance = hSysRes; - if (menu_name == NULL || - (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || - (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) { - return 0; - } - hMenu = LoadMenuIndirect((LPSTR)menu_desc); -/* - hMenu = CreateMenu(); - ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu); - GlobalUnlock(hMenu_desc); - GlobalFree(hMenu_desc); -*/ - return hMenu; + if (instance == (HANDLE)NULL) instance = hSysRes; + if (menu_name == NULL || + (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || + (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) { + return 0; + } + hMenu = LoadMenuIndirect((LPSTR)menu_desc); + return hMenu; } @@ -1622,16 +1862,16 @@ HMENU LoadMenu(HINSTANCE instance, char *menu_name) */ HMENU GetSystemMenu(HWND hWnd, BOOL bRevert) { - WND *wndPtr; - wndPtr = WIN_FindWndPtr(hWnd); - if (!bRevert) { + WND *wndPtr; + wndPtr = WIN_FindWndPtr(hWnd); + if (!bRevert) { + return wndPtr->hSysMenu; + } + else { + DestroyMenu(wndPtr->hSysMenu); + wndPtr->hSysMenu = CopySysMenu(); + } return wndPtr->hSysMenu; - } - else { - DestroyMenu(wndPtr->hSysMenu); - wndPtr->hSysMenu = CopySysMenu(); - } - return wndPtr->hSysMenu; } @@ -1640,9 +1880,9 @@ HMENU GetSystemMenu(HWND hWnd, BOOL bRevert) */ HMENU GetMenu(HWND hWnd) { - WND * wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == NULL) return 0; - return wndPtr->wIDmenu; + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return 0; + return wndPtr->wIDmenu; } /********************************************************************** @@ -1650,19 +1890,20 @@ HMENU GetMenu(HWND hWnd) */ BOOL SetMenu(HWND hWnd, HMENU hMenu) { - LPPOPUPMENU lppop; - WND * wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == NULL) return FALSE; + LPPOPUPMENU lppop; + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return FALSE; #ifdef DEBUG_MENU - printf("SetMenu(%04X, %04X);\n", hWnd, hMenu); + printf("SetMenu(%04X, %04X);\n", hWnd, hMenu); #endif - wndPtr->wIDmenu = hMenu; - if (hMenu == 0) return TRUE; - lppop = (LPPOPUPMENU) GlobalLock(hMenu); - if (lppop == NULL) return FALSE; - lppop->ownerWnd = hWnd; - GlobalUnlock(hMenu); - return TRUE; + wndPtr->wIDmenu = hMenu; + if (hMenu == 0) return TRUE; + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + if (lppop == NULL) return FALSE; + lppop->ownerWnd = hWnd; + ResetHiliteFlags(lppop); + GlobalUnlock(hMenu); + return TRUE; } @@ -1671,28 +1912,31 @@ BOOL SetMenu(HWND hWnd, HMENU hMenu) */ HMENU GetSubMenu(HMENU hMenu, short nPos) { - HMENU hSubMenu; - LPPOPUPMENU lppop; - LPMENUITEM lpitem; - int i; + HMENU hSubMenu; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + int i; #ifdef DEBUG_MENU - printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos); + printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos); #endif - if (hMenu == 0) return 0; - lppop = (LPPOPUPMENU) GlobalLock(hMenu); - if (lppop == NULL) return 0; - lpitem = lppop->firstItem; - for (i = 0; i < lppop->nItems; i++) { - if (lpitem == NULL) break; - if (i == nPos) { - if (lpitem->item_flags & MF_POPUP) - return hSubMenu; - else - return 0; - } - lpitem = (LPMENUITEM)lpitem->next; - } - return 0; + if (hMenu == 0) return 0; + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + if (lppop == NULL) return 0; + lpitem = lppop->firstItem; + for (i = 0; i < lppop->nItems; i++) { + if (lpitem == NULL) break; + if (i == nPos) { +#ifdef DEBUG_MENU + printf(" found %04x\n", lpitem->item_id); +#endif + if (lpitem->item_flags & MF_POPUP) + return lpitem->item_id; + else + return 0; + } + lpitem = (LPMENUITEM)lpitem->next; + } + return 0; } @@ -1701,17 +1945,29 @@ HMENU GetSubMenu(HMENU hMenu, short nPos) */ void DrawMenuBar(HWND hWnd) { - WND *wndPtr; + WND *wndPtr; + LPPOPUPMENU lppop; + HDC hDC; #ifdef DEBUG_MENU - printf("DrawMenuBar (%04X)\n", hWnd); + printf("DrawMenuBar (%04X)\n", hWnd); #endif - wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr != NULL && wndPtr->wIDmenu != 0) { + wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr != NULL && (wndPtr->dwStyle & WS_CHILD) == 0 && + wndPtr->wIDmenu != 0) { #ifdef DEBUG_MENU - printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu); + printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu); #endif - SendMessage(hWnd, WM_NCPAINT, 1, 0L); - } + lppop = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu); + if (lppop == NULL) return; + if ((lppop->rect.bottom - lppop->rect.top) != 0) { + hDC = GetWindowDC(hWnd); + StdDrawMenuBar(hDC, &lppop->rect, lppop); + ReleaseDC(hWnd, hDC); + } + else + SendMessage(hWnd, WM_NCPAINT, 1, 0L); + GlobalUnlock(wndPtr->wIDmenu); + } } @@ -1720,15 +1976,19 @@ void DrawMenuBar(HWND hWnd) */ HMENU LoadMenuIndirect(LPSTR menu_template) { - HMENU hMenu; - MENU_HEADER *menu_desc; + HMENU hMenu; + MENU_HEADER *menu_desc; + LPPOPUPMENU lppop; #ifdef DEBUG_MENU - printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template); + printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template); #endif - hMenu = CreateMenu(); - menu_desc = (MENU_HEADER *)menu_template; - ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu); - return hMenu; + hMenu = CreateMenu(); + menu_desc = (MENU_HEADER *)menu_template; + ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu); + lppop = (LPPOPUPMENU) GlobalLock(hMenu); + ResetHiliteFlags(lppop); + GlobalUnlock(hMenu); + return hMenu; } @@ -1737,46 +1997,47 @@ HMENU LoadMenuIndirect(LPSTR menu_template) */ HMENU CopySysMenu() { - HMENU hMenu; - LPPOPUPMENU menu; - LPPOPUPMENU sysmenu; + HMENU hMenu; + LPPOPUPMENU menu; + LPPOPUPMENU sysmenu; #ifdef DEBUG_MENU - printf("CopySysMenu entry !\n"); + printf("CopySysMenu entry !\n"); #endif - if (hSysMenu == 0) { - hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); -/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/ -/* hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); */ if (hSysMenu == 0) { - printf("SysMenu not found in system resources !\n"); - return (HMENU)NULL; - } + hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); +/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/ +/* hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU"); */ + if (hSysMenu == 0) { + printf("SysMenu not found in system resources !\n"); + return (HMENU)NULL; + } #ifdef DEBUG_MENU - else - printf("SysMenu loaded from system resources %04X !\n", hSysMenu); + else + printf("SysMenu loaded from system resources %04X !\n", hSysMenu); #endif - } - hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); - menu = (LPPOPUPMENU) GlobalLock(hMenu); - sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu); - if (menu != NULL && sysmenu != NULL) { - sysmenu->BarFlags = FALSE; - memcpy(menu, sysmenu, sizeof(POPUPMENU)); - } - else { - printf("CopySysMenu // Bad SysMenu pointers !\n"); - if (menu != NULL) { - GlobalUnlock(hMenu); - GlobalFree(hMenu); - } - return (HMENU)NULL; - } - GlobalUnlock(hMenu); - GlobalUnlock(hSysMenu); + } + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); + menu = (LPPOPUPMENU) GlobalLock(hMenu); + sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu); + if (menu != NULL && sysmenu != NULL) { + sysmenu->BarFlag = FALSE; + sysmenu->SysFlag = TRUE; + memcpy(menu, sysmenu, sizeof(POPUPMENU)); + } + else { + printf("CopySysMenu // Bad SysMenu pointers !\n"); + if (menu != NULL) { + GlobalUnlock(hMenu); + GlobalFree(hMenu); + } + return (HMENU)NULL; + } + GlobalUnlock(hMenu); + GlobalUnlock(hSysMenu); #ifdef DEBUG_MENU - printf("CopySysMenu hMenu=%04X !\n", hMenu); + printf("CopySysMenu hMenu=%04X !\n", hMenu); #endif - return hMenu; + return hMenu; } @@ -1806,11 +2067,13 @@ WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) hSubMenu, popup_item->item_text); } else { - MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item; - next_item = (WORD *) (normal_item->item_text + - strlen(normal_item->item_text) + 1); - AppendMenu(hMenu, normal_item->item_flags, - normal_item->item_id, normal_item->item_text); + MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item; + next_item = (WORD *) (normal_item->item_text + + strlen(normal_item->item_text) + 1); + if (strlen(normal_item->item_text) == 0 && normal_item->item_id == 0) + normal_item->item_flags |= MF_SEPARATOR; + AppendMenu(hMenu, normal_item->item_flags, + normal_item->item_id, normal_item->item_text); } } while (!(*item & MF_END)); diff --git a/controls/scroll.c b/controls/scroll.c index 2894b211cc2..1d05ee37e33 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -10,14 +10,16 @@ */ static char Copyright[] = "Copyright Martin Ayotte, 1993"; +#include +#include +#include +#include #include "windows.h" #include "sysmetrics.h" #include "scroll.h" #include "heap.h" #include "win.h" -#include -#include -#include +#include "prototypes.h" HBITMAP hUpArrow = 0; HBITMAP hDnArrow = 0; @@ -142,174 +144,212 @@ return(0); void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y) { - LPHEADSCROLL lphs; - HWND hWndParent; - RECT rect, rect2; - int width, height; - LONG dwOwner; - lphs = GetScrollObjectStruct(hWnd, nBar); + LPHEADSCROLL lphs; + HWND hWndParent; + RECT rect, rect2; + int width, height; + LONG dwOwner; + lphs = GetScrollObjectStruct(hWnd, nBar); + if (nBar == SB_CTL) { + hWndParent = GetParent(hWnd); + dwOwner = MAKELONG(0, lphs->hWndOwner); #ifdef DEBUG_SCROLL - printf("ScrollBarButtonDown // x=%d y=%d\n", x, y); + printf("ScrollBarButtonDown SB_CTL // x=%d y=%d\n", x, y); #endif - if (nBar == SB_CTL) { - hWndParent = GetParent(hWnd); - dwOwner = MAKELONG(0, lphs->hWndOwner); - } - else { - hWndParent = hWnd; - dwOwner = 0L; - } + } + else { + hWndParent = hWnd; + dwOwner = 0L; +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown SB_?SCROLL // x=%d y=%d\n", x, y); +#endif + } /* - SetFocus(lphs->hWndOwner); + SetFocus(lphs->hWndOwner); */ - CopyRect(&rect, &lphs->rect); + CopyRect(&rect, &lphs->rect); #ifdef DEBUG_SCROLL - printf("ScrollDown / x=%d y=%d left=%d top=%d right=%d bottom=%d \n", - x, y, rect.left, rect.top, rect.right, rect.bottom); + printf("ScrollDown / x=%d y=%d left=%d top=%d right=%d bottom=%d \n", + x, y, rect.left, rect.top, rect.right, rect.bottom); #endif - if (lphs->Direction == WM_VSCROLL) { - width = rect.right - rect.left; - if (y < (lphs->CurPix + width)) { - if (y < width) { - lphs->ButtonDown = 1; - CopyRect(&rect2, &rect); - rect2.bottom = rect2.top + width; - InvalidateRect(lphs->hWndOwner, &rect2, TRUE); - SendMessage(hWndParent, lphs->Direction, - SB_LINEUP, dwOwner); - } - else { - lphs->ButtonDown = 5; - SendMessage(hWndParent, lphs->Direction, - SB_PAGEUP, dwOwner); - } - } - if (y > (lphs->CurPix + (width << 1))) { - if (y > (rect.bottom - rect.top - width)) { - lphs->ButtonDown = 2; - CopyRect(&rect2, &rect); - rect2.top = rect2.bottom - width; - InvalidateRect(lphs->hWndOwner, &rect2, TRUE); - SendMessage(hWndParent, lphs->Direction, - SB_LINEDOWN, dwOwner); - } - else { - lphs->ButtonDown = 6; - SendMessage(hWndParent, lphs->Direction, - SB_PAGEDOWN, dwOwner); - } - } - if ((y > (lphs->CurPix + width)) && - (y < (lphs->CurPix + (width << 1)))) { - lphs->ThumbActive = TRUE; + if (lphs->Direction == WM_VSCROLL) { + width = rect.right - rect.left; + if (y < (lphs->CurPix + width)) { + if (y < width) { + lphs->ButtonDown = 1; + CopyRect(&rect2, &rect); + rect2.bottom = rect2.top + width; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); #ifdef DEBUG_SCROLL - printf("THUMB DOWN !\n"); + printf("ScrollBarButtonDown send SB_LINEUP\n"); #endif - } - } - else { - height = rect.bottom - rect.top; - if (x < (lphs->CurPix + height)) { - if (x < height) { - lphs->ButtonDown = 3; - CopyRect(&rect2, &rect); - rect2.right = rect2.left + height; - InvalidateRect(lphs->hWndOwner, &rect2, TRUE); - SendMessage(hWndParent, lphs->Direction, - SB_LINEUP, dwOwner); - } - else { - lphs->ButtonDown = 5; - SendMessage(hWndParent, lphs->Direction, - SB_PAGEUP, dwOwner); - } - } - if (x > (lphs->CurPix + (height << 1))) { - if (x > (rect.right - rect.left - height)) { - lphs->ButtonDown = 4; - CopyRect(&rect2, &rect); - rect2.left = rect2.right - height; - InvalidateRect(lphs->hWndOwner, &rect2, TRUE); - SendMessage(hWndParent, lphs->Direction, - SB_LINEDOWN, dwOwner); - } - else { - lphs->ButtonDown = 6; - SendMessage(hWndParent, lphs->Direction, - SB_PAGEDOWN, dwOwner); - } - } - if ((x > (lphs->CurPix + height)) && - (x < (lphs->CurPix + (height << 1)))) { - lphs->ThumbActive = TRUE; + SendMessage(hWndParent, lphs->Direction, + SB_LINEUP, dwOwner); + } + else { + lphs->ButtonDown = 5; #ifdef DEBUG_SCROLL - printf("THUMB DOWN !\n"); + printf("ScrollBarButtonDown send SB_PAGEUP\n"); #endif - } - } - if (lphs->ButtonDown != 0) { - UpdateWindow(lphs->hWndOwner); - if (!lphs->TimerPending && nBar == SB_CTL) { - lphs->TimerPending = TRUE; - SetTimer(lphs->hWndOwner, 1, 500, NULL); - } - } + SendMessage(hWndParent, lphs->Direction, + SB_PAGEUP, dwOwner); + } + } + if (y > (lphs->CurPix + (width << 1))) { + if (y > (rect.bottom - rect.top - width)) { + lphs->ButtonDown = 2; + CopyRect(&rect2, &rect); + rect2.top = rect2.bottom - width; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown send SB_LINEDOWN\n"); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_LINEDOWN, dwOwner); + } + else { + lphs->ButtonDown = 6; +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown send SB_PAGEDOWN\n"); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_PAGEDOWN, dwOwner); + } + } + if ((y > (lphs->CurPix + width)) && + (y < (lphs->CurPix + (width << 1)))) { + lphs->ThumbActive = TRUE; +#ifdef DEBUG_SCROLL + printf("THUMB DOWN !\n"); +#endif + } + } + else { + height = rect.bottom - rect.top; + if (x < (lphs->CurPix + height)) { + if (x < height) { + lphs->ButtonDown = 3; + CopyRect(&rect2, &rect); + rect2.right = rect2.left + height; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown send SB_LINEUP\n"); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_LINEUP, dwOwner); + } + else { + lphs->ButtonDown = 5; +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown send SB_PAGEUP\n"); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_PAGEUP, dwOwner); + } + } + if (x > (lphs->CurPix + (height << 1))) { + if (x > (rect.right - rect.left - height)) { + lphs->ButtonDown = 4; + CopyRect(&rect2, &rect); + rect2.left = rect2.right - height; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown send SB_LINEDOWN\n"); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_LINEDOWN, dwOwner); + } + else { + lphs->ButtonDown = 6; +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown send SB_PAGEDOWN\n"); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_PAGEDOWN, dwOwner); + } + } + if ((x > (lphs->CurPix + height)) && + (x < (lphs->CurPix + (height << 1)))) { + lphs->ThumbActive = TRUE; +#ifdef DEBUG_SCROLL + printf("THUMB DOWN !\n"); +#endif + } + } + if (lphs->ButtonDown != 0) { + UpdateWindow(lphs->hWndOwner); + if (!lphs->TimerPending && nBar == SB_CTL) { + lphs->TimerPending = TRUE; + SetTimer(lphs->hWndOwner, 1, 500, NULL); + } + } } void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y) { - LPHEADSCROLL lphs; - RECT rect, rect2; + LPHEADSCROLL lphs; + RECT rect, rect2; + HDC hDC; #ifdef DEBUG_SCROLL - printf("ScrollBarButtonUp // x=%d y=%d\n", x, y); + printf("ScrollBarButtonUp // x=%d y=%d\n", x, y); #endif - lphs = GetScrollObjectStruct(hWnd, nBar); - lphs->ThumbActive = FALSE; - if (lphs->ButtonDown != 0) { - lphs->ButtonDown = 0; - GetClientRect(lphs->hWndOwner, &rect); - InvalidateRect(lphs->hWndOwner, &rect, TRUE); - UpdateWindow(lphs->hWndOwner); - } + lphs = GetScrollObjectStruct(hWnd, nBar); + lphs->ThumbActive = FALSE; + if (lphs->ButtonDown != 0) { + lphs->ButtonDown = 0; + GetClientRect(lphs->hWndOwner, &rect); + if (nBar == SB_CTL) { + InvalidateRect(lphs->hWndOwner, &rect, TRUE); + UpdateWindow(lphs->hWndOwner); + } + else { + hDC = GetWindowDC(lphs->hWndOwner); + StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs); + ReleaseDC(lphs->hWndOwner, hDC); + } + } } void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y) { - LPHEADSCROLL lphs; - HWND hWndParent; - HWND hWndOwner; - LONG dwOwner; - if ((wParam & MK_LBUTTON) == 0) return; + LPHEADSCROLL lphs; + HWND hWndParent; + HWND hWndOwner; + LONG dwOwner; + if ((wParam & MK_LBUTTON) == 0) return; + lphs = GetScrollObjectStruct(hWnd, nBar); + if (lphs->ThumbActive == 0) return; + if (nBar == SB_CTL) { + hWndParent = GetParent(hWnd); + hWndOwner = lphs->hWndOwner; #ifdef DEBUG_SCROLL - printf("ScrollBarButtonMove // w=%04X x=%d y=%d \n", wParam, x, y); + printf("ScrollBarButtonMove SB_CTL // x=%d y=%d\n", x, y); #endif - lphs = GetScrollObjectStruct(hWnd, nBar); - if (lphs->ThumbActive == 0) return; - if (nBar == SB_CTL) { - hWndParent = GetParent(hWnd); - hWndOwner = lphs->hWndOwner; - } - else { - hWndParent = hWnd; - hWndOwner = 0; - } - if (lphs->Direction == WM_VSCROLL) { - int butsiz = lphs->rect.right - lphs->rect.left; - y = y - butsiz - (butsiz >> 1); - } - else { - int butsiz = lphs->rect.bottom - lphs->rect.top; - y = x - butsiz - (butsiz >> 1); - } - x = (y * (lphs->MaxVal - lphs->MinVal) / - lphs->MaxPix) + lphs->MinVal; + } + else { + hWndParent = hWnd; + hWndOwner = 0; #ifdef DEBUG_SCROLL - printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y); + printf("ScrollBarButtonMove SB_?SCROLL // x=%d y=%d\n", x, y); #endif - SendMessage(hWndParent, lphs->Direction, - SB_THUMBTRACK, MAKELONG(x, hWndOwner)); + } + if (lphs->Direction == WM_VSCROLL) { + int butsiz = lphs->rect.right - lphs->rect.left; + y = y - butsiz - (butsiz >> 1); + } + else { + int butsiz = lphs->rect.bottom - lphs->rect.top; + y = x - butsiz - (butsiz >> 1); + } + x = (y * (lphs->MaxVal - lphs->MinVal) / + lphs->MaxPix) + lphs->MinVal; +#ifdef DEBUG_SCROLL + printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_THUMBTRACK, MAKELONG(x, hWndOwner)); } @@ -341,6 +381,7 @@ LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd) } + void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs) { HWND hWndParent; @@ -385,19 +426,15 @@ void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL SelectObject(hMemDC, hUpArrowD); else SelectObject(hMemDC, hUpArrow); - BitBlt(hDC, rect.left, rect.top, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); -/* - StretchBlt(hDC, 0, 0, lpdis->rcItem.right, lpdis->rcItem.right, - hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); -*/ + StretchBlt(hDC, rect.left, rect.top, w, w, hMemDC, + 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm); if (lphs->ButtonDown == 2) SelectObject(hMemDC, hDnArrowD); else SelectObject(hMemDC, hDnArrow); - BitBlt(hDC, rect.left, rect.bottom - bm.bmHeight, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + StretchBlt(hDC, rect.left, rect.bottom - w, w, w, hMemDC, + 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); rect.top += w; rect.bottom -= w; } @@ -407,15 +444,15 @@ void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL SelectObject(hMemDC, hLfArrowD); else SelectObject(hMemDC, hLfArrow); - BitBlt(hDC, rect.left, rect.top, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + StretchBlt(hDC, rect.left, rect.top, h, h, hMemDC, + 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm); if (lphs->ButtonDown == 4) SelectObject(hMemDC, hRgArrowD); else SelectObject(hMemDC, hRgArrow); - BitBlt(hDC, rect.right - bm.bmWidth, rect.top, - bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + StretchBlt(hDC, rect.right - h, rect.top, h, h, hMemDC, + 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); rect.left += h; rect.right -= h; } @@ -549,7 +586,6 @@ void NC_CreateScrollBars(HWND hWnd) LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar) { WND *wndPtr; - LPHEADSCROLL lphs; if (nBar != SB_CTL) { wndPtr = WIN_FindWndPtr(hWnd); if (nBar == SB_VERT) return (LPHEADSCROLL)wndPtr->VScroll; @@ -565,13 +601,14 @@ LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar) */ int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw) { - int nRet; - LPHEADSCROLL lphs; - lphs = GetScrollObjectStruct(hWnd, nBar); - if (lphs == NULL) return 0; - nRet = lphs->CurVal; - lphs->CurVal = (short)nPos; - if (lphs->MaxVal != lphs->MinVal) + LPHEADSCROLL lphs; + HDC hDC; + int nRet; + lphs = GetScrollObjectStruct(hWnd, nBar); + if (lphs == NULL) return 0; + nRet = lphs->CurVal; + lphs->CurVal = (short)nPos; + if (lphs->MaxVal != lphs->MinVal) lphs->CurPix = lphs->MaxPix * (abs((short)nPos) - abs(lphs->MinVal)) / (abs(lphs->MaxVal) - abs(lphs->MinVal)); if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix; @@ -582,8 +619,17 @@ int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw) lphs->MinVal, lphs->MaxVal); #endif if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) { - InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE); - UpdateWindow(lphs->hWndOwner); + if (nBar == SB_CTL) { + InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE); + UpdateWindow(lphs->hWndOwner); + } + else { + if (lphs->rect.right != 0 && lphs->rect.bottom != 0) { + hDC = GetWindowDC(lphs->hWndOwner); + StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs); + ReleaseDC(lphs->hWndOwner, hDC); + } + } } return nRet; } @@ -609,6 +655,7 @@ int GetScrollPos(HWND hWnd, int nBar) void SetScrollRange(HWND hWnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) { LPHEADSCROLL lphs; + HDC hDC; lphs = GetScrollObjectStruct(hWnd, nBar); if (lphs == NULL) return; lphs->MinVal = (short)MinPos; @@ -622,8 +669,17 @@ void SetScrollRange(HWND hWnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal); #endif if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) { - InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE); - UpdateWindow(lphs->hWndOwner); + if (nBar == SB_CTL) { + InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE); + UpdateWindow(lphs->hWndOwner); + } + else { + if (lphs->rect.right != 0 && lphs->rect.bottom != 0) { + hDC = GetWindowDC(lphs->hWndOwner); + StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs); + ReleaseDC(lphs->hWndOwner, hDC); + } + } } } diff --git a/controls/static.c b/controls/static.c index 655d2fed52e..a78fd770412 100644 --- a/controls/static.c +++ b/controls/static.c @@ -7,6 +7,7 @@ static char Copyright[] = "Copyright David W. Metcalfe, 1993"; +#include #include #include "win.h" #include "user.h" diff --git a/controls/widgets.c b/controls/widgets.c index 1ad506d8012..c56daba5363 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -7,7 +7,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "win.h" - +#include "desktop.h" +#include "mdi.h" +#include "gdi.h" LONG ButtonWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG StaticWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); @@ -16,6 +18,7 @@ LONG ListBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG DesktopWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG MDIClientWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); static WNDCLASS WIDGETS_BuiltinClasses[] = @@ -32,10 +35,12 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = 0, 0, 0, 0, NULL, "COMBOBOX" }, { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8, 0, 0, 0, 0, NULL, "POPUPMENU" }, - { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, 0, + { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO), 0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME }, { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, - 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } + 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME }, + { CS_GLOBALCLASS, (LONG(*)())MDIClientWndProc, 0, sizeof(MDICLIENTINFO), + 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" } }; #define NB_BUILTIN_CLASSES \ @@ -47,7 +52,7 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = * * Initialize the built-in window classes. */ -BOOL WIDGETS_Init() +BOOL WIDGETS_Init(void) { int i; for (i = 0; i < NB_BUILTIN_CLASSES; i++) diff --git a/if1632/Imakefile b/if1632/Imakefile index 6803aaaa42b..deee54f928a 100644 --- a/if1632/Imakefile +++ b/if1632/Imakefile @@ -8,15 +8,25 @@ SRCS = \ callback.c \ relay.c -/* - * Hack alert. There appear to be no object files, 'cause a very - * nasty rule below links *.o together, which is a generally bad idea, - * but I can't see how else to do it. - */ -OBJS = \ - call.o \ - callback.o \ - relay.o +DLLOBJS = \ + dll_gdi.o \ + dll_kernel.o \ + dll_keyboard.o \ + dll_shell.o \ + dll_sound.o \ + dll_stress.o \ + dll_unixlib.o \ + dll_user.o \ + dll_win87em.o \ + dll_winsock.o + +OBJS1= $(SRCS:.S=.o) + +#ifndef NewBuild +OBJS = $(DLLOBJS) $(OBJS1:.c=.o) $(DLLOBJS:.o=_tab.o) +#else +OBJS = $(DLLOBJS) $(OBJS1:.c=.o) $(DLLOBJS:.o=_tab.o) $(DLLOBJS:dll_.rly_) +#endif /* * If you add a new spec file, copy one of these lines @@ -26,21 +36,19 @@ MakeDllFromSpec(kernel,$(TOP)/$(MODULE)) MakeDllFromSpec(keyboard,$(TOP)/$(MODULE)) MakeDllFromSpec(shell,$(TOP)/$(MODULE)) MakeDllFromSpec(sound,$(TOP)/$(MODULE)) +MakeDllFromSpec(stress,$(TOP)/$(MODULE)) MakeDllFromSpec(unixlib,$(TOP)/$(MODULE)) MakeDllFromSpec(user,$(TOP)/$(MODULE)) MakeDllFromSpec(win87em,$(TOP)/$(MODULE)) MakeDllFromSpec(winsock,$(TOP)/$(MODULE)) -/* - * Yes I know *.o is not very clever, but can you do it cleaner ? - */ -WineRelocatableTarget($(TOP)/$(MODULE),*.o,) +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() -$(TOP)/$(MODULE).o: $(OBJS) +includes:: + +install:: clean:: $(RM) dll* dtb* - -depend:: - -includes:: diff --git a/if1632/call.S b/if1632/call.S index 5b49777aa8e..420d7bbd91e 100644 --- a/if1632/call.S +++ b/if1632/call.S @@ -105,7 +105,7 @@ _CallToInit16: movw $UDATASEL,%ax movw %ax,%fs movw %ax,%gs - movw %ds,%ax +/* movw %ds,%ax */ /* * Call entry point diff --git a/if1632/gdi.spec b/if1632/gdi.spec index 144e0dfeb03..b1a46fbbdbd 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -126,6 +126,8 @@ length 490 148 pascal SetBrushOrg(word s_word s_word) SetBrushOrg(1 2 3) 149 pascal GetBrushOrg(word) GetBrushOrg(1) 150 pascal UnrealizeObject(word) UnrealizeObject(1) +153 pascal CreateIC(ptr ptr ptr ptr) CreateIC(1 2 3 4) +154 pascal GetNearestColor(word long) GetNearestColor(1 2) 161 pascal PtInRegion(word s_word s_word) PtInRegion(1 2 3) 162 pascal GetBitmapDimension(word) GetBitmapDimension(1) 163 pascal SetBitmapDimension(word s_word s_word) SetBitmapDimension(1 2 3) @@ -134,6 +136,7 @@ length 490 179 pascal GetDCState(word) GetDCState(1) 180 pascal SetDCState(word word) SetDCState(1 2) 181 pascal RectInRegionOld(word ptr) RectInRegion(1 2) +250 pascal Copy(ptr ptr word) Copy(1 2 3) 345 pascal GetTextAlign(word) GetTextAlign(1) 346 pascal SetTextAlign(word word) SetTextAlign(1 2) 348 pascal Chord(word s_word s_word s_word s_word s_word s_word s_word s_word) @@ -141,14 +144,21 @@ length 490 349 pascal SetMapperFlags(word word) SetMapperFlags(1 2) 350 pascal GetCharWidth(word word word ptr) GetCharWidth(1 2 3 4) 360 pascal CreatePalette(ptr) CreatePalette(1) +361 pascal GDISelectPalette(word word) GDISelectPalette(1 2) +362 pascal GDIRealizePalette(word) GDIRealizePalette(1) 363 pascal GetPaletteEntries(word word word ptr) GetPaletteEntries(1 2 3 4) 364 pascal SetPaletteEntries(word word word ptr) SetPaletteEntries(1 2 3 4) +365 pascal RealizeDefaultPalette(word) RealizeDefaultPalette(1) 370 pascal GetNearestPaletteIndex(word long) GetNearestPaletteIndex(1 2) +375 pascal GetSystemPaletteEntries(word word word ptr) + GetSystemPaletteEntries(1 2 3 4) 411 pascal GetCurLogFont(word) GetCurLogFont(1) 440 pascal SetDIBits(word word word word ptr ptr word) SetDIBits(1 2 3 4 5 6 7) 441 pascal GetDIBits(word word word word ptr ptr word) GetDIBits(1 2 3 4 5 6 7) 442 pascal CreateDIBitmap(word ptr long ptr ptr word) CreateDIBitmap(1 2 3 4 5 6) +443 pascal SetDIBitsToDevice(word s_word s_word word word word word word word ptr ptr word) + SetDIBitsToDevice(1 2 3 4 5 6 7 8 9 10 11 12) 444 pascal CreateRoundRectRgn(s_word s_word s_word s_word s_word s_word) CreateRoundRectRgn(1 2 3 4 5 6) 445 pascal CreateDIBPatternBrush(word word) CreateDIBPatternBrush(1 2) diff --git a/if1632/kernel.spec b/if1632/kernel.spec index a3f9dd2ada7..44722896358 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -6,16 +6,16 @@ length 415 3 pascal GetVersion() GetVersion() #return GetVersion 0 0x301 -4 pascal LocalInit(word word word) LocalInit(1 2 3) -5 pascal LocalAlloc(word word) LocalAlloc(1 2) -6 pascal LocalReAlloc(word word word) LocalReAlloc(1 2 3) -7 pascal LocalFree(word) LocalFree(1) -8 pascal LocalLock(word) LocalLock(1) -9 pascal LocalUnlock(word) LocalUnlock(1) -10 pascal LocalSize(word) LocalSize(1) +4 pascal LocalInit(word word word) WIN16_LocalInit(1 2 3) +5 pascal LocalAlloc(word word) WIN16_LocalAlloc(1 2) +6 pascal LocalReAlloc(word word word) WIN16_LocalReAlloc(1 2 3) +7 pascal LocalFree(word) WIN16_LocalFree(1) +8 pascal LocalLock(word) WIN16_LocalLock(1) +9 pascal LocalUnlock(word) WIN16_LocalUnlock(1) +10 pascal LocalSize(word) WIN16_LocalSize(1) 11 pascal LocalHandle(word) ReturnArg(1) -12 pascal LocalFlags(word) LocalFlags(1) -13 pascal LocalCompact(word) LocalCompact(1) +12 pascal LocalFlags(word) WIN16_LocalFlags(1) +13 pascal LocalCompact(word) WIN16_LocalCompact(1) 14 return LocalNotify 4 0 15 pascal GlobalAlloc(word long) GlobalAlloc(1 2) 16 pascal GlobalReAlloc(word long word) GlobalReAlloc(1 2 3) @@ -89,6 +89,7 @@ length 415 163 pascal GlobalLRUOldest(word) ReturnArg(1) 164 pascal GlobalLRUNewest(word) ReturnArg(1) 166 pascal WinExec(ptr word) WinExec(1 2) +169 pascal GetFreeSpace(word) GetFreeSpace(1) 170 pascal AllocCStoDSAlias(word) AllocDStoCSAlias(1) 171 pascal AllocDStoCSAlias(word) AllocDStoCSAlias(1) 175 pascal AllocSelector(word) AllocSelector(1) diff --git a/if1632/relay.c b/if1632/relay.c index 92d5622a061..21898550b24 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -3,6 +3,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include +#include #include #include #include @@ -14,6 +15,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #endif #include + #include "neexe.h" #include "segmem.h" #include "prototypes.h" @@ -22,7 +24,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #define DEBUG_RELAY /* */ -#define N_BUILTINS 9 +#define N_BUILTINS 10 struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] = { @@ -35,6 +37,7 @@ struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] = { "SOUND", SOUND_table, 20, 7 }, { "KEYBOARD",KEYBOARD_table,137, 8 }, { "WINSOCK", WINSOCK_table, 155, 9 }, + { "STRESS", STRESS_table, 15,10 }, }; unsigned short *Stack16Frame; @@ -65,6 +68,7 @@ int DLLRelay(unsigned int func_num, unsigned int seg_off) { struct dll_table_entry_s *dll_p; + unsigned short *saved_Stack16Frame; unsigned int segment; unsigned int offset; unsigned int dll_id; @@ -78,6 +82,7 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) /* * Determine address of arguments. */ + saved_Stack16Frame = Stack16Frame; Stack16Frame = (unsigned short *) seg_off; arg_ptr = (void *) (seg_off + 0x18); @@ -138,7 +143,11 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) * if we choose. */ if (dll_p->n_args == 0) - return (*func_ptr)(arg_ptr); + { + ret_val = (*func_ptr)(arg_ptr); + Stack16Frame = saved_Stack16Frame; + return ret_val; + } /* * Getting this far means we need to convert the 16-bit argument stack. @@ -197,6 +206,7 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) } #endif + Stack16Frame = saved_Stack16Frame; return ret_val; } diff --git a/if1632/stress.spec b/if1632/stress.spec new file mode 100644 index 00000000000..8c93cb7f4f3 --- /dev/null +++ b/if1632/stress.spec @@ -0,0 +1,18 @@ +# summary: resource modification dll +# +name stress +id 10 +length 15 + +2 pascal allocmem(long) AllocMem(1) +3 pascal freeallmem() FreeAllMem() +6 pascal allocfilehandles(word) AllocFileHandles(1) +7 pascal unallocfilehandles() UnAllocFileHandles() +8 pascal getfreefilehandles() GetFreeFileHandles() +10 pascal allocdiskspace(long word) AllocDiskSpace(1 2) +11 pascal unallocdiskspace(word) UnAllocDiskSpace(1) +12 pascal allocusermem(word) AllocUserMem(1) +13 pascal freeallusermem() FreeAllUserMem() +14 pascal allocgdimem(word) AllocGDIMem(1) +15 pascal freeallgdimem() FreeAllGDIMem() + diff --git a/if1632/user.spec b/if1632/user.spec index d6f213a3de4..d79948c5999 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -152,7 +152,7 @@ length 540 167 pascal ShowCaret(word) ShowCaret(1) 168 pascal SetCaretBlinkTime(word) SetCaretBlinkTime(1) 169 pascal GetCaretBlinkTime() GetCaretBlinkTime() -171 pascal WinHelp(word word long) WinHelp(1 2 3) +171 pascal WinHelp(word ptr word long) WinHelp(1 2 3 4) 173 pascal LoadCursor(word ptr) LoadCursor(1 2) 174 pascal LoadIcon(word ptr) LoadIcon(1 2) 175 pascal LoadBitmap(word ptr) LoadBitmap(1 2) @@ -215,6 +215,7 @@ length 540 277 pascal GetDlgCtrlID(word) GetDlgCtrlID(1) 282 pascal SelectPalette(word word word) SelectPalette(1 2 3) 283 pascal RealizePalette(word) RealizePalette(1) +284 pascal GetFreeSystemResources(word) GetFreeSystemResources(1) 286 pascal GetDesktopWindow() GetDesktopWindow() 288 pascal GetMessageExtraInfo() GetMessageExtraInfo() 290 pascal RedrawWindow(word ptr word word) RedrawWindow(1 2 3 4) @@ -235,6 +236,8 @@ length 540 404 pascal GetClassInfo(word ptr ptr) GetClassInfo(1 2 3) 406 pascal CreateCursor(word word word word word ptr ptr) CreateCursor(1 2 3 4 5 6 7) +407 pascal CreateIcon(word word word byte byte ptr ptr) + CreateIcon(1 2 3 4 5 6 7) 410 pascal InsertMenu(word word word word ptr) InsertMenu(1 2 3 4 5) 411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4) 412 pascal RemoveMenu(word word word) RemoveMenu(1 2 3) @@ -257,6 +260,9 @@ length 540 436 pascal IsCharLower(byte) IsCharLower(1) 437 pascal AnsiUpperBuff(ptr word) AnsiUpperBuff(1 2) 438 pascal AnsiLowerBuff(ptr word) AnsiLowerBuff(1 2) +445 pascal DefFrameProc(word word word word long) DefFrameProc(1 2 3 4 5) +447 pascal DefMDIChildProc(word word word long) DefMDIChildProc(1 2 3 4) +451 pascal TranslateMDISysAccel(word ptr) TranslateMDISysAccel(1 2) 452 pascal CreateWindowEx(long ptr ptr long s_word s_word s_word s_word word word word ptr) CreateWindowEx(1 2 3 4 5 6 7 8 9 10 11 12) diff --git a/include/arch.h b/include/arch.h index 50e8255be73..c929a3e5add 100644 --- a/include/arch.h +++ b/include/arch.h @@ -5,13 +5,20 @@ */ #if defined (mc68000) || defined (sparc) -#define CONV_LONG(a) (((a)&0xFF) << 24) | (((a) & 0xFF00) << 8) | (((a) & 0xFF0000) >> 8) | ((a)&0xFF000000 >> 24) -#define CONV_SHORT(a) (((a) & 0xFF) << 8) | (((a) & 0xFF00) >> 8) -#define CONV_CHAR_TO_LONG(x) ((x) >> 24) -#define CONV_SHORT_TO_LONG(x) ((x) >> 16) + +#define CONV_LONG(a) (((a)&0xFF) << 24) | (((a) & 0xFF00) << 8) | (((unsigned long)(a) & 0xFF0000) >> 8) | ((unsigned long)((a)&0xFF000000) >> 24) +#define CONV_SHORT(a) (((a) & 0xFF) << 8) | (((unsigned long)(a) & 0xFF00) >> 8) +#define CONV_CHAR_TO_LONG(x) ((unsigned long)(x) >> 24) +#define CONV_SHORT_TO_LONG(x) ((unsigned long)(x) >> 16) + +#define CONV_BITMAPINFO ARCH_ConvBitmapInfo +#define CONV_BITMAPCOREHEADER ARCH_ConvCoreHeader #else #define CONV_LONG(a) (a) #define CONV_SHORT(a) (a) #define CONV_CHAR_TO_LONG(a) (a) #define CONV_SHORT_TO_LONG(a) (a) + +#define CONV_BITMAPINFO +#define CONV_BITMAPCOREHEADER #endif diff --git a/include/atom.h b/include/atom.h index c6234f4db10..9182769962a 100644 --- a/include/atom.h +++ b/include/atom.h @@ -9,7 +9,6 @@ #include "windows.h" - typedef struct { HANDLE next; @@ -27,7 +26,10 @@ typedef struct #ifdef WINELIB #define LocalAlign(flags,bytes) LocalAlloc (flags|LMEM_WINE_ALIGN,bytes) #else -#define LocalAlign(flags,bytes) LocalAlloc (flags,bytes) +#define LocalAlign(flags,bytes) WIN16_LocalAlloc((flags),(bytes)) +#define LocalAlloc WIN16_LocalAlloc +#define LocalLock WIN16_LocalLock +#define LocalFree WIN16_LocalFree #endif #endif /* ATOM_H */ diff --git a/include/bitmap.h b/include/bitmap.h new file mode 100644 index 00000000000..9addd88a478 --- /dev/null +++ b/include/bitmap.h @@ -0,0 +1,22 @@ +/* + * GDI bitmap definitions + * + * Copyright 1993 Alexandre Julliard + */ + +#ifndef BITMAP_H +#define BITMAP_H + +#include +#include "windows.h" + + /* Handle of the bitmap selected by default in a memory DC */ +extern HBITMAP BITMAP_hbitmapMemDC; + + /* 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) + +#endif /* BITMAP_H */ diff --git a/include/desktop.h b/include/desktop.h new file mode 100644 index 00000000000..38b7868e5d9 --- /dev/null +++ b/include/desktop.h @@ -0,0 +1,20 @@ +/* + * Desktop window definitions. + * + * Copyright 1994 Alexandre Julliard + */ + +#ifndef DESKTOP_H +#define DESKTOP_H + +#include "windows.h" + +typedef struct +{ + HBRUSH hbrushPattern; + HBITMAP hbitmapWallPaper; +} DESKTOPINFO; + +extern BOOL DESKTOP_SetPattern(char *pattern ); + +#endif /* DESKTOP_H */ diff --git a/include/dlls.h b/include/dlls.h index f82ae94a4f8..19a2dfbd000 100644 --- a/include/dlls.h +++ b/include/dlls.h @@ -63,5 +63,6 @@ extern struct dll_table_entry_s SHELL_table[]; extern struct dll_table_entry_s SOUND_table[]; extern struct dll_table_entry_s KEYBOARD_table[]; extern struct dll_table_entry_s WINSOCK_table[]; +extern struct dll_table_entry_s STRESS_table[]; #endif /* DLLS_H */ diff --git a/include/gdi.h b/include/gdi.h index c1a56717d0e..3ec95eaac7c 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -69,10 +69,9 @@ typedef struct tagFONTOBJ typedef struct tagBITMAPOBJ { GDIOBJHDR header; - HANDLE hBitmap; - BOOL bSelected; - HDC hdc; - SIZE size; + BITMAP bitmap; + Pixmap pixmap; + SIZE size; /* For SetBitmapDimension() */ } BITMAPOBJ; typedef struct tagRGNOBJ @@ -152,7 +151,6 @@ typedef struct short breakExtra; /* breakTotalExtra / breakCount */ short breakRem; /* breakTotalExtra % breakCount */ - BYTE planes; BYTE bitsPerPixel; WORD MapMode; @@ -179,6 +177,8 @@ typedef struct int style; int pixel; int width; + char * dashes; + int dash_len; } X_PHYSPEN; /* X physical brush */ @@ -197,6 +197,13 @@ typedef struct TEXTMETRIC metrics; } X_PHYSFONT; + /* X physical palette information */ +typedef struct +{ + HANDLE hMapping; + WORD mappingSize; +} X_PHYSPALETTE; + /* X-specific DC information */ typedef struct { @@ -205,6 +212,7 @@ typedef struct X_PHYSFONT font; X_PHYSPEN pen; X_PHYSBRUSH brush; + X_PHYSPALETTE pal; } X_DC_INFO; @@ -282,7 +290,7 @@ typedef struct tagDC extern MDESC *GDI_Heap; #define GDI_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&GDI_Heap,f,size) & 0xffff) -#define GDI_HEAP_ADDR(handle) ((void *)(handle | ((int)GDI_Heap & 0xffff0000))) +#define GDI_HEAP_ADDR(handle) ((void *)((handle)|((int)GDI_Heap & 0xffff0000))) #define GDI_HEAP_FREE(handle) (HEAP_Free(&GDI_Heap,GDI_HEAP_ADDR(handle))) #endif @@ -296,5 +304,7 @@ extern Screen * XT_screen; /* Will be removed */ extern Display * display; extern Screen * screen; +extern Window rootWindow; +extern int screenWidth, screenHeight, screenDepth; #endif /* GDI_H */ diff --git a/include/heap.h b/include/heap.h index 2b3b157b9a4..94ba9c95667 100644 --- a/include/heap.h +++ b/include/heap.h @@ -6,6 +6,10 @@ #ifndef HEAP_H #define HEAP_H +#include "segmem.h" +#include "regfunc.h" +#include "atom.h" + /********************************************************************** * LOCAL HEAP STRUCTURES AND FUNCTIONS */ @@ -17,11 +21,24 @@ typedef struct heap_mem_desc_s unsigned char flags; } MDESC; +typedef struct heap_local_heap_s +{ + struct heap_local_heap_s *next; + MDESC *free_list; + ATOMTABLE *local_table; + unsigned short selector; +} LHEAP; + extern void HEAP_Init(MDESC **free_list, void *start, int length); extern void *HEAP_Alloc(MDESC **free_list, int flags, int bytes); extern int HEAP_Free(MDESC **free_list, void *block); extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block, int new_size, unsigned int flags); +extern LHEAP *HEAP_LocalFindHeap(unsigned short owner); + +#define HEAP_OWNER (Segments[Stack16Frame[11] >> 3].owner) +#define LOCALHEAP() (&HEAP_LocalFindHeap(HEAP_OWNER)->free_list) +#define LOCALATOMTABLE() (&HEAP_LocalFindHeap(HEAP_OWNER)->local_table) /********************************************************************** * GLOBAL HEAP STRUCTURES AND FUNCTIONS: diff --git a/include/mdi.h b/include/mdi.h new file mode 100644 index 00000000000..b6d179ebb9e --- /dev/null +++ b/include/mdi.h @@ -0,0 +1,33 @@ +/* MDI.H + * + * Copyright 1994, Bob Amstadt + * + * MDI structure definitions. + */ + +#ifndef MDI_H +#define MDI_H + +#include "windows.h" + +#define MDI_MAXLISTLENGTH 64 + +typedef struct mdi_child_info_s +{ + struct mdi_child_info_s *next, *prev; + HWND hwnd; +} MDICHILDINFO; + +typedef struct +{ + HMENU hWindowMenu; + MDICHILDINFO *infoActiveChildren; + WORD nActiveChildren; + WORD idFirstChild; + HWND hwndActiveChild; + HWND hwndHitTest; + BOOL flagMenuAltered; + BOOL flagChildMaximized; +} MDICLIENTINFO; + +#endif /* MDI_H */ diff --git a/include/menu.h b/include/menu.h index 315ef2ee5e4..19a66441e9f 100644 --- a/include/menu.h +++ b/include/menu.h @@ -28,15 +28,17 @@ typedef struct tagMENUITEM typedef struct tagPOPUPMENU { - HWND hWnd; /* PopupMenu window handle */ - HWND hWndParent; /* Parent opupMenu window handle */ - HWND ownerWnd; /* Owner window */ - WORD nItems; /* Number of items on menu */ + HWND hWnd; /* PopupMenu window handle */ + HWND hWndParent; /* Parent PopupMenu window handle */ + HWND ownerWnd; /* Owner window */ + HWND hWndPrev; /* Previous Window Focus Owner */ + WORD nItems; /* Number of items on menu */ MENUITEM *firstItem; WORD FocusedItem; WORD MouseFlags; - WORD BarFlags; - BOOL SysFlag; + BOOL BarFlag; /* TRUE if menu is a MENUBAR */ + BOOL SysFlag; /* TRUE if menu is a SYSMENU */ + BOOL ChildFlag; /* TRUE if child of other menu */ WORD Width; WORD Height; WORD CheckWidth; @@ -64,7 +66,7 @@ typedef struct } MENUITEMTEMPLATE; void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop); -void MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y); +BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y); void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y); extern void NC_TrackSysMenu(HWND hwnd); diff --git a/include/message.h b/include/message.h index fc3054dfc8d..905d182a02c 100644 --- a/include/message.h +++ b/include/message.h @@ -48,9 +48,10 @@ extern void MSG_IncPaintCount( HANDLE hQueue ); extern void MSG_DecPaintCount( HANDLE hQueue ); extern void MSG_IncTimerCount( HANDLE hQueue ); extern void MSG_DecTimerCount( HANDLE hQueue ); +extern void MSG_Synchronize(); extern BOOL MSG_CreateSysMsgQueue( int size ); -extern void hardware_event(HWND hwnd, WORD message, WORD wParam, LONG lParam, - WORD xPos, WORD yPos, DWORD time, DWORD extraInfo); +extern void hardware_event( WORD message, WORD wParam, LONG lParam, + int xPos, int yPos, DWORD time, DWORD extraInfo ); extern BOOL MSG_GetHardwareMessage( LPMSG msg ); #endif /* MESSAGE_H */ diff --git a/include/int21.h b/include/msdos.h similarity index 65% rename from include/int21.h rename to include/msdos.h index 2d3d221b337..b06d56cea31 100644 --- a/include/int21.h +++ b/include/msdos.h @@ -1,6 +1,7 @@ -#ifndef INT21_H -#define INT21_H +#ifndef __MSDOS_H +#define __MSDOS_H #include +#include struct dosdirent { int inuse; @@ -11,20 +12,9 @@ struct dosdirent { char attribute; long filesize; long filetime; - long filedate; }; -struct diskinfo { - unsigned int infolevel; - unsigned long serialnumber; - char label[11]; - char fstype[8]; -}; - -#define DosVersion 0x0303; - -#define SectorSize 0x200; -#define SectorsPerCluster 0x04; +#define DOSVERSION 0x0330; #define EAX context->sc_eax #define EBX context->sc_ebx @@ -45,13 +35,39 @@ struct diskinfo { #define EFL context->sc_efl -#define pointer(a,b) (((unsigned int) a << 16) | b) -#define segment(a) (a >> 16) -#define offset(a) (a & 0xffff) - #define SetCflag (EFL |= 0x00000001L) #define ResetCflag (EFL &= 0xfffffffeL) +#define pointer(a,b) (BYTE*)(((WORD) a << 16) | b) +#define segment(a) ((DWORD)a >> 16) +#define offset(a) ((DWORD)a & 0xffff) + +#define setword(a,b) *(BYTE*)a = b & 0xff; \ + *((BYTE*)a + 1) = (b>>8) & 0xff; + +#define setdword(a,b) *(BYTE*)a = b & 0xff; \ + *((BYTE*)a + 1) = (b>>8) & 0xff; \ + *((BYTE*)a + 2) = (b>>16) & 0xff; \ + *((BYTE*)a + 3) = (b>>24) & 0xff; + +#define getword(a) (WORD) *(BYTE*)a + \ + (*((BYTE*)a + 1) << 8) + +#define getdword(a) (DWORD) (*(BYTE*)a + \ + (*((BYTE*)a + 1) << 8) + \ + (*((BYTE*)a + 2) << 16) + \ + (*((BYTE*)a + 3) << 24)) + +/* dos file attributes */ + +#define FA_NORMAL 0x00 /* Normal file, no attributes */ +#define FA_RDONLY 0x01 /* Read only attribute */ +#define FA_HIDDEN 0x02 /* Hidden file */ +#define FA_SYSTEM 0x04 /* System file */ +#define FA_LABEL 0x08 /* Volume label */ +#define FA_DIREC 0x10 /* Directory */ +#define FA_ARCH 0x20 /* Archive */ + /* extended error codes */ #define NoError 0x00 @@ -113,4 +129,4 @@ struct diskinfo { #define EL_Network 0x03 #define EL_Memory 0x05 -#endif /* INT21_H */ +#endif /* __MSDOS_H */ diff --git a/include/neexe.h b/include/neexe.h index cf2700d030f..d31a0e31580 100644 --- a/include/neexe.h +++ b/include/neexe.h @@ -220,4 +220,7 @@ struct resource_typeinfo_s #define NE_RSCTYPE_RCDATA 0x800a #define NE_RSCTYPE_STRING 0x8006 +int load_typeinfo (int, struct resource_typeinfo_s *); +int load_nameinfo (int, struct resource_nameinfo_s *); + #endif /* NEEXE_H */ diff --git a/include/options.h b/include/options.h index e313305a644..ae38f73448f 100644 --- a/include/options.h +++ b/include/options.h @@ -10,6 +10,8 @@ struct options { char * spyFilename; + char * desktopGeometry; /* NULL when no desktop */ + char * programName; /* To use when loading resources */ int usePrivateMap; int synchronous; short cmdShow; diff --git a/include/prototypes.h b/include/prototypes.h index d8a319588b8..a972176f4e3 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -3,54 +3,259 @@ /* * Copyright Robert J. Amstadt, 1993 */ -#ifndef PROTOTYPES_H -#define PROTOTYPES_H +#ifndef _WINE_PROTOTYPES_H +#define _WINE_PROTOTYPES_H #include #include "neexe.h" #include "segmem.h" #include "wine.h" -#include "int21.h" +#include "heap.h" +#include "msdos.h" +#include "windows.h" #ifndef WINELIB -extern struct segment_descriptor_s * - CreateSelectors(struct w_files *); + +/* loader/dump.c */ extern void PrintFileHeader(struct ne_header_s *ne_header); extern void PrintSegmentTable(struct ne_segment_table_entry_s *seg_table, - int nentries); + int nentries); extern void PrintRelocationTable(char *exe_ptr, - struct ne_segment_table_entry_s *seg_entry_p, - int segment); -extern int FixupSegment(struct w_files * wpnt, int segment_num); -extern struct dll_table_entry_s *FindDLLTable(char *dll_name); -extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, - int ordinal); + struct ne_segment_table_entry_s *seg_entry_p, + int segment); -extern struct segment_descriptor_s *GetNextSegment(unsigned int flags, - unsigned int limit); -extern struct segment_descriptor_s *CreateNewSegments(int code_flag, - int read_only, - int length, - int n_segments); +/* loader/ldtlib.c */ + +struct segment_descriptor * +make_sd(unsigned base, unsigned limit, int contents, int read_exec_only, int seg32, int inpgs); +int get_ldt(void *buffer); +int set_ldt_entry(int entry, unsigned long base, unsigned int limit, + int seg_32bit_flag, int contents, int read_only_flag, + int limit_in_pages_flag); + +/* loader/resource.c */ + +extern int OpenResourceFile(HANDLE instance); +extern HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image ); +extern HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image ); +extern int FindResourceByNumber(struct resource_nameinfo_s *result_p, + int type_id, int resource_id); +extern int FindResourceByName(struct resource_nameinfo_s *result_p, + int type_id, char *resource_name); +extern HICON LoadIcon(HANDLE instance, LPSTR icon_name); +extern HANDLE RSC_LoadResource(int instance, char *rsc_name, int type, + int *image_size_ret); +extern int LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen); +extern HANDLE RSC_LoadMenu(HANDLE instance, LPSTR menu_name); +extern HBITMAP LoadBitmap(HANDLE instance, LPSTR bmp_name); + +/* loader/selector.c */ + +extern int FindUnusedSelectors(int n_selectors); +extern int IPCCopySelector(int i_old, unsigned long new, int swap_type); +extern WORD AllocSelector(WORD old_selector); +extern unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector); +extern WORD AllocDStoCSAlias(WORD ds_selector); +extern WORD FreeSelector(WORD sel); +extern SEGDESC *CreateNewSegments(int code_flag, int read_only, int length, + int n_segments); +extern SEGDESC *GetNextSegment(unsigned int flags, unsigned int limit); +extern unsigned int GetEntryDLLName(char *dll_name, char *function, int *sel, + int *addr); +extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, int *sel, + int *addr); +extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, + int ordinal); +extern SEGDESC *CreateSelectors(struct w_files * wpnt); + +/* loader/signal.c */ + +extern int init_wine_signals(void); + +/* loader/wine.c */ + +extern void myerror(const char *s); +extern void load_mz_header (int, struct mz_header_s *); +extern void load_ne_header (int, struct ne_header_s *); + +extern char *GetFilenameFromInstance(unsigned short instance); +extern struct w_files *GetFileInfo(unsigned short instance); +extern HINSTANCE LoadImage(char *modulename, int filetype); +extern int _WinMain(int argc, char **argv); +extern void InitializeLoadedDLLs(); +extern int FixupSegment(struct w_files * wpnt, int segment_num); +/* extern struct mz_header_s *CurrentMZHeader; extern struct ne_header_s *CurrentNEHeader; extern int CurrentNEFile; -extern do_int1A(struct sigcontext_struct * context); -extern do_int21(struct sigcontext_struct * context); +*/ -extern void GetUnixDirName(char *rootdir, char *name); -extern char *GetDirectUnixFileName(char *dosfilename); +/* if1632/relay.c */ + +extern int CallBack16(void *func, int n_args, ...); +extern void *CALLBACK_MakeProcInstance(void *func, int instance); +extern void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam); +extern void winestat(void); + +/* if1632/callback.c */ + +extern int DLLRelay(unsigned int func_num, unsigned int seg_off); +extern struct dll_table_entry_s *FindDLLTable(char *dll_name); +extern int FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name); +extern int ReturnArg(int arg); + +/* miscemu/int1a.c */ + +extern do_int1A(struct sigcontext_struct *context); + +/* miscemu/int21.c */ + +extern do_int21(struct sigcontext_struct *context); + +/* miscemu/kernel.c */ + +extern int KERNEL_LockSegment(int segment); +extern int KERNEL_UnlockSegment(int segment); +extern KERNEL_InitTask(); +extern int KERNEL_WaitEvent(int task); + +/* misc/comm.c */ + +void Comm_Init(void); +void Comm_DeInit(void); + +/* misc/dos_fs.c */ + +extern void DOS_InitFS(void); +extern WORD DOS_GetEquipment(void); +extern int DOS_ValidDrive(int drive); +extern int DOS_GetDefaultDrive(void); +extern void DOS_SetDefaultDrive(int drive); +extern void ToUnix(char *s); +extern void ToDos(char *s); +extern void ChopOffSlash(char *string); +extern int DOS_DisableDrive(int drive); +extern int DOS_EnableDrive(int drive); extern char *GetUnixFileName(char *dosfilename); - +extern char *DOS_GetCurrentDir(int drive); +extern int DOS_ChangeDir(int drive, char *dirname); +extern int DOS_MakeDir(int drive, char *dirname); +extern int DOS_GetSerialNumber(int drive, unsigned long *serialnumber); +extern int DOS_SetSerialNumber(int drive, unsigned long serialnumber); +extern char *DOS_GetVolumeLabel(int drive); +extern int DOS_SetVolumeLabel(int drive, char *label); +extern int DOS_GetFreeSpace(int drive, long *size, long *available); extern char *FindFile(char *buffer, int buflen, char *rootname, char **extensions, char *path); extern char *WineIniFileName(void); -extern char *WinIniFileName(void); -extern struct dosdirent *DOS_opendir(char *dosdirname); +extern char *WinIniFileName(void); +extern struct dosdirent *DOS_opendir(char *dosdirname); extern struct dosdirent *DOS_readdir(struct dosdirent *de); extern void DOS_closedir(struct dosdirent *de); -#endif /* WINELIB */ +/* misc/profile.c */ -#endif /* PROTOTYPES_H */ +extern void sync_profiles(void); + +/* misc/spy.c */ + +extern void SpyInit(void); + +/* controls/button.c */ + +extern LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam); + +/* controls/combo.c */ + +extern LONG ComboBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); + +/* controls/desktop.c */ + +extern LONG DesktopWndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam); +extern BOOL DESKTOP_SetPattern(char *pattern); + +/* controls/listbox.c */ + +extern LONG ListBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); + +/* controls/menu.c */ + +extern LONG PopupMenuWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); + +/* controls/scrollbar.c */ + +extern LONG ScrollBarWndProc(HWND hWnd, WORD message, WORD wParam, LONG lParam); + +/* controls/static.c */ + +extern LONG StaticWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); + +/* controls/widget.c */ + +extern BOOL WIDGETS_Init(void); + +/* memory/heap.c */ + +extern void HEAP_Init(MDESC **free_list, void *start, int length); +extern void *HEAP_Alloc(MDESC **free_list, int flags, int bytes); +extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block, int new_size, unsigned int flags); +extern int HEAP_Free(MDESC **free_list, void *block); +extern LHEAP *HEAP_LocalFindHeap(unsigned short owner); +extern void HEAP_LocalInit(unsigned short owner, void *start, int length); +extern void *WIN16_LocalAlloc(int flags, int bytes); +extern int WIN16_LocalCompact(int min_free); +extern unsigned int WIN16_LocalFlags(unsigned int handle); +extern unsigned int WIN16_LocalFree(unsigned int handle); +extern unsigned int WIN16_LocalInit(unsigned int segment, unsigned int start, unsigned int end); +extern void *WIN16_LocalLock(unsigned int handle); +extern void *WIN16_LocalReAlloc(unsigned int handle, int flags, int bytes); +extern unsigned int WIN16_LocalSize(unsigned int handle); +extern unsigned int WIN16_LocalUnlock(unsigned int handle); + +/* objects/bitmaps.c */ + +extern BOOL BITMAP_Init(void); + +/* objects/color.c */ + +extern BOOL COLOR_Init(void); + +/* objects/dib.c */ + +extern int DIB_BitmapInfoSize(BITMAPINFO *info, WORD coloruse); + +/* objects/gdiobj.c */ + +extern BOOL GDI_Init(void); + +/* objects/palette.c */ + +extern BOOL PALETTE_Init(void); + +/* objects/region.c */ + +extern BOOL REGION_Init(void); + +/* windows/graphic.c */ + +extern void DrawReliefRect(HDC hdc, RECT rect, int thickness, BOOL pressed); + +/* windows/dce.c */ + +extern void DCE_Init(void); + +/* windows/dialog.c */ + +extern BOOL DIALOG_Init(void); + +/* windows/syscolor.c */ + +extern void SYSCOLOR_Init(void); + +/* windows/sysmetrics.c */ + +extern void SYSMETRICS_Init(void); + +#endif /* WINELIB */ +#endif /* _WINE_PROTOTYPES_H */ diff --git a/include/regfunc.h b/include/regfunc.h index e31e9aa17e9..96f2fef0ea3 100644 --- a/include/regfunc.h +++ b/include/regfunc.h @@ -6,6 +6,7 @@ extern unsigned short *Stack16Frame; +#define _CONTEXT &Stack16Frame[12] #define _AX Stack16Frame[34] #define _BX Stack16Frame[28] #define _CX Stack16Frame[32] diff --git a/include/stress.h b/include/stress.h new file mode 100644 index 00000000000..190e675a89a --- /dev/null +++ b/include/stress.h @@ -0,0 +1,30 @@ +#ifndef __STRESS_H +#define __STRESS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EDS_WIN 1 +#define EDS_CUR 2 +#define EDS_TEMP 3 + +BOOL AllocGDIMem(UINT); +BOOL AllocMem(DWORD); +BOOL AllocUserMem(UINT); +int AllocDiskSpace(long, UINT); +int AllocFileHandles(int); +int GetFreeFileHandles(void); +void FreeAllGDIMem(void); +void FreeAllMem(void); +void FreeAllUserMem(void); +void UnAllocDiskSpace(UINT); +void UnAllocFileHandles(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STRESS_H */ diff --git a/include/user.h b/include/user.h index d702023e55a..166a7070eab 100644 --- a/include/user.h +++ b/include/user.h @@ -25,7 +25,7 @@ extern MDESC *USER_Heap; #define USER_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&USER_Heap,f,size) & 0xffff) #define USER_HEAP_REALLOC(handle,size,f) ((int)HEAP_ReAlloc(&USER_Heap, \ USER_HEAP_ADDR(handle),size,f) & 0xffff) -#define USER_HEAP_ADDR(handle) ((void *)(handle|((int)USER_Heap & 0xffff0000))) +#define USER_HEAP_ADDR(handle) ((void *)((handle)|((int)USER_Heap&0xffff0000))) #define USER_HEAP_FREE(handle) (HEAP_Free(&USER_Heap,USER_HEAP_ADDR(handle))) #endif /* WINELIB */ diff --git a/include/win.h b/include/win.h index 706deec2e7c..26319115f52 100644 --- a/include/win.h +++ b/include/win.h @@ -67,8 +67,11 @@ WND *WIN_FindWndPtr( HWND hwnd ); BOOL WIN_UnlinkWindow( HWND hwnd ); BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); HWND WIN_FindWinToRepaint( HWND hwnd ); +BOOL WINPOS_IsAnActiveWindow( HWND hwnd ); +void WINPOS_ActivateChild( HWND hwnd ); extern Display * display; extern Screen * screen; +extern Window rootWindow; #endif /* WIN_H */ diff --git a/include/windows.h b/include/windows.h index 4bd02053647..7986183bb19 100644 --- a/include/windows.h +++ b/include/windows.h @@ -5,6 +5,7 @@ #ifndef _WINARGS +typedef short INT; typedef unsigned short UINT; typedef unsigned short WORD; typedef unsigned long DWORD; @@ -218,6 +219,25 @@ typedef struct { DWORD dwExStyle WINE_PACKED; } CREATESTRUCT, *LPCREATESTRUCT; +typedef struct +{ + HMENU hWindowMenu; + WORD idFirstChild; +} CLIENTCREATESTRUCT, *LPCLIENTCREATESTRUCT; + +typedef struct +{ + LPSTR szClass; + LPSTR szTitle; + HANDLE hOwner; + short x; + short y; + short cx; + short cy; + LONG style WINE_PACKED; + LONG lParam WINE_PACKED; +} MDICREATESTRUCT, *LPMDICREATESTRUCT; + /* Offsets for GetWindowLong() and GetWindowWord() */ #define GWL_EXSTYLE (-20) #define GWL_STYLE (-16) @@ -466,7 +486,9 @@ typedef WORD ATOM; typedef DWORD COLORREF; -#define RGB(r,g,b) ((COLORREF)((r) | ((g) << 8) | ((b) << 16))) +#define RGB(r,g,b) ((COLORREF)((r) | ((g) << 8) | ((b) << 16))) +#define PALETTERGB(r,g,b) (0x02000000 | RGB(r,g,b)) +#define PALETTEINDEX(i) ((COLORREF)(0x01000000 | (WORD)(i))) #define GetRValue(rgb) ((rgb) & 0xff) #define GetGValue(rgb) (((rgb) >> 8) & 0xff) @@ -987,6 +1009,8 @@ typedef OFSTRUCT *LPOFSTRUCT; #define OF_SHARE_EXCLUSIVE 0x0010 #define OF_VERIFY 0x0400 +#define DRIVE_CANNOTDETERMINE 0 +#define DRIVE_DOESNOTEXIST 1 #define DRIVE_REMOVABLE 2 #define DRIVE_FIXED 3 #define DRIVE_REMOTE 4 @@ -1378,6 +1402,18 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #define WM_PARENTNOTIFY 0x0210 +#define WM_MDICREATE 0x0220 +#define WM_MDIDESTROY 0x0221 +#define WM_MDIACTIVATE 0x0222 +#define WM_MDIRESTORE 0x0223 +#define WM_MDINEXT 0x0224 +#define WM_MDIMAXIMIZE 0x0225 +#define WM_MDITILE 0x0226 +#define WM_MDICASCADE 0x0227 +#define WM_MDIICONARRANGE 0x0228 +#define WM_MDIGETACTIVE 0x0229 +#define WM_MDISETMENU 0x0230 + #define WM_ENTERSIZEMOVE 0x0231 #define WM_EXITSIZEMOVE 0x0232 @@ -2117,6 +2153,7 @@ int wsprintf(LPSTR a,LPSTR b,...); F(HMENU,CreateMenu) F(BOOL,GetInputState) +F(BOOL,SetDeskPattern) F(LPSTR,GetDOSEnvironment) F(DWORD,GetMessagePos) F(LONG,GetMessageTime) @@ -2199,9 +2236,11 @@ Fa(BOOL,DestroyWindow,HWND,a) Fa(BOOL,EnableHardwareInput,BOOL,a) Fa(BOOL,FreeModule,HANDLE,a) Fa(BOOL,FreeResource,HANDLE,a) +#ifndef GLOBAL_SOURCE Fa(BOOL,GlobalUnWire,HANDLE,a) Fa(BOOL,GlobalUnfix,HANDLE,a) Fa(BOOL,GlobalUnlock,HANDLE,a) +#endif Fa(BOOL,InitAtomTable,WORD,a) Fa(BOOL,IsClipboardFormatAvailable,WORD,a) Fa(BOOL,IsIconic,HWND,a) @@ -2215,6 +2254,7 @@ Fa(BOOL,LocalUnlock,HANDLE,a) Fa(BOOL,OpenClipboard,HWND,a) Fa(BOOL,OpenIcon,HWND,a) Fa(BOOL,RemoveFontResource,LPSTR,a) +Fa(BOOL,SetDeskWallPaper,LPSTR,a) Fa(BOOL,SetErrorMode,WORD,a) Fa(BOOL,SwapMouseButton,BOOL,a) Fa(BOOL,UnrealizeObject,HBRUSH,a) @@ -2232,9 +2272,11 @@ Fa(DWORD,GetViewportExt,HDC,a) Fa(DWORD,GetViewportOrg,HDC,a) Fa(DWORD,GetWindowExt,HDC,a) Fa(DWORD,GetWindowOrg,HDC,a) +#ifndef GLOBAL_SOURCE Fa(DWORD,GlobalCompact,DWORD,a) Fa(DWORD,GlobalHandle,WORD,a) Fa(DWORD,GlobalSize,HANDLE,a) +#endif Fa(DWORD,OemKeyScan,WORD,a) Fa(FARPROC,LocalNotify,FARPROC,a) Fa(HANDLE,BeginDeferWindowPos,int,nNumWindows) @@ -2248,9 +2290,11 @@ Fa(HANDLE,GetMetaFileBits,HANDLE,a) Fa(HANDLE,GetModuleHandle,LPSTR,a) Fa(HANDLE,GetStockObject,int,a) Fa(HANDLE,GetWindowTask,HWND,a) +#ifndef GLOBAL_SOURCE Fa(HANDLE,GlobalFree,HANDLE,a) Fa(HANDLE,GlobalLRUNewest,HANDLE,a) Fa(HANDLE,GlobalLRUOldest,HANDLE,a) +#endif Fa(HANDLE,LoadLibrary,LPSTR,a) Fa(HANDLE,LocalFree,HANDLE,a) Fa(HANDLE,LocalHandle,WORD,a) @@ -2289,13 +2333,19 @@ Fa(LONG,SetSwapAreaSize,WORD,a) Fa(LPSTR,AnsiLower,LPSTR,a) Fa(LPSTR,AnsiNext,LPSTR,a) Fa(LPSTR,AnsiUpper,LPSTR,a) +#ifndef GLOBAL_SOURCE Fa(LPSTR,GlobalLock,HANDLE,a) Fa(LPSTR,GlobalWire,HANDLE,a) +#endif Fa(LPSTR,LockResource,HANDLE,a) +#ifndef GLOBAL_SOURCE Fa(void,GlobalFix,HANDLE,a) Fa(void,GlobalNotify,FARPROC,a) +#endif Fa(void,LimitEmsPages,DWORD,a) Fa(void,SetConvertHook,BOOL,a) +Fa(UINT,GDIRealizePalette,HDC,a) +Fa(UINT,RealizePalette,HDC,a) Fa(WORD,AllocDStoCSAlias,WORD,a) Fa(WORD,AllocSelector,WORD,a) Fa(WORD,ArrangeIconicWindows,HWND,a) @@ -2305,13 +2355,15 @@ Fa(WORD,GetDriveType,int,a) Fa(WORD,GetMenuItemCount,HMENU,a) Fa(WORD,GetTaskQueue,HANDLE,a) Fa(WORD,GetTextAlign,HDC,a) +#ifndef GLOBAL_SOURCE Fa(WORD,GlobalFlags,HANDLE,a) Fa(WORD,GlobalPageLock,HANDLE,a) Fa(WORD,GlobalPageUnlock,HANDLE,a) +#endif Fa(WORD,LocalCompact,WORD,a) Fa(WORD,LocalFlags,HANDLE,a) Fa(WORD,LocalSize,HANDLE,a) -Fa(int,RealizePalette,HDC,a) +Fa(WORD,RealizeDefaultPalette,HDC,a) Fa(WORD,RegisterClipboardFormat,LPCSTR,a) Fa(WORD,RegisterWindowMessage,LPCSTR,a) Fa(WORD,SetHandleCount,WORD,a) @@ -2412,7 +2464,9 @@ Fb(FARPROC,MakeProcInstance,FARPROC,a,HANDLE,b) Fb(FARPROC,SetWindowsHook,int,a,FARPROC,b) Fb(HANDLE,CopyMetaFile,HANDLE,a,LPSTR,b) Fb(HANDLE,GetProp,HWND,a,LPSTR,b) +#ifndef GLOBAL_SOURCE Fb(HANDLE,GlobalAlloc,WORD,a,DWORD,b) +#endif Fb(HANDLE,LoadAccelerators,HANDLE,a,LPSTR,b) Fb(HANDLE,LoadModule,LPSTR,a,LPVOID,b) Fb(HANDLE,LoadResource,HANDLE,a,HANDLE,b) @@ -2425,6 +2479,7 @@ Fb(HBRUSH,CreateDIBPatternBrush,HANDLE,a,WORD,b) Fb(HBRUSH,CreateHatchBrush,short,a,COLORREF,b) Fb(HCURSOR,LoadCursor,HANDLE,a,LPSTR,b) Fb(HICON,LoadIcon,HANDLE,a,LPSTR,b) +Fb(HPALETTE,GDISelectPalette,HDC,a,HPALETTE,b) Fb(HMENU,GetSubMenu,HMENU,a,short,b) Fb(HMENU,GetSystemMenu,HWND,a,BOOL,b) Fb(HMENU,LoadMenu,HANDLE,a,LPSTR,b) @@ -2553,7 +2608,9 @@ Fc(DWORD,SetWindowOrg,HDC,a,short,b,short,c) Fc(FARPROC,SetResourceHandler,HANDLE,a,LPSTR,b,FARPROC,c) Fc(HANDLE,AllocResource,HANDLE,a,HANDLE,b,DWORD,c) Fc(HANDLE,FindResource,HANDLE,a,LPSTR,b,LPSTR,c) +#ifndef GLOBAL_SOURCE Fc(HANDLE,GlobalReAlloc,HANDLE,a,DWORD,b,WORD,c) +#endif Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c) Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c) Fc(HBITMAP,CreateDiscardableBitmap,HDC,a,short,b,short,c) @@ -2737,7 +2794,7 @@ Fi(BOOL,Pie,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStar Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,short,x,short,y,short,w,short,h,HWND,d,HMENU,e,,HANDLE i,LPSTR,g) Fk(BOOL,StretchBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,short,i,short,j,DWORD,k) Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,short,e,short,f,short,g,short,h,HWND,i,HMENU,j,HANDLE,k,LPSTR,l) -Fl(int,SetDIBitsToDevice,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l) +Fl(int,SetDIBitsToDevice,HDC,a,short,b,short,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l) Fm(int,StretchDIBits,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l,DWORD,m) Fn(HFONT,CreateFont,int,a,int,b,int,c,int,d,int,e,BYTE,f,BYTE,g,BYTE,h,BYTE,i,BYTE,j,BYTE,k,BYTE,l,BYTE,m,LPSTR,n) diff --git a/include/wine.h b/include/wine.h index 13eee6158b2..28cda57fefe 100644 --- a/include/wine.h +++ b/include/wine.h @@ -3,28 +3,35 @@ #include "dlls.h" -struct w_files{ - struct w_files * next; - char * name; /* Name, as it appears in the windows binaries */ - char * filename; /* Actual name of the unix file that satisfies this */ - int fd; - struct mz_header_s *mz_header; - struct ne_header_s *ne_header; - struct ne_segment_table_entry_s *seg_table; - struct segment_descriptor_s *selector_table; - char * lookup_table; - char * nrname_table; - char * rname_table; - unsigned short hinstance; +#define MAX_NAME_LENGTH 64 + +typedef struct resource_name_table +{ + struct resource_name_table *next; + unsigned short type_ord; + unsigned short id_ord; + char id[MAX_NAME_LENGTH]; +} RESNAMTAB; + +struct w_files +{ + struct w_files * next; + char * name; /* Name, as it appears in the windows binaries */ + char * filename; /* Actual name of the unix file that satisfies this */ + int fd; + struct mz_header_s *mz_header; + struct ne_header_s *ne_header; + struct ne_segment_table_entry_s *seg_table; + struct segment_descriptor_s *selector_table; + char * lookup_table; + char * nrname_table; + char * rname_table; + unsigned short hinstance; + RESNAMTAB *resnamtab; }; extern struct w_files * wine_files; -extern char *GetFilenameFromInstance(unsigned short instance); -extern struct w_files *GetFileInfo(unsigned short instance); -extern char *WineIniFileName(void); -extern char *WinIniFileName(void); - #define MAX_DOS_DRIVES 26 #define WINE_INI WineIniFileName() @@ -63,9 +70,4 @@ struct sigcontext_struct { #define HZ 100 #endif -void load_mz_header (int, struct mz_header_s *); -void load_ne_header (int, struct ne_header_s *); -int load_typeinfo (int, struct resource_typeinfo_s *); -int load_nameinfo (int, struct resource_nameinfo_s *); - #endif /* WINE_H */ diff --git a/include/winsock.h b/include/winsock.h index 6b83e52ab82..c36be06068c 100644 --- a/include/winsock.h +++ b/include/winsock.h @@ -63,6 +63,7 @@ typedef WSADATA FAR *LPWSADATA; #endif #ifndef _SYS_SOCKET_H_ +#ifndef _sys_socket_h /* * Structure used by kernel to pass protocol * information in raw sockets. @@ -72,6 +73,7 @@ struct sockproto { u_short sp_protocol; /* protocol */ }; #endif +#endif /* * Maximum queue length specifiable by listen. diff --git a/loader/Imakefile b/loader/Imakefile index 7c9ddeb670d..df538543359 100644 --- a/loader/Imakefile +++ b/loader/Imakefile @@ -9,6 +9,7 @@ SRCS = \ selector.c \ signal.c \ library.c \ + resource.c \ wine.c OBJS = $(SRCS:.c=.o) diff --git a/loader/dump.c b/loader/dump.c index 42fee12c923..08e1962d5a2 100644 --- a/loader/dump.c +++ b/loader/dump.c @@ -1,3 +1,4 @@ +#ifndef WINELIB static char RCSId[] = "$Id: dump.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; @@ -89,3 +90,4 @@ PrintRelocationTable(char *exe_ptr, printf("TARGET %04.4x %04.4x\n", rep->target1, rep->target2); } } +#endif /* ifndef WINELIB */ diff --git a/loader/ldt.c b/loader/ldt.c index 8ac6b1e9ec4..96ca5e4d4e1 100644 --- a/loader/ldt.c +++ b/loader/ldt.c @@ -1,11 +1,12 @@ +#ifndef WINELIB static char RCSId[] = "$Id: ldt.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include - #include "prototypes.h" + #if defined(__NetBSD__) || defined(__FreeBSD__) #include #endif @@ -84,3 +85,5 @@ print_ldt() } } } + +#endif /* ifndef WINELIB */ diff --git a/loader/ldtlib.c b/loader/ldtlib.c index d3610407d66..c2649796cbe 100644 --- a/loader/ldtlib.c +++ b/loader/ldtlib.c @@ -1,3 +1,4 @@ +#ifndef WINELIB static char RCSId[] = "$Id: ldtlib.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; @@ -90,3 +91,4 @@ set_ldt_entry(int entry, unsigned long base, unsigned int limit, #endif } +#endif /* ifndef WINELIB */ diff --git a/loader/library.c b/loader/library.c index ebb91fec64a..39ea0bba1bb 100644 --- a/loader/library.c +++ b/loader/library.c @@ -1,5 +1,7 @@ +#ifndef WINELIB #include #include +#include #include #include #include @@ -9,8 +11,18 @@ #include "wine.h" #include "dlls.h" +typedef struct module_table_entry +{ + HINSTANCE hInst; + LPSTR name; + WORD count; +} MODULEENTRY; + extern struct w_files * wine_files; +#define N_BUILTINS 10 + +extern struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS]; /********************************************************************** * GetCurrentTask [KERNEL.36] @@ -28,19 +40,27 @@ HTASK GetCurrentTask() */ HANDLE GetModuleHandle(LPSTR lpModuleName) { - register struct w_files *w = wine_files; - printf("GetModuleHandle('%s');\n", lpModuleName); - while (w) { - printf("GetModuleHandle // '%s' \n", w->name); - if (strcmp(w->name, lpModuleName) == 0) { - printf("GetModuleHandle('%s') return %04X \n", - lpModuleName, w->hinstance); - return w->hinstance; - } - w = w->next; - } - printf("GetModuleHandle('%s') not found !\n", lpModuleName); - return 0; + register struct w_files *w = wine_files; + int i; + printf("GetModuleHandle('%s');\n", lpModuleName); + while (w) { +/* printf("GetModuleHandle // '%s' \n", w->name); */ + if (strcmp(w->name, lpModuleName) == 0) { + printf("GetModuleHandle('%s') return %04X \n", + lpModuleName, w->hinstance); + return w->hinstance; + } + w = w->next; + } + for (i = 0; i < N_BUILTINS; i++) { + if (strcmp(dll_builtin_table[i].dll_name, lpModuleName) == 0) { + printf("GetModuleHandle('%s') return %04X \n", + lpModuleName, 0xFF00 + i); + return (0xFF00 + i); + } + } + printf("GetModuleHandle('%s') not found !\n", lpModuleName); + return 0; } @@ -79,11 +99,11 @@ int GetModuleFileName(HANDLE hModule, LPSTR lpFileName, short nSize) */ HANDLE LoadLibrary(LPSTR libname) { - HANDLE hRet; + HANDLE hModule; printf("LoadLibrary '%s'\n", libname); - hRet = LoadImage(libname, DLL); - printf("after LoadLibrary hRet=%04X\n", hRet); - return hRet; + hModule = LoadImage(libname, DLL); + printf("LoadLibrary returned hModule=%04X\n", hModule); + return hModule; } @@ -97,3 +117,64 @@ void FreeLibrary(HANDLE hLib) } +/********************************************************************** + * GetProcAddress [KERNEL.50] + */ +FARPROC GetProcAddress(HANDLE hModule, char *proc_name) +{ + WORD wOrdin; + int sel, addr, ret; + register struct w_files *w = wine_files; + int ordinal, len; + char * cpnt; + char C[128]; + if (hModule == 0) { + printf("GetProcAddress: Bad Module handle=%#04X\n", hModule); + return NULL; + } + if (hModule >= 0xF000) { + if ((int) proc_name & 0xffff0000) { + printf("GetProcAddress: builtin %#04x, '%s'\n", hModule, proc_name); +/* wOrdin = FindOrdinalFromName(struct dll_table_entry_s *dll_table, proc_name); */ + } + else { + printf("GetProcAddress: builtin %#04x, %d\n", hModule, (int) proc_name); + } + return NULL; + } + while (w && w->hinstance != hModule) w = w->next; + printf("GetProcAddress // Module Found ! w->filename='%s'\n", w->filename); + if (w == NULL) return NULL; + if ((int) proc_name & 0xffff0000) { + AnsiUpper(proc_name); + printf("GetProcAddress: %#04x, '%s'\n", hModule, proc_name); + cpnt = w->nrname_table; + while(TRUE) { + if (((int) cpnt) - ((int)w->nrname_table) > + w->ne_header->nrname_tab_length) return NULL; + len = *cpnt++; + strncpy(C, cpnt, len); + C[len] = '\0'; + printf("pointing Function '%s' !\n", C); + if (strncmp(cpnt, proc_name, len) == 0) break; + cpnt += len + 2; + }; + ordinal = *((unsigned short *) (cpnt + len)); + } + else { + printf("GetProcAddress: %#04x, %d\n", hModule, (int) proc_name); + ordinal = (int)proc_name; + } + ret = GetEntryPointFromOrdinal(w, ordinal); + if (ret == -1) { + printf("GetProcAddress // Function not found !\n"); + return NULL; + } + addr = ret & 0xffff; + sel = (ret >> 16); + printf("GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret, sel, addr); + return ret; +} + +#endif /* ifndef WINELIB */ + diff --git a/misc/resource.c b/loader/resource.c similarity index 81% rename from misc/resource.c rename to loader/resource.c index 680b61f1f93..4ff3c28db03 100644 --- a/misc/resource.c +++ b/loader/resource.c @@ -1,14 +1,14 @@ -#ifndef WINELIB static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; -#endif #include #include +#include #include #include #include #include + #include "arch.h" #include "prototypes.h" #include "windows.h" @@ -17,6 +17,8 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "icon.h" #include "accel.h" +/* #define DEBUG_RESOURCE */ + #define MIN(a,b) ((a) < (b) ? (a) : (b)) typedef struct resource_s @@ -34,18 +36,105 @@ static struct w_files *ResourceFileInfo = NULL; static RESOURCE *Top = NULL; extern HINSTANCE hSysRes; -HANDLE RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret); +HANDLE RSC_LoadResource(int instance, char *rsc_name, int type, + int *image_size_ret); +void RSC_LoadNameTable(void); extern char *ProgramName; -/***************************************************************************** - * Super Patch, I promise to arrange things as soon as I can. - * -******************************************************************************/ -#ifdef WINELIB -#include "../loader/wine.c" -#endif + +/********************************************************************** + * RSC_LoadNameTable + */ +#ifndef WINELIB +void +RSC_LoadNameTable() +{ + struct resource_typeinfo_s typeinfo; + struct resource_nameinfo_s nameinfo; + unsigned short size_shift; + RESNAMTAB *top, *new; + char read_buf[1024]; + char *p; + int i; + unsigned short len; + off_t rtoff; + off_t saved_pos; + + top = NULL; + /* + * Move to beginning of resource table. + */ + rtoff = (ResourceFileInfo->mz_header->ne_offset + + ResourceFileInfo->ne_header->resource_tab_offset); + lseek(ResourceFd, rtoff, SEEK_SET); + + /* + * Read block size. + */ + if (read(ResourceFd, &size_shift, sizeof(size_shift)) != + sizeof(size_shift)) + { + return; + } + size_shift = CONV_SHORT(size_shift); + + /* + * Find resource. + */ + typeinfo.type_id = 0xffff; + while (typeinfo.type_id != 0) + { + if (!load_typeinfo (ResourceFd, &typeinfo)) + break; + + if (typeinfo.type_id == 0) + break; + if (typeinfo.type_id == 0x800f) + { + for (i = 0; i < typeinfo.count; i++) + { + if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != + sizeof(nameinfo)) + { + break; + } + + saved_pos = lseek(ResourceFd, 0, SEEK_CUR); + lseek(ResourceFd, (long) nameinfo.offset << size_shift, + SEEK_SET); + read(ResourceFd, &len, sizeof(len)); + while (len) + { + new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new)); + new->next = top; + top = new; + + read(ResourceFd, &new->type_ord, 2); + read(ResourceFd, &new->id_ord, 2); + read(ResourceFd, read_buf, len - 6); + + p = read_buf + strlen(read_buf) + 1; + strncpy(new->id, p, MAX_NAME_LENGTH); + new->id[MAX_NAME_LENGTH - 1] = '\0'; + + read(ResourceFd, &len, sizeof(len)); + } + + lseek(ResourceFd, saved_pos, SEEK_SET); + } + break; + } + else + { + lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR); + } + } + + ResourceFileInfo->resnamtab = top; +} +#endif /* WINELIB */ /********************************************************************** * OpenResourceFile @@ -69,8 +158,15 @@ OpenResourceFile(HANDLE instance) close(ResourceFd); ResourceInst = instance; - - ResourceFd = open (res_file, O_RDONLY); + ResourceFd = open (res_file, O_RDONLY); +#if 1 +#ifndef WINELIB + if (w->resnamtab == (RESNAMTAB *) -1) + { + RSC_LoadNameTable(); + } +#endif +#endif #ifdef DEBUG_RESOURCE printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n", @@ -241,6 +337,25 @@ FindResourceByName(struct resource_nameinfo_s *result_p, int i; off_t rtoff; + /* + * Check for loaded name table. + */ + if (ResourceFileInfo->resnamtab != NULL) + { + RESNAMTAB *e; + + for (e = ResourceFileInfo->resnamtab; e != NULL; e = e->next) + { + if (e->type_ord == (type_id & 0x000f) && + strcasecmp(e->id, resource_name) == 0) + { + return FindResourceByNumber(result_p, type_id, e->id_ord); + } + } + + return -1; + } + /* * Move to beginning of resource table. */ @@ -311,9 +426,7 @@ FindResourceByName(struct resource_nameinfo_s *result_p, typeinfo.type_id, i + 1, typeinfo.count, name, resource_name); #endif -/* if (strcasecmp(name, resource_name) == 0) */ - if (strcasecmp(name, resource_name) == 0 || - (nameinfo.id == 0x8001 && type_id == NE_RSCTYPE_MENU)) + if (strcasecmp(name, resource_name) == 0) { memcpy(result_p, &nameinfo, sizeof(nameinfo)); return size_shift; @@ -794,6 +907,10 @@ LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) HANDLE RSC_LoadMenu(HANDLE instance, LPSTR menu_name) { +#ifdef DEBUG_RESOURCE + printf("RSC_LoadMenu: instance = %04x, name = '%s'\n", + instance, menu_name); +#endif return RSC_LoadResource(instance, menu_name, NE_RSCTYPE_MENU, NULL); } @@ -808,7 +925,8 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) HDC hdc; long *lp; int image_size; - + int size; + #ifdef DEBUG_RESOURCE printf("LoadBitmap: instance = %04x, name = %08x\n", instance, bmp_name); @@ -828,14 +946,73 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) GlobalFree(rsc_mem); return 0; } - if (*lp == sizeof(BITMAPCOREHEADER)) + size = CONV_LONG (*lp); + if (size == sizeof(BITMAPCOREHEADER)){ + CONV_BITMAPCOREHEADER (lp); hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp ); - else if (*lp == sizeof(BITMAPINFOHEADER)) + } else if (size == sizeof(BITMAPINFOHEADER)){ + CONV_BITMAPINFO (lp); hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp ); - else hbitmap = 0; + } else hbitmap = 0; GlobalFree(rsc_mem); ReleaseDC( 0, hdc ); return hbitmap; } + +/********************************************************************** + * CreateIcon [USER.407] + */ +HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight, + BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits, + LPSTR lpXORbits) +{ + HICON hIcon; + ICONALLOC *lpico; +#ifdef DEBUG_RESOURCE + printf("CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n", + hInstance, nWidth, nHeight); + printf(" nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel); + printf(" lpANDbits= %04x, lpXORbits = %04x, \n",lpANDbits, lpXORbits); +#endif + if (hInstance == (HANDLE)NULL) { + printf("CreateIcon / hInstance %04x not Found!\n",hInstance); + return 0; + } + hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024); + if (hIcon == (HICON)NULL) { + printf("Can't allocate memory for Icon in CreateIcon\n"); + return 0; + } + lpico= (ICONALLOC *)GlobalLock(hIcon); + + lpico->descriptor.Width=nWidth; + lpico->descriptor.Height=nHeight; + lpico->descriptor.ColorCount=16; /* Dummy Value */ + lpico->descriptor.Reserved1=0; + lpico->descriptor.Reserved2=nPlanes; + lpico->descriptor.Reserved3=nWidth*nHeight; + + /* either nPlanes and/or nBitCount is set to one */ + lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel; + lpico->descriptor.icoDIBOffset=0; + + if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel, + lpXORbits)) ) { + printf("CreateIcon: couldn't create the XOR bitmap\n"); + return(0); + } + + /* the AND BitMask is always monochrome */ + if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) { + printf("CreateIcon: couldn't create the AND bitmap\n"); + return(0); + } + + GlobalUnlock(hIcon); +#ifdef DEBUG_RESOURCE + printf("CreateIcon Alloc hIcon=%X\n", hIcon); +#endif + return hIcon; +} diff --git a/loader/selector.c b/loader/selector.c index bea1886e594..834e25229a2 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -1,12 +1,16 @@ +#ifndef WINELIB static char RCSId[] = "$Id: selector.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include +#include #include #include #include #include +#include + #ifdef __linux__ #include #include @@ -16,14 +20,16 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #endif #if defined(__NetBSD__) || defined(__FreeBSD__) #include +#include #endif -#include + #include "neexe.h" #include "segmem.h" -#include "prototypes.h" #include "wine.h" +#include "windows.h" +#include "prototypes.h" -/* #define DEBUG_SELECTORS /* */ +/* #define DEBUG_SELECTORS */ #ifdef linux #define DEV_ZERO @@ -31,7 +37,6 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #endif #if defined(__NetBSD__) || defined(__FreeBSD__) -#include #define PAGE_SIZE getpagesize() #define MODIFY_LDT_CONTENTS_DATA 0 #define MODIFY_LDT_CONTENTS_STACK 1 @@ -214,8 +219,7 @@ IPCCopySelector(int i_old, unsigned long new, int swap_type) * This is very bad!!! This function is implemented for Windows * compatibility only. Do not call this from the emulation library. */ -unsigned int -AllocSelector(unsigned int old_selector) +WORD AllocSelector(WORD old_selector) { SEGDESC *s_new, *s_old; int i_new, i_old; @@ -382,7 +386,7 @@ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) /********************************************************************** * AllocCStoDSAlias */ -AllocDStoCSAlias(unsigned int ds_selector) +WORD AllocDStoCSAlias(WORD ds_selector) { unsigned int cs_selector; @@ -396,7 +400,7 @@ AllocDStoCSAlias(unsigned int ds_selector) /********************************************************************** * FreeSelector */ -unsigned int FreeSelector(unsigned int sel) +WORD FreeSelector(WORD sel) { SEGDESC *s; int sel_idx; @@ -694,10 +698,9 @@ GetEntryPointFromOrdinal(struct w_files * wpnt, int ordinal) /********************************************************************** * GetDOSEnvironment */ -void * -GetDOSEnvironment() +LPSTR GetDOSEnvironment(void) { - return EnvironmentSelector->base_addr; + return (LPSTR) EnvironmentSelector->base_addr; } /********************************************************************** @@ -916,3 +919,4 @@ CreateSelectors(struct w_files * wpnt) return selectors; } +#endif /* ifndef WINELIB */ diff --git a/loader/signal.c b/loader/signal.c index be88b963335..d788cc06c01 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -1,6 +1,8 @@ -#include +#ifndef WINELIB #include #include +#include +#include #include #if defined(__NetBSD__) || defined(__FreeBSD__) @@ -8,14 +10,14 @@ #else #include #endif -#include -#include #ifdef linux #include #include #endif + #include "wine.h" #include "segmem.h" +#include "prototypes.h" char * cstack[4096]; struct sigaction segv_act; @@ -40,92 +42,145 @@ wine_sigaction(int sig,struct sigaction * new, struct sigaction * old) } #ifdef linux -static void win_fault(int signal, struct sigcontext_struct context){ - struct sigcontext_struct *scp = &context; +static void win_fault(int signal, struct sigcontext_struct context) +{ + struct sigcontext_struct *scp = &context; #else -static void win_fault(int signal, int code, struct sigcontext *scp){ +static void win_fault(int signal, int code, struct sigcontext *scp) +{ #endif - unsigned char * instr; - unsigned char intno; - unsigned int * dump; - int i; + unsigned char * instr; + unsigned int * dump; + int i; /* First take care of a few preliminaries */ #ifdef linux - if(signal != SIGSEGV) exit(1); - if((scp->sc_cs & 7) != 7){ + if(signal != SIGSEGV) + exit(1); + if((scp->sc_cs & 7) != 7) + { #endif #if defined(__NetBSD__) || defined(__FreeBSD__) /* set_es(0x27); set_ds(0x27); */ - if(signal != SIGBUS) exit(1); - if(scp->sc_cs == 0x1f){ -#endif - fprintf(stderr, - "Segmentation fault in Wine program (%x:%x)." - " Please debug\n", - scp->sc_cs, scp->sc_eip); - goto oops; - }; - - /* Now take a look at the actual instruction where the program - bombed */ - instr = (char *) SAFEMAKEPTR(scp->sc_cs, scp->sc_eip); - - if(*instr != 0xcd) { - fprintf(stderr, - "Unexpected Windows program segfault" - " - opcode = %x\n", *instr); -#if 0 - return; -#else - goto oops; -#endif - }; - - instr++; - intno = *instr; - switch(intno){ - case 0x21: - if(!do_int21(scp)) goto oops; - break; - case 0x11: - scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment(); - break; - case 0x12: - scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L; - break; /* get base mem size */ - case 0x1A: - if(!do_int1A(scp)) goto oops; - break; - default: - fprintf(stderr,"Unexpected Windows interrupt %x\n", intno); - goto oops; - }; - - /* OK, done handling the interrupt */ - - scp->sc_eip += 2; /* Bypass the int instruction */ - return; - oops: - fprintf(stderr,"In win_fault %x:%x\n", scp->sc_cs, scp->sc_eip); -#ifdef linux - wine_debug(scp); /* Enter our debugger */ -#else - fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp); - dump = (int*) scp; - for(i=0; i<22; i++) - { - fprintf(stderr," %8.8x", *dump++); - if ((i % 8) == 7) - fprintf(stderr,"\n"); - } - fprintf(stderr,"\n"); + if(signal != SIGBUS) exit(1); + if(scp->sc_cs == 0x1f) + { +#endif + fprintf(stderr, + "Segmentation fault in Wine program (%x:%x)." + " Please debug\n", + scp->sc_cs, scp->sc_eip); + goto oops; + }; + + /* Now take a look at the actual instruction where the program + bombed */ + instr = (unsigned char *) SAFEMAKEPTR(scp->sc_cs, scp->sc_eip); + + switch(*instr) + { + case 0xcd: /* int */ + instr++; + switch(*instr) + { + case 0x10: + if(!do_int10(scp)) + goto oops; + break; + + case 0x11: + scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment(); + break; + + case 0x12: + scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L; + break; /* get base mem size */ + + case 0x1A: + if(!do_int1A(scp)) + goto oops; + break; + + case 0x21: + if (!do_int21(scp)) + goto oops; + break; + + case 0x22: + scp->sc_eax = 0x1234; + scp->sc_ebx = 0x5678; + scp->sc_ecx = 0x9abc; + scp->sc_edx = 0xdef0; + break; + + case 0x25: + if (!do_int25(scp)) + goto oops; + break; + + case 0x26: + if (!do_int26(scp)) + goto oops; + break; + + default: + fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr); + goto oops; + } + scp->sc_eip += 2; /* Bypass the int instruction */ + break; + + case 0xec: /* inb al,dx */ + inportb(scp); + scp->sc_eip++; + break; + + case 0xed: /* in ax,dx */ + inport(scp); + scp->sc_eip++; + break; + + case 0xee: /* outb dx,al */ + outportb(scp); + scp->sc_eip++; + break; + + case 0xef: /* out dx,ax */ + outport(scp); + scp->sc_eip++; + break; + + default: + fprintf(stderr, "Unexpected Windows program segfault" + " - opcode = %x\n", *instr); + goto oops; + } + + /* OK, done handling the interrupt */ + + return; + + oops: + fprintf(stderr,"In win_fault %x:%x\n", scp->sc_cs, scp->sc_eip); +#ifdef linux + wine_debug(scp); /* Enter our debugger */ +#else + fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp); + dump = (int*) scp; + for(i=0; i<22; i++) + { + fprintf(stderr," %8.8x", *dump++); + if ((i % 8) == 7) + fprintf(stderr,"\n"); + } + fprintf(stderr,"\n"); + exit(1); #endif } -int -init_wine_signals(){ +int init_wine_signals(void) +{ #ifdef linux segv_act.sa_handler = (__sighandler_t) win_fault; /* Point to the top of the stack, minus 4 just in case, and make @@ -155,3 +210,4 @@ init_wine_signals(){ #endif } +#endif /* ifndef WINELIB */ diff --git a/loader/wine.c b/loader/wine.c index 26936da4ebd..4edecaaaa33 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -49,7 +49,6 @@ HINSTANCE hSysRes; static char *DLL_Extensions[] = { "dll", "exe", NULL }; static char *EXE_Extensions[] = { "exe", NULL }; -static char *WinePath = NULL; FILE *SpyFp = NULL; @@ -137,7 +136,7 @@ HINSTANCE LoadImage(char *modulename, int filetype) if (FindFile(buffer, sizeof(buffer), modulename, (filetype == EXE ? EXE_Extensions : DLL_Extensions), WindowsPath) ==NULL) { - fprintf(stderr,"LoadImage: I can't find %s !\n",modulename); + fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",modulename, modulename); return (HINSTANCE) NULL; } fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer); @@ -155,6 +154,7 @@ HINSTANCE LoadImage(char *modulename, int filetype) wpnt1->next = wpnt; }; wpnt->next = NULL; + wpnt->resnamtab = (RESNAMTAB *) -1; /* * Open file for reading. @@ -248,8 +248,6 @@ HINSTANCE LoadImage(char *modulename, int filetype) */ for(i=0; ine_header->n_mod_ref_tab; i++){ char buff[14]; - char buff2[256]; - int fd, j; GetModuleName(wpnt, i + 1, buff); #ifndef WINELIB @@ -265,37 +263,26 @@ return(wpnt->hinstance); } +#ifndef WINELIB /********************************************************************** * main */ -_WinMain(int argc, char **argv) +int _WinMain(int argc, char **argv) { int segment; char *p; char *sysresname; char filename[100]; - char syspath[256]; - char exe_path[256]; #ifdef WINESTAT char * cp; #endif struct w_files * wpnt; int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg; - int i; int rv; Argc = argc - 1; Argv = argv + 1; - WinePath = malloc(1024); - - getcwd(WinePath, 512); - - if ((p = getenv("WINEPATH")) != NULL) { - strcat(WinePath, ";"); - strcat(WinePath, p); - } - if (LoadImage(Argv[0], EXE) == (HINSTANCE) NULL ) { fprintf(stderr, "wine: can't find %s!.\n", Argv[0]); exit(1); @@ -393,6 +380,7 @@ void InitializeLoadedDLLs() } } } +#endif /********************************************************************** @@ -402,10 +390,8 @@ char * GetImportedName(int fd, struct mz_header_s *mz_header, struct ne_header_s *ne_header, int name_offset, char *buffer) { - char *p; int length; int status; - int i; status = lseek(fd, mz_header->ne_offset + ne_header->iname_tab_offset + name_offset, SEEK_SET); @@ -426,7 +412,6 @@ GetModuleName(struct w_files * wpnt, int index, char *buffer) int fd = wpnt->fd; struct mz_header_s *mz_header = wpnt->mz_header; struct ne_header_s *ne_header = wpnt->ne_header; - char *p; int length; WORD name_offset, status; int i; @@ -714,16 +699,4 @@ FixupSegment(struct w_files * wpnt, int segment_num) return 0; } -/********************************************************************** - * GetProcAddress - */ -FARPROC GetProcAddress(HINSTANCE hinstance, char *proc_name) -{ - if ((int) proc_name & 0xffff0000) - printf("GetProcAddress: %#04x, '%s'\n", hinstance, proc_name); - else - printf("GetProcAddress: %#04x, %d\n", hinstance, (int) proc_name); - - return NULL; -} #endif diff --git a/memory/global.c b/memory/global.c index 76b558fc25f..11ab3631232 100644 --- a/memory/global.c +++ b/memory/global.c @@ -1,8 +1,11 @@ static char RCSId[] = "$Id: global.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +#define GLOBAL_SOURCE + #include #include +#include #include "prototypes.h" #include "heap.h" #include "segmem.h" @@ -153,7 +156,7 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) /********************************************************************** * GlobalAlloc */ -unsigned int +HANDLE GlobalAlloc(unsigned int flags, unsigned long size) { GDESC *g; @@ -258,7 +261,7 @@ GlobalAlloc(unsigned int flags, unsigned long size) * Windows programs will pass a handle in the "block" parameter, but * this function will also accept a 32-bit address. */ -unsigned int +HANDLE GlobalFree(unsigned int block) { GDESC *g; @@ -269,18 +272,7 @@ GlobalFree(unsigned int block) /* * Find GDESC for this block. */ - if (block & 0xffff0000) - { - for (g = GlobalList; g != NULL; g = g->next) - if (g->handle > 0 && (unsigned int) g->addr == block) - break; - } - else - { - for (g = GlobalList; g != NULL; g = g->next) - if (g->handle == block) - break; - } + g = GlobalGetGDesc(block); if (g == NULL) return block; @@ -556,12 +548,7 @@ GlobalReAlloc(unsigned int block, unsigned int new_size, unsigned int flags) /* * Find GDESC for this block. */ - for (g = GlobalList; g != NULL; g = g->next) - { - if (g->handle == block) - break; - } - + g = GlobalGetGDesc(block); if (g == NULL) return 0; @@ -733,6 +720,70 @@ GlobalHandleFromPointer(void *block) else return g->handle; } + +/********************************************************************** + * GetFreeSpace (kernel.169) + */ +DWORD GetFreeSpace(UINT wFlags) +/* windows 3.1 doesn't use the wFlags parameter !! + (so I won't either) */ +{ + GDESC *g; + unsigned char free_map[512]; + unsigned int max_selector_used = 0; + unsigned int i; + unsigned int selector; + int total_free; + /* + * Initialize free list to all items not controlled by GlobalAlloc() + */ + for (i = 0; i < 512; i++) + free_map[i] = -1; + /* + * Traverse table looking for used and free selectors. + */ + for (g = GlobalList; g != NULL; g = g->next) + { + /* + * Check for free segments. + */ + if (g->sequence == -1) + { + free_map[g->handle >> 3] = 1; + if (g->handle > max_selector_used) + max_selector_used = g->handle; + } + + /* + * Check for heap allocated segments. + */ + else if (g->handle == 0) + { + selector = (unsigned int) g->addr >> 16; + free_map[selector >> 3] = 0; + if (selector > max_selector_used) + max_selector_used = selector; + } + } + + /* + * All segments past the biggest selector used are free. + */ + for (i = (max_selector_used >> 3) + 1; i < 512; i++) + free_map[i] = 1; + + /* + * Add up the total free segments (obviously this amount of memory + may not be contiguous, use GlobalCompact to get largest contiguous + memory available). + */ + total_free=0; + for (i = 0; i < 512; i++) + if (free_map[i] == 1) + total_free++; + + return total_free << 16; +} diff --git a/memory/heap.c b/memory/heap.c index 18f50a4c7dd..71cb56113af 100644 --- a/memory/heap.c +++ b/memory/heap.c @@ -3,17 +3,13 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include +#include #include "prototypes.h" #include "segmem.h" #include "heap.h" #include "regfunc.h" -typedef struct heap_local_heap_s -{ - struct heap_local_heap_s *next; - MDESC *free_list; - unsigned short selector; -} LHEAP; +/* #define DEBUG_HEAP */ LHEAP *LocalHeaps = NULL; @@ -23,6 +19,9 @@ LHEAP *LocalHeaps = NULL; void HEAP_Init(MDESC **free_list, void *start, int length) { + if (length < 2 * sizeof(MDESC)) + return; + *free_list = (MDESC *) start; (*free_list)->prev = NULL; (*free_list)->next = NULL; @@ -302,8 +301,6 @@ HEAP_LocalFindHeap(unsigned short owner) return NULL; } -#define LOCALHEAP() (&HEAP_LocalFindHeap(Segments[Stack16Frame[11] >> 3].owner)->free_list) - /********************************************************************** * HEAP_LocalInit */ @@ -316,43 +313,47 @@ HEAP_LocalInit(unsigned short owner, void *start, int length) printf("HEAP_LocalInit: owner %04x, start %08x, length %04x\n", owner, start, length); #endif + + if (length < 2 * sizeof(MDESC)) + return; lh = (LHEAP *) malloc(sizeof(*lh)); if (lh == NULL) return; - lh->selector = owner; - lh->next = LocalHeaps; + lh->next = LocalHeaps; + lh->selector = owner; + lh->local_table = NULL; HEAP_Init(&lh->free_list, start, length); LocalHeaps = lh; } /********************************************************************** - * LocalAlloc + * WIN16_LocalAlloc */ void * -LocalAlloc(int flags, int bytes) +WIN16_LocalAlloc(int flags, int bytes) { void *m; #ifdef DEBUG_HEAP - printf("LocalAlloc: flags %x, bytes %d\n", flags, bytes); + printf("WIN16_LocalAlloc: flags %x, bytes %d\n", flags, bytes); printf(" called from segment %04x\n", Stack16Frame[11]); #endif m = HEAP_Alloc(LOCALHEAP(), flags, bytes); #ifdef DEBUG_HEAP - printf("LocalAlloc: returning %x\n", (int) m); + printf("WIN16_LocalAlloc: returning %x\n", (int) m); #endif return m; } /********************************************************************** - * LocalCompact + * WIN16_LocalCompact */ int -LocalCompact(int min_free) +WIN16_LocalCompact(int min_free) { MDESC *m; int max_block; @@ -366,10 +367,10 @@ LocalCompact(int min_free) } /********************************************************************** - * LocalFlags + * WIN16_LocalFlags */ unsigned int -LocalFlags(unsigned int handle) +WIN16_LocalFlags(unsigned int handle) { MDESC *m; @@ -382,10 +383,10 @@ LocalFlags(unsigned int handle) } /********************************************************************** - * LocalFree + * WIN16_LocalFree */ unsigned int -LocalFree(unsigned int handle) +WIN16_LocalFree(unsigned int handle) { unsigned int addr; @@ -397,12 +398,12 @@ LocalFree(unsigned int handle) } /********************************************************************** - * LocalInit + * WIN16_LocalInit */ unsigned int -LocalInit(unsigned int segment, unsigned int start, unsigned int end) +WIN16_LocalInit(unsigned int segment, unsigned int start, unsigned int end) { - unsigned short owner = Segments[Stack16Frame[11] >> 3].owner; + unsigned short owner = HEAP_OWNER; LHEAP *lh = HEAP_LocalFindHeap(owner); if (segment == 0) @@ -426,10 +427,10 @@ LocalInit(unsigned int segment, unsigned int start, unsigned int end) } /********************************************************************** - * LocalLock + * WIN16_LocalLock */ void * -LocalLock(unsigned int handle) +WIN16_LocalLock(unsigned int handle) { MDESC *m; @@ -443,10 +444,10 @@ LocalLock(unsigned int handle) } /********************************************************************** - * LocalReAlloc + * WIN16_LocalReAlloc */ void * -LocalReAlloc(unsigned int handle, int flags, int bytes) +WIN16_LocalReAlloc(unsigned int handle, int flags, int bytes) { void *m; @@ -458,10 +459,10 @@ LocalReAlloc(unsigned int handle, int flags, int bytes) } /********************************************************************** - * LocalSize + * WIN16_LocalSize */ unsigned int -LocalSize(unsigned int handle) +WIN16_LocalSize(unsigned int handle) { MDESC *m; @@ -474,10 +475,10 @@ LocalSize(unsigned int handle) } /********************************************************************** - * LocalUnlock + * WIN16_LocalUnlock */ unsigned int -LocalUnlock(unsigned int handle) +WIN16_LocalUnlock(unsigned int handle) { MDESC *m; @@ -491,3 +492,49 @@ LocalUnlock(unsigned int handle) return 0; } + +/********************************************************************** + * GetFreeSystemResources (user.284) + + */ +#define USERRESOURCES 2 +#define GDIRESOURCES 1 +#define SYSTEMRESOURCES 0 +#include +#include + +WORD GetFreeSystemResources(WORD SystemResourceType) +{ + unsigned int GdiFree=0,GdiResult=0; + unsigned int UserFree=0,UserResult=0; + unsigned int result=0; + MDESC *m; + + printf("GetFreeSystemResources(%u)\n",SystemResourceType); + + switch(SystemResourceType) { + case(USERRESOURCES): + for (m = USER_Heap; m != NULL; m = m->next) /* add up free area in heap */ + UserFree += m->length; + result=(UserFree*100)/65516; /* 65516 == 64K */ + break; + case(GDIRESOURCES): + for (m = GDI_Heap; m != NULL; m = m->next) + GdiFree += m->length; + result=(GdiFree*100)/65516; + break; + case(SYSTEMRESOURCES): + for (m = USER_Heap; m != NULL; m = m->next) + UserFree += m->length; + UserResult=(UserFree*100)/65516; + for (m = GDI_Heap; m != NULL; m = m->next) + GdiFree += m->length; + GdiResult=(GdiFree*100)/65516; + result=(UserResult < GdiResult) ? UserResult:GdiResult; + break; + default: + result=0; + break; + } + return(result); +} diff --git a/memory/linear.c b/memory/linear.c index af403e28c57..1bceeaacb52 100644 --- a/memory/linear.c +++ b/memory/linear.c @@ -3,6 +3,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1994"; #include #include +#include #include "prototypes.h" #include "heap.h" #include "segmem.h" diff --git a/misc/Imakefile b/misc/Imakefile index 43ee484af2b..2979b52987c 100644 --- a/misc/Imakefile +++ b/misc/Imakefile @@ -16,9 +16,9 @@ SRCS = \ message.c \ profile.c \ rect.c \ - resource.c \ sound.c \ spy.c \ + stress.c \ user.c \ winsocket.c diff --git a/misc/atom.c b/misc/atom.c index 79db3b9b092..f8f7d0758d3 100644 --- a/misc/atom.c +++ b/misc/atom.c @@ -7,13 +7,6 @@ /* * Current limitations: * - * - This code should work fine when called from the emulation library, - * but probably not when called from the Windows program. The reason - * is that everything is allocated on the current local heap, instead - * of taking into account the DS register. Correcting this will also - * require some changes in the local heap management to bring it closer - * to Windows. - * * - The code assumes that LocalAlloc() returns a block aligned on a * 4-bytes boundary (because of the shifting done in HANDLETOATOM). * If this is not the case, the allocation code will have to be changed. @@ -30,22 +23,35 @@ * aligned block. Needed to test the Library. */ -#include #include +#include #include +#include #include "user.h" #include "atom.h" - +#include "prototypes.h" +#ifndef WINELIB +#include "heap.h" +#endif #define DEFAULT_ATOMTABLE_SIZE 37 #define MIN_STR_ATOM 0xc000 +#ifdef WINELIB +#define ATOMTOHANDLE +#define HANDLETOATOM +#else #define ATOMTOHANDLE(atom) ((HANDLE)(atom) << 2) #define HANDLETOATOM(handle) ((ATOM)(0xc000 | ((handle) >> 2))) +#endif - +#ifdef WINELIB static ATOMTABLE * localTable = NULL; +#undef LOCALATOMTABLE +#define LOCALATOMTABLE() &localTable +#endif + static ATOMTABLE * globalTable = NULL; @@ -56,18 +62,31 @@ static BOOL ATOM_InitTable( ATOMTABLE ** table, WORD entries ) { int i; HANDLE handle; + + if (table == &globalTable) + { + handle = USER_HEAP_ALLOC(LMEM_MOVEABLE, sizeof(ATOMTABLE) + + (entries-1) * sizeof(HANDLE) ); + if (!handle) + return FALSE; + *table = (ATOMTABLE *) USER_HEAP_ADDR( handle ); + } + else + { + handle = LocalAlign ( LMEM_MOVEABLE, sizeof(ATOMTABLE) + + (entries-1) * sizeof(HANDLE) ); + if (!handle) + return FALSE; + *table = (ATOMTABLE *) LocalLock( handle ); + } - handle = LocalAlign ( LMEM_MOVEABLE, sizeof(ATOMTABLE) + - (entries-1) * sizeof(HANDLE) ); - if (!handle) return FALSE; - *table = (ATOMTABLE *) LocalLock( handle ); (*table)->size = entries; - for (i = 0; i < entries; i++) (*table)->entries[i] = 0; + for (i = 0; i < entries; i++) + (*table)->entries[i] = 0; return TRUE; } - /*********************************************************************** * ATOM_Init * @@ -87,7 +106,11 @@ BOOL ATOM_Init() */ static ATOMENTRY * ATOM_MakePtr( ATOMTABLE * table, HANDLE handle ) { +#ifdef WINELIB + return (ATOMENTRY *) LocalLock (handle); +#else return (ATOMENTRY *) (((int)table & 0xffff0000) | (int)handle); +#endif } @@ -132,8 +155,18 @@ static ATOM ATOM_AddAtom( ATOMTABLE * table, LPCSTR str ) } entry = entryPtr->next; } + + if (table == globalTable) + { + entry = (int) USER_HEAP_ALLOC(LMEM_MOVEABLE, + sizeof(ATOMENTRY)+len-1 ) & 0xffff; + } + else + { + entry = (int) LocalAlign(LMEM_MOVEABLE, + sizeof(ATOMENTRY)+len-1 ) & 0xffff; + } - entry = (int)LocalAlign( LMEM_MOVEABLE, sizeof(ATOMENTRY)+len-1 ) & 0xffff; if (!entry) return 0; entryPtr = ATOM_MakePtr( table, entry ); entryPtr->next = table->entries[hash]; @@ -173,7 +206,10 @@ static ATOM ATOM_DeleteAtom( ATOMTABLE * table, ATOM atom ) if (--entryPtr->refCount == 0) { *prevEntry = entryPtr->next; - USER_HEAP_FREE( entry ); + if (table == globalTable) + USER_HEAP_FREE(entry); + else + LocalFree( entry ); } return 0; } @@ -246,7 +282,7 @@ static WORD ATOM_GetAtomName( ATOMTABLE * table, ATOM atom, */ BOOL InitAtomTable( WORD entries ) { - return ATOM_InitTable( &localTable, entries ); + return ATOM_InitTable( LOCALATOMTABLE(), entries ); } @@ -265,8 +301,8 @@ HANDLE GetAtomHandle( ATOM atom ) */ ATOM AddAtom( LPCSTR str ) { - if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); - return ATOM_AddAtom( localTable, str ); + if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_AddAtom( *LOCALATOMTABLE(), str ); } @@ -275,8 +311,8 @@ ATOM AddAtom( LPCSTR str ) */ ATOM DeleteAtom( ATOM atom ) { - if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); - return ATOM_DeleteAtom( localTable, atom ); + if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_DeleteAtom( *LOCALATOMTABLE(), atom ); } @@ -285,8 +321,8 @@ ATOM DeleteAtom( ATOM atom ) */ ATOM FindAtom( LPCSTR str ) { - if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); - return ATOM_FindAtom( localTable, str ); + if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_FindAtom( *LOCALATOMTABLE(), str ); } @@ -295,8 +331,8 @@ ATOM FindAtom( LPCSTR str ) */ WORD GetAtomName( ATOM atom, LPSTR buffer, short count ) { - if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); - return ATOM_GetAtomName( localTable, atom, buffer, count ); + if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_GetAtomName( *LOCALATOMTABLE(), atom, buffer, count ); } diff --git a/misc/clipboard.c b/misc/clipboard.c index f62d083837c..17cca794ab6 100644 --- a/misc/clipboard.c +++ b/misc/clipboard.c @@ -10,6 +10,8 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994"; #define DEBUG_CLIPBOARD */ +#include +#include #include #include #include diff --git a/misc/comm.c b/misc/comm.c index 84cc620f557..0a51b77d600 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -8,11 +8,14 @@ #include #include #include +#include #include #if defined(__NetBSD__) || defined(__FreeBSD__) #include #include #endif +#include + #include "wine.h" #include "windows.h" @@ -38,7 +41,7 @@ void Comm_DeInit(void); void Comm_Init(void) { int x, serial = 0, parallel = 0; - char option[10], temp[256], *ptr; + char option[10], temp[256]; struct stat st; for (x=0; x!=MAX_PORTS; x++) { @@ -145,10 +148,10 @@ int BuildCommDCB(LPSTR device, DCB FAR *lpdcb) /* 012345 */ int port; - char *ptr, *ptr2, temp[256],temp2[10]; + char *ptr, temp[256]; #ifdef DEBUG_COMM -fprintf(stderr,"BuildCommDCB: (%s), ptr %d\n", device, lpdcb); +fprintf(stderr,"BuildCommDCB: (%s), ptr %d\n", device, (long) lpdcb); #endif commerror = 0; @@ -296,8 +299,6 @@ fprintf(stderr,"OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue); int CloseComm(int fd) { - int status; - #ifdef DEBUG_COMM fprintf(stderr,"CloseComm: fd %d\n", fd); #endif @@ -477,7 +478,7 @@ int SetCommState(DCB FAR *lpdcb) struct termios port; #ifdef DEBUG_COMM -fprintf(stderr,"SetCommState: fd %d, ptr %d\n", lpdcb->Id, lpdcb); +fprintf(stderr,"SetCommState: fd %d, ptr %d\n", lpdcb->Id, (long) lpdcb); #endif if (tcgetattr(lpdcb->Id, &port) == -1) { @@ -666,7 +667,7 @@ int GetCommState(int fd, DCB FAR *lpdcb) struct termios port; #ifdef DEBUG_COMM -fprintf(stderr,"GetCommState: fd %d, ptr %d\n", fd, lpdcb); +fprintf(stderr,"GetCommState: fd %d, ptr %d\n", fd, (long) lpdcb); #endif if (tcgetattr(fd, &port) == -1) { @@ -836,7 +837,7 @@ int ReadComm(int fd, LPSTR lpvBuf, int cbRead) struct DosDeviceStruct *ptr; #ifdef DEBUG_COMM -fprintf(stderr,"ReadComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbRead); +fprintf(stderr,"ReadComm: fd %d, ptr %d, length %d\n", fd, (long) lpvBuf, cbRead); #endif if ((ptr = GetDeviceStruct(fd)) == NULL) { @@ -875,7 +876,7 @@ int WriteComm(int fd, LPSTR lpvBuf, int cbWrite) struct DosDeviceStruct *ptr; #ifdef DEBUG_COMM -fprintf(stderr,"WriteComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbWrite); +fprintf(stderr,"WriteComm: fd %d, ptr %d, length %d\n", fd, (long) lpvBuf, cbWrite); #endif if ((ptr = GetDeviceStruct(fd)) == NULL) { diff --git a/misc/cursor.c b/misc/cursor.c index 931d538e411..fa2d0ec5bb1 100644 --- a/misc/cursor.c +++ b/misc/cursor.c @@ -7,14 +7,15 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #define DEBUG_CURSOR */ -#include -#include #include #include +#include #include #include #include #include +#include +#include #include "prototypes.h" #include "windows.h" #include "win.h" @@ -28,6 +29,7 @@ static HCURSOR hEmptyCursor = 0; RECT ClipCursorRect; extern HINSTANCE hSysRes; extern Window winHasCursor; +extern int desktopX, desktopY; /* misc/main.c */ static struct { LPSTR name; HCURSOR cursor; } system_cursor[] = { @@ -116,6 +118,11 @@ HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_h_double_arrow); GlobalUnlock(hCursor); return hCursor; + case IDC_SIZENWSE: + case IDC_SIZENESW: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_fleur); + GlobalUnlock(hCursor); + return hCursor; default: break; } @@ -358,19 +365,10 @@ HCURSOR SetCursor(HCURSOR hCursor) */ void SetCursorPos(short x, short y) { - Window root, child; - int rootX, rootY; - int childX, childY; - unsigned int mousebut; #ifdef DEBUG_CURSOR printf("SetCursorPos // x=%d y=%d\n", x, y); #endif - XQueryPointer(XT_display, DefaultRootWindow(XT_display), - &root, &child, &rootX, &rootY, &childX, &childY, &mousebut); - XWarpPointer(XT_display, child, root, 0, 0, - DisplayWidth(XT_display, DefaultScreen(XT_display)), - DisplayHeight(XT_display, DefaultScreen(XT_display)), - (int)x, (int)y); + XWarpPointer( display, None, rootWindow, 0, 0, 0, 0, x, y ); } @@ -383,15 +381,19 @@ void GetCursorPos(LPPOINT lpRetPoint) int rootX, rootY; int childX, childY; unsigned int mousebut; - if (lpRetPoint != NULL) { - XQueryPointer(XT_display, DefaultRootWindow(XT_display), - &root, &child, &rootX, &rootY, &childX, &childY, &mousebut); + + if (!lpRetPoint) return; + if (!XQueryPointer( display, rootWindow, &root, &child, + &rootX, &rootY, &childX, &childY, &mousebut )) + lpRetPoint->x = lpRetPoint->y = 0; + else + { + lpRetPoint->x = rootX + desktopX; + lpRetPoint->y = rootY + desktopY; + } #ifdef DEBUG_CURSOR - printf("GetCursorPos // x=%d y=%d\n", rootX, rootY); + printf("GetCursorPos // x=%d y=%d\n", lpRetPoint->x, lpRetPoint->y); #endif - lpRetPoint->x = rootX; - lpRetPoint->y = rootY; - } } diff --git a/misc/dos_fs.c b/misc/dos_fs.c index cc220c4d6f3..9c9e9ef6fbe 100644 --- a/misc/dos_fs.c +++ b/misc/dos_fs.c @@ -10,6 +10,11 @@ #include #include #include +#include +#include +#include +#include + #if defined(__linux__) || defined(sun) #include #endif @@ -17,27 +22,23 @@ #include #include #endif -#include -#include "windows.h" -#include "wine.h" -#include "int21.h" -/* - #define DEBUG -*/ +#include "windows.h" +#include "msdos.h" +#include "prototypes.h" +#include "autoconf.h" + +/* #define DEBUG */ + +#define WINE_INI_USER "~/.winerc" #define MAX_OPEN_DIRS 16 +#define MAX_DOS_DRIVES 26 extern char WindowsDirectory[256], SystemDirectory[256],TempDirectory[256]; char WindowsPath[256]; -void DOS_DeInitFS(void); -int DOS_SetDefaultDrive(int); -char *GetDirectUnixFileName(char *); -void ToDos(char *); -void ToUnix(char *); - -int CurrentDrive = 2; +static int CurrentDrive = 2; struct DosDriveStruct { /* eg: */ char *rootdir; /* /usr/windows */ @@ -47,9 +48,35 @@ struct DosDriveStruct { /* eg: */ int disabled; /* 0 */ }; -struct DosDriveStruct DosDrives[MAX_DOS_DRIVES]; +static struct DosDriveStruct DosDrives[MAX_DOS_DRIVES]; +static struct dosdirent DosDirs[MAX_OPEN_DIRS]; -struct dosdirent DosDirs[MAX_OPEN_DIRS]; +static void ExpandTildeString(char *s) +{ + struct passwd *entry; + char temp[1024], *ptr = temp; + + strcpy(temp, s); + while (*ptr) + { + if (*ptr != '~') { + *s++ = *ptr++; + continue; + } + ptr++; + if ( (entry = getpwuid(getuid())) == NULL) { + continue; + } + strcpy(s, entry->pw_dir); + s += strlen(entry->pw_dir); + } +} + +void ChopOffSlash(char *path) +{ + if (path[strlen(path)-1] == '/' || path[strlen(path)-1] == '\\') + path[strlen(path)-1] = '\0'; +} void DOS_InitFS(void) { @@ -68,10 +95,17 @@ void DOS_InitFS(void) GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system", WindowsPath, sizeof(WindowsPath), WINE_INI); + ChopOffSlash(WindowsDirectory); ToDos(WindowsDirectory); + + ChopOffSlash(SystemDirectory); ToDos(SystemDirectory); + + ChopOffSlash(TempDirectory); ToDos(TempDirectory); + ToDos(WindowsPath); + ExpandTildeString(WindowsPath); for (x=0; x!=MAX_DOS_DRIVES; x++) { DosDrives[x].serialnumber = (0xEB0500L | x); @@ -86,16 +120,15 @@ void DOS_InitFS(void) DosDrives[x].disabled = 1; continue; } - + ExpandTildeString(temp); if ((ptr = (char *) malloc(strlen(temp)+1)) == NULL) { fprintf(stderr,"DOSFS: can't malloc for drive info!"); continue; } - if (temp[strlen(temp)-1] == '/') - temp[strlen(temp)] = '\0'; + ChopOffSlash(temp); DosDrives[x].rootdir = ptr; strcpy(DosDrives[x].rootdir, temp); - strcpy(DosDrives[x].cwd, "/"); + strcpy(DosDrives[x].cwd, "/windows/"); strcpy(DosDrives[x].label, "DRIVE-"); strcat(DosDrives[x].label, drive); DosDrives[x].disabled = 0; @@ -130,27 +163,6 @@ void DOS_InitFS(void) #endif } -void DOS_DeInitFS(void) -{ - int x; - - for (x=0; x!=MAX_DOS_DRIVES ; x++) - if (DosDrives[x].rootdir != NULL) { -#ifdef DEBUG - - fprintf(stderr, "DOSFS: %c: => %s %s %s %X %d\n", - 'A'+x, - DosDrives[x].rootdir, - DosDrives[x].cwd, - DosDrives[x].label, - DosDrives[x].serialnumber, - DosDrives[x].disabled - ); - free(DosDrives[x].rootdir); -#endif - } -} - WORD DOS_GetEquipment(void) { WORD equipment; @@ -214,40 +226,51 @@ int DOS_GetDefaultDrive(void) return( CurrentDrive); } -int DOS_SetDefaultDrive(int drive) +void DOS_SetDefaultDrive(int drive) { #ifdef DEBUG fprintf(stderr,"SetDefaultDrive to %c:\n",'A'+drive); #endif - if (!DOS_ValidDrive(drive)) - return 1; - - CurrentDrive = drive; + if (DOS_ValidDrive(drive)) + CurrentDrive = drive; } void ToUnix(char *s) { - while (*s) { - if (*s == '/') - break; - if (*s == '\\') - *s = '/'; - if (isupper(*s)) - *s = tolower(*s); - s++; + /* \WINDOWS\\SYSTEM => /windows/system */ + + char *p; + + for (p = s; *p; p++) + { + if (*p != '\\') + *s++ = tolower(*p); + else { + *s++ = '/'; + if (*(p+1) == '/' || *(p+1) == '\\') + p++; + } } + *s = '\0'; } void ToDos(char *s) { - while (*s) { - if (*s == '/') - *s = '\\'; - if (islower(*s)) - *s = toupper(*s); - s++; + /* /windows//system => \WINDOWS\SYSTEM */ + + char *p; + for (p = s; *p; p++) + { + if (*p != '/') + *s++ = toupper(*p); + else { + *s++ = '\\'; + if (*s == '/' || *s == '\\') + p++; + } } + *s = '\0'; } int DOS_DisableDrive(int drive) @@ -272,9 +295,9 @@ int DOS_EnableDrive(int drive) return 1; } -void GetUnixDirName(char *rootdir, char *name) +static void GetUnixDirName(char *rootdir, char *name) { - int filename; + int filename = 1; char *nameptr, *cwdptr; cwdptr = rootdir + strlen(rootdir); @@ -299,7 +322,6 @@ void GetUnixDirName(char *rootdir, char *name) *(cwdptr+1) = '\0'; goto next; } - } goto next; } @@ -330,13 +352,12 @@ void GetUnixDirName(char *rootdir, char *name) */ } -char *GetDirectUnixFileName(char *dosfilename) +char *GetUnixFileName(char *dosfilename) { - /* a:\windows\system.ini => /dos/windows/system.ini */ + /* a:\windows\system.ini => /dos/windows/system.ini */ - static char temp[256]; + char temp[256]; int drive; - char x; if (dosfilename[1] == ':') { @@ -349,59 +370,22 @@ char *GetDirectUnixFileName(char *dosfilename) } else drive = CurrentDrive; - strcpy(temp,DosDrives[drive].rootdir); + strcpy(temp, DosDrives[drive].rootdir); strcat(temp, DosDrives[drive].cwd); GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dosfilename); ToUnix(temp); #ifdef DEBUG - fprintf(stderr,"GetDirectUnixFileName: %c:%s => %s\n",'A'+ drive, dosfilename, temp); + fprintf(stderr,"GetUnixFileName: %s => %s\n", dosfilename, temp); #endif return(temp); } -char *GetUnixFileName(char *dosfilename) -{ - char *dirname, *unixname, workingpath[256], temp[256]; - - /* check if program specified a path */ - - if (*dosfilename == '.' || *dosfilename == '\\') - return( GetDirectUnixFileName(dosfilename) ); - - /* nope, lets find it */ - -#ifdef DEBUG - fprintf(stderr,"GetUnixFileName: %s\n",dosfilename); -#endif - - strcpy(workingpath, WindowsPath); - - for(dirname = strtok(workingpath, ";") ; - dirname != NULL; - dirname = strtok(NULL, ";")) - { - strcpy(temp,dirname); - if (temp[strlen(temp)-1] != '\\') - strcat(temp,"\\"); - strcat(temp,dosfilename); - -#ifdef DEBUG - fprintf(stderr,"trying %s\n",temp); -#endif - - if ( (unixname = GetDirectUnixFileName(temp)) != NULL) - return unixname; - } - puts("FAILED!"); - return NULL; -} - -char *DOS_GetCurrentDir(int drive, char *dirname) +char *DOS_GetCurrentDir(int drive) { - /* should return 'windows\system' */ + /* should return 'WINDOWS\SYSTEM' */ char temp[256]; @@ -410,25 +394,29 @@ char *DOS_GetCurrentDir(int drive, char *dirname) strcpy(temp, DosDrives[drive].cwd); ToDos(temp); - - if (temp[strlen(temp)-1] == '\\') - temp[strlen(temp)] = '\0'; + fprintf(stderr, "2 %s\n", temp); + ChopOffSlash(temp); #ifdef DEBUG - fprintf(stderr,"DOS_GetCWD: %c:\%s",'A'+drive, temp+1); + fprintf(stderr,"DOS_GetCWD: %c: %s\n",'A'+drive, temp + 1); #endif - return (temp+1); + return (temp + 1); } int DOS_ChangeDir(int drive, char *dirname) { + char temp[256]; + if (!DOS_ValidDrive(drive)) return 0; - GetUnixDirName(DosDrives[drive].cwd, dirname); + strcpy(temp, dirname); + ToUnix(temp); + + GetUnixDirName(DosDrives[drive].cwd, temp); strcat(DosDrives[drive].cwd,"/"); #ifdef DEBUG - fprintf(stderr,"DOS_SetCWD: %c:\%s",'A'+drive, DosDrives[drive].cwd); + fprintf(stderr,"DOS_SetCWD: %c: %s\n",'A'+drive, DosDrives[drive].cwd); #endif return 1; } @@ -450,35 +438,9 @@ int DOS_MakeDir(int drive, char *dirname) #ifdef DEBUG fprintf(stderr,"DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp); #endif + return 1; } -/* -void main(void) -{ - strcpy(DosDrives[0].cwd, "1/2/3/"); - - puts(DosDrives[0].cwd); - ChangeDir(0,".."); - puts(DosDrives[0].cwd); - - ChangeDir(0,"..\\.."); - puts(DosDrives[0].cwd); - - ChangeDir(0,"."); - puts(DosDrives[0].cwd); - - ChangeDir(0,"test"); - puts(DosDrives[0].cwd); - - ChangeDir(0,"\\qwerty\\ab"); - puts(DosDrives[0].cwd); - - ChangeDir(0,"erik\\.\\bos\\..\\24"); - puts(DosDrives[0].cwd); - -} -*/ - int DOS_GetSerialNumber(int drive, unsigned long *serialnumber) { if (!DOS_ValidDrive(drive)) @@ -497,6 +459,23 @@ int DOS_SetSerialNumber(int drive, unsigned long serialnumber) return 1; } +char *DOS_GetVolumeLabel(int drive) +{ + if (!DOS_ValidDrive(drive)) + return NULL; + + return (DosDrives[drive].label); +} + +int DOS_SetVolumeLabel(int drive, char *label) +{ + if (!DOS_ValidDrive(drive)) + return 0; + + strncpy(DosDrives[drive].label, label, 8); + return 1; +} + int DOS_GetFreeSpace(int drive, long *size, long *available) { struct statfs info; @@ -515,50 +494,39 @@ int DOS_GetFreeSpace(int drive, long *size, long *available) return 1; } -char *FindFile(char *buffer, int buflen, char *rootname, char **extensions, +char *FindFile(char *buffer, int buflen, char *filename, char **extensions, char *path) { - char *workingpath; - char *dirname; + char *workingpath, *dirname, *rootname, **e; DIR *d; struct dirent *f; - char **e; - int rootnamelen; - int found = 0; + int rootnamelen, found = 0; + struct stat filestat; - - if (strchr(rootname, '\\') != NULL) + if (strchr(filename, '\\') != NULL) { - strncpy(buffer, GetDirectUnixFileName(rootname), buflen); + strncpy(buffer, GetUnixFileName(filename), buflen); ToUnix(buffer); - -#ifdef DEBUG -fprintf(stderr,"FindFile: %s -> %s\n",rootname,buffer); -#endif - return buffer; } - if (strchr(rootname, '/') != NULL) + if (strchr(filename, '/') != NULL) { - strncpy(buffer, rootname, buflen); - -#ifdef DEBUG -fprintf(stderr,"FindFile: %s -> %s\n",rootname,buffer); -#endif - + strncpy(buffer, filename, buflen); return buffer; } #ifdef DEBUG -fprintf(stderr,"FindFile: looking for %s\n",rootname); +fprintf(stderr,"FindFile: looking for %s\n", filename); #endif + rootnamelen = strlen(filename); + if ((rootname = malloc(rootnamelen + 1)) == NULL) + return NULL; + strcpy(rootname, filename); ToUnix(rootname); - rootnamelen = strlen(rootname); - workingpath = malloc(strlen(path) + 1); - if (workingpath == NULL) + if ((workingpath = malloc(strlen(path) + 1)) == NULL) return NULL; strcpy(workingpath, path); @@ -566,8 +534,8 @@ fprintf(stderr,"FindFile: looking for %s\n",rootname); dirname != NULL; dirname = strtok(NULL, ";")) { - if (strchr(dirname, '\\')!=NULL) - d = opendir( GetDirectUnixFileName(dirname) ); + if (strchr(dirname, '\\') != NULL) + d = opendir( GetUnixFileName(dirname) ); else d = opendir( dirname ); @@ -583,38 +551,37 @@ fprintf(stderr,"FindFile: looking for %s\n",rootname); { if (extensions == NULL || strcasecmp(rootname, f->d_name) == 0) - { - found = 1; - } - else if (f->d_name[rootnamelen] == '.') - { + found = 1; + else + if (f->d_name[rootnamelen] == '.') for (e = extensions; *e != NULL; e++) - { if (strcasecmp(*e, f->d_name + rootnamelen + 1) == 0) { found = 1; break; } - } - } - + if (found) { - if (strchr(dirname, '\\')!=NULL) - strncpy(buffer, GetDirectUnixFileName(dirname), buflen); - else + if (strchr(dirname, '\\') != NULL) + strncpy(buffer, GetUnixFileName(dirname), buflen); + else strncpy(buffer, dirname, buflen); - if (buffer[strlen(buffer)-1]!='/') - strncat(buffer, "/", buflen - strlen(buffer)); - + strncat(buffer, "/", buflen - strlen(buffer)); strncat(buffer, f->d_name, buflen - strlen(buffer)); - closedir(d); - ToUnix(buffer); + fprintf(stderr,"$$%s$$\n", buffer); - return buffer; + stat(buffer, &filestat); + if (S_ISREG(filestat.st_mode)) { + closedir(d); + free(rootname); + ToUnix(buffer); + return buffer; + } else + found = 0; } } } @@ -629,52 +596,52 @@ fprintf(stderr,"FindFile: looking for %s\n",rootname); */ char *WineIniFileName(void) { - static char *IniName = NULL, *env; + int fd; + static char *filename = NULL; + char name[256]; - char inipath[256]; - - if (IniName) - return IniName; + if (filename) + return filename; - getcwd(inipath, 256); - - if ((env = getenv("HOME")) !=NULL) { - strcat(inipath, ";"); - strcat(inipath, env); - } - if ((env = getenv("WINEPATH")) !=NULL) { - strcat(inipath, ";"); - strcat(inipath, env); - } - - IniName = malloc(1024); - if (FindFile(IniName, 1024, "wine.ini", NULL, inipath) == NULL) - { - free(IniName); - IniName = NULL; - return NULL; - } - - IniName = realloc(IniName, strlen(IniName) + 1); - - ToUnix(IniName); - - return IniName; + strcpy(name, WINE_INI_USER); + ExpandTildeString(name); + if ((fd = open(name, O_RDONLY)) != -1) { + close(fd); + filename = malloc(strlen(name) + 1); + strcpy(filename, name); + return(filename); + } + if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) { + close(fd); + filename = malloc(strlen(WINE_INI_GLOBAL) + 1); + strcpy(filename, WINE_INI_GLOBAL); + return(filename); + } + fprintf(stderr,"wine: can't open configuration file %s or %s !\n", + WINE_INI_GLOBAL, WINE_INI_USER); + exit(1); } -char *WinIniFileName() +char *WinIniFileName(void) { - static char name[256]; + static char *name = NULL; - strcpy(name,GetDirectUnixFileName(WindowsDirectory)); - strcat(name,"win.ini"); + if (name) + return name; + + name = malloc(1024); + strcpy(name, GetUnixFileName(WindowsDirectory)); + strcat(name, "/"); + strcat(name, "win.ini"); ToUnix(name); + + name = realloc(name, strlen(name) + 1); return name; } -int match(char *filename, char *filemask) +static int match(char *filename, char *filemask) { int x, masklength = strlen(filemask); @@ -683,10 +650,8 @@ int match(char *filename, char *filemask) #endif for (x = 0; x != masklength ; x++) { -#ifdef DEBUG - printf("(%c%c) ", *filename, filemask[x]); -#endif - +/* printf("(%c%c) ", *filename, filemask[x]); +*/ if (!*filename) /* stop if EOFname */ return 1; @@ -723,12 +688,10 @@ struct dosdirent *DOS_opendir(char *dosdirname) if (x == MAX_OPEN_DIRS) return NULL; - if ((unixdirname = GetDirectUnixFileName(dosdirname)) == NULL) + if ((unixdirname = GetUnixFileName(dosdirname)) == NULL) return NULL; strcpy(temp, unixdirname); - - y = strlen(temp); while (y--) { @@ -779,15 +742,18 @@ struct dosdirent *DOS_readdir(struct dosdirent *de) ToDos(de->filename); } while ( !match(de->filename, de->filemask) ); - de->attribute = 0x0; - strcpy(temp,de->unixpath); strcat(temp,"/"); strcat(temp,de->filename); ToUnix(temp); + stat (temp, &st); + de->attribute = 0x0; if S_ISDIR(st.st_mode) - de->attribute |= 0x08; + de->attribute |= FA_DIREC; + + de->filesize = st.st_size; + de->filetime = st.st_mtime; return de; } diff --git a/misc/exec.c b/misc/exec.c index a41a95cdc90..f6730c610d9 100644 --- a/misc/exec.c +++ b/misc/exec.c @@ -3,6 +3,10 @@ * */ +#include +#include +#include +#include #include "windows.h" #define HELP_CONTEXT 0x0001 @@ -23,79 +27,65 @@ WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow) { - int X, X2, C; - char *ArgV[20]; - printf("WinExec('%s', %04X)\n", lpCmdLine, nCmdShow); - for (X = X2 = C = 0; X < strlen(lpCmdLine) + 1; X++) { - if ((lpCmdLine[X] == ' ') || (lpCmdLine[X] == '\0')) { - ArgV[C] = (char *)malloc(X - X2 + 1); - strncpy(ArgV[C], &lpCmdLine[X2], X - X2); - ArgV[C][X - X2] = '\0'; - C++; X2 = X + 1; - } - } - ArgV[C] = NULL; - for (C = 0; ; C++) { - if (ArgV[C] == NULL) break; - printf("--> '%s' \n", ArgV[C]); - } - switch(fork()) { - case -1: - printf("Can't 'fork' process !\n"); - break; - case 0: - printf("New process started !\n"); - execvp(ArgV[0], ArgV); - printf("Child process died !\n"); - exit(1); - break; - default: - printf("Main process stay alive !\n"); - break; - } - for (C = 0; ; C++) { - if (ArgV[C] == NULL) break; - free(ArgV[C]); - } - return(TRUE); + int X, X2, C; + char *ArgV[20]; + printf("WinExec('%s', %04X)\n", lpCmdLine, nCmdShow); + ArgV[0] = "wine"; + C = 1; + for (X = X2 = 0; X < strlen(lpCmdLine) + 1; X++) { + if ((lpCmdLine[X] == ' ') || (lpCmdLine[X] == '\0')) { + ArgV[C] = (char *)malloc(X - X2 + 1); + strncpy(ArgV[C], &lpCmdLine[X2], X - X2); + ArgV[C][X - X2] = '\0'; + C++; X2 = X + 1; + } + } + ArgV[C] = NULL; + for (C = 0; ; C++) { + if (ArgV[C] == NULL) break; + printf("--> '%s' \n", ArgV[C]); + } + switch(fork()) { + case -1: + printf("Can't 'fork' process !\n"); + break; + case 0: + printf("New process started !\n"); + execvp(ArgV[0], ArgV); + printf("Child process died !\n"); + exit(1); + break; + default: + printf("Main process stay alive !\n"); + break; + } + for (C = 0; ; C++) { + if (ArgV[C] == NULL) break; + free(ArgV[C]); + } + return(TRUE); } BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData) { - char *ArgV[6]; - char str[32]; - printf("WinHelp(%s, %u, %lu)\n", lpHelpFile, wCommand, dwData); - switch(fork()) { - case -1: - printf("Can't 'fork' process !\n"); - break; - case 0: - printf("New process started !\n"); - ArgV[0] = "wine"; - ArgV[1] = "winhelp.exe"; - ArgV[2] = lpHelpFile; - switch (wCommand) { - case HELP_CONTEXT: - case HELP_KEY: - case HELP_SETINDEX: - sprintf(str, "%lu", dwData); - ArgV[3] = str; - default: - ArgV[3] = NULL; - } - ArgV[4] = NULL; - if (wCommand == HELP_HELPONHELP) ArgV[2] = NULL; -/* - _WinMain(ArgV, 2); -*/ - execvp(ArgV[0], ArgV); - printf("Child process died !\n"); - exit(1); - break; - default: - printf("Main process stay alive !\n"); - break; - } -return(TRUE); + char str[256]; + printf("WinHelp(%s, %u, %lu)\n", lpHelpFile, wCommand, dwData); + switch(wCommand) { + case 0: + case HELP_HELPONHELP: + GetWindowsDirectory(str, sizeof(str)); + strcat(str, "\\winhelp.exe"); + printf("'%s'\n", str); + break; + case HELP_INDEX: + GetWindowsDirectory(str, sizeof(str)); + strcat(str, "\\winhelp.exe"); + printf("'%s'\n", str); + break; + default: + return FALSE; + } + WinExec(str, SW_SHOWNORMAL); + return(TRUE); } diff --git a/misc/file.c b/misc/file.c index de8a7e29a36..5d41f1cb929 100644 --- a/misc/file.c +++ b/misc/file.c @@ -19,16 +19,16 @@ #define DEBUG_FILE -#include #include #include #include #include +#include +#include #include "prototypes.h" char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256]; - /*************************************************************************** _lopen @@ -40,12 +40,12 @@ int _lopen (LPSTR lpPathName, int iReadWrite) char *UnixFileName; #ifdef DEBUG_FILE - fprintf (stderr, "_lopen: open %s\n", lpPathName); + fprintf (stderr, "_lopen: open('%s', %X);\n", lpPathName, iReadWrite); #endif if ((UnixFileName = GetUnixFileName(lpPathName)) == NULL) return HFILE_ERROR; - + iReadWrite &= 0x000F; handle = open (UnixFileName, iReadWrite); #ifdef DEBUG_FILE @@ -67,7 +67,7 @@ WORD _lread (int hFile, LPSTR lpBuffer, int wBytes) #ifdef DEBUG_FILE fprintf(stderr, "_lread: handle %d, buffer = %ld, length = %d\n", - hFile, lpBuffer, wBytes); + hFile, (int) lpBuffer, wBytes); #endif result = read (hFile, lpBuffer, wBytes); @@ -87,7 +87,7 @@ WORD _lwrite (int hFile, LPSTR lpBuffer, int wBytes) #ifdef DEBUG_FILE fprintf(stderr, "_lwrite: handle %d, buffer = %ld, length = %d\n", - hFile, lpBuffer, wBytes); + hFile, (int) lpBuffer, wBytes); #endif result = write (hFile, lpBuffer, wBytes); @@ -103,10 +103,12 @@ WORD _lwrite (int hFile, LPSTR lpBuffer, int wBytes) int _lclose (int hFile) { #ifdef DEBUG_FILE - fprintf(stderr, "_lclose: handle %d\n", hFile); + fprintf(stderr, "_lclose: handle %d\n", hFile); #endif - - close (hFile); + if (close (hFile)) + return HFILE_ERROR; + else + return 0; } /************************************************************************** @@ -221,12 +223,12 @@ UINT GetDriveType(int drive) #endif if (!DOS_ValidDrive(drive)) - return 0; + return DRIVE_DOESNOTEXIST; if (drive == 0 || drive == 1) return DRIVE_REMOVABLE; - return DRIVE_REMOTE; + return DRIVE_REMOVABLE; } /*************************************************************************** @@ -254,6 +256,7 @@ UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath) fprintf(stderr,"GetWindowsDirectory (%s)\n",lpszSysPath); #endif + ChopOffSlash(lpszSysPath); return(strlen(lpszSysPath)); } /*************************************************************************** @@ -270,6 +273,7 @@ UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath) fprintf(stderr,"GetSystemDirectory (%s)\n",lpszSysPath); #endif + ChopOffSlash(lpszSysPath); return(strlen(lpszSysPath)); } /*************************************************************************** @@ -288,7 +292,7 @@ int GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LP strcpy(tempname,lpszPrefixString); tempname[3]='\0'; - sprintf(lpszTempFileName,"%s\%s%d.tmp",WindowsDirectory, tempname, + sprintf(lpszTempFileName,"%s\\%s%d.tmp",WindowsDirectory, tempname, unique); ToDos(lpszTempFileName); @@ -308,3 +312,52 @@ WORD SetErrorMode(WORD x) { fprintf(stderr,"wine: SetErrorMode %4x (ignored)\n",x); } + +/*************************************************************************** + _hread + ***************************************************************************/ +long _hread(int hf, void FAR *hpvBuffer, long cbBuffer) +{ + long dataread = 0; + size_t status, size; + + while (cbBuffer) + { + size = cbBuffer < 30000 ? cbBuffer : 30000; + + status = read(hf, hpvBuffer, size); + if (status == -1) + return HFILE_ERROR; + if (status == 0) + return dataread; + + dataread += status; + hpvBuffer += status; + cbBuffer -= status; + } + return dataread; +} +/*************************************************************************** + _hwrite + ***************************************************************************/ +long _hwrite(int hf, const void FAR *hpvBuffer, long cbBuffer) +{ + long datawritten = 0; + size_t status, size; + + while (cbBuffer) + { + size = cbBuffer < 30000 ? cbBuffer : 30000; + + status = write(hf, hpvBuffer, size); + if (status == -1) + return HFILE_ERROR; + if (status == 0) + return datawritten; + + datawritten += status; + hpvBuffer += status; + cbBuffer -= status; + } + return datawritten; +} diff --git a/misc/keyboard.c b/misc/keyboard.c index cc4b01740b8..178a74fbc6c 100644 --- a/misc/keyboard.c +++ b/misc/keyboard.c @@ -1,6 +1,8 @@ static char RCSId[] = "$Id: keyboard.c,v 1.2 1993/09/13 18:52:02 scott Exp $"; static char Copyright[] = "Copyright Scott A. Laird, 1993"; +#include +#include #include "prototypes.h" #include "windows.h" diff --git a/misc/lstr.c b/misc/lstr.c index bd30f8804cb..cec274838ea 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -6,6 +6,7 @@ static char Copyright[] = "Copyright Yngvi Sigurjonsson (yngvi@hafro.is), 1993" #include #include #include +#include #include "prototypes.h" #include "regfunc.h" diff --git a/misc/main.c b/misc/main.c index 59bd197139e..c98b72381a3 100644 --- a/misc/main.c +++ b/misc/main.c @@ -7,24 +7,36 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #include +#include +#include #include #include - +#include +#include +#include "msdos.h" #include "windows.h" #include "options.h" +#include "prototypes.h" +#define WINE_CLASS "Wine" /* Class name for resources */ Display * XT_display; /* To be removed */ Screen * XT_screen; /* To be removed */ -Display * display; -Screen * screen; +Display *display; +Screen *screen; +Window rootWindow; +int screenWidth = 0, screenHeight = 0; /* Desktop window dimensions */ +int screenDepth = 0; /* Screen depth to use */ +int desktopX = 0, desktopY = 0; /* Desktop window position (if any) */ char *ProgramName; /* Used by resource.c with WINELIB */ struct options Options = { /* default options */ NULL, /* spyFilename */ + NULL, /* desktopGeometry */ + NULL, /* programName */ FALSE, /* usePrivateMap */ FALSE, /* synchronous */ SW_SHOWNORMAL, /* cmdShow */ @@ -34,8 +46,11 @@ struct options Options = static XrmOptionDescRec optionsTable[] = { + { "-desktop", ".desktop", XrmoptionSepArg, (caddr_t)NULL }, + { "-depth", ".depth", XrmoptionSepArg, (caddr_t)NULL }, { "-display", ".display", XrmoptionSepArg, (caddr_t)NULL }, { "-iconic", ".iconic", XrmoptionNoArg, (caddr_t)"on" }, + { "-name", ".name", XrmoptionSepArg, (caddr_t)NULL }, { "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" }, { "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" }, { "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL }, @@ -44,19 +59,78 @@ static XrmOptionDescRec optionsTable[] = #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0])) +#define USAGE \ + "Usage: %s [options] program_name [arguments]\n" \ + "\n" \ + "Options:\n" \ + " -depth n Change the depth to use for multiple-depth screens\n" \ + " -desktop geom Use a desktop window of the given geometry\n" \ + " -display name Use the specified display\n" \ + " -iconic Start as an icon\n" \ + " -name name Set the application name\n" \ + " -privatemap Use a private color map\n" \ + " -synchronous Turn on synchronous display mode\n" \ + " -spy file Turn on message spying to the specified file\n" \ + " -relaydbg Display call relay information\n" + /*********************************************************************** * MAIN_Usage */ static void MAIN_Usage( char *name ) { - fprintf( stderr,"Usage: %s [-display name] [-iconic] [-privatemap]\n" - " [-synchronous] [-spy file] program [arguments]\n", - name ); + fprintf( stderr, USAGE, name ); exit(1); } +/*********************************************************************** + * MAIN_GetProgramName + * + * Get the program name. The name is specified by (in order of precedence): + * - the option '-name'. + * - the environment variable 'WINE_NAME'. + * - the last component of argv[0]. + */ +static char *MAIN_GetProgramName( int argc, char *argv[] ) +{ + int i; + char *p; + + for (i = 1; i < argc-1; i++) + if (!strcmp( argv[i], "-name" )) return argv[i+1]; + if ((p = getenv( "WINE_NAME" )) != NULL) return p; + if ((p = strrchr( argv[0], '/' )) != NULL) return p+1; + return argv[0]; +} + + +/*********************************************************************** + * MAIN_GetResource + * + * Fetch the value of resource 'name' using the correct instance name. + * 'name' must begin with '.' or '*' + */ +static int MAIN_GetResource( XrmDatabase db, char *name, XrmValue *value ) +{ + char *buff_instance, *buff_class; + char *dummy; + int retval; + + buff_instance = (char *)malloc(strlen(Options.programName)+strlen(name)+1); + buff_class = (char *)malloc( strlen(WINE_CLASS) + strlen(name) + 1 ); + + strcpy( buff_instance, Options.programName ); + strcat( buff_instance, name ); + strcpy( buff_class, WINE_CLASS ); + strcat( buff_class, name ); + retval = XrmGetResource( db, buff_instance, buff_class, &dummy, value ); + free( buff_instance ); + free( buff_class ); + return retval; +} + + /*********************************************************************** * MAIN_ParseOptions * @@ -64,18 +138,25 @@ static void MAIN_Usage( char *name ) */ static void MAIN_ParseOptions( int *argc, char *argv[] ) { - char *dummy, *display_name; + char *display_name; XrmValue value; XrmDatabase db = NULL; - XrmParseCommand( &db, optionsTable, NB_OPTIONS, "wine", argc, argv ); + /* Parse command line */ + + Options.programName = MAIN_GetProgramName( *argc, argv ); + XrmParseCommand( &db, optionsTable, NB_OPTIONS, + Options.programName, argc, argv ); #ifdef WINELIB /* Need to assemble command line and pass it to WinMain */ #else - if (*argc < 2) MAIN_Usage( argv[0] ); + if (*argc < 2 || strcasecmp(argv[1], "-h") == 0) + MAIN_Usage( argv[0] ); #endif - if (XrmGetResource( db, "wine.display", "Wine.display", &dummy, &value )) - display_name = value.addr; + + /* Open display */ + + if (MAIN_GetResource( db, ".display", &value )) display_name = value.addr; else display_name = NULL; if (!(display = XOpenDisplay( display_name ))) @@ -85,50 +166,98 @@ static void MAIN_ParseOptions( int *argc, char *argv[] ) exit(1); } - if (XrmGetResource(db,"wine.iconic","Wine.iconic",&dummy,&value)) + /* Get all options */ + + if (MAIN_GetResource( db, ".iconic", &value )) Options.cmdShow = SW_SHOWMINIMIZED; - if (XrmGetResource(db,"wine.privatemap","Wine.privatemap",&dummy,&value)) + if (MAIN_GetResource( db, ".privatemap", &value )) Options.usePrivateMap = TRUE; - if (XrmGetResource(db,"wine.synchronous","Wine.synchronous",&dummy,&value)) + if (MAIN_GetResource( db, ".synchronous", &value )) Options.synchronous = TRUE; - if (XrmGetResource(db,"wine.relaydbg","Wine.relaydbg",&dummy,&value)) + if (MAIN_GetResource( db, ".relaydbg", &value )) Options.relay_debug = TRUE; - if (XrmGetResource(db,"wine.spy","Wine.spy",&dummy,&value)) + if (MAIN_GetResource( db, ".spy", &value)) Options.spyFilename = value.addr; + if (MAIN_GetResource( db, ".depth", &value)) + screenDepth = atoi( value.addr ); + if (MAIN_GetResource( db, ".desktop", &value)) + Options.desktopGeometry = value.addr; } /*********************************************************************** - * main + * MAIN_CreateDesktop */ -int main( int argc, char *argv[] ) -{ - int ret_val; - XKeyboardState keyboard_state; - XKeyboardControl keyboard_value; - - XrmInitialize(); - - MAIN_ParseOptions( &argc, argv ); +static void MAIN_CreateDesktop( int argc, char *argv[] ) +{ + int flags; + unsigned int width = 640, height = 480; /* Default size = 640x480 */ + char *name = "Wine desktop"; + XSizeHints size_hints; + XWMHints wm_hints; + XClassHint class_hints; + XSetWindowAttributes win_attr; + XTextProperty window_name; - screen = DefaultScreenOfDisplay( display ); - XT_display = display; - XT_screen = screen; - if (Options.synchronous) XSynchronize( display, True ); + flags = XParseGeometry( Options.desktopGeometry, + &desktopX, &desktopY, &width, &height ); + screenWidth = width; + screenHeight = height; + /* Create window */ + + win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | + ButtonReleaseMask | EnterWindowMask | + StructureNotifyMask; + win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow ); + + rootWindow = XCreateWindow( display, DefaultRootWindow(display), + desktopX, desktopY, width, height, 0, + CopyFromParent, InputOutput, CopyFromParent, + CWEventMask | CWCursor, &win_attr ); + + /* Set window manager properties */ + + size_hints.min_width = size_hints.max_width = width; + size_hints.min_height = size_hints.max_height = height; + size_hints.flags = PMinSize | PMaxSize; + if (flags & (XValue | YValue)) size_hints.flags |= USPosition; + if (flags & (WidthValue | HeightValue)) size_hints.flags |= USSize; + else size_hints.flags |= PSize; + + wm_hints.flags = InputHint | StateHint; + wm_hints.input = True; + wm_hints.initial_state = NormalState; + class_hints.res_name = argv[0]; + class_hints.res_class = "Wine"; + + XStringListToTextProperty( &name, 1, &window_name ); + XSetWMProperties( display, rootWindow, &window_name, &window_name, + argv, argc, &size_hints, &wm_hints, &class_hints ); + + /* Map window */ + + XMapWindow( display, rootWindow ); +} + + +XKeyboardState keyboard_state; + +/*********************************************************************** + * MAIN_SaveSetup + */ +static void MAIN_SaveSetup(void) +{ XGetKeyboardControl(display, &keyboard_state); +} - ProgramName = argv [0]; - DOS_InitFS(); - Comm_Init(); - - ret_val = _WinMain( argc, argv ); - - Comm_DeInit (); - DOS_DeInitFS (); - sync_profiles (); - - /* restore sounds/keyboard settings */ +/*********************************************************************** + * MAIN_RestoreSetup + */ +static void MAIN_RestoreSetup(void) +{ + XKeyboardControl keyboard_value; keyboard_value.key_click_percent = keyboard_state.key_click_percent; keyboard_value.bell_percent = keyboard_state.bell_percent; @@ -138,6 +267,65 @@ int main( int argc, char *argv[] ) XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value); +} + +static void called_at_exit(void) +{ + Comm_DeInit(); + sync_profiles(); + MAIN_RestoreSetup(); +} + +/*********************************************************************** + * main + */ +int main( int argc, char *argv[] ) +{ + int ret_val; + int depth_count, i; + int *depth_list; + + XrmInitialize(); + + MAIN_ParseOptions( &argc, argv ); + + screen = DefaultScreenOfDisplay( display ); + screenWidth = WidthOfScreen( screen ); + screenHeight = HeightOfScreen( screen ); + XT_display = display; + XT_screen = screen; + if (screenDepth) /* -depth option specified */ + { + depth_list = XListDepths(display,DefaultScreen(display),&depth_count); + for (i = 0; i < depth_count; i++) + if (depth_list[i] == screenDepth) break; + XFree( depth_list ); + if (i >= depth_count) + { + fprintf( stderr, "%s: Depth %d not supported on this screen.\n", + Options.programName, screenDepth ); + exit(1); + } + } + else screenDepth = DefaultDepthOfScreen( screen ); + if (Options.synchronous) XSynchronize( display, True ); + if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv ); + else rootWindow = DefaultRootWindow( display ); + + ProgramName = argv [0]; + MAIN_SaveSetup(); + DOS_InitFS(); + Comm_Init(); + +#ifndef sun + atexit(called_at_exit); +#endif + + ret_val = _WinMain( argc, argv ); + +#ifdef sunos + called_at_exit(); +#endif return ret_val; } @@ -145,7 +333,7 @@ int main( int argc, char *argv[] ) /*********************************************************************** * MessageBeep (USER.104) */ -void MessageBeep( WORD i ) +void MessageBeep(WORD i) { XBell(display, 100); } @@ -155,7 +343,7 @@ void MessageBeep( WORD i ) */ LONG GetVersion(void) { - return (0x04001003); /* dos version 4.00, win ver 3.1 */ + return( 0x03300a03 ); /* dos 3.30 & win 3.10 */ } /*********************************************************************** @@ -179,9 +367,12 @@ LONG GetTimerResolution(void) */ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT fuWinIni) { + int timeout, temp; + char buffer[256]; XKeyboardState keyboard_state; XKeyboardControl keyboard_value; + fprintf(stderr, "SystemParametersInfo: action %d, param %x, flag %x\n", uAction, uParam, fuWinIni); @@ -195,7 +386,7 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT f break; case SPI_GETBORDER: - *(int *) lpvParam = 1; + *(INT *) lpvParam = 1; break; case SPI_GETFASTTASKSWITCH: @@ -203,7 +394,7 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT f break; case SPI_GETGRIDGRANULARITY: - *(int *) lpvParam = 1; + *(INT *) lpvParam = 1; break; case SPI_GETICONTITLEWRAP: @@ -211,7 +402,7 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT f break; case SPI_GETKEYBOARDDELAY: - *(int *) lpvParam = 1; + *(INT *) lpvParam = 1; break; case SPI_GETKEYBOARDSPEED: @@ -223,25 +414,26 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT f break; case SPI_GETSCREENSAVEACTIVE: - *(WORD *) lpvParam = FALSE; + *(BOOL *) lpvParam = FALSE; break; case SPI_GETSCREENSAVETIMEOUT: - *(int *) lpvParam = 0; + XGetScreenSaver(display, &timeout, &temp,&temp,&temp); + *(INT *) lpvParam = timeout * 1000; break; case SPI_ICONHORIZONTALSPACING: if (lpvParam == NULL) fprintf(stderr, "SystemParametersInfo: Horizontal icon spacing set to %d\n.", uParam); else - *(int *) lpvParam = 50; + *(INT *) lpvParam = 50; break; case SPI_ICONVERTICALSPACING: if (lpvParam == NULL) fprintf(stderr, "SystemParametersInfo: Vertical icon spacing set to %d\n.", uParam); else - *(int *) lpvParam = 50; + *(INT *) lpvParam = 50; break; case SPI_SETBEEP: @@ -265,10 +457,22 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT f DefaultExposures); break; + case SPI_SETDESKWALLPAPER: + return (SetDeskWallPaper((LPSTR) lpvParam)); + break; + + case SPI_SETDESKPATTERN: + if ((INT) uParam == -1) { + GetProfileString("Desktop", "Pattern", + "170 85 170 85 170 85 170 85", + buffer, sizeof(buffer) ); + return (DESKTOP_SetPattern((LPSTR) buffer)); + } else + return (DESKTOP_SetPattern((LPSTR) lpvParam)); + break; + case SPI_LANGDRIVER: case SPI_SETBORDER: - case SPI_SETDESKPATTERN: - case SPI_SETDESKWALLPAPER: case SPI_SETDOUBLECLKHEIGHT: case SPI_SETDOUBLECLICKTIME: case SPI_SETDOUBLECLKWIDTH: @@ -280,7 +484,33 @@ BOOL SystemParametersInfo (UINT uAction, UINT uParam, void FAR *lpvParam, UINT f default: fprintf(stderr, "SystemParametersInfo: unknown option %d.\n", uParam); - break; + break; } return 1; } + +/*********************************************************************** +* HMEMCPY (KERNEL.348) +*/ +void hmemcpy(void FAR *hpvDest, const void FAR *hpvSource, long cbCopy) +{ + size_t copysize; + + while (cbCopy) + { + copysize = cbCopy < 30000 ? cbCopy : 30000; + + memcpy(hpvDest, hpvSource, copysize); + hpvDest += copysize; + hpvSource += copysize; + cbCopy -= copysize; + } +} + +/*********************************************************************** +* COPY (GDI.250) +*/ +void Copy(LPVOID lpSource, LPVOID lpDest, WORD nBytes) +{ + memcpy(lpDest, lpSource, nBytes); +} diff --git a/misc/message.c b/misc/message.c index 79a49f7f40b..57428e7faf4 100644 --- a/misc/message.c +++ b/misc/message.c @@ -8,6 +8,9 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #define DEBUG_MSGBOX +#include +#include +#include #include #include #include @@ -43,53 +46,55 @@ LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type) { - HWND hDlg; - WND *wndPtr; - WNDCLASS wndClass; - MSG msg; - MSGBOX mb; - DWORD dwStyle; - HINSTANCE hInst; - wndPtr = WIN_FindWndPtr(hWnd); + HWND hDlg, hWndOld; + WND *wndPtr; + WNDCLASS wndClass; + MSG msg; + MSGBOX mb; + DWORD dwStyle; + HINSTANCE hInst; + wndPtr = WIN_FindWndPtr(hWnd); #ifdef DEBUG_MSGBOX - printf( "MessageBox: '%s'\n", str ); + printf( "MessageBox: '%s'\n", str ); #endif - if (wndPtr == NULL) + if (wndPtr == NULL) hInst = hSysRes; - else + else hInst = wndPtr->hInstance; - wndClass.style = CS_HREDRAW | CS_VREDRAW ; - wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = hInst; - wndClass.hIcon = (HICON)NULL; - wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); - wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); - wndClass.lpszMenuName = NULL; - wndClass.lpszClassName = "MESSAGEBOX"; - if (!RegisterClass(&wndClass)) return 0; - memset(&mb, 0, sizeof(MSGBOX)); - mb.Title = title; - mb.Str = str; - mb.wType = type; - mb.ActiveFlg = TRUE; - dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE; - if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION; - hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120, - (HWND)NULL, (HMENU)NULL, hInst, (LPSTR)&mb); - if (hDlg == 0) return 0; - while(TRUE) { - if (!mb.ActiveFlg) break; - if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - if (!UnregisterClass("MESSAGEBOX", hInst)) return 0; + wndClass.style = CS_HREDRAW | CS_VREDRAW ; + wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = hInst; + wndClass.hIcon = (HICON)NULL; + wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); + wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); + wndClass.lpszMenuName = NULL; + wndClass.lpszClassName = "MESSAGEBOX"; + if (!RegisterClass(&wndClass)) return 0; + memset(&mb, 0, sizeof(MSGBOX)); + mb.Title = title; + mb.Str = str; + mb.wType = type; + mb.ActiveFlg = TRUE; + dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE; + if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION; + hWndOld = GetFocus(); + hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120, + (HWND)NULL, (HMENU)NULL, hInst, (LPSTR)&mb); + if (hDlg == 0) return 0; + while(TRUE) { + if (!mb.ActiveFlg) break; + if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + SetFocus(hWndOld); + if (!UnregisterClass("MESSAGEBOX", hInst)) return 0; #ifdef DEBUG_MSGBOX - printf( "MessageBox return %04X !\n", mb.wRetVal); + printf( "MessageBox return %04X !\n", mb.wRetVal); #endif - return(mb.wRetVal); + return(mb.wRetVal); } LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd) @@ -110,113 +115,113 @@ LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd) LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) { - WND *wndPtr; - CREATESTRUCT *createStruct; - PAINTSTRUCT ps; - HDC hDC; - RECT rect; - LPMSGBOX lpmb; - LPMSGBOX lpmbInit; - BITMAP bm; - HBITMAP hBitMap; - HDC hMemDC; - HICON hIcon; - HINSTANCE hInst2; - int x; - switch(message) { + WND *wndPtr; + CREATESTRUCT *createStruct; + PAINTSTRUCT ps; + HDC hDC; + RECT rect; + LPMSGBOX lpmb; + LPMSGBOX lpmbInit; + BITMAP bm; + HBITMAP hBitMap; + HDC hMemDC; + HICON hIcon; + HINSTANCE hInst2; + int x; + switch(message) { case WM_CREATE: #ifdef DEBUG_MSGBOX - printf("MessageBox WM_CREATE !\n"); + printf("MessageBox WM_CREATE !\n"); #endif - wndPtr = WIN_FindWndPtr(hWnd); - createStruct = (CREATESTRUCT *)lParam; - lpmbInit = (LPMSGBOX)createStruct->lpCreateParams; - if (lpmbInit == 0) break; - *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit; - lpmb = MsgBoxGetStorageHeader(hWnd); - GetClientRect(hWnd, &rect); - CopyRect(&lpmb->rectStr, &rect); - lpmb->rectStr.bottom -= 32; - switch(lpmb->wType & MB_TYPEMASK) { + wndPtr = WIN_FindWndPtr(hWnd); + createStruct = (CREATESTRUCT *)lParam; + lpmbInit = (LPMSGBOX)createStruct->lpCreateParams; + if (lpmbInit == 0) break; + *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit; + lpmb = MsgBoxGetStorageHeader(hWnd); + GetClientRect(hWnd, &rect); + CopyRect(&lpmb->rectStr, &rect); + lpmb->rectStr.bottom -= 32; + switch(lpmb->wType & MB_TYPEMASK) { case MB_OK : - lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 30, rect.bottom - 25, - 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L); - break; + lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 30, rect.bottom - 25, + 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L); + break; case MB_OKCANCEL : - lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 65, rect.bottom - 25, - 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L); - lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 5, rect.bottom - 25, - 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L); - break; + lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 65, rect.bottom - 25, + 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L); + lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 5, rect.bottom - 25, + 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L); + break; case MB_ABORTRETRYIGNORE : - lpmb->hWndYes = CreateWindow("BUTTON", "&Retry", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 100, rect.bottom - 25, - 60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L); - lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 30, rect.bottom - 25, - 60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L); - lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 40, rect.bottom - 25, - 60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L); - break; + lpmb->hWndYes = CreateWindow("BUTTON", "&Retry", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 100, rect.bottom - 25, + 60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L); + lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 30, rect.bottom - 25, + 60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L); + lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 40, rect.bottom - 25, + 60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L); + break; case MB_YESNO : - lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 65, rect.bottom - 25, - 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L); - lpmb->hWndNo = CreateWindow("BUTTON", "&No", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 5, rect.bottom - 25, - 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L); - break; + lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 65, rect.bottom - 25, + 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L); + lpmb->hWndNo = CreateWindow("BUTTON", "&No", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 5, rect.bottom - 25, + 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L); + break; case MB_YESNOCANCEL : - lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 100, rect.bottom - 25, - 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L); - lpmb->hWndNo = CreateWindow("BUTTON", "&No", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 30, rect.bottom - 25, - 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L); - lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 40, rect.bottom - 25, - 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L); - break; + lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 100, rect.bottom - 25, + 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L); + lpmb->hWndNo = CreateWindow("BUTTON", "&No", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 - 30, rect.bottom - 25, + 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L); + lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, + rect.right / 2 + 40, rect.bottom - 25, + 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L); + break; } switch(lpmb->wType & MB_ICONMASK) { case MB_ICONEXCLAMATION: - printf("MsgBox LoadIcon Exclamation !\n"); - lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); - break; + printf("MsgBox LoadIcon Exclamation !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); + break; case MB_ICONQUESTION: - printf("MsgBox LoadIcon Question !\n"); - lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION); - break; + printf("MsgBox LoadIcon Question !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION); + break; case MB_ICONASTERISK: - printf("MsgBox LoadIcon Asterisk !\n"); - lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK); - break; + printf("MsgBox LoadIcon Asterisk !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK); + break; case MB_ICONHAND: - printf("MsgBox LoadIcon Hand !\n"); - lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND); - break; - } + printf("MsgBox LoadIcon Hand !\n"); + lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND); + break; + } if (lpmb->hIcon != (HICON)NULL) { - SetRect(&lpmb->rectIcon, 16, - lpmb->rectStr.bottom / 2 - 16, 48, - lpmb->rectStr.bottom / 2 + 16); - lpmb->rectStr.left += 64; - } + SetRect(&lpmb->rectIcon, 16, + lpmb->rectStr.bottom / 2 - 16, 48, + lpmb->rectStr.bottom / 2 + 16); + lpmb->rectStr.left += 64; + } break; case WM_PAINT: #ifdef DEBUG_MSGBOX @@ -259,6 +264,37 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) #endif PostMessage(hWnd, WM_CLOSE, 0, 0L); break; + case WM_CHAR: + lpmb = MsgBoxGetStorageHeader(hWnd); + if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A'; + switch(wParam) { + case 'Y': + lpmb->wRetVal = IDYES; + break; + case 'O': + lpmb->wRetVal = IDOK; + break; + case 'R': + lpmb->wRetVal = IDRETRY; + break; + case 'A': + lpmb->wRetVal = IDABORT; + break; + case 'N': + lpmb->wRetVal = IDNO; + break; + case 'I': + lpmb->wRetVal = IDIGNORE; + break; + case 'C': + case VK_ESCAPE: + lpmb->wRetVal = IDCANCEL; + break; + default: + return 0; + } + PostMessage(hWnd, WM_CLOSE, 0, 0L); + break; default: return DefWindowProc(hWnd, message, wParam, lParam ); } diff --git a/misc/profile.c b/misc/profile.c index f150c9c4bee..377924ade21 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -14,9 +14,12 @@ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; #include +#include #include -#include "windows.h" + #include "wine.h" +#include "windows.h" +#include "prototypes.h" /* #define DEBUG */ @@ -121,12 +124,18 @@ static TSecHeader *load (char *file) } if (state == FirstBrace) /* On first pass, don't allow dangling keys */ break; - + if (c == ' ' || c == '\t') break; if (c == '\n' || c == ';' || overflow) /* Abort Definition */ next = CharBuffer; + + if (c == ';') + { + state = IgnoreToEOL; + break; + } if (c == '=' || overflow){ TKeys *temp; @@ -165,7 +174,7 @@ static TSecHeader *load (char *file) return SecHeader; } -static new_key (TSecHeader *section, char *KeyName, char *Value) +static void new_key (TSecHeader *section, char *KeyName, char *Value) { TKeys *key; diff --git a/misc/rect.c b/misc/rect.c index cbb2281f347..b5c0fc5acd7 100644 --- a/misc/rect.c +++ b/misc/rect.c @@ -150,6 +150,12 @@ BOOL EqualRect( LPRECT rect1, LPRECT rect2 ) BOOL SubtractRect( LPRECT dest, LPRECT src1, LPRECT src2 ) { RECT tmp; + + if (IsRectEmpty( src1 )) + { + SetRectEmpty( dest ); + return FALSE; + } *dest = *src1; if (IntersectRect( &tmp, src1, src2 )) { @@ -160,13 +166,13 @@ BOOL SubtractRect( LPRECT dest, LPRECT src1, LPRECT src2 ) } if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom)) { - if (tmp.left == dest->left) dest->right = tmp.right; - else if (tmp.right == dest->right) dest->left = tmp.left; + if (tmp.left == dest->left) dest->left = tmp.right; + else if (tmp.right == dest->right) dest->right = tmp.left; } else if ((tmp.left == dest->left) && (tmp.right == dest->right)) { - if (tmp.top == dest->top) dest->bottom = tmp.bottom; - else if (tmp.bottom == dest->bottom) dest->top = tmp.top; + if (tmp.top == dest->top) dest->top = tmp.bottom; + else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top; } } return TRUE; diff --git a/misc/sound.c b/misc/sound.c index 90e9c7dc1b8..c976a9788da 100644 --- a/misc/sound.c +++ b/misc/sound.c @@ -1,6 +1,8 @@ static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +#include +#include #include "prototypes.h" int OpenSound(void) diff --git a/misc/spy.c b/misc/spy.c index 86e5791844f..bfc0042d89d 100644 --- a/misc/spy.c +++ b/misc/spy.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "wineopts.h" #include "windows.h" #include "wine.h" @@ -14,7 +15,7 @@ #ifndef NOSPY -#define SPY_MAX_MSGNUM 0x0210 +#define SPY_MAX_MSGNUM 0x0232 const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = { @@ -92,7 +93,9 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_NCCREATE", /* 0x0081 */ "WM_NCDESTROY", /* 0x0082 */ "WM_NCCALCSIZE", /* 0x0083 */ - NULL, NULL, NULL, + "WM_NCHITTEST", /* 0x0084 */ + "WM_NCPAINT", /* 0x0085 */ + "WM_NCACTIVATE", /* 0x0086 */ "WM_GETDLGCODE", /* 0x0087 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -135,9 +138,9 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_KEYLAST", /* 0x0108 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "WM_INITDIALOG", /* 0x0110 */ + "WM_INITDIALOG", /* 0x0110 */ "WM_COMMAND", /* 0x0111 */ - NULL, + "WM_SYSCOMMAND", /* 0x0112 */ "WM_TIMER", /* 0x0113 */ "WM_HSCROLL", /* 0x0114 */ "WM_VSCROLL", /* 0x0115 */ @@ -211,9 +214,26 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_MBUTTONDOWN", /* 0x0207 */ "WM_MBUTTONUP", /* 0x0208 */ "WM_MBUTTONDBLCLK", /* 0x0209 */ + NULL, NULL, NULL, NULL, NULL, NULL, + "WM_PARENTNOTIFY", /* 0x0210 */ + + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /* 0x0220 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + + NULL, /* 0x0230 */ + "WM_ENTERSIZEMOVE", /* 0x0231 */ + "WM_EXITSIZEMOVE" /* 0x0232 */ }; +char SpyFilters[256]; +char SpyIncludes[256]; + #endif /* NOSPY */ /********************************************************************** @@ -222,18 +242,24 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = void SpyMessage(HWND hwnd, WORD msg, WORD wParam, LONG lParam) { #ifndef NOSPY + char msg_name[80]; + if (SpyFp == NULL) return; if (msg > SPY_MAX_MSGNUM || MessageTypeNames[msg] == NULL) - { - fprintf(SpyFp, "%04.4x %04.4x %04.4x %08.8x\n", - hwnd, msg, wParam, lParam); - } + msg_name[0] = '\0'; else + strcpy(msg_name, MessageTypeNames[msg]); + + strcat(msg_name, ";"); + + if ((strlen(SpyIncludes) == 0 || strstr(SpyIncludes, msg_name) != NULL) && + strstr(SpyFilters, msg_name) == NULL) { - fprintf(SpyFp, "%04.4x %20.20s %04.4x %08.8x\n", - hwnd, MessageTypeNames[msg], wParam, lParam); + msg_name[strlen(msg_name) - 1] = '\0'; + fprintf(SpyFp, "%04.4x %20.20s %04.4x %04.4x %08.8x\n", + hwnd, msg_name, msg, wParam, lParam); } #endif } @@ -245,7 +271,7 @@ void SpyInit(void) { char filename[100]; - if (SpyFp == NULL) + if (SpyFp != NULL) return; if (Options.spyFilename == NULL) @@ -261,5 +287,13 @@ void SpyInit(void) else if (strlen(filename)) SpyFp = fopen(filename, "a"); else + { SpyFp = NULL; + return; + } + + GetPrivateProfileString("spy", "exclude", "", SpyFilters, + sizeof(SpyFilters), WINE_INI); + GetPrivateProfileString("spy", "include", "", SpyIncludes, + sizeof(SpyIncludes), WINE_INI); } diff --git a/misc/stress.c b/misc/stress.c new file mode 100644 index 00000000000..2b748b78c2a --- /dev/null +++ b/misc/stress.c @@ -0,0 +1,109 @@ +#include +#include +#include "windows.h" +#include "stress.h" + +#define STRESS_DEBUG + +int AllocDiskSpace(long lLeft, UINT uDrive) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: AllocDiskSpace %d, %ld\n", uDrive, lLeft); +#endif + + return 1; +} + +int AllocFileHandles(int Left) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: AllocFileHandles %d\n", Left); +#endif + + if (Left < 0) + return -1; + else + return 1; +} + +BOOL AllocGDIMem(UINT uLeft) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: AllocGDIMem %d\n", uLeft); +#endif + + return 1; +} + +BOOL AllocMem(DWORD dwLeft) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: AllocMem %ld\n", dwLeft); +#endif + + return 1; +} + +BOOL AllocUserMem(UINT uContig) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: AllocUserMem %d\n", uContig); +#endif + + return 1; +} + +void FreeAllMem(void) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: FreeAllMem\n"); +#endif +} + +void FreeAllGDIMem(void) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: FreeAllGDIMem\n"); +#endif +} + +void FreeAllUserMem(void) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: FreeAllUserMem\n"); +#endif +} + +void GetFreeAllUserMem(void) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: GetFreeAllUserMem\n"); +#endif +} + +int GetFreeFileHandles(void) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: GetFreeFileHandles\n"); +#endif + +#ifndef OPEN_MAX + return _POSIX_OPEN_MAX +#else + return OPEN_MAX; +#endif +} + +void UnAllocDiskSpace(UINT drive) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: UnAllocDiskSpace %d\n", drive); +#endif +} + +void UnAllocFileHandles(void) +{ +#ifdef STRESS_DEBUG + fprintf(stderr, "stress.dll: GetFreeAllUserMem\n"); +#endif +} diff --git a/misc/user.c b/misc/user.c index 51b94afc241..ed0045b1d96 100644 --- a/misc/user.c +++ b/misc/user.c @@ -17,6 +17,7 @@ MDESC *USER_Heap = NULL; extern BOOL ATOM_Init(); extern BOOL GDI_Init(); extern void SYSMETRICS_Init(); +extern BOOL WIN_CreateDesktopWindow(); #ifndef WINELIB /*********************************************************************** @@ -44,6 +45,11 @@ USER_InitApp(int hInstance) SpyInit(); +#ifndef WINELIB + /* Create USER heap */ + if (!USER_HeapInit()) return 0; +#endif + /* Global atom table initialisation */ if (!ATOM_Init()) return 0; @@ -54,11 +60,6 @@ USER_InitApp(int hInstance) SYSMETRICS_Init(); SYSCOLOR_Init(); -#ifndef WINELIB - /* Create USER heap */ - if (!USER_HeapInit()) return 0; -#endif - /* Create the DCEs */ DCE_Init(); @@ -76,9 +77,14 @@ USER_InitApp(int hInstance) queueSize = GetProfileInt( "windows", "DefaultQueueSize", 8 ); if (!SetMessageQueue( queueSize )) return 0; + /* Create desktop window */ + if (!WIN_CreateDesktopWindow()) return 0; + +#if 1 #ifndef WINELIB /* Initialize DLLs */ InitializeLoadedDLLs(); +#endif #endif return 1; diff --git a/misc/winsocket.c b/misc/winsocket.c index d5483f9f42c..0d520db709e 100644 --- a/misc/winsocket.c +++ b/misc/winsocket.c @@ -1,18 +1,19 @@ /* * based on Windows Sockets 1.1 specs * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT) + * + * (C) 1993,1994 John Brezak, Erik Bos. */ -#include #include +#include #include #include -#if defined(__FreeBSD__) #include -#endif #include #include #include +#include #include "winsock.h" #define DEBUG_WINSOCK @@ -47,12 +48,12 @@ WORD errno_to_wsaerrno(int errno) sys_errlist[errno], errno); #else fprintf(stderr, "winsock: errno_to_wsaerrno translation failure.\n\t: %s (%d)\n", - strerror [errno], errno); + strerror[errno], errno); #endif #else fprintf (stderr, "winsock: errno_to_wsaerrno translation failure.\n"); #endif - break; + return WSAENETDOWN; } } diff --git a/miscemu/Imakefile b/miscemu/Imakefile index dca1f1dbe44..c9c9db8897c 100644 --- a/miscemu/Imakefile +++ b/miscemu/Imakefile @@ -4,8 +4,12 @@ MODULE = miscemu SRCS = \ emulate.c \ + int10.c \ int1a.c \ int21.c \ + int25.c \ + int26.c \ + ioports.c \ kernel.c OBJS = $(SRCS:.c=.o) diff --git a/miscemu/emulate.c b/miscemu/emulate.c index c53aaa9e70e..b43f9f312cd 100644 --- a/miscemu/emulate.c +++ b/miscemu/emulate.c @@ -1,6 +1,8 @@ static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +#include +#include #include "prototypes.h" #include "regfunc.h" @@ -13,9 +15,6 @@ struct Win87EmInfoStruct { unsigned short Unused; }; - - - int WIN87_fpmath() { @@ -49,5 +48,3 @@ WIN87_WinEm87Save(void *pWin87EmSaveArea, int cbWin87EmSaveArea) { printf( "__WinEm87Save(%p,%d)\n",pWin87EmSaveArea,cbWin87EmSaveArea); } - - diff --git a/miscemu/int10.c b/miscemu/int10.c new file mode 100644 index 00000000000..0f932bd4c2f --- /dev/null +++ b/miscemu/int10.c @@ -0,0 +1,36 @@ +#include +#include "msdos.h" +#include "wine.h" + +static void Barf(struct sigcontext_struct *context) +{ + fprintf(stderr, "int10: unknown/not implemented parameters:\n"); + fprintf(stderr, "int10: AX %04x, BX %04x, CX %04x, DX %04x, " + "SI %04x, DI %04x, DS %04x, ES %04x\n", + AX, BX, CX, DX, SI, DI, DS, ES); +} + +int do_int10(struct sigcontext_struct *context) +{ + switch((context->sc_eax >> 8) & 0xff) + { + case 0x0f: + EAX = (EAX & 0xffffff00) | 0x5b; + break; + + case 0x12: + if ((EBX & 0xff) == 0x10) { + EBX = (EBX & 0xffff0000) | 0x0003; + ECX = (ECX & 0xffff0000) | 0x0009; + } + break; + + case 0x1a: + EBX = (EBX & 0xffff0000) | 0x0008; + break; + + default: + Barf(context); + }; + return 1; +} diff --git a/miscemu/int1a.c b/miscemu/int1a.c index addfdbcbb92..0d25a777b15 100644 --- a/miscemu/int1a.c +++ b/miscemu/int1a.c @@ -1,5 +1,6 @@ #include #include +#include "msdos.h" #include "wine.h" #ifdef linux diff --git a/miscemu/int21.c b/miscemu/int21.c index 47368e1f200..350f9e0baf0 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c @@ -1,13 +1,10 @@ #include #include #include -#ifndef __STDC__ -#include -#endif #include #include +#include #include -#include #include #include @@ -15,24 +12,80 @@ #include "regfunc.h" #include "windows.h" #include "wine.h" -#include "int21.h" +#include "msdos.h" +#include "options.h" static char Copyright[] = "copyright Erik Bos, 1993"; WORD ExtendedError, CodePage = 437; BYTE ErrorClass, Action, ErrorLocus; +BYTE *dta; extern char TempDirectory[]; -void Error(int e, int class, int el) +static int Error(int e, int class, int el) { - ExtendedError = e; ErrorClass = class; Action = SA_Ask4Retry; ErrorLocus = el; + ExtendedError = e; + + return e; } -void GetFreeDiskSpace(struct sigcontext_struct *context) +static void Barf(struct sigcontext_struct *context) +{ + fprintf(stderr, "int21: unknown/not implemented parameters:\n"); + fprintf(stderr, "int21: AX %04x, BX %04x, CX %04x, DX %04x, " + "SI %04x, DI %04x, DS %04x, ES %04x\n", + AX, BX, CX, DX, SI, DI, DS, ES); +} + +void ChopOffWhiteSpace(char *string) +{ + int length; + + for (length = strlen(string) ; length ; length--) + if (string[length] == ' ') + string[length] = '\0'; +} + +static void CreateBPB(int drive, BYTE *data) +{ + if (drive > 1) { + setword(data, 512); + data[2] = 2; + setword(&data[3], 0); + data[5] = 2; + setword(&data[6], 240); + setword(&data[8], 64000); + data[0x0a] = 0xf8; + setword(&data[0x0b], 40); + setword(&data[0x0d], 56); + setword(&data[0x0f], 2); + setword(&data[0x11], 0); + setword(&data[0x1f], 800); + data[0x21] = 5; + setword(&data[0x22], 1); + } else { /* 1.44mb */ + setword(data, 512); + data[2] = 2; + setword(&data[3], 0); + data[5] = 2; + setword(&data[6], 240); + setword(&data[8], 2880); + data[0x0a] = 0xf8; + setword(&data[0x0b], 6); + setword(&data[0x0d], 18); + setword(&data[0x0f], 2); + setword(&data[0x11], 0); + setword(&data[0x1f], 80); + data[0x21] = 7; + setword(&data[0x22], 2); + } +} + +static void GetFreeDiskSpace(struct sigcontext_struct *context) { int drive; long size,available; @@ -54,15 +107,15 @@ void GetFreeDiskSpace(struct sigcontext_struct *context) return; } - EAX = (EAX & 0xffff0000L) | SectorsPerCluster; - ECX = (ECX & 0xffff0000L) | SectorSize; + EAX = (EAX & 0xffff0000L) | 4; + ECX = (ECX & 0xffff0000L) | 512; EBX = (EBX & 0xffff0000L) | (available / (CX * AX)); EDX = (EDX & 0xffff0000L) | (size / (CX * AX)); Error (0,0,0); } -void SetDefaultDrive(struct sigcontext_struct *context) +static void SetDefaultDrive(struct sigcontext_struct *context) { int drive; @@ -78,13 +131,13 @@ void SetDefaultDrive(struct sigcontext_struct *context) } } -void GetDefaultDrive(struct sigcontext_struct *context) +static void GetDefaultDrive(struct sigcontext_struct *context) { EAX = (EAX & 0xffffff00L) | DOS_GetDefaultDrive(); Error (0,0,0); } -void GetDriveAllocInfo(struct sigcontext_struct *context) +static void GetDriveAllocInfo(struct sigcontext_struct *context) { int drive; long size, available; @@ -93,8 +146,8 @@ void GetDriveAllocInfo(struct sigcontext_struct *context) drive = EDX & 0xffL; if (!DOS_ValidDrive(drive)) { - EAX = (EAX & 0xffff0000L) | SectorsPerCluster; - ECX = (ECX & 0xffff0000L) | SectorSize; + EAX = (EAX & 0xffff0000L) | 4; + ECX = (ECX & 0xffff0000L) | 512; EDX = (EDX & 0xffff0000L); Error (InvalidDrive, EC_MediaError, EL_Disk); return; @@ -106,8 +159,8 @@ void GetDriveAllocInfo(struct sigcontext_struct *context) return; } - EAX = (EAX & 0xffff0000L) | SectorsPerCluster; - ECX = (ECX & 0xffff0000L) | SectorSize; + EAX = (EAX & 0xffff0000L) | 4; + ECX = (ECX & 0xffff0000L) | 512; EDX = (EDX & 0xffff0000L) | (size / (CX * AX)); mediaID = 0xf0; @@ -117,20 +170,20 @@ void GetDriveAllocInfo(struct sigcontext_struct *context) Error (0,0,0); } -void GetDefDriveAllocInfo(struct sigcontext_struct *context) +static void GetDefDriveAllocInfo(struct sigcontext_struct *context) { EDX = DOS_GetDefaultDrive(); GetDriveAllocInfo(context); } -void GetDrivePB(struct sigcontext_struct *context) +static void GetDrivePB(struct sigcontext_struct *context) { Error (InvalidDrive, EC_MediaError, EL_Disk); EAX = (EAX & 0xffff0000L) | 0xffL; /* I'm sorry but I only got networked drives :-) */ } -void ReadFile(struct sigcontext_struct *context) +static void ReadFile(struct sigcontext_struct *context) { char *ptr; int size; @@ -144,7 +197,7 @@ void ReadFile(struct sigcontext_struct *context) return; } - ptr = (char *) pointer (DS,DX); + ptr = pointer (DS,DX); if (BX == 0) { *ptr = EOF; @@ -182,12 +235,12 @@ void ReadFile(struct sigcontext_struct *context) } } -void WriteFile(struct sigcontext_struct *context) +static void WriteFile(struct sigcontext_struct *context) { char *ptr; int x,size; - ptr = (char *) pointer (DS,DX); + ptr = pointer (DS,DX); if (BX == 0) { Error (InvalidHandle, EC_Unknown, EL_Unknown); @@ -238,9 +291,9 @@ void WriteFile(struct sigcontext_struct *context) } } -void UnlinkFile(struct sigcontext_struct *context) +static void UnlinkFile(struct sigcontext_struct *context) { - if (unlink( GetUnixFileName((char *) pointer(DS,DX)) ) == -1) { + if (unlink( GetUnixFileName( pointer(DS,DX)) ) == -1) { switch (errno) { case EACCES: case EPERM: @@ -267,9 +320,9 @@ void UnlinkFile(struct sigcontext_struct *context) ResetCflag; } -void SeekFile(struct sigcontext_struct *context) +static void SeekFile(struct sigcontext_struct *context) { - int handle, status, fileoffset; + int status, fileoffset; switch (EAX & 0xffL) { case 1: fileoffset = SEEK_CUR; @@ -300,31 +353,82 @@ void SeekFile(struct sigcontext_struct *context) ResetCflag; } -void GetFileAttributes(struct sigcontext_struct *context) +static void GetFileAttributes(struct sigcontext_struct *context) { EAX &= 0xfffff00L; ResetCflag; } -void SetFileAttributes(struct sigcontext_struct *context) +static void SetFileAttributes(struct sigcontext_struct *context) { ResetCflag; } -void DosIOCTL(struct sigcontext_struct *context) +static void ioctlGetDeviceInfo(struct sigcontext_struct *context) { - fprintf(stderr,"int21: IOCTL\n"); - EAX = (EAX & 0xfffff00L) | UnknownUnit; - SetCflag; + WORD handle = EBX & 0xffff; + + switch (handle) { + case 0: + case 1: + case 2: + EDX = (EDX & 0xffff0000) | 0x80d3; + break; + + default: + Barf(context); + EDX = (EDX & 0xffff0000) | 0x50; + } + ResetCflag; } -void DupeFileHandle(struct sigcontext_struct *context) +static void ioctlGenericBlkDevReq(struct sigcontext_struct *context) +{ + BYTE *dataptr = pointer(DS, DX); + int drive; + + if (!(EBX & 0xffL)) + drive = DOS_GetDefaultDrive(); + else + drive = (EBX & 0xffL) - 1; + + if ((ECX & 0xff00L) != 0x0800) { + Barf(context); + return; + } + switch (ECX & 0xffL) { + case 0x60: /* get device parameters */ + /* used by w4wgrp's winfile */ + dataptr[0] = 0x04; + dataptr[6] = 0; /* media type */ + if (drive > 1) + { + dataptr[1] = 0x05; /* fixed disk */ + setword(&dataptr[2], 0x01); /* non removable */ + setword(&dataptr[4], 0x300); /* # of cylinders */ + } + else + { + dataptr[1] = 0x07; /* block dev, floppy */ + setword(&dataptr[2], 0x02); /* removable */ + setword(&dataptr[4], 80); /* # of cylinders */ + } + CreateBPB(drive, &dataptr[7]); + EAX = (EAX & 0xfffff00L); + ResetCflag; + return; + default: + Barf(context); + } +} + +static void DupeFileHandle(struct sigcontext_struct *context) { EAX = (EAX & 0xffff0000L) | dup(BX); ResetCflag; } -void GetSystemDate(struct sigcontext_struct *context) +static void GetSystemDate(struct sigcontext_struct *context) { struct tm *now; time_t ltime; @@ -332,12 +436,12 @@ void GetSystemDate(struct sigcontext_struct *context) ltime = time(NULL); now = localtime(<ime); - ECX = (ECX & 0xffff0000L) | now->tm_year + 1900; + ECX = (ECX & 0xffff0000L) | (now->tm_year + 1900); EDX = (EDX & 0xffff0000L) | ((now->tm_mon + 1) << 8) | now->tm_mday; EAX = (EAX & 0xffff0000L) | now->tm_wday; } -void GetSystemTime(struct sigcontext_struct *context) +static void GetSystemTime(struct sigcontext_struct *context) { struct tm *now; time_t ltime; @@ -349,14 +453,14 @@ void GetSystemTime(struct sigcontext_struct *context) EDX = (EDX & 0xffffff00L) | now->tm_sec << 8; } -void GetExtendedErrorInfo(struct sigcontext_struct *context) +static void GetExtendedErrorInfo(struct sigcontext_struct *context) { EAX = (EAX & 0xffffff00L) | ExtendedError; EBX = (EBX & 0xffff0000L) | (0x100 * ErrorClass) | Action; ECX = (ECX & 0xffff00ffL) | (0x100 * ErrorLocus); } -void GetInDosFlag(struct sigcontext_struct *context) +static void GetInDosFlag(struct sigcontext_struct *context) { const BYTE InDosFlag = 0; @@ -364,11 +468,11 @@ void GetInDosFlag(struct sigcontext_struct *context) EBX = (EBX & 0xffff0000L) | offset(InDosFlag); } -void CreateFile(struct sigcontext_struct *context) +static void CreateFile(struct sigcontext_struct *context) { int handle; - if ((handle = open(GetUnixFileName((char *) pointer(DS,DX)), O_CREAT | O_TRUNC)) == -1) { + if ((handle = open(GetUnixFileName( pointer(DS,DX)), O_CREAT | O_TRUNC)) == -1) { switch (errno) { case EACCES: case EPERM: @@ -401,13 +505,13 @@ void CreateFile(struct sigcontext_struct *context) ResetCflag; } -void OpenExistingFile(struct sigcontext_struct *context) +static void OpenExistingFile(struct sigcontext_struct *context) { int handle; - fprintf(stderr,"OpenExistingFile (%s)\n",(char *) pointer(DS,DX)); + fprintf(stderr,"OpenExistingFile (%s)\n", pointer(DS,DX)); - if ((handle = open(GetUnixFileName((char*) pointer(DS,DX)), O_RDWR)) == -1) { + if ((handle = open(GetUnixFileName(pointer(DS,DX)), O_RDWR)) == -1) { switch (errno) { case EACCES: case EPERM: @@ -443,7 +547,7 @@ void OpenExistingFile(struct sigcontext_struct *context) ResetCflag; } -void CloseFile(struct sigcontext_struct *context) +static void CloseFile(struct sigcontext_struct *context) { if (close(BX) == -1) { switch (errno) { @@ -463,34 +567,35 @@ void CloseFile(struct sigcontext_struct *context) ResetCflag; } -void RenameFile(struct sigcontext_struct *context) +static void RenameFile(struct sigcontext_struct *context) { char *newname, *oldname; - fprintf(stderr,"int21: renaming %s to %s\n",(char *) pointer(DS,DX), pointer(ES,DI) ); + fprintf(stderr,"int21: renaming %s to %s\n", + pointer(DS,DX), pointer(ES,DI) ); - oldname = GetUnixFileName( (char *) pointer(DS,DX) ); - newname = GetUnixFileName( (char *) pointer(ES,DI) ); + oldname = GetUnixFileName( pointer(DS,DX) ); + newname = GetUnixFileName( pointer(ES,DI) ); rename( oldname, newname); ResetCflag; } -void GetTrueFileName(struct sigcontext_struct *context) +static void GetTrueFileName(struct sigcontext_struct *context) { - fprintf(stderr,"int21: GetTrueFileName of %s\n",(char *) pointer(DS,SI)); + fprintf(stderr,"int21: GetTrueFileName of %s\n", pointer(DS,SI) ); - strncpy((char *) pointer(ES,DI), (char *) pointer(DS,SI), strlen((char *) pointer(DS,SI)) & 0x7f); + strncpy(pointer(ES,DI), pointer(DS,SI), strlen(pointer(DS,SI)) & 0x7f); ResetCflag; } -void MakeDir(struct sigcontext_struct *context) +static void MakeDir(struct sigcontext_struct *context) { char *dirname; - fprintf(stderr,"int21: makedir %s\n",(char *) pointer(DS,DX) ); + fprintf(stderr,"int21: makedir %s\n", pointer(DS,DX) ); - if ((dirname = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + if ((dirname = GetUnixFileName( pointer(DS,DX) ))== NULL) { EAX = (EAX & 0xffffff00L) | CanNotMakeDir; SetCflag; return; @@ -504,20 +609,26 @@ void MakeDir(struct sigcontext_struct *context) ResetCflag; } -void ChangeDir(struct sigcontext_struct *context) +static void ChangeDir(struct sigcontext_struct *context) { - fprintf(stderr,"int21: changedir %s\n",(char *) pointer(DS,DX) ); - - DOS_ChangeDir(DOS_GetDefaultDrive(), (char *) pointer (DS,DX)); + int drive; + char *dirname = pointer(DS,DX); + drive = DOS_GetDefaultDrive(); + fprintf(stderr,"int21: changedir %s\n", dirname); + if (dirname != NULL && dirname[1] == ':') { + drive = toupper(dirname[0]) - 'A'; + dirname += 2; + } + DOS_ChangeDir(drive, dirname); } -void RemoveDir(struct sigcontext_struct *context) +static void RemoveDir(struct sigcontext_struct *context) { char *dirname; - fprintf(stderr,"int21: removedir %s\n",(char *) pointer(DS,DX) ); + fprintf(stderr,"int21: removedir %s\n", pointer(DS,DX) ); - if ((dirname = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + if ((dirname = GetUnixFileName( pointer(DS,DX) ))== NULL) { EAX = (EAX & 0xffffff00L) | CanNotMakeDir; SetCflag; return; @@ -536,82 +647,151 @@ void RemoveDir(struct sigcontext_struct *context) ResetCflag; } -void AllocateMemory(struct sigcontext_struct *context) +static void AllocateMemory(struct sigcontext_struct *context) { char *ptr; fprintf(stderr,"int21: malloc %d bytes\n", BX * 0x10 ); - if ((ptr = (void *) memalign((size_t) (BX * 0x10), 0x10)) == NULL) { +/* if ((ptr = (void *) memalign((size_t) (BX * 0x10), 0x10)) == NULL) { EAX = (EAX & 0xffffff00L) | OutOfMemory; - EBX = (EBX & 0xffffff00L); /* out of memory */ + EBX = (EBX & 0xffffff00L); SetCflag; } fprintf(stderr,"int21: malloc (ptr = %d)\n", ptr ); - EAX = (EAX & 0xffff0000L) | segment((unsigned long) ptr); - ResetCflag; + EAX = (EAX & 0xffff0000L) | segment(ptr); +*/ + Barf(context); + SetCflag; } -void FreeMemory(struct sigcontext_struct *context) +static void FreeMemory(struct sigcontext_struct *context) { fprintf(stderr,"int21: freemem (ptr = %d)\n", ES * 0x10 ); - +/* free((void *)(ES * 0x10)); +*/ Barf(context); ResetCflag; } -void ResizeMemoryBlock(struct sigcontext_struct *context) +static void ResizeMemoryBlock(struct sigcontext_struct *context) { char *ptr; fprintf(stderr,"int21: realloc (ptr = %d)\n", ES * 0x10 ); - if ((ptr = (void *) realloc((void *)(ES * 0x10), (size_t) BX * 0x10)) == NULL) { +/* if ((ptr = (void *) realloc((void *)(ES * 0x10), (size_t) BX * 0x10)) == NULL) { EAX = (EAX & 0xffffff00L) | OutOfMemory; - EBX = (EBX & 0xffffff00L); /* out of memory */ + EBX = (EBX & 0xffffff00L); SetCflag; } - EBX = (EBX & 0xffff0000L) | segment((unsigned long) ptr); - ResetCflag; + EBX = (EBX & 0xffff0000L) | segment(ptr); +*/ Barf(context); + SetCflag; } -void ExecProgram(struct sigcontext_struct *context) +static void ExecProgram(struct sigcontext_struct *context) { - execl("wine", GetUnixFileName((char *) pointer(DS,DX)) ); + execl("wine", GetUnixFileName( pointer(DS,DX)) ); } -void GetReturnCode(struct sigcontext_struct *context) +static void GetReturnCode(struct sigcontext_struct *context) { EAX = (EAX & 0xffffff00L) | NoError; /* normal exit */ } -void FindFirst(struct sigcontext_struct *context) +static void FindNext(struct sigcontext_struct *context) { + struct dosdirent *dp; + + dp = (struct dosdirent *)(dta + 0x0d); + do { + if ((dp = DOS_readdir(dp)) == NULL) { + DOS_closedir(dp); + Error(NoMoreFiles, EC_MediaError , EL_Disk); + EAX = (EAX & 0xffffff00L) | NoMoreFiles; + SetCflag; + return; + } + } while (*(dta + 0x0c) != dp->attribute); + + setword(&dta[0x16], 0x1234); /* time */ + setword(&dta[0x18], 0x1234); /* date */ + setdword(&dta[0x1a], dp->filesize); + strncpy(dta + 0x1e, dp->filename, 13); + + EAX = (EAX & 0xffffff00L); + ResetCflag; + return; } -void FindNext(struct sigcontext_struct *context) +static void FindFirst(struct sigcontext_struct *context) { + BYTE drive, *path = pointer(DS, DX); + struct dosdirent *dp; + if (path[1] == ':') { + drive = (islower(*path) ? toupper(*path) : *path) - 'A'; + + if (!DOS_ValidDrive(drive)) { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xffffff00L) | InvalidDrive; + SetCflag; + return; + } + } else + drive = DOS_GetDefaultDrive(); + + *dta = drive; + memset(dta + 1 , '?', 11); + *(dta + 0x0c) = ECX & (FA_LABEL | FA_DIREC); + + if (ECX & FA_LABEL) { + /* return volume label */ + + if (DOS_GetVolumeLabel(drive) != NULL) + strncpy(dta + 0x1e, DOS_GetVolumeLabel(drive), 8); + + EAX = (EAX & 0xffffff00L); + ResetCflag; + return; + } + + if ((dp = DOS_opendir(path)) == NULL) { + Error(PathNotFound, EC_MediaError, EL_Disk); + EAX = (EAX & 0xffffff00L) | FileNotFound; + SetCflag; + return; + } +/* strncpy(dta + 1, AsciizToFCB(dp->filemask), 11); */ + +/* *((BYTE *) ((void*)dta + 0x0d)) = (BYTE *) dp; */ + + *((struct dosdirent *)(dta + 0x0d)) + = + *dp; + FindNext(context); } -void GetSysVars(struct sigcontext_struct *context) +static void GetSysVars(struct sigcontext_struct *context) { /* return a null pointer, to encourage anyone who tries to use the pointer */ ES = 0x0; EBX = (EBX & 0xffff0000L); + Barf(context); } -void GetFileDateTime(struct sigcontext_struct *context) +static void GetFileDateTime(struct sigcontext_struct *context) { char *filename; struct stat filestat; struct tm *now; - if ((filename = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + if ((filename = GetUnixFileName( pointer(DS,DX) ))== NULL) { EAX = (EAX & 0xffffff00L) | FileNotFound; SetCflag; return; @@ -620,18 +800,18 @@ void GetFileDateTime(struct sigcontext_struct *context) now = localtime (&filestat.st_mtime); - ECX = (ECX & 0xffff0000L) | (now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2; - EDX = (EDX & 0xffff0000L) | (now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday; + ECX = (ECX & 0xffff0000L) | ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2); + EDX = (EDX & 0xffff0000L) | ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday); ResetCflag; } -void SetFileDateTime(struct sigcontext_struct *context) +static void SetFileDateTime(struct sigcontext_struct *context) { char *filename; struct utimbuf filetime; - filename = GetUnixFileName((char *) pointer(DS,DX)); + filename = GetUnixFileName( pointer(DS,DX) ); filetime.actime = 0L; filetime.modtime = filetime.actime; @@ -640,10 +820,10 @@ void SetFileDateTime(struct sigcontext_struct *context) ResetCflag; } -void CreateTempFile(struct sigcontext_struct *context) +static void CreateTempFile(struct sigcontext_struct *context) { - char *filename, temp[256]; - int drive, handle; + char temp[256]; + int handle; sprintf(temp,"%s\\win%d.tmp",TempDirectory,(int) getpid()); @@ -657,17 +837,17 @@ void CreateTempFile(struct sigcontext_struct *context) return; } - strcpy((char *) pointer(DS,DX), temp); + strcpy(pointer(DS,DX), temp); EAX = (EAX & 0xffff0000L) | handle; ResetCflag; } -void CreateNewFile(struct sigcontext_struct *context) +static void CreateNewFile(struct sigcontext_struct *context) { int handle; - if ((handle = open(GetUnixFileName((char *) pointer(DS,DX)), O_CREAT | O_TRUNC | O_RDWR)) == -1) { + if ((handle = open(GetUnixFileName( pointer(DS,DX) ), O_CREAT | O_TRUNC | O_RDWR)) == -1) { EAX = (EAX & 0xffffff00L) | WriteProtected; SetCflag; return; @@ -677,17 +857,17 @@ void CreateNewFile(struct sigcontext_struct *context) ResetCflag; } -void FileLock(struct sigcontext_struct *context) +static void FileLock(struct sigcontext_struct *context) { - + fprintf(stderr, "int21: flock()\n"); } -void GetExtendedCountryInfo(struct sigcontext_struct *context) +static void GetExtendedCountryInfo(struct sigcontext_struct *context) { ResetCflag; } -void GetCurrentDirectory(struct sigcontext_struct *context) +static void GetCurrentDirectory(struct sigcontext_struct *context) { int drive; @@ -702,20 +882,20 @@ void GetCurrentDirectory(struct sigcontext_struct *context) return; } - DOS_GetCurrentDir(drive, (char *) pointer(DS,SI) ); + strcpy(pointer(DS,SI), DOS_GetCurrentDir(drive) ); ResetCflag; } -void GetCurrentPSP(struct sigcontext_struct *context) +static void GetCurrentPSP(struct sigcontext_struct *context) { - + Barf(context); } -void GetDiskSerialNumber(struct sigcontext_struct *context) +static void GetDiskSerialNumber(struct sigcontext_struct *context) { int drive; - unsigned long serialnumber; - struct diskinfo *ptr; + BYTE *dataptr = pointer(DS, DX); + DWORD serialnumber; if ((EBX & 0xffL) == 0) drive = DOS_GetDefaultDrive(); @@ -728,474 +908,640 @@ void GetDiskSerialNumber(struct sigcontext_struct *context) return; } - DOS_GetSerialNumber(drive,&serialnumber); + DOS_GetSerialNumber(drive, &serialnumber); - ptr = (struct diskinfo *) pointer(DS,SI); - - ptr->infolevel = 0; - ptr->serialnumber = serialnumber; - strcpy(ptr->label,"NO NAME "); - strcpy(ptr->fstype,"FAT16 "); + setword(dataptr, 0); + setdword(&dataptr[2], serialnumber); + strncpy(dataptr + 6, DOS_GetVolumeLabel(drive), 8); + strncpy(dataptr + 0x11, "FAT16 ", 8); - EAX = (EAX & 0xffffff00L) | NoError; + EAX = (EAX & 0xffffff00L); ResetCflag; } -void SetDiskSerialNumber(struct sigcontext_struct *context) +static void SetDiskSerialNumber(struct sigcontext_struct *context) { + int drive; + BYTE *dataptr = pointer(DS, DX); + DWORD serialnumber; + + if ((EBX & 0xffL) == 0) + drive = DOS_GetDefaultDrive(); + else + drive = (EBX & 0xffL) - 1; + + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffffff00L) | InvalidDrive; + SetCflag; + return; + } + + serialnumber = dataptr[1] + (dataptr[2] << 8) + (dataptr[3] << 16) + + (dataptr[4] << 24); + + DOS_SetSerialNumber(drive, serialnumber); EAX = (EAX & 0xffffff00L) | 1L; ResetCflag; } +static void DumpFCB(BYTE *fcb) +{ + int x, y; + + fcb -= 7; + + for (y = 0; y !=2 ; y++) { + for (x = 0; x!=15;x++) + fprintf(stderr, "%02x ", *fcb++); + fprintf(stderr,"\n"); + } +} + +/* microsoft's programmers should be shot for using CP/M style int21 + calls in Windows for Workgroup's winfile.exe */ + +static void FindFirstFCB(struct sigcontext_struct *context) +{ + BYTE *fcb = pointer(DS, DX); + int drive; + + DumpFCB( fcb ); + + if (*fcb) + drive = *fcb - 1; + else + drive = DOS_GetDefaultDrive(); + + if (*(fcb - 7) == 0xff) { + if (*(fcb - 1) == FA_DIREC) { + /* return volume label */ + + memset(dta, ' ', 11); + if (DOS_GetVolumeLabel(drive) != NULL) + strncpy(dta, DOS_GetVolumeLabel(drive), 8); + *(dta + 0x0b) = FA_DIREC; + + EAX = (EAX & 0xffffff00L); + return; + } + } + Barf(context); +} + +static void DeleteFileFCB(struct sigcontext_struct *context) +{ + BYTE *fcb = pointer(DS, DX); + int drive; + struct dosdirent *dp; + char temp[256], *ptr; + + DumpFCB( fcb ); + + if (*fcb) + drive = *fcb - 1; + else + drive = DOS_GetDefaultDrive(); + + strcpy(temp, DOS_GetCurrentDir(drive)); + strcat(temp, "\\"); + strncat(temp, fcb + 1, 8); + ChopOffWhiteSpace(temp); + strncat(temp, fcb + 9, 3); + ChopOffWhiteSpace(temp); + + if ((dp = DOS_opendir(temp)) == NULL) { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xffffff00L) | 0xffL; + return; + } + + strcpy(temp, DOS_GetCurrentDir(drive) ); + strcat(temp, "\\"); + + ptr = temp + strlen(temp); + + while (DOS_readdir(dp) != NULL) + { + strcpy(ptr, dp->filename); + fprintf(stderr, "int21: delete file %s\n", temp); + /* unlink(GetUnixFileName(temp)); */ + } + + DOS_closedir(dp); + EAX = (EAX & 0xffffff00L); +} + +static void RenameFileFCB(struct sigcontext_struct *context) +{ + BYTE *fcb = pointer(DS, DX); + int drive; + struct dosdirent *dp; + char temp[256], oldname[256], newname[256], *oldnameptr, *newnameptr; + + DumpFCB( fcb ); + + if (*fcb) + drive = *fcb - 1; + else + drive = DOS_GetDefaultDrive(); + + strcpy(temp, DOS_GetCurrentDir(drive)); + strcat(temp, "\\"); + strncat(temp, fcb + 1, 8); + ChopOffWhiteSpace(temp); + strncat(temp, fcb + 9, 3); + ChopOffWhiteSpace(temp); + + if ((dp = DOS_opendir(temp)) == NULL) { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xffffff00L) | 0xffL; + return; + } + + strcpy(oldname, DOS_GetCurrentDir(drive) ); + strcat(oldname, "\\"); + oldnameptr = oldname + strlen(oldname); + + strcpy(newname, DOS_GetCurrentDir(drive) ); + strcat(newname, "\\"); + newnameptr = newname + strlen(newname); + + while (DOS_readdir(dp) != NULL) + { + strcpy(oldnameptr, dp->filename); + strcpy(newnameptr, fcb + 1); + fprintf(stderr, "int21: renamefile %s -> %s\n", oldname, newname); + } + + DOS_closedir(dp); + EAX = (EAX & 0xffffff00L); +} + /************************************************************************/ int do_int21(struct sigcontext_struct * context) { - int ah; + int ah; - fprintf(stderr, "int21: AX %04x, BX %04x, CX %04x, DX %04x, SI %04x, DI %04x, DS %04x, ES %04x\n", - AX, BX, CX, DX, SI, DI, DS, ES); + if (Options.relay_debug) + { + printf("int21: AX %04x, BX %04x, CX %04x, DX %04x, " + "SI %04x, DI %04x, DS %04x, ES %04x\n", + AX, BX, CX, DX, SI, DI, DS, ES); + } - ah = (EAX >> 8) & 0xffL; + ah = (EAX >> 8) & 0xffL; - if (ah == 0x59) { - GetExtendedErrorInfo(context); - return 1; - } else { - - Error (0,0,0); - - switch(ah) { - - case 0x00: /* TERMINATE PROGRAM */ - exit(0); - - case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */ - case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */ - case 0x03: /* READ CHARACTER FROM STDAUX */ - case 0x04: /* WRITE CHARACTER TO STDAUX */ - case 0x05: /* WRITE CHARACTER TO PRINTER */ - case 0x06: /* DIRECT CONSOLE IN/OUTPUT */ - case 0x07: /* DIRECT CHARACTER INPUT, WITHOUT ECHO */ - case 0x08: /* CHARACTER INPUT WITHOUT ECHO */ - case 0x09: /* WRITE STRING TO STANDARD OUTPUT */ - case 0x0a: /* BUFFERED INPUT */ - case 0x0b: /* GET STDIN STATUS */ - case 0x0c: /* FLUSH BUFFER AND READ STANDARD INPUT */ - case 0x0d: /* DISK BUFFER FLUSH */ - break; - - /* no FCB support for CP/M hackers */ - - case 0x0f: /* OPEN FILE USING FCB */ - case 0x10: /* CLOSE FILE USING FCB */ - case 0x11: /* FIND FIRST MATCHING FILE USING FCB */ - case 0x12: /* FIND NEXT MATCHING FILE USING FCB */ - case 0x13: /* DELETE FILE USING FCB */ - case 0x14: /* SEQUENTIAL READ FROM FCB FILE */ - case 0x15: /* SEQUENTIAL WRITE TO FCB FILE */ - case 0x16: /* CREATE OR TRUNCATE FILE USING FCB */ - case 0x17: /* RENAME FILE USING FCB */ - case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */ - case 0x21: /* READ RANDOM RECORD FROM FCB FILE */ - case 0x22: /* WRITE RANDOM RECORD TO FCB FILE */ - case 0x23: /* GET FILE SIZE FOR FCB */ - case 0x24: /* SET RANDOM RECORD NUMBER FOR FCB */ - case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */ - case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */ - case 0x29: /* PARSE FILENAME INTO FCB */ - case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */ - - case 0x2e: /* SET VERIFY FLAG */ - break; - - case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */ - case 0x1d: - case 0x1e: - case 0x20: - case 0x2b: /* SET SYSTEM DATE */ - case 0x2d: /* SET SYSTEM TIME */ - case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER - "SWITCHAR" - SET SWITCH CHARACTER - "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */ - case 0x54: /* GET VERIFY FLAG */ - case 0x61: /* UNUSED */ - case 0x6b: /* NULL FUNCTION */ - EAX &= 0xff00; - break; - - case 0x67: /* SET HANDLE COUNT */ - ResetCflag; - break; - - case 0x0e: /* SELECT DEFAULT DRIVE */ - SetDefaultDrive(context); - break; - - case 0x19: /* GET CURRENT DEFAULT DRIVE */ - GetDefaultDrive(context); - break; - - case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */ - GetDefDriveAllocInfo(context); - break; - - case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */ - GetDriveAllocInfo(context); - break; - - case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */ - case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */ - GetDrivePB(context); - break; - - case 0x25: /* SET INTERRUPT VECTOR */ - /* Ignore any attempt to set a segment vector */ - return 1; - - case 0x26: /* CREATE NEW PROGRAM SEGMENT PREFIX */ - break; - - case 0x2a: /* GET SYSTEM DATE */ - GetSystemDate(context); - break; - - case 0x2c: /* GET SYSTEM TIME */ - GetSystemTime(context); - break; - - case 0x30: /* GET DOS VERSION */ - fprintf(stderr,"int21: GetDosVersion\n"); - EAX = DosVersion; /* Hey folks, this is DOS V3.3! */ - EBX = 0x0012; /* 0x123456 is Wine's serial # */ - ECX = 0x3456; - break; - - case 0x31: /* TERMINATE AND STAY RESIDENT */ - break; - - case 0x33: /* MULTIPLEXED */ - switch (EAX & 0xff) { - case 0x00: /* GET CURRENT EXTENDED BREAK STATE */ - if (!(EAX & 0xffL)) - EDX &= 0xff00L; - break; - - case 0x01: /* SET EXTENDED BREAK STATE */ - break; - - case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE */ - EDX &= 0xff00L; - break; - - case 0x05: /* GET BOOT DRIVE */ - EDX = (EDX & 0xff00L) | 2; - /* c: is Wine's bootdrive */ - break; - - case 0x06: /* GET TRUE VERSION NUMBER */ - EBX = DosVersion; - EDX = 0x00; - break; - default: - break; - } - break; - - case 0x34: /* GET ADDRESS OF INDOS FLAG */ - GetInDosFlag(context); - break; - - case 0x35: /* GET INTERRUPT VECTOR */ - /* Return a NULL segment selector - this will bomb, - if anyone ever tries to use it */ - ES = 0; - EBX = 0; - break; - - case 0x36: /* GET FREE DISK SPACE */ - GetFreeDiskSpace(context); - break; - - case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ - EAX &= 0xff00; - EAX |= 0x02; /* no country support available */ - SetCflag; - break; - - case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */ - MakeDir(context); - break; - - case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */ - RemoveDir(context); - break; - - case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */ - ChangeDir(context); - break; - - case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */ - CreateFile(context); - break; - - case 0x3d: /* "OPEN" - OPEN EXISTING FILE */ - OpenExistingFile(context); - break; - - case 0x3e: /* "CLOSE" - CLOSE FILE */ - CloseFile(context); - break; - - case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */ - ReadFile(context); - break; - - case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */ - WriteFile(context); - break; - - case 0x41: /* "UNLINK" - DELETE FILE */ - UnlinkFile(context); - break; - - case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */ - SeekFile(context); - break; - - case 0x43: /* FILE ATTRIBUTES */ - switch (EAX & 0xff) { - case 0x00: - GetFileAttributes(context); - break; - case 0x01: - SetFileAttributes(context); - break; - } - break; - - case 0x44: /* IOCTL */ - DosIOCTL(context); - break; - - case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */ - case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ - DupeFileHandle(context); - break; - - case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ - GetCurrentDirectory(context); - EAX = (EAX & 0xffff0000L) | 0x0100; - /* many Microsoft products for Windows rely on this */ - break; - - case 0x48: /* ALLOCATE MEMORY */ - AllocateMemory(context); - break; - - case 0x49: /* FREE MEMORY */ - FreeMemory(context); - break; - - case 0x4a: /* RESIZE MEMORY BLOCK */ - ResizeMemoryBlock(context); - break; - - case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */ - ExecProgram(context); - break; - - case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */ - fprintf(stderr,"int21: DosExit\n"); - exit(EAX & 0xff); - break; - - case 0x4d: /* GET RETURN CODE */ - GetReturnCode(context); - break; - - case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */ - FindFirst(context); - break; - - case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */ - FindNext(context); - break; - - case 0x52: /* "SYSVARS" - GET LIST OF LISTS */ - GetSysVars(context); - break; - - case 0x56: /* "RENAME" - RENAME FILE */ - RenameFile(context); - break; - - case 0x57: /* FILE DATE AND TIME */ - switch (EAX & 0xff) { - case 0x00: - GetFileDateTime(context); - break; - case 0x01: - SetFileDateTime(context); - break; - } - break; - - case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ - switch (EAX & 0xff) { - case 0x00: - EAX = (EAX & 0xffffff00L) | 0x01L; - break; - case 0x02: - EAX &= 0xff00L; - break; - case 0x01: - case 0x03: - break; - } - ResetCflag; - break; - - case 0x59: /* GET EXTENDED ERROR INFO */ - GetExtendedErrorInfo(context); - break; - - case 0x5a: /* CREATE TEMPORARY FILE */ - CreateTempFile(context); - break; - - case 0x5b: /* CREATE NEW FILE */ - CreateNewFile(context); - break; - - case 0x5c: /* "FLOCK" - RECORD LOCKING */ - FileLock(context); - break; - - case 0x5d: /* NETWORK */ - case 0x5e: - EAX = (EAX & 0xfffff00L) | NoNetwork; /* network software not installed */ - SetCflag; - break; - - case 0x5f: /* NETWORK */ - switch (EAX & 0xffL) { - case 0x07: /* ENABLE DRIVE */ - if (!DOS_EnableDrive(EDX & 0xffL)) { - Error(InvalidDrive, EC_MediaError , EL_Disk); - EAX = (EAX & 0xfffff00L) | InvalidDrive; - SetCflag; - break; - } else { - ResetCflag; - break; - } - case 0x08: /* DISABLE DRIVE */ - if (!DOS_DisableDrive(EDX & 0xffL)) { - Error(InvalidDrive, EC_MediaError , EL_Disk); - EAX = (EAX & 0xfffff00L) | InvalidDrive; - SetCflag; - break; - } else { - ResetCflag; - break; - } - default: - EAX = (EAX & 0xfffff00L) | NoNetwork; /* network software not installed */ - SetCflag; - break; - } - break; - - case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ - GetTrueFileName(context); - break; - - case 0x62: /* GET CURRENT PSP ADDRESS */ - GetCurrentPSP(context); - break; - - case 0x65: /* GET EXTENDED COUNTRY INFORMATION */ - GetExtendedCountryInfo(context); - break; - - case 0x66: /* GLOBAL CODE PAGE TABLE */ - switch (EAX & 0xffL) { - case 0x01: - EBX = CodePage; - EDX = EBX; - ResetCflag; - break; - case 0x02: - CodePage = EBX; - ResetCflag; - break; - } - break; - - case 0x68: /* "FFLUSH" - COMMIT FILE */ - ResetCflag; - break; - - case 0x69: /* DISK SERIAL NUMBER */ - switch (EAX & 0xff) { - case 0x00: - GetDiskSerialNumber(context); - break; - case 0x01: - SetDiskSerialNumber(context); - break; - } - break; - - case 0x6a: /* COMMIT FILE */ - ResetCflag; - break; - - default: - fprintf(stderr,"Unable to handle int 0x21 %x\n", context->sc_eax); - return 1; - }; - } + if (ah == 0x59) + { + GetExtendedErrorInfo(context); return 1; + } + else + { + Error (0,0,0); + switch(ah) + { + case 0x00: /* TERMINATE PROGRAM */ + exit(0); + + case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */ + case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */ + case 0x03: /* READ CHARACTER FROM STDAUX */ + case 0x04: /* WRITE CHARACTER TO STDAUX */ + case 0x05: /* WRITE CHARACTER TO PRINTER */ + case 0x06: /* DIRECT CONSOLE IN/OUTPUT */ + case 0x07: /* DIRECT CHARACTER INPUT, WITHOUT ECHO */ + case 0x08: /* CHARACTER INPUT WITHOUT ECHO */ + case 0x09: /* WRITE STRING TO STANDARD OUTPUT */ + case 0x0a: /* BUFFERED INPUT */ + case 0x0b: /* GET STDIN STATUS */ + case 0x0c: /* FLUSH BUFFER AND READ STANDARD INPUT */ + case 0x0f: /* OPEN FILE USING FCB */ + case 0x10: /* CLOSE FILE USING FCB */ + case 0x12: /* FIND NEXT MATCHING FILE USING FCB */ + case 0x14: /* SEQUENTIAL READ FROM FCB FILE */ + case 0x15: /* SEQUENTIAL WRITE TO FCB FILE */ + case 0x16: /* CREATE OR TRUNCATE FILE USING FCB */ + case 0x21: /* READ RANDOM RECORD FROM FCB FILE */ + case 0x22: /* WRITE RANDOM RECORD TO FCB FILE */ + case 0x23: /* GET FILE SIZE FOR FCB */ + case 0x24: /* SET RANDOM RECORD NUMBER FOR FCB */ + case 0x26: /* CREATE NEW PROGRAM SEGMENT PREFIX */ + case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */ + case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */ + case 0x29: /* PARSE FILENAME INTO FCB */ + case 0x2e: /* SET VERIFY FLAG */ + Barf(context); + break; + + case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */ + case 0x1d: + case 0x1e: + case 0x20: + case 0x2b: /* SET SYSTEM DATE */ + case 0x2d: /* SET SYSTEM TIME */ + case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER + "SWITCHAR" - SET SWITCH CHARACTER + "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */ + case 0x54: /* GET VERIFY FLAG */ + case 0x61: /* UNUSED */ + case 0x6b: /* NULL FUNCTION */ + Barf(context); + EAX &= 0xff00; + break; + + case 0x0d: /* DISK BUFFER FLUSH */ + ResetCflag; /* dos 6+ only */ + break; + + case 0x0e: /* SELECT DEFAULT DRIVE */ + SetDefaultDrive(context); + break; + + case 0x11: /* FIND FIRST MATCHING FILE USING FCB */ + FindFirstFCB(context); + break; + + case 0x13: /* DELETE FILE USING FCB */ + DeleteFileFCB(context); + break; + + case 0x17: /* RENAME FILE USING FCB */ + RenameFileFCB(context); + break; + + case 0x19: /* GET CURRENT DEFAULT DRIVE */ + GetDefaultDrive(context); + break; + + case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */ + dta = pointer(DS, DX); + break; + + case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */ + GetDefDriveAllocInfo(context); + break; + + case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */ + GetDriveAllocInfo(context); + break; + + case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */ + GetDrivePB(context); + break; + + case 0x25: /* SET INTERRUPT VECTOR */ + /* Ignore any attempt to set a segment vector */ + fprintf(stderr, "int21: set interrupt vector %2x (%04x:%04x)\n", AX & 0xff, DS, DX); + break; + + case 0x2a: /* GET SYSTEM DATE */ + GetSystemDate(context); + break; + + case 0x2c: /* GET SYSTEM TIME */ + GetSystemTime(context); + break; + + case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */ + ES = segment(dta); + EBX = (EBX & 0xffff0000L) | offset(dta); + break; + + case 0x30: /* GET DOS VERSION */ + EAX = (EAX & 0xffff0000L) | DOSVERSION; + EBX = (EBX & 0xffff0000L) | 0x0012; /* 0x123456 is Wine's serial # */ + ECX = (ECX & 0xffff0000L) | 0x3456; + break; + + case 0x31: /* TERMINATE AND STAY RESIDENT */ + Barf(context); + break; + + case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */ + GetDrivePB(context); + break; + + case 0x33: /* MULTIPLEXED */ + switch (EAX & 0xff) { + case 0x00: /* GET CURRENT EXTENDED BREAK STATE */ + if (!(EAX & 0xffL)) + EDX &= 0xff00L; + break; + + case 0x01: /* SET EXTENDED BREAK STATE */ + break; + + case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE*/ + EDX &= 0xff00L; + break; + + case 0x05: /* GET BOOT DRIVE */ + EDX = (EDX & 0xff00L) | 2; + /* c: is Wine's bootdrive */ + break; + + case 0x06: /* GET TRUE VERSION NUMBER */ + EBX = DOSVERSION; + EDX = 0x00; + break; + default: + break; + } + break; + + case 0x34: /* GET ADDRESS OF INDOS FLAG */ + GetInDosFlag(context); + break; + + case 0x35: /* GET INTERRUPT VECTOR */ + /* Return a NULL segment selector - this will bomb, + if anyone ever tries to use it */ + fprintf(stderr, "int21: get interrupt vector %2x\n", AX & 0xff); + ES = 0; + EBX = 0; + break; + + case 0x36: /* GET FREE DISK SPACE */ + GetFreeDiskSpace(context); + break; + + case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ + EAX &= 0xff00; + EAX |= 0x02; /* no country support available */ + SetCflag; + break; + + case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */ + MakeDir(context); + break; + + case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */ + RemoveDir(context); + break; + + case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */ + ChangeDir(context); + break; + + case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */ + CreateFile(context); + break; + + case 0x3d: /* "OPEN" - OPEN EXISTING FILE */ + OpenExistingFile(context); + break; + + case 0x3e: /* "CLOSE" - CLOSE FILE */ + CloseFile(context); + break; + + case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */ + ReadFile(context); + break; + + case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */ + WriteFile(context); + break; + + case 0x41: /* "UNLINK" - DELETE FILE */ + UnlinkFile(context); + break; + + case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */ + SeekFile(context); + break; + + case 0x43: /* FILE ATTRIBUTES */ + switch (EAX & 0xffL) + { + case 0x00: + GetFileAttributes(context); + break; + case 0x01: + SetFileAttributes(context); + break; + } + break; + + case 0x44: /* IOCTL */ + switch (EAX & 0xff) + { + case 0x00: + ioctlGetDeviceInfo(context); + break; + + case 0x0d: + ioctlGenericBlkDevReq(context); + break; + + default: + Barf(context); + break; + } + break; + + + case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */ + case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ + DupeFileHandle(context); + break; + + case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ + GetCurrentDirectory(context); + EAX = (EAX & 0xffff0000L) | 0x0100; + /* intlist: many Microsoft products for Windows rely on this */ + break; + + case 0x48: /* ALLOCATE MEMORY */ + AllocateMemory(context); + break; + + case 0x49: /* FREE MEMORY */ + FreeMemory(context); + break; + + case 0x4a: /* RESIZE MEMORY BLOCK */ + ResizeMemoryBlock(context); + break; + + case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */ + ExecProgram(context); + break; + + case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */ + exit(EAX & 0xffL); + break; + + case 0x4d: /* GET RETURN CODE */ + GetReturnCode(context); + break; + + case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */ + FindFirst(context); + break; + + case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */ + FindNext(context); + break; + + case 0x52: /* "SYSVARS" - GET LIST OF LISTS */ + GetSysVars(context); + break; + + case 0x56: /* "RENAME" - RENAME FILE */ + RenameFile(context); + break; + + case 0x57: /* FILE DATE AND TIME */ + switch (EAX & 0xffL) + { + case 0x00: + GetFileDateTime(context); + break; + case 0x01: + SetFileDateTime(context); + break; + } + break; + + case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ + switch (EAX & 0xffL) + { + case 0x00: + EAX = (EAX & 0xffffff00L) | 0x01L; + break; + case 0x02: + EAX &= 0xff00L; + break; + case 0x01: + case 0x03: + break; + } + ResetCflag; + break; + + case 0x5a: /* CREATE TEMPORARY FILE */ + CreateTempFile(context); + break; + + case 0x5b: /* CREATE NEW FILE */ + CreateNewFile(context); + break; + + case 0x5c: /* "FLOCK" - RECORD LOCKING */ + FileLock(context); + break; + + case 0x5d: /* NETWORK */ + case 0x5e: + /* network software not installed */ + EAX = (EAX & 0xfffff00L) | NoNetwork; + SetCflag; + break; + + case 0x5f: /* NETWORK */ + switch (EAX & 0xffL) + { + case 0x07: /* ENABLE DRIVE */ + if (!DOS_EnableDrive(EDX & 0xffL)) + { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xfffff00L) | InvalidDrive; + SetCflag; + break; + } + else + { + ResetCflag; + break; + } + case 0x08: /* DISABLE DRIVE */ + if (!DOS_DisableDrive(EDX & 0xffL)) + { + Error(InvalidDrive, EC_MediaError , EL_Disk); + EAX = (EAX & 0xfffff00L) | InvalidDrive; + SetCflag; + break; + } + else + { + ResetCflag; + break; + } + default: + /* network software not installed */ + EAX = (EAX & 0xfffff00L) | NoNetwork; + SetCflag; + break; + } + break; + + case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */ + GetTrueFileName(context); + break; + + case 0x62: /* GET CURRENT PSP ADDRESS */ + GetCurrentPSP(context); + break; + + case 0x65: /* GET EXTENDED COUNTRY INFORMATION */ + GetExtendedCountryInfo(context); + break; + + case 0x66: /* GLOBAL CODE PAGE TABLE */ + switch (EAX & 0xffL) + { + case 0x01: + EBX = CodePage; + EDX = BX; + ResetCflag; + break; + case 0x02: + CodePage = BX; + ResetCflag; + break; + } + break; + + case 0x68: /* "FFLUSH" - COMMIT FILE */ + ResetCflag; + break; + + case 0x69: /* DISK SERIAL NUMBER */ + switch (EAX & 0xffL) + { + case 0x00: + GetDiskSerialNumber(context); + break; + case 0x01: + SetDiskSerialNumber(context); + break; + } + break; + + case 0x6a: /* COMMIT FILE */ + ResetCflag; + break; + + case 0x67: /* SET HANDLE COUNT */ + ResetCflag; + break; + + default: + Barf(context); + return 1; + } + } + return 1; } /********************************************************************** * DOS3Call */ -int DOS3Call() +void DOS3Call() { - static struct sigcontext_struct *context = NULL; - - if (!context) - context = malloc(sizeof(struct sigcontext_struct)); - -/* fprintf(stderr, "DOS3: AX %04x, BX %04x, CX %04x, DX %04x, SI %04x, DI %04x, DS %04x, ES %04x\n", - _AX, _BX, _CX, _DX, _SI, _DI, _DS, _ES); -*/ - EAX = _AX; - EBX = _BX; - ECX = _CX; - EDX = _DX; - DS = _DS; - ES = _ES; - DI = _DI; - SI = _SI; -/* EFL = _FL; -*/ - do_int21(context); - - _AX = AX; - _BX = BX; - _CX = CX; - _DX = DX; - - _DS = DS; - _ES = ES; - - _DI = DI; - _SI = SI; -/* _FL = EFL; - */ - return 0; + do_int21((struct sigcontext_struct *) _CONTEXT); + ReturnFromRegisterFunc(); } diff --git a/miscemu/int25.c b/miscemu/int25.c new file mode 100644 index 00000000000..f08c7a9c455 --- /dev/null +++ b/miscemu/int25.c @@ -0,0 +1,30 @@ +#include +#include "msdos.h" +#include "wine.h" + +int do_int25(struct sigcontext_struct *context) +{ + BYTE *dataptr = pointer(DS, BX); + DWORD begin, length; + + if( (ECX & 0xffff) == 0xffff) + { + begin = getdword(dataptr); + + length = getword(&dataptr[4]); + + dataptr = (BYTE *) getdword(&dataptr[6]); + + fprintf(stderr, "int25: abs diskread, drive %d, sector %d, " + "count %d, buffer %d\n", EAX & 0xff, begin, length, (int) dataptr); + } + + begin = EDX & 0xffff; + length = ECX & 0xffff; + + fprintf(stderr,"int25: abs diskread-2, drive %d, sector %d, count %d," + " buffer %d\n", EAX & 0xff, begin, length, (int) dataptr); + + ResetCflag; + return 1; +} diff --git a/miscemu/int26.c b/miscemu/int26.c new file mode 100644 index 00000000000..c4f84643b3d --- /dev/null +++ b/miscemu/int26.c @@ -0,0 +1,28 @@ +#include +#include "msdos.h" +#include "wine.h" + +int do_int26(struct sigcontext_struct *context) +{ + BYTE *dataptr = pointer(DS, BX); + DWORD begin, length; + + if( (ECX & 0xffff) == 0xffff) + { + begin = getdword(dataptr); + length = getword(&dataptr[4]); + dataptr = (BYTE *) getdword(&dataptr[6]); + + fprintf(stderr, "int26: abs diskread, drive %d, sector %d, " + "count %d, buffer %d\n", EAX & 0xff, begin, length, (int) dataptr); + } + + begin = EDX & 0xffff; + length = ECX & 0xffff; + + fprintf(stderr,"int26: abs diskread-2, drive %d, sector %d, count %d," + " buffer %d\n", EAX & 0xff, begin, length, (int) dataptr); + + ResetCflag; + return 1; +} diff --git a/miscemu/ioports.c b/miscemu/ioports.c new file mode 100644 index 00000000000..44fa971c4fe --- /dev/null +++ b/miscemu/ioports.c @@ -0,0 +1,60 @@ +#include +#include +#include "msdos.h" +#include "wine.h" + +static BYTE cmosaddress; + +static BYTE cmosimage[64] = { + 0x27, 0x34, 0x31, 0x47, 0x16, 0x15, 0x00, 0x01, + 0x04, 0x94, 0x26, 0x02, 0x50, 0x80, 0x00, 0x00, + 0x40, 0xb1, 0x00, 0x9c, 0x01, 0x80, 0x02, 0x00, + 0x1c, 0x00, 0x00, 0xad, 0x02, 0x10, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0x58, + 0x00, 0x1c, 0x19, 0x81, 0x00, 0x0e, 0x00, 0x80, + 0x1b, 0x7b, 0x21, 0x00, 0x00, 0x00, 0x05, 0x5f }; + +void inportb(struct sigcontext_struct *context) +{ + fprintf(stderr, "IO: inb (%x)\n", EDX & 0xffff); + + switch(EDX & 0xffff) + { + case 0x70: + EAX = (EAX & 0xffffff00L) | cmosaddress; + break; + case 0x71: + EAX = (EAX & 0xffffff00L) | cmosimage[cmosaddress & 0x3f]; + break; + default: + } +} + +void inport(struct sigcontext_struct *context) +{ + fprintf(stderr, "IO: in (%x)\n", EDX & 0xffff); + + EAX = (EAX & 0xffff0000L) | 0xffff; +} + +void outportb(struct sigcontext_struct *context) +{ + fprintf(stderr, "IO: outb (%x), %x\n", EDX & 0xffff, EAX & 0xff); + + switch (EDX & 0xffff) + { + case 0x70: + cmosaddress = EAX & 0xff; + break; + case 0x71: + cmosimage[cmosaddress & 0x3f] = EAX & 0xff; + break; + default: + } +} + +void outport(struct sigcontext_struct *context) +{ + fprintf(stderr, "IO: out (%x), %x\n", EDX & 0xffff, EAX & 0xffff); +} diff --git a/objects/Imakefile b/objects/Imakefile index 458761d9172..bce8061220e 100644 --- a/objects/Imakefile +++ b/objects/Imakefile @@ -16,7 +16,8 @@ SRCS = \ clipping.c \ bitblt.c \ linedda.c \ - color.c + color.c \ + dither.c OBJS = \ bitmap.o \ @@ -32,7 +33,8 @@ OBJS = \ clipping.o \ bitblt.o \ linedda.o \ - color.o + color.o \ + dither.o WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) DependTarget() diff --git a/objects/bitblt.c b/objects/bitblt.c index bbfa3bd5e52..992f7cad786 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c @@ -314,7 +314,7 @@ BOOL StretchBlt( HDC hdcDest, short xDest, short yDest, short widthDest, short h sxi = XGetImage(display, dcSrc->u.x.drawable, xs1, ys1, widthSrc, heightSrc, AllPlanes, ZPixmap); dxi = XCreateImage(display, DefaultVisualOfScreen(screen), - DefaultDepthOfScreen(screen), ZPixmap, + screenDepth, ZPixmap, 0, NULL, widthDest, heightDest, 32, 0); dxi->data = malloc(dxi->bytes_per_line * heightDest); diff --git a/objects/bitmap.c b/objects/bitmap.c index ffec3e9a760..6c21e0c8ee5 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -6,22 +6,18 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include +#include +#include #include "gdi.h" +#include "bitmap.h" -/* A GDI bitmap object contains a handle to a packed BITMAP, - * which is stored on the global heap. - * A packed BITMAP is a BITMAP structure followed by the bitmap bits. - */ /* Handle of the bitmap selected by default in a memory DC */ -HBITMAP BITMAP_hbitmapMemDC; +HBITMAP BITMAP_hbitmapMemDC = 0; - /* List of supported depths */ -static int depthCount; -static int * depthList; - - /* List of GC used for bitmap to pixmap operations (one for each depth) */ -static GC * bitmapGC; + /* GCs used for B&W and color bitmap operations */ +GC BITMAP_monoGC = 0, BITMAP_colorGC = 0; /*********************************************************************** @@ -29,27 +25,25 @@ static GC * bitmapGC; */ BOOL BITMAP_Init() { - int i; Pixmap tmpPixmap; - depthList = XListDepths( XT_display, DefaultScreen(XT_display), - &depthCount ); - if (!depthList || !depthCount) return FALSE; - if (!(bitmapGC = (GC *) malloc( depthCount * sizeof(GC) ))) return FALSE; - /* Create the necessary GCs */ - for (i = 0; i < depthCount; i++) + if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 ))) { - tmpPixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - 1, 1, depthList[i] ); - if (tmpPixmap) + BITMAP_monoGC = XCreateGC( display, tmpPixmap, 0, NULL ); + XSetGraphicsExposures( display, BITMAP_monoGC, False ); + XFreePixmap( display, tmpPixmap ); + } + + if (screenDepth != 1) + { + if ((tmpPixmap = XCreatePixmap(display, rootWindow, 1,1,screenDepth))) { - bitmapGC[i] = XCreateGC( XT_display, tmpPixmap, 0, NULL ); - XSetGraphicsExposures( XT_display, bitmapGC[i], False ); - XFreePixmap( XT_display, tmpPixmap ); + BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL ); + XSetGraphicsExposures( display, BITMAP_colorGC, False ); + XFreePixmap( display, tmpPixmap ); } - else bitmapGC[i] = 0; } BITMAP_hbitmapMemDC = CreateBitmap( 1, 1, 1, 1, NULL ); @@ -57,27 +51,14 @@ BOOL BITMAP_Init() } -/*********************************************************************** - * BITMAP_FindGCForDepth - * - * Return a GC appropriate for operations with the given depth. - */ -GC BITMAP_FindGCForDepth( int depth ) -{ - int i; - for (i = 0; i < depthCount; i++) - if (depthList[i] == depth) return bitmapGC[i]; - return 0; -} - - /*********************************************************************** * BITMAP_BmpToImage * * Create an XImage pointing to the bitmap data. */ -XImage * BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) +static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) { + extern void _XInitImageFuncPtrs( XImage* ); XImage * image; image = XCreateImage( XT_display, DefaultVisualOfScreen(XT_screen), @@ -92,57 +73,6 @@ XImage * BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) } -/*********************************************************************** - * BITMAP_CopyToPixmap - * - * Copy the content of the bitmap to the pixmap. Both must have the same depth. - */ -BOOL BITMAP_CopyToPixmap( BITMAP * bmp, Pixmap pixmap, - int x, int y, int width, int height ) -{ - GC gc; - XImage * image; - - gc = BITMAP_FindGCForDepth( bmp->bmBitsPixel ); - if (!gc) return FALSE; - - image = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); - if (!image) return FALSE; - -#ifdef DEBUG_GDI - printf( "BITMAP_CopyToPixmap: %dx%d %d colors -> %d,%d %dx%d\n", - bmp->bmWidth, bmp->bmHeight, 1 << bmp->bmBitsPixel, x, y, width, height ); -#endif - XPutImage(XT_display, pixmap, gc, image, 0, 0, x, y, width, height); - image->data = NULL; - XDestroyImage( image ); - return TRUE; -} - - -/*********************************************************************** - * BITMAP_CopyFromPixmap - * - * Copy the content of the pixmap to the bitmap. Both must have - * the same dimensions and depth. - */ -BOOL BITMAP_CopyFromPixmap( BITMAP * bmp, Pixmap pixmap ) -{ - XImage *image = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); - if (!image) return FALSE; - -#ifdef DEBUG_GDI - printf( "BITMAP_CopyFromPixmap: %dx%d %d colors\n", - bmp->bmWidth, bmp->bmHeight, 1 << bmp->bmBitsPixel ); -#endif - XGetSubImage( XT_display, pixmap, 0, 0, bmp->bmWidth, bmp->bmHeight, - AllPlanes, ZPixmap, image, 0, 0 ); - image->data = NULL; - XDestroyImage( image ); - return TRUE; -} - - /*********************************************************************** * CreateBitmap (GDI.48) */ @@ -154,9 +84,6 @@ HBITMAP CreateBitmap( short width, short height, printf( "CreateBitmap: %dx%d, %d colors\n", width, height, 1 << (planes*bpp) ); #endif - if (!width || !height) return 0; - if ((planes != 1) && (bpp != 1)) return 0; - bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2; return CreateBitmapIndirect( &bitmap ); } @@ -166,15 +93,12 @@ HBITMAP CreateBitmap( short width, short height, */ HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) { - HBITMAP hbitmap; DC * dc; #ifdef DEBUG_GDI printf( "CreateCompatibleBitmap: %d %dx%d\n", hdc, width, height ); #endif - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) return 0; - hbitmap = CreateBitmap( width, height, dc->w.planes, dc->w.bitsPerPixel, NULL); - return hbitmap; + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + return CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL ); } @@ -184,72 +108,34 @@ HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) HBITMAP CreateBitmapIndirect( BITMAP * bmp ) { BITMAPOBJ * bmpObjPtr; - char * bmpPtr; HBITMAP hbitmap; - int size = bmp->bmPlanes * bmp->bmHeight * bmp->bmWidthBytes; - - /* Create the BITMAPOBJ */ + /* Check parameters */ + if (!bmp->bmHeight || !bmp->bmWidth) return 0; + if (bmp->bmPlanes != 1) return 0; + if ((bmp->bmBitsPixel != 1) && (bmp->bmBitsPixel != screenDepth)) return 0; + + /* Create the BITMAPOBJ */ hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC ); if (!hbitmap) return 0; bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap ); - - /* Create the bitmap in global heap */ - bmpObjPtr->hBitmap = GlobalAlloc( GMEM_MOVEABLE, sizeof(BITMAP) + size ); - if (!bmpObjPtr->hBitmap) + bmpObjPtr->size.cx = 0; + bmpObjPtr->size.cy = 0; + bmpObjPtr->bitmap = *bmp; + bmpObjPtr->bitmap.bmBits = NULL; + bmpObjPtr->bitmap.bmWidthBytes = (bmp->bmWidth*bmp->bmBitsPixel+15)/16 * 2; + + /* Create the pixmap */ + bmpObjPtr->pixmap = XCreatePixmap( display, rootWindow, bmp->bmWidth, + bmp->bmHeight, bmp->bmBitsPixel ); + if (!bmpObjPtr->pixmap) { - GDI_FreeObject( hbitmap ); - return 0; + GDI_HEAP_FREE( hbitmap ); + hbitmap = 0; } - bmpPtr = (char *) GlobalLock( bmpObjPtr->hBitmap ); - memcpy( bmpPtr, bmp, sizeof(BITMAP) ); - ((BITMAP *)bmpPtr)->bmBits = NULL; - if (bmp->bmBits) memcpy( bmpPtr + sizeof(BITMAP), bmp->bmBits, size ); - GlobalUnlock( bmpObjPtr->hBitmap ); - - bmpObjPtr->bSelected = FALSE; - bmpObjPtr->hdc = 0; - bmpObjPtr->size.cx = 0; - bmpObjPtr->size.cy = 0; - return hbitmap; -} - - -/*********************************************************************** - * BITMAP_GetSetBitmapBits - */ -LONG BITMAP_GetSetBitmapBits( HBITMAP hbitmap, LONG count, - LPSTR buffer, int set ) -{ - BITMAPOBJ * bmpObjPtr; - BITMAP * bmp; - DC * dc = NULL; - int maxSize; - - if (!count) return 0; - bmpObjPtr = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); - if (!bmpObjPtr) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObjPtr->hBitmap ))) return 0; - - if (bmpObjPtr->bSelected) - dc = (DC *) GDI_GetObjPtr( bmpObjPtr->hdc, DC_MAGIC ); - - maxSize = bmp->bmPlanes * bmp->bmHeight * bmp->bmWidthBytes; - if (count > maxSize) count = maxSize; - - if (set) - { - memcpy( bmp+1, buffer, count ); - if (dc) BITMAP_CopyToPixmap( bmp, dc->u.x.drawable, - 0, 0, bmp->bmWidth, bmp->bmHeight ); - } - else - { - if (dc) BITMAP_CopyFromPixmap( bmp, dc->u.x.drawable ); - memcpy( buffer, bmp+1, count ); - } - GlobalUnlock( bmpObjPtr->hBitmap ); + else if (bmp->bmBits) /* Set bitmap bits */ + SetBitmapBits( hbitmap, bmp->bmHeight*bmp->bmWidthBytes, bmp->bmBits ); return hbitmap; } @@ -259,7 +145,29 @@ LONG BITMAP_GetSetBitmapBits( HBITMAP hbitmap, LONG count, */ LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) { - return BITMAP_GetSetBitmapBits( hbitmap, count, buffer, 0 ); + BITMAPOBJ * bmp; + LONG height; + XImage * image; + + bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + if (!bmp) return 0; + +#ifdef DEBUG_BITMAP + printf( "GetBitmapBits: %dx%d %d colors %p\n", + bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, + 1 << bmp->bitmap.bmBitsPixel, buffer ); +#endif + /* Only get entire lines */ + height = count / bmp->bitmap.bmWidthBytes; + if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; + if (!height) return 0; + + if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0; + XGetSubImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, height, + AllPlanes, ZPixmap, image, 0, 0 ); + image->data = NULL; + XDestroyImage( image ); + return height * bmp->bitmap.bmWidthBytes; } @@ -268,7 +176,29 @@ LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) */ LONG SetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) { - return BITMAP_GetSetBitmapBits( hbitmap, count, buffer, 1 ); + BITMAPOBJ * bmp; + LONG height; + XImage * image; + + bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + if (!bmp) return 0; + +#ifdef DEBUG_BITMAP + printf( "SetBitmapBits: %dx%d %d colors %p\n", + bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, + 1 << bmp->bitmap.bmBitsPixel, buffer ); +#endif + /* Only set entire lines */ + height = count / bmp->bitmap.bmWidthBytes; + if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; + if (!height) return 0; + + if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0; + XPutImage( display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0, + 0, 0, bmp->bitmap.bmWidth, height ); + image->data = NULL; + XDestroyImage( image ); + return height * bmp->bitmap.bmWidthBytes; } @@ -277,8 +207,7 @@ LONG SetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) */ BOOL BMP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bitmap ) { - /* Free bitmap on global heap */ - GlobalFree( bitmap->hBitmap ); + XFreePixmap( display, bitmap->pixmap ); return GDI_FreeObject( hbitmap ); } @@ -286,95 +215,39 @@ BOOL BMP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bitmap ) /*********************************************************************** * BMP_GetObject */ -int BMP_GetObject( BITMAPOBJ * bitmap, int count, LPSTR buffer ) +int BMP_GetObject( BITMAPOBJ * bmp, int count, LPSTR buffer ) { - char * bmpPtr = (char *) GlobalLock( bitmap->hBitmap ); if (count > sizeof(BITMAP)) count = sizeof(BITMAP); - memcpy( buffer, bmpPtr, count ); - GlobalUnlock( bitmap->hBitmap ); + memcpy( buffer, &bmp->bitmap, count ); return count; } - -/*********************************************************************** - * BITMAP_UnselectBitmap - * - * Unselect the bitmap from the DC. Used by SelectObject and DeleteDC. - */ -BOOL BITMAP_UnselectBitmap( DC * dc ) -{ - BITMAPOBJ * bmp; - BITMAP * bmpPtr; - - if (!dc->w.hBitmap) return TRUE; - bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC ); - if (!bmp) return FALSE; - - if (!(bmpPtr = (BITMAP *) GlobalLock( bmp->hBitmap ))) return FALSE; - - BITMAP_CopyFromPixmap( bmpPtr, dc->u.x.drawable ); - XFreePixmap( XT_display, dc->u.x.drawable ); - bmp->bSelected = FALSE; - bmp->hdc = 0; - GlobalUnlock( bmp->hBitmap ); - return TRUE; -} - /*********************************************************************** * BITMAP_SelectObject */ HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap, - BITMAPOBJ * bitmap ) + BITMAPOBJ * bmp ) { - BITMAP * bmp; HBITMAP prevHandle = dc->w.hBitmap; if (!(dc->w.flags & DC_MEMORY)) return 0; - if (bitmap->bSelected && hbitmap != BITMAP_hbitmapMemDC) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bitmap->hBitmap ))) return 0; - - /* Make sure the bitmap has the right format */ - - if ((bmp->bmPlanes != 1) || !BITMAP_FindGCForDepth( bmp->bmBitsPixel )) - { - GlobalUnlock( bitmap->hBitmap ); - return 0; - } - - /* Unselect the previous bitmap */ - - if (!BITMAP_UnselectBitmap( dc )) - { - GlobalUnlock( bitmap->hBitmap ); - return 0; - } - - /* Create the pixmap */ - - dc->u.x.drawable = XCreatePixmap( XT_display, - DefaultRootWindow( XT_display ), - bmp->bmWidth, bmp->bmHeight, - bmp->bmBitsPixel ); - dc->w.DCSizeX = bmp->bmWidth; - dc->w.DCSizeY = bmp->bmHeight; - BITMAP_CopyToPixmap( bmp, dc->u.x.drawable, - 0, 0, bmp->bmWidth, bmp->bmHeight ); + dc->u.x.drawable = bmp->pixmap; + dc->w.DCSizeX = bmp->bitmap.bmWidth; + dc->w.DCSizeY = bmp->bitmap.bmHeight; + dc->w.hBitmap = hbitmap; /* Change GC depth if needed */ - if (dc->w.bitsPerPixel != bmp->bmBitsPixel) + if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel) { - XFreeGC( XT_display, dc->u.x.gc ); - dc->u.x.gc = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL ); - dc->w.bitsPerPixel = bmp->bmBitsPixel; - DC_SetDeviceInfo( hdc, dc ); + XFreeGC( display, dc->u.x.gc ); + dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL ); + dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel; + /* Re-select objects with changed depth */ + SelectObject( hdc, dc->w.hPen ); + SelectObject( hdc, dc->w.hBrush ); } - - GlobalUnlock( bitmap->hBitmap ); - dc->w.hBitmap = hbitmap; - bitmap->bSelected = TRUE; - bitmap->hdc = hdc; return prevHandle; } diff --git a/objects/brush.c b/objects/brush.c index 582349eca26..94641842cc2 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -7,6 +7,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" +#include "bitmap.h" +#include "prototypes.h" #define NB_HATCH_STYLES 6 @@ -21,7 +23,8 @@ static char HatchBrushes[NB_HATCH_STYLES][8] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 } /* HS_DIAGCROSS */ }; -extern XImage * BITMAP_BmpToImage( BITMAP *, void * ); +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); + /*********************************************************************** * CreateBrushIndirect (GDI.50) @@ -57,23 +60,21 @@ HBRUSH CreateHatchBrush( short style, COLORREF color ) HBRUSH CreatePatternBrush( HBITMAP hbitmap ) { LOGBRUSH logbrush = { BS_PATTERN, 0, 0 }; - BITMAPOBJ * bmpObj; - BITMAP * bmp; - + BITMAPOBJ *bmp, *newbmp; + #ifdef DEBUG_GDI printf( "CreatePatternBrush: %d\n", hbitmap ); #endif /* Make a copy of the bitmap */ - if (!(bmpObj = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0; - logbrush.lbHatch = CreateBitmap( bmp->bmWidth, bmp->bmHeight, - bmp->bmPlanes, bmp->bmBitsPixel, - ((char *)bmp) + sizeof(BITMAP) ); - GlobalUnlock( bmpObj->hBitmap ); - if (!logbrush.lbHatch) return 0; + logbrush.lbHatch = CreateBitmapIndirect( &bmp->bitmap ); + newbmp = (BITMAPOBJ *) GDI_GetObjPtr( logbrush.lbHatch, BITMAP_MAGIC ); + if (!newbmp) return 0; + XCopyArea( display, bmp->pixmap, newbmp->pixmap, BITMAP_GC(bmp), + 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, 0, 0 ); return CreateBrushIndirect( &logbrush ); } @@ -171,33 +172,47 @@ int BRUSH_GetObject( BRUSHOBJ * brush, int count, LPSTR buffer ) } +/*********************************************************************** + * BRUSH_MakeSolidBrush + */ +static void BRUSH_SelectSolidBrush( DC *dc, COLORREF color ) +{ + if ((dc->w.bitsPerPixel > 1) && !COLOR_IsSolid( color )) + { + /* Dithered brush */ + dc->u.x.brush.pixmap = DITHER_DitherColor( dc, color ); + dc->u.x.brush.fillStyle = FillTiled; + dc->u.x.brush.pixel = 0; + } + else + { + /* Solid brush */ + dc->u.x.brush.pixel = COLOR_ToPhysical( dc, color ); + dc->u.x.brush.fillStyle = FillSolid; + } +} + + /*********************************************************************** * BRUSH_SelectPatternBrush */ -BOOL BRUSH_SelectPatternBrush( DC * dc, HBITMAP hbitmap ) +static BOOL BRUSH_SelectPatternBrush( DC * dc, HBITMAP hbitmap ) { - BITMAPOBJ * bmpObjPtr; - BITMAP * bmp; + BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + if (!bmp) return FALSE; + dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow, + 8, 8, bmp->bitmap.bmBitsPixel ); + XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap, + BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 ); - bmpObjPtr = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); - if (!bmpObjPtr) return FALSE; - if (!(bmp = (BITMAP *) GlobalLock( bmpObjPtr->hBitmap ))) return FALSE; - - dc->u.x.brush.pixmap = XCreatePixmap( XT_display, - DefaultRootWindow(XT_display), - 8, 8, bmp->bmBitsPixel ); - BITMAP_CopyToPixmap( bmp, dc->u.x.brush.pixmap, 0, 0, 8, 8 ); - - if (bmp->bmBitsPixel > 1) + if (bmp->bitmap.bmBitsPixel > 1) { dc->u.x.brush.fillStyle = FillTiled; - XSetTile( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap ); dc->u.x.brush.pixel = 0; /* Ignored */ } else { dc->u.x.brush.fillStyle = FillOpaqueStippled; - XSetStipple( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap ); dc->u.x.brush.pixel = -1; /* Special case (see DC_SetupGCForBrush) */ } return TRUE; @@ -218,28 +233,24 @@ HBRUSH BRUSH_SelectObject( HDC hdc, DC * dc, HBRUSH hbrush, BRUSHOBJ * brush ) if (dc->u.x.brush.pixmap) { - XFreePixmap( XT_display, dc->u.x.brush.pixmap ); + XFreePixmap( display, dc->u.x.brush.pixmap ); dc->u.x.brush.pixmap = 0; } dc->u.x.brush.style = brush->logbrush.lbStyle; switch(brush->logbrush.lbStyle) { - case BS_SOLID: case BS_NULL: - dc->u.x.brush.pixel = GetNearestPaletteIndex( dc->w.hPalette, - brush->logbrush.lbColor ); - dc->u.x.brush.fillStyle = FillSolid; + break; + + case BS_SOLID: + BRUSH_SelectSolidBrush( dc, brush->logbrush.lbColor ); break; case BS_HATCHED: - dc->u.x.brush.pixel = GetNearestPaletteIndex( dc->w.hPalette, - brush->logbrush.lbColor ); - dc->u.x.brush.pixmap = XCreateBitmapFromData(XT_display, - DefaultRootWindow(XT_display), - HatchBrushes[brush->logbrush.lbHatch], - 8, 8 ); - XSetStipple( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap ); + dc->u.x.brush.pixel = COLOR_ToPhysical( dc, brush->logbrush.lbColor ); + dc->u.x.brush.pixmap = XCreateBitmapFromData( display, rootWindow, + HatchBrushes[brush->logbrush.lbHatch], 8, 8 ); dc->u.x.brush.fillStyle = FillStippled; break; @@ -264,5 +275,3 @@ HBRUSH BRUSH_SelectObject( HDC hdc, DC * dc, HBRUSH hbrush, BRUSHOBJ * brush ) return prevHandle; } - - diff --git a/objects/color.c b/objects/color.c index 8eb9c2e5b91..41f3ae63700 100644 --- a/objects/color.c +++ b/objects/color.c @@ -11,55 +11,46 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "options.h" - -extern Display * display; -extern Screen * screen; +#include "gdi.h" Colormap COLOR_WinColormap = 0; + /* System palette static colors */ - /* System colors */ +#define NB_RESERVED_COLORS 20 -static const char * SysColors[] = + /* The first and last eight colors are EGA colors */ +static PALETTEENTRY COLOR_sysPaletteEntries[NB_RESERVED_COLORS] = { - /* Low pixel values (0..7) */ + /* red green blue flags */ + { 0x00, 0x00, 0x00, 0 }, + { 0x80, 0x00, 0x00, 0 }, + { 0x00, 0x80, 0x00, 0 }, + { 0x80, 0x80, 0x00, 0 }, + { 0x00, 0x00, 0x80, 0 }, + { 0x80, 0x00, 0x80, 0 }, + { 0x00, 0x80, 0x80, 0 }, + { 0xc0, 0xc0, 0xc0, 0 }, + { 0xc0, 0xdc, 0xc0, 0 }, + { 0xa6, 0xca, 0xf0, 0 }, - "black", "red4", "green4", "yellow4", - "blue4", "magenta4", "cyan4", "gray50", - - /* High pixel values (max-7..max) */ - - "gray75", "red", "green", "yellow", - "blue", "magenta", "cyan", "white" + { 0xff, 0xfb, 0xf0, 0 }, + { 0xa0, 0xa0, 0xa4, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0xff, 0x00, 0x00, 0 }, + { 0x00, 0xff, 0x00, 0 }, + { 0xff, 0xff, 0x00, 0 }, + { 0x00, 0x00, 0xff, 0 }, + { 0xff, 0x00, 0xff, 0 }, + { 0x00, 0xff, 0xff, 0 }, + { 0xff, 0xff, 0xff, 0 } }; -#define NB_SYS_COLORS (sizeof(SysColors) / sizeof(SysColors[0])) +static HANDLE hSysColorTranslation = 0; - -/*********************************************************************** - * COLOR_FillDefaultMap - * - * Try to allocate colors from default screen map (used when we - * don't want to or can't use a private map). - */ -static int COLOR_FillDefaultMap() -{ - XColor color; - int i, total = 0; - - for (i = 0; i < NB_SYS_COLORS; i++) - { - if (XParseColor( display, DefaultColormapOfScreen( screen ), - SysColors[i], &color )) - { - if (XAllocColor( display, DefaultColormapOfScreen( screen ), - &color )) - total++; - } - } - return total; -} + /* Map an EGA index (0..15) to a pixel value. Used for dithering. */ +int COLOR_mapEGAPixel[16]; /*********************************************************************** @@ -70,50 +61,108 @@ static int COLOR_FillDefaultMap() static BOOL COLOR_BuildMap( Colormap map, int depth, int size ) { XColor color; - int i; + int r, g, b, red_incr, green_incr, blue_incr; + int index = 0; /* Fill the whole map with a range of colors */ - if ((1 << depth) > NB_SYS_COLORS) - { - int red_incr, green_incr, blue_incr; - int r, g, b; - - blue_incr = 0x10000 >> (depth / 3); - red_incr = 0x10000 >> ((depth + 1) / 3); - green_incr = 0x10000 >> ((depth + 2) / 3); + blue_incr = 0x10000 >> (depth / 3); + red_incr = 0x10000 >> ((depth + 1) / 3); + green_incr = 0x10000 >> ((depth + 2) / 3); - for (i = 0, r = red_incr - 1; r < 0x10000; r += red_incr) - for (g = green_incr - 1; g < 0x10000; g += green_incr) - for (b = blue_incr - 1; b < 0x10000; b += blue_incr) - { - if (i >= size) break; - color.pixel = i++; - color.red = r; - color.green = g; - color.blue = b; - XStoreColor( display, map, &color ); - } - } - - /* Store the system palette colors */ + for (r = red_incr - 1; r < 0x10000; r += red_incr) + for (g = green_incr - 1; g < 0x10000; g += green_incr) + for (b = blue_incr - 1; b < 0x10000; b += blue_incr) + { + if (index >= size) break; + color.pixel = index++; + color.red = r; + color.green = g; + color.blue = b; + XStoreColor( display, map, &color ); + } - for (i = 0; i < NB_SYS_COLORS; i++) - { - if (!XParseColor( display, map, SysColors[i], &color )) - color.red = color.green = color.blue = color.flags = 0; - if (i < NB_SYS_COLORS/2) color.pixel = i; - else color.pixel = (1 << depth) - NB_SYS_COLORS + i; - if (color.pixel < size) XStoreColor( display, map, &color ); - } return TRUE; } /*********************************************************************** - * COLOR_Init + * COLOR_InitPalette + * + * Create the system palette. */ -BOOL COLOR_Init() +static HPALETTE COLOR_InitPalette() +{ + int i, size; + XColor color; + HPALETTE hpalette; + LOGPALETTE * palPtr; + WORD *colorTranslation; + + if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE, + sizeof(WORD)*NB_RESERVED_COLORS ))) return FALSE; + colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation ); + size = DefaultVisual( display, DefaultScreen(display) )->map_entries; + for (i = 0; i < NB_RESERVED_COLORS; i++) + { + color.red = COLOR_sysPaletteEntries[i].peRed * 65535 / 255; + color.green = COLOR_sysPaletteEntries[i].peGreen * 65535 / 255; + color.blue = COLOR_sysPaletteEntries[i].peBlue * 65535 / 255; + color.flags = DoRed | DoGreen | DoBlue; + + 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; + } + XStoreColor( display, COLOR_WinColormap, &color ); + } + else if (!XAllocColor( display, COLOR_WinColormap, &color )) + { + printf( "Warning: Not enough free colors. Try using the -privatemap option.\n" ); + color.pixel = color.red = color.green = color.blue = 0; + } + 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 + /* Set EGA mapping if color in the first or last eight */ + if (i < 8) + COLOR_mapEGAPixel[i] = color.pixel; + else if (i >= NB_RESERVED_COLORS-8) + COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel; + } + + palPtr = malloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) ); + if (!palPtr) return FALSE; + palPtr->palVersion = 0x300; + palPtr->palNumEntries = NB_RESERVED_COLORS; + memcpy( palPtr->palPalEntry, COLOR_sysPaletteEntries, + sizeof(COLOR_sysPaletteEntries) ); + hpalette = CreatePalette( palPtr ); + free( palPtr ); + return hpalette; +} + + +/*********************************************************************** + * COLOR_Init + * + * Initialize color map and system palette. + */ +HPALETTE COLOR_Init() { Visual * visual = DefaultVisual( display, DefaultScreen(display) ); @@ -124,14 +173,19 @@ BOOL COLOR_Init() case DirectColor: if (Options.usePrivateMap) { - COLOR_WinColormap = XCreateColormap( display, - DefaultRootWindow(display), + COLOR_WinColormap = XCreateColormap( display, rootWindow, visual, AllocAll ); if (COLOR_WinColormap) { - COLOR_BuildMap(COLOR_WinColormap, - DefaultDepth(display, DefaultScreen(display)), - visual->map_entries ); + COLOR_BuildMap( COLOR_WinColormap, screenDepth, + visual->map_entries ); + if (rootWindow != DefaultRootWindow(display)) + { + XSetWindowAttributes win_attr; + win_attr.colormap = COLOR_WinColormap; + XChangeWindowAttributes( display, rootWindow, + CWColormap, &win_attr ); + } break; } } @@ -139,9 +193,109 @@ BOOL COLOR_Init() case StaticGray: case StaticColor: case TrueColor: - COLOR_FillDefaultMap(); COLOR_WinColormap = DefaultColormapOfScreen( screen ); break; } - return TRUE; + return COLOR_InitPalette(); +} + + +/*********************************************************************** + * COLOR_IsSolid + * + * Check whether 'color' can be represented with a solid color. + */ +BOOL COLOR_IsSolid( COLORREF color ) +{ + int i; + PALETTEENTRY *pEntry = COLOR_sysPaletteEntries; + + if (color & 0xff000000) return TRUE; + if (!color || (color == 0xffffff)) return TRUE; + for (i = NB_RESERVED_COLORS; i > 0; i--, pEntry++) + { + if ((GetRValue(color) == pEntry->peRed) && + (GetGValue(color) == pEntry->peGreen) && + (GetBValue(color) == pEntry->peBlue)) return TRUE; + } + return FALSE; +} + + +/*********************************************************************** + * COLOR_ToPhysical + * + * Return the physical color closest to 'color'. + */ +WORD COLOR_ToPhysical( DC *dc, COLORREF color ) +{ + WORD index = 0; + WORD *mapping; + + if (!dc->u.x.pal.hMapping) return 0; + switch(color & 0xff000000) + { + case 0: /* RGB */ + index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color ); + break; + case 1: /* PALETTEINDEX */ + index = color & 0xffff; + break; + case 2: /* PALETTERGB */ + index = GetNearestPaletteIndex( dc->w.hPalette, color ); + break; + } + if (index >= dc->u.x.pal.mappingSize) return 0; + mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); + return mapping[index]; +} + + +/*********************************************************************** + * COLOR_SetMapping + * + * Set the color-mapping table in a DC. + */ +void COLOR_SetMapping( DC *dc, HANDLE map, WORD size ) +{ + WORD *pmap, *pnewmap; + + if (dc->u.x.pal.hMapping && (dc->u.x.pal.hMapping != hSysColorTranslation)) + GDI_HEAP_FREE( dc->u.x.pal.hMapping ); + if (map && (map != hSysColorTranslation)) + { + /* Copy mapping table */ + dc->u.x.pal.hMapping = GDI_HEAP_ALLOC(GMEM_MOVEABLE,sizeof(WORD)*size); + pmap = (WORD *) GDI_HEAP_ADDR( map ); + pnewmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); + memcpy( pnewmap, pmap, sizeof(WORD)*size ); + } + else dc->u.x.pal.hMapping = map; + dc->u.x.pal.mappingSize = size; +} + + +/*********************************************************************** + * GetNearestColor (GDI.154) + */ +COLORREF GetNearestColor( HDC hdc, COLORREF color ) +{ + WORD index; + DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + if (!dc) return 0; + index = COLOR_ToPhysical( dc, color & 0xffffff ); + return PALETTEINDEX( index ); +} + + +/*********************************************************************** + * RealizeDefaultPalette (GDI.365) + */ +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 ); + return NB_RESERVED_COLORS; } diff --git a/objects/dcvalues.c b/objects/dcvalues.c index 73c98aabedd..12b775f1b02 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c @@ -40,7 +40,6 @@ const WIN_DC_INFO DCVAL_defaultValues = 0, /* breakCount */ 0, /* breakExtra */ 0, /* breakRem */ - 1, /* planes */ 1, /* bitsPerPixel */ MM_TEXT, /* MapMode */ 0, /* DCOrgX */ diff --git a/objects/dib.c b/objects/dib.c index 15e3d09594b..c6d9d4474f3 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -8,13 +8,13 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include - +#include +#include #include "gdi.h" +#include "bitmap.h" #include "icon.h" - -extern XImage * BITMAP_BmpToImage( BITMAP *, void * ); - +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); /* color.c */ /*********************************************************************** * DIB_BitmapInfoSize @@ -39,8 +39,9 @@ int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse ) * * Create an XImage pointing to the bitmap data. */ -XImage * DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) +static XImage *DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) { + extern void _XInitImageFuncPtrs( XImage* ); XImage * image; int bytesPerLine = (bmp->biWidth * bmp->biBitCount + 31) / 32 * 4; @@ -56,6 +57,198 @@ XImage * DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) } +/*********************************************************************** + * DIB_SetImageBits_1 + * + * SetDIBits for a 1-bit deep DIB. + */ +static void DIB_SetImageBits_1( WORD lines, BYTE *bits, WORD width, + WORD *colors, XImage *bmpImage ) +{ + WORD i, x; + BYTE pad, pix; + + if (!(width & 31)) pad = 0; + else pad = ((32 - (width & 31)) + 7) / 8; + + while (lines--) + { + for (i = width/8, x = 0; (i > 0); i--) + { + pix = *bits++; + XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 6) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 5) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 4) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 3) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 2) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 1) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[pix & 1] ); + } + pix = *bits; + switch(width & 7) + { + case 7: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 6: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 5: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 4: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 3: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 2: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 1: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); + } + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits_4 + * + * SetDIBits for a 4-bit deep DIB. + */ +static void DIB_SetImageBits_4( WORD lines, BYTE *bits, WORD width, + WORD *colors, XImage *bmpImage ) +{ + WORD i, x; + BYTE pad; + + if (!(width & 7)) pad = 0; + else pad = ((8 - (width & 7)) + 1) / 2; + + while (lines--) + { + for (i = width/2, x = 0; i > 0; i--) + { + BYTE pix = *bits++; + XPutPixel( bmpImage, x++, lines, colors[pix >> 4] ); + XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] ); + } + if (width & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] ); + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits_8 + * + * SetDIBits for an 8-bit deep DIB. + */ +static void DIB_SetImageBits_8( WORD lines, BYTE *bits, WORD width, + WORD *colors, XImage *bmpImage ) +{ + WORD x; + BYTE pad = (4 - (width & 3)) & 3; + + while (lines--) + { + for (x = 0; x < width; x++) + XPutPixel( bmpImage, x, lines, colors[*bits++] ); + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits_24 + * + * SetDIBits for a 24-bit deep DIB. + */ +static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width, + DC *dc, XImage *bmpImage ) +{ + WORD x; + BYTE pad = (4 - ((width*3) & 3)) & 3; + + while (lines--) + { + for (x = 0; x < width; x++, bits += 3) + { + XPutPixel( bmpImage, x, lines, + COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) )); + } + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits + * + * Transfer the bits to an X image. + * Helper function for SetDIBits() and SetDIBitsToDevice(). + */ +static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits, + BITMAPINFO *info, WORD coloruse, + Drawable drawable, GC gc, int xSrc, int ySrc, + int xDest, int yDest, int width, int height ) +{ + WORD *colorMapping; + XImage *bmpImage; + void *bmpData; + int i, colors, widthBytes; + + /* Build the color mapping table */ + + if (info->bmiHeader.biBitCount == 24) colorMapping = NULL; + else + { + colors = info->bmiHeader.biClrUsed; + if (!colors) colors = 1 << info->bmiHeader.biBitCount; + if (!(colorMapping = (WORD *)malloc( colors * sizeof(WORD) ))) + return 0; + if (coloruse == DIB_RGB_COLORS) + { + RGBQUAD * rgbPtr = info->bmiColors; + for (i = 0; i < colors; i++, rgbPtr++) + colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgbPtr->rgbRed, + rgbPtr->rgbGreen, + rgbPtr->rgbBlue) ); + } + else + { + WORD * index = (WORD *)info->bmiColors; + for (i = 0; i < colors; i++, index++) + colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*index) ); + } + } + + /* Transfer the pixels */ + + widthBytes = (info->bmiHeader.biWidth * depth + 31) / 32 * 4; + bmpData = malloc( lines * widthBytes ); + bmpImage = XCreateImage( display, DefaultVisualOfScreen(screen), + depth, ZPixmap, 0, bmpData, + info->bmiHeader.biWidth, lines, 32, widthBytes ); + + switch(info->bmiHeader.biBitCount) + { + case 1: + DIB_SetImageBits_1( lines, bits, info->bmiHeader.biWidth, + colorMapping, bmpImage ); + break; + case 4: + DIB_SetImageBits_4( lines, bits, info->bmiHeader.biWidth, + colorMapping, bmpImage ); + break; + case 8: + DIB_SetImageBits_8( lines, bits, info->bmiHeader.biWidth, + colorMapping, bmpImage ); + break; + case 24: + DIB_SetImageBits_24( lines, bits, info->bmiHeader.biWidth, + dc, bmpImage ); + break; + } + if (colorMapping) free(colorMapping); + + XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc, + xDest, yDest, width, height ); + XDestroyImage( bmpImage ); + return lines; +} + + /*********************************************************************** * SetDIBits (GDI.440) */ @@ -63,64 +256,53 @@ int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, LPSTR bits, BITMAPINFO * info, WORD coloruse ) { DC * dc; - BITMAPOBJ * bmpObj; - BITMAP * bmp; - WORD * colorMapping; - RGBQUAD * rgbPtr; - XImage * bmpImage, * dibImage; - int i, x, y, pixel, colors; - - if (!lines) return 0; + BITMAPOBJ * bmp; + + /* Check parameters */ + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0; + if (!lines || (startscan >= (WORD)info->bmiHeader.biHeight)) return 0; + if (startscan+lines > info->bmiHeader.biHeight) + lines = info->bmiHeader.biHeight - startscan; - /* Build the color mapping table */ + return DIB_SetImageBits( dc, lines, bmp->bitmap.bmBitsPixel, + bits, info, coloruse, bmp->pixmap, BITMAP_GC(bmp), + 0, 0, 0, startscan, bmp->bitmap.bmWidth, lines ); +} - if (info->bmiHeader.biBitCount == 24) colorMapping = NULL; - else if (coloruse == DIB_RGB_COLORS) - { - colors = info->bmiHeader.biClrUsed; - if (!colors) colors = 1 << info->bmiHeader.biBitCount; - if (!(colorMapping = (WORD *)malloc( colors * sizeof(WORD) ))) - { - GlobalUnlock( bmpObj->hBitmap ); - return 0; - } - for (i = 0, rgbPtr = info->bmiColors; i < colors; i++, rgbPtr++) - colorMapping[i] = GetNearestPaletteIndex( dc->w.hPalette, - RGB(rgbPtr->rgbRed, - rgbPtr->rgbGreen, - rgbPtr->rgbBlue) ); - } - else colorMapping = (WORD *)info->bmiColors; - /* Transfer the pixels (very slow...) */ +/*********************************************************************** + * SetDIBitsToDevice (GDI.443) + */ +int SetDIBitsToDevice( HDC hdc, short xDest, short yDest, WORD cx, WORD cy, + WORD xSrc, WORD ySrc, WORD startscan, WORD lines, + LPSTR bits, BITMAPINFO * info, WORD coloruse ) +{ + DC * dc; - bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); - dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits ); + /* Check parameters */ - for (y = 0; y < lines; y++) - { - for (x = 0; x < info->bmiHeader.biWidth; x++) - { - pixel = XGetPixel( dibImage, x, y ); - if (colorMapping) pixel = colorMapping[pixel]; - else pixel = GetNearestPaletteIndex(dc->w.hPalette,(COLORREF)pixel); - XPutPixel( bmpImage, x, bmp->bmHeight - startscan - y - 1, pixel ); - } - } + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + if (!lines || (startscan >= info->bmiHeader.biHeight)) return 0; + if (startscan+lines > info->bmiHeader.biHeight) + lines = info->bmiHeader.biHeight - startscan; + if (ySrc < startscan) ySrc = startscan; + else if (ySrc >= startscan+lines) return 0; + if (xSrc >= info->bmiHeader.biWidth) return 0; + if (ySrc+cy >= startscan+lines) cy = startscan + lines - ySrc; + if (xSrc+cx >= info->bmiHeader.biWidth) cx = info->bmiHeader.biWidth-xSrc; + if (!cx || !cy) return 0; - bmpImage->data = NULL; - dibImage->data = NULL; - XDestroyImage( bmpImage ); - XDestroyImage( dibImage ); - - if (colorMapping && (coloruse == DIB_RGB_COLORS)) free(colorMapping); - - GlobalUnlock( bmpObj->hBitmap ); - return lines; + DC_SetupGCForText( dc ); /* To have the correct ROP */ + return DIB_SetImageBits( dc, lines, dc->w.bitsPerPixel, + bits, info, coloruse, + dc->u.x.drawable, dc->u.x.gc, + xSrc, ySrc - startscan, + dc->w.DCOrgX + XLPTODP( dc, xDest ), + dc->w.DCOrgY + YLPTODP( dc, yDest ), + cx, cy ); } @@ -131,8 +313,7 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, LPSTR bits, BITMAPINFO * info, WORD coloruse ) { DC * dc; - BITMAPOBJ * bmpObj; - BITMAP * bmp; + BITMAPOBJ * bmp; PALETTEENTRY * palEntry; PALETTEOBJ * palette; XImage * bmpImage, * dibImage; @@ -140,11 +321,10 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, if (!lines) return 0; if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0; if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC ))) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0; /* Transfer color info */ @@ -165,7 +345,8 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, if (bits) { - bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); + bmpImage = XGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, + bmp->bitmap.bmHeight, AllPlanes, ZPixmap ); dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits ); for (y = 0; y < lines; y++) @@ -173,18 +354,15 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, for (x = 0; x < info->bmiHeader.biWidth; x++) { XPutPixel( dibImage, x, y, - XGetPixel(bmpImage, x, bmp->bmHeight-startscan-y-1) ); + XGetPixel(bmpImage, x, bmp->bitmap.bmHeight-startscan-y-1) ); } } - bmpImage->data = NULL; dibImage->data = NULL; - XDestroyImage( bmpImage ); XDestroyImage( dibImage ); + XDestroyImage( bmpImage ); } - - GlobalUnlock( bmpObj->hBitmap ); return lines; } diff --git a/objects/dither.c b/objects/dither.c new file mode 100644 index 00000000000..52101063ac6 --- /dev/null +++ b/objects/dither.c @@ -0,0 +1,140 @@ +/* + * Dithering functions + * + * Copyright 1994 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1994"; + +#include +#include +#include + +#include "gdi.h" +#include "bitmap.h" + + + /* Levels of each primary */ +#define PRIMARY_LEVELS 3 +#define TOTAL_LEVELS (PRIMARY_LEVELS*PRIMARY_LEVELS*PRIMARY_LEVELS) + + /* Dithering matrix size */ +#define MATRIX_SIZE 8 +#define MATRIX_SIZE_2 (MATRIX_SIZE*MATRIX_SIZE) + + /* Total number of possible levels for a dithered primary color */ +#define DITHER_LEVELS (MATRIX_SIZE_2 * (PRIMARY_LEVELS-1) + 1) + + /* Dithering matrix */ +static const int dither_matrix[MATRIX_SIZE_2] = +{ + 0, 32, 8, 40, 2, 34, 10, 42, + 48, 16, 56, 24, 50, 18, 58, 26, + 12, 44, 4, 36, 14, 46, 6, 38, + 60, 28, 52, 20, 62, 30, 54, 22, + 3, 35, 11, 43, 1, 33, 9, 41, + 51, 19, 59, 27, 49, 17, 57, 25, + 15, 47, 7, 39, 13, 45, 5, 37, + 63, 31, 55, 23, 61, 29, 53, 21 +}; + + /* Mapping between (R,G,B) triples and EGA colors */ +static const int EGAmapping[TOTAL_LEVELS] = +{ + 0, /* 000000 -> 000000 */ + 4, /* 00007f -> 000080 */ + 12, /* 0000ff -> 0000ff */ + 2, /* 007f00 -> 008000 */ + 6, /* 007f7f -> 008080 */ + 6, /* 007fff -> 008080 */ + 10, /* 00ff00 -> 00ff00 */ + 6, /* 00ff7f -> 008080 */ + 14, /* 00ffff -> 00ffff */ + 1, /* 7f0000 -> 800000 */ + 5, /* 7f007f -> 800080 */ + 5, /* 7f00ff -> 800080 */ + 3, /* 7f7f00 -> 808000 */ + 8, /* 7f7f7f -> 808080 */ + 7, /* 7f7fff -> c0c0c0 */ + 3, /* 7fff00 -> 808000 */ + 7, /* 7fff7f -> c0c0c0 */ + 7, /* 7fffff -> c0c0c0 */ + 9, /* ff0000 -> ff0000 */ + 5, /* ff007f -> 800080 */ + 13, /* ff00ff -> ff00ff */ + 3, /* ff7f00 -> 808000 */ + 7, /* ff7f7f -> c0c0c0 */ + 7, /* ff7fff -> c0c0c0 */ + 11, /* ffff00 -> ffff00 */ + 7, /* ffff7f -> c0c0c0 */ + 15 /* ffffff -> ffffff */ +}; + + /* Map an EGA index (0..15) to a pixel value */ +extern int COLOR_mapEGAPixel[16]; /* in color.c */ + +#define PIXEL_VALUE(r,g,b) \ + COLOR_mapEGAPixel[EGAmapping[((r)*PRIMARY_LEVELS+(g))*PRIMARY_LEVELS+(b)]] + + /* X image for building dithered pixmap */ +static XImage *ditherImage = NULL; +static char *imageData = NULL; + + +/*********************************************************************** + * DITHER_Init + * + * Create the X image used for dithering. + */ +BOOL DITHER_Init() +{ + 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 ); + return (ditherImage != NULL); +} + + +/*********************************************************************** + * DITHER_DitherColor + */ +Pixmap DITHER_DitherColor( DC *dc, COLORREF color ) +{ + static COLORREF prevColor = 0xffffffff; + unsigned int x, y; + Pixmap pixmap; + +/* printf( "Dither: %x\n", color ); */ + + if (color != prevColor) + { + int r = GetRValue( color ) * DITHER_LEVELS; + int g = GetGValue( color ) * DITHER_LEVELS; + 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++) + { + int d = *pmatrix++ * 256; + int dr = ((r + d) / MATRIX_SIZE_2) / 256; + int dg = ((g + d) / MATRIX_SIZE_2) / 256; + int db = ((b + d) / MATRIX_SIZE_2) / 256; + XPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) ); + } + } + prevColor = color; + } + + pixmap = XCreatePixmap( display, rootWindow, + MATRIX_SIZE, MATRIX_SIZE, screenDepth ); + XPutImage( display, pixmap, BITMAP_colorGC, ditherImage, 0, 0, + 0, 0, MATRIX_SIZE, MATRIX_SIZE ); + return pixmap; +} diff --git a/objects/font.c b/objects/font.c index 883e699bf98..382976b2235 100644 --- a/objects/font.c +++ b/objects/font.c @@ -8,6 +8,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include +#include #include #include "gdi.h" @@ -17,7 +18,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; * * Find a X font matching the logical font. */ -XFontStruct * FONT_MatchFont( DC * dc, LOGFONT * font ) +static XFontStruct * FONT_MatchFont( LOGFONT * font ) { char pattern[100]; char *family, *weight, *charset; @@ -44,8 +45,16 @@ XFontStruct * FONT_MatchFont( DC * dc, LOGFONT * font ) default: family = "*"; break; } - sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s", - family, weight, slant, height, spacing, width, charset ); + /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */ + if ( width == 0 ) + sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-*-%s", + family, weight, slant, height, spacing, charset + ); + else + sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s", + family, weight, slant, height, spacing, width, charset + ); + #ifdef DEBUG_FONT printf( "FONT_MatchFont: '%s'\n", pattern ); #endif @@ -166,13 +175,24 @@ HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font ) /* Load font if necessary */ + if (!font) + { + HFONT hnewfont; + + hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE, + FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, + DEFAULT_QUALITY, FF_DONTCARE, "*" ); + font = (FONTOBJ *) GDI_HEAP_ADDR( hnewfont ); + } + if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT)) stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT]; - else stockPtr = NULL; + else + stockPtr = NULL; if (!stockPtr || !stockPtr->fstruct) { - fontStruct = FONT_MatchFont( dc, &font->logfont ); + fontStruct = FONT_MatchFont( &font->logfont ); } else { diff --git a/objects/gdiobj.c b/objects/gdiobj.c index bc59d860b15..cd7888755c3 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -6,11 +6,14 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include +#include #include "gdi.h" - +#include "prototypes.h" MDESC *GDI_Heap = NULL; +extern HPALETTE COLOR_Init(); /* color.c */ /*********************************************************************** * GDI stock objects @@ -130,12 +133,10 @@ static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] = (GDIOBJHDR *) &AnsiVarFont, (GDIOBJHDR *) &SystemFont, (GDIOBJHDR *) &DeviceDefaultFont, - NULL, /* DEFAULT_PALETTE created by PALETTE_Init */ + NULL, /* DEFAULT_PALETTE created by COLOR_Init */ (GDIOBJHDR *) &SystemFixedFont }; -extern GDIOBJHDR * PALETTE_systemPalette; - /*********************************************************************** * GDI_Init @@ -144,6 +145,7 @@ extern GDIOBJHDR * PALETTE_systemPalette; */ BOOL GDI_Init() { + HPALETTE hpalette; struct segment_descriptor_s * s; #ifndef WINELIB @@ -156,9 +158,8 @@ BOOL GDI_Init() /* Create default palette */ - COLOR_Init(); - PALETTE_Init(); - StockObjects[DEFAULT_PALETTE] = PALETTE_systemPalette; + if (!(hpalette = COLOR_Init())) return FALSE; + StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette ); /* Create default bitmap */ @@ -168,6 +169,10 @@ BOOL GDI_Init() if (!REGION_Init()) return FALSE; + /* Initialise dithering */ + + if (!DITHER_Init()) return FALSE; + return TRUE; } @@ -217,7 +222,6 @@ HANDLE GDI_AllocObject( WORD size, WORD magic ) BOOL GDI_FreeObject( HANDLE handle ) { GDIOBJHDR * object; - HANDLE prev; /* Can't free stock objects */ if (handle >= FIRST_STOCK_HANDLE) return FALSE; diff --git a/objects/palette.c b/objects/palette.c index 03300c43778..dc52635a23e 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -1,62 +1,32 @@ /* * GDI palette objects * - * Copyright 1993 Alexandre Julliard + * Copyright 1993,1994 Alexandre Julliard */ -static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +static char Copyright[] = "Copyright Alexandre Julliard, 1993,1994"; #include +#include +#include +/* #ifdef linux #include #endif +*/ + #if !defined (MAXINT) #include #define MAXINT INT_MAX #endif #include - #include "gdi.h" +extern void COLOR_SetMapping( DC *dc, HANDLE map, WORD size ); /* color.c */ + extern Colormap COLOR_WinColormap; -GDIOBJHDR * PALETTE_systemPalette; - - -/*********************************************************************** - * PALETTE_Init - */ -BOOL PALETTE_Init() -{ - int i, size; - XColor color; - HPALETTE hpalette; - LOGPALETTE * palPtr; - - size = DefaultVisual( display, DefaultScreen(display) )->map_entries; - palPtr = malloc( sizeof(LOGPALETTE) + (size-1)*sizeof(PALETTEENTRY) ); - if (!palPtr) return FALSE; - palPtr->palVersion = 0x300; - palPtr->palNumEntries = size; - memset( palPtr->palPalEntry, 0xff, size*sizeof(PALETTEENTRY) ); - - for (i = 0; i < size; i++) - { - color.pixel = i; - XQueryColor( display, COLOR_WinColormap, &color ); - palPtr->palPalEntry[i].peRed = color.red >> 8; - palPtr->palPalEntry[i].peGreen = color.green >> 8; - palPtr->palPalEntry[i].peBlue = color.blue >> 8; - palPtr->palPalEntry[i].peFlags = 0; - } - - hpalette = CreatePalette( palPtr ); - PALETTE_systemPalette = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette ); - free( palPtr ); - return TRUE; -} - /*********************************************************************** * CreatePalette (GDI.360) @@ -116,6 +86,33 @@ WORD SetPaletteEntries( HPALETTE hpalette, WORD start, WORD count, } +/*********************************************************************** + * GetSystemPaletteEntries (GDI.375) + */ +WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count, + LPPALETTEENTRY entries ) +{ + WORD i; + DC *dc; + XColor color; + + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + if (start >= dc->w.devCaps->sizePalette) return 0; + if (start+count >= dc->w.devCaps->sizePalette) + count = dc->w.devCaps->sizePalette - start; + for (i = 0; i < count; i++) + { + color.pixel = start + i; + XQueryColor( display, COLOR_WinColormap, &color ); + entries[i].peRed = color.red >> 8; + entries[i].peGreen = color.green >> 8; + entries[i].peBlue = color.blue >> 8; + entries[i].peFlags = 0; + } + return count; +} + + /*********************************************************************** * GetNearestPaletteIndex (GDI.370) */ @@ -143,7 +140,8 @@ WORD GetNearestPaletteIndex( HPALETTE hpalette, COLORREF color ) b = GetBValue(color); entry = palPtr->logpalette.palPalEntry; - for (i = 0, minDist = MAXINT; i < palPtr->logpalette.palNumEntries; i++) + for (i = 0, minDist = MAXINT; minDist !=0 && + i < palPtr->logpalette.palNumEntries ; i++) { if (entry->peFlags != 0xff) { @@ -177,19 +175,52 @@ int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer ) } +/*********************************************************************** + * GDISelectPalette (GDI.361) + */ +HPALETTE GDISelectPalette( HDC hdc, HPALETTE hpal ) +{ + HPALETTE prev; + DC *dc; + +#ifdef DEBUG_PALETTE + printf( "GDISelectPalette: %d %d\n", hdc, hpal ); +#endif + 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 ); + else RealizeDefaultPalette( hdc ); /* Always realize default palette */ + return prev; +} + + +/*********************************************************************** + * GDIRealizePalette (GDI.362) + */ +UINT GDIRealizePalette( HDC hdc ) +{ +#ifdef DEBUG_PALETTE + printf( "GDIRealizePalette: %d\n", hdc ); +#endif + return 0; +} + + /*********************************************************************** * SelectPalette (USER.282) */ HPALETTE SelectPalette(HDC hDC, HPALETTE hPal, BOOL bForceBackground) { - return (HPALETTE)NULL; + return GDISelectPalette( hDC, hPal ); } + /*********************************************************************** * RealizePalette (USER.283) */ -int RealizePalette(HDC hDC) +UINT RealizePalette(HDC hDC) { - return 0; + return GDIRealizePalette( hDC ); } diff --git a/objects/pen.c b/objects/pen.c index a0a7ad78632..48da2526a73 100644 --- a/objects/pen.c +++ b/objects/pen.c @@ -8,6 +8,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); /*********************************************************************** * CreatePen (GDI.61) @@ -68,21 +69,24 @@ HPEN PEN_SelectObject( DC * dc, HPEN hpen, PENOBJ * pen ) / dc->w.WndExtX; if (dc->u.x.pen.width < 0) dc->u.x.pen.width = -dc->u.x.pen.width; if (dc->u.x.pen.width == 1) dc->u.x.pen.width = 0; /* Faster */ - dc->u.x.pen.pixel = GetNearestPaletteIndex( dc->w.hPalette, - pen->logpen.lopnColor ); + dc->u.x.pen.pixel = COLOR_ToPhysical( dc, pen->logpen.lopnColor ); switch(pen->logpen.lopnStyle) { case PS_DASH: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dash, 2 ); + dc->u.x.pen.dashes = dash_dash; + dc->u.x.pen.dash_len = 2; break; case PS_DOT: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dot, 2 ); + dc->u.x.pen.dashes = dash_dot; + dc->u.x.pen.dash_len = 2; break; case PS_DASHDOT: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dashdot, 4 ); + dc->u.x.pen.dashes = dash_dashdot; + dc->u.x.pen.dash_len = 4; break; case PS_DASHDOTDOT: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dashdotdot, 6 ); + dc->u.x.pen.dashes = dash_dashdotdot; + dc->u.x.pen.dash_len = 6; break; } diff --git a/objects/region.c b/objects/region.c index 3a7b9ef290a..afe4dd449df 100644 --- a/objects/region.c +++ b/objects/region.c @@ -8,13 +8,13 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include +#include +#include #include "gdi.h" - /* GC used for region operations */ static GC regionGC = 0; - /*********************************************************************** * REGION_Init */ @@ -23,8 +23,7 @@ BOOL REGION_Init() Pixmap tmpPixmap; /* CreateGC needs a drawable */ - tmpPixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - 1, 1, 1 ); + tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 ); if (tmpPixmap) { regionGC = XCreateGC( XT_display, tmpPixmap, 0, NULL ); @@ -68,8 +67,7 @@ static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect ) /* Create pixmap */ - region->pixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - width, height, 1 ); + region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); if (!region->pixmap) return FALSE; /* Fill pixmap */ @@ -576,8 +574,19 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) width = region->box.right - region->box.left; height = region->box.bottom - region->box.top; - region->pixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - width, height, 1 ); + if (!width || !height) + { + printf( "CombineRgn: width or height is 0. Please report this.\n" ); + printf( "src1=%d,%d-%d,%d src2=%d,%d-%d,%d dst=%d,%d-%d,%d op=%d\n", + src1Obj->region.box.left, src1Obj->region.box.top, + src1Obj->region.box.right, src1Obj->region.box.bottom, + src2Obj->region.box.left, src2Obj->region.box.top, + src2Obj->region.box.right, src2Obj->region.box.bottom, + region->box.left, region->box.top, + region->box.right, region->box.bottom, mode ); + exit(1); + } + region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); switch(mode) { diff --git a/objects/text.c b/objects/text.c index 787b0f72737..a900baa136c 100644 --- a/objects/text.c +++ b/objects/text.c @@ -221,7 +221,6 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) (rect->bottom - rect->top) / 2 - size.cy / 2; else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } - if (!(flags & DT_CALCRECT)) if (!TextOut(hdc, x, y, line, len)) return 0; if (prefix_offset != -1) diff --git a/test/blandmdi.exe b/test/blandmdi.exe new file mode 100644 index 00000000000..6dc03d50d5a Binary files /dev/null and b/test/blandmdi.exe differ diff --git a/test/btnlook.exe b/test/btnlook.exe deleted file mode 100755 index d952b617895..00000000000 Binary files a/test/btnlook.exe and /dev/null differ diff --git a/test/hw.exe b/test/hw.exe deleted file mode 100755 index 0567dc3e0d7..00000000000 Binary files a/test/hw.exe and /dev/null differ diff --git a/test/hyperoid.exe b/test/hyperoid.exe deleted file mode 100644 index 4e689f0eeb6..00000000000 Binary files a/test/hyperoid.exe and /dev/null differ diff --git a/test/menutest.exe b/test/menutest.exe deleted file mode 100755 index ad4f7912b4c..00000000000 Binary files a/test/menutest.exe and /dev/null differ diff --git a/test/winetest2.exe b/test/winetest2.exe deleted file mode 100755 index 57d7edcd549..00000000000 Binary files a/test/winetest2.exe and /dev/null differ diff --git a/toolkit/Imakefile b/toolkit/Imakefile index 53a7da3ffc0..5ddccc8a75e 100644 --- a/toolkit/Imakefile +++ b/toolkit/Imakefile @@ -3,6 +3,7 @@ MODULE = toolkit SRCS = \ + arch.c \ heap.c \ sup.c \ winmain.c diff --git a/toolkit/arch.c b/toolkit/arch.c new file mode 100644 index 00000000000..9f9c6c70d8b --- /dev/null +++ b/toolkit/arch.c @@ -0,0 +1,32 @@ +/* + * Big endian structure conversion routines + * + * Copyright Miguel de Icaza, 1994 + */ + +#include "arch.h" +#include "windows.h" + +void ARCH_ConvBitmapInfo (BITMAPINFOHEADER *image) +{ + image->biSize = CONV_LONG (image->biSize); + image->biWidth = CONV_LONG (image->biWidth); + image->biHeight = CONV_LONG (image->biHeight); + image->biPlanes = CONV_SHORT (image->biPlanes); + image->biBitCount = CONV_SHORT (image->biBitCount); + image->biCompression = CONV_LONG (image->biCompression); + image->biSizeImage = CONV_LONG (image->biSizeImage); + image->biXPelsPerMeter = CONV_LONG (image->biXPelsPerMeter); + image->biYPelsPerMeter = CONV_LONG (image->biYPelsPerMeter); + image->biClrUsed = CONV_LONG (image->biClrUsed); + image->biClrImportant = CONV_LONG (image->biClrImportant); +} + +void ARCH_ConvCoreHeader (BITMAPCOREHEADER *image) +{ + image->bcSize = CONV_LONG (image->bcSize); + image->bcWidth = CONV_SHORT (image->bcWidth); + image->bcHeight = CONV_SHORT (image->bcHeight); + image->bcPlanes = CONV_SHORT (image->bcPlanes); + image->bcBitCount = CONV_SHORT (image->bcBitCount); +} diff --git a/tools/Imakefile b/tools/Imakefile index 7b739a187fa..c993ef4f38d 100644 --- a/tools/Imakefile +++ b/tools/Imakefile @@ -2,4 +2,8 @@ MODULE = tools +#ifndef NewBuild SimpleProgramTarget(build) +#else +SimpleProgramTarget(newbuild) +#endif \ No newline at end of file diff --git a/tools/newbuild.c b/tools/newbuild.c new file mode 100644 index 00000000000..647594f239c --- /dev/null +++ b/tools/newbuild.c @@ -0,0 +1,954 @@ +static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; +static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; + +#include +#include +#include +#include + +#ifdef linux +#define UTEXTSEL 0x23 +#define UDATASEL 0x2b +#endif +#if defined(__NetBSD__) || defined(__FreeBSD__) +#define UTEXTSEL 0x1f +#define UDATASEL 0x27 +#endif + +#define VARTYPE_BYTE 0 +#define VARTYPE_SIGNEDWORD 0 +#define VARTYPE_WORD 1 +#define VARTYPE_LONG 2 +#define VARTYPE_FARPTR 3 + +#define FUNCTYPE_PASCAL 16 +#define FUNCTYPE_C 17 +#define FUNCTYPE_REG 19 + +#define EQUATETYPE_ABS 18 +#define TYPE_RETURN 20 + +#define MAX_ORDINALS 1024 + +typedef struct ordinal_definition_s +{ + int valid; + int type; + char export_name[80]; + void *additional_data; +} ORDDEF; + +typedef struct ordinal_variable_definition_s +{ + int n_values; + int *values; +} ORDVARDEF; + +typedef struct ordinal_function_definition_s +{ + int n_args_16; + int arg_types_16[16]; + int arg_16_offsets[16]; + int arg_16_size; + char internal_name[80]; + int n_args_32; + int arg_indices_32[16]; +} ORDFUNCDEF; + +typedef struct ordinal_return_definition_s +{ + int arg_size; + int ret_value; +} ORDRETDEF; + +ORDDEF OrdinalDefinitions[MAX_ORDINALS]; + +char LowerDLLName[80]; +char UpperDLLName[80]; +int Limit; +int DLLId; +FILE *SpecFp; + +char *ParseBuffer = NULL; +char *ParseNext; +char ParseSaveChar; +int Line; + +int IsNumberString(char *s) +{ + while (*s != '\0') + if (!isdigit(*s++)) + return 0; + + return 1; +} + +char *strlower(char *s) +{ + char *p; + + for(p = s; *p != '\0'; p++) + *p = tolower(*p); + + return s; +} + +char *strupper(char *s) +{ + char *p; + + for(p = s; *p != '\0'; p++) + *p = toupper(*p); + + return s; +} + +int stricmp(char *s1, char *s2) +{ + if (strlen(s1) != strlen(s2)) + return -1; + + while (*s1 != '\0') + if (*s1++ != *s2++) + return -1; + + return 0; +} + +char * +GetTokenInLine(void) +{ + char *p; + char *token; + + if (ParseNext != ParseBuffer) + { + if (ParseSaveChar == '\0') + return NULL; + *ParseNext = ParseSaveChar; + } + + /* + * Remove initial white space. + */ + for (p = ParseNext; isspace(*p); p++) + ; + + if (*p == '\0') + return NULL; + + /* + * Find end of token. + */ + token = p++; + if (*token != '(' && *token != ')') + while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p)) + p++; + + ParseSaveChar = *p; + ParseNext = p; + *p = '\0'; + + return token; +} + +char * +GetToken(void) +{ + char *token; + + if (ParseBuffer == NULL) + { + ParseBuffer = malloc(512); + ParseNext = ParseBuffer; + Line++; + while (1) + { + if (fgets(ParseBuffer, 511, SpecFp) == NULL) + return NULL; + if (ParseBuffer[0] != '#') + break; + } + } + + while ((token = GetTokenInLine()) == NULL) + { + ParseNext = ParseBuffer; + Line++; + while (1) + { + if (fgets(ParseBuffer, 511, SpecFp) == NULL) + return NULL; + if (ParseBuffer[0] != '#') + break; + } + } + + return token; +} + +int +ParseVariable(int ordinal, int type) +{ + ORDDEF *odp; + ORDVARDEF *vdp; + char export_name[80]; + char *token; + char *endptr; + int *value_array; + int n_values; + int value_array_size; + + strcpy(export_name, GetToken()); + + token = GetToken(); + if (*token != '(') + { + fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token); + exit(1); + } + + n_values = 0; + value_array_size = 25; + value_array = malloc(sizeof(*value_array) * value_array_size); + + while ((token = GetToken()) != NULL) + { + if (*token == ')') + break; + + value_array[n_values++] = strtol(token, &endptr, 0); + if (n_values == value_array_size) + { + value_array_size += 25; + value_array = realloc(value_array, + sizeof(*value_array) * value_array_size); + } + + if (endptr == NULL || *endptr != '\0') + { + fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, + token); + exit(1); + } + } + + if (token == NULL) + { + fprintf(stderr, "%d: End of file in variable declaration\n", Line); + exit(1); + } + + if (ordinal >= MAX_ORDINALS) + { + fprintf(stderr, "%d: Ordinal number too large\n", Line); + exit(1); + } + + odp = &OrdinalDefinitions[ordinal]; + odp->valid = 1; + odp->type = type; + strcpy(odp->export_name, export_name); + + vdp = malloc(sizeof(*vdp)); + odp->additional_data = vdp; + + vdp->n_values = n_values; + vdp->values = realloc(value_array, sizeof(*value_array) * n_values); + + return 0; +} + +int +ParseExportFunction(int ordinal, int type) +{ + char *token; + ORDDEF *odp; + ORDFUNCDEF *fdp; + int arg_types[16]; + int i; + int arg_num; + int current_offset; + int arg_size; + + + if (ordinal >= MAX_ORDINALS) + { + fprintf(stderr, "%d: Ordinal number too large\n", Line); + exit(1); + } + + odp = &OrdinalDefinitions[ordinal]; + strcpy(odp->export_name, GetToken()); + odp->valid = 1; + odp->type = type; + fdp = malloc(sizeof(*fdp)); + odp->additional_data = fdp; + + token = GetToken(); + if (*token != '(') + { + fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token); + exit(1); + } + + fdp->arg_16_size = 0; + for (i = 0; i < 16; i++) + { + token = GetToken(); + if (*token == ')') + break; + + if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0) + { + fdp->arg_types_16[i] = VARTYPE_WORD; + fdp->arg_16_size += 2; + fdp->arg_16_offsets[i] = 2; + } + else if (stricmp(token, "s_byte") == 0 || + stricmp(token, "s_word") == 0) + { + fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD; + fdp->arg_16_size += 2; + fdp->arg_16_offsets[i] = 2; + } + else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0) + { + fdp->arg_types_16[i] = VARTYPE_LONG; + fdp->arg_16_size += 4; + fdp->arg_16_offsets[i] = 4; + } + else if (stricmp(token, "ptr") == 0) + { + fdp->arg_types_16[i] = VARTYPE_FARPTR; + fdp->arg_16_size += 4; + fdp->arg_16_offsets[i] = 4; + } + else + { + fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token); + exit(1); + } + } + fdp->n_args_16 = i; + + if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG) + { + current_offset = 0; + for (i--; i >= 0; i--) + { + arg_size = fdp->arg_16_offsets[i]; + fdp->arg_16_offsets[i] = current_offset; + current_offset += arg_size; + } + } + else + { + current_offset = 0; + for (i = 0; i < fdp->n_args_16; i++) + { + arg_size = fdp->arg_16_offsets[i]; + fdp->arg_16_offsets[i] = current_offset; + current_offset += arg_size; + } + } + + strcpy(fdp->internal_name, GetToken()); + token = GetToken(); + if (*token != '(') + { + fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token); + exit(1); + } + for (i = 0; i < 16; i++) + { + token = GetToken(); + if (*token == ')') + break; + + fdp->arg_indices_32[i] = atoi(token); + if (fdp->arg_indices_32[i] < 1 || + fdp->arg_indices_32[i] > fdp->n_args_16) + { + fprintf(stderr, "%d: Bad argument index %d\n", Line, + fdp->arg_indices_32[i]); + exit(1); + } + } + fdp->n_args_32 = i; + + return 0; +} + +int +ParseEquate(int ordinal) +{ + ORDDEF *odp; + char *token; + char *endptr; + int value; + + if (ordinal >= MAX_ORDINALS) + { + fprintf(stderr, "%d: Ordinal number too large\n", Line); + exit(1); + } + + odp = &OrdinalDefinitions[ordinal]; + strcpy(odp->export_name, GetToken()); + + token = GetToken(); + value = strtol(token, &endptr, 0); + if (endptr == NULL || *endptr != '\0') + { + fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, + token); + exit(1); + } + + odp->valid = 1; + odp->type = EQUATETYPE_ABS; + odp->additional_data = (void *) value; + + return 0; +} + +int +ParseReturn(int ordinal) +{ + ORDDEF *odp; + ORDRETDEF *rdp; + char *token; + char *endptr; + int value; + + if (ordinal >= MAX_ORDINALS) + { + fprintf(stderr, "%d: Ordinal number too large\n", Line); + exit(1); + } + + rdp = malloc(sizeof(*rdp)); + + odp = &OrdinalDefinitions[ordinal]; + strcpy(odp->export_name, GetToken()); + odp->valid = 1; + odp->type = TYPE_RETURN; + odp->additional_data = rdp; + + token = GetToken(); + rdp->arg_size = strtol(token, &endptr, 0); + if (endptr == NULL || *endptr != '\0') + { + fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, + token); + exit(1); + } + + token = GetToken(); + rdp->ret_value = strtol(token, &endptr, 0); + if (endptr == NULL || *endptr != '\0') + { + fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, + token); + exit(1); + } + + return 0; +} + +int +ParseOrdinal(int ordinal) +{ + char *token; + + token = GetToken(); + if (token == NULL) + { + fprintf(stderr, "%d: Expected type after ordinal\n", Line); + exit(1); + } + + if (stricmp(token, "byte") == 0) + return ParseVariable(ordinal, VARTYPE_BYTE); + else if (stricmp(token, "word") == 0) + return ParseVariable(ordinal, VARTYPE_WORD); + else if (stricmp(token, "long") == 0) + return ParseVariable(ordinal, VARTYPE_LONG); + else if (stricmp(token, "c") == 0) + return ParseExportFunction(ordinal, FUNCTYPE_C); + else if (stricmp(token, "p") == 0) + return ParseExportFunction(ordinal, FUNCTYPE_PASCAL); + else if (stricmp(token, "pascal") == 0) + return ParseExportFunction(ordinal, FUNCTYPE_PASCAL); + else if (stricmp(token, "register") == 0) + return ParseExportFunction(ordinal, FUNCTYPE_REG); + else if (stricmp(token, "equate") == 0) + return ParseEquate(ordinal); + else if (stricmp(token, "return") == 0) + return ParseReturn(ordinal); + else + { + fprintf(stderr, + "%d: Expected type after ordinal, found '%s' instead\n", + Line, token); + exit(1); + } +} + +int +ParseTopLevel(void) +{ + char *token; + + while ((token = GetToken()) != NULL) + { + if (stricmp(token, "name") == 0) + { + strcpy(LowerDLLName, GetToken()); + strlower(LowerDLLName); + + strcpy(UpperDLLName, LowerDLLName); + strupper(UpperDLLName); + } + else if (stricmp(token, "id") == 0) + { + token = GetToken(); + if (!IsNumberString(token)) + { + fprintf(stderr, "%d: Expected number after id\n", Line); + exit(1); + } + + DLLId = atoi(token); + } + else if (stricmp(token, "length") == 0) + { + token = GetToken(); + if (!IsNumberString(token)) + { + fprintf(stderr, "%d: Expected number after length\n", Line); + exit(1); + } + + Limit = atoi(token); + } + else if (IsNumberString(token)) + { + int ordinal; + int rv; + + ordinal = atoi(token); + if ((rv = ParseOrdinal(ordinal)) < 0) + return rv; + } + else + { + fprintf(stderr, + "%d: Expected name, id, length or ordinal\n", Line); + exit(1); + } + } + + return 0; +} + +void +OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp) +{ + ORDVARDEF *vdp; + int i; + + fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); + + vdp = odp->additional_data; + for (i = 0; i < vdp->n_values; i++) + { + if ((i & 7) == 0) + fprintf(fp, "\t%s\t", storage); + + fprintf(fp, "%d", vdp->values[i]); + + if ((i & 7) == 7 || i == vdp->n_values - 1) + fprintf(fp, "\n"); + else + fprintf(fp, ", "); + } + fprintf(fp, "\n"); +} + +main(int argc, char **argv) +{ + ORDDEF *odp; + ORDFUNCDEF *fdp; + ORDRETDEF *rdp; + FILE *fp; + char filename[80]; + char buffer[80]; + char *p; + int i; + + if (argc < 2) + { + fprintf(stderr, "usage: build SPECNAME\n"); + exit(1); + } + + SpecFp = fopen(argv[1], "r"); + if (SpecFp == NULL) + { + fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]); + exit(1); + } + + ParseTopLevel(); + + /********************************************************************** + * DLL ENTRY POINTS + */ + sprintf(filename, "dll_%s.S", LowerDLLName); + fp = fopen(filename, "w"); + + fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName); + fprintf(fp, "_%s_Dispatch:\n", UpperDLLName); + fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); + fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); + fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16); + fprintf(fp, "\tjmp\t_CallTo32\n\n"); + + odp = OrdinalDefinitions; + for (i = 0; i <= Limit; i++, odp++) + { + fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i); + + if (!odp->valid) + { + fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); +#ifdef BOB_SAYS_NO + fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); + fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); +#endif + fprintf(fp, "\tmovl\t$%d,%%eax\n", i); + fprintf(fp, "\tpushw\t$0\n"); + fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName); + } + else + { + fdp = odp->additional_data; + rdp = odp->additional_data; + + switch (odp->type) + { + case EQUATETYPE_ABS: + fprintf(fp, "_%s_Ordinal_%d = %d\n\n", + UpperDLLName, i, (int) odp->additional_data); + break; + + case VARTYPE_BYTE: + OutputVariableCode(fp, ".byte", odp); + break; + + case VARTYPE_WORD: + OutputVariableCode(fp, ".word", odp); + break; + + case VARTYPE_LONG: + OutputVariableCode(fp, ".long", odp); + break; + + case TYPE_RETURN: + fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); + fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff); + fprintf(fp, "\tmovw\t$%d,%%dx\n", + (rdp->ret_value >> 16) & 0xffff); + fprintf(fp, "\t.byte\t0x66\n"); + if (rdp->arg_size != 0) + fprintf(fp, "\tlret\t$%d\n", rdp->arg_size); + else + fprintf(fp, "\tlret\n"); + break; + + case FUNCTYPE_REG: + fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); + fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); + fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); + fprintf(fp, "\tpushl\t$0\n"); /* cr2 */ + fprintf(fp, "\tpushl\t$0\n"); /* oldmask */ + fprintf(fp, "\tpushl\t$0\n"); /* i387 */ + fprintf(fp, "\tpushw\t$0\n"); /* __ssh */ + fprintf(fp, "\tpushw\t%%ss\n"); /* ss */ + fprintf(fp, "\tpushl\t%%esp\n"); /* esp */ + fprintf(fp, "\tpushfl\n"); /* eflags */ + fprintf(fp, "\tpushw\t$0\n"); /* __csh */ + fprintf(fp, "\tpushw\t%%cs\n"); /* cs */ + fprintf(fp, "\tpushl\t$0\n"); /* eip */ + fprintf(fp, "\tpushl\t$0\n"); /* err */ + fprintf(fp, "\tpushl\t$0\n"); /* trapno */ + fprintf(fp, "\tpushal\n"); /* AX, ... */ + fprintf(fp, "\tpushw\t$0\n"); /* __dsh */ + fprintf(fp, "\tpushw\t%%ds\n"); /* ds */ + fprintf(fp, "\tpushw\t$0\n"); /* __esh */ + fprintf(fp, "\tpushw\t%%es\n"); /* es */ + fprintf(fp, "\tpushw\t$0\n"); /* __fsh */ + fprintf(fp, "\tpushw\t%%fs\n"); /* fs */ + fprintf(fp, "\tpushw\t$0\n"); /* __gsh */ + fprintf(fp, "\tpushw\t%%gs\n"); /* gs */ + fprintf(fp, "\tmovl\t%%ebp,%%eax\n"); + fprintf(fp, "\tmovw\t%%esp,%%ebp\n"); + fprintf(fp, "\tpushl\t88(%%ebp)\n"); + fprintf(fp, "\tmovl\t%%eax,%%ebp\n"); + fprintf(fp, "\tmovl\t$%d,%%eax\n", i); + fprintf(fp, "\tpushw\t$92\n"); + fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i); + break; + + case FUNCTYPE_PASCAL: + fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); +#ifdef BOB_SAYS_NO + fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); + fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); +#endif + fprintf(fp, "\tmovl\t$%d,%%eax\n", i); + fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size); + fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i); + break; + + case FUNCTYPE_C: + default: + fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); +#ifdef BOB_SAYS_NO + fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); + fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); +#endif + fprintf(fp, "\tmovl\t$%d,%%eax\n", i); + fprintf(fp, "\tpushw\t$0\n"); + fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i); + break; + } + } + } + + fclose(fp); + + /********************************************************************** + * RELAY CODE + */ + sprintf(filename, "rly_%s.S", LowerDLLName); + fp = fopen(filename, "w"); + + odp = OrdinalDefinitions; + for (i = 0; i <= Limit; i++, odp++) + { + if (!odp->valid) + continue; + + fdp = odp->additional_data; + + fprintf(fp, "\t.globl _%s_Relay_%d\n", UpperDLLName, i); + fprintf(fp, "_%s_Relay_%d:\n", UpperDLLName, i); + fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); + fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); + + fprintf(fp, "\tpushl\t%%ebp\n"); + fprintf(fp, "\tmovl\t%%esp,%%ebp\n"); + + /* + * Save registers. 286 mode does not have fs or gs. + */ + fprintf(fp, "\tpushw\t%%ds\n"); + fprintf(fp, "\tpushw\t%%es\n"); + + /* + * Restore segment registers. + */ + fprintf(fp, "\tmovw\t%d,%%ax\n", UDATASEL); + fprintf(fp, "\tmovw\t%%ax,%%ds\n"); + fprintf(fp, "\tmovw\t%%ax,%%es\n"); + + /* + * Save old stack save variables, save stack registers, reload + * stack registers. + */ + fprintf(fp, "\tpushl\t_IF1632_Saved16_esp\n"); + fprintf(fp, "\tpushl\t_IF1632_Saved16_ebp\n"); + fprintf(fp, "\tpushw\t_IF1632_Saved16_ss\n"); + + fprintf(fp, "\tmovw\t%%ss,_IF1632_Saved16_ss\n"); + fprintf(fp, "\tmovl\t%%esp,_IF1632_Saved16_esp\n"); + fprintf(fp, "\tmovl\t%%ebp,_IF1632_Saved16_ebp\n"); + + fprintf(fp, "\tmovw\t%%ss,%%ax\n"); + fprintf(fp, "\tshll\t16,%%eax\n"); + fprintf(fp, "\torl\t%%esp,%%eax\n"); + + fprintf(fp, "\tmovw\t_IF1632_Saved32_ss,%%ss\n"); + fprintf(fp, "\tmovl\t_IF1632_Saved32_esp,%%esp\n"); + fprintf(fp, "\tmovl\t_IF1632_Saved32_ebp,%%ebp\n"); + + fprintf(fp, "\tpushl\t_Stack16Frame\n"); + fprintf(fp, "\tmovl\t%%eax,_Stack16Frame\n"); + + /* + * Move arguments. + */ + + + /* + * Call entry point + */ + fprintf(fp, "\tcall\t%s\n", fdp->internal_name); + + /* + * Restore registers, but do not destroy return value. + */ + fprintf(fp, "\tmovw\t_IF1632_Saved16_ss,%%ss\n"); + fprintf(fp, "\tmovl\t_IF1632_Saved16_esp,%%esp\n"); + fprintf(fp, "\tmovl\t_IF1632_Saved16_ebp,%%ebp\n"); + + fprintf(fp, "\tpopw\t_IF1632_Saved16_ss\n"); + fprintf(fp, "\tpopl\t_IF1632_Saved16_ebp\n"); + fprintf(fp, "\tpopl\t_IF1632_Saved16_esp\n"); + + fprintf(fp, "\tpopw\t%%es\n"); + fprintf(fp, "\tpopw\t%%ds\n"); + + fprintf(fp, "\t.align\t2,0x90\n"); + fprintf(fp, "\tleave\n"); + + /* + * Now we need to ditch the parameter bytes that were left on the + * stack. We do this by effectively popping the number of bytes, + * and the return address, removing the parameters and then putting + * the return address back on the stack. + * Normally this field is filled in by the relevant function in + * the emulation library, since it should know how many bytes to + * expect. + */ + fprintf(fp, "\tpopw\t%%gs:nbytes\n"); + fprintf(fp, "\tcmpw\t$0,%%gs:nbytes\n"); + fprintf(fp, "\tje\tnoargs\n"); + fprintf(fp, "\tpopw\t%%gs:offset\n"); + fprintf(fp, "\tpopw\t%%gs:selector\n"); + fprintf(fp, "\taddw\t%%gs:nbytes,%%esp\n"); + fprintf(fp, "\tpushw\t%%gs:selector\n"); + fprintf(fp, "\tpushw\t%%gs:offset\n"); + fprintf(fp, "noargs:\n"); + + /* + * Last, but not least we need to move the high word from eax to dx + */ + fprintf(fp, "\t pushl\t%%eax\n"); + fprintf(fp, "\tpopw\t%%dx\n"); + fprintf(fp, "\tpopw\t%%dx\n"); + + fprintf(fp, "\t.byte\t0x66\n"); + fprintf(fp, "\tlret\n"); + + } + + fclose(fp); + + /********************************************************************** + * DLL ENTRY TABLE + */ +#ifndef SHORTNAMES + sprintf(filename, "dll_%s_tab.c", LowerDLLName); +#else + sprintf(filename, "dtb_%s.c", LowerDLLName); +#endif + fp = fopen(filename, "w"); + + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \042dlls.h\042\n\n"); + + for (i = 0; i <= Limit; i++) + { + fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i); + } + + odp = OrdinalDefinitions; + for (i = 0; i <= Limit; i++, odp++) + { + if (odp->valid && + (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C || + odp->type == FUNCTYPE_REG)) + { + fdp = odp->additional_data; + fprintf(fp, "extern int %s();\n", fdp->internal_name); + } + } + + fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n", + UpperDLLName, Limit + 1); + fprintf(fp, "{\n"); + odp = OrdinalDefinitions; + for (i = 0; i <= Limit; i++, odp++) + { + fdp = odp->additional_data; + + if (!odp->valid) + odp->type = -1; + + switch (odp->type) + { + case FUNCTYPE_PASCAL: + case FUNCTYPE_REG: + fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); + fprintf(fp, "\042%s\042, ", odp->export_name); + fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name); +#ifdef WINESTAT + fprintf(fp, "0, "); +#endif + fprintf(fp, "%d, ", fdp->n_args_32); + if (fdp->n_args_32 > 0) + { + int argnum; + + fprintf(fp, "\n {\n"); + for (argnum = 0; argnum < fdp->n_args_32; argnum++) + { + fprintf(fp, " { %d, %d },\n", + fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1], + fdp->arg_types_16[argnum]); + } + fprintf(fp, " }\n "); + } + fprintf(fp, "}, \n"); + break; + + case FUNCTYPE_C: + fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); + fprintf(fp, "\042%s\042, ", odp->export_name); + fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name); +#ifdef WINESTAT + fprintf(fp, "0, "); +#endif + fprintf(fp, "%d, ", fdp->n_args_32); + if (fdp->n_args_32 > 0) + { + int argnum; + + fprintf(fp, "\n {\n"); + for (argnum = 0; argnum < fdp->n_args_32; argnum++) + { + fprintf(fp, " { %d, %d },\n", + fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1], + fdp->arg_types_16[argnum]); + } + fprintf(fp, " }\n "); + } + fprintf(fp, "}, \n"); + break; + + default: + fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", + UTEXTSEL, UpperDLLName, i); + break; + } + } + fprintf(fp, "};\n"); + + fclose(fp); +} + diff --git a/windows/Imakefile b/windows/Imakefile index 947968a3deb..9689eff7bbc 100644 --- a/windows/Imakefile +++ b/windows/Imakefile @@ -15,6 +15,7 @@ SRCS = \ graphics.c \ keyboard.c \ mapping.c \ + mdi.c \ message.c \ nonclient.c \ painting.c \ diff --git a/windows/class.c b/windows/class.c index fbec0a16819..68277c661ce 100644 --- a/windows/class.c +++ b/windows/class.c @@ -6,11 +6,16 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include +#include +#include #include "class.h" #include "user.h" #include "win.h" #include "dce.h" +/* #define DEBUG_CLASS /* */ + static HCLASS firstClass = 0; @@ -88,8 +93,9 @@ ATOM RegisterClass( LPWNDCLASS class ) HCLASS handle, prevClass; #ifdef DEBUG_CLASS - printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n", - class->lpfnWndProc, class->hInstance, class->lpszClassName ); + printf( "RegisterClass: wndproc=%08x hinst=%d name='%s' background %x\n", + class->lpfnWndProc, class->hInstance, class->lpszClassName, + class->hbrBackground ); #endif /* Check if a class with this name already exists */ @@ -117,14 +123,25 @@ ATOM RegisterClass( LPWNDCLASS class ) if (newClass->wc.style & CS_GLOBALCLASS) newClass->atomName = GlobalAddAtom( class->lpszClassName ); else newClass->atomName = AddAtom( class->lpszClassName ); + newClass->wc.lpszClassName = NULL; if (newClass->wc.style & CS_CLASSDC) newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC ); else newClass->hdce = 0; - /* Menu name should also be set to zero. */ - newClass->wc.lpszClassName = NULL; - + /* Make a copy of the menu name (only if it is a string) */ + + if ((int)class->lpszMenuName & 0xffff0000) + { + HANDLE hname; + hname = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(class->lpszMenuName)+1); + if (hname) + { + newClass->wc.lpszMenuName = (char *)USER_HEAP_ADDR( hname ); + strcpy( newClass->wc.lpszMenuName, class->lpszMenuName ); + } + } + if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra ); firstClass = handle; return newClass->atomName; @@ -136,7 +153,7 @@ ATOM RegisterClass( LPWNDCLASS class ) */ BOOL UnregisterClass( LPSTR className, HANDLE instance ) { - HANDLE class, next, prevClass; + HANDLE class, prevClass; CLASS * classPtr, * prevClassPtr; /* Check if we can remove this class */ @@ -167,6 +184,8 @@ BOOL UnregisterClass( LPSTR className, HANDLE instance ) if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground ); if (classPtr->wc.style & CS_GLOBALCLASS) GlobalDeleteAtom( classPtr->atomName ); else DeleteAtom( classPtr->atomName ); + if ((int)classPtr->wc.lpszMenuName & 0xffff0000) + USER_HEAP_FREE( (int)classPtr->wc.lpszMenuName & 0xffff ); USER_HEAP_FREE( class ); return TRUE; } diff --git a/windows/dc.c b/windows/dc.c index 4224b3ad335..58dd531dbb5 100644 --- a/windows/dc.c +++ b/windows/dc.c @@ -7,16 +7,17 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include - +#include #include "gdi.h" - -extern HBITMAP BITMAP_hbitmapMemDC; +#include "bitmap.h" static DeviceCaps * displayDevCaps = NULL; extern const WIN_DC_INFO DCVAL_defaultValues; -extern void CLIPPING_SetDeviceClipping( DC * dc ); /* in objects/clipping.c */ +extern void CLIPPING_SetDeviceClipping( DC * dc ); /* objects/clipping.c */ +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color );/* objects/color.c */ +extern void COLOR_SetMapping( DC *dc, HANDLE, WORD ); /* objects/color.c */ /* ROP code to GC function conversion */ @@ -50,11 +51,11 @@ void DC_FillDevCaps( DeviceCaps * caps ) { caps->version = 0x300; caps->technology = DT_RASDISPLAY; - caps->horzSize = WidthMMOfScreen( XT_screen ); - caps->vertSize = HeightMMOfScreen( XT_screen ); - caps->horzRes = WidthOfScreen( XT_screen ); - caps->vertRes = HeightOfScreen( XT_screen ); - caps->bitsPixel = DefaultDepthOfScreen( XT_screen ); + caps->horzSize = WidthMMOfScreen(screen) * screenWidth / WidthOfScreen(screen); + caps->vertSize = HeightMMOfScreen(screen) * screenHeight / HeightOfScreen(screen); + caps->horzRes = screenWidth; + caps->vertRes = screenHeight; + caps->bitsPixel = screenDepth; caps->planes = 1; caps->numBrushes = 0; caps->numPens = 0; @@ -81,26 +82,26 @@ void DC_FillDevCaps( DeviceCaps * caps ) caps->aspectXY = 51; caps->logPixelsX = (int)(caps->horzRes * 25.4 / caps->horzSize); caps->logPixelsY = (int)(caps->vertRes * 25.4 / caps->vertSize); - caps->sizePalette = DefaultVisual( XT_display, DefaultScreen(XT_display) )->map_entries; + caps->sizePalette = DefaultVisual(display,DefaultScreen(display))->map_entries; caps->numReserved = 0; caps->colorRes = 0; } /*********************************************************************** - * DC_SetDeviceInfo + * DC_InitDC * - * Set device-specific info from device-independent info. + * Setup device-specific DC values for a newly created DC. */ -void DC_SetDeviceInfo( HDC hdc, DC * dc ) +static void DC_InitDC( HDC hdc ) { + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + RealizeDefaultPalette( hdc ); SetTextColor( hdc, dc->w.textColor ); SetBkColor( hdc, dc->w.backgroundColor ); - SetROP2( hdc, dc->w.ROPmode ); SelectObject( hdc, dc->w.hPen ); SelectObject( hdc, dc->w.hBrush ); SelectObject( hdc, dc->w.hFont ); - XSetGraphicsExposures( XT_display, dc->u.x.gc, False ); CLIPPING_SetDeviceClipping( dc ); } @@ -114,6 +115,9 @@ void DC_SetDeviceInfo( HDC hdc, DC * dc ) */ int DC_SetupGCForBrush( DC * dc ) { + XGCValues val; + unsigned long mask = 0; + if (dc->u.x.brush.style == BS_NULL) return 0; if (dc->u.x.brush.pixel == -1) { @@ -121,26 +125,34 @@ int DC_SetupGCForBrush( DC * dc ) * We need to swap foreground and background because * Windows does it the wrong way... */ - XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel ); - XSetBackground( XT_display, dc->u.x.gc, dc->w.textPixel ); + val.foreground = dc->w.backgroundPixel; + val.background = dc->w.textPixel; } else { - XSetForeground( XT_display, dc->u.x.gc, dc->u.x.brush.pixel ); - XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel ); + val.foreground = dc->u.x.brush.pixel; + val.background = dc->w.backgroundPixel; } - - if (dc->u.x.brush.fillStyle != FillStippled) - XSetFillStyle( XT_display, dc->u.x.gc, dc->u.x.brush.fillStyle ); - else - XSetFillStyle( XT_display, dc->u.x.gc, - (dc->w.backgroundMode == OPAQUE) ? - FillOpaqueStippled : FillStippled ); - XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX + dc->w.brushOrgX, - dc->w.DCOrgY + dc->w.brushOrgY ); - XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] ); - XSetFillRule( XT_display, dc->u.x.gc, - (dc->w.polyFillMode == WINDING) ? WindingRule : EvenOddRule ); + val.function = DC_XROPfunction[dc->w.ROPmode-1]; + val.fill_style = dc->u.x.brush.fillStyle; + if (val.fill_style == FillStippled) + { + if (dc->w.backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled; + val.stipple = dc->u.x.brush.pixmap; + mask = GCStipple; + } + else if (val.fill_style == FillTiled) + { + 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; + val.fill_rule = (dc->w.polyFillMode==WINDING) ? WindingRule : EvenOddRule; + XChangeGC( display, dc->u.x.gc, + GCFunction | GCForeground | GCBackground | GCFillStyle | + GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask, + &val ); return 1; } @@ -153,23 +165,27 @@ int DC_SetupGCForBrush( DC * dc ) */ int DC_SetupGCForPen( DC * dc ) { + XGCValues val; + if (dc->u.x.pen.style == PS_NULL) return 0; - XSetForeground( XT_display, dc->u.x.gc, dc->u.x.pen.pixel ); - XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel ); - XSetFillStyle( XT_display, dc->u.x.gc, FillSolid ); - if ((dc->u.x.pen.style == PS_SOLID) || - (dc->u.x.pen.style == PS_INSIDEFRAME)) + val.function = DC_XROPfunction[dc->w.ROPmode-1]; + val.foreground = dc->u.x.pen.pixel; + val.background = dc->w.backgroundPixel; + val.fill_style = FillSolid; + if ((dc->u.x.pen.style!=PS_SOLID) && (dc->u.x.pen.style!=PS_INSIDEFRAME)) { - XSetLineAttributes( XT_display, dc->u.x.gc, dc->u.x.pen.width, - LineSolid, CapRound, JoinBevel ); + XSetDashes( display, dc->u.x.gc, 0, + dc->u.x.pen.dashes, dc->u.x.pen.dash_len ); + val.line_style = (dc->w.backgroundMode == OPAQUE) ? + LineDoubleDash : LineOnOffDash; } - else - { - XSetLineAttributes( XT_display, dc->u.x.gc, dc->u.x.pen.width, - (dc->w.backgroundMode == OPAQUE) ? LineDoubleDash : LineOnOffDash, - CapRound, JoinBevel ); - } - XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] ); + else val.line_style = LineSolid; + val.line_width = dc->u.x.pen.width; + val.cap_style = CapRound; + val.join_style = JoinBevel; + XChangeGC( display, dc->u.x.gc, + GCFunction | GCForeground | GCBackground | GCLineWidth | + GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val ); return 1; } @@ -182,12 +198,20 @@ int DC_SetupGCForPen( DC * dc ) */ int DC_SetupGCForText( DC * dc ) { - XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel ); - XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel ); - XSetFillStyle( XT_display, dc->u.x.gc, FillSolid ); - XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] ); - if (!dc->u.x.font.fstruct) return 0; - XSetFont( XT_display, dc->u.x.gc, dc->u.x.font.fstruct->fid ); + XGCValues val; + + if (!dc->u.x.font.fstruct) + { + FONT_SelectObject(dc, STOCK_SYSTEM_FIXED_FONT, NULL); + } + val.function = DC_XROPfunction[dc->w.ROPmode-1]; + val.foreground = dc->w.textPixel; + val.background = dc->w.backgroundPixel; + val.fill_style = FillSolid; + val.font = dc->u.x.font.fstruct->fid; + XChangeGC( display, dc->u.x.gc, + GCFunction | GCForeground | GCBackground | GCFillStyle | + GCFont, &val ); return 1; } @@ -223,6 +247,7 @@ HDC GetDCState( HDC hdc ) CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY ); } newdc->w.hGCClipRgn = 0; + COLOR_SetMapping( newdc, dc->u.x.pal.hMapping, dc->u.x.pal.mappingSize ); return handle; } @@ -243,10 +268,16 @@ void SetDCState( HDC hdc, HDC hdcs ) if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn ); if (dc->w.hVisRgn) DeleteObject( dc->w.hVisRgn ); if (dc->w.hGCClipRgn) DeleteObject( dc->w.hGCClipRgn ); + memcpy( &dc->w, &dcs->w, sizeof(dc->w) ); + memcpy( &dc->u.x.pen, &dcs->u.x.pen, sizeof(dc->u.x.pen) ); dc->w.hClipRgn = dc->w.hVisRgn = dc->w.hGCClipRgn = 0; dc->w.flags &= ~DC_SAVED; - DC_SetDeviceInfo( hdc, dc ); + + SelectObject( hdc, dcs->w.hBrush ); + SelectObject( hdc, dcs->w.hFont ); + COLOR_SetMapping( dc, dcs->u.x.pal.hMapping, dcs->u.x.pal.mappingSize ); + SelectClipRgn( hdc, dcs->w.hClipRgn ); SelectVisRgn( hdc, dcs->w.hVisRgn ); } @@ -284,14 +315,14 @@ BOOL RestoreDC( HDC hdc, short level ) #endif if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE; if (level == -1) level = dc->saveLevel; - if ((level < 1) || (level > dc->saveLevel)) return FALSE; + if ((level < 1) || (level > (short)dc->saveLevel)) return FALSE; - while (dc->saveLevel >= level) + while ((short)dc->saveLevel >= level) { HDC hdcs = dc->header.hNext; if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return FALSE; dc->header.hNext = dcs->header.hNext; - if (--dc->saveLevel < level) SetDCState( hdc, hdcs ); + if ((short)--dc->saveLevel < level) SetDCState( hdc, hdcs ); DeleteDC( hdcs ); } return TRUE; @@ -324,21 +355,30 @@ HDC CreateDC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData ) memcpy( &dc->w, &DCVAL_defaultValues, sizeof(DCVAL_defaultValues) ); memset( &dc->u.x, 0, sizeof(dc->u.x) ); - dc->u.x.drawable = DefaultRootWindow( XT_display ); - dc->u.x.gc = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL ); + dc->u.x.drawable = rootWindow; + dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL ); dc->w.flags = 0; dc->w.devCaps = displayDevCaps; - dc->w.planes = displayDevCaps->planes; dc->w.bitsPerPixel = displayDevCaps->bitsPixel; dc->w.DCSizeX = displayDevCaps->horzRes; dc->w.DCSizeY = displayDevCaps->vertRes; - DC_SetDeviceInfo( handle, dc ); + DC_InitDC( handle ); return handle; } +/*********************************************************************** + * CreateIC (GDI.153) + */ +HDC CreateIC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData ) +{ + /* Nothing special yet for ICs */ + return CreateDC( driver, device, output, initData ); +} + + /*********************************************************************** * CreateCompatibleDC (GDI.52) */ @@ -359,20 +399,17 @@ HDC CreateCompatibleDC( HDC hdc ) memcpy( &dc->w, &DCVAL_defaultValues, sizeof(DCVAL_defaultValues) ); memset( &dc->u.x, 0, sizeof(dc->u.x) ); - dc->u.x.drawable = XCreatePixmap( XT_display, - DefaultRootWindow( XT_display ), - 1, 1, 1 ); - dc->u.x.gc = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL ); + dc->u.x.drawable = XCreatePixmap( display, rootWindow, 1, 1, 1 ); + dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL ); dc->w.flags = DC_MEMORY; - dc->w.planes = 1; dc->w.bitsPerPixel = 1; dc->w.devCaps = displayDevCaps; dc->w.DCSizeX = 1; dc->w.DCSizeY = 1; SelectObject( handle, BITMAP_hbitmapMemDC ); - DC_SetDeviceInfo( handle, dc ); - + DC_InitDC( handle ); + return handle; } @@ -404,9 +441,7 @@ BOOL DeleteDC( HDC hdc ) SelectObject( hdc, STOCK_BLACK_PEN ); SelectObject( hdc, STOCK_WHITE_BRUSH ); SelectObject( hdc, STOCK_SYSTEM_FONT ); - - XFreeGC( XT_display, dc->u.x.gc ); - if (dc->w.flags & DC_MEMORY) BITMAP_UnselectBitmap( dc ); + XFreeGC( display, dc->u.x.gc ); } if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn ); @@ -446,8 +481,7 @@ COLORREF SetBkColor( HDC hdc, COLORREF color ) oldColor = dc->w.backgroundColor; dc->w.backgroundColor = color; - dc->w.backgroundPixel = GetNearestPaletteIndex( dc->w.hPalette, color ); - XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel ); + dc->w.backgroundPixel = COLOR_ToPhysical( dc, color ); return oldColor; } @@ -463,8 +497,7 @@ COLORREF SetTextColor( HDC hdc, COLORREF color ) oldColor = dc->w.textColor; dc->w.textColor = color; - dc->w.textPixel = GetNearestPaletteIndex( dc->w.hPalette, color ); - XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel ); + dc->w.textPixel = COLOR_ToPhysical( dc, color ); return oldColor; } diff --git a/windows/dce.c b/windows/dce.c index 6df7ccd121f..3dfe56ef66c 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -193,7 +193,7 @@ HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) IntersectVisRect( hdc, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom ); } - else dc->u.x.drawable = DefaultRootWindow( display ); + else dc->u.x.drawable = rootWindow; if (flags & DCX_CLIPCHILDREN) XSetSubwindowMode( display, dc->u.x.gc, ClipByChildren ); diff --git a/windows/defwnd.c b/windows/defwnd.c index a495d08b088..5163a2015bb 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -6,7 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; - +#include +#include #include "windows.h" #include "win.h" #include "class.h" @@ -21,6 +22,7 @@ extern LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam ); extern LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ); extern LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam ); extern void NC_TrackSysMenu( HWND hwnd ); /* menu.c */ +extern BOOL ActivateMenuFocus(HWND hWnd); /* menu.c */ @@ -48,10 +50,11 @@ void DEFWND_SetText( HWND hwnd, LPSTR text ) */ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { - CLASS * classPtr; - LPSTR textPtr; - int len; - WND * wndPtr = WIN_FindWndPtr( hwnd ); + MEASUREITEMSTRUCT *measure; + CLASS * classPtr; + LPSTR textPtr; + int len; + WND * wndPtr = WIN_FindWndPtr( hwnd ); #ifdef DEBUG_MESSAGE printf( "DefWindowProc: %d %d %d %08x\n", hwnd, msg, wParam, lParam ); @@ -208,15 +211,31 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) return NC_HandleSysCommand( hwnd, wParam, MAKEPOINT(lParam) ); case WM_SYSKEYDOWN: - if (wParam == VK_MENU) { - printf("VK_MENU Pressed // hMenu=%04X !\n", GetMenu(hwnd)); - NC_TrackSysMenu(hwnd); - } - break; + if (wParam == VK_MENU) ActivateMenuFocus(hwnd); + break; case WM_SYSKEYUP: - if (wParam == VK_MENU) { - printf("VK_MENU Released // hMenu=%04X !\n", GetMenu(hwnd)); - } + break; + case WM_MENUCHAR: + MessageBeep(0); + break; + case WM_MEASUREITEM: + measure = (MEASUREITEMSTRUCT *)lParam; + switch(measure->CtlType) { + case ODT_BUTTON: + break; + case ODT_COMBOBOX: + measure->itemHeight = 10; +/* printf("defwndproc WM_MEASUREITEM // ODT_COMBOBOX !\n");*/ + break; + case ODT_LISTBOX: + measure->itemHeight = 10; +/* printf("defwndproc WM_MEASUREITEM // ODT_LISTBOX !\n");*/ + break; + case ODT_MENU: + break; + default: + break; + } break; } return 0; diff --git a/windows/dialog.c b/windows/dialog.c index 9f0b64af166..35dc9f0db8b 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -6,6 +6,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include +#include +#include #include "windows.h" #include "dialog.h" #include "win.h" diff --git a/windows/event.c b/windows/event.c index 87c0229a240..887d0253315 100644 --- a/windows/event.c +++ b/windows/event.c @@ -6,6 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include +#include #include #include #include @@ -21,7 +23,7 @@ typedef char *XPointer; #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ -extern Display * display; +extern int desktopX, desktopY; /* misc/main.c */ extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/ @@ -29,10 +31,10 @@ extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/ static XContext winContext = 0; /* State variables */ +BOOL MouseButtonsStates[NB_BUTTONS] = { FALSE, FALSE, FALSE }; static WORD ALTKeyState; static HWND captureWnd = 0; Window winHasCursor = 0; -extern HWND hWndFocus; /* Keyboard translation tables */ static int special_key[] = @@ -117,13 +119,13 @@ static char *event_names[] = /* Event handlers */ static void EVENT_key( HWND hwnd, XKeyEvent *event ); -static void EVENT_ButtonPress( HWND hwnd, XButtonEvent *event ); -static void EVENT_ButtonRelease( HWND hwnd, XButtonEvent *event ); -static void EVENT_MotionNotify( HWND hwnd, XMotionEvent *event ); -static void EVENT_EnterNotify( HWND hwnd, XCrossingEvent *event ); -static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ); +static void EVENT_ButtonPress( XButtonEvent *event ); +static void EVENT_ButtonRelease( XButtonEvent *event ); +static void EVENT_MotionNotify( XMotionEvent *event ); +static void EVENT_EnterNotify( XCrossingEvent *event ); static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ); static void EVENT_Expose( HWND hwnd, XExposeEvent *event ); +static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event ); /*********************************************************************** @@ -151,23 +153,19 @@ void EVENT_ProcessEvent( XEvent *event ) break; case ButtonPress: - EVENT_ButtonPress( hwnd, (XButtonEvent*)event ); + EVENT_ButtonPress( (XButtonEvent*)event ); break; case ButtonRelease: - EVENT_ButtonRelease( hwnd, (XButtonEvent*)event ); + EVENT_ButtonRelease( (XButtonEvent*)event ); break; case MotionNotify: - EVENT_MotionNotify( hwnd, (XMotionEvent*)event ); + EVENT_MotionNotify( (XMotionEvent*)event ); break; case EnterNotify: - EVENT_EnterNotify( hwnd, (XCrossingEvent*)event ); - break; - - case FocusIn: - EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event ); + EVENT_EnterNotify( (XCrossingEvent*)event ); break; case FocusOut: @@ -178,6 +176,10 @@ void EVENT_ProcessEvent( XEvent *event ) EVENT_Expose( hwnd, (XExposeEvent*)event ); break; + case ConfigureNotify: + EVENT_ConfigureNotify( hwnd, (XConfigureEvent*)event ); + break; + #ifdef DEBUG_EVENT default: printf( "Unprocessed event %s for hwnd %d\n", @@ -225,8 +227,10 @@ static WORD EVENT_XStateToKeyState( int state ) static void EVENT_Expose( HWND hwnd, XExposeEvent *event ) { RECT rect; + UINT flags; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return; + /* Make position relative to client area instead of window */ rect.left = event->x - (wndPtr->rectClient.left - wndPtr->rectWindow.left); rect.top = event->y - (wndPtr->rectClient.top - wndPtr->rectWindow.top); @@ -234,8 +238,10 @@ static void EVENT_Expose( HWND hwnd, XExposeEvent *event ) rect.bottom = rect.top + event->height; winHasCursor = event->window; - RedrawWindow( hwnd, &rect, 0, - RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_NOCHILDREN ); + flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME; + /* Erase desktop background synchronously */ + if (event->window == rootWindow) flags |= RDW_ERASENOW | RDW_NOCHILDREN; + RedrawWindow( hwnd, &rect, 0, flags ); } @@ -252,7 +258,7 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) WORD xkey, vkey, key_type, key; KEYLP keylp; BOOL extended = FALSE; - WND * wndPtr = WIN_FindWndPtr( hwnd ); + int count = XLookupString(event, Str, 1, &keysym, &cs); Str[count] = '\0'; #ifdef DEBUG_KEY @@ -260,12 +266,6 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) keysym, count, Str[0], Str); #endif - if (wndPtr->dwStyle & WS_DISABLED) { - if (event->type == KeyPress) XBell(display, 0); - return; - } - - xkey = LOWORD(keysym); key_type = HIBYTE(xkey); key = LOBYTE(xkey); @@ -273,10 +273,6 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) printf(" key_type=%X, key=%X\n", key_type, key); #endif - /* Position must be relative to client area */ - event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; - event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; - if (key_type == 0xFF) /* non-character key */ { if (key >= 0x08 && key <= 0x1B) /* special key */ @@ -320,9 +316,9 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) #ifdef DEBUG_KEY printf(" wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); #endif - hardware_event( hwnd, ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN, + hardware_event( ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN, vkey, keylp.lp2, - event->x_root & 0xffff, event->y_root & 0xffff, + event->x_root - desktopX, event->y_root - desktopY, event->time, 0 ); KeyDown = TRUE; @@ -351,11 +347,10 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) #ifdef DEBUG_KEY printf(" wParam=%X, lParam=%lX\n", vkey, keylp.lp2 ); #endif - hardware_event( hwnd, - ((ALTKeyState || vkey == VK_MENU) ? + hardware_event( ((ALTKeyState || vkey == VK_MENU) ? WM_SYSKEYUP : WM_KEYUP), vkey, keylp.lp2, - event->x_root & 0xffff, event->y_root & 0xffff, + event->x_root - desktopX, event->y_root - desktopY, event->time, 0 ); KeyDown = FALSE; } @@ -365,138 +360,84 @@ static void EVENT_key( HWND hwnd, XKeyEvent *event ) /*********************************************************************** * EVENT_MotionNotify */ -static void EVENT_MotionNotify( HWND hwnd, XMotionEvent *event ) +static void EVENT_MotionNotify( XMotionEvent *event ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - if (!wndPtr) return; - if (wndPtr->dwStyle & WS_DISABLED) { - return; - } - - - hardware_event( hwnd, WM_MOUSEMOVE, - EVENT_XStateToKeyState( event->state ), 0L, - event->x_root & 0xffff, event->y_root & 0xffff, - event->time, 0 ); + hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), 0L, + event->x_root - desktopX, event->y_root - desktopY, + event->time, 0 ); } /*********************************************************************** * EVENT_ButtonPress */ -static void EVENT_ButtonPress( HWND hwnd, XButtonEvent *event ) +static void EVENT_ButtonPress( XButtonEvent *event ) { static WORD messages[NB_BUTTONS] = { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN }; int buttonNum = event->button - 1; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) { - printf("couldn't find window\n"); - return; - } - if (wndPtr->dwStyle & WS_DISABLED) { - XBell(display, 0); - return; - } - - - - if (buttonNum >= NB_BUTTONS) return; + if (buttonNum >= NB_BUTTONS) return; + MouseButtonsStates[buttonNum] = TRUE; winHasCursor = event->window; - hardware_event( hwnd, messages[buttonNum], + hardware_event( messages[buttonNum], EVENT_XStateToKeyState( event->state ), 0L, - event->x_root & 0xffff, event->y_root & 0xffff, - event->time, 0 ); + event->x_root - desktopX, event->y_root - desktopY, + event->time, 0 ); } /*********************************************************************** * EVENT_ButtonRelease */ -static void EVENT_ButtonRelease( HWND hwnd, XButtonEvent *event ) +static void EVENT_ButtonRelease( XButtonEvent *event ) { static const WORD messages[NB_BUTTONS] = { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP }; int buttonNum = event->button - 1; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - if (!wndPtr) return; - if (wndPtr->dwStyle & WS_DISABLED) { - return; - } - if (buttonNum >= NB_BUTTONS) return; + MouseButtonsStates[buttonNum] = FALSE; winHasCursor = event->window; - hardware_event( hwnd, messages[buttonNum], + hardware_event( messages[buttonNum], EVENT_XStateToKeyState( event->state ), 0L, - event->x_root & 0xffff, event->y_root & 0xffff, - event->time, 0 ); -} - - -/********************************************************************** - * EVENT_FocusIn - */ -static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ) -{ - - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - if (!wndPtr) return; - if (wndPtr->dwStyle & WS_DISABLED) { - return; - } - - - PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 ); - hWndFocus = hwnd; + event->x_root - desktopX, event->y_root - desktopY, + event->time, 0 ); } /********************************************************************** * EVENT_FocusOut + * + * Note: only top-level override-redirect windows get FocusOut events. */ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; - + if (event->detail == NotifyPointer) return; if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE ); - - if (wndPtr->dwStyle & WS_DISABLED) { - return; - } - - if (hWndFocus) - { - PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 ); - hWndFocus = 0; - } + if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus())) SetFocus( 0 ); } /********************************************************************** * EVENT_EnterNotify */ -static void EVENT_EnterNotify( HWND hwnd, XCrossingEvent *event ) +static void EVENT_EnterNotify( XCrossingEvent *event ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - if (!wndPtr) return; - if (wndPtr->dwStyle & WS_DISABLED) { - return; - } - if (captureWnd != 0) return; winHasCursor = event->window; - /* Simulate a mouse motion to set the correct cursor */ - hardware_event( hwnd, WM_MOUSEMOVE, - EVENT_XStateToKeyState( event->state ), 0L, - event->x_root & 0xffff, event->y_root & 0xffff, - event->time, 0 ); +} + + +/********************************************************************** + * EVENT_ConfigureNotify + * + * The ConfigureNotify event is only selected on the desktop window. + */ +static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event ) +{ + desktopX = event->x; + desktopY = event->y; } @@ -529,15 +470,7 @@ HWND SetCapture(HWND wnd) */ void ReleaseCapture() { - WND *wnd_p; - - if (captureWnd == 0) - return; - - wnd_p = WIN_FindWndPtr(captureWnd); - if (wnd_p == NULL) - return; - + if (captureWnd == 0) return; XUngrabPointer( display, CurrentTime ); captureWnd = 0; } diff --git a/windows/focus.c b/windows/focus.c index a3ac280e1c7..8850af0b607 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -2,13 +2,56 @@ * Focus functions * * Copyright 1993 David Metcalfe + * Copyright 1994 Alexandre Julliard */ static char Copyright[] = "Copyright David Metcalfe, 1993"; +static char Copyright2[] = "Copyright Alexandre Julliard, 1994"; #include "win.h" -HWND hWndFocus = 0; +extern Colormap COLOR_WinColormap; + +static HWND hWndFocus = 0; + + +/***************************************************************** + * FOCUS_SetXFocus + * + * Set the X focus. + */ +static void FOCUS_SetXFocus( HWND hwnd ) +{ + WND *wndPtr; + XWindowAttributes win_attr; + + /* Only mess with the X focus if there's no desktop window */ + if (rootWindow != DefaultRootWindow(display)) return; + + if (!hwnd) /* If setting the focus to 0, uninstall the colormap */ + { + if (COLOR_WinColormap != DefaultColormapOfScreen(screen)) + XUninstallColormap( display, COLOR_WinColormap ); + return; + } + + /* Set X focus on the top-level ancestor. */ + + /* Find ancestor */ + wndPtr = WIN_FindWndPtr( hWndFocus ); + while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) + wndPtr = WIN_FindWndPtr( wndPtr->hwndParent ); + if (!wndPtr) return; + + /* Make sure window is viewable */ + if (!XGetWindowAttributes( display, wndPtr->window, &win_attr ) || + (win_attr.map_state != IsViewable)) return; + + /* Set X focus and install colormap */ + XSetInputFocus( display, wndPtr->window, RevertToParent, CurrentTime ); + if (COLOR_WinColormap != DefaultColormapOfScreen(screen)) + XInstallColormap( display, COLOR_WinColormap ); +} /***************************************************************** @@ -17,29 +60,44 @@ HWND hWndFocus = 0; HWND SetFocus(HWND hwnd) { - HWND hWndPrevFocus; + HWND hWndPrevFocus, hwndParent; WND *wndPtr; - hWndPrevFocus = hWndFocus; - hWndFocus = hwnd; + if (hwnd == hWndFocus) return hWndFocus; /* Nothing to do! */ - if (hwnd == 0) + if (hwnd) { - XSetInputFocus(display, None, RevertToPointerRoot, CurrentTime); - } - else - { - XWindowAttributes win_attr; - wndPtr = WIN_FindWndPtr(hwnd); - - if (XGetWindowAttributes( display, wndPtr->window, &win_attr )) + /* Check if we can set the focus to this window */ + + hwndParent = hwnd; + while ((wndPtr = WIN_FindWndPtr( hwndParent )) != NULL) { - if (win_attr.map_state == IsViewable) - XSetInputFocus(display, wndPtr->window, - RevertToParent, CurrentTime); + if ((wndPtr->dwStyle & WS_MINIMIZE) || + (wndPtr->dwStyle & WS_DISABLED)) return 0; + if (!(wndPtr->dwStyle & WS_CHILD)) break; + hwndParent = wndPtr->hwndParent; + } + + /* Now hwndParent is the top-level ancestor. Activate it. */ + + if (hwndParent != GetActiveWindow()) + { + SetWindowPos( hwndParent, HWND_TOP, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE ); + if (!IsWindow( hwnd )) return 0; /* Abort if window destroyed */ } } + /* Change focus and send messages */ + + hWndPrevFocus = hWndFocus; + hWndFocus = hwnd; + if (hWndPrevFocus) SendMessage( hWndPrevFocus, WM_KILLFOCUS, hwnd, 0 ); + if (hwnd == hWndFocus) /* Maybe already changed during WM_KILLFOCUS */ + { + if (hwnd) SendMessage( hWndFocus, WM_SETFOCUS, hWndPrevFocus, 0 ); + FOCUS_SetXFocus( hwnd ); + } return hWndPrevFocus; } diff --git a/windows/graphics.c b/windows/graphics.c index b37da40b692..fb3e580d23a 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -17,6 +17,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" +extern int COLOR_ToPhysical( DC *dc, COLORREF color ); + /*********************************************************************** * LineTo (GDI.19) */ @@ -351,7 +353,7 @@ COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color ) x = dc->w.DCOrgX + XLPTODP( dc, x ); y = dc->w.DCOrgY + YLPTODP( dc, y ); - pixel = GetNearestPaletteIndex( dc->w.hPalette, color ); + pixel = COLOR_ToPhysical( dc, color ); GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry ); XSetForeground( XT_display, dc->u.x.gc, pixel ); diff --git a/windows/keyboard.c b/windows/keyboard.c index e3afb20a365..3738a411347 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -8,10 +8,21 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; #include "win.h" +extern BOOL MouseButtonsStates[3]; + /********************************************************************** * GetKeyState (USER.106) */ int GetKeyState(int keycode) { - return 0; + switch(keycode) { + case VK_LBUTTON: + return MouseButtonsStates[0]; + case VK_MBUTTON: + return MouseButtonsStates[1]; + case VK_RBUTTON: + return MouseButtonsStates[2]; + default: + return 0; + } } diff --git a/windows/mdi.c b/windows/mdi.c new file mode 100644 index 00000000000..19122951763 --- /dev/null +++ b/windows/mdi.c @@ -0,0 +1,448 @@ +/* MDI.C + * + * Copyright 1994, Bob Amstadt + * + * This file contains routines to support MDI features. + */ +#include +#include +#include "windows.h" +#include "win.h" +#include "mdi.h" +#include "user.h" + +/* #define DEBUG_MDI /* */ + +/********************************************************************** + * MDIRecreateMenuList + */ +void +MDIRecreateMenuList(MDICLIENTINFO *ci) +{ + MDICHILDINFO *chi; + char buffer[128]; + int id, n, index; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIRecreateMenuList: hWindowMenu %04.4x\n", + ci->hWindowMenu); +#endif + + id = ci->idFirstChild; + while (DeleteMenu(ci->hWindowMenu, id, MF_BYCOMMAND)) + id++; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIRecreateMenuList: id %04.4x, idFirstChild %04.4x\n", + id, ci->idFirstChild); +#endif + + if (!ci->flagMenuAltered) + { + ci->flagMenuAltered = TRUE; + AppendMenu(ci->hWindowMenu, MF_SEPARATOR, 0, NULL); + } + + id = ci->idFirstChild; + index = 1; + for (chi = ci->infoActiveChildren; chi != NULL; chi = chi->next) + { + n = sprintf(buffer, "%d ", index++); + GetWindowText(chi->hwnd, buffer + n, sizeof(buffer) - n - 1); + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIRecreateMenuList: id %04.4x, '%s'\n", + id, buffer); +#endif + + AppendMenu(ci->hWindowMenu, MF_STRING, id++, buffer); + } +} + +/********************************************************************** + * MDICreateClient + */ +HWND +MDICreateClient(WND *w, MDICLIENTINFO *ci, HWND parent, LPMDICREATESTRUCT cs) +{ + HWND hwnd; + + /* + * Create child window + */ + cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL); + + hwnd = CreateWindowEx(0, cs->szClass, cs->szTitle, + WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | + WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | + WS_THICKFRAME | WS_VISIBLE | cs->style, + cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0, + w->hInstance, cs->lParam); + + if (hwnd) + { + HANDLE h = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MDICHILDINFO)); + MDICHILDINFO *child_info = USER_HEAP_ADDR(h); + if (!h) + { + DestroyWindow(hwnd); + return 0; + } + + ci->nActiveChildren++; + + child_info->next = ci->infoActiveChildren; + child_info->prev = NULL; + child_info->hwnd = hwnd; + + if (ci->infoActiveChildren) + ci->infoActiveChildren->prev = child_info; + + ci->infoActiveChildren = child_info; + + SendMessage(parent, WM_CHILDACTIVATE, 0, 0); + } + + return hwnd; +} + +/********************************************************************** + * MDIDestroyClient + */ +HWND +MDIDestroyClient(WND *w_parent, MDICLIENTINFO *ci, HWND parent, HWND child, + BOOL flagDestroy) +{ + MDICHILDINFO *chi; + + chi = ci->infoActiveChildren; + while (chi && chi->hwnd != child) + chi = chi->next; + + if (chi) + { + if (chi->prev) + chi->prev->next = chi->next; + if (chi->next) + chi->next->prev = chi->prev; + if (ci->infoActiveChildren == chi) + ci->infoActiveChildren = chi->next; + + ci->nActiveChildren--; + + if (chi->hwnd == ci->hwndActiveChild) + SendMessage(parent, WM_CHILDACTIVATE, 0, 0); + + USER_HEAP_FREE((HANDLE) chi); + + if (flagDestroy) + DestroyWindow(child); + } + + return 0; +} + +/********************************************************************** + * MDIBringChildToTop + */ +void MDIBringChildToTop(HWND parent, WORD id, WORD by_id) +{ + MDICHILDINFO *chi; + MDICLIENTINFO *ci; + WND *w; + int i; + + w = WIN_FindWndPtr(parent); + ci = (MDICLIENTINFO *) w->wExtra; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIBringToTop: id %04.4x, by_id %d\n", id, by_id); +#endif + + if (by_id) + id -= ci->idFirstChild; + if (!by_id || id < ci->nActiveChildren) + { + chi = ci->infoActiveChildren; + + if (by_id) + { + for (i = 0; i < id; i++) + chi = chi->next; + } + else + { + while (chi && chi->hwnd != id) + chi = chi->next; + } + + if (!chi) + return; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIBringToTop: child %04.4x\n", chi->hwnd); +#endif + if (chi != ci->infoActiveChildren) + { + SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE ); + + if (chi->next) + chi->next->prev = chi->prev; + + if (chi->prev) + chi->prev->next = chi->next; + + chi->prev = NULL; + chi->next = ci->infoActiveChildren; + chi->next->prev = chi; + ci->infoActiveChildren = chi; + + SendMessage(parent, WM_CHILDACTIVATE, 0, 0); + } + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIBringToTop: pos %04.4x, hwnd %04.4x\n", + id, chi->hwnd); +#endif + } +} + +/********************************************************************** + * MDIChildActivated + */ +LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent) +{ + MDICHILDINFO *chi; + HWND deact_hwnd; + HWND act_hwnd; + LONG lParam; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIChildActivate: top %04.4x\n", w->hwndChild); +#endif + + chi = ci->infoActiveChildren; + if (chi) + { + deact_hwnd = ci->hwndActiveChild; + act_hwnd = chi->hwnd; + lParam = ((LONG) deact_hwnd << 16) | act_hwnd; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDIChildActivate: deact %04.4x, act %04.4x\n", + deact_hwnd, act_hwnd); +#endif + + ci->hwndActiveChild = act_hwnd; + + if (deact_hwnd != act_hwnd) + { + MDIRecreateMenuList(ci); + SendMessage(deact_hwnd, WM_NCACTIVATE, FALSE, 0); + SendMessage(deact_hwnd, WM_MDIACTIVATE, FALSE, lParam); + } + + SendMessage(act_hwnd, WM_NCACTIVATE, TRUE, 0); + SendMessage(act_hwnd, WM_MDIACTIVATE, TRUE, lParam); + } + + if (chi || ci->nActiveChildren == 0) + { + MDIRecreateMenuList(ci); + DrawMenuBar(GetParent(parent)); + } + + return 0; +} + +/********************************************************************** + * MDICascade + */ +LONG MDICascade(HWND parent, MDICLIENTINFO *ci) +{ + MDICHILDINFO *chi; + RECT rect; + int spacing, xsize, ysize; + int x, y; + + GetClientRect(parent, &rect); + spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); + ysize = abs(rect.bottom - rect.top) - 8 * spacing; + xsize = abs(rect.right - rect.left) - 8 * spacing; + +#ifdef DEBUG_MDI + fprintf(stderr, + "MDICascade: Client wnd at (%d,%d) - (%d,%d), spacing %d\n", + rect.left, rect.top, rect.right, rect.bottom, spacing); + fprintf(stderr, "MDICascade: searching for last child\n"); +#endif + for (chi = ci->infoActiveChildren; chi->next != NULL; chi = chi->next) + ; + +#ifdef DEBUG_MDI + fprintf(stderr, "MDICascade: last child is %04.4x\n", chi->hwnd); +#endif + x = 0; + y = 0; + for ( ; chi != NULL; chi = chi->prev) + { +#ifdef DEBUG_MDI + fprintf(stderr, "MDICascade: move %04.4x to (%d,%d) size [%d,%d]\n", + chi->hwnd, x, y, xsize, ysize); +#endif + SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize, + SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER); + + x += spacing; + y += spacing; + } + + return 0; +} + +/********************************************************************** + * MDIClientWndProc + * + * This function is the handler for all MDI requests. + */ +LONG +MDIClientWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) +{ + LPCREATESTRUCT cs; + LPCLIENTCREATESTRUCT ccs; + MDICLIENTINFO *ci; + WND *w; + RECT rect; + + w = WIN_FindWndPtr(hwnd); + ci = (MDICLIENTINFO *) w->wExtra; + + switch (message) + { + case WM_CHILDACTIVATE: + return MDIChildActivated(w, ci, hwnd); + + case WM_CREATE: + cs = (LPCREATESTRUCT) lParam; + ccs = (LPCLIENTCREATESTRUCT) cs->lpCreateParams; + ci->hWindowMenu = ccs->hWindowMenu; + ci->idFirstChild = ccs->idFirstChild; + ci->infoActiveChildren = NULL; + ci->flagMenuAltered = FALSE; + ci->flagChildMaximized = FALSE; + w->dwStyle |= WS_CLIPCHILDREN; + + GetClientRect(w->hwndParent, &rect); + MoveWindow(hwnd, 0, 0, rect.right, rect.bottom, 1); + + return 0; + + case WM_MDIACTIVATE: + MDIBringChildToTop(hwnd, wParam, FALSE); + return 0; + + case WM_MDICASCADE: + return MDICascade(hwnd, ci); + + case WM_MDICREATE: + return MDICreateClient(w, ci, hwnd, (LPMDICREATESTRUCT) lParam); + + case WM_MDIDESTROY: + return MDIDestroyClient(w, ci, hwnd, wParam, TRUE); + + case WM_MDIGETACTIVE: + return ((LONG) ci->hwndActiveChild | + ((LONG) ci->flagChildMaximized << 16)); + + case WM_MDIICONARRANGE: + /* return MDIIconArrange(...) */ + break; + + case WM_MDIMAXIMIZE: + ci->flagChildMaximized = TRUE; + MDIBringChildToTop(hwnd, wParam, FALSE); + return 0; + + case WM_NCACTIVATE: + SendMessage(ci->hwndActiveChild, message, wParam, lParam); + break; + + case WM_PARENTNOTIFY: + if (wParam == WM_DESTROY) + return MDIDestroyClient(w, ci, hwnd, LOWORD(lParam), FALSE); + else if (wParam == WM_LBUTTONDOWN) + MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE); + break; + + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +/********************************************************************** + * DefFrameProc (USER.445) + * + */ +LONG +DefFrameProc(HWND hwnd, HWND hwndMDIClient, WORD message, + WORD wParam, LONG lParam) +{ + switch (message) + { + case WM_COMMAND: + MDIBringChildToTop(hwndMDIClient, wParam, TRUE); + break; + + case WM_NCACTIVATE: + SendMessage(hwndMDIClient, message, wParam, lParam); + break; + + case WM_SETFOCUS: + SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam); + break; + + case WM_SIZE: + MoveWindow(hwndMDIClient, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); + break; + + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +/********************************************************************** + * DefMDIChildProc (USER.447) + * + */ +LONG +DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) +{ + MDICLIENTINFO *ci; + WND *w; + + w = WIN_FindWndPtr(GetParent(hwnd)); + ci = (MDICLIENTINFO *) w->wExtra; + + switch (message) + { + case WM_NCHITTEST: + ci->hwndHitTest = hwnd; + break; + + case WM_NCPAINT: + return NC_DoNCPaint(hwnd, (HRGN)1, + hwnd == ci->hwndActiveChild); + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + +/********************************************************************** + * TranslateMDISysAccel (USER.451) + * + */ +BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg) +{ + return 0; +} diff --git a/windows/message.c b/windows/message.c index 910f7a418c2..62fd98178b9 100644 --- a/windows/message.c +++ b/windows/message.c @@ -22,10 +22,13 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ -extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */ +extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg, + HWND hwnd, BOOL remove ); /* timer.c */ extern void EVENT_ProcessEvent( XEvent *event ); /* event.c */ extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/ - +extern void WIN_SendParentNotify( HWND hwnd, WORD event, + LONG lParam ); /* win.c */ + extern Display * display; /* System message queue (for hardware events) */ @@ -214,6 +217,11 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg ) LONG hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, MAKELONG( msg->pt.x, msg->pt.y ) ); + /* Send the WM_PARENTNOTIFY message */ + + if (mouseClick) WIN_SendParentNotify( msg->hwnd, msg->message, + MAKELONG( msg->pt.x, msg->pt.y ) ); + /* Activate the window if needed */ if (mouseClick) @@ -360,20 +368,51 @@ void MSG_DecTimerCount( HANDLE hQueue ) * hardware_event * * Add an event to the system message queue. - * Note: the position is in screen coordinates. + * Note: the position is relative to the desktop window. */ -void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam, - WORD xPos, WORD yPos, DWORD time, DWORD extraInfo ) +void hardware_event( WORD message, WORD wParam, LONG lParam, + int xPos, int yPos, DWORD time, DWORD extraInfo ) { MSG msg; - msg.hwnd = hwnd; + msg.hwnd = 0; msg.message = message; msg.wParam = wParam; msg.lParam = lParam; msg.time = time; - msg.pt.x = xPos; - msg.pt.y = yPos; + msg.pt.x = xPos & 0xffff; + msg.pt.y = yPos & 0xffff; + + /* Determine the hwnd for this message */ + /* Maybe this should be done in GetMessage() */ + + if ((message >= WM_MOUSEFIRST) && (message <= WM_MOUSELAST)) + { + /* Mouse event */ + if (GetCapture()) msg.hwnd = GetCapture(); + else msg.hwnd = WindowFromPoint( msg.pt ); + } + else if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) + { + /* Keyboard event */ + msg.hwnd = GetFocus(); + if (!msg.hwnd && ((message==WM_KEYDOWN) || (message==WM_SYSKEYDOWN))) + MessageBeep(0); /* Beep on key press if no focus */ + } + if (!msg.hwnd) return; /* No window for this message */ + + /* Merge with previous event if possible */ + + if (sysMsgQueue->msgCount && (message == WM_MOUSEMOVE)) + { + MSG *prevMsg = &sysMsgQueue->messages[sysMsgQueue->nextMessage].msg; + if ((prevMsg->message == message) && (prevMsg->wParam == wParam)) + { + *prevMsg = msg; /* Overwrite previous message */ + return; + } + } + if (!MSG_AddMsg( sysMsgQueue, &msg, extraInfo )) printf( "hardware_event: Queue is full\n" ); } @@ -480,6 +519,24 @@ BOOL GetInputState() } +/*********************************************************************** + * MSG_Synchronize + * + * Synchronize with the X server. Should not be used too often. + */ +void MSG_Synchronize() +{ + XEvent event; + + XSync( display, False ); + while (XPending( display )) + { + XNextEvent( display, &event ); + EVENT_ProcessEvent( &event ); + } +} + + /*********************************************************************** * MSG_PeekMessage */ @@ -487,7 +544,7 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags, BOOL peek ) { int pos, mask; - DWORD nextExp; /* Next timer expiration time */ + LONG nextExp; /* Next timer expiration time */ XEvent event; if (first || last) @@ -584,8 +641,11 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, /* Finally handle WM_TIMER messages */ if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER)) - if (TIMER_CheckTimer( &nextExp )) - continue; /* Restart the whole search */ + { + if (TIMER_CheckTimer( &nextExp, msg, hwnd, flags & PM_REMOVE )) + break; /* Got a timer msg */ + } + else nextExp = -1; /* No timeout needed */ /* Wait until something happens */ if (peek) return FALSE; @@ -635,7 +695,10 @@ BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { MSG msg; - + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE; + msg.hwnd = hwnd; msg.message = message; msg.wParam = wParam; @@ -643,7 +706,7 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) msg.time = GetTickCount(); msg.pt.x = 0; msg.pt.y = 0; - + return MSG_AddMsg( appMsgQueue, &msg, 0 ); } diff --git a/windows/nonclient.c b/windows/nonclient.c index 5456b08ff36..9a7f85fffa5 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -522,7 +522,7 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, * Paint the non-client area. * 'hrgn' is the update rgn to use (in client coords) or 1 if no update rgn. */ -static void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active ) +void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active ) { HDC hdc; RECT rect, rect2; @@ -648,7 +648,7 @@ static void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active ) */ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) { - NC_DoNCPaint( hwnd, hrgn, (hwnd == GetActiveWindow()) ); + NC_DoNCPaint( hwnd, hrgn, hwnd == GetActiveWindow() ); return 0; } @@ -884,9 +884,9 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt ) if (wndPtr->dwStyle & WS_CHILD) hdc = GetDC( wndPtr->hwndParent ); else - { /* Grab the server only when moving top-level windows */ + { /* Grab the server only when moving top-level windows without desktop */ hdc = GetDC( 0 ); - XGrabServer( display ); + if (rootWindow == DefaultRootWindow(display)) XGrabServer( display ); } NC_DrawMovingFrame( hdc, &sizingRect, thickframe ); @@ -951,7 +951,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt ) else { ReleaseDC( 0, hdc ); - XUngrabServer( display ); + if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display ); } SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 ); @@ -1018,9 +1018,8 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam ) */ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt ) { - MSG msg; - WORD scrollbar; - + MSG msg; + WORD scrollbar; if ((wParam & 0xfff0) == SC_HSCROLL) { if ((wParam & 0x0f) != HTHSCROLL) return; @@ -1071,26 +1070,27 @@ static void NC_TrackMouseMenuBar( HWND hwnd, WORD wParam, POINT pt ) #endif ScreenToClient(hwnd, &pt); pt.y += lppop->rect.bottom; - MenuButtonDown(hwnd, lppop, pt.x, pt.y); SetCapture(hwnd); - do { - if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; - ScreenToClient(hwnd, &msg.pt); - msg.pt.y += lppop->rect.bottom; - switch(msg.message) { - case WM_LBUTTONUP: - MenuButtonUp(hwnd, lppop, msg.pt.x, msg.pt.y); - break; - case WM_MOUSEMOVE: - MenuMouseMove(hwnd, lppop, msg.wParam, msg.pt.x, msg.pt.y); - break; - default: - TranslateMessage(&msg); - DispatchMessage(&msg); - break; + if (!MenuButtonDown(hwnd, lppop, pt.x, pt.y)) { + do { + if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; + ScreenToClient(hwnd, &msg.pt); + msg.pt.y += lppop->rect.bottom; + switch(msg.message) { + case WM_LBUTTONUP: + MenuButtonUp(hwnd, lppop, msg.pt.x, msg.pt.y); + break; + case WM_MOUSEMOVE: + MenuMouseMove(hwnd, lppop, msg.wParam, msg.pt.x, msg.pt.y); + break; + default: + TranslateMessage(&msg); + DispatchMessage(&msg); + break; + } + } while (msg.message != WM_LBUTTONUP); + ReleaseCapture(); } - } while (msg.message != WM_LBUTTONUP); - ReleaseCapture(); GlobalUnlock(wndPtr->wIDmenu); } @@ -1216,6 +1216,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) case SC_VSCROLL: case SC_HSCROLL: + if (wndPtr->dwStyle & WS_CHILD) ClientToScreen(wndPtr->hwndParent, &pt); NC_TrackScrollBar( hwnd, wParam, pt ); break; diff --git a/windows/painting.c b/windows/painting.c index 0090d916cb8..36c72e722b5 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -25,8 +25,10 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) if (!wndPtr) return 0; hrgnUpdate = wndPtr->hrgnUpdate; /* Save update region */ - - if (!(lps->hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, + if (!hrgnUpdate) /* Create an empty region */ + if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0; + + if (!(lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0; GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint ); @@ -37,7 +39,7 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT); SendMessage( hwnd, WM_NCPAINT, hrgnUpdate, 0 ); - if (hrgnUpdate) DeleteObject( hrgnUpdate ); + DeleteObject( hrgnUpdate ); if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE; else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 ); diff --git a/windows/syscolor.c b/windows/syscolor.c index a3ca9ace0f3..80b69d5f0c4 100644 --- a/windows/syscolor.c +++ b/windows/syscolor.c @@ -2,62 +2,62 @@ * Support for system colors * * Copyright David W. Metcalfe, 1993 + * Copyright Alexandre Julliard, 1994 * */ static char Copyright[] = "Copyright David W. Metcalfe, 1993"; +static char Copyright2[] = "Copyright Alexandre Julliard, 1994"; #include -#include #include "windows.h" -#include "gdi.h" -/* Default system colors - loosely based on Windows default color set */ -static const char *DefSysColors[] = + +static char * DefSysColors[] = { - "gray80", /* COLOR_SCROLLBAR */ - "gray60", /* COLOR_BACKGROUND */ - "blue4", /* COLOR_ACTIVECAPTION */ - "white", /* COLOR_INACTIVECAPTION */ - "white", /* COLOR_MENU */ - "white", /* COLOR_WINDOW */ - "black", /* COLOR_WINDOWFRAME */ - "black", /* COLOR_MENUTEXT */ - "black", /* COLOR_WINDOWTEXT */ - "white", /* COLOR_CAPTIONTEXT */ - "gray40", /* COLOR_ACTIVEBORDER */ - "white", /* COLOR_INACTIVEBORDER */ - "gray60", /* COLOR_APPWORKSPACE */ - "black", /* COLOR_HIGHLIGHT */ - "white", /* COLOR_HIGHLIGHTTEXT */ - "gray70", /* COLOR_BTNFACE */ - "gray30", /* COLOR_BTNSHADOW */ - "gray70", /* COLOR_GRAYTEXT */ - "black", /* COLOR_BTNTEXT */ - "black", /* COLOR_INACTIVECAPTIONTEXT */ - "white", /* COLOR_BTNHIGHLIGHT */ + "Scrollbar", "224 224 224", /* COLOR_SCROLLBAR */ + "Background", "192 192 192", /* COLOR_BACKGROUND */ + "ActiveTitle", "0 64 128", /* COLOR_ACTIVECAPTION */ + "InactiveTitle", "255 255 255", /* COLOR_INACTIVECAPTION */ + "Menu", "0 255 255", /* COLOR_MENU */ + "Window", "255 255 255", /* COLOR_WINDOW */ + "WindowFrame", "0 0 0", /* COLOR_WINDOWFRAME */ + "MenuText", "0 0 0", /* COLOR_MENUTEXT */ + "WindowText", "0 0 0", /* COLOR_WINDOWTEXT */ + "TitleText", "255 255 255", /* COLOR_CAPTIONTEXT */ + "ActiveBorder", "128 128 128", /* COLOR_ACTIVEBORDER */ + "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER */ + "AppWorkspace", "255 255 232", /* COLOR_APPWORKSPACE */ + "Hilight", "166 202 240", /* COLOR_HIGHLIGHT */ + "HilightText", "0 0 0", /* COLOR_HIGHLIGHTTEXT */ + "ButtonFace", "192 192 192", /* COLOR_BTNFACE */ + "ButtonShadow", "128 128 128", /* COLOR_BTNSHADOW */ + "GrayText", "192 192 192", /* COLOR_GRAYTEXT */ + "ButtonText", "0 0 0", /* COLOR_BTNTEXT */ + "InactiveTitleText", "0 0 0", /* COLOR_INACTIVECAPTIONTEXT */ + "ButtonHilight", "255 255 255" /* COLOR_BTNHIGHLIGHT */ }; -#define NUM_SYS_COLORS (sizeof(DefSysColors) / sizeof(DefSysColors[0])) +#define NUM_SYS_COLORS (COLOR_BTNHIGHLIGHT+1) static COLORREF SysColors[NUM_SYS_COLORS]; -extern Colormap COLOR_WinColormap; - +/************************************************************************* + * SYSCOLOR_Init + */ void SYSCOLOR_Init() { - XColor color; - int i; + int i, r, g, b; + char **p; + char buffer[100]; - for (i = 0; i < NUM_SYS_COLORS; i++) + for (i = 0, p = DefSysColors; i < NUM_SYS_COLORS; i++, p += 2) { - if (XParseColor(XT_display, COLOR_WinColormap, DefSysColors[i], &color)) - { - SysColors[i] = RGB(color.red >> 8, color.green >> 8, - color.blue >> 8); - } + GetProfileString( "colors", p[0], p[1], buffer, 100 ); + if (!sscanf( buffer, " %d %d %d", &r, &g, &b )) r = g = b = 0; + SysColors[i] = RGB( r, g, b ); } } diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c index bea45613500..71413c715af 100644 --- a/windows/sysmetrics.c +++ b/windows/sysmetrics.c @@ -14,6 +14,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; short sysMetrics[SM_CMETRICS]; extern Display * display; +extern int screenWidth, screenHeight; /*********************************************************************** * SYSMETRICS_Init @@ -22,8 +23,8 @@ extern Display * display; */ void SYSMETRICS_Init() { - sysMetrics[SM_CXSCREEN] = DisplayWidth( display, DefaultScreen(display) ); - sysMetrics[SM_CYSCREEN] = DisplayHeight( display, DefaultScreen(display) ); + sysMetrics[SM_CXSCREEN] = screenWidth; + sysMetrics[SM_CYSCREEN] = screenHeight; sysMetrics[SM_CXVSCROLL] = SYSMETRICS_CXVSCROLL; sysMetrics[SM_CYHSCROLL] = SYSMETRICS_CYHSCROLL; sysMetrics[SM_CYCAPTION] = SYSMETRICS_CYCAPTION; diff --git a/windows/timer.c b/windows/timer.c index 2a40bec2c28..641bbe05bf8 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -28,6 +28,10 @@ static TIMER TimersArray[NB_TIMERS]; static TIMER * pNextTimer = NULL; /* Next timer to expire */ + /* Duration from 'time' until expiration of the timer */ +#define EXPIRE_TIME(pTimer,time) \ + (((pTimer)->expires <= (time)) ? 0 : (pTimer)->expires - (time)) + /*********************************************************************** * TIMER_InsertTimer @@ -46,7 +50,7 @@ static void TIMER_InsertTimer( TIMER * pTimer ) TIMER * ptr = pNextTimer; while (ptr->next && (pTimer->expires >= ptr->next->expires)) ptr = ptr->next; - pTimer->next = ptr; + pTimer->next = ptr->next; ptr->next = pTimer; } } @@ -71,42 +75,50 @@ static void TIMER_RemoveTimer( TIMER * pTimer ) /*********************************************************************** - * TIMER_NextExpire + * TIMER_RestartTimers * - * Return time until next timer expiration (-1 if none). + * Restart an expired timer. */ -static DWORD TIMER_NextExpire( DWORD curTime ) +static void TIMER_RestartTimer( TIMER * pTimer, DWORD curTime ) { - if (!pNextTimer) return -1; - if (pNextTimer->expires <= curTime) return 0; - return pNextTimer->expires - curTime; + TIMER_RemoveTimer( pTimer ); + pTimer->expires = curTime + pTimer->timeout; + TIMER_InsertTimer( pTimer ); } - + /*********************************************************************** * TIMER_CheckTimer * - * Check whether a timer has expired, and post a message if necessary. - * Return TRUE if msg posted, and return time until next expiration in 'next'. + * Check whether a timer has expired, and create a message if necessary. + * Otherwise, return time until next timer expiration in 'next'. + * If 'hwnd' is not NULL, only consider timers for this window. + * If 'remove' is TRUE, remove all expired timers up to the returned one. */ -BOOL TIMER_CheckTimer( DWORD *next ) +BOOL TIMER_CheckTimer( LONG *next, MSG *msg, HWND hwnd, BOOL remove ) { TIMER * pTimer = pNextTimer; DWORD curTime = GetTickCount(); - - if ((*next = TIMER_NextExpire( curTime )) != 0) return FALSE; - PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, (LONG)pTimer->proc ); - TIMER_RemoveTimer( pTimer ); + if (hwnd) /* Find first timer for this window */ + while (pTimer && (pTimer->hwnd != hwnd)) pTimer = pTimer->next; - /* If timeout == 0, the timer has been removed by KillTimer */ - if (pTimer->timeout) + if (!pTimer) *next = -1; + else *next = EXPIRE_TIME( pTimer, curTime ); + if (*next != 0) return FALSE; /* No timer expired */ + + if (remove) /* Restart all timers before pTimer, and then pTimer itself */ { - /* Restart the timer */ - pTimer->expires = curTime + pTimer->timeout; - TIMER_InsertTimer( pTimer ); + while (pNextTimer != pTimer) TIMER_RestartTimer( pNextTimer, curTime ); + TIMER_RestartTimer( pTimer, curTime ); } - *next = TIMER_NextExpire( curTime ); + + /* Build the message */ + msg->hwnd = pTimer->hwnd; + msg->message = pTimer->msg; + msg->wParam = pTimer->id; + msg->lParam = (LONG)pTimer->proc; + msg->time = curTime; return TRUE; } diff --git a/windows/win.c b/windows/win.c index 45157f9eac3..cfc8e852e6f 100644 --- a/windows/win.c +++ b/windows/win.c @@ -6,6 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include +#include #include #include "class.h" @@ -19,7 +21,11 @@ extern Colormap COLOR_WinColormap; extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */ extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.c */ +extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/ extern HMENU CopySysMenu(); /* menu.c */ +extern LONG MDIClientWndProc(HWND hwnd, WORD message, + WORD wParam, LONG lParam); /* mdi.c */ + static HWND hwndDesktop = 0; @@ -109,7 +115,8 @@ BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ) HWND WIN_FindWinToRepaint( HWND hwnd ) { WND * wndPtr; - + + /* Note: the desktop window never gets WM_PAINT messages */ if (!hwnd) hwnd = GetTopWindow( hwndDesktop ); for ( ; hwnd != 0; hwnd = wndPtr->hwndNext ) { @@ -133,15 +140,15 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless * the window has the WS_EX_NOPARENTNOTIFY style. */ -static void WIN_SendParentNotify( HWND hwnd, WND * wndPtr, WORD event ) +void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam ) { HWND current = GetParent( hwnd ); - - if (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) return; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) return; while (current) { - SendMessage( current, WM_PARENTNOTIFY, - event, MAKELONG( hwnd, wndPtr->wIDmenu ) ); + SendMessage( current, WM_PARENTNOTIFY, event, lParam ); current = GetParent( current ); } } @@ -152,19 +159,19 @@ static void WIN_SendParentNotify( HWND hwnd, WND * wndPtr, WORD event ) * * Create the desktop window. */ -static HWND WIN_CreateDesktopWindow() +BOOL WIN_CreateDesktopWindow() { - HWND hwnd; WND *wndPtr; HCLASS hclass; CLASS *classPtr; if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, &classPtr ))) - return 0; + return FALSE; - hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra); - if (!hwnd) return 0; - wndPtr = (WND *) USER_HEAP_ADDR( hwnd ); + hwndDesktop = USER_HEAP_ALLOC( GMEM_MOVEABLE, + sizeof(WND)+classPtr->wc.cbWndExtra ); + if (!hwndDesktop) return FALSE; + wndPtr = (WND *) USER_HEAP_ADDR( hwndDesktop ); wndPtr->hwndNext = 0; wndPtr->hwndChild = 0; @@ -187,7 +194,7 @@ static HWND WIN_CreateDesktopWindow() wndPtr->hrgnUpdate = 0; wndPtr->hwndLastActive = 0; wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; - wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; + wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; wndPtr->dwExStyle = 0; wndPtr->hdce = 0; wndPtr->hmenuSystem = 0; @@ -196,9 +203,15 @@ static HWND WIN_CreateDesktopWindow() wndPtr->wIDmenu = 0; wndPtr->hText = 0; wndPtr->flags = 0; - wndPtr->window = DefaultRootWindow( display ); + wndPtr->window = rootWindow; wndPtr->hSysMenu = 0; - return hwnd; + + /* Send dummy WM_NCCREATE message */ + SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 ); + EVENT_RegisterWindow( wndPtr->window, hwndDesktop ); + RedrawWindow( hwndDesktop, NULL, 0, + RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW ); + return TRUE; } @@ -228,18 +241,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, HANDLE hcreateStruct; int wmcreate; XSetWindowAttributes win_attr; - Window parentWindow; - int x_rel, y_rel; #ifdef DEBUG_WIN printf( "CreateWindowEx: %d '%s' '%s' %d,%d %dx%d %08x %x\n", exStyle, className, windowName, x, y, width, height, style, parent); #endif - /* Before anything, create the desktop window */ - if (!hwndDesktop) - if (!(hwndDesktop = WIN_CreateDesktopWindow())) return 0; - if (x == CW_USEDEFAULT) x = y = 0; if (width == CW_USEDEFAULT) { @@ -257,7 +264,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, if (!(parentPtr = WIN_FindWndPtr( parent ))) return 0; } else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ - + if (!(class = CLASS_FindClassByName( className, &classPtr ))) { printf("CreateWindow BAD CLASSNAME '%s' !\n", className); return 0; @@ -345,30 +352,25 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | - ButtonReleaseMask | FocusChangeMask | EnterWindowMask; - win_attr.override_redirect = True; - win_attr.colormap = COLOR_WinColormap; - if (style & WS_CHILD) + ButtonReleaseMask | EnterWindowMask; + win_attr.override_redirect = (rootWindow == DefaultRootWindow(display)); + win_attr.colormap = COLOR_WinColormap; + if (!(style & WS_CHILD)) { - parentWindow = parentPtr->window; - x_rel = x + parentPtr->rectClient.left - parentPtr->rectWindow.left; - y_rel = y + parentPtr->rectClient.top - parentPtr->rectWindow.top; + parentPtr = WIN_FindWndPtr( hwndDesktop ); + /* Only select focus events on top-level override-redirect windows */ + if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask; } - else - { - parentWindow = DefaultRootWindow( display ); - x_rel = x; - y_rel = y; - } - wndPtr->window = XCreateWindow(display, parentWindow, - x_rel, y_rel, width, height, 0, - CopyFromParent, InputOutput, CopyFromParent, - CWEventMask | CWOverrideRedirect | - CWColormap, &win_attr ); + wndPtr->window = XCreateWindow( display, parentPtr->window, + x + parentPtr->rectClient.left - parentPtr->rectWindow.left, + y + parentPtr->rectClient.top - parentPtr->rectWindow.top, + width, height, 0, + CopyFromParent, InputOutput, CopyFromParent, + CWEventMask | CWOverrideRedirect | CWColormap, &win_attr ); XStoreName( display, wndPtr->window, windowName ); /* Send the WM_CREATE message */ - + hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) ); createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct ); createStruct->lpCreateParams = data; @@ -427,12 +429,13 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, EVENT_RegisterWindow( wndPtr->window, hwnd ); - WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE ); + WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) ); if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); return hwnd; } + /*********************************************************************** * DestroyWindow (USER.53) */ @@ -443,9 +446,12 @@ BOOL DestroyWindow( HWND hwnd ) /* Initialisation */ + if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE; - WIN_SendParentNotify( hwnd, wndPtr, WM_DESTROY ); + if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE ); + if (hwnd == GetFocus()) SetFocus( 0 ); + WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) ); /* Send destroy messages and destroy children */ @@ -501,7 +507,34 @@ BOOL OpenIcon(HWND hWnd) */ HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch) { - return((HWND)NULL); + HCLASS hclass; + CLASS *classPtr; + HWND hwnd; + + if (ClassMatch) + { + hclass = CLASS_FindClassByName( ClassMatch, &classPtr ); + if (!hclass) return 0; + } + else hclass = 0; + + hwnd = GetTopWindow( hwndDesktop ); + while(hwnd) + { + WND *wndPtr = WIN_FindWndPtr( hwnd ); + if (!hclass || (wndPtr->hClass == hclass)) + { + /* Found matching class */ + if (!TitleMatch) return hwnd; + if (wndPtr->hText) + { + char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText ); + if (!strcmp( textPtr, TitleMatch )) return hwnd; + } + } + hwnd = wndPtr->hwndNext; + } + return 0; } @@ -514,6 +547,47 @@ HWND GetDesktopWindow() } +/******************************************************************* + * EnableWindow (USER.34) + */ +BOOL EnableWindow( HWND hwnd, BOOL enable ) +{ + WND *wndPtr; + + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; + if (enable && (wndPtr->dwStyle & WS_DISABLED)) + { + /* Enable window */ + wndPtr->dwStyle &= ~WS_DISABLED; + SendMessage( hwnd, WM_ENABLE, TRUE, 0 ); + return TRUE; + } + else if (!enable && !(wndPtr->dwStyle & WS_DISABLED)) + { + /* Disable window */ + wndPtr->dwStyle |= WS_DISABLED; + if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() )) + SetFocus( 0 ); /* A disabled window can't have the focus */ + if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() )) + ReleaseCapture(); /* A disabled window can't capture the mouse */ + SendMessage( hwnd, WM_ENABLE, FALSE, 0 ); + return FALSE; + } + return ((wndPtr->dwStyle & WS_DISABLED) != 0); +} + + +/*********************************************************************** + * IsWindowEnabled (USER.35) + */ +BOOL IsWindowEnabled(HWND hWnd) +{ + WND * wndPtr; + + if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE; + return !(wndPtr->dwStyle & WS_DISABLED); +} + /********************************************************************** * GetWindowWord (USER.133) @@ -554,86 +628,6 @@ WORD SetWindowWord( HWND hwnd, short offset, WORD newval ) } - -/******************************************************************* - * WIN_SetSensitive - * - * sets hWnd and all children to the same sensitivity - * - * sets hWnd sensitive and then calls SetSensitive on hWnd's child - * and all of hWnd's child's Next windows - */ -static BOOL WIN_SetSensitive(HWND hWnd, BOOL fEnable) -{ - WND *wndPtr; - HWND hwnd; - - printf("in SetSenitive\n"); - - if (!hWnd) return 0; - if (!(wndPtr = WIN_FindWndPtr(hWnd))) return 0; - - - if (fEnable) { - wndPtr->dwStyle &= ~WS_DISABLED; - } else { - wndPtr->dwStyle |= WS_DISABLED; - } - - hwnd=wndPtr->hwndChild; - while (hwnd) { /* mk next child sens */ - WIN_SetSensitive(hwnd, fEnable); - if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) return 0; - hwnd=wndPtr->hwndNext; - } - return 1; - -} - -/******************************************************************* - * EnableWindow (USER.34) - * - * - */ - -BOOL EnableWindow(HWND hWnd, BOOL fEnable) -{ - WND *wndPtr; - int eprev; - - if (hWnd == 0) return 0; - - wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == 0) return 0; - - eprev = ! (wndPtr->dwStyle & WS_DISABLED); - - if (fEnable != eprev) { /* change req */ - printf("changing window\n"); - WIN_SetSensitive(hWnd, fEnable); - SendMessage(hWnd, WM_ENABLE, (WORD)fEnable, 0); - } - return !eprev; -} - -/*********************************************************************** - * IsWindowEnabled (USER.35) - */ - -BOOL IsWindowEnabled(HWND hWnd) -{ - WND * wndPtr; - - if (hWnd == 0) return 0; - wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == 0) return 0; - - return !(wndPtr->dwStyle & WS_DISABLED); -} - - - - /********************************************************************** * GetWindowLong (USER.135) */ diff --git a/windows/winpos.c b/windows/winpos.c index ee37ecb2850..0534bc846e6 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -9,8 +9,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "sysmetrics.h" #include "user.h" #include "win.h" - -extern Display * display; +#include "message.h" static HWND hwndActive = 0; /* Currently active window */ @@ -68,15 +67,32 @@ void ScreenToClient( HWND hwnd, LPPOINT lppnt ) */ HWND WindowFromPoint( POINT pt ) { - RECT rect; - HWND hwnd = GetTopWindow( GetDesktopWindow() ); - while (hwnd) + HWND hwndRet = 0; + HWND hwnd = GetDesktopWindow(); + + while(hwnd) { - GetWindowRect( hwnd, &rect ); - if (PtInRect( &rect, pt )) return hwnd; - hwnd = GetWindow( hwnd, GW_HWNDNEXT ); + /* If point is in window, and window is visible, */ + /* not disabled and not transparent, then explore */ + /* its children. Otherwise, go to the next window. */ + + WND *wndPtr = WIN_FindWndPtr( hwnd ); + if ((pt.x >= wndPtr->rectWindow.left) && + (pt.x < wndPtr->rectWindow.right) && + (pt.y >= wndPtr->rectWindow.top) && + (pt.y < wndPtr->rectWindow.bottom) && + !(wndPtr->dwStyle & WS_DISABLED) && + (wndPtr->dwStyle & WS_VISIBLE) && + !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)) + { + pt.x -= wndPtr->rectClient.left; + pt.y -= wndPtr->rectClient.top; + hwndRet = hwnd; + hwnd = wndPtr->hwndChild; + } + else hwnd = wndPtr->hwndNext; } - return 0; + return hwndRet; } @@ -97,7 +113,7 @@ HWND ChildWindowFromPoint( HWND hwndParent, POINT pt ) if (PtInRect( &rect, pt )) return hwnd; hwnd = GetWindow( hwnd, GW_HWNDNEXT ); } - return 0; + return hwndParent; } @@ -168,7 +184,6 @@ HWND GetActiveWindow() return hwndActive; } - /******************************************************************* * SetActiveWindow (USER.59) */ @@ -461,6 +476,20 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, winPos->cy = cy; winPos->flags = flags; SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos ); + hwndInsertAfter = winPos->hwndInsertAfter; + + /* Some sanity checks */ + + if (!IsWindow( hwnd ) || (hwnd == GetDesktopWindow())) goto Abort; + if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) + flags |= SWP_NOMOVE | SWP_NOSIZE; + if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE))) + { + if (hwnd != hwndActive) hwndInsertAfter = HWND_TOP; + else if ((hwndInsertAfter == HWND_TOPMOST) || + (hwndInsertAfter == HWND_NOTOPMOST)) + hwndInsertAfter = HWND_TOP; + } /* Calculate new position and size */ @@ -485,8 +514,6 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, if (!(winPos->flags & SWP_NOZORDER)) { - hwndInsertAfter = winPos->hwndInsertAfter; - /* TOPMOST not supported yet */ if ((hwndInsertAfter == HWND_TOPMOST) || (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP; @@ -571,6 +598,12 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, { wndPtr->dwStyle |= WS_VISIBLE; XMapWindow( display, wndPtr->window ); + MSG_Synchronize(); + if (!(winPos->flags & SWP_NOREDRAW)) + RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | + RDW_ERASENOW | RDW_FRAME ); + else RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE ); + } else if (winPos->flags & SWP_HIDEWINDOW) { diff --git a/wine.ini b/wine.ini index d8755c42bf5..b2c79af09a7 100644 --- a/wine.ini +++ b/wine.ini @@ -2,7 +2,7 @@ A=/mnt/fd0 C=/dos D=/usr/windows -E=/home/bob/Wine/work +E=/home/bob/wine/work F=/home/bob/test [wine] @@ -11,7 +11,6 @@ System=c:\windows\system Temp=c:\temp Path=c:\windows;c:\windows\system;e:\;e:\test;f:\ SystemResources=sysres.dll -; SystemResources= [serialports] Com1=/dev/cua0 @@ -21,12 +20,14 @@ Com2=/dev/cua1 Lpt1=/dev/lp0 [spy] -;;;;; Uncomment the following line to activate spying to the console ;;;;; -File=CON +;;;;; Uncomment the following line to activate spying to the console ;;;;; +;File=CON -;;;;; Uncomment the following line to activate spying to the spy.log ;;;;; +;;;;; Uncomment the following line to activate spying to the spy.log ;;;;; ;File=spy.log -;;;;; The following options are not supported yet ;;;;; -;Include= -;Exclude= +;;;;; List of ; separated (and terminated) msg names to exclude from log ;;;;; +Exclude=WM_TIMER;WM_SETCURSOR;WM_MOUSEMOVE; + +;;;;; List of ; separated (and terminated) msg names to include in log ;;;;; +;Include=WM_COMMAND;