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().
diff --git a/ChangeLog b/ChangeLog
index ebf46f1..151f65b 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 @@
* [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 0000000..26b35f4
--- /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 0000000..3854e93
--- /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 11a884a..1f7221c 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 @@
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 0000000..a7d2f7a
--- /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 ba0b81b..1b090d4 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 @@
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 0000000..492af84
--- /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 0000000..3bb9466
--- /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 99fa57a..68fa157 100644
--- a/bsdmake.patch
+++ b/bsdmake.patch
@@ -6,7 +6,7 @@
# 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 0000000..aee3e14
--- /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 e471589..c8e32b9 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -17,60 +17,24 @@
#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 @@
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 @@
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 a71eb92..b1dfb73 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 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 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 @@
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 @@
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 @@
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,9 +218,102 @@
MAKELONG(hwnd, LBN_DBLCLK));
printf("ListBox Send LBN_DBLCLK !\n");
return 0;
+ case WM_MOUSEMOVE:
+ if ((wParam & MK_LBUTTON) != 0) {
+ y = HIWORD(lParam);
+ if (y < 4) {
+ lphl = ListBoxGetStorageHeader(hwnd);
+ if (lphl->FirstVisible > 1) {
+ lphl->FirstVisible--;
+ if (wndPtr->hWndVScroll != (HWND)NULL)
+ SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+ break;
+ }
+ }
+ GetClientRect(hwnd, &rect);
+ if (y > (rect.bottom - 4)) {
+ lphl = ListBoxGetStorageHeader(hwnd);
+ if (lphl->FirstVisible < lphl->ItemsCount) {
+ lphl->FirstVisible++;
+ if (wndPtr->hWndVScroll != (HWND)NULL)
+ SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+ break;
+ }
+ }
+ if ((y > 0) && (y < (rect.bottom - 4))) {
+ if ((y < rectsel.top) || (y > rectsel.bottom)) {
+ wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
+ if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
+ lphl->ItemFocused = wRet;
+ }
+ else {
+ ListBoxSetCurSel(hwnd, wRet);
+ }
+ ListBoxGetItemRect(hwnd, wRet, &rectsel);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+ }
+
+ }
+ }
+ break;
case WM_KEYDOWN:
- printf("ListBox WM_KEYDOWN wParam %X!\n", wParam);
- ListBoxFindNextMatch(hwnd, wParam);
+ 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);
@@ -216,42 +327,6 @@
}
StdDrawListBox(hwnd);
break;
- case WM_MOUSEMOVE:
- if ((wParam & MK_LBUTTON) != 0) {
- y = HIWORD(lParam);
- if (y < 4) {
- lphl = ListBoxGetStorageHeader(hwnd);
- if (lphl->FirstVisible > 1) {
- lphl->FirstVisible--;
- SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE);
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- break;
- }
- }
- GetClientRect(hwnd, &rect);
- if (y > (rect.bottom - 4)) {
- lphl = ListBoxGetStorageHeader(hwnd);
- if (lphl->FirstVisible < lphl->ItemsCount) {
- lphl->FirstVisible++;
- SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE);
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- break;
- }
- }
- if ((y > 0) && (y < (rect.bottom - 4))) {
- if ((y < rectsel.top) || (y > rectsel.bottom)) {
- wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
- ListBoxSetCurSel(hwnd, wRet);
- ListBoxGetItemRect(hwnd, wRet, &rectsel);
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- }
-
- }
- }
- break;
case LB_RESETCONTENT:
printf("ListBox LB_RESETCONTENT !\n");
@@ -260,17 +335,17 @@
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 @@
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 @@
case LB_GETITEMRECT:
return wRet;
case LB_GETSEL:
+ wRet = ListBoxGetSel(hwnd, wParam);
return wRet;
case LB_GETSELCOUNT:
return wRet;
@@ -317,7 +392,9 @@
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 @@
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 @@
void StdDrawListBox(HWND hwnd)
{
+ WND *wndPtr;
LPHEADLIST lphl;
LPLISTSTRUCT lpls;
PAINTSTRUCT ps;
@@ -399,7 +468,7 @@
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 @@
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 @@
void OwnerDrawListBox(HWND hwnd)
{
+ WND *wndPtr;
LPHEADLIST lphl;
LPLISTSTRUCT lpls;
PAINTSTRUCT ps;
@@ -456,38 +549,47 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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,22 +968,44 @@
-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) || (wIndex == (WORD)-1)) {
+ lpls2->dis.itemState = state;
+ break;
+ }
+ if (lpls == NULL) break;
+ }
+ return LB_ERR;
+}
+
+
+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) {
- lpls2->dis.itemState = 1;
- break;
+ return lpls2->dis.itemState;
}
if (lpls == NULL) break;
}
@@ -844,28 +1015,56 @@
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 @@
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 @@
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 @@
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 @@
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 2d22115..c1cd758 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 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 @@
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 fd8e45a..9cfa550 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -17,7 +17,8 @@
#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 @@
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 @@
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 @@
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)
+/*************************************************************************
+ * GetScrollWindowHandle
+ */
+HWND GetScrollWindowHandle(HWND hWnd, int nBar)
{
- LPHEADSCROLL lphs;
- lphs = ScrollBarGetStorageHeader(hwnd);
- if (lphs == NULL) return 0;
- return lphs->CurVal;
+ 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;
}
-
-void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax)
-{
- LPHEADSCROLL lphs;
- lphs = ScrollBarGetStorageHeader(hwnd);
- if (lphs == NULL) return;
- *lpMin = lphs->MinVal;
- *lpMax = lphs->MaxVal;
-}
-
-
-
+/*************************************************************************
+ * 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 @@
+/*************************************************************************
+ * 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 @@
+/*************************************************************************
+ * 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 6928139..558110b 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -109,6 +109,18 @@
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 6733486..c88ac44 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -13,23 +13,28 @@
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 0000000..4b4ed04
--- /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 0000000..817f4af
--- /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 0000000..b398809
--- /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 0000000..87948b0
--- /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 0000000..8c11afd
--- /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 1852185..82c71de 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -7,7 +7,7 @@
#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 @@
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 a1fc5c5..f2e2baa 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -43,6 +43,11 @@
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 142f451..86a1508 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -28,6 +28,8 @@
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 @@
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 @@
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 @@
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 859144c..d6ad335 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -173,7 +173,7 @@
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 bf032d6..86682f1 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -13,12 +13,16 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 0000000..4e37987
--- /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 0000000..97bc6f4
--- /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 0000000..61cf6b1
--- /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 9ab50e4..285e81b 100644
--- a/include/class.h
+++ b/include/class.h
@@ -17,7 +17,7 @@
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 eff58a5..d95c781 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 1b628a2..0000000
--- 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 bb5b632..aade98d 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 @@
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 @@
{
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 92cabc5..f44c9a4 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 f44cf8c..5d89f9e 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -14,16 +14,17 @@
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 15d251a..edc0bec 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -27,7 +27,10 @@
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 @@
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 0bbfc9a..d64b4fc 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 @@
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 e610ba4..58e67cc 100644
--- a/include/neexe.h
+++ b/include/neexe.h
@@ -136,7 +136,9 @@
/* 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 c1c7bf9..69fc97b 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 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 ea9f851..437dfd9 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 3db21d2..3b9867d 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 894da98..b90675d 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 @@
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 9d3eaf3..ae37d54 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -64,7 +64,8 @@
#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 @@
#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 WORD ATOM;
+#define MAKEINTATOM(i) ((LPCSTR)MAKELP(0, (i)))
+
+
/* Raster operations */
#define R2_BLACK 1
@@ -558,6 +592,19 @@
#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 @@
#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 @@
#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 @@
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 @@
#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 @@
#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 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,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,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,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,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,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,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,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,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(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(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 6a602e9..dbc034c 100644
--- a/include/wine.h
+++ b/include/wine.h
@@ -22,9 +22,14 @@
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 0000000..9c5130a
--- /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 873a6ac..083d8f6 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 0000000..039c1c3
--- /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 a4371c6..0000000
--- 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/int21.c b/loader/int21.c
deleted file mode 100644
index fdf506a..0000000
--- a/loader/int21.c
+++ /dev/null
@@ -1,1206 +0,0 @@
-#include <time.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <malloc.h>
-#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 "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);
-
-WORD ExtendedError, CodePage = 437;
-BYTE ErrorClass, Action, ErrorLocus;
-
-void Error(int e, int class, int el)
-{
- ExtendedError = e;
- ErrorClass = class;
- Action = SA_Ask4Retry;
- ErrorLocus = el;
-}
-
-void GetFreeDiskSpace(struct sigcontext_struct *context)
-{
- int drive;
- struct statfs info;
- long size,avail;
-
- if (!(DX & 0xff))
- drive = CurrentDrive;
- else
- drive = (DX & 0xff) - 1;
-
- if (!ValidDrive(drive)) {
- Error(InvalidDrive, EC_MediaError , EL_Disk);
- AX = 0xffff;
- 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;
- avail = info.f_bavail * info.f_bsize / 1024;
-
- #ifdef DOSDEBUG
- fprintf(stderr,"statfs: size: %8d avail: %8d\n",size,avail);
- #endif
-
- AX = SectorsPerCluster;
- CX = SectorSize;
-
- BX = (avail / (CX * AX));
- DX = (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
- Error (InvalidDrive, EC_MediaError, EL_Disk);
-}
-
-void GetDefaultDrive(struct sigcontext_struct *context)
-{
- AX &= 0xff00;
- AX |= CurrentDrive;
- Error (0,0,0);
-}
-
-void GetDriveAllocInfo(struct sigcontext_struct *context)
-{
- int drive;
- long size;
- BYTE mediaID;
- struct statfs info;
-
- drive = DX & 0xff;
-
- if (!ValidDrive(drive)) {
- AX = SectorsPerCluster;
- CX = SectorSize;
- DX = 0;
- 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;
-
- #ifdef DOSDEBUG
- fprintf(stderr,"statfs: size: %8d\n",size);
- #endif
-
- AX = SectorsPerCluster;
- CX = SectorSize;
- DX = (size / (CX * AX));
-
- mediaID = 0xf0;
-
- DS = segment(mediaID);
- BX = offset(mediaID);
- Error (0,0,0);
- }
-}
-
-void GetDefDriveAllocInfo(struct sigcontext_struct *context)
-{
- DX = CurrentDrive;
- 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 :-) */
-}
-
-void ReadFile(struct sigcontext_struct *context)
-{
- char *ptr;
- int size;
-
- /* can't read from stdout / stderr */
-
- if (((BX & 0xffff) == 1) ||((BX & 0xffff) == 2)) {
- Error (InvalidHandle, EL_Unknown, EC_Unknown);
- AX = InvalidHandle;
- SetCflag;
- return;
- }
-
- ptr = (char *) pointer (DS,DX);
-
- if ((BX & 0xffff) == 0) {
- *ptr = EOF;
- Error (0,0,0);
- AX = 1;
- ResetCflag;
- return;
- } else {
- size = read(BX, ptr, CX);
- if (size == 0) {
- Error (ReadFault, EC_Unknown, EL_Unknown);
- AX = ExtendedError;
- return;
- }
-
- if (size == -1) {
- switch (errno) {
- case EAGAIN:
- Error (ShareViolation, EC_Temporary, EL_Unknown);
- break;
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- AX = ExtendedError;
- SetCflag;
- return;
- }
- Error (0,0,0);
- AX = size;
- ResetCflag;
- }
-}
-
-void WriteFile(struct sigcontext_struct *context)
-{
- char *ptr;
- int x,size;
-
- ptr = (char *) pointer (DS,DX);
-
- if ((BX & 0xffff) == 0) {
- Error (InvalidHandle, EC_Unknown, EL_Unknown);
- AX = InvalidHandle;
- SetCflag;
- return;
- }
-
- if ((BX & 0xffff) < 3) {
- for (x = 0;x != CX;x++) {
- fprintf(stderr, "%c", *ptr++);
- }
- fflush(stderr);
-
- Error (0,0,0);
- AX = CX;
- ResetCflag;
- } else {
- size = write(BX, ptr , CX);
- if (size == 0) {
- Error (WriteFault, EC_Unknown, EL_Unknown);
- AX = ExtendedError;
- return;
- }
-
- if (size == -1) {
- switch (errno) {
- case EAGAIN:
- Error (ShareViolation, EC_Temporary, EL_Unknown);
- break;
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- 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);
- AX = 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;
- }
-}
-
-void SeekFile(struct sigcontext_struct *context)
-{
- char UnixFileName[256];
- int drive, handle, status, fileoffset;
-
-
- ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive);
-
- {
- switch (AX & 0xff) {
- 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 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;
- }
-}
-
-void GetFileAttributes(struct sigcontext_struct *context)
-{
- char UnixFileName[256];
- int drive,handle;
-
- ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive);
-
- {
- CX = 0x0;
- ResetCflag;
- }
-}
-
-void SetFileAttributes(struct sigcontext_struct *context)
-{
- ResetCflag;
-}
-
-void DosIOCTL(struct sigcontext_struct *context)
-{
- AX = UnknownUnit;
- SetCflag;
-}
-
-void DupeFileHandle(struct sigcontext_struct *context)
-{
- AX = dup(BX);
- ResetCflag;
-}
-
-void GetSystemDate(struct sigcontext_struct *context)
-{
- struct tm *now;
- time_t ltime;
-
- 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;
-}
-
-void GetSystemTime(struct sigcontext_struct *context)
-{
- struct tm *now;
- time_t ltime;
-
- ltime = time(NULL);
- now = localtime(<ime);
-
- CX = (now->tm_hour << 8) | now->tm_min;
- DX = now->tm_sec << 8;
-}
-
-void GetExtendedErrorInfo(struct sigcontext_struct *context)
-{
- AX = ExtendedError;
- BX = (0x100 * ErrorClass) | Action;
- CX &= 0x00ff;
- CX |= (0x100 * ErrorLocus);
-}
-
-void GetInDosFlag(struct sigcontext_struct *context)
-{
- const BYTE InDosFlag = 0;
-
- ES = segment(InDosFlag);
- BX = offset(InDosFlag);
-}
-
-void CreateFile(struct sigcontext_struct *context)
-{
- char UnixFileName[256];
- int drive,handle;
-
- ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive);
-
- {
- 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;
- }
-}
-
-void OpenExistingFile(struct sigcontext_struct *context)
-{
- char UnixFileName[256];
- int drive, handle;
-
- ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive);
-
- {
- handle = open(UnixFileName, O_RDWR);
-
- 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;
- }
-}
-
-void CloseFile(struct sigcontext_struct *context)
-{
- if (close(BX) == -1) {
- switch (errno) {
- case EBADF:
- Error (InvalidHandle, EC_AppError, EL_Unknown);
- break;
- default:
- Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
- break;
- }
- AX = ExtendedError;
- SetCflag;
- return;
- }
- Error (0,0,0);
- AX = NoError;
- ResetCflag;
-}
-
-void RenameFile(struct sigcontext_struct *context)
-{
- rename((char *) pointer(DS,DX), (char *) pointer(ES,DI));
- ResetCflag;
-}
-
-void GetTrueFileName(struct sigcontext_struct *context)
-{
- 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);
-
- {
- if (mkdir(unixname,0) == -1) {
- AX = CanNotMakeDir;
- SetCflag;
- }
- ResetCflag;
- }
-}
-
-void ChangeDir(struct sigcontext_struct *context)
-{
- int drive;
- char *dirname;
- char unixname[256];
-
- dirname = (char *) pointer(DS,DX);
-
- ParseDOSFileName(unixname,dirname,&drive);
-
- {
- strcpy(unixname,DosDrives[drive].CurrentDirectory);
- ResetCflag;
- }
-}
-
-void RemoveDir(struct sigcontext_struct *context)
-{
- int drive;
- char *dirname;
- char unixname[256];
-
- dirname = (char *) pointer(DS,DX);
-
- ParseDOSFileName(unixname,dirname,&drive);
-
- {
- 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;
- }
-}
-
-void AllocateMemory(struct sigcontext_struct *context)
-{
- char *ptr;
-
- if ((ptr = (void *) memalign((size_t) (BX * 0x10), 0x10)) == NULL) {
- AX = OutOfMemory;
- BX = 0x0; /* out of memory */
- SetCflag;
- }
- AX = segment((unsigned long) ptr);
- ResetCflag;
-}
-
-void FreeMemory(struct sigcontext_struct *context)
-{
- free((void *)(ES * 0x10));
- ResetCflag;
-}
-
-void ResizeMemoryBlock(struct sigcontext_struct *context)
-{
- char *ptr;
-
- if ((ptr = (void *) realloc((void *)(ES * 0x10), (size_t) BX * 0x10)) == NULL) {
- AX = OutOfMemory;
- BX = 0x0; /* out of memory */
- SetCflag;
- }
- BX = segment((unsigned long) ptr);
- ResetCflag;
-}
-
-void ExecProgram(struct sigcontext_struct *context)
-{
- execl("wine",(char *) pointer(DS,DX));
-}
-
-void GetReturnCode(struct sigcontext_struct *context)
-{
- AX = NoError; /* normal exit */
-}
-
-void FindFirst(struct sigcontext_struct *context)
-{
-
-}
-
-void FindNext(struct sigcontext_struct *context)
-{
-
-}
-
-void GetSysVars(struct sigcontext_struct *context)
-{
- ES = 0x0;
- BX = 0x0;
-}
-
-void GetFileDateTime(struct sigcontext_struct *context)
-{
- int drive;
- char *dirname;
- char unixname[256];
- struct stat filestat;
- struct tm *now;
-
- dirname = (char *) pointer(DS,DX);
- ParseDOSFileName(unixname, dirname, &drive);
-
- {
- stat(unixname, &filestat);
-
- 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;
-
- ResetCflag;
- }
-}
-
-void SetFileDateTime(struct sigcontext_struct *context)
-{
- int drive;
- char *dirname;
- char unixname[256];
- struct utimbuf filetime;
-
- dirname = (char *) pointer(DS,DX);
-
- ParseDOSFileName(unixname, dirname, &drive);
-
- {
- filetime.actime = 0L;
- filetime.modtime = filetime.actime;
-
- utime(unixname,&filetime);
- ResetCflag;
- }
-}
-
-void CreateTempFile(struct sigcontext_struct *context)
-{
- char UnixFileName[256],TempString[256];
- int drive,handle;
-
- ParseDOSFileName(UnixFileName, (char *) pointer(DS,DX), &drive);
-
- sprintf(TempString,"%s%s%d",UnixFileName,"eb",(int) getpid());
-
- {
- handle = open(TempString, O_CREAT | O_TRUNC | O_RDWR);
-
- if (handle == -1) {
- AX = WriteProtected;
- SetCflag;
- return;
- }
-
- strcpy((char *) pointer(DS,DX), UnixFileName);
-
- AX = handle;
- ResetCflag;
- }
-}
-
-void CreateNewFile(struct sigcontext_struct *context)
-{
- char UnixFileName[256];
- int drive,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;
- }
-}
-
-void FileLock(struct sigcontext_struct *context)
-{
-
-}
-
-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;
- else
- drive = (DX & 0xff)-1;
-
- if (!ValidDrive(drive)) {
- AX = InvalidDrive;
- SetCflag;
- return;
- }
-
- strcpy((char *) pointer(DS,SI), DosDrives[drive].CurrentDirectory);
- ResetCflag;
- AX = 0x0100;
-}
-
-void GetCurrentPSP(struct sigcontext_struct *context)
-{
-
-}
-
-void GetDiskSerialNumber(struct sigcontext_struct *context)
-{
- int drive;
- struct diskinfo *ptr;
-
- if ((BX & 0xff)== 0)
- drive = CurrentDrive;
- else
- drive = (BX & 0xff)-1;
-
- if (!ValidDrive(drive)) {
- AX = InvalidDrive;
- SetCflag;
- return;
- }
-
- {
- ptr =(struct diskinfo *) pointer(DS,SI);
-
- ptr->infolevel = 0;
- ptr->serialnumber = 0xEBEBEB00 | drive;
- strcpy(ptr->label,"NO NAME ");
- strcpy(ptr->fstype,"FAT16 ");
-
- AX = NoError;
- ResetCflag;
- }
-}
-
-void SetDiskSerialNumber(struct sigcontext_struct *context)
-{
- AX &= 0xff00;
- AX |= 1;
- 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);
-
- ah = (AX >> 8) & 0xff;
-
- if (ah == 0x59) {
- GetExtendedErrorInfo(context);
- return 1;
- } else {
-
- Error (0,0,0);
-
- switch(ah) {
-
- case 0x00: /* TERMINATE PROGRAM */
- exit(0);
-
- case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */
- case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */
- case 0x03: /* READ CHARACTER FROM STDAUX */
- case 0x04: /* WRITE CHARACTER TO STDAUX */
- case 0x05: /* WRITE CHARACTER TO PRINTER */
- case 0x06: /* DIRECT CONSOLE IN/OUTPUT */
- case 0x07: /* DIRECT CHARACTER INPUT, WITHOUT ECHO */
- case 0x08: /* CHARACTER INPUT WITHOUT ECHO */
- case 0x09: /* WRITE STRING TO STANDARD OUTPUT */
- case 0x0a: /* BUFFERED INPUT */
- case 0x0b: /* GET STDIN STATUS */
- case 0x0c: /* FLUSH BUFFER AND READ STANDARD INPUT */
- case 0x0d: /* DISK BUFFER FLUSH */
- break;
-
- /* no FCB support for CP/M hackers */
-
- case 0x0f: /* OPEN FILE USING FCB */
- case 0x10: /* CLOSE FILE USING FCB */
- case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
- case 0x12: /* FIND NEXT MATCHING FILE USING FCB */
- case 0x13: /* DELETE FILE USING FCB */
- case 0x14: /* SEQUENTIAL READ FROM FCB FILE */
- case 0x15: /* SEQUENTIAL WRITE TO FCB FILE */
- case 0x16: /* CREATE OR TRUNCATE FILE USING FCB */
- case 0x17: /* RENAME FILE USING FCB */
- case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
- case 0x21: /* READ RANDOM RECORD FROM FCB FILE */
- case 0x22: /* WRITE RANDOM RECORD TO FCB FILE */
- case 0x23: /* GET FILE SIZE FOR FCB */
- case 0x24: /* SET RANDOM RECORD NUMBER FOR FCB */
- case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */
- case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
- case 0x29: /* PARSE FILENAME INTO FCB */
- case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
-
- case 0x2e: /* SET VERIFY FLAG */
- break;
-
- case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
- case 0x1d:
- case 0x1e:
- case 0x20:
- case 0x2b: /* SET SYSTEM DATE */
- case 0x2d: /* SET SYSTEM TIME */
- case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER
- "SWITCHAR" - SET SWITCH CHARACTER
- "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
- case 0x54: /* GET VERIFY FLAG */
- case 0x61: /* UNUSED */
- case 0x6b: /* NULL FUNCTION */
- AX &= 0xff00;
- break;
-
- case 0x67: /* SET HANDLE COUNT */
- ResetCflag;
- break;
-
- case 0x0e: /* SELECT DEFAULT DRIVE */
- SetDefaultDrive(context);
- break;
-
- case 0x19: /* GET CURRENT DEFAULT DRIVE */
- GetDefaultDrive(context);
- break;
-
- case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
- GetDefDriveAllocInfo(context);
- break;
-
- case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
- GetDriveAllocInfo(context);
- break;
-
- case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
- case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
- GetDrivePB(context);
- break;
-
- case 0x25: /* SET INTERRUPT VECTOR */
- /* Ignore any attempt to set a segment vector */
- return 1;
-
- case 0x26: /* CREATE NEW PROGRAM SEGMENT PREFIX */
- break;
-
- case 0x2a: /* GET SYSTEM DATE */
- GetSystemDate(context);
- break;
-
- case 0x2c: /* GET SYSTEM TIME */
- GetSystemTime(context);
- break;
-
- case 0x30: /* GET DOS VERSION */
- AX = DosVersion; /* Hey folks, this is DOS V3.3! */
- BX = 0x0012; /* 0x123456 is Wine's serial # */
- CX = 0x3456;
- break;
-
- case 0x31: /* TERMINATE AND STAY RESIDENT */
- break;
-
- case 0x33: /* MULTIPLEXED */
- switch (AX & 0xff) {
- case 0x00: /* GET CURRENT EXTENDED BREAK STATE */
- if (!(AX & 0xff))
- DX &= 0xff00;
- break;
-
- case 0x01: /* SET EXTENDED BREAK STATE */
- break;
-
- case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE */
- DX &= 0xff00;
- break;
-
- case 0x05: /* GET BOOT DRIVE */
- DX &= 0xff00;
- DX |= 2; /* c: is Wine's bootdrive */
- break;
-
- case 0x06: /* GET TRUE VERSION NUMBER */
- BX = DosVersion;
- DX = 0x00;
- break;
- default:
- break;
- }
- break;
-
- case 0x34: /* GET ADDRESS OF INDOS FLAG */
- GetInDosFlag(context);
- break;
-
- case 0x35: /* GET INTERRUPT VECTOR */
- /* Return a NULL segment selector - this will bomb,
- if anyone ever tries to use it */
- ES = 0;
- BX = 0;
- break;
-
- case 0x36: /* GET FREE DISK SPACE */
- GetFreeDiskSpace(context);
- break;
-
- case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
- AX &= 0xff00;
- AX |= 0x02; /* no country support available */
- SetCflag;
- break;
-
- case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
- MakeDir(context);
- break;
-
- case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
- RemoveDir(context);
- break;
-
- case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
- ChangeDir(context);
- break;
-
- case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
- CreateFile(context);
- break;
-
- case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
- OpenExistingFile(context);
- break;
-
- case 0x3e: /* "CLOSE" - CLOSE FILE */
- case 0x68: /* "FFLUSH" - COMMIT FILE */
- case 0x6a: /* COMMIT FILE */
-
- CloseFile(context);
- break;
-
- case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
- ReadFile(context);
- break;
-
- case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */
- WriteFile(context);
- break;
-
- case 0x41: /* "UNLINK" - DELETE FILE */
- UnlinkFile(context);
- break;
-
- case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
- SeekFile(context);
- break;
-
- case 0x43: /* FILE ATTRIBUTES */
- switch (AX & 0xff) {
- case 0x00:
- GetFileAttributes(context);
- break;
- case 0x01:
- SetFileAttributes(context);
- break;
- }
- break;
-
- case 0x44: /* IOCTL */
- DosIOCTL(context);
- break;
-
- case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
- case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
- DupeFileHandle(context);
- break;
-
- case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
- GetCurrentDirectory(context);
- AX = 0x0100; /* many Microsoft products for Windows rely
- on this */
- break;
-
- case 0x48: /* ALLOCATE MEMORY */
- AllocateMemory(context);
- break;
-
- case 0x49: /* FREE MEMORY */
- FreeMemory(context);
- break;
-
- case 0x4a: /* RESIZE MEMORY BLOCK */
- ResizeMemoryBlock(context);
- break;
-
- case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
- ExecProgram(context);
- break;
-
- case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
- exit(AX & 0xff);
-
- case 0x4d: /* GET RETURN CODE */
- GetReturnCode(context);
- break;
-
- case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
- FindFirst(context);
- break;
-
- case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */
- FindNext(context);
- break;
-
- case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
- GetSysVars(context);
- break;
-
- case 0x56: /* "RENAME" - RENAME FILE */
- RenameFile(context);
- break;
-
- case 0x57: /* FILE DATE AND TIME */
- switch (AX & 0xff) {
- case 0x00:
- GetFileDateTime(context);
- break;
- case 0x01:
- SetFileDateTime(context);
- break;
- }
- break;
-
- case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
- switch (AX & 0xff) {
- case 0x00:
- AX = 0x01;
- break;
- case 0x02:
- AX &= 0xff00;
- break;
- case 0x01:
- case 0x03:
- break;
- }
- ResetCflag;
- break;
-
- case 0x59: /* GET EXTENDED ERROR INFO */
- GetExtendedErrorInfo(context);
- break;
-
- case 0x5a: /* CREATE TEMPORARY FILE */
- CreateTempFile(context);
- break;
-
- case 0x5b: /* CREATE NEW FILE */
- CreateNewFile(context);
- break;
-
- case 0x5c: /* "FLOCK" - RECORD LOCKING */
- FileLock(context);
- break;
-
- case 0x5d: /* NETWORK */
- case 0x5e:
- case 0x5f:
- AX &= 0xff00;
- AX |= NoNetwork; /* network software not installed */
- SetCflag;
- break;
-
- case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
- GetTrueFileName(context);
- break;
-
- case 0x62: /* GET CURRENT PSP ADDRESS */
- GetCurrentPSP(context);
- break;
-
- case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
- GetExtendedCountryInfo(context);
- break;
-
- case 0x66: /* GLOBAL CODE PAGE TABLE */
- switch (AX & 0xff) {
- case 0x01:
- BX = CodePage;
- DX = BX;
- ResetCflag;
- break;
- case 0x02:
- CodePage = BX;
- ResetCflag;
- break;
- }
- break;
-
- case 0x69: /* DISK SERIAL NUMBER */
- switch (AX & 0xff) {
- case 0x00:
- GetDiskSerialNumber(context);
- break;
- case 0x01:
- SetDiskSerialNumber(context);
- break;
- }
- break;
-
- default:
- fprintf(stderr,"Unable to handle int 0x21 %x\n", context->sc_eax);
- return 1;
- };
- }
- return 1;
-}
diff --git a/loader/library.c b/loader/library.c
index 6e96351..fe7813e 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -20,7 +20,7 @@
{
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 a0c986c..9d97305 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -14,7 +14,6 @@
#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 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 @@
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 @@
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 @@
(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 @@
BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0, SRCINVERT);
DeleteDC(hMemDC);
DeleteDC(hMemDC2);
-
- ReleaseDC(0, hdc);
+ ReleaseDC(GetDesktopWindow(), hdc);
return hIcon;
}
@@ -407,165 +408,6 @@
/**********************************************************************
- * 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
*/
HANDLE
@@ -586,6 +428,10 @@
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 @@
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 f091d1d..5edee7fa 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -7,7 +7,7 @@
#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 @@
#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 @@
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 @@
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 @@
*/
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 @@
* 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 @@
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 @@
*/
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 @@
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 @@
/**********************************************************************
* 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 @@
/*
* Fill in selector info.
*/
- s = malloc(sizeof(*s));
+ s = &Segments[i];
if (code_flag)
{
contents = MODIFY_LDT_CONTENTS_CODE;
@@ -305,13 +449,12 @@
(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 @@
/**********************************************************************
* GetNextSegment
*/
-struct segment_descriptor_s *
+SEGDESC *
GetNextSegment(unsigned int flags, unsigned int limit)
{
return CreateNewSegment(0, 0, limit);
@@ -494,11 +637,11 @@
/**********************************************************************
* 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 @@
/**********************************************************************
* 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 @@
/**********************************************************************
* 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 @@
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 7b2727c..b2a492e 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 @@
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 7124317..60b606b 100644
--- a/loader/wine.c
+++ b/loader/wine.c
@@ -28,11 +28,14 @@
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 @@
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 @@
* 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.
@@ -123,9 +125,23 @@
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 @@
/*
* Establish header pointers.
*/
- wpnt->filename = strdup(filename);
+ wpnt->filename = strdup(buffer);
wpnt->name = NULL;
if(modulename) wpnt->name = strdup(modulename);
@@ -181,7 +197,7 @@
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 @@
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 @@
{
int segment;
char *p;
+ char *sysresname;
+ char syspath[256];
char exe_path[256];
#ifdef WINESTAT
char * cp;
@@ -273,19 +285,20 @@
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 @@
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 @@
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 @@
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 @@
/*
* 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 @@
#endif
break;
+ case NE_RELTYPE_NAMEADD:
+ additive = 1;
+
case NE_RELTYPE_NAME:
if (GetModuleName(wpnt, rep->target1, dll_name)
== NULL)
@@ -543,30 +582,50 @@
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 @@
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 @@
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 0000000..edf4b6d
--- /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 b624e09..f3ff2c7 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 0000000..1fd5f48
--- /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 169ebc3..bf11b37 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -75,7 +75,7 @@
else if (count)
count = 0;
}
-
+
/*
* If we couldn't find enough segments, then we need to create some.
*/
@@ -87,18 +87,22 @@
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 @@
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 @@
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 0000000..53eda76
--- /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 12180d0..8cdcee9 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 0000000..c0db9d5
--- /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 f5f80fc..0000000
--- 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 0000000..e072274
--- /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 559fac0..adc4368 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.
- *
- * Finally we need to store the current drive letter in this module.
- *
* WARNING : Many options of OpenFile are not yet implemeted.
*
- *
+ * NOV 93 Erik Bos (erik@(trashcan.)hacktic.nl
+ * - removed ParseDosFileName, and DosDrive structures.
+ * - structures dynamically configured at runtime.
+ * - _lopen modified to use GetUnixFileName.
+ *
+ * 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 @@
***************************************************************************/
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__lread (WORD hFile, LPSTR lpBuffer, WORD wBytes)
{
int result;
+
+#ifdef DEBUG_FILE
+ fprintf(stderr, "_lread: handle %d, buffer = %ld, length = %d\n",
+ hFile, lpBuffer, wBytes);
+#endif
result = read (hFile, lpBuffer, wBytes);
-#ifdef DEBUG_FILE
- fprintf(stderr, "_lread: hFile = %d, lpBuffer = %s, wBytes = %d\n",
- hFile, lpBuffer, wBytes);
-#endif
- return result;
-}
+ 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__lclose (WORD hFile)
{
+#ifdef DEBUG_FILE
+ fprintf(stderr, "_lclose: handle %d\n", hFile);
+#endif
+
close (hFile);
}
@@ -166,7 +118,9 @@
{
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 @@
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 2441d77..addfdbc 100644
--- a/loader/int1a.c
+++ b/misc/int1a.c
@@ -51,7 +51,7 @@
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/misc/int21.c b/misc/int21.c
new file mode 100644
index 0000000..4d1ae70
--- /dev/null
+++ b/misc/int21.c
@@ -0,0 +1,1227 @@
+#include <time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include "prototypes.h"
+#include "regfunc.h"
+#include "windows.h"
+#include "wine.h"
+#include "int21.h"
+
+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;
+ ErrorClass = class;
+ Action = SA_Ask4Retry;
+ ErrorLocus = el;
+}
+
+void GetFreeDiskSpace(struct sigcontext_struct *context)
+{
+ int drive;
+ long size,available;
+
+ if (!(EDX & 0xffL))
+ drive = DOS_GetDefaultDrive();
+ else
+ drive = (EDX & 0xffL) - 1;
+
+ if (!DOS_ValidDrive(drive)) {
+ Error(InvalidDrive, EC_MediaError , EL_Disk);
+ EAX |= 0xffffL;
+ return;
+ }
+
+ if (!DOS_GetFreeSpace(drive, &size, &available)) {
+ Error(GeneralFailure, EC_MediaError , EL_Disk);
+ EAX |= 0xffffL;
+ return;
+ }
+
+ EAX = (EAX & 0xffff0000L) | SectorsPerCluster;
+ ECX = (ECX & 0xffff0000L) | SectorSize;
+
+ EBX = (EBX & 0xffff0000L) | (available / (CX * AX));
+ EDX = (EDX & 0xffff0000L) | (size / (CX * AX));
+ Error (0,0,0);
+}
+
+void SetDefaultDrive(struct sigcontext_struct *context)
+{
+ 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)
+{
+ EAX = (EAX & 0xffffff00L) | DOS_GetDefaultDrive();
+ Error (0,0,0);
+}
+
+void GetDriveAllocInfo(struct sigcontext_struct *context)
+{
+ int drive;
+ long size, available;
+ BYTE mediaID;
+
+ drive = EDX & 0xffL;
+
+ if (!DOS_ValidDrive(drive)) {
+ EAX = (EAX & 0xffff0000L) | SectorsPerCluster;
+ ECX = (ECX & 0xffff0000L) | SectorSize;
+ EDX = (EDX & 0xffff0000L);
+ Error (InvalidDrive, EC_MediaError, EL_Disk);
+ return;
+ }
+
+ if (!DOS_GetFreeSpace(drive, &size, &available)) {
+ Error(GeneralFailure, EC_MediaError , EL_Disk);
+ EAX |= 0xffffL;
+ return;
+ }
+
+ EAX = (EAX & 0xffff0000L) | SectorsPerCluster;
+ ECX = (ECX & 0xffff0000L) | SectorSize;
+ EDX = (EDX & 0xffff0000L) | (size / (CX * AX));
+
+ mediaID = 0xf0;
+
+ DS = segment(mediaID);
+ EBX = offset(mediaID);
+ Error (0,0,0);
+}
+
+void GetDefDriveAllocInfo(struct sigcontext_struct *context)
+{
+ EDX = DOS_GetDefaultDrive();
+ GetDriveAllocInfo(context);
+}
+
+void GetDrivePB(struct sigcontext_struct *context)
+{
+ Error (InvalidDrive, EC_MediaError, EL_Disk);
+ EAX = (EAX & 0xffff0000L) | 0xffL;
+ /* I'm sorry but I only got networked drives :-) */
+}
+
+void ReadFile(struct sigcontext_struct *context)
+{
+ char *ptr;
+ int size;
+
+ /* can't read from stdout / stderr */
+
+ if ((BX == 1) || (BX == 2)) {
+ Error (InvalidHandle, EL_Unknown, EC_Unknown);
+ EAX = (EAX & 0xffff0000L) | InvalidHandle;
+ SetCflag;
+ return;
+ }
+
+ ptr = (char *) pointer (DS,DX);
+
+ if (BX == 0) {
+ *ptr = EOF;
+ Error (0,0,0);
+ EAX = (EAX & 0xffff0000L) | 1;
+ ResetCflag;
+ return;
+ } else {
+ size = read(BX, ptr, CX);
+ if (size == 0) {
+ Error (ReadFault, EC_Unknown, EL_Unknown);
+ EAX = (EAX & 0xffffff00L) | ExtendedError;
+ return;
+ }
+
+ if (size == -1) {
+ switch (errno) {
+ case EAGAIN:
+ Error (ShareViolation, EC_Temporary, EL_Unknown);
+ break;
+ case EBADF:
+ Error (InvalidHandle, EC_AppError, EL_Unknown);
+ break;
+ default:
+ Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
+ break;
+ }
+ EAX = (EAX & 0xffffff00L) | ExtendedError;
+ SetCflag;
+ return;
+ }
+ Error (0,0,0);
+ EAX = (EAX & 0xffff0000L) | size;
+ ResetCflag;
+ }
+}
+
+void WriteFile(struct sigcontext_struct *context)
+{
+ char *ptr;
+ int x,size;
+
+ ptr = (char *) pointer (DS,DX);
+
+ if (BX == 0) {
+ Error (InvalidHandle, EC_Unknown, EL_Unknown);
+ EAX = InvalidHandle;
+ SetCflag;
+ return;
+ }
+
+ if (BX < 3) {
+ for (x = 0;x != CX;x++) {
+ fprintf(stderr, "%c", *ptr++);
+ }
+ fflush(stderr);
+
+ Error (0,0,0);
+ EAX = (EAX & 0xffffff00L) | CX;
+ ResetCflag;
+ } else {
+ size = write(BX, ptr , CX);
+ if (size == 0) {
+ Error (WriteFault, EC_Unknown, EL_Unknown);
+ EAX = (EAX & 0xffffff00L) | ExtendedError;
+ return;
+ }
+
+ if (size == -1) {
+ switch (errno) {
+ case EAGAIN:
+ Error (ShareViolation, EC_Temporary, EL_Unknown);
+ break;
+ case EBADF:
+ Error (InvalidHandle, EC_AppError, EL_Unknown);
+ 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);
+ EAX = (EAX & 0xffff0000L) | size;
+ ResetCflag;
+ }
+}
+
+void UnlinkFile(struct sigcontext_struct *context)
+{
+ 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)
+{
+ int handle, status, fileoffset;
+
+ 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 EINVAL:
+ Error (DataInvalid, EC_AppError, EL_Unknown);
+ break;
+ default:
+ Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
+ break;
+ }
+ EAX = (EAX & 0xffffff00L) | ExtendedError; SetCflag;
+ return;
+ }
+ Error (0,0,0);
+ ResetCflag;
+}
+
+void GetFileAttributes(struct sigcontext_struct *context)
+{
+ EAX &= 0xfffff00L;
+ ResetCflag;
+}
+
+void SetFileAttributes(struct sigcontext_struct *context)
+{
+ ResetCflag;
+}
+
+void DosIOCTL(struct sigcontext_struct *context)
+{
+ fprintf(stderr,"int21: IOCTL\n");
+ EAX = (EAX & 0xfffff00L) | UnknownUnit;
+ SetCflag;
+}
+
+void DupeFileHandle(struct sigcontext_struct *context)
+{
+ EAX = (EAX & 0xffff0000L) | dup(BX);
+ ResetCflag;
+}
+
+void GetSystemDate(struct sigcontext_struct *context)
+{
+ struct tm *now;
+ time_t ltime;
+
+ ltime = time(NULL);
+ now = localtime(<ime);
+
+ 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)
+{
+ struct tm *now;
+ time_t ltime;
+
+ ltime = time(NULL);
+ now = localtime(<ime);
+
+ ECX = (ECX & 0xffffff00L) | (now->tm_hour << 8) | now->tm_min;
+ EDX = (EDX & 0xffffff00L) | now->tm_sec << 8;
+}
+
+void GetExtendedErrorInfo(struct sigcontext_struct *context)
+{
+ EAX = (EAX & 0xffffff00L) | ExtendedError;
+ EBX = (EBX & 0xffff0000L) | (0x100 * ErrorClass) | Action;
+ ECX = (ECX & 0xffff00ffL) | (0x100 * ErrorLocus);
+}
+
+void GetInDosFlag(struct sigcontext_struct *context)
+{
+ const BYTE InDosFlag = 0;
+
+ ES = (ES & 0xffff0000L) | segment(InDosFlag);
+ EBX = (EBX & 0xffff0000L) | offset(InDosFlag);
+}
+
+void CreateFile(struct sigcontext_struct *context)
+{
+ int handle;
+
+ 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)
+{
+ int handle;
+
+ 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)
+{
+ if (close(BX) == -1) {
+ switch (errno) {
+ case EBADF:
+ Error (InvalidHandle, EC_AppError, EL_Unknown);
+ break;
+ default:
+ Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
+ break;
+ }
+ EAX = (EAX & 0xffffff00L) | ExtendedError;
+ SetCflag;
+ return;
+ }
+ Error (0,0,0);
+ EAX = (EAX & 0xffffff00L) | NoError;
+ ResetCflag;
+}
+
+void RenameFile(struct sigcontext_struct *context)
+{
+ 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)
+{
+ char *dirname;
+
+ 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(dirname,0) == -1) {
+ EAX = (EAX & 0xffffff00L) | CanNotMakeDir;
+ SetCflag;
+ return;
+ }
+ ResetCflag;
+}
+
+void ChangeDir(struct sigcontext_struct *context)
+{
+ fprintf(stderr,"int21: changedir %s\n",(char *) pointer(DS,DX) );
+
+ DOS_ChangeDir(DOS_GetDefaultDrive(), (char *) pointer (DS,DX));
+}
+
+void RemoveDir(struct sigcontext_struct *context)
+{
+ char *dirname;
+
+ fprintf(stderr,"int21: removedir %s\n",(char *) pointer(DS,DX) );
+
+ 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) {
+ EAX = (EAX & 0xffffff00L) | OutOfMemory;
+ EBX = (EBX & 0xffffff00L); /* out of memory */
+ SetCflag;
+ }
+ 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;
+}
+
+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) {
+ EAX = (EAX & 0xffffff00L) | OutOfMemory;
+ EBX = (EBX & 0xffffff00L); /* out of memory */
+ SetCflag;
+ }
+ EBX = (EBX & 0xffff0000L) | segment((unsigned long) ptr);
+ ResetCflag;
+}
+
+void ExecProgram(struct sigcontext_struct *context)
+{
+ execl("wine", GetUnixFileName((char *) pointer(DS,DX)) );
+}
+
+void GetReturnCode(struct sigcontext_struct *context)
+{
+ EAX = (EAX & 0xffffff00L) | NoError; /* normal exit */
+}
+
+void FindFirst(struct sigcontext_struct *context)
+{
+
+}
+
+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;
+ EBX = (EBX & 0xffff0000L);
+}
+
+void GetFileDateTime(struct sigcontext_struct *context)
+{
+ char *filename;
+ struct stat filestat;
+ struct tm *now;
+
+ if ((filename = GetUnixFileName( (char *) pointer(DS,DX) ))== NULL) {
+ EAX = (EAX & 0xffffff00L) | FileNotFound;
+ SetCflag;
+ return;
+ }
+ stat(filename, &filestat);
+
+ now = localtime (&filestat.st_mtime);
+
+ ECX = (ECX & 0xffff0000L) | (now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2;
+ EDX = (EDX & 0xffff0000L) | (now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday;
+
+ ResetCflag;
+}
+
+void SetFileDateTime(struct sigcontext_struct *context)
+{
+ char *filename;
+ struct utimbuf filetime;
+
+ filename = GetUnixFileName((char *) pointer(DS,DX));
+
+ filetime.actime = 0L;
+ filetime.modtime = filetime.actime;
+
+ utime(filename, &filetime);
+ ResetCflag;
+}
+
+void CreateTempFile(struct sigcontext_struct *context)
+{
+ char *filename, temp[256];
+ int drive, handle;
+
+ sprintf(temp,"%s\\win%d.tmp",TempDirectory,(int) getpid());
+
+ fprintf(stderr,"CreateTempFile %s\n",temp);
+
+ 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)
+{
+ int handle;
+
+ 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)
+{
+
+}
+
+void GetExtendedCountryInfo(struct sigcontext_struct *context)
+{
+ ResetCflag;
+}
+
+void GetCurrentDirectory(struct sigcontext_struct *context)
+{
+ int drive;
+
+ if ((EDX & 0xffL) == 0)
+ drive = DOS_GetDefaultDrive();
+ else
+ drive = (EDX & 0xffL)-1;
+
+ if (!DOS_ValidDrive(drive)) {
+ EAX = (EAX & 0xffffff00L) | InvalidDrive;
+ SetCflag;
+ return;
+ }
+
+ DOS_GetCurrentDir(drive, (char *) pointer(DS,SI) );
+ ResetCflag;
+}
+
+void GetCurrentPSP(struct sigcontext_struct *context)
+{
+
+}
+
+void GetDiskSerialNumber(struct sigcontext_struct *context)
+{
+ int drive;
+ unsigned long serialnumber;
+ struct diskinfo *ptr;
+
+ if ((EBX & 0xffL) == 0)
+ drive = DOS_GetDefaultDrive();
+ else
+ drive = (EBX & 0xffL) - 1;
+
+ if (!DOS_ValidDrive(drive)) {
+ EAX = (EAX & 0xffffff00L) |InvalidDrive;
+ SetCflag;
+ return;
+ }
+
+ DOS_GetSerialNumber(drive,&serialnumber);
+
+ ptr = (struct diskinfo *) pointer(DS,SI);
+
+ ptr->infolevel = 0;
+ ptr->serialnumber = serialnumber;
+ strcpy(ptr->label,"NO NAME ");
+ strcpy(ptr->fstype,"FAT16 ");
+
+ EAX = (EAX & 0xffffff00L) | NoError;
+ ResetCflag;
+}
+
+void SetDiskSerialNumber(struct sigcontext_struct *context)
+{
+ EAX = (EAX & 0xffffff00L) | 1L;
+ ResetCflag;
+}
+
+/************************************************************************/
+
+int do_int21(struct sigcontext_struct * context){
+ int ah;
+
+ fprintf(stderr,"int21: doing AX=%04x BX=%04x CX=%04x DX=%04x\n",
+ EAX & 0xffffL,EBX & 0xffffL,ECX & 0xffffL,EDX & 0xffffL);
+
+ ah = (EAX >> 8) & 0xffL;
+
+ if (ah == 0x59) {
+ GetExtendedErrorInfo(context);
+ return 1;
+ } else {
+
+ Error (0,0,0);
+
+ switch(ah) {
+
+ case 0x00: /* TERMINATE PROGRAM */
+ exit(0);
+
+ case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */
+ case 0x02: /* WRITE CHARACTER TO STANDARD OUTPUT */
+ case 0x03: /* READ CHARACTER FROM STDAUX */
+ case 0x04: /* WRITE CHARACTER TO STDAUX */
+ case 0x05: /* WRITE CHARACTER TO PRINTER */
+ case 0x06: /* DIRECT CONSOLE IN/OUTPUT */
+ case 0x07: /* DIRECT CHARACTER INPUT, WITHOUT ECHO */
+ case 0x08: /* CHARACTER INPUT WITHOUT ECHO */
+ case 0x09: /* WRITE STRING TO STANDARD OUTPUT */
+ case 0x0a: /* BUFFERED INPUT */
+ case 0x0b: /* GET STDIN STATUS */
+ case 0x0c: /* FLUSH BUFFER AND READ STANDARD INPUT */
+ case 0x0d: /* DISK BUFFER FLUSH */
+ break;
+
+ /* no FCB support for CP/M hackers */
+
+ case 0x0f: /* OPEN FILE USING FCB */
+ case 0x10: /* CLOSE FILE USING FCB */
+ case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
+ case 0x12: /* FIND NEXT MATCHING FILE USING FCB */
+ case 0x13: /* DELETE FILE USING FCB */
+ case 0x14: /* SEQUENTIAL READ FROM FCB FILE */
+ case 0x15: /* SEQUENTIAL WRITE TO FCB FILE */
+ case 0x16: /* CREATE OR TRUNCATE FILE USING FCB */
+ case 0x17: /* RENAME FILE USING FCB */
+ case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
+ case 0x21: /* READ RANDOM RECORD FROM FCB FILE */
+ case 0x22: /* WRITE RANDOM RECORD TO FCB FILE */
+ case 0x23: /* GET FILE SIZE FOR FCB */
+ case 0x24: /* SET RANDOM RECORD NUMBER FOR FCB */
+ case 0x27: /* RANDOM BLOCK READ FROM FCB FILE */
+ case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
+ case 0x29: /* PARSE FILENAME INTO FCB */
+ case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
+
+ case 0x2e: /* SET VERIFY FLAG */
+ break;
+
+ case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
+ case 0x1d:
+ case 0x1e:
+ case 0x20:
+ case 0x2b: /* SET SYSTEM DATE */
+ case 0x2d: /* SET SYSTEM TIME */
+ case 0x37: /* "SWITCHAR" - GET SWITCH CHARACTER
+ "SWITCHAR" - SET SWITCH CHARACTER
+ "AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
+ case 0x54: /* GET VERIFY FLAG */
+ case 0x61: /* UNUSED */
+ case 0x6b: /* NULL FUNCTION */
+ EAX &= 0xff00;
+ break;
+
+ case 0x67: /* SET HANDLE COUNT */
+ ResetCflag;
+ break;
+
+ case 0x0e: /* SELECT DEFAULT DRIVE */
+ SetDefaultDrive(context);
+ break;
+
+ case 0x19: /* GET CURRENT DEFAULT DRIVE */
+ GetDefaultDrive(context);
+ break;
+
+ case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
+ GetDefDriveAllocInfo(context);
+ break;
+
+ case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
+ GetDriveAllocInfo(context);
+ break;
+
+ case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
+ case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
+ GetDrivePB(context);
+ break;
+
+ case 0x25: /* SET INTERRUPT VECTOR */
+ /* Ignore any attempt to set a segment vector */
+ return 1;
+
+ case 0x26: /* CREATE NEW PROGRAM SEGMENT PREFIX */
+ break;
+
+ case 0x2a: /* GET SYSTEM DATE */
+ GetSystemDate(context);
+ break;
+
+ case 0x2c: /* GET SYSTEM TIME */
+ GetSystemTime(context);
+ break;
+
+ case 0x30: /* GET DOS VERSION */
+ fprintf(stderr,"int21: GetDosVersion\n");
+ EAX = DosVersion; /* Hey folks, this is DOS V3.3! */
+ EBX = 0x0012; /* 0x123456 is Wine's serial # */
+ ECX = 0x3456;
+ break;
+
+ case 0x31: /* TERMINATE AND STAY RESIDENT */
+ break;
+
+ case 0x33: /* MULTIPLEXED */
+ switch (EAX & 0xff) {
+ case 0x00: /* GET CURRENT EXTENDED BREAK STATE */
+ if (!(EAX & 0xffL))
+ EDX &= 0xff00L;
+ break;
+
+ case 0x01: /* SET EXTENDED BREAK STATE */
+ break;
+
+ case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE */
+ EDX &= 0xff00L;
+ break;
+
+ case 0x05: /* GET BOOT DRIVE */
+ EDX = (EDX & 0xff00L) | 2;
+ /* c: is Wine's bootdrive */
+ break;
+
+ case 0x06: /* GET TRUE VERSION NUMBER */
+ EBX = DosVersion;
+ EDX = 0x00;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 0x34: /* GET ADDRESS OF INDOS FLAG */
+ GetInDosFlag(context);
+ break;
+
+ case 0x35: /* GET INTERRUPT VECTOR */
+ /* Return a NULL segment selector - this will bomb,
+ if anyone ever tries to use it */
+ ES = 0;
+ EBX = 0;
+ break;
+
+ case 0x36: /* GET FREE DISK SPACE */
+ GetFreeDiskSpace(context);
+ break;
+
+ case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
+ EAX &= 0xff00;
+ EAX |= 0x02; /* no country support available */
+ SetCflag;
+ break;
+
+ case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
+ MakeDir(context);
+ break;
+
+ case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
+ RemoveDir(context);
+ break;
+
+ case 0x3b: /* "CHDIR" - SET CURRENT DIRECTORY */
+ ChangeDir(context);
+ break;
+
+ case 0x3c: /* "CREAT" - CREATE OR TRUNCATE FILE */
+ CreateFile(context);
+ break;
+
+ case 0x3d: /* "OPEN" - OPEN EXISTING FILE */
+ OpenExistingFile(context);
+ break;
+
+ case 0x3e: /* "CLOSE" - CLOSE FILE */
+ CloseFile(context);
+ break;
+
+ case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */
+ ReadFile(context);
+ break;
+
+ case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */
+ WriteFile(context);
+ break;
+
+ case 0x41: /* "UNLINK" - DELETE FILE */
+ UnlinkFile(context);
+ break;
+
+ case 0x42: /* "LSEEK" - SET CURRENT FILE POSITION */
+ SeekFile(context);
+ break;
+
+ case 0x43: /* FILE ATTRIBUTES */
+ switch (EAX & 0xff) {
+ case 0x00:
+ GetFileAttributes(context);
+ break;
+ case 0x01:
+ SetFileAttributes(context);
+ break;
+ }
+ break;
+
+ case 0x44: /* IOCTL */
+ DosIOCTL(context);
+ break;
+
+ case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
+ case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
+ DupeFileHandle(context);
+ break;
+
+ case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
+ GetCurrentDirectory(context);
+ EAX = (EAX & 0xffff0000L) | 0x0100;
+ /* many Microsoft products for Windows rely on this */
+ break;
+
+ case 0x48: /* ALLOCATE MEMORY */
+ AllocateMemory(context);
+ break;
+
+ case 0x49: /* FREE MEMORY */
+ FreeMemory(context);
+ break;
+
+ case 0x4a: /* RESIZE MEMORY BLOCK */
+ ResizeMemoryBlock(context);
+ break;
+
+ case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
+ ExecProgram(context);
+ break;
+
+ case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
+ fprintf(stderr,"int21: DosExit\n");
+ exit(EAX & 0xff);
+ break;
+
+ case 0x4d: /* GET RETURN CODE */
+ GetReturnCode(context);
+ break;
+
+ case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
+ FindFirst(context);
+ break;
+
+ case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */
+ FindNext(context);
+ break;
+
+ case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
+ GetSysVars(context);
+ break;
+
+ case 0x56: /* "RENAME" - RENAME FILE */
+ RenameFile(context);
+ break;
+
+ case 0x57: /* FILE DATE AND TIME */
+ switch (EAX & 0xff) {
+ case 0x00:
+ GetFileDateTime(context);
+ break;
+ case 0x01:
+ SetFileDateTime(context);
+ break;
+ }
+ break;
+
+ case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
+ switch (EAX & 0xff) {
+ case 0x00:
+ EAX = (EAX & 0xffffff00L) | 0x01L;
+ break;
+ case 0x02:
+ EAX &= 0xff00L;
+ break;
+ case 0x01:
+ case 0x03:
+ break;
+ }
+ ResetCflag;
+ break;
+
+ case 0x59: /* GET EXTENDED ERROR INFO */
+ GetExtendedErrorInfo(context);
+ break;
+
+ case 0x5a: /* CREATE TEMPORARY FILE */
+ CreateTempFile(context);
+ break;
+
+ case 0x5b: /* CREATE NEW FILE */
+ CreateNewFile(context);
+ break;
+
+ case 0x5c: /* "FLOCK" - RECORD LOCKING */
+ FileLock(context);
+ break;
+
+ case 0x5d: /* NETWORK */
+ case 0x5e:
+ EAX = (EAX & 0xfffff00L) | NoNetwork; /* network software not installed */
+ SetCflag;
+ break;
+
+ case 0x5f: /* NETWORK */
+ switch (EAX & 0xffL) {
+ case 0x07: /* ENABLE DRIVE */
+ if (!DOS_EnableDrive(EDX & 0xffL)) {
+ Error(InvalidDrive, EC_MediaError , EL_Disk);
+ EAX = (EAX & 0xfffff00L) | InvalidDrive;
+ SetCflag;
+ break;
+ } else {
+ ResetCflag;
+ break;
+ }
+ case 0x08: /* DISABLE DRIVE */
+ if (!DOS_DisableDrive(EDX & 0xffL)) {
+ Error(InvalidDrive, EC_MediaError , EL_Disk);
+ EAX = (EAX & 0xfffff00L) | InvalidDrive;
+ SetCflag;
+ break;
+ } else {
+ ResetCflag;
+ break;
+ }
+ default:
+ EAX = (EAX & 0xfffff00L) | NoNetwork; /* network software not installed */
+ SetCflag;
+ break;
+ }
+ break;
+
+ case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
+ GetTrueFileName(context);
+ break;
+
+ case 0x62: /* GET CURRENT PSP ADDRESS */
+ GetCurrentPSP(context);
+ break;
+
+ case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
+ GetExtendedCountryInfo(context);
+ break;
+
+ case 0x66: /* GLOBAL CODE PAGE TABLE */
+ switch (EAX & 0xffL) {
+ case 0x01:
+ EBX = CodePage;
+ EDX = EBX;
+ ResetCflag;
+ break;
+ case 0x02:
+ CodePage = EBX;
+ ResetCflag;
+ break;
+ }
+ break;
+
+ case 0x68: /* "FFLUSH" - COMMIT FILE */
+ ResetCflag;
+ break;
+
+ case 0x69: /* DISK SERIAL NUMBER */
+ switch (EAX & 0xff) {
+ case 0x00:
+ GetDiskSerialNumber(context);
+ break;
+ case 0x01:
+ SetDiskSerialNumber(context);
+ break;
+ }
+ break;
+
+ case 0x6a: /* COMMIT FILE */
+ ResetCflag;
+ break;
+
+ default:
+ fprintf(stderr,"Unable to handle int 0x21 %x\n", context->sc_eax);
+ return 1;
+ };
+ }
+ 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 281b012..cde5164 100644
--- a/misc/message.c
+++ b/misc/message.c
@@ -21,6 +21,8 @@
HWND hWndNo;
HWND hWndCancel;
HICON hIcon;
+ RECT rectIcon;
+ RECT rectStr;
} MSGBOX;
typedef MSGBOX FAR* LPMSGBOX;
@@ -46,7 +48,7 @@
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 @@
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 @@
*((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 @@
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 @@
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 @@
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 ac50d86..12d12fe 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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 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 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 58087ee..501448c 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -6,8 +6,7 @@
#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 @@
MDESC *USER_Heap = NULL;
+extern BOOL ATOM_Init();
+extern BOOL GDI_Init();
+
/***********************************************************************
* USER_HeapInit
*/
@@ -24,7 +26,6 @@
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 @@
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 @@
/* 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 8d386ae..a829a5b 100644
--- a/misc/xt.c
+++ b/misc/xt.c
@@ -41,6 +41,8 @@
XT_display = XtDisplay( topLevelWidget );
XT_screen = XtScreen( topLevelWidget );
+ DOS_InitFS();
+ Comm_Init();
_WinMain( argc, argv );
}
@@ -58,12 +60,6 @@
XBell(XT_display, 100);
}
-WORD RegisterWindowMessage( LPSTR str )
-{
- printf( "RegisterWindowMessage: '%s'\n", str );
- return 0xc000;
-}
-
/***********************************************************************
* GetTickCount (USER.13)
*/
@@ -94,11 +90,10 @@
{
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 0000000..458761d
--- /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 53e9ba1..c4ed6bc 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -38,10 +38,10 @@
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 @@
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 @@
}
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 9de4c1c..ffec3e9 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -46,6 +46,7 @@
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 @@
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 ec9de9c..5776eb8 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -11,9 +11,32 @@
/***********************************************************************
+ * 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 @@
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 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 @@
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 b496e2e..73c98aa 100644
--- a/objects/dcvalues.c
+++ b/objects/dcvalues.c
@@ -45,6 +45,8 @@
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 1299a26..10bc76b 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -331,6 +331,36 @@
}
+/***********************************************************************/
+
+#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 @@
{
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 @@
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 32bb4b8..cc539a4 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -153,7 +153,6 @@
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 @@
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 3b101b2..511cf3f 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -177,3 +177,21 @@
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 08274ca..3a7b9ef 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -31,6 +31,7 @@
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 bbb2740..07aef58 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -229,7 +229,8 @@
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 @@
}
}
while (strPtr);
-
+ if (flags & DT_CALCRECT) rect->bottom = y;
return 1;
}
@@ -314,10 +315,10 @@
{
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 @@
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 @@
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 @@
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 44a53ab..38c7ca9 100755
--- a/sysres.dll
+++ b/sysres.dll
Binary files differ
diff --git a/test/Imakefile b/test/Imakefile
new file mode 100644
index 0000000..d45263d
--- /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 0000000..535cc47
--- /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 6afbf24..ea5dc2f 100755
--- a/test/widget.exe
+++ b/test/widget.exe
Binary files differ
diff --git a/tools/Imakefile b/tools/Imakefile
new file mode 100644
index 0000000..7b739a1
--- /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 0000000..b16652f
--- /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 0c5d34a..30570a1 100644
--- a/windows/Makefile
+++ b/windows/Makefile
@@ -2,7 +2,7 @@
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 0000000..eb78dc8
--- /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 23a2c49..4ca2d9f 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -9,6 +9,7 @@
#include "class.h"
#include "user.h"
#include "win.h"
+#include "dce.h"
static HCLASS firstClass = 0;
@@ -18,19 +19,50 @@
* 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)
{
- *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;
+ }
+ }
}
+
+ /* Then search global classes */
+
+ if ((atom = GlobalFindAtom( 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;
+ }
+ }
+ }
+
return 0;
}
+
/***********************************************************************
* CLASS_FindClassPtr
*
@@ -52,37 +84,50 @@
*/
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_CLASSDC)
- newClass->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
- else newClass->hdc = 0;
+ if (newClass->wc.style & CS_GLOBALCLASS)
+ newClass->atomName = GlobalAddAtom( class->lpszClassName );
+ else newClass->atomName = AddAtom( class->lpszClassName );
- /* 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 );
+ if (newClass->wc.style & CS_CLASSDC)
+ newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
+ else newClass->hdce = 0;
+
+ /* Menu name should also be set to zero. */
+ newClass->wc.lpszClassName = NULL;
if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
-
firstClass = handle;
- return handle; /* Should be an atom */
+ return newClass->atomName;
}
@@ -118,8 +163,10 @@
}
/* 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 @@
*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 2126c28..3c759a6 100644
--- a/windows/clipping.c
+++ b/windows/clipping.c
@@ -10,6 +10,7 @@
#include "windows.h"
#include "win.h"
+#include "message.h"
/***********************************************************************
@@ -34,6 +35,7 @@
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 @@
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 @@
*/
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)
{
- HDC hdc = GetDC( hwnd );
- if (hdc)
- {
- SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
- ReleaseDC( hwnd, hdc );
- }
+ if (!(hrgnClip = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
+ retval = CombineRgn( hrgn, hrgnClip, 0, RGN_COPY );
}
- return CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
+ else
+ {
+ 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)
+ {
+ HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
+ DCX_INTERSECTRGN | DCX_USESTYLE );
+ if (hdc)
+ {
+ SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
+ ReleaseDC( hwnd, hdc );
+ }
+ }
+ }
+ DeleteObject( hrgnClip );
+ return retval;
}
diff --git a/windows/dc.c b/windows/dc.c
index 1a65b41..4224b3a 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 aaea4b0..7b24f1d 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -23,6 +23,53 @@
/***********************************************************************
+ * 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
*/
void DCE_Init()
@@ -33,84 +80,133 @@
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 );
}
}
/***********************************************************************
+ * GetDCEx (USER.359)
+ */
+/* 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;
+
+ if (hwnd)
+ {
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ }
+ 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)
+ {
+ if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
+ if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break;
+ }
+ }
+ 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( hdc, DC_MAGIC ))) return 0;
+
+ if (wndPtr)
+ {
+ 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 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))
+ {
+ 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_DC
+ printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd, hrgnClip, flags, hdc);
+#endif
+ return hdc;
+}
+
+
+/***********************************************************************
* GetDC (USER.66)
*/
HDC GetDC( HWND hwnd )
{
- HANDLE hdce;
- HDC hdc = 0;
- DCE * dce;
- DC * dc;
- WND * wndPtr = NULL;
- CLASS * classPtr;
-
+ 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 (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- if (wndPtr->hdc) hdc = wndPtr->hdc;
- else if (classPtr->hdc) hdc = classPtr->hdc;
+ if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN;
+ if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
}
-
- if (!hdc)
- {
- for (hdce = firstDCE; (hdce); hdce = dce->hNext)
- {
- dce = (DCE *) USER_HEAP_ADDR( hdce );
- if (!dce) return 0;
- if (!dce->inUse) break;
- }
- if (!hdce) return 0;
- dce->hwndCurrent = hwnd;
- dce->inUse = TRUE;
- hdc = dce->hdc;
- }
-
- /* Initialize DC */
-
- if (!(dc = (DC *) GDI_GetObjPtr( dce->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);
- }
- else
- {
- dc->u.x.drawable = DefaultRootWindow( XT_display );
- dc->u.x.widget = 0;
- XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors );
- }
-
-#ifdef DEBUG_WIN
- printf( "GetDC(%d): returning %d\n", hwnd, hdc );
-#endif
- return hdc;
+ return GetDCEx( hwnd, 0, flags );
}
@@ -119,33 +215,23 @@
*/
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 3d3a280..e2f9a39 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 @@
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 @@
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 @@
{
if (wParam)
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText)
{
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
@@ -123,7 +171,6 @@
case WM_GETTEXTLENGTH:
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText)
{
textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
@@ -134,7 +181,6 @@
case WM_SETTEXT:
{
- wndPtr = WIN_FindWndPtr(hwnd);
if (wndPtr->hText)
USER_HEAP_FREE(wndPtr->hText);
@@ -142,10 +188,18 @@
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 108c964..83a0389 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -8,7 +8,6 @@
#include "windows.h"
#include "dialog.h"
-#include "prototypes.h"
#include "win.h"
@@ -149,25 +148,19 @@
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 @@
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 3130189..5f3aa3d 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -18,6 +18,8 @@
#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_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 @@
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_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 @@
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 @@
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 @@
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_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 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 @@
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;
+ winHasCursor = event->window;
- MSG_AddMsg( &msg );
+ 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 @@
{
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_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 @@
{
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 @@
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,12 +637,24 @@
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)
*/
void SetDoubleClickTime (WORD interval)
diff --git a/windows/focus.c b/windows/focus.c
index ce1a91a2..639b2df 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -32,7 +32,7 @@
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 a2a1e32..9fd5d27 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -23,8 +23,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 7307461..09b49e7 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 @@
#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_CreateMsgQueue
+ *
+ * Create a message queue.
+ */
+static HANDLE MSG_CreateMsgQueue( int size )
+{
+ 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_GetMessageType
+ * MSG_CreateSysMsgQueue
*
+ * Create the system message queue. Must be called only once.
*/
-int MSG_GetMessageType( int msg )
+BOOL MSG_CreateSysMsgQueue( 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;
+ 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 @@
*
* 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 @@
/* 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 @@
*
* 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 @@
*
* 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 @@
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;
-
+ HANDLE hQueue;
+
+ if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
+
/* Free the old message queue */
- if (msgQueue) free(msgQueue);
+ if ((hQueue = GetTaskQueue(0)) != 0)
+ {
+ GlobalUnlock( hQueue );
+ GlobalFree( hQueue );
+ }
- if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return FALSE;
-
- queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
- msgQueue = (MESSAGEQUEUE *) malloc(queueSize);
- if (!msgQueue) return FALSE;
-
- 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 (!(hQueue = MSG_CreateMsgQueue( size ))) return FALSE;
+ SetTaskQueue( 0, hQueue );
+ appMsgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue );
return TRUE;
}
@@ -206,9 +299,9 @@
*/
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 @@
*/
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 @@
*/
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)
{
- if ((!first && !last) ||
- ((msgQueue->msg >= first) && (msgQueue->msg <= last)))
+ 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 (!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;
+ /* 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(pos);
- return TRUE;
+ 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 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 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 @@
msg.pt.x = 0;
msg.pt.y = 0;
- return MSG_AddMsg( &msg, 0 );
+ return MSG_AddMsg( appMsgQueue, &msg, 0 );
}
@@ -380,16 +559,39 @@
*/
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 @@
*/
DWORD GetMessagePos(void)
{
- return msgQueue->GetMessagePosVal;
+ return appMsgQueue->GetMessagePosVal;
}
@@ -407,14 +609,27 @@
*/
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 4f21b13..5a8e60a 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -10,6 +10,7 @@
#include <X11/Xlib.h>
#include "win.h"
+#include "message.h"
/* Last CTLCOLOR id */
#define CTLCOLOR_MAX CTLCOLOR_STATIC
@@ -23,27 +24,21 @@
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 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 2aeb88ee..da64961 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 @@
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))
{
- CallWindowProc(pTimer->proc, pTimer->hwnd, pTimer->msg,
- pTimer->id, GetTickCount());
+ pTimer->next = pNextTimer;
+ pNextTimer = pTimer;
}
- else
- PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, 0 );
+ else
+ {
+ TIMER * ptr = pNextTimer;
+ while (ptr->next && (pTimer->expires >= ptr->next->expires))
+ ptr = ptr->next;
+ pTimer->next = ptr;
+ ptr->next = pTimer;
+ }
+}
+
+
+/***********************************************************************
+ * 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 @@
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 @@
/***********************************************************************
* 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 @@
/* 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 @@
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 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 d7fe3a2..8411e48 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -10,11 +10,11 @@
#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 @@
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
*
@@ -43,6 +39,76 @@
/***********************************************************************
+ * 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
*
* Find a window that needs repaint.
@@ -55,8 +121,6 @@
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 @@
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 @@
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 @@
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++;
+ /* Get class or window DC if needed */
+ if (classPtr->wc.style & CS_OWNDC)
+ {
+ wndPtr->flags |= WIN_OWN_DC;
+ wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
+ }
+ else if (classPtr->wc.style & CS_CLASSDC)
+ {
+ wndPtr->flags |= WIN_CLASS_DC;
+ wndPtr->hdce = classPtr->hdce;
+ }
+ else wndPtr->hdce = 0;
+
/* Insert the window in the linked list */
- if (parent)
- {
- wndPtr->hwndNext = parentPtr->hwndChild;
- parentPtr->hwndChild = hwnd;
- }
- else /* Top-level window */
- {
- wndPtr->hwndNext = firstWindow;
- firstWindow = hwnd;
- }
-
- if (!strcasecmp(className, "SCROLLBAR"))
- {
- SCROLLBAR_CreateScrollBar(className, windowName, hwnd);
- goto WinCreated;
- }
- if (!strcasecmp(className, "LISTBOX"))
- {
- LISTBOX_CreateListBox(className, windowName, hwnd);
- goto WinCreated;
- }
+ WIN_LinkWindow( hwnd, HWND_TOP );
+
if (!strcasecmp(className, "COMBOBOX"))
{
- COMBOBOX_CreateComboBox(className, windowName, hwnd);
- goto WinCreated;
+ height = 16;
}
- /* Create the widgets */
+
+#ifdef USE_XLIB
+ {
+ 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 );
+ }
+#else
+ /* Create the widgets */
if (style & WS_CHILD)
{
@@ -223,6 +317,7 @@
XtNwidth, width,
XtNheight, height,
XtNborderColor, borderCol,
+ XtNmappedWhenManaged, FALSE,
NULL );
}
else
@@ -235,6 +330,7 @@
XtNwidth, width,
XtNheight, height,
XtNborderWidth, 0,
+ XtNmappedWhenManaged, FALSE,
NULL );
}
}
@@ -247,6 +343,7 @@
XtNx, x,
XtNy, y,
XtNcolormap, COLOR_WinColormap,
+ XtNmappedWhenManaged, FALSE,
NULL );
wndPtr->compositeWidget = XtVaCreateManagedWidget(className,
formWidgetClass,
@@ -296,8 +393,24 @@
NULL );
}
}
+ if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
+ if (wndPtr->compositeWidget) XtRealizeWidget( wndPtr->compositeWidget );
+ XtRealizeWidget( wndPtr->winWidget );
+ wndPtr->window = XtWindow( wndPtr->winWidget );
+#endif /* USE_XLIB */
-WinCreated:
+ 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 @@
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 @@
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;
}
-
- EVENT_AddHandlers( wndPtr->winWidget, hwnd );
- if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
+#ifdef USE_XLIB
+ EVENT_AddHandlers( wndPtr->window, hwnd );
+#else
+ EVENT_AddHandlers( wndPtr->winWidget, hwnd );
+#endif
+
WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE );
+
+ if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
return hwnd;
}
@@ -350,7 +489,6 @@
BOOL DestroyWindow( HWND hwnd )
{
WND * wndPtr;
- HWND * curWndPtr;
CLASS * classPtr;
/* Initialisation */
@@ -366,30 +504,24 @@
/* 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;
@@ -397,100 +529,6 @@
/***********************************************************************
- * 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)
*/
void CloseWindow(HWND hWnd)
@@ -498,7 +536,6 @@
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 @@
*/
BOOL OpenIcon(HWND hWnd)
{
- WND * wndPtr = WIN_FindWndPtr(hWnd);
if (!IsIconic(hWnd)) return FALSE;
ShowWindow(hWnd, SW_SHOWNORMAL);
return(TRUE);
@@ -523,35 +559,9 @@
{
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)
*/
void UpdateWindow( HWND hwnd )
@@ -578,8 +588,10 @@
*/
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 @@
}
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 @@
}
-/***********************************************************************
- * 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 @@
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 @@
HWND GetParent(HWND hwnd)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
+ if (!wndPtr) return 0;
return wndPtr->hwndParent;
}
@@ -838,14 +799,9 @@
*/
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 0000000..0b474e2
--- /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 0000000..d9958be
--- /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