From a2f2e0196206a0ff341d1817353e88a500794c33 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Tue, 6 Jun 1995 16:40:35 +0000 Subject: [PATCH] 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! --- ANNOUNCE | 20 +- ChangeLog | 94 ++++ controls/menu.c | 1 + debugger/debug.l | 45 +- debugger/info.c | 4 +- if1632/gdi.spec | 1 + if1632/kernel.spec | 10 +- if1632/relay.c | 1 + if1632/shell.spec | 2 +- if1632/user.spec | 2 +- if1632/winprocs.spec | 20 + include/callback.h | 3 + include/miscemu.h | 8 + include/stackframe.h | 1 + include/task.h | 6 +- include/windows.h | 2 +- loader/Imakefile | 1 - loader/main.c | 9 +- loader/module.c | 166 ++++--- loader/ne_image.c | 23 +- loader/resource.c | 18 + loader/signal.c | 120 ++--- loader/task.c | 71 ++- memory/Imakefile | 1 + memory/global.c | 2 +- {loader => memory}/ldt.c | 0 memory/local.c | 374 ++++++++++++---- misc/commdlg.c | 927 +++++++++++++++------------------------ misc/compobj.c | 2 +- misc/shell.c | 7 +- misc/user.c | 16 - miscemu/Imakefile | 2 + miscemu/int21.c | 21 +- miscemu/int5c.c | 33 ++ miscemu/interrupts.c | 190 ++++++++ objects/bitblt.c | 32 +- objects/bitmap.c | 95 ++-- objects/dib.c | 30 +- objects/gdiobj.c | 4 +- objects/palette.c | 19 +- objects/text.c | 9 +- rc/sysres.rc | 8 +- rc/sysres_De.rc | 8 +- rc/sysres_No.rc | 8 +- tools/build.c | 145 +++++- windows/graphics.c | 60 ++- windows/keyboard.c | 12 + windows/win.c | 2 +- 48 files changed, 1612 insertions(+), 1023 deletions(-) rename {loader => memory}/ldt.c (100%) create mode 100644 miscemu/int5c.c create mode 100644 miscemu/interrupts.c diff --git a/ANNOUNCE b/ANNOUNCE index 03f377e65a8..1fbc97c5bc4 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 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-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 fb55ccd5bc8..4cef5d6e9f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,97 @@ +---------------------------------------------------------------------- +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) diff --git a/controls/menu.c b/controls/menu.c index 01a040c65f4..6cea09d3842 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -344,6 +344,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner ) 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 18a6b5acf45..6e9817efd4a 100644 --- a/debugger/debug.l +++ b/debugger/debug.l @@ -173,34 +173,27 @@ dbg_read(char * buf, int size){ 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 b31eeae7989..938150a49b7 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -284,12 +284,10 @@ void dbg_bt(){ 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 598d289bb0d..81584dbc6d2 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -234,6 +234,7 @@ id 3 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 7ca626c248f..1fbeb4eca0b 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -32,7 +32,7 @@ id 1 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 @@ id 1 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 @@ id 1 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 @@ id 1 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 @@ id 1 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 50498276e14..c628457684c 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -60,6 +60,7 @@ WORD IF1632_Saved16_sp = 0; /* 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 b00a5c4ac5d..ad04c352b2e 100644 --- a/if1632/shell.spec +++ b/if1632/shell.spec @@ -23,7 +23,7 @@ id 5 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 e69390c6802..f4156d44f3f 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -221,7 +221,7 @@ id 2 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 16240c4f008..8a0e88d15aa 100644 --- a/if1632/winprocs.spec +++ b/if1632/winprocs.spec @@ -25,3 +25,23 @@ id 24 22 pascal ComboLBoxWndProc(word word word long) ComboLBoxWndProc 23 pascal16 CARET_Callback(word word word long) CARET_Callback 24 pascal16 TASK_Reschedule() TASK_Reschedule + +# 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 05107589377..3a2dba32ab2 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 1cc6fcc1c51..4f8b37878d6 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_int26(struct sigcontext_struct *); extern int do_int2a(struct sigcontext_struct *); extern int do_int2f(struct sigcontext_struct *); extern int do_int31(struct sigcontext_struct *); +extern int do_int5c(struct sigcontext_struct *); extern void inportb(struct sigcontext_struct *context); extern void inport(struct sigcontext_struct *context); @@ -24,6 +28,10 @@ extern void outport_abs(struct sigcontext_struct *context); 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 81964616c0e..3295e8330aa 100644 --- a/include/stackframe.h +++ b/include/stackframe.h @@ -55,6 +55,7 @@ extern WORD IF1632_Saved16_sp; /* 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 e78f6d5fea3..cbd28ae7e4e 100644 --- a/include/task.h +++ b/include/task.h @@ -21,9 +21,9 @@ typedef struct 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 76ec59d4887..7230f397dc2 100644 --- a/include/windows.h +++ b/include/windows.h @@ -2836,7 +2836,7 @@ Fc(int,FrameRect,HDC,a,LPRECT,b,HBRUSH,c) 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 9c15c281413..befe47a6a63 100644 --- a/loader/Imakefile +++ b/loader/Imakefile @@ -4,7 +4,6 @@ MODULE = loader SRCS = \ dump.c \ - ldt.c \ main.c \ module.c \ ne_image.c \ diff --git a/loader/main.c b/loader/main.c index 3ace9d3c30d..e6ad03e50f1 100644 --- a/loader/main.c +++ b/loader/main.c @@ -10,12 +10,12 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #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 @@ int MAIN_Init(void) /* 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 c4af5bfd3d5..aa397d8c1e3 100644 --- a/loader/module.c +++ b/loader/module.c @@ -292,7 +292,7 @@ int MODULE_OpenFile( HMODULE hModule ) /*********************************************************************** * MODULE_CreateSegments */ -BOOL MODULE_CreateSegments( HMODULE hModule ) +static BOOL MODULE_CreateSegments( HMODULE hModule ) { SEGTABLEENTRY *pSegment; NE_MODULE *pModule; @@ -308,9 +308,8 @@ BOOL MODULE_CreateSegments( HMODULE hModule ) { /* 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, @@ -326,6 +325,57 @@ BOOL MODULE_CreateSegments( HMODULE hModule ) } +/*********************************************************************** + * 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 */ @@ -517,62 +567,6 @@ HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs ) } -/*********************************************************************** - * 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 * @@ -800,6 +794,7 @@ HMODULE MODULE_FindModule( LPCSTR path ) 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 @@ HMODULE MODULE_FindModule( LPCSTR path ) 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 @@ static void MODULE_FreeModule( HMODULE hModule ) 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 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock ) 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 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock ) } } - /* Load the segments (except the DGROUP) */ - - for (i = 1; i <= pModule->seg_count; i++) - if (i != pModule->dgroup) NE_LoadSegment( hModule, i ); - - /* Create an instance for this module */ + /* Load the segments */ - 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 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock ) 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 @@ BOOL FreeModule( HANDLE hModule ) */ 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 @@ int GetModuleFileName( HANDLE hModule, LPSTR lpFileName, short nSize ) 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 LoadLibrary( LPCSTR libname ) 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 @@ HANDLE LoadLibrary( LPCSTR libname ) 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 1a14ef2b1af..4529f622341 100644 --- a/loader/ne_image.c +++ b/loader/ne_image.c @@ -56,6 +56,14 @@ BOOL NE_LoadSegment( HMODULE hModule, WORD segnum ) 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 @@ void NE_InitializeDLLs( HMODULE hModule ) 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 adbfc803d7a..09707867f4c 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 @@ HGLOBAL AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ) } } +/********************************************************************** + * 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 b395d41c44a..6ac04ad5031 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 @@ wine_sigaction(int sig,struct sigaction * new, struct sigaction * old) } #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 @@ static void win_fault(int signal, int code, struct sigcontext *scp) /* And back up over the int3 instruction. */ if(signal == SIGTRAP) { - scp->sc_eip--; + EIP--; goto oops; } #endif @@ -126,76 +129,83 @@ static void win_fault(int signal, int code, struct sigcontext *scp) 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 @@ static void win_fault(int signal, int code, struct sigcontext *scp) 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 33d53de8dee..5663419cb10 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, /* 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 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, 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 @@ void TASK_KillCurrentTask( int exitCode ) TASK_UnlinkTask( hCurrentTask ); hTaskToKill = hCurrentTask; + hLockedTask = 0; Yield(); /* We never return from Yield() */ } @@ -454,6 +456,10 @@ void TASK_Reschedule(void) 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 @@ void TASK_Reschedule(void) 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 TASK_Reschedule(void) */ void InitTask( struct sigcontext_struct context ) { + static int firstTask = 1; TDB *pTask; NE_MODULE *pModule; @@ -526,6 +534,22 @@ void InitTask( struct sigcontext_struct context ) 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: @@ -601,6 +625,26 @@ void SetPriority( HTASK hTask, int delta ) } +/*********************************************************************** + * 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) */ @@ -746,6 +790,19 @@ WORD GetCurrentPDB(void) } +/*********************************************************************** + * 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) */ diff --git a/memory/Imakefile b/memory/Imakefile index 3364fecc32d..8dbf16f2864 100644 --- a/memory/Imakefile +++ b/memory/Imakefile @@ -5,6 +5,7 @@ MODULE = memory SRCS = \ selector.c \ global.c \ + ldt.c \ local.c OBJS = $(SRCS:.c=.o) diff --git a/memory/global.c b/memory/global.c index 7a0a1446c05..d7fd15bc68b 100644 --- a/memory/global.c +++ b/memory/global.c @@ -139,7 +139,7 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, /* 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 134c1bf18f7..1cd4a588815 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 @@ typedef struct } 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 @@ typedef struct #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 @@ static LOCALHEAPINFO *LOCAL_GetHeap( WORD ds ) { 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 @@ static void LOCAL_AddFreeBlock( char *baseptr, WORD block ) 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 @@ static void LOCAL_RemoveBlock( char *baseptr, WORD block ) /* 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 @@ static void LOCAL_PrintHeap( WORD ds ) 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 @@ static void LOCAL_PrintHeap( WORD ds ) } 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 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end ) 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 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end ) 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 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end ) 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 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end ) /* 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 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end ) /* 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; +} - /* Make a block out of the free arena */ +/*********************************************************************** + * 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,11 +466,165 @@ HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size ) } 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_NewHTable + */ +static BOOL LOCAL_NewHTable( WORD ds ) +{ + char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + LOCALHEAPINFO *pInfo; + HLOCAL 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; + } + + 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_FreeArena + */ +HLOCAL LOCAL_FreeArena( WORD ds, WORD arena ) +{ + char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + LOCALHEAPINFO *pInfo; + LOCALARENA *pArena, *pPrev, *pNext; + + 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) { + /* 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 */ + + pPrev = ARENA_PTR( ptr, pArena->prev & ~3 ); + pNext = ARENA_PTR( ptr, pArena->next ); + if ((pPrev->prev & 3) == LOCAL_ARENA_FREE) + { + arena = pArena->prev & ~3; + pArena = pPrev; + LOCAL_RemoveBlock( ptr, pPrev->next ); + pInfo->items--; + } + else /* Make a new free block */ + { + LOCAL_AddFreeBlock( ptr, arena ); + } + + /* Check if we can merge with the next block */ + + if ((pArena->next == pArena->free_next) && + (pArena->next != pInfo->last)) + { + LOCAL_RemoveBlock( ptr, pArena->next ); + pInfo->items--; + } + return 0; +} + + +/*********************************************************************** + * 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 @@ -428,29 +636,42 @@ 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; + 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; - arena = handle - ARENA_HEADER_SIZE; + + 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 (size < pArena->next - handle) + if (nextarena < pArena->next) { - if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA))) + 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, handle + size ); - LOCAL_AddFreeBlock( ptr, handle + size ); + LOCAL_AddBlock( ptr, arena, nextarena ); + LOCAL_AddFreeBlock( ptr, nextarena ); pInfo->items++; } dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle ); @@ -461,14 +682,15 @@ HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags ) pNext = ARENA_PTR( ptr, pArena->next ); if (((pNext->prev & 3) == LOCAL_ARENA_FREE) && - (size <= pNext->next - handle)) + (nextarena <= pNext->next)) { LOCAL_RemoveBlock( ptr, pArena->next ); - if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA))) + 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, handle + size ); - LOCAL_AddFreeBlock( ptr, handle + size ); + LOCAL_AddBlock( ptr, arena, nextarena ); + LOCAL_AddFreeBlock( ptr, nextarena ); pInfo->items++; } dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle ); @@ -477,61 +699,21 @@ HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags ) /* 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 ); + 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_Free - * - * Implementation of LocalFree(). - */ -HLOCAL LOCAL_Free( WORD ds, HLOCAL handle ) -{ - 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; - pArena = ARENA_PTR( ptr, arena ); - if ((pArena->prev & 3) == LOCAL_ARENA_FREE) return handle; - - /* Check if we can merge with the previous block */ - - pPrev = ARENA_PTR( ptr, pArena->prev & ~3 ); - pNext = ARENA_PTR( ptr, pArena->next ); - if ((pPrev->prev & 3) == LOCAL_ARENA_FREE) - { - arena = pArena->prev & ~3; - pArena = pPrev; - LOCAL_RemoveBlock( ptr, pPrev->next ); - pInfo->items--; - } - else /* Make a new free block */ - { - LOCAL_AddFreeBlock( ptr, arena ); - } - - /* Check if we can merge with the next block */ - - if ((pArena->next == pArena->free_next) && - (pArena->next != pInfo->last)) - { - LOCAL_RemoveBlock( ptr, pArena->next ); - pInfo->items--; - } - return 0; -} - - /*********************************************************************** * LOCAL_Size * @@ -589,6 +771,11 @@ HLOCAL LocalFree( HLOCAL handle ) */ 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 @@ WORD LocalSize( HLOCAL handle ) */ 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 d9a0f31fe2a..47d08ed34a9 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 hFloppy = 0; 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 GetOpenFileName(LPOPENFILENAME lpofn) 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 @@ BOOL GetOpenFileName(LPOPENFILENAME lpofn) 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 GetSaveFileName(LPOPENFILENAME lpofn) BOOL bRet; LPCSTR dlgTemplate; + if (!FileDlg_Init()) return FALSE; + if (lpofn == NULL) return FALSE; if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) { dlgTemplate = GlobalLock(lpofn->hInstance); @@ -243,263 +149,368 @@ BOOL GetSaveFileName(LPOPENFILENAME lpofn) 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); + } +} /*********************************************************************** - * FileOpenDlgProc [COMMDLG.6] + * FILEDLG_ScanDir [internal] */ -BOOL FileOpenDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) +static BOOL FILEDLG_ScanDir(HWND hWnd, LPSTR newPath) { - 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); - } + 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); - 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; - } - /* 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); + return TRUE; +} + +/*********************************************************************** + * FILEDLG_GetFileType [internal] + */ +static LPSTR FILEDLG_GetFileType(LPSTR ptr, WORD index) +{ + int n, i; - 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 (ptr == NULL) return NULL; - if (!OpenDlg_ScanDir(hWnd, str)) { - printf("OpenDlg_ScanDir // ChangeDir Error !\n"); + 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; } - /* select current drive in combo */ - nDrive = DOS_GetDefaultDrive(); - SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, nDrive, 0L); + 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; - ShowWindow(hWnd, SW_SHOWNORMAL); - return TRUE; + 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; + } - case WM_SHOWWINDOW: - if (wParam == 0) break; - if (!(lpofn->Flags & OFN_SHOWHELP)) { - ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE); + 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 (lpofn->Flags & OFN_HIDEREADONLY) { - ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); + 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 TRUE; + return FALSE; +} - case WM_MEASUREITEM: +/*********************************************************************** + * 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; - 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; + 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; } - 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; + + /* set default filter */ + SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL, + 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,""); } - 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; + 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 (!(lpofn->Flags & OFN_SHOWHELP)) { + ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE); + } + if (lpofn->Flags & OFN_HIDEREADONLY) { + ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); } - break; + 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_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; + 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); + } + return TRUE; 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, 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); } - 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 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 FileOpenDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) */ 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); @@ -784,6 +570,21 @@ BOOL FileSaveDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) } +/*********************************************************************** + * 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] */ diff --git a/misc/compobj.c b/misc/compobj.c index c527b0fc241..690cfa4d2ee 100644 --- a/misc/compobj.c +++ b/misc/compobj.c @@ -20,6 +20,6 @@ OLESTATUS WINAPI CoDisconnectObject( 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 bab7b02fcc8..f300710d9d5 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -458,13 +458,10 @@ HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon) /************************************************************************* * 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 d9bf1d890ed..9e0333f3a92 100644 --- a/misc/user.c +++ b/misc/user.c @@ -92,24 +92,8 @@ BOOL USER_HeapInit(void) */ 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 11e38401965..70a5b6a7628 100644 --- a/miscemu/Imakefile +++ b/miscemu/Imakefile @@ -15,6 +15,8 @@ SRCS = \ 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 e4bb91f77b0..f0af67be3d0 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c @@ -1324,10 +1324,7 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 @@ int do_int21(struct sigcontext_struct * context) 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 00000000000..060da7649b6 --- /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 00000000000..01f957e8374 --- /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 6822f53f309..f5037b01a53 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 @@ static void BITBLT_GetRow( XImage *image, int *pdata, short row, 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 @@ static void BITBLT_GetRow( XImage *image, int *pdata, short row, } 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 @@ BOOL PatBlt( HDC hdc, short left, short top, 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 @@ BOOL BitBlt( HDC hdcDst, short xDst, short yDst, short width, short height, 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 @@ BOOL StretchBlt( HDC hdcDst, short xDst, short yDst, 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 e394ccb8e4b..e0f15c47c2c 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" @@ -80,46 +79,18 @@ static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) */ 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 ); -} - - -/*********************************************************************** - * CreateCompatibleBitmap (GDI.51) - */ -HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) -{ - DC * dc; - dprintf_gdi(stddeb, "CreateCompatibleBitmap: %d %dx%d\n", - hdc, width, height ); - if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - return CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL ); -} - - -/*********************************************************************** - * CreateBitmapIndirect (GDI.49) - */ -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; + dprintf_gdi( stddeb, "CreateBitmap: %dx%d, %d colors\n", + width, height, 1 << (planes*bpp) ); - if (bmp->bmHeight < 0) - bmp->bmHeight = -bmp->bmHeight; - - if (bmp->bmWidth < 0) - bmp->bmWidth = -bmp->bmWidth; - + /* 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 ); @@ -128,24 +99,50 @@ HBITMAP CreateBitmapIndirect( BITMAP * bmp ) bmpObjPtr->size.cx = 0; bmpObjPtr->size.cy = 0; - bmpObjPtr->bitmap = *bmp; + 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; - bmpObjPtr->bitmap.bmWidthBytes = (bmp->bmWidth*bmp->bmBitsPixel+15)/16 * 2; /* Create the pixmap */ - bmpObjPtr->pixmap = XCreatePixmap( display, rootWindow, bmp->bmWidth, - bmp->bmHeight, bmp->bmBitsPixel ); + bmpObjPtr->pixmap = XCreatePixmap(display, rootWindow, width, height, bpp); 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 ); + else if (bits) /* Set bitmap bits */ + SetBitmapBits( hbitmap, height * bmpObjPtr->bitmap.bmWidthBytes, bits); return hbitmap; } +/*********************************************************************** + * CreateCompatibleBitmap (GDI.51) + */ +HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) +{ + DC * dc; + dprintf_gdi(stddeb, "CreateCompatibleBitmap: %d %dx%d\n", + hdc, width, height ); + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + return CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL ); +} + + +/*********************************************************************** + * CreateBitmapIndirect (GDI.49) + */ +HBITMAP CreateBitmapIndirect( BITMAP * bmp ) +{ + return CreateBitmap( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes, + bmp->bmBitsPixel, PTR_SEG_TO_LIN( bmp->bmBits ) ); +} + + /*********************************************************************** * GetBitmapBits (GDI.74) */ @@ -167,8 +164,9 @@ LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) 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 @@ LONG SetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) 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 b8d731333ab..f55c44fb138 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 @@ static void DIB_SetImageBits_RLE4( WORD lines, BYTE *bits, WORD width, { 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 @@ int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, 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 @@ int SetDIBitsToDevice( HDC hdc, short xDest, short yDest, WORD cx, WORD cy, 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 c34a379fd05..2cfcd75d9a2 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 80b64c4024c..dd925ceaa75 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -21,6 +21,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993,1994"; /* #define DEBUG_PALETTE */ #include "debug.h" +static WORD SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */ + /*********************************************************************** * CreatePalette (GDI.360) */ @@ -79,14 +81,27 @@ WORD SetPaletteEntries( HPALETTE hpalette, WORD start, WORD count, } +/*********************************************************************** + * 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 9e3347c7452..52673fe3978 100644 --- a/objects/text.c +++ b/objects/text.c @@ -302,9 +302,12 @@ BOOL ExtTextOut( HDC hdc, short x, short y, WORD flags, LPRECT lprect, 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 2ca57c8d122..44e217f0961 100644 --- a/rc/sysres.rc +++ b/rc/sysres.rc @@ -29,14 +29,14 @@ BEGIN 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 00bb4983e93..4f74ac2d796 100644 --- a/rc/sysres_De.rc +++ b/rc/sysres_De.rc @@ -27,14 +27,14 @@ BEGIN 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 ee189b26003..2a860580233 100644 --- a/rc/sysres_No.rc +++ b/rc/sysres_No.rc @@ -27,14 +27,14 @@ BEGIN 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 b79dc514c13..045de3cb4e2 100644 --- a/tools/build.c +++ b/tools/build.c @@ -295,12 +295,6 @@ static int ParseExportFunction(int ordinal, int type) } 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; } @@ -945,6 +939,110 @@ static void BuildSpec16Files( char *specname ) } +/******************************************************************* + * 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 * @@ -1100,6 +1198,8 @@ static void RestoreContext(void) * 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 @@ static void BuildCall32Func( char *profile ) /* 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 @@ static void BuildCall32Func( char *profile ) { /* 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 @@ int main(int argc, char **argv) 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 2531ed3feba..26ba7b36769 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" @@ -882,14 +883,46 @@ static void GRAPH_InternalFloodFill( XImage *image, DC *dc, } +/********************************************************************** + * 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 @@ BOOL ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, WORD fillType ) 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 e02ebd7e48a..7610ae9edb2 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -42,6 +42,18 @@ void GetKeyboardState(BYTE FAR *lpKeyState) } } +/********************************************************************** + * 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) * diff --git a/windows/win.c b/windows/win.c index 29dc18a798b..be129410b3b 100644 --- a/windows/win.c +++ b/windows/win.c @@ -210,7 +210,7 @@ static void WIN_DestroyWindow( HWND hwnd ) * * Create the desktop window. */ -BOOL WIN_CreateDesktopWindow() +BOOL WIN_CreateDesktopWindow(void) { WND *wndPtr; HCLASS hclass; -- GitLab