From e2991ea7bdef3c55cd2a07fc9bca48d0a6063a7c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 29 Jul 1995 13:09:43 +0000 Subject: [PATCH] Release 950727 Sat Jul 22 22:39:09 IDT 1995 Michael Veksler * [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 * [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 * [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 * [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 * [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 * [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 * [*/*] Added missing prototypes to header files and relevant includes to reduce compile time warnings. Sun Jul 9 18:32:56 1995 Michael Patra * [configure.in] [include/config.h] [*/Makefile.in] New configuration scheme based on autoconf. Sat Jul 8 14:12:45 1995 Morten Welinder * [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 * [misc/dos_fs.c] ChopOffSlash(): A path consisting off a single slash is left intact, and multiple slashes are all removed. --- ANNOUNCE | 21 +- ChangeLog | 190 ++++- Configure | 2 - Imakefile | 11 +- Makefile.in | 87 ++ autoconf.h.in | 3 + configure | 1752 +++++++++++++++++++++++++++++++++++++++++ configure.in | 148 ++++ controls/Makefile.in | 49 ++ controls/listbox.c | 10 +- controls/menu.c | 21 +- debugger/Makefile.in | 68 ++ debugger/dbg.y | 6 +- debugger/debug.l | 2 +- debugger/info.c | 5 - debugger/readline/Imakefile | 5 +- debugger/readline/Makefile.in | 50 ++ debugger/readline/complete.c | 222 ------ debugger/readline/editline.c | 108 +-- debugger/readline/editline.h | 43 +- debugger/readline/sysunix.c | 1 + debugger/readline/testit.c | 62 -- debugger/readline/unix.h | 22 - if1632/Makefile.in | 88 +++ if1632/gdi.spec | 2 +- if1632/kernel.spec | 6 +- if1632/keyboard.spec | 48 +- if1632/mouse.spec | 3 +- if1632/relay.c | 15 +- if1632/user.spec | 6 +- if1632/winprocs.spec | 258 +++++- if1632/winsock.spec | 4 +- include/atom.h | 10 + include/bit_array.h | 53 ++ include/config.h.in | 6 + include/dde.h | 61 ++ include/dde_atom.h | 23 + include/dde_mem.h | 34 + include/dde_proc.h | 57 ++ include/debug.h | 381 +++++---- include/dos_fs.h | 5 +- include/global.h | 10 +- include/ldt.h | 6 +- include/miscemu.h | 64 +- include/msdos.h | 30 +- include/options.h | 1 - include/pe_image.h | 1 + include/prototypes.h | 33 - include/region.h | 1 + include/registers.h | 8 + include/resource.h | 3 + include/shell.h | 2 + include/shm_block.h | 86 ++ include/shm_fragment.h | 47 ++ include/shm_main_blk.h | 55 ++ include/shm_semaph.h | 24 + include/stackframe.h | 1 + include/stddebug.h | 10 + include/task.h | 4 + include/user.h | 1 + include/win.h | 1 + include/windows.h | 12 +- include/wineopts.h | 11 - include/winsock.h | 2 +- ipc/Imakefile | 33 + ipc/Makefile.in | 57 ++ ipc/README | 8 + ipc/TEST_FRAGMENT.std | 42 + ipc/bit_array.c | 276 +++++++ ipc/bit_array_test.c | 93 +++ ipc/dde_atom.c | 273 +++++++ ipc/dde_atom_test.c | 100 +++ ipc/dde_mem.c | 282 +++++++ ipc/dde_mem_test.c | 73 ++ ipc/dde_proc.c | 718 +++++++++++++++++ ipc/dde_proc_test.c | 117 +++ ipc/generic_hash.c | 678 ++++++++++++++++ ipc/generic_hash.h | 141 ++++ ipc/hash_test.c | 117 +++ ipc/run_tests | 49 ++ ipc/shm_block.c | 191 +++++ ipc/shm_fragment.c | 178 +++++ ipc/shm_fragment_test.c | 100 +++ ipc/shm_main_blk.c | 264 +++++++ ipc/shm_semaph.c | 136 ++++ ipc/shm_semaph_test.c | 128 +++ ipc/wine_test_stub.c | 117 +++ loader/Imakefile | 1 - loader/Makefile.in | 50 ++ loader/dump.c | 75 -- loader/main.c | 26 +- loader/module.c | 43 +- loader/pe_image.c | 2 +- loader/resource.c | 10 + loader/selector.c | 21 - loader/signal.c | 17 +- loader/task.c | 26 +- memory/Makefile.in | 49 ++ memory/global.c | 121 ++- memory/ldt.c | 3 +- memory/selector.c | 93 ++- misc/Makefile.in | 59 ++ misc/atom.c | 16 +- misc/dos_fs.c | 896 ++++++++++----------- misc/exec.c | 1 - misc/file.c | 14 +- misc/kernel32.c | 1 + misc/main.c | 30 +- misc/profile.c | 23 +- misc/spy.c | 137 +++- misc/user.c | 1 - misc/winsocket.c | 224 ++++-- miscemu/Imakefile | 2 - miscemu/Makefile.in | 51 ++ miscemu/dpmi.c | 33 +- miscemu/instr.c | 218 +++-- miscemu/int10.c | 85 +- miscemu/int13.c | 22 +- miscemu/int15.c | 19 - miscemu/int16.c | 19 - miscemu/int1a.c | 21 +- miscemu/int21.c | 151 ++-- miscemu/int25.c | 21 +- miscemu/int26.c | 21 +- miscemu/int2a.c | 25 +- miscemu/int2f.c | 42 +- miscemu/int5c.c | 20 +- miscemu/interrupts.c | 317 +++----- miscemu/ioports.c | 173 ++-- multimedia/Imakefile | 4 +- multimedia/Makefile.in | 51 ++ multimedia/joystick.c | 98 +++ multimedia/midi.c | 10 - multimedia/mmsystem.c | 293 +------ multimedia/time.c | 198 +++++ objects/Makefile.in | 51 ++ objects/bitmap.c | 2 +- objects/clipping.c | 4 +- objects/dib.c | 19 +- objects/font.c | 43 +- objects/gdiobj.c | 2 +- objects/metafile.c | 2 +- objects/region.c | 21 + objects/text.c | 4 +- rc/Imakefile | 4 +- rc/Makefile.in | 59 ++ rc/winerc.c | 6 +- toolkit/sup.c | 1 - tools/Makefile.in | 41 + tools/build.c | 31 +- tools/ipcl | 92 +++ windows/Makefile.in | 54 ++ windows/class.c | 11 +- windows/cursor.c | 16 +- windows/defwnd.c | 14 +- windows/dialog.c | 2 +- windows/event.c | 3 +- windows/graphics.c | 12 + windows/mdi.c | 19 +- windows/message.c | 212 +++-- windows/nonclient.c | 6 +- windows/painting.c | 2 +- windows/timer.c | 4 + windows/win.c | 67 +- windows/winpos.c | 9 +- 165 files changed, 10494 insertions(+), 2684 deletions(-) create mode 100644 Makefile.in create mode 100644 autoconf.h.in create mode 100755 configure create mode 100644 configure.in create mode 100644 controls/Makefile.in create mode 100644 debugger/Makefile.in create mode 100644 debugger/readline/Makefile.in delete mode 100644 debugger/readline/complete.c delete mode 100644 debugger/readline/testit.c delete mode 100644 debugger/readline/unix.h create mode 100644 if1632/Makefile.in rewrite if1632/keyboard.spec (69%) create mode 100644 include/bit_array.h create mode 100644 include/config.h.in create mode 100644 include/dde.h create mode 100644 include/dde_atom.h create mode 100644 include/dde_mem.h create mode 100644 include/dde_proc.h rewrite include/miscemu.h (81%) delete mode 100644 include/prototypes.h create mode 100644 include/shm_block.h create mode 100644 include/shm_fragment.h create mode 100644 include/shm_main_blk.h create mode 100644 include/shm_semaph.h delete mode 100644 include/wineopts.h create mode 100644 ipc/Imakefile create mode 100644 ipc/Makefile.in create mode 100644 ipc/README create mode 100644 ipc/TEST_FRAGMENT.std create mode 100644 ipc/bit_array.c create mode 100644 ipc/bit_array_test.c create mode 100644 ipc/dde_atom.c create mode 100644 ipc/dde_atom_test.c create mode 100644 ipc/dde_mem.c create mode 100644 ipc/dde_mem_test.c create mode 100644 ipc/dde_proc.c create mode 100644 ipc/dde_proc_test.c create mode 100644 ipc/generic_hash.c create mode 100644 ipc/generic_hash.h create mode 100644 ipc/hash_test.c create mode 100644 ipc/run_tests create mode 100644 ipc/shm_block.c create mode 100644 ipc/shm_fragment.c create mode 100644 ipc/shm_fragment_test.c create mode 100644 ipc/shm_main_blk.c create mode 100644 ipc/shm_semaph.c create mode 100644 ipc/shm_semaph_test.c create mode 100644 ipc/wine_test_stub.c create mode 100644 loader/Makefile.in delete mode 100644 loader/dump.c create mode 100644 memory/Makefile.in create mode 100644 misc/Makefile.in create mode 100644 miscemu/Makefile.in rewrite miscemu/int10.c (80%) delete mode 100644 miscemu/int15.c delete mode 100644 miscemu/int16.c rewrite miscemu/interrupts.c (66%) rewrite miscemu/ioports.c (91%) create mode 100644 multimedia/Makefile.in create mode 100644 multimedia/joystick.c create mode 100644 multimedia/time.c create mode 100644 objects/Makefile.in create mode 100644 rc/Makefile.in create mode 100644 tools/Makefile.in create mode 100644 tools/ipcl create mode 100644 windows/Makefile.in diff --git a/ANNOUNCE b/ANNOUNCE index 35713f19d3a..a8b38b9f3d3 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 @@ Because of lags created by using mirror, this message may reach you before 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 4eab56d2e3a..b093b418be6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,193 @@ ---------------------------------------------------------------------- -Wed Jul 5 19:06:35 1995 Alexandre Julliard +Sat Jul 22 22:39:09 IDT 1995 Michael Veksler + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 + + * [*/*] + Added missing prototypes to header files and relevant includes + to reduce compile time warnings. + +Sun Jul 9 18:32:56 1995 Michael Patra + + * [configure.in] [include/config.h] [*/Makefile.in] + New configuration scheme based on autoconf. + +Sat Jul 8 14:12:45 1995 Morten Welinder + + * [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 + + * [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 * [controls/scroll.c] Fixed drawing bug that caused part of a non-client scroll bar diff --git a/Configure b/Configure index 3a4c6f7cfb8..9a9435a9dc0 100644 --- a/Configure +++ b/Configure @@ -106,7 +106,6 @@ then 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 @@ Com2=$CF_Com2 Lpt1=$CF_Lpt1 [spy] -File=$CF_File Exclude=$CF_Exclude EOF diff --git a/Imakefile b/Imakefile index 492798d0bf6..5488945df88 100644 --- a/Imakefile +++ b/Imakefile @@ -7,13 +7,6 @@ CC = gcc -D__FreeBSD__ #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 @@ CDEBUGFLAGS = -O2 -Wall COMMONSUBDIRS = \ controls \ rc \ + ipc \ loader \ misc \ multimedia \ @@ -53,6 +47,7 @@ WINEDIR = $(LIBDIR)/wine COMMONOBJS = \ controls/controls.o \ + ipc/ipc.o \ loader/loader.o \ misc/misc.o \ multimedia/multimedia.o \ @@ -122,4 +117,4 @@ etags:: 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 00000000000..bec1f10eece --- /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 +# + +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 00000000000..9c92cf47545 --- /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 00000000000..f495a92c155 --- /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 <&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 < +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 < +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 +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 <&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 <&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 < +/* 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 <&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 +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 <&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 < +#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 <&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 <&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 <&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 < +#include + +#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 <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 </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 < +#include +#include +#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* + 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 +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 +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 < +#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 < +#if STDC_HEADERS +#include +#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 <&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 </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 <> $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 <> $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 00000000000..9912fa92015 --- /dev/null +++ b/configure.in @@ -0,0 +1,148 @@ +dnl Process this file with autoconf to produce a configure script. +dnl Author: Michael Patra +dnl +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 00000000000..5bdd7a9cfeb --- /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 d1fc9ac64c2..1a081f02f90 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -601,14 +601,12 @@ int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec) } 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 6cea09d3842..d838e49ab53 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -1660,15 +1660,17 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt 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 @@ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt { 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 00000000000..39cada30b95 --- /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 c9a5585a4a3..7d0022f0e23 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -72,7 +72,8 @@ void mode_command(int); | 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 @@ x_command: 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 4b8ccf100f3..862c1f8a5ec 100644 --- a/debugger/debug.l +++ b/debugger/debug.l @@ -37,7 +37,7 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]* \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 65f8bbd10c7..109161dc3cc 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 aebd03a0c97..6678bcb7ed7 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 00000000000..9f2023eadee --- /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 c5cbaaa26a5..00000000000 --- a/debugger/readline/complete.c +++ /dev/null @@ -1,222 +0,0 @@ -/* $Revision: 1.3 $ -** -** History and file completion functions for editline library. -*/ -#include -#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 cd20bbbb4a0..eea22d76a48 100644 --- a/debugger/readline/editline.c +++ b/debugger/readline/editline.c @@ -78,8 +78,8 @@ STATIC int OldPoint; 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 @@ TTYinfo() } -/* -** 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 @@ end_line() 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 @@ STATIC KEYMAP Map[33] = { { 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 @@ STATIC KEYMAP MetaMap[16]= { { '.', 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 40a20258bd0..fa16f3b318d 100644 --- a/debugger/readline/editline.h +++ b/debugger/readline/editline.h @@ -3,20 +3,17 @@ ** Internal header file for editline library. */ #include -#if defined(HAVE_STDLIB) #include #include -#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 +#include -#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 @@ typedef unsigned char CHAR; #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 char *rl_complete(); 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 010744e1c4a..e2b72e1a01c 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 diff --git a/debugger/readline/testit.c b/debugger/readline/testit.c deleted file mode 100644 index e6384b8adb7..00000000000 --- 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 -#if defined(HAVE_STDLIB) -#include -#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 fe6beedcec2..00000000000 --- 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 -#include - -#if defined(USE_DIRENT) -#include -typedef struct dirent DIRENTRY; -#else -#include -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 00000000000..71ea491e09a --- /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 94a31ec1ab1..7b302ad3b45 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -47,7 +47,7 @@ id 3 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 e546d1d9e7b..a35124277eb 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -42,7 +42,7 @@ id 1 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 @@ id 1 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 @@ id 1 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 dissimilarity index 69% index afea764bd1b..af38f70a9c7 100644 --- a/if1632/keyboard.spec +++ b/if1632/keyboard.spec @@ -1,24 +1,24 @@ -name keyboard -id 7 - -#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 -#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 -#136 pascal EnableKbSysReq -#137 pascal GetBiosKeyProc - +name keyboard +id 7 + +#1 pascal Inquire +#2 pascal Enable +#3 pascal Disable +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 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 879ecfcde34..0c04a8d1f03 100644 --- a/if1632/mouse.spec +++ b/if1632/mouse.spec @@ -6,5 +6,6 @@ id 13 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 152451738a8..72de9662eef 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 @@ BOOL RELAY_Init(void) 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 @@ BOOL RELAY_Init(void) /*********************************************************************** * 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 @@ void RELAY_DebugCall32( char *args ) 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 @@ void RELAY_DebugReturn( int func_type, int ret_val ) 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 b5512b37680..8be2aa3aa09 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -253,7 +253,7 @@ id 2 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 @@ id 2 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 @@ id 2 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 8a0e88d15aa..b95e0744a91 100644 --- a/if1632/winprocs.spec +++ b/if1632/winprocs.spec @@ -25,23 +25,265 @@ id 24 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 24187167f2e..813f364019f 100644 --- a/if1632/winsock.spec +++ b/if1632/winsock.spec @@ -15,7 +15,7 @@ id 8 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 @@ id 8 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 045c3437388..631f185638e 100644 --- a/include/atom.h +++ b/include/atom.h @@ -31,4 +31,14 @@ typedef struct #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 00000000000..b07cdf66dd5 --- /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 00000000000..10c6b6989b6 --- /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 00000000000..72d250c7bea --- /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 00000000000..56df6b7e75d --- /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 00000000000..6a830e15161 --- /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 00000000000..85e682accfb --- /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 +#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 d728531dd6c..8d746158440 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 @@ short debug_msg_enabled[]={ #else 0, #endif +#ifdef DEBUG_ATOM + 1, +#else + 0, +#endif #ifdef DEBUG_BITBLT 1, #else @@ -229,6 +244,11 @@ short debug_msg_enabled[]={ #else 0, #endif +#ifdef DEBUG_DDE + 1, +#else + 0, +#endif #ifdef DEBUG_DIALOG 1, #else @@ -469,6 +489,21 @@ short debug_msg_enabled[]={ #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #ifdef DEBUG_DEFINE_VARIABLES static char *debug_msg_name[] = { "accel", + "atom", "bitblt", "bitmap", "caret", @@ -1448,6 +1549,7 @@ static char *debug_msg_name[] = { "comm", "cursor", "dc", + "dde", "dialog", "dll", "dosfs", @@ -1496,6 +1598,9 @@ static char *debug_msg_name[] = { "scroll", "selector", "selectors", + "sem", + "shm", + "spy", "stress", "syscolor", "task", diff --git a/include/dos_fs.h b/include/dos_fs.h index 01a458cdaea..a6a91a34c43 100644 --- a/include/dos_fs.h +++ b/include/dos_fs.h @@ -10,10 +10,9 @@ extern int DOS_GetDefaultDrive(void); extern void DOS_SetDefaultDrive(int drive); extern void ToUnix(char *s); extern void ToDos(char *s); -extern void ChopOffSlash(char *string); extern int DOS_DisableDrive(int drive); extern int DOS_EnableDrive(int drive); -extern char *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 char *WinIniFileName(void); extern struct dosdirent *DOS_opendir(char *dosdirname); extern struct dosdirent *DOS_readdir(struct dosdirent *de); extern void DOS_closedir(struct dosdirent *de); -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 dd912ce1372..6ea7b40a631 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 6e7c8531323..76f9ca0eee3 100644 --- a/include/ldt.h +++ b/include/ldt.h @@ -44,13 +44,13 @@ typedef struct 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 @@ extern ldt_copy_entry ldt_copy[LDT_SIZE]; #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 @@ extern unsigned char ldt_flags_copy[LDT_SIZE]; #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 dissimilarity index 81% index e979ff16d95..2507a80456a 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -1,39 +1,25 @@ -#ifndef __WINE_MISCEMU_H -#define __WINE_MISCEMU_H - -#include "wintypes.h" -#include "wine.h" - -extern BOOL INSTR_HandleInstruction( 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 BOOL INT_Init(void); -extern SEGPTR INT_GetHandler( BYTE intnum ); -extern void INT_SetHandler( BYTE intnum, SEGPTR handler ); - -extern void INT21_Init(void); - -#endif /* __WINE_MISCEMU_H */ +#ifndef __WINE_MISCEMU_H +#define __WINE_MISCEMU_H + +#include "wintypes.h" +#include "wine.h" + +extern BOOL INSTR_EmulateInstruction( 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 ); +extern void INT_SetHandler( BYTE intnum, SEGPTR handler ); + +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 1a94bca3ebc..636ae22f169 100644 --- a/include/msdos.h +++ b/include/msdos.h @@ -40,21 +40,23 @@ extern WORD ExtendedError; 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 getword(a) (WORD) *(BYTE*)(a) + \ - (*((BYTE*)(a) + 1) << 8) - -#define getdword(a) (DWORD) (*(BYTE*)(a) + \ - (*((BYTE*)(a) + 1) << 8) + \ - (*((BYTE*)(a) + 2) << 16) + \ - (*((BYTE*)(a) + 3) << 24)) +#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) + \ + ((WORD)*((BYTE*)(a) + 1) << 8)) + +#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 80b8a73a1f9..a19ae5717bd 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 d7fceee18ee..169ddd8f1d0 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 5c8d64de2e5..00000000000 --- 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 - -#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 7d87c1360cc..e8f62618fcd 100644 --- a/include/region.h +++ b/include/region.h @@ -18,5 +18,6 @@ typedef struct 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 4af04bc0b79..e6253f35299 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 d389ce4d714..6a5eeb253f1 100644 --- a/include/resource.h +++ b/include/resource.h @@ -17,6 +17,9 @@ extern SEGPTR NE_LockResource( HMODULE hModule, HGLOBAL handle ); 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 6a30151d129..b222e7efb36 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 00000000000..c19c84ff026 --- /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 +#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 00000000000..81a4b66a371 --- /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 00000000000..e3f9e5b9b85 --- /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 +#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 00000000000..55624464894 --- /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 ee0195bb54e..81fcf8ee333 100644 --- a/include/stackframe.h +++ b/include/stackframe.h @@ -19,6 +19,7 @@ typedef struct { 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 b56809834ce..b2620207255 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 cbd28ae7e4e..dd7e9e81d31 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 f74900721e6..dc5c68acae3 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 e1d1efeb2a4..2322240d3be 100644 --- a/include/win.h +++ b/include/win.h @@ -74,6 +74,7 @@ extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); 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 0389728daa0..eb2f91015d0 100644 --- a/include/windows.h +++ b/include/windows.h @@ -2455,6 +2455,8 @@ Fa(DWORD,GetCurrentPosition,HDC,a) 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,GlobalLock,HGLOBAL,a) 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,SetMapMode,HDC,a,WORD,b) 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,GetTextFace,HDC,a,INT,b,LPSTR,c) 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,GetInternalWindowPos,HWND,a,LPRECT,b,LPPOINT,c) 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 6f3e66b81c5..00000000000 --- a/include/wineopts.h +++ /dev/null @@ -1,11 +0,0 @@ -/* WINEOPTS.H - */ - -#ifndef WINEOPTS_H -#define WINEOPTS_H - -#include - -FILE *SpyFp; - -#endif /* WINEOPTS_H */ diff --git a/include/winsock.h b/include/winsock.h index 2a2674b5072..a0450c24912 100644 --- a/include/winsock.h +++ b/include/winsock.h @@ -7,13 +7,13 @@ #ifndef _WINSOCKAPI_ #define _WINSOCKAPI_ -#include #include #include #include #include #include #include +#include "windows.h" /* * The new type to be used in all diff --git a/ipc/Imakefile b/ipc/Imakefile new file mode 100644 index 00000000000..cf5d6df44b8 --- /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 00000000000..fea89fe5824 --- /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 00000000000..6903f53265e --- /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 00000000000..968a440b1a0 --- /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 00000000000..d4cede85d75 --- /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 + +#include + +#include "bit_array.h" +#if defined(HAS_BITOPS) +# include +#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 00000000000..14ecb344615 --- /dev/null +++ b/ipc/bit_array_test.c @@ -0,0 +1,93 @@ +#include +#include +#include +#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 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 00000000000..c6ca2aa5b01 --- /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 +#include +#include +#include +#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<> (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 (atomsem); + + 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 (atomsem); + 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 00000000000..dd587c4413b --- /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 +#include +#include +#include "dde_atom.h" +#include "shm_main_blk.h" +#include +#include +#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=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 +#include +#include +#include +#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 00000000000..2fe42a5a326 --- /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 +#include +#include +#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 00000000000..9f5f59e9010 --- /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 +#include +#include +#include +#include +#include +#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_nummsg=-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_idxpid==-1) + break; /* found! */ + + if (proc_idxmsg); + 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 00000000000..1291fd849b2 --- /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 +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#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 00000000000..6cee5d39a53 --- /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 +#include +#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 00000000000..5def7e6a794 --- /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 00000000000..dec32c4c6c5 --- /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 +#include +#include +#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 00000000000..638fb1807a2 --- /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 00000000000..057c981e271 --- /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 +#include +#include +#include +#include +#include +#include +#include +#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 00000000000..098d6cc14a9 --- /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 /* for debugging only */ +#include +#include /* 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 00000000000..896471543a2 --- /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 +#include +#include +#define DEBUG_DEFINE_VARIABLES /* just avoid dumb errors */ +#include /* for "stddeb" */ +#include +#include +#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 00000000000..3fb798e6f50 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#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 00000000000..c2268089950 --- /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 +#include +#include +#include +#include +#include +#include +#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 00000000000..fdceeb58f1d --- /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 +#include +#include +#include +#include +#include +#include "shm_semaph.h" +#include +#define DEBUG_DEFINE_VARIABLES +#include +#include + +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 00000000000..fb1747e66d0 --- /dev/null +++ b/ipc/wine_test_stub.c @@ -0,0 +1,117 @@ +#include +#include "dde.h" +#include +#include "global.h" +#include +#define DEBUG_DEFINE_VARIABLES +#define DEBUG_ALL +#include +#include + +#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 befe47a6a63..3ec199f6ce7 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 00000000000..b9cd285d6a3 --- /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 39344e52b68..00000000000 --- 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 -#include -#include -#include -#include -#include -#ifdef linux -#include -#include -#include -#endif -#include -#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 7a2d4350121..0e301df154d 100644 --- a/loader/main.c +++ b/loader/main.c @@ -11,6 +11,18 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #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 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #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 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; int MAIN_Init(void) { extern BOOL RELAY_Init(void); + extern BOOL RELAY32_Init(void); int queueSize; @@ -103,14 +117,22 @@ int MAIN_Init(void) 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 01d2678f52f..12cf6ba8f23 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 @@ BOOL MODULE_Init(void) 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 @@ BOOL MODULE_Init(void) 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 @@ BOOL MODULE_Init(void) 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 @@ static BOOL MODULE_CreateSegments( HMODULE hModule ) { 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 @@ BOOL FreeModule( HANDLE hModule ) /********************************************************************** * 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 ee1b119f724..2d284b5f86f 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -197,7 +197,7 @@ HINSTANCE PE_LoadImage(struct w_files *wpnt) 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 4cf44cf20bc..4e6bbfc00d9 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 d04e4f1a6fa..ab211bdeb37 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -8,33 +8,12 @@ #include #include #include -#include -#include -#include #include #ifndef WINELIB -#ifdef __linux__ -#include -#include -#include -#include -#include -#include -#endif -#if defined(__NetBSD__) || defined(__FreeBSD__) -#include -#include -#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 e7c83816d60..4ede072c318 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 @@ static void win_fault(int signal, int code, struct sigcontext *context) 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 @@ void init_wine_signals(void) 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 222bd016256..53d1006f3a0 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, /* 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, /* 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, /* 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 @@ void TASK_Reschedule(void) 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 00000000000..80be79aa6e5 --- /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 c1f5ab9feab..83c32131ca4 100644 --- a/memory/global.c +++ b/memory/global.c @@ -6,10 +6,12 @@ #include #include + #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 @@ typedef struct 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 @@ static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount ) } +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 @@ static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount ) */ 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 @@ HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size, 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 @@ BOOL GLOBAL_FreeBlock( HGLOBAL handle ) 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 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, { void *ptr; HGLOBAL handle; + SHMDATA shmdata; dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags ); @@ -145,13 +194,16 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, /* 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 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, 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 @@ HGLOBAL GlobalAlloc( WORD flags, DWORD size ) 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 GlobalAlloc( WORD flags, DWORD size ) */ 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 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags ) (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 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags ) /* 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 GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags ) */ 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 @@ SEGPTR WIN16_GlobalLock( HGLOBAL handle ) 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 @@ SEGPTR WIN16_GlobalLock( HGLOBAL handle ) 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 @@ WORD GlobalHandleToSel( HGLOBAL handle ) { 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 f80b2ccddb3..2b07893656e 100644 --- a/memory/ldt.c +++ b/memory/ldt.c @@ -157,7 +157,8 @@ int LDT_SetEntry( int entry, const ldt_entry *content ) 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 57afc7f10d7..1959c712c31 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 @@ WORD AllocSelectorArray( WORD count ) 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 @@ WORD FreeSelector( WORD sel ) 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 @@ static void SELECTOR_SetEntries( WORD sel, void *base, DWORD size, /*********************************************************************** - * 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_AllocBlock( void *base, DWORD size, enum seg_type type, 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) size = 1; + oldcount = (GET_SEL_LIMIT(sel) >> 16) + 1; + newcount = (size + 0xffff) >> 16; - if (!size) + 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; + } + } + 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; + } } - count = (size + 0xffff) / 0x10000; - sel = SELECTOR_ReallocArray( sel, count ); 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 00000000000..84afd90dc2e --- /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 a34e0626cc4..f3286cdaae2 100644 --- a/misc/atom.c +++ b/misc/atom.c @@ -329,36 +329,36 @@ WORD GetAtomName( ATOM atom, LPSTR buffer, short count ) /*********************************************************************** - * 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 08de3c00992..c1fd2403d6a 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 @@ static int CurrentDrive = 2; 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 @@ static void ExpandTildeString(char *s) *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]; - - 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; + 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", "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; - - /* 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, "\\" ); - - 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 - ); - } + 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. + */ + + 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); } - - 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 @@ void DOS_InitFS(void) 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 @@ WORD DOS_GetEquipment(void) 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) -- ",'A'+drive,drive); + dprintf_dosfs(stddeb,"ValidDrive %c (%d)\n",'A'+drive,drive); - 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; -} + if (drive < 0 || drive >= MAX_DOS_DRIVES) return 0; + if (DosDrives[drive].rootdir == NULL) return 0; + if (DosDrives[drive].disabled) return 0; - -int DOS_ValidDirectory(char *name) -{ - 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; + dprintf_dosfs(stddeb, " -- valid\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) +static void DOS_GetCurrDir_Unix(char *buffer, int drive) { - 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'; +char *DOS_GetCurrentDir(int drive) +{ + static char temp[256]; - ToUnix(rootdir); + if (!DOS_ValidDrive(drive)) return 0; - dprintf_dosfs(stddeb,"%s\n", rootdir); + DOS_GetCurrDir_Unix(temp, drive); + DOS_SimplifyPath( temp ); + ToDos(temp); + ChopOffSlash(temp); + dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp); + return temp + 1; } -char *DOS_GetUnixFileName(char *dosfilename) +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 temp[256]; - static char dostemp[256]; - int drive; - - if (dosfilename[0] && (dosfilename[1] == ':')) - { - drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A'; - - if (!DOS_ValidDrive(drive)) - return NULL; - else - dosfilename+=2; - } else - drive = CurrentDrive; - - /* Consider dosfilename const */ - strncpy( dostemp, dosfilename, 255 ); - dostemp[255] = '\0'; - - /* 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); + /* 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; + + 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_GetUnixFileName(char *dosfilename) */ 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); + } + } + 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); - return(temp); + } + sprintf(temp, "Z:%s", unixfilename); + ToDos(temp+2); + return temp; } -char *DOS_GetCurrentDir(int drive) -{ - static char temp[256]; - - if (!DOS_ValidDrive(drive)) - return 0; - - strcpy(temp, DosDrives[drive].cwd); - DOS_SimplifyPath( temp ); - ToDos(temp); - ChopOffSlash(temp); - - dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp); - return (temp + 1); +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; } -int DOS_ChangeDir(int drive, char *dirname) +int DOS_GetDefaultDrive(void) { - char temp[256],old[256]; - - if (!DOS_ValidDrive(drive)) - return 0; - - strcpy(temp, dirname); - ToUnix(temp); - strcpy(old, DosDrives[drive].cwd); - - GetUnixDirName(DosDrives[drive].cwd, temp); - strcat(DosDrives[drive].cwd,"/"); - - dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s\n",'A'+drive, - DosDrives[drive].cwd); + TDB *pTask = (TDB *)GlobalLock(GetCurrentTask()); + int drive = pTask == NULL ? CurrentDrive : pTask->curdrive & ~0x80; + + dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+drive); + return drive; +} - if (!DOS_ValidDirectory(DosDrives[drive].cwd)) - { - strcpy(DosDrives[drive].cwd, old); - return 0; +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"); } - DOS_SimplifyPath(DosDrives[drive].cwd); - return 1; + } } -int DOS_MakeDir(int drive, char *dirname) +int DOS_DisableDrive(int drive) { - char temp[256]; - - if (!DOS_ValidDrive(drive)) - return 0; + if (drive >= MAX_DOS_DRIVES) return 0; + if (DosDrives[drive].rootdir == NULL) 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; + DosDrives[drive].disabled = 1; + 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) +int DOS_EnableDrive(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; + if (drive >= MAX_DOS_DRIVES) return 0; + if (DosDrives[drive].rootdir == NULL) return 0; - strcpy(temp, DosDrives[drive].cwd); - strcat(temp, filename); - strcpy(filename, temp); - - dprintf_dosfs(stddeb, " Expanded = %s\n", temp); + DosDrives[drive].disabled = 0; + return 1; } -/* 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) +int DOS_ChangeDir(int drive, char *dirname) { - char temp[256]; + TDB *pTask = (TDB *)GlobalLock(GetCurrentTask()); + char temp[256]; + + if (!DOS_ValidDrive(drive)) return 0; - if(filename[0] == '/') - return; + if (dirname[0] == '\\') { + strcpy(temp, dirname); + } 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); + + 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; +} - 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); +int DOS_MakeDir(int drive, char *dirname) +{ + char temp[256], currdir[256]; + + if (!DOS_ValidDrive(drive)) return 0; + + 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 @@ char *DOS_GetVolumeLabel(int drive) 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 @@ char *DOS_FindFile(char *buffer, int buflen, char *filename, char **extensions, if (S_ISREG(filestat.st_mode)) { closedir(d); free(rootname); + DOS_SimplifyPath(buffer); return buffer; } } @@ -769,15 +674,15 @@ char *WineIniFileName(void) 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 @@ static int match(char *filename, char *filemask) struct dosdirent *DOS_opendir(char *dosdirname) { - int x,y; - char *unixdirname; - char temp[256]; - DIR *ds; - - if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL) - return NULL; - - 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) { + 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; + + 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 @@ struct dosdirent *DOS_readdir(struct dosdirent *de) 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 635f4bde847..ab5bc0eb5e5 100644 --- a/misc/exec.c +++ b/misc/exec.c @@ -8,7 +8,6 @@ #include #include #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 ef45ec50266..3581ce3d1f1 100644 --- a/misc/file.c +++ b/misc/file.c @@ -108,8 +108,8 @@ INT _lclose (INT hFile) { 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 @@ INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle) 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 @@ INT _lcreat (LPSTR lpszFilename, INT fnAttribute) 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 @@ UINT GetWindowsDirectory(LPSTR lpszSysPath, UINT cbSysPath) dprintf_file(stddeb,"GetWindowsDirectory (%s)\n",lpszSysPath); - ChopOffSlash(lpszSysPath); - return(strlen(lpszSysPath)); + return strlen(lpszSysPath); } /*************************************************************************** GetSystemDirectory @@ -387,8 +386,7 @@ UINT GetSystemDirectory(LPSTR lpszSysPath, UINT cbSysPath) 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 0be2b097325..df6a5ba1217 100644 --- a/misc/kernel32.c +++ b/misc/kernel32.c @@ -9,6 +9,7 @@ #include "windows.h" #include "winerror.h" +#include int WIN32_LastError; diff --git a/misc/main.c b/misc/main.c index f5f8544c58d..3528df55c55 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 #include #include @@ -24,7 +23,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #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 @@ int desktopX = 0, desktopY = 0; /* Desktop window position (if any) */ struct options Options = { /* default options */ - NULL, /* spyFilename */ NULL, /* desktopGeometry */ NULL, /* programName */ FALSE, /* usePrivateMap */ @@ -86,7 +83,6 @@ static XrmOptionDescRec optionsTable[] = { "-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 @@ static XrmOptionDescRec optionsTable[] = " -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 @@ static void MAIN_ParseOptions( int *argc, char *argv[] ) 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 @@ static void MAIN_RestoreSetup(void) 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 main( int argc, char *argv[] ) 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 GetVersion(void) 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 71e537372ce..0c3df911bde 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -96,7 +96,8 @@ static TSecHeader *load (char *filename, char **pfullname) 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 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, 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 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, 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 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, 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 7c82b106253..835f8c64023 100644 --- a/misc/spy.c +++ b/misc/spy.c @@ -8,14 +8,13 @@ #include #include #include -#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 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "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 @@ void SpyMessage(HWND hwnd, WORD msg, WORD wParam, LONG lParam) 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 SpyMessage(HWND hwnd, WORD msg, WORD wParam, LONG lParam) */ 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 @@ void SpyInit(void) if (*SpyFilters != 0) { strcat(SpyFilters, ";"); } -#endif } diff --git a/misc/user.c b/misc/user.c index 86a09f5871d..98b7b1b5ce2 100644 --- a/misc/user.c +++ b/misc/user.c @@ -17,7 +17,6 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #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 ee953753920..2fdd5a6c595 100644 --- a/misc/winsocket.c +++ b/misc/winsocket.c @@ -20,6 +20,7 @@ #include #include #include "winsock.h" +#include "toolhelp.h" #include "stddebug.h" #include "debug.h" @@ -37,33 +38,36 @@ struct ipc_packet { 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 WinSockHeap { 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 @@ static struct WinSockHeap *heap; 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 @@ static void convert_sockopt(INT *level, INT *optname) } #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_PROTOENT(struct WIN_protoent *heap, struct protoent *proto) +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_SERVENT(struct WIN_servent *heap, struct servent *serv) +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 *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 @@ char *WINSOCK_inet_ntoa(struct in_addr in) 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); + + /* 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 (ioctl(s, cmd, argp) < 0) { + 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 @@ SOCKET WINSOCK_socket(INT af, INT type, INT protocol) 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 @@ struct WIN_hostent *WINSOCK_gethostbyaddr(const char *addr, INT len, INT type) 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 @@ struct WIN_hostent *WINSOCK_gethostbyname(const char *name) 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 @@ INT WINSOCK_gethostname(char *name, INT namelen) return 0; } -struct WIN_protoent *WINSOCK_getprotobyname(char *name) +/* +struct WIN_protoent * +*/ +SEGPTR WINSOCK_getprotobyname(char *name) { struct protoent *proto; @@ -536,12 +664,15 @@ struct WIN_protoent *WINSOCK_getprotobyname(char *name) 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 @@ struct WIN_protoent *WINSOCK_getprotobynumber(INT number) 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 @@ struct WIN_servent *WINSOCK_getservbyname(const char *name, const char *proto) 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 @@ struct WIN_servent *WINSOCK_getservbyport(INT port, const char *proto) 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 WSACancelBlockingCall(void) 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 @@ WSADATA WINSOCK_data = { INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) { - int HeapHandle; dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested); @@ -903,7 +1039,7 @@ INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) 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 a73da1c745e..74a89dfce05 100644 --- a/miscemu/Imakefile +++ b/miscemu/Imakefile @@ -8,8 +8,6 @@ SRCS = \ 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 00000000000..8cf8cce7945 --- /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 c44a6af6c70..2b63159cbb7 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 @@ int do_int31( struct sigcontext_struct *context ) 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 @@ int do_int31( struct sigcontext_struct *context ) 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 b025452f64b..3be1990e7c3 100644 --- a/miscemu/instr.c +++ b/miscemu/instr.c @@ -6,55 +6,11 @@ #include #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 @@ static int do_int(int intnum, struct sigcontext_struct *context) */ 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 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context ) 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 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context ) switch(*instr) { - case 0xcd: /* int */ - instr++; - /* FIXME: should check if handler has been changed */ - if (!do_int(*instr, context)) + case 0xcd: /* int */ + 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 @@ BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context ) 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 dissimilarity index 80% index 501b1838940..04a1a87bdec 100644 --- a/miscemu/int10.c +++ b/miscemu/int10.c @@ -1,44 +1,41 @@ -#include -#include -#include "registers.h" -#include "wine.h" -#include "miscemu.h" -#include "stddebug.h" -/* #define DEBUG_INT */ -#include "debug.h" - -void IntBarf(int i, struct sigcontext_struct *context) -{ - 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); -} - -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 0x1a: - BX = 0x0008; - break; - - default: - IntBarf(0x10, context); - }; - return 1; -} +#include +#include +#include "registers.h" +#include "wine.h" +#include "miscemu.h" +#include "stddebug.h" +/* #define DEBUG_INT */ +#include "debug.h" + + +/********************************************************************** + * INT_Int10Handler + * + * Handler for int 10h (video). + */ +void INT_Int10Handler( struct sigcontext_struct sigcontext ) +{ +#define context (&sigcontext) + switch(AH) + { + case 0x0f: + AL = 0x5b; + break; + + case 0x12: + if (BL == 0x10) + { + BX = 0x0003; + CX = 0x0009; + } + break; + + case 0x1a: + BX = 0x0008; + break; + + default: + INT_BARF( 0x10 ); + } +#undef context +} diff --git a/miscemu/int13.c b/miscemu/int13.c index e0e62f51f6f..d570768c36b 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 @@ int do_int13(struct sigcontext_struct *context) 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 9efc47c553a..00000000000 --- a/miscemu/int15.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#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 b3cc06e1d49..00000000000 --- a/miscemu/int16.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#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 60a29ab4313..60cf634e691 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 @@ int do_int1a(struct sigcontext_struct * context){ 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 078f34e84b1..25b2f8c18a6 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 @@ static void GetFreeDiskSpace(struct sigcontext_struct *context) 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 GetFreeDiskSpace(struct sigcontext_struct *context) 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 @@ static void GetDriveAllocInfo(struct sigcontext_struct *context) 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 @@ static void GetDriveAllocInfo(struct sigcontext_struct *context) 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 @@ static void GetDrivePB(struct sigcontext_struct *context, int drive) 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 @@ static void ioctlGetDeviceInfo(struct sigcontext_struct *context) if (fstat(BX, &sbuf) < 0) { - IntBarf(0x21, context); + INT_BARF( 0x21 ); SetCflag; return; } @@ -444,8 +443,8 @@ static void ioctlGenericBlkDevReq(struct sigcontext_struct *context) } if (CH != 0x08) { - IntBarf(0x21, context); - return; + INT_BARF( 0x21 ); + return; } switch (CL) { case 0x60: /* get device parameters */ @@ -469,7 +468,7 @@ static void ioctlGenericBlkDevReq(struct sigcontext_struct *context) ResetCflag; return; default: - IntBarf(0x21, context); + INT_BARF( 0x21 ); } } @@ -508,18 +507,18 @@ static void GetExtendedErrorInfo(struct sigcontext_struct *context) 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 @@ static void FindNext(struct sigcontext_struct *context) 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 @@ static void FindFirst(struct sigcontext_struct *context) 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 @@ static void CreateTempFile(struct sigcontext_struct *context) 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 @@ static void CreateNewFile(struct sigcontext_struct *context) { 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 @@ static void GetFileAttribute (struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) "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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) break; default: - IntBarf(0x21, context); + INT_BARF( 0x21 ); break; } break; @@ -1541,7 +1528,7 @@ int do_int21(struct sigcontext_struct * context) break; default: - IntBarf(0x21, context); + INT_BARF( 0x21 ); break; } break; @@ -1575,8 +1562,8 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 6ebc32ea45a..54270757290 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 @@ int do_int25(struct sigcontext_struct *context) { 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 @@ int do_int25(struct sigcontext_struct *context) *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 97bf02ded47..aa281d7f504 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 @@ int do_int26(struct sigcontext_struct *context) { 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 @@ int do_int26(struct sigcontext_struct *context) "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 63ed11d4bfe..35921fb6a0a 100644 --- a/miscemu/int2a.c +++ b/miscemu/int2a.c @@ -2,20 +2,27 @@ #include #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 ad797d13111..88bd229c370 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 @@ int do_int2f_16(struct sigcontext_struct *context) 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 @@ int do_int2f_16(struct sigcontext_struct *context) 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 0bd1fd12e5f..ad94c25b558 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 dissimilarity index 66% index 01f957e8374..b576424c5a9 100644 --- a/miscemu/interrupts.c +++ b/miscemu/interrupts.c @@ -1,190 +1,127 @@ -/* - * Interrupt vectors emulation - * - * Copyright 1995 Alexandre Julliard - */ - -#include "windows.h" -#include "miscemu.h" -#include "module.h" -#include "stddebug.h" -#include "debug.h" - -static SEGPTR INT_Vectors[256]; - - /* Ordinal number for interrupt 0 handler in WINPROCS.DLL */ -#define FIRST_INTERRUPT_ORDINAL 100 - - -/********************************************************************** - * INT_Init - */ -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; - } - return TRUE; -} - - -/********************************************************************** - * INT_GetHandler - * - * Return the interrupt vector for a given interrupt. - */ -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]; -} - - -/********************************************************************** - * INT_SetHandler - * - * Set the interrupt handler for a given interrupt. - */ -void INT_SetHandler( BYTE intnum, SEGPTR handler ) -{ - dprintf_int( stddeb, "Set interrupt vector %02x <- %04x:%04x\n", - intnum, HIWORD(handler), LOWORD(handler) ); - INT_Vectors[intnum] = handler; -} - - -/********************************************************************** - * INT_DummyHandler - */ -void INT_DummyHandler( struct sigcontext_struct context ) -{ - 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 ); -} - - -/********************************************************************** - * INT_Int13Handler - */ -void INT_Int13Handler( struct sigcontext_struct context ) -{ - dprintf_int( stddeb, "int 13 called indirectly through handler!\n" ); - do_int13( &context ); -} - - -/********************************************************************** - * INT_Int15Handler - */ -void INT_Int15Handler( struct sigcontext_struct context ) -{ - dprintf_int( stddeb, "int 15 called indirectly through handler!\n" ); - do_int15( &context ); -} - - -/********************************************************************** - * INT_Int16Handler - */ -void INT_Int16Handler( struct sigcontext_struct context ) -{ - 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 ); -} +/* + * Interrupt vectors emulation + * + * Copyright 1995 Alexandre Julliard + */ + +#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" + +static SEGPTR INT_Vectors[256]; + + /* Ordinal number for interrupt 0 handler in WINPROCS.DLL */ +#define FIRST_INTERRUPT_ORDINAL 100 + + +/********************************************************************** + * INT_Init + */ +BOOL INT_Init(void) +{ + WORD vector; + HMODULE hModule = GetModuleHandle( "WINPROCS" ); + + for (vector = 0; vector < 256; vector++) + { + 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; +} + + +/********************************************************************** + * INT_GetHandler + * + * Return the interrupt vector for a given interrupt. + */ +SEGPTR INT_GetHandler( BYTE intnum ) +{ + return INT_Vectors[intnum]; +} + + +/********************************************************************** + * INT_SetHandler + * + * Set the interrupt handler for a given interrupt. + */ +void INT_SetHandler( BYTE intnum, SEGPTR handler ) +{ + dprintf_int( stddeb, "Set interrupt vector %02x <- %04x:%04x\n", + intnum, HIWORD(handler), LOWORD(handler) ); + INT_Vectors[intnum] = handler; +} + + +/********************************************************************** + * INT_DummyHandler + */ +void INT_DummyHandler( struct sigcontext_struct sigcontext ) +{ +#define context (&sigcontext) + INT_BARF( CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL ); +#undef context +} + + +/********************************************************************** + * INT_Int11Handler + * + * Handler for int 11h (get equipment list). + */ +void INT_Int11Handler( struct sigcontext_struct sigcontext ) +{ +#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 sigcontext ) +{ +#define context (&sigcontext) + INT_BARF( 0x15 ); +#undef context +} + + +/********************************************************************** + * INT_Int16Handler + * + * Handler for int 16h (keyboard). + */ +void INT_Int16Handler( struct sigcontext_struct sigcontext ) +{ +#define context (&sigcontext) + INT_BARF( 0x16 ); +#undef context +} diff --git a/miscemu/ioports.c b/miscemu/ioports.c dissimilarity index 91% index 161ca066f78..3ea012a25a9 100644 --- a/miscemu/ioports.c +++ b/miscemu/ioports.c @@ -1,87 +1,86 @@ -#include -#include -#include -#include "registers.h" -#include "wine.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) -{ - dprintf_int(stddeb, "IO: inb (%x)\n", DX); - - switch(DX) { - case 0x70: - AL = cmosaddress; - break; - case 0x71: - AL = cmosimage[cmosaddress & 0x3f]; - break; - default: - } -} - -void inport( struct sigcontext_struct *context, int long_op ) -{ - dprintf_int(stdnimp, "IO: in (%x)\n", DX); - if (long_op) EAX = 0xffffffff; - else AX = 0xffff; -} - -void inportb_abs(struct sigcontext_struct *context) -{ - dprintf_int(stdnimp, "IO: in (%x)\n", *(BYTE *)(EIP+1)); - AL = 0xff; -} - -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) - { - case 0x70: - cmosaddress = AL & 0x7f; - break; - case 0x71: - cmosimage[cmosaddress & 0x3f] = AL; - break; - default: - } -} - -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) -{ - dprintf_int(stdnimp, "IO: out (%x), %x\n", *(BYTE *)(EIP+1), AL); -} - -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); -} +/* + * 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 +#include +#include +#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 +}; + + +DWORD inport( int port, int count ) +{ + DWORD res = 0; + BYTE b; + + dprintf_int(stddeb, "IO: %d bytes from port 0x%02x\n", count, port ); + + while (count-- > 0) + { + switch (port++) + { + case 0x70: + b = cmosaddress; + break; + case 0x71: + b = cmosimage[cmosaddress & 0x3f]; + break; + default: + b = 0xff; + } + res = (res << 8) | b; + } + return res; +} + + +void outport( int port, int count, DWORD value ) +{ + BYTE b; + + 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 c7db9346c4e..582e384f1ba 100644 --- a/multimedia/Imakefile +++ b/multimedia/Imakefile @@ -4,11 +4,13 @@ MODULE = multimedia 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 00000000000..ceec464b0cd --- /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 00000000000..9eff80181da --- /dev/null +++ b/multimedia/joystick.c @@ -0,0 +1,98 @@ +/* + * MMSYTEM functions + * + * Copyright 1993 Martin Ayotte + */ + +#ifndef WINELIB + +#include +#include +#include +#include +#include +#include +#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 0a61f362f70..faa61b5c8b5 100644 --- a/multimedia/midi.c +++ b/multimedia/midi.c @@ -1227,16 +1227,6 @@ static DWORD modReset(WORD wDevID) /************************************************************************** -* 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 2a0164177bb..0d130a0ad41 100644 --- a/multimedia/mmsystem.c +++ b/multimedia/mmsystem.c @@ -25,40 +25,21 @@ static int InstalledCount; 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 @@ BOOL DriverCallback(DWORD dwCallBack, UINT uFlags, HANDLE hDev, } /************************************************************************** -* 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 @@ UINT waveInGetPosition(HWAVEIN hWaveIn, MMTIME FAR* lpTime, UINT uSize) 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 @@ UINT waveInGetID(HWAVEIN hWaveIn, UINT FAR* lpuDeviceID) * 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 @@ DWORD waveInMessage(HWAVEIN hWaveIn, UINT uMessage, /************************************************************************** -* 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 @@ HMMIO mmioOpen(LPSTR szFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwOpenFlags) 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 @@ UINT mmioClose(HMMIO hmmio, UINT uFlags) /************************************************************************** -* mmioRead [MMSYSTEM.1212] +* mmioRead [MMSYSTEM.1212] */ LONG mmioRead(HMMIO hmmio, HPSTR pch, LONG cch) { @@ -2175,7 +1926,7 @@ LONG mmioRead(HMMIO hmmio, HPSTR pch, LONG cch) /************************************************************************** -* mmioWrite [MMSYSTEM.1213] +* mmioWrite [MMSYSTEM.1213] */ LONG mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch) { @@ -2190,7 +1941,7 @@ LONG mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch) } /************************************************************************** -* mmioSeek [MMSYSTEM.1214] +* mmioSeek [MMSYSTEM.1214] */ LONG mmioSeek(HMMIO hmmio, LONG lOffset, int iOrigin) { @@ -2208,7 +1959,7 @@ LONG mmioSeek(HMMIO hmmio, LONG lOffset, int iOrigin) } /************************************************************************** -* mmioGetInfo [MMSYSTEM.1215] +* mmioGetInfo [MMSYSTEM.1215] */ UINT mmioGetInfo(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags) { @@ -2222,7 +1973,7 @@ UINT mmioGetInfo(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags) } /************************************************************************** -* mmioSetInfo [MMSYSTEM.1216] +* mmioSetInfo [MMSYSTEM.1216] */ UINT mmioSetInfo(HMMIO hmmio, const MMIOINFO FAR* lpmmioinfo, UINT uFlags) { @@ -2245,7 +1996,7 @@ UINT mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, } /************************************************************************** -* mmioFlush [MMSYSTEM.1218] +* mmioFlush [MMSYSTEM.1218] */ UINT mmioFlush(HMMIO hmmio, UINT uFlags) { @@ -2258,7 +2009,7 @@ UINT mmioFlush(HMMIO hmmio, UINT uFlags) } /************************************************************************** -* mmioAdvance [MMSYSTEM.1219] +* mmioAdvance [MMSYSTEM.1219] */ UINT mmioAdvance(HMMIO hmmio, MMIOINFO FAR* lpmmioinfo, UINT uFlags) { @@ -2311,7 +2062,7 @@ LRESULT mmioSendMessage(HMMIO hmmio, UINT uMessage, } /************************************************************************** -* mmioDescend [MMSYSTEM.1223] +* mmioDescend [MMSYSTEM.1223] */ UINT mmioDescend(HMMIO hmmio, MMCKINFO FAR* lpck, const MMCKINFO FAR* lpckParent, UINT uFlags) @@ -2372,7 +2123,7 @@ UINT mmioDescend(HMMIO hmmio, MMCKINFO FAR* lpck, } /************************************************************************** -* mmioAscend [MMSYSTEM.1224] +* mmioAscend [MMSYSTEM.1224] */ UINT mmioAscend(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags) { @@ -2391,7 +2142,7 @@ UINT mmioCreateChunk(HMMIO hmmio, MMCKINFO FAR* lpck, UINT uFlags) /************************************************************************** -* mmioRename [MMSYSTEM.1226] +* mmioRename [MMSYSTEM.1226] */ UINT mmioRename(LPCSTR szFileName, LPCSTR szNewFileName, MMIOINFO FAR* lpmmioinfo, DWORD dwRenameFlags) @@ -2402,7 +2153,7 @@ UINT mmioRename(LPCSTR szFileName, LPCSTR szNewFileName, } /************************************************************************** -* DrvOpen [MMSYSTEM.1100] +* DrvOpen [MMSYSTEM.1100] */ HDRVR DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam) { @@ -2413,7 +2164,7 @@ HDRVR DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam) /************************************************************************** -* 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 00000000000..bfa5abc9177 --- /dev/null +++ b/multimedia/time.c @@ -0,0 +1,198 @@ +/* + * MMSYTEM time functions + * + * Copyright 1993 Martin Ayotte + */ + +#ifndef WINELIB + +#include +#include +#include +#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 00000000000..4196d0a0f91 --- /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 e0f15c47c2c..179d16d7541 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 42dda4e6eae..003a6aec886 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -314,7 +314,9 @@ BOOL RectVisible( HDC hdc, LPRECT rect ) 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 78ab1ee7062..c2538b48ba2 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -517,17 +517,8 @@ static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits, 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 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, 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 @@ BOOL DrawIcon(HDC hDC, short x, short y, HICON hIcon) SetBkColor( hDC, oldBg ); return TRUE; } - diff --git a/objects/font.c b/objects/font.c index be927071373..200b605633c 100644 --- a/objects/font.c +++ b/objects/font.c @@ -262,32 +262,31 @@ void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont, /*********************************************************************** * 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 @@ int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData) 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 @@ int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData 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 2cfcd75d9a2..af7cccceccd 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -416,7 +416,7 @@ int EnumObjects(HDC hDC, int nObjType, FARPROC lpEnumFunc, LPSTR lpData) 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 9a8208a7b7b..846964e54f8 100644 --- a/objects/metafile.c +++ b/objects/metafile.c @@ -212,7 +212,7 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf) 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 41df11b6b7f..02a10d71935 100644 --- a/objects/region.c +++ b/objects/region.c @@ -377,6 +377,27 @@ static int REGION_CopyRegion( RGNOBJ *src, RGNOBJ *dest ) } } +/*********************************************************************** + * 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 09a58e48254..1ee64d0fe7a 100644 --- a/objects/text.c +++ b/objects/text.c @@ -188,7 +188,9 @@ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) 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 4984ba4f334..571cb8f39ed 100644 --- a/rc/Imakefile +++ b/rc/Imakefile @@ -26,7 +26,7 @@ includes:: 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 @@ y.tab.c y.tab.h: parser.y $(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 00000000000..b27628149ad --- /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 14f3af0205b..c8832cf1735 100644 --- a/rc/winerc.c +++ b/rc/winerc.c @@ -37,11 +37,7 @@ int main(int argc,char *argv[]) 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 @@ void create_output(gen_res* top) 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 25ab9f1b8f3..9a66e74ae35 100644 --- a/toolkit/sup.c +++ b/toolkit/sup.c @@ -1,5 +1,4 @@ #include -#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 00000000000..e5b6a7b78cf --- /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 e88bbd9f994..4fab002ebc3 100644 --- a/tools/build.c +++ b/tools/build.c @@ -1145,10 +1145,10 @@ static void BuildContext(void) 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 @@ static void RestoreContext(void) 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 @@ static void BuildCall32Func( char *profile ) 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 @@ static void BuildCall32Func( char *profile ) 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 @@ static void BuildCall32Func( char *profile ) { 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 @@ static void BuildCall32Func( char *profile ) } } - /* 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 @@ static void BuildCall16Func( char *profile ) 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 @@ static void BuildCall16Func( char *profile ) { /* 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 00000000000..7a066d5ef3c --- /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() { + 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 00000000000..3b0d31898ae --- /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 050d4e7412b..4c60a79bacc 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_FindClassByName( char * name, WORD hinstance, CLASS **ptr ) 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 @@ ATOM RegisterClass( LPWNDCLASS class ) 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 @@ BOOL UnregisterClass( LPSTR className, HANDLE hinstance ) /* 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 @@ int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount) 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 @@ BOOL ClassNext( CLASSENTRY *pClassEntry ) 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 810dcf276a8..5a41d3ccfda 100644 --- a/windows/cursor.c +++ b/windows/cursor.c @@ -18,9 +18,8 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #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 @@ HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name) 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 @@ HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, */ 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 @@ void GetClipCursor(LPRECT lpRetClipRect) if (lpRetClipRect != NULL) CopyRect(lpRetClipRect, &ClipCursorRect); } - - - - diff --git a/windows/defwnd.c b/windows/defwnd.c index e5811fbc95f..6263dd57586 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 #include @@ -38,7 +36,6 @@ void DEFWND_SetText( HWND hwnd, LPSTR text ) strcpy( textPtr, text ); } -#include /*********************************************************************** * DefWindowProc (USER.107) @@ -206,7 +203,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText); return (DWORD)strlen(textPtr); } - return (0L); + return 0; } case WM_SETTEXT: @@ -226,14 +223,13 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) 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 b5b78a40262..79116d4ebe8 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -415,7 +415,7 @@ static int DIALOG_DoDialogBox( HWND hwnd, HWND owner ) 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 05c21ce2a59..9803e0a23cf 100644 --- a/windows/event.c +++ b/windows/event.c @@ -283,7 +283,8 @@ static void EVENT_key( XKeyEvent *event ) 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 bbc674b94fe..d623752e96a 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 @@ BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush ) 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 85b49b504e1..aa67bf09126 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 @@ void MDIRecreateMenuList(MDICLIENTINFO *ci) } } +/********************************************************************** + * 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 @@ LONG MDIClientWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) 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 37a869c9edc..957f611380e 100644 --- a/windows/message.c +++ b/windows/message.c @@ -7,15 +7,17 @@ #include #include #include +#include #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 @@ static int MSG_FindMsg(MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last) { 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 @@ static INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd ) { WND *wndPtr; HWND hwnd; - INT hittest, x, y; + INT hittest = HTERROR; + INT x, y; *phwnd = hwnd = GetDesktopWindow(); x = pt.x; @@ -212,11 +226,11 @@ static INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd ) (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 INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd ) 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 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam ); return TRUE; /* No need to further process the message */ } - else hittest_result = MSG_GetWindowForEvent( msg->pt, &msg->hwnd ); + + if ((hittest = MSG_GetWindowForEvent( msg->pt, &msg->hwnd )) != HTERROR) + { - /* Send the WM_PARENTNOTIFY message */ + /* Send the WM_PARENTNOTIFY message */ - if (mouseClick) WIN_SendParentNotify( msg->hwnd, msg->message, - MAKELONG( msg->pt.x, msg->pt.y ) ); + if (mouseClick) WIN_SendParentNotify( msg->hwnd, msg->message, + MAKELONG( msg->pt.x, msg->pt.y ) ); - /* Activate the window if needed */ + /* Activate the window if needed */ - if (mouseClick) - { - 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 ); - } - } + 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 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) (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 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove ) /* 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 @@ BOOL MSG_WaitXEvent( LONG maxWait ) 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 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, 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 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) 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 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) 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 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) 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 @@ LONG SendMessage( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { 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 @@ void WaitMessage( void ) 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 @@ void WaitMessage( void ) 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 @@ LONG DispatchMessage( LPMSG msg ) 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 RegisterWindowMessage( LPCSTR str ) { 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 8af8dd3b180..a192262f2f1 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 @@ void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, 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 e29056e2cb5..b188ac39d10 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -124,7 +124,7 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) 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 96fff6a39d2..88b70735ad7 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -114,6 +114,8 @@ BOOL TIMER_CheckTimer( LONG *next, MSG *msg, HWND hwnd, BOOL remove ) 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 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, 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 aad35461b00..de84af96138 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 @@ HWND WIN_FindWinToRepaint( HWND hwnd ) */ 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 @@ static void WIN_DestroyWindow( HWND hwnd ) 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 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, 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 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, 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 @@ BOOL IsWindow( HWND hwnd ) 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 @@ HWND GetNextWindow( HWND hwnd, WORD flag ) 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 @@ BOOL EnumWindows( FARPROC lpEnumFunc, LPARAM lParam ) /* 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 @@ BOOL EnumWindows( FARPROC lpEnumFunc, LPARAM lParam ) /* 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 @@ BOOL EnumTaskWindows( HTASK hTask, FARPROC lpEnumFunc, LONG lParam ) /* 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 @@ BOOL EnumTaskWindows( HTASK hTask, FARPROC lpEnumFunc, LONG lParam ) /* 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 b241afcda86..577221d565d 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -773,7 +773,8 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, (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 @@ HDWP DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter, INT x, INT y, 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; -- 2.11.4.GIT