diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000000..84079969ed9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,53 @@ +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 diff --git a/Makefile b/Makefile index 43a46838250..f386ccd9598 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -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) diff --git a/README b/README index 078934faa5a..0a911dfb926 100644 --- a/README +++ b/README @@ -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 diff --git a/Windows.tcl b/Windows.tcl deleted file mode 100755 index 0257f1e27f4..00000000000 --- a/Windows.tcl +++ /dev/null @@ -1,91 +0,0 @@ -# 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 -} diff --git a/callback.c b/callback.c index 0cfb00f9582..c0d82bd64f9 100644 --- a/callback.c +++ b/callback.c @@ -1,6 +1,7 @@ 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 ); +} diff --git a/callback.h b/callback.h index b867e43c728..ba845739a33 100644 --- a/callback.h +++ b/callback.h @@ -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 */ diff --git a/class.c b/class.c new file mode 100644 index 00000000000..3a7cf2bbc82 --- /dev/null +++ b/class.c @@ -0,0 +1,141 @@ +/* + * 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; +} diff --git a/class.h b/class.h new file mode 100644 index 00000000000..1e7fa2b9969 --- /dev/null +++ b/class.h @@ -0,0 +1,33 @@ +/* + * 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 */ diff --git a/event.c b/event.c new file mode 100644 index 00000000000..6e65f298de1 --- /dev/null +++ b/event.c @@ -0,0 +1,188 @@ +/* + * X events handling functions + * + * Copyright 1993 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include +#include +#include + +#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 ); +} + diff --git a/global.c b/global.c index 3ef21eebf82..0bef480ee1f 100644 --- a/global.c +++ b/global.c @@ -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; } + /* + * Save position of heap descriptor. + */ + g_prev = g; + /* * We have a new block. Let's create a GDESC entry for it. */ - g_prev = NULL; - i = 0; - for (g = GlobalList; g != NULL; g = g->next, i++) - g_prev = g; - 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; +} diff --git a/heap.c b/heap.c index fa061241ac4..e2aed78e409 100644 --- a/heap.c +++ b/heap.c @@ -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; +} diff --git a/heap.h b/heap.h index 2d8bfa867d6..d602d843de3 100644 --- a/heap.h +++ b/heap.h @@ -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 */ diff --git a/kernel.c b/kernel.c index 24b0e903627..13f30c77610 100644 --- a/kernel.c +++ b/kernel.c @@ -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 */ diff --git a/kernel.spec b/kernel.spec index 1942b75ea59..382630caaad 100644 --- a/kernel.spec +++ b/kernel.spec @@ -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) diff --git a/ldt512.tar b/ldt512.tar new file mode 100644 index 00000000000..978751ce28a Binary files /dev/null and b/ldt512.tar differ diff --git a/message.c b/message.c new file mode 100644 index 00000000000..d013d1d1e5e --- /dev/null +++ b/message.c @@ -0,0 +1,428 @@ +/* + * 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 +#include + +#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; +} + diff --git a/message.h b/message.h new file mode 100644 index 00000000000..0bbfc9a3ef0 --- /dev/null +++ b/message.h @@ -0,0 +1,44 @@ +/* + * 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 */ diff --git a/prototypes.h b/prototypes.h index c03097155fd..39560dd2677 100644 --- a/prototypes.h +++ b/prototypes.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; diff --git a/relay.c b/relay.c index a86b92c4cb1..2331947d2a6 100644 --- a/relay.c +++ b/relay.c @@ -200,3 +200,11 @@ FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name) return 0; } +/********************************************************************** + * ReturnArg + */ +int +ReturnArg(int arg) +{ + return arg; +} diff --git a/resource.c b/resource.c index 93895e1e139..531f9c08f17 100644 --- a/resource.c +++ b/resource.c @@ -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. */ diff --git a/tclIndex b/tclIndex deleted file mode 100644 index 045f1463cad..00000000000 --- a/tclIndex +++ /dev/null @@ -1,12 +0,0 @@ -# Tcl autoload index file: each line identifies a Tcl -# procedure and the file where that procedure is -# defined. Generated by the "auto_mkindex" command. - -CreateWindow Windows.tcl -CreateMenuBar Windows.tcl -AppendMenu Windows.tcl -# Unimplemented stuff -LoadIcon Windows.tcl -LoadCursor Windows.tcl -GetStockObject Windows.tcl -DefWindowProc Windows.tcl diff --git a/tkInt.h b/tkInt.h deleted file mode 100644 index 728847c2636..00000000000 --- a/tkInt.h +++ /dev/null @@ -1,555 +0,0 @@ -/* - * tkInt.h -- - * - * Declarations for things used internally by the Tk - * procedures but not exported outside the module. - * - * Copyright 1990-1992 Regents of the University of California. - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. The University of California - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * $Header: /user6/ouster/wish/RCS/tkInt.h,v 1.84 93/01/23 16:59:14 ouster Exp $ SPRITE (Berkeley) - */ - -#ifndef _TKINT -#define _TKINT - -#ifndef _XLIB_H_ -#include -#endif -#ifndef _XUTIL_H -#include -#endif -#ifndef _TK -#include "tk.h" -#endif -#ifndef _TCL -#include "tcl.h" -#endif -#ifndef _TCLHASH -#include "tclHash.h" -#endif - -/* - * Opaque type declarations: - */ - -typedef struct Tk_PostscriptInfo Tk_PostscriptInfo; -typedef struct TkGrabEvent TkGrabEvent; - -/* - * One of the following structures is maintained for each display - * containing a window managed by Tk: - */ - -typedef struct TkDisplay { - Display *display; /* Xlib's info about display. */ - struct TkDisplay *nextPtr; /* Next in list of all displays. */ - char *name; /* Name of display (with any screen - * identifier removed). Malloc-ed. */ - Time lastEventTime; /* Time of last event received for this - * display. */ - - /* - * Information used by tkFocus.c and tkEvent.c: - */ - - struct TkWindow *focusTopLevelPtr; - /* Pointer to the top-level window that - * currently contains the focus for this - * display. NULL means none of the - * top-levels managed by this application - * contains the focus. */ - int focussedOnEnter; /* Non-zero means the focus was set - * implicitly from an Enter event rather - * than from a FocusIn event. */ - - /* - * Information used primarily by tkBind.c: - */ - - int bindInfoStale; /* Non-zero means the variables in this - * part of the structure are potentially - * incorrect and should be recomputed. */ - unsigned int modeModMask; /* Has one bit set to indicate the modifier - * corresponding to "mode shift". If no - * such modifier, than this is zero. */ - enum {IGNORE, CAPS, SHIFT} lockUsage; - /* Indicates how to interpret lock modifier. */ - - /* - * Information used by tkError.c only: - */ - - struct TkErrorHandler *errorPtr; - /* First in list of error handlers - * for this display. NULL means - * no handlers exist at present. */ - int deleteCount; /* Counts # of handlers deleted since - * last time inactive handlers were - * garbage-collected. When this number - * gets big, handlers get cleaned up. */ - - /* - * Information used by tkSend.c only: - */ - - Tk_Window commWindow; /* Window used for communication - * between interpreters during "send" - * commands. NULL means send info hasn't - * been initialized yet. */ - Atom commProperty; /* X's name for comm property. */ - Atom registryProperty; /* X's name for property containing - * registry of interpreter names. */ - - /* - * Information used by tkSelect.c only: - */ - - Tk_Window selectionOwner; /* Current owner of selection, or - * NULL if selection isn't owned by - * a window in this process. */ - int selectionSerial; /* Serial number of last XSelectionSetOwner - * request we made to server (used to - * filter out redundant SelectionClear - * events. */ - Time selectionTime; /* Timestamp used to acquire selection. */ - Atom multipleAtom; /* Atom for MULTIPLE. None means - * selection stuff isn't initialized. */ - Atom incrAtom; /* Atom for INCR. */ - Atom targetsAtom; /* Atom for TARGETS. */ - Atom timestampAtom; /* Atom for TIMESTAMP. */ - Atom textAtom; /* Atom for TEXT. */ - Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ - Atom applicationAtom; /* Atom for APPLICATION. */ - Atom windowNameAtom; /* Atom for WINDOW_NAME. */ - - /* - * Information used by tkAtom.c only: - */ - - int atomInit; /* 0 means stuff below hasn't been - * initialized yet. */ - Tcl_HashTable nameTable; /* Maps from names to Atom's. */ - Tcl_HashTable atomTable; /* Maps from Atom's back to names. */ - - /* - * Information used by tkCursor.c only: - */ - - Font cursorFont; /* Font to use for standard cursors. - * None means font not loaded yet. */ - - /* - * Information used by tkGrab.c only: - */ - - struct TkWindow *grabWinPtr; - /* Window in which the pointer is currently - * grabbed, or NULL if none. */ - struct TkWindow *eventualGrabWinPtr; - /* Value that grabWinPtr will have once the - * grab event queue (below) has been - * completely emptied. */ - struct TkWindow *buttonWinPtr; - /* Window in which first mouse button was - * pressed while grab was in effect, or NULL - * if no such press in effect. */ - struct TkWindow *serverWinPtr; - /* If no application contains the pointer then - * this is NULL. Otherwise it contains the - * last window for which we've gotten an - * Enter or Leave event from the server (i.e. - * the last window known to have contained - * the pointer). Doesn't reflect events - * that were synthesized in tkGrab.c. */ - TkGrabEvent *firstGrabEventPtr; - /* First in list of enter/leave events - * synthesized by grab code. These events - * must be processed in order before any other - * events are processed. NULL means no such - * events. */ - TkGrabEvent *lastGrabEventPtr; - /* Last in list of synthesized events, or NULL - * if list is empty. */ - int grabFlags; /* Miscellaneous flag values. See definitions - * in tkGrab.c. */ - - /* - * Miscellaneous information: - */ - - Tk_ColorModel *colorModels; /* Array of color models, one per screen; - * indicates whether windows should attempt - * to use full color for display, just mono, - * etc. Malloc'ed. */ -} TkDisplay; - -/* - * One of the following structures exists for each error handler - * created by a call to Tk_CreateErrorHandler. The structure - * is managed by tkError.c. - */ - -typedef struct TkErrorHandler { - TkDisplay *dispPtr; /* Display to which handler applies. */ - unsigned long firstRequest; /* Only errors with serial numbers - * >= to this are considered. */ - unsigned long lastRequest; /* Only errors with serial numbers - * <= to this are considered. This - * field is filled in when XUnhandle - * is called. -1 means XUnhandle - * hasn't been called yet. */ - int error; /* Consider only errors with this - * error_code (-1 means consider - * all errors). */ - int request; /* Consider only errors with this - * major request code (-1 means - * consider all major codes). */ - int minorCode; /* Consider only errors with this - * minor request code (-1 means - * consider all minor codes). */ - Tk_ErrorProc *errorProc; /* Procedure to invoke when a matching - * error occurs. NULL means just ignore - * errors. */ - ClientData clientData; /* Arbitrary value to pass to - * errorProc. */ - struct TkErrorHandler *nextPtr; - /* Pointer to next older handler for - * this display, or NULL for end of - * list. */ -} TkErrorHandler; - -/* - * One of the following structures exists for each event handler - * created by calling Tk_CreateEventHandler. This information - * is used by tkEvent.c only. - */ - -typedef struct TkEventHandler { - unsigned long mask; /* Events for which to invoke - * proc. */ - Tk_EventProc *proc; /* Procedure to invoke when an event - * in mask occurs. */ - ClientData clientData; /* Argument to pass to proc. */ - struct TkEventHandler *nextPtr; - /* Next in list of handlers - * associated with window (NULL means - * end of list). */ -} TkEventHandler; - -/* - * One of the following structures exists for each selection - * handler created by calling Tk_CreateSelHandler. This - * information is used by tkSelect.c only. - */ - -typedef struct TkSelHandler { - Atom target; /* Target type for selection - * conversion, such as TARGETS or - * STRING. */ - Atom format; /* Format in which selection - * info will be returned, such - * as STRING or ATOM. */ - Tk_SelectionProc *proc; /* Procedure to generate selection - * in this format. */ - ClientData clientData; /* Argument to pass to proc. */ - int size; /* Size of units returned by proc - * (8 for STRING, 32 for almost - * anything else). */ - struct TkSelHandler *nextPtr; - /* Next selection handler associated - * with same window (NULL for end of - * list). */ -} TkSelHandler; - -/* - * Tk keeps one of the following data structures for each main - * window (created by a call to Tk_CreateMainWindow). It stores - * information that is shared by all of the windows associated - * with a particular main window. - */ - -typedef struct TkMainInfo { - struct TkWindow *winPtr; /* Pointer to main window. */ - Tcl_Interp *interp; /* Interpreter associated with application. */ - Tcl_HashTable nameTable; /* Hash table mapping path names to TkWindow - * structs for all windows related to this - * main window. Managed by tkWindow.c. */ - Tk_BindingTable bindingTable; - /* Used in conjunction with "bind" command - * to bind events to Tcl commands. */ - struct TkWindow *focusPtr; /* Identifies window that currently has the - * focus (or that will get the focus the next - * time the pointer enters any of the top-level - * windows associated with this main window). - * NULL means nobody has the focus. - * Managed by tkFocus.c. */ - struct TkWindow *focusDefaultPtr; - /* Window that is to receive the focus by - * default when the focusPtr window is - * deleted. */ - struct ElArray *optionRootPtr; - /* Top level of option hierarchy for this - * main window. NULL means uninitialized. - * Managed by tkOption.c. */ -} TkMainInfo; - -/* - * Tk keeps one of the following structures for each window. - * Some of the information (like size and location) is a shadow - * of information managed by the X server, and some is special - * information used here, such as event and geometry management - * information. This information is (mostly) managed by tkWindow.c. - * WARNING: the declaration below must be kept consistent with the - * Tk_ClientWindow structure in tk.h. If you change one, be sure to - * change the other!! - */ - -typedef struct TkWindow { - - /* - * Structural information: - */ - - Display *display; /* Display containing window. */ - TkDisplay *dispPtr; /* Tk's information about display - * for window. */ - int screenNum; /* Index of screen for window, among all - * those for dispPtr. */ - Visual *visual; /* Visual to use for window. If not default, - * MUST be set before X window is created. */ - int depth; /* Number of bits/pixel. */ - Window window; /* X's id for window. NULL means window - * hasn't actually been created yet, or it's - * been deleted. */ - struct TkWindow *childList; /* First in list of child windows, - * or NULL if no children. */ - struct TkWindow *parentPtr; /* Pointer to parent window (logical - * parent, not necessarily X parent), or - * NULL if this is a main window. */ - struct TkWindow *nextPtr; /* Next in list of children with - * same parent (NULL if end of - * list). */ - TkMainInfo *mainPtr; /* Information shared by all windows - * associated with a particular main - * window. NULL means this window is - * a rogue that isn't associated with - * any application (at present, there - * should never be any rogues). */ - - /* - * Name and type information for the window: - */ - - char *pathName; /* Path name of window (concatenation - * of all names between this window and - * its top-level ancestor). This is a - * pointer into an entry in - * mainPtr->nameTable or NULL if mainPtr - * is NULL. */ - Tk_Uid nameUid; /* Name of the window within its parent - * (unique within the parent). */ - Tk_Uid classUid; /* Class of the window. NULL means window - * hasn't been given a class yet. */ - - /* - * Geometry and other attributes of window. This information - * may not be updated on the server immediately; stuff that - * hasn't been reflected in the server yet is called "dirty". - * At present, information can be dirty only if the window - * hasn't yet been created. - */ - - XWindowChanges changes; /* Geometry and other info about - * window. */ - unsigned int dirtyChanges; /* Bits indicate fields of "changes" - * that are dirty. */ - XSetWindowAttributes atts; /* Current attributes of window. */ - unsigned long dirtyAtts; /* Bits indicate fields of "atts" - * that are dirty. */ - - unsigned int flags; /* Various flag values: these are all - * defined in tk.h (confusing, but they're - * needed there for some query macros). */ - - /* - * Information kept by the event manager (tkEvent.c): - */ - - TkEventHandler *handlerList;/* First in list of event handlers - * declared for this window, or - * NULL if none. */ - /* - * Information related to input focussing (tkFocus.c): - */ - - Tk_FocusProc *focusProc; /* Procedure to invoke when this window - * gets or loses the input focus. NULL - * means this window is not prepared to - * receive the focus. */ - ClientData focusData; /* Arbitrary value to pass to focusProc. */ - - /* - * Information used by tkOption.c to manage options for the - * window. - */ - - int optionLevel; /* -1 means no option information is - * currently cached for this window. - * Otherwise this gives the level in - * the option stack at which info is - * cached. */ - /* - * Information used by tkSelect.c to manage the selection. - */ - - TkSelHandler *selHandlerList; - /* First in list of handlers for - * returning the selection in various - * forms. */ - Tk_LostSelProc *selClearProc; - ClientData selClearData; /* Info to pass to selClearProc. */ - - /* - * Information used by tkGeometry.c for geometry management. - */ - - Tk_GeometryProc *geomProc; /* Procedure to handle geometry - * requests (NULL means no window is - * unmanaged). */ - ClientData geomData; /* Argument for geomProc. */ - int reqWidth, reqHeight; /* Arguments from last call to - * Tk_GeometryRequest, or 0's if - * Tk_GeometryRequest hasn't been - * called. */ - int internalBorderWidth; /* Width of internal border of window - * (0 means no internal border). Geom. - * mgr. should not place children on top - * of the border. */ - - /* - * Information maintained by tkWm.c for window manager communication. - */ - - struct TkWmInfo *wmInfoPtr; /* For top-level windows, points to - * structure with wm-related info (see - * tkWm.c). For other windows, this - * is NULL. */ -} TkWindow; - -/* - * The context below is used to map from an X window id to - * the TkWindow structure associated with the window. - */ - -extern XContext tkWindowContext; - -/* - * Pointer to first entry in list of all displays currently known. - */ - -extern TkDisplay *tkDisplayList; - -/* - * Flags passed to TkMeasureChars: - */ - -#define TK_WHOLE_WORDS 1 -#define TK_AT_LEAST_ONE 2 -#define TK_PARTIAL_OK 4 -#define TK_NEWLINES_NOT_SPECIAL 8 - -/* - * Location of library directory containing Tk scripts. This value - * is put in the $tkLibrary variable for each application. - */ - -#ifndef TK_LIBRARY -#define TK_LIBRARY "/usr/local/lib/tk" -#endif - -/* - * Miscellaneous variables shared among Tk modules but not exported - * to the outside world: - */ - -extern Tk_Uid tkActiveUid; -extern Tk_Uid tkDisabledUid; -extern Tk_Uid tkNormalUid; - -/* - * Internal procedures shared among Tk modules but not exported - * to the outside world: - */ - -extern int TkAreaToPolygon _ANSI_ARGS_((double *polyPtr, - int numPoints, double *rectPtr)); -extern void TkBezierPoints _ANSI_ARGS_((double control[], - int numSteps, double *coordPtr)); -extern void TkBindEventProc _ANSI_ARGS_((TkWindow *winPtr, - XEvent *eventPtr)); -extern Time TkCurrentTime _ANSI_ARGS_((TkDisplay *dispPtr)); -extern int TkDeadAppCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -extern void TkDisplayChars _ANSI_ARGS_((Display *display, - Drawable drawable, GC gc, - XFontStruct *fontStructPtr, char *string, - int numChars, int x, int y, int flags)); -extern void TkEventDeadWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern void TkFocusDeadWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern int TkFocusFilterEvent _ANSI_ARGS_((TkWindow *winPtr, - XEvent *eventPtr)); -extern void TkGetButtPoints _ANSI_ARGS_((double p1[], double p2[], - double width, int project, double m1[], - double m2[])); -extern int TkGetInterpNames _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin)); -extern int TkGetMiterPoints _ANSI_ARGS_((double p1[], double p2[], - double p3[], double width, double m1[], - double m2[])); -extern void TkGrabDeadWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern void TkGrabTriggerProc _ANSI_ARGS_((XEvent *eventPtr)); -extern int TkLineToArea _ANSI_ARGS_((double end1Ptr[2], - double end2Ptr[2], double rectPtr[4])); -extern double TkLineToPoint _ANSI_ARGS_((double end1Ptr[2], - double end2Ptr[2], double pointPtr[2])); -extern void TkMakeBezierPostscript _ANSI_ARGS_((Tcl_Interp *interp, - double *pointPtr, int numPoints, - Tk_PostscriptInfo *psInfoPtr)); -extern int TkMeasureChars _ANSI_ARGS_((XFontStruct *fontStructPtr, - char *source, int maxChars, int startX, int maxX, - int flags, int *nextXPtr)); -extern void TkOptionDeadWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern int TkOvalToArea _ANSI_ARGS_((double *ovalPtr, - double *rectPtr)); -extern double TkOvalToPoint _ANSI_ARGS_((double ovalPtr[4], - double width, int filled, double pointPtr[2])); -extern int TkPointerEvent _ANSI_ARGS_((XEvent *eventPtr, - TkWindow *winPtr)); -extern int TkPolygonToArea _ANSI_ARGS_((double *polyPtr, - int numPoints, double *rectPtr)); -extern double TkPolygonToPoint _ANSI_ARGS_((double *polyPtr, - int numPoints, double *pointPtr)); -extern void TkSelDeadWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern void TkSelEventProc _ANSI_ARGS_((Tk_Window tkwin, - XEvent *eventPtr)); -extern void TkSelPropProc _ANSI_ARGS_((XEvent *eventPtr)); -extern void TkUnderlineChars _ANSI_ARGS_((Display *display, - Drawable drawable, GC gc, - XFontStruct *fontStructPtr, char *string, - int x, int y, int flags, int firstChar, - int lastChar)); -extern void TkWmDeadWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern void TkWmMapWindow _ANSI_ARGS_((TkWindow *winPtr)); -extern void TkWmProtocolEventProc _ANSI_ARGS_((TkWindow *winPtr, - XEvent *evenvPtr)); -extern void TkWmSetClass _ANSI_ARGS_((TkWindow *winPtr)); -extern void TkWmNewWindow _ANSI_ARGS_((TkWindow *winPtr)); - -#endif /* _TKINT */ diff --git a/user.c b/user.c index dcc5db6198b..280ba3ff119 100644 --- a/user.c +++ b/user.c @@ -5,6 +5,9 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include "prototypes.h" +#define DEFAULT_MSG_QUEUE_SIZE 8 + + /********************************************************************** * USER_InitApp * @@ -13,5 +16,11 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; int USER_InitApp(int hInstance) { + /* Initialize built-in window classes */ + WIDGETS_Init(); + + /* Create task message queue */ + if (!SetMessageQueue( DEFAULT_MSG_QUEUE_SIZE )) return 0; + return 1; } diff --git a/user.spec b/user.spec index fa9953e99ad..bf14b8057aa 100644 --- a/user.spec +++ b/user.spec @@ -13,14 +13,20 @@ length 540 41 pascal CreateWindow(ptr ptr long word word word word word word word ptr) CreateWindow(1 2 3 4 5 6 7 8 9 10 11) 42 pascal ShowWindow(word word) ShowWindow(1 2) +53 pascal DestroyWindow(word) DestroyWindow(1) 57 pascal RegisterClass(ptr) RegisterClass(1) 66 pascal GetDC(word) GetDC(1) -85 pascal DrawText(word ptr word ptr word) DrawText(1 2 3 4 5) +85 pascal DrawText(word ptr s_word ptr word) DrawText(1 2 3 4 5) 104 pascal MessageBeep(word) MessageBeep(1) 107 pascal DefWindowProc(word word word long) DefWindowProc(1 2 3 4) 108 pascal GetMessage(ptr word word word) GetMessage(1 2 3 4) +109 pascal PeekMessage(ptr word word word word) PeekMessage(1 2 3 4 5) +110 pascal PostMessage(word word word word) PostMessage(1 2 3 4) +111 pascal SendMessage(word word word word) SendMessage(1 2 3 4) 113 pascal TranslateMessage(ptr) TranslateMessage(1) 114 pascal DispatchMessage(ptr) DispatchMessage(1) +119 pascal GetMessagePos() GetMessagePos() +120 pascal GetMessageTime() GetMessageTime() 124 pascal UpdateWindow(word) UpdateWindow(1) 151 pascal CreateMenu() CreateMenu() 157 pascal GetMenu(word) GetMenu(1) @@ -29,4 +35,9 @@ length 540 174 pascal LoadIcon(word ptr) RSC_LoadIcon(1 2) 175 pascal LoadBitmap(word ptr) RSC_LoadBitmap(1 2) 176 pascal LoadString(word word ptr s_word) RSC_LoadString(1 2 3 4) +266 pascal SetMessageQueue(word) SetMessageQueue(1) +288 pascal GetMessageExtraInfo() GetMessageExtraInfo() +334 pascal GetQueueStatus(word) GetQueueStatus(1) +335 pascal GetInputState() GetInputState() +403 pascal UnregisterClass(ptr word) UnregisterClass(1 2) 411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4) diff --git a/widgets.c b/widgets.c new file mode 100644 index 00000000000..f80a23ea12c --- /dev/null +++ b/widgets.c @@ -0,0 +1,121 @@ +/* + * Windows widgets (built-in window classes) + * + * Copyright 1993 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include "windows.h" + + +static LONG WIDGETS_ButtonWndProc( HWND hwnd, WORD message, + WORD wParam, LONG lParam ); +static LONG WIDGETS_StaticWndProc( HWND hwnd, WORD message, + WORD wParam, LONG lParam ); + +#define NB_BUILTIN_CLASSES 2 + +static WNDCLASS WIDGETS_BuiltinClasses[NB_BUILTIN_CLASSES] = +{ + { 0, WIDGETS_ButtonWndProc, 0, 0, 0, 0, 0, 0, NULL, "BUTTON" }, + { 0, WIDGETS_StaticWndProc, 0, 0, 0, 0, 0, 0, NULL, "STATIC" } +}; + +static FARPROC WndProc32[NB_BUILTIN_CLASSES]; + + +/*********************************************************************** + * WIDGETS_Init + * + * Initialize the built-in window classes. + */ +BOOL WIDGETS_Init() +{ + int i; + WNDCLASS * pClass = WIDGETS_BuiltinClasses; + + for (i = 0; i < NB_BUILTIN_CLASSES; i++, pClass++) + { + WndProc32[i] = pClass->lpfnWndProc; + pClass->lpfnWndProc = (FARPROC) i+1; + if (!RegisterClass(pClass)) return FALSE; + } + return TRUE; +} + + +/********************************************************************** + * WIDGETS_Call32WndProc + * + * Call the window procedure of a built-in class. + */ +LONG WIDGETS_Call32WndProc( FARPROC func, HWND hwnd, WORD message, + WORD wParam, LONG lParam ) +{ + unsigned int i = (unsigned int) func; + if (!i || (i > NB_BUILTIN_CLASSES)) return 0; + return (*WndProc32[i-1])( hwnd, message, wParam, lParam ); +} + + +/*********************************************************************** + * WIDGETS_ButtonWndProc + */ +static LONG WIDGETS_ButtonWndProc( HWND hwnd, WORD message, + WORD wParam, LONG lParam ) +{ + switch(message) + { + case WM_CREATE: + return 0; + + case WM_PAINT: + { + HDC hdc; + PAINTSTRUCT ps; + RECT rect; + + hdc = BeginPaint( hwnd, &ps ); + GetClientRect( hwnd, &rect ); + DrawText(hdc, "Button", -1, &rect, + DT_SINGLELINE | DT_CENTER | DT_VCENTER ); + EndPaint( hwnd, &ps ); + return 0; + } + + default: + return DefWindowProc( hwnd, message, wParam, lParam ); + } +} + + +/*********************************************************************** + * WIDGETS_StaticWndProc + */ +static LONG WIDGETS_StaticWndProc( HWND hwnd, WORD message, + WORD wParam, LONG lParam ) +{ + switch(message) + { + case WM_CREATE: + return 0; + + case WM_PAINT: + { + HDC hdc; + PAINTSTRUCT ps; + RECT rect; + + hdc = BeginPaint( hwnd, &ps ); + GetClientRect( hwnd, &rect ); + DrawText(hdc, "Static", -1, &rect, + DT_SINGLELINE | DT_CENTER | DT_VCENTER ); + EndPaint( hwnd, &ps ); + return 0; + } + + default: + return DefWindowProc( hwnd, message, wParam, lParam ); + } +} diff --git a/win.c b/win.c new file mode 100644 index 00000000000..b0373cafc63 --- /dev/null +++ b/win.c @@ -0,0 +1,287 @@ +/* + * Window related functions + * + * Copyright 1993 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include +#include +#include +#include + +#include "class.h" +#include "win.h" + +extern Widget XT_topLevelWidget; + + +static HWND firstWindow = 0; + + +/*********************************************************************** + * WIN_FindWndPtr + * + * Return a pointer to the WND structure corresponding to a HWND. + * The caller must GlobalUnlock the pointer. + */ +WND * WIN_FindWndPtr( HWND hwnd ) +{ + WND * ptr; + + if (!hwnd) return NULL; + ptr = (WND *) GlobalLock( hwnd ); + if (ptr->dwMagic != WND_MAGIC) + { + GlobalUnlock( hwnd ); + return NULL; + } + return ptr; +} + + +/*********************************************************************** + * CreateWindow (USER.41) + */ +HWND CreateWindow( LPSTR className, LPSTR windowName, + DWORD style, int x, int y, int width, int height, + HWND parent, HMENU menu, HANDLE instance, LPSTR data ) +{ + HANDLE class, hwnd; + CLASS *classPtr; + WND *wndPtr, *parentPtr = NULL; + CREATESTRUCT createStruct; + Widget parentWidget = 0; + + printf( "CreateWindow: %s\n", windowName ); + + if (x == CW_USEDEFAULT) x = 0; + if (y == CW_USEDEFAULT) y = 0; + if (width == CW_USEDEFAULT) width = 600; + if (height == CW_USEDEFAULT) height = 400; + + /* Find the parent and class */ + + if (parent) + { + /* Check if parent is valid */ + parentPtr = WIN_FindWndPtr( parent ); + if (!parentPtr) return 0; + } + else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ + + if (!(class = CLASS_FindClassByName( className, &classPtr ))) + { + GlobalUnlock( parent ); + return 0; + } + + /* Create the window structure */ + + hwnd = GlobalAlloc( GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra ); + if (!hwnd) + { + GlobalUnlock( parent ); + GlobalUnlock( class ); + return 0; + } + + /* Fill the structure */ + + wndPtr = (WND *) GlobalLock( hwnd ); + wndPtr->hwndNext = 0; + wndPtr->hwndChild = 0; + wndPtr->dwMagic = WND_MAGIC; + wndPtr->hwndParent = parent; + wndPtr->hwndOwner = parent; /* What else? */ + wndPtr->hClass = class; + wndPtr->hInstance = instance; + wndPtr->rectClient.left = x; + wndPtr->rectClient.top = y; + wndPtr->rectClient.right = x + width; + wndPtr->rectClient.bottom = y + height; + wndPtr->rectWindow = wndPtr->rectClient; + wndPtr->hrgnUpdate = 0; + wndPtr->hwndLastActive = 0; + wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; + wndPtr->dwStyle = style; + wndPtr->hDCE = 0; + wndPtr->hmenuSystem = 0; + wndPtr->wIDmenu = menu; + if (classPtr->wc.cbWndExtra) + memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); + classPtr->cWindows++; + + /* Insert the window in the linked list */ + + if (parent) + { + wndPtr->hwndNext = parentPtr->hwndChild; + parentPtr->hwndChild = hwnd; + } + else /* Top-level window */ + { + wndPtr->hwndNext = firstWindow; + firstWindow = hwnd; + } + + /* Fill the CREATESTRUCT */ + + createStruct.lpCreateParams = data; + createStruct.hInstance = instance; + createStruct.hMenu = menu; + createStruct.hwndParent = parent; + createStruct.cx = width; + createStruct.cy = height; + createStruct.x = x; + createStruct.y = y; + createStruct.style = style; + createStruct.lpszName = windowName; + createStruct.lpszClass = className; + createStruct.dwExStyle = 0; + + /* Create the widgets */ + + if (style & WS_CHILD) + { + wndPtr->shellWidget = 0; + wndPtr->winWidget = XtVaCreateManagedWidget(className, + coreWidgetClass, + parentPtr->winWidget, + XtNx, x, + XtNy, y, + XtNwidth, width, + XtNheight, height, + NULL ); + } + else + { + wndPtr->shellWidget = XtVaAppCreateShell(className, + windowName, + topLevelShellWidgetClass, + XtDisplay(XT_topLevelWidget), + XtNx, x, + XtNy, y, + NULL ); + wndPtr->winWidget = XtVaCreateManagedWidget(className, + compositeWidgetClass, + wndPtr->shellWidget, + XtNwidth, width, + XtNheight, height, + NULL ); + } + + /* Send the WM_CREATE message */ + + if (CallWindowProc( wndPtr->lpfnWndProc, hwnd, + WM_CREATE, 0, (LONG) &createStruct ) == -1) + { + /* Abort window creation */ + if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); + else XtDestroyWidget( wndPtr->winWidget ); + GlobalUnlock( parent ); + GlobalUnlock( class ); + GlobalUnlock( hwnd ); + GlobalFree( hwnd ); + return 0; + } + + EVENT_AddHandlers( wndPtr->winWidget, hwnd ); + + GlobalUnlock( parent ); + GlobalUnlock( class ); + GlobalUnlock( hwnd ); + return hwnd; +} + +/*********************************************************************** + * DestroyWindow (USER.53) + */ +BOOL DestroyWindow( HWND hwnd ) +{ + WND *wndPtr, *parentPtr; + CLASS * classPtr; + + wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr) return FALSE; + + if (wndPtr->hwndParent) + { + parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); + printf( "INTERNAL ERROR: DestroyWindow: Invalid window parent\n" ); + return FALSE; + } + + classPtr = CLASS_FindClassPtr( wndPtr->hClass ); + if (!classPtr) + { + printf( "INTERNAL ERROR: DestroyWindow: Invalid window class\n" ); + return FALSE; + } + + SendMessage( hwnd, WM_DESTROY, 0, 0 ); + + /* Destroy all children */ + + /* ........... */ + + /* Remove the window from the linked list */ + + /* ........... */ + + /* Destroy the window */ + + if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); + else XtDestroyWidget( wndPtr->winWidget ); + classPtr->cWindows--; + GlobalUnlock( wndPtr->hClass ); + if (wndPtr->hwndParent) GlobalUnlock( wndPtr->hwndParent ); + GlobalUnlock( hwnd ); + GlobalFree( hwnd ); + return TRUE; +} + + +/*********************************************************************** + * GetClientRect (USER.33) + */ +void GetClientRect( HWND hwnd, LPRECT rect ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + rect->left = rect->top = rect->right = rect->bottom = 0; + if (wndPtr) + { + XtVaGetValues(wndPtr->winWidget, + XtNwidth, &rect->right, + XtNheight, &rect->bottom, + NULL ); + GlobalUnlock( hwnd ); + } +} + + +/*********************************************************************** + * ShowWindow (USER.42) + */ +BOOL ShowWindow( HWND hwnd, int cmd ) +{ + WND * wndPtr = WIN_FindWndPtr( hwnd ); + if (wndPtr) + { + if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); + GlobalUnlock( hwnd ); + } + return TRUE; +} + + +/*********************************************************************** + * UpdateWindow (USER.124) + */ +void UpdateWindow( HWND hwnd ) +{ + SendMessage( hwnd, WM_PAINT, 0, 0 ); +} + + diff --git a/win.h b/win.h new file mode 100644 index 00000000000..93162ab6576 --- /dev/null +++ b/win.h @@ -0,0 +1,50 @@ +/* + * Window definitions + * + * Copyright 1993 Alexandre Julliard + */ + +#ifndef WIN_H +#define WIN_H + +#include +#include +#include + +#include "windows.h" + + +#define WND_MAGIC 0x444e4957 /* 'WIND' */ + + +typedef struct tagWND +{ + HWND hwndNext; /* Next sibling */ + HWND hwndChild; /* First child */ + DWORD dwMagic; /* Magic number (must be WND_MAGIC) */ + HWND hwndParent; /* Window parent (from CreateWindow) */ + HWND hwndOwner; /* Window owner */ + HCLASS hClass; /* Window class */ + HANDLE hInstance; /* Window hInstance (from CreateWindow) */ + RECT rectClient; /* Window client area screen coords */ + RECT rectWindow; /* Window whole area screen coords */ + HRGN hrgnUpdate; /* Update region */ + HWND hwndLastActive; /* Last active popup hwnd */ + FARPROC lpfnWndProc; /* Window procedure */ + DWORD dwStyle; /* Window style (from CreateWindow) */ + HANDLE hDCE; /* Window DC Entry (if CS_OWNDC) */ + HMENU hmenuSystem; /* System menu */ + WORD wIDmenu; /* ID or hmenu (from CreateWindow) */ + Widget shellWidget; /* For top-level windows */ + Widget winWidget; /* For all windows */ + WORD wExtra[1]; /* Window extra bytes */ +} WND; + + + /* The caller must GlobalUnlock the pointer returned + * by this function (except when NULL). + */ +WND * WIN_FindWndPtr( HWND hwnd ); + + +#endif /* WIN_H */ diff --git a/windows.h b/windows.h index c97f5fed20c..f8ae2beb502 100644 --- a/windows.h +++ b/windows.h @@ -1,5 +1,8 @@ /* Initial draft attempt of windows.h, by Peter MacDonald, pmacdona@sanjuan.uvic.ca */ +#ifndef WINDOWS_H +#define WINDOWS_H + #ifndef _WINARGS typedef unsigned short WORD; @@ -12,19 +15,20 @@ typedef long LONG; typedef WORD HANDLE; typedef HANDLE HWND; typedef HANDLE HDC; +typedef HANDLE HCLASS; typedef HANDLE HCURSOR; typedef HANDLE HFONT; typedef HANDLE HPEN; typedef HANDLE HRGN; typedef HANDLE HPALETTE; typedef HANDLE HICON; +typedef HANDLE HINSTANCE; typedef HANDLE HMENU; typedef HANDLE HBITMAP; typedef HANDLE HBRUSH; typedef HANDLE LOCALHANDLE; typedef char *LPSTR; typedef char *NPSTR; -typedef char *LPMSG; typedef int *LPINT; typedef void *LPVOID; typedef long (*FARPROC)(); @@ -66,25 +70,44 @@ typedef struct { HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; - LPSTR lpszMenuName, lpszClassName; + LPSTR lpszMenuName __attribute__ ((packed)); + LPSTR lpszClassName __attribute__ ((packed)); } WNDCLASS; typedef WNDCLASS * PWNDCLASS; typedef WNDCLASS * NPWNDCLASS; typedef WNDCLASS * LPWNDCLASS; -typedef struct { int x, y; } POINT; +typedef struct { + void * lpCreateParams; + HINSTANCE hInstance; + HMENU hMenu; + HWND hwndParent; + short cy; + short cx; + short y; + short x; + LONG style __attribute__ ((packed)); + char * lpszName __attribute__ ((packed)); + char * lpszClass __attribute__ ((packed)); + DWORD dwExStyle __attribute__ ((packed)); +} CREATESTRUCT, *LPCREATESTRUCT; + + +typedef struct { short x, y; } POINT; typedef POINT *PPOINT; typedef POINT *NPPOINT; typedef POINT *LPPOINT; -typedef struct { - HWND hwnd; - WORD message, wParam; - long lParam; - DWORD time; - POINT pt; -} MSG; +typedef struct tagMSG +{ + HWND hwnd; + WORD message; + WORD wParam; + DWORD lParam __attribute__ ((packed)); + DWORD time __attribute__ ((packed)); + POINT pt __attribute__ ((packed)); +} MSG, *LPMSG; typedef WORD ATOM; @@ -270,7 +293,57 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE WM_DELETEITEM, WM_VKEYTOITEM, WM_CHARTOITEM, WM_SETFONT, WM_GETFONT }; -#define WM_COMMAND 0x0111 + /* Keyboard messages */ +#define WM_KEYDOWN 0x0100 +#define WM_KEYUP 0x0101 +#define WM_CHAR 0x0102 +#define WM_DEADCHAR 0x0103 +#define WM_SYSKEYDOWN 0x0104 +#define WM_SYSKEYUP 0x0105 +#define WM_SYSCHAR 0x0106 +#define WM_SYSDEADCHAR 0x0107 +#define WM_KEYFIRST WM_KEYDOWN +#define WM_KEYLAST 0x0108 + +#define WM_COMMAND 0x0111 +#define WM_TIMER 0x0113 + + /* Mouse messages */ +#define WM_MOUSEMOVE 0x0200 +#define WM_LBUTTONDOWN 0x0201 +#define WM_LBUTTONUP 0x0202 +#define WM_LBUTTONDBLCLK 0x0203 +#define WM_RBUTTONDOWN 0x0204 +#define WM_RBUTTONUP 0x0205 +#define WM_RBUTTONDBLCLK 0x0206 +#define WM_MBUTTONDOWN 0x0207 +#define WM_MBUTTONUP 0x0208 +#define WM_MBUTTONDBLCLK 0x0209 +#define WM_MOUSEFIRST WM_MOUSEMOVE +#define WM_MOUSELAST WM_MBUTTONDBLCLK + + /* Key status flags for mouse events */ +#define MK_LBUTTON 0x0001 +#define MK_RBUTTON 0x0002 +#define MK_SHIFT 0x0004 +#define MK_CONTROL 0x0008 +#define MK_MBUTTON 0x0010 + + /* Queue status flags */ +#define QS_KEY 0x0001 +#define QS_MOUSEMOVE 0x0002 +#define QS_MOUSEBUTTON 0x0004 +#define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON) +#define QS_POSTMESSAGE 0x0008 +#define QS_TIMER 0x0010 +#define QS_PAINT 0x0020 +#define QS_SENDMESSAGE 0x0040 +#define QS_ALLINPUT 0x007f + + /* PeekMessage() options */ +#define PM_NOREMOVE 0x0000 +#define PM_REMOVE 0x0001 +#define PM_NOYIELD 0x0002 enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, SW_MAXIMIZE, SW_SHOWNOACTIVATE, SW_SHOW, SW_MINIMIZE, @@ -400,16 +473,23 @@ int wsprintf(LPSTR a,LPSTR b,...); /* Implemented functions */ F(HMENU,CreateMenu) +F(BOOL,GetInputState) +F(LPSTR,GetDOSEnvironment) +F(DWORD,GetMessagePos) +F(LONG,GetMessageTime) +F(LONG,GetMessageExtraInfo) Fa(BOOL,IsCharAlpha,char,ch) Fa(BOOL,IsCharAlphaNumeric,char,ch) Fa(BOOL,IsCharLower,char,ch) Fa(BOOL,IsCharUpper,char,ch) -Fa(BOOL,RegisterClass,LPWNDCLASS,a) +Fa(ATOM,RegisterClass,LPWNDCLASS,a) Fa(BOOL,TranslateMessage,LPMSG,a) +Fa(void,PostQuitMessage,int,a) +Fa(BOOL,SetMessageQueue,int,a) Fa(int,_lclose,int,a) Fb(int,_lopen,LPSTR,a,int,b) Fa(int,lstrlen,LPSTR,a) -Fa(long,DispatchMessage,MSG *,msg) +Fa(LONG,DispatchMessage,LPMSG,msg) Fa(void,UpdateWindow,HWND,a) Fb(BOOL,ExitWindows,DWORD,dwReserved,WORD,wReturnCode) Fb(BOOL,ShowWindow,HWND,a,int,b) @@ -421,6 +501,7 @@ Fb(int,lstrcmp,LPSTR,a,LPSTR,b ) Fb(int,lstrcmpi,LPSTR,a,LPSTR,b ) Fb(void,EndPaint,HWND,a,LPPAINTSTRUCT,b) Fb(void,GetClientRect,HWND,a,LPRECT,b) +Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b) Fc(BOOL,LineTo,HDC,a,int,b,int,c) Fc(LONG,_llseek,int,a,long,b,int,c) Fc(WORD,_lread,int,a,LPSTR,b,int,c) @@ -428,9 +509,13 @@ Fc(WORD,_lwrite,int,a,LPSTR,b,int,c) Fc(int,FillRect,HDC,a,LPRECT,b,HBRUSH,c) Fc(DWORD,MoveTo,HDC,a,int,b,int,c) Fd(BOOL,AppendMenu,HMENU,a,WORD,b,WORD,c,LPSTR,d) +Fd(BOOL,PostMessage,HWND,a,WORD,b,WORD,c,LONG,d) +Fd(LONG,SendMessage,HWND,a,WORD,b,WORD,c,LONG,d) Fd(BOOL,GetMessage,LPMSG,msg,HWND,b,WORD,c,WORD,d) Fe(BOOL,Rectangle,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom) Fe(int,DrawText,HDC,a,LPSTR,str,int,c,LPRECT,d,WORD,flag) +Fe(BOOL,PeekMessage,LPMSG,a,HWND,b,WORD,c,WORD,d,WORD,e) +Fe(LONG,CallWindowProc,FARPROC,a,HWND,b,WORD,c,WORD,d,LONG,e) Fi(BOOL,Arc,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd) Fi(BOOL,Chord,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd) Fi(BOOL,Pie,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd) @@ -440,10 +525,8 @@ Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,int,x,int,y,int,w,int, F(BOOL,AnyPopup) F(BOOL,CloseClipboard) F(BOOL,EmptyClipboard) -F(BOOL,GetInputState) F(BOOL,InSendMessage) F(DWORD,GetCurrentTime) -F(DWORD,GetMessagePos) F(DWORD,GetTickCount) F(HANDLE,GetCurrentTask) F(HMENU,CreatePopupMenu) @@ -456,10 +539,8 @@ F(HWND,GetDesktopWindow) F(HWND,GetFocus) F(HWND,GetSysModalWindow) F(LONG,GetMenuCheckMarkDimensions) -F(LONG,GetMessageTime) F(LONG,GetWinFlags) F(LPINT,GetThresholdEvent) -/*F(LPSTR,GetDOSEnvironment)*/ F(LPSTR,ValidateFreeSpaces) F(void,ValidateCodeSegments) F(WORD,GetCaretBlinkTime) @@ -521,7 +602,6 @@ Fa(BOOL,OpenClipboard,HWND,a) Fa(BOOL,OpenIcon,HWND,a) Fa(BOOL,RemoveFontResource,LPSTR,a) Fa(BOOL,SetErrorMode,WORD,a) -Fa(BOOL,SetMessageQueue,int,a) Fa(BOOL,SwapMouseButton,BOOL,a) Fa(BOOL,UnrealizeObject,HBRUSH,a) Fa(BYTE,GetTempDrive,BYTE,a) @@ -656,7 +736,6 @@ Fa(void,GetKeyboardState,BYTE FAR*,a) Fa(void,HideCaret,HWND,a) Fa(void,MessageBeep,WORD,a) Fa(void,OutputDebugString,LPSTR,a) -Fa(void,PostQuitMessage,int,a) Fa(void,ReplyMessage,LONG,a) Fa(void,SetCaretBlinkTime,WORD,a) Fa(void,SetDoubleClickTime,WORD,a) @@ -688,7 +767,6 @@ Fb(BOOL,SetConvertParams,int,a,int,b) Fb(BOOL,SetMenu,HWND,a,HMENU,b) Fb(BOOL,TranslateMDISysAccel,HWND,a,LPMSG,b) Fb(BOOL,UnhookWindowsHook,int,a,FARPROC,b) -Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b) Fb(DWORD,GetNearestColor,HDC,a,DWORD,b) Fb(DWORD,SetBkColor,HDC,a,DWORD,b) Fb(DWORD,SetMapperFlags,HDC,a,DWORD,b) @@ -885,7 +963,6 @@ Fd(BOOL,GetCharWidth,HDC,a,WORD,b,WORD,c,LPINT,d) Fd(BOOL,HiliteMenuItem,HWND,a,HMENU,b,WORD,c,WORD,d) Fd(BOOL,PolyPolygon,HDC,a,LPPOINT,b,LPINT,c,int,d) Fd(BOOL,PostAppMessage,HANDLE,a,WORD,b,WORD,c,LONG,d) -Fd(BOOL,PostMessage,HWND,a,WORD,b,WORD,c,LONG,d) Fd(BOOL,WinHelp,HWND,hwndMain,LPSTR,lpszHelp,WORD,usCommand,DWORD,ulData) Fd(BOOL,WritePrivateProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d) Fd(DWORD,DefHookProc,int,a,WORD,b,DWORD,c,FARPROC FAR*,d) @@ -900,7 +977,6 @@ Fd(HWND,CreateDialogIndirect,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d) Fd(LONG,DefDlgProc,HWND,a,WORD,b,WORD,c,LONG,d) Fd(LONG,DefMDIChildProc,HWND,a,WORD,b,WORD,c,LONG,d) Fd(LONG,DefWindowProc,HWND,a,WORD,b,WORD,c,LONG,d) -Fd(LONG,SendMessage,HWND,a,WORD,b,WORD,c,LONG,d) Fd(WORD,GetDlgItemInt,HWND,a,int,b,BOOL FAR*,c,BOOL,d) Fd(WORD,GetPaletteEntries,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d) Fd(WORD,GetPrivateProfileInt,LPSTR,a,LPSTR,b,int,c,LPSTR,d) @@ -931,7 +1007,6 @@ Fe(BOOL,ExtFloodFill,HDC,a,int,b,int,c,DWORD,d,WORD,e) Fe(BOOL,FrameRgn,HDC,a,HRGN,b,HBRUSH,e,int,c,int,d) Fe(BOOL,InsertMenu,HMENU,a,WORD,b,WORD,c,WORD,d,LPSTR,e) Fe(BOOL,ModifyMenu,HMENU,a,WORD,b,WORD,c,WORD,d,LPSTR,e) -Fe(BOOL,PeekMessage,LPMSG,a,HWND,b,WORD,c,WORD,d,WORD,e) Fe(BOOL,SetMenuItemBitmaps,HMENU,a,WORD,b,WORD,c,HBITMAP,d,HBITMAP,e) Fe(BOOL,TextOut,HDC,a,int,b,int,c,LPSTR,d,int,e) Fe(DWORD,GetTabbedTextExtent,HDC,a,LPSTR,b,int,c,int,d,LPINT,e) @@ -940,7 +1015,6 @@ Fe(DWORD,ScaleWindowExt,HDC,a,int,b,int,c,int,d,int,e) Fe(HBITMAP,CreateBitmap,int,a,int,b,BYTE,c,BYTE,d,LPSTR,e) Fe(HWND,CreateDialogIndirectParam,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d,LONG,e) Fe(HWND,CreateDialogParam,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d,LONG,e) -Fe(LONG,CallWindowProc,FARPROC,a,HWND,b,WORD,c,WORD,d,LONG,e) Fe(LONG,DefFrameProc,HWND,a,HWND,b,WORD,c,WORD,d,LONG,e) Fe(LONG,SendDlgItemMessage,HWND,a,int,b,WORD,c,WORD,d,LONG,e) Fe(int,DialogBoxIndirectParam,HANDLE,a,HANDLE,b,HWND,c,FARPROC,d,LONG,e) @@ -982,3 +1056,5 @@ Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,int,e,int,f,int,g,int,h,H Fl(int,SetDIBitsToDevice,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l) Fm(int,StretchDIBits,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l,DWORD,m) Fn(HFONT,CreateFont,int,a,int,b,int,c,int,d,int,e,BYTE,f,BYTE,g,BYTE,h,BYTE,i,BYTE,j,BYTE,k,BYTE,l,BYTE,m,LPSTR,n) + +#endif /* WINDOWS_H */ diff --git a/wintcl.c b/wintcl.c deleted file mode 100644 index a9bdbb9cbfd..00000000000 --- a/wintcl.c +++ /dev/null @@ -1,858 +0,0 @@ -#define _WINMAIN -/* - * main.c -- - * - * This file contains the main program for "wish", a windowing - * shell based on Tk and Tcl. It also provides a template that - * can be used as the basis for main programs for other Tk - * applications. - * - * Copyright 1990-1992 Regents of the University of California. - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. The University of California - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * Modifiyed by Peter MacDonald for windows API. - */ - -#ifndef lint -static char rcsid[] = "$Header: /user6/ouster/wish/RCS/main.c,v 1.72 93/02/03 10:20:42 ouster Exp $ SPRITE (Berkeley)"; -#endif - - -#include -#include -#include "tkConfig.h" -#include "tkInt.h" - -#include "callback.h" - -#define dprintf(n,s) dodprintf(s) - -void dodprintf(char *str, ... ) -{ - va_list va; - char buf[2000]; - va_start(va, str); - vsprintf(buf,str,va); - puts(buf); - va_end(str); -} - -#define TK_EXTENDED -#ifdef TK_EXTENDED -# include "tclExtend.h" - extern Tcl_Interp *tk_mainInterp; /* Need to process signals */ -#endif - -/* - * Declarations for library procedures: - */ - -extern int isatty(); - -/* - * Command used to initialize wish: - */ - -#ifdef TK_EXTENDED -static char initCmd[] = "load wishx.tcl"; -#else -static char initCmd[] = "source $tk_library/wish.tcl"; -#endif - -/* - * Global variables used by the main program: - */ - -static Tk_Window w; /* The main window for the application. If - * NULL then the application no longer - * exists. */ -static Tcl_Interp *interp; /* Interpreter for this application. */ -static int x, y; /* Coordinates of last location moved to; - * used by "moveto" and "lineto" commands. */ -static Tcl_CmdBuf buffer; /* Used to assemble lines of terminal input - * into Tcl commands. */ -static int tty; /* Non-zero means standard input is a - * terminal-like device. Zero means it's - * a file. */ - -/* - * Command-line options: - */ - -int synchronize = 0; -char *fileName = NULL; -char *name = NULL; -char *display = NULL; -char *geometry = NULL; - -Tk_ArgvInfo argTable[] = { - {"-file", TK_ARGV_STRING, (char *) NULL, (char *) &fileName, - "File from which to read commands"}, - {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry, - "Initial geometry for window"}, - {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display, - "Display to use"}, - {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name, - "Name to use for application"}, - {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, - "Use synchronous mode for display server"}, - {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, - (char *) NULL} -}; - -/* - * Declaration for Tcl command procedure to create demo widget. This - * procedure is only invoked if SQUARE_DEMO is defined. - */ - -extern int Tk_SquareCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); - -/* - * Forward declarations for procedures defined later in this file: - */ - -static void DelayedMap _ANSI_ARGS_((ClientData clientData)); -static int LinetoCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -static int MovetoCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -static void StdinProc _ANSI_ARGS_((ClientData clientData, - int mask)); -static void StructureProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static int _WinCallBack _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -static int _getStrHandle _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); - - -/* - *---------------------------------------------------------------------- - * - * main -- - * - * Main program for Wish. - * - * Results: - * None. This procedure never returns (it exits the process when - * it's done - * - * Side effects: - * This procedure initializes the wish world and then starts - * interpreting commands; almost anything could happen, depending - * on the script being interpreted. - * - *---------------------------------------------------------------------- - */ - -int -main( int argc, /* Number of arguments. */ - char **argv) /* Array of argument strings. */ -{ - char *args, *p, *msg; - char buf[20]; char bigBuf[300]; - int result; - Tk_3DBorder border; - -#ifdef TK_EXTENDED - tk_mainInterp = interp = Tcl_CreateExtendedInterp(); -#else - interp = Tcl_CreateInterp(); -#endif -#ifdef TCL_MEM_DEBUG - Tcl_InitMemory(interp); -#endif - - /* - * Parse command-line arguments. - */ - -#if 0 - if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, argTable, 0) - != TCL_OK) { - fprintf(stderr, "%s\n", interp->result); - exit(1); - } -#endif - if (name == NULL) { - if (fileName != NULL) { - p = fileName; - } else { - p = argv[0]; - } - name = strrchr(p, '/'); - if (name != NULL) { - name++; - } else { - name = p; - } - } - - /* - * Initialize the Tk application and arrange to map the main window - * after the startup script has been executed, if any. This way - * the script can withdraw the window so it isn't ever mapped - * at all. - */ - - w = Tk_CreateMainWindow(interp, display, name); - if (w == NULL) { - fprintf(stderr, "%s\n", interp->result); - exit(1); - } - Tk_SetClass(w, "Tk"); - Tk_CreateEventHandler(w, StructureNotifyMask, StructureProc, - (ClientData) NULL); - Tk_DoWhenIdle(DelayedMap, (ClientData) NULL); - if (synchronize) { - XSynchronize(Tk_Display(w), True); - } - Tk_GeometryRequest(w, 200, 200); - border = Tk_Get3DBorder(interp, w, None, "#ffe4c4"); - if (border == NULL) { - Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); - Tk_SetWindowBackground(w, WhitePixelOfScreen(Tk_Screen(w))); - } else { - Tk_SetBackgroundFromBorder(w, border); - } - XSetForeground(Tk_Display(w), DefaultGCOfScreen(Tk_Screen(w)), - BlackPixelOfScreen(Tk_Screen(w))); - - /* - * Make command-line arguments available in the Tcl variables "argc" - * and "argv". Also set the "geometry" variable from the geometry - * specified on the command line. - */ - -#if 0 - args = Tcl_Merge(argc-1, argv+1); - Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY); - ckfree(args); - sprintf(buf, "%d", argc-1); - Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY); -#endif - if (geometry != NULL) { - Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY); - } - - /* - * Add a few application-specific commands to the application's - * interpreter. - */ - - Tcl_CreateCommand(interp, "lineto", LinetoCmd, (ClientData) w, - (void (*)()) NULL); - Tcl_CreateCommand(interp, "moveto", MovetoCmd, (ClientData) w, - (void (*)()) NULL); -#ifdef SQUARE_DEMO - Tcl_CreateCommand(interp, "square", Tk_SquareCmd, (ClientData) w, - (void (*)()) NULL); -#endif - Tcl_CreateCommand(interp, "wincallback", _WinCallBack, (ClientData) w, - (void (*)()) NULL); - Tcl_CreateCommand(interp, "getstrhandle", _getStrHandle, (ClientData) w, - (void (*)()) NULL); - - /* - * Execute Wish's initialization script, followed by the script specified - * on the command line, if any. - */ - -#ifdef TK_EXTENDED - tclAppName = "Wish"; - tclAppLongname = "Wish - Tk Shell"; - tclAppVersion = TK_VERSION; - Tcl_ShellEnvInit (interp, TCLSH_ABORT_STARTUP_ERR, - name, - 0, NULL, /* argv var already set */ - fileName == NULL, /* interactive? */ - NULL); /* Standard default file */ -#endif - result = Tcl_Eval(interp, initCmd, 0, (char **) NULL); - if (result != TCL_OK) { - goto error; - } - strcpy(bigBuf, Tcl_GetVar(interp, "auto_path", TCL_GLOBAL_ONLY)); - strcat(bigBuf," /usr/local/windows"); - Tcl_SetVar(interp, "auto_path", bigBuf, TCL_GLOBAL_ONLY); - dprintf(4,("set auto_path \"$auto_path /usr/local/windows\"")); - if (result != TCL_OK) { - goto error; - } -#if 0 - tty = isatty(0); - if (fileName != NULL) { - result = Tcl_VarEval(interp, "source ", fileName, (char *) NULL); - if (result != TCL_OK) { - goto error; - } - tty = 0; - } else { - /* - * Commands will come from standard input. Set up a handler - * to receive those characters and print a prompt if the input - * device is a terminal. - */ - - Tk_CreateFileHandler(0, TK_READABLE, StdinProc, (ClientData) 0); - if (tty) { - printf("wish: "); - } - } -#endif - fflush(stdout); - buffer = Tcl_CreateCmdBuf(); - (void) Tcl_Eval(interp, "update", 0, (char **) NULL); - - /* - * Loop infinitely, waiting for commands to execute. When there - * are no windows left, Tk_MainLoop returns and we clean up and - * exit. - */ -/* Tcl_Eval( interp, "button .hello -text \"Hello, world\" -command {\n puts stdout \"Hello, world\"; destroy .\n\ -}\n pack append . .hello {top}\n", 0, (char **)NULL); */ - _WinMain(argc,argv); - Tcl_DeleteInterp(interp); - Tcl_DeleteCmdBuf(buffer); - exit(0); - -error: - msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); - if (msg == NULL) { - msg = interp->result; - } - fprintf(stderr, "%s\n", msg); - Tcl_Eval(interp, "destroy .", 0, (char **) NULL); - exit(1); - return 0; /* Needed only to prevent compiler warnings. */ -} - -/* - *---------------------------------------------------------------------- - * - * StdinProc -- - * - * This procedure is invoked by the event dispatcher whenever - * standard input becomes readable. It grabs the next line of - * input characters, adds them to a command being assembled, and - * executes the command if it's complete. - * - * Results: - * None. - * - * Side effects: - * Could be almost arbitrary, depending on the command that's - * typed. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -static void -StdinProc(clientData, mask) - ClientData clientData; /* Not used. */ - int mask; /* Not used. */ -{ -#define BUFFER_SIZE 4000 - char input[BUFFER_SIZE+1]; - static int gotPartial = 0; - char *cmd; - int result, count; - -count=strlen(input); - if (count <= 0) { - if (!gotPartial) { - if (tty) { - Tcl_Eval(interp, "destroy .", 0, (char **) NULL); - exit(0); - } else { - Tk_DeleteFileHandler(0); - } - return; - } else { - input[0] = 0; - } - } else { - input[count] = 0; - } - cmd = Tcl_AssembleCmd(buffer, input); - if (cmd == NULL) { - gotPartial = 1; - return; - } - gotPartial = 0; - result = Tcl_RecordAndEval(interp, cmd, 0); - if (*interp->result != 0) { - if ((result != TCL_OK) || (tty)) { - printf("%s\n", interp->result); - } - } - if (tty) { - printf("wish: "); - fflush(stdout); - } -} - -/* - *---------------------------------------------------------------------- - * - * StructureProc -- - * - * This procedure is invoked whenever a structure-related event - * occurs on the main window. If the window is deleted, the - * procedure modifies "w" to record that fact. - * - * Results: - * None. - * - * Side effects: - * Variable "w" may get set to NULL. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -static void -StructureProc(clientData, eventPtr) - ClientData clientData; /* Information about window. */ - XEvent *eventPtr; /* Information about event. */ -{ - if (eventPtr->type == DestroyNotify) { - w = NULL; - } -} - -/* - *---------------------------------------------------------------------- - * - * DelayedMap -- - * - * This procedure is invoked by the event dispatcher once the - * startup script has been processed. It waits for all other - * pending idle handlers to be processed (so that all the - * geometry information will be correct), then maps the - * application's main window. - * - * Results: - * None. - * - * Side effects: - * The main window gets mapped. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -static void -DelayedMap(clientData) - ClientData clientData; /* Not used. */ -{ - - while (Tk_DoOneEvent(TK_IDLE_EVENTS) != 0) { - /* Empty loop body. */ - } - if (w == NULL) { - return; - } - Tk_MapWindow(w); -} - -/* - *---------------------------------------------------------------------- - * - * MoveToCmd and LineToCmd -- - * - * This procedures are registered as the command procedures for - * "moveto" and "lineto" Tcl commands. They provide a trivial - * drawing facility. They don't really work right, in that the - * drawn information isn't persistent on the screen (it will go - * away if the window is iconified and de-iconified again). The - * commands are here partly for testing and partly to illustrate - * how to add application-specific commands to Tk. You probably - * shouldn't use these commands in any real scripts. - * - * Results: - * The procedures return standard Tcl results. - * - * Side effects: - * The screen gets modified. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -static int -MovetoCmd(dummy, interp, argc, argv) - ClientData dummy; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ -{ - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " x y\"", (char *) NULL); - return TCL_ERROR; - } - x = strtol(argv[1], (char **) NULL, 0); - y = strtol(argv[2], (char **) NULL, 0); - return TCL_OK; -} - /* ARGSUSED */ -static int -LinetoCmd(dummy, interp, argc, argv) - ClientData dummy; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ -{ - int newX, newY; - - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " x y\"", (char *) NULL); - return TCL_ERROR; - } - newX = strtol(argv[1], (char **) NULL, 0); - newY = strtol(argv[2], (char **) NULL, 0); - Tk_MakeWindowExist(w); - XDrawLine(Tk_Display(w), Tk_WindowId(w), - DefaultGCOfScreen(Tk_Screen(w)), x, y, newX, newY); - x = newX; - y = newY; - return TCL_OK; -} - -/*===============================================================*/ - -#define _WIN_CODE_SECTION -static int dte(char *str,...); -#include -#include - - -LPWNDCLASS LpWndClass; - -static int tclexec(char *str, ... ) -{ int result; - va_list va; - char buf[2000]; - va_start(va, str); - vsprintf(buf,str,va); - dprintf(32,("tclexec'ing:%s",buf)); - result = Tcl_Eval( interp, buf, 0, (char **)NULL); - va_end(str); - if (result != TCL_OK) - { printf("error evaluating %s\n", buf); - fprintf(stderr, "%s\n", interp->result); - exit(-1); - } - return(result); -} - -static void str2lower(char *str) -{ - while (*str) - { *str = tolower(*str); - str++; - } -} - -static char *_handles[300]; -static int _handInd=0; - -static char* getStrHandle(int hndl) -{ static char buf[20]; - if((hndl<_handInd) && (hndl>=0)) - return(_handles[hndl]); - sprintf(buf, "%d", hndl); - return(buf); -} - -static int findHandle(char* str) -{ int i; - for (i=0; i<_handInd; i++) - if (!strcmp(str,_handles[i])) - return(i); - return(-1); -} - -typedef enum {enum_win, enum_frame, enum_canvas, enum_button, enum_menu} class_enum; - -static int allocStrHandle(char *seed, class_enum class) -{ - static char *classes[]= {"win", "frame", "canvas", "button", "menu"}; - static int classInds[10] = { 0, 0, 0, 0, 0, 0}; - char buf[200]; - assert((class>=0) && (class<=4)); - if (seed && *seed) - sprintf(buf,"%s.%s%d", seed, classes[class], ++classInds[class]); - else - sprintf(buf,"%s%d", classes[class], ++classInds[class]); - str2lower(buf); - _handles[_handInd]=strdup(buf); - return(_handInd++); -} - -#if 0 -static _WinMain(int argc, char *argv[]) -{ int i; char buf[300]; - - *buf = 0; - for (i=1; i2) - { if (!strcmp(argv[1],"menu")) - { -#if 0 - LpWndClass->lpfnWndProc(findHandle(argv[2]), - WM_COMMAND,atoi(argv[4]),0); -#else - CALLWNDPROC(LpWndClass->lpfnWndProc, - findHandle(argv[2]), - WM_COMMAND, - atoi(argv[4]), - 0); -#endif - } - } -/* for (i=0; iresult, "%s: invalid arg\n", argv[0]); - return(TCL_ERROR); - } - i = atoi(argv[1]); - strcpy(interp->result, getStrHandle(i)); - return(TCL_OK); -} - -_MsMsg2XvMsg(HWND hwnd, char *event) -{ - WORD message, wParam = 0; LONG lParam = 0; - if (1) message=WM_PAINT; -#if 0 - LpWndClass->lpfnWndProc(hwnd,message,wParam,lParam); -#else - CALLWNDPROC(LpWndClass->lpfnWndProc, hwnd, message, wParam, lParam); -#endif -} - -static short *closed_bits; - -HWND CreateWindow(LPSTR szAppName, LPSTR Label, DWORD ol, int x, int y, int w, int h, HWND d, HMENU e, HANDLE i, LPSTR g) -{ int result, n; - static int called=0; - if (x == CW_USEDEFAULT) x=0; - if (y == CW_USEDEFAULT) y=0; - if (w == CW_USEDEFAULT) w=500; - if (h == CW_USEDEFAULT) h=400; - n=allocStrHandle("",enum_win); - tclexec( "CreateWindow %s \"%s\" %d %d %d %d", getStrHandle(n), Label, x, y, w, h); - called=1; - return((HWND)n); -} - -int DrawText(HDC a, LPSTR str, int c, LPRECT d, WORD flag) -{ int x=d->left, y=d->top, w = d->right, h=d->bottom; - if (flag&DT_SINGLELINE); - if (flag&DT_CENTER); - x=200; - if (flag&DT_VCENTER); - y=200; - /*tclexec(".%s create text 200 200 -text \"%s\" -anchor n\n",getStrHandle(a), str); */ - tclexec("DrawText %s \"%s\" %d %d %d %d\n",getStrHandle(a), str, - y,x,h,w); -} - -BOOL GetMessage(LPMSG msg,HWND b,WORD c, WORD d) -{ static int called=0; - if (!called) - _MsMsg2XvMsg(b, 0); - called=1; - return(1); -} - -long DispatchMessage(MSG *msg) -{ - if (tk_NumMainWindows > 0) { - Tk_DoOneEvent(0); - return(0); - } - exit(0); -} - -BOOL TranslateMessage(LPMSG a){} - -void MyEventProc( ClientData clientData, XEvent *eventPtr) -{ -} - - -BOOL RegisterClass(LPWNDCLASS a) -{ - /* Tk_CreateEventHandler(win,mask,proc,data); */ - LpWndClass = a; return(1); -} - -BOOL ShowWindow(HWND a, int b) -{ - if (b != SW_SHOWNORMAL) - { assert(b==SW_SHOWMINNOACTIVE); /* iconize */ - } - return(TRUE); -} - -void UpdateWindow(HWND a) -{ -} - -HDC BeginPaint(HWND a, LPPAINTSTRUCT b) -{ return(a); -} -void EndPaint(HWND a, LPPAINTSTRUCT b) { } - -void GetClientRect(HWND a, LPRECT b) -{ b->top = 0; b->left = 0; - b->bottom = b->top+0; - b->right = b->left+0; -} - -HMENU CreateMenu(void) -{ static int n, called=0; - int result; - if (!called) - { n=allocStrHandle("",enum_frame); - tclexec( "CreateMenuBar %s\n",getStrHandle(n)); - } - else - { n=allocStrHandle("",enum_menu); - tclexec( "CreateMenuEntry %s any 0\n",getStrHandle(n)); - } - called=1; - return(n); -} - -BOOL AppendMenu(HMENU a, WORD b, WORD c, LPSTR d) -{ char *buf; int dist,n; - char *cmd = getStrHandle(a); - if (d) - { char *t; - buf = strdup(d); - if (t=strchr(buf,'&')) - strcpy(t,strchr(d,'&')+1); - dist = t-buf; - } - tclexec("AppendMenu %s %d %s {%s} %d", cmd, b, getStrHandle(c), - buf, dist); - return(1); -} - -/* Graphics Primitives */ -BOOL Rectangle(HDC a, int xLeft, int yTop, int xRight, int yBottom) -{ - XDrawRectangle(Tk_Display(w), Tk_WindowId(w), DefaultGCOfScreen(Tk_Screen(w)), - xLeft, yTop, xRight-xLeft+1, yBottom-yTop+1); -} - -int FillRect(HDC a,LPRECT b,HBRUSH c) -{ - XFillRectangle(Tk_Display(w), Tk_WindowId(w), DefaultGCOfScreen(Tk_Screen(w)), - b->left, b->top, b->right-b->left+1, b->bottom-b->top+1); -} - -static int _LineX=0, _LineY=0; - -int LineTo(HDC a, int b, int c) -{ - XDrawLine(Tk_Display(w), Tk_WindowId(w), DefaultGCOfScreen(Tk_Screen(w)), - _LineX,b, _LineY,c); - _LineX=b; _LineY=c; -} - -int MoveTo(HDC a, int b, int c) { _LineX=b; _LineY=c; } - -BOOL Arc(HDC a, int xLeft, int yTop, int xRight, int yBottom, - int xStart, int yStart, int xEnd, int yEnd) -{ int w, h, x, y; -/* XDrawArc(Tk_Display(w), Tk_WindowId(w), DefaultGCOfScreen(Tk_Screen(w)), x,y,..);*/ -} - -BOOL Pie(HDC a, int xLeft, int yTop, int xRight, int yBottom, - int xStart, int yStart, int xEnd, int yEnd) -{ int w, h, x,y; -} - -BOOL Chord(HDC a, int xLeft, int yTop, int xRight, int yBottom, - int xStart, int yStart, int xEnd, int yEnd) -{ int w, h, x,y; -} - -static int dte(char *str,...) -{ char cmd[300], *ptr, *ptr2; - int n, i; - va_list va; - va_start(va, str); - strcpy(cmd, str); - n = va_arg(va,int); - for (i=0; i +#include +#include +#include + +#include "message.h" +#include "callback.h" +#include "win.h" + + +Widget XT_topLevelWidget; + +static XtAppContext app_context; + + +/*********************************************************************** + * main + */ +void main(int argc, char **argv) +{ + XT_topLevelWidget = XtVaAppInitialize(&app_context, + "XWine", /* Application class */ + NULL, 0, /* Option list */ + &argc, argv, /* Command line args */ + NULL, /* Fallback resources */ + NULL ); + _WinMain( argc, argv ); +} + + +/*********************************************************************** + * GetMessage (USER.108) + */ +BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) +{ + XEvent event; + + while(1) + { + if (PeekMessage( msg, hwnd, first, last, PM_REMOVE )) break; + XtAppNextEvent( app_context, &event ); + XtDispatchEvent( &event ); + } + + return (msg->message != WM_QUIT); +} + + +/*********************************************************************** + * DefWindowProc (USER.107) + */ +LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) +{ + PAINTSTRUCT paintstruct; + + printf( "DefWindowProc: %d %d %d %d\n", hwnd, msg, wParam, lParam ); + + switch(msg) + { + case WM_PAINT: + BeginPaint( hwnd, &paintstruct ); + EndPaint( hwnd, &paintstruct ); + return 0; + + case WM_CREATE: + return 0; + + } + return 0; +} + + +/******************************************************************** + * + * Miscellaneous partially implemented functions. + * + */ + + +HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) +{ + return hwnd; +} + + +void EndPaint( HWND hwnd, LPPAINTSTRUCT lps ) +{ + MSG_EndPaint(); +} + +int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) +{ + WND * wndPtr = WIN_FindWndPtr( hdc ); + int x = rect->left, y = rect->top; + + if (flags & DT_CENTER) x = (rect->left + rect->right) / 2; + if (flags & DT_VCENTER) y = (rect->top + rect->bottom) / 2; + if (count == -1) count = strlen(str); + + printf( "DrawText: %d,%d '%s'\n", x, y, str ); + if (wndPtr) + { + XDrawString( XtDisplay(wndPtr->winWidget), + XtWindow(wndPtr->winWidget), + DefaultGCOfScreen(XtScreen(wndPtr->winWidget)), + x, y, str, count ); + GlobalUnlock( hdc ); + } +} + +int MessageBox( HWND hwnd, LPSTR str, LPSTR title, WORD type ) +{ + printf( "MessageBox: '%s'\n", str ); +} + +void MessageBeep( WORD i ) +{ + printf( "MessageBeep: %d\n", i ); +} + +HDC GetDC( HWND hwnd ) { } + +HMENU CreateMenu() { } + +HMENU GetMenu( HWND hwnd ) { } + +BOOL SetMenu( HWND hwnd, HMENU hmenu ) { } + +BOOL AppendMenu( HMENU hmenu, WORD flags, WORD id, LPSTR text ) { } + +BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) { } + +HANDLE GetStockObject( int obj ) { } + +