mirror of
https://github.com/reactos/wine.git
synced 2025-01-31 09:01:59 +00:00
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!
This commit is contained in:
parent
2787be8766
commit
a2f2e01962
20
ANNOUNCE
20
ANNOUNCE
@ -1,15 +1,14 @@
|
||||
This is release 950522 of Wine the MS Windows emulator. This is still a
|
||||
This is release 950606 of Wine the MS Windows emulator. This is still a
|
||||
developer's only release. There are many bugs and many unimplemented API
|
||||
features. Most applications still do not work.
|
||||
|
||||
Patches should be submitted to "wine-new@amscons.com". Please don't forget
|
||||
to include a ChangeLog entry. I'll make a new release every other Sunday.
|
||||
|
||||
WHAT'S NEW with Wine-950522: (see ChangeLog for details)
|
||||
- Preliminary Win32 support.
|
||||
- Multimedia code works better.
|
||||
- Better message boxes, listboxes and combos.
|
||||
- SYSRES.DLL is no longer needed.
|
||||
WHAT'S NEW with Wine-950606: (see ChangeLog for details)
|
||||
- Lots of module fixes.
|
||||
- Better interrupt vectors emulation.
|
||||
- Stack no longer limited to 64k when calling X bitmap functions.
|
||||
- Lots of bug fixes.
|
||||
|
||||
See the README file in the distribution for installation instructions.
|
||||
@ -18,10 +17,11 @@ Because of lags created by using mirror, this message may reach you before
|
||||
the release is available at the ftp sites. The sources will be available
|
||||
from the following locations:
|
||||
|
||||
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950522.tar.gz
|
||||
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950522.tar.gz
|
||||
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950522.tar.gz
|
||||
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950522.tar.gz
|
||||
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950606.tar.gz
|
||||
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950606.tar.gz
|
||||
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950606.tar.gz
|
||||
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950606.tar.gz
|
||||
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950606.tar.gz
|
||||
|
||||
It should also be available from any site that mirrors tsx-11 or sunsite.
|
||||
|
||||
|
94
ChangeLog
94
ChangeLog
@ -1,3 +1,97 @@
|
||||
----------------------------------------------------------------------
|
||||
Tue Jun 6 12:11:41 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
|
||||
|
||||
* [controls/menu.c]
|
||||
Fixed bug with drawing multi-column menus with vertical separator.
|
||||
|
||||
* [debugger/debug.l]
|
||||
Fixed NULL-pointer reference after readline().
|
||||
|
||||
* [if1632/winprocs.spec] [miscemu/int21.c] [miscemu/interrupts.c]
|
||||
Added interrupt vector emulation. Allows to retrieve an interrupt
|
||||
vector and jump to it without crashing.
|
||||
|
||||
* [loader/ldt.c]
|
||||
Moved ldt.c to memory directory.
|
||||
|
||||
* [loader/task.c]
|
||||
Implemented LockCurrentTask() and GetInstanceData().
|
||||
|
||||
* [objects/bitblt.c]
|
||||
Fixed a bug that caused StretchBlt() to use wrong colors when
|
||||
stretching a monochrome bitmap to a color display.
|
||||
|
||||
* [objects/bitmap.c]
|
||||
Fixed a segmented pointer bug in CreateBitmapIndirect().
|
||||
|
||||
* [tools/build.c]
|
||||
Added possibility to have arguments for register functions; used
|
||||
by interrupt vectors to remove the flags from the stack.
|
||||
Generate a new function CallTo32_LargeStack(), that allows calling
|
||||
a 32-bit function using the original 32-bit stack, for functions
|
||||
that need more that 64k of stack.
|
||||
|
||||
Tue May 30 10:29:56 1995 Martin von Loewis <martin@informatik.hu-berlin.de>
|
||||
|
||||
* [if1632/shell.spec] [misc/shell.c]
|
||||
DoEnvironmentSubst: fixed prototype
|
||||
|
||||
* [if1632/gdi.spec] [objects/palette.c]
|
||||
SetSystemPaletteUse: new function
|
||||
|
||||
* [if1632/kernel.spec] [loader/resource.c]
|
||||
DirectResAlloc: new function
|
||||
|
||||
* [if1632/user.spec] [windows/keyboard.c]
|
||||
SetKeyboardState: new function
|
||||
|
||||
Mon May 29 12:58:28 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
|
||||
|
||||
* [tools/build.c]
|
||||
Prevent interrupts from destroying the args for a 32 bit function
|
||||
by loading the correct value into %esp directly after %ss.
|
||||
|
||||
* [loader/ne_image.c] [loader/module.c]
|
||||
The new instance must be created earlier in LoadModule(), so that
|
||||
fixups referencing it will be handled correctly.
|
||||
Initialize the local heap for a DGROUP in NE_LoadSegment().
|
||||
|
||||
* [objects/dib.c]
|
||||
Like RLE8 bitmaps, RLE4 bitmaps don't always end with a proper code.
|
||||
This used to crash Wine. Fixed.
|
||||
|
||||
* [objects/text.c]
|
||||
Fix possible null pointer dereference in debugging output.
|
||||
|
||||
* [misc/commdlg.c]
|
||||
Handle user input in the edit control better. Some bugs fixed.
|
||||
|
||||
* [memory/local.c]
|
||||
Started implementing moveable blocks. This is unfinished (!), but
|
||||
at least it does not seem to break things.
|
||||
|
||||
Wed May 24 13:26:36 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
|
||||
|
||||
* [loader/module.c]
|
||||
LoadModule(): DLLs occasionally have a data segment, and they work
|
||||
much better if it is loaded :-)
|
||||
LoadLibrary(): pass HMODULE instead of HINSTANCE to NE_InitializeDLLs.
|
||||
FindModule(): also strip off the last backslash of the pathnames
|
||||
(Winhelp tried to load C:\WINDOWS\SYSTEM\COMMDLG.DLL).
|
||||
GetModuleHandle(): just call MODULE_FindModule, it does the same job,
|
||||
only better.
|
||||
|
||||
* [loader/ne_image.c]
|
||||
LocalInit() the heap of a DLL in NE_InitDLL. (This is probably
|
||||
not really correct, it seems that all programs and DLLs try to do
|
||||
this themselves. But they pass weird parameters.)
|
||||
NE_InitializeDLLs should also call NE_InitDLL for the passed hModule.
|
||||
|
||||
* [loader/task.c] [misc/user.c]
|
||||
Finish global initializations in InitTask instead of InitApp, or
|
||||
all the DLLs will be initialized in InitTask without any available
|
||||
window classes!
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Sun May 21 12:30:30 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef __WINE_MISCEMU_H
|
||||
#define __WINE_MISCEMU_H
|
||||
|
||||
#include "wintypes.h"
|
||||
#include "wine.h"
|
||||
|
||||
extern int do_int10(struct sigcontext_struct *);
|
||||
extern int do_int13(struct sigcontext_struct *);
|
||||
extern int do_int15(struct sigcontext_struct *);
|
||||
@ -12,6 +15,7 @@ extern int do_int26(struct sigcontext_struct *);
|
||||
extern int do_int2a(struct sigcontext_struct *);
|
||||
extern int do_int2f(struct sigcontext_struct *);
|
||||
extern int do_int31(struct sigcontext_struct *);
|
||||
extern int do_int5c(struct sigcontext_struct *);
|
||||
|
||||
extern void inportb(struct sigcontext_struct *context);
|
||||
extern void inport(struct sigcontext_struct *context);
|
||||
@ -24,6 +28,10 @@ extern void outport_abs(struct sigcontext_struct *context);
|
||||
|
||||
extern void IntBarf(int i, struct sigcontext_struct *context);
|
||||
|
||||
extern BOOL INT_Init(void);
|
||||
extern SEGPTR INT_GetHandler( BYTE intnum );
|
||||
extern void INT_SetHandler( BYTE intnum, SEGPTR handler );
|
||||
|
||||
extern void INT21_Init(void);
|
||||
|
||||
#endif /* __WINE_MISCEMU_H */
|
||||
|
@ -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();
|
||||
|
||||
|
166
loader/module.c
166
loader/module.c
@ -292,7 +292,7 @@ int MODULE_OpenFile( HMODULE hModule )
|
||||
/***********************************************************************
|
||||
* MODULE_CreateSegments
|
||||
*/
|
||||
BOOL MODULE_CreateSegments( HMODULE hModule )
|
||||
static BOOL MODULE_CreateSegments( HMODULE hModule )
|
||||
{
|
||||
SEGTABLEENTRY *pSegment;
|
||||
NE_MODULE *pModule;
|
||||
@ -308,9 +308,8 @@ BOOL MODULE_CreateSegments( HMODULE hModule )
|
||||
{
|
||||
/* FIXME: this is needed because heap growing is not implemented */
|
||||
pModule->heap_size = 0x10000 - minsize;
|
||||
/* For tasks, the DGROUP is allocated by MODULE_MakeNewInstance */
|
||||
minsize = 0x10000;
|
||||
if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) continue;
|
||||
/* The DGROUP is allocated by MODULE_CreateInstance */
|
||||
continue;
|
||||
}
|
||||
pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
|
||||
minsize, hModule,
|
||||
@ -326,6 +325,57 @@ BOOL MODULE_CreateSegments( HMODULE hModule )
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_GetInstance
|
||||
*/
|
||||
static HINSTANCE MODULE_GetInstance( HMODULE hModule )
|
||||
{
|
||||
SEGTABLEENTRY *pSegment;
|
||||
NE_MODULE *pModule;
|
||||
|
||||
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
|
||||
if (pModule->dgroup == 0) return hModule;
|
||||
|
||||
pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
|
||||
|
||||
return pSegment->selector;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_CreateInstance
|
||||
*/
|
||||
static HINSTANCE MODULE_CreateInstance( HMODULE hModule, LOADPARAMS *params )
|
||||
{
|
||||
SEGTABLEENTRY *pSegment;
|
||||
NE_MODULE *pModule;
|
||||
int minsize;
|
||||
HINSTANCE hNewInstance, hPrevInstance;
|
||||
|
||||
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
|
||||
if (pModule->dgroup == 0) return hModule;
|
||||
|
||||
pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
|
||||
hPrevInstance = pSegment->selector;
|
||||
|
||||
/* if it's a library, create a new instance only the first time */
|
||||
if (hPrevInstance)
|
||||
{
|
||||
if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
|
||||
if (params == (LOADPARAMS*)-1) return hPrevInstance;
|
||||
}
|
||||
|
||||
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
|
||||
if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
|
||||
minsize += pModule->heap_size;
|
||||
hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
|
||||
minsize, hModule, FALSE, FALSE, FALSE );
|
||||
if (!hNewInstance) return 0;
|
||||
pSegment->selector = hNewInstance;
|
||||
return hNewInstance;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_LoadExeHeader
|
||||
*/
|
||||
@ -517,62 +567,6 @@ HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_MakeNewInstance
|
||||
*
|
||||
* Create a new instance of the specified module.
|
||||
*/
|
||||
HINSTANCE MODULE_MakeNewInstance( HMODULE hModule, LOADPARAMS *params )
|
||||
{
|
||||
NE_MODULE *pModule;
|
||||
SEGTABLEENTRY *pSegment;
|
||||
HINSTANCE hNewInstance, hPrevInstance;
|
||||
int minsize;
|
||||
|
||||
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
|
||||
if (!pModule->dgroup) return hModule; /* No DGROUP -> return the module */
|
||||
|
||||
pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
|
||||
hPrevInstance = pSegment->selector;
|
||||
|
||||
/* Don't create a new instance if it's a library */
|
||||
|
||||
if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
|
||||
if (params == (LOADPARAMS*)-1) return hPrevInstance;
|
||||
|
||||
/* Allocate the new data segment */
|
||||
|
||||
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
|
||||
if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
|
||||
minsize += pModule->heap_size;
|
||||
hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
|
||||
minsize, hModule, FALSE, FALSE, FALSE );
|
||||
if (!hNewInstance) return 0;
|
||||
pSegment->selector = hNewInstance;
|
||||
NE_LoadSegment( hModule, pModule->dgroup );
|
||||
|
||||
/* Create a new task for this instance */
|
||||
if (!TASK_CreateTask( hModule, hNewInstance, hPrevInstance,
|
||||
params->hEnvironment,
|
||||
(LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
|
||||
*((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) ))
|
||||
{
|
||||
GlobalFree( hNewInstance );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize the local heap */
|
||||
|
||||
if (pModule->heap_size)
|
||||
{
|
||||
WORD heapstart = pSegment->minsize;
|
||||
if (pModule->ss == pModule->dgroup) heapstart += pModule->stack_size;
|
||||
LocalInit( hNewInstance, heapstart, heapstart + pModule->heap_size );
|
||||
}
|
||||
return hNewInstance;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MODULE_GetOrdinal
|
||||
*
|
||||
@ -800,6 +794,7 @@ HMODULE MODULE_FindModule( LPCSTR path )
|
||||
BYTE len, *name_table;
|
||||
|
||||
if (!(filename = strrchr( path, '\\' ))) filename = path;
|
||||
else filename++;
|
||||
if ((dotptr = strrchr( filename, '.' )) != NULL)
|
||||
len = (BYTE)(dotptr - filename);
|
||||
else len = strlen( filename );
|
||||
@ -811,6 +806,7 @@ HMODULE MODULE_FindModule( LPCSTR path )
|
||||
modulepath = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
|
||||
if (!(modulename = strrchr( modulepath, '\\' )))
|
||||
modulename = modulepath;
|
||||
else modulename++;
|
||||
if (!strcasecmp( modulename, filename )) return hModule;
|
||||
|
||||
name_table = (BYTE *)pModule + pModule->name_table;
|
||||
@ -878,8 +874,9 @@ static void MODULE_FreeModule( HMODULE hModule )
|
||||
HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
|
||||
{
|
||||
HMODULE hModule;
|
||||
HANDLE hInstance;
|
||||
HANDLE hInstance, hPrevInstance;
|
||||
NE_MODULE *pModule;
|
||||
LOADPARAMS *params = (LOADPARAMS *)paramBlock;
|
||||
WORD *pModRef, *pDLLs;
|
||||
int i, fd;
|
||||
|
||||
@ -906,6 +903,9 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
|
||||
|
||||
MODULE_CreateSegments( hModule );
|
||||
|
||||
hPrevInstance = 0;
|
||||
hInstance = MODULE_CreateInstance( hModule, (LOADPARAMS*)paramBlock );
|
||||
|
||||
/* Load the referenced DLLs */
|
||||
|
||||
pModRef = (WORD *)((char *)pModule + pModule->modref_table);
|
||||
@ -950,14 +950,9 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the segments (except the DGROUP) */
|
||||
/* Load the segments */
|
||||
|
||||
for (i = 1; i <= pModule->seg_count; i++)
|
||||
if (i != pModule->dgroup) NE_LoadSegment( hModule, i );
|
||||
|
||||
/* Create an instance for this module */
|
||||
|
||||
hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
|
||||
for (i = 1; i <= pModule->seg_count; i++) NE_LoadSegment( hModule, i );
|
||||
|
||||
/* Fixup the functions prologs */
|
||||
|
||||
@ -971,10 +966,23 @@ 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
|
||||
|
120
loader/signal.c
120
loader/signal.c
@ -18,6 +18,7 @@
|
||||
#include "dos_fs.h"
|
||||
#include "prototypes.h"
|
||||
#include "miscemu.h"
|
||||
#include "registers.h"
|
||||
#include "win.h"
|
||||
|
||||
#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
|
||||
@ -44,57 +45,59 @@ wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_int(int intnum, struct sigcontext_struct *scp)
|
||||
int do_int(int intnum, struct sigcontext_struct *context)
|
||||
{
|
||||
switch(intnum)
|
||||
{
|
||||
case 0x10: return do_int10(scp);
|
||||
case 0x10: return do_int10(context);
|
||||
|
||||
case 0x11:
|
||||
scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
|
||||
AX = DOS_GetEquipment();
|
||||
return 1;
|
||||
|
||||
case 0x12:
|
||||
scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
|
||||
AX = 640;
|
||||
return 1; /* get base mem size */
|
||||
|
||||
case 0x13: return do_int13(scp);
|
||||
case 0x15: return do_int15(scp);
|
||||
case 0x16: return do_int16(scp);
|
||||
case 0x1a: return do_int1a(scp);
|
||||
case 0x21: return do_int21(scp);
|
||||
case 0x13: return do_int13(context);
|
||||
case 0x15: return do_int15(context);
|
||||
case 0x16: return do_int16(context);
|
||||
case 0x1a: return do_int1a(context);
|
||||
case 0x21: return do_int21(context);
|
||||
|
||||
case 0x22:
|
||||
scp->sc_eax = 0x1234;
|
||||
scp->sc_ebx = 0x5678;
|
||||
scp->sc_ecx = 0x9abc;
|
||||
scp->sc_edx = 0xdef0;
|
||||
AX = 0x1234;
|
||||
BX = 0x5678;
|
||||
CX = 0x9abc;
|
||||
DX = 0xdef0;
|
||||
return 1;
|
||||
|
||||
case 0x25: return do_int25(scp);
|
||||
case 0x26: return do_int26(scp);
|
||||
case 0x2a: return do_int2a(scp);
|
||||
case 0x2f: return do_int2f(scp);
|
||||
case 0x31: return do_int31(scp);
|
||||
case 0x25: return do_int25(context);
|
||||
case 0x26: return do_int26(context);
|
||||
case 0x2a: return do_int2a(context);
|
||||
case 0x2f: return do_int2f(context);
|
||||
case 0x31: return do_int31(context);
|
||||
case 0x5c: return do_int5c(context);
|
||||
|
||||
default:
|
||||
printf("int%02x: Unimplemented!\n", intnum);
|
||||
fprintf(stderr,"int%02x: Unimplemented!\n", intnum);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef linux
|
||||
static void win_fault(int signal, struct sigcontext_struct context)
|
||||
static void win_fault(int signal, struct sigcontext_struct context_struct)
|
||||
{
|
||||
struct sigcontext_struct *scp = &context;
|
||||
struct sigcontext_struct *context = &context_struct;
|
||||
#else
|
||||
static void win_fault(int signal, int code, struct sigcontext *scp)
|
||||
static void win_fault(int signal, int code, struct sigcontext *context)
|
||||
{
|
||||
#endif
|
||||
unsigned char * instr;
|
||||
WORD *stack;
|
||||
#if !(defined (linux) || defined (__NetBSD__))
|
||||
int i, *dump;
|
||||
int i, *dump;
|
||||
#endif
|
||||
|
||||
/* First take care of a few preliminaries */
|
||||
@ -112,7 +115,7 @@ static void win_fault(int signal, int code, struct sigcontext *scp)
|
||||
|
||||
/* And back up over the int3 instruction. */
|
||||
if(signal == SIGTRAP) {
|
||||
scp->sc_eip--;
|
||||
EIP--;
|
||||
goto oops;
|
||||
}
|
||||
#endif
|
||||
@ -126,76 +129,83 @@ static void win_fault(int signal, int code, struct sigcontext *scp)
|
||||
if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
|
||||
exit(1);
|
||||
#endif
|
||||
if (scp->sc_cs == WINE_CODE_SELECTOR)
|
||||
if (CS == WINE_CODE_SELECTOR)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Segmentation fault in Wine program (%x:%lx)."
|
||||
" Please debug\n",
|
||||
scp->sc_cs, scp->sc_eip);
|
||||
" Please debug\n", CS, EIP );
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* Now take a look at the actual instruction where the program
|
||||
bombed */
|
||||
instr = (unsigned char *) PTR_SEG_OFF_TO_LIN(scp->sc_cs, scp->sc_eip);
|
||||
instr = (unsigned char *) PTR_SEG_OFF_TO_LIN( CS, EIP );
|
||||
|
||||
switch(*instr)
|
||||
{
|
||||
case 0xcd: /* int <XX> */
|
||||
instr++;
|
||||
if (!do_int(*instr, scp)) {
|
||||
if (!do_int(*instr, context)) {
|
||||
fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
|
||||
goto oops;
|
||||
}
|
||||
scp->sc_eip += 2; /* Bypass the int instruction */
|
||||
EIP += 2; /* Bypass the int instruction */
|
||||
break;
|
||||
|
||||
|
||||
case 0xcf: /* iret */
|
||||
stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
|
||||
EIP = *stack++;
|
||||
CS = *stack++;
|
||||
EFL = *stack;
|
||||
SP += 6; /* Pop the return address and flags */
|
||||
break;
|
||||
|
||||
case 0xe4: /* inb al,XX */
|
||||
inportb_abs(scp);
|
||||
scp->sc_eip += 2;
|
||||
inportb_abs(context);
|
||||
EIP += 2;
|
||||
break;
|
||||
|
||||
case 0xe5: /* in ax,XX */
|
||||
inport_abs(scp);
|
||||
scp->sc_eip += 2;
|
||||
inport_abs(context);
|
||||
EIP += 2;
|
||||
break;
|
||||
|
||||
case 0xe6: /* outb XX,al */
|
||||
outportb_abs(scp);
|
||||
scp->sc_eip += 2;
|
||||
outportb_abs(context);
|
||||
EIP += 2;
|
||||
break;
|
||||
|
||||
case 0xe7: /* out XX,ax */
|
||||
outport_abs(scp);
|
||||
scp->sc_eip += 2;
|
||||
outport_abs(context);
|
||||
EIP += 2;
|
||||
break;
|
||||
|
||||
case 0xec: /* inb al,dx */
|
||||
inportb(scp);
|
||||
scp->sc_eip++;
|
||||
inportb(context);
|
||||
EIP++;
|
||||
break;
|
||||
|
||||
case 0xed: /* in ax,dx */
|
||||
inport(scp);
|
||||
scp->sc_eip++;
|
||||
inport(context);
|
||||
EIP++;
|
||||
break;
|
||||
|
||||
case 0xee: /* outb dx,al */
|
||||
outportb(scp);
|
||||
scp->sc_eip++;
|
||||
outportb(context);
|
||||
EIP++;
|
||||
break;
|
||||
|
||||
case 0xef: /* out dx,ax */
|
||||
outport(scp);
|
||||
scp->sc_eip++;
|
||||
outport(context);
|
||||
EIP++;
|
||||
break;
|
||||
|
||||
case 0xfa: /* cli, ignored */
|
||||
scp->sc_eip++;
|
||||
EIP++;
|
||||
break;
|
||||
|
||||
case 0xfb: /* sti, ignored */
|
||||
scp->sc_eip++;
|
||||
EIP++;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -210,14 +220,14 @@ static void win_fault(int signal, int code, struct sigcontext *scp)
|
||||
|
||||
oops:
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
XUngrabServer(display);
|
||||
XFlush(display);
|
||||
fprintf(stderr,"In win_fault %x:%lx\n", scp->sc_cs, scp->sc_eip);
|
||||
XUngrabServer(display);
|
||||
XFlush(display);
|
||||
fprintf(stderr,"In win_fault %x:%lx\n", CS, EIP );
|
||||
#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
wine_debug(signal, (int *)scp); /* Enter our debugger */
|
||||
wine_debug(signal, (int *)context); /* Enter our debugger */
|
||||
#else
|
||||
fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
|
||||
dump = (int*) scp;
|
||||
fprintf(stderr,"Stack: %x:%x\n", SS, ESP );
|
||||
dump = (int*) context;
|
||||
for(i=0; i<22; i++)
|
||||
{
|
||||
fprintf(stderr," %8.8x", *dump++);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "callback.h"
|
||||
#include "global.h"
|
||||
#include "instance.h"
|
||||
#include "miscemu.h"
|
||||
#include "module.h"
|
||||
#include "neexe.h"
|
||||
#include "selectors.h"
|
||||
@ -31,6 +32,7 @@
|
||||
static HTASK hFirstTask = 0;
|
||||
static HTASK hCurrentTask = 0;
|
||||
static HTASK hTaskToKill = 0;
|
||||
static HTASK hLockedTask = 0;
|
||||
static WORD nTaskCount = 0;
|
||||
|
||||
/* TASK_Reschedule() 16-bit entry point */
|
||||
@ -281,12 +283,11 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
|
||||
/* Fill the PDB */
|
||||
|
||||
pTask->pdb.int20 = 0x20cd;
|
||||
pTask->pdb.dispatcher[0] = 0x9a;
|
||||
pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */
|
||||
*(DWORD *)&pTask->pdb.dispatcher[1] = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 102 ); /* KERNEL.102 is DOS3Call() */
|
||||
pTask->pdb.savedint22 = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"),
|
||||
137 ); /* KERNEL.137 is FatalAppExit() */
|
||||
pTask->pdb.savedint23 = pTask->pdb.savedint22;
|
||||
pTask->pdb.savedint24 = pTask->pdb.savedint22;
|
||||
pTask->pdb.savedint22 = INT_GetHandler( 0x22 );
|
||||
pTask->pdb.savedint23 = INT_GetHandler( 0x23 );
|
||||
pTask->pdb.savedint24 = INT_GetHandler( 0x24 );
|
||||
pTask->pdb.environment = hEnvironment;
|
||||
strncpy( pTask->pdb.cmdLine + 1, cmdLine, 126 );
|
||||
pTask->pdb.cmdLine[127] = '\0';
|
||||
@ -347,8 +348,8 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
|
||||
frame16->saved_sp = pTask->sp;
|
||||
frame16->ds = pTask->hInstance;
|
||||
frame16->entry_point = 0;
|
||||
frame16->ordinal_number = 1;
|
||||
frame16->dll_id = 1;
|
||||
frame16->ordinal_number = 24; /* WINPROCS.24 is TASK_Reschedule */
|
||||
frame16->dll_id = 24; /* WINPROCS */
|
||||
frame16->bp = 0;
|
||||
frame16->ip = LOWORD( CALL16_RetAddr_word );
|
||||
frame16->cs = HIWORD( CALL16_RetAddr_word );
|
||||
@ -431,6 +432,7 @@ void TASK_KillCurrentTask( int exitCode )
|
||||
TASK_UnlinkTask( hCurrentTask );
|
||||
|
||||
hTaskToKill = hCurrentTask;
|
||||
hLockedTask = 0;
|
||||
Yield();
|
||||
/* We never return from Yield() */
|
||||
}
|
||||
@ -454,6 +456,10 @@ void TASK_Reschedule(void)
|
||||
if (hTaskToKill && (hTaskToKill != hCurrentTask))
|
||||
TASK_DeleteTask( hTaskToKill );
|
||||
|
||||
/* If current task is locked, simply return */
|
||||
|
||||
if (hLockedTask) return;
|
||||
|
||||
/* Find a task to yield to */
|
||||
|
||||
pOldTask = (TDB *)GlobalLock( hCurrentTask );
|
||||
@ -496,6 +502,7 @@ void TASK_Reschedule(void)
|
||||
pOldTask->sp = IF1632_Saved16_sp;
|
||||
pOldTask->esp = IF1632_Saved32_esp;
|
||||
}
|
||||
else IF1632_Original32_esp = IF1632_Saved32_esp;
|
||||
|
||||
/* Make the task the last in the linked list (round-robin scheduling) */
|
||||
|
||||
@ -519,6 +526,7 @@ void TASK_Reschedule(void)
|
||||
*/
|
||||
void InitTask( struct sigcontext_struct context )
|
||||
{
|
||||
static int firstTask = 1;
|
||||
TDB *pTask;
|
||||
NE_MODULE *pModule;
|
||||
|
||||
@ -526,6 +534,22 @@ void InitTask( struct sigcontext_struct context )
|
||||
if (!(pTask = (TDB *)GlobalLock( hCurrentTask ))) return;
|
||||
if (!(pModule = (NE_MODULE *)GlobalLock( pTask->hModule ))) return;
|
||||
|
||||
if (firstTask)
|
||||
{
|
||||
extern BOOL WIDGETS_Init(void);
|
||||
extern BOOL WIN_CreateDesktopWindow(void);
|
||||
|
||||
/* Perform global initialisations that need a task context */
|
||||
|
||||
/* Initialize built-in window classes */
|
||||
if (!WIDGETS_Init()) return;
|
||||
|
||||
/* Create desktop window */
|
||||
if (!WIN_CreateDesktopWindow()) return;
|
||||
|
||||
firstTask = 0;
|
||||
}
|
||||
|
||||
NE_InitializeDLLs( pTask->hModule );
|
||||
|
||||
/* Registers on return are:
|
||||
@ -601,6 +625,26 @@ void SetPriority( HTASK hTask, int delta )
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* LockCurrentTask (KERNEL.33)
|
||||
*/
|
||||
HTASK LockCurrentTask( BOOL bLock )
|
||||
{
|
||||
if (bLock) hLockedTask = hCurrentTask;
|
||||
else hLockedTask = 0;
|
||||
return hLockedTask;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* IsTaskLocked (KERNEL.122)
|
||||
*/
|
||||
WORD IsTaskLocked(void)
|
||||
{
|
||||
return hLockedTask;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OldYield (KERNEL.117)
|
||||
*/
|
||||
@ -746,6 +790,19 @@ WORD GetCurrentPDB(void)
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetInstanceData (KERNEL.54)
|
||||
*/
|
||||
int GetInstanceData( HANDLE instance, WORD buffer, int len )
|
||||
{
|
||||
char *ptr = (char *)GlobalLock( instance );
|
||||
if (!ptr || !len) return 0;
|
||||
if ((int)buffer + len >= 0x10000) len = 0x10000 - buffer;
|
||||
memcpy( ptr + buffer, (char *)GlobalLock( CURRENT_DS ) + buffer, len );
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetNumTasks (KERNEL.152)
|
||||
*/
|
||||
|
@ -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;
|
||||
|
||||
|
388
memory/local.c
388
memory/local.c
@ -17,6 +17,7 @@
|
||||
#include "ldt.h"
|
||||
#include "instance.h"
|
||||
#include "local.h"
|
||||
#include "module.h"
|
||||
#include "stackframe.h"
|
||||
#include "toolhelp.h"
|
||||
#include "stddebug.h"
|
||||
@ -39,13 +40,15 @@ typedef struct
|
||||
} LOCALARENA;
|
||||
|
||||
#define ARENA_HEADER_SIZE 4
|
||||
#define ARENA_HEADER( handle) ( ((handle) & ~3) - ARENA_HEADER_SIZE)
|
||||
|
||||
/* Arena types (stored in 'prev' field of the arena) */
|
||||
#define LOCAL_ARENA_FREE 0
|
||||
#define LOCAL_ARENA_FIXED 1
|
||||
#define LOCAL_ARENA_MOVEABLE 3
|
||||
|
||||
|
||||
#define LMEM_NOCOMPACT 0x0010
|
||||
#define LMEM_NODISCARD 0x0020
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -93,6 +96,9 @@ typedef struct
|
||||
#define ARENA_NEXT(ptr,arena) (ARENA_PTR(ptr,arena)->next)
|
||||
#define ARENA_FLAGS(ptr,arena) (ARENA_PTR(ptr,arena)->prev & 3)
|
||||
|
||||
/* determine whether the handle belongs to a fixed or a moveable block */
|
||||
#define HANDLE_FIXED(handle) (((handle) & 3) == 0)
|
||||
#define HANDLE_MOVEABLE(handle) (((handle) & 3) == 2)
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_GetHeap
|
||||
@ -103,6 +109,7 @@ static LOCALHEAPINFO *LOCAL_GetHeap( WORD ds )
|
||||
{
|
||||
LOCALHEAPINFO *pInfo;
|
||||
INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
dprintf_local( stddeb, "Heap at %04x\n", ptr->heap );
|
||||
if (!ptr->heap) return 0;
|
||||
pInfo = (LOCALHEAPINFO*)((char*)ptr + ptr->heap);
|
||||
if (pInfo->magic != LOCAL_HEAP_MAGIC) return NULL;
|
||||
@ -138,6 +145,7 @@ static void LOCAL_AddFreeBlock( char *baseptr, WORD block )
|
||||
next = pNext->next;
|
||||
}
|
||||
|
||||
dprintf_local( stddeb, "Local_AddFreeBlock %04x, next %04x\n", block, next );
|
||||
/* Insert the free block in the free-list */
|
||||
|
||||
pArena->free_prev = pNext->free_prev;
|
||||
@ -202,6 +210,7 @@ static void LOCAL_RemoveBlock( char *baseptr, WORD block )
|
||||
|
||||
/* Remove the block from the free-list */
|
||||
|
||||
dprintf_local( stddeb, "Local_RemoveBlock\n");
|
||||
pArena = ARENA_PTR( baseptr, block );
|
||||
if ((pArena->prev & 3) == LOCAL_ARENA_FREE)
|
||||
LOCAL_RemoveFreeBlock( baseptr, block );
|
||||
@ -229,6 +238,7 @@ static void LOCAL_PrintHeap( WORD ds )
|
||||
LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
|
||||
WORD arena;
|
||||
|
||||
if (!debugging_local) return;
|
||||
if (!pInfo)
|
||||
{
|
||||
printf( "Local Heap corrupted! ds=%04x\n", ds );
|
||||
@ -266,7 +276,8 @@ static void LOCAL_PrintHeap( WORD ds )
|
||||
}
|
||||
if ((ARENA_PTR(ptr,pArena->next)->prev & ~3) != arena)
|
||||
{
|
||||
printf( "*** arena->next->prev != arena\n" );
|
||||
printf( "*** arena->next->prev != arena (%04x, %04x)\n",
|
||||
pArena->next, ARENA_PTR(ptr,pArena->next)->prev);
|
||||
break;
|
||||
}
|
||||
arena = pArena->next;
|
||||
@ -283,7 +294,8 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end )
|
||||
WORD heapInfoArena, freeArena, lastArena;
|
||||
LOCALHEAPINFO *pHeapInfo;
|
||||
LOCALARENA *pArena, *pFirstArena, *pLastArena;
|
||||
|
||||
NE_MODULE *pModule;
|
||||
|
||||
/* The initial layout of the heap is: */
|
||||
/* - first arena (FIXED) */
|
||||
/* - heap info structure (FIXED) */
|
||||
@ -295,14 +307,24 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end )
|
||||
ptr = PTR_SEG_OFF_TO_LIN( selector, 0 );
|
||||
pHeapInfo = LOCAL_GetHeap(selector);
|
||||
/* If there's already a local heap in this segment, */
|
||||
/* we simply return TRUE. Helps some programs, but */
|
||||
/* does not seem to be 100% correct yet (there are */
|
||||
/* still some "heap corrupted" messages in LocalAlloc */
|
||||
/* we simply return TRUE. This helps some programs. */
|
||||
if (pHeapInfo) {
|
||||
dprintf_local(stddeb,"LocalInit: Heap %04x initialized twice.\n",selector);
|
||||
if (debugging_local) LOCAL_PrintHeap(selector);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Check if the segment is the DGROUP of a module */
|
||||
|
||||
if ((pModule = (NE_MODULE *)GlobalLock( GetExePtr( selector ) )))
|
||||
{
|
||||
SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
|
||||
if (pModule->dgroup && (pSeg->selector == selector))
|
||||
start = max( start, pSeg->minsize );
|
||||
}
|
||||
#endif
|
||||
|
||||
start = LALIGN( max( start, sizeof(INSTANCEDATA) ) );
|
||||
heapInfoArena = LALIGN(start + sizeof(LOCALARENA) );
|
||||
freeArena = LALIGN( heapInfoArena + ARENA_HEADER_SIZE
|
||||
@ -335,6 +357,7 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end )
|
||||
pHeapInfo->items = 4;
|
||||
pHeapInfo->first = start;
|
||||
pHeapInfo->last = lastArena;
|
||||
pHeapInfo->htable = 0;
|
||||
pHeapInfo->hdelta = 0x20;
|
||||
pHeapInfo->extra = 0x200;
|
||||
pHeapInfo->minsize = lastArena - freeArena;
|
||||
@ -352,7 +375,7 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end )
|
||||
/* Initialise the last block */
|
||||
|
||||
pLastArena = ARENA_PTR( ptr, lastArena );
|
||||
pLastArena->prev = heapInfoArena | LOCAL_ARENA_FREE;
|
||||
pLastArena->prev = freeArena | LOCAL_ARENA_FREE;
|
||||
pLastArena->next = lastArena; /* this one */
|
||||
pLastArena->size = LALIGN(sizeof(LOCALARENA));
|
||||
pLastArena->free_prev = freeArena;
|
||||
@ -361,49 +384,80 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end )
|
||||
/* Store the local heap address in the instance data */
|
||||
|
||||
((INSTANCEDATA *)ptr)->heap = heapInfoArena + ARENA_HEADER_SIZE;
|
||||
LOCAL_PrintHeap( selector );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_Compact
|
||||
*/
|
||||
static WORD LOCAL_Compact( WORD ds, WORD minfree, WORD flags )
|
||||
{
|
||||
if (flags & LMEM_NOCOMPACT) return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_Alloc
|
||||
*
|
||||
* Implementation of LocalAlloc().
|
||||
* LOCAL_FindFreeBlock
|
||||
*/
|
||||
HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size )
|
||||
static HLOCAL LOCAL_FindFreeBlock( WORD ds, WORD size )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
LOCALHEAPINFO *pInfo;
|
||||
LOCALARENA *pArena;
|
||||
WORD arena;
|
||||
|
||||
dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
|
||||
|
||||
/* Find a suitable free block */
|
||||
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) {
|
||||
dprintf_local( stddeb, "LocalAlloc: Heap not found\n");
|
||||
LOCAL_PrintHeap(ds);
|
||||
return 0;
|
||||
dprintf_local( stddeb, "Local_FindFreeBlock: Local heap not found\n" );
|
||||
LOCAL_PrintHeap(ds);
|
||||
return 0;
|
||||
}
|
||||
size += ARENA_HEADER_SIZE;
|
||||
size = LALIGN( max( size, sizeof(LOCALARENA) ) );
|
||||
|
||||
arena = pInfo->first;
|
||||
pArena = ARENA_PTR( ptr, arena );
|
||||
for (;;)
|
||||
{
|
||||
if (arena == pArena->free_next) {
|
||||
fprintf(stderr, "Local heap full\n");
|
||||
if (debugging_local) LOCAL_PrintHeap(ds);
|
||||
return 0; /* not found */
|
||||
}
|
||||
while (arena != pArena->free_next) {
|
||||
arena = pArena->free_next;
|
||||
pArena = ARENA_PTR( ptr, arena );
|
||||
if (pArena->size >= size) break;
|
||||
if (pArena->size >= size) return arena;
|
||||
}
|
||||
dprintf_local( stddeb, "Local_FindFreeBlock: not enough space\n" );
|
||||
if (debugging_local) LOCAL_PrintHeap(ds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_GetBlock
|
||||
*/
|
||||
static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
LOCALHEAPINFO *pInfo;
|
||||
LOCALARENA *pArena;
|
||||
WORD arena;
|
||||
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) {
|
||||
dprintf_local( stddeb, "Local_GetBlock: Local heap not found\n");
|
||||
LOCAL_PrintHeap(ds);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size += ARENA_HEADER_SIZE;
|
||||
size = LALIGN( max( size, sizeof(LOCALARENA) ) );
|
||||
|
||||
/* Find a suitable free block */
|
||||
arena = LOCAL_FindFreeBlock( ds, size );
|
||||
if (arena == 0) {
|
||||
LOCAL_Compact( ds, size, flags );
|
||||
arena = LOCAL_FindFreeBlock( ds, size );
|
||||
}
|
||||
if (arena == 0) {
|
||||
fprintf( stderr, "Local_GetBlock: not enough space!\n" );
|
||||
}
|
||||
|
||||
dprintf_local( stddeb, "LOCAL_GetBlock size = %04x\n", size );
|
||||
/* Make a block out of the free arena */
|
||||
|
||||
pArena = ARENA_PTR( ptr, arena );
|
||||
if (pArena->size > size + LALIGN(sizeof(LOCALARENA)))
|
||||
{
|
||||
LOCAL_AddBlock( ptr, arena, arena+size );
|
||||
@ -412,97 +466,78 @@ 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_ReAlloc
|
||||
*
|
||||
* Implementation of LocalReAlloc().
|
||||
* LOCAL_NewHTable
|
||||
*/
|
||||
HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags )
|
||||
static BOOL LOCAL_NewHTable( WORD ds )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
LOCALHEAPINFO *pInfo;
|
||||
LOCALARENA *pArena, *pNext;
|
||||
WORD arena, newhandle;
|
||||
HLOCAL handle;
|
||||
|
||||
dprintf_local( stddeb, "LocalReAlloc: %04x %d %04x ds=%04x\n",
|
||||
handle, size, flags, ds );
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
|
||||
arena = handle - ARENA_HEADER_SIZE;
|
||||
pArena = ARENA_PTR( ptr, arena );
|
||||
if (flags & LMEM_MODIFY) {
|
||||
dprintf_local( stddeb, "LMEM_MODIFY set\n");
|
||||
return handle;
|
||||
}
|
||||
if (!size) size = 1;
|
||||
size = LALIGN( size );
|
||||
|
||||
/* Check for size reduction */
|
||||
|
||||
if (size < pArena->next - handle)
|
||||
{
|
||||
if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA)))
|
||||
{
|
||||
/* It is worth making a new free block */
|
||||
LOCAL_AddBlock( ptr, arena, handle + size );
|
||||
LOCAL_AddFreeBlock( ptr, handle + size );
|
||||
pInfo->items++;
|
||||
}
|
||||
dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
|
||||
return handle;
|
||||
dprintf_local( stddeb, "Local_NewHTable\n" );
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) {
|
||||
dprintf_local( stddeb, "Local heap not found\n");
|
||||
LOCAL_PrintHeap(ds);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check if the next block is free */
|
||||
|
||||
pNext = ARENA_PTR( ptr, pArena->next );
|
||||
if (((pNext->prev & 3) == LOCAL_ARENA_FREE) &&
|
||||
(size <= pNext->next - handle))
|
||||
{
|
||||
LOCAL_RemoveBlock( ptr, pArena->next );
|
||||
if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA)))
|
||||
{
|
||||
/* It is worth making a new free block */
|
||||
LOCAL_AddBlock( ptr, arena, handle + size );
|
||||
LOCAL_AddFreeBlock( ptr, handle + size );
|
||||
pInfo->items++;
|
||||
}
|
||||
dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
|
||||
return handle;
|
||||
}
|
||||
|
||||
/* Now we have to allocate a new block */
|
||||
|
||||
newhandle = LOCAL_Alloc( ds, flags, size );
|
||||
if (!newhandle) return 0;
|
||||
memcpy( ptr + newhandle, ptr + handle, pArena->next - handle );
|
||||
LOCAL_Free( ds, handle );
|
||||
dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
|
||||
return newhandle;
|
||||
handle = LOCAL_GetBlock( ds, pInfo->hdelta*4 + 2, LMEM_FIXED );
|
||||
if (handle == 0) return FALSE;
|
||||
*(WORD *)(ptr + handle) = 0; /* no handles in this block yet */
|
||||
pInfo->htable = handle;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_GetNewHandle
|
||||
*/
|
||||
static HLOCAL LOCAL_GetNewHandle( WORD ds )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
LOCALHEAPINFO *pInfo;
|
||||
WORD count;
|
||||
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) {
|
||||
dprintf_local( stddeb, "LOCAL_GetNewHandle: Local heap not found\n");
|
||||
LOCAL_PrintHeap(ds);
|
||||
return 0;
|
||||
}
|
||||
/* Check if we need a new handle table */
|
||||
if (pInfo->htable == 0)
|
||||
if (!LOCAL_NewHTable( ds )) return 0;
|
||||
if (*(WORD *)(ptr + pInfo->htable) == pInfo->hdelta)
|
||||
if (!LOCAL_NewHTable( ds )) return 0;
|
||||
|
||||
/* increase count */
|
||||
count = (*(WORD *)(ptr + pInfo->htable))++;
|
||||
dprintf_local( stddeb, "Local_GetNewHandle: %04x\n", pInfo->htable + 2 + 4*count );
|
||||
return pInfo->htable + 2 + 4*count;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_Free
|
||||
*
|
||||
* Implementation of LocalFree().
|
||||
* LOCAL_FreeArena
|
||||
*/
|
||||
HLOCAL LOCAL_Free( WORD ds, HLOCAL handle )
|
||||
HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
LOCALHEAPINFO *pInfo;
|
||||
LOCALARENA *pArena, *pPrev, *pNext;
|
||||
WORD arena;
|
||||
|
||||
dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds );
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) return handle;
|
||||
arena = handle - ARENA_HEADER_SIZE;
|
||||
dprintf_local( stddeb, "LocalFreeArena: %04x ds=%04x\n", arena, ds );
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) return arena;
|
||||
|
||||
pArena = ARENA_PTR( ptr, arena );
|
||||
if ((pArena->prev & 3) == LOCAL_ARENA_FREE) return handle;
|
||||
if ((pArena->prev & 3) == LOCAL_ARENA_FREE) {
|
||||
/* shouldn't happen */
|
||||
fprintf( stderr, "LocalFreeArena: Trying to free a block twice!\n" );
|
||||
LOCAL_PrintHeap( ds );
|
||||
return arena;
|
||||
}
|
||||
|
||||
/* Check if we can merge with the previous block */
|
||||
|
||||
@ -532,6 +567,153 @@ HLOCAL LOCAL_Free( WORD ds, HLOCAL handle )
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_Free
|
||||
*
|
||||
* Implementation of LocalFree().
|
||||
*/
|
||||
HLOCAL LOCAL_Free( WORD ds, HLOCAL handle )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
WORD arena;
|
||||
|
||||
dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds );
|
||||
|
||||
if (HANDLE_FIXED( handle )) {
|
||||
arena = ARENA_HEADER( handle );
|
||||
} else {
|
||||
arena = ARENA_HEADER( *(WORD *)(ptr + handle) );
|
||||
dprintf_local( stddeb, "LocalFree: real block at %04x\n", arena);
|
||||
}
|
||||
arena = LOCAL_FreeArena( ds, arena );
|
||||
if (arena != 0) return handle; /* couldn't free it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_Alloc
|
||||
*
|
||||
* Implementation of LocalAlloc().
|
||||
*/
|
||||
HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
HLOCAL handle;
|
||||
|
||||
dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
|
||||
|
||||
if (flags & LMEM_MOVEABLE) {
|
||||
LOCALHANDLEENTRY *plhe;
|
||||
HLOCAL hmem;
|
||||
|
||||
hmem = LOCAL_GetBlock( ds, size + 2, flags );
|
||||
if (hmem == 0) return 0;
|
||||
handle = LOCAL_GetNewHandle( ds );
|
||||
if (handle == 0) {
|
||||
fprintf( stderr, "LocalAlloc: couldn't get handle\n");
|
||||
LOCAL_FreeArena( ds, ARENA_HEADER(hmem) );
|
||||
return 0;
|
||||
}
|
||||
*(WORD *)(ptr + hmem) = handle;
|
||||
plhe = (LOCALHANDLEENTRY *)(ptr + handle);
|
||||
plhe->addr = hmem + 2;
|
||||
plhe->lock = 0;
|
||||
} else {
|
||||
handle = LOCAL_GetBlock( ds, size, flags );
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_ReAlloc
|
||||
*
|
||||
* Implementation of LocalReAlloc().
|
||||
*/
|
||||
HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags )
|
||||
{
|
||||
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
|
||||
LOCALHEAPINFO *pInfo;
|
||||
LOCALARENA *pArena, *pNext;
|
||||
WORD arena, newhandle, blockhandle, nextarena;
|
||||
|
||||
dprintf_local( stddeb, "LocalReAlloc: %04x %d %04x ds=%04x\n",
|
||||
handle, size, flags, ds );
|
||||
if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
|
||||
|
||||
if (HANDLE_FIXED( handle )) {
|
||||
blockhandle = handle;
|
||||
} else {
|
||||
size += 2;
|
||||
blockhandle = *(WORD *)(ptr + handle);
|
||||
dprintf_local( stddeb, " blockhandle %04x (%04x)\n", blockhandle,
|
||||
*(WORD *)(ptr + blockhandle - 2));
|
||||
}
|
||||
arena = ARENA_HEADER( blockhandle );
|
||||
dprintf_local( stddeb, "LocalReAlloc: arena is %04x\n", arena );
|
||||
pArena = ARENA_PTR( ptr, arena );
|
||||
|
||||
if (flags & LMEM_MODIFY) {
|
||||
dprintf_local( stddeb, "LMEM_MODIFY set\n");
|
||||
return handle;
|
||||
}
|
||||
if (!size) size = 1;
|
||||
size = LALIGN( size );
|
||||
nextarena = LALIGN(blockhandle + size);
|
||||
|
||||
/* Check for size reduction */
|
||||
|
||||
if (nextarena < pArena->next)
|
||||
{
|
||||
if (nextarena < pArena->next - LALIGN(sizeof(LOCALARENA)))
|
||||
{
|
||||
dprintf_local( stddeb, "size reduction, making new free block\n");
|
||||
/* It is worth making a new free block */
|
||||
LOCAL_AddBlock( ptr, arena, nextarena );
|
||||
LOCAL_AddFreeBlock( ptr, nextarena );
|
||||
pInfo->items++;
|
||||
}
|
||||
dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
|
||||
return handle;
|
||||
}
|
||||
|
||||
/* Check if the next block is free */
|
||||
|
||||
pNext = ARENA_PTR( ptr, pArena->next );
|
||||
if (((pNext->prev & 3) == LOCAL_ARENA_FREE) &&
|
||||
(nextarena <= pNext->next))
|
||||
{
|
||||
LOCAL_RemoveBlock( ptr, pArena->next );
|
||||
if (nextarena < pArena->next - LALIGN(sizeof(LOCALARENA)))
|
||||
{
|
||||
dprintf_local( stddeb, "size increase, making new free block\n");
|
||||
/* It is worth making a new free block */
|
||||
LOCAL_AddBlock( ptr, arena, nextarena );
|
||||
LOCAL_AddFreeBlock( ptr, nextarena );
|
||||
pInfo->items++;
|
||||
}
|
||||
dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
|
||||
return handle;
|
||||
}
|
||||
|
||||
/* Now we have to allocate a new block */
|
||||
|
||||
newhandle = LOCAL_GetBlock( ds, size, flags );
|
||||
if (newhandle == 0) return 0;
|
||||
memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), size );
|
||||
LOCAL_FreeArena( ds, arena );
|
||||
if (HANDLE_MOVEABLE( handle )) {
|
||||
newhandle += 2;
|
||||
dprintf_local( stddeb, "LocalReAlloc: fixing handle\n");
|
||||
*(WORD *)(ptr + handle) = newhandle;
|
||||
newhandle = handle;
|
||||
}
|
||||
dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
|
||||
return newhandle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* LOCAL_Size
|
||||
*
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
935
misc/commdlg.c
935
misc/commdlg.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
|
16
misc/user.c
16
misc/user.c
@ -92,24 +92,8 @@ BOOL USER_HeapInit(void)
|
||||
*/
|
||||
int USER_InitApp(int hInstance)
|
||||
{
|
||||
extern BOOL WIDGETS_Init(void);
|
||||
|
||||
static int firstTask = 1;
|
||||
int queueSize;
|
||||
|
||||
if (firstTask)
|
||||
{
|
||||
/* Perform global initialisations that need a task context */
|
||||
|
||||
/* Initialize built-in window classes */
|
||||
if (!WIDGETS_Init()) return 0;
|
||||
|
||||
/* Create desktop window */
|
||||
if (!WIN_CreateDesktopWindow()) return 0;
|
||||
|
||||
firstTask = 0;
|
||||
}
|
||||
|
||||
/* Create task message queue */
|
||||
queueSize = GetProfileInt( "windows", "DefaultQueueSize", 8 );
|
||||
if (!SetMessageQueue( queueSize )) return 0;
|
||||
|
@ -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 )
|
||||
{
|
||||
|
33
miscemu/int5c.c
Normal file
33
miscemu/int5c.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* NetBIOS interrupt handling
|
||||
*
|
||||
* Copyright 1995 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "miscemu.h"
|
||||
#include "registers.h"
|
||||
#include "wine.h"
|
||||
#include "stddebug.h"
|
||||
/* #define DEBUG_INT */
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* do_int5c
|
||||
*/
|
||||
int do_int5c(struct sigcontext_struct * context)
|
||||
{
|
||||
dprintf_int(stddeb,"NetBiosCall: AX %04x, BX %04x, CX %04x, DX %04x, "
|
||||
"SI %04x, DI %04x, DS %04x, ES %04x\n",
|
||||
AX, BX, CX, DX, SI, DI, DS, ES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* NetBIOSCall (KERNEL.103)
|
||||
*/
|
||||
void NetBIOSCall( struct sigcontext_struct context )
|
||||
{
|
||||
do_int5c( &context );
|
||||
}
|
190
miscemu/interrupts.c
Normal file
190
miscemu/interrupts.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Interrupt vectors emulation
|
||||
*
|
||||
* Copyright 1995 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "windows.h"
|
||||
#include "miscemu.h"
|
||||
#include "module.h"
|
||||
#include "stddebug.h"
|
||||
#include "debug.h"
|
||||
|
||||
static SEGPTR INT_Vectors[256];
|
||||
|
||||
/* Ordinal number for interrupt 0 handler in WINPROCS.DLL */
|
||||
#define FIRST_INTERRUPT_ORDINAL 100
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Init
|
||||
*/
|
||||
BOOL INT_Init(void)
|
||||
{
|
||||
SEGPTR addr, dummyHandler;
|
||||
WORD vector;
|
||||
HMODULE hModule = GetModuleHandle( "WINPROCS" );
|
||||
|
||||
dummyHandler = MODULE_GetEntryPoint( hModule, FIRST_INTERRUPT_ORDINAL+256);
|
||||
for (vector = 0; vector < 256; vector++)
|
||||
{
|
||||
addr = MODULE_GetEntryPoint( hModule, FIRST_INTERRUPT_ORDINAL+vector );
|
||||
INT_Vectors[vector] = addr ? addr : dummyHandler;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_GetHandler
|
||||
*
|
||||
* Return the interrupt vector for a given interrupt.
|
||||
*/
|
||||
SEGPTR INT_GetHandler( BYTE intnum )
|
||||
{
|
||||
dprintf_int( stddeb, "Get interrupt vector %02x -> %04x:%04x\n",
|
||||
intnum, HIWORD(INT_Vectors[intnum]),
|
||||
LOWORD(INT_Vectors[intnum]) );
|
||||
return INT_Vectors[intnum];
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_SetHandler
|
||||
*
|
||||
* Set the interrupt handler for a given interrupt.
|
||||
*/
|
||||
void INT_SetHandler( BYTE intnum, SEGPTR handler )
|
||||
{
|
||||
dprintf_int( stddeb, "Set interrupt vector %02x <- %04x:%04x\n",
|
||||
intnum, HIWORD(handler), LOWORD(handler) );
|
||||
INT_Vectors[intnum] = handler;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_DummyHandler
|
||||
*/
|
||||
void INT_DummyHandler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "Dummy handler called!\n" );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int10Handler
|
||||
*/
|
||||
void INT_Int10Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 10 called indirectly through handler!\n" );
|
||||
do_int10( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int13Handler
|
||||
*/
|
||||
void INT_Int13Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 13 called indirectly through handler!\n" );
|
||||
do_int13( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int15Handler
|
||||
*/
|
||||
void INT_Int15Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 15 called indirectly through handler!\n" );
|
||||
do_int15( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int16Handler
|
||||
*/
|
||||
void INT_Int16Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 16 called indirectly through handler!\n" );
|
||||
do_int16( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int1aHandler
|
||||
*/
|
||||
void INT_Int1aHandler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 1a called indirectly through handler!\n" );
|
||||
do_int1a( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int21Handler
|
||||
*/
|
||||
void INT_Int21Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 21 called indirectly through handler!\n" );
|
||||
do_int21( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int25Handler
|
||||
*/
|
||||
void INT_Int25Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 25 called indirectly through handler!\n" );
|
||||
do_int25( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int26Handler
|
||||
*/
|
||||
void INT_Int26Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 26 called indirectly through handler!\n" );
|
||||
do_int26( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int2aHandler
|
||||
*/
|
||||
void INT_Int2aHandler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 2a called indirectly through handler!\n" );
|
||||
do_int2a( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int2fHandler
|
||||
*/
|
||||
void INT_Int2fHandler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 2f called indirectly through handler!\n" );
|
||||
do_int2f( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int31Handler
|
||||
*/
|
||||
void INT_Int31Handler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 31 called indirectly through handler!\n" );
|
||||
do_int31( &context );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* INT_Int5cHandler
|
||||
*/
|
||||
void INT_Int5cHandler( struct sigcontext_struct context )
|
||||
{
|
||||
dprintf_int( stddeb, "int 5c called indirectly through handler!\n" );
|
||||
do_int5c( &context );
|
||||
}
|
@ -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,10 +80,43 @@ 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 );
|
||||
BITMAPOBJ * bmpObjPtr;
|
||||
HBITMAP hbitmap;
|
||||
|
||||
dprintf_gdi( stddeb, "CreateBitmap: %dx%d, %d colors\n",
|
||||
width, height, 1 << (planes*bpp) );
|
||||
|
||||
/* Check parameters */
|
||||
if (!height || !width || planes != 1) return 0;
|
||||
if ((bpp != 1) && (bpp != screenDepth)) return 0;
|
||||
if (height < 0) height = -height;
|
||||
if (width < 0) width = -width;
|
||||
|
||||
/* Create the BITMAPOBJ */
|
||||
hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
|
||||
if (!hbitmap) return 0;
|
||||
bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
|
||||
|
||||
bmpObjPtr->size.cx = 0;
|
||||
bmpObjPtr->size.cy = 0;
|
||||
bmpObjPtr->bitmap.bmType = 0;
|
||||
bmpObjPtr->bitmap.bmWidth = width;
|
||||
bmpObjPtr->bitmap.bmHeight = height;
|
||||
bmpObjPtr->bitmap.bmPlanes = planes;
|
||||
bmpObjPtr->bitmap.bmBitsPixel = bpp;
|
||||
bmpObjPtr->bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2;
|
||||
bmpObjPtr->bitmap.bmBits = NULL;
|
||||
|
||||
/* Create the pixmap */
|
||||
bmpObjPtr->pixmap = XCreatePixmap(display, rootWindow, width, height, bpp);
|
||||
if (!bmpObjPtr->pixmap)
|
||||
{
|
||||
GDI_HEAP_FREE( hbitmap );
|
||||
hbitmap = 0;
|
||||
}
|
||||
else if (bits) /* Set bitmap bits */
|
||||
SetBitmapBits( hbitmap, height * bmpObjPtr->bitmap.bmWidthBytes, bits);
|
||||
return hbitmap;
|
||||
}
|
||||
|
||||
|
||||
@ -106,43 +138,8 @@ HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height )
|
||||
*/
|
||||
HBITMAP CreateBitmapIndirect( BITMAP * bmp )
|
||||
{
|
||||
BITMAPOBJ * bmpObjPtr;
|
||||
HBITMAP hbitmap;
|
||||
|
||||
/* Check parameters */
|
||||
if (!bmp->bmHeight || !bmp->bmWidth) return 0;
|
||||
if (bmp->bmPlanes != 1) return 0;
|
||||
if ((bmp->bmBitsPixel != 1) && (bmp->bmBitsPixel != screenDepth)) return 0;
|
||||
|
||||
if (bmp->bmHeight < 0)
|
||||
bmp->bmHeight = -bmp->bmHeight;
|
||||
|
||||
if (bmp->bmWidth < 0)
|
||||
bmp->bmWidth = -bmp->bmWidth;
|
||||
|
||||
|
||||
/* Create the BITMAPOBJ */
|
||||
hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
|
||||
if (!hbitmap) return 0;
|
||||
bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
|
||||
|
||||
bmpObjPtr->size.cx = 0;
|
||||
bmpObjPtr->size.cy = 0;
|
||||
bmpObjPtr->bitmap = *bmp;
|
||||
bmpObjPtr->bitmap.bmBits = NULL;
|
||||
bmpObjPtr->bitmap.bmWidthBytes = (bmp->bmWidth*bmp->bmBitsPixel+15)/16 * 2;
|
||||
|
||||
/* Create the pixmap */
|
||||
bmpObjPtr->pixmap = XCreatePixmap( display, rootWindow, bmp->bmWidth,
|
||||
bmp->bmHeight, bmp->bmBitsPixel );
|
||||
if (!bmpObjPtr->pixmap)
|
||||
{
|
||||
GDI_HEAP_FREE( hbitmap );
|
||||
hbitmap = 0;
|
||||
}
|
||||
else if (bmp->bmBits) /* Set bitmap bits */
|
||||
SetBitmapBits( hbitmap, bmpObjPtr->bitmap.bmHeight*bmpObjPtr->bitmap.bmWidthBytes, bmp->bmBits );
|
||||
return hbitmap;
|
||||
return CreateBitmap( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
|
||||
bmp->bmBitsPixel, PTR_SEG_TO_LIN( bmp->bmBits ) );
|
||||
}
|
||||
|
||||
|
||||
@ -167,8 +164,9 @@ 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)
|
||||
*/
|
||||
@ -79,14 +81,27 @@ WORD SetPaletteEntries( HPALETTE hpalette, WORD start, WORD count,
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetSystemPaletteUse (GDI.373)
|
||||
* Should this be per DC rather than system wide?
|
||||
* Currently, it does not matter as the use is only set and returned,
|
||||
* but not taken into account
|
||||
*/
|
||||
WORD SetSystemPaletteUse( HDC hdc, WORD use)
|
||||
{
|
||||
WORD old=SystemPaletteUse;
|
||||
printf("SetSystemPaletteUse(%04X,%04X) // empty stub !!!\n", hdc, use);
|
||||
SystemPaletteUse=use;
|
||||
return old;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetSystemPaletteUse (GDI.374)
|
||||
*/
|
||||
WORD GetSystemPaletteUse( HDC hdc )
|
||||
{
|
||||
printf("GetSystemPaletteUse(%04X) // empty stub !!!\n", hdc);
|
||||
/* Assuming there is remaining system colors ... */
|
||||
return SYSPAL_STATIC;
|
||||
return SystemPaletteUse;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
145
tools/build.c
145
tools/build.c
@ -295,12 +295,6 @@ static int ParseExportFunction(int ordinal, int type)
|
||||
}
|
||||
fdp->arg_types[i] = '\0';
|
||||
|
||||
if ((type == TYPE_REGISTER) && (i > 0))
|
||||
{
|
||||
fprintf( stderr, "%d: Register function can't have arguments\n", Line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
strcpy(fdp->internal_name, GetToken());
|
||||
return 0;
|
||||
}
|
||||
@ -945,6 +939,110 @@ static void BuildSpec16Files( char *specname )
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* BuildCall32LargeStack
|
||||
*
|
||||
* Build the function used to switch to the original 32-bit stack
|
||||
* before calling a 32-bit function from 32-bit code. This is used for
|
||||
* functions that need a large stack, like X bitmaps functions.
|
||||
*
|
||||
* The generated function has the following prototype:
|
||||
* int CallTo32_LargeStack( int (*func)(), int nbargs, ... )
|
||||
*
|
||||
* Stack layout:
|
||||
* ... ...
|
||||
* (ebp+20) arg2
|
||||
* (ebp+16) arg1
|
||||
* (ebp+12) nbargs
|
||||
* (ebp+8) func
|
||||
* (ebp+4) ret addr
|
||||
* (ebp) ebp
|
||||
*/
|
||||
static void BuildCall32LargeStack(void)
|
||||
{
|
||||
/* Function header */
|
||||
|
||||
printf( "/**********\n" );
|
||||
printf( " * " PREFIX "CallTo32_LargeStack\n" );
|
||||
printf( " **********/\n" );
|
||||
printf( "\t.align 4\n" );
|
||||
printf( "\t.globl " PREFIX "CallTo32_LargeStack\n\n" );
|
||||
printf( PREFIX "CallTo32_LargeStack:\n" );
|
||||
|
||||
/* Entry code */
|
||||
|
||||
printf( "\tpushl %%ebp\n" );
|
||||
printf( "\tmovl %%esp,%%ebp\n" );
|
||||
|
||||
/* Save registers */
|
||||
|
||||
printf( "\tpushl %%ecx\n" );
|
||||
printf( "\tpushl %%esi\n" );
|
||||
printf( "\tpushl %%edi\n" );
|
||||
|
||||
/* Switch to the new stack (if any) */
|
||||
|
||||
printf( "\tleal 16(%%ebp),%%esi\n" );
|
||||
printf( "\tmovl " PREFIX "IF1632_Original32_esp, %%ecx\n" );
|
||||
printf( "\tjcxz 0f\n" );
|
||||
printf( "\tmovl %%ecx,%%esp\n" );
|
||||
|
||||
/* Transfer the arguments */
|
||||
|
||||
printf( "\tmovl 12(%%ebp),%%ecx\n" );
|
||||
printf( "\tjcxz 1f\n" );
|
||||
printf( "\tshl $2,%%ecx\n" );
|
||||
printf( "\tsubl %%ecx,%%esp\n" );
|
||||
printf( "\tmovl %%esp,%%edi\n" );
|
||||
printf( "\tshr $2,%%ecx\n" );
|
||||
printf( "\trep; movsl\n" );
|
||||
printf( "1:\n" );
|
||||
|
||||
/* Call the function */
|
||||
|
||||
printf( "\tcall 8(%%ebp)\n" );
|
||||
|
||||
/* Switch back to the normal stack */
|
||||
|
||||
printf( "\tleal -12(%%ebp),%%esp\n" );
|
||||
|
||||
/* Restore registers and return */
|
||||
|
||||
printf( "\tpopl %%edi\n" );
|
||||
printf( "\tpopl %%esi\n" );
|
||||
printf( "\tpopl %%ecx\n" );
|
||||
|
||||
printf( "\tpopl %%ebp\n" );
|
||||
printf( "\tret\n" );
|
||||
|
||||
/* We get here if IF1632_Original32_esp is 0, i.e. we have not */
|
||||
/* switched to another 32-bit stack yet. */
|
||||
|
||||
printf( "0:\n" );
|
||||
|
||||
/* Restore the registers */
|
||||
|
||||
printf( "\tpopl %%edi\n" );
|
||||
printf( "\tpopl %%esi\n" );
|
||||
printf( "\tpopl %%ecx\n" );
|
||||
|
||||
/* Move the return address up the stack */
|
||||
|
||||
printf( "\tmovl 4(%%ebp),%%eax\n" );
|
||||
printf( "\tmovl %%eax,12(%%ebp)\n" );
|
||||
|
||||
/* Restore ebp and remove old return address */
|
||||
|
||||
printf( "\tpopl %%ebp\n" );
|
||||
printf( "\taddl $4,%%esp\n" );
|
||||
|
||||
/* Now jump to the routine, leaving the original return address and */
|
||||
/* the arguments on the stack. */
|
||||
|
||||
printf( "\tret\n" );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* TransferArgs16To32
|
||||
*
|
||||
@ -1100,6 +1198,8 @@ static void RestoreContext(void)
|
||||
* profile is: type_xxxxx, where 'type' is one of 'regs', 'word' or
|
||||
* 'long' and each 'x' is an argument ('w'=word, 's'=signed word,
|
||||
* 'l'=long, 'p'=pointer).
|
||||
* For register functions, the arguments are ignored, but they are still
|
||||
* removed from the stack upon return.
|
||||
*
|
||||
* Stack layout upon entry to the callback function:
|
||||
* ... ...
|
||||
@ -1174,20 +1274,16 @@ static void BuildCall32Func( char *profile )
|
||||
|
||||
/* Switch to the 32-bit stack */
|
||||
|
||||
printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebp\n" );
|
||||
printf( "\tpushw %%ds\n" );
|
||||
printf( "\tpopw %%ss\n" );
|
||||
printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" );
|
||||
printf( "\tleal -%d(%%ebp),%%esp\n",
|
||||
reg_func ? sizeof(struct sigcontext_struct) : 4 * strlen(args) );
|
||||
|
||||
/* Setup %ebp to point to the previous stack frame (built by CallTo16) */
|
||||
|
||||
printf( "\tmovl %%esp,%%ebp\n" );
|
||||
printf( "\taddl $24,%%ebp\n" );
|
||||
|
||||
if (reg_func)
|
||||
printf( "\tsubl $%d,%%esp\n", sizeof(struct sigcontext_struct) );
|
||||
else if (*args)
|
||||
printf( "\tsubl $%d,%%esp\n", 4 * strlen(args) );
|
||||
|
||||
/* Call the entry point */
|
||||
|
||||
if (debugging)
|
||||
@ -1226,6 +1322,25 @@ static void BuildCall32Func( char *profile )
|
||||
{
|
||||
/* Restore registers from the context structure */
|
||||
RestoreContext();
|
||||
|
||||
/* Calc the arguments size */
|
||||
while (*args)
|
||||
{
|
||||
switch(*args)
|
||||
{
|
||||
case 'w':
|
||||
case 's':
|
||||
argsize += 2;
|
||||
break;
|
||||
case 'p':
|
||||
case 'l':
|
||||
argsize += 4;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unknown arg type '%c'\n", *args );
|
||||
}
|
||||
args++;
|
||||
}
|
||||
}
|
||||
else /* Store the return value in dx:ax if needed */
|
||||
{
|
||||
@ -1502,6 +1617,10 @@ int main(int argc, char **argv)
|
||||
printf( "/* File generated automatically. Do no edit! */\n\n" );
|
||||
printf( "\t.text\n" );
|
||||
|
||||
/* Build the 32-bit large stack callback */
|
||||
|
||||
BuildCall32LargeStack();
|
||||
|
||||
/* Build the callback functions */
|
||||
|
||||
for (i = 2; i < argc; i++) BuildCall32Func( argv[i] );
|
||||
|
@ -14,6 +14,7 @@
|
||||
#endif
|
||||
#include "dc.h"
|
||||
#include "bitmap.h"
|
||||
#include "callback.h"
|
||||
#include "metafile.h"
|
||||
#include "syscolor.h"
|
||||
#include "stddebug.h"
|
||||
@ -882,14 +883,46 @@ static void GRAPH_InternalFloodFill( XImage *image, DC *dc,
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* GRAPH_DoFloodFill
|
||||
*
|
||||
* Main flood-fill routine.
|
||||
*/
|
||||
static BOOL GRAPH_DoFloodFill( DC *dc, RECT *rect, INT x, INT y,
|
||||
COLORREF color, WORD fillType )
|
||||
{
|
||||
XImage *image;
|
||||
|
||||
if (!(image = XGetImage( display, dc->u.x.drawable,
|
||||
dc->w.DCOrgX + rect->left,
|
||||
dc->w.DCOrgY + rect->top,
|
||||
rect->right - rect->left,
|
||||
rect->bottom - rect->top,
|
||||
AllPlanes, ZPixmap ))) return FALSE;
|
||||
|
||||
if (DC_SetupGCForBrush( dc ))
|
||||
{
|
||||
/* ROP mode is always GXcopy for flood-fill */
|
||||
XSetFunction( display, dc->u.x.gc, GXcopy );
|
||||
GRAPH_InternalFloodFill( image, dc,
|
||||
XLPTODP(dc,x) - rect->left,
|
||||
YLPTODP(dc,y) - rect->top,
|
||||
dc->w.DCOrgX + rect->left,
|
||||
dc->w.DCOrgY + rect->top,
|
||||
COLOR_ToPhysical( dc, color ), fillType );
|
||||
}
|
||||
|
||||
XDestroyImage( image );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* ExtFloodFill (GDI.372)
|
||||
*/
|
||||
BOOL ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, WORD fillType )
|
||||
{
|
||||
RECT rect;
|
||||
Pixel pixel;
|
||||
XImage *image;
|
||||
DC *dc;
|
||||
|
||||
dprintf_graphics( stddeb, "ExtFloodFill %x %d,%d %06lx %d\n",
|
||||
@ -906,28 +939,9 @@ BOOL ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, WORD fillType )
|
||||
|
||||
if (!PtVisible( hdc, x, y )) return FALSE;
|
||||
if (GetRgnBox( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE;
|
||||
pixel = COLOR_ToPhysical( dc, color );
|
||||
|
||||
if (!(image = XGetImage( display, dc->u.x.drawable,
|
||||
dc->w.DCOrgX + rect.left, dc->w.DCOrgY + rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
AllPlanes, ZPixmap ))) return FALSE;
|
||||
|
||||
if (DC_SetupGCForBrush( dc ))
|
||||
{
|
||||
/* ROP mode is always GXcopy for flood-fill */
|
||||
XSetFunction( display, dc->u.x.gc, GXcopy );
|
||||
/* We can pass anything except 0 as a region */
|
||||
GRAPH_InternalFloodFill( image, dc,
|
||||
XLPTODP(dc,x) - rect.left,
|
||||
YLPTODP(dc,y) - rect.top,
|
||||
dc->w.DCOrgX + rect.left,
|
||||
dc->w.DCOrgY + rect.top,
|
||||
pixel, fillType );
|
||||
}
|
||||
|
||||
XDestroyImage( image );
|
||||
return TRUE;
|
||||
return CallTo32_LargeStack( (int(*)())GRAPH_DoFloodFill, 6,
|
||||
dc, &rect, x, y, color, fillType );
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,6 +42,18 @@ void GetKeyboardState(BYTE FAR *lpKeyState)
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* SetKeyboardState [USER.223]
|
||||
*/
|
||||
void SetKeyboardState(BYTE FAR *lpKeyState)
|
||||
{
|
||||
if (lpKeyState != NULL) {
|
||||
memcpy(KeyStateTable, lpKeyState, 256);
|
||||
MouseButtonsStates[0] = KeyStateTable[VK_LBUTTON];
|
||||
MouseButtonsStates[1] = KeyStateTable[VK_MBUTTON];
|
||||
MouseButtonsStates[2] = KeyStateTable[VK_RBUTTON];
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* GetAsyncKeyState (USER.249)
|
||||
*
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user