Release 0.1.0

WHAT'S NEW with version 0.1.0:
    - Integrated patches from Alexandre.
    - Minor bug fix in if1632.S

WHAT'S NEW with version 0.0.5:
    - Patches from Alexandre Julliard.  Some integration with Tcl.
    - Generic interface for callback procedures.  This will allow
      callbacks into DLLs.
    - MakeProcInstance() has been implemented but untested.

WHAT'S NEW with version 0.0.4:
    - Eric Youngdale modified wine.c and selector.c to allow loading
      of Windows DLLs.
    - Added global memory allocation routines (GlobalAlloc, GlobalFree,
      and GlobalLock)
    - Bitmap resource loading into global memory.
diff --git a/Makefile b/Makefile
index aeaa47a..43a4683 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS=-g -DDEBUG_RESOURCE
+CFLAGS=-g -DDEBUG_RESOURCE -DDEBUG_HEAP -I./
 
 ######################################################################
 # FILES:
@@ -18,19 +18,22 @@
 MUST_BE_LINKED_FIRST=if1632.o $(BUILDOBJS)
 
 OBJS=$(MUST_BE_LINKED_FIRST) \
-	dump.o heap.o ldt.o kernel.o relay.o resource.o \
-	selector.o user.o wine.o
+	callback.o dump.o global.o heap.o ldt.o kernel.o relay.o resource.o \
+	selector.o user.o wine.o wintcl.o
 
 TARGET=wine
-LIBS=-lldt
+LIBS=-L. -L/usr/X386/lib -L/dasd3/usr/lib -lldt -ltk -ltcl -lX11
 
-all: $(TARGET) libldt.a
+all: $(TARGET)
 
 clean:
-	rm -f *.o *~ *.s dll_*
+	rm -f *.o *~ *.s dll_* *.a
 
-$(TARGET): $(OBJS)
-	$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
+ci:
+	ci Makefile README *.c *.h *.S build-spec.txt *.spec
+
+$(TARGET): $(OBJS) libldt.a
+	$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
 
 build: build.c
 	cc -g -o build build.c
@@ -56,3 +59,6 @@
 
 dll_shell.S dll_shell_tab.c: build shell.spec
 	build shell.spec
+
+wintcl.o: wintcl.c windows.h
+	cc -c -I. -g wintcl.c
diff --git a/README b/README
index 3bcf6c8..078934f 100644
--- a/README
+++ b/README
@@ -2,11 +2,28 @@
 warranty.  It is my intent to cover this code with the Gnu Public
 License.
 
-So here goes release 0.0.3 of the Windows loader.  It will do some 
+So here goes release 0.1.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.1.0:
+    - Integrated patches from Alexandre.
+    - Minor bug fix in if1632.S
+
+WHAT'S NEW with version 0.0.5:
+    - Patches from Alexandre Julliard.  Some integration with Tcl.
+    - Generic interface for callback procedures.  This will allow
+      callbacks into DLLs.
+    - MakeProcInstance() has been implemented but untested.
+
+WHAT'S NEW with version 0.0.4:
+    - Eric Youngdale modified wine.c and selector.c to allow loading
+      of Windows DLLs.
+    - Added global memory allocation routines (GlobalAlloc, GlobalFree,
+      and GlobalLock)
+    - Bitmap resource loading into global memory.
+
 WHAT'S NEW with version 0.0.3:
     - Fixed bug with sector sizes.
     - Registers at program startup are now set correctly.
@@ -41,24 +58,21 @@
 TODO:
 
     - Segment fixup code completion.
-    - Make changes to the kernel to allow more than 32 LDT entries.
     - Trap and handle DOS and DPMI calls.
-    - Windows emulation library (connect to Peter MacDonald's library).
-    - Allowing loading of 16-bit DLLs for use with program.
-    - global memory allocation.
+    - global memory allocation completion
+    - GlobalAlloc should support ZEROINIT.
+    - GlobalAlloc of code segments.
     - complete and improve local heap allocation.
     - Handle self-loading applications.
-    - Deal with callback functions.
     - Resource loading
 
 INSTALLATION:
 
     Uncompress and untar this archive into the directory of your
 choice.  The file "ldt.tar" contains a necessary kernel patch against
-Linux 0.99.10.  If you installed the "ldt.tar" from the first release
-of this package, then you MUST to replace it.  In the directory 
-/usr/src/linux (or whereever you keep your kernel sources), untar 
-this file it contains three files:
+Linux 0.99.10.  "ldt.tar" is unchanged from the version released
+with release 0.0.2.  In the directory /usr/src/linux (or whereever 
+you keep your kernel sources), untar this file it contains three files:
 
 	kernel/ldt.c
 		- This is source for a new system call.
diff --git a/Windows.tcl b/Windows.tcl
new file mode 100755
index 0000000..0257f1e
--- /dev/null
+++ b/Windows.tcl
@@ -0,0 +1,91 @@
+# 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/build.c b/build.c
index 8905cc9..5c0b0f4 100644
--- a/build.c
+++ b/build.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: build.c,v 1.2 1993/06/30 14:24:33 root Exp root $";
+static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
diff --git a/callback.c b/callback.c
new file mode 100644
index 0000000..0cfb00f
--- /dev/null
+++ b/callback.c
@@ -0,0 +1,108 @@
+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 "callback.h"
+#include "wine.h"
+#include "segmem.h"
+
+extern unsigned short SelectorOwners[];
+extern unsigned short IF1632_Saved16_ss;
+extern unsigned long  IF1632_Saved16_esp;
+extern struct segment_descriptor_s *MakeProcThunks;
+
+struct thunk_s
+{
+    int used;
+    unsigned char thunk[10];
+};
+
+/**********************************************************************
+ *					PushOn16
+ */
+static void
+PushOn16(int size, unsigned int value)
+{
+    char *p = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
+			(IF1632_Saved16_esp & 0xffff));
+    if (size)
+    {
+	unsigned long *lp = (unsigned long *) p - 1;
+	
+	*lp = value;
+	IF1632_Saved16_esp -= 4;
+    }
+    else
+    {
+	unsigned short *sp = (unsigned short *) p - 1;
+	
+	*sp = value;
+	IF1632_Saved16_esp -= 2;
+    }
+}
+
+/**********************************************************************
+ *					FindDataSegmentForCode
+ */
+static unsigned short
+FindDataSegmentForCode(unsigned long csip)
+{
+    unsigned int seg_idx;
+    
+    seg_idx = (unsigned short) (csip >> 19);
+    return SelectorOwners[seg_idx];
+}
+
+/**********************************************************************
+ *					CallBack16
+ */
+int
+CallBack16(void *func, int n_args, ...)
+{
+    va_list ap;
+    int i;
+    int arg_type, arg_value;
+    
+    va_start(ap, n_args);
+
+    for (i = 0; i < n_args; i++)
+    {
+	arg_type = va_arg(ap, int);
+	arg_value = va_arg(ap, int);
+	PushOn16(arg_type, arg_value);
+    }
+
+    va_end(ap);
+
+    return CallTo16((unsigned int) func, 
+		    FindDataSegmentForCode((unsigned long) func));
+}
+
+/**********************************************************************
+ *					CALLBACK_MakeProcInstance
+ */
+void *
+CALLBACK_MakeProcInstance(void *func, int instance)
+{
+    int handle;
+    void *new_func;
+    struct thunk_s *tp;
+    int i;
+    
+    tp = (struct thunk_s *) MakeProcThunks->base_addr;
+    for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
+	if (!tp->used)
+	    break;
+    
+    if (tp->used)
+	return (void *) 0;
+    
+    tp->thunk[0] = 0xb8;
+    tp->thunk[1] = (unsigned char) instance;
+    tp->thunk[2] = (unsigned char) (instance >> 8);
+    tp->thunk[3] = 0x8e;
+    tp->thunk[4] = 0xd8;
+    tp->thunk[5] = 0xea;
+    memcpy(&tp->thunk[6], &func, 4);
+
+    return tp->thunk;
+}
diff --git a/callback.h b/callback.h
new file mode 100644
index 0000000..b867e43
--- /dev/null
+++ b/callback.h
@@ -0,0 +1,29 @@
+/* $Id$
+ */
+/*
+ * Copyright  Robert J. Amstadt, 1993
+ */
+
+#ifndef CALLBACK_H
+#define CALLBACK_H
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#define CALLBACK_SIZE_WORD	0
+#define CALLBACK_SIZE_LONG	1
+
+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/dlls.h b/dlls.h
index 87d3dc8..a4c4483 100644
--- a/dlls.h
+++ b/dlls.h
@@ -1,4 +1,4 @@
-/* $Id: dlls.h,v 1.1 1993/06/29 15:55:18 root Exp $
+/* $Id: dlls.h,v 1.2 1993/07/04 04:04:21 root Exp root $
  */
 /*
  * Copyright  Robert J. Amstadt, 1993
diff --git a/dump.c b/dump.c
index 6c21f9e..96b1c44 100644
--- a/dump.c
+++ b/dump.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: dump.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: dump.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
diff --git a/gdi.spec b/gdi.spec
index 3537537..7e5d3ad 100644
--- a/gdi.spec
+++ b/gdi.spec
@@ -1,5 +1,9 @@
-# $Id: gdi.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
+# $Id: gdi.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	gdi
 id	3
 length	490
+
+27  pascal Rectangle(word word word word word) Rectangle(1 2 3 4 5)
+82  pascal GetObject(word word ptr) RSC_GetObject(1 2 3)
+87  pascal GetStockObject(word) GetStockObject(1)
diff --git a/global.c b/global.c
new file mode 100644
index 0000000..3ef21ee
--- /dev/null
+++ b/global.c
@@ -0,0 +1,316 @@
+static char RCSId[] = "$Id: global.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
+static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "prototypes.h"
+#include "heap.h"
+#include "segmem.h"
+
+/*
+ * Global memory pool descriptor.
+ *
+ * handle  = 0, this descriptor contains the address of a free pool.
+ *        != 0, this describes an allocated block.
+ *
+ * sequence = 0, this is not a huge block
+ *          > 0, this is a portion of a huge block
+ *          =-1, this is a free segment
+ *
+ * addr	      - address of this memory block.
+ *
+ * length     - used to maintain huge blocks.
+ *
+ */
+typedef struct global_mem_desc_s
+{
+    struct global_mem_desc_s *next;
+    struct global_mem_desc_s *prev;
+    unsigned short handle;
+    short sequence;
+    void *addr;
+    int length;
+} GDESC;
+
+GDESC *GlobalList = NULL;
+
+/**********************************************************************
+ *					GLOBAL_GetFreeSegments
+ */
+GDESC *
+GLOBAL_GetFreeSegments(unsigned int flags, int n_segments)
+{
+    struct segment_descriptor_s *s;
+    GDESC *g;
+    GDESC *g_start;
+    GDESC *g_prev;
+    int count, i;
+
+    /*
+     * Try to find some empty segments in our list.
+     */
+    count = 0;
+    for (g = GlobalList; g != NULL && count != n_segments; g = g->next)
+    {
+	if ((int) g->sequence == -1)
+	{
+	    if (count > 0)
+	    {
+		if (g->prev->handle + 8 != g->handle)
+		    count = 0;
+		else
+		    count++;
+	    }
+	    else
+	    {
+		g_start = g;
+		count = 1;
+	    }
+	}
+	else if (count)
+	    count = 0;
+    }
+
+    /*
+     * If we couldn't find enough segments, then we need to create some.
+     */
+    if (count != n_segments)
+    {
+	/*
+	 * Find list tail.
+	 */
+	g_prev = NULL;
+	for (g = GlobalList; g != NULL; g = g->next)
+	    g_prev = g;
+
+	/*
+	 * Allocate segments.
+	 */
+	for (count = 0; count < n_segments; count++)
+	{
+	    s = GetNextSegment(flags, 0x10000);
+	    if (s == NULL)
+		return NULL;
+
+	    g = (GDESC *) malloc(sizeof(*g));
+	    
+	    g->prev = g_prev;
+	    g->next = NULL;
+	    g->handle = s->selector;
+	    g->sequence = -1;
+	    g->addr = s->base_addr;
+	    g->length = s->length;
+
+	    free(s);
+
+	    if (count == 0)
+		g_start = g;
+
+	    if (g_prev != NULL)
+	    {
+		g_prev->next = g;
+		g->prev = g_prev;
+	    }
+	    else
+		GlobalList = g;
+	}
+    }
+
+    /*
+     * We have all of the segments we need.  Let's adjust their contents.
+     */
+    g = g_start;
+    for (i = 0; i < n_segments; i++, g = g->next)
+    {
+	g->sequence = i + 1;
+	g->length = n_segments;
+    }
+
+    return g_start;
+}
+
+/**********************************************************************
+ *					GLOBAL_Alloc
+ */
+unsigned int
+GLOBAL_Alloc(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
+     * segments.
+     */
+    if (size > 0x8000 || !(flags & GLOBAL_FLAGS_MOVEABLE))
+    {
+	int segments = (size >> 16) + 1;
+
+	g = GLOBAL_GetFreeSegments(flags, segments);
+	if (g == NULL)
+	    return 0;
+	else
+	    return g->handle;
+    }
+    /*
+     * Otherwise we just need a little piece of a segment.
+     */
+    else
+    {
+	/*
+	 * Try to allocate from active free lists.
+	 */
+	for (g = GlobalList; g != NULL; g = g->next)
+	{
+	    if (g->handle == 0 && g->sequence == 0)
+	    {
+		m = HEAP_Alloc((MDESC **) g->addr, 0, size);
+		if (m != NULL)
+		    break;
+	    }
+	}
+
+	/*
+	 * If we couldn't get the memory there, then we need to create
+	 * a new free list.
+	 */
+	if (m == NULL)
+	{
+	    g = GLOBAL_GetFreeSegments(0, 1);
+	    if (g == NULL)
+		return 0;
+
+	    g->handle = 0;
+	    g->sequence = 0;
+	    HEAP_Init((MDESC **) g->addr, (MDESC **) g->addr + 1, 
+		      0x10000 - sizeof(MDESC **));
+	    m = HEAP_Alloc((MDESC **) g->addr, 0, size);
+	    if (m == NULL)
+		return 0;
+	}
+
+	/*
+	 * 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));
+	if (g == NULL)
+	    return 0;
+
+	g->handle = i << 3;
+	g->sequence = 0;
+	g->addr = m;
+	g->length = size;
+	g->next = NULL;
+
+	if (g_prev != NULL)
+	{
+	    g_prev->next = g;
+	    g->prev = g_prev;
+	}
+	else
+	{
+	    GlobalList = g;
+	    g->prev = NULL;
+	}
+	
+	return g->handle;
+    }
+}
+
+/**********************************************************************
+ *					GLOBAL_Free
+ *
+ * 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)
+{
+    GDESC *g;
+
+    if (block == 0)
+	return 0;
+
+    /*
+     * Find GDESC for this block.
+     */
+    if (block & 0xffff0000)
+    {
+	for (g = GlobalList; g != NULL; g = g->next)
+	    if (g->handle > 0 && (unsigned int) g->addr == block)
+		break;
+    }
+    else
+    {
+	for (g = GlobalList; g != NULL; g = g->next)
+	    if (g->handle == block)
+		break;
+    }
+    if (g == NULL)
+	return block;
+
+    /*
+     * If the sequence number is zero then use HEAP_Free to deallocate
+     * memory, and throw away this descriptor.
+     */
+    if (g->sequence == 0)
+    {
+	HEAP_Free((MDESC **) (block & 0xffff0000), (void *) block);
+
+	if (g->prev != NULL)
+	    g->prev->next = g->next;
+	else
+	    GlobalList = g->next;
+	
+	if (g->next != NULL)
+	    g->next->prev = g->prev;
+
+	free(g);
+    }
+    
+    /*
+     * Otherwise just mark these descriptors as free.
+     */
+    else
+    {
+	int i, limit;
+	
+	g->length;
+	for (i = 0; i < limit; i++)
+	{
+	    g->sequence = -1;
+	    g->length = 0x10000;
+	}
+    }
+
+    return 0;
+}
+
+/**********************************************************************
+ *					GLOBAL_Lock
+ *
+ */
+void *
+GLOBAL_Lock(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->addr;
+
+    return NULL;
+}
diff --git a/heap.c b/heap.c
index b6e7f9c..fa06124 100644
--- a/heap.c
+++ b/heap.c
@@ -1,48 +1,45 @@
-static char RCSId[] = "$Id: heap.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "prototypes.h"
+#include "segmem.h"
+#include "heap.h"
 
-typedef struct heap_mem_desc_s
-{
-    struct heap_mem_desc_s *prev, *next;
-    int   length;
-} MDESC;
-
-MDESC *FreeList;
+MDESC *LOCAL_FreeList;
 
 /**********************************************************************
- *					HEAP_LocalInit
+ *					HEAP_Init
  */
 void
-HEAP_LocalInit(void *start, int length)
+HEAP_Init(MDESC **free_list, void *start, int length)
 {
-    FreeList = (MDESC *) start;
-    FreeList->prev = NULL;
-    FreeList->next = NULL;
-    FreeList->length = length - sizeof(MDESC);
+    *free_list = (MDESC *) start;
+    (*free_list)->prev = NULL;
+    (*free_list)->next = NULL;
+    (*free_list)->length = length - sizeof(MDESC);
 }
 
 /**********************************************************************
- *					HEAP_LocalAlloc
+ *					HEAP_Alloc
  */
 void *
-HEAP_LocalAlloc(int flags, int bytes)
+HEAP_Alloc(MDESC **free_list, int flags, int bytes)
 {
     MDESC *m, *m_new;
     
-#ifdef HEAP_DEBUG
-    printf("LocalAlloc: flags %x, bytes %d, ", flags, bytes);
+#ifdef DEBUG_HEAP
+    printf("HeapAlloc: free_list %08x, flags %x, bytes %d\n", 
+	   free_list, flags, bytes);
 #endif
 
     /*
      * Find free block big enough.
      */
-    for (m = FreeList; m != NULL; m = m->next)
+    for (m = *free_list; m != NULL; m = m->next)
     {
-	if (m->length == bytes && m->length < bytes + 4 * sizeof(MDESC))
+	if (m->length >= bytes && m->length < bytes + 4 * sizeof(MDESC))
 	{
 	    break;
 	}
@@ -50,7 +47,7 @@
 	{
 	    m_new = m + (bytes / sizeof(MDESC)) + 2;
 	    if (m->prev == NULL)
-		FreeList = m_new;
+		*free_list = m_new;
 	    else
 		m->prev->next = m_new;
 	    
@@ -62,9 +59,8 @@
 	    m_new->length = m->length - ((int) m_new - (int) m);
 	    m->length -= (m_new->length + sizeof(MDESC));
 
-#ifdef HEAP_DEBUG
-	    printf("Returning %x\n", (int) (m + 1));
-#endif
+	    m->prev = m;
+	    m->next = m;
 	    return (void *) (m + 1);
 	}
     }
@@ -72,22 +68,144 @@
     if (m != NULL)
     {
 	if (m->prev == NULL)
-	    FreeList = m->next;
+	    *free_list = m->next;
 	else
 	    m->prev->next = m->next;
 	
 	if (m->next != NULL)
 	    m->next->prev = m->prev;
 	
-#ifdef HEAP_DEBUG
-	printf("Returning %x\n", (int) (m + 1));
-#endif
+	m->prev = m;
+	m->next = m;
 	return (void *) (m + 1);
     }
 
-#ifdef HEAP_DEBUG
-    printf("Returning 0\n");
-#endif
     return 0;
 }
 
+/**********************************************************************
+ *					HEAP_Free
+ */
+void
+HEAP_Free(MDESC **free_list, void *block)
+{
+    MDESC *m_free;
+    MDESC *m;
+    MDESC *m_prev;
+
+    /*
+     * Validate pointer.
+     */
+    m_free = (MDESC *) block - 1;
+    if (m_free->prev != m_free || m_free->next != m_free || 
+	((int) m_free & 0xffff0000) != ((int) *free_list & 0xffff0000))
+    {
+#ifdef DEBUG_HEAP
+	printf("Attempt to free bad pointer,"
+	       "m_free = %08x, *free_list = %08x\n",
+	       m_free, free_list);
+#endif
+	return;
+    }
+
+    /*
+     * Find location in free list.
+     */
+    m_prev = NULL;
+    for (m = *free_list; m != NULL && m < m_free; m = m->next)
+	m_prev = m;
+    
+    if (m_prev != NULL && (int) m_prev + m_prev->length > (int) m_free)
+    {
+#ifdef DEBUG_HEAP
+	printf("Attempt to free bad pointer,"
+	       "m_free = %08x, m_prev = %08x (length %x)\n",
+	       m_free, m_prev, m_prev->length);
+#endif
+	return;
+    }
+	
+    if ((m != NULL && (int) m_free + m_free->length > (int) m) ||
+	(int) m_free + m_free->length > ((int) m_free | 0xffff))
+    {
+#ifdef DEBUG_HEAP
+	printf("Attempt to free bad pointer,"
+	       "m_free = %08x (length %x), m = %08x\n",
+	       m_free, m_free->length, m);
+#endif
+	return;
+    }
+
+    /*
+     * Put block back in free list.
+     * Does it merge with the previos block?
+     */
+    if (m_prev != NULL)
+    {
+	if ((int) m_prev + m_prev->length == (int) m_free)
+	{
+	    m_prev->length += sizeof(MDESC) + m_free->length;
+	    m_free = m_prev;
+	}
+	else
+	{
+	    m_prev->next = m_free;
+	    m_free->prev = m_prev;
+	}
+    }
+    else
+    {
+	*free_list = m_free;
+	m_free->prev = NULL;
+    }
+    
+    /*
+     * Does it merge with the next block?
+     */
+    if (m != NULL)
+    {
+	if ((int) m_free + m_free->length == (int) m)
+	{
+	    m_free->length += sizeof(MDESC) + m->length;
+	    m_free->next = m->next;
+	}
+	else
+	{
+	    m->prev = m_free;
+	    m_free->next = m;
+	}
+    }
+    else
+    {
+	m_free->next = NULL;
+    }
+}
+
+/**********************************************************************
+ *					HEAP_LocalInit
+ */
+void
+HEAP_LocalInit(void *start, int length)
+{
+    HEAP_Init(&LOCAL_FreeList, start, length);
+}
+
+/**********************************************************************
+ *					HEAP_LocalAlloc
+ */
+void *
+HEAP_LocalAlloc(int flags, int bytes)
+{
+    void *m;
+    
+#ifdef DEBUG_HEAP
+    printf("LocalAlloc: flags %x, bytes %d\n", flags, bytes);
+#endif
+
+    m = HEAP_Alloc(&LOCAL_FreeList, flags, bytes);
+	
+#ifdef DEBUG_HEAP
+	printf("LocalAlloc: returning %x\n", (int) m);
+#endif
+    return m;
+}
diff --git a/heap.h b/heap.h
new file mode 100644
index 0000000..2d8bfa8
--- /dev/null
+++ b/heap.h
@@ -0,0 +1,19 @@
+/* $Id: heap.h,v 1.2 1993/07/04 04:04:21 root Exp root $
+ */
+/*
+ * Copyright  Robert J. Amstadt, 1993
+ */
+#ifndef HEAP_H
+#define HEAP_H
+
+typedef struct heap_mem_desc_s
+{
+    struct heap_mem_desc_s *prev, *next;
+    int   length;
+} MDESC;
+
+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);
+
+#endif /* HEAP_H */
diff --git a/if1632.S b/if1632.S
index 807d32e..b971d8a 100644
--- a/if1632.S
+++ b/if1632.S
@@ -19,11 +19,12 @@
 /**********************************************************************
  *	Places to keep info about the current 16-bit stack frame.
  */
