Release 0.3.0

Fri Sep  3 11:52:18 1993  Bob Amstadt

	* [windows/timer.c]
	Changed to use CallWindowProc() rather directly calling callback.

	* [windows/event.c]
	Implemented SetCapture() and ReleaseCapture()

	* [windows/keyboard.c]
	Created stub for GetKeyState()

	* [objects/linedda.c]
	Created stub for LineDDA()

	* [if1632/callback.c]
	Created callback handler for LineDDA callback procedure.

	* [if1632/callback.c]
	Created FreeProcInstance()

Fri Sep  3 08:36:52 1993  David Metcalfe

	* [loader/signal.c]
	Patch to and code for INT 1A

Thu Sep  2 00:31:54 1993  Alexandre Julliard

	* [objects/font.c] [objects/text.c]
	More text support: implemented justification and underlining.

	* [windows/clipping.c] [objects/clipping.c]
	Moved low-level clipping functions to objects/clipping.c.

	* [windows/clipping.c] [windows/event.c] [windows/message.c]
	Implemented window update regions.

	* [windows/dc.c] [objects/dcvalues.c]
	Moved some device-independent DC functions to objects/dcvalues.c.

	* [windows/graphics.c]
	Implemented InvertRect() and GetPixel().

Sat Aug 28 08:40:23 1993  Eric Youngdale

	* [include/neexe.h] [loader/wine.c]
	Added code to handle relocation type 4.

	* [loader/signal.h] [loader/wine.c] [loader/selector.c]
	Added support for dos interrupts.

Thu 26 Aug 19:15:00 1993  Eric Youngdale

	* [loader/selector.c]
	Fixed bug dealing with loading DLLs.

Thu Aug 26 19:22:40 1993  Alexandre Julliard

        * [include/gdi.h] [objects/font.c] [windows/dc.c]
        Beginning of real font support.

        * [windows/graphics.c]
        Implemented PatBlt().

        * [memory/global.c]
        Corrected a bug with linked list handling in GlobalAlloc().

        * [objects/bitmap.c]
        Corrected a bug in BITMAP_SelectObject().

Tue Aug 24 19:22:40 1993  David Metcalfe

        * [controls/Command*] [controls/Label*] [controls[MenuButto*]
	  [controls/SmeMenuButt*]
	Change code to support & as a special character in menu item text.

Tue Aug 24 19:22:40 1993  Alexandre Julliard

	* [include/gdi.h] [windows/dc.c]
	Heavily modified the DC structure for better device-independence.

	* [objects/bitmap.c]
	Implemented bitmap dimensions.

	* [windows/dc.c] [windows/dce.c]
	Implemented DC state saving and restoring.

	* [windows/dc.c]
	Implemented ROP mode.

	* [windows/graphics.c]
	Implemented FillRect().

Mon Aug 23 22:08:34 1993  Bob Amstadt  (bob at pooh)

	* [misc/xt.c]
	Fixed bug in InvalidateRect().  Solitaire attempted to
	clear window before it was realized.

	* [loader/resource.c]
	Began rewrite of LoadBitmap().

	* [loader/wine.c]
	Fixed code which set Argv and Argc global variables.

	* [loader/selector.c]
	Added code to set up command line arguments.

	* [include/neexe.h]
	Fixed error in PSP structure.

Tue Aug 17 20:41:12 1993  Alexandre Julliard

	* [include/gdi.h] [windows/dc.c]
	Implemented device capabilities.

	* [objects/region.c]
	Implemented EqualRgn() and CombineRgn().

	* [windows/clipping.c]
	Implemented Save/RestoreVisRgn().

	* [windows/graphics.c]
	Implemented PaintRgn() and FillRgn().

	* [windows/mapping.c]
	Implemented mapping modes.

Tue Aug 10 14:07:38 1993  Alexandre Julliard

	* [if1632/user.spec] [misc/rect.c]
	Implemented rectangle API functions.

	* [if1632/gdi.spec] [include/gdi.h] [objects/region.c]
	Implemented regions.

	* [windows/class.c]
	Corrected a typo in UnregisterClass().

	* [windows/clipping.c] [windows/dc.c]
	Implemented DC clipping and visible region.

Tue Aug 10 20:57:56 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c]
	SetMenu(), GetMenu(), CheckMenuItem() implemented

Thu Aug  5 22:33:22 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c]
	Many improvements menus.  LoadMenu() should work.

Wed Aug  4 14:55:36 1993  Alexandre Julliard

        * [objects/dib.c]
        Started the implementation of device-independent bitmaps.

        * [objects/bitmap.c]
        Added support for multiple bitmap depths.

        * [objects/brush.c]
        Implemented pattern brushes.

        * [windows/dc.c] [windows/graphics.c]
        Implemented some GDI graphics primitives.

Tue Aug  3 21:16:47 1993  Bob Amstadt  (bob at pooh)

	* [controls/menu.c] [windows/win.c] [include/menu.h]
	Code to load class menus from executable file.

	* [if1632/user.spec]
	Fixed specification of SendMessage() and PostMessage.

Mon Jul 26 21:53:24 1993  Alexandre Julliard

	* [if1632/call.S]
	Corrected a bug in KERNEL_InitTask().

	* [include/windows.h]
	Added a lot of constants.

	* [loader/selector.c]
	Corrected a bug in segment allocation in CreateSelectors().

	* [objects/bitmap.c]
	Implemented SelectObject() for bitmaps.

	* [objects/brush.c]
	Implemented hatched brushes and SelectObject().

	* [objects/gdiobj.c]
	Removed linked list (not needed).

	* [objects/palette.c]
	Implemented system palette creation and misc. palette API functions.

	* [windows/timer.c]
	Implemented timers.

	* [windows/dc.c]
	Implemented memory device contexts.

Tue Jul 20 10:38:59 1993  Bob Amstadt  (bob at pooh)

        * [dos.c]
	Split DOS3Call() out of kernel.c.  Added support for get date
	and time functions.

	* [call.S]
	Added function ReturnFromRegisterFunc() to allow DOS calls
	to return values in registers.

	* [regfunc.h]
	Macros to access registers saved on stack.

Tue Jul 20 10:38:59 1993  Alexandre Julliard

        * [win.c]
        Corrected allocation of the WM_CREATE data structure.

        * [dce.c] [dce.h]
        Implemented DCE handling.

        * [bitmap.c] [brush.c] [dc.c] [font.c] [gdi.h] [gdi.spec] 
          [gdiobj.c] [palette.c] [pen.c]
        Implemented the GDI objects data structures and allocation.

        * [windows.h]
        Added several structures and constants for GDI objects.

Mon Jul 19 12:51:10 1993  Bob Amstadt  (bob at pooh)

	* [ldtlib.c]
	Modified system calls to match Linus' new interface for
	the LDT modification.

	* [win.c]
	Fixed bug with WM_CREATE message.

	* [heap.c] [kernel.spec]
	Completed local heap allocation functions.

	* [global.c]
	Created function GlobalQuickAlloc() for easy allocation from DLLs
diff --git a/ALPHA-diffs b/ALPHA-diffs
new file mode 100644
index 0000000..1bc9396
--- /dev/null
+++ b/ALPHA-diffs
@@ -0,0 +1,1419 @@
+diff -u --recursive --new-files pl12/linux/config.in linux/config.in
+--- pl12/linux/config.in	Sun Aug 15 11:24:56 1993
++++ linux/config.in	Sat Aug 21 10:51:27 1993
+@@ -13,6 +13,10 @@
+ bool 'System V IPC' CONFIG_SYSVIPC y
+ bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
+ *
++* Program binary formats
++*
++bool 'Elf executables' CONFIG_BINFMT_ELF y
++*
+ * SCSI support
+ *
+ bool 'SCSI support?' CONFIG_SCSI n
+diff -u --recursive --new-files pl12/linux/fs/Makefile linux/fs/Makefile
+--- pl12/linux/fs/Makefile	Sun Mar  7 16:21:10 1993
++++ linux/fs/Makefile	Fri Aug 20 08:59:30 1993
+@@ -34,6 +34,9 @@
+ FS_SUBDIRS := $(FS_SUBDIRS) xiafs
+ endif
+ 
++ifdef CONFIG_BINFMT_ELF
++BINFMTS := $(BINFMTS) binfmt_elf.o
++endif
+ 
+ .c.s:
+ 	$(CC) $(CFLAGS) -S $<
+@@ -44,7 +47,7 @@
+ 
+ OBJS=	open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \
+ 	block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
+-	select.o fifo.o locks.o filesystems.o
++	select.o fifo.o locks.o filesystems.o $(BINFMTS)
+ 
+ all: fs.o filesystems.a
+ 
+diff -u --recursive --new-files pl12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
+--- pl12/linux/fs/binfmt_elf.c
++++ linux/fs/binfmt_elf.c	Fri Aug 20 08:59:30 1993
+@@ -0,0 +1,358 @@
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/mman.h>
++#include <linux/a.out.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/binfmts.h>
++#include <asm/segment.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++
++extern "C" int sys_exit(int exit_code);
++extern "C" int sys_close(unsigned fd);
++extern "C" int sys_open(const char *, int, int);
++
++/*
++ * These are the functions used to load ELF style executables and shared
++ * libraries.  There is no binary dependent code anywhere else.
++ */
++
++#include <linux/elf.h>
++
++int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
++{
++	struct elfhdr elf_ex;
++	struct file * file;
++  	struct exec ex;
++	struct inode *interpreter_inode;
++	int i;
++	int old_fs;
++	int error;
++	struct elf_phdr * elf_ppnt, *elf_phdata;
++	int elf_exec_fileno;
++	unsigned int elf_bss, k, elf_brk;
++	int retval;
++	char * elf_interpreter;
++	unsigned int elf_entry;
++	int status;
++	unsigned int start_code, end_code, end_data;
++	unsigned int elf_stack;
++	char passed_fileno[6];
++	
++	status = 0;
++	elf_ex = *((struct elfhdr *) bprm->buf);	  /* exec-header */
++	
++	if (elf_ex.e_ident[0] != 0x7f ||
++	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
++		return  -ENOEXEC;
++	
++	
++	/* First of all, some simple consistency checks */
++	if(elf_ex.e_type != ET_EXEC || 
++	   (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
++	   (!bprm->inode->i_op || !bprm->inode->i_op->bmap || 
++	    !bprm->inode->i_op->default_file_ops->mmap)){
++		return -ENOEXEC;
++	};
++	
++	/* Now read in all of the header information */
++	
++	elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * 
++						 elf_ex.e_phnum, GFP_KERNEL);
++	
++	old_fs = get_fs();
++	set_fs(get_ds());
++	retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
++			   elf_ex.e_phentsize * elf_ex.e_phnum);
++	set_fs(old_fs);
++	if (retval < 0)
++		return retval;
++	
++	elf_ppnt = elf_phdata;
++	
++	elf_bss = 0;
++	elf_brk = 0;
++	
++	elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
++
++	if (elf_exec_fileno < 0) return elf_exec_fileno;
++
++	file = current->filp[elf_exec_fileno];
++	
++	elf_stack = 0xffffffff;
++	elf_interpreter = NULL;
++	start_code = 0;
++	end_code = 0;
++	end_data = 0;
++	
++	old_fs = get_fs();
++	set_fs(get_ds());
++	
++	for(i=0;i < elf_ex.e_phnum; i++){
++		if(elf_ppnt->p_type == PT_INTERP) {
++			/* This is the program interpreter used for shared libraries - 
++			   for now assume that this is an a.out format binary */
++			
++			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, 
++							   GFP_KERNEL);
++			
++			retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
++					   elf_ppnt->p_filesz);
++			printk("Using ELF interpreter %s\n", elf_interpreter);
++			if(retval >= 0)
++				retval = namei(elf_interpreter, &interpreter_inode);
++			if(retval >= 0)
++				retval = read_exec(interpreter_inode,0,bprm->buf,128);
++			
++			if(retval >= 0){
++				ex = *((struct exec *) bprm->buf);		/* exec-header */
++				
++#if 0
++				printk("Interpreter: %x %x %x\n",N_MAGIC(ex), ex.a_text,ex.a_data);
++#endif
++			};
++		};
++		elf_ppnt++;
++	};
++	
++	set_fs(old_fs);
++	
++	/* Some simple consistency checks for the interpreter */
++	if(elf_interpreter){
++		if(retval < 0) {
++			kfree(elf_interpreter);
++			kfree(elf_phdata);
++			return -ELIBACC;
++		};
++		if((N_MAGIC(ex) != OMAGIC) && (N_MAGIC(ex) != ZMAGIC)) {
++			kfree(elf_interpreter);
++			kfree(elf_phdata);
++			return -ELIBBAD;
++		};
++	}
++	
++	/* OK, we are done with that, now set up the arg stuff,
++	   and then start this sucker up */
++	
++	if (!bprm->sh_bang) {
++		char * passed_p;
++		
++		sprintf(passed_fileno, "%d", elf_exec_fileno);
++		passed_p = passed_fileno;
++		
++		if(elf_interpreter) {
++			bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
++			bprm->argc++;
++		};
++		if (!bprm->p) {
++			return -E2BIG;
++		}
++	}
++	
++	/* OK, This is the point of no return */
++	flush_old_exec(bprm);
++
++	current->end_data = 0;
++	current->end_code = 0;
++	current->start_mmap = ELF_START_MMAP;
++	current->mmap = NULL;
++	elf_entry = (unsigned int) elf_ex.e_entry;
++	
++	/* Do this so that we can load the interpreter, if need be.  We will
++	   change some of these later */
++	current->rss = 0;
++	bprm->p += change_ldt(0, bprm->page);
++	current->start_stack = bprm->p;
++	
++	/* Now we do a little grungy work by mmaping the ELF image into
++	   the correct location in memory.  At this point, we assume that
++	   the image should be loaded at fixed address, not at a variable
++	   address. */
++	
++	old_fs = get_fs();
++	set_fs(get_ds());
++	
++	elf_ppnt = elf_phdata;
++	for(i=0;i < elf_ex.e_phnum; i++){
++		
++		if(elf_ppnt->p_type == PT_INTERP) {
++			/* Set these up so that we are able to load the interpreter */
++			current->brk = ex.a_bss +
++				(current->end_data = ex.a_data +
++				 (current->end_code = ex.a_text));
++			elf_entry = ex.a_entry;
++			
++			/* Now load the interpreter into user address space */
++			set_fs(old_fs);
++			
++			if (N_MAGIC(ex) == OMAGIC) {
++				retval = read_exec(interpreter_inode, 32, (char *) 0, 
++						   ex.a_text+ex.a_data);
++				iput(interpreter_inode);
++			} else if (N_MAGIC(ex) == ZMAGIC) {
++				retval = read_exec(interpreter_inode, 1024, (char *) 0, 
++						   ex.a_text+ex.a_data);
++				iput(interpreter_inode);
++			} else
++				retval = -1;
++			
++			old_fs = get_fs();
++			set_fs(get_ds());
++			
++			if(retval >= 0)
++				zeromap_page_range((ex.a_text + ex.a_data + 0xfff) & 
++						   0xfffff000, ex.a_bss, PAGE_COPY);
++			kfree(elf_interpreter);
++			
++			if(retval < 0) { 
++				kfree(elf_phdata);
++				send_sig(SIGSEGV, current, 0);
++				return 0;
++			};
++		};
++		
++		
++		if(elf_ppnt->p_type == PT_LOAD) {
++			error = do_mmap(file,
++					elf_ppnt->p_vaddr & 0xfffff000,
++					elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
++					PROT_READ | PROT_WRITE | PROT_EXEC,
++					MAP_FIXED | MAP_PRIVATE,
++					elf_ppnt->p_offset & 0xfffff000);
++			
++#ifdef LOW_ELF_STACK
++			if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack) 
++				elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
++#endif
++			
++			k = elf_ppnt->p_vaddr;
++			if(k > start_code) start_code = k;
++			k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
++			if(k > elf_bss) elf_bss = k;
++			if((elf_ppnt->p_flags | PROT_WRITE) && end_code <  k)
++				end_code = k; 
++			if(end_data < k) end_data = k; 
++			k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
++			if(k > elf_brk) elf_brk = k;		     
++			
++			if(status == 0xffffffff) {
++				set_fs(old_fs);
++				kfree(elf_phdata);
++				send_sig(SIGSEGV, current, 0);
++				return 0;
++			};
++		};
++		elf_ppnt++;
++	};
++	set_fs(old_fs);
++	
++	kfree(elf_phdata);
++	
++	if(!elf_interpreter) sys_close(elf_exec_fileno);
++	current->elf_executable = 1;
++	current->executable = bprm->inode;
++	bprm->inode->i_count++;
++#ifdef LOW_ELF_STACK
++	current->start_stack = p = elf_stack - 4;
++#endif
++	bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
++	bprm->p = (unsigned long) create_tables((char *)bprm->p,bprm->argc,bprm->envc);
++	if(elf_interpreter) current->arg_start += strlen(passed_fileno) + 1;
++	current->start_brk = current->brk = elf_brk;
++	current->end_code = end_code;
++	current->start_code = start_code;
++	current->start_stack = bprm->p;
++	current->suid = current->euid = bprm->e_uid;
++	current->sgid = current->egid = bprm->e_gid;
++	zeromap_page_range((elf_bss + 0xfff) & 0xfffff000, elf_brk - elf_bss,
++			   PAGE_COPY);
++	regs->eip = elf_entry;		/* eip, magic happens :-) */
++	regs->esp = bprm->p;			/* stack pointer */
++	if (current->flags & PF_PTRACED)
++		send_sig(SIGTRAP, current, 0);
++	
++	return 0;
++}
++
++
++int load_elf_library(int fd){
++        struct file * file;
++	struct elfhdr elf_ex;
++	struct elf_phdr *elf_phdata  =  NULL;
++	struct  inode * inode;
++	unsigned int len;
++	int old_fs, retval;
++	unsigned int bss;
++	int error;
++	int i,j;
++	
++	len = 0;
++	file = current->filp[fd];
++	inode = file->f_inode;
++	
++	set_fs(KERNEL_DS);
++	if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
++		sys_close(fd);
++		return -EACCES;
++	}
++	set_fs(USER_DS);
++	
++	if (elf_ex.e_ident[0] != 0x7f ||
++	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
++		return -ENOEXEC;
++	
++	/* First of all, some simple consistency checks */
++	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
++	   (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
++	   (!inode->i_op || !inode->i_op->bmap || 
++	    !inode->i_op->default_file_ops->mmap)){
++		return -ENOEXEC;
++	};
++	
++	/* Now read in all of the header information */
++	
++	if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) 
++		return -ENOEXEC;
++	
++	elf_phdata =  (struct elf_phdr *) 
++		kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
++	
++	old_fs = get_fs();
++	set_fs(get_ds());
++	retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
++			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
++	set_fs(old_fs);
++	
++	j = 0;
++	for(i=0; i<elf_ex.e_phnum; i++)
++		if((elf_phdata + i)->p_type == PT_LOAD) j++;
++	
++	if(j != 1)  {
++		kfree(elf_phdata);
++		return -ENOEXEC;
++	};
++	
++	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
++	
++	/* Now use mmap to map the library into memory. */
++	error = do_mmap(file,
++			elf_phdata->p_vaddr & 0xfffff000,
++			elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
++			PROT_READ | PROT_WRITE | PROT_EXEC,
++			MAP_FIXED | MAP_PRIVATE,
++			elf_phdata->p_offset & 0xfffff000);
++	
++	sys_close(fd);
++	if (error != elf_phdata->p_vaddr & 0xfffff000)
++		return error;
++	len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
++	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
++	if (bss > len)
++		zeromap_page_range(len, bss-len, PAGE_COPY);
++	kfree(elf_phdata);
++	return 0;
++}
++
+diff -u --recursive --new-files pl12/linux/fs/exec.c linux/fs/exec.c
+--- pl12/linux/fs/exec.c	Sun Aug 15 11:33:07 1993
++++ linux/fs/exec.c	Fri Aug 20 08:59:31 1993
+@@ -50,7 +50,7 @@
+ 
+ extern void shm_exit (void);
+ 
+-static int open_inode(struct inode * inode, int mode)
++int open_inode(struct inode * inode, int mode)
+ {
+ 	int error, fd;
+ 	struct file *f, **fpp;
+@@ -316,7 +316,7 @@
+  * it is expensive to load a segment register, we try to avoid calling
+  * set_fs() unless we absolutely have to.
+  */
+-static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
++unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
+ 		unsigned long p, int from_kmem)
+ {
+ 	char *tmp, *pag = NULL;
+@@ -649,6 +649,7 @@
+ 		}
+ 	}
+ 
++	bprm.sh_bang = sh_bang;
+ 	fmt = formats;
+ 	do {
+ 		int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
+@@ -694,9 +695,16 @@
+ 			    struct pt_regs * regs);
+ extern int load_aout_library(int fd);
+ 
++extern int load_elf_binary(struct linux_binprm *,
++			    struct pt_regs * regs);
++extern int load_elf_library(int fd);
++
+ /* Here are the actual binaries that will be accepted  */
+ struct linux_binfmt formats[] = {
+ 	{load_aout_binary, load_aout_library},
++#ifdef CONFIG_BINFMT_ELF
++	{load_elf_binary, load_elf_library},
++#endif
+ 	{NULL, NULL}
+ };
+ 
+@@ -713,17 +721,20 @@
+ 	unsigned long p = bprm->p;
+ 
+ 	ex = *((struct exec *) bprm->buf);		/* exec-header */
+-	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
++	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
++	     N_MAGIC(ex) != QMAGIC) ||
+ 	    ex.a_trsize || ex.a_drsize ||
+ 	    bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
+ 		return -ENOEXEC;
+ 	}
+-	if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
++
++	if (N_MAGIC(ex) == ZMAGIC &&
+ 	    (N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) {
+ 		printk("N_TXTOFF < BLOCK_SIZE. Please convert binary.");
+ 		return -ENOEXEC;
+ 	}
+-	if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) {
++
++	if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) {
+ 		printk("N_TXTOFF != BLOCK_SIZE. See a.out.h.");
+ 		return -ENOEXEC;
+ 	}
+@@ -732,7 +743,10 @@
+ 	flush_old_exec(bprm);
+ 	current->start_brk = current->brk = ex.a_bss +
+ 		(current->end_data = ex.a_data +
+-		 (current->end_code = ex.a_text));
++		 (current->end_code = N_TXTADDR(ex) + ex.a_text));
++
++	current->start_code += N_TXTADDR(ex);
++
+ 	current->rss = 0;
+ 	current->suid = current->euid = bprm->e_uid;
+ 	current->mmap = NULL;
+@@ -751,23 +765,25 @@
+ 		file = current->filp[fd];
+ 		if (!file->f_op || !file->f_op->mmap) {
+ 			sys_close(fd);
+-			read_exec(bprm->inode, 1024, (char *) 0, ex.a_text+ex.a_data);
++			read_exec(bprm->inode, N_TXTOFF(ex), 
++				  (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
+ 			goto beyond_if;
+ 		}
+-		error = do_mmap(file, 0, ex.a_text,
++		error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
+ 				PROT_READ | PROT_EXEC,
+ 				MAP_FIXED | MAP_SHARED, N_TXTOFF(ex));
+-		if (error != 0) {
++
++		if (error != N_TXTADDR(ex)) {
+ 			sys_close(fd);
+ 			send_sig(SIGSEGV, current, 0);
+ 			return 0;
+ 		};
+ 		
+-		error = do_mmap(file, ex.a_text, ex.a_data,
++ 		error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
+ 				PROT_READ | PROT_WRITE | PROT_EXEC,
+ 				MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text);
+ 		sys_close(fd);
+-		if (error != ex.a_text) {
++		if (error != N_TXTADDR(ex) + ex.a_text) {
+ 			send_sig(SIGSEGV, current, 0);
+ 			return 0;
+ 		};
+@@ -818,6 +834,8 @@
+ 		return -ENOEXEC;
+ 	}
+ 	
++	if (N_FLAGS(ex)) return -ENOEXEC;
++
+ 	/* Now use mmap to map the library into memory. */
+ 	error = do_mmap(file, ex.a_entry, ex.a_text + ex.a_data,
+ 			PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
+diff -u --recursive --new-files pl12/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
+--- pl12/linux/fs/ext2/namei.c	Thu Aug 12 20:54:00 1993
++++ linux/fs/ext2/namei.c	Thu Aug 19 10:04:52 1993
+@@ -937,6 +937,8 @@
+ 		new_inode->i_nlink--;
+ 		new_inode->i_dirt = 1;
+ 	}
++	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
++	old_dir->i_dirt = 1;
+ 	old_bh->b_dirt = 1;
+ 	new_bh->b_dirt = 1;
+ 	if (dir_bh) {
+diff -u --recursive --new-files pl12/linux/fs/file_table.c linux/fs/file_table.c
+--- pl12/linux/fs/file_table.c	Mon Aug  9 17:41:22 1993
++++ linux/fs/file_table.c	Tue Aug 17 18:32:13 1993
+@@ -45,7 +45,7 @@
+ 	struct file * file;
+ 	int i;
+ 
+-	file = (struct file*) __get_free_page(GFP_BUFFER);
++	file = (struct file *) get_free_page(GFP_KERNEL);
+ 
+ 	if (!file)
+ 		return;
+diff -u --recursive --new-files pl12/linux/fs/inode.c linux/fs/inode.c
+--- pl12/linux/fs/inode.c	Mon Aug  9 17:41:22 1993
++++ linux/fs/inode.c	Tue Aug 17 18:41:05 1993
+@@ -87,7 +87,7 @@
+ 	struct inode * inode;
+ 	int i;
+ 
+-	if(!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
++	if (!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
+ 		return;
+ 
+ 	i=PAGE_SIZE / sizeof(struct inode);
+diff -u --recursive --new-files pl12/linux/fs/namei.c linux/fs/namei.c
+--- pl12/linux/fs/namei.c	Mon Aug  9 18:02:29 1993
++++ linux/fs/namei.c	Tue Aug 17 23:40:11 1993
+@@ -266,7 +266,7 @@
+  *
+  * namei for open - this is in fact almost the whole open-routine.
+  *
+- * Note that the low bits of "flag" aren't the same asin the open
++ * Note that the low bits of "flag" aren't the same as in the open
+  * system call - they are 00 - no permissions needed
+  *			  01 - read permission needed
+  *			  10 - write permission needed
+@@ -376,6 +376,16 @@
+ 			}
+  		}
+  	}
++	if (flag & O_TRUNC) {
++	      inode->i_size = 0;
++	      if (inode->i_op && inode->i_op->truncate)
++	           inode->i_op->truncate(inode);
++	      if ((error = notify_change(NOTIFY_SIZE, inode))) {
++		   iput(inode);
++		   return error;
++	      }
++	      inode->i_dirt = 1;
++	}
+ 	*res_inode = inode;
+ 	return 0;
+ }
+diff -u --recursive --new-files pl12/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c
+--- pl12/linux/fs/nfs/mmap.c	Sun Aug 15 11:46:03 1993
++++ linux/fs/nfs/mmap.c	Sat Aug 21 10:31:31 1993
+@@ -50,11 +50,9 @@
+ {
+ 	struct vm_area_struct * mpnt;
+ 
+-	if (off & (inode->i_sb->s_blocksize - 1))
++	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
+ 		return -EINVAL;
+-	if (len > high_memory || off > high_memory - len) /* avoid overflow */
+-		return -ENXIO;
+-	if (get_limit(USER_DS) != TASK_SIZE)
++	if (off & (inode->i_sb->s_blocksize - 1))
+ 		return -EINVAL;
+ 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
+ 		return -EACCES;
+@@ -79,10 +77,6 @@
+ 	mpnt->vm_ops = &nfs_file_mmap;
+ 	mpnt->vm_next = current->mmap;
+ 	current->mmap = mpnt;
+-#if 0
+-	printk("VFS: Loaded mmap at %08x - %08x\n",
+-		mpnt->vm_start,	mpnt->vm_end);
+-#endif
+ 	return 0;
+ }
+ 
+diff -u --recursive --new-files pl12/linux/fs/open.c linux/fs/open.c
+--- pl12/linux/fs/open.c	Mon Aug  9 18:02:29 1993
++++ linux/fs/open.c	Tue Aug 17 23:40:11 1993
+@@ -378,18 +378,7 @@
+ 		f->f_count--;
+ 		return error;
+ 	}
+-	if (flag & O_TRUNC) {
+-		inode->i_size = 0;
+-		if (inode->i_op && inode->i_op->truncate)
+-			inode->i_op->truncate(inode);
+-		if ((error = notify_change(NOTIFY_SIZE, inode))) {
+-			iput(inode);
+-			current->filp[fd] = NULL;
+-			f->f_count--;
+-			return error;
+-		}
+-		inode->i_dirt = 1;
+-	}
++
+ 	f->f_inode = inode;
+ 	f->f_pos = 0;
+ 	f->f_reada = 0;
+diff -u --recursive --new-files pl12/linux/fs/proc/array.c linux/fs/proc/array.c
+--- pl12/linux/fs/proc/array.c	Mon Aug  9 18:02:29 1993
++++ linux/fs/proc/array.c	Fri Aug 20 09:40:57 1993
+@@ -194,7 +194,7 @@
+ 	if (vsize) {
+ 		eip = KSTK_EIP(vsize);
+ 		esp = KSTK_ESP(vsize);
+-		vsize = (*p)->brk + PAGE_SIZE-1;
++		vsize = (*p)->brk - (*p)->start_code + PAGE_SIZE-1;
+ 		if (esp)
+ 			vsize += TASK_SIZE - esp;
+ 	}
+@@ -264,7 +264,7 @@
+ 		return 0;
+ 	tpag = (*p)->end_code / PAGE_SIZE;
+ 	if ((*p)->state != TASK_ZOMBIE) {
+-	  pagedir = PAGE_DIR_OFFSET((*p)->tss.cr3,(*p)->start_code);
++	  pagedir = (unsigned long *) (*p)->tss.cr3;
+ 	  for (i = 0; i < 0x300; ++i) {
+ 	    if ((ptbl = pagedir[i]) == 0) {
+ 	      tpag -= PTRS_PER_PAGE;
+diff -u --recursive --new-files pl12/linux/include/linux/a.out.h linux/include/linux/a.out.h
+--- pl12/linux/include/linux/a.out.h	Mon Aug  9 17:41:23 1993
++++ linux/include/linux/a.out.h	Fri Aug 20 08:59:31 1993
+@@ -71,24 +71,26 @@
+ #define NMAGIC 0410
+ /* Code indicating demand-paged executable.  */
+ #define ZMAGIC 0413
++/* This indicates a demand-paged executable with the header in the text. 
++   The first page is unmapped to help trap NULL pointer references */
++#define QMAGIC 0314
+ 
+ /* Code indicating core file.  */
+ #define CMAGIC 0421
++
+ #if !defined (N_BADMAG)
+-#define N_BADMAG(x)					\
+- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC		\
+-  && N_MAGIC(x) != ZMAGIC)
++#define N_BADMAG(x)	  (N_MAGIC(x) != OMAGIC		\
++			&& N_MAGIC(x) != NMAGIC		\
++  			&& N_MAGIC(x) != ZMAGIC \
++		        && N_MAGIC(x) != QMAGIC)
+ #endif
+ 
+-#define _N_BADMAG(x)					\
+- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC		\
+-  && N_MAGIC(x) != ZMAGIC)
+-
+ #define _N_HDROFF(x) (1024 - sizeof (struct exec))
+ 
+ #if !defined (N_TXTOFF)
+ #define N_TXTOFF(x) \
+- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
++ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
++  (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
+ #endif
+ 
+ #if !defined (N_DATOFF)
+@@ -113,7 +115,7 @@
+ 
+ /* Address of text segment in memory after it is loaded.  */
+ #if !defined (N_TXTADDR)
+-#define N_TXTADDR(x) 0
++#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
+ #endif
+ 
+ /* Address of data segment in memory after it is loaded.
+diff -u --recursive --new-files pl12/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
+--- pl12/linux/include/linux/binfmts.h	Fri Aug  6 13:32:00 1993
++++ linux/include/linux/binfmts.h	Fri Aug 20 08:59:31 1993
+@@ -15,6 +15,7 @@
+   char buf[128];
+   unsigned long page[MAX_ARG_PAGES];
+   unsigned long p;
++  int sh_bang;
+   struct inode * inode;
+   int e_uid, e_gid;
+   int argc, envc;
+@@ -31,6 +32,15 @@
+ 
+ extern struct linux_binfmt formats[];
+ 
++extern int read_exec(struct inode *inode, unsigned long offset,
++	char * addr, unsigned long count);
+ 
++extern int open_inode(struct inode * inode, int mode);
++
++extern void flush_old_exec(struct linux_binprm * bprm);
++extern unsigned long change_ldt(unsigned long text_size,unsigned long * page);
++extern unsigned long * create_tables(char * p,int argc,int envc);
++extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
++		unsigned long p, int from_kmem);
+ 
+ #endif
+diff -u --recursive --new-files pl12/linux/include/linux/elf.h linux/include/linux/elf.h
+--- pl12/linux/include/linux/elf.h
++++ linux/include/linux/elf.h	Fri Aug 20 08:59:31 1993
+@@ -0,0 +1,306 @@
++#ifndef _ELF_H
++#define _ELF_H
++
++/* THese constants are for the segment types stored in the image headers */
++#define PT_NULL    0
++#define PT_LOAD    1
++#define PT_DYNAMIC 2
++#define PT_INTERP  3
++#define PT_NOTE    4
++#define PT_SHLIB   5
++#define PT_PHDR    6
++#define PT_LOPROC  0x70000000
++#define PT_HIPROC  0x7fffffff
++
++/* These constants define the different elf file types */
++#define ET_NONE   0
++#define ET_REL    1
++#define ET_EXEC   2
++#define ET_DYN    3
++#define ET_CORE   4
++#define ET_LOPROC 5
++#define ET_HIPROC 6
++
++/* These constants define the various ELF target machines */
++#define EM_NONE  0
++#define EM_M32   1
++#define EM_SPARC 2
++#define EM_386   3
++#define EM_68K   4
++#define EM_88K   5
++#define EM_486   6   /* Perhaps disused */
++#define EM_860   7
++
++/* This is the info that is needed to parse the dynamic section of the file */
++#define DT_NULL		0
++#define DT_NEEDED	1
++#define DT_PLTRELSZ	2
++#define DT_PLTGOT	3
++#define DT_HASH		4
++#define DT_STRTAB	5
++#define DT_SYMTAB	6
++#define DT_RELA		7
++#define DT_RELASZ	8
++#define DT_RELAENT	9
++#define DT_STRSZ	10
++#define DT_SYMENT	11
++#define DT_INIT		12
++#define DT_FINI		13
++#define DT_SONAME	14
++#define DT_RPATH 	15
++#define DT_SYMBOLIC	16
++#define DT_REL	        17
++#define DT_RELSZ	18
++#define DT_RELENT	19
++#define DT_PLTREL	20
++#define DT_DEBUG	21
++#define DT_TEXTREL	22
++#define DT_JMPREL	23
++#define DT_LOPROC	0x70000000
++#define DT_HIPROC	0x7fffffff
++
++/* This info is needed when parsing the symbol table */
++#define STB_LOCAL  0
++#define STB_GLOBAL 1
++#define STB_WEAK   2
++
++#define STT_NOTYPE  0
++#define STT_OBJECT  1
++#define STT_FUNC    2
++#define STT_SECTION 3
++#define STT_FILE    4
++
++#define ELF32_ST_BIND(x) ((x) >> 4)
++#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
++
++
++
++struct dynamic{
++  int d_tag;
++  union{
++    int d_val;
++    char * d_ptr;
++  } d_un;
++};
++
++/* THe following are used with relocations */
++#define ELF32_R_SYM(x) ((x) >> 8)
++#define ELF32_R_TYPE(x) ((x) & 0xff)
++
++#define R_386_NONE	0
++#define R_386_32	1
++#define R_386_PC32	2
++#define R_386_GOT32	3
++#define R_386_PLT32	4
++#define R_386_COPY	5
++#define R_386_GLOB_DAT	6
++#define R_386_JMP_SLOT	7
++#define R_386_RELATIVE	8
++#define R_386_GOTOFF	9
++#define R_386_GOTPC	10
++#define R_386_NUM	11
++
++struct Elf32_Rel{
++  unsigned int * offset;
++  int info;
++};
++
++struct Elf32_Rela{
++  unsigned int * offset;
++  int info;
++  int addend;
++};
++
++struct Elf32_Sym{
++  int st_name;
++  unsigned int st_value;
++  int st_size;
++  unsigned char st_info;
++  unsigned char st_other;
++  short int st_shndx;
++};
++
++struct elfhdr{
++  char	e_ident[16];
++  short int e_type;
++  short int e_machine;
++  int   e_version;
++  char *e_entry;  /* Entry point */
++  int   e_phoff;
++  int   e_shoff;
++  int   e_flags;
++  short int e_ehsize;
++  short int e_phentsize;
++  short int e_phnum;
++  short int e_shentsize;
++  short int e_shnum;
++  short int e_shstrndx;
++};
++
++struct elf_phdr{
++  int p_type;
++  int p_offset;
++  int p_vaddr;
++  int p_paddr;
++  int p_filesz;
++  int p_memsz;
++  int p_flags;
++  int p_align;
++};
++
++#define ELF_START_MMAP 0x80000000
++
++#endif
++#ifndef _ELF_H
++#define _ELF_H
++
++/* THese constants are for the segment types stored in the image headers */
++#define PT_NULL    0
++#define PT_LOAD    1
++#define PT_DYNAMIC 2
++#define PT_INTERP  3
++#define PT_NOTE    4
++#define PT_SHLIB   5
++#define PT_PHDR    6
++#define PT_LOPROC  0x70000000
++#define PT_HIPROC  0x7fffffff
++
++/* These constants define the different elf file types */
++#define ET_NONE   0
++#define ET_REL    1
++#define ET_EXEC   2
++#define ET_DYN    3
++#define ET_CORE   4
++#define ET_LOPROC 5
++#define ET_HIPROC 6
++
++/* These constants define the various ELF target machines */
++#define EM_NONE  0
++#define EM_M32   1
++#define EM_SPARC 2
++#define EM_386   3
++#define EM_68K   4
++#define EM_88K   5
++#define EM_486   6   /* Perhaps disused */
++#define EM_860   7
++
++/* This is the info that is needed to parse the dynamic section of the file */
++#define DT_NULL		0
++#define DT_NEEDED	1
++#define DT_PLTRELSZ	2
++#define DT_PLTGOT	3
++#define DT_HASH		4
++#define DT_STRTAB	5
++#define DT_SYMTAB	6
++#define DT_RELA		7
++#define DT_RELASZ	8
++#define DT_RELAENT	9
++#define DT_STRSZ	10
++#define DT_SYMENT	11
++#define DT_INIT		12
++#define DT_FINI		13
++#define DT_SONAME	14
++#define DT_RPATH 	15
++#define DT_SYMBOLIC	16
++#define DT_REL	        17
++#define DT_RELSZ	18
++#define DT_RELENT	19
++#define DT_PLTREL	20
++#define DT_DEBUG	21
++#define DT_TEXTREL	22
++#define DT_JMPREL	23
++#define DT_LOPROC	0x70000000
++#define DT_HIPROC	0x7fffffff
++
++/* This info is needed when parsing the symbol table */
++#define STB_LOCAL  0
++#define STB_GLOBAL 1
++#define STB_WEAK   2
++
++#define STT_NOTYPE  0
++#define STT_OBJECT  1
++#define STT_FUNC    2
++#define STT_SECTION 3
++#define STT_FILE    4
++
++#define ELF32_ST_BIND(x) ((x) >> 4)
++#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
++
++
++
++struct dynamic{
++  int d_tag;
++  union{
++    int d_val;
++    char * d_ptr;
++  } d_un;
++};
++
++/* THe following are used with relocations */
++#define ELF32_R_SYM(x) ((x) >> 8)
++#define ELF32_R_TYPE(x) ((x) & 0xff)
++
++#define R_386_NONE	0
++#define R_386_32	1
++#define R_386_PC32	2
++#define R_386_GOT32	3
++#define R_386_PLT32	4
++#define R_386_COPY	5
++#define R_386_GLOB_DAT	6
++#define R_386_JMP_SLOT	7
++#define R_386_RELATIVE	8
++#define R_386_GOTOFF	9
++#define R_386_GOTPC	10
++#define R_386_NUM	11
++
++struct Elf32_Rel{
++  unsigned int * offset;
++  int info;
++};
++
++struct Elf32_Rela{
++  unsigned int * offset;
++  int info;
++  int addend;
++};
++
++struct Elf32_Sym{
++  int st_name;
++  unsigned int st_value;
++  int st_size;
++  unsigned char st_info;
++  unsigned char st_other;
++  short int st_shndx;
++};
++
++struct elfhdr{
++  char	e_ident[16];
++  short int e_type;
++  short int e_machine;
++  int   e_version;
++  char *e_entry;  /* Entry point */
++  int   e_phoff;
++  int   e_shoff;
++  int   e_flags;
++  short int e_ehsize;
++  short int e_phentsize;
++  short int e_phnum;
++  short int e_shentsize;
++  short int e_shnum;
++  short int e_shstrndx;
++};
++
++struct elf_phdr{
++  int p_type;
++  int p_offset;
++  int p_vaddr;
++  int p_paddr;
++  int p_filesz;
++  int p_memsz;
++  int p_flags;
++  int p_align;
++};
++
++#define ELF_START_MMAP 0x80000000
++
++#endif
+diff -u --recursive --new-files pl12/linux/include/linux/signal.h linux/include/linux/signal.h
+--- pl12/linux/include/linux/signal.h	Thu May 20 10:34:30 1993
++++ linux/include/linux/signal.h	Mon Aug 16 18:55:12 1993
+@@ -53,6 +53,9 @@
+ */
+ #define SIGPWR		30
+ 
++/* Arggh. Bad user source code wants this.. */
++#define SIGBUS		SIGUNUSED
++
+ /*
+  * sa_flags values: SA_STACK is not currently supported, but will allow the
+  * usage of signal stacks by using the (now obsolete) sa_restorer field in
+diff -u --recursive --new-files pl12/linux/include/linux/tasks.h linux/include/linux/tasks.h
+--- pl12/linux/include/linux/tasks.h	Mon Jan 18 22:06:34 1993
++++ linux/include/linux/tasks.h	Wed Aug 18 23:05:21 1993
+@@ -4,6 +4,6 @@
+ /*
+  * This is the maximum nr of tasks - change it if you need to
+  */
+-#define NR_TASKS	64
++#define NR_TASKS	128
+ 
+ #endif
+diff -u --recursive --new-files pl12/linux/include/linux/timer.h linux/include/linux/timer.h
+--- pl12/linux/include/linux/timer.h	Sat Aug 14 23:47:22 1993
++++ linux/include/linux/timer.h	Tue Aug 17 18:39:34 1993
+@@ -17,6 +17,8 @@
+  * 
+  * HD_TIMER		harddisk timer
+  *
++ * HD_TIMER2		(atdisk2 patches)
++ *
+  * FLOPPY_TIMER		floppy disk timer (not used right now)
+  * 
+  * SCSI_TIMER		scsi.c timeout timer
+@@ -43,6 +45,8 @@
+ 
+ #define TAPE_QIC02_TIMER	22	/* hhb */
+ #define MCD_TIMER	23
++
++#define HD_TIMER2	24
+ 
+ struct timer_struct {
+ 	unsigned long expires;
+diff -u --recursive --new-files pl12/linux/kernel/chr_drv/keyboard.c linux/kernel/chr_drv/keyboard.c
+--- pl12/linux/kernel/chr_drv/keyboard.c	Sat Aug 14 18:52:34 1993
++++ linux/kernel/chr_drv/keyboard.c	Thu Aug 19 18:45:38 1993
+@@ -584,6 +584,8 @@
+ 		value = KVAL(K_SHIFT);
+ 		clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
+ 	}
++	if (value > 3)
++		return;
+ 
+ 	if (up_flag) {
+ 		if (k_down[value])
+diff -u --recursive --new-files pl12/linux/kernel/chr_drv/mem.c linux/kernel/chr_drv/mem.c
+--- pl12/linux/kernel/chr_drv/mem.c	Mon Aug  9 18:02:32 1993
++++ linux/kernel/chr_drv/mem.c	Sat Aug 21 10:19:32 1993
+@@ -129,12 +129,28 @@
+ static int mmap_mem(struct inode * inode, struct file * file,
+ 	unsigned long addr, size_t len, int prot, unsigned long off)
+ {
++	struct vm_area_struct * mpnt;
++
+ 	if (off & 0xfff || off + len < off)
+ 		return -ENXIO;
+-
+ 	if (remap_page_range(addr, off, len, prot))
+ 		return -EAGAIN;
+-	
++/* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */
++	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
++	if (!mpnt)
++		return 0;
++
++	mpnt->vm_task = current;
++	mpnt->vm_start = addr;
++	mpnt->vm_end = addr + len;
++	mpnt->vm_page_prot = prot;
++	mpnt->vm_share = NULL;
++	mpnt->vm_inode = inode;
++	inode->i_count++;
++	mpnt->vm_offset = off;
++	mpnt->vm_ops = NULL;
++	mpnt->vm_next = current->mmap;
++	current->mmap = mpnt;
+ 	return 0;
+ }
+ 
+diff -u --recursive --new-files pl12/linux/kernel/chr_drv/serial.c linux/kernel/chr_drv/serial.c
+--- pl12/linux/kernel/chr_drv/serial.c	Fri Aug 13 21:20:52 1993
++++ linux/kernel/chr_drv/serial.c	Wed Aug 18 01:13:23 1993
+@@ -1321,12 +1321,10 @@
+ 	
+ 	switch (cmd) {
+ 		case TCSBRK:	/* SVID version: non-zero arg --> no break */
+-			wait_until_sent(tty);
+ 			if (!arg)
+ 				send_break(info, HZ/4);	/* 1/4 second */
+ 			return 0;
+ 		case TCSBRKP:	/* support for POSIX tcsendbreak() */
+-			wait_until_sent(tty);
+ 			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+ 			return 0;
+ 		case TIOCGSOFTCAR:
+diff -u --recursive --new-files pl12/linux/kernel/chr_drv/tty_ioctl.c linux/kernel/chr_drv/tty_ioctl.c
+--- pl12/linux/kernel/chr_drv/tty_ioctl.c	Thu Jul 29 12:15:25 1993
++++ linux/kernel/chr_drv/tty_ioctl.c	Wed Aug 18 01:13:07 1993
+@@ -605,7 +605,12 @@
+ 			     tty->packet = 0;
+ 			   return (0);
+ 			}
+-
++		case TCSBRK: case TCSBRKP:
++			wait_until_sent(tty);
++			if (!tty->ioctl)
++				return 0;
++			tty->ioctl(tty, file, cmd, arg);
++			return 0;
+ 		default:
+ 			if (tty->ioctl) {
+ 				retval = (tty->ioctl)(tty, file, cmd, arg);
+diff -u --recursive --new-files pl12/linux/kernel/exit.c linux/kernel/exit.c
+--- pl12/linux/kernel/exit.c	Mon Aug  2 18:16:26 1993
++++ linux/kernel/exit.c	Sat Aug 21 11:14:59 1993
+@@ -376,7 +376,7 @@
+ 		current->mmap = NULL;
+ 		while (mpnt) {
+ 			mpnt1 = mpnt->vm_next;
+-			if (mpnt->vm_ops->close)
++			if (mpnt->vm_ops && mpnt->vm_ops->close)
+ 				mpnt->vm_ops->close(mpnt);
+ 			kfree(mpnt);
+ 			mpnt = mpnt1;
+diff -u --recursive --new-files pl12/linux/kernel/signal.c linux/kernel/signal.c
+--- pl12/linux/kernel/signal.c	Sun Aug 15 14:28:14 1993
++++ linux/kernel/signal.c	Sat Aug 21 10:38:00 1993
+@@ -22,6 +22,31 @@
+ 
+ extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs);
+ 
++struct sigcontext_struct {
++	unsigned short gs, __gsh;
++	unsigned short fs, __fsh;
++	unsigned short es, __esh;
++	unsigned short ds, __dsh;
++	unsigned long edi;
++	unsigned long esi;
++	unsigned long ebp;
++	unsigned long esp;
++	unsigned long ebx;
++	unsigned long edx;
++	unsigned long ecx;
++	unsigned long eax;
++	unsigned long trapno;
++	unsigned long err;
++	unsigned long eip;
++	unsigned short cs, __csh;
++	unsigned long eflags;
++	unsigned long esp_at_signal;
++	unsigned short ss, __ssh;
++	unsigned long i387;
++	unsigned long oldmask;
++	unsigned long cr2;
++};
++
+ extern "C" int sys_sgetmask(void)
+ {
+ 	return current->blocked;
+@@ -151,15 +176,32 @@
+ /*
+  * This sets regs->esp even though we don't actually use sigstacks yet..
+  */
+-extern "C" int sys_sigreturn(unsigned long oldmask, unsigned long eip, unsigned long esp)
++extern "C" int sys_sigreturn(unsigned long __unused)
+ {
++#define CHECK_SEG(x) if (x) x |= 3
++#define COPY(x) regs->x = context.x
++	struct sigcontext_struct context;
+ 	struct pt_regs * regs;
+ 
+-	regs = (struct pt_regs *) &oldmask;
+-	current->blocked = oldmask & _BLOCKABLE;
+-	regs->eip = eip;
+-	regs->esp = esp;
+-	return 0;
++	regs = (struct pt_regs *) &__unused;
++	memcpy_fromfs(&context,(void *) regs->esp, sizeof(context));
++	current->blocked = context.oldmask & _BLOCKABLE;
++	CHECK_SEG(context.ss);
++	CHECK_SEG(context.cs);
++	CHECK_SEG(context.ds);
++	CHECK_SEG(context.es);
++	CHECK_SEG(context.fs);
++	CHECK_SEG(context.gs);
++	COPY(eip); COPY(eflags);
++	COPY(ecx); COPY(edx);
++	COPY(ebx);
++	COPY(esp); COPY(ebp);
++	COPY(edi); COPY(esi);
++	COPY(cs); COPY(ss);
++	COPY(ds); COPY(es);
++	COPY(fs); COPY(gs);
++	regs->orig_eax = -1;		/* disable syscall checks */
++	return context.eax;
+ }
+ 
+ /*
+@@ -186,32 +228,26 @@
+ 	put_fs_long(regs->edi, frame+6);
+ 	put_fs_long(regs->esi, frame+7);
+ 	put_fs_long(regs->ebp, frame+8);
+-	put_fs_long(regs->esp, frame+9);
++	put_fs_long((long)*fp, frame+9);
+ 	put_fs_long(regs->ebx, frame+10);
+ 	put_fs_long(regs->edx, frame+11);
+ 	put_fs_long(regs->ecx, frame+12);
+ 	put_fs_long(regs->eax, frame+13);
+-	put_fs_long(0, frame+14);		/* trapno */
+-	put_fs_long(0, frame+15);		/* err */
+-	put_fs_long(regs->eip, frame+16);
++	put_fs_long(0, frame+14);		/* trapno - not implemented */
++	put_fs_long(0, frame+15);		/* err - not implemented */
++	put_fs_long(eip, frame+16);
+ 	put_fs_long(regs->cs, frame+17);
+ 	put_fs_long(regs->eflags, frame+18);
+ 	put_fs_long(regs->esp, frame+19);
+ 	put_fs_long(regs->ss, frame+20);
+-	put_fs_long(0,frame+21);		/* 387 state pointer */
+-/* linux extended stack - easier to handle.. */
+-	put_fs_long(regs->eflags, frame+22);
+-	put_fs_long(eip, frame+23);
++	put_fs_long(0,frame+21);		/* 387 state pointer - not implemented*/
++/* non-iBCS2 extensions.. */
++	put_fs_long(oldmask, frame+22);
++	put_fs_long(0, frame+23);		/* cr2 - not implemented */
+ /* set up the return code... */
+ 	put_fs_long(0x0000b858, CODE(0));	/* popl %eax ; movl $,%eax */
+-	put_fs_long(0x00bb0000, CODE(4));	/* movl $,%ebx */
+-	put_fs_long(0xcd000000, CODE(8));	/* int $0x80 */
+-	put_fs_long(0x0fa90f80, CODE(12));	/* pop %gs ; pop %fs */
+-	put_fs_long(0x611f07a1, CODE(16));	/* pop %es ; pop %ds ; popad */
+-	put_fs_long(0x20c48390, CODE(20));	/* nop ; addl $32,%esp */
+-	put_fs_long(0x0020c29d, CODE(24));	/* popfl ; ret $32 */
+-	put_fs_long(__NR_ssetmask, CODE(2));
+-	put_fs_long(oldmask, CODE(7));
++	put_fs_long(0x80cd0000, CODE(4));	/* int $0x80 */
++	put_fs_long(__NR_sigreturn, CODE(2));
+ 	*fp = frame;
+ #undef __CODE
+ #undef CODE
+@@ -317,8 +353,8 @@
+ 	frame = (unsigned long *) regs->esp;
+ 	signr = 1;
+ 	sa = current->sigaction;
+-	if (regs->cs != USER_CS || regs->ss != USER_DS)
+-		printk("Warning: signal handler with nonstandard code/stack segment\n");
++	if (regs->ss != USER_DS)
++		printk("Warning: signal handler with nonstandard stack segment\n");
+ 	for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
+ 		if (mask > handler_signal)
+ 			break;
+@@ -331,6 +367,9 @@
+ 		__asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler));
+ 		setup_frame(&frame,eip,regs,signr,sa_handler,oldmask);
+ 		eip = sa_handler;
++		regs->cs = USER_CS; regs->ss = USER_DS;
++		regs->ds = USER_DS; regs->es = USER_DS;
++		regs->gs = USER_DS; regs->fs = USER_DS;
+ 		current->blocked |= sa->sa_mask;
+ 		oldmask |= sa->sa_mask;
+ 	}
+diff -u --recursive --new-files pl12/linux/mm/memory.c linux/mm/memory.c
+--- pl12/linux/mm/memory.c	Sun Aug 15 11:09:18 1993
++++ linux/mm/memory.c	Sat Aug 21 10:23:07 1993
+@@ -760,7 +760,7 @@
+ {
+ 	struct task_struct ** p;
+ 
+-	if (!inode || inode->i_count < 2)
++	if (!inode || inode->i_count < 2 || !area->vm_ops)
+ 		return 0;
+ 	for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
+ 		if (!*p)
+@@ -773,8 +773,8 @@
+ 			   we can share pages with */
+ 			if(area){
+ 			  struct vm_area_struct * mpnt;
+-			  for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next){
+-			    if(mpnt->vm_ops && mpnt->vm_ops == area->vm_ops &&
++			  for (mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
++			    if (mpnt->vm_ops == area->vm_ops &&
+ 			       mpnt->vm_inode->i_ino == area->vm_inode->i_ino&&
+ 			       mpnt->vm_inode->i_dev == area->vm_inode->i_dev){
+ 			      if (mpnt->vm_ops->share(mpnt, area, address))
+@@ -851,6 +851,8 @@
+ 			continue;
+ 		if (address >= ((mpnt->vm_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
+ 			continue;
++		if (!mpnt->vm_ops || !mpnt->vm_ops->nopage)
++			break;
+ 		mpnt->vm_ops->nopage(error_code, mpnt, address);
+ 		return;
+ 	}
+@@ -858,7 +860,7 @@
+ 	get_empty_page(tsk,address);
+ 	if (tsk != current)
+ 		return;
+-	if (address < tsk->brk)
++	if (address >= tsk->end_data && address < tsk->brk)
+ 		return;
+ 	if (address+8192 >= (user_esp & 0xfffff000) && 
+ 	    address <= current->start_stack)
+diff -u --recursive --new-files pl12/linux/mm/mmap.c linux/mm/mmap.c
+--- pl12/linux/mm/mmap.c	Mon Aug  9 18:02:33 1993
++++ linux/mm/mmap.c	Sat Aug 21 11:37:00 1993
+@@ -52,11 +52,11 @@
+ 	switch (flags & MAP_TYPE) {
+ 	case MAP_SHARED:
+ 		if ((prot & PROT_WRITE) && !(file->f_mode & 2))
+-			return -EINVAL;
++			return -EACCES;
+ 		/* fall through */
+ 	case MAP_PRIVATE:
+ 		if (!(file->f_mode & 1))
+-			return -EINVAL;
++			return -EACCES;
+ 		break;
+ 
+ 	default:
+@@ -169,7 +169,7 @@
+ 	while (free) {
+ 		mpnt = free;
+ 		free = free->vm_next;
+-		if (mpnt->vm_ops->close)
++		if (mpnt->vm_ops && mpnt->vm_ops->close)
+ 			mpnt->vm_ops->close(mpnt);
+ 		kfree(mpnt);
+ 	}
+@@ -197,11 +197,9 @@
+ 	extern struct vm_operations_struct file_mmap;
+ 	struct buffer_head * bh;
+ 
+-	if (off & (inode->i_sb->s_blocksize - 1))
++	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported right now */
+ 		return -EINVAL;
+-	if (len > high_memory || off > high_memory - len) /* avoid overflow */
+-		return -ENXIO;
+-	if (get_limit(USER_DS)  != TASK_SIZE)
++	if (off & (inode->i_sb->s_blocksize - 1))
+ 		return -EINVAL;
+ 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
+ 		return -EACCES;
+@@ -231,10 +229,6 @@
+ 	mpnt->vm_ops = &file_mmap;
+ 	mpnt->vm_next = current->mmap;
+ 	current->mmap = mpnt;
+-#if 0
+-	printk("VFS: Loaded mmap at %08x -  %08x\n",
+-		mpnt->vm_start,	mpnt->vm_end);
+-#endif
+ 	return 0;
+ }
+ 
+diff -u --recursive --new-files pl12/linux/net/inet/slip.c linux/net/inet/slip.c
+--- pl12/linux/net/inet/slip.c	Sat Jul 31 15:42:22 1993
++++ linux/net/inet/slip.c	Thu Aug 19 09:46:23 1993
+@@ -688,7 +688,7 @@
+   if (already++ == 0) {
+ 	printk("SLIP: version %s (%d channels): ",
+ 				SLIP_VERSION, SL_NRUNIT);
+-
++	printk("CSLIP code copyright 1989 Regents of the University of California\n");
+ 	/* Fill in our LDISC request block. */
+ 	sl_ldisc.flags	= 0;
+ 	sl_ldisc.open	= slip_open;
diff --git a/BUGS b/BUGS
new file mode 100644
index 0000000..1e43469
--- /dev/null
+++ b/BUGS
@@ -0,0 +1 @@
+- EBP and ESP are sometimes corrupted while running 16-bit code.
diff --git a/ChangeLog b/ChangeLog
index 8407996..c88a3c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,248 @@
+Fri Sep  3 11:52:18 1993  Bob Amstadt
+
+	* [windows/timer.c]
+	Changed to use CallWindowProc() rather directly calling callback.
+
+	* [windows/event.c]
+	Implemented SetCapture() and ReleaseCapture()
+
+	* [windows/keyboard.c]
+	Created stub for GetKeyState()
+
+	* [objects/linedda.c]
+	Created stub for LineDDA()
+
+	* [if1632/callback.c]
+	Created callback handler for LineDDA callback procedure.
+
+	* [if1632/callback.c]
+	Created FreeProcInstance()
+
+Fri Sep  3 08:36:52 1993  David Metcalfe
+
+	* [loader/signal.c]
+	Patch to and code for INT 1A
+
+Thu Sep  2 00:31:54 1993  Alexandre Julliard
+
+	* [objects/font.c] [objects/text.c]
+	More text support: implemented justification and underlining.
+
+	* [windows/clipping.c] [objects/clipping.c]
+	Moved low-level clipping functions to objects/clipping.c.
+
+	* [windows/clipping.c] [windows/event.c] [windows/message.c]
+	Implemented window update regions.
+
+	* [windows/dc.c] [objects/dcvalues.c]
+	Moved some device-independent DC functions to objects/dcvalues.c.
+
+	* [windows/graphics.c]
+	Implemented InvertRect() and GetPixel().
+
+Sat Aug 28 08:40:23 1993  Eric Youngdale
+
+	* [include/neexe.h] [loader/wine.c]
+	Added code to handle relocation type 4.
+
+	* [loader/signal.h] [loader/wine.c] [loader/selector.c]
+	Added support for dos interrupts.
+
+Thu 26 Aug 19:15:00 1993  Eric Youngdale
+
+	* [loader/selector.c]
+	Fixed bug dealing with loading DLLs.
+
+Thu Aug 26 19:22:40 1993  Alexandre Julliard
+
+        * [include/gdi.h] [objects/font.c] [windows/dc.c]
+        Beginning of real font support.
+
+        * [windows/graphics.c]
+        Implemented PatBlt().
+
+        * [memory/global.c]
+        Corrected a bug with linked list handling in GlobalAlloc().
+
+        * [objects/bitmap.c]
+        Corrected a bug in BITMAP_SelectObject().
+
+Tue Aug 24 19:22:40 1993  David Metcalfe
+
+        * [controls/Command*] [controls/Label*] [controls[MenuButto*]
+	  [controls/SmeMenuButt*]
+	Change code to support & as a special character in menu item text.
+
+Tue Aug 24 19:22:40 1993  Alexandre Julliard
+
+	* [include/gdi.h] [windows/dc.c]
+	Heavily modified the DC structure for better device-independence.
+
+	* [objects/bitmap.c]
+	Implemented bitmap dimensions.
+
+	* [windows/dc.c] [windows/dce.c]
+	Implemented DC state saving and restoring.
+
+	* [windows/dc.c]
+	Implemented ROP mode.
+
+	* [windows/graphics.c]
+	Implemented FillRect().
+
+Mon Aug 23 22:08:34 1993  Bob Amstadt  (bob at pooh)
+
+	* [misc/xt.c]
+	Fixed bug in InvalidateRect().  Solitaire attempted to
+	clear window before it was realized.
+
+	* [loader/resource.c]
+	Began rewrite of LoadBitmap().
+
+	* [loader/wine.c]
+	Fixed code which set Argv and Argc global variables.
+
+	* [loader/selector.c]
+	Added code to set up command line arguments.
+
+	* [include/neexe.h]
+	Fixed error in PSP structure.
+
+Tue Aug 17 20:41:12 1993  Alexandre Julliard
+
+	* [include/gdi.h] [windows/dc.c]
+	Implemented device capabilities.
+
+	* [objects/region.c]
+	Implemented EqualRgn() and CombineRgn().
+
+	* [windows/clipping.c]
+	Implemented Save/RestoreVisRgn().
+
+	* [windows/graphics.c]
+	Implemented PaintRgn() and FillRgn().
+
+	* [windows/mapping.c]
+	Implemented mapping modes.
+
+Tue Aug 10 14:07:38 1993  Alexandre Julliard
+
+	* [if1632/user.spec] [misc/rect.c]
+	Implemented rectangle API functions.
+
+	* [if1632/gdi.spec] [include/gdi.h] [objects/region.c]
+	Implemented regions.
+
+	* [windows/class.c]
+	Corrected a typo in UnregisterClass().
+
+	* [windows/clipping.c] [windows/dc.c]
+	Implemented DC clipping and visible region.
+
+Tue Aug 10 20:57:56 1993  Bob Amstadt  (bob at pooh)
+
+	* [controls/menu.c] [windows/win.c]
+	SetMenu(), GetMenu(), CheckMenuItem() implemented
+
+Thu Aug  5 22:33:22 1993  Bob Amstadt  (bob at pooh)
+
+	* [controls/menu.c] [windows/win.c]
+	Many improvements menus.  LoadMenu() should work.
+
+Wed Aug  4 14:55:36 1993  Alexandre Julliard
+
+        * [objects/dib.c]
+        Started the implementation of device-independent bitmaps.
+
+        * [objects/bitmap.c]
+        Added support for multiple bitmap depths.
+
+        * [objects/brush.c]
+        Implemented pattern brushes.
+
+        * [windows/dc.c] [windows/graphics.c]
+        Implemented some GDI graphics primitives.
+
+Tue Aug  3 21:16:47 1993  Bob Amstadt  (bob at pooh)
+
+	* [controls/menu.c] [windows/win.c] [include/menu.h]
+	Code to load class menus from executable file.
+
+	* [if1632/user.spec]
+	Fixed specification of SendMessage() and PostMessage.
+
+Mon Jul 26 21:53:24 1993  Alexandre Julliard
+
+	* [if1632/call.S]
+	Corrected a bug in KERNEL_InitTask().
+
+	* [include/windows.h]
+	Added a lot of constants.
+
+	* [loader/selector.c]
+	Corrected a bug in segment allocation in CreateSelectors().
+
+	* [objects/bitmap.c]
+	Implemented SelectObject() for bitmaps.
+
+	* [objects/brush.c]
+	Implemented hatched brushes and SelectObject().
+
+	* [objects/gdiobj.c]
+	Removed linked list (not needed).
+
+	* [objects/palette.c]
+	Implemented system palette creation and misc. palette API functions.
+
+	* [windows/timer.c]
+	Implemented timers.
+
+	* [windows/dc.c]
+	Implemented memory device contexts.
+
+Tue Jul 20 10:38:59 1993  Bob Amstadt  (bob at pooh)
+
+        * [dos.c]
+	Split DOS3Call() out of kernel.c.  Added support for get date
+	and time functions.
+
+	* [call.S]
+	Added function ReturnFromRegisterFunc() to allow DOS calls
+	to return values in registers.
+
+	* [regfunc.h]
+	Macros to access registers saved on stack.
+
+Tue Jul 20 10:38:59 1993  Alexandre Julliard
+
+        * [win.c]
+        Corrected allocation of the WM_CREATE data structure.
+
+        * [dce.c] [dce.h]
+        Implemented DCE handling.
+
+        * [bitmap.c] [brush.c] [dc.c] [font.c] [gdi.h] [gdi.spec] 
+          [gdiobj.c] [palette.c] [pen.c]
+        Implemented the GDI objects data structures and allocation.
+
+        * [windows.h]
+        Added several structures and constants for GDI objects.
+
+Mon Jul 19 12:51:10 1993  Bob Amstadt  (bob at pooh)
+
+	* [ldtlib.c]
+	Modified system calls to match Linus' new interface for
+	the LDT modification.
+
+	* [win.c]
+	Fixed bug with WM_CREATE message.
+
+	* [heap.c] [kernel.spec]
+	Completed local heap allocation functions.
+
+	* [global.c]
+	Created function GlobalQuickAlloc() for easy allocation from DLLs
+
 Tue Jul 13 20:31:31 1993  Bob Amstadt  (bob at pooh)
 
 	* [global.c]
diff --git a/Makefile b/Makefile
index f386ccd..ea2caf1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,64 +1,33 @@
-CFLAGS=-g -DDEBUG_RESOURCE -I./
+######################################################################
+# These variables are inherited by the sub-makefiles
+DEBUGOPTS=
+COPTS=-O2 -m486
+INCLUDE_DIR=include
 
 ######################################################################
-# FILES:
-#
-#	Be very careful if you change the order of the files listed
-# here.  if1632.o must linked first to guarrantee that it sits at a low
-# enough address.  I intend to change this requirement someday, but
-# for now live with it.
-#
-DLL_LENGTH=256
-
-BUILDOBJS=dll_kernel.o dll_user.o dll_gdi.o dll_unixlib.o \
-	  dll_win87em.o dll_shell.o \
-	  dll_kernel_tab.o dll_user_tab.o dll_gdi_tab.o dll_unixlib_tab.o \
-	  dll_win87em_tab.o dll_shell_tab.o
-
-MUST_BE_LINKED_FIRST=if1632.o $(BUILDOBJS)
-
-OBJS=$(MUST_BE_LINKED_FIRST) \
-	callback.o dump.o global.o heap.o ldt.o kernel.o relay.o resource.o \
-	selector.o message.o user.o wine.o class.o win.o widgets.o event.o xt.o
-
+# These definitions are for the top level
 TARGET=wine
-LIBS=-L. -L/usr/X386/lib -lldt -lXt -lX11
+LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm
+OBJS=if1632/if1632.o controls/controls.o loader/loader.o \
+	memory/memory.o misc/misc.o objects/objects.o windows/windows.o
+SUBDIRS=if1632 controls loader memory misc objects windows
 
 all: $(TARGET)
 
+dummy:
+
 clean:
-	rm -f *.o *~ *.s dll_* *.a
+	rm -f *~ *.o
+	@for i in tools $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done
 
-ci:
-	ci Makefile README *.c *.h *.S build-spec.txt *.spec
-
-$(TARGET): $(OBJS) libldt.a
+$(TARGET): dummy
+	@for i in tools $(SUBDIRS); \
+	do (cd $$i && echo $$i && $(MAKE) INCLUDE_DIR=../$(INCLUDE_DIR) \
+	COPTS="$(COPTS)" DEBUGOPTS="$(DEBUGOPTS)") || exit; done
 	$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
 
-build: build.c
-	cc -g -o build build.c
-
-libldt.a: ldtlib.c
-	$(CC) -O6 -c ldtlib.c
-	ar rcs libldt.a ldtlib.o
-
-dll_kernel.S dll_kernel_tab.c: build kernel.spec
-	build kernel.spec
-
-dll_user.S dll_user_tab.c: build user.spec
-	build user.spec
-
-dll_gdi.S dll_gdi_tab.c: build gdi.spec
-	build gdi.spec
-
-dll_unixlib.S dll_unixlib_tab.c: build unixlib.spec
-	build unixlib.spec
-
-dll_win87em.S dll_win87em_tab.c: build win87em.spec
-	build win87em.spec
-
-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
+depend:
+	@for i in tools $(SUBDIRS); \
+	     do (cd $$i && echo $$i && \
+	     $(MAKE) INCLUDE_DIR=../$(INCLUDE_DIR) depend) \
+	     || exit; done
diff --git a/README b/README
index 0a911df..ff6e23d 100644
--- a/README
+++ b/README
@@ -2,10 +2,70 @@
 warranty.  It is my intent to cover this code with the Gnu Public
 License.
 
-So here goes release 0.2.0 of the Windows loader.  It will do some 
-relocations and then run the program.  I have successfully loaded 
-the Windows solitaire game.  Try it.  It currently stops a call to
-GetObject().
+INSTALLATION:
+
+    Uncompress and untar this archive into the directory of your
+choice.  This release requires a Linux version 0.99 pl12 kernel with
+ALPHA-diffs and sognal-diffs.  Apply ALPHA-diffs first, and then
+signal-diffs.
+
+To build Wine, first do a "make depend" and then a "make".  The
+executable "wine" will be built.
+
+WHAT'S NEW with version 0.3.0: (see ChangeLog for details)
+	- Mouse capture
+	- Text justification and underlining
+	- Clipping
+	- LoadBitmap() completed
+	- Code generated by the Borland compiler should now work
+
+WHAT'S NEW with version 0.2.8: (see ChangeLog for details)
+	- Text functions from Alexandre
+	- INT 21h from Eric
+	- Menu improvements from David
+	- Bug fixes and GetProcAddress() stub from me
+
+WHAT'S NEW with version 0.2.7: (see ChangeLog for details)
+    - sol.exe gets further.  I did some debugging and now solitaire
+      stops when it tries to call GetTextExtent().  Any volunteers?
+    - Many DC updates from Alexandre.
+    - Menu updates to support underlining characters from David Metcalfe.
+
+WHAT'S NEW with version 0.2.6: (see ChangeLog for details)
+    - More region updates from Alexandre
+
+WHAT'S NEW with version 0.2.5: (see ChangeLog for details)
+    - Regions implemented by Alexandre
+    - More menuing code from me
+
+WHAT'S NEW with version 0.2.4: (see ChangeLog for details)
+    - Many improvements to GDI from Alexandre
+    - Many improvements to menu handling by me.
+
+WHAT'S NEW with version 0.2.3: (see ChangeLog for details)
+    - Bug fixes with SendMessage() and PostMessage()
+    - Preliminary menu support
+
+WHAT'S NEW with version 0.2.2: (see ChangeLog for details)
+    - Misc bug fixes
+    - More bitmap code
+    - Timers
+    - Memory DC's
+
+WHAT'S NEW with version 0.2.1:
+    - I have placed things into sub-directories.  The organization is
+      not finalized.  I imagine that the directory structure will
+      change as is necessary.  Files in the ./misc directory need
+      to be split apart and placed in apropriate directories.
+    - Tons of code from Alexandre.  He has constructed the framework
+      for handling GDI objects.  He has also provided code for DCEs.
+    - Local heap functions have been completed.
+    - Bug fixes in global.c and win.c
+    - New function GlobalQuickAlloc() combines GlobalAlloc() and
+      GlobalLock() into a single function call.
+    - New patch kit for Linux 0.99 pl11 kernel.  Thanks to Linus
+      who has graciously included our patches into the ALPHA patch
+      release cycle.
 
 WHAT'S NEW with version 0.2.0:
     - Alexandre Julliard has provided a replacement for the Tcl code.
@@ -76,33 +136,9 @@
     - GlobalAlloc of code segments.
     - Rewrite global memory support including kernel mods to allow
       application to mess with page map.
-    - complete and improve local heap allocation.
     - Handle self-loading applications.
     - Resource loading
-
-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.  "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.
-	
-	include/linux/ldt.h
-		- This contains structures defining the system call
-		  interface.
-
-	ldt.patch
-		- This is a patch that must be applied to the kernel.
-		  It updates two header files, and the kernel Makefile.
-
-Or follow the same procedure with "ldt512.tar".  This file contains
-Eric Youngdales patches for ALPHA-pl11.  These patches give the
-emulator 512 ldt entries instead of the 32 available with the older
-patch kit.
+    - Lots and lots of API fiunctions.
 
 BUILD:
 
diff --git a/class.c b/class.c
deleted file mode 100644
index 3a7cf2b..0000000
--- a/class.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Window classes functions
- *
- * Copyright 1993 Alexandre Julliard
- */
-
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-
-#include "class.h"
-
-
-static HCLASS firstClass = 0;
-
-
-/***********************************************************************
- *           CLASS_FindClassByName
- *
- * Return a handle and a pointer to the class.
- * The caller must GlobalUnlock the pointer.
- */
-HCLASS CLASS_FindClassByName( char * name, CLASS **ptr )
-{
-    HCLASS class, next;
-    
-    class = firstClass;
-    while(class)
-    {
-	*ptr = (CLASS *) GlobalLock(class);
-	if (!strcmp( (*ptr)->wc.lpszClassName, name )) return class;
-	next = (*ptr)->hNext;
-	GlobalUnlock(class);
-	class = next;
-    }
-    return 0;
-}
-
-/***********************************************************************
- *           CLASS_FindClassPtr
- *
- * Return a pointer to the CLASS structure corresponding to a HCLASS.
- * The caller must GlobalUnlock the pointer.
- */
-CLASS * CLASS_FindClassPtr( HCLASS hclass )
-{
-    CLASS * ptr;
-    
-    if (!hclass) return NULL;
-    ptr = (CLASS *) GlobalLock( hclass );
-    if (ptr->wMagic != CLASS_MAGIC) 
-    {
-	GlobalUnlock( hclass );
-	return NULL;
-    }	
-    return ptr;
-}
-
-
-/***********************************************************************
- *           RegisterClass    (USER.57)
- */
-ATOM RegisterClass( LPWNDCLASS class )
-{
-    CLASS * newClass;
-    HCLASS handle;
-    int i;
-    
-#ifdef DEBUG_CLASS
-    printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n", 
-	    class->lpfnWndProc, class->hInstance, class->lpszClassName );
-#endif
-
-    handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra );
-    if (!handle) return 0;
-    newClass = (CLASS *) GlobalLock( handle );
-    newClass->hNext      = firstClass;
-    newClass->wMagic     = CLASS_MAGIC;
-    newClass->atomName   = handle;  /* Should be an atom */
-    newClass->hDCE       = 0;  /* Should allocate a DCE if needed */
-    newClass->cWindows   = 0;  
-    newClass->wc         = *class;
-        
-    newClass->wc.lpszMenuName = 0;
-
-      /* Class name should also be set to zero. For now we need the
-       * name because we don't have atoms.
-       */
-    newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1);
-    strcpy( newClass->wc.lpszClassName, class->lpszClassName );
-    
-    if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
-
-    GlobalUnlock( handle );
-    
-    firstClass = handle;
-    return handle;  /* Should be an atom */
-}
-
-
-/***********************************************************************
- *           UnregisterClass    (USER.403)
- */
-BOOL UnregisterClass( LPSTR className, HANDLE instance )
-{
-    HANDLE class, next, prevClass;
-    CLASS * classPtr, * prevClassPtr;
-    
-      /* Check if we can remove this class */
-    class = CLASS_FindClassByName( className, &classPtr );
-    if (!class) return FALSE;
-    if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
-    {
-	GlobalUnlock( class );
-	return FALSE;
-    }
-    
-      /* Remove the class from the linked list */
-    if (firstClass == class) firstClass = classPtr->hNext;
-    else
-    {
-	prevClass = firstClass; 
-	while (prevClass)
-	{
-	    prevClassPtr = (CLASS *) GlobalLock(prevClass);
-	    next == prevClassPtr->hNext;
-	    if (next == class) break;
-	    GlobalUnlock(prevClass);
-	    prevClass = next;
-	}
-	if (!prevClass)
-	{
-	    printf( "ERROR: Class list corrupted\n" );
-	    return FALSE;
-	}
-	prevClassPtr->hNext = classPtr->hNext;
-	GlobalUnlock( prevClass );
-    }
-    
-    GlobalUnlock( class );
-    GlobalFree( class );
-    return TRUE;
-}
diff --git a/controls/Makefile b/controls/Makefile
new file mode 100644
index 0000000..4c7b67a
--- /dev/null
+++ b/controls/Makefile
@@ -0,0 +1,19 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+OBJS=menu.o widgets.o SmeMenuButto.o WinLabel.o WinCommand.o WinMenuButto.o
+#     WinButton.o
+
+default: controls.o
+
+controls.o: $(OBJS)
+	$(LD) -r -o controls.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/controls/SmeMenuButtP.h b/controls/SmeMenuButtP.h
new file mode 100644
index 0000000..176577d
--- /dev/null
+++ b/controls/SmeMenuButtP.h
@@ -0,0 +1,117 @@
+/*
+ * $XConsortium: SmeMenuButtP.h,v 1.6 89/12/11 15:20:15 kit Exp $
+ *
+ * Copyright 1989 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Chris D. Peterson, MIT X Consortium
+ *
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Added code to translate ampersand to underlined char
+ */
+
+/* 
+ * SmeP.h - Private definitions for Sme object
+ * 
+ */
+
+#ifndef _XawSmeMenuButtP_h
+#define _XawSmeMenuButtP_h
+
+/***********************************************************************
+ *
+ * Sme Object Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw/SmeP.h>
+#include "SmeMenuButto.h"
+
+/************************************************************
+ *
+ * New fields for the Sme Object class record.
+ *
+ ************************************************************/
+
+typedef struct _SmeMenuButtonClassPart {
+  XtPointer extension;
+} SmeMenuButtonClassPart;
+
+/* Full class record declaration */
+typedef struct _SmeMenuButtonClassRec {
+    RectObjClassPart       rect_class;
+    SmeClassPart     sme_class;
+    SmeMenuButtonClassPart  sme_bsb_class;
+} SmeMenuButtonClassRec;
+
+extern SmeMenuButtonClassRec smeMenuButtonClassRec;
+
+/* New fields for the Sme Object record */
+typedef struct {
+    /* resources */
+    String label;		/* The entry label. */
+    int vert_space;		/* extra vert space to leave, as a percentage
+				   of the font height of the label. */
+    Pixmap left_bitmap, right_bitmap; /* bitmaps to show. */
+    Dimension left_margin, right_margin; /* left and right margins. */
+    Pixel foreground;		/* foreground color. */
+    XFontStruct * font;		/* The font to show label in. */
+    XtJustify justify;		/* Justification for the label. */
+    String menu_name;		/* Menu to activate */
+    Boolean inactive;		/* True if can't be selected */
+
+/* private resources. */
+
+    Boolean set_values_area_cleared; /* Remember if we need to unhighlight. */
+    GC norm_gc;			/* noral color gc. */
+    GC rev_gc;			/* reverse color gc. */
+    GC norm_gray_gc;		/* Normal color (grayed out) gc. */
+    GC invert_gc;		/* gc for flipping colors. */
+
+    Dimension left_bitmap_width; /* size of each bitmap. */
+    Dimension left_bitmap_height;
+    Dimension right_bitmap_width;
+    Dimension right_bitmap_height;
+
+    int ul_pos;                 /* Offset in chars of underlined character */
+                                /* in label */
+} SmeMenuButtonPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _SmeMenuButtonRec {
+  ObjectPart         object;
+  RectObjPart        rectangle;
+  SmePart	     sme;
+  SmeMenuButtonPart   sme_bsb;
+} SmeMenuButtonRec;
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+#endif /* _XawSmeMenuButtP_h */
diff --git a/controls/SmeMenuButto.c b/controls/SmeMenuButto.c
new file mode 100644
index 0000000..5d426fc
--- /dev/null
+++ b/controls/SmeMenuButto.c
@@ -0,0 +1,758 @@
+/* $XConsortium: SmeMenuButton.c,v 1.16 91/03/15 15:59:41 gildea Exp $ */
+
+/*
+ * Copyright 1989 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * SmeMenuButton.c - Source code file for BSB Menu Entry object.
+ *
+ * Date:    September 26, 1989
+ *
+ * By:      Chris D. Peterson
+ *          MIT X Consortium 
+ *          kit@expo.lcs.mit.edu
+ *
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Added code to translate ampersand to underlined char
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+
+#include <X11/Xmu/Drawing.h>
+
+#include <X11/Xaw/XawInit.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include "SmeMenuButtP.h"
+#include <X11/Xaw/Cardinals.h>
+
+#include <stdio.h>
+
+#define ONE_HUNDRED 100
+
+#define offset(field) XtOffsetOf(SmeMenuButtonRec, sme_bsb.field)
+
+static XtResource resources[] = {
+  {XtNlabel,  XtCLabel, XtRString, sizeof(String),
+     offset(label), XtRString, NULL},
+  {XtNvertSpace,  XtCVertSpace, XtRInt, sizeof(int),
+     offset(vert_space), XtRImmediate, (XtPointer) 25},
+  {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap),
+     offset(left_bitmap), XtRImmediate, (XtPointer)None},
+  {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
+     offset(justify), XtRImmediate, (XtPointer) XtJustifyLeft},
+  {XtNrightBitmap, XtCRightBitmap, XtRBitmap, sizeof(Pixmap),
+     offset(right_bitmap), XtRImmediate, (XtPointer)None},
+  {XtNleftMargin,  XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
+     offset(left_margin), XtRImmediate, (XtPointer) 15},
+  {XtNrightMargin,  XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
+     offset(right_margin), XtRImmediate, (XtPointer) 5},
+  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+     offset(foreground), XtRString, XtDefaultForeground},
+  {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+     offset(font), XtRString, XtDefaultFont},
+  {XtNmenuName, XtCMenuName, XtRString, sizeof(String), 
+    offset(menu_name), XtRString, (XtPointer) NULL},
+  {XtNinactive, XtCInactive, XtRBoolean, sizeof(Boolean),
+    offset(inactive), XtRImmediate, (XtPointer) FALSE },
+};   
+#undef offset
+
+/*
+ * Semi Public function definitions. 
+ */
+
+static void Redisplay(), Destroy(), Initialize(), FlipColors();
+static void ClassInitialize();
+static void PopupMenu(), Unhighlight();
+static Boolean SetValues();
+static XtGeometryResult QueryGeometry();
+
+/* 
+ * Private Function Definitions.
+ */
+
+static void GetDefaultSize(), DrawBitmaps(), GetBitmapInfo();
+static void CreateGCs(), DestroyGCs();
+static void RemoveAmpersand();
+    
+#define superclass (&smeClassRec)
+SmeMenuButtonClassRec smeMenuButtonClassRec = {
+  {
+    /* superclass         */    (WidgetClass) superclass,
+    /* class_name         */    "SmeMenuButton",
+    /* size               */    sizeof(SmeMenuButtonRec),
+    /* class_initializer  */	ClassInitialize,
+    /* class_part_initialize*/	NULL,
+    /* Class init'ed      */	FALSE,
+    /* initialize         */    Initialize,
+    /* initialize_hook    */	NULL,
+    /* realize            */    NULL,
+    /* actions            */    NULL,
+    /* num_actions        */    ZERO,
+    /* resources          */    resources,
+    /* resource_count     */	XtNumber(resources),
+    /* xrm_class          */    NULLQUARK,
+    /* compress_motion    */    FALSE, 
+    /* compress_exposure  */    FALSE,
+    /* compress_enterleave*/ 	FALSE,
+    /* visible_interest   */    FALSE,
+    /* destroy            */    Destroy,
+    /* resize             */    NULL,
+    /* expose             */    Redisplay,
+    /* set_values         */    SetValues,
+    /* set_values_hook    */	NULL,
+    /* set_values_almost  */	XtInheritSetValuesAlmost,  
+    /* get_values_hook    */	NULL,			
+    /* accept_focus       */    NULL,
+    /* intrinsics version */	XtVersion,
+    /* callback offsets   */    NULL,
+    /* tm_table		  */    NULL,
+    /* query_geometry	  */    QueryGeometry,
+    /* display_accelerator*/    NULL,
+    /* extension	  */    NULL
+  },{
+    /* Menu Entry Fields */
+      
+    /* highlight */             FlipColors,
+    /* unhighlight */           Unhighlight,
+    /* notify */		XtInheritNotify,		
+    /* extension	  */    NULL
+  }, {
+    /* BSB Menu entry Fields */  
+
+    /* extension	  */    NULL
+  }
+};
+
+WidgetClass smeMenuButtonObjectClass = (WidgetClass) &smeMenuButtonClassRec;
+
+/************************************************************
+ *
+ * Semi-Public Functions.
+ *
+ ************************************************************/
+
+/*	Function Name: ClassInitialize
+ *	Description: Initializes the SmeMenuButtonObject. 
+ *	Arguments: none.
+ *	Returns: none.
+ */
+
+static void 
+ClassInitialize()
+{
+    XawInitializeWidgetSet();
+    XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0 );
+}
+
+/*      Function Name: Initialize
+ *      Description: Initializes the simple menu widget
+ *      Arguments: request - the widget requested by the argument list.
+ *                 new     - the new widget with both resource and non
+ *                           resource values.
+ *      Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new)
+Widget request, new;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) new;
+
+    if (entry->sme_bsb.label == NULL) 
+	entry->sme_bsb.label = XtName(new);
+    else
+	entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
+
+    RemoveAmpersand(new);
+
+    GetDefaultSize(new, &(entry->rectangle.width), &(entry->rectangle.height));
+    CreateGCs(new);
+
+    entry->sme_bsb.left_bitmap_width = entry->sme_bsb.left_bitmap_height = 0;
+    entry->sme_bsb.right_bitmap_width = entry->sme_bsb.right_bitmap_height = 0;
+
+    GetBitmapInfo(new, TRUE);	/* Left Bitmap Info */
+    GetBitmapInfo(new, FALSE);	/* Right Bitmap Info */
+}
+
+/*      Function Name: Destroy
+ *      Description: Called at destroy time, cleans up.
+ *      Arguments: w - the simple menu widget.
+ *      Returns: none.
+ */
+
+static void
+Destroy(w)
+Widget w;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+
+    DestroyGCs(w);
+    if (entry->sme_bsb.label != XtName(w))
+	XtFree(entry->sme_bsb.label);
+}
+
+/*      Function Name: Redisplay
+ *      Description: Redisplays the contents of the widget.
+ *      Arguments: w - the simple menu widget.
+ *                 event - the X event that caused this redisplay.
+ *                 region - the region the needs to be repainted. 
+ *      Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, region)
+Widget w;
+XEvent * event;
+Region region;
+{
+    GC gc;
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+    int	font_ascent, font_descent, y_loc;
+    int ul_x_loc, ul_y_loc, ul_width;
+
+    entry->sme_bsb.set_values_area_cleared = FALSE;    
+    font_ascent = entry->sme_bsb.font->max_bounds.ascent;
+    font_descent = entry->sme_bsb.font->max_bounds.descent;
+
+    y_loc = entry->rectangle.y;
+    
+    if (XtIsSensitive(w) && XtIsSensitive( XtParent(w) ) ) {
+	if ( w == XawSimpleMenuGetActiveEntry(XtParent(w)) ) {
+	    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), 
+			   entry->sme_bsb.norm_gc, 0, y_loc,
+			   (unsigned int) entry->rectangle.width,
+			   (unsigned int) entry->rectangle.height);
+	    gc = entry->sme_bsb.rev_gc;
+	}
+	else
+	    gc = entry->sme_bsb.norm_gc;
+    }
+    else
+	gc = entry->sme_bsb.norm_gray_gc;
+    
+    if (entry->sme_bsb.label != NULL) {
+	int x_loc = entry->sme_bsb.left_margin;
+	int len = strlen(entry->sme_bsb.label);
+	char * label = entry->sme_bsb.label;
+
+	switch(entry->sme_bsb.justify) {
+	    int width, t_width;
+
+	case XtJustifyCenter:
+	    t_width = XTextWidth(entry->sme_bsb.font, label, len);
+	    width = entry->rectangle.width - (entry->sme_bsb.left_margin +
+					      entry->sme_bsb.right_margin);
+	    x_loc += (width - t_width)/2;
+	    break;
+	case XtJustifyRight:
+	    t_width = XTextWidth(entry->sme_bsb.font, label, len);
+	    x_loc = entry->rectangle.width - (entry->sme_bsb.right_margin +
+					      t_width);
+	    break;
+	case XtJustifyLeft:
+	default:
+	    break;
+	}
+
+	y_loc += ((int)entry->rectangle.height - 
+		  (font_ascent + font_descent)) / 2 + font_ascent;
+	
+	XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
+		    x_loc, y_loc, label, len);
+
+	if (entry->sme_bsb.ul_pos != -1)
+	{
+	    ul_x_loc = x_loc + XTextWidth(entry->sme_bsb.font,
+		       entry->sme_bsb.label, entry->sme_bsb.ul_pos);
+	    ul_y_loc = entry->rectangle.y + (entry->rectangle.height + 
+		       font_ascent + font_descent) / 2;
+	    ul_width = XTextWidth(entry->sme_bsb.font,
+		       entry->sme_bsb.label + entry->sme_bsb.ul_pos, 1);
+
+	    XDrawLine(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
+		      ul_x_loc, ul_y_loc, ul_x_loc + ul_width - 1, ul_y_loc);
+	}
+    }
+
+    DrawBitmaps(w, gc);
+}
+
+
+/*      Function Name: SetValues
+ *      Description: Relayout the menu when one of the resources is changed.
+ *      Arguments: current - current state of the widget.
+ *                 request - what was requested.
+ *                 new - what the widget will become.
+ *      Returns: none
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new)
+Widget current, request, new;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) new;
+    SmeMenuButtonObject old_entry = (SmeMenuButtonObject) current;
+    Boolean ret_val = FALSE;
+
+    if (old_entry->sme_bsb.label != entry->sme_bsb.label) {
+        if (old_entry->sme_bsb.label != XtName( new ) )
+	    XtFree( (char *) old_entry->sme_bsb.label );
+
+	if (entry->sme_bsb.label != XtName(new) ) 
+	    entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
+
+	RemoveAmpersand(new);
+	ret_val = True;
+    }
+
+    if (entry->rectangle.sensitive != old_entry->rectangle.sensitive )
+	ret_val = TRUE;
+
+    if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap) {
+	GetBitmapInfo(new, TRUE);
+	ret_val = TRUE;
+    }
+
+    if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap) {
+	GetBitmapInfo(new, FALSE);
+	ret_val = TRUE;
+    }
+
+    if ( (old_entry->sme_bsb.font != entry->sme_bsb.font) ||
+	 (old_entry->sme_bsb.foreground != entry->sme_bsb.foreground) ) {
+	DestroyGCs(current);
+	CreateGCs(new);
+	ret_val = TRUE;
+    }
+
+    if (ret_val) {
+	GetDefaultSize(new, 
+		       &(entry->rectangle.width), &(entry->rectangle.height));
+	entry->sme_bsb.set_values_area_cleared = TRUE;
+    }
+    return(ret_val);
+}
+
+/*	Function Name: QueryGeometry.
+ *	Description: Returns the preferred geometry for this widget.
+ *	Arguments: w - the menu entry object.
+ *                 itended, return_val - the intended and return geometry info.
+ *	Returns: A Geometry Result.
+ *
+ * See the Intrinsics manual for details on what this function is for.
+ * 
+ * I just return the height and width of the label plus the margins.
+ */
+
+static XtGeometryResult
+QueryGeometry(w, intended, return_val) 
+Widget w;
+XtWidgetGeometry *intended, *return_val;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+    Dimension width, height;
+    XtGeometryResult ret_val = XtGeometryYes;
+    XtGeometryMask mode = intended->request_mode;
+
+    GetDefaultSize(w, &width, &height );    
+
+    if ( ((mode & CWWidth) && (intended->width != width)) ||
+	 !(mode & CWWidth) ) {
+	return_val->request_mode |= CWWidth;
+	return_val->width = width;
+	ret_val = XtGeometryAlmost;
+    }
+
+    if ( ((mode & CWHeight) && (intended->height != height)) ||
+	 !(mode & CWHeight) ) {
+	return_val->request_mode |= CWHeight;
+	return_val->height = height;
+	ret_val = XtGeometryAlmost;
+    }
+
+    if (ret_val == XtGeometryAlmost) {
+	mode = return_val->request_mode;
+	
+	if ( ((mode & CWWidth) && (width == entry->rectangle.width)) &&
+	     ((mode & CWHeight) && (height == entry->rectangle.height)) )
+	    return(XtGeometryNo);
+    }
+
+    return(ret_val);
+}
+    
+/*      Function Name: FlipColors
+ *      Description: Invert the colors of the current entry.
+ *      Arguments: w - the bsb menu entry widget.
+ *      Returns: none.
+ */
+
+static void 
+FlipColors(w)
+Widget w;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+
+    if (entry->sme_bsb.set_values_area_cleared || entry->sme_bsb.inactive) 
+	return;
+
+    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
+		   entry->sme_bsb.invert_gc, 0, (int) entry->rectangle.y,
+		   (unsigned int) entry->rectangle.width, 
+		   (unsigned int) entry->rectangle.height);
+}
+
+/************************************************************
+ *
+ * Private Functions.
+ *
+ ************************************************************/
+
+/*	Function Name: GetDefaultSize
+ *	Description: Calculates the Default (preferred) size of
+ *                   this menu entry.
+ *	Arguments: w - the menu entry widget.
+ *                 width, height - default sizes (RETURNED).
+ *	Returns: none.
+ */
+
+static void
+GetDefaultSize(w, width, height) 
+Widget w;
+Dimension * width, * height;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+
+    if (entry->sme_bsb.label == NULL) 
+	*width = 0;
+    else
+	*width = XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label,
+			    strlen(entry->sme_bsb.label));
+
+    *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
+    
+    *height = (entry->sme_bsb.font->max_bounds.ascent +
+	       entry->sme_bsb.font->max_bounds.descent);
+
+    *height = ((int)*height * ( ONE_HUNDRED + 
+			        entry->sme_bsb.vert_space )) / ONE_HUNDRED;
+}
+
+/*      Function Name: DrawBitmaps
+ *      Description: Draws left and right bitmaps.
+ *      Arguments: w - the simple menu widget.
+ *                 gc - graphics context to use for drawing.
+ *      Returns: none
+ */
+
+static void
+DrawBitmaps(w, gc)
+Widget w;
+GC gc;
+{
+    int x_loc, y_loc;
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+    
+    if ( (entry->sme_bsb.left_bitmap == None) && 
+	 (entry->sme_bsb.right_bitmap == None) ) return;
+
+/*
+ * Draw Left Bitmap.
+ */
+
+  if (entry->sme_bsb.left_bitmap != None) {
+    x_loc = (int)(entry->sme_bsb.left_margin -
+	          entry->sme_bsb.left_bitmap_width) / 2;
+
+    y_loc = entry->rectangle.y + (int)(entry->rectangle.height -
+				       entry->sme_bsb.left_bitmap_height) / 2;
+
+    XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.left_bitmap,
+	       XtWindowOfObject(w), gc, 0, 0, 
+	       entry->sme_bsb.left_bitmap_width,
+	       entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1);
+  }
+
+/*
+ * Draw Right Bitmap.
+ */
+
+
+  if (entry->sme_bsb.right_bitmap != None) {
+    x_loc = entry->rectangle.width -
+	      (int)(entry->sme_bsb.right_margin +
+		    entry->sme_bsb.right_bitmap_width) / 2;
+
+    y_loc = entry->rectangle.y + (int)(entry->rectangle.height -
+				       entry->sme_bsb.right_bitmap_height) / 2;
+
+    XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.right_bitmap,
+	       XtWindowOfObject(w), gc, 0, 0, 
+	       entry->sme_bsb.right_bitmap_width,
+	       entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1);
+  }
+}
+
+/*      Function Name: GetBitmapInfo
+ *      Description: Gets the bitmap information from either of the bitmaps.
+ *      Arguments: w - the bsb menu entry widget.
+ *                 is_left - TRUE if we are testing left bitmap,
+ *                           FALSE if we are testing the right bitmap.
+ *      Returns: none
+ */
+
+static void
+GetBitmapInfo(w, is_left)
+Widget w;
+Boolean is_left;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;    
+    unsigned int depth, bw;
+    Window root;
+    int x, y;
+    unsigned int width, height;
+    char buf[BUFSIZ];
+    
+    if (is_left) {
+	if (entry->sme_bsb.left_bitmap != None) {
+	    if (!XGetGeometry(XtDisplayOfObject(w), 
+			      entry->sme_bsb.left_bitmap, &root, 
+			      &x, &y, &width, &height, &bw, &depth)) {
+		sprintf(buf, "SmeMenuButton Object: %s %s \"%s\".", "Could not",
+			"get Left Bitmap geometry information for menu entry ",
+			XtName(w));
+		XtAppError(XtWidgetToApplicationContext(w), buf);
+	    }
+	    if (depth != 1) {
+		sprintf(buf, "SmeMenuButton Object: %s \"%s\"%s.", 
+			"Left Bitmap of entry ", 
+			XtName(w), " is not one bit deep.");
+		XtAppError(XtWidgetToApplicationContext(w), buf);
+	    }
+	    entry->sme_bsb.left_bitmap_width = (Dimension) width; 
+	    entry->sme_bsb.left_bitmap_height = (Dimension) height;
+	}
+    }
+    else if (entry->sme_bsb.right_bitmap != None) {
+	if (!XGetGeometry(XtDisplayOfObject(w),
+			  entry->sme_bsb.right_bitmap, &root,
+			  &x, &y, &width, &height, &bw, &depth)) {
+	    sprintf(buf, "SmeMenuButton Object: %s %s \"%s\".", "Could not",
+		    "get Right Bitmap geometry information for menu entry ",
+		    XtName(w));
+	    XtAppError(XtWidgetToApplicationContext(w), buf);
+	}
+	if (depth != 1) {
+	    sprintf(buf, "SmeMenuButton Object: %s \"%s\"%s.", 
+		    "Right Bitmap of entry ", XtName(w),
+		    " is not one bit deep.");
+	    XtAppError(XtWidgetToApplicationContext(w), buf);
+	}
+	entry->sme_bsb.right_bitmap_width = (Dimension) width; 
+	entry->sme_bsb.right_bitmap_height = (Dimension) height;
+    }
+}      
+
+/*      Function Name: CreateGCs
+ *      Description: Creates all gc's for the simple menu widget.
+ *      Arguments: w - the simple menu widget.
+ *      Returns: none.
+ */
+
+static void
+CreateGCs(w)
+Widget w;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;    
+    XGCValues values;
+    XtGCMask mask;
+    
+    values.foreground = XtParent(w)->core.background_pixel;
+    values.background = entry->sme_bsb.foreground;
+    values.font = entry->sme_bsb.font->fid;
+    values.graphics_exposures = FALSE;
+    mask        = GCForeground | GCBackground | GCFont | GCGraphicsExposures;
+    entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values);
+    
+    values.foreground = entry->sme_bsb.foreground;
+    values.background = XtParent(w)->core.background_pixel;
+    entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values);
+    
+    values.fill_style = FillTiled;
+    values.tile   = XmuCreateStippledPixmap(XtScreenOfObject(w), 
+					    entry->sme_bsb.foreground,
+					    XtParent(w)->core.background_pixel,
+					    XtParent(w)->core.depth);
+    values.graphics_exposures = FALSE;
+    mask |= GCTile | GCFillStyle;
+    entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values);
+    
+    values.foreground ^= values.background;
+    values.background = 0;
+    values.function = GXxor;
+    mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction;
+    entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values);
+}
+
+/*      Function Name: DestroyGCs
+ *      Description: Removes all gc's for the simple menu widget.
+ *      Arguments: w - the simple menu widget.
+ *      Returns: none.
+ */
+
+static void
+DestroyGCs(w)
+Widget w;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;    
+
+    XtReleaseGC(w, entry->sme_bsb.norm_gc);
+    XtReleaseGC(w, entry->sme_bsb.norm_gray_gc);
+    XtReleaseGC(w, entry->sme_bsb.rev_gc);
+    XtReleaseGC(w, entry->sme_bsb.invert_gc);
+}
+
+static void
+PopupMenu(w)
+Widget w;
+{
+  SmeMenuButtonObject mbw = (SmeMenuButtonObject) w;
+  Widget menu, temp;
+  Arg arglist[2];
+  Cardinal num_args;
+  int menu_x, menu_y, menu_width, menu_height, button_width;
+  Position button_x, button_y;
+
+  if (mbw->sme_bsb.menu_name == NULL || strlen(mbw->sme_bsb.menu_name) == 0)
+      return;
+
+  temp = w;
+  while(temp != NULL) {
+    menu = XtNameToWidget(temp, mbw->sme_bsb.menu_name);
+    if (menu == NULL) 
+      temp = XtParent(temp);
+    else
+      break;
+  }
+
+  if (menu == NULL) {
+    char error_buf[BUFSIZ];
+    sprintf(error_buf, "MenuButton: %s %s.",
+	    "Could not find menu widget named", mbw->sme_bsb.menu_name);
+    XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+    return;
+  }
+  if (!XtIsRealized(menu))
+    XtRealizeWidget(menu);
+  
+  menu_width = menu->core.width + 2 * menu->core.border_width;
+  button_width = mbw->rectangle.width + 2 * mbw->rectangle.border_width;
+  menu_height = menu->core.height + 2 * menu->core.border_width;
+
+  XtTranslateCoords(w, 0, 0, &button_x, &button_y);
+  menu_x = button_x + button_width;
+  menu_y = button_y;
+
+  if (menu_x >= 0) {
+    int scr_width = WidthOfScreen(XtScreen(menu));
+    if (menu_x + menu_width > scr_width)
+      menu_x = scr_width - menu_width;
+  }
+  if (menu_x < 0) 
+    menu_x = 0;
+
+  if (menu_y >= 0) {
+    int scr_height = HeightOfScreen(XtScreen(menu));
+    if (menu_y + menu_height > scr_height)
+      menu_y = scr_height - menu_height;
+  }
+  if (menu_y < 0)
+    menu_y = 0;
+
+  num_args = 0;
+  XtSetArg(arglist[num_args], XtNx, menu_x); num_args++;
+  XtSetArg(arglist[num_args], XtNy, menu_y); num_args++;
+  XtSetValues(menu, arglist, num_args);
+
+  XtPopupSpringLoaded(menu);
+}
+
+static void
+Unhighlight(w)
+Widget w;
+{
+    SmeMenuButtonObject mbw = (SmeMenuButtonObject) w;
+    Display  *display;
+    Screen   *screen;
+    Window   win, rootwin;
+    int      rootwin_x, rootwin_y;
+    int      win_x, win_y;
+    unsigned int mask;
+    Position left, right, top, bottom;
+
+    if (mbw->sme_bsb.inactive)
+	return;
+    
+    display = XtDisplayOfObject(w);
+    screen  = XtScreenOfObject(w);
+    XQueryPointer(display, RootWindowOfScreen(screen),
+                  &rootwin, &win, &rootwin_x, &rootwin_y,
+                  &win_x, &win_y, &mask);
+
+    XtTranslateCoords(w, 0, 0, &left, &top);
+    XtTranslateCoords(w, mbw->rectangle.width, mbw->rectangle.height, 
+		      &right, &bottom);
+
+    if (rootwin_x >= right && rootwin_y >= top && rootwin_y < bottom)
+    {
+	PopupMenu(w);
+    }
+
+    FlipColors(w);
+}
+
+static void
+RemoveAmpersand(w)
+Widget w;
+{
+    SmeMenuButtonObject entry = (SmeMenuButtonObject) w;
+
+    entry->sme_bsb.ul_pos = strcspn(entry->sme_bsb.label, "&");
+    if (entry->sme_bsb.ul_pos == strlen(entry->sme_bsb.label))
+    {
+	entry->sme_bsb.ul_pos = -1;
+	return;
+    }
+
+    /* Remove ampersand from label */
+    strcpy(entry->sme_bsb.label + entry->sme_bsb.ul_pos,
+	   entry->sme_bsb.label + entry->sme_bsb.ul_pos + 1);
+}
+
diff --git a/controls/SmeMenuButto.h b/controls/SmeMenuButto.h
new file mode 100644
index 0000000..72c9a51
--- /dev/null
+++ b/controls/SmeMenuButto.h
@@ -0,0 +1,100 @@
+/*
+ * $XConsortium: SmeMenuButton.h,v 1.5 89/12/11 15:20:14 kit Exp $
+ *
+ * Copyright 1989 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * SmeMenuButton.h - Public Header file for SmeMenuButton object.
+ *
+ * This is the public header file for the Athena BSB Sme object.
+ * It is intended to be used with the simple menu widget.  This object
+ * provides bitmap - string - bitmap style entries.
+ *
+ * Date:    April 3, 1989
+ *
+ * By:      Chris D. Peterson
+ *          MIT X Consortium 
+ *          kit@expo.lcs.mit.edu
+ *
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Added code to translate ampersand to underlined char
+ */
+
+#ifndef _SmeMenuButto_h
+#define _SmeMenuButto_h
+
+#include <X11/Xmu/Converters.h>
+
+#include <X11/Xaw/Sme.h>
+
+/****************************************************************
+ *
+ * SmeMenuButton object
+ *
+ ****************************************************************/
+
+/* BSB Menu Entry Resources:
+
+ Name		     Class		RepType		Default Value
+ ----		     -----		-------		-------------
+ callback            Callback           Callback        NULL
+ destroyCallback     Callback		Pointer		NULL
+ font                Font               XFontStruct *   XtDefaultFont
+ foreground          Foreground         Pixel           XtDefaultForeground
+ height		     Height		Dimension	0
+ label               Label              String          Name of entry
+ leftBitmap          LeftBitmap         Pixmap          None
+ leftMargin          HorizontalMargins  Dimension       4
+ rightBitmap         RightBitmap        Pixmap          None
+ rightMargin         HorizontalMargins  Dimension       4
+ sensitive	     Sensitive		Boolean		True
+ vertSpace           VertSpace          int             25
+ width		     Width		Dimension	0
+ x		     Position		Position	0n
+ y		     Position		Position	0
+ menuName            MenuName           String          "menu"
+ inactive	     Inactive		Boolean		False
+
+*/
+
+typedef struct _SmeMenuButtonClassRec    *SmeMenuButtonObjectClass;
+typedef struct _SmeMenuButtonRec         *SmeMenuButtonObject;
+
+extern WidgetClass smeMenuButtonObjectClass;
+
+#define XtNleftBitmap "leftBitmap"
+#define XtNleftMargin "leftMargin"
+#define XtNrightBitmap "rightBitmap"
+#define XtNrightMargin "rightMargin"
+#define XtNvertSpace   "vertSpace"
+#define XtNmenuName "menuName"
+#define XtNinactive "inactive"
+
+#define XtCLeftBitmap "LeftBitmap"
+#define XtCHorizontalMargins "HorizontalMargins"
+#define XtCRightBitmap "RightBitmap"
+#define XtCVertSpace   "VertSpace"
+#define XtCMenuName "MenuName"
+#define XtCInactive "Inactive"
+
+#endif /* _SmeMenuButto_h */
diff --git a/controls/WinCommand.c b/controls/WinCommand.c
new file mode 100644
index 0000000..e05da8e
--- /dev/null
+++ b/controls/WinCommand.c
@@ -0,0 +1,567 @@
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Modifications for Wine
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinCommand
+ */
+
+/*
+ * WinCommand.c - WinCommand button widget
+ */
+
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xaw/XawInit.h>
+#include "WinCommandP.h"
+#include <X11/Xmu/Converters.h>
+
+#define DEFAULT_HIGHLIGHT_THICKNESS 2
+#define DEFAULT_SHAPE_HIGHLIGHT 32767
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+static char defaultTranslations[] =
+    "<EnterWindow>:	highlight()		\n\
+     <LeaveWindow>:	reset()			\n\
+     <Btn1Down>:	set()			\n\
+     <Btn1Up>:		notify() unset()	";
+
+#define offset(field) XtOffsetOf(WinCommandRec, field)
+static XtResource resources[] = { 
+   {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), 
+      offset(wincommand.callbacks), XtRCallback, (XtPointer)NULL},
+   {XtNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension),
+      offset(wincommand.highlight_thickness), XtRImmediate,
+      (XtPointer) DEFAULT_SHAPE_HIGHLIGHT},
+   {XtNshapeStyle, XtCShapeStyle, XtRShapeStyle, sizeof(int),
+      offset(wincommand.shape_style), XtRImmediate, 
+	    (XtPointer)XawShapeRectangle},
+   {XtNcornerRoundPercent, XtCCornerRoundPercent, 
+	XtRDimension, sizeof(Dimension),
+	offset(wincommand.corner_round), XtRImmediate, (XtPointer) 25},
+};
+#undef offset
+
+static Boolean SetValues();
+static void Initialize(), Redisplay(), Set(), Reset(), Notify(), Unset();
+static void Highlight(), Unhighlight(), Destroy(), PaintWinCommandWidget();
+static void ClassInitialize();
+static Boolean ShapeButton();
+static void Realize(), Resize();
+
+static XtActionsRec actionsList[] = {
+  {"set",		Set},
+  {"notify",		Notify},
+  {"highlight",		Highlight},
+  {"reset",		Reset},
+  {"unset",		Unset},
+  {"unhighlight",	Unhighlight}
+};
+
+#define SuperClass ((WinLabelWidgetClass)&winLabelClassRec)
+
+WinCommandClassRec winCommandClassRec = {
+  {
+    (WidgetClass) SuperClass,		/* superclass		  */	
+    "WinCommand",			/* class_name		  */
+    sizeof(WinCommandRec),		/* size			  */
+    ClassInitialize,			/* class_initialize	  */
+    NULL,				/* class_part_initialize  */
+    FALSE,				/* class_inited		  */
+    Initialize,				/* initialize		  */
+    NULL,				/* initialize_hook	  */
+    Realize,				/* realize		  */
+    actionsList,			/* actions		  */
+    XtNumber(actionsList),		/* num_actions		  */
+    resources,				/* resources		  */
+    XtNumber(resources),		/* resource_count	  */
+    NULLQUARK,				/* xrm_class		  */
+    FALSE,				/* compress_motion	  */
+    TRUE,				/* compress_exposure	  */
+    TRUE,				/* compress_enterleave    */
+    FALSE,				/* visible_interest	  */
+    Destroy,				/* destroy		  */
+    Resize,				/* resize		  */
+    Redisplay,				/* expose		  */
+    SetValues,				/* set_values		  */
+    NULL,				/* set_values_hook	  */
+    XtInheritSetValuesAlmost,		/* set_values_almost	  */
+    NULL,				/* get_values_hook	  */
+    NULL,				/* accept_focus		  */
+    XtVersion,				/* version		  */
+    NULL,				/* callback_private	  */
+    defaultTranslations,		/* tm_table		  */
+    XtInheritQueryGeometry,		/* query_geometry	  */
+    XtInheritDisplayAccelerator,	/* display_accelerator	  */
+    NULL				/* extension		  */
+  },  /* CoreClass fields initialization */
+  {
+    XtInheritChangeSensitive		/* change_sensitive	*/
+  },  /* SimpleClass fields initialization */
+  {
+    0,                                     /* field not used    */
+  },  /* WinLabelClass fields initialization */
+  {
+    0,                                     /* field not used    */
+  },  /* WinCommandClass fields initialization */
+};
+
+  /* for public consumption */
+WidgetClass winCommandWidgetClass = (WidgetClass) &winCommandClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static GC 
+Get_GC(cbw, fg, bg)
+WinCommandWidget cbw;
+Pixel fg, bg;
+{
+  XGCValues	values;
+  
+  values.foreground   = fg;
+  values.background	= bg;
+  values.font		= cbw->winlabel.font->fid;
+  values.cap_style = CapProjecting;
+  
+  if (cbw->wincommand.highlight_thickness > 1 )
+    values.line_width   = cbw->wincommand.highlight_thickness;
+  else 
+    values.line_width   = 0;
+  
+  return XtGetGC((Widget)cbw,
+		 (GCForeground|GCBackground|GCFont|GCLineWidth|GCCapStyle),
+		 &values);
+}
+
+
+/* ARGSUSED */
+static void 
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;			/* unused */
+Cardinal *num_args;		/* unused */
+{
+  WinCommandWidget cbw = (WinCommandWidget) new;
+  int shape_event_base, shape_error_base;
+
+  if (cbw->wincommand.shape_style != XawShapeRectangle
+      && !XShapeQueryExtension(XtDisplay(new), &shape_event_base, 
+			       &shape_error_base))
+      cbw->wincommand.shape_style = XawShapeRectangle;
+  if (cbw->wincommand.highlight_thickness == DEFAULT_SHAPE_HIGHLIGHT) {
+      if (cbw->wincommand.shape_style != XawShapeRectangle)
+	  cbw->wincommand.highlight_thickness = 0;
+      else
+	  cbw->wincommand.highlight_thickness = DEFAULT_HIGHLIGHT_THICKNESS;
+  }
+
+  cbw->wincommand.normal_GC = Get_GC(cbw, cbw->winlabel.foreground, 
+				  cbw->core.background_pixel);
+  cbw->wincommand.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, 
+				   cbw->winlabel.foreground);
+  XtReleaseGC(new, cbw->winlabel.normal_GC);
+  cbw->winlabel.normal_GC = cbw->wincommand.normal_GC;
+
+  cbw->wincommand.set = FALSE;
+  cbw->wincommand.highlighted = HighlightNone;
+}
+
+static Region 
+HighlightRegion(cbw)
+WinCommandWidget cbw;
+{
+  static Region outerRegion = NULL, innerRegion, emptyRegion;
+  XRectangle rect;
+
+  if (cbw->wincommand.highlight_thickness == 0 ||
+      cbw->wincommand.highlight_thickness >
+      (Dimension) ((Dimension) Min(cbw->core.width, cbw->core.height)/2))
+    return(NULL);
+
+  if (outerRegion == NULL) {
+    /* save time by allocating scratch regions only once. */
+    outerRegion = XCreateRegion();
+    innerRegion = XCreateRegion();
+    emptyRegion = XCreateRegion();
+  }
+
+  rect.x = rect.y = 0;
+  rect.width = cbw->core.width;
+  rect.height = cbw->core.height;
+  XUnionRectWithRegion( &rect, emptyRegion, outerRegion );
+  rect.x = rect.y = cbw->wincommand.highlight_thickness;
+  rect.width -= cbw->wincommand.highlight_thickness * 2;
+  rect.height -= cbw->wincommand.highlight_thickness * 2;
+  XUnionRectWithRegion( &rect, emptyRegion, innerRegion );
+  XSubtractRegion( outerRegion, innerRegion, outerRegion );
+  return outerRegion;
+}
+
+/***************************
+*
+*  Action Procedures
+*
+***************************/
+
+/* ARGSUSED */
+static void 
+Set(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;		/* unused */
+Cardinal *num_params;	/* unused */
+{
+  WinCommandWidget cbw = (WinCommandWidget)w;
+
+  if (cbw->wincommand.set)
+    return;
+
+  cbw->wincommand.set= TRUE;
+  if (XtIsRealized(w))
+    PaintWinCommandWidget(w, (Region) NULL, TRUE);
+}
+
+/* ARGSUSED */
+static void
+Unset(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;		/* unused */
+Cardinal *num_params;
+{
+  WinCommandWidget cbw = (WinCommandWidget)w;
+
+  if (!cbw->wincommand.set)
+    return;
+
+  cbw->wincommand.set = FALSE;
+  if (XtIsRealized(w)) {
+    XClearWindow(XtDisplay(w), XtWindow(w));
+    PaintWinCommandWidget(w, (Region) NULL, TRUE);
+  }
+}
+
+/* ARGSUSED */
+static void 
+Reset(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;		/* unused */
+Cardinal *num_params;   /* unused */
+{
+  WinCommandWidget cbw = (WinCommandWidget)w;
+
+  if (cbw->wincommand.set) {
+    cbw->wincommand.highlighted = HighlightNone;
+    Unset(w, event, params, num_params);
+  }
+  else
+    Unhighlight(w, event, params, num_params);
+}
+
+/* ARGSUSED */
+static void 
+Highlight(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;		
+Cardinal *num_params;	
+{
+  WinCommandWidget cbw = (WinCommandWidget)w;
+
+  if ( *num_params == (Cardinal) 0) 
+    cbw->wincommand.highlighted = HighlightWhenUnset;
+  else {
+    if ( *num_params != (Cardinal) 1) 
+      XtWarning("Too many parameters passed to highlight action table.");
+    switch (params[0][0]) {
+    case 'A':
+    case 'a':
+      cbw->wincommand.highlighted = HighlightAlways;
+      break;
+    default:
+      cbw->wincommand.highlighted = HighlightWhenUnset;
+      break;
+    }
+  }
+
+  if (XtIsRealized(w))
+    PaintWinCommandWidget(w, HighlightRegion(cbw), TRUE);
+}
+
+/* ARGSUSED */
+static void 
+Unhighlight(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;		/* unused */
+Cardinal *num_params;	/* unused */
+{
+  WinCommandWidget cbw = (WinCommandWidget)w;
+
+  cbw->wincommand.highlighted = HighlightNone;
+  if (XtIsRealized(w))
+    PaintWinCommandWidget(w, HighlightRegion(cbw), TRUE);
+}
+
+/* ARGSUSED */
+static void 
+Notify(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;		/* unused */
+Cardinal *num_params;	/* unused */
+{
+  WinCommandWidget cbw = (WinCommandWidget)w; 
+
+  /* check to be sure state is still Set so that user can cancel
+     the action (e.g. by moving outside the window, in the default
+     bindings.
+  */
+  if (cbw->wincommand.set)
+    XtCallCallbackList(w, cbw->wincommand.callbacks, NULL);
+}
+
+/*
+ * Repaint the widget window
+ */
+
+/************************
+*
+*  REDISPLAY (DRAW)
+*
+************************/
+
+/* ARGSUSED */
+static void 
+Redisplay(w, event, region)
+Widget w;
+XEvent *event;
+Region region;
+{
+  PaintWinCommandWidget(w, region, FALSE);
+}
+
+/*	Function Name: PaintWinCommandWidget
+ *	Description: Paints the wincommand widget.
+ *	Arguments: w - the wincommand widget.
+ *                 region - region to paint (passed to the superclass).
+ *                 change - did it change either set or highlight state?
+ *	Returns: none
+ */
+
+static void 
+PaintWinCommandWidget(w, region, change)
+Widget w;
+Region region;
+Boolean change;
+{
+  WinCommandWidget cbw = (WinCommandWidget) w;
+  Boolean very_thick;
+  GC norm_gc, rev_gc;
+   
+  very_thick = cbw->wincommand.highlight_thickness >
+               (Dimension)((Dimension) Min(cbw->core.width, 
+					   cbw->core.height)/2);
+
+  if (cbw->wincommand.set) {
+    cbw->winlabel.normal_GC = cbw->wincommand.inverse_GC;
+    XFillRectangle(XtDisplay(w), XtWindow(w), cbw->wincommand.normal_GC,
+		   0, 0, cbw->core.width, cbw->core.height);
+    region = NULL;		/* Force label to repaint text. */
+  }
+  else
+      cbw->winlabel.normal_GC = cbw->wincommand.normal_GC;
+
+  if (cbw->wincommand.highlight_thickness <= 0)
+  {
+    (*SuperClass->core_class.expose) (w, (XEvent *) NULL, region);
+    return;
+  }
+
+/*
+ * If we are set then use the same colors as if we are not highlighted. 
+ */
+
+  if (cbw->wincommand.set == (cbw->wincommand.highlighted == HighlightNone)) {
+    norm_gc = cbw->wincommand.inverse_GC;
+    rev_gc = cbw->wincommand.normal_GC;
+  }
+  else {
+    norm_gc = cbw->wincommand.normal_GC;
+    rev_gc = cbw->wincommand.inverse_GC;
+  }
+
+  if ( !( (!change && (cbw->wincommand.highlighted == HighlightNone)) ||
+	  ((cbw->wincommand.highlighted == HighlightWhenUnset) &&
+	   (cbw->wincommand.set))) ) {
+    if (very_thick) {
+      cbw->winlabel.normal_GC = norm_gc; /* Give the label the right GC. */
+      XFillRectangle(XtDisplay(w),XtWindow(w), rev_gc,
+		     0, 0, cbw->core.width, cbw->core.height);
+    }
+    else {
+      /* wide lines are centered on the path, so indent it */
+      int offset = cbw->wincommand.highlight_thickness/2;
+      XDrawRectangle(XtDisplay(w),XtWindow(w), rev_gc, offset, offset, 
+		     cbw->core.width - cbw->wincommand.highlight_thickness,
+		     cbw->core.height - cbw->wincommand.highlight_thickness);
+    }
+  }
+  (*SuperClass->core_class.expose) (w, (XEvent *) NULL, region);
+}
+
+static void 
+Destroy(w)
+Widget w;
+{
+  WinCommandWidget cbw = (WinCommandWidget) w;
+
+  /* so WinLabel can release it */
+  if (cbw->winlabel.normal_GC == cbw->wincommand.normal_GC)
+    XtReleaseGC( w, cbw->wincommand.inverse_GC );
+  else
+    XtReleaseGC( w, cbw->wincommand.normal_GC );
+}
+
+/*
+ * Set specified arguments into widget
+ */
+
+/* ARGSUSED */
+static Boolean 
+SetValues (current, request, new)
+Widget current, request, new;
+{
+  WinCommandWidget oldcbw = (WinCommandWidget) current;
+  WinCommandWidget cbw = (WinCommandWidget) new;
+  Boolean redisplay = False;
+
+  if ( oldcbw->core.sensitive != cbw->core.sensitive && !cbw->core.sensitive) {
+    /* about to become insensitive */
+    cbw->wincommand.set = FALSE;
+    cbw->wincommand.highlighted = HighlightNone;
+    redisplay = TRUE;
+  }
+  
+  if ( (oldcbw->winlabel.foreground != cbw->winlabel.foreground)           ||
+       (oldcbw->core.background_pixel != cbw->core.background_pixel) ||
+       (oldcbw->wincommand.highlight_thickness != 
+                                   cbw->wincommand.highlight_thickness) ||
+       (oldcbw->winlabel.font != cbw->winlabel.font) ) 
+  {
+    if (oldcbw->winlabel.normal_GC == oldcbw->wincommand.normal_GC)
+	/* WinLabel has release one of these */
+      XtReleaseGC(new, cbw->wincommand.inverse_GC);
+    else
+      XtReleaseGC(new, cbw->wincommand.normal_GC);
+
+    cbw->wincommand.normal_GC = Get_GC(cbw, cbw->winlabel.foreground, 
+				    cbw->core.background_pixel);
+    cbw->wincommand.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, 
+				     cbw->winlabel.foreground);
+    XtReleaseGC(new, cbw->winlabel.normal_GC);
+    cbw->winlabel.normal_GC = (cbw->wincommand.set
+			    ? cbw->wincommand.inverse_GC
+			    : cbw->wincommand.normal_GC);
+    
+    redisplay = True;
+  }
+
+  if ( XtIsRealized(new)
+       && oldcbw->wincommand.shape_style != cbw->wincommand.shape_style
+       && !ShapeButton(cbw, TRUE))
+  {
+      cbw->wincommand.shape_style = oldcbw->wincommand.shape_style;
+  }
+
+  return (redisplay);
+}
+
+static void ClassInitialize()
+{
+    XawInitializeWidgetSet();
+    XtSetTypeConverter( XtRString, XtRShapeStyle, XmuCvtStringToShapeStyle,
+		        NULL, 0, XtCacheNone, NULL );
+}
+
+
+static Boolean
+ShapeButton(cbw, checkRectangular)
+WinCommandWidget cbw;
+Boolean checkRectangular;
+{
+    Dimension corner_size;
+
+    if ( (cbw->wincommand.shape_style == XawShapeRoundedRectangle) ) {
+	corner_size = (cbw->core.width < cbw->core.height) ? cbw->core.width 
+	                                                   : cbw->core.height;
+	corner_size = (int) (corner_size * cbw->wincommand.corner_round) / 100;
+    }
+
+    if (checkRectangular || cbw->wincommand.shape_style != XawShapeRectangle) {
+	if (!XmuReshapeWidget((Widget) cbw, cbw->wincommand.shape_style,
+			      corner_size, corner_size)) {
+	    cbw->wincommand.shape_style = XawShapeRectangle;
+	    return(False);
+	}
+    }
+    return(TRUE);
+}
+
+static void Realize(w, valueMask, attributes)
+    Widget w;
+    Mask *valueMask;
+    XSetWindowAttributes *attributes;
+{
+    (*winCommandWidgetClass->core_class.superclass->core_class.realize)
+	(w, valueMask, attributes);
+
+    ShapeButton( (WinCommandWidget) w, FALSE);
+}
+
+static void Resize(w)
+    Widget w;
+{
+    if (XtIsRealized(w)) 
+	ShapeButton( (WinCommandWidget) w, FALSE);
+
+    (*winCommandWidgetClass->core_class.superclass->core_class.resize)(w);
+}
+
diff --git a/controls/WinCommand.h b/controls/WinCommand.h
new file mode 100644
index 0000000..0b69e06
--- /dev/null
+++ b/controls/WinCommand.h
@@ -0,0 +1,100 @@
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Modifications for Wine
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinCommand
+ */
+
+#ifndef _WinCommand_h
+#define _WinCommand_h
+
+#include "WinLabel.h"
+
+/* Command widget resources:
+
+ Name		     Class		RepType		Default Value
+ ----		     -----		-------		-------------
+ accelerators	     Accelerators	AcceleratorTable NULL
+ ancestorSensitive   AncestorSensitive	Boolean		True
+ background	     Background		Pixel		XtDefaultBackground
+ backgroundPixmap    Pixmap		Pixmap		XtUnspecifiedPixmap
+ bitmap		     Pixmap		Pixmap		None
+ borderColor	     BorderColor	Pixel		XtDefaultForeground
+ borderPixmap	     Pixmap		Pixmap		XtUnspecifiedPixmap
+ borderWidth	     BorderWidth	Dimension	1
+ callback	     Callback		XtCallbackList	NULL
+ colormap	     Colormap		Colormap	parent's colormap
+ cornerRoundPercent  CornerRoundPercent	Dimension	25
+ cursor		     Cursor		Cursor		None
+ cursorName	     Cursor		String		NULL
+ depth		     Depth		int		parent's depth
+ destroyCallback     Callback		XtCallbackList	NULL
+ encoding	     Encoding		UnsignedChar	XawTextEncoding8bit
+ font		     Font		XFontStruct*	XtDefaultFont
+ foreground	     Foreground		Pixel		XtDefaultForeground
+ height		     Height		Dimension	text height
+ highlightThickness  Thickness		Dimension	0 if shaped, else 2
+ insensitiveBorder   Insensitive	Pixmap		Gray
+ internalHeight	     Height		Dimension	2
+ internalWidth	     Width		Dimension	4
+ justify	     Justify		XtJustify	XtJustifyCenter
+ label		     Label		String		NULL
+ leftBitmap	     LeftBitmap		Pixmap		None
+ mappedWhenManaged   MappedWhenManaged	Boolean		True
+ pointerColor	     Foreground		Pixel		XtDefaultForeground
+ pointerColorBackground Background	Pixel		XtDefaultBackground
+ resize		     Resize		Boolean		True
+ screen		     Screen		Screen		parent's Screen
+ sensitive	     Sensitive		Boolean		True
+ shapeStyle	     ShapeStyle		ShapeStyle	Rectangle
+ translations	     Translations	TranslationTable see doc or source
+ width		     Width		Dimension	text width
+ x		     Position		Position	0
+ y		     Position		Position	0
+
+*/
+
+#define XtNhighlightThickness "highlightThickness"
+
+#define XtNshapeStyle "shapeStyle"
+#define XtCShapeStyle "ShapeStyle"
+#define XtRShapeStyle "ShapeStyle"
+#define XtNcornerRoundPercent "cornerRoundPercent"
+#define XtCCornerRoundPercent "CornerRoundPercent"
+
+#define XawShapeRectangle XmuShapeRectangle
+#define XawShapeOval XmuShapeOval
+#define XawShapeEllipse XmuShapeEllipse
+#define XawShapeRoundedRectangle XmuShapeRoundedRectangle
+
+extern WidgetClass     winCommandWidgetClass;
+
+typedef struct _WinCommandClassRec   *WinCommandWidgetClass;
+typedef struct _WinCommandRec        *WinCommandWidget;
+
+#endif /* _WinCommand_h */
+/* DON'T ADD STUFF AFTER THIS */
diff --git a/controls/WinCommandP.h b/controls/WinCommandP.h
new file mode 100644
index 0000000..5f79931
--- /dev/null
+++ b/controls/WinCommandP.h
@@ -0,0 +1,118 @@
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Modifications for Wine
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Convrted to WinCommand
+ */
+
+/* 
+ * WinCommandP.h - Private definitions for WinCommand widget
+ * 
+ */
+
+#ifndef _WinCommandP_h
+#define _WinCommandP_h
+
+#include "WinCommand.h"
+#include "WinLabelP.h"
+
+/***********************************************************************
+ *
+ * WinCommand Widget Private Data
+ *
+ ***********************************************************************/
+
+typedef enum {
+  HighlightNone,		/* Do not highlight. */
+  HighlightWhenUnset,		/* Highlight only when unset, this is
+				   to preserve current command widget 
+				   functionality. */
+  HighlightAlways		/* Always highlight, lets the toggle widget
+				   and other subclasses do the right thing. */
+} XtCommandHighlight;
+
+/************************************
+ *
+ *  Class structure
+ *
+ ***********************************/
+
+
+   /* New fields for the WinCommand widget class record */
+typedef struct _WinCommandClass 
+  {
+    int makes_compiler_happy;  /* not used */
+  } WinCommandClassPart;
+
+   /* Full class record declaration */
+typedef struct _WinCommandClassRec {
+    CoreClassPart	core_class;
+    SimpleClassPart	simple_class;
+    WinLabelClassPart	winlabel_class;
+    WinCommandClassPart wincommand_class;
+} WinCommandClassRec;
+
+extern WinCommandClassRec winCommandClassRec;
+
+/***************************************
+ *
+ *  Instance (widget) structure 
+ *
+ **************************************/
+
+    /* New fields for the WinCommand widget record */
+typedef struct {
+    /* resources */
+    Dimension   highlight_thickness;
+    XtCallbackList callbacks;
+
+    /* private state */
+    Pixmap      	gray_pixmap;
+    GC          	normal_GC;
+    GC          	inverse_GC;
+    Boolean     	set;
+    XtCommandHighlight	highlighted;
+    /* more resources */
+    int			shape_style;    
+    Dimension		corner_round;
+} WinCommandPart;
+
+
+/*    XtEventsPtr eventTable;*/
+
+
+   /* Full widget declaration */
+typedef struct _WinCommandRec {
+    CorePart         core;
+    SimplePart	     simple;
+    WinLabelPart     winlabel;
+    WinCommandPart   wincommand;
+} WinCommandRec;
+
+#endif /* _WinCommandP_h */
+
+
diff --git a/controls/WinLabel.c b/controls/WinLabel.c
new file mode 100644
index 0000000..f079ed7
--- /dev/null
+++ b/controls/WinLabel.c
@@ -0,0 +1,691 @@
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Added code to translate ampersand to underlined char
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinLabel
+ */
+
+/*
+ * WinLabel.c - WinLabel widget
+ *
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xaw/XawInit.h>
+#include "WinLabelP.h"
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/Drawing.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define streq(a,b) (strcmp( (a), (b) ) == 0)
+
+#define MULTI_LINE_LABEL 32767
+
+#ifdef CRAY
+#define WORD64
+#endif
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+#define offset(field) XtOffsetOf(WinLabelRec, field)
+static XtResource resources[] = {
+    {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+        offset(winlabel.foreground), XtRString, XtDefaultForeground},
+    {XtNfont,  XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+        offset(winlabel.font),XtRString, XtDefaultFont},
+    {XtNlabel,  XtCLabel, XtRString, sizeof(String),
+        offset(winlabel.label), XtRString, NULL},
+    {XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char),
+        offset(winlabel.encoding), XtRImmediate, 
+	                             (XtPointer)XawTextEncoding8bit},
+    {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
+	offset(winlabel.justify), XtRImmediate, (XtPointer)XtJustifyCenter},
+    {XtNinternalWidth, XtCWidth, XtRDimension,  sizeof(Dimension),
+	offset(winlabel.internal_width), XtRImmediate, (XtPointer)4},
+    {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
+	offset(winlabel.internal_height), XtRImmediate, (XtPointer)4},
+    {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap),
+       offset(winlabel.left_bitmap), XtRImmediate, (XtPointer) None},
+    {XtNbitmap, XtCPixmap, XtRBitmap, sizeof(Pixmap),
+	offset(winlabel.pixmap), XtRImmediate, (XtPointer)None},
+    {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean),
+	offset(winlabel.resize), XtRImmediate, (XtPointer)True},
+};
+#undef offset
+
+static void Initialize();
+static void Resize();
+static void Redisplay();
+static Boolean SetValues();
+static void ClassInitialize();
+static void Destroy();
+static XtGeometryResult QueryGeometry();
+
+WinLabelClassRec winLabelClassRec = {
+  {
+/* core_class fields */	
+#define superclass		(&simpleClassRec)
+    /* superclass	  	*/	(WidgetClass) superclass,
+    /* class_name	  	*/	"WinLabel",
+    /* widget_size	  	*/	sizeof(WinLabelRec),
+    /* class_initialize   	*/	ClassInitialize,
+    /* class_part_initialize	*/	NULL,
+    /* class_inited       	*/	FALSE,
+    /* initialize	  	*/	Initialize,
+    /* initialize_hook		*/	NULL,
+    /* realize		  	*/	XtInheritRealize,
+    /* actions		  	*/	NULL,
+    /* num_actions	  	*/	0,
+    /* resources	  	*/	resources,
+    /* num_resources	  	*/	XtNumber(resources),
+    /* xrm_class	  	*/	NULLQUARK,
+    /* compress_motion	  	*/	TRUE,
+    /* compress_exposure  	*/	TRUE,
+    /* compress_enterleave	*/	TRUE,
+    /* visible_interest	  	*/	FALSE,
+    /* destroy		  	*/	Destroy,
+    /* resize		  	*/	Resize,
+    /* expose		  	*/	Redisplay,
+    /* set_values	  	*/	SetValues,
+    /* set_values_hook		*/	NULL,
+    /* set_values_almost	*/	XtInheritSetValuesAlmost,
+    /* get_values_hook		*/	NULL,
+    /* accept_focus	 	*/	NULL,
+    /* version			*/	XtVersion,
+    /* callback_private   	*/	NULL,
+    /* tm_table		   	*/	NULL,
+    /* query_geometry		*/	QueryGeometry,
+    /* display_accelerator	*/	XtInheritDisplayAccelerator,
+    /* extension		*/	NULL
+  },
+/* Simple class fields initialization */
+  {
+    /* change_sensitive		*/	XtInheritChangeSensitive
+  }
+};
+WidgetClass winLabelWidgetClass = (WidgetClass)&winLabelClassRec;
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void ClassInitialize()
+{
+    XawInitializeWidgetSet();
+    XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, NULL, 0 );
+}
+
+#ifndef WORD64
+
+#define TXT16 XChar2b
+
+#else
+
+#define TXT16 char
+
+static XChar2b *buf2b;
+static int buf2blen = 0;
+
+_WinLabelWidth16(fs, str, n)
+    XFontStruct *fs;
+    char *str;
+    int	n;
+{
+    int i;
+    XChar2b *ptr;
+
+    if (n > buf2blen) {
+	buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
+	buf2blen = n;
+    }
+    for (ptr = buf2b, i = n; --i >= 0; ptr++) {
+	ptr->byte1 = *str++;
+	ptr->byte2 = *str++;
+    }
+    return XTextWidth16(fs, buf2b, n);
+}
+
+_WinLabelDraw16(dpy, d, gc, x, y, str, n)
+    Display *dpy;
+    Drawable d;
+    GC gc;
+    int x, y;
+    char *str;
+    int n;
+{
+    int i;
+    XChar2b *ptr;
+
+    if (n > buf2blen) {
+	buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
+	buf2blen = n;
+    }
+    for (ptr = buf2b, i = n; --i >= 0; ptr++) {
+	ptr->byte1 = *str++;
+	ptr->byte2 = *str++;
+    }
+    XDrawString16(dpy, d, gc, x, y, buf2b, n);
+}
+
+#define XTextWidth16 _WinLabelWidth16
+#define XDrawString16 _WinLabelDraw16
+
+#endif /* WORD64 */
+
+/*
+ * Calculate width and height of displayed text in pixels
+ */
+
+static void SetTextWidthAndHeight(lw)
+    WinLabelWidget lw;
+{
+    register XFontStruct	*fs = lw->winlabel.font;
+    char *nl;
+
+    if (lw->winlabel.pixmap != None) {
+	Window root;
+	int x, y;
+	unsigned int width, height, bw, depth;
+	if (XGetGeometry(XtDisplay(lw), lw->winlabel.pixmap, &root, &x, &y,
+			 &width, &height, &bw, &depth)) {
+	    lw->winlabel.label_height = height;
+	    lw->winlabel.label_width = width;
+	    lw->winlabel.label_len = depth;
+	    return;
+	}
+    }
+
+    lw->winlabel.label_height = fs->max_bounds.ascent + fs->max_bounds.descent;
+    if (lw->winlabel.label == NULL) {
+	lw->winlabel.label_len = 0;
+	lw->winlabel.label_width = 0;
+    }
+    else if ((nl = index(lw->winlabel.label, '\n')) != NULL) {
+	char *label;
+	lw->winlabel.label_len = MULTI_LINE_LABEL;
+	lw->winlabel.label_width = 0;
+	for (label = lw->winlabel.label; nl != NULL; nl = index(label, '\n')) {
+	    int width;
+
+	    if (lw->winlabel.encoding)
+		width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label)/2);
+	    else
+		width = XTextWidth(fs, label, (int)(nl - label));
+	    if (width > (int)lw->winlabel.label_width)
+		lw->winlabel.label_width = width;
+	    label = nl + 1;
+	    if (*label)
+		lw->winlabel.label_height +=
+		    fs->max_bounds.ascent + fs->max_bounds.descent;
+	}
+	if (*label) {
+	    int width = XTextWidth(fs, label, strlen(label));
+
+	    if (lw->winlabel.encoding)
+		width = XTextWidth16(fs, (TXT16*)label, (int)strlen(label)/2);
+	    else
+		width = XTextWidth(fs, label, strlen(label));
+	    if (width > (int) lw->winlabel.label_width)
+		lw->winlabel.label_width = width;
+	}
+    } else {
+	lw->winlabel.label_len = strlen(lw->winlabel.label);
+	if (lw->winlabel.encoding)
+	    lw->winlabel.label_width =
+		XTextWidth16(fs, (TXT16*)lw->winlabel.label,
+			     (int) lw->winlabel.label_len/2);
+	else
+	    lw->winlabel.label_width =
+		XTextWidth(fs, lw->winlabel.label, 
+			   (int) lw->winlabel.label_len);
+    }
+}
+
+static void GetnormalGC(lw)
+    WinLabelWidget lw;
+{
+    XGCValues	values;
+
+    values.foreground	= lw->winlabel.foreground;
+    values.background	= lw->core.background_pixel;
+    values.font		= lw->winlabel.font->fid;
+    values.graphics_exposures = False;
+
+    lw->winlabel.normal_GC = XtGetGC(
+	(Widget)lw,
+	(unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures,
+	&values);
+}
+
+static void GetgrayGC(lw)
+    WinLabelWidget lw;
+{
+    XGCValues	values;
+
+    values.foreground = lw->winlabel.foreground;
+    values.background = lw->core.background_pixel;
+    values.font	      = lw->winlabel.font->fid;
+    values.fill_style = FillTiled;
+    values.tile       = XmuCreateStippledPixmap(XtScreen((Widget)lw),
+						lw->winlabel.foreground, 
+						lw->core.background_pixel,
+						lw->core.depth);
+    values.graphics_exposures = False;
+
+    lw->winlabel.stipple = values.tile;
+    lw->winlabel.gray_GC = XtGetGC((Widget)lw, 
+				(unsigned) GCForeground | GCBackground |
+					   GCFont | GCTile | GCFillStyle |
+					   GCGraphicsExposures,
+				&values);
+}
+
+static void compute_bitmap_offsets (lw)
+    WinLabelWidget lw;
+{
+    /*
+     * label will be displayed at (internal_width, internal_height + lbm_y)
+     */
+    if (lw->winlabel.lbm_height != 0) {
+	lw->winlabel.lbm_y = (((int) lw->core.height) -
+			   ((int) lw->winlabel.internal_height * 2) -
+			   ((int) lw->winlabel.lbm_height)) / 2;
+    } else {
+	lw->winlabel.lbm_y = 0;
+    }
+}
+
+
+static void set_bitmap_info (lw)
+    WinLabelWidget lw;
+{
+    Window root;
+    int x, y;
+    unsigned int bw, depth;
+
+    if (!(lw->winlabel.left_bitmap &&
+	  XGetGeometry (XtDisplay(lw), lw->winlabel.left_bitmap, &root, &x, &y,
+			&lw->winlabel.lbm_width, &lw->winlabel.lbm_height,
+			&bw, &depth))) {
+	lw->winlabel.lbm_width = lw->winlabel.lbm_height = 0;
+    }
+    compute_bitmap_offsets (lw);
+}
+
+static void
+RemoveAmpersand(w)
+Widget w;
+{
+    WinLabelWidget lw = (WinLabelWidget) w;
+
+    lw->winlabel.ul_pos = strcspn(lw->winlabel.label, "&");
+    if (lw->winlabel.ul_pos == strlen(lw->winlabel.label))
+    {
+	lw->winlabel.ul_pos = -1;
+	return;
+    }
+
+    /* Remove ampersand from label */
+    strcpy(lw->winlabel.label + lw->winlabel.ul_pos,
+	   lw->winlabel.label + lw->winlabel.ul_pos + 1);
+}
+
+
+
+/* ARGSUSED */
+static void Initialize(request, new)
+ Widget request, new;
+{
+    WinLabelWidget lw = (WinLabelWidget) new;
+
+    if (lw->winlabel.label == NULL) 
+        lw->winlabel.label = XtNewString(lw->core.name);
+    else {
+        lw->winlabel.label = XtNewString(lw->winlabel.label);
+    }
+
+    RemoveAmpersand(new);
+
+    GetnormalGC(lw);
+    GetgrayGC(lw);
+
+    SetTextWidthAndHeight(lw);
+
+    if (lw->core.height == 0)
+        lw->core.height = lw->winlabel.label_height + 
+		          2*lw->winlabel.internal_height;
+
+    set_bitmap_info (lw);		/* need core.height */
+
+    if (lw->core.width == 0)		/* need winlabel.lbm_width */
+        lw->core.width = (lw->winlabel.label_width + 
+			  2 * lw->winlabel.internal_width
+			  + LEFT_OFFSET(lw));
+
+    lw->winlabel.label_x = lw->winlabel.label_y = 0;
+    (*XtClass(new)->core_class.resize) ((Widget)lw);
+
+} /* Initialize */
+
+/*
+ * Repaint the widget window
+ */
+
+/* ARGSUSED */
+static void Redisplay(w, event, region)
+    Widget w;
+    XEvent *event;
+    Region region;
+{
+   WinLabelWidget lw = (WinLabelWidget) w;
+   GC gc;
+   int ul_x_loc, ul_y_loc, ul_width;
+
+   if (region != NULL) {
+       int x = lw->winlabel.label_x;
+       unsigned int width = lw->winlabel.label_width;
+       if (lw->winlabel.lbm_width) {
+	   if (lw->winlabel.label_x > (x = lw->winlabel.internal_width))
+	       width += lw->winlabel.label_x - x;
+       }
+       if (XRectInRegion(region, x, lw->winlabel.label_y,
+			 width, lw->winlabel.label_height) == RectangleOut)
+	   return;
+   }
+
+   gc = XtIsSensitive((Widget)lw) ? lw->winlabel.normal_GC 
+	                          : lw->winlabel.gray_GC;
+#ifdef notdef
+   if (region != NULL) XSetRegion(XtDisplay(w), gc, region);
+#endif /*notdef*/
+   if (lw->winlabel.pixmap == None) {
+       int len = lw->winlabel.label_len;
+       char *label = lw->winlabel.label;
+       Position y = lw->winlabel.label_y + 
+	            lw->winlabel.font->max_bounds.ascent;
+
+       /* display left bitmap */
+       if (lw->winlabel.left_bitmap && lw->winlabel.lbm_width != 0) {
+	   XCopyPlane (XtDisplay(w), lw->winlabel.left_bitmap, XtWindow(w), gc,
+		       0, 0, lw->winlabel.lbm_width, lw->winlabel.lbm_height,
+		       (int) lw->winlabel.internal_width, 
+		       (int) lw->winlabel.internal_height + 
+		       lw->winlabel.lbm_y, 
+		       (unsigned long) 1L);
+       }
+
+       if (len == MULTI_LINE_LABEL) {
+	   char *nl;
+	   while ((nl = index(label, '\n')) != NULL) {
+	       if (lw->winlabel.encoding)
+		   XDrawString16(XtDisplay(w), XtWindow(w), gc,
+				 lw->winlabel.label_x, y,
+				 (TXT16*)label, (int)(nl - label)/2);
+	       else
+		   XDrawString(XtDisplay(w), XtWindow(w), gc,
+			       lw->winlabel.label_x, y, label, 
+			       (int)(nl - label));
+	       y += lw->winlabel.font->max_bounds.ascent + 
+		               lw->winlabel.font->max_bounds.descent;
+	       label = nl + 1;
+	   }
+	   len = strlen(label);
+       }
+       if (len) {
+	   if (lw->winlabel.encoding)
+	       XDrawString16(XtDisplay(w), XtWindow(w), gc,
+			     lw->winlabel.label_x, y, (TXT16*)label, len/2);
+	   else
+	       XDrawString(XtDisplay(w), XtWindow(w), gc,
+			   lw->winlabel.label_x, y, label, len);
+
+	   if (lw->winlabel.ul_pos != -1)
+	   {
+	       /* Don't bother with two byte chars at present */
+	       if (!lw->winlabel.encoding)
+	       {
+	           ul_x_loc = lw->winlabel.label_x + 
+			      XTextWidth(lw->winlabel.font,
+		              lw->winlabel.label, lw->winlabel.ul_pos);
+	           ul_y_loc = lw->winlabel.label_height + 
+		              lw->winlabel.internal_height + 1;
+	           ul_width = XTextWidth(lw->winlabel.font,
+		              lw->winlabel.label + lw->winlabel.ul_pos, 1);
+
+	           XDrawLine(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
+		        ul_x_loc, ul_y_loc, ul_x_loc + ul_width - 1, ul_y_loc);
+	       }
+           }
+       }
+   } else if (lw->winlabel.label_len == 1) { /* depth */
+       XCopyPlane(XtDisplay(w), lw->winlabel.pixmap, XtWindow(w), gc,
+		  0, 0, lw->winlabel.label_width, lw->winlabel.label_height,
+		  lw->winlabel.label_x, lw->winlabel.label_y, 1L);
+   } else {
+       XCopyArea(XtDisplay(w), lw->winlabel.pixmap, XtWindow(w), gc,
+		 0, 0, lw->winlabel.label_width, lw->winlabel.label_height,
+		 lw->winlabel.label_x, lw->winlabel.label_y);
+   }
+#ifdef notdef
+   if (region != NULL) XSetClipMask(XtDisplay(w), gc, (Pixmap)None);
+#endif /* notdef */
+}
+
+static void _Reposition(lw, width, height, dx, dy)
+    register WinLabelWidget lw;
+    Dimension width, height;
+    Position *dx, *dy;
+{
+    Position newPos;
+    Position leftedge = lw->winlabel.internal_width + LEFT_OFFSET(lw);
+
+    switch (lw->winlabel.justify) {
+
+	case XtJustifyLeft   :
+	    newPos = leftedge;
+	    break;
+
+	case XtJustifyRight  :
+	    newPos = width -
+		(lw->winlabel.label_width + lw->winlabel.internal_width);
+	    break;
+
+	case XtJustifyCenter :
+	default:
+	    newPos = (int)(width - lw->winlabel.label_width) / 2;
+	    break;
+    }
+    if (newPos < (Position)leftedge)
+	newPos = leftedge;
+    *dx = newPos - lw->winlabel.label_x;
+    lw->winlabel.label_x = newPos;
+    *dy = (newPos = (int)(height - lw->winlabel.label_height) / 2)
+	  - lw->winlabel.label_y;
+    lw->winlabel.label_y = newPos;
+    return;
+}
+
+static void Resize(w)
+    Widget w;
+{
+    WinLabelWidget lw = (WinLabelWidget)w;
+    Position dx, dy;
+    _Reposition(lw, w->core.width, w->core.height, &dx, &dy);
+    compute_bitmap_offsets (lw);
+}
+
+/*
+ * Set specified arguments into widget
+ */
+
+#define PIXMAP 0
+#define WIDTH 1
+#define HEIGHT 2
+#define NUM_CHECKS 3
+
+static Boolean SetValues(current, request, new, args, num_args)
+    Widget current, request, new;
+    ArgList args;
+    Cardinal *num_args;
+{
+    WinLabelWidget curlw = (WinLabelWidget) current;
+    WinLabelWidget reqlw = (WinLabelWidget) request;
+    WinLabelWidget newlw = (WinLabelWidget) new;
+    int i;
+    Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS];
+
+    for (i = 0; i < NUM_CHECKS; i++)
+	checks[i] = FALSE;
+
+    for (i = 0; i < *num_args; i++) {
+	if (streq(XtNbitmap, args[i].name))
+	    checks[PIXMAP] = TRUE;
+	if (streq(XtNwidth, args[i].name))
+	    checks[WIDTH] = TRUE;
+	if (streq(XtNheight, args[i].name))
+	    checks[HEIGHT] = TRUE;
+    }
+
+    if (newlw->winlabel.label == NULL) {
+	newlw->winlabel.label = newlw->core.name;
+    }
+
+    /*
+     * resize on bitmap change
+     */
+    if (curlw->winlabel.left_bitmap != newlw->winlabel.left_bitmap) {
+	was_resized = True;
+    }
+
+    if (curlw->winlabel.encoding != newlw->winlabel.encoding)
+	was_resized = True;
+
+    if (curlw->winlabel.label != newlw->winlabel.label) {
+        if (curlw->winlabel.label != curlw->core.name)
+	    XtFree( (char *)curlw->winlabel.label );
+
+	if (newlw->winlabel.label != newlw->core.name) {
+	    newlw->winlabel.label = XtNewString( newlw->winlabel.label );
+	}
+	RemoveAmpersand(new);
+	was_resized = True;
+    }
+
+    if (was_resized || (curlw->winlabel.font != newlw->winlabel.font) ||
+	(curlw->winlabel.justify != newlw->winlabel.justify) 
+	|| checks[PIXMAP]) {
+
+	SetTextWidthAndHeight(newlw);
+	was_resized = True;
+    }
+
+    /* recalculate the window size if something has changed. */
+    if (newlw->winlabel.resize && was_resized) {
+	if ((curlw->core.height == reqlw->core.height) && !checks[HEIGHT])
+	    newlw->core.height = (newlw->winlabel.label_height + 
+				  2 * newlw->winlabel.internal_height);
+
+	set_bitmap_info (newlw);
+
+	if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH])
+	    newlw->core.width = (newlw->winlabel.label_width +
+				 LEFT_OFFSET(newlw) +
+				 2 * newlw->winlabel.internal_width);
+    }
+
+    if (curlw->winlabel.foreground != newlw->winlabel.foreground
+	|| curlw->core.background_pixel != newlw->core.background_pixel
+	|| curlw->winlabel.font->fid != newlw->winlabel.font->fid) {
+
+	XtReleaseGC(new, curlw->winlabel.normal_GC);
+	XtReleaseGC(new, curlw->winlabel.gray_GC);
+	XmuReleaseStippledPixmap( XtScreen(current), curlw->winlabel.stipple );
+	GetnormalGC(newlw);
+	GetgrayGC(newlw);
+	redisplay = True;
+    }
+
+    if ((curlw->winlabel.internal_width != newlw->winlabel.internal_width)
+        || (curlw->winlabel.internal_height != newlw->winlabel.internal_height)
+	|| was_resized) {
+	/* Resize() will be called if geometry changes succeed */
+	Position dx, dy;
+	_Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy);
+    }
+
+    return was_resized || redisplay ||
+	   XtIsSensitive(current) != XtIsSensitive(new);
+}
+
+static void Destroy(w)
+    Widget w;
+{
+    WinLabelWidget lw = (WinLabelWidget)w;
+
+    XtFree( lw->winlabel.label );
+    XtReleaseGC( w, lw->winlabel.normal_GC );
+    XtReleaseGC( w, lw->winlabel.gray_GC);
+    XmuReleaseStippledPixmap( XtScreen(w), lw->winlabel.stipple );
+}
+
+
+static XtGeometryResult QueryGeometry(w, intended, preferred)
+    Widget w;
+    XtWidgetGeometry *intended, *preferred;
+{
+    register WinLabelWidget lw = (WinLabelWidget)w;
+
+    preferred->request_mode = CWWidth | CWHeight;
+    preferred->width = (lw->winlabel.label_width + 
+			2 * lw->winlabel.internal_width +
+			LEFT_OFFSET(lw));
+    preferred->height = lw->winlabel.label_height + 
+	                2*lw->winlabel.internal_height;
+    if (  ((intended->request_mode & (CWWidth | CWHeight))
+	   	== (CWWidth | CWHeight)) &&
+	  intended->width == preferred->width &&
+	  intended->height == preferred->height)
+	return XtGeometryYes;
+    else if (preferred->width == w->core.width &&
+	     preferred->height == w->core.height)
+	return XtGeometryNo;
+    else
+	return XtGeometryAlmost;
+}
diff --git a/controls/WinLabel.h b/controls/WinLabel.h
new file mode 100644
index 0000000..de285da
--- /dev/null
+++ b/controls/WinLabel.h
@@ -0,0 +1,106 @@
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Added code to translate ampersand to underlined char
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinLabel
+ */
+
+#ifndef _WinLabel_h
+#define _WinLabel_h
+
+/***********************************************************************
+ *
+ * WinLabel Widget
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw/Simple.h>
+
+/* Resources:
+
+ Name		     Class		RepType		Default Value
+ ----		     -----		-------		-------------
+ background	     Background		Pixel		XtDefaultBackground
+ bitmap		     Pixmap		Pixmap		None
+ border		     BorderColor	Pixel		XtDefaultForeground
+ borderWidth	     BorderWidth	Dimension	1
+ cursor		     Cursor		Cursor		None
+ cursorName	     Cursor		String		NULL
+ destroyCallback     Callback		XtCallbackList	NULL
+ encoding	     Encoding		unsigned char	XawTextEncoding8bit
+ font		     Font		XFontStruct*	XtDefaultFont
+ foreground	     Foreground		Pixel		XtDefaultForeground
+ height		     Height		Dimension	text height
+ insensitiveBorder   Insensitive	Pixmap		Gray
+ internalHeight	     Height		Dimension	2
+ internalWidth	     Width		Dimension	4
+ justify	     Justify		XtJustify	XtJustifyCenter
+ label		     Label		String		NULL
+ leftBitmap	     LeftBitmap		Pixmap		None
+ mappedWhenManaged   MappedWhenManaged	Boolean		True
+ pointerColor	     Foreground		Pixel		XtDefaultForeground
+ pointerColorBackground Background	Pixel		XtDefaultBackground
+ resize		     Resize		Boolean		True
+ sensitive	     Sensitive		Boolean		True
+ width		     Width		Dimension	text width
+ x		     Position		Position	0
+ y		     Position		Position	0
+
+*/
+
+#define XawTextEncoding8bit 0
+#define XawTextEncodingChar2b 1
+
+#define XtNleftBitmap "leftBitmap"
+#define XtCLeftBitmap "LeftBitmap"
+#define XtNencoding "encoding"
+#define XtCEncoding "Encoding"
+
+#ifndef _XtStringDefs_h_
+#define XtNbitmap "bitmap"
+#define XtNforeground "foreground"
+#define XtNlabel "label"
+#define XtNfont "font"
+#define XtNinternalWidth "internalWidth"
+#define XtNinternalHeight "internalHeight"
+#define XtNresize "resize"
+#define XtCResize "Resize"
+#define XtCBitmap "Bitmap"
+#endif
+
+/* Class record constants */
+
+extern WidgetClass winLabelWidgetClass;
+
+typedef struct _WinLabelClassRec *WinLabelWidgetClass;
+typedef struct _WinLabelRec      *WinLabelWidget;
+
+#endif /* _WinLabel_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/controls/WinLabelP.h b/controls/WinLabelP.h
new file mode 100644
index 0000000..f84c2b7
--- /dev/null
+++ b/controls/WinLabelP.h
@@ -0,0 +1,114 @@
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Added code to translate ampersand to underlined char
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinLabel
+ */
+
+/* 
+ * WinLabelP.h - Private definitions for WinLabel widget
+ * 
+ */
+
+#ifndef _WinLabelP_h
+#define _WinLabelP_h
+
+/***********************************************************************
+ *
+ * WinLabel Widget Private Data
+ *
+ ***********************************************************************/
+
+#include "WinLabel.h"
+#include <X11/Xaw/SimpleP.h>
+
+/* New fields for the WinLabel widget class record */
+
+typedef struct {int foo;} WinLabelClassPart;
+
+/* Full class record declaration */
+typedef struct _WinLabelClassRec {
+    CoreClassPart	core_class;
+    SimpleClassPart	simple_class;
+    WinLabelClassPart	winlabel_class;
+} WinLabelClassRec;
+
+extern WinLabelClassRec winLabelClassRec;
+
+/* New fields for the WinLabel widget record */
+typedef struct {
+    /* resources */
+    Pixel	foreground;
+    XFontStruct	*font;
+    char	*label;
+    XtJustify	justify;
+    Dimension	internal_width;
+    Dimension	internal_height;
+    Pixmap	pixmap;
+    Boolean	resize;
+    unsigned char encoding;
+    Pixmap	left_bitmap;
+
+    /* private state */
+    GC		normal_GC;
+    GC          gray_GC;
+    Pixmap	stipple;
+    Position	label_x;
+    Position	label_y;
+    Dimension	label_width;
+    Dimension	label_height;
+    Dimension	label_len;
+    int		lbm_y;			/* where in label */
+    unsigned int lbm_width, lbm_height;	 /* size of pixmap */
+
+    int ul_pos;                 /* Offset in chars of underlined character */
+                                /* in label */
+} WinLabelPart;
+
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _WinLabelRec {
+    CorePart	core;
+    SimplePart	simple;
+    WinLabelPart winlabel;
+} WinLabelRec;
+
+#define LEFT_OFFSET(lw) ((lw)->winlabel.left_bitmap \
+			 ? (lw)->winlabel.lbm_width + \
+			 (lw)->winlabel.internal_width \
+			 : 0)
+
+#endif /* _WinLabelP_h */
+
diff --git a/controls/WinMenuButtP.h b/controls/WinMenuButtP.h
new file mode 100644
index 0000000..e5d45b1
--- /dev/null
+++ b/controls/WinMenuButtP.h
@@ -0,0 +1,100 @@
+/*
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Modifications for Wine
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinMenuButton
+ */
+
+/***********************************************************************
+ *
+ * WinMenuButton Widget
+ *
+ ***********************************************************************/
+
+/*
+ * WinMenuButtP.h - Private Header file for WinMenuButton widget.
+ *
+ * This is the private header file for the WinMenuButton widget.
+ * It is intended to provide an easy method of activating pulldown menus.
+ *
+ * Date:    May 2, 1989
+ *
+ * By:      Chris D. Peterson
+ *          MIT X Consortium 
+ *          kit@expo.lcs.mit.edu
+ */
+
+#ifndef _WinMenuButtonP_h
+#define _WinMenuButtonP_h
+
+#include "WinMenuButto.h"
+#include "WinCommandP.h"
+
+/************************************
+ *
+ *  Class structure
+ *
+ ***********************************/
+
+
+   /* New fields for the WinMenuButton widget class record */
+typedef struct _WinMenuButtonClass 
+{
+  int makes_compiler_happy;  /* not used */
+} WinMenuButtonClassPart;
+
+   /* Full class record declaration */
+typedef struct _WinMenuButtonClassRec {
+	CoreClassPart	    core_class;
+  SimpleClassPart	    simple_class;
+  WinLabelClassPart	    winLabel_class;
+  WinCommandClassPart	    winCommand_class;
+  WinMenuButtonClassPart    winMenuButton_class;
+} WinMenuButtonClassRec;
+
+extern WinMenuButtonClassRec winMenuButtonClassRec;
+
+/***************************************
+ *
+ *  Instance (widget) structure 
+ *
+ **************************************/
+
+    /* New fields for the WinMenuButton widget record */
+typedef struct {
+  /* resources */
+  String menu_name;
+
+} WinMenuButtonPart;
+
+   /* Full widget declaration */
+typedef struct _WinMenuButtonRec {
+    CorePart         core;
+    SimplePart	     simple;
+    WinLabelPart     winlabel;
+    WinCommandPart   wincommand;
+    WinMenuButtonPart winmenu_button;
+} WinMenuButtonRec;
+
+#endif /* _WinMenuButtonP_h */
+
+
diff --git a/controls/WinMenuButto.c b/controls/WinMenuButto.c
new file mode 100644
index 0000000..71508e0
--- /dev/null
+++ b/controls/WinMenuButto.c
@@ -0,0 +1,215 @@
+/*
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * Modifications for Wine
+ *
+ * 8/27/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinMenuButton
+ */
+
+/***********************************************************************
+ *
+ * WinMenuButton Widget
+ *
+ ***********************************************************************/
+
+/*
+ * WinMenuButto.c - Source code for WinMenuButton widget.
+ *
+ * This is the source code for the WinMenuButton widget.
+ * It is intended to provide an easy method of activating pulldown menus.
+ *
+ * Date:    May 2, 1989
+ *
+ * By:      Chris D. Peterson
+ *          MIT X Consortium 
+ *          kit@expo.lcs.mit.edu
+ */
+
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw/XawInit.h>
+#include "WinMenuButtP.h"
+
+static void ClassInitialize();
+static void PopupMenu();
+
+#define superclass ((WinCommandWidgetClass)&winCommandClassRec)
+
+static char defaultTranslations[] = 
+    "<EnterWindow>:     highlight()             \n\
+     <LeaveWindow>:     reset()                 \n\
+     <BtnDown>:         reset() PopupMenu()     ";
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+#define offset(field) XtOffsetOf(WinMenuButtonRec, field)
+static XtResource resources[] = {
+  {
+    XtNmenuName, XtCMenuName, XtRString, sizeof(String), 
+    offset(winmenu_button.menu_name), XtRString, (XtPointer)"menu"},
+};
+#undef offset
+
+static XtActionsRec actionsList[] =
+{
+  {"PopupMenu",	PopupMenu}
+};
+
+WinMenuButtonClassRec winMenuButtonClassRec = {
+  {
+    (WidgetClass) superclass,		/* superclass		  */	
+    "WinMenuButton",			/* class_name		  */
+    sizeof(WinMenuButtonRec),       	/* size			  */
+    ClassInitialize,			/* class_initialize	  */
+    NULL,				/* class_part_initialize  */
+    FALSE,				/* class_inited		  */
+    NULL,				/* initialize		  */
+    NULL,				/* initialize_hook	  */
+    XtInheritRealize,			/* realize		  */
+    actionsList,			/* actions		  */
+    XtNumber(actionsList),		/* num_actions		  */
+    resources,				/* resources		  */
+    XtNumber(resources),		/* resource_count	  */
+    NULLQUARK,				/* xrm_class		  */
+    FALSE,				/* compress_motion	  */
+    TRUE,				/* compress_exposure	  */
+    TRUE,				/* compress_enterleave    */
+    FALSE,				/* visible_interest	  */
+    NULL,				/* destroy		  */
+    XtInheritResize,			/* resize		  */
+    XtInheritExpose,			/* expose		  */
+    NULL,				/* set_values		  */
+    NULL,				/* set_values_hook	  */
+    XtInheritSetValuesAlmost,		/* set_values_almost	  */
+    NULL,				/* get_values_hook	  */
+    NULL,				/* accept_focus		  */
+    XtVersion,				/* version		  */
+    NULL,				/* callback_private	  */
+    defaultTranslations,               	/* tm_table		  */
+    XtInheritQueryGeometry,		/* query_geometry	  */
+    XtInheritDisplayAccelerator,	/* display_accelerator	  */
+    NULL				/* extension		  */
+  },  /* CoreClass fields initialization */
+  {
+    XtInheritChangeSensitive		/* change_sensitive	  */ 
+  },  /* SimpleClass fields initialization */
+  {
+    0,                                     /* field not used    */
+  },  /* WinLabelClass fields initialization */
+  {
+    0,                                     /* field not used    */
+  },  /* WinCommandClass fields initialization */
+  {
+    0,                                     /* field not used    */
+  },  /* WinMenuButtonClass fields initialization */
+};
+
+  /* for public consumption */
+WidgetClass winMenuButtonWidgetClass = (WidgetClass) &winMenuButtonClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void ClassInitialize()
+{
+    XawInitializeWidgetSet();
+    XtRegisterGrabAction(PopupMenu, True, ButtonPressMask | ButtonReleaseMask,
+			 GrabModeAsync, GrabModeAsync);
+}
+
+/* ARGSUSED */
+static void
+PopupMenu(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+  WinMenuButtonWidget mbw = (WinMenuButtonWidget) w;
+  Widget menu, temp;
+  Arg arglist[2];
+  Cardinal num_args;
+  int menu_x, menu_y, menu_width, menu_height, button_height;
+  Position button_x, button_y;
+
+  temp = w;
+  while(temp != NULL) {
+    menu = XtNameToWidget(temp, mbw->winmenu_button.menu_name);
+    if (menu == NULL) 
+      temp = XtParent(temp);
+    else
+      break;
+  }
+
+  if (menu == NULL) {
+    char error_buf[BUFSIZ];
+    sprintf(error_buf, "MenuButton: %s %s.",
+	    "Could not find menu widget named", mbw->winmenu_button.menu_name);
+    XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+    return;
+  }
+  if (!XtIsRealized(menu))
+    XtRealizeWidget(menu);
+  
+  menu_width = menu->core.width + 2 * menu->core.border_width;
+  button_height = w->core.height + 2 * w->core.border_width;
+  menu_height = menu->core.height + 2 * menu->core.border_width;
+
+  XtTranslateCoords(w, 0, 0, &button_x, &button_y);
+  menu_x = button_x;
+  menu_y = button_y + button_height;
+
+  if (menu_x >= 0) {
+    int scr_width = WidthOfScreen(XtScreen(menu));
+    if (menu_x + menu_width > scr_width)
+      menu_x = scr_width - menu_width;
+  }
+  if (menu_x < 0) 
+    menu_x = 0;
+
+  if (menu_y >= 0) {
+    int scr_height = HeightOfScreen(XtScreen(menu));
+    if (menu_y + menu_height > scr_height)
+      menu_y = scr_height - menu_height;
+  }
+  if (menu_y < 0)
+    menu_y = 0;
+
+  num_args = 0;
+  XtSetArg(arglist[num_args], XtNx, menu_x); num_args++;
+  XtSetArg(arglist[num_args], XtNy, menu_y); num_args++;
+  XtSetValues(menu, arglist, num_args);
+
+  XtPopupSpringLoaded(menu);
+}
+
diff --git a/controls/WinMenuButto.h b/controls/WinMenuButto.h
new file mode 100644
index 0000000..3dcb3f3
--- /dev/null
+++ b/controls/WinMenuButto.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1989 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Modifications for Wine
+ *
+ * 8/23/93  David Metcalfe (david@prism.demon.co.uk)
+ *          Converted to WinMenuButton
+ */
+
+/***********************************************************************
+ *
+ * WinMenuButton Widget
+ *
+ ***********************************************************************/
+
+/*
+ * WinMenuButton.h - Public Header file for WinMenuButton widget.
+ *
+ * This is the public header file for the WinMenuButton widget.
+ * It is intended to provide an easy method of activating pulldown menus.
+ *
+ * Date:    May 2, 1989
+ *
+ * By:      Chris D. Peterson
+ *          MIT X Consortium 
+ *          kit@expo.lcs.mit.edu
+ */
+
+#ifndef _WinMenuButton_h
+#define _WinMenuButton_h
+
+#include "WinCommand.h"
+
+/* Resources:
+
+ Name		     Class		RepType		Default Value
+ ----		     -----		-------		-------------
+ background	     Background		Pixel		XtDefaultBackground
+ bitmap		     Pixmap		Pixmap		None
+ border		     BorderColor	Pixel		XtDefaultForeground
+ borderWidth	     BorderWidth	Dimension	1
+ callback	     Callback		Pointer		NULL
+ cursor		     Cursor		Cursor		None
+ destroyCallback     Callback		Pointer		NULL
+ font		     Font		XFontStruct*	XtDefaultFont
+ foreground	     Foreground		Pixel		XtDefaultForeground
+ height		     Height		Dimension	text height
+ highlightThickness  Thickness		Dimension	2
+ insensitiveBorder   Insensitive	Pixmap		Gray
+ internalHeight	     Height		Dimension	2
+ internalWidth	     Width		Dimension	4
+ justify	     Justify		XtJustify	XtJustifyCenter
+ label		     Label		String		NULL
+ mappedWhenManaged   MappedWhenManaged	Boolean		True
+ menuName            MenuName           String          "menu"
+ resize		     Resize		Boolean		True
+ sensitive	     Sensitive		Boolean		True
+ width		     Width		Dimension	text width
+ x		     Position		Position	0
+ y		     Position		Position	0
+
+*/
+
+#define XtNmenuName "menuName"
+#define XtCMenuName "MenuName"
+
+extern WidgetClass     winMenuButtonWidgetClass;
+
+typedef struct _WinMenuButtonClassRec   *WinMenuButtonWidgetClass;
+typedef struct _WinMenuButtonRec        *WinMenuButtonWidget;
+
+#endif /* _WinMenuButton_h --  DON'T ADD STUFF AFTER THIS */
diff --git a/controls/menu.c b/controls/menu.c
new file mode 100644
index 0000000..951fc74
--- /dev/null
+++ b/controls/menu.c
@@ -0,0 +1,569 @@
+static char RCSId[] = "$Id$";
+static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/SmeLine.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include "WinMenuButto.h"
+#include "SmeMenuButto.h"
+#include "windows.h"
+#include "menu.h"
+#include "heap.h"
+#include "win.h"
+#include "bitmaps/check_bitmap"
+#include "bitmaps/nocheck_bitmap"
+
+static LPMENUBAR firstMenu = NULL;
+static MENUITEM *parentItem;
+static MENUITEM *siblingItem;
+static int       lastLevel;
+static int       menuId = 0;
+static Pixmap    checkBitmap = XtUnspecifiedPixmap;
+static Pixmap    nocheckBitmap = XtUnspecifiedPixmap;
+
+/**********************************************************************
+ *					MENU_CheckWidget
+ */
+void
+MENU_CheckWidget(Widget w, Boolean check)
+{
+    if (checkBitmap == XtUnspecifiedPixmap)
+    {
+	Display *display = XtDisplayOfObject(w);
+	    
+	checkBitmap = XCreateBitmapFromData(display,
+					    DefaultRootWindow(display),
+					    check_bitmap_bits,
+					    check_bitmap_width,
+					    check_bitmap_height);
+	nocheckBitmap = XCreateBitmapFromData(display,
+					    DefaultRootWindow(display),
+					    nocheck_bitmap_bits,
+					    nocheck_bitmap_width,
+					    nocheck_bitmap_height);
+    }
+	    
+    if (check)
+	XtVaSetValues(w, XtNleftBitmap, checkBitmap, NULL);
+    else
+	XtVaSetValues(w, XtNleftBitmap, nocheckBitmap, NULL);
+}
+
+/**********************************************************************
+ *					MENU_ParseMenu
+ */
+WORD *
+MENU_ParseMenu(WORD *first_item, 
+	       int level,
+	       int limit,
+	       int (*action)(WORD *item, int level, void *app_data),
+	       void *app_data)
+{
+    WORD *item;
+    WORD *next_item;
+    int   i;
+
+    level++;
+    next_item = first_item;
+    i = 0;
+    do
+    {
+	i++;
+	item = next_item;
+	(*action)(item, level, app_data);
+	if (*item & MF_POPUP)
+	{
+	    MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item;
+
+	    next_item = (WORD *) (popup_item->item_text + 
+				  strlen(popup_item->item_text) + 1);
+	    next_item = MENU_ParseMenu(next_item, level, 0, action, app_data);
+	}
+	else
+	{
+	    MENU_NORMALITEM *normal_item = (MENU_NORMALITEM *) item;
+
+	    next_item = (WORD *) (normal_item->item_text + 
+				  strlen(normal_item->item_text) + 1);
+	}
+    }
+    while (!(*item & MF_END) && i != limit);
+
+    return next_item;
+}
+
+/**********************************************************************
+ *					MENU_FindMenuBar
+ */
+LPMENUBAR
+MENU_FindMenuBar(MENUITEM *this_item)
+{
+    MENUITEM *root;
+    LPMENUBAR menu;
+
+    /*
+     * Find root item on menu bar.
+     */
+    for (root = this_item; root->parent != NULL; root = root->parent)
+	;
+    for ( ; root->prev != NULL; root = root->prev)
+	;
+
+    /*
+     * Find menu bar for the root item.
+     */
+    for (menu = firstMenu; 
+	 menu != NULL && menu->firstItem != root; 
+	 menu = menu->next)
+	;
+    
+    return menu;
+}
+
+/**********************************************************************
+ *					MENU_SelectionCallback
+ */
+static void
+MENU_SelectionCallback(Widget w, XtPointer client_data, XtPointer call_data)
+{
+    MENUITEM *this_item = (MENUITEM *) client_data;
+    LPMENUBAR menu;
+    WND	     *wndPtr;
+
+    if (this_item->menu_w != NULL || (this_item->item_flags & MF_DISABLED))
+	return;
+
+    /*
+     * Find menu bar for the root item.
+     */
+    menu = MENU_FindMenuBar(this_item);
+    if (menu != NULL)
+    {
+	wndPtr = (WND *) GlobalLock(menu->ownerWnd);
+	if (wndPtr == NULL)
+	    return;
+
+#ifdef DEBUG_MENU
+	printf("Selected '%s' (%d).\n", 
+	       this_item->item_text, this_item->item_id);
+#endif
+	
+	CallWindowProc(wndPtr->lpfnWndProc, menu->ownerWnd, WM_COMMAND,
+		       this_item->item_id, 0);
+	
+	GlobalUnlock(menu->ownerWnd);
+    }
+}
+
+/**********************************************************************
+ *					MENU_CreateItems
+ */
+int
+MENU_CreateItems(WORD *item, int level, void *app_data)
+{
+    MENU_POPUPITEM     *popup_item;
+    MENU_NORMALITEM    *normal_item;
+    MENUITEM	       *this_item;
+    Arg			this_args[10];
+    int			n_args = 0;
+    LPMENUBAR           menu = (LPMENUBAR) app_data;
+
+    if (menu->nItems == 0)
+	this_item = menu->firstItem;
+    else
+	this_item = (MENUITEM *) GlobalQuickAlloc(sizeof(MENUITEM));
+
+    if (this_item == NULL)
+	return 0;
+
+    if (level > lastLevel)
+    {
+	parentItem  = siblingItem;
+	siblingItem = NULL;
+    }
+
+    while (level < lastLevel)
+    {
+	siblingItem = parentItem;
+	if (siblingItem != NULL)
+	    parentItem = siblingItem->parent;
+	else
+	    parentItem = NULL;
+
+	lastLevel--;
+    }
+    lastLevel = level;
+    
+    this_item->next = NULL;
+    this_item->prev = siblingItem;
+    this_item->child = NULL;
+    this_item->parent = parentItem;
+    
+    if (siblingItem !=  NULL)
+	siblingItem->next = this_item;
+    if (parentItem != NULL && parentItem->child == NULL)
+	parentItem->child = this_item;
+    
+    siblingItem = this_item;
+    
+    if (*item & MF_POPUP)
+    {
+	popup_item = (MENU_POPUPITEM *) item;
+	this_item->item_flags = popup_item->item_flags;
+	this_item->item_id    = -1;
+	this_item->item_text  = popup_item->item_text;
+
+#ifdef DEBUG_MENU
+	printf("%d: popup %s\n", level, this_item->item_text);
+#endif
+    }
+    else
+    {
+	normal_item = (MENU_NORMALITEM *) item;
+	this_item->item_flags = normal_item->item_flags;
+	this_item->item_id    = normal_item->item_id;
+	this_item->item_text  = normal_item->item_text;
+
+#ifdef DEBUG_MENU
+	printf("%d: normal %s (%04x)\n", level, this_item->item_text,
+	       this_item->item_flags);
+#endif
+    }
+
+    if (level == 1)
+    {
+	menu->nItems++;
+
+	if (this_item->prev != NULL)
+	{
+	    XtSetArg(this_args[n_args], XtNhorizDistance, 10); 
+	    n_args++;
+	    XtSetArg(this_args[n_args], XtNfromHoriz, this_item->prev->w); 
+	    n_args++;
+	}
+
+	if (this_item->item_flags & MF_POPUP)
+	{
+	    sprintf(this_item->menu_name, "Menu%d", menuId++);
+	    XtSetArg(this_args[n_args], XtNmenuName, this_item->menu_name);
+	    n_args++;
+	    
+	    this_item->w = XtCreateManagedWidget(this_item->item_text,
+						 winMenuButtonWidgetClass, 
+						 menu->parentWidget,
+						 this_args, n_args);
+	    this_item->menu_w = XtCreatePopupShell(this_item->menu_name,
+						 simpleMenuWidgetClass, 
+						 this_item->w,
+						 NULL, 0);
+	}
+	else
+	{
+	    this_item->w = XtCreateManagedWidget(this_item->item_text,
+						 winCommandWidgetClass, 
+						 menu->parentWidget,
+						 this_args, n_args);
+	    this_item->menu_w = NULL;
+	    XtAddCallback(this_item->w, XtNcallback, MENU_SelectionCallback,
+			  (XtPointer) this_item);
+	}
+
+	if (menu->firstItem == NULL)
+	    menu->firstItem = this_item;
+    }
+    else
+    {
+	if ((this_item->item_flags & MF_MENUBREAK) ||
+	    (strlen(this_item->item_text) == 0))
+	{
+	    XtSetArg(this_args[n_args], XtNheight, 10);
+	    n_args++;
+	    this_item->w = XtCreateManagedWidget("separator",
+						 smeLineObjectClass,
+						 this_item->parent->menu_w,
+						 this_args, n_args);
+	}
+	else
+	{
+	    XtSetArg(this_args[n_args], XtNmenuName, this_item->menu_name);
+	    n_args++;
+	    this_item->w = XtCreateManagedWidget(this_item->item_text,
+						 smeMenuButtonObjectClass,
+						 this_item->parent->menu_w,
+						 this_args, n_args);
+
+	    if (this_item->item_flags & MF_POPUP)
+	    {
+		sprintf(this_item->menu_name, "Menu%d", menuId++);
+		this_item->menu_w = XtCreatePopupShell(this_item->menu_name,
+						     simpleMenuWidgetClass, 
+						     this_item->parent->menu_w,
+						     NULL, 0);
+	    }
+	    else
+	    {
+		this_item->menu_w = NULL;
+		XtAddCallback(this_item->w, XtNcallback, 
+			      MENU_SelectionCallback, (XtPointer) this_item);
+	    }
+	}
+    }
+
+    if (this_item->w != NULL)
+    {
+	if (this_item->item_flags & MF_GRAYED)
+	    XtSetSensitive(this_item->w, False);
+	if (this_item->item_flags & MF_DISABLED)
+	    XtVaSetValues(this_item->w, XtNinactive, True, NULL);
+	if (this_item->item_flags & MF_CHECKED)
+	    MENU_CheckWidget(this_item->w, True);
+    }
+
+    return 1;
+}
+
+/**********************************************************************
+ *					MENU_UseMenu
+ */
+LPMENUBAR
+MENU_UseMenu(Widget parent, HANDLE instance, HWND wnd, HMENU hmenu, int width)
+{
+    LPMENUBAR 		menubar;
+    MENUITEM           *menu;
+    MENU_HEADER        *menu_desc;
+
+    menu  = (MENUITEM *) GlobalLock(hmenu);
+    if (hmenu == 0 || menu == NULL)
+    {
+	return NULL;
+    }
+
+    menubar = MENU_FindMenuBar(menu);
+    if (menubar == NULL)
+    {
+	GlobalUnlock(hmenu);
+	return NULL;
+    }
+
+    menubar->nItems 	     = 0;
+    menubar->parentWidget    = parent;
+    menubar->ownerWnd	     = wnd;
+
+    menu_desc = (MENU_HEADER *) GlobalLock(menubar->menuDescription);
+    
+    parentItem  = NULL;
+    siblingItem = NULL;
+    lastLevel   = 0;
+    MENU_ParseMenu((WORD *) (menu_desc + 1), 0, 0, MENU_CreateItems, menubar);
+
+    menubar->menuBarWidget = menubar->firstItem->w;
+
+    menubar->next = firstMenu;
+    firstMenu = menubar;
+    
+    return menubar;
+}
+
+/**********************************************************************
+ *					MENU_CreateMenuBar
+ */
+LPMENUBAR
+MENU_CreateMenuBar(Widget parent, HANDLE instance, HWND wnd,
+		   char *menu_name, int width)
+{
+    LPMENUBAR 		menubar;
+    HMENU     		hmenu;
+    MENUITEM           *menu;
+    MENU_HEADER        *menu_desc;
+
+#ifdef DEBUG_MENU
+    printf("CreateMenuBar: instance %02x, menu '%s', width %d\n",
+	   instance, menu_name, width);
+#endif
+
+    hmenu = LoadMenu(instance, menu_name);
+    return MENU_UseMenu(parent, instance, wnd, hmenu, width);
+}
+
+/**********************************************************************
+ *					MENU_FindItem
+ */
+MENUITEM *
+MENU_FindItem(MENUITEM *menu, WORD item_id, WORD flags)
+{
+    MENUITEM *item;
+    WORD position;
+    
+    if (flags & MF_BYPOSITION)
+    {
+	item = menu;
+	for (position = 0; item != NULL && position != item_id; position++)
+	    item = item->next;
+	
+	if (position == item_id)
+	    return item;
+    }
+    else
+    {
+	for ( ; menu != NULL; menu = menu->next)
+	{
+	    if (menu->item_id == item_id && menu->child == NULL)
+		return menu;
+	    if (menu->child != NULL)
+	    {
+		item = MENU_FindItem(menu->child, item_id, flags);
+		if (item != NULL)
+		    return item;
+	    }
+	}
+    }
+
+    return NULL;
+}
+
+/**********************************************************************
+ *					MENU_CollapseMenu
+ */
+static void
+MENU_CollapseBranch(MENUITEM *item, Boolean first_flag)
+{
+    MENUITEM *next_item;
+    
+    for ( ; item != NULL; item = next_item)
+    {
+	next_item = item->next;
+	
+	if (item->child != NULL)
+	    MENU_CollapseBranch(item->child, False);
+	    
+	if (item->w != NULL)
+	    XtDestroyWidget(item->w);
+	if (item->menu_w != NULL)
+	    XtDestroyWidget(item->menu_w);
+	
+	if (first_flag)
+	{
+	    item->prev 	     = NULL;
+	    item->child      = NULL;
+	    item->next 	     = NULL;
+	    item->parent     = NULL;
+	    item->item_flags = 0;
+	    item->item_id    = 0;
+	    item->item_text  = NULL;
+	    item->w 	     = NULL;
+	    item->menu_w     = NULL;
+
+	    first_flag = False;
+	}
+	else
+	{
+	    GlobalFree((unsigned int) item);
+	}
+    }
+}
+
+void
+MENU_CollapseMenu(LPMENUBAR menubar)
+{
+    MENU_CollapseBranch(menubar->firstItem, True);
+    
+    menubar->nItems 	     = 0;
+    menubar->parentWidget    = NULL;
+    menubar->ownerWnd	     = 0;
+    menubar->menuBarWidget   = NULL;
+}
+
+
+/**********************************************************************
+ *					CheckMenu
+ */
+BOOL
+CheckMenu(HMENU hmenu, WORD item_id, WORD check_flags)
+{
+    MENUITEM *item;
+    Pixmap left_bitmap;
+
+    if ((item = (MENUITEM *) GlobalLock(hmenu)) == NULL)
+	return -1;
+    
+    item = MENU_FindItem(item, item_id, check_flags);
+    if (item == NULL)
+    {
+	GlobalUnlock(hmenu);
+	return -1;
+    }
+
+    XtVaGetValues(item->w, XtNleftBitmap, &left_bitmap, NULL);
+    MENU_CheckWidget(item->w, (check_flags & MF_CHECKED));
+
+    if (left_bitmap == XtUnspecifiedPixmap)
+	return MF_UNCHECKED;
+    else
+	return MF_CHECKED;
+}
+
+/**********************************************************************
+ *					LoadMenu
+ */
+HMENU
+LoadMenu(HINSTANCE instance, char *menu_name)
+{
+    HANDLE		hmenubar;
+    LPMENUBAR 		menu;
+    HANDLE		hmenu_desc;
+    HMENU     		hmenu;
+    MENU_HEADER        *menu_desc;
+
+#ifdef DEBUG_MENU
+    printf("LoadMenu: instance %02x, menu '%s'\n",
+	   instance, menu_name);
+#endif
+
+    if (menu_name == NULL || 
+	(hmenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
+	(menu_desc = (MENU_HEADER *) GlobalLock(hmenu_desc)) == NULL)
+    {
+	return 0;
+    }
+
+    hmenubar = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUBAR));
+    menu = (LPMENUBAR) GlobalLock(hmenubar);
+    if (menu == NULL)
+    {
+	GlobalFree(hmenu_desc);
+	GlobalFree(hmenubar);
+	return 0;
+    }
+
+    hmenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
+    if (hmenu == 0)
+    {
+	GlobalFree(hmenu_desc);
+	GlobalFree(hmenubar);
+	return 0;
+    }
+
+    menu->menuDescription = hmenu_desc;
+    menu->nItems 	  = 0;
+    menu->parentWidget    = NULL;
+    menu->firstItem       = (MENUITEM *) GlobalLock(hmenu);
+    menu->ownerWnd	  = 0;
+    menu->menuBarWidget   = NULL;
+
+    menu->firstItem->next 	= NULL;
+    menu->firstItem->prev 	= NULL;
+    menu->firstItem->child 	= NULL;
+    menu->firstItem->parent 	= NULL;
+    menu->firstItem->item_flags	= 0;
+    menu->firstItem->item_id 	= 0;
+    menu->firstItem->item_text 	= NULL;
+    menu->firstItem->w 		= NULL;
+    menu->firstItem->menu_w 	= NULL;
+
+    menu->next = firstMenu;
+    firstMenu  = menu;
+    
+    return GlobalHandleFromPointer(menu->firstItem);
+}
diff --git a/widgets.c b/controls/widgets.c
similarity index 100%
rename from widgets.c
rename to controls/widgets.c
diff --git a/gdi-ordinals b/etc/gdi-ordinals
similarity index 100%
rename from gdi-ordinals
rename to etc/gdi-ordinals
diff --git a/kernel-ordinals b/etc/kernel-ordinals
similarity index 100%
rename from kernel-ordinals
rename to etc/kernel-ordinals
diff --git a/user-ordinals b/etc/user-ordinals
similarity index 100%
rename from user-ordinals
rename to etc/user-ordinals
diff --git a/gdi.spec b/gdi.spec
deleted file mode 100644
index 7e5d3ad..0000000
--- a/gdi.spec
+++ /dev/null
@@ -1,9 +0,0 @@
-# $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/heap.c b/heap.c
deleted file mode 100644
index e2aed78..0000000
--- a/heap.c
+++ /dev/null
@@ -1,252 +0,0 @@
-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"
-
-MDESC *LOCAL_FreeList;
-
-/**********************************************************************
- *					HEAP_Init
- */
-void
-HEAP_Init(MDESC **free_list, void *start, int length)
-{
-    *free_list = (MDESC *) start;
-    (*free_list)->prev = NULL;
-    (*free_list)->next = NULL;
-    (*free_list)->length = length - sizeof(MDESC);
-}
-
-/**********************************************************************
- *					HEAP_Alloc
- */
-void *
-HEAP_Alloc(MDESC **free_list, int flags, int bytes)
-{
-    MDESC *m, *m_new;
-    
-#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 = *free_list; m != NULL; m = m->next)
-    {
-	if (m->length >= bytes && m->length < bytes + 4 * sizeof(MDESC))
-	{
-	    break;
-	}
-	else if (m->length > bytes)
-	{
-	    m_new = m + (bytes / sizeof(MDESC)) + 2;
-	    if (m->prev == NULL)
-		*free_list = m_new;
-	    else
-		m->prev->next = m_new;
-	    
-	    if (m->next != NULL)
-		m->next->prev = m_new;
-	    
-	    m_new->next = m->next;
-	    m_new->prev = m->prev;
-	    m_new->length = m->length - ((int) m_new - (int) m);
-	    m->length -= (m_new->length + sizeof(MDESC));
-
-	    m->prev = m;
-	    m->next = m;
-	    if (flags & GLOBAL_FLAGS_ZEROINIT)
-		memset(m + 1, 0, bytes);
-#ifdef DEBUG_HEAP
-	    printf("HeapAlloc: returning %08x\n", (m + 1));
-#endif
-	    return (void *) (m + 1);
-	}
-    }
-
-    if (m != NULL)
-    {
-	if (m->prev == NULL)
-	    *free_list = m->next;
-	else
-	    m->prev->next = m->next;
-	
-	if (m->next != NULL)
-	    m->next->prev = m->prev;
-	
-	m->prev = m;
-	m->next = m;
-	if (flags & GLOBAL_FLAGS_ZEROINIT)
-	    memset(m + 1, 0, bytes);
-#ifdef DEBUG_HEAP
-	printf("HeapAlloc: returning %08x\n", (m + 1));
-#endif
-	return (void *) (m + 1);
-    }
-
-#ifdef DEBUG_HEAP
-    printf("HeapAlloc: returning %08x\n", 0);
-#endif
-    return 0;
-}
-
-/**********************************************************************
- *					HEAP_ReAlloc
- */
-void *
-HEAP_ReAlloc(MDESC **free_list, void *old_block, 
-	     int new_size, unsigned int flags)
-{
-    return 0;
-}
-
-
-/**********************************************************************
- *					HEAP_Free
- */
-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;
-}
-
-/**********************************************************************
- *					HEAP_LocalCompact
- */
-int
-HEAP_LocalCompact(int min_free)
-{
-    MDESC *m;
-    int max_block;
-    
-    max_block = 0;
-    for (m = LOCAL_FreeList; m != NULL; m = m->next)
-	if (m->length > max_block)
-	    max_block = m->length;
-    
-    return max_block;
-}
diff --git a/if1632/Makefile b/if1632/Makefile
new file mode 100644
index 0000000..1f12d6c
--- /dev/null
+++ b/if1632/Makefile
@@ -0,0 +1,43 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+BUILDOBJS=dll_kernel.o dll_user.o dll_gdi.o dll_unixlib.o \
+	  dll_win87em.o dll_shell.o \
+	  dll_kernel_tab.o dll_user_tab.o dll_gdi_tab.o dll_unixlib_tab.o \
+	  dll_win87em_tab.o dll_shell_tab.o
+
+MUST_BE_LINKED_FIRST=call.o $(BUILDOBJS)
+
+OBJS=$(MUST_BE_LINKED_FIRST) callback.o relay.o
+
+default: if1632.o
+
+if1632.o: $(OBJS)
+	$(LD) -r -o if1632.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+dll_kernel.S dll_kernel_tab.c: ../tools/build kernel.spec
+	../tools/build kernel.spec
+
+dll_user.S dll_user_tab.c: ../tools/build user.spec
+	../tools/build user.spec
+
+dll_gdi.S dll_gdi_tab.c: ../tools/build gdi.spec
+	../tools/build gdi.spec
+
+dll_unixlib.S dll_unixlib_tab.c: ../tools/build unixlib.spec
+	../tools/build unixlib.spec
+
+dll_win87em.S dll_win87em_tab.c: ../tools/build win87em.spec
+	../tools/build win87em.spec
+
+dll_shell.S dll_shell_tab.c: ../tools/build shell.spec
+	../tools/build shell.spec
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/if1632.S b/if1632/call.S
similarity index 85%
rename from if1632.S
rename to if1632/call.S
index b971d8a..c5e9e05 100644
--- a/if1632.S
+++ b/if1632/call.S
@@ -35,7 +35,7 @@
 	.word	0
 
 	.text
-
+
 /**********************************************************************
  *	int CallToInit16(unsigned long csip, unsigned long sssp,
  *		     unsigned short ds)
@@ -93,6 +93,7 @@
 	movl	%eax,%esp
 	movw	14(%ebp),%ax
 	movw	%ax,%ss
+	movl	%esp,%eax
 	movl	%eax,%ebp
 
 	/*
@@ -100,7 +101,7 @@
 	 */
 	.byte	0x66
 	lcall	%fs:(%edx)
-
+
 	/*
 	 * Restore old stack and segment registers.
 	 *
@@ -135,7 +136,7 @@
 	.align	2,0x90
 	leave
 	ret
-
+
 /**********************************************************************
  *	int CallTo16(unsigned long csip, unsigned short ds)
  *
@@ -180,7 +181,7 @@
 	movw	%ax,%ds
 	.byte	0x66
 	lcall	%fs:(%edx)
-
+
 	/*
 	 * Restore old stack and segment registers.
 	 *
@@ -217,7 +218,7 @@
 	.align	2,0x90
 	leave
 	ret
-
+
 /**********************************************************************
  *	CallTo32()
  *
@@ -276,7 +277,7 @@
 	pushw	_IF1632_Saved16_esp
 	pushl	%eax
 	call	_DLLRelay
-
+
 	/*
  	 * Restore registers, but do not destroy return value.
 	 */
@@ -321,19 +322,14 @@
 
 	.byte	0x66
 	lret
-
+
 /**********************************************************************
- *	KERNEL_InitTask()
- *
- *	This interface functions is special because it returns all
- *	of its values in registers.  Thus we can't just fall back through
- *	the C functions that called us.  Instead we simply abandon
- *	the 32-bit stack, set up the registers and return.
+ *	ReturnFromRegisterFunc()
  */
-	.globl _KERNEL_InitTask
-_KERNEL_InitTask:
+	.globl _ReturnFromRegisterFunc
+_ReturnFromRegisterFunc:
 	/*
- 	 * Restore stack
+ 	 * Restore 16-bit stack
 	 */
 	movw	_IF1632_Saved16_ss,%ss
 	movl	_IF1632_Saved16_esp,%esp
@@ -349,32 +345,25 @@
 	.align	2,0x90
 	leave
 	/*
-	 * Now we need to ditch the parameter bytes that were left on the
-	 * stack. We do this by effectively popping the number of bytes,
-	 * and the return address, removing the parameters and then putting
-	 * the return address back on the stack.
-	 * Normally this field is filled in by the relevant function in
-	 * the emulation library, since it should know how many bytes to
-	 * expect.
+	 * This leaves us with a stack that has number of arguments,
+	 * the return address, the saved registers, and the return 
+	 * address again.
 	 */
-	popw	%gs:nbytes
-	cmpw	$0,%gs:nbytes
-	je	noargs_2
-	popw	%gs:offset
-	popw	%gs:selector
-	addw	%gs:nbytes,%esp
-	pushw	%gs:selector
-	pushw	%gs:offset
-noargs_2:
+	popw	%ax	/* Throw away the number of arguments */
+	popl	%eax	/* Throw away first copy of return address */
+	popw	%es
+	popw	%ds
+	popw	%di
+	popw	%si
+	popw	%bp
+	popw	%ax	/* Throw away pushed stack pointer */
+	popw	%bx
+	popw	%dx
+	popw	%cx
+	popw	%ax
 
 	/*
-	 * Last, we need to load the return values.
+	 * Return to original caller.
 	 */
-	movl	$0,%esi
-	movw	$1,%ax
-	movw	%gs:_WIN_StackSize,%cx
-	movw	$1,%dx
-	movw	0x80,%bx
-
 	.byte	0x66
 	lret
diff --git a/callback.c b/if1632/callback.c
similarity index 78%
rename from callback.c
rename to if1632/callback.c
index c0d82bd..dd5d035 100644
--- a/callback.c
+++ b/if1632/callback.c
@@ -109,6 +109,27 @@
 }
 
 /**********************************************************************
+ *					FreeProcInstance (KERNEL.52)
+ */
+void FreeProcInstance(FARPROC func)
+{
+    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 ((void *) tp->thunk == (void *) func)
+	{
+	    tp->used = 0;
+	    break;
+	}
+    }
+}
+
+/**********************************************************************
  *					CallWindowProc    (USER.122)
  */
 LONG CallWindowProc( FARPROC func, HWND hwnd, WORD message,
@@ -126,3 +147,15 @@
     else
 	return WIDGETS_Call32WndProc( func, hwnd, message, wParam, lParam );
 }
+
+/**********************************************************************
+ *					CallLineDDAProc
+ */
+void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam)
+{
+    PushOn16( CALLBACK_SIZE_WORD, xPos );
+    PushOn16( CALLBACK_SIZE_WORD, yPos );
+    PushOn16( CALLBACK_SIZE_LONG, lParam );
+    CallTo16((unsigned int) func, 
+	     FindDataSegmentForCode((unsigned long) func));   
+}
diff --git a/if1632/findfunc b/if1632/findfunc
new file mode 100755
index 0000000..44eb903
--- /dev/null
+++ b/if1632/findfunc
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+name="blah"
+
+while [ "$name" != "" ]
+do
+    echo -n 'Function: '
+    read name
+    grep -i $name *.spec
+done
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
new file mode 100644
index 0000000..f0810fe
--- /dev/null
+++ b/if1632/gdi.spec
@@ -0,0 +1,170 @@
+# $Id: gdi.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
+#
+name	gdi
+id	3
+length	490
+
+1   pascal SetBkColor(word long) SetBkColor(1 2)
+2   pascal SetBkMode(word word) SetBkMode(1 2)
+3   pascal SetMapMode(word word) SetMapMode(1 2)
+4   pascal SetROP2(word word) SetROP2(1 2)
+5   pascal SetRelAbs(word word) SetRelAbs(1 2)
+6   pascal SetPolyFillMode(word word) SetPolyFillMode(1 2)
+7   pascal SetStretchBltMode(word word) SetStretchBltMode(1 2)
+8   pascal SetTextCharacterExtra(word s_word) SetTextCharacterExtra(1 2)
+9   pascal SetTextColor(word long) SetTextColor(1 2)
+10  pascal SetTextJustification(word s_word s_word) SetTextJustification(1 2 3)
+11  pascal SetWindowOrg(word s_word s_word) SetWindowOrg(1 2 3)
+12  pascal SetWindowExt(word s_word s_word) SetWindowExt(1 2 3)
+13  pascal SetViewportOrg(word s_word s_word) SetViewportOrg(1 2 3)
+14  pascal SetViewportExt(word s_word s_word) SetViewportExt(1 2 3)
+15  pascal OffsetWindowOrg(word s_word s_word) OffsetWindowOrg(1 2 3)
+16  pascal ScaleWindowExt(word s_word s_word s_word s_word)
+	   ScaleWindowExt(1 2 3 4 5)
+17  pascal OffsetViewportOrg(word s_word s_word) OffsetViewportOrg(1 2 3)
+18  pascal ScaleViewportExt(word s_word s_word s_word s_word)
+	   ScaleViewportExt(1 2 3 4 5)
+19  pascal LineTo(word s_word s_word) LineTo(1 2 3)
+20  pascal MoveTo(word s_word s_word) MoveTo(1 2 3)
+21  pascal ExcludeClipRect(word s_word s_word s_word s_word)
+	   ExcludeClipRect(1 2 3 4 5)
+22  pascal IntersectClipRect(word s_word s_word s_word s_word)
+	   IntersectClipRect(1 2 3 4 5)
+23  pascal Arc(word s_word s_word s_word s_word s_word s_word s_word s_word)
+	   Arc(1 2 3 4 5 6 7 8 9)
+24  pascal Ellipse(word s_word s_word s_word s_word) Ellipse(1 2 3 4 5)
+26  pascal Pie(word s_word s_word s_word s_word s_word s_word s_word s_word)
+	   Pie(1 2 3 4 5 6 7 8 9)
+27  pascal Rectangle(word s_word s_word s_word s_word) Rectangle(1 2 3 4 5)
+29  pascal PatBlt(word s_word s_word s_word s_word long) PatBlt(1 2 3 4 5 6)
+30  pascal SaveDC(word) SaveDC(1)
+31  pascal SetPixel(word s_word s_word long) SetPixel(1 2 3 4)
+32  pascal OffsetClipRgn(word s_word s_word) OffsetClipRgn(1 2 3)
+33  pascal TextOut(word s_word s_word ptr word) TextOut(1 2 3 4 5)
+34  pascal BitBlt( word s_word s_word s_word s_word word s_word s_word long)
+	   BitBlt(1 2 3 4 5 6 7 8 9)
+39  pascal RestoreDC(word s_word) RestoreDC(1 2)
+40  pascal FillRgn(word word word) FillRgn(1 2 3)
+43  pascal PaintRgn(word word) PaintRgn(1 2)
+44  pascal SelectClipRgn(word word) SelectClipRgn(1 2)
+45  pascal SelectObject(word word) SelectObject(1 2)
+47  pascal CombineRgn(word word word word) CombineRgn(1 2 3 4)
+48  pascal CreateBitmap(word word word word ptr) CreateBitmap(1 2 3 4 5)
+49  pascal CreateBitmapIndirect(ptr) CreateBitmapIndirect(1)
+50  pascal CreateBrushIndirect(ptr) CreateBrushIndirect(1)
+51  pascal CreateCompatibleBitmap(word word word) CreateCompatibleBitmap(1 2 3)
+52  pascal CreateCompatibleDC(word) CreateCompatibleDC(1)
+53  pascal CreateDC(ptr ptr ptr ptr) CreateDC(1 2 3 4)
+54  pascal CreateEllipticRgn(s_word s_word s_word s_word)
+	   CreateEllipticRgn(1 2 3 4)
+55  pascal CreateEllipticRgnIndirect(ptr) CreateEllipticRgnIndirect(1)
+56  pascal CreateFont(s_word s_word s_word s_word s_word word word word 
+	              word word word word word ptr)
+	   CreateFont(1 2 3 4 5 6 7 8 9 10 11 12 13 14)
+57  pascal CreateFontIndirect(ptr) CreateFontIndirect(1)
+58  pascal CreateHatchBrush(word long) CreateHatchBrush(1 2)
+60  pascal CreatePatternBrush(word) CreatePatternBrush(1)
+61  pascal CreatePen(s_word s_word long) CreatePen(1 2 3)
+62  pascal CreatePenIndirect(ptr) CreatePenIndirect(1)
+63  pascal CreatePolygonRgn(ptr word word) CreatePolygonRgn(1 2 3)
+64  pascal CreateRectRgn(s_word s_word s_word s_word) CreateRectRgn(1 2 3 4)
+65  pascal CreateRectRgnIndirect(ptr) CreateRectRgnIndirect(1)
+66  pascal CreateSolidBrush(long) CreateSolidBrush(1)
+67  pascal DPtoLP(word ptr s_word) DPtoLP(1 2 3)
+68  pascal DeleteDC(word) DeleteDC(1)
+69  pascal DeleteObject(word) DeleteObject(1)
+72  pascal EqualRgn(word word) EqualRgn(1 2)
+73  pascal ExcludeVisRect(word s_word s_word s_word s_word)
+	   ExcludeVisRect(1 2 3 4 5)
+74  pascal GetBitmapBits(word long ptr) GetBitmapBits(1 2 3)
+75  pascal GetBkColor(word) GetBkColor(1)
+76  pascal GetBkMode(word) GetBkMode(1)
+77  pascal GetClipBox(word ptr) GetClipBox(1 2)
+78  pascal GetCurrentPosition(word) GetCurrentPosition(1)
+79  pascal GetDCOrg(word) GetDCOrg(1)
+80  pascal GetDeviceCaps(word s_word) GetDeviceCaps(1 2)
+81  pascal GetMapMode(word) GetMapMode(1)
+82  pascal GetObject(word word ptr) GetObject(1 2 3)
+83  pascal GetPixel(word s_word s_word) GetPixel(1 2 3)
+84  pascal GetPolyFillMode(word) GetPolyFillMode(1)
+85  pascal GetROP2(word) GetROP2(1)
+86  pascal GetRelAbs(word) GetRelAbs(1)
+87  pascal GetStockObject(word) GetStockObject(1)
+88  pascal GetStretchBltMode(word) GetStretchBltMode(1)
+89  pascal GetTextCharacterExtra(word) GetTextCharacterExtra(1)
+90  pascal GetTextColor(word) GetTextColor(1)
+91  pascal GetTextExtent(word ptr s_word) GetTextExtent(1 2 3)
+93  pascal GetTextMetrics(word ptr) GetTextMetrics(1 2)
+94  pascal GetViewportExt(word) GetViewportExt(1)
+95  pascal GetViewportOrg(word) GetViewportOrg(1)
+96  pascal GetWindowExt(word) GetWindowExt(1)
+97  pascal GetWindowOrg(word) GetWindowOrg(1)
+98  pascal IntersectVisRect(word s_word s_word s_word s_word)
+	   IntersectVisRect(1 2 3 4 5)
+99  pascal LPtoDP(word ptr s_word) LPtoDP(1 2 3)
+100 pascal LineDDA(s_word s_word s_word s_word ptr long)
+	   LineDDA(1 2 3 4 5 6)
+101 pascal OffsetRgn(word s_word s_word) OffsetRgn(1 2 3)
+102 pascal OffsetVisRgn(word s_word s_word) OffsetVisRgn(1 2 3)
+103 pascal PtVisible(word s_word s_word) PtVisible(1 2 3)
+104 pascal RectVisibleOld(word ptr) RectVisible(1 2)
+105 pascal SelectVisRgn(word word) SelectVisRgn(1 2)
+106 pascal SetBitmapBits(word long ptr) SetBitmapBits(1 2 3)
+117 pascal SetDCOrg(word s_word s_word) SetDCOrg(1 2 3)
+129 pascal SaveVisRgn(word) SaveVisRgn(1)
+130 pascal RestoreVisRgn(word) RestoreVisRgn(1)
+131 pascal InquireVisRgn(word) InquireVisRgn(1)
+134 pascal GetRgnBox(word ptr) GetRgnBox(1 2)
+148 pascal SetBrushOrg(word s_word s_word) SetBrushOrg(1 2 3)
+149 pascal GetBrushOrg(word) GetBrushOrg(1)
+150 pascal UnrealizeObject(word) UnrealizeObject(1)
+161 pascal PtInRegion(word s_word s_word) PtInRegion(1 2 3)
+162 pascal GetBitmapDimension(word) GetBitmapDimension(1)
+163 pascal SetBitmapDimension(word s_word s_word) SetBitmapDimension(1 2 3)
+172 pascal SetRectRgn(word s_word s_word s_word s_word) SetRectRgn(1 2 3 4 5)
+173 pascal GetClipRgn(word) GetClipRgn(1)
+179 pascal GetDCState(word) GetDCState(1)
+180 pascal SetDCState(word word) SetDCState(1 2)
+181 pascal RectInRegionOld(word ptr) RectInRegion(1 2)
+345 pascal GetTextAlign(word) GetTextAlign(1)
+346 pascal SetTextAlign(word word) SetTextAlign(1 2)
+348 pascal Chord(word s_word s_word s_word s_word s_word s_word s_word s_word)
+	   Chord(1 2 3 4 5 6 7 8 9)
+360 pascal CreatePalette(ptr) CreatePalette(1)
+363 pascal GetPaletteEntries(word word word ptr) GetPaletteEntries(1 2 3 4)
+364 pascal SetPaletteEntries(word word word ptr) SetPaletteEntries(1 2 3 4)
+370 pascal GetNearestPaletteIndex(word long) GetNearestPaletteIndex(1 2)
+411 pascal GetCurLogFont(word) GetCurLogFont(1)
+440 pascal SetDIBits(word word word word ptr ptr word) SetDIBits(1 2 3 4 5 6 7)
+441 pascal GetDIBits(word word word word ptr ptr word) GetDIBits(1 2 3 4 5 6 7)
+442 pascal CreateDIBitmap(word ptr long ptr ptr word)
+	   CreateDIBitmap(1 2 3 4 5 6)
+444 pascal CreateRoundRectRgn(s_word s_word s_word s_word s_word s_word)
+	   CreateRoundRectRgn(1 2 3 4 5 6)
+445 pascal CreateDIBPatternBrush(word word) CreateDIBPatternBrush(1 2)
+451 pascal CreatePolyPolygonRgn(ptr ptr word word)
+	   CreatePolyPolygonRgn(1 2 3 4)
+465 pascal RectVisible(word ptr) RectVisible(1 2)
+466 pascal RectInRegion(word ptr) RectInRegion(1 2)
+468 pascal GetBitmapDimensionEx(word ptr) GetBitmapDimensionEx(1 2)
+469 pascal GetBrushOrgEx(word ptr) GetBrushOrgEx(1 2)
+470 pascal GetCurrentPositionEx(word ptr) GetCurrentPositionEx(1 2)
+471 pascal GetTextExtentPoint(word ptr s_word ptr) GetTextExtentPoint(1 2 3 4)
+472 pascal GetViewportExtEx(word ptr) GetViewportExtEx(1 2)
+473 pascal GetViewportOrgEx(word ptr) GetViewportOrgEx(1 2)
+474 pascal GetWindowExtEx(word ptr) GetWindowExtEx(1 2)
+475 pascal GetWindowOrgEx(word ptr) GetWindowOrgEx(1 2)
+476 pascal OffsetViewportOrgEx(word s_word s_word ptr)
+	   OffsetViewportOrgEx(1 2 3 4)
+477 pascal OffsetWindowOrgEx(word s_word s_word ptr) OffsetWindowOrgEx(1 2 3 4)
+478 pascal SetBitmapDimensionEx(word s_word s_word ptr)
+	   SetBitmapDimensionEx(1 2 3 4)
+479 pascal SetViewportExtEx(word s_word s_word ptr) SetViewportExtEx(1 2 3 4)
+480 pascal SetViewportOrgEx(word s_word s_word ptr) SetViewportOrgEx(1 2 3 4)
+481 pascal SetWindowExtEx(word s_word s_word ptr) SetWindowExtEx(1 2 3 4)
+482 pascal SetWindowOrgEx(word s_word s_word ptr) SetWindowOrgEx(1 2 3 4)
+483 pascal MoveToEx(word s_word s_word ptr) MoveToEx(1 2 3 4)
+484 pascal ScaleViewportExtEx(word s_word s_word s_word s_word ptr)
+	   ScaleViewportExtEx(1 2 3 4 5 6)
+485 pascal ScaleWindowExtEx(word s_word s_word s_word s_word ptr)
+	   ScaleWindowExtEx(1 2 3 4 5 6)
diff --git a/kernel.spec b/if1632/kernel.spec
similarity index 61%
rename from kernel.spec
rename to if1632/kernel.spec
index 382630c..655d8d7 100644
--- a/kernel.spec
+++ b/if1632/kernel.spec
@@ -5,7 +5,17 @@
 length	410
 
 3   return GetVersion 0 0x301
-5   pascal LocalAlloc(word word) HEAP_LocalAlloc(1 2)
+4   pascal LocalInit(word word word) LocalInit(1 2 3)
+5   pascal LocalAlloc(word word) LocalAlloc(1 2)
+6   pascal LocalReAlloc(word word word) LocalReAlloc(1 2 3)
+7   pascal LocalFree(word) LocalFree(1)
+8   pascal LocalLock(word) LocalLock(1)
+9   pascal LocalUnlock(word) LocalUnlock(1)
+10  pascal LocalSize(word) LocalSize(1)
+11  pascal LocalHandle(word) ReturnArg(1)
+12  pascal LocalFlags(word) LocalFlags(1)
+13  pascal LocalCompact(word) LocalCompact(1)
+14  return LocalNotify 4 0
 15  pascal GlobalAlloc(word long) GlobalAlloc(1 2)
 16  pascal GlobalReAlloc(word long word) GlobalReAlloc(1 2 3)
 17  pascal GlobalFree(word) GlobalFree(1)
@@ -19,13 +29,22 @@
 25  pascal GlobalCompact(long) GlobalCompact(1)
 30  pascal WaitEvent(word) KERNEL_WaitEvent(1)
 49  pascal GetModuleFileName(word ptr s_word) KERNEL_GetModuleFileName(1 2 3)
+50  pascal GetProcAddress(word ptr) GetProcAddress(1 2)
 51  pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2)
-91  pascal InitTask() KERNEL_InitTask()
+52  pascal FreeProcInstance(ptr) FreeProcInstance(1)
+91  register InitTask(word word word word word
+		      word word word word word) 
+	     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)
+	     KERNEL_DOS3Call()
 111 pascal GlobalWire(word) GlobalLock(1)
 112 pascal GlobalUnWire(word) GlobalUnlock(1)
+121 return LocalShrink 4 0
+127 pascal GetPrivateProfileInt(ptr ptr s_word ptr)
+	   GetPrivateProfileInt(1 2 3 4)
+128 pascal GetPrivateProfileString(ptr ptr ptr ptr s_word ptr)
+	   GetPrivateProfileString(1 2 3 4 5 6)
 131 pascal GetDOSEnvironment() GetDOSEnvironment()
 132 return GetWinFlags 0 0x413
 154 return GlobalNotify 4 0
diff --git a/relay.c b/if1632/relay.c
similarity index 78%
rename from relay.c
rename to if1632/relay.c
index 2331947..1c8691c 100644
--- a/relay.c
+++ b/if1632/relay.c
@@ -31,6 +31,10 @@
 
 unsigned short *Stack16Frame;
 
+extern unsigned long  IF1632_Saved16_esp;
+extern unsigned long  IF1632_Saved16_ebp;
+extern unsigned short IF1632_Saved16_ss;
+
 /**********************************************************************
  *					DLLRelay
  *
@@ -61,6 +65,7 @@
     void *arg_ptr;
     int (*func_ptr)();
     int i;
+    int ret_val;
     
     /*
      * Determine address of arguments.
@@ -75,18 +80,35 @@
     ordinal = func_num & 0xffff;
     dll_p   = &dll_builtin_table[dll_id].dll_table[ordinal];
 
-#ifdef RELAY_DEBUG
+#ifdef DEBUG_RELAY
     {
 	unsigned int *ret_addr;
 	unsigned short *stack_p;
 	
 	ret_addr = (unsigned int *) ((char *) seg_off + 0x14);
-	printf("RELAY: Calling %s.%d, 16-bit stack at %04x:%04x, ",
+	printf("Calling %s (%s.%d), 16-bit stack at %04x:%04x, ",
+	       dll_p->export_name,
 	       dll_builtin_table[dll_id].dll_name, ordinal,
 	       seg_off >> 16, seg_off & 0xffff);
 	printf("return to %08x\n", *ret_addr);
+	printf("  ESP %08x, EBP %08x, SS %04x\n", 
+	       IF1632_Saved16_esp, IF1632_Saved16_ebp,
+	       IF1632_Saved16_ss);
 
-#ifdef STACK_DEBUG
+	if (strcmp("GetMessage", dll_p->export_name) == 0 &&
+	    seg_off == 0x00972526 &&
+	    *ret_addr == 0x004700cd &&
+	    IF1632_Saved16_esp == 0x2526 &&
+	    IF1632_Saved16_ebp == 0x2534 &&
+	    IF1632_Saved16_ss  == 0x0097)
+	    printf("ACK!!\n");
+
+#if 0
+	IF1632_Saved16_esp &= 0x0000ffff;
+	IF1632_Saved16_ebp &= 0x0000ffff;
+#endif
+
+#ifdef DEBUG_STACK
 	stack_p = (unsigned short *) seg_off;
 	for (i = 0; i < 24; i++, stack_p++)
 	{
@@ -95,9 +117,9 @@
 		printf("\n");
 	}
 	printf("\n");
-#endif /* STACK_DEBUG */
+#endif /* DEBUG_STACK */
     }
-#endif /* RELAY_DEBUG */
+#endif /* DEBUG_RELAY */
 
     /*
      * Make sure we have a handler defined for this call.
@@ -155,12 +177,21 @@
     /*
      * Call the handler
      */
-    return (*func_ptr)(arg_table[0], arg_table[1], arg_table[2], 
-		       arg_table[3], arg_table[4], arg_table[5], 
-		       arg_table[6], arg_table[7], arg_table[8], 
-		       arg_table[9], arg_table[10], arg_table[11],
-		       arg_table[12], arg_table[13], arg_table[14], 
-		       arg_table[15]);
+    ret_val = (*func_ptr)(arg_table[0], arg_table[1], arg_table[2], 
+			  arg_table[3], arg_table[4], arg_table[5], 
+			  arg_table[6], arg_table[7], arg_table[8], 
+			  arg_table[9], arg_table[10], arg_table[11],
+			  arg_table[12], arg_table[13], arg_table[14], 
+			  arg_table[15]);
+
+#ifdef DEBUG_RELAY
+    printf("Returning %08.8x from %s (%s.%d)\n",
+	   ret_val,
+	   dll_p->export_name,
+	   dll_builtin_table[dll_id].dll_name, ordinal);
+#endif
+
+    return ret_val;
 }
 
 /**********************************************************************
diff --git a/shell.spec b/if1632/shell.spec
similarity index 100%
rename from shell.spec
rename to if1632/shell.spec
diff --git a/unixlib.spec b/if1632/unixlib.spec
similarity index 100%
rename from unixlib.spec
rename to if1632/unixlib.spec
diff --git a/if1632/user.spec b/if1632/user.spec
new file mode 100644
index 0000000..575926b
--- /dev/null
+++ b/if1632/user.spec
@@ -0,0 +1,85 @@
+# $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)
+10  pascal SetTimer(word word word ptr) SetTimer(1 2 3 4)
+11  pascal SetSystemTimer(word word word ptr) SetSystemTimer(1 2 3 4)
+12  pascal KillTimer(word word) KillTimer(1 2)
+13  pascal GetTickCount() GetTickCount()
+14  return GetTimerResolution 0 1000
+15  pascal GetCurrentTime() GetTickCount()
+18  pascal SetCapture(word) SetCapture(1)
+19  pascal ReleaseCapture() ReleaseCapture()
+31  pascal IsIconic(word) IsIconic(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 s_word s_word s_word s_word word word word ptr) 
+	   CreateWindow(1 2 3 4 5 6 7 8 9 10 11)
+42  pascal ShowWindow(word word) ShowWindow(1 2)
+53  pascal DestroyWindow(word) DestroyWindow(1)
+57  pascal RegisterClass(ptr) RegisterClass(1)
+66  pascal GetDC(word) GetDC(1)
+68  pascal ReleaseDC(word word) ReleaseDC(1 2)
+72  pascal SetRect(ptr s_word s_word s_word s_word) SetRect(1 2 3 4 5)
+73  pascal SetRectEmpty(ptr) SetRectEmpty(1)
+74  pascal CopyRect(ptr ptr) CopyRect(1 2)
+75  pascal IsRectEmpty(ptr) IsRectEmpty(1)
+76  pascal PtInRect(ptr long) PtInRect(1 2)
+77  pascal OffsetRect(ptr s_word s_word) OffsetRect(1 2 3)
+78  pascal InflateRect(ptr s_word s_word) InflateRect(1 2 3)
+79  pascal IntersectRect(ptr ptr ptr) IntersectRect(1 2 3)
+80  pascal UnionRect(ptr ptr ptr) UnionRect(1 2 3)
+81  pascal FillRect(word ptr word) FillRect(1 2 3)
+82  pascal InvertRect(word ptr) InvertRect(1 2)
+85  pascal DrawText(word ptr s_word ptr word) DrawText(1 2 3 4 5)
+102 pascal AdjustWindowRect(ptr long word) AdjustWindowRect(1 2 3)
+104 pascal MessageBeep(word) MessageBeep(1)
+106 pascal GetKeyState(word) GetKeyState(1)
+107 pascal DefWindowProc(word word word long) DefWindowProc(1 2 3 4)
+108 pascal GetMessage(ptr word word word) GetMessage(1 2 3 4)
+109 pascal PeekMessage(ptr word word word word) PeekMessage(1 2 3 4 5)
+110 pascal PostMessage(word word word long) PostMessage(1 2 3 4)
+111 pascal SendMessage(word word word long) SendMessage(1 2 3 4)
+113 pascal TranslateMessage(ptr) TranslateMessage(1)
+114 pascal DispatchMessage(ptr) DispatchMessage(1)
+118 pascal RegisterWindowMessage(ptr) RegisterWindowMessage(1)
+119 pascal GetMessagePos() GetMessagePos()
+120 pascal GetMessageTime() GetMessageTime()
+124 pascal UpdateWindow(word) UpdateWindow(1)
+125 pascal InvalidateRect(word ptr word) InvalidateRect(1 2 3)
+126 pascal InvalidateRgn(word word word) InvalidateRgn(1 2 3)
+127 pascal ValidateRect(word ptr) ValidateRect(1 2)
+128 pascal ValidateRgn(word word) ValidateRgn(1 2)
+129 pascal GetClassWord(word s_word) GetClassWord(1 2)
+130 pascal SetClassWord(word s_word word) SetClassWord(1 2 3)
+131 pascal GetClassLong(word s_word) GetClassLong(1 2)
+132 pascal SetClassLong(word s_word long) SetClassLong(1 2 3)
+150 pascal LoadMenu(word ptr) LoadMenu(1 2)
+151 pascal CreateMenu() CreateMenu()
+154 pascal CheckMenu(word word word) CheckMenu(1 2 3)
+157 pascal GetMenu(word) GetMenu(1)
+158 pascal SetMenu(word word) SetMenu(1 2)
+173 pascal LoadCursor(word ptr) LoadCursor(1 2)
+174 pascal LoadIcon(word ptr) LoadIcon(1 2)
+175 pascal LoadBitmap(word ptr) LoadBitmap(1 2)
+176 pascal LoadString(word word ptr s_word) LoadString(1 2 3 4)
+179 pascal GetSystemMetrics(word) GetSystemMetrics(1)
+182 pascal KillSystemTimer(word word) KillSystemTimer(1 2)
+190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3)
+237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3)
+244 pascal EqualRect(ptr ptr) EqualRect(1 2)
+266 pascal SetMessageQueue(word) SetMessageQueue(1)
+288 pascal GetMessageExtraInfo() GetMessageExtraInfo()
+324 pascal FillWindow(word word word word) FillWindow(1 2 3 4)
+325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5)
+334 pascal GetQueueStatus(word) GetQueueStatus(1)
+335 pascal GetInputState() GetInputState()
+373 pascal SubtractRect(ptr ptr ptr) SubtractRect(1 2 3)
+403 pascal UnregisterClass(ptr word) UnregisterClass(1 2)
+411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4)
diff --git a/win87em.spec b/if1632/win87em.spec
similarity index 100%
rename from win87em.spec
rename to if1632/win87em.spec
diff --git a/include/bitmaps/check_bitmap b/include/bitmaps/check_bitmap
new file mode 100644
index 0000000..bc76d9f
--- /dev/null
+++ b/include/bitmaps/check_bitmap
@@ -0,0 +1,7 @@
+#define check_bitmap_width 10
+#define check_bitmap_height 10
+#define check_bitmap_x_hot 0
+#define check_bitmap_y_hot 0
+static char check_bitmap_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0xc0, 0x00,
+   0x63, 0x00, 0x36, 0x00, 0x1c, 0x00, 0x08, 0x00};
diff --git a/include/bitmaps/nocheck_bitmap b/include/bitmaps/nocheck_bitmap
new file mode 100644
index 0000000..a56ae35
--- /dev/null
+++ b/include/bitmaps/nocheck_bitmap
@@ -0,0 +1,7 @@
+#define nocheck_bitmap_width 10
+#define nocheck_bitmap_height 10
+#define nocheck_bitmap_x_hot 0
+#define nocheck_bitmap_y_hot 0
+static char nocheck_bitmap_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/callback.h b/include/callback.h
similarity index 100%
rename from callback.h
rename to include/callback.h
diff --git a/class.h b/include/class.h
similarity index 88%
rename from class.h
rename to include/class.h
index 1e7fa2b..f2cc80a 100644
--- a/class.h
+++ b/include/class.h
@@ -11,6 +11,7 @@
 
 #define CLASS_MAGIC   0x4b4e      /* 'NK' */
 
+  /* !! Don't change this structure (see GetClassLong()) */
 typedef struct tagCLASS
 {
     HCLASS       hNext;         /* Next class */
@@ -23,9 +24,6 @@
 } CLASS;
 
 
- /* The caller must GlobalUnlock the pointer returned 
-  * by these functions (except when NULL).
-  */
 HCLASS CLASS_FindClassByName( char * name, CLASS **ptr );
 CLASS * CLASS_FindClassPtr( HCLASS hclass );
 
diff --git a/include/dce.h b/include/dce.h
new file mode 100644
index 0000000..eff58a5
--- /dev/null
+++ b/include/dce.h
@@ -0,0 +1,24 @@
+/*
+ * USER DCE definitions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#ifndef DCE_H
+#define DCE_H
+
+#include "windows.h"
+
+typedef struct tagDCE
+{
+    HANDLE     hNext;
+    HWND       hwndCurrent;
+    HDC        hdc;
+    BYTE       flags;
+    BOOL       inUse;
+    WORD       xOrigin;
+    WORD       yOrigin;
+} DCE;
+
+
+#endif  /* DCE_H */
diff --git a/dlls.h b/include/dlls.h
similarity index 100%
rename from dlls.h
rename to include/dlls.h
diff --git a/include/gdi.h b/include/gdi.h
new file mode 100644
index 0000000..bb5b632
--- /dev/null
+++ b/include/gdi.h
@@ -0,0 +1,287 @@
+/*
+ * GDI definitions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#ifndef GDI_H
+#define GDI_H
+
+#include <X11/Intrinsic.h>
+
+#include "windows.h"
+#include "segmem.h"
+#include "heap.h"
+
+  /* GDI objects magic numbers */
+#define PEN_MAGIC             0x4f47
+#define BRUSH_MAGIC           0x4f48
+#define FONT_MAGIC            0x4f49
+#define PALETTE_MAGIC         0x4f4a
+#define BITMAP_MAGIC          0x4f4b
+#define REGION_MAGIC          0x4f4c
+#define DC_MAGIC              0x4f4d
+#define DISABLED_DC_MAGIC     0x4f4e
+#define META_DC_MAGIC         0x4f4f
+#define METAFILE_MAGIC        0x4f50
+#define METAFILE_DC_MAGIC     0x4f51
+
+
+typedef struct tagREGION
+{
+    WORD        type;
+    RECT        box;
+    Pixmap      pixmap;
+} REGION;
+
+typedef struct tagGDIOBJHDR
+{
+    HANDLE      hNext;
+    WORD        wMagic;
+    DWORD       dwCount;
+    WORD        wMetaList;
+} GDIOBJHDR;
+
+typedef struct tagBRUSHOBJ
+{
+    GDIOBJHDR   header;
+    LOGBRUSH    logbrush __attribute__ ((packed));
+} BRUSHOBJ;
+
+typedef struct tagPENOBJ
+{
+    GDIOBJHDR   header;
+    LOGPEN      logpen __attribute__ ((packed));
+} PENOBJ;
+
+typedef struct tagPALETTEOBJ
+{
+    GDIOBJHDR   header;
+    LOGPALETTE  logpalette __attribute__ ((packed));
+} PALETTEOBJ;
+
+typedef struct tagFONTOBJ
+{
+    GDIOBJHDR   header;
+    LOGFONT     logfont __attribute__ ((packed));
+} FONTOBJ;
+
+typedef struct tagBITMAPOBJ
+{
+    GDIOBJHDR   header;
+    HANDLE      hBitmap;
+    BOOL        bSelected;
+    HDC         hdc;
+    SIZE        size;
+} BITMAPOBJ;
+
+typedef struct tagRGNOBJ
+{
+    GDIOBJHDR   header;
+    REGION      region;
+} RGNOBJ;
+
+typedef struct
+{
+    WORD   version;       /*   0: driver version */
+    WORD   technology;    /*   2: device technology */
+    WORD   horzSize;      /*   4: width of display in mm */
+    WORD   vertSize;      /*   6: height of display in mm */
+    WORD   horzRes;       /*   8: width of display in pixels */
+    WORD   vertRes;       /*  10: width of display in pixels */
+    WORD   bitsPixel;     /*  12: bits per pixel */
+    WORD   planes;        /*  14: color planes */
+    WORD   numBrushes;    /*  16: device-specific brushes */
+    WORD   numPens;       /*  18: device-specific pens */
+    WORD   numMarkers;    /*  20: device-specific markers */
+    WORD   numFonts;      /*  22: device-specific fonts */
+    WORD   numColors;     /*  24: size of color table */
+    WORD   pdeviceSize;   /*  26: size of PDEVICE structure */
+    WORD   curveCaps;     /*  28: curve capabilities */
+    WORD   lineCaps;      /*  30: line capabilities */
+    WORD   polygonalCaps; /*  32: polygon capabilities */
+    WORD   textCaps;      /*  34: text capabilities */
+    WORD   clipCaps;      /*  36: clipping capabilities */
+    WORD   rasterCaps;    /*  38: raster capabilities */
+    WORD   aspectX;       /*  40: relative width of device pixel */
+    WORD   aspectY;       /*  42: relative height of device pixel */
+    WORD   aspectXY;      /*  44: relative diagonal width of device pixel */
+    WORD   pad1[21];      /*  46-86: reserved */
+    WORD   logPixelsX;    /*  88: pixels / logical X inch */
+    WORD   logPixelsY;    /*  90: pixels / logical Y inch */
+    WORD   pad2[6];       /*  92-102: reserved */
+    WORD   sizePalette;   /* 104: entries in system palette */
+    WORD   numReserved;   /* 106: reserved entries */
+    WORD   colorRes;      /* 108: color resolution */    
+} DeviceCaps;
+
+
+  /* Device independent DC information */
+typedef struct
+{
+    int           flags;
+    DeviceCaps   *devCaps;
+
+    HANDLE        hMetaFile;
+    HRGN          hClipRgn;     /* Clip region */
+    HRGN          hVisRgn;      /* Visible region */
+    HRGN          hGCClipRgn;   /* GC clip region (ClipRgn AND VisRgn) */
+    HPEN          hPen;
+    HBRUSH        hBrush;
+    HFONT         hFont;
+    HBITMAP       hBitmap;
+    HANDLE        hDevice;
+    HPALETTE      hPalette;
+
+    WORD          ROPmode;
+    WORD          polyFillMode;
+    WORD          stretchBltMode;
+    WORD          relAbsMode;
+    WORD          backgroundMode;
+    COLORREF      backgroundColor;
+    COLORREF      textColor;
+    int           backgroundPixel;
+    int           textPixel;
+    short         brushOrgX;
+    short         brushOrgY;
+
+    WORD          textAlign;         /* Text alignment from SetTextAlign() */
+    short         charExtra;         /* Spacing from SetTextCharacterExtra() */
+    short         breakTotalExtra;   /* Total extra space for justification */
+    short         breakCount;        /* Break char. count */
+    short         breakExtra;        /* breakTotalExtra / breakCount */
+    short         breakRem;          /* breakTotalExtra % breakCount */
+
+    BYTE          planes;
+    BYTE          bitsPerPixel;
+
+    WORD          MapMode;
+    short         DCOrgX;            /* DC origin */
+    short         DCOrgY;
+    short         CursPosX;          /* Current position */
+    short         CursPosY;
+    short         WndOrgX;
+    short         WndOrgY;
+    short         WndExtX;
+    short         WndExtY;
+    short         VportOrgX;
+    short         VportOrgY;
+    short         VportExtX;
+    short         VportExtY;
+} WIN_DC_INFO;
+
+
+  /* X physical pen */
+typedef struct
+{
+    int          style;
+    int          pixel;
+    int          width;
+} X_PHYSPEN;
+
+  /* X physical brush */
+typedef struct
+{
+    int          style;
+    int          fillStyle;
+    int          pixel;
+    Pixmap       pixmap;
+} X_PHYSBRUSH;
+
+  /* X physical font */
+typedef struct
+{
+    XFontStruct * fstruct;
+    TEXTMETRIC    metrics;
+} X_PHYSFONT;
+
+  /* X-specific DC information */
+typedef struct
+{
+    GC            gc;          /* X Window GC */
+    Drawable      drawable;
+    Widget        widget;
+    X_PHYSFONT    font;
+    X_PHYSPEN     pen;
+    X_PHYSBRUSH   brush;
+} X_DC_INFO;
+
+
+typedef struct tagDC
+{
+    GDIOBJHDR     header;
+    WORD          saveLevel;
+    WIN_DC_INFO   w;
+    union
+    {
+	X_DC_INFO x;
+	/* other devices (e.g. printer) */
+    } u;
+} DC;
+
+  /* DC flags */
+#define DC_MEMORY     1   /* It is a memory DC */
+#define DC_SAVED      2   /* It is a saved DC */
+
+  /* Last 32 bytes are reserved for stock object handles */
+#define GDI_HEAP_SIZE               0xffe0  
+
+  /* First handle possible for stock objects (must be >= GDI_HEAP_SIZE) */
+#define FIRST_STOCK_HANDLE          GDI_HEAP_SIZE
+
+  /* Stock objects handles */
+
+#define STOCK_WHITE_BRUSH	    (FIRST_STOCK_HANDLE + WHITE_BRUSH)
+#define STOCK_LTGRAY_BRUSH	    (FIRST_STOCK_HANDLE + LTGRAY_BRUSH)
+#define STOCK_GRAY_BRUSH	    (FIRST_STOCK_HANDLE + GRAY_BRUSH)
+#define STOCK_DKGRAY_BRUSH	    (FIRST_STOCK_HANDLE + DKGRAY_BRUSH)
+#define STOCK_BLACK_BRUSH	    (FIRST_STOCK_HANDLE + BLACK_BRUSH)
+#define STOCK_NULL_BRUSH	    (FIRST_STOCK_HANDLE + NULL_BRUSH)
+#define STOCK_HOLLOW_BRUSH	    (FIRST_STOCK_HANDLE + HOLLOW_BRUSH)
+#define STOCK_WHITE_PEN	            (FIRST_STOCK_HANDLE + WHITE_PEN)
+#define STOCK_BLACK_PEN	            (FIRST_STOCK_HANDLE + BLACK_PEN)
+#define STOCK_NULL_PEN	            (FIRST_STOCK_HANDLE + NULL_PEN)
+#define STOCK_OEM_FIXED_FONT	    (FIRST_STOCK_HANDLE + OEM_FIXED_FONT)
+#define STOCK_ANSI_FIXED_FONT       (FIRST_STOCK_HANDLE + ANSI_FIXED_FONT)
+#define STOCK_ANSI_VAR_FONT	    (FIRST_STOCK_HANDLE + ANSI_VAR_FONT)
+#define STOCK_SYSTEM_FONT	    (FIRST_STOCK_HANDLE + SYSTEM_FONT)
+#define STOCK_DEVICE_DEFAULT_FONT   (FIRST_STOCK_HANDLE + DEVICE_DEFAULT_FONT)
+#define STOCK_DEFAULT_PALETTE       (FIRST_STOCK_HANDLE + DEFAULT_PALETTE)
+#define STOCK_SYSTEM_FIXED_FONT     (FIRST_STOCK_HANDLE + SYSTEM_FIXED_FONT)
+
+#define NB_STOCK_OBJECTS            (SYSTEM_FIXED_FONT + 1)
+
+#define FIRST_STOCK_FONT            STOCK_OEM_FIXED_FONT
+#define LAST_STOCK_FONT             STOCK_SYSTEM_FIXED_FONT
+
+
+
+  /* Device <-> logical coords conversion */
+
+#define XDPTOLP(dc,x) \
+(((x)-(dc)->w.VportOrgX) * (dc)->w.WndExtX / (dc)->w.VportExtX+(dc)->w.WndOrgX)
+#define YDPTOLP(dc,y) \
+(((y)-(dc)->w.VportOrgY) * (dc)->w.WndExtY / (dc)->w.VportExtY+(dc)->w.WndOrgY)
+#define XLPTODP(dc,x) \
+(((x)-(dc)->w.WndOrgX) * (dc)->w.VportExtX / (dc)->w.WndExtX+(dc)->w.VportOrgX)
+#define YLPTODP(dc,y) \
+(((y)-(dc)->w.WndOrgY) * (dc)->w.VportExtY / (dc)->w.WndExtY+(dc)->w.VportOrgY)
+
+
+  /* GDI local heap */
+
+extern MDESC *GDI_Heap;
+
+#define GDI_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&GDI_Heap,f,size) & 0xffff)
+#define GDI_HEAP_ADDR(handle) ((void *)(handle | ((int)GDI_Heap & 0xffff0000)))
+#define GDI_HEAP_FREE(handle) (HEAP_Free(&GDI_Heap,GDI_HEAP_ADDR(handle)))
+
+
+extern HANDLE GDI_AllocObject( WORD, WORD );
+extern BOOL GDI_FreeObject( HANDLE );
+extern GDIOBJHDR * GDI_GetObjPtr( HANDLE, WORD );
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+#endif  /* GDI_H */
diff --git a/heap.h b/include/heap.h
similarity index 67%
rename from heap.h
rename to include/heap.h
index d602d84..efbcd0d 100644
--- a/heap.h
+++ b/include/heap.h
@@ -9,13 +9,18 @@
 typedef struct heap_mem_desc_s
 {
     struct heap_mem_desc_s *prev, *next;
-    int   length;
+    unsigned short length;
+    unsigned char  lock;
+    unsigned char  flags;
 } 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);
+extern int  HEAP_Free(MDESC **free_list, void *block);
 extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block, 
 			  int new_size, unsigned int flags);
 
+extern void *GlobalQuickAlloc(int size);
+extern unsigned int GlobalHandleFromPointer(void *block);
+
 #endif /* HEAP_H */
diff --git a/include/menu.h b/include/menu.h
new file mode 100644
index 0000000..15d251a
--- /dev/null
+++ b/include/menu.h
@@ -0,0 +1,67 @@
+/* $Id$
+ *
+ * Menu definitions
+ */
+
+#ifndef MENU_H
+#define MENU_H
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Core.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Box.h>
+
+#include "windows.h"
+
+typedef struct tagMENUITEM
+{
+    struct tagMENUITEM *next;
+    struct tagMENUITEM *prev;
+    struct tagMENUITEM *child;
+    struct tagMENUITEM *parent;
+    WORD	item_flags;
+    WORD	item_id;
+    char       *item_text;
+    Widget	w;
+    Widget	menu_w;
+    char	menu_name[10];
+} MENUITEM;
+
+typedef struct tagMENUBAR
+{
+    struct tagMENUBAR *next;
+    HANDLE	menuDescription;	/* Memory containing menu desc.   */
+    HWND	ownerWnd;		/* Owner window			  */
+    int		nItems;    		/* Number of items on menu	  */
+    Widget	parentWidget;		/* Parent of menu widget	  */
+    Widget	menuBarWidget;		/* Widget to contain menu options */
+    MENUITEM   *firstItem;
+} MENUBAR, *LPMENUBAR;
+
+typedef struct
+{
+    WORD	version;		/* Should be zero		  */
+    WORD	reserved;		/* Must be zero			  */
+} MENU_HEADER;
+
+typedef struct
+{
+    WORD	item_flags;		/* See windows.h		  */
+    char	item_text[1];		/* Text for menu item		  */
+} MENU_POPUPITEM;
+
+typedef struct
+{
+    WORD	item_flags;		/* See windows.h		  */
+    WORD	item_id;		/* Control Id for menu item	  */
+    char	item_text[1];		/* Text for menu item		  */
+} MENU_NORMALITEM;
+
+extern LPMENUBAR MENU_CreateMenuBar(Widget parent, HANDLE instance, 
+				    HWND wnd, char *menu_name, int width);
+extern LPMENUBAR MENU_UseMenu(Widget parent, HANDLE instance, 
+			      HWND wnd, HMENU hmenu, int width);
+
+#endif /* MENU_H */
diff --git a/message.h b/include/message.h
similarity index 100%
rename from message.h
rename to include/message.h
diff --git a/neexe.h b/include/neexe.h
similarity index 97%
rename from neexe.h
rename to include/neexe.h
index 839ac3e..deb99ab 100644
--- a/neexe.h
+++ b/include/neexe.h
@@ -133,7 +133,9 @@
 #define NE_RELTYPE_ORDINAL	1
 #define NE_RELTYPE_NAME		2
 #define NE_RELTYPE_OSFIXUP	3
-
+/* Used by Windows 3.0 programs, like when getting selector to be
+   given to makeprocinst */
+#define NE_RELTYPE_INT1		4
 /*
  * DOS PSP
  */
@@ -151,6 +153,7 @@
     unsigned short pspReserved3[23];
     unsigned char  pspFCB_1[16];
     unsigned char  pspFCB_2[16];
+    unsigned char  pspReserved4[4];
     unsigned char  pspCommandTailCount;
     unsigned char  pspCommandTail[128];
 };
diff --git a/prototypes.h b/include/prototypes.h
similarity index 100%
rename from prototypes.h
rename to include/prototypes.h
diff --git a/include/regfunc.h b/include/regfunc.h
new file mode 100644
index 0000000..263675f
--- /dev/null
+++ b/include/regfunc.h
@@ -0,0 +1,22 @@
+/* $Id$
+ */
+
+#ifndef REGFUNC_H
+#define REGFUNC_H
+
+extern unsigned short *Stack16Frame;
+
+#define _AX	Stack16Frame[21]
+#define _BX	Stack16Frame[18]
+#define _CX	Stack16Frame[20]
+#define _DX	Stack16Frame[19]
+#define _SP	Stack16Frame[17]
+#define _BP	Stack16Frame[16]
+#define _SI	Stack16Frame[15]
+#define _DI	Stack16Frame[14]
+#define _DS	Stack16Frame[13]
+#define _ES	Stack16Frame[12]
+
+extern void ReturnFromRegisterFunc(void);
+
+#endif /* REGFUNC_H */
diff --git a/segmem.h b/include/segmem.h
similarity index 100%
rename from segmem.h
rename to include/segmem.h
diff --git a/include/user.h b/include/user.h
new file mode 100644
index 0000000..3db21d2
--- /dev/null
+++ b/include/user.h
@@ -0,0 +1,21 @@
+/*
+ * USER definitions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#ifndef USER_H
+#define USER_H
+
+#include "segmem.h"
+#include "heap.h"
+
+  /* USER local heap */
+
+extern MDESC *USER_Heap;
+
+#define USER_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&USER_Heap,f,size) & 0xffff)
+#define USER_HEAP_ADDR(handle) ((void *)(handle|((int)USER_Heap & 0xffff0000)))
+#define USER_HEAP_FREE(handle) (HEAP_Free(&USER_Heap,USER_HEAP_ADDR(handle)))
+
+#endif  /* USER_H */
diff --git a/win.h b/include/win.h
similarity index 85%
rename from win.h
rename to include/win.h
index 93162ab..5c7c235 100644
--- a/win.h
+++ b/include/win.h
@@ -12,7 +12,7 @@
 #include <X11/Core.h>
 
 #include "windows.h"
-
+#include "menu.h"
 
 #define WND_MAGIC     0x444e4957  /* 'WIND' */
 
@@ -35,11 +35,17 @@
     HANDLE       hDCE;           /* Window DC Entry (if CS_OWNDC) */
     HMENU        hmenuSystem;    /* System menu */
     WORD         wIDmenu;        /* ID or hmenu (from CreateWindow) */
+    WORD         flags;          /* Misc. flags */
     Widget       shellWidget;    /* For top-level windows */
     Widget       winWidget;      /* For all windows */
+    Widget       compositeWidget;/* For top-level windows */
+    LPMENUBAR	 menuBarPtr;	 /* Menu bar */
     WORD         wExtra[1];      /* Window extra bytes */
 } WND;
 
+  /* WND flags values */
+#define WIN_ERASE_UPDATERGN       1   /* Update region needs erasing */
+
 
  /* The caller must GlobalUnlock the pointer returned 
   * by this function (except when NULL).
diff --git a/windows.h b/include/windows.h
similarity index 61%
rename from windows.h
rename to include/windows.h
index f8ae2be..9d74b29 100644
--- a/windows.h
+++ b/include/windows.h
@@ -29,7 +29,7 @@
 typedef HANDLE LOCALHANDLE;
 typedef char *LPSTR;
 typedef char *NPSTR;
-typedef int *LPINT;
+typedef short *LPINT;
 typedef void *LPVOID;
 typedef long (*FARPROC)();
 typedef int CATCHBUF[9];
@@ -37,7 +37,7 @@
 
 #define TRUE 1
 #define FALSE 0
-#define CW_USEDEFAULT ((int)0x8000)
+#define CW_USEDEFAULT ((short)0x8000)
 #define FAR
 #define NEAR
 #define PASCAL
@@ -62,6 +62,8 @@
 typedef PAINTSTRUCT *NPPAINTSTRUCT;
 typedef PAINTSTRUCT *LPPAINTSTRUCT;
 
+  /* Window classes */
+
 typedef struct {
 	WORD	style;
 	LONG	(*lpfnWndProc)() __attribute__ ((packed));
@@ -72,11 +74,35 @@
 	HBRUSH	hbrBackground;
 	LPSTR	lpszMenuName __attribute__ ((packed));
 	LPSTR   lpszClassName __attribute__ ((packed));
-} WNDCLASS;
+} WNDCLASS, *LPWNDCLASS;
 
-typedef  WNDCLASS * PWNDCLASS;
-typedef  WNDCLASS * NPWNDCLASS;
-typedef  WNDCLASS * LPWNDCLASS;
+#define CS_VREDRAW          0x0001
+#define CS_HREDRAW          0x0002
+#define CS_KEYCVTWINDOW     0x0004
+#define CS_DBLCLKS          0x0008
+#define CS_OWNDC            0x0020
+#define CS_CLASSDC          0x0040
+#define CS_PARENTDC         0x0080
+#define CS_NOKEYCVT         0x0100
+#define CS_NOCLOSE          0x0200
+#define CS_SAVEBITS         0x0800
+#define CS_BYTEALIGNCLIENT  0x1000
+#define CS_BYTEALIGNWINDOW  0x2000
+#define CS_GLOBALCLASS      0x4000
+
+  /* Offsets for GetClassLong() and GetClassWord() */
+#define GCL_MENUNAME        (-8)
+#define GCW_HBRBACKGROUND   (-10)
+#define GCW_HCURSOR         (-12)
+#define GCW_HICON           (-14)
+#define GCW_HMODULE         (-16)
+#define GCW_CBWNDEXTRA      (-18)
+#define GCW_CBCLSEXTRA      (-20)
+#define GCL_WNDPROC         (-24)
+#define GCW_STYLE           (-26)
+#define GCW_ATOM            (-32)
+
+
 
 typedef struct {
     void *    lpCreateParams;
@@ -99,6 +125,13 @@
 typedef POINT *NPPOINT;
 typedef POINT *LPPOINT;
 
+typedef struct 
+{
+    short cx;
+    short cy;
+} SIZE, *LPSIZE;
+
+
 typedef struct tagMSG
 {
   HWND    hwnd;
@@ -111,54 +144,292 @@
 	
 typedef WORD ATOM;
 
+  /* Raster operations */
+
+#define R2_BLACK         1
+#define R2_NOTMERGEPEN   2
+#define R2_MASKNOTPEN    3
+#define R2_NOTCOPYPEN    4
+#define R2_MASKPENNOT    5
+#define R2_NOT           6
+#define R2_XORPEN        7
+#define R2_NOTMASKPEN    8
+#define R2_MASKPEN       9
+#define R2_NOTXORPEN    10
+#define R2_NOP          11
+#define R2_MERGENOTPEN  12
+#define R2_COPYPEN      13
+#define R2_MERGEPENNOT  14
+#define R2_MERGEPEN     15
+#define R2_WHITE        16
+
+#define SRCCOPY         0xcc0020
+#define SRCPAINT        0xee0086
+#define SRCAND          0x8800c6
+#define SRCINVERT       0x660046
+#define SRCERASE        0x440328
+#define NOTSRCCOPY      0x330008
+#define NOTSRCERASE     0x1100a6
+#define MERGECOPY       0xc000ca
+#define MERGEPAINT      0xbb0226
+#define PATCOPY         0xf00021
+#define PATPAINT        0xfb0a09
+#define PATINVERT       0x5a0049
+#define DSTINVERT       0x550009
+#define BLACKNESS       0x000042
+#define WHITENESS       0xff0062
+
+  /* StretchBlt() modes */
+#define BLACKONWHITE         1
+#define WHITEONBLACK         2
+#define COLORONCOLOR	     3
+
+#define STRETCH_ANDSCANS     BLACKONWHITE
+#define STRETCH_ORSCANS      WHITEONBLACK
+#define STRETCH_DELETESCANS  COLORONCOLOR
+
+
+  /* Colors */
+
+typedef DWORD COLORREF;
+
+#define RGB(r,g,b)  ((COLORREF)((r) | ((g) << 8) | ((b) << 16)))
+
+#define GetRValue(rgb)	    ((rgb) & 0xff)
+#define GetGValue(rgb)      (((rgb) >> 8) & 0xff)
+#define GetBValue(rgb)	    (((rgb) >> 16) & 0xff)
+
+#define COLOR_SCROLLBAR		    0
+#define COLOR_BACKGROUND	    1
+#define COLOR_ACTIVECAPTION	    2
+#define COLOR_INACTIVECAPTION	    3
+#define COLOR_MENU		    4
+#define COLOR_WINDOW		    5
+#define COLOR_WINDOWFRAME	    6
+#define COLOR_MENUTEXT		    7
+#define COLOR_WINDOWTEXT	    8
+#define COLOR_CAPTIONTEXT  	    9
+#define COLOR_ACTIVEBORDER	   10
+#define COLOR_INACTIVEBORDER	   11
+#define COLOR_APPWORKSPACE	   12
+#define COLOR_HIGHLIGHT		   13
+#define COLOR_HIGHLIGHTTEXT	   14
+#define COLOR_BTNFACE              15
+#define COLOR_BTNSHADOW            16
+#define COLOR_GRAYTEXT             17
+#define COLOR_BTNTEXT		   18
+#define COLOR_INACTIVECAPTIONTEXT  19
+#define COLOR_BTNHIGHLIGHT         20
+
+  /* WM_CTLCOLOR values */
+#define CTLCOLOR_MSGBOX             0
+#define CTLCOLOR_EDIT               1
+#define CTLCOLOR_LISTBOX            2
+#define CTLCOLOR_BTN                3
+#define CTLCOLOR_DLG                4
+#define CTLCOLOR_SCROLLBAR          5
+#define CTLCOLOR_STATIC             6
+
+  /* Bitmaps */
+
 typedef struct tagBITMAP
 {
-    unsigned short bmType;
-    unsigned short bmWidth;
-    unsigned short bmHeight;
-    unsigned short bmWidthBytes;
-    unsigned char  bmPlanes;
-    unsigned char  bmBitsPixel;
-    unsigned long  bmBits __attribute__ ((packed));
+    short  bmType;
+    short  bmWidth;
+    short  bmHeight;
+    short  bmWidthBytes;
+    BYTE   bmPlanes;
+    BYTE   bmBitsPixel;
+    void * 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;
+  /* Brushes */
+
+typedef struct tagLOGBRUSH
+{ 
+    WORD       lbStyle; 
+    COLORREF   lbColor __attribute__ ((packed));
+    short      lbHatch; 
+} LOGBRUSH, *PLOGBRUSH, *NPLOGBRUSH, *LPLOGBRUSH;
+
+  /* Brush styles */
+#define BS_SOLID	    0
+#define BS_NULL		    1
+#define BS_HOLLOW	    1
+#define BS_HATCHED	    2
+#define BS_PATTERN	    3
+#define BS_INDEXED	    4
+#define	BS_DIBPATTERN	    5
+
+  /* Hatch styles */
+#define HS_HORIZONTAL       0
+#define HS_VERTICAL         1
+#define HS_FDIAGONAL        2
+#define HS_BDIAGONAL        3
+#define HS_CROSS            4
+#define HS_DIAGCROSS        5
+
+  /* Fonts */
 
 #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 tagLOGFONT
+{
+    short lfHeight, lfWidth, lfEscapement, lfOrientation, lfWeight;
+    BYTE lfItalic, lfUnderline, lfStrikeOut, lfCharSet;
+    BYTE lfOutPrecision, lfClipPrecision, lfQuality, lfPitchAndFamily;
+    BYTE lfFaceName[LF_FACESIZE] __attribute__ ((packed));
+} LOGFONT, *PLOGFONT, *NPLOGFONT, *LPLOGFONT;
 
-typedef struct PALETTEENTRY {
+  /* lfWeight values */
+#define FW_DONTCARE	    0
+#define FW_THIN 	    100
+#define FW_EXTRALIGHT	    200
+#define FW_ULTRALIGHT	    200
+#define FW_LIGHT	    300
+#define FW_NORMAL	    400
+#define FW_REGULAR	    400
+#define FW_MEDIUM	    500
+#define FW_SEMIBOLD	    600
+#define FW_DEMIBOLD	    600
+#define FW_BOLD 	    700
+#define FW_EXTRABOLD	    800
+#define FW_ULTRABOLD	    800
+#define FW_HEAVY	    900
+#define FW_BLACK	    900
+
+  /* lfCharSet values */
+#define ANSI_CHARSET	      0
+#define DEFAULT_CHARSET       1
+#define SYMBOL_CHARSET	      2
+#define SHIFTJIS_CHARSET      128
+#define OEM_CHARSET	      255
+
+  /* lfOutPrecision values */
+#define OUT_DEFAULT_PRECIS	0
+#define OUT_STRING_PRECIS	1
+#define OUT_CHARACTER_PRECIS	2
+#define OUT_STROKE_PRECIS	3
+#define OUT_TT_PRECIS		4
+#define OUT_DEVICE_PRECIS	5
+#define OUT_RASTER_PRECIS	6
+#define OUT_TT_ONLY_PRECIS	7
+
+  /* lfClipPrecision values */
+#define CLIP_DEFAULT_PRECIS     0x00
+#define CLIP_CHARACTER_PRECIS   0x01
+#define CLIP_STROKE_PRECIS      0x02
+#define CLIP_MASK		0x0F
+#define CLIP_LH_ANGLES		0x10
+#define CLIP_TT_ALWAYS		0x20
+#define CLIP_EMBEDDED		0x80
+
+  /* lfQuality values */
+#define DEFAULT_QUALITY     0
+#define DRAFT_QUALITY       1
+#define PROOF_QUALITY       2
+
+  /* lfPitchAndFamily pitch values */
+#define DEFAULT_PITCH       0x00
+#define FIXED_PITCH         0x01
+#define VARIABLE_PITCH      0x02
+#define FF_DONTCARE         0x00
+#define FF_ROMAN            0x10
+#define FF_SWISS            0x20
+#define FF_MODERN           0x30
+#define FF_SCRIPT           0x40
+#define FF_DECORATIVE       0x50
+
+typedef struct tagTEXTMETRIC
+{
+    short     tmHeight;
+    short     tmAscent;
+    short     tmDescent;
+    short     tmInternalLeading;
+    short     tmExternalLeading;
+    short     tmAveCharWidth;
+    short     tmMaxCharWidth;
+    short     tmWeight;
+    BYTE      tmItalic;
+    BYTE      tmUnderlined;
+    BYTE      tmStruckOut;
+    BYTE      tmFirstChar;
+    BYTE      tmLastChar;
+    BYTE      tmDefaultChar;
+    BYTE      tmBreakChar;
+    BYTE      tmPitchAndFamily;
+    BYTE      tmCharSet;
+    short     tmOverhang;
+    short     tmDigitizedAspectX;
+    short     tmDigitizedAspectY;
+} TEXTMETRIC, *PTEXTMETRIC, *NPTEXTMETRIC, *LPTEXTMETRIC;
+
+  /* tmPitchAndFamily values */
+#define TMPF_FIXED_PITCH    1
+#define TMPF_VECTOR	    2
+#define TMPF_TRUETYPE	    4
+#define TMPF_DEVICE	    8
+
+  /* Text alignment */
+#define TA_NOUPDATECP       0x00
+#define TA_UPDATECP         0x01
+#define TA_LEFT             0x00
+#define TA_RIGHT            0x02
+#define TA_CENTER           0x06
+#define TA_TOP              0x00
+#define TA_BOTTOM           0x08
+#define TA_BASELINE         0x18
+
+
+typedef struct tagPALETTEENTRY
+{
 	BYTE peRed, peGreen, peBlue, peFlags;
-} PALETTEENTRY;
-typedef PALETTEENTRY *LPPALETTEENTRY;
+} PALETTEENTRY, *LPPALETTEENTRY;
 
-typedef struct { 
-	WORD palVersion, palNumEntries;
-	PALETTEENTRY palPalEntries[1];
-} LOGPALETTE;
-typedef LOGPALETTE *PLOGPALETTE;
-typedef LOGPALETTE *NPLOGPALETTE;
-typedef LOGPALETTE *LPLOGPALETTE;
+typedef struct tagLOGPALETTE
+{ 
+    WORD           palVersion;
+    WORD           palNumEntries;
+    PALETTEENTRY   palPalEntry[1] __attribute__ ((packed));
+} LOGPALETTE, *PLOGPALETTE, *NPLOGPALETTE, *LPLOGPALETTE;
 
-typedef struct { WORD lopnStyle; POINT lopnWidth; DWORD lopnColor; } LOGPEN;
-typedef LOGPEN *PLOGPEN;
-typedef LOGPEN *NPLOGPEN;
-typedef LOGPEN *LPLOGPEN;
+
+  /* Pens */
+
+typedef struct tagLOGPEN
+{
+    WORD     lopnStyle; 
+    POINT    lopnWidth __attribute__ ((packed));
+    COLORREF lopnColor __attribute__ ((packed));
+} LOGPEN, *PLOGPEN, *NPLOGPEN, *LPLOGPEN;
+
+#define PS_SOLID	  0
+#define PS_DASH           1
+#define PS_DOT            2
+#define PS_DASHDOT        3
+#define PS_DASHDOTDOT     4
+#define PS_NULL 	  5
+#define PS_INSIDEFRAME 	  6
+
+  /* Regions */
+
+#define ERROR             0
+#define NULLREGION        1
+#define SIMPLEREGION      2
+#define COMPLEXREGION     3
+
+#define RGN_AND           1
+#define RGN_OR            2
+#define RGN_XOR           3
+#define RGN_DIFF          4
+#define RGN_COPY          5
+
+  /* Polygon modes */
+#define ALTERNATE         1
+#define WINDING           2
 
 typedef struct {
 	DWORD rdSize;
@@ -168,7 +439,185 @@
 typedef METARECORD *NPMETARECORD;
 typedef METARECORD *PMETARECORD;
 
-/* Unimplemented structs */
+  /* Background modes */
+#define TRANSPARENT       1
+#define OPAQUE            2
+
+  /* Map modes */
+#define MM_TEXT		  1
+#define MM_LOMETRIC	  2
+#define MM_HIMETRIC	  3
+#define MM_LOENGLISH	  4
+#define MM_HIENGLISH	  5
+#define MM_TWIPS	  6
+#define MM_ISOTROPIC	  7
+#define MM_ANISOTROPIC	  8
+
+  /* Coordinate modes */
+#define ABSOLUTE          1
+#define RELATIVE          2
+
+  /* Device parameters for GetDeviceCaps() */
+#define DRIVERVERSION     0
+#define TECHNOLOGY        2
+#define HORZSIZE          4
+#define VERTSIZE          6
+#define HORZRES           8
+#define VERTRES           10
+#define BITSPIXEL         12
+#define PLANES            14
+#define NUMBRUSHES        16
+#define NUMPENS           18
+#define NUMMARKERS        20
+#define NUMFONTS          22
+#define NUMCOLORS         24
+#define PDEVICESIZE       26
+#define CURVECAPS         28
+#define LINECAPS          30
+#define POLYGONALCAPS     32
+#define TEXTCAPS          34
+#define CLIPCAPS          36
+#define RASTERCAPS        38
+#define ASPECTX           40
+#define ASPECTY           42
+#define ASPECTXY          44
+#define LOGPIXELSX        88
+#define LOGPIXELSY        90
+#define SIZEPALETTE       104
+#define NUMRESERVED       106
+#define COLORRES          108
+
+/* TECHNOLOGY */
+#define DT_PLOTTER        0
+#define DT_RASDISPLAY     1
+#define DT_RASPRINTER     2
+#define DT_RASCAMERA      3
+#define DT_CHARSTREAM     4
+#define DT_METAFILE       5
+#define DT_DISPFILE       6
+
+/* CURVECAPS */
+#define CC_NONE           0x0000
+#define CC_CIRCLES        0x0001
+#define CC_PIE            0x0002
+#define CC_CHORD          0x0004
+#define CC_ELLIPSES       0x0008
+#define CC_WIDE           0x0010
+#define CC_STYLED         0x0020
+#define CC_WIDESTYLED     0x0040
+#define CC_INTERIORS      0x0080
+#define CC_ROUNDRECT      0x0100
+
+/* LINECAPS */
+#define LC_NONE           0x0000
+#define LC_POLYLINE       0x0002
+#define LC_MARKER         0x0004
+#define LC_POLYMARKER     0x0008
+#define LC_WIDE           0x0010
+#define LC_STYLED         0x0020
+#define LC_WIDESTYLED     0x0040
+#define LC_INTERIORS      0x0080
+
+/* POLYGONALCAPS */
+#define PC_NONE           0x0000
+#define PC_POLYGON        0x0001
+#define PC_RECTANGLE      0x0002
+#define PC_WINDPOLYGON    0x0004
+#define PC_SCANLINE       0x0008
+#define PC_WIDE           0x0010
+#define PC_STYLED         0x0020
+#define PC_WIDESTYLED     0x0040
+#define PC_INTERIORS      0x0080
+
+/* TEXTCAPS */
+#define TC_OP_CHARACTER   0x0001
+#define TC_OP_STROKE      0x0002
+#define TC_CP_STROKE      0x0004
+#define TC_CR_90          0x0008
+#define TC_CR_ANY         0x0010
+#define TC_SF_X_YINDEP    0x0020
+#define TC_SA_DOUBLE      0x0040
+#define TC_SA_INTEGER     0x0080
+#define TC_SA_CONTIN      0x0100
+#define TC_EA_DOUBLE      0x0200
+#define TC_IA_ABLE        0x0400
+#define TC_UA_ABLE        0x0800
+#define TC_SO_ABLE        0x1000
+#define TC_RA_ABLE        0x2000
+#define TC_VA_ABLE        0x4000
+#define TC_RESERVED       0x8000
+
+/* CLIPCAPS */
+#define CP_NONE           0x0000
+#define CP_RECTANGLE      0x0001
+#define CP_REGION         0x0002
+
+/* RASTERCAPS */
+#define RC_NONE           0x0000
+#define RC_BITBLT         0x0001
+#define RC_BANDING        0x0002
+#define RC_SCALING        0x0004
+#define RC_BITMAP64       0x0008
+#define RC_GDI20_OUTPUT   0x0010
+#define RC_GDI20_STATE    0x0020
+#define RC_SAVEBITMAP     0x0040
+#define RC_DI_BITMAP      0x0080
+#define RC_PALETTE        0x0100
+#define RC_DIBTODEV       0x0200
+#define RC_BIGFONT        0x0400
+#define RC_STRETCHBLT     0x0800
+#define RC_FLOODFILL      0x1000
+#define RC_STRETCHDIB     0x2000
+#define RC_OP_DX_OUTPUT   0x4000
+#define RC_DEVBITS        0x8000
+
+  /* GetSystemMetrics() codes */
+#define SM_CXSCREEN	       0
+#define SM_CYSCREEN            1
+#define SM_CXVSCROLL           2
+#define SM_CYHSCROLL	       3
+#define SM_CYCAPTION	       4
+#define SM_CXBORDER	       5
+#define SM_CYBORDER	       6
+#define SM_CXDLGFRAME	       7
+#define SM_CYDLGFRAME	       8
+#define SM_CYVTHUMB	       9
+#define SM_CXHTHUMB	      10
+#define SM_CXICON	      11
+#define SM_CYICON	      12
+#define SM_CXCURSOR	      13
+#define SM_CYCURSOR	      14
+#define SM_CYMENU	      15
+#define SM_CXFULLSCREEN       16
+#define SM_CYFULLSCREEN       17
+#define SM_CYKANJIWINDOW      18
+#define SM_MOUSEPRESENT       19
+#define SM_CYVSCROLL	      20
+#define SM_CXHSCROLL	      21
+#define SM_DEBUG	      22
+#define SM_SWAPBUTTON	      23
+#define SM_RESERVED1	      24
+#define SM_RESERVED2	      25
+#define SM_RESERVED3	      26
+#define SM_RESERVED4	      27
+#define SM_CXMIN	      28
+#define SM_CYMIN	      29
+#define SM_CXSIZE	      30
+#define SM_CYSIZE	      31
+#define SM_CXFRAME	      32
+#define SM_CYFRAME	      33
+#define SM_CXMINTRACK	      34
+#define SM_CYMINTRACK	      35
+#define SM_CXDOUBLECLK        36
+#define SM_CYDOUBLECLK        37
+#define SM_CXICONSPACING      38
+#define SM_CYICONSPACING      39
+#define SM_MENUDROPALIGNMENT  40
+#define SM_PENWINDOWS         41
+#define SM_DBCSENABLED        42
+
+  /* Device-independent bitmaps */
+
 typedef struct { BYTE rgbBlue, rgbGreen, rgbRed, rgbReserved; } RGBQUAD;
 typedef struct { BYTE rgbtBlue, rgbtGreen, rgbtRed; } RGBTRIPLE;
 
@@ -191,6 +640,11 @@
 typedef BITMAPINFOHEADER * NPBITMAPINFOHEADER;
 typedef BITMAPINFOHEADER * PBITMAPINFOHEADER;
 
+  /* biCompression */
+#define BI_RGB           0
+#define BI_RLE8          1
+#define BI_RLE4          2
+
 typedef struct {
 	BITMAPINFOHEADER bmiHeader;
 	RGBQUAD	bmiColors[1];
@@ -208,6 +662,12 @@
     unsigned short bcBitCount;
 } BITMAPCOREHEADER;
 
+#define DIB_RGB_COLORS   0
+#define DIB_PAL_COLORS   1
+#define CBM_INIT         4
+
+
+/* Unimplemented structs */
 typedef struct {
 	BYTE Id;  /* much more .... */
 } DCB;
@@ -216,12 +676,7 @@
 	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 .... */
@@ -249,11 +704,6 @@
 }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)
@@ -274,11 +724,26 @@
 #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 };
+  /* Stock GDI objects for GetStockObject() */
+
+#define WHITE_BRUSH	    0
+#define LTGRAY_BRUSH	    1
+#define GRAY_BRUSH	    2
+#define DKGRAY_BRUSH	    3
+#define BLACK_BRUSH	    4
+#define NULL_BRUSH	    5
+#define HOLLOW_BRUSH	    5
+#define WHITE_PEN	    6
+#define BLACK_PEN	    7
+#define NULL_PEN	    8
+#define OEM_FIXED_FONT	    10
+#define ANSI_FIXED_FONT     11
+#define ANSI_VAR_FONT	    12
+#define SYSTEM_FONT	    13
+#define DEVICE_DEFAULT_FONT 14
+#define DEFAULT_PALETTE     15
+#define SYSTEM_FIXED_FONT   16
+
 
 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, 
@@ -307,6 +772,7 @@
  
 #define WM_COMMAND          0x0111
 #define WM_TIMER	    0x0113
+#define WM_SYSTIMER	    0x0118
 
   /* Mouse messages */
 #define WM_MOUSEMOVE	    0x0200
@@ -349,6 +815,14 @@
 	SW_MAXIMIZE, SW_SHOWNOACTIVATE, SW_SHOW, SW_MINIMIZE,
 	SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_RESTORE };
 
+  /* WM_SIZE message wParam values */
+#define SIZE_RESTORED        0
+#define SIZE_MINIMIZED       1
+#define SIZE_MAXIMIZED       2
+#define SIZE_MAXSHOW         3
+#define SIZE_MAXHIDE         4
+
+
 #define MF_INSERT 0
 #define MF_CHANGE 0x0080
 #define MF_APPEND 0x0100
@@ -374,6 +848,7 @@
 #define MF_SYSMENU 0x2000
 #define MF_HELP 0x4000
 #define MF_MOUSESELECT 0x8000
+#define MF_END 0x0080
 
 #ifndef NOWINOFFSETS
 #define GCW_HBRBACKGROUND (-10)
@@ -432,23 +907,6 @@
 
 #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);
@@ -464,64 +922,18 @@
 #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)
 F(BOOL,GetInputState)
 F(LPSTR,GetDOSEnvironment)
 F(DWORD,GetMessagePos)
 F(LONG,GetMessageTime)
 F(LONG,GetMessageExtraInfo)
-Fa(BOOL,IsCharAlpha,char,ch)
-Fa(BOOL,IsCharAlphaNumeric,char,ch)
-Fa(BOOL,IsCharLower,char,ch)
-Fa(BOOL,IsCharUpper,char,ch)
-Fa(ATOM,RegisterClass,LPWNDCLASS,a) 
-Fa(BOOL,TranslateMessage,LPMSG,a)
-Fa(void,PostQuitMessage,int,a)
-Fa(BOOL,SetMessageQueue,int,a)
-Fa(int,_lclose,int,a)
-Fb(int,_lopen,LPSTR,a,int,b)
-Fa(int,lstrlen,LPSTR,a)
-Fa(LONG,DispatchMessage,LPMSG,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)
-Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b)
-Fc(BOOL,LineTo,HDC,a,int,b,int,c)
-Fc(LONG,_llseek,int,a,long,b,int,c)
-Fc(WORD,_lread,int,a,LPSTR,b,int,c)
-Fc(WORD,_lwrite,int,a,LPSTR,b,int,c)
-Fc(int,FillRect,HDC,a,LPRECT,b,HBRUSH,c)
-Fc(DWORD,MoveTo,HDC,a,int,b,int,c)
-Fd(BOOL,AppendMenu,HMENU,a,WORD,b,WORD,c,LPSTR,d)
-Fd(BOOL,PostMessage,HWND,a,WORD,b,WORD,c,LONG,d)
-Fd(LONG,SendMessage,HWND,a,WORD,b,WORD,c,LONG,d)
-Fd(BOOL,GetMessage,LPMSG,msg,HWND,b,WORD,c,WORD,d)
-Fe(BOOL,Rectangle,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom)
-Fe(int,DrawText,HDC,a,LPSTR,str,int,c,LPRECT,d,WORD,flag)
-Fe(BOOL,PeekMessage,LPMSG,a,HWND,b,WORD,c,WORD,d,WORD,e)
-Fe(LONG,CallWindowProc,FARPROC,a,HWND,b,WORD,c,WORD,d,LONG,e)
-Fi(BOOL,Arc,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
-Fi(BOOL,Chord,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
-Fi(BOOL,Pie,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
-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)
@@ -569,6 +981,19 @@
 F(void,SwitchStackBack)
 F(void,WaitMessage)
 F(void,Yield)
+Fa(BOOL,IsCharAlpha,char,ch)
+Fa(BOOL,IsCharAlphaNumeric,char,ch)
+Fa(BOOL,IsCharLower,char,ch)
+Fa(BOOL,IsCharUpper,char,ch)
+Fa(ATOM,RegisterClass,LPWNDCLASS,a) 
+Fa(BOOL,TranslateMessage,LPMSG,a)
+Fa(void,PostQuitMessage,int,a)
+Fa(BOOL,SetMessageQueue,int,a)
+Fa(int,_lclose,int,a)
+Fb(int,_lopen,LPSTR,a,int,b)
+Fa(int,lstrlen,LPSTR,a)
+Fa(LONG,DispatchMessage,LPMSG,msg)
+Fa(void,UpdateWindow,HWND,a)
 Fa(ATOM,AddAtom,LPSTR,a)
 Fa(ATOM,DeleteAtom,ATOM,a)
 Fa(ATOM,FindAtom,LPSTR,a)
@@ -607,13 +1032,13 @@
 Fa(BYTE,GetTempDrive,BYTE,a)
 Fa(DWORD,GetAspectRatioFilter,HDC,a)
 Fa(DWORD,GetBitmapDimension,HBITMAP,a)
-Fa(DWORD,GetBkColor,HDC,a)
+Fa(COLORREF,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(COLORREF,GetSysColor,short,a)
+Fa(COLORREF,GetTextColor,HDC,a)
 Fa(DWORD,GetViewportExt,HDC,a)
 Fa(DWORD,GetViewportOrg,HDC,a)
 Fa(DWORD,GetWindowExt,HDC,a)
@@ -650,6 +1075,7 @@
 Fa(HCURSOR,SetCursor,HCURSOR,a)
 Fa(HDC,CreateCompatibleDC,HDC,a)
 Fa(HDC,GetDC,HWND,a)
+Fa(HDC,GetDCState,HDC,a)
 Fa(HDC,GetWindowDC,HWND,a)
 Fa(HFONT,CreateFontIndirect,LOGFONT FAR*,a)
 Fa(HMENU,GetMenu,HWND,a)
@@ -658,6 +1084,9 @@
 Fa(HPEN,CreatePenIndirect,LOGPEN FAR*,a)
 Fa(HRGN,CreateEllipticRgnIndirect,LPRECT,a)
 Fa(HRGN,CreateRectRgnIndirect,LPRECT,a)
+Fa(HRGN,GetClipRgn,HDC,a)
+Fa(HRGN,InquireVisRgn,HDC,a)
+Fa(HRGN,SaveVisRgn,HDC,a)
 Fa(HWND,GetLastActivePopup,HWND,a)
 Fa(HWND,GetParent,HWND,a)
 Fa(HWND,GetTopWindow,HWND,a)
@@ -704,24 +1133,26 @@
 Fa(int,CloseComm,int,a)
 Fa(int,CountVoiceNotes,int,a)
 Fa(int,GetAsyncKeyState,int,a)
-Fa(int,GetBkMode,HDC,a)
+Fa(WORD,GetBkMode,HDC,a)
 Fa(int,GetDlgCtrlID,HWND,a)
 Fa(int,GetKeyState,int,a)
 Fa(int,GetKeyboardType,int,a)
-Fa(int,GetMapMode,HDC,a)
+Fa(WORD,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(WORD,GetPolyFillMode,HDC,a)
+Fa(WORD,GetRelAbs,HDC,a)
+Fa(WORD,GetROP2,HDC,a)
+Fa(WORD,GetStretchBltMode,HDC,a)
+Fa(int,GetSystemMetrics,short,a)
 Fa(int,GetWindowTextLength,HWND,a)
+Fa(int,RestoreVisRgn,HDC,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(short,GetTextCharacterExtra,HDC,a)
 Fa(void,BringWindowToTop,HWND,a)
 Fa(void,ClipCursor,LPRECT,a)
 Fa(void,CloseWindow,HWND,a)
@@ -743,6 +1174,19 @@
 Fa(void,SetRectEmpty,LPRECT,a)
 Fa(void,ShowCaret,HWND,a)
 Fa(void,SwapRecording,WORD,a)
+Fb(BOOL,ExitWindows,DWORD,dwReserved,WORD,wReturnCode)
+Fb(BOOL,GetBitmapDimensionEx,HBITMAP,a,LPSIZE,b)
+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)
+Fb(void,SetDCState,HDC,a,HDC,b)
+Fb(BOOL,UnregisterClass,LPSTR,a,HANDLE,b)
 Fb(BOOL,CallMsgFilter,LPMSG,a,int,b)
 Fb(BOOL,ChangeClipboardChain,HWND,a,HWND,b)
 Fb(BOOL,EnableWindow,HWND,a,BOOL,b)
@@ -750,11 +1194,12 @@
 Fb(BOOL,EqualRect,LPRECT,a,LPRECT,b)
 Fb(BOOL,EqualRgn,HRGN,a,HRGN,b)
 Fb(BOOL,FlashWindow,HWND,a,BOOL,b)
+Fb(BOOL,GetBrushOrgEx,HDC,a,LPPOINT,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,KillTimer,HWND,a,WORD,b)
 Fb(BOOL,OemToAnsi,LPSTR,a,LPSTR,b)
 Fb(BOOL,PaintRgn,HDC,a,HRGN,b)
 Fb(BOOL,PlayMetaFile,HDC,a,HANDLE,b)
@@ -762,13 +1207,13 @@
 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,RestoreDC,HDC,a,short,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(DWORD,GetNearestColor,HDC,a,DWORD,b)
-Fb(DWORD,SetBkColor,HDC,a,DWORD,b)
+Fb(DWORD,SetBkColor,HDC,a,COLORREF,b)
 Fb(DWORD,SetMapperFlags,HDC,a,DWORD,b)
 Fb(DWORD,SetTextColor,HDC,a,DWORD,b)
 Fb(FARPROC,GetProcAddress,HANDLE,a,LPSTR,b)
@@ -786,7 +1231,7 @@
 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(HBRUSH,CreateHatchBrush,short,a,COLORREF,b)
 Fb(HCURSOR,LoadCursor,HANDLE,a,LPSTR,b)
 Fb(HICON,LoadIcon,HANDLE,a,LPSTR,b)
 Fb(HMENU,GetSubMenu,HMENU,a,int,b)
@@ -797,21 +1242,26 @@
 Fb(HWND,GetDlgItem,HWND,a,int,b)
 Fb(HWND,GetNextWindow,HWND,a,WORD,b)
 Fb(HWND,GetWindow,HWND,a,WORD,b)
+Fb(BOOL,GetCurrentPositionEx,HDC,a,LPPOINT,b)
+Fb(BOOL,GetViewportExtEx,HDC,a,LPPOINT,b)
+Fb(BOOL,GetViewportOrgEx,HDC,a,LPPOINT,b)
+Fb(BOOL,GetWindowExtEx,HDC,a,LPPOINT,b)
+Fb(BOOL,GetWindowOrgEx,HDC,a,LPPOINT,b)
 Fb(HWND,SetParent,HWND,a,HWND,b)
-Fb(LONG,GetClassLong,HWND,a,int,b)
-Fb(LONG,GetWindowLong,HWND,a,int,b)
+Fb(LONG,GetClassLong,HWND,a,short,b)
+Fb(LONG,GetWindowLong,HWND,a,short,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,GetClassWord,HWND,a,short,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,GetWindowWord,HWND,a,short,b)
 Fb(WORD,GetWindowsDirectory,LPSTR,a,WORD,b)
 Fb(WORD,IsDlgButtonChecked,HWND,a,int,b)
 Fb(WORD,LocalShrink,HANDLE,a,WORD,b)
@@ -824,7 +1274,7 @@
 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(void,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)
@@ -832,23 +1282,19 @@
 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,GetDeviceCaps,HDC,a,WORD,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,SelectVisRgn,HDC,a,HRGN,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(short,SetTextCharacterExtra,HDC,a,short,b)
 Fb(void,ClientToScreen,HWND,a,LPPOINT,b)
 Fb(void,DrawFocusRect,HDC,a,LPRECT,b)
 Fb(void,EndDialog,HWND,a,int,b)
@@ -866,6 +1312,12 @@
 Fb(void,Throw,LPCATCHBUF,a,int,b)
 Fb(void,ValidateRect,HWND,a,LPRECT,b)
 Fb(void,ValidateRgn,HWND,a,HRGN,b)
+Fc(BOOL,LineTo,HDC,a,short,b,short,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,short,b,short,c)
 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)
@@ -881,43 +1333,52 @@
 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,PtInRegion,HRGN,a,short,b,short,c)
+Fc(BOOL,PtVisible,HDC,a,short,b,short,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(BOOL,IntersectRect,LPRECT,a,LPRECT,b,LPRECT,c)
+Fc(BOOL,UnionRect,LPRECT,a,LPRECT,b,LPRECT,c)
+Fc(BOOL,SubtractRect,LPRECT,a,LPRECT,b,LPRECT,c)
+Fc(DWORD,GetPixel,HDC,a,short,b,short,c)
+Fc(DWORD,GetTextExtent,HDC,a,LPSTR,b,short,c)
+Fc(DWORD,OffsetViewportOrg,HDC,a,short,b,short,c)
+Fc(DWORD,OffsetWindowOrg,HDC,a,short,b,short,c)
+Fc(DWORD,SetBitmapDimension,HBITMAP,a,short,b,short,c)
+Fc(DWORD,SetBrushOrg,HDC,a,short,b,short,c)
+Fc(DWORD,SetViewportExt,HDC,a,short,b,short,c)
+Fc(DWORD,SetViewportOrg,HDC,a,short,b,short,c)
+Fc(DWORD,SetWindowExt,HDC,a,short,b,short,c)
+Fc(DWORD,SetWindowOrg,HDC,a,short,b,short,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(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c)
+Fc(HBITMAP,CreateDiscardableBitmap,HDC,a,short,b,short,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(HPEN,CreatePen,short,a,short,b,COLORREF,c)
+Fc(HRGN,CreatePolygonRgn,LPPOINT,a,short,b,short,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(LONG,SetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
+Fc(LONG,SetClassLong,HWND,a,short,b,LONG,c)
+Fc(LONG,SetWindowLong,HWND,a,short,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(WORD,SetClassWord,HWND,a,short,b,WORD,c)
+Fc(WORD,SetWindowWord,HWND,a,short,b,WORD,c)
+Fb(WORD,SetBkMode,HDC,a,WORD,b)
+Fb(WORD,SetMapMode,HDC,a,WORD,b)
+Fb(WORD,SetPolyFillMode,HDC,a,WORD,b)
+Fb(WORD,SetRelAbs,HDC,a,WORD,b)
+Fb(WORD,SetROP2,HDC,a,WORD,b)
+Fb(WORD,SetStretchBltMode,HDC,a,WORD,b)
 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)
@@ -929,49 +1390,54 @@
 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,OffsetClipRgn,HDC,a,short,b,short,c)
+Fc(int,OffsetRgn,HRGN,a,short,b,short,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(short,SetTextJustification,HDC,a,short,b,short,c)
+Fc(void,AdjustWindowRect,LPRECT,a,DWORD,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,InflateRect,LPRECT,a,short,b,short,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,OffsetRect,LPRECT,a,short,b,short,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,AppendMenu,HMENU,a,WORD,b,WORD,c,LPSTR,d)
+Fd(BOOL,PostMessage,HWND,a,WORD,b,WORD,c,LONG,d)
+Fd(LONG,SendMessage,HWND,a,WORD,b,WORD,c,LONG,d)
+Fd(BOOL,GetMessage,LPMSG,msg,HWND,b,WORD,c,WORD,d)
+Fd(BOOL,GetTextExtentPoint,HDC,a,LPSTR,b,short,c,LPSIZE,d)
 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,MoveToEx,HDC,a,short,b,short,c,LPPOINT,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,SetBitmapDimensionEx,HBITMAP,a,short,b,short,c,LPSIZE,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(COLORREF,SetPixel,HDC,a,short,b,short,c,COLORREF,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(HRGN,CreateEllipticRgn,short,a,short,b,short,c,short,d)
+Fd(HRGN,CreatePolyPolygonRgn,LPPOINT,a,LPINT,b,short,c,short,d)
+Fd(HRGN,CreateRectRgn,short,a,short,b,short,c,short,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)
@@ -979,11 +1445,17 @@
 Fd(LONG,DefWindowProc,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,GetPrivateProfileInt,LPSTR,a,LPSTR,b,short,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(WORD,SetTimer,HWND,a,WORD,d,WORD,b,FARPROC,c)
+Fd(BOOL,SetViewportExtEx,HDC,a,short,b,short,c,LPSIZE,d)
+Fd(BOOL,SetViewportOrgEx,HDC,a,short,b,short,c,LPPOINT,d)
+Fd(BOOL,SetWindowExtEx,HDC,a,short,b,short,c,LPSIZE,d)
+Fd(BOOL,SetWindowOrgEx,HDC,a,short,b,short,c,LPPOINT,d)
+Fd(BOOL,OffsetViewportOrgEx,HDC,a,short,b,short,c,LPPOINT,d)
+Fd(BOOL,OffsetWindowOrgEx,HDC,a,short,b,short,c,LPPOINT,d)
+Fd(int,CombineRgn,HRGN,a,HRGN,b,HRGN,c,short,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)
@@ -998,9 +1470,14 @@
 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,FillWindow,HWND,a,HWND,b,HDC,c,HBRUSH,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,Rectangle,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom)
+Fe(int,DrawText,HDC,a,LPSTR,str,int,c,LPRECT,d,WORD,flag)
+Fe(BOOL,PeekMessage,LPMSG,a,HWND,b,WORD,c,WORD,d,WORD,e)
+Fe(LONG,CallWindowProc,FARPROC,a,HWND,b,WORD,c,WORD,d,LONG,e)
 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)
@@ -1008,11 +1485,11 @@
 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,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(BOOL,TextOut,HDC,a,short,b,short,c,LPSTR,d,short,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(DWORD,ScaleViewportExt,HDC,a,short,b,short,c,short,d,short,e)
+Fe(DWORD,ScaleWindowExt,HDC,a,short,b,short,c,short,d,short,e)
+Fe(HBITMAP,CreateBitmap,short,a,short,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,DefFrameProc,HWND,a,HWND,b,WORD,c,WORD,d,LONG,e)
@@ -1022,23 +1499,28 @@
 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,ExcludeClipRect,HDC,a,short,b,short,c,short,d,short,e)
+Fe(int,ExcludeVisRect,HDC,a,short,b,short,c,short,d,short,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,IntersectClipRect,HDC,a,short,b,short,c,short,d,short,e)
+Fe(int,IntersectVisRect,HDC,a,short,b,short,c,short,d,short,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,PaintRect,HWND,a,HWND,b,HDC,c,HBRUSH,d,LPRECT,e)
 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,SetRect,LPRECT,a,short,b,short,c,short,d,short,e)
+Fe(void,SetRectRgn,HRGN,a,short,b,short,c,short,d,short,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(BOOL,PatBlt,HDC,a,short,b,short,c,short,d,short,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)
+Ff(HRGN,CreateRoundRectRgn,short,a,short,b,short,c,short,d,short,e,short,f)
+Ff(short,GetPrivateProfileString,LPSTR,a,LPSTR,b,LPSTR,c,LPSTR,d,short,e,LPSTR,f)
+Ff(void,LineDDA,short,a,short,b,short,c,short,d,FARPROC,e,long,f)
+Ff(void,MoveWindow,HWND,a,short,b,short,c,short,d,short,e,BOOL,f)
+Ff(BOOL,ScaleViewportExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f)
+Ff(BOOL,ScaleWindowExtEx,HDC,a,short,b,short,c,short,d,short,e,LPSIZE,f)
+Fg(BOOL,RoundRect,HDC,a,short,b,short,c,short,d,short,e,short,f,short,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)
@@ -1049,10 +1531,14 @@
 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,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,BitBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,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)
+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,short,x,short,y,short,w,short,h,HWND,d,HMENU,e,,HANDLE i,LPSTR,g)
+Fk(BOOL,StretchBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,short,i,short,j,DWORD,k)
+Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,short,e,short,f,short,g,short,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.h b/include/wine.h
similarity index 100%
rename from wine.h
rename to include/wine.h
diff --git a/ldt.tar b/ldt.tar
deleted file mode 100644
index a4c8dde..0000000
--- a/ldt.tar
+++ /dev/null
Binary files differ
diff --git a/ldt512.tar b/ldt512.tar
deleted file mode 100644
index 978751c..0000000
--- a/ldt512.tar
+++ /dev/null
Binary files differ
diff --git a/loader/Makefile b/loader/Makefile
new file mode 100644
index 0000000..a48a749
--- /dev/null
+++ b/loader/Makefile
@@ -0,0 +1,18 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+OBJS=dump.o ldt.o ldtlib.o resource.o selector.o signal.o wine.o
+
+default: loader.o
+
+loader.o: $(OBJS)
+	$(LD) -r -o loader.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/dump.c b/loader/dump.c
similarity index 100%
rename from dump.c
rename to loader/dump.c
diff --git a/ldt.c b/loader/ldt.c
similarity index 100%
rename from ldt.c
rename to loader/ldt.c
diff --git a/ldtlib.c b/loader/ldtlib.c
similarity index 79%
rename from ldtlib.c
rename to loader/ldtlib.c
index af23677..4eeec36 100644
--- a/ldtlib.c
+++ b/loader/ldtlib.c
@@ -8,12 +8,12 @@
 #include <linux/head.h>
 #include <linux/ldt.h>
 
-_syscall2(int, modify_ldt, int, func, void *, ptr)
+_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
 
 int
 get_ldt(void *buffer)
 {
-    return modify_ldt(0, buffer);
+    return modify_ldt(0, buffer, 32 * sizeof(struct modify_ldt_ldt_s));
 }
 
 int
@@ -31,5 +31,5 @@
     ldt_info.read_exec_only = read_only_flag;
     ldt_info.limit_in_pages = limit_in_pages_flag;
 
-    return modify_ldt(1, &ldt_info);
+    return modify_ldt(1, &ldt_info, sizeof(ldt_info));
 }
diff --git a/loader/resource.c b/loader/resource.c
new file mode 100644
index 0000000..f469a48
--- /dev/null
+++ b/loader/resource.c
@@ -0,0 +1,393 @@
+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"
+#include "gdi.h"
+
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+
+/**********************************************************************
+ *					ConvertCoreBitmap
+ */
+HBITMAP
+ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
+{
+    BITMAPINFO * bmpInfo;
+    HBITMAP hbitmap;
+    char * bits;
+    int i, size, n_colors;
+    
+    n_colors = 1 << image->bcBitCount;
+
+    if (image->bcBitCount < 24)
+    {
+	size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);	
+	bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
+    }
+    else
+    {
+	size = sizeof(BITMAPINFOHEADER);
+	bits = (char *) (image + 1);
+    }
+    bmpInfo = (BITMAPINFO *) malloc( size );
+
+    bmpInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
+    bmpInfo->bmiHeader.biWidth         = image->bcWidth;
+    bmpInfo->bmiHeader.biHeight        = image->bcHeight;
+    bmpInfo->bmiHeader.biPlanes        = image->bcPlanes;
+    bmpInfo->bmiHeader.biBitCount      = image->bcBitCount;
+    bmpInfo->bmiHeader.biCompression   = 0;
+    bmpInfo->bmiHeader.biSizeImage     = 0;
+    bmpInfo->bmiHeader.biXPelsPerMeter = 0;
+    bmpInfo->bmiHeader.biYPelsPerMeter = 0;
+    bmpInfo->bmiHeader.biClrUsed       = 0;
+    bmpInfo->bmiHeader.biClrImportant  = 0;
+
+    if (image->bcBitCount < 24)
+    {
+	RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
+	RGBQUAD * newMap = bmpInfo->bmiColors;
+	for (i = 0; i < n_colors; i++, oldMap++, newMap++)
+	{
+	    newMap->rgbRed      = oldMap->rgbtRed;
+	    newMap->rgbGreen    = oldMap->rgbtGreen;
+	    newMap->rgbBlue     = oldMap->rgbtBlue;
+	    newMap->rgbReserved = 0;
+	}
+    }
+
+    hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
+			      bits, bmpInfo, DIB_RGB_COLORS );
+    free( bmpInfo );
+    return hbitmap;
+}
+
+/**********************************************************************
+ *					ConvertInfoBitmap
+ */
+HBITMAP
+ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
+{
+    char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
+    return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
+			   bits, image, DIB_RGB_COLORS );
+} 
+
+/**********************************************************************
+ *					FindResourceByNumber
+ */
+int
+FindResourceByNumber(struct resource_nameinfo_s *result_p,
+		     int type_id, int resource_id)
+{
+    struct resource_typeinfo_s typeinfo;
+    struct resource_nameinfo_s nameinfo;
+    unsigned short size_shift;
+    int i;
+
+    /*
+     * Move to beginning of resource table.
+     */
+    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
+			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
+    
+    /*
+     * Read block size.
+     */
+    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
+	sizeof(size_shift))
+    {
+	return -1;
+    }
+    
+    /*
+     * Find resource.
+     */
+    typeinfo.type_id = 0xffff;
+    while (typeinfo.type_id != 0)
+    {
+	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
+	    sizeof(typeinfo))
+	{
+	    return -1;
+	}
+	if (typeinfo.type_id != 0)
+	{
+	    for (i = 0; i < typeinfo.count; i++)
+	    {
+		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
+		    sizeof(nameinfo))
+		{
+		    return -1;
+		}
+
+#if defined(DEBUG_RESOURCE) && defined(VERBOSE_DEBUG)
+		if (type_id == typeinfo.type_id)
+		{
+		    printf("FindResource: type id = %d, resource id = %x\n",
+			   type_id, nameinfo.id);
+		}
+#endif
+		if ((type_id == -1 || typeinfo.type_id == type_id) &&
+		    nameinfo.id == resource_id)
+		{
+		    memcpy(result_p, &nameinfo, sizeof(nameinfo));
+		    return size_shift;
+		}
+	    }
+	}
+    }
+    
+    return -1;
+}
+
+/**********************************************************************
+ *					FindResourceByName
+ */
+int
+FindResourceByName(struct resource_nameinfo_s *result_p,
+		     int type_id, char *resource_name)
+{
+    struct resource_typeinfo_s typeinfo;
+    struct resource_nameinfo_s nameinfo;
+    unsigned short size_shift;
+    off_t old_pos, new_pos;
+    unsigned char nbytes;
+    char name[256];
+    int i;
+
+    /*
+     * Move to beginning of resource table.
+     */
+    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
+			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
+    
+    /*
+     * Read block size.
+     */
+    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
+	sizeof(size_shift))
+    {
+	return -1;
+    }
+    
+    /*
+     * Find resource.
+     */
+    typeinfo.type_id = 0xffff;
+    while (typeinfo.type_id != 0)
+    {
+	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
+	    sizeof(typeinfo))
+	{
+	    return -1;
+	}
+	if (typeinfo.type_id == type_id || type_id == -1)
+	{
+	    for (i = 0; i < typeinfo.count; i++)
+	    {
+		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
+		    sizeof(nameinfo))
+		{
+		    return -1;
+		}
+
+		if (nameinfo.id & 0x8000)
+		    continue;
+		
+		old_pos = lseek(CurrentNEFile, 0, SEEK_CUR);
+		new_pos = (CurrentMZHeader->ne_offset +
+			   CurrentNEHeader->resource_tab_offset +
+			   nameinfo.id);
+		lseek(CurrentNEFile, new_pos, SEEK_SET);
+		read(CurrentNEFile, &nbytes, 1);
+		read(CurrentNEFile, name, nbytes);
+		lseek(CurrentNEFile, old_pos, SEEK_SET);
+		name[nbytes] = '\0';
+
+		if (strcasecmp(name, resource_name) == 0)
+		{
+		    memcpy(result_p, &nameinfo, sizeof(nameinfo));
+		    return size_shift;
+		}
+	    }
+	}
+    }
+    
+    return -1;
+}
+
+/**********************************************************************
+ *					LoadString
+ */
+int
+LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
+{
+    struct resource_nameinfo_s nameinfo;
+    unsigned short target_id;
+    unsigned char string_length;
+    int size_shift;
+    int string_num;
+    int i;
+
+#ifdef DEBUG_RESOURCE
+    printf("LoadString: instance = %04x, id = %d, "
+	   "buffer = %08x, length = %d\n",
+	   instance, resource_id, buffer, buflen);
+#endif
+    
+    /*
+     * Find string entry.
+     */
+    target_id = (resource_id >> 4) + 0x8001;
+    string_num = resource_id & 0x000f;
+
+    size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_STRING, target_id);
+    if (size_shift == -1)
+	return 0;
+    
+    lseek(CurrentNEFile, (int) nameinfo.offset << size_shift, SEEK_SET);
+
+    for (i = 0; i < string_num; i++)
+    {
+	read(CurrentNEFile, &string_length, 1);
+	lseek(CurrentNEFile, string_length, SEEK_CUR);
+    }
+			
+    read(CurrentNEFile, &string_length, 1);
+    i = MIN(string_length, buflen - 1);
+    read(CurrentNEFile, buffer, i);
+    buffer[i] = '\0';
+#ifdef DEBUG_RESOURCE
+    printf("            '%s'\n", buffer);
+#endif
+    return i;
+}
+
+/**********************************************************************
+ *					LoadIcon
+ */
+HICON
+LoadIcon(HANDLE instance, LPSTR icon_name)
+{
+    return 0;
+}
+
+/**********************************************************************
+ *					LoadCursor
+ */
+HCURSOR
+LoadCursor(HANDLE instance, LPSTR cursor_name)
+{
+    return 0;
+}
+
+/**********************************************************************
+ *					RSC_LoadResource
+ */
+HANDLE
+RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret)
+{
+    struct resource_nameinfo_s nameinfo;
+    HANDLE hmem;
+    void *image;
+    int image_size;
+    int size_shift;
+    
+    /*
+     * Built-in resources
+     */
+    if (instance == 0)
+    {
+	return 0;
+    }
+    /*
+     * Get resource by ordinal
+     */
+    else if (((int) rsc_name & 0xffff0000) == 0)
+    {
+	size_shift = FindResourceByNumber(&nameinfo, type,
+					  (int) rsc_name | 0x8000);
+    }
+    /*
+     * Get resource by name
+     */
+    else
+    {
+	size_shift = FindResourceByName(&nameinfo, type, rsc_name);
+    }
+    if (size_shift == -1)
+	return 0;
+
+    /*
+     * Read resource.
+     */
+    lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
+
+    image_size = nameinfo.length << size_shift;
+    if (image_size_ret != NULL)
+	*image_size_ret = image_size;
+    
+    hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
+    image = GlobalLock(hmem);
+    if (image == NULL || read(CurrentNEFile, image, image_size) != image_size)
+    {
+	GlobalFree(hmem);
+	return 0;
+    }
+
+    GlobalUnlock(hmem);
+    return hmem;
+}
+
+/**********************************************************************
+ *					RSC_LoadMenu
+ */
+HANDLE
+RSC_LoadMenu(HANDLE instance, LPSTR menu_name)
+{
+    return RSC_LoadResource(instance, menu_name, NE_RSCTYPE_MENU, NULL);
+}
+
+/**********************************************************************
+ *					LoadBitmap
+ */
+HBITMAP
+LoadBitmap(HANDLE instance, LPSTR bmp_name)
+{
+    HBITMAP hbitmap;
+    HANDLE rsc_mem;
+    HDC hdc;
+    long *lp;
+    int image_size;
+
+#ifdef DEBUG_RESOURCE
+    printf("LoadBitmap: instance = %04x, name = %08x\n",
+	   instance, bmp_name);
+#endif
+    
+    if (!(hdc = GetDC( 0 ))) return 0;
+
+    rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP, 
+			       &image_size);
+    lp = (long *) GlobalLock(rsc_mem);
+    if (lp == NULL)
+    {
+	GlobalFree(rsc_mem);
+	return 0;
+    }
+
+    if (*lp == sizeof(BITMAPCOREHEADER))
+	hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
+    else if (*lp == sizeof(BITMAPINFOHEADER))
+	hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
+    else hbitmap = 0;
+
+    GlobalFree(rsc_mem);
+    ReleaseDC( 0, hdc );
+    return hbitmap;
+}
diff --git a/selector.c b/loader/selector.c
similarity index 93%
rename from selector.c
rename to loader/selector.c
index ef52ae7..bff46c5 100644
--- a/selector.c
+++ b/loader/selector.c
@@ -27,10 +27,13 @@
 unsigned char ran_out = 0;
 unsigned short SelectorOwners[MAX_SELECTORS];
 
-static int next_unused_selector = 0;
+static int next_unused_selector = 8;
 extern void KERNEL_Ordinal_102();
 extern void UNIXLIB_Ordinal_0();
 
+extern char **Argv;
+extern int Argc;
+
 /**********************************************************************
  *					GetNextSegment
  */
@@ -142,7 +145,12 @@
 		j = GetEntryPointFromOrdinal(wpnt, ordinal);
 		*addr  = j & 0xffff;
 		j = j >> 16;
+#if 0
+		/* This seems like it would never work */
 		*sel = wpnt->selector_table[j].selector;
+#else
+		*sel = j;  /* Is there any reason this will ever fail?? */
+#endif
 		return 0;
 	};
 	return 1;
@@ -322,6 +330,8 @@
     unsigned short *usp;
     int sel_idx;
     struct segment_descriptor_s * s;
+    char *p1, *p2;
+    int i;
 
     s = (struct segment_descriptor_s *) 
 	    malloc(sizeof(struct segment_descriptor_s));
@@ -355,9 +365,22 @@
     psp->pspCritErrorVector[0] = (unsigned short) UNIXLIB_Ordinal_0;
     psp->pspCritErrorVector[1] = 0x0023;
     psp->pspEnvironment = EnvironmentSelector->selector;
-    psp->pspCommandTailCount = 1;
-    strcpy(psp->pspCommandTail, "\r");
-    
+
+    p1 = psp->pspCommandTail;
+    for (i = 1; i < Argc; i++)
+    {
+	if ((int) ((int) p1 - (int) psp->pspCommandTail) + 
+	    strlen(Argv[i]) > 124)
+	    break;
+	
+	for (p2 = Argv[i]; *p2 != '\0'; )
+	    *p1++ = *p2++;
+	
+	*p1++ = ' ';
+    }
+    *p1++ = '\r';
+    *p1 = '\0';
+    psp->pspCommandTailCount = strlen(psp->pspCommandTail);
 
     /*
      * Create entry in LDT for this segment.
@@ -387,7 +410,7 @@
     int i;
     int status;
     FILE * zfile;
-    int old_length;
+    int old_length, file_image_length;
 
     /*
      * Allocate memory for the table to keep track of all selectors.
@@ -433,7 +456,9 @@
 	    /*
 	     * Image in file, let's just point to the image in memory.
 	     */
-	    s->length    = seg_table[i].seg_data_length;
+	    s->length         = seg_table[i].min_alloc;
+	    file_image_length = seg_table[i].seg_data_length;
+	    if (file_image_length == 0)	file_image_length = 0x10000;
 	}
 
 	if (s->length == 0)
@@ -484,13 +509,13 @@
 	     */
 	    status = lseek(fd, seg_table[i].seg_data_offset * 
 			   (1 << ne_header->align_shift_count), SEEK_SET);
-	    if(read(fd, s->base_addr, old_length) != old_length)
+	    if(read(fd, s->base_addr, file_image_length) != file_image_length)
 		myerror("Unable to read segment from file");
 	}
 	/*
 	 * Create entry in LDT for this segment.
 	 */
-	if (set_ldt_entry(i, (unsigned long) s->base_addr, 
+	if (set_ldt_entry(s->selector >> 3, (unsigned long) s->base_addr, 
 			  (s->length - 1) & 0xffff, 0, 
 			  contents, read_only, 0) < 0)
 	{
diff --git a/loader/signal.c b/loader/signal.c
new file mode 100644
index 0000000..39f4080
--- /dev/null
+++ b/loader/signal.c
@@ -0,0 +1,216 @@
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <syscall.h>
+#include <signal.h>
+#include <errno.h>
+#include <linux/sched.h>
+#include <asm/system.h>
+ 
+extern void ___sig_restore();
+extern void ___masksig_restore();
+
+/* Similar to the sigaction function in libc, except it leaves alone the
+   restorer field */
+
+static int
+wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
+{
+	__asm__("int $0x80":"=a" (sig)
+		:"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
+	if (sig>=0)
+		return 0;
+	errno = -sig;
+	return -1;
+}
+
+char * cstack[4096];
+struct sigaction segv_act;
+
+struct sigcontext_struct {
+	unsigned short gs, __gsh;
+	unsigned short fs, __fsh;
+	unsigned short es, __esh;
+	unsigned short ds, __dsh;
+	unsigned long edi;
+	unsigned long esi;
+	unsigned long ebp;
+	unsigned long esp;
+	unsigned long ebx;
+	unsigned long edx;
+	unsigned long ecx;
+	unsigned long eax;
+	unsigned long trapno;
+	unsigned long err;
+	unsigned long eip;
+	unsigned short cs, __csh;
+	unsigned long eflags;
+	unsigned long esp_at_signal;
+	unsigned short ss, __ssh;
+	unsigned long i387;
+	unsigned long oldmask;
+	unsigned long cr2;
+};
+
+static void
+GetTimeDate(int time_flag, struct sigcontext_struct * context)
+{
+    struct tm *now;
+    time_t ltime;
+    
+    ltime = time(NULL);
+    now = localtime(&ltime);
+    if (time_flag)
+    {
+	 context->ecx = (now->tm_hour << 8) | now->tm_min;
+	 context->edx = now->tm_sec << 8;
+    }
+    else
+    {
+	context->ecx = now->tm_year + 1900;
+	context->edx = ((now->tm_mon + 1) << 8) | now->tm_mday;
+	context->eax &= 0xff00;
+	context->eax |= now->tm_wday;
+    }
+}
+
+/* We handle all int21 calls here.  There is some duplicate code from
+   misc/dos.c that I am unsure how to deal with, since the locations
+   that we store the registers are all different */
+
+static int
+do_int21(struct sigcontext_struct * context){
+	fprintf(stderr,"Doing int21 %x   ", (context->eax >> 8) & 0xff);
+	switch((context->eax >> 8) & 0xff){
+	case 0x30:
+		context->eax = 0x0303;  /* Hey folks, this is DOS V3.3! */
+		context->ebx = 0;
+		context->ecx = 0;
+		break;
+	
+		/* Ignore any attempt to set a segment vector */
+	case 0x25:
+		return 1;
+
+	case 0x35:  /* Return a NULL segment selector - this will bomb
+		       if anyone ever tries to use it */
+		context->es = 0;
+		context->ebx = 0;
+		break;
+		
+	case 0x2a:
+		GetTimeDate(0, context);
+	/* Function does not return */
+		
+	case 0x2c:
+		GetTimeDate(1, context);
+		/* Function does not return */
+
+	case 0x4c:
+		exit(context->eax & 0xff);
+		
+
+	default:
+		fprintf(stderr,"Unable to handle int 0x21 %x\n", context->eax);
+		return 1;
+	};
+	return 1;
+}
+
+static int
+do_int1A(struct sigcontext_struct * context){
+	time_t ltime;
+	int ticks;
+
+	switch((context->eax >> 8) & 0xff){
+	case 0:
+		ltime = time(NULL);
+		ticks = (int) (ltime * HZ);
+		context->ecx = ticks >> 16;
+		context->edx = ticks & 0x0000FFFF;
+		context->eax = 0;  /* No midnight rollover */
+		break;
+	
+	default:
+		fprintf(stderr,"Unable to handle int 0x1A %x\n", context->eax);
+		return 1;
+	};
+	return 1;
+}
+
+static void win_segfault(int signal, struct sigcontext_struct context){
+	unsigned char * instr;
+	unsigned char intno;
+	unsigned int * dump;
+	int i;
+
+	/* First take care of a few preliminaries */
+	if(signal != SIGSEGV) exit(1);
+	if((context.cs & 7) != 7){
+		fprintf(stderr,
+			"Segmentation fault in Wine program (%x:%x)."
+			"  Please debug\n",
+			context.cs, context.eip);
+		goto oops;
+	};
+
+	/*  Now take a look at the actual instruction where the program
+	    bombed */
+	instr = (char *) ((context.cs << 16) | (context.eip & 0xffff));
+
+	if(*instr != 0xcd) {
+		fprintf(stderr,
+			"Unexpected Windows program segfault"
+			" - opcode = %x\n", *instr);
+#if 0
+		return;
+#else
+		goto oops;
+#endif
+	};
+
+	instr++;
+	intno = *instr;
+	switch(intno){
+	case 0x21:
+		if(!do_int21(&context)) goto oops;
+		break;
+	case 0x1A:
+		if(!do_int1A(&context)) goto oops;
+		break;
+	default:
+		fprintf(stderr,"Unexpected Windows interrupt %x\n", intno);
+		goto oops;
+	};
+
+	/* OK, done handling the interrupt */
+
+	context.eip += 2;  /* Bypass the int instruction */
+	return;
+
+ oops:
+	fprintf(stderr,"In win_segfault %x:%x\n", context.cs, context.eip);
+	fprintf(stderr,"Stack: %x:%x\n", context.ss, context.esp_at_signal);
+	dump = (int*) &context;
+	for(i=0; i<22; i++) 
+	{
+	    fprintf(stderr," %8.8x", *dump++);
+	    if ((i % 8) == 7)
+		fprintf(stderr,"\n");
+	}
+	fprintf(stderr,"\n");
+	exit(1);
+}
+
+int
+init_wine_signals(){
+	segv_act.sa_handler = (__sighandler_t) win_segfault;
+	/* Point to the top of the stack, minus 4 just in case, and make
+	   it aligned  */
+	segv_act.sa_restorer = 
+		(void (*)()) (((unsigned int)(cstack + sizeof(cstack) - 4)) & ~3);
+	wine_sigaction(SIGSEGV, &segv_act, NULL);
+}
+
diff --git a/wine.c b/loader/wine.c
similarity index 96%
rename from wine.c
rename to loader/wine.c
index 09d7fc7..9abdfdc 100644
--- a/wine.c
+++ b/loader/wine.c
@@ -18,6 +18,7 @@
 #include "prototypes.h"
 #include "dlls.h"
 #include "wine.h"
+#include "windows.h"
 
 extern int CallToInit16(unsigned long csip, unsigned long sssp, 
 			unsigned short ds);
@@ -52,13 +53,10 @@
 void
 myerror(const char *s)
 {
-    char buffer[200];
-    
-    sprintf(buffer, "%s", Argv[0]);
     if (s == NULL)
-	perror(buffer);
+	perror("wine");
     else
-	fprintf(stderr, "%s: %s\n", buffer, s);
+	fprintf(stderr, "wine: %s\n", s);
 
     exit(1);
 }
@@ -229,8 +227,8 @@
 	int i;
 	int rv;
 	
-	Argc = argc;
-	Argv = argv;
+	Argc = argc - 1;
+	Argv = argv + 1;
 	
 	if (argc < 2)
 	{
@@ -272,6 +270,8 @@
     ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector;
     sp_reg = wine_files->ne_header->sp;
 
+    init_wine_signals();
+
     rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
     printf ("rv = %x\n", rv);
 }
@@ -452,6 +452,7 @@
 	    break;
 	    
 	  case NE_RELTYPE_INTERNAL:
+    	  case NE_RELTYPE_INT1:
 	    if (rep->target1 == 0x00ff)
 	    {
 		address  = GetEntryPointFromOrdinal(wpnt, rep->target2);
@@ -549,3 +550,16 @@
     free(rep1);
     return 0;
 }
+
+/**********************************************************************
+ *					GetProcAddress
+ */
+FARPROC GetProcAddress(HINSTANCE hinstance, char *proc_name)
+{
+    if ((int) proc_name & 0xffff0000)
+	printf("GetProcAddress: %#04x, '%s'\n", hinstance, proc_name);
+    else
+	printf("GetProcAddress: %#04x, %d\n", hinstance, (int) proc_name);
+
+    return NULL;
+}
diff --git a/memory/Makefile b/memory/Makefile
new file mode 100644
index 0000000..1b8c9d8
--- /dev/null
+++ b/memory/Makefile
@@ -0,0 +1,18 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+OBJS=global.o heap.o
+
+default: memory.o
+
+memory.o: $(OBJS)
+	$(LD) -r -o memory.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/global.c b/memory/global.c
similarity index 93%
rename from global.c
rename to memory/global.c
index 0bef480..3edfbbe 100644
--- a/global.c
+++ b/memory/global.c
@@ -220,6 +220,7 @@
 	g->addr = m;
 	g->length = size;
 	g->next = g_prev->next;
+	if (g->next) g->next->prev = g;
 	g->lock_count = 0;
 
 	g_prev->next = g;
@@ -274,7 +275,7 @@
      */
     if (g->sequence == 0)
     {
-	HEAP_Free((MDESC **) (block & 0xffff0000), (void *) block);
+	HEAP_Free((MDESC **) ((int) g->addr & 0xffff0000), (void *) g->addr);
 
 	g->prev->next = g->next;
 	
@@ -677,3 +678,46 @@
      */
     return 0;
 }
+
+/**********************************************************************
+ *					GlobalQuickAlloc
+ */
+void *
+GlobalQuickAlloc(int size)
+{
+    unsigned int hmem;
+    
+    hmem = GlobalAlloc(GLOBAL_FLAGS_MOVEABLE, size);
+    if (hmem == 0)
+	return NULL;
+    else
+	return GlobalLock(hmem);
+}
+
+/**********************************************************************
+ *					GlobalHandleFromPointer
+
+ */
+unsigned int
+GlobalHandleFromPointer(void *block)
+{
+    GDESC *g;
+
+    if (block == NULL)
+	return 0;
+
+    /*
+     * Find GDESC for this block.
+     */
+    for (g = GlobalList; g != NULL; g = g->next)
+	if (g->handle > 0 && g->addr == block)
+	    break;
+
+    if (g == NULL)
+	return 0;
+    else
+	return g->handle;
+}
+
+
+
diff --git a/memory/heap.c b/memory/heap.c
new file mode 100644
index 0000000..e97ce84
--- /dev/null
+++ b/memory/heap.c
@@ -0,0 +1,430 @@
+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"
+
+MDESC *LOCAL_FreeList;
+
+/**********************************************************************
+ *					HEAP_Init
+ */
+void
+HEAP_Init(MDESC **free_list, void *start, int length)
+{
+    *free_list = (MDESC *) start;
+    (*free_list)->prev = NULL;
+    (*free_list)->next = NULL;
+    (*free_list)->length = length - sizeof(MDESC);
+}
+
+/**********************************************************************
+ *					HEAP_Alloc
+ */
+void *
+HEAP_Alloc(MDESC **free_list, int flags, int bytes)
+{
+    MDESC *m, *m_new;
+    
+#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 = *free_list; m != NULL; m = m->next)
+    {
+	if (m->length >= bytes && m->length < bytes + 4 * sizeof(MDESC))
+	{
+	    break;
+	}
+	else if (m->length > bytes)
+	{
+	    m_new = m + (bytes / sizeof(MDESC)) + 2;
+	    if (m->prev == NULL)
+		*free_list = m_new;
+	    else
+		m->prev->next = m_new;
+	    
+	    if (m->next != NULL)
+		m->next->prev = m_new;
+	    
+	    m_new->next = m->next;
+	    m_new->prev = m->prev;
+	    m_new->length = m->length - ((int) m_new - (int) m);
+	    m->length -= (m_new->length + sizeof(MDESC));
+
+	    m->prev = m;
+	    m->next = m;
+	    m->lock = 0;
+	    m->flags = 0;
+	    if (flags & GLOBAL_FLAGS_ZEROINIT)
+		memset(m + 1, 0, bytes);
+#ifdef DEBUG_HEAP
+	    printf("HeapAlloc: returning %08x\n", (m + 1));
+#endif
+	    return (void *) (m + 1);
+	}
+    }
+
+    if (m != NULL)
+    {
+	if (m->prev == NULL)
+	    *free_list = m->next;
+	else
+	    m->prev->next = m->next;
+	
+	if (m->next != NULL)
+	    m->next->prev = m->prev;
+	
+	m->prev = m;
+	m->next = m;
+	m->lock = 0;
+	m->flags = 0;
+	if (flags & GLOBAL_FLAGS_ZEROINIT)
+	    memset(m + 1, 0, bytes);
+#ifdef DEBUG_HEAP
+	printf("HeapAlloc: returning %08x\n", (m + 1));
+#endif
+	return (void *) (m + 1);
+    }
+
+#ifdef DEBUG_HEAP
+    printf("HeapAlloc: returning %08x\n", 0);
+#endif
+    return 0;
+}
+
+/**********************************************************************
+ *					HEAP_ReAlloc
+ */
+void *
+HEAP_ReAlloc(MDESC **free_list, void *old_block, 
+	     int new_size, unsigned int flags)
+{
+    MDESC *m_free;
+    MDESC *m;
+
+    /*
+     * Check validity of block
+     */
+    m = (MDESC *) old_block - 1;
+    if (m->prev != m || m->next != m || 
+	((int) m & 0xffff0000) != ((int) *free_list & 0xffff0000))
+    {
+#ifdef DEBUG_HEAP
+	printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
+	       m, free_list);
+#endif
+	return NULL;
+    }
+    
+    /*
+     * Check for grow block
+     */
+    if (new_size > m->length)
+    {
+	m_free = m + 1 + m->length / sizeof(MDESC);
+	if (m_free->next != m_free || 
+	    m_free->prev != m_free ||
+	    m_free->length + sizeof(MDESC) < new_size)
+	{
+	    void *new_p = HEAP_Alloc(free_list, flags, new_size);
+	    
+	    if (new_p ==NULL)
+		return NULL;
+	    memcpy(new_p, old_block, m->length);
+	    HEAP_Free(free_list, old_block);
+	    return new_p;
+	}
+
+	if (m_free->prev == NULL)
+	    *free_list = m_free->next;
+	else
+	    m_free->prev->next = m_free->next;
+	
+	if (m_free->next != NULL)
+	    m_free->next->prev = m_free->prev;
+	
+	m->length += sizeof(MDESC) + m_free->length;
+	if (flags & GLOBAL_FLAGS_ZEROINIT)
+	    memset(m_free, '\0', sizeof(MDESC) + m_free->length);
+    }
+    
+    /*
+     * Check for shrink block.
+     */
+    if (new_size < m->length - 4 * sizeof(MDESC))
+    {
+	m_free = m + new_size / sizeof(MDESC) + 2;
+	m_free->next = m_free;
+	m_free->prev = m_free;
+	m_free->length = m->length - (int) m_free - (int) m;
+	m->length = (int) m_free - (int) (m + 1);
+	HEAP_Free(free_list, m_free + 1);
+    }
+    
+    return old_block;
+}
+
+
+/**********************************************************************
+ *					HEAP_Free
+ */
+int
+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 -1;
+    }
+
+    /*
+     * 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 -1;
+    }
+	
+    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 -1;
+    }
+
+    /*
+     * 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;
+    }
+
+    return 0;
+}
+
+/**********************************************************************
+ *					HEAP_LocalInit
+ */
+void
+HEAP_LocalInit(void *start, int length)
+{
+    HEAP_Init(&LOCAL_FreeList, start, length);
+}
+
+/**********************************************************************
+ *					LocalAlloc
+ */
+void *
+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;
+}
+
+/**********************************************************************
+ *					LocalCompact
+ */
+int
+LocalCompact(int min_free)
+{
+    MDESC *m;
+    int max_block;
+    
+    max_block = 0;
+    for (m = LOCAL_FreeList; m != NULL; m = m->next)
+	if (m->length > max_block)
+	    max_block = m->length;
+    
+    return max_block;
+}
+
+/**********************************************************************
+ *					LocalFlags
+ */
+unsigned int
+LocalFlags(unsigned int handle)
+{
+    MDESC *m;
+    
+    m = (MDESC *) (((int) LOCAL_FreeList & 0xffff0000) | 
+		   (handle & 0xffff)) - 1;
+    if (m->next != m || m->prev != m)
+	return 0;
+    
+    return m->lock;
+}
+
+/**********************************************************************
+ *					LocalFree
+ */
+unsigned int 
+LocalFree(unsigned int handle)
+{
+    unsigned int addr;
+    
+    addr = ((int) LOCAL_FreeList & 0xffff0000) | (handle & 0xffff);
+    if (HEAP_Free(&LOCAL_FreeList, (void *) addr) < 0)
+	return handle;
+    else
+	return 0;
+}
+
+/**********************************************************************
+ *					LocalInit
+ */
+unsigned int
+LocalInit(unsigned int segment, unsigned int start, unsigned int end)
+{
+    HEAP_Init(&LOCAL_FreeList, 
+	      (void *) ((segment << 16) | start), end - start + 1);
+
+    return segment;
+}
+
+/**********************************************************************
+ *					LocalLock
+ */
+void *
+LocalLock(unsigned int handle)
+{
+    MDESC *m;
+    
+    m = (MDESC *) (((int) LOCAL_FreeList & 0xffff0000) | 
+		   (handle & 0xffff)) - 1;
+    if (m->next != m || m->prev != m)
+	return 0;
+
+    m->lock++;
+    return (void *) (m + 1);
+}
+
+/**********************************************************************
+ *					LocalReAlloc
+ */
+void *
+LocalReAlloc(unsigned int handle, int flags, int bytes)
+{
+    void *m;
+    
+    m = HEAP_ReAlloc(&LOCAL_FreeList, (void *)
+		     (((int) LOCAL_FreeList & 0xffff0000) | (handle & 0xffff)),
+		     bytes, flags);
+	
+    return m;
+}
+
+/**********************************************************************
+ *					LocalSize
+ */
+unsigned int
+LocalSize(unsigned int handle)
+{
+    MDESC *m;
+    
+    m = (MDESC *) (((int) LOCAL_FreeList & 0xffff0000) | 
+		   (handle & 0xffff)) - 1;
+    if (m->next != m || m->prev != m)
+	return 0;
+
+    return m->length;
+}
+
+/**********************************************************************
+ *					LocalUnlock
+ */
+unsigned int
+LocalUnlock(unsigned int handle)
+{
+    MDESC *m;
+    
+    m = (MDESC *) (((int) LOCAL_FreeList & 0xffff0000) | 
+		   (handle & 0xffff)) - 1;
+    if (m->next != m || m->prev != m)
+	return 1;
+
+    if (m->lock > 0)
+	m->lock--;
+
+    return 0;
+}
diff --git a/misc/Makefile b/misc/Makefile
new file mode 100644
index 0000000..4cbfdea
--- /dev/null
+++ b/misc/Makefile
@@ -0,0 +1,18 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+OBJS=dos.o kernel.o user.o xt.o rect.o
+
+default: misc.o
+
+misc.o: $(OBJS)
+	$(LD) -r -o misc.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/misc/dos.c b/misc/dos.c
new file mode 100644
index 0000000..f5f80fc
--- /dev/null
+++ b/misc/dos.c
@@ -0,0 +1,76 @@
+static char RCSId[] = "$Id$";
+static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "prototypes.h"
+#include "regfunc.h"
+
+static void
+GetTimeDate(int time_flag)
+{
+    struct tm *now;
+    time_t ltime;
+    
+    ltime = time(NULL);
+    now = localtime(&ltime);
+    if (time_flag)
+    {
+	_CX = (now->tm_hour << 8) | now->tm_min;
+	_DX = now->tm_sec << 8;
+    }
+    else
+    {
+	_CX = now->tm_year + 1900;
+	_DX = ((now->tm_mon + 1) << 8) | now->tm_mday;
+	_AX &= 0xff00;
+	_AX |= now->tm_wday;
+    }
+#ifdef DEBUG_DOS
+    printf("GetTimeDate: AX = %04x, CX = %04x, DX = %04x\n", _AX, _CX, _DX);
+#endif
+    
+    ReturnFromRegisterFunc();
+    /* Function does not return */
+}
+
+/**********************************************************************
+ *					KERNEL_DOS3Call
+ */
+int
+KERNEL_DOS3Call()
+{
+    switch ((_AX >> 8) & 0xff)
+    {
+      case 0x30:
+	_AX = 0x0303;
+	ReturnFromRegisterFunc();
+	/* Function does not return */
+	
+      case 0x25:
+      case 0x35:
+	return 0;
+
+      case 0x2a:
+	GetTimeDate(0);
+	/* Function does not return */
+	
+      case 0x2c:
+	GetTimeDate(1);
+	/* Function does not return */
+
+      case 0x4c:
+	exit(_AX & 0xff);
+
+      default:
+	fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n",
+		_AX, _BX, _CX, _DX);
+	fprintf(stderr, "     SP %04x, BP %04x, SI %04x, DI %04x\n",
+		_SP, _BP, _SI, _DI);
+	fprintf(stderr, "     DS %04x, ES %04x\n",
+		_DS, _ES);
+    }
+    
+    return 0;
+}
diff --git a/kernel.c b/misc/kernel.c
similarity index 71%
rename from kernel.c
rename to misc/kernel.c
index 13f30c7..cb6aa17 100644
--- a/kernel.c
+++ b/misc/kernel.c
@@ -4,8 +4,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "prototypes.h"
+#include "regfunc.h"
 
-extern unsigned short *Stack16Frame;
+extern unsigned short WIN_StackSize;
 
 /**********************************************************************
  *					KERNEL_LockSegment
@@ -40,6 +41,20 @@
 }
 
 /**********************************************************************
+ *					KERNEL_InitTask
+ */
+KERNEL_InitTask()
+{
+    _BX = 0x81;
+    _AX = 1;
+    _CX = WIN_StackSize;
+    _DX = 1;
+    _SI = 0;
+    ReturnFromRegisterFunc();
+    /* Function does not return */
+}
+
+/**********************************************************************
  *					KERNEL_WaitEvent
  */
 int
@@ -65,34 +80,3 @@
     
     return strlen(filename);
 }
-
-/**********************************************************************
- *					KERNEL_DOS3Call
- */
-int
-KERNEL_DOS3Call(int ax, int cx, int dx, int bx, int sp, int bp,
-		int si, int di, int ds, int es)
-{
-    switch ((ax >> 8) & 0xff)
-    {
-      case 0x30:
-	return 0x0303;
-	
-      case 0x25:
-      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);
-	fprintf(stderr, "     SP %04x, BP %04x, SI %04x, DI %04x\n",
-		sp, bp, si, di);
-	fprintf(stderr, "     DS %04x, ES %04x\n",
-		ds, es);
-    }
-    
-    return 0;
-}
diff --git a/misc/rect.c b/misc/rect.c
new file mode 100644
index 0000000..fb96fd6
--- /dev/null
+++ b/misc/rect.c
@@ -0,0 +1,167 @@
+/*
+ * Rectangle-related functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "windows.h"
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+
+/***********************************************************************
+ *           SetRect    (USER.72)
+ */
+void SetRect( LPRECT rect, short left, short top, short right, short bottom )
+{
+    rect->left   = left;
+    rect->right  = right;
+    rect->top    = top;
+    rect->bottom = bottom;
+}
+
+
+/***********************************************************************
+ *           SetRectEmpty    (USER.73)
+ */
+void SetRectEmpty( LPRECT rect )
+{
+    rect->left = rect->right = rect->top = rect->bottom = 0;
+}
+
+
+/***********************************************************************
+ *           CopyRect    (USER.74)
+ */
+void CopyRect( LPRECT dest, LPRECT src )
+{
+    *dest = *src;
+}
+
+
+/***********************************************************************
+ *           IsRectEmpty    (USER.75)
+ */
+BOOL IsRectEmpty( LPRECT rect )
+{
+    return ((rect->left == rect->right) || (rect->top == rect->bottom));
+}
+
+
+/***********************************************************************
+ *           PtInRect    (USER.76)
+ */
+BOOL PtInRect( LPRECT rect, POINT pt )
+{
+    return ((pt.x >= rect->left) && (pt.x < rect->right) &&
+	    (pt.y >= rect->top) && (pt.y < rect->bottom));
+}
+
+
+/***********************************************************************
+ *           OffsetRect    (USER.77)
+ */
+void OffsetRect( LPRECT rect, short x, short y )
+{
+    rect->left   += x;
+    rect->right  += x;
+    rect->top    += y;
+    rect->bottom += y;    
+}
+
+
+/***********************************************************************
+ *           InflateRect    (USER.78)
+ */
+void InflateRect( LPRECT rect, short x, short y )
+{
+    rect->right  += x;
+    rect->bottom += y;
+}
+
+
+/***********************************************************************
+ *           IntersectRect    (USER.79)
+ */
+BOOL IntersectRect( LPRECT dest, LPRECT src1, LPRECT src2 )
+{
+    if ((src1->left >= src2->right) || (src2->left >= src1->right) ||
+	(src1->top >= src2->bottom) || (src2->top >= src1->bottom))
+    {
+	SetRectEmpty( dest );
+	return FALSE;
+    }
+    dest->left   = MAX( src1->left, src2->left );
+    dest->right  = MIN( src1->right, src2->right );
+    dest->top    = MAX( src1->top, src2->top );
+    dest->bottom = MIN( src1->bottom, src2->bottom );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           UnionRect    (USER.80)
+ */
+BOOL UnionRect( LPRECT dest, LPRECT src1, LPRECT src2 )
+{
+    if (IsRectEmpty(src1))
+    {
+	if (IsRectEmpty(src2))
+	{
+	    SetRectEmpty( dest );
+	    return FALSE;
+	}
+	else *dest = *src2;
+    }
+    else
+    {
+	if (IsRectEmpty(src2)) *dest = *src1;
+	else
+	{
+	    dest->left   = MIN( src1->left, src2->left );
+	    dest->right  = MAX( src1->right, src2->right );
+	    dest->top    = MIN( src1->top, src2->top );
+	    dest->bottom = MAX( src1->bottom, src2->bottom );	    
+	}
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           EqualRect    (USER.244)
+ */
+BOOL EqualRect( LPRECT rect1, LPRECT rect2 )
+{
+    return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
+	    (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
+}
+
+
+/***********************************************************************
+ *           SubtractRect    (USER.373)
+ */
+BOOL SubtractRect( LPRECT dest, LPRECT src1, LPRECT src2 )
+{
+    RECT tmp;
+    *dest = *src1;
+    if (IntersectRect( &tmp, src1, src2 ))
+    {
+	if (EqualRect( &tmp, dest )) SetRectEmpty( src1 );
+	else if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
+	{
+	    if (tmp.left == dest->left) dest->right = tmp.right;
+	    else if (tmp.right == dest->right) dest->left = tmp.left;
+	}
+	else if ((tmp.left == dest->left) && (tmp.right == dest->right))
+	{
+	    if (tmp.top == dest->top) dest->bottom = tmp.bottom;
+	    else if (tmp.bottom == dest->bottom) dest->top = tmp.top;
+	}
+    }
+    return TRUE;
+}
+
diff --git a/misc/user.c b/misc/user.c
new file mode 100644
index 0000000..a75bd42
--- /dev/null
+++ b/misc/user.c
@@ -0,0 +1,56 @@
+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>
+#include <stdlib.h>
+#include "prototypes.h"
+#include "windows.h"
+#include "user.h"
+
+#define DEFAULT_MSG_QUEUE_SIZE  8
+
+#define USER_HEAP_SIZE          0x10000
+
+
+MDESC *USER_Heap = NULL;
+
+
+/***********************************************************************
+ *           USER_HeapInit
+ */
+static BOOL USER_HeapInit()
+{
+    struct segment_descriptor_s * s;
+    s = GetNextSegment( 0, 0x10000 );
+    if (s == NULL) return FALSE;
+    HEAP_Init( &USER_Heap, s->base_addr, USER_HEAP_SIZE );
+    free(s);
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *					USER_InitApp
+ *
+ * Load necessary resources?
+ */
+int
+USER_InitApp(int hInstance)
+{
+      /* GDI initialisation */
+    if (!GDI_Init()) return 0;
+    
+      /* Create USER heap */
+    if (!USER_HeapInit()) return 0;
+    
+      /* Create the DCEs */
+    DCE_Init();
+    
+      /* Initialize built-in window classes */
+    WIDGETS_Init();
+    
+      /* Create task message queue */
+    if (!SetMessageQueue( DEFAULT_MSG_QUEUE_SIZE )) return 0;
+        
+    return 1;
+}
diff --git a/misc/xt.c b/misc/xt.c
new file mode 100644
index 0000000..e407577
--- /dev/null
+++ b/misc/xt.c
@@ -0,0 +1,174 @@
+/*
+ * X toolkit functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <sys/param.h>
+#include <sys/times.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Core.h>
+#include <X11/Shell.h>
+
+#include "message.h"
+#include "callback.h"
+#include "win.h"
+#include "class.h"
+#include "gdi.h"
+
+
+Display * XT_display;
+Screen * XT_screen;
+XtAppContext XT_app_context;
+
+static Widget topLevelWidget;
+
+
+/***********************************************************************
+ *           main
+ */
+void main(int argc, char **argv)
+{    
+    topLevelWidget = XtVaAppInitialize(&XT_app_context,
+				       "XWine",     /* Application class */
+				       NULL, 0,     /* Option list */
+				       &argc, argv, /* Command line args */
+				       NULL,        /* Fallback resources */
+				       NULL );
+    XT_display = XtDisplay( topLevelWidget );
+    XT_screen  = XtScreen( topLevelWidget );
+    
+    _WinMain( argc, argv );
+}
+
+
+/***********************************************************************
+ *           DefWindowProc   (USER.107)
+ */
+LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
+{
+    WND * wndPtr;
+    CLASS * classPtr;
+    
+#ifdef DEBUG_MESSAGE
+    printf( "DefWindowProc: %d %d %d %08x\n", hwnd, msg, wParam, lParam );
+#endif
+
+    switch(msg)
+    {
+    case WM_PAINT:
+	{
+	    PAINTSTRUCT paintstruct;
+	    BeginPaint( hwnd, &paintstruct );
+	    EndPaint( hwnd, &paintstruct );
+	    return 0;
+	}
+
+    case WM_CREATE:
+	return 0;
+
+    case WM_CLOSE:
+	DestroyWindow( hwnd );
+	return 0;
+
+    case WM_ERASEBKGND:
+    case WM_ICONERASEBKGND:
+	{
+	    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 1;
+	    if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 1;
+	    if (!classPtr->wc.hbrBackground) return 1;
+	    FillWindow( wndPtr->hwndParent, hwnd, (HDC)wParam,
+		        classPtr->wc.hbrBackground );
+	    GlobalUnlock( hwnd );
+	    return 0;
+	}
+    }
+    return 0;
+}
+
+
+/********************************************************************
+ *
+ * Miscellaneous partially implemented functions.
+ * 
+ */
+
+
+int MessageBox( HWND hwnd, LPSTR str, LPSTR title, WORD type )
+{
+    printf( "MessageBox: '%s'\n", str );
+}
+
+void MessageBeep( WORD i )
+{
+    printf( "MessageBeep: %d\n", i );
+}
+
+WORD RegisterWindowMessage( LPSTR str )
+{
+    printf( "RegisterWindowMessage: '%s'\n", str );
+    return 0xc000;
+}
+
+/***********************************************************************
+ *           GetTickCount    (USER.13)
+ */
+DWORD GetTickCount()
+{
+    struct tms dummy;
+    return times(&dummy) / (1000 / HZ);
+}
+
+
+int GetSystemMetrics( short index )
+{
+    printf( "GetSystemMetrics: %d\n", index );
+    switch(index)
+    {
+      case SM_CXSCREEN:
+	return DisplayWidth( XT_display, DefaultScreen( XT_display ));
+
+      case SM_CYSCREEN:
+	return DisplayHeight( XT_display, DefaultScreen( XT_display ));
+
+      default:
+	  return 0;
+    }
+}
+
+void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
+{
+    printf( "AdjustWindowRect: (%d,%d)-(%d,%d) %d %d\n", rect->left, rect->top,
+	   rect->right, rect->bottom, style, menu );
+}
+
+WORD GetPrivateProfileInt( LPSTR section, LPSTR entry,
+			   short defval, LPSTR filename )
+{
+    printf( "GetPrivateProfileInt: %s %s %d %s\n", section, entry, defval, filename );
+    return defval;
+}
+
+short GetPrivateProfileString( LPSTR section, LPSTR entry, LPSTR defval,
+			       LPSTR buffer, short count, LPSTR filename )
+{
+    printf( "GetPrivateProfileString: %s %s %s %d %s\n", section, entry, defval, count, filename );
+    strncpy( buffer, defval, count );
+    buffer[count-1] = 0;
+    return strlen(buffer);
+}
+
+BOOL IsIconic( HWND hwnd )
+{
+    printf( "IsIconic: returning FALSE\n" );
+    return FALSE;
+}
+
+HMENU CreateMenu() { }
+
+BOOL AppendMenu( HMENU hmenu, WORD flags, WORD id, LPSTR text ) { }
+
diff --git a/objects/Makefile b/objects/Makefile
new file mode 100644
index 0000000..ad4d119
--- /dev/null
+++ b/objects/Makefile
@@ -0,0 +1,19 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+OBJS=bitmap.o brush.o font.o gdiobj.o palette.o pen.o dib.o region.o \
+	text.o dcvalues.o clipping.o bitblt.o linedda.o
+
+default: objects.o
+
+objects.o: $(OBJS)
+	$(LD) -r -o objects.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/objects/bitblt.c b/objects/bitblt.c
new file mode 100644
index 0000000..53e9ba1
--- /dev/null
+++ b/objects/bitblt.c
@@ -0,0 +1,111 @@
+/*
+ * GDI bit-blit operations
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+
+#include "gdi.h"
+
+extern const int DC_XROPfunction[];
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+
+/***********************************************************************
+ *           PatBlt    (GDI.29)
+ */
+BOOL PatBlt( HDC hdc, short left, short top,
+	     short width, short height, DWORD rop)
+{
+    int x1, x2, y1, y2;
+    
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+#ifdef DEBUG_GDI
+    printf( "PatBlt: %d %d,%d %dx%d %06x\n",
+	    hdc, left, top, width, height, rop );
+#endif
+
+    rop >>= 16;
+    if (!DC_SetupGCForBrush( dc )) rop &= 0x0f;
+    else rop = (rop & 0x03) | ((rop >> 4) & 0x0c);
+    XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[rop] );
+
+    x1 = XLPTODP( dc, left );
+    x2 = XLPTODP( dc, left + width );
+    y1 = YLPTODP( dc, top );
+    y2 = YLPTODP( dc, top + height );
+    XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		   MIN(x1,x2), MIN(y1,y2), abs(x2-x1), abs(y2-y1) );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           BitBlt    (GDI.34)
+ */
+BOOL BitBlt( HDC hdcDest, short xDest, short yDest, short width, short height,
+	     HDC hdcSrc, short xSrc, short ySrc, DWORD rop )
+{
+    int xs1, xs2, ys1, ys2;
+    int xd1, xd2, yd1, yd2;
+    DC *dcDest, *dcSrc;
+
+#ifdef DEBUG_GDI    
+    printf( "BitBlt: %d %d,%d %dx%d %d %d,%d %08x\n",
+	   hdcDest, xDest, yDest, width, height, hdcSrc, xSrc, ySrc, rop );
+#endif
+
+    if ((rop & 0xcc0000) == ((rop & 0x330000) << 2))
+	return PatBlt( hdcDest, xDest, yDest, width, height, rop );
+
+    rop >>= 16;
+    if ((rop & 0x0f) != (rop >> 4))
+    {
+	printf( "BitBlt: Unimplemented ROP %02x\n", rop );
+	return FALSE;
+    }
+    
+    dcDest = (DC *) GDI_GetObjPtr( hdcDest, DC_MAGIC );
+    if (!dcDest) return FALSE;
+    dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC );
+    if (!dcSrc) return FALSE;
+
+    xs1 = XLPTODP( dcSrc, xSrc );
+    xs2 = XLPTODP( dcSrc, xSrc + width );
+    ys1 = YLPTODP( dcSrc, ySrc );
+    ys2 = YLPTODP( dcSrc, ySrc + height );
+    xd1 = XLPTODP( dcDest, xDest );
+    xd2 = XLPTODP( dcDest, xDest + width );
+    yd1 = YLPTODP( dcDest, yDest );
+    yd2 = YLPTODP( dcDest, yDest + height );
+
+    if ((abs(xs2-xs1) != abs(xd2-xd1)) || (abs(ys2-ys1) != abs(yd2-yd1)))
+	return FALSE;  /* Should call StretchBlt here */
+    
+    DC_SetupGCForText( dcDest );
+    XSetFunction( XT_display, dcDest->u.x.gc, DC_XROPfunction[rop & 0x0f] );
+    if (dcSrc->w.bitsPerPixel == dcDest->w.bitsPerPixel)
+    {
+	XCopyArea( XT_display, dcSrc->u.x.drawable,
+		   dcDest->u.x.drawable, dcDest->u.x.gc,
+		   MIN(xs1,xs2), MIN(ys1,ys2), abs(xs2-xs1), abs(ys2-ys1),
+		   MIN(xd1,xd2), MIN(yd1,yd2) );
+    }
+    else
+    {
+	if (dcSrc->w.bitsPerPixel != 1) return FALSE;
+	XCopyPlane( XT_display, dcSrc->u.x.drawable,
+		    dcDest->u.x.drawable, dcDest->u.x.gc,
+		    MIN(xs1,xs2), MIN(ys1,ys2), abs(xs2-xs1), abs(ys2-ys1),
+		    MIN(xd1,xd2), MIN(yd1,yd2), 1 );
+    }
+    return TRUE;
+}
diff --git a/objects/bitmap.c b/objects/bitmap.c
new file mode 100644
index 0000000..9de4c1c
--- /dev/null
+++ b/objects/bitmap.c
@@ -0,0 +1,423 @@
+/*
+ * GDI bitmap objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "gdi.h"
+
+/* A GDI bitmap object contains a handle to a packed BITMAP,
+ * which is stored on the global heap.
+ * A packed BITMAP is a BITMAP structure followed by the bitmap bits.
+ */
+
+  /* Handle of the bitmap selected by default in a memory DC */
+HBITMAP BITMAP_hbitmapMemDC;
+
+  /* List of supported depths */
+static int depthCount;
+static int * depthList;
+
+  /* List of GC used for bitmap to pixmap operations (one for each depth) */
+static GC * bitmapGC;
+
+
+/***********************************************************************
+ *           BITMAP_Init
+ */
+BOOL BITMAP_Init()
+{
+    int i;
+    Pixmap tmpPixmap;
+    
+    depthList = XListDepths( XT_display, DefaultScreen(XT_display), 
+			     &depthCount );
+    if (!depthList || !depthCount) return FALSE;
+    if (!(bitmapGC = (GC *) malloc( depthCount * sizeof(GC) ))) return FALSE;
+    
+      /* Create the necessary GCs */
+    
+    for (i = 0; i < depthCount; i++)
+    {
+	tmpPixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display),
+				  1, 1, depthList[i] );
+	if (tmpPixmap)
+	{
+	    bitmapGC[i] = XCreateGC( XT_display, tmpPixmap, 0, NULL );
+	    XFreePixmap( XT_display, tmpPixmap );
+	}
+	else bitmapGC[i] = 0;
+    }
+
+    BITMAP_hbitmapMemDC = CreateBitmap( 1, 1, 1, 1, NULL );
+    return (BITMAP_hbitmapMemDC != 0);
+}
+
+
+/***********************************************************************
+ *           BITMAP_FindGCForDepth
+ *
+ * Return a GC appropriate for operations with the given depth.
+ */
+GC BITMAP_FindGCForDepth( int depth )
+{
+    int i;
+    for (i = 0; i < depthCount; i++)
+	if (depthList[i] == depth) return bitmapGC[i];
+    return 0;
+}
+
+
+/***********************************************************************
+ *           BITMAP_BmpToImage
+ *
+ * Create an XImage pointing to the bitmap data.
+ */
+XImage * BITMAP_BmpToImage( BITMAP * bmp, void * bmpData )
+{
+    XImage * image;
+
+    image = XCreateImage( XT_display, DefaultVisualOfScreen(XT_screen),
+			  bmp->bmBitsPixel, ZPixmap, 0, bmpData,
+			  bmp->bmWidth, bmp->bmHeight, 16, bmp->bmWidthBytes );
+    if (!image) return 0;
+    image->byte_order = MSBFirst;
+    image->bitmap_bit_order = MSBFirst;
+    image->bitmap_unit = 16;
+    _XInitImageFuncPtrs(image);
+    return image;
+}
+
+
+/***********************************************************************
+ *           BITMAP_CopyToPixmap
+ *
+ * Copy the content of the bitmap to the pixmap. Both must have the same depth.
+ */
+BOOL BITMAP_CopyToPixmap( BITMAP * bmp, Pixmap pixmap,
+			  int x, int y, int width, int height )
+{
+    GC gc;
+    XImage * image;
+    
+    gc = BITMAP_FindGCForDepth( bmp->bmBitsPixel );
+    if (!gc) return FALSE;
+    
+    image = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) );
+    if (!image) return FALSE;
+
+#ifdef DEBUG_GDI
+    printf( "BITMAP_CopyToPixmap: %dx%d %d colors -> %d,%d %dx%d\n",
+	    bmp->bmWidth, bmp->bmHeight, 1 << bmp->bmBitsPixel, x, y, width, height );
+#endif
+    XPutImage(XT_display, pixmap, gc, image, 0, 0, x, y, width, height); 
+    image->data = NULL;
+    XDestroyImage( image );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           BITMAP_CopyFromPixmap
+ *
+ * Copy the content of the pixmap to the bitmap. Both must have
+ * the same dimensions and depth.
+ */
+BOOL BITMAP_CopyFromPixmap( BITMAP * bmp, Pixmap pixmap )
+{
+    XImage *image = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) );
+    if (!image) return FALSE;
+
+#ifdef DEBUG_GDI
+    printf( "BITMAP_CopyFromPixmap: %dx%d %d colors\n",
+	    bmp->bmWidth, bmp->bmHeight, 1 << bmp->bmBitsPixel );
+#endif    
+    XGetSubImage( XT_display, pixmap, 0, 0, bmp->bmWidth, bmp->bmHeight,
+		  AllPlanes, ZPixmap, image, 0, 0 );
+    image->data = NULL;
+    XDestroyImage( image );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CreateBitmap    (GDI.48)
+ */
+HBITMAP CreateBitmap( short width, short height, 
+		      BYTE planes, BYTE bpp, LPSTR bits )
+{
+    BITMAP bitmap = { 0, width, height, 0, planes, bpp, bits };
+#ifdef DEBUG_GDI
+    printf( "CreateBitmap: %dx%d, %d colors\n", 
+	     width, height, 1 << (planes*bpp) );
+#endif
+    if (!width || !height) return 0;
+    if ((planes != 1) && (bpp != 1)) return 0;
+    bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2;
+    return CreateBitmapIndirect( &bitmap );
+}
+
+
+/***********************************************************************
+ *           CreateCompatibleBitmap    (GDI.51)
+ */
+HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height )
+{
+    HBITMAP hbitmap;
+    DC * dc;
+#ifdef DEBUG_GDI
+    printf( "CreateCompatibleBitmap: %d %dx%d\n", hdc, width, height );
+#endif
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    hbitmap = CreateBitmap( width, height, dc->w.planes, dc->w.bitsPerPixel, NULL);
+    return hbitmap;
+}
+
+
+/***********************************************************************
+ *           CreateBitmapIndirect    (GDI.49)
+ */
+HBITMAP CreateBitmapIndirect( BITMAP * bmp )
+{
+    BITMAPOBJ * bmpObjPtr;
+    char * bmpPtr;
+    HBITMAP hbitmap;
+    int size = bmp->bmPlanes * bmp->bmHeight * bmp->bmWidthBytes;
+    
+      /* Create the BITMAPOBJ */
+
+    hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
+    if (!hbitmap) return 0;
+    bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap );
+    
+      /* Create the bitmap in global heap */
+
+    bmpObjPtr->hBitmap = GlobalAlloc( GMEM_MOVEABLE, sizeof(BITMAP) + size );
+    if (!bmpObjPtr->hBitmap)
+    {
+	GDI_FreeObject( hbitmap );
+	return 0;
+    }
+    bmpPtr = (char *) GlobalLock( bmpObjPtr->hBitmap );
+    memcpy( bmpPtr, bmp, sizeof(BITMAP) );
+    ((BITMAP *)bmpPtr)->bmBits = NULL;
+    if (bmp->bmBits) memcpy( bmpPtr + sizeof(BITMAP), bmp->bmBits, size );
+    GlobalUnlock( bmpObjPtr->hBitmap );
+
+    bmpObjPtr->bSelected = FALSE;
+    bmpObjPtr->hdc       = 0;
+    bmpObjPtr->size.cx   = 0;
+    bmpObjPtr->size.cy   = 0;
+    return hbitmap;
+}
+
+
+/***********************************************************************
+ *           BITMAP_GetSetBitmapBits
+ */
+LONG BITMAP_GetSetBitmapBits( HBITMAP hbitmap, LONG count,
+			      LPSTR buffer, int set )
+{
+    BITMAPOBJ * bmpObjPtr;
+    BITMAP * bmp;
+    DC * dc = NULL;
+    int maxSize;
+    
+    if (!count) return 0;
+    bmpObjPtr = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+    if (!bmpObjPtr) return 0;
+    if (!(bmp = (BITMAP *) GlobalLock( bmpObjPtr->hBitmap ))) return 0;
+    
+    if (bmpObjPtr->bSelected) 
+	dc = (DC *) GDI_GetObjPtr( bmpObjPtr->hdc, DC_MAGIC );
+
+    maxSize = bmp->bmPlanes * bmp->bmHeight * bmp->bmWidthBytes;
+    if (count > maxSize) count = maxSize;
+    	
+    if (set)
+    {
+	memcpy( bmp+1, buffer, count );
+	if (dc) BITMAP_CopyToPixmap( bmp, dc->u.x.drawable,
+				     0, 0, bmp->bmWidth, bmp->bmHeight );
+    }
+    else
+    {
+	if (dc) BITMAP_CopyFromPixmap( bmp, dc->u.x.drawable );
+	memcpy( buffer, bmp+1, count );
+    }
+    GlobalUnlock( bmpObjPtr->hBitmap );
+    return hbitmap;
+}
+
+
+/***********************************************************************
+ *           GetBitmapBits    (GDI.74)
+ */
+LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer )
+{
+    return BITMAP_GetSetBitmapBits( hbitmap, count, buffer, 0 );
+}
+
+
+/***********************************************************************
+ *           SetBitmapBits    (GDI.106)
+ */
+LONG SetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer )
+{
+    return BITMAP_GetSetBitmapBits( hbitmap, count, buffer, 1 );
+}
+
+
+/***********************************************************************
+ *           BMP_DeleteObject
+ */
+BOOL BMP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bitmap )
+{
+      /* Free bitmap on global heap */
+    GlobalFree( bitmap->hBitmap );
+    return GDI_FreeObject( hbitmap );
+}
+
+	
+/***********************************************************************
+ *           BMP_GetObject
+ */
+int BMP_GetObject( BITMAPOBJ * bitmap, int count, LPSTR buffer )
+{
+    char * bmpPtr = (char *) GlobalLock( bitmap->hBitmap );    
+    if (count > sizeof(BITMAP)) count = sizeof(BITMAP);
+    memcpy( buffer, bmpPtr, count );
+    GlobalUnlock( bitmap->hBitmap );
+    return count;
+}
+
+    
+/***********************************************************************
+ *           BITMAP_UnselectBitmap
+ *
+ * Unselect the bitmap from the DC. Used by SelectObject and DeleteDC.
+ */
+BOOL BITMAP_UnselectBitmap( DC * dc )
+{
+    BITMAPOBJ * bmp;
+    BITMAP * bmpPtr;
+
+    if (!dc->w.hBitmap) return TRUE;
+    bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC );
+    if (!bmp) return FALSE;
+    
+    if (!(bmpPtr = (BITMAP *) GlobalLock( bmp->hBitmap ))) return FALSE;
+    
+    BITMAP_CopyFromPixmap( bmpPtr, dc->u.x.drawable );
+    XFreePixmap( XT_display, dc->u.x.drawable );
+    bmp->bSelected = FALSE;
+    bmp->hdc       = 0;
+    GlobalUnlock( bmp->hBitmap );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           BITMAP_SelectObject
+ */
+HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap,
+			     BITMAPOBJ * bitmap )
+{
+    BITMAP * bmp;
+    HBITMAP prevHandle = dc->w.hBitmap;
+    
+    if (!(dc->w.flags & DC_MEMORY)) return 0;
+    if (bitmap->bSelected && hbitmap != BITMAP_hbitmapMemDC) return 0;
+    if (!(bmp = (BITMAP *) GlobalLock( bitmap->hBitmap ))) return 0;
+
+      /* Make sure the bitmap has the right format */
+
+    if ((bmp->bmPlanes != 1) || !BITMAP_FindGCForDepth( bmp->bmBitsPixel ))
+    {
+	GlobalUnlock( bitmap->hBitmap );
+	return 0;
+    }
+    
+      /* Unselect the previous bitmap */
+
+    if (!BITMAP_UnselectBitmap( dc ))
+    {
+	GlobalUnlock( bitmap->hBitmap );
+	return 0;
+    }
+    
+      /* Create the pixmap */
+    
+    dc->u.x.drawable   = XCreatePixmap( XT_display,
+				        DefaultRootWindow( XT_display ), 
+				        bmp->bmWidth, bmp->bmHeight,
+				        bmp->bmBitsPixel );
+    BITMAP_CopyToPixmap( bmp, dc->u.x.drawable,
+			 0, 0, bmp->bmWidth, bmp->bmHeight );
+
+      /* Change GC depth if needed */
+
+    if (dc->w.bitsPerPixel != bmp->bmBitsPixel)
+    {
+	XFreeGC( XT_display, dc->u.x.gc );
+	dc->u.x.gc = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL );
+	dc->w.bitsPerPixel = bmp->bmBitsPixel;
+	DC_SetDeviceInfo( hdc, dc );
+    }
+    
+    GlobalUnlock( bitmap->hBitmap );
+    dc->w.hBitmap     = hbitmap;
+    bitmap->bSelected = TRUE;
+    bitmap->hdc       = hdc;
+    return prevHandle;
+}
+
+
+/***********************************************************************
+ *           GetBitmapDimensionEx    (GDI.468)
+ */
+BOOL GetBitmapDimensionEx( HBITMAP hbitmap, LPSIZE size )
+{
+    BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+    if (!bmp) return FALSE;
+    *size = bmp->size;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetBitmapDimension    (GDI.162)
+ */
+DWORD GetBitmapDimension( HBITMAP hbitmap )
+{
+    SIZE size;
+    if (!GetBitmapDimensionEx( hbitmap, &size )) return 0;
+    return size.cx | (size.cy << 16);
+}
+
+/***********************************************************************
+ *           SetBitmapDimensionEx    (GDI.478)
+ */
+BOOL SetBitmapDimensionEx( HBITMAP hbitmap, short x, short y, LPSIZE prevSize )
+{
+    BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+    if (!bmp) return FALSE;
+    if (prevSize) *prevSize = bmp->size;
+    bmp->size.cx = x;
+    bmp->size.cy = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetBitmapDimension    (GDI.163)
+ */
+DWORD SetBitmapDimension( HBITMAP hbitmap, short x, short y )
+{
+    SIZE size;
+    if (!SetBitmapDimensionEx( hbitmap, x, y, &size )) return 0;
+    return size.cx | (size.cy << 16);    
+}
diff --git a/objects/brush.c b/objects/brush.c
new file mode 100644
index 0000000..11a430b
--- /dev/null
+++ b/objects/brush.c
@@ -0,0 +1,270 @@
+/*
+ * GDI brush objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "gdi.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+#define NB_HATCH_STYLES  6
+
+static char HatchBrushes[NB_HATCH_STYLES][8] =
+{
+    { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HS_HORIZONTAL */
+    { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HS_VERTICAL   */
+    { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HS_FDIAGONAL  */
+    { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HS_BDIAGONAL  */
+    { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HS_CROSS      */
+    { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }  /* HS_DIAGCROSS  */
+};
+
+extern XImage * BITMAP_BmpToImage( BITMAP *, void * );
+
+/***********************************************************************
+ *           CreateBrushIndirect    (GDI.50)
+ */
+HBRUSH CreateBrushIndirect( LOGBRUSH * brush )
+{
+    BRUSHOBJ * brushPtr;
+    HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
+    if (!hbrush) return 0;
+    brushPtr = (BRUSHOBJ *) GDI_HEAP_ADDR( hbrush );
+    memcpy( &brushPtr->logbrush, brush, sizeof(LOGBRUSH) );
+    return hbrush;
+}
+
+
+/***********************************************************************
+ *           CreateHatchBrush    (GDI.58)
+ */
+HBRUSH CreateHatchBrush( short style, COLORREF color )
+{
+    LOGBRUSH logbrush = { BS_HATCHED, color, style };
+#ifdef DEBUG_GDI
+    printf( "CreateHatchBrush: %d %06x\n", style, color );
+#endif
+    if ((style < 0) || (style >= NB_HATCH_STYLES)) return 0;
+    return CreateBrushIndirect( &logbrush );
+}
+
+
+/***********************************************************************
+ *           CreatePatternBrush    (GDI.60)
+ */
+HBRUSH CreatePatternBrush( HBITMAP hbitmap )
+{
+    LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
+    BITMAPOBJ * bmpObj;
+    BITMAP * bmp;
+    
+#ifdef DEBUG_GDI
+    printf( "CreatePatternBrush: %d\n", hbitmap );
+#endif
+
+      /* Make a copy of the bitmap */
+
+    if (!(bmpObj = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
+	return 0;
+    if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0;    
+    logbrush.lbHatch = CreateBitmap( bmp->bmWidth, bmp->bmHeight,
+				     bmp->bmPlanes, bmp->bmBitsPixel,
+				     ((char *)bmp) + sizeof(BITMAP) );
+    GlobalUnlock( bmpObj->hBitmap );
+    if (!logbrush.lbHatch) return 0;
+    return CreateBrushIndirect( &logbrush );
+}
+
+
+/***********************************************************************
+ *           CreateDIBPatternBrush    (GDI.445)
+ */
+HBRUSH CreateDIBPatternBrush( HANDLE hbitmap, WORD coloruse )
+{
+    LOGBRUSH logbrush = { BS_DIBPATTERN, coloruse, 0 };
+    BITMAPINFO *info, *newInfo;
+    int size;
+    
+#ifdef DEBUG_GDI
+    printf( "CreateDIBPatternBrush: %d\n", hbitmap );
+#endif
+
+      /* Make a copy of the bitmap */
+
+    if (!(info = (BITMAPINFO *) GlobalLock( hbitmap ))) return 0;
+
+    size = info->bmiHeader.biSizeImage;
+    if (!size)
+	size = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) / 32
+	         * 8 * info->bmiHeader.biHeight;
+    size += DIB_BitmapInfoSize( info, coloruse );
+
+    if (!(logbrush.lbHatch = GlobalAlloc( GMEM_MOVEABLE, size )))
+    {
+	GlobalUnlock( hbitmap );
+	return 0;
+    }
+    newInfo = (BITMAPINFO *) GlobalLock( logbrush.lbHatch );
+    memcpy( newInfo, info, size );
+    GlobalUnlock( logbrush.lbHatch );
+    GlobalUnlock( hbitmap );
+    return CreateBrushIndirect( &logbrush );
+}
+
+
+/***********************************************************************
+ *           CreateSolidBrush    (GDI.66)
+ */
+HBRUSH CreateSolidBrush( COLORREF color )
+{
+    LOGBRUSH logbrush = { BS_SOLID, color, 0 };
+#ifdef DEBUG_GDI
+    printf( "CreateSolidBrush: %06x\n", color );
+#endif
+    return CreateBrushIndirect( &logbrush );
+}
+
+
+/***********************************************************************
+ *           SetBrushOrg    (GDI.148)
+ */
+DWORD SetBrushOrg( HDC hdc, short x, short y )
+{
+    DWORD retval;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    retval = dc->w.brushOrgX | (dc->w.brushOrgY << 16);
+    dc->w.brushOrgX = x;
+    dc->w.brushOrgY = y;
+    return retval;
+}
+
+
+/***********************************************************************
+ *           BRUSH_DeleteObject
+ */
+BOOL BRUSH_DeleteObject( HBRUSH hbrush, BRUSHOBJ * brush )
+{
+    switch(brush->logbrush.lbStyle)
+    {
+      case BS_PATTERN:
+	  DeleteObject( brush->logbrush.lbHatch );
+	  break;
+      case BS_DIBPATTERN:
+	  GlobalFree( brush->logbrush.lbHatch );
+	  break;
+    }
+    return GDI_FreeObject( hbrush );
+}
+
+
+/***********************************************************************
+ *           BRUSH_GetObject
+ */
+int BRUSH_GetObject( BRUSHOBJ * brush, int count, LPSTR buffer )
+{
+    if (count > sizeof(LOGBRUSH)) count = sizeof(LOGBRUSH);
+    memcpy( buffer, &brush->logbrush, count );
+    return count;
+}
+
+
+/***********************************************************************
+ *           BRUSH_SelectPatternBrush
+ */
+BOOL BRUSH_SelectPatternBrush( DC * dc, HBITMAP hbitmap )
+{
+    BITMAPOBJ * bmpObjPtr;
+    BITMAP * bmp;
+    
+    bmpObjPtr = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+    if (!bmpObjPtr) return FALSE;
+    if (!(bmp = (BITMAP *) GlobalLock( bmpObjPtr->hBitmap ))) return FALSE;
+
+    dc->u.x.brush.pixmap = XCreatePixmap( XT_display,
+					  DefaultRootWindow(XT_display),
+					  8, 8, bmp->bmBitsPixel );
+    BITMAP_CopyToPixmap( bmp, dc->u.x.brush.pixmap, 0, 0, 8, 8 );
+    
+    if (bmp->bmBitsPixel > 1)
+    {
+	dc->u.x.brush.fillStyle = FillTiled;
+	XSetTile( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap );
+	dc->u.x.brush.pixel = 0;  /* Ignored */
+    }
+    else
+    {
+	dc->u.x.brush.fillStyle = FillOpaqueStippled;
+	XSetStipple( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap );
+	dc->u.x.brush.pixel = -1;  /* Special case (see DC_SetupGCForBrush) */
+    }
+    return TRUE;
+}
+
+
+
+/***********************************************************************
+ *           BRUSH_SelectObject
+ */
+HBRUSH BRUSH_SelectObject( HDC hdc, DC * dc, HBRUSH hbrush, BRUSHOBJ * brush )
+{
+    HBITMAP hBitmap;
+    BITMAPINFO * bmpInfo;
+    HBRUSH prevHandle = dc->w.hBrush;
+    
+    dc->w.hBrush = hbrush;
+
+    if (dc->u.x.brush.pixmap)
+    {
+	XFreePixmap( XT_display, dc->u.x.brush.pixmap );
+	dc->u.x.brush.pixmap = 0;
+    }
+    dc->u.x.brush.style = brush->logbrush.lbStyle;
+    
+    switch(brush->logbrush.lbStyle)
+    {
+      case BS_SOLID:
+      case BS_NULL:
+	dc->u.x.brush.pixel = GetNearestPaletteIndex( dc->w.hPalette, 
+						 brush->logbrush.lbColor );
+	dc->u.x.brush.fillStyle = FillSolid;
+	break;
+	
+      case BS_HATCHED:
+	dc->u.x.brush.pixel = GetNearestPaletteIndex( dc->w.hPalette, 
+						 brush->logbrush.lbColor );
+	dc->u.x.brush.pixmap = XCreateBitmapFromData(XT_display, 
+					DefaultRootWindow(XT_display),
+					HatchBrushes[brush->logbrush.lbHatch],
+					8, 8 );
+	XSetStipple( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap );
+	dc->u.x.brush.fillStyle = FillStippled;
+	break;
+	
+      case BS_PATTERN:
+	BRUSH_SelectPatternBrush( dc, brush->logbrush.lbHatch );
+	break;
+
+      case BS_DIBPATTERN:
+	if ((bmpInfo = (BITMAPINFO *) GlobalLock( brush->logbrush.lbHatch )))
+	{
+	    int size = DIB_BitmapInfoSize( bmpInfo, brush->logbrush.lbColor );
+	    hBitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
+				      ((char *)bmpInfo) + size, bmpInfo,
+				      (WORD) brush->logbrush.lbColor );
+	    BRUSH_SelectPatternBrush( dc, hBitmap );
+	    DeleteObject( hBitmap );
+	    GlobalUnlock( brush->logbrush.lbHatch );	    
+	}
+	
+	break;
+    }
+    
+    return prevHandle;
+}
+
+
diff --git a/objects/clipping.c b/objects/clipping.c
new file mode 100644
index 0000000..ec9de9c
--- /dev/null
+++ b/objects/clipping.c
@@ -0,0 +1,354 @@
+/*
+ * DC clipping functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdio.h>
+#include "gdi.h"
+
+
+/***********************************************************************
+ *           CLIPPING_UpdateGCRegion
+ *
+ * Update the GC clip region when the ClipRgn of VisRgn have changed.
+ */
+static void CLIPPING_UpdateGCRegion( DC * dc )
+{
+    if (!dc->w.hGCClipRgn) dc->w.hGCClipRgn = CreateRectRgn(0,0,0,0);
+
+    if (!dc->w.hVisRgn)
+    {
+	if (!dc->w.hClipRgn)
+	{
+	    DeleteObject( dc->w.hGCClipRgn );
+	    dc->w.hGCClipRgn = 0;
+	}
+	else
+	    CombineRgn( dc->w.hGCClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
+    }
+    else
+    {
+	if (!dc->w.hClipRgn)
+	    CombineRgn( dc->w.hGCClipRgn, dc->w.hVisRgn, 0, RGN_COPY );
+	else
+	    CombineRgn( dc->w.hGCClipRgn, dc->w.hClipRgn, dc->w.hVisRgn, RGN_AND );
+    }
+    
+    if (dc->w.hGCClipRgn)
+    {
+	RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hGCClipRgn, REGION_MAGIC );
+	XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap );
+	XSetClipOrigin( XT_display, dc->u.x.gc,
+		        obj->region.box.left, obj->region.box.top );
+    }
+    else
+    {
+	XSetClipMask( XT_display, dc->u.x.gc, None );
+	XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 );
+    }	
+}
+
+
+/***********************************************************************
+ *           CLIPPING_SelectRgn
+ *
+ * Helper function for SelectClipRgn() and SelectVisRgn().
+ */
+static int CLIPPING_SelectRgn( DC * dc, HRGN * hrgnPrev, HRGN hrgn )
+{
+    int retval;
+    
+    if (hrgn)
+    {
+	if (!*hrgnPrev) *hrgnPrev = CreateRectRgn(0,0,0,0);
+	retval = CombineRgn( *hrgnPrev, hrgn, 0, RGN_COPY );
+    }
+    else
+    {
+	if (*hrgnPrev) DeleteObject( *hrgnPrev );
+	*hrgnPrev = 0;
+	retval = SIMPLEREGION; /* Clip region == client area */
+    }
+    CLIPPING_UpdateGCRegion( dc );
+    return retval;
+}
+
+
+/***********************************************************************
+ *           SelectClipRgn    (GDI.44)
+ */
+int SelectClipRgn( HDC hdc, HRGN hrgn )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;
+    
+#ifdef DEBUG_CLIPPING
+    printf( "SelectClipRgn: %d %d\n", hdc, hrgn );
+#endif
+    return CLIPPING_SelectRgn( dc, &dc->w.hClipRgn, hrgn );
+}
+
+
+/***********************************************************************
+ *           SelectVisRgn    (GDI.105)
+ */
+int SelectVisRgn( HDC hdc, HRGN hrgn )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;
+    
+#ifdef DEBUG_CLIPPING
+    printf( "SelectVisRgn: %d %d\n", hdc, hrgn );
+#endif
+    return CLIPPING_SelectRgn( dc, &dc->w.hVisRgn, hrgn );
+}
+
+
+/***********************************************************************
+ *           OffsetClipRgn    (GDI.32)
+ */
+int OffsetClipRgn( HDC hdc, short x, short y )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "OffsetClipRgn: %d %d,%d\n", hdc, x, y );
+#endif
+
+    if (dc->w.hClipRgn)
+    {
+	int retval = OffsetRgn( dc->w.hClipRgn, x, y );
+	CLIPPING_UpdateGCRegion( dc );
+	return retval;
+    }
+    else return SIMPLEREGION; /* Clip region == client area */
+}
+
+
+/***********************************************************************
+ *           OffsetVisRgn    (GDI.102)
+ */
+int OffsetVisRgn( HDC hdc, short x, short y )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "OffsetVisRgn: %d %d,%d\n", hdc, x, y );
+#endif
+
+    if (dc->w.hVisRgn)
+    {
+	int retval = OffsetRgn( dc->w.hVisRgn, x, y );
+	CLIPPING_UpdateGCRegion( dc );
+	return retval;
+    }
+    else return SIMPLEREGION; /* Clip region == client area */
+}
+
+
+/***********************************************************************
+ *           CLIPPING_IntersectRect
+ *
+ * Helper function for {Intersect,Exclude}{Clip,Vis}Rect
+ */
+int CLIPPING_IntersectRect( DC * dc, HRGN * hrgn, short left, short top,
+			    short right, short bottom, int exclude )
+{
+    HRGN tempRgn, newRgn;
+    RGNOBJ *newObj, *prevObj;
+    int retval;
+
+    if (!*hrgn) return NULLREGION;
+    if (!(newRgn = CreateRectRgn( 0, 0, 0, 0))) return ERROR;
+    if (!(tempRgn = CreateRectRgn( left, top, right, bottom )))
+    {
+	DeleteObject( newRgn );
+	return ERROR;
+    }
+    retval = CombineRgn( newRgn, *hrgn, tempRgn, exclude ? RGN_DIFF : RGN_AND);
+    newObj = (RGNOBJ *) GDI_GetObjPtr( newRgn, REGION_MAGIC );
+    prevObj = (RGNOBJ *) GDI_GetObjPtr( *hrgn, REGION_MAGIC );
+    if (newObj && prevObj) newObj->header.hNext = prevObj->header.hNext;
+    DeleteObject( tempRgn );
+    DeleteObject( *hrgn );
+    *hrgn = newRgn;    
+    CLIPPING_UpdateGCRegion( dc );
+    return retval;
+}
+
+
+/***********************************************************************
+ *           ExcludeClipRect    (GDI.21)
+ */
+int ExcludeClipRect( HDC hdc, short left, short top,
+		     short right, short bottom )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "ExcludeClipRect: %d %dx%d,%dx%d\n",
+	    hdc, left, top, right, bottom );
+#endif
+    return CLIPPING_IntersectRect( dc, &dc->w.hClipRgn, left, top,
+				   right, bottom, 1 );
+}
+
+
+/***********************************************************************
+ *           IntersectClipRect    (GDI.22)
+ */
+int IntersectClipRect( HDC hdc, short left, short top,
+		       short right, short bottom )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "IntersectClipRect: %d %dx%d,%dx%d\n",
+	    hdc, left, top, right, bottom );
+#endif
+    return CLIPPING_IntersectRect( dc, &dc->w.hClipRgn, left, top,
+				   right, bottom, 0 );
+}
+
+
+/***********************************************************************
+ *           ExcludeVisRect    (GDI.73)
+ */
+int ExcludeVisRect( HDC hdc, short left, short top,
+		    short right, short bottom )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "ExcludeVisRect: %d %dx%d,%dx%d\n",
+	    hdc, left, top, right, bottom );
+#endif
+    return CLIPPING_IntersectRect( dc, &dc->w.hVisRgn, left, top,
+				   right, bottom, 1 );
+}
+
+
+/***********************************************************************
+ *           IntersectVisRect    (GDI.98)
+ */
+int IntersectVisRect( HDC hdc, short left, short top,
+		      short right, short bottom )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "IntersectVisRect: %d %dx%d,%dx%d\n",
+	    hdc, left, top, right, bottom );
+#endif
+    return CLIPPING_IntersectRect( dc, &dc->w.hVisRgn, left, top,
+				   right, bottom, 0 );
+}
+
+
+/***********************************************************************
+ *           PtVisible    (GDI.103)
+ */
+BOOL PtVisible( HDC hdc, short x, short y )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "PtVisible: %d %d,%d\n", hdc, x, y );
+#endif
+    if (!dc->w.hClipRgn) return FALSE;
+    return PtInRegion( dc->w.hClipRgn, x, y );
+}
+
+
+/***********************************************************************
+ *           RectVisible    (GDI.104)
+ */
+BOOL RectVisible( HDC hdc, LPRECT rect )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "RectVisible: %d %p\n", hdc, rect );
+#endif
+    if (!dc->w.hClipRgn) return FALSE;
+    return RectInRegion( dc->w.hClipRgn, rect );
+}
+
+
+/***********************************************************************
+ *           GetClipBox    (GDI.77)
+ */
+int GetClipBox( HDC hdc, LPRECT rect )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "GetClipBox: %d %p\n", hdc, rect );
+#endif
+
+    if (dc->w.hGCClipRgn) return GetRgnBox( dc->w.hGCClipRgn, rect );
+    else
+    {
+	Window root;
+	int width, height, x, y, border, depth;
+	XGetGeometry( XT_display, dc->u.x.drawable, &root, &x, &y, 
+		      &width, &height, &border, &depth );
+	rect->top = rect->left = 0;
+	rect->right  = width & 0xffff;
+	rect->bottom = height & 0xffff;
+	return SIMPLEREGION;
+    }
+}
+
+
+/***********************************************************************
+ *           SaveVisRgn    (GDI.129)
+ */
+HRGN SaveVisRgn( HDC hdc )
+{
+    HRGN copy;
+    RGNOBJ *obj, *copyObj;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+#ifdef DEBUG_CLIPPING
+    printf( "SaveVisRgn: %d\n", hdc );
+#endif
+    if (!dc->w.hVisRgn) return 0;
+    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC )))
+	return 0;
+    if (!(copy = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
+    CombineRgn( copy, dc->w.hVisRgn, 0, RGN_COPY );
+    if (!(copyObj = (RGNOBJ *) GDI_GetObjPtr( copy, REGION_MAGIC )))
+	return 0;
+    copyObj->header.hNext = obj->header.hNext;
+    obj->header.hNext = copy;
+    return copy;
+}
+
+
+/***********************************************************************
+ *           RestoreVisRgn    (GDI.130)
+ */
+int RestoreVisRgn( HDC hdc )
+{
+    HRGN saved;
+    RGNOBJ *obj, *savedObj;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return ERROR;    
+#ifdef DEBUG_CLIPPING
+    printf( "RestoreVisRgn: %d\n", hdc );
+#endif
+    if (!dc->w.hVisRgn) return ERROR;
+    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC )))
+	return ERROR;
+    if (!(saved = obj->header.hNext)) return ERROR;
+    if (!(savedObj = (RGNOBJ *) GDI_GetObjPtr( saved, REGION_MAGIC )))
+	return ERROR;
+    DeleteObject( dc->w.hVisRgn );
+    dc->w.hVisRgn = saved;
+    CLIPPING_UpdateGCRegion( dc );
+    return savedObj->region.type;
+}
diff --git a/objects/dcvalues.c b/objects/dcvalues.c
new file mode 100644
index 0000000..b496e2e
--- /dev/null
+++ b/objects/dcvalues.c
@@ -0,0 +1,142 @@
+/*
+ * DC device-independent Get/SetXXX functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "gdi.h"
+
+  /* Default DC values */
+const WIN_DC_INFO DCVAL_defaultValues =
+{
+    0,                      /* flags */
+    NULL,                   /* devCaps */
+    0,                      /* hMetaFile */
+    0,                      /* hClipRgn */
+    0,                      /* hVisRgn */
+    0,                      /* hGCClipRgn */
+    STOCK_BLACK_PEN,        /* hPen */
+    STOCK_WHITE_BRUSH,      /* hBrush */
+    STOCK_SYSTEM_FONT,      /* hFont */
+    0,                      /* hBitmap */
+    0,                      /* hDevice */
+    STOCK_DEFAULT_PALETTE,  /* hPalette */
+    R2_COPYPEN,             /* ROPmode */
+    ALTERNATE,              /* polyFillMode */
+    BLACKONWHITE,           /* stretchBltMode */
+    ABSOLUTE,               /* relAbsMode */
+    OPAQUE,                 /* backgroundMode */
+    RGB( 255, 255, 255 ),   /* backgroundColor */
+    RGB( 0, 0, 0 ),         /* textColor */
+    0,                      /* backgroundPixel */
+    0,                      /* textPixel */
+    0,                      /* brushOrgX */
+    0,                      /* brushOrgY */
+    TA_LEFT | TA_TOP | TA_NOUPDATECP,  /* textAlign */
+    0,                      /* charExtra */
+    0,                      /* breakTotalExtra */
+    0,                      /* breakCount */
+    0,                      /* breakExtra */
+    0,                      /* breakRem */
+    1,                      /* planes */
+    1,                      /* bitsPerPixel */
+    MM_TEXT,                /* MapMode */
+    0,                      /* DCOrgX */
+    0,                      /* DCOrgY */
+    0,                      /* CursPosX */
+    0,                      /* CursPosY */
+    0,                      /* WndOrgX */
+    0,                      /* WndOrgY */
+    1,                      /* WndExtX */
+    1,                      /* WndExtY */
+    0,                      /* VportOrgX */
+    0,                      /* VportOrgY */
+    1,                      /* VportExtX */
+    1                       /* VportExtY */
+};
+
+
+#define DC_GET_VAL( func_type, func_name, dc_field ) \
+func_type func_name( HDC hdc ) \
+{ \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if (!dc) return 0; \
+    return dc->w.dc_field; \
+}
+
+#define DC_GET_X_Y( func_type, func_name, ret_x, ret_y ) \
+func_type func_name( HDC hdc ) \
+{ \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if (!dc) return 0; \
+    return dc->w.ret_x | (dc->w.ret_y << 16); \
+}
+
+#define DC_GET_VAL_EX( func_name, ret_x, ret_y ) \
+BOOL func_name( HDC hdc, LPPOINT pt ) \
+{ \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if (!dc) return FALSE; \
+    pt->x = dc->w.ret_x; \
+    pt->y = dc->w.ret_y; \
+    return TRUE; \
+}
+
+#define DC_SET_VAL( func_type, func_name, dc_field ) \
+func_type func_name( HDC hdc, func_type val ) \
+{ \
+    func_type prevVal; \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if (!dc) return 0; \
+    prevVal = dc->w.dc_field; \
+    dc->w.dc_field = val; \
+    return prevVal; \
+}
+
+#define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
+WORD func_name( HDC hdc, WORD mode ) \
+{ \
+    WORD prevMode; \
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
+    if (!dc) return 0; \
+    if ((mode < min_val) || (mode > max_val)) return 0; \
+    prevMode = dc->w.dc_field; \
+    dc->w.dc_field = mode; \
+    return prevMode; \
+}
+
+
+DC_SET_MODE( SetBkMode, backgroundMode, TRANSPARENT, OPAQUE )     /* GDI.2 */
+DC_SET_MODE( SetROP2, ROPmode, R2_BLACK, R2_WHITE )               /* GDI.4 */
+DC_SET_MODE( SetRelAbs, relAbsMode, ABSOLUTE, RELATIVE )          /* GDI.5 */
+DC_SET_MODE( SetPolyFillMode, polyFillMode, ALTERNATE, WINDING )  /* GDI.6 */
+DC_SET_MODE( SetStretchBltMode, stretchBltMode,
+	     BLACKONWHITE, COLORONCOLOR )                         /* GDI.7 */
+DC_GET_VAL( COLORREF, GetBkColor, backgroundColor )               /* GDI.75 */
+DC_GET_VAL( WORD, GetBkMode, backgroundMode )                     /* GDI.76 */
+DC_GET_X_Y( DWORD, GetCurrentPosition, CursPosX, CursPosY )       /* GDI.78 */
+DC_GET_X_Y( DWORD, GetDCOrg, DCOrgX, DCOrgY )                     /* GDI.79 */
+DC_GET_VAL( WORD, GetMapMode, MapMode )                           /* GDI.81 */
+DC_GET_VAL( WORD, GetPolyFillMode, polyFillMode )                 /* GDI.84 */
+DC_GET_VAL( WORD, GetROP2, ROPmode )                              /* GDI.85 */
+DC_GET_VAL( WORD, GetRelAbs, relAbsMode )                         /* GDI.86 */
+DC_GET_VAL( WORD, GetStretchBltMode, stretchBltMode )             /* GDI.88 */
+DC_GET_VAL( COLORREF, GetTextColor, textColor )                   /* GDI.90 */
+DC_GET_X_Y( DWORD, GetViewportExt, VportExtX, VportExtY )         /* GDI.94 */
+DC_GET_X_Y( DWORD, GetViewportOrg, VportOrgX, VportOrgY )         /* GDI.95 */
+DC_GET_X_Y( DWORD, GetWindowExt, WndExtX, WndExtY )               /* GDI.96 */
+DC_GET_X_Y( DWORD, GetWindowOrg, WndOrgX, WndOrgY )               /* GDI.97 */
+DC_GET_VAL( HRGN, InquireVisRgn, hVisRgn )                        /* GDI.131 */
+DC_GET_X_Y( DWORD, GetBrushOrg, brushOrgX, brushOrgY )            /* GDI.149 */
+DC_GET_VAL( HRGN, GetClipRgn, hClipRgn )                          /* GDI.173 */
+DC_GET_VAL( WORD, GetTextAlign, textAlign )                       /* GDI.345 */
+DC_SET_VAL( WORD, SetTextAlign, textAlign )                       /* GDI.346 */
+DC_GET_VAL( HFONT, GetCurLogFont, hFont )                         /* GDI.411 */
+DC_GET_VAL_EX( GetBrushOrgEx, brushOrgX, brushOrgY )              /* GDI.469 */
+DC_GET_VAL_EX( GetCurrentPositionEx, CursPosX, CursPosY )         /* GDI.470 */
+DC_GET_VAL_EX( GetViewportExtEx, VportExtX, VportExtY )           /* GDI.472 */
+DC_GET_VAL_EX( GetViewportOrgEx, VportOrgX, VportOrgY )           /* GDI.473 */
+DC_GET_VAL_EX( GetWindowExtEx, WndExtX, WndExtY )                 /* GDI.474 */
+DC_GET_VAL_EX( GetWindowOrgEx, WndOrgX, WndOrgY )                 /* GDI.475 */
diff --git a/objects/dib.c b/objects/dib.c
new file mode 100644
index 0000000..839f0b5
--- /dev/null
+++ b/objects/dib.c
@@ -0,0 +1,203 @@
+/*
+ * GDI device independent bitmaps
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdlib.h>
+
+#include "gdi.h"
+
+
+extern XImage * BITMAP_BmpToImage( BITMAP *, void * );
+
+
+/***********************************************************************
+ *           DIB_BitmapInfoSize
+ *
+ * Return the size of the bitmap info structure.
+ */
+int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
+{
+    int size = info->bmiHeader.biClrUsed;
+    if (!size && (info->bmiHeader.biBitCount != 24))
+	size = 1 << info->bmiHeader.biBitCount;
+    if (coloruse == DIB_RGB_COLORS) 
+	size = info->bmiHeader.biSize + size * sizeof(RGBQUAD);
+    else
+	size = info->bmiHeader.biSize + size * sizeof(WORD);
+    return size;
+}
+
+
+/***********************************************************************
+ *           DIB_DIBmpToImage
+ *
+ * Create an XImage pointing to the bitmap data.
+ */
+XImage * DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData )
+{
+    XImage * image;
+    int bytesPerLine = (bmp->biWidth * bmp->biBitCount + 31) / 32 * 4;
+    
+    image = XCreateImage( XT_display, DefaultVisualOfScreen( XT_screen ),
+			  bmp->biBitCount, ZPixmap, 0, bmpData,
+			  bmp->biWidth, bmp->biHeight, 32, bytesPerLine );
+    if (!image) return 0;
+    image->byte_order = MSBFirst;
+    image->bitmap_bit_order = MSBFirst;
+    image->bitmap_unit = 16;
+    _XInitImageFuncPtrs(image);
+    return image;
+}
+
+
+/***********************************************************************
+ *           SetDIBits    (GDI.440)
+ */
+int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
+	       LPSTR bits, BITMAPINFO * info, WORD coloruse )
+{
+    DC * dc;
+    BITMAPOBJ * bmpObj;
+    BITMAP * bmp;
+    WORD * colorMapping;
+    RGBQUAD * rgbPtr;
+    XImage * bmpImage, * dibImage;
+    int i, x, y, pixel, colors;
+        
+    if (!lines) return 0;
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
+	return 0;
+    if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0;
+
+      /* Build the color mapping table */
+
+    if (info->bmiHeader.biBitCount == 24) colorMapping = NULL;
+    else if (coloruse == DIB_RGB_COLORS)
+    {
+	colors = info->bmiHeader.biClrUsed;
+	if (!colors) colors = 1 << info->bmiHeader.biBitCount;
+	if (!(colorMapping = (WORD *)malloc( colors * sizeof(WORD) )))
+	{
+	    GlobalUnlock( bmpObj->hBitmap );
+	    return 0;
+	}
+	for (i = 0, rgbPtr = info->bmiColors; i < colors; i++, rgbPtr++)
+	    colorMapping[i] = GetNearestPaletteIndex( dc->w.hPalette, 
+						     RGB(rgbPtr->rgbRed,
+							 rgbPtr->rgbGreen,
+							 rgbPtr->rgbBlue) );
+    }
+    else colorMapping = (WORD *)info->bmiColors;
+
+      /* Transfer the pixels (very slow...) */
+
+    bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) );
+    dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
+
+    for (y = 0; y < lines; y++)
+    {
+	for (x = 0; x < info->bmiHeader.biWidth; x++)
+	{
+	    pixel = XGetPixel( dibImage, x, y );
+	    if (colorMapping) pixel = colorMapping[pixel];
+	    else pixel = GetNearestPaletteIndex(dc->w.hPalette,(COLORREF)pixel);
+	    XPutPixel( bmpImage, x, bmp->bmHeight - startscan - y - 1, pixel );
+	}
+    }
+
+    bmpImage->data = NULL;
+    dibImage->data = NULL;
+    XDestroyImage( bmpImage );
+    XDestroyImage( dibImage );
+
+    if (colorMapping && (coloruse == DIB_RGB_COLORS)) free(colorMapping);
+    
+    GlobalUnlock( bmpObj->hBitmap );
+    return lines;
+}
+
+
+/***********************************************************************
+ *           GetDIBits    (GDI.441)
+ */
+int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
+	       LPSTR bits, BITMAPINFO * info, WORD coloruse )
+{
+    DC * dc;
+    BITMAPOBJ * bmpObj;
+    BITMAP * bmp;
+    PALETTEENTRY * palEntry;
+    PALETTEOBJ * palette;
+    XImage * bmpImage, * dibImage;
+    int i, x, y;
+        
+    if (!lines) return 0;
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
+	return 0;
+    if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
+	return 0;
+    if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0;
+
+      /* Transfer color info */
+    
+    palEntry = palette->logpalette.palPalEntry;
+    for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
+    {
+	if (coloruse == DIB_RGB_COLORS)
+	{
+	    info->bmiColors[i].rgbRed      = palEntry->peRed;
+	    info->bmiColors[i].rgbGreen    = palEntry->peGreen;
+	    info->bmiColors[i].rgbBlue     = palEntry->peBlue;
+	    info->bmiColors[i].rgbReserved = 0;
+	}
+	else ((WORD *)info->bmiColors)[i] = (WORD)i;
+    }
+    
+      /* Transfer the pixels (very slow...) */
+
+    if (bits)
+    {	
+	bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) );
+	dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
+
+	for (y = 0; y < lines; y++)
+	{
+	    for (x = 0; x < info->bmiHeader.biWidth; x++)
+	    {
+		XPutPixel( dibImage, x, y,
+		         XGetPixel(bmpImage, x, bmp->bmHeight-startscan-y-1) );
+		
+	    }
+	}
+	
+	bmpImage->data = NULL;
+	dibImage->data = NULL;
+	XDestroyImage( bmpImage );
+	XDestroyImage( dibImage );
+    }
+
+    GlobalUnlock( bmpObj->hBitmap );
+    return lines;
+}
+
+
+/***********************************************************************
+ *           CreateDIBitmap    (GDI.442)
+ */
+HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init,
+		        LPSTR bits, BITMAPINFO * data, WORD coloruse )
+{
+    HBITMAP handle;
+    
+    handle = CreateCompatibleBitmap( hdc, header->biWidth, header->biHeight );
+    if (!handle) return 0;
+    if (init == CBM_INIT) SetDIBits( hdc, handle, 0, header->biHeight,
+				    bits, data, coloruse );
+    return handle;
+}
diff --git a/objects/font.c b/objects/font.c
new file mode 100644
index 0000000..c30fcec
--- /dev/null
+++ b/objects/font.c
@@ -0,0 +1,332 @@
+/*
+ * GDI font objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xatom.h>
+#include "gdi.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+
+/***********************************************************************
+ *           FONT_MatchFont
+ *
+ * Find a X font matching the logical font.
+ */
+XFontStruct * FONT_MatchFont( DC * dc, LOGFONT * font )
+{
+    char pattern[100];
+    char *family, *weight, *charset;
+    char **names;
+    char slant, spacing;
+    int width, height, count;
+    XFontStruct * fontStruct;
+    
+    weight = (font->lfWeight > 550) ? "bold" : "medium";
+    slant = font->lfItalic ? 'i' : 'r';
+    height = font->lfHeight * 10;
+    width = font->lfWidth * 10;
+    spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
+	      (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
+    charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*";
+    family = font->lfFaceName;
+    if (!*family) switch(font->lfPitchAndFamily & 0xf0)
+    {
+      case FF_ROMAN:      family = "times"; break;
+      case FF_SWISS:      family = "helvetica"; break;
+      case FF_MODERN:     family = "courier"; break;
+      case FF_SCRIPT:     family = "*"; break;
+      case FF_DECORATIVE: family = "*"; break;
+      default:            family = "*"; break;
+    }
+    
+    sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s",
+	    family, weight, slant, height, spacing, width, charset );
+#ifdef DEBUG_FONT
+    printf( "FONT_MatchFont: '%s'\n", pattern );
+#endif
+    names = XListFonts( XT_display, pattern, 1, &count );
+    if (!count)
+    {
+#ifdef DEBUG_FONT
+	printf( "        No matching font found\n" );	
+#endif
+	return NULL;
+    }
+#ifdef DEBUG_FONT
+    printf( "        Found '%s'\n", *names );
+#endif
+    fontStruct = XLoadQueryFont( XT_display, *names );
+    XFreeFontNames( names );
+    return fontStruct;
+}
+
+
+/***********************************************************************
+ *           FONT_GetMetrics
+ */
+void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
+		      TEXTMETRIC * metrics )
+{    
+    int average, i;
+    unsigned long prop;
+	
+    metrics->tmAscent  = xfont->ascent;
+    metrics->tmDescent = xfont->descent;
+    metrics->tmHeight  = xfont->ascent + xfont->descent;
+
+    metrics->tmInternalLeading  = 0;
+    if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
+	metrics->tmInternalLeading = xfont->ascent - (short)prop;
+    metrics->tmExternalLeading  = 0;
+    metrics->tmMaxCharWidth     = xfont->max_bounds.width;
+    metrics->tmWeight           = logfont->lfWeight;
+    metrics->tmItalic           = logfont->lfItalic;
+    metrics->tmUnderlined       = logfont->lfUnderline;
+    metrics->tmStruckOut        = logfont->lfStrikeOut;
+    metrics->tmFirstChar        = xfont->min_char_or_byte2;
+    metrics->tmLastChar         = xfont->max_char_or_byte2;
+    metrics->tmDefaultChar      = xfont->default_char;
+    metrics->tmBreakChar        = ' ';
+    metrics->tmPitchAndFamily   = logfont->lfPitchAndFamily;
+    metrics->tmCharSet          = logfont->lfCharSet;
+    metrics->tmOverhang         = 0;
+    metrics->tmDigitizedAspectX = 1;
+    metrics->tmDigitizedAspectY = 1;
+
+    if (xfont->per_char) average = metrics->tmMaxCharWidth;
+    else
+    {
+	XCharStruct * charPtr = xfont->per_char;
+	average = 0;
+	for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
+	{
+	    average += charPtr->width;
+	    charPtr++;
+	}
+	average /= metrics->tmLastChar - metrics->tmFirstChar + 1;
+    }
+    metrics->tmAveCharWidth = average;
+}
+
+
+/***********************************************************************
+ *           CreateFontIndirect    (GDI.57)
+ */
+HFONT CreateFontIndirect( LOGFONT * font )
+{
+    FONTOBJ * fontPtr;
+    HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
+    if (!hfont) return 0;
+    fontPtr = (FONTOBJ *) GDI_HEAP_ADDR( hfont );
+    memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
+    return hfont;
+}
+
+
+/***********************************************************************
+ *           CreateFont    (GDI.56)
+ */
+HFONT CreateFont( int height, int width, int esc, int orient, int weight,
+		  BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
+		  BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
+		  LPSTR name )
+{
+    LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
+		    strikeout, charset, outpres, clippres, quality, pitch, };
+    strncpy( logfont.lfFaceName, name, LF_FACESIZE );
+    return CreateFontIndirect( &logfont );
+}
+
+
+/***********************************************************************
+ *           FONT_GetObject
+ */
+int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
+{
+    if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
+    memcpy( buffer, &font->logfont, count );
+    return count;
+}
+
+
+/***********************************************************************
+ *           FONT_SelectObject
+ */
+HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
+{
+    static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
+    X_PHYSFONT * stockPtr;
+    HFONT prevHandle = dc->w.hFont;
+    XFontStruct * fontStruct;
+
+      /* Load font if necessary */
+
+    if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
+	stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
+    else stockPtr = NULL;
+    
+    if (!stockPtr || !stockPtr->fstruct)
+    {
+	fontStruct = FONT_MatchFont( dc, &font->logfont );
+    }
+    else
+    {
+	fontStruct = stockPtr->fstruct;
+#ifdef DEBUG_FONT
+	printf( "FONT_SelectObject: Loaded font from cache %x %p\n",
+	        hfont, fontStruct );
+#endif
+    }	
+    if (!fontStruct) return 0;
+
+      /* Free previous font */
+
+    if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
+    {
+	if (dc->u.x.font.fstruct)
+	    XFreeFont( XT_display, dc->u.x.font.fstruct );
+    }
+
+      /* Store font */
+
+    dc->w.hFont = hfont;
+    if (stockPtr)
+    {
+	if (!stockPtr->fstruct)
+	{
+	    stockPtr->fstruct = fontStruct;
+	    FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
+	}
+	memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
+    }
+    else
+    {
+	dc->u.x.font.fstruct = fontStruct;
+	FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
+    }
+    return prevHandle;
+}
+
+
+/***********************************************************************
+ *           GetTextCharacterExtra    (GDI.89)
+ */
+short GetTextCharacterExtra( HDC hdc )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
+	         / dc->w.VportExtX );
+}
+
+
+/***********************************************************************
+ *           SetTextCharacterExtra    (GDI.8)
+ */
+short SetTextCharacterExtra( HDC hdc, short extra )
+{
+    short prev;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;    
+    prev = dc->w.charExtra;
+    dc->w.charExtra = abs(extra);
+    return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
+}
+
+
+/***********************************************************************
+ *           SetTextJustification    (GDI.10)
+ */
+short SetTextJustification( HDC hdc, short extra, short breaks )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+
+    extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
+    if (!extra) breaks = 0;
+    dc->w.breakTotalExtra = extra;
+    dc->w.breakCount = breaks;
+    if (breaks)
+    {	
+	dc->w.breakExtra = extra / breaks;
+	dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
+    }
+    else
+    {
+	dc->w.breakExtra = 0;
+	dc->w.breakRem   = 0;
+    }
+    return 1;
+}
+
+
+/***********************************************************************
+ *           GetTextExtent    (GDI.91)
+ */
+DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
+{
+    SIZE size;
+    if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
+    return size.cx | (size.cy << 16);
+}
+
+
+/***********************************************************************
+ *           GetTextExtentPoint    (GDI.471)
+ */
+BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
+{
+    int dir, ascent, descent;
+    XCharStruct info;
+
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
+		  &ascent, &descent, &info );
+    size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
+		    * dc->w.WndExtX / dc->w.VportExtX);
+    size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
+		    * dc->w.WndExtY / dc->w.VportExtY);
+
+#ifdef DEBUG_FONT
+    printf( "GetTextExtentPoint(%d '%s' %d %p): returning %d,%d\n",
+	    hdc, str, count, size, size->cx, size->cy );
+#endif
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetTextMetrics    (GDI.93)
+ */
+BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
+
+    metrics->tmAscent  = abs( metrics->tmAscent
+			      * dc->w.WndExtY / dc->w.VportExtY );
+    metrics->tmDescent = abs( metrics->tmDescent
+			      * dc->w.WndExtY / dc->w.VportExtY );
+    metrics->tmHeight  = metrics->tmAscent + metrics->tmDescent;
+    metrics->tmInternalLeading = abs( metrics->tmInternalLeading
+				      * dc->w.WndExtY / dc->w.VportExtY );
+    metrics->tmExternalLeading = abs( metrics->tmExternalLeading
+				      * dc->w.WndExtY / dc->w.VportExtY );
+    metrics->tmMaxCharWidth    = abs( metrics->tmMaxCharWidth 
+				      * dc->w.WndExtX / dc->w.VportExtX );
+    metrics->tmAveCharWidth    = abs( metrics->tmAveCharWidth
+				      * dc->w.WndExtX / dc->w.VportExtX );
+    return TRUE;
+}
+
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
new file mode 100644
index 0000000..55237c3
--- /dev/null
+++ b/objects/gdiobj.c
@@ -0,0 +1,380 @@
+/*
+ * GDI functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "gdi.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+MDESC *GDI_Heap = NULL;
+
+
+/***********************************************************************
+ *          GDI stock objects 
+ */
+
+static BRUSHOBJ WhiteBrush =
+{
+    { 0, BRUSH_MAGIC, 1, 0 },          /* header */
+    { BS_SOLID, RGB(255,255,255), 0 }  /* logbrush */
+};
+
+static BRUSHOBJ LtGrayBrush =
+{
+    { 0, BRUSH_MAGIC, 1, 0 },          /* header */
+    { BS_SOLID, RGB(192,192,192), 0 }  /* logbrush */
+};
+
+static BRUSHOBJ GrayBrush =
+{
+    { 0, BRUSH_MAGIC, 1, 0 },          /* header */
+    { BS_SOLID, RGB(128,128,128), 0 }  /* logbrush */
+};
+
+static BRUSHOBJ DkGrayBrush =
+{
+    { 0, BRUSH_MAGIC, 1, 0 },       /* header */
+    { BS_SOLID, RGB(64,64,64), 0 }  /* logbrush */
+};
+
+static BRUSHOBJ BlackBrush =
+{
+    { 0, BRUSH_MAGIC, 1, 0 },    /* header */
+    { BS_SOLID, RGB(0,0,0), 0 }  /* logbrush */
+};
+
+static BRUSHOBJ NullBrush =
+{
+    { 0, BRUSH_MAGIC, 1, 0 },  /* header */
+    { BS_NULL, 0, 0 }          /* logbrush */
+};
+
+static PENOBJ WhitePen =
+{
+    { 0, PEN_MAGIC, 1, 0 },                  /* header */
+    { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
+};
+
+static PENOBJ BlackPen =
+{
+    { 0, PEN_MAGIC, 1, 0 },            /* header */
+    { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
+};
+
+static PENOBJ NullPen =
+{
+    { 0, PEN_MAGIC, 1, 0 },   /* header */
+    { PS_NULL, { 1, 0 }, 0 }  /* logpen */
+};
+
+static FONTOBJ OEMFixedFont =
+{
+    { 0, FONT_MAGIC, 1, 0 },   /* header */
+    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
+      0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
+};
+
+static FONTOBJ AnsiFixedFont =
+{
+    { 0, FONT_MAGIC, 1, 0 },   /* header */
+    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+      0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
+};
+
+static FONTOBJ AnsiVarFont =
+{
+    { 0, FONT_MAGIC, 1, 0 },   /* header */
+    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
+};
+
+static FONTOBJ SystemFont =
+{
+    { 0, FONT_MAGIC, 1, 0 },   /* header */
+    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
+};
+
+static FONTOBJ DeviceDefaultFont =
+{
+    { 0, FONT_MAGIC, 1, 0 },   /* header */
+    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+      0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
+};
+
+static FONTOBJ SystemFixedFont =
+{
+    { 0, FONT_MAGIC, 1, 0 },   /* header */
+    { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+      0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
+};
+
+
+static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
+{
+    (GDIOBJHDR *) &WhiteBrush,
+    (GDIOBJHDR *) &LtGrayBrush,
+    (GDIOBJHDR *) &GrayBrush,
+    (GDIOBJHDR *) &DkGrayBrush,
+    (GDIOBJHDR *) &BlackBrush,
+    (GDIOBJHDR *) &NullBrush,
+    (GDIOBJHDR *) &WhitePen,
+    (GDIOBJHDR *) &BlackPen,
+    (GDIOBJHDR *) &NullPen,
+    NULL,
+    (GDIOBJHDR *) &OEMFixedFont,
+    (GDIOBJHDR *) &AnsiFixedFont,
+    (GDIOBJHDR *) &AnsiVarFont,
+    (GDIOBJHDR *) &SystemFont,
+    (GDIOBJHDR *) &DeviceDefaultFont,
+    NULL,            /* DEFAULT_PALETTE created by PALETTE_Init */
+    (GDIOBJHDR *) &SystemFixedFont
+};
+
+extern GDIOBJHDR * PALETTE_systemPalette;
+
+
+/***********************************************************************
+ *           GDI_Init
+ *
+ * GDI initialisation.
+ */
+BOOL GDI_Init()
+{
+    struct segment_descriptor_s * s;
+
+      /* Create GDI heap */
+
+    s = GetNextSegment( 0, 0x10000 );
+    if (s == NULL) return FALSE;
+    HEAP_Init( &GDI_Heap, s->base_addr, GDI_HEAP_SIZE );
+    free(s);
+
+      /* Create default palette */
+
+    PALETTE_Init();
+    StockObjects[DEFAULT_PALETTE] = PALETTE_systemPalette;
+
+      /* Create default bitmap */
+
+    if (!BITMAP_Init()) return FALSE;
+
+      /* Initialise regions */
+
+    if (!REGION_Init()) return FALSE;
+    
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GDI_FindPrevObject
+ *
+ * Return the GDI object whose hNext field points to obj.
+ */
+HANDLE GDI_FindPrevObject( HANDLE first, HANDLE obj )
+{
+    HANDLE handle;
+        
+    for (handle = first; handle && (handle != obj); )
+    {
+	GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+	handle = header->hNext;
+    }
+    return handle;
+}
+
+
+/***********************************************************************
+ *           GDI_AllocObject
+ */
+HANDLE GDI_AllocObject( WORD size, WORD magic )
+{
+    static DWORD count = 0;
+    GDIOBJHDR * obj;
+    HANDLE handle = GDI_HEAP_ALLOC( GMEM_MOVEABLE, size );
+    if (!handle) return 0;
+    
+    obj = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    obj->hNext   = 0;
+    obj->wMagic  = magic;
+    obj->dwCount = ++count;
+    return handle;
+}
+
+
+/***********************************************************************
+ *           GDI_FreeObject
+ */
+BOOL GDI_FreeObject( HANDLE handle )
+{
+    GDIOBJHDR * object;
+    HANDLE prev;
+
+      /* Can't free stock objects */
+    if (handle >= FIRST_STOCK_HANDLE) return FALSE;
+    
+    object = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    if (!object) return FALSE;
+
+      /* Free object */
+    
+    GDI_HEAP_FREE( handle );
+    return TRUE;
+}
+
+/***********************************************************************
+ *           GDI_GetObjPtr
+ *
+ * Return a pointer to the GDI object associated to the handle.
+ * Return NULL if the object has the wrong magic number.
+ */
+GDIOBJHDR * GDI_GetObjPtr( HANDLE handle, WORD magic )
+{
+    GDIOBJHDR * ptr = NULL;
+
+    if (handle >= FIRST_STOCK_HANDLE)
+    {
+	if (handle < FIRST_STOCK_HANDLE + NB_STOCK_OBJECTS)
+	    ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
+    }
+    else ptr = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    if (!ptr) return NULL;
+    if (ptr->wMagic != magic) return NULL;
+    return ptr;
+}
+
+
+/***********************************************************************
+ *           DeleteObject    (GDI.69)
+ */
+BOOL DeleteObject( HANDLE obj )
+{
+      /* Check if object is valid */
+
+    GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_ADDR( obj );
+    if (!header) return FALSE;
+
+#ifdef DEBUG_GDI
+    printf( "DeleteObject: %d\n", obj );
+#endif
+
+      /* Delete object */
+
+    switch(header->wMagic)
+    {
+      case PEN_MAGIC:     return GDI_FreeObject( obj );
+      case BRUSH_MAGIC:   return BRUSH_DeleteObject( obj, header );
+      case FONT_MAGIC:    return GDI_FreeObject( obj );
+      case PALETTE_MAGIC: return GDI_FreeObject( obj );
+      case BITMAP_MAGIC:  return BMP_DeleteObject( obj, header );
+      case REGION_MAGIC:  return REGION_DeleteObject( obj, header );
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           GetStockObject    (GDI.87)
+ */
+HANDLE GetStockObject( int obj )
+{
+    if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
+    if (!StockObjects[obj]) return 0;
+#ifdef DEBUG_GDI
+    printf( "GetStockObject: returning %04x\n", FIRST_STOCK_HANDLE + obj );
+#endif
+    return FIRST_STOCK_HANDLE + obj;
+}
+
+
+/***********************************************************************
+ *           GetObject    (GDI.82)
+ */
+int GetObject( HANDLE handle, int count, LPSTR buffer )
+{
+    GDIOBJHDR * ptr = NULL;
+#ifdef DEBUG_GDI
+    printf( "GetObject: %04x %d %08x\n", handle, count, buffer );
+#endif
+    if (!count) return 0;
+
+    if (handle >= FIRST_STOCK_HANDLE)
+    {
+	if (handle < FIRST_STOCK_HANDLE + NB_STOCK_OBJECTS)
+	    ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
+    }
+    else ptr = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    if (!ptr) return 0;
+    
+    switch(ptr->wMagic)
+    {
+      case PEN_MAGIC:
+	  return PEN_GetObject( (PENOBJ *)ptr, count, buffer );
+      case BRUSH_MAGIC: 
+	  return BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
+      case BITMAP_MAGIC: 
+	  return BMP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
+      case FONT_MAGIC:
+	  return FONT_GetObject( (FONTOBJ *)ptr, count, buffer );
+      case PALETTE_MAGIC:
+	  return PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           SelectObject    (GDI.45)
+ */
+HANDLE SelectObject( HDC hdc, HANDLE handle )
+{
+    GDIOBJHDR * ptr = NULL;
+    DC * dc;
+    
+#ifdef DEBUG_GDI
+    printf( "SelectObject: %d %04x\n", hdc, handle );
+#endif
+    if (handle >= FIRST_STOCK_HANDLE)
+    {
+	if (handle < FIRST_STOCK_HANDLE + NB_STOCK_OBJECTS)
+	    ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
+    }
+    else ptr = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    if (!ptr) return 0;
+    
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    
+    switch(ptr->wMagic)
+    {
+      case PEN_MAGIC:
+	  return PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
+      case BRUSH_MAGIC:
+	  return BRUSH_SelectObject( hdc, dc, handle, (BRUSHOBJ *)ptr );
+      case BITMAP_MAGIC:
+	  return BITMAP_SelectObject( hdc, dc, handle, (BITMAPOBJ *)ptr );
+      case FONT_MAGIC:
+	  return FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );	  
+      case REGION_MAGIC:
+	  return SelectClipRgn( hdc, handle );
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           UnrealizeObject    (GDI.150)
+ */
+BOOL UnrealizeObject( HANDLE handle )
+{
+#ifdef DEBUG_GDI
+    printf( "UnrealizeObject: %04x\n", handle );
+#endif
+    return TRUE;
+}
diff --git a/objects/linedda.c b/objects/linedda.c
new file mode 100644
index 0000000..f95ea48
--- /dev/null
+++ b/objects/linedda.c
@@ -0,0 +1,19 @@
+/*
+ * LineDDA
+ *
+ * Copyright 1993 Bob Amstadt
+ */
+
+static char Copyright[] = "Copyright  Bob Amstadt, 1993";
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include "win.h"
+
+/**********************************************************************
+ *		LineDDA		(GDI.100)
+ */
+void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd,
+	     FARPROC callback, long lParam)
+{
+}
diff --git a/objects/palette.c b/objects/palette.c
new file mode 100644
index 0000000..bdde29d
--- /dev/null
+++ b/objects/palette.c
@@ -0,0 +1,191 @@
+/*
+ * GDI palette objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdlib.h>
+#include <values.h>
+#include <X11/Xlib.h>
+
+#include "gdi.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+
+#define NB_RESERVED_COLORS  17
+static char * ReservedColors[NB_RESERVED_COLORS] =
+{
+    "black",
+    "gray25",
+    "gray50",
+    "gray75",
+    "white",
+    "red1",
+    "red4",
+    "green1",
+    "green4",
+    "blue1",
+    "blue4",
+    "cyan1",
+    "cyan4",
+    "magenta1",
+    "magenta4",
+    "yellow1",
+    "yellow4"
+};
+
+GDIOBJHDR * PALETTE_systemPalette;
+
+static int SysColorPixels[NB_RESERVED_COLORS];
+
+
+/***********************************************************************
+ *           PALETTE_Init
+ */
+BOOL PALETTE_Init()
+{
+    int i, size, pixel;
+    XColor serverColor, exactColor;
+    HPALETTE hpalette;
+    LOGPALETTE * palPtr;
+
+    size = DefaultVisual(XT_display,DefaultScreen(XT_display))->map_entries;
+    palPtr = malloc( sizeof(LOGPALETTE) + (size-1)*sizeof(PALETTEENTRY) );
+    if (!palPtr) return FALSE;
+    palPtr->palVersion = 0x300;
+    palPtr->palNumEntries = size;
+    memset( palPtr->palPalEntry, 0xff, size*sizeof(PALETTEENTRY) );
+    
+    for (i = 0; i < NB_RESERVED_COLORS; i++)
+    {
+	if (XAllocNamedColor( XT_display,
+			      DefaultColormapOfScreen( XT_screen ),
+			      ReservedColors[i], 
+			      &serverColor, &exactColor ))
+	{
+	    pixel = serverColor.pixel;
+	    palPtr->palPalEntry[pixel].peRed   = serverColor.red >> 8;
+	    palPtr->palPalEntry[pixel].peGreen = serverColor.green >> 8;
+	    palPtr->palPalEntry[pixel].peBlue  = serverColor.blue >> 8;
+	    palPtr->palPalEntry[pixel].peFlags = 0;
+	}
+    }
+    hpalette = CreatePalette( palPtr );
+    PALETTE_systemPalette = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette );
+    free( palPtr );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CreatePalette    (GDI.360)
+ */
+HPALETTE CreatePalette( LOGPALETTE * palette )
+{
+    PALETTEOBJ * palettePtr;
+    HPALETTE hpalette;
+    int size;
+
+    size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
+    hpalette = GDI_AllocObject( sizeof(GDIOBJHDR) + size, PALETTE_MAGIC );
+    if (!hpalette) return 0;
+    palettePtr = (PALETTEOBJ *) GDI_HEAP_ADDR( hpalette );
+    memcpy( &palettePtr->logpalette, palette, size );
+    return hpalette;
+}
+
+
+/***********************************************************************
+ *           GetPaletteEntries    (GDI.363)
+ */
+WORD GetPaletteEntries( HPALETTE hpalette, WORD start, WORD count,
+		        LPPALETTEENTRY entries )
+{
+    PALETTEOBJ * palPtr;
+    int numEntries;
+        
+    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+    if (!palPtr) return 0;
+    numEntries = palPtr->logpalette.palNumEntries;
+    if (start >= numEntries) return 0;
+    if (start+count > numEntries) count = numEntries - start;
+    memcpy( entries, &palPtr->logpalette.palPalEntry[start],
+	    count * sizeof(PALETTEENTRY) );
+    return count;
+}
+
+
+/***********************************************************************
+ *           SetPaletteEntries    (GDI.364)
+ */
+WORD SetPaletteEntries( HPALETTE hpalette, WORD start, WORD count,
+		        LPPALETTEENTRY entries )
+{
+    PALETTEOBJ * palPtr;
+    int numEntries;
+        
+    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+    if (!palPtr) return 0;
+    numEntries = palPtr->logpalette.palNumEntries;
+    if (start >= numEntries) return 0;
+    if (start+count > numEntries) count = numEntries - start;
+    memcpy( &palPtr->logpalette.palPalEntry[start], entries,
+	    count * sizeof(PALETTEENTRY) );
+    return count;
+}
+
+
+/***********************************************************************
+ *           GetNearestPaletteIndex    (GDI.370)
+ */
+WORD GetNearestPaletteIndex( HPALETTE hpalette, COLORREF color )
+{
+    int i, minDist, dist;
+    WORD index = 0;
+    BYTE r, g, b;
+    PALETTEENTRY * entry;
+    PALETTEOBJ * palPtr;
+    
+    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+    if (!palPtr) return 0;
+    
+    r = GetRValue(color);
+    g = GetGValue(color);
+    b = GetBValue(color);
+    entry = palPtr->logpalette.palPalEntry;
+    for (i = 0, minDist = MAXINT; i < palPtr->logpalette.palNumEntries; i++)
+    {
+	if (entry->peFlags != 0xff)
+	{
+	    dist = (r - entry->peRed) * (r - entry->peRed) +
+		   (g - entry->peGreen) * (g - entry->peGreen) +
+		   (b - entry->peBlue) * (b - entry->peBlue);	
+	    if (dist < minDist)
+	    {
+		minDist = dist;
+		index = i;
+	    }
+	}
+	entry++;
+    }
+#ifdef DEBUG_GDI
+    printf( "GetNearestPaletteIndex(%x,%06x) : returning %d\n", 
+	     hpalette, color, index );
+#endif
+    return index;
+}
+
+
+/***********************************************************************
+ *           PALETTE_GetObject
+ */
+int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
+{
+    if (count > sizeof(WORD)) count = sizeof(WORD);
+    memcpy( buffer, &palette->logpalette.palNumEntries, count );
+    return count;
+}
diff --git a/objects/pen.c b/objects/pen.c
new file mode 100644
index 0000000..fa49ef3
--- /dev/null
+++ b/objects/pen.c
@@ -0,0 +1,93 @@
+/*
+ * GDI pen objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "gdi.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+
+/***********************************************************************
+ *           CreatePen    (GDI.61)
+ */
+HPEN CreatePen( short style, short width, COLORREF color )
+{
+    LOGPEN logpen = { style, { width, 0 }, color };
+#ifdef DEBUG_GDI
+    printf( "CreatePen: %d %d %06x\n", style, width, color );
+#endif
+    return CreatePenIndirect( &logpen );
+}
+
+
+/***********************************************************************
+ *           CreatePenIndirect    (GDI.62)
+ */
+HPEN CreatePenIndirect( LOGPEN * pen )
+{
+    PENOBJ * penPtr;
+    HPEN hpen;
+
+    if (pen->lopnStyle > PS_INSIDEFRAME) return 0;
+    hpen = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC );
+    if (!hpen) return 0;
+    penPtr = (PENOBJ *) GDI_HEAP_ADDR( hpen );    
+    memcpy( &penPtr->logpen, pen, sizeof(LOGPEN) );
+    return hpen;
+}
+
+
+/***********************************************************************
+ *           PEN_GetObject
+ */
+int PEN_GetObject( PENOBJ * pen, int count, LPSTR buffer )
+{
+    if (count > sizeof(LOGPEN)) count = sizeof(LOGPEN);
+    memcpy( buffer, &pen->logpen, count );
+    return count;
+}
+
+
+/***********************************************************************
+ *           PEN_SelectObject
+ */
+HPEN PEN_SelectObject( DC * dc, HPEN hpen, PENOBJ * pen )
+{
+    static char dash_dash[]       = { 5, 3 };      /* -----   -----   -----  */
+    static char dash_dot[]        = { 2, 2 };      /* --  --  --  --  --  -- */
+    static char dash_dashdot[]    = { 4,3,2,3 };   /* ----   --   ----   --  */
+    static char dash_dashdotdot[] = { 4,2,2,2,2,2 };  /* ----  --  --  ----  */
+
+    HPEN prevHandle = dc->w.hPen;
+    dc->w.hPen = hpen;
+
+    dc->u.x.pen.style = pen->logpen.lopnStyle;
+    dc->u.x.pen.width = pen->logpen.lopnWidth.x * dc->w.VportExtX
+	                  / dc->w.WndExtX;
+    if (dc->u.x.pen.width < 0) dc->u.x.pen.width = -dc->u.x.pen.width;
+    if (dc->u.x.pen.width == 1) dc->u.x.pen.width = 0;  /* Faster */
+    dc->u.x.pen.pixel = GetNearestPaletteIndex( dc->w.hPalette,
+					        pen->logpen.lopnColor );    
+    switch(pen->logpen.lopnStyle)
+    {
+      case PS_DASH:
+	XSetDashes( XT_display, dc->u.x.gc, 0, dash_dash, 2 );
+	break;
+      case PS_DOT:
+	XSetDashes( XT_display, dc->u.x.gc, 0, dash_dot, 2 );
+	break;
+      case PS_DASHDOT:
+	XSetDashes( XT_display, dc->u.x.gc, 0, dash_dashdot, 4 );
+	break;
+      case PS_DASHDOTDOT:
+	XSetDashes( XT_display, dc->u.x.gc, 0, dash_dashdotdot, 6 );
+	break;
+    }
+    
+    return prevHandle;
+}
diff --git a/objects/region.c b/objects/region.c
new file mode 100644
index 0000000..2c22ee4
--- /dev/null
+++ b/objects/region.c
@@ -0,0 +1,614 @@
+/*
+ * GDI region objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "gdi.h"
+
+
+  /* GC used for region operations */
+static GC regionGC = 0;
+
+
+/***********************************************************************
+ *           REGION_Init
+ */
+BOOL REGION_Init()
+{
+    Pixmap tmpPixmap;
+
+      /* CreateGC needs a drawable */
+    tmpPixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display),
+			       1, 1, 1 );
+    if (tmpPixmap)
+    {
+	regionGC = XCreateGC( XT_display, tmpPixmap, 0, NULL );
+	XFreePixmap( XT_display, tmpPixmap );
+	if (!regionGC) return FALSE;
+	XSetForeground( XT_display, regionGC, 1 );
+	return TRUE;
+    }
+    else return FALSE;
+}
+
+
+/***********************************************************************
+ *           REGION_SetRect
+ *
+ * Set the bounding box of the region and create the pixmap.
+ * The hrgn must be valid.
+ */
+static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect )
+{
+    int width, height;
+
+      /* Fill region */
+
+    REGION * region = &((RGNOBJ *)GDI_HEAP_ADDR( hrgn ))->region;
+    width  = rect->right - rect->left;
+    height = rect->bottom - rect->top;
+    if ((width <= 0) || (height <= 0))
+    {
+	region->type       = NULLREGION;
+	region->box.left   = 0;
+	region->box.right  = 0;
+	region->box.top    = 0;
+	region->box.bottom = 0;
+	region->pixmap     = 0;
+	return TRUE;
+    }
+    region->type = SIMPLEREGION;
+    region->box  = *rect;
+    
+      /* Create pixmap */
+
+    region->pixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display),
+				    width, height, 1 );
+    if (!region->pixmap) return FALSE;
+
+      /* Fill pixmap */
+
+    XSetFunction( XT_display, regionGC, GXclear );
+    XFillRectangle( XT_display, region->pixmap, regionGC,
+		    0, 0, width, height );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           REGION_DeleteObject
+ */
+BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj )
+{
+    if (obj->region.pixmap) XFreePixmap( XT_display, obj->region.pixmap );
+    return GDI_FreeObject( hrgn );
+}
+
+
+/***********************************************************************
+ *           OffsetRgn    (GDI.101)
+ */
+int OffsetRgn( HRGN hrgn, short x, short y )
+{
+    RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
+    if (!obj) return ERROR;
+#ifdef DEBUG_REGION
+    printf( "OffsetRgn: %d %d,%d\n", hrgn, x, y );
+#endif
+    OffsetRect( &obj->region.box, x, y );
+    return obj->region.type;
+}
+
+
+/***********************************************************************
+ *           GetRgnBox    (GDI.134)
+ */
+int GetRgnBox( HRGN hrgn, LPRECT rect )
+{
+    RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
+    if (!obj) return ERROR;
+#ifdef DEBUG_REGION
+    printf( "GetRgnBox: %d\n", hrgn );
+#endif
+    *rect = obj->region.box;
+    return obj->region.type;
+}
+
+
+/***********************************************************************
+ *           CreateRectRgn    (GDI.64)
+ */
+HRGN CreateRectRgn( short left, short top, short right, short bottom )
+{
+    RECT rect = { left, top, right, bottom };    
+    return CreateRectRgnIndirect( &rect );
+}
+
+
+/***********************************************************************
+ *           CreateRectRgnIndirect    (GDI.65)
+ */
+HRGN CreateRectRgnIndirect( LPRECT rect )
+{
+    RGNOBJ * rgnObj;
+    HRGN hrgn;
+
+#ifdef DEBUG_REGION
+    printf( "CreateRectRgnIndirect: %d,%d-%d,%d\n",
+	    rect->left, rect->top, rect->right, rect->bottom );
+#endif
+    
+      /* Create region */
+
+    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
+    if (!REGION_SetRect( hrgn, rect ))
+    {
+	GDI_FreeObject( hrgn );
+	return 0;
+    }
+    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+
+      /* Fill pixmap */
+    
+    if (rgnObj->region.type != NULLREGION)
+    {
+	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
+	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
+	XSetFunction( XT_display, regionGC, GXcopy );
+	XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC,
+		        0, 0, width, height );
+    }
+    
+    return hrgn;
+}
+
+
+/***********************************************************************
+ *           CreateRoundRectRgn    (GDI.444)
+ */
+HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
+			 short ellipse_width, short ellipse_height )
+{
+    RECT rect = { left, top, right, bottom };    
+    RGNOBJ * rgnObj;
+    HRGN hrgn;
+
+#ifdef DEBUG_REGION
+    printf( "CreateRoundRectRgn: %d,%d-%d,%d %dx%d\n",
+	    left, top, right, bottom, ellipse_width, ellipse_height );
+#endif
+    
+      /* Create region */
+
+    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
+    if (!REGION_SetRect( hrgn, &rect ))
+    {
+	GDI_FreeObject( hrgn );
+	return 0;
+    }
+    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+
+      /* Fill pixmap */
+    
+    if (rgnObj->region.type != NULLREGION)
+    {
+	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
+	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
+	XSetFunction( XT_display, regionGC, GXcopy );
+	XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC,
+		        0, ellipse_height / 2,
+		        width, height - ellipse_height );
+	XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC,
+		        ellipse_width / 2, 0,
+		        width - ellipse_width, height );
+	XFillArc( XT_display, rgnObj->region.pixmap, regionGC,
+		  0, 0,
+		  ellipse_width, ellipse_height, 0, 360*64 );
+	XFillArc( XT_display, rgnObj->region.pixmap, regionGC,
+		  width - ellipse_width, 0,
+		  ellipse_width, ellipse_height, 0, 360*64 );
+	XFillArc( XT_display, rgnObj->region.pixmap, regionGC,
+		  0, height - ellipse_height,
+		  ellipse_width, ellipse_height, 0, 360*64 );
+	XFillArc( XT_display, rgnObj->region.pixmap, regionGC,
+		  width - ellipse_width, height - ellipse_height,
+		  ellipse_width, ellipse_height, 0, 360*64 );
+    }
+    
+    return hrgn;
+}
+
+
+/***********************************************************************
+ *           SetRectRgn    (GDI.172)
+ */
+void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
+{
+    RECT rect = { left, top, right, bottom };    
+    RGNOBJ * rgnObj;
+
+#ifdef DEBUG_REGION
+    printf( "SetRectRgn: %d %d,%d-%d,%d\n", hrgn, left, top, right, bottom );
+#endif
+    
+      /* Free previous pixmap */
+
+    if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
+    if (rgnObj->region.pixmap) 
+	XFreePixmap( XT_display, rgnObj->region.pixmap );
+
+    if (!REGION_SetRect( hrgn, &rect )) return;
+
+      /* Fill pixmap */
+    
+    if (rgnObj->region.type != NULLREGION)
+    {
+	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
+	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
+	XSetFunction( XT_display, regionGC, GXcopy );
+	XFillRectangle( XT_display, rgnObj->region.pixmap, regionGC,
+		        0, 0, width, height );
+    }
+}
+
+
+/***********************************************************************
+ *           CreateEllipticRgn    (GDI.54)
+ */
+HRGN CreateEllipticRgn( short left, short top, short right, short bottom )
+{
+    RECT rect = { left, top, right, bottom };    
+    return CreateEllipticRgnIndirect( &rect );
+}
+
+
+/***********************************************************************
+ *           CreateEllipticRgnIndirect    (GDI.55)
+ */
+HRGN CreateEllipticRgnIndirect( LPRECT rect )
+{
+    RGNOBJ * rgnObj;
+    HRGN hrgn;
+
+#ifdef DEBUG_REGION
+    printf( "CreateEllipticRgnIndirect: %d,%d-%d,%d\n",
+	    rect->left, rect->top, rect->right, rect->bottom );
+#endif
+    
+      /* Create region */
+
+    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
+    if (!REGION_SetRect( hrgn, rect ))
+    {
+	GDI_FreeObject( hrgn );
+	return 0;
+    }
+    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+
+      /* Fill pixmap */
+    
+    if (rgnObj->region.type != NULLREGION)
+    {
+	int width  = rgnObj->region.box.right - rgnObj->region.box.left;
+	int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
+	XSetFunction( XT_display, regionGC, GXcopy );
+	XFillArc( XT_display, rgnObj->region.pixmap, regionGC,
+		  0, 0, width, height, 0, 360*64 );
+    }
+    
+    return hrgn;
+}
+
+
+/***********************************************************************
+ *           CreatePolygonRgn    (GDI.63)
+ */
+HRGN CreatePolygonRgn( POINT * points, short count, short mode )
+{
+    return CreatePolyPolygonRgn( points, &count, 1, mode );
+}
+
+
+/***********************************************************************
+ *           CreatePolyPolygonRgn    (GDI.451)
+ */
+HRGN CreatePolyPolygonRgn( POINT * points, short * count,
+			   short nbpolygons, short mode )
+{
+    RGNOBJ * rgnObj;
+    HRGN hrgn;
+    RECT box;
+    int i, j, totalPoints;
+    POINT * pt;
+    XPoint * xpoints;
+    
+    if (!nbpolygons) return 0;
+#ifdef DEBUG_REGION
+    printf( "CreatePolyPolygonRgn: %d polygons\n", nbpolygons );
+#endif
+    
+      /* Find bounding box */
+
+    box.top   = box.left   = 32767;
+    box.right = box.bottom = 0;
+    for (i = totalPoints = 0, pt = points; i < nbpolygons; i++)
+    {
+	totalPoints += count[i];
+	for (j = 0; j < count[i]; j++, pt++)
+	{
+	    if (pt->x < box.left) box.left = pt->x;
+	    if (pt->x > box.right) box.right = pt->x;
+	    if (pt->y < box.top) box.top = pt->y;
+	    if (pt->y > box.bottom) box.bottom = pt->y;
+	}
+    }        
+    if (!totalPoints) return 0;
+    
+      /* Build points array */
+
+    xpoints = (XPoint *) malloc( sizeof(XPoint) * totalPoints );
+    if (!xpoints) return 0;
+    for (i = 0, pt = points; i < totalPoints; i++, pt++)
+    {
+	xpoints[i].x = pt->x - box.left;
+	xpoints[i].y = pt->y - box.top;
+    }
+
+      /* Create region */
+
+    if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC )) ||
+	!REGION_SetRect( hrgn, &box ))
+    {
+	if (hrgn) GDI_FreeObject( hrgn );
+	free( xpoints );
+	return 0;
+    }
+    rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+
+      /* Fill pixmap */
+
+    if (rgnObj->region.type != NULLREGION)
+    {
+	XSetFunction( XT_display, regionGC, GXcopy );
+	if (mode == WINDING) XSetFillRule( XT_display, regionGC, WindingRule );
+	else XSetFillRule( XT_display, regionGC, EvenOddRule );
+	for (i = j = 0; i < nbpolygons; i++)
+	{
+	    XFillPolygon( XT_display, rgnObj->region.pixmap, regionGC,
+			  &xpoints[j], count[i], Complex, CoordModeOrigin );
+	    j += count[i];
+	}
+    }
+    
+    free( xpoints );
+    return hrgn;
+}
+
+
+/***********************************************************************
+ *           PtInRegion    (GDI.161)
+ */
+BOOL PtInRegion( HRGN hrgn, short x, short y )
+{
+    XImage * image;
+    BOOL res;
+    RGNOBJ * obj;
+    POINT pt = { x, y };
+    
+    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
+    if (!PtInRect( &obj->region.box, pt )) return FALSE;
+    image = XGetImage( XT_display, obj->region.pixmap,
+		       x - obj->region.box.left, y - obj->region.box.top,
+		       1, 1, AllPlanes, ZPixmap );
+    if (!image) return FALSE;
+    res = (XGetPixel( image, 0, 0 ) != 0);
+    XDestroyImage( image );
+    return res;
+}
+
+
+/***********************************************************************
+ *           RectInRegion    (GDI.181)
+ */
+BOOL RectInRegion( HRGN hrgn, LPRECT rect )
+{
+    XImage * image;
+    RGNOBJ * obj;
+    RECT intersect;
+    int x, y;
+    
+    if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
+    if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE;
+    
+    image = XGetImage( XT_display, obj->region.pixmap,
+		       intersect.left - obj->region.box.left,
+		       intersect.top - obj->region.box.top,
+		       intersect.right - intersect.left,
+		       intersect.bottom - intersect.top,
+		       AllPlanes, ZPixmap );
+    if (!image) return FALSE;
+    for (y = 0; y < image->height; y++)
+	for (x = 0; x < image->width; x++)
+	    if (XGetPixel( image, x, y ) != 0)
+	    {
+		XDestroyImage( image );
+		return TRUE;
+	    }
+    
+    XDestroyImage( image );
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *           EqualRgn    (GDI.72)
+ */
+BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
+{
+    RGNOBJ *obj1, *obj2;
+    XImage *image1, *image2;
+    int width, height, x, y;
+
+      /* Compare bounding boxes */
+
+    if (!(obj1 = (RGNOBJ *) GDI_GetObjPtr( rgn1, REGION_MAGIC ))) return FALSE;
+    if (!(obj2 = (RGNOBJ *) GDI_GetObjPtr( rgn2, REGION_MAGIC ))) return FALSE;
+    if (obj1->region.type == NULLREGION)
+	return (obj2->region.type == NULLREGION);
+    else if (obj2->region.type == NULLREGION) return FALSE;
+    if (!EqualRect( &obj1->region.box, &obj2->region.box )) return FALSE;
+
+      /* Get pixmap contents */
+
+    width  = obj1->region.box.right - obj1->region.box.left;
+    height = obj1->region.box.bottom - obj1->region.box.top;
+    image1 = XGetImage( XT_display, obj1->region.pixmap,
+		        0, 0, width, height, AllPlanes, ZPixmap );
+    if (!image1) return FALSE;
+    image2 = XGetImage( XT_display, obj2->region.pixmap,
+		        0, 0, width, height, AllPlanes, ZPixmap );
+    if (!image2)
+    {
+	XDestroyImage( image1 );
+	return FALSE;
+    }
+    
+      /* Compare pixmaps */
+    for (y = 0; y < height; y++)
+	for (x = 0; x < width; x++)
+	    if (XGetPixel( image1, x, y ) != XGetPixel( image2, x, y))
+	    {
+		XDestroyImage( image1 );
+		XDestroyImage( image2 );
+		return FALSE;
+	    }
+    
+    XDestroyImage( image1 );
+    XDestroyImage( image2 );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           REGION_CopyIntersection
+ *
+ * Copy to dest->pixmap the area of src->pixmap delimited by
+ * the intersection of dest and src regions, using the current GC function.
+ */
+void REGION_CopyIntersection( REGION * dest, REGION * src )
+{
+    RECT inter;
+    if (!IntersectRect( &inter, &dest->box, &src->box )) return;
+    XCopyArea( XT_display, src->pixmap, dest->pixmap, regionGC,
+	       inter.left - src->box.left, inter.top - src->box.top,
+	       inter.right - inter.left, inter.bottom - inter.top,
+	       inter.left - dest->box.left, inter.top - dest->box.top );
+}
+
+
+/***********************************************************************
+ *           CombineRgn    (GDI.451)
+ */
+int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
+{
+    RGNOBJ *destObj, *src1Obj, *src2Obj;
+    REGION * region;
+    int width, height;
+    BOOL res;
+    
+#ifdef DEBUG_REGION
+    printf( "CombineRgn: %d %d %d %d\n", hDest, hSrc1, hSrc2, mode );
+#endif
+    
+    if (!(destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC )))
+	return ERROR;
+    if (!(src1Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc1, REGION_MAGIC )))
+	return ERROR;
+    if (mode != RGN_COPY)
+	if (!(src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC )))
+	    return ERROR;
+    region = &destObj->region;
+
+    switch(mode)
+    {
+      case RGN_AND:
+	res = IntersectRect( &region->box, &src1Obj->region.box,
+			     &src2Obj->region.box );
+	break;
+
+      case RGN_OR:
+      case RGN_XOR:
+	res = UnionRect( &region->box, &src1Obj->region.box,
+			 &src2Obj->region.box );
+	break;
+
+      case RGN_DIFF:
+	res = SubtractRect( &region->box, &src1Obj->region.box,
+			    &src2Obj->region.box );
+	break;
+
+      case RGN_COPY:
+	region->box  = src1Obj->region.box;
+	region->type = src1Obj->region.type;
+	res = (region->type != NULLREGION);
+	break;
+
+      default:
+	return ERROR;
+    }
+
+    if (region->pixmap) XFreePixmap( XT_display, region->pixmap );    
+    if (!res)
+    {
+	region->type   = NULLREGION;
+	region->pixmap = 0;
+	return NULLREGION;
+    }
+    
+    width  = region->box.right - region->box.left;
+    height = region->box.bottom - region->box.top;
+    region->pixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display),
+				    width, height, 1 );
+
+    switch(mode)
+    {
+      case RGN_AND:
+	  XSetFunction( XT_display, regionGC, GXcopy );
+	  REGION_CopyIntersection( region, &src1Obj->region );
+	  XSetFunction( XT_display, regionGC, GXand );
+	  REGION_CopyIntersection( region, &src2Obj->region );
+	  return COMPLEXREGION;
+
+      case RGN_OR:
+      case RGN_XOR:
+	  XSetFunction( XT_display, regionGC, GXclear );
+	  XFillRectangle( XT_display, region->pixmap, regionGC,
+			  0, 0, width, height );
+	  XSetFunction( XT_display, regionGC, (mode == RGN_OR) ? GXor : GXxor);
+	  REGION_CopyIntersection( region, &src1Obj->region );
+	  REGION_CopyIntersection( region, &src2Obj->region );
+	  return COMPLEXREGION;
+	  
+      case RGN_DIFF:
+	  XSetFunction( XT_display, regionGC, GXclear );
+	  XFillRectangle( XT_display, region->pixmap, regionGC,
+			  0, 0, width, height );
+	  XSetFunction( XT_display, regionGC, GXcopy );
+	  REGION_CopyIntersection( region, &src1Obj->region );
+	  XSetFunction( XT_display, regionGC, GXandInverted );
+	  REGION_CopyIntersection( region, &src2Obj->region );
+	  return COMPLEXREGION;
+	  
+      case RGN_COPY:
+	  XSetFunction( XT_display, regionGC, GXcopy );
+	  XCopyArea( XT_display, src1Obj->region.pixmap, region->pixmap,
+		     regionGC, 0, 0, width, height, 0, 0 );
+	  return region->type;
+    }
+    return ERROR;
+}
diff --git a/objects/text.c b/objects/text.c
new file mode 100644
index 0000000..43b095a
--- /dev/null
+++ b/objects/text.c
@@ -0,0 +1,168 @@
+/*
+ * text functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Core.h>
+#include <X11/Shell.h>
+#include <X11/Xatom.h>
+
+#include "message.h"
+#include "callback.h"
+#include "win.h"
+#include "gdi.h"
+
+
+/***********************************************************************
+ *           DrawText    (USER.85)
+ */
+int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags )
+{
+    int x = rect->left, y = rect->top;
+    if (flags & DT_CENTER) x = (rect->left + rect->right) / 2;
+    if (flags & DT_VCENTER) y = (rect->top + rect->bottom) / 2;
+    if (count == -1) count = strlen(str);
+
+    if (!TextOut( hdc, x, y, str, count )) return 0;
+    return 1;
+}
+
+
+/***********************************************************************
+ *           TextOut    (GDI.33)
+ */
+BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count )
+{
+    int dir, ascent, descent, i;
+    XCharStruct info;
+    XFontStruct *font;
+
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (!DC_SetupGCForText( dc )) return TRUE;
+    font = dc->u.x.font.fstruct;
+
+    if (dc->w.textAlign & TA_UPDATECP)
+    {
+	x = dc->w.CursPosX;
+	y = dc->w.CursPosY;
+    }
+#ifdef DEBUG_TEXT
+    printf( "TextOut: %d,%d '%s'\n", x, y, str );
+#endif
+    x = XLPTODP( dc, x );
+    y = YLPTODP( dc, y );
+
+    XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
+    info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
+
+      /* Compute starting position */
+
+    switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
+    {
+      case TA_LEFT:
+ 	  if (dc->w.textAlign & TA_UPDATECP)
+	      dc->w.CursPosX = XDPTOLP( dc, x + info.width );
+	  break;
+      case TA_RIGHT:
+	  x -= info.width;
+	  if (dc->w.textAlign & TA_UPDATECP) dc->w.CursPosX = XDPTOLP( dc, x );
+	  break;
+      case TA_CENTER:
+	  x -= info.width / 2;
+	  break;
+    }
+    switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
+    {
+      case TA_TOP:
+	  y += font->ascent;
+	  break;
+      case TA_BOTTOM:
+	  y -= font->descent;
+	  break;
+      case TA_BASELINE:
+	  break;
+    }
+
+      /* Draw text */
+
+    if (!dc->w.charExtra && !dc->w.breakExtra)
+    {
+	if (dc->w.backgroundMode == TRANSPARENT)
+	    XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc, 
+			 x, y, str, count );
+	else
+	    XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
+			      x, y, str, count );
+    }
+    else
+    {
+	char * p = str;
+	int xchar = x;
+	for (i = 0; i < count; i++, p++)
+	{
+	    XCharStruct * charStr;
+	    unsigned char ch = *p;
+	    int extraWidth;
+	    
+	    if ((ch < font->min_char_or_byte2)||(ch > font->max_char_or_byte2))
+		ch = font->default_char;
+	    if (!font->per_char) charStr = &font->min_bounds;
+	    else charStr = font->per_char + ch - font->min_char_or_byte2;
+
+	    extraWidth = dc->w.charExtra;
+	    if (ch == dc->u.x.font.metrics.tmBreakChar)
+		extraWidth += dc->w.breakExtra;
+
+	    if (dc->w.backgroundMode == TRANSPARENT)
+		XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
+			     xchar, y, p, 1 );
+	    else
+	    {
+		XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
+				  xchar, y, p, 1 );
+		XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
+		XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
+			        xchar + charStr->width, y - font->ascent,
+			        extraWidth, font->ascent + font->descent );
+		XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
+	    }
+	    xchar += charStr->width + extraWidth;
+	}
+    }
+
+      /* Draw underline and strike-out if needed */
+
+    if (dc->u.x.font.metrics.tmUnderlined)
+    {
+	long linePos, lineWidth;       
+	if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
+	    linePos = font->descent-1;
+	if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
+	    lineWidth = 0;
+	else if (lineWidth == 1) lineWidth = 0;
+	XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth,
+			    LineSolid, CapRound, JoinBevel ); 
+	XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		   x, y + linePos, x + info.width, y + linePos );
+    }
+    if (dc->u.x.font.metrics.tmStruckOut)
+    {
+	long lineAscent, lineDescent;
+	if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
+	    lineAscent = font->ascent / 3;
+	if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
+	    lineDescent = -lineAscent;
+	XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent,
+			    LineSolid, CapRound, JoinBevel ); 
+	XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		   x, y - lineAscent, x + info.width, y - lineAscent );
+    }
+    
+    return TRUE;
+}
diff --git a/resource.c b/resource.c
deleted file mode 100644
index 531f9c0..0000000
--- a/resource.c
+++ /dev/null
@@ -1,410 +0,0 @@
-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))
-
-typedef struct resource_data_s
-{
-    int resource_type;
-    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 = GlobalAlloc(GMEM_MOVEABLE, 
-			  image_size + sizeof(*new_image) + n_colors);
-    new_image = GlobalLock(handle);
-#ifdef DEBUG_RESOURCE
-    printf("ConvertCoreBitmap: handle = %04x, new image = %08x\n", 
-	   handle, new_image);
-#endif
-    if (new_image == NULL)
-	return NULL;
-
-    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)
-{
-#ifdef DEBUG_RESOURCE
-    printf("ConvertInfoBitmap: \n");
-#endif
-
-    return NULL;
-}
-
-/**********************************************************************
- *					AddResource
- */
-int
-AddResource(int type, void *data)
-{
-    RSCD *r;
-    int i;
-    int j;
-    
-    /*
-     * Find free resource id.
-     */
-    r = Resources;
-    for (i = 0; i < ResourceArraySize; i++, r++)
-	if (r->resource_type == 0)
-	    break;
-    
-    /*
-     * Do we need to add more resource slots?
-     */
-    if (i == ResourceArraySize)
-    {
-	if (ResourceArraySize > 0)
-	    r = realloc(Resources, (ResourceArraySize + 32) * sizeof(RSCD));
-	else
-	    r = malloc(32 * sizeof(RSCD));
-	if (r == NULL)
-	    return 0;
-
-	for (j = ResourceArraySize; j < ResourceArraySize + 32; j++)
-	    r[j].resource_type = 0;
-	
-	ResourceArraySize += 32;
-	Resources = r;
-	r = &Resources[i];
-    }
-    
-    /*
-     * Add new resource to list.
-     */
-    r->resource_type = type;
-    r->resource_data = data;
-
-#ifdef DEBUG_RESOURCE
-    printf("AddResource: return handle %d\n", i + 1);
-#endif
-    /*
-     * Return a unique handle.
-     */
-    return i + 1;
-}
-
-/**********************************************************************
- *					FindResourceByNumber
- */
-int
-FindResourceByNumber(struct resource_nameinfo_s *result_p,
-		     int type_id, int resource_id)
-{
-    struct resource_typeinfo_s typeinfo;
-    struct resource_nameinfo_s nameinfo;
-    unsigned short size_shift;
-    int i;
-
-    /*
-     * Move to beginning of resource table.
-     */
-    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
-			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
-    
-    /*
-     * Read block size.
-     */
-    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
-	sizeof(size_shift))
-    {
-	return -1;
-    }
-    
-    /*
-     * Find resource.
-     */
-    typeinfo.type_id = 0xffff;
-    while (typeinfo.type_id != 0)
-    {
-	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
-	    sizeof(typeinfo))
-	{
-	    return -1;
-	}
-	if (typeinfo.type_id != 0)
-	{
-	    for (i = 0; i < typeinfo.count; i++)
-	    {
-		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
-		    sizeof(nameinfo))
-		{
-		    return -1;
-		}
-
-#if defined(DEBUG_RESOURCE) && defined(VERBOSE_DEBUG)
-		if (type_id == typeinfo.type_id)
-		{
-		    printf("FindResource: type id = %d, resource id = %x\n",
-			   type_id, nameinfo.id);
-		}
-#endif
-		if ((type_id == -1 || typeinfo.type_id == type_id) &&
-		    nameinfo.id == resource_id)
-		{
-		    memcpy(result_p, &nameinfo, sizeof(nameinfo));
-		    return size_shift;
-		}
-	    }
-	}
-    }
-    
-    return -1;
-}
-
-/**********************************************************************
- *					RSC_LoadString
- */
-int
-RSC_LoadString(int instance, int resource_id, char *buffer, int buflen)
-{
-    struct resource_nameinfo_s nameinfo;
-    unsigned short target_id;
-    unsigned char string_length;
-    int size_shift;
-    int string_num;
-    int i;
-
-#ifdef DEBUG_RESOURCE
-    printf("LoadString: instance = %04x, id = %d, "
-	   "buffer = %08x, length = %d\n",
-	   instance, resource_id, buffer, buflen);
-#endif
-    
-    /*
-     * Find string entry.
-     */
-    target_id = (resource_id >> 4) + 0x8001;
-    string_num = resource_id & 0x000f;
-
-    size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_STRING, target_id);
-    if (size_shift == -1)
-	return 0;
-    
-    lseek(CurrentNEFile, (int) nameinfo.offset << size_shift, SEEK_SET);
-
-    for (i = 0; i < string_num; i++)
-    {
-	read(CurrentNEFile, &string_length, 1);
-	lseek(CurrentNEFile, string_length, SEEK_CUR);
-    }
-			
-    read(CurrentNEFile, &string_length, 1);
-    i = MIN(string_length, buflen - 1);
-    read(CurrentNEFile, buffer, i);
-    buffer[i] = '\0';
-#ifdef DEBUG_RESOURCE
-    printf("            '%s'\n", buffer);
-#endif
-    return i;
-}
-
-/**********************************************************************
- *					RSC_LoadResource
- */
-int 
-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;
-    
-    /*
-     * Built-in resources
-     */
-    if (instance == 0)
-    {
-	return 0;
-    }
-    /*
-     * Get resource by ordinal
-     */
-    else if (((int) rsc_name & 0xffff0000) == 0)
-    {
-	size_shift = FindResourceByNumber(&nameinfo, type,
-					  (int) rsc_name | 0x8000);
-    }
-    /*
-     * Get resource by name
-     */
-    else
-    {
-	size_shift = -1;
-    }
-    if (size_shift == -1)
-	return 0;
-
-    /*
-     * Read resource.
-     */
-    lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
-
-    image_size = nameinfo.length << size_shift;
-    image = malloc(image_size);
-    if (image == NULL || read(CurrentNEFile, image, image_size) != image_size)
-    {
-	free(image);
-	return 0;
-    }
-
-    /*
-     * 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);
-
-#ifdef DEBUG_RESOURCE
-    printf("LoadResource: rsc_image = %08x\n", rsc_image);
-#endif
-    /*
-     * Add to resource list.
-     */
-    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/signal-diffs b/signal-diffs
new file mode 100644
index 0000000..9b49973
--- /dev/null
+++ b/signal-diffs
@@ -0,0 +1,90 @@
+diff -c -r linux.99pl12/linux//kernel/signal.c linux//kernel/signal.c
+*** linux.99pl12/linux//kernel/signal.c	Sat Aug 28 00:24:01 1993
+--- linux//kernel/signal.c	Fri Aug 27 22:45:41 1993
+***************
+*** 195,201 ****
+  	COPY(eip); COPY(eflags);
+  	COPY(ecx); COPY(edx);
+  	COPY(ebx);
+! 	COPY(esp); COPY(ebp);
+  	COPY(edi); COPY(esi);
+  	COPY(cs); COPY(ss);
+  	COPY(ds); COPY(es);
+--- 195,202 ----
+  	COPY(eip); COPY(eflags);
+  	COPY(ecx); COPY(edx);
+  	COPY(ebx);
+! 	regs->esp = context.esp_at_signal; /* Can be different with Wine */
+! 	COPY(ebp);
+  	COPY(edi); COPY(esi);
+  	COPY(cs); COPY(ss);
+  	COPY(ds); COPY(es);
+***************
+*** 353,360 ****
+  	frame = (unsigned long *) regs->esp;
+  	signr = 1;
+  	sa = current->sigaction;
+! 	if (regs->ss != USER_DS)
+! 		printk("Warning: signal handler with nonstandard stack segment\n");
+  	for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
+  		if (mask > handler_signal)
+  			break;
+--- 354,360 ----
+  	frame = (unsigned long *) regs->esp;
+  	signr = 1;
+  	sa = current->sigaction;
+! 
+  	for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
+  		if (mask > handler_signal)
+  			break;
+***************
+*** 365,370 ****
+--- 365,381 ----
+  			sa->sa_handler = NULL;
+  /* force a supervisor-mode page-in of the signal handler to reduce races */
+  		__asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler));
++ 
++ 		/* If ss != USER_DS, we cannot rely upon the ss:esp as a */
++ 		/* stack. We will instead use USER_DS:sa->sa_restorer */
++ 		if (regs->ss != USER_DS) {
++ 			frame = (unsigned long *) sa->sa_restorer;
++ 			if(frame == NULL) {
++ 				printk("No signal handler stack available\n");
++ 				do_exit(signr);
++ 			};
++ 		};
++ 
+  		setup_frame(&frame,eip,regs,signr,sa_handler,oldmask);
+  		eip = sa_handler; regs->cs = USER_CS;
+  		current->blocked |= sa->sa_mask;
+***************
+*** 371,376 ****
+--- 382,392 ----
+  		oldmask |= sa->sa_mask;
+  	}
+  	regs->esp = (unsigned long) frame;
++ 	/* When running the Wine program, the segment registers may be holding
++ 	   unusual values */
++ 	regs->ss = USER_DS;  /* Make sure that this is correct */
++ 	regs->ds = USER_DS;  /* And the same here */
++ 	regs->es = USER_DS;  /* And here again */
+  	regs->eip = eip;			/* "return" to the first handler */
+  	return 1;
+  }
+diff -c -r linux.99pl12/linux//kernel/traps.c linux//kernel/traps.c
+*** linux.99pl12/linux//kernel/traps.c	Thu Aug 19 00:34:24 1993
+--- linux//kernel/traps.c	Fri Aug 27 09:11:01 1993
+***************
+*** 66,71 ****
+--- 66,76 ----
+  
+  	if ((regs->eflags & VM_MASK) || ((0xffff & regs->cs) == USER_CS))
+  		return;
++ 
++ 	/* See if we are using the LDT.  If so, pass along the signal. */
++ 	if((7 & regs->cs) == 7 && current->ldt && (regs->cs >> 3) < 512)
++ 		return;
++ 
+  	printk("%s: %04x\n", str, err & 0xffff);
+  	printk("EIP:    %04x:%p\nEFLAGS: %p\n", 0xffff & regs->cs,regs->eip,regs->eflags);
+  	printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
diff --git a/test/hw.exe b/test/hw.exe
new file mode 100755
index 0000000..0567dc3
--- /dev/null
+++ b/test/hw.exe
Binary files differ
diff --git a/test/menutest.exe b/test/menutest.exe
new file mode 100755
index 0000000..ad4f791
--- /dev/null
+++ b/test/menutest.exe
Binary files differ
diff --git a/test/winetest2.exe b/test/winetest2.exe
new file mode 100755
index 0000000..57d7edc
--- /dev/null
+++ b/test/winetest2.exe
Binary files differ
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644
index 0000000..5dea1b0
--- /dev/null
+++ b/tools/Makefile
@@ -0,0 +1,17 @@
+build: build.c
+	cc -O2 -o build build.c
+
+clean:
+	rm -f *.o *~
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+dummy:
+
+#
+# Dependency lists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
\ No newline at end of file
diff --git a/build-spec.txt b/tools/build-spec.txt
similarity index 100%
rename from build-spec.txt
rename to tools/build-spec.txt
diff --git a/build.c b/tools/build.c
similarity index 97%
rename from build.c
rename to tools/build.c
index 5c0b0f4..3ca4410 100644
--- a/build.c
+++ b/tools/build.c
@@ -610,6 +610,8 @@
 	if (!odp->valid)
 	{
 	    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+	    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+	    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
 	    fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 	    fprintf(fp, "\tpushw\t$0\n");
 	    fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
@@ -652,6 +654,8 @@
 
 	      case FUNCTYPE_REG:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
 		fprintf(fp, "\tpushw\t%%ax\n");
 		fprintf(fp, "\tpushw\t%%cx\n");
 		fprintf(fp, "\tpushw\t%%dx\n");
@@ -673,6 +677,8 @@
 
 	      case FUNCTYPE_PASCAL:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 		fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
@@ -681,6 +687,8 @@
 	      case FUNCTYPE_C:
 	      default:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 		fprintf(fp, "\tpushw\t$0\n");
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
diff --git a/user.c b/user.c
deleted file mode 100644
index 280ba3f..0000000
--- a/user.c
+++ /dev/null
@@ -1,26 +0,0 @@
-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>
-#include <stdlib.h>
-#include "prototypes.h"
-
-#define DEFAULT_MSG_QUEUE_SIZE  8
-
-
-/**********************************************************************
- *					USER_InitApp
- *
- * Load necessary resources?
- */
-int
-USER_InitApp(int hInstance)
-{
-      /* Initialize built-in window classes */
-    WIDGETS_Init();
-    
-      /* Create task message queue */
-    if (!SetMessageQueue( DEFAULT_MSG_QUEUE_SIZE )) return 0;
-        
-    return 1;
-}
diff --git a/user.spec b/user.spec
deleted file mode 100644
index bf14b80..0000000
--- a/user.spec
+++ /dev/null
@@ -1,43 +0,0 @@
-# $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)
-53  pascal DestroyWindow(word) DestroyWindow(1)
-57  pascal RegisterClass(ptr) RegisterClass(1)
-66  pascal GetDC(word) GetDC(1)
-85  pascal DrawText(word ptr s_word ptr word) DrawText(1 2 3 4 5)
-104 pascal MessageBeep(word) MessageBeep(1)
-107 pascal DefWindowProc(word word word long) DefWindowProc(1 2 3 4)
-108 pascal GetMessage(ptr word word word) GetMessage(1 2 3 4)
-109 pascal PeekMessage(ptr word word word word) PeekMessage(1 2 3 4 5)
-110 pascal PostMessage(word word word word) PostMessage(1 2 3 4)
-111 pascal SendMessage(word word word word) SendMessage(1 2 3 4)
-113 pascal TranslateMessage(ptr) TranslateMessage(1)
-114 pascal DispatchMessage(ptr) DispatchMessage(1)
-119 pascal GetMessagePos() GetMessagePos()
-120 pascal GetMessageTime() GetMessageTime()
-124 pascal UpdateWindow(word) UpdateWindow(1)
-151 pascal CreateMenu() CreateMenu()
-157 pascal GetMenu(word) GetMenu(1)
-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)
-266 pascal SetMessageQueue(word) SetMessageQueue(1)
-288 pascal GetMessageExtraInfo() GetMessageExtraInfo()
-334 pascal GetQueueStatus(word) GetQueueStatus(1)
-335 pascal GetInputState() GetInputState()
-403 pascal UnregisterClass(ptr word) UnregisterClass(1 2)
-411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4)
diff --git a/win.c b/win.c
deleted file mode 100644
index b0373ca..0000000
--- a/win.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Window related functions
- *
- * Copyright 1993 Alexandre Julliard
- */
-
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Core.h>
-#include <X11/Shell.h>
-
-#include "class.h"
-#include "win.h"
-
-extern Widget XT_topLevelWidget;
-
-
-static HWND firstWindow = 0;
-
-
-/***********************************************************************
- *           WIN_FindWndPtr
- *
- * Return a pointer to the WND structure corresponding to a HWND.
- * The caller must GlobalUnlock the pointer.
- */
-WND * WIN_FindWndPtr( HWND hwnd )
-{
-    WND * ptr;
-    
-    if (!hwnd) return NULL;
-    ptr = (WND *) GlobalLock( hwnd );
-    if (ptr->dwMagic != WND_MAGIC)
-    {
-	GlobalUnlock( hwnd );
-	return NULL;
-    }
-    return ptr;
-}
-
-
-/***********************************************************************
- *           CreateWindow   (USER.41)
- */
-HWND CreateWindow( LPSTR className, LPSTR windowName,
-		   DWORD style, int x, int y, int width, int height,
-		   HWND parent, HMENU menu, HANDLE instance, LPSTR data ) 
-{
-    HANDLE class, hwnd;
-    CLASS *classPtr;
-    WND *wndPtr, *parentPtr = NULL;
-    CREATESTRUCT createStruct;
-    Widget parentWidget = 0;
-
-    printf( "CreateWindow: %s\n", windowName );
-
-    if (x == CW_USEDEFAULT) x = 0;
-    if (y == CW_USEDEFAULT) y = 0;
-    if (width == CW_USEDEFAULT) width = 600;
-    if (height == CW_USEDEFAULT) height = 400;
-
-      /* Find the parent and class */
-
-    if (parent) 
-    {
-	  /* Check if parent is valid */
-	parentPtr = WIN_FindWndPtr( parent );
-	if (!parentPtr) return 0;
-    }
-    else if (style & WS_CHILD) return 0;  /* WS_CHILD needs a parent */
-
-    if (!(class = CLASS_FindClassByName( className, &classPtr )))
-    {
-	GlobalUnlock( parent );
-	return 0;
-    }
-    
-      /* Create the window structure */
-
-    hwnd = GlobalAlloc( GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra );
-    if (!hwnd)
-    {
-	GlobalUnlock( parent );
-	GlobalUnlock( class );
-	return 0;
-    }
-
-      /* Fill the structure */
-
-    wndPtr = (WND *) GlobalLock( hwnd );
-    wndPtr->hwndNext   = 0;
-    wndPtr->hwndChild  = 0;
-    wndPtr->dwMagic    = WND_MAGIC;
-    wndPtr->hwndParent = parent;
-    wndPtr->hwndOwner  = parent;  /* What else? */
-    wndPtr->hClass     = class;
-    wndPtr->hInstance  = instance;
-    wndPtr->rectClient.left   = x;
-    wndPtr->rectClient.top    = y;
-    wndPtr->rectClient.right  = x + width;
-    wndPtr->rectClient.bottom = y + height;
-    wndPtr->rectWindow        = wndPtr->rectClient;
-    wndPtr->hrgnUpdate        = 0;
-    wndPtr->hwndLastActive    = 0;
-    wndPtr->lpfnWndProc       = classPtr->wc.lpfnWndProc;
-    wndPtr->dwStyle           = style;
-    wndPtr->hDCE              = 0;
-    wndPtr->hmenuSystem       = 0;
-    wndPtr->wIDmenu           = menu;
-    if (classPtr->wc.cbWndExtra)
-	memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
-    classPtr->cWindows++;
-
-      /* Insert the window in the linked list */
-
-    if (parent)
-    {
-	wndPtr->hwndNext = parentPtr->hwndChild;
-	parentPtr->hwndChild = hwnd;
-    }
-    else  /* Top-level window */
-    {
-	wndPtr->hwndNext = firstWindow;
-	firstWindow = hwnd;
-    }
-    
-      /* Fill the CREATESTRUCT */
-
-    createStruct.lpCreateParams = data;
-    createStruct.hInstance      = instance;
-    createStruct.hMenu          = menu;
-    createStruct.hwndParent     = parent;
-    createStruct.cx             = width;
-    createStruct.cy             = height;
-    createStruct.x              = x;
-    createStruct.y              = y;
-    createStruct.style          = style;
-    createStruct.lpszName       = windowName;
-    createStruct.lpszClass      = className;
-    createStruct.dwExStyle      = 0;
-
-      /* Create the widgets */
-
-    if (style & WS_CHILD)
-    {
-	wndPtr->shellWidget = 0;
-	wndPtr->winWidget = XtVaCreateManagedWidget(className,
-						    coreWidgetClass,
-						    parentPtr->winWidget,
-						    XtNx, x,
-						    XtNy, y,
-						    XtNwidth, width,
-						    XtNheight, height,
-						    NULL );
-    }
-    else
-    {
-	wndPtr->shellWidget = XtVaAppCreateShell(className, 
-						 windowName,
-						 topLevelShellWidgetClass,
-						 XtDisplay(XT_topLevelWidget),
-						 XtNx, x,
-						 XtNy, y,
-						 NULL );
-    	wndPtr->winWidget = XtVaCreateManagedWidget(className,
-						    compositeWidgetClass,
-						    wndPtr->shellWidget,
-						    XtNwidth, width,
-						    XtNheight, height,
-						    NULL );
-    }
-
-      /* Send the WM_CREATE message */
-
-    if (CallWindowProc( wndPtr->lpfnWndProc, hwnd, 
-		        WM_CREATE, 0, (LONG) &createStruct ) == -1)
-    {
-	  /* Abort window creation */
-	if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
-	else XtDestroyWidget( wndPtr->winWidget );
-	GlobalUnlock( parent );
-	GlobalUnlock( class );
-	GlobalUnlock( hwnd );
-	GlobalFree( hwnd );
-	return 0;
-    }
-    
-    EVENT_AddHandlers( wndPtr->winWidget, hwnd );
-    
-    GlobalUnlock( parent );
-    GlobalUnlock( class );
-    GlobalUnlock( hwnd );
-    return hwnd;
-}
-
-/***********************************************************************
- *           DestroyWindow   (USER.53)
- */
-BOOL DestroyWindow( HWND hwnd )
-{
-    WND *wndPtr, *parentPtr;
-    CLASS * classPtr;
-    
-    wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return FALSE;
-
-    if (wndPtr->hwndParent)
-    {
-	parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
-	printf( "INTERNAL ERROR: DestroyWindow: Invalid window parent\n" );
-	return FALSE;
-    }
-    
-    classPtr = CLASS_FindClassPtr( wndPtr->hClass );
-    if (!classPtr)
-    {
-	printf( "INTERNAL ERROR: DestroyWindow: Invalid window class\n" );
-	return FALSE;
-    }
-    
-    SendMessage( hwnd, WM_DESTROY, 0, 0 );
-    
-      /* Destroy all children */
-
-    /* ........... */
-
-      /* Remove the window from the linked list */
-    
-    /* ........... */
-
-      /* Destroy the window */
-
-    if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
-    else XtDestroyWidget( wndPtr->winWidget );
-    classPtr->cWindows--;
-    GlobalUnlock( wndPtr->hClass );
-    if (wndPtr->hwndParent) GlobalUnlock( wndPtr->hwndParent );
-    GlobalUnlock( hwnd );
-    GlobalFree( hwnd );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GetClientRect   (USER.33)
- */
-void GetClientRect( HWND hwnd, LPRECT rect ) 
-{
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    rect->left = rect->top = rect->right = rect->bottom = 0;
-    if (wndPtr) 
-    {
-	XtVaGetValues(wndPtr->winWidget,
-		      XtNwidth, &rect->right,
-		      XtNheight, &rect->bottom,
-		      NULL );
-	GlobalUnlock( hwnd );
-    }
-}
-
-
-/***********************************************************************
- *           ShowWindow   (USER.42)
- */
-BOOL ShowWindow( HWND hwnd, int cmd ) 
-{    
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (wndPtr) 
-    {
-	if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
-	GlobalUnlock( hwnd );
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           UpdateWindow   (USER.124)
- */
-void UpdateWindow( HWND hwnd )
-{
-    SendMessage( hwnd, WM_PAINT, 0, 0 );
-}
-
-
diff --git a/windows/Makefile b/windows/Makefile
new file mode 100644
index 0000000..0e6fe69
--- /dev/null
+++ b/windows/Makefile
@@ -0,0 +1,19 @@
+CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
+
+OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \
+    	clipping.o mapping.o painting.o keyboard.o
+
+default: windows.o
+
+windows.o: $(OBJS)
+	$(LD) -r -o windows.o $(OBJS)
+
+clean:
+	rm -f *.o *~ *.s dll_* *.a
+
+depend:
+	$(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/windows/class.c b/windows/class.c
new file mode 100644
index 0000000..2cb42ec
--- /dev/null
+++ b/windows/class.c
@@ -0,0 +1,187 @@
+/*
+ * Window classes functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "class.h"
+#include "user.h"
+#include "win.h"
+
+
+static HCLASS firstClass = 0;
+
+
+/***********************************************************************
+ *           CLASS_FindClassByName
+ *
+ * Return a handle and a pointer to the class.
+ */
+HCLASS CLASS_FindClassByName( char * name, CLASS **ptr )
+{
+    HCLASS class = firstClass;
+    while(class)
+    {
+	*ptr = (CLASS *) USER_HEAP_ADDR(class);
+	if (!strcmp( (*ptr)->wc.lpszClassName, name )) return class;
+	class = (*ptr)->hNext;
+    }
+    return 0;
+}
+
+/***********************************************************************
+ *           CLASS_FindClassPtr
+ *
+ * Return a pointer to the CLASS structure corresponding to a HCLASS.
+ */
+CLASS * CLASS_FindClassPtr( HCLASS hclass )
+{
+    CLASS * ptr;
+    
+    if (!hclass) return NULL;
+    ptr = (CLASS *) USER_HEAP_ADDR( hclass );
+    if (ptr->wMagic != CLASS_MAGIC) return NULL;
+    return ptr;
+}
+
+
+/***********************************************************************
+ *           RegisterClass    (USER.57)
+ */
+ATOM RegisterClass( LPWNDCLASS class )
+{
+    CLASS * newClass;
+    HCLASS handle;
+    
+#ifdef DEBUG_CLASS
+    printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n", 
+	    class->lpfnWndProc, class->hInstance, class->lpszClassName );
+#endif
+
+    handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra );
+    if (!handle) return 0;
+    newClass = (CLASS *) USER_HEAP_ADDR( handle );
+    newClass->hNext      = firstClass;
+    newClass->wMagic     = CLASS_MAGIC;
+    newClass->atomName   = handle;  /* Should be an atom */
+    newClass->hDCE       = 0;  /* Should allocate a DCE if needed */
+    newClass->cWindows   = 0;  
+    newClass->wc         = *class;
+        
+      /* Class name should also be set to zero. For now we need the
+       * name because we don't have atoms.
+       */
+    newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1);
+    strcpy( newClass->wc.lpszClassName, class->lpszClassName );
+    
+    if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
+    
+    firstClass = handle;
+    return handle;  /* Should be an atom */
+}
+
+
+/***********************************************************************
+ *           UnregisterClass    (USER.403)
+ */
+BOOL UnregisterClass( LPSTR className, HANDLE instance )
+{
+    HANDLE class, next, prevClass;
+    CLASS * classPtr, * prevClassPtr;
+    
+      /* Check if we can remove this class */
+    class = CLASS_FindClassByName( className, &classPtr );
+    if (!class) return FALSE;
+    if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
+	return FALSE;
+    
+      /* Remove the class from the linked list */
+    if (firstClass == class) firstClass = classPtr->hNext;
+    else
+    {
+	for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
+	{
+	    prevClassPtr = (CLASS *) USER_HEAP_ADDR(prevClass);
+	    if (prevClassPtr->hNext == class) break;
+	}
+	if (!prevClass)
+	{
+	    printf( "ERROR: Class list corrupted\n" );
+	    return FALSE;
+	}
+	prevClassPtr->hNext = classPtr->hNext;
+    }
+    
+    USER_HEAP_FREE( class );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetClassWord    (USER.129)
+ */
+WORD GetClassWord( HWND hwnd, short offset )
+{
+    return (WORD)GetClassLong( hwnd, offset );
+}
+
+
+/***********************************************************************
+ *           SetClassWord    (USER.130)
+ */
+WORD SetClassWord( HWND hwnd, short offset, WORD newval )
+{
+    CLASS * classPtr;
+    WND * wndPtr;
+    WORD retval = 0;
+    
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+    if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
+    {
+	WORD * ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
+	retval = *ptr;
+	*ptr = newval;
+    }
+    GlobalUnlock( hwnd );
+    return retval;
+}
+
+
+/***********************************************************************
+ *           GetClassLong    (USER.131)
+ */
+LONG GetClassLong( HWND hwnd, short offset )
+{
+    CLASS * classPtr;
+    WND * wndPtr;
+    LONG retval = 0;
+    
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+    if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
+	retval = *(LONG *)(((char *)classPtr->wExtra) + offset);
+    GlobalUnlock( hwnd );
+    return retval;
+}
+
+
+/***********************************************************************
+ *           SetClassLong    (USER.132)
+ */
+LONG SetClassLong( HWND hwnd, short offset, LONG newval )
+{
+    CLASS * classPtr;
+    WND * wndPtr;
+    LONG retval = 0;
+    
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+    if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
+    {
+	LONG * ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
+	retval = *ptr;
+	*ptr = newval;
+    }
+    GlobalUnlock( hwnd );
+    return retval;
+}
diff --git a/windows/clipping.c b/windows/clipping.c
new file mode 100644
index 0000000..80b19d2
--- /dev/null
+++ b/windows/clipping.c
@@ -0,0 +1,156 @@
+/*
+ * Window clipping functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdio.h>
+
+#include "windows.h"
+#include "win.h"
+
+
+/***********************************************************************
+ *           InvalidateRgn   (USER.126)
+ */
+void InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
+{
+    HRGN newRgn;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return;
+    
+    if (!hrgn)
+    {
+	newRgn = CreateRectRgn(0, 0, 
+		   wndPtr->rectClient.right-wndPtr->rectClient.left,
+		   wndPtr->rectClient.bottom-wndPtr->rectClient.top );
+    }
+    else 
+    {
+	if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return;
+	if (!wndPtr->hrgnUpdate) CombineRgn( newRgn, hrgn, 0, RGN_COPY );
+	else CombineRgn( newRgn, wndPtr->hrgnUpdate, hrgn, RGN_OR );
+    }
+    if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
+    wndPtr->hrgnUpdate = newRgn;
+    if (erase) wndPtr->flags |= WIN_ERASE_UPDATERGN;
+}
+
+
+/***********************************************************************
+ *           InvalidateRect   (USER.125)
+ */
+void InvalidateRect( HWND hwnd, LPRECT rect, BOOL erase )
+{
+    HRGN hrgn = 0;
+
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return;
+
+#ifdef DEBUG_WIN
+    if (rect) printf( "InvalidateRect: %d %d,%d-%d,%d\n", hwnd,
+		     rect->left, rect->top, rect->right, rect->bottom );
+    else printf( "InvalidateRect: %d NULL\n", hwnd );
+#endif
+    if (rect) hrgn = CreateRectRgnIndirect( rect );
+    InvalidateRgn( hwnd, hrgn, erase );
+    if (hrgn) DeleteObject( hrgn );
+}
+
+
+/***********************************************************************
+ *           ValidateRgn   (USER.128)
+ */
+void ValidateRgn( HWND hwnd, HRGN hrgn )
+{
+    HRGN newRgn;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return;
+
+    if (!wndPtr->hrgnUpdate) return;
+    if (!hrgn) newRgn = 0;
+    else
+    {
+	if (!(newRgn = CreateRectRgn( 0, 0, 0, 0 ))) return;
+	if (CombineRgn( newRgn, wndPtr->hrgnUpdate, hrgn, RGN_DIFF ) == NULLREGION)
+	{
+	    DeleteObject( newRgn );
+	    newRgn = 0;
+	}
+    }
+    DeleteObject( wndPtr->hrgnUpdate );
+    wndPtr->hrgnUpdate = newRgn;
+    if (!wndPtr->hrgnUpdate) wndPtr->flags &= ~WIN_ERASE_UPDATERGN;
+}
+
+
+/***********************************************************************
+ *           ValidateRect   (USER.127)
+ */
+void ValidateRect( HWND hwnd, LPRECT rect )
+{
+    HRGN hrgn = 0;
+
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return;
+
+    if (rect) hrgn = CreateRectRgnIndirect( rect );
+    ValidateRgn( hwnd, hrgn );
+    if (hrgn) DeleteObject( hrgn );
+}
+
+
+/***********************************************************************
+ *           GetUpdateRect   (USER.190)
+ */
+BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
+{
+    BOOL retval;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return FALSE;
+
+    retval = (wndPtr->hrgnUpdate != 0);
+
+    if (rect)
+    {
+        if (wndPtr->hrgnUpdate) GetRgnBox( wndPtr->hrgnUpdate, rect );
+	else SetRectEmpty( rect );
+	if (erase && wndPtr->hrgnUpdate)
+	{
+	    HDC hdc = GetDC( hwnd );
+	    if (hdc)
+	    {
+		SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
+		ReleaseDC( hwnd, hdc );
+	    }
+	}
+    }
+    GlobalUnlock( hwnd );
+    return retval;
+}
+
+
+/***********************************************************************
+ *           GetUpdateRgn   (USER.237)
+ */
+int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
+{
+    int retval;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return ERROR;
+
+    if (erase && wndPtr->hrgnUpdate)
+    {
+	HDC hdc = GetDC( hwnd );
+	if (hdc)
+	{
+	    SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
+	    ReleaseDC( hwnd, hdc );
+	}
+    }
+    retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
+    GlobalUnlock( hwnd );
+    return retval;    
+}
diff --git a/windows/dc.c b/windows/dc.c
new file mode 100644
index 0000000..926b7ca
--- /dev/null
+++ b/windows/dc.c
@@ -0,0 +1,488 @@
+/*
+ * GDI Device Context functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdlib.h>
+#include <X11/Intrinsic.h>
+
+#include "gdi.h"
+
+extern HBITMAP BITMAP_hbitmapMemDC;
+
+static DeviceCaps * displayDevCaps = NULL;
+
+extern const WIN_DC_INFO DCVAL_defaultValues;
+
+
+  /* ROP code to GC function conversion */
+const int DC_XROPfunction[16] =
+{
+    GXclear,        /* R2_BLACK */
+    GXnor,          /* R2_NOTMERGEPEN */
+    GXandInverted,  /* R2_MASKNOTPEN */
+    GXcopyInverted, /* R2_NOTCOPYPEN */
+    GXandReverse,   /* R2_MASKPENNOT */
+    GXinvert,       /* R2_NOT */
+    GXxor,          /* R2_XORPEN */
+    GXnand,         /* R2_NOTMASKPEN */
+    GXand,          /* R2_MASKPEN */
+    GXequiv,        /* R2_NOTXORPEN */
+    GXnoop,         /* R2_NOP */
+    GXorInverted,   /* R2_MERGENOTPEN */
+    GXcopy,         /* R2_COPYPEN */
+    GXorReverse,    /* R2_MERGEPENNOT */
+    GXor,           /* R2_MERGEPEN */
+    GXset           /* R2_WHITE */
+};
+
+
+/***********************************************************************
+ *           DC_FillDevCaps
+ *
+ * Fill the device caps structure.
+ */
+void DC_FillDevCaps( DeviceCaps * caps )
+{
+    caps->version       = 0x300; 
+    caps->technology    = DT_RASDISPLAY;
+    caps->horzSize      = WidthMMOfScreen( XT_screen );
+    caps->vertSize      = HeightMMOfScreen( XT_screen );
+    caps->horzRes       = WidthOfScreen( XT_screen );
+    caps->vertRes       = HeightOfScreen( XT_screen );
+    caps->bitsPixel     = DefaultDepthOfScreen( XT_screen );
+    caps->planes        = 1;
+    caps->numBrushes    = 0;
+    caps->numPens       = 0;
+    caps->numMarkers    = 0;
+    caps->numFonts      = 0;
+    caps->numColors     = 1 << caps->bitsPixel;
+    caps->pdeviceSize   = 0;
+    caps->curveCaps     = CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
+	                  CC_WIDE | CC_STYLED | CC_WIDESTYLED | 
+			  CC_INTERIORS | CC_ROUNDRECT;
+    caps->lineCaps      = LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+	                  LC_STYLED | LC_WIDESTYLED | LC_INTERIORS;
+    caps->polygonalCaps = PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
+	                  PC_SCANLINE | PC_WIDE | PC_STYLED | 
+			  PC_WIDESTYLED | PC_INTERIORS;
+    caps->textCaps      = TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
+	                  TC_IA_ABLE | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
+    caps->clipCaps      = CP_REGION;
+    caps->rasterCaps    = RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
+	                  RC_DI_BITMAP | RC_PALETTE | RC_DIBTODEV | RC_BIGFONT|
+			  RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
+    caps->aspectX       = 36;  /* ?? */
+    caps->aspectY       = 36;  /* ?? */
+    caps->aspectXY      = 51;
+    caps->logPixelsX    = (int)(caps->horzRes * 25.4 / caps->horzSize);
+    caps->logPixelsY    = (int)(caps->vertRes * 25.4 / caps->vertSize);
+    caps->sizePalette   = DefaultVisual( XT_display, DefaultScreen(XT_display) )->map_entries;
+    caps->numReserved   = 0;
+    caps->colorRes      = 0;
+}
+
+
+/***********************************************************************
+ *           DC_SetDeviceInfo
+ *
+ * Set device-specific info from device-independent info.
+ */
+void DC_SetDeviceInfo( HDC hdc, DC * dc )
+{
+    SetTextColor( hdc, dc->w.textColor );
+    SetBkColor( hdc, dc->w.backgroundColor );
+    SetROP2( hdc, dc->w.ROPmode );
+    SelectObject( hdc, dc->w.hPen );
+    SelectObject( hdc, dc->w.hBrush );
+    SelectObject( hdc, dc->w.hFont );
+    
+    if (dc->w.hGCClipRgn)
+    {
+	RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC);
+	XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap );
+	XSetClipOrigin( XT_display, dc->u.x.gc,
+		        obj->region.box.left, obj->region.box.top );
+    }
+    else
+    {
+	XSetClipMask( XT_display, dc->u.x.gc, None );
+	XSetClipOrigin( XT_display, dc->u.x.gc, 0, 0 );
+    }
+}
+
+
+/***********************************************************************
+ *           DC_SetupDCForBrush
+ *
+ * Setup dc->u.x.gc for drawing operations using current brush.
+ * Return 0 if brush is BS_NULL, 1 otherwise.
+ */
+int DC_SetupGCForBrush( DC * dc )
+{
+    if (dc->u.x.brush.style == BS_NULL) return 0;
+    if (dc->u.x.brush.pixel == -1)
+    {
+	/* Special case used for monochrome pattern brushes.
+	 * We need to swap foreground and background because
+	 * Windows does it the wrong way...
+	 */
+	XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel );
+	XSetBackground( XT_display, dc->u.x.gc, dc->w.textPixel );
+    }
+    else
+    {
+	XSetForeground( XT_display, dc->u.x.gc, dc->u.x.brush.pixel );
+	XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel );
+    }
+
+    if (dc->u.x.brush.fillStyle != FillStippled)
+	XSetFillStyle( XT_display, dc->u.x.gc, dc->u.x.brush.fillStyle );
+    else
+	XSetFillStyle( XT_display, dc->u.x.gc,
+		       (dc->w.backgroundMode == OPAQUE) ? 
+		          FillOpaqueStippled : FillStippled );
+    XSetTSOrigin( XT_display, dc->u.x.gc, dc->w.brushOrgX, dc->w.brushOrgY );
+    XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           DC_SetupDCForPen
+ *
+ * Setup dc->u.x.gc for drawing operations using current pen.
+ * Return 0 if pen is PS_NULL, 1 otherwise.
+ */
+int DC_SetupGCForPen( DC * dc )
+{
+    if (dc->u.x.pen.style == PS_NULL) return 0;
+    XSetForeground( XT_display, dc->u.x.gc, dc->u.x.pen.pixel );
+    XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel );
+    XSetFillStyle( XT_display, dc->u.x.gc, FillSolid );
+    if ((dc->u.x.pen.style == PS_SOLID) ||
+	(dc->u.x.pen.style == PS_INSIDEFRAME))
+    {
+	XSetLineAttributes( XT_display, dc->u.x.gc, dc->u.x.pen.width, 
+			    LineSolid, CapRound, JoinBevel );    
+    }
+    else
+    {
+    	XSetLineAttributes( XT_display, dc->u.x.gc, dc->u.x.pen.width, 
+	     (dc->w.backgroundMode == OPAQUE) ? LineDoubleDash : LineOnOffDash,
+	     CapRound, JoinBevel );
+    }
+    XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
+    return 1;    
+}
+
+
+/***********************************************************************
+ *           DC_SetupDCForText
+ *
+ * Setup dc->u.x.gc for text drawing operations.
+ * Return 0 if the font is null, 1 otherwise.
+ */
+int DC_SetupGCForText( DC * dc )
+{
+    XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
+    XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel );
+    XSetFillStyle( XT_display, dc->u.x.gc, FillSolid );
+    XSetFunction( XT_display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
+    if (!dc->u.x.font.fstruct) return 0;
+    XSetFont( XT_display, dc->u.x.gc, dc->u.x.font.fstruct->fid );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           GetDCState    (GDI.179)
+ */
+HDC GetDCState( HDC hdc )
+{
+    DC * newdc, * dc;
+    HANDLE handle;
+    
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return 0;
+    newdc = (DC *) GDI_HEAP_ADDR( handle );
+
+#ifdef DEBUG_DC
+    printf( "GetDCState(%d): returning %d\n", hdc, handle );
+#endif
+
+    memcpy( &newdc->w, &dc->w, sizeof(dc->w) );
+    newdc->saveLevel = 0;
+    newdc->w.flags |= DC_SAVED;
+
+    if (dc->w.hClipRgn)
+    {
+	newdc->w.hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
+	CombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
+    }
+    if (dc->w.hVisRgn)
+    {
+	newdc->w.hVisRgn = CreateRectRgn( 0, 0, 0, 0 );
+	CombineRgn( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY );
+	
+    }
+    newdc->w.hGCClipRgn = 0;
+    return handle;
+}
+
+
+/***********************************************************************
+ *           SetDCState    (GDI.180)
+ */
+void SetDCState( HDC hdc, HDC hdcs )
+{
+    DC * dc, * dcs;
+    
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
+    if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return;
+    if (!dcs->w.flags & DC_SAVED) return;
+#ifdef DEBUG_DC
+    printf( "SetDCState: %d %d\n", hdc, hdcs );
+#endif
+    if (dc->w.hClipRgn)	DeleteObject( dc->w.hClipRgn );
+    if (dc->w.hVisRgn) DeleteObject( dc->w.hVisRgn );
+    if (dc->w.hGCClipRgn) DeleteObject( dc->w.hGCClipRgn );
+    memcpy( &dc->w, &dcs->w, sizeof(dc->w) );
+    dc->w.hClipRgn = dc->w.hVisRgn = dc->w.hGCClipRgn = 0;
+    dc->w.flags &= ~DC_SAVED;
+    DC_SetDeviceInfo( hdc, dc );
+    SelectClipRgn( hdc, dcs->w.hClipRgn );
+    SelectVisRgn( hdc, dcs->w.hGCClipRgn );
+}
+
+
+/***********************************************************************
+ *           SaveDC    (GDI.30)
+ */
+int SaveDC( HDC hdc )
+{
+    HDC hdcs;
+    DC * dc, * dcs;
+
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    if (!(hdcs = GetDCState( hdc ))) return 0;
+    dcs = (DC *) GDI_HEAP_ADDR( hdcs );
+    dcs->header.hNext = dc->header.hNext;
+    dc->header.hNext = hdcs;
+#ifdef DEBUG_DC
+    printf( "SaveDC(%d): returning %d\n", hdc, dc->saveLevel+1 );
+#endif    
+    return ++dc->saveLevel;
+}
+
+
+/***********************************************************************
+ *           RestoreDC    (GDI.39)
+ */
+BOOL RestoreDC( HDC hdc, short level )
+{
+    DC * dc, * dcs;
+
+#ifdef DEBUG_DC
+    printf( "RestoreDC: %d %d\n", hdc, level );
+#endif    
+    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
+    if (level == -1) level = dc->saveLevel;
+    if ((level < 1) || (level > dc->saveLevel))	return FALSE;
+    
+    while (dc->saveLevel >= level)
+    {
+	HDC hdcs = dc->header.hNext;
+	if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return FALSE;
+	dc->header.hNext = dcs->header.hNext;
+	if (--dc->saveLevel < level) SetDCState( hdc, hdcs );
+	DeleteDC( hdcs );
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           CreateDC    (GDI.53)
+ */
+HDC CreateDC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData )
+{
+    DC * dc;
+    HANDLE handle;
+    
+    handle = GDI_AllocObject( sizeof(DC), DC_MAGIC );
+    if (!handle) return 0;
+    dc = (DC *) GDI_HEAP_ADDR( handle );
+
+#ifdef DEBUG_DC
+    printf( "CreateDC(%s %s %s): returning %d\n", driver, device, output, handle );
+#endif
+
+    if (!displayDevCaps)
+    {
+	displayDevCaps = (DeviceCaps *) malloc( sizeof(DeviceCaps) );
+	DC_FillDevCaps( displayDevCaps );
+    }
+
+    dc->saveLevel = 0;
+    memcpy( &dc->w, &DCVAL_defaultValues, sizeof(DCVAL_defaultValues) );
+    memset( &dc->u.x, 0, sizeof(dc->u.x) );
+
+    dc->u.x.drawable   = DefaultRootWindow( XT_display );
+    dc->u.x.gc         = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL );
+    dc->w.flags        = 0;
+    dc->w.devCaps      = displayDevCaps;
+    dc->w.planes       = displayDevCaps->planes;
+    dc->w.bitsPerPixel = displayDevCaps->bitsPixel;
+
+    XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors );    
+    DC_SetDeviceInfo( handle, dc );
+
+    return handle;
+}
+
+
+/***********************************************************************
+ *           CreateCompatibleDC    (GDI.52)
+ */
+HDC CreateCompatibleDC( HDC hdc )
+{
+    DC * dc;
+    HANDLE handle;
+    
+    handle = GDI_AllocObject( sizeof(DC), DC_MAGIC );
+    if (!handle) return 0;
+    dc = (DC *) GDI_HEAP_ADDR( handle );
+
+#ifdef DEBUG_DC
+    printf( "CreateCompatibleDC(%d): returning %d\n", hdc, handle );
+#endif
+
+    dc->saveLevel = 0;
+    memcpy( &dc->w, &DCVAL_defaultValues, sizeof(DCVAL_defaultValues) );
+    memset( &dc->u.x, 0, sizeof(dc->u.x) );
+
+    dc->u.x.drawable   = XCreatePixmap( XT_display,
+				        DefaultRootWindow( XT_display ),
+				        1, 1, 1 );
+    dc->u.x.gc         = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL );
+    dc->w.flags        = DC_MEMORY;
+    dc->w.planes       = 1;
+    dc->w.bitsPerPixel = 1;
+    dc->w.devCaps      = displayDevCaps;
+
+    SelectObject( handle, BITMAP_hbitmapMemDC );
+    DC_SetDeviceInfo( handle, dc );
+    
+    return handle;
+}
+
+
+/***********************************************************************
+ *           DeleteDC    (GDI.68)
+ */
+BOOL DeleteDC( HDC hdc )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+#ifdef DEBUG_DC
+    printf( "DeleteDC: %d\n", hdc );
+#endif
+
+    while (dc->saveLevel)
+    {
+	DC * dcs;
+	HDC hdcs = dc->header.hNext;
+	if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
+	dc->header.hNext = dcs->header.hNext;
+	dc->saveLevel--;
+	DeleteDC( hdcs );
+    }
+    
+    if (!(dc->w.flags & DC_SAVED))
+    {
+	SelectObject( hdc, STOCK_BLACK_PEN );
+	SelectObject( hdc, STOCK_WHITE_BRUSH );
+	SelectObject( hdc, STOCK_SYSTEM_FONT );
+	
+	XFreeGC( XT_display, dc->u.x.gc );
+	if (dc->w.flags & DC_MEMORY) BITMAP_UnselectBitmap( dc );
+    }
+    
+    if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn );
+    if (dc->w.hVisRgn) DeleteObject( dc->w.hVisRgn );
+    if (dc->w.hGCClipRgn) DeleteObject( dc->w.hGCClipRgn );
+    
+    return GDI_FreeObject( hdc );
+}
+
+
+/***********************************************************************
+ *           GetDeviceCaps    (GDI.80)
+ */
+int GetDeviceCaps( HDC hdc, WORD cap )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+
+    if (cap > sizeof(DeviceCaps)-sizeof(WORD)) return 0;
+    
+#ifdef DEBUG_DC
+    printf( "GetDeviceCaps(%d,%d): returning %d\n",
+	    hdc, cap, *(WORD *)(((char *)dc->w.devCaps) + cap) );
+#endif
+    return *(WORD *)(((char *)dc->w.devCaps) + cap);
+}
+
+
+/***********************************************************************
+ *           SetBkColor    (GDI.1)
+ */
+COLORREF SetBkColor( HDC hdc, COLORREF color )
+{
+    COLORREF oldColor;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0x80000000;
+
+    oldColor = dc->w.backgroundColor;
+    dc->w.backgroundColor = color;
+    dc->w.backgroundPixel = GetNearestPaletteIndex( dc->w.hPalette, color );
+    XSetBackground( XT_display, dc->u.x.gc, dc->w.backgroundPixel );
+    return oldColor;
+}
+
+
+/***********************************************************************
+ *           SetTextColor    (GDI.9)
+ */
+COLORREF SetTextColor( HDC hdc, COLORREF color )
+{
+    COLORREF oldColor;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0x80000000;
+
+    oldColor = dc->w.textColor;
+    dc->w.textColor = color;
+    dc->w.textPixel = GetNearestPaletteIndex( dc->w.hPalette, color );
+    XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
+    return oldColor;
+}
+
+
+/***********************************************************************
+ *           SetDCOrg    (GDI.117)
+ */
+DWORD SetDCOrg( HDC hdc, short x, short y )
+{
+    DWORD prevOrg;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+    prevOrg = dc->w.DCOrgX | (dc->w.DCOrgY << 16);
+    dc->w.DCOrgX = x;
+    dc->w.DCOrgY = y;
+    return prevOrg;
+}
diff --git a/windows/dce.c b/windows/dce.c
new file mode 100644
index 0000000..d0019b2
--- /dev/null
+++ b/windows/dce.c
@@ -0,0 +1,157 @@
+/*
+ * USER DCE functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "dce.h"
+#include "win.h"
+#include "gdi.h"
+
+
+#define NB_DCE    5  /* Number of DCEs created at startup */
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+static HANDLE firstDCE = 0;
+static HDC defaultDCstate = 0;
+
+
+/***********************************************************************
+ *           DCE_Init
+ */
+void DCE_Init()
+{
+    int i;
+    HANDLE handle;
+    DCE * dce;
+        
+    for (i = 0; i < NB_DCE; i++)
+    {
+	handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(DCE) );
+	if (!handle) return;
+	dce = (DCE *) GlobalLock( handle );
+	dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
+	if (!dce->hdc)
+	{
+	    GlobalUnlock( handle );
+	    GlobalFree( handle );
+	    return;
+	}
+	dce->hwndCurrent = 0;
+	dce->flags = 0;
+	dce->inUse = FALSE;
+	dce->xOrigin = 0;
+	dce->yOrigin = 0;
+	dce->hNext = firstDCE;
+	firstDCE = handle;
+	if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc );
+	GlobalUnlock( handle );
+    }
+}
+
+
+/***********************************************************************
+ *           GetDC    (USER.66)
+ */
+HDC GetDC( HWND hwnd )
+{
+    HANDLE hdce, next;
+    HDC hdc;
+    DCE * dce;
+    DC * dc;
+    WND * wndPtr = NULL;
+    
+    if (hwnd)
+    {
+	wndPtr = WIN_FindWndPtr( hwnd );
+	if (!wndPtr) return 0;
+    }
+        
+    for (hdce = firstDCE; (hdce); hdce = next)
+    {
+	dce = (DCE *) GlobalLock( hdce );
+	if (!dce) return 0;
+	if (!dce->inUse) break;
+	next = dce->hNext;
+	GlobalUnlock( hdce );
+    }
+
+    if (!hdce)
+    {
+	if (hwnd) GlobalUnlock( hwnd );
+	return 0;
+    }
+    
+      /* Initialize DC */
+    
+    dc = (DC *) GDI_GetObjPtr( dce->hdc, DC_MAGIC );
+    if (!dc)
+    {
+	if (hwnd) GlobalUnlock( hwnd );
+	return 0;
+    }
+    if (wndPtr)
+    {
+	dc->u.x.drawable = XtWindow( wndPtr->winWidget );
+    	dc->u.x.widget   = wndPtr->winWidget;
+    }
+    else
+    {
+	dc->u.x.drawable = DefaultRootWindow( XT_display );
+	dc->u.x.widget   = 0;
+    }   
+    SetDCState( dce->hdc, defaultDCstate );
+
+    dce->hwndCurrent = hwnd;
+    dce->inUse       = TRUE;
+    hdc = dce->hdc;
+    GlobalUnlock( hdce );
+    if (hwnd) GlobalUnlock( hwnd );
+#ifdef DEBUG_WIN
+    printf( "GetDC(%d): returning %d\n", hwnd, hdc );
+#endif
+    return hdc;
+}
+
+
+/***********************************************************************
+ *           ReleaseDC    (USER.68)
+ */
+int ReleaseDC( HWND hwnd, HDC hdc )
+{
+    HANDLE hdce, next;
+    DCE * dce;
+    WND * wndPtr = NULL;
+    
+#ifdef DEBUG_WIN
+    printf( "ReleaseDC: %d %d\n", hwnd, hdc );
+#endif
+        
+    if (hwnd)
+    {
+	wndPtr = WIN_FindWndPtr( hwnd );
+	if (!wndPtr) return 0;
+    }
+
+    for (hdce = firstDCE; (hdce); hdce = next)
+    {
+	dce = (DCE *) GlobalLock( hdce );
+	if (!dce) return 0;
+	if (dce->inUse && (dce->hdc == hdc)) break;
+	next = dce->hNext;
+	GlobalUnlock( hdce );
+    }
+
+    if (hdce) 
+    {
+	dce->inUse = FALSE;
+    	GlobalUnlock( hdce );
+    }
+
+    if (hwnd) GlobalUnlock( hwnd );
+    return (hdce != 0);
+}
diff --git a/event.c b/windows/event.c
similarity index 68%
rename from event.c
rename to windows/event.c
index 6e65f29..ea0bfc4 100644
--- a/event.c
+++ b/windows/event.c
@@ -11,6 +11,7 @@
 #include <X11/Core.h>
 
 #include "windows.h"
+#include "win.h"
 
 
 #define NB_BUTTONS      3     /* Windows can handle 3 buttons */
@@ -22,7 +23,10 @@
 static void EVENT_key();
 static void EVENT_mouse_motion();
 static void EVENT_mouse_button();
+static void EVENT_structure();
 
+  /* State variables */
+static HWND captureWnd = 0;
 
 /***********************************************************************
  *           EVENT_AddHandlers
@@ -39,6 +43,8 @@
 		      EVENT_mouse_motion, (XtPointer)hwnd );
     XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE,
 		      EVENT_mouse_button, (XtPointer)hwnd );
+    XtAddEventHandler(w, StructureNotifyMask, FALSE,
+		      EVENT_structure, (XtPointer)hwnd );
 }
 
 
@@ -57,6 +63,8 @@
 			 EVENT_mouse_motion, (XtPointer)hwnd );
     XtRemoveEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE,
 			 EVENT_mouse_button, (XtPointer)hwnd );
+    XtRemoveEventHandler(w, StructureNotifyMask, FALSE,
+			 EVENT_structure, (XtPointer)hwnd );
 }
 
 
@@ -84,21 +92,16 @@
  *
  * Handle a X expose event
  */
-static void EVENT_expose( Widget w, int hwnd, XEvent *event,
+static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event,
 			  Boolean *cont_dispatch )
 {
-    MSG msg;
-    XExposeEvent * expEvt = (XExposeEvent *)expEvt;
+    RECT rect;
+    rect.left   = event->x;
+    rect.top    = event->y;
+    rect.right  = event->x + event->width;
+    rect.bottom = event->y + event->height;
     
-    msg.hwnd    = hwnd;
-    msg.message = WM_PAINT;
-    msg.wParam  = 0;
-    msg.lParam  = 0;
-    msg.time = 0;
-    msg.pt.x = 0;
-    msg.pt.y = 0;
-            
-    MSG_AddMsg( &msg, 0 );
+    InvalidateRect( hwnd, &rect, TRUE );
 }
 
 
@@ -186,3 +189,80 @@
     MSG_AddMsg( &msg );    
 }
 
+
+/***********************************************************************
+ *           EVENT_structure
+ *
+ * Handle a X StructureNotify event
+ */
+static void EVENT_structure( Widget w, int hwnd, XEvent *event, 
+ 			     Boolean *cont_dispatch )
+{
+    MSG msg;
+    
+    msg.hwnd = hwnd;
+    msg.time = GetTickCount();
+    msg.pt.x = 0;
+    msg.pt.y = 0;
+
+    switch(event->type)
+    {
+      case ConfigureNotify:
+	{
+	    XConfigureEvent * evt = (XConfigureEvent *)event;
+	    WND * wndPtr = WIN_FindWndPtr( hwnd );
+	    if (!wndPtr) return;
+	    wndPtr->rectClient.right  = wndPtr->rectClient.left + evt->width;
+	    wndPtr->rectClient.bottom = wndPtr->rectClient.top + evt->height;
+	    PostMessage( hwnd, WM_SIZE, SIZE_RESTORED,
+			 (evt->width & 0xffff) | (evt->height << 16) );
+	}
+	break;
+	
+    }    
+}
+
+/**********************************************************************
+ *		SetCapture 	(USER.18)
+ */
+HWND SetCapture(HWND wnd)
+{
+    int rv;
+    HWND old_capture_wnd = captureWnd;
+    WND *wnd_p = WIN_FindWndPtr(wnd);
+    if (wnd_p == NULL)
+	return 0;
+    
+    rv = XtGrabPointer(wnd_p->winWidget, False, 
+		       ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
+		       GrabModeAsync, GrabModeSync, None, None, CurrentTime);
+
+    GlobalUnlock(wnd);
+    if (rv == GrabSuccess)
+    {
+	captureWnd = wnd;
+	return old_capture_wnd;
+    }
+    else
+	return 0;
+}
+
+/**********************************************************************
+ *		ReleaseCapture	(USER.19)
+ */
+void ReleaseCapture()
+{
+    WND *wnd_p;
+    
+    if (captureWnd == 0)
+	return;
+    
+    wnd_p = WIN_FindWndPtr(captureWnd);
+    if (wnd_p == NULL)
+	return;
+    
+    XtUngrabPointer(wnd_p->winWidget, CurrentTime);
+
+    GlobalUnlock(captureWnd);
+    captureWnd = 0;
+}
diff --git a/windows/graphics.c b/windows/graphics.c
new file mode 100644
index 0000000..cc47f99
--- /dev/null
+++ b/windows/graphics.c
@@ -0,0 +1,335 @@
+/*
+ * GDI graphics operations
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <math.h>
+#include <X11/Xlib.h>
+
+#include "gdi.h"
+
+/***********************************************************************
+ *           LineTo    (GDI.19)
+ */
+BOOL LineTo( HDC hdc, short x, short y )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (DC_SetupGCForPen( dc ))
+	XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc, 
+		  XLPTODP( dc, dc->w.CursPosX ), YLPTODP( dc, dc->w.CursPosY ),
+		  XLPTODP( dc, x ), YLPTODP( dc, y ) );
+    dc->w.CursPosX = x;
+    dc->w.CursPosY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           MoveTo    (GDI.20)
+ */
+DWORD MoveTo( HDC hdc, short x, short y )
+{
+    POINT pt;
+    if (MoveToEx( hdc, x, y, &pt )) return pt.x | (pt.y << 16);
+    else return 0;
+}
+
+
+/***********************************************************************
+ *           MoveToEx    (GDI.483)
+ */
+BOOL MoveToEx( HDC hdc, short x, short y, LPPOINT pt )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (pt)
+    {
+	pt->x = dc->w.CursPosX;
+	pt->y = dc->w.CursPosY;
+    }
+    dc->w.CursPosX = x;
+    dc->w.CursPosY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GRAPH_DrawArc
+ *
+ * Helper functions for Arc(), Chord() and Pie().
+ * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
+ */
+BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom,
+		    int xstart, int ystart, int xend, int yend, int lines )
+{
+    int xcenter, ycenter;
+    double start_angle, end_angle, diff_angle;
+    XPoint points[3];
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    left   = XLPTODP( dc, left );
+    top    = YLPTODP( dc, top );
+    right  = XLPTODP( dc, right );
+    bottom = YLPTODP( dc, bottom );
+    xstart = XLPTODP( dc, xstart );
+    ystart = YLPTODP( dc, ystart );
+    xend   = XLPTODP( dc, xend );
+    yend   = YLPTODP( dc, yend );
+    if ((left == right) || (top == bottom)) return FALSE;
+
+    if (!DC_SetupGCForPen( dc )) return TRUE;
+
+    xcenter = (right + left) / 2;
+    ycenter = (bottom + top) / 2;
+    start_angle = atan2( (double)(ycenter-ystart)*(right-left),
+			 (double)(xstart-xcenter)*(bottom-top) );
+    end_angle   = atan2( (double)(ycenter-yend)*(right-left),
+			 (double)(xend-xcenter)*(bottom-top) );
+    diff_angle  = end_angle - start_angle;
+    if (diff_angle < 0.0) diff_angle += 2*PI;
+
+    XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
+	      left, top, right-left-1, bottom-top-1,
+	      (int)(start_angle * 180 * 64 / PI),
+	      (int)(diff_angle * 180 * 64 / PI) );
+    if (!lines) return TRUE;
+
+    points[0].x = xcenter + (int)(cos(start_angle) * (right-left) / 2);
+    points[0].y = ycenter - (int)(sin(start_angle) * (bottom-top) / 2);
+    points[1].x = xcenter + (int)(cos(end_angle) * (right-left) / 2);
+    points[1].y = ycenter - (int)(sin(end_angle) * (bottom-top) / 2);
+    if (lines == 2)
+    {
+	points[2] = points[1];
+	points[1].x = xcenter;
+	points[1].y = ycenter;
+    }
+    XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
+	        points, lines+1, CoordModeOrigin );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           Arc    (GDI.23)
+ */
+BOOL Arc( HDC hdc, int left, int top, int right, int bottom,
+	  int xstart, int ystart, int xend, int yend )
+{
+    return GRAPH_DrawArc( hdc, left, top, right, bottom,
+			  xstart, ystart, xend, yend, 0 );
+}
+
+
+/***********************************************************************
+ *           Pie    (GDI.26)
+ */
+BOOL Pie( HDC hdc, int left, int top, int right, int bottom,
+	  int xstart, int ystart, int xend, int yend )
+{
+    return GRAPH_DrawArc( hdc, left, top, right, bottom,
+			  xstart, ystart, xend, yend, 2 );
+}
+
+
+/***********************************************************************
+ *           Chord    (GDI.348)
+ */
+BOOL Chord( HDC hdc, int left, int top, int right, int bottom,
+	    int xstart, int ystart, int xend, int yend )
+{
+    return GRAPH_DrawArc( hdc, left, top, right, bottom,
+			  xstart, ystart, xend, yend, 1 );
+}
+
+
+/***********************************************************************
+ *           Ellipse    (GDI.24)
+ */
+BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    left   = XLPTODP( dc, left );
+    top    = YLPTODP( dc, top );
+    right  = XLPTODP( dc, right );
+    bottom = YLPTODP( dc, bottom );
+    if ((left == right) || (top == bottom)) return FALSE;
+    
+    if (DC_SetupGCForBrush( dc ))
+	XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		  left, top, right-left-1, bottom-top-1, 0, 360*64 );
+    if (DC_SetupGCForPen( dc ))
+	XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		  left, top, right-left-1, bottom-top-1, 0, 360*64 );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           Rectangle    (GDI.27)
+ */
+BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    left   = XLPTODP( dc, left );
+    top    = YLPTODP( dc, top );
+    right  = XLPTODP( dc, right );
+    bottom = YLPTODP( dc, bottom );
+    
+    if (DC_SetupGCForBrush( dc ))
+	XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		        left, top, right-left-1, bottom-top-1 );
+    if (DC_SetupGCForPen( dc ))
+	XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		        left, top, right-left-1, bottom-top-1 );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           FillRect    (USER.81)
+ */
+int FillRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
+{
+    HBRUSH prevBrush;
+
+    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
+    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
+    PatBlt( hdc, rect->left, rect->top,
+	    rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
+    SelectObject( hdc, prevBrush );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           InvertRect    (USER.82)
+ */
+void InvertRect( HDC hdc, LPRECT rect )
+{
+    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return;
+    PatBlt( hdc, rect->left, rect->top,
+	    rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
+}
+
+
+/***********************************************************************
+ *           SetPixel    (GDI.31)
+ */
+COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color )
+{
+    int pixel;
+    PALETTEENTRY entry;
+    
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+
+    x = XLPTODP( dc, x );
+    y = YLPTODP( dc, y );
+    pixel = GetNearestPaletteIndex( dc->w.hPalette, color );
+    GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
+    
+    XSetForeground( XT_display, dc->u.x.gc, pixel );
+    XDrawPoint( XT_display, dc->u.x.drawable, dc->u.x.gc, x, y );
+
+    return RGB( entry.peRed, entry.peGreen, entry.peBlue );
+}
+
+
+/***********************************************************************
+ *           GetPixel    (GDI.83)
+ */
+COLORREF GetPixel( HDC hdc, short x, short y )
+{
+    PALETTEENTRY entry;
+    XImage * image;
+    
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+
+    x = XLPTODP( dc, x );
+    y = YLPTODP( dc, y );
+    if ((x < 0) || (y < 0)) return 0;
+    
+    if (dc->u.x.widget)
+    {
+	XWindowAttributes win_attr;
+	
+	if (!XtIsRealized(dc->u.x.widget)) return 0;
+	if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr ))
+	    return 0;
+	if (win_attr.map_state != IsViewable) return 0;
+	if ((x >= win_attr.width) || (y >= win_attr.height)) return 0;
+    }
+    
+    image = XGetImage( XT_display, dc->u.x.drawable, x, y,
+		       1, 1, AllPlanes, ZPixmap );
+    GetPaletteEntries( dc->w.hPalette, XGetPixel( image, 0, 0 ), 1, &entry );
+    XDestroyImage( image );
+    return RGB( entry.peRed, entry.peGreen, entry.peBlue );
+}
+
+
+/***********************************************************************
+ *           PaintRgn    (GDI.43)
+ */
+BOOL PaintRgn( HDC hdc, HRGN hrgn )
+{
+    RECT box;
+    HRGN tmpVisRgn, prevVisRgn;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+      /* Modify visible region */
+
+    prevVisRgn = SaveVisRgn( hdc );
+    if (prevVisRgn)
+    {
+	if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 )))
+	{
+	    RestoreVisRgn( hdc );
+	    return FALSE;
+	}
+	CombineRgn( tmpVisRgn, prevVisRgn, hrgn, RGN_AND );
+	SelectVisRgn( hdc, tmpVisRgn );
+	DeleteObject( tmpVisRgn );
+    }
+    else SelectVisRgn( hdc, hrgn );
+
+      /* Fill the region */
+
+    GetClipBox( hdc, &box );
+    if (DC_SetupGCForBrush( dc ))
+	XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		        box.left, box.top,
+		        box.right-box.left, box.bottom-box.top );
+
+      /* Restore the visible region */
+
+    if (prevVisRgn) RestoreVisRgn( hdc );
+    else SelectVisRgn( hdc, 0 );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           FillRgn    (GDI.40)
+ */
+BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
+{
+    BOOL retval;
+    HBRUSH prevBrush = SelectObject( hdc, hbrush );
+    if (!prevBrush) return FALSE;
+    retval = PaintRgn( hdc, hrgn );
+    SelectObject( hdc, prevBrush );
+    return retval;
+}
diff --git a/windows/keyboard.c b/windows/keyboard.c
new file mode 100644
index 0000000..888fd27
--- /dev/null
+++ b/windows/keyboard.c
@@ -0,0 +1,19 @@
+/*
+ * Keyboard related functions
+ *
+ * Copyright 1993 Bob Amstadt
+ */
+
+static char Copyright[] = "Copyright  Bob Amstadt, 1993";
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include "win.h"
+
+/**********************************************************************
+ *		GetKeyState	(USER.106)
+ */
+int GetKeyState(int keycode)
+{
+    return 0;
+}
diff --git a/windows/mapping.c b/windows/mapping.c
new file mode 100644
index 0000000..e361a0f
--- /dev/null
+++ b/windows/mapping.c
@@ -0,0 +1,408 @@
+/*
+ * GDI mapping mode functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include "gdi.h"
+
+
+/***********************************************************************
+ *           MAPPING_FixIsotropic
+ *
+ * Fix viewport extensions for isotropic mode.
+ */
+void MAPPING_FixIsotropic( DC * dc )
+{
+    double xdim = (double)dc->w.VportExtX * dc->w.devCaps->horzSize /
+	          (dc->w.devCaps->horzRes * dc->w.WndExtX);
+    double ydim = (double)dc->w.VportExtY * dc->w.devCaps->vertSize /
+	          (dc->w.devCaps->vertRes * dc->w.WndExtY);
+    if (xdim > ydim)
+    {
+	dc->w.VportExtX = dc->w.VportExtX * ydim / xdim;
+	if (!dc->w.VportExtX) dc->w.VportExtX = 1;
+    }
+    else
+    {
+	dc->w.VportExtY = dc->w.VportExtY * xdim / ydim;
+	if (!dc->w.VportExtY) dc->w.VportExtY = 1;
+    }	
+}
+
+/***********************************************************************
+ *           DPtoLP    (GDI.67)
+ */
+BOOL DPtoLP( HDC hdc, LPPOINT points, int count )
+{
+    POINT * pt;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    
+    for (pt = points; count > 0; pt++, count--)
+    {
+	pt->x = XDPTOLP( dc, pt->x );
+	pt->y = YDPTOLP( dc, pt->y );
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LPtoDP    (GDI.99)
+ */
+BOOL LPtoDP( HDC hdc, LPPOINT points, int count )
+{
+    POINT * pt;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    
+    for (pt = points; count > 0; pt++, count--)
+    {
+	pt->x = XLPTODP( dc, pt->x );
+	pt->y = YLPTODP( dc, pt->y );
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetMapMode    (GDI.3)
+ */
+WORD SetMapMode( HDC hdc, WORD mode )
+{
+    WORD prevMode;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return 0;
+
+#ifdef DEBUG_GDI
+    printf( "SetMapMode: %d %d\n", hdc, mode );
+#endif
+    
+    prevMode = dc->w.MapMode;
+    switch(mode)
+    {
+      case MM_TEXT:
+	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
+	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
+	  dc->w.WndExtX   = 1;
+	  dc->w.WndExtY   = 1;
+	  dc->w.VportExtX = 1;
+	  dc->w.VportExtY = 1;
+	  break;
+	  
+      case MM_LOMETRIC:
+      case MM_ISOTROPIC:
+	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
+	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
+	  dc->w.WndExtX   = dc->w.devCaps->horzSize;
+	  dc->w.WndExtY   = dc->w.devCaps->vertSize;
+	  dc->w.VportExtX = dc->w.devCaps->horzRes / 10;
+	  dc->w.VportExtY = dc->w.devCaps->vertRes / -10;
+	  break;
+	  
+      case MM_HIMETRIC:
+	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
+	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
+	  dc->w.WndExtX   = dc->w.devCaps->horzSize * 10;
+	  dc->w.WndExtY   = dc->w.devCaps->vertSize * 10;
+	  dc->w.VportExtX = dc->w.devCaps->horzRes / 10;
+	  dc->w.VportExtY = dc->w.devCaps->vertRes / -10;
+	  break;
+	  
+      case MM_LOENGLISH:
+	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
+	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
+	  dc->w.WndExtX   = dc->w.devCaps->horzSize;
+	  dc->w.WndExtY   = dc->w.devCaps->vertSize;
+	  dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
+	  dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
+	  break;	  
+	  
+      case MM_HIENGLISH:
+	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
+	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
+	  dc->w.WndExtX   = dc->w.devCaps->horzSize * 10;
+	  dc->w.WndExtY   = dc->w.devCaps->vertSize * 10;
+	  dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
+	  dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
+	  break;
+	  
+      case MM_TWIPS:
+	  dc->w.WndOrgX   = dc->w.WndOrgY   = 0;
+	  dc->w.VportOrgX = dc->w.VportOrgY = 0;
+	  dc->w.WndExtX   = (short)(144L * dc->w.devCaps->horzSize / 10);
+	  dc->w.WndExtY   = (short)(144L * dc->w.devCaps->vertSize / 10);
+	  dc->w.VportExtX = (short)(254L * dc->w.devCaps->horzRes / 1000);
+	  dc->w.VportExtY = (short)(-254L * dc->w.devCaps->vertRes / 1000);
+	  break;
+	  
+      case MM_ANISOTROPIC:
+	  break;
+
+      default:
+	  return prevMode;
+    }
+    dc->w.MapMode = mode;
+    return prevMode;
+}
+
+
+/***********************************************************************
+ *           SetViewportExt    (GDI.14)
+ */
+DWORD SetViewportExt( HDC hdc, short x, short y )
+{
+    SIZE size;
+    if (!SetViewportExtEx( hdc, x, y, &size )) return 0;
+    return size.cx | (size.cy << 16);
+}
+
+
+/***********************************************************************
+ *           SetViewportExtEx    (GDI.479)
+ */
+BOOL SetViewportExtEx( HDC hdc, short x, short y, LPSIZE size )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (size)
+    {
+	size->cx = dc->w.VportExtX;
+	size->cy = dc->w.VportExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!x || !y) return FALSE;
+    dc->w.VportExtX = x;
+    dc->w.VportExtY = y;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetViewportOrg    (GDI.13)
+ */
+DWORD SetViewportOrg( HDC hdc, short x, short y )
+{
+    POINT pt;
+    if (!SetViewportOrgEx( hdc, x, y, &pt )) return 0;
+    return pt.x | (pt.y << 16);
+}
+
+
+/***********************************************************************
+ *           SetViewportOrgEx    (GDI.480)
+ */
+BOOL SetViewportOrgEx( HDC hdc, short x, short y, LPPOINT pt )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (pt)
+    {
+	pt->x = dc->w.VportOrgX;
+	pt->y = dc->w.VportOrgY;
+    }
+    dc->w.VportOrgX = x;
+    dc->w.VportOrgY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetWindowExt    (GDI.12)
+ */
+DWORD SetWindowExt( HDC hdc, short x, short y )
+{
+    SIZE size;
+    if (!SetWindowExtEx( hdc, x, y, &size )) return 0;
+    return size.cx | (size.cy << 16);
+}
+
+
+/***********************************************************************
+ *           SetWindowExtEx    (GDI.481)
+ */
+BOOL SetWindowExtEx( HDC hdc, short x, short y, LPSIZE size )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (size)
+    {
+	size->cx = dc->w.WndExtX;
+	size->cy = dc->w.WndExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!x || !y) return FALSE;
+    dc->w.WndExtX = x;
+    dc->w.WndExtY = y;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetWindowOrg    (GDI.11)
+ */
+DWORD SetWindowOrg( HDC hdc, short x, short y )
+{
+    POINT pt;
+    if (!SetWindowOrgEx( hdc, x, y, &pt )) return 0;
+    return pt.x | (pt.y << 16);
+}
+
+
+/***********************************************************************
+ *           SetWindowOrgEx    (GDI.482)
+ */
+BOOL SetWindowOrgEx( HDC hdc, short x, short y, LPPOINT pt )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (pt)
+    {
+	pt->x = dc->w.WndOrgX;
+	pt->y = dc->w.WndOrgY;
+    }
+    dc->w.WndOrgX = x;
+    dc->w.WndOrgY = y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OffsetViewportOrg    (GDI.17)
+ */
+DWORD OffsetViewportOrg( HDC hdc, short x, short y )
+{
+    POINT pt;
+    if (!OffsetViewportOrgEx( hdc, x, y, &pt )) return 0;
+    return pt.x | (pt.y << 16);
+}
+
+
+/***********************************************************************
+ *           OffsetViewportOrgEx    (GDI.476)
+ */
+BOOL OffsetViewportOrgEx( HDC hdc, short x, short y, LPPOINT pt )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (pt)
+    {
+	pt->x = dc->w.VportOrgX;
+	pt->y = dc->w.VportOrgY;
+    }
+    dc->w.VportOrgX += x;
+    dc->w.VportOrgY += y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           OffsetWindowOrg    (GDI.15)
+ */
+DWORD OffsetWindowOrg( HDC hdc, short x, short y )
+{
+    POINT pt;
+    if (!OffsetWindowOrgEx( hdc, x, y, &pt )) return 0;
+    return pt.x | (pt.y << 16);
+}
+
+
+/***********************************************************************
+ *           OffsetWindowOrgEx    (GDI.477)
+ */
+BOOL OffsetWindowOrgEx( HDC hdc, short x, short y, LPPOINT pt )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (pt)
+    {
+	pt->x = dc->w.WndOrgX;
+	pt->y = dc->w.WndOrgY;
+    }
+    dc->w.WndOrgX += x;
+    dc->w.WndOrgY += y;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ScaleViewportExt    (GDI.18)
+ */
+DWORD ScaleViewportExt( HDC hdc, short xNum, short xDenom,
+		      short yNum, short yDenom )
+{
+    SIZE size;
+    if (!ScaleViewportExtEx( hdc, xNum, xDenom, yNum, yDenom, &size ))
+	return 0;
+    return size.cx | (size.cy << 16);
+}
+
+
+/***********************************************************************
+ *           ScaleViewportExtEx    (GDI.484)
+ */
+BOOL ScaleViewportExtEx( HDC hdc, short xNum, short xDenom,
+			 short yNum, short yDenom, LPSIZE size )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (size)
+    {
+	size->cx = dc->w.VportExtX;
+	size->cy = dc->w.VportExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
+    dc->w.VportExtX = (dc->w.VportExtX * xNum) / xDenom;
+    dc->w.VportExtY = (dc->w.VportExtY * yNum) / yDenom;
+    if (dc->w.VportExtX == 0) dc->w.VportExtX = 1;
+    if (dc->w.VportExtY == 0) dc->w.VportExtY = 1;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           ScaleWindowExt    (GDI.16)
+ */
+DWORD ScaleWindowExt( HDC hdc, short xNum, short xDenom,
+		      short yNum, short yDenom )
+{
+    SIZE size;
+    if (!ScaleWindowExtEx( hdc, xNum, xDenom, yNum, yDenom, &size ))
+	return 0;
+    return size.cx | (size.cy << 16);
+}
+
+
+/***********************************************************************
+ *           ScaleWindowExtEx    (GDI.485)
+ */
+BOOL ScaleWindowExtEx( HDC hdc, short xNum, short xDenom,
+		       short yNum, short yDenom, LPSIZE size )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+    if (size)
+    {
+	size->cx = dc->w.WndExtX;
+	size->cy = dc->w.WndExtY;
+    }
+    if ((dc->w.MapMode != MM_ISOTROPIC) && (dc->w.MapMode != MM_ANISOTROPIC))
+	return TRUE;
+    if (!xNum || !xDenom || !xNum || !yDenom) return FALSE;
+    dc->w.WndExtX = (dc->w.WndExtX * xNum) / xDenom;
+    dc->w.WndExtY = (dc->w.WndExtY * yNum) / yDenom;
+    if (dc->w.WndExtX == 0) dc->w.WndExtX = 1;
+    if (dc->w.WndExtY == 0) dc->w.WndExtY = 1;
+    if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    return TRUE;
+}
diff --git a/message.c b/windows/message.c
similarity index 88%
rename from message.c
rename to windows/message.c
index d013d1d..45cca4a 100644
--- a/message.c
+++ b/windows/message.c
@@ -11,8 +11,7 @@
 
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
-#include <sys/param.h>
-#include <sys/times.h>
+#include <stdlib.h>
 
 #include "message.h"
 #include "win.h"
@@ -20,6 +19,11 @@
 
 #define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
 
+extern HWND WIN_FindWinToRepaint( HWND hwnd );
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+extern XtAppContext XT_app_context;
 
 static MESSAGEQUEUE * msgQueue = NULL;
 
@@ -50,19 +54,12 @@
 int MSG_AddMsg( MSG * msg, DWORD extraInfo )
 {
     int pos, type;
-    QMSG * qmsg;
   
     if (!msgQueue) return FALSE;
     pos = msgQueue->nextFreeMessage;
 
       /* No need to store WM_PAINT messages */
-    if (msg->message == WM_PAINT)
-    {
-	msgQueue->status |= QS_PAINT;
-	msgQueue->tempStatus |= QS_PAINT;
-	/* For now we need to store them to keep the hwnd somewhere */
-	/* return TRUE; */
-    }
+    if (msg->message == WM_PAINT) return TRUE;
         
       /* Check if queue is full */
     if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
@@ -121,7 +118,7 @@
  */
 void MSG_RemoveMsg( int pos )
 {
-    int oldpos, i, type;
+    int i, type;
     QMSG * qmsg;
     
     if (!msgQueue) return;
@@ -155,37 +152,12 @@
 	type |= MSG_GetMessageType( msgQueue->messages[pos].msg.message );
 	if (++pos >= msgQueue->queueSize-1) pos = 0;
     }
-    msgQueue->status = msgQueue->status & (QS_PAINT | QS_SENDMESSAGE) | type;
+    msgQueue->status = (msgQueue->status & QS_SENDMESSAGE) | type;
     msgQueue->tempStatus = 0;
 }
 
 
 /***********************************************************************
- *           MSG_EndPaint
- *
- * Remove the WM_PAINT message from the queue
- */
-void MSG_EndPaint()
-{
-    msgQueue->status &= ~QS_PAINT;
-}
-
-
-/***********************************************************************
- *           MSG_GetTime
- *
- * Return the time elapsed from the starting of the system, in milliseconds.
- * Used to timestamp messages.
- */
-
-LONG MSG_GetTime()
-{
-    struct tms dummy;
-    return times(&dummy) / (1000 / HZ);
-}
-
-
-/***********************************************************************
  *           SetMessageQueue  (USER.266)
  */
 BOOL SetMessageQueue( int size )
@@ -242,6 +214,10 @@
 DWORD GetQueueStatus( int flags )
 {
     unsigned long ret = (msgQueue->status << 16) | msgQueue->tempStatus;
+    if (flags & QS_PAINT)
+    {
+	if (WIN_FindWinToRepaint(0)) ret |= QS_PAINT | (QS_PAINT << 16);
+    }
     msgQueue->tempStatus = 0;
     return ret & ((flags << 16) | flags);
 }
@@ -257,12 +233,12 @@
 
 
 /***********************************************************************
- *           PeekMessage   (USER.109)
+ *           MSG_PeekMessage
  */
-BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
+BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
 {
     int pos;
-    
+
       /* First handle a WM_QUIT message */
     if (msgQueue->wPostQMsg)
     {
@@ -307,23 +283,46 @@
     }
 
       /* If nothing else, return a WM_PAINT message */
-    if (msgQueue->status & QS_PAINT)
+    if ((!first && !last) || ((first <= WM_PAINT) && (last >= WM_PAINT)))
     {
-	if ((!first && !last) || ((first <= WM_PAINT) && (last >= WM_PAINT)))
-	{
-	    msg->hwnd = hwnd;
-	    msg->message = WM_PAINT;
-	    msg->wParam = 0;
-	    msg->lParam = 0;
-	    return TRUE;
-	}
-	
+	msg->hwnd = WIN_FindWinToRepaint( hwnd );
+	msg->message = WM_PAINT;
+	msg->wParam = 0;
+	msg->lParam = 0;
+	return (msg->hwnd != 0);
     }	
     return FALSE;
 }
 
 
 /***********************************************************************
+ *           PeekMessage   (USER.109)
+ */
+BOOL PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, WORD flags )
+{
+    while (XtAppPending( XT_app_context ))
+	XtAppProcessEvent( XT_app_context, XtIMAll );
+
+    return MSG_PeekMessage( msg, hwnd, first, last, flags );
+}
+
+
+/***********************************************************************
+ *           GetMessage   (USER.108)
+ */
+BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) 
+{
+    while(1)
+    {
+	if (MSG_PeekMessage( msg, hwnd, first, last, PM_REMOVE )) break;
+	XtAppProcessEvent( XT_app_context, XtIMAll );
+    }
+
+    return (msg->message != WM_QUIT);
+}
+
+
+/***********************************************************************
  *           PostMessage   (USER.110)
  */
 BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam )
@@ -334,7 +333,7 @@
     msg.message = message;
     msg.wParam  = wParam;
     msg.lParam  = lParam;
-    msg.time    = MSG_GetTime();
+    msg.time    = GetTickCount();
     msg.pt.x    = 0;
     msg.pt.y    = 0;
     
diff --git a/windows/painting.c b/windows/painting.c
new file mode 100644
index 0000000..050a5cb
--- /dev/null
+++ b/windows/painting.c
@@ -0,0 +1,92 @@
+/*
+ * Window painting functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <math.h>
+#include <X11/Xlib.h>
+
+#include "win.h"
+
+  /* Last CTLCOLOR id */
+#define CTLCOLOR_MAX   CTLCOLOR_STATIC
+
+
+/***********************************************************************
+ *           BeginPaint    (USER.39)
+ */
+HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) 
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return 0;
+
+    lps->hdc = GetDC( hwnd );
+    if (!lps->hdc) return 0;
+    
+    SelectVisRgn( lps->hdc, wndPtr->hrgnUpdate );
+    if (wndPtr->hrgnUpdate)
+    {
+	GetRgnBox( wndPtr->hrgnUpdate, &lps->rcPaint );
+	DeleteObject( wndPtr->hrgnUpdate );
+	wndPtr->hrgnUpdate = 0;
+    }
+    else
+    {
+	lps->rcPaint.left   = 0;
+	lps->rcPaint.top    = 0;
+	lps->rcPaint.right  = wndPtr->rectClient.right-wndPtr->rectClient.left;
+	lps->rcPaint.bottom = wndPtr->rectClient.bottom-wndPtr->rectClient.top;
+    }    
+
+    if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
+    else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
+
+    GlobalUnlock( hwnd );
+    return lps->hdc;
+}
+
+
+/***********************************************************************
+ *           EndPaint    (USER.40)
+ */
+void EndPaint( HWND hwnd, LPPAINTSTRUCT lps )
+{
+    ReleaseDC( hwnd, lps->hdc );
+}
+
+
+/***********************************************************************
+ *           FillWindow    (USER.324)
+ */
+void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush )
+{
+    RECT rect;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return;
+    rect.left   = 0;
+    rect.top    = 0;
+    rect.right  = wndPtr->rectClient.right - wndPtr->rectClient.left;
+    rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
+    PaintRect( hwndParent, hwnd, hdc, hbrush, &rect );
+    GlobalUnlock( hwnd );
+}
+
+
+/***********************************************************************
+ *           PaintRect    (USER.325)
+ */
+void PaintRect(HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush, LPRECT rect)
+{
+      /* Send WM_CTLCOLOR message if needed */
+
+    if (hbrush <= CTLCOLOR_MAX)
+    {
+	if (!hwndParent) return;
+	hbrush = (HBRUSH)SendMessage( hwndParent, WM_CTLCOLOR,
+				      hdc, hwnd | (hbrush << 16) );
+    }
+    if (hbrush) FillRect( hdc, rect, hbrush );
+}
diff --git a/windows/timer.c b/windows/timer.c
new file mode 100644
index 0000000..2aeb88ee
--- /dev/null
+++ b/windows/timer.c
@@ -0,0 +1,165 @@
+/*
+ * Timer functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <X11/Intrinsic.h>
+
+#include "windows.h"
+
+extern XtAppContext XT_app_context;
+
+
+typedef struct
+{
+    HWND          hwnd;
+    WORD          msg;  /* WM_TIMER or WM_SYSTIMER */
+    WORD          id;
+    WORD          timeout;
+    FARPROC       proc;
+    XtIntervalId  xtid;
+} TIMER;
+
+#define NB_TIMERS            34
+#define NB_RESERVED_TIMERS    2  /* for SetSystemTimer */
+
+static TIMER TimersArray[NB_TIMERS];
+
+
+/***********************************************************************
+ *           TIMER_callback
+ */
+static void TIMER_callback( XtPointer data, XtIntervalId * xtid )
+{
+    TIMER * pTimer = (TIMER *) data;
+    
+    pTimer->xtid = 0;  /* In case the timer procedure calls KillTimer */
+    
+    if (pTimer->proc)
+    {
+	CallWindowProc(pTimer->proc, pTimer->hwnd, pTimer->msg, 
+		       pTimer->id, GetTickCount());
+    }
+    else 
+	PostMessage( pTimer->hwnd, pTimer->msg, pTimer->id, 0 );
+
+      /* If timeout == 0, the timer has been removed by KillTimer */
+    if (pTimer->timeout)
+	pTimer->xtid = XtAppAddTimeOut( XT_app_context, pTimer->timeout,
+				        TIMER_callback, pTimer );
+}
+
+
+/***********************************************************************
+ *           TIMER_SetTimer
+ */
+WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc, BOOL sys )
+{
+    int i;
+    TIMER * pTimer;
+    
+    if (!timeout) return 0;
+    if (!hwnd && !proc) return 0;
+    
+      /* Find a free timer */
+    
+    for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
+	if (!pTimer->timeout) break;
+
+    if (i >= NB_TIMERS) return 0;
+    if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return 0;
+    if (!hwnd) id = i + 1;
+    
+      /* Add the timer */
+
+    pTimer->hwnd    = hwnd;
+    pTimer->msg     = sys ? WM_SYSTIMER : WM_TIMER;
+    pTimer->id      = id;
+    pTimer->timeout = timeout;
+    pTimer->proc    = proc;
+    pTimer->xtid    = XtAppAddTimeOut( XT_app_context, timeout,
+				       TIMER_callback, pTimer );
+    return id;
+}
+
+
+/***********************************************************************
+ *           TIMER_KillTimer
+ */
+BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys )
+{
+    int i;
+    TIMER * pTimer;
+    
+      /* Find the timer */
+    
+    for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
+	if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
+	    (pTimer->timeout != 0)) break;
+    if (i >= NB_TIMERS) return FALSE;
+    if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return FALSE;
+    if (!sys && (pTimer->msg != WM_TIMER)) return FALSE;
+    else if (sys && (pTimer->msg != WM_SYSTIMER)) return FALSE;    
+
+      /* Delete the timer */
+
+    if (pTimer->xtid) XtRemoveTimeOut( pTimer->xtid );
+    pTimer->hwnd    = 0;
+    pTimer->msg     = 0;
+    pTimer->id      = 0;
+    pTimer->timeout = 0;
+    pTimer->proc    = 0;
+    pTimer->xtid    = 0;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetTimer   (USER.10)
+ */
+WORD SetTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
+{
+#ifdef DEBUG_TIMER    
+    printf( "SetTimer: %d %d %d %08x\n", hwnd, id, timeout, proc );
+#endif
+    return TIMER_SetTimer( hwnd, id, timeout, proc, FALSE );
+}
+
+
+/***********************************************************************
+ *           SetSystemTimer   (USER.11)
+ */
+WORD SetSystemTimer( HWND hwnd, WORD id, WORD timeout, FARPROC proc )
+{
+#ifdef DEBUG_TIMER    
+    printf( "SetSystemTimer: %d %d %d %08x\n", hwnd, id, timeout, proc );
+#endif
+    return TIMER_SetTimer( hwnd, id, timeout, proc, TRUE );
+}
+
+
+/***********************************************************************
+ *           KillTimer   (USER.12)
+ */
+BOOL KillTimer( HWND hwnd, WORD id )
+{
+#ifdef DEBUG_TIMER
+    printf( "KillTimer: %d %d\n", hwnd, id );
+#endif
+    return TIMER_KillTimer( hwnd, id, FALSE );
+}
+
+
+/***********************************************************************
+ *           KillSystemTimer   (USER.182)
+ */
+BOOL KillSystemTimer( HWND hwnd, WORD id )
+{
+#ifdef DEBUG_TIMER
+    printf( "KillSystemTimer: %d %d\n", hwnd, id );
+#endif
+    return TIMER_KillTimer( hwnd, id, TRUE );
+}
diff --git a/windows/win.c b/windows/win.c
new file mode 100644
index 0000000..615339a
--- /dev/null
+++ b/windows/win.c
@@ -0,0 +1,443 @@
+/*
+ * Window related functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Core.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Box.h>
+
+#include "class.h"
+#include "win.h"
+#include "heap.h"
+
+extern Display * XT_display;
+
+
+static HWND firstWindow = 0;
+
+
+/***********************************************************************
+ *           WIN_FindWndPtr
+ *
+ * Return a pointer to the WND structure corresponding to a HWND.
+ * The caller must GlobalUnlock the pointer.
+ */
+WND * WIN_FindWndPtr( HWND hwnd )
+{
+    WND * ptr;
+    
+    if (!hwnd) return NULL;
+    ptr = (WND *) GlobalLock( hwnd );
+    if (ptr->dwMagic != WND_MAGIC)
+    {
+	GlobalUnlock( hwnd );
+	return NULL;
+    }
+    return ptr;
+}
+
+
+/***********************************************************************
+ *           WIN_FindWinToRepaint
+ *
+ * Find a window that needs repaint.
+ */
+HWND WIN_FindWinToRepaint( HWND hwnd )
+{
+    WND * wndPtr;
+    
+    if (!hwnd) hwnd = firstWindow;
+    while (hwnd)
+    {
+	if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+	if (wndPtr->hrgnUpdate) return hwnd;
+	if (wndPtr->hwndChild)
+	{
+	    HWND child;
+	    if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
+		return child;
+	}
+	hwnd = wndPtr->hwndNext;
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           CreateWindow   (USER.41)
+ */
+HWND CreateWindow( LPSTR className, LPSTR windowName,
+		   DWORD style, short x, short y, short width, short height,
+		   HWND parent, HMENU menu, HANDLE instance, LPSTR data ) 
+{
+    HANDLE class, hwnd;
+    CLASS *classPtr;
+    WND *wndPtr, *parentPtr = NULL;
+    CREATESTRUCT *createStruct;
+    HANDLE hcreateStruct;
+    int wmcreate;
+    Widget parentWidget = 0;
+
+#ifdef DEBUG_WIN
+    printf( "CreateWindow: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height );
+#endif
+
+    if (x == CW_USEDEFAULT) x = 0;
+    if (y == CW_USEDEFAULT) y = 0;
+    if (width == CW_USEDEFAULT) width = 600;
+    if (height == CW_USEDEFAULT) height = 400;
+
+      /* Find the parent and class */
+
+    if (parent) 
+    {
+	  /* Check if parent is valid */
+	parentPtr = WIN_FindWndPtr( parent );
+	if (!parentPtr) return 0;
+    }
+    else if (style & WS_CHILD) return 0;  /* WS_CHILD needs a parent */
+
+    if (!(class = CLASS_FindClassByName( className, &classPtr )))
+    {
+	GlobalUnlock( parent );
+	return 0;
+    }
+    
+      /* Create the window structure */
+
+    hwnd = GlobalAlloc( GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra );
+    if (!hwnd)
+    {
+	GlobalUnlock( parent );
+	return 0;
+    }
+
+      /* Fill the structure */
+
+    wndPtr = (WND *) GlobalLock( hwnd );
+    wndPtr->hwndNext   = 0;
+    wndPtr->hwndChild  = 0;
+    wndPtr->dwMagic    = WND_MAGIC;
+    wndPtr->hwndParent = parent;
+    wndPtr->hwndOwner  = parent;  /* What else? */
+    wndPtr->hClass     = class;
+    wndPtr->hInstance  = instance;
+    wndPtr->rectClient.left   = x;
+    wndPtr->rectClient.top    = y;
+    wndPtr->rectClient.right  = x + width;
+    wndPtr->rectClient.bottom = y + height;
+    wndPtr->rectWindow        = wndPtr->rectClient;
+    wndPtr->hrgnUpdate        = 0;
+    wndPtr->hwndLastActive    = 0;
+    wndPtr->lpfnWndProc       = classPtr->wc.lpfnWndProc;
+    wndPtr->dwStyle           = style;
+    wndPtr->hDCE              = 0;
+    wndPtr->hmenuSystem       = 0;
+    wndPtr->wIDmenu           = menu;
+    wndPtr->flags             = 0;
+    if (classPtr->wc.cbWndExtra)
+	memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
+    classPtr->cWindows++;
+
+      /* Insert the window in the linked list */
+
+    if (parent)
+    {
+	wndPtr->hwndNext = parentPtr->hwndChild;
+	parentPtr->hwndChild = hwnd;
+    }
+    else  /* Top-level window */
+    {
+	wndPtr->hwndNext = firstWindow;
+	firstWindow = hwnd;
+    }
+    
+      /* Create the widgets */
+
+    if (style & WS_CHILD)
+    {
+	wndPtr->shellWidget = 0;
+	wndPtr->winWidget = XtVaCreateManagedWidget(className,
+						    coreWidgetClass,
+						    parentPtr->winWidget,
+						    XtNx, x,
+						    XtNy, y,
+						    XtNwidth, width,
+						    XtNheight, height,
+						    NULL );
+    }
+    else
+    {
+	wndPtr->shellWidget = XtVaAppCreateShell(className, 
+						 windowName,
+						 topLevelShellWidgetClass,
+						 XT_display,
+						 XtNx, x,
+						 XtNy, y,
+						 NULL );
+    	wndPtr->compositeWidget = XtVaCreateManagedWidget(className,
+						    formWidgetClass,
+						    wndPtr->shellWidget,
+						    NULL );
+	if (wndPtr->wIDmenu == 0)
+	{
+	    wndPtr->menuBarPtr = MENU_CreateMenuBar(wndPtr->compositeWidget,
+						    instance, hwnd,
+						    classPtr->wc.lpszMenuName,
+						    width);
+	    wndPtr->wIDmenu = 
+		GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem);
+	}
+	else
+	{
+	    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget,
+					      instance, hwnd,
+					      wndPtr->wIDmenu, width);
+	}
+
+	if (wndPtr->menuBarPtr != NULL)
+	{
+	    wndPtr->winWidget = 
+		XtVaCreateManagedWidget(className,
+					compositeWidgetClass,
+					wndPtr->compositeWidget,
+					XtNwidth, width,
+					XtNheight, height,
+					XtNfromVert,
+					wndPtr->menuBarPtr->menuBarWidget,
+					XtNvertDistance, 4,
+					NULL );
+	}
+	else
+	{
+	    wndPtr->winWidget = 
+		XtVaCreateManagedWidget(className,
+					compositeWidgetClass,
+					wndPtr->compositeWidget,
+					XtNwidth, width,
+					XtNheight, height,
+					NULL );
+	}
+    }
+
+      /* Send the WM_CREATE message */
+	
+    hcreateStruct = GlobalAlloc( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
+    createStruct = (CREATESTRUCT *) GlobalLock( hcreateStruct );
+    createStruct->lpCreateParams = data;
+    createStruct->hInstance      = instance;
+    createStruct->hMenu          = menu;
+    createStruct->hwndParent     = parent;
+    createStruct->cx             = width;
+    createStruct->cy             = height;
+    createStruct->x              = x;
+    createStruct->y              = y;
+    createStruct->style          = style;
+    createStruct->lpszName       = windowName;
+    createStruct->lpszClass      = className;
+    createStruct->dwExStyle      = 0;
+
+    wmcreate = CallWindowProc( wndPtr->lpfnWndProc, hwnd, 
+			       WM_CREATE, 0, (LONG) createStruct );
+    GlobalUnlock( hcreateStruct );
+    GlobalFree( hcreateStruct );
+    
+    if (wmcreate == -1)
+    {
+	  /* Abort window creation */
+	if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
+	else XtDestroyWidget( wndPtr->winWidget );
+	GlobalUnlock( parent );
+	GlobalUnlock( hwnd );
+	GlobalFree( hwnd );
+	return 0;
+    }
+    
+    EVENT_AddHandlers( wndPtr->winWidget, hwnd );
+
+    if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
+    
+    GlobalUnlock( parent );
+    GlobalUnlock( hwnd );
+    return hwnd;
+}
+
+/***********************************************************************
+ *           DestroyWindow   (USER.53)
+ */
+BOOL DestroyWindow( HWND hwnd )
+{
+    WND *wndPtr, *parentPtr;
+    CLASS * classPtr;
+    
+    wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return FALSE;
+
+    if (wndPtr->hwndParent)
+    {
+	parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
+	printf( "INTERNAL ERROR: DestroyWindow: Invalid window parent\n" );
+	return FALSE;
+    }
+    
+    classPtr = CLASS_FindClassPtr( wndPtr->hClass );
+    if (!classPtr)
+    {
+	printf( "INTERNAL ERROR: DestroyWindow: Invalid window class\n" );
+	return FALSE;
+    }
+    
+    SendMessage( hwnd, WM_DESTROY, 0, 0 );
+    
+      /* Destroy all children */
+
+    /* ........... */
+
+      /* Remove the window from the linked list */
+    
+    /* ........... */
+
+      /* Destroy the window */
+
+    if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
+    else XtDestroyWidget( wndPtr->winWidget );
+    classPtr->cWindows--;
+    if (wndPtr->hwndParent) GlobalUnlock( wndPtr->hwndParent );
+    GlobalUnlock( hwnd );
+    GlobalFree( hwnd );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetClientRect   (USER.33)
+ */
+void GetClientRect( HWND hwnd, LPRECT rect ) 
+{
+    int width, height;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+
+    rect->left = rect->top = rect->right = rect->bottom = 0;
+    if (wndPtr) 
+    {
+	XtVaGetValues(wndPtr->winWidget,
+		      XtNwidth, &width,
+		      XtNheight, &height,
+		      NULL );
+	GlobalUnlock( hwnd );
+	rect->right  = width & 0xffff;
+	rect->bottom = height & 0xffff;
+    }
+}
+
+
+/***********************************************************************
+ *           ShowWindow   (USER.42)
+ */
+BOOL ShowWindow( HWND hwnd, int cmd ) 
+{    
+    int width, height;
+    
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (wndPtr) 
+    {
+	if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
+	GlobalUnlock( hwnd );
+	XtVaGetValues(wndPtr->winWidget, 
+		      XtNwidth, &width,
+		      XtNheight, &height,
+		      NULL );
+	SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, 
+		     (width & 0xffff) | (height << 16) );
+	SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 );
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           UpdateWindow   (USER.124)
+ */
+void UpdateWindow( HWND hwnd )
+{
+    if (GetUpdateRect( hwnd, NULL, FALSE )) 
+	SendMessage( hwnd, WM_PAINT, 0, 0 );
+}
+
+/**********************************************************************
+ *	     GetMenu	    (USER.157)
+ */
+HMENU GetMenu( HWND hwnd ) 
+{ 
+    WND *wndPtr;
+    HMENU hmenu;
+    
+    wndPtr = WIN_FindWndPtr(hwnd);
+    if (wndPtr == NULL)
+	return 0;
+
+    hmenu = wndPtr->wIDmenu;
+    
+    GlobalUnlock(hwnd);
+    return hmenu;
+}
+
+/**********************************************************************
+ *           SetMenu        (USER.158)
+ */
+BOOL SetMenu(HWND hwnd, HMENU hmenu)
+{
+    WND *wndPtr;
+    
+    wndPtr = WIN_FindWndPtr(hwnd);
+    if (wndPtr == NULL)
+	return FALSE;
+
+    if (wndPtr->dwStyle & WS_CHILD)
+    {
+	GlobalUnlock(hwnd);
+	return FALSE;
+    }
+
+    if (wndPtr->menuBarPtr != NULL)
+    {
+	XtVaSetValues(wndPtr->winWidget, XtNfromVert, NULL, NULL);
+	MENU_CollapseMenu(wndPtr->menuBarPtr);
+    }
+    
+    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, 
+				      wndPtr->hInstance, hwnd, hmenu, 
+				      wndPtr->rectClient.right -
+				      wndPtr->rectClient.left);
+
+    if (wndPtr->menuBarPtr != NULL)
+    {
+	XtVaSetValues(wndPtr->winWidget, 
+		      XtNfromVert, wndPtr->menuBarPtr->menuBarWidget, 
+		      XtNvertDistance, 4,
+		      NULL);
+    }
+    else
+    {
+	if (wndPtr->wIDmenu != 0)
+	{
+	    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, 
+					      wndPtr->hInstance, hwnd, 
+					      wndPtr->wIDmenu, 
+					      wndPtr->rectClient.right -
+					      wndPtr->rectClient.left);
+	}
+	
+	GlobalUnlock(hwnd);
+	return FALSE;
+    }
+
+    GlobalUnlock(hwnd);
+    return TRUE;
+}
diff --git a/xt.c b/xt.c
deleted file mode 100644
index 040560f..0000000
--- a/xt.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * X toolkit functions
- *
- * Copyright 1993 Alexandre Julliard
- */
-
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
-
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Core.h>
-#include <X11/Shell.h>
-
-#include "message.h"
-#include "callback.h"
-#include "win.h"
-
-
-Widget XT_topLevelWidget;
-
-static XtAppContext app_context;
-
-
-/***********************************************************************
- *           main
- */
-void main(int argc, char **argv)
-{    
-    XT_topLevelWidget = XtVaAppInitialize(&app_context,
-					  "XWine",     /* Application class */
-					  NULL, 0,     /* Option list */
-					  &argc, argv, /* Command line args */
-					  NULL,        /* Fallback resources */
-					  NULL );
-    _WinMain( argc, argv );
-}
-
-
-/***********************************************************************
- *           GetMessage   (USER.108)
- */
-BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) 
-{
-    XEvent event;
-    
-    while(1)
-    {
-	if (PeekMessage( msg, hwnd, first, last, PM_REMOVE )) break;
-	XtAppNextEvent( app_context, &event );
-	XtDispatchEvent( &event );
-    }
-
-    return (msg->message != WM_QUIT);
-}
-
-
-/***********************************************************************
- *           DefWindowProc   (USER.107)
- */
-LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
-{
-    PAINTSTRUCT paintstruct;
-    
-    printf( "DefWindowProc: %d %d %d %d\n", hwnd, msg, wParam, lParam );
-
-    switch(msg)
-    {
-    case WM_PAINT:
-	BeginPaint( hwnd, &paintstruct );
-	EndPaint( hwnd, &paintstruct );
-	return 0;
-
-    case WM_CREATE:
-	return 0;
-
-    }
-    return 0;
-}
-
-
-/********************************************************************
- *
- * Miscellaneous partially implemented functions.
- * 
- */
-
-
-HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) 
-{
-    return hwnd;
-}
-
-
-void EndPaint( HWND hwnd, LPPAINTSTRUCT lps )
-{
-    MSG_EndPaint();
-}
-
-int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags )
-{
-    WND * wndPtr = WIN_FindWndPtr( hdc );
-    int x = rect->left, y = rect->top;
-        
-    if (flags & DT_CENTER) x = (rect->left + rect->right) / 2;
-    if (flags & DT_VCENTER) y = (rect->top + rect->bottom) / 2;
-    if (count == -1) count = strlen(str);
-
-    printf( "DrawText: %d,%d '%s'\n", x, y, str );
-    if (wndPtr)
-    {
-	XDrawString( XtDisplay(wndPtr->winWidget),
-		    XtWindow(wndPtr->winWidget),
-		    DefaultGCOfScreen(XtScreen(wndPtr->winWidget)),
-		    x, y, str, count );    
-	GlobalUnlock( hdc );
-    }
-}
-
-int MessageBox( HWND hwnd, LPSTR str, LPSTR title, WORD type )
-{
-    printf( "MessageBox: '%s'\n", str );
-}
-
-void MessageBeep( WORD i )
-{
-    printf( "MessageBeep: %d\n", i );
-}
-
-HDC GetDC( HWND hwnd ) { }
-
-HMENU CreateMenu() { }
-
-HMENU GetMenu( HWND hwnd ) { }
-
-BOOL SetMenu( HWND hwnd, HMENU hmenu ) { }
-
-BOOL AppendMenu( HMENU hmenu, WORD flags, WORD id, LPSTR text ) { }
-
-BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) { }
-
-HANDLE GetStockObject( int obj ) { }
-
-