Release 950727
Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>
* [ipc/*]
New directory. This directory contains the new inter-wine
communications support. It enables DDE protocols between two wine
instances. Currently it is limited to DDE, but can be enhanced to
support OLE between 2 different wine instances. This is very
important for libwine.a DDE/OLE support.
* [tools/ipcl]
A script to delete garbage IPC handles (shared memory, semaphores
and message queues). The current inter-wine communication is not
perfect, and sometimes leaves garbage behind.
* [if1632/relay.c] [include/atom.h] [include/global.h]
[loader/selector.c] [loader/task.c] [loader/module.c]
[loader/signal.c] [memory/global.c] [misc/atom.c]
[windows/class.c] [windows/message.c] [windows/win.c]
[Imakefile]
Hooks for inter-wine DDE support, current Global.*Atom functions
renamed to Local.*Atom since Global.*Atom are used for Inter-Wine
DDE communication. (The first call to these functions sets up the
IPC structures - which otherwise cause unneeded overhead.
Mon Jul 17 19:55:21 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
* [controls/menu.c]
Don't crash if a NULL string is passed to menu functions.
* [memory/selector.c]
We now use a bit in ldt_flags_copy to indicate free LDT entries.
Fixed a bug in SELECTOR_ReallocBlock that could cause it to
overwrite valid LDT entries when growing a block.
* [miscemu/instr.c]
Emulate int xx instruction by storing the interrupt vector in
CS:IP and returning directly. This allows a program to install an
interrupt vector.
* [windows/win.c]
Added function WIN_GetTopParent to get the top-level parent of a
window.
Sun Jul 16 18:17:17 1995 Gregory Trubetskoy <grisha@mira.com>
* [loader/resource.c]
Added LoadIconHandler. It doesn't do anything yet, but now you
can use borland help files with winhelp.exe.
Sun Jul 16 11:58:45 1995 Anand Kumria <akumria@ozemail.com.au>
* [misc/main.c]
Fixed to return 386 Enhanced mode correctly. Also return the same
type of CPU, for both Enhanced and Standard mode, namely a 386.
Sun Jul 16 00:02:04 1995 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [Configure] [include/options.h] [include/wineopts.h]
[misc/main.c][misc/spy.c]
Removed support of spy file. Redirected spy messages to stddeb.
Removed -spy option. Added -debugmsg +spy option.
* [debugger/dbg.y][debugger/debug.l]
Enabled segmented addresses (seg:offs) for break and x commands.
* [if1632/gdi.spec] [objects/region.c] [windows/graphics.c]
[include/region.h]
FrameRgn, REGION_FrameRgn: New functions
* [if1632/kernel.spec]
IsWinOldApTask: Return false
* [if1632/mouse.spec]
CplApplet: Removed
* [if1632/user.spec] [windows/win.c]
ShowOwnedPopups: New function
* [if1632/winsock.spec] [misc/winsocket.c]
inet_addr, select: New prototypes in relay code
Fixed memory layout for netdb functions (getXbyY).
WINSOCK_ioctlsocket: Translated FIONREAD, FIONBIO, and FIOASYNC
* [objects/clipping.c]
RectVisible: Fixed call to LPToDP
* [rc/winerc.c]
main: Removed extra argument to getopt for Linux.
Tue Jul 11 00:14:41 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [controls/listbox.c]
Yet another fix for ListBoxDirectory().
* [loader/module.c] [if1632/kernel.spec]
Make GetModuleHandle() accept instance handles as parameter.
* [if1632/relay.c] [loader/task.c]
Put a magic cookie at the bottom of the 32 bit stack, and check on
each return from a 32 bit function whether it's still there. Complain
if it's not.
* [if1632/user.spec]
Wrong entry for CloseDriver().
* [misc/dos_fs.c] [loader/task.c] [include/dos_fs.h] [misc/file.c]
[miscemu/int21.c]
Large parts of dos_fs.c simplified. Changed it to use one
current drive/directory per task, which is set to the module path on
task creation.
Prevent CorelPaint from closing stdin.
open() with O_CREAT set must be passed three parameters.
DOS FindFirst()/FindNext() could crash when FA_LABEL was set. Fixed,
it's in DOS_readdir() now.
* [misc/profile.c]
Some badly written software (Lotus Freelance Graphics) passes a bogus
size parameter that caused Wine to write off the end of a segment.
Fixed. (It's probably too paranoid now.)
* [multimedia/mmsystem.c] [multimedia/time.c] [multimedia/joystick.c]
[multimedia/Imakefile] [if1632/winprocs.spec]
16 bit entry point for MMSysTimeCallback.
Split off time.c and joystick.c from mmsystem.c.
* [objects/dib.c]
GetDIBits(): call XGetImage() via CallTo32_LargeStack.
* [windows/cursor.c]
DestroyCursor(): do nothing for builtin cursors.
* [windows/mdi.c]
Half of WM_MDISETMENU implemented.
* [windows/win.c]
EnumWindows() and EnumTaskWindows() never enumerated any windows.
Fixed.
* [windows/*.c]
Fixed GetParent() to return correct values for owned windows.
* [windows/message.c]
Don't try to activate disabled top-level windows.
* [windows/nonclient.c]
Work around a bug in gcc-2.7.0.
* [tools/build.c] [include/stackframe.h] [memory/global.c]
[loader/task.c] [memory/selector.c]
Some Visual Basic programs (and possibly others, too) expect ES to be
preserved by a call to an API function, so we have to save it.
In GlobalFree() and FreeSelector(), we must clear CURRENT_STACK16->es
to prevent segfaults if ES contained the selector to be freed.
Sun Jul 9 20:21:20 1995 Jon Tombs <jon@gtex02.us.es>
* [*/*]
Added missing prototypes to header files and relevant includes
to reduce compile time warnings.
Sun Jul 9 18:32:56 1995 Michael Patra <micky@marie.physik.tu-berlin.de>
* [configure.in] [include/config.h] [*/Makefile.in]
New configuration scheme based on autoconf.
Sat Jul 8 14:12:45 1995 Morten Welinder <terra+@cs.cmu.edu>
* [miscemu/ioports.c]
Revamp to have only one in- and one out- variant, both really
implemented.
* [miscemu/instr.c]
INSTR_EmulateInstruction: Use new ioport interface. Implement
string io. Correct instruction pointer for 32-bit code.
* [include/miscemu.h]
Update port function prototypes.
* [include/registers.h]
Defined FS and GS.
Sat Jul 8 13:38:54 1995 Hans de Graaff <graaff@twi72.twi.tudelft.nl>
* [misc/dos_fs.c]
ChopOffSlash(): A path consisting off a single slash is left
intact, and multiple slashes are all removed.
diff --git a/ANNOUNCE b/ANNOUNCE
index 35713f1..a8b38b9 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,15 @@
-This is release 950706 of Wine the MS Windows emulator. This is still a
+This is release 950727 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "wine-new@amscons.com". Please don't forget
to include a ChangeLog entry. I'll make a new release every other Sunday.
-WHAT'S NEW with Wine-950706: (see ChangeLog for details)
- - Built-in debugger supports single-stepping (please test it on *BSD).
- - Winelib should compile again.
- - More OLE2 functions.
+WHAT'S NEW with Wine-950727: (see ChangeLog for details)
+ - New configuration scheme based on autoconf (please test it).
+ - DDE communication between separate Wine processes.
+ - Lots of file handling fixes.
+ - Fixes to built-in WINSOCK.DLL.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@@ -17,11 +18,11 @@
the release is available at the ftp sites. The sources will be available
from the following locations:
- sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950706.tar.gz
- tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950706.tar.gz
- ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950706.tar.gz
- ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950706.tar.gz
- aris.com:/pub/linux/ALPHA/Wine/development/Wine-950706.tar.gz
+ sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950727.tar.gz
+ tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
+ ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950727.tar.gz
+ ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950727.tar.gz
+ aris.com:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
diff --git a/ChangeLog b/ChangeLog
index 4eab56d..b093b41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,193 @@
----------------------------------------------------------------------
-Wed Jul 5 19:06:35 1995 Alexandre Julliard <alex@numenor>
+Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>
+
+ * [ipc/*]
+ New directory. This directory contains the new inter-wine
+ communications support. It enables DDE protocols between two wine
+ instances. Currently it is limited to DDE, but can be enhanced to
+ support OLE between 2 different wine instances. This is very
+ important for libwine.a DDE/OLE support.
+
+ * [tools/ipcl]
+ A script to delete garbage IPC handles (shared memory, semaphores
+ and message queues). The current inter-wine communication is not
+ perfect, and sometimes leaves garbage behind.
+
+ * [if1632/relay.c] [include/atom.h] [include/global.h]
+ [loader/selector.c] [loader/task.c] [loader/module.c]
+ [loader/signal.c] [memory/global.c] [misc/atom.c]
+ [windows/class.c] [windows/message.c] [windows/win.c]
+ [Imakefile]
+ Hooks for inter-wine DDE support, current Global.*Atom functions
+ renamed to Local.*Atom since Global.*Atom are used for Inter-Wine
+ DDE communication. (The first call to these functions sets up the
+ IPC structures - which otherwise cause unneeded overhead.
+
+Mon Jul 17 19:55:21 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
+
+ * [controls/menu.c]
+ Don't crash if a NULL string is passed to menu functions.
+
+ * [memory/selector.c]
+ We now use a bit in ldt_flags_copy to indicate free LDT entries.
+ Fixed a bug in SELECTOR_ReallocBlock that could cause it to
+ overwrite valid LDT entries when growing a block.
+
+ * [miscemu/instr.c]
+ Emulate int xx instruction by storing the interrupt vector in
+ CS:IP and returning directly. This allows a program to install an
+ interrupt vector.
+
+ * [windows/win.c]
+ Added function WIN_GetTopParent to get the top-level parent of a
+ window.
+
+Sun Jul 16 18:17:17 1995 Gregory Trubetskoy <grisha@mira.com>
+
+ * [loader/resource.c]
+ Added LoadIconHandler. It doesn't do anything yet, but now you
+ can use borland help files with winhelp.exe.
+
+Sun Jul 16 11:58:45 1996 Anand Kumria <akumria@ozemail.com.au>
+
+ * [misc/main.c]
+ Fixed to return 386 Enhanced mode correctly. Also return the same
+ type of CPU, for both Enhanced and Standard mode, namely a 386.
+
+Sun Jul 16 00:02:04 1995 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * [Configure] [include/options.h] [include/wineopts.h]
+ [misc/main.c][misc/spy.c]
+ Removed support of spy file. Redirected spy messages to stddeb.
+ Removed -spy option. Added -debugmsg +spy option.
+
+ * [debugger/dbg.y][debugger/debug.l]
+ Enabled segmented addresses (seg:offs) for break and x commands.
+
+ * [if1632/gdi.spec] [objects/region.c] [windows/graphics.c]
+ [include/region.h]
+ FrameRgn, REGION_FrameRgn: New functions
+
+ * [if1632/kernel.spec]
+ IsWinOldApTask: Return false
+
+ * [if1632/mouse.spec]
+ CplApplet: Removed
+
+ * [if1632/user.spec] [windows/win.c]
+ ShowOwnedPopups: New function
+
+ * [if1632/winsock.spec] [misc/winsocket.c]
+ inet_addr, select: New prototypes in relay code
+ Fixed memory layout for netdb functions (getXbyY).
+ WINSOCK_ioctlsocket: Translated FIONREAD, FIONBIO, and FIOASYNC
+
+ * [objects/clipping.c]
+ RectVisible: Fixed call to LPToDP
+
+ * [rc/winerc.c]
+ main: Removed extra argument to getopt for Linux.
+
+Tue Jul 11 00:14:41 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * [controls/listbox.c]
+ Yet another fix for ListBoxDirectory().
+
+ * [loader/module.c] [if1632/kernel.spec]
+ Make GetModuleHandle() accept instance handles as parameter.
+
+ * [if1632/relay.c] [loader/task.c]
+ Put a magic cookie at the bottom of the 32 bit stack, and check on
+ each return from a 32 bit function whether it's still there. Complain
+ if it's not.
+
+ * [if1632/user.spec]
+ Wrong entry for CloseDriver().
+
+ * [misc/dos_fs.c] [loader/task.c] [include/dos_fs.h] [misc/file.c]
+ [miscemu/int21.c]
+ Large parts of dos_fs.c simplified. Changed it to use one
+ current drive/directory per task, which is set to the module path on
+ task creation.
+ Prevent CorelPaint from closing stdin.
+ open() with O_CREAT set must be passed three parameters.
+ DOS FindFirst()/FindNext() could crash when FA_LABEL was set. Fixed,
+ it's in DOS_readdir() now.
+
+ * [misc/profile.c]
+ Some badly written software (Lotus Freelance Graphics) passes a bogus
+ size parameter that caused Wine to write off the end of a segment.
+ Fixed. (It's probably too paranoid now.)
+
+ * [multimedia/mmsystem.c] [multimedia/time.c] [multimedia/joystick.c]
+ [multimedia/Imakefile] [if1632/winprocs.spec]
+ 16 bit entry point for MMSysTimeCallback.
+ Split off time.c and joystick.c from mmsystem.c.
+
+ * [objects/dib.c]
+ GetDIBits(): call XGetImage() via CallTo32_LargeStack.
+
+ * [windows/cursor.c]
+ DestroyCursor(): do nothing for builtin cursors.
+
+ * [windows/mdi.c]
+ Half of WM_MDISETMENU implemented.
+
+ * [windows/win.c]
+ EnumWindows() and EnumTaskWindows() never enumerated any windows.
+ Fixed.
+
+ * [windows/*.c]
+ Fixed GetParent() to return correct values for owned windows.
+
+ * [windows/message.c]
+ Don't try to activate disabled top-level windows.
+
+ * [windows/nonclient.c]
+ Work around a bug in gcc-2.7.0.
+
+ * [tools/build.c] [include/stackframe.h] [memory/global.c]
+ [loader/task.c] [memory/selector.c]
+ Some Visual Basic programs (and possibly others, too) expect ES to be
+ preserved by a call to an API function, so we have to save it.
+ In GlobalFree() and FreeSelector(), we must clear CURRENT_STACK16->es
+ to prevent segfaults if ES contained the selector to be freed.
+
+Sun Jul 9 20:21:20 1995 Jon Tombs <jon@gtex02.us.es>
+
+ * [*/*]
+ Added missing prototypes to header files and relevant includes
+ to reduce compile time warnings.
+
+Sun Jul 9 18:32:56 1995 Michael Patra <micky@marie.physik.tu-berlin.de>
+
+ * [configure.in] [include/config.h] [*/Makefile.in]
+ New configuration scheme based on autoconf.
+
+Sat Jul 8 14:12:45 1995 Morten Welinder <terra+@cs.cmu.edu>
+
+ * [miscemu/ioports.c]
+ Revamp to have only one in- and one out- variant, both really
+ implemented.
+
+ * [miscemu/instr.c]
+ INSTR_EmulateInstruction: Use new ioport interface. Implement
+ string io. Correct instruction pointer for 32-bit code.
+
+ * [include/miscemu.h]
+ Update port function prototypes.
+
+ * [include/registers.h]
+ Defined FS and GS.
+
+Sat Jul 8 13:38:54 1995 Hans de Graaff <graaff@twi72.twi.tudelft.nl>
+
+ * [misc/dos_fs.c]
+ ChopOffSlash(): A path consisting off a single slash is left
+ intact, and multiple slashes are all removed.
+
+----------------------------------------------------------------------
+Wed Jul 5 19:06:35 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
* [controls/scroll.c]
Fixed drawing bug that caused part of a non-client scroll bar
diff --git a/Configure b/Configure
index 3a4c6f7..9a9435a 100644
--- a/Configure
+++ b/Configure
@@ -106,7 +106,6 @@
prompt "Where is COM1" CF_Com1 '/dev/cua0'
prompt "Where is COM2" CF_Com2 '/dev/cua1'
prompt "Where is LPT1" CF_Lpt1 '/dev/lp0'
- prompt "Log messages to which file (CON = stdout)" CF_File 'CON'
echo
sed -n -e 's/^ *\"\(WM_[A-Z0-9]*\)\".*/\1/p' < misc/spy.c | \
@@ -147,7 +146,6 @@
Lpt1=$CF_Lpt1
[spy]
-File=$CF_File
Exclude=$CF_Exclude
EOF
diff --git a/Imakefile b/Imakefile
index 492798d..5488945 100644
--- a/Imakefile
+++ b/Imakefile
@@ -7,13 +7,6 @@
#endif
DEFINES = AutoDefines -DUSE_READLINE
-#ifdef __ELF__
-LD = /usr/i486-linuxaout/bin/ld -m i386linux
-CDEBUGFLAGS = -O2 -Wall -b i486-linuxaout
-ASFLAGS = -b i486-linuxaout
-#else
-CDEBUGFLAGS = -O2 -Wall
-#endif
/*
* This is the second try at using Imakefiles. There are probably many
@@ -33,6 +26,7 @@
COMMONSUBDIRS = \
controls \
rc \
+ ipc \
loader \
misc \
multimedia \
@@ -53,6 +47,7 @@
COMMONOBJS = \
controls/controls.o \
+ ipc/ipc.o \
loader/loader.o \
misc/misc.o \
multimedia/multimedia.o \
@@ -122,4 +117,4 @@
distclean: clean
echo "/* autoconf.h generated automatically. Run Configure */" >autoconf.h
echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
- $(RM) `find . -name Makefile -print`
+ $(RM) config.* `find . -name Makefile -print`
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..bec1f10
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,87 @@
+# This Makefile understands the following targets:
+#
+# all (default): build wine
+# clean: remove all intermediate files
+# distclean: also remove all files created by configure
+# countryclean: remove all files which have to be remade if
+# a different LANGuage is selected
+# winelibclean: remove all files which differ for the emulator
+# and the library
+# depend: create the dependencies
+#
+# Author: Michael Patra <micky@marie.physik.tu-berlin.de>
+# <patra@itp1.physik.tu-berlin.de>
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+XPM_LIB = -lXpm
+XLIB = -lXext -lX11
+XDIR = -L@x_libraries@
+LDLIBS = -lm
+LD = @LD@
+LANG = @LANG@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+COMMONSUBDIRS = controls rc ipc loader misc multimedia objects windows
+
+EMUSUBDIRS = tools debugger if1632 memory miscemu
+
+LIBSUBDIRS = toolkit
+
+COMMONOBJS = controls/controls.o ipc/ipc.o loader/loader.o misc/misc.o \
+ multimedia/multimedia.o objects/objects.o rc/rc.o \
+ windows/windows.o
+
+EMUOBJS = debugger/debugger.o if1632/if1632.o memory/memory.o miscemu/miscemu.o
+
+LIBOBJS = toolkit/toolkit.o
+
+
+
+SUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS)
+
+OBJS = $(COMMONOBJS) $(EMUOBJS)
+
+
+all:
+ for i in $(SUBDIRS); do \
+ ( cd $(TOPSRC)/$$i; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' 'LANG=$(LANG)'); \
+ done
+ $(CC) -o wine $(OBJS) $(LDOPTIONS) $(XDIR) $(XPM_LIB) $(XLIB) $(LDLIBS)
+ nm wine | grep -v _compiled | sort >wine.sym
+
+depend:
+ for i in $(SUBDIRS); do \
+ ( cd $(TOPSRC)/$$i; $(MAKE) depend); \
+ done
+
+clean:
+ for i in $(SUBDIRS); do \
+ ( cd $(TOPSRC)/$$i; $(MAKE) clean); \
+ done
+ rm -f *.o \#*\# *~ wine wine.sym
+
+distclean:
+ for i in $(SUBDIRS); do \
+ ( cd $(TOPSRC)/$$i; $(MAKE) distclean); \
+ done
+ echo "/* autoconf.h generated automatically. Run Configure */" >autoconf.h
+ echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
+ rm -f *.o \#*\# *~ wine wine.sym
+ rm -f stamp-config config.* include/config.h Makefile
+
+countryclean:
+ for i in $(SUBDIRS); do \
+ ( cd $(TOPSRC)/$$i; $(MAKE) countryclean); \
+ done
+ rm -f wine wine.sym
+
+winelibclean:
+ for i in $(SUBDIRS); do \
+ ( cd $(TOPSRC)/$$i; $(MAKE) winelibclean); \
+ done
+
diff --git a/autoconf.h.in b/autoconf.h.in
new file mode 100644
index 0000000..9c92cf4
--- /dev/null
+++ b/autoconf.h.in
@@ -0,0 +1,3 @@
+/* @configure_input@ */
+#define WINE_INI_GLOBAL @WINE_INI_GLOBAL@
+#define AutoDefines @LANG@
diff --git a/configure b/configure
new file mode 100755
index 0000000..f495a92
--- /dev/null
+++ b/configure
@@ -0,0 +1,1752 @@
+#! /bin/sh
+
+# From configure.in configure.in 1.00
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.4
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-x use the X Window System"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Initialize some other variables.
+subdirs=
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -build | --build | --buil | --bui | --bu | --b)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=PREFIX install architecture-dependent files in PREFIX
+ [same as prefix]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+--enable and --with options recognized:$ac_help
+EOF
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.4"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=controls/edit.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+# We want these before the checks, so the checks can modify their values.
+test -z "$CFLAGS" && CFLAGS="-g -O2 -Wall"
+test -z "$LDFLAGS" && LDFLAGS=-g
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+set dummy ${MAKE-make}; ac_make=$2
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ if test "${CFLAGS+set}" != set; then
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_gcc_g=yes
+else
+ ac_cv_prog_gcc_g=no
+fi
+rm -f conftest*
+
+fi
+ echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
+ if test $ac_cv_prog_gcc_g = yes; then
+ CFLAGS="-g -O"
+ else
+ CFLAGS="-O"
+ fi
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 525 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 539 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+
+# Check whether --with-x or --without-x was given.
+withval="$with_x"
+if test -n "$withval"; then
+ :
+fi
+
+if test "x$with_x" = xno; then
+ no_x=yes
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ no_x=
+ else
+if eval "test \"`echo '$''{'ac_cv_path_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+no_x=yes
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ no_x=
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `make acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$no_x" = yes; then
+test -z "$x_direct_test_library" && x_direct_test_library=Xt
+test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+cat > conftest.$ac_ext <<EOF
+#line 625 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ no_x= ac_x_includes=
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ for ac_dir in \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X11/include \
+ /usr/include/X11 \
+ /usr/local/X11/include \
+ /usr/local/include/X11 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ no_x= ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+
+# Check for the libraries.
+# See if we find them without any special options.
+# Don't add to $LIBS permanently.
+ac_save_LIBS="$LIBS"
+LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 688 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS" no_x= ac_x_libraries=
+else
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X11/lib \
+ /usr/lib/X11 \
+ /usr/local/X11/lib \
+ /usr/local/lib/X11 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ no_x= ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+
+fi
+if test "$no_x" = yes; then
+ ac_cv_path_x="no_x=yes"
+else
+ ac_cv_path_x="no_x= ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_path_x"
+fi # $with_x != no
+
+if test "$no_x" = yes; then
+ echo "$ac_t""no" 1>&6
+else
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ ac_cv_path_x="no_x= ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for -l$ac_lib""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 844 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+yywrap()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+if test -n "$x_includes" ; then
+ x_includes="-I$x_includes"
+fi
+if test -n "$x_no" ; then
+ AXFILES='AXFILES='
+fi
+
+
+
+
+
+LD=ld
+LDCOMBINEFLAGS="-r"
+
+
+
+for ac_func in tcgetattr
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 895 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in stdlib.h
+do
+ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 947 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 984 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() { return 0; }
+int t() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if eval $ac_compile; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for -ldir""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_lib_dir'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1023 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+opendir()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_lib_dir=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_dir=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'dir`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for -lx""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_lib_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1057 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+opendir()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_lib_x=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_x=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'x`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1090 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(S_ISBLK) && defined(S_IFDIR)
+# if S_ISBLK (S_IFDIR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISBLK) && defined(S_IFCHR)
+# if S_ISBLK (S_IFCHR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISLNK) && defined(S_IFREG)
+# if S_ISLNK (S_IFREG)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISSOCK) && defined(S_IFREG)
+# if S_ISSOCK (S_IFREG)
+You lose.
+# endif
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "You lose" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_header_stat_broken=yes
+else
+ rm -rf conftest*
+ ac_cv_header_stat_broken=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_header_stat_broken" 1>&6
+if test $ac_cv_header_stat_broken = yes; then
+ cat >> confdefs.h <<\EOF
+#define STAT_MACROS_BROKEN 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1144 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero;
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if eval $ac_compile; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+# If we cannot run a trivial program, we must be cross compiling.
+echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_cross=yes
+else
+cat > conftest.$ac_ext <<EOF
+#line 1221 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_c_cross=no
+else
+ ac_cv_c_cross=yes
+fi
+fi
+rm -fr conftest*
+fi
+cross_compiling=$ac_cv_c_cross
+echo "$ac_t""$ac_cv_c_cross" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1242 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1264 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1282 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ ac_cv_header_stdc=no
+else
+cat > conftest.$ac_ext <<EOF
+#line 1303 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+fi
+rm -fr conftest*
+fi
+fi
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1337 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "size_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+
+if test -z "${top_srcdir}"; then
+TOP_SRCDIR="."
+else
+TOP_SRCDIR="${top_srcdir}"
+fi
+echo $ac_n "checking for language in autoconf.h""... $ac_c" 1>&6
+if test -f ${TOP_SRCDIR}/autoconf.h; then
+LANG=`tr ' ' '\n' < ${TOP_SRCDIR}/autoconf.h | grep '\-ALANG' | head -1`
+if test -n "${LANG}"; then
+echo "$ac_t""`echo "${LANG}" | cut -b9-10`" 1>&6
+fi
+fi
+if test -z "${LANG}"; then
+echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "${LANG}"; then
+echo $ac_n "checking for language through domainname""... $ac_c" 1>&6
+DNAME=`domainname`
+if test `echo "${DNAME}" | grep -c "\.no"` -ne 0; then
+LANG="-ALANG\(No\)"
+echo "$ac_t""No" 1>&6
+fi
+if test `echo "${DNAME}" | grep -c "\.de"` -ne 0; then
+LANG="-ALANG\(De\)"
+echo "$ac_t""De" 1>&6
+fi
+if test `echo "${DNAME}" | grep -c "\.uk"` -ne 0; then
+LANG="-ALANG\(En\)"
+echo "$ac_t""En" 1>&6
+fi
+if test `echo "${DNAME}" | grep -c "\.com"` -ne 0; then
+LANG="-ALANG\(En\)"
+echo "$ac_t""En" 1>&6
+fi
+if test `echo "${DNAME}" | grep -c "\.edu"` -ne 0; then
+LANG="-ALANG\(En\)"
+echo "$ac_t""En" 1>&6
+fi
+if test `echo "${DNAME}" | grep -c "\.gov"` -ne 0; then
+LANG="-ALANG\(En\)"
+echo "$ac_t""En" 1>&6
+fi
+if test -z "${LANG}"; then
+echo "$ac_t""no" 1>&6
+fi
+fi
+
+if test -z "${LANG}"; then
+echo $ac_n "checking for linux""... $ac_c" 1>&6
+cat > conftest.$ac_ext <<EOF
+#line 1416 "configure"
+#include "confdefs.h"
+#ifdef linux
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+echo $ac_n "checking for language by examining keymap""... $ac_c" 1>&6
+if test `dumpkeys | grep "keycode *26" | tr ' ' '\n' | grep -c udiaeresis` -ne 0; then
+echo "$ac_t""De" 1>&6
+LANG='-ALANG\(De\)'
+else
+echo "$ac_t""no" 1>&6
+LANG='-ALANG\(En\)'
+fi
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+LANG='-ALANG\(En\)'
+
+fi
+rm -f conftest*
+
+fi
+
+echo $ac_n "checking for wine.ini in autoconf.h""... $ac_c" 1>&6
+if test -f ${TOP_SRCDIR}/autoconf.h; then
+if test `grep -c WINE_INI_GLOBAL ${TOP_SRCDIR}/autoconf.h` -ne 0; then
+WINE_INI_GLOBAL=`grep WINE_INI_GLOBAL ${TOP_SRCDIR}/autoconf.h | tr ' ' '\n' | tail -1`
+echo "$ac_t""${WINE_INI_GLOBAL}" 1>&6
+fi
+fi
+if test -z "${WINE_INI_GLOBAL}"; then
+echo "$ac_t""no" 1>&6
+fi
+
+if test -z "${WINE_INI_GLOBAL}"; then
+echo $ac_n "checking for /usr/local/etc/wine.conf""... $ac_c" 1>&6
+if test -f /usr/local/etc/wine.conf; then
+echo "$ac_t""yes" 1>&6
+WINE_INI_GLOBAL='"/usr/local/etc/wine.conf"'
+else
+echo "$ac_t""no" 1>&6
+WINE_INI_GLOBAL="\"${TOP_SRCDIR}/wine.ini\""
+fi
+fi
+
+
+
+test -z "$LDFLAGS" && LDFLAGS=-g
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
+ >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.4"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "controls/Makefile ipc/Makefile loader/Makefile memory/Makefile misc/Makefile miscemu/Makefile multimedia/Makefile objects/Makefile windows/Makefile rc/Makefile debugger/Makefile debugger/readline/Makefile tools/Makefile if1632/Makefile Makefile autoconf.h include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@AXFILES@%$AXFILES%g
+s%@x_includes@%$x_includes%g
+s%@x_libraries@%$x_libraries%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@LD@%$LD%g
+s%@LDCOMBINEFLAGS@%$LDCOMBINEFLAGS%g
+s%@LANG@%$LANG%g
+s%@WINE_INI_GLOBAL@%$WINE_INI_GLOBAL%g
+
+CEOF
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"controls/Makefile ipc/Makefile loader/Makefile memory/Makefile misc/Makefile miscemu/Makefile multimedia/Makefile objects/Makefile windows/Makefile rc/Makefile debugger/Makefile debugger/readline/Makefile tools/Makefile if1632/Makefile Makefile autoconf.h"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust relative srcdir, etc. for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+fi; done
+rm -f conftest.subs
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+CONFIG_HEADERS=${CONFIG_HEADERS-"include/config.h"}
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ cp $ac_given_srcdir/$ac_file_in conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+# Maximum number of lines to put in a single here document.
+ac_max_here_lines=12
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+
+touch stamp-config
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+echo
+echo "Configure finished. Do 'make depend; make' to compile Wine."
+echo
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..9912fa9
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,148 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Author: Michael Patra <micky@marie.physik.tu-berlin.de>
+dnl <patra@itp1.physik.tu-berlin.de>
+AC_REVISION([configure.in 1.00])
+AC_INIT(controls/edit.c)
+AC_CONFIG_HEADER(include/config.h)
+
+# We want these before the checks, so the checks can modify their values.
+test -z "$CFLAGS" && CFLAGS="-g -O2 -Wall" AC_SUBST(CFLAGS)
+test -z "$LDFLAGS" && LDFLAGS=-g AC_SUBST(LDFLAGS)
+
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PATH_X
+AC_PROG_YACC
+AC_PROG_LEX
+if test -n "$x_includes" ; then
+ x_includes="-I$x_includes"
+fi
+if test -n "$x_no" ; then
+ AXFILES='AXFILES='
+fi
+AC_SUBST(AXFILES)
+AC_SUBST(x_includes)
+AC_SUBST(x_libraries)
+AC_SUBST(LIBOBJS)
+
+LD=ld
+LDCOMBINEFLAGS="-r"
+AC_SUBST(LD)
+AC_SUBST(LDCOMBINEFLAGS)
+
+AC_CHECK_FUNCS(tcgetattr)
+AC_CHECK_HEADERS(stdlib.h)
+AC_HEADER_DIRENT()
+AC_HEADER_STAT()
+AC_C_CONST()
+AC_TYPE_SIZE_T()
+
+if test -z "${top_srcdir}"; then
+TOP_SRCDIR="."
+else
+TOP_SRCDIR="${top_srcdir}"
+fi
+AC_MSG_CHECKING(for language in autoconf.h)
+if test -f ${TOP_SRCDIR}/autoconf.h; then
+LANG=`tr ' ' '\n' < ${TOP_SRCDIR}/autoconf.h | grep '\-ALANG' | head -1`
+if test -n "${LANG}"; then
+AC_MSG_RESULT(`echo "${LANG}" | cut -b9-10`)
+fi
+fi
+if test -z "${LANG}"; then
+AC_MSG_RESULT(no)
+fi
+AC_SUBST(LANG)
+
+if test -z "${LANG}"; then
+AC_MSG_CHECKING(for language through domainname)
+DNAME=`domainname`
+if test `echo "${DNAME}" | grep -c "\.no"` -ne 0; then
+LANG="-ALANG\(No\)"
+AC_MSG_RESULT(No)
+fi
+if test `echo "${DNAME}" | grep -c "\.de"` -ne 0; then
+LANG="-ALANG\(De\)"
+AC_MSG_RESULT(De)
+fi
+if test `echo "${DNAME}" | grep -c "\.uk"` -ne 0; then
+LANG="-ALANG\(En\)"
+AC_MSG_RESULT(En)
+fi
+if test `echo "${DNAME}" | grep -c "\.com"` -ne 0; then
+LANG="-ALANG\(En\)"
+AC_MSG_RESULT(En)
+fi
+if test `echo "${DNAME}" | grep -c "\.edu"` -ne 0; then
+LANG="-ALANG\(En\)"
+AC_MSG_RESULT(En)
+fi
+if test `echo "${DNAME}" | grep -c "\.gov"` -ne 0; then
+LANG="-ALANG\(En\)"
+AC_MSG_RESULT(En)
+fi
+if test -z "${LANG}"; then
+AC_MSG_RESULT(no)
+fi
+fi
+
+if test -z "${LANG}"; then
+AC_MSG_CHECKING(for linux)
+AC_EGREP_CPP(yes,
+[#ifdef linux
+ yes
+#endif
+], AC_MSG_RESULT(yes)
+AC_MSG_CHECKING(for language by examining keymap)
+if test `dumpkeys | grep "keycode *26" | tr ' ' '\n' | grep -c udiaeresis` -ne 0; then
+AC_MSG_RESULT(De)
+LANG='-ALANG\(De\)'
+else
+AC_MSG_RESULT(no)
+LANG='-ALANG\(En\)'
+fi
+,
+AC_MSG_RESULT(no)
+LANG='-ALANG\(En\)'
+)
+fi
+
+AC_MSG_CHECKING(for wine.ini in autoconf.h)
+if test -f ${TOP_SRCDIR}/autoconf.h; then
+if test `grep -c WINE_INI_GLOBAL ${TOP_SRCDIR}/autoconf.h` -ne 0; then
+WINE_INI_GLOBAL=`grep WINE_INI_GLOBAL ${TOP_SRCDIR}/autoconf.h | tr ' ' '\n' | tail -1`
+AC_MSG_RESULT(${WINE_INI_GLOBAL})
+fi
+fi
+if test -z "${WINE_INI_GLOBAL}"; then
+AC_MSG_RESULT(no)
+fi
+
+if test -z "${WINE_INI_GLOBAL}"; then
+AC_MSG_CHECKING(for /usr/local/etc/wine.conf)
+if test -f /usr/local/etc/wine.conf; then
+AC_MSG_RESULT(yes)
+WINE_INI_GLOBAL='"/usr/local/etc/wine.conf"'
+else
+AC_MSG_RESULT(no)
+WINE_INI_GLOBAL="\"${TOP_SRCDIR}/wine.ini\""
+fi
+fi
+AC_SUBST(WINE_INI_GLOBAL)
+
+
+test -z "$LDFLAGS" && LDFLAGS=-g AC_SUBST(LDFLAGS)
+
+
+AC_OUTPUT(controls/Makefile ipc/Makefile loader/Makefile memory/Makefile misc/Makefile miscemu/Makefile multimedia/Makefile objects/Makefile windows/Makefile rc/Makefile debugger/Makefile debugger/readline/Makefile tools/Makefile if1632/Makefile Makefile autoconf.h, [touch stamp-config])
+
+echo
+echo "Configure finished. Do 'make depend; make' to compile Wine."
+echo
+
+dnl Local Variables:
+dnl comment-start: "dnl "
+dnl comment-end: ""
+dnl comment-start-skip: "\\bdnl\\b\\s *"
+dnl compile-command: "make configure config.h.in"
+dnl End:
diff --git a/controls/Makefile.in b/controls/Makefile.in
new file mode 100644
index 0000000..5bdd7a9
--- /dev/null
+++ b/controls/Makefile.in
@@ -0,0 +1,49 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+MODULE = controls
+
+SRCS = button.c combo.c desktop.c edit.c listbox.c menu.c scroll.c \
+ static.c widgets.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/controls/listbox.c b/controls/listbox.c
index d1fc9ac..1a081f0 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -601,14 +601,12 @@
}
strcpy(temp,filespec);
tstr = strrchr(temp, '\\');
- if (tstr == NULL)
- DOS_SetDefaultDrive( drive );
- else {
- *tstr = 0;
- filespec = tstr + 1;
+ if (tstr != NULL) {
+ *(tstr+1) = 0;
+ filespec += tstr - temp + 1;
if (!DOS_ChangeDir( drive, temp )) return 0;
- DOS_SetDefaultDrive( drive );
}
+ DOS_SetDefaultDrive( drive );
dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
drive+'A', temp, filespec);
}
diff --git a/controls/menu.c b/controls/menu.c
index 6cea09d..d838e49 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1660,15 +1660,17 @@
HANDLE hNewItems;
MENUITEM *lpitem, *newItems;
LPPOPUPMENU menu;
-
+
if (IS_STRING_ITEM(wFlags))
- {
- dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, '%s') !\n",
- hMenu, nPos, wFlags, wItemID, lpNewItem);
- }
+ {
+ dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, '%s') !\n",
+ hMenu, nPos, wFlags, wItemID,
+ lpNewItem ? lpNewItem : "(null)");
+ if (!lpNewItem) return FALSE;
+ }
else
- dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, %p) !\n",
- hMenu, nPos, wFlags, wItemID, lpNewItem);
+ dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, %p) !\n",
+ hMenu, nPos, wFlags, wItemID, lpNewItem);
/* Find where to insert new item */
@@ -1816,8 +1818,11 @@
{
LPMENUITEM lpitem;
if (IS_STRING_ITEM(wFlags))
+ {
dprintf_menu(stddeb,"ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n",
- hMenu, nPos, wFlags, wItemID, lpNewItem);
+ hMenu, nPos, wFlags, wItemID, lpNewItem ? lpNewItem : "(null)");
+ if (!lpNewItem) return FALSE;
+ }
else
dprintf_menu(stddeb,"ModifyMenu (%04X, %04X, %04X, %04X, %p) !\n",
hMenu, nPos, wFlags, wItemID, lpNewItem);
diff --git a/debugger/Makefile.in b/debugger/Makefile.in
new file mode 100644
index 0000000..39cada3
--- /dev/null
+++ b/debugger/Makefile.in
@@ -0,0 +1,68 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+BISON = @YACC@
+FLEX = @LEX@
+DIVDEFS = -DUSE_READLINE
+COMPILE = $(CC) $(CFLAGS) $(DIVINCL) $(DIVDEFS)
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+@SET_MAKE@
+
+
+MODULE = debugger
+
+SRCS = break.c db_disasm.c hash.c info.c registers.c stack.c
+
+OBJS = $(SRCS:.c=.o) dbg.tab.o lex.yy.o
+
+all: $(MODULE).o dbg.tab.o lex.yy.o
+
+dbg.tab.c: dbg.y
+ $(BISON) -b dbg -d dbg.y
+
+dbg.tab.h: dbg.y
+ $(BISON) -b dbg -d dbg.y
+
+lex.yy.c: debug.l dbg.tab.h dbg.tab.h
+ $(FLEX) -8 -I debug.l
+
+.c.o:
+ $(COMPILE) -c -o $*.o $<
+
+$(MODULE).o: $(OBJS)
+ (cd readline; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) readline/readline.o -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ (cd readline; $(MAKE) clean)
+ rm -f *.o \#*\# *~ dbg.tab.c dbg.tab.h lex.yy.c y.tab.c y.tab.h tmp_make
+
+distclean: clean
+ (cd readline; $(MAKE) distclean)
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dbg.tab.o: dbg.tab.c
+lex.yy.o: lex.yy.c
+
+dummy:
+
+### Dependencies:
diff --git a/debugger/dbg.y b/debugger/dbg.y
index c9a5585..7d0022f 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -72,7 +72,8 @@
| MODE NUM '\n' { mode_command($2); }
| ENABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, TRUE ); }
| DISABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, FALSE ); }
- | BREAK '*' expr { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
+ | BREAK '*' expr '\n' { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
+ | BREAK '*' expr ':' expr '\n' { DEBUG_AddBreakpoint( $3, $5); }
| BREAK '\n' { DEBUG_AddBreakpoint( 0xffffffff, EIP ); }
| DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); }
| BACKTRACE '\n' { DEBUG_BackTrace(); }
@@ -90,6 +91,9 @@
EXAM expr '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
| EXAM FORMAT expr '\n' { examine_memory( 0xffffffff, $3,
$2 >> 8, $2 & 0xff ); }
+ | EXAM expr ':' expr '\n' { examine_memory( $2, $4, 1, 'x' ); }
+ | EXAM FORMAT expr ':' expr'\n' { examine_memory( $3, $5,
+ $2 >> 8, $2 & 0xff ); }
print_command:
PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); }
diff --git a/debugger/debug.l b/debugger/debug.l
index 4b8ccf1..862c1f8 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -37,7 +37,7 @@
\n { syntax_error = 0; return '\n'; } /*Indicate end of command*/
-[-+=()*] { return *yytext; }
+[-+=()*:] { return *yytext; }
"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval); return NUM; }
{DIGIT}+ { sscanf(yytext, "%d", &yylval); return NUM; }
diff --git a/debugger/info.c b/debugger/info.c
index 65f8bbd..109161d 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -10,11 +10,6 @@
extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
-void application_not_running()
-{
- fprintf(stderr,"Application not running\n");
-}
-
void print_address( unsigned int segment, unsigned int addr, int addrlen )
{
char *name = find_nearest_symbol( segment, addr );
diff --git a/debugger/readline/Imakefile b/debugger/readline/Imakefile
index aebd03a..6678bcb 100644
--- a/debugger/readline/Imakefile
+++ b/debugger/readline/Imakefile
@@ -2,12 +2,9 @@
MODULE = readline
-YACC = yacc -b dbg -d
-
-EXTRA_DEFINES= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX
+EXTRA_DEFINES= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE
SRCS = \
- complete.c \
editline.c \
sysunix.c
diff --git a/debugger/readline/Makefile.in b/debugger/readline/Makefile.in
new file mode 100644
index 0000000..9f2023e
--- /dev/null
+++ b/debugger/readline/Makefile.in
@@ -0,0 +1,50 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+DIVDEFS = -DHIDE -DANSI_ARROWS
+
+
+MODULE = readline
+
+SRCS = editline.c sysunix.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(DIVDEFS) $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/debugger/readline/complete.c b/debugger/readline/complete.c
deleted file mode 100644
index c5cbaaa..0000000
--- a/debugger/readline/complete.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* $Revision: 1.3 $
-**
-** History and file completion functions for editline library.
-*/
-#include <stdlib.h>
-#include "editline.h"
-
-#if defined(NEED_STRDUP)
-/*
-** Return an allocated copy of a string.
-*/
-char *
-strdup(p)
- char *p;
-{
- char *new;
-
- if ((new = NEW(char, strlen(p) + 1)) != NULL)
- (void)strcpy(new, p);
- return new;
-}
-#endif /* defined(NEED_STRDUP) */
-
-/*
-** strcmp-like sorting predicate for qsort.
-*/
-STATIC int
-compare(p1, p2)
- CONST void *p1;
- CONST void *p2;
-{
- CONST char **v1;
- CONST char **v2;
-
- v1 = (CONST char **)p1;
- v2 = (CONST char **)p2;
- return strcmp(*v1, *v2);
-}
-
-/*
-** Fill in *avp with an array of names that match file, up to its length.
-** Ignore . and .. .
-*/
-STATIC int
-FindMatches(dir, file, avp)
- char *dir;
- char *file;
- char ***avp;
-{
- char **av;
- char **new;
- char *p;
- DIR *dp;
- DIRENTRY *ep;
- SIZE_T ac;
- SIZE_T len;
-
- if ((dp = opendir(dir)) == NULL)
- return 0;
-
- av = NULL;
- ac = 0;
- len = strlen(file);
- while ((ep = readdir(dp)) != NULL) {
- p = ep->d_name;
- if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
- continue;
- if (len && strncmp(p, file, len) != 0)
- continue;
-
- if ((ac % MEM_INC) == 0) {
- if ((new = NEW(char*, ac + MEM_INC)) == NULL)
- break;
- if (ac) {
- COPYFROMTO(new, av, ac * sizeof (char **));
- DISPOSE(av);
- }
- *avp = av = new;
- }
-
- if ((av[ac] = strdup(p)) == NULL) {
- if (ac == 0)
- DISPOSE(av);
- break;
- }
- ac++;
- }
-
- /* Clean up and return. */
- (void)closedir(dp);
- if (ac)
- qsort(av, ac, sizeof (char **), compare);
- return ac;
-}
-
-/*
-** Split a pathname into allocated directory and trailing filename parts.
-*/
-STATIC int
-SplitPath(path, dirpart, filepart)
- char *path;
- char **dirpart;
- char **filepart;
-{
- static char DOT[] = ".";
- char *dpart;
- char *fpart;
-
- if ((fpart = strrchr(path, '/')) == NULL) {
- if ((dpart = strdup(DOT)) == NULL)
- return -1;
- if ((fpart = strdup(path)) == NULL) {
- DISPOSE(dpart);
- return -1;
- }
- }
- else {
- if ((dpart = strdup(path)) == NULL)
- return -1;
- dpart[fpart - path] = '\0';
- if ((fpart = strdup(++fpart)) == NULL) {
- DISPOSE(dpart);
- return -1;
- }
- }
- *dirpart = dpart;
- *filepart = fpart;
- return 0;
-}
-
-/*
-** Attempt to complete the pathname, returning an allocated copy.
-** Fill in *unique if we completed it, or set it to 0 if ambiguous.
-*/
-char *
-rl_complete(pathname, unique)
- char *pathname;
- int *unique;
-{
- char **av;
- char *dir;
- char *file;
- char *new;
- char *p;
- SIZE_T ac;
- SIZE_T end;
- SIZE_T i;
- SIZE_T j;
- SIZE_T len;
-
- if (SplitPath(pathname, &dir, &file) < 0)
- return NULL;
- if ((ac = FindMatches(dir, file, &av)) == 0) {
- DISPOSE(dir);
- DISPOSE(file);
- return NULL;
- }
-
- p = NULL;
- len = strlen(file);
- if (ac == 1) {
- /* Exactly one match -- finish it off. */
- *unique = 1;
- j = strlen(av[0]) - len + 2;
- if ((p = NEW(char, j + 1)) != NULL) {
- COPYFROMTO(p, av[0] + len, j);
- if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) {
- (void)strcpy(new, dir);
- (void)strcat(new, "/");
- (void)strcat(new, av[0]);
- rl_add_slash(new, p);
- DISPOSE(new);
- }
- }
- }
- else {
- *unique = 0;
- if (len) {
- /* Find largest matching substring. */
- for (i = len, end = strlen(av[0]); i < end; i++)
- for (j = 1; j < ac; j++)
- if (av[0][i] != av[j][i])
- goto breakout;
- breakout:
- if (i > len) {
- j = i - len + 1;
- if ((p = NEW(char, j)) != NULL) {
- COPYFROMTO(p, av[0] + len, j);
- p[j - 1] = '\0';
- }
- }
- }
- }
-
- /* Clean up and return. */
- DISPOSE(dir);
- DISPOSE(file);
- for (i = 0; i < ac; i++)
- DISPOSE(av[i]);
- DISPOSE(av);
- return p;
-}
-
-/*
-** Return all possible completions.
-*/
-int
-rl_list_possib(pathname, avp)
- char *pathname;
- char ***avp;
-{
- char *dir;
- char *file;
- int ac;
-
- if (SplitPath(pathname, &dir, &file) < 0)
- return 0;
- ac = FindMatches(dir, file, avp);
- DISPOSE(dir);
- DISPOSE(file);
- return ac;
-}
diff --git a/debugger/readline/editline.c b/debugger/readline/editline.c
index cd20bbb..eea22d7 100644
--- a/debugger/readline/editline.c
+++ b/debugger/readline/editline.c
@@ -78,8 +78,8 @@
STATIC int Point;
STATIC int PushBack;
STATIC int Pushed;
-FORWARD KEYMAP Map[33];
-FORWARD KEYMAP MetaMap[16];
+STATIC KEYMAP Map[33];
+STATIC KEYMAP MetaMap[16];
STATIC SIZE_T Length;
STATIC SIZE_T ScreenCount;
STATIC SIZE_T ScreenSize;
@@ -243,41 +243,6 @@
}
-/*
-** Print an array of words in columns.
-*/
-STATIC void
-columns(ac, av)
- int ac;
- CHAR **av;
-{
- CHAR *p;
- int i;
- int j;
- int k;
- int len;
- int skip;
- int longest;
- int cols;
-
- /* Find longest name, determine column count from that. */
- for (longest = 0, i = 0; i < ac; i++)
- if ((j = strlen((char *)av[i])) > longest)
- longest = j;
- cols = TTYwidth / (longest + 3);
-
- TTYputs((CHAR *)NEWLINE);
- for (skip = ac / cols + 1, i = 0; i < skip; i++) {
- for (j = i; j < ac; j += skip) {
- for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++)
- TTYput(*p);
- if (j + skip < ac)
- while (++len < longest + 3)
- TTYput(' ');
- }
- TTYputs((CHAR *)NEWLINE);
- }
-}
STATIC void
reposition()
@@ -1026,71 +991,6 @@
return CSstay;
}
-/*
-** Move back to the beginning of the current word and return an
-** allocated copy of it.
-*/
-STATIC CHAR *
-find_word()
-{
- static char SEPS[] = "#;&|^$=`'{}()<>\n\t ";
- CHAR *p;
- CHAR *new;
- SIZE_T len;
-
- for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--)
- continue;
- len = Point - (p - Line) + 1;
- if ((new = NEW(CHAR, len)) == NULL)
- return NULL;
- COPYFROMTO(new, p, len);
- new[len - 1] = '\0';
- return new;
-}
-
-STATIC STATUS
-c_complete()
-{
- CHAR *p;
- CHAR *word;
- int unique;
- STATUS s;
-
- word = find_word();
- p = (CHAR *)rl_complete((char *)word, &unique);
- if (word)
- DISPOSE(word);
- if (p && *p) {
- s = insert_string(p);
- if (!unique)
- (void)ring_bell();
- DISPOSE(p);
- return s;
- }
- return ring_bell();
-}
-
-STATIC STATUS
-c_possible()
-{
- CHAR **av;
- CHAR *word;
- int ac;
-
- word = find_word();
- ac = rl_list_possib((char *)word, (char ***)&av);
- if (word)
- DISPOSE(word);
- if (ac) {
- columns(ac, av);
- while (--ac >= 0)
- DISPOSE(av[ac]);
- DISPOSE(av);
- return CSmove;
- }
- return ring_bell();
-}
-
STATIC STATUS
accept_line()
{
@@ -1335,7 +1235,7 @@
{ CTL('F'), fd_char },
{ CTL('G'), ring_bell },
{ CTL('H'), bk_del_char },
- { CTL('I'), c_complete },
+ { CTL('I'), ring_bell },
{ CTL('J'), accept_line },
{ CTL('K'), kill_line },
{ CTL('L'), redisplay },
@@ -1367,7 +1267,7 @@
{ '.', last_argument },
{ '<', h_first },
{ '>', h_last },
- { '?', c_possible },
+ { '?', ring_bell },
{ 'b', bk_word },
{ 'd', fd_kill_word },
{ 'f', fd_word },
diff --git a/debugger/readline/editline.h b/debugger/readline/editline.h
index 40a2025..fa16f3b 100644
--- a/debugger/readline/editline.h
+++ b/debugger/readline/editline.h
@@ -3,20 +3,17 @@
** Internal header file for editline library.
*/
#include <stdio.h>
-#if defined(HAVE_STDLIB)
#include <stdlib.h>
#include <string.h>
-#endif /* defined(HAVE_STDLIB) */
-#if defined(SYS_UNIX)
-#include "unix.h"
-#endif /* defined(SYS_UNIX) */
-#if defined(SYS_OS9)
-#include "os9.h"
-#endif /* defined(SYS_OS9) */
+#include <sys/types.h>
+#include <sys/stat.h>
-#if !defined(SIZE_T)
-#define SIZE_T unsigned int
-#endif /* !defined(SIZE_T) */
+
+#define CRLF "\r\n"
+
+
+#define SIZE_T size_t
+#define CONST const
typedef unsigned char CHAR;
@@ -26,15 +23,6 @@
#define STATIC /* NULL */
#endif /* !defined(HIDE) */
-#if !defined(CONST)
-#if defined(__STDC__)
-#define CONST const
-#else
-#define CONST
-#endif /* defined(__STDC__) */
-#endif /* !defined(CONST) */
-
-
#define MEM_INC 64
#define SCREEN_INC 256
@@ -59,18 +47,3 @@
extern int rl_list_possib();
extern void rl_ttyset();
extern void rl_add_slash();
-
-#if !defined(HAVE_STDLIB)
-extern char *getenv();
-extern char *malloc();
-extern char *realloc();
-extern char *memcpy();
-extern char *strcat();
-extern char *strchr();
-extern char *strrchr();
-extern char *strcpy();
-extern char *strdup();
-extern int strcmp();
-extern int strlen();
-extern int strncmp();
-#endif /* !defined(HAVE_STDLIB) */
diff --git a/debugger/readline/sysunix.c b/debugger/readline/sysunix.c
index 010744e1..e2b72e1 100644
--- a/debugger/readline/sysunix.c
+++ b/debugger/readline/sysunix.c
@@ -3,6 +3,7 @@
** Unix system-dependant routines for editline library.
*/
#include "editline.h"
+#include "config.h"
#if defined(HAVE_TCGETATTR)
#include <termios.h>
diff --git a/debugger/readline/testit.c b/debugger/readline/testit.c
deleted file mode 100644
index e6384b8..0000000
--- a/debugger/readline/testit.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $Revision: 1.2 $
-**
-** A "micro-shell" to test editline library.
-** If given any arguments, commands aren't executed.
-*/
-#include <stdio.h>
-#if defined(HAVE_STDLIB)
-#include <stdlib.h>
-#endif /* defined(HAVE_STDLIB) */
-
-const char version_string[] = "4.321";
-
-
-extern char *readline();
-extern void add_history();
-
-#if !defined(HAVE_STDLIB)
-extern int chdir();
-extern int free();
-extern int strncmp();
-extern int system();
-extern void exit();
-#endif /* !defined(HAVE_STDLIB) */
-
-
-#if defined(NEED_PERROR)
-void
-perror(s)
- char *s;
-{
- extern int errno;
-
- (voidf)printf(stderr, "%s: error %d\n", s, errno);
-}
-#endif /* defined(NEED_PERROR) */
-
-
-/* ARGSUSED1 */
-int
-main(ac, av)
- int ac;
- char *av[];
-{
- char *p;
- int doit;
-
- doit = ac == 1;
- while ((p = readline("testit> ")) != NULL) {
- (void)printf("\t\t\t|%s|\n", p);
- if (doit)
- if (strncmp(p, "cd ", 3) == 0) {
- if (chdir(&p[3]) < 0)
- perror(&p[3]);
- }
- else if (system(p) != 0)
- perror(p);
- add_history(p);
- free(p);
- }
- exit(0);
- /* NOTREACHED */
-}
diff --git a/debugger/readline/unix.h b/debugger/readline/unix.h
deleted file mode 100644
index fe6beed..0000000
--- a/debugger/readline/unix.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* $Revision: 1.1 $
-**
-** Editline system header file for Unix.
-*/
-
-#define CRLF "\r\n"
-#define FORWARD STATIC
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if defined(USE_DIRENT)
-#include <dirent.h>
-typedef struct dirent DIRENTRY;
-#else
-#include <sys/dir.h>
-typedef struct direct DIRENTRY;
-#endif /* defined(USE_DIRENT) */
-
-#if !defined(S_ISDIR)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif /* !defined(S_ISDIR) */
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
new file mode 100644
index 0000000..71ea491
--- /dev/null
+++ b/if1632/Makefile.in
@@ -0,0 +1,88 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+BUILD = $(TOPSRC)/tools/build
+@SET_MAKE@
+
+
+MODULE = if1632
+
+SRCS = callback.c relay.c relay32.c
+
+DLLS16 = commdlg.spec compobj.spec ddeml.spec gdi.spec kernel.spec \
+ keyboard.spec mmsystem.spec mouse.spec ole2.spec ole2conv.spec \
+ ole2disp.spec ole2nls.spec ole2prox.spec olecli.spec olesvr.spec \
+ shell.spec sound.spec storage.spec stress.spec system.spec \
+ toolhelp.spec user.spec win87em.spec winprocs.spec winsock.spec
+
+DLLS32 = gdi32.spec kernel32.spec shell32.spec user32.spec winprocs32.spec
+
+
+OBJS = $(SRCS:.c=.o) $(DLLS16:.spec=.o) $(DLLS32:.spec=.o) call16.o call32.o
+
+SFILES = $(DLLS16:.spec=.S)
+
+.SUFFIXES: .spec
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+.spec.S:
+ $(BUILD) -spec16 $< > $*.S
+
+.S.o:
+ $(CC) -c -o $*.o $<
+
+all: checkbuild $(MODULE).o
+
+gdi32.c: gdi32.spec
+ $(BUILD) -spec32 gdi32.spec > gdi32.c
+
+kernel32.c: kernel32.spec
+ $(BUILD) -spec32 kernel32.spec > kernel32.c
+
+shell32.c: shell32.spec
+ $(BUILD) -spec32 shell32.spec > shell32.c
+
+user32.c: user32.spec
+ $(BUILD) -spec32 user32.spec > user32.c
+
+winprocs32.c: winprocs32.spec
+ $(BUILD) -spec32 winprocs32.spec > winprocs32.c
+
+checkbuild:
+ (cd $(TOPSRC)/tools; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
+
+call16.S: $(TOPSRC)/include/callback.h
+ $(TOPSRC)/tools/build -call16 `cat $(TOPSRC)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S
+
+call32.S: $(SFILES)
+ $(BUILD) -call32 `cat $(SFILES) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S
+
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM callback.c relay32.c relay.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ *.S gdi32.c kernel32.c shell32.c user32.c winprocs32.c tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+winelibclean:
+
+dummy:
+
+### Dependencies:
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 94a31ec..7b302ad 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -47,7 +47,7 @@
38 pascal Escape(word word word ptr ptr) Escape
39 pascal16 RestoreDC(word s_word) RestoreDC
40 pascal16 FillRgn(word word word) FillRgn
-41 stub FrameRgn
+41 pascal16 FrameRgn(word word word word word) FrameRgn
42 pascal16 InvertRgn(word word) InvertRgn
43 pascal16 PaintRgn(word word) PaintRgn
44 pascal16 SelectClipRgn(word word) SelectClipRgn
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index e546d1d..a351242 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -42,7 +42,7 @@
42 return DisableDos 0 0
45 pascal16 LoadModule(ptr ptr) LoadModule
46 pascal16 FreeModule(word) FreeModule
-47 pascal16 GetModuleHandle(ptr) GetModuleHandle
+47 pascal16 GetModuleHandle(segptr) WIN16_GetModuleHandle
48 pascal16 GetModuleUsage(word) GetModuleUsage
49 pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName
50 pascal GetProcAddress(word segptr) GetProcAddress
@@ -82,7 +82,7 @@
84 pascal _llseek(word long word) _llseek
85 pascal16 _lopen(ptr word) _lopen
86 pascal16 _lwrite(word ptr word) _lwrite
-87 stub RESERVED5
+87 pascal16 RESERVED5(ptr ptr) lstrcmp
88 pascal lstrcpy(segptr segptr) lstrcpy
89 pascal lstrcat(segptr segptr) lstrcat
90 pascal16 lstrlen(ptr) lstrlen
@@ -146,7 +146,7 @@
155 pascal16 GetTaskDS() GetTaskDS
156 stub LimitEMSPages
157 return GetCurPID 4 0
-158 stub IsWinOldApTask
+158 return IsWinOldApTask 2 0
159 stub GlobalHandleNoRIP
160 stub EMSCopy
161 pascal16 LocalCountFree() LocalCountFree
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index afea764..af38f70 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -4,21 +4,21 @@
#1 pascal Inquire
#2 pascal Enable
#3 pascal Disable
-4 pascal ToAscii(word word ptr ptr word) ToAscii
-5 pascal AnsiToOem(ptr ptr) AnsiToOem
-6 pascal OemToAnsi(ptr ptr) OemToAnsi
+4 pascal16 ToAscii(word word ptr ptr word) ToAscii
+5 pascal16 AnsiToOem(ptr ptr) AnsiToOem
+6 pascal16 OemToAnsi(ptr ptr) OemToAnsi
#7 pascal SetSpeed
#100 pascal ScreenSwitchEnable
#126 pascal GetTableSeg
#127 pascal NewTable
-128 pascal OemKeyScan(word) OemKeyScan
-129 pascal VkKeyScan(byte) VkKeyScan
-130 pascal GetKeyboardType(byte) GetKeyboardType
-131 pascal MapVirtualKey(word word) MapVirtualKey
-132 pascal GetKbCodePage() GetKbCodePage
-133 pascal GetKeyNameText(long ptr word) GetKeyNameText
-134 pascal AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
-135 pascal OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
+128 pascal OemKeyScan(word) OemKeyScan
+129 pascal16 VkKeyScan(byte) VkKeyScan
+130 pascal16 GetKeyboardType(byte) GetKeyboardType
+131 pascal16 MapVirtualKey(word word) MapVirtualKey
+132 pascal16 GetKbCodePage() GetKbCodePage
+133 pascal16 GetKeyNameText(long ptr word) GetKeyNameText
+134 pascal16 AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
+135 pascal16 OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
#136 pascal EnableKbSysReq
#137 pascal GetBiosKeyProc
diff --git a/if1632/mouse.spec b/if1632/mouse.spec
index 879ecfc..0c04a8d 100644
--- a/if1632/mouse.spec
+++ b/if1632/mouse.spec
@@ -6,5 +6,6 @@
3 stub DISABLE
4 stub MOUSEGETINTVECT
5 stub GETSETMOUSEDATA
-6 stub CPLAPPLET
+#Control Panel thinks this is implemented if it is available
+#6 stub CPLAPPLET
7 stub POWEREVENTPROC
diff --git a/if1632/relay.c b/if1632/relay.c
index 1524517..72de966 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -8,6 +8,7 @@
#include "dlls.h"
#include "global.h"
#include "module.h"
+#include "registers.h"
#include "stackframe.h"
#include "stddebug.h"
/* #define DEBUG_RELAY */
@@ -80,7 +81,7 @@
codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALL16_Start,
(int)CALL16_End - (int)CALL16_Start,
- 0, TRUE, TRUE, FALSE );
+ 0, TRUE, TRUE, FALSE, NULL );
if (!codesel) return FALSE;
/* Patch the return addresses for CallTo16 routines */
@@ -97,7 +98,7 @@
/***********************************************************************
* RELAY_DebugCall32
*/
-void RELAY_DebugCall32( char *args )
+void RELAY_DebugCall32( int func_type, char *args )
{
STACK16FRAME *frame;
struct dll_table_s *table;
@@ -150,6 +151,13 @@
if (*args) printf( "," );
}
printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
+
+ if (func_type == 2) /* register function */
+ {
+ struct sigcontext_struct *context = (struct sigcontext_struct *)args16;
+ printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
+ AX, BX, CX, DX, SI, DI, ES, EFL );
+ }
}
@@ -162,6 +170,9 @@
struct dll_table_s *table;
char *name;
+ if (*(DWORD *)PTR_SEG_TO_LIN(IF1632_Stack32_base) != 0xDEADBEEF) {
+ fprintf(stderr, "Wine wrote past the end of the 32 bit stack. Please report this.\n");
+ }
if (!debugging_relay) return;
frame = CURRENT_STACK16;
diff --git a/if1632/user.spec b/if1632/user.spec
index b5512b3..8be2aa3 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -253,7 +253,7 @@
250 pascal16 GetMenuState(word word word) GetMenuState
251 pascal SendDriverMessage(word word long long) SendDriverMessage
252 pascal16 OpenDriver(ptr ptr long) OpenDriver
-253 pascal CloseDriver(word word long) CloseDriver
+253 pascal CloseDriver(word long long) CloseDriver
254 pascal16 GetDriverModuleHandle(word) GetDriverModuleHandle
255 pascal DefDriverProc(long word word long long) DefDriverProc
256 pascal16 GetDriverInfo(word ptr) GetDriverInfo
@@ -266,7 +266,7 @@
262 pascal16 GetWindow(word word) GetWindow
263 pascal16 GetMenuItemCount(word) GetMenuItemCount
264 pascal16 GetMenuItemID(word word) GetMenuItemID
-265 stub ShowOwnedPopups
+265 pascal16 ShowOwnedPopups(word word) ShowOwnedPopups
266 pascal16 SetMessageQueue(word) SetMessageQueue
267 pascal16 ShowScrollBar(word word word) ShowScrollBar
268 pascal16 GlobalAddAtom(ptr) GlobalAddAtom
@@ -371,7 +371,7 @@
word word word segptr) CreateWindowEx
454 pascal16 AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx
455 stub GetIconId
-456 stub LoadIconHandler
+456 pascal16 LoadIconHandler(word word) LoadIconHandler
457 pascal16 DestroyIcon(word) DestroyIcon
458 pascal16 DestroyCursor(word) DestroyCursor
459 pascal DumpIcon(ptr ptr ptr ptr) DumpIcon
diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec
index 8a0e88d..b95e074 100644
--- a/if1632/winprocs.spec
+++ b/if1632/winprocs.spec
@@ -25,23 +25,265 @@
22 pascal ComboLBoxWndProc(word word word long) ComboLBoxWndProc
23 pascal16 CARET_Callback(word word word long) CARET_Callback
24 pascal16 TASK_Reschedule() TASK_Reschedule
+25 pascal MMSysTimeCallback(word word word long) MMSysTimeCallback
# Interrupt vectors 0-255 are ordinals 100-355
-# Undefined functions are mapped to the dummy handler (ordinal 356)
# The 'word' parameter are the flags pushed on the stack by the interrupt
-
+100 register INT_Int00Handler(word) INT_DummyHandler
+101 register INT_Int01Handler(word) INT_DummyHandler
+102 register INT_Int02Handler(word) INT_DummyHandler
+103 register INT_Int03Handler(word) INT_DummyHandler
+104 register INT_Int04Handler(word) INT_DummyHandler
+105 register INT_Int05Handler(word) INT_DummyHandler
+106 register INT_Int06Handler(word) INT_DummyHandler
+107 register INT_Int07Handler(word) INT_DummyHandler
+108 register INT_Int08Handler(word) INT_DummyHandler
+109 register INT_Int09Handler(word) INT_DummyHandler
+110 register INT_Int0aHandler(word) INT_DummyHandler
+111 register INT_Int0bHandler(word) INT_DummyHandler
+112 register INT_Int0cHandler(word) INT_DummyHandler
+113 register INT_Int0dHandler(word) INT_DummyHandler
+114 register INT_Int0eHandler(word) INT_DummyHandler
+115 register INT_Int0fHandler(word) INT_DummyHandler
116 register INT_Int10Handler(word) INT_Int10Handler
+117 register INT_Int11Handler(word) INT_Int11Handler
+118 register INT_Int12Handler(word) INT_Int12Handler
119 register INT_Int13Handler(word) INT_Int13Handler
+120 register INT_Int14Handler(word) INT_DummyHandler
121 register INT_Int15Handler(word) INT_Int15Handler
122 register INT_Int16Handler(word) INT_Int16Handler
+123 register INT_Int17Handler(word) INT_DummyHandler
+124 register INT_Int18Handler(word) INT_DummyHandler
+125 register INT_Int19Handler(word) INT_DummyHandler
126 register INT_Int1aHandler(word) INT_Int1aHandler
-133 register INT_Int21Handler(word) INT_Int21Handler
-137 register INT_Int25Handler(word) INT_Int25Handler
-138 register INT_Int26Handler(word) INT_Int26Handler
+127 register INT_Int1bHandler(word) INT_DummyHandler
+128 register INT_Int1cHandler(word) INT_DummyHandler
+129 register INT_Int1dHandler(word) INT_DummyHandler
+130 register INT_Int1eHandler(word) INT_DummyHandler
+131 register INT_Int1fHandler(word) INT_DummyHandler
+132 register INT_Int20Handler(word) INT_DummyHandler
+133 register INT_Int21Handler(word) DOS3Call
+134 register INT_Int22Handler(word) INT_DummyHandler
+135 register INT_Int23Handler(word) INT_DummyHandler
+136 register INT_Int24Handler(word) INT_DummyHandler
+# Note: int 25 and 26 don't pop the flags from the stack
+137 register INT_Int25Handler() INT_Int25Handler
+138 register INT_Int26Handler() INT_Int26Handler
+139 register INT_Int27Handler(word) INT_DummyHandler
+140 register INT_Int28Handler(word) INT_DummyHandler
+141 register INT_Int29Handler(word) INT_DummyHandler
142 register INT_Int2aHandler(word) INT_Int2aHandler
+143 register INT_Int2bHandler(word) INT_DummyHandler
+144 register INT_Int2cHandler(word) INT_DummyHandler
+145 register INT_Int2dHandler(word) INT_DummyHandler
+146 register INT_Int2eHandler(word) INT_DummyHandler
147 register INT_Int2fHandler(word) INT_Int2fHandler
+148 register INT_Int30Handler(word) INT_DummyHandler
149 register INT_Int31Handler(word) INT_Int31Handler
-192 register INT_Int5cHandler(word) INT_Int5cHandler
+150 register INT_Int32Handler(word) INT_DummyHandler
+151 register INT_Int33Handler(word) INT_DummyHandler
+152 register INT_Int34Handler(word) INT_DummyHandler
+153 register INT_Int35Handler(word) INT_DummyHandler
+154 register INT_Int36Handler(word) INT_DummyHandler
+155 register INT_Int37Handler(word) INT_DummyHandler
+156 register INT_Int38Handler(word) INT_DummyHandler
+157 register INT_Int39Handler(word) INT_DummyHandler
+158 register INT_Int3aHandler(word) INT_DummyHandler
+159 register INT_Int3bHandler(word) INT_DummyHandler
+160 register INT_Int3cHandler(word) INT_DummyHandler
+161 register INT_Int3dHandler(word) INT_DummyHandler
+162 register INT_Int3eHandler(word) INT_DummyHandler
+163 register INT_Int3fHandler(word) INT_DummyHandler
+164 register INT_Int40Handler(word) INT_DummyHandler
+165 register INT_Int41Handler(word) INT_DummyHandler
+166 register INT_Int42Handler(word) INT_DummyHandler
+167 register INT_Int43Handler(word) INT_DummyHandler
+168 register INT_Int44Handler(word) INT_DummyHandler
+169 register INT_Int45Handler(word) INT_DummyHandler
+170 register INT_Int46Handler(word) INT_DummyHandler
+171 register INT_Int47Handler(word) INT_DummyHandler
+172 register INT_Int48Handler(word) INT_DummyHandler
+173 register INT_Int49Handler(word) INT_DummyHandler
+174 register INT_Int4aHandler(word) INT_DummyHandler
+175 register INT_Int4bHandler(word) INT_DummyHandler
+176 register INT_Int4cHandler(word) INT_DummyHandler
+177 register INT_Int4dHandler(word) INT_DummyHandler
+178 register INT_Int4eHandler(word) INT_DummyHandler
+179 register INT_Int4fHandler(word) INT_DummyHandler
+180 register INT_Int50Handler(word) INT_DummyHandler
+181 register INT_Int51Handler(word) INT_DummyHandler
+182 register INT_Int52Handler(word) INT_DummyHandler
+183 register INT_Int53Handler(word) INT_DummyHandler
+184 register INT_Int54Handler(word) INT_DummyHandler
+185 register INT_Int55Handler(word) INT_DummyHandler
+186 register INT_Int56Handler(word) INT_DummyHandler
+187 register INT_Int57Handler(word) INT_DummyHandler
+188 register INT_Int58Handler(word) INT_DummyHandler
+189 register INT_Int59Handler(word) INT_DummyHandler
+190 register INT_Int5aHandler(word) INT_DummyHandler
+191 register INT_Int5bHandler(word) INT_DummyHandler
+192 register INT_Int5cHandler(word) NetBIOSCall
+193 register INT_Int5dHandler(word) INT_DummyHandler
+194 register INT_Int5eHandler(word) INT_DummyHandler
+195 register INT_Int5fHandler(word) INT_DummyHandler
+196 register INT_Int60Handler(word) INT_DummyHandler
+197 register INT_Int61Handler(word) INT_DummyHandler
+198 register INT_Int62Handler(word) INT_DummyHandler
+199 register INT_Int63Handler(word) INT_DummyHandler
+200 register INT_Int64Handler(word) INT_DummyHandler
+201 register INT_Int65Handler(word) INT_DummyHandler
+202 register INT_Int66Handler(word) INT_DummyHandler
+203 register INT_Int67Handler(word) INT_DummyHandler
+204 register INT_Int68Handler(word) INT_DummyHandler
+205 register INT_Int69Handler(word) INT_DummyHandler
+206 register INT_Int6aHandler(word) INT_DummyHandler
+207 register INT_Int6bHandler(word) INT_DummyHandler
+208 register INT_Int6cHandler(word) INT_DummyHandler
+209 register INT_Int6dHandler(word) INT_DummyHandler
+210 register INT_Int6eHandler(word) INT_DummyHandler
+211 register INT_Int6fHandler(word) INT_DummyHandler
+212 register INT_Int70Handler(word) INT_DummyHandler
+213 register INT_Int71Handler(word) INT_DummyHandler
+214 register INT_Int72Handler(word) INT_DummyHandler
+215 register INT_Int73Handler(word) INT_DummyHandler
+216 register INT_Int74Handler(word) INT_DummyHandler
+217 register INT_Int75Handler(word) INT_DummyHandler
+218 register INT_Int76Handler(word) INT_DummyHandler
+219 register INT_Int77Handler(word) INT_DummyHandler
+220 register INT_Int78Handler(word) INT_DummyHandler
+221 register INT_Int79Handler(word) INT_DummyHandler
+222 register INT_Int7aHandler(word) INT_DummyHandler
+223 register INT_Int7bHandler(word) INT_DummyHandler
+224 register INT_Int7cHandler(word) INT_DummyHandler
+225 register INT_Int7dHandler(word) INT_DummyHandler
+226 register INT_Int7eHandler(word) INT_DummyHandler
+227 register INT_Int7fHandler(word) INT_DummyHandler
+228 register INT_Int80Handler(word) INT_DummyHandler
+229 register INT_Int81Handler(word) INT_DummyHandler
+230 register INT_Int82Handler(word) INT_DummyHandler
+231 register INT_Int83Handler(word) INT_DummyHandler
+232 register INT_Int84Handler(word) INT_DummyHandler
+233 register INT_Int85Handler(word) INT_DummyHandler
+234 register INT_Int86Handler(word) INT_DummyHandler
+235 register INT_Int87Handler(word) INT_DummyHandler
+236 register INT_Int88Handler(word) INT_DummyHandler
+237 register INT_Int89Handler(word) INT_DummyHandler
+238 register INT_Int8aHandler(word) INT_DummyHandler
+239 register INT_Int8bHandler(word) INT_DummyHandler
+240 register INT_Int8cHandler(word) INT_DummyHandler
+241 register INT_Int8dHandler(word) INT_DummyHandler
+242 register INT_Int8eHandler(word) INT_DummyHandler
+243 register INT_Int8fHandler(word) INT_DummyHandler
+244 register INT_Int90Handler(word) INT_DummyHandler
+245 register INT_Int91Handler(word) INT_DummyHandler
+246 register INT_Int92Handler(word) INT_DummyHandler
+247 register INT_Int93Handler(word) INT_DummyHandler
+248 register INT_Int94Handler(word) INT_DummyHandler
+249 register INT_Int95Handler(word) INT_DummyHandler
+250 register INT_Int96Handler(word) INT_DummyHandler
+251 register INT_Int97Handler(word) INT_DummyHandler
+252 register INT_Int98Handler(word) INT_DummyHandler
+253 register INT_Int99Handler(word) INT_DummyHandler
+254 register INT_Int9aHandler(word) INT_DummyHandler
+255 register INT_Int9bHandler(word) INT_DummyHandler
+256 register INT_Int9cHandler(word) INT_DummyHandler
+257 register INT_Int9dHandler(word) INT_DummyHandler
+258 register INT_Int9eHandler(word) INT_DummyHandler
+259 register INT_Int9fHandler(word) INT_DummyHandler
+260 register INT_Inta0Handler(word) INT_DummyHandler
+261 register INT_Inta1Handler(word) INT_DummyHandler
+262 register INT_Inta2Handler(word) INT_DummyHandler
+263 register INT_Inta3Handler(word) INT_DummyHandler
+264 register INT_Inta4Handler(word) INT_DummyHandler
+265 register INT_Inta5Handler(word) INT_DummyHandler
+266 register INT_Inta6Handler(word) INT_DummyHandler
+267 register INT_Inta7Handler(word) INT_DummyHandler
+268 register INT_Inta8Handler(word) INT_DummyHandler
+269 register INT_Inta9Handler(word) INT_DummyHandler
+270 register INT_IntaaHandler(word) INT_DummyHandler
+271 register INT_IntabHandler(word) INT_DummyHandler
+272 register INT_IntacHandler(word) INT_DummyHandler
+273 register INT_IntadHandler(word) INT_DummyHandler
+274 register INT_IntaeHandler(word) INT_DummyHandler
+275 register INT_IntafHandler(word) INT_DummyHandler
+276 register INT_Intb0Handler(word) INT_DummyHandler
+277 register INT_Intb1Handler(word) INT_DummyHandler
+278 register INT_Intb2Handler(word) INT_DummyHandler
+279 register INT_Intb3Handler(word) INT_DummyHandler
+280 register INT_Intb4Handler(word) INT_DummyHandler
+281 register INT_Intb5Handler(word) INT_DummyHandler
+282 register INT_Intb6Handler(word) INT_DummyHandler
+283 register INT_Intb7Handler(word) INT_DummyHandler
+284 register INT_Intb8Handler(word) INT_DummyHandler
+285 register INT_Intb9Handler(word) INT_DummyHandler
+286 register INT_IntbaHandler(word) INT_DummyHandler
+287 register INT_IntbbHandler(word) INT_DummyHandler
+288 register INT_IntbcHandler(word) INT_DummyHandler
+289 register INT_IntbdHandler(word) INT_DummyHandler
+290 register INT_IntbeHandler(word) INT_DummyHandler
+291 register INT_IntbfHandler(word) INT_DummyHandler
+292 register INT_Intc0Handler(word) INT_DummyHandler
+293 register INT_Intc1Handler(word) INT_DummyHandler
+294 register INT_Intc2Handler(word) INT_DummyHandler
+295 register INT_Intc3Handler(word) INT_DummyHandler
+296 register INT_Intc4Handler(word) INT_DummyHandler
+297 register INT_Intc5Handler(word) INT_DummyHandler
+298 register INT_Intc6Handler(word) INT_DummyHandler
+299 register INT_Intc7Handler(word) INT_DummyHandler
+300 register INT_Intc8Handler(word) INT_DummyHandler
+301 register INT_Intc9Handler(word) INT_DummyHandler
+302 register INT_IntcaHandler(word) INT_DummyHandler
+303 register INT_IntcbHandler(word) INT_DummyHandler
+304 register INT_IntccHandler(word) INT_DummyHandler
+305 register INT_IntcdHandler(word) INT_DummyHandler
+306 register INT_IntceHandler(word) INT_DummyHandler
+307 register INT_IntcfHandler(word) INT_DummyHandler
+308 register INT_Intd0Handler(word) INT_DummyHandler
+309 register INT_Intd1Handler(word) INT_DummyHandler
+310 register INT_Intd2Handler(word) INT_DummyHandler
+311 register INT_Intd3Handler(word) INT_DummyHandler
+312 register INT_Intd4Handler(word) INT_DummyHandler
+313 register INT_Intd5Handler(word) INT_DummyHandler
+314 register INT_Intd6Handler(word) INT_DummyHandler
+315 register INT_Intd7Handler(word) INT_DummyHandler
+316 register INT_Intd8Handler(word) INT_DummyHandler
+317 register INT_Intd9Handler(word) INT_DummyHandler
+318 register INT_IntdaHandler(word) INT_DummyHandler
+319 register INT_IntdbHandler(word) INT_DummyHandler
+320 register INT_IntdcHandler(word) INT_DummyHandler
+321 register INT_IntddHandler(word) INT_DummyHandler
+322 register INT_IntdeHandler(word) INT_DummyHandler
+323 register INT_IntdfHandler(word) INT_DummyHandler
+324 register INT_Inte0Handler(word) INT_DummyHandler
+325 register INT_Inte1Handler(word) INT_DummyHandler
+326 register INT_Inte2Handler(word) INT_DummyHandler
+327 register INT_Inte3Handler(word) INT_DummyHandler
+328 register INT_Inte4Handler(word) INT_DummyHandler
+329 register INT_Inte5Handler(word) INT_DummyHandler
+330 register INT_Inte6Handler(word) INT_DummyHandler
+331 register INT_Inte7Handler(word) INT_DummyHandler
+332 register INT_Inte8Handler(word) INT_DummyHandler
+333 register INT_Inte9Handler(word) INT_DummyHandler
+334 register INT_InteaHandler(word) INT_DummyHandler
+335 register INT_IntebHandler(word) INT_DummyHandler
+336 register INT_IntecHandler(word) INT_DummyHandler
+337 register INT_IntedHandler(word) INT_DummyHandler
+338 register INT_InteeHandler(word) INT_DummyHandler
+339 register INT_IntefHandler(word) INT_DummyHandler
+340 register INT_Intf0Handler(word) INT_DummyHandler
+341 register INT_Intf1Handler(word) INT_DummyHandler
+342 register INT_Intf2Handler(word) INT_DummyHandler
+343 register INT_Intf3Handler(word) INT_DummyHandler
+344 register INT_Intf4Handler(word) INT_DummyHandler
+345 register INT_Intf5Handler(word) INT_DummyHandler
+346 register INT_Intf6Handler(word) INT_DummyHandler
+347 register INT_Intf7Handler(word) INT_DummyHandler
+348 register INT_Intf8Handler(word) INT_DummyHandler
+349 register INT_Intf9Handler(word) INT_DummyHandler
+350 register INT_IntfaHandler(word) INT_DummyHandler
+351 register INT_IntfbHandler(word) INT_DummyHandler
+352 register INT_IntfcHandler(word) INT_DummyHandler
+353 register INT_IntfdHandler(word) INT_DummyHandler
+354 register INT_IntfeHandler(word) INT_DummyHandler
+355 register INT_IntffHandler(word) INT_DummyHandler
-# Dummy interrupt vector
-356 register INT_DummyHandler(word) INT_DummyHandler
diff --git a/if1632/winsock.spec b/if1632/winsock.spec
index 2418716..813f364 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -15,7 +15,7 @@
7 pascal16 getsockopt(word word word ptr ptr) WINSOCK_getsockopt
8 pascal htonl(long) WINSOCK_htonl
9 pascal16 htons(word) WINSOCK_htons
-10 pascal inet_addr(long) WINSOCK_inet_addr
+10 pascal inet_addr(ptr) WINSOCK_inet_addr
11 pascal inet_ntoa(long) WINSOCK_inet_ntoa
12 pascal16 ioctlsocket(word long ptr) WINSOCK_ioctlsocket
13 pascal16 listen(word word) WINSOCK_listen
@@ -23,7 +23,7 @@
15 pascal16 ntohs(word) WINSOCK_ntohs
16 pascal16 recv(word ptr word word) WINSOCK_recv
17 pascal16 recvfrom(word ptr word word ptr ptr) WINSOCK_recvfrom
-18 pascal16 select(word ptr ptr ptr ptr word) WINSOCK_select
+18 pascal16 select(word ptr ptr ptr ptr ptr) WINSOCK_select
19 pascal16 send(word ptr word word) WINSOCK_send
20 pascal16 sendto(word ptr word word ptr ptr) WINSOCK_sendto
21 pascal16 setsockopt(word word word ptr word) WINSOCK_setsockopt
diff --git a/include/atom.h b/include/atom.h
index 045c343..631f185 100644
--- a/include/atom.h
+++ b/include/atom.h
@@ -31,4 +31,14 @@
#define LocalAlign(flags,bytes) LocalAlloc((flags),(bytes))
#endif
+ATOM LocalAddAtom( LPCSTR str );
+ATOM LocalDeleteAtom( ATOM atom );
+ATOM LocalFindAtom( LPCSTR str );
+WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
+
+ATOM LocalAddAtom( LPCSTR str );
+ATOM LocalDeleteAtom( ATOM atom );
+ATOM LocalFindAtom( LPCSTR str );
+WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
+
#endif /* ATOM_H */
diff --git a/include/bit_array.h b/include/bit_array.h
new file mode 100644
index 0000000..b07cdf6
--- /dev/null
+++ b/include/bit_array.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: bit_array.h
+ * Purpose : manipulate array of bits,
+ * Important: operations may be considered atomic.
+ *
+ ***************************************************************************
+ */
+#ifndef __WINE_BIT_ARRAY_H
+#define __WINE_BIT_ARRAY_H
+
+
+#define BITS_PER_BYTE (8)
+#define BITS_PER_INT (sizeof(int)*BITS_PER_BYTE) /* must be power of 2 */
+
+#define BYTE_LOG2 (3)
+#if defined(INT_LOG2)
+/* nothing to do, IN_LOG2 is ok */
+#elif defined(__i386__)
+# define INT_LOG2 (5)
+#else
+# error "Can't find log2 of BITS_PER_INT, please code it manualy"
+#endif
+
+
+typedef struct bit_array {
+ int bits; /* number of bits in the array */
+ unsigned int *array; /* Actual array data (Never NULL) */
+} bit_array ;
+
+bit_array *AssembleArray(bit_array *new_array, unsigned int *buff, int bits);
+int ResetArray(bit_array *bits);
+
+/* Return index of first free bit, or -1 on failure */
+int VacantBit(bit_array *bits);
+
+
+/* Return the value of bit 'i' */
+int SampleBit(bit_array *bits, int i);
+
+/* Assign 'val' to a bit no. 'i'. Return: old bit's value */
+int AssignBit(bit_array *bits, int i, int val);
+
+/*
+** Allocate a free bit (==0) and make it used (==1).
+** Return: allocated bit index, or -1 on failure.
+*/
+int AllocateBit(bit_array *bits);
+
+#endif /* __WINE_BIT_ARRAY_H */
diff --git a/include/config.h.in b/include/config.h.in
new file mode 100644
index 0000000..10c6b69
--- /dev/null
+++ b/include/config.h.in
@@ -0,0 +1,6 @@
+#undef HAVE_STDLIB_H
+#undef HAVE_TCGETATTR
+#undef HAVE_DIRENT_H
+#undef HAVE_SYS_NDIR_H
+#undef HAVE_NDIR_H
+#undef STAT_MACROS_BROKEN
diff --git a/include/dde.h b/include/dde.h
new file mode 100644
index 0000000..72d250c
--- /dev/null
+++ b/include/dde.h
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde.h
+ * Purpose: dde declarations
+ *
+ *****************************************************************************
+ */
+#ifndef __WINE_DDE_H
+#define __WINE_DDE_H
+
+#include "wintypes.h"
+#include "dde_proc.h"
+
+#define WM_DDE_INITIATE 0x3E0
+#define WM_DDE_TERMINATE 0x3E1
+#define WM_DDE_ADVISE 0x3E2
+#define WM_DDE_UNADVISE 0x3E3
+#define WM_DDE_ACK 0x3E4
+#define WM_DDE_DATA 0x3E5
+#define WM_DDE_REQUEST 0x3E6
+#define WM_DDE_POKE 0x3E7
+#define WM_DDE_EXECUTE 0x3E8
+#define WM_DDE_LAST WM_DDE_EXECUTE
+#define WM_DDE_FIRST WM_DDE_INITIATE
+
+/* DDEACK: wStatus in WM_DDE_ACK message */
+struct tagDDEACK
+{
+ WORD bAppReturnCode:8, reserved:6, fBusy:1, fAck:1;
+};
+typedef struct tagDDEACK DDEACK;
+
+/* DDEDATA: hData in WM_DDE_DATA message */
+struct tagDDEDATA
+{
+ WORD unused:12, fResponse:1, fRelease:1, reserved:1, fAckReq:1,
+ cfFormat:16;
+ BYTE Value[1]; /* undetermined array */
+};
+typedef struct tagDDEDATA DDEDATA;
+
+
+/* DDEADVISE: hOptions in WM_DDE_ADVISE message */
+struct tagDDEADVISE
+{
+ WORD reserved:14, fDeferUpd:1, fAckReq:1, cfFormat:16;
+};
+typedef struct tagDDEADVISE DDEADVISE;
+
+/* DDEPOKE: hData in WM_DDE_POKE message. */
+struct tagDDEPOKE
+{
+ WORD unused:13, fRelease:1, fReserved:2, cfFormat:16;
+ BYTE Value[1]; /* undetermined array */
+};
+typedef struct tagDDEPOKE DDEPOKE;
+
+#endif /* __WINE_DDE_H */
diff --git a/include/dde_atom.h b/include/dde_atom.h
new file mode 100644
index 0000000..56df6b7
--- /dev/null
+++ b/include/dde_atom.h
@@ -0,0 +1,23 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_atom.h
+ * Purpose : atom functionality for DDE
+ ***************************************************************************
+ */
+#ifndef __WINE_DDE_ATOM_H
+#define __WINE_DDE_ATOM_H
+#include "windows.h"
+
+#define DDE_ATOMS 157 /* a prime number for hashing */
+
+void ATOM_GlobalInit(void);
+/*
+ATOM GlobalAddAtom( LPCSTR str );
+ATOM GlobalDeleteAtom( ATOM atom );
+ATOM GlobalFindAtom( LPCSTR str );
+WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
+*/
+#endif __WINE_DDE_ATOM_H
diff --git a/include/dde_mem.h b/include/dde_mem.h
new file mode 100644
index 0000000..6a830e1
--- /dev/null
+++ b/include/dde_mem.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_mem.h
+ * Purpose : shared DDE memory functionality for DDE
+ ***************************************************************************
+ */
+#ifndef __WINE_DDE_MEM_H
+#define __WINE_DDE_MEM_H
+#include "wintypes.h"
+#include "global.h"
+#include "shm_block.h"
+
+#define DDE_HANDLES 0x0400
+#define is_dde_handle(block) ( (block) >= (1<<15) && (block) < (1<<15)+DDE_HANDLES )
+typedef struct {
+ int shmid;
+ REL_PTR rel;
+}DDE_HWND;
+
+WORD DDE_SyncHandle(HGLOBAL handle, WORD sel);
+void *DDE_malloc(unsigned int flags,unsigned long size, SHMDATA *shmdata);
+HANDLE DDE_GlobalReAlloc(WORD,long,WORD);
+HANDLE DDE_GlobalFree(WORD block);
+void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr);
+WORD DDE_GlobalHandleToSel( HGLOBAL handle );
+int DDE_GlobalUnlock(int);
+HANDLE DDE_GlobalSize(WORD);
+HANDLE DDE_GlobalHandle(WORD);
+HANDLE DDE_GlobalFlags(WORD);
+
+#endif /* __WINE_DDE_MEM_H */
diff --git a/include/dde_proc.h b/include/dde_proc.h
new file mode 100644
index 0000000..85e682a
--- /dev/null
+++ b/include/dde_proc.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_proc.h
+ * Purpose : DDE signals and processes functionality for DDE
+ ***************************************************************************
+ */
+#ifndef __WINE_DDE_PROC_H
+#define __WINE_DDE_PROC_H
+#include <setjmp.h>
+#include "wintypes.h"
+#include "windows.h"
+#define DDE_PROCS 64
+#define DDE_WINDOWS 64
+struct _dde_proc {
+ int msg; /* message queue for this process */
+ int shmid; /* first shared memory block id. */
+ int sem; /* semaphore for fragment allocation */
+ int pid;
+} ;
+typedef struct _dde_proc *dde_proc;
+
+extern sigjmp_buf env_wait_x;
+enum stop_wait_op { /* The action to be taken upon SIGUSR2 */
+ CONT, /* Don't do anything */
+ STOP_WAIT_ACK, /* Use siglongjmp to stop wait_ack() */
+ STOP_WAIT_X /* siglongjmp to stop MSG_WaitXEvent() */
+};
+
+typedef struct {
+ WORD proc_idx; /* index into wine's process table */
+ HWND wnd; /* Window on the local proccess */
+} WND_DATA;
+extern enum stop_wait_op stop_wait_op;
+extern int had_SIGUSR2;
+
+extern int curr_proc_idx;
+void stop_wait(int a); /* signal handler for SIGUSR2
+ (interrupts "select" system call) */
+void dde_proc_init(dde_proc proc); /* init proc array */
+void dde_proc_done(dde_proc proc); /* delete a proc entry */
+void dde_proc_refresh(dde_proc proc); /* delete entry, if old junk */
+void dde_proc_add(dde_proc proc); /* Add current proc to proc array */
+void dde_msg_setup(int *msg_ptr);
+int dde_reschedule();
+void dde_wnd_setup(); /* setup Data structure of DDE windows */
+
+/* Send ack. to hnd indicating that posted/sent msg. got to destination*/
+void dde_proc_send_ack(HWND wnd, BOOL val);
+BOOL DDE_PostMessage( MSG *msg);
+BOOL DDE_SendMessage( MSG *msg);
+int DDE_GetRemoteMessage();
+void DDE_DestroyWindow(HWND hwnd); /* delete DDE info regarding hwnd */
+void DDE_TestDDE(HWND hwnd); /* do we have dde handling in the window ?*/
+#endif /* __WINE_DDE_PROC_H */
diff --git a/include/debug.h b/include/debug.h
index d728531..8d74615 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -17,6 +17,7 @@
#ifdef DEBUG_NONE_EXT
#undef DEBUG_ACCEL
+#undef DEBUG_ATOM
#undef DEBUG_BITBLT
#undef DEBUG_BITMAP
#undef DEBUG_CARET
@@ -29,6 +30,7 @@
#undef DEBUG_COMM
#undef DEBUG_CURSOR
#undef DEBUG_DC
+#undef DEBUG_DDE
#undef DEBUG_DIALOG
#undef DEBUG_DLL
#undef DEBUG_DOSFS
@@ -77,6 +79,9 @@
#undef DEBUG_SCROLL
#undef DEBUG_SELECTOR
#undef DEBUG_SELECTORS
+#undef DEBUG_SEM
+#undef DEBUG_SHM
+#undef DEBUG_SPY
#undef DEBUG_STRESS
#undef DEBUG_SYSCOLOR
#undef DEBUG_TASK
@@ -90,6 +95,7 @@
#ifdef DEBUG_ALL_EXT
#define DEBUG_ACCEL
+#define DEBUG_ATOM
#define DEBUG_BITBLT
#define DEBUG_BITMAP
#define DEBUG_CARET
@@ -102,6 +108,7 @@
#define DEBUG_COMM
#define DEBUG_CURSOR
#define DEBUG_DC
+#define DEBUG_DDE
#define DEBUG_DIALOG
#define DEBUG_DLL
#define DEBUG_DOSFS
@@ -150,6 +157,9 @@
#define DEBUG_SCROLL
#define DEBUG_SELECTOR
#define DEBUG_SELECTORS
+#define DEBUG_SEM
+#define DEBUG_SHM
+#define DEBUG_SPY
#define DEBUG_STRESS
#define DEBUG_SYSCOLOR
#define DEBUG_TASK
@@ -169,6 +179,11 @@
#else
0,
#endif
+#ifdef DEBUG_ATOM
+ 1,
+#else
+ 0,
+#endif
#ifdef DEBUG_BITBLT
1,
#else
@@ -229,6 +244,11 @@
#else
0,
#endif
+#ifdef DEBUG_DDE
+ 1,
+#else
+ 0,
+#endif
#ifdef DEBUG_DIALOG
1,
#else
@@ -469,6 +489,21 @@
#else
0,
#endif
+#ifdef DEBUG_SEM
+ 1,
+#else
+ 0,
+#endif
+#ifdef DEBUG_SHM
+ 1,
+#else
+ 0,
+#endif
+#ifdef DEBUG_SPY
+ 1,
+#else
+ 0,
+#endif
#ifdef DEBUG_STRESS
1,
#else
@@ -535,8 +570,21 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_bitblt if(!debug_msg_enabled[1]) ; else fprintf
-#define debugging_bitblt debug_msg_enabled[1]
+#define dprintf_atom if(!debug_msg_enabled[1]) ; else fprintf
+#define debugging_atom debug_msg_enabled[1]
+#else
+#ifdef DEBUG_ATOM
+#define dprintf_atom fprintf
+#define debugging_atom 1
+#else
+#define dprintf_atom while(0) fprintf
+#define debugging_atom 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_bitblt if(!debug_msg_enabled[2]) ; else fprintf
+#define debugging_bitblt debug_msg_enabled[2]
#else
#ifdef DEBUG_BITBLT
#define dprintf_bitblt fprintf
@@ -548,8 +596,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_bitmap if(!debug_msg_enabled[2]) ; else fprintf
-#define debugging_bitmap debug_msg_enabled[2]
+#define dprintf_bitmap if(!debug_msg_enabled[3]) ; else fprintf
+#define debugging_bitmap debug_msg_enabled[3]
#else
#ifdef DEBUG_BITMAP
#define dprintf_bitmap fprintf
@@ -561,8 +609,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_caret if(!debug_msg_enabled[3]) ; else fprintf
-#define debugging_caret debug_msg_enabled[3]
+#define dprintf_caret if(!debug_msg_enabled[4]) ; else fprintf
+#define debugging_caret debug_msg_enabled[4]
#else
#ifdef DEBUG_CARET
#define dprintf_caret fprintf
@@ -574,8 +622,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_catch if(!debug_msg_enabled[4]) ; else fprintf
-#define debugging_catch debug_msg_enabled[4]
+#define dprintf_catch if(!debug_msg_enabled[5]) ; else fprintf
+#define debugging_catch debug_msg_enabled[5]
#else
#ifdef DEBUG_CATCH
#define dprintf_catch fprintf
@@ -587,8 +635,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_cdaudio if(!debug_msg_enabled[5]) ; else fprintf
-#define debugging_cdaudio debug_msg_enabled[5]
+#define dprintf_cdaudio if(!debug_msg_enabled[6]) ; else fprintf
+#define debugging_cdaudio debug_msg_enabled[6]
#else
#ifdef DEBUG_CDAUDIO
#define dprintf_cdaudio fprintf
@@ -600,8 +648,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_class if(!debug_msg_enabled[6]) ; else fprintf
-#define debugging_class debug_msg_enabled[6]
+#define dprintf_class if(!debug_msg_enabled[7]) ; else fprintf
+#define debugging_class debug_msg_enabled[7]
#else
#ifdef DEBUG_CLASS
#define dprintf_class fprintf
@@ -613,8 +661,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_clipboard if(!debug_msg_enabled[7]) ; else fprintf
-#define debugging_clipboard debug_msg_enabled[7]
+#define dprintf_clipboard if(!debug_msg_enabled[8]) ; else fprintf
+#define debugging_clipboard debug_msg_enabled[8]
#else
#ifdef DEBUG_CLIPBOARD
#define dprintf_clipboard fprintf
@@ -626,8 +674,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_clipping if(!debug_msg_enabled[8]) ; else fprintf
-#define debugging_clipping debug_msg_enabled[8]
+#define dprintf_clipping if(!debug_msg_enabled[9]) ; else fprintf
+#define debugging_clipping debug_msg_enabled[9]
#else
#ifdef DEBUG_CLIPPING
#define dprintf_clipping fprintf
@@ -639,8 +687,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_combo if(!debug_msg_enabled[9]) ; else fprintf
-#define debugging_combo debug_msg_enabled[9]
+#define dprintf_combo if(!debug_msg_enabled[10]) ; else fprintf
+#define debugging_combo debug_msg_enabled[10]
#else
#ifdef DEBUG_COMBO
#define dprintf_combo fprintf
@@ -652,8 +700,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_comm if(!debug_msg_enabled[10]) ; else fprintf
-#define debugging_comm debug_msg_enabled[10]
+#define dprintf_comm if(!debug_msg_enabled[11]) ; else fprintf
+#define debugging_comm debug_msg_enabled[11]
#else
#ifdef DEBUG_COMM
#define dprintf_comm fprintf
@@ -665,8 +713,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_cursor if(!debug_msg_enabled[11]) ; else fprintf
-#define debugging_cursor debug_msg_enabled[11]
+#define dprintf_cursor if(!debug_msg_enabled[12]) ; else fprintf
+#define debugging_cursor debug_msg_enabled[12]
#else
#ifdef DEBUG_CURSOR
#define dprintf_cursor fprintf
@@ -678,8 +726,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_dc if(!debug_msg_enabled[12]) ; else fprintf
-#define debugging_dc debug_msg_enabled[12]
+#define dprintf_dc if(!debug_msg_enabled[13]) ; else fprintf
+#define debugging_dc debug_msg_enabled[13]
#else
#ifdef DEBUG_DC
#define dprintf_dc fprintf
@@ -691,8 +739,21 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_dialog if(!debug_msg_enabled[13]) ; else fprintf
-#define debugging_dialog debug_msg_enabled[13]
+#define dprintf_dde if(!debug_msg_enabled[14]) ; else fprintf
+#define debugging_dde debug_msg_enabled[14]
+#else
+#ifdef DEBUG_DDE
+#define dprintf_dde fprintf
+#define debugging_dde 1
+#else
+#define dprintf_dde while(0) fprintf
+#define debugging_dde 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_dialog if(!debug_msg_enabled[15]) ; else fprintf
+#define debugging_dialog debug_msg_enabled[15]
#else
#ifdef DEBUG_DIALOG
#define dprintf_dialog fprintf
@@ -704,8 +765,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_dll if(!debug_msg_enabled[14]) ; else fprintf
-#define debugging_dll debug_msg_enabled[14]
+#define dprintf_dll if(!debug_msg_enabled[16]) ; else fprintf
+#define debugging_dll debug_msg_enabled[16]
#else
#ifdef DEBUG_DLL
#define dprintf_dll fprintf
@@ -717,8 +778,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_dosfs if(!debug_msg_enabled[15]) ; else fprintf
-#define debugging_dosfs debug_msg_enabled[15]
+#define dprintf_dosfs if(!debug_msg_enabled[17]) ; else fprintf
+#define debugging_dosfs debug_msg_enabled[17]
#else
#ifdef DEBUG_DOSFS
#define dprintf_dosfs fprintf
@@ -730,8 +791,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_driver if(!debug_msg_enabled[16]) ; else fprintf
-#define debugging_driver debug_msg_enabled[16]
+#define dprintf_driver if(!debug_msg_enabled[18]) ; else fprintf
+#define debugging_driver debug_msg_enabled[18]
#else
#ifdef DEBUG_DRIVER
#define dprintf_driver fprintf
@@ -743,8 +804,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_edit if(!debug_msg_enabled[17]) ; else fprintf
-#define debugging_edit debug_msg_enabled[17]
+#define dprintf_edit if(!debug_msg_enabled[19]) ; else fprintf
+#define debugging_edit debug_msg_enabled[19]
#else
#ifdef DEBUG_EDIT
#define dprintf_edit fprintf
@@ -756,8 +817,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_enum if(!debug_msg_enabled[18]) ; else fprintf
-#define debugging_enum debug_msg_enabled[18]
+#define dprintf_enum if(!debug_msg_enabled[20]) ; else fprintf
+#define debugging_enum debug_msg_enabled[20]
#else
#ifdef DEBUG_ENUM
#define dprintf_enum fprintf
@@ -769,8 +830,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_event if(!debug_msg_enabled[19]) ; else fprintf
-#define debugging_event debug_msg_enabled[19]
+#define dprintf_event if(!debug_msg_enabled[21]) ; else fprintf
+#define debugging_event debug_msg_enabled[21]
#else
#ifdef DEBUG_EVENT
#define dprintf_event fprintf
@@ -782,8 +843,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_exec if(!debug_msg_enabled[20]) ; else fprintf
-#define debugging_exec debug_msg_enabled[20]
+#define dprintf_exec if(!debug_msg_enabled[22]) ; else fprintf
+#define debugging_exec debug_msg_enabled[22]
#else
#ifdef DEBUG_EXEC
#define dprintf_exec fprintf
@@ -795,8 +856,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_file if(!debug_msg_enabled[21]) ; else fprintf
-#define debugging_file debug_msg_enabled[21]
+#define dprintf_file if(!debug_msg_enabled[23]) ; else fprintf
+#define debugging_file debug_msg_enabled[23]
#else
#ifdef DEBUG_FILE
#define dprintf_file fprintf
@@ -808,8 +869,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_fixup if(!debug_msg_enabled[22]) ; else fprintf
-#define debugging_fixup debug_msg_enabled[22]
+#define dprintf_fixup if(!debug_msg_enabled[24]) ; else fprintf
+#define debugging_fixup debug_msg_enabled[24]
#else
#ifdef DEBUG_FIXUP
#define dprintf_fixup fprintf
@@ -821,8 +882,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_font if(!debug_msg_enabled[23]) ; else fprintf
-#define debugging_font debug_msg_enabled[23]
+#define dprintf_font if(!debug_msg_enabled[25]) ; else fprintf
+#define debugging_font debug_msg_enabled[25]
#else
#ifdef DEBUG_FONT
#define dprintf_font fprintf
@@ -834,8 +895,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_gdi if(!debug_msg_enabled[24]) ; else fprintf
-#define debugging_gdi debug_msg_enabled[24]
+#define dprintf_gdi if(!debug_msg_enabled[26]) ; else fprintf
+#define debugging_gdi debug_msg_enabled[26]
#else
#ifdef DEBUG_GDI
#define dprintf_gdi fprintf
@@ -847,8 +908,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_global if(!debug_msg_enabled[25]) ; else fprintf
-#define debugging_global debug_msg_enabled[25]
+#define dprintf_global if(!debug_msg_enabled[27]) ; else fprintf
+#define debugging_global debug_msg_enabled[27]
#else
#ifdef DEBUG_GLOBAL
#define dprintf_global fprintf
@@ -860,8 +921,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_graphics if(!debug_msg_enabled[26]) ; else fprintf
-#define debugging_graphics debug_msg_enabled[26]
+#define dprintf_graphics if(!debug_msg_enabled[28]) ; else fprintf
+#define debugging_graphics debug_msg_enabled[28]
#else
#ifdef DEBUG_GRAPHICS
#define dprintf_graphics fprintf
@@ -873,8 +934,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_icon if(!debug_msg_enabled[27]) ; else fprintf
-#define debugging_icon debug_msg_enabled[27]
+#define dprintf_icon if(!debug_msg_enabled[29]) ; else fprintf
+#define debugging_icon debug_msg_enabled[29]
#else
#ifdef DEBUG_ICON
#define dprintf_icon fprintf
@@ -886,8 +947,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_int if(!debug_msg_enabled[28]) ; else fprintf
-#define debugging_int debug_msg_enabled[28]
+#define dprintf_int if(!debug_msg_enabled[30]) ; else fprintf
+#define debugging_int debug_msg_enabled[30]
#else
#ifdef DEBUG_INT
#define dprintf_int fprintf
@@ -899,8 +960,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_key if(!debug_msg_enabled[29]) ; else fprintf
-#define debugging_key debug_msg_enabled[29]
+#define dprintf_key if(!debug_msg_enabled[31]) ; else fprintf
+#define debugging_key debug_msg_enabled[31]
#else
#ifdef DEBUG_KEY
#define dprintf_key fprintf
@@ -912,8 +973,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_keyboard if(!debug_msg_enabled[30]) ; else fprintf
-#define debugging_keyboard debug_msg_enabled[30]
+#define dprintf_keyboard if(!debug_msg_enabled[32]) ; else fprintf
+#define debugging_keyboard debug_msg_enabled[32]
#else
#ifdef DEBUG_KEYBOARD
#define dprintf_keyboard fprintf
@@ -925,8 +986,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_ldt if(!debug_msg_enabled[31]) ; else fprintf
-#define debugging_ldt debug_msg_enabled[31]
+#define dprintf_ldt if(!debug_msg_enabled[33]) ; else fprintf
+#define debugging_ldt debug_msg_enabled[33]
#else
#ifdef DEBUG_LDT
#define dprintf_ldt fprintf
@@ -938,8 +999,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_listbox if(!debug_msg_enabled[32]) ; else fprintf
-#define debugging_listbox debug_msg_enabled[32]
+#define dprintf_listbox if(!debug_msg_enabled[34]) ; else fprintf
+#define debugging_listbox debug_msg_enabled[34]
#else
#ifdef DEBUG_LISTBOX
#define dprintf_listbox fprintf
@@ -951,8 +1012,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_local if(!debug_msg_enabled[33]) ; else fprintf
-#define debugging_local debug_msg_enabled[33]
+#define dprintf_local if(!debug_msg_enabled[35]) ; else fprintf
+#define debugging_local debug_msg_enabled[35]
#else
#ifdef DEBUG_LOCAL
#define dprintf_local fprintf
@@ -964,8 +1025,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_malloc if(!debug_msg_enabled[34]) ; else fprintf
-#define debugging_malloc debug_msg_enabled[34]
+#define dprintf_malloc if(!debug_msg_enabled[36]) ; else fprintf
+#define debugging_malloc debug_msg_enabled[36]
#else
#ifdef DEBUG_MALLOC
#define dprintf_malloc fprintf
@@ -977,8 +1038,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mci if(!debug_msg_enabled[35]) ; else fprintf
-#define debugging_mci debug_msg_enabled[35]
+#define dprintf_mci if(!debug_msg_enabled[37]) ; else fprintf
+#define debugging_mci debug_msg_enabled[37]
#else
#ifdef DEBUG_MCI
#define dprintf_mci fprintf
@@ -990,8 +1051,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mcianim if(!debug_msg_enabled[36]) ; else fprintf
-#define debugging_mcianim debug_msg_enabled[36]
+#define dprintf_mcianim if(!debug_msg_enabled[38]) ; else fprintf
+#define debugging_mcianim debug_msg_enabled[38]
#else
#ifdef DEBUG_MCIANIM
#define dprintf_mcianim fprintf
@@ -1003,8 +1064,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mciwave if(!debug_msg_enabled[37]) ; else fprintf
-#define debugging_mciwave debug_msg_enabled[37]
+#define dprintf_mciwave if(!debug_msg_enabled[39]) ; else fprintf
+#define debugging_mciwave debug_msg_enabled[39]
#else
#ifdef DEBUG_MCIWAVE
#define dprintf_mciwave fprintf
@@ -1016,8 +1077,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mdi if(!debug_msg_enabled[38]) ; else fprintf
-#define debugging_mdi debug_msg_enabled[38]
+#define dprintf_mdi if(!debug_msg_enabled[40]) ; else fprintf
+#define debugging_mdi debug_msg_enabled[40]
#else
#ifdef DEBUG_MDI
#define dprintf_mdi fprintf
@@ -1029,8 +1090,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_menu if(!debug_msg_enabled[39]) ; else fprintf
-#define debugging_menu debug_msg_enabled[39]
+#define dprintf_menu if(!debug_msg_enabled[41]) ; else fprintf
+#define debugging_menu debug_msg_enabled[41]
#else
#ifdef DEBUG_MENU
#define dprintf_menu fprintf
@@ -1042,8 +1103,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_menucalc if(!debug_msg_enabled[40]) ; else fprintf
-#define debugging_menucalc debug_msg_enabled[40]
+#define dprintf_menucalc if(!debug_msg_enabled[42]) ; else fprintf
+#define debugging_menucalc debug_msg_enabled[42]
#else
#ifdef DEBUG_MENUCALC
#define dprintf_menucalc fprintf
@@ -1055,8 +1116,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_message if(!debug_msg_enabled[41]) ; else fprintf
-#define debugging_message debug_msg_enabled[41]
+#define dprintf_message if(!debug_msg_enabled[43]) ; else fprintf
+#define debugging_message debug_msg_enabled[43]
#else
#ifdef DEBUG_MESSAGE
#define dprintf_message fprintf
@@ -1068,8 +1129,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_metafile if(!debug_msg_enabled[42]) ; else fprintf
-#define debugging_metafile debug_msg_enabled[42]
+#define dprintf_metafile if(!debug_msg_enabled[44]) ; else fprintf
+#define debugging_metafile debug_msg_enabled[44]
#else
#ifdef DEBUG_METAFILE
#define dprintf_metafile fprintf
@@ -1081,8 +1142,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_midi if(!debug_msg_enabled[43]) ; else fprintf
-#define debugging_midi debug_msg_enabled[43]
+#define dprintf_midi if(!debug_msg_enabled[45]) ; else fprintf
+#define debugging_midi debug_msg_enabled[45]
#else
#ifdef DEBUG_MIDI
#define dprintf_midi fprintf
@@ -1094,8 +1155,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mmio if(!debug_msg_enabled[44]) ; else fprintf
-#define debugging_mmio debug_msg_enabled[44]
+#define dprintf_mmio if(!debug_msg_enabled[46]) ; else fprintf
+#define debugging_mmio debug_msg_enabled[46]
#else
#ifdef DEBUG_MMIO
#define dprintf_mmio fprintf
@@ -1107,8 +1168,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mmsys if(!debug_msg_enabled[45]) ; else fprintf
-#define debugging_mmsys debug_msg_enabled[45]
+#define dprintf_mmsys if(!debug_msg_enabled[47]) ; else fprintf
+#define debugging_mmsys debug_msg_enabled[47]
#else
#ifdef DEBUG_MMSYS
#define dprintf_mmsys fprintf
@@ -1120,8 +1181,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_mmtime if(!debug_msg_enabled[46]) ; else fprintf
-#define debugging_mmtime debug_msg_enabled[46]
+#define dprintf_mmtime if(!debug_msg_enabled[48]) ; else fprintf
+#define debugging_mmtime debug_msg_enabled[48]
#else
#ifdef DEBUG_MMTIME
#define dprintf_mmtime fprintf
@@ -1133,8 +1194,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_module if(!debug_msg_enabled[47]) ; else fprintf
-#define debugging_module debug_msg_enabled[47]
+#define dprintf_module if(!debug_msg_enabled[49]) ; else fprintf
+#define debugging_module debug_msg_enabled[49]
#else
#ifdef DEBUG_MODULE
#define dprintf_module fprintf
@@ -1146,8 +1207,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_msg if(!debug_msg_enabled[48]) ; else fprintf
-#define debugging_msg debug_msg_enabled[48]
+#define dprintf_msg if(!debug_msg_enabled[50]) ; else fprintf
+#define debugging_msg debug_msg_enabled[50]
#else
#ifdef DEBUG_MSG
#define dprintf_msg fprintf
@@ -1159,8 +1220,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_nonclient if(!debug_msg_enabled[49]) ; else fprintf
-#define debugging_nonclient debug_msg_enabled[49]
+#define dprintf_nonclient if(!debug_msg_enabled[51]) ; else fprintf
+#define debugging_nonclient debug_msg_enabled[51]
#else
#ifdef DEBUG_NONCLIENT
#define dprintf_nonclient fprintf
@@ -1172,8 +1233,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_ole if(!debug_msg_enabled[50]) ; else fprintf
-#define debugging_ole debug_msg_enabled[50]
+#define dprintf_ole if(!debug_msg_enabled[52]) ; else fprintf
+#define debugging_ole debug_msg_enabled[52]
#else
#ifdef DEBUG_OLE
#define dprintf_ole fprintf
@@ -1185,8 +1246,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_palette if(!debug_msg_enabled[51]) ; else fprintf
-#define debugging_palette debug_msg_enabled[51]
+#define dprintf_palette if(!debug_msg_enabled[53]) ; else fprintf
+#define debugging_palette debug_msg_enabled[53]
#else
#ifdef DEBUG_PALETTE
#define dprintf_palette fprintf
@@ -1198,8 +1259,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_profile if(!debug_msg_enabled[52]) ; else fprintf
-#define debugging_profile debug_msg_enabled[52]
+#define dprintf_profile if(!debug_msg_enabled[54]) ; else fprintf
+#define debugging_profile debug_msg_enabled[54]
#else
#ifdef DEBUG_PROFILE
#define dprintf_profile fprintf
@@ -1211,8 +1272,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_prop if(!debug_msg_enabled[53]) ; else fprintf
-#define debugging_prop debug_msg_enabled[53]
+#define dprintf_prop if(!debug_msg_enabled[55]) ; else fprintf
+#define debugging_prop debug_msg_enabled[55]
#else
#ifdef DEBUG_PROP
#define dprintf_prop fprintf
@@ -1224,8 +1285,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_reg if(!debug_msg_enabled[54]) ; else fprintf
-#define debugging_reg debug_msg_enabled[54]
+#define dprintf_reg if(!debug_msg_enabled[56]) ; else fprintf
+#define debugging_reg debug_msg_enabled[56]
#else
#ifdef DEBUG_REG
#define dprintf_reg fprintf
@@ -1237,8 +1298,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_region if(!debug_msg_enabled[55]) ; else fprintf
-#define debugging_region debug_msg_enabled[55]
+#define dprintf_region if(!debug_msg_enabled[57]) ; else fprintf
+#define debugging_region debug_msg_enabled[57]
#else
#ifdef DEBUG_REGION
#define dprintf_region fprintf
@@ -1250,8 +1311,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_relay if(!debug_msg_enabled[56]) ; else fprintf
-#define debugging_relay debug_msg_enabled[56]
+#define dprintf_relay if(!debug_msg_enabled[58]) ; else fprintf
+#define debugging_relay debug_msg_enabled[58]
#else
#ifdef DEBUG_RELAY
#define dprintf_relay fprintf
@@ -1263,8 +1324,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_resource if(!debug_msg_enabled[57]) ; else fprintf
-#define debugging_resource debug_msg_enabled[57]
+#define dprintf_resource if(!debug_msg_enabled[59]) ; else fprintf
+#define debugging_resource debug_msg_enabled[59]
#else
#ifdef DEBUG_RESOURCE
#define dprintf_resource fprintf
@@ -1276,8 +1337,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_scroll if(!debug_msg_enabled[58]) ; else fprintf
-#define debugging_scroll debug_msg_enabled[58]
+#define dprintf_scroll if(!debug_msg_enabled[60]) ; else fprintf
+#define debugging_scroll debug_msg_enabled[60]
#else
#ifdef DEBUG_SCROLL
#define dprintf_scroll fprintf
@@ -1289,8 +1350,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_selector if(!debug_msg_enabled[59]) ; else fprintf
-#define debugging_selector debug_msg_enabled[59]
+#define dprintf_selector if(!debug_msg_enabled[61]) ; else fprintf
+#define debugging_selector debug_msg_enabled[61]
#else
#ifdef DEBUG_SELECTOR
#define dprintf_selector fprintf
@@ -1302,8 +1363,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_selectors if(!debug_msg_enabled[60]) ; else fprintf
-#define debugging_selectors debug_msg_enabled[60]
+#define dprintf_selectors if(!debug_msg_enabled[62]) ; else fprintf
+#define debugging_selectors debug_msg_enabled[62]
#else
#ifdef DEBUG_SELECTORS
#define dprintf_selectors fprintf
@@ -1315,8 +1376,47 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_stress if(!debug_msg_enabled[61]) ; else fprintf
-#define debugging_stress debug_msg_enabled[61]
+#define dprintf_sem if(!debug_msg_enabled[63]) ; else fprintf
+#define debugging_sem debug_msg_enabled[63]
+#else
+#ifdef DEBUG_SEM
+#define dprintf_sem fprintf
+#define debugging_sem 1
+#else
+#define dprintf_sem while(0) fprintf
+#define debugging_sem 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_shm if(!debug_msg_enabled[64]) ; else fprintf
+#define debugging_shm debug_msg_enabled[64]
+#else
+#ifdef DEBUG_SHM
+#define dprintf_shm fprintf
+#define debugging_shm 1
+#else
+#define dprintf_shm while(0) fprintf
+#define debugging_shm 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_spy if(!debug_msg_enabled[65]) ; else fprintf
+#define debugging_spy debug_msg_enabled[65]
+#else
+#ifdef DEBUG_SPY
+#define dprintf_spy fprintf
+#define debugging_spy 1
+#else
+#define dprintf_spy while(0) fprintf
+#define debugging_spy 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_stress if(!debug_msg_enabled[66]) ; else fprintf
+#define debugging_stress debug_msg_enabled[66]
#else
#ifdef DEBUG_STRESS
#define dprintf_stress fprintf
@@ -1328,8 +1428,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_syscolor if(!debug_msg_enabled[62]) ; else fprintf
-#define debugging_syscolor debug_msg_enabled[62]
+#define dprintf_syscolor if(!debug_msg_enabled[67]) ; else fprintf
+#define debugging_syscolor debug_msg_enabled[67]
#else
#ifdef DEBUG_SYSCOLOR
#define dprintf_syscolor fprintf
@@ -1341,8 +1441,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_task if(!debug_msg_enabled[63]) ; else fprintf
-#define debugging_task debug_msg_enabled[63]
+#define dprintf_task if(!debug_msg_enabled[68]) ; else fprintf
+#define debugging_task debug_msg_enabled[68]
#else
#ifdef DEBUG_TASK
#define dprintf_task fprintf
@@ -1354,8 +1454,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_text if(!debug_msg_enabled[64]) ; else fprintf
-#define debugging_text debug_msg_enabled[64]
+#define dprintf_text if(!debug_msg_enabled[69]) ; else fprintf
+#define debugging_text debug_msg_enabled[69]
#else
#ifdef DEBUG_TEXT
#define dprintf_text fprintf
@@ -1367,8 +1467,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_timer if(!debug_msg_enabled[65]) ; else fprintf
-#define debugging_timer debug_msg_enabled[65]
+#define dprintf_timer if(!debug_msg_enabled[70]) ; else fprintf
+#define debugging_timer debug_msg_enabled[70]
#else
#ifdef DEBUG_TIMER
#define dprintf_timer fprintf
@@ -1380,8 +1480,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_toolhelp if(!debug_msg_enabled[66]) ; else fprintf
-#define debugging_toolhelp debug_msg_enabled[66]
+#define dprintf_toolhelp if(!debug_msg_enabled[71]) ; else fprintf
+#define debugging_toolhelp debug_msg_enabled[71]
#else
#ifdef DEBUG_TOOLHELP
#define dprintf_toolhelp fprintf
@@ -1393,8 +1493,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_utility if(!debug_msg_enabled[67]) ; else fprintf
-#define debugging_utility debug_msg_enabled[67]
+#define dprintf_utility if(!debug_msg_enabled[72]) ; else fprintf
+#define debugging_utility debug_msg_enabled[72]
#else
#ifdef DEBUG_UTILITY
#define dprintf_utility fprintf
@@ -1406,8 +1506,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_win if(!debug_msg_enabled[68]) ; else fprintf
-#define debugging_win debug_msg_enabled[68]
+#define dprintf_win if(!debug_msg_enabled[73]) ; else fprintf
+#define debugging_win debug_msg_enabled[73]
#else
#ifdef DEBUG_WIN
#define dprintf_win fprintf
@@ -1419,8 +1519,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_winsock if(!debug_msg_enabled[69]) ; else fprintf
-#define debugging_winsock debug_msg_enabled[69]
+#define dprintf_winsock if(!debug_msg_enabled[74]) ; else fprintf
+#define debugging_winsock debug_msg_enabled[74]
#else
#ifdef DEBUG_WINSOCK
#define dprintf_winsock fprintf
@@ -1436,6 +1536,7 @@
#ifdef DEBUG_DEFINE_VARIABLES
static char *debug_msg_name[] = {
"accel",
+ "atom",
"bitblt",
"bitmap",
"caret",
@@ -1448,6 +1549,7 @@
"comm",
"cursor",
"dc",
+ "dde",
"dialog",
"dll",
"dosfs",
@@ -1496,6 +1598,9 @@
"scroll",
"selector",
"selectors",
+ "sem",
+ "shm",
+ "spy",
"stress",
"syscolor",
"task",
diff --git a/include/dos_fs.h b/include/dos_fs.h
index 01a458c..a6a91a3 100644
--- a/include/dos_fs.h
+++ b/include/dos_fs.h
@@ -10,10 +10,9 @@
extern void DOS_SetDefaultDrive(int drive);
extern void ToUnix(char *s);
extern void ToDos(char *s);
-extern void ChopOffSlash(char *string);
extern int DOS_DisableDrive(int drive);
extern int DOS_EnableDrive(int drive);
-extern char *DOS_GetUnixFileName(char *dosfilename);
+extern char *DOS_GetUnixFileName(const char *dosfilename);
extern char *DOS_GetDosFileName(char *unixfilename);
extern char *DOS_GetCurrentDir(int drive);
extern int DOS_ChangeDir(int drive, char *dirname);
@@ -29,8 +28,6 @@
extern struct dosdirent *DOS_opendir(char *dosdirname);
extern struct dosdirent *DOS_readdir(struct dosdirent *de);
extern void DOS_closedir(struct dosdirent *de);
-extern void DOS_ExpandToFullPath(char *filename, int drive);
-extern void DOS_ExpandToFullUnixPath(char *filename);
extern char *DOS_GetRedirectedDir(int drive);
extern void errno_to_doserr(void);
diff --git a/include/global.h b/include/global.h
index dd912ce..6ea7b40 100644
--- a/include/global.h
+++ b/include/global.h
@@ -9,9 +9,17 @@
#include "wintypes.h"
+typedef struct
+{
+ HGLOBAL handle;
+ WORD sel;
+ int shmid;
+} SHMDATA;
+
extern HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
HGLOBAL hOwner, BOOL isCode,
- BOOL is32Bit, BOOL isReadOnly );
+ BOOL is32Bit, BOOL isReadOnly,
+ SHMDATA *shmdata);
extern BOOL GLOBAL_FreeBlock( HGLOBAL handle );
extern HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
BOOL isCode, BOOL is32Bit, BOOL isReadOnly );
diff --git a/include/ldt.h b/include/ldt.h
index 6e7c853..76f9ca0 100644
--- a/include/ldt.h
+++ b/include/ldt.h
@@ -44,13 +44,13 @@
extern ldt_copy_entry ldt_copy[LDT_SIZE];
-#define __AHSHIFT 3
+#define __AHSHIFT 3 /* don't change! */
#define __AHINCR (1 << __AHSHIFT)
#ifndef WINELIB
#define SELECTOR_TO_ENTRY(sel) (((int)(sel) & 0xffff) >> __AHSHIFT)
#define ENTRY_TO_SELECTOR(i) ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
-#define IS_LDT_ENTRY_FREE(i) (!(ldt_copy[(i)].base || ldt_copy[(i)].limit))
+#define IS_LDT_ENTRY_FREE(i) (!(ldt_flags_copy[(i)] & LDT_FLAGS_ALLOCATED))
#define IS_SELECTOR_FREE(sel) (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
#define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
#define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
@@ -59,6 +59,7 @@
#define SELECTOR_TO_ENTRY(sel) error.error
#define ENTRY_TO_SELECTOR(i) error.error
#define IS_LDT_ENTRY_FREE(i) error.error
+#define IS_SELECTOR_FREE(sel) error.error
#define GET_SEL_BASE(sel) error.error
#define GET_SEL_LIMIT(sel) error.error
#endif
@@ -83,6 +84,7 @@
#define LDT_FLAGS_EXECONLY 0x04 /* Segment is execute-only (code) */
#define LDT_FLAGS_32BIT 0x08 /* Segment is 32-bit (code or stack) */
#define LDT_FLAGS_BIG 0x10 /* Segment is big (limit is in pages) */
+#define LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
#define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)])
diff --git a/include/miscemu.h b/include/miscemu.h
index e979ff1..2507a80 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -4,31 +4,10 @@
#include "wintypes.h"
#include "wine.h"
-extern BOOL INSTR_HandleInstruction( struct sigcontext_struct *context );
+extern BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context );
-extern int do_int10(struct sigcontext_struct *);
-extern int do_int13(struct sigcontext_struct *);
-extern int do_int15(struct sigcontext_struct *);
-extern int do_int16(struct sigcontext_struct *);
-extern int do_int1a(struct sigcontext_struct *);
-extern int do_int21(struct sigcontext_struct *);
-extern int do_int25(struct sigcontext_struct *);
-extern int do_int26(struct sigcontext_struct *);
-extern int do_int2a(struct sigcontext_struct *);
-extern int do_int2f(struct sigcontext_struct *);
-extern int do_int31(struct sigcontext_struct *);
-extern int do_int5c(struct sigcontext_struct *);
-
-extern void inportb( struct sigcontext_struct *context );
-extern void inport( struct sigcontext_struct *context, int long_op );
-extern void outportb( struct sigcontext_struct *context );
-extern void outport( struct sigcontext_struct *context, int long_op );
-extern void inportb_abs( struct sigcontext_struct *context);
-extern void inport_abs( struct sigcontext_struct *context, int long_op );
-extern void outportb_abs( struct sigcontext_struct *context );
-extern void outport_abs( struct sigcontext_struct *context, int long_op );
-
-extern void IntBarf(int i, struct sigcontext_struct *context);
+extern DWORD inport( int port, int count );
+extern void outport( int port, int count, DWORD value );
extern BOOL INT_Init(void);
extern SEGPTR INT_GetHandler( BYTE intnum );
@@ -36,4 +15,11 @@
extern void INT21_Init(void);
+
+#define INT_BARF(num) \
+ fprintf( stderr, "int%x: unknown/not implemented parameters:\n" \
+ "int%x: AX %04x, BX %04x, CX %04x, DX %04x, " \
+ "SI %04x, DI %04x, DS %04x, ES %04x\n", \
+ (num), (num), AX, BX, CX, DX, SI, DI, DS, ES )
+
#endif /* __WINE_MISCEMU_H */
diff --git a/include/msdos.h b/include/msdos.h
index 1a94bca..636ae22 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -40,21 +40,23 @@
extern struct DosDeviceStruct COM[MAX_PORTS];
extern struct DosDeviceStruct LPT[MAX_PORTS];
-#define setword(a,b) *(BYTE*)(a) = (b) & 0xff; \
- *((BYTE*)((a)+1)) = ((b)>>8) & 0xff;
+#define setword(a,b) do { *(BYTE*)(a) = (b) & 0xff; \
+ *((BYTE*)((a)+1)) = ((b)>>8) & 0xff;\
+ } while(0)
-#define setdword(a,b) *(BYTE*)(a) = (b) & 0xff; \
- *((BYTE*)(a)+1) = ((b)>>8) & 0xff; \
- *((BYTE*)(a)+2) = ((b)>>16) & 0xff; \
- *((BYTE*)(a)+3) = ((b)>>24) & 0xff;
+#define setdword(a,b) do { *(BYTE*)(a) = (b) & 0xff; \
+ *((BYTE*)(a)+1) = ((b)>>8) & 0xff; \
+ *((BYTE*)(a)+2) = ((b)>>16) & 0xff; \
+ *((BYTE*)(a)+3) = ((b)>>24) & 0xff; \
+ } while(0)
-#define getword(a) (WORD) *(BYTE*)(a) + \
- (*((BYTE*)(a) + 1) << 8)
+#define getword(a) ( (WORD)*(BYTE*)(a) + \
+ ((WORD)*((BYTE*)(a) + 1) << 8))
-#define getdword(a) (DWORD) (*(BYTE*)(a) + \
- (*((BYTE*)(a) + 1) << 8) + \
- (*((BYTE*)(a) + 2) << 16) + \
- (*((BYTE*)(a) + 3) << 24))
+#define getdword(a) ( (DWORD)*(BYTE*)(a) + \
+ (DWORD)(*((BYTE*)(a) + 1) << 8) + \
+ (DWORD)(*((BYTE*)(a) + 2) << 16) + \
+ (DWORD)(*((BYTE*)(a) + 3) << 24))
/* dos file attributes */
diff --git a/include/options.h b/include/options.h
index 80b8a73..a19ae57 100644
--- a/include/options.h
+++ b/include/options.h
@@ -9,7 +9,6 @@
struct options
{
- char * spyFilename;
char * desktopGeometry; /* NULL when no desktop */
char * programName; /* To use when loading resources */
int usePrivateMap;
diff --git a/include/pe_image.h b/include/pe_image.h
index d7fceee..169ddd8 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -1,6 +1,7 @@
#ifndef __WINE_PE_IMAGE_H
#define __WINE_PE_IMAGE_H
+extern void *RELAY32_GetEntryPoint(char *dll_name, char *item, int hint);
extern int PE_unloadImage(struct w_files *wpnt);
extern int PE_StartProgram(struct w_files *wpnt);
extern void PE_InitDLL(struct w_files *wpnt);
diff --git a/include/prototypes.h b/include/prototypes.h
deleted file mode 100644
index 5c8d64d..0000000
--- a/include/prototypes.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* $Id: prototypes.h,v 1.3 1993/07/04 04:04:21 root Exp root $
- */
-/*
- * Copyright Robert J. Amstadt, 1993
- */
-#ifndef _WINE_PROTOTYPES_H
-#define _WINE_PROTOTYPES_H
-
-#include <sys/types.h>
-
-#include "windows.h"
-
-#ifndef WINELIB
-
-/* loader/resource.c */
-
-extern HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image );
-extern HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image );
-
-/* loader/signal.c */
-
-extern void init_wine_signals(void);
-
-/* loader/wine.c */
-
-extern int _WinMain(int argc, char **argv);
-
-/* misc/spy.c */
-
-extern void SpyInit(void);
-
-#endif /* WINELIB */
-#endif /* _WINE_PROTOTYPES_H */
diff --git a/include/region.h b/include/region.h
index 7d87c13..e8f6261 100644
--- a/include/region.h
+++ b/include/region.h
@@ -18,5 +18,6 @@
extern BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj );
+extern BOOL REGION_FrameRgn(HRGN dest,HRGN src,int x,int y);
#endif /* __WINE_REGION_H */
diff --git a/include/registers.h b/include/registers.h
index 4af04bc..e6253f3 100644
--- a/include/registers.h
+++ b/include/registers.h
@@ -37,6 +37,14 @@
#define ES (context->sc_es)
#define SS (context->sc_ss)
+#ifdef linux
+#define FS (context->sc_fs)
+#define GS (context->sc_gs)
+#else /* FIXME: are fs and gs supported under *BSD? */
+#define FS 0
+#define GS 0
+#endif
+
#ifndef __FreeBSD__
#define EFL (context->sc_eflags)
#define FL (*(WORD*)&context->sc_eflags)
diff --git a/include/resource.h b/include/resource.h
index d389ce4..6a5eeb2 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -17,6 +17,9 @@
extern HGLOBAL NE_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size );
extern HGLOBAL NE_LoadResource( HMODULE hModule, HRSRC hRsrc );
+extern HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image );
+extern HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image );
+
struct ResourceTable
{
int id,type;
diff --git a/include/shell.h b/include/shell.h
index 6a30151..b222e7e 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -2,6 +2,8 @@
* Shell Library definitions
*/
+extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon);
+
#define ERROR_SUCCESS 0L
#define ERROR_BADDB 1L
#define ERROR_BADKEY 2L
diff --git a/include/shm_block.h b/include/shm_block.h
new file mode 100644
index 0000000..c19c84f
--- /dev/null
+++ b/include/shm_block.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_block.ch
+ * Purpose: treat a shared memory block.
+ ***************************************************************************
+ */
+#ifndef __WINE_SHM_BLOCK_H
+#define __WINE_SHM_BLOCK_H
+#include <sys/shm.h>
+#include "wintypes.h"
+#define SEGSIZE 0x10000 /* 64 */
+#define SHM_GRANULARITY SEGSIZE
+#define SHM_MINBLOCK SHM_GRANULARITY
+#define SHM_MAXBLOCK (((int)SHMMAX/(int)SHM_GRANULARITY)* \
+ SHM_GRANULARITY)
+#define PTR2REL(block,ptr) (REL_PTR) ( (char *) (ptr) - (char *) (block) )
+#define REL2PTR(block,rel) (void *) ( (char *) (block) + (rel) )
+
+typedef int REL_PTR;
+
+/* full info for each shm block. */
+struct shm_block {
+ /* private */
+ int next_shm_id; /* IPC shm ID (for initial linking) */
+
+ /* public (read only) */
+ int size; /* size of the shm block */
+ int free; /* how much of the block is free */
+ int proc_idx; /* The index of the owner */
+
+ /* public - writable for shm_fragment */
+ REL_PTR free_list; /* first item in the free list */
+};
+
+/* used for mapping local attachments */
+struct local_shm_map {
+ struct local_shm_map *next;
+ int shm_id;
+ int proc_idx;
+
+ /* 32 bit pointer to the beginning of the block */
+ struct shm_block *ptr;
+};
+extern struct local_shm_map *shm_map;
+void shm_setup_block(struct shm_block *block, REL_PTR first, int size);
+
+/* shm_create_block:
+ * allocate and setup a new block:
+ * first - first non header byte.
+ * size - block size (in bytes).
+ * shm_id- IPC shared memory ID.
+ */
+struct shm_block *shm_create_block(REL_PTR first, int size, int *shm_id);
+
+/* shm_locate_block:
+ * locate existing block according to shm_id,
+ * Attach the block if needed. Assume the shm_id is wine's
+ * Set selectors also.
+ */
+struct shm_block *shm_locate_block(int shm_id, struct local_shm_map *map);
+
+/* shm_locate_attached_block:
+ * locate existing block according to shm_id,
+ * Blocks are never attached.
+ * if proc_idx is not NULL, it will be set to owner's index.
+ * map - localy mapped info about block may be NULL;
+ */
+struct shm_block *shm_locate_attached_block(int shm_id,
+ struct local_shm_map *map);
+
+/* shm_attach_block: attach existing shm block, setup selectors
+ * shm_id - id of the block to attach.
+ * proc_idx - if not -1, puts this data into local mapping
+ * map - localy mapped info about this block. (may be NULL)
+ * NOTE: same block can be attached many times
+ */
+struct shm_block *shm_attach_block(int shm_id, int proc_idx,
+ struct local_shm_map *map);
+
+/* delete chain of shm blocks (pointing to each other */
+void shm_delete_chain(int *shmid);
+
+#endif /* __WINE_SHM_BLOCK_H */
diff --git a/include/shm_fragment.h b/include/shm_fragment.h
new file mode 100644
index 0000000..81a4b66
--- /dev/null
+++ b/include/shm_fragment.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_fragment.h
+ * Purpose: Data fragments and free list items. Allocate and free blocks.
+ ***************************************************************************
+ */
+#ifndef __WINE_SHM_FRAGMENT_H
+#define __WINE_SHM_FRAGMENT_H
+
+#include "shm_block.h"
+
+#define NIL ((int) 0)
+/* memory fragment: used or free (when free - it's an item of "free list",
+ * when allocated it contains the data, and it's size)
+ */
+struct shm_fragment {
+ int size; /* fragment's size */
+
+ /* The type of info depends on fragment's status (free/allocated) */
+ union info {
+ int next; /* next free fragment */
+ char data[1]; /* the data */
+ } info;
+};
+
+/* setup first item in the free list */
+void shm_FragmentInit(struct shm_block *block,REL_PTR first,int size);
+
+/* allocate shm fragment. return: offset to data in fragment, or NULL */
+REL_PTR shm_FragmentAlloc(struct shm_block *block, int size);
+
+/* like shm_FragmentAlloc, returns pointer instead of offset */
+char *shm_FragPtrAlloc(struct shm_block *block, int size);
+
+/* free shm fragment - according to offset */
+void shm_FragmentFree(struct shm_block *block, int ofs);
+
+/* free shm fragment - according to pointer */
+void shm_FragPtrFree(struct shm_block *block, void *ptr);
+
+/* This is used for debugging only */
+void shm_print_free_list(struct shm_block *block);
+
+#endif /* __WINE_SHM_FRAGMENT_H */
diff --git a/include/shm_main_blk.h b/include/shm_main_blk.h
new file mode 100644
index 0000000..e3f9e5b
--- /dev/null
+++ b/include/shm_main_blk.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_main_blk.h
+ * Purpose: Main Wine's shared memory block
+ ***************************************************************************
+ */
+#ifndef __WINE_SHM_MAIN_BLK_H
+#define __WINE_SHM_MAIN_BLK_H
+#include <sys/shm.h>
+#include "shm_block.h"
+#include "shm_semaph.h"
+#include "dde_proc.h"
+#include "dde_atom.h"
+#include "dde_mem.h"
+/*****************************************************************************
+ *
+ * main block object
+ *
+ *****************************************************************************
+ */
+#ifndef __inline__
+#ifndef __GNUC__
+#define __inline__
+#endif /* __GNUC__ */
+#endif /* __inline__ */
+
+#define DDE_HANDLES_BIT_ARRAY_SIZE (DDE_HANDLES/sizeof(int)/8)
+
+#define SHM_MAXID SHMSEG /* maximum shm blocks (Wine's limit) */
+struct shm_main_block {
+ /* NOTE: "block" declaration must be the first */
+ struct shm_block block;
+ char magic[64]; /* magic string to identify the block */
+ int build_lock; /* =1 when data structure not stable yet */
+ shm_sem sem; /* semaphores for main_block integrity */
+ struct _dde_proc proc[DDE_PROCS]; /* information about processes */
+ REL_PTR atoms[DDE_ATOMS]; /* relative reference to global atoms */
+ /* Translation from global window handles to local handles */
+ WND_DATA windows[DDE_WINDOWS];
+ DDE_HWND handles[DDE_HANDLES];
+ /* bit array stating if a handle is free (bit=0), LSB in */
+ /* free_handles[0] refers handle 0x8000, the MSB refers 0x801F */
+ unsigned free_handles[DDE_HANDLES_BIT_ARRAY_SIZE];
+};
+extern struct shm_main_block *main_block;
+int shm_init(void);
+void shm_delete_all(int shm_id);
+void DDE_mem_init();
+int DDE_no_of_attached();
+#define DDE_IPC_init() ( (main_block==NULL) ? (DDE_mem_init()) : 0 )
+
+#endif /* __WINE_SHM_MAIN_BLK_H */
diff --git a/include/shm_semaph.h b/include/shm_semaph.h
new file mode 100644
index 0000000..5562446
--- /dev/null
+++ b/include/shm_semaph.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_semaph.h
+ * Purpose: Handle semaphores for shared memory operations.
+ ***************************************************************************
+ */
+
+#ifndef __WINE_SHM_SEMAPH_H
+#define __WINE_SHM_SEMAPH_H
+/* IMPORTANT: If possible, restrict usage of these functions. */
+
+typedef int shm_sem;
+
+void shm_read_wait(shm_sem semid);
+void shm_write_wait(shm_sem semid);
+void shm_write_signal(shm_sem semid);
+void shm_read_signal(shm_sem semid);
+void shm_sem_init(shm_sem *semptr);
+void shm_sem_done(shm_sem *semptr);
+
+#endif /* __WINE_SHM_SEMAPH_H */
diff --git a/include/stackframe.h b/include/stackframe.h
index ee0195b..81fcf8e 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -19,6 +19,7 @@
{
WORD saved_ss; /* saved previous 16-bit stack */
WORD saved_sp;
+ WORD es;
WORD ds; /* 16-bit ds */
DWORD entry_point WINE_PACKED; /* entry point to call */
WORD ordinal_number; /* ordinal number of entry point */
diff --git a/include/stddebug.h b/include/stddebug.h
index b568098..b262020 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -77,6 +77,7 @@
#ifdef DEBUG_NONE
#undef DEBUG_ACCEL
+#undef DEBUG_ATOM
#undef DEBUG_BITBLT
#undef DEBUG_BITMAP
#undef DEBUG_CARET
@@ -89,6 +90,7 @@
#undef DEBUG_COMM
#undef DEBUG_CURSOR
#undef DEBUG_DC
+#undef DEBUG_DDE
#undef DEBUG_DIALOG
#undef DEBUG_DLL
#undef DEBUG_DOSFS
@@ -137,6 +139,9 @@
#undef DEBUG_SCROLL
#undef DEBUG_SELECTOR
#undef DEBUG_SELECTORS
+#undef DEBUG_SEM
+#undef DEBUG_SHM
+#undef DEBUG_SPY
#undef DEBUG_STRESS
#undef DEBUG_SYSCOLOR
#undef DEBUG_TASK
@@ -150,6 +155,7 @@
#ifdef DEBUG_ALL
#define DEBUG_ACCEL
+#define DEBUG_ATOM
#define DEBUG_BITBLT
#define DEBUG_BITMAP
#define DEBUG_CARET
@@ -162,6 +168,7 @@
#define DEBUG_COMM
#define DEBUG_CURSOR
#define DEBUG_DC
+#define DEBUG_DDE
#define DEBUG_DIALOG
#define DEBUG_DLL
#define DEBUG_DOSFS
@@ -210,6 +217,9 @@
#define DEBUG_SCROLL
#define DEBUG_SELECTOR
#define DEBUG_SELECTORS
+#define DEBUG_SEM
+#define DEBUG_SHM
+#define DEBUG_SPY
#define DEBUG_STRESS
#define DEBUG_SYSCOLOR
#define DEBUG_TASK
diff --git a/include/task.h b/include/task.h
index cbd28ae..dd7e9e8 100644
--- a/include/task.h
+++ b/include/task.h
@@ -13,6 +13,10 @@
#pragma pack(1)
#endif
+
+extern BOOL TASK_Init(void);
+extern void TASK_KillCurrentTask( int exitCode );
+
/* Process database (i.e. a normal DOS PSP) */
typedef struct
diff --git a/include/user.h b/include/user.h
index f749007..dc5c68a 100644
--- a/include/user.h
+++ b/include/user.h
@@ -10,6 +10,7 @@
#include "ldt.h"
#include "local.h"
+extern BOOL USER_HeapInit(void);
/* USER local heap */
#ifdef WINELIB
diff --git a/include/win.h b/include/win.h
index e1d1efe..2322240 100644
--- a/include/win.h
+++ b/include/win.h
@@ -74,6 +74,7 @@
extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam );
extern BOOL WIN_CreateDesktopWindow(void);
+extern HWND WIN_GetTopParent( HWND hwnd );
extern Display * display;
extern Screen * screen;
diff --git a/include/windows.h b/include/windows.h
index 0389728..eb2f910 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -2455,6 +2455,8 @@
Fa(DWORD,GetDCOrg,HDC,a)
Fa(DWORD,GetFreeSpace,WORD,a)
Fa(DWORD,GetHeapSpaces,HMODULE,a)
+Fa(DWORD,GetSelectorBase,WORD,a)
+Fa(DWORD,GetSelectorLimit,WORD,a)
Fa(DWORD,GetViewportExt,HDC,a)
Fa(DWORD,GetViewportOrg,HDC,a)
Fa(DWORD,GetWindowExt,HDC,a)
@@ -2524,10 +2526,11 @@
Fa(LPSTR,LockResource,HANDLE,a)
Fa(SEGPTR,AnsiNext,SEGPTR,a)
Fa(SEGPTR,GlobalWire,HGLOBAL,a)
-Fa(SEGPTR,WIN16_LockResource,HANDLE,a)
Fa(SEGPTR,WIN16_GlobalLock,HGLOBAL,a)
+Fa(SEGPTR,WIN16_LockResource,HANDLE,a)
Fa(UINT,GDIRealizePalette,HDC,a)
Fa(UINT,RealizePalette,HDC,a)
+Fa(WORD,AllocCStoDSAlias,WORD,a)
Fa(WORD,AllocDStoCSAlias,WORD,a)
Fa(WORD,AllocSelector,WORD,a)
Fa(WORD,AllocSelectorArray,WORD,a)
@@ -2716,6 +2719,8 @@
Fb(WORD,SetPolyFillMode,HDC,a,WORD,b)
Fb(WORD,SetROP2,HDC,a,WORD,b)
Fb(WORD,SetRelAbs,HDC,a,WORD,b)
+Fb(WORD,SetSelectorBase,WORD,a,DWORD,b)
+Fb(WORD,SetSelectorLimit,WORD,a,DWORD,b)
Fb(WORD,SetStretchBltMode,HDC,a,WORD,b)
Fb(WORD,SetSystemPaletteUse,HDC,a,WORD,b)
Fb(WORD,SetTextAlign,HDC,a,WORD,b)
@@ -2818,12 +2823,12 @@
Fc(INT,OpenFile,LPSTR,a,LPOFSTRUCT,b,WORD,c)
Fc(INT,_lread,INT,a,LPSTR,b,WORD,c)
Fc(INT,_lwrite,INT,a,LPCSTR,b,WORD,c)
-Fc(LONG,_hread,INT,a,LPSTR,b,LONG,c)
-Fc(LONG,_hwrite,INT,a,LPCSTR,b,LONG,c)
Fc(LONG,GetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
Fc(LONG,SetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
Fc(LONG,SetClassLong,HWND,a,short,b,LONG,c)
Fc(LONG,SetWindowLong,HWND,a,short,b,LONG,c)
+Fc(LONG,_hread,INT,a,LPSTR,b,LONG,c)
+Fc(LONG,_hwrite,INT,a,LPCSTR,b,LONG,c)
Fc(LONG,_llseek,INT,a,LONG,b,INT,c)
Fc(SEGPTR,lstrcpyn,SEGPTR,a,SEGPTR,b,WORD,c)
Fc(WORD,GetAtomName,ATOM,a,LPSTR,b,short,c)
@@ -2831,6 +2836,7 @@
Fc(WORD,GetMenuState,HMENU,a,WORD,b,WORD,c)
Fc(WORD,GetProfileInt,LPSTR,a,LPSTR,b,int,c)
Fc(WORD,GlobalGetAtomName,ATOM,a,LPSTR,b,short,c)
+Fc(WORD,SelectorAccessRights,WORD,a,WORD,b,WORD,c)
Fc(WORD,SetClassWord,HWND,a,short,b,WORD,c)
Fc(WORD,SetWindowWord,HWND,a,short,b,WORD,c)
Fc(int,FillRect,HDC,a,LPRECT,b,HBRUSH,c)
diff --git a/include/wineopts.h b/include/wineopts.h
deleted file mode 100644
index 6f3e66b..0000000
--- a/include/wineopts.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* WINEOPTS.H
- */
-
-#ifndef WINEOPTS_H
-#define WINEOPTS_H
-
-#include <stdio.h>
-
-FILE *SpyFp;
-
-#endif /* WINEOPTS_H */
diff --git a/include/winsock.h b/include/winsock.h
index 2a2674b..a0450c2 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -7,13 +7,13 @@
#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
-#include <windows.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
+#include "windows.h"
/*
* The new type to be used in all
diff --git a/ipc/Imakefile b/ipc/Imakefile
new file mode 100644
index 0000000..cf5d6df
--- /dev/null
+++ b/ipc/Imakefile
@@ -0,0 +1,33 @@
+#include "../Wine.tmpl"
+
+MODULE = ipc
+
+TEST_SRCS = \
+ shm_fragment_test.c \
+ bit_array_test.c\
+ dde_proc_test.c \
+ dde_atom_test.c \
+ shm_semaph_test.c \
+ wine_test_stub.c \
+ hash_test.c \
+ dde_mem_test.c
+
+SRCS = bit_array.c \
+ dde_atom.c \
+ dde_mem.c \
+ dde_proc.c \
+ generic_hash.c \
+ shm_block.c \
+ shm_fragment.c \
+ shm_main_blk.c \
+ shm_semaph.c
+
+OBJS = $(SRCS:.c=.o)
+TEST_OBJS = $(TEST_SRCS:.c=.o)
+
+WineRelocatableTarget($(MODULE),,$(OBJS))
+DependTarget()
+
+includes::
+
+install::
diff --git a/ipc/Makefile.in b/ipc/Makefile.in
new file mode 100644
index 0000000..fea89fe
--- /dev/null
+++ b/ipc/Makefile.in
@@ -0,0 +1,57 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = ipc
+
+SRCS = bit_array.c \
+ dde_atom.c \
+ dde_mem.c \
+ dde_proc.c \
+ generic_hash.c \
+ shm_block.c \
+ shm_fragment.c \
+ shm_main_blk.c \
+ shm_semaph.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/ipc/README b/ipc/README
new file mode 100644
index 0000000..6903f53
--- /dev/null
+++ b/ipc/README
@@ -0,0 +1,8 @@
+This is a pre-alpha code, it does not work for 100%,
+but it does not break anything (I hope).
+Proper documentation (LaTeX) will be ready for the next release.
+
+You can use "ipcl" perl script to remove junk IPC stuff.
+You can use "ipcs" system program to find junk IPC stuff.
+
+Michael
diff --git a/ipc/TEST_FRAGMENT.std b/ipc/TEST_FRAGMENT.std
new file mode 100644
index 0000000..968a440
--- /dev/null
+++ b/ipc/TEST_FRAGMENT.std
@@ -0,0 +1,42 @@
+After shm_FragmentInit
+{0x0020,0xffe0} [total free=ffe0]
+0: After shm_FragmentAlloc(block, 0x010000) == NULL
+{0x0020,0xffe0} [total free=ffe0]
+1: After shm_FragmentAlloc(block, 0x003fdc) == 0x00c024
+{0x0020,0xc000} [total free=c000]
+2: After shm_FragmentAlloc(block, 0x003ffc) == 0x008024
+{0x0020,0x8000} [total free=8000]
+3: After shm_FragmentAlloc(block, 0x003ffc) == 0x004024
+{0x0020,0x4000} [total free=4000]
+4: After shm_FragmentAlloc(block, 0x003ffd) == NULL
+{0x0020,0x4000} [total free=4000]
+5: After shm_FragmentAlloc(block, 0x003ffc) == 0x000024
+no free fragments [total free=0000]
+6: Doing shm_FragmentFree(block, 0x000024)
+{0x0020,0x4000} [total free=4000]
+7: After shm_FragmentAlloc(block, 0x001bfc) == 0x002424
+{0x0020,0x2400} [total free=2400]
+8: After shm_FragmentAlloc(block, 0x0013fc) == 0x001024
+{0x0020,0x1000} [total free=1000]
+9: After shm_FragmentAlloc(block, 0x000ffc) == 0x000024
+no free fragments [total free=0000]
+10: Doing shm_FragmentFree(block, 0x000024)
+{0x0020,0x1000} [total free=1000]
+11: Doing shm_FragmentFree(block, 0x004024)
+{0x0020,0x1000} {0x4020,0x4000} [total free=5000]
+12: Doing shm_FragmentFree(block, 0x00c024)
+{0x0020,0x1000} {0x4020,0x4000} {0xc020,0x3fe0} [total free=8fe0]
+13: After shm_FragmentAlloc(block, 0x000ffc) == 0x000024
+{0x4020,0x4000} {0xc020,0x3fe0} [total free=7fe0]
+14: Doing shm_FragmentFree(block, 0x000024)
+{0x0020,0x1000} {0x4020,0x4000} {0xc020,0x3fe0} [total free=8fe0]
+15: After shm_FragmentAlloc(block, 0x000ffd) == 0x007014
+{0x0020,0x1000} {0x4020,0x2ff0} {0xc020,0x3fe0} [total free=7fd0]
+16: Doing shm_FragmentFree(block, 0x008024)
+{0x0020,0x1000} {0x4020,0x2ff0} {0x8020,0x7fe0} [total free=bfd0]
+17: Doing shm_FragmentFree(block, 0x001024)
+{0x0020,0x2400} {0x4020,0x2ff0} {0x8020,0x7fe0} [total free=d3d0]
+18: Doing shm_FragmentFree(block, 0x002424)
+{0x0020,0x6ff0} {0x8020,0x7fe0} [total free=efd0]
+19: Doing shm_FragmentFree(block, 0x007014)
+{0x0020,0xffe0} [total free=ffe0]
diff --git a/ipc/bit_array.c b/ipc/bit_array.c
new file mode 100644
index 0000000..d4cede8
--- /dev/null
+++ b/ipc/bit_array.c
@@ -0,0 +1,276 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: bit_array.c
+ * Purpose : manipulate array of bits
+ * Portability: This is not completely portable, non CISC arcitectures
+ * Might not have atomic Clear/Set/Toggle bit. On those
+ * architectures semaphores should be used.
+ * Big Endian Concerns: This code is big endian compatible,
+ * but the byte order will be different (i.e. bit 0 will be
+ * located in byte 3).
+ ***************************************************************************
+ */
+
+/*
+** uncoment the following line to disable assertions,
+** this may boost performance by up to 50%
+*/
+/* #define NDEBUG */
+
+#ifndef NO_ASM
+#define HAS_BITOPS
+#endif
+
+#include <stdio.h>
+
+#include <assert.h>
+
+#include "bit_array.h"
+#if defined(HAS_BITOPS)
+# include <asm/bitops.h>
+#else
+static __inline__ int clear_bit(int bit, int *mem);
+static __inline__ int set_bit(int bit, int *mem);
+#endif /* HAS_BITOPS */
+
+
+#define INT_NR(bit_nr) ((bit_nr) >> INT_LOG2)
+#define INT_COUNT(bit_count) INT_NR( bit_count + BITS_PER_INT - 1 )
+#define BIT_IN_INT(bit_nr) ((bit_nr) & (BITS_PER_INT - 1))
+
+#if !defined(HAS_BITOPS)
+
+/* first_zero maps bytes value to the index of first zero bit */
+static char first_zero[256];
+static int arrays_initialized=0;
+
+
+/*
+** initialize static arrays used for bit operations speedup.
+** Currently initialized: first_zero[256]
+** set "arrays_initialized" to inidate that arrays where initialized
+*/
+
+static void initialize_arrays()
+{
+ int i;
+ int bit;
+
+ for (i=0 ; i<256 ; i++) {
+ /* find the first zero bit in `i' */
+ for (bit=0 ; bit < BITS_PER_BYTE ; bit++)
+ /* break if the bit is zero */
+ if ( ( (1 << bit) & i )
+ == 0)
+ break;
+ first_zero[i]= bit;
+ }
+ arrays_initialized=1;
+}
+
+/*
+** Find first zero bit in the integer.
+** Assume there is at least one zero.
+*/
+static __inline__ int find_zbit_in_integer(unsigned int integer)
+{
+ int i;
+
+ /* find the zero bit */
+ for (i=0 ; i < sizeof(int) ; i++, integer>>=8) {
+ int byte= integer & 0xff;
+
+ if (byte != 0xff)
+ return ( first_zero[ byte ]
+ + (i << BYTE_LOG2) );
+ }
+ assert(0); /* never reached */
+ return 0;
+}
+
+/* return -1 on failure */
+static __inline__ int find_first_zero_bit(unsigned *array, int bits)
+{
+ unsigned int integer;
+ int i;
+ int bytes=INT_COUNT(bits);
+
+ if (!arrays_initialized)
+ initialize_arrays();
+
+ for ( i=bytes ; i ; i--, array++) {
+ integer= *array;
+
+ /* test if integer contains a zero bit */
+ if (integer != ~0U)
+ return ( find_zbit_in_integer(integer)
+ + ((bytes-i) << INT_LOG2) );
+ }
+
+ /* indicate failure */
+ return -1;
+}
+
+static __inline__ int test_bit(int pos, unsigned *array)
+{
+ unsigned int integer;
+ int bit = BIT_IN_INT(pos);
+
+ integer= array[ pos >> INT_LOG2 ];
+
+ return ( (integer & (1 << bit)) != 0
+ ? 1
+ : 0 ) ;
+}
+
+/*
+** The following two functions are x86 specific ,
+** other processors will need porting
+*/
+
+/* inputs: bit number and memory address (32 bit) */
+/* output: Value of the bit before modification */
+static __inline__ int clear_bit(int bit, int *mem)
+{
+ int ret;
+
+ __asm__("xor %1,%1
+ btrl %2,%0
+ adcl %1,%1"
+ :"=m" (*mem), "=&r" (ret)
+ :"r" (bit));
+ return (ret);
+}
+
+static __inline__ int set_bit(int bit, int *mem)
+{
+ int ret;
+ __asm__("xor %1,%1
+ btsl %2,%0
+ adcl %1,%1"
+ :"=m" (*mem), "=&r" (ret)
+ :"r" (bit));
+ return (ret);
+}
+
+#endif /* !deined(HAS_BITOPS) */
+
+
+/* AssembleArray: assemble an array object using existing data */
+bit_array *AssembleArray(bit_array *new_array, unsigned int *buff, int bits)
+{
+ assert(new_array!=NULL);
+ assert(buff!=NULL);
+ assert(bits>0);
+ assert((1 << INT_LOG2) == BITS_PER_INT); /* if fails, redefine INT_LOG2 */
+
+ new_array->bits=bits;
+ new_array->array=buff;
+ return new_array;
+}
+
+/* ResetArray: reset the bit array to zeros */
+int ResetArray(bit_array *bits)
+{
+ int i;
+ int *p;
+
+ assert(bits!=NULL);
+ assert(bits->array!=NULL);
+
+ for(i= INT_COUNT(bits->bits), p=bits->array; i ; p++, i--)
+ *p=0;
+ return 1;
+}
+
+
+/* VacantBit: find a vacant (zero) bit in the array,
+ * Return: Bit index on success, -1 on failure.
+ */
+int VacantBit(bit_array *bits)
+{
+ int bit;
+
+ assert(bits!=NULL);
+ assert(bits->array!=NULL);
+
+ bit= find_first_zero_bit(bits->array, bits->bits);
+
+ if (bit >= bits->bits) /* failed? */
+ return -1;
+
+ return bit;
+}
+
+int SampleBit(bit_array *bits, int i)
+{
+ assert(bits != NULL);
+ assert(bits->array != NULL);
+ assert(i >= 0 && i < bits->bits);
+
+ return ( test_bit(i,bits->array) != 0
+ ? 1
+ : 0
+ );
+}
+
+
+/*
+** Use "compare and exchange" mechanism to make sure
+** that bits are not modified while "integer" value
+** is calculated.
+**
+** This may be the slowest technique, but it is the most portable
+** (Since most architectures have compare and exchange command)
+*/
+int AssignBit(bit_array *bits, int bit_nr, int val)
+{
+ int ret;
+
+ assert(bits != NULL);
+ assert(bits->array != NULL);
+ assert(val==0 || val==1);
+ assert(bit_nr >= 0 && bit_nr < bits->bits);
+
+ if (val==0)
+ ret= clear_bit(BIT_IN_INT(bit_nr), &bits->array[ INT_NR(bit_nr) ]);
+ else
+ ret= set_bit(BIT_IN_INT(bit_nr), &bits->array[ INT_NR(bit_nr) ]);
+
+ return ( (ret!=0) ? 1 : 0);
+}
+
+/*
+** Allocate a free bit (==0) and make it used (==1).
+** This operation is guaranteed to resemble an atomic instruction.
+**
+** Return: allocated bit index, or -1 on failure.
+**
+** There is a crack between locating free bit, and allocating it.
+** We assign 1 to the bit, test it was not '1' before the assignment.
+** If it was, restart the seek and assign cycle.
+**
+*/
+
+int AllocateBit(bit_array *bits)
+{
+ int bit_nr;
+ int orig_bit;
+
+ assert(bits != NULL);
+ assert(bits->array != NULL);
+
+ do {
+ bit_nr= VacantBit(bits);
+
+ if (bit_nr == -1) /* No vacant bit ? */
+ return -1;
+
+ orig_bit = AssignBit(bits, bit_nr, 1);
+ } while (orig_bit != 0); /* it got assigned before we tried */
+
+ return bit_nr;
+}
diff --git a/ipc/bit_array_test.c b/ipc/bit_array_test.c
new file mode 100644
index 0000000..14ecb34
--- /dev/null
+++ b/ipc/bit_array_test.c
@@ -0,0 +1,93 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "bit_array.h"
+#define SIZE (8*sizeof(int)*3)
+
+static bit_array array;
+static int simple_array[SIZE];
+static int bits;
+
+int are_equal()
+{
+ int i;
+ for (i=0 ; i < SIZE ; i++)
+ if (SampleBit(&array,i) != simple_array[i]){
+ printf("failed bit %d (packed=%d, simple=%d)\n", i,
+ SampleBit(&array,i), simple_array[i]);
+ return 0;
+ }
+ return 1;
+}
+
+int is_same_vacant()
+{
+ int vacant;
+ for (vacant =0 ; simple_array[vacant]!=0 ; vacant++)
+ if ( vacant >= SIZE) {
+ vacant=-1;
+ break;
+ }
+
+
+ if ( VacantBit(&array) == vacant )
+ return 1;
+ else
+ return 0;
+}
+void assign_both(int bit_nr, int bit_val)
+{
+ int old_bit= simple_array[bit_nr];
+
+ simple_array[bit_nr]= bit_val;
+
+ bits+=bit_val - old_bit;
+
+ assert(AssignBit(&array, bit_nr, bit_val) == old_bit);
+ assert(are_equal());
+ assert(is_same_vacant());
+}
+
+
+int main()
+{
+ unsigned int integers[SIZE >> 5];
+ int i,j;
+
+ assert( AssembleArray(&array, integers, SIZE)
+ == &array);
+ ResetArray(&array);
+ for (i=0 ; i<SIZE ; i++)
+ simple_array[i]=0;
+
+ for (j=5 ; j ; j--) {
+ printf("\rleft %d\r",j);
+
+ for (i=0 ; VacantBit(&array) != -1 ; i++ ) {
+ if (i % 256 == 0) {
+ printf("left %d ",j);
+ printf("%3d up \r", bits);
+ fflush(stdout);
+ }
+ assign_both(rand() % SIZE,
+ (rand()% SIZE > bits ) ? 0 : 1 );
+ }
+
+ assign_both(rand() % SIZE, 1);
+
+ for (i=0 ; bits ; i++ ) {
+ if (i % 256 == 0) {
+ printf("left %d ",j);
+ printf("%3d down\r", bits);
+ fflush(stdout);
+ }
+ assign_both(rand() % SIZE,
+ (rand()% SIZE <= (SIZE-bits) ) ? 0 : 1 );
+ }
+
+ assign_both(rand() % SIZE, 0);
+ }
+
+ putchar('\n');
+ return 0;
+}
diff --git a/ipc/dde_atom.c b/ipc/dde_atom.c
new file mode 100644
index 0000000..c6ca2aa
--- /dev/null
+++ b/ipc/dde_atom.c
@@ -0,0 +1,273 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_atom.c
+ * Purpose : atom functionality for DDE
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "dde_atom.h"
+#include "shm_main_blk.h"
+#include "shm_fragment.h"
+#include "stddebug.h"
+#include "debug.h"
+
+typedef struct
+{
+ WORD count;
+ BYTE str[1];
+} AtomData, *AtomData_ptr;
+
+#define EMPTY 0 /* empty hash entry */
+#define DELETED -1 /* deleted hash entry */
+#define MIN_STR_ATOM 0xfc00
+
+/* OFS2AtomData_ptr: extract AtomData_ptr from ofs */
+#define OFS2AtomData_ptr(ofs) ((AtomData*)((int)&main_block->block+(ofs)))
+
+/* OFS2AtomStr: find the string of the atom */
+#define OFS2AtomStr(ofs) (OFS2AtomData_ptr(atom_ofs)->str)
+
+/* offset of an atom according to index */
+#define ATOM_OFS(idx) (main_block->atoms[idx])
+
+/* rot_left: rotate (with wrap-around) */
+static __inline__ int rot_left(unsigned var,int count)
+{
+ return (var<<count) | (var>> (sizeof(var)-count));
+}
+/* find the entry in the atom table for this string */
+static int FindHash(LPCSTR str) /* ignore str case */
+{
+ int i,j;
+ unsigned hash1,hash2;
+ int deleted=-1; /* hash for deleted entry */
+ int atom_ofs;
+
+ /* get basic hash parameters */
+ for (i= hash1= hash2= 0; str[i] ; i++) {
+ hash1= rot_left(hash1,5) ^ toupper(str[i]);
+ hash2= rot_left(hash2,4) ^ toupper(str[i]);
+ }
+
+ hash1%= DDE_ATOMS;
+ atom_ofs=ATOM_OFS(hash1);
+ switch (atom_ofs) {
+ case EMPTY: /* empty atom entry */
+ return hash1;
+ case DELETED: /* deleted atom entry */
+ deleted=hash1;
+ break;
+ default : /* non empty atom entry */
+ if ( strcasecmp( OFS2AtomStr(atom_ofs) , str) == 0)
+ return hash1; /* found string in atom table */
+ }
+ hash2%= DDE_ATOMS-1 ; /* hash2=0..(DDE_ATOMS-2) */
+ hash2++; /* hash2=1..(DDE_ATOMS-1) */
+
+ /* make jumps in the hash table by hash2 steps */
+ for (i=hash1+hash2 ; ; i+=hash2) {
+ /* i wraps around into j */
+ j=i-DDE_ATOMS;
+ if (j >= 0)
+ i=j; /* i wraps around */
+
+ if (i==hash1)
+ /* here if covered all hash locations, and got back to beginning */
+ return deleted; /* return first empty entry - if any */
+ atom_ofs=ATOM_OFS(i);
+ switch (atom_ofs) {
+ case EMPTY: /* empty atom entry */
+ return i;
+ case DELETED: /* deleted atom entry */
+ if (deleted < 0)
+ /* consider only the first deleted entry */
+ deleted= i;
+ break;
+ default : /* nonempty atom entry */
+ if ( strcasecmp( OFS2AtomStr(atom_ofs) , str) == 0)
+ return i; /* found string in atom table */
+ }
+ }
+}
+
+void ATOM_GlobalInit(void)
+{
+ int i;
+
+ for (i=0 ; i < DDE_ATOMS ; i++)
+ ATOM_OFS(i)=EMPTY;
+}
+
+/***********************************************************************
+ * GlobalAddAtom (USER.268)
+ */
+
+/* important! don't forget to unlock semaphores before return */
+ATOM GlobalAddAtom( LPCSTR str )
+{
+ int atom_idx;
+ int atom_ofs;
+ AtomData_ptr ptr;
+ ATOM atom;
+
+ dprintf_atom(stddeb,"GlobalAddAtom(%p)\n", str);
+ if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
+ return (ATOM) (unsigned) str;
+ if (str[0] == '#') { /* wine convention */
+ atom= (ATOM) atoi(&str[1]);
+ return (atom<MIN_STR_ATOM) ? atom : 0;
+ }
+ dprintf_atom(stddeb,"GlobalAddAtom(\"%s\")\n",str);
+
+ DDE_IPC_init(); /* will initialize only if needed */
+
+ shm_write_wait(main_block->sem);
+
+ atom_idx=FindHash(str);
+ atom=(ATOM)0;
+
+ /* use "return" only at the end so semaphore handling is done only once */
+ if (atom_idx>=0) {
+ /* unless table full and item not found */
+ switch (atom_ofs= ATOM_OFS(atom_idx)) {
+ case DELETED:
+ case EMPTY: /* need to allocate new atom */
+ atom_ofs= shm_FragmentAlloc(&main_block->block,
+ strlen(str)+sizeof(AtomData));
+ if (atom_ofs==NIL)
+ break; /* no more memory (atom==0) */
+ ATOM_OFS(atom_idx)=atom_ofs;
+ ptr=OFS2AtomData_ptr(atom_ofs);
+ strcpy(ptr->str,str);
+ ptr->count=1;
+ atom=(ATOM)(atom_idx+MIN_STR_ATOM);
+ break;
+ default : /* has to update existing atom */
+ OFS2AtomData_ptr(atom_ofs)->count++;
+ atom=(ATOM)(atom_idx+MIN_STR_ATOM);
+ } /* end of switch */
+ } /* end of if */
+ shm_write_signal(main_block->sem);
+ return atom;
+}
+
+/***********************************************************************
+ * GlobalDeleteAtom (USER.269)
+ */
+
+ATOM GlobalDeleteAtom( ATOM atom )
+{
+ int atom_idx;
+ int atom_ofs;
+ AtomData_ptr atom_ptr;
+ ATOM retval=(ATOM) 0;
+
+ dprintf_atom(stddeb,"GlobalDeleteAtom(\"%d\")\n",(int)atom);
+ atom_idx=(int)atom - MIN_STR_ATOM;
+
+ if (atom_idx < 0 )
+ return 0;
+
+ DDE_IPC_init(); /* will initialize only if needed */
+
+ shm_write_wait(main_block->sem);
+ /* return used only once from here on -- for semaphore simplicity */
+ switch (atom_ofs=ATOM_OFS(atom_idx)) {
+ case DELETED:
+ case EMPTY:
+ fprintf(stderr,"trying to free unallocated atom %d\n", atom);
+ retval=atom;
+ break;
+ default :
+ atom_ptr=OFS2AtomData_ptr(atom_ofs);
+ if ( --atom_ptr->count == 0) {
+ shm_FragmentFree(&main_block->block,atom_ofs);
+ ATOM_OFS(atom_idx)=DELETED;
+ }
+ }
+
+ shm_write_signal(main_block->sem);
+ return retval;
+}
+
+/***********************************************************************
+ * GlobalFindAtom (USER.270)
+ */
+ATOM GlobalFindAtom( LPCSTR str )
+{
+ int atom_idx;
+ int atom_ofs;
+
+ dprintf_atom(stddeb,"GlobalFindAtom(%p)\n", str );
+ if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
+ return (ATOM) (unsigned) str;
+ if (str[0] == '#') { /* wine convention */
+ ATOM atom= (ATOM) atoi(&str[1]);
+ return (atom<MIN_STR_ATOM) ? atom : 0;
+ }
+ dprintf_atom(stddeb,"GlobalFindAtom(\"%s\")\n",str);
+
+ DDE_IPC_init(); /* will initialize only if needed */
+
+ shm_read_wait(main_block->sem);
+ atom_idx=FindHash(str);
+ if (atom_idx>=0)
+ atom_ofs=ATOM_OFS(atom_idx); /* is it free ? */
+ else
+ atom_ofs=EMPTY;
+ shm_read_signal(main_block->sem);
+
+ if (atom_ofs==EMPTY || atom_ofs==DELETED)
+ return 0;
+ else
+ return (ATOM)(atom_idx+MIN_STR_ATOM);
+}
+
+/***********************************************************************
+ * GlobalGetAtomName (USER.271)
+ */
+WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
+{
+ int atom_idx, atom_ofs;
+ int size;
+ /* temporary buffer to hold maximum "#65535\0" */
+ char str_num[7];
+
+ if (count<2) /* no sense to go on */
+ return 0;
+ atom_idx=(int)atom - MIN_STR_ATOM;
+
+ if (atom_idx < 0) { /* word atom */
+ /* use wine convention... */
+ sprintf(str_num,"#%d%n",(int)atom,&size);
+ if (size+1>count) { /* overflow ? */
+ /* truncate the string */
+ size=count-1;
+ str_num[size]='\0';
+ }
+ strcpy(buffer,str_num);
+ return size;
+ }
+
+ DDE_IPC_init(); /* will initialize only if needed */
+
+ /* string atom */
+ shm_read_wait(main_block->sem);
+ atom_ofs=ATOM_OFS(atom_idx);
+ if (atom_ofs==EMPTY || atom_ofs==DELETED) {
+ fprintf(stderr,"GlobalGetAtomName: illegal atom=%d\n",(int)atom);
+ size=0;
+ } else { /* non empty entry */
+ /* string length will be at most count-1, find actual size */
+ sprintf(buffer,"%.*s%n",count-1, OFS2AtomStr(atom_ofs), &size);
+ }
+ shm_read_signal(main_block->sem);
+ return size;
+}
+
diff --git a/ipc/dde_atom_test.c b/ipc/dde_atom_test.c
new file mode 100644
index 0000000..dd587c4
--- /dev/null
+++ b/ipc/dde_atom_test.c
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_atom_test.c
+ * Purpose : tests for dde_atom object
+ ***************************************************************************
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <win.h>
+#include "dde_atom.h"
+#include "shm_main_blk.h"
+#include <stddebug.h>
+#include <debug.h>
+#define TOGETHER (DDE_ATOMS/5)
+
+
+/* run random sequences */
+int main()
+{
+ ATOM atom_list[TOGETHER];
+ char str[TOGETHER][80];
+ int i,j,atom_n;
+ int atom_len[TOGETHER];
+
+ debugging_shm=1;
+ debugging_atom=0;
+ debugging_sem=0;
+
+ for (i=0 ; i<=10000/TOGETHER ; i++) {
+ for (atom_n=0 ; atom_n<TOGETHER ; atom_n++) {
+ atom_len[atom_n]=rand()%64+1;
+ for (j=atom_len[atom_n]-1; j>=0; j--)
+ do {
+ str[atom_n][j]=(char)(rand()%255+1);
+ } while (j==0 && str[atom_n][j]=='#');
+
+ str[atom_n][ atom_len[atom_n] ]='\0';
+
+ atom_list[atom_n]=GlobalAddAtom(str[atom_n]);
+
+ if (atom_list[atom_n]==0) {
+ fprintf(stderr,"failed i=%d, atom_n=%d\n",i,atom_n);
+ return 1;
+ }
+ if (atom_list[atom_n]!=GlobalAddAtom(str[atom_n])) {
+ fprintf(stderr,
+ "wrong second GlobalAddAtom(\"%s\")\n", str[atom_n]);
+ return 1;
+ }
+ } /* for */
+ for (atom_n=0 ; atom_n<TOGETHER ; atom_n++) {
+ char buf[80];
+ int len;
+
+ len=GlobalGetAtomName( atom_list[atom_n], buf, 79);
+ if (atom_len[atom_n] != len) {
+ fprintf(stderr, "i=%d, atom_n=%d; ", i, atom_n);
+ fprintf(stderr,
+ "wrong length of GlobalGetAtomName(\"%s\")\n",
+ str[atom_n]);
+
+ return 1;
+ }
+
+ }
+ for (atom_n=0 ; atom_n<TOGETHER ; atom_n++) {
+ GlobalDeleteAtom(atom_list[atom_n]);
+ if (atom_list[atom_n]!=GlobalAddAtom(str[atom_n])) {
+ fprintf(stderr, "i=%d, atom_n=%d; ", i, atom_n);
+ fprintf(stderr,
+ "wrong third GlobalAddAtom(\"%s\")\n", str[atom_n]);
+ return 1;
+ }
+ GlobalDeleteAtom(atom_list[atom_n]);
+ GlobalDeleteAtom(atom_list[atom_n]);
+
+ atom_list[atom_n]=GlobalAddAtom(str[atom_n]);
+ if (atom_list[atom_n]!=GlobalAddAtom(str[atom_n])) {
+ fprintf(stderr,
+ "i=%d, atom_n=%d wrong fifth GlobalAddAtom(\"%s\")\n",
+ i, atom_n,
+ str[atom_n]);
+ return 1;
+ }
+ GlobalDeleteAtom(atom_list[atom_n]);
+ if (atom_list[atom_n]!=GlobalFindAtom(str[atom_n])) {
+ fprintf(stderr,
+ "i=%d, atom_n=%d wrong GlobalFindAtom(\"%s\")\n",
+ i, atom_n,
+ str[atom_n]);
+ return 1;
+ }
+ GlobalDeleteAtom(atom_list[atom_n]);
+ }
+ }
+ return 0;
+}
diff --git a/ipc/dde_mem.c b/ipc/dde_mem.c
new file mode 100644
index 0000000..f19b013
--- /dev/null
+++ b/ipc/dde_mem.c
@@ -0,0 +1,282 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_mem.c
+ * Purpose : shared DDE memory functionality for DDE
+ ***************************************************************************
+ */
+#include <stdio.h>
+#include <stddebug.h>
+#include <debug.h>
+#include <assert.h>
+#include "ldt.h"
+#include "shm_main_blk.h"
+#include "shm_fragment.h"
+#include "shm_semaph.h"
+#include "dde_mem.h"
+#include "bit_array.h"
+
+#define SEGPTR2HANDLE_INFO(sptr) ( (struct handle_info*)PTR_SEG_TO_LIN(sptr) )
+
+#define HINFO2DATAPTR(h_info_ptr) ( (void*) ( (char*)h_info_ptr + \
+ sizeof(struct handle_info) ) )
+#define DDE_MEM_IDX(handle) ((handle)& 0x7fff)
+#define DDE_MEM_HANDLE(idx) ((idx) | 0x8000)
+#define DDE_MEM_INFO(handle) (main_block->handles[ DDE_MEM_IDX(handle) ])
+/* List of shared handles.
+ * This entry resides on the shared memory, the data comes right
+ * after the `handle_info'.
+ * The entry is on the same block as the actual data.
+ * The `next' field gives relative reference (relative to the start of
+ * the blcok.
+ */
+struct handle_info {
+ WORD lock_count;
+ WORD flags;
+ int size; /* size of the data (net)*/
+};
+
+static bit_array free_handles;
+int debug_last_handle_size= 0; /* for debugging purpose only */
+
+
+/* locate_handle:
+ * locate a shared memory handle.
+ * Application:
+ * The handle is first searched for in attached blocks.
+ * At the beginning, only blocks owned by this process are
+ * attached.
+ * If a handle is not found, new blocks are attached.
+ * Arguments:
+ * h - the handle.
+ * RETURN: pointer to handle info.
+ */
+static struct handle_info *locate_handle(HGLOBAL h, struct local_shm_map *map)
+{
+ struct shm_block *block;
+
+ dprintf_global(stddeb,"shm:locate_handle(0x%04x)\n", h);
+
+
+ if (SampleBit( &free_handles, DDE_MEM_IDX(h)) == 0) {
+ dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
+ return NULL; /* free!!! */
+ }
+
+ block= shm_locate_block(DDE_MEM_INFO(h).shmid, map);
+ if (block == NULL) {
+ /* nothing found */
+ dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
+ return NULL;
+ }
+
+ return (struct handle_info *) REL2PTR(block, DDE_MEM_INFO(h).rel);
+
+}
+
+/* dde_alloc_handle: allocate shared DDE handle */
+static HGLOBAL dde_alloc_handle()
+{
+ int bit_nr;
+
+ bit_nr= AllocateBit( &free_handles);
+
+ if (bit_nr != -1)
+ return DDE_MEM_HANDLE(bit_nr);
+
+ dprintf_global(stddeb,"dde_alloc_handle: no free DDE handle found\n");
+ return 0;
+}
+/**********************************************************************
+ * DDE_malloc
+ */
+void *
+DDE_malloc(unsigned int flags, unsigned long size, SHMDATA *shmdata)
+{
+ int shmid;
+ struct shm_block *block;
+ struct handle_info *h_info;
+ struct local_shm_map *curr;
+ HGLOBAL handle;
+
+ dprintf_global(stddeb,"DDE_malloc flags %4X, size %ld\n", flags, size);
+ DDE_IPC_init(); /* make sure main shm block allocated */
+
+ shm_write_wait(main_block->proc[curr_proc_idx].sem);
+
+ /* Try to find fragment big enough for `size' */
+ /* iterate through all local shm blocks, and try to allocate
+ the fragment */
+
+ h_info= NULL;
+ for (curr= shm_map ; curr != NULL ; curr= curr->next) {
+ if (curr->proc_idx == curr_proc_idx) {
+ h_info= (struct handle_info *)
+ shm_FragPtrAlloc(curr->ptr, size+sizeof(struct handle_info));
+ if (h_info!=NULL) {
+ shmid= curr->shm_id;
+ break;
+ }
+ }
+ }
+
+ if (h_info == NULL) {
+
+ block= shm_create_block(0, size+sizeof(struct handle_info), &shmid);
+ if (block==NULL) {
+ shm_write_signal(main_block->proc[curr_proc_idx].sem);
+ return 0;
+ }
+ /* put the new block in the linked list */
+ block->next_shm_id= main_block->proc[curr_proc_idx].shmid;
+ main_block->proc[curr_proc_idx].shmid= shmid;
+ h_info= (struct handle_info *)
+ shm_FragPtrAlloc(block, size+sizeof(struct handle_info));
+ if (h_info==NULL) {
+ fprintf(stderr,"DDE_malloc: BUG! unallocated fragment\n");
+ shm_write_signal(main_block->proc[curr_proc_idx].sem);
+ return 0;
+ }
+ } else {
+ block= curr->ptr;
+ }
+
+ /* Here we have an allocated fragment */
+ h_info->flags= flags;
+ h_info->lock_count= 0;
+ h_info->size= size;
+ handle= dde_alloc_handle();
+
+ if (handle) {
+ dprintf_global(stddeb,
+ "DDE_malloc returning handle=0x%4x, ptr=0x%08lx\n",
+ (int)handle, (long) HINFO2DATAPTR(h_info));
+ DDE_MEM_INFO(handle).rel= PTR2REL(block, h_info);
+ DDE_MEM_INFO(handle).shmid= shmid;
+ }
+ else
+ dprintf_global(stddeb,"DDE_malloc failed\n");
+
+ shm_write_signal(main_block->proc[curr_proc_idx].sem);
+
+ shmdata->handle= handle;
+ return (char *)HINFO2DATAPTR(h_info);
+}
+
+HGLOBAL DDE_GlobalFree(HGLOBAL h)
+{
+ struct handle_info *h_info;
+ int handle_index= h & 0x7fff;
+ struct local_shm_map map;
+
+ dprintf_global(stddeb,"DDE_GlobalFree(0x%04x)\n",h);
+
+ if (h==0)
+ return 0;
+
+ h_info= locate_handle(h, &map);
+ if (h_info == NULL)
+ return h;
+
+ shm_write_wait(main_block->proc[map.proc_idx].sem);
+
+ shm_FragPtrFree(map.ptr, (struct shm_fragment *) h_info);
+
+ AssignBit( &free_handles, handle_index, 0);
+
+ /* FIXME: must free the shm block some day. */
+ shm_write_signal(main_block->proc[map.proc_idx].sem);
+ return 0;
+}
+
+WORD DDE_SyncHandle(HGLOBAL handle, WORD sel)
+
+{
+ struct handle_info *h_info;
+ void *local_ptr;
+ ldt_entry entry;
+
+ h_info= locate_handle(handle, NULL);
+ local_ptr= (void *)GET_SEL_BASE(sel);
+
+
+ if (h_info == NULL)
+ return 0;
+
+ if (local_ptr == (void *) HINFO2DATAPTR(h_info))
+ return sel;
+
+ /* need syncronization ! */
+ LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+ entry.base= (unsigned long) HINFO2DATAPTR(h_info);
+ LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+
+ return sel;
+}
+
+/*
+ * DDE_AttachHandle:
+ * Attach shm memory (The data must not be already attached).
+ * Parameters:
+ * handle - the memory to attach.
+ * segptr - in not null, return SEGPTR to the same block.
+ * return value:
+ * 32 bit pointer to the memory.
+ */
+
+void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr)
+{
+ struct handle_info *h_info;
+ SHMDATA shmdata;
+ void *ptr;
+ HGLOBAL hOwner = GetCurrentPDB();
+
+ assert(is_dde_handle(handle));
+ if (segptr != NULL)
+ *segptr=0;
+
+ dprintf_global(stddeb,"DDE_AttachHandle(%04x)\n",handle);
+ h_info=locate_handle(handle, NULL);
+
+ if (h_info == NULL)
+ return NULL;
+
+ if ( !(h_info->flags & GMEM_DDESHARE) ) {
+ fprintf(stderr,"DDE_AttachHandle: Corrupted memory handle info\n");
+ return NULL;
+ }
+
+ dprintf_global(stddeb,"DDE_AttachHandle: h_info=%06lx\n",(long)h_info);
+
+ shmdata.handle= handle;
+ shmdata.shmid= DDE_MEM_INFO(handle).shmid;
+
+ ptr= HINFO2DATAPTR(h_info);
+ /* Allocate the selector(s) */
+ if (! GLOBAL_CreateBlock( h_info->flags, ptr, h_info->size, hOwner,
+ FALSE, FALSE, FALSE, &shmdata))
+ return NULL;
+
+ if (segptr != NULL)
+ *segptr= (SEGPTR)MAKELONG( 0, shmdata.sel);
+
+ if (debugging_dde)
+ debug_last_handle_size= h_info->size;
+
+ dprintf_global(stddeb,"DDE_AttachHandle returns ptr=0x%08lx\n", (long)ptr);
+
+ return (LPSTR)ptr;
+
+}
+
+void DDE_mem_init()
+{
+ int nr_of_bits;
+
+ shm_init();
+
+ nr_of_bits= BITS_PER_BYTE * sizeof(main_block->free_handles);
+ AssembleArray( &free_handles, main_block->free_handles, nr_of_bits);
+}
diff --git a/ipc/dde_mem_test.c b/ipc/dde_mem_test.c
new file mode 100644
index 0000000..2fe42a5
--- /dev/null
+++ b/ipc/dde_mem_test.c
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_mem_test.c
+ * Purpose : test shared DDE memory functionality for DDE
+ * Usage: Look for assertion failures
+ ***************************************************************************
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <win.h>
+#include "dde_mem.h"
+/* stub */
+
+void ATOM_GlobalInit()
+{
+ printf("ATOM_GlobalInit\n");
+}
+
+
+int main()
+{
+ HWND h1,h2,h3;
+ int ret;
+ void *p1,*p2,*p3,*p;
+ SHMDATA shmdata;
+
+ /* alloc h1, h2, h3 */
+
+ setbuf(stdout,NULL);
+ p1=DDE_malloc(GMEM_DDESHARE, 0x6000, &shmdata);
+ h1= shmdata.handle;
+ assert(p1 != NULL);
+ assert(h1 != 0);
+ p2=DDE_malloc(GMEM_DDESHARE, 0xff00, &shmdata);
+ h2= shmdata.handle;
+ assert(p2 != NULL);
+ assert(h2 != 0);
+ p3=DDE_malloc(GMEM_DDESHARE, 0x6000, &shmdata);
+ h3= shmdata.handle;
+ assert(p3 != 0);
+ assert(h3 != 0);
+
+ /* lock h1, h2, h3 */
+ p=DDE_AttachHandle(h1,NULL);
+ assert(p1==p);
+ p=DDE_AttachHandle(h2,NULL);
+ assert(p2==p);
+ p=DDE_AttachHandle(h3,NULL);
+ assert(p3==p);
+
+
+
+ ret=DDE_GlobalFree(h1);
+ assert(ret==0);
+ /* do some implementation dependant tests */
+ p=DDE_malloc(GMEM_DDESHARE, 0x6000, &shmdata);
+ assert(p!=NULL);
+ assert(shmdata.handle==h1);
+ p=DDE_AttachHandle(h1,NULL);
+ assert(p1==p);
+
+ /* check freeing */
+ ret=DDE_GlobalFree(h1);
+ assert(ret==0);
+ ret=DDE_GlobalFree(h2);
+ assert(ret==0);
+ ret=DDE_GlobalFree(h3);
+ assert(ret==0);
+ return 0;
+}
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
new file mode 100644
index 0000000..9f5f59e
--- /dev/null
+++ b/ipc/dde_proc.c
@@ -0,0 +1,718 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_proc.c
+ * Purpose : DDE signals and processes functionality for DDE
+ ***************************************************************************
+ */
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/msg.h>
+#include "wintypes.h"
+#include "win.h"
+#include "shm_semaph.h"
+#include "shm_main_blk.h"
+#include "dde_proc.h"
+#include "dde_mem.h"
+#include "dde.h"
+#include "stddebug.h"
+#include "debug.h"
+
+int curr_proc_idx= -1;
+
+enum stop_wait_op stop_wait_op=CONT;
+int had_SIGUSR2 = 0;
+sigjmp_buf env_get_ack;
+sigjmp_buf env_wait_x;
+
+#define IDX_TO_HWND(idx) (0xfffe - (idx))
+#define HWND_TO_IDX(wnd) (0xfffe - (wnd))
+#define DDE_WIN_INFO(win) ( main_block->windows[HWND_TO_IDX(win)] )
+#define DDE_WIN2PROC(win) ( DDE_WIN_INFO(win).proc_idx )
+#define DDE_IsRemoteWindow(win) ( (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
+#define DDE_SEND 1
+#define DDE_POST 2
+#define DDE_ACK 3
+#define DDE_MSG_SIZE sizeof(MSG)
+#define FREE_WND (WORD)(-2)
+#define DELETED_WND (WORD)(-3)
+#if defined(DEBUG_MSG) || defined(DEBUG_RUNTIME)
+static char *msg_type[4]={"********", "DDE_SEND", "DDE_POST", "DDE_ACK"};
+#endif
+
+struct msg_dat {
+ struct msgbuf dat;
+ char filler[DDE_MSG_SIZE];
+} ;
+
+typedef struct fifo_element {
+ int value;
+ struct fifo_element *next;
+} fifo_element;
+
+struct fifo {
+ fifo_element *first; /* first element in the fifo or NULL */
+ fifo_element *last; /* last element in the fifo or NULL */
+};
+static struct fifo fifo = {NULL,NULL};
+
+void dde_proc_delete(int proc_idx);
+
+void dde_proc_add_fifo(int val)
+{
+ fifo_element *created;
+
+ created= (fifo_element*) malloc( sizeof(fifo_element) );
+ created->value = val;
+ created->next = NULL;
+
+ if (fifo.first==NULL)
+ fifo.first= created;
+ else
+ fifo.last->next= created;
+ fifo.last = created;
+}
+
+/* get an item from the fifo, and return it.
+ * If fifo is empty, return -1
+ */
+int dde_proc_shift_fifo()
+{
+ int val;
+ fifo_element *deleted;
+
+ if (fifo.first == NULL)
+ return -1;
+
+ deleted= fifo.first;
+ val= deleted->value;
+ fifo.first= deleted->next;
+ if (fifo.first == NULL)
+ fifo.last= NULL;
+
+ free(deleted);
+ return val;
+}
+
+static void print_dde_message(char *desc, MSG *msg);
+
+/* This should be run only when main_block is first allocated. */
+void dde_proc_init(dde_proc proc)
+{
+ int proc_num;
+
+ for (proc_num=0 ; proc_num<DDE_PROCS ; proc_num++, proc++) {
+ proc->msg=-1;
+ proc->sem=-1;
+ proc->shmid=-1;
+ proc->pid=-1;
+ }
+}
+
+/* add current process to the list of processes */
+void dde_proc_add(dde_proc procs)
+{
+ dde_proc proc;
+ int proc_idx;
+ dprintf_dde(stddeb,"dde_proc_add(..)\n");
+ shm_write_wait(main_block->sem);
+
+ /* find free proc_idx and allocate it */
+ for (proc_idx=0, proc=procs ; proc_idx<DDE_PROCS ; proc_idx++, proc++)
+ if (proc->pid==-1)
+ break; /* found! */
+
+ if (proc_idx<DDE_PROCS) { /* got here beacuse a free was found ? */
+ dde_msg_setup(&proc->msg);
+ proc->pid=getpid();
+ curr_proc_idx=proc_idx;
+ shm_sem_init(&proc->sem);
+ }
+ else {
+ fflush(stdout);
+ fprintf(stderr,"dde_proc_add: Can't allocate process\n");
+ }
+ shm_write_signal(main_block->sem);
+}
+
+/* wait for dde - acknowledge message - or timout */
+static BOOL get_ack()
+{
+ struct timeval timeout;
+ int size;
+ struct msg_dat ack_buff;
+
+ /* timeout after exactly one seconf */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ sigsetjmp(env_get_ack, 1);
+ /* get here after normal execution, or after siglongjmp */
+
+ do { /* loop to wait for DDE_ACK */
+ had_SIGUSR2=0;
+ stop_wait_op=CONT; /* sensitive code: disallow siglongjmp */
+ size= msgrcv( main_block->proc[curr_proc_idx].msg , &ack_buff.dat,
+ 1, DDE_ACK, IPC_NOWAIT);
+ if (size>=0) {
+ dprintf_msg(stddeb,"get_ack: received DDE_ACK message\n");
+ return TRUE;
+ }
+ if (DDE_GetRemoteMessage()) {
+ had_SIGUSR2=1; /* might have recieved SIGUSR2 */
+ }
+ stop_wait_op=STOP_WAIT_ACK; /* allow siglongjmp */
+
+ } while (had_SIGUSR2); /* loop if SIGUSR2 was recieved */
+
+ /* siglongjmp should be enabled at this moment */
+ select( 0, NULL, NULL, NULL, &timeout );
+ stop_wait_op=CONT; /* disallow further siglongjmp */
+
+ /* timeout !! (otherwise there would have been a siglongjmp) */
+ return FALSE;
+}
+
+/* Transfer one message to a given process */
+static BOOL DDE_DoOneMessage (int proc_idx, int size, struct msgbuf *msgbuf)
+{
+ dde_proc proc= &main_block->proc[ proc_idx ];
+
+
+ if (proc_idx == curr_proc_idx)
+ return FALSE;
+
+ if (kill(proc->pid,0) < 0) {
+ /* pid does not exist, or not our */
+ dde_proc_delete(proc_idx);
+ return FALSE;
+ }
+
+ if (debugging_dde) {
+ MSG *msg=(MSG*) &msgbuf->mtext;
+ char *title;
+ if (msgbuf->mtype==DDE_SEND)
+ title="sending dde:";
+ else if (msgbuf->mtype==DDE_POST)
+ title="posting dde:";
+ else
+ title=NULL;
+ if (title)
+ print_dde_message(title, msg);
+ else
+ fprintf(stddeb,"Unknown message type=0x%lx\n",msgbuf->mtype);
+ }
+ dprintf_msg(stddeb,
+ "DDE_DoOneMessage: to proc_idx=%d (pid=%d), queue=%u\n",
+ proc_idx, proc->pid, (unsigned)proc->msg);
+ if ( proc->msg != -1) {
+ dprintf_msg(stddeb, "DDE_DoOneMessage: doing...(type=%s)\n",
+ msg_type[msgbuf->mtype]);
+ size=msgsnd (proc->msg, msgbuf, size, 0);
+
+ if (size<0) {
+ fflush(stdout);
+ perror("msgsnd");
+ }
+ kill(proc->pid,SIGUSR2); /* tell the process there is a message */
+
+ dprintf_msg(stddeb,"DDE_DoOneMessage: "
+ "Trying to get acknowledgment from msg queue=%d\n",
+ proc->msg);
+ Yield(); /* force task switch, and */
+ /* acknowledgment sending */
+ if (get_ack()) {
+ return TRUE;
+ } else {
+ fflush(stdout);
+ fprintf(stderr,"get_ack: DDE_DoOneMessage: timeout\n");
+ return FALSE;
+ }
+ }
+ else {
+ dprintf_msg(stddeb,"DDE_DoOneMessage: message not sent, "
+ "target has no message queue\n");
+ return FALSE;
+ }
+}
+
+/* Do some sort of premitive hash table */
+static HWND HWND_Local2Remote(HWND orig)
+{
+ int dde_wnd_idx;
+ int deleted_idx= -1;
+ WND_DATA *tested;
+ WND_DATA *deleted= NULL;
+ int i;
+
+ dde_wnd_idx= orig % DDE_WINDOWS;
+ for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
+ if (dde_wnd_idx >= DDE_WINDOWS)
+ dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
+
+ tested= &main_block->windows[ dde_wnd_idx ];
+ if (tested->proc_idx == FREE_WND)
+ break;
+
+ if (deleted == NULL && tested->proc_idx == DELETED_WND) {
+ deleted= tested;
+ deleted_idx= dde_wnd_idx;
+ } else if (tested->wnd == orig && tested->proc_idx == curr_proc_idx) {
+ return IDX_TO_HWND(dde_wnd_idx);
+ }
+ }
+ if (deleted != NULL) { /* deleted is preferable */
+ /* free item, allocate it */
+ deleted->proc_idx= curr_proc_idx;
+ deleted->wnd = orig;
+ return IDX_TO_HWND(deleted_idx);
+ }
+ if (tested->proc_idx == FREE_WND) {
+ tested->proc_idx= curr_proc_idx;
+ tested->wnd = orig;
+ return IDX_TO_HWND(dde_wnd_idx);
+ }
+
+ fprintf(stderr,
+ "HWND_Local2Remote: Can't map any more windows to DDE windows\n");
+ return 0;
+}
+
+static BOOL DDE_DoMessage( MSG *msg, int type )
+{
+ int proc_idx;
+
+ MSG *remote_message;
+ struct msg_dat msg_dat;
+ BOOL success;
+
+ if (msg->wParam == 0)
+ return FALSE;
+
+ if (main_block==NULL) {
+ if (msg->message >= WM_DDE_FIRST && msg->message <= WM_DDE_LAST)
+ DDE_IPC_init();
+ else
+ return FALSE;
+ }
+
+
+ if (msg->wParam == (HWND)-1)
+ return FALSE;
+
+ if ( ! DDE_IsRemoteWindow(msg->hwnd) && msg->hwnd!= (HWND)-1)
+ return FALSE;
+
+ dprintf_msg(stddeb, "%s: DDE_DoMessage(hwnd=0x%x,msg=0x%x,..)\n",
+ msg_type[type], (int)msg->hwnd,(int)msg->message);
+
+
+ dprintf_msg(stddeb,
+ "DDE_DoMessage(hwnd=0x%x,msg=0x%x,..) // HWND_BROADCAST !\n",
+ (int)msg->hwnd,(int)msg->message);
+ remote_message=(void*)&msg_dat.dat.mtext;
+
+ memcpy(remote_message, msg, sizeof(*msg));
+ remote_message->wParam= HWND_Local2Remote(msg->wParam);
+ if (remote_message->wParam == 0)
+ return FALSE;
+
+ msg_dat.dat.mtype=type;
+
+ if (msg->hwnd == (HWND)-1) {
+ success= FALSE;
+ for ( proc_idx=0; proc_idx < DDE_PROCS ; proc_idx++) {
+ if (proc_idx == curr_proc_idx)
+ continue;
+ if (main_block->proc[ proc_idx ].msg != -1)
+ success|=DDE_DoOneMessage(proc_idx, DDE_MSG_SIZE, &msg_dat.dat);
+ }
+ return success;
+ } else {
+ return DDE_DoOneMessage(DDE_WIN2PROC(msg->hwnd), DDE_MSG_SIZE,
+ &msg_dat.dat);
+ }
+}
+
+BOOL DDE_SendMessage( MSG *msg)
+{
+ return DDE_DoMessage(msg, DDE_SEND);
+}
+
+BOOL DDE_PostMessage( MSG *msg)
+{
+ return DDE_DoMessage(msg, DDE_POST);
+}
+
+
+void dde_proc_send_ack(HWND wnd, BOOL val) {
+ int proc,msg;
+
+ static struct msgbuf msg_ack={DDE_ACK,{'0'}};
+
+ proc=DDE_WIN2PROC(wnd);
+ msg=main_block->proc[proc].msg;
+ dprintf_msg(stddeb,"DDE_GetRemoteMessage: sending ACK "
+ "to wnd=%4x, proc=%d,msg=%d, pid=%d\n",wnd,proc,msg,
+ main_block->proc[proc].pid
+ );
+
+ msg_ack.mtext[0]=val;
+ msgsnd (msg, &msg_ack, 1, 0);
+ kill(main_block->proc[proc].pid, SIGUSR2);
+}
+
+/* return true (non zero) if had a remote message */
+#undef DDE_GetRemoteMessage
+
+int DDE_GetRemoteMessage()
+{
+ static int nesting=0; /* to avoid infinite recursion */
+
+ MSG *remote_message;
+ int size;
+ struct msg_dat msg_dat;
+ BOOL was_sent; /* sent/received */
+ BOOL passed;
+ HWND hwnd;
+ WND *window;
+
+ if (curr_proc_idx==-1) /* do we have DDE initialized ? */
+ return 0;
+
+ if (nesting>10) {
+ fflush(stdout);
+ fprintf(stderr,"DDE_GetRemoteMessage: suspecting infinite recursion, exiting");
+ return 0;
+ }
+
+ remote_message=(void*)&msg_dat.dat.mtext;
+
+ /* test for SendMessage */
+ size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
+ DDE_MSG_SIZE, DDE_SEND, IPC_NOWAIT);
+
+ if (size==DDE_MSG_SIZE) { /* is this a correct message (if any) ?*/
+ was_sent=TRUE;
+ dprintf_msg(stddeb,
+ "DDE:receive sent message. msg=%04x wPar=%04x"
+ " lPar=%08lx\n",
+ remote_message->message, remote_message->wParam,
+ remote_message->lParam);
+ } else {
+ size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
+ DDE_MSG_SIZE, DDE_POST, IPC_NOWAIT);
+
+ if (size==DDE_MSG_SIZE) { /* is this a correct message (if any) ?*/
+ was_sent=FALSE;
+ dprintf_msg(stddeb,
+ "DDE:receive posted message. "
+ "msg=%04x wPar=%04x lPar=%08lx\n",
+ remote_message->message, remote_message->wParam,
+ remote_message->lParam);
+ }
+ else
+ return 0; /* no DDE message found */
+ }
+
+ /* At this point we are sure that there is a DDE message,
+ * was_sent is TRUE is the message was sent, and false if it was posted
+ */
+
+ nesting++;
+
+ if (debugging_dde) {
+ char *title;
+ if (was_sent)
+ title="receive sent dde:";
+ else
+ title="receive posted dde:";
+ print_dde_message(title, remote_message);
+ }
+
+ if (remote_message->hwnd != (HWND) -1 ) {
+ HWND dde_window= DDE_WIN_INFO(remote_message->hwnd).wnd;
+ /* we should know exactly where to send the message (locally)*/
+ if (was_sent) {
+ dprintf_dde(stddeb,
+ "SendMessage(wnd=0x%04x, msg=0x%04x, wPar=0x%04x,"
+ "lPar=0x%08x\n",
+ dde_window, remote_message->message,
+ remote_message->wParam, (int)remote_message->lParam);
+
+ /* execute the recieved message */
+ passed= SendMessage(dde_window, remote_message->message,
+ remote_message->wParam, remote_message->lParam);
+
+ /* Tell the sended, that the message is here */
+ dde_proc_send_ack(remote_message->wParam, passed);
+ }
+ else {
+ passed= PostMessage(dde_window, remote_message->message,
+ remote_message->wParam, remote_message->lParam);
+ if (passed == FALSE) {
+ /* Tell the sender, that the message is here, and failed */
+ dde_proc_send_ack(remote_message->wParam, FALSE);
+ }
+ else {
+ /* ack will be sent later, at the first peek/get message */
+ dde_proc_add_fifo(remote_message->wParam);
+ }
+ }
+ nesting--;
+ return 1;
+ }
+
+ /* iterate through all the windows */
+ for (hwnd = GetTopWindow(GetDesktopWindow());
+ hwnd && (window = WIN_FindWndPtr(hwnd))!=NULL ;
+ hwnd = window->hwndNext) {
+ if (window->dwStyle & WS_POPUP || window->dwStyle & WS_CAPTION) {
+ if (was_sent)
+ SendMessage( hwnd, remote_message->message,
+ remote_message->wParam, remote_message->lParam );
+ else
+ PostMessage( hwnd, remote_message->message,
+ remote_message->wParam, remote_message->lParam );
+ } /* if */
+ } /* for */
+
+ /* replay with DDE_ACK after broadcasting in DDE_GetRemoteMessage */
+ dde_proc_send_ack(remote_message->wParam, TRUE);
+
+ nesting--;
+ return 1;
+}
+
+int dde_reschedule()
+{
+ int ack_wnd;
+
+ ack_wnd= dde_proc_shift_fifo();
+ if (ack_wnd != -1) {
+ dde_proc_send_ack(ack_wnd, TRUE);
+ usleep(10000); /* force unix task switch */
+ return 1;
+ }
+ return 0;
+}
+void dde_msg_setup(int *msg_ptr)
+{
+ *msg_ptr= msgget (IPC_PRIVATE, IPC_CREAT | 0700);
+ if (*msg_ptr==-1)
+ perror("dde_msg_setup fails to get message queue");
+}
+
+/* do we have dde handling in the window ?
+ * If we have, atom usage will make this instance of wine set up
+ * it's IPC stuff.
+ */
+void DDE_TestDDE(HWND hwnd)
+{
+
+ if (main_block != NULL)
+ return;
+ dprintf_msg(stddeb,"DDE_TestDDE(0x%04x)\n", hwnd);
+ if (hwnd==0)
+ hwnd=-1;
+ /* just send a message to see how things are going */
+ SendMessage( hwnd, WM_DDE_INITIATE, 0, 0);
+}
+
+void dde_proc_delete(int proc_idx)
+{
+ dde_proc_done(&main_block->proc[proc_idx]);
+}
+void stop_wait(int a)
+{
+
+ had_SIGUSR2=1;
+ switch(stop_wait_op) {
+ case STOP_WAIT_ACK:
+ siglongjmp(env_get_ack,1);
+ break; /* never reached */
+ case STOP_WAIT_X:
+ siglongjmp(env_wait_x,1);
+ break; /* never reached */
+ case CONT:
+ /* do nothing */
+ }
+}
+
+static void print_dde_message(char *desc, MSG *msg)
+{
+ extern const char *MessageTypeNames[];
+ extern int debug_last_handle_size;
+ WORD wStatus,hWord;
+ void *ptr;
+ DDEACK *ddeack;
+ DDEADVISE *ddeadvise;
+ DDEDATA *ddedata;
+ DDEPOKE *ddepoke;
+
+ if (is_dde_handle(msg->lParam & 0xffff) )
+ ptr=DDE_AttachHandle(msg->lParam&0xffff, NULL);
+ else
+ ptr =NULL;
+ wStatus=LOWORD(msg->lParam);
+ hWord=HIWORD(msg->lParam);
+
+ fprintf(stddeb,"%s", desc);
+ fprintf(stddeb,"%04x %04x==%s %04x %08lx ",
+ msg->hwnd, msg->message,MessageTypeNames[msg->message],
+ msg->wParam, msg->lParam);
+ switch(msg->message) {
+ case WM_DDE_INITIATE:
+ case WM_DDE_REQUEST:
+ case WM_DDE_EXECUTE:
+ case WM_DDE_TERMINATE:
+ /* nothing to do */
+ break;
+ case WM_DDE_ADVISE:
+ /* DDEADVISE: hOptions in WM_DDE_ADVISE message */
+ if (ptr) {
+ ddeadvise=ptr;
+ fprintf(stddeb,"fDeferUpd=%d,fAckReq=%d,cfFormat=0x%x",
+ ddeadvise->fDeferUpd, ddeadvise->fAckReq,
+ ddeadvise->cfFormat);
+ } else
+ fprintf(stddeb,"NO-DATA");
+ fprintf(stddeb," atom=0x%x",hWord);
+ break;
+
+ case WM_DDE_UNADVISE:
+ fprintf(stddeb,"format=0x%x, atom=0x%x",wStatus,hWord);
+ break;
+ case WM_DDE_ACK:
+ ddeack=(DDEACK*)&wStatus;
+ fprintf(stddeb,"bAppReturnCode=%d,fBusy=%d,fAck=%d",
+ ddeack->bAppReturnCode, ddeack->fBusy, ddeack->fAck);
+ if (ddeack->fAck)
+ fprintf(stddeb,"(True)");
+ else
+ fprintf(stddeb,"(False)");
+ break;
+
+ case WM_DDE_DATA:
+ if (ptr) {
+ ddedata=ptr;
+ fprintf(stddeb,"fResponse=%d,fRelease=%d,"
+ "fAckReq=%d,cfFormat=0x%x,value=\"%.*s\"",
+ ddedata->fResponse, ddedata->fRelease,
+ ddedata->fAckReq, ddedata->cfFormat,
+ debug_last_handle_size- (int)sizeof(*ddedata)+1,
+ ddedata->Value);
+ } else
+ fprintf(stddeb,"NO-DATA");
+ fprintf(stddeb," atom=0x%04x",hWord);
+ break;
+
+ case WM_DDE_POKE:
+ if (ptr) {
+ ddepoke=ptr;
+ fprintf(stddeb,"fRelease=%d,cfFormat=0x%x,value[0]='%c'",
+ ddepoke->fRelease, ddepoke->cfFormat, ddepoke->Value[0]);
+ } else
+ fprintf(stddeb,"NO-DATA");
+ fprintf(stddeb," atom=0x%04x",hWord);
+ break;
+ }
+ fprintf(stddeb,"\n");
+}
+
+void dde_proc_done(dde_proc proc)
+{
+ if (proc->msg != -1)
+ msgctl(proc->msg, IPC_RMID, NULL);
+ proc->msg=-1;
+ proc->pid=-1;
+ shm_delete_chain(&proc->shmid);
+ shm_sem_done(&proc->sem);
+}
+
+/* delete entry, if old junk */
+void dde_proc_refresh(dde_proc proc)
+{
+ if (proc->pid == -1)
+ return;
+
+ if (kill(proc->pid, 0) != -1)
+ return;
+
+ /* get here if entry non empty, and the process does not exist */
+ dde_proc_done(proc);
+}
+
+void dde_wnd_setup()
+{
+ int i;
+
+ for (i=0 ; i < DDE_WINDOWS ; i++)
+ main_block->windows[i].proc_idx = FREE_WND;
+}
+
+static BOOL DDE_ProcHasWindows(int proc_idx)
+{
+ WND_DATA *tested;
+ int i;
+
+ for ( i=0 ; i < DDE_WINDOWS ; i++) {
+ tested= &main_block->windows[ i ];
+
+ if (tested->proc_idx == proc_idx)
+ return TRUE;
+ }
+ return FALSE;
+}
+/* Look for hwnd in the hash table of DDE windows,
+ * Delete it from there. If there are no more windows for this
+ * process, remove the process from the DDE data-structure.
+ * If there are no more processes - delete the whole DDE struff.
+ *
+ * This is inefficient, but who cares for the efficiency of this rare
+ * operation...
+ */
+void DDE_DestroyWindow(HWND hwnd)
+{
+ int dde_wnd_idx;
+ WND_DATA *tested;
+ int i;
+
+ if (main_block == NULL)
+ return;
+
+ dde_wnd_idx= hwnd % DDE_WINDOWS;
+
+ for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
+ if (dde_wnd_idx >= DDE_WINDOWS)
+ dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
+
+ tested= &main_block->windows[ dde_wnd_idx ];
+ if (tested->proc_idx == FREE_WND)
+ return; /* No window will get deleted here */
+
+ if (tested->wnd == hwnd && tested->proc_idx == curr_proc_idx) {
+ dde_reschedule();
+ tested->proc_idx= DELETED_WND;
+ if (DDE_ProcHasWindows( curr_proc_idx ))
+ return;
+ while (dde_reschedule()) /* make sure there are no other */
+ /* processes waiting for acknowledgment */
+ ;
+ dde_proc_delete( curr_proc_idx );
+ if (DDE_no_of_attached() == 1)
+ shm_delete_all(-1);
+ else {
+ shmdt( (void *) main_block);
+ main_block= NULL;
+ }
+ return;
+ }
+ }
+}
+
diff --git a/ipc/dde_proc_test.c b/ipc/dde_proc_test.c
new file mode 100644
index 0000000..1291fd8
--- /dev/null
+++ b/ipc/dde_proc_test.c
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: dde_proc.c
+ * Purpose : test DDE signals and processes functionality for DDE
+ * Usage: run two independant processes, one with an argument another
+ * without (with the argument is the server).
+ ***************************************************************************
+ */
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#include <sys/syscall.h>
+#include <sys/param.h>
+#else
+#include <syscall.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <win.h>
+#include "dde.h"
+#include "dde_proc.h"
+#include "shm_main_blk.h"
+
+#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
+char * cstack[4096];
+#endif
+#ifdef linux
+extern void ___sig_restore();
+extern void ___masksig_restore();
+
+/* Similar to the sigaction function in libc, except it leaves alone the
+ restorer field */
+
+static int
+wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
+{
+ __asm__("int $0x80":"=a" (sig)
+ :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
+ if (sig>=0)
+ return 0;
+ errno = -sig;
+ return -1;
+}
+#endif
+
+struct sigaction usr2_act;
+
+
+void init_signals()
+{
+#ifdef linux
+ usr2_act.sa_handler = (__sighandler_t) stop_wait;
+ usr2_act.sa_flags = 0;
+ usr2_act.sa_restorer =
+ (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
+ wine_sigaction(SIGUSR2,&usr2_act,NULL);
+#endif
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+ usr2_act.sa_hadnler = (void (*)) stop_wait;
+ usr2_act.sa_flags = SA_ONSTACK;
+ usr2_act.sa_mask = sig_mask;
+ usr2_act.sa_restorer =
+ (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
+ if (sigaction(SIGUSR2,&usr2_act,NULL) <0) {
+ perror("sigaction: SIGUSR2");
+ exit(1);
+ }
+#endif
+}
+void ATOM_GlobalInit()
+{
+ printf("ATOM_GlobalInit\n");
+}
+
+
+void idle_loop()
+{
+ int timeout;
+ for(timeout=500; timeout ; timeout--) {
+ if (DDE_GetRemoteMessage())
+ exit(0); ;
+ usleep(1000);
+ }
+ exit(-1);
+}
+
+void client()
+{
+ MSG msg;
+ msg.hwnd=(HWND)-1;
+ msg.message= WM_DDE_INITIATE;
+ msg.wParam= 3;
+ msg.lParam= 4;
+ if (!DDE_SendMessage(&msg))
+ exit(-1);
+ idle_loop();
+}
+void server()
+{
+ DDE_IPC_init();
+ idle_loop();
+}
+
+int main(int argc, char *argv[])
+{
+ printf("Kill when done one message\n");
+ init_signals();
+ if (argc>1)
+ server();
+ else
+ client();
+ return 0;
+}
diff --git a/ipc/generic_hash.c b/ipc/generic_hash.c
new file mode 100644
index 0000000..6cee5d3
--- /dev/null
+++ b/ipc/generic_hash.c
@@ -0,0 +1,678 @@
+/***************************************************************************
+ * Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
+ ***************************************************************************
+ * File: generic_hash.c
+ * Purpose : dynamically growing hash, may use shared or local memory.
+ ***************************************************************************
+ */
+#include <stdlib.h>
+#include <assert.h>
+#include "generic_hash.h"
+
+#define ROUND_UP4(num) (( (num)+3) & ~3)
+
+#define FREE_ENTRY 0
+#define DELETED_ENTRY ((DWORD)-1)
+
+#define NO_OF_PRIMES 512
+#define GET_ITEM(items,size,i)\
+ (*(HASH_ITEM*) \
+ ( ((char *)(items))+ \
+ (i)*(size)) )
+
+static HASH_ITEM *locate_entry(HASH_CONTAINER* hash, DWORD key,
+ HASH_VAL *seeked_data, BOOL skip_deleted);
+
+static void copy_hash_items(HASH_CONTAINER *hash, HASH_ITEM *old_items,
+ int old_n_items);
+
+static BOOL arrays_initialized = FALSE;
+static int primes[NO_OF_PRIMES];
+static int best_primes[NO_OF_PRIMES];
+static int no_of_primes;
+static int no_of_best_primes;
+static int max_num;
+
+/* binary search for `num' in the `primes' array */
+static BOOL prime_binary_search_found(int num)
+{
+ int min_idx, max_idx, idx;
+
+ min_idx=0;
+ max_idx=no_of_primes-1;
+
+ while (min_idx <= max_idx) {
+ idx = (max_idx + min_idx) >> 1;
+ if (num == primes[idx])
+ return TRUE;
+ if (num < primes[idx])
+ max_idx = idx-1;
+ else
+ min_idx = idx+1;
+ }
+ return FALSE;
+}
+
+static BOOL is_prime(int num)
+{
+ int i;
+ if ((num & 0x1) == 0) /* can be divided by 2 */
+ if (num == 2)
+ return TRUE;
+ else
+ return FALSE;
+
+ if (num <= primes[no_of_primes-1])
+ return prime_binary_search_found(num);
+
+ for (i=0 ; i < no_of_primes ; i++) {
+ if (num % primes[i] == 0)
+ return FALSE;
+ if (num < primes[i] * primes[i])
+ return TRUE;
+ }
+ return TRUE;
+}
+
+static void setup_primes()
+{
+ int num;
+
+ primes[0]=2;
+ primes[1]=3;
+ no_of_primes=2;
+
+ /* count in modulo 6 to avoid numbers that divide by 2 or 3 */
+ for (num=5 ; ; num+=6) {
+ if (is_prime(num)) {
+ primes[no_of_primes++]=num;
+ if (no_of_primes >= NO_OF_PRIMES)
+ break;
+ }
+ if (is_prime(num+2)) {
+ primes[no_of_primes++]=num+2;
+ if (no_of_primes >= NO_OF_PRIMES)
+ break;
+ }
+ }
+ max_num= primes[no_of_primes-1] * primes[no_of_primes-1];
+}
+
+
+/* Find primes which are far "enough" from powers of two */
+
+void setup_best_primes()
+{
+ int i;
+ int num;
+ int pow2before, pow2after;
+ int min_range, max_range;
+
+ min_range=3;
+ max_range=3;
+ pow2before= 2;
+ pow2after= 4;
+
+ no_of_best_primes= 0;
+ for (i=0 ; i < no_of_primes ; i++){
+ num= primes[i];
+
+ if (num > pow2after) {
+ pow2before= pow2after;
+ pow2after <<=1;
+ min_range= pow2before+ (pow2before >> 3);
+ max_range= pow2after- (pow2before >> 2);
+ }
+ if (num > min_range && num < max_range)
+ best_primes[no_of_best_primes++]=num;
+ }
+}
+
+/* binary search for `num' in the `best_primes' array,
+ * Return smallest best_prime >= num.
+ */
+static int best_prime_binary_search(int num)
+{
+ int min_idx, max_idx, idx;
+
+ min_idx=0;
+ max_idx=no_of_best_primes-1;
+
+ while (1) {
+ idx = (max_idx + min_idx) >> 1;
+ if (num == best_primes[idx])
+ return num;
+ if (num < best_primes[idx]) {
+ max_idx = idx-1;
+ if (max_idx <= min_idx)
+ return best_primes[idx];
+ }
+ else {
+ min_idx = idx+1;
+ if (min_idx >= max_idx)
+ return best_primes[max_idx];
+ }
+ }
+
+}
+
+/* Find the best prime, near `num' (which can be any number) */
+static int best_prime(int num)
+{
+ int log2;
+ int pow2less, pow2more;
+ int min_range, max_range;
+
+ if (num < 11)
+ return 11;
+
+ if (num <= best_primes[no_of_best_primes-1])
+ return best_prime_binary_search(num);
+
+ assert( num < max_num );
+
+ for (log2=0 ; num >> log2 ; log2++)
+ ;
+
+ pow2less= 1 << log2;
+ pow2more= 1 << (log2+1);
+ min_range= pow2less + (pow2less >> 3);
+ max_range= pow2more - (pow2more >> 3);
+
+ if (num < min_range)
+ num= min_range;
+
+ num |= 1; /* make sure num can't be divided by 2 */
+
+ while (1) {
+ if (num >= max_range) {
+ pow2less<<= 1;
+ pow2more<<= 1;
+ min_range= pow2less + (pow2less >> 3);
+ max_range= pow2more - (pow2more >> 3);
+ num= min_range | 1; /* make sure num can't be divided by 2 */
+ }
+ /* num should be here in the range: (min_range, max_range) */
+ if (is_prime(num))
+ return num;
+ num+=2;
+ }
+}
+
+/* FIXME: This can be done before compiling. (uning a script)*/
+static void setup_arrays()
+{
+ setup_primes();
+ setup_best_primes();
+}
+
+/* Discard all DELETED_ENTRYs moving the data to it's correct location.
+ * Done without a temporary buffer.
+ * May require some efficiency improvements ( currently it's o(N^2)
+ * or is it o(N^3) in the worst case ? In the avarege it seems to be
+ * something like o(N log (N)))
+ */
+static void static_collect_garbge(HASH_CONTAINER *hash)
+{
+ int i;
+ BOOL change;
+ HASH_ITEM *items;
+ HASH_ITEM *located;
+ HASH_ITEM *item;
+ int key;
+
+ items= hash->items;
+
+ do {
+ change= FALSE;
+ for (i=hash->shared->total_items-1 ; i >= 0 ; i--) {
+ item= &GET_ITEM(items,hash->bytes_per_item,i);
+ key= item->key;
+ if (key != DELETED_ENTRY && key != FREE_ENTRY) {
+ /* try to place the entry in a deleted location */
+ located= locate_entry(hash, key, &item->data,
+ 0 /* no skip_deleted */);
+ if (located->key == DELETED_ENTRY) {
+ change= TRUE;
+ memcpy(&located, &item,
+ hash->bytes_per_item);
+ item->key= DELETED_ENTRY;
+ }
+ }
+ }
+ } while (change);
+
+ /* No change means that there is no need to go through a DELETED_ENTRY
+ * in order to reach an item, so DELETED_ENTRY looses it's special
+ * meaning, and it is the same as FREE_ENTRY.
+ */
+ for (i=hash->shared->total_items-1 ; i >= 0 ; i--)
+ if (GET_ITEM(items,hash->bytes_per_item,i).key == DELETED_ENTRY)
+ GET_ITEM(items,hash->bytes_per_item,i).key = FREE_ENTRY;
+ hash->shared->deleted_items=0;
+}
+
+static void collect_garbge(HASH_CONTAINER *hash)
+{
+ HASH_SHARED *shared= hash->shared;
+ HASH_ITEM *temp_items;
+ int size;
+
+ size= shared->total_items * hash->bytes_per_item;
+ temp_items= (HASH_ITEM*)malloc(size);
+ if (temp_items==NULL) {
+ static_collect_garbge(hash);
+ } else {
+ memcpy(temp_items, hash->items, size);
+ copy_hash_items(hash, temp_items, shared->total_items);
+ }
+}
+
+
+static void copy_hash_items(HASH_CONTAINER *hash, HASH_ITEM *old_items,
+ int old_n_items)
+{
+ HASH_SHARED *shared= hash->shared;
+ HASH_ITEM *item;
+ int i;
+
+ shared->deleted_items = 0;
+ shared->free_items= shared->total_items;
+
+ /* make all items free */
+ for (i= shared->total_items-1 ; i>=0 ; i--)
+ GET_ITEM(hash->items, hash->bytes_per_item, i).key = FREE_ENTRY;
+
+ /* copy items */
+ for (i=0 ; i <= old_n_items; i++) {
+ item= &GET_ITEM(old_items, hash->bytes_per_item,i);
+ if (item->key != FREE_ENTRY && item->key != DELETED_ENTRY)
+ hash_add_item(hash, item->key, &item->data);
+ }
+}
+
+
+static void reorder_hash(HASH_CONTAINER *hash)
+{
+ HASH_SHARED *shared= hash->shared;
+ HASH_ITEM *items, *old_items;
+ HASH_PTR shared_items, old_shared_items;
+ int n_items, old_n_items;
+ int size;
+
+ if (shared->deleted_items > hash->min_free_items) {
+ collect_garbge(hash);
+ return;
+ }
+ n_items= best_prime(shared->total_items * HASH_REALLOC_JUMPS);
+
+ size= n_items *
+ (sizeof(items[0]) - sizeof(items[0].data) + hash->bytes_per_item);
+
+ shared_items= hash->allocate_mem(size);
+ items= hash->access_mem(shared_items);
+
+ if (items == NULL) {
+ collect_garbge(hash);
+ return;
+ }
+ old_shared_items = shared->items;
+ old_n_items= shared->total_items;
+ old_items= hash->items;
+
+ /* setup a new clean hash based on the parameters of the original one */
+ hash->items= items;
+ shared->total_items = n_items;
+ shared->items= shared_items;
+ set_hash_parameters(hash, hash->maximum_load);
+ copy_hash_items(hash, old_items, old_n_items);
+
+ hash->free_mem(old_shared_items);
+ hash->last_ptr_update= ++shared->ptr_updates;
+}
+
+/* low level: attach hash existing hash items, no checks are performed
+ * No complex calculations done.
+ */
+static HASH_CONTAINER *attach_no_check(HASH_ITEM *items, int bytes_per_datum)
+{
+ HASH_CONTAINER *hash;
+ int bytes_per_item;
+ HASH_ITEM dummy_item;
+
+ hash= (HASH_CONTAINER*) malloc(sizeof(HASH_CONTAINER) );
+ if (hash == NULL)
+ return NULL;
+
+ bytes_per_item= bytes_per_datum+
+ sizeof(dummy_item)-sizeof(dummy_item.data);
+ hash->bytes_per_item= ROUND_UP4(bytes_per_item);
+ hash->items= items;
+ hash->is_correct_item= NULL;
+ hash->allocate_mem= HASH_MEM_ALLOC;
+ hash->access_mem= HASH_MEM_ACCESS;
+ hash->free_mem= HASH_MEM_FREE;
+ set_hash_parameters(hash, HASH_LOAD);
+
+
+ return hash;
+}
+
+
+/* Attach existing & running remote (i.e. shared) hash.
+ * Attach the items using the data stored in "shared"
+ */
+HASH_CONTAINER *attach_remote_hash(HASH_SHARED *shared, int bytes_per_datum,
+ HASH_ITEM *(*access_mem)(HASH_PTR))
+{
+ HASH_CONTAINER *hash;
+ HASH_ITEM *items;
+
+ assert(access_mem != NULL);
+ if (! arrays_initialized)
+ setup_arrays();
+
+ items=access_mem(shared->items);
+ hash= attach_no_check(items, bytes_per_datum);
+ if (hash == NULL)
+ return NULL;
+
+ hash->shared_was_malloced = FALSE;
+ hash->shared= shared;
+ return (hash);
+}
+
+
+HASH_CONTAINER *create_remote_hash(HASH_SHARED *shared,
+ int bytes_per_datum,
+ int total_items,
+ HASH_PTR (*allocate_mem)(int size),
+ HASH_ITEM *(*access_mem)(HASH_PTR))
+{
+ HASH_CONTAINER *hash;
+ int size;
+ int i;
+
+ assert(total_items >= 1);
+ assert(bytes_per_datum >=1);
+ assert(access_mem != NULL);
+ assert(allocate_mem != NULL);
+ assert(shared != NULL);
+ if (! arrays_initialized)
+ setup_arrays();
+
+ if (total_items < MIN_HASH)
+ total_items= MIN_HASH;
+ else
+ total_items= best_prime(total_items);
+
+ hash= attach_no_check(NULL, bytes_per_datum);
+
+ if (hash==NULL) {
+ free(hash);
+ return NULL;
+ }
+
+ shared->total_items= total_items;
+ hash->shared= shared;
+ hash->shared_was_malloced = FALSE;
+
+ size= total_items * hash->bytes_per_item;
+
+ shared->items = allocate_mem(size);
+ hash->items= access_mem(shared->items);
+
+ if (hash->items == NULL ) {
+ free(hash);
+ return NULL;
+ }
+ shared->items.ptr= hash->items;
+
+ /* make all items free */
+ for (i=0 ; i < total_items ; i++)
+ GET_ITEM(hash->items,hash->bytes_per_item,i).key = FREE_ENTRY;
+
+ shared->deleted_items= 0;
+ shared->free_items= total_items;
+ shared->ptr_updates= 0;
+ return hash;
+
+}
+
+/* hash constructor: create brand new hash */
+HASH_CONTAINER *create_hash(int bytes_per_datum, int total_items)
+{
+ HASH_CONTAINER *hash;
+ HASH_SHARED *shared;
+
+
+ shared= (HASH_SHARED*)malloc(sizeof(HASH_SHARED));
+ if (shared == NULL)
+ return NULL;
+
+ hash= create_remote_hash(shared, bytes_per_datum, total_items,
+ HASH_MEM_ALLOC, HASH_MEM_ACCESS);
+
+ if (hash == NULL) {
+ free(shared);
+ return NULL;
+ }
+
+ hash->shared_was_malloced = TRUE;
+ return hash;
+}
+
+/* set the extra handlers to non default values */
+void set_hash_handlers(HASH_CONTAINER *hash,
+ HASH_ITEM_TEST *is_correct_item,
+ HASH_PTR (*allocate_mem)(int size),
+ void (*free_mem)(HASH_PTR),
+ HASH_ITEM *(*access_mem)(HASH_PTR))
+{
+ assert(hash);
+ assert(allocate_mem);
+ assert(free_mem);
+
+ hash->free_mem = free_mem;
+ hash->allocate_mem = allocate_mem;
+ hash->access_mem = access_mem;
+ hash->is_correct_item = is_correct_item;
+}
+
+
+/* set extra parameters */
+void set_hash_parameters(HASH_CONTAINER *hash, int load)
+{
+ assert(hash);
+ assert(load>30); /* no sence to realloc with less than */
+ /* 50% load, limiting to 30% to be on */
+ /* the safe size */
+ assert(load<=100);
+
+ hash->maximum_load= load;
+ hash->min_free_items= (1.0 - load/100.0) * hash->shared->total_items + 1 ;
+}
+
+/* hash destructor: destroy anything related to the hash */
+void destroy_hash(HASH_CONTAINER *hash)
+{
+ assert(hash);
+ hash->free_mem(hash->shared->items);
+ if (hash->shared_was_malloced)
+ free(hash->shared);
+ free(hash);
+}
+
+/* hash destructor: just detach hash, without destroing it (makes */
+/* sence in shared memory environment) */
+void detach_hash(HASH_CONTAINER *hash)
+{
+ assert(hash);
+ free(hash);
+}
+
+
+/********** Hash usage *************/
+static __inline__ BOOL
+correct_entry(HASH_ITEM *item, int key, HASH_VAL *seeked_data,
+ HASH_ITEM_TEST *is_correct_item, BOOL skip_deleted)
+{
+ switch(item->key) {
+ case FREE_ENTRY:
+ return TRUE;
+
+ case DELETED_ENTRY:
+ return skip_deleted ? FALSE : TRUE;
+
+ default:
+ if (item->key != key)
+ return FALSE;
+ if (is_correct_item != NULL)
+ return is_correct_item(&item->data, seeked_data);
+ else
+ return TRUE;
+ }
+
+}
+
+/* The algorithm of the hash (one of the 2 standard hash implementations):
+ * Iterate through the hash table until
+ * 1. The entry has been found.
+ * 2. A FREE entry has been found.
+ * 3. For insert operations only- A DELETED entry has been found.
+ * The difference between DELETED and FREE entires is that
+ * DELETED entry was one occupied, while FREE was never allocated.
+ * The idea behind this structure to keep other entries reachable.
+ */
+
+static HASH_ITEM *locate_entry(HASH_CONTAINER* hash, DWORD key,
+ HASH_VAL *seeked_data, BOOL skip_deleted)
+{
+ DWORD hash_idx, hash_leaps;
+ HASH_ITEM *item;
+ int i;
+ int total_items;
+
+ assert(hash);
+
+ total_items= hash->shared->total_items;
+ hash_idx= key % total_items;
+
+ item= &GET_ITEM(hash->items, hash->bytes_per_item, hash_idx);
+
+ if ( correct_entry( item, key, seeked_data,
+ hash->is_correct_item, skip_deleted) )
+ return item;
+
+ /* get the WORDs in different order in this DWORD to avoid clustering */
+ hash_leaps=((DWORD)MAKELONG(HIWORD(key), LOWORD(key))
+ % (total_items-1)) +1;
+
+ /* interate through the hash table using hash_leaps */
+ for (i= total_items ; i ; i--) {
+ hash_idx+= hash_leaps;
+ if (hash_idx > total_items)
+ hash_idx -= total_items;
+
+ item= &GET_ITEM(hash->items,hash->bytes_per_item, hash_idx);
+ if ( correct_entry( item, key, seeked_data,
+ hash->is_correct_item, skip_deleted) )
+ return item;
+ }
+ return NULL;
+
+}
+
+static __inline__ void sync_shared_hash(HASH_CONTAINER *hash)
+{
+ HASH_SHARED *shared= hash->shared;
+
+ if (shared->ptr_updates == hash->last_ptr_update)
+ return;
+
+ assert(shared->ptr_updates >= hash->last_ptr_update);
+ hash->last_ptr_update= shared->ptr_updates;
+ hash->min_free_items= (1.0 - hash->maximum_load/100.0) *
+ shared->total_items + 1 ;
+
+ hash->items= hash->access_mem(shared->items);
+}
+
+HASH_VAL *hash_locate_item(HASH_CONTAINER* hash,
+ int key, HASH_VAL *seeked_data)
+{
+ HASH_ITEM *item;
+
+ assert(hash != NULL);
+ sync_shared_hash(hash);
+
+ item= locate_entry(hash, key, seeked_data, 1 /* skip_deleted */);
+ if (item == NULL)
+ return NULL;
+ if (item->key == FREE_ENTRY )
+ return NULL;
+
+ return &item->data;
+}
+
+
+BOOL hash_add_item(HASH_CONTAINER* hash, int key, HASH_VAL *data)
+{
+ HASH_SHARED *shared;
+ HASH_ITEM *item;
+
+ assert(hash != NULL);
+
+ sync_shared_hash(hash);
+ shared= hash->shared;
+
+ item=locate_entry(hash, key, data, 0 /* no skip_deleted */);
+ assert(item != NULL);
+ if (item->key == key)
+ return FALSE;
+ if (item->key == FREE_ENTRY)
+ shared->free_items--;
+ else
+ shared->deleted_items--;
+
+ item->key= key;
+ memcpy(&item->data, data, hash->bytes_per_item-sizeof(key));
+
+ if (shared->free_items < hash->min_free_items ||
+ shared->deleted_items > hash->min_free_items)
+ reorder_hash(hash);
+
+ return TRUE;
+}
+
+
+BOOL hash_delete_item(HASH_CONTAINER* hash, int key, HASH_VAL *seeked_data)
+{
+ HASH_ITEM *item;
+
+ assert(hash != NULL);
+ sync_shared_hash(hash);
+
+ item=locate_entry(hash, key, seeked_data, 1 /* skip_deleted */);
+ if (item == NULL)
+ return FALSE;
+
+ if (item->key == FREE_ENTRY)
+ return FALSE;
+
+ item->key = DELETED_ENTRY;
+ hash->shared->deleted_items++;
+
+ return TRUE;
+}
+
+void *ret_null()
+{
+ return NULL;
+}
+
+
+HASH_ITEM *access_local_hash(HASH_PTR ptr)
+{
+ return ptr.ptr;
+}
diff --git a/ipc/generic_hash.h b/ipc/generic_hash.h
new file mode 100644
index 0000000..5def7e6
--- /dev/null
+++ b/ipc/generic_hash.h
@@ -0,0 +1,141 @@
+/***************************************************************************
+ * Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
+ ***************************************************************************
+ * File: generic_hash.h
+ * Purpose : dynamically growing hash, may use shared or local memory.
+ ***************************************************************************
+ */
+#ifndef _GENERIC_HASH_H_
+#define _GENERIC_HASH_H_
+
+#include "wintypes.h"
+#include "shm_block.h"
+/* default hash values */
+#define HASH_LOAD 70
+#define HASH_MEM_ALLOC (HASH_PTR (*)(int size)) malloc
+#define HASH_MEM_FREE (void (*)(HASH_PTR)) free
+#define HASH_MEM_ACCESS access_local_hash
+#define HASH_REALLOC_JUMPS 1.5 /* Relative size of the new memory */
+#define MIN_HASH 13
+
+typedef union {
+ char string[1];
+ WORD words[1];
+ DWORD dwords[1];
+ char *ptr;
+ SEGPTR segptr;
+} HASH_VAL;
+
+typedef struct hash_item_struct {
+ DWORD key;
+ HASH_VAL data;
+} HASH_ITEM;
+
+/* point to the hash structure */
+typedef union {
+ HASH_ITEM* ptr; /* Local pointer */
+ REL_PTR rel; /* IPC relative address */
+ SEGPTR segptr; /* Universal (can be IPC or local) */
+} HASH_PTR;
+
+typedef struct hash_share_struct {
+ int total_items; /* total number of items (array size) */
+ int free_items; /* number of free items (excluding deleted) */
+ int deleted_items; /* number of deleted items */
+ int ptr_updates; /* Number of updates to `items' pointer */
+ /* (of items) - used for intecepting */
+ /* changes to the pointer. */
+ HASH_PTR items; /* pointer to the items */
+} HASH_SHARED;
+typedef BOOL HASH_ITEM_TEST(HASH_VAL *value, HASH_VAL *seeked_data);
+
+/* NOTE:
+ * 1. Keys 0 and -1 are reserved.
+ * 2. none of these items should be accessed directly, use existing
+ * functions. If they are not enough, add a new function.
+ */
+typedef struct hash_container_struct {
+ int bytes_per_item;
+ int maximum_load; /* in percents (0..100) default is 70 */
+ int min_free_items; /* minimum free items before reallocating
+ (Function of maximum_load) */
+
+ int last_ptr_update; /* to be compared with shared.ptr_updates */
+ BOOL shared_was_malloced; /* Need that to know how to destroy hash */
+
+ /* This is an optional handler.
+ * If not NULL, this function is used for distinguishing between
+ * different data with the same key (key field holds integer and
+ * is too short for long keys like strings).
+ */
+ HASH_ITEM_TEST *is_correct_item;
+
+ /* Handlers used for reallocating memory
+ * [by allocating new data and then freeing old data]
+ */
+ HASH_PTR (*allocate_mem)(int size);
+ void (*free_mem)(HASH_PTR);
+
+ /* Translator from HASH_PTR construct to a regular pointer.
+ use HASH_MEM_ACCESS, if no translation is needed */
+ HASH_ITEM *(*access_mem)(HASH_PTR);
+
+ HASH_ITEM *items;
+ HASH_SHARED *shared; /* Things to be on shared memory. */
+} HASH_CONTAINER;
+
+
+/********** Hash maintenance functions ***********/
+
+
+
+/* Attach existing & running remote (i.e. shared) hash.
+ * Attach the items using the data stored in "shared"
+ */
+HASH_CONTAINER *attach_remote_hash(HASH_SHARED *shared, int bytes_per_datum,
+ HASH_ITEM *(*access_mem)(HASH_PTR));
+
+
+HASH_CONTAINER *create_remote_hash(HASH_SHARED *shared,
+ int bytes_per_datum,
+ int total_items,
+ HASH_PTR (*allocate_mem)(int size),
+ HASH_ITEM *(*access_mem)(HASH_PTR));
+/* hash constructor: create brand new hash (not on shared memory) */
+HASH_CONTAINER *create_hash(int bytes_per_datum, int total_items);
+
+/* set the extra handlers to non default values */
+void set_hash_handlers(HASH_CONTAINER *hash,
+ HASH_ITEM_TEST *is_correct_item,
+ HASH_PTR (*allocate_mem)(int size),
+ void (*free_mem)(HASH_PTR),
+ HASH_ITEM *(*access_mem)(HASH_PTR));
+
+/* set extra parameters */
+void set_hash_parameters(HASH_CONTAINER *hash, int load);
+
+/* hash destructors */
+void destroy_hash(HASH_CONTAINER *hash);
+void detach_hash(HASH_CONTAINER *hash);
+
+
+/********** Hash usage *************/
+
+/* All following functions have the same format:
+ * hash- the hash structure to use
+ * key- used as primary means to get to the entry.
+ * data- 1. a secondary key (used only if `is_correct_item' is set).
+ * 2. data to store. (for hash_add_item).
+ */
+HASH_VAL *hash_locate_item(HASH_CONTAINER* hash,int key, HASH_VAL* seeked_data);
+BOOL hash_add_item(HASH_CONTAINER* hash, int key, HASH_VAL* data);
+BOOL hash_delete_item(HASH_CONTAINER* hash, int key, HASH_VAL* seeked_data);
+
+
+void *ret_null(); /* function returning null (used for */
+ /* disabling memory reallocation) */
+
+/* access function used by local (non IPC) memory */
+HASH_ITEM *access_local_hash(HASH_PTR ptr);
+
+#endif /* _GENERIC_HASH_H_ */
diff --git a/ipc/hash_test.c b/ipc/hash_test.c
new file mode 100644
index 0000000..dec32c4
--- /dev/null
+++ b/ipc/hash_test.c
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
+ ***************************************************************************
+ * File: hash_test.c
+ * Purpose : test generic_hash correctness.
+ * NOTE:
+ * This code covers only about 80% of generic_hash code.
+ * There might be bugs in the remaining 20% - although most
+ * of the functionality is tested with wine linckage.
+ * For complete testing a little more work should be done.
+ ***************************************************************************
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include "generic_hash.h"
+
+#define SIZE 200
+typedef struct { int a,b;} DATA ;
+DATA data[SIZE];
+int keys[SIZE];
+int peeks=0;
+
+HASH_CONTAINER *hash1;
+HASH_CONTAINER *hash2; /* actual data is shared with hash1 */
+
+/* test insertion using keys[] and data[] inserting using hash1 and */
+/* hash2 periodically, test hash after every 2 insertions */
+void test_insert()
+{
+ int i,j;
+ HASH_VAL *item;
+
+ printf("testing insertion \n");
+ for (i=0 ; i < SIZE-1 ; i+=2) {
+ assert(hash_add_item(hash1, keys[i], (HASH_VAL *)&data[i]));
+ assert(hash_add_item(hash2, keys[i+1], (HASH_VAL *)&data[i+1]));
+ for (j=0 ; j <= i+1 ; j++) {
+ item= hash_locate_item(hash1, keys[j], (HASH_VAL *)&data[j]);
+ if (item == NULL) {
+ printf("NULL item: i=%d,j=%d\n",i,j);
+ continue;
+ }
+ peeks++;
+ if (memcmp(item,&data[j],sizeof(DATA))!=0) {
+ printf("i=%d,j=%d\n",i,j);
+ printf("saved=(%d,%d), orig=(%d,%d)\n",
+ ((DATA*)item)->a, ((DATA*)item)->b,
+ data[j].a, data[j].b);
+ }
+ }
+ }
+}
+
+/* test deletion using keys[] and data[] deleting using hash1 and */
+/* hash2 periodicly, test hash after every 2 deletions */
+void test_delete()
+{
+ int i,j;
+ HASH_VAL *item;
+
+ printf("testing deletion\n");
+ for (i=0 ; i < SIZE-1 ; i+=2) {
+ assert(hash_delete_item(hash2, keys[i], NULL));
+ assert(hash_delete_item(hash1, keys[i+1], NULL));
+ for (j=0 ; j < SIZE ; j++) {
+ item= hash_locate_item(hash2, keys[j], (HASH_VAL *)&data[j]);
+ if (item == NULL) {
+ if ( j > i+1)
+ printf("NULL item: i=%d,j=%d\n",i,j);
+ continue;
+ }
+ if (item != NULL && j <= i+1) {
+ printf("Non NULL item: i=%d,j=%d\n",i,j);
+ continue;
+ }
+ if (memcmp(item,&data[j],sizeof(DATA))!=0) {
+ printf("i=%d,j=%d\n",i,j);
+ printf("saved=(%d,%d), orig=(%d,%d)\n",
+ ((DATA*)item)->a, ((DATA*)item)->b,
+ data[j].a, data[j].b);
+ }
+ }
+ }
+
+}
+
+
+int main()
+{
+ int i;
+
+ hash1= create_hash(sizeof(DATA), 1);
+ assert(hash1);
+ hash2= attach_remote_hash(hash1->shared, sizeof(DATA), HASH_MEM_ACCESS);
+ assert(hash2);
+
+ for (i=0 ; i< SIZE ; i++) {
+ data[i].a= rand();
+ data[i].b= rand();
+ keys[i]= rand();
+ }
+
+ test_insert();
+ detach_hash(hash1);
+ free(hash1);
+ hash1= attach_remote_hash(hash2->shared, sizeof(DATA), HASH_MEM_ACCESS);
+
+ test_delete();
+ test_insert();
+
+ detach_hash(hash1);
+ destroy_hash(hash2);
+ printf("peeks=%d\n", peeks);
+ return 0;
+}
diff --git a/ipc/run_tests b/ipc/run_tests
new file mode 100644
index 0000000..638fb18
--- /dev/null
+++ b/ipc/run_tests
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+bit_array_test
+bit_array=$?
+
+dde_mem_test
+mem=$?
+
+hash_test
+hash=$?
+
+shm_semaph_test
+semaph=$?
+
+dde_atom_test
+atom=$?
+
+dde_proc_test 1 > proc_server &
+sleep 1
+dde_proc_test > proc_client
+fgrep "DDE:receive sent message. msg=03e0 wPar=fffb lPar=00000004" proc_server &&
+fgrep "DDE_GetRemoteMessage: sending ACK to wnd=fffb, proc=1" proc_server &&
+fgrep "get_ack: received DDE_ACK message" proc_client
+proc=$?
+rm proc_client proc_server
+
+shm_fragment_test | diff TEST_FRAGMENT.std -
+fragment=$?
+
+echo ====================================================================
+echo Test results:
+
+echo -n "bit_array "
+if [ $bit_array -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
+
+echo -n "dde_mem "
+if [ $mem -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
+
+echo -n "hash "
+if [ $hash -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
+
+echo -n "shm_semaph "
+if [ $semaph -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
+
+echo -n "dde_proc "
+if [ $proc -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
+
+echo -n "shm_fragment "
+if [ $fragment -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
diff --git a/ipc/shm_block.c b/ipc/shm_block.c
new file mode 100644
index 0000000..057c981
--- /dev/null
+++ b/ipc/shm_block.c
@@ -0,0 +1,191 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_block.c
+ * Purpose: Treat a shared memory block.
+ ***************************************************************************
+ */
+
+#define inline __inline__
+#include <sys/sem.h>
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stddebug.h>
+#include <debug.h>
+#include <global.h>
+#include "selectors.h"
+#include "shm_fragment.h"
+#include "shm_block.h"
+#include "shm_semaph.h"
+#include "dde_proc.h"
+
+/* How each shmid is maped to local pointer */
+/* Only attached shm blocks are in this construct */
+struct local_shm_map *shm_map=NULL;
+
+/* setup a new shm block (construct a shm block object).
+ * block: The pointer to the memory block (local mapping)
+ * first: The first data byte (excluding header stuff),
+ * if 0 (zero) Use the default.
+ * size: The size of the memory block.
+ */
+void shm_setup_block(struct shm_block *block, int first, int size)
+{
+ dprintf_shm(stddeb,"Setting up shm block at 0x%08x\n",(int )block);
+ /* setup block internal data structure */
+ if (first <= 0) {
+ first=sizeof(*block);
+ /* round up - so everything starts on cache line boundary
+ * (assume cache line=32 bytes, may be bigger/smaller for
+ * different processors and different L2 caches .)
+ */
+ first=(first+0x1f) & ~0x1f;
+ }
+ block->free=size-first;
+ block->next_shm_id=-1; /* IPC shm ID (for initial linking) */
+ block->proc_idx= curr_proc_idx;
+ /* block->size is initialized in shm_FragmentInit */
+ shm_FragmentInit(block, first, size); /* first item in the free list */
+
+ dprintf_shm(stddeb,
+ "block was set up at 0x%08x, size=0x%04xKB, 1st usable=%02x\n",
+ (int )block,size/1024,first);
+}
+
+/* shm_attach_block: attach existing shm block, setup selectors
+ * shm_id - id of the block to attach.
+ * proc_idx - if not -1, puts this data into local mapping
+ * map - localy mapped info about this block.
+ */
+/* NOTE: there is no check if this block is already attached.
+ * Attaching the same block more than once - is possible
+ * In case of doubt use shm_locate_block.
+ */
+struct shm_block *shm_attach_block(int shm_id, int proc_idx,
+ struct local_shm_map *map)
+{
+ struct shm_block *block;
+ struct shmid_ds ds;
+ struct local_shm_map *this;
+
+ shmctl(shm_id, IPC_STAT, &ds );
+
+ block=(struct shm_block*)shmat(shm_id, NULL, 0);
+ if (block==NULL) return NULL;
+
+ this=(struct local_shm_map *)malloc(sizeof(*this));
+ this->next= shm_map;
+ shm_map = this;
+ this->shm_id= shm_id;
+ this->ptr = block;
+
+ if (proc_idx < 0)
+ this->proc_idx=block->proc_idx;
+ else
+ this->proc_idx=proc_idx;
+
+ if (map != NULL) {
+ memcpy(map, this, sizeof(map));
+ map->next= NULL; /* don't pass private info */
+ }
+
+ return block;
+}
+
+struct shm_block *shm_create_block(int first, int size, int *shm_id)
+{
+ struct shm_block *block;
+
+ if (size==0)
+ size=SHM_MINBLOCK;
+ else
+ /* round up size to a multiple of SHM_MINBLOCK */
+ size= (size+SHM_MINBLOCK-1) & ~(SHM_MINBLOCK-1);
+ *shm_id= shmget ( IPC_PRIVATE, size ,0700);
+ if (*shm_id==-1)
+ return NULL;
+ block=shm_attach_block(*shm_id, curr_proc_idx, NULL);
+ if (block!=NULL)
+ shm_setup_block(block, first, size);
+
+ return block;
+}
+
+/*
+** Locate attached block. (return it, or NULL on failure)
+** shm_id is the block we look for.
+** *map - will get all the info related to this local map + proc_idx
+** (may be NULL)
+** *seg - will get the segment this block is attached to.
+*/
+struct shm_block *shm_locate_attached_block(int shm_id,
+ struct local_shm_map *map)
+{
+ struct local_shm_map *curr;
+
+ for (curr= shm_map ; curr != NULL ; curr= curr->next) {
+ if (curr->shm_id == shm_id) {
+ if (map) {
+ memcpy(map, curr, sizeof(*curr) );
+ map->next = NULL; /* this is private info ! */
+ }
+ return curr->ptr;
+ }
+ }
+
+ /* block not found ! */
+ return 0;
+}
+
+/* shm_locate_block: see shm_attach_block.
+ In addition to shm_attach_block, make sure this
+ block is not already attached.
+ */
+struct shm_block *shm_locate_block(int shm_id, struct local_shm_map *map)
+{
+
+ struct shm_block *ret;
+ ret= shm_locate_attached_block(shm_id, map);
+ if (ret!=NULL)
+ return ret;
+ /* block not found ! , try to attach */
+ return shm_attach_block(shm_id, -1, map);
+}
+
+static void forget_attached(int shmid)
+{
+ struct local_shm_map *curr, **point_to_curr;
+
+ for (curr= shm_map, point_to_curr= &shm_map ;
+ curr != NULL ;
+ curr= curr->next, point_to_curr= &curr->next ) {
+ if (curr->shm_id == shmid) {
+ *point_to_curr= curr->next;
+ return;
+ }
+ }
+}
+
+/* delete chain of shm blocks (pointing to each other)
+ * Do it in reverse order. (This is what the recursion is for)
+ */
+void shm_delete_chain(int *shmid)
+{
+ struct shm_block *block;
+
+ if (*shmid == -1)
+ return;
+
+ block= shm_locate_block(*shmid, NULL);
+ forget_attached( *shmid );
+ if (block == NULL)
+ return;
+ shm_delete_chain(&block->next_shm_id);
+ shmctl(*shmid, IPC_RMID, NULL);
+ *shmid=-1;
+ shmdt((char *)block);
+}
diff --git a/ipc/shm_fragment.c b/ipc/shm_fragment.c
new file mode 100644
index 0000000..098d6cc
--- /dev/null
+++ b/ipc/shm_fragment.c
@@ -0,0 +1,178 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_fragment.c
+ * Purpose: Data fragments and free list items. Allocate and free blocks.
+ ***************************************************************************
+ */
+#include <stdio.h> /* for debugging only */
+#include <stddebug.h>
+#include <debug.h> /* for "stddeb" */
+
+#include "shm_fragment.h"
+#include "shm_block.h"
+
+/******************************************************************************
+ *
+ * Free list: all fragments are ordered according to memory location.
+ * new fragments are inserted in this way.
+ *
+ ******************************************************************************
+ */
+
+#define FRAG_PTR(block,ofs) ((struct shm_fragment *) ((char *) block + ofs) )
+#define NEXT_FRAG(block,ofs) ( FRAG_PTR(block,ofs)->info.next )
+
+/* setup first item in the free list */
+void shm_FragmentInit(struct shm_block *block,int first, int size)
+{
+ struct shm_fragment *fragment;
+
+ /* round up to nearest 16 byte boundary */
+ first=(first+15)& ~15;
+ block->free_list=first;
+
+ /* make all the block (exluding the header) free */
+ fragment= FRAG_PTR(block, first);
+ block->free= fragment->size= size-first;
+ fragment->info.next=0;
+}
+
+void shm_FragPtrFree(struct shm_block *block, void *ptr)
+{
+ /* ptr points to fragment->info.data, find pointer to fragment,
+ * find the offset of this pointer in block.
+ */
+ if (ptr)
+ shm_FragmentFree(block, PTR2REL(block, ptr));
+}
+void shm_FragmentFree(struct shm_block *block, int fragment_ofs)
+{
+ struct shm_fragment *fragment=NULL;
+ int prev;
+ int next;
+
+ fragment_ofs-=(int )&fragment->info.data;
+ fragment= FRAG_PTR(block, fragment_ofs);
+
+ block->free+=fragment->size;
+ /* scan free list to find candidates for merging with fragment */
+ for (prev=0, next=block->free_list;
+ (next!=0) && (fragment_ofs > next) ;
+ prev=next, next=NEXT_FRAG(block,next) )
+ ;
+
+ /* insert fragment between, prev and next
+ * prev==0: fragment will be the first item in free list
+ * next==0: fragment will be the last item in free list
+ */
+
+
+ /* update fragment (point to next, or merge with next) */
+
+ if ( fragment_ofs+fragment->size == next ) {
+ /* merge with the next free block */
+ fragment->size+= FRAG_PTR(block,next)->size;
+ fragment->info.next=FRAG_PTR(block,next)->info.next;
+ } else
+ /* fragment should be inserted before the next fragment or end of */
+ /* list. (not merged) */
+ fragment->info.next=next;
+ /* now fragment has all the information about the rest of the list */
+
+
+ /* upate prev fragment (point or merge with fragment) */
+
+ if (prev==0) /* first item in free list */
+ block->free_list=fragment_ofs;
+ else if ( prev+FRAG_PTR(block,prev)->size == fragment_ofs ) {
+ /* merge fragment with previous fragment */
+ FRAG_PTR(block,prev)->size+= fragment->size;
+ FRAG_PTR(block,prev)->info.next=fragment->info.next;
+ } else
+ /* insert fragment after previous fragment */
+ FRAG_PTR(block,prev)->info.next=fragment_ofs;
+}
+
+/* use "first fit" algorithm,
+ * return: offset to data in fragment.
+ */
+int shm_FragmentAlloc(struct shm_block *block, int size)
+{
+ int prev;
+ int candidate;
+ struct shm_fragment *fragment;
+ struct shm_fragment *ret_fragment;
+
+ if (size <= 0)
+ return NIL;
+ /* add size of "fragment->size" */
+ size+= (char *)&fragment->info.data - (char *)fragment ;
+
+ /* round "size" to nearest 16 byte value */
+ size= (size+15) & ~15;
+ if (size > block->free)
+ return NIL;
+ /* scan free list to find candidates for allocation */
+ for (prev=0, candidate=block->free_list;
+ candidate!=0 ;
+ prev=candidate, candidate= fragment->info.next )
+ {
+ fragment=FRAG_PTR(block,candidate);
+ if (fragment->size >= size)
+ break;
+ }
+
+ if (candidate == 0)
+ return NIL;
+
+ block->free-=size;
+ if (fragment->size == size) {
+ if (prev == 0)
+ block->free_list= fragment->info.next;
+ else
+ FRAG_PTR(block,prev)->info.next= fragment->info.next;
+ return PTR2REL(block, &fragment->info.data);
+ }
+
+ /* fragment->size > size */
+
+ /* Split fragment in two, return one part, put the other in free list. */
+ /* The part that starts at the old location - will stay in the free list. */
+ fragment->size -= size;
+
+ ret_fragment=FRAG_PTR(block, candidate + fragment->size);
+ ret_fragment->size= size;
+ return PTR2REL(block, ret_fragment->info.data);
+}
+
+/* like shm_FragmentAlloc, returns pointer instead of offset */
+char *shm_FragPtrAlloc(struct shm_block *block, int size)
+{
+ int ofs;
+ ofs= shm_FragmentAlloc(block,size);
+ if (ofs == NIL)
+ return NULL;
+ else
+ return (char *) REL2PTR(block, ofs);
+}
+/* This is used for debugging only */
+void shm_print_free_list(struct shm_block *block)
+{
+ struct shm_fragment *fragment;
+ int item;
+
+ item=block->free_list;
+ if (item==0) {
+ fprintf(stddeb,"no free fragments");
+ } else {
+ for (; item ; item=fragment->info.next) {
+ fragment=FRAG_PTR(block,item);
+ fprintf(stddeb,"{0x%04x,0x%04x} ",item,fragment->size);
+ }
+ }
+ fprintf(stddeb," [total free=%04x]\n",block->free);
+ fflush(stddeb);
+}
diff --git a/ipc/shm_fragment_test.c b/ipc/shm_fragment_test.c
new file mode 100644
index 0000000..8964715
--- /dev/null
+++ b/ipc/shm_fragment_test.c
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_fragment_test.c
+ * Purpose: Test data fragments and free list items. Allocate and free blocks.
+ ***************************************************************************
+ */
+#include <assert.h>
+#include <stdio.h>
+#include <stddebug.h>
+#define DEBUG_DEFINE_VARIABLES /* just avoid dumb errors */
+#include <debug.h> /* for "stddeb" */
+#include <stdlib.h>
+#include <string.h>
+#include "shm_block.h"
+#include "shm_fragment.h"
+
+#define DO_FREE(id) (-id)
+#define LIST_LENGTH 20
+
+int main()
+{
+ struct shm_block *block;
+ char *ret;
+ int size;
+ int i;
+
+ /* important: The test will work only for the current implementation of */
+ /* allocation, if the implementation will change, the list should also */
+ /* cahnge. */
+ static int sizes[LIST_LENGTH]={
+ SHM_MINBLOCK, /* 0: should fail */
+ 0x3fe0-4, /* 1: */
+ 0x4000-4, /* 2: */
+ 0x4000-4, /* 3: */
+ 0x4000-4+1, /* 4: should fail */
+ 0x4000-4, /* 5: */
+ /* allocated(5,3,2,1) free() */
+ -5, /* 6: */
+ 0x1c00-4, /* 7: */
+ 0x1400-4, /* 8: */
+ 0x1000-4, /* 9: */
+ /* allocated(9,8,7,3,2,1) free() */
+ -9, /* 10: */
+ -3, /* 11: */
+ -1, /* 12: */
+ /* allocated(8,7,2) free(9,3,1) */
+ 0x1000-4, /* 13: */
+ -13, /* 14: */
+ 0x1000+1-4, /* 15: */
+ /* allocated(8,7,15,2) free(9,[3-15],1) */
+ -2, /* 16: */
+ /* allocated(8,7,15) free(9,[3-15],1+2) */
+ -8, /* 17: */
+ -7, /* 18: */
+ -15 /* 19: */
+ };
+
+ static char *ptr[LIST_LENGTH];
+
+ block=malloc(SHM_MINBLOCK);
+ assert(block);
+
+ /* setup first item in the free list */
+ shm_FragmentInit(block, sizeof(*block), SHM_MINBLOCK);
+
+ fprintf(stddeb,"After shm_FragmentInit\n");
+ shm_print_free_list(block);
+
+ for(i=0 ; i < LIST_LENGTH; i++) {
+ size=sizes[i];
+ if (size>0) { /* allocate */
+ ret=shm_FragPtrAlloc(block, size);
+ ptr[i]=ret;
+ fprintf(stddeb,
+ "%d: After shm_FragmentAlloc(block, 0x%06x) == ",
+ i, size);
+ if (ret==NULL)
+ fprintf(stddeb, "NULL\n");
+ else {
+ fprintf(stddeb, "0x%06x\n", (int)ret-(int)block);
+ bzero (ret,size); /* test boundaries */
+ }
+ } else { /* free */
+ /* free shm fragment */
+ ret=ptr[-sizes[i]];
+ fprintf(stddeb, "%d: Doing shm_FragmentFree(block, ", i);
+ if (ret==NULL)
+ fprintf(stddeb, "NULL)\n");
+ else
+ fprintf(stddeb, "0x%06x)\n", (int)ret-(int)block);
+ fflush(stddeb);
+ shm_FragPtrFree(block, ret);
+ }
+ shm_print_free_list(block);
+ }
+ return 0;
+}
diff --git a/ipc/shm_main_blk.c b/ipc/shm_main_blk.c
new file mode 100644
index 0000000..3fb798e
--- /dev/null
+++ b/ipc/shm_main_blk.c
@@ -0,0 +1,264 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_main_blk.c
+ * Purpose: Main Wine's shared memory block
+ ***************************************************************************
+ */
+#define inline __inline__
+#include <sys/sem.h>
+#include <stdio.h>
+#include <time.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <stddebug.h>
+#include <debug.h>
+#include "shm_fragment.h"
+#include "shm_block.h"
+#include "shm_main_blk.h"
+#include "shm_semaph.h"
+
+#define WineKey ( 'W'+((int)'i'<<8)+((int)'n'<<16)+((int)'e'<<24) )
+#define SHM_KEY_RANGE 8
+
+/* main block (set during initialization) */
+struct shm_main_block *main_block=NULL;
+static char *shm_header="Wine - Windows emulator DDE mechanism";
+static int main_shm_id;
+
+static void shm_main_refresh();
+
+/* for debugging only */
+static void print_perm(struct ipc_perm *perm)
+{
+ printf("Permission:\n");
+ printf("\tKey=%d, mode=%03o, sequence #=%d\n",
+ (int)perm->key,perm->mode, perm->seq);
+ printf("\towner: uid=%d, gid=%d ;" ,perm->uid, perm->gid);
+ printf(" creator: uid=%d, gid=%d\n",perm->cuid,perm->cgid);
+}
+
+/* for debugging only */
+/* print_shm_info: print shared memory descriptor info */
+static void print_shm_info(int shm_id)
+{
+ struct shmid_ds ds;
+ shmctl(shm_id, IPC_STAT, &ds );
+
+ printf("shm_id=%d, Size=0x%08x , Number of attaches=%d\n",
+ shm_id, ds.shm_segsz, (int)ds.shm_nattch);
+ if (ds.shm_atime)
+ printf("Last attach=%s",ctime(&ds.shm_atime));
+ if (ds.shm_dtime)
+ printf("Last detach=%s",ctime(&ds.shm_dtime));
+ printf("Last change=%s",ctime(&ds.shm_ctime));
+ printf("pid: creator=%d, last operator=%d\n",
+ (int)ds.shm_cpid,(int)ds.shm_lpid);
+ print_perm( &ds.shm_perm);
+
+}
+
+int proc_exist(__pid_t pid)
+{
+ if ( kill(pid,0) == 0) /* dummy signal to test existence */
+ return 1;
+ else if (errno==ESRCH) /* "no such process" */
+ return 0;
+ else
+ return 1;
+}
+
+/* setup a new main shm block (only construct a shm block object). */
+static void shm_setup_main_block()
+{
+ dprintf_shm(stddeb,"creating data structure\n");
+ main_block->build_lock=1;
+ strcpy(main_block->magic, shm_header);
+
+ shm_setup_block(&main_block->block,sizeof(*main_block),SHM_MINBLOCK);
+
+ dde_proc_init(main_block->proc);
+ ATOM_GlobalInit();
+ shm_sem_init(&main_block->sem);
+
+ /* main block set and data structure is stable now */
+ main_block->build_lock=0;
+}
+
+/* Delete everything related to main_block */
+void shm_delete_all(int shmid)
+{
+ int proc_idx;
+
+ if (shmid == -1)
+ shmid= main_shm_id;
+
+ shmctl( shmid, IPC_RMID, NULL);
+
+ for (proc_idx= 0 ; proc_idx < DDE_PROCS ; proc_idx++)
+ dde_proc_done( &main_block->proc[proc_idx] );
+
+ shm_sem_done(&main_block->sem);
+ shmdt( (void *) main_block);
+ main_block= NULL;
+}
+
+int DDE_no_of_attached()
+{
+ struct shmid_ds shm_info;
+
+ if (shmctl(main_shm_id, IPC_STAT, &shm_info) == -1)
+ return -1;
+
+ return shm_info.shm_nattch;
+}
+/*
+** Test if shm_id is MainBlock and attach it (if it is),
+** Return 1 if ok, 0 otherwise.
+*/
+static int attach_MainBlock(int shm_id)
+{
+ struct shmid_ds shm_info;
+
+ if (shmctl(shm_id, IPC_STAT, &shm_info) == -1)
+ return 0;
+
+ /* Make sure we don't work on somebody else's block */
+ if (shm_info.shm_perm.cuid != getuid()) { /* creator is not me */
+ dprintf_shm(stddeb,"Creator is not me!\n");
+ return 0;
+ }
+
+ dprintf_shm(stddeb,"shared memory exist, attaching anywhere\n");
+ main_block=(struct shm_main_block *)shmat(shm_id, 0, 0);
+ if ( (int)main_block==-1) {
+ dprintf_shm(stddeb,"Attach failed\n");
+ return 0;
+ }
+
+ if (strcmp(main_block->magic, shm_header) != 0) {
+ dprintf_shm(stddeb,"Detaching, wrong magic\n");
+ shmdt((void *)main_block);
+ return 0;
+ }
+
+ if (debugging_shm)
+ print_shm_info(shm_id);
+
+ /* Is it an old unused block ? */
+ if (shm_info.shm_nattch == 0) {
+ dprintf_shm(stddeb,"No attaches, deleting old data\n");
+ shm_delete_all(shm_id);
+ return 0;
+ }
+
+ /* Wait for data structure to stabilize */
+ while (main_block->build_lock)
+ usleep(10000);
+
+ main_shm_id= shm_id;
+
+ shm_main_refresh();
+ return 1;
+}
+
+/* (Function used by the constructor)
+ * Try to get existing shared memory with key="Wine", size=SHM_MINBLOCK
+ * complete user permission.
+ * If such block is found - return true (1), else return false (0)
+ */
+static int shm_locate_MainBlock(key_t shm_key)
+{
+ int shm_id; /* Descriptor to this shared memory */
+ int i;
+
+ dprintf_shm(stddeb,"shm_locate_MainBlock: trying to attach, key=0x%x\n",
+ shm_key);
+ for (i=0 ; i < SHM_KEY_RANGE ; i++) {
+ dprintf_shm(stddeb,"iteration=%d\n", i);
+
+ shm_id= shmget ( shm_key+i, SHM_MINBLOCK ,0700);
+
+ if (shm_id != -1) {
+ if ( attach_MainBlock(shm_id) ) {
+ return 1; /* success! */
+ }
+ } else {
+ switch(errno) {
+ case EIDRM: /* segment destroyed */
+ case EACCES: /* no user permision */
+ break;
+
+ case ENOMEM: /* no free memory */
+ case ENOENT: /* this key does not exist */
+ default :
+ dprintf_shm(stddeb,"shmget failed, errno=%d, %s\n",
+ errno, strerror(errno) );
+ return 0; /* Failed */
+ }
+ } /* if .. else */
+ } /* for */
+ return 0;
+}
+
+/* (Function used by the constructor)
+ * Try to allocate new shared memory with key="Wine", size=SHM_MINBLOCK
+ * with complete user permission.
+ * If allocation succeeds - return true (1), else return false (0)
+ */
+static int shm_create_MainBlock(key_t MainShmKey)
+{
+ int shm_id;
+ int flags= 0700 | IPC_CREAT | IPC_EXCL;
+ int i;
+
+ dprintf_shm(stddeb,"creating shared memory\n");
+
+ /* try to allocate shared memory with key="Wine", size=SHM_MINBLOCK, */
+ /* complete user permission */
+ for (i=0 ; i < SHM_KEY_RANGE ; i++) {
+ shm_id= shmget ( (key_t) MainShmKey, SHM_MINBLOCK, flags);
+ if (shm_id != -1)
+ break;
+ }
+ if (shm_id == -1) {
+ dprintf_shm(stddeb,"failed to create shared memory\n");
+ return 0;
+ }
+ dprintf_shm(stddeb,"shared memory created, attaching\n");
+ main_block=(struct shm_main_block*) shmat(shm_id, 0,0);
+ if (debugging_shm)
+ print_shm_info(shm_id);
+ main_shm_id= shm_id;
+ shm_setup_main_block();
+ dde_wnd_setup();
+ return 1;
+
+}
+
+/* link to the dde shared memory block */
+/* RETURN: 0 on success, non zero on failure */
+int shm_init(void)
+{
+ if ( !shm_locate_MainBlock(WineKey)
+ && !shm_create_MainBlock(WineKey)) {
+ fflush(stdout);
+ fprintf(stderr,"shm_init: failed to init main shm block\n");
+ exit(1);
+ }
+
+ dde_proc_add(main_block->proc);
+ return 0;
+}
+
+static void shm_main_refresh()
+{
+ int proc_idx;
+
+ for (proc_idx= 0 ; proc_idx < DDE_PROCS ; proc_idx++)
+ dde_proc_refresh( &main_block->proc[proc_idx] );
+}
diff --git a/ipc/shm_semaph.c b/ipc/shm_semaph.c
new file mode 100644
index 0000000..c226808
--- /dev/null
+++ b/ipc/shm_semaph.c
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_semaph.c
+ * Purpose: Handle semaphores for shared memory operations.
+ ***************************************************************************
+ */
+#define inline __inline__
+#include <assert.h>
+#include <unistd.h>
+#include <sys/sem.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stddebug.h>
+#include <debug.h>
+#include "shm_semaph.h"
+#define SEM_READ 0
+#define SEM_WRITE 1
+
+/* IMPORTANT: Make sure that killed process will not lock everything.
+ * If possible, restrict usage of these functions.
+ */
+void shm_read_wait(shm_sem semid)
+{
+ struct sembuf sop[2];
+ int ret;
+
+ dprintf_sem(stddeb,"shm_read_wait(%d)\n",semid);
+ sop[0].sem_num=SEM_READ;
+ sop[0].sem_op=1; /* add this read instance */
+ sop[0].sem_flg=SEM_UNDO; /* undo in case process dies */
+
+ sop[1].sem_num=SEM_WRITE;
+ sop[1].sem_op=0; /* wait until no writing instance exists */
+ sop[1].sem_flg=SEM_UNDO;
+
+ do {
+ ret=semop (semid,sop , 2);
+ } while (ret<0 && errno==EINTR); /* interrupted system call? */
+
+ if (ret<0)
+ fprintf(stderr,"failed semaphore lock for read. semid=%d,errno=%d\n",
+ semid, errno);
+}
+void shm_write_wait(shm_sem semid)
+{
+ struct sembuf sop[3];
+ int ret;
+
+ dprintf_sem(stddeb,"shm_write_wait(%d)\n",semid);
+ sop[0].sem_num=SEM_READ;
+ sop[0].sem_op=0; /* wait until no reading instance exist */
+ sop[0].sem_flg=SEM_UNDO;
+
+ sop[1].sem_num=SEM_WRITE;
+ sop[1].sem_op=1; /* writing is in progress - disable read */
+ sop[1].sem_flg=SEM_UNDO; /* undo if process dies */
+
+ sop[2].sem_num=SEM_READ;
+ sop[2].sem_op=1; /* disable new writes */
+ sop[2].sem_flg=SEM_UNDO;
+
+ do {
+ ret=semop (semid,sop , 3);
+ } while (ret<0 && errno==EINTR); /* interrupted system call? */
+
+ if (ret<0) /* test for the error */
+ fprintf(stderr,"failed semaphore lock for write. semid=%d,errno=%d\n",
+ semid, errno);
+}
+void shm_write_signal(shm_sem semid)
+{
+ struct sembuf sop[2];
+ int ret;
+
+ dprintf_sem(stddeb,"shm_write_signal(%d)\n",semid);
+ sop[0].sem_num=SEM_READ;
+ sop[0].sem_op=-1;
+ sop[0].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
+
+ sop[1].sem_num=SEM_WRITE;
+ sop[1].sem_op=-1;
+ sop[1].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
+
+ do {
+ ret=semop (semid,sop , 2);
+ } while (ret<0 && errno==EINTR); /* interrupted system call? */
+
+ if (ret<0) /* test for the error */
+ fprintf(stderr,"failed semaphore unlock for write. semid=%d,errno=%d\n",
+ semid, errno);
+}
+
+void shm_read_signal(shm_sem semid)
+{
+ struct sembuf sop[2];
+ int ret;
+
+ dprintf_sem(stddeb,"shm_read_signal(%d)\n",semid);
+ sop[0].sem_num=SEM_READ;
+ sop[0].sem_op=-1;
+ sop[0].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
+
+ do {
+ ret=semop (semid,sop , 1);
+ } while (ret<0 && errno==EINTR); /* interrupted system call? */
+
+ if (ret<0) /* test for the error */
+ fprintf(stderr,"failed semaphore unlock for read. semid=%d,errno=%d\n",
+ semid, errno);
+}
+
+void shm_sem_init(shm_sem *sptr)
+{
+ shm_sem semid;
+ union semun arg;
+
+ semid=semget (IPC_PRIVATE, 2, 0700 | IPC_CREAT);
+
+ arg.val=0;
+ semctl (semid, 0, SETVAL, arg);
+ semctl (semid, 1, SETVAL, arg);
+ *sptr=semid;
+}
+
+void shm_sem_done(shm_sem *semptr)
+{
+ union semun arg;
+
+ semctl (*semptr, 0, IPC_RMID , arg);
+ semctl (*semptr, 1, IPC_RMID , arg);
+
+ *semptr= -1;
+}
diff --git a/ipc/shm_semaph_test.c b/ipc/shm_semaph_test.c
new file mode 100644
index 0000000..fdceeb5
--- /dev/null
+++ b/ipc/shm_semaph_test.c
@@ -0,0 +1,128 @@
+/***************************************************************************
+ * Copyright 1995, Technion, Israel Institute of Technology
+ * Electrical Eng, Software Lab.
+ * Author: Michael Veksler.
+ ***************************************************************************
+ * File: shm_semaph_test.c
+ * Purpose: Test semaphores handleingr shared memory operations.
+ ***************************************************************************
+ */
+#include <time.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include "shm_semaph.h"
+#include <sys/shm.h>
+#define DEBUG_DEFINE_VARIABLES
+#include <stddebug.h>
+#include <debug.h>
+
+static volatile int * volatile data;
+static int isparent=0;
+#define DELAY (rand()%10)
+shm_sem sem;
+
+static void read_write(int num)
+{
+ int i,j ;
+ volatile float dummy=0;
+ int val;
+
+ srand(num+time(NULL));
+ for (i=0x3fff;i>=0;i--) {
+ if((i&0x7ff)==0 && isparent)
+ fprintf(stderr,"0x%06x\r",i);
+ shm_write_wait(sem);
+ *data= num;
+ for (j=DELAY ; j>=0;j--)
+ dummy*=2;
+ if (*data!=num) {
+ fprintf(stderr,"\nbad shm_write_wait(), num=%d\n",num);
+ shm_write_signal(sem);
+ return;
+ }
+ shm_write_signal(sem);
+ for (j=DELAY ; j>=0 ;j--)
+ dummy*=2;
+ shm_read_wait(sem);
+ val=*data;
+ for (j=DELAY; j>=0 ;j--)
+ dummy*=0.5;
+ if (*data!=val) {
+ fprintf(stderr,"\nbad shm_read_wait(), num=%d,val=%d,*data=%d\n",
+ num,val,*data);
+ shm_read_signal(sem);
+ return;
+ }
+ shm_read_signal(sem);
+ }
+ if (isparent)
+ fputc('\n',stderr);
+}
+static void child1()
+{
+ read_write(2);
+}
+static void child2()
+{
+ read_write(10);
+}
+static void parent()
+{
+ isparent=1;
+ read_write(60);
+}
+
+int main()
+{
+ int shmid;
+ int ret1, ret2;
+ int pid1, pid2;
+ int stat=0;
+
+ shm_sem_init(&sem);
+ shmid=shmget(IPC_PRIVATE, 0x100, IPC_CREAT | 0700);
+ data= (int *)shmat ( shmid, NULL, 0);
+ *data=0;
+
+ switch (pid1=fork()) {
+ case -1:
+ perror("fork 1");
+ return 1;
+ case 0:
+ fprintf(stderr,"child1\n");
+ child1();
+ fprintf(stderr,"child1 done\n");
+ return 0;
+ default :
+ }
+ switch (pid2=fork()) {
+ case -1:
+ perror("fork 2");
+ stat|=1;
+ break;
+ case 0:
+ fprintf(stderr,"child2\n");
+ child2();
+ fprintf(stderr,"child2 done\n");
+ return 0;
+ default :
+ }
+ fprintf(stderr,"parent\n");
+ if (pid2>0) { /* if second fork did not fail */
+ parent();
+ fprintf(stderr,"parent done, waiting for child2\n");
+ waitpid(pid2,&ret2,WUNTRACED);
+ stat|=ret2;
+ }
+ fprintf(stderr,"parent done, waiting for child1\n");
+ waitpid(pid1,&ret1,WUNTRACED);
+ stat|=ret1;
+ fprintf(stderr,"all done\n");
+
+ shmctl(shmid, IPC_RMID,NULL);
+ shm_sem_done(&sem);
+ return stat;
+}
diff --git a/ipc/wine_test_stub.c b/ipc/wine_test_stub.c
new file mode 100644
index 0000000..fb1747e
--- /dev/null
+++ b/ipc/wine_test_stub.c
@@ -0,0 +1,117 @@
+#include <stdlib.h>
+#include "dde.h"
+#include <wintypes.h>
+#include "global.h"
+#include <win.h>
+#define DEBUG_DEFINE_VARIABLES
+#define DEBUG_ALL
+#include <stddebug.h>
+#include <debug.h>
+
+#define DDE_PROC2WIN(proc_idx) ( (HWND) ~( (proc_idx)+1) )
+#define DDE_WIN2PROC(win) ( (int) ~(short) ((win)+1) )
+#define DDE_IsRemoteWindow(win) ( (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
+
+
+char *MessageTypeNames[0x400]={NULL};
+char *dummy_store_for_debug_msg_name;
+
+ldt_copy_entry ldt_copy[LDT_SIZE];
+
+int LDT_GetEntry( int entry, ldt_entry *content )
+{
+ return 0;
+}
+
+int LDT_SetEntry( int entry, ldt_entry *content )
+{
+ return 0;
+}
+
+void dummy_usage_of_debug_msg_name()
+{
+ dummy_store_for_debug_msg_name=debug_msg_name[0];
+}
+
+/* stub */
+HWND GetDesktopWindow()
+{
+ printf("GetDesktopWindow\n");
+ return 0;
+}
+/* stub */
+/* smart stub */
+LONG SendMessage(HWND a,WORD b,WORD c,LONG d)
+{
+ MSG msg;
+ printf("SendMessage(%04x,%04x,%04x,%04lx)\n",a,b,c,d);
+ if (DDE_IsRemoteWindow(a) || a==(HWND)-1)
+ return 0;
+ if (b!=WM_DDE_INITIATE)
+ return 0;
+ msg.hwnd=c;
+ msg.message= WM_DDE_ACK;
+ msg.lParam= 0;
+ msg.wParam= 0;
+ return DDE_SendMessage(&msg);
+}
+/* stub */
+BOOL PostMessage(HWND a,WORD b,WORD c,LONG d)
+{
+ printf("PostMessage(%04x,%04x,%04x,%04lx)\n",a,b,c,d);
+ return 0;
+}
+/* stub */
+HWND GetTopWindow(HWND a)
+{
+ printf("GetTopWindow(%04x)\n",a);
+ return 1;
+}
+/* stub */
+WORD FreeSelector(WORD a)
+{
+ printf("FreeSelector(%04x)\n",a);
+ return 0;
+}
+
+/* stub that partially emulates the true GLOBAL_CreateBlock function */
+HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
+ HGLOBAL hOwner, BOOL isCode,
+ BOOL is32Bit, BOOL isReadOnly,
+ SHMDATA *shmdata )
+{
+
+ printf("GLOBAL_CreateBlock(flags=0x%x,ptr=0x%08lx, size=0x%x,hOwner=0x%x\n",
+ (int)flags, (long)ptr, (int)size, (int)hOwner);
+ printf("isCode=%d, is32Bit=%d, isReadOnly=%d, \n", isCode, is32Bit,
+ isReadOnly);
+ printf("*shmdata={handle=0x%x,sel=0x%x, shmid=%d})\n",
+ shmdata->handle, shmdata->sel, shmdata->shmid);
+ return 1;
+}
+
+/* stub */
+WND *WIN_FindWndPtr(HWND hwnd)
+{
+ static WND win;
+ printf("WIN_FindWndPtr(%d)\n",hwnd);
+ if (hwnd==0)
+ return NULL;
+ win.hwndNext=0;
+ win.dwStyle=WS_POPUP;
+
+ return &win;
+}
+
+/* stub */
+WORD GetCurrentPDB(void)
+{
+ printf("GetCurrentPDB()\n");
+
+ return 0;
+}
+
+/* stub */
+void Yield(void)
+{
+}
diff --git a/loader/Imakefile b/loader/Imakefile
index befe47a..3ec199f 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -3,7 +3,6 @@
MODULE = loader
SRCS = \
- dump.c \
main.c \
module.c \
ne_image.c \
diff --git a/loader/Makefile.in b/loader/Makefile.in
new file mode 100644
index 0000000..b9cd285
--- /dev/null
+++ b/loader/Makefile.in
@@ -0,0 +1,50 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = loader
+
+SRCS = main.c module.c ne_image.c ne_resource.c pe_image.c \
+ pe_resource.c selector.c signal.c resource.c task.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/loader/dump.c b/loader/dump.c
deleted file mode 100644
index 39344e5..0000000
--- a/loader/dump.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef WINELIB
-/*
-static char RCSId[] = "$Id: dump.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#ifdef linux
-#include <linux/unistd.h>
-#include <linux/head.h>
-#include <linux/ldt.h>
-#endif
-#include <errno.h>
-#include "neexe.h"
-#include "prototypes.h"
-
-/**********************************************************************
- * PrintFileHeader
- */
-void
-PrintFileHeader(struct ne_header_s *ne_header)
-{
- printf("ne_header: %c%c\n",
- ne_header->ne_magic & 0xff,
- ne_header->ne_magic >> 8 );
- printf("linker version: %d.%d\n", ne_header->linker_version,
- ne_header->linker_revision);
- printf("format flags: %04x\n", ne_header->format_flags);
- printf("automatic data segment: %04x\n", ne_header->auto_data_seg);
- printf("CS:IP %04x:%04x\n", ne_header->cs, ne_header->ip);
- printf("SS:SP %04x:%04x\n", ne_header->ss, ne_header->sp);
- printf("additional flags: %02x\n", ne_header->additional_flags);
- printf("operating system: %02x\n", ne_header->operating_system);
- printf("fast load offset: %04x\n", ne_header->fastload_offset);
- printf("fast load length: %04x\n", ne_header->fastload_length);
-}
-
-/**********************************************************************
- * PrintRelocationTable
- */
-void
-PrintRelocationTable(char *exe_ptr,
- struct ne_segment_table_entry_s *seg_entry_p,
- int segment)
-{
- struct relocation_entry_s *rep;
- int i;
- int offset;
- u_short n_entries, *sp;
-
- printf("RELOCATION TABLE %d:\n", segment + 1);
-
- if (seg_entry_p->seg_data_offset == 0)
- return;
-
- offset = seg_entry_p->seg_data_length;
- if (offset == 0)
- offset = 0x10000;
-
- sp = (u_short *) (exe_ptr + seg_entry_p->seg_data_offset * 512 + offset);
- n_entries = *sp;
-
- rep = (struct relocation_entry_s *) (sp + 1);
- for (i = 0; i < n_entries; i++, rep++)
- {
- printf(" ADDR TYPE %d, TYPE %d, OFFSET %04x,",
- rep->address_type, rep->relocation_type, rep->offset);
- printf("TARGET %04x %04x\n", rep->target1, rep->target2);
- }
-}
-#endif /* ifndef WINELIB */
diff --git a/loader/main.c b/loader/main.c
index 7a2d435..0e301df 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -11,6 +11,18 @@
#include <string.h>
#include <errno.h>
#include "windows.h"
+#include "module.h"
+#include "task.h"
+#include "selectors.h"
+#include "comm.h"
+#include "user.h"
+#include "menu.h"
+#include "atom.h"
+#include "dialog.h"
+#include "message.h"
+#include "syscolor.h"
+#include "sysmetrics.h"
+#include "gdi.h"
#include "debugger.h"
#include "dos_fs.h"
#include "dlls.h"
@@ -18,6 +30,7 @@
#include "neexe.h"
#include "options.h"
#include "task.h"
+#include "dce.h"
#include "pe_image.h"
#include "stddebug.h"
#include "debug.h"
@@ -29,6 +42,7 @@
int MAIN_Init(void)
{
extern BOOL RELAY_Init(void);
+ extern BOOL RELAY32_Init(void);
int queueSize;
@@ -103,14 +117,22 @@
int _WinMain(int argc, char **argv)
{
int i;
+ HANDLE handle;
if (!MAIN_Init()) return 0;
for (i = 1; i < argc; i++)
{
- if (WinExec( argv[i], SW_SHOWNORMAL ) < 32)
+ if ((handle = WinExec( argv[i], SW_SHOWNORMAL )) < 32)
{
- fprintf(stderr, "wine: can't exec '%s'.\n", argv[i]);
+ fprintf(stderr, "wine: can't exec '%s': ", argv[i]);
+ switch (handle)
+ {
+ case 2: fprintf( stderr, "file not found\n" ); break;
+ case 11: fprintf( stderr, "invalid exe file\n" ); break;
+ case 21: fprintf( stderr, "win32 executable\n" ); break;
+ default: fprintf( stderr, "error=%d\n", handle ); break;
+ }
exit(1);
}
}
diff --git a/loader/module.c b/loader/module.c
index 01d2678..12cf6ba 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -21,7 +21,6 @@
#include "task.h"
#include "toolhelp.h"
#include "stddebug.h"
-/* #define DEBUG_MODULE */
#include "debug.h"
@@ -53,7 +52,7 @@
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->module_start,
table->module_end - table->module_start,
- 0, FALSE, FALSE, FALSE );
+ 0, FALSE, FALSE, FALSE, NULL );
if (!hModule) return FALSE;
FarSetOwner( hModule, hModule );
@@ -69,7 +68,7 @@
pSegTable->selector = GLOBAL_CreateBlock(GMEM_FIXED, table->code_start,
pSegTable->minsize, hModule,
- TRUE, TRUE, FALSE );
+ TRUE, TRUE, FALSE, NULL );
if (!pSegTable->selector) return FALSE;
pSegTable++;
@@ -99,35 +98,34 @@
MODULE_SetEntryPoint( hModule, 183, /* KERNEL.183: __0000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 193, /* KERNEL.193: __0040H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400,
- 0x100, hModule, FALSE, FALSE, FALSE ) );
+ 0x100, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 174, /* KERNEL.174: __A000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 181, /* KERNEL.181: __B000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 182, /* KERNEL.182: __B800H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 195, /* KERNEL.195: __C000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 179, /* KERNEL.179: __D000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 190, /* KERNEL.190: __E000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 173, /* KERNEL.173: __ROMBIOS */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 194, /* KERNEL.194: __F000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
- 0x10000, hModule, FALSE, FALSE, FALSE ) );
-
+ 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
return TRUE;
}
@@ -304,15 +302,8 @@
{
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
if (i == pModule->ss) minsize += pModule->stack_size;
- if (i == pModule->dgroup)
- {
-#if 0
- /* FIXME: this is needed because heap growing is not implemented */
- pModule->heap_size = 0x10000 - minsize;
-#endif
- /* The DGROUP is allocated by MODULE_CreateInstance */
- continue;
- }
+ /* The DGROUP is allocated by MODULE_CreateInstance */
+ if (i == pModule->dgroup) continue;
pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
minsize, hModule,
!(pSegment->flags & NE_SEGFLAGS_DATA),
@@ -1013,6 +1004,12 @@
/**********************************************************************
* GetModuleHandle (KERNEL.47)
*/
+HMODULE WIN16_GetModuleHandle( SEGPTR name )
+{
+ if (HIWORD(name) == 0) return GetExePtr( LOWORD(name) );
+ return MODULE_FindModule( PTR_SEG_TO_LIN(name) );
+}
+
HMODULE GetModuleHandle( LPCSTR name )
{
return MODULE_FindModule( name );
diff --git a/loader/pe_image.c b/loader/pe_image.c
index ee1b119..2d284b5 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -197,7 +197,7 @@
wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
}
if(result==-1){
- fprintf(stderr,"Could not load section %x to desired address %x\n",
+ fprintf(stderr,"Could not load section %x to desired address %lx\n",
i, load_addr+wpnt->pe->pe_seg[i].Virtual_Address);
fprintf(stderr,"Need to implement relocations now\n");
exit(0);
diff --git a/loader/resource.c b/loader/resource.c
index 4cf44cf..4e6bbfc 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -32,6 +32,16 @@
else \
dprintf_resource( stddeb, "#%04x", LOWORD(name));
+
+/**********************************************************************
+ * LoadIconHandler (USER.456)
+ */
+HICON LoadIconHandler( HANDLE hResource, BOOL bNew )
+{
+ return 0;
+}
+
+
/**********************************************************************
* FindResource (KERNEL.60)
*/
diff --git a/loader/selector.c b/loader/selector.c
index d04e4f1..ab211bd 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -8,33 +8,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <unistd.h>
#ifndef WINELIB
-#ifdef __linux__
-#include <sys/mman.h>
-#include <linux/unistd.h>
-#include <linux/head.h>
-#include <linux/mman.h>
-#include <linux/a.out.h>
-#include <linux/ldt.h>
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#include <sys/mman.h>
-#include <machine/segments.h>
-#endif
-
#include "windows.h"
-#include "ldt.h"
-#include "wine.h"
#include "global.h"
-#include "dlls.h"
-#include "neexe.h"
-#include "prototypes.h"
#include "module.h"
#include "stddebug.h"
/* #define DEBUG_SELECTORS */
diff --git a/loader/signal.c b/loader/signal.c
index e7c8381..4ede072 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -15,7 +15,6 @@
#endif
#include "debugger.h"
-#include "prototypes.h"
#include "miscemu.h"
#include "registers.h"
#include "win.h"
@@ -24,6 +23,7 @@
char * cstack[4096];
#endif
struct sigaction segv_act;
+struct sigaction usr2_act;
#ifdef linux
extern void ___sig_restore();
@@ -71,15 +71,21 @@
void init_wine_signals(void)
{
+ extern void stop_wait(int a);
#ifdef linux
segv_act.sa_handler = (__sighandler_t) win_fault;
/* Point to the top of the stack, minus 4 just in case, and make
it aligned */
segv_act.sa_restorer =
- (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
+ (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
+ usr2_act.sa_restorer= segv_act.sa_restorer;
+ usr2_act.sa_handler = (__sighandler_t) stop_wait;
+ /* Point to the top of the stack, minus 4 just in case, and make
+ it aligned */
wine_sigaction(SIGSEGV, &segv_act, NULL);
wine_sigaction(SIGILL, &segv_act, NULL);
wine_sigaction(SIGFPE, &segv_act, NULL);
+ wine_sigaction(SIGUSR2, &usr2_act, NULL);
#ifdef SIGBUS
wine_sigaction(SIGBUS, &segv_act, NULL);
#endif
@@ -126,6 +132,13 @@
perror("sigaction: SIGTRAP");
exit(1);
}
+ usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
+ usr2_act.sa_flags = SA_ONSTACK;
+ usr2_act.sa_mask = sig_mask;
+ if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
+ perror("sigaction: SIGUSR2");
+ exit(1);
+ }
#endif
}
diff --git a/loader/task.c b/loader/task.c
index 222bd01..53d1006 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -21,6 +21,7 @@
#include "toolhelp.h"
#include "stddebug.h"
#include "debug.h"
+#include "dde_proc.h"
/* Min. number of thunks allocated when creating a new segment */
#define MIN_THUNKS 32
@@ -247,7 +248,8 @@
STACK16FRAME *frame16;
STACK32FRAME *frame32;
extern DWORD CALL16_RetAddr_word;
-
+ char filename[256];
+
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
pSegTable = NE_SEG_TABLE( pModule );
@@ -258,6 +260,12 @@
if (!hTask) return 0;
pTask = (TDB *)GlobalLock( hTask );
+ /* get current directory */
+
+ GetModuleFileName( hModule, filename, sizeof(filename) );
+ name = strrchr(filename, '\\');
+ if (name) *(name+1) = 0;
+
/* Fill the task structure */
pTask->nEvents = 1; /* So the task can be started */
@@ -268,10 +276,10 @@
pTask->hPrevInstance = hPrevInstance;
pTask->hModule = hModule;
pTask->hParent = hCurrentTask;
- pTask->curdrive = 'C' - 'A' + 0x80;
+ pTask->curdrive = filename[0] - 'A' + 0x80;
pTask->magic = TDB_MAGIC;
pTask->nCmdShow = cmdShow;
- strcpy( pTask->curdir, "WINDOWS" );
+ strcpy( pTask->curdir, filename+2 );
/* Create the thunks block */
@@ -302,13 +310,13 @@
/* Allocate a selector for the PDB */
pTask->hPDB = GLOBAL_CreateBlock( GMEM_FIXED, &pTask->pdb, sizeof(PDB),
- hModule, FALSE, FALSE, FALSE );
+ hModule, FALSE, FALSE, FALSE, NULL );
/* Allocate a code segment alias for the TDB */
pTask->hCSAlias = GLOBAL_CreateBlock( GMEM_FIXED, (void *)pTask,
sizeof(TDB), pTask->hPDB, TRUE,
- FALSE, FALSE );
+ FALSE, FALSE, NULL );
/* Set the owner of the environment block */
@@ -326,6 +334,7 @@
/* Create the 32-bit stack frame */
+ *(DWORD *)GlobalLock(pTask->hStack32) = 0xDEADBEEF;
stack32Top = (char*)GlobalLock(pTask->hStack32) + STACK32_SIZE;
frame32 = (STACK32FRAME *)stack32Top - 1;
frame32->saved_esp = (DWORD)stack32Top;
@@ -342,13 +351,13 @@
/* Create the 16-bit stack frame */
pTask->ss = hInstance;
- pTask->sp = (pModule->sp != 0) ? pModule->sp :
- pSegTable[pModule->ss-1].minsize + pModule->stack_size;
+ pTask->sp = ((pModule->sp != 0) ? pModule->sp :
+ pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1;
stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp );
frame16 = (STACK16FRAME *)stack16Top - 1;
frame16->saved_ss = pTask->ss;
frame16->saved_sp = pTask->sp;
- frame16->ds = pTask->hInstance;
+ frame16->ds = frame16->es = pTask->hInstance;
frame16->entry_point = 0;
frame16->ordinal_number = 24; /* WINPROCS.24 is TASK_Reschedule */
frame16->dll_id = 24; /* WINPROCS */
@@ -461,6 +470,7 @@
TDB *pOldTask = NULL, *pNewTask;
HTASK hTask = 0;
+ dde_reschedule();
/* First check if there's a task to kill */
if (hTaskToKill && (hTaskToKill != hCurrentTask))
diff --git a/memory/Makefile.in b/memory/Makefile.in
new file mode 100644
index 0000000..80be79a
--- /dev/null
+++ b/memory/Makefile.in
@@ -0,0 +1,49 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = memory
+
+SRCS = selector.c global.c ldt.c local.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/memory/global.c b/memory/global.c
index c1f5ab9..83c3213 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -6,10 +6,12 @@
#include <stdlib.h>
#include <string.h>
+
#include "windows.h"
#include "global.h"
#include "toolhelp.h"
#include "selectors.h"
+#include "dde_mem.h"
#include "stackframe.h"
#include "stddebug.h"
#include "debug.h"
@@ -25,12 +27,14 @@
BYTE pageLockCount; /* Count of GlobalPageLock() calls */
BYTE flags; /* Allocation flags */
BYTE selCount; /* Number of selectors allocated for this block */
+ int shmid;
} GLOBALARENA;
/* Flags definitions */
#define GA_MOVEABLE 0x02 /* same as GMEM_MOVEABLE */
#define GA_DGROUP 0x04
#define GA_DISCARDABLE 0x08
+#define GA_IPCSHARE 0x10 /* same as GMEM_DDESHARE */
/* Arena array */
static GLOBALARENA *pGlobalArena = NULL;
@@ -62,6 +66,36 @@
}
+void debug_handles()
+{
+ int printed=0;
+ int i;
+ for (i = globalArenaSize-1 ; i>=0 ; i--) {
+ if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
+ printed=1;
+ printf("0x%08x, ",pGlobalArena[i].handle);
+ }
+ }
+ if (printed)
+ printf("\n");
+}
+/***********************************************************************
+ * GLOBAL_FindArena
+ *
+ * Find the arena for a given handle
+ * (when handle is not serial - e.g. DDE)
+ */
+static GLOBALARENA *GLOBAL_FindArena( HGLOBAL handle)
+{
+ int i;
+ for (i = globalArenaSize-1 ; i>=0 ; i--) {
+ if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
+ return ( &pGlobalArena[i] );
+ }
+ return NULL;
+}
+
+
/***********************************************************************
* GLOBAL_CreateBlock
*
@@ -69,15 +103,18 @@
*/
HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
HGLOBAL hOwner, BOOL isCode,
- BOOL is32Bit, BOOL isReadOnly )
+ BOOL is32Bit, BOOL isReadOnly,
+ SHMDATA *shmdata )
{
WORD sel, selcount;
GLOBALARENA *pArena;
/* Allocate the selector(s) */
- sel = SELECTOR_AllocBlock( ptr, size, isCode ? SEGMENT_CODE : SEGMENT_DATA,
- is32Bit, isReadOnly );
+ sel = SELECTOR_AllocBlock( ptr, size,
+ isCode ? SEGMENT_CODE : SEGMENT_DATA,
+ is32Bit, isReadOnly );
+
if (!sel) return 0;
selcount = (size + 0xffff) / 0x10000;
@@ -91,12 +128,23 @@
pArena->base = (DWORD)ptr;
pArena->size = GET_SEL_LIMIT(sel) + 1;
- pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
+ if (flags & GMEM_DDESHARE)
+ {
+ pArena->handle = shmdata->handle;
+ pArena->shmid = shmdata->shmid;
+ shmdata->sel = sel;
+ }
+ else
+ {
+ pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
+ pArena->shmid = 0;
+ }
pArena->hOwner = hOwner;
pArena->lockCount = 0;
pArena->pageLockCount = 0;
pArena->flags = flags & GA_MOVEABLE;
if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
+ if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
if (!isCode) pArena->flags |= GA_DGROUP;
pArena->selCount = selcount;
if (selcount > 1) /* clear the next arena blocks */
@@ -119,7 +167,7 @@
if (!handle) return TRUE;
sel = GlobalHandleToSel( handle );
if (FreeSelector( sel )) return FALSE; /* failed */
- memset( GET_ARENA_PTR(handle), 0, sizeof(GLOBALARENA) );
+ memset( GET_ARENA_PTR(sel), 0, sizeof(GLOBALARENA) );
return TRUE;
}
@@ -134,6 +182,7 @@
{
void *ptr;
HGLOBAL handle;
+ SHMDATA shmdata;
dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags );
@@ -145,13 +194,16 @@
/* Allocate the linear memory */
- ptr = malloc( size );
+ if (flags & GMEM_DDESHARE)
+ ptr= DDE_malloc(flags, size, &shmdata);
+ else
+ ptr = malloc( size );
if (!ptr) return 0;
/* Allocate the selector(s) */
handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
- isCode, is32Bit, isReadOnly);
+ isCode, is32Bit, isReadOnly, &shmdata);
if (!handle)
{
free( ptr );
@@ -162,6 +214,29 @@
return handle;
}
+/***********************************************************************
+ * DDE_GlobalHandleToSel
+ */
+
+WORD DDE_GlobalHandleToSel( HGLOBAL handle )
+{
+ GLOBALARENA *pArena;
+ SEGPTR segptr;
+
+ pArena= GLOBAL_FindArena(handle);
+ if (pArena) {
+ int ArenaIdx = pArena - pGlobalArena;
+
+ /* See if synchronized to the shared memory */
+ return DDE_SyncHandle(handle, ( ArenaIdx << __AHSHIFT) | 7);
+ }
+
+ /* attach the block */
+ DDE_AttachHandle(handle, &segptr);
+
+ return SELECTOROF( segptr );
+}
+
/***********************************************************************
* GlobalAlloc (KERNEL.15)
@@ -172,7 +247,6 @@
if (flags & GMEM_DDESHARE)
owner = GetExePtr(owner); /* Make it a module handle */
-
return GLOBAL_Alloc( flags, size, owner, FALSE, FALSE, FALSE );
}
@@ -182,14 +256,22 @@
*/
HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
{
- WORD sel, selcount;
+ WORD selcount;
DWORD oldsize;
void *ptr;
GLOBALARENA *pArena, *pNewArena;
+ WORD sel = GlobalHandleToSel( handle );
dprintf_global( stddeb, "GlobalReAlloc: %04x %ld flags=%04x\n",
handle, size, flags );
if (!handle) return 0;
+
+ if (flags & GMEM_DDESHARE || is_dde_handle(handle)) {
+ fprintf(stdnimp,
+ "GlobalReAlloc: shared memory reallocating unimplemented\n");
+ return 0;
+ }
+
pArena = GET_ARENA_PTR( handle );
/* Discard the block if requested */
@@ -201,6 +283,10 @@
(pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
free( (void *)pArena->base );
pArena->base = 0;
+ /* Note: we rely on the fact that SELECTOR_ReallocBlock won't */
+ /* change the selector if we are shrinking the block */
+ SELECTOR_ReallocBlock( sel, 0, 1, SEGMENT_DATA, 0, 0 );
+ return handle;
}
/* Fixup the size */
@@ -221,7 +307,6 @@
/* Reallocate the linear memory */
- sel = GlobalHandleToSel( handle );
ptr = (void *)pArena->base;
oldsize = pArena->size;
dprintf_global(stddeb,"oldsize %08lx\n",oldsize);
@@ -275,12 +360,12 @@
*/
HGLOBAL GlobalFree( HGLOBAL handle )
{
- void *ptr;
+ void *ptr = GlobalLock( handle );
dprintf_global( stddeb, "GlobalFree: %04x\n", handle );
- if (!(ptr = GlobalLock( handle ))) return handle; /* failed */
if (!GLOBAL_FreeBlock( handle )) return handle; /* failed */
- free( ptr );
+ if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
+ if (ptr) free( ptr );
return 0;
}
@@ -295,7 +380,9 @@
dprintf_global( stddeb, "WIN16_GlobalLock(%04x) -> %08lx\n",
handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
if (!handle) return 0;
- if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
+ if ( !is_dde_handle(handle) && !GET_ARENA_PTR(handle)->base)
+ return (SEGPTR)0;
+
return (SEGPTR)MAKELONG( 0, GlobalHandleToSel(handle) );
}
@@ -308,6 +395,9 @@
LPSTR GlobalLock( HGLOBAL handle )
{
if (!handle) return 0;
+ if (is_dde_handle(handle)) {
+ return DDE_AttachHandle(handle, NULL);
+ }
return (LPSTR)GET_ARENA_PTR(handle)->base;
}
@@ -552,6 +642,9 @@
{
dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
if (!handle) return 0;
+ if (is_dde_handle(handle))
+ return DDE_GlobalHandleToSel(handle);
+
if (!(handle & 7))
{
fprintf( stderr, "Program attempted invalid selector conversion\n" );
diff --git a/memory/ldt.c b/memory/ldt.c
index f80b2cc..2b07893 100644
--- a/memory/ldt.c
+++ b/memory/ldt.c
@@ -157,7 +157,8 @@
ldt_flags_copy[entry] = (content->type & LDT_FLAGS_TYPE) |
(content->read_only ? LDT_FLAGS_READONLY : 0) |
(content->seg_32bit ? LDT_FLAGS_32BIT : 0) |
- (content->limit_in_pages ? LDT_FLAGS_BIG : 0);
+ (content->limit_in_pages ? LDT_FLAGS_BIG : 0) |
+ (ldt_flags_copy[entry] & LDT_FLAGS_ALLOCATED);
return ret;
}
diff --git a/memory/selector.c b/memory/selector.c
index 57afc7f..1959c71 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -8,6 +8,7 @@
#include "windows.h"
#include "ldt.h"
#include "selectors.h"
+#include "stackframe.h"
#include "stddebug.h"
#include "debug.h"
@@ -29,7 +30,9 @@
else if (++size >= count) break;
}
if (i == LDT_SIZE) return 0;
- return ENTRY_TO_SELECTOR( i - size + 1 );
+ /* Mark selector as allocated */
+ while (size--) ldt_flags_copy[i--] |= LDT_FLAGS_ALLOCATED;
+ return ENTRY_TO_SELECTOR( i + 1 );
}
@@ -68,8 +71,22 @@
if (IS_SELECTOR_FREE(sel)) return sel; /* error */
count = (GET_SEL_LIMIT(sel) >> 16) + 1;
memset( &entry, 0, sizeof(entry) ); /* clear the LDT entries */
- for (i = 0; i < count; i++)
- LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+ /* FIXME: is it correct to free the whole array? */
+ for (i = SELECTOR_TO_ENTRY(sel); count; i++, count--)
+ {
+ LDT_SetEntry( i, &entry );
+ ldt_flags_copy[i] &= ~LDT_FLAGS_ALLOCATED;
+ }
+
+ /* Clear the saved 16-bit selector */
+#ifndef WINELIB
+ if (CURRENT_STACK16)
+ {
+ /* FIXME: maybe we ought to walk up the stack and fix all frames */
+ if (CURRENT_STACK16->ds == sel) CURRENT_STACK16->ds = 0;
+ if (CURRENT_STACK16->es == sel) CURRENT_STACK16->es = 0;
+ }
+#endif
return 0;
}
@@ -108,38 +125,6 @@
/***********************************************************************
- * SELECTOR_ReallocArray
- *
- * Change the size of an allocated selector array.
- */
-static WORD SELECTOR_ReallocArray( WORD sel, WORD newcount )
-{
- WORD i, oldcount;
- ldt_entry entry;
-
- oldcount = (GET_SEL_LIMIT(sel) >> 16) + 1;
- if (oldcount < newcount) /* We need to add selectors */
- {
- /* Check if the next selectors are free */
- for (i = oldcount; i < newcount; i++)
- if (!IS_SELECTOR_FREE(sel+i)) break;
- if (i < newcount)
- {
- FreeSelector( sel );
- sel = AllocSelectorArray( newcount );
- }
- }
- else if (oldcount > newcount) /* We need to remove selectors */
- {
- memset( &entry, 0, sizeof(entry) ); /* clear the LDT entries */
- for (i = oldcount; i < newcount; i++)
- LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
- }
- return sel;
-}
-
-
-/***********************************************************************
* SELECTOR_AllocBlock
*
* Allocate selectors for a block of linear memory.
@@ -165,15 +150,41 @@
WORD SELECTOR_ReallocBlock( WORD sel, void *base, DWORD size,
enum seg_type type, BOOL is32bit, BOOL readonly )
{
- WORD count;
+ WORD i, oldcount, newcount;
+ ldt_entry entry;
- if (!size)
+ if (!size) size = 1;
+ oldcount = (GET_SEL_LIMIT(sel) >> 16) + 1;
+ newcount = (size + 0xffff) >> 16;
+
+ if (oldcount < newcount) /* We need to add selectors */
{
- FreeSelector( sel );
- return 0;
+ /* Check if the next selectors are free */
+ if (SELECTOR_TO_ENTRY(sel) + newcount > LDT_SIZE) i = oldcount;
+ else
+ for (i = oldcount; i < newcount; i++)
+ if (!IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)+i)) break;
+
+ if (i < newcount) /* they are not free */
+ {
+ FreeSelector( sel );
+ sel = AllocSelectorArray( newcount );
+ }
+ else /* mark the selectors as allocated */
+ {
+ for (i = oldcount; i < newcount; i++)
+ ldt_flags_copy[SELECTOR_TO_ENTRY(sel)+i] |=LDT_FLAGS_ALLOCATED;
+ }
}
- count = (size + 0xffff) / 0x10000;
- sel = SELECTOR_ReallocArray( sel, count );
+ else if (oldcount > newcount) /* We need to remove selectors */
+ {
+ memset( &entry, 0, sizeof(entry) ); /* clear the LDT entries */
+ for (i = oldcount; i < newcount; i++)
+ {
+ LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+ ldt_flags_copy[SELECTOR_TO_ENTRY(sel) + i] &= ~LDT_FLAGS_ALLOCATED;
+ }
+ }
if (sel) SELECTOR_SetEntries( sel, base, size, type, is32bit, readonly );
return sel;
}
diff --git a/misc/Makefile.in b/misc/Makefile.in
new file mode 100644
index 0000000..84afd90
--- /dev/null
+++ b/misc/Makefile.in
@@ -0,0 +1,59 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include -I$(TOPSRC)
+LD = @LD@
+LANG = @LANG@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+@SET_MAKE@
+
+
+MODULE = misc
+
+SRCS = atom.c clipboard.c comm.c commdlg.c compobj.c dos_fs.c \
+ driver.c exec.c escape.c file.c keyboard.c kernel32.c lstr.c \
+ main.c ole2.c ole2disp.c ole2nls.c olecli.c olesvr.c network.c \
+ profile.c rect.c shell.c sound.c spy.c stress.c user.c \
+ winsocket.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) $(LANG) -o $*.o $<
+
+all: checkrc $(MODULE).o
+
+checkrc:
+ (cd $(TOPSRC)/rc; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+ rm -f ole2nls.o shell.o commdlg.o
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/misc/atom.c b/misc/atom.c
index a34e062..f3286cd 100644
--- a/misc/atom.c
+++ b/misc/atom.c
@@ -329,36 +329,36 @@
/***********************************************************************
- * GlobalAddAtom (USER.268)
+ * LocalAddAtom (USER.268)
*/
-ATOM GlobalAddAtom( LPCSTR str )
+ATOM LocalAddAtom( LPCSTR str )
{
return ATOM_AddAtom( USER_HeapSel, str );
}
/***********************************************************************
- * GlobalDeleteAtom (USER.269)
+ * LocalDeleteAtom (USER.269)
*/
-ATOM GlobalDeleteAtom( ATOM atom )
+ATOM LocalDeleteAtom( ATOM atom )
{
return ATOM_DeleteAtom( USER_HeapSel, atom );
}
/***********************************************************************
- * GlobalFindAtom (USER.270)
+ * LocalFindAtom (USER.270)
*/
-ATOM GlobalFindAtom( LPCSTR str )
+ATOM LocalFindAtom( LPCSTR str )
{
return ATOM_FindAtom( USER_HeapSel, str );
}
/***********************************************************************
- * GlobalGetAtomName (USER.271)
+ * LocalGetAtomName (USER.271)
*/
-WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
+WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count )
{
return ATOM_GetAtomName( USER_HeapSel, atom, buffer, count );
}
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index 08de3c0..c1fd240 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -31,6 +31,7 @@
#include "dos_fs.h"
#include "autoconf.h"
#include "comm.h"
+#include "task.h"
#include "stddebug.h"
#include "debug.h"
@@ -47,7 +48,7 @@
struct DosDriveStruct { /* eg: */
char *rootdir; /* /usr/windows */
char cwd[256]; /* / */
- char label[13]; /* DRIVE-A */
+ char label[13]; /* DRIVE-A */
unsigned int serialnumber; /* ABCD5678 */
int disabled; /* 0 */
};
@@ -83,146 +84,154 @@
*s = 0;
}
+/* Simplify the path in "name" by removing "//"'s and
+ ".."'s in names like "/usr/bin/../lib/test" */
+static void DOS_SimplifyPath(char *name)
+{
+ char *l,*p;
+ BOOL changed;
+
+ dprintf_dosfs(stddeb,"SimplifyPath: Before %s\n",name);
+ do {
+ changed = FALSE;
+ while ((l = strstr(name,"//"))) {
+ strcpy(l,l+1); changed = TRUE;
+ }
+ while ((l = strstr(name,"/../"))) {
+ *l = 0;
+ p = strrchr(name,'/');
+ if (p == NULL) p = name;
+ strcpy(p,l+3);
+ changed = TRUE;
+ }
+ } while (changed);
+ dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name);
+}
+
+
+/* ChopOffSlash takes care to strip directory slashes from the
+ * end off the path name, but leaves a single slash. Multiple
+ * slashes at the end of a path are all removed.
+ */
+
void ChopOffSlash(char *path)
{
- if (path[strlen(path)-1] == '/' || path[strlen(path)-1] == '\\')
- path[strlen(path)-1] = '\0';
+ char *p = path + strlen(path) - 1;
+ while ((*p == '\\') && (p > path)) *p-- = '\0';
}
void ToUnix(char *s)
{
- /* \WINDOWS\\SYSTEM => /windows/system */
-
- char *p;
-
- for (p = s; *p; p++)
- {
- if (*p != '\\')
- *s++ = tolower(*p);
- else {
- *s++ = '/';
- if (*(p+1) == '/' || *(p+1) == '\\')
- p++;
- }
- }
- *s = '\0';
+ while(*s){
+ if (*s == '\\') *s = '/';
+ s++;
+ }
}
void ToDos(char *s)
{
- /* /windows//system => \WINDOWS\SYSTEM */
-
- char *p;
- for (p = s; *p; p++)
- {
- if (*p != '/')
- *s++ = toupper(*p);
- else {
- *s++ = '\\';
- if (*(p+1) == '/' || *(p+1) == '\\')
- p++;
- }
- }
- *s = '\0';
+ while(*s){
+ if (*s == '/') *s = '\\';
+ s++;
+ }
}
void DOS_InitFS(void)
{
- int x;
- char drive[2], temp[256];
+ int x;
+ char drive[2], temp[256];
+
+ 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", "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);
-
- ChopOffSlash(WindowsDirectory);
- ToDos(WindowsDirectory);
-
- ChopOffSlash(SystemDirectory);
- ToDos(SystemDirectory);
-
- ChopOffSlash(TempDirectory);
- ToDos(TempDirectory);
-
- ToDos(WindowsPath);
- ExpandTildeString(WindowsPath);
-
- for (x=0; x!=MAX_DOS_DRIVES; x++) {
- DosDrives[x].serialnumber = (0xEB0500L | x);
-
- 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;
- }
- ExpandTildeString(temp);
- ChopOffSlash(temp);
- DosDrives[x].rootdir = strdup(temp);
- strcpy(DosDrives[x].rootdir, temp);
- strcpy(DosDrives[x].cwd, "/windows/");
- strcpy(DosDrives[x].label, "DRIVE-");
- strcat(DosDrives[x].label, drive);
- DosDrives[x].disabled = 0;
+ GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
+ WindowsPath, sizeof(WindowsPath), WINE_INI);
+
+ ChopOffSlash(WindowsDirectory);
+ ToDos(WindowsDirectory);
+
+ ChopOffSlash(SystemDirectory);
+ ToDos(SystemDirectory);
+
+ ChopOffSlash(TempDirectory);
+ ToDos(TempDirectory);
+
+ ToDos(WindowsPath);
+ ExpandTildeString(WindowsPath);
+
+ for (x=0; x!=MAX_DOS_DRIVES; x++) {
+ DosDrives[x].serialnumber = (0xEB0500L | x);
+
+ 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;
}
- DosDrives[25].rootdir = "/";
- strcpy(DosDrives[25].cwd, "/");
- strcpy(DosDrives[25].label, "UNIX-FS");
- DosDrives[25].serialnumber = 0x12345678;
- DosDrives[25].disabled = 0;
+ ExpandTildeString(temp);
+ ChopOffSlash(temp);
+ DosDrives[x].rootdir = strdup(temp);
+ strcpy(DosDrives[x].rootdir, temp);
+ strcpy(DosDrives[x].cwd, "/windows/");
+ strcpy(DosDrives[x].label, "DRIVE-");
+ strcat(DosDrives[x].label, drive);
+ DosDrives[x].disabled = 0;
+ }
+ DosDrives[25].rootdir = "/";
+ strcpy(DosDrives[25].cwd, "/");
+ strcpy(DosDrives[25].label, "UNIX-FS");
+ DosDrives[25].serialnumber = 0x12345678;
+ DosDrives[25].disabled = 0;
+
+ /* Get the startup directory and try to map it to a DOS drive
+ * and directory. (i.e., if we start in /dos/windows/word and
+ * drive C is defined as /dos, the starting wd for C will be
+ * /windows/word) Also set the default drive to whatever drive
+ * corresponds to the directory we started in.
+ */
- /* Get the startup directory and try to map it to a DOS drive
- * and directory. (i.e., if we start in /dos/windows/word and
- * drive C is defined as /dos, the starting wd for C will be
- * /windows/word) Also set the default drive to whatever drive
- * corresponds to the directory we started in.
- */
+ for (x=0; x!=MAX_DOS_DRIVES; x++)
+ if (DosDrives[x].rootdir != NULL)
+ strcpy( DosDrives[x].cwd, "/" );
- for (x=0; x!=MAX_DOS_DRIVES; x++)
- if (DosDrives[x].rootdir != NULL)
- strcpy( DosDrives[x].cwd, "\\" );
-
- getcwd(temp, 254);
- strcat(temp, "/"); /* For DOS_GetDosFileName */
- strcpy(temp, DOS_GetDosFileName(temp));
- if(temp[0] != 'Z')
- {
- ToUnix(&temp[2]);
- strcpy(DosDrives[temp[0] - 'A'].cwd, &temp[2]);
- DOS_SetDefaultDrive(temp[0] - 'A');
- }
- else
- {
- DOS_SetDefaultDrive(2);
- }
-
- for (x=0; x!=MAX_DOS_DRIVES; x++) {
- if (DosDrives[x].rootdir != NULL) {
- dprintf_dosfs(stddeb, "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
- );
- }
+ getcwd(temp, 254);
+ strcat(temp, "/"); /* For DOS_GetDosFileName */
+ strcpy(temp, DOS_GetDosFileName(temp));
+ if(temp[0] != 'Z')
+ {
+ ToUnix(temp + 2);
+ strcpy(DosDrives[temp[0] - 'A'].cwd, &temp[2]);
+ DOS_SetDefaultDrive(temp[0] - 'A');
+ }
+ else
+ {
+ DOS_SetDefaultDrive(2);
+ }
+
+ for (x=0; x!=MAX_DOS_DRIVES; x++) {
+ if (DosDrives[x].rootdir != NULL) {
+ dprintf_dosfs(stddeb, "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);
}
-
- for (x=0; x!=max_open_dirs ; x++)
- DosDirs[x].inuse = 0;
+ }
+
+ for (x=0; x!=max_open_dirs ; x++)
+ DosDirs[x].inuse = 0;
dprintf_dosfs(stddeb,"wine.ini = %s\n",WINE_INI);
dprintf_dosfs(stddeb,"win.ini = %s\n",WIN_INI);
@@ -234,11 +243,11 @@
WORD DOS_GetEquipment(void)
{
- WORD equipment;
- int diskdrives = 0;
- int parallelports = 0;
- int serialports = 0;
- int x;
+ WORD equipment;
+ int diskdrives = 0;
+ int parallelports = 0;
+ int serialports = 0;
+ int x;
/* borrowed from Ralph Brown's interrupt lists
@@ -266,219 +275,102 @@
bit 2 (always set)
*/
- if (DosDrives[0].rootdir != NULL)
- diskdrives++;
- if (DosDrives[1].rootdir != NULL)
- diskdrives++;
- if (diskdrives)
- diskdrives--;
+ if (DosDrives[0].rootdir != NULL)
+ diskdrives++;
+ if (DosDrives[1].rootdir != NULL)
+ diskdrives++;
+ if (diskdrives)
+ diskdrives--;
- for (x=0; x!=MAX_PORTS; x++) {
- if (COM[x].devicename)
- serialports++;
- if (LPT[x].devicename)
- parallelports++;
- }
- if (serialports > 7) /* 3 bits -- maximum value = 7 */
- serialports=7;
- if (parallelports > 3) /* 2 bits -- maximum value = 3 */
- parallelports=3;
-
- equipment = (diskdrives << 6) | (serialports << 9) |
- (parallelports << 14) | 0x02;
+ for (x=0; x!=MAX_PORTS; x++) {
+ if (COM[x].devicename)
+ serialports++;
+ if (LPT[x].devicename)
+ parallelports++;
+ }
+ if (serialports > 7) /* 3 bits -- maximum value = 7 */
+ serialports=7;
+ if (parallelports > 3) /* 2 bits -- maximum value = 3 */
+ parallelports=3;
+
+ equipment = (diskdrives << 6) | (serialports << 9) |
+ (parallelports << 14) | 0x02;
dprintf_dosfs(stddeb, "DOS_GetEquipment : diskdrives = %d serialports = %d "
- "parallelports = %d\n"
- "DOS_GetEquipment : equipment = %d\n",
- diskdrives, serialports, parallelports, equipment);
-
- return (equipment);
+ "parallelports = %d\n"
+ "DOS_GetEquipment : equipment = %d\n",
+ diskdrives, serialports, parallelports, equipment);
+
+ return equipment;
}
int DOS_ValidDrive(int drive)
{
- int valid = 1;
+ dprintf_dosfs(stddeb,"ValidDrive %c (%d)\n",'A'+drive,drive);
- dprintf_dosfs(stddeb,"ValidDrive %c (%d) -- ",'A'+drive,drive);
+ if (drive < 0 || drive >= MAX_DOS_DRIVES) return 0;
+ if (DosDrives[drive].rootdir == NULL) return 0;
+ if (DosDrives[drive].disabled) return 0;
- if (drive < 0 || drive >= MAX_DOS_DRIVES)
- valid = 0;
- if (DosDrives[drive].rootdir == NULL)
- valid = 0;
- if (DosDrives[drive].disabled)
- valid = 0;
-
- dprintf_dosfs(stddeb, "%s\n", valid ? "Valid" : "Invalid");
- return valid;
+ dprintf_dosfs(stddeb, " -- valid\n");
+ return 1;
}
-
-int DOS_ValidDirectory(char *name)
+static void DOS_GetCurrDir_Unix(char *buffer, int drive)
{
- char *dirname;
- struct stat s;
- dprintf_dosfs(stddeb, "DOS_ValidDirectory: '%s'\n", name);
- if ((dirname = DOS_GetUnixFileName(name)) == NULL)
- return 0;
- if (stat(dirname,&s))
- return 0;
- if (!S_ISDIR(s.st_mode))
- return 0;
- dprintf_dosfs(stddeb, "==> OK\n");
- return 1;
-}
-
-
-
-/* Simplify the path in "name" by removing "//"'s and
- ".."'s in names like "/usr/bin/../lib/test" */
-void DOS_SimplifyPath(char *name)
-{
- char *l,*p;
- BOOL changed;
-
- dprintf_dosfs(stddeb,"SimplifyPath: Before %s\n",name);
- do {
- changed = FALSE;
- while ((l = strstr(name,"//"))) {
- strcpy(l,l+1); changed = TRUE;
- }
- while ((l = strstr(name,"/../"))) {
- *l = 0;
- p = strrchr(name,'/');
- if (p == NULL) p = name;
- strcpy(p,l+3);
- changed = TRUE;
+ TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
+
+ if (pTask != NULL && (pTask->curdrive & ~0x80) == drive) {
+ strcpy(buffer, pTask->curdir);
+ ToUnix(buffer);
+ } else {
+ strcpy(buffer, DosDrives[drive].cwd);
}
- } while (changed);
- dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name);
}
-
-int DOS_GetDefaultDrive(void)
-{
- dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+CurrentDrive);
- return( CurrentDrive);
-}
-
-void DOS_SetDefaultDrive(int drive)
-{
- dprintf_dosfs(stddeb,"SetDefaultDrive to %c:\n",'A'+drive);
- if (DOS_ValidDrive(drive))
- CurrentDrive = drive;
-}
-
-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;
-}
-
-static void GetUnixDirName(char *rootdir, char *name)
-{
- int filename = 1;
- char *nameptr, *cwdptr;
-
- cwdptr = rootdir + strlen(rootdir);
- nameptr = name;
-
- dprintf_dosfs(stddeb,"GetUnixDirName: %s <=> %s => ",rootdir, name);
-
- 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);
-
- dprintf_dosfs(stddeb,"%s\n", rootdir);
-
-}
-
-char *DOS_GetUnixFileName(char *dosfilename)
+char *DOS_GetCurrentDir(int drive)
{
- /* a:\windows\system.ini => /dos/windows/system.ini */
+ static char temp[256];
- /* FIXME: should handle devices here (like LPT: or NUL:) */
+ if (!DOS_ValidDrive(drive)) return 0;
- static char temp[256];
- static char dostemp[256];
- int drive;
+ DOS_GetCurrDir_Unix(temp, drive);
+ DOS_SimplifyPath( temp );
+ ToDos(temp);
+ ChopOffSlash(temp);
- if (dosfilename[0] && (dosfilename[1] == ':'))
- {
- drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A';
-
- if (!DOS_ValidDrive(drive))
- return NULL;
- else
- dosfilename+=2;
- } else
- drive = CurrentDrive;
+ dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
+ return temp + 1;
+}
- /* Consider dosfilename const */
- strncpy( dostemp, dosfilename, 255 );
- dostemp[255] = '\0';
+char *DOS_GetUnixFileName(const char *dosfilename)
+{
+ /* a:\windows\system.ini => /dos/windows/system.ini */
+
+ /* FIXME: should handle devices here (like LPT: or NUL:) */
+
+ static char dostemp[256], temp[256];
+ int drive = DOS_GetDefaultDrive();
+
+ if (dosfilename[0] && dosfilename[1] == ':')
+ {
+ drive = toupper(*dosfilename) - 'A';
+ dosfilename += 2;
+ }
+ if (!DOS_ValidDrive(drive)) return NULL;
- /* Expand the filename to it's full path if it doesn't
- * start from the root.
- */
- DOS_ExpandToFullPath(dostemp, drive);
-
- strcpy(temp, DosDrives[drive].rootdir);
- strcat(temp, DosDrives[drive].cwd);
- GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dostemp);
-
- dprintf_dosfs(stddeb,"GetUnixFileName: %s => %s\n", dosfilename, temp);
- return(temp);
+ strncpy( dostemp, dosfilename, 255 );
+ dostemp[255] = 0;
+ ToUnix(dostemp);
+ strcpy(temp, DosDrives[drive].rootdir);
+ if (dostemp[0] != '/') {
+ DOS_GetCurrDir_Unix(temp+strlen(temp), drive);
+ }
+ strcat(temp, dostemp);
+ DOS_SimplifyPath(temp);
+
+ dprintf_dosfs(stddeb,"GetUnixFileName: %s => %s\n", dosfilename, temp);
+ return temp;
}
/* Note: This function works on directories as well as long as
@@ -486,136 +378,148 @@
*/
char *DOS_GetDosFileName(char *unixfilename)
{
- int i;
- static char temp[256], rootdir[256];
- /* /dos/windows/system.ini => c:\windows\system.ini */
-
- /* Expand it if it's a relative name.
- */
- DOS_ExpandToFullUnixPath(unixfilename);
-
- for (i = 0 ; i != MAX_DOS_DRIVES; i++) {
- if (DosDrives[i].rootdir != NULL) {
- strcpy(rootdir, DosDrives[i].rootdir);
- strcat(rootdir, "/");
- if (strncmp(rootdir, unixfilename, strlen(rootdir)) == 0) {
- sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(rootdir));
- ToDos(temp);
- return temp;
- }
- }
+ int i;
+ static char temp[256], temp2[256];
+ /* /dos/windows/system.ini => c:\windows\system.ini */
+
+ dprintf_dosfs(stddeb,"DOS_GetDosFileName: %s\n", unixfilename);
+ if (unixfilename[0] == '/') {
+ strncpy(temp, unixfilename, 255);
+ temp[255] = 0;
+ } else {
+ /* Expand it if it's a relative name. */
+ getcwd(temp, 255);
+ if(strncmp(unixfilename, "./", 2) != 0) {
+ strcat(temp, unixfilename + 1);
+ } else {
+ strcat(temp, "/");
+ strcat(temp, unixfilename);
}
- sprintf(temp, "Z:%s", unixfilename);
- ToDos(temp);
- return(temp);
+ }
+ for (i = 0 ; i < MAX_DOS_DRIVES; i++) {
+ if (DosDrives[i].rootdir != NULL) {
+ int len = strlen(DosDrives[i].rootdir);
+ dprintf_dosfs(stddeb, " check %c:%s\n", i+'A', DosDrives[i].rootdir);
+ if (strncmp(DosDrives[i].rootdir, temp, len) == 0 && temp[len] == '/')
+ {
+ sprintf(temp2, "%c:%s", 'A' + i, temp+len);
+ ToDos(temp2+2);
+ return temp2;
+ }
+ }
+ }
+ sprintf(temp, "Z:%s", unixfilename);
+ ToDos(temp+2);
+ return temp;
}
-char *DOS_GetCurrentDir(int drive)
-{
- static char temp[256];
+int DOS_ValidDirectory(int drive, char *name)
+{
+ char temp[256];
+ struct stat s;
+
+ strcpy(temp, DosDrives[drive].rootdir);
+ strcat(temp, name);
+ if (stat(temp, &s)) return 0;
+ if (!S_ISDIR(s.st_mode)) return 0;
+ dprintf_dosfs(stddeb, "==> OK\n");
+ return 1;
+}
- if (!DOS_ValidDrive(drive))
- return 0;
-
- strcpy(temp, DosDrives[drive].cwd);
- DOS_SimplifyPath( temp );
- ToDos(temp);
- ChopOffSlash(temp);
+int DOS_GetDefaultDrive(void)
+{
+ TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
+ int drive = pTask == NULL ? CurrentDrive : pTask->curdrive & ~0x80;
+
+ dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+drive);
+ return drive;
+}
- dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
- return (temp + 1);
+void DOS_SetDefaultDrive(int drive)
+{
+ TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
+
+ dprintf_dosfs(stddeb,"SetDefaultDrive to %c:\n",'A'+drive);
+ if (DOS_ValidDrive(drive) && drive != DOS_GetDefaultDrive()) {
+ if (pTask == NULL) CurrentDrive = drive;
+ else {
+ char temp[256];
+ pTask->curdrive = drive | 0x80;
+ strcpy(temp, DosDrives[drive].rootdir);
+ strcat(temp, DosDrives[drive].cwd);
+ strcpy(temp, DOS_GetDosFileName(temp));
+ dprintf_dosfs(stddeb, " curdir = %s\n", temp);
+ if (strlen(temp)-2 < sizeof(pTask->curdir)) strcpy(pTask->curdir, temp+2);
+ else fprintf(stderr, "dosfs: curdir too long\n");
+ }
+ }
+}
+
+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;
}
int DOS_ChangeDir(int drive, char *dirname)
{
- char temp[256],old[256];
+ TDB *pTask = (TDB *)GlobalLock(GetCurrentTask());
+ char temp[256];
+
+ if (!DOS_ValidDrive(drive)) return 0;
- if (!DOS_ValidDrive(drive))
- return 0;
-
+ if (dirname[0] == '\\') {
strcpy(temp, dirname);
- ToUnix(temp);
- strcpy(old, DosDrives[drive].cwd);
-
- GetUnixDirName(DosDrives[drive].cwd, temp);
- strcat(DosDrives[drive].cwd,"/");
+ } else {
+ DOS_GetCurrDir_Unix(temp, drive);
+ strcat(temp, dirname);
+ }
+ ToUnix(temp);
+ strcat(temp, "/");
+ DOS_SimplifyPath(temp);
+ dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s ==> %s\n", 'A'+drive, dirname, temp);
- dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s\n",'A'+drive,
- DosDrives[drive].cwd);
-
- if (!DOS_ValidDirectory(DosDrives[drive].cwd))
- {
- strcpy(DosDrives[drive].cwd, old);
- return 0;
- }
- DOS_SimplifyPath(DosDrives[drive].cwd);
- return 1;
+ if (!DOS_ValidDirectory(drive, temp)) return 0;
+ strcpy(DosDrives[drive].cwd, temp);
+ if (pTask != NULL && DOS_GetDefaultDrive() == drive) {
+ strcpy(temp, DosDrives[drive].rootdir);
+ strcat(temp, DosDrives[drive].cwd);
+ strcpy(temp, DOS_GetDosFileName(temp));
+ dprintf_dosfs(stddeb, " curdir = %s\n", temp);
+ if (strlen(temp)-2 < sizeof(pTask->curdir)) strcpy(pTask->curdir, temp+2);
+ else fprintf(stderr, "dosfs: curdir too long\n");
+ }
+ return 1;
}
int DOS_MakeDir(int drive, char *dirname)
{
- char temp[256];
-
- if (!DOS_ValidDrive(drive))
- return 0;
+ char temp[256], currdir[256];
+
+ if (!DOS_ValidDrive(drive)) return 0;
- strcpy(temp, DosDrives[drive].cwd);
- GetUnixDirName(temp, dirname);
- strcat(DosDrives[drive].cwd,"/");
-
- ToUnix(temp + strlen(DosDrives[drive].cwd));
- mkdir(temp,0);
-
- dprintf_dosfs(stddeb,
- "DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
- return 1;
-}
-
-/* DOS_ExpandToFullPath takes a dos-style filename and converts it
- * into a full path based on the current working directory.
- * (e.g., "foo.bar" => "d:\\moo\\foo.bar")
- */
-void DOS_ExpandToFullPath(char *filename, int drive)
-{
- char temp[256];
-
- dprintf_dosfs(stddeb, "DOS_ExpandToFullPath: Original = %s\n", filename);
-
- /* If the filename starts with '/' or '\',
- * don't bother -- we're already at the root.
- */
- if(filename[0] == '/' || filename[0] == '\\')
- return;
-
- strcpy(temp, DosDrives[drive].cwd);
- strcat(temp, filename);
- strcpy(filename, temp);
-
- dprintf_dosfs(stddeb, " Expanded = %s\n", temp);
-}
-
-/* DOS_ExpandToFullUnixPath takes a unix filename and converts it
- * into a full path based on the current working directory. Thus,
- * it's probably not a good idea to get a relative name, change the
- * working directory, and then convert it...
- */
-void DOS_ExpandToFullUnixPath(char *filename)
-{
- char temp[256];
-
- if(filename[0] == '/')
- return;
-
- getcwd(temp, 255);
- if(!strncmp(filename, "./", 2))
- strcat(temp, filename + 1);
- else
- {
- strcat(temp, "/");
- strcat(temp, filename);
- }
- dprintf_dosfs(stddeb, "DOS_ExpandToFullUnixPath: %s => %s\n", filename, temp);
- strcpy(filename, temp);
+ strcpy(temp, DosDrives[drive].rootdir);
+ DOS_GetCurrDir_Unix(currdir, drive);
+ strcat(temp, currdir);
+ strcat(temp, dirname);
+ ToUnix(temp);
+ DOS_SimplifyPath(temp);
+ mkdir(temp,0);
+
+ dprintf_dosfs(stddeb, "DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
+ return 1;
}
int DOS_GetSerialNumber(int drive, unsigned long *serialnumber)
@@ -641,7 +545,7 @@
if (!DOS_ValidDrive(drive))
return NULL;
- return (DosDrives[drive].label);
+ return DosDrives[drive].label;
}
int DOS_SetVolumeLabel(int drive, char *label)
@@ -743,6 +647,7 @@
if (S_ISREG(filestat.st_mode)) {
closedir(d);
free(rootname);
+ DOS_SimplifyPath(buffer);
return buffer;
}
}
@@ -769,15 +674,15 @@
if ((fd = open(name, O_RDONLY)) != -1) {
close(fd);
filename = name;
- return(filename);
+ return filename;
}
if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) {
close(fd);
filename = WINE_INI_GLOBAL;
- return(filename);
+ return filename;
}
- fprintf(stderr,"wine: can't open configuration file %s or %s !\n",
- WINE_INI_GLOBAL, WINE_INI_USER);
+ fprintf(stderr,"wine: can't open configuration file %s or %s !\n",
+ WINE_INI_GLOBAL, WINE_INI_USER);
exit(1);
}
@@ -866,59 +771,48 @@
struct dosdirent *DOS_opendir(char *dosdirname)
{
- int x,y;
- char *unixdirname;
- char temp[256];
- DIR *ds;
-
- if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL)
- return NULL;
+ int x, len;
+ char *unixdirname;
+ char dirname[256];
+ DIR *ds;
+
+ if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL) return NULL;
+
+ len = strrchr(unixdirname, '/') - unixdirname + 1;
+ strncpy(dirname, unixdirname, len);
+ dirname[len] = 0;
+ unixdirname = strrchr(unixdirname, '/') + 1;
- strcpy(temp, unixdirname);
- y = strlen(temp);
- while (y--)
- {
- if (temp[y] == '/')
- {
- temp[y++] = '\0';
- unixdirname += y;
- break;
- }
- }
-
- for (x=0; x <= max_open_dirs; x++) {
- if (x == max_open_dirs) {
+ for (x=0; x <= max_open_dirs; x++) {
+ if (x == max_open_dirs) {
if (DosDirs) {
- DosDirs=(struct dosdirent*)realloc(DosDirs,(++max_open_dirs)*sizeof(DosDirs[0]));
+ DosDirs=(struct dosdirent*)realloc(DosDirs,(++max_open_dirs)*sizeof(DosDirs[0]));
} else {
- DosDirs=(struct dosdirent*)malloc(sizeof(DosDirs[0]));
- max_open_dirs=1;
+ DosDirs=(struct dosdirent*)malloc(sizeof(DosDirs[0]));
+ max_open_dirs=1;
}
break; /* this one is definitely not in use */
- }
- if (!DosDirs[x].inuse) break;
- if (strcmp(DosDirs[x].unixpath,temp) == 0) break;
}
-
- strncpy(DosDirs[x].filemask, unixdirname, 12);
- DosDirs[x].filemask[12] = 0;
- ToDos(DosDirs[x].filemask);
- dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, temp);
+ if (!DosDirs[x].inuse) break;
+ if (strcmp(DosDirs[x].unixpath, dirname) == 0) break;
+ }
+
+ strncpy(DosDirs[x].filemask, unixdirname, 12);
+ DosDirs[x].filemask[12] = 0;
+ dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, dirname);
- DosDirs[x].inuse = 1;
- strcpy(DosDirs[x].unixpath, temp);
- DosDirs[x].entnum = 0;
+ DosDirs[x].inuse = 1;
+ strcpy(DosDirs[x].unixpath, dirname);
+ DosDirs[x].entnum = 0;
- if ((ds = opendir(temp)) == NULL)
- return NULL;
- if (-1==(DosDirs[x].telldirnum=telldir(ds))) {
- closedir(ds);
- return NULL;
- }
- if (-1==closedir(ds))
- return NULL;
+ if ((ds = opendir(dirname)) == NULL) return NULL;
+ if (-1==(DosDirs[x].telldirnum=telldir(ds))) {
+ closedir(ds);
+ return NULL;
+ }
+ if (-1==closedir(ds)) return NULL;
- return &DosDirs[x];
+ return &DosDirs[x];
}
@@ -931,22 +825,36 @@
if (!de->inuse)
return NULL;
- if (-1==(ds=opendir(de->unixpath)))
- return NULL;
+ if (!(ds=opendir(de->unixpath))) return NULL;
seekdir(ds,de->telldirnum); /* returns no error value. strange */
- do {
- if ((d = readdir(ds)) == NULL) {
- de->telldirnum=telldir(ds);
- closedir(ds);
- return NULL;
+
+ if (de->search_attribute & FA_LABEL) {
+ int drive;
+ de->search_attribute &= ~FA_LABEL; /* don't find it again */
+ for(drive = 0; drive < MAX_DOS_DRIVES; drive++) {
+ if (DosDrives[drive].rootdir != NULL &&
+ strcmp(DosDrives[drive].rootdir, de->unixpath) == 0)
+ {
+ strcpy(de->filename, DOS_GetVolumeLabel(drive));
+ de->attribute = FA_LABEL;
+ return de;
}
+ }
+ }
+
+ do {
+ if ((d = readdir(ds)) == NULL) {
+ de->telldirnum=telldir(ds);
+ closedir(ds);
+ return NULL;
+ }
- de->entnum++; /* Increment the directory entry number */
- strcpy(de->filename, d->d_name);
- if (d->d_reclen > 12)
- de->filename[12] = '\0';
-
- ToDos(de->filename);
+ de->entnum++; /* Increment the directory entry number */
+ strcpy(de->filename, d->d_name);
+ if (d->d_reclen > 12)
+ de->filename[12] = '\0';
+
+ ToDos(de->filename);
} while ( !match(de->filename, de->filemask) );
strcpy(temp,de->unixpath);
diff --git a/misc/exec.c b/misc/exec.c
index 635f4bd..ab5bc0e 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -8,7 +8,6 @@
#include <string.h>
#include <unistd.h>
#include "neexe.h"
-#include "prototypes.h"
#include "dlls.h"
#include "windows.h"
#include "callback.h"
diff --git a/misc/file.c b/misc/file.c
index ef45ec5..3581ce3 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -108,8 +108,8 @@
{
dprintf_file(stddeb, "_lclose: handle %d\n", hFile);
- if (hFile == 1 || hFile == 2) {
- fprintf( stderr, "Program attempted to close stdout or stderr!\n" );
+ if (hFile == 0 || hFile == 1 || hFile == 2) {
+ fprintf( stderr, "Program attempted to close stdin, stdout or stderr!\n" );
return 0;
}
if (close (hFile))
@@ -154,7 +154,7 @@
ofs->nErrCode = ExtendedError;
return -1;
}
- handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0x666);
+ handle = open (unixfilename, (wStyle & 0x0003) | O_CREAT, 0666);
if (handle == -1)
{
errno_to_doserr();
@@ -325,7 +325,7 @@
lpszFilename, fnAttribute);
if ((UnixFileName = DOS_GetUnixFileName(lpszFilename)) == NULL)
return HFILE_ERROR;
- handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 426);
+ handle = open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 0666);
if (handle == -1)
return HFILE_ERROR;
@@ -372,8 +372,7 @@
dprintf_file(stddeb,"GetWindowsDirectory (%s)\n",lpszSysPath);
- ChopOffSlash(lpszSysPath);
- return(strlen(lpszSysPath));
+ return strlen(lpszSysPath);
}
/***************************************************************************
GetSystemDirectory
@@ -387,8 +386,7 @@
dprintf_file(stddeb,"GetSystemDirectory (%s)\n",lpszSysPath);
- ChopOffSlash(lpszSysPath);
- return(strlen(lpszSysPath));
+ return strlen(lpszSysPath);
}
/***************************************************************************
GetTempFileName
diff --git a/misc/kernel32.c b/misc/kernel32.c
index 0be2b09..df6a5ba 100644
--- a/misc/kernel32.c
+++ b/misc/kernel32.c
@@ -9,6 +9,7 @@
#include "windows.h"
#include "winerror.h"
+#include <unistd.h>
int WIN32_LastError;
diff --git a/misc/main.c b/misc/main.c
index f5f8544..3528df5 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -2,9 +2,8 @@
* Main function.
*
* Copyright 1994 Alexandre Julliard
- *
-static char Copyright[] = "Copyright Alexandre Julliard, 1994";
-*/
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -24,7 +23,6 @@
#include "winsock.h"
#include "options.h"
#include "desktop.h"
-#include "prototypes.h"
#include "dlls.h"
#define DEBUG_DEFINE_VARIABLES
#include "stddebug.h"
@@ -63,7 +61,6 @@
struct options Options =
{ /* default options */
- NULL, /* spyFilename */
NULL, /* desktopGeometry */
NULL, /* programName */
FALSE, /* usePrivateMap */
@@ -86,7 +83,6 @@
{ "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
{ "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
{ "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
- { "-spy", ".spy", XrmoptionSepArg, (caddr_t)NULL },
{ "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
{ "-debugmsg", ".debugmsg", XrmoptionSepArg, (caddr_t)NULL },
{ "-dll", ".dll", XrmoptionSepArg, (caddr_t)NULL },
@@ -109,11 +105,11 @@
" -privatemap Use a private color map\n" \
" -synchronous Turn on synchronous display mode\n" \
" -backingstore Turn on backing store\n" \
- " -spy file Turn on message spying to the specified file\n" \
+ " -spy file Obsolete. Use -debugmsg +spy for Spy messages\n" \
" -debugmsg name Turn debugging-messages on or off\n" \
" -dll name Enable or disable built-in DLLs\n" \
" -allowreadonly Read only files may be opened in write mode\n" \
- " -enhanced Start wine in enhanced mode\n"
+ " -enhanced Start wine in enhanced mode (like 'win /3') \n"
@@ -313,8 +309,6 @@
Options.allowReadOnly = TRUE;
if (MAIN_GetResource( db, ".enhanced", &value ))
Options.enhanced = TRUE;
- if (MAIN_GetResource( db, ".spy", &value))
- Options.spyFilename = value.addr;
if (MAIN_GetResource( db, ".depth", &value))
screenDepth = atoi( value.addr );
if (MAIN_GetResource( db, ".desktop", &value))
@@ -463,14 +457,20 @@
KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
}
+
+#ifdef MALLOC_DEBUGGING
static void malloc_error()
{
fprintf(stderr,"malloc is not feeling well. Good bye\n");
exit(1);
}
+#endif /* MALLOC_DEBUGGING */
+
static void called_at_exit(void)
{
+ extern void sync_profiles(void);
+
sync_profiles();
MAIN_RestoreSetup();
WSACleanup();
@@ -485,8 +485,10 @@
int depth_count, i;
int *depth_list;
- setbuf(stdout,NULL);
- setbuf(stderr,NULL);
+ extern int _WinMain(int argc, char **argv);
+
+ setbuf(stdout,NULL);
+ setbuf(stderr,NULL);
setlocale(LC_CTYPE,"");
@@ -565,9 +567,9 @@
LONG GetWinFlags(void)
{
if (Options.enhanced)
- return (WF_STANDARD | WF_ENHANCED | WF_CPU386 | WF_PMODE | WF_80x87);
+ return (WF_ENHANCED | WF_CPU386 | WF_PMODE | WF_80x87 | WF_PAGING);
else
- return (WF_STANDARD | WF_CPU286 | WF_PMODE | WF_80x87);
+ return (WF_STANDARD | WF_CPU386 | WF_PMODE | WF_80x87);
}
/***********************************************************************
diff --git a/misc/profile.c b/misc/profile.c
index 71e5373..0c3df91 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -96,7 +96,8 @@
int state;
TSecHeader *SecHeader = 0;
char CharBuffer [STRSIZE];
- char *next, *file;
+ char *next = '\0';
+ char *file;
char c;
char path[MAX_PATH+1];
@@ -287,6 +288,7 @@
return (Size - 2 - left);
}
for (key = section->Keys; key; key = key->link){
+ int slen;
if (strcasecmp (key->KeyName, KeyName))
continue;
if (set){
@@ -295,19 +297,21 @@
Current->changed=TRUE;
return 1;
}
- ReturnedString [Size-1] = 0;
- strncpy (ReturnedString, key->Value, Size-1);
+ slen = min(strlen(key->Value), Size - 1);
+ ReturnedString[slen] = 0;
+ strncpy (ReturnedString, key->Value, slen);
dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString);
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 */
/* No key found */
- if (set)
+ if (set) {
new_key (section, KeyName, Default);
- else {
- ReturnedString [Size-1] = 0;
- strncpy (ReturnedString, Default, Size-1);
+ } else {
+ int slen = min(strlen(Default), Size - 1);
+ ReturnedString[slen] = 0;
+ strncpy(ReturnedString, Default, slen);
dprintf_profile(stddeb,"GetSetProfile // Key not found\n");
}
return 1;
@@ -322,8 +326,9 @@
Current->Section = section;
Current->changed = TRUE;
} else {
- ReturnedString [Size-1] = 0;
- strncpy (ReturnedString, Default, Size-1);
+ int slen = min(strlen(Default), Size - 1);
+ ReturnedString[slen] = 0;
+ strncpy(ReturnedString, Default, slen);
dprintf_profile(stddeb,"GetSetProfile // Section not found\n");
}
return 1;
diff --git a/misc/spy.c b/misc/spy.c
index 7c82b10..835f8c6 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -8,14 +8,13 @@
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <string.h>
-#include "wineopts.h"
#include "windows.h"
#include "wine.h"
#include "options.h"
+#include "stddebug.h"
+#include "debug.h"
-#ifndef NOSPY
-
-#define SPY_MAX_MSGNUM 0x0232
+#define SPY_MAX_MSGNUM 0x03e8
const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
{
@@ -245,27 +244,115 @@
"WM_MDIICONARRANGE", /* 0x0228 */
"WM_MDIGETACTIVE", /* 0x0229 */
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ /* 0x0230*/
"WM_MDISETMENU", /* 0x0230 */
"WM_ENTERSIZEMOVE", /* 0x0231 */
- "WM_EXITSIZEMOVE" /* 0x0232 */
+ "WM_EXITSIZEMOVE", /* 0x0232 */
+ NULL, NULL, NULL, NULL, NULL,
+ /* 0x0238*/
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0240 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0250 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0260 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0280 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x02c0 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0300 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0340 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x0380 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x03c0 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* 0x03e0 */
+ "WM_DDE_INITIATE", /* 0x3E0 */
+ "WM_DDE_TERMINATE", /* 0x3E1 */
+ "WM_DDE_ADVISE", /* 0x3E2 */
+ "WM_DDE_UNADVISE", /* 0x3E3 */
+ "WM_DDE_ACK", /* 0x3E4 */
+ "WM_DDE_DATA", /* 0x3E5 */
+ "WM_DDE_REQUEST", /* 0x3E6 */
+ "WM_DDE_POKE", /* 0x3E7 */
+ "WM_DDE_EXECUTE" /* 0x3E8 */
};
char SpyFilters[256+1];
char SpyIncludes[256+1];
-#endif /* NOSPY */
-
/**********************************************************************
* SpyMessage
*/
void SpyMessage(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
{
-#ifndef NOSPY
char msg_name[80];
- if (SpyFp == NULL)
- return;
-
+ if(!debugging_spy)
+ return;
+
if (msg > SPY_MAX_MSGNUM || MessageTypeNames[msg] == NULL)
sprintf(msg_name, "%04x", msg);
else
@@ -277,10 +364,9 @@
strstr(SpyFilters, msg_name) == NULL)
{
msg_name[strlen(msg_name) - 1] = '\0';
- fprintf(SpyFp, "%04x %20.20s %04x %04x %08lx\n",
+ dprintf_spy(stddeb, "%04x %20.20s %04x %04x %08lx\n",
hwnd, msg_name, msg, wParam, lParam);
}
-#endif
}
/**********************************************************************
@@ -288,30 +374,6 @@
*/
void SpyInit(void)
{
-#ifndef NOSPY
- char filename[100];
-
- if (SpyFp != NULL)
- return;
-
- if (Options.spyFilename == NULL)
- {
- GetPrivateProfileString("spy", "file", "", filename, sizeof(filename),
- WINE_INI);
- }
- else
- strncpy(filename, Options.spyFilename, 100);
-
- if (strcasecmp(filename, "CON") == 0)
- SpyFp = stdout;
- else if (strlen(filename))
- SpyFp = fopen(filename, "a");
- else
- {
- SpyFp = NULL;
- return;
- }
-
GetPrivateProfileString("spy", "exclude", "", SpyFilters,
sizeof(SpyFilters)-1, WINE_INI);
GetPrivateProfileString("spy", "include", "", SpyIncludes,
@@ -323,5 +385,4 @@
if (*SpyFilters != 0) {
strcat(SpyFilters, ";");
}
-#endif
}
diff --git a/misc/user.c b/misc/user.c
index 86a09f5..98b7b1b 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -17,7 +17,6 @@
#include "syscolor.h"
#include "win.h"
#include "windows.h"
-#include "prototypes.h"
#include "user.h"
#include "message.h"
#include "toolhelp.h"
diff --git a/misc/winsocket.c b/misc/winsocket.c
index ee95375..2fdd5a6 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -20,6 +20,7 @@
#include <netdb.h>
#include <unistd.h>
#include "winsock.h"
+#include "toolhelp.h"
#include "stddebug.h"
#include "debug.h"
@@ -37,33 +38,36 @@
LONG lParam;
};
+#ifndef WINELIB
#pragma pack(1)
+#endif
#define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
#define MTYPE 0xb0b0eb05
-#define WINE_PACKED __attribute__ ((packed))
+
+/* These structures are Win16 only */
struct WIN_hostent {
- char *h_name WINE_PACKED; /* official name of host */
- char **h_aliases WINE_PACKED; /* alias list */
- int h_addrtype WINE_PACKED; /* host address type */
- int h_length WINE_PACKED; /* length of address */
+ SEGPTR h_name WINE_PACKED; /* official name of host */
+ SEGPTR h_aliases WINE_PACKED; /* alias list */
+ INT h_addrtype WINE_PACKED; /* host address type */
+ INT h_length WINE_PACKED; /* length of address */
char **h_addr_list WINE_PACKED; /* list of addresses from name server */
char *names[2];
char hostname[200];
};
struct WIN_protoent {
- char *p_name WINE_PACKED; /* official protocol name */
- char **p_aliases WINE_PACKED; /* alias list */
- int p_proto WINE_PACKED; /* protocol # */
+ SEGPTR p_name WINE_PACKED; /* official protocol name */
+ SEGPTR p_aliases WINE_PACKED; /* alias list */
+ INT p_proto WINE_PACKED; /* protocol # */
};
struct WIN_servent {
- char *s_name WINE_PACKED; /* official service name */
- char **s_aliases WINE_PACKED; /* alias list */
- int s_port WINE_PACKED; /* port # */
- char *s_proto WINE_PACKED; /* protocol to use */
+ SEGPTR s_name WINE_PACKED; /* official service name */
+ SEGPTR s_aliases WINE_PACKED; /* alias list */
+ INT s_port WINE_PACKED; /* port # */
+ SEGPTR s_proto WINE_PACKED; /* protocol to use */
};
struct WinSockHeap {
@@ -82,10 +86,23 @@
struct WIN_protoent WSAprotoent_number;
struct WIN_servent WSAservent_name;
struct WIN_servent WSAservent_port;
+ /* 8K scratch buffer for aliases and friends are hopefully enough */
+ char scratch[8192];
};
-static struct WinSockHeap *heap;
+static struct WinSockHeap *Heap;
+static int HeapHandle;
+static int ScratchPtr;
+#ifndef WINELIB
+#define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
+ GlobalHandleToSel(HeapHandle))
+#else
+#define GET_SEG_PTR(x) (x)
+#endif
+
+#ifndef WINELIB
#pragma pack(4)
+#endif
#define dump_sockaddr(a) \
fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
@@ -93,6 +110,28 @@
inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
ntohs(((struct sockaddr_in *)a)->sin_port))
+static void ResetScratch()
+{
+ ScratchPtr=0;
+}
+
+static void *scratch_alloc(int size)
+{
+ char *ret;
+ if(ScratchPtr+size > sizeof(Heap->scratch))
+ return 0;
+ ret = Heap->scratch + ScratchPtr;
+ ScratchPtr += size;
+ return ret;
+}
+
+static SEGPTR scratch_strdup(char * s)
+{
+ char *ret=scratch_alloc(strlen(s)+1);
+ strcpy(ret,s);
+ return GET_SEG_PTR(ret);
+}
+
static WORD wsaerrno(void)
{
#ifdef DEBUG_WINSOCK
@@ -208,19 +247,70 @@
}
#ifndef WINELIB
-static void CONVERT_HOSTENT(struct WIN_hostent *heap, struct hostent *host)
+static SEGPTR copy_stringlist(char **list)
{
+ SEGPTR *s_list;
+ int i;
+ for(i=0;list[i];i++)
+ ;
+ s_list = scratch_alloc(sizeof(SEGPTR)*(i+1));
+ for(i=0;list[i];i++)
+ {
+ void *copy = scratch_alloc(strlen(list[i])+1);
+ strcpy(copy,list[i]);
+ s_list[i]=GET_SEG_PTR(copy);
+ }
+ s_list[i]=0;
+ return GET_SEG_PTR(s_list);
+}
+
+static void CONVERT_HOSTENT(struct WIN_hostent *heapent, struct hostent *host)
+{
+ SEGPTR *addr_list;
+ int i;
+ ResetScratch();
+ strcpy(heapent->hostname,host->h_name);
+ heapent->h_name = GET_SEG_PTR(heapent->hostname);
+ /* Convert aliases. Have to create array with FAR pointers */
+ if(!host->h_aliases)
+ heapent->h_aliases = 0;
+ else
+ heapent->h_aliases = copy_stringlist(host->h_aliases);
+
+ heapent->h_addrtype = host->h_addrtype;
+ heapent->h_length = host->h_length;
+ for(i=0;host->h_addr_list[i];i++)
+ ;
+ addr_list=scratch_alloc(sizeof(SEGPTR)*(i+1));
+ heapent->h_addr_list = GET_SEG_PTR(addr_list);
+ for(i=0;host->h_addr_list[i];i++)
+ {
+ void *addr=scratch_alloc(host->h_length);
+ memcpy(addr,host->h_addr_list[i],host->h_length);
+ addr_list[i]=GET_SEG_PTR(addr);
+ }
+ addr_list[i]=0;
}
-static void CONVERT_PROTOENT(struct WIN_protoent *heap, struct protoent *proto)
+static void CONVERT_PROTOENT(struct WIN_protoent *heapent,
+ struct protoent *proto)
{
-
+ ResetScratch();
+ heapent->p_name= scratch_strdup(proto->p_name);
+ heapent->p_aliases=proto->p_aliases ?
+ copy_stringlist(proto->p_aliases) : 0;
+ heapent->p_proto = proto->p_proto;
}
-static void CONVERT_SERVENT(struct WIN_servent *heap, struct servent *serv)
+static void CONVERT_SERVENT(struct WIN_servent *heapent, struct servent *serv)
{
-
+ ResetScratch();
+ heapent->s_name = scratch_strdup(serv->s_name);
+ heapent->s_aliases = serv->s_aliases ?
+ copy_stringlist(serv->s_aliases) : 0;
+ heapent->s_port = serv->s_port;
+ heapent->s_proto = scratch_strdup(serv->s_proto);
}
#else
#define CONVERT_HOSTENT(a,b) memcpy(a, &b, sizeof(a))
@@ -339,16 +429,45 @@
return NULL;
}
- strncpy(heap->ntoa_buffer, s, sizeof(heap->ntoa_buffer) );
+ strncpy(Heap->ntoa_buffer, s, sizeof(Heap->ntoa_buffer) );
- return (char *) &heap->ntoa_buffer;
+ return (char *) GET_SEG_PTR(&Heap->ntoa_buffer);
}
-INT WINSOCK_ioctlsocket(SOCKET s, long cmd, u_long *argp)
+INT WINSOCK_ioctlsocket(SOCKET s, u_long cmd, u_long *argp)
{
- dprintf_winsock(stddeb, "WSA_ioctl: socket %d, cmd %ld, ptr %8x\n", s, cmd, (int) argp);
+ long newcmd;
+ u_long *newargp;
+ char *ctlname;
+ dprintf_winsock(stddeb, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s, cmd, (int) argp);
- if (ioctl(s, cmd, argp) < 0) {
+ /* Why can't they all use the same ioctl numbers */
+ newcmd=cmd;
+ newargp=argp;
+ ctlname=0;
+ if(cmd == _IOR('f',127,u_long))
+ {
+ ctlname="FIONREAD";
+ newcmd=FIONREAD;
+ }else
+ if(cmd == _IOW('f',126,u_long) || cmd == _IOR('f',126,u_long))
+ {
+ ctlname="FIONBIO";
+ newcmd=FIONBIO;
+ }else
+ if(cmd == _IOW('f',125,u_long))
+ {
+ ctlname="FIOASYNC";
+ newcmd=FIOASYNC;
+ }
+
+ if(!ctlname)
+ fprintf(stderr,"Unknown winsock ioctl. Trying anyway\n");
+ else
+ dprintf_winsock(stddeb,"Recognized as %s\n", ctlname);
+
+
+ if (ioctl(s, newcmd, newargp) < 0) {
errno_to_wsaerrno();
return SOCKET_ERROR;
}
@@ -485,7 +604,10 @@
return sock;
}
-struct WIN_hostent *WINSOCK_gethostbyaddr(const char *addr, INT len, INT type)
+/*
+struct WIN_hostent *
+*/
+SEGPTR WINSOCK_gethostbyaddr(const char *addr, INT len, INT type)
{
struct hostent *host;
@@ -495,12 +617,15 @@
errno_to_wsaerrno();
return NULL;
}
- CONVERT_HOSTENT(&heap->hostent_addr, host);
+ CONVERT_HOSTENT(&Heap->hostent_addr, host);
- return &heap->hostent_addr;
+ return GET_SEG_PTR(&Heap->hostent_addr);
}
-struct WIN_hostent *WINSOCK_gethostbyname(const char *name)
+/*
+struct WIN_hostent *
+*/
+SEGPTR WINSOCK_gethostbyname(const char *name)
{
struct hostent *host;
@@ -510,9 +635,9 @@
errno_to_wsaerrno();
return NULL;
}
- CONVERT_HOSTENT(&heap->hostent_name, host);
+ CONVERT_HOSTENT(&Heap->hostent_name, host);
- return &heap->hostent_name;
+ return GET_SEG_PTR(&Heap->hostent_name);
}
INT WINSOCK_gethostname(char *name, INT namelen)
@@ -526,7 +651,10 @@
return 0;
}
-struct WIN_protoent *WINSOCK_getprotobyname(char *name)
+/*
+struct WIN_protoent *
+*/
+SEGPTR WINSOCK_getprotobyname(char *name)
{
struct protoent *proto;
@@ -536,12 +664,15 @@
errno_to_wsaerrno();
return NULL;
}
- CONVERT_PROTOENT(&heap->protoent_name, proto);
+ CONVERT_PROTOENT(&Heap->protoent_name, proto);
- return &heap->protoent_name;
+ return GET_SEG_PTR(&Heap->protoent_name);
}
-struct WIN_protoent *WINSOCK_getprotobynumber(INT number)
+/*
+struct WIN_protoent *
+*/
+SEGPTR WINSOCK_getprotobynumber(INT number)
{
struct protoent *proto;
@@ -551,12 +682,15 @@
errno_to_wsaerrno();
return NULL;
}
- CONVERT_PROTOENT(&heap->protoent_number, proto);
+ CONVERT_PROTOENT(&Heap->protoent_number, proto);
- return &heap->protoent_number;
+ return GET_SEG_PTR(&Heap->protoent_number);
}
-struct WIN_servent *WINSOCK_getservbyname(const char *name, const char *proto)
+/*
+struct WIN_servent *
+*/
+SEGPTR WINSOCK_getservbyname(const char *name, const char *proto)
{
struct servent *service;
@@ -569,12 +703,15 @@
errno_to_wsaerrno();
return NULL;
}
- CONVERT_SERVENT(&heap->servent_name, service);
+ CONVERT_SERVENT(&Heap->servent_name, service);
- return &heap->servent_name;
+ return GET_SEG_PTR(&Heap->servent_name);
}
-struct WIN_servent *WINSOCK_getservbyport(INT port, const char *proto)
+/*
+struct WIN_servent *
+*/
+SEGPTR WINSOCK_getservbyport(INT port, const char *proto)
{
struct servent *service;
@@ -584,9 +721,9 @@
errno_to_wsaerrno();
return NULL;
}
- CONVERT_SERVENT(&heap->servent_port, service);
+ CONVERT_SERVENT(&Heap->servent_port, service);
- return &heap->servent_port;
+ return GET_SEG_PTR(&Heap->servent_port);
}
/******************** winsock specific functions ************************
@@ -831,7 +968,7 @@
INT WSAGetLastError(void)
{
- dprintf_winsock(stddeb, "WSA_GetLastError\n");
+ dprintf_winsock(stddeb, "WSA_GetLastError = %x\n", wsa_errno);
return wsa_errno;
}
@@ -886,7 +1023,6 @@
INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
{
- int HeapHandle;
dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);
@@ -903,7 +1039,7 @@
if ((HeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct WinSockHeap))) == 0)
return WSASYSNOTREADY;
- heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
+ Heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
bcopy(&WINSOCK_data, lpWSAData, sizeof(WINSOCK_data));
/* ipc stuff */
diff --git a/miscemu/Imakefile b/miscemu/Imakefile
index a73da1c..74a89df 100644
--- a/miscemu/Imakefile
+++ b/miscemu/Imakefile
@@ -8,8 +8,6 @@
instr.c \
int10.c \
int13.c \
- int15.c \
- int16.c \
int1a.c \
int21.c \
int25.c \
diff --git a/miscemu/Makefile.in b/miscemu/Makefile.in
new file mode 100644
index 0000000..8cf8cce
--- /dev/null
+++ b/miscemu/Makefile.in
@@ -0,0 +1,51 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = miscemu
+
+SRCS = dpmi.c emulate.c instr.c int10.c int13.c \
+ int1a.c int21.c int25.c int26.c int2a.c int2f.c int5c.c interrupts.c \
+ ioports.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index c44a6af..2b63159 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -18,19 +18,16 @@
/**********************************************************************
- * do_int31
+ * INT_Int31Handler
*
- * Handle the DPMI interrupt (int 31h).
+ * Handler for int 31h (DPMI).
*/
-int do_int31( struct sigcontext_struct *context )
+void INT_Int31Handler( struct sigcontext_struct sigcontext )
{
+#define context (&sigcontext)
DWORD dw;
BYTE *ptr;
- dprintf_int( stddeb, "int31 (DPMI): AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES );
-
ResetCflag;
switch(AX)
{
@@ -116,16 +113,27 @@
SetCflag;
break;
+ case 0x0204: /* Get protected mode interrupt vector */
+ dw = (DWORD)INT_GetHandler( BL );
+ CX = HIWORD(dw);
+ DX = LOWORD(dw);
+ break;
+
+ case 0x0205: /* Set protected mode interrupt vector */
+ INT_SetHandler( BL, (SEGPTR)MAKELONG( DX, CX ) );
+ break;
+
case 0x0400: /* Get DPMI version */
- AX = 0x0009; /* DPMI version 0.9 */
+ AX = 0x005a; /* DPMI version 0.90 */
BX = 0x0005; /* Flags: 32-bit, virtual memory */
- CL = 4; /* CPU type: 486 */
+ CL = 3; /* CPU type: 386 */
DX = 0x0102; /* Master and slave interrupt controller base */
break;
case 0x0500: /* Get free memory information */
- memset( PTR_SEG_OFF_TO_LIN( ES, DI ),
- 0xff, 0x30 ); /* No information supported */
+ ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES, DI );
+ *(DWORD *)ptr = 0x00ff0000; /* Largest block available */
+ memset( ptr + 4, 0xff, 0x2c ); /* No other information supported */
break;
case 0x0501: /* Allocate memory block */
@@ -165,9 +173,10 @@
break; /* Just ignore it */
default:
+ INT_BARF( 0x31 );
AX = 0x8001; /* unsupported function */
SetCflag;
break;
}
- return 1;
+#undef context
}
diff --git a/miscemu/instr.c b/miscemu/instr.c
index b025452..3be1990 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -6,55 +6,11 @@
#include <stdio.h>
#include "windows.h"
-#include "dos_fs.h"
#include "ldt.h"
#include "miscemu.h"
#include "registers.h"
-static int do_int(int intnum, struct sigcontext_struct *context)
-{
- switch(intnum)
- {
- case 0x10: return do_int10(context);
-
- case 0x11:
- AX = DOS_GetEquipment();
- return 1;
-
- case 0x12:
- AX = 640;
- return 1; /* get base mem size */
-
- case 0x13: return do_int13(context);
- case 0x15: return do_int15(context);
- case 0x16: return do_int16(context);
- case 0x1a: return do_int1a(context);
- case 0x21: return do_int21(context);
-
- case 0x22:
- AX = 0x1234;
- BX = 0x5678;
- CX = 0x9abc;
- DX = 0xdef0;
- return 1;
-
- case 0x25: return do_int25(context);
- case 0x26: return do_int26(context);
- case 0x2a: return do_int2a(context);
- case 0x2f: return do_int2f(context);
- case 0x31: return do_int31(context);
- case 0x3d: return 1;
- case 0x5c: return do_int5c(context);
-
- default:
- fprintf(stderr,"int%02x: Unimplemented!\n", intnum);
- break;
- }
- return 0;
-}
-
-
/***********************************************************************
* INSTR_EmulateInstruction
*
@@ -62,35 +18,38 @@
*/
BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
{
- int prefix, segprefix, long_op, long_addr;
- BYTE *instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, IP );
+ int prefix, segprefix, repX, long_op, long_addr;
+ BYTE *instr;
+
+ long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
+ instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, long_op ? EIP : IP );
/* First handle any possible prefix */
- long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
- segprefix = 0; /* no prefix */
+ segprefix = -1; /* no prefix */
prefix = 1;
+ repX = 0;
while(prefix)
{
switch(*instr)
{
case 0x2e:
- segprefix = 1; /* CS */
+ segprefix = CS;
break;
case 0x36:
- segprefix = 2; /* SS */
+ segprefix = SS;
break;
case 0x3e:
- segprefix = 3; /* DS */
+ segprefix = DS;
break;
case 0x26:
- segprefix = 4; /* ES */
+ segprefix = ES;
break;
case 0x64:
- segprefix = 5; /* FS */
+ segprefix = FS;
break;
case 0x65:
- segprefix = 6; /* GS */
+ segprefix = GS;
break;
case 0x66:
long_op = !long_op; /* opcode size prefix */
@@ -99,8 +58,12 @@
long_addr = !long_addr; /* addr size prefix */
break;
case 0xf0: /* lock */
+ break;
case 0xf2: /* repne */
+ repX = 1;
+ break;
case 0xf3: /* repe */
+ repX = 2;
break;
default:
prefix = 0; /* no more prefixes */
@@ -117,22 +80,33 @@
switch(*instr)
{
- case 0xcd: /* int <XX> */
- instr++;
- /* FIXME: should check if handler has been changed */
- if (!do_int(*instr, context))
+ case 0xcd: /* int <XX> */
+ if (long_op)
{
- fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
- return FALSE;
- }
- EIP += 2; /* Bypass the int instruction */
+ fprintf(stderr, "int xx from 32-bit code is not supported.\n");
+ return FALSE; /* Unable to emulate it */
+ }
+ else
+ {
+ SEGPTR addr = INT_GetHandler( instr[1] );
+ /* FIXME: should check the stack 'big' bit */
+ WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
+ /* Push the flags and return address on the stack */
+ *(--stack) = FL;
+ *(--stack) = CS;
+ *(--stack) = IP + 2;
+ SP -= 3 * sizeof(WORD);
+ /* Jump to the interrupt handler */
+ CS = HIWORD(addr);
+ EIP = LOWORD(addr);
+ }
break;
- case 0xcf: /* iret */
+ case 0xcf: /* iret */
if (long_op)
{
/* FIXME: should check the stack 'big' bit */
- DWORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
+ DWORD *stack = (DWORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
EIP = *stack++;
CS = *stack++;
EFL = *stack;
@@ -144,59 +118,135 @@
WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
EIP = *stack++;
CS = *stack++;
- EFL = (EFL & 0xffff0000) | *stack;
+ FL = *stack;
SP += 3*sizeof(WORD); /* Pop the return address and flags */
}
break;
- case 0xe4: /* inb al,XX */
- inportb_abs(context);
+ case 0xe4: /* inb al,XX */
+ AL = inport( instr[1], 1 );
EIP += 2;
break;
- case 0xe5: /* in ax,XX */
- inport_abs( context, long_op );
+ case 0xe5: /* in (e)ax,XX */
+ if (long_op) EAX = inport( instr[1], 4 );
+ else AX = inport( instr[1], 2 );
EIP += 2;
break;
- case 0xe6: /* outb XX,al */
- outportb_abs(context);
+ case 0xe6: /* outb XX,al */
+ outport( instr[1], 1, AL );
EIP += 2;
break;
- case 0xe7: /* out XX,ax */
- outport_abs( context, long_op );
- EIP += 2;
+ case 0xe7: /* out XX,(e)ax */
+ if (long_op) outport( instr[1], 4, EAX );
+ else outport( instr[1], 2, AX );
+ EIP += 2;
break;
- case 0xec: /* inb al,dx */
- inportb(context);
+ case 0xec: /* inb al,dx */
+ AL = inport( DX, 1 );
EIP++;
break;
- case 0xed: /* in ax,dx */
- inport( context, long_op );
+ case 0xed: /* in (e)ax,dx */
+ if (long_op) EAX = inport( DX, 4 );
+ else AX = inport( DX, 2 );
EIP++;
break;
- case 0xee: /* outb dx,al */
- outportb(context);
+ case 0xee: /* outb dx,al */
+ outport( DX, 1, AL );
EIP++;
break;
- case 0xef: /* out dx,ax */
- outport( context, long_op );
+ case 0xef: /* out dx,(e)ax */
+ if (long_op) outport( DX, 4, EAX );
+ else outport( DX, 2, AX );
EIP++;
break;
- case 0xfa: /* cli, ignored */
+ case 0xfa: /* cli, ignored */
EIP++;
break;
- case 0xfb: /* sti, ignored */
+ case 0xfb: /* sti, ignored */
EIP++;
break;
+ case 0x6c: /* insb */
+ case 0x6d: /* insw/d */
+ case 0x6e: /* outsb */
+ case 0x6f: /* outsw/d */
+ {
+ int typ = *instr; /* Just in case it's overwritten. */
+ int outp = (typ >= 0x6e);
+ unsigned long count = repX ? (long_addr ? ECX : CX) : 1;
+ int opsize = (typ & 1) ? (long_op ? 4 : 2) : 1;
+ int step = (EFL & 0x400) ? -opsize : +opsize;
+ /* FIXME: Check this, please. */
+ int seg = outp ? (segprefix >= 0 ? segprefix : DS) : ES;
+
+ if (outp)
+ /* FIXME: Check segment readable. */
+ ;
+ else
+ /* FIXME: Check segment writeable. */
+ ;
+
+ if (repX)
+ if (long_addr)
+ ECX = 0;
+ else
+ CX = 0;
+
+ while (count-- > 0)
+ {
+ void *data;
+ if (outp)
+ {
+ data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? ESI : SI);
+ if (long_addr)
+ ESI += step;
+ else
+ SI += step;
+ }
+ else
+ {
+ data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? EDI : DI);
+ if (long_addr)
+ EDI += step;
+ else
+ DI += step;
+ }
+
+ switch (typ)
+ {
+ case 0x6c:
+ *((BYTE *)data) = inport (DX, 1);
+ break;
+ case 0x6d:
+ if (long_op)
+ *((DWORD *)data) = inport (DX, 4);
+ else
+ *((WORD *)data) = inport (DX, 2);
+ break;
+ case 0x6e:
+ outport (DX, 1, *((BYTE *)data));
+ break;
+ case 0x6f:
+ if (long_op)
+ outport (DX, 4, *((DWORD *)data));
+ else
+ outport (DX, 2, *((WORD *)data));
+ break;
+ }
+ }
+ EIP++;
+ break;
+ }
+
default:
fprintf(stderr, "Unexpected Windows program segfault"
" - opcode = %x\n", *instr);
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 501b183..04a1a87 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -7,38 +7,35 @@
/* #define DEBUG_INT */
#include "debug.h"
-void IntBarf(int i, struct sigcontext_struct *context)
+
+/**********************************************************************
+ * INT_Int10Handler
+ *
+ * Handler for int 10h (video).
+ */
+void INT_Int10Handler( struct sigcontext_struct sigcontext )
{
- dprintf_int(stddeb, "int%x: unknown/not implemented parameters:\n", i);
- dprintf_int(stddeb, "int%x: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- i, AX, BX, CX, DX, SI, DI, DS, ES);
-}
+#define context (&sigcontext)
+ switch(AH)
+ {
+ case 0x0f:
+ AL = 0x5b;
+ break;
-int do_int10(struct sigcontext_struct *context)
-{
- dprintf_int(stddeb,"int10: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
-
- switch(AH) {
- case 0x0f:
- AL = 0x5b;
- break;
-
- case 0x12:
- if (BL == 0x10) {
- BX = 0x0003;
- CX = 0x0009;
- }
- break;
+ case 0x12:
+ if (BL == 0x10)
+ {
+ BX = 0x0003;
+ CX = 0x0009;
+ }
+ break;
- case 0x1a:
- BX = 0x0008;
- break;
+ case 0x1a:
+ BX = 0x0008;
+ break;
- default:
- IntBarf(0x10, context);
- };
- return 1;
+ default:
+ INT_BARF( 0x10 );
+ }
+#undef context
}
diff --git a/miscemu/int13.c b/miscemu/int13.c
index e0e62f5..d570768 100644
--- a/miscemu/int13.c
+++ b/miscemu/int13.c
@@ -7,13 +7,17 @@
/* #define DEBUG_INT */
#include "debug.h"
-int do_int13(struct sigcontext_struct *context)
-{
- dprintf_int(stddeb,"int13: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
- switch(AH) {
+/**********************************************************************
+ * INT_Int13Handler
+ *
+ * Handler for int 13h (disk I/O).
+ */
+void INT_Int13Handler( struct sigcontext_struct sigcontext )
+{
+#define context (&sigcontext)
+ switch(AH)
+ {
case 0x00: /* RESET DISK SYSTEM */
case 0x04: /* VERIFY DISK SECTOR(S) */
AH = 0;
@@ -52,7 +56,7 @@
break;
default:
- IntBarf(0x13, context);
- };
- return 1;
+ INT_BARF( 0x13 );
+ }
+#undef context
}
diff --git a/miscemu/int15.c b/miscemu/int15.c
deleted file mode 100644
index 9efc47c..0000000
--- a/miscemu/int15.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "registers.h"
-#include "wine.h"
-#include "miscemu.h"
-#include "stddebug.h"
-/* #define DEBUG_INT */
-#include "debug.h"
-
-int do_int15(struct sigcontext_struct *context)
-{
- switch(AH) {
- case 0xc0:
-
- default:
- IntBarf(0x15, context);
- };
- return 1;
-}
diff --git a/miscemu/int16.c b/miscemu/int16.c
deleted file mode 100644
index b3cc06e..0000000
--- a/miscemu/int16.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "registers.h"
-#include "wine.h"
-#include "miscemu.h"
-#include "stddebug.h"
-/* #define DEBUG_INT */
-#include "debug.h"
-
-int do_int16(struct sigcontext_struct *context)
-{
- switch(AH) {
- case 0xc0:
-
- default:
- IntBarf(0x16, context);
- };
- return 1;
-}
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index 60a29ab..60cf634 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -13,16 +13,20 @@
#define BCD_TO_BIN(x) ((x&15) + (x>>4)*10)
#define BIN_TO_BCD(x) ((x%10) + ((x/10)<<4))
-int do_int1a(struct sigcontext_struct * context){
+
+/**********************************************************************
+ * INT_Int1aHandler
+ *
+ * Handler for int 1ah (date and time).
+ */
+void INT_Int1aHandler( struct sigcontext_struct sigcontext )
+{
+#define context (&sigcontext)
time_t ltime;
DWORD ticks;
struct tm *bdtime;
struct timeval tvs;
- dprintf_int(stddeb,"int1A: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
-
switch(AH) {
case 0:
/* This should give us the (approximately) correct
@@ -68,8 +72,7 @@
break;
default:
- IntBarf(0x1a, context);
- return 1;
- };
- return 1;
+ INT_BARF( 0x1a );
+ }
+#undef context
}
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 078f34e..25b2f8c 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -24,7 +24,6 @@
#include "options.h"
#include "miscemu.h"
#include "stddebug.h"
-/* #define DEBUG_INT */
#include "debug.h"
/* Define the drive parameter block, as used by int21/1F
@@ -196,7 +195,7 @@
return;
}
- AX = 4;
+ AX = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */
CX = 512;
BX = (available / (CX * AX));
@@ -206,8 +205,14 @@
static void GetDriveAllocInfo(struct sigcontext_struct *context)
{
+ int drive;
long size, available;
+ if (DL == 0)
+ drive = DOS_GetDefaultDrive();
+ else
+ drive = DL - 1;
+
if (!DOS_ValidDrive(DL)) {
AX = 4;
CX = 512;
@@ -222,7 +227,7 @@
return;
}
- AX = 4;
+ AX = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */
CX = 512;
DX = (size / (CX * AX));
@@ -233,12 +238,6 @@
Error (0,0,0);
}
-static void GetDefDriveAllocInfo(struct sigcontext_struct *context)
-{
- DX = DOS_GetDefaultDrive();
- GetDriveAllocInfo(context);
-}
-
static void GetDrivePB(struct sigcontext_struct *context, int drive)
{
if(!DOS_ValidDrive(drive))
@@ -260,12 +259,12 @@
dpb->drive_num = dpb->unit_num = drive; /* The same? */
dpb->sector_size = 512;
dpb->high_sector = 1;
- dpb->shift = 0;
+ dpb->shift = drive < 2 ? 0 : 6; /* 6 for HD, 0 for floppy */
dpb->reserved = 0;
dpb->num_FAT = 1;
dpb->dir_entries = 2;
dpb->first_data = 2;
- dpb->high_cluster = 1023;
+ dpb->high_cluster = 64000;
dpb->sectors_in_FAT = 1;
dpb->start_dir = 1;
dpb->driver_head = 0;
@@ -414,7 +413,7 @@
if (fstat(BX, &sbuf) < 0)
{
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
SetCflag;
return;
}
@@ -444,8 +443,8 @@
}
if (CH != 0x08) {
- IntBarf(0x21, context);
- return;
+ INT_BARF( 0x21 );
+ return;
}
switch (CL) {
case 0x60: /* get device parameters */
@@ -469,7 +468,7 @@
ResetCflag;
return;
default:
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
}
}
@@ -508,18 +507,18 @@
static void CreateFile(struct sigcontext_struct *context)
{
- int handle;
-
- if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)),
- O_CREAT | O_TRUNC | O_RDWR )) == -1) {
- errno_to_doserr();
- AX = ExtendedError;
- SetCflag;
- return;
- }
- Error (0,0,0);
- AX = handle;
- ResetCflag;
+ int handle;
+ handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)),
+ O_CREAT | O_TRUNC | O_RDWR, 0666 );
+ if (handle == -1) {
+ errno_to_doserr();
+ AX = ExtendedError;
+ SetCflag;
+ return;
+ }
+ Error (0,0,0);
+ AX = handle;
+ ResetCflag;
}
void OpenExistingFile(struct sigcontext_struct *context)
@@ -725,6 +724,7 @@
memcpy(&dp, dta+0x11, sizeof(dp));
+ dprintf_int(stddeb, "int21: FindNext, dta %p, dp %p\n", dta, dp);
do {
if ((dp = DOS_readdir(dp)) == NULL) {
Error(NoMoreFiles, EC_MediaError , EL_Disk);
@@ -778,17 +778,6 @@
memset(dta + 1 , '?', 11);
*(dta + 0x0c) = ECX & (FA_LABEL | FA_DIREC);
- if (ECX & FA_LABEL) {
- /* return volume label */
-
- if (DOS_GetVolumeLabel(drive) != NULL)
- strncpy(dta + 0x1e, DOS_GetVolumeLabel(drive), 8);
-
- AX = 0;
- ResetCflag;
- return;
- }
-
if ((dp = DOS_opendir(path)) == NULL) {
Error(PathNotFound, EC_MediaError, EL_Disk);
AX = FileNotFound;
@@ -841,7 +830,7 @@
dprintf_int(stddeb,"CreateTempFile %s\n",temp);
- handle = open(DOS_GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR);
+ handle = open(DOS_GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR, 0666);
if (handle == -1) {
Error( WriteProtected, EC_AccessDenied, EL_Disk );
@@ -860,7 +849,7 @@
{
int handle;
- if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR)) == -1) {
+ if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR, 0666)) == -1) {
Error( WriteProtected, EC_AccessDenied, EL_Disk );
AX = WriteProtected;
SetCflag;
@@ -1204,20 +1193,18 @@
extern void LOCAL_PrintHeap (WORD ds);
-/************************************************************************/
-
-int do_int21(struct sigcontext_struct * context)
+/***********************************************************************
+ * DOS3Call (KERNEL.102)
+ */
+void DOS3Call( struct sigcontext_struct sigcontext )
{
+#define context (&sigcontext)
int drive;
- dprintf_int(stddeb,"int21: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
-
if (AH == 0x59)
{
GetExtendedErrorInfo(context);
- return 1;
+ return;
}
else
{
@@ -1255,7 +1242,7 @@
case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
case 0x29: /* PARSE FILENAME INTO FCB */
case 0x2e: /* SET VERIFY FLAG */
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
break;
case 0x2b: /* SET SYSTEM DATE */
@@ -1264,7 +1251,7 @@
"SWITCHAR" - SET SWITCH CHARACTER
"AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
case 0x54: /* GET VERIFY FLAG */
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
break;
case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
@@ -1284,15 +1271,14 @@
break;
case 0x0e: /* SELECT DEFAULT DRIVE */
- if (!DOS_ValidDrive(DL)) {
- Error (InvalidDrive, EC_MediaError, EL_Disk);
- AX = MAX_DOS_DRIVES;
- break;
- } else {
- DOS_SetDefaultDrive(DL);
- AX = MAX_DOS_DRIVES;
- Error(0,0,0);
+ if (!DOS_ValidDrive(DL))
+ Error (InvalidDrive, EC_MediaError, EL_Disk);
+ else
+ {
+ DOS_SetDefaultDrive(DL);
+ Error(0,0,0);
}
+ AL = MAX_DOS_DRIVES;
break;
case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
@@ -1321,7 +1307,8 @@
break;
case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
- GetDefDriveAllocInfo(context);
+ DL = 0;
+ GetDriveAllocInfo(context);
break;
case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
@@ -1359,7 +1346,7 @@
break;
case 0x31: /* TERMINATE AND STAY RESIDENT */
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
break;
case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
@@ -1390,7 +1377,7 @@
break;
default:
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
break;
}
break;
@@ -1541,7 +1528,7 @@
break;
default:
- IntBarf(0x21, context);
+ INT_BARF( 0x21 );
break;
}
break;
@@ -1575,8 +1562,8 @@
case 0x48: /* ALLOCATE MEMORY */
case 0x49: /* FREE MEMORY */
case 0x4a: /* RESIZE MEMORY BLOCK */
- IntBarf(0x21, context);
- break;
+ INT_BARF( 0x21 );
+ break;
case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
WinExec( PTR_SEG_OFF_TO_LIN(DS,DX), SW_NORMAL );
@@ -1597,12 +1584,19 @@
case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */
FindNext(context);
break;
-
- case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
- ES = 0x0;
- BX = 0x0;
- IntBarf(0x21, context);
+
+ case 0x51: /* GET PSP ADDRESS */
+ case 0x62: /* GET PSP ADDRESS */
+ /* FIXME: should we return the original DOS PSP upon */
+ /* Windows startup ? */
+ BX = GetCurrentPDB();
break;
+
+ case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
+ ES = 0x0;
+ BX = 0x0;
+ INT_BARF( 0x21 );
+ break;
case 0x56: /* "RENAME" - RENAME FILE */
RenameFile(context);
@@ -1694,12 +1688,11 @@
break;
case 0x61: /* UNUSED */
- case 0x62: /* GET CURRENT PSP ADDRESS */
case 0x63: /* UNUSED */
case 0x64: /* OS/2 DOS BOX */
case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
- IntBarf(0x21, context);
- break;
+ INT_BARF( 0x21 );
+ break;
case 0x66: /* GLOBAL CODE PAGE TABLE */
switch (AL) {
@@ -1741,26 +1734,18 @@
break;
default:
- IntBarf(0x21, context);
- return 1;
+ INT_BARF( 0x21 );
+ break;
}
}
dprintf_int(stddeb,"ret21: AX %04x, BX %04x, CX %04x, DX %04x, "
"SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
AX, BX, CX, DX, SI, DI, DS, ES, EFL);
- return 1;
+#undef context
}
-/***********************************************************************
- * DOS3Call (KERNEL.102)
- */
-void DOS3Call( struct sigcontext_struct context )
-{
- do_int21( &context );
-}
-
void INT21_Init(void)
{
if ((DosHeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct DosHeap))) == 0)
diff --git a/miscemu/int25.c b/miscemu/int25.c
index 6ebc32e..5427075 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -11,8 +11,14 @@
/* #define DEBUG_INT */
#include "debug.h"
-int do_int25(struct sigcontext_struct *context)
+/**********************************************************************
+ * INT_Int25Handler
+ *
+ * Handler for int 25h (absolute disk read).
+ */
+void INT_Int25Handler( struct sigcontext_struct sigcontext )
{
+#define context (&sigcontext)
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
DWORD begin, length;
@@ -20,11 +26,7 @@
{
SetCflag;
AX = 0x0101; /* unknown unit */
-
- /* push flags on stack */
- SP -= sizeof(WORD);
- setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
- return 1;
+ return;
}
if (CX == 0xffff) {
@@ -48,10 +50,5 @@
*dataptr = 0xf8;
ResetCflag;
-
- /* push flags on stack */
- SP -= sizeof(WORD);
- setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
-
- return 1;
+#undef context
}
diff --git a/miscemu/int26.c b/miscemu/int26.c
index 97bf02d..aa281d7 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -10,8 +10,14 @@
/* #define DEBUG_INT */
#include "debug.h"
-int do_int26(struct sigcontext_struct *context)
+/**********************************************************************
+ * INT_Int26Handler
+ *
+ * Handler for int 26h (absolute disk read).
+ */
+void INT_Int26Handler( struct sigcontext_struct sigcontext )
{
+#define context (&sigcontext)
BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
DWORD begin, length;
@@ -19,11 +25,7 @@
{
SetCflag;
AX = 0x0101; /* unknown unit */
-
- /* push flags on stack */
- SP -= sizeof(WORD);
- setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
- return 1;
+ return;
}
if (CX == 0xffff) {
@@ -40,10 +42,5 @@
"count %ld, buffer %d\n", AL, begin, length, (int) dataptr);
ResetCflag;
-
- /* push flags on stack */
- SP -= sizeof(WORD);
- setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
-
- return 1;
+#undef context
}
diff --git a/miscemu/int2a.c b/miscemu/int2a.c
index 63ed11d..35921fb 100644
--- a/miscemu/int2a.c
+++ b/miscemu/int2a.c
@@ -2,20 +2,27 @@
#include <stdlib.h>
#include "msdos.h"
#include "wine.h"
+#include "registers.h"
#include "miscemu.h"
#include "stddebug.h"
/* #define DEBUG_INT */
#include "debug.h"
-int do_int2a(struct sigcontext_struct *context)
+/**********************************************************************
+ * INT_Int2aHandler
+ *
+ * Handler for int 2ah (network).
+ */
+void INT_Int2aHandler( struct sigcontext_struct sigcontext )
{
- switch((context->sc_eax >> 8) & 0xff)
- {
- case 0x00: /* NETWORK INSTALLATION CHECK */
- break;
+#define context (&sigcontext)
+ switch(AH)
+ {
+ case 0x00: /* NETWORK INSTALLATION CHECK */
+ break;
- default:
- IntBarf(0x2a, context);
- };
- return 1;
+ default:
+ INT_BARF( 0x2a );
+ }
+#undef context
}
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index ad797d1..88bd229 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -9,35 +9,37 @@
/* #define DEBUG_INT */
#include "debug.h"
-int do_int2f_16(struct sigcontext_struct *context);
+static void do_int2f_16(struct sigcontext_struct *context);
-int do_int2f(struct sigcontext_struct *context)
+/**********************************************************************
+ * INT_Int2fHandler
+ *
+ * Handler for int 2fh (multiplex).
+ */
+void INT_Int2fHandler( struct sigcontext_struct sigcontext )
{
- dprintf_int(stddeb,"int2f: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
-
- switch(AH)
- {
+#define context (&sigcontext)
+ switch(AH)
+ {
case 0x10:
AL = 0xff; /* share is installed */
break;
case 0x15: /* mscdex */
/* ignore requests */
- return 1;
+ break;
case 0x16:
- return do_int2f_16(context);
-
+ do_int2f_16( context );
+ break;
default:
- IntBarf(0x2f, context);
- };
- return 1;
+ INT_BARF( 0x2f );
+ }
+#undef context
}
-int do_int2f_16(struct sigcontext_struct *context)
+static void do_int2f_16(struct sigcontext_struct *context)
{
switch(AL)
{
@@ -51,6 +53,9 @@
CX = Options.enhanced ? 3 : 2;
break;
+ case 0x80: /* Release time-slice */
+ break; /* nothing to do */
+
case 0x86: /* DPMI detect mode */
AX = 0; /* Running under DPMI */
break;
@@ -58,17 +63,16 @@
case 0x87: /* DPMI installation check */
AX = 0x0000; /* DPMI Installed */
BX = 0x0001; /* 32bits available */
- CX = 0x04; /* processor 486 */
- DX = 0x0009; /* DPMI major/minor 0.9 */
+ CL = 0x03; /* processor 386 */
+ DX = 0x005a; /* DPMI major/minor 0.90 */
SI = 0; /* # of para. of DOS extended private data */
ES = 0; /* ES:DI is DPMI switch entry point */
DI = 0;
break;
default:
- IntBarf(0x2f, context);
+ INT_BARF( 0x2f );
}
- return 1;
}
diff --git a/miscemu/int5c.c b/miscemu/int5c.c
index 0bd1fd1..ad94c25 100644
--- a/miscemu/int5c.c
+++ b/miscemu/int5c.c
@@ -13,21 +13,13 @@
/***********************************************************************
- * do_int5c
- */
-int do_int5c(struct sigcontext_struct * context)
-{
- dprintf_int(stddeb,"NetBiosCall: AX %04x, BX %04x, CX %04x, DX %04x, "
- "SI %04x, DI %04x, DS %04x, ES %04x\n",
- AX, BX, CX, DX, SI, DI, DS, ES);
- return 0;
-}
-
-
-/***********************************************************************
* NetBIOSCall (KERNEL.103)
+ *
+ * Also handler for interrupt 5c.
*/
-void NetBIOSCall( struct sigcontext_struct context )
+void NetBIOSCall( struct sigcontext_struct sigcontext )
{
- do_int5c( &context );
+#define context (&sigcontext)
+ INT_BARF( 0x5c );
+#undef context
}
diff --git a/miscemu/interrupts.c b/miscemu/interrupts.c
index 01f957e..b576424 100644
--- a/miscemu/interrupts.c
+++ b/miscemu/interrupts.c
@@ -6,7 +6,10 @@
#include "windows.h"
#include "miscemu.h"
+#include "dos_fs.h"
#include "module.h"
+#include "registers.h"
+#include "stackframe.h"
#include "stddebug.h"
#include "debug.h"
@@ -21,15 +24,17 @@
*/
BOOL INT_Init(void)
{
- SEGPTR addr, dummyHandler;
WORD vector;
HMODULE hModule = GetModuleHandle( "WINPROCS" );
- dummyHandler = MODULE_GetEntryPoint( hModule, FIRST_INTERRUPT_ORDINAL+256);
for (vector = 0; vector < 256; vector++)
{
- addr = MODULE_GetEntryPoint( hModule, FIRST_INTERRUPT_ORDINAL+vector );
- INT_Vectors[vector] = addr ? addr : dummyHandler;
+ if (!(INT_Vectors[vector] = MODULE_GetEntryPoint( hModule,
+ FIRST_INTERRUPT_ORDINAL+vector )))
+ {
+ fprintf(stderr,"Internal error: no vector for int %02x\n",vector);
+ return FALSE;
+ }
}
return TRUE;
}
@@ -42,9 +47,6 @@
*/
SEGPTR INT_GetHandler( BYTE intnum )
{
- dprintf_int( stddeb, "Get interrupt vector %02x -> %04x:%04x\n",
- intnum, HIWORD(INT_Vectors[intnum]),
- LOWORD(INT_Vectors[intnum]) );
return INT_Vectors[intnum];
}
@@ -65,126 +67,61 @@
/**********************************************************************
* INT_DummyHandler
*/
-void INT_DummyHandler( struct sigcontext_struct context )
+void INT_DummyHandler( struct sigcontext_struct sigcontext )
{
- dprintf_int( stddeb, "Dummy handler called!\n" );
-}
-
-/**********************************************************************
- * INT_Int10Handler
- */
-void INT_Int10Handler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 10 called indirectly through handler!\n" );
- do_int10( &context );
+#define context (&sigcontext)
+ INT_BARF( CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL );
+#undef context
}
/**********************************************************************
- * INT_Int13Handler
+ * INT_Int11Handler
+ *
+ * Handler for int 11h (get equipment list).
*/
-void INT_Int13Handler( struct sigcontext_struct context )
+void INT_Int11Handler( struct sigcontext_struct sigcontext )
{
- dprintf_int( stddeb, "int 13 called indirectly through handler!\n" );
- do_int13( &context );
+#define context (&sigcontext)
+ AX = DOS_GetEquipment();
+#undef context
+}
+
+
+/**********************************************************************
+ * INT_Int12Handler
+ *
+ * Handler for int 12h (get memory size).
+ */
+void INT_Int12Handler( struct sigcontext_struct sigcontext )
+{
+#define context (&sigcontext)
+ AX = 640;
+#undef context
}
/**********************************************************************
* INT_Int15Handler
+ *
+ * Handler for int 15h.
*/
-void INT_Int15Handler( struct sigcontext_struct context )
+void INT_Int15Handler( struct sigcontext_struct sigcontext )
{
- dprintf_int( stddeb, "int 15 called indirectly through handler!\n" );
- do_int15( &context );
+#define context (&sigcontext)
+ INT_BARF( 0x15 );
+#undef context
}
/**********************************************************************
* INT_Int16Handler
+ *
+ * Handler for int 16h (keyboard).
*/
-void INT_Int16Handler( struct sigcontext_struct context )
+void INT_Int16Handler( struct sigcontext_struct sigcontext )
{
- dprintf_int( stddeb, "int 16 called indirectly through handler!\n" );
- do_int16( &context );
-}
-
-
-/**********************************************************************
- * INT_Int1aHandler
- */
-void INT_Int1aHandler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 1a called indirectly through handler!\n" );
- do_int1a( &context );
-}
-
-
-/**********************************************************************
- * INT_Int21Handler
- */
-void INT_Int21Handler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 21 called indirectly through handler!\n" );
- do_int21( &context );
-}
-
-
-/**********************************************************************
- * INT_Int25Handler
- */
-void INT_Int25Handler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 25 called indirectly through handler!\n" );
- do_int25( &context );
-}
-
-
-/**********************************************************************
- * INT_Int26Handler
- */
-void INT_Int26Handler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 26 called indirectly through handler!\n" );
- do_int26( &context );
-}
-
-
-/**********************************************************************
- * INT_Int2aHandler
- */
-void INT_Int2aHandler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 2a called indirectly through handler!\n" );
- do_int2a( &context );
-}
-
-
-/**********************************************************************
- * INT_Int2fHandler
- */
-void INT_Int2fHandler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 2f called indirectly through handler!\n" );
- do_int2f( &context );
-}
-
-
-/**********************************************************************
- * INT_Int31Handler
- */
-void INT_Int31Handler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 31 called indirectly through handler!\n" );
- do_int31( &context );
-}
-
-
-/**********************************************************************
- * INT_Int5cHandler
- */
-void INT_Int5cHandler( struct sigcontext_struct context )
-{
- dprintf_int( stddeb, "int 5c called indirectly through handler!\n" );
- do_int5c( &context );
+#define context (&sigcontext)
+ INT_BARF( 0x16 );
+#undef context
}
diff --git a/miscemu/ioports.c b/miscemu/ioports.c
index 161ca06..3ea012a 100644
--- a/miscemu/ioports.c
+++ b/miscemu/ioports.c
@@ -1,87 +1,86 @@
+/*
+ * Emulation of processor ioports.
+ *
+ * Copyright 1995 Morten Welinder
+ */
+
+/* Known problems:
+ - only a few ports are emulated.
+ - real-time clock in "cmos" is bogus. A nifty alarm() setup could
+ fix that, I guess.
+*/
+
+
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include "registers.h"
-#include "wine.h"
+#include "windows.h"
#include "stddebug.h"
/* #define DEBUG_INT */
#include "debug.h"
static BYTE cmosaddress;
-static BYTE cmosimage[64] = {
- 0x27, 0x34, 0x31, 0x47, 0x16, 0x15, 0x00, 0x01,
- 0x04, 0x94, 0x26, 0x02, 0x50, 0x80, 0x00, 0x00,
- 0x40, 0xb1, 0x00, 0x9c, 0x01, 0x80, 0x02, 0x00,
- 0x1c, 0x00, 0x00, 0xad, 0x02, 0x10, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0x58,
- 0x00, 0x1c, 0x19, 0x81, 0x00, 0x0e, 0x00, 0x80,
- 0x1b, 0x7b, 0x21, 0x00, 0x00, 0x00, 0x05, 0x5f };
-
-void inportb(struct sigcontext_struct *context)
+static BYTE cmosimage[64] =
{
- dprintf_int(stddeb, "IO: inb (%x)\n", DX);
+ 0x27, 0x34, 0x31, 0x47, 0x16, 0x15, 0x00, 0x01,
+ 0x04, 0x94, 0x26, 0x02, 0x50, 0x80, 0x00, 0x00,
+ 0x40, 0xb1, 0x00, 0x9c, 0x01, 0x80, 0x02, 0x00,
+ 0x1c, 0x00, 0x00, 0xad, 0x02, 0x10, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0x58,
+ 0x00, 0x1c, 0x19, 0x81, 0x00, 0x0e, 0x00, 0x80,
+ 0x1b, 0x7b, 0x21, 0x00, 0x00, 0x00, 0x05, 0x5f
+};
- switch(DX) {
- case 0x70:
- AL = cmosaddress;
- break;
- case 0x71:
- AL = cmosimage[cmosaddress & 0x3f];
- break;
- default:
- }
-}
-void inport( struct sigcontext_struct *context, int long_op )
+DWORD inport( int port, int count )
{
- dprintf_int(stdnimp, "IO: in (%x)\n", DX);
- if (long_op) EAX = 0xffffffff;
- else AX = 0xffff;
-}
+ DWORD res = 0;
+ BYTE b;
-void inportb_abs(struct sigcontext_struct *context)
-{
- dprintf_int(stdnimp, "IO: in (%x)\n", *(BYTE *)(EIP+1));
- AL = 0xff;
-}
+ dprintf_int(stddeb, "IO: %d bytes from port 0x%02x\n", count, port );
-void inport_abs( struct sigcontext_struct *context, int long_op )
-{
- dprintf_int(stdnimp, "IO: in (%x)\n", *(BYTE *)(EIP+1));
- if (long_op) EAX = 0xffffffff;
- else AX = 0xffff;
-}
-
-void outportb(struct sigcontext_struct *context)
-{
- dprintf_int(stdnimp, "IO: outb (%x), %x\n", DX, AX);
-
- switch (EDX & 0xffff)
+ while (count-- > 0)
+ {
+ switch (port++)
{
- case 0x70:
- cmosaddress = AL & 0x7f;
- break;
- case 0x71:
- cmosimage[cmosaddress & 0x3f] = AL;
- break;
- default:
+ case 0x70:
+ b = cmosaddress;
+ break;
+ case 0x71:
+ b = cmosimage[cmosaddress & 0x3f];
+ break;
+ default:
+ b = 0xff;
}
+ res = (res << 8) | b;
+ }
+ return res;
}
-void outport( struct sigcontext_struct *context, int long_op )
-{
- dprintf_int(stdnimp, "IO: out (%x), %lx\n", DX, long_op ? EAX : AX);
-}
-void outportb_abs(struct sigcontext_struct *context)
+void outport( int port, int count, DWORD value )
{
- dprintf_int(stdnimp, "IO: out (%x), %x\n", *(BYTE *)(EIP+1), AL);
-}
+ BYTE b;
-void outport_abs( struct sigcontext_struct *context, int long_op )
-{
- dprintf_int(stdnimp, "IO: out (%x), %lx\n", *(BYTE *)(EIP+1),
- long_op ? EAX : AX);
+ dprintf_int( stddeb, "IO: 0x%lx (%d bytes) to port 0x%02x\n",
+ value, count, port );
+
+ while (count-- > 0)
+ {
+ b = value & 0xff;
+ value >>= 8;
+ switch (port++)
+ {
+ case 0x70:
+ cmosaddress = b & 0x7f;
+ break;
+ case 0x71:
+ cmosimage[cmosaddress & 0x3f] = b;
+ break;
+ default:
+ /* Rien du tout. */
+ }
+ }
}
diff --git a/multimedia/Imakefile b/multimedia/Imakefile
index c7db934..582e384 100644
--- a/multimedia/Imakefile
+++ b/multimedia/Imakefile
@@ -4,11 +4,13 @@
SRCS = \
audio.c \
+ joystick.c \
mcianim.c \
mcicda.c \
midi.c \
mmaux.c \
- mmsystem.c
+ mmsystem.c \
+ time.c
OBJS = $(SRCS:.c=.o)
diff --git a/multimedia/Makefile.in b/multimedia/Makefile.in
new file mode 100644
index 0000000..ceec464
--- /dev/null
+++ b/multimedia/Makefile.in
@@ -0,0 +1,51 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = multimedia
+
+SRCS = audio.c joystick.c mcianim.c mcicda.c midi.c mmaux.c \
+ mmsystem.c time.c
+
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/multimedia/joystick.c b/multimedia/joystick.c
new file mode 100644
index 0000000..9eff801
--- /dev/null
+++ b/multimedia/joystick.c
@@ -0,0 +1,98 @@
+/*
+ * MMSYTEM functions
+ *
+ * Copyright 1993 Martin Ayotte
+ */
+
+#ifndef WINELIB
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "windows.h"
+#include "ldt.h"
+#include "callback.h"
+#include "user.h"
+#include "driver.h"
+#include "mmsystem.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/**************************************************************************
+ * JoyGetNumDevs [MMSYSTEM.101]
+ */
+WORD JoyGetNumDevs(void)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoyGetNumDevs();\n");
+ return 0;
+}
+
+/**************************************************************************
+ * JoyGetDevCaps [MMSYSTEM.102]
+ */
+WORD JoyGetDevCaps(WORD wID, LPJOYCAPS lpCaps, WORD wSize)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoyGetDevCaps(%04X, %p, %d);\n",
+ wID, lpCaps, wSize);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+ * JoyGetPos [MMSYSTEM.103]
+ */
+WORD JoyGetPos(WORD wID, LPJOYINFO lpInfo)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoyGetPos(%04X, %p);\n", wID, lpInfo);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+ * JoyGetThreshold [MMSYSTEM.104]
+ */
+WORD JoyGetThreshold(WORD wID, LPWORD lpThreshold)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoyGetThreshold(%04X, %p);\n", wID, lpThreshold);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+ * JoyReleaseCapture [MMSYSTEM.105]
+ */
+WORD JoyReleaseCapture(WORD wID)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoyReleaseCapture(%04X);\n", wID);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+ * JoySetCapture [MMSYSTEM.106]
+ */
+WORD JoySetCapture(HWND hWnd, WORD wID, WORD wPeriod, BOOL bChanged)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoySetCapture(%04X, %04X, %d, %d);\n",
+ hWnd, wID, wPeriod, bChanged);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+ * JoySetThreshold [MMSYSTEM.107]
+ */
+WORD JoySetThreshold(WORD wID, WORD wThreshold)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoySetThreshold(%04X, %d);\n", wID, wThreshold);
+ return MMSYSERR_NODRIVER;
+}
+
+/**************************************************************************
+ * JoySetCalibration [MMSYSTEM.109]
+ */
+WORD JoySetCalibration(WORD wID)
+{
+ fprintf(stdnimp, "EMPTY STUB !!! JoySetCalibration(%04X);\n", wID);
+ return MMSYSERR_NODRIVER;
+}
+
+#endif
diff --git a/multimedia/midi.c b/multimedia/midi.c
index 0a61f36..faa61b5 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -1227,16 +1227,6 @@
/**************************************************************************
-* modGetPosition [internal]
-*/
-static DWORD modGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
-{
- dprintf_midi(stddeb, "modGetposition(%u, %p, %08lX);\n", wDevID, lpTime, uSize);
- return MMSYSERR_NOTENABLED;
-}
-
-
-/**************************************************************************
* modMessage [sample driver]
*/
DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 2a01641..0d130a0 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -25,40 +25,21 @@
static int InstalledListLen;
static LPSTR lpInstallNames = NULL;
-static BOOL mmTimeStarted = FALSE;
-static MMTIME mmSysTimeMS;
-static MMTIME mmSysTimeSMPTE;
-
-typedef struct tagTIMERENTRY {
- WORD wDelay;
- WORD wResol;
- FARPROC lpFunc;
- DWORD dwUser;
- WORD wFlags;
- WORD wTimerID;
- WORD wCurTime;
- struct tagTIMERENTRY *Next;
- struct tagTIMERENTRY *Prev;
- } TIMERENTRY;
-typedef TIMERENTRY *LPTIMERENTRY;
-
-static LPTIMERENTRY lpTimerList = NULL;
-
static MCI_OPEN_DRIVER_PARMS mciDrv[MAXMCIDRIVERS];
UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize);
LONG DrvDefDriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2);
+ DWORD dwParam1, DWORD dwParam2);
LONG WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2);
+ DWORD dwParam1, DWORD dwParam2);
LONG MIDI_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2);
+ DWORD dwParam1, DWORD dwParam2);
LONG CDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2);
+ DWORD dwParam1, DWORD dwParam2);
LONG ANIM_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2);
+ DWORD dwParam1, DWORD dwParam2);
/**************************************************************************
* MMSYSTEM_WEP [MMSYSTEM.1]
@@ -242,81 +223,6 @@
}
/**************************************************************************
-* JoyGetNumDevs [MMSYSTEM.101]
-*/
-WORD JoyGetNumDevs()
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoyGetNumDevs();\n");
- return 0;
-}
-
-/**************************************************************************
-* JoyGetDevCaps [MMSYSTEM.102]
-*/
-WORD JoyGetDevCaps(WORD wID, LPJOYCAPS lpCaps, WORD wSize)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoyGetDevCaps(%04X, %p, %d);\n",
- wID, lpCaps, wSize);
- return MMSYSERR_NODRIVER;
-}
-
-/**************************************************************************
-* JoyGetPos [MMSYSTEM.103]
-*/
-WORD JoyGetPos(WORD wID, LPJOYINFO lpInfo)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoyGetPos(%04X, %p);\n", wID, lpInfo);
- return MMSYSERR_NODRIVER;
-}
-
-/**************************************************************************
-* JoyGetThreshold [MMSYSTEM.104]
-*/
-WORD JoyGetThreshold(WORD wID, LPWORD lpThreshold)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoyGetThreshold(%04X, %p);\n", wID, lpThreshold);
- return MMSYSERR_NODRIVER;
-}
-
-/**************************************************************************
-* JoyReleaseCapture [MMSYSTEM.105]
-*/
-WORD JoyReleaseCapture(WORD wID)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoyReleaseCapture(%04X);\n", wID);
- return MMSYSERR_NODRIVER;
-}
-
-/**************************************************************************
-* JoySetCapture [MMSYSTEM.106]
-*/
-WORD JoySetCapture(HWND hWnd, WORD wID, WORD wPeriod, BOOL bChanged)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoySetCapture(%04X, %04X, %d, %d);\n",
- hWnd, wID, wPeriod, bChanged);
- return MMSYSERR_NODRIVER;
-}
-
-/**************************************************************************
-* JoySetThreshold [MMSYSTEM.107]
-*/
-WORD JoySetThreshold(WORD wID, WORD wThreshold)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoySetThreshold(%04X, %d);\n", wID, wThreshold);
- return MMSYSERR_NODRIVER;
-}
-
-/**************************************************************************
-* JoySetCalibration [MMSYSTEM.109]
-*/
-WORD JoySetCalibration(WORD wID)
-{
- fprintf(stdnimp, "EMPTY STUB !!! JoySetCalibration(%04X);\n", wID);
- return MMSYSERR_NODRIVER;
-}
-
-
-/**************************************************************************
* auxGetNumDevs [MMSYSTEM.350]
*/
UINT auxGetNumDevs()
@@ -1930,7 +1836,7 @@
lpDesc = (LPWAVEOPENDESC) USER_HEAP_LIN_ADDR(hWaveIn);
if (lpDesc == NULL) return MMSYSERR_INVALHANDLE;
return widMessage(0, WIDM_GETPOS, lpDesc->dwInstance,
- (DWORD)lpTime, (DWORD)uSize);
+ (DWORD)lpTime, (DWORD)uSize);
}
@@ -1949,7 +1855,7 @@
* waveInMessage [MMSYSTEM.514]
*/
DWORD waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
LPWAVEOPENDESC lpDesc;
dprintf_mmsys(stddeb, "waveInMessage(%04X, %04X, %08lX, %08lX)\n",
@@ -1961,161 +1867,7 @@
/**************************************************************************
-* MMSysTimeCallback [internal]
-*/
-WORD FAR PASCAL MMSysTimeCallback(HWND hWnd, WORD wMsg, int nID, DWORD dwTime)
-{
- LPTIMERENTRY lpTimer = lpTimerList;
- mmSysTimeMS.u.ms += 33;
- mmSysTimeSMPTE.u.smpte.frame++;
- while (lpTimer != NULL) {
- lpTimer->wCurTime--;
- if (lpTimer->wCurTime == 0) {
- lpTimer->wCurTime = lpTimer->wDelay;
- if (lpTimer->lpFunc != (FARPROC)NULL) {
- dprintf_mmtime(stddeb,"MMSysTimeCallback // before CallBack16 !\n");
- CallTimeFuncProc( lpTimer->lpFunc,
- lpTimer->wTimerID, 0,
- lpTimer->dwUser, 0, 0 );
- dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
- fflush(stdout);
- }
- if (lpTimer->wFlags & TIME_ONESHOT)
- timeKillEvent(lpTimer->wTimerID);
- }
- lpTimer = lpTimer->Next;
- }
- return 0;
-}
-
-/**************************************************************************
-* StartMMTime [internal]
-*/
-void StartMMTime()
-{
- if (!mmTimeStarted) {
- mmTimeStarted = TRUE;
- mmSysTimeMS.wType = TIME_MS;
- mmSysTimeMS.u.ms = 0;
- mmSysTimeSMPTE.wType = TIME_SMPTE;
- mmSysTimeSMPTE.u.smpte.hour = 0;
- mmSysTimeSMPTE.u.smpte.min = 0;
- mmSysTimeSMPTE.u.smpte.sec = 0;
- mmSysTimeSMPTE.u.smpte.frame = 0;
- mmSysTimeSMPTE.u.smpte.fps = 0;
- mmSysTimeSMPTE.u.smpte.dummy = 0;
- SetTimer(0, 1, 33, (FARPROC)MMSysTimeCallback);
- }
-}
-
-/**************************************************************************
-* timeGetSystemTime [MMSYSTEM.601]
-*/
-WORD timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
-{
- dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
- if (!mmTimeStarted) StartMMTime();
- return 0;
-}
-
-/**************************************************************************
-* timeSetEvent [MMSYSTEM.602]
-*/
-WORD timeSetEvent(WORD wDelay, WORD wResol,
- LPTIMECALLBACK lpFunc,
- DWORD dwUser, WORD wFlags)
-{
- WORD wNewID = 0;
- LPTIMERENTRY lpNewTimer;
- LPTIMERENTRY lpTimer = lpTimerList;
- dprintf_mmsys(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
- wDelay, wResol, lpFunc, dwUser, wFlags);
- if (!mmTimeStarted) StartMMTime();
- lpNewTimer = (LPTIMERENTRY) malloc(sizeof(TIMERENTRY));
- if (lpNewTimer == NULL) return 0;
- while (lpTimer != NULL) {
- wNewID = max(wNewID, lpTimer->wTimerID);
- if (lpTimer->Next == NULL) break;
- lpTimer = lpTimer->Next;
- }
- if (lpTimerList == NULL) {
- lpTimerList = lpNewTimer;
- lpNewTimer->Prev = NULL;
- }
- else {
- lpTimer->Next = lpNewTimer;
- lpNewTimer->Prev = lpTimer;
- }
- lpNewTimer->Next = NULL;
- lpNewTimer->wTimerID = wNewID + 1;
- lpNewTimer->wCurTime = wDelay;
- lpNewTimer->wDelay = wDelay;
- lpNewTimer->wResol = wResol;
- lpNewTimer->lpFunc = (FARPROC)lpFunc;
- lpNewTimer->dwUser = dwUser;
- lpNewTimer->wFlags = wFlags;
- return lpNewTimer->wTimerID;
-}
-
-/**************************************************************************
-* timeKillEvent [MMSYSTEM.603]
-*/
-WORD timeKillEvent(WORD wID)
-{
- LPTIMERENTRY lpTimer = lpTimerList;
- while (lpTimer != NULL) {
- if (wID == lpTimer->wTimerID) {
- if (lpTimer->Prev != NULL) lpTimer->Prev->Next = lpTimer->Next;
- if (lpTimer->Next != NULL) lpTimer->Next->Prev = lpTimer->Prev;
- free(lpTimer);
- return TRUE;
- }
- lpTimer = lpTimer->Next;
- }
- return 0;
-}
-
-/**************************************************************************
-* timeGetDevCaps [MMSYSTEM.604]
-*/
-WORD timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
-{
- dprintf_mmsys(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
- return 0;
-}
-
-/**************************************************************************
-* timeBeginPeriod [MMSYSTEM.605]
-*/
-WORD timeBeginPeriod(WORD wPeriod)
-{
- dprintf_mmsys(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
- if (!mmTimeStarted) StartMMTime();
- return 0;
-}
-
-/**************************************************************************
-* timeEndPeriod [MMSYSTEM.606]
-*/
-WORD timeEndPeriod(WORD wPeriod)
-{
- dprintf_mmsys(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
- return 0;
-}
-
-/**************************************************************************
-* timeGetTime [MMSYSTEM.607]
-*/
-DWORD timeGetTime()
-{
- dprintf_mmsys(stddeb, "timeGetTime(); !\n");
- if (!mmTimeStarted) StartMMTime();
- return 0;
-}
-
-
-/**************************************************************************
-* mmioOpen [MMSYSTEM.1210]
+* mmioOpen [MMSYSTEM.1210]
*/
HMMIO mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwOpenFlags)
{
@@ -2134,13 +1886,12 @@
lpmminfo->dwReserved2 = MAKELONG(hFile, 0);
GlobalUnlock(hmmio);
dprintf_mmsys(stddeb, "mmioOpen // return hmmio=%04X\n", hmmio);
- return (HMMIO)hmmio;
+ return hmmio;
}
-
/**************************************************************************
-* mmioClose [MMSYSTEM.1211]
+* mmioClose [MMSYSTEM.1211]
*/
UINT mmioClose(HMMIO hmmio, UINT uFlags)
{
@@ -2157,7 +1908,7 @@
/**************************************************************************
-* mmioRead [MMSYSTEM.1212]
+* mmioRead [MMSYSTEM.1212]
*/
LONG mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
{
@@ -2175,7 +1926,7 @@
/**************************************************************************
-* mmioWrite [MMSYSTEM.1213]
+* mmioWrite [MMSYSTEM.1213]
*/
LONG mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
{
@@ -2190,7 +1941,7 @@
}
/**************************************************************************
-* mmioSeek [MMSYSTEM.1214]
+* mmioSeek [MMSYSTEM.1214]
*/
LONG mmioSeek(HMMIO hmmio, LONG lOffset, int iOrigin)
{
@@ -2208,7 +1959,7 @@
}
/**************************************************************************
-* mmioGetInfo [MMSYSTEM.1215]
+* mmioGetInfo [MMSYSTEM.1215]
*/
UINT mmioGetInfo(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags)
{
@@ -2222,7 +1973,7 @@
}
/**************************************************************************
-* mmioSetInfo [MMSYSTEM.1216]
+* mmioSetInfo [MMSYSTEM.1216]
*/
UINT mmioSetInfo(HMMIO hmmio, const MMIOINFO FAR* lpmmioinfo, UINT uFlags)
{
@@ -2245,7 +1996,7 @@
}
/**************************************************************************
-* mmioFlush [MMSYSTEM.1218]
+* mmioFlush [MMSYSTEM.1218]
*/
UINT mmioFlush(HMMIO hmmio, UINT uFlags)
{
@@ -2258,7 +2009,7 @@
}
/**************************************************************************
-* mmioAdvance [MMSYSTEM.1219]
+* mmioAdvance [MMSYSTEM.1219]
*/
UINT mmioAdvance(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags)
{
@@ -2311,7 +2062,7 @@
}
/**************************************************************************
-* mmioDescend [MMSYSTEM.1223]
+* mmioDescend [MMSYSTEM.1223]
*/
UINT mmioDescend(HMMIO hmmio, MMCKINFO FAR* lpck,
const MMCKINFO FAR* lpckParent, UINT uFlags)
@@ -2372,7 +2123,7 @@
}
/**************************************************************************
-* mmioAscend [MMSYSTEM.1224]
+* mmioAscend [MMSYSTEM.1224]
*/
UINT mmioAscend(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags)
{
@@ -2391,7 +2142,7 @@
/**************************************************************************
-* mmioRename [MMSYSTEM.1226]
+* mmioRename [MMSYSTEM.1226]
*/
UINT mmioRename(LPCSTR szFileName, LPCSTR szNewFileName,
MMIOINFO FAR* lpmmioinfo, DWORD dwRenameFlags)
@@ -2402,7 +2153,7 @@
}
/**************************************************************************
-* DrvOpen [MMSYSTEM.1100]
+* DrvOpen [MMSYSTEM.1100]
*/
HDRVR DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
{
@@ -2413,7 +2164,7 @@
/**************************************************************************
-* DrvClose [MMSYSTEM.1101]
+* DrvClose [MMSYSTEM.1101]
*/
LRESULT DrvClose(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
{
diff --git a/multimedia/time.c b/multimedia/time.c
new file mode 100644
index 0000000..bfa5abc
--- /dev/null
+++ b/multimedia/time.c
@@ -0,0 +1,198 @@
+/*
+ * MMSYTEM time functions
+ *
+ * Copyright 1993 Martin Ayotte
+ */
+
+#ifndef WINELIB
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "windows.h"
+#include "ldt.h"
+#include "callback.h"
+#include "user.h"
+#include "driver.h"
+#include "mmsystem.h"
+#include "selectors.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static BOOL mmTimeStarted = FALSE;
+static MMTIME mmSysTimeMS;
+static MMTIME mmSysTimeSMPTE;
+
+typedef struct tagTIMERENTRY {
+ WORD wDelay;
+ WORD wResol;
+ FARPROC lpFunc;
+ DWORD dwUser;
+ WORD wFlags;
+ WORD wTimerID;
+ WORD wCurTime;
+ struct tagTIMERENTRY *Next;
+ struct tagTIMERENTRY *Prev;
+} TIMERENTRY, *LPTIMERENTRY;
+
+static LPTIMERENTRY lpTimerList = NULL;
+
+/**************************************************************************
+ * MMSysTimeCallback [internal]
+ */
+WORD MMSysTimeCallback(HWND hWnd, WORD wMsg, INT nID, DWORD dwTime)
+{
+ LPTIMERENTRY lpTimer = lpTimerList;
+ mmSysTimeMS.u.ms += 33;
+ mmSysTimeSMPTE.u.smpte.frame++;
+ while (lpTimer != NULL) {
+ lpTimer->wCurTime--;
+ if (lpTimer->wCurTime == 0) {
+ lpTimer->wCurTime = lpTimer->wDelay;
+ if (lpTimer->lpFunc != (FARPROC) NULL) {
+ dprintf_mmtime(stddeb, "MMSysTimeCallback // before CallBack16 !\n");
+ CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID, 0,
+ lpTimer->dwUser, 0, 0);
+ dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
+ fflush(stdout);
+ }
+ if (lpTimer->wFlags & TIME_ONESHOT)
+ timeKillEvent(lpTimer->wTimerID);
+ }
+ lpTimer = lpTimer->Next;
+ }
+ return 0;
+}
+
+/**************************************************************************
+ * StartMMTime [internal]
+ */
+void StartMMTime()
+{
+ if (!mmTimeStarted) {
+ mmTimeStarted = TRUE;
+ mmSysTimeMS.wType = TIME_MS;
+ mmSysTimeMS.u.ms = 0;
+ mmSysTimeSMPTE.wType = TIME_SMPTE;
+ mmSysTimeSMPTE.u.smpte.hour = 0;
+ mmSysTimeSMPTE.u.smpte.min = 0;
+ mmSysTimeSMPTE.u.smpte.sec = 0;
+ mmSysTimeSMPTE.u.smpte.frame = 0;
+ mmSysTimeSMPTE.u.smpte.fps = 0;
+ mmSysTimeSMPTE.u.smpte.dummy = 0;
+ SetTimer(0, 1, 33, GetWndProcEntry16("MMSysTimeCallback"));
+ }
+}
+
+/**************************************************************************
+ * timeGetSystemTime [MMSYSTEM.601]
+ */
+WORD timeGetSystemTime(LPMMTIME lpTime, WORD wSize)
+{
+ dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
+ if (!mmTimeStarted)
+ StartMMTime();
+ return 0;
+}
+
+/**************************************************************************
+ * timeSetEvent [MMSYSTEM.602]
+ */
+WORD timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
+ DWORD dwUser, WORD wFlags)
+{
+ WORD wNewID = 0;
+ LPTIMERENTRY lpNewTimer;
+ LPTIMERENTRY lpTimer = lpTimerList;
+ dprintf_mmsys(stddeb, "timeSetEvent(%u, %u, %p, %08lX, %04X);\n",
+ wDelay, wResol, lpFunc, dwUser, wFlags);
+ if (!mmTimeStarted)
+ StartMMTime();
+ lpNewTimer = (LPTIMERENTRY) malloc(sizeof(TIMERENTRY));
+ if (lpNewTimer == NULL)
+ return 0;
+ while (lpTimer != NULL) {
+ wNewID = max(wNewID, lpTimer->wTimerID);
+ if (lpTimer->Next == NULL)
+ break;
+ lpTimer = lpTimer->Next;
+ }
+ if (lpTimerList == NULL) {
+ lpTimerList = lpNewTimer;
+ lpNewTimer->Prev = NULL;
+ } else {
+ lpTimer->Next = lpNewTimer;
+ lpNewTimer->Prev = lpTimer;
+ }
+ lpNewTimer->Next = NULL;
+ lpNewTimer->wTimerID = wNewID + 1;
+ lpNewTimer->wCurTime = wDelay;
+ lpNewTimer->wDelay = wDelay;
+ lpNewTimer->wResol = wResol;
+ lpNewTimer->lpFunc = (FARPROC) lpFunc;
+ lpNewTimer->dwUser = dwUser;
+ lpNewTimer->wFlags = wFlags;
+ return lpNewTimer->wTimerID;
+}
+
+/**************************************************************************
+ * timeKillEvent [MMSYSTEM.603]
+ */
+WORD timeKillEvent(WORD wID)
+{
+ LPTIMERENTRY lpTimer = lpTimerList;
+ while (lpTimer != NULL) {
+ if (wID == lpTimer->wTimerID) {
+ if (lpTimer->Prev != NULL)
+ lpTimer->Prev->Next = lpTimer->Next;
+ if (lpTimer->Next != NULL)
+ lpTimer->Next->Prev = lpTimer->Prev;
+ free(lpTimer);
+ return TRUE;
+ }
+ lpTimer = lpTimer->Next;
+ }
+ return 0;
+}
+
+/**************************************************************************
+ * timeGetDevCaps [MMSYSTEM.604]
+ */
+WORD timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
+{
+ dprintf_mmsys(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
+ return 0;
+}
+
+/**************************************************************************
+ * timeBeginPeriod [MMSYSTEM.605]
+ */
+WORD timeBeginPeriod(WORD wPeriod)
+{
+ dprintf_mmsys(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
+ if (!mmTimeStarted)
+ StartMMTime();
+ return 0;
+}
+
+/**************************************************************************
+ * timeEndPeriod [MMSYSTEM.606]
+ */
+WORD timeEndPeriod(WORD wPeriod)
+{
+ dprintf_mmsys(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
+ return 0;
+}
+
+/**************************************************************************
+ * timeGetTime [MMSYSTEM.607]
+ */
+DWORD timeGetTime()
+{
+ dprintf_mmsys(stddeb, "timeGetTime(); !\n");
+ if (!mmTimeStarted)
+ StartMMTime();
+ return 0;
+}
+
+#endif /* WINELIB */
diff --git a/objects/Makefile.in b/objects/Makefile.in
new file mode 100644
index 0000000..4196d0a
--- /dev/null
+++ b/objects/Makefile.in
@@ -0,0 +1,51 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = objects
+
+SRCS = bitblt.c bitmap.c brush.c clipping.c color.c dc.c dcvalues.c \
+ dib.c font.c gdiobj.c linedda.c metafile.c oembitmap.c palette.c \
+ pen.c region.c text.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/objects/bitmap.c b/objects/bitmap.c
index e0f15c4..179d16d 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -12,7 +12,7 @@
#include "callback.h"
#include "dc.h"
#include "bitmap.h"
-#include "prototypes.h"
+#include "resource.h" /* for ConvertCore/InfoBitmap */
#include "stddebug.h"
/* #define DEBUG_GDI */
/* #define DEBUG_BITMAP */
diff --git a/objects/clipping.c b/objects/clipping.c
index 42dda4e..003a6ae 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -314,7 +314,9 @@
dprintf_clipping(stddeb,"RectVisible: %x %d,%dx%d,%d\n",
hdc, rect->left, rect->top, rect->right, rect->bottom );
if (!dc->w.hGCClipRgn) return FALSE;
- LPtoDP( hdc, (LPPOINT)rect, 2 );
+ /* copy rectangle to avoid overwriting by LPtoDP */
+ tmpRect = *rect;
+ LPtoDP( hdc, (LPPOINT)&tmpRect, 2 );
return RectInRegion( dc->w.hGCClipRgn, &tmpRect );
}
diff --git a/objects/dib.c b/objects/dib.c
index 78ab1ee..c2538b4 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -517,17 +517,8 @@
break;
}
if (colorMapping) free(colorMapping);
- {
- WORD saved_ds = CURRENT_DS;
- XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
- xDest, yDest, width, height );
- if (saved_ds != CURRENT_DS) {
- fprintf(stderr,"Uh oh. XPutImage clobbered the 16 bit stack.\n"
- "Please report: %s compression, %d bitplanes!!\n",
- info->bmiHeader.biCompression ? "" : "no",
- info->bmiHeader.biBitCount);
- }
- }
+ XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
+ xDest, yDest, width, height );
XDestroyImage( bmpImage );
return lines;
}
@@ -656,8 +647,9 @@
if (bits)
{
- bmpImage = XGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
- bmp->bitmap.bmHeight, AllPlanes, ZPixmap );
+ bmpImage = (XImage *)CallTo32_LargeStack( (int (*)())XGetImage, 8,
+ display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
+ bmp->bitmap.bmHeight, AllPlanes, ZPixmap );
dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
for (y = 0; y < lines; y++)
@@ -733,4 +725,3 @@
SetBkColor( hDC, oldBg );
return TRUE;
}
-
diff --git a/objects/font.c b/objects/font.c
index be92707..200b605 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -262,32 +262,31 @@
/***********************************************************************
* GetGlyphOutLine (GDI.309)
*/
-DWORD GetGlyphOutLine(
- HDC hdc, UINT uChar, UINT fuFormat, LPGLYPHMETRICS lpgm,
- DWORD cbBuffer, LPSTR lpBuffer, LPMAT2 lpmat2
-) {
- dprintf_font(stdnimp,"GetGlyphOutLine(0x%x, '%c', 0x%x, %p, %d, %p, %p) // - empty stub!\n",
- hdc,uChar,fuFormat,lpgm,cbBuffer,lpBuffer,lpmat2
- );
- return (DWORD)-1; /* failure */
+DWORD GetGlyphOutLine(HDC hdc, UINT uChar, UINT fuFormat, LPGLYPHMETRICS lpgm,
+ DWORD cbBuffer, LPSTR lpBuffer, LPMAT2 lpmat2)
+{
+ fprintf( stdnimp,"GetGlyphOutLine(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
+ hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
+ return (DWORD)-1; /* failure */
}
+
+
/***********************************************************************
* CreateScalableFontResource (GDI.310)
*/
-BOOL CreateScalableFontResource(
- UINT fHidden,LPSTR lpszResourceFile,
- LPSTR lpszFontFile,LPSTR lpszCurrentPath
-) {
- /* fHidden=1 - only visible for the calling app, read-only, not
- * enumbered with EnumFonts/EnumFontFamilies
- * lpszCurrentPath can be NULL
- */
- dprintf_font(stdnimp,"CreateScalableFontResource(%d,%s,%s,%x(%s)) // empty stub!\n",
- fHidden,lpszResourceFile,lpszFontFile,lpszCurrentPath
- );
- return FALSE; /* create failed */
+BOOL CreateScalableFontResource( UINT fHidden,LPSTR lpszResourceFile,
+ LPSTR lpszFontFile, LPSTR lpszCurrentPath )
+{
+ /* fHidden=1 - only visible for the calling app, read-only, not
+ * enumbered with EnumFonts/EnumFontFamilies
+ * lpszCurrentPath can be NULL
+ */
+ fprintf(stdnimp,"CreateScalableFontResource(%d,%s,%s,%s) // empty stub!\n",
+ fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
+ return FALSE; /* create failed */
}
+
/***********************************************************************
* CreateFontIndirect (GDI.57)
*/
@@ -737,7 +736,7 @@
LPTEXTMETRIC lptm;
LPSTR lpOldName;
char FaceName[LF_FACESIZE];
- int nRet;
+ int nRet = 0;
int i;
dprintf_font(stddeb,"EnumFonts(%04X, %p='%s', %08lx, %p)\n",
@@ -807,7 +806,7 @@
LPTEXTMETRIC lptm;
LPSTR lpOldName;
char FaceName[LF_FACESIZE];
- int nRet;
+ int nRet = 0;
int i;
dprintf_font(stddeb,"EnumFontFamilies(%04X, %p, %08lx, %p)\n",
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 2cfcd75..af7cccc 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -416,7 +416,7 @@
WORD wMagic;
LPSTR lpLog; /* Point to a LOGBRUSH or LOGPEN struct */
HANDLE hLog;
- int i, nRet = 0;
+ int nRet = 0;
if (lpEnumFunc == NULL) {
fprintf(stderr,"EnumObjects // Bad EnumProc callback address !\n");
diff --git a/objects/metafile.c b/objects/metafile.c
index 9a8208a..846964e 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -212,7 +212,7 @@
METAHEADER *mh;
METARECORD *mr;
HANDLETABLE *ht;
- char *buffer;
+ char *buffer = (char *)NULL;
if (mf->wMagic != METAFILE_MAGIC)
return FALSE;
diff --git a/objects/region.c b/objects/region.c
index 41df11b..02a10d7 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -377,6 +377,27 @@
}
}
+/***********************************************************************
+ * REGION_CreateFrameRgn
+ *
+ * Create a region that is a frame around another region
+ */
+BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, int x, int y )
+{
+ RGNOBJ *destObj,*srcObj;
+ Region result;
+
+ destObj = (RGNOBJ*) GDI_GetObjPtr( hDest, REGION_MAGIC );
+ srcObj = (RGNOBJ*) GDI_GetObjPtr( hSrc, REGION_MAGIC );
+ if (!srcObj->xrgn) return 0;
+ REGION_CopyRegion( srcObj, destObj );
+ XShrinkRegion( destObj->xrgn, -x, -y );
+ result = XCreateRegion();
+ XSubtractRegion( destObj->xrgn, srcObj->xrgn, result );
+ XDestroyRegion( destObj->xrgn );
+ destObj->xrgn = result;
+ return 1;
+}
/***********************************************************************
* CombineRgn (GDI.451)
diff --git a/objects/text.c b/objects/text.c
index 09a58e4..1ee64d0 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -188,7 +188,9 @@
SIZE size;
char *strPtr;
static char line[1024];
- int len, lh, prefix_x, prefix_end;
+ int len, lh;
+ int prefix_x = 0;
+ int prefix_end = 0;
TEXTMETRIC tm;
int x = rect->left, y = rect->top;
int width = rect->right - rect->left;
diff --git a/rc/Imakefile b/rc/Imakefile
index 4984ba4..571cb8f 100644
--- a/rc/Imakefile
+++ b/rc/Imakefile
@@ -26,7 +26,7 @@
touch $(RCSRCS:.rc=.h)
clean::
- $(RM) $(RCSRCS:.rc=.c) $(RCSRCS:.rc=.h)
+ $(RM) $(RCSRCS:.rc=.c) $(RCSRCS:.rc=.h) $(RCSRCS:.rc=.rct)
XCOMM Rules to build the winerc program
@@ -60,6 +60,6 @@
$(YACC) -d -t parser.y
lex.yy.c: parser.l y.tab.h
- $(LEX) -I parser.l
+ $(LEX) -8 -I parser.l
diff --git a/rc/Makefile.in b/rc/Makefile.in
new file mode 100644
index 0000000..b276281
--- /dev/null
+++ b/rc/Makefile.in
@@ -0,0 +1,59 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+BISON = @YACC@
+FLEX = @LEX@
+LANG = @LANG@
+COMPILE = $(CC) $(CFLAGS) $(DIVINCL) $(LANG)
+
+all: rc.o
+
+y.tab.c: parser.y
+ $(BISON) -d -t parser.y
+
+y.tab.h: parser.y
+ $(BISON) -d -t parser.y
+
+lex.yy.c: parser.l parser.h y.tab.h
+ $(FLEX) -8 -I parser.l
+
+winerc: lex.yy.o winerc.o y.tab.o
+ $(COMPILE) lex.yy.o winerc.o y.tab.o -o winerc
+
+sysres.rct: sysres.rc
+ echo "#include \"windows.h\"" >sysres.rct
+ echo WINDOWS_H_ENDS_HERE >>sysres.rct
+ cat sysres.rc >>sysres.rct
+
+sysres.c: sysres.rct winerc
+ $(COMPILE) -E -x c -P sysres.rct > sysres.tmp
+ cat sysres.tmp | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o sysres -v -p sysres
+
+sysres.h: sysres.rct winerc
+ $(COMPILE) -E -x c -P sysres.rct > sysres.tmp
+ cat sysres.tmp | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ./winerc -o sysres -v -p sysres
+
+rc.o: sysres.o
+ cp sysres.o rc.o
+
+.c.o:
+ $(COMPILE) -c -o $*.o $<
+
+clean:
+ rm -f *.o \#*\# *~ lex.yy.c sysres.tmp sysres.rct winerc y.tab.c \
+ y.tab.h sysres.c sysres.h tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+winelibclean: clean
+
+depend: sysres.h
+
+y.tab.o: y.tab.c
+lex.yy.o: lex.yy.c
+winerc.o: $(TOPSRC)/include/windows.h $(TOPSRC)/include/neexe.h parser.h y.tab.h
+
diff --git a/rc/winerc.c b/rc/winerc.c
index 14f3af0..c8832cf 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -37,11 +37,7 @@
extern char* optarg;
int optc,lose,ret,binary;
lose=binary=0;
-#if defined(__NetBSD__) || defined(__FreeBSD__)
while((optc=getopt(argc,argv,"bdp:vo:"))!=EOF)
-#else
- while((optc=getopt(argc,argv,"bdp:vo:",0))!=EOF)
-#endif
switch(optc)
{
/* bison will print state transitions on stderr */
@@ -531,7 +527,7 @@
fprintf(header,"extern %sstruct ResourceTable %sTable[];\n",
ISCONSTANT,prefix);
- fprintf(code,"#include \"prototypes.h\"\n#include \"%s\"\n",hname);
+ fprintf(code,"#include \"windows.h\"\n#include \"%s\"\n",hname);
/* print the resource table (0 terminated) */
fprintf(code,"\n%sstruct ResourceTable %sTable[]={\n",ISCONSTANT,prefix);
diff --git a/toolkit/sup.c b/toolkit/sup.c
index 25ab9f1..9a66e74 100644
--- a/toolkit/sup.c
+++ b/toolkit/sup.c
@@ -1,5 +1,4 @@
#include <stdio.h>
-#include "prototypes.h"
#include "windows.h"
#include "callback.h"
#include "wine.h"
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000..e5b6a7b
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,41 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+
+
+all: build
+
+build: build.o
+ $(CC) $(CFLAGS) -o build build.o
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ build tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/tools/build.c b/tools/build.c
index e88bbd9..4fab002 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1145,10 +1145,10 @@
printf( "\tmovl %%edx,%d(%%ebx)\n", CONTEXTOFFSET(sc_edx) );
printf( "\tmovl %%esi,%d(%%ebx)\n", CONTEXTOFFSET(sc_esi) );
printf( "\tmovl %%edi,%d(%%ebx)\n", CONTEXTOFFSET(sc_edi) );
- printf( "\tpushw %%es\n" );
- printf( "\tpopw %d(%%ebx)\n", CONTEXTOFFSET(sc_es) );
printf( "\tmovw -10(%%ebp),%%ax\n" ); /* Get saved ds from stack */
printf( "\tmovw %%ax,%d(%%ebx)\n", CONTEXTOFFSET(sc_ds) );
+ printf( "\tmovw -12(%%ebp),%%ax\n" ); /* Get saved es from stack */
+ printf( "\tmovw %%ax,%d(%%ebx)\n", CONTEXTOFFSET(sc_es) );
printf( "\tpushfl\n" );
#ifndef __FreeBSD__
printf( "\tpopl %d(%%ebx)\n", CONTEXTOFFSET(sc_eflags) );
@@ -1175,10 +1175,9 @@
printf( "\tmovl %d(%%ebx),%%edx\n", CONTEXTOFFSET(sc_edx) );
printf( "\tmovl %d(%%ebx),%%esi\n", CONTEXTOFFSET(sc_esi) );
printf( "\tmovl %d(%%ebx),%%edi\n", CONTEXTOFFSET(sc_edi) );
- printf( "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(sc_es) );
- printf( "\tpopw %%es\n" );
- printf( "\tpopw %%ax\n" ); /* Remove old ds from the stack */
+ printf( "\tpopl %%eax\n" ); /* Remove old ds and es from stack */
printf( "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(sc_ds) ); /* Push new ds */
+ printf( "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(sc_es) ); /* Push new es */
#ifndef __FreeBSD__
printf( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(sc_eflags) );
#else
@@ -1241,14 +1240,17 @@
printf( "\tmovzwl %%sp,%%ebp\n" );
printf( "\taddw $8,%%bp\n" );
- /* Save 16-bit ds */
+ /* Save 16-bit ds and es */
printf( "\tpushw %%ds\n" );
+ printf( "\tpushw %%es\n" );
- /* Restore 32-bit ds */
+ /* Restore 32-bit ds and es */
- printf( "\tpushw $0x%04x\n", WINE_DATA_SELECTOR );
+ printf( "\tpushl $0x%04x%04x\n", WINE_DATA_SELECTOR, WINE_DATA_SELECTOR );
printf( "\tpopw %%ds\n" );
+ printf( "\tpopw %%es\n" );
+
/* Save the 16-bit stack */
@@ -1271,11 +1273,6 @@
if (!reg_func && short_ret)
printf( "\tmovl %%edx,-8(%%ebp)\n" );
- /* Setup es */
-
- printf( "\tpushw %%ds\n" );
- printf( "\tpopw %%es\n" );
-
/* Switch to the 32-bit stack */
printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebp\n" );
@@ -1294,9 +1291,11 @@
{
printf( "\tpushl %%eax\n" );
printf( "\tpushl $CALL32_Str_%s\n", profile );
+ printf( "\tpushl $%d\n", reg_func ? 2 : (short_ret ? 1 : 0) );
printf( "\tcall " PREFIX "RELAY_DebugCall32\n" );
printf( "\tpopl %%eax\n" );
printf( "\tpopl %%eax\n" );
+ printf( "\tpopl %%eax\n" );
}
/* Call the entry point */
@@ -1346,8 +1345,9 @@
}
}
- /* Restore ds */
+ /* Restore ds and es */
+ printf( "\tpopw %%es\n" );
printf( "\tpopw %%ds\n" );
/* Get the return value into dx:ax and clean up the stack */
@@ -1532,7 +1532,6 @@
printf( "\tpushl 12(%%ebx)\n" );
/* Get the 16-bit ds */
- /* FIXME: this shouldn't be necessary if function prologs fixup worked. */
if (reg_func)
{
@@ -1544,8 +1543,6 @@
{
/* Set ax equal to ds for window procedures */
printf( "\tmovw 16(%%ebx),%%ax\n" );
-
- /* This seems to be needed, although I still don't see why... */
printf( "\tmovw %%ax,%%ds\n" );
}
diff --git a/tools/ipcl b/tools/ipcl
new file mode 100644
index 0000000..7a066d5
--- /dev/null
+++ b/tools/ipcl
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+#
+# Copyright 1995. Michael Veksler.
+#
+
+$IPC_RMID=0;
+$USER=$ENV{USER};
+
+do open_pipe(IPCS,"ipcs");
+
+#
+# The following part is OS dependant, it works under linux only.
+# To make it work under other OS
+# You should fill in @shm, @sem, @msq lists, with the relevent IPC
+# keys.
+
+#
+# This code was written to be as much as possible generic, but...
+# It works for Linux and ALPHA. I had no BSD machine to test it.
+# (As I remember, AIX will work also).
+
+while(<IPCS>) {
+ split;
+
+ # try to find out the IPC-ID, assume it is the first number.
+ foreach (@_) {
+ $_ ne int($_) && next; # not a decimal number
+ $num=$_;
+ last;
+ }
+ if (/mem/i .. /^\s*$/ ) {
+ index($_,$USER)>=0 || next;
+ push(@shm,$num);
+ }
+ if (/sem/i .. /^\s*$/ ) {
+ index($_,$USER)>=0 || next;
+ push(@sem,$num);
+ }
+ if (/mes/i .. /^\s*$/ ) {
+ index($_,$USER)>=0 || next;
+ push(@msq,$num);
+ }
+}
+
+
+#
+# This is the end of OS dependant code.
+#
+
+@shm && print "shmid ", join(":",@shm),"\n";
+@sem && print "semid ", join(":",@sem),"\n";
+@msq && print "msqid ", join(":",@msq),"\n";
+foreach (@shm) {
+ shmctl($_, $IPC_RMID,0);
+}
+foreach (@sem) {
+ semctl($_, 0, $IPC_RMID,0);
+}
+foreach (@msq) {
+ msgctl($_, $IPC_RMID,0);
+}
+
+exit(0);
+
+
+
+
+
+sub open_pipe {
+ local($pid);
+ local($handle,@params)=@_;
+ pipe($handle,WRITE) || die "can't pipe";
+
+ $pid=fork();
+
+ die "can't fork" if ($pid<0);
+ if ($pid>0) {
+ # whe are in the parent
+ close(WRITE);
+ waitpid($pid,0) || print "$params[0] exits status=$? ",$? >> 8, "\n";
+ } else {
+ # we are in the son.
+ open(STDOUT,">&WRITE");
+ open(STDERR, ">&WRITE");
+ close($handle);
+ close(WRITE);
+ exec(@params);
+ exit(-1);
+ }
+
+}
diff --git a/windows/Makefile.in b/windows/Makefile.in
new file mode 100644
index 0000000..3b0d318
--- /dev/null
+++ b/windows/Makefile.in
@@ -0,0 +1,54 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+XINCL = @x_includes@
+TOPSRC = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD = @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE = windows
+
+SRCS = caret.c class.c cursor.c dce.c defdlg.c defwnd.c dialog.c \
+ event.c focus.c graphics.c hook.c keyboard.c mapping.c mdi.c \
+ message.c msgbox.c nonclient.c painting.c property.c scroll.c \
+ syscolor.c sysmetrics.c timer.c utility.c win.c \
+ winpos.c
+
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+ $(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+ $(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+ cp tmp_make Makefile
+ rm tmp_make
+
+clean:
+ rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+ rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+ for i in $(NAMES); do \
+ if test `grep -c WINELIB $$i.c` -ne 0; then \
+ rm $$i.o; \
+ fi; \
+ done
+
+dummy:
+
+### Dependencies:
diff --git a/windows/class.c b/windows/class.c
index 050d4e7..4c60a79 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -11,6 +11,7 @@
#include "user.h"
#include "win.h"
#include "dce.h"
+#include "atom.h"
#include "toolhelp.h"
#include "stddebug.h"
/* #define DEBUG_CLASS */
@@ -32,7 +33,7 @@
HCLASS class;
CLASS * classPtr;
- if (!(atom = GlobalFindAtom( name ))) return 0;
+ if (!(atom = LocalFindAtom( name ))) return 0;
/* First search task-specific classes */
@@ -122,7 +123,7 @@
newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
newClass->wc.cbClsExtra = classExtra;
- newClass->atomName = GlobalAddAtom( name );
+ newClass->atomName = LocalAddAtom( name );
newClass->wc.lpszClassName = NULL;
if (newClass->wc.style & CS_CLASSDC)
@@ -183,7 +184,7 @@
/* Delete the class */
if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
- /*if (classPtr->wc.style & CS_GLOBALCLASS)*/ GlobalDeleteAtom( classPtr->atomName );
+ /*if (classPtr->wc.style & CS_GLOBALCLASS)*/ LocalDeleteAtom( classPtr->atomName );
/*else DeleteAtom( classPtr->atomName );*/
if ((int)classPtr->wc.lpszMenuName & 0xffff0000)
USER_HEAP_FREE( (int)classPtr->wc.lpszMenuName & 0xffff );
@@ -264,7 +265,7 @@
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
- return GlobalGetAtomName(classPtr->atomName, lpClassName, maxCount);
+ return LocalGetAtomName(classPtr->atomName, lpClassName, maxCount);
}
@@ -328,7 +329,7 @@
pClassEntry->hInst = classPtr->wc.hInstance;
pClassEntry->wNext = classPtr->hNext;
- GlobalGetAtomName( classPtr->atomName, pClassEntry->szClassName,
+ LocalGetAtomName( classPtr->atomName, pClassEntry->szClassName,
sizeof(pClassEntry->szClassName) );
return TRUE;
}
diff --git a/windows/cursor.c b/windows/cursor.c
index 810dcf2..5a41d3c 100644
--- a/windows/cursor.c
+++ b/windows/cursor.c
@@ -18,9 +18,8 @@
#include "neexe.h"
#include "wine.h"
#include "cursor.h"
+#include "resource.h"
#include "stddebug.h"
-/* #define DEBUG_CURSOR */
-/* #define DEBUG_RESOURCE */
#include "debug.h"
#include "arch.h"
@@ -191,7 +190,7 @@
fprintf(stderr,"No bitmap for cursor?\n");
lpcur->hBitmap = 0;
}
- lpl = (char *)lpl + size + 8;
+ lpl = (LONG *)((char *)lpl + size + 8);
/* This is rather strange! The data is stored *BACKWARDS* and */
/* mirrored! But why?? FIXME: the image must be flipped at the Y */
/* axis, either here or in CreateCusor(); */
@@ -308,8 +307,13 @@
*/
BOOL DestroyCursor(HCURSOR hCursor)
{
+ int i;
CURSORALLOC *lpcur;
- if (hCursor == (HCURSOR)NULL) return FALSE;
+
+ if (hCursor == 0) return FALSE;
+ for (i = 0; i < NB_SYS_CURSORS; i++) {
+ if (system_cursor[i].cursor == hCursor) return TRUE;
+ }
lpcur = (CURSORALLOC *)GlobalLock(hCursor);
if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap);
GlobalUnlock(hCursor);
@@ -451,7 +455,3 @@
if (lpRetClipRect != NULL)
CopyRect(lpRetClipRect, &ClipCursorRect);
}
-
-
-
-
diff --git a/windows/defwnd.c b/windows/defwnd.c
index e5811fb..6263dd5 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -2,9 +2,7 @@
* Default window procedure
*
* Copyright 1993 Alexandre Julliard
-
-static char Copyright[] = "Copyright Alexandre Julliard, 1993";
-*/
+ */
#include <stdlib.h>
#include <stdio.h>
@@ -38,7 +36,6 @@
strcpy( textPtr, text );
}
-#include <assert.h>
/***********************************************************************
* DefWindowProc (USER.107)
@@ -206,7 +203,7 @@
textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
return (DWORD)strlen(textPtr);
}
- return (0L);
+ return 0;
}
case WM_SETTEXT:
@@ -226,14 +223,13 @@
case WM_SYSKEYDOWN:
if (wParam == VK_MENU)
{ /* Send to WS_OVERLAPPED parent. TODO: Handle MDI */
- HWND top;
- for(top=hwnd;GetParent(top)!=0;top=GetParent(top));
- SendMessage( top, WM_SYSCOMMAND, SC_KEYMENU, 0L );
+ SendMessage( WIN_GetTopParent(hwnd), WM_SYSCOMMAND,
+ SC_KEYMENU, 0L );
}
break;
case WM_SYSKEYUP:
- break;
+ break;
}
return 0;
}
diff --git a/windows/dialog.c b/windows/dialog.c
index b5b78a4..79116d4 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -415,7 +415,7 @@
int retval;
/* Owner must be a top-level window */
- while (owner && GetParent(owner)) owner = GetParent(owner);
+ owner = WIN_GetTopParent( owner );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG) ))) return -1;
lpmsg = (MSG *) USER_HEAP_LIN_ADDR( msgHandle );
diff --git a/windows/event.c b/windows/event.c
index 05c21ce..9803e0a 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -283,7 +283,8 @@
char Str[24];
XComposeStatus cs;
KeySym keysym;
- WORD xkey, vkey, key_type, key;
+ WORD vkey = 0;
+ WORD xkey, key_type, key;
KEYLP keylp;
BOOL extended = FALSE;
diff --git a/windows/graphics.c b/windows/graphics.c
index bbc674b..d623752 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -19,6 +19,7 @@
#include "syscolor.h"
#include "stddebug.h"
#include "color.h"
+#include "region.h"
#include "debug.h"
static __inline__ void swap_int(int *a, int *b)
@@ -626,6 +627,17 @@
return retval;
}
+/***********************************************************************
+ * FrameRgn (GDI.41)
+ */
+BOOL FrameRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush, int nWidth, int nHeight )
+{
+ HRGN tmp = CreateRectRgn( 0, 0, 0, 0 );
+ if(!REGION_FrameRgn( tmp, hrgn, nWidth, nHeight )) return 0;
+ FillRgn( hdc, tmp, hbrush );
+ DeleteObject( tmp );
+ return 1;
+}
/***********************************************************************
* InvertRgn (GDI.42)
diff --git a/windows/mdi.c b/windows/mdi.c
index 85b49b5..aa67bf0 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -15,7 +15,6 @@
#include "menu.h"
#include "sysmetrics.h"
#include "stddebug.h"
-/* #define DEBUG_MDI */
#include "debug.h"
/**********************************************************************
@@ -61,6 +60,21 @@
}
}
+/**********************************************************************
+ * MDISetMenu
+ * FIXME: This is not complete.
+ */
+HMENU MDISetMenu(HWND hwnd, BOOL fRefresh, HMENU hmenuFrame, HMENU hmenuWindow)
+{
+ dprintf_mdi(stddeb, "WM_MDISETMENU: %04x %04x %04x %04x\n", hwnd, fRefresh, hmenuFrame, hmenuWindow);
+ if (!fRefresh) {
+ HWND hwndFrame = GetParent(hwnd);
+ HMENU oldFrameMenu = GetMenu(hwndFrame);
+ SetMenu(hwndFrame, hmenuFrame);
+ return oldFrameMenu;
+ }
+ return 0;
+}
/**********************************************************************
* MDIIconArrange
@@ -666,8 +680,7 @@
return MDIRestoreChild(hwnd, ci);
case WM_MDISETMENU:
- /* return MDISetMenu(...) */
- break;
+ return MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam));
case WM_MDITILE:
return MDITile(hwnd, ci);
diff --git a/windows/message.c b/windows/message.c
index 37a869c..957f611 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -7,15 +7,17 @@
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <errno.h>
#include "message.h"
#include "win.h"
#include "gdi.h"
-#include "wineopts.h"
#include "sysmetrics.h"
#include "hook.h"
#include "event.h"
#include "winpos.h"
+#include "atom.h"
+#include "dde.h"
#include "stddebug.h"
/* #define DEBUG_MSG */
#include "debug.h"
@@ -26,6 +28,15 @@
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
+/* used for passing message information when sending message */
+typedef struct {
+ LONG lParam;
+ WORD wParam;
+ WORD wMsg;
+ WORD hWnd;
+} msgstruct;
+
+
extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg,
HWND hwnd, BOOL remove ); /* timer.c */
@@ -135,6 +146,8 @@
{
int i, pos = msgQueue->nextMessage;
+ dprintf_msg(stddeb,"MSG_FindMsg: hwnd=0x%04x, proc=%d\n",
+ hwnd, curr_proc_idx);
if (!msgQueue->msgCount) return -1;
if (!hwnd && !first && !last) return pos;
@@ -191,7 +204,8 @@
{
WND *wndPtr;
HWND hwnd;
- INT hittest, x, y;
+ INT hittest = HTERROR;
+ INT x, y;
*phwnd = hwnd = GetDesktopWindow();
x = pt.x;
@@ -212,11 +226,11 @@
(y < wndPtr->rectWindow.bottom))
{
*phwnd = hwnd;
+ x -= wndPtr->rectClient.left;
+ y -= wndPtr->rectClient.top;
/* If window is minimized or disabled, ignore its children */
if ((wndPtr->dwStyle & WS_MINIMIZE) ||
(wndPtr->dwStyle & WS_DISABLED)) break;
- x -= wndPtr->rectClient.left;
- y -= wndPtr->rectClient.top;
hwnd = wndPtr->hwndChild;
}
else hwnd = wndPtr->hwndNext;
@@ -276,7 +290,7 @@
static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
{
BOOL eatMsg = FALSE;
- INT hittest_result;
+ INT hittest;
static DWORD lastClickTime = 0;
static WORD lastClickMsg = 0;
static POINT lastClickPos = { 0, 0 };
@@ -294,38 +308,40 @@
ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam );
return TRUE; /* No need to further process the message */
}
- else hittest_result = MSG_GetWindowForEvent( msg->pt, &msg->hwnd );
-
- /* Send the WM_PARENTNOTIFY message */
-
- if (mouseClick) WIN_SendParentNotify( msg->hwnd, msg->message,
- MAKELONG( msg->pt.x, msg->pt.y ) );
-
- /* Activate the window if needed */
-
- if (mouseClick)
+
+ if ((hittest = MSG_GetWindowForEvent( msg->pt, &msg->hwnd )) != HTERROR)
{
- HWND parent, hwndTop = msg->hwnd;
- while ((parent = GetParent(hwndTop)) != 0) hwndTop = parent;
- if (hwndTop != GetActiveWindow())
- {
- LONG ret = SendMessage( msg->hwnd, WM_MOUSEACTIVATE, hwndTop,
- MAKELONG( hittest_result, msg->message ) );
- if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
- eatMsg = TRUE;
- if ((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
- {
- SetWindowPos( hwndTop, HWND_TOP, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
- WINPOS_ChangeActiveWindow( hwndTop, TRUE );
- }
- }
+
+ /* Send the WM_PARENTNOTIFY message */
+
+ if (mouseClick) WIN_SendParentNotify( msg->hwnd, msg->message,
+ MAKELONG( msg->pt.x, msg->pt.y ) );
+
+ /* Activate the window if needed */
+
+ if (mouseClick)
+ {
+ HWND hwndTop = WIN_GetTopParent( msg->hwnd );
+ if (hwndTop != GetActiveWindow())
+ {
+ LONG ret = SendMessage( msg->hwnd, WM_MOUSEACTIVATE, hwndTop,
+ MAKELONG( hittest, msg->message ) );
+ if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
+ eatMsg = TRUE;
+ if ((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
+ {
+ SetWindowPos( hwndTop, HWND_TOP, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
+ WINPOS_ChangeActiveWindow( hwndTop, TRUE );
+ }
+ }
+ }
}
/* Send the WM_SETCURSOR message */
SendMessage( msg->hwnd, WM_SETCURSOR, msg->hwnd,
- MAKELONG( hittest_result, msg->message ));
+ MAKELONG( hittest, msg->message ));
if (eatMsg) return FALSE;
/* Check for double-click */
@@ -340,7 +356,7 @@
(abs(msg->pt.y - lastClickPos.y) < SYSMETRICS_CYDOUBLECLK/2))
dbl_click = TRUE;
- if (dbl_click && (hittest_result == HTCLIENT))
+ if (dbl_click && (hittest == HTCLIENT))
{
/* Check whether window wants the double click message. */
WND * wndPtr = WIN_FindWndPtr( msg->hwnd );
@@ -366,13 +382,13 @@
/* Build the translated message */
msg->lParam = MAKELONG( msg->pt.x, msg->pt.y );
- if (hittest_result == HTCLIENT)
+ if (hittest == HTCLIENT)
{
ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam );
}
else
{
- msg->wParam = hittest_result;
+ msg->wParam = hittest;
msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN;
}
@@ -713,19 +729,43 @@
XEvent event;
int fd = ConnectionNumber(display);
- if (!XPending(display) && (maxWait != -1))
+ if (!XPending(display))
{
FD_ZERO( &read_set );
FD_SET( fd, &read_set );
- timeout.tv_sec = maxWait / 1000;
- timeout.tv_usec = (maxWait % 1000) * 1000;
- if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
- return FALSE; /* Timeout or error */
+ sigsetjmp(env_wait_x, 1);
+
+ stop_wait_op= CONT;
+
+ if (DDE_GetRemoteMessage()) {
+ while(DDE_GetRemoteMessage())
+ ;
+ return TRUE;
+ }
+
+ timeout.tv_usec = (maxWait % 1000) * 1000;
+ timeout.tv_sec = maxWait / 1000;
+
+ stop_wait_op= STOP_WAIT_X;
+ /* The code up to the next "stop_wait_op= CONT" must be reentrant */
+ if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1 &&
+ !XPending(display)) {
+ stop_wait_op= CONT;
+ return FALSE;
+ } else {
+ stop_wait_op= CONT;
+ }
+
}
/* Process the event (and possibly others that occurred in the meantime) */
do
{
+ if (DDE_GetRemoteMessage()) {
+ while(DDE_GetRemoteMessage())
+ ;
+ return TRUE;
+ }
XNextEvent( display, &event );
EVENT_ProcessEvent( &event );
}
@@ -744,6 +784,9 @@
MESSAGEQUEUE *msgQueue;
LONG nextExp; /* Next timer expiration time */
+ DDE_TestDDE(hwnd); /* do we have dde handling in the window ?*/
+ DDE_GetRemoteMessage();
+
if (first || last)
{
mask = QS_POSTMESSAGE; /* Always selectioned */
@@ -918,6 +961,17 @@
MSG msg;
WND *wndPtr;
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.time = GetTickCount();
+ msg.pt.x = 0;
+ msg.pt.y = 0;
+
+ if (DDE_PostMessage(&msg))
+ return TRUE;
+
if (hwnd == HWND_BROADCAST) {
dprintf_msg(stddeb,"PostMessage // HWND_BROADCAST !\n");
hwnd = GetTopWindow(GetDesktopWindow());
@@ -928,11 +982,6 @@
hwnd, message, wParam, lParam);
PostMessage(hwnd, message, wParam, lParam);
}
- /*{
- char str[128];
- GetWindowText(hwnd, str, sizeof(str));
- dprintf_msg(stddeb, "BROADCAST GetWindowText()='%s' !\n", str);
- }*/
hwnd = wndPtr->hwndNext;
}
dprintf_msg(stddeb,"PostMessage // End of HWND_BROADCAST !\n");
@@ -941,13 +990,6 @@
wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE;
- msg.hwnd = hwnd;
- msg.message = message;
- msg.wParam = wParam;
- msg.lParam = lParam;
- msg.time = GetTickCount();
- msg.pt.x = 0;
- msg.pt.y = 0;
return MSG_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
}
@@ -979,35 +1021,48 @@
{
WND * wndPtr;
LONG ret;
-
- wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr) return 0;
- else {
- /* Argh. This is inefficient. */
- typedef struct {
+ MSG DDE_msg;
+ struct
+ {
LONG lParam;
WORD wParam;
WORD wMsg;
WORD hWnd;
- } msgstruct;
- HANDLE msgh = GlobalAlloc(0,sizeof(msgstruct));
- SEGPTR segmsg = WIN16_GlobalLock(msgh);
- msgstruct *Msg = PTR_SEG_TO_LIN(segmsg);
-
- Msg->hWnd = hwnd;
- Msg->wMsg = msg;
- Msg->wParam = wParam;
- Msg->lParam = lParam;
- CALL_SYSTEM_HOOK( WH_CALLWNDPROC, 0, 0, (LPARAM)segmsg );
- CALL_TASK_HOOK( WH_CALLWNDPROC, 0, 0, (LPARAM)segmsg );
- ret = CallWindowProc( wndPtr->lpfnWndProc, Msg->hWnd, Msg->wMsg, Msg->wParam,
- Msg->lParam );
- GlobalUnlock(msgh);
- GlobalFree(msgh);
- dprintf_msg( stddeb,"SendMessage(%4.4x,%x,%x,%lx) -> %lx\n",
- hwnd, msg, wParam, lParam, ret );
- return ret;
+ } msgstruct = { lParam, wParam, msg, hwnd };
+
+ DDE_msg.hwnd = hwnd;
+ DDE_msg.message = msg;
+ DDE_msg.wParam = wParam;
+ DDE_msg.lParam = lParam;
+ if (DDE_SendMessage(&DDE_msg)) return TRUE;
+
+ if (hwnd == HWND_BROADCAST)
+ {
+ dprintf_msg(stddeb,"SendMessage // HWND_BROADCAST !\n");
+ hwnd = GetTopWindow(GetDesktopWindow());
+ while (hwnd)
+ {
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) break;
+ if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
+ {
+ dprintf_msg(stddeb,"BROADCAST Message to hWnd=%04X m=%04X w=%04X l=%08lX !\n",
+ hwnd, msg, wParam, lParam);
+ ret |= SendMessage( hwnd, msg, wParam, lParam );
+ }
+ hwnd = wndPtr->hwndNext;
+ }
+ dprintf_msg(stddeb,"SendMessage // End of HWND_BROADCAST !\n");
+ return TRUE;
}
+
+ CALL_SYSTEM_HOOK( WH_CALLWNDPROC, 0, 0, MAKE_SEGPTR(&msgstruct) );
+ CALL_TASK_HOOK( WH_CALLWNDPROC, 0, 0, MAKE_SEGPTR(&msgstruct) );
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ ret = CallWindowProc( wndPtr->lpfnWndProc, msgstruct.hWnd, msgstruct.wMsg,
+ msgstruct.wParam, msgstruct.lParam );
+ dprintf_msg( stddeb,"SendMessage(%4.4x,%x,%x,%lx) -> %lx\n",
+ hwnd, msg, wParam, lParam, ret );
+ return ret;
}
@@ -1020,6 +1075,8 @@
MESSAGEQUEUE *queue;
LONG nextExp = -1; /* Next timer expiration time */
+ DDE_GetRemoteMessage();
+
if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return;
if ((queue->wPostQMsg) ||
(queue->status & (QS_SENDMESSAGE | QS_PAINT)) ||
@@ -1028,6 +1085,7 @@
if ((queue->status & QS_TIMER) &&
TIMER_CheckTimer( &nextExp, &msg, 0, FALSE))
return;
+ /* FIXME: (dde) must check DDE & X-events simultaneously */
MSG_WaitXEvent( nextExp );
}
@@ -1066,8 +1124,12 @@
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
{
if (msg->lParam)
- return CallWndProc( (WNDPROC)msg->lParam, CURRENT_DS, msg->hwnd,
- msg->message, msg->wParam, GetTickCount() );
+ {
+ WORD ds = msg->hwnd ? GetWindowWord( msg->hwnd, GWW_HINSTANCE )
+ : CURRENT_DS;
+ return CallWndProc( (WNDPROC)msg->lParam, ds, msg->hwnd,
+ msg->message, msg->wParam, GetTickCount() );
+ }
}
if (!msg->hwnd) return 0;
@@ -1131,7 +1193,7 @@
{
WORD wRet;
dprintf_msg(stddeb, "RegisterWindowMessage: '%s'\n", str );
- wRet = GlobalAddAtom( str );
+ wRet = LocalAddAtom( str );
return wRet;
}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 8af8dd3..a192262 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -10,6 +10,7 @@
#include "message.h"
#include "sysmetrics.h"
#include "user.h"
+#include "shell.h"
#include "dialog.h"
#include "syscolor.h"
#include "menu.h"
@@ -152,7 +153,10 @@
MinMax.ptMaxSize.x += 2 * xinc;
MinMax.ptMaxSize.y += 2 * yinc;
- if ((wndPtr->ptMaxPos.x != -1) || (wndPtr->ptMaxPos.y != -1))
+ /* Note: The '+' in the following test should really be a ||, but
+ * that would cause gcc-2.7.0 to generate incorrect code.
+ */
+ if ((wndPtr->ptMaxPos.x != -1) + (wndPtr->ptMaxPos.y != -1))
MinMax.ptMaxPosition = wndPtr->ptMaxPos;
else
{
diff --git a/windows/painting.c b/windows/painting.c
index e29056e..b188ac3 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -124,7 +124,7 @@
if (!hwnd) hwnd = GetDesktopWindow();
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
- if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
+ if (!IsWindowVisible(hwnd) || (wndPtr->flags & WIN_NO_REDRAW))
return TRUE; /* No redraw needed */
if (rectUpdate)
diff --git a/windows/timer.c b/windows/timer.c
index 96fff6a..88b7073 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -114,6 +114,8 @@
TIMER_RestartTimer( pTimer, curTime );
}
+ dprintf_timer(stddeb, "Timer expired: %p, %04x, %04x, %04x, %08lx\n",
+ pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, pTimer->proc);
/* Build the message */
msg->hwnd = pTimer->hwnd;
msg->message = pTimer->msg;
@@ -168,6 +170,8 @@
pTimer->timeout = timeout;
pTimer->expires = GetTickCount() + timeout;
pTimer->proc = proc;
+ dprintf_timer(stddeb, "Timer added: %p, %04x, %04x, %04x, %08lx\n",
+ pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, pTimer->proc);
TIMER_InsertTimer( pTimer );
MSG_IncTimerCount( GetTaskQueue(0) );
if (!id)
diff --git a/windows/win.c b/windows/win.c
index aad3546..de84af9 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -21,6 +21,8 @@
#include "nonclient.h"
#include "winpos.h"
#include "color.h"
+#include "shm_main_blk.h"
+#include "dde_proc.h"
#include "callback.h"
#include "stddebug.h"
/* #define DEBUG_WIN */
@@ -165,14 +167,14 @@
*/
void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam )
{
- HWND current = GetParent( hwnd );
WND *wndPtr = WIN_FindWndPtr( hwnd );
- if (!wndPtr || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) return;
- while (current)
+ while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
{
- SendMessage( current, WM_PARENTNOTIFY, event, lParam );
- current = GetParent( current );
+ if (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) break;
+ SendMessage( wndPtr->hwndParent, WM_PARENTNOTIFY, event, lParam );
+ wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
+
}
}
@@ -187,6 +189,9 @@
WND *wndPtr = WIN_FindWndPtr( hwnd );
CLASS *classPtr = CLASS_FindClassPtr( wndPtr->hClass );
+ if (main_block)
+ DDE_DestroyWindow(hwnd);
+
if (!wndPtr || !classPtr) return;
WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
wndPtr->dwMagic = 0; /* Mark it as invalid */
@@ -364,7 +369,7 @@
wndPtr->window = 0;
wndPtr->dwMagic = WND_MAGIC;
wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
- wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
+ wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : WIN_GetTopParent(parent);
wndPtr->hClass = class;
wndPtr->hInstance = instance;
wndPtr->ptIconPos.x = -1;
@@ -390,11 +395,6 @@
memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
classPtr->cWindows++;
- /* Make sure owner is a top-level window */
-
- while (wndPtr->hwndOwner && GetParent(wndPtr->hwndOwner))
- wndPtr->hwndOwner = GetParent(wndPtr->hwndOwner);
-
/* Get class or window DC if needed */
if (classPtr->wc.style & CS_OWNDC)
@@ -844,10 +844,29 @@
HWND GetParent(HWND hwnd)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
- if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
- return wndPtr->hwndParent;
+ if (!wndPtr) return 0;
+ return (wndPtr->dwStyle & WS_CHILD) ?
+ wndPtr->hwndParent : wndPtr->hwndOwner;
}
+
+/*****************************************************************
+ * WIN_GetTopParent
+ *
+ * Get the top-level parent for a child window.
+ */
+HWND WIN_GetTopParent( HWND hwnd )
+{
+ while (hwnd)
+ {
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+ if (wndPtr->dwStyle & WS_CHILD) hwnd = wndPtr->hwndParent;
+ else break;
+ }
+ return hwnd;
+}
+
+
/*****************************************************************
* SetParent (USER.233)
*/
@@ -984,6 +1003,20 @@
return GetWindow( hwnd, flag );
}
+/*******************************************************************
+ * ShowOwnedPopups (USER.265)
+ */
+void ShowOwnedPopups( HWND owner, BOOL fShow )
+{
+ HWND hwnd = GetWindow( hwndDesktop, GW_CHILD );
+ while (hwnd)
+ {
+ WND *wnd = WIN_FindWndPtr(hwnd);
+ if (wnd->hwndOwner == owner && (wnd->dwStyle & WS_POPUP))
+ ShowWindow( hwnd, fShow ? SW_SHOW : SW_HIDE );
+ hwnd = wnd->hwndNext;
+ }
+}
/*******************************************************************
@@ -1015,7 +1048,7 @@
/* First count the windows */
count = 0;
- for (hwnd = hwndDesktop; hwnd != 0; hwnd = wndPtr->hwndNext)
+ for (hwnd = GetTopWindow(hwndDesktop); hwnd != 0; hwnd = wndPtr->hwndNext)
{
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
count++;
@@ -1025,7 +1058,7 @@
/* Now build the list of all windows */
if (!(list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
- for (hwnd = hwndDesktop, pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
+ for (hwnd = GetTopWindow(hwndDesktop), pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
{
wndPtr = WIN_FindWndPtr( hwnd );
*pWnd++ = hwnd;
@@ -1061,7 +1094,7 @@
/* First count the windows */
count = 0;
- for (hwnd = hwndDesktop; hwnd != 0; hwnd = wndPtr->hwndNext)
+ for (hwnd = GetTopWindow(hwndDesktop); hwnd != 0; hwnd = wndPtr->hwndNext)
{
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
if (wndPtr->hmemTaskQ == hQueue) count++;
@@ -1071,7 +1104,7 @@
/* Now build the list of all windows */
if (!(list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
- for (hwnd = hwndDesktop, pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
+ for (hwnd = GetTopWindow(hwndDesktop), pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
{
wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr->hmemTaskQ == hQueue) *pWnd++ = hwnd;
diff --git a/windows/winpos.c b/windows/winpos.c
index b241afc..577221d 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -773,7 +773,8 @@
(hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
/* hwndInsertAfter must be a sibling of the window */
if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM) &&
- (GetParent(hwnd) != GetParent(hwndInsertAfter))) return FALSE;
+ (wndPtr->hwndParent != WIN_FindWndPtr(hwndInsertAfter)->hwndParent))
+ return FALSE;
/* Fill the WINDOWPOS structure */
@@ -965,14 +966,16 @@
DWP *pDWP;
int i;
HDWP newhdwp = hdwp;
+ HWND parent;
pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
if (!pDWP) return 0;
/* All the windows of a DeferWindowPos() must have the same parent */
- if (pDWP->actualCount == 0) pDWP->hwndParent = GetParent( hwnd );
- else if (GetParent( hwnd ) != pDWP->hwndParent)
+ parent = WIN_FindWndPtr( hwnd )->hwndParent;
+ if (pDWP->actualCount == 0) pDWP->hwndParent = parent;
+ else if (parent != pDWP->hwndParent)
{
USER_HEAP_FREE( hdwp );
return 0;