-saved_16esp:
+	.globl	_IF1632_Saved16_esp,_IF1632_Saved16_ebp,_IF1632_Saved16_ss
+_IF1632_Saved16_esp:
 	.long	0
-saved_16ebp:
+_IF1632_Saved16_ebp:
 	.long	0
-saved_16ss:
+_IF1632_Saved16_ss:
 	.word	0
 
 nbytes:
@@ -136,6 +137,88 @@
 	ret
 
 /**********************************************************************
+ *	int CallTo16(unsigned long csip, unsigned short ds)
+ *
+ *	Stack:	 	0	ebp
+ *		 	4	eip
+ *		 	8	target ip
+ *			10	target cs
+ *			12	target ds
+ */
+	.align	4
+	.globl _CallTo16
+_CallTo16:
+	pushl	%ebp
+	movl	%esp,%ebp
+
+	/*
+	 * Get target address and new ds
+	 */
+	movl	8(%ebp),%eax
+	movl	%eax,jump_target
+	lea	jump_target,%edx
+	movw	12(%ebp),%ax
+
+	/*
+	 * Switch to 16-bit stack
+	 */
+	pushl	saved_esp
+	pushl	saved_ebp
+	pushw	saved_ss
+
+	movw	%ss,saved_ss
+	movl	%esp,saved_esp
+	movl	%ebp,saved_ebp
+
+	movw	_IF1632_Saved16_ss,%ss
+	movl	_IF1632_Saved16_esp,%esp
+	movl	_IF1632_Saved16_ebp,%ebp
+
+	/*
+	 * Call entry point
+	 */
+	movw	%ax,%ds
+	.byte	0x66
+	lcall	%fs:(%edx)
+
+	/*
+	 * Restore old stack and segment registers.
+	 *
+	 * Two choices here:
+	 *	1. Trust that fs or gs hasn't changed.
+	 *	2. Rely on knowledge of Linux use of segments.
+	 *
+	 * I'll opt for choice 2 because who knows what programs we
+	 * going to run.  Linux should be fairly stable in terms of
+	 * GDT usage.
+	 */
+	pushl	%eax
+	movw	$0x2b,%ax
+	movw	%ax,%ds
+	movw	%ax,%es
+	movw	%ax,%fs
+	movw	%ax,%gs
+	popl	%eax
+
+	movw	%ss,_IF1632_Saved16_ss
+	movl	%esp,_IF1632_Saved16_esp
+	movl	%ebp,_IF1632_Saved16_ebp
+
+	movw	saved_ss,%ss
+	movl	saved_esp,%esp
+	movl	saved_ebp,%ebp
+
+	popw	saved_ss
+	popl	saved_ebp
+	popl	saved_esp
+
+	movl	%eax,return_value
+	movw	return_value+2,%dx
+	.align	2,0x90
+	leave
+	ret
+
+/**********************************************************************
  *	CallTo32()
  *
  *	This function is called as a relay point to the built function
@@ -174,13 +257,13 @@
 	 * Save old stack save variables, save stack registers, reload
 	 * stack registers.
 	 */
-	pushl	saved_16esp
-	pushl	saved_16ebp
-	pushw	saved_16ss
+	pushl	_IF1632_Saved16_esp
+	pushl	_IF1632_Saved16_ebp
+	pushw	_IF1632_Saved16_ss
 
-	movw	%ss,saved_16ss
-	movl	%esp,saved_16esp
-	movl	%ebp,saved_16ebp
+	movw	%ss,_IF1632_Saved16_ss
+	movl	%esp,_IF1632_Saved16_esp
+	movl	%ebp,_IF1632_Saved16_ebp
 
 	movw	saved_ss,%ss
 	movl	saved_esp,%esp
@@ -189,21 +272,21 @@
 	/*
 	 * Call entry point
 	 */
-	pushw	saved_16ss
-	pushw	saved_16esp
+	pushw	_IF1632_Saved16_ss
+	pushw	_IF1632_Saved16_esp
 	pushl	%eax
 	call	_DLLRelay
 
 	/*
  	 * Restore registers, but do not destroy return value.
 	 */
-	movw	saved_16ss,%ss
-	movl	saved_16esp,%esp
-	movl	saved_16ebp,%ebp
+	movw	_IF1632_Saved16_ss,%ss
+	movl	_IF1632_Saved16_esp,%esp
+	movl	_IF1632_Saved16_ebp,%ebp
 
-	popw	saved_16ss
-	popl	saved_16ebp
-	popl	saved_16esp
+	popw	_IF1632_Saved16_ss
+	popl	_IF1632_Saved16_ebp
+	popl	_IF1632_Saved16_esp
 
 	popw	%es
 	popw	%ds
@@ -252,17 +335,15 @@
 	/*
  	 * Restore stack
 	 */
-	movw	saved_16ss,%ss
-	movl	saved_16esp,%esp
-	movl	saved_16ebp,%ebp
+	movw	_IF1632_Saved16_ss,%ss
+	movl	_IF1632_Saved16_esp,%esp
+	movl	_IF1632_Saved16_ebp,%ebp
 
-	popw	saved_16ss
-	popl	saved_16ebp
-	popl	saved_16esp
+	popw	_IF1632_Saved16_ss
+	popl	_IF1632_Saved16_ebp
+	popl	_IF1632_Saved16_esp
 
 	popw	%es
-/*	movw	_PSPSelector,%ax
-	movw	%ax,%es */
 	popw	%ds
 
 	.align	2,0x90
diff --git a/kernel.c b/kernel.c
index cf23a44..24b0e90 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: kernel.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: kernel.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
@@ -93,6 +93,9 @@
       case 0x35:
 	return 0;
 
+      case 0x4c:
+	exit(ax & 0xff);
+
       default:
 	fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n",
 		ax, bx, cx, dx);
diff --git a/kernel.spec b/kernel.spec
index 127fabe..1942b75 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -1,4 +1,4 @@
-# $Id: kernel.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
+# $Id: kernel.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	kernel
 id	1
@@ -6,13 +6,18 @@
 
 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)
 23  pascal LockSegment(s_word) KERNEL_LockSegment(1)
 24  pascal UnlockSegment(s_word) KERNEL_UnlockSegment(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)
 91  pascal InitTask() KERNEL_InitTask()
 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)
 131 pascal GetDOSEnvironment() GetDOSEnvironment()
+132 return GetWinFlags 0 0x413
 178 equate __WINFLAGS 0x413
diff --git a/ldt.c b/ldt.c
index 7ab12df..326ac5e 100644
--- a/ldt.c
+++ b/ldt.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: ldt.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: ldt.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
diff --git a/ldtlib.c b/ldtlib.c
index cfd2e25..af23677 100644
--- a/ldtlib.c
+++ b/ldtlib.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: ldtlib.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: ldtlib.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
diff --git a/neexe.h b/neexe.h
index c1b0070..839ac3e 100644
--- a/neexe.h
+++ b/neexe.h
@@ -1,4 +1,4 @@
-/* $Id: neexe.h,v 1.3 1993/06/30 14:24:33 root Exp root $
+/* $Id: neexe.h,v 1.4 1993/07/04 04:04:21 root Exp root $
  */
 /*
  * Copyright  Robert J. Amstadt, 1993
diff --git a/prototypes.h b/prototypes.h
index 526079fc..c030971 100644
--- a/prototypes.h
+++ b/prototypes.h
@@ -1,4 +1,4 @@
-/* $Id: prototypes.h,v 1.1 1993/06/29 15:55:18 root Exp $
+/* $Id: prototypes.h,v 1.3 1993/07/04 04:04:21 root Exp root $
  */
 /*
  * Copyright  Robert J. Amstadt, 1993
@@ -9,10 +9,10 @@
 #include <sys/types.h>
 #include "neexe.h"
 #include "segmem.h"
+#include "wine.h"
 
 extern struct segment_descriptor_s *
-    CreateSelectors(int fd, struct ne_segment_table_entry_s *seg_table,
-  		    struct ne_header_s *ne_header);
+    CreateSelectors(struct w_files *);
 
 extern void PrintFileHeader(struct ne_header_s *ne_header);
 extern void PrintSegmentTable(struct ne_segment_table_entry_s *seg_table, 
@@ -20,18 +20,17 @@
 extern void PrintRelocationTable(char *exe_ptr, 
 				 struct ne_segment_table_entry_s *seg_entry_p,
 				 int segment);
-extern int FixupSegment(int fd, struct mz_header_s * mz_header,
-			struct ne_header_s *ne_header,
-			struct ne_segment_table_entry_s *seg_table, 
-			struct segment_descriptor_s *selecetor_table,
-			int segment_num);
+extern int FixupSegment(struct w_files * wpnt, int segment_num);
 extern struct  dll_table_entry_s *FindDLLTable(char *dll_name);
-extern unsigned int GetEntryPointFromOrdinal(int fd, 
-					     struct mz_header_s *mz_header, 
-					     struct ne_header_s *ne_header, 
+extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, 
 					     int ordinal);
 
-extern char WIN_CommandLine[];
+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 0dc6d49..a86b92c 100644
--- a/relay.c
+++ b/relay.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: relay.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
diff --git a/resource.c b/resource.c
index 7d674bc..93895e1 100644
--- a/resource.c
+++ b/resource.c
@@ -1,10 +1,11 @@
-static char RCSId[] = "$Id: resource.c,v 1.3 1993/06/30 14:24:33 root Exp root $";
+static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "prototypes.h"
 #include "neexe.h"
+#include "windows.h"
 
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 
@@ -14,10 +15,90 @@
     void *resource_data;
 } RSCD;
 
+int ResourceSizes[16] =
+{
+    0, 0, sizeof(BITMAP), 0,
+    0, 0, 0, 0,
+    0, 0, 0, 0,
+    0, 0, 0, 0,
+};
+
 RSCD *Resources;
 int ResourceArraySize;
 
 /**********************************************************************
+ *					ConvertCoreBitmap
+ */
+void *
+ConvertCoreBitmap(BITMAPCOREHEADER *image, int image_size)
+{
+    BITMAP *new_image;
+    char *old_p, *new_p;
+    int old_line_length, new_line_length;
+    unsigned int handle;
+    int i;
+    int n_colors;
+    
+    n_colors = 1 << image->bcBitCount;
+    handle = GLOBAL_Alloc(GMEM_MOVEABLE, 
+			  image_size + sizeof(*new_image) + n_colors);
+    new_image = GLOBAL_Lock(handle);
+    if (new_image == NULL)
+	return NULL;
+
+    new_image->bmType = 0;
+    new_image->bmWidth = image->bcWidth;
+    new_image->bmHeight = image->bcHeight;
+    new_image->bmPlanes = image->bcPlanes;
+    new_image->bmBitsPixel = image->bcBitCount;
+
+    if (image->bcBitCount < 24)
+    {
+	RGBTRIPLE *old_color = (RGBTRIPLE *) (image + 1);
+	RGBQUAD *new_color = (RGBQUAD *) (new_image + 1);
+	for (i = 0; i < n_colors; i++)
+	{
+	    memcpy(new_color, old_color, sizeof(*old_color));
+	    new_color++;
+	    old_color++;
+	}
+
+	old_p = (char *) old_color;
+	new_p = (char *) new_color;
+	old_line_length = image->bcWidth / (8 / image->bcBitCount);
+    }
+    else
+    {
+	old_p = (char *) (image + 1);
+	new_p = (char *) (new_image + 1);
+	old_line_length = image->bcWidth * 3;
+    }
+    
+    new_line_length = (old_line_length + 1) & ~1;
+    old_line_length = (old_line_length + 3) & ~3;
+
+    new_image->bmBits = (unsigned long) new_p;
+    new_image->bmWidthBytes = new_line_length;
+
+    for (i = 0; i < image->bcHeight; i++)
+    {
+	memcpy(new_p, old_p, new_line_length);
+	new_p += new_line_length;
+	old_p += old_line_length;
+    }
+
+    return new_image;
+}
+
+/**********************************************************************
+ *					ConvertInfoBitmap
+ */
+void *
+ConvertInfoBitmap(BITMAPINFOHEADER *image, int image_size)
+{
+}
+
+/**********************************************************************
  *					AddResource
  */
 int
@@ -183,37 +264,35 @@
 }
 
 /**********************************************************************
- *					RSC_LoadBitmap
+ *					RSC_LoadResource
  */
 int 
-RSC_LoadBitmap(int instance, char *bmp_name)
+RSC_LoadResource(int instance, char *rsc_name, int type)
 {
     struct resource_nameinfo_s nameinfo;
     void *image;
+    void *rsc_image;
+    long *lp;
     int image_size;
     int size_shift;
     
-#ifdef DEBUG_RESOURCE
-    printf("LoadBitmap: instance = %04x, name = %08x\n",
-	   instance, bmp_name);
-#endif
     /*
-     * Built-in bitmaps
+     * Built-in resources
      */
     if (instance == 0)
     {
 	return 0;
     }
     /*
-     * Get bitmap by ordinal
+     * Get resource by ordinal
      */
-    else if (((int) bmp_name & 0xffff0000) == 0)
+    else if (((int) rsc_name & 0xffff0000) == 0)
     {
-	size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_BITMAP,
-					  (int) bmp_name | 0x8000);
+	size_shift = FindResourceByNumber(&nameinfo, type,
+					  (int) rsc_name | 0x8000);
     }
     /*
-     * Get bitmap by name
+     * Get resource by name
      */
     else
     {
@@ -223,7 +302,7 @@
 	return 0;
 
     /*
-     * Read bitmap.
+     * Read resource.
      */
     lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
 
@@ -236,7 +315,81 @@
     }
 
     /*
+     * Convert bitmap to internal format.
+     */
+    lp = (long *) image;
+    if (*lp == sizeof(BITMAPCOREHEADER))
+	rsc_image = ConvertCoreBitmap(image, image_size);
+    else if (*lp == sizeof(BITMAPINFOHEADER))
+	rsc_image = ConvertInfoBitmap(image, image_size);
+
+    free(image);
+
+    /*
      * Add to resource list.
      */
-    return AddResource(NE_RSCTYPE_BITMAP, image);
+    if (rsc_image)
+	return AddResource(type, rsc_image);
+    else
+	return 0;
+}
+
+/**********************************************************************
+ *					RSC_LoadIcon
+ */
+int 
+RSC_LoadIcon(int instance, char *icon_name)
+{
+#ifdef DEBUG_RESOURCE
+    printf("LoadIcon: instance = %04x, name = %08x\n",
+	   instance, icon_name);
+#endif
+    return RSC_LoadResource( instance, icon_name, NE_RSCTYPE_ICON);
+}
+
+/**********************************************************************
+ *					RSC_LoadBitmap
+ */
+int 
+RSC_LoadBitmap(int instance, char *bmp_name)
+{
+#ifdef DEBUG_RESOURCE
+    printf("LoadBitmap: instance = %04x, name = %08x\n",
+	   instance, bmp_name);
+#endif
+    return RSC_LoadResource( instance, bmp_name, NE_RSCTYPE_BITMAP);
+}
+
+/**********************************************************************
+ *					RSC_LoadCursor
+ */
+int 
+RSC_LoadCursor(int instance, char *cursor_name)
+{
+#ifdef DEBUG_RESOURCE
+    printf("LoadCursor: instance = %04x, name = %08x\n",
+	   instance, cursor_name);
+#endif
+    return RSC_LoadResource( instance, cursor_name, NE_RSCTYPE_CURSOR);
+}
+
+/**********************************************************************
+ *					RSC_GetObject
+ */
+int
+RSC_GetObject(int handle, int nbytes, void *buffer)
+{
+    if (handle > 0 && handle <= ResourceArraySize)
+    {
+	RSCD *r = &Resources[handle - 1];
+	
+	if (r->resource_type > 0)
+	{
+	    int n = MIN(nbytes, ResourceSizes[r->resource_type & 0xf]);
+	    memcpy(buffer, r->resource_data, n);
+	    return n;
+	}
+    }
+    
+    return 0;
 }
diff --git a/segmem.h b/segmem.h
index 3495c8f..5775cdc 100644
--- a/segmem.h
+++ b/segmem.h
@@ -1,4 +1,4 @@
-/* $Id: segmem.h,v 1.1 1993/06/29 15:55:18 root Exp $
+/* $Id: segmem.h,v 1.3 1993/07/04 04:04:21 root Exp root $
  */
 /*
  * Copyright  Robert J. Amstadt, 1993
@@ -23,4 +23,13 @@
  */
 #define NE_SEGFLAGS_MALLOCED	0x00010000 /* Memory allocated with malloc() */
 
+/*
+ * Global memory flags
+ */
+#define GLOBAL_FLAGS_MOVEABLE		0x0002
+#define GLOBAL_FLAGS_ZEROINIT		0x0040
+#define GLOBAL_FLAGS_CODE		0x00010000
+#define GLOBAL_FLAGS_EXECUTEONLY	0x00020000
+#define GLOBAL_FLAGS_READONLY		0x00020000
+
 #endif /* SEGMEM_H */
diff --git a/selector.c b/selector.c
index ba3a654..ef52ae7 100644
--- a/selector.c
+++ b/selector.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: selector.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: selector.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
@@ -16,34 +16,155 @@
 #include "neexe.h"
 #include "segmem.h"
 #include "prototypes.h"
+#include "wine.h"
 
-struct segment_descriptor_s *SelectorTable;
-int SelectorTableLength;
-int EnvironmentSelectorIdx;
-int PSPSelectorIdx;
+#define MAX_SELECTORS	512
+
+static struct segment_descriptor_s * EnvironmentSelector =  NULL;
+static struct segment_descriptor_s * PSP_Selector = NULL;
+struct segment_descriptor_s * MakeProcThunks = NULL;
 unsigned short PSPSelector;
+unsigned char ran_out = 0;
+unsigned short SelectorOwners[MAX_SELECTORS];
 
+static int next_unused_selector = 0;
 extern void KERNEL_Ordinal_102();
 extern void UNIXLIB_Ordinal_0();
 
 /**********************************************************************
+ *					GetNextSegment
+ */
+struct segment_descriptor_s *
+GetNextSegment(unsigned int flags, unsigned int limit)
+{
+    struct segment_descriptor_s *selectors, *s;
+    int sel_idx;
+    FILE *zfile;
+
+    sel_idx = next_unused_selector++;
+
+    /*
+     * Fill in selector info.
+     */
+    zfile = fopen("/dev/zero","r");
+
+    s = malloc(sizeof(*s));
+    s->flags = NE_SEGFLAGS_DATA;
+    s->selector = (sel_idx << 3) | 0x0007;
+    s->length = limit;
+    s->base_addr = (void *) mmap((char *) (s->selector << 16),
+				 ((s->length + PAGE_SIZE - 1) & 
+				  ~(PAGE_SIZE - 1)),
+				 PROT_EXEC | PROT_READ | PROT_WRITE,
+				 MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0);
+
+    fclose(zfile);
+
+    if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, 
+		      (s->length - 1) & 0xffff, 0, 
+		      MODIFY_LDT_CONTENTS_DATA, 0, 0) < 0)
+    {
+	next_unused_selector--;
+	free(s);
+	return NULL;
+    }
+
+    return s;
+}
+
+/**********************************************************************
  *					GetEntryPointFromOrdinal
  */
-unsigned int 
-GetEntryPointFromOrdinal(int fd, struct mz_header_s *mz_header, 
-			 struct ne_header_s *ne_header, int ordinal)
+union lookup{
+    struct entry_tab_header_s *eth;
+    struct entry_tab_movable_s *etm;
+    struct entry_tab_fixed_s *etf;
+    char  * cpnt;
+};
+
+unsigned int GetEntryDLLName(char * dll_name, char * function, int * sel, 
+				int  * addr)
 {
-    struct entry_tab_header_s eth;
-    struct entry_tab_movable_s etm;
-    struct entry_tab_fixed_s etf;
+	struct dll_table_entry_s *dll_table;
+	struct w_files * wpnt;
+	char * cpnt;
+	int ordinal, j, len;
+
+	dll_table = FindDLLTable(dll_name);
+
+	if(dll_table) {
+		ordinal = FindOrdinalFromName(dll_table, function);
+		*sel = dll_table[ordinal].selector;
+		*addr  = (unsigned int) dll_table[ordinal].address;
+		return 0;
+	};
+
+	/* We need a means  of determining the ordinal for the function. */
+	/* Not a builtin symbol, look to see what the file has for us */
+	for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
+		if(strcmp(wpnt->name, dll_name)) continue;
+		cpnt  = wpnt->nrname_table;
+		while(1==1){
+			if( ((int) cpnt)  - ((int)wpnt->nrname_table) >  
+			   wpnt->ne_header->nrname_tab_length)  return 1;
+			len = *cpnt++;
+			if(strncmp(cpnt, function, len) ==  0) break;
+			cpnt += len + 2;
+		};
+		ordinal =  *((unsigned short *)  (cpnt +  len));
+		j = GetEntryPointFromOrdinal(wpnt, ordinal);		
+		*addr  = j & 0xffff;
+		j = j >> 16;
+		*sel = wpnt->selector_table[j].selector;
+		return 0;
+	};
+	return 1;
+}
+
+unsigned int GetEntryDLLOrdinal(char * dll_name, int ordinal, int * sel, 
+				int  * addr)
+{
+	struct dll_table_entry_s *dll_table;
+	struct w_files * wpnt;
+	int j;
+
+	dll_table = FindDLLTable(dll_name);
+
+	if(dll_table) {
+	    *sel = dll_table[ordinal].selector;
+	    *addr  = (unsigned int) dll_table[ordinal].address;
+	    return 0;
+	};
+
+	/* Not a builtin symbol, look to see what the file has for us */
+	for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
+		if(strcmp(wpnt->name, dll_name)) continue;
+		j = GetEntryPointFromOrdinal(wpnt, ordinal);
+		*addr  = j & 0xffff;
+		j = j >> 16;
+		*sel = wpnt->selector_table[j].selector;
+		return 0;
+	};
+	return 1;
+}
+
+unsigned int 
+GetEntryPointFromOrdinal(struct w_files * wpnt, int ordinal)
+{
+   int fd =  wpnt->fd;
+   struct mz_header_s *mz_header = wpnt->mz_header;   
+   struct ne_header_s *ne_header = wpnt->ne_header;   
+
+   
+    union lookup entry_tab_pointer;
+    struct entry_tab_header_s *eth;
+    struct entry_tab_movable_s *etm;
+    struct entry_tab_fixed_s *etf;
     int current_ordinal;
     int i;
     
-    /*
-     * Move to the beginning of the entry table.
-     */
-    lseek(fd, mz_header->ne_offset + ne_header->entry_tab_offset, SEEK_SET);
 
+   entry_tab_pointer.cpnt = wpnt->lookup_table;
     /*
      * Let's walk through the table until we get to our entry.
      */
@@ -53,46 +174,44 @@
 	/*
 	 * Read header for this bundle.
 	 */
-	if (read(fd, &eth, sizeof(eth)) != sizeof(eth))
-	    myerror("Error reading entry table");
+	eth = entry_tab_pointer.eth++;
 	
-	if (eth.n_entries == 0)
-	    return 0;
+	if (eth->n_entries == 0)
+	    return 0xffffffff;  /* Yikes - we went off the end of the table */
 
-	if (eth.seg_number == 0)
+	if (eth->seg_number == 0)
 	{
-	    current_ordinal++;
+	    current_ordinal += eth->n_entries;
+	    if(current_ordinal > ordinal) return 0;
 	    continue;
 	}
 
 	/*
 	 * Read each of the bundle entries.
 	 */
-	for (i = 0; i < eth.n_entries; i++, current_ordinal++)
+	for (i = 0; i < eth->n_entries; i++, current_ordinal++)
 	{
-	    if (eth.seg_number >= 0xfe)
+	    if (eth->seg_number >= 0xfe)
 	    {
-		if (read(fd, &etm, sizeof(etm)) != sizeof(etm))
-		    myerror("Error reading entry table");
+		    etm = entry_tab_pointer.etm++;
 
 		if (current_ordinal == ordinal)
 		{
 		    return ((unsigned int) 
-			    (SelectorTable[etm.seg_number - 1].base_addr + 
-			     etm.offset));
+			    (wpnt->selector_table[etm->seg_number - 1].base_addr + 
+			     etm->offset));
 		}
 	    }
 	    else
 	    {
-		if (read(fd, &etf, sizeof(etf)) != sizeof(etf))
-		    myerror("Error reading entry table");
+		    etf = entry_tab_pointer.etf++;
 
 		if (current_ordinal == ordinal)
 		{
 		    return ((unsigned int) 
-			    (SelectorTable[eth.seg_number - 1].base_addr + 
-			     (int) etf.offset[0] + 
-			     ((int) etf.offset[1] << 8)));
+			    (wpnt->selector_table[eth->seg_number - 1].base_addr + 
+			     (int) etf->offset[0] + 
+			     ((int) etf->offset[1] << 8)));
 		}
 	    }
 	}
@@ -105,24 +224,28 @@
 void *
 GetDOSEnvironment()
 {
-    return SelectorTable[EnvironmentSelectorIdx].base_addr;
+    return EnvironmentSelector->base_addr;
 }
 
 /**********************************************************************
  *					CreateEnvironment
  */
-void
-CreateEnvironment(int sel_idx, struct segment_descriptor_s *s, FILE *zfile)
+static struct segment_descriptor_s *
+CreateEnvironment(FILE *zfile)
 {
     char *p;
+    int sel_idx;
+    struct segment_descriptor_s * s;
 
-    EnvironmentSelectorIdx = sel_idx;
+    s = (struct segment_descriptor_s *) 
+	    malloc(sizeof(struct segment_descriptor_s));
 
+    sel_idx =  next_unused_selector;
     /*
      * Create memory to hold environment.
      */
     s->flags = NE_SEGFLAGS_DATA;
-    s->selector = (sel_idx << 3) | 0x0007;
+    s->selector = (next_unused_selector++ << 3) | 0x0007;
     s->length = PAGE_SIZE;
     s->base_addr = (void *) mmap((char *) (s->selector << 16),
 				 PAGE_SIZE,
@@ -143,29 +266,72 @@
     /*
      * Create entry in LDT for this segment.
      */
-    if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, s->length, 0, 
+    if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, 
+		      (s->length - 1) & 0xffff, 0, 
 		      MODIFY_LDT_CONTENTS_DATA, 0, 0) < 0)
     {
 	myerror("Could not create LDT entry for environment");
     }
+    return  s;
+}
+
+/**********************************************************************
+ *					CreateThunks
+ */
+static struct segment_descriptor_s *
+CreateThunks(FILE *zfile)
+{
+    int sel_idx;
+    struct segment_descriptor_s * s;
+
+    s = (struct segment_descriptor_s *) 
+	    malloc(sizeof(struct segment_descriptor_s));
+
+    sel_idx =  next_unused_selector;
+    /*
+     * Create memory to hold environment.
+     */
+    s->flags = 0;
+    s->selector = (next_unused_selector++ << 3) | 0x0007;
+    s->length = 0x10000;
+    s->base_addr = (void *) mmap((char *) (s->selector << 16),
+				 s->length,
+				 PROT_EXEC | PROT_READ | PROT_WRITE,
+				 MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0);
+
+
+    /*
+     * Create entry in LDT for this segment.
+     */
+    if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, 
+		      (s->length - 1) & 0xffff, 0, 
+		      MODIFY_LDT_CONTENTS_CODE, 0, 0) < 0)
+    {
+	myerror("Could not create LDT entry for thunks");
+    }
+    return  s;
 }
 
 /**********************************************************************
  *					CreatePSP
  */
-void
-CreatePSP(int sel_idx, struct segment_descriptor_s *s, FILE *zfile)
+static struct segment_descriptor_s *
+CreatePSP(FILE *zfile)
 {
     struct dos_psp_s *psp;
     unsigned short *usp;
-    
-    PSPSelectorIdx = sel_idx;
+    int sel_idx;
+    struct segment_descriptor_s * s;
 
+    s = (struct segment_descriptor_s *) 
+	    malloc(sizeof(struct segment_descriptor_s));
+    
+    sel_idx =  next_unused_selector;
     /*
      * Create memory to hold PSP.
      */
     s->flags = NE_SEGFLAGS_DATA;
-    s->selector = (sel_idx << 3) | 0x0007;
+    s->selector = (next_unused_selector++ << 3) | 0x0007;
     s->length = PAGE_SIZE;
     s->base_addr = (void *) mmap((char *) (s->selector << 16),
 				 PAGE_SIZE,
@@ -188,7 +354,7 @@
     psp->pspControlCVector[1] = 0x0023;
     psp->pspCritErrorVector[0] = (unsigned short) UNIXLIB_Ordinal_0;
     psp->pspCritErrorVector[1] = 0x0023;
-    psp->pspEnvironment = SelectorTable[EnvironmentSelectorIdx].selector;
+    psp->pspEnvironment = EnvironmentSelector->selector;
     psp->pspCommandTailCount = 1;
     strcpy(psp->pspCommandTail, "\r");
     
@@ -196,22 +362,28 @@
     /*
      * Create entry in LDT for this segment.
      */
-    if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, s->length, 0, 
+    if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, 
+		      (s->length - 1) & 0xffff, 0, 
 		      MODIFY_LDT_CONTENTS_DATA, 0, 0) < 0)
     {
 	myerror("Could not create LDT entry for PSP");
     }
+    return s;
 }
 
 /**********************************************************************
  *					CreateSelectors
  */
 struct segment_descriptor_s *
-CreateSelectors(int fd, struct ne_segment_table_entry_s *seg_table,
-		struct ne_header_s *ne_header)
+CreateSelectors(struct  w_files * wpnt)
 {
+    int fd = wpnt->fd;
+    struct ne_segment_table_entry_s *seg_table = wpnt->seg_table;
+    struct ne_header_s *ne_header = wpnt->ne_header;
     struct segment_descriptor_s *selectors, *s;
+    unsigned short *sp;
     int contents, read_only;
+    int SelectorTableLength;
     int i;
     int status;
     FILE * zfile;
@@ -220,11 +392,10 @@
     /*
      * Allocate memory for the table to keep track of all selectors.
      */
-    SelectorTableLength = ne_header->n_segment_tab + 2;
+    SelectorTableLength = ne_header->n_segment_tab;
     selectors = malloc(SelectorTableLength * sizeof(*selectors));
     if (selectors == NULL)
 	return NULL;
-    SelectorTable = selectors;
 
     /*
      * Step through the segment table in the exe header.
@@ -245,7 +416,7 @@
 	 * Store the flags in our table.
 	 */
 	s->flags = seg_table[i].seg_flags;
-	s->selector = (i << 3) | 0x0007;
+	s->selector = ((next_unused_selector + i) << 3) | 0x0007;
 
 	/*
 	 * Is there an image for this segment in the file?
@@ -319,10 +490,13 @@
 	/*
 	 * Create entry in LDT for this segment.
 	 */
-	if (set_ldt_entry(i, (unsigned long) s->base_addr, s->length, 0, 
+	if (set_ldt_entry(i, (unsigned long) s->base_addr, 
+			  (s->length - 1) & 0xffff, 0, 
 			  contents, read_only, 0) < 0)
 	{
 	    free(selectors);
+	    fprintf(stderr,"Ran out of ldt  entries.\n");
+	    ran_out++;
 	    return NULL;
 	}
 	/*
@@ -336,8 +510,18 @@
 	}
     }
 
-    CreateEnvironment(i++, s++, zfile);
-    CreatePSP(i++, s++, zfile);
+    sp = &SelectorOwners[next_unused_selector];
+    for (i = 0; i < ne_header->n_segment_tab; i++)
+	*sp++ = (((next_unused_selector + ne_header->auto_data_seg - 1) << 3)
+		 | 0x0007);
+
+    next_unused_selector += ne_header->n_segment_tab;
+
+    if(!EnvironmentSelector) {
+	    EnvironmentSelector = CreateEnvironment(zfile);
+	    PSP_Selector = CreatePSP(zfile);
+	    MakeProcThunks = CreateThunks(zfile);
+    };
 
     fclose(zfile);
 
diff --git a/shell.spec b/shell.spec
index 79f46d9..436d68b 100644
--- a/shell.spec
+++ b/shell.spec
@@ -1,4 +1,4 @@
-# $Id: shell.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
+# $Id: shell.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	shell
 id	5
diff --git a/tclIndex b/tclIndex
new file mode 100644
index 0000000..045f146
--- /dev/null
+++ b/tclIndex
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..728847c
--- /dev/null
+++ b/tkInt.h
@@ -0,0 +1,555 @@
+/*
+ * 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 <X11/Xlib.h>
+#endif
+#ifndef _XUTIL_H
+#include <X11/Xutil.h>
+#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/unixlib.spec b/unixlib.spec
index e24d02f..a8b408a 100644
--- a/unixlib.spec
+++ b/unixlib.spec
@@ -1,4 +1,4 @@
-# $Id: unixlib.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
+# $Id: unixlib.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	unixlib
 id	4
diff --git a/user.c b/user.c
index 8f7ac82..dcc5db6 100644
--- a/user.c
+++ b/user.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: user.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+static char RCSId[] = "$Id: user.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
 #include <stdio.h>
diff --git a/user.spec b/user.spec
index 1bc3a9a..fa9953e 100644
--- a/user.spec
+++ b/user.spec
@@ -1,9 +1,32 @@
-# $Id: user.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
+# $Id: user.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	user
 id	2
 length	540
 
+1   pascal MessageBox(word ptr ptr word) MessageBox(1 2 3 4)
 5   pascal InitApp(word) USER_InitApp(1)
+6   pascal PostQuitMessage(word) PostQuitMessage(1)
+33  pascal GetClientRect(word ptr) GetClientRect(1 2)
+39  pascal BeginPaint(word ptr) BeginPaint(1 2)
+40  pascal EndPaint(word ptr) EndPaint(1 2)
+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)
+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)
+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)
+113 pascal TranslateMessage(ptr) TranslateMessage(1)
+114 pascal DispatchMessage(ptr) DispatchMessage(1)
+124 pascal UpdateWindow(word) UpdateWindow(1)
+151 pascal CreateMenu() CreateMenu()
+157 pascal GetMenu(word) GetMenu(1)
+158 pascal SetMenu(word word) SetMenu(1 2)
+173 pascal LoadCursor(word ptr) RSC_LoadCursor(1 2)
+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)
+411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4)
diff --git a/win87em.spec b/win87em.spec
index 5044d2d..11c5720 100644
--- a/win87em.spec
+++ b/win87em.spec
@@ -1,4 +1,4 @@
-# $Id: win87em.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
+# $Id: win87em.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	win87em
 id	5
diff --git a/windows.h b/windows.h
index 7d89f66..c97f5fe 100644
--- a/windows.h
+++ b/windows.h
@@ -1,13 +1,153 @@
-#ifndef WINDOWS_H
-#define WINDOWS_H
+/* Initial draft attempt of windows.h, by Peter MacDonald, pmacdona@sanjuan.uvic.ca */
 
-typedef struct tagRGBQUAD
+#ifndef _WINARGS
+
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+#ifndef _WINMAIN
+typedef unsigned short BOOL;
+typedef unsigned char BYTE;
+#endif
+typedef long LONG;
+typedef WORD HANDLE;
+typedef HANDLE HWND;
+typedef HANDLE HDC;
+typedef HANDLE HCURSOR;
+typedef HANDLE HFONT;
+typedef HANDLE HPEN;
+typedef HANDLE HRGN;
+typedef HANDLE HPALETTE;
+typedef HANDLE HICON;
+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)();
+typedef int CATCHBUF[9];
+typedef int *LPCATCHBUF;
+
+#define TRUE 1
+#define FALSE 0
+#define CW_USEDEFAULT ((int)0x8000)
+#define FAR
+#define NEAR
+#define PASCAL
+#ifndef NULL
+#define NULL (void *)0
+#endif
+
+typedef struct { short left, top, right, bottom; } RECT;
+typedef RECT *LPRECT;
+typedef RECT *NPRECT;
+typedef RECT *PRECT;
+
+typedef struct {
+	HDC hdc;
+	BOOL	fErase;
+	RECT	rcPaint;
+	BOOL	fRestore, fIncUpdate;
+	BYTE	rgbReserved[16];
+} PAINTSTRUCT;
+
+typedef PAINTSTRUCT *PPAINTSTRUCT;
+typedef PAINTSTRUCT *NPPAINTSTRUCT;
+typedef PAINTSTRUCT *LPPAINTSTRUCT;
+
+typedef struct {
+	WORD	style;
+	LONG	(*lpfnWndProc)() __attribute__ ((packed));
+	short	cbClsExtra, cbWndExtra;
+	HANDLE	hInstance;
+	HICON	hIcon;
+	HCURSOR	hCursor;
+	HBRUSH	hbrBackground;
+	LPSTR	lpszMenuName, lpszClassName;
+} WNDCLASS;
+
+typedef  WNDCLASS * PWNDCLASS;
+typedef  WNDCLASS * NPWNDCLASS;
+typedef  WNDCLASS * LPWNDCLASS;
+
+typedef struct { int 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 WORD ATOM;
+
+typedef struct tagBITMAP
 {
-    unsigned char rgbBlue;
-    unsigned char rgbGreen;
-    unsigned char rgbRed;
-    unsigned char rgbReserved;
-};
+    unsigned short bmType;
+    unsigned short bmWidth;
+    unsigned short bmHeight;
+    unsigned short bmWidthBytes;
+    unsigned char  bmPlanes;
+    unsigned char  bmBitsPixel;
+    unsigned long  bmBits __attribute__ ((packed));
+} BITMAP;
+
+typedef BITMAP *PBITMAP;
+typedef BITMAP *NPBITMAP;
+typedef BITMAP *LPBITMAP;
+
+typedef struct { WORD lbStyle; DWORD lbColor; int lbHatch; } LOGBRUSH;
+typedef LOGBRUSH *PLOGBRUSH;
+typedef LOGBRUSH *NPLOGBRUSH;
+typedef LOGBRUSH *LPLOGBRUSH;
+
+#define LF_FACESIZE 32
+typedef struct {
+	int lfHeight, lfWidth, lfEscapement, lfOrientation, lfWeight;
+	BYTE lfItalic, lfUnderline, lfStrikeOut, lfCharSet;
+	BYTE lfOutPrecision, lfClipPrecision, lfQuality, lfPitchAndFamily;
+	BYTE lfFaceName[LF_FACESIZE];
+} LOGFONT;
+typedef LOGFONT *PLOGFONT;
+typedef LOGFONT *NPLOGFONT;
+typedef LOGFONT *LPLOGFONT;
+
+typedef struct PALETTEENTRY {
+	BYTE peRed, peGreen, peBlue, peFlags;
+} PALETTEENTRY;
+typedef PALETTEENTRY *LPPALETTEENTRY;
+
+typedef struct { 
+	WORD palVersion, palNumEntries;
+	PALETTEENTRY palPalEntries[1];
+} LOGPALETTE;
+typedef LOGPALETTE *PLOGPALETTE;
+typedef LOGPALETTE *NPLOGPALETTE;
+typedef LOGPALETTE *LPLOGPALETTE;
+
+typedef struct { WORD lopnStyle; POINT lopnWidth; DWORD lopnColor; } LOGPEN;
+typedef LOGPEN *PLOGPEN;
+typedef LOGPEN *NPLOGPEN;
+typedef LOGPEN *LPLOGPEN;
+
+typedef struct {
+	DWORD rdSize;
+	WORD rdFunction, rdParam[1];
+} METARECORD;
+typedef METARECORD *LPMETARECORD;
+typedef METARECORD *NPMETARECORD;
+typedef METARECORD *PMETARECORD;
+
+/* Unimplemented structs */
+typedef struct { BYTE rgbBlue, rgbGreen, rgbRed, rgbReserved; } RGBQUAD;
+typedef struct { BYTE rgbtBlue, rgbtGreen, rgbtRed; } RGBTRIPLE;
 
 typedef struct tagBITMAPINFOHEADER
 {
@@ -24,4 +164,821 @@
     unsigned long biClrImportant;
 } BITMAPINFOHEADER;
 
+typedef BITMAPINFOHEADER * LPBITMAPINFOHEADER;
+typedef BITMAPINFOHEADER * NPBITMAPINFOHEADER;
+typedef BITMAPINFOHEADER * PBITMAPINFOHEADER;
+
+typedef struct {
+	BITMAPINFOHEADER bmiHeader;
+	RGBQUAD	bmiColors[1];
+} BITMAPINFO;
+typedef BITMAPINFO *LPBITMAPINFO;
+typedef BITMAPINFO *NPBITMAPINFO;
+typedef BITMAPINFO *PBITMAPINFO;
+
+typedef struct tagBITMAPCOREHEADER
+{
+    unsigned long bcSize;
+    unsigned short bcWidth;
+    unsigned short bcHeight;
+    unsigned short bcPlanes;
+    unsigned short bcBitCount;
+} BITMAPCOREHEADER;
+
+typedef struct {
+	BYTE Id;  /* much more .... */
+} DCB;
+
+typedef struct {
+	BYTE i;  /* much more .... */
+} COMSTAT;
+
+typedef struct {
+	BYTE i;  /* much more .... */
+} TEXTMETRIC;
+typedef TEXTMETRIC *PTEXTMETRIC;
+typedef TEXTMETRIC *LPTEXTMETRIC;
+typedef TEXTMETRIC *NPTEXTMETRIC;
+
+typedef struct {
+	BYTE i;  /* much more .... */
+} KANJISTRUCT;
+typedef KANJISTRUCT *LPKANJISTRUCT;
+typedef KANJISTRUCT *NPKANJISTRUCT;
+typedef KANJISTRUCT *PKANJISTRUCT;
+
+typedef struct {
+	BYTE cBytes, fFixedDisk;
+	WORD nErrCode;
+	BYTE reserved[4], szPathName[128];
+} OFSTRUCT;
+typedef OFSTRUCT *POFSTRUCT;
+typedef OFSTRUCT *NPOFSTRUCT;
+typedef OFSTRUCT *LPOFSTRUCT;
+
+#define OF_READ 0x0000
+#define OF_WRITE 0x0001
+#define OF_READWRITE 0x0002
+
+typedef struct 
+{
+	HANDLE objectHandle[1];
+}HANDLETABLE;
+typedef HANDLETABLE *LPHANDLETABLE;
+
+#define CS_VREDRAW 0x0001
+#define CS_HREDRAW 0x0002
+#define CS_KEYCVTWINDOW 0x0004
+#define CS_KBLCLKS 0x0008
+
+#define MAKEINTRESOURCE(i) (LPSTR)((DWORD)((WORD)(i)))
+
+#define IDI_APPLICATION MAKEINTRESOURCE(32512)
+#define IDI_HAND MAKEINTRESOURCE(32513)
+#define IDI_QUESTION MAKEINTRESOURCE(32514)
+#define IDI_EXCLAMATION MAKEINTRESOURCE(32515)
+#define IDI_ASTERISK MAKEINTRESOURCE(32516)
+
+#define IDC_ARROW MAKEINTRESOURCE(32512)
+#define IDC_IBEAM MAKEINTRESOURCE(32513)
+#define IDC_WAIT MAKEINTRESOURCE(32514)
+#define IDC_CROSS MAKEINTRESOURCE(32515)
+#define IDC_UPARROW MAKEINTRESOURCE(32516)
+#define IDC_SIZE MAKEINTRESOURCE(32540)
+#define IDC_ICON MAKEINTRESOURCE(32541)
+#define IDC_SIZENWSE MAKEINTRESOURCE(32542)
+#define IDC_SIZENESW MAKEINTRESOURCE(32543)
+#define IDC_SIZEWE MAKEINTRESOURCE(32544)
+#define IDC_SIZENS MAKEINTRESOURCE(32545)
+
+enum { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, 
+	BLACK_BRUSH, NULL_BRUSH, HOLLOW_BRUSH, WHITE_PEN,
+	BLACK_PEN, NULL_PEN, OEM_FIXED_FONT, ANSI_FIXED_FONT, 
+	ANSI_VAR_FONT, SYSTEM_FONT_FONT, DEVICE_DEFAULT_FONT,
+	DEFAULT_PALETTE, SYSTEM_FIXED_FONT };
+
+enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE,
+	WM_SETFOCUS, WM_KILLFOCUS, WM_UNUSED1, WM_ENABLE, WM_SETREDRAW, 
+	WM_SETTEXT, WM_GETTEXT, WM_GETTEXTLENGTH, WM_PAINT, WM_CLOSE, 
+	WM_QUERYENDSESSION, WM_QUIT, WM_QUERYOPEN, WM_ERASEBKGND, 
+	WM_SYSCOLORCHANGE, WM_ENDSESSION, WM_UNUSED2,
+	WM_SHOWWINDOW, WM_CTLCOLOR, WM_WININICHANGE, WM_DEVMODECHANGE,
+	WM_ACTIVATEAPP, WM_FONTCHANGE, WM_TIMECHANGE, WM_CANCELMODE, WM_SETCURSOR,
+	WM_MOUSEACTIVATE, WM_CHILDACTIVATE, WM_QUEUESYNC, WM_GETMINMAXINFO,
+	WM_UNUSED3, WM_PAINTICON, WM_ICONERASEBKGND, WM_NEXTDLGCTL, 
+	WM_UNUSED4, WM_SPOOLERSTATUS, WM_DRAWITEM, WM_MEASUREITEM, 
+	WM_DELETEITEM, WM_VKEYTOITEM,
+	WM_CHARTOITEM, WM_SETFONT, WM_GETFONT };
+
+#define WM_COMMAND 0x0111
+
+enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED,
+	SW_MAXIMIZE, SW_SHOWNOACTIVATE, SW_SHOW, SW_MINIMIZE,
+	SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_RESTORE };
+
+#define MF_INSERT 0
+#define MF_CHANGE 0x0080
+#define MF_APPEND 0x0100
+#define MF_DELETE 0x0200
+#define MF_REMOVE 0x1000
+#define MF_BYCOMMAND 0
+#define MF_BYPOSITION 0x0400
+#define MF_SEPARATOR 0x080
+#define MF_ENABLED 0
+#define MF_GRAYED 0x0001
+#define MF_DISABLED 0x0002
+#define MF_UNCHECKED 0
+#define MF_CHECKED 0x0008
+#define MF_USECHECKBITMAPS 0x0200
+#define MF_STRING 0
+#define MF_BITMAP 0x0004
+#define MF_OWNERDRAW 0x0100
+#define MF_POPUP 0x0010
+#define MF_MENUBARBREAK 0x0020
+#define MF_MENUBREAK 0x0040
+#define MF_UNHILITE 0
+#define MF_HILITE 0x0080
+#define MF_SYSMENU 0x2000
+#define MF_HELP 0x4000
+#define MF_MOUSESELECT 0x8000
+
+#ifndef NOWINOFFSETS
+#define GCW_HBRBACKGROUND (-10)
 #endif
