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;