Skip to content
Snippets Groups Projects
Commit 75a839a0 authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

Release 0.2.0

Tue Jul 13 20:31:31 1993  Bob Amstadt  (bob at pooh)

	* [global.c]
	Completed global memory pool API

Sun Jul 11 16:59:52 1993  Alexandre Julliard

	* [message.c] [user.c] [user.spec] [windows.h]
	Added emulation of Windows message queue.

Thu Jul  8 19:29:27 1993  Bob Amstadt  (bob at pooh)

	* [build.c] Original by Bob Amstadt
	* [callback.c] Original by Bob Amstadt, updates by 
	Alexandre Julliard
	* [dump.c] Original by Bob Amstadt
	* [global.c] Original by Bob Amstadt
	* [heap.c] Original by Bob Amstadt
	* [kernel.c] Original by Bob Amstadt
	* [ldt.c] Original by Bob Amstadt
	* [ldtlib.c] Original by Bob Amstadt
	* [relay.c] Original by Bob Amstadt
	* [resource.c] Original by Bob Amstadt, updates by 
	Alexandre Juliard
	* [selector.c] Original by Bob Amstadt, updates by Eric Youngdale
	* [user.c] Original by Bob Amstadt
	* [wine.c] Original by Bob Amstadt, updates by Eric Youngdale and
	Alexandre Julliard
	* [wintcl.c] Original by Regents of the University of California,
	updates by Peter MacDonald and Alexandre Julliard
	* [callback.h] Original by Bob Amstadt
	* [dlls.h] Original by Bob Amstadt
	* [heap.h] Original by Bob Amstadt
	* [neexe.h] Original by Bob Amstadt
	* [prototypes.h] Original by Bob Amstadt, updates by 
	Eric Youngdale
	* [segmem.h] Original by Bob Amstadt
	* [tkInt.h] Original by Regents of the University of California
	* [windows.h] Original by Peter MacDonald, updates by 
	Alexandre Julliard and Bob Amstadt
	* [wine.h] Original by Eric Youngdale
	* [kernel.spec] Original by Bob Amstadt, updates by 
	Alexandre Julliard
	* [gdi.spec] Original by Bob Amstadt, updates by 
	Alexandre Julliard
	* [shell.spec] Original by Bob Amstadt
	* [unixlib.spec] Original by Bob Amstadt
	* [user.spec] Original by Bob Amstadt, updates by Alexandre Julliard
	* [win87em.spec] Original by Bob Amstadt
	* [Windows.tcl] Original by Peter MacDonald, updates by 
	Alexandre Julliard
	* [build-spec.txt] Original by Bob Amstadt
	* [if1632.S] Original by Bob Amstadt, updates by Eric Youngdale
