Commit a2f2e019 authored by Alexandre Julliard's avatar Alexandre Julliard

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!
parent 2787be87
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.
......
----------------------------------------------------------------------
Tue Jun 6 12:11:41 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
* [controls/menu.c]
Fixed bug with drawing multi-column menus with vertical separator.
* [debugger/debug.l]
Fixed NULL-pointer reference after readline().
* [if1632/winprocs.spec] [miscemu/int21.c] [miscemu/interrupts.c]
Added interrupt vector emulation. Allows to retrieve an interrupt
vector and jump to it without crashing.
* [loader/ldt.c]
Moved ldt.c to memory directory.
* [loader/task.c]
Implemented LockCurrentTask() and GetInstanceData().
* [objects/bitblt.c]
Fixed a bug that caused StretchBlt() to use wrong colors when
stretching a monochrome bitmap to a color display.
* [objects/bitmap.c]
Fixed a segmented pointer bug in CreateBitmapIndirect().
* [tools/build.c]
Added possibility to have arguments for register functions; used
by interrupt vectors to remove the flags from the stack.
Generate a new function CallTo32_LargeStack(), that allows calling
a 32-bit function using the original 32-bit stack, for functions
that need more that 64k of stack.
Tue May 30 10:29:56 1995 Martin von Loewis <martin@informatik.hu-berlin.de>
* [if1632/shell.spec] [misc/shell.c]
DoEnvironmentSubst: fixed prototype
* [if1632/gdi.spec] [objects/palette.c]
SetSystemPaletteUse: new function
* [if1632/kernel.spec] [loader/resource.c]
DirectResAlloc: new function
* [if1632/user.spec] [windows/keyboard.c]
SetKeyboardState: new function
Mon May 29 12:58:28 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [tools/build.c]
Prevent interrupts from destroying the args for a 32 bit function
by loading the correct value into %esp directly after %ss.
* [loader/ne_image.c] [loader/module.c]
The new instance must be created earlier in LoadModule(), so that
fixups referencing it will be handled correctly.
Initialize the local heap for a DGROUP in NE_LoadSegment().
* [objects/dib.c]
Like RLE8 bitmaps, RLE4 bitmaps don't always end with a proper code.
This used to crash Wine. Fixed.
* [objects/text.c]
Fix possible null pointer dereference in debugging output.
* [misc/commdlg.c]
Handle user input in the edit control better. Some bugs fixed.
* [memory/local.c]
Started implementing moveable blocks. This is unfinished (!), but
at least it does not seem to break things.
Wed May 24 13:26:36 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [loader/module.c]
LoadModule(): DLLs occasionally have a data segment, and they work
much better if it is loaded :-)
LoadLibrary(): pass HMODULE instead of HINSTANCE to NE_InitializeDLLs.
FindModule(): also strip off the last backslash of the pathnames
(Winhelp tried to load C:\WINDOWS\SYSTEM\COMMDLG.DLL).
GetModuleHandle(): just call MODULE_FindModule, it does the same job,
only better.
* [loader/ne_image.c]
LocalInit() the heap of a DLL in NE_InitDLL. (This is probably
not really correct, it seems that all programs and DLLs try to do
this themselves. But they pass weird parameters.)
NE_InitializeDLLs should also call NE_InitDLL for the passed hModule.
* [loader/task.c] [misc/user.c]
Finish global initializations in InitTask instead of InitApp, or
all the DLLs will be initialized in InitTask without any available
window classes!
----------------------------------------------------------------------
Sun May 21 12:30:30 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
* [debugger/hash.c] [debugger/info.c]
......
......@@ -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)
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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 */
......
#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 */
......@@ -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))
......
......@@ -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 */
......
......@@ -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)
......
......@@ -4,7 +4,6 @@ MODULE = loader
SRCS = \
dump.c \
ldt.c \
main.c \
module.c \
ne_image.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();
......
......@@ -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,
......@@ -327,6 +326,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
*/
HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
......@@ -518,62 +568,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
*
* Lookup the ordinal for a given name.
......@@ -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;
}
......
......@@ -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 );
}
......@@ -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
......
......@@ -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++);
......
......@@ -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:
......@@ -602,6 +626,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)
*/
void OldYield(void)
......@@ -747,6 +791,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)
*/
WORD GetNumTasks(void)
......
......@@ -5,6 +5,7 @@ MODULE = memory
SRCS = \
selector.c \
global.c \
ldt.c \
local.c
OBJS = $(SRCS:.c=.o)
......
......@@ -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;
......
......@@ -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,62 +699,22 @@ 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
*
* Implementation of LocalSize().
......@@ -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;
}
......
......@@ -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);
......@@ -785,6 +571,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]
*/
BOOL ColorDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
......
......@@ -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;
}
......@@ -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;
}
......
......@@ -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;
......
......@@ -15,6 +15,8 @@ SRCS = \
int2a.c \
int2f.c \
int31.c \
int5c.c \
interrupts.c \
ioports.c
OBJS = $(SRCS:.c=.o)
......
......@@ -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 )
{
......
/*
* 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 );
}
/*
* 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 );
}
......@@ -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 );
}
......@@ -2,15 +2,14 @@
* GDI bitmap objects
*
* Copyright 1993 Alexandre Julliard
*
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
*/
*/
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "gdi.h"
#include "arch.h"
#include "callback.h"
#include "dc.h"
#include "bitmap.h"
#include "prototypes.h"
......@@ -81,45 +80,17 @@ 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,25 +99,51 @@ 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)
*/
LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer )
......@@ -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;
......
......@@ -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 );
}
......
......@@ -2,9 +2,7 @@
* GDI functions
*
* Copyright 1993 Alexandre Julliard
*
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
*/
*/
#include <stdlib.h>
#include <stdio.h>
......
......@@ -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)
*/
......@@ -80,13 +82,26 @@ 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;
}
......
......@@ -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 */
......
......@@ -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
}
......
......@@ -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
}
......
......@@ -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
}
......
......@@ -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;
}
......@@ -946,6 +940,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
*
* Get the arguments from the 16-bit stack and push them on the 32-bit stack.
......@@ -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] );
......
......@@ -14,6 +14,7 @@
#endif
#include "dc.h"
#include "bitmap.h"
#include "callback.h"
#include "metafile.h"
#include "syscolor.h"
#include "stddebug.h"
......@@ -883,13 +884,45 @@ 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 );
}
......
......@@ -43,6 +43,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)
*
* Determine if a key is or was pressed. retval has high-order
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment