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, ð, 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); }
+