+
+#define MB_OK 0
+#define MB_ICONINFORMATION 0x0040
+
+#define DT_TOP 0
+#define DT_LEFT 0
+#define DT_CENTER 1
+#define DT_RIGHT 2
+#define DT_VCENTER 4
+#define DT_BOTTOM 8
+#define DT_WORDBREAK 16
+#define DT_SINGLELINE 32
+#define DT_EXPANDTABS 64
+#define DT_TABSTOP 128
+#define DT_NOCLIP 256
+#define DT_EXTERNALLEADING 512
+#define DT_CALCRECT 1024
+#define DT_NOPREFIX 2048
+#define DT_INTERNAL 4096
+
+
+
+
+#define WS_OVERLAPPED 0x00000000L
+#define WS_POPUP 0x80000000L
+#define WS_CHILD 0x40000000L
+#define WS_MINIMIZE 0x20000000L
+#define WS_VISIBLE 0x10000000L
+#define WS_DISABLED 0x08000000L
+#define WS_CLIPSIBLINGS 0x04000000L
+#define WS_CLIPCHILDREN 0x02000000L
+#define WS_MAXIMIZE 0x01000000L
+#define WS_CAPTION 0x00C00000L
+#define WS_BORDER 0x00800000L
+#define WS_DLGFRAME 0x00400000L
+#define WS_VSCROLL 0x00200000L
+#define WS_HSCROLL 0x00100000L
+#define WS_SYSMENU 0x00080000L
+#define WS_THICKFRAME 0x00040000L
+#define WS_GROUP 0x00020000L
+#define WS_TABSTOP 0x00010000L
+#define WS_MINIMIZEBOX 0x00020000L
+#define WS_MINIMIZEBOX 0x00020000L
+#define WS_MAXIMIZEBOX 0x00010000L
+#define WS_TILED WS_OVERLAPPED
+#define WS_ICONIC WS_MINIMIZE
+#define WS_SIZEBOX WS_THICKFRAME
+#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME| WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
+#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
+#define WS_CHILDWINDOW (WS_CHILD)
+#define WS_TILEDWINDOW (WS_OVERLAPPEDWINDOW)
+
+#define GMEM_MOVEABLE	0x0002
+
+#ifdef _WIN_CODE_SECTION
+#define F(ret,name) ret name(void) {dte(#name, 0);}
+#define Fa(ret,name,t1,a1) ret name(t1 a1) {dte(#name, 1, #t1,a1); }
+#define Fb(ret,name,t1,a1,t2,a2) ret name(t1 a1,t2 a2) { dte(#name, 2, #t1,a1,#t2,a2); }
+#define Fc(ret,name,t1,a1,t2,a2,t3,a3) ret name(t1 a1,t2 a2,t3 a3){dte(#name,3,#t1,a1,#t2,a2,#t3,a3); }
+#define Fd(ret,name,t1,a1,t2,a2,t3,a3,t4,a4) ret name(t1 a1,t2 a2,t3 a3,t4 a4){dte(#name,4,#t1,a1,#t2,a2,#t3,a3,#t4,a4);}
+#define Fe(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) ret name( t1 a1,t2 a2,t3 a3,t4 a4,t5 a5) {dte(#name,5,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5);}
+#define Ff(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6) {dte(#name,6,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6);}
+#define Fg(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) ret name( t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7) {dte(#name,7,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7);}
+#define Fh(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8){dte(#name,8,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8);}
+#define Fi(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9) {dte(#name,9,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8,#t9,a9);}
+#define Fj(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10){dte(#name,10,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8,#t9,a9,#t10,a10);}
+#define Fk(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11) ret name (t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11){dte(#name,11, #t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8,#t9,a9,#t10,a10,#t11,a11);}
+#define Fl(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12){dte(#name,12,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8,#t9,a9,#t10,a10,#t11,a11,#t12,a12);}
+#define Fm(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13){dte(#name,13,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8,#t9,a9,#t10,a10,#t11,a11,#t12,a12,#t13,a13);}
+#define Fn(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13,t14,a14) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13,t14 a14){dte(#name,14,#t1,a1,#t2,a2,#t3,a3,#t4,a4,#t5,a5,#t6,a6,#t7,a7,#t8,a8,#t9,a9,#t10,a10,#t11,a11,#t12,a12,#t13,a13,#t14,a14);}
+#else
+#define F(ret,name) ret name(void);
+#define Fa(ret,name,t1,a1) ret name(t1 a1);
+#define Fb(ret,name,t1,a1,t2,a2) ret name(t1 a1,t2 a2);
+#define Fc(ret,name,t1,a1,t2,a2,t3,a3) ret name(t1 a1,t2 a2,t3 a3);
+#define Fd(ret,name,t1,a1,t2,a2,t3,a3,t4,a4) ret name(t1 a1,t2 a2,t3 a3,t4 a4);
+#define Fe(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) ret name( t1 a1,t2 a2,t3 a3,t4 a4,t5 a5);
+#define Ff(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6);
+#define Fg(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) ret name( t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7);
+#define Fh(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8);
+#define Fi(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9);
+#define Fj(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10);
+#define Fk(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11) ret name (t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11);
+#define Fl(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12);
+#define Fm(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13);
+#define Fn(ret,name,t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7,t8,a8,t9,a9,t10,a10,t11,a11,t12,a12,t13,a13,t14,a14) ret name(t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13,t14 a14);
+#endif
+
+int wsprintf(LPSTR a,LPSTR b,...);
+#endif
+
+#if !defined(_WIN_CODE_SECTION) || defined(_WINARGS)
+
+/* Implemented functions */
+F(HMENU,CreateMenu)
+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(BOOL,TranslateMessage,LPMSG,a)
+Fa(int,_lclose,int,a)
+Fb(int,_lopen,LPSTR,a,int,b)
+Fa(int,lstrlen,LPSTR,a)
+Fa(long,DispatchMessage,MSG *,msg)
+Fa(void,UpdateWindow,HWND,a)
+Fb(BOOL,ExitWindows,DWORD,dwReserved,WORD,wReturnCode)
+Fb(BOOL,ShowWindow,HWND,a,int,b) 
+Fb(HDC,BeginPaint,HWND,a,LPPAINTSTRUCT,b) 
+Fb(LPSTR,lstrcat,LPSTR,a,LPSTR,b )
+Fb(LPSTR,lstrcpy,LPSTR,a,LPSTR,b )
+Fb(int,_lcreat,LPSTR,a,int,b)
+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)
+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)
+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,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)
+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)
+Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,int,x,int,y,int,w,int,h,HWND,d,HMENU,e,,HANDLE i,LPSTR,g)
+#endif
+
+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)
+F(HWND,GetActiveWindow)
+F(HWND,GetCapture)
+F(HWND,GetClipboardOwner)
+F(HWND,GetClipboardViewer)
+F(HWND,GetDesktopHwnd)
+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)
+F(WORD,GetCurrentPDB)
+F(WORD,GetDoubleClickTime)
+F(WORD,GetNumTasks)
+F(WORD,GetVersion)
+F(int,CountClipboardFormats)
+F(int,GetKBCodePage)
+F(int,GetThresholdStatus)
+F(int,OpenSound)
+F(int,ProfInsChk)
+F(int,StartSound)
+F(int,StopSound)
+F(int,SyncAllVoices)
+F(long,GetDialogBaseUnits)
+F(void,CloseSound)
+F(void,DebugBreak)
+F(void,DestroyCaret)
+F(void,ProfClear)
+F(void,ProfFinish)
+F(void,ProfFlush)
+F(void,ProfStart)
+F(void,ProfStop)
+F(void,ReleaseCapture)
+F(void,SwitchStackBack)
+F(void,WaitMessage)
+F(void,Yield)
+Fa(ATOM,AddAtom,LPSTR,a)
+Fa(ATOM,DeleteAtom,ATOM,a)
+Fa(ATOM,FindAtom,LPSTR,a)
+Fa(ATOM,GlobalAddAtom,LPSTR,a)
+Fa(ATOM,GlobalDeleteAtom,ATOM,a)
+Fa(ATOM,GlobalFindAtom,LPSTR,a)
+Fa(BOOL,DeleteDC,HDC,a)
+Fa(BOOL,DeleteMetaFile,HANDLE,a)
+Fa(BOOL,DeleteObject,HANDLE,a)
+Fa(BOOL,DestroyCursor,HCURSOR,a)
+Fa(BOOL,DestroyIcon,HICON,a)
+Fa(BOOL,DestroyMenu,HMENU,a)
+Fa(BOOL,DestroyWindow,HWND,a)
+Fa(BOOL,EnableHardwareInput,BOOL,a)
+Fa(BOOL,FreeModule,HANDLE,a)
+Fa(BOOL,FreeResource,HANDLE,a)
+Fa(BOOL,GlobalUnWire,HANDLE,a)
+Fa(BOOL,GlobalUnfix,HANDLE,a)
+Fa(BOOL,GlobalUnlock,HANDLE,a)
+Fa(BOOL,InitAtomTable,int,a)
+Fa(BOOL,IsClipboardFormatAvailable,WORD,a)
+Fa(BOOL,IsIconic,HWND,a)
+Fa(BOOL,IsRectEmpty,LPRECT,a)
+Fa(BOOL,IsTwoByteCharPrefix,char,a)
+Fa(BOOL,IsWindow,HWND,a)
+Fa(BOOL,IsWindowEnabled,HWND,a)
+Fa(BOOL,IsWindowVisible,HWND,a)
+Fa(BOOL,IsZoomed,HWND,a)
+Fa(BOOL,LocalUnlock,HANDLE,a)
+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)
+Fa(DWORD,GetAspectRatioFilter,HDC,a)
+Fa(DWORD,GetBitmapDimension,HBITMAP,a)
+Fa(DWORD,GetBkColor,HDC,a)
+Fa(DWORD,GetBrushOrg,HDC,a)
+Fa(DWORD,GetCurrentPosition,HDC,a)
+Fa(DWORD,GetDCOrg,HDC,a)
+Fa(DWORD,GetFreeSpace,WORD,a)
+Fa(DWORD,GetSysColor,int,a)
+Fa(DWORD,GetTextColor,HDC,a)
+Fa(DWORD,GetViewportExt,HDC,a)
+Fa(DWORD,GetViewportOrg,HDC,a)
+Fa(DWORD,GetWindowExt,HDC,a)
+Fa(DWORD,GetWindowOrg,HDC,a)
+Fa(DWORD,GlobalCompact,DWORD,a)
+Fa(DWORD,GlobalHandle,WORD,a)
+Fa(DWORD,GlobalSize,HANDLE,a)
+Fa(DWORD,OemKeyScan,WORD,a)
+Fa(FARPROC,LocalNotify,FARPROC,a)
+Fa(HANDLE,BeginDeferWindowPos,int,nNumWindows)
+Fa(HANDLE,CloseMetaFile,HANDLE,a)
+Fa(HANDLE,CreateMetaFile,LPSTR,a)
+Fa(HANDLE,GetAtomHandle,ATOM,a)
+Fa(HANDLE,GetClipboardData,WORD,a)
+Fa(HANDLE,GetCodeHandle,FARPROC,a)
+Fa(HANDLE,GetMetaFile,LPSTR,a)
+Fa(HANDLE,GetMetaFileBits,HANDLE,a)
+Fa(HANDLE,GetModuleHandle,LPSTR,a)
+Fa(HANDLE,GetStockObject,int,a)
+Fa(HANDLE,GetWindowTask,HWND,a)
+Fa(HANDLE,GlobalFree,HANDLE,a)
+Fa(HANDLE,GlobalLRUNewest,HANDLE,a)
+Fa(HANDLE,GlobalLRUOldest,HANDLE,a)
+Fa(HANDLE,LoadLibrary,LPSTR,a)
+Fa(HANDLE,LocalFree,HANDLE,a)
+Fa(HANDLE,LocalHandle,WORD,a)
+Fa(HANDLE,LockSegment,WORD,a)
+Fa(HANDLE,SetMetaFileBits,HANDLE,a)
+Fa(HANDLE,UnlockSegment,WORD,a)
+Fa(HBITMAP,CreateBitmapIndirect,BITMAP FAR*,a)
+Fa(HBRUSH,CreateBrushIndirect,LOGBRUSH FAR*,a)
+Fa(HBRUSH,CreatePatternBrush,HBITMAP,a)
+Fa(HBRUSH,CreateSolidBrush,DWORD,a)
+Fa(HCURSOR,SetCursor,HCURSOR,a)
+Fa(HDC,CreateCompatibleDC,HDC,a)
+Fa(HDC,GetDC,HWND,a)
+Fa(HDC,GetWindowDC,HWND,a)
+Fa(HFONT,CreateFontIndirect,LOGFONT FAR*,a)
+Fa(HMENU,GetMenu,HWND,a)
+Fa(HMENU,LoadMenuIndirect,LPSTR,a)
+Fa(HPALETTE,CreatePalette,LPLOGPALETTE,a)
+Fa(HPEN,CreatePenIndirect,LOGPEN FAR*,a)
+Fa(HRGN,CreateEllipticRgnIndirect,LPRECT,a)
+Fa(HRGN,CreateRectRgnIndirect,LPRECT,a)
+Fa(HWND,GetLastActivePopup,HWND,a)
+Fa(HWND,GetParent,HWND,a)
+Fa(HWND,GetTopWindow,HWND,a)
+Fa(HWND,SetActiveWindow,HWND,a)
+Fa(HWND,SetCapture,HWND,a)
+Fa(HWND,SetClipboardViewer,HWND,a)
+Fa(HWND,SetFocus,HWND,a)
+Fa(HWND,SetSysModalWindow,HWND,a)
+Fa(HWND,WindowFromPoint,POINT,a)
+Fa(LONG,SetSwapAreaSize,WORD,a)
+Fa(LPSTR,AnsiLower,LPSTR,a)
+Fa(LPSTR,AnsiNext,LPSTR,a)
+Fa(LPSTR,AnsiUpper,LPSTR,a)
+Fa(LPSTR,GlobalLock,HANDLE,a)
+Fa(LPSTR,GlobalWire,HANDLE,a)
+Fa(LPSTR,LockResource,HANDLE,a)
+Fa(void,GlobalFix,HANDLE,a)
+Fa(void,GlobalNotify,FARPROC,a)
+Fa(void,LimitEmsPages,DWORD,a)
+Fa(void,SetConvertHook,BOOL,a)
+Fa(WORD,AllocDStoCSAlias,WORD,a)
+Fa(WORD,AllocSelector,WORD,a)
+Fa(WORD,ArrangeIconicWindows,HWND,a)
+Fa(WORD,EnumClipboardFormats,WORD,a)
+Fa(WORD,FreeSelector,WORD,a)
+Fa(WORD,GetDriveType,int,a)
+Fa(WORD,GetMenuItemCount,HMENU,a)
+Fa(WORD,GetTextAlign,HDC,a)
+Fa(WORD,GlobalFlags,HANDLE,a)
+Fa(WORD,GlobalPageLock,HANDLE,a)
+Fa(WORD,GlobalPageUnlock,HANDLE,a)
+Fa(WORD,LocalCompact,WORD,a)
+Fa(WORD,LocalFlags,HANDLE,a)
+Fa(WORD,LocalSize,HANDLE,a)
+Fa(WORD,RealizePalette,HDC,a)
+Fa(WORD,RegisterClipboardFormat,LPSTR,a)
+Fa(WORD,RegisterWindowMessage,LPSTR,a)
+Fa(WORD,SetHandleCount,WORD,a)
+Fa(WORD,VkKeyScan,WORD,a)
+Fa(char NEAR*,LocalLock,HANDLE,a)
+Fa(int,AddFontResource,LPSTR,a)
+Fa(int,Catch,LPCATCHBUF,a)
+Fa(int,ClearCommBreak,int,a)
+Fa(int,CloseComm,int,a)
+Fa(int,CountVoiceNotes,int,a)
+Fa(int,GetAsyncKeyState,int,a)
+Fa(int,GetBkMode,HDC,a)
+Fa(int,GetDlgCtrlID,HWND,a)
+Fa(int,GetKeyState,int,a)
+Fa(int,GetKeyboardType,int,a)
+Fa(int,GetMapMode,HDC,a)
+Fa(int,GetModuleUsage,HANDLE,a)
+Fa(int,GetPolyFillMode,HDC,a)
+Fa(int,GetROP2,HDC,a)
+Fa(int,GetStretchBltMode,HDC,a)
+Fa(int,GetSystemMetrics,int,a)
+Fa(int,GetTextCharacterExtra,HDC,a)
+Fa(int,GetWindowTextLength,HWND,a)
+Fa(int,SaveDC,HDC,a)
+Fa(int,SetCommBreak,int,a)
+Fa(int,SetCommState,DCB*,a)
+Fa(int,ShowCursor,BOOL,a)
+Fa(int,UpdateColors,HDC,a)
+Fa(int,WaitSoundState,int,a)
+Fa(void,BringWindowToTop,HWND,a)
+Fa(void,ClipCursor,LPRECT,a)
+Fa(void,CloseWindow,HWND,a)
+Fa(void,DrawMenuBar,HWND,a)
+Fa(void,EndDeferWindowPos,HANDLE,hWinPosInfo)
+Fa(void,FatalExit,int,a)
+Fa(void,FreeLibrary,HANDLE,a)
+Fa(void,FreeProcInstance,FARPROC,a)
+Fa(void,GetCaretPos,LPPOINT,a)
+Fa(void,GetCursorPos,LPPOINT,a)
+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)
+Fa(void,SetKeyboardState,BYTE FAR*,a)
+Fa(void,SetRectEmpty,LPRECT,a)
+Fa(void,ShowCaret,HWND,a)
+Fa(void,SwapRecording,WORD,a)
+Fb(BOOL,CallMsgFilter,LPMSG,a,int,b)
+Fb(BOOL,ChangeClipboardChain,HWND,a,HWND,b)
+Fb(BOOL,EnableWindow,HWND,a,BOOL,b)
+Fb(BOOL,EnumWindows,FARPROC,a,LONG,b)
+Fb(BOOL,EqualRect,LPRECT,a,LPRECT,b)
+Fb(BOOL,EqualRgn,HRGN,a,HRGN,b)
+Fb(BOOL,FlashWindow,HWND,a,BOOL,b)
+Fb(BOOL,GetTextMetrics,HDC,a,LPTEXTMETRIC,b)
+Fb(BOOL,InvertRgn,HDC,a,HRGN,b)
+Fb(BOOL,IsChild,HWND,a,HWND,b)
+Fb(BOOL,IsDialogMessage,HWND,a,LPMSG,b)
+Fb(BOOL,KillTimer,HWND,a,int,b)
+Fb(BOOL,OemToAnsi,LPSTR,a,LPSTR,b)
+Fb(BOOL,PaintRgn,HDC,a,HRGN,b)
+Fb(BOOL,PlayMetaFile,HDC,a,HANDLE,b)
+Fb(BOOL,PtInRect,LPRECT,a,POINT,b)
+Fb(BOOL,RectInRegion,HRGN,a,LPRECT,b)
+Fb(BOOL,RectVisible,HDC,a,LPRECT,b)
+Fb(BOOL,ResizePalette,HPALETTE,a,WORD,b)
+Fb(BOOL,RestoreDC,HDC,a,int,b)
+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)
+Fb(DWORD,SetTextColor,HDC,a,DWORD,b)
+Fb(FARPROC,GetProcAddress,HANDLE,a,LPSTR,b)
+Fb(FARPROC,MakeProcInstance,FARPROC,a,HANDLE,b)
+Fb(FARPROC,SetWindowsHook,int,a,FARPROC,b)
+Fb(HANDLE,CopyMetaFile,HANDLE,a,LPSTR,b)
+Fb(HANDLE,GetProp,HWND,a,LPSTR,b)
+Fb(HANDLE,GlobalAlloc,WORD,a,DWORD,b)
+Fb(HANDLE,LoadAccelerators,HANDLE,a,LPSTR,b)
+Fb(HANDLE,LoadModule,LPSTR,a,LPVOID,b)
+Fb(HANDLE,LoadResource,HANDLE,a,HANDLE,b)
+Fb(HANDLE,LocalAlloc,WORD,a,WORD,b)
+Fb(HANDLE,RemoveProp,HWND,a,LPSTR,b)
+Fb(HANDLE,SelectObject,HDC,a,HANDLE,b)
+Fb(HANDLE,SetClipboardData,WORD,a,HANDLE,b)
+Fb(HBITMAP,LoadBitmap,HANDLE,a,LPSTR,b)
+Fb(HBRUSH,CreateDIBPatternBrush,HANDLE,a,WORD,b)
+Fb(HBRUSH,CreateHatchBrush,int,a,DWORD,b)
+Fb(HCURSOR,LoadCursor,HANDLE,a,LPSTR,b)
+Fb(HICON,LoadIcon,HANDLE,a,LPSTR,b)
+Fb(HMENU,GetSubMenu,HMENU,a,int,b)
+Fb(HMENU,GetSystemMenu,HWND,a,BOOL,b)
+Fb(HMENU,LoadMenu,HANDLE,a,LPSTR,b)
+Fb(HWND,ChildWindowFromPoint,HWND,a,POINT,b)
+Fb(HWND,FindWindow,LPSTR,a,LPSTR,b)
+Fb(HWND,GetDlgItem,HWND,a,int,b)
+Fb(HWND,GetNextWindow,HWND,a,WORD,b)
+Fb(HWND,GetWindow,HWND,a,WORD,b)
+Fb(HWND,SetParent,HWND,a,HWND,b)
+Fb(LONG,GetClassLong,HWND,a,int,b)
+Fb(LONG,GetWindowLong,HWND,a,int,b)
+Fb(LPSTR,AnsiPrev,LPSTR,a,LPSTR,b)
+Fb(WORD FAR*,SetCommEventMask,int,a,WORD,b)
+Fb(WORD,AnsiLowerBuff,LPSTR,a,WORD,b)
+Fb(WORD,AnsiUpperBuff,LPSTR,a,WORD,b)
+Fb(WORD,ChangeSelector,WORD,a,WORD,b)
+Fb(WORD,GetClassWord,HWND,a,int,b)
+Fb(WORD,GetCommEventMask,int,a,int,b)
+Fb(WORD,GetMenuItemID,HMENU,a,int,b)
+Fb(WORD,GetNearestPaletteIndex,HPALETTE,a,DWORD,b)
+Fb(WORD,GetSystemDirectory,LPSTR,a,WORD,b)
+Fb(WORD,GetSystemPaletteUse,HDC,a,WORD,b)
+Fb(WORD,GetWindowWord,HWND,a,int,b)
+Fb(WORD,GetWindowsDirectory,LPSTR,a,WORD,b)
+Fb(WORD,IsDlgButtonChecked,HWND,a,int,b)
+Fb(WORD,LocalShrink,HANDLE,a,WORD,b)
+Fb(WORD,MapVirtualKey,WORD,a,WORD,b)
+Fb(WORD,SetSystemPaletteUse,HDC,a,WORD,b)
+Fb(WORD,SetTextAlign,HDC,a,WORD,b)
+Fb(WORD,SizeofResource,HANDLE,a,HANDLE,b)
+Fb(WORD,WinExec,LPSTR,a,WORD,b)
+Fb(int,AccessResource,HANDLE,a,HANDLE,b)
+Fb(int,AnsiToOem,LPSTR,a,LPSTR,b)
+Fb(int,BuildCommDCB,LPSTR,a,DCB*,b)
+Fb(int,ConvertRequest,HWND,a,LPKANJISTRUCT,b)
+Fb(int,CopyRect,LPRECT,a,LPRECT,b)
+Fb(int,EnumProps,HWND,a,FARPROC,b)
+Fb(int,EscapeCommFunction,int,a,int,b)
+Fb(int,ExcludeUpdateRgn,HDC,a,HWND,b)
+Fb(int,FlushComm,int,a,int,b)
+Fb(int,GetClipBox,HDC,a,LPRECT,b)
+Fb(int,GetCommError,int,a,COMSTAT*,b)
+Fb(int,GetCommState,int,a,DCB*,b)
+Fb(int,GetDeviceCaps,HDC,a,int,b)
+Fb(int,GetPriorityClipboardFormat,WORD FAR*,a,int,b)
+Fb(int,GetRgnBox,HRGN,a,LPRECT,b)
+Fb(int,GetScrollPos,HWND,a,int,b)
+Fb(int,ReleaseDC,HWND,a,HDC,b)
+Fb(int,SelectClipRgn,HDC,a,HRGN,b)
+Fb(int,SetBkMode,HDC,a,int,b)
+Fb(int,SetMapMode,HDC,a,int,b)
+Fb(int,SetPolyFillMode,HDC,a,int,b)
+Fb(int,SetROP2,HDC,a,int,b)
+Fb(int,SetSoundNoise,int,a,int,b)
+Fb(int,SetStretchBltMode,HDC,a,int,b)
+Fb(int,SetTextCharacterExtra,HDC,a,int,b)
+Fb(int,SetVoiceQueueSize,int,a,int,b)
+Fb(int,SetVoiceThreshold,int,a,int,b)
+Fb(int,TransmitCommChar,int,a,char,b)
+Fb(int,UngetCommChar,int,a,char,b)
+Fb(void,ClientToScreen,HWND,a,LPPOINT,b)
+Fb(void,DrawFocusRect,HDC,a,LPRECT,b)
+Fb(void,EndDialog,HWND,a,int,b)
+Fb(void,GetCodeInfo,FARPROC,lpProc,LPVOID,lpSegInfo)
+Fb(void,GetWindowRect,HWND,a,LPRECT,b)
+Fb(void,InvertRect,HDC,a,LPRECT,b)
+Fb(void,MapDialogRect,HWND,a,LPRECT,b)
+Fb(void,ProfSampRate,int,a,int,b)
+Fb(void,ProfSetup,int,a,int,b)
+Fb(void,ScreenToClient,HWND,a,LPPOINT,b)
+Fb(void,SetCaretPos,int,a,int,b)
+Fb(void,SetCursorPos,int,a,int,b)
+Fb(void,SetWindowText,HWND,a,LPSTR,b)
+Fb(void,ShowOwnedPopups,HWND,a,BOOL,b)
+Fb(void,Throw,LPCATCHBUF,a,int,b)
+Fb(void,ValidateRect,HWND,a,LPRECT,b)
+Fb(void,ValidateRgn,HWND,a,HRGN,b)
+Fc(BOOL,CheckMenuItem,HMENU,a,WORD,b,WORD,c)
+Fc(BOOL,DPtoLP,HDC,a,LPPOINT,b,int,c)
+Fc(BOOL,DeleteMenu,HMENU,a,WORD,b,WORD,c)
+Fc(BOOL,DlgDirSelect,HWND,a,LPSTR,b,int,c)
+Fc(BOOL,DlgDirSelectComboBox,HWND,a,LPSTR,b,int,c)
+Fc(BOOL,EnableMenuItem,HMENU,a,WORD,b,WORD,c)
+Fc(BOOL,EnumChildWindows,HWND,a,FARPROC,b,LONG,c)
+Fc(BOOL,EnumTaskWindows,HANDLE,a,FARPROC,b,LONG,c)
+Fc(BOOL,FillRgn,HDC,a,HRGN,b,HBRUSH,c)
+Fc(BOOL,GetClassInfo,HANDLE,a,LPSTR,b,LPWNDCLASS,c)
+Fc(BOOL,GetUpdateRect,HWND,a,LPRECT,b,BOOL,c)
+Fc(BOOL,LPtoDP,HDC,a,LPPOINT,b,int,c)
+Fc(BOOL,LocalInit,WORD,a,WORD,b,WORD,c)
+Fc(BOOL,Polygon,HDC,a,LPPOINT,b,int,c)
+Fc(BOOL,Polyline,HDC,a,LPPOINT,b,int,c)
+Fc(BOOL,PtInRegion,HRGN,a,int,b,int,c)
+Fc(BOOL,PtVisible,HDC,a,int,b,int,c)
+Fc(BOOL,RemoveMenu,HMENU,a,WORD,b,WORD,c)
+Fc(BOOL,SetProp,HWND,a,LPSTR,b,HANDLE,c)
+Fc(BOOL,WriteProfileString,LPSTR,a,LPSTR,b,LPSTR,c)
+Fc(DWORD,GetPixel,HDC,a,int,b,int,c)
+Fc(DWORD,GetTextExtent,HDC,a,LPSTR,b,int,c)
+Fc(DWORD,OffsetViewportOrg,HDC,a,int,b,int,c)
+Fc(DWORD,OffsetWindowOrg,HDC,a,int,b,int,c)
+Fc(DWORD,SetBitmapDimension,HBITMAP,a,int,b,int,c)
+Fc(DWORD,SetBrushOrg,HDC,a,int,b,int,c)
+Fc(DWORD,SetViewportExt,HDC,a,int,b,int,c)
+Fc(DWORD,SetViewportOrg,HDC,a,int,b,int,c)
+Fc(DWORD,SetWindowExt,HDC,a,int,b,int,c)
+Fc(DWORD,SetWindowOrg,HDC,a,int,b,int,c)
+Fc(FARPROC,SetResourceHandler,HANDLE,a,LPSTR,b,FARPROC,c)
+Fc(HANDLE,AllocResource,HANDLE,a,HANDLE,b,DWORD,c)
+Fc(HANDLE,FindResource,HANDLE,a,LPSTR,b,LPSTR,c)
+Fc(HANDLE,GlobalReAlloc,HANDLE,a,DWORD,b,WORD,c)
+Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c)
+Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,int,b,int,c)
+Fc(HBITMAP,CreateDiscardableBitmap,HDC,a,int,b,int,c)
+Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c)
+Fc(HPEN,CreatePen,int,a,int,b,DWORD,c)
+Fc(HRGN,CreatePolygonRgn,LPPOINT,a,int,b,int,c)
+Fc(HWND,GetNextDlgGroupItem,HWND,a,HWND,b,BOOL,c)
+Fc(HWND,GetNextDlgTabItem,HWND,a,HWND,b,BOOL,c)
+Fc(LONG,GetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
+Fc(LONG,SetBitmapBits,HBITMAP,a,DWORD,b,LPSTR,c)
+Fc(LONG,SetClassLong,HWND,a,int,b,LONG,c)
+Fc(LONG,SetWindowLong,HWND,a,int,b,LONG,c)
+Fc(WORD,GetAtomName,ATOM,a,LPSTR,b,int,c)
+Fc(WORD,GetMenuState,HMENU,a,WORD,b,WORD,c)
+Fc(WORD,GetProfileInt,LPSTR,a,LPSTR,b,int,c)
+Fc(WORD,GlobalGetAtomName,ATOM,a,LPSTR,b,int,c)
+Fc(WORD,SetClassWord,HWND,a,int,b,WORD,c)
+Fc(WORD,SetWindowWord,HWND,a,int,b,WORD,c)
+Fc(int,FrameRect,HDC,a,LPRECT,b,HBRUSH,c)
+Fc(int,GetClassName,HWND,a,LPSTR,b,int,c)
+Fc(int,GetClipboardFormatName,WORD,a,LPSTR,b,int,c)
+Fc(int,GetEnvironment,LPSTR,a,LPSTR,b,WORD,c)
+Fc(int,GetInstanceData,HANDLE,a,NPSTR,b,int,c)
+Fc(int,GetKeyNameText,LONG,a,LPSTR,b,int,c)
+Fc(int,GetModuleFileName,HANDLE,a,LPSTR,b,int,c)
+Fc(int,GetObject,HANDLE,a,int,b,LPSTR,c)
+Fc(int,GetTextFace,HDC,a,int,b,LPSTR,c)
+Fc(int,GetUpdateRgn,HWND,a,HRGN,b,BOOL,c)
+Fc(int,GetWindowText,HWND,a,LPSTR,b,int,c)
+Fc(int,IntersectRect,LPRECT,a,LPRECT,b,LPRECT,c)
+Fc(int,MulDiv,int,a,int,b,int,c)
+Fc(int,OffsetClipRgn,HDC,a,int,b,int,c)
+Fc(int,OffsetRgn,HRGN,a,int,b,int,c)
+Fc(int,OpenComm,LPSTR,a,WORD,b,WORD,c)
+Fc(int,OpenFile,LPSTR,a,LPOFSTRUCT,b,WORD,c)
+Fc(int,ReadComm,int,a,LPSTR,b,int,c)
+Fc(int,SetEnvironment,LPSTR,a,LPSTR,b,WORD,c)
+Fc(int,SetTextJustification,HDC,a,int,b,int,c)
+Fc(int,SetVoiceEnvelope,int,a,int,b,int,c)
+Fc(int,SetVoiceSound,int,a,LONG,b,int,c)
+Fc(int,TranslateAccelerator,HWND,a,HANDLE,b,LPMSG,c)
+Fc(int,UnionRect,LPRECT,a,LPRECT,b,LPRECT,c)
+Fc(int,WriteComm,int,a,LPSTR,b,int,c)
+Fc(int,wvsprintf,LPSTR,a,LPSTR,b,LPSTR,c)
+Fc(void,AdjustWindowRect,LPRECT,a,LONG,b,BOOL,c)
+Fc(void,AnsiToOemBuff,LPSTR,a,LPSTR,b,int,c)
+Fc(void,CheckDlgButton,HWND,a,int,b,WORD,c)
+Fc(void,InflateRect,LPRECT,a,int,b,int,c)
+Fc(void,InvalidateRect,HWND,a,LPRECT,b,BOOL,c)
+Fc(void,InvalidateRgn,HWND,a,HRGN,b,BOOL,c)
+Fc(void,OemToAnsiBuff,LPSTR,a,LPSTR,b,int,c)
+Fc(void,OffsetRect,LPRECT,a,int,b,int,c)
+Fc(void,SetDlgItemText,HWND,a,int,b,LPSTR,c)
+Fc(void,SetSysColors,int,a,LPINT,b,LONG*,c)
+Fc(void,ShowScrollBar,HWND,a,WORD,b,BOOL,c)
+Fc(void,SwitchStackTo,WORD,a,WORD,b,WORD,c)
+Fd(BOOL,DrawIcon,HDC,a,int,b,int,c,HICON,d)
+Fd(BOOL,EnumMetaFile,HDC,a,LOCALHANDLE,b,FARPROC,c,BYTE FAR*,d)
+Fd(BOOL,FloodFill,HDC,a,int,b,int,c,DWORD,d)
+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)
+Fd(DWORD,SetPixel,HDC,a,int,b,int,c,DWORD,d)
+Fd(HDC,CreateDC,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d)
+Fd(HDC,CreateIC,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d)
+Fd(HRGN,CreateEllipticRgn,int,a,int,b,int,c,int,d)
+Fd(HRGN,CreatePolyPolygonRgn,LPPOINT,a,LPINT,b,int,c,int,d)
+Fd(HRGN,CreateRectRgn,int,a,int,b,int,c,int,d)
+Fd(HWND,CreateDialog,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d)
+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)
+Fd(WORD,GetSystemPaletteEntries,HDC,a,WORD,b,WORD,c,LPPALETTEENTRY,d)
+Fd(WORD,SetPaletteEntries,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d)
+Fd(WORD,SetTimer,HWND,a,int,d,WORD,b,FARPROC,c)
+Fd(int,CombineRgn,HRGN,a,HRGN,b,HRGN,c,int,d)
+Fd(int,DialogBox,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d)
+Fd(int,DialogBoxIndirect,HANDLE,a,HANDLE,b,HWND,c,FARPROC,d)
+Fd(int,EnumFonts,HDC,a,LPSTR,b,FARPROC,c,LPSTR,d)
+Fd(int,EnumObjects,HDC,a,int,b,FARPROC,c,LPSTR,d)
+Fd(int,GetDlgItemText,HWND,a,int,b,LPSTR,c,int,d)
+Fd(int,GetTempFileName,BYTE,a,LPSTR,b,WORD,c,LPSTR,d)
+Fd(int,LoadString,HANDLE,a,WORD,b,LPSTR,c,int,d)
+Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d)
+Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d)
+Fd(int,SetVoiceNote,int,a,int,b,int,c,int,d)
+Fd(void,AdjustWindowRectEx,LPRECT,a,LONG,b,BOOL,c,DWORD,d)
+Fd(void,AnimatePalette,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d)
+Fd(void,CheckRadioButton,HWND,a,int,b,int,c,int,d)
+Fd(void,CreateCaret,HWND,a,HBITMAP,b,int,c,int,d)
+Fd(void,GetScrollRange,HWND,a,int,b,LPINT,c,LPINT,d)
+Fd(void,PlayMetaFileRecord,HDC,a,LPHANDLETABLE,b,LPMETARECORD,c,WORD,d)
+Fd(void,SetDlgItemInt,HWND,a,int,b,WORD,c,BOOL,d)
+Fe(BOOL,ChangeMenu,HMENU,a,WORD,b,LPSTR,c,WORD,d,WORD,e)
+Fe(BOOL,Ellipse,HDC,a,int,b,int,c,int,d,int,e)
+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)
+Fe(DWORD,ScaleViewportExt,HDC,a,int,b,int,c,int,d,int,e)
+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)
+Fe(int,DialogBoxParam,HANDLE,a,LPSTR,b,HWND,c,FARPROC,d,LONG,e)
+Fe(int,DlgDirList,HWND,a,LPSTR,b,int,c,int,d,WORD,e)
+Fe(int,DlgDirListComboBox,HWND,a,LPSTR,b,int,c,int,d,WORD,e)
+Fe(int,Escape,HDC,a,int,b,int,c,LPSTR,d,LPSTR,e)
+Fe(int,ExcludeClipRect,HDC,a,int,b,int,c,int,d,int,e)
+Fe(int,GetMenuString,HMENU,a,WORD,b,LPSTR,c,int,d,WORD,e)
+Fe(int,GetProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d,int,e)
+Fe(int,IntersectClipRect,HDC,a,int,b,int,c,int,d,int,e)
+Fe(int,SetVoiceAccent,int,a,int,b,int,c,int,d,int,e)
+Fe(int,ToAscii,WORD,wVirtKey,WORD,wScanCode,LPSTR,lpKeyState,LPVOID,lpChar,WORD,wFlags)
+Fe(void,ScrollWindow,HWND,a,int,b,int,c,LPRECT,d,LPRECT,e)
+Fe(void,SetRect,LPRECT,a,int,b,int,c,int,d,int,e)
+Fe(void,SetRectRgn,HRGN,a,int,b,int,c,int,d,int,e)
+Fe(void,SetScrollRange,HWND,a,int,b,int,c,int,d,BOOL,e)
+Ff(BOOL,PatBlt,HDC,a,int,b,int,c,int,d,int,e,DWORD,f)
+Ff(HBITMAP,CreateDIBitmap,HDC,a,LPBITMAPINFOHEADER,b,DWORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f)
+Ff(HRGN,CreateRoundRectRgn,int,a,int,b,int,c,int,d,int,e,int,f)
+Ff(int,GetPrivateProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d,int,e,LPSTR,f)
+Ff(void,LineDDA,int,a,int,b,int,c,int,d,FARPROC,e,LPSTR,f)
+Ff(void,MoveWindow,HWND,a,int,b,int,c,int,d,int,e,BOOL,f)
+Fg(BOOL,RoundRect,HDC,a,int,b,int,c,int,d,int,e,int,f,int,g)
+Fg(BOOL,ScrollDC,HDC,a,int,b,int,c,LPRECT,d,LPRECT,e,HRGN,f,LPRECT,g)
+Fg(BOOL,TrackPopupMenu,HMENU,a,WORD,b,int,c,int,d,int,e,HWND,f,LPRECT,g)
+Fg(HCURSOR,CreateCursor,HANDLE,a,int,b,int,c,int,d,int,e,LPSTR,f,LPSTR,g)
+Fg(HICON,CreateIcon,HANDLE,a,int,b,int,c,BYTE,d,BYTE,e,LPSTR,f,LPSTR,g)
+Fg(int,GetDIBits,HDC,a,HANDLE,a2,WORD,b,WORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f)
+Fg(int,SetDIBits,HDC,a,HANDLE,a2,WORD,b,WORD,c,LPSTR,d,LPBITMAPINFO,e,WORD,f)
+Fg(void,SetWindowPos,HWND,a,HWND,b,int,c,int,d,int,e,int,f,WORD,g)
+Fh(BOOL,ExtTextOut,HDC,a,int,b,int,c,WORD,d,LPRECT,e,LPSTR,f,WORD,g,LPINT,h)
+Fh(HANDLE,DeferWindowPos,HANDLE,hWinPosInfo,HWND,hWnd,HWND,hWndInsertAfter,int,x,int,y,int,cx,int,cy,WORD,wFlags)
+Fh(LONG,TabbedTextOut,HDC,a,int,b,int,c,LPSTR,d,int,e,int,f,LPINT,g,int,h)
+Fi(BOOL,BitBlt,HDC,a,int,b,int,c,int,d,int,e,HDC,f,int,g,int,h,DWORD,i)
+Fi(BOOL,GrayString,HDC,a,HBRUSH,b,FARPROC,c,DWORD,d,int,e,int,f,int,g,int,h,int,i)
+Fk(BOOL,StretchBlt,HDC,a,int,b,int,c,int,d,int,e,HDC,f,int,g,int,h,int,i,int,j,DWORD,k)
+Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,int,e,int,f,int,g,int,h,HWND,i,HMENU,j,HANDLE,k,LPSTR,l)
+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)
diff --git a/wine.c b/wine.c
index 3e53965..09d7fc7 100644
--- a/wine.c
+++ b/wine.c
@@ -1,4 +1,4 @@
-static char RCSId[] = "$Id: wine.c,v 1.1 1993/06/29 15:55:18 root Exp $";
+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 <stdio.h>
@@ -11,19 +11,25 @@
 #include <linux/head.h>
 #include <linux/ldt.h>
 #include <linux/segment.h>