parent 121bd98c
No related branches found
No related tags found
No related merge requests found
Tue Jul 13 20:31:31 1993 Bob Amstadt (bob at pooh)
* [global.c]
Completed global memory pool API
Sun Jul 11 16:59:52 1993 Alexandre Julliard
* [message.c] [user.c] [user.spec] [windows.h]
Added emulation of Windows message queue.
Thu Jul 8 19:29:27 1993 Bob Amstadt (bob at pooh)
* [build.c] Original by Bob Amstadt
* [callback.c] Original by Bob Amstadt, updates by
Alexandre Julliard
* [dump.c] Original by Bob Amstadt
* [global.c] Original by Bob Amstadt
* [heap.c] Original by Bob Amstadt
* [kernel.c] Original by Bob Amstadt
* [ldt.c] Original by Bob Amstadt
* [ldtlib.c] Original by Bob Amstadt
* [relay.c] Original by Bob Amstadt
* [resource.c] Original by Bob Amstadt, updates by
Alexandre Juliard
* [selector.c] Original by Bob Amstadt, updates by Eric Youngdale
* [user.c] Original by Bob Amstadt
* [wine.c] Original by Bob Amstadt, updates by Eric Youngdale and
Alexandre Julliard
* [wintcl.c] Original by Regents of the University of California,
updates by Peter MacDonald and Alexandre Julliard
* [callback.h] Original by Bob Amstadt
* [dlls.h] Original by Bob Amstadt
* [heap.h] Original by Bob Amstadt
* [neexe.h] Original by Bob Amstadt
* [prototypes.h] Original by Bob Amstadt, updates by
Eric Youngdale
* [segmem.h] Original by Bob Amstadt
* [tkInt.h] Original by Regents of the University of California
* [windows.h] Original by Peter MacDonald, updates by
Alexandre Julliard and Bob Amstadt
* [wine.h] Original by Eric Youngdale
* [kernel.spec] Original by Bob Amstadt, updates by
Alexandre Julliard
* [gdi.spec] Original by Bob Amstadt, updates by
Alexandre Julliard
* [shell.spec] Original by Bob Amstadt
* [unixlib.spec] Original by Bob Amstadt
* [user.spec] Original by Bob Amstadt, updates by Alexandre Julliard
* [win87em.spec] Original by Bob Amstadt
* [Windows.tcl] Original by Peter MacDonald, updates by
Alexandre Julliard
* [build-spec.txt] Original by Bob Amstadt
* [if1632.S] Original by Bob Amstadt, updates by Eric Youngdale
CFLAGS=-g -DDEBUG_RESOURCE -DDEBUG_HEAP -I./
CFLAGS=-g -DDEBUG_RESOURCE -I./
######################################################################
# FILES:
......@@ -19,10 +19,10 @@ MUST_BE_LINKED_FIRST=if1632.o $(BUILDOBJS)
OBJS=$(MUST_BE_LINKED_FIRST) \
callback.o dump.o global.o heap.o ldt.o kernel.o relay.o resource.o \
selector.o user.o wine.o wintcl.o
selector.o message.o user.o wine.o class.o win.o widgets.o event.o xt.o
TARGET=wine
LIBS=-L. -L/usr/X386/lib -L/dasd3/usr/lib -lldt -ltk -ltcl -lX11
LIBS=-L. -L/usr/X386/lib -lldt -lXt -lX11
all: $(TARGET)
......
......@@ -2,14 +2,28 @@ Copyright Robert J. Amstadt, 1993. All code is provided without
warranty. It is my intent to cover this code with the Gnu Public
License.
So here goes release 0.1.0 of the Windows loader. It will do some
So here goes release 0.2.0 of the Windows loader. It will do some
relocations and then run the program. I have successfully loaded
the Windows solitaire game. Try it. It currently stops a call to
GetObject().
WHAT'S NEW with version 0.2.0:
- Alexandre Julliard has provided a replacement for the Tcl code.
The new code uses Xlib and Xt directly with no intervening
interpretted language. This should reduce the learning
curve for casual hackers.
- I changed all GLOBAL_ names to Global.
WHAT'S NEW with version 0.1.1:
- I have completed global memory allocation, but I don't like it.
It is not 100% compatible with Windows. I need some more kernel
modifications for 100% compatibility.
- Alexandre Julliard has provided written better emulation for
the Windows message queue.
WHAT'S NEW with version 0.1.0:
- Integrated patches from Alexandre.
- Minor bug fix in if1632.S
- Latest patches from Alexandre Julliard.
- minor bug fix in if1632.S
WHAT'S NEW with version 0.0.5:
- Patches from Alexandre Julliard. Some integration with Tcl.
......@@ -59,9 +73,9 @@ TODO:
- Segment fixup code completion.
- Trap and handle DOS and DPMI calls.
- global memory allocation completion
- GlobalAlloc should support ZEROINIT.
- GlobalAlloc of code segments.
- Rewrite global memory support including kernel mods to allow
application to mess with page map.
- complete and improve local heap allocation.
- Handle self-loading applications.
- Resource loading
......@@ -85,6 +99,11 @@ you keep your kernel sources), untar this file it contains three files:
- This is a patch that must be applied to the kernel.
It updates two header files, and the kernel Makefile.
Or follow the same procedure with "ldt512.tar". This file contains
Eric Youngdales patches for ALPHA-pl11. These patches give the
emulator 512 ldt entries instead of the 32 available with the older
patch kit.
BUILD:
The documentation for the build program is in the file build-spec.txt
......
# Windows Tcl/Tk emulation scripts
# Initial implementation by Peter MacDonald pmacdona@sanjuan.uvic.ca
proc CreateWindow { f t x y h w } {
global baseframe
set baseframe $f
wm title . "$t"
frame .$f
pack append . .$f {top}
canvas .$f.canvas1 -scrollregion " $x $y $h $w " -width 15c -height 10c
pack append .$f .$f.canvas1 {top}
}
proc CreateMenuEntry { fn t x } {
global baseframe
menubutton .$fn -text "$t" -underline $x -menu .$fn.m
pack append .$baseframe .$fn left
menu .$fn.m
}
proc CreateMenuBar { f } {
global allmenus
global baseframe
set allmenus ""
frame .$f -relief raised -borderwidth 1
pack before .$baseframe .$f {top fillx}
}
proc AppendMenu { a b c d x } {
global allmenus
global baseframe
if { ($b == 0x10) } {
.$c configure -text "$d" -underline "$x"
pack append .$a .$c left
set allmenus "$allmenus $c"
tk_menuBar .$a $allmenus
tk_bindForTraversal .$baseframe.canvas1
} else { if { ($b == 0x0800) } {
.$a.m add separator
} else {
.$a.m add command -label "$d" -command "wincallback menu $a $b $c $d" -underline $x
}}
}
####################################################################
# Misc unimplemented stuff
####################################################################
proc LoadIcon { wind name } {
echo "LoadIcon"
}
proc LoadBitmap { wind name } {
echo "LoadBitmap"
}
proc LoadCursor { wind name } {
echo "LoadCursor"
}
proc GetObject { obj count ptr } {
echo "GetObject $obj $count $ptr"
}
proc GetStockObject { wind } {
echo "GetStockObject $wind"
}
proc DefWindowProc { a b c d } {
echo "DefWindowProc $a $b $c $d"
}
proc GetMenu { a } {
echo "GetMenu $a"
}
proc SetMenu { a b } {
echo "SetMenu $a $b"
}
proc MessageBeep {a } {
echo "MessageBeep $a"
}
proc MessageBox { wind msg title type } {
echo "MessageBox '$msg'"
}
proc DrawText { f t top left right bottom } {
.$f.canvas1 create text $top $left -text "$t" -anchor n
}
static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include "windows.h"
#include "callback.h"
#include "wine.h"
#include "segmem.h"
......@@ -106,3 +107,22 @@ CALLBACK_MakeProcInstance(void *func, int instance)
return tp->thunk;
}
/**********************************************************************
* CallWindowProc (USER.122)
*/
LONG CallWindowProc( FARPROC func, HWND hwnd, WORD message,
WORD wParam, LONG lParam )
{
if ((unsigned int)func & 0xffff0000)
{
PushOn16( CALLBACK_SIZE_WORD, hwnd );
PushOn16( CALLBACK_SIZE_WORD, message );
PushOn16( CALLBACK_SIZE_WORD, wParam );
PushOn16( CALLBACK_SIZE_LONG, lParam );
return CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
else
return WIDGETS_Call32WndProc( func, hwnd, message, wParam, lParam );
}
......@@ -17,13 +17,4 @@ extern int CallTo16(unsigned int csip, unsigned short ds);
extern int CallBack16(void *func, int n_args, ...);
/*
* Windows procedure calling:
* f(a, b, c, d)
* wndprocfunc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
*/
#define CALLWNDPROC(f, a, b, c, d) \
CallBack16((f), 4, CALLBACK_SIZE_WORD, (a), CALLBACK_SIZE_WORD, (b), \
CALLBACK_SIZE_WORD, (c), CALLBACK_SIZE_LONG, (d))
#endif /* CALLBACK_H */
class.c 0 → 100644
/*
* Window classes functions
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include "class.h"
static HCLASS firstClass = 0;
/***********************************************************************
* CLASS_FindClassByName
*
* Return a handle and a pointer to the class.
* The caller must GlobalUnlock the pointer.
*/
HCLASS CLASS_FindClassByName( char * name, CLASS **ptr )
{
HCLASS class, next;
class = firstClass;
while(class)
{
*ptr = (CLASS *) GlobalLock(class);
if (!strcmp( (*ptr)->wc.lpszClassName, name )) return class;
next = (*ptr)->hNext;
GlobalUnlock(class);
class = next;
}
return 0;
}
/***********************************************************************
* CLASS_FindClassPtr
*
* Return a pointer to the CLASS structure corresponding to a HCLASS.
* The caller must GlobalUnlock the pointer.
*/
CLASS * CLASS_FindClassPtr( HCLASS hclass )
{
CLASS * ptr;
if (!hclass) return NULL;
ptr = (CLASS *) GlobalLock( hclass );
if (ptr->wMagic != CLASS_MAGIC)
{
GlobalUnlock( hclass );
return NULL;
}
return ptr;
}
/***********************************************************************
* RegisterClass (USER.57)
*/
ATOM RegisterClass( LPWNDCLASS class )
{
CLASS * newClass;
HCLASS handle;
int i;
#ifdef DEBUG_CLASS
printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n",
class->lpfnWndProc, class->hInstance, class->lpszClassName );
#endif
handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra );
if (!handle) return 0;
newClass = (CLASS *) GlobalLock( handle );
newClass->hNext = firstClass;
newClass->wMagic = CLASS_MAGIC;
newClass->atomName = handle; /* Should be an atom */
newClass->hDCE = 0; /* Should allocate a DCE if needed */
newClass->cWindows = 0;
newClass->wc = *class;
newClass->wc.lpszMenuName = 0;
/* Class name should also be set to zero. For now we need the
* name because we don't have atoms.
*/
newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1);
strcpy( newClass->wc.lpszClassName, class->lpszClassName );
if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
GlobalUnlock( handle );
firstClass = handle;
return handle; /* Should be an atom */
}
/***********************************************************************
* UnregisterClass (USER.403)
*/
BOOL UnregisterClass( LPSTR className, HANDLE instance )
{
HANDLE class, next, prevClass;
CLASS * classPtr, * prevClassPtr;
/* Check if we can remove this class */
class = CLASS_FindClassByName( className, &classPtr );
if (!class) return FALSE;
if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
{
GlobalUnlock( class );
return FALSE;
}
/* Remove the class from the linked list */
if (firstClass == class) firstClass = classPtr->hNext;
else
{
prevClass = firstClass;
while (prevClass)
{
prevClassPtr = (CLASS *) GlobalLock(prevClass);
next == prevClassPtr->hNext;
if (next == class) break;
GlobalUnlock(prevClass);
prevClass = next;
}
if (!prevClass)
{
printf( "ERROR: Class list corrupted\n" );
return FALSE;
}
prevClassPtr->hNext = classPtr->hNext;
GlobalUnlock( prevClass );
}
GlobalUnlock( class );
GlobalFree( class );
return TRUE;
}
class.h 0 → 100644
/*
* Window classes definitions
*
* Copyright 1993 Alexandre Julliard
*/
#ifndef CLASS_H
#define CLASS_H
#include "windows.h"
#define CLASS_MAGIC 0x4b4e /* 'NK' */
typedef struct tagCLASS
{
HCLASS hNext; /* Next class */
WORD wMagic; /* Magic number (must be CLASS_MAGIC) */
ATOM atomName; /* Name of the class */
HANDLE hDCE; /* Class DC Entry (if CS_CLASSDC) */
WORD cWindows; /* Count of existing windows of this class */
WNDCLASS wc __attribute__ ((packed)); /* Class information */
WORD wExtra[1]; /* Class extra bytes */
} CLASS;
/* The caller must GlobalUnlock the pointer returned
* by these functions (except when NULL).
*/
HCLASS CLASS_FindClassByName( char * name, CLASS **ptr );
CLASS * CLASS_FindClassPtr( HCLASS hclass );
#endif /* CLASS_H */
event.c 0 → 100644
/*
* X events handling functions
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Core.h>
#include "windows.h"
#define NB_BUTTONS 3 /* Windows can handle 3 buttons */
#define DBLCLICK_TIME 300 /* Max. time for a double click (milliseconds) */
/* Event handlers */
static void EVENT_expose();
static void EVENT_key();
static void EVENT_mouse_motion();
static void EVENT_mouse_button();
/***********************************************************************
* EVENT_AddHandlers
*
* Add the event handlers to the given window
*/
void EVENT_AddHandlers( Widget w, int hwnd )
{
XtAddEventHandler(w, ExposureMask, FALSE,
EVENT_expose, (XtPointer)hwnd );
XtAddEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE,
EVENT_key, (XtPointer)hwnd );
XtAddEventHandler(w, PointerMotionMask, FALSE,
EVENT_mouse_motion, (XtPointer)hwnd );
XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE,
EVENT_mouse_button, (XtPointer)hwnd );
}
/***********************************************************************
* EVENT_RemoveHandlers
*
* Remove the event handlers of the given window
*/
void EVENT_RemoveHandlers( Widget w, int hwnd )
{
XtRemoveEventHandler(w, ExposureMask, FALSE,
EVENT_expose, (XtPointer)hwnd );
XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE,
EVENT_key, (XtPointer)hwnd );
XtRemoveEventHandler(w, PointerMotionMask, FALSE,
EVENT_mouse_motion, (XtPointer)hwnd );
XtRemoveEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE,
EVENT_mouse_button, (XtPointer)hwnd );
}
/***********************************************************************
* EVENT_XStateToKeyState
*
* Translate a X event state (Button1Mask, ShiftMask, etc...) to
* a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
*/
static WORD EVENT_XStateToKeyState( int state )
{
int kstate = 0;
if (state & Button1Mask) kstate |= MK_LBUTTON;
if (state & Button2Mask) kstate |= MK_MBUTTON;
if (state & Button3Mask) kstate |= MK_RBUTTON;
if (state & ShiftMask) kstate |= MK_SHIFT;
if (state & ControlMask) kstate |= MK_CONTROL;
return kstate;
}
/***********************************************************************
* EVENT_expose
*
* Handle a X expose event
*/
static void EVENT_expose( Widget w, int hwnd, XEvent *event,
Boolean *cont_dispatch )
{
MSG msg;
XExposeEvent * expEvt = (XExposeEvent *)expEvt;
msg.hwnd = hwnd;
msg.message = WM_PAINT;
msg.wParam = 0;
msg.lParam = 0;
msg.time = 0;
msg.pt.x = 0;
msg.pt.y = 0;
MSG_AddMsg( &msg, 0 );
}
/***********************************************************************
* EVENT_key
*
* Handle a X key event
*/
static void EVENT_key( Widget w, int hwnd, XKeyEvent *event,
Boolean *cont_dispatch )
{
MSG msg;
msg.hwnd = hwnd;
msg.message = (event->type == KeyRelease) ? WM_KEYUP : WM_KEYDOWN;
msg.wParam = 0;
msg.lParam = (event->x & 0xffff) | (event->y << 16);
msg.time = event->time;
msg.pt.x = event->x & 0xffff;
msg.pt.y = event->y & 0xffff;
MSG_AddMsg( &msg );
}
/***********************************************************************
* EVENT_mouse_motion
*
* Handle a X mouse motion event
*/
static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event,
Boolean *cont_dispatch )
{
MSG msg;
msg.hwnd = hwnd;
msg.message = WM_MOUSEMOVE;
msg.wParam = EVENT_XStateToKeyState( event->state );
msg.lParam = (event->x & 0xffff) | (event->y << 16);
msg.time = event->time;
msg.pt.x = event->x & 0xffff;
msg.pt.y = event->y & 0xffff;
MSG_AddMsg( &msg );
}
/***********************************************************************
* EVENT_mouse_button
*
* Handle a X mouse button event
*/
static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event,
Boolean *cont_dispatch )
{
static WORD messages[3][NB_BUTTONS] =
{
{ WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN },
{ WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP },
{ WM_LBUTTONDBLCLK, WM_MBUTTONDBLCLK, WM_RBUTTONDBLCLK }
};
static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 };
MSG msg;
int buttonNum, prevTime, type;
buttonNum = event->button-1;
if (buttonNum >= NB_BUTTONS) return;
if (event->type == ButtonRelease) type = 1;
else
{ /* Check if double-click */
prevTime = lastClickTime[buttonNum];
lastClickTime[buttonNum] = event->time;
type = (event->time - prevTime < DBLCLICK_TIME) ? 2 : 0;
}
msg.hwnd = hwnd;
msg.message = messages[type][buttonNum];
msg.wParam = EVENT_XStateToKeyState( event->state );
msg.lParam = (event->x & 0xffff) | (event->y << 16);
msg.time = event->time;
msg.pt.x = event->x & 0xffff;
msg.pt.y = event->y & 0xffff;
MSG_AddMsg( &msg );
}
......@@ -8,7 +8,9 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include "segmem.h"
/*
* Global memory pool descriptor.
* Global memory pool descriptor. Segments MUST be maintained in segment
* ascending order. If not the reallocation routine will die a horrible
* death.
*
* handle = 0, this descriptor contains the address of a free pool.
* != 0, this describes an allocated block.
......@@ -30,15 +32,18 @@ typedef struct global_mem_desc_s
short sequence;
void *addr;
int length;
int lock_count;
} GDESC;
GDESC *GlobalList = NULL;
static unsigned short next_unused_handle = 1;
/**********************************************************************
* GLOBAL_GetFreeSegments
* GlobalGetFreeSegments
*/
GDESC *
GLOBAL_GetFreeSegments(unsigned int flags, int n_segments)
GlobalGetFreeSegments(unsigned int flags, int n_segments)
{
struct segment_descriptor_s *s;
GDESC *g;
......@@ -100,7 +105,11 @@ GLOBAL_GetFreeSegments(unsigned int flags, int n_segments)
g->sequence = -1;
g->addr = s->base_addr;
g->length = s->length;
if (!(flags & GLOBAL_FLAGS_MOVEABLE))
g->lock_count = 1;
else
g->lock_count = 0;
free(s);
if (count == 0)
......@@ -130,15 +139,14 @@ GLOBAL_GetFreeSegments(unsigned int flags, int n_segments)
}
/**********************************************************************
* GLOBAL_Alloc
* GlobalAlloc
*/
unsigned int
GLOBAL_Alloc(unsigned int flags, unsigned long size)
GlobalAlloc(unsigned int flags, unsigned long size)
{
GDESC *g;
GDESC *g_prev;
void *m;
int i;
/*
* If this block is fixed or very big we need to allocate entire
......@@ -148,7 +156,7 @@ GLOBAL_Alloc(unsigned int flags, unsigned long size)
{
int segments = (size >> 16) + 1;
g = GLOBAL_GetFreeSegments(flags, segments);
g = GlobalGetFreeSegments(flags, segments);
if (g == NULL)
return 0;
else
......@@ -176,9 +184,9 @@ GLOBAL_Alloc(unsigned int flags, unsigned long size)
* If we couldn't get the memory there, then we need to create
* a new free list.
*/
if (m == NULL)
if (g == NULL)
{
g = GLOBAL_GetFreeSegments(0, 1);
g = GlobalGetFreeSegments(0, 1);
if (g == NULL)
return 0;
......@@ -186,52 +194,56 @@ GLOBAL_Alloc(unsigned int flags, unsigned long size)
g->sequence = 0;
HEAP_Init((MDESC **) g->addr, (MDESC **) g->addr + 1,
0x10000 - sizeof(MDESC **));
m = HEAP_Alloc((MDESC **) g->addr, 0, size);
m = HEAP_Alloc((MDESC **) g->addr, flags & GLOBAL_FLAGS_ZEROINIT,
size);
if (m == NULL)
return 0;
}
/*
* We have a new block. Let's create a GDESC entry for it.
* Save position of heap descriptor.
*/
g_prev = NULL;
i = 0;
for (g = GlobalList; g != NULL; g = g->next, i++)
g_prev = g;
g_prev = g;
/*
* We have a new block. Let's create a GDESC entry for it.
*/
g = malloc(sizeof(*g));
#ifdef DEBUG_HEAP
printf("New GDESC %08x\n", g);
#endif
if (g == NULL)
return 0;
g->handle = i << 3;
g->handle = next_unused_handle;
g->sequence = 0;
g->addr = m;
g->length = size;
g->next = NULL;
g->next = g_prev->next;
g->lock_count = 0;
if (g_prev != NULL)
{
g_prev->next = g;
g->prev = g_prev;
}
else
{
GlobalList = g;
g->prev = NULL;
}
g_prev->next = g;
g->prev = g_prev;
next_unused_handle++;
if ((next_unused_handle & 7) == 7)
next_unused_handle++;
#ifdef DEBUG_HEAP
printf("GlobalAlloc: returning %04x\n", g->handle);
#endif
return g->handle;
}
}
/**********************************************************************
* GLOBAL_Free
* GlobalFree
*
* Windows programs will pass a handle in the "block" parameter, but
* this function will also accept a 32-bit address.
*/
unsigned int
GLOBAL_Free(unsigned int block)
GlobalFree(unsigned int block)
{
GDESC *g;
......@@ -264,10 +276,7 @@ GLOBAL_Free(unsigned int block)
{
HEAP_Free((MDESC **) (block & 0xffff0000), (void *) block);
if (g->prev != NULL)
g->prev->next = g->next;
else
GlobalList = g->next;
g->prev->next = g->next;
if (g->next != NULL)
g->next->prev = g->prev;
......@@ -282,8 +291,8 @@ GLOBAL_Free(unsigned int block)
{
int i, limit;
g->length;
for (i = 0; i < limit; i++)
limit = g->length;
for (i = g->sequence - 1; i < limit && g != NULL; i++, g = g->next)
{
g->sequence = -1;
g->length = 0x10000;
......@@ -294,11 +303,11 @@ GLOBAL_Free(unsigned int block)
}
/**********************************************************************
* GLOBAL_Lock
* GlobalLock
*
*/
void *
GLOBAL_Lock(unsigned int block)
GlobalLock(unsigned int block)
{
GDESC *g;
......@@ -309,8 +318,362 @@ GLOBAL_Lock(unsigned int block)
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == block)
{
g->lock_count++;
#ifdef DEBUG_HEAP
printf("GlobalLock: returning %08x\n", g->addr);
#endif
return g->addr;
}
}
#ifdef DEBUG_HEAP
printf("GlobalLock: returning %08x\n", 0);
#endif
return NULL;
}
/**********************************************************************
* GlobalUnlock
*
*/
int
GlobalUnlock(unsigned int block)
{
GDESC *g;
if (block == 0)
return 0;
/*
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == block && g->lock_count > 0)
{
g->lock_count--;
return 0;
}
}
return 1;
}
/**********************************************************************
* GlobalFlags
*
*/
unsigned int
GlobalFlags(unsigned int block)
{
GDESC *g;
if (block == 0)
return 0;
/*
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == block)
return g->lock_count;
}
return 0;
}
/**********************************************************************
* GlobalSize
*
*/
unsigned int
GlobalSize(unsigned int block)
{
GDESC *g;
if (block == 0)
return 0;
/*
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == block)
return g->length;
}
return 0;
}
/**********************************************************************
* GlobalHandle
*
* This routine is not strictly correct. MS Windows creates a selector
* for every locked global block. We do not. If the allocation is small
* enough, we only give out a little piece of a selector. Thus this
* function cannot be implemented.
*/
unsigned int
GlobalHandle(unsigned int selector)
{
GDESC *g;
if (selector == 0)
return 0;
/*
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == selector)
{
if (g->sequence > 0)
return g->handle;
else
{
fprintf(stderr, "Attempt to get a handle "
"from a selector to a far heap.\n");
return 0;
}
}
}
return 0;
}
/**********************************************************************
* GlobalCompact
*
*/
unsigned int
GlobalCompact(unsigned int desired)
{
GDESC *g;
unsigned char free_map[512];
unsigned int max_selector_used = 0;
unsigned int i;
unsigned int selector;
int current_free;
int max_free;
/*
* Initialize free list to all items not controlled by GlobalAlloc()
*/
for (i = 0; i < 512; i++)
free_map[i] = -1;
/*
* Traverse table looking for used and free selectors.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
/*
* Check for free segments.
*/
if (g->sequence == -1)
{
free_map[g->handle >> 3] = 1;
if (g->handle > max_selector_used)
max_selector_used = g->handle;
}
/*
* Check for heap allocated segments.
*/
else if (g->handle == 0)
{
selector = (unsigned int) g->addr >> 16;
free_map[selector >> 3] = 0;
if (selector > max_selector_used)
max_selector_used = selector;
}
}
/*
* All segments past the biggest selector used are free.
*/
for (i = (max_selector_used >> 3) + 1; i < 512; i++)
free_map[i] = 1;
/*
* Find the largest free block of segments
*/
current_free = 0;
max_free = 0;
for (i = 0; i < 512; i++)
{
if (free_map[i] == 1)
{
current_free++;
}
else
{
if (current_free > max_free)
max_free = current_free;
current_free = 0;
}
}
return max_free << 16;
}
/**********************************************************************
* GlobalReAlloc
*
*/
unsigned int
GlobalReAlloc(unsigned int block, unsigned int new_size, unsigned int flags)
{
GDESC *g;
unsigned int n_segments;
int i;
if (block == 0)
return 0;
/*
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == block)
break;
}
if (g == NULL)
return 0;
/*
* If this is a heap allocated block, then use HEAP_ReAlloc() to
* reallocate the block. If this fails, call GlobalAlloc() to get
* a new block.
*/
if (g->sequence = 0)
{
MDESC **free_list;
void *p;
free_list = (MDESC **) ((unsigned int) g->addr & 0xffff0000);
p = HEAP_ReAlloc(free_list, g->addr, new_size, flags) ;
if (p == NULL)
{
unsigned int handle = GlobalAlloc(flags, new_size);
if (handle == 0)
return 0;
p = GlobalLock(handle);
memcpy(p, g->addr, g->length);
GlobalUnlock(handle);
GlobalFree(g->handle);
return handle;
}
else
{
g->addr = p;
g->length = new_size;
return g->handle;
}
}
/*
* Otherwise, we need to do the work ourselves. First verify the
* handle.
*/
else
{
if (g->sequence != 1)
return 0;
/*
* Do we need more memory? Segments are in ascending order in
* the GDESC list.
*/
n_segments = (new_size >> 16) + 1;
if (n_segments > g->length)
{
GDESC *g_new;
GDESC *g_start = g;
int old_segments = g_start->length;
unsigned short next_handle = g_start->handle;
for (i = 1; i <= n_segments; i++, g = g->next)
{
/*
* If we run into a block allocated to something else,
* try GlobalGetFreeSegments() and memcpy(). (Yuk!)
*/
if (g->sequence != i || g->handle != next_handle)
{
g = GlobalGetFreeSegments(flags, n_segments);
if (g == NULL)
return 0;
memcpy(g->addr, g_start->addr,
g_start->length << 16);
GlobalFree(block);
return g->handle;
}
/*
* Otherwise this block is used by us or free. So,
* snatch it. If this block is new and we are supposed to
* zero init, then do some erasing.
*/
if (g->sequence == -1 && (flags & GLOBAL_FLAGS_ZEROINIT))
memset(g->addr, 0, 0x10000);
g->sequence = i;
g->length = n_segments;
next_handle += 8;
/*
* If the next descriptor is non-existant, then use
* GlobalGetFreeSegments to create them.
*/
if (i != n_segments && g->next == NULL)
{
g_new = GlobalGetFreeSegments(flags, n_segments - i);
if (g_new == NULL)
return 0;
GlobalFree(g_new->handle);
}
}
return g_start->handle;
}
/*
* Do we need less memory?
*/
else if (n_segments < g->length)
{
GDESC *g_free;
g_free = g;
for (i = 0; i < n_segments; i++)
{
if (g_free->sequence != i + 1)
return 0;
g_free = g_free->next;
}
}
/*
* We already have exactly the right amount of memory.
*/
else
return block;
}
/*
* If we fall through it must be an error.
*/
return 0;
}
......@@ -61,6 +61,11 @@ HEAP_Alloc(MDESC **free_list, int flags, int bytes)
m->prev = m;
m->next = m;
if (flags & GLOBAL_FLAGS_ZEROINIT)
memset(m + 1, 0, bytes);
#ifdef DEBUG_HEAP
printf("HeapAlloc: returning %08x\n", (m + 1));
#endif
return (void *) (m + 1);
}
}
......@@ -77,12 +82,31 @@ HEAP_Alloc(MDESC **free_list, int flags, int bytes)
m->prev = m;
m->next = m;
if (flags & GLOBAL_FLAGS_ZEROINIT)
memset(m + 1, 0, bytes);
#ifdef DEBUG_HEAP
printf("HeapAlloc: returning %08x\n", (m + 1));
#endif
return (void *) (m + 1);
}
#ifdef DEBUG_HEAP
printf("HeapAlloc: returning %08x\n", 0);
#endif
return 0;
}
/**********************************************************************
* HEAP_ReAlloc
*/
void *
HEAP_ReAlloc(MDESC **free_list, void *old_block,
int new_size, unsigned int flags)
{
return 0;
}
/**********************************************************************
* HEAP_Free
*/
......@@ -209,3 +233,20 @@ HEAP_LocalAlloc(int flags, int bytes)
#endif
return m;
}
/**********************************************************************
* HEAP_LocalCompact
*/
int
HEAP_LocalCompact(int min_free)
{
MDESC *m;
int max_block;
max_block = 0;
for (m = LOCAL_FreeList; m != NULL; m = m->next)
if (m->length > max_block)
max_block = m->length;
return max_block;
}
......@@ -15,5 +15,7 @@ typedef struct heap_mem_desc_s
extern void HEAP_Init(MDESC **free_list, void *start, int length);
extern void *HEAP_Alloc(MDESC **free_list, int flags, int bytes);
extern void HEAP_Free(MDESC **free_list, void *block);
extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block,
int new_size, unsigned int flags);
#endif /* HEAP_H */
......@@ -7,17 +7,6 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
extern unsigned short *Stack16Frame;
/**********************************************************************
* KERNEL_GetVersion
*
* Return the version of Windows that we emulate.
*/
int
KERNEL_GetVersion(void)
{
return 0x0301;
}
/**********************************************************************
* KERNEL_LockSegment
*/
......
......@@ -6,11 +6,17 @@ length 410
3 return GetVersion 0 0x301
5 pascal LocalAlloc(word word) HEAP_LocalAlloc(1 2)
15 pascal GlobalAlloc(word long) GLOBAL_Alloc(1 2)
17 pascal GlobalFree(word) GLOBAL_Free(1)
18 pascal GLobalLock(word) GLOBAL_Lock(1)
15 pascal GlobalAlloc(word long) GlobalAlloc(1 2)
16 pascal GlobalReAlloc(word long word) GlobalReAlloc(1 2 3)
17 pascal GlobalFree(word) GlobalFree(1)
18 pascal GlobalLock(word) GlobalLock(1)
19 pascal GlobalUnlock(word) GlobalUnlock(1)
20 pascal GlobalSize(word) GlobalSize(1)
21 pascal GlobalHandle(word) GlobalHandle(1)
22 pascal GlobalFlags(word) GlobalFlags(1)
23 pascal LockSegment(s_word) KERNEL_LockSegment(1)
24 pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1)
25 pascal GlobalCompact(long) GlobalCompact(1)
30 pascal WaitEvent(word) KERNEL_WaitEvent(1)
49 pascal GetModuleFileName(word ptr s_word) KERNEL_GetModuleFileName(1 2 3)
51 pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2)
......@@ -18,6 +24,17 @@ length 410
102 register DOS3Call(word word word word word
word word word word word)
KERNEL_DOS3Call(1 2 3 4 5 6 7 8 9 10)
111 pascal GlobalWire(word) GlobalLock(1)
112 pascal GlobalUnWire(word) GlobalUnlock(1)
131 pascal GetDOSEnvironment() GetDOSEnvironment()
132 return GetWinFlags 0 0x413
154 return GlobalNotify 4 0
163 pascal GlobalLRUOldest(word) ReturnArg(1)
164 pascal GlobalLRUNewest(word) ReturnArg(1)
178 equate __WINFLAGS 0x413
184 return GlobalDOSAlloc 4 0
185 return GlobalDOSFree 2 0
191 pascal GlobalPageLock(word) GlobalLock(1)
192 pascal GlobalPageUnlock(word) GlobalUnlock(1)
197 pascal GlobalFix(word) GlobalLock(1)
198 pascal GlobalUnfix(word) GlobalUnlock(1)
File added
message.c 0 → 100644
/*
* Message queues related functions
*
* Copyright 1993 Alexandre Julliard
*/
/*
* This code assumes that there is only one Windows task (hence
* one message queue).
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <sys/param.h>
#include <sys/times.h>
#include "message.h"
#include "win.h"
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
static MESSAGEQUEUE * msgQueue = NULL;
/***********************************************************************
* MSG_GetMessageType
*
*/
int MSG_GetMessageType( int msg )
{
if ((msg >= WM_KEYFIRST) && (msg <= WM_KEYLAST)) return QS_KEY;
else if ((msg >= WM_MOUSEFIRST) && (msg <= WM_MOUSELAST))
{
if (msg == WM_MOUSEMOVE) return QS_MOUSEMOVE;
else return QS_MOUSEBUTTON;
}
else if (msg == WM_PAINT) return QS_PAINT;
else if (msg == WM_TIMER) return QS_TIMER;
return QS_POSTMESSAGE;
}
/***********************************************************************
* MSG_AddMsg
*
* Add a message to the queue. Return FALSE if queue is full.
*/
int MSG_AddMsg( MSG * msg, DWORD extraInfo )
{
int pos, type;
QMSG * qmsg;
if (!msgQueue) return FALSE;
pos = msgQueue->nextFreeMessage;
/* No need to store WM_PAINT messages */
if (msg->message == WM_PAINT)
{
msgQueue->status |= QS_PAINT;
msgQueue->tempStatus |= QS_PAINT;
/* For now we need to store them to keep the hwnd somewhere */
/* return TRUE; */
}
/* Check if queue is full */
if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
return FALSE;
/* Store message */
msgQueue->messages[pos].msg = *msg;
msgQueue->messages[pos].extraInfo = extraInfo;
/* Store message type */
type = MSG_GetMessageType( msg->message );
msgQueue->status |= type;
msgQueue->tempStatus |= type;
if (pos < msgQueue->queueSize-1) pos++;
else pos = 0;
msgQueue->nextFreeMessage = pos;
msgQueue->msgCount++;
return TRUE;
}
/***********************************************************************
* MSG_FindMsg
*
* Find a message matching the given parameters. Return -1 if none available.
*/
int MSG_FindMsg( HWND hwnd, int first, int last )
{
int i, pos = msgQueue->nextMessage;
if (!msgQueue->msgCount) return -1;
if (!hwnd && !first && !last) return pos;
for (i = 0; i < msgQueue->msgCount; i++)
{
MSG * msg = &msgQueue->messages[pos].msg;
if (!hwnd || (msg->hwnd == hwnd))
{
if (!first && !last) return pos;
if ((msg->message >= first) && (msg->message <= last)) return pos;
}
if (pos < msgQueue->queueSize-1) pos++;
else pos = 0;
}
return -1;
}
/***********************************************************************
* MSG_RemoveMsg
*
* Remove a message from the queue (pos must be a valid position).
*/
void MSG_RemoveMsg( int pos )
{
int oldpos, i, type;
QMSG * qmsg;
if (!msgQueue) return;
qmsg = &msgQueue->messages[pos];
if (pos >= msgQueue->nextMessage)
{
int count = pos - msgQueue->nextMessage;
if (count) memmove( &msgQueue->messages[msgQueue->nextMessage+1],
&msgQueue->messages[msgQueue->nextMessage],
count * sizeof(QMSG) );
msgQueue->nextMessage++;
if (msgQueue->nextMessage >= msgQueue->queueSize)
msgQueue->nextMessage = 0;
}
else
{
int count = msgQueue->nextFreeMessage - pos;
if (count) memmove( &msgQueue->messages[pos],
&msgQueue->messages[pos+1], count * sizeof(QMSG) );
if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
}
msgQueue->msgCount--;
/* Recalc status */
type = 0;
pos = msgQueue->nextMessage;
for (i = 0; i < msgQueue->msgCount; i++)
{
type |= MSG_GetMessageType( msgQueue->messages[pos].msg.message );
if (++pos >= msgQueue->queueSize-1) pos = 0;
}
msgQueue->status = msgQueue->status & (QS_PAINT | QS_SENDMESSAGE) | type;
msgQueue->tempStatus = 0;
}
/***********************************************************************
* MSG_EndPaint
*
* Remove the WM_PAINT message from the queue
*/
void MSG_EndPaint()
{
msgQueue->status &= ~QS_PAINT;
}
/***********************************************************************
* MSG_GetTime
*
* Return the time elapsed from the starting of the system, in milliseconds.
* Used to timestamp messages.
*/
LONG MSG_GetTime()
{
struct tms dummy;
return times(&dummy) / (1000 / HZ);
}
/***********************************************************************
* SetMessageQueue (USER.266)
*/
BOOL SetMessageQueue( int size )
{
int queueSize;
/* Free the old message queue */
if (msgQueue) free(msgQueue);
if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return FALSE;
queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
msgQueue = (MESSAGEQUEUE *) malloc(queueSize);
if (!msgQueue) return FALSE;
msgQueue->next = 0;
msgQueue->hTask = 0;
msgQueue->msgSize = sizeof(QMSG);
msgQueue->msgCount = 0;
msgQueue->nextMessage = 0;
msgQueue->nextFreeMessage = 0;
msgQueue->queueSize = size;
msgQueue->GetMessageTimeVal = 0;
msgQueue->GetMessagePosVal = 0;
msgQueue->GetMessageExtraInfoVal = 0;
msgQueue->lParam = 0;
msgQueue->wParam = 0;
msgQueue->msg = 0;
msgQueue->hWnd = 0;
msgQueue->wPostQMsg = 0;
msgQueue->wExitCode = 0;
msgQueue->InSendMessageHandle = 0;
msgQueue->tempStatus = 0;
msgQueue->status = 0;
return TRUE;
}
/***********************************************************************
* PostQuitMessage (USER.6)
*/
void PostQuitMessage( int exitCode )
{
if (!msgQueue) return;
msgQueue->wPostQMsg = TRUE;
msgQueue->wExitCode = exitCode;
}
/***********************************************************************
* GetQueueStatus (USER.334)
*/
DWORD GetQueueStatus( int flags )
{
unsigned long ret = (msgQueue->status << 16) | msgQueue->tempStatus;
msgQueue->tempStatus = 0;
return ret & ((flags << 16) | flags);
}
/***********************************************************************
* GetInputState (USER.335)
*/
BOOL GetInputState()
{
return msgQueue->status & (QS_KEY | QS_MOUSEBUTTON);
}
/***********************************************************************
* PeekMessage (USER.109)
*/
BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
{
int pos;
/* First handle a WM_QUIT message */
if (msgQueue->wPostQMsg)
{
msg->hwnd = hwnd;
msg->message = WM_QUIT;
msg->wParam = msgQueue->wExitCode;
msg->lParam = 0;
return TRUE;
}
/* Then handle a message put by SendMessage() */
if (msgQueue->status & QS_SENDMESSAGE)
{
if (!hwnd || (msgQueue->hWnd == hwnd))
{
if ((!first && !last) ||
((msgQueue->msg >= first) && (msgQueue->msg <= last)))
{
msg->hwnd = msgQueue->hWnd;
msg->message = msgQueue->msg;
msg->wParam = msgQueue->wParam;
msg->lParam = msgQueue->lParam;
if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE;
return TRUE;
}
}
}
/* Now find a normal message */
pos = MSG_FindMsg( hwnd, first, last );
if (pos != -1)
{
QMSG *qmsg = &msgQueue->messages[pos];
*msg = qmsg->msg;
msgQueue->GetMessageTimeVal = msg->time;
msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
if (flags & PM_REMOVE) MSG_RemoveMsg(pos);
return TRUE;
}
/* If nothing else, return a WM_PAINT message */
if (msgQueue->status & QS_PAINT)
{
if ((!first && !last) || ((first <= WM_PAINT) && (last >= WM_PAINT)))
{
msg->hwnd = hwnd;
msg->message = WM_PAINT;
msg->wParam = 0;
msg->lParam = 0;
return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* PostMessage (USER.110)
*/
BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam )
{
MSG msg;
msg.hwnd = hwnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
msg.time = MSG_GetTime();
msg.pt.x = 0;
msg.pt.y = 0;
return MSG_AddMsg( &msg, 0 );
}
/***********************************************************************
* SendMessage (USER.111)
*/
LONG SendMessage( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
{
LONG retval = 0;
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr)
{
retval = CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg,
wParam, lParam );
GlobalUnlock( hwnd );
}
return retval;
}
/***********************************************************************
* TranslateMessage (USER.113)
*/
BOOL TranslateMessage( LPMSG msg )
{
int message = msg->message;
if ((message == WM_KEYDOWN) || (message == WM_KEYUP) ||
(message == WM_SYSKEYDOWN) || (message == WM_SYSKEYUP))
{
#ifdef DEBUG_MSG
printf( "Translating key message\n" );
#endif
return TRUE;
}
return FALSE;
}
/***********************************************************************
* DispatchMessage (USER.114)
*/
LONG DispatchMessage( LPMSG msg )
{
LONG retval = 0;
WND * wndPtr = WIN_FindWndPtr( msg->hwnd );
#ifdef DEBUG_MSG
printf( "Dispatch message hwnd=%08x msg=%d w=%d l=%d time=%u pt=%d,%d\n",
msg->hwnd, msg->message, msg->wParam, msg->lParam,
msg->time, msg->pt.x, msg->pt.y );
#endif
if (wndPtr)
{
retval = CallWindowProc(wndPtr->lpfnWndProc, msg->hwnd, msg->message,
msg->wParam, msg->lParam );
GlobalUnlock( msg->hwnd );
}
return retval;
}
/***********************************************************************
* GetMessagePos (USER.119)
*/
DWORD GetMessagePos(void)
{
return msgQueue->GetMessagePosVal;
}
/***********************************************************************
* GetMessageTime (USER.120)
*/
LONG GetMessageTime(void)
{
return msgQueue->GetMessageTimeVal;
}
/***********************************************************************
* GetMessageExtraInfo (USER.288)
*/
LONG GetMessageExtraInfo(void)
{
return msgQueue->GetMessageExtraInfoVal;
}
/*
* Message queues definitions
*
* Copyright 1993 Alexandre Julliard
*/
#ifndef MESSAGE_H
#define MESSAGE_H
#include "windows.h"
/* Message as stored in the queue (contains the extraInfo field) */
typedef struct tagQMSG
{
MSG msg;
DWORD extraInfo __attribute__ ((packed)); /* Only in 3.1 */
} QMSG;
typedef struct tagMESSAGEQUEUE
{
WORD next;
WORD hTask; /* hTask owning the queue */
WORD msgSize; /* Size of messages in the queue */
WORD msgCount; /* Number of waiting messages */
WORD nextMessage; /* Next message to be retrieved */
WORD nextFreeMessage; /* Next available slot in the queue */
WORD queueSize; /* Size of the queue */
DWORD GetMessageTimeVal; /* Value returned by GetMessageTime */
DWORD GetMessagePosVal; /* Value returned by GetMessagePos */
WORD GetMessageExtraInfoVal; /* Value returned by GetMessageExtraInfo */
DWORD lParam; /* Next four values set by SetMessage */
WORD wParam;
WORD msg;
WORD hWnd;
WORD wPostQMsg; /* PostQuitMessage flag */
WORD wExitCode; /* PostQuitMessage exit code */
WORD InSendMessageHandle; /* Handle of task that sent a message */
WORD tempStatus; /* State reset by GetQueueStatus */
WORD status; /* Queue state */
QMSG messages[1]; /* Queue messages */
} MESSAGEQUEUE;
#endif /* MESSAGE_H */
......@@ -27,10 +27,6 @@ extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt,
extern struct segment_descriptor_s *GetNextSegment(unsigned int flags,
unsigned int limit);
extern unsigned int GLOBAL_Alloc(unsigned int flags, unsigned long size);
extern unsigned int GLOBAL_Free(unsigned int block);
extern void *GLOBAL_Lock(unsigned int block);
extern struct mz_header_s *CurrentMZHeader;
extern struct ne_header_s *CurrentNEHeader;
extern int CurrentNEFile;
......
......@@ -200,3 +200,11 @@ FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name)
return 0;
}
/**********************************************************************
* ReturnArg
*/
int
ReturnArg(int arg)
{
return arg;
}
......@@ -40,9 +40,13 @@ ConvertCoreBitmap(BITMAPCOREHEADER *image, int image_size)
int n_colors;
n_colors = 1 << image->bcBitCount;
handle = GLOBAL_Alloc(GMEM_MOVEABLE,
handle = GlobalAlloc(GMEM_MOVEABLE,
image_size + sizeof(*new_image) + n_colors);
new_image = GLOBAL_Lock(handle);
new_image = GlobalLock(handle);
#ifdef DEBUG_RESOURCE
printf("ConvertCoreBitmap: handle = %04x, new image = %08x\n",
handle, new_image);
#endif
if (new_image == NULL)
return NULL;
......@@ -96,6 +100,11 @@ ConvertCoreBitmap(BITMAPCOREHEADER *image, int image_size)
void *
ConvertInfoBitmap(BITMAPINFOHEADER *image, int image_size)
{
#ifdef DEBUG_RESOURCE
printf("ConvertInfoBitmap: \n");
#endif
return NULL;
}
/**********************************************************************
......@@ -142,6 +151,9 @@ AddResource(int type, void *data)
r->resource_type = type;
r->resource_data = data;
#ifdef DEBUG_RESOURCE
printf("AddResource: return handle %d\n", i + 1);
#endif
/*
* Return a unique handle.
*/
......@@ -325,6 +337,9 @@ RSC_LoadResource(int instance, char *rsc_name, int type)
free(image);
#ifdef DEBUG_RESOURCE
printf("LoadResource: rsc_image = %08x\n", rsc_image);
#endif
/*
* Add to resource list.
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment