Release 950606
Tue Jun 6 12:11:41 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
* [controls/menu.c]
Fixed bug with drawing multi-column menus with vertical separator.
* [debugger/debug.l]
Fixed NULL-pointer reference after readline().
* [if1632/winprocs.spec] [miscemu/int21.c] [miscemu/interrupts.c]
Added interrupt vector emulation. Allows to retrieve an interrupt
vector and jump to it without crashing.
* [loader/ldt.c]
Moved ldt.c to memory directory.
* [loader/task.c]
Implemented LockCurrentTask() and GetInstanceData().
* [objects/bitblt.c]
Fixed a bug that caused StretchBlt() to use wrong colors when
stretching a monochrome bitmap to a color display.
* [objects/bitmap.c]
Fixed a segmented pointer bug in CreateBitmapIndirect().
* [tools/build.c]
Added possibility to have arguments for register functions; used
by interrupt vectors to remove the flags from the stack.
Generate a new function CallTo32_LargeStack(), that allows calling
a 32-bit function using the original 32-bit stack, for functions
that need more that 64k of stack.
Tue May 30 10:29:56 1995 Martin von Loewis <martin@informatik.hu-berlin.de>
* [if1632/shell.spec] [misc/shell.c]
DoEnvironmentSubst: fixed prototype
* [if1632/gdi.spec] [objects/palette.c]
SetSystemPaletteUse: new function
* [if1632/kernel.spec] [loader/resource.c]
DirectResAlloc: new function
* [if1632/user.spec] [windows/keyboard.c]
SetKeyboardState: new function
Mon May 29 12:58:28 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [tools/build.c]
Prevent interrupts from destroying the args for a 32 bit function
by loading the correct value into %esp directly after %ss.
* [loader/ne_image.c] [loader/module.c]
The new instance must be created earlier in LoadModule(), so that
fixups referencing it will be handled correctly.
Initialize the local heap for a DGROUP in NE_LoadSegment().
* [objects/dib.c]
Like RLE8 bitmaps, RLE4 bitmaps don't always end with a proper code.
This used to crash Wine. Fixed.
* [objects/text.c]
Fix possible null pointer dereference in debugging output.
* [misc/commdlg.c]
Handle user input in the edit control better. Some bugs fixed.
* [memory/local.c]
Started implementing moveable blocks. This is unfinished (!), but
at least it does not seem to break things.
Wed May 24 13:26:36 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [loader/module.c]
LoadModule(): DLLs occasionally have a data segment, and they work
much better if it is loaded :-)
LoadLibrary(): pass HMODULE instead of HINSTANCE to NE_InitializeDLLs.
FindModule(): also strip off the last backslash of the pathnames
(Winhelp tried to load C:\WINDOWS\SYSTEM\COMMDLG.DLL).
GetModuleHandle(): just call MODULE_FindModule, it does the same job,
only better.
* [loader/ne_image.c]
LocalInit() the heap of a DLL in NE_InitDLL. (This is probably
not really correct, it seems that all programs and DLLs try to do
this themselves. But they pass weird parameters.)
NE_InitializeDLLs should also call NE_InitDLL for the passed hModule.
* [loader/task.c] [misc/user.c]
Finish global initializations in InitTask instead of InitApp, or
all the DLLs will be initialized in InitTask without any available
window classes!
diff --git a/ANNOUNCE b/ANNOUNCE
index 03f377e..1fbc97c 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,14 @@
-This is release 950522 of Wine the MS Windows emulator. This is still a
+This is release 950606 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-950522: (see ChangeLog for details)
- - Preliminary Win32 support.
- - Multimedia code works better.
- - Better message boxes, listboxes and combos.
- - SYSRES.DLL is no longer needed.
+WHAT'S NEW with Wine-950606: (see ChangeLog for details)
+ - Lots of module fixes.
+ - Better interrupt vectors emulation.
+ - Stack no longer limited to 64k when calling X bitmap functions.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@@ -18,10 +17,11 @@
the release is available at the ftp sites. The sources will be available
from the following locations:
- sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950522.tar.gz
- tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950522.tar.gz
- ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950522.tar.gz
- ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950522.tar.gz
+ sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950606.tar.gz
+ tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950606.tar.gz
+ ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950606.tar.gz
+ ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950606.tar.gz
+ aris.com:/pub/linux/ALPHA/Wine/development/Wine-950606.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
diff --git a/ChangeLog b/ChangeLog
index fb55ccd..4cef5d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,98 @@
----------------------------------------------------------------------
+Tue Jun 6 12:11:41 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
+
+ * [controls/menu.c]
+ Fixed bug with drawing multi-column menus with vertical separator.
+
+ * [debugger/debug.l]
+ Fixed NULL-pointer reference after readline().
+
+ * [if1632/winprocs.spec] [miscemu/int21.c] [miscemu/interrupts.c]
+ Added interrupt vector emulation. Allows to retrieve an interrupt
+ vector and jump to it without crashing.
+
+ * [loader/ldt.c]
+ Moved ldt.c to memory directory.
+
+ * [loader/task.c]
+ Implemented LockCurrentTask() and GetInstanceData().
+
+ * [objects/bitblt.c]
+ Fixed a bug that caused StretchBlt() to use wrong colors when
+ stretching a monochrome bitmap to a color display.
+
+ * [objects/bitmap.c]
+ Fixed a segmented pointer bug in CreateBitmapIndirect().
+
+ * [tools/build.c]
+ Added possibility to have arguments for register functions; used
+ by interrupt vectors to remove the flags from the stack.
+ Generate a new function CallTo32_LargeStack(), that allows calling
+ a 32-bit function using the original 32-bit stack, for functions
+ that need more that 64k of stack.
+
+Tue May 30 10:29:56 1995 Martin von Loewis <martin@informatik.hu-berlin.de>
+
+ * [if1632/shell.spec] [misc/shell.c]
+ DoEnvironmentSubst: fixed prototype
+
+ * [if1632/gdi.spec] [objects/palette.c]
+ SetSystemPaletteUse: new function
+
+ * [if1632/kernel.spec] [loader/resource.c]
+ DirectResAlloc: new function
+
+ * [if1632/user.spec] [windows/keyboard.c]
+ SetKeyboardState: new function
+
+Mon May 29 12:58:28 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * [tools/build.c]
+ Prevent interrupts from destroying the args for a 32 bit function
+ by loading the correct value into %esp directly after %ss.
+
+ * [loader/ne_image.c] [loader/module.c]
+ The new instance must be created earlier in LoadModule(), so that
+ fixups referencing it will be handled correctly.
+ Initialize the local heap for a DGROUP in NE_LoadSegment().
+
+ * [objects/dib.c]
+ Like RLE8 bitmaps, RLE4 bitmaps don't always end with a proper code.
+ This used to crash Wine. Fixed.
+
+ * [objects/text.c]
+ Fix possible null pointer dereference in debugging output.
+
+ * [misc/commdlg.c]
+ Handle user input in the edit control better. Some bugs fixed.
+
+ * [memory/local.c]
+ Started implementing moveable blocks. This is unfinished (!), but
+ at least it does not seem to break things.
+
+Wed May 24 13:26:36 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+ * [loader/module.c]
+ LoadModule(): DLLs occasionally have a data segment, and they work
+ much better if it is loaded :-)
+ LoadLibrary(): pass HMODULE instead of HINSTANCE to NE_InitializeDLLs.
+ FindModule(): also strip off the last backslash of the pathnames
+ (Winhelp tried to load C:\WINDOWS\SYSTEM\COMMDLG.DLL).
+ GetModuleHandle(): just call MODULE_FindModule, it does the same job,
+ only better.
+
+ * [loader/ne_image.c]
+ LocalInit() the heap of a DLL in NE_InitDLL. (This is probably
+ not really correct, it seems that all programs and DLLs try to do
+ this themselves. But they pass weird parameters.)
+ NE_InitializeDLLs should also call NE_InitDLL for the passed hModule.
+
+ * [loader/task.c] [misc/user.c]
+ Finish global initializations in InitTask instead of InitApp, or
+ all the DLLs will be initialized in InitTask without any available
+ window classes!
+
+----------------------------------------------------------------------
Sun May 21 12:30:30 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
* [debugger/hash.c] [debugger/info.c]
diff --git a/controls/menu.c b/controls/menu.c
index 01a040c..6cea09d 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -344,6 +344,7 @@
if ((i != start) &&
(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, FALSE );
+ if (lpitem->item_flags & MF_MENUBARBREAK) orgX++;
maxX = max( maxX, lpitem->rect.right );
orgY = lpitem->rect.bottom;
if (lpitem->xTab)
diff --git a/debugger/debug.l b/debugger/debug.l
index 18a6b5a..6e9817e 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -173,34 +173,27 @@
do{
flush_symbols();
line = readline ("Wine-dbg>");
+ if (!line) return 0;
len = strlen(line);
-
- if (!line)
- {
- return 0;
- }
- else
- {
- /* Remove leading and trailing whitespace from the line.
- Then, if there is anything left, add it to the history list
- and execute it. */
- stripwhite (line);
-
- if (*line)
- {
- add_history (line);
- if(size < len + 1){
- fprintf(stderr,"Fatal readline goof.\n");
- exit(0);
- };
- strcpy(buf, line);
- buf[len] = '\n';
- buf[len+1] = 0;
- free(line);
- return len + 1;
- }
- }
+ /* Remove leading and trailing whitespace from the line.
+ Then, if there is anything left, add it to the history list
+ and execute it. */
+ stripwhite (line);
+
+ if (*line)
+ {
+ add_history (line);
+ if(size < len + 1){
+ fprintf(stderr,"Fatal readline goof.\n");
+ exit(0);
+ }
+ strcpy(buf, line);
+ buf[len] = '\n';
+ buf[len+1] = 0;
+ free(line);
+ return len + 1;
+ }
} while (1==1);
}
diff --git a/debugger/info.c b/debugger/info.c
index b31eeae..938150a 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -284,12 +284,10 @@
while((cs & 3) == 3) {
/* See if in 32 bit mode or not. Assume GDT means 32 bit. */
if ((cs & 7) != 7) {
- extern int main();
fprintf(stderr,"%d ",frameno++);
print_address(frame->u.win32.saved_ip,stderr,32);
fprintf( stderr, "\n" );
- if (frame->u.win32.saved_ip >= ((unsigned long)main) &&
- frame->u.win32.saved_ip <= ((unsigned long)main+1000)) break;
+ if (!frame->u.win32.saved_ip) break;
frame = (struct frame *) frame->u.win32.saved_bp;
} else {
if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs;
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 598d289..81584db 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -234,6 +234,7 @@
368 stub ResizePalette
370 pascal16 GetNearestPaletteIndex(word long) GetNearestPaletteIndex
372 pascal16 ExtFloodFill(word s_word s_word long word) ExtFloodFill
+373 pascal16 SetSystemPaletteUse(word word) SetSystemPaletteUse
374 pascal16 GetSystemPaletteUse(word) GetSystemPaletteUse
375 pascal16 GetSystemPaletteEntries(word word word ptr)
GetSystemPaletteEntries
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 7ca626c..1fbeb4e 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -32,7 +32,7 @@
30 pascal16 WaitEvent(word) WaitEvent
31 pascal16 PostEvent(word) PostEvent
32 pascal16 SetPriority(word s_word) SetPriority
-33 stub LockCurrentTask
+33 pascal16 LockCurrentTask(word) LockCurrentTask
34 pascal SetTaskQueue(word word) SetTaskQueue
35 pascal16 GetTaskQueue(word) GetTaskQueue
36 pascal GetCurrentTask() GetCurrentTask
@@ -49,7 +49,7 @@
51 pascal MakeProcInstance(segptr word) MakeProcInstance
52 pascal16 FreeProcInstance(segptr) FreeProcInstance
53 stub CallProcInstance
-54 stub GetInstanceData
+54 pascal16 GetInstanceData(word word word) GetInstanceData
55 pascal16 Catch(ptr) Catch
56 pascal16 Throw(ptr word) Throw
57 pascal16 GetProfileInt(ptr ptr word) GetProfileInt
@@ -98,7 +98,7 @@
100 stub ValidateCodeSegments
101 stub NoHookDosCall
102 register DOS3Call() DOS3Call
-103 stub NetBiosCall
+103 register NetBIOSCall() NetBIOSCall
104 stub GetCodeInfo
105 stub GetExeVersion
106 pascal SetSwapAreaSize(word) SetSwapAreaSize
@@ -117,7 +117,7 @@
119 stub GetTaskQueueES
120 stub UndefDynLink
121 pascal16 LocalShrink(word word) LocalShrink
-122 stub IsTaskLocked
+122 pascal16 IsTaskLocked() IsTaskLocked
123 stub KbdRst
124 return EnableKernel 0 0
125 return DisableKernel 0 0
@@ -156,7 +156,7 @@
165 stub A20Proc
166 pascal16 WinExec(ptr word) WinExec
167 stub GetExpWinVer
-168 stub DirectResAlloc
+168 pascal16 DirectResAlloc(word word word) DirectResAlloc
169 pascal GetFreeSpace(word) GetFreeSpace
170 pascal16 AllocCStoDSAlias(word) AllocCStoDSAlias
171 pascal16 AllocDStoCSAlias(word) AllocDStoCSAlias
diff --git a/if1632/relay.c b/if1632/relay.c
index 5049827..c628457 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -60,6 +60,7 @@
/* Saved 32-bit stack */
DWORD IF1632_Saved32_esp = 0;
SEGPTR IF1632_Stack32_base = 0;
+DWORD IF1632_Original32_esp = 0;
/***********************************************************************
* RELAY_Init
diff --git a/if1632/shell.spec b/if1632/shell.spec
index b00a5c4..ad04c35 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -23,7 +23,7 @@
33 pascal AboutDlgProc(word word word long) AboutDlgProc
34 pascal ExtractIcon(word ptr s_word) ExtractIcon
36 pascal ExtractAssociatedIcon(word ptr ptr) ExtractAssociatedIcon
- 37 pascal DoEnvironmentSubst(ptr word word) DoEnvironmentSubst
+ 37 pascal DoEnvironmentSubst(ptr word) DoEnvironmentSubst
39 stub InternalExtractIcon
102 pascal RegisterShellHook(ptr) RegisterShellHook
103 pascal ShellHookProc() ShellHookProc
diff --git a/if1632/user.spec b/if1632/user.spec
index e69390c..f4156d4 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -221,7 +221,7 @@
220 pascal LoadMenuIndirect(ptr) LoadMenuIndirect
221 pascal ScrollDC(word s_word s_word ptr ptr word ptr) ScrollDC
222 pascal16 GetKeyboardState(ptr) GetKeyboardState
-223 stub SetKeyboardState
+223 pascal16 SetKeyboardState(ptr) SetKeyboardState
224 pascal16 GetWindowTask(word) GetWindowTask
225 pascal EnumTaskWindows(word segptr long) EnumTaskWindows
226 stub LockInput
diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec
index 16240c4..8a0e88d 100644
--- a/if1632/winprocs.spec
+++ b/if1632/winprocs.spec
@@ -25,3 +25,23 @@
22 pascal ComboLBoxWndProc(word word word long) ComboLBoxWndProc
23 pascal16 CARET_Callback(word word word long) CARET_Callback
24 pascal16 TASK_Reschedule() TASK_Reschedule
+
+# 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
+
+116 register INT_Int10Handler(word) INT_Int10Handler
+119 register INT_Int13Handler(word) INT_Int13Handler
+121 register INT_Int15Handler(word) INT_Int15Handler
+122 register INT_Int16Handler(word) INT_Int16Handler
+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
+142 register INT_Int2aHandler(word) INT_Int2aHandler
+147 register INT_Int2fHandler(word) INT_Int2fHandler
+149 register INT_Int31Handler(word) INT_Int31Handler
+192 register INT_Int5cHandler(word) INT_Int5cHandler
+
+# Dummy interrupt vector
+356 register INT_DummyHandler(word) INT_DummyHandler
diff --git a/include/callback.h b/include/callback.h
index 0510758..3a2dba3 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -14,6 +14,9 @@
#ifndef WINELIB
+extern int CallTo32_LargeStack( int (*func)(), int nbargs, ... );
+
+
/* List of the 16-bit callback functions. This list is used */
/* by the build program to generate the file if1632/call16.S */
diff --git a/include/miscemu.h b/include/miscemu.h
index 1cc6fcc..4f8b378 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -1,6 +1,9 @@
#ifndef __WINE_MISCEMU_H
#define __WINE_MISCEMU_H
+#include "wintypes.h"
+#include "wine.h"
+
extern int do_int10(struct sigcontext_struct *);
extern int do_int13(struct sigcontext_struct *);
extern int do_int15(struct sigcontext_struct *);
@@ -12,6 +15,7 @@
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);
@@ -24,6 +28,10 @@
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 */
diff --git a/include/stackframe.h b/include/stackframe.h
index 8196461..3295e83 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -55,6 +55,7 @@
/* Saved 32-bit stack */
extern DWORD IF1632_Saved32_esp;
extern SEGPTR IF1632_Stack32_base;
+extern DWORD IF1632_Original32_esp;
#define CURRENT_STACK16 \
((STACK16FRAME *)PTR_SEG_OFF_TO_LIN(IF1632_Saved16_ss,IF1632_Saved16_sp))
diff --git a/include/task.h b/include/task.h
index e78f6d5..cbd28ae 100644
--- a/include/task.h
+++ b/include/task.h
@@ -21,9 +21,9 @@
WORD nextParagraph; /* Segment of next paragraph */
BYTE reserved1;
BYTE dispatcher[5]; /* Long call to DOS */
- DWORD savedint22; /* Saved int 22h handler */
- DWORD savedint23; /* Saved int 23h handler */
- DWORD savedint24; /* Saved int 24h handler */
+ SEGPTR savedint22; /* Saved int 22h handler */
+ SEGPTR savedint23; /* Saved int 23h handler */
+ SEGPTR savedint24; /* Saved int 24h handler */
WORD parentPSP; /* Selector of parent PSP */
BYTE fileHandles[20]; /* Open file handles */
HANDLE environment; /* Selector of environment */
diff --git a/include/windows.h b/include/windows.h
index 76ec59d..7230f39 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -2836,7 +2836,7 @@
Fc(int,GetClassName,HWND,a,LPSTR,b,short,c)
Fc(int,GetClipboardFormatName,WORD,a,LPSTR,b,short,c)
Fc(int,GetEnvironment,LPSTR,a,LPSTR,b,WORD,c)
-Fc(int,GetInstanceData,HANDLE,a,NPSTR,b,int,c)
+Fc(int,GetInstanceData,HANDLE,a,WORD,b,int,c)
Fc(int,GetKeyNameText,LONG,a,LPSTR,b,int,c)
Fc(int,GetModuleFileName,HANDLE,a,LPSTR,b,short,c)
Fc(int,GetObject,HANDLE,a,int,b,LPSTR,c)
diff --git a/loader/Imakefile b/loader/Imakefile
index 9c15c28..befe47a 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -4,7 +4,6 @@
SRCS = \
dump.c \
- ldt.c \
main.c \
module.c \
ne_image.c \
diff --git a/loader/main.c b/loader/main.c
index 3ace9d3..e6ad03e 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -10,12 +10,12 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
-#include "neexe.h"
+#include "windows.h"
#include "dos_fs.h"
#include "dlls.h"
-#include "windows.h"
+#include "miscemu.h"
+#include "neexe.h"
#include "wineopts.h"
-#include "wine.h"
#include "task.h"
#include "options.h"
#include "pe_image.h"
@@ -46,6 +46,9 @@
/* Initialize tasks */
if (!TASK_Init()) return 0;
+ /* Initialize interrupt vectors */
+ if (!INT_Init()) return 0;
+
/* Initialize the DOS file system */
DOS_InitFS();
diff --git a/loader/module.c b/loader/module.c
index c4af5bf..aa397d8 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -292,7 +292,7 @@
/***********************************************************************
* MODULE_CreateSegments
*/
-BOOL MODULE_CreateSegments( HMODULE hModule )
+static BOOL MODULE_CreateSegments( HMODULE hModule )
{
SEGTABLEENTRY *pSegment;
NE_MODULE *pModule;
@@ -308,9 +308,8 @@
{
/* FIXME: this is needed because heap growing is not implemented */
pModule->heap_size = 0x10000 - minsize;
- /* For tasks, the DGROUP is allocated by MODULE_MakeNewInstance */
- minsize = 0x10000;
- if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) continue;
+ /* The DGROUP is allocated by MODULE_CreateInstance */
+ continue;
}
pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
minsize, hModule,
@@ -327,6 +326,57 @@
/***********************************************************************
+ * MODULE_GetInstance
+ */
+static HINSTANCE MODULE_GetInstance( HMODULE hModule )
+{
+ SEGTABLEENTRY *pSegment;
+ NE_MODULE *pModule;
+
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+ if (pModule->dgroup == 0) return hModule;
+
+ pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+
+ return pSegment->selector;
+}
+
+
+/***********************************************************************
+ * MODULE_CreateInstance
+ */
+static HINSTANCE MODULE_CreateInstance( HMODULE hModule, LOADPARAMS *params )
+{
+ SEGTABLEENTRY *pSegment;
+ NE_MODULE *pModule;
+ int minsize;
+ HINSTANCE hNewInstance, hPrevInstance;
+
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+ if (pModule->dgroup == 0) return hModule;
+
+ pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+ hPrevInstance = pSegment->selector;
+
+ /* if it's a library, create a new instance only the first time */
+ if (hPrevInstance)
+ {
+ if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
+ if (params == (LOADPARAMS*)-1) return hPrevInstance;
+ }
+
+ minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+ if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
+ minsize += pModule->heap_size;
+ hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
+ minsize, hModule, FALSE, FALSE, FALSE );
+ if (!hNewInstance) return 0;
+ pSegment->selector = hNewInstance;
+ return hNewInstance;
+}
+
+
+/***********************************************************************
* MODULE_LoadExeHeader
*/
HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
@@ -518,62 +568,6 @@
/***********************************************************************
- * MODULE_MakeNewInstance
- *
- * Create a new instance of the specified module.
- */
-HINSTANCE MODULE_MakeNewInstance( HMODULE hModule, LOADPARAMS *params )
-{
- NE_MODULE *pModule;
- SEGTABLEENTRY *pSegment;
- HINSTANCE hNewInstance, hPrevInstance;
- int minsize;
-
- if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
- if (!pModule->dgroup) return hModule; /* No DGROUP -> return the module */
-
- pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
- hPrevInstance = pSegment->selector;
-
- /* Don't create a new instance if it's a library */
-
- if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
- if (params == (LOADPARAMS*)-1) return hPrevInstance;
-
- /* Allocate the new data segment */
-
- minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
- if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
- minsize += pModule->heap_size;
- hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
- minsize, hModule, FALSE, FALSE, FALSE );
- if (!hNewInstance) return 0;
- pSegment->selector = hNewInstance;
- NE_LoadSegment( hModule, pModule->dgroup );
-
- /* Create a new task for this instance */
- if (!TASK_CreateTask( hModule, hNewInstance, hPrevInstance,
- params->hEnvironment,
- (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
- *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) ))
- {
- GlobalFree( hNewInstance );
- return 0;
- }
-
- /* Initialize the local heap */
-
- if (pModule->heap_size)
- {
- WORD heapstart = pSegment->minsize;
- if (pModule->ss == pModule->dgroup) heapstart += pModule->stack_size;
- LocalInit( hNewInstance, heapstart, heapstart + pModule->heap_size );
- }
- return hNewInstance;
-}
-
-
-/***********************************************************************
* MODULE_GetOrdinal
*
* Lookup the ordinal for a given name.
@@ -800,6 +794,7 @@
BYTE len, *name_table;
if (!(filename = strrchr( path, '\\' ))) filename = path;
+ else filename++;
if ((dotptr = strrchr( filename, '.' )) != NULL)
len = (BYTE)(dotptr - filename);
else len = strlen( filename );
@@ -811,6 +806,7 @@
modulepath = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
if (!(modulename = strrchr( modulepath, '\\' )))
modulename = modulepath;
+ else modulename++;
if (!strcasecmp( modulename, filename )) return hModule;
name_table = (BYTE *)pModule + pModule->name_table;
@@ -878,8 +874,9 @@
HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
{
HMODULE hModule;
- HANDLE hInstance;
+ HANDLE hInstance, hPrevInstance;
NE_MODULE *pModule;
+ LOADPARAMS *params = (LOADPARAMS *)paramBlock;
WORD *pModRef, *pDLLs;
int i, fd;
@@ -906,6 +903,9 @@
MODULE_CreateSegments( hModule );
+ hPrevInstance = 0;
+ hInstance = MODULE_CreateInstance( hModule, (LOADPARAMS*)paramBlock );
+
/* Load the referenced DLLs */
pModRef = (WORD *)((char *)pModule + pModule->modref_table);
@@ -950,14 +950,9 @@
}
}
- /* Load the segments (except the DGROUP) */
+ /* Load the segments */
- for (i = 1; i <= pModule->seg_count; i++)
- if (i != pModule->dgroup) NE_LoadSegment( hModule, i );
-
- /* Create an instance for this module */
-
- hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+ for (i = 1; i <= pModule->seg_count; i++) NE_LoadSegment( hModule, i );
/* Fixup the functions prologs */
@@ -971,10 +966,23 @@
else
{
pModule = (NE_MODULE *)GlobalLock( hModule );
- hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+ hPrevInstance = MODULE_GetInstance( hModule );
+ hInstance = MODULE_CreateInstance( hModule, params );
+ if (hInstance != hPrevInstance) /* not a library */
+ NE_LoadSegment( hModule, pModule->dgroup );
pModule->count++;
}
+ /* Create a task for this instance */
+
+ if (!(pModule->flags & NE_FFLAGS_LIBMODULE) && (paramBlock != (LPVOID)-1))
+ {
+ TASK_CreateTask( hModule, hInstance, hPrevInstance,
+ params->hEnvironment,
+ (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
+ *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) );
+ }
+
return hInstance;
}
@@ -999,20 +1007,7 @@
*/
HMODULE GetModuleHandle( LPCSTR name )
{
- BYTE len = strlen(name);
- HMODULE hModule = hFirstModule;
-
- while( hModule )
- {
- NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
- char *pname = (char *)pModule + pModule->name_table;
- if (((BYTE)*pname == len) && !strncasecmp( pname+1, name, len ))
- break;
- hModule = pModule->next;
- }
- dprintf_module( stddeb, "GetModuleHandle('%s'): returning %04x\n",
- name, hModule );
- return hModule;
+ return MODULE_FindModule( name );
}
@@ -1044,6 +1039,7 @@
name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
strncpy( lpFileName, name, nSize );
lpFileName[nSize-1] = '\0';
+ dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName );
return strlen(lpFileName);
}
@@ -1056,6 +1052,8 @@
HANDLE handle;
dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
+ if ((handle = MODULE_FindModule( libname )) != 0) return handle;
+
handle = LoadModule( libname, (LPVOID)-1 );
if (handle == 2) /* file not found */
{
@@ -1064,7 +1062,7 @@
strcat( buffer, ".dll" );
handle = LoadModule( buffer, (LPVOID)-1 );
}
- if (handle >= 32) NE_InitializeDLLs( handle );
+ if (handle >= 32) NE_InitializeDLLs( GetExePtr(handle) );
return handle;
}
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 1a14ef2..4529f62 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -56,6 +56,14 @@
lseek( fd, pSeg->filepos << pModule->alignment, SEEK_SET );
read( fd, GlobalLock( pSeg->selector ), pSeg->size ? pSeg->size : 0x10000);
+ if ( pModule->heap_size && pModule->dgroup == segnum )
+ {
+ /* Initialize the local heap */
+ WORD heapstart = pSeg->minsize;
+ if (pModule->ss == pModule->dgroup) heapstart += pModule->stack_size;
+ LocalInit( pSeg->selector, heapstart, heapstart + pModule->heap_size );
+ }
+
if (!(pSeg->flags & NE_SEGFLAGS_RELOC_DATA))
return TRUE; /* No relocation data, we are done */
@@ -413,12 +421,15 @@
WORD *pDLL;
pModule = (NE_MODULE *)GlobalLock( hModule );
- if (!pModule->dlls_to_init) return;
- for (pDLL = (WORD *)GlobalLock( pModule->dlls_to_init ); *pDLL; pDLL++)
+ if (pModule->dlls_to_init)
{
- NE_InitDLL( *pDLL );
- NE_InitializeDLLs( *pDLL );
+ for (pDLL = (WORD *)GlobalLock( pModule->dlls_to_init ); *pDLL; pDLL++)
+ {
+ NE_InitDLL( *pDLL );
+ NE_InitializeDLLs( *pDLL );
+ }
+ GlobalFree( pModule->dlls_to_init );
+ pModule->dlls_to_init = 0;
}
- GlobalFree( pModule->dlls_to_init );
- pModule->dlls_to_init = 0;
+ NE_InitDLL( hModule );
}
diff --git a/loader/resource.c b/loader/resource.c
index adbfc80..0970786 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -16,6 +16,7 @@
#include "windows.h"
#include "gdi.h"
#include "bitmap.h"
+#include "global.h"
#include "neexe.h"
#include "icon.h"
#include "accel.h"
@@ -221,6 +222,23 @@
}
}
+/**********************************************************************
+ * DirectResAlloc (KERNEL.168)
+ * Check Schulman, p. 232 for details
+ */
+HANDLE DirectResAlloc(HANDLE hInstance, WORD wType, WORD wSize)
+{
+ HANDLE hModule;
+ dprintf_resource(stddeb,"DirectResAlloc(%x,%x,%x)\n",hInstance,wType,wSize);
+ hModule = GetExePtr(hInstance);
+ if(!hModule)return 0;
+ if(wType != 0x10) /* 0x10 is the only observed value, passed from
+ CreateCursorIndirect. */
+ fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
+ /* This hopefully does per-module allocation rather than per-instance */
+ return GLOBAL_Alloc(GMEM_FIXED, wSize, hModule, FALSE, FALSE, FALSE);
+}
+
/**********************************************************************
* ConvertCoreBitmap
diff --git a/loader/signal.c b/loader/signal.c
index b395d41..6ac04ad 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -18,6 +18,7 @@
#include "dos_fs.h"
#include "prototypes.h"
#include "miscemu.h"
+#include "registers.h"
#include "win.h"
#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
@@ -44,57 +45,59 @@
}
#endif
-int do_int(int intnum, struct sigcontext_struct *scp)
+int do_int(int intnum, struct sigcontext_struct *context)
{
switch(intnum)
{
- case 0x10: return do_int10(scp);
+ case 0x10: return do_int10(context);
case 0x11:
- scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
+ AX = DOS_GetEquipment();
return 1;
case 0x12:
- scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
+ AX = 640;
return 1; /* get base mem size */
- case 0x13: return do_int13(scp);
- case 0x15: return do_int15(scp);
- case 0x16: return do_int16(scp);
- case 0x1a: return do_int1a(scp);
- case 0x21: return do_int21(scp);
+ 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:
- scp->sc_eax = 0x1234;
- scp->sc_ebx = 0x5678;
- scp->sc_ecx = 0x9abc;
- scp->sc_edx = 0xdef0;
+ AX = 0x1234;
+ BX = 0x5678;
+ CX = 0x9abc;
+ DX = 0xdef0;
return 1;
- case 0x25: return do_int25(scp);
- case 0x26: return do_int26(scp);
- case 0x2a: return do_int2a(scp);
- case 0x2f: return do_int2f(scp);
- case 0x31: return do_int31(scp);
+ 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 0x5c: return do_int5c(context);
default:
- printf("int%02x: Unimplemented!\n", intnum);
+ fprintf(stderr,"int%02x: Unimplemented!\n", intnum);
break;
}
return 0;
}
#ifdef linux
-static void win_fault(int signal, struct sigcontext_struct context)
+static void win_fault(int signal, struct sigcontext_struct context_struct)
{
- struct sigcontext_struct *scp = &context;
+ struct sigcontext_struct *context = &context_struct;
#else
-static void win_fault(int signal, int code, struct sigcontext *scp)
+static void win_fault(int signal, int code, struct sigcontext *context)
{
#endif
unsigned char * instr;
+ WORD *stack;
#if !(defined (linux) || defined (__NetBSD__))
- int i, *dump;
+ int i, *dump;
#endif
/* First take care of a few preliminaries */
@@ -112,7 +115,7 @@
/* And back up over the int3 instruction. */
if(signal == SIGTRAP) {
- scp->sc_eip--;
+ EIP--;
goto oops;
}
#endif
@@ -126,76 +129,83 @@
if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
exit(1);
#endif
- if (scp->sc_cs == WINE_CODE_SELECTOR)
+ if (CS == WINE_CODE_SELECTOR)
{
fprintf(stderr,
"Segmentation fault in Wine program (%x:%lx)."
- " Please debug\n",
- scp->sc_cs, scp->sc_eip);
+ " Please debug\n", CS, EIP );
goto oops;
}
/* Now take a look at the actual instruction where the program
bombed */
- instr = (unsigned char *) PTR_SEG_OFF_TO_LIN(scp->sc_cs, scp->sc_eip);
+ instr = (unsigned char *) PTR_SEG_OFF_TO_LIN( CS, EIP );
switch(*instr)
{
case 0xcd: /* int <XX> */
instr++;
- if (!do_int(*instr, scp)) {
+ if (!do_int(*instr, context)) {
fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
goto oops;
}
- scp->sc_eip += 2; /* Bypass the int instruction */
+ EIP += 2; /* Bypass the int instruction */
break;
-
+
+ case 0xcf: /* iret */
+ stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
+ EIP = *stack++;
+ CS = *stack++;
+ EFL = *stack;
+ SP += 6; /* Pop the return address and flags */
+ break;
+
case 0xe4: /* inb al,XX */
- inportb_abs(scp);
- scp->sc_eip += 2;
+ inportb_abs(context);
+ EIP += 2;
break;
case 0xe5: /* in ax,XX */
- inport_abs(scp);
- scp->sc_eip += 2;
+ inport_abs(context);
+ EIP += 2;
break;
case 0xe6: /* outb XX,al */
- outportb_abs(scp);
- scp->sc_eip += 2;
+ outportb_abs(context);
+ EIP += 2;
break;
case 0xe7: /* out XX,ax */
- outport_abs(scp);
- scp->sc_eip += 2;
+ outport_abs(context);
+ EIP += 2;
break;
case 0xec: /* inb al,dx */
- inportb(scp);
- scp->sc_eip++;
+ inportb(context);
+ EIP++;
break;
case 0xed: /* in ax,dx */
- inport(scp);
- scp->sc_eip++;
+ inport(context);
+ EIP++;
break;
case 0xee: /* outb dx,al */
- outportb(scp);
- scp->sc_eip++;
+ outportb(context);
+ EIP++;
break;
case 0xef: /* out dx,ax */
- outport(scp);
- scp->sc_eip++;
+ outport(context);
+ EIP++;
break;
case 0xfa: /* cli, ignored */
- scp->sc_eip++;
+ EIP++;
break;
case 0xfb: /* sti, ignored */
- scp->sc_eip++;
+ EIP++;
break;
default:
@@ -210,14 +220,14 @@
oops:
XUngrabPointer(display, CurrentTime);
- XUngrabServer(display);
- XFlush(display);
- fprintf(stderr,"In win_fault %x:%lx\n", scp->sc_cs, scp->sc_eip);
+ XUngrabServer(display);
+ XFlush(display);
+ fprintf(stderr,"In win_fault %x:%lx\n", CS, EIP );
#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
- wine_debug(signal, (int *)scp); /* Enter our debugger */
+ wine_debug(signal, (int *)context); /* Enter our debugger */
#else
- fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
- dump = (int*) scp;
+ fprintf(stderr,"Stack: %x:%x\n", SS, ESP );
+ dump = (int*) context;
for(i=0; i<22; i++)
{
fprintf(stderr," %8.8x", *dump++);
diff --git a/loader/task.c b/loader/task.c
index 33d53de..5663419 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -12,6 +12,7 @@
#include "callback.h"
#include "global.h"
#include "instance.h"
+#include "miscemu.h"
#include "module.h"
#include "neexe.h"
#include "selectors.h"
@@ -31,6 +32,7 @@
static HTASK hFirstTask = 0;
static HTASK hCurrentTask = 0;
static HTASK hTaskToKill = 0;
+static HTASK hLockedTask = 0;
static WORD nTaskCount = 0;
/* TASK_Reschedule() 16-bit entry point */
@@ -281,12 +283,11 @@
/* Fill the PDB */
pTask->pdb.int20 = 0x20cd;
- pTask->pdb.dispatcher[0] = 0x9a;
+ pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */
*(DWORD *)&pTask->pdb.dispatcher[1] = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 102 ); /* KERNEL.102 is DOS3Call() */
- pTask->pdb.savedint22 = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"),
- 137 ); /* KERNEL.137 is FatalAppExit() */
- pTask->pdb.savedint23 = pTask->pdb.savedint22;
- pTask->pdb.savedint24 = pTask->pdb.savedint22;
+ pTask->pdb.savedint22 = INT_GetHandler( 0x22 );
+ pTask->pdb.savedint23 = INT_GetHandler( 0x23 );
+ pTask->pdb.savedint24 = INT_GetHandler( 0x24 );
pTask->pdb.environment = hEnvironment;
strncpy( pTask->pdb.cmdLine + 1, cmdLine, 126 );
pTask->pdb.cmdLine[127] = '\0';
@@ -347,8 +348,8 @@
frame16->saved_sp = pTask->sp;
frame16->ds = pTask->hInstance;
frame16->entry_point = 0;
- frame16->ordinal_number = 1;
- frame16->dll_id = 1;
+ frame16->ordinal_number = 24; /* WINPROCS.24 is TASK_Reschedule */
+ frame16->dll_id = 24; /* WINPROCS */
frame16->bp = 0;
frame16->ip = LOWORD( CALL16_RetAddr_word );
frame16->cs = HIWORD( CALL16_RetAddr_word );
@@ -431,6 +432,7 @@
TASK_UnlinkTask( hCurrentTask );
hTaskToKill = hCurrentTask;
+ hLockedTask = 0;
Yield();
/* We never return from Yield() */
}
@@ -454,6 +456,10 @@
if (hTaskToKill && (hTaskToKill != hCurrentTask))
TASK_DeleteTask( hTaskToKill );
+ /* If current task is locked, simply return */
+
+ if (hLockedTask) return;
+
/* Find a task to yield to */
pOldTask = (TDB *)GlobalLock( hCurrentTask );
@@ -496,6 +502,7 @@
pOldTask->sp = IF1632_Saved16_sp;
pOldTask->esp = IF1632_Saved32_esp;
}
+ else IF1632_Original32_esp = IF1632_Saved32_esp;
/* Make the task the last in the linked list (round-robin scheduling) */
@@ -519,6 +526,7 @@
*/
void InitTask( struct sigcontext_struct context )
{
+ static int firstTask = 1;
TDB *pTask;
NE_MODULE *pModule;
@@ -526,6 +534,22 @@
if (!(pTask = (TDB *)GlobalLock( hCurrentTask ))) return;
if (!(pModule = (NE_MODULE *)GlobalLock( pTask->hModule ))) return;
+ if (firstTask)
+ {
+ extern BOOL WIDGETS_Init(void);
+ extern BOOL WIN_CreateDesktopWindow(void);
+
+ /* Perform global initialisations that need a task context */
+
+ /* Initialize built-in window classes */
+ if (!WIDGETS_Init()) return;
+
+ /* Create desktop window */
+ if (!WIN_CreateDesktopWindow()) return;
+
+ firstTask = 0;
+ }
+
NE_InitializeDLLs( pTask->hModule );
/* Registers on return are:
@@ -602,6 +626,26 @@
/***********************************************************************
+ * LockCurrentTask (KERNEL.33)
+ */
+HTASK LockCurrentTask( BOOL bLock )
+{
+ if (bLock) hLockedTask = hCurrentTask;
+ else hLockedTask = 0;
+ return hLockedTask;
+}
+
+
+/***********************************************************************
+ * IsTaskLocked (KERNEL.122)
+ */
+WORD IsTaskLocked(void)
+{
+ return hLockedTask;
+}
+
+
+/***********************************************************************
* OldYield (KERNEL.117)
*/
void OldYield(void)
@@ -747,6 +791,19 @@
/***********************************************************************
+ * GetInstanceData (KERNEL.54)
+ */
+int GetInstanceData( HANDLE instance, WORD buffer, int len )
+{
+ char *ptr = (char *)GlobalLock( instance );
+ if (!ptr || !len) return 0;
+ if ((int)buffer + len >= 0x10000) len = 0x10000 - buffer;
+ memcpy( ptr + buffer, (char *)GlobalLock( CURRENT_DS ) + buffer, len );
+ return len;
+}
+
+
+/***********************************************************************
* GetNumTasks (KERNEL.152)
*/
WORD GetNumTasks(void)
diff --git a/memory/Imakefile b/memory/Imakefile
index 3364fec..8dbf16f 100644
--- a/memory/Imakefile
+++ b/memory/Imakefile
@@ -5,6 +5,7 @@
SRCS = \
selector.c \
global.c \
+ ldt.c \
local.c
OBJS = $(SRCS:.c=.o)
diff --git a/memory/global.c b/memory/global.c
index 7a0a144..d7fd15b 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -139,7 +139,7 @@
/* Fixup the size */
- if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x0f) return 0;
+ if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0;
if (size == 0) size = 0x20;
else size = (size + 0x1f) & ~0x1f;
diff --git a/loader/ldt.c b/memory/ldt.c
similarity index 100%
rename from loader/ldt.c
rename to memory/ldt.c
diff --git a/memory/local.c b/memory/local.c
index 134c1bf..1cd4a58 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -17,6 +17,7 @@
#include "ldt.h"
#include "instance.h"
#include "local.h"
+#include "module.h"
#include "stackframe.h"
#include "toolhelp.h"
#include "stddebug.h"
@@ -39,13 +40,15 @@
} LOCALARENA;
#define ARENA_HEADER_SIZE 4
+#define ARENA_HEADER( handle) ( ((handle) & ~3) - ARENA_HEADER_SIZE)
/* Arena types (stored in 'prev' field of the arena) */
#define LOCAL_ARENA_FREE 0
#define LOCAL_ARENA_FIXED 1
#define LOCAL_ARENA_MOVEABLE 3
-
+#define LMEM_NOCOMPACT 0x0010
+#define LMEM_NODISCARD 0x0020
typedef struct
{
@@ -93,6 +96,9 @@
#define ARENA_NEXT(ptr,arena) (ARENA_PTR(ptr,arena)->next)
#define ARENA_FLAGS(ptr,arena) (ARENA_PTR(ptr,arena)->prev & 3)
+ /* determine whether the handle belongs to a fixed or a moveable block */
+#define HANDLE_FIXED(handle) (((handle) & 3) == 0)
+#define HANDLE_MOVEABLE(handle) (((handle) & 3) == 2)
/***********************************************************************
* LOCAL_GetHeap
@@ -103,6 +109,7 @@
{
LOCALHEAPINFO *pInfo;
INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 );
+ dprintf_local( stddeb, "Heap at %04x\n", ptr->heap );
if (!ptr->heap) return 0;
pInfo = (LOCALHEAPINFO*)((char*)ptr + ptr->heap);
if (pInfo->magic != LOCAL_HEAP_MAGIC) return NULL;
@@ -138,6 +145,7 @@
next = pNext->next;
}
+ dprintf_local( stddeb, "Local_AddFreeBlock %04x, next %04x\n", block, next );
/* Insert the free block in the free-list */
pArena->free_prev = pNext->free_prev;
@@ -202,6 +210,7 @@
/* Remove the block from the free-list */
+ dprintf_local( stddeb, "Local_RemoveBlock\n");
pArena = ARENA_PTR( baseptr, block );
if ((pArena->prev & 3) == LOCAL_ARENA_FREE)
LOCAL_RemoveFreeBlock( baseptr, block );
@@ -229,6 +238,7 @@
LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
WORD arena;
+ if (!debugging_local) return;
if (!pInfo)
{
printf( "Local Heap corrupted! ds=%04x\n", ds );
@@ -266,7 +276,8 @@
}
if ((ARENA_PTR(ptr,pArena->next)->prev & ~3) != arena)
{
- printf( "*** arena->next->prev != arena\n" );
+ printf( "*** arena->next->prev != arena (%04x, %04x)\n",
+ pArena->next, ARENA_PTR(ptr,pArena->next)->prev);
break;
}
arena = pArena->next;
@@ -283,7 +294,8 @@
WORD heapInfoArena, freeArena, lastArena;
LOCALHEAPINFO *pHeapInfo;
LOCALARENA *pArena, *pFirstArena, *pLastArena;
-
+ NE_MODULE *pModule;
+
/* The initial layout of the heap is: */
/* - first arena (FIXED) */
/* - heap info structure (FIXED) */
@@ -295,14 +307,24 @@
ptr = PTR_SEG_OFF_TO_LIN( selector, 0 );
pHeapInfo = LOCAL_GetHeap(selector);
/* If there's already a local heap in this segment, */
- /* we simply return TRUE. Helps some programs, but */
- /* does not seem to be 100% correct yet (there are */
- /* still some "heap corrupted" messages in LocalAlloc */
+ /* we simply return TRUE. This helps some programs. */
if (pHeapInfo) {
dprintf_local(stddeb,"LocalInit: Heap %04x initialized twice.\n",selector);
if (debugging_local) LOCAL_PrintHeap(selector);
return TRUE;
}
+
+#if 0
+ /* Check if the segment is the DGROUP of a module */
+
+ if ((pModule = (NE_MODULE *)GlobalLock( GetExePtr( selector ) )))
+ {
+ SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+ if (pModule->dgroup && (pSeg->selector == selector))
+ start = max( start, pSeg->minsize );
+ }
+#endif
+
start = LALIGN( max( start, sizeof(INSTANCEDATA) ) );
heapInfoArena = LALIGN(start + sizeof(LOCALARENA) );
freeArena = LALIGN( heapInfoArena + ARENA_HEADER_SIZE
@@ -335,6 +357,7 @@
pHeapInfo->items = 4;
pHeapInfo->first = start;
pHeapInfo->last = lastArena;
+ pHeapInfo->htable = 0;
pHeapInfo->hdelta = 0x20;
pHeapInfo->extra = 0x200;
pHeapInfo->minsize = lastArena - freeArena;
@@ -352,7 +375,7 @@
/* Initialise the last block */
pLastArena = ARENA_PTR( ptr, lastArena );
- pLastArena->prev = heapInfoArena | LOCAL_ARENA_FREE;
+ pLastArena->prev = freeArena | LOCAL_ARENA_FREE;
pLastArena->next = lastArena; /* this one */
pLastArena->size = LALIGN(sizeof(LOCALARENA));
pLastArena->free_prev = freeArena;
@@ -361,49 +384,80 @@
/* Store the local heap address in the instance data */
((INSTANCEDATA *)ptr)->heap = heapInfoArena + ARENA_HEADER_SIZE;
+ LOCAL_PrintHeap( selector );
return TRUE;
}
+/***********************************************************************
+ * LOCAL_Compact
+ */
+static WORD LOCAL_Compact( WORD ds, WORD minfree, WORD flags )
+{
+ if (flags & LMEM_NOCOMPACT) return 0;
+
+ return 0;
+}
/***********************************************************************
- * LOCAL_Alloc
- *
- * Implementation of LocalAlloc().
+ * LOCAL_FindFreeBlock
*/
-HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size )
+static HLOCAL LOCAL_FindFreeBlock( WORD ds, WORD size )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo;
LOCALARENA *pArena;
WORD arena;
- dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
-
- /* Find a suitable free block */
-
if (!(pInfo = LOCAL_GetHeap( ds ))) {
- dprintf_local( stddeb, "LocalAlloc: Heap not found\n");
- LOCAL_PrintHeap(ds);
- return 0;
+ dprintf_local( stddeb, "Local_FindFreeBlock: Local heap not found\n" );
+ LOCAL_PrintHeap(ds);
+ return 0;
}
- size += ARENA_HEADER_SIZE;
- size = LALIGN( max( size, sizeof(LOCALARENA) ) );
+
arena = pInfo->first;
pArena = ARENA_PTR( ptr, arena );
- for (;;)
- {
- if (arena == pArena->free_next) {
- fprintf(stderr, "Local heap full\n");
- if (debugging_local) LOCAL_PrintHeap(ds);
- return 0; /* not found */
- }
+ while (arena != pArena->free_next) {
arena = pArena->free_next;
pArena = ARENA_PTR( ptr, arena );
- if (pArena->size >= size) break;
+ if (pArena->size >= size) return arena;
+ }
+ dprintf_local( stddeb, "Local_FindFreeBlock: not enough space\n" );
+ if (debugging_local) LOCAL_PrintHeap(ds);
+ return 0;
+}
+
+/***********************************************************************
+ * LOCAL_GetBlock
+ */
+static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags )
+{
+ char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+ LOCALHEAPINFO *pInfo;
+ LOCALARENA *pArena;
+ WORD arena;
+
+ if (!(pInfo = LOCAL_GetHeap( ds ))) {
+ dprintf_local( stddeb, "Local_GetBlock: Local heap not found\n");
+ LOCAL_PrintHeap(ds);
+ return 0;
+ }
+
+ size += ARENA_HEADER_SIZE;
+ size = LALIGN( max( size, sizeof(LOCALARENA) ) );
+
+ /* Find a suitable free block */
+ arena = LOCAL_FindFreeBlock( ds, size );
+ if (arena == 0) {
+ LOCAL_Compact( ds, size, flags );
+ arena = LOCAL_FindFreeBlock( ds, size );
+ }
+ if (arena == 0) {
+ fprintf( stderr, "Local_GetBlock: not enough space!\n" );
}
+ dprintf_local( stddeb, "LOCAL_GetBlock size = %04x\n", size );
/* Make a block out of the free arena */
-
+ pArena = ARENA_PTR( ptr, arena );
if (pArena->size > size + LALIGN(sizeof(LOCALARENA)))
{
LOCAL_AddBlock( ptr, arena, arena+size );
@@ -412,97 +466,78 @@
}
LOCAL_RemoveFreeBlock( ptr, arena );
- dprintf_local( stddeb, "LocalAlloc: returning %04x\n",
- arena + ARENA_HEADER_SIZE );
+ dprintf_local( stddeb, "Local_GetBlock: arena at %04x\n", arena );
return arena + ARENA_HEADER_SIZE;
}
-
/***********************************************************************
- * LOCAL_ReAlloc
- *
- * Implementation of LocalReAlloc().
+ * LOCAL_NewHTable
*/
-HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags )
+static BOOL LOCAL_NewHTable( WORD ds )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo;
- LOCALARENA *pArena, *pNext;
- WORD arena, newhandle;
+ HLOCAL handle;
- dprintf_local( stddeb, "LocalReAlloc: %04x %d %04x ds=%04x\n",
- handle, size, flags, ds );
- if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
- arena = handle - ARENA_HEADER_SIZE;
- pArena = ARENA_PTR( ptr, arena );
- if (flags & LMEM_MODIFY) {
- dprintf_local( stddeb, "LMEM_MODIFY set\n");
- return handle;
- }
- if (!size) size = 1;
- size = LALIGN( size );
-
- /* Check for size reduction */
-
- if (size < pArena->next - handle)
- {
- if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA)))
- {
- /* It is worth making a new free block */
- LOCAL_AddBlock( ptr, arena, handle + size );
- LOCAL_AddFreeBlock( ptr, handle + size );
- pInfo->items++;
- }
- dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
- return handle;
+ dprintf_local( stddeb, "Local_NewHTable\n" );
+ if (!(pInfo = LOCAL_GetHeap( ds ))) {
+ dprintf_local( stddeb, "Local heap not found\n");
+ LOCAL_PrintHeap(ds);
+ return FALSE;
}
- /* Check if the next block is free */
-
- pNext = ARENA_PTR( ptr, pArena->next );
- if (((pNext->prev & 3) == LOCAL_ARENA_FREE) &&
- (size <= pNext->next - handle))
- {
- LOCAL_RemoveBlock( ptr, pArena->next );
- if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA)))
- {
- /* It is worth making a new free block */
- LOCAL_AddBlock( ptr, arena, handle + size );
- LOCAL_AddFreeBlock( ptr, handle + size );
- pInfo->items++;
- }
- dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
- return handle;
- }
-
- /* Now we have to allocate a new block */
-
- newhandle = LOCAL_Alloc( ds, flags, size );
- if (!newhandle) return 0;
- memcpy( ptr + newhandle, ptr + handle, pArena->next - handle );
- LOCAL_Free( ds, handle );
- dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
- return newhandle;
+ handle = LOCAL_GetBlock( ds, pInfo->hdelta*4 + 2, LMEM_FIXED );
+ if (handle == 0) return FALSE;
+ *(WORD *)(ptr + handle) = 0; /* no handles in this block yet */
+ pInfo->htable = handle;
+ return TRUE;
}
+/***********************************************************************
+ * LOCAL_GetNewHandle
+ */
+static HLOCAL LOCAL_GetNewHandle( WORD ds )
+{
+ char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+ LOCALHEAPINFO *pInfo;
+ WORD count;
+
+ if (!(pInfo = LOCAL_GetHeap( ds ))) {
+ dprintf_local( stddeb, "LOCAL_GetNewHandle: Local heap not found\n");
+ LOCAL_PrintHeap(ds);
+ return 0;
+ }
+ /* Check if we need a new handle table */
+ if (pInfo->htable == 0)
+ if (!LOCAL_NewHTable( ds )) return 0;
+ if (*(WORD *)(ptr + pInfo->htable) == pInfo->hdelta)
+ if (!LOCAL_NewHTable( ds )) return 0;
+
+ /* increase count */
+ count = (*(WORD *)(ptr + pInfo->htable))++;
+ dprintf_local( stddeb, "Local_GetNewHandle: %04x\n", pInfo->htable + 2 + 4*count );
+ return pInfo->htable + 2 + 4*count;
+}
/***********************************************************************
- * LOCAL_Free
- *
- * Implementation of LocalFree().
+ * LOCAL_FreeArena
*/
-HLOCAL LOCAL_Free( WORD ds, HLOCAL handle )
+HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo;
LOCALARENA *pArena, *pPrev, *pNext;
- WORD arena;
- dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds );
- if (!(pInfo = LOCAL_GetHeap( ds ))) return handle;
- arena = handle - ARENA_HEADER_SIZE;
+ dprintf_local( stddeb, "LocalFreeArena: %04x ds=%04x\n", arena, ds );
+ if (!(pInfo = LOCAL_GetHeap( ds ))) return arena;
+
pArena = ARENA_PTR( ptr, arena );
- if ((pArena->prev & 3) == LOCAL_ARENA_FREE) return handle;
+ if ((pArena->prev & 3) == LOCAL_ARENA_FREE) {
+ /* shouldn't happen */
+ fprintf( stderr, "LocalFreeArena: Trying to free a block twice!\n" );
+ LOCAL_PrintHeap( ds );
+ return arena;
+ }
/* Check if we can merge with the previous block */
@@ -533,6 +568,153 @@
/***********************************************************************
+ * LOCAL_Free
+ *
+ * Implementation of LocalFree().
+ */
+HLOCAL LOCAL_Free( WORD ds, HLOCAL handle )
+{
+ char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+ WORD arena;
+
+ dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds );
+
+ if (HANDLE_FIXED( handle )) {
+ arena = ARENA_HEADER( handle );
+ } else {
+ arena = ARENA_HEADER( *(WORD *)(ptr + handle) );
+ dprintf_local( stddeb, "LocalFree: real block at %04x\n", arena);
+ }
+ arena = LOCAL_FreeArena( ds, arena );
+ if (arena != 0) return handle; /* couldn't free it */
+ return 0;
+}
+
+
+/***********************************************************************
+ * LOCAL_Alloc
+ *
+ * Implementation of LocalAlloc().
+ */
+HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size )
+{
+ char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+ HLOCAL handle;
+
+ dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
+
+ if (flags & LMEM_MOVEABLE) {
+ LOCALHANDLEENTRY *plhe;
+ HLOCAL hmem;
+
+ hmem = LOCAL_GetBlock( ds, size + 2, flags );
+ if (hmem == 0) return 0;
+ handle = LOCAL_GetNewHandle( ds );
+ if (handle == 0) {
+ fprintf( stderr, "LocalAlloc: couldn't get handle\n");
+ LOCAL_FreeArena( ds, ARENA_HEADER(hmem) );
+ return 0;
+ }
+ *(WORD *)(ptr + hmem) = handle;
+ plhe = (LOCALHANDLEENTRY *)(ptr + handle);
+ plhe->addr = hmem + 2;
+ plhe->lock = 0;
+ } else {
+ handle = LOCAL_GetBlock( ds, size, flags );
+ }
+ return handle;
+}
+
+
+/***********************************************************************
+ * LOCAL_ReAlloc
+ *
+ * Implementation of LocalReAlloc().
+ */
+HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags )
+{
+ char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+ LOCALHEAPINFO *pInfo;
+ LOCALARENA *pArena, *pNext;
+ WORD arena, newhandle, blockhandle, nextarena;
+
+ dprintf_local( stddeb, "LocalReAlloc: %04x %d %04x ds=%04x\n",
+ handle, size, flags, ds );
+ if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
+
+ if (HANDLE_FIXED( handle )) {
+ blockhandle = handle;
+ } else {
+ size += 2;
+ blockhandle = *(WORD *)(ptr + handle);
+ dprintf_local( stddeb, " blockhandle %04x (%04x)\n", blockhandle,
+ *(WORD *)(ptr + blockhandle - 2));
+ }
+ arena = ARENA_HEADER( blockhandle );
+ dprintf_local( stddeb, "LocalReAlloc: arena is %04x\n", arena );
+ pArena = ARENA_PTR( ptr, arena );
+
+ if (flags & LMEM_MODIFY) {
+ dprintf_local( stddeb, "LMEM_MODIFY set\n");
+ return handle;
+ }
+ if (!size) size = 1;
+ size = LALIGN( size );
+ nextarena = LALIGN(blockhandle + size);
+
+ /* Check for size reduction */
+
+ if (nextarena < pArena->next)
+ {
+ if (nextarena < pArena->next - LALIGN(sizeof(LOCALARENA)))
+ {
+ dprintf_local( stddeb, "size reduction, making new free block\n");
+ /* It is worth making a new free block */
+ LOCAL_AddBlock( ptr, arena, nextarena );
+ LOCAL_AddFreeBlock( ptr, nextarena );
+ pInfo->items++;
+ }
+ dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
+ return handle;
+ }
+
+ /* Check if the next block is free */
+
+ pNext = ARENA_PTR( ptr, pArena->next );
+ if (((pNext->prev & 3) == LOCAL_ARENA_FREE) &&
+ (nextarena <= pNext->next))
+ {
+ LOCAL_RemoveBlock( ptr, pArena->next );
+ if (nextarena < pArena->next - LALIGN(sizeof(LOCALARENA)))
+ {
+ dprintf_local( stddeb, "size increase, making new free block\n");
+ /* It is worth making a new free block */
+ LOCAL_AddBlock( ptr, arena, nextarena );
+ LOCAL_AddFreeBlock( ptr, nextarena );
+ pInfo->items++;
+ }
+ dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
+ return handle;
+ }
+
+ /* Now we have to allocate a new block */
+
+ newhandle = LOCAL_GetBlock( ds, size, flags );
+ if (newhandle == 0) return 0;
+ memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), size );
+ LOCAL_FreeArena( ds, arena );
+ if (HANDLE_MOVEABLE( handle )) {
+ newhandle += 2;
+ dprintf_local( stddeb, "LocalReAlloc: fixing handle\n");
+ *(WORD *)(ptr + handle) = newhandle;
+ newhandle = handle;
+ }
+ dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
+ return newhandle;
+}
+
+
+/***********************************************************************
* LOCAL_Size
*
* Implementation of LocalSize().
@@ -589,6 +771,11 @@
*/
WORD LocalLock( HLOCAL handle )
{
+ char *ptr = PTR_SEG_OFF_TO_LIN( CURRENT_DS, 0 );
+
+ if (HANDLE_MOVEABLE(handle)) {
+ handle = *(WORD *)(ptr + handle);
+ }
return handle;
}
@@ -616,7 +803,12 @@
*/
HLOCAL LocalHandle( WORD addr )
{
+ char *ptr = PTR_SEG_OFF_TO_LIN( CURRENT_DS, 0 );
+
dprintf_local( stddeb, "LocalHandle: %04x\n", addr );
+ if (HANDLE_MOVEABLE( addr )) {
+ addr = *(WORD *)(ptr + addr - 2);
+ }
return addr;
}
diff --git a/misc/commdlg.c b/misc/commdlg.c
index d9a0f31..47d08ed 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -15,6 +15,8 @@
#include "dlgs.h"
#include "selectors.h"
#include "../rc/sysres.h"
+#include "dos_fs.h"
+#include "stackframe.h"
#define OPENFILEDLG2 11
#define SAVEFILEDLG2 12
@@ -27,128 +29,28 @@
static HBITMAP hHDisk = 0;
static HBITMAP hCDRom = 0;
-int DOS_GetDefaultDrive(void);
-void DOS_SetDefaultDrive(int drive);
-char *DOS_GetCurrentDir(int drive);
-int DOS_ChangeDir(int drive, char *dirname);
-
-BOOL FileOpenDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-BOOL FileSaveDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-BOOL ColorDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-BOOL PrintDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-BOOL PrintSetupDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-BOOL ReplaceTextDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-BOOL FindTextDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
-
-/***********************************************************************
- * COMMDLG_IsPathName [internal]
- */
-
-static BOOL COMMDLG_IsPathName(LPSTR str)
-{
- if (str[strlen(str)-1] == ':' && strlen(str) == 2) return TRUE;
- if (str[strlen(str)-1] == '\\') return TRUE;
- if (strchr(str,'*') != NULL) return TRUE;
- return FALSE;
-}
-
/***********************************************************************
* FileDlg_Init [internal]
*/
static BOOL FileDlg_Init()
{
- if (!hFolder) hFolder = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER));
- if (!hFolder2) hFolder2 = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER2));
- if (!hFloppy) hFloppy = LoadBitmap(0, MAKEINTRESOURCE(OBM_FLOPPY));
- if (!hHDisk) hHDisk = LoadBitmap(0, MAKEINTRESOURCE(OBM_HDISK));
- if (!hCDRom) hCDRom = LoadBitmap(0, MAKEINTRESOURCE(OBM_CDROM));
- if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
- hHDisk == 0 || hCDRom == 0)
- fprintf(stderr, "FileDlg_Init // Error loading bitmaps !");
- return TRUE;
-}
-
-/***********************************************************************
- * OpenDlg_FixDirName [internal]
- */
-void OpenDlg_FixDirName(LPSTR dirname)
-{
- char temp[512];
- char* strp1;
- char* strp2;
-
- strp1=dirname;
- if( dirname[1] != ':'){
- temp[0]=(char)((char)DOS_GetDefaultDrive()+'A');
- temp[1]=':';
- temp[2]='\\';
- temp[3]= '\0';
- strcat(temp, DOS_GetCurrentDir(DOS_GetDefaultDrive()));
- if(dirname[0]=='.' && dirname[1]=='.') {
- strp2 = strrchr(temp, '\\');
- if (strp2 != NULL){
- *strp2='\0';
- strp1+=2;
- }
- }
- strcat(temp, "\\");
- strcat(temp, strp1);
- strcpy(dirname, temp);
- }
-}
-
-
-/***********************************************************************
- * OpenDlg_ScanDir [internal]
- */
-static BOOL OpenDlg_ScanDir(HWND hWnd, LPSTR newPath)
-{
- static HANDLE hStr = 0;
- static LPSTR str = NULL;
- static SEGPTR str16 = 0;
- LPSTR strp;
-
- OpenDlg_FixDirName(newPath);
- if (str == NULL) {
- hStr = GlobalAlloc(0,512);
- str = GlobalLock(hStr);
- str16 = WIN16_GlobalLock(hStr);
- }
-
- strcpy(str,newPath);
- DlgDirList(hWnd, str, lst1, 0, 0x0000);
- strp = strrchr(str,'\\');
- if (strp == NULL) {
- if (str[1] == ':') {
- strp = str+2;
- } else {
- strp = str;
- }
- } else strp++;
- strcpy(str,strp);
- SendDlgItemMessage(hWnd,edt1,WM_SETTEXT, 0, str16);
- strcpy(str,"*.*");
- DlgDirList(hWnd, str, lst2, stc1, 0x8010);
-
- return TRUE;
-}
-
-/***********************************************************************
- * OpenDlg_GetFileType [internal]
- */
-static LPSTR OpenDlg_GetFileType(LPCSTR types, WORD index)
-{
- int n;
- int i = 1;
- LPSTR ptr = (LPSTR) types;
- if (ptr == NULL) return NULL;
- while((n = strlen(ptr)) != 0) {
- ptr += ++n;
- if (i++ == index) return ptr;
- n = strlen(ptr);
- ptr += ++n;
+ static BOOL initialized = 0;
+
+ if (!initialized) {
+ if (!hFolder) hFolder = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER));
+ if (!hFolder2) hFolder2 = LoadBitmap(0, MAKEINTRESOURCE(OBM_FOLDER2));
+ if (!hFloppy) hFloppy = LoadBitmap(0, MAKEINTRESOURCE(OBM_FLOPPY));
+ if (!hHDisk) hHDisk = LoadBitmap(0, MAKEINTRESOURCE(OBM_HDISK));
+ if (!hCDRom) hCDRom = LoadBitmap(0, MAKEINTRESOURCE(OBM_CDROM));
+ if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 ||
+ hHDisk == 0 || hCDRom == 0)
+ {
+ fprintf(stderr, "FileDlg_Init // Error loading bitmaps !");
+ return FALSE;
}
- return NULL;
+ initialized = TRUE;
+ }
+ return TRUE;
}
/***********************************************************************
@@ -162,6 +64,8 @@
BOOL bRet;
LPCSTR dlgTemplate;
+ if (!FileDlg_Init()) return FALSE;
+
if (lpofn == NULL) return FALSE;
if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
dlgTemplate = GlobalLock(lpofn->hInstance);
@@ -190,7 +94,7 @@
hInst = GetWindowWord(lpofn->hwndOwner, GWW_HINSTANCE);
bRet = DialogBoxIndirectParamPtr(hInst, dlgTemplate, lpofn->hwndOwner,
GetWndProcEntry16("FileOpenDlgProc"),
- (DWORD)lpofn);
+ (DWORD)lpofn);
printf("GetOpenFileName // return lpstrFile='%s' !\n",
(LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
@@ -209,6 +113,8 @@
BOOL bRet;
LPCSTR dlgTemplate;
+ if (!FileDlg_Init()) return FALSE;
+
if (lpofn == NULL) return FALSE;
if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
dlgTemplate = GlobalLock(lpofn->hInstance);
@@ -243,100 +149,210 @@
return bRet;
}
-
/***********************************************************************
- * ChooseColor [COMMDLG.5]
+ * FILEDLG_StripEditControl [internal]
+ * Strip pathnames off the contents of the edit control.
*/
-BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
+static void FILEDLG_StripEditControl(HWND hwnd)
{
- WND *wndPtr;
- BOOL bRet;
- wndPtr = WIN_FindWndPtr(lpChCol->hwndOwner);
- bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, sysres_DIALOG_8,
- lpChCol->hwndOwner, GetWndProcEntry16("ColorDlgProc"),
- (DWORD)lpChCol);
- return bRet;
+ char temp[512], *cp;
+
+ SendDlgItemMessage(hwnd, edt1, WM_GETTEXT, 511, MAKE_SEGPTR(temp));
+ cp = strrchr(temp, '\\');
+ if (cp != NULL) {
+ strcpy(temp, cp+1);
+ }
+ cp = strrchr(temp, ':');
+ if (cp != NULL) {
+ strcpy(temp, cp+1);
+ }
}
+/***********************************************************************
+ * FILEDLG_ScanDir [internal]
+ */
+static BOOL FILEDLG_ScanDir(HWND hWnd, LPSTR newPath)
+{
+ char str[512],str2[512];
+
+ strcpy(str,newPath);
+ SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, MAKE_SEGPTR(str2));
+ strcat(str, str2);
+ if (!DlgDirList(hWnd, str, lst1, 0, 0x0000)) return FALSE;
+ DlgDirList(hWnd, "*.*", lst2, stc1, 0x8010);
+
+ return TRUE;
+}
/***********************************************************************
- * FileOpenDlgProc [COMMDLG.6]
+ * FILEDLG_GetFileType [internal]
*/
-BOOL FileOpenDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
+static LPSTR FILEDLG_GetFileType(LPSTR ptr, WORD index)
{
- int n;
- LPSTR ptr;
- LPSTR fspec;
- WORD wRet;
- LONG lRet;
- HBRUSH hBrush;
- HDC hMemDC;
- HBITMAP hBitmap;
- BITMAP bm;
- LPMEASUREITEMSTRUCT lpmeasure;
- LPDRAWITEMSTRUCT lpdis;
- int nDrive;
- static LPOPENFILENAME lpofn;/* FIXME - this won't multitask */
-
- SEGPTR tempsegp;
-
- static HANDLE hStr = 0;
- static LPSTR str = NULL;
- static SEGPTR str16 = 0;
-
- if (str == NULL) {
- hStr = GlobalAlloc(0,512);
- str = GlobalLock(hStr);
- str16 = WIN16_GlobalLock(hStr);
- }
-
- switch (wMsg) {
- case WM_INITDIALOG:
- printf("FileOpenDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
- if (!FileDlg_Init()) return TRUE;
- SendDlgItemMessage(hWnd, cmb1, CB_RESETCONTENT, 0, 0);
- lpofn = (LPOPENFILENAME)lParam;
- ptr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
- tempsegp = lpofn->lpstrFilter;
- while(*ptr) {
- n = strlen(ptr);
- SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, tempsegp);
- ptr += n + 1; tempsegp += n + 1;
- n = strlen(ptr);
- ptr += n + 1; tempsegp += n + 1;
+ int n, i;
+
+ if (ptr == NULL) return NULL;
+
+ for (i = 1;;i++) {
+ n = strlen(ptr);
+ if (n == 0) break;
+ ptr += n + 1;
+ if (i == index) return ptr;
+ n = strlen(ptr);
+ ptr += n + 1;
}
+ return NULL;
+}
+
+/***********************************************************************
+ * FILEDLG_WMDrawItem [internal]
+ */
+static LONG FILEDLG_WMDrawItem(HWND hWnd, WORD wParam, LONG lParam)
+{
+ LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
+ LPSTR str;
+ HBRUSH hBrush;
+ HBITMAP hBitmap, hPrevBitmap;
+ BITMAP bm;
+ HDC hMemDC;
+
+ if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) {
+ hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
+ SelectObject(lpdis->hDC, hBrush);
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
+ str = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
+ if (str != NULL) {
+ TextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
+ str, strlen(str));
+ if (lpdis->itemState != 0) {
+ InvertRect(lpdis->hDC, &lpdis->rcItem);
+ }
+ }
+ return TRUE;
+ }
+
+ if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) {
+ hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
+ SelectObject(lpdis->hDC, hBrush);
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
+ str = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
+ if (str != NULL) {
+ hBitmap = hFolder;
+ GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
+ TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
+ lpdis->rcItem.top, str, strlen(str));
+ hMemDC = CreateCompatibleDC(lpdis->hDC);
+ hPrevBitmap = SelectObject(hMemDC, hBitmap);
+ BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
+ bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+ SelectObject(hMemDC, hPrevBitmap);
+ DeleteDC(hMemDC);
+ if (lpdis->itemState != 0) {
+ InvertRect(lpdis->hDC, &lpdis->rcItem);
+ }
+ }
+ return TRUE;
+ }
+ if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) {
+ hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
+ SelectObject(lpdis->hDC, hBrush);
+ FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
+ str = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
+ if (str != NULL) {
+ switch(str[2]) {
+ case 'a': case 'b':
+ hBitmap = hFloppy;
+ break;
+ default:
+ hBitmap = hHDisk;
+ break;
+ }
+ GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
+ TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
+ lpdis->rcItem.top, str, strlen(str));
+ hMemDC = CreateCompatibleDC(lpdis->hDC);
+ hPrevBitmap = SelectObject(hMemDC, hBitmap);
+ BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
+ bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+ SelectObject(hMemDC, hPrevBitmap);
+ DeleteDC(hMemDC);
+ if (lpdis->itemState != 0) {
+ InvertRect(lpdis->hDC, &lpdis->rcItem);
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ * FILEDLG_WMMeasureItem [internal]
+ */
+static LONG FILEDLG_WMMeasureItem(HWND hWnd, WORD wParam, LONG lParam)
+{
+ BITMAP bm;
+ LPMEASUREITEMSTRUCT lpmeasure;
+
+ GetObject(hFolder2, sizeof(BITMAP), (LPSTR)&bm);
+ lpmeasure = (LPMEASUREITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
+ lpmeasure->itemHeight = bm.bmHeight;
+ return TRUE;
+}
+
+/***********************************************************************
+ * FILEDLG_WMInitDialog [internal]
+ */
+static LONG FILEDLG_WMInitDialog(HWND hWnd, WORD wParam, LONG lParam)
+{
+ int n;
+ LPOPENFILENAME lpofn;
+ char tmpstr[512];
+ LPSTR pstr;
+
+ SetWindowLong(hWnd, DWL_USER, lParam);
+ lpofn = (LPOPENFILENAME)lParam;
+
+ /* read filter information */
+ pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
+ while(*pstr) {
+ n = strlen(pstr);
+ strcpy(tmpstr, pstr);
+ SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, MAKE_SEGPTR(tmpstr));
+ pstr += n + 1;
+ n = strlen(pstr);
+ pstr += n + 1;
+ }
+
/* set default filter */
SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL,
- lpofn->nFilterIndex - 1, 0L);
- /* get drive information into combo 2 */
- strcpy(str,"");
- DlgDirListComboBox(hWnd, str16, cmb2, 0, 0xC000);
-
- if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) {
- strcpy(str, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
- if (str[strlen(str)-1] != '\\' && str[strlen(str)-1] != ':') {
- strcat(str,"\\");
- }
- } else {
- strcpy(str,"");
+ lpofn->nFilterIndex - 1, 0);
+ strcpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter),
+ lpofn->nFilterIndex));
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+
+ /* get drive list */
+ strcpy(tmpstr,"");
+ DlgDirListComboBox(hWnd, MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
+
+ /* read initial directory */
+ if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) {
+ strcpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
+ if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\'
+ && tmpstr[strlen(tmpstr)-1] != ':')
+ {
+ strcat(tmpstr,"\\");
+ }
+ } else {
+ strcpy(tmpstr,"");
}
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcat(str,fspec);
+ if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
+ fprintf(stderr, "FileDlg: couldn't read initial directory!\n");
+ }
+
+ /* select current drive in combo 2 */
+ n = DOS_GetDefaultDrive();
+ SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n, 0);
- if (!OpenDlg_ScanDir(hWnd, str)) {
- printf("OpenDlg_ScanDir // ChangeDir Error !\n");
- }
- /* select current drive in combo */
- nDrive = DOS_GetDefaultDrive();
- SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, nDrive, 0L);
-
- ShowWindow(hWnd, SW_SHOWNORMAL);
- return TRUE;
-
- case WM_SHOWWINDOW:
- if (wParam == 0) break;
if (!(lpofn->Flags & OFN_SHOWHELP)) {
ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
}
@@ -344,162 +360,157 @@
ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
}
return TRUE;
+}
- case WM_MEASUREITEM:
- GetObject(hFolder2, sizeof(BITMAP), (LPSTR)&bm);
- lpmeasure = (LPMEASUREITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
- lpmeasure->itemHeight = bm.bmHeight;
- return TRUE;
+/***********************************************************************
+ * FILEDLG_WMCommand [internal]
+ */
+static LONG FILEDLG_WMCommand(HWND hWnd, WORD wParam, LONG lParam)
+{
+ LONG lRet;
+ LPOPENFILENAME lpofn;
+ char tmpstr[512], tmpstr2[512];
+ LPSTR pstr, pstr2;
- case WM_DRAWITEM:
- if (lParam == 0L) break;
- lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
- if ((lpdis->CtlType == ODT_LISTBOX) && (lpdis->CtlID == lst1)) {
- hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
- SelectObject(lpdis->hDC, hBrush);
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
- ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
- if (ptr == NULL) break;
- TextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- ptr, strlen(ptr));
- if (lpdis->itemState != 0) {
- InvertRect(lpdis->hDC, &lpdis->rcItem);
- }
- return TRUE;
- }
- if ((lpdis->CtlType == ODT_LISTBOX) && (lpdis->CtlID == lst2)) {
- hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
- SelectObject(lpdis->hDC, hBrush);
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
- ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
- if (ptr == NULL) break;
- hBitmap = hFolder;
- GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
- TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
- lpdis->rcItem.top, ptr, strlen(ptr));
- hMemDC = CreateCompatibleDC(lpdis->hDC);
- SelectObject(hMemDC, hBitmap);
- BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
- DeleteDC(hMemDC);
- if (lpdis->itemState != 0) {
- InvertRect(lpdis->hDC, &lpdis->rcItem);
- }
- return TRUE;
- }
- if ((lpdis->CtlType == ODT_COMBOBOX) && (lpdis->CtlID == cmb2)) {
- hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
- SelectObject(lpdis->hDC, hBrush);
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
- ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
- if (ptr == NULL) break;
- switch(ptr[2]) {
- case 'a': case 'b':
- hBitmap = hFloppy;
- break;
- default:
- hBitmap = hHDisk;
- break;
- }
- GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
- TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
- lpdis->rcItem.top, ptr, strlen(ptr));
- hMemDC = CreateCompatibleDC(lpdis->hDC);
- SelectObject(hMemDC, hBitmap);
- BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
- DeleteDC(hMemDC);
- if (lpdis->itemState != 0) {
- InvertRect(lpdis->hDC, &lpdis->rcItem);
- }
- return TRUE;
- }
- break;
-
- case WM_COMMAND:
+ lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
switch (wParam) {
case lst1:
- if (HIWORD(lParam) == LBN_DBLCLK) {
- lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return 0;
- SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet, str16);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- }
- break;
- case lst2:
- if (HIWORD(lParam) == LBN_DBLCLK) {
- lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return 0;
- SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet, str16);
-
- if (str[0] == '[') {
- str[strlen(str) - 1] = 0;
- strcpy(str,str+1);
+ FILEDLG_StripEditControl(hWnd);
+ if (HIWORD(lParam) == LBN_DBLCLK) {
+ lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
+ if (lRet == LB_ERR) return TRUE;
+ SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet, MAKE_SEGPTR(tmpstr));
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+ return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
}
- strcat(str,"\\");
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcat(str,"\\"); strcat(str,fspec);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- }
- break;
+ return TRUE;
+ case lst2:
+ FILEDLG_StripEditControl(hWnd);
+ if (HIWORD(lParam) == LBN_DBLCLK) {
+ lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0);
+ if (lRet == LB_ERR) return TRUE;
+ SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet, MAKE_SEGPTR(tmpstr));
+
+ if (tmpstr[0] == '[') {
+ tmpstr[strlen(tmpstr) - 1] = 0;
+ strcpy(tmpstr,tmpstr+1);
+ }
+ strcat(tmpstr, "\\");
+ FILEDLG_ScanDir(hWnd, tmpstr);
+ }
+ return TRUE;
+
case cmb1:
- if (HIWORD(lParam) == CBN_SELCHANGE) {
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcpy(str,fspec);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- }
- break;
+ if (HIWORD(lParam) == CBN_SELCHANGE) {
+ lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
+ if (lRet == LB_ERR) return TRUE;
+ strcpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter),
+ lRet + 1));
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+ FILEDLG_ScanDir(hWnd, "");
+ }
+ return TRUE;
+
case cmb2:
- wRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
- if (wRet == (WORD)LB_ERR) return 0;
- SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, wRet, str16);
- str[0] = str[2]; str[1] = ':'; str[2] = 0;
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcat(str,fspec);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- break;
+ FILEDLG_StripEditControl(hWnd);
+ lRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
+ if (lRet == LB_ERR) return 0;
+ SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, lRet, MAKE_SEGPTR(tmpstr));
+ sprintf(tmpstr, "%c:", tmpstr[2]);
+ FILEDLG_ScanDir(hWnd, tmpstr);
+ return TRUE;
+
case chx1:
-#ifdef DEBUG_OPENDLG
- printf("FileOpenDlgProc // read-only toggled !\n");
-#endif
- break;
+ return TRUE;
+
case pshHelp:
-#ifdef DEBUG_OPENDLG
- printf("FileOpenDlgProc // pshHelp pressed !\n");
-#endif
- break;
+ return TRUE;
+
case IDOK:
- SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, str16);
- if (COMMDLG_IsPathName(str)) {
- OpenDlg_ScanDir(hWnd, str);
- } else {
- ShowWindow(hWnd, SW_HIDE);
- strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), str);
+ SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, MAKE_SEGPTR(tmpstr));
+
+ pstr = strrchr(tmpstr, '\\');
+ if (pstr == NULL) pstr = strrchr(tmpstr, ':');
+
+ if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL) {
+ /* edit control contains wildcards */
+ if (pstr != NULL) {
+ strcpy(tmpstr2, pstr+1);
+ *(pstr+1) = 0;
+ } else {
+ strcpy(tmpstr2, tmpstr);
+ strcpy(tmpstr, "");
+ }
+ printf("commdlg: %s, %s\n", tmpstr, tmpstr2);
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+ FILEDLG_ScanDir(hWnd, tmpstr);
+ return TRUE;
+ }
+
+ /* no wildcards, we might have a directory or a filename */
+ /* try appending a wildcard and reading the directory */
+ pstr2 = tmpstr + strlen(tmpstr);
+ if (pstr == NULL || *(pstr+1) != 0) {
+ strcat(tmpstr, "\\");
+ }
+ lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
+ if (lRet == LB_ERR) return TRUE;
+ strcpy(tmpstr2, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter),
+ lRet + 1));
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+ /* if ScanDir succeeds, we have changed the directory */
+ if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
+
+ /* if not, this must be a filename */
+ *pstr2 = 0;
+
+ if (pstr != NULL) {
+ /* strip off the pathname */
+ *pstr = 0;
+ strcpy(tmpstr2, pstr+1);
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+ /* Should we MessageBox() if this fails? */
+ if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
+ strcpy(tmpstr, tmpstr2);
+ } else {
+ SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+ }
+
+ ShowWindow(hWnd, SW_HIDE);
+ strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr);
lpofn->nFileOffset = 0;
lpofn->nFileExtension = strlen(PTR_SEG_TO_LIN(lpofn->lpstrFile)) - 3;
if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) {
- wRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0L);
- SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, wRet, str16);
- strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), str);
+ lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
+ SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet, MAKE_SEGPTR(tmpstr));
+ strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
}
EndDialog(hWnd, TRUE);
- }
- return TRUE;
+ return TRUE;
case IDCANCEL:
- EndDialog(hWnd, FALSE);
- return TRUE;
+ EndDialog(hWnd, FALSE);
+ return TRUE;
}
-/* return FALSE;*/
+ return FALSE;
+}
+
+/***********************************************************************
+ * FileOpenDlgProc [COMMDLG.6]
+ */
+BOOL FileOpenDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
+{
+ switch (wMsg) {
+ case WM_INITDIALOG:
+ return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
+
+ case WM_MEASUREITEM:
+ return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
+
+ case WM_DRAWITEM:
+ return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
+
+ case WM_COMMAND:
+ return FILEDLG_WMCommand(hWnd, wParam, lParam);
}
/*
@@ -526,245 +537,20 @@
*/
BOOL FileSaveDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
{
- int n;
- LPSTR ptr;
- LPSTR fspec;
- WORD wRet;
- LONG lRet;
- HBRUSH hBrush;
- HDC hMemDC;
- HBITMAP hBitmap;
- BITMAP bm;
- LPMEASUREITEMSTRUCT lpmeasure;
- LPDRAWITEMSTRUCT lpdis;
- int nDrive;
- static LPOPENFILENAME lpofn;/* FIXME - this won't multitask */
-
- SEGPTR tempsegp;
-
- static HANDLE hStr = 0;
- static LPSTR str = NULL;
- static SEGPTR str16 = 0;
-
- if (str == NULL) {
- hStr = GlobalAlloc(0,512);
- str = GlobalLock(hStr);
- str16 = WIN16_GlobalLock(hStr);
- }
-
switch (wMsg) {
case WM_INITDIALOG:
- printf("FileSaveDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
- if (!FileDlg_Init()) return TRUE;
- SendDlgItemMessage(hWnd, cmb1, CB_RESETCONTENT, 0, 0);
- lpofn = (LPOPENFILENAME)lParam;
- ptr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
- tempsegp = lpofn->lpstrFilter;
- while(*ptr) {
- n = strlen(ptr);
- SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, tempsegp);
- ptr += n + 1; tempsegp += n + 1;
- n = strlen(ptr);
- ptr += n + 1; tempsegp += n + 1;
- }
- /* set default filter */
- SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL,
- lpofn->nFilterIndex - 1, 0L);
- /* get drive information into combo 2 */
- strcpy(str,"");
- DlgDirListComboBox(hWnd, str16, cmb2, 0, 0xC000);
-
- if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) {
- strcpy(str, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
- if (str[strlen(str)-1] != '\\' && str[strlen(str)-1] != ':') {
- strcat(str,"\\");
- }
- } else {
- strcpy(str,"");
- }
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcat(str,fspec);
-
- if (!OpenDlg_ScanDir(hWnd, str)) {
- printf("SaveDlg_ScanDir // ChangeDir Error !\n");
- }
- /* select current drive in combo */
- nDrive = DOS_GetDefaultDrive();
- SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, nDrive, 0L);
-
- ShowWindow(hWnd, SW_SHOWNORMAL);
- return TRUE;
-
- case WM_SHOWWINDOW:
- if (wParam == 0) break;
- if (!(lpofn->Flags & OFN_SHOWHELP)) {
- ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
- }
- if (lpofn->Flags & OFN_HIDEREADONLY) {
- ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
- }
- return TRUE;
-
+ return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
+
case WM_MEASUREITEM:
- GetObject(hFolder2, sizeof(BITMAP), (LPSTR)&bm);
- lpmeasure = (LPMEASUREITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
- lpmeasure->itemHeight = bm.bmHeight;
- return TRUE;
+ return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
case WM_DRAWITEM:
- if (lParam == 0L) break;
- lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
- if ((lpdis->CtlType == ODT_LISTBOX) && (lpdis->CtlID == lst1)) {
- hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
- SelectObject(lpdis->hDC, hBrush);
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
- ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
- if (ptr == NULL) break;
- TextOut(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- ptr, strlen(ptr));
- if (lpdis->itemState != 0) {
- InvertRect(lpdis->hDC, &lpdis->rcItem);
- }
- return TRUE;
- }
- if ((lpdis->CtlType == ODT_LISTBOX) && (lpdis->CtlID == lst2)) {
- hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
- SelectObject(lpdis->hDC, hBrush);
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
- ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
- if (ptr == NULL) break;
- hBitmap = hFolder;
- GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
- TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
- lpdis->rcItem.top, ptr, strlen(ptr));
- hMemDC = CreateCompatibleDC(lpdis->hDC);
- SelectObject(hMemDC, hBitmap);
- BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
- DeleteDC(hMemDC);
- if (lpdis->itemState != 0) {
- InvertRect(lpdis->hDC, &lpdis->rcItem);
- }
- return TRUE;
- }
- if ((lpdis->CtlType == ODT_COMBOBOX) && (lpdis->CtlID == cmb2)) {
- hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
- SelectObject(lpdis->hDC, hBrush);
- FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
- ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
- if (ptr == NULL) break;
- switch(ptr[2]) {
- case 'a': case 'b':
- hBitmap = hFloppy;
- break;
- default:
- hBitmap = hHDisk;
- break;
- }
- GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
- TextOut(lpdis->hDC, lpdis->rcItem.left + bm.bmWidth,
- lpdis->rcItem.top, ptr, strlen(ptr));
- hMemDC = CreateCompatibleDC(lpdis->hDC);
- SelectObject(hMemDC, hBitmap);
- BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
- bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
- DeleteDC(hMemDC);
- if (lpdis->itemState != 0) {
- InvertRect(lpdis->hDC, &lpdis->rcItem);
- }
- return TRUE;
- }
- break;
-
- case WM_COMMAND:
- switch (wParam) {
- case lst1:
- if (HIWORD(lParam) == LBN_DBLCLK) {
- lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return 0;
- SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet, str16);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- }
- break;
- case lst2:
- if (HIWORD(lParam) == LBN_DBLCLK) {
- lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return 0;
- SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet, str16);
+ return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
- if (str[0] == '[') {
- str[strlen(str) - 1] = 0;
- strcpy(str,str+1);
- }
- strcat(str,"\\");
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcat(str,"\\"); strcat(str,fspec);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- }
- break;
- case cmb1:
- if (HIWORD(lParam) == CBN_SELCHANGE) {
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcpy(str,fspec);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- }
- break;
- case cmb2:
- wRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
- if (wRet == (WORD)LB_ERR) return 0;
- SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, wRet, str16);
- str[0] = str[2]; str[1] = ':'; str[2] = 0;
- lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0L);
- if (lRet == LB_ERR) return FALSE;
- fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), lRet + 1);
- strcat(str,fspec);
- SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, str16);
- return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
- break;
- case chx1:
-#ifdef DEBUG_OPENDLG
- printf("FileSaveDlgProc // read-only toggled !\n");
-#endif
- break;
- case pshHelp:
-#ifdef DEBUG_OPENDLG
- printf("FileSaveDlgProc // pshHelp pressed !\n");
-#endif
- break;
- case IDOK:
- SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, str16);
- if (COMMDLG_IsPathName(str)) {
- OpenDlg_ScanDir(hWnd, str);
- } else {
- ShowWindow(hWnd, SW_HIDE);
- strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), str);
- lpofn->nFileOffset = 0;
- lpofn->nFileExtension = strlen(PTR_SEG_TO_LIN(lpofn->lpstrFile)) - 3;
- if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) {
- wRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0L);
- SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, wRet, str16);
- strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), str);
- }
- EndDialog(hWnd, TRUE);
- }
- return TRUE;
- case IDCANCEL:
- EndDialog(hWnd, FALSE);
- return TRUE;
- }
-/* return FALSE;*/
+ case WM_COMMAND:
+ return FILEDLG_WMCommand(hWnd, wParam, lParam);
}
-
/*
case WM_CTLCOLOR:
SetBkColor((HDC)wParam, 0x00C0C0C0);
@@ -785,6 +571,21 @@
/***********************************************************************
+ * ChooseColor [COMMDLG.5]
+ */
+BOOL ChooseColor(LPCHOOSECOLOR lpChCol)
+{
+ WND *wndPtr;
+ BOOL bRet;
+ wndPtr = WIN_FindWndPtr(lpChCol->hwndOwner);
+ bRet = DialogBoxIndirectParamPtr(wndPtr->hInstance, sysres_DIALOG_8,
+ lpChCol->hwndOwner, GetWndProcEntry16("ColorDlgProc"),
+ (DWORD)lpChCol);
+ return bRet;
+}
+
+
+/***********************************************************************
* ColorDlgProc [COMMDLG.8]
*/
BOOL ColorDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
diff --git a/misc/compobj.c b/misc/compobj.c
index c527b0f..690cfa4 100644
--- a/misc/compobj.c
+++ b/misc/compobj.c
@@ -20,6 +20,6 @@
LPUNKNOWN lpUnk,
DWORD reserved)
{
- dprintf_ole(stdnimp,"CoDisconnectObject:%x %x\n",lpUnk,reserved);
+ dprintf_ole(stdnimp,"CoDisconnectObject:%p %lx\n",lpUnk,reserved);
return OLE_OK;
}
diff --git a/misc/shell.c b/misc/shell.c
index bab7b02..f300710 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -458,13 +458,10 @@
/*************************************************************************
* DoEnvironmentSubst [SHELL.37]
- * I couldn't find any reference, so even the number of bytes on the
- * stack might be wrong
*/
-WORD DoEnvironmentSubst(LPSTR a,WORD b,WORD c)
+DWORD DoEnvironmentSubst(LPSTR str,WORD len)
{
- printf(stderr, "DoEnvironmentSubst: Unknown argument count\n");
- dprintf_reg(stdnimp, "DoEnvironmentSubst %x %x %x\n",a,b,c);
+ dprintf_reg(stdnimp, "DoEnvironmentSubst(%s,%x): Empyt Stub !!!\n",str,len);
return 0;
}
diff --git a/misc/user.c b/misc/user.c
index d9bf1d8..9e0333f 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -92,24 +92,8 @@
*/
int USER_InitApp(int hInstance)
{
- extern BOOL WIDGETS_Init(void);
-
- static int firstTask = 1;
int queueSize;
- if (firstTask)
- {
- /* Perform global initialisations that need a task context */
-
- /* Initialize built-in window classes */
- if (!WIDGETS_Init()) return 0;
-
- /* Create desktop window */
- if (!WIN_CreateDesktopWindow()) return 0;
-
- firstTask = 0;
- }
-
/* Create task message queue */
queueSize = GetProfileInt( "windows", "DefaultQueueSize", 8 );
if (!SetMessageQueue( queueSize )) return 0;
diff --git a/miscemu/Imakefile b/miscemu/Imakefile
index 11e3840..70a5b6a 100644
--- a/miscemu/Imakefile
+++ b/miscemu/Imakefile
@@ -15,6 +15,8 @@
int2a.c \
int2f.c \
int31.c \
+ int5c.c \
+ interrupts.c \
ioports.c
OBJS = $(SRCS:.c=.o)
diff --git a/miscemu/int21.c b/miscemu/int21.c
index e4bb91f..f0af67b 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -1324,10 +1324,7 @@
break;
case 0x25: /* SET INTERRUPT VECTOR */
- /* Ignore any attempt to set a segment vector */
- dprintf_int(stddeb,
- "int21: set interrupt vector %2x (%04x:%04x)\n",
- AL, DS, DX);
+ INT_SetHandler( AL, MAKELONG( DX, DS ) );
break;
case 0x2a: /* GET SYSTEM DATE */
@@ -1396,12 +1393,11 @@
break;
case 0x35: /* GET INTERRUPT VECTOR */
- /* Return a NULL segment selector - this will bomb,
- if anyone ever tries to use it */
- dprintf_int(stddeb, "int21: get interrupt vector %2x\n",
- AX & 0xff);
- ES = 0;
- BX = 0;
+ {
+ SEGPTR addr = INT_GetHandler( AL );
+ ES = SELECTOROF(addr);
+ BX = OFFSETOF(addr);
+ }
break;
case 0x36: /* GET FREE DISK SPACE */
@@ -1734,8 +1730,9 @@
return 1;
}
-/**********************************************************************
- * DOS3Call
+
+/***********************************************************************
+ * DOS3Call (KERNEL.102)
*/
void DOS3Call( struct sigcontext_struct context )
{
diff --git a/miscemu/int5c.c b/miscemu/int5c.c
new file mode 100644
index 0000000..060da76
--- /dev/null
+++ b/miscemu/int5c.c
@@ -0,0 +1,33 @@
+/*
+ * NetBIOS interrupt handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include "miscemu.h"
+#include "registers.h"
+#include "wine.h"
+#include "stddebug.h"
+/* #define DEBUG_INT */
+#include "debug.h"
+
+
+/***********************************************************************
+ * 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)
+ */
+void NetBIOSCall( struct sigcontext_struct context )
+{
+ do_int5c( &context );
+}
diff --git a/miscemu/interrupts.c b/miscemu/interrupts.c
new file mode 100644
index 0000000..01f957e
--- /dev/null
+++ b/miscemu/interrupts.c
@@ -0,0 +1,190 @@
+/*
+ * 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 );
+}
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 6822f53..f5037b0 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -9,6 +9,7 @@
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include "bitmap.h"
+#include "callback.h"
#include "color.h"
#include "dc.h"
#include "metafile.h"
@@ -581,7 +582,7 @@
register short i;
pdata += swap ? start+width-1 : start;
- if (image->depth == depthDst)
+ if (image->depth == depthDst) /* color -> color */
{
if (COLOR_PixelToPalette && (depthDst != 1))
if (swap) for (i = 0; i < width; i++)
@@ -596,16 +597,25 @@
}
else
{
- if (image->depth == 1)
+ if (image->depth == 1) /* monochrome -> color */
+ {
+ if (COLOR_PixelToPalette)
+ {
+ fg = COLOR_PixelToPalette[fg];
+ bg = COLOR_PixelToPalette[bg];
+ }
if (swap) for (i = 0; i < width; i++)
*pdata-- = XGetPixel( image, i, row ) ? bg : fg;
else for (i = 0; i < width; i++)
*pdata++ = XGetPixel( image, i, row ) ? bg : fg;
- else
+ }
+ else /* color -> monochrome */
+ {
if (swap) for (i = 0; i < width; i++)
*pdata-- = (XGetPixel( image, i, row ) == bg) ? 1 : 0;
else for (i = 0; i < width; i++)
*pdata++ = (XGetPixel( image, i, row ) == bg) ? 1 : 0;
+ }
}
}
@@ -1203,8 +1213,9 @@
dprintf_bitblt(stddeb, "PatBlt: %d %d,%d %dx%d %06lx\n",
hdc, left, top, width, height, rop );
- return BITBLT_InternalStretchBlt( dc, left, top, width, height,
- NULL, 0, 0, 0, 0, rop );
+ return CallTo32_LargeStack( (int(*)())BITBLT_InternalStretchBlt, 11,
+ dc, left, top, width, height,
+ NULL, 0, 0, 0, 0, rop );
}
@@ -1231,8 +1242,9 @@
hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
dprintf_bitblt(stddeb," src org=%d,%d dst org=%d,%d\n",
dcSrc->w.DCOrgX, dcSrc->w.DCOrgY, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
- return BITBLT_InternalStretchBlt( dcDst, xDst, yDst, width, height,
- dcSrc, xSrc, ySrc, width, height, rop );
+ return CallTo32_LargeStack( (int(*)())BITBLT_InternalStretchBlt, 11,
+ dcDst, xDst, yDst, width, height,
+ dcSrc, xSrc, ySrc, width, height, rop );
}
@@ -1261,7 +1273,7 @@
dcSrc ? dcSrc->w.bitsPerPixel : 0, hdcDst, xDst, yDst,
widthDst, heightDst, dcDst->w.bitsPerPixel, rop );
- return BITBLT_InternalStretchBlt( dcDst, xDst, yDst, widthDst, heightDst,
- dcSrc, xSrc, ySrc, widthSrc, heightSrc,
- rop );
+ return CallTo32_LargeStack( (int(*)())BITBLT_InternalStretchBlt, 11,
+ dcDst, xDst, yDst, widthDst, heightDst,
+ dcSrc, xSrc, ySrc, widthSrc, heightSrc, rop );
}
diff --git a/objects/bitmap.c b/objects/bitmap.c
index e394ccb..e0f15c4 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -2,15 +2,14 @@
* GDI bitmap objects
*
* Copyright 1993 Alexandre Julliard
- *
-static char Copyright[] = "Copyright Alexandre Julliard, 1993";
-*/
+ */
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "gdi.h"
#include "arch.h"
+#include "callback.h"
#include "dc.h"
#include "bitmap.h"
#include "prototypes.h"
@@ -81,10 +80,43 @@
HBITMAP CreateBitmap( short width, short height,
BYTE planes, BYTE bpp, LPSTR bits )
{
- BITMAP bitmap = { 0, width, height, 0, planes, bpp, bits };
- dprintf_gdi(stddeb, "CreateBitmap: %dx%d, %d colors\n",
- width, height, 1 << (planes*bpp) );
- return CreateBitmapIndirect( &bitmap );
+ BITMAPOBJ * bmpObjPtr;
+ HBITMAP hbitmap;
+
+ dprintf_gdi( stddeb, "CreateBitmap: %dx%d, %d colors\n",
+ width, height, 1 << (planes*bpp) );
+
+ /* Check parameters */
+ if (!height || !width || planes != 1) return 0;
+ if ((bpp != 1) && (bpp != screenDepth)) return 0;
+ if (height < 0) height = -height;
+ if (width < 0) width = -width;
+
+ /* Create the BITMAPOBJ */
+ hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
+ if (!hbitmap) return 0;
+ bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
+
+ bmpObjPtr->size.cx = 0;
+ bmpObjPtr->size.cy = 0;
+ bmpObjPtr->bitmap.bmType = 0;
+ bmpObjPtr->bitmap.bmWidth = width;
+ bmpObjPtr->bitmap.bmHeight = height;
+ bmpObjPtr->bitmap.bmPlanes = planes;
+ bmpObjPtr->bitmap.bmBitsPixel = bpp;
+ bmpObjPtr->bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2;
+ bmpObjPtr->bitmap.bmBits = NULL;
+
+ /* Create the pixmap */
+ bmpObjPtr->pixmap = XCreatePixmap(display, rootWindow, width, height, bpp);
+ if (!bmpObjPtr->pixmap)
+ {
+ GDI_HEAP_FREE( hbitmap );
+ hbitmap = 0;
+ }
+ else if (bits) /* Set bitmap bits */
+ SetBitmapBits( hbitmap, height * bmpObjPtr->bitmap.bmWidthBytes, bits);
+ return hbitmap;
}
@@ -106,43 +138,8 @@
*/
HBITMAP CreateBitmapIndirect( BITMAP * bmp )
{
- BITMAPOBJ * bmpObjPtr;
- HBITMAP hbitmap;
-
- /* Check parameters */
- if (!bmp->bmHeight || !bmp->bmWidth) return 0;
- if (bmp->bmPlanes != 1) return 0;
- if ((bmp->bmBitsPixel != 1) && (bmp->bmBitsPixel != screenDepth)) return 0;
-
- if (bmp->bmHeight < 0)
- bmp->bmHeight = -bmp->bmHeight;
-
- if (bmp->bmWidth < 0)
- bmp->bmWidth = -bmp->bmWidth;
-
-
- /* Create the BITMAPOBJ */
- hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
- if (!hbitmap) return 0;
- bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
-
- bmpObjPtr->size.cx = 0;
- bmpObjPtr->size.cy = 0;
- bmpObjPtr->bitmap = *bmp;
- bmpObjPtr->bitmap.bmBits = NULL;
- bmpObjPtr->bitmap.bmWidthBytes = (bmp->bmWidth*bmp->bmBitsPixel+15)/16 * 2;
-
- /* Create the pixmap */
- bmpObjPtr->pixmap = XCreatePixmap( display, rootWindow, bmp->bmWidth,
- bmp->bmHeight, bmp->bmBitsPixel );
- if (!bmpObjPtr->pixmap)
- {
- GDI_HEAP_FREE( hbitmap );
- hbitmap = 0;
- }
- else if (bmp->bmBits) /* Set bitmap bits */
- SetBitmapBits( hbitmap, bmpObjPtr->bitmap.bmHeight*bmpObjPtr->bitmap.bmWidthBytes, bmp->bmBits );
- return hbitmap;
+ return CreateBitmap( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
+ bmp->bmBitsPixel, PTR_SEG_TO_LIN( bmp->bmBits ) );
}
@@ -167,8 +164,9 @@
if (!height) return 0;
if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0;
- XGetSubImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, height,
- AllPlanes, ZPixmap, image, 0, 0 );
+ CallTo32_LargeStack( (int(*)())XGetSubImage, 11,
+ display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
+ height, AllPlanes, ZPixmap, image, 0, 0 );
image->data = NULL;
XDestroyImage( image );
return height * bmp->bitmap.bmWidthBytes;
@@ -197,8 +195,9 @@
if (!height) return 0;
if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0;
- XPutImage( display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0,
- 0, 0, bmp->bitmap.bmWidth, height );
+ CallTo32_LargeStack( XPutImage, 10,
+ display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0,
+ 0, 0, bmp->bitmap.bmWidth, height );
image->data = NULL;
XDestroyImage( image );
return height * bmp->bitmap.bmWidthBytes;
diff --git a/objects/dib.c b/objects/dib.c
index b8d7313..f55c44f 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -10,6 +10,7 @@
#include <X11/Xutil.h>
#include "dc.h"
#include "bitmap.h"
+#include "callback.h"
#include "palette.h"
#include "icon.h"
#include "stackframe.h"
@@ -172,9 +173,10 @@
{
int x = 0, c, length;
BYTE *begin = bits;
-
- lines--;
- while (1) {
+
+ lines--;
+ while ((INT)lines >= 0)
+ {
length = *bits++;
if (length) { /* encoded */
c = *bits++;
@@ -562,9 +564,11 @@
if (startscan+lines > info->bmiHeader.biHeight)
lines = info->bmiHeader.biHeight - startscan;
- return DIB_SetImageBits( dc, lines, bmp->bitmap.bmBitsPixel,
- bits, info, coloruse, bmp->pixmap, BITMAP_GC(bmp),
- 0, 0, 0, startscan, bmp->bitmap.bmWidth, lines );
+ return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 14,
+ dc, lines, bmp->bitmap.bmBitsPixel,
+ bits, info, coloruse, bmp->pixmap,
+ BITMAP_GC(bmp), 0, 0, 0, startscan,
+ bmp->bitmap.bmWidth, lines );
}
@@ -592,13 +596,13 @@
DC_SetupGCForText( dc ); /* To have the correct colors */
XSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
- return DIB_SetImageBits( dc, lines, dc->w.bitsPerPixel,
- bits, info, coloruse,
- dc->u.x.drawable, dc->u.x.gc,
- xSrc, ySrc - startscan,
- dc->w.DCOrgX + XLPTODP( dc, xDest ),
- dc->w.DCOrgY + YLPTODP( dc, yDest ),
- cx, cy );
+ return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 14,
+ dc, lines, dc->w.bitsPerPixel, bits, info,
+ coloruse, dc->u.x.drawable, dc->u.x.gc,
+ xSrc, ySrc - startscan,
+ dc->w.DCOrgX + XLPTODP( dc, xDest ),
+ dc->w.DCOrgY + YLPTODP( dc, yDest ),
+ cx, cy );
}
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index c34a379..2cfcd75 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -2,9 +2,7 @@
* GDI functions
*
* Copyright 1993 Alexandre Julliard
- *
-static char Copyright[] = "Copyright Alexandre Julliard, 1993";
-*/
+ */
#include <stdlib.h>
#include <stdio.h>
diff --git a/objects/palette.c b/objects/palette.c
index 80b64c4..dd925ce 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -21,6 +21,8 @@
/* #define DEBUG_PALETTE */
#include "debug.h"
+static WORD SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
+
/***********************************************************************
* CreatePalette (GDI.360)
*/
@@ -80,13 +82,26 @@
/***********************************************************************
+ * SetSystemPaletteUse (GDI.373)
+ * Should this be per DC rather than system wide?
+ * Currently, it does not matter as the use is only set and returned,
+ * but not taken into account
+ */
+WORD SetSystemPaletteUse( HDC hdc, WORD use)
+{
+ WORD old=SystemPaletteUse;
+ printf("SetSystemPaletteUse(%04X,%04X) // empty stub !!!\n", hdc, use);
+ SystemPaletteUse=use;
+ return old;
+}
+
+/***********************************************************************
* GetSystemPaletteUse (GDI.374)
*/
WORD GetSystemPaletteUse( HDC hdc )
{
printf("GetSystemPaletteUse(%04X) // empty stub !!!\n", hdc);
- /* Assuming there is remaining system colors ... */
- return SYSPAL_STATIC;
+ return SystemPaletteUse;
}
diff --git a/objects/text.c b/objects/text.c
index 9e3347c..52673fe 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -302,9 +302,12 @@
if (!DC_SetupGCForText( dc )) return TRUE;
font = dc->u.x.font.fstruct;
- dprintf_text(stddeb,"ExtTextOut: %d,%d '%*.*s', %d flags=%d rect=%d,%d,%d,%d\n",
- x, y, count, count, str, count, flags,
- lprect->left, lprect->top, lprect->right, lprect->bottom );
+ dprintf_text(stddeb,"ExtTextOut: %d,%d '%*.*s', %d flags=%d\n",
+ x, y, count, count, str, count, flags);
+ if (lprect != NULL) {
+ dprintf_text(stddeb, "rect %d %d %d %d\n",
+ lprect->left, lprect->top, lprect->right, lprect->bottom );
+ }
/* Setup coordinates */
diff --git a/rc/sysres.rc b/rc/sysres.rc
index 2ca57c8..44e217f 100644
--- a/rc/sysres.rc
+++ b/rc/sysres.rc
@@ -29,14 +29,14 @@
PUSHBUTTON "&No", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
END
-SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 149
+SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 179
STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "About X"
FONT 10, "System"
{
- DEFPUSHBUTTON "OK", 1, 86, 130, 40, 14
- CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 90
- LTEXT "Text", 100, 11, 40, 190, 80, SS_NOPREFIX | WS_GROUP
+ DEFPUSHBUTTON "OK", 1, 86, 160, 40, 14
+ CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 120
+ LTEXT "Text", 100, 11, 40, 190, 110, SS_NOPREFIX | WS_GROUP
ICON "", 1088, 185, 10, 18, 20
}
diff --git a/rc/sysres_De.rc b/rc/sysres_De.rc
index 00bb498..4f74ac2 100644
--- a/rc/sysres_De.rc
+++ b/rc/sysres_De.rc
@@ -27,14 +27,14 @@
PUSHBUTTON "&Nein", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
END
-SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 149
+SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 179
STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION ""
FONT 10, "System"
{
- DEFPUSHBUTTON "OK", 1, 86, 130, 40, 14
- CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 90
- LTEXT "Text", 100, 11, 40, 190, 80, SS_NOPREFIX | WS_GROUP
+ DEFPUSHBUTTON "OK", 1, 86, 160, 40, 14
+ CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 120
+ LTEXT "Text", 100, 11, 40, 190, 110, SS_NOPREFIX | WS_GROUP
ICON "", 1088, 185, 10, 18, 20
}
diff --git a/rc/sysres_No.rc b/rc/sysres_No.rc
index ee189b2..2a86058 100644
--- a/rc/sysres_No.rc
+++ b/rc/sysres_No.rc
@@ -27,14 +27,14 @@
PUSHBUTTON "&Nei", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
END
-SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 149
+SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 50, 44, 213, 179
STYLE DS_LOCALEDIT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Om X"
FONT 10, "System"
{
- DEFPUSHBUTTON "OK", 1, 86, 130, 40, 14
- CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 90
- LTEXT "Tekst", 100, 11, 40, 190, 80, SS_NOPREFIX | WS_GROUP
+ DEFPUSHBUTTON "OK", 1, 86, 160, 40, 14
+ CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE | WS_DISABLED, 4, 35, 205, 120
+ LTEXT "Tekst", 100, 11, 40, 190, 110, SS_NOPREFIX | WS_GROUP
ICON "", 1088, 185, 10, 18, 20
}
diff --git a/tools/build.c b/tools/build.c
index b79dc51..045de3c 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -295,12 +295,6 @@
}
fdp->arg_types[i] = '\0';
- if ((type == TYPE_REGISTER) && (i > 0))
- {
- fprintf( stderr, "%d: Register function can't have arguments\n", Line);
- exit(1);
- }
-
strcpy(fdp->internal_name, GetToken());
return 0;
}
@@ -946,6 +940,110 @@
/*******************************************************************
+ * BuildCall32LargeStack
+ *
+ * Build the function used to switch to the original 32-bit stack
+ * before calling a 32-bit function from 32-bit code. This is used for
+ * functions that need a large stack, like X bitmaps functions.
+ *
+ * The generated function has the following prototype:
+ * int CallTo32_LargeStack( int (*func)(), int nbargs, ... )
+ *
+ * Stack layout:
+ * ... ...
+ * (ebp+20) arg2
+ * (ebp+16) arg1
+ * (ebp+12) nbargs
+ * (ebp+8) func
+ * (ebp+4) ret addr
+ * (ebp) ebp
+ */
+static void BuildCall32LargeStack(void)
+{
+ /* Function header */
+
+ printf( "/**********\n" );
+ printf( " * " PREFIX "CallTo32_LargeStack\n" );
+ printf( " **********/\n" );
+ printf( "\t.align 4\n" );
+ printf( "\t.globl " PREFIX "CallTo32_LargeStack\n\n" );
+ printf( PREFIX "CallTo32_LargeStack:\n" );
+
+ /* Entry code */
+
+ printf( "\tpushl %%ebp\n" );
+ printf( "\tmovl %%esp,%%ebp\n" );
+
+ /* Save registers */
+
+ printf( "\tpushl %%ecx\n" );
+ printf( "\tpushl %%esi\n" );
+ printf( "\tpushl %%edi\n" );
+
+ /* Switch to the new stack (if any) */
+
+ printf( "\tleal 16(%%ebp),%%esi\n" );
+ printf( "\tmovl " PREFIX "IF1632_Original32_esp, %%ecx\n" );
+ printf( "\tjcxz 0f\n" );
+ printf( "\tmovl %%ecx,%%esp\n" );
+
+ /* Transfer the arguments */
+
+ printf( "\tmovl 12(%%ebp),%%ecx\n" );
+ printf( "\tjcxz 1f\n" );
+ printf( "\tshl $2,%%ecx\n" );
+ printf( "\tsubl %%ecx,%%esp\n" );
+ printf( "\tmovl %%esp,%%edi\n" );
+ printf( "\tshr $2,%%ecx\n" );
+ printf( "\trep; movsl\n" );
+ printf( "1:\n" );
+
+ /* Call the function */
+
+ printf( "\tcall 8(%%ebp)\n" );
+
+ /* Switch back to the normal stack */
+
+ printf( "\tleal -12(%%ebp),%%esp\n" );
+
+ /* Restore registers and return */
+
+ printf( "\tpopl %%edi\n" );
+ printf( "\tpopl %%esi\n" );
+ printf( "\tpopl %%ecx\n" );
+
+ printf( "\tpopl %%ebp\n" );
+ printf( "\tret\n" );
+
+ /* We get here if IF1632_Original32_esp is 0, i.e. we have not */
+ /* switched to another 32-bit stack yet. */
+
+ printf( "0:\n" );
+
+ /* Restore the registers */
+
+ printf( "\tpopl %%edi\n" );
+ printf( "\tpopl %%esi\n" );
+ printf( "\tpopl %%ecx\n" );
+
+ /* Move the return address up the stack */
+
+ printf( "\tmovl 4(%%ebp),%%eax\n" );
+ printf( "\tmovl %%eax,12(%%ebp)\n" );
+
+ /* Restore ebp and remove old return address */
+
+ printf( "\tpopl %%ebp\n" );
+ printf( "\taddl $4,%%esp\n" );
+
+ /* Now jump to the routine, leaving the original return address and */
+ /* the arguments on the stack. */
+
+ printf( "\tret\n" );
+}
+
+
+/*******************************************************************
* TransferArgs16To32
*
* Get the arguments from the 16-bit stack and push them on the 32-bit stack.
@@ -1100,6 +1198,8 @@
* profile is: type_xxxxx, where 'type' is one of 'regs', 'word' or
* 'long' and each 'x' is an argument ('w'=word, 's'=signed word,
* 'l'=long, 'p'=pointer).
+ * For register functions, the arguments are ignored, but they are still
+ * removed from the stack upon return.
*
* Stack layout upon entry to the callback function:
* ... ...
@@ -1174,20 +1274,16 @@
/* Switch to the 32-bit stack */
+ printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebp\n" );
printf( "\tpushw %%ds\n" );
printf( "\tpopw %%ss\n" );
- printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" );
+ printf( "\tleal -%d(%%ebp),%%esp\n",
+ reg_func ? sizeof(struct sigcontext_struct) : 4 * strlen(args) );
/* Setup %ebp to point to the previous stack frame (built by CallTo16) */
- printf( "\tmovl %%esp,%%ebp\n" );
printf( "\taddl $24,%%ebp\n" );
- if (reg_func)
- printf( "\tsubl $%d,%%esp\n", sizeof(struct sigcontext_struct) );
- else if (*args)
- printf( "\tsubl $%d,%%esp\n", 4 * strlen(args) );
-
/* Call the entry point */
if (debugging)
@@ -1226,6 +1322,25 @@
{
/* Restore registers from the context structure */
RestoreContext();
+
+ /* Calc the arguments size */
+ while (*args)
+ {
+ switch(*args)
+ {
+ case 'w':
+ case 's':
+ argsize += 2;
+ break;
+ case 'p':
+ case 'l':
+ argsize += 4;
+ break;
+ default:
+ fprintf( stderr, "Unknown arg type '%c'\n", *args );
+ }
+ args++;
+ }
}
else /* Store the return value in dx:ax if needed */
{
@@ -1502,6 +1617,10 @@
printf( "/* File generated automatically. Do no edit! */\n\n" );
printf( "\t.text\n" );
+ /* Build the 32-bit large stack callback */
+
+ BuildCall32LargeStack();
+
/* Build the callback functions */
for (i = 2; i < argc; i++) BuildCall32Func( argv[i] );
diff --git a/windows/graphics.c b/windows/graphics.c
index 2531ed3..26ba7b3 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -14,6 +14,7 @@
#endif
#include "dc.h"
#include "bitmap.h"
+#include "callback.h"
#include "metafile.h"
#include "syscolor.h"
#include "stddebug.h"
@@ -883,13 +884,45 @@
/**********************************************************************
+ * GRAPH_DoFloodFill
+ *
+ * Main flood-fill routine.
+ */
+static BOOL GRAPH_DoFloodFill( DC *dc, RECT *rect, INT x, INT y,
+ COLORREF color, WORD fillType )
+{
+ XImage *image;
+
+ if (!(image = XGetImage( display, dc->u.x.drawable,
+ dc->w.DCOrgX + rect->left,
+ dc->w.DCOrgY + rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top,
+ AllPlanes, ZPixmap ))) return FALSE;
+
+ if (DC_SetupGCForBrush( dc ))
+ {
+ /* ROP mode is always GXcopy for flood-fill */
+ XSetFunction( display, dc->u.x.gc, GXcopy );
+ GRAPH_InternalFloodFill( image, dc,
+ XLPTODP(dc,x) - rect->left,
+ YLPTODP(dc,y) - rect->top,
+ dc->w.DCOrgX + rect->left,
+ dc->w.DCOrgY + rect->top,
+ COLOR_ToPhysical( dc, color ), fillType );
+ }
+
+ XDestroyImage( image );
+ return TRUE;
+}
+
+
+/**********************************************************************
* ExtFloodFill (GDI.372)
*/
BOOL ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, WORD fillType )
{
RECT rect;
- Pixel pixel;
- XImage *image;
DC *dc;
dprintf_graphics( stddeb, "ExtFloodFill %x %d,%d %06lx %d\n",
@@ -906,28 +939,9 @@
if (!PtVisible( hdc, x, y )) return FALSE;
if (GetRgnBox( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE;
- pixel = COLOR_ToPhysical( dc, color );
- if (!(image = XGetImage( display, dc->u.x.drawable,
- dc->w.DCOrgX + rect.left, dc->w.DCOrgY + rect.top,
- rect.right - rect.left, rect.bottom - rect.top,
- AllPlanes, ZPixmap ))) return FALSE;
-
- if (DC_SetupGCForBrush( dc ))
- {
- /* ROP mode is always GXcopy for flood-fill */
- XSetFunction( display, dc->u.x.gc, GXcopy );
- /* We can pass anything except 0 as a region */
- GRAPH_InternalFloodFill( image, dc,
- XLPTODP(dc,x) - rect.left,
- YLPTODP(dc,y) - rect.top,
- dc->w.DCOrgX + rect.left,
- dc->w.DCOrgY + rect.top,
- pixel, fillType );
- }
-
- XDestroyImage( image );
- return TRUE;
+ return CallTo32_LargeStack( (int(*)())GRAPH_DoFloodFill, 6,
+ dc, &rect, x, y, color, fillType );
}
diff --git a/windows/keyboard.c b/windows/keyboard.c
index e02ebd7..7610ae9 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -43,6 +43,18 @@
}
/**********************************************************************
+ * SetKeyboardState [USER.223]
+ */
+void SetKeyboardState(BYTE FAR *lpKeyState)
+{
+ if (lpKeyState != NULL) {
+ memcpy(KeyStateTable, lpKeyState, 256);
+ MouseButtonsStates[0] = KeyStateTable[VK_LBUTTON];
+ MouseButtonsStates[1] = KeyStateTable[VK_MBUTTON];
+ MouseButtonsStates[2] = KeyStateTable[VK_RBUTTON];
+ }
+}
+/**********************************************************************
* GetAsyncKeyState (USER.249)
*
* Determine if a key is or was pressed. retval has high-order
diff --git a/windows/win.c b/windows/win.c
index 29dc18a..be12941 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -210,7 +210,7 @@
*
* Create the desktop window.
*/
-BOOL WIN_CreateDesktopWindow()
+BOOL WIN_CreateDesktopWindow(void)
{
WND *wndPtr;
HCLASS hclass;