Release 940405 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()
diff --git a/BUGS b/BUGS index 1e43469..d005f85 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 5533bfc..c69135a 100644 --- a/ChangeLog +++ b/ChangeLog
@@ -1,4 +1,453 @@ ---------------------------------------------------------------------- +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) * [Configure] [*/Imakefile]
diff --git a/Configure b/Configure index c6bf097..15c7c31 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 @@ 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 3321aa9..da8a598 100644 --- a/DEVELOPERS-HINTS +++ b/DEVELOPERS-HINTS
@@ -12,8 +12,9 @@ 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 @@ 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 e0662aa..89039f0 100644 --- a/Imakefile +++ b/Imakefile
@@ -27,6 +27,7 @@ controls \ etc \ include \ + loader \ misc \ objects \ test \ @@ -36,7 +37,6 @@ tools \ debugger \ if1632 \ - loader \ memory \ miscemu @@ -47,6 +47,7 @@ COMMONOBJS = \ controls.o \ + loader.o \ misc.o \ objects.o \ windows.o @@ -58,7 +59,6 @@ EMUOBJS = \ if1632.o \ debugger.o \ - loader.o \ memory.o \ miscemu.o \ readline.o @@ -74,11 +74,13 @@ 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 c7ff6b4..abc84a9 100644 --- a/README +++ b/README
@@ -2,7 +2,9 @@ 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 @@ 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: <driveletter> = <rootdirectory> +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 = <directory> +default: c:\windows + +Used to specify an different windows directory. + +format: system = <directory> +default: c:\windows\system + +Used to specify an different system directory. + +format: temp = <directory> +default: c:\temp + +Used to specify a directory where windows applications can store temporary +files. + +format: path = <directories separated by semi-colons> +default: c:\windows;c:\windows\system + +Used to specify the path which will be used to find executables and DLL's. + +format: systemresources = <filename> +default: c:\temp + +Used to specify the name of sysres.dll, a dll which is used by wine itself. + +* [serialports] + +format: com[12345678] = <devicename> +default: none + +Used to specify the devices which are used as com1 - com8. + +* [parallelports] + +format: lpt[12345678] = <devicename> +default: none + +Used to specify the devices which are used as lpt1 - lpt8. + +* [spy] + +format: file = <filename or CON when logging to stdout> +default: none + +used to specify the file which will be used as logfile. + +format: exclude = <message names separated by semicolons> +default: none + +Used to specify which messages will be excluded from the logfile. + +format: include = <message names separated by semicolons> +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 @@ 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 @@ 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 7740d32..13a84cc 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 7ecd9db..f58057b 100644 --- a/controls/button.c +++ b/controls/button.c
@@ -963,7 +963,10 @@ 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 61b5e20..ae18601 100644 --- a/controls/combo.c +++ b/controls/combo.c
@@ -11,13 +11,16 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> + #include "windows.h" #include "combo.h" #include "heap.h" #include "win.h" -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> +#include "prototypes.h" HBITMAP hComboBit = 0; @@ -45,275 +48,290 @@ 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 14bf3c5..183b2a2 100644 --- a/controls/desktop.c +++ b/controls/desktop.c
@@ -6,16 +6,108 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; -#include "windows.h" +#include <stdio.h> +#include <string.h> +#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 76a3ecd..a20eea9 100644 --- a/controls/listbox.c +++ b/controls/listbox.c
@@ -12,17 +12,17 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include <stdio.h> +#include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> -#include <dirent.h> #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 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 @@ */ 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 @@ 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 @@ 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 @@ } +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 @@ 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 @@ 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 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 @@ 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 @@ } } } - +#ifdef DEBUG_LISTBOX + printf("End of ListBoxDirectory !\n"); +#endif return wRet; }
diff --git a/controls/menu.c b/controls/menu.c index 53d9f0d..9ab0366 100644 --- a/controls/menu.c +++ b/controls/menu.c
@@ -6,35 +6,44 @@ /* #define DEBUG_MENU -#define DEBUG_SYSMENU */ +#include <stdlib.h> +#include <stdio.h> #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 @@ */ 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 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 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 @@ 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 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 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 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 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 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 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 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 @@ 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 @@ */ 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 @@ 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 @@ */ 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 @@ 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 @@ */ 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 @@ */ 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 @@ */ 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 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 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 @@ */ 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 @@ */ 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 @@ */ 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 @@ */ 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 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 @@ 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 2894b21..1d05ee3 100644 --- a/controls/scroll.c +++ b/controls/scroll.c
@@ -10,14 +10,16 @@ */ static char Copyright[] = "Copyright Martin Ayotte, 1993"; +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> #include "windows.h" #include "sysmetrics.h" #include "scroll.h" #include "heap.h" #include "win.h" -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> +#include "prototypes.h" HBITMAP hUpArrow = 0; HBITMAP hDnArrow = 0; @@ -142,174 +144,212 @@ 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 @@ } + void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs) { HWND hWndParent; @@ -385,19 +426,15 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ 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 @@ 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 655d2fe..a78fd77 100644 --- a/controls/static.c +++ b/controls/static.c
@@ -7,6 +7,7 @@ static char Copyright[] = "Copyright David W. Metcalfe, 1993"; +#include <stdio.h> #include <windows.h> #include "win.h" #include "user.h"
diff --git a/controls/widgets.c b/controls/widgets.c index 1ad506d..c56daba 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 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 @@ 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 @@ * * 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 6803aaa..deee54f 100644 --- a/if1632/Imakefile +++ b/if1632/Imakefile
@@ -8,15 +8,25 @@ 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(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 5b49777..420d7bb 100644 --- a/if1632/call.S +++ b/if1632/call.S
@@ -105,7 +105,7 @@ 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 144e0df..b1a46fb 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec
@@ -126,6 +126,8 @@ 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 @@ 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 @@ 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 a3f9dd2..4472289 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec
@@ -6,16 +6,16 @@ 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 @@ 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 92d5622..2189855 100644 --- a/if1632/relay.c +++ b/if1632/relay.c
@@ -3,6 +3,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -14,6 +15,7 @@ #include <linux/segment.h> #endif #include <errno.h> + #include "neexe.h" #include "segmem.h" #include "prototypes.h" @@ -22,7 +24,7 @@ #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 @@ { "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 @@ 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 @@ /* * Determine address of arguments. */ + saved_Stack16Frame = Stack16Frame; Stack16Frame = (unsigned short *) seg_off; arg_ptr = (void *) (seg_off + 0x18); @@ -138,7 +143,11 @@ * 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 @@ } #endif + Stack16Frame = saved_Stack16Frame; return ret_val; }
diff --git a/if1632/stress.spec b/if1632/stress.spec new file mode 100644 index 0000000..8c93cb7 --- /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 d6f213a..d79948c 100644 --- a/if1632/user.spec +++ b/if1632/user.spec
@@ -152,7 +152,7 @@ 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 @@ 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 @@ 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 @@ 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 50e8255..c929a3e 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 c6234f4..9182769 100644 --- a/include/atom.h +++ b/include/atom.h
@@ -9,7 +9,6 @@ #include "windows.h" - typedef struct { HANDLE next; @@ -27,7 +26,10 @@ #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 0000000..9addd88 --- /dev/null +++ b/include/bitmap.h
@@ -0,0 +1,22 @@ +/* + * GDI bitmap definitions + * + * Copyright 1993 Alexandre Julliard + */ + +#ifndef BITMAP_H +#define BITMAP_H + +#include <X11/Xlib.h> +#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 0000000..38b7868 --- /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 f82ae94..19a2dfb 100644 --- a/include/dlls.h +++ b/include/dlls.h
@@ -63,5 +63,6 @@ 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 c1a5671..3ec95ea 100644 --- a/include/gdi.h +++ b/include/gdi.h
@@ -69,10 +69,9 @@ 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 @@ short breakExtra; /* breakTotalExtra / breakCount */ short breakRem; /* breakTotalExtra % breakCount */ - BYTE planes; BYTE bitsPerPixel; WORD MapMode; @@ -179,6 +177,8 @@ int style; int pixel; int width; + char * dashes; + int dash_len; } X_PHYSPEN; /* X physical brush */ @@ -197,6 +197,13 @@ 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 @@ X_PHYSFONT font; X_PHYSPEN pen; X_PHYSBRUSH brush; + X_PHYSPALETTE pal; } X_DC_INFO; @@ -282,7 +290,7 @@ 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 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 2b3b157..94ba9c9 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 @@ 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 0000000..b6d179e --- /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 315ef2e..19a6644 100644 --- a/include/menu.h +++ b/include/menu.h
@@ -28,15 +28,17 @@ 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 @@ } 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 fc3054d..905d182 100644 --- a/include/message.h +++ b/include/message.h
@@ -48,9 +48,10 @@ 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 2d3d221..b06d56c 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 <dirent.h> +#include <windows.h> struct dosdirent { int inuse; @@ -11,20 +12,9 @@ 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 @@ #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 @@ #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 cf2700d..d31a0e3 100644 --- a/include/neexe.h +++ b/include/neexe.h
@@ -220,4 +220,7 @@ #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 e313305..ae38f73 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 d8a3195..a972176 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 <sys/types.h> #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 e31e9aa..96f2fef 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 0000000..190e675 --- /dev/null +++ b/include/stress.h
@@ -0,0 +1,30 @@ +#ifndef __STRESS_H +#define __STRESS_H + +#include <windows.h> + +#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 d702023..166a707 100644 --- a/include/user.h +++ b/include/user.h
@@ -25,7 +25,7 @@ #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 706deec..2631911 100644 --- a/include/win.h +++ b/include/win.h
@@ -67,8 +67,11 @@ 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 4bd0205..7986183 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 @@ 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 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 @@ #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 @@ #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 @@ F(HMENU,CreateMenu) F(BOOL,GetInputState) +F(BOOL,SetDeskPattern) F(LPSTR,GetDOSEnvironment) F(DWORD,GetMessagePos) F(LONG,GetMessageTime) @@ -2199,9 +2236,11 @@ 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,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,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,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(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,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,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,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(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 @@ 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 13eee61..28cda57 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 @@ #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 6b83e52..c36be06 100644 --- a/include/winsock.h +++ b/include/winsock.h
@@ -63,6 +63,7 @@ #endif #ifndef _SYS_SOCKET_H_ +#ifndef _sys_socket_h /* * Structure used by kernel to pass protocol * information in raw sockets. @@ -72,6 +73,7 @@ u_short sp_protocol; /* protocol */ }; #endif +#endif /* * Maximum queue length specifiable by listen.
diff --git a/loader/Imakefile b/loader/Imakefile index 7c9ddeb..df53854 100644 --- a/loader/Imakefile +++ b/loader/Imakefile
@@ -9,6 +9,7 @@ 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 42fee12..08e1962 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 @@ 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 8ac6b1e..96ca5e4 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 <stdio.h> #include <stdlib.h> #include <errno.h> - #include "prototypes.h" + #if defined(__NetBSD__) || defined(__FreeBSD__) #include <machine/segments.h> #endif @@ -84,3 +85,5 @@ } } } + +#endif /* ifndef WINELIB */
diff --git a/loader/ldtlib.c b/loader/ldtlib.c index d361040..c264979 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 @@ #endif } +#endif /* ifndef WINELIB */
diff --git a/loader/library.c b/loader/library.c index ebb91fe..39ea0bb 100644 --- a/loader/library.c +++ b/loader/library.c
@@ -1,5 +1,7 @@ +#ifndef WINELIB #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -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 @@ */ 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 @@ */ 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 @@ } +/********************************************************************** + * 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 80% rename from misc/resource.c rename to loader/resource.c index 680b61f1..4ff3c28 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 <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> + #include "arch.h" #include "prototypes.h" #include "windows.h" @@ -17,6 +17,8 @@ #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 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 @@ 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", @@ -242,6 +338,25 @@ 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. */ rtoff = (ResourceFileInfo->mz_header->ne_offset + @@ -311,9 +426,7 @@ 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 @@ 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 @@ 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 @@ 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 bea1886..834e252 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 <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> +#include <errno.h> + #ifdef __linux__ #include <linux/unistd.h> #include <linux/head.h> @@ -16,14 +20,16 @@ #endif #if defined(__NetBSD__) || defined(__FreeBSD__) #include <sys/mman.h> +#include <machine/segments.h> #endif -#include <errno.h> + #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 @@ #endif #if defined(__NetBSD__) || defined(__FreeBSD__) -#include <machine/segments.h> #define PAGE_SIZE getpagesize() #define MODIFY_LDT_CONTENTS_DATA 0 #define MODIFY_LDT_CONTENTS_STACK 1 @@ -214,8 +219,7 @@ * 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 @@ /********************************************************************** * AllocCStoDSAlias */ -AllocDStoCSAlias(unsigned int ds_selector) +WORD AllocDStoCSAlias(WORD ds_selector) { unsigned int cs_selector; @@ -396,7 +400,7 @@ /********************************************************************** * FreeSelector */ -unsigned int FreeSelector(unsigned int sel) +WORD FreeSelector(WORD sel) { SEGDESC *s; int sel_idx; @@ -694,10 +698,9 @@ /********************************************************************** * GetDOSEnvironment */ -void * -GetDOSEnvironment() +LPSTR GetDOSEnvironment(void) { - return EnvironmentSelector->base_addr; + return (LPSTR) EnvironmentSelector->base_addr; } /********************************************************************** @@ -916,3 +919,4 @@ return selectors; } +#endif /* ifndef WINELIB */
diff --git a/loader/signal.c b/loader/signal.c index be88b96..d788cc0 100644 --- a/loader/signal.c +++ b/loader/signal.c
@@ -1,6 +1,8 @@ -#include <signal.h> +#ifndef WINELIB #include <stdio.h> #include <stdlib.h> +#include <signal.h> +#include <errno.h> #include <time.h> #if defined(__NetBSD__) || defined(__FreeBSD__) @@ -8,14 +10,14 @@ #else #include <syscall.h> #endif -#include <signal.h> -#include <errno.h> #ifdef linux #include <linux/sched.h> #include <asm/system.h> #endif + #include "wine.h" #include "segmem.h" +#include "prototypes.h" char * cstack[4096]; struct sigaction segv_act; @@ -40,92 +42,145 @@ } #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 <XX> */ + 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 @@ #endif } +#endif /* ifndef WINELIB */
diff --git a/loader/wine.c b/loader/wine.c index 26936da..4edecaa 100644 --- a/loader/wine.c +++ b/loader/wine.c
@@ -49,7 +49,6 @@ static char *DLL_Extensions[] = { "dll", "exe", NULL }; static char *EXE_Extensions[] = { "exe", NULL }; -static char *WinePath = NULL; FILE *SpyFp = NULL; @@ -137,7 +136,7 @@ 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 @@ wpnt1->next = wpnt; }; wpnt->next = NULL; + wpnt->resnamtab = (RESNAMTAB *) -1; /* * Open file for reading. @@ -248,8 +248,6 @@ */ for(i=0; i<wpnt->ne_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 @@ } +#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 @@ } } } +#endif /********************************************************************** @@ -402,10 +390,8 @@ 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 @@ 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 @@ 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 76b558f..11ab363 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 <stdio.h> #include <stdlib.h> +#include <string.h> #include "prototypes.h" #include "heap.h" #include "segmem.h" @@ -153,7 +156,7 @@ /********************************************************************** * GlobalAlloc */ -unsigned int +HANDLE GlobalAlloc(unsigned int flags, unsigned long size) { GDESC *g; @@ -258,7 +261,7 @@ * 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 @@ /* * 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 @@ /* * 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 @@ 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 18f50a4..71cb561 100644 --- a/memory/heap.c +++ b/memory/heap.c
@@ -3,17 +3,13 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #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 @@ 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 @@ return NULL; } -#define LOCALHEAP() (&HEAP_LocalFindHeap(Segments[Stack16Frame[11] >> 3].owner)->free_list) - /********************************************************************** * HEAP_LocalInit */ @@ -316,43 +313,47 @@ 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 @@ } /********************************************************************** - * LocalFlags + * WIN16_LocalFlags */ unsigned int -LocalFlags(unsigned int handle) +WIN16_LocalFlags(unsigned int handle) { MDESC *m; @@ -382,10 +383,10 @@ } /********************************************************************** - * LocalFree + * WIN16_LocalFree */ unsigned int -LocalFree(unsigned int handle) +WIN16_LocalFree(unsigned int handle) { unsigned int addr; @@ -397,12 +398,12 @@ } /********************************************************************** - * 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 @@ } /********************************************************************** - * LocalLock + * WIN16_LocalLock */ void * -LocalLock(unsigned int handle) +WIN16_LocalLock(unsigned int handle) { MDESC *m; @@ -443,10 +444,10 @@ } /********************************************************************** - * 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 @@ } /********************************************************************** - * LocalSize + * WIN16_LocalSize */ unsigned int -LocalSize(unsigned int handle) +WIN16_LocalSize(unsigned int handle) { MDESC *m; @@ -474,10 +475,10 @@ } /********************************************************************** - * LocalUnlock + * WIN16_LocalUnlock */ unsigned int -LocalUnlock(unsigned int handle) +WIN16_LocalUnlock(unsigned int handle) { MDESC *m; @@ -491,3 +492,49 @@ return 0; } + +/********************************************************************** + * GetFreeSystemResources (user.284) + + */ +#define USERRESOURCES 2 +#define GDIRESOURCES 1 +#define SYSTEMRESOURCES 0 +#include <user.h> +#include <gdi.h> + +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 af403e2..1bceeaa 100644 --- a/memory/linear.c +++ b/memory/linear.c
@@ -3,6 +3,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "prototypes.h" #include "heap.h" #include "segmem.h"
diff --git a/misc/Imakefile b/misc/Imakefile index 43ee484..2979b52 100644 --- a/misc/Imakefile +++ b/misc/Imakefile
@@ -16,9 +16,9 @@ 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 79db3b9..f8f7d07 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 <ctype.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> +#include <ctype.h> #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 @@ { 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 @@ */ 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 @@ } 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 @@ 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 @@ */ BOOL InitAtomTable( WORD entries ) { - return ATOM_InitTable( &localTable, entries ); + return ATOM_InitTable( LOCALATOMTABLE(), entries ); } @@ -265,8 +301,8 @@ */ 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 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 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 @@ */ 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 f62d083..17cca79 100644 --- a/misc/clipboard.c +++ b/misc/clipboard.c
@@ -10,6 +10,8 @@ #define DEBUG_CLIPBOARD */ +#include <stdlib.h> +#include <stdio.h> #include <windows.h> #include <sys/types.h> #include <sys/stat.h>
diff --git a/misc/comm.c b/misc/comm.c index 84cc620..0a51b77 100644 --- a/misc/comm.c +++ b/misc/comm.c
@@ -8,11 +8,14 @@ #include <fcntl.h> #include <string.h> #include <errno.h> +#include <ctype.h> #include <sys/stat.h> #if defined(__NetBSD__) || defined(__FreeBSD__) #include <errno.h> #include <sys/ioctl.h> #endif +#include <unistd.h> + #include "wine.h" #include "windows.h" @@ -38,7 +41,7 @@ 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 @@ /* 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 @@ int CloseComm(int fd) { - int status; - #ifdef DEBUG_COMM fprintf(stderr,"CloseComm: fd %d\n", fd); #endif @@ -477,7 +478,7 @@ 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 @@ 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 @@ 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 @@ 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 931d538..fa2d0ec 100644 --- a/misc/cursor.c +++ b/misc/cursor.c
@@ -7,14 +7,15 @@ #define DEBUG_CURSOR */ -#include <X11/cursorfont.h> -#include <X11/Xlib.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> +#include <X11/cursorfont.h> +#include <X11/Xlib.h> #include "prototypes.h" #include "windows.h" #include "win.h" @@ -28,6 +29,7 @@ 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 @@ 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 @@ */ 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 @@ 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 cc220c4..9c9e9ef 100644 --- a/misc/dos_fs.c +++ b/misc/dos_fs.c
@@ -10,6 +10,11 @@ #include <stdlib.h> #include <string.h> #include <sys/stat.h> +#include <pwd.h> +#include <dirent.h> +#include <unistd.h> +#include <fcntl.h> + #if defined(__linux__) || defined(sun) #include <sys/vfs.h> #endif @@ -17,27 +22,23 @@ #include <sys/types.h> #include <sys/mount.h> #endif -#include <dirent.h> -#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 @@ 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 @@ 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 @@ 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 @@ #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 @@ 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 @@ 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 @@ *(cwdptr+1) = '\0'; goto next; } - } goto next; } @@ -330,13 +352,12 @@ */ } -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 @@ } 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 @@ 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 @@ #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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ */ 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 @@ #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 @@ 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 @@ 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 a41a95c..f6730c6 100644 --- a/misc/exec.c +++ b/misc/exec.c
@@ -3,6 +3,10 @@ * */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> #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 de8a7e2..5d41f1c 100644 --- a/misc/file.c +++ b/misc/file.c
@@ -19,16 +19,16 @@ #define DEBUG_FILE -#include <windows.h> #include <stdio.h> #include <fcntl.h> #include <limits.h> #include <unistd.h> +#include <time.h> +#include <windows.h> #include "prototypes.h" char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256]; - /*************************************************************************** _lopen @@ -40,12 +40,12 @@ 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 @@ #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 @@ #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 @@ 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 @@ #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 @@ fprintf(stderr,"GetWindowsDirectory (%s)\n",lpszSysPath); #endif + ChopOffSlash(lpszSysPath); return(strlen(lpszSysPath)); } /*************************************************************************** @@ -270,6 +273,7 @@ fprintf(stderr,"GetSystemDirectory (%s)\n",lpszSysPath); #endif + ChopOffSlash(lpszSysPath); return(strlen(lpszSysPath)); } /*************************************************************************** @@ -288,7 +292,7 @@ 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 @@ { 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 cc4b017..178a74f 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 <stdlib.h> +#include <stdio.h> #include "prototypes.h" #include "windows.h"
diff --git a/misc/lstr.c b/misc/lstr.c index bd30f88..cec2748 100644 --- a/misc/lstr.c +++ b/misc/lstr.c
@@ -6,6 +6,7 @@ #include <ctype.h> #include <sys/types.h> #include <fcntl.h> +#include <unistd.h> #include "prototypes.h" #include "regfunc.h"
diff --git a/misc/main.c b/misc/main.c index 59bd197..c98b723 100644 --- a/misc/main.c +++ b/misc/main.c
@@ -7,24 +7,36 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <X11/Xlib.h> #include <X11/Xresource.h> - +#include <X11/Xutil.h> +#include <X11/cursorfont.h> +#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 @@ 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,38 +59,104 @@ #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 * * Parse command line options and open display. */ 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 @@ 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 @@ 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 @@ /*********************************************************************** * MessageBeep (USER.104) */ -void MessageBeep( WORD i ) +void MessageBeep(WORD i) { XBell(display, 100); } @@ -155,7 +343,7 @@ */ 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 @@ */ 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 @@ break; case SPI_GETBORDER: - *(int *) lpvParam = 1; + *(INT *) lpvParam = 1; break; case SPI_GETFASTTASKSWITCH: @@ -203,7 +394,7 @@ break; case SPI_GETGRIDGRANULARITY: - *(int *) lpvParam = 1; + *(INT *) lpvParam = 1; break; case SPI_GETICONTITLEWRAP: @@ -211,7 +402,7 @@ break; case SPI_GETKEYBOARDDELAY: - *(int *) lpvParam = 1; + *(INT *) lpvParam = 1; break; case SPI_GETKEYBOARDSPEED: @@ -223,25 +414,26 @@ 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 @@ 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 @@ 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 79a49f7..57428e7 100644 --- a/misc/message.c +++ b/misc/message.c
@@ -8,6 +8,9 @@ #define DEBUG_MSGBOX +#include <stdlib.h> +#include <stdio.h> +#include <string.h> #include <windows.h> #include <sys/types.h> #include <sys/stat.h> @@ -43,53 +46,55 @@ 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 @@ 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 @@ #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 f150c9c..377924a 100644 --- a/misc/profile.c +++ b/misc/profile.c
@@ -14,9 +14,12 @@ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include "windows.h" + #include "wine.h" +#include "windows.h" +#include "prototypes.h" /* #define DEBUG */ @@ -121,12 +124,18 @@ } 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 @@ 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 cbb2281..b5c0fc5 100644 --- a/misc/rect.c +++ b/misc/rect.c
@@ -150,6 +150,12 @@ 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 @@ } 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 90e9c7d..c976a97 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 <stdlib.h> +#include <stdio.h> #include "prototypes.h" int OpenSound(void)
diff --git a/misc/spy.c b/misc/spy.c index 86e5791..bfc0042 100644 --- a/misc/spy.c +++ b/misc/spy.c
@@ -7,6 +7,7 @@ #include <stdio.h> #include <X11/Xlib.h> #include <X11/Xresource.h> +#include <string.h> #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 @@ "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 @@ "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 @@ "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 @@ 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 @@ { char filename[100]; - if (SpyFp == NULL) + if (SpyFp != NULL) return; if (Options.spyFilename == NULL) @@ -261,5 +287,13 @@ 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 0000000..2b748b7 --- /dev/null +++ b/misc/stress.c
@@ -0,0 +1,109 @@ +#include <stdio.h> +#include <limits.h> +#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 51b94af..ed0045b 100644 --- a/misc/user.c +++ b/misc/user.c
@@ -17,6 +17,7 @@ extern BOOL ATOM_Init(); extern BOOL GDI_Init(); extern void SYSMETRICS_Init(); +extern BOOL WIN_CreateDesktopWindow(); #ifndef WINELIB /*********************************************************************** @@ -44,6 +45,11 @@ 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 @@ SYSMETRICS_Init(); SYSCOLOR_Init(); -#ifndef WINELIB - /* Create USER heap */ - if (!USER_HeapInit()) return 0; -#endif - /* Create the DCEs */ DCE_Init(); @@ -76,10 +77,15 @@ 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 d5483f9..0d520db 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 <netdb.h> #include <stdio.h> +#include <string.h> #include <sys/types.h> #include <sys/socket.h> -#if defined(__FreeBSD__) #include <netinet/in.h> -#endif #include <arpa/inet.h> #include <errno.h> #include <netdb.h> +#include <unistd.h> #include "winsock.h" #define DEBUG_WINSOCK @@ -47,12 +48,12 @@ 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 dca1f1d..c9c9db8 100644 --- a/miscemu/Imakefile +++ b/miscemu/Imakefile
@@ -4,8 +4,12 @@ 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 c53aaa9..b43f9f3 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 <stdlib.h> +#include <stdio.h> #include "prototypes.h" #include "regfunc.h" @@ -13,9 +15,6 @@ unsigned short Unused; }; - - - int WIN87_fpmath() { @@ -49,5 +48,3 @@ { printf( "__WinEm87Save(%p,%d)\n",pWin87EmSaveArea,cbWin87EmSaveArea); } - -
diff --git a/miscemu/int10.c b/miscemu/int10.c new file mode 100644 index 0000000..0f932bd --- /dev/null +++ b/miscemu/int10.c
@@ -0,0 +1,36 @@ +#include <stdio.h> +#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 addfdbc..0d25a77 100644 --- a/miscemu/int1a.c +++ b/miscemu/int1a.c
@@ -1,5 +1,6 @@ #include <time.h> #include <stdio.h> +#include "msdos.h" #include "wine.h" #ifdef linux
diff --git a/miscemu/int21.c b/miscemu/int21.c index 47368e1..350f9e0 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c
@@ -1,13 +1,10 @@ #include <time.h> #include <fcntl.h> #include <errno.h> -#ifndef __STDC__ -#include <malloc.h> -#endif #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/stat.h> -#include <time.h> #include <unistd.h> #include <utime.h> @@ -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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ return; } - ptr = (char *) pointer (DS,DX); + ptr = pointer (DS,DX); if (BX == 0) { *ptr = EOF; @@ -182,12 +235,12 @@ } } -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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ ResetCflag; } -void CloseFile(struct sigcontext_struct *context) +static void CloseFile(struct sigcontext_struct *context) { if (close(BX) == -1) { switch (errno) { @@ -463,34 +567,35 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 0000000..f08c7a9 --- /dev/null +++ b/miscemu/int25.c
@@ -0,0 +1,30 @@ +#include <stdio.h> +#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 0000000..c4f8464 --- /dev/null +++ b/miscemu/int26.c
@@ -0,0 +1,28 @@ +#include <stdio.h> +#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 0000000..44fa971 --- /dev/null +++ b/miscemu/ioports.c
@@ -0,0 +1,60 @@ +#include <stdio.h> +#include <time.h> +#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 458761d..bce8061 100644 --- a/objects/Imakefile +++ b/objects/Imakefile
@@ -16,7 +16,8 @@ clipping.c \ bitblt.c \ linedda.c \ - color.c + color.c \ + dither.c OBJS = \ bitmap.o \ @@ -32,7 +33,8 @@ 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 bbfa3bd..992f7ca 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c
@@ -314,7 +314,7 @@ 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 ffec3e9..6c21e0c 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c
@@ -6,22 +6,18 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> #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 @@ */ 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 ); @@ -58,26 +52,13 @@ /*********************************************************************** - * 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), @@ -93,57 +74,6 @@ /*********************************************************************** - * 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) */ HBITMAP CreateBitmap( short width, short height, @@ -154,9 +84,6 @@ 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 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 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 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 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 @@ */ 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 @@ /*********************************************************************** * 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 582349e..9464184 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 @@ { 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 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 ); } @@ -172,32 +173,46 @@ /*********************************************************************** + * 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 @@ 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 @@ return prevHandle; } - -
diff --git a/objects/color.c b/objects/color.c index 8eb9c2e..41f3ae6 100644 --- a/objects/color.c +++ b/objects/color.c
@@ -11,55 +11,46 @@ #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 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 @@ 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 @@ 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 73c98aa..12b775f 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c
@@ -40,7 +40,6 @@ 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 15e3d09..c6d9d44 100644 --- a/objects/dib.c +++ b/objects/dib.c
@@ -8,13 +8,13 @@ #include <stdio.h> #include <stdlib.h> - +#include <X11/Xlib.h> +#include <X11/Xutil.h> #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 @@ * * 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; @@ -57,70 +58,251 @@ /*********************************************************************** + * 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) */ 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 @@ 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 @@ 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 @@ 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 @@ 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 0000000..5210106 --- /dev/null +++ b/objects/dither.c
@@ -0,0 +1,140 @@ +/* + * Dithering functions + * + * Copyright 1994 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1994"; + +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#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 883e699..382976b 100644 --- a/objects/font.c +++ b/objects/font.c
@@ -8,6 +8,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <X11/Xatom.h> #include "gdi.h" @@ -17,7 +18,7 @@ * * 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 @@ 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 @@ /* 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 bc59d86..cd78887 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c
@@ -6,11 +6,14 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <stdio.h> #include "gdi.h" - +#include "prototypes.h" MDESC *GDI_Heap = NULL; +extern HPALETTE COLOR_Init(); /* color.c */ /*********************************************************************** * GDI stock objects @@ -130,12 +133,10 @@ (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 @@ */ BOOL GDI_Init() { + HPALETTE hpalette; struct segment_descriptor_s * s; #ifndef WINELIB @@ -156,9 +158,8 @@ /* 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 @@ if (!REGION_Init()) return FALSE; + /* Initialise dithering */ + + if (!DITHER_Init()) return FALSE; + return TRUE; } @@ -217,7 +222,6 @@ 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 03300c4..dc52635 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 <stdlib.h> +#include <string.h> +#include <limits.h> +/* #ifdef linux #include <values.h> #endif +*/ + #if !defined (MAXINT) #include <limits.h> #define MAXINT INT_MAX #endif #include <X11/Xlib.h> - #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) @@ -117,6 +87,33 @@ /*********************************************************************** + * 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) */ WORD GetNearestPaletteIndex( HPALETTE hpalette, COLORREF color ) @@ -143,7 +140,8 @@ 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) { @@ -178,18 +176,51 @@ /*********************************************************************** + * 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 a0a7ad7..48da252 100644 --- a/objects/pen.c +++ b/objects/pen.c
@@ -8,6 +8,7 @@ #include "gdi.h" +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); /*********************************************************************** * CreatePen (GDI.61) @@ -68,21 +69,24 @@ / 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 3a7b9ef..afe4dd4 100644 --- a/objects/region.c +++ b/objects/region.c
@@ -8,13 +8,13 @@ #include <stdlib.h> #include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> #include "gdi.h" - /* GC used for region operations */ static GC regionGC = 0; - /*********************************************************************** * REGION_Init */ @@ -23,8 +23,7 @@ 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 @@ /* 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 @@ 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 787b0f7..a900baa 100644 --- a/objects/text.c +++ b/objects/text.c
@@ -221,7 +221,6 @@ (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 0000000..6dc03d5 --- /dev/null +++ b/test/blandmdi.exe Binary files differ
diff --git a/test/btnlook.exe b/test/btnlook.exe deleted file mode 100755 index d952b61..0000000 --- a/test/btnlook.exe +++ /dev/null Binary files differ
diff --git a/test/hw.exe b/test/hw.exe deleted file mode 100755 index 0567dc3..0000000 --- a/test/hw.exe +++ /dev/null Binary files differ
diff --git a/test/hyperoid.exe b/test/hyperoid.exe deleted file mode 100644 index 4e689f0..0000000 --- a/test/hyperoid.exe +++ /dev/null Binary files differ
diff --git a/test/menutest.exe b/test/menutest.exe deleted file mode 100755 index ad4f791..0000000 --- a/test/menutest.exe +++ /dev/null Binary files differ
diff --git a/test/winetest2.exe b/test/winetest2.exe deleted file mode 100755 index 57d7edc..0000000 --- a/test/winetest2.exe +++ /dev/null Binary files differ
diff --git a/toolkit/Imakefile b/toolkit/Imakefile index 53a7da3..5ddccc8 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 0000000..9f9c6c7 --- /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 7b739a1..c993ef4 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 0000000..647594f --- /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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#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 <stdio.h>\n"); + fprintf(fp, "#include <stdlib.h>\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 947968a..9689eff 100644 --- a/windows/Imakefile +++ b/windows/Imakefile
@@ -15,6 +15,7 @@ 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 fbec0a1..68277c6 100644 --- a/windows/class.c +++ b/windows/class.c
@@ -6,11 +6,16 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <stdio.h> +#include <string.h> #include "class.h" #include "user.h" #include "win.h" #include "dce.h" +/* #define DEBUG_CLASS /* */ + static HCLASS firstClass = 0; @@ -88,8 +93,9 @@ 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 @@ 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 @@ */ 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 @@ 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 4224b3a..58dd531 100644 --- a/windows/dc.c +++ b/windows/dc.c
@@ -7,16 +7,17 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include <stdlib.h> - +#include <string.h> #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 @@ { 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 @@ 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 @@ */ 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 @@ * 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_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_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 @@ 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 @@ 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 @@ #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,22 +355,31 @@ 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) */ HDC CreateCompatibleDC( HDC hdc ) @@ -359,20 +399,17 @@ 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 @@ 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 @@ 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 @@ 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 6df7ccd..3dfe56e 100644 --- a/windows/dce.c +++ b/windows/dce.c
@@ -193,7 +193,7 @@ 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 a495d08..5163a20 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c
@@ -6,7 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; - +#include <stdlib.h> +#include <stdio.h> #include "windows.h" #include "win.h" #include "class.h" @@ -21,6 +22,7 @@ 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 @@ */ 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 @@ 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 9f0b64a..35dc9f0 100644 --- a/windows/dialog.c +++ b/windows/dialog.c
@@ -6,6 +6,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <stdio.h> +#include <string.h> #include "windows.h" #include "dialog.h" #include "win.h"
diff --git a/windows/event.c b/windows/event.c index 87c0229..887d025 100644 --- a/windows/event.c +++ b/windows/event.c
@@ -6,6 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <stdio.h> #include <X11/Xlib.h> #include <X11/Xresource.h> #include <X11/Xutil.h> @@ -21,7 +23,7 @@ #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 @@ 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 @@ /* 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 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #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 @@ #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 @@ /*********************************************************************** * 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 @@ */ 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 a3ac280..8850af0 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 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 b37da40..fb3e580 100644 --- a/windows/graphics.c +++ b/windows/graphics.c
@@ -17,6 +17,8 @@ #include "gdi.h" +extern int COLOR_ToPhysical( DC *dc, COLORREF color ); + /*********************************************************************** * LineTo (GDI.19) */ @@ -351,7 +353,7 @@ 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 e3afb20..3738a41 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c
@@ -8,10 +8,21 @@ #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 0000000..1912295 --- /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 <stdlib.h> +#include <stdio.h> +#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 910f7a4..62fd981 100644 --- a/windows/message.c +++ b/windows/message.c
@@ -22,10 +22,13 @@ #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 @@ 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 @@ * 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" ); } @@ -481,13 +520,31 @@ /*********************************************************************** + * 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 */ 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 @@ /* 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 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 @@ 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 5456b08..9a7f85f 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c
@@ -522,7 +522,7 @@ * 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 @@ */ 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 @@ 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 @@ 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_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 @@ #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 @@ 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 0090d91..36c72e7 100644 --- a/windows/painting.c +++ b/windows/painting.c
@@ -25,8 +25,10 @@ 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 @@ 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 a3ca9ac..80b69d5 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 <stdlib.h> -#include <X11/Xlib.h> #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 bea4561..71413c7 100644 --- a/windows/sysmetrics.c +++ b/windows/sysmetrics.c
@@ -14,6 +14,7 @@ short sysMetrics[SM_CMETRICS]; extern Display * display; +extern int screenWidth, screenHeight; /*********************************************************************** * SYSMETRICS_Init @@ -22,8 +23,8 @@ */ 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 2a40bec..641bbe0 100644 --- a/windows/timer.c +++ b/windows/timer.c
@@ -28,6 +28,10 @@ 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 @@ 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 @@ /*********************************************************************** - * 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 45157f9..cfc8e85 100644 --- a/windows/win.c +++ b/windows/win.c
@@ -6,6 +6,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <stdio.h> #include <string.h> #include "class.h" @@ -19,7 +21,11 @@ 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 @@ 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 @@ * 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 @@ * * 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ */ 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 @@ } +/******************************************************************* + * 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 @@ } - -/******************************************************************* - * 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 ee37ecb..0534bc8 100644 --- a/windows/winpos.c +++ b/windows/winpos.c
@@ -9,8 +9,7 @@ #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 @@ */ 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 @@ if (PtInRect( &rect, pt )) return hwnd; hwnd = GetWindow( hwnd, GW_HWNDNEXT ); } - return 0; + return hwndParent; } @@ -168,7 +184,6 @@ return hwndActive; } - /******************************************************************* * SetActiveWindow (USER.59) */ @@ -461,6 +476,20 @@ 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 @@ 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 @@ { 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 d8755c4..b2c79af 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 @@ 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 @@ 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;