From 5f721f81fd9afd332ec5bba762a7010663b427af Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Tue, 4 Jan 1994 20:14:34 +0000 Subject: [PATCH] Release 0.5 Sun Jan 2 12:38:53 1994 David Metcalfe <david@prism.demon.co.uk> * [windows/class.c] Implemented GetClassName and GetClassInfo. * [windows/caret.c] Various improvements to text caret code. Fri Dec 31 15:22:22 1993 John Brezak <brezak@apollo.hp.com> * [misc/comm.c] Patches to work with NetBSD. Thu Dec 30 12:11:55 1993 John Richardson <jrichard@cs.uml.edu> * [objects/bitblt.c] Added StretchBlt(). Tue Jan 4 05:22:07 1994 julliard@di.epfl.ch (Alexandre Julliard) * [misc/user.c] Added creation of system message queue. * [objects/bitmap.c] [objects/dcvalues.c] [windows/dc.c] Added DC size fields into DC structure. * [objects/clipping.c] Bug fix in CLIPPING_IntersectRect(). * [windows/class.c] Allocate a DCE instead of a DC for CS_CLASSDC classes. * [windows/clipping.c] Fixed GetUpdateRect() and GetUpdateRgn() to clip to the client area. * [windows/dce.c] Implemented GetDCEx() and GetWindowDC(). * [windows/defwnd.c] Implemented WM_WINDOWPOSCHANGED handling. * [windows/event.c] Preliminary support for Xlib event handling instead of Xt callbacks. Changed MSG_AddMsg() calls to hardware_event() or PostMessage(). * [windows/message.c] Preliminary support for multiple message queues. Implemented hardware_event() to store messages into the system queue. Implemented Get/SetTaskQueue(). Better WM_PAINT and WM_TIMER handling. Changes to use Xlib instead of Xt for events. * [windows/painting.c] Use GetDCEx() to retrieve the DC, to get a correct visible region. * [windows/timer.c] Moved the timer procedure callback into DispatchMessage(). Changed implementation to get rid of Xt timeouts. Timer checking is now done inside GetMessage(). * [windows/win.c] Allocate a DCE instead of a DC for CS_OWNDC windows. Replaced Xt calls with Xlib calls. Moved window positioning functions into windows/winpos.c * [windows/winpos.c] (New file) Rewritten most of the window positioning functions. Implemented SetWindowPos() and MapWindowPoints(). Jan 3, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [if1632/user.spec] Bad arguments description for function SetDlgItemText. * [objects/text.c] Function DrawText now handle DT_CALCRECT request. * [misc/message.c] Message boxes now use DrawText with DT_CALCRECT. * [windows/graphics.c] Bug fix in function FrameRect, (it was using PEN instead of BRUSH). * [windows/win.c] Bug fix for flags in function ShowWindow. More accurate WM_SIZE generated by function ShowWindow. * [controls/listbox.c] More code for LBS_MULTIPLESEL. More code for LBS_MULTICOLUMN. * [include/windows.h] Bad define for MF_SEPARATOR. * [controls/menu.c] New functions: PopMenuWndProc() with 'glues', CreatePopupMenu(), AppendMenu(), InsertMenu(), RemoveMenu(), DeleteMenu(), ModifyMenu(), TrackPopupMenu(). Code in stubs: CreateMenu(), DestroyMenu(). Sat Jan 1 10:22:43 1994 Bob Amstadt (bob@pooh) * loader/wine.c: Added support for relocation types 5 and 6. Mon Dec 27 11:06:03 1993 Erik Bos (erik@trashcan.hacktic.nl) * [misc/comm.c] new functions: BuildCommDCB(), OpenComm(), CloseComm(), SetCommBreak(), ClearCommBreak(), EscapeCommFunction(), FlushComm(), GetCommError(), SetCommEventMask(), GetCommEventMask(), SetCommState(), GetCommState(), TransmitCommChar(), ReadComm(), WriteComm(). Wed Dec 22 13:00:15 1993 David Metcalfe <david@prism.demon.co.uk> * [windows/caret.c] Implemented text caret functions. Tue Dec 21 06:13:58 1993 julliard@di.epfl.ch (Alexandre Julliard) * [loader/wine.c] Bug fix in LoadImage(). * [objects/bitblt.c] [objects/clipping.c] [objects/text.c] [windows/dc.c] [windows/dce.c] [windows/graphics.c] Modified graphics calls to take into account the DC origin. * [windows/defwnd.c] Added preliminary WM_NCCALCSIZE handling. * [windows/event.c] Send WM_NCCALCSIZE message on resize event. * [windows/win.c] Send WM_NCCALCSIZE message in CreateWindow(). Realize widgets at creation time (should prevent problems with unrealized widgets). Dec 19, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/static.c] Send mouse & keyboard message received to its parent. * [controls/scroll.c] Send keyboard message received to its parent. * [controls/listbox.c] Add Navigation keys . ListBox now use VSCROLL & HSCROLL instead of children. Alpha version of LBS_MULTIPLESEL. Alpha version of LBS_MULTICOLUMN. * [controls/combo.c] Add Navigation keys on closed ComboBox. Remove useless 'COMBOBOX_CreateComboBox' function. Mon Dec 19 20:39:34 1993 Erik Bos (erik@trashcan.hacktic.nl) * [loader/wine. LoadImage() modified to use FindFile(). * [misc/file.c] SetErrorMode added * [misc/dos_fs.c] bug fixes. Dec 13, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [memory/global.c] bug fix in GlobalGetFreeSegment : good ptr in 'g_prev'. * [sysres.dll] preliminary version of a 'glass of wine' bitmap * [windows/event.c] New function 'GetCapture'. * [controls/scroll.c] Remove useless 'SCROLLBAR_CreateScrollBar' function. * [controls/listbox.c] Remove useless 'LISTBOX_CreateListBox' function. Mon Dec 13 13:51:00 1993 David Metcalfe <david@prism.demon.co.uk> * [objects/font.c] Corrected bugs in GetCharWidth(). * [windows/event.c] Modified EVENT_key to send Windows virtual key codes for WM_KEYDOWN and WM_KEYUP messages, and a WM_CHAR message for printable characters. Wed Dec 08 19:20:00 1993 Karl Guenter Wuensch (hn324wu@unidui.uni-duisburg.de) * [windows/graphics.c] Added Polyline and Polygon Mon Dec 13 14:51:54 1993 Erik Bos (erik@trashcan.hacktic.nl) * [controls/listbox.c] ListBoxDirectory() modified to use dos_fs.c's functions to access files&|drives. Sat Dec 04 17:04:23 1993 Erik Bos (erik@trashcan.hacktic.nl) * [misc/dos_fs.c] Added FindFile() to search a file in a dos/unix style path. * [misc/file.c] New Win31 functions: OpenFile, _lcreate, _llseek, GetTempDrive, GetTempFileName, GetWindowsDirectory, GetSystemDirectory, GetDriveType. * [misc/int21.c] Modified. Wed Dec 1 16:20:45 1993 Miguel de Icaza (miguel@roxanne.nuclecu.unam.mx) * [misc/profile.c] The Profile functions now return the correct values. They now implement all the features described in the SDK. Tue Nov 30 13:55:27 1993 Bob Amstadt (bob at amscons) * [loader/selector.c] Rewrote selector aliasing routines to use System V IPC routine to alias memory segments. Nov 28, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [controls/listbox.c] More consistency in functions using wIndexes * [controls/scroll.c] New function : ShowScrollBar(). * [loader/cursor.c] ... New file Move cursor functions from [loader/resource.c]. New function : ClipCursor(). New function : GetClipCursor(). New function : CreateCursor(). SetCursor() now working using gloabal variable 'winHasCursor'. *[object/palette.c] New stub only : SelectPalette(). New stub only : RealizePalette(). *[win/event.c] New function : EVENT_enter_notify(), update 'winHasCursor' and send WM_SETCURSOR. *[win/defwnd.c] Add processing of WM_SETCURSOR message. *[win/win.c] New members in WND structure : hCursor, hWndVScroll & hWndHScroll. CreateWindowEx() now create children for WM_HSCROLL & WM_VSCROLL. New function ClientToScreen(). New function ScreenToClient(). Mon Nov 25 18:25:40 1993 Erik Bos (erik@trashcan.hacktic.nl) * [files.h / regfunc.h / misc/dos.c] Removed. * [misc/dos_fs.c] Added support for loading dosdrive cfg from wine.ini. * [misc/int21.c] Modified. Wed Nov 24 11:37:33 1993 julliard@disuns2.epfl.ch (Alexandre Julliard) * [include/atom.h] [memory/atom.c] Implemented atoms. * [windows/class.c] Modified RegisterClass() to use atoms. Implemented CS_GLOBALCLASS style. * [windows/message.c] Implemented RegisterWindowMessage(). * [loader/resource.c] Bug fix in LoadResource(). * [windows/dialog.c] Modified CreateDialogParam() to use Find/LoadResource(). --- ChangeLog | 293 +++++++++++- Imakefile | 66 +++ LICENSE | 1 + Makefile | 8 +- PROPOSED_LICENSE | 29 ++ README | 54 ++- WARRANTY | 7 + Wine.tmpl | 29 ++ bsdmake.patch | 2 +- controls/Imakefile | 37 ++ controls/combo.c | 108 +++-- controls/listbox.c | 637 ++++++++++++++++--------- controls/menu.c | 616 +++++++++++++++++++++++- controls/scroll.c | 151 +++--- controls/static.c | 12 + controls/widgets.c | 31 +- debugger/Imakefile | 62 +++ debugger/readline/Imakefile | 25 + etc/Imakefile | 11 + etc/Makefile | 358 ++++++++++++++ if1632/Imakefile | 37 ++ if1632/callback.c | 4 +- if1632/gdi.spec | 5 + if1632/kernel.spec | 10 + if1632/relay.c | 2 +- if1632/user.spec | 60 ++- include/Imakefile | 38 ++ include/Makefile | 360 ++++++++++++++ include/atom.h | 27 ++ include/class.h | 2 +- include/dce.h | 13 +- include/files.h | 17 - include/gdi.h | 5 +- include/int21.h | 40 +- include/listbox.h | 9 +- include/menu.h | 15 +- include/message.h | 17 +- include/neexe.h | 4 +- include/prototypes.h | 13 +- include/segmem.h | 21 +- include/user.h | 2 + include/win.h | 24 +- include/windows.h | 331 +++++++++++-- include/wine.h | 11 +- loader/Imakefile | 35 ++ loader/Makefile | 4 +- loader/cursor.c | 385 +++++++++++++++ loader/files.c | 109 ----- loader/library.c | 2 +- loader/resource.c | 178 +------ loader/selector.c | 269 ++++++++--- loader/signal.c | 12 +- loader/wine.c | 141 ++++-- memory/Imakefile | 21 + memory/Makefile | 2 +- memory/atom.c | 328 +++++++++++++ memory/global.c | 25 +- misc/Imakefile | 45 ++ misc/Makefile | 7 +- misc/comm.c | 872 ++++++++++++++++++++++++++++++++++ misc/dos.c | 76 --- misc/dos_fs.c | 756 +++++++++++++++++++++++++++++ misc/file.c | 289 ++++++++---- {loader => misc}/int1a.c | 2 +- {loader => misc}/int21.c | 917 ++++++++++++++++++------------------ misc/message.c | 70 ++- misc/profile.c | 55 ++- misc/user.c | 21 +- misc/xt.c | 17 +- objects/Imakefile | 43 ++ objects/bitblt.c | 99 +++- objects/bitmap.c | 3 + objects/clipping.c | 75 +-- objects/dcvalues.c | 2 + objects/font.c | 42 +- objects/gdiobj.c | 6 +- objects/palette.c | 18 + objects/region.c | 1 + objects/text.c | 22 +- sysres.dll | Bin 66048 -> 86528 bytes test/Imakefile | 8 + test/Makefile | 347 ++++++++++++++ test/widget.exe | Bin 140094 -> 306490 bytes tools/Imakefile | 5 + windows/Imakefile | 53 +++ windows/Makefile | 2 +- windows/caret.c | 250 ++++++++++ windows/class.c | 116 ++++- windows/clipping.c | 48 +- windows/dc.c | 31 +- windows/dce.c | 204 +++++--- windows/defwnd.c | 70 ++- windows/dialog.c | 19 +- windows/event.c | 437 ++++++++++++++--- windows/focus.c | 2 +- windows/graphics.c | 128 +++-- windows/message.c | 505 ++++++++++++++------ windows/painting.c | 30 +- windows/timer.c | 126 +++-- windows/win.c | 440 ++++++++--------- windows/winpos.c | 389 +++++++++++++++ wine.ini | 19 + 102 files changed, 9566 insertions(+), 2216 deletions(-) create mode 100644 Imakefile create mode 100644 LICENSE create mode 100644 PROPOSED_LICENSE create mode 100644 WARRANTY create mode 100644 Wine.tmpl create mode 100644 controls/Imakefile create mode 100644 debugger/Imakefile create mode 100644 debugger/readline/Imakefile create mode 100644 etc/Imakefile create mode 100644 etc/Makefile create mode 100644 if1632/Imakefile create mode 100644 include/Imakefile create mode 100644 include/Makefile create mode 100644 include/atom.h delete mode 100644 include/files.h create mode 100644 loader/Imakefile create mode 100644 loader/cursor.c delete mode 100644 loader/files.c create mode 100644 memory/Imakefile create mode 100644 memory/atom.c create mode 100644 misc/Imakefile create mode 100644 misc/comm.c delete mode 100644 misc/dos.c create mode 100644 misc/dos_fs.c rename {loader => misc}/int1a.c (93%) rename {loader => misc}/int21.c (52%) create mode 100644 objects/Imakefile create mode 100644 test/Imakefile create mode 100644 test/Makefile create mode 100644 tools/Imakefile create mode 100644 windows/Imakefile create mode 100644 windows/caret.c create mode 100644 windows/winpos.c create mode 100644 wine.ini diff --git a/ChangeLog b/ChangeLog index ebf46f14a76..151f65bfec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,295 @@ +Sun Jan 2 12:38:53 1994 David Metcalfe <david@prism.demon.co.uk> + + * [windows/class.c] + Implemented GetClassName and GetClassInfo. + + * [windows/caret.c] + Various improvements to text caret code. + +Fri Dec 31 15:22:22 1993 John Brezak <brezak@apollo.hp.com> + + * [misc/comm.c] + Patches to work with NetBSD. + +Thu Dec 30 12:11:55 1993 John Richardson <jrichard@cs.uml.edu> + + * [objects/bitblt.c] Added StretchBlt(). + +Tue Jan 4 05:22:07 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [misc/user.c] + Added creation of system message queue. + + * [objects/bitmap.c] [objects/dcvalues.c] [windows/dc.c] + Added DC size fields into DC structure. + + * [objects/clipping.c] + Bug fix in CLIPPING_IntersectRect(). + + * [windows/class.c] + Allocate a DCE instead of a DC for CS_CLASSDC classes. + + * [windows/clipping.c] + Fixed GetUpdateRect() and GetUpdateRgn() to clip to the client area. + + * [windows/dce.c] + Implemented GetDCEx() and GetWindowDC(). + + * [windows/defwnd.c] + Implemented WM_WINDOWPOSCHANGED handling. + + * [windows/event.c] + Preliminary support for Xlib event handling instead of Xt callbacks. + Changed MSG_AddMsg() calls to hardware_event() or PostMessage(). + + * [windows/message.c] + Preliminary support for multiple message queues. + Implemented hardware_event() to store messages into the system queue. + Implemented Get/SetTaskQueue(). + Better WM_PAINT and WM_TIMER handling. + Changes to use Xlib instead of Xt for events. + + * [windows/painting.c] + Use GetDCEx() to retrieve the DC, to get a correct visible region. + + * [windows/timer.c] + Moved the timer procedure callback into DispatchMessage(). + Changed implementation to get rid of Xt timeouts. Timer checking + is now done inside GetMessage(). + + * [windows/win.c] + Allocate a DCE instead of a DC for CS_OWNDC windows. + Replaced Xt calls with Xlib calls. + Moved window positioning functions into windows/winpos.c + + * [windows/winpos.c] (New file) + Rewritten most of the window positioning functions. + Implemented SetWindowPos() and MapWindowPoints(). + +Jan 3, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [if1632/user.spec] + Bad arguments description for function SetDlgItemText. + + * [objects/text.c] + Function DrawText now handle DT_CALCRECT request. + + * [misc/message.c] + Message boxes now use DrawText with DT_CALCRECT. + + * [windows/graphics.c] + Bug fix in function FrameRect, (it was using PEN instead of BRUSH). + + * [windows/win.c] + Bug fix for flags in function ShowWindow. + More accurate WM_SIZE generated by function ShowWindow. + + * [controls/listbox.c] + More code for LBS_MULTIPLESEL. + More code for LBS_MULTICOLUMN. + + * [include/windows.h] + Bad define for MF_SEPARATOR. + + * [controls/menu.c] + New functions: PopMenuWndProc() with 'glues', + CreatePopupMenu(), AppendMenu(), InsertMenu(), RemoveMenu(), + DeleteMenu(), ModifyMenu(), TrackPopupMenu(). + Code in stubs: CreateMenu(), DestroyMenu(). + +Sat Jan 1 10:22:43 1994 Bob Amstadt (bob@pooh) + + * loader/wine.c: Added support for relocation types 5 and 6. + +---------------------------------------------------------------------- +Mon Dec 27 11:06:03 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [misc/comm.c] + new functions: BuildCommDCB(), OpenComm(), CloseComm(), + SetCommBreak(), ClearCommBreak(), EscapeCommFunction(), FlushComm(), + GetCommError(), SetCommEventMask(), GetCommEventMask(), + SetCommState(), GetCommState(), TransmitCommChar(), ReadComm(), + WriteComm(). + +Wed Dec 22 13:00:15 1993 David Metcalfe <david@prism.demon.co.uk> + + * [windows/caret.c] + Implemented text caret functions. + +Tue Dec 21 06:13:58 1993 julliard@di.epfl.ch (Alexandre Julliard) + + * [loader/wine.c] + Bug fix in LoadImage(). + + * [objects/bitblt.c] [objects/clipping.c] [objects/text.c] + [windows/dc.c] [windows/dce.c] [windows/graphics.c] + Modified graphics calls to take into account the DC origin. + + * [windows/defwnd.c] + Added preliminary WM_NCCALCSIZE handling. + + * [windows/event.c] + Send WM_NCCALCSIZE message on resize event. + + * [windows/win.c] + Send WM_NCCALCSIZE message in CreateWindow(). + Realize widgets at creation time (should prevent problems with + unrealized widgets). + +Dec 19, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/static.c] + Send mouse & keyboard message received to its parent. + + * [controls/scroll.c] + Send keyboard message received to its parent. + + * [controls/listbox.c] + Add Navigation keys . + ListBox now use VSCROLL & HSCROLL instead of children. + Alpha version of LBS_MULTIPLESEL. + Alpha version of LBS_MULTICOLUMN. + + * [controls/combo.c] + Add Navigation keys on closed ComboBox. + Remove useless 'COMBOBOX_CreateComboBox' function. + +Mon Dec 19 20:39:34 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [loader/wine. + LoadImage() modified to use FindFile(). + + * [misc/file.c] + SetErrorMode added + + * [misc/dos_fs.c] + bug fixes. + +Dec 13, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [memory/global.c] + bug fix in GlobalGetFreeSegment : good ptr in 'g_prev'. + + * [sysres.dll] + preliminary version of a 'glass of wine' bitmap + + * [windows/event.c] + New function 'GetCapture'. + + * [controls/scroll.c] + Remove useless 'SCROLLBAR_CreateScrollBar' function. + + * [controls/listbox.c] + Remove useless 'LISTBOX_CreateListBox' function. + +Mon Dec 13 13:51:00 1993 David Metcalfe <david@prism.demon.co.uk> + + * [objects/font.c] + Corrected bugs in GetCharWidth(). + + * [windows/event.c] + Modified EVENT_key to send Windows virtual key codes for + WM_KEYDOWN and WM_KEYUP messages, and a WM_CHAR message + for printable characters. + +Wed Dec 08 19:20:00 1993 Karl Guenter Wuensch (hn324wu@unidui.uni-duisburg.de) + + * [windows/graphics.c] + Added Polyline and Polygon + +Mon Dec 13 14:51:54 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [controls/listbox.c] + ListBoxDirectory() modified to use dos_fs.c's functions to + access files&|drives. + +Sat Dec 04 17:04:23 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [misc/dos_fs.c] + Added FindFile() to search a file in a dos/unix style path. + + * [misc/file.c] + New Win31 functions: OpenFile, _lcreate, _llseek, GetTempDrive, + GetTempFileName, GetWindowsDirectory, GetSystemDirectory, + GetDriveType. + + * [misc/int21.c] + Modified. + +Wed Dec 1 16:20:45 1993 Miguel de Icaza (miguel@roxanne.nuclecu.unam.mx) + + * [misc/profile.c] + The Profile functions now return the correct values. They now + implement all the features described in the SDK. + +Tue Nov 30 13:55:27 1993 Bob Amstadt (bob at amscons) + + * [loader/selector.c] + Rewrote selector aliasing routines to use System V IPC + routine to alias memory segments. + +Nov 28, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [controls/listbox.c] + More consistency in functions using wIndexes + + * [controls/scroll.c] + New function : ShowScrollBar(). + + * [loader/cursor.c] ... New file + Move cursor functions from [loader/resource.c]. + New function : ClipCursor(). + New function : GetClipCursor(). + New function : CreateCursor(). + SetCursor() now working using gloabal variable 'winHasCursor'. + + *[object/palette.c] + New stub only : SelectPalette(). + New stub only : RealizePalette(). + + *[win/event.c] + New function : EVENT_enter_notify(), + update 'winHasCursor' and send WM_SETCURSOR. + + *[win/defwnd.c] + Add processing of WM_SETCURSOR message. + + *[win/win.c] + New members in WND structure : hCursor, hWndVScroll & hWndHScroll. + CreateWindowEx() now create children for WM_HSCROLL & WM_VSCROLL. + New function ClientToScreen(). + New function ScreenToClient(). + +Mon Nov 25 18:25:40 1993 Erik Bos (erik@trashcan.hacktic.nl) + + * [files.h / regfunc.h / misc/dos.c] + Removed. + + * [misc/dos_fs.c] + Added support for loading dosdrive cfg from wine.ini. + + * [misc/int21.c] + Modified. + + +Wed Nov 24 11:37:33 1993 julliard@disuns2.epfl.ch (Alexandre Julliard) + + * [include/atom.h] [memory/atom.c] + Implemented atoms. + + * [windows/class.c] + Modified RegisterClass() to use atoms. + Implemented CS_GLOBALCLASS style. + + * [windows/message.c] + Implemented RegisterWindowMessage(). + + * [loader/resource.c] + Bug fix in LoadResource(). + + * [windows/dialog.c] + Modified CreateDialogParam() to use Find/LoadResource(). + Mon Nov 22 13:58:56 1993 David Metcalfe <david@prism.demon.co.uk> * [windows/scroll.c] @@ -37,7 +329,6 @@ Nov 21, 93 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [sysres.dll] Resources only 16bits DLL for System Resources, icons, etc... ----------------------------------------------------------------------- Sun Nov 14 14:39:06 1993 julliard@di.epfl.ch (Alexandre Julliard) * [include/dialog.h] [windows/dialog.c] diff --git a/Imakefile b/Imakefile new file mode 100644 index 00000000000..26b35f407aa --- /dev/null +++ b/Imakefile @@ -0,0 +1,66 @@ +#include "Wine.tmpl" + +/* + * This is the first try at using Imakefiles. There are probably many + * problems and things I haven't even considered. I do not have a Linux + * system to test them on, just NetBSD, so you may need to change things + * like the the SYSLIBS definition below... + * + * Peter Galbavy, 5th Dec 1993 peter@wonderland.org + */ + +#define IHaveSubDirs +#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' + +SUBDIRS = \ + tools \ + controls \ + debugger \ + etc \ + if1632 \ + include \ + loader \ + memory \ + misc \ + objects \ + test \ + windows + +WINEDIR = $(LIBDIR)/wine + +OBJS = \ + if1632.o \ + controls.o \ + loader.o \ + memory.o \ + misc.o \ + objects.o \ + windows.o \ + debugger.o \ + readline.o + +#ifdef i386BsdArchitecture +SYSLIBS = -ll -lm -li386 -lgnumalloc +#else +#ifdef LinuxArchitechture +SYSLIBS = -lm +#endif +#endif + +AllTarget(wine) + +NamedTargetSubdirs($(OBJS),$(SUBDIRS),"making",PassCDebugFlags,all) +MakefileSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +IncludesSubdirs($(SUBDIRS)) +CleanSubdirs($(SUBDIRS)) + +NormalProgramTarget(wine,$(OBJS),XawClientDepLibs,XawClientLibs,$(SYSLIBS)) + +depend:: + +install:: + +includes:: + +clean:: diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..3854e932ad3 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +All code unless stated otherwise is covered by the GNU Pubic License. diff --git a/Makefile b/Makefile index 11a884a9bbf..1f7221cbd49 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ###################################################################### # These variables are inherited by the sub-makefiles -DEBUGOPTS= +DEBUGOPTS=-DUSE_XLIB COPTS=-O2 -m486 INCLUDE_DIR=include LDFLAGS= @@ -12,11 +12,17 @@ LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ memory/memory.o misc/misc.o objects/objects.o windows/windows.o debugger/debugger.o SUBDIRS=if1632 controls loader memory misc objects windows debugger +TAGFILES=if1632/{*.c,*.S} controls/{*.c,*.S} loader/{*.c,*.S} \ + memory/{*.c,*.S} misc/{*.c,*.S} objects/{*.c,*.S} \ + windows/{*.c,*.S} debugger/{*.c,*.S} all: $(TARGET) dummy: +tags: + etags $(TAGFILES) + clean: rm -f *~ *.o *# @for i in tools $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done diff --git a/PROPOSED_LICENSE b/PROPOSED_LICENSE new file mode 100644 index 00000000000..a7d2f7a94a3 --- /dev/null +++ b/PROPOSED_LICENSE @@ -0,0 +1,29 @@ +You may without charge, royalty or other payment, copy and +distribute copies of this work and derivative works of this work +in source or binary form provided that: (1) +you appropriately publish on each copy an appropriate copyright +notice; (2) faithfully reproduce all prior copyright notices +included in the original work (you may also add your own +copyright notice); and (3) agree to indemnify and hold all prior +authors, copyright holders and licensors of the work harmless +from and against all damages arising from use of the work. + +You may distribute sources of derivative works of the work +provided that (1) (a) all source files of the original work that +have been modified, (b) all source files of the derivative work +that contain any party of the original work, and (c) all source +files of the derivative work that are necessary to compile, link +and run the derivative work without unresolved external calls and +with the same functionality of the original work ("Necessary +Sources") carry a prominent notice explaining the nature and date +of the modification and/or creation. You are encouraged to make +the Necessary Sources available under this license in order to +further the development and acceptance of the work. + +EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED +WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING +BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A +PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS +OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR +LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/README b/README index ba0b81b1a75..1b090d42f7a 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ Copyright Robert J. Amstadt, 1993. All code is provided without -warranty. It is my intent to cover this code with the Gnu Public -License. +warranty. All code is covered by the license contained in the file +LICENSE unless explicitly stated in the individual source file. INSTALLATION: @@ -19,18 +19,56 @@ All: To build Wine, first do a "make depend" and then a "make". The executable "wine" will be built. "wine" will load and run Windows' -executables. You must specify the entire path to the executable, -have the executable in the current directory, or specify a load -path with environment variable WINEPATH. +executables. You must have a file "wine.ini" in the current directory, +your homedirectory, or in the path specified by the environment +variable WINEPATH. Multiple directories in WINEPATH should be seperated +by semi-colons and NOT by colons! -For example, to run Windows' solitaire: +You must specify the entire path to the executable, or a filename only +(using the path= statement in wine.ini as the search path) - export WINEPATH=/dos/windows;/dos/windows/system - wine sol +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 c:\\windows\\sol.exe (using a dosfilename) + + wine /usr/windows/sol.exe (using a unixfilename) Have a nice game of solitaire, but be careful. Emulation isn't perfect. So, occassionally it will crash. +WHAT'S NEW with version 0.5: (see ChangeLog for details) + - Working towards elimination of Xt-dependent code. + - StretchBlt() + - GetClassName() & GetClassInfo() + - Implemented loader relocation types 5 and 6. + +WHAT'S NEW with version 0.4.14: (see ChangeLog for details) + - Bug fixes and enhancements + - Comm functions + - Text caret functions + +WHAT'S NEW with version 0.4.13: (see ChangeLog for details) + - Bug fixes + - GetCapture() + - More keyboard handling + - Polyline() and Polygon() + +WHAT'S NEW with version 0.4.12: (see ChangeLog for details) + - Bug fixes + - New DOS file functions + - Experimental Imakefiles + +WHAT'S NEW with version 0.4.11: (see ChangeLog for details) + - Bug fixes + - New cursor functions + - New file system handling + - Atoms + WHAT'S NEW with version 0.4.10: (see ChangeLog for details) - Bug fixes - More scroll bar functions diff --git a/WARRANTY b/WARRANTY new file mode 100644 index 00000000000..492af846b2e --- /dev/null +++ b/WARRANTY @@ -0,0 +1,7 @@ +EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED +WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING +BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A +PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS +OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR +LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/Wine.tmpl b/Wine.tmpl new file mode 100644 index 00000000000..3bb9466ace7 --- /dev/null +++ b/Wine.tmpl @@ -0,0 +1,29 @@ +XCOMM $Id$ + +INCLUDES = -I$(TOP)/include + +XCOMM Imake rules go here + +XCOMM First, dll description to files etc +#ifndef MakeDllFromSpec +#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 @@\ + +#endif + +/* + * WineRelocatableTarget - generate rules to produce a relocatable object + * file instead of a library. + */ +#ifndef WineRelocatableTarget +#define WineRelocatableTarget(objname,objlist,depobj) @@\ +AllTarget(objname.o) @@\ + @@\ +objname.o: depobj @@\ + $(RM) $@ @@\ + $(LD) $(LDCOMBINEFLAGS) objlist depobj -o $@ +#endif /* WineRelocatableTarget */ + diff --git a/bsdmake.patch b/bsdmake.patch index 99fa57a116e..68fa15782a3 100644 --- a/bsdmake.patch +++ b/bsdmake.patch @@ -6,7 +6,7 @@ diff -ruN ../Backup//Makefile ./Makefile # These definitions are for the top level TARGET=wine -LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -+LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -li386 -lgnumalloc ++LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -li386 -lgnumalloc -ll OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ memory/memory.o misc/misc.o objects/objects.o windows/windows.o SUBDIRS=if1632 controls loader memory misc objects windows diff --git a/controls/Imakefile b/controls/Imakefile new file mode 100644 index 00000000000..aee3e147848 --- /dev/null +++ b/controls/Imakefile @@ -0,0 +1,37 @@ +#include "../Wine.tmpl" + +MODULE = controls + +SRCS = \ + menu.c \ + widgets.c \ + button.c \ + scroll.c \ + listbox.c \ + combo.c \ + static.c \ + SmeMenuButto.c \ + WinLabel.c \ + WinCommand.c \ + WinMenuButto.c + +OBJS = \ + menu.o \ + widgets.o \ + button.o \ + scroll.o \ + listbox.o \ + combo.o \ + static.o \ + SmeMenuButto.o \ + WinLabel.o \ + WinCommand.o \ + WinMenuButto.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/controls/combo.c b/controls/combo.c index e4715891a87..c8e32b9794a 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -17,60 +17,24 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include "combo.h" #include "heap.h" #include "win.h" -#include "dirent.h" +#include <sys/types.h> +#include <dirent.h> #include <sys/stat.h> LPHEADCOMBO ComboGetStorageHeader(HWND hwnd); int CreateComboStruct(HWND hwnd); -void COMBOBOX_CreateComboBox(LPSTR className, LPSTR comboLabel, HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - DWORD style; - char widgetName[15]; - -#ifdef DEBUG_COMBO - printf("combo: label = %s, x = %d, y = %d\n", comboLabel, - wndPtr->rectClient.left, wndPtr->rectClient.top); - printf(" width = %d, height = %d\n", - wndPtr->rectClient.right - wndPtr->rectClient.left, - wndPtr->rectClient.bottom - wndPtr->rectClient.top); -#endif - - if (!wndPtr) - return; - - style = wndPtr->dwStyle & 0x0000FFFF; -/* - if ((style & LBS_NOTIFY) == LBS_NOTIFY) -*/ - sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); - wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, wndPtr->rectClient.left, - XtNy, wndPtr->rectClient.top, - XtNwidth, wndPtr->rectClient.right - - wndPtr->rectClient.left, - XtNheight, 16, - NULL ); - GlobalUnlock(hwnd); - GlobalUnlock(wndPtr->hwndParent); -} - - /*********************************************************************** - * WIDGETS_ComboWndProc + * ComboWndProc */ -LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ) +LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WORD wRet; RECT rect; - int y; + int y, count; int width, height; + int AltState; WND *wndPtr; LPHEADCOMBO lphc; char str[128]; @@ -106,17 +70,20 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, case WM_DESTROY: lphc = ComboGetStorageHeader(hwnd); if (lphc == 0) return 0; +/* DestroyWindow(lphc->hWndDrop); DestroyWindow(lphc->hWndEdit); -/* - DestroyWindow(lphc->hWndLBox); */ + DestroyWindow(lphc->hWndLBox); free(lphc); - *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; +/* + *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; + printf("Combo WM_DESTROY after clearing wExtra !\n"); +*/ #ifdef DEBUG_COMBO printf("Combo WM_DESTROY %lX !\n", lphc); #endif - return 0; + return DefWindowProc( hwnd, message, wParam, lParam ); case WM_COMMAND: wndPtr = WIN_FindWndPtr(hwnd); @@ -169,9 +136,56 @@ LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, break; case WM_LBUTTONDOWN: printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam); + 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); break; case WM_KEYDOWN: - printf("Combo WM_KEYDOWN wParam %X!\n", wParam); + 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); + 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; case WM_CTLCOLOR: return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam)); diff --git a/controls/listbox.c b/controls/listbox.c index a71eb92b3fe..b1dfb731b25 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -11,16 +11,21 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; +#include <stdio.h> #include <X11/Intrinsic.h> #include <X11/StringDefs.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 "wine.h" #include "listbox.h" #include "scroll.h" -#include "dirent.h" -#include <sys/stat.h> +#include "int21.h" +#include "prototypes.h" #define GMEM_ZEROINIT 0x0040 @@ -38,7 +43,8 @@ int ListBoxDeleteString(HWND hwnd, UINT uIndex); int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr); int ListBoxResetContent(HWND hwnd); int ListBoxSetCurSel(HWND hwnd, WORD wIndex); -int ListBoxSetSel(HWND hwnd, WORD wIndex); +int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state); +int ListBoxGetSel(HWND hwnd, WORD wIndex); int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec); int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT rect); int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height); @@ -47,59 +53,16 @@ int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, int ListBoxFindNextMatch(HWND hwnd, WORD wChar); - -void LISTBOX_CreateListBox(LPSTR className, LPSTR listboxLabel, HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - DWORD style; - char widgetName[15]; - -#ifdef DEBUG_LISTBOX - printf("listbox: label = %s, x = %d, y = %d\n", listboxLabel, - wndPtr->rectClient.left, wndPtr->rectClient.top); - printf(" width = %d, height = %d\n", - wndPtr->rectClient.right - wndPtr->rectClient.left, - wndPtr->rectClient.bottom - wndPtr->rectClient.top); -#endif - - if (!wndPtr) - return; - - style = wndPtr->dwStyle & 0x0000FFFF; -/* - if ((style & LBS_NOTIFY) == LBS_NOTIFY) - if ((style & LBS_SORT) == LBS_SORT) -*/ - sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); - wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, wndPtr->rectClient.left, - XtNy, wndPtr->rectClient.top, - XtNwidth, wndPtr->rectClient.right - - wndPtr->rectClient.left, - XtNheight, wndPtr->rectClient.bottom - - wndPtr->rectClient.top, - NULL ); - GlobalUnlock(hwnd); - GlobalUnlock(wndPtr->hwndParent); -} - - - /*********************************************************************** - * WIDGETS_ListBoxWndProc + * ListBoxWndProc */ -LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ) +LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WND *wndPtr; LPHEADLIST lphl; WORD wRet; RECT rect; int y; - int width, height; CREATESTRUCT *createStruct; static RECT rectsel; switch(message) @@ -115,19 +78,23 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); else lphl->hWndLogicParent = GetParent(hwnd); - width = wndPtr->rectClient.right - wndPtr->rectClient.left; - height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; - lphl->hWndScroll = CreateWindow("SCROLLBAR", "", - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBS_VERT, - width - 17, 0, 16, height, hwnd, 1, wndPtr->hInstance, NULL); - ShowWindow(lphl->hWndScroll, SW_HIDE); - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); + lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; + if (wndPtr->hWndVScroll != (HWND)NULL) { + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + ShowScrollBar(hwnd, SB_VERT, FALSE); + } + if (wndPtr->hWndHScroll != (HWND)NULL) { + SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } + if (wndPtr->hCursor == (HCURSOR)NULL) + wndPtr->hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW); return 0; case WM_DESTROY: - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == 0) return 0; ListBoxResetContent(hwnd); - DestroyWindow(lphl->hWndScroll); + DestroyCursor(wndPtr->hCursor); free(lphl); *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; #ifdef DEBUG_LISTBOX @@ -164,23 +131,74 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, if (lphl->FirstVisible > lphl->ItemsCount) lphl->FirstVisible = lphl->ItemsCount; if (y != lphl->FirstVisible) { - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + 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); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + } + return 0; + case WM_LBUTTONDOWN: /* SetFocus(hwnd); */ SetCapture(hwnd); - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; - lphl->PrevSelected = lphl->ItemSelected; - wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - ListBoxSetCurSel(hwnd, wRet); - ListBoxGetItemRect(hwnd, wRet, &rectsel); + 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; @@ -188,7 +206,7 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, ReleaseCapture(); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; - if (lphl->PrevSelected != lphl->ItemSelected) + if (lphl->PrevFocused != lphl->ItemFocused) SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); return 0; @@ -200,22 +218,6 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, MAKELONG(hwnd, LBN_DBLCLK)); printf("ListBox Send LBN_DBLCLK !\n"); return 0; - case WM_KEYDOWN: - printf("ListBox WM_KEYDOWN wParam %X!\n", wParam); - ListBoxFindNextMatch(hwnd, wParam); - 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_MOUSEMOVE: if ((wParam & MK_LBUTTON) != 0) { y = HIWORD(lParam); @@ -223,7 +225,8 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, lphl = ListBoxGetStorageHeader(hwnd); if (lphl->FirstVisible > 1) { lphl->FirstVisible--; - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; @@ -234,7 +237,8 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, lphl = ListBoxGetStorageHeader(hwnd); if (lphl->FirstVisible < lphl->ItemsCount) { lphl->FirstVisible++; - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; @@ -243,7 +247,12 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, if ((y > 0) && (y < (rect.bottom - 4))) { if ((y < rectsel.top) || (y > rectsel.bottom)) { wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - ListBoxSetCurSel(hwnd, wRet); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = wRet; + } + else { + ListBoxSetCurSel(hwnd, wRet); + } ListBoxGetItemRect(hwnd, wRet, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -252,6 +261,72 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, } } 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->hWndVScroll != (HWND)NULL) + 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 LB_RESETCONTENT: printf("ListBox LB_RESETCONTENT !\n"); @@ -260,17 +335,17 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_DIR: printf("ListBox LB_DIR !\n"); wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + 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); +#endif return wRet; case LB_INSERTSTRING: wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam); @@ -289,9 +364,8 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, return lphl->ItemsCount; case LB_GETCURSEL: lphl = ListBoxGetStorageHeader(hwnd); - printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemSelected); - if (lphl->ItemSelected == 0) return LB_ERR; - return lphl->ItemSelected; + printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); + return lphl->ItemFocused; case LB_GETHORIZONTALEXTENT: return wRet; case LB_GETITEMDATA: @@ -301,6 +375,7 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_GETITEMRECT: return wRet; case LB_GETSEL: + wRet = ListBoxGetSel(hwnd, wParam); return wRet; case LB_GETSELCOUNT: return wRet; @@ -317,7 +392,9 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, case LB_SETCARETINDEX: return wRet; case LB_SETCOLUMNWIDTH: - return wRet; + lphl = ListBoxGetStorageHeader(hwnd); + lphl->ColumnsWidth = wParam; + break; case LB_SETHORIZONTALEXTENT: return wRet; case LB_SETITEMDATA: @@ -329,38 +406,29 @@ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam); #endif wRet = ListBoxSetCurSel(hwnd, wParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + 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, wParam); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + 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; - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } + if (wndPtr->hWndVScroll != (HWND)NULL) + 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); - if (IsWindowVisible(hwnd)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } return wRet; default: @@ -392,6 +460,7 @@ LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) void StdDrawListBox(HWND hwnd) { + WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; @@ -399,7 +468,7 @@ void StdDrawListBox(HWND hwnd) HWND hWndParent; HDC hdc; RECT rect; - UINT i, h, h2; + UINT i, h, h2, maxwidth, ipc; char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); @@ -407,41 +476,64 @@ void StdDrawListBox(HWND hwnd) EndPaint( hwnd, &ps ); return; } - GetClientRect(hwnd, &rect); - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) goto EndOfPaint; hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); - if (lphl->ItemsCount > lphl->ItemsVisible) rect.right -= 16; + GetClientRect(hwnd, &rect); + if ((wndPtr->hWndVScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; + if ((wndPtr->hWndHScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; FillRect(hdc, &rect, hBrush); + maxwidth = rect.right; + rect.right = lphl->ColumnsWidth; if (lphl->ItemsCount == 0) goto EndOfPaint; lpls = lphl->lpFirst; if (lpls == NULL) goto EndOfPaint; lphl->ItemsVisible = 0; + lphl->ItemsPerColumn = ipc = 0; for(i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; + lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; - TextOut(hdc, 5, h + 2, (char *)lpls->dis.itemData, + 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); } + if (lphl->ItemFocused == i - 1) { + DrawFocusRect(hdc, &lpls->dis.rcItem); + } h += h2; lphl->ItemsVisible++; - if (h > rect.bottom) break; + ipc++; + if (h > rect.bottom) { + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc); + ipc = 0; + h = 0; + rect.left += lphl->ColumnsWidth; + rect.right += lphl->ColumnsWidth; + if (rect.left > maxwidth) break; + } + else + break; + } } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); - if (lphl->ItemsCount > lphl->ItemsVisible) { - InvalidateRect(lphl->hWndScroll, NULL, TRUE); - UpdateWindow(lphl->hWndScroll); + if ((lphl->ItemsCount > lphl->ItemsVisible) & + (wndPtr->hWndVScroll != (HWND)NULL)) { + InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); + UpdateWindow(wndPtr->hWndVScroll); } } @@ -449,6 +541,7 @@ EndOfPaint: void OwnerDrawListBox(HWND hwnd) { + WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; @@ -456,38 +549,47 @@ void OwnerDrawListBox(HWND hwnd) HWND hWndParent; HDC hdc; RECT rect; - UINT i, h, h2; + UINT i, h, h2, maxwidth; char C[128]; h = 0; - hdc = BeginPaint( hwnd, &ps ); + hdc = BeginPaint(hwnd, &ps); if (!IsWindowVisible(hwnd)) { EndPaint( hwnd, &ps ); return; } - GetClientRect(hwnd, &rect); - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) goto EndOfPaint; hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); - if (lphl->ItemsCount > lphl->ItemsVisible) rect.right -= 16; + GetClientRect(hwnd, &rect); + if ((wndPtr->hWndVScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; + if ((wndPtr->hWndHScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; FillRect(hdc, &rect, hBrush); + maxwidth = rect.right; + rect.right = lphl->ColumnsWidth; if (lphl->ItemsCount == 0) goto EndOfPaint; lpls = lphl->lpFirst; if (lpls == NULL) goto EndOfPaint; lphl->ItemsVisible = 0; - for(i = 1; i <= lphl->ItemsCount; i++) { + for (i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { lpls->dis.hDC = hdc; - lpls->dis.itemID = i; + lpls->dis.itemID = i - 1; h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; + lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; lpls->dis.itemAction = ODA_DRAWENTIRE; if (lpls->dis.itemState != 0) { lpls->dis.itemAction |= ODA_SELECT; } + if (lphl->ItemFocused == i - 1) { + lpls->dis.itemAction |= ODA_FOCUS; + } #ifdef DEBUT_LISTBOX printf("LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n", i, lpls->dis.rcItem.left, lpls->dis.rcItem.top, @@ -502,16 +604,17 @@ void OwnerDrawListBox(HWND hwnd) } h += h2; lphl->ItemsVisible++; - if (h > rect.bottom) break; + if (h > rect.bottom) goto EndOfPaint; } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); - if (lphl->ItemsCount > lphl->ItemsVisible) { - InvalidateRect(lphl->hWndScroll, NULL, TRUE); - UpdateWindow(lphl->hWndScroll); + if ((lphl->ItemsCount > lphl->ItemsVisible) & + (wndPtr->hWndVScroll != (HWND)NULL)) { + InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); + UpdateWindow(wndPtr->hWndVScroll); } } @@ -519,27 +622,42 @@ EndOfPaint: int ListBoxFindMouse(HWND hwnd, int X, int Y) { -LPHEADLIST lphl; -LPLISTSTRUCT lpls; -RECT rect; -UINT i, h, h2; -char C[128]; -h = 0; -lphl = ListBoxGetStorageHeader(hwnd); -if (lphl == NULL) return LB_ERR; -if (lphl->ItemsCount == 0) return LB_ERR; -lpls = lphl->lpFirst; -if (lpls == NULL) return LB_ERR; -for(i = 1; i <= lphl->ItemsCount; i++) { - if (i >= lphl->FirstVisible) { - h2 = h; - h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; - if ((Y > h2) && (Y < h)) return(i); + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + RECT rect; + UINT i, h, h2, w, w2; + char C[128]; + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + if (lphl->ItemsCount == 0) return LB_ERR; + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + GetClientRect(hwnd, &rect); + if ((wndPtr->hWndVScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; + if ((wndPtr->hWndHScroll != (HWND)NULL) && + IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; + h = w2 = 0; + w = lphl->ColumnsWidth; + for(i = 1; i <= lphl->ItemsCount; i++) { + if (i >= lphl->FirstVisible) { + h2 = h; + h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; + if ((Y > h2) && (Y < h) && + (X > w2) && (X < w)) return(i - 1); + if (h > rect.bottom) { + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR; + h = 0; + w2 = w; + w += lphl->ColumnsWidth; + if (w2 > rect.right) return LB_ERR; + } + } + if (lpls->lpNext == NULL) return LB_ERR; + lpls = (LPLISTSTRUCT)lpls->lpNext; } - if (lpls->lpNext == NULL) return LB_ERR; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } -return(LB_ERR); + return(LB_ERR); } @@ -602,14 +720,22 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, - (lphl->FirstVisible != 1)); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } - if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) - ShowWindow(lphl->hWndScroll, SW_NORMAL); + if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) { + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, TRUE); + } return lphl->ItemsCount; } @@ -624,7 +750,7 @@ int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - if (uIndex < 1 || uIndex > lphl->ItemsCount) 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; @@ -653,11 +779,19 @@ int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, - (lphl->FirstVisible != 1)); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, + (lphl->FirstVisible != 1)); + if (wndPtr->hWndHScroll != (HWND)NULL && 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)) - ShowWindow(lphl->hWndScroll, SW_NORMAL); + (lphl->ItemsVisible != 0)) { + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, TRUE); + } if ((lphl->FirstVisible <= uIndex) && ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { InvalidateRect(hwnd, NULL, TRUE); @@ -675,11 +809,11 @@ int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr) UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - if (uIndex < 1 || uIndex > lphl->ItemsCount) 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++) { + for(Count = 0; Count < uIndex; Count++) { if (lpls->lpNext == NULL) return LB_ERR; lpls = (LPLISTSTRUCT)lpls->lpNext; } @@ -698,12 +832,13 @@ int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr) int ListBoxDeleteString(HWND hwnd, UINT uIndex) { + WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT Count; - lphl = ListBoxGetStorageHeader(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - if (uIndex < 1 || uIndex > lphl->ItemsCount) 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; @@ -716,9 +851,17 @@ int ListBoxDeleteString(HWND hwnd, UINT uIndex) lphl->ItemsCount--; if (lpls->hData != 0) USER_HEAP_FREE(lpls->hData); if (lpls->hMem != 0) USER_HEAP_FREE(lpls->hMem); - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); - if (lphl->ItemsCount < lphl->ItemsVisible) - ShowWindow(lphl->hWndScroll, SW_HIDE); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, TRUE); + if (lphl->ItemsCount < lphl->ItemsVisible) { + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, FALSE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, FALSE); + } if ((lphl->FirstVisible <= uIndex) && ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { InvalidateRect(hwnd, NULL, TRUE); @@ -735,13 +878,12 @@ int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr) UINT Count; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (nFirst < 1 || nFirst > lphl->ItemsCount) return LB_ERR; + if (nFirst > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - Count = 1; + Count = 0; while(lpls != NULL) { - if (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) - return Count; + if (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) return Count; lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } @@ -774,14 +916,21 @@ int ListBoxResetContent(HWND hwnd) lphl->lpFirst = NULL; lphl->FirstVisible = 1; lphl->ItemsCount = 0; - lphl->ItemSelected = 0; - lphl->PrevSelected = 0; + lphl->ItemFocused = 0; + lphl->PrevFocused = 0; if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) SendMessage(wndPtr->hwndParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); - SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); - ShowWindow(lphl->hWndScroll, SW_HIDE); + if (wndPtr->hWndVScroll != (HWND)NULL) + SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); + if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, TRUE); + if (wndPtr->hWndVScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_VERT, FALSE); + if (wndPtr->hWndHScroll != (HWND)NULL) + ShowScrollBar(hwnd, SB_HORZ, FALSE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return TRUE; @@ -796,8 +945,8 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) UINT i; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; - lphl->ItemSelected = LB_ERR; - if (wIndex < 0 || wIndex >= lphl->ItemsCount) return LB_ERR; + lphl->ItemFocused = LB_ERR; + if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { @@ -810,7 +959,7 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) lpls2->dis.itemState = 0; if (lpls == NULL) break; } - lphl->ItemSelected = wIndex; + lphl->ItemFocused = wIndex; if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) SendMessage(wndPtr->hwndParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); @@ -819,21 +968,21 @@ int ListBoxSetCurSel(HWND hwnd, WORD wIndex) -int ListBoxSetSel(HWND hwnd, WORD wIndex) +int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 0 || wIndex >= lphl->ItemsCount) return LB_ERR; + if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; - if (i == wIndex) { - lpls2->dis.itemState = 1; + if ((i == wIndex) || (wIndex == (WORD)-1)) { + lpls2->dis.itemState = state; break; } if (lpls == NULL) break; @@ -842,30 +991,80 @@ int ListBoxSetSel(HWND hwnd, WORD wIndex) } +int ListBoxGetSel(HWND hwnd, WORD wIndex) +{ + LPHEADLIST lphl; + LPLISTSTRUCT lpls, lpls2; + UINT i; + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return LB_ERR; + if (wIndex >= lphl->ItemsCount) return LB_ERR; + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + for(i = 0; i < lphl->ItemsCount; i++) { + lpls2 = lpls; + lpls = (LPLISTSTRUCT)lpls->lpNext; + if (i == wIndex) { + return lpls2->dis.itemState; + } + if (lpls == NULL) break; + } + return LB_ERR; +} + + int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) { -DIR *dirp; -struct dirent *dp; -struct stat st; -char str[128]; -int wRet; -dirp = opendir("."); -while ( (dp = readdir(dirp)) != NULL) - { - stat(dp->d_name, &st); -#ifdef DEBUG_LBDIR - printf("LB_DIR : st_mode=%lX / d_name='%s'\n", st.st_mode, dp->d_name); -#endif - if S_ISDIR(st.st_mode) { - sprintf(str, "[%s]", dp->d_name); + struct dosdirent *dp; + struct stat st; + int x, wRet; + char temp[256]; + + fprintf(stderr,"ListBoxDirectory: %s, %4x\n",filespec,attrib); + + + 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 (attrib & DDL_DIRECTORY) { + sprintf(temp, "[%s]", dp->filename); + if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) + break; + } + } else + if (attrib & DDL_EXCLUSIVE) { + if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM) ) + if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR) + break; + } else { + if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR) + break; + } } - else - strcpy(str, dp->d_name); - wRet = ListBoxAddString(hwnd, str); - if (wRet == LB_ERR) break; - } -closedir(dirp); -return wRet; + DOS_closedir(dp); + + if (attrib & DDL_DRIVES) + { + for (x=0;x!=MAX_DOS_DRIVES;x++) + { + if (DOS_ValidDrive(x)) + { + sprintf(temp, "[-%c-]", 'A'+x); + if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) + break; + } + } + } + + return wRet; } @@ -876,10 +1075,10 @@ int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect) UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; + if (wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - for(i = 0; i <= lphl->ItemsCount; i++) { + for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { @@ -900,14 +1099,16 @@ int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height) UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; - if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; + if (wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; - for(i = 0; i <= lphl->ItemsCount; i++) { + for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { lpls2->dis.rcItem.bottom = lpls2->dis.rcItem.top + (short)height; + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); break; } if (lpls == NULL) break; @@ -954,14 +1155,19 @@ int ListBoxFindNextMatch(HWND hwnd, WORD wChar) return LB_ERR; } } - Count = 1; + Count = 0; while(lpls != NULL) { - if (Count > lphl->ItemSelected) { + if (Count > lphl->ItemFocused) { if (*((char *)lpls->dis.itemData) == (char)wChar) { lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - ListBoxSetCurSel(hwnd, Count); - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = Count; + } + else { + ListBoxSetCurSel(hwnd, Count); + } + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; @@ -970,15 +1176,20 @@ int ListBoxFindNextMatch(HWND hwnd, WORD wChar) lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } - Count = 1; + Count = 0; lpls = lphl->lpFirst; while(lpls != NULL) { if (*((char *)lpls->dis.itemData) == (char)wChar) { - if (Count == lphl->ItemSelected) return LB_ERR; + if (Count == lphl->ItemFocused) return LB_ERR; lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - ListBoxSetCurSel(hwnd, Count); - SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = Count; + } + else { + ListBoxSetCurSel(hwnd, Count); + } + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; diff --git a/controls/menu.c b/controls/menu.c index 2d22115fa0d..c1cd758484d 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -1,6 +1,8 @@ static char RCSId[] = "$Id$"; static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; +#define DEBUG_MENU + #include <X11/Intrinsic.h> #include <X11/StringDefs.h> #include <X11/Xaw/SmeBSB.h> @@ -22,7 +24,306 @@ static int lastLevel; static int menuId = 0; static Pixmap checkBitmap = XtUnspecifiedPixmap; static Pixmap nocheckBitmap = XtUnspecifiedPixmap; - + +LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd); +LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr); +void StdDrawPopupMenu(HWND hwnd); +LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet); +LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos); + +/*********************************************************************** + * PopupMenuWndProc + */ +LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) +{ + CREATESTRUCT *createStruct; + WORD wRet; + short x, y; + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem, lpitem2; + HMENU hSubMenu; + RECT rect; + HDC hDC; + switch(message) + { + case WM_CREATE: +#ifdef DEBUG_MENU + printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam); +#endif + createStruct = (CREATESTRUCT *)lParam; + lppop = (LPPOPUPMENU)createStruct->lpCreateParams; + if (lppop == 0) break; + wndPtr = WIN_FindWndPtr(hwnd); + *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop; +#ifdef DEBUG_MENU + printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop); +#endif + return 0; + case WM_DESTROY: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); +#ifdef DEBUG_MENU + printf("PopupMenu WM_DESTROY %lX !\n", lppop); +#endif + return 0; + + case WM_LBUTTONDOWN: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + SetCapture(hwnd); + lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + printf("PopupMenu WM_LBUTTONDOWN wRet=%d lpitem=%08X !\n", wRet, lpitem); + if (lpitem != NULL) { + lppop->FocusedItem = wRet; + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hDC = GetDC(hwnd); + InvertRect(hDC, &lpitem->rect); + ReleaseDC(hwnd, hDC); + } + } + break; + case WM_LBUTTONUP: + lppop = PopupMenuGetStorageHeader(hwnd); + ReleaseCapture(); + lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem); + if (lpitem != NULL) { + if (lppop->FocusedItem != (WORD)-1) { + lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem); + if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + hDC = GetDC(hwnd); + InvertRect(hDC, &lpitem2->rect); + ReleaseDC(hwnd, hDC); + } + } + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + hSubMenu = (HMENU)lpitem->item_id; + printf("ShowSubmenu hSubMenu=%04X !\n", hSubMenu); + GetClientRect(hwnd, &rect); + x = rect.right; + GetWindowRect(hwnd, &rect); + x += rect.left; + TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, + x, rect.top + HIWORD(lParam), + 0, lppop->ownerWnd, (LPRECT)NULL); + break; + } + if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { + SendMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); + printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", + lpitem->item_id); + ShowWindow(lppop->hWnd, SW_HIDE); + break; + } + } + break; + case WM_MOUSEMOVE: + if ((wParam & MK_LBUTTON) != 0) { + lppop = PopupMenuGetStorageHeader(hwnd); + lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet); + if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) { + 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); + } + lppop->FocusedItem = wRet; + printf("PopupMenu WM_MOUSEMOVE wRet=%d lpitem=%08X !\n", wRet, lpitem); + InvertRect(hDC, &lpitem->rect); + ReleaseDC(hwnd, hDC); + } + } + break; + + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); + + case WM_PAINT: + printf("PopupMenu WM_PAINT !\n"); + StdDrawPopupMenu(hwnd); + break; + default: + return DefWindowProc( hwnd, message, wParam, lParam ); + } +return(0); +} + + + +LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr) +{ + WND *Ptr; + LPPOPUPMENU lppop; + *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); + if (Ptr == 0) { + printf("Bad Window handle on PopupMenu !\n"); + return 0; + } + lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); + return lppop; +} + + +LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd) +{ + WND *Ptr; + LPPOPUPMENU lppop; + Ptr = WIN_FindWndPtr(hwnd); + if (Ptr == 0) { + printf("Bad Window handle on PopupMenu !\n"); + return 0; + } + lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]); + return lppop; +} + + +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; + HBITMAP hBitMap; + BITMAP bm; + UINT i; + hDC = BeginPaint( hwnd, &ps ); + if (!IsWindowVisible(hwnd)) { + EndPaint( hwnd, &ps ); + return; + } + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) goto EndOfPaint; + hBrush = SendMessage(lppop->ownerWnd, WM_CTLCOLOR, (WORD)hDC, + MAKELONG(hwnd, CTLCOLOR_LISTBOX)); + if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); + GetClientRect(hwnd, &rect); + GetClientRect(hwnd, &rect2); + FillRect(hDC, &rect, hBrush); + if (lppop->nItems == 0) goto EndOfPaint; + lpitem = lppop->firstItem->next; + if (lpitem == NULL) goto EndOfPaint; + for(i = 0; i < lppop->nItems; i++) { + if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { + rect2.bottom = rect2.top + 3; + CopyRect(&lpitem->rect, &rect2); + hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN)); + MoveTo(hDC, rect2.left, rect2.top + 1); + LineTo(hDC, rect2.right, rect2.top + 1); + SelectObject(hDC, hOldPen); + rect2.top += 3; + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD(lpitem->item_text); + rect2.bottom = rect2.top + bm.bmHeight; + CopyRect(&lpitem->rect, &rect2); + 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); + rect2.top += bm.bmHeight; + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + rect2.bottom = rect2.top + 15; + CopyRect(&lpitem->rect, &rect2); + TextOut(hDC, rect2.left + 5, rect2.top + 2, + (char *)lpitem->item_text, strlen((char *)lpitem->item_text)); + rect2.top += 15; + } + if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) { + CopyRect(&rect3, &rect2); + rect3.left = rect3.right - rect3.bottom + rect3.top; + InvertRect(hDC, &rect3); + } + if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) { + CopyRect(&rect3, &rect2); + rect3.left = rect3.right - rect3.bottom + rect3.top; + FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH)); + } + if (lpitem->next == NULL) goto EndOfPaint; + lpitem = (LPMENUITEM)lpitem->next; + } +EndOfPaint: + EndPaint( hwnd, &ps ); +} + + + +LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet) +{ + WND *wndPtr; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + RECT rect, rect2; + HBITMAP hBitMap; + BITMAP bm; + UINT i; + lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); + if (lppop == NULL) return NULL; + GetClientRect(hwnd, &rect); + if (lppop->nItems == 0) return NULL; + lpitem = lppop->firstItem->next; + if (lpitem == NULL) return NULL; + for(i = 0; i < lppop->nItems; i++) { + if (y < rect2.top) return NULL; + if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { + rect2.bottom = rect2.top + 3; + rect2.top += 3; + } + if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) { + hBitMap = (HBITMAP)LOWORD(lpitem->item_text); + GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); + rect2.bottom = rect2.top + bm.bmHeight; + rect2.top += bm.bmHeight; + } + if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) && + ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && + ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) { + rect2.bottom = rect2.top + 15; + rect2.top += 15; + } + if (y < rect2.bottom) { + if (lpRet != NULL) *lpRet = i; + return lpitem; + } + if (lpitem->next == NULL) return NULL; + lpitem = (LPMENUITEM)lpitem->next; + } + return NULL; +} + + + +LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos) +{ + LPMENUITEM lpitem; + int i; + if (menu == NULL) return NULL; + lpitem = menu->firstItem; + for (i = 0; i < menu->nItems; i++) { + if (lpitem->next == NULL) return NULL; + lpitem = (LPMENUITEM)lpitem->next; + if (i == nPos) return(lpitem); + } + return NULL; +} + + /********************************************************************** * MENU_CheckWidget */ @@ -565,3 +866,316 @@ LoadMenu(HINSTANCE instance, char *menu_name) return GlobalHandleFromPointer(menu->firstItem); } + + +/********************************************************************** + * CheckMenuItem [USER.154] + */ +BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) +{ +} + + +/********************************************************************** + * EnableMenuItem [USER.155] + */ +BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags) +{ +} + + +/********************************************************************** + * InsertMenu [USER.410] + */ +BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) +{ + WND *wndPtr; + LPPOPUPMENU menu; + HANDLE hNewItem; + LPMENUITEM lpitem, lpitem2; + int i; +#ifdef DEBUG_MENU + 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->next == NULL) 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) return FALSE; + lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); + if (lpitem2 == 0) { + GlobalFree(hNewItem); + return FALSE; + } + lpitem2->item_flags = wFlags; + lpitem2->item_id = wItemID; + if ((wFlags & MF_STRING) == MF_STRING) { + lpitem2->item_text = lpNewItem; + } + 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; + lpitem2->w = NULL; + lpitem2->menu_w = NULL; + menu->nItems++; + return TRUE; +} + + +/********************************************************************** + * AppendMenu [USER.411] + */ +BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem) +{ + WND *wndPtr; + LPPOPUPMENU menu; + HANDLE hNewItem; + LPMENUITEM lpitem, lpitem2; +#ifdef DEBUG_MENU + printf("AppendMenu (%04X, %04X, %04X, %08X) !\n", + hMenu, wFlags, wItemID, lpNewItem); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + lpitem = menu->firstItem; + while (lpitem->next != NULL) { + lpitem = (LPMENUITEM)lpitem->next; + printf("AppendMenu // during loop items !\n"); + } + printf("AppendMenu // after loop items !\n"); + hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hNewItem == 0) return FALSE; + lpitem2 = (LPMENUITEM)GlobalLock(hNewItem); + if (lpitem2 == 0) { + GlobalFree(hNewItem); + return FALSE; + } + lpitem2->item_flags = wFlags; + lpitem2->item_id = wItemID; + if ((wFlags & MF_STRING) == MF_STRING) { + lpitem2->item_text = lpNewItem; + } + else + lpitem2->item_text = lpNewItem; + lpitem->next = lpitem2; + lpitem2->prev = lpitem; + lpitem2->next = NULL; + lpitem2->child = NULL; + lpitem2->parent = NULL; + lpitem2->w = NULL; + lpitem2->menu_w = NULL; + menu->nItems++; + return TRUE; +} + + +/********************************************************************** + * RemoveMenu [USER.412] + */ +BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags) +{ + WND *wndPtr; + LPPOPUPMENU menu; + LPMENUITEM lpitem; + int i; +#ifdef DEBUG_MENU + 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->next == NULL) break; + lpitem = (LPMENUITEM)lpitem->next; + if (i == nPos) { + lpitem->prev->next = lpitem->next; + lpitem->next->prev = lpitem->prev; + GlobalFree(HIWORD(lpitem)); + return(TRUE); + } + printf("RemoveMenu // during loop items !\n"); + } + printf("RemoveMenu // after loop items !\n"); + return FALSE; +} + + +/********************************************************************** + * DeleteMenu [USER.413] + */ +BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags) +{ +#ifdef DEBUG_MENU + printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags); +#endif + return TRUE; +} + + +/********************************************************************** + * ModifyMenu [USER.414] + */ +BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem) +{ +#ifdef DEBUG_MENU + printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n", + hMenu, nPos, wFlags, wItemID, lpNewItem); +#endif + return TRUE; +} + + +/********************************************************************** + * CreatePopupMenu [USER.415] + */ +HMENU CreatePopupMenu() +{ + HANDLE hItem; + HMENU hMenu; + LPPOPUPMENU menu; +#ifdef DEBUG_MENU + printf("CreatePopupMenu !\n"); +#endif + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU)); + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) { + GlobalFree(hMenu); + return 0; + } + hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hItem == 0) { + GlobalFree(hMenu); + return 0; + } + menu->nItems = 0; + menu->firstItem = (LPMENUITEM)GlobalLock(hItem); + menu->ownerWnd = 0; + menu->hWnd = 0; + + menu->firstItem->next = NULL; + menu->firstItem->prev = NULL; + menu->firstItem->child = NULL; + menu->firstItem->parent = NULL; + menu->firstItem->item_flags = 0; + menu->firstItem->item_id = 0; + menu->firstItem->item_text = NULL; + menu->firstItem->w = NULL; + menu->firstItem->menu_w = NULL; + return hMenu; +} + + +/********************************************************************** + * TrackPopupMenu [USER.414] + */ +BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, + short nReserved, HWND hWnd, LPRECT lpRect) +{ + WND *wndPtr; + LPPOPUPMENU menu; +#ifdef DEBUG_MENU + printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n", + hMenu, wFlags, x, y, nReserved, hWnd, lpRect); +#endif + menu = (LPPOPUPMENU) GlobalLock(hMenu); + if (menu == NULL) return FALSE; + wndPtr = WIN_FindWndPtr(hWnd); + menu->ownerWnd = hWnd; + if (menu->hWnd == NULL) { + menu->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE, + x, y, 100, 150, hWnd, 0, wndPtr->hInstance, (LPSTR)menu); + } + else + ShowWindow(menu->hWnd, SW_SHOW); + return TRUE; +} + + +/********************************************************************** + * CreateMenu [USER.151] + */ +HMENU CreateMenu() +{ + HANDLE hItem; + HMENU hMenu; + LPMENUBAR menu; +#ifdef DEBUG_MENU + printf("CreateMenu !\n"); +#endif + hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUBAR)); + menu = (LPMENUBAR) GlobalLock(hMenu); + if (menu == NULL) { + GlobalFree(hMenu); + return 0; + } + hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM)); + if (hItem == 0) { + GlobalFree(hMenu); + return 0; + } + menu->menuDescription = 0; + menu->nItems = 0; + menu->parentWidget = NULL; + menu->firstItem = (LPMENUITEM) GlobalLock(hItem); + menu->ownerWnd = 0; + menu->menuBarWidget = NULL; + + menu->firstItem->next = NULL; + menu->firstItem->prev = NULL; + menu->firstItem->child = NULL; + menu->firstItem->parent = NULL; + menu->firstItem->item_flags = 0; + menu->firstItem->item_id = 0; + menu->firstItem->item_text = NULL; + menu->firstItem->w = NULL; + menu->firstItem->menu_w = NULL; + return hMenu; +} + + +/********************************************************************** + * DestroyMenu [USER.152] + */ +BOOL DestroyMenu(HMENU hMenu) +{ + LPPOPUPMENU lppop; + LPMENUITEM lpitem, lpitem2; +#ifdef DEBUG_MENU + 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->next != NULL) { +#ifdef DEBUG_MENU + 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; + } + GlobalFree(hMenu); +#ifdef DEBUG_MENU + printf("DestroyMenu (%04X) // End !\n", hMenu); +#endif + return TRUE; +} + + diff --git a/controls/scroll.c b/controls/scroll.c index fd8e45a24ee..9cfa55010d1 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -17,7 +17,8 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include "scroll.h" #include "heap.h" #include "win.h" -#include "dirent.h" +#include <sys/types.h> +#include <dirent.h> #include <sys/stat.h> LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr); @@ -26,50 +27,10 @@ void StdDrawScrollBar(HWND hwnd); int CreateScrollBarStruct(HWND hwnd); -void SCROLLBAR_CreateScrollBar(LPSTR className, LPSTR scrollLabel, HWND hwnd) -{ - WND *wndPtr = WIN_FindWndPtr(hwnd); - WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); - DWORD style; - char widgetName[15]; - -#ifdef DEBUG_SCROLLBAR - printf("scroll: label = %s, x = %d, y = %d\n", scrollLabel, - wndPtr->rectClient.left, wndPtr->rectClient.top); - printf(" width = %d, height = %d\n", - wndPtr->rectClient.right - wndPtr->rectClient.left, - wndPtr->rectClient.bottom - wndPtr->rectClient.top); -#endif - - if (!wndPtr) - return; - - style = wndPtr->dwStyle & 0x0000FFFF; -/* - if ((style & SBS_NOTIFY) == SBS_NOTIFY) -*/ - sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); - wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, - compositeWidgetClass, - parentPtr->winWidget, - XtNx, wndPtr->rectClient.left, - XtNy, wndPtr->rectClient.top, - XtNwidth, wndPtr->rectClient.right - - wndPtr->rectClient.left, - XtNheight, wndPtr->rectClient.bottom - - wndPtr->rectClient.top, - NULL ); - GlobalUnlock(hwnd); - GlobalUnlock(wndPtr->hwndParent); -} - - - /*********************************************************************** * WIDGETS_ScrollBarWndProc */ -LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ) +LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WORD wRet; short x, y; @@ -169,8 +130,11 @@ LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, break; case WM_KEYDOWN: - printf("ScrollBar WM_KEYDOWN wParam %X !\n", wParam); - break; + case WM_KEYUP: + case WM_CHAR: + lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); + case WM_PAINT: StdDrawScrollBar(hwnd); break; @@ -330,36 +294,36 @@ int CreateScrollBarStruct(HWND hwnd) wndPtr->hInstance, 0L); } if (lphs->MaxPix < 1) lphs->MaxPix = 1; + if (wndPtr->hCursor == (HCURSOR)NULL) + wndPtr->hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW); return TRUE; } - -int GetScrollPos(HWND hwnd, int nBar) -{ - LPHEADSCROLL lphs; - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return 0; - return lphs->CurVal; -} - - - -void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax) +/************************************************************************* + * GetScrollWindowHandle + */ +HWND GetScrollWindowHandle(HWND hWnd, int nBar) { - LPHEADSCROLL lphs; - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) return; - *lpMin = lphs->MinVal; - *lpMax = lphs->MaxVal; + WND *wndPtr; + if (nBar != SB_CTL) { + wndPtr = WIN_FindWndPtr(hWnd); + if (nBar == SB_VERT) return wndPtr->hWndVScroll; + if (nBar == SB_HORZ) return wndPtr->hWndHScroll; + return (HWND)NULL; + } + return hWnd; } - +/************************************************************************* + * SetScrollPos [USER.62] + */ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) { int nRet; LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); lphs = ScrollBarGetStorageHeader(hwnd); if (lphs == NULL) return 0; nRet = lphs->CurVal; @@ -383,9 +347,27 @@ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) +/************************************************************************* + * GetScrollPos [USER.63] + */ +int GetScrollPos(HWND hwnd, int nBar) +{ + LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); + lphs = ScrollBarGetStorageHeader(hwnd); + if (lphs == NULL) return 0; + return lphs->CurVal; +} + + + +/************************************************************************* + * SetScrollRange [USER.64] + */ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) { LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); lphs = ScrollBarGetStorageHeader(hwnd); if (lphs == NULL) return; lphs->MinVal = (short)MinPos; @@ -406,5 +388,50 @@ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) +/************************************************************************* + * GetScrollRange [USER.65] + */ +void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax) +{ + LPHEADSCROLL lphs; + hwnd = GetScrollWindowHandle(hwnd, nBar); + lphs = ScrollBarGetStorageHeader(hwnd); + if (lphs == NULL) return; + *lpMin = lphs->MinVal; + *lpMax = lphs->MaxVal; +} + + + +/************************************************************************* + * ShowScrollBar [USER.267] + */ +void ShowScrollBar(HWND hWnd, WORD wBar, BOOL bFlag) +{ + WND *wndPtr; +#ifdef DEBUG_SCROLL + printf("ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n", hWnd, wBar, bFlag); +#endif + if (wBar == SB_CTL) { + if (bFlag) + ShowWindow(hWnd, SW_SHOW); + else + ShowWindow(hWnd, SW_HIDE); + return; + } + wndPtr = WIN_FindWndPtr(hWnd); + if ((wBar == SB_VERT) || (wBar == SB_BOTH)) { + if (bFlag) + ShowWindow(wndPtr->hWndVScroll, SW_SHOW); + else + ShowWindow(wndPtr->hWndVScroll, SW_HIDE); + } + if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) { + if (bFlag) + ShowWindow(wndPtr->hWndHScroll, SW_SHOW); + else + ShowWindow(wndPtr->hWndHScroll, SW_HIDE); + } +} diff --git a/controls/static.c b/controls/static.c index 692813973d8..558110b6659 100644 --- a/controls/static.c +++ b/controls/static.c @@ -109,6 +109,18 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam) InvalidateRect(hWnd, NULL, TRUE); break; + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSEMOVE: + return(SendMessage(wndPtr->hwndParent, uMsg, wParam, lParam)); + default: lResult = DefWindowProc(hWnd, uMsg, wParam, lParam); break; diff --git a/controls/widgets.c b/controls/widgets.c index 673348685a9..c88ac448a07 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -13,23 +13,28 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; LONG ButtonWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG StaticWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); - -LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ); -LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ); -LONG COMBOBOX_ComboBoxWndProc( HWND hwnd, WORD message, - WORD wParam, LONG lParam ); +LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG ListBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); static WNDCLASS WIDGETS_BuiltinClasses[] = { - { 0, (LONG(*)())ButtonWndProc, 0, 2, 0, 0, 0, 0, NULL, "BUTTON" }, - { 0, (LONG(*)())StaticWndProc, 0, 0, 0, 0, 0, 0, NULL, "STATIC" }, - { 0, (LONG(*)())SCROLLBAR_ScrollBarWndProc, 0, 8, 0, 0, 0, 0, NULL, "SCROLLBAR" }, - { 0, (LONG(*)())LISTBOX_ListBoxWndProc, 0, 8, 0, 0, 0, 0, NULL, "LISTBOX" }, - { 0, (LONG(*)())COMBOBOX_ComboBoxWndProc, 0, 8, 0, 0, 0, 0, NULL, "COMBOBOX" }, - { 0, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } + { CS_GLOBALCLASS, (LONG(*)())ButtonWndProc, 0, 2, + 0, 0, 0, 0, NULL, "BUTTON" }, + { CS_GLOBALCLASS, (LONG(*)())StaticWndProc, 0, 0, + 0, 0, 0, 0, NULL, "STATIC" }, + { CS_GLOBALCLASS, (LONG(*)())ScrollBarWndProc, 0, 8, + 0, 0, 0, 0, NULL, "SCROLLBAR" }, + { CS_GLOBALCLASS, (LONG(*)())ListBoxWndProc, 0, 8, + 0, 0, 0, 0, NULL, "LISTBOX" }, + { CS_GLOBALCLASS, (LONG(*)())ComboBoxWndProc, 0, 8, + 0, 0, 0, 0, NULL, "COMBOBOX" }, + { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8, + 0, 0, 0, 0, NULL, "POPUPMENU" }, + { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, + 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } }; #define NB_BUILTIN_CLASSES \ diff --git a/debugger/Imakefile b/debugger/Imakefile new file mode 100644 index 00000000000..4b4ed0442c9 --- /dev/null +++ b/debugger/Imakefile @@ -0,0 +1,62 @@ +#include "../Wine.tmpl" + +#define IHavSubDirs +#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' + +MODULE = debugger + +DEFINES = -DUSE_READLINE + +SUBDIRS = readline + +/* Quick and dirt hack, since i386 is defined as 1. sigh */ +#define temp i386 +#undef i386 + +SRCS = \ + dbg.tab.c \ + hash.c \ + lex.yy.c \ + info.c \ + i386-pinsn.c + +OBJS = \ + dbg.tab.o \ + hash.o \ + lex.yy.o \ + info.o \ + i386-pinsn.o + +#define i386 temp +#undef temp + +/* + * All the SUBDIR stuff + */ +MakeSubdirs($(SUBDIRS)) +MakefileSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +CleanSubdirs($(SUBDIRS)) +IncludesSubdirs($(SUBDIRS)) + +/* + * The main act + */ +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) + +depend:: dbg.tab.c dbg.tab.h lex.yy.c + +DependTarget() + +includes:: + +install:: + +clean:: + $(RM) lex.yy.c dbg.tab* y.tab.c + +dbg.tab.c dbg.tab.h: dbg.y + $(YACC) -b dbg -d dbg.y + +lex.yy.c: debug.l + $(LEX) -I debug.l diff --git a/debugger/readline/Imakefile b/debugger/readline/Imakefile new file mode 100644 index 00000000000..817f4afea06 --- /dev/null +++ b/debugger/readline/Imakefile @@ -0,0 +1,25 @@ +#include "../../Wine.tmpl" + +MODULE = readline + +YACC = yacc -b dbg -d + +DEFINES = -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX + +SRCS = \ + complete.c \ + editline.c \ + sysunix.c + +OBJS = \ + complete.o \ + editline.o \ + sysunix.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/etc/Imakefile b/etc/Imakefile new file mode 100644 index 00000000000..b39880926cc --- /dev/null +++ b/etc/Imakefile @@ -0,0 +1,11 @@ +#include "../Wine.tmpl" + +MODULE = etc + +AllTarget() + +depend:: + +CleanTarget() + +includes:: diff --git a/etc/Makefile b/etc/Makefile new file mode 100644 index 00000000000..87948b04a9d --- /dev/null +++ b/etc/Makefile @@ -0,0 +1,358 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and <Imakefile> +# $XFree86: mit/config/Imake.tmpl,v 1.17 1993/06/03 15:26:36 dawes Exp $ +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate <vendor>.cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit x386.cf to change + +# $XFree86: mit/config/x386.cf,v 1.90 1993/06/04 16:02:50 dawes Exp $ +# platform: $XConsortium: x386.cf,v 1.7 91/08/16 19:30:10 gildea Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version definition +# $XFree86: mit/config/xf86_vers.def,v 1.5 1993/06/01 09:12:47 dawes Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version: 1300 +# ------------------------------------------------------------------------- + +# $XFree86: mit/config/lnuxLib.rules,v 1.2 1993/06/02 13:48:12 dawes Exp $ + +DLL_BINDIR = /usr/dll/bin + +# operating system: Linux + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + + SHELL = /bin/sh + + TOP = ../. + CURRENT_DIR = ./etc + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = gcc + AS = as + + LEX = flex + + YACC = bison -y + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = /lib/cpp $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MAKE = make + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = psroff + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + OS_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = + SHLIBDEF = + + PROTO_DEFINES = -DFUNCPROTO=11 -DNARROWPROTO + + INSTPGMFLAGS = -s + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -s -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -s -m 4755 + + PROJECTROOT = /usr/X386 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O2 + CCOPTIONS = -m486 -DNO_ASM -fwritable-strings + ANSICCOPTIONS = + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(OS_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -r + DEPENDFLAGS = + + MACROFILE = x386.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XFree86: mit/config/Project.tmpl,v 1.13 1993/03/27 03:32:45 dawes Exp $ +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +_percentC_ = %C + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/X386/lib + BINDIR = /usr/X386/bin + INCROOT = /usr/X386/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/X386/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = 1x + LIBMANSUFFIX = 3x + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + LINKKITDIR = $(USRLIBDIR)/Server + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XFree86: mit/config/lnuxLib.tmpl,v 1.1 1993/04/16 14:06:06 dawes Exp $ + +SHLIBLDFLAGS = +PICFLAGS = -B/usr/dll/jump/ + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = + XMULIB = -lXmu + + DEPXTOOLLIB = + XTOOLLIB = -lXt + + DEPXAWLIB = + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPXTESTLIB = + XTESTLIB = -lXtst + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 3.0.1 + SOXTREV = 3.0.1 + SOXAWREV = 3.0.1 + SOOLDXREV = 3.0.1 + SOXMUREV = 3.0.1 + SOXEXTREV = 3.0.1 + SOXINPUTREV = 3.0.1 + SOPEXREV = 1.0.1 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPOLDXLIB = $(USRLIBDIR)/liboldX.a + OLDXLIB = -loldX + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# $XFree86: mit/config/Imake.rules,v 1.9 1993/03/23 12:56:27 dawes Exp $ +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +# $Id$ + +INCLUDES = -I$(TOP)/include + +# Imake rules go here + +# First, dll description to files etc + +MODULE = etc + +all:: + +depend:: + +clean:: + $(RM_CMD) "#"* + +includes:: + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +install.linkkit:: + @echo "install.linkkit in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/if1632/Imakefile b/if1632/Imakefile new file mode 100644 index 00000000000..8c11afdfe95 --- /dev/null +++ b/if1632/Imakefile @@ -0,0 +1,37 @@ +#include "../Wine.tmpl" + +MODULE = if1632 + +SRCS = \ + call.S \ + callback.c \ + relay.c + +OBJS = \ + call.o \ + callback.o \ + relay.o + +/* + * If you add a new spec file, copy one of these lines + */ +MakeDllFromSpec(gdi,$(TOP)/$(MODULE)) +MakeDllFromSpec(kernel,$(TOP)/$(MODULE)) +MakeDllFromSpec(keyboard,$(TOP)/$(MODULE)) +MakeDllFromSpec(shell,$(TOP)/$(MODULE)) +MakeDllFromSpec(sound,$(TOP)/$(MODULE)) +MakeDllFromSpec(unixlib,$(TOP)/$(MODULE)) +MakeDllFromSpec(user,$(TOP)/$(MODULE)) +MakeDllFromSpec(win87em,$(TOP)/$(MODULE)) + +/* + * Yes I know *.o is not veru clever, but can you do it cleaner ? + */ +WineRelocatableTarget($(TOP)/$(MODULE),*.o,$(OBJS)) + +clean:: + $(RM) dll* + +depend:: + +includes:: diff --git a/if1632/callback.c b/if1632/callback.c index 1852185f8d5..82c71de459b 100644 --- a/if1632/callback.c +++ b/if1632/callback.c @@ -7,7 +7,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "segmem.h" #include <setjmp.h> -extern unsigned short SelectorOwners[]; +extern SEGDESC Segments[]; extern unsigned short IF1632_Saved16_ss; extern unsigned long IF1632_Saved16_ebp; extern unsigned long IF1632_Saved16_esp; @@ -56,7 +56,7 @@ FindDataSegmentForCode(unsigned long csip) unsigned int seg_idx; seg_idx = (unsigned short) (csip >> 19); - return SelectorOwners[seg_idx]; + return Segments[seg_idx].owner; } /********************************************************************** diff --git a/if1632/gdi.spec b/if1632/gdi.spec index a1fc5c59847..f2e2baae437 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -43,6 +43,11 @@ length 490 33 pascal TextOut(word s_word s_word ptr word) TextOut(1 2 3 4 5) 34 pascal BitBlt( word s_word s_word s_word s_word word s_word s_word long) BitBlt(1 2 3 4 5 6 7 8 9) +35 pascal StrechBlt( word s_word s_word s_word s_word word s_word s_word s_word s_word long) + StrechBlt(1 2 3 4 5 6 7 8 9 10 11) + +36 pascal Polygon (word ptr word) Polygon (1 2 3) +37 pascal Polyline (word ptr word) Polyline (1 2 3) 39 pascal RestoreDC(word s_word) RestoreDC(1 2) 40 pascal FillRgn(word word word) FillRgn(1 2 3) 43 pascal PaintRgn(word word) PaintRgn(1 2) diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 142f4512f59..86a15087b2d 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -28,6 +28,8 @@ length 415 24 pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1) 25 pascal GlobalCompact(long) GlobalCompact(1) 30 pascal WaitEvent(word) KERNEL_WaitEvent(1) +34 pascal SetTaskQueue(word word) SetTaskQueue(1 2) +35 pascal GetTaskQueue(word) GetTaskQueue(1) 49 pascal GetModuleFileName(word ptr s_word) KERNEL_GetModuleFileName(1 2 3) 50 pascal GetProcAddress(word ptr) GetProcAddress(1 2) 51 pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2) @@ -43,6 +45,8 @@ length 415 74 pascal OpenFile(ptr ptr word) KERNEL_OpenFile(1 2 3) 81 pascal _lclose(word) KERNEL__lclose(1) 82 pascal _lread(word ptr word) KERNEL__lread(1 2 3) +83 pascal _lcreate(ptr word) KERNEL__lcreate(1 2) +84 pascal _llseek(word long word) KERNEL__llseek(1 2 3) 85 pascal _lopen(ptr word) KERNEL__lopen(1 2) 86 pascal _lwrite(word ptr word) KERNEL__lwrite(1 2 3) 88 pascal lstrcpy(ptr ptr) lstrcpy(1 2) @@ -51,11 +55,14 @@ length 415 91 register InitTask(word word word word word word word word word word) KERNEL_InitTask() +92 pascal GetTempDrive(byte) GetTempDrive(1) 95 pascal LoadLibrary(ptr) LoadLibrary(1) 96 pascal FreeLibrary(word) FreeLibrary(1) +97 pascal GetTempFileName(byte ptr word ptr) GetTempDrive(1 2 3 4) 102 register DOS3Call(word word word word word word word word word word) KERNEL_DOS3Call() +107 pascal SetErrorMode(word) SetErrorMode(1) 111 pascal GlobalWire(word) GlobalLock(1) 112 pascal GlobalUnWire(word) GlobalUnlock(1) 115 pascal OutputDebugString(ptr) OutputDebugString(1) @@ -68,6 +75,9 @@ length 415 WritePrivateProfileString(1 2 3 4) 131 pascal GetDOSEnvironment() GetDOSEnvironment() 132 return GetWinFlags 0 0x413 +134 pascal GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2) +135 pascal GetSystemDirectory(ptr word) GetSystemDirectory(1 2) +136 pascal GetDriveType(byte) GetWindowsDirectory(1) 154 return GlobalNotify 4 0 163 pascal GlobalLRUOldest(word) ReturnArg(1) 164 pascal GlobalLRUNewest(word) ReturnArg(1) diff --git a/if1632/relay.c b/if1632/relay.c index 859144c7274..d6ad3353fdb 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -173,7 +173,7 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) case DLL_ARGTYPE_FARPTR: ip = (int *) ((char *) arg_ptr + offset); if (*ip & 0xffff0000) - arg_table[i] = SAFEMAKEPTR((unsigned) *ip >> 16, *ip); + arg_table[i] = FIXPTR(*ip); else arg_table[i] = *ip; break; diff --git a/if1632/user.spec b/if1632/user.spec index bf032d68149..86682f18c6e 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -13,12 +13,16 @@ length 540 13 pascal GetTickCount() GetTickCount() 14 return GetTimerResolution 0 1000 15 pascal GetCurrentTime() GetTickCount() +16 pascal ClipCursor(ptr) ClipCursor(1) +17 pascal GetCursorPos(ptr) GetCursorPos(1) 18 pascal SetCapture(word) SetCapture(1) 19 pascal ReleaseCapture() ReleaseCapture() 20 pascal SetDoubleClickTime(word) SetDoubleClickTime(1) 21 pascal GetDoubleClickTime() GetDoubleClickTime() 22 pascal SetFocus(word) SetFocus(1) 23 pascal GetFocus() GetFocus() +28 pascal ClientToScreen(word ptr) ClientToScreen(1 2) +29 pascal ScreenToClient(word ptr) ScreenToClient(1 2) 31 pascal IsIconic(word) IsIconic(1) 32 pascal GetWindowRect(word ptr) GetWindowRect(1 2) 33 pascal GetClientRect(word ptr) GetClientRect(1 2) @@ -41,13 +45,18 @@ length 540 56 pascal MoveWindow(word word word word word word) MoveWindow(1 2 3 4 5 6) 57 pascal RegisterClass(ptr) RegisterClass(1) +58 pascal GetClassName(word ptr word) GetClassName(1 2 3) 61 pascal ScrollWindow(word s_word s_word ptr ptr) ScrollWindow(1 2 3 4 5) 62 pascal SetScrollPos(word word word word) SetScrollPos(1 2 3 4) +63 pascal GetScrollPos(word word) GetScrollPos(1 2) 64 pascal SetScrollRange(word word word word word) SetScrollRange(1 2 3 4 5) +65 pascal GetScrollRange(word word ptr ptr) GetScrollRange(1 2 3 4) 66 pascal GetDC(word) GetDC(1) +67 pascal GetWindowDC(word) GetWindowDC(1) 68 pascal ReleaseDC(word word) ReleaseDC(1 2) -69 pascal SetCursor(word word) SetCursor(1 2) -71 pascal ShowCursor(word word) ShowCursor(1 2) +69 pascal SetCursor(word) SetCursor(1) +70 pascal SetCursorPos(word word) SetCursorPos(1 2) +71 pascal ShowCursor(word) ShowCursor(1) 72 pascal SetRect(ptr s_word s_word s_word s_word) SetRect(1 2 3 4 5) 73 pascal SetRectEmpty(ptr) SetRectEmpty(1) 74 pascal CopyRect(ptr ptr) CopyRect(1 2) @@ -67,7 +76,7 @@ length 540 89 pascal CreateDialog(word ptr word ptr) CreateDialog(1 2 3 4) 90 pascal IsDialogMessage(word ptr) IsDialogMessage(1 2) 91 pascal GetDlgItem(word word) GetDlgItem(1 2) -92 pascal SetDlgItemText(word ptr) SetDlgItemText(1 2) +92 pascal SetDlgItemText(word word ptr) SetDlgItemText(1 2 3) 93 pascal GetDlgItemText(word word ptr word) GetDlgItemText(1 2 3 4) 94 pascal SetDlgItemInt(word word word word) SetDlgItemInt(1 2 3 4) 95 pascal GetDlgItemInt(word word ptr word) GetDlgItemInt(1 2 3 4) @@ -106,9 +115,18 @@ length 540 136 pascal SetWindowLong(word s_word long) SetWindowLong(1 2 3) 150 pascal LoadMenu(word ptr) LoadMenu(1 2) 151 pascal CreateMenu() CreateMenu() -154 pascal CheckMenu(word word word) CheckMenu(1 2 3) +152 pascal DestroyMenu(word) DestroyMenu(1) +154 pascal CheckMenuItem(word word word) CheckMenuItem(1 2 3) +155 pascal EnableMenuItem(word word word) EnableMenuItem(1 2 3) 157 pascal GetMenu(word) GetMenu(1) 158 pascal SetMenu(word word) SetMenu(1 2) +163 pascal CreateCaret(word word word word) CreateCaret(1 2 3 4) +164 pascal DestroyCaret() DestroyCaret() +165 pascal SetCaretPos(word word) SetCaretPos(1 2) +166 pascal HideCaret(word) HideCaret(1) +167 pascal ShowCaret(word) ShowCaret(1) +166 pascal SetCaretBlinkTime(word) SetCaretBlinkTime(1) +169 pascal GetCaretBlinkTime() GetCaretBlinkTime() 171 pascal WinHelp(word word long) WinHelp(1 2 3) 173 pascal LoadCursor(word ptr) LoadCursor(1 2) 174 pascal LoadIcon(word ptr) LoadIcon(1 2) @@ -119,7 +137,24 @@ length 540 180 pascal GetSysColor(word) GetSysColor(1) 181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3) 182 pascal KillSystemTimer(word word) KillSystemTimer(1 2) +183 pascal GetCaretPos(ptr) GetCaretPos(1) 190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3) +200 pascal OpenComm(ptr word word) OpenComm(1 2 3) +201 pascal SetCommState(ptr) SetCommState(1) +202 pascal GetCommState(word ptr) GetCommState(1 2) +203 pascal GetCommError(word ptr) GetCommError(1 2) +204 pascal ReadComm(word ptr word) ReadComm(1 2 3) +205 pascal WriteComm(word ptr word) WriteComm(1 2 3) +206 pascal TransmitCommChar(word byte) TransmitCommChar (1 2) +207 pascal CloseComm(word) CloseComm(1) +208 pascal SetCommEventMask(word word) SetCommEventMask(1 2) +209 pascal GetCommEventMask(word word) GetCommEventMask(1 2) +210 pascal SetCommBreak(word) SetCommBreak(1) +211 pascal ClearCommBreak(word) ClearCommBreak(1) +212 pascal UngetCommChar(word byte) UngetCommChar(1 2) +213 pascal BuildCommDCB(ptr ptr) BuildCommDCB(1 2) +214 pascal EscapeCommFunction(word word) EscapeCommFunction(1 2) +215 pascal FlushComm(word word) FlushComm(1 2) 218 pascal DialogBoxIndirect(word word word ptr) DialogBoxIndirect(1 2 3 4) 219 pascal CreateDialogIndirect(word ptr word ptr) CreateDialogIndirect(1 2 3 4) @@ -131,6 +166,7 @@ length 540 230 pascal GetNextWindow(word word) GetNextWindow(1 2) 232 pascal SetWindowPos(word word word word word word word) SetWindowPos(1 2 3 4 5 6 7) +236 pascal GetCapture() GetCapture() 237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3) 239 pascal DialogBoxParam(word ptr word ptr long) DialogBoxParam(1 2 3 4 5) 240 pascal DialogBoxIndirectParam(word word word ptr long) @@ -140,9 +176,14 @@ length 540 242 pascal CreateDialogIndirectParam(word ptr word ptr long) CreateDialogIndirectParam(1 2 3 4 5) 244 pascal EqualRect(ptr ptr) EqualRect(1 2) +258 pascal MapWindowPoints(word word ptr word) MapWindowPoints(1 2 3 4) 262 pascal GetWindow(word word) GetWindow(1 2) 266 pascal SetMessageQueue(word) SetMessageQueue(1) +267 pascal ShowScrollBar(word word word) ShowScrollBar(1 2 3) +272 pascal IsZoomed(word) IsZoomed(1) 277 pascal GetDlgCtrlID(word) GetDlgCtrlID(1) +282 pascal SelectPalette(word word word) SelectPalette(1 2 3) +283 pascal RealizePalette(word) RealizePalette(1) 286 pascal GetDesktopWindow() GetDesktopWindow() 288 pascal GetMessageExtraInfo() GetMessageExtraInfo() 319 pascal ScrollWindowEx(word s_word s_word ptr ptr word ptr word) @@ -151,9 +192,20 @@ length 540 325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5) 334 pascal GetQueueStatus(word) GetQueueStatus(1) 335 pascal GetInputState() GetInputState() +359 pascal GetDCEx(word word long) GetDCEx(1 2 3) 373 pascal SubtractRect(ptr ptr ptr) SubtractRect(1 2 3) 403 pascal UnregisterClass(ptr word) UnregisterClass(1 2) +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) +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) +413 pascal DeleteMenu(word word word) DeleteMenu(1 2 3) +414 pascal ModifyMenu(word word word word ptr) ModifyMenu(1 2 3 4 5) +415 pascal CreatePopupMenu() CreatePopupMenu() +416 pascal TrackPopupMenu(word word word word word word ptr) + TrackPopupMenu(1 2 3 4 5 6 7) 420 pascal wsprintf(ptr ptr) wsprintf(1 2) 421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3) 430 pascal lstrcmp(ptr ptr) lstrcmp(1 2) diff --git a/include/Imakefile b/include/Imakefile new file mode 100644 index 00000000000..4e3798738ac --- /dev/null +++ b/include/Imakefile @@ -0,0 +1,38 @@ +#include "../Wine.tmpl" + +MODULE = include + +HEADERS = \ + atom.h \ + callback.h \ + class.h \ + combo.h \ + cursor.h \ + dce.h \ + dialog.h \ + dlls.h \ + files.h \ + gdi.h \ + heap.h \ + icon.h \ + int21.h \ + listbox.h \ + menu.h \ + message.h \ + neexe.h \ + prototypes.h \ + regfunc.h \ + scroll.h \ + segmem.h \ + user.h \ + win.h \ + windows.h \ + wine.h + +AllTarget() + +depend:: + +CleanTarget() + +includes:: diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 00000000000..97bc6f4a06b --- /dev/null +++ b/include/Makefile @@ -0,0 +1,360 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and <Imakefile> +# $XFree86: mit/config/Imake.tmpl,v 1.17 1993/06/03 15:26:36 dawes Exp $ +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate <vendor>.cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit x386.cf to change + +# $XFree86: mit/config/x386.cf,v 1.90 1993/06/04 16:02:50 dawes Exp $ +# platform: $XConsortium: x386.cf,v 1.7 91/08/16 19:30:10 gildea Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version definition +# $XFree86: mit/config/xf86_vers.def,v 1.5 1993/06/01 09:12:47 dawes Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version: 1300 +# ------------------------------------------------------------------------- + +# $XFree86: mit/config/lnuxLib.rules,v 1.2 1993/06/02 13:48:12 dawes Exp $ + +DLL_BINDIR = /usr/dll/bin + +# operating system: Linux + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + + SHELL = /bin/sh + + TOP = ../. + CURRENT_DIR = ./include + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = gcc + AS = as + + LEX = flex + + YACC = bison -y + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = /lib/cpp $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MAKE = make + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = psroff + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + OS_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = + SHLIBDEF = + + PROTO_DEFINES = -DFUNCPROTO=11 -DNARROWPROTO + + INSTPGMFLAGS = -s + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -s -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -s -m 4755 + + PROJECTROOT = /usr/X386 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O2 + CCOPTIONS = -m486 -DNO_ASM -fwritable-strings + ANSICCOPTIONS = + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(OS_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -r + DEPENDFLAGS = + + MACROFILE = x386.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XFree86: mit/config/Project.tmpl,v 1.13 1993/03/27 03:32:45 dawes Exp $ +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +_percentC_ = %C + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/X386/lib + BINDIR = /usr/X386/bin + INCROOT = /usr/X386/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/X386/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = 1x + LIBMANSUFFIX = 3x + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + LINKKITDIR = $(USRLIBDIR)/Server + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XFree86: mit/config/lnuxLib.tmpl,v 1.1 1993/04/16 14:06:06 dawes Exp $ + +SHLIBLDFLAGS = +PICFLAGS = -B/usr/dll/jump/ + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = + XMULIB = -lXmu + + DEPXTOOLLIB = + XTOOLLIB = -lXt + + DEPXAWLIB = + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPXTESTLIB = + XTESTLIB = -lXtst + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 3.0.1 + SOXTREV = 3.0.1 + SOXAWREV = 3.0.1 + SOOLDXREV = 3.0.1 + SOXMUREV = 3.0.1 + SOXEXTREV = 3.0.1 + SOXINPUTREV = 3.0.1 + SOPEXREV = 1.0.1 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPOLDXLIB = $(USRLIBDIR)/liboldX.a + OLDXLIB = -loldX + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# $XFree86: mit/config/Imake.rules,v 1.9 1993/03/23 12:56:27 dawes Exp $ +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +# $Id$ + +INCLUDES = -I$(TOP)/include + +# Imake rules go here + +# First, dll description to files etc + +MODULE = include + +HEADERS = atom.h callback.h class.h combo.h cursor.h dce.h dialog.h dlls.h files.h gdi.h heap.h icon.h int21.h listbox.h menu.h message.h neexe.h prototypes.h regfunc.h scroll.h segmem.h user.h win.h windows.h wine.h + +all:: + +depend:: + +clean:: + $(RM_CMD) "#"* + +includes:: + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +install.linkkit:: + @echo "install.linkkit in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/include/atom.h b/include/atom.h new file mode 100644 index 00000000000..61cf6b1b7c7 --- /dev/null +++ b/include/atom.h @@ -0,0 +1,27 @@ +/* + * Atom table definitions + * + * Copyright 1993 Alexandre Julliard + */ + +#ifndef ATOM_H +#define ATOM_H + +#include "windows.h" + + +typedef struct +{ + HANDLE next; + WORD refCount; + BYTE length; + BYTE str[1]; +} ATOMENTRY; + +typedef struct +{ + WORD size; + HANDLE entries[1]; +} ATOMTABLE; + +#endif /* ATOM_H */ diff --git a/include/class.h b/include/class.h index 9ab50e4e2f5..285e81bf746 100644 --- a/include/class.h +++ b/include/class.h @@ -17,7 +17,7 @@ typedef struct tagCLASS HCLASS hNext; /* Next class */ WORD wMagic; /* Magic number (must be CLASS_MAGIC) */ ATOM atomName; /* Name of the class */ - HDC hdc; /* Class DC (if CS_CLASSDC) */ + HANDLE hdce; /* Class DCE (if CS_CLASSDC) */ WORD cWindows; /* Count of existing windows of this class */ WNDCLASS wc __attribute__ ((packed)); /* Class information */ WORD wExtra[1]; /* Class extra bytes */ diff --git a/include/dce.h b/include/dce.h index eff58a5a890..d95c7812e6a 100644 --- a/include/dce.h +++ b/include/dce.h @@ -9,16 +9,27 @@ #include "windows.h" +typedef enum +{ + DCE_CACHE_DC, /* This is a cached DC (allocated by USER) */ + DCE_CLASS_DC, /* This is a class DC (style CS_CLASSDC) */ + DCE_WINDOW_DC /* This is a window DC (style CS_OWNDC) */ +} DCE_TYPE; + + typedef struct tagDCE { HANDLE hNext; HWND hwndCurrent; HDC hdc; - BYTE flags; + DCE_TYPE type; BOOL inUse; WORD xOrigin; WORD yOrigin; } DCE; +extern HANDLE DCE_AllocDCE( DCE_TYPE type ); +extern void DCE_FreeDCE( HANDLE hdce ); + #endif /* DCE_H */ diff --git a/include/files.h b/include/files.h deleted file mode 100644 index 1b628a23d4f..00000000000 --- a/include/files.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _FILES_H -#define _FILES_H - -#define OPEN_MAX 256 - -/*************************************************************************** - This structure stores the infomation needed for a single DOS drive - ***************************************************************************/ -struct DosDriveStruct -{ - char RootDirectory [256]; /* Unix base for this drive letter */ - char CurrentDirectory [256]; /* Current directory for this drive */ - char VolumeLabel [11]; - unsigned long serialnumber; -}; - -#endif /*_FILES_H*/ diff --git a/include/gdi.h b/include/gdi.h index bb5b6323b27..aade98d919f 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -7,7 +7,7 @@ #ifndef GDI_H #define GDI_H -#include <X11/Intrinsic.h> +#include <X11/Xlib.h> #include "windows.h" #include "segmem.h" @@ -158,6 +158,8 @@ typedef struct WORD MapMode; short DCOrgX; /* DC origin */ short DCOrgY; + short DCSizeX; /* DC dimensions */ + short DCSizeY; short CursPosX; /* Current position */ short CursPosY; short WndOrgX; @@ -200,7 +202,6 @@ typedef struct { GC gc; /* X Window GC */ Drawable drawable; - Widget widget; X_PHYSFONT font; X_PHYSPEN pen; X_PHYSBRUSH brush; diff --git a/include/int21.h b/include/int21.h index 92cabc559da..f44c9a433fa 100644 --- a/include/int21.h +++ b/include/int21.h @@ -1,15 +1,40 @@ #ifndef INT21_H #define INT21_H +#include <dirent.h> + +struct dosdirent { + int inuse; + DIR *ds; + char unixpath[256]; + char filename[256]; + 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 AX context->sc_eax -#define BX context->sc_ebx -#define CX context->sc_ecx -#define DX context->sc_edx +#define EAX context->sc_eax +#define EBX context->sc_ebx +#define ECX context->sc_ecx +#define EDX context->sc_edx + +#define AX (context->sc_eax & 0x0000ffffL) +#define BX (context->sc_ebx & 0x0000ffffL) +#define CX (context->sc_ecx & 0x0000ffffL) +#define DX (context->sc_edx & 0x0000ffffL) + #define ES context->sc_es #define DS context->sc_ds #define DI context->sc_edi @@ -22,13 +47,6 @@ #define SetCflag (context->sc_efl |= 0x00000001L) #define ResetCflag (context->sc_efl &= 0xfffffffeL) -struct diskinfo { - WORD infolevel; - DWORD serialnumber; - char label[11]; - char fstype[8]; -}; - /* extended error codes */ #define NoError 0x00 diff --git a/include/listbox.h b/include/listbox.h index f44cf8ce8ee..5d89f9eba22 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -14,16 +14,17 @@ typedef LISTSTRUCT FAR* LPLISTSTRUCT; typedef struct tagHEADLIST { short FirstVisible; - short ItemSelect; short ItemsCount; short ItemsVisible; - short ItemSelected; - short PrevSelected; + short ColumnsVisible; + short ItemsPerColumn; + short ItemFocused; + short PrevFocused; short StdItemHeight; + short ColumnsWidth; short DrawCtlType; void *lpFirst; DWORD dwStyle; - HWND hWndScroll; HWND hWndLogicParent; } HEADLIST; typedef HEADLIST FAR* LPHEADLIST; diff --git a/include/menu.h b/include/menu.h index 15d251adf53..edc0bec12b0 100644 --- a/include/menu.h +++ b/include/menu.h @@ -27,7 +27,10 @@ typedef struct tagMENUITEM Widget w; Widget menu_w; char menu_name[10]; -} MENUITEM; + RECT rect; + HBITMAP hCheckBit; + HBITMAP hUnCheckBit; +} MENUITEM, *LPMENUITEM; typedef struct tagMENUBAR { @@ -40,6 +43,16 @@ typedef struct tagMENUBAR MENUITEM *firstItem; } MENUBAR, *LPMENUBAR; +typedef struct tagPOPUPMENU +{ + HWND hWnd; /* PopupMenu window handle */ + HWND ownerWnd; /* Owner window */ + WORD nItems; /* Number of items on menu */ + MENUITEM *firstItem; + WORD FocusedItem; + WORD MouseFlags; +} POPUPMENU, *LPPOPUPMENU; + typedef struct { WORD version; /* Should be zero */ diff --git a/include/message.h b/include/message.h index 0bbfc9a3ef0..d64b4fcbb2f 100644 --- a/include/message.h +++ b/include/message.h @@ -12,8 +12,8 @@ /* Message as stored in the queue (contains the extraInfo field) */ typedef struct tagQMSG { + DWORD extraInfo; /* Only in 3.1 */ MSG msg; - DWORD extraInfo __attribute__ ((packed)); /* Only in 3.1 */ } QMSG; @@ -28,17 +28,28 @@ typedef struct tagMESSAGEQUEUE WORD queueSize; /* Size of the queue */ DWORD GetMessageTimeVal; /* Value returned by GetMessageTime */ DWORD GetMessagePosVal; /* Value returned by GetMessagePos */ - WORD GetMessageExtraInfoVal; /* Value returned by GetMessageExtraInfo */ - DWORD lParam; /* Next four values set by SetMessage */ + DWORD GetMessageExtraInfoVal; /* Value returned by GetMessageExtraInfo */ + DWORD lParam; /* Next four values set by SendMessage */ WORD wParam; WORD msg; WORD hWnd; WORD wPostQMsg; /* PostQuitMessage flag */ WORD wExitCode; /* PostQuitMessage exit code */ WORD InSendMessageHandle; /* Handle of task that sent a message */ + WORD wPaintCount; /* Number of WM_PAINT needed */ + WORD wTimerCount; /* Number of timers for this application */ WORD tempStatus; /* State reset by GetQueueStatus */ WORD status; /* Queue state */ QMSG messages[1]; /* Queue messages */ } MESSAGEQUEUE; + +extern void MSG_IncPaintCount( HANDLE hQueue ); +extern void MSG_DecPaintCount( HANDLE hQueue ); +extern void MSG_IncTimerCount( HANDLE hQueue ); +extern void MSG_DecTimerCount( HANDLE hQueue ); +extern 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); + #endif /* MESSAGE_H */ diff --git a/include/neexe.h b/include/neexe.h index e610ba45ad0..58e67ccc275 100644 --- a/include/neexe.h +++ b/include/neexe.h @@ -136,7 +136,9 @@ struct relocation_entry_s /* Used by Windows 3.0 programs, like when getting selector to be given to makeprocinst */ #define NE_RELTYPE_INT1 4 -#define NE_RELTYPE_OFFSET16 5 +#define NE_RELTYPE_ORDINALADD 5 +#define NE_RELTYPE_NAMEADD 6 + /* * DOS PSP */ diff --git a/include/prototypes.h b/include/prototypes.h index c1c7bf9f483..69fc97bd4a9 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -10,6 +10,7 @@ #include "neexe.h" #include "segmem.h" #include "wine.h" +#include "int21.h" extern struct segment_descriptor_s * CreateSelectors(struct w_files *); @@ -33,5 +34,15 @@ extern int CurrentNEFile; extern do_int1A(struct sigcontext_struct * context); extern do_int21(struct sigcontext_struct * context); -#endif /* PROTOTYPES_H */ +extern void GetUnixDirName(char *rootdir, char *name); +extern char *GetDirectUnixFileName(char *dosfilename); +extern char *GetUnixFileName(char *dosfilename); + +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 struct dosdirent *DOS_readdir(struct dosdirent *de); +extern void DOS_closedir(struct dosdirent *de); +#endif /* PROTOTYPES_H */ diff --git a/include/segmem.h b/include/segmem.h index ea9f8512402..437dfd98c38 100644 --- a/include/segmem.h +++ b/include/segmem.h @@ -6,6 +6,12 @@ #ifndef SEGMEM_H #define SEGMEM_H +#ifdef __linux__ +#define HAVE_IPC +#include <sys/ipc.h> +#include <sys/shm.h> +#endif + /* * Array to track selector allocation. */ @@ -15,21 +21,32 @@ extern unsigned short SelectorMap[MAX_SELECTORS]; +#ifdef HAVE_IPC +#define SAFEMAKEPTR(s, o) (((int) (s) << 16) | ((o) & 0xffff)) +#define FIXPTR(p) (p) +#else #define SAFEMAKEPTR(s, o) \ (((int) SelectorMap[SelectorMap[(s) >> 3] & SELECTOR_INDEXMASK] << 19) \ | 0x70000 | ((o) & 0xffff)) +#define FIXPTR(p) SAFEMAKEPTR((unsigned long) (p) >> 16, (p)) +#endif /* * Structure to hold info about each selector we create. */ -struct segment_descriptor_s +typedef struct segment_descriptor_s { void *base_addr; /* Pointer to segment in flat memory */ unsigned int length; /* Length of segment */ unsigned int flags; /* Segment flags (see neexe.h and below)*/ unsigned short selector; /* Selector used to access this segment */ -}; + unsigned short owner; /* Handle of owner program */ + unsigned char type; /* DATA or CODE */ +#ifdef HAVE_IPC + key_t shm_key; /* Shared memory key or IPC_PRIVATE */ +#endif +} SEGDESC; /* * Additional flags diff --git a/include/user.h b/include/user.h index 3db21d2dc82..3b9867db86b 100644 --- a/include/user.h +++ b/include/user.h @@ -15,6 +15,8 @@ extern MDESC *USER_Heap; #define USER_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&USER_Heap,f,size) & 0xffff) +#define USER_HEAP_REALLOC(handle,size,f) ((int)HEAP_ReAlloc(&USER_Heap, \ + USER_HEAP_ADDR(handle),size,f) & 0xffff) #define USER_HEAP_ADDR(handle) ((void *)(handle|((int)USER_Heap & 0xffff0000))) #define USER_HEAP_FREE(handle) (HEAP_Free(&USER_Heap,USER_HEAP_ADDR(handle))) diff --git a/include/win.h b/include/win.h index 894da98ff12..b90675db260 100644 --- a/include/win.h +++ b/include/win.h @@ -8,8 +8,6 @@ #define WIN_H #include <X11/Intrinsic.h> -#include <X11/StringDefs.h> -#include <X11/Core.h> #include "windows.h" #include "menu.h" @@ -26,31 +24,41 @@ typedef struct tagWND HWND hwndOwner; /* Window owner */ HCLASS hClass; /* Window class */ HANDLE hInstance; /* Window hInstance (from CreateWindow) */ - RECT rectClient; /* Window client area screen coords */ - RECT rectWindow; /* Window whole area screen coords */ + RECT rectClient; /* Client area rel. to parent client area */ + RECT rectWindow; /* Whole window rel. to parent client area */ + HANDLE hmemTaskQ; /* Task queue global memory handle */ HRGN hrgnUpdate; /* Update region */ HWND hwndLastActive; /* Last active popup hwnd */ FARPROC lpfnWndProc; /* Window procedure */ DWORD dwStyle; /* Window style (from CreateWindow) */ DWORD dwExStyle; /* Extended style (from CreateWindowEx) */ - HDC hdc; /* Window DC (if CS_OWNDC) */ + HANDLE hdce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */ HMENU hmenuSystem; /* System menu */ + HCURSOR hCursor; /* Window Current Cursor */ + HWND hWndVScroll; /* Verti. ScrollBar handle of the window */ + HWND hWndHScroll; /* Horiz. ScrollBar handle of the window */ WORD wIDmenu; /* ID or hmenu (from CreateWindow) */ HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags */ Widget shellWidget; /* For top-level windows */ Widget winWidget; /* For all windows */ Widget compositeWidget;/* For top-level windows */ + Window window; /* X window */ LPMENUBAR menuBarPtr; /* Menu bar */ WORD wExtra[1]; /* Window extra bytes */ } WND; /* WND flags values */ -#define WIN_ERASE_UPDATERGN 1 /* Update region needs erasing */ - +#define WIN_ERASE_UPDATERGN 0x01 /* Update region needs erasing */ +#define WIN_NEEDS_BEGINPAINT 0x02 /* WM_PAINT sent to window */ +#define WIN_GOT_SIZEMSG 0x04 /* WM_SIZE has been sent to the window */ +#define WIN_OWN_DC 0x08 /* Win class has style CS_OWNDC */ +#define WIN_CLASS_DC 0x10 /* Win class has style CS_CLASSDC */ /* Window functions */ -WND * WIN_FindWndPtr( HWND hwnd ); +WND *WIN_FindWndPtr( HWND hwnd ); +BOOL WIN_UnlinkWindow( HWND hwnd ); +BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); HWND WIN_FindWinToRepaint( HWND hwnd ); diff --git a/include/windows.h b/include/windows.h index 9d3eaf3ba76..ae37d54da4e 100644 --- a/include/windows.h +++ b/include/windows.h @@ -64,7 +64,8 @@ typedef int *LPCATCHBUF; #define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) -#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16))) +#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | \ + (((DWORD)((WORD)(high))) << 16))) #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) @@ -208,6 +209,36 @@ typedef struct { #define GW_OWNER 4 #define GW_CHILD 5 + /* WM_WINDOWPOSCHANGING/CHANGED struct */ +typedef struct +{ + HWND hwnd; + HWND hwndInsertAfter; + int x; + int y; + int cx; + int cy; + UINT flags; +} WINDOWPOS; + + /* WM_NCCALCSIZE parameter structure */ +typedef struct +{ + RECT rgrc[3]; + WINDOWPOS FAR* lppos; +} NCCALCSIZE_PARAMS; + + /* WM_NCCALCSIZE return flags */ +#define WVR_ALIGNTOP 0x0010 +#define WVR_ALIGNLEFT 0x0020 +#define WVR_ALIGNBOTTOM 0x0040 +#define WVR_ALIGNRIGHT 0x0080 +#define WVR_HREDRAW 0x0100 +#define WVR_VREDRAW 0x0200 +#define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW) +#define WVR_VALIDRECTS 0x0400 + + /* Dialogs */ /* cbWndExtra bytes for dialog class */ @@ -275,6 +306,9 @@ typedef struct tagMSG typedef WORD ATOM; +#define MAKEINTATOM(i) ((LPCSTR)MAKELP(0, (i))) + + /* Raster operations */ #define R2_BLACK 1 @@ -558,6 +592,19 @@ typedef struct tagLOGPEN #define RGN_DIFF 4 #define RGN_COPY 5 + /* Device contexts */ + +/* GetDCEx flags */ +#define DCX_WINDOW 0x00000001 +#define DCX_CACHE 0x00000002 +#define DCX_CLIPCHILDREN 0x00000008 +#define DCX_CLIPSIBLINGS 0x00000010 +#define DCX_PARENTCLIP 0x00000020 +#define DCX_EXCLUDERGN 0x00000040 +#define DCX_INTERSECTRGN 0x00000080 +#define DCX_LOCKWINDOWUPDATE 0x00000400 +#define DCX_USESTYLE 0x00010000 + /* Polygon modes */ #define ALTERNATE 1 #define WINDING 2 @@ -797,18 +844,6 @@ typedef struct tagBITMAPCOREHEADER #define DIB_PAL_COLORS 1 #define CBM_INIT 4 - -/* Unimplemented structs */ -typedef struct { - BYTE Id; /* much more .... */ -} DCB; - -typedef struct { - BYTE i; /* much more .... */ -} COMSTAT; - - - typedef struct { BYTE i; /* much more .... */ } KANJISTRUCT; @@ -842,6 +877,160 @@ typedef OFSTRUCT *LPOFSTRUCT; #define OF_SHARE_EXCLUSIVE 0x0010 #define OF_VERIFY 0x0400 +#define DRIVE_REMOVABLE 2 +#define DRIVE_FIXED 3 +#define DRIVE_REMOTE 4 + +#define HFILE_ERROR -1 + +#define DDL_READWRITE 0x0000 +#define DDL_READONLY 0x0001 +#define DDL_HIDDEN 0x0002 +#define DDL_SYSTEM 0x0004 +#define DDL_DIRECTORY 0x0010 +#define DDL_ARCHIVE 0x0020 + +#define DDL_POSTMSGS 0x2000 +#define DDL_DRIVES 0x4000 +#define DDL_EXCLUSIVE 0x8000 + +/* comm */ + +#define CBR_110 0xFF10 +#define CBR_300 0xFF11 +#define CBR_600 0xFF12 +#define CBR_1200 0xFF13 +#define CBR_2400 0xFF14 +#define CBR_4800 0xFF15 +#define CBR_9600 0xFF16 +#define CBR_14400 0xFF17 +#define CBR_19200 0xFF18 +#define CBR_38400 0xFF1B +#define CBR_56000 0xFF1F +#define CBR_128000 0xFF23 +#define CBR_256000 0xFF27 + +#define NOPARITY 0 +#define ODDPARITY 1 +#define EVENPARITY 2 +#define MARKPARITY 3 +#define SPACEPARITY 4 +#define ONESTOPBIT 0 +#define ONE5STOPBITS 1 +#define TWOSTOPBITS 2 +#define IGNORE 0 +#define INFINITE 0xFFFF + +#define CE_RXOVER 0x0001 +#define CE_OVERRUN 0x0002 +#define CE_RXPARITY 0x0004 +#define CE_FRAME 0x0008 +#define CE_BREAK 0x0010 +#define CE_CTSTO 0x0020 +#define CE_DSRTO 0x0040 +#define CE_RLSDTO 0x0080 +#define CE_TXFULL 0x0100 +#define CE_PTO 0x0200 +#define CE_IOE 0x0400 +#define CE_DNS 0x0800 +#define CE_OOP 0x1000 +#define CE_MODE 0x8000 + +#define IE_BADID -1 +#define IE_OPEN -2 +#define IE_NOPEN -3 +#define IE_MEMORY -4 +#define IE_DEFAULT -5 +#define IE_HARDWARE -10 +#define IE_BYTESIZE -11 +#define IE_BAUDRATE -12 + +#define EV_RXCHAR 0x0001 +#define EV_RXFLAG 0x0002 +#define EV_TXEMPTY 0x0004 +#define EV_CTS 0x0008 +#define EV_DSR 0x0010 +#define EV_RLSD 0x0020 +#define EV_BREAK 0x0040 +#define EV_ERR 0x0080 +#define EV_RING 0x0100 +#define EV_PERR 0x0200 +#define EV_CTSS 0x0400 +#define EV_DSRS 0x0800 +#define EV_RLSDS 0x1000 +#define EV_RINGTE 0x2000 +#define EV_RingTe EV_RINGTE + +#define SETXOFF 1 +#define SETXON 2 +#define SETRTS 3 +#define CLRRTS 4 +#define SETDTR 5 +#define CLRDTR 6 +#define RESETDEV 7 +#define GETMAXLPT 8 +#define GETMAXCOM 9 +#define GETBASEIRQ 10 + +#define CN_RECEIVE 0x0001 +#define CN_TRANSMIT 0x0002 +#define CN_EVENT 0x0004 + +typedef struct tagDCB +{ + BYTE Id; + UINT BaudRate; + BYTE ByteSize; + BYTE Parity; + BYTE StopBits; + UINT RlsTimeout; + UINT CtsTimeout; + UINT DsrTimeout; + + UINT fBinary :1; + UINT fRtsDisable :1; + UINT fParity :1; + UINT fOutxCtsFlow :1; + UINT fOutxDsrFlow :1; + UINT fDummy :2; + UINT fDtrDisable :1; + + UINT fOutX :1; + UINT fInX :1; + UINT fPeChar :1; + UINT fNull :1; + UINT fChEvt :1; + UINT fDtrflow :1; + UINT fRtsflow :1; + UINT fDummy2 :1; + + char XonChar; + char XoffChar; + UINT XonLim; + UINT XoffLim; + char PeChar; + char EofChar; + char EvtChar; + UINT TxDelay; +} DCB; +typedef DCB FAR* LPDCB; + +typedef struct tagCOMSTAT +{ + BYTE status; + UINT cbInQue; + UINT cbOutQue; +} COMSTAT; + +#define CSTF_CTSHOLD 0x01 +#define CSTF_DSRHOLD 0x02 +#define CSTF_RLSDHOLD 0x04 +#define CSTF_XOFFHOLD 0x08 +#define CSTF_XOFFSENT 0x10 +#define CSTF_EOF 0x20 +#define CSTF_TXIM 0x40 + +/* */ typedef struct { @@ -903,8 +1092,12 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE WM_DELETEITEM, WM_VKEYTOITEM, WM_CHARTOITEM, WM_SETFONT, WM_GETFONT }; +#define WM_WINDOWPOSCHANGING 0x0046 +#define WM_WINDOWPOSCHANGED 0x0047 + #define WM_NCCREATE 0x0081 #define WM_NCDESTROY 0x0082 +#define WM_NCCALCSIZE 0x0083 #define WM_GETDLGCODE 0x0087 @@ -1008,6 +1201,12 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define HWND_TOPMOST ((HWND)-1) #define HWND_NOTOPMOST ((HWND)-2) +/* Flags for TrackPopupMenu */ +#define TPM_LEFTBUTTON 0x0000 +#define TPM_RIGHTBUTTON 0x0002 +#define TPM_LEFTALIGN 0x0000 +#define TPM_CENTERALIGN 0x0004 +#define TPM_RIGHTALIGN 0x0008 #define MF_INSERT 0 #define MF_CHANGE 0x0080 @@ -1016,7 +1215,7 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define MF_REMOVE 0x1000 #define MF_BYCOMMAND 0 #define MF_BYPOSITION 0x0400 -#define MF_SEPARATOR 0x080 +#define MF_SEPARATOR 0x0800 #define MF_ENABLED 0 #define MF_GRAYED 0x0001 #define MF_DISABLED 0x0002 @@ -1492,6 +1691,80 @@ typedef struct tagCOMPAREITEMSTRUCT typedef COMPAREITEMSTRUCT NEAR* PCOMPAREITEMSTRUCT; typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT; +/* Virtual key codes */ +#define VK_LBUTTON 0x01 +#define VK_RBUTTON 0x02 +#define VK_CANCEL 0x03 +#define VK_MBUTTON 0x04 +#define VK_BACK 0x08 +#define VK_TAB 0x09 +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 +#define VK_PAUSE 0x13 +#define VK_CAPITAL 0x14 +#define VK_ESCAPE 0x1B +#define VK_SPACE 0x20 +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SELECT 0x29 +#define VK_PRINT 0x2A +#define VK_EXECUTE 0x2B +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E +#define VK_HELP 0x2F +#define VK_NUMPAD0 0x60 +#define VK_NUMPAD1 0x61 +#define VK_NUMPAD2 0x62 +#define VK_NUMPAD3 0x63 +#define VK_NUMPAD4 0x64 +#define VK_NUMPAD5 0x65 +#define VK_NUMPAD6 0x66 +#define VK_NUMPAD7 0x67 +#define VK_NUMPAD8 0x68 +#define VK_NUMPAD9 0x69 +#define VK_MULTIPLY 0x6A +#define VK_ADD 0x6B +#define VK_SEPARATOR 0x6C +#define VK_SUBTRACT 0x6D +#define VK_DECIMAL 0x6E +#define VK_DIVIDE 0x6F +#define VK_F1 0x70 +#define VK_F2 0x71 +#define VK_F3 0x72 +#define VK_F4 0x73 +#define VK_F5 0x74 +#define VK_F6 0x75 +#define VK_F7 0x76 +#define VK_F8 0x77 +#define VK_F9 0x78 +#define VK_F10 0x79 +#define VK_F11 0x7A +#define VK_F12 0x7B +#define VK_F13 0x7C +#define VK_F14 0x7D +#define VK_F15 0x7E +#define VK_F16 0x7F +#define VK_F17 0x80 +#define VK_F18 0x81 +#define VK_F19 0x82 +#define VK_F20 0x83 +#define VK_F21 0x84 +#define VK_F22 0x85 +#define VK_F23 0x86 +#define VK_F24 0x87 +#define VK_NUMLOCK 0x90 +#define VK_SCROLL 0x91 + #define LMEM_MOVEABLE 0x0002 @@ -1719,6 +1992,7 @@ Fa(WORD,EnumClipboardFormats,WORD,a) Fa(WORD,FreeSelector,WORD,a) Fa(WORD,GetDriveType,int,a) Fa(WORD,GetMenuItemCount,HMENU,a) +Fa(WORD,GetTaskQueue,HANDLE,a) Fa(WORD,GetTextAlign,HDC,a) Fa(WORD,GlobalFlags,HANDLE,a) Fa(WORD,GlobalPageLock,HANDLE,a) @@ -1726,9 +2000,9 @@ Fa(WORD,GlobalPageUnlock,HANDLE,a) Fa(WORD,LocalCompact,WORD,a) Fa(WORD,LocalFlags,HANDLE,a) Fa(WORD,LocalSize,HANDLE,a) -Fa(WORD,RealizePalette,HDC,a) -Fa(WORD,RegisterClipboardFormat,LPSTR,a) -Fa(WORD,RegisterWindowMessage,LPSTR,a) +Fa(int,RealizePalette,HDC,a) +Fa(WORD,RegisterClipboardFormat,LPCSTR,a) +Fa(WORD,RegisterWindowMessage,LPCSTR,a) Fa(WORD,SetHandleCount,WORD,a) Fa(WORD,VkKeyScan,WORD,a) Fa(char NEAR*,LocalLock,HANDLE,a) @@ -1872,6 +2146,7 @@ Fb(WORD,IsDlgButtonChecked,HWND,a,WORD,b) Fb(WORD,LocalShrink,HANDLE,a,WORD,b) Fb(WORD,MapVirtualKey,WORD,a,WORD,b) Fb(WORD,SetSystemPaletteUse,HDC,a,WORD,b) +Fb(WORD,SetTaskQueue,HANDLE,a,HANDLE,b) Fb(WORD,SetTextAlign,HDC,a,WORD,b) Fb(WORD,SizeofResource,HANDLE,a,HANDLE,b) Fb(WORD,WinExec,LPSTR,a,WORD,b) @@ -1881,7 +2156,7 @@ Fb(int,BuildCommDCB,LPSTR,a,DCB*,b) Fb(int,ConvertRequest,HWND,a,LPKANJISTRUCT,b) Fb(void,CopyRect,LPRECT,a,LPRECT,b) Fb(int,EnumProps,HWND,a,FARPROC,b) -Fb(int,EscapeCommFunction,int,a,int,b) +Fb(LONG,EscapeCommFunction,int,a,int,b) Fb(int,ExcludeUpdateRgn,HDC,a,HWND,b) Fb(int,FlushComm,int,a,int,b) Fb(int,GetClipBox,HDC,a,LPRECT,b) @@ -1910,8 +2185,8 @@ Fb(void,MapDialogRect,HWND,a,LPRECT,b) Fb(void,ProfSampRate,int,a,int,b) Fb(void,ProfSetup,int,a,int,b) Fb(void,ScreenToClient,HWND,a,LPPOINT,b) -Fb(void,SetCaretPos,int,a,int,b) -Fb(void,SetCursorPos,int,a,int,b) +Fb(void,SetCaretPos,short,a,short,b) +Fb(void,SetCursorPos,short,a,short,b) Fb(void,SetWindowText,HWND,a,LPSTR,b) Fb(void,ShowOwnedPopups,HWND,a,BOOL,b) Fb(void,Throw,LPCATCHBUF,a,int,b) @@ -1963,6 +2238,7 @@ Fc(HANDLE,GlobalReAlloc,HANDLE,a,DWORD,b,WORD,c) 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) +Fc(HDC,GetDCEx,HWND,a,HRGN,b,DWORD,c) Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c) Fc(HPEN,CreatePen,short,a,short,b,COLORREF,c) Fc(HRGN,CreatePolygonRgn,LPPOINT,a,short,b,short,c) @@ -1985,7 +2261,7 @@ Fb(WORD,SetRelAbs,HDC,a,WORD,b) Fb(WORD,SetROP2,HDC,a,WORD,b) Fb(WORD,SetStretchBltMode,HDC,a,WORD,b) Fc(int,FrameRect,HDC,a,LPRECT,b,HBRUSH,c) -Fc(int,GetClassName,HWND,a,LPSTR,b,int,c) +Fc(int,GetClassName,HWND,a,LPSTR,b,short,c) Fc(int,GetClipboardFormatName,WORD,a,LPSTR,b,int,c) Fc(int,GetEnvironment,LPSTR,a,LPSTR,b,WORD,c) Fc(int,GetInstanceData,HANDLE,a,NPSTR,b,int,c) @@ -2066,7 +2342,7 @@ Fd(int,DialogBoxIndirect,HANDLE,a,HANDLE,b,HWND,c,FARPROC,d) Fd(int,EnumFonts,HDC,a,LPSTR,b,FARPROC,c,LPSTR,d) Fd(int,EnumObjects,HDC,a,int,b,FARPROC,c,LPSTR,d) Fd(int,GetDlgItemText,HWND,a,WORD,b,LPSTR,c,WORD,d) -Fd(int,GetTempFileName,BYTE,a,LPSTR,b,WORD,c,LPSTR,d) +Fd(int,GetTempFileName,BYTE,a,LPCSTR,b,UINT,c,LPSTR,d) Fd(int,LoadString,HANDLE,a,WORD,b,LPSTR,c,int,d) Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d) Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d) @@ -2074,9 +2350,10 @@ Fd(int,SetVoiceNote,int,a,int,b,int,c,int,d) Fd(void,AdjustWindowRectEx,LPRECT,a,LONG,b,BOOL,c,DWORD,d) Fd(void,AnimatePalette,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d) Fd(void,CheckRadioButton,HWND,a,WORD,b,WORD,c,WORD,d) -Fd(void,CreateCaret,HWND,a,HBITMAP,b,int,c,int,d) +Fd(void,CreateCaret,HWND,a,HBITMAP,b,short,c,short,d) Fd(void,FillWindow,HWND,a,HWND,b,HDC,c,HBRUSH,d) Fd(void,GetScrollRange,HWND,a,int,b,LPINT,c,LPINT,d) +Fd(void,MapWindowPoints,HWND,a,HWND,b,LPPOINT,c,WORD,d) Fd(void,PlayMetaFileRecord,HDC,a,LPHANDLETABLE,b,LPMETARECORD,c,WORD,d) Fd(void,SetDlgItemInt,HWND,a,WORD,b,WORD,c,BOOL,d) Fe(BOOL,Rectangle,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom) @@ -2122,17 +2399,17 @@ Ff(HBITMAP,CreateDIBitmap,HDC,a,LPBITMAPINFOHEADER,b,DWORD,c,LPSTR,d,LPBITMAPINF Ff(HRGN,CreateRoundRectRgn,short,a,short,b,short,c,short,d,short,e,short,f) Ff(short,GetPrivateProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d,short,e,LPSTR,f) Ff(void,LineDDA,short,a,short,b,short,c,short,d,FARPROC,e,long,f) -Ff(void,MoveWindow,HWND,a,short,b,short,c,short,d,short,e,BOOL,f) +Ff(BOOL,MoveWindow,HWND,a,short,b,short,c,short,d,short,e,BOOL,f) Ff(BOOL,ScaleViewportExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f) Ff(BOOL,ScaleWindowExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f) Fg(BOOL,RoundRect,HDC,a,short,b,short,c,short,d,short,e,short,f,short,g) Fg(BOOL,ScrollDC,HDC,a,short,b,short,c,LPRECT,d,LPRECT,e,HRGN,f,LPRECT,g) -Fg(BOOL,TrackPopupMenu,HMENU,a,WORD,b,int,c,int,d,int,e,HWND,f,LPRECT,g) -Fg(HCURSOR,CreateCursor,HANDLE,a,int,b,int,c,int,d,int,e,LPSTR,f,LPSTR,g) +Fg(BOOL,TrackPopupMenu,HMENU,a,WORD,b,short,c,short,d,short,e,HWND,f,LPRECT,g) +Fg(HCURSOR,CreateCursor,HANDLE,a,short,b,short,c,short,d,short,e,LPSTR,f,LPSTR,g) Fg(HICON,CreateIcon,HANDLE,a,int,b,int,c,BYTE,d,BYTE,e,LPSTR,f,LPSTR,g) Fg(int,GetDIBits,HDC,a,HANDLE,a2,WORD,b,WORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f) Fg(int,SetDIBits,HDC,a,HANDLE,a2,WORD,b,WORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f) -Fg(void,SetWindowPos,HWND,a,HWND,b,short,c,short,d,short,e,short,f,WORD,g) +Fg(BOOL,SetWindowPos,HWND,a,HWND,b,short,c,short,d,short,e,short,f,WORD,g) Fh(BOOL,ExtTextOut,HDC,a,int,b,int,c,WORD,d,LPRECT,e,LPSTR,f,WORD,g,LPINT,h) Fh(HANDLE,DeferWindowPos,HANDLE,hWinPosInfo,HWND,hWnd,HWND,hWndInsertAfter,int,x,int,y,int,cx,int,cy,WORD,wFlags) Fh(LONG,TabbedTextOut,HDC,a,int,b,int,c,LPSTR,d,int,e,int,f,LPINT,g,int,h) diff --git a/include/wine.h b/include/wine.h index 6a602e9da40..dbc034cd806 100644 --- a/include/wine.h +++ b/include/wine.h @@ -22,9 +22,14 @@ extern struct w_files * wine_files; extern char *GetFilenameFromInstance(unsigned short instance); extern struct w_files *GetFileInfo(unsigned short instance); -extern char *FindFileInPath(char *buffer, int buflen, char *rootname, - char **extensions, char *path); -extern char *GetSystemIniFilename(void); +extern char *WineIniFileName(void); +extern char *WinIniFileName(void); + +#define MAX_DOS_DRIVES 26 + +#define WINE_INI WineIniFileName() +#define WIN_INI WinIniFileName() + #ifdef linux struct sigcontext_struct { unsigned short sc_gs, __gsh; diff --git a/loader/Imakefile b/loader/Imakefile new file mode 100644 index 00000000000..9c5130a48a6 --- /dev/null +++ b/loader/Imakefile @@ -0,0 +1,35 @@ +#include "../Wine.tmpl" + +MODULE = loader + +SRCS = \ + dump.c \ + files.c \ + ldt.c \ + ldtlib.c \ + resource.c \ + selector.c \ + signal.c \ + library.c \ + wine.c \ + cursor.c + +OBJS = \ + dump.o \ + files.o \ + ldt.o \ + ldtlib.o \ + resource.o \ + selector.o \ + signal.o \ + library.o \ + wine.o \ + cursor.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/loader/Makefile b/loader/Makefile index 873a6acd59d..083d8f68a65 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I../include -OBJS=dump.o files.o ldt.o ldtlib.o resource.o selector.o signal.o int1a.o \ - int21.o wine.o library.o +OBJS=dump.o ldt.o ldtlib.o resource.o selector.o signal.o library.o \ + wine.o cursor.o default: loader.o diff --git a/loader/cursor.c b/loader/cursor.c new file mode 100644 index 00000000000..039c1c35bf9 --- /dev/null +++ b/loader/cursor.c @@ -0,0 +1,385 @@ +/* + * WINE +*/ +static char Copyright[] = "Copyright Martin Ayotte, 1993"; + +/* +#define DEBUG_CURSOR +*/ + +#include <X11/Intrinsic.h> +#include <X11/cursorfont.h> +#include <X11/Xlib.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include "prototypes.h" +#include "windows.h" +#include "win.h" +#include "gdi.h" +#include "wine.h" +#include "cursor.h" + +static int ShowCursCount = 0; +static HCURSOR hActiveCursor; +static HCURSOR hEmptyCursor = 0; +RECT ClipCursorRect; +extern HINSTANCE hSysRes; +extern Window winHasCursor; + +/********************************************************************** + * LoadCursor [USER.173] + */ +HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) +{ + XColor bkcolor; + XColor fgcolor; + HCURSOR hCursor; + HANDLE rsc_mem; + WORD *lp; + CURSORDESCRIP *lpcurdesc; + CURSORALLOC *lpcur; + BITMAP BitMap; + HBITMAP hBitMap; + HDC hMemDC; + HDC hdc; + int i, j, image_size; +#ifdef DEBUG_RESOURCE + printf("LoadCursor: instance = %04x, name = %08x\n", + instance, cursor_name); +#endif + hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); + if (hCursor == (HCURSOR)NULL) return 0; +#ifdef DEBUG_CURSOR + printf("LoadCursor Alloc hCursor=%X\n", hCursor); +#endif + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + memset(lpcur, 0, sizeof(CURSORALLOC)); + if (instance == (HANDLE)NULL) { + instance = hSysRes; + switch((LONG)cursor_name) { + case IDC_ARROW: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow); + GlobalUnlock(hCursor); + return hCursor; + case IDC_CROSS: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_crosshair); + GlobalUnlock(hCursor); + return hCursor; + case IDC_IBEAM: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_xterm); + GlobalUnlock(hCursor); + return hCursor; + case IDC_WAIT: + lpcur->xcursor = XCreateFontCursor(XT_display, XC_watch); + GlobalUnlock(hCursor); + return hCursor; + default: + break; + } + } + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, + &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadCursor / Cursor %08X not Found !\n", cursor_name); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lpcurdesc = (CURSORDESCRIP *)(lp + 3); +#ifdef DEBUG_CURSOR + printf("LoadCursor / image_size=%d\n", image_size); + printf("LoadCursor / curReserved=%X\n", *lp); + printf("LoadCursor / curResourceType=%X\n", *(lp + 1)); + printf("LoadCursor / curResourceCount=%X\n", *(lp + 2)); + printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width); + printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height); + printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot); + printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot); + printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize); + printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); +#endif + lpcur->descriptor = *lpcurdesc; + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + rsc_mem = RSC_LoadResource(instance, + MAKEINTRESOURCE(lpcurdesc->curDIBOffset), + NE_RSCTYPE_CURSOR, &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lp = (WORD *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + lp += 2; + for (j = 0; j < 16; j++) + printf("%04X ", *(lp + j)); +/* + if (*lp == sizeof(BITMAPINFOHEADER)) + lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp); + else +*/ + lpcur->hBitmap = 0; + lp += sizeof(BITMAP); + for (i = 0; i < 81; i++) { + char temp = *((char *)lp + 162 + i); + *((char *)lp + 162 + i) = *((char *)lp + 324 - i); + *((char *)lp + 324 - i) = temp; + } + lpcur->pixshape = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + ((char *)lp + 211), 32, 32, +/* + lpcurdesc->Width / 2, lpcurdesc->Height / 4, +*/ + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + lpcur->pixmask = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + ((char *)lp + 211), 32, 32, + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + memset(&bkcolor, 0, sizeof(XColor)); + memset(&fgcolor, 0, sizeof(XColor)); + bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); + fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); +printf("LoadCursor / before XCreatePixmapCursor !\n"); + lpcur->xcursor = XCreatePixmapCursor(XT_display, + lpcur->pixshape, lpcur->pixmask, + &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot); + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); +/* + hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot, 32, 32, + (LPSTR)lp + 211, , (LPSTR)lp + 211); +*/ + XFreePixmap(XT_display, lpcur->pixshape); + XFreePixmap(XT_display, lpcur->pixmask); + ReleaseDC(GetDesktopWindow(), hdc); + GlobalUnlock(hCursor); + return hCursor; +} + + + +/********************************************************************** + * CreateCursor [USER.406] + */ +HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, + short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane) +{ + XColor bkcolor; + XColor fgcolor; + HCURSOR hCursor; + CURSORALLOC *lpcur; + BITMAP BitMap; + HBITMAP hBitMap; + HDC hMemDC; + HDC hdc; + int i, j; +#ifdef DEBUG_RESOURCE + printf("CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n", + nXhotspot, nYhotspot, nWidth, nHeight); + printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n", + LPSTR lpANDbitPlane, LPSTR lpXORbitPlane); +#endif + if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); + if (hCursor == (HCURSOR)NULL) { + ReleaseDC(GetDesktopWindow(), hdc); + return 0; + } + printf("CreateCursor Alloc hCursor=%X\n", hCursor); + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + memset(lpcur, 0, sizeof(CURSORALLOC)); + lpcur->descriptor.curXHotspot = nXhotspot; + lpcur->descriptor.curYHotspot = nYhotspot; + lpcur->pixshape = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + lpXORbitPlane, nWidth, nHeight, + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + lpcur->pixmask = XCreatePixmapFromBitmapData( + XT_display, DefaultRootWindow(XT_display), + lpANDbitPlane, nWidth, nHeight, + WhitePixel(XT_display, DefaultScreen(XT_display)), + BlackPixel(XT_display, DefaultScreen(XT_display)), 1); + memset(&bkcolor, 0, sizeof(XColor)); + memset(&fgcolor, 0, sizeof(XColor)); + bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); + fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); + lpcur->xcursor = XCreatePixmapCursor(XT_display, + lpcur->pixshape, lpcur->pixmask, + &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot); + XFreePixmap(XT_display, lpcur->pixshape); + XFreePixmap(XT_display, lpcur->pixmask); + ReleaseDC(GetDesktopWindow(), hdc); + GlobalUnlock(hCursor); + return hCursor; +} + + + +/********************************************************************** + * DestroyCursor [USER.458] + */ +BOOL DestroyCursor(HCURSOR hCursor) +{ + CURSORALLOC *lpcur; + if (hCursor == (HCURSOR)NULL) return FALSE; + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap); + GlobalUnlock(hCursor); + GlobalFree(hCursor); + return TRUE; +} + + +/********************************************************************** + * SetCursor [USER.69] + */ +HCURSOR SetCursor(HCURSOR hCursor) +{ + HDC hDC; + HDC hMemDC; + BITMAP bm; + CURSORALLOC *lpcur; + HCURSOR hOldCursor; + Window root, child; + int rootX, rootY; + int childX, childY; + unsigned int mousebut; +#ifdef DEBUG_CURSOR + printf("SetCursor / hCursor=%04X !\n", hCursor); +#endif + if (hCursor == (HCURSOR)NULL) return FALSE; + lpcur = (CURSORALLOC *)GlobalLock(hCursor); + hOldCursor = hActiveCursor; +#ifdef DEBUG_CURSOR + printf("SetCursor / lpcur->xcursor=%08X !\n", &lpcur->xcursor); + XQueryPointer(XT_display, DefaultRootWindow(XT_display), + &root, &child, &rootX, &rootY, &childX, &childY, &mousebut); + printf("SetCursor / winHasCursor=%08X !\n", winHasCursor); + printf("SetCursor / child=%08X !\n", child); +#endif + if (hActiveCursor != hCursor) ShowCursCount = 0; + if ((ShowCursCount >= 0) & (winHasCursor != 0)) { +/* XUndefineCursor(XT_display, winHasCursor); */ + XDefineCursor(XT_display, winHasCursor, lpcur->xcursor); + } + GlobalUnlock(hCursor); + hActiveCursor = hCursor; + return hOldCursor; +} + + +/********************************************************************** + * SetCursorPos [USER.70] + */ +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); +} + + +/********************************************************************** + * GetCursorPos [USER.17] + */ +void GetCursorPos(LPPOINT lpRetPoint) +{ + Window root, child; + 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); +#ifdef DEBUG_CURSOR + printf("GetCursorPos // x=%d y=%d\n", rootX, rootY); +#endif + lpRetPoint->x = rootX; + lpRetPoint->y = rootY; + } +} + + +/********************************************************************** + * ShowCursor [USER.71] + */ +int ShowCursor(BOOL bShow) +{ + HCURSOR hCursor; +#ifdef DEBUG_CURSOR + printf("ShowCursor bShow=%d ShowCount=%d !\n", bShow, ShowCursCount); +#endif + if (bShow) + ShowCursCount++; + else + ShowCursCount--; + if (ShowCursCount >= 0) { +/* if (hCursor == (HCURSOR)NULL) */ + hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW); + SetCursor(hCursor); + } + else { +/* XUndefineCursor(XT_display, winHasCursor); */ + if (hEmptyCursor == (HCURSOR)NULL) + hEmptyCursor = CreateCursor((HINSTANCE)NULL, 1, 1, 1, 1, + "\xFF\xFF", "\xFF\xFF"); + hCursor = SetCursor(hEmptyCursor); + hActiveCursor = hCursor; + } + return 0; +} + + +/********************************************************************** + * ClipCursor [USER.16] + */ +void ClipCursor(LPRECT lpNewClipRect) +{ + CopyRect(&ClipCursorRect, lpNewClipRect); +} + + +/********************************************************************** + * GetClipCursor [USER.309] + */ +void GetClipCursor(LPRECT lpRetClipRect) +{ + if (lpRetClipRect != NULL) + CopyRect(lpRetClipRect, &ClipCursorRect); +} + + + + diff --git a/loader/files.c b/loader/files.c deleted file mode 100644 index a4371c6e8ac..00000000000 --- a/loader/files.c +++ /dev/null @@ -1,109 +0,0 @@ -static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; -static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; - -#include <stdlib.h> -#include <dirent.h> -#include <string.h> - -/********************************************************************** - * FindFileInPath - */ -char * -FindFileInPath(char *buffer, int buflen, char *rootname, - char **extensions, char *path) -{ - char *workingpath; - char *dirname; - DIR *d; - struct dirent *f; - char **e; - int rootnamelen; - int found = 0; - - if (strchr(rootname, '/') != NULL) - { - strncpy(buffer, rootname, buflen); - return buffer; - } - - rootnamelen = strlen(rootname); - workingpath = malloc(strlen(path) + 1); - if (workingpath == NULL) - return NULL; - strcpy(workingpath, path); - - for(dirname = strtok(workingpath, ":;"); - dirname != NULL; - dirname = strtok(NULL, ":;")) - { - d = opendir(dirname); - if (d != NULL) - { - while ((f = readdir(d)) != NULL) - { - if (strncasecmp(rootname, f->d_name, rootnamelen) == 0) - { - if (extensions == NULL || - strcasecmp(rootname, f->d_name) == 0) - { - 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) - { - strncpy(buffer, dirname, buflen); - strncat(buffer, "/", buflen - strlen(buffer)); - strncat(buffer, f->d_name, buflen - strlen(buffer)); - closedir(d); - return buffer; - } - } - } - closedir(d); - } - } - - return NULL; -} - -/********************************************************************** - * GetSystemIniFilename - */ -char * -GetSystemIniFilename() -{ - static char *IniName = NULL; - char inipath[256]; - - if (IniName) - return IniName; - - getcwd(inipath, 256); - strcat(inipath, ":"); - strcat(inipath, getenv("HOME")); - strcat(inipath, ":"); - strcat(inipath, getenv("WINEPATH")); - - IniName = malloc(1024); - if (FindFileInPath(IniName, 1024, "wine.ini", NULL, inipath) == NULL) - { - free(IniName); - IniName = NULL; - return NULL; - } - - IniName = realloc(IniName, strlen(IniName) + 1); - return IniName; -} diff --git a/loader/library.c b/loader/library.c index 6e96351de24..fe7813e26e3 100644 --- a/loader/library.c +++ b/loader/library.c @@ -20,7 +20,7 @@ HANDLE LoadLibrary(LPSTR libname) { HANDLE hRet; printf("LoadLibrary '%s'\n", libname); - hRet = LoadImage(libname, NULL); + hRet = LoadImage(libname); printf("after LoadLibrary hRet=%04X\n", hRet); return hRet; } diff --git a/loader/resource.c b/loader/resource.c index a0c986c49f1..9d973058c68 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -14,7 +14,6 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "gdi.h" #include "wine.h" #include "icon.h" -#include "cursor.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -31,7 +30,6 @@ static int ResourceFd = -1; static HANDLE ResourceInst = 0; static struct w_files *ResourceFileInfo = NULL; static RESOURCE *Top = NULL; -static HCURSOR hActiveCursor; extern HINSTANCE hSysRes; HANDLE RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret); @@ -313,23 +311,26 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) instance, icon_name); #endif - if (instance == (HANDLE)NULL) instance = hSysRes; if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + if (instance == (HANDLE)NULL) instance = hSysRes; rsc_mem = RSC_LoadResource(instance, icon_name, NE_RSCTYPE_GROUP_ICON, &image_size); if (rsc_mem == (HANDLE)NULL) { printf("LoadIcon / Icon %04X not Found !\n", icon_name); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } lp = (WORD *)GlobalLock(rsc_mem); if (lp == NULL) { GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } lpicodesc = (ICONDESCRIP *)(lp + 3); hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024); if (hIcon == (HICON)NULL) { GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } printf("LoadIcon Alloc hIcon=%X\n", hIcon); @@ -344,11 +345,13 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) NE_RSCTYPE_ICON, &image_size); if (rsc_mem == (HANDLE)NULL) { printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } lp = (WORD *)GlobalLock(rsc_mem); if (lp == NULL) { GlobalFree(rsc_mem); + ReleaseDC(GetDesktopWindow(), hdc); return 0; } bmi = (BITMAPINFO *)lp; @@ -378,7 +381,6 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) (BITMAPINFO *)bih, DIB_RGB_COLORS ); GlobalUnlock(rsc_mem); GlobalFree(rsc_mem); - hMemDC = CreateCompatibleDC(hdc); hMemDC2 = CreateCompatibleDC(hdc); SelectObject(hMemDC, lpico->hBitmap); @@ -386,8 +388,7 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT); DeleteDC(hMemDC); DeleteDC(hMemDC2); - - ReleaseDC(0, hdc); + ReleaseDC(GetDesktopWindow(), hdc); return hIcon; } @@ -406,165 +407,6 @@ BOOL DestroyIcon(HICON hIcon) } -/********************************************************************** - * LoadCursor [USER.173] - */ -HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) -{ - XColor bkcolor; - XColor fgcolor; - HCURSOR hCursor; - HANDLE rsc_mem; - WORD *lp; - CURSORDESCRIP *lpcurdesc; - CURSORALLOC *lpcur; - BITMAP BitMap; - HBITMAP hBitMap; - HDC hMemDC; - HDC hdc; - int i, j, image_size; -#ifdef DEBUG_RESOURCE - printf("LoadCursor: instance = %04x, name = %08x\n", - instance, cursor_name); -#endif - if (!(hdc = GetDC(GetDesktopWindow()))) return 0; - if (instance == (HANDLE)NULL) instance = hSysRes; - rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, - &image_size); - if (rsc_mem == (HANDLE)NULL) { - printf("LoadCursor / Cursor %08X not Found !\n", cursor_name); - return 0; - } - lp = (WORD *)GlobalLock(rsc_mem); - if (lp == NULL) { - GlobalFree(rsc_mem); - return 0; - } - lpcurdesc = (CURSORDESCRIP *)(lp + 3); -#ifdef DEBUG_CURSOR - printf("LoadCursor / image_size=%d\n", image_size); - printf("LoadCursor / curReserved=%X\n", *lp); - printf("LoadCursor / curResourceType=%X\n", *(lp + 1)); - printf("LoadCursor / curResourceCount=%X\n", *(lp + 2)); - printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width); - printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height); - printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot); - printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot); - printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize); - printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); -#endif - hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); - if (hCursor == (HCURSOR)NULL) { - GlobalFree(rsc_mem); - return 0; - } - printf("LoadCursor Alloc hCursor=%X\n", hCursor); - lpcur = (CURSORALLOC *)GlobalLock(hCursor); - lpcur->descriptor = *lpcurdesc; - GlobalUnlock(rsc_mem); - GlobalFree(rsc_mem); - rsc_mem = RSC_LoadResource(instance, - MAKEINTRESOURCE(lpcurdesc->curDIBOffset), - NE_RSCTYPE_CURSOR, &image_size); - if (rsc_mem == (HANDLE)NULL) { - printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name); - return 0; - } - lp = (WORD *)GlobalLock(rsc_mem); - if (lp == NULL) { - GlobalFree(rsc_mem); - return 0; - } - lp += 2; - for (j = 0; j < 16; j++) - printf("%04X ", *(lp + j)); - if (*lp == sizeof(BITMAPINFOHEADER)) - lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp); - else - lpcur->hBitmap = 0; - lp += sizeof(BITMAP); - for (i = 0; i < 81; i++) { - char temp = *((char *)lp + 162 + i); - *((char *)lp + 162 + i) = *((char *)lp + 324 - i); - *((char *)lp + 324 - i) = temp; - } -printf("LoadCursor / before XCreatePixmapFromBitmapData !\n"); - lpcur->pixshape = XCreatePixmapFromBitmapData( - XT_display, DefaultRootWindow(XT_display), - ((char *)lp + 211), 32, 32, -/* - lpcurdesc->Width / 2, lpcurdesc->Height / 4, -*/ - WhitePixel(XT_display, DefaultScreen(XT_display)), - BlackPixel(XT_display, DefaultScreen(XT_display)), 1); - lpcur->pixmask = lpcur->pixshape; - bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); - fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display)); -printf("LoadCursor / before XCreatePixmapCursor !\n"); - lpcur->xcursor = XCreatePixmapCursor(XT_display, - lpcur->pixshape, lpcur->pixmask, - &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, - lpcur->descriptor.curYHotspot); - - ReleaseDC(0, hdc); - GlobalUnlock(rsc_mem); - GlobalFree(rsc_mem); - return hCursor; -} - - - -/********************************************************************** - * DestroyCursor [USER.458] - */ -BOOL DestroyCursor(HCURSOR hCursor) -{ - CURSORALLOC *lpcur; - if (hCursor == (HCURSOR)NULL) return FALSE; - lpcur = (CURSORALLOC *)GlobalLock(hCursor); - if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap); - GlobalUnlock(hCursor); - GlobalFree(hCursor); - return TRUE; -} - - -/********************************************************************** - * SetCursor [USER.69] - */ -HCURSOR SetCursor(HCURSOR hCursor) -{ - HDC hDC; - HDC hMemDC; - BITMAP bm; - CURSORALLOC *lpcur; - HCURSOR hOldCursor; -#ifdef DEBUG_CURSOR - printf("SetCursor / hCursor=%04X !\n", hCursor); -#endif - if (hCursor == (HCURSOR)NULL) return FALSE; - lpcur = (CURSORALLOC *)GlobalLock(hCursor); - hOldCursor = hActiveCursor; - -printf("SetCursor / before XDefineCursor !\n"); - XDefineCursor(XT_display, DefaultRootWindow(XT_display), lpcur->xcursor); - GlobalUnlock(hCursor); - hActiveCursor = hCursor; - return hOldCursor; -} - - -/********************************************************************** - * ShowCursor [USER.71] - */ -int ShowCursor(BOOL bShow) -{ - if (bShow) { - } - return 0; -} - - /********************************************************************** * LoadAccelerators */ @@ -586,6 +428,10 @@ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) if (instance == 0) return 0; +#ifdef DEBUG_RESOURCE + printf("FindResource hInst=%04X typename=%08X resname=%08X\n", + instance, type_name, resource_name); +#endif if (OpenResourceFile(instance) < 0) return 0; @@ -644,6 +490,8 @@ HANDLE LoadResource(HANDLE instance, HANDLE hResInfo) h = r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size); image = GlobalLock(h); + lseek(ResourceFd, ((int) r->nameinfo.offset << r->size_shift), SEEK_SET); + if (image == NULL || read(ResourceFd, image, image_size) != image_size) { GlobalFree(h); diff --git a/loader/selector.c b/loader/selector.c index f091d1da963..5edee7fa4d7 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -7,7 +7,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> -#ifdef linux +#ifdef __linux__ #include <linux/unistd.h> #include <linux/head.h> #include <linux/mman.h> @@ -38,17 +38,16 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #define UTEXTSEL 0x1f #endif -static struct segment_descriptor_s * EnvironmentSelector = NULL; -static struct segment_descriptor_s * PSP_Selector = NULL; -struct segment_descriptor_s * MakeProcThunks = NULL; +static SEGDESC * EnvironmentSelector = NULL; +static SEGDESC * PSP_Selector = NULL; +SEGDESC * MakeProcThunks = NULL; unsigned short PSPSelector; unsigned char ran_out = 0; -unsigned short SelectorOwners[MAX_SELECTORS]; -unsigned short SelectorMap[MAX_SELECTORS]; -unsigned short SelectorLimits[MAX_SELECTORS]; -unsigned char SelectorTypes[MAX_SELECTORS]; int LastUsedSelector = FIRST_SELECTOR - 1; +unsigned short SelectorMap[MAX_SELECTORS]; +SEGDESC Segments[MAX_SELECTORS]; + #ifdef DEV_ZERO static FILE *zfile = NULL; #endif @@ -83,6 +82,74 @@ FindUnusedSelector(void) return i; } +#ifdef HAVE_IPC +/********************************************************************** + * IPCCopySelector + */ +int +IPCCopySelector(int i_old, int i_new, int swap_type) +{ + SEGDESC *s_new, *s_old; + + s_old = &Segments[i_old]; + s_new = &Segments[i_new]; + + SelectorMap[i_new] = i_new; + + s_new->selector = (i_new << 3) | 0x0007; + s_new->base_addr = (void *) ((long) s_new->selector << 16); + s_new->length = s_old->length; + s_new->flags = s_old->flags; + s_new->owner = s_old->owner; + if (swap_type) + { + if (s_old->type == MODIFY_LDT_CONTENTS_DATA) + s_new->type = MODIFY_LDT_CONTENTS_CODE; + else + s_new->type = MODIFY_LDT_CONTENTS_DATA; + } + else + s_new->type = s_old->type; + + if (s_old->shm_key == 0) + { + s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, 0600); + if (s_old->shm_key == 0) + { + memset(s_new, 0, sizeof(*s_new)); + return 0; + } + if (shmat(s_old->shm_key, s_new->base_addr, 0) == NULL) + { + memset(s_new, 0, sizeof(*s_new)); + shmctl(s_old->shm_key, IPC_RMID, NULL); + return 0; + } + memcpy(s_new->base_addr, s_old->base_addr, s_new->length); + munmap(s_old->base_addr, + ((s_old->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + shmat(s_old->shm_key, s_old->base_addr, 0); + } + else + { + if (shmat(s_old->shm_key, s_new->base_addr, 0) == NULL) + { + memset(s_new, 0, sizeof(*s_new)); + return 0; + } + } + s_new->shm_key = s_old->shm_key; + + if (set_ldt_entry(i_new, (unsigned long) s_new->base_addr, + s_new->length - 1, 0, s_new->type, 0, 0) < 0) + { + return 0; + } + + return s_new->selector; +} +#endif + /********************************************************************** * AllocSelector * @@ -92,32 +159,38 @@ FindUnusedSelector(void) unsigned int AllocSelector(unsigned int old_selector) { + SEGDESC *s_new, *s_old; int i_new, i_old; - long base; i_new = FindUnusedSelector(); + s_new = &Segments[i_new]; + if (old_selector) { i_old = (old_selector >> 3); - SelectorMap[i_new] = i_old; - base = SAFEMAKEPTR(old_selector, 0); - if (set_ldt_entry(i_new, base, - SelectorLimits[i_old], 0, - SelectorTypes[i_old], 0, 0) < 0) +#ifdef HAVE_IPC + return IPCCopySelector(i_old, i_new, 0); +#else + s_old = &Segments[i_old]; + s_new->selector = (i_new << 3) | 0x0007; + *s_new = *s_old; + SelectorMap[i_new] = SelectorMap[i_old]; + + if (set_ldt_entry(i_new, s_new->base_addr, + s_new->length - 1, 0, + s_new->type, 0, 0) < 0) { return 0; } - - SelectorLimits[i_new] = SelectorLimits[i_old]; - SelectorTypes[i_new] = SelectorTypes[i_old]; - SelectorMap[i_new] = SelectorMap[i_old]; +#endif } else { + memset(s_new, 0, sizeof(*s_new)); SelectorMap[i_new] = i_new; } - return i_new; + return (i_new << 3) | 0x0007; } /********************************************************************** @@ -128,35 +201,64 @@ AllocSelector(unsigned int old_selector) */ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) { - long dst_base, src_base; +#ifdef HAVE_IPC + SEGDESC *src_s; + int src_idx, dst_idx; + + src_idx = src_selector >> 3; + dst_idx = dst_selector >> 3; + + if (src_idx == dst_idx) + { + src_s = &Segments[src_idx]; + + if (src_s->type == MODIFY_LDT_CONTENTS_DATA) + src_s->type = MODIFY_LDT_CONTENTS_CODE; + else + src_s->type = MODIFY_LDT_CONTENTS_DATA; + + if (set_ldt_entry(src_idx, (long) src_s->base_addr, + src_s->length - 1, 0, src_s->type, 0, 0) < 0) + { + return 0; + } + + return src_s->selector; + } + else + { + return IPCCopySelector(src_idx, dst_idx, 1); + } +#else /* HAVE_IPC */ + SEGDESC *src_s, *dst_s; char *p; int src_idx, dst_idx; int alias_count; int i; - + src_idx = (SelectorMap[src_selector >> 3]); dst_idx = dst_selector >> 3; - src_base = (src_idx << 19) | 0x70000; - dst_base = (dst_idx << 19) | 0x70000; + src_s = &Segments[src_idx]; + dst_s = &Segments[dst_idx]; alias_count = 0; for (i = FIRST_SELECTOR; i < MAX_SELECTORS; i++) if (SelectorMap[i] == src_idx) alias_count++; - if (SelectorTypes[src_idx] == MODIFY_LDT_CONTENTS_DATA + if (src_s->type == MODIFY_LDT_CONTENTS_DATA || alias_count > 1 || src_idx == dst_idx) { - if (SelectorTypes[src_idx] == MODIFY_LDT_CONTENTS_DATA) - SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_CODE; + *dst_s = *src_s; + + if (src_s->type == MODIFY_LDT_CONTENTS_DATA) + dst_s->type = MODIFY_LDT_CONTENTS_CODE; else - SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_DATA; + dst_s->type = MODIFY_LDT_CONTENTS_DATA; SelectorMap[dst_idx] = SelectorMap[src_idx]; - SelectorLimits[dst_idx] = SelectorLimits[src_idx]; - if (set_ldt_entry(dst_idx, src_base, - SelectorLimits[dst_idx], 0, - SelectorTypes[dst_idx], 0, 0) < 0) + if (set_ldt_entry(dst_idx, (long) dst_s->base_addr, + dst_s->length - 1, 0, dst_s->type, 0, 0) < 0) { return 0; } @@ -168,20 +270,22 @@ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) * segment. The SAFEST (but ugliest) way to deal with * this is to map the new segment and copy all the contents. */ - SelectorTypes[dst_idx] = MODIFY_LDT_CONTENTS_DATA; - SelectorMap[dst_idx] = SelectorMap[src_idx]; - SelectorLimits[dst_idx] = SelectorLimits[src_idx]; + SelectorMap[dst_idx] = dst_idx; + *dst_s = *src_s; + dst_s->selector = (dst_idx << 3) | 0x0007; + dst_s->base_addr = (void *) ((unsigned int) dst_s->selector << 16); + dst_s->type = MODIFY_LDT_CONTENTS_DATA; #ifdef DEV_ZERO if (zfile == NULL) zfile = fopen("/dev/zero","r"); - p = (void *) mmap((char *) dst_base, - ((SelectorLimits[dst_idx] + PAGE_SIZE) + p = (void *) mmap((char *) dst_s->base_addr, + ((dst_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); #else - p = (void *) mmap((char *) dst_base, - ((SelectorLimits[dst_idx] + PAGE_SIZE) + p = (void *) mmap((char *) dst_s->base_addr, + ((dst_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); @@ -189,23 +293,27 @@ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector) if (p == NULL) return 0; - memcpy((void *) dst_base, (void *) src_base, - SelectorLimits[dst_idx] + 1); - if (set_ldt_entry(src_idx, dst_base, - SelectorLimits[dst_idx], 0, - SelectorTypes[dst_idx], 0, 0) < 0) + memcpy((void *) dst_s->base_addr, (void *) src_s->base_addr, + dst_s->length); + if (set_ldt_entry(src_idx, dst_s->base_addr, + dst_s->length - 1, 0, dst_s->type, 0, 0) < 0) { return 0; } - if (set_ldt_entry(dst_idx, dst_base, - SelectorLimits[dst_idx], 0, - SelectorTypes[dst_idx], 0, 0) < 0) + if (set_ldt_entry(dst_idx, dst_s->base_addr, + dst_s->length - 1, 0, dst_s->type, 0, 0) < 0) { return 0; } + + munmap(src_s->base_addr, + (src_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)); + SelectorMap[src_idx] = dst_idx; + src_s->base_addr = dst_s->base_addr; } - return (dst_idx << 3) | 0x0007; + return dst_s->selector; +#endif /* HAVE_IPC */ } /********************************************************************** @@ -227,12 +335,46 @@ AllocDStoCSAlias(unsigned int ds_selector) */ unsigned int FreeSelector(unsigned int sel) { + SEGDESC *s; int sel_idx; int alias_count; int i; + +#ifdef HAVE_IPC + sel_idx = sel >> 3; + + if (sel_idx < FIRST_SELECTOR || sel_idx >= MAX_SELECTORS) + return 0; + s = &Segments[sel_idx]; + if (s->shm_key == 0) + { + munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + memcpy(s, 0, sizeof(*s)); + SelectorMap[sel_idx] = 0; + } + else + { + shmdt(s->base_addr); + + alias_count = 0; + for (i = FIRST_SELECTOR; i < MAX_SELECTORS; i++) + if (SelectorMap[i] && Segments[i].shm_key == s->shm_key) + alias_count++; + + if (alias_count == 1) + shmctl(s->shm_key, IPC_RMID, NULL); + + memcpy(s, 0, sizeof(*s)); + SelectorMap[sel_idx] = 0; + } + +#else /* HAVE_IPC */ sel_idx = SelectorMap[sel >> 3]; + if (sel_idx < FIRST_SELECTOR || sel_idx >= MAX_SELECTORS) + return 0; + if (sel_idx != (sel >> 3)) { SelectorMap[sel >> 3] = 0; @@ -246,10 +388,12 @@ unsigned int FreeSelector(unsigned int sel) if (alias_count == 1) { - munmap((char *) (sel << 16), - ((SelectorLimits[sel_idx] + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + s = &Segments[sel_idx]; + munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); + memcpy(s, 0, sizeof(*s)); SelectorMap[sel >> 3] = 0; } +#endif /* HAVE_IPC */ return 0; } @@ -257,10 +401,10 @@ unsigned int FreeSelector(unsigned int sel) /********************************************************************** * CreateNewSegment */ -struct segment_descriptor_s * +SEGDESC * CreateNewSegment(int code_flag, int read_only, int length) { - struct segment_descriptor_s *s; + SEGDESC *s; int contents; int i; @@ -269,7 +413,7 @@ CreateNewSegment(int code_flag, int read_only, int length) /* * Fill in selector info. */ - s = malloc(sizeof(*s)); + s = &Segments[i]; if (code_flag) { contents = MODIFY_LDT_CONTENTS_CODE; @@ -305,13 +449,12 @@ CreateNewSegment(int code_flag, int read_only, int length) (s->length - 1) & 0xffff, 0, contents, read_only, 0) < 0) { - free(s); + memset(s, 0, sizeof(*s)); return NULL; } SelectorMap[i] = (unsigned short) i; - SelectorLimits[i] = s->length - 1; - SelectorTypes[i] = contents; + s->type = contents; return s; } @@ -319,7 +462,7 @@ CreateNewSegment(int code_flag, int read_only, int length) /********************************************************************** * GetNextSegment */ -struct segment_descriptor_s * +SEGDESC * GetNextSegment(unsigned int flags, unsigned int limit) { return CreateNewSegment(0, 0, limit); @@ -494,11 +637,11 @@ GetDOSEnvironment() /********************************************************************** * CreateEnvironment */ -static struct segment_descriptor_s * +static SEGDESC * CreateEnvironment(void) { char *p; - struct segment_descriptor_s * s; + SEGDESC * s; s = CreateNewSegment(0, 0, PAGE_SIZE); if (s == NULL) @@ -521,12 +664,12 @@ CreateEnvironment(void) /********************************************************************** * CreatePSP */ -static struct segment_descriptor_s * +static SEGDESC * CreatePSP(void) { struct dos_psp_s *psp; unsigned short *usp; - struct segment_descriptor_s * s; + SEGDESC * s; char *p1, *p2; int i; @@ -572,13 +715,13 @@ CreatePSP(void) /********************************************************************** * CreateSelectors */ -struct segment_descriptor_s * +SEGDESC * CreateSelectors(struct w_files * wpnt) { int fd = wpnt->fd; struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; struct ne_header_s *ne_header = wpnt->ne_header; - struct segment_descriptor_s *selectors, *s, *stmp; + SEGDESC *selectors, *s, *stmp; unsigned short auto_data_sel; int contents, read_only; int SelectorTableLength; @@ -692,7 +835,7 @@ CreateSelectors(struct w_files * wpnt) s = selectors; for (i = 0; i < ne_header->n_segment_tab; i++, s++) - SelectorOwners[s->selector >> 3] = auto_data_sel; + Segments[s->selector >> 3].owner = auto_data_sel; if(!EnvironmentSelector) { EnvironmentSelector = CreateEnvironment(); diff --git a/loader/signal.c b/loader/signal.c index 7b2727cae54..b2a492e221f 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -3,7 +3,11 @@ #include <stdlib.h> #include <time.h> +#ifdef __NetBSD__ +#include <sys/syscall.h> +#else #include <syscall.h> +#endif #include <signal.h> #include <errno.h> #ifdef linux @@ -85,11 +89,11 @@ static void win_fault(int signal, int code, struct sigcontext *scp){ if(!do_int21(scp)) goto oops; break; case 0x11: - scp->sc_eax = 0x00000000; /* get equipment list: we haven't */ - break; /* got anything */ + scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment(); + break; case 0x12: - scp->sc_eax = 640L; /* get base mem size */ - break; + scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L; + break; /* get base mem size */ case 0x1A: if(!do_int1A(scp)) goto oops; break; diff --git a/loader/wine.c b/loader/wine.c index 7124317f09a..60b606bbf4a 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -28,11 +28,14 @@ extern void CallTo32(); char * GetModuleName(struct w_files * wpnt, int index, char *buffer); extern unsigned char ran_out; +extern char WindowsPath[256]; unsigned short WIN_StackSize; unsigned short WIN_HeapSize; struct w_files * wine_files = NULL; +int WineForceFail = 0; + char **Argv; int Argc; struct mz_header_s *CurrentMZHeader; @@ -40,11 +43,9 @@ struct ne_header_s *CurrentNEHeader; int CurrentNEFile; HINSTANCE hSysRes; -static char *dllExtensions[] = { "dll", "exe", NULL }; -static char *exeExtensions[] = { "exe", NULL }; +static char *Extensions[] = { "dll", "exe", NULL }; static char *WinePath = NULL; - /********************************************************************** * DebugPrintString */ @@ -101,12 +102,13 @@ GetFileInfo(unsigned short instance) * LoadImage * Load one NE format executable into memory */ -HINSTANCE LoadImage(char * filename, char * modulename) +HINSTANCE LoadImage(char *modulename) { unsigned int read_size; int i; struct w_files * wpnt, *wpnt1; unsigned int status; + char buffer[256]; /* First allocate a spot to store the info we collect, and add it to * our linked list. @@ -122,10 +124,24 @@ HINSTANCE LoadImage(char * filename, char * modulename) }; wpnt->next = NULL; + /* + * search file + */ + + if (FindFile(buffer, sizeof(buffer), modulename, Extensions, WindowsPath) + ==NULL) + { + char temp[256]; + + sprintf(temp,"LoadImage: I can't find %s !\n",modulename); + myerror(temp); + } + fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer); + /* * Open file for reading. */ - wpnt->fd = open(filename, O_RDONLY); + wpnt->fd = open(buffer, O_RDONLY); if (wpnt->fd < 0) { myerror(NULL); @@ -133,7 +149,7 @@ HINSTANCE LoadImage(char * filename, char * modulename) /* * Establish header pointers. */ - wpnt->filename = strdup(filename); + wpnt->filename = strdup(buffer); wpnt->name = NULL; if(modulename) wpnt->name = strdup(modulename); @@ -181,7 +197,7 @@ HINSTANCE LoadImage(char * filename, char * modulename) wpnt->selector_table = CreateSelectors(wpnt); wpnt->hinstance = wpnt-> - selector_table[wine_files->ne_header->auto_data_seg-1].selector; + selector_table[wpnt->ne_header->auto_data_seg-1].selector; /* Get the lookup table. This is used for looking up the addresses of functions that are exported */ @@ -227,16 +243,10 @@ HINSTANCE LoadImage(char * filename, char * modulename) if(FindDLLTable(buff)) continue; /* This module already loaded */ - if (FindFileInPath(buff2, sizeof(buff2), - buff, dllExtensions, WinePath) != NULL && - (fd = open(buff2, O_RDONLY)) >= 0) - { - close(fd); - LoadImage(buff2, buff); - continue; - } - + LoadImage(buff); +/* fprintf(stderr,"Unable to load:%s\n", buff); +*/ } return(wpnt->hinstance); } @@ -249,6 +259,8 @@ _WinMain(int argc, char **argv) { int segment; char *p; + char *sysresname; + char syspath[256]; char exe_path[256]; #ifdef WINESTAT char * cp; @@ -273,19 +285,20 @@ _WinMain(int argc, char **argv) strcat(WinePath, ";"); strcat(WinePath, p); - if (FindFileInPath(exe_path, 256, argv[1], exeExtensions, WinePath) - == NULL) - { - fprintf(stderr, "Could not find file '%s'\n", argv[1]); - exit(1); - } - - LoadImage(exe_path, NULL); - hSysRes = LoadImage("sysres.dll", NULL); + LoadImage(argv[1]); + hSysRes = LoadImage("sysres.dll"); + if (hSysRes == (HINSTANCE)NULL) + printf("Error Loading System Resources !!!\n"); + else + printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes); if(ran_out) exit(1); #ifdef DEBUG - GetEntryDLLName("USER", "INITAPP", 0, 0); + { + int dummy1, dummy2; + + GetEntryDLLName("USER", "INITAPP", &dummy1, &dummy2); + } for(i=0; i<1024; i++) { int j; j = GetEntryPointFromOrdinal(wine_files, i); @@ -327,6 +340,21 @@ _WinMain(int argc, char **argv) init_wine_signals(); + if (WineForceFail) + { + p = (char *) ((cs_reg << 16) | ip_reg); + + *p++ = 0xcd; + *p++ = 0x20; + } + + if (ss_reg == 0) + { + fprintf(stderr, "SS is 0. Send email to bob@amscons.com.\n"); + fprintf(stderr, " No. Really. I want to know what programs\n"); + fprintf(stderr, " do this.\n"); + } + rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg); printf ("rv = %x\n", rv); } @@ -392,12 +420,11 @@ GetModuleName(struct w_files * wpnt, int index, char *buffer) int FixupSegment(struct w_files * wpnt, int segment_num) { - int fd = wpnt->fd; - struct mz_header_s * mz_header = wpnt->mz_header; - struct ne_header_s *ne_header = wpnt->ne_header; - struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; - struct segment_descriptor_s *selector_table = wpnt->selector_table; - + int fd = wpnt->fd; + struct mz_header_s * mz_header = wpnt->mz_header; + struct ne_header_s *ne_header = wpnt->ne_header; + struct ne_segment_table_entry_s *seg_table = wpnt->seg_table; + struct segment_descriptor_s *selector_table = wpnt->selector_table; struct relocation_entry_s *rep, *rep1; struct ne_segment_table_entry_s *seg; struct segment_descriptor_s *sel; @@ -410,10 +437,14 @@ FixupSegment(struct w_files * wpnt, int segment_num) char dll_name[257]; char func_name[257]; int i, n_entries; + int additive; seg = &seg_table[segment_num]; sel = &selector_table[segment_num]; + fprintf(stderr, "Segment fixups for %s, segment %d, selector %x\n", + wpnt->name, segment_num, (int) sel->base_addr >> 16); + if ((seg->seg_data_offset == 0) || !(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA)) return 0; @@ -445,8 +476,13 @@ FixupSegment(struct w_files * wpnt, int segment_num) /* * Get the target address corresponding to this entry. */ + additive = 0; + switch (rep->relocation_type) { + case NE_RELTYPE_ORDINALADD: + additive = 1; + case NE_RELTYPE_ORDINAL: if (GetModuleName(wpnt, rep->target1, dll_name) == NULL) @@ -474,6 +510,9 @@ FixupSegment(struct w_files * wpnt, int segment_num) #endif break; + case NE_RELTYPE_NAMEADD: + additive = 1; + case NE_RELTYPE_NAME: if (GetModuleName(wpnt, rep->target1, dll_name) == NULL) @@ -543,30 +582,50 @@ FixupSegment(struct w_files * wpnt, int segment_num) continue; default: -#ifndef DEBUG_FIXUP fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", i + 1, rep->address_type, rep->relocation_type, rep->offset); - fprintf(stderr,"TARGET %04.4x %04.4x\n", rep->target1, rep->target2); -#endif + fprintf(stderr,"TARGET %04.4x %04.4x\n", + rep->target1, rep->target2); free(rep1); - return -1; +#if 0 + sp = (unsigned short *) ((char *) sel->base_addr + rep->offset); + fprintf(stderr, " FIXUP ADDRESS %04.4x:%04.4x\n", + (int) sel->base_addr >> 16, rep->offset); + WineForceFail = 1; + continue; +#endif } /* * Stuff the right size result in. */ sp = (unsigned short *) ((char *) sel->base_addr + rep->offset); + if (additive) + { + if (FindDLLTable(dll_name) == NULL) + additive = 2; + + fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", + i + 1, rep->address_type, rep->relocation_type, + rep->offset); + fprintf(stderr,"TARGET %04.4x %04.4x\n", + rep->target1, rep->target2); + fprintf(stderr, " Additive = %d\n", additive); + } + switch (rep->address_type) { case NE_RADDR_OFFSET16: do { next_addr = *sp; *sp = (unsigned short) address; + if (additive == 2) + *sp += next_addr; sp = (unsigned short *) ((char *) sel->base_addr + next_addr); } - while (next_addr != 0xffff); + while (next_addr != 0xffff && !additive); break; @@ -574,10 +633,12 @@ FixupSegment(struct w_files * wpnt, int segment_num) do { next_addr = *sp; *sp = (unsigned short) address; + if (additive == 2) + *sp += next_addr; *(sp+1) = (unsigned short) selector; sp = (unsigned short *) ((char *) sel->base_addr + next_addr); } - while (next_addr != 0xffff); + while (next_addr != 0xffff && !additive); break; @@ -589,17 +650,15 @@ FixupSegment(struct w_files * wpnt, int segment_num) if (rep->relocation_type == NE_RELTYPE_INT1) break; } - while (next_addr != 0xffff); + while (next_addr != 0xffff && !additive); break; default: -#ifndef DEBUG_FIXUP printf("%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", i + 1, rep->address_type, rep->relocation_type, rep->offset); printf("TARGET %04.4x %04.4x\n", rep->target1, rep->target2); -#endif free(rep1); return -1; } diff --git a/memory/Imakefile b/memory/Imakefile new file mode 100644 index 00000000000..edf4b6d5604 --- /dev/null +++ b/memory/Imakefile @@ -0,0 +1,21 @@ +#include "../Wine.tmpl" + +MODULE = memory + +SRCS = \ + global.c \ + heap.c \ + atom.c + +OBJS = \ + global.o \ + heap.o \ + atom.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/memory/Makefile b/memory/Makefile index b624e09fd6f..f3ff2c766b6 100644 --- a/memory/Makefile +++ b/memory/Makefile @@ -1,6 +1,6 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) -OBJS=global.o heap.o +OBJS=global.o heap.o atom.o default: memory.o diff --git a/memory/atom.c b/memory/atom.c new file mode 100644 index 00000000000..1fd5f489f89 --- /dev/null +++ b/memory/atom.c @@ -0,0 +1,328 @@ +/* + * Atom table functions + * + * Copyright 1993 Alexandre Julliard + */ + +/* + * 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. + * + * - Integer atoms created with MAKEINTATOM are not supported. This is + * because they can't generally be differentiated from string constants + * located below 0x10000 in the emulation library. If you need + * integer atoms, use the "#1234" form. + */ + +#include <stdlib.h> +#include <string.h> + +#include "atom.h" + + +#define DEFAULT_ATOMTABLE_SIZE 37 +#define MIN_STR_ATOM 0xc000 + +#define ATOMTOHANDLE(atom) ((HANDLE)(atom) << 2) +#define HANDLETOATOM(handle) ((ATOM)(0xc000 | ((handle) >> 2))) + + +static ATOMTABLE * localTable = NULL; +static ATOMTABLE * globalTable = NULL; + + +/*********************************************************************** + * ATOM_InitTable + */ +static BOOL ATOM_InitTable( ATOMTABLE ** table, WORD entries ) +{ + int i; + HANDLE handle; + + handle = LocalAlloc( 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; + return TRUE; + +} + + +/*********************************************************************** + * ATOM_Init + * + * Global table initialisation. + */ +BOOL ATOM_Init() +{ + return ATOM_InitTable( &globalTable, DEFAULT_ATOMTABLE_SIZE ); +} + + +/*********************************************************************** + * ATOM_MakePtr + * + * Make an ATOMENTRY pointer from a handle (obtained from GetAtomHandle()). + * Is is assumed that the atom is in the same segment as the table. + */ +static ATOMENTRY * ATOM_MakePtr( ATOMTABLE * table, HANDLE handle ) +{ + return (ATOMENTRY *) (((int)table & 0xffff0000) | (int)handle); +} + + +/*********************************************************************** + * ATOM_Hash + */ +static WORD ATOM_Hash( WORD entries, LPCSTR str, WORD len ) +{ + WORD i, hash = 0; + + for (i = 0; i < len; i++) hash ^= str[i] + i; + return hash % entries; +} + + +/*********************************************************************** + * ATOM_AddAtom + */ +static ATOM ATOM_AddAtom( ATOMTABLE * table, LPCSTR str ) +{ + WORD hash; + HANDLE entry; + ATOMENTRY * entryPtr; + int len; + + if ((len = strlen( str )) > 255) len = 255; + + /* Check for integer atom */ +/* if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */ + if (str[0] == '#') return atoi( &str[1] ); + + hash = ATOM_Hash( table->size, str, len ); + entry = table->entries[hash]; + while (entry) + { + entryPtr = ATOM_MakePtr( table, entry ); + if ((entryPtr->length == len) && + (!strncasecmp( entryPtr->str, str, len ))) + { + entryPtr->refCount++; + return HANDLETOATOM( entry ); + } + entry = entryPtr->next; + } + + entry = (int)LocalAlloc( LMEM_MOVEABLE, sizeof(ATOMENTRY)+len-1 ) & 0xffff; + if (!entry) return 0; + entryPtr = ATOM_MakePtr( table, entry ); + entryPtr->next = table->entries[hash]; + entryPtr->refCount = 1; + entryPtr->length = len; + memcpy( entryPtr->str, str, len ); + table->entries[hash] = entry; + return HANDLETOATOM( entry ); +} + + +/*********************************************************************** + * ATOM_DeleteAtom + */ +static ATOM ATOM_DeleteAtom( ATOMTABLE * table, ATOM atom ) +{ + ATOMENTRY * entryPtr; + HANDLE entry, *prevEntry; + WORD hash; + + if (atom < MIN_STR_ATOM) return 0; /* Integer atom */ + + entry = ATOMTOHANDLE( atom ); + entryPtr = ATOM_MakePtr( table, entry ); + + /* Find previous atom */ + hash = ATOM_Hash( table->size, entryPtr->str, entryPtr->length ); + prevEntry = &table->entries[hash]; + while (*prevEntry && *prevEntry != entry) + { + ATOMENTRY * prevEntryPtr = ATOM_MakePtr( table, *prevEntry ); + prevEntry = &prevEntryPtr->next; + } + if (!*prevEntry) return atom; + + /* Delete atom */ + if (--entryPtr->refCount == 0) + { + *prevEntry = entryPtr->next; + LocalFree( entry ); + } + return 0; +} + + +/*********************************************************************** + * ATOM_FindAtom + */ +static ATOM ATOM_FindAtom( ATOMTABLE * table, LPCSTR str ) +{ + WORD hash; + HANDLE entry; + int len; + + if ((len = strlen( str )) > 255) len = 255; + + /* Check for integer atom */ +/* if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */ + if (str[0] == '#') return atoi( &str[1] ); + + hash = ATOM_Hash( table->size, str, len ); + entry = table->entries[hash]; + while (entry) + { + ATOMENTRY * entryPtr = ATOM_MakePtr( table, entry ); + if ((entryPtr->length == len) && + (!strncasecmp( entryPtr->str, str, len ))) + return HANDLETOATOM( entry ); + entry = entryPtr->next; + } + return 0; +} + + +/*********************************************************************** + * ATOM_GetAtomName + */ +static WORD ATOM_GetAtomName( ATOMTABLE * table, ATOM atom, + LPSTR buffer, short count ) +{ + ATOMENTRY * entryPtr; + HANDLE entry; + char * strPtr; + int len; + char text[8]; + + if (!count) return 0; + if (atom < MIN_STR_ATOM) + { + sprintf( text, "#%d", atom ); + len = strlen(text); + strPtr = text; + } + else + { + entry = ATOMTOHANDLE( atom ); + entryPtr = ATOM_MakePtr( table, entry ); + len = entryPtr->length; + strPtr = entryPtr->str; + } + if (len >= count) len = count-1; + memcpy( buffer, strPtr, len ); + buffer[len] = '\0'; + return len; +} + + +/*********************************************************************** + * InitAtomTable (KERNEL.68) + */ +BOOL InitAtomTable( WORD entries ) +{ + return ATOM_InitTable( &localTable, entries ); +} + + +/*********************************************************************** + * GetAtomHandle (KERNEL.73) + */ +HANDLE GetAtomHandle( ATOM atom ) +{ + if (atom < MIN_STR_ATOM) return 0; + return ATOMTOHANDLE( atom ); +} + + +/*********************************************************************** + * AddAtom (KERNEL.70) + */ +ATOM AddAtom( LPCSTR str ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_AddAtom( localTable, str ); +} + + +/*********************************************************************** + * DeleteAtom (KERNEL.71) + */ +ATOM DeleteAtom( ATOM atom ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_DeleteAtom( localTable, atom ); +} + + +/*********************************************************************** + * FindAtom (KERNEL.69) + */ +ATOM FindAtom( LPCSTR str ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_FindAtom( localTable, str ); +} + + +/*********************************************************************** + * GetAtomName (KERNEL.72) + */ +WORD GetAtomName( ATOM atom, LPSTR buffer, short count ) +{ + if (!localTable) InitAtomTable( DEFAULT_ATOMTABLE_SIZE ); + return ATOM_GetAtomName( localTable, atom, buffer, count ); +} + + +/*********************************************************************** + * GlobalAddAtom (USER.268) + */ +ATOM GlobalAddAtom( LPCSTR str ) +{ + return ATOM_AddAtom( globalTable, str ); +} + + +/*********************************************************************** + * GlobalDeleteAtom (USER.269) + */ +ATOM GlobalDeleteAtom( ATOM atom ) +{ + return ATOM_DeleteAtom( globalTable, atom ); +} + + +/*********************************************************************** + * GlobalFindAtom (USER.270) + */ +ATOM GlobalFindAtom( LPCSTR str ) +{ + return ATOM_FindAtom( globalTable, str ); +} + + +/*********************************************************************** + * GlobalGetAtomName (USER.271) + */ +WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count ) +{ + return ATOM_GetAtomName( globalTable, atom, buffer, count ); +} diff --git a/memory/global.c b/memory/global.c index 169ebc3878a..bf11b370f13 100644 --- a/memory/global.c +++ b/memory/global.c @@ -75,7 +75,7 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) else if (count) count = 0; } - + /* * If we couldn't find enough segments, then we need to create some. */ @@ -87,18 +87,22 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) g_prev = NULL; for (g = GlobalList; g != NULL; g = g->next) g_prev = g; - + /* * Allocate segments. */ for (count = 0; count < n_segments; count++) { s = GetNextSegment(flags, 0x10000); - if (s == NULL) + if (s == NULL) { + printf("GlobalGetFreeSegments // bad GetNextSegment !\n"); return NULL; - + } g = (GDESC *) malloc(sizeof(*g)); - + if (g == NULL) { + printf("GlobalGetFreeSegments // bad GDESC malloc !\n"); + return NULL; + } g->prev = g_prev; g->next = NULL; g->handle = s->selector; @@ -110,18 +114,15 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) else g->lock_count = 0; - free(s); - - if (count == 0) - g_start = g; + if (count == 0) g_start = g; if (g_prev != NULL) { g_prev->next = g; - g->prev = g_prev; } else GlobalList = g; + g_prev = g; } } @@ -131,6 +132,10 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) g = g_start; for (i = 0; i < n_segments; i++, g = g->next) { + if (g == NULL) { + printf("GlobalGetFreeSegments // bad Segments chain !\n"); + return NULL; + } g->sequence = i + 1; g->length = n_segments; } diff --git a/misc/Imakefile b/misc/Imakefile new file mode 100644 index 00000000000..53eda7629f5 --- /dev/null +++ b/misc/Imakefile @@ -0,0 +1,45 @@ +#include "../Wine.tmpl" + +MODULE = misc + +SRCS = \ + kernel.c \ + user.c \ + rect.c \ + file.c \ + sound.c \ + emulate.c \ + keyboard.c \ + profile.c \ + lstr.c \ + exec.c \ + message.c \ + int1a.c \ + int21.c \ + dos_fs.c \ + xt.c + +OBJS = \ + kernel.o \ + user.o \ + rect.o \ + file.o \ + sound.o \ + emulate.o \ + keyboard.o \ + profile.o \ + lstr.o \ + exec.o \ + message.o \ + int1a.o \ + int21.o \ + dos_fs.o \ + xt.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/misc/Makefile b/misc/Makefile index 12180d04200..8cdcee9ea77 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -1,7 +1,8 @@ -CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) +CFLAGS=$(COPTS) $(DEBUGOPTS) -I../include -OBJS=dos.o kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ - keyboard.o profile.o lstr.o exec.o message.o +OBJS=kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ + keyboard.o profile.o lstr.o exec.o message.o int1a.o int21.o \ + dos_fs.o comm.o default: misc.o diff --git a/misc/comm.c b/misc/comm.c new file mode 100644 index 00000000000..c0db9d590ff --- /dev/null +++ b/misc/comm.c @@ -0,0 +1,872 @@ +/* + * DEC 93 Erik Bos (erik@trashcan.hacktic.nl) + */ + +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#ifdef __NetBSD__ +#include <errno.h> +#include <sys/ioctl.h> +#endif +#include "wine.h" +#include "windows.h" + +#define DEBUG_COMM + +#define MAX_PORTS 16 + +int commerror = 0, eventmask = 0; + +struct DosDeviceStruct { + char *devicename; /* /dev/cua1 */ + int fd; + int suspended; +}; + +struct DosDeviceStruct COM[MAX_PORTS]; +struct DosDeviceStruct LPT[MAX_PORTS]; + +void Comm_DeInit(void); + +void Comm_Init(void) +{ + int x, serial = 0, parallel = 0; + char option[10], temp[256], *ptr; + struct stat st; + + for (x=0; x!=MAX_PORTS; x++) { + strcpy(option,"COMx"); + option[3] = '0' + x; + option[4] = '\0'; + + GetPrivateProfileString("serialports", option, "*", temp, sizeof(temp), WINE_INI); + if (!strcmp(temp, "*") || *temp == '\0') + COM[serial].devicename = NULL; + else { + stat(temp, &st); + if (!S_ISCHR(st.st_mode)) + fprintf(stderr,"comm: can 't use `%s' as COM%d !\n", temp, x); + else + if ((ptr = malloc(strlen(temp)+1)) == NULL) + fprintf(stderr,"comm: can't malloc for device info!\n"); + else { + COM[serial].fd = 0; + COM[serial].devicename = ptr; + strcpy(COM[serial++].devicename, temp); + } + } + + strcpy(option, "LPTx"); + option[3] = '0' + x; + option[4] = '\0'; + + GetPrivateProfileString("parallelports", option, "*", temp, sizeof(temp), WINE_INI); + if (!strcmp(temp, "*") || *temp == '\0') + LPT[parallel].devicename = NULL; + else { + stat(temp, &st); + if (!S_ISCHR(st.st_mode)) + fprintf(stderr,"comm: can 't use `%s' as LPT%d !\n", temp, x); + else + if ((ptr = malloc(strlen(temp)+1)) == NULL) + fprintf(stderr,"comm: can't malloc for device info!\n"); + else { + LPT[serial].fd = 0; + LPT[serial].devicename = ptr; + strcpy(LPT[serial++].devicename, temp); + } + } + + } + atexit(Comm_DeInit); + +#ifdef DEBUG_COMM + for (x=0; x!=MAX_PORTS; x++) { + if (COM[x].devicename) + fprintf(stderr, "comm: COM%d = %s\n", x, COM[x].devicename); + if (LPT[x].devicename) + fprintf(stderr, "comm: LPT%d = %s\n", x, LPT[x].devicename); + } +#endif +} + +void Comm_DeInit(void) +{ + int x; + + for (x=0; x!=MAX_PORTS; x++) { + + if (COM[x].devicename) { + if (COM[x].fd) + close(COM[x].fd); + fprintf(stderr, "comm: COM%d = %s\n",x,COM[x].devicename); + free(COM[x].devicename); + } + if (LPT[x].devicename) { + if (LPT[x].fd) + close(LPT[x].fd); + fprintf(stderr, "comm: LPT%d = %s\n",x,LPT[x].devicename); + free(LPT[x].devicename); + } + } +} + +struct DosDeviceStruct *GetDeviceStruct(int fd) +{ + int x; + + for (x=0; x!=MAX_PORTS; x++) { + if (COM[x].fd == fd) + return &COM[x]; + if (LPT[x].fd == fd) + return &LPT[x]; + } + + return NULL; +} + +int ValidCOMPort(int x) +{ + return(x < MAX_PORTS ? (int) COM[x].devicename : 0); +} + +int ValidLPTPort(int x) +{ + return(x < MAX_PORTS ? (int) LPT[x].devicename : 0); +} + +int WinError(void) +{ + perror("comm"); + switch (errno) { + default: + return CE_IOE; + } +} + +int BuildCommDCB(LPSTR device, DCB FAR *lpdcb) +{ + /* "COM1:9600,n,8,1" */ + /* 012345 */ + + int port; + char *ptr, *ptr2, temp[256],temp2[10]; + +#ifdef DEBUG_COMM +fprintf(stderr,"BuildCommDCB: (%s), ptr %d\n", device, lpdcb); +#endif + commerror = 0; + + if (!strncmp(device,"COM",3)) { + port = device[3] - '0'; + + if (!ValidCOMPort(port)) { + commerror = IE_BADID; + return -1; + } + + if (!COM[port].fd) { + commerror = IE_NOPEN; + return -1; + } + lpdcb->Id = COM[port].fd; + + if (!*(device+4)) + return 0; + + if (*(device+4) != ':') + return -1; + + strcpy(temp,device+5); + ptr = strtok(temp, ","); + + fprintf(stderr,"BuildCommDCB: baudrate (%s)\n", ptr); + lpdcb->BaudRate = atoi(ptr); + + ptr = strtok(NULL, ","); + if (islower(*ptr)) + *ptr = toupper(*ptr); + + fprintf(stderr,"BuildCommDCB: parity (%c)\n", *ptr); + switch (*ptr) { + case 'N': + lpdcb->Parity = NOPARITY; + lpdcb->fParity = 0; + break; + + lpdcb->fParity = 1; + + case 'E': + lpdcb->Parity = EVENPARITY; + break; + case 'M': + lpdcb->Parity = MARKPARITY; + break; + case 'O': + lpdcb->Parity = ODDPARITY; + break; + default: + fprintf(stderr,"comm: unknown parity `%c'!\n", *ptr); + return -1; + } + + ptr = strtok(NULL, ","); + fprintf(stderr, "BuildCommDCB: charsize (%c)\n", *ptr); + lpdcb->ByteSize = *ptr - '0'; + + ptr = strtok(NULL, ","); + fprintf(stderr, "BuildCommDCB: stopbits (%c)\n", *ptr); + switch (*ptr) { + case '1': + lpdcb->StopBits = ONESTOPBIT; + break; + case '2': + lpdcb->StopBits = TWOSTOPBITS; + break; + default: + fprintf(stderr,"comm: unknown # of stopbits `%c'!\n", *ptr); + return -1; + } + } + + return 0; +} + +int OpenComm(LPSTR device, UINT cbInQueue, UINT cbOutQueue) +{ + int port, fd; + +#ifdef DEBUG_COMM +fprintf(stderr,"OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue); +#endif + + commerror = 0; + + if (!strncmp(device,"COM",3)) { + port = device[3] - '0'; + + if (!ValidCOMPort(port)) { + commerror = IE_BADID; + return -1; + } + if (COM[port].fd) { + commerror = IE_OPEN; + return -1; + } + + fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK, 0); + if (fd == -1) { + commerror = WinError(); + return -1; + } else { + COM[port].fd = fd; + return fd; + } + } + else + if (!strncmp(device,"LPT",3)) { + port = device[3] - '0'; + + if (!ValidLPTPort(port)) { + commerror = IE_BADID; + return -1; + } + if (LPT[port].fd) { + commerror = IE_OPEN; + return -1; + } + + fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0); + if (fd == -1) { + commerror = WinError(); + return -1; + } else { + LPT[port].fd = fd; + return fd; + } + } + return 0; +} + +int CloseComm(int fd) +{ + int status; + +#ifdef DEBUG_COMM +fprintf(stderr,"CloseComm: fd %d\n", fd); +#endif + + if (close(fd) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int SetCommBreak(int fd) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"SetCommBreak: fd: %d\n", fd); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + ptr->suspended = 1; + commerror = 0; + return 0; +} + +int ClearCommBreak(int fd) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"ClearCommBreak: fd: %d\n", fd); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + ptr->suspended = 0; + commerror = 0; + return 0; +} + +LONG EscapeCommFunction(int fd, int nFunction) +{ + int max; + struct termios port; + +#ifdef DEBUG_COMM +fprintf(stderr,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction); +#endif + + if (tcgetattr(fd, &port) == -1) { + commerror = WinError(); + return -1; + } + + switch (nFunction) { + case RESETDEV: + break; + + case GETMAXCOM: + for (max = 0;COM[max].devicename;max++) + ; + return max; + break; + + case GETMAXLPT: + for (max = 0;LPT[max].devicename;max++) + ; + return 0x80 + max; + break; + + case CLRDTR: + port.c_cflag &= TIOCM_DTR; + break; + + case CLRRTS: + port.c_cflag &= TIOCM_RTS; + break; + + case SETDTR: + port.c_cflag |= CRTSCTS; + break; + + case SETRTS: + port.c_cflag |= CRTSCTS; + break; + + case SETXOFF: + port.c_iflag |= IXOFF; + break; + + case SETXON: + port.c_iflag |= IXON; + break; + + default: + fprintf(stderr,"EscapeCommFunction fd: %d, unknown function: %d\n", fd, nFunction); + break; + } + + if (tcsetattr(fd, TCSADRAIN, &port) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int FlushComm(int fd, int fnQueue) +{ + int queue; + +#ifdef DEBUG_COMM +fprintf(stderr,"FlushComm fd: %d, queue: %d\n", fd, fnQueue); +#endif + + switch (fnQueue) { + case 0: + queue = TCOFLUSH; + break; + case 1: + queue = TCIFLUSH; + break; + default: + fprintf(stderr,"FlushComm fd: %d, UNKNOWN queue: %d\n", fd, fnQueue); + return -1; + } + + if (tcflush(fd, fnQueue)) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int GetCommError(int fd, COMSTAT FAR *lpStat) +{ +#ifdef DEBUG_COMM +fprintf(stderr,"GetCommError: fd %d (current error %d)\n", fd, commerror); +#endif + + return(commerror); +} + +UINT FAR* SetCommEventMask(int fd, UINT fuEvtMask) +{ +#ifdef DEBUG_COMM +fprintf(stderr,"SetCommEventMask: fd %d, mask %d\n", fd, fuEvtMask); +#endif + + eventmask |= fuEvtMask; + return (UINT *)&eventmask; +} + +UINT GetCommEventMask(int fd, int fnEvtClear) +{ +#ifdef DEBUG_COMM +fprintf(stderr,"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear); +#endif + eventmask &= ~fnEvtClear; + return eventmask; +} + +int SetCommState(DCB FAR *lpdcb) +{ + struct termios port; + +#ifdef DEBUG_COMM +fprintf(stderr,"SetCommState: fd %d, ptr %d\n", lpdcb->Id, lpdcb); +#endif + + if (tcgetattr(lpdcb->Id, &port) == -1) { + commerror = WinError(); + return -1; + } + cfmakeraw(&port); + port.c_cc[VMIN] = 0; + port.c_cc[VTIME] = 0; + + fprintf(stderr,"SetCommState: baudrate %d\n",lpdcb->BaudRate); +#ifdef CBAUD + port.c_cflag &= ~CBAUD; + switch (lpdcb->BaudRate) { + case 110: + case CBR_110: + port.c_cflag |= B110; + break; + case 300: + case CBR_300: + port.c_cflag |= B300; + break; + case 600: + case CBR_600: + port.c_cflag |= B600; + break; + case 1200: + case CBR_1200: + port.c_cflag |= B1200; + break; + case 2400: + case CBR_2400: + port.c_cflag |= B2400; + break; + case 4800: + case CBR_4800: + port.c_cflag |= B4800; + break; + case 9600: + case CBR_9600: + port.c_cflag |= B9600; + break; + case 19200: + case CBR_19200: + port.c_cflag |= B19200; + break; + case 38400: + case CBR_38400: + port.c_cflag |= B38400; + break; + default: + commerror = IE_BAUDRATE; + return -1; + } +#else + switch (lpdcb->BaudRate) { + case 110: + case CBR_110: + port.c_ospeed = B110; + break; + case 300: + case CBR_300: + port.c_ospeed = B300; + break; + case 600: + case CBR_600: + port.c_ospeed = B600; + break; + case 1200: + case CBR_1200: + port.c_ospeed = B1200; + break; + case 2400: + case CBR_2400: + port.c_ospeed = B2400; + break; + case 4800: + case CBR_4800: + port.c_ospeed = B4800; + break; + case 9600: + case CBR_9600: + port.c_ospeed = B9600; + break; + case 19200: + case CBR_19200: + port.c_ospeed = B19200; + break; + case 38400: + case CBR_38400: + port.c_ospeed = B38400; + break; + default: + commerror = IE_BAUDRATE; + return -1; + } + port.c_ispeed = port.c_ospeed; +#endif + fprintf(stderr,"SetCommState: bytesize %d\n",lpdcb->ByteSize); + port.c_cflag &= ~CSIZE; + switch (lpdcb->ByteSize) { + case 5: + port.c_cflag |= CS5; + break; + case 6: + port.c_cflag |= CS6; + break; + case 7: + port.c_cflag |= CS7; + break; + case 8: + port.c_cflag |= CS8; + break; + default: + commerror = IE_BYTESIZE; + return -1; + } + + fprintf(stderr,"SetCommState: parity %d\n",lpdcb->Parity); + port.c_cflag &= ~(PARENB | PARODD); + if (lpdcb->fParity) + switch (lpdcb->Parity) { + case NOPARITY: + port.c_iflag &= ~INPCK; + break; + case ODDPARITY: + port.c_cflag |= (PARENB | PARODD); + port.c_iflag |= INPCK; + break; + case EVENPARITY: + port.c_cflag |= PARENB; + port.c_iflag |= INPCK; + break; + default: + commerror = IE_BYTESIZE; + return -1; + } + + + fprintf(stderr,"SetCommState: stopbits %d\n",lpdcb->StopBits); + switch (lpdcb->StopBits) { + case ONESTOPBIT: + port.c_cflag &= ~CSTOPB; + break; + case TWOSTOPBITS: + port.c_cflag |= CSTOPB; + break; + default: + commerror = IE_BYTESIZE; + return -1; + } + + if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow) + port.c_cflag |= CRTSCTS; + + if (lpdcb->fDtrDisable) + port.c_cflag &= ~CRTSCTS; + + if (lpdcb->fInX) + port.c_iflag |= IXON; + if (lpdcb->fOutX) + port.c_iflag |= IXOFF; + + if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int GetCommState(int fd, DCB FAR *lpdcb) +{ + struct termios port; + +#ifdef DEBUG_COMM +fprintf(stderr,"GetCommState: fd %d, ptr %d\n", fd, lpdcb); +#endif + + if (tcgetattr(fd, &port) == -1) { + commerror = WinError(); + return -1; + } + + lpdcb->Id = fd; + +#ifdef CBAUD + switch (port.c_cflag & CBAUD) { +#else + switch (port.c_ospeed) { +#endif + case B110: + lpdcb->BaudRate = 110; + break; + case B300: + lpdcb->BaudRate = 300; + break; + case B600: + lpdcb->BaudRate = 600; + break; + case B1200: + lpdcb->BaudRate = 1200; + break; + case B2400: + lpdcb->BaudRate = 2400; + break; + case B4800: + lpdcb->BaudRate = 4800; + break; + case B9600: + lpdcb->BaudRate = 9600; + break; + case B19200: + lpdcb->BaudRate = 19200; + break; + case B38400: + lpdcb->BaudRate = 38400; + break; + } + + switch (port.c_cflag & CSIZE) { + case CS5: + lpdcb->ByteSize = 5; + break; + case CS6: + lpdcb->ByteSize = 6; + break; + case CS7: + lpdcb->ByteSize = 7; + break; + case CS8: + lpdcb->ByteSize = 8; + break; + } + + switch (port.c_cflag & ~(PARENB | PARODD)) { + case 0: + lpdcb->fParity = NOPARITY; + break; + case PARENB: + lpdcb->fParity = EVENPARITY; + break; + case (PARENB | PARODD): + lpdcb->fParity = ODDPARITY; + break; + } + + if (port.c_cflag & CSTOPB) + lpdcb->StopBits = TWOSTOPBITS; + else + lpdcb->StopBits = ONESTOPBIT; + + lpdcb->RlsTimeout = 50; + lpdcb->CtsTimeout = 50; + lpdcb->DsrTimeout = 50; + lpdcb->fNull = 0; + lpdcb->fChEvt = 0; + lpdcb->fBinary = 1; + + lpdcb->fDtrDisable = 0; + if (port.c_cflag & CRTSCTS) { + lpdcb->fDtrflow = 1; + lpdcb->fRtsflow = 1; + lpdcb->fOutxCtsFlow = 1; + lpdcb->fOutxDsrFlow = 1; + } else + lpdcb->fDtrDisable = 1; + + if (port.c_iflag & IXON) + lpdcb->fInX = 1; + else + lpdcb->fInX = 0; + + if (port.c_iflag & IXOFF) + lpdcb->fOutX = 1; + else + lpdcb->fOutX = 0; +/* + lpdcb->XonChar = + lpdcb->XoffChar = + */ + lpdcb->XonLim = 10; + lpdcb->XoffLim = 10; + + commerror = 0; + return 0; +} + +int TransmitCommChar(int fd, char chTransmit) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"TransmitCommChar: fd %d, data %d \n", fd, chTransmit); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + if (write(fd, (void *) &chTransmit, 1) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int UngetCommChar(int fd, char chUnget) +{ + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"UngetCommChar: fd %d (char %d)\n", fd, chUnget); +#endif + fprintf(stderr,"NOT implemented!\n"); + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + commerror = 0; + return 0; +} + +int ReadComm(int fd, LPSTR lpvBuf, int cbRead) +{ + struct DosDeviceStruct *ptr; +#ifdef DEBUG_COMM +fprintf(stderr,"ReadComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbRead); +#endif + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + if (read(fd, (void *) lpvBuf, cbRead) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} + +int WriteComm(int fd, LPSTR lpvBuf, int cbWrite) +{ + int x; + struct DosDeviceStruct *ptr; + +#ifdef DEBUG_COMM +fprintf(stderr,"WriteComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbWrite); +#endif + + if ((ptr = GetDeviceStruct(fd)) == NULL) { + commerror = IE_BADID; + return -1; + } + + if (ptr->suspended) { + commerror = IE_HARDWARE; + return -1; + } + + for (x=0; x != cbWrite ; x++) + fprintf(stderr,"%c", *(lpvBuf + x) ); + + if (write(fd, (void *) lpvBuf, cbWrite) == -1) { + commerror = WinError(); + return -1; + } else { + commerror = 0; + return 0; + } +} diff --git a/misc/dos.c b/misc/dos.c deleted file mode 100644 index f5f80fcced5..00000000000 --- a/misc/dos.c +++ /dev/null @@ -1,76 +0,0 @@ -static char RCSId[] = "$Id$"; -static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include "prototypes.h" -#include "regfunc.h" - -static void -GetTimeDate(int time_flag) -{ - struct tm *now; - time_t ltime; - - ltime = time(NULL); - now = localtime(<ime); - if (time_flag) - { - _CX = (now->tm_hour << 8) | now->tm_min; - _DX = now->tm_sec << 8; - } - else - { - _CX = now->tm_year + 1900; - _DX = ((now->tm_mon + 1) << 8) | now->tm_mday; - _AX &= 0xff00; - _AX |= now->tm_wday; - } -#ifdef DEBUG_DOS - printf("GetTimeDate: AX = %04x, CX = %04x, DX = %04x\n", _AX, _CX, _DX); -#endif - - ReturnFromRegisterFunc(); - /* Function does not return */ -} - -/********************************************************************** - * KERNEL_DOS3Call - */ -int -KERNEL_DOS3Call() -{ - switch ((_AX >> 8) & 0xff) - { - case 0x30: - _AX = 0x0303; - ReturnFromRegisterFunc(); - /* Function does not return */ - - case 0x25: - case 0x35: - return 0; - - case 0x2a: - GetTimeDate(0); - /* Function does not return */ - - case 0x2c: - GetTimeDate(1); - /* Function does not return */ - - case 0x4c: - exit(_AX & 0xff); - - default: - fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n", - _AX, _BX, _CX, _DX); - fprintf(stderr, " SP %04x, BP %04x, SI %04x, DI %04x\n", - _SP, _BP, _SI, _DI); - fprintf(stderr, " DS %04x, ES %04x\n", - _DS, _ES); - } - - return 0; -} diff --git a/misc/dos_fs.c b/misc/dos_fs.c new file mode 100644 index 00000000000..e0722741415 --- /dev/null +++ b/misc/dos_fs.c @@ -0,0 +1,756 @@ +/* + * DOS-FS + * NOV 1993 Erik Bos (erik@(trashcan.)hacktic.nl) + * + * FindFile by Bob, hacked for dos & unixpaths by Erik. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#ifdef __linux__ +#include <sys/vfs.h> +#endif +#ifdef __NetBSD__ +#include <sys/types.h> +#include <sys/mount.h> +#endif +#include <dirent.h> +#include "windows.h" +#include "wine.h" +#include "int21.h" + +/* + #define DEBUG +*/ +#define MAX_OPEN_DIRS 16 + +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; + +struct DosDriveStruct { /* eg: */ + char *rootdir; /* /usr/windows */ + char cwd[256]; /* / */ + char label[13]; /* DRIVE-A */ + unsigned int serialnumber; /* ABCD5678 */ + int disabled; /* 0 */ +}; + +struct DosDriveStruct DosDrives[MAX_DOS_DRIVES]; + +struct dosdirent DosDirs[MAX_OPEN_DIRS]; + +void DOS_InitFS(void) +{ + int x; + char drive[2], temp[256], *ptr; + + GetPrivateProfileString("wine", "windows", "c:\\windows", + WindowsDirectory, sizeof(WindowsDirectory), WINE_INI); + + GetPrivateProfileString("wine", "system", "c:\\windows\\system", + SystemDirectory, sizeof(SystemDirectory), WINE_INI); + + GetPrivateProfileString("wine", "temp", "c:\\windows", + TempDirectory, sizeof(TempDirectory), WINE_INI); + + GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system", + WindowsPath, sizeof(WindowsPath), WINE_INI); + + ToDos(WindowsDirectory); + ToDos(SystemDirectory); + ToDos(TempDirectory); + ToDos(WindowsPath); + +#ifdef DEBUG + fprintf(stderr,"wine.ini = %s\n",WINE_INI); + fprintf(stderr,"win.ini = %s\n",WIN_INI); + fprintf(stderr,"windir = %s\n",WindowsDirectory); + fprintf(stderr,"sysdir = %s\n",SystemDirectory); + fprintf(stderr,"tempdir = %s\n",TempDirectory); + fprintf(stderr,"path = %s\n",WindowsPath); +#endif + + for (x=0; x!=MAX_DOS_DRIVES; x++) { + DosDrives[x].serialnumber = (0xEB0500L | x); + + drive[0] = 'A' + x; + drive[1] = '\0'; + GetPrivateProfileString("drives", drive, "*", temp, sizeof(temp), WINE_INI); + if (!strcmp(temp, "*") || *temp == '\0') { + DosDrives[x].rootdir = NULL; + DosDrives[x].cwd[0] = '\0'; + DosDrives[x].label[0] = '\0'; + DosDrives[x].disabled = 1; + continue; + } + + 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'; + DosDrives[x].rootdir = ptr; + strcpy(DosDrives[x].rootdir, temp); + strcpy(DosDrives[x].cwd, "/windows/"); + strcpy(DosDrives[x].label, "DRIVE-"); + strcat(DosDrives[x].label, drive); + DosDrives[x].disabled = 0; + } + + atexit(DOS_DeInitFS); + + DOS_SetDefaultDrive(2); + + for (x=0; x!=MAX_DOS_DRIVES; x++) { + if (DosDrives[x].rootdir != NULL) { +#ifdef DEBUG + fprintf(stderr, "DOSFS: %c: => %-40s %s %s %X %d\n", + 'A'+x, + DosDrives[x].rootdir, + DosDrives[x].cwd, + DosDrives[x].label, + DosDrives[x].serialnumber, + DosDrives[x].disabled + ); +#endif + } + } + + for (x=0; x!=MAX_OPEN_DIRS ; x++) + DosDirs[x].inuse = 0; + +} + +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; + int diskdrives = 0; + +/* borrowed from Ralph Brown's interrupt lists + + bits 15-14: number of parallel devices + bit 13: [Conv] Internal modem + bit 12: reserved + bits 11- 9: number of serial devices + bit 8: reserved + bits 7- 6: number of diskette drives minus one + bits 5- 4: Initial video mode: + 00b = EGA,VGA,PGA + 01b = 40 x 25 color + 10b = 80 x 25 color + 11b = 80 x 25 mono + bit 3: reserved + bit 2: [PS] =1 if pointing device + [non-PS] reserved + bit 1: =1 if math co-processor + bit 0: =1 if diskette available for boot +*/ + + if (DosDrives[0].rootdir != NULL) + diskdrives++; + if (DosDrives[1].rootdir != NULL) + diskdrives++; + if (diskdrives) + diskdrives--; + + equipment = diskdrives << 6; + + return (equipment); +} + +int DOS_ValidDrive(int drive) +{ +/* +#ifdef DEBUG + fprintf(stderr,"ValidDrive %c (%d)\n",'A'+drive,drive); +#endif +*/ + if (drive >= MAX_DOS_DRIVES) + return 0; + if (DosDrives[drive].rootdir == NULL) + return 0; + if (DosDrives[drive].disabled) + return 0; + + return 1; +} + +int DOS_GetDefaultDrive(void) +{ +#ifdef DEBUG + fprintf(stderr,"GetDefaultDrive (%c)\n",'A'+CurrentDrive); +#endif + + return( CurrentDrive); +} + +int DOS_SetDefaultDrive(int drive) +{ +#ifdef DEBUG + fprintf(stderr,"SetDefaultDrive to %c:\n",'A'+drive); +#endif + + if (!DOS_ValidDrive(drive)) + return 1; + + CurrentDrive = drive; +} + +void ToUnix(char *s) +{ + while (*s) { + if (*s == '/') + break; + if (*s == '\\') + *s = '/'; + if (isupper(*s)) + *s = tolower(*s); + s++; + } +} + +void ToDos(char *s) +{ + while (*s) { + if (*s == '/') + *s = '\\'; + if (islower(*s)) + *s = toupper(*s); + s++; + } +} + +int DOS_DisableDrive(int drive) +{ + if (drive >= MAX_DOS_DRIVES) + return 0; + if (DosDrives[drive].rootdir == NULL) + return 0; + + DosDrives[drive].disabled = 1; + return 1; +} + +int DOS_EnableDrive(int drive) +{ + if (drive >= MAX_DOS_DRIVES) + return 0; + if (DosDrives[drive].rootdir == NULL) + return 0; + + DosDrives[drive].disabled = 0; + return 1; +} + +void GetUnixDirName(char *rootdir, char *name) +{ + int filename; + char *nameptr, *cwdptr; + + cwdptr = rootdir + strlen(rootdir); + nameptr = name; +/* +#ifdef DEBUG + fprintf(stderr,"GetUnixDirName: %s <=> %s => ",rootdir, name); +#endif +*/ + while (*nameptr) { + if (*nameptr == '.' & !filename) { + nameptr++; + if (*nameptr == '\0') { + cwdptr--; + break; + } + if (*nameptr == '.') { + cwdptr--; + while (cwdptr != rootdir) { + cwdptr--; + if (*cwdptr == '/') { + *(cwdptr+1) = '\0'; + goto next; + } + + } + goto next; + } + if (*nameptr == '\\' || *nameptr == '/') { + next: nameptr++; + filename = 0; + continue; + } + } + if (*nameptr == '\\' || *nameptr == '/') { + filename = 0; + if (nameptr == name) + cwdptr = rootdir; + *cwdptr++='/'; + nameptr++; + continue; + } + filename = 1; + *cwdptr++ = *nameptr++; + } + *cwdptr = '\0'; + + ToUnix(rootdir); +/* +#ifdef DEBUG + fprintf(stderr,"%s\n", rootdir); +#endif +*/ +} + +char *GetDirectUnixFileName(char *dosfilename) +{ + /* a:\windows\system.ini => /dos/windows/system.ini */ + + int drive; + char x, temp[256]; + + if (dosfilename[1] == ':') + { + drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A'; + + if (!DOS_ValidDrive(drive)) + return NULL; + else + dosfilename+=2; + } else + drive = CurrentDrive; + + 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); +#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) +{ + /* should return 'windows\system' */ + + char temp[256]; + + if (!DOS_ValidDrive(drive)) + return 0; + + strcpy(temp, DosDrives[drive].cwd); + ToDos(temp); + + if (temp[strlen(temp)-1] == '\\') + temp[strlen(temp)] = '\0'; + +#ifdef DEBUG + fprintf(stderr,"DOS_GetCWD: %c:\%s",'A'+drive, temp+1); +#endif + return (temp+1); +} + +int DOS_ChangeDir(int drive, char *dirname) +{ + if (!DOS_ValidDrive(drive)) + return 0; + + GetUnixDirName(DosDrives[drive].cwd, dirname); + strcat(DosDrives[drive].cwd,"/"); +#ifdef DEBUG + fprintf(stderr,"DOS_SetCWD: %c:\%s",'A'+drive, DosDrives[drive].cwd); +#endif + return 1; +} + +int DOS_MakeDir(int drive, char *dirname) +{ + char temp[256]; + + if (!DOS_ValidDrive(drive)) + return 0; + + strcpy(temp, DosDrives[drive].cwd); + GetUnixDirName(temp, dirname); + strcat(DosDrives[drive].cwd,"/"); + + ToUnix(temp); + mkdir(temp,0); + +#ifdef DEBUG + fprintf(stderr,"DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp); +#endif +} + +/* +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)) + return 0; + + *serialnumber = DosDrives[drive].serialnumber; + return 1; +} + +int DOS_SetSerialNumber(int drive, unsigned long serialnumber) +{ + if (!DOS_ValidDrive(drive)) + return 0; + + DosDrives[drive].serialnumber = serialnumber; + return 1; +} + +int DOS_GetFreeSpace(int drive, long *size, long *available) +{ + struct statfs info; + + if (!DOS_ValidDrive(drive)) + return 0; + + if (statfs(DosDrives[drive].rootdir, &info) < 0) { + fprintf(stderr,"dosfs: cannot do statfs(%s)\n",DosDrives[drive].rootdir); + return 0; + } + + *size = info.f_bsize * info.f_blocks / 1024; + *available = info.f_bavail * info.f_bsize / 1024; + + return 1; +} + +char *FindFile(char *buffer, int buflen, char *rootname, char **extensions, + char *path) +{ + char *workingpath; + char *dirname; + DIR *d; + struct dirent *f; + char **e; + int rootnamelen; + int found = 0; + + + if (strchr(rootname, '\\') != NULL) + { + strncpy(buffer, GetDirectUnixFileName(rootname), buflen); + ToUnix(buffer); + +#ifdef DEBUG +fprintf(stderr,"FindFile: %s -> %s\n",rootname,buffer); +#endif + + return buffer; + } + + if (strchr(rootname, '/') != NULL) + { + strncpy(buffer, rootname, buflen); + +#ifdef DEBUG +fprintf(stderr,"FindFile: %s -> %s\n",rootname,buffer); +#endif + + return buffer; + } + +#ifdef DEBUG +fprintf(stderr,"FindFile: looking for %s\n",rootname); +#endif + + ToUnix(rootname); + + rootnamelen = strlen(rootname); + workingpath = malloc(strlen(path) + 1); + if (workingpath == NULL) + return NULL; + strcpy(workingpath, path); + + for(dirname = strtok(workingpath, ";"); + dirname != NULL; + dirname = strtok(NULL, ";")) + { + if (strchr(dirname, '\\')!=NULL) + d = opendir( GetDirectUnixFileName(dirname) ); + else + d = opendir( dirname ); + +#ifdef DEBUG + fprintf(stderr,"in %s\n",dirname); +#endif + + if (d != NULL) + { + while ((f = readdir(d)) != NULL) + { + if (strncasecmp(rootname, f->d_name, rootnamelen) == 0) + { + if (extensions == NULL || + strcasecmp(rootname, f->d_name) == 0) + { + 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 + strncpy(buffer, dirname, buflen); + + if (buffer[strlen(buffer)-1]!='/') + strncat(buffer, "/", buflen - strlen(buffer)); + + strncat(buffer, f->d_name, buflen - strlen(buffer)); + closedir(d); + + ToUnix(buffer); + + return buffer; + } + } + } + closedir(d); + } + } + return NULL; +} + +/********************************************************************** + * WineIniFileName + */ +char *WineIniFileName(void) +{ + static char *IniName = NULL; + char inipath[256]; + + if (IniName) + return IniName; + + getcwd(inipath, 256); + strcat(inipath, ";"); + strcat(inipath, getenv("HOME")); + strcat(inipath, ";"); + strcat(inipath, getenv("WINEPATH")); + + 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; +} + +char *WinIniFileName() +{ + char name[256]; + + strcpy(name,GetDirectUnixFileName(WindowsDirectory)); + strcat(name,"win.ini"); + + ToUnix(name); + + return name; +} + +struct dosdirent *DOS_opendir(char *dosdirname) +{ + int x,y; + char *unixdirname; + char temp[256]; + + for (x=0; x != MAX_OPEN_DIRS && DosDirs[x].inuse; x++) + ; + + if (x == MAX_OPEN_DIRS) + return NULL; + + if ((unixdirname = GetDirectUnixFileName(dosdirname)) == NULL) + return NULL; + + strcpy(temp,unixdirname); + + + y = strlen(temp); + + while (y--) + { + if (temp[y] == '/') + { + temp[y] = '\0'; + break; + } + } + + fprintf(stderr,"%s -> %s\n",unixdirname,temp); + + DosDirs[x].inuse = 1; + strcpy(DosDirs[x].unixpath, temp); + + if ((DosDirs[x].ds = opendir(temp)) == NULL) + return NULL; + + return &DosDirs[x]; +} + + +struct dosdirent *DOS_readdir(struct dosdirent *de) +{ + char temp[256]; + struct dirent *d; + struct stat st; + + if (!de->inuse) + return NULL; + + if ((d = readdir(de->ds)) == NULL) + { + closedir(de->ds); + de->inuse = 0; + return de; + } + + strcpy(de->filename, d->d_name); + if (d->d_reclen > 12) + de->filename[12] = '\0'; + ToDos (de->filename); + + de->attribute = 0x0; + + strcpy(temp,de->unixpath); + strcat(temp,"/"); + strcat(temp,de->filename); + ToUnix(temp); + stat (temp, &st); + if S_ISDIR(st.st_mode) + de->attribute |= 0x08; + + return de; +} + +void DOS_closedir(struct dosdirent *de) +{ + if (de->inuse) + { + closedir(de->ds); + de->inuse = 0; + } +} diff --git a/misc/file.c b/misc/file.c index 559fac09cd3..adc43683313 100644 --- a/misc/file.c +++ b/misc/file.c @@ -3,98 +3,29 @@ * * File I/O routines for the Linux Wine Project. * - * There are two main parts to this module - first there are the - * actual emulation functions, and secondly a routine for translating - * DOS filenames into UNIX style filenames. - * - * For each DOS drive letter, we need to store the location in the unix - * file system to map that drive to, and the current directory for that - * drive. + * WARNING : Many options of OpenFile are not yet implemeted. * - * Finally we need to store the current drive letter in this module. + * NOV 93 Erik Bos (erik@(trashcan.)hacktic.nl + * - removed ParseDosFileName, and DosDrive structures. + * - structures dynamically configured at runtime. + * - _lopen modified to use GetUnixFileName. * - * WARNING : Many options of OpenFile are not yet implemeted. + * DEC 93 Erik Bos (erik@(trashcan.)hacktic.nl) + * - Existing functions modified to use dosfs functions. + * - Added _llseek, _lcreate, GetDriveType, GetTempDrive, + * GetWindowsDirectory, GetSystemDirectory, GetTempFileName. * - * ************************************************************************/ +#define DEBUG_FILE + #include <windows.h> -#include <assert.h> #include <stdio.h> #include <fcntl.h> -#include <string.h> #include <limits.h> +#include "prototypes.h" -#define OPEN_MAX 256 - -/*************************************************************************** - This structure stores the infomation needed for a single DOS drive - ***************************************************************************/ -struct DosDriveStruct -{ - char RootDirectory [256]; /* Unix base for this drive letter */ - char CurrentDirectory [256]; /* Current directory for this drive */ -}; - -/*************************************************************************** - Table for DOS drives - ***************************************************************************/ -struct DosDriveStruct DosDrives[] = -{ - {"/mnt/floppy1" , ""}, - {"/mnt/floppy2" , ""}, - {"/mnt/HardDisk", "/wine"}, - {"" , "/wine/Wine"} -}; - -#define NUM_DRIVES (sizeof (DosDrives) / sizeof (struct DosDriveStruct)) - - -/************************************************************************** - Global variable to store current drive letter (0 = A, 1 = B etc) - **************************************************************************/ -int CurrentDrive = 2; - -/************************************************************************** - ParseDOSFileName - - Return a fully specified DOS filename with the disk letter separated from - the path information. - **************************************************************************/ -void ParseDOSFileName (char *UnixFileName, char *DosFileName, int *Drive) -{ - int character; - - for (character = 0; character < strlen(DosFileName); character++) - { - if (DosFileName[character] == '\\') - DosFileName[character] = '/'; - } - - - if (DosFileName[1] == ':') - { - *Drive = DosFileName[0] - 'A'; - if (*Drive > 26) - *Drive = *Drive - 'a' + 'A'; - DosFileName = DosFileName + 2; - } - else - *Drive = CurrentDrive; - - if (DosFileName[0] == '/') - { - strcpy (UnixFileName, DosDrives[*Drive].RootDirectory); - strcat (UnixFileName, DosFileName); - return; - } - - strcpy (UnixFileName, DosDrives[*Drive].RootDirectory); - strcat (UnixFileName, DosDrives[*Drive].CurrentDirectory); - strcat (UnixFileName, "/"); - strcat (UnixFileName, DosFileName); - return; -} +char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256]; /*************************************************************************** @@ -104,20 +35,26 @@ void ParseDOSFileName (char *UnixFileName, char *DosFileName, int *Drive) ***************************************************************************/ WORD KERNEL__lopen (LPSTR lpPathName, WORD iReadWrite) { - char UnixFileName[256]; - int Drive; int handle; + char *UnixFileName; - ParseDOSFileName (UnixFileName, lpPathName, &Drive); - +#ifdef DEBUG_FILE + fprintf (stderr, "_lopen: open %s\n", lpPathName); +#endif + if ((UnixFileName = GetUnixFileName(lpPathName)) == NULL) + return HFILE_ERROR; handle = open (UnixFileName, iReadWrite); #ifdef DEBUG_FILE - fprintf (stderr, "_lopen: %s (Handle = %d)\n", UnixFileName, handle); + fprintf (stderr, "_lopen: open: %s (handle %d)\n", UnixFileName, handle); #endif - return handle; + + if (handle == -1) + return HFILE_ERROR; + else + return handle; } /*************************************************************************** @@ -126,26 +63,37 @@ WORD KERNEL__lopen (LPSTR lpPathName, WORD iReadWrite) WORD KERNEL__lread (WORD hFile, LPSTR lpBuffer, WORD wBytes) { int result; - - result = read (hFile, lpBuffer, wBytes); + #ifdef DEBUG_FILE - fprintf(stderr, "_lread: hFile = %d, lpBuffer = %s, wBytes = %d\n", - hFile, lpBuffer, wBytes); + fprintf(stderr, "_lread: handle %d, buffer = %ld, length = %d\n", + hFile, lpBuffer, wBytes); #endif - return result; -} + + result = read (hFile, lpBuffer, wBytes); + if (result == -1) + return HFILE_ERROR; + else + return result; +} /**************************************************************************** _lwrite ****************************************************************************/ WORD KERNEL__lwrite (WORD hFile, LPSTR lpBuffer, WORD wBytes) { + int result; + #ifdef DEBUG_FILE - fprintf(stderr, "_lwrite: hFile = %d, lpBuffer = %s, wBytes = %d\n", - hFile, lpBuffer, wBytes); + fprintf(stderr, "_lwrite: handle %d, buffer = %ld, length = %d\n", + hFile, lpBuffer, wBytes); #endif - return write (hFile, lpBuffer, wBytes); + result = write (hFile, lpBuffer, wBytes); + + if (result == -1) + return HFILE_ERROR; + else + return result; } /*************************************************************************** @@ -153,6 +101,10 @@ WORD KERNEL__lwrite (WORD hFile, LPSTR lpBuffer, WORD wBytes) ***************************************************************************/ WORD KERNEL__lclose (WORD hFile) { +#ifdef DEBUG_FILE + fprintf(stderr, "_lclose: handle %d\n", hFile); +#endif + close (hFile); } @@ -166,7 +118,9 @@ WORD KERNEL_OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle) { int base,flags; +#ifdef DEBUG_FILE fprintf(stderr,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle); +#endif base=wStyle&0xF; flags=wStyle&0xFFF0; @@ -204,7 +158,148 @@ WORD SetHandleCount (WORD wNumber) return((wNumber<OPEN_MAX) ? wNumber : OPEN_MAX); } +/*************************************************************************** + _llseek + ***************************************************************************/ +LONG KERNEL__llseek (WORD hFile, LONG lOffset, int nOrigin) +{ + int origin; + +#ifdef DEBUG_FILE + fprintf(stderr, "_llseek: handle %d, offset %ld, origin %d\n", hFile, lOffset, nOrigin); +#endif + switch (nOrigin) { + case 1: origin = SEEK_CUR; + break; + case 2: origin = SEEK_END; + break; + default: origin = SEEK_SET; + break; + } + return ( lseek(hFile, lOffset, origin) ); +} + +/*************************************************************************** + _lcreate + ***************************************************************************/ +LONG KERNEL__lcreate (LPSTR lpszFilename, int fnAttribute) +{ + int handle; + char *UnixFileName; + +#ifdef DEBUG_FILE + fprintf(stderr, "_lcreate: filename %s, attributes %d\n",lpszFilename, + fnAttribute); +#endif + + if ((UnixFileName = GetUnixFileName(lpszFilename)) == NULL) + return HFILE_ERROR; + + handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY ); + + if (handle == -1) + return HFILE_ERROR; + else + return handle; +} + +/*************************************************************************** + GetDriveType + ***************************************************************************/ +UINT GetDriveType(int drive) +{ + +#ifdef DEBUG_FILE + fprintf(stderr,"GetDriveType %c:\n",'A'+drive); +#endif + if (!DOS_ValidDrive(drive)) + return 0; + if (drive == 0 || drive == 1) + return DRIVE_REMOVABLE; + + return DRIVE_REMOTE; +} + +/*************************************************************************** + GetTempDrive + ***************************************************************************/ +BYTE GetTempDrive(BYTE chDriveLetter) +{ +#ifdef DEBUG_FILE + fprintf(stderr,"GetTempDrive (%d)\n",chDriveLetter); +#endif + return('C'); +} + +/*************************************************************************** + GetWindowsDirectory + ***************************************************************************/ +UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath) +{ + if (cbSysPath < strlen(WindowsDirectory)) + *lpszSysPath = 0; + else + strcpy(lpszSysPath, WindowsDirectory); + +#ifdef DEBUG_FILE + fprintf(stderr,"GetWindowsDirectory (%s)\n",lpszSysPath); +#endif + + return(strlen(lpszSysPath)); +} +/*************************************************************************** + GetSystemDirectory + ***************************************************************************/ +UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath) +{ + if (cbSysPath < strlen(SystemDirectory)) + *lpszSysPath = 0; + else + strcpy(lpszSysPath, SystemDirectory); + +#ifdef DEBUG_FILE + fprintf(stderr,"GetSystemDirectory (%s)\n",lpszSysPath); +#endif + + return(strlen(lpszSysPath)); +} +/*************************************************************************** + GetTempFileName + ***************************************************************************/ +int GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName) +{ + int unique; + char tempname[256]; + + if (uUnique == 0) + unique = time(NULL)%99999L; + else + unique = uUnique%99999L; + + strcpy(tempname,lpszPrefixString); + tempname[3]='\0'; + + sprintf(lpszTempFileName,"%s\%s%d.tmp",WindowsDirectory, tempname, + unique); + + ToDos(lpszTempFileName); + +#ifdef DEBUG_FILE + fprintf(stderr,"GetTempFilename: %c %s %d => %s\n",bDriveLetter, + lpszPrefixString,uUnique,lpszTempFileName); +#endif + + return unique; +} + +/*************************************************************************** + SetErrorMode + ***************************************************************************/ +WORD SetErrorMode(WORD x) +{ + fprintf(stderr,"wine: SetErrorMode %4x (ignored)\n",x); +} diff --git a/loader/int1a.c b/misc/int1a.c similarity index 93% rename from loader/int1a.c rename to misc/int1a.c index 2441d77f526..addfdbcbb92 100644 --- a/loader/int1a.c +++ b/misc/int1a.c @@ -51,7 +51,7 @@ int do_int1A(struct sigcontext_struct * context){ break; default: - fprintf(stderr,"Unable to handle int 0x1A AX %x\n", context->sc_eax); + fprintf(stderr,"Unable to handle int 0x1A AX %04x\n", context->sc_eax & 0xffffL); return 1; }; return 1; diff --git a/loader/int21.c b/misc/int21.c similarity index 52% rename from loader/int21.c rename to misc/int21.c index fdf506aa486..4d1ae704d76 100644 --- a/loader/int21.c +++ b/misc/int21.c @@ -5,34 +5,23 @@ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> -#ifdef linux -#include <sys/vfs.h> -#endif -#ifdef __NetBSD__ -#include <sys/mount.h> -#endif #include <time.h> #include <unistd.h> #include <utime.h> +#include "prototypes.h" +#include "regfunc.h" #include "windows.h" #include "wine.h" #include "int21.h" -#include "files.h" - -#define MAX_DRIVES 26 - -static char Copyright[] = "int21.c, copyright Erik Bos, 1993"; - -extern struct DosDriveStruct DosDrives[]; -extern int CurrentDrive; -extern void ParseDOSFileName(); -int ValidDrive(int); +static char Copyright[] = "copyright Erik Bos, 1993"; WORD ExtendedError, CodePage = 437; BYTE ErrorClass, Action, ErrorLocus; +extern char *TempDirectory; + void Error(int e, int class, int el) { ExtendedError = e; @@ -44,115 +33,99 @@ void Error(int e, int class, int el) void GetFreeDiskSpace(struct sigcontext_struct *context) { int drive; - struct statfs info; - long size,avail; + long size,available; - if (!(DX & 0xff)) - drive = CurrentDrive; + if (!(EDX & 0xffL)) + drive = DOS_GetDefaultDrive(); else - drive = (DX & 0xff) - 1; + drive = (EDX & 0xffL) - 1; - if (!ValidDrive(drive)) { + if (!DOS_ValidDrive(drive)) { Error(InvalidDrive, EC_MediaError , EL_Disk); - AX = 0xffff; + EAX |= 0xffffL; return; } - { - if (statfs(DosDrives[drive].RootDirectory, &info) < 0) { - fprintf(stderr,"cannot do statfs(%s)\n",DosDrives[drive].RootDirectory); - Error(GeneralFailure, EC_MediaError , EL_Disk); - AX = 0xffff; - return; - } + if (!DOS_GetFreeSpace(drive, &size, &available)) { + Error(GeneralFailure, EC_MediaError , EL_Disk); + EAX |= 0xffffL; + return; + } - size = info.f_bsize * info.f_blocks / 1024; - avail = info.f_bavail * info.f_bsize / 1024; - - #ifdef DOSDEBUG - fprintf(stderr,"statfs: size: %8d avail: %8d\n",size,avail); - #endif + EAX = (EAX & 0xffff0000L) | SectorsPerCluster; + ECX = (ECX & 0xffff0000L) | SectorSize; - AX = SectorsPerCluster; - CX = SectorSize; - - BX = (avail / (CX * AX)); - DX = (size / (CX * AX)); - Error (0,0,0); - } + EBX = (EBX & 0xffff0000L) | (available / (CX * AX)); + EDX = (EDX & 0xffff0000L) | (size / (CX * AX)); + Error (0,0,0); } void SetDefaultDrive(struct sigcontext_struct *context) { - if ((DX & 0xff) < MAX_DRIVES) { - CurrentDrive = DX & 0xff; - AX &= 0xff00; - AX |= MAX_DRIVES; /* # of valid drive letters */ - Error (0,0,0); - } else + int drive; + + drive = EDX & 0xffL; + + if (!DOS_ValidDrive(drive)) { Error (InvalidDrive, EC_MediaError, EL_Disk); + return; + } else { + DOS_SetDefaultDrive(drive); + EAX = (EAX &0xffffff00L) | MAX_DOS_DRIVES; + Error (0,0,0); + } } void GetDefaultDrive(struct sigcontext_struct *context) { - AX &= 0xff00; - AX |= CurrentDrive; + EAX = (EAX & 0xffffff00L) | DOS_GetDefaultDrive(); Error (0,0,0); } void GetDriveAllocInfo(struct sigcontext_struct *context) { int drive; - long size; + long size, available; BYTE mediaID; - struct statfs info; - drive = DX & 0xff; + drive = EDX & 0xffL; - if (!ValidDrive(drive)) { - AX = SectorsPerCluster; - CX = SectorSize; - DX = 0; + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffff0000L) | SectorsPerCluster; + ECX = (ECX & 0xffff0000L) | SectorSize; + EDX = (EDX & 0xffff0000L); Error (InvalidDrive, EC_MediaError, EL_Disk); return; } - { - if (statfs(DosDrives[drive].RootDirectory, &info) < 0) { - fprintf(stderr,"cannot do statfs(%s)\n",DosDrives[drive].RootDirectory); - Error(GeneralFailure, EC_MediaError , EL_Disk); - AX = 0xffff; - return; - } - - size = info.f_bsize * info.f_blocks / 1024; + if (!DOS_GetFreeSpace(drive, &size, &available)) { + Error(GeneralFailure, EC_MediaError , EL_Disk); + EAX |= 0xffffL; + return; + } - #ifdef DOSDEBUG - fprintf(stderr,"statfs: size: %8d\n",size); - #endif + EAX = (EAX & 0xffff0000L) | SectorsPerCluster; + ECX = (ECX & 0xffff0000L) | SectorSize; + EDX = (EDX & 0xffff0000L) | (size / (CX * AX)); - AX = SectorsPerCluster; - CX = SectorSize; - DX = (size / (CX * AX)); + mediaID = 0xf0; - mediaID = 0xf0; - - DS = segment(mediaID); - BX = offset(mediaID); - Error (0,0,0); - } + DS = segment(mediaID); + EBX = offset(mediaID); + Error (0,0,0); } void GetDefDriveAllocInfo(struct sigcontext_struct *context) { - DX = CurrentDrive; + EDX = DOS_GetDefaultDrive(); GetDriveAllocInfo(context); } void GetDrivePB(struct sigcontext_struct *context) { Error (InvalidDrive, EC_MediaError, EL_Disk); - AX = 0xff; /* I'm sorry but I only got networked drives :-) */ + EAX = (EAX & 0xffff0000L) | 0xffL; + /* I'm sorry but I only got networked drives :-) */ } void ReadFile(struct sigcontext_struct *context) @@ -162,26 +135,26 @@ void ReadFile(struct sigcontext_struct *context) /* can't read from stdout / stderr */ - if (((BX & 0xffff) == 1) ||((BX & 0xffff) == 2)) { + if ((BX == 1) || (BX == 2)) { Error (InvalidHandle, EL_Unknown, EC_Unknown); - AX = InvalidHandle; + EAX = (EAX & 0xffff0000L) | InvalidHandle; SetCflag; return; } ptr = (char *) pointer (DS,DX); - if ((BX & 0xffff) == 0) { + if (BX == 0) { *ptr = EOF; Error (0,0,0); - AX = 1; + EAX = (EAX & 0xffff0000L) | 1; ResetCflag; return; } else { size = read(BX, ptr, CX); if (size == 0) { Error (ReadFault, EC_Unknown, EL_Unknown); - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; return; } @@ -197,12 +170,12 @@ void ReadFile(struct sigcontext_struct *context) Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; return; } Error (0,0,0); - AX = size; + EAX = (EAX & 0xffff0000L) | size; ResetCflag; } } @@ -214,27 +187,27 @@ void WriteFile(struct sigcontext_struct *context) ptr = (char *) pointer (DS,DX); - if ((BX & 0xffff) == 0) { + if (BX == 0) { Error (InvalidHandle, EC_Unknown, EL_Unknown); - AX = InvalidHandle; + EAX = InvalidHandle; SetCflag; return; } - if ((BX & 0xffff) < 3) { + if (BX < 3) { for (x = 0;x != CX;x++) { fprintf(stderr, "%c", *ptr++); } fflush(stderr); Error (0,0,0); - AX = CX; + EAX = (EAX & 0xffffff00L) | CX; ResetCflag; } else { size = write(BX, ptr , CX); if (size == 0) { Error (WriteFault, EC_Unknown, EL_Unknown); - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; return; } @@ -253,105 +226,82 @@ void WriteFile(struct sigcontext_struct *context) Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; return; } Error (0,0,0); - AX = size; + EAX = (EAX & 0xffff0000L) | size; ResetCflag; } } void UnlinkFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive, status; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - status = unlink((char *) pointer(DS,DX)); - if (status == -1) { - switch (errno) { - case EACCES: - case EPERM: - case EROFS: - Error (WriteProtected, EC_AccessDenied, EL_Unknown); - break; - case EBUSY: - Error (LockViolation, EC_AccessDenied, EL_Unknown); - break; - case EAGAIN: - Error (ShareViolation, EC_Temporary, EL_Unknown); - break; - case ENOENT: - Error (FileNotFound, EC_NotFound, EL_Unknown); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - ResetCflag; - } + if (unlink( GetUnixFileName((char *) pointer(DS,DX)) ) == -1) { + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + Error (WriteProtected, EC_AccessDenied, EL_Unknown); + break; + case EBUSY: + Error (LockViolation, EC_AccessDenied, EL_Unknown); + break; + case EAGAIN: + Error (ShareViolation, EC_Temporary, EL_Unknown); + break; + case ENOENT: + Error (FileNotFound, EC_NotFound, EL_Unknown); + break; + default: + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); + break; + } + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; + return; + } + Error (0,0,0); + ResetCflag; } void SeekFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive, handle, status, fileoffset; - - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); + int handle, status, fileoffset; - { - switch (AX & 0xff) { - case 1: fileoffset = SEEK_CUR; + switch (EAX & 0xffL) { + case 1: fileoffset = SEEK_CUR; + break; + case 2: fileoffset = SEEK_END; + break; + default: + case 0: fileoffset = SEEK_SET; + break; + } + status = lseek(BX, (CX * 0x100) + DX, fileoffset); + if (status == -1) { + switch (errno) { + case EBADF: + Error (InvalidHandle, EC_AppError, EL_Unknown); break; - case 2: fileoffset = SEEK_END; + case EINVAL: + Error (DataInvalid, EC_AppError, EL_Unknown); break; default: - case 0: fileoffset = SEEK_SET; + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - status = lseek(BX, (CX * 0x100) + DX, fileoffset); - if (status == -1) { - switch (errno) { - case EBADF: - Error (InvalidHandle, EC_AppError, EL_Unknown); - break; - case EINVAL: - Error (DataInvalid, EC_AppError, EL_Unknown); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - ResetCflag; - } + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; + return; + } + Error (0,0,0); + ResetCflag; } void GetFileAttributes(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive,handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - CX = 0x0; - ResetCflag; - } + EAX &= 0xfffff00L; + ResetCflag; } void SetFileAttributes(struct sigcontext_struct *context) @@ -361,13 +311,14 @@ void SetFileAttributes(struct sigcontext_struct *context) void DosIOCTL(struct sigcontext_struct *context) { - AX = UnknownUnit; + fprintf(stderr,"int21: IOCTL\n"); + EAX = (EAX & 0xfffff00L) | UnknownUnit; SetCflag; } void DupeFileHandle(struct sigcontext_struct *context) { - AX = dup(BX); + EAX = (EAX & 0xffff0000L) | dup(BX); ResetCflag; } @@ -379,10 +330,9 @@ void GetSystemDate(struct sigcontext_struct *context) ltime = time(NULL); now = localtime(<ime); - CX = now->tm_year + 1900; - DX = ((now->tm_mon + 1) << 8) | now->tm_mday; - AX &= 0xff00; - AX |= now->tm_wday; + 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) @@ -393,115 +343,102 @@ void GetSystemTime(struct sigcontext_struct *context) ltime = time(NULL); now = localtime(<ime); - CX = (now->tm_hour << 8) | now->tm_min; - DX = now->tm_sec << 8; + ECX = (ECX & 0xffffff00L) | (now->tm_hour << 8) | now->tm_min; + EDX = (EDX & 0xffffff00L) | now->tm_sec << 8; } void GetExtendedErrorInfo(struct sigcontext_struct *context) { - AX = ExtendedError; - BX = (0x100 * ErrorClass) | Action; - CX &= 0x00ff; - CX |= (0x100 * ErrorLocus); + EAX = (EAX & 0xffffff00L) | ExtendedError; + EBX = (EBX & 0xffff0000L) | (0x100 * ErrorClass) | Action; + ECX = (ECX & 0xffff00ffL) | (0x100 * ErrorLocus); } void GetInDosFlag(struct sigcontext_struct *context) { const BYTE InDosFlag = 0; - ES = segment(InDosFlag); - BX = offset(InDosFlag); + ES = (ES & 0xffff0000L) | segment(InDosFlag); + EBX = (EBX & 0xffff0000L) | offset(InDosFlag); } void CreateFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive,handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); + int handle; - { - handle = open(UnixFileName, O_CREAT | O_TRUNC); - - if (handle == -1) { - switch (errno) { - case EACCES: - case EPERM: - case EROFS: - Error (WriteProtected, EC_AccessDenied, EL_Unknown); - break; - case EISDIR: - Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); - break; - case ENFILE: - case EMFILE: - Error (NoMoreFiles, EC_MediaError, EL_Unknown); - case EEXIST: - Error (FileExists, EC_Exists, EL_Disk); - break; - case ENOSPC: - Error (DiskFull, EC_MediaError, EL_Disk); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - BX = handle; - AX = NoError; - ResetCflag; - } + if ((handle = open(GetUnixFileName((char *) pointer(DS,DX)), O_CREAT | O_TRUNC)) == -1) { + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + Error (WriteProtected, EC_AccessDenied, EL_Unknown); + break; + case EISDIR: + Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); + break; + case ENFILE: + case EMFILE: + Error (NoMoreFiles, EC_MediaError, EL_Unknown); + case EEXIST: + Error (FileExists, EC_Exists, EL_Disk); + break; + case ENOSPC: + Error (DiskFull, EC_MediaError, EL_Disk); + break; + default: + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); + break; + } + EAX = (EAX & 0xffffff00L) | ExtendedError; + SetCflag; + return; + } + Error (0,0,0); + EBX = (EBX & 0xffff0000L) | handle; + EAX = (EAX & 0xffffff00L) | NoError; + ResetCflag; } void OpenExistingFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive, handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - handle = open(UnixFileName, O_RDWR); + int handle; - if (handle == -1) { - switch (errno) { - case EACCES: - case EPERM: - case EROFS: - Error (WriteProtected, EC_AccessDenied, EL_Unknown); - break; - case EISDIR: - Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); - break; - case ENFILE: - case EMFILE: - Error (NoMoreFiles, EC_MediaError, EL_Unknown); - case EEXIST: - Error (FileExists, EC_Exists, EL_Disk); - break; - case ENOSPC: - Error (DiskFull, EC_MediaError, EL_Disk); - break; - case ENOENT: - Error (FileNotFound, EC_MediaError, EL_Disk); - break; - default: - Error (GeneralFailure, EC_SystemFailure, EL_Unknown); - break; - } - AX = ExtendedError; - SetCflag; - return; - } - Error (0,0,0); - BX = handle; - AX = NoError; - ResetCflag; - } + fprintf(stderr,"OpenExistingFile (%s)\n",(char *) pointer(DS,DX)); + + if ((handle = open(GetUnixFileName((char*) pointer(DS,DX)), O_RDWR)) == -1) { + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + Error (WriteProtected, EC_AccessDenied, EL_Unknown); + break; + case EISDIR: + Error (CanNotMakeDir, EC_AccessDenied, EL_Unknown); + break; + case ENFILE: + case EMFILE: + Error (NoMoreFiles, EC_MediaError, EL_Unknown); + case EEXIST: + Error (FileExists, EC_Exists, EL_Disk); + break; + case ENOSPC: + Error (DiskFull, EC_MediaError, EL_Disk); + break; + case ENOENT: + Error (FileNotFound, EC_MediaError, EL_Disk); + break; + default: + Error (GeneralFailure, EC_SystemFailure, EL_Unknown); + break; + } + EAX = (EAX & 0xffffff00L) | ExtendedError; + SetCflag; + return; + } + Error (0,0,0); + EBX = (EBX & 0xffff0000L) | handle; + EAX = (EAX & 0xffffff00L) | NoError; + ResetCflag; } void CloseFile(struct sigcontext_struct *context) @@ -515,105 +452,109 @@ void CloseFile(struct sigcontext_struct *context) Error (GeneralFailure, EC_SystemFailure, EL_Unknown); break; } - AX = ExtendedError; + EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag; return; } Error (0,0,0); - AX = NoError; + EAX = (EAX & 0xffffff00L) | NoError; ResetCflag; } void RenameFile(struct sigcontext_struct *context) { - rename((char *) pointer(DS,DX), (char *) pointer(ES,DI)); + char *newname, *oldname; + + fprintf(stderr,"int21: renaming %s to %s\n",(char *) pointer(DS,DX), pointer(ES,DI) ); + + oldname = GetUnixFileName( (char *) pointer(DS,DX) ); + newname = GetUnixFileName( (char *) pointer(ES,DI) ); + + rename( oldname, newname); ResetCflag; } void GetTrueFileName(struct sigcontext_struct *context) -{ +{ + fprintf(stderr,"int21: GetTrueFileName of %s\n",(char *) pointer(DS,SI)); + strncpy((char *) pointer(ES,DI), (char *) pointer(DS,SI), strlen((char *) pointer(DS,SI)) & 0x7f); ResetCflag; } void MakeDir(struct sigcontext_struct *context) { - int drive; char *dirname; - char unixname[256]; - - dirname = (char *) pointer(DS,DX); - ParseDOSFileName(unixname,dirname,&drive); + fprintf(stderr,"int21: makedir %s\n",(char *) pointer(DS,DX) ); + + if ((dirname = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + return; + } - { - if (mkdir(unixname,0) == -1) { - AX = CanNotMakeDir; - SetCflag; - } - ResetCflag; + if (mkdir(dirname,0) == -1) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + return; } + ResetCflag; } void ChangeDir(struct sigcontext_struct *context) { - int drive; - char *dirname; - char unixname[256]; - - dirname = (char *) pointer(DS,DX); + fprintf(stderr,"int21: changedir %s\n",(char *) pointer(DS,DX) ); - ParseDOSFileName(unixname,dirname,&drive); - - { - strcpy(unixname,DosDrives[drive].CurrentDirectory); - ResetCflag; - } + DOS_ChangeDir(DOS_GetDefaultDrive(), (char *) pointer (DS,DX)); } void RemoveDir(struct sigcontext_struct *context) { - int drive; char *dirname; - char unixname[256]; - - dirname = (char *) pointer(DS,DX); - ParseDOSFileName(unixname,dirname,&drive); + fprintf(stderr,"int21: removedir %s\n",(char *) pointer(DS,DX) ); - { - if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) { - AX = CanNotRemoveCwd; - SetCflag; - } - - #ifdef DOSDEBUG - fprintf(stderr,"rmdir %s\n",unixname); - #endif - - if (rmdir(unixname) == -1) { - AX = CanNotMakeDir; /* HUH ?*/ - SetCflag; - } - ResetCflag; + if ((dirname = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + return; } + +/* + if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) { + EAX = (EAX & 0xffffff00L) | CanNotRemoveCwd; + SetCflag; + } +*/ + if (rmdir(dirname) == -1) { + EAX = (EAX & 0xffffff00L) | CanNotMakeDir; + SetCflag; + } + ResetCflag; } 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) { - AX = OutOfMemory; - BX = 0x0; /* out of memory */ + EAX = (EAX & 0xffffff00L) | OutOfMemory; + EBX = (EBX & 0xffffff00L); /* out of memory */ SetCflag; } - AX = segment((unsigned long) ptr); + fprintf(stderr,"int21: malloc (ptr = %d)\n", ptr ); + + EAX = (EAX & 0xffff0000L) | segment((unsigned long) ptr); ResetCflag; } void FreeMemory(struct sigcontext_struct *context) { + fprintf(stderr,"int21: freemem (ptr = %d)\n", ES * 0x10 ); + free((void *)(ES * 0x10)); ResetCflag; } @@ -621,24 +562,26 @@ void FreeMemory(struct sigcontext_struct *context) 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) { - AX = OutOfMemory; - BX = 0x0; /* out of memory */ + EAX = (EAX & 0xffffff00L) | OutOfMemory; + EBX = (EBX & 0xffffff00L); /* out of memory */ SetCflag; } - BX = segment((unsigned long) ptr); + EBX = (EBX & 0xffff0000L) | segment((unsigned long) ptr); ResetCflag; } void ExecProgram(struct sigcontext_struct *context) { - execl("wine",(char *) pointer(DS,DX)); + execl("wine", GetUnixFileName((char *) pointer(DS,DX)) ); } void GetReturnCode(struct sigcontext_struct *context) { - AX = NoError; /* normal exit */ + EAX = (EAX & 0xffffff00L) | NoError; /* normal exit */ } void FindFirst(struct sigcontext_struct *context) @@ -653,97 +596,83 @@ void FindNext(struct sigcontext_struct *context) void GetSysVars(struct sigcontext_struct *context) { + /* return a null pointer, to encourage anyone who tries to + use the pointer */ + ES = 0x0; - BX = 0x0; + EBX = (EBX & 0xffff0000L); } void GetFileDateTime(struct sigcontext_struct *context) { - int drive; - char *dirname; - char unixname[256]; + char *filename; struct stat filestat; struct tm *now; - dirname = (char *) pointer(DS,DX); - ParseDOSFileName(unixname, dirname, &drive); - - { - stat(unixname, &filestat); + if ((filename = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) { + EAX = (EAX & 0xffffff00L) | FileNotFound; + SetCflag; + return; + } + stat(filename, &filestat); - now = localtime (&filestat.st_mtime); + now = localtime (&filestat.st_mtime); - CX = (now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2; - DX = (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; - } + ResetCflag; } void SetFileDateTime(struct sigcontext_struct *context) { - int drive; - char *dirname; - char unixname[256]; + char *filename; struct utimbuf filetime; - dirname = (char *) pointer(DS,DX); + filename = GetUnixFileName((char *) pointer(DS,DX)); - ParseDOSFileName(unixname, dirname, &drive); + filetime.actime = 0L; + filetime.modtime = filetime.actime; - { - filetime.actime = 0L; - filetime.modtime = filetime.actime; - - utime(unixname,&filetime); - ResetCflag; - } + utime(filename, &filetime); + ResetCflag; } void CreateTempFile(struct sigcontext_struct *context) { - char UnixFileName[256],TempString[256]; - int drive,handle; - - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); + char *filename, temp[256]; + int drive, handle; - sprintf(TempString,"%s%s%d",UnixFileName,"eb",(int) getpid()); + sprintf(temp,"%s\\win%d.tmp",TempDirectory,(int) getpid()); - { - handle = open(TempString, O_CREAT | O_TRUNC | O_RDWR); + fprintf(stderr,"CreateTempFile %s\n",temp); - if (handle == -1) { - AX = WriteProtected; - SetCflag; - return; - } - - strcpy((char *) pointer(DS,DX), UnixFileName); - - AX = handle; - ResetCflag; + handle = open(GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR); + + if (handle == -1) { + EAX = (EAX & 0xffffff00L) | WriteProtected; + SetCflag; + return; } + + strcpy((char *) pointer(DS,DX), temp); + + EAX = (EAX & 0xffff0000L) | handle; + ResetCflag; } void CreateNewFile(struct sigcontext_struct *context) { - char UnixFileName[256]; - int drive,handle; + int handle; - ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive); - - { - handle = open(UnixFileName, O_CREAT | O_TRUNC | O_RDWR); - - if (handle == -1) { - AX = WriteProtected; - SetCflag; - return; - } - - AX = handle; - ResetCflag; + if ((handle = open(GetUnixFileName((char *) pointer(DS,DX)), O_CREAT | O_TRUNC | O_RDWR)) == -1) { + EAX = (EAX & 0xffffff00L) | WriteProtected; + SetCflag; + return; } + + EAX = (EAX & 0xffff0000L) | handle; + ResetCflag; } void FileLock(struct sigcontext_struct *context) @@ -756,30 +685,23 @@ void GetExtendedCountryInfo(struct sigcontext_struct *context) ResetCflag; } -int ValidDrive(int d) -{ - return 1; -} - void GetCurrentDirectory(struct sigcontext_struct *context) { int drive; - char *ptr; - if ((DX & 0xff) == 0) - drive = CurrentDrive; + if ((EDX & 0xffL) == 0) + drive = DOS_GetDefaultDrive(); else - drive = (DX & 0xff)-1; + drive = (EDX & 0xffL)-1; - if (!ValidDrive(drive)) { - AX = InvalidDrive; + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffffff00L) | InvalidDrive; SetCflag; return; } - - strcpy((char *) pointer(DS,SI), DosDrives[drive].CurrentDirectory); + + DOS_GetCurrentDir(drive, (char *) pointer(DS,SI) ); ResetCflag; - AX = 0x0100; } void GetCurrentPSP(struct sigcontext_struct *context) @@ -790,53 +712,48 @@ void GetCurrentPSP(struct sigcontext_struct *context) void GetDiskSerialNumber(struct sigcontext_struct *context) { int drive; + unsigned long serialnumber; struct diskinfo *ptr; - if ((BX & 0xff)== 0) - drive = CurrentDrive; + if ((EBX & 0xffL) == 0) + drive = DOS_GetDefaultDrive(); else - drive = (BX & 0xff)-1; + drive = (EBX & 0xffL) - 1; - if (!ValidDrive(drive)) { - AX = InvalidDrive; + if (!DOS_ValidDrive(drive)) { + EAX = (EAX & 0xffffff00L) |InvalidDrive; SetCflag; return; } - { - ptr =(struct diskinfo *) pointer(DS,SI); + DOS_GetSerialNumber(drive,&serialnumber); - ptr->infolevel = 0; - ptr->serialnumber = 0xEBEBEB00 | drive; - strcpy(ptr->label,"NO NAME "); - strcpy(ptr->fstype,"FAT16 "); + ptr = (struct diskinfo *) pointer(DS,SI); + + ptr->infolevel = 0; + ptr->serialnumber = serialnumber; + strcpy(ptr->label,"NO NAME "); + strcpy(ptr->fstype,"FAT16 "); - AX = NoError; - ResetCflag; - } + EAX = (EAX & 0xffffff00L) | NoError; + ResetCflag; } void SetDiskSerialNumber(struct sigcontext_struct *context) { - AX &= 0xff00; - AX |= 1; + EAX = (EAX & 0xffffff00L) | 1L; ResetCflag; } -void CommitFile(struct sigcontext_struct *context) -{ - -} - /************************************************************************/ int do_int21(struct sigcontext_struct * context){ int ah; - fprintf(stderr,"int21: doing AX=%4x BX=%4x CX=%4x DX=%4x\n", - AX & 0xffff,BX & 0xffff,CX & 0xffff,DX & 0xffff); + fprintf(stderr,"int21: doing AX=%04x BX=%04x CX=%04x DX=%04x\n", + EAX & 0xffffL,EBX & 0xffffL,ECX & 0xffffL,EDX & 0xffffL); - ah = (AX >> 8) & 0xff; + ah = (EAX >> 8) & 0xffL; if (ah == 0x59) { GetExtendedErrorInfo(context); @@ -901,7 +818,7 @@ int do_int21(struct sigcontext_struct * context){ case 0x54: /* GET VERIFY FLAG */ case 0x61: /* UNUSED */ case 0x6b: /* NULL FUNCTION */ - AX &= 0xff00; + EAX &= 0xff00; break; case 0x67: /* SET HANDLE COUNT */ @@ -945,36 +862,37 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x30: /* GET DOS VERSION */ - AX = DosVersion; /* Hey folks, this is DOS V3.3! */ - BX = 0x0012; /* 0x123456 is Wine's serial # */ - CX = 0x3456; + 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 (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: /* GET CURRENT EXTENDED BREAK STATE */ - if (!(AX & 0xff)) - DX &= 0xff00; + if (!(EAX & 0xffL)) + EDX &= 0xff00L; break; case 0x01: /* SET EXTENDED BREAK STATE */ break; case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE */ - DX &= 0xff00; + EDX &= 0xff00L; break; case 0x05: /* GET BOOT DRIVE */ - DX &= 0xff00; - DX |= 2; /* c: is Wine's bootdrive */ + EDX = (EDX & 0xff00L) | 2; + /* c: is Wine's bootdrive */ break; case 0x06: /* GET TRUE VERSION NUMBER */ - BX = DosVersion; - DX = 0x00; + EBX = DosVersion; + EDX = 0x00; break; default: break; @@ -989,7 +907,7 @@ int do_int21(struct sigcontext_struct * context){ /* Return a NULL segment selector - this will bomb, if anyone ever tries to use it */ ES = 0; - BX = 0; + EBX = 0; break; case 0x36: /* GET FREE DISK SPACE */ @@ -997,8 +915,8 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ - AX &= 0xff00; - AX |= 0x02; /* no country support available */ + EAX &= 0xff00; + EAX |= 0x02; /* no country support available */ SetCflag; break; @@ -1023,9 +941,6 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x3e: /* "CLOSE" - CLOSE FILE */ - case 0x68: /* "FFLUSH" - COMMIT FILE */ - case 0x6a: /* COMMIT FILE */ - CloseFile(context); break; @@ -1046,7 +961,7 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x43: /* FILE ATTRIBUTES */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: GetFileAttributes(context); break; @@ -1067,8 +982,8 @@ int do_int21(struct sigcontext_struct * context){ case 0x47: /* "CWD" - GET CURRENT DIRECTORY */ GetCurrentDirectory(context); - AX = 0x0100; /* many Microsoft products for Windows rely - on this */ + EAX = (EAX & 0xffff0000L) | 0x0100; + /* many Microsoft products for Windows rely on this */ break; case 0x48: /* ALLOCATE MEMORY */ @@ -1088,8 +1003,10 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */ - exit(AX & 0xff); - + fprintf(stderr,"int21: DosExit\n"); + exit(EAX & 0xff); + break; + case 0x4d: /* GET RETURN CODE */ GetReturnCode(context); break; @@ -1111,7 +1028,7 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x57: /* FILE DATE AND TIME */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: GetFileDateTime(context); break; @@ -1122,12 +1039,12 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: - AX = 0x01; + EAX = (EAX & 0xffffff00L) | 0x01L; break; case 0x02: - AX &= 0xff00; + EAX &= 0xff00L; break; case 0x01: case 0x03: @@ -1154,11 +1071,38 @@ int do_int21(struct sigcontext_struct * context){ case 0x5d: /* NETWORK */ case 0x5e: - case 0x5f: - AX &= 0xff00; - AX |= NoNetwork; /* network software not installed */ + 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); @@ -1173,21 +1117,25 @@ int do_int21(struct sigcontext_struct * context){ break; case 0x66: /* GLOBAL CODE PAGE TABLE */ - switch (AX & 0xff) { + switch (EAX & 0xffL) { case 0x01: - BX = CodePage; - DX = BX; + EBX = CodePage; + EDX = EBX; ResetCflag; break; case 0x02: - CodePage = BX; + CodePage = EBX; ResetCflag; break; } break; + + case 0x68: /* "FFLUSH" - COMMIT FILE */ + ResetCflag; + break; case 0x69: /* DISK SERIAL NUMBER */ - switch (AX & 0xff) { + switch (EAX & 0xff) { case 0x00: GetDiskSerialNumber(context); break; @@ -1197,6 +1145,10 @@ int do_int21(struct sigcontext_struct * context){ } break; + case 0x6a: /* COMMIT FILE */ + ResetCflag; + break; + default: fprintf(stderr,"Unable to handle int 0x21 %x\n", context->sc_eax); return 1; @@ -1204,3 +1156,72 @@ int do_int21(struct sigcontext_struct * context){ } return 1; } + +/********************************************************************/ + +static void +GetTimeDate(int time_flag) +{ + struct tm *now; + time_t ltime; + + ltime = time(NULL); + now = localtime(<ime); + if (time_flag) + { + _CX = (now->tm_hour << 8) | now->tm_min; + _DX = now->tm_sec << 8; + } + else + { + _CX = now->tm_year + 1900; + _DX = ((now->tm_mon + 1) << 8) | now->tm_mday; + _AX &= 0xff00; + _AX |= now->tm_wday; + } +#ifdef DEBUG_DOS + printf("GetTimeDate: AX = %04x, CX = %04x, DX = %04x\n", _AX, _CX, _DX); +#endif + + ReturnFromRegisterFunc(); + /* Function does not return */ +} + +/********************************************************************** + * KERNEL_DOS3Call + */ +int KERNEL_DOS3Call() +{ + switch ((_AX >> 8) & 0xff) + { + case 0x30: + _AX = 0x0303; + ReturnFromRegisterFunc(); + /* Function does not return */ + + case 0x25: + case 0x35: + return 0; + + case 0x2a: + GetTimeDate(0); + /* Function does not return */ + + case 0x2c: + GetTimeDate(1); + /* Function does not return */ + + case 0x4c: + exit(_AX & 0xff); + + default: + fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n", + _AX, _BX, _CX, _DX); + fprintf(stderr, " SP %04x, BP %04x, SI %04x, DI %04x\n", + _SP, _BP, _SI, _DI); + fprintf(stderr, " DS %04x, ES %04x\n", + _DS, _ES); + } + + return 0; +} diff --git a/misc/message.c b/misc/message.c index 281b0121a14..cde516415a0 100644 --- a/misc/message.c +++ b/misc/message.c @@ -21,6 +21,8 @@ typedef struct tagMSGBOX { HWND hWndNo; HWND hWndCancel; HICON hIcon; + RECT rectIcon; + RECT rectStr; } MSGBOX; typedef MSGBOX FAR* LPMSGBOX; @@ -46,7 +48,7 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) wndClass.cbWndExtra = 0; wndClass.hInstance = wndPtr->hInstance; wndClass.hIcon = (HICON)NULL; - wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); + wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = "MESSAGEBOX"; @@ -57,7 +59,7 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) mb.wType = type; mb.ActiveFlg = TRUE; hDlg = CreateWindow("MESSAGEBOX", title, - WS_POPUP | WS_DLGFRAME | WS_VISIBLE, 100, 150, 320, 120, + WS_POPUP | WS_DLGFRAME | WS_VISIBLE, 100, 150, 400, 120, (HWND)NULL, (HMENU)NULL, wndPtr->hInstance, (LPSTR)&mb); if (hDlg == 0) return 0; while(TRUE) { @@ -113,47 +115,63 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) *((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 - 70, rect.bottom - 25, + rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); break; case MB_OKCANCEL : lpmb->hWndYes = CreateWindow("BUTTON", "&Ok", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 65, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 10, rect.bottom - 25, + rect.right / 2 + 5, rect.bottom - 25, 60, 18, hWnd, 2, wndPtr->hInstance, 0L); break; case MB_ABORTRETRYIGNORE : lpmb->hWndYes = CreateWindow("BUTTON", "&Retry", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 100, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 10, rect.bottom - 25, + rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, 2, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 80, rect.bottom - 25, + rect.right / 2 + 40, rect.bottom - 25, 60, 18, hWnd, 3, wndPtr->hInstance, 0L); break; case MB_YESNO : lpmb->hWndYes = CreateWindow("BUTTON", "&Yes", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 - 70, rect.bottom - 25, + rect.right / 2 - 65, rect.bottom - 25, 60, 18, hWnd, 1, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", "&No", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, - rect.right / 2 + 10, rect.bottom - 25, + rect.right / 2 + 5, rect.bottom - 25, 60, 18, hWnd, 2, 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, 1, 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, 2, 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, 3, wndPtr->hInstance, 0L); + break; } switch(lpmb->wType & MB_ICONMASK) { case MB_ICONEXCLAMATION: @@ -173,16 +191,25 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) 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; + } break; case WM_PAINT: lpmb = MsgBoxGetStorageHeader(hWnd); - GetClientRect(hWnd, &rect); + CopyRect(&rect, &lpmb->rectStr); hDC = BeginPaint(hWnd, &ps); - if (lpmb->hIcon) DrawIcon(hDC, 30, 20, lpmb->hIcon); - TextOut(hDC, rect.right / 2, 15, - lpmb->Title, strlen(lpmb->Title)); - TextOut(hDC, rect.right / 2, 30, - lpmb->Str, strlen(lpmb->Str)); + if (lpmb->hIcon) + DrawIcon(hDC, lpmb->rectIcon.left, + lpmb->rectIcon.top, lpmb->hIcon); + DrawText(hDC, lpmb->Str, -1, &rect, + DT_CALCRECT | DT_CENTER | DT_WORDBREAK); + rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2; + rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2; + DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: @@ -216,7 +243,7 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) DeleteDC(hMemDC); } */ - hBitMap = LoadBitmap((HINSTANCE)NULL, "SMILE"); + hBitMap = LoadBitmap((HINSTANCE)NULL, "WINELOGO"); GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); printf("bm.bmWidth=%d bm.bmHeight=%d\n", bm.bmWidth, bm.bmHeight); @@ -234,12 +261,15 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) break; case 3: hDC = GetDC(hWnd); - hInst2 = LoadImage("ev3lite.exe", NULL); + hInst2 = LoadImage("ev3lite.exe"); + printf("hInst2=%04X\n", hInst2); hIcon = LoadIcon(hInst2, "EV3LITE"); DrawIcon(hDC, 20, 20, hIcon); DestroyIcon(hIcon); - hInst2 = LoadImage("sysres.dll", NULL); - hIcon = LoadIcon(hInst2, "WINEICON"); + hInst2 = LoadImage("moricons.dll"); + printf("hInst2=%04X\n", hInst2); + hIcon = LoadIcon(hInst2, MAKEINTRESOURCE(1)); +/* hIcon = LoadIcon(hInst2, "WINEICON"); */ DrawIcon(hDC, 60, 20, hIcon); DestroyIcon(hIcon); hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); diff --git a/misc/profile.c b/misc/profile.c index ac50d862833..12d12fe2704 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -3,6 +3,12 @@ * * Copyright (c) 1993 Miguel de Icaza * + * 1/Dec o Corrected return values for Get*ProfileString + * + * o Now, if AppName == NULL in Get*ProfileString it returns a list + * of the KeyNames (as documented in the MS-SDK). + * + * o if KeyValue == NULL now clears the value in Get*ProfileString */ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; @@ -12,7 +18,8 @@ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; #include "windows.h" #include "wine.h" -#define INIFILE GetSystemIniFilename() +/* #define DEBUG */ + #define STRSIZE 255 #define xmalloc(x) malloc(x) #define overflow (next == &CharBuffer [STRSIZE-1]) @@ -63,9 +70,15 @@ static TSecHeader *load (char *file) char *next; char c; +#ifdef DEBUG + printf("Load %s\n", file); +#endif if ((f = fopen (file, "r"))==NULL) return NULL; +#ifdef DEBUG + printf("Loading %s\n", file); +#endif state = FirstBrace; while ((c = getc (f)) != EOF){ if (c == '\r') /* Ignore Carriage Return */ @@ -79,6 +92,9 @@ static TSecHeader *load (char *file) next = CharBuffer; SecHeader->AppName = strdup (CharBuffer); state = IgnoreToEOL; +#ifdef DEBUG + printf("%s: section %s\n", file, CharBuffer); +#endif } else *next++ = c; break; @@ -122,6 +138,9 @@ static TSecHeader *load (char *file) SecHeader->Keys->KeyName = strdup (CharBuffer); state = KeyValue; next = CharBuffer; +#ifdef DEBUG + printf("%s: key %s\n", file, CharBuffer); +#endif } else *next++ = c; break; @@ -175,22 +194,36 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, section = New->Section; Current = New; } - /* Start search */ for (; section; section = section->link){ if (strcasecmp (section->AppName, AppName)) continue; + + /* If no key value given, then list all the keys */ + if ((!AppName) && (!set)){ + char *p = ReturnedString; + int left = Size - 1; + int slen; + + for (key = section->Keys; key; key = key->link){ + strncpy (p, key->KeyName, left); + slen = strlen (key->KeyName) + 1; + left -= slen+1; + p += slen; + } + return left; + } for (key = section->Keys; key; key = key->link){ if (strcasecmp (key->KeyName, KeyName)) continue; if (set){ free (key->Value); - key->Value = strdup (Default); + key->Value = strdup (Default ? Default : ""); return 1; } ReturnedString [Size-1] = 0; strncpy (ReturnedString, key->Value, Size-1); - return 1; + return 1; } /* If Getting the information, then don't write the information to the INI file, need to run a couple of tests with windog */ @@ -222,14 +255,20 @@ short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, LPSTR ReturnedString, short Size, LPSTR FileName) { - return (GetSetProfile (0, AppName, KeyName, Default, ReturnedString, Size, FileName)); + int v; + + v = GetSetProfile (0,AppName,KeyName,Default,ReturnedString,Size,FileName); + if (AppName) + return strlen (ReturnedString); + else + return Size - v; } int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, LPSTR ReturnedString, int Size) { return GetPrivateProfileString (AppName, KeyName, Default, - ReturnedString, Size, INIFILE); + ReturnedString, Size, WIN_INI); } WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default, @@ -251,7 +290,7 @@ WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default, WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default) { - return GetPrivateProfileInt (AppName, KeyName, Default, INIFILE); + return GetPrivateProfileInt (AppName, KeyName, Default, WIN_INI); } BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String, @@ -262,7 +301,7 @@ BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String, BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String) { - return (WritePrivateProfileString (AppName, KeyName, String, INIFILE)); + return (WritePrivateProfileString (AppName, KeyName, String, WIN_INI)); } static void dump_keys (FILE *profile, TKeys *p) diff --git a/misc/user.c b/misc/user.c index 58087eeaaa8..501448cd55d 100644 --- a/misc/user.c +++ b/misc/user.c @@ -6,8 +6,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "prototypes.h" #include "windows.h" #include "user.h" - -#define DEFAULT_MSG_QUEUE_SIZE 8 +#include "message.h" #define USER_HEAP_SIZE 0x10000 @@ -15,6 +14,9 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; MDESC *USER_Heap = NULL; +extern BOOL ATOM_Init(); +extern BOOL GDI_Init(); + /*********************************************************************** * USER_HeapInit */ @@ -24,7 +26,6 @@ static BOOL USER_HeapInit() s = GetNextSegment( 0, 0x10000 ); if (s == NULL) return FALSE; HEAP_Init( &USER_Heap, s->base_addr, USER_HEAP_SIZE ); - free(s); return TRUE; } @@ -37,6 +38,11 @@ static BOOL USER_HeapInit() int USER_InitApp(int hInstance) { + int queueSize; + + /* Global atom table initialisation */ + if (!ATOM_Init()) return 0; + /* GDI initialisation */ if (!GDI_Init()) return 0; @@ -54,9 +60,14 @@ USER_InitApp(int hInstance) /* Initialize dialog manager */ if (!DIALOG_Init()) return 0; - + + /* Create system message queue */ + queueSize = GetProfileInt( "windows", "TypeAhead", 120 ); + if (!MSG_CreateSysMsgQueue( queueSize )) return 0; + /* Create task message queue */ - if (!SetMessageQueue( DEFAULT_MSG_QUEUE_SIZE )) return 0; + queueSize = GetProfileInt( "windows", "DefaultQueueSize", 8 ); + if (!SetMessageQueue( queueSize )) return 0; return 1; } diff --git a/misc/xt.c b/misc/xt.c index 8d386ae87d4..a829a5b8429 100644 --- a/misc/xt.c +++ b/misc/xt.c @@ -41,6 +41,8 @@ void main(int argc, char **argv) XT_display = XtDisplay( topLevelWidget ); XT_screen = XtScreen( topLevelWidget ); + DOS_InitFS(); + Comm_Init(); _WinMain( argc, argv ); } @@ -58,12 +60,6 @@ void MessageBeep( WORD i ) XBell(XT_display, 100); } -WORD RegisterWindowMessage( LPSTR str ) -{ - printf( "RegisterWindowMessage: '%s'\n", str ); - return 0xc000; -} - /*********************************************************************** * GetTickCount (USER.13) */ @@ -94,11 +90,10 @@ void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) { printf( "AdjustWindowRect: (%d,%d)-(%d,%d) %d %d\n", rect->left, rect->top, rect->right, rect->bottom, style, menu ); +#ifdef USE_XLIB + rect->right += 8; + rect->bottom += 34; +#endif } -HMENU CreateMenu() { return 0; } - -BOOL AppendMenu( HMENU hmenu, WORD flags, WORD id, LPSTR text ) { return TRUE;} - -BOOL DestroyMenu( HMENU hmenu ) { return TRUE; } diff --git a/objects/Imakefile b/objects/Imakefile new file mode 100644 index 00000000000..458761d9172 --- /dev/null +++ b/objects/Imakefile @@ -0,0 +1,43 @@ +#include "../Wine.tmpl" + +MODULE = objects + +SRCS = \ + bitmap.c \ + brush.c \ + font.c \ + gdiobj.c \ + palette.c \ + pen.c \ + dib.c \ + region.c \ + text.c \ + dcvalues.c \ + clipping.c \ + bitblt.c \ + linedda.c \ + color.c + +OBJS = \ + bitmap.o \ + brush.o \ + font.o \ + gdiobj.o \ + palette.o \ + pen.o \ + dib.o \ + region.o \ + text.o \ + dcvalues.o \ + clipping.o \ + bitblt.o \ + linedda.o \ + color.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/objects/bitblt.c b/objects/bitblt.c index 53e9ba1a03a..c4ed6bc516c 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c @@ -38,10 +38,10 @@ BOOL PatBlt( HDC hdc, short left, short top, else rop = (rop & 0x03) | ((rop >> 4) & 0x0c); XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[rop] ); - x1 = XLPTODP( dc, left ); - x2 = XLPTODP( dc, left + width ); - y1 = YLPTODP( dc, top ); - y2 = YLPTODP( dc, top + height ); + x1 = dc->w.DCOrgX + XLPTODP( dc, left ); + x2 = dc->w.DCOrgX + XLPTODP( dc, left + width ); + y1 = dc->w.DCOrgY + YLPTODP( dc, top ); + y2 = dc->w.DCOrgY + YLPTODP( dc, top + height ); XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, MIN(x1,x2), MIN(y1,y2), abs(x2-x1), abs(y2-y1) ); return TRUE; @@ -78,14 +78,14 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ); if (!dcSrc) return FALSE; - xs1 = XLPTODP( dcSrc, xSrc ); - xs2 = XLPTODP( dcSrc, xSrc + width ); - ys1 = YLPTODP( dcSrc, ySrc ); - ys2 = YLPTODP( dcSrc, ySrc + height ); - xd1 = XLPTODP( dcDest, xDest ); - xd2 = XLPTODP( dcDest, xDest + width ); - yd1 = YLPTODP( dcDest, yDest ); - yd2 = YLPTODP( dcDest, yDest + height ); + xs1 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc ); + xs2 = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc + width ); + ys1 = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc ); + ys2 = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc + height ); + xd1 = dcDest->w.DCOrgX + XLPTODP( dcDest, xDest ); + xd2 = dcDest->w.DCOrgX + XLPTODP( dcDest, xDest + width ); + yd1 = dcDest->w.DCOrgY + YLPTODP( dcDest, yDest ); + yd2 = dcDest->w.DCOrgY + YLPTODP( dcDest, yDest + height ); if ((abs(xs2-xs1) != abs(xd2-xd1)) || (abs(ys2-ys1) != abs(yd2-yd1))) return FALSE; /* Should call StretchBlt here */ @@ -109,3 +109,78 @@ BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height, } return TRUE; } + + + +/*********************************************************************** + * StrechBlt (GDI.35) + */ +BOOL StrechBlt( HDC hdcDest, short xDest, short yDest, short widthDest, short heightDest, + HDC hdcSrc, short xSrc, short ySrc, short widthSrc, short heightSrc, DWORD rop ) +{ + int xs1, xs2, ys1, ys2; + int xd1, xd2, yd1, yd2; + DC *dcDest, *dcSrc; + +/*#ifdef DEBUG_GDI */ + + printf( "StrechBlt: %d %d,%d %dx%d %d %d,%d %dx%d %08x\n", + hdcDest, xDest, yDest, widthDest, heightDest, hdcSrc, xSrc, + ySrc, widthSrc, heightSrc, rop ); +/*#endif */ + + + + if ((rop & 0xcc0000) == ((rop & 0x330000) << 2)) + return PatBlt( hdcDest, xDest, yDest, widthDest, heightDest, rop ); + + printf("here\n"); + + rop >>= 16; + if ((rop & 0x0f) != (rop >> 4)) + { + printf( "BitBlt: Unimplemented ROP %02x\n", rop ); + return FALSE; + } + + printf("here2\n"); + + dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC ); + if (!dcDest) return FALSE; + dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ); + if (!dcSrc) return FALSE; + + xs1 = XLPTODP( dcSrc, xSrc ); + xs2 = XLPTODP( dcSrc, xSrc + widthSrc ); + ys1 = YLPTODP( dcSrc, ySrc ); + ys2 = YLPTODP( dcSrc, ySrc + heightSrc ); + xd1 = XLPTODP( dcDest, xDest ); + xd2 = XLPTODP( dcDest, xDest + widthDest ); + yd1 = YLPTODP( dcDest, yDest ); + yd2 = YLPTODP( dcDest, yDest + heightDest ); + + DC_SetupGCForText( dcDest ); + XSetFunction( XT_display, dcDest->u.x.gc, DC_XROPfunction[rop & 0x0f] ); + + if (dcSrc->w.bitsPerPixel == dcDest->w.bitsPerPixel) + { + printf("XCopyArea\n"); + XCopyArea( XT_display, dcSrc->u.x.drawable, + dcDest->u.x.drawable, dcDest->u.x.gc, + MIN(xs1,xs2), MIN(ys1,ys2), abs(xd2-xd1), abs(yd2-yd1), + MIN(xd1,xd2), MIN(yd1,yd2) ); + } + else + { + printf("XCopyPlane\n"); + if (dcSrc->w.bitsPerPixel != 1) return FALSE; + XCopyPlane( XT_display, dcSrc->u.x.drawable, + dcDest->u.x.drawable, dcDest->u.x.gc, + MIN(xs1,xs2), MIN(ys1,ys2), abs(xd2-xd1), abs(yd2-yd1), + MIN(xd1,xd2), MIN(yd1,yd2), 1 ); + } + return TRUE; + + +} + diff --git a/objects/bitmap.c b/objects/bitmap.c index 9de4c1c31a5..ffec3e9a760 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -46,6 +46,7 @@ BOOL BITMAP_Init() if (tmpPixmap) { bitmapGC[i] = XCreateGC( XT_display, tmpPixmap, 0, NULL ); + XSetGraphicsExposures( XT_display, bitmapGC[i], False ); XFreePixmap( XT_display, tmpPixmap ); } else bitmapGC[i] = 0; @@ -355,6 +356,8 @@ HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap, 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 ); diff --git a/objects/clipping.c b/objects/clipping.c index ec9de9ccde5..5776eb857d0 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -10,10 +10,33 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" +/*********************************************************************** + * CLIPPING_SetDeviceClipping + * + * Set the clip region of the physical device. + */ +void CLIPPING_SetDeviceClipping( DC * dc ) +{ + if (dc->w.hGCClipRgn) + { + RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); + XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); + XSetClipOrigin( XT_display, dc->u.x.gc, + dc->w.DCOrgX + obj->region.box.left, + dc->w.DCOrgY + obj->region.box.top ); + } + else + { + XSetClipMask( XT_display, dc->u.x.gc, None ); + XSetClipOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY ); + } +} + + /*********************************************************************** * CLIPPING_UpdateGCRegion * - * Update the GC clip region when the ClipRgn of VisRgn have changed. + * Update the GC clip region when the ClipRgn or VisRgn have changed. */ static void CLIPPING_UpdateGCRegion( DC * dc ) { @@ -36,19 +59,7 @@ static void CLIPPING_UpdateGCRegion( DC * dc ) else CombineRgn( dc->w.hGCClipRgn, dc->w.hClipRgn, dc->w.hVisRgn, RGN_AND ); } - - if (dc->w.hGCClipRgn) - { - RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hGCClipRgn, REGION_MAGIC ); - XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); - XSetClipOrigin( XT_display, dc->u.x.gc, - obj->region.box.left, obj->region.box.top ); - } - else - { - XSetClipMask( XT_display, dc->u.x.gc, None ); - XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 ); - } + CLIPPING_SetDeviceClipping( dc ); } @@ -157,26 +168,40 @@ int OffsetVisRgn( HDC hdc, short x, short y ) int CLIPPING_IntersectRect( DC * dc, HRGN * hrgn, short left, short top, short right, short bottom, int exclude ) { - HRGN tempRgn, newRgn; + HRGN tempRgn = 0, prevRgn = 0, newRgn = 0; RGNOBJ *newObj, *prevObj; int retval; - if (!*hrgn) return NULLREGION; - if (!(newRgn = CreateRectRgn( 0, 0, 0, 0))) return ERROR; - if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) + if (!*hrgn) { - DeleteObject( newRgn ); - return ERROR; + if (!(*hrgn = CreateRectRgn( 0, 0, dc->w.DCSizeX, dc->w.DCSizeY ))) + goto Error; + prevRgn = *hrgn; } + if (!(newRgn = CreateRectRgn( 0, 0, 0, 0))) goto Error; + if (!(tempRgn = CreateRectRgn( left, top, right, bottom ))) goto Error; + retval = CombineRgn( newRgn, *hrgn, tempRgn, exclude ? RGN_DIFF : RGN_AND); + if (retval == ERROR) goto Error; + newObj = (RGNOBJ *) GDI_GetObjPtr( newRgn, REGION_MAGIC ); prevObj = (RGNOBJ *) GDI_GetObjPtr( *hrgn, REGION_MAGIC ); if (newObj && prevObj) newObj->header.hNext = prevObj->header.hNext; DeleteObject( tempRgn ); - DeleteObject( *hrgn ); + if (*hrgn) DeleteObject( *hrgn ); *hrgn = newRgn; CLIPPING_UpdateGCRegion( dc ); return retval; + + Error: + if (tempRgn) DeleteObject( tempRgn ); + if (newRgn) DeleteObject( newRgn ); + if (prevRgn) + { + DeleteObject( prevRgn ); + *hrgn = 0; + } + return ERROR; } @@ -292,13 +317,9 @@ int GetClipBox( HDC hdc, LPRECT rect ) if (dc->w.hGCClipRgn) return GetRgnBox( dc->w.hGCClipRgn, rect ); else { - Window root; - int width, height, x, y, border, depth; - XGetGeometry( XT_display, dc->u.x.drawable, &root, &x, &y, - &width, &height, &border, &depth ); rect->top = rect->left = 0; - rect->right = width & 0xffff; - rect->bottom = height & 0xffff; + rect->right = dc->w.DCSizeX; + rect->bottom = dc->w.DCSizeY; return SIMPLEREGION; } } diff --git a/objects/dcvalues.c b/objects/dcvalues.c index b496e2e3609..73c98aabedd 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c @@ -45,6 +45,8 @@ const WIN_DC_INFO DCVAL_defaultValues = MM_TEXT, /* MapMode */ 0, /* DCOrgX */ 0, /* DCOrgY */ + 0, /* DCSizeX */ + 0, /* DCSizeY */ 0, /* CursPosX */ 0, /* CursPosY */ 0, /* WndOrgX */ diff --git a/objects/font.c b/objects/font.c index 1299a26ac51..10bc76b7b08 100644 --- a/objects/font.c +++ b/objects/font.c @@ -331,6 +331,36 @@ BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics ) } +/***********************************************************************/ + +#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ + (((cs)->rbearing|(cs)->lbearing| \ + (cs)->ascent|(cs)->descent) == 0)) + +/* + * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit + * character. If the character is in the column and exists, then return the + * appropriate metrics (note that fonts with common per-character metrics will + * return min_bounds). If none of these hold true, try again with the default + * char. + */ +#define CI_GET_CHAR_INFO(fs,col,def,cs) \ +{ \ + cs = def; \ + if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ +} + +#define CI_GET_DEFAULT_INFO(fs,cs) \ + CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs) + + /*********************************************************************** * GetCharWidth (GDI.350) */ @@ -338,8 +368,7 @@ BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer) { int i, j; XFontStruct *xfont; - XCharStruct *charPtr; - int default_width; + XCharStruct *cs, *def; DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC); if (!dc) return FALSE; @@ -353,15 +382,12 @@ BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer) return TRUE; } - charPtr = xfont->per_char; - default_width = (charPtr + xfont->default_char)->width; + CI_GET_DEFAULT_INFO(xfont, def); for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++) { - if (i < xfont->min_char_or_byte2 || i > xfont->max_char_or_byte2) - *(lpBuffer + j) = default_width; - else - *(lpBuffer + j) = charPtr->width; + CI_GET_CHAR_INFO(xfont, i, def, cs); + *(lpBuffer + j) = cs->width; } return TRUE; } diff --git a/objects/gdiobj.c b/objects/gdiobj.c index 32bb4b8ae01..cc539a49025 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -153,7 +153,6 @@ BOOL GDI_Init() s = (struct segment_descriptor_s *)GetNextSegment( 0, 0x10000 ); if (s == NULL) return FALSE; HEAP_Init( &GDI_Heap, s->base_addr, GDI_HEAP_SIZE ); - free(s); /* Create default palette */ @@ -200,8 +199,11 @@ HANDLE GDI_AllocObject( WORD size, WORD magic ) GDIOBJHDR * obj; HANDLE handle = GDI_HEAP_ALLOC( GMEM_MOVEABLE, size ); if (!handle) return 0; - obj = (GDIOBJHDR *) GDI_HEAP_ADDR( handle ); + if (obj == NULL) { + printf("GDI_AllocObject // Error trying to get GDI_HEAD_ADDR !\n"); + return 0; + } obj->hNext = 0; obj->wMagic = magic; obj->dwCount = ++count; diff --git a/objects/palette.c b/objects/palette.c index 3b101b2608f..511cf3f0efb 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -177,3 +177,21 @@ int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer ) memcpy( buffer, &palette->logpalette.palNumEntries, count ); return count; } + + +/*********************************************************************** + * SelectPalette (USER.282) + */ +HPALETTE SelectPalette(HDC hDC, HPALETTE hPal, BOOL bForceBackground) +{ + return (HPALETTE)NULL; +} + +/*********************************************************************** + * RealizePalette (USER.283) + */ +int RealizePalette(HDC hDC) +{ + return 0; +} + diff --git a/objects/region.c b/objects/region.c index 08274ca08aa..3a7b9ef290a 100644 --- a/objects/region.c +++ b/objects/region.c @@ -31,6 +31,7 @@ BOOL REGION_Init() XFreePixmap( XT_display, tmpPixmap ); if (!regionGC) return FALSE; XSetForeground( XT_display, regionGC, 1 ); + XSetGraphicsExposures( XT_display, regionGC, False ); return TRUE; } else return FALSE; diff --git a/objects/text.c b/objects/text.c index bbb2740085d..07aef5835c4 100644 --- a/objects/text.c +++ b/objects/text.c @@ -229,7 +229,8 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } - if (!TextOut(hdc, x, y, line, len)) return 0; + if (!(flags & DT_CALCRECT)) + if (!TextOut(hdc, x, y, line, len)) return 0; if (prefix_offset != -1) { MoveTo(hdc, x + prefix_x, y + size.cy); @@ -247,7 +248,7 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) } } while (strPtr); - + if (flags & DT_CALCRECT) rect->bottom = y; return 1; } @@ -314,10 +315,10 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) { if (dc->w.backgroundMode == TRANSPARENT) XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y, str, count ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count ); else XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y, str, count ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count ); } else { @@ -340,14 +341,15 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) if (dc->w.backgroundMode == TRANSPARENT) XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc, - xchar, y, p, 1 ); + dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 ); else { XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc, - xchar, y, p, 1 ); + dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 ); XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel); XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - xchar + charStr->width, y - font->ascent, + dc->w.DCOrgX + xchar + charStr->width, + dc->w.DCOrgY + y - font->ascent, extraWidth, font->ascent + font->descent ); XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel ); } @@ -368,7 +370,8 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth, LineSolid, CapRound, JoinBevel ); XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y + linePos, x + info.width, y + linePos ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos, + dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos ); } if (dc->u.x.font.metrics.tmStruckOut) { @@ -380,7 +383,8 @@ BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count ) XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent, LineSolid, CapRound, JoinBevel ); XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc, - x, y - lineAscent, x + info.width, y - lineAscent ); + dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent, + dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent ); } return TRUE; diff --git a/sysres.dll b/sysres.dll index 44a53abd38e2eccc301fd1aa8481aa829a9fce04..38c7ca909d2540ae5515dee73c18b4706a6d6a08 100755 GIT binary patch literal 86528 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ƉV(tl$TD(ksTr+vKwK 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 Xeso>;kICXh8Vu2s!)$qeljHvfW$j!c literal 66048 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 O96bhI>Ca!}_WuV;YmdqR diff --git a/test/Imakefile b/test/Imakefile new file mode 100644 index 00000000000..d45263d3c95 --- /dev/null +++ b/test/Imakefile @@ -0,0 +1,8 @@ +all:: + +depend:: + +clean:: + +includes:: + diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000000..535cc4716d3 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,347 @@ +# Makefile generated by imake - do not edit! +# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $ + +# ------------------------------------------------------------------------- +# Makefile generated from "Imake.tmpl" and <Imakefile> +# $XFree86: mit/config/Imake.tmpl,v 1.17 1993/06/03 15:26:36 dawes Exp $ +# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $ +# +# Platform-specific parameters may be set in the appropriate <vendor>.cf +# configuration files. Site-specific parameters should be set in the file +# site.def. Full rebuilds are recommended if any parameters are changed. +# +# If your C preprocessor does not define any unique symbols, you will need +# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing +# "make World" the first time). +# + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that need to come before +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + +# ------------------------------------------------------------------------- +# platform-specific configuration parameters - edit x386.cf to change + +# $XFree86: mit/config/x386.cf,v 1.90 1993/06/04 16:02:50 dawes Exp $ +# platform: $XConsortium: x386.cf,v 1.7 91/08/16 19:30:10 gildea Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version definition +# $XFree86: mit/config/xf86_vers.def,v 1.5 1993/06/01 09:12:47 dawes Exp $ + +# ------------------------------------------------------------------------- +# XFree86 version: 1300 +# ------------------------------------------------------------------------- + +# $XFree86: mit/config/lnuxLib.rules,v 1.2 1993/06/02 13:48:12 dawes Exp $ + +DLL_BINDIR = /usr/dll/bin + +# operating system: Linux + +# ------------------------------------------------------------------------- +# site-specific configuration parameters that go after +# the platform-specific parameters - edit site.def to change + +# $XFree86: mit/config/site.def,v 1.65 1993/06/04 16:02:47 dawes Exp $ +# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $ + +# obz: changes for making Linux distribution + + SHELL = /bin/sh + + TOP = ../. + CURRENT_DIR = ./test + + AR = ar clq + BOOTSTRAPCFLAGS = + CC = gcc + AS = as + + LEX = flex + + YACC = bison -y + + COMPRESS = compress + CPP = /lib/cpp $(STD_CPP_DEFINES) + PREPROCESSCMD = /lib/cpp $(STD_CPP_DEFINES) + INSTALL = install + LD = ld + LINT = lint + LINTLIBFLAG = -C + LINTOPTS = -axz + LN = ln -s + MAKE = make + MV = mv + CP = cp + + RANLIB = ranlib + RANLIBINSTFLAGS = + + RM = rm -f + TROFF = psroff + MSMACROS = -ms + TBL = tbl + EQN = eqn + STD_INCLUDES = + STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -Dlinux + EXTRA_LOAD_FLAGS = + EXTRA_LIBRARIES = + OS_LIBRARIES = + TAGS = ctags + + SHAREDCODEDEF = + SHLIBDEF = + + PROTO_DEFINES = -DFUNCPROTO=11 -DNARROWPROTO + + INSTPGMFLAGS = -s + + INSTBINFLAGS = -m 0755 + INSTUIDFLAGS = -s -m 4755 + INSTLIBFLAGS = -m 0644 + INSTINCFLAGS = -m 0444 + INSTMANFLAGS = -m 0444 + INSTDATFLAGS = -m 0444 + INSTKMEMFLAGS = -s -m 4755 + + PROJECTROOT = /usr/X386 + + TOP_INCLUDES = -I$(INCROOT) + + CDEBUGFLAGS = -O2 + CCOPTIONS = -m486 -DNO_ASM -fwritable-strings + ANSICCOPTIONS = + + ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES) + CFLAGS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) + LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) + + LDLIBS = $(OS_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) + + LDOPTIONS = $(ANSICCOPTIONS) $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR) + + LDCOMBINEFLAGS = -r + DEPENDFLAGS = + + MACROFILE = x386.cf + RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut + + IMAKE_DEFINES = + + IRULESRC = $(CONFIGDIR) + IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) + + ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES) + +# ------------------------------------------------------------------------- +# X Window System Build Parameters +# $XFree86: mit/config/Project.tmpl,v 1.13 1993/03/27 03:32:45 dawes Exp $ +# $XConsortium: Project.tmpl,v 1.138.1.1 92/11/11 09:49:19 rws Exp $ + +_percentC_ = %C + +# ------------------------------------------------------------------------- +# X Window System make variables; this need to be coordinated with rules + + PATHSEP = / + USRLIBDIR = /usr/X386/lib + BINDIR = /usr/X386/bin + INCROOT = /usr/X386/include + BUILDINCROOT = $(TOP) + BUILDINCDIR = $(BUILDINCROOT)/X11 + BUILDINCTOP = .. + INCDIR = $(INCROOT)/X11 + ADMDIR = /usr/adm + LIBDIR = $(USRLIBDIR)/X11 + CONFIGDIR = $(LIBDIR)/config + LINTLIBDIR = $(USRLIBDIR)/lint + + FONTDIR = $(LIBDIR)/fonts + XINITDIR = $(LIBDIR)/xinit + XDMDIR = $(LIBDIR)/xdm + TWMDIR = $(LIBDIR)/twm + MANPATH = /usr/X386/man + MANSOURCEPATH = $(MANPATH)/man + MANSUFFIX = 1x + LIBMANSUFFIX = 3x + MANDIR = $(MANSOURCEPATH)1 + LIBMANDIR = $(MANSOURCEPATH)3 + NLSDIR = $(LIBDIR)/nls + PEXAPIDIR = $(LIBDIR)/PEX + XAPPLOADDIR = $(LIBDIR)/app-defaults + FONTCFLAGS = -t + LINKKITDIR = $(USRLIBDIR)/Server + + INSTAPPFLAGS = $(INSTDATFLAGS) + + IMAKE = imake + DEPEND = makedepend + RGB = rgb + + FONTC = bdftopcf + + MKFONTDIR = mkfontdir + MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier + + CONFIGSRC = $(TOP)/config + DOCUTILSRC = $(TOP)/doc/util + CLIENTSRC = $(TOP)/clients + DEMOSRC = $(TOP)/demos + LIBSRC = $(TOP)/lib + FONTSRC = $(TOP)/fonts + INCLUDESRC = $(TOP)/X11 + SERVERSRC = $(TOP)/server + UTILSRC = $(TOP)/util + SCRIPTSRC = $(UTILSRC)/scripts + EXAMPLESRC = $(TOP)/examples + CONTRIBSRC = $(TOP)/../contrib + DOCSRC = $(TOP)/doc + RGBSRC = $(TOP)/rgb + DEPENDSRC = $(UTILSRC)/makedepend + IMAKESRC = $(CONFIGSRC) + XAUTHSRC = $(LIBSRC)/Xau + XLIBSRC = $(LIBSRC)/X + XMUSRC = $(LIBSRC)/Xmu + TOOLKITSRC = $(LIBSRC)/Xt + AWIDGETSRC = $(LIBSRC)/Xaw + OLDXLIBSRC = $(LIBSRC)/oldX + XDMCPLIBSRC = $(LIBSRC)/Xdmcp + BDFTOSNFSRC = $(FONTSRC)/bdftosnf + BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf + BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf + MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir + FSLIBSRC = $(FONTSRC)/lib/fs + FONTSERVERSRC = $(FONTSRC)/server + EXTENSIONSRC = $(TOP)/extensions + XILIBSRC = $(EXTENSIONSRC)/lib/xinput + PEXLIBSRC = $(EXTENSIONSRC)/lib/PEXlib + PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX + +# $XFree86: mit/config/lnuxLib.tmpl,v 1.1 1993/04/16 14:06:06 dawes Exp $ + +SHLIBLDFLAGS = +PICFLAGS = -B/usr/dll/jump/ + + DEPEXTENSIONLIB = + EXTENSIONLIB = -lXext + + DEPXLIB = $(DEPEXTENSIONLIB) + XLIB = $(EXTENSIONLIB) -lX11 + + DEPXMULIB = + XMULIB = -lXmu + + DEPXTOOLLIB = + XTOOLLIB = -lXt + + DEPXAWLIB = + XAWLIB = -lXaw + + DEPXILIB = + XILIB = -lXi + + DEPXTESTLIB = + XTESTLIB = -lXtst + + DEPPEXLIB = + PEXLIB = -lPEX5 + + SOXLIBREV = 3.0.1 + SOXTREV = 3.0.1 + SOXAWREV = 3.0.1 + SOOLDXREV = 3.0.1 + SOXMUREV = 3.0.1 + SOXEXTREV = 3.0.1 + SOXINPUTREV = 3.0.1 + SOPEXREV = 1.0.1 + + DEPXAUTHLIB = $(USRLIBDIR)/libXau.a + XAUTHLIB = -lXau + DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a + XDMCPLIB = -lXdmcp + + DEPOLDXLIB = $(USRLIBDIR)/liboldX.a + OLDXLIB = -loldX + + DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a + PHIGSLIB = -lphigs + + DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a + XBSDLIB = -lXbsd + + LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln + LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln + LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln + LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln + LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln + LINTXI = $(LINTLIBDIR)/llib-lXi.ln + LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln + LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln + + DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + + DEPLIBS1 = $(DEPLIBS) + DEPLIBS2 = $(DEPLIBS) + DEPLIBS3 = $(DEPLIBS) + +# ------------------------------------------------------------------------- +# Imake rules for building libraries, programs, scripts, and data files +# $XFree86: mit/config/Imake.rules,v 1.9 1993/03/23 12:56:27 dawes Exp $ +# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $ + +# ------------------------------------------------------------------------- +# start of Imakefile + +all:: + +depend:: + +clean:: + +includes:: + +# ------------------------------------------------------------------------- +# common rules for all Makefiles - do not edit + +emptyrule:: + +clean:: + $(RM_CMD) "#"* + +Makefile:: + -@if [ -f Makefile ]; then set -x; \ + $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ + else exit 0; fi + $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) + +tags:: + $(TAGS) -w *.[ch] + $(TAGS) -xw *.[ch] > TAGS + +# ------------------------------------------------------------------------- +# empty rules for directories that do not have SUBDIRS - do not edit + +install:: + @echo "install in $(CURRENT_DIR) done" + +install.man:: + @echo "install.man in $(CURRENT_DIR) done" + +install.linkkit:: + @echo "install.linkkit in $(CURRENT_DIR) done" + +Makefiles:: + +includes:: + +# ------------------------------------------------------------------------- +# dependencies generated by makedepend + diff --git a/test/widget.exe b/test/widget.exe index 6afbf24984c0166f9304baee6c47ceacef6e88cd..ea5dc2f8bf328cb955a66477af23da5f561865ef 100755 GIT binary patch literal 306490 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	}_UEY{DFr!LN7XAfyMTx%aZp|)0? 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 L#ORC3IoEza^&On7 literal 140094 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≻E%_o+tes#D| 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 KR})jl68$%wrB1^D diff --git a/tools/Imakefile b/tools/Imakefile new file mode 100644 index 00000000000..7b739a187fa --- /dev/null +++ b/tools/Imakefile @@ -0,0 +1,5 @@ +#include "../Wine.tmpl" + +MODULE = tools + +SimpleProgramTarget(build) diff --git a/windows/Imakefile b/windows/Imakefile new file mode 100644 index 00000000000..b16652fcaab --- /dev/null +++ b/windows/Imakefile @@ -0,0 +1,53 @@ +#include "../Wine.tmpl" + +MODULE = windows + +SRCS = \ + class.c \ + dc.c \ + dce.c \ + event.c \ + message.c \ + win.c \ + timer.c \ + graphics.c \ + clipping.c \ + mapping.c \ + painting.c \ + keyboard.c \ + utility.c \ + syscolor.c \ + defwnd.c \ + defdlg.c \ + dialog.c \ + focus.c \ + scroll.c + +OBJS = \ + class.o \ + dc.o \ + dce.o \ + event.o \ + message.o \ + win.o \ + timer.o \ + graphics.o \ + clipping.o \ + mapping.o \ + painting.o \ + keyboard.o \ + utility.o \ + syscolor.o \ + defwnd.o \ + defdlg.o \ + dialog.o \ + focus.o \ + scroll.o + +WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) +DependTarget() +CleanTarget() + +includes:: + +install:: diff --git a/windows/Makefile b/windows/Makefile index 0c5d34add37..30570a109c9 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -2,7 +2,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \ clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o \ - defwnd.o defdlg.o dialog.o focus.o scroll.o + defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o default: windows.o diff --git a/windows/caret.c b/windows/caret.c new file mode 100644 index 00000000000..eb78dc80ec1 --- /dev/null +++ b/windows/caret.c @@ -0,0 +1,250 @@ +/* + * Caret functions + * + * Copyright 1993 David Metcalfe + */ + +static char Copyright[] = "Copyright David Metcalfe, 1993"; + +#include <X11/Intrinsic.h> + +#include "windows.h" + +extern XtAppContext XT_app_context; + +typedef struct +{ + HWND hwnd; + short hidden; + BOOL on; + short x; + short y; + short width; + short height; + COLORREF color; + WORD timeout; + XtIntervalId xtid; +} CARET; + +static CARET Caret; +static BOOL LockCaret; + +static void CARET_Callback(XtPointer data, XtIntervalId *xtid); +static void CARET_HideCaret(CARET *pCaret); + + +/***************************************************************** + * CARET_Callback + */ + +static void CARET_Callback(XtPointer data, XtIntervalId *xtid) +{ + CARET *pCaret = (CARET *)data; + HDC hdc; + HBRUSH hBrush; + HRGN rgn; + +#ifdef DEBUG_CARET + printf("CARET_Callback: LockCaret=%d, hidden=%d, on=%d\n", + LockCaret, pCaret->hidden, pCaret->on); +#endif + if (!LockCaret && (!pCaret->hidden || pCaret->on)) + { + pCaret->on = (pCaret->on ? FALSE : TRUE); + hdc = GetDC(pCaret->hwnd); + hBrush = CreateSolidBrush(pCaret->color); + SelectObject(hdc, (HANDLE)hBrush); + SetROP2(hdc, R2_XORPEN); + rgn = CreateRectRgn(pCaret->x, pCaret->y, + pCaret->x + pCaret->width, + pCaret->y + pCaret->height); + FillRgn(hdc, rgn, hBrush); + DeleteObject((HANDLE)rgn); + DeleteObject((HANDLE)hBrush); + ReleaseDC(pCaret->hwnd, hdc); + } + + pCaret->xtid = XtAppAddTimeOut(XT_app_context, pCaret->timeout, + CARET_Callback, pCaret); +} + + +/***************************************************************** + * CARET_HideCaret + */ + +static void CARET_HideCaret(CARET *pCaret) +{ + HDC hdc; + HBRUSH hBrush; + HRGN rgn; + + pCaret->on = FALSE; + hdc = GetDC(pCaret->hwnd); + hBrush = CreateSolidBrush(pCaret->color); + SelectObject(hdc, (HANDLE)hBrush); + SetROP2(hdc, R2_XORPEN); + rgn = CreateRectRgn(pCaret->x, pCaret->y, + pCaret->x + pCaret->width, + pCaret->y + pCaret->height); + FillRgn(hdc, rgn, hBrush); + DeleteObject((HANDLE)rgn); + DeleteObject((HANDLE)hBrush); + ReleaseDC(pCaret->hwnd, hdc); +} + + +/***************************************************************** + * CreateCaret (USER.163) + */ + +void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) +{ + if (!hwnd) return; + + /* if cursor already exists, destroy it */ +/* if (Caret.hwnd) + DestroyCaret(); +*/ + if (bitmap) + { + printf("CreateCaret: Bitmaps are currently not supported\n"); + return; + } + + if (width) + Caret.width = width; + else + Caret.width = 3; /* should be SM_CXBORDER */ + + if (height) + Caret.height = height; + else + Caret.height = 3; /* should be SM_CYBORDER */ + + Caret.hwnd = hwnd; + Caret.hidden = 1; + Caret.on = FALSE; + Caret.x = 0; + Caret.y = 0; + Caret.color = GetSysColor(COLOR_WINDOWTEXT); + Caret.timeout = 750; + LockCaret = FALSE; + + Caret.xtid = XtAppAddTimeOut(XT_app_context, Caret.timeout, + CARET_Callback, &Caret); +} + + +/***************************************************************** + * DestroyCaret (USER.164) + */ + +void DestroyCaret() +{ +/* if (!Caret.hwnd) return; +*/ + XtRemoveTimeOut(Caret.xtid); + + if (Caret.on) + CARET_HideCaret(&Caret); + + Caret.hwnd = 0; /* cursor marked as not existing */ +} + + +/***************************************************************** + * SetCaretPos (USER.165) + */ + +void SetCaretPos(short x, short y) +{ + HDC hdc; + HBRUSH hBrush; + HRGN rgn; + + if (!Caret.hwnd) return; + +#ifdef DEBUG_CARET + printf("SetCaretPos: x=%d, y=%d\n", x, y); +#endif + + LockCaret = TRUE; + if (Caret.on) + CARET_HideCaret(&Caret); + + Caret.x = x; + Caret.y = y; + LockCaret = FALSE; +} + +/***************************************************************** + * HideCaret (USER.166) + */ + +void HideCaret(HWND hwnd) +{ + if (!Caret.hwnd) return; + if (hwnd && (Caret.hwnd != hwnd)) return; + + LockCaret = TRUE; + if (Caret.on) + CARET_HideCaret(&Caret); + + ++Caret.hidden; + LockCaret = FALSE; +} + + +/***************************************************************** + * ShowCaret (USER.167) + */ + +void ShowCaret(HWND hwnd) +{ + if (!Caret.hwnd) return; + if (hwnd && (Caret.hwnd != hwnd)) return; + +#ifdef DEBUG_CARET + printf("ShowCaret: hidden=%d\n", Caret.hidden); +#endif + if (Caret.hidden) + --Caret.hidden; +} + + +/***************************************************************** + * SetCaretBlinkTime (USER.168) + */ + +void SetCaretBlinkTime(WORD msecs) +{ + if (!Caret.hwnd) return; + + Caret.timeout = msecs; +} + + +/***************************************************************** + * GetCaretBlinkTime (USER.169) + */ + +WORD GetCaretBlinkTime() +{ + if (!Caret.hwnd) return; + + return Caret.timeout; +} + + +/***************************************************************** + * GetCaretPos (USER.183) + */ + +void GetCaretPos(LPPOINT pt) +{ + if (!Caret.hwnd || !pt) return; + + pt->x = Caret.x; + pt->y = Caret.y; +} diff --git a/windows/class.c b/windows/class.c index 23a2c495764..4ca2d9f5a2d 100644 --- a/windows/class.c +++ b/windows/class.c @@ -9,6 +9,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "class.h" #include "user.h" #include "win.h" +#include "dce.h" static HCLASS firstClass = 0; @@ -18,19 +19,50 @@ static HCLASS firstClass = 0; * CLASS_FindClassByName * * Return a handle and a pointer to the class. + * 'ptr' can be NULL if the pointer is not needed. */ HCLASS CLASS_FindClassByName( char * name, CLASS **ptr ) { - HCLASS class = firstClass; - while(class) + ATOM atom; + HCLASS class; + CLASS * classPtr; + + /* First search task-specific classes */ + + if ((atom = FindAtom( name )) != 0) + { + for (class = firstClass; (class); class = classPtr->hNext) + { + classPtr = (CLASS *) USER_HEAP_ADDR(class); + if (classPtr->wc.style & CS_GLOBALCLASS) continue; + if (classPtr->atomName == atom) + { + if (ptr) *ptr = classPtr; + return class; + } + } + } + + /* Then search global classes */ + + if ((atom = GlobalFindAtom( name )) != 0) { - *ptr = (CLASS *) USER_HEAP_ADDR(class); - if (!strcasecmp( (*ptr)->wc.lpszClassName, name )) return class; - class = (*ptr)->hNext; + for (class = firstClass; (class); class = classPtr->hNext) + { + classPtr = (CLASS *) USER_HEAP_ADDR(class); + if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue; + if (classPtr->atomName == atom) + { + if (ptr) *ptr = classPtr; + return class; + } + } } + return 0; } + /*********************************************************************** * CLASS_FindClassPtr * @@ -52,37 +84,50 @@ CLASS * CLASS_FindClassPtr( HCLASS hclass ) */ ATOM RegisterClass( LPWNDCLASS class ) { - CLASS * newClass; - HCLASS handle; + CLASS * newClass, * prevClassPtr; + HCLASS handle, prevClass; #ifdef DEBUG_CLASS printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n", class->lpfnWndProc, class->hInstance, class->lpszClassName ); #endif + /* Check if a class with this name already exists */ + + prevClass = CLASS_FindClassByName( class->lpszClassName, &prevClassPtr ); + if (prevClass) + { + /* Class can be created only if it is local and */ + /* if the class with the same name is global. */ + + if (class->style & CS_GLOBALCLASS) return 0; + if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0; + } + + /* Create class */ + handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra ); if (!handle) return 0; newClass = (CLASS *) USER_HEAP_ADDR( handle ); newClass->hNext = firstClass; newClass->wMagic = CLASS_MAGIC; - newClass->atomName = handle; /* Should be an atom */ newClass->cWindows = 0; newClass->wc = *class; + if (newClass->wc.style & CS_GLOBALCLASS) + newClass->atomName = GlobalAddAtom( class->lpszClassName ); + else newClass->atomName = AddAtom( class->lpszClassName ); + if (newClass->wc.style & CS_CLASSDC) - newClass->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ); - else newClass->hdc = 0; - - /* Class name should also be set to zero. For now we need the - * name because we don't have atoms. - */ - newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1); - strcpy( newClass->wc.lpszClassName, class->lpszClassName ); + newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC ); + else newClass->hdce = 0; + + /* Menu name should also be set to zero. */ + newClass->wc.lpszClassName = NULL; if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra ); - firstClass = handle; - return handle; /* Should be an atom */ + return newClass->atomName; } @@ -118,8 +163,10 @@ BOOL UnregisterClass( LPSTR className, HANDLE instance ) } /* Delete the class */ - if (classPtr->hdc) DeleteDC( classPtr->hdc ); + if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce ); if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground ); + if (classPtr->wc.style & CS_GLOBALCLASS) GlobalDeleteAtom( classPtr->atomName ); + else DeleteAtom( classPtr->atomName ); USER_HEAP_FREE( class ); return TRUE; } @@ -182,3 +229,34 @@ LONG SetClassLong( HWND hwnd, short offset, LONG newval ) *ptr = newval; return retval; } + + +/*********************************************************************** + * GetClassName (USER.58) + */ +int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount) +{ + WND *wndPtr; + CLASS *classPtr; + + if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; + if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0; + + return (GetAtomName(classPtr->atomName, lpClassName, maxCount)); +} + + +/*********************************************************************** + * GetClassInfo (USER.404) + */ +BOOL GetClassInfo(HANDLE hInstance, LPSTR lpClassName, + LPWNDCLASS lpWndClass) +{ + CLASS *classPtr; + + if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE; + if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE; + + memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS)); + return TRUE; +} diff --git a/windows/clipping.c b/windows/clipping.c index 2126c287333..3c759a68790 100644 --- a/windows/clipping.c +++ b/windows/clipping.c @@ -10,6 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "win.h" +#include "message.h" /*********************************************************************** @@ -34,6 +35,7 @@ void InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) else CombineRgn( newRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR ); } if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate ); + else MSG_IncPaintCount( wndPtr->hmemTaskQ ); wndPtr->hrgnUpdate = newRgn; if (erase) wndPtr->flags |= WIN_ERASE_UPDATERGN; } @@ -112,17 +114,14 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) if (rect) { - if (wndPtr->hrgnUpdate) GetRgnBox( wndPtr->hrgnUpdate, rect ); - else SetRectEmpty( rect ); - if (erase && wndPtr->hrgnUpdate) + if (wndPtr->hrgnUpdate) { - HDC hdc = GetDC( hwnd ); - if (hdc) - { - SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ); - ReleaseDC( hwnd, hdc ); - } + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE; + GetRgnBox( hrgn, rect ); + DeleteObject( hrgn ); } + else SetRectEmpty( rect ); } return (wndPtr->hrgnUpdate != 0); } @@ -133,17 +132,34 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) */ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) { + HRGN hrgnClip; + int retval; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return ERROR; - if (erase && wndPtr->hrgnUpdate) + if (!wndPtr->hrgnUpdate) + { + if (!(hrgnClip = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR; + retval = CombineRgn( hrgn, hrgnClip, 0, RGN_COPY ); + } + else { - HDC hdc = GetDC( hwnd ); - if (hdc) + hrgnClip = CreateRectRgn( 0, 0, + wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top ); + if (!hrgnClip) return ERROR; + retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND ); + if (erase) { - SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ); - ReleaseDC( hwnd, hdc ); - } + HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, + DCX_INTERSECTRGN | DCX_USESTYLE ); + if (hdc) + { + SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ); + ReleaseDC( hwnd, hdc ); + } + } } - return CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY ); + DeleteObject( hrgnClip ); + return retval; } diff --git a/windows/dc.c b/windows/dc.c index 1a65b415927..4224b3ad335 100644 --- a/windows/dc.c +++ b/windows/dc.c @@ -7,7 +7,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include <stdlib.h> -#include <X11/Intrinsic.h> #include "gdi.h" @@ -17,6 +16,8 @@ static DeviceCaps * displayDevCaps = NULL; extern const WIN_DC_INFO DCVAL_defaultValues; +extern void CLIPPING_SetDeviceClipping( DC * dc ); /* in objects/clipping.c */ + /* ROP code to GC function conversion */ const int DC_XROPfunction[16] = @@ -100,18 +101,8 @@ void DC_SetDeviceInfo( HDC hdc, DC * dc ) SelectObject( hdc, dc->w.hBrush ); SelectObject( hdc, dc->w.hFont ); - if (dc->w.hGCClipRgn) - { - RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC); - XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap ); - XSetClipOrigin( XT_display, dc->u.x.gc, - obj->region.box.left, obj->region.box.top ); - } - else - { - XSetClipMask( XT_display, dc->u.x.gc, None ); - XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 ); - } + XSetGraphicsExposures( XT_display, dc->u.x.gc, False ); + CLIPPING_SetDeviceClipping( dc ); } @@ -145,8 +136,11 @@ int DC_SetupGCForBrush( DC * dc ) XSetFillStyle( XT_display, dc->u.x.gc, (dc->w.backgroundMode == OPAQUE) ? FillOpaqueStippled : FillStippled ); - XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.brushOrgX, dc->w.brushOrgY ); + 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 ); return 1; } @@ -226,8 +220,7 @@ HDC GetDCState( HDC hdc ) if (dc->w.hVisRgn) { newdc->w.hVisRgn = CreateRectRgn( 0, 0, 0, 0 ); - CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY ); - + CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY ); } newdc->w.hGCClipRgn = 0; return handle; @@ -255,7 +248,7 @@ void SetDCState( HDC hdc, HDC hdcs ) dc->w.flags &= ~DC_SAVED; DC_SetDeviceInfo( hdc, dc ); SelectClipRgn( hdc, dcs->w.hClipRgn ); - SelectVisRgn( hdc, dcs->w.hGCClipRgn ); + SelectVisRgn( hdc, dcs->w.hVisRgn ); } @@ -337,6 +330,8 @@ HDC CreateDC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData ) 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 ); @@ -372,6 +367,8 @@ HDC CreateCompatibleDC( HDC hdc ) 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 ); diff --git a/windows/dce.c b/windows/dce.c index aaea4b012c1..7b24f1d4d94 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -22,6 +22,53 @@ static HANDLE firstDCE = 0; static HDC defaultDCstate = 0; +/*********************************************************************** + * DCE_AllocDCE + * + * Allocate a new DCE. + */ +HANDLE DCE_AllocDCE( DCE_TYPE type ) +{ + DCE * dce; + HANDLE handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) ); + if (!handle) return 0; + dce = (DCE *) USER_HEAP_ADDR( handle ); + if (!(dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ))) + { + USER_HEAP_FREE( handle ); + return 0; + } + dce->hwndCurrent = 0; + dce->type = type; + dce->inUse = (type != DCE_CACHE_DC); + dce->xOrigin = 0; + dce->yOrigin = 0; + dce->hNext = firstDCE; + firstDCE = handle; + return handle; +} + + +/*********************************************************************** + * DCE_FreeDCE + */ +void DCE_FreeDCE( HANDLE hdce ) +{ + DCE * dce; + HANDLE *handle = &firstDCE; + + if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return; + while (*handle && (*handle != hdce)) + { + DCE * prev = (DCE *) USER_HEAP_ADDR( *handle ); + handle = &prev->hNext; + } + if (*handle == hdce) *handle = dce->hNext; + DeleteDC( dce->hdc ); + USER_HEAP_FREE( hdce ); +} + + /*********************************************************************** * DCE_Init */ @@ -33,119 +80,158 @@ void DCE_Init() for (i = 0; i < NB_DCE; i++) { - handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) ); - if (!handle) return; - dce = (DCE *) USER_HEAP_ADDR( handle ); - dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL ); - if (!dce->hdc) - { - USER_HEAP_FREE( handle ); - return; - } - dce->hwndCurrent = 0; - dce->flags = 0; - dce->inUse = FALSE; - dce->xOrigin = 0; - dce->yOrigin = 0; - dce->hNext = firstDCE; - firstDCE = handle; + if (!(handle = DCE_AllocDCE( DCE_CACHE_DC ))) return; + dce = (DCE *) USER_HEAP_ADDR( handle ); if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc ); } } /*********************************************************************** - * GetDC (USER.66) + * GetDCEx (USER.359) */ -HDC GetDC( HWND hwnd ) +/* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP + */ +HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) { HANDLE hdce; HDC hdc = 0; DCE * dce; DC * dc; - WND * wndPtr = NULL; - CLASS * classPtr; + WND * wndPtr; if (hwnd) { if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0; - if (wndPtr->hdc) hdc = wndPtr->hdc; - else if (classPtr->hdc) hdc = classPtr->hdc; } - - if (!hdc) + else wndPtr = NULL; + + if (flags & DCX_USESTYLE) + { + /* Not sure if this is the real meaning of the DCX_USESTYLE flag... */ + flags &= ~(DCX_CACHE | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS); + if (wndPtr) + { + if (!(wndPtr->flags & (WIN_CLASS_DC | WIN_OWN_DC))) + flags |= DCX_CACHE; + if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN; + if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS; + } + else flags |= DCX_CACHE; + } + + if (flags & DCX_CACHE) { for (hdce = firstDCE; (hdce); hdce = dce->hNext) { - dce = (DCE *) USER_HEAP_ADDR( hdce ); - if (!dce) return 0; - if (!dce->inUse) break; + if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0; + if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break; } - if (!hdce) return 0; - dce->hwndCurrent = hwnd; - dce->inUse = TRUE; - hdc = dce->hdc; } + else hdce = wndPtr->hdce; + + if (!hdce) return 0; + dce = (DCE *) USER_HEAP_ADDR( hdce ); + dce->hwndCurrent = hwnd; + dce->inUse = TRUE; + hdc = dce->hdc; /* Initialize DC */ - if (!(dc = (DC *) GDI_GetObjPtr( dce->hdc, DC_MAGIC ))) return 0; + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; if (wndPtr) { - dc->u.x.drawable = XtWindow( wndPtr->winWidget ); - dc->u.x.widget = wndPtr->winWidget; - if (wndPtr->dwStyle & WS_CLIPCHILDREN) - XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren ); - else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors); + dc->u.x.drawable = wndPtr->window; + if (flags & DCX_WINDOW) + { + dc->w.DCOrgX = 0; + dc->w.DCOrgY = 0; + dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left; + dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; + } + else + { + dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left; + dc->w.DCOrgY = wndPtr->rectClient.top - wndPtr->rectWindow.top; + dc->w.DCSizeX = wndPtr->rectClient.right - wndPtr->rectClient.left; + dc->w.DCSizeY = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + IntersectVisRect( hdc, 0, 0, dc->w.DCSizeX, dc->w.DCSizeY ); + } } - else + else dc->u.x.drawable = DefaultRootWindow( XT_display ); + + if (flags & DCX_CLIPCHILDREN) + XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren ); + else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors); + + if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN)) { - dc->u.x.drawable = DefaultRootWindow( XT_display ); - dc->u.x.widget = 0; - XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors ); - } + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + if (hrgn) + { + if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip, + (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) + SelectVisRgn( hdc, hrgn ); + DeleteObject( hrgn ); + } + } -#ifdef DEBUG_WIN - printf( "GetDC(%d): returning %d\n", hwnd, hdc ); +#ifdef DEBUG_DC + printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd, hrgnClip, flags, hdc); #endif return hdc; } +/*********************************************************************** + * GetDC (USER.66) + */ +HDC GetDC( HWND hwnd ) +{ + return GetDCEx( hwnd, 0, DCX_USESTYLE ); +} + + +/*********************************************************************** + * GetWindowDC (USER.67) + */ +HDC GetWindowDC( HWND hwnd ) +{ + int flags = DCX_CACHE | DCX_WINDOW; + if (hwnd) + { + WND * wndPtr; + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; + if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN; + if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS; + } + return GetDCEx( hwnd, 0, flags ); +} + + /*********************************************************************** * ReleaseDC (USER.68) */ int ReleaseDC( HWND hwnd, HDC hdc ) { - HANDLE hdce, next; + HANDLE hdce; DCE * dce; - WND * wndPtr = NULL; - CLASS * classPtr; -#ifdef DEBUG_WIN +#ifdef DEBUG_DC printf( "ReleaseDC: %d %d\n", hwnd, hdc ); #endif - if (hwnd) - { - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (wndPtr->hdc && (wndPtr->hdc == hdc)) return 1; - if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0; - if (classPtr->hdc && (classPtr->hdc == hdc)) return 1; - } - for (hdce = firstDCE; (hdce); hdce = dce->hNext) { if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0; if (dce->inUse && (dce->hdc == hdc)) break; } - if (hdce) + if (dce->type == DCE_CACHE_DC) { SetDCState( dce->hdc, defaultDCstate ); dce->inUse = FALSE; - } + } return (hdce != 0); } diff --git a/windows/defwnd.c b/windows/defwnd.c index 3d3a280cdf5..e2f9a397885 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -6,24 +6,27 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#ifndef USE_XLIB #include <X11/Intrinsic.h> #include <X11/Shell.h> +#endif #include "windows.h" #include "win.h" #include "class.h" #include "user.h" +extern Display * XT_display; /*********************************************************************** * DefWindowProc (USER.107) */ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { - WND * wndPtr; 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 ); @@ -34,24 +37,57 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_NCCREATE: { CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam; - wndPtr = WIN_FindWndPtr(hwnd); if (createStruct->lpszName) { /* Allocate space for window text */ wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, - strlen(createStruct->lpszName) + 1); + strlen(createStruct->lpszName) + 2); textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); strcpy(textPtr, createStruct->lpszName); + *(textPtr + strlen(createStruct->lpszName) + 1) = '\0'; + /* for use by edit control */ } return 1; } + + case WM_NCCALCSIZE: + { +#ifdef USE_XLIB + NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; + if (wndPtr->dwStyle & WS_CHILD) + { + if (wndPtr->dwStyle & WS_BORDER) + { + params->rgrc[0].left += 1; /* SM_CXBORDER */ + params->rgrc[0].top += 1; /* SM_CYBORDER */ + params->rgrc[0].right -= 1; /* SM_CXBORDER */ + params->rgrc[0].bottom -= 1; /* SM_CYBORDER */ + } + } + else + { + params->rgrc[0].left += 4; /* SM_CXFRAME */ + params->rgrc[0].top += 30; /* SM_CYFRAME+SM_CYCAPTION */ + params->rgrc[0].right -= 4; /* SM_CXFRAME */ + params->rgrc[0].bottom -= 4; /* SM_CYFRAME */ + if (wndPtr->dwStyle & WS_VSCROLL) + { + params->rgrc[0].right -= 16; /* SM_CXVSCROLL */ + } + if (wndPtr->dwStyle & WS_HSCROLL) + { + params->rgrc[0].bottom += 16; /* SM_CYHSCROLL */ + } + } +#endif + return 0; + } case WM_CREATE: return 0; case WM_NCDESTROY: { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText); wndPtr->hText = 0; return 0; @@ -69,10 +105,23 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) DestroyWindow( hwnd ); return 0; + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS * winPos = (WINDOWPOS *)lParam; + if (!(winPos->flags & SWP_NOMOVE)) + SendMessage( hwnd, WM_MOVE, 0, + MAKELONG( wndPtr->rectClient.left, + wndPtr->rectClient.top )); + if (!(winPos->flags & SWP_NOSIZE)) + SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + return 0; + } + case WM_ERASEBKGND: case WM_ICONERASEBKGND: { - if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 1; if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 1; if (!classPtr->wc.hbrBackground) return 1; FillWindow( GetParent(hwnd), hwnd, (HDC)wParam, @@ -106,7 +155,6 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { if (wParam) { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) { textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); @@ -123,7 +171,6 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_GETTEXTLENGTH: { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) { textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); @@ -134,7 +181,6 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_SETTEXT: { - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr->hText) USER_HEAP_FREE(wndPtr->hText); @@ -142,10 +188,18 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) strlen((LPSTR)lParam) + 1); textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); strcpy(textPtr, (LPSTR)lParam); +#ifdef USE_XLIB + XStoreName( XT_display, wndPtr->window, textPtr ); +#else if (wndPtr->shellWidget) XtVaSetValues( wndPtr->shellWidget, XtNtitle, textPtr, NULL ); +#endif return (0L); } + case WM_SETCURSOR: + if (wndPtr->hCursor != (HCURSOR)NULL) + SetCursor(wndPtr->hCursor); + return 0L; } return 0; } diff --git a/windows/dialog.c b/windows/dialog.c index 108c964c5cb..83a03899566 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -8,7 +8,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "dialog.h" -#include "prototypes.h" #include "win.h" @@ -149,25 +148,19 @@ HWND CreateDialogParam( HINSTANCE hInst, LPCSTR dlgTemplate, HWND hwnd = 0; HANDLE hres, hmem; LPCSTR data; - int size; #ifdef DEBUG_DIALOG printf( "CreateDialogParam: %d,'%s',%d,%p,%d\n", hInst, dlgTemplate, owner, dlgProc, param ); #endif - -#if 0 - if (!(hres = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0; + + /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */ + if (!(hres = FindResource( hInst, dlgTemplate, MAKEINTRESOURCE(0x8005) ))) + return 0; if (!(hmem = LoadResource( hInst, hres ))) return 0; if (!(data = LockResource( hmem ))) hwnd = 0; else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param); FreeResource( hmem ); -#else - hmem = RSC_LoadResource( hInst, dlgTemplate, NE_RSCTYPE_DIALOG, &size ); - data = (LPCSTR) GlobalLock( hmem ); - hwnd = CreateDialogIndirectParam( hInst, data, owner, dlgProc, param ); - GlobalFree( hmem ); -#endif return hwnd; } @@ -314,8 +307,8 @@ HWND CreateDialogIndirectParam( HINSTANCE hInst, LPCSTR dlgTemplate, if (dlgInfo->hUserFont) SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0); SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ); - if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param )) - SetFocus( dlgInfo->hwndFocus ); +/* if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param )) + SetFocus( dlgInfo->hwndFocus ); */ return hwnd; } diff --git a/windows/event.c b/windows/event.c index 31301896e61..5f3aa3d9e97 100644 --- a/windows/event.c +++ b/windows/event.c @@ -18,6 +18,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */ +extern Display * XT_display; + /* Event handlers */ static void EVENT_expose(); static void EVENT_key(); @@ -25,17 +27,175 @@ static void EVENT_mouse_motion(); static void EVENT_mouse_button(); static void EVENT_structure(); static void EVENT_focus_change(); +static void EVENT_enter_notify(); + + /* X context to associate a hwnd to an X window */ +static XContext winContext = 0; /* State variables */ static HWND captureWnd = 0; - +Window winHasCursor = 0; extern HWND hWndFocus; +/* Keyboard translation tables */ +static int special_key[] = +{ + VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */ + 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */ + 0, 0, 0, VK_ESCAPE /* FF18 */ +}; + +static cursor_key[] = +{ + VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR, + VK_NEXT, VK_END /* FF50 */ +}; + +static misc_key[] = +{ + VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */ + VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */ +}; + +static keypad_key[] = +{ + VK_MENU, VK_NUMLOCK, /* FF7E */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */ + 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */ + 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, + VK_DECIMAL, VK_DIVIDE, /* FFA8 */ + VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, + VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */ + VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */ +}; + +static function_key[] = +{ + VK_F1, VK_F2, /* FFBE */ + VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */ + VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */ +}; + +static modifier_key[] = +{ + VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, + 0, 0, /* FFE1 */ + 0, VK_MENU, VK_MENU /* FFE8 */ +}; + +typedef union +{ + struct + { + unsigned long count : 16; + unsigned long code : 8; + unsigned long extended : 1; + unsigned long : 4; + unsigned long context : 1; + unsigned long previous : 1; + unsigned long transition : 1; + } lp1; + unsigned long lp2; +} KEYLP; + +static BOOL KeyDown = FALSE; + + +#ifdef DEBUG_EVENT +static char *event_names[] = +{ + "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", + "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", + "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify", + "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest", + "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", + "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", + "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify", + "ClientMessage", "MappingNotify" +}; +#endif + + +/*********************************************************************** + * EVENT_ProcessEvent + * + * Process an X event. + */ +void EVENT_ProcessEvent( XEvent *event ) +{ + HWND hwnd; + XPointer ptr; + Boolean cont_dispatch = TRUE; + + XFindContext( XT_display, ((XAnyEvent *)event)->window, winContext, &ptr ); + hwnd = (HWND)ptr & 0xffff; + +#ifdef DEBUG_EVENT + printf( "Got event %s for hwnd %d\n", + event_names[event->type], hwnd ); +#endif + + switch(event->type) + { + case Expose: + EVENT_expose( 0, hwnd, event, &cont_dispatch ); + break; + + case KeyPress: + case KeyRelease: + EVENT_key( 0, hwnd, event, &cont_dispatch ); + break; + + case MotionNotify: + EVENT_mouse_motion( 0, hwnd, event, &cont_dispatch ); + break; + + case ButtonPress: + case ButtonRelease: + EVENT_mouse_button( 0, hwnd, event, &cont_dispatch ); + break; + + case CirculateNotify: + case ConfigureNotify: + case MapNotify: + case UnmapNotify: + EVENT_structure( 0, hwnd, event, &cont_dispatch ); + break; + + case FocusIn: + case FocusOut: + EVENT_focus_change( 0, hwnd, event, &cont_dispatch ); + break; + + case EnterNotify: + EVENT_enter_notify( 0, hwnd, event, &cont_dispatch ); + break; + +#ifdef DEBUG_EVENT + default: + printf( "Unprocessed event %s for hwnd %d\n", + event_names[event->type], hwnd ); + break; +#endif + } +} + + /*********************************************************************** * EVENT_AddHandlers * * Add the event handlers to the given window */ +#ifdef USE_XLIB +void EVENT_AddHandlers( Window w, int hwnd ) +{ + if (!winContext) winContext = XUniqueContext(); + XSaveContext( XT_display, w, winContext, (XPointer)hwnd ); +} +#else void EVENT_AddHandlers( Widget w, int hwnd ) { XtAddEventHandler(w, ExposureMask, FALSE, @@ -50,7 +210,10 @@ void EVENT_AddHandlers( Widget w, int hwnd ) EVENT_structure, (XtPointer)hwnd ); XtAddEventHandler(w, FocusChangeMask, FALSE, EVENT_focus_change, (XtPointer)hwnd ); + XtAddEventHandler(w, EnterWindowMask, FALSE, + EVENT_enter_notify, (XtPointer)hwnd ); } +#endif /*********************************************************************** @@ -60,6 +223,7 @@ void EVENT_AddHandlers( Widget w, int hwnd ) */ void EVENT_RemoveHandlers( Widget w, int hwnd ) { +#ifndef USE_XLIB XtRemoveEventHandler(w, ExposureMask, FALSE, EVENT_expose, (XtPointer)hwnd ); XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, @@ -72,6 +236,9 @@ void EVENT_RemoveHandlers( Widget w, int hwnd ) EVENT_structure, (XtPointer)hwnd ); XtRemoveEventHandler(w, FocusChangeMask, FALSE, EVENT_focus_change, (XtPointer)hwnd ); + XtRemoveEventHandler(w, EnterWindowMask, FALSE, + EVENT_enter_notify, (XtPointer)hwnd ); +#endif } @@ -103,10 +270,14 @@ static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event, Boolean *cont_dispatch ) { RECT rect; - rect.left = event->x; - rect.top = event->y; - rect.right = event->x + event->width; - rect.bottom = event->y + event->height; + 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); + rect.right = rect.left + event->width; + rect.bottom = rect.top + event->height; + winHasCursor = event->window; InvalidateRect( hwnd, &rect, TRUE ); } @@ -121,24 +292,128 @@ static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, Boolean *cont_dispatch ) { MSG msg; - char Str[24]; XComposeStatus cs; - KeySym key; - int count = XLookupString(event, Str, 1, &key, &cs); + KeySym keysym; + 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 - printf("WM_KEY??? : count=%u / %X / '%s'\n",count, Str[0], Str); -#endif - msg.hwnd = hwnd; - msg.message = (event->type == KeyRelease) ? WM_KEYUP : WM_KEYDOWN; - msg.wParam = Str[0]; - msg.lParam = (event->x & 0xffff) | (event->y << 16); - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; + printf("WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n", + keysym, count, Str[0], Str); +#endif + + xkey = LOWORD(keysym); + key_type = HIBYTE(xkey); + key = LOBYTE(xkey); +#ifdef DEBUG_KEY + 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 */ + vkey = special_key[key - 0x08]; + else if (key >= 0x50 && key <= 0x57) /* cursor key */ + vkey = cursor_key[key - 0x50]; + else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */ + vkey = misc_key[key - 0x60]; + else if (key >= 0x7E && key <= 0xB9) /* keypad key */ + { + vkey = keypad_key[key - 0x7E]; + extended = TRUE; + } + else if (key >= 0xBE && key <= 0xCD) /* function key */ + { + vkey = function_key[key - 0xBE]; + extended = TRUE; + } + else if (key >= 0xE1 && key <= 0xEA) /* modifier key */ + vkey = modifier_key[key - 0xE1]; + else if (key == 0xFF) /* DEL key */ + vkey = VK_DELETE; + } + else if (key_type == 0) /* character key */ + { + if (key >= 0x61 && key <= 0x7A) + vkey = key - 0x20; /* convert lower to uppercase */ + else + vkey = key; + } + + if (event->type == KeyPress) + { + msg.hwnd = hwnd; + msg.message = WM_KEYDOWN; + msg.wParam = vkey; + keylp.lp1.count = 1; + keylp.lp1.code = LOBYTE(event->keycode); + keylp.lp1.extended = (extended ? 1 : 0); + keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); + keylp.lp1.previous = (KeyDown ? 0 : 1); + keylp.lp1.transition = 0; + msg.lParam = keylp.lp2; +#ifdef DEBUG_KEY + printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); +#endif + msg.time = event->time; + msg.pt.x = event->x & 0xffff; + msg.pt.y = event->y & 0xffff; - MSG_AddMsg( &msg ); + hardware_event( hwnd, WM_KEYDOWN, vkey, keylp.lp2, + event->x & 0xffff, event->y & 0xffff, event->time, 0 ); + KeyDown = TRUE; + + /* The key translation ought to take place in TranslateMessage(). + * However, there is no way of passing the required information + * in a Windows message, so TranslateMessage does not currently + * do anything and the translation is done here. + */ + if (count == 1) /* key has an ASCII representation */ + { + msg.hwnd = hwnd; + msg.message = WM_CHAR; + msg.wParam = (WORD)Str[0]; + msg.lParam = keylp.lp2; +#ifdef DEBUG_KEY + printf("WM_CHAR : wParam=%X\n", msg.wParam); +#endif + msg.time = event->time; + msg.pt.x = event->x & 0xffff; + msg.pt.y = event->y & 0xffff; + PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 ); + } + } + else + { + msg.hwnd = hwnd; + msg.message = WM_KEYUP; + msg.wParam = vkey; + keylp.lp1.count = 1; + keylp.lp1.code = LOBYTE(event->keycode); + keylp.lp1.extended = (extended ? 1 : 0); + keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); + keylp.lp1.previous = 1; + keylp.lp1.transition = 1; + msg.lParam = keylp.lp2; +#ifdef DEBUG_KEY + printf(" wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam); +#endif + msg.time = event->time; + msg.pt.x = event->x & 0xffff; + msg.pt.y = event->y & 0xffff; + + hardware_event( hwnd, WM_KEYUP, vkey, keylp.lp2, + event->x & 0xffff, event->y & 0xffff, event->time, 0 ); + KeyDown = FALSE; + } } @@ -150,17 +425,17 @@ static void EVENT_key( Widget w, int hwnd, XKeyEvent *event, static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event, Boolean *cont_dispatch ) { - MSG msg; - - msg.hwnd = hwnd; - msg.message = WM_MOUSEMOVE; - msg.wParam = EVENT_XStateToKeyState( event->state ); - msg.lParam = (event->x & 0xffff) | (event->y << 16); - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; - - MSG_AddMsg( &msg ); + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + + /* Position must be relative to client area */ + event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; + event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; + + hardware_event( hwnd, WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ), + (event->x & 0xffff) | (event->y << 16), + event->x & 0xffff, event->y & 0xffff, + event->time, 0 ); } @@ -180,9 +455,15 @@ static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, }; static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 }; - MSG msg; int buttonNum, prevTime, type; - + + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + + /* Position must be relative to client area */ + event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left; + event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top; + buttonNum = event->button-1; if (buttonNum >= NB_BUTTONS) return; if (event->type == ButtonRelease) type = 1; @@ -201,15 +482,13 @@ static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, else type = 0; } - msg.hwnd = hwnd; - msg.message = messages[type][buttonNum]; - msg.wParam = EVENT_XStateToKeyState( event->state ); - msg.lParam = (event->x & 0xffff) | (event->y << 16); - msg.time = event->time; - msg.pt.x = event->x & 0xffff; - msg.pt.y = event->y & 0xffff; - - MSG_AddMsg( &msg ); + winHasCursor = event->window; + + hardware_event( hwnd, messages[type][buttonNum], + EVENT_XStateToKeyState( event->state ), + (event->x & 0xffff) | (event->y << 16), + event->x & 0xffff, event->y & 0xffff, + event->time, 0 ); } @@ -232,13 +511,31 @@ static void EVENT_structure( Widget w, int hwnd, XEvent *event, { case ConfigureNotify: { + HANDLE handle; + NCCALCSIZE_PARAMS *params; XConfigureEvent * evt = (XConfigureEvent *)event; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return; - wndPtr->rectClient.right = wndPtr->rectClient.left + evt->width; - wndPtr->rectClient.bottom = wndPtr->rectClient.top + evt->height; + wndPtr->rectWindow.left = evt->x; + wndPtr->rectWindow.top = evt->y; + wndPtr->rectWindow.right = evt->x + evt->width; + wndPtr->rectWindow.bottom = evt->y + evt->height; + + /* Send WM_NCCALCSIZE message */ + handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); + params = (NCCALCSIZE_PARAMS *)GlobalLock( handle ); + params->rgrc[0] = wndPtr->rectWindow; + params->lppos = NULL; /* Should be WINDOWPOS struct */ + SendMessage( hwnd, WM_NCCALCSIZE, FALSE, params ); + wndPtr->rectClient = params->rgrc[0]; + PostMessage( hwnd, WM_MOVE, 0, + MAKELONG( wndPtr->rectClient.left, + wndPtr->rectClient.top )); PostMessage( hwnd, WM_SIZE, SIZE_RESTORED, - (evt->width & 0xffff) | (evt->height << 16) ); + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + GlobalUnlock( handle ); + GlobalFree( handle ); } break; @@ -254,21 +551,12 @@ static void EVENT_structure( Widget w, int hwnd, XEvent *event, static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, Boolean *cont_dispatch ) { - MSG msg; - - msg.hwnd = hwnd; - msg.time = GetTickCount(); - msg.pt.x = 0; - msg.pt.y = 0; - switch(event->type) { case FocusIn: { - msg.message = WM_SETFOCUS; - msg.wParam = hwnd; + PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 ); hWndFocus = hwnd; - } break; @@ -276,13 +564,32 @@ static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, { if (hWndFocus) { - msg.message = WM_KILLFOCUS; - msg.wParam = hwnd; + PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 ); hWndFocus = 0; } } } - MSG_AddMsg( &msg ); +} + + +/********************************************************************** + * EVENT_enter_notify + * + * Handle an X EnterNotify event + */ +static void EVENT_enter_notify( Widget w, int hwnd, XCrossingEvent *event, + Boolean *cont_dispatch ) +{ + if (captureWnd != 0) return; + + winHasCursor = event->window; + + switch(event->type) + { + case EnterNotify: + PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 ); + break; + } } @@ -297,9 +604,15 @@ HWND SetCapture(HWND wnd) if (wnd_p == NULL) return 0; +#ifdef USE_XLIB + rv = XGrabPointer(XT_display, wnd_p->window, False, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeSync, None, None, CurrentTime); +#else rv = XtGrabPointer(wnd_p->winWidget, False, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeSync, None, None, CurrentTime); +#endif if (rv == GrabSuccess) { @@ -324,11 +637,23 @@ void ReleaseCapture() if (wnd_p == NULL) return; +#ifdef USE_XLIB + XUngrabPointer( XT_display, CurrentTime ); +#else XtUngrabPointer(wnd_p->winWidget, CurrentTime); +#endif captureWnd = 0; } +/********************************************************************** + * GetCapture (USER.236) + */ +HWND GetCapture() +{ + return captureWnd; +} + /********************************************************************** * SetDoubleClickTime (USER.20) */ diff --git a/windows/focus.c b/windows/focus.c index ce1a91a25ff..639b2dfd85a 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -32,7 +32,7 @@ HWND SetFocus(HWND hwnd) else { wndPtr = WIN_FindWndPtr(hwnd); - XSetInputFocus(XT_display, XtWindow(wndPtr->winWidget), + XSetInputFocus(XT_display, wndPtr->window, RevertToParent, CurrentTime); } diff --git a/windows/graphics.c b/windows/graphics.c index a2a1e3254d6..9fd5d27a55f 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -23,8 +23,10 @@ BOOL LineTo( HDC hdc, short x, short y ) if (!dc) return FALSE; if (DC_SetupGCForPen( dc )) XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc, - XLPTODP( dc, dc->w.CursPosX ), YLPTODP( dc, dc->w.CursPosY ), - XLPTODP( dc, x ), YLPTODP( dc, y ) ); + dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ), + dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ), + dc->w.DCOrgX + XLPTODP( dc, x ), + dc->w.DCOrgY + YLPTODP( dc, y ) ); dc->w.CursPosX = x; dc->w.CursPosY = y; return TRUE; @@ -97,20 +99,21 @@ BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom, if (diff_angle < 0.0) diff_angle += 2*PI; XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1, + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1, (int)(start_angle * 180 * 64 / PI), (int)(diff_angle * 180 * 64 / PI) ); if (!lines) return TRUE; - points[0].x = xcenter + (int)(cos(start_angle) * (right-left) / 2); - points[0].y = ycenter - (int)(sin(start_angle) * (bottom-top) / 2); - points[1].x = xcenter + (int)(cos(end_angle) * (right-left) / 2); - points[1].y = ycenter - (int)(sin(end_angle) * (bottom-top) / 2); + points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2); + points[0].y = dc->w.DCOrgY + ycenter - (int)(sin(start_angle) * (bottom-top) / 2); + points[1].x = dc->w.DCOrgX + xcenter + (int)(cos(end_angle) * (right-left) / 2); + points[1].y = dc->w.DCOrgY + ycenter - (int)(sin(end_angle) * (bottom-top) / 2); if (lines == 2) { points[2] = points[1]; - points[1].x = xcenter; - points[1].y = ycenter; + points[1].x = dc->w.DCOrgX + xcenter; + points[1].y = dc->w.DCOrgY + ycenter; } XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc, points, lines+1, CoordModeOrigin ); @@ -167,10 +170,12 @@ BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom ) if (DC_SetupGCForBrush( dc )) XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1, 0, 360*64 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1, 0, 360*64 ); if (DC_SetupGCForPen( dc )) XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1, 0, 360*64 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1, 0, 360*64 ); return TRUE; } @@ -190,10 +195,12 @@ BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) if (DC_SetupGCForBrush( dc )) XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1 ); if (DC_SetupGCForPen( dc )) XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1 ); return TRUE; } @@ -244,10 +251,16 @@ int FrameRect( HDC hdc, LPRECT rect, HBRUSH hbrush ) right = XLPTODP( dc, rect->right ); bottom = YLPTODP( dc, rect->bottom ); - if (DC_SetupGCForBrush( dc )) - XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); - + if (DC_SetupGCForBrush( dc )) { + PatBlt( hdc, rect->left, rect->top, 1, + rect->bottom - rect->top, PATCOPY ); + PatBlt( hdc, rect->right - 1, rect->top, 1, + rect->bottom - rect->top, PATCOPY ); + PatBlt( hdc, rect->left, rect->top, + rect->right - rect->left, 1, PATCOPY ); + PatBlt( hdc, rect->left, rect->bottom - 1, + rect->right - rect->left, 1, PATCOPY ); + } SelectObject( hdc, prevBrush ); return 1; } @@ -264,8 +277,8 @@ COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color ) DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; - x = XLPTODP( dc, x ); - y = YLPTODP( dc, y ); + x = dc->w.DCOrgX + XLPTODP( dc, x ); + y = dc->w.DCOrgY + YLPTODP( dc, y ); pixel = GetNearestPaletteIndex( dc->w.hPalette, color ); GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry ); @@ -288,15 +301,14 @@ COLORREF GetPixel( HDC hdc, short x, short y ) DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) return 0; - x = XLPTODP( dc, x ); - y = YLPTODP( dc, y ); + x = dc->w.DCOrgX + XLPTODP( dc, x ); + y = dc->w.DCOrgY + YLPTODP( dc, y ); if ((x < 0) || (y < 0)) return 0; - if (dc->u.x.widget) + if (!(dc->w.flags & DC_MEMORY)) { XWindowAttributes win_attr; - if (!XtIsRealized(dc->u.x.widget)) return 0; if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr )) return 0; if (win_attr.map_state != IsViewable) return 0; @@ -342,7 +354,7 @@ BOOL PaintRgn( HDC hdc, HRGN hrgn ) GetClipBox( hdc, &box ); if (DC_SetupGCForBrush( dc )) XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - box.left, box.top, + dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top, box.right-box.left, box.bottom-box.top ); /* Restore the visible region */ @@ -385,15 +397,16 @@ void DrawFocusRect( HDC hdc, LPRECT rc ) hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT)); hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen); -/* oldDrawMode = SetROP2(hdc, R2_XORPEN); */ + oldDrawMode = SetROP2(hdc, R2_XORPEN); oldBkMode = SetBkMode(hdc, TRANSPARENT); if (DC_SetupGCForPen( dc )) XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc, - left, top, right-left-1, bottom-top-1 ); + dc->w.DCOrgX + left, dc->w.DCOrgY + top, + right-left-1, bottom-top-1 ); SetBkMode(hdc, oldBkMode); -/* SetROP2(hdc, oldDrawMode); */ + SetROP2(hdc, oldDrawMode); SelectObject(hdc, (HANDLE)hOldPen); DeleteObject((HANDLE)hPen); } @@ -441,3 +454,64 @@ while(ThickNess > 0) { SelectObject(hDC, hOldPen); DeleteObject(hDKGRAYPen); } + +/********************************************************************** + * Polyline (GDI.37) + */ +BOOL Polyline (HDC hdc, LPPOINT pt, int count) +{ + register int i; + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + + if (DC_SetupGCForPen( dc )) + { + for (i = 0; i < count-1; i ++) + XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc, + dc->w.DCOrgX + XLPTODP(dc, pt [i].x), + dc->w.DCOrgY + YLPTODP(dc, pt [i].y), + dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x), + dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y)); + XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc, + dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x), + dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y), + dc->w.DCOrgX + XLPTODP(dc, pt [0].x), + dc->w.DCOrgY + YLPTODP(dc, pt [0].y)); + } + + return (TRUE); +} + + +/********************************************************************** + * Polygon (GDI.36) + */ +BOOL Polygon (HDC hdc, LPPOINT pt, int count) +{ + register int i; + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1); + + if (DC_SetupGCForBrush( dc )) + { + + for (i = 0; i < count; i++) + { + points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x); + points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y); + } + points [count] = points [0]; + + XFillPolygon( XT_display, dc->u.x.drawable, dc->u.x.gc, + points, count, Complex, CoordModeOrigin); + + if (DC_SetupGCForPen ( dc )) + { + XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc, + points, count, CoordModeOrigin ); + } + } + free ((void *) points); + return (TRUE); +} + + diff --git a/windows/message.c b/windows/message.c index 7307461d99d..09b49e7861c 100644 --- a/windows/message.c +++ b/windows/message.c @@ -12,10 +12,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include <stdlib.h> - -#ifdef __NetBSD__ -#define HZ 100 -#endif +#include <sys/time.h> +#include <sys/types.h> #include "message.h" #include "win.h" @@ -23,30 +21,72 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ -extern HWND WIN_FindWinToRepaint( HWND hwnd ); +extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */ extern Display * XT_display; extern Screen * XT_screen; extern XtAppContext XT_app_context; -static MESSAGEQUEUE * msgQueue = NULL; + /* System message queue (for hardware events) */ +static HANDLE hmemSysMsgQueue = 0; +static MESSAGEQUEUE * sysMsgQueue = NULL; + /* Application message queue (should be a list, one queue per task) */ +static HANDLE hmemAppMsgQueue = 0; +static MESSAGEQUEUE * appMsgQueue = NULL; /*********************************************************************** - * MSG_GetMessageType + * MSG_CreateMsgQueue * + * Create a message queue. */ -int MSG_GetMessageType( int msg ) +static HANDLE MSG_CreateMsgQueue( int size ) { - if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST)) return QS_KEY; - else if ((msg >= WM_MOUSEFIRST) && (msg <= WM_MOUSELAST)) - { - if (msg == WM_MOUSEMOVE) return QS_MOUSEMOVE; - else return QS_MOUSEBUTTON; - } - else if (msg == WM_PAINT) return QS_PAINT; - else if (msg == WM_TIMER) return QS_TIMER; - return QS_POSTMESSAGE; + HANDLE hQueue; + MESSAGEQUEUE * msgQueue; + int queueSize; + + queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG); + if (!(hQueue = GlobalAlloc( GMEM_FIXED, queueSize ))) return 0; + msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue ); + msgQueue->next = 0; + msgQueue->hTask = 0; + msgQueue->msgSize = sizeof(QMSG); + msgQueue->msgCount = 0; + msgQueue->nextMessage = 0; + msgQueue->nextFreeMessage = 0; + msgQueue->queueSize = size; + msgQueue->GetMessageTimeVal = 0; + msgQueue->GetMessagePosVal = 0; + msgQueue->GetMessageExtraInfoVal = 0; + msgQueue->lParam = 0; + msgQueue->wParam = 0; + msgQueue->msg = 0; + msgQueue->hWnd = 0; + msgQueue->wPostQMsg = 0; + msgQueue->wExitCode = 0; + msgQueue->InSendMessageHandle = 0; + msgQueue->wPaintCount = 0; + msgQueue->wTimerCount = 0; + msgQueue->tempStatus = 0; + msgQueue->status = 0; + GlobalUnlock( hQueue ); + return hQueue; +} + + +/*********************************************************************** + * MSG_CreateSysMsgQueue + * + * Create the system message queue. Must be called only once. + */ +BOOL MSG_CreateSysMsgQueue( int size ) +{ + if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE; + else if (size <= 0) size = 1; + if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE; + sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue ); + return TRUE; } @@ -55,16 +95,13 @@ int MSG_GetMessageType( int msg ) * * Add a message to the queue. Return FALSE if queue is full. */ -int MSG_AddMsg( MSG * msg, DWORD extraInfo ) +static int MSG_AddMsg( MESSAGEQUEUE * msgQueue, MSG * msg, DWORD extraInfo ) { - int pos, type; + int pos; if (!msgQueue) return FALSE; pos = msgQueue->nextFreeMessage; - /* No need to store WM_PAINT messages */ - if (msg->message == WM_PAINT) return TRUE; - /* Check if queue is full */ if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0)) return FALSE; @@ -72,17 +109,12 @@ int MSG_AddMsg( MSG * msg, DWORD extraInfo ) /* Store message */ msgQueue->messages[pos].msg = *msg; msgQueue->messages[pos].extraInfo = extraInfo; - - /* Store message type */ - type = MSG_GetMessageType( msg->message ); - msgQueue->status |= type; - msgQueue->tempStatus |= type; - if (pos < msgQueue->queueSize-1) pos++; else pos = 0; msgQueue->nextFreeMessage = pos; msgQueue->msgCount++; - + msgQueue->status |= QS_POSTMESSAGE; + msgQueue->tempStatus |= QS_POSTMESSAGE; return TRUE; } @@ -92,7 +124,7 @@ int MSG_AddMsg( MSG * msg, DWORD extraInfo ) * * Find a message matching the given parameters. Return -1 if none available. */ -int MSG_FindMsg( HWND hwnd, int first, int last ) +static int MSG_FindMsg(MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last) { int i, pos = msgQueue->nextMessage; @@ -120,9 +152,8 @@ int MSG_FindMsg( HWND hwnd, int first, int last ) * * Remove a message from the queue (pos must be a valid position). */ -void MSG_RemoveMsg( int pos ) +static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) { - int i, type; QMSG * qmsg; if (!msgQueue) return; @@ -147,56 +178,118 @@ void MSG_RemoveMsg( int pos ) else msgQueue->nextFreeMessage = msgQueue->queueSize-1; } msgQueue->msgCount--; - - /* Recalc status */ - type = 0; - pos = msgQueue->nextMessage; - for (i = 0; i < msgQueue->msgCount; i++) - { - type |= MSG_GetMessageType( msgQueue->messages[pos].msg.message ); - if (++pos >= msgQueue->queueSize-1) pos = 0; - } - msgQueue->status = (msgQueue->status & QS_SENDMESSAGE) | type; + if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE; msgQueue->tempStatus = 0; } +/*********************************************************************** + * MSG_IncPaintCount + */ +void MSG_IncPaintCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wPaintCount++; + appMsgQueue->status |= QS_PAINT; + appMsgQueue->tempStatus |= QS_PAINT; +} + + +/*********************************************************************** + * MSG_DecPaintCount + */ +void MSG_DecPaintCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wPaintCount--; + if (!appMsgQueue->wPaintCount) appMsgQueue->status &= ~QS_PAINT; +} + + +/*********************************************************************** + * MSG_IncTimerCount + */ +void MSG_IncTimerCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wTimerCount++; + appMsgQueue->status |= QS_TIMER; + appMsgQueue->tempStatus |= QS_TIMER; +} + + +/*********************************************************************** + * MSG_DecTimerCount + */ +void MSG_DecTimerCount( HANDLE hQueue ) +{ + if (hQueue != hmemAppMsgQueue) return; + appMsgQueue->wTimerCount--; + if (!appMsgQueue->wTimerCount) appMsgQueue->status &= ~QS_TIMER; +} + + +/*********************************************************************** + * hardware_event + * + * Add an event to the system message queue. + */ +void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam, + WORD xPos, WORD yPos, DWORD time, DWORD extraInfo ) +{ + MSG msg; + + msg.hwnd = hwnd; + msg.message = message; + msg.wParam = wParam; + msg.lParam = lParam; + msg.time = time; + msg.pt.x = xPos; + msg.pt.y = yPos; + if (!MSG_AddMsg( sysMsgQueue, &msg, extraInfo )) + printf( "hardware_event: Queue is full\n" ); +} + + +/*********************************************************************** + * SetTaskQueue (KERNEL.34) + */ +WORD SetTaskQueue( HANDLE hTask, HANDLE hQueue ) +{ + HANDLE prev = hmemAppMsgQueue; + hmemAppMsgQueue = hQueue; + return prev; +} + + +/*********************************************************************** + * GetTaskQueue (KERNEL.35) + */ +WORD GetTaskQueue( HANDLE hTask ) +{ + return hmemAppMsgQueue; +} + + /*********************************************************************** * SetMessageQueue (USER.266) */ BOOL SetMessageQueue( int size ) { - int queueSize; - - /* Free the old message queue */ - if (msgQueue) free(msgQueue); - - if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return FALSE; - - queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG); - msgQueue = (MESSAGEQUEUE *) malloc(queueSize); - if (!msgQueue) return FALSE; + HANDLE hQueue; - msgQueue->next = 0; - msgQueue->hTask = 0; - msgQueue->msgSize = sizeof(QMSG); - msgQueue->msgCount = 0; - msgQueue->nextMessage = 0; - msgQueue->nextFreeMessage = 0; - msgQueue->queueSize = size; - msgQueue->GetMessageTimeVal = 0; - msgQueue->GetMessagePosVal = 0; - msgQueue->GetMessageExtraInfoVal = 0; - msgQueue->lParam = 0; - msgQueue->wParam = 0; - msgQueue->msg = 0; - msgQueue->hWnd = 0; - msgQueue->wPostQMsg = 0; - msgQueue->wExitCode = 0; - msgQueue->InSendMessageHandle = 0; - msgQueue->tempStatus = 0; - msgQueue->status = 0; + if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE; + /* Free the old message queue */ + if ((hQueue = GetTaskQueue(0)) != 0) + { + GlobalUnlock( hQueue ); + GlobalFree( hQueue ); + } + + if (!(hQueue = MSG_CreateMsgQueue( size ))) return FALSE; + SetTaskQueue( 0, hQueue ); + appMsgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ); return TRUE; } @@ -206,9 +299,9 @@ BOOL SetMessageQueue( int size ) */ void PostQuitMessage( int exitCode ) { - if (!msgQueue) return; - msgQueue->wPostQMsg = TRUE; - msgQueue->wExitCode = exitCode; + if (!appMsgQueue) return; + appMsgQueue->wPostQMsg = TRUE; + appMsgQueue->wExitCode = exitCode; } @@ -217,12 +310,8 @@ void PostQuitMessage( int exitCode ) */ DWORD GetQueueStatus( int flags ) { - unsigned long ret = (msgQueue->status << 16) | msgQueue->tempStatus; - if (flags & QS_PAINT) - { - if (WIN_FindWinToRepaint(0)) ret |= QS_PAINT | (QS_PAINT << 16); - } - msgQueue->tempStatus = 0; + unsigned long ret = (appMsgQueue->status << 16) | appMsgQueue->tempStatus; + appMsgQueue->tempStatus = 0; return ret & ((flags << 16) | flags); } @@ -232,70 +321,169 @@ DWORD GetQueueStatus( int flags ) */ BOOL GetInputState() { - return msgQueue->status & (QS_KEY | QS_MOUSEBUTTON); + return appMsgQueue->status & (QS_KEY | QS_MOUSEBUTTON); } +#ifndef USE_XLIB +static XtIntervalId xt_timer = 0; + +/*********************************************************************** + * MSG_TimerCallback + */ +static void MSG_TimerCallback( XtPointer data, XtIntervalId * xtid ) +{ + DWORD nextExp; + TIMER_CheckTimer( &nextExp ); + if (nextExp != (DWORD)-1) + xt_timer = XtAppAddTimeOut( XT_app_context, nextExp, + MSG_TimerCallback, NULL ); + else xt_timer = 0; +} +#endif /* USE_XLIB */ + + /*********************************************************************** * MSG_PeekMessage */ -BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) +static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, + WORD first, WORD last, WORD flags, BOOL peek ) { - int pos; + int pos, mask; + DWORD nextExp; /* Next timer expiration time */ +#ifdef USE_XLIB + XEvent event; +#endif - /* First handle a WM_QUIT message */ - if (msgQueue->wPostQMsg) + if (first || last) { - msg->hwnd = hwnd; - msg->message = WM_QUIT; - msg->wParam = msgQueue->wExitCode; - msg->lParam = 0; - return TRUE; + mask = QS_POSTMESSAGE; /* Always selectioned */ + if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY; + if ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) mask |= QS_MOUSE; + if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= WM_TIMER; + if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= WM_TIMER; + if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= WM_PAINT; } + else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT; - /* Then handle a message put by SendMessage() */ - if (msgQueue->status & QS_SENDMESSAGE) +#ifdef USE_XLIB + while (XPending( XT_display )) { - if (!hwnd || (msgQueue->hWnd == hwnd)) + XNextEvent( XT_display, &event ); + EVENT_ProcessEvent( &event ); + } +#else + while (XtAppPending( XT_app_context )) + XtAppProcessEvent( XT_app_context, XtIMAll ); +#endif + + while(1) + { + /* First handle a WM_QUIT message */ + if (msgQueue->wPostQMsg) + { + msg->hwnd = hwnd; + msg->message = WM_QUIT; + msg->wParam = msgQueue->wExitCode; + msg->lParam = 0; + break; + } + + /* Then handle a message put by SendMessage() */ + if (msgQueue->status & QS_SENDMESSAGE) { - if ((!first && !last) || - ((msgQueue->msg >= first) && (msgQueue->msg <= last))) + if (!hwnd || (msgQueue->hWnd == hwnd)) { - msg->hwnd = msgQueue->hWnd; - msg->message = msgQueue->msg; - msg->wParam = msgQueue->wParam; - msg->lParam = msgQueue->lParam; - if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE; - return TRUE; + if ((!first && !last) || + ((msgQueue->msg >= first) && (msgQueue->msg <= last))) + { + msg->hwnd = msgQueue->hWnd; + msg->message = msgQueue->msg; + msg->wParam = msgQueue->wParam; + msg->lParam = msgQueue->lParam; + if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE; + break; + } } } - - } - /* Now find a normal message */ - pos = MSG_FindMsg( hwnd, first, last ); - if (pos != -1) - { - QMSG *qmsg = &msgQueue->messages[pos]; - *msg = qmsg->msg; - msgQueue->GetMessageTimeVal = msg->time; - msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; - msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; - - if (flags & PM_REMOVE) MSG_RemoveMsg(pos); - return TRUE; + /* Now find a normal message */ + pos = MSG_FindMsg( msgQueue, hwnd, first, last ); + if (pos != -1) + { + QMSG *qmsg = &msgQueue->messages[pos]; + *msg = qmsg->msg; + msgQueue->GetMessageTimeVal = msg->time; + msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; + msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; + + if (flags & PM_REMOVE) MSG_RemoveMsg( msgQueue, pos ); + break; + } + + /* Now find a hardware event */ + pos = MSG_FindMsg( sysMsgQueue, hwnd, first, last ); + if (pos != -1) + { + QMSG *qmsg = &sysMsgQueue->messages[pos]; + *msg = qmsg->msg; + msgQueue->GetMessageTimeVal = msg->time; + msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; + msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; + + if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos ); + break; + } + + /* Now find a WM_PAINT message */ + if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT)) + { + msg->hwnd = WIN_FindWinToRepaint( hwnd ); + msg->message = WM_PAINT; + msg->wParam = 0; + msg->lParam = 0; + if (msg->hwnd != 0) break; + } + + /* Finally handle WM_TIMER messages */ + if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER)) + { + BOOL posted = TIMER_CheckTimer( &nextExp ); +#ifndef USE_XLIB + if (xt_timer) XtRemoveTimeOut( xt_timer ); + if (nextExp != (DWORD)-1) + xt_timer = XtAppAddTimeOut( XT_app_context, nextExp, + MSG_TimerCallback, NULL ); + else xt_timer = 0; +#endif + if (posted) continue; /* Restart the whole thing */ + } + + /* Wait until something happens */ + if (peek) return FALSE; +#ifdef USE_XLIB + if (!XPending( XT_display ) && (nextExp != -1)) + { + fd_set read_set; + struct timeval timeout; + int fd = ConnectionNumber(XT_display); + FD_ZERO( &read_set ); + FD_SET( fd, &read_set ); + timeout.tv_sec = nextExp / 1000; + timeout.tv_usec = (nextExp % 1000) * 1000; + if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1) + continue; /* On timeout or error, restart from the start */ + } + XNextEvent( XT_display, &event ); + EVENT_ProcessEvent( &event ); +#else + XtAppProcessEvent( XT_app_context, XtIMAll ); +#endif } - /* If nothing else, return a WM_PAINT message */ - if ((!first && !last) || ((first <= WM_PAINT) && (last >= WM_PAINT))) - { - msg->hwnd = WIN_FindWinToRepaint( hwnd ); - msg->message = WM_PAINT; - msg->wParam = 0; - msg->lParam = 0; - return (msg->hwnd != 0); - } - return FALSE; + /* We got a message */ + if (peek) return TRUE; + else return (msg->message != WM_QUIT); } @@ -304,10 +492,7 @@ BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) */ BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) { - while (XtAppPending( XT_app_context )) - XtAppProcessEvent( XT_app_context, XtIMAll ); - - return MSG_PeekMessage( msg, hwnd, first, last, flags ); + return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, flags, TRUE ); } @@ -316,13 +501,7 @@ BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags ) */ BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) { - while(1) - { - if (MSG_PeekMessage( msg, hwnd, first, last, PM_REMOVE )) break; - XtAppProcessEvent( XT_app_context, XtIMAll ); - } - - return (msg->message != WM_QUIT); + return MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, PM_REMOVE, FALSE ); } @@ -341,7 +520,7 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) msg.pt.x = 0; msg.pt.y = 0; - return MSG_AddMsg( &msg, 0 ); + return MSG_AddMsg( appMsgQueue, &msg, 0 ); } @@ -380,16 +559,39 @@ BOOL TranslateMessage( LPMSG msg ) */ LONG DispatchMessage( LPMSG msg ) { - WND * wndPtr = WIN_FindWndPtr( msg->hwnd ); - + WND * wndPtr; + LONG retval; + int painting; + #ifdef DEBUG_MSG printf( "Dispatch message hwnd=%08x msg=%d w=%d l=%d time=%u pt=%d,%d\n", msg->hwnd, msg->message, msg->wParam, msg->lParam, msg->time, msg->pt.x, msg->pt.y ); #endif - if (!wndPtr) return 0; - return CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message, - msg->wParam, msg->lParam ); + + /* Process timer messages */ + if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER)) + { + if (msg->lParam) + return CallWindowProc( (FARPROC)msg->lParam, msg->hwnd, + msg->message, msg->wParam, GetTickCount() ); + } + + if (!msg->hwnd) return 0; + if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0; + if (!wndPtr->lpfnWndProc) return 0; + painting = (msg->message == WM_PAINT); + if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT; + retval = CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message, + msg->wParam, msg->lParam ); + if (painting && (wndPtr->flags & WIN_NEEDS_BEGINPAINT)) + { +#ifdef DEBUG_WIN + printf( "BeginPaint not called on WM_PAINT!\n" ); +#endif + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + } + return retval; } @@ -398,7 +600,7 @@ LONG DispatchMessage( LPMSG msg ) */ DWORD GetMessagePos(void) { - return msgQueue->GetMessagePosVal; + return appMsgQueue->GetMessagePosVal; } @@ -407,14 +609,27 @@ DWORD GetMessagePos(void) */ LONG GetMessageTime(void) { - return msgQueue->GetMessageTimeVal; + return appMsgQueue->GetMessageTimeVal; } + /*********************************************************************** * GetMessageExtraInfo (USER.288) */ LONG GetMessageExtraInfo(void) { - return msgQueue->GetMessageExtraInfoVal; + return appMsgQueue->GetMessageExtraInfoVal; +} + + +/*********************************************************************** + * RegisterWindowMessage (USER.118) + */ +WORD RegisterWindowMessage( LPCSTR str ) +{ +#ifdef DEBUG_MSG + printf( "RegisterWindowMessage: '%s'\n", str ); +#endif + return GlobalAddAtom( str ); } diff --git a/windows/painting.c b/windows/painting.c index 4f21b13b0a5..5a8e60a0e11 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -10,6 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include <X11/Xlib.h> #include "win.h" +#include "message.h" /* Last CTLCOLOR id */ #define CTLCOLOR_MAX CTLCOLOR_STATIC @@ -23,27 +24,21 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return 0; - lps->hdc = GetDC( hwnd ); - if (!lps->hdc) return 0; - - SelectVisRgn( lps->hdc, wndPtr->hrgnUpdate ); + if (!(lps->hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate, + DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0; + GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint ); + if (wndPtr->hrgnUpdate) { - GetRgnBox( wndPtr->hrgnUpdate, &lps->rcPaint ); DeleteObject( wndPtr->hrgnUpdate ); wndPtr->hrgnUpdate = 0; + MSG_DecPaintCount( wndPtr->hmemTaskQ ); } - else - { - lps->rcPaint.left = 0; - lps->rcPaint.top = 0; - lps->rcPaint.right = wndPtr->rectClient.right-wndPtr->rectClient.left; - lps->rcPaint.bottom = wndPtr->rectClient.bottom-wndPtr->rectClient.top; - } - + wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT; + if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE; else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 ); - + return lps->hdc; } @@ -63,12 +58,7 @@ void EndPaint( HWND hwnd, LPPAINTSTRUCT lps ) void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush ) { RECT rect; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; - rect.left = 0; - rect.top = 0; - rect.right = wndPtr->rectClient.right - wndPtr->rectClient.left; - rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + GetClientRect( hwnd, &rect ); PaintRect( hwndParent, hwnd, hdc, hbrush, &rect ); } diff --git a/windows/timer.c b/windows/timer.c index 2aeb88ee585..da649610fd2 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -6,21 +6,19 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -#include <X11/Intrinsic.h> - #include "windows.h" - -extern XtAppContext XT_app_context; +#include "message.h" -typedef struct +typedef struct tagTIMER { - HWND hwnd; - WORD msg; /* WM_TIMER or WM_SYSTIMER */ - WORD id; - WORD timeout; - FARPROC proc; - XtIntervalId xtid; + HWND hwnd; + WORD msg; /* WM_TIMER or WM_SYSTIMER */ + WORD id; + WORD timeout; + struct tagTIMER *next; + DWORD expires; + FARPROC proc; } TIMER; #define NB_TIMERS 34 @@ -28,39 +26,100 @@ typedef struct static TIMER TimersArray[NB_TIMERS]; +static TIMER * pNextTimer = NULL; /* Next timer to expire */ + /*********************************************************************** - * TIMER_callback + * TIMER_InsertTimer + * + * Insert the timer at its place in the chain. */ -static void TIMER_callback( XtPointer data, XtIntervalId * xtid ) +static void TIMER_InsertTimer( TIMER * pTimer ) { - TIMER * pTimer = (TIMER *) data; - - pTimer->xtid = 0; /* In case the timer procedure calls KillTimer */ - - if (pTimer->proc) + if (!pNextTimer || (pTimer->expires < pNextTimer->expires)) + { + pTimer->next = pNextTimer; + pNextTimer = pTimer; + } + else { - CallWindowProc(pTimer->proc, pTimer->hwnd, pTimer->msg, - pTimer->id, GetTickCount()); + TIMER * ptr = pNextTimer; + while (ptr->next && (pTimer->expires >= ptr->next->expires)) + ptr = ptr->next; + pTimer->next = ptr; + ptr->next = pTimer; } - else - PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, 0 ); +} + + +/*********************************************************************** + * TIMER_RemoveTimer + * + * Remove the timer from the chain. + */ +static void TIMER_RemoveTimer( TIMER * pTimer ) +{ + if (pTimer == pNextTimer) pNextTimer = pTimer->next; + else + { + TIMER * ptr = pNextTimer; + while (ptr && (ptr->next != pTimer)) ptr = ptr->next; + if (ptr) ptr->next = pTimer->next; + } + pTimer->next = NULL; +} + + +/*********************************************************************** + * TIMER_NextExpire + * + * Return time until next timer expiration (-1 if none). + */ +static DWORD TIMER_NextExpire( DWORD curTime ) +{ + if (!pNextTimer) return -1; + if (pNextTimer->expires <= curTime) return 0; + return pNextTimer->expires - curTime; +} + + +/*********************************************************************** + * 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'. + */ +BOOL TIMER_CheckTimer( DWORD *next ) +{ + 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 timeout == 0, the timer has been removed by KillTimer */ if (pTimer->timeout) - pTimer->xtid = XtAppAddTimeOut( XT_app_context, pTimer->timeout, - TIMER_callback, pTimer ); + { + /* Restart the timer */ + pTimer->expires = curTime + pTimer->timeout; + TIMER_InsertTimer( pTimer ); + } + *next = TIMER_NextExpire( curTime ); + return TRUE; } /*********************************************************************** * TIMER_SetTimer */ -WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys ) +static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, + FARPROC proc, BOOL sys ) { int i; TIMER * pTimer; - + if (!timeout) return 0; if (!hwnd && !proc) return 0; @@ -79,9 +138,10 @@ WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys ) pTimer->msg = sys ? WM_SYSTIMER : WM_TIMER; pTimer->id = id; pTimer->timeout = timeout; + pTimer->expires = GetTickCount() + timeout; pTimer->proc = proc; - pTimer->xtid = XtAppAddTimeOut( XT_app_context, timeout, - TIMER_callback, pTimer ); + TIMER_InsertTimer( pTimer ); + MSG_IncTimerCount( GetTaskQueue(0) ); return id; } @@ -89,7 +149,7 @@ WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys ) /*********************************************************************** * TIMER_KillTimer */ -BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) +static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) { int i; TIMER * pTimer; @@ -106,13 +166,13 @@ BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) /* Delete the timer */ - if (pTimer->xtid) XtRemoveTimeOut( pTimer->xtid ); pTimer->hwnd = 0; pTimer->msg = 0; pTimer->id = 0; pTimer->timeout = 0; pTimer->proc = 0; - pTimer->xtid = 0; + TIMER_RemoveTimer( pTimer ); + MSG_DecTimerCount( GetTaskQueue(0) ); return TRUE; } @@ -123,7 +183,7 @@ BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc ) { #ifdef DEBUG_TIMER - printf( "SetTimer: %d %d %d %08x\n", hwnd, id, timeout, proc ); + printf( "SetTimer: %d %d %d %p\n", hwnd, id, timeout, proc ); #endif return TIMER_SetTimer( hwnd, id, timeout, proc, FALSE ); } @@ -135,7 +195,7 @@ WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc ) WORD SetSystemTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc ) { #ifdef DEBUG_TIMER - printf( "SetSystemTimer: %d %d %d %08x\n", hwnd, id, timeout, proc ); + printf( "SetSystemTimer: %d %d %d %p\n", hwnd, id, timeout, proc ); #endif return TIMER_SetTimer( hwnd, id, timeout, proc, TRUE ); } diff --git a/windows/win.c b/windows/win.c index d7fe3a2c88e..8411e489860 100644 --- a/windows/win.c +++ b/windows/win.c @@ -10,11 +10,11 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include <X11/StringDefs.h> #include <X11/Core.h> #include <X11/Shell.h> -#include <X11/Xaw/Box.h> #include "class.h" #include "win.h" #include "user.h" +#include "dce.h" extern Display * XT_display; extern Screen * XT_screen; @@ -22,10 +22,6 @@ extern Colormap COLOR_WinColormap; static HWND firstWindow = 0; -void SCROLLBAR_CreateScrollBar(LPSTR className, LPSTR Label, HWND hwnd); -void LISTBOX_CreateListBox(LPSTR className, LPSTR Label, HWND hwnd); -void COMBOBOX_CreateComboBox(LPSTR className, LPSTR Label, HWND hwnd); - /*********************************************************************** * WIN_FindWndPtr * @@ -42,6 +38,76 @@ WND * WIN_FindWndPtr( HWND hwnd ) } +/*********************************************************************** + * WIN_UnlinkWindow + * + * Remove a window from the siblings linked list. + */ +BOOL WIN_UnlinkWindow( HWND hwnd ) +{ + HWND * curWndPtr; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr) return FALSE; + if (wndPtr->hwndParent) + { + WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); + curWndPtr = &parentPtr->hwndChild; + } + else curWndPtr = &firstWindow; + + while (*curWndPtr != hwnd) + { + WND * curPtr = WIN_FindWndPtr( *curWndPtr ); + curWndPtr = &curPtr->hwndNext; + } + *curWndPtr = wndPtr->hwndNext; + return TRUE; +} + + +/*********************************************************************** + * WIN_LinkWindow + * + * Insert a window into the siblings linked list. + * The window is inserted after the specified window, which can also + * be specified as HWND_TOP or HWND_BOTTOM. + */ +BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ) +{ + HWND * hwndPtr = NULL; /* pointer to hwnd to change */ + + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return FALSE; + + if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM)) + { + /* Make hwndPtr point to the first sibling hwnd */ + if (wndPtr->hwndParent) + { + WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); + if (parentPtr) hwndPtr = &parentPtr->hwndChild; + } + else hwndPtr = &firstWindow; + if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */ + while (*hwndPtr) + { + WND * nextPtr = WIN_FindWndPtr( *hwndPtr ); + hwndPtr = &nextPtr->hwndNext; + } + } + else /* Normal case */ + { + WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter ); + if (afterPtr) hwndPtr = &afterPtr->hwndNext; + } + if (!hwndPtr) return FALSE; + wndPtr->hwndNext = *hwndPtr; + *hwndPtr = hwnd; + return TRUE; +} + + /*********************************************************************** * WIN_FindWinToRepaint * @@ -55,8 +121,6 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) for ( ; hwnd != 0; hwnd = wndPtr->hwndNext ) { if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; - if (!wndPtr || !wndPtr->winWidget) continue; - if (!XtIsRealized( wndPtr->winWidget )) continue; if (wndPtr->hrgnUpdate) return hwnd; if (wndPtr->hwndChild) { @@ -114,9 +178,11 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, CREATESTRUCT *createStruct; HANDLE hcreateStruct; int wmcreate; + short newwidth, newheight; #ifdef DEBUG_WIN - printf( "CreateWindowEx: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height ); + printf( "CreateWindowEx: %s %s %d,%d %dx%d %08x\n", + className, windowName, x, y, width, height, style ); #endif if (x == CW_USEDEFAULT) x = 0; @@ -155,11 +221,12 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->hwndOwner = parent; /* What else? */ wndPtr->hClass = class; wndPtr->hInstance = instance; - wndPtr->rectClient.left = x; - wndPtr->rectClient.top = y; - wndPtr->rectClient.right = x + width; - wndPtr->rectClient.bottom = y + height; - wndPtr->rectWindow = wndPtr->rectClient; + wndPtr->rectWindow.left = x; + wndPtr->rectWindow.top = y; + wndPtr->rectWindow.right = x + width; + wndPtr->rectWindow.bottom = y + height; + wndPtr->rectClient = wndPtr->rectWindow; + wndPtr->hmemTaskQ = GetTaskQueue(0); wndPtr->hrgnUpdate = 0; wndPtr->hwndLastActive = 0; wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; @@ -169,43 +236,70 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->wIDmenu = menu; wndPtr->hText = 0; wndPtr->flags = 0; + wndPtr->hCursor = 0; + wndPtr->hWndVScroll = 0; + wndPtr->hWndHScroll = 0; if (classPtr->wc.cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); - if (classPtr->wc.style & CS_OWNDC) - wndPtr->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL); - else wndPtr->hdc = 0; classPtr->cWindows++; - /* Insert the window in the linked list */ - - if (parent) - { - wndPtr->hwndNext = parentPtr->hwndChild; - parentPtr->hwndChild = hwnd; - } - else /* Top-level window */ + /* Get class or window DC if needed */ + if (classPtr->wc.style & CS_OWNDC) { - wndPtr->hwndNext = firstWindow; - firstWindow = hwnd; + wndPtr->flags |= WIN_OWN_DC; + wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC ); } - - if (!strcasecmp(className, "SCROLLBAR")) + else if (classPtr->wc.style & CS_CLASSDC) { - SCROLLBAR_CreateScrollBar(className, windowName, hwnd); - goto WinCreated; + wndPtr->flags |= WIN_CLASS_DC; + wndPtr->hdce = classPtr->hdce; } - if (!strcasecmp(className, "LISTBOX")) + else wndPtr->hdce = 0; + + /* Insert the window in the linked list */ + + WIN_LinkWindow( hwnd, HWND_TOP ); + + if (!strcasecmp(className, "COMBOBOX")) { - LISTBOX_CreateListBox(className, windowName, hwnd); - goto WinCreated; + height = 16; } - if (!strcasecmp(className, "COMBOBOX")) + +#ifdef USE_XLIB { - COMBOBOX_CreateComboBox(className, windowName, hwnd); - goto WinCreated; + XSetWindowAttributes win_attr; + Window parentWindow; + int x_rel, y_rel; + + win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | + ButtonReleaseMask | StructureNotifyMask | + FocusChangeMask | EnterWindowMask; + win_attr.override_redirect = /*True*/ False; + 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; + } + else + { + parentWindow = DefaultRootWindow( XT_display ); + x_rel = x; + y_rel = y; + } + wndPtr->window = XCreateWindow( XT_display, parentWindow, + x_rel, y_rel, width, height, 0, + CopyFromParent, InputOutput, + CopyFromParent, + CWEventMask | CWOverrideRedirect | + CWColormap, &win_attr ); + XStoreName( XT_display, wndPtr->window, windowName ); } - /* Create the widgets */ +#else + /* Create the widgets */ if (style & WS_CHILD) { @@ -223,6 +317,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XtNwidth, width, XtNheight, height, XtNborderColor, borderCol, + XtNmappedWhenManaged, FALSE, NULL ); } else @@ -235,6 +330,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XtNwidth, width, XtNheight, height, XtNborderWidth, 0, + XtNmappedWhenManaged, FALSE, NULL ); } } @@ -247,6 +343,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, XtNx, x, XtNy, y, XtNcolormap, COLOR_WinColormap, + XtNmappedWhenManaged, FALSE, NULL ); wndPtr->compositeWidget = XtVaCreateManagedWidget(className, formWidgetClass, @@ -296,8 +393,24 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, NULL ); } } - -WinCreated: + if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); + if (wndPtr->compositeWidget) XtRealizeWidget( wndPtr->compositeWidget ); + XtRealizeWidget( wndPtr->winWidget ); + wndPtr->window = XtWindow( wndPtr->winWidget ); +#endif /* USE_XLIB */ + + if ((style & WS_VSCROLL) == WS_VSCROLL) { + newheight = height - (((style & WS_HSCROLL) == WS_HSCROLL) ? 16 : 0); + wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, + width - 16, 0, 16, newheight, hwnd, 2, instance, 0L); + } + if ((style & WS_HSCROLL) == WS_HSCROLL) { + newwidth = width - (((style & WS_VSCROLL) == WS_VSCROLL) ? 16 : 0); + wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "", + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, + 0, height - 16, newwidth, 16, hwnd, 3, instance, 0L); + } /* Send the WM_CREATE message */ @@ -318,7 +431,24 @@ WinCreated: wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct ); if (!wmcreate) wmcreate = -1; - else wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct ); + else + { + /* Send WM_NCCALCSIZE message */ + NCCALCSIZE_PARAMS *params; + HANDLE hparams; + hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); + if (hparams) + { + params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams ); + params->rgrc[0] = wndPtr->rectWindow; + params->lppos = NULL; + SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params ); + wndPtr->rectClient = params->rgrc[0]; + GlobalUnlock( hparams ); + GlobalFree( hparams ); + } + wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct ); + } GlobalUnlock( hcreateStruct ); GlobalFree( hcreateStruct ); @@ -329,18 +459,27 @@ WinCreated: if (parent) parentPtr->hwndChild = wndPtr->hwndNext; else firstWindow = wndPtr->hwndNext; +#ifdef USE_XLIB + XDestroyWindow( XT_display, wndPtr->window ); +#else if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); - if (wndPtr->hdc) DeleteDC( wndPtr->hdc ); +#endif + if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); return 0; } - + +#ifdef USE_XLIB + EVENT_AddHandlers( wndPtr->window, hwnd ); +#else EVENT_AddHandlers( wndPtr->winWidget, hwnd ); +#endif - if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE ); + + if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); return hwnd; } @@ -350,7 +489,6 @@ WinCreated: BOOL DestroyWindow( HWND hwnd ) { WND * wndPtr; - HWND * curWndPtr; CLASS * classPtr; /* Initialisation */ @@ -366,130 +504,30 @@ BOOL DestroyWindow( HWND hwnd ) /* Destroy all children */ + if (wndPtr->hWndVScroll) DestroyWindow(wndPtr->hWndVScroll); + if (wndPtr->hWndHScroll) DestroyWindow(wndPtr->hWndHScroll); while (wndPtr->hwndChild) /* The child removes itself from the list */ DestroyWindow( wndPtr->hwndChild ); /* Remove the window from the linked list */ - if (wndPtr->hwndParent) - { - WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); - curWndPtr = &parentPtr->hwndChild; - } - else curWndPtr = &firstWindow; - - while (*curWndPtr != hwnd) - { - WND * curPtr = WIN_FindWndPtr( *curWndPtr ); - curWndPtr = &curPtr->hwndNext; - } - *curWndPtr = wndPtr->hwndNext; + WIN_UnlinkWindow( hwnd ); /* Destroy the window */ +#ifdef USE_XLIB + XDestroyWindow( XT_display, wndPtr->window ); +#else if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); - if (wndPtr->hdc) DeleteDC( wndPtr->hdc ); +#endif + if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); return TRUE; } -/*********************************************************************** - * GetWindowRect (USER.32) - */ -void GetWindowRect( HWND hwnd, LPRECT rect ) -{ - int x, y, width, height; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - if (wndPtr) - { - XtVaGetValues(wndPtr->winWidget, - XtNx, &x, XtNy, &y, - XtNwidth, &width, - XtNheight, &height, - NULL ); - rect->left = x & 0xffff; - rect->top = y & 0xffff; - rect->right = width & 0xffff; - rect->bottom = height & 0xffff; - } -} - - -/*********************************************************************** - * GetClientRect (USER.33) - */ -void GetClientRect( HWND hwnd, LPRECT rect ) -{ - int width, height; - WND * wndPtr = WIN_FindWndPtr( hwnd ); - - rect->left = rect->top = rect->right = rect->bottom = 0; - if (wndPtr) - { - XtVaGetValues(wndPtr->winWidget, - XtNwidth, &width, - XtNheight, &height, - NULL ); - rect->right = width & 0xffff; - rect->bottom = height & 0xffff; - } -} - - -/*********************************************************************** - * ShowWindow (USER.42) - */ -BOOL ShowWindow( HWND hwnd, int cmd ) -{ - int width, height; - - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (wndPtr) - { - if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); - XtVaGetValues(wndPtr->winWidget, - XtNwidth, &width, - XtNheight, &height, - NULL ); - switch(cmd) - { - case SW_HIDE: - XtSetMappedWhenManaged(wndPtr->winWidget, FALSE); - wndPtr->dwStyle &= (WS_VISIBLE ^ 0xFFFFFFFL); - SendMessage( hwnd, WM_SHOWWINDOW, FALSE, 0 ); - break; - case SW_SHOWMINNOACTIVE: - case SW_SHOWMINIMIZED: - case SW_MINIMIZE: - wndPtr->dwStyle |= WS_ICONIC; - goto WINVisible; - case SW_SHOWNA: - case SW_SHOWNOACTIVATE: - case SW_MAXIMIZE: - case SW_SHOWMAXIMIZED: - case SW_SHOW: - case SW_NORMAL: - case SW_SHOWNORMAL: - wndPtr->dwStyle &= (WS_ICONIC ^ 0xFFFFFFFL); -WINVisible: - XtSetMappedWhenManaged(wndPtr->winWidget, TRUE); - wndPtr->dwStyle |= WS_VISIBLE; - SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, - (width & 0xffff) | (height << 16) ); - SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 ); - break; - default: - break; - } - } - return TRUE; -} - - /*********************************************************************** * CloseWindow (USER.43) */ @@ -498,7 +536,6 @@ void CloseWindow(HWND hWnd) WND * wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr->dwStyle & WS_CHILD) return; ShowWindow(hWnd, SW_MINIMIZE); - PostMessage(hWnd, WM_CLOSE, 0, 0L); } @@ -508,7 +545,6 @@ void CloseWindow(HWND hWnd) */ BOOL OpenIcon(HWND hWnd) { - WND * wndPtr = WIN_FindWndPtr(hWnd); if (!IsIconic(hWnd)) return FALSE; ShowWindow(hWnd, SW_SHOWNORMAL); return(TRUE); @@ -523,34 +559,8 @@ HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch) { return((HWND)NULL); } - -/*********************************************************************** - * MoveWindow (USER.56) - */ -void MoveWindow(HWND hWnd, short x, short y, short w, short h, BOOL bRepaint) -{ - WND * wndPtr = WIN_FindWndPtr( hWnd ); - if (wndPtr) - { - wndPtr->rectClient.left = x; - wndPtr->rectClient.top = y; - wndPtr->rectClient.right = x + w; - wndPtr->rectClient.bottom = y + h; - XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y, - XtNwidth, w, XtNheight, h, NULL ); - SendMessage(hWnd, WM_MOVE, 0, MAKELONG(x, y)); - printf("MoveWindow(%X, %d, %d, %d, %d, %d); !\n", - hWnd, x, y, w, h, bRepaint); - if (bRepaint) { - InvalidateRect(hWnd, NULL, TRUE); - UpdateWindow(hWnd); - } - } -} - - /*********************************************************************** * UpdateWindow (USER.124) */ @@ -578,8 +588,10 @@ HMENU GetMenu( HWND hwnd ) */ BOOL SetMenu(HWND hwnd, HMENU hmenu) { +#ifdef USE_XLIB + return FALSE; +#else WND *wndPtr; - wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr == NULL) return FALSE; @@ -618,44 +630,7 @@ BOOL SetMenu(HWND hwnd, HMENU hmenu) } return TRUE; -} - - -/*********************************************************************** - * SetWindowPos (USER.232) - */ -void SetWindowPos(HWND hWnd, HWND hWndInsertAfter, short x, short y, short w, short h, WORD wFlag) -{ - WND * wndPtr = WIN_FindWndPtr( hWnd ); - if (wndPtr) - { - if ((wFlag & SWP_NOMOVE) != SWP_NOMOVE) { - wndPtr->rectClient.left = x; - wndPtr->rectClient.top = y; - XtVaSetValues(wndPtr->winWidget, XtNx, x, XtNy, y, NULL ); - } - if ((wFlag & SWP_NOSIZE) != SWP_NOSIZE) { - wndPtr->rectClient.right = x + w; - wndPtr->rectClient.bottom = y + h; - XtVaSetValues(wndPtr->winWidget, XtNwidth, w, XtNheight, h, NULL ); - } - if ((wFlag & SWP_NOREDRAW) != SWP_NOREDRAW) { - InvalidateRect(hWnd, NULL, TRUE); - UpdateWindow(hWnd); - } - if ((wFlag & SWP_HIDEWINDOW) == SWP_HIDEWINDOW) - ShowWindow(hWnd, SW_HIDE); - if ((wFlag & SWP_SHOWWINDOW) == SWP_SHOWWINDOW) - ShowWindow(hWnd, SW_SHOW); -/* - if ((wFlag & SWP_NOACTIVATE) != SWP_NOACTIVATE) - SetActiveWindow(hWnd); - if ((wFlag & SWP_NOZORDER) != SWP_NOZORDER) - { } -*/ - printf("SetWindowPos(%X, %X, %d, %d, %d, %d, %X); !\n", - hWnd, hWndInsertAfter, x, y, w, h, wFlag); - } +#endif /* USE_XLIB */ } @@ -748,21 +723,6 @@ LONG SetWindowLong( HWND hwnd, short offset, LONG newval ) } -/*********************************************************************** - * IsIconic (USER.31) - */ -BOOL IsIconic(HWND hWnd) -{ - WND * wndPtr; - if (hWnd == 0) return(FALSE); - wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr == 0) return(FALSE); - if (wndPtr->dwStyle & WS_ICONIC) return(TRUE); - return(FALSE); -} - - - /******************************************************************* * GetWindowText (USER.36) */ @@ -796,7 +756,7 @@ int GetWindowTextLength(HWND hwnd) BOOL IsWindow( HWND hwnd ) { WND * wndPtr = WIN_FindWndPtr( hwnd ); - return (wndPtr->dwMagic == WND_MAGIC); + return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC)); } @@ -806,6 +766,7 @@ BOOL IsWindow( HWND hwnd ) HWND GetParent(HWND hwnd) { WND *wndPtr = WIN_FindWndPtr(hwnd); + if (!wndPtr) return 0; return wndPtr->hwndParent; } @@ -838,14 +799,9 @@ BOOL IsChild( HWND parent, HWND child ) */ BOOL IsWindowVisible(HWND hWnd) { - WND * wndPtr; - if (hWnd == 0) return(FALSE); - wndPtr = WIN_FindWndPtr(hWnd); + WND * wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == 0) return(FALSE); - if (wndPtr->dwStyle & WS_VISIBLE) { - if (XtIsRealized(wndPtr->winWidget)) return(TRUE); - } - return(FALSE); + else return ((wndPtr->dwStyle & WS_VISIBLE) != 0); } diff --git a/windows/winpos.c b/windows/winpos.c new file mode 100644 index 00000000000..0b474e2e3ea --- /dev/null +++ b/windows/winpos.c @@ -0,0 +1,389 @@ +/* + * Window position related functions. + * + * Copyright 1993 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include "win.h" + +extern Display * XT_display; +extern Screen * XT_screen; + + +/*********************************************************************** + * GetWindowRect (USER.32) + */ +void GetWindowRect( HWND hwnd, LPRECT rect ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return; + + *rect = wndPtr->rectWindow; + if (wndPtr->hwndParent) + MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 ); +} + + +/*********************************************************************** + * GetClientRect (USER.33) + */ +void GetClientRect( HWND hwnd, LPRECT rect ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + + rect->left = rect->top = rect->right = rect->bottom = 0; + if (wndPtr) + { + rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left; + rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + } +} + + +/******************************************************************* + * ClientToScreen (USER.28) + */ +void ClientToScreen( HWND hwnd, LPPOINT lppnt ) +{ + MapWindowPoints( hwnd, 0, lppnt, 1 ); +} + + +/******************************************************************* + * ScreenToClient (USER.29) + */ +void ScreenToClient( HWND hwnd, LPPOINT lppnt ) +{ + MapWindowPoints( 0, hwnd, lppnt, 1 ); +} + + +/******************************************************************* + * MapWindowPoints (USER.258) + */ +void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count ) +{ + WND * wndPtr; + POINT * curpt; + POINT origin = { 0, 0 }; + WORD i; + + /* Translate source window origin to screen coords */ + while(hwndFrom) + { + wndPtr = WIN_FindWndPtr( hwndFrom ); + origin.x += wndPtr->rectClient.left; + origin.y += wndPtr->rectClient.top; + hwndFrom = wndPtr->hwndParent; + } + + /* Translate origin to destination window coords */ + while(hwndTo) + { + wndPtr = WIN_FindWndPtr( hwndTo ); + origin.x -= wndPtr->rectClient.left; + origin.y -= wndPtr->rectClient.top; + hwndTo = wndPtr->hwndParent; + } + + /* Translate points */ + for (i = 0, curpt = lppt; i < count; i++, curpt++) + { + curpt->x += origin.x; + curpt->y += origin.y; + } +} + + +/*********************************************************************** + * IsIconic (USER.31) + */ +BOOL IsIconic(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return FALSE; + return (wndPtr->dwStyle & WS_MINIMIZE) != 0; +} + + +/*********************************************************************** + * IsZoomed (USER.272) + */ +BOOL IsZoomed(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return FALSE; + return (wndPtr->dwStyle & WS_MAXIMIZE) != 0; +} + + +/*********************************************************************** + * MoveWindow (USER.56) + */ +BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint) +{ + int flags = SWP_NOZORDER | SWP_NOACTIVATE; + if (!repaint) flags |= SWP_NOREDRAW; +#ifdef DEBUG_WIN + printf( "MoveWindow: %d %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint ); +#endif + return SetWindowPos( hwnd, 0, x, y, cx, cy, flags ); +} + + +/*********************************************************************** + * ShowWindow (USER.42) + */ +BOOL ShowWindow( HWND hwnd, int cmd ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + BOOL wasVisible; + int swpflags = 0; + +#ifdef DEBUG_WIN + printf("ShowWindow: hwnd=%d, cmd=%d\n", hwnd, cmd); +#endif + + if (!wndPtr) return FALSE; + wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0; + switch(cmd) + { + case SW_HIDE: + if (!wasVisible) return FALSE; /* Nothing to do */ + swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER; + break; + + case SW_SHOWMINNOACTIVE: + case SW_SHOWMINIMIZED: + case SW_MINIMIZE: + wndPtr->dwStyle |= WS_MINIMIZE; + swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER; + break; + + case SW_SHOWNA: + case SW_SHOWNOACTIVATE: + case SW_MAXIMIZE: + case SW_SHOWMAXIMIZED: + case SW_SHOW: + case SW_NORMAL: + case SW_SHOWNORMAL: + wndPtr->dwStyle &= ~WS_MINIMIZE; + swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER; + break; + } + SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); + SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags ); + + /* Send WM_SIZE and WM_MOVE messages if not already done */ + if (!(wndPtr->flags & WIN_GOT_SIZEMSG)) + { + int wParam = SIZE_RESTORED; + if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED; + else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED; + wndPtr->flags |= WIN_GOT_SIZEMSG; + SendMessage( hwnd, WM_SIZE, wParam, + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + SendMessage( hwnd, WM_MOVE, 0, + MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) ); + } + return wasVisible; +} + + +/*********************************************************************** + * SetWindowPos (USER.232) + */ +/* Unimplemented flags: SWP_NOREDRAW, SWP_NOACTIVATE + */ +/* Note: all this code should be in the DeferWindowPos() routines, + * and SetWindowPos() should simply call them. This will be implemented + * some day... + */ +BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, + short cx, short cy, WORD flags ) +{ + WINDOWPOS *winPos; + HANDLE hmem = 0; + RECT newWindowRect, newClientRect; + WND *wndPtr; + int calcsize_result = 0; +#ifdef USE_XLIB + XWindowChanges winChanges; + int changeMask = 0; +#endif + +#ifdef DEBUG_WIN + printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n", + hwnd, hwndInsertAfter, x, y, cx, cy, flags ); +#endif + + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; + if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) + flags |= SWP_NOMOVE | SWP_NOSIZE; + + /* Send WM_WINDOWPOSCHANGING message */ + + if (!(hmem = GlobalAlloc( GMEM_MOVEABLE,sizeof(WINDOWPOS) ))) return FALSE; + winPos = (WINDOWPOS *)GlobalLock( hmem ); + winPos->hwnd = hwnd; + winPos->hwndInsertAfter = hwndInsertAfter; + winPos->x = x; + winPos->y = y; + winPos->cx = cx; + winPos->cy = cy; + winPos->flags = flags; + SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos ); + + /* Calculate new position and size */ + + newWindowRect = wndPtr->rectWindow; + newClientRect = wndPtr->rectClient; + + if (!(winPos->flags & SWP_NOSIZE)) + { + newWindowRect.right = newWindowRect.left + winPos->cx; + newWindowRect.bottom = newWindowRect.top + winPos->cy; + } + + if (!(winPos->flags & SWP_NOMOVE)) + { + newWindowRect.left = winPos->x; + newWindowRect.top = winPos->y; + newWindowRect.right += winPos->x - wndPtr->rectWindow.left; + newWindowRect.bottom += winPos->y - wndPtr->rectWindow.top; + } + + /* Reposition window in Z order */ + + if (!(winPos->flags & SWP_NOZORDER)) + { + hwndInsertAfter = winPos->hwndInsertAfter; + + /* TOPMOST not supported yet */ + if ((hwndInsertAfter == HWND_TOPMOST) || + (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP; + + /* Make sure hwndInsertAfter is a sibling of hwnd */ + if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM)) + if (wndPtr->hwndParent != GetParent(hwndInsertAfter)) goto Abort; + + WIN_UnlinkWindow( hwnd ); + WIN_LinkWindow( hwnd, hwndInsertAfter ); + } + + /* Recalculate client area position */ + + if (winPos->flags & SWP_FRAMECHANGED) + { + /* Send WM_NCCALCSIZE message */ + NCCALCSIZE_PARAMS *params; + HANDLE hparams; + + if (!(hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ))) + goto Abort; + params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams ); + params->rgrc[0] = newWindowRect; + params->rgrc[1] = wndPtr->rectWindow; + params->rgrc[2] = wndPtr->rectClient; + params->lppos = winPos; + calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params); + GlobalUnlock( hparams ); + GlobalFree( hparams ); + newClientRect = params->rgrc[0]; + /* Handle result here */ + } + else + { + newClientRect.left = newWindowRect.left + wndPtr->rectClient.left + - wndPtr->rectWindow.left; + newClientRect.top = newWindowRect.top + wndPtr->rectClient.top + - wndPtr->rectWindow.top; + newClientRect.right = newWindowRect.right + wndPtr->rectClient.right + - wndPtr->rectWindow.right; + newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom + - wndPtr->rectWindow.bottom; + } + + /* Perform the moving and resizing */ +#ifdef USE_XLIB + if (!(winPos->flags & SWP_NOMOVE)) + { + WND * parentPtr; + winChanges.x = newWindowRect.left; + winChanges.y = newWindowRect.top; + if (wndPtr->hwndParent) + { + parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); + winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left; + winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top; + } + changeMask |= CWX | CWY; + } + if (!(winPos->flags & SWP_NOSIZE)) + { + winChanges.width = newWindowRect.right - newWindowRect.left; + winChanges.height = newWindowRect.bottom - newWindowRect.top; + changeMask |= CWWidth | CWHeight; + } + if (!(winPos->flags & SWP_NOZORDER)) + { + if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above; + else winChanges.stack_mode = Below; + if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM)) + { + WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter ); + winChanges.sibling = insertPtr->window; + changeMask |= CWSibling; + } + changeMask |= CWStackMode; + } + if (changeMask) XConfigureWindow( XT_display, wndPtr->window, + changeMask, &winChanges ); +#endif + + if (winPos->flags & SWP_SHOWWINDOW) + { + wndPtr->dwStyle |= WS_VISIBLE; +#ifdef USE_XLIB + XMapWindow( XT_display, wndPtr->window ); +#else + if (wndPtr->shellWidget) XtMapWidget( wndPtr->shellWidget ); + else XtMapWidget( wndPtr->winWidget ); +#endif + } + else if (winPos->flags & SWP_HIDEWINDOW) + { + wndPtr->dwStyle &= ~WS_VISIBLE; +#ifdef USE_XLIB + XUnmapWindow( XT_display, wndPtr->window ); +#else + if (wndPtr->shellWidget) XtUnmapWidget( wndPtr->shellWidget ); + else XtUnmapWidget( wndPtr->winWidget ); +#endif + } + + /* Finally send the WM_WINDOWPOSCHANGED message */ + wndPtr->rectWindow = newWindowRect; + wndPtr->rectClient = newClientRect; + SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos ); + GlobalUnlock( hmem ); + GlobalFree( hmem ); + + return TRUE; + + Abort: /* Fatal error encountered */ + if (hmem) + { + GlobalUnlock( hmem ); + GlobalFree( hmem ); + } + return FALSE; +} + + diff --git a/wine.ini b/wine.ini new file mode 100644 index 00000000000..d9958bea4f0 --- /dev/null +++ b/wine.ini @@ -0,0 +1,19 @@ +[drives] +a=/mnt/fd0 +c=/dos +d=/usr/windows +e=/home/bob/Wine/work +f=/home/bob/test + +[wine] +windows=c:\windows +system=c:\windows\system +temp=c:\temp +path=c:\windows;c:\windows\system;e:\;e:\test;f:\ + +[serialports] +com1=/dev/cua0 +com2=/dev/cua1 + +[parallelports] +lpt1=/dev/lp0 -- GitLab