+#include <string.h>
 #include <errno.h>
 #include "neexe.h"
 #include "segmem.h"
 #include "prototypes.h"
 #include "dlls.h"
+#include "wine.h"
 
 extern int CallToInit16(unsigned long csip, unsigned long sssp, 
 			unsigned short ds);
 extern void CallTo32();
 
+char * GetModuleName(struct w_files * wpnt, int index, char *buffer);
+extern unsigned char ran_out;
 unsigned short WIN_StackSize;
 unsigned short WIN_HeapSize;
 
+struct  w_files * wine_files = NULL;
+
 char **Argv;
 int Argc;
 struct mz_header_s *CurrentMZHeader;
@@ -57,109 +63,214 @@
     exit(1);
 }
 
-/**********************************************************************
- *					main
- */
-main(int argc, char **argv)
-{
-    struct stat finfo;
-    struct mz_header_s *mz_header;
-    struct ne_header_s *ne_header;
-    struct ne_segment_table_entry_s *seg_table;
-    unsigned int status;
-    unsigned int read_size;
-    struct segment_descriptor_s *selector_table;
-    int fd;
-    int segment;
-    int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
-    int rv;
 
-    Argc = argc;
-    Argv = argv;
-    
-    if (argc < 2)
-    {
-	fprintf(stderr, "usage: %s FILENAME\n", argv[0]);
-	exit(1);
-    }
-    
+/* Load one NE format executable into memory */
+LoadImage(char * filename,  char * modulename)
+{
+    unsigned int read_size;
+    int i;
+    struct w_files * wpnt, *wpnt1;
+    unsigned int status;
+
+    /* First allocate a spot to store the info we collect, and add it to
+     * our linked list.
+     */
+
+    wpnt = (struct w_files *) malloc(sizeof(struct w_files));
+    if(wine_files == NULL)
+      wine_files = wpnt;
+    else {
+      wpnt1 = wine_files;
+      while(wpnt1->next) wpnt1 =  wpnt1->next;
+      wpnt1->next  = wpnt;
+    };
+    wpnt->next = NULL;
+
     /*
      * Open file for reading.
      */
-    fd = open(argv[1], O_RDONLY);
-    if (fd < 0)
+    wpnt->fd = open(filename, O_RDONLY);
+    if (wpnt->fd < 0)
     {
 	myerror(NULL);
     }
-
-    /*
-     * Allocate memory to hold entire executable.
-     */
-    if (fstat(fd, &finfo) < 0)
-	myerror(NULL);
-    
     /*
      * Establish header pointers.
      */
-    mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
-    status = lseek(fd, 0, SEEK_SET);
-    if (read(fd, mz_header, sizeof(struct mz_header_s)) !=
+    wpnt->filename = strdup(filename);
+    wpnt->name = NULL;
+    if(modulename)  wpnt->name = strdup(modulename);
+
+    wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
+    status = lseek(wpnt->fd, 0, SEEK_SET);
+    if (read(wpnt->fd, wpnt->mz_header, sizeof(struct mz_header_s)) !=
 	sizeof(struct mz_header_s))
     {
 	myerror("Unable to read MZ header from file");
     }
-    if (mz_header->must_be_0x40 != 0x40)
+    if (wpnt->mz_header->must_be_0x40 != 0x40)
 	myerror("This is not a Windows program");
     
-    ne_header = (struct ne_header_s *) malloc(sizeof(struct ne_header_s));
-    status = lseek(fd, mz_header->ne_offset, SEEK_SET);
-    if (read(fd, ne_header, sizeof(struct ne_header_s)) 
+    wpnt->ne_header = (struct ne_header_s *) malloc(sizeof(struct ne_header_s));
+    status = lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
+    if (read(wpnt->fd, wpnt->ne_header, sizeof(struct ne_header_s)) 
 	!= sizeof(struct ne_header_s))
     {
 	myerror("Unable to read NE header from file");
     }
-    if (ne_header->header_type[0] != 'N' || ne_header->header_type[1] != 'E')
-	myerror("This is not a Windows program");
+    if (wpnt->ne_header->header_type[0] != 'N' || 
+	wpnt->ne_header->header_type[1] != 'E')
+      myerror("This is not a Windows program");
 
-    CurrentMZHeader = mz_header;
-    CurrentNEHeader = ne_header;
-    CurrentNEFile   = fd;
-
-    WIN_StackSize = ne_header->stack_length;
-    WIN_HeapSize = ne_header->local_heap_length;
+    if(wine_files ==  wpnt){
+      CurrentMZHeader = wpnt->mz_header;
+      CurrentNEHeader = wpnt->ne_header;
+      CurrentNEFile   = wpnt->fd;
+      
+      WIN_StackSize = wpnt->ne_header->stack_length;
+      WIN_HeapSize = wpnt->ne_header->local_heap_length;
+    };
 
     /*
      * Create segment selectors.
      */
-    status = lseek(fd, mz_header->ne_offset + ne_header->segment_tab_offset,
+    status = lseek(wpnt->fd, wpnt->mz_header->ne_offset + 
+		   wpnt->ne_header->segment_tab_offset,
 		   SEEK_SET);
-    read_size  = ne_header->n_segment_tab *
+    read_size  = wpnt->ne_header->n_segment_tab *
 	         sizeof(struct ne_segment_table_entry_s);
-    seg_table = (struct ne_segment_table_entry_s *) malloc(read_size);
-    if (read(fd, seg_table, read_size) != read_size)
+    wpnt->seg_table = (struct ne_segment_table_entry_s *) malloc(read_size);
+    if (read(wpnt->fd, wpnt->seg_table, read_size) != read_size)
 	myerror("Unable to read segment table header from file");
-    selector_table = CreateSelectors(fd, seg_table, ne_header);
-    
+    wpnt->selector_table = CreateSelectors(wpnt);
+
+    /* Get the lookup  table.  This is used for looking up the addresses
+       of functions that are exported */
+
+    read_size  = wpnt->ne_header->entry_tab_length;
+    wpnt->lookup_table = (char *) malloc(read_size);
+    lseek(wpnt->fd, wpnt->mz_header->ne_offset + 
+	  wpnt->ne_header->entry_tab_offset, SEEK_SET);
+    if (read(wpnt->fd, wpnt->lookup_table, read_size) != read_size)
+	myerror("Unable to read lookup table header from file");
+
+    /* Get the iname table.  This is used for looking up the names
+       of functions that are exported */
+
+    status = lseek(wpnt->fd, wpnt->ne_header->nrname_tab_offset,  SEEK_SET);
+    read_size  = wpnt->ne_header->nrname_tab_length;
+    wpnt->nrname_table = (char *) malloc(read_size);
+    if (read(wpnt->fd, wpnt->nrname_table, read_size) != read_size)
+	myerror("Unable to read nrname table header from file");
+
+    status = lseek(wpnt->fd, wpnt->mz_header->ne_offset + 
+		   wpnt->ne_header->rname_tab_offset,  SEEK_SET);
+    read_size  = wpnt->ne_header->moduleref_tab_offset - 
+	    wpnt->ne_header->rname_tab_offset;
+    wpnt->rname_table = (char *) malloc(read_size);
+    if (read(wpnt->fd, wpnt->rname_table, read_size) != read_size)
+	myerror("Unable to read rname table header from file");
+
+    /* Now get the module name */
+
+    wpnt->name  = (char*) malloc(*wpnt->rname_table + 1);
+    memcpy(wpnt->name, wpnt->rname_table+1, *wpnt->rname_table);
+    wpnt->name[*wpnt->rname_table] =  0;
+
+    /*
+     * Now load any DLLs that  this module refers to.
+     */
+    for(i=0; i<wpnt->ne_header->n_mod_ref_tab; i++){
+      char buff[14];
+      char buff2[14];
+      int  fd, j;
+      GetModuleName(wpnt, i + 1, buff);
+      
+      if(FindDLLTable(buff)) continue;  /* This module already loaded */
+
+      /* The next trick is to convert the case, and add the .dll
+       * extension if required to find the actual library.  We may want
+       * to use a search path at some point as well. */
+
+      /*  First try  the straight name */
+       strcpy(buff2, buff);
+      if(fd = open(buff2, O_RDONLY)  >= 0) {
+	close(fd);
+	LoadImage(buff2, buff);
+	continue;
+      };
+
+      /* OK, that did not work,  try making it lower-case, and add the .dll
+	 extension */
+
+      for(j=0;  j<strlen(buff2);  j++)  
+	if(buff2[j] >= 'A' && buff2[j] <= 'Z')  buff2[j] |= 0x20;
+      strcat(buff2, ".dll");
+      
+      if(fd = open(buff2, O_RDONLY)  >= 0) {
+	close(fd);
+	LoadImage(buff2, buff);
+	continue;
+      };
+
+      fprintf(stderr,"Unable to load:%s\n",  buff);
+    };
+}
+
+
+/**********************************************************************
+ *					main
+ */
+_WinMain(int argc, char **argv)
+{
+	int segment;
+	struct w_files * wpnt;
+	int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
+	int i;
+	int rv;
+	
+	Argc = argc;
+	Argv = argv;
+	
+	if (argc < 2)
+	{
+		fprintf(stderr, "usage: %s FILENAME\n", argv[0]);
+		exit(1);
+	}
+	
+	LoadImage(argv[1], NULL);
+	
+	if(ran_out) exit(1);
+#ifdef DEBUG
+	GetEntryDLLName("USER", "INITAPP", 0, 0);
+	for(i=0; i<1024; i++) {
+		int j;
+		j = GetEntryPointFromOrdinal(wine_files, i);
+		if(j == 0)  break;
+		fprintf(stderr," %d %x\n", i,  j);
+	};
+#endif
     /*
      * Fixup references.
      */
-    for (segment = 0; segment < ne_header->n_segment_tab; segment++)
-    {
-	if (FixupSegment(fd, mz_header, ne_header, seg_table,
-			 selector_table, segment) < 0)
+    wpnt = wine_files;
+    for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
+      for (segment = 0; segment < wpnt->ne_header->n_segment_tab; segment++)
 	{
-	    myerror("fixup failed.");
+	  if (FixupSegment(wpnt, segment) < 0)
+	    {
+	      myerror("fixup failed.");
+	    }
 	}
-    }
 
     /*
      * Fixup stack and jump to start.
      */
-    ds_reg = selector_table[ne_header->auto_data_seg-1].selector;
-    cs_reg = selector_table[ne_header->cs-1].selector;
-    ip_reg = ne_header->ip;
-    ss_reg = selector_table[ne_header->ss-1].selector;
-    sp_reg = ne_header->sp;
+    ds_reg = wine_files->selector_table[wine_files->ne_header->auto_data_seg-1].selector;
+    cs_reg = wine_files->selector_table[wine_files->ne_header->cs-1].selector;
+    ip_reg = wine_files->ne_header->ip;
+    ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector;
+    sp_reg = wine_files->ne_header->sp;
 
     rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
     printf ("rv = %x\n", rv);
@@ -191,9 +302,11 @@
  *					GetModuleName
  */
 char *
-GetModuleName(int fd, struct mz_header_s *mz_header, 
-	      struct ne_header_s *ne_header, int index, char *buffer)
+GetModuleName(struct w_files * wpnt, int index, char *buffer)
 {
+    int fd = wpnt->fd;
+    struct mz_header_s *mz_header = wpnt->mz_header; 
+    struct ne_header_s *ne_header = wpnt->ne_header;
     char *p;
     int length;
     int name_offset, status;
@@ -209,6 +322,11 @@
     read(fd, &length, 1);  /* Get the length byte */
     read(fd, buffer, length);
     buffer[length] = 0;
+
+    /* Module names  are always upper case */
+    for(i=0; i<length; i++)
+	    if(buffer[i] >= 'a' && buffer[i] <= 'z')  buffer[i] &= ~0x20;
+
     return buffer;
 }
 
@@ -217,21 +335,23 @@
  *					FixupSegment
  */
 int
-FixupSegment(int fd, struct mz_header_s * mz_header,
-	     struct ne_header_s *ne_header,
-	     struct ne_segment_table_entry_s *seg_table, 
-	     struct segment_descriptor_s *selector_table,
-	     int segment_num)
+FixupSegment(struct w_files * wpnt, int segment_num)
 {
+  int fd =  wpnt->fd;
+  struct mz_header_s * mz_header = wpnt->mz_header;
+  struct ne_header_s *ne_header =  wpnt->ne_header;
+  struct ne_segment_table_entry_s *seg_table = wpnt->seg_table;
+  struct segment_descriptor_s *selector_table = wpnt->selector_table;
+
     struct relocation_entry_s *rep, *rep1;
     struct ne_segment_table_entry_s *seg;
     struct segment_descriptor_s *sel;
     struct dll_table_entry_s *dll_table;
+    int status;
     unsigned short *sp;
     unsigned int selector, address;
     unsigned int next_addr;
     int ordinal;
-    int status;
     char dll_name[257];
     char func_name[257];
     int i, n_entries;
@@ -239,7 +359,8 @@
     seg = &seg_table[segment_num];
     sel = &selector_table[segment_num];
 
-    if (seg->seg_data_offset == 0)
+    if ((seg->seg_data_offset == 0) ||
+	!(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA))
 	return 0;
 
     /*
@@ -272,25 +393,26 @@
 	switch (rep->relocation_type)
 	{
 	  case NE_RELTYPE_ORDINAL:
-	    if (GetModuleName(fd, mz_header, ne_header, rep->target1,
+	    if (GetModuleName(wpnt, rep->target1,
 			      dll_name) == NULL)
 	    {
+	      fprintf(stderr, "NE_RELTYPE_ORDINAL failed");
 		return -1;
 	    }
 	    
- 	    dll_table = FindDLLTable(dll_name);
-	    if (dll_table == NULL)
+	    ordinal = rep->target2;
+
+  	    status = GetEntryDLLOrdinal(dll_name, ordinal, &selector,
+					&address);
+	    if (status)
 	    {
 		char s[80];
 		
-		sprintf(s, "Bad DLL name '%s'", dll_name);
+		sprintf(s, "Bad DLL name '%s.%d'", dll_name, ordinal);
 		myerror(s);
 		return -1;
 	    }
 
-	    ordinal = rep->target2;
-	    selector = dll_table[ordinal].selector;
-	    address  = (unsigned int) dll_table[ordinal].address;
 #ifdef DEBUG_FIXUP
 	    printf("%d: %s.%d: %04.4x:%04.4x\n", i + 1, dll_name, ordinal,
 		   selector, address);
@@ -298,29 +420,31 @@
 	    break;
 	    
 	  case NE_RELTYPE_NAME:
-	    if (GetModuleName(fd, mz_header, ne_header, rep->target1, dll_name)
+	    if (GetModuleName(wpnt, rep->target1, dll_name)
 		== NULL)
 	    {
-		return -1;
-	    }
- 	    dll_table = FindDLLTable(dll_name);
-	    if (dll_table == NULL)
-	    {
-		char s[80];
-		
-		sprintf(s, "Bad DLL name '%s'", dll_name);
-		myerror(s);
+	      fprintf(stderr,"NE_RELTYPE_NAME failed");
 		return -1;
 	    }
 
 	    if (GetImportedName(fd, mz_header, ne_header, 
 				rep->target2, func_name) == NULL)
 	    {
+	      fprintf(stderr,"getimportedname failed");
 		return -1;
 	    }
-	    ordinal = FindOrdinalFromName(dll_table, func_name);
-	    selector = dll_table[ordinal].selector;
-	    address  = (unsigned int) dll_table[ordinal].address;
+
+  	    status = GetEntryDLLName(dll_name, func_name, &selector, 
+					   &address);
+	    if (status)
+	    {
+		char s[80];
+		
+		sprintf(s, "Bad DLL name '%s (%s)'", dll_name,func_name);
+		myerror(s);
+		return -1;
+	    }
+
 #ifdef DEBUG_FIXUP
 	    printf("%d: %s %s.%d: %04.4x:%04.4x\n", i + 1, func_name,
 		   dll_name, ordinal, selector, address);
@@ -330,8 +454,7 @@
 	  case NE_RELTYPE_INTERNAL:
 	    if (rep->target1 == 0x00ff)
 	    {
-		address  = GetEntryPointFromOrdinal(fd, mz_header, ne_header,
-						    rep->target2);
+		address  = GetEntryPointFromOrdinal(wpnt, rep->target2);
 		selector = (address >> 16) & 0xffff;
 		address &= 0xffff;
 	    }
@@ -364,7 +487,7 @@
 	    continue;
 	    
 	  default:
-#ifdef DEBUG_FIXUP
+#ifndef DEBUG_FIXUP
 	    printf("%d: ADDR TYPE %d,  TYPE %d,  OFFSET %04.4x,  ",
 		   i + 1, rep->address_type, rep->relocation_type, 
 		   rep->offset);
diff --git a/wine.h b/wine.h
new file mode 100644
index 0000000..621fcdb
--- /dev/null
+++ b/wine.h
@@ -0,0 +1,22 @@
+#ifndef  WINE_H
+#define  WINE_H
+
+#include "dlls.h"
+
+struct w_files{
+  struct w_files  * next;
+  char * name;   /* Name, as it appears in the windows binaries */
+  char * filename;  /* Actual name of the unix file that satisfies this */
+  int fd;
+  struct mz_header_s *mz_header;
+  struct ne_header_s *ne_header;
+  struct ne_segment_table_entry_s *seg_table;
+  struct segment_descriptor_s *selector_table;
+  char * lookup_table;
+  char * nrname_table;
+  char * rname_table;
+};
+
+extern struct  w_files * wine_files;
+
+#endif
diff --git a/wintcl.c b/wintcl.c
new file mode 100644
index 0000000..a9bdbb9
--- /dev/null
+++ b/wintcl.c
@@ -0,0 +1,858 @@
+#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 <stdio.h>
+#include <stdarg.h>
+#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 <windows.h>
+#include <assert.h>
+
+
+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; i<argc; i++)
+	{	if (*buf) strcat(buf," ");
+		strcat(buf,argv[i]);
+	}
+	WinMain(getpid(),NULL,buf,SW_SHOWNORMAL); /* or SW_SHOWMINNOACTIVE*/
+	exit(0);
+}
+#endif
+
+static int _WinCallBack( ClientData  clientData, Tcl_Interp *interp,
+	int         argc, char      **argv)
+{
+	int i;
+	if (argc>2)
+	{	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; i<argc; i++)
+		printf("%s\n", argv[i]);
+	printf("\n"); */
+	return(TCL_OK);
+}
+
+static int _getStrHandle( ClientData  clientData, Tcl_Interp *interp,
+	int         argc, char      **argv)
+{
+	int i;
+	if (argc != 2)
+	{	sprintf(interp->result, "%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<n; i++)
+	{	ptr = va_arg(va,char *);
+		ptr2 = va_arg(va,char *);
+		if (!strncmp("LPSTR",ptr,5))
+			sprintf(cmd+strlen(cmd)," \"%s\"", (ptr2?ptr2:""));
+		else if (!strncmp("char",ptr,4))
+			sprintf(cmd+strlen(cmd)," %c\0", ptr2);
+		else if (!strncmp("HANDLE",ptr,6))
+			sprintf(cmd+strlen(cmd)," %s", getStrHandle((int)ptr2));
+		else
+			sprintf(cmd+strlen(cmd)," %d", ptr2);
+	}
+	strcat(cmd,"\n");
+	va_end(va);
+	tclexec(cmd);
+}
+
+int wsprintf(LPSTR a,LPSTR b,...) {}
+
+BOOL  IsCharAlpha(char ch) { return(isalpha(ch)); }
+BOOL  IsCharAlphaNumeric(char ch) { return(isalnum(ch)); }
+BOOL  IsCharUpper(char ch) { return(isupper(ch)); }
+BOOL  IsCharLower(char ch) { return(islower(ch)); }
+int	 lstrcmp( LPSTR a, LPSTR b ) { return(strcmp(a,b)); }
+int	 lstrcmpi( LPSTR a, LPSTR b ) { return(strcasecmp(a,b)); }
+LPSTR	lstrcpy( LPSTR a, LPSTR b ) { return(strcpy(a,b)); }
+LPSTR	lstrcat( LPSTR a, LPSTR b ) { return(strcat(a,b)); }
+int	 lstrlen( LPSTR a) { return(strlen(a)); }
+int	 _lopen( LPSTR a, int b) { return(open(a,b)); }
+int	 _lclose( int a) { return(close(a)); }
+int	 _lcreat( LPSTR a, int b) { return(creat(a,b)); }
+LONG	_llseek( int a, long b, int c) { return(lseek(a,b,c)); }
+WORD	_lread( int a, LPSTR b, int c) { return(read(a,b,c)); }
+WORD	_lwrite( int a, LPSTR b, int c) { return(write(a,b,c)); }
+BOOL  ExitWindows(DWORD dwReserved, WORD wReturnCode) {exit(0); }
+