Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Sep 1999 22:47:57 +0200 (MET DST)
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/13952: update emulators/wine to 990923 (supersedes ports/13670)
Message-ID:  <199909252047.WAA56452@saturn.kn-bremen.de>

next in thread | raw e-mail | index | archive | help

>Number:         13952
>Category:       ports
>Synopsis:       update emulators/wine to 990923 (supersedes ports/13670)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 25 14:10:00 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Juergen Lock
>Release:        FreeBSD 3.3-STABLE i386
>Organization:
me?  organized?
>Environment:

	3.3-STABLE i386, xpm-3.4k

>Description:

	From the ANNOUNCE:

This is release 990923 of Wine, a free implementation of Windows on
Unix.  This is still a developers only release.  There are many bugs
and unimplemented features.  Most applications still do not work
correctly.

Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
forget to include a ChangeLog entry.

WHAT'S NEW with Wine-990923: (see ChangeLog for details)
	- DIB optimizations.
	- Multimedia and OLE DLLs reorganization.
	- Many fixes in font mapping.
	- Clipboard support improvements.
	- Lots of bug fixes.

>How-To-Repeat:

	n/a

>Fix:

Changed files:
Makefile, files/md5, patches/patch-ad, pkg/PLIST

New files:
files/README.patch, files/patch-3.3-sys-ldtshare,
files/patch-3.3-sys-sigtrap,
patches/patch-ba, patches/patch-bd, patches/patch-bf,
patches/patch-bg, patches/patch-bi, patches/patch-bj,
patches/patch-cb, patches/patch-ce, patches/patch-ch,
patches/patch-cj, patches/patch-ck, patches/patch-cl,
pkg/MESSAGE

Removed files:
patches/patch-am, patches/patch-an, patches/patch-aw,
patches/patch-ay

Index: Makefile
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/Makefile,v
retrieving revision 1.73
diff -u -u -r1.73 Makefile
--- Makefile	1999/08/31 06:43:57	1.73
+++ Makefile	1999/09/25 17:20:57
@@ -1,14 +1,14 @@
 # New ports collection makefile for:    wine
-# Version required:     980517
+# Version required:     990923
 # Date created:         Sa   9 Nov 1996 00:52:22 MET
 # Whom:			se
 #
 # $FreeBSD: ports/emulators/wine/Makefile,v 1.73 1999/08/31 06:43:57 mharo Exp $
 #
 
-DATE=		990426
+DATE=		990923
 DISTNAME=	Wine-${DATE}
-PKGNAME=	wine-99.04.26
+PKGNAME=	wine-99.09.23
 CATEGORIES=	emulators
 MASTER_SITES=	${MASTER_SITE_SUNSITE}
 MASTER_SITE_SUBDIR=	ALPHA/wine/development
@@ -22,6 +22,8 @@
 MAN1=		wine.1
 ONLY_FOR_ARCHS=	i386
 
+CFLAGS+=	-g
+
 pre-configure:
 	@${ECHO} "WINE_INI_GLOBAL \"${PREFIX}/etc/wine.conf\"" \
 		>> ${WRKSRC}/autoconf.h
@@ -34,7 +36,14 @@
 	-@${MKDIR} ${PREFIX}/etc 2>/dev/null
 	[ -f ${PREFIX}/etc/wine.conf ] \
 		|| ${CP} ${WRKSRC}/wine.ini ${PREFIX}/etc/wine.conf
-	${CP} ${WRKSRC}/wine.sym ${PREFIX}/etc
-	${CP} ${WRKSRC}/documentation/wine.man ${PREFIX}/man/man1/wine.1
+	${INSTALL_DATA} ${WRKSRC}/wine.sym ${PREFIX}/etc
+	${INSTALL_DATA} ${WRKSRC}/documentation/wine.man ${PREFIX}/man/man1/wine.1
+	-@${MKDIR} ${PREFIX}/share/wine 2>/dev/null
+	${INSTALL_DATA} ${FILESDIR}/README.patch \
+		${FILESDIR}/patch-3.3-sys-ldtshare \
+		${FILESDIR}/patch-3.3-sys-sigtrap \
+		${PREFIX}/share/wine
+	${ECHO}
+	@${SED} s+/usr/local+${PREFIX}+g <${PKGMESSAGE}
 
 .include <bsd.port.mk>
Index: files/md5
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/files/md5,v
retrieving revision 1.46
diff -u -u -r1.46 md5
--- md5	1999/05/03 22:36:11	1.46
+++ md5	1999/09/25 01:31:15
@@ -1 +1 @@
-MD5 (Wine-990426.tar.gz) = ddc5561393b7fedb02b933889658eb7f
+MD5 (Wine-990923.tar.gz) = 14f7e147463730e21e4b43f99ed14c40
Index: patches/patch-ad
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/patches/patch-ad,v
retrieving revision 1.5
diff -u -u -r1.5 patch-ad
--- patch-ad	1996/08/13 16:35:27	1.5
+++ patch-ad	1999/09/08 22:06:47
@@ -1,40 +1,27 @@
-*** wine.ini.orig	Wed Jul 17 22:00:24 1996
---- wine.ini	Mon Aug 12 19:51:38 1996
-***************
-*** 35,39 ****
-  Temp=e:\
-  Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
-! SymbolTableFile=./wine.sym
-  
-  [options]
---- 35,39 ----
-  Temp=e:\
-  Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
-! SymbolTableFile=/usr/local/etc/wine.sym
-  
-  [options]
-***************
-*** 54,64 ****
-  
-  [serialports]
-! Com1=/dev/cua0
-! Com2=/dev/cua1
-  Com3=/dev/modem,38400
-  Com4=/dev/modem
-  
-  [parallelports]
-! Lpt1=/dev/lp0
-  
-  [spy]
---- 54,64 ----
-  
-  [serialports]
-! Com1=/dev/ttyd0
-! Com2=/dev/ttyd1
-  Com3=/dev/modem,38400
-  Com4=/dev/modem
-  
-  [parallelports]
-! Lpt1=/dev/lpt0
-  
-  [spy]
+Index: wine.ini
+@@ -52,7 +52,7 @@
+ System=c:\windows\system
+ Temp=e:\
+ Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
+-SymbolTableFile=./wine.sym
++SymbolTableFile=/usr/local/etc/wine.sym
+ 
+ # <wineconf>
+ 
+@@ -105,13 +105,13 @@
+ Default = -adobe-times-
+ 
+ [serialports]
+-Com1=/dev/ttyS0
+-Com2=/dev/ttyS1
++Com1=/dev/ttyd0
++Com2=/dev/ttyd1
+ Com3=/dev/modem,38400
+ Com4=/dev/modem
+ 
+ [parallelports]
+-Lpt1=/dev/lp0
++Lpt1=/dev/lpt0
+ 
+ [spooler]
+ LPT1:=|lpr
Index: pkg/PLIST
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/pkg/PLIST,v
retrieving revision 1.3
diff -u -u -r1.3 PLIST
--- PLIST	1998/08/17 09:43:16	1.3
+++ PLIST	1999/09/09 20:58:35
@@ -1,3 +1,6 @@
 bin/wine
 etc/wine.conf
 etc/wine.sym
+share/wine/README.patch
+share/wine/patch-3.3-sys-ldtshare
+share/wine/patch-3.3-sys-sigtrap
--- /dev/null	Sat Sep 25 22:11:00 1999
+++ files/README.patch	Sat Sep 25 22:08:04 1999
@@ -0,0 +1,40 @@
+Here are two patches for FreeBSD's kernel that are necessary for wine
+(well not strictly _necessary_ but without them parts of it won't work.)
+They unfortunately didn't make it into the base distribution in time
+for the 3.3 release code freeze...
+
+patch-3.3-sys-ldtshare:
+make kernel threads (rfork(), which wine uses) share one LDT instead of
+each having its own.  this fixes the same problem that wine also had on
+linux kernels before 2.2.
+
+patch-3.3-sys-sigtrap:
+stop wine's SIGTRAP handler from being called in the sigreturn syscall,
+causing problems for wine's internal debugger.  (it would still
+correctly show a crash backtrace but all commands that use single-
+stepping failed.)
+
+Apply as follows:
+
+	(cd /usr/src/sys && patch ) <patch-3.3-sys-ldtshare
+	(cd /usr/src/sys && patch ) <patch-3.3-sys-sigtrap
+
+then build a new kernel. (don't forget to include the options USER_LDT,
+SYSVSHM, SYSVSEM, and SYSVMSG, wine needs these.)
+
+-current users:
+someone of you :) needs to implement a runtime check in wine for the
+FreeBSD version and based on that use/set the sc_gs and sc_fs values
+in the sigcontext struct in signal handlers for versions >= 4.0.
+(see the `wine signal handlers lose %fs on FreeBSD' thread on the
+wine-devel list for details, can be read at
+http://www.integrita.com/cgi-local/lwgate.pl/WINE-DEVEL/archives/1999-09/Subject/article-15.html
+at least i ended up there when i searched it today.  yes you could also
+simply define FS_sig and GS_sig in wine's include/sig_context.h and be
+done with it but the resulting wine would only work on 4.0 and
+Alexandre (wine maintainer) didn't like that idea...)
+
+A LDT patch for -current is at http://www.freebsd.org/~luoqi
+(not included since i don't know if it still applies), the sigtrap
+patch looks like it could also apply to -current but i haven't tried.
+(and if not, i guess a similar fix will be committed soon anyway.)
--- /dev/null	Sat Sep 25 20:08:17 1999
+++ files/patch-3.3-sys-ldtshare	Thu Sep  9 19:28:21 1999
@@ -0,0 +1,656 @@
+Index: alpha/alpha/vm_machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/alpha/alpha/vm_machdep.c,v
+retrieving revision 1.7.2.2
+diff -u -u -r1.7.2.2 vm_machdep.c
+--- vm_machdep.c	1999/08/29 15:56:38	1.7.2.2
++++ vm_machdep.c	1999/09/04 20:32:00
+@@ -114,11 +114,15 @@
+  * ready to run and return to user mode.
+  */
+ void
+-cpu_fork(p1, p2)
++cpu_fork(p1, p2, flags)
+ 	register struct proc *p1, *p2;
++	int flags;
+ {
+ 	struct user *up = p2->p_addr;
+ 	int i;
++
++	if ((flags & RFPROC) == 0)
++		return;
+ 
+ 	p2->p_md.md_tf = p1->p_md.md_tf;
+ 	p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
+Index: i386/i386/genassym.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/genassym.c,v
+retrieving revision 1.62.2.2
+diff -u -u -r1.62.2.2 genassym.c
+--- genassym.c	1999/08/29 16:05:40	1.62.2.2
++++ genassym.c	1999/09/04 20:35:59
+@@ -125,7 +125,9 @@
+ 	printf("#define\tPCB_EBX %#x\n", OS(pcb, pcb_ebx));
+ 	printf("#define\tPCB_EIP %#x\n", OS(pcb, pcb_eip));
+ 	printf("#define\tTSS_ESP0 %#x\n", OS(i386tss, tss_esp0));
++#ifdef USER_LDT
+ 	printf("#define\tPCB_USERLDT %#x\n", OS(pcb, pcb_ldt));
++#endif
+ 	printf("#define\tPCB_FS %#x\n", OS(pcb, pcb_fs));
+ 	printf("#define\tPCB_GS %#x\n", OS(pcb, pcb_gs));
+ #ifdef VM86
+Index: i386/i386/machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/machdep.c,v
+retrieving revision 1.322.2.8
+diff -u -u -r1.322.2.8 machdep.c
+--- machdep.c	1999/08/29 16:05:43	1.322.2.8
++++ machdep.c	1999/09/04 20:36:02
+@@ -817,15 +827,7 @@
+ 
+ #ifdef USER_LDT
+ 	/* was i386_user_cleanup() in NetBSD */
+-	if (pcb->pcb_ldt) {
+-		if (pcb == curpcb) {
+-			lldt(_default_ldt);
+-			currentldt = _default_ldt;
+-		}
+-		kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+-			pcb->pcb_ldt_len * sizeof(union descriptor));
+-		pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
+- 	}
++	user_ldt_free(pcb);
+ #endif
+   
+ 	bzero((char *)regs, sizeof(struct trapframe));
+Index: i386/i386/sys_machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/sys_machdep.c,v
+retrieving revision 1.38.2.1
+diff -u -u -r1.38.2.1 sys_machdep.c
+--- sys_machdep.c	1999/08/29 16:05:55	1.38.2.1
++++ sys_machdep.c	1999/09/04 20:36:09
+@@ -41,6 +41,7 @@
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/sysproto.h>
++#include <sys/malloc.h>
+ #include <sys/proc.h>
+ 
+ #include <vm/vm.h>
+@@ -65,7 +66,6 @@
+ 
+ 
+ #ifdef USER_LDT
+-void set_user_ldt	__P((struct pcb *pcb));
+ static int i386_get_ldt	__P((struct proc *, char *));
+ static int i386_set_ldt	__P((struct proc *, char *));
+ #endif
+@@ -259,13 +259,72 @@
+ void
+ set_user_ldt(struct pcb *pcb)
+ {
+-	gdt_segs[GUSERLDT_SEL].ssd_base = (unsigned)pcb->pcb_ldt;
+-	gdt_segs[GUSERLDT_SEL].ssd_limit = (pcb->pcb_ldt_len * sizeof(union descriptor)) - 1;
+-	ssdtosd(&gdt_segs[GUSERLDT_SEL], &gdt[GUSERLDT_SEL].sd);
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
++#ifdef SMP
++	gdt[cpuid * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
++#else
++	gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
++#endif
+ 	lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
+ 	currentldt = GSEL(GUSERLDT_SEL, SEL_KPL);
+ }
+ 
++struct pcb_ldt *
++user_ldt_alloc(struct pcb *pcb, int len)
++{
++	struct pcb_ldt *pcb_ldt, *new_ldt;
++
++	MALLOC(new_ldt, struct pcb_ldt *, sizeof(struct pcb_ldt),
++		M_SUBPROC, M_WAITOK);
++	if (new_ldt == NULL)
++		return NULL;
++
++	new_ldt->ldt_len = len = NEW_MAX_LD(len);
++	new_ldt->ldt_base = (caddr_t)kmem_alloc(kernel_map,
++		len * sizeof(union descriptor));
++	if (new_ldt->ldt_base == NULL) {
++		FREE(new_ldt, M_SUBPROC);
++		return NULL;
++	}
++	new_ldt->ldt_refcnt = 1;
++	new_ldt->ldt_active = 0;
++
++	gdt_segs[GUSERLDT_SEL].ssd_base = (unsigned)new_ldt->ldt_base;
++	gdt_segs[GUSERLDT_SEL].ssd_limit = len * sizeof(union descriptor) - 1;
++	ssdtosd(&gdt_segs[GUSERLDT_SEL], &new_ldt->ldt_sd);
++
++	if ((pcb_ldt = pcb->pcb_ldt)) {
++		if (len > pcb_ldt->ldt_len)
++			len = pcb_ldt->ldt_len;
++		bcopy(pcb_ldt->ldt_base, new_ldt->ldt_base,
++			len * sizeof(union descriptor));
++	} else {
++		bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
++	}
++	return new_ldt;
++}
++
++void
++user_ldt_free(struct pcb *pcb)
++{
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
++
++	if (pcb_ldt == NULL)
++		return;
++
++	if (pcb == curpcb) {
++		lldt(_default_ldt);
++		currentldt = _default_ldt;
++	}
++
++	if (--pcb_ldt->ldt_refcnt == 0) {
++		kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
++			pcb_ldt->ldt_len * sizeof(union descriptor));
++		FREE(pcb_ldt, M_SUBPROC);
++	}
++	pcb->pcb_ldt = NULL;
++}
++
+ struct i386_get_ldt_args {
+ 	int start;
+ 	union descriptor *desc;
+@@ -279,6 +338,7 @@
+ {
+ 	int error = 0;
+ 	struct pcb *pcb = &p->p_addr->u_pcb;
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+ 	int nldt, num;
+ 	union descriptor *lp;
+ 	int s;
+@@ -299,10 +359,10 @@
+ 
+ 	s = splhigh();
+ 
+-	if (pcb->pcb_ldt) {
+-		nldt = pcb->pcb_ldt_len;
++	if (pcb_ldt) {
++		nldt = pcb_ldt->ldt_len;
+ 		num = min(uap->num, nldt);
+-		lp = &((union descriptor *)(pcb->pcb_ldt))[uap->start];
++		lp = &((union descriptor *)(pcb_ldt->ldt_base))[uap->start];
+ 	} else {
+ 		nldt = sizeof(ldt)/sizeof(ldt[0]);
+ 		num = min(uap->num, nldt);
+@@ -335,6 +395,7 @@
+ 	int error = 0, i, n;
+  	int largest_ld;
+ 	struct pcb *pcb = &p->p_addr->u_pcb;
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+ 	int s;
+ 	struct i386_set_ldt_args ua, *uap;
+ 
+@@ -348,36 +409,37 @@
+ 	    uap->start, uap->num, (void *)uap->desc);
+ #endif
+ 
+- 	/* verify range of descriptors to modify */
+- 	if ((uap->start < 0) || (uap->start >= MAX_LD) || (uap->num < 0) ||
+- 		(uap->num > MAX_LD))
+- 	{
++	/* verify range of descriptors to modify */
++	if ((uap->start < 0) || (uap->start >= MAX_LD) || (uap->num < 0) ||
++		(uap->num > MAX_LD))
++	{
++		return(EINVAL);
++	}
++	largest_ld = uap->start + uap->num - 1;
++	if (largest_ld >= MAX_LD)
+  		return(EINVAL);
+- 	}
+- 	largest_ld = uap->start + uap->num - 1;
+- 	if (largest_ld >= MAX_LD)
+-  		return(EINVAL);
+-  
+-  	/* allocate user ldt */
+- 	if (!pcb->pcb_ldt || (largest_ld >= pcb->pcb_ldt_len)) {
+- 		union descriptor *new_ldt = (union descriptor *)kmem_alloc(
+- 			kernel_map, SIZE_FROM_LARGEST_LD(largest_ld));
+- 		if (new_ldt == NULL) {
+- 			return ENOMEM;
+- 		}
+- 		if (pcb->pcb_ldt) {
+- 			bcopy(pcb->pcb_ldt, new_ldt, pcb->pcb_ldt_len
+- 				* sizeof(union descriptor));
+- 			kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+- 				pcb->pcb_ldt_len * sizeof(union descriptor));
+- 		} else {
+- 			bcopy(ldt, new_ldt, sizeof(ldt));
+- 		}
+-  		pcb->pcb_ldt = (caddr_t)new_ldt;
+- 		pcb->pcb_ldt_len = NEW_MAX_LD(largest_ld);
+- 		if (pcb == curpcb)
+- 		    set_user_ldt(pcb);
+-  	}
++ 
++ 	/* allocate user ldt */
++	if (!pcb_ldt || (largest_ld >= pcb_ldt->ldt_len)) {
++		struct pcb_ldt *new_ldt = user_ldt_alloc(pcb, largest_ld);
++		if (new_ldt == NULL) {
++			return ENOMEM;
++		}
++	        if (pcb_ldt) {
++	                pcb_ldt->ldt_sd = new_ldt->ldt_sd;
++#ifdef SMP
++		/* signal other cpus to reload ldt */
++#endif
++			kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
++				pcb_ldt->ldt_len * sizeof(union descriptor));
++			pcb_ldt->ldt_base = new_ldt->ldt_base;
++			pcb_ldt->ldt_len = new_ldt->ldt_len;
++			FREE(new_ldt, M_SUBPROC);
++	        } else
++			pcb->pcb_ldt = pcb_ldt = new_ldt;
++		if (pcb == curpcb)
++			set_user_ldt(pcb);
++	}
+ 
+ 	/* Check descriptors for access violations */
+ 	for (i = 0, n = uap->start; i < uap->num; i++, n++) {
+@@ -388,70 +450,70 @@
+ 			return(error);
+ 
+ 		switch (desc.sd.sd_type) {
+- 		case SDT_SYSNULL:	/* system null */ 
+- 			desc.sd.sd_p = 0;
+-  			break;
+- 		case SDT_SYS286TSS: /* system 286 TSS available */
+- 		case SDT_SYSLDT:    /* system local descriptor table */
+- 		case SDT_SYS286BSY: /* system 286 TSS busy */
+- 		case SDT_SYSTASKGT: /* system task gate */
+- 		case SDT_SYS286IGT: /* system 286 interrupt gate */
+- 		case SDT_SYS286TGT: /* system 286 trap gate */
+- 		case SDT_SYSNULL2:  /* undefined by Intel */ 
+- 		case SDT_SYS386TSS: /* system 386 TSS available */
+- 		case SDT_SYSNULL3:  /* undefined by Intel */
+- 		case SDT_SYS386BSY: /* system 386 TSS busy */
+- 		case SDT_SYSNULL4:  /* undefined by Intel */ 
+- 		case SDT_SYS386IGT: /* system 386 interrupt gate */
+- 		case SDT_SYS386TGT: /* system 386 trap gate */
+- 		case SDT_SYS286CGT: /* system 286 call gate */ 
+- 		case SDT_SYS386CGT: /* system 386 call gate */
+- 			/* I can't think of any reason to allow a user proc
+- 			 * to create a segment of these types.  They are
+- 			 * for OS use only.
+- 			 */
+-     	    	    	return EACCES;
+- 
+- 		/* memory segment types */
+- 		case SDT_MEMEC:   /* memory execute only conforming */
+- 		case SDT_MEMEAC:  /* memory execute only accessed conforming */
+- 		case SDT_MEMERC:  /* memory execute read conforming */
+- 		case SDT_MEMERAC: /* memory execute read accessed conforming */
+-                         /* Must be "present" if executable and conforming. */
+-                         if (desc.sd.sd_p == 0)
+-                                 return (EACCES);
++		case SDT_SYSNULL:	/* system null */ 
++			desc.sd.sd_p = 0;
+  			break;
+- 		case SDT_MEMRO:   /* memory read only */
+- 		case SDT_MEMROA:  /* memory read only accessed */
+- 		case SDT_MEMRW:   /* memory read write */
+- 		case SDT_MEMRWA:  /* memory read write accessed */
+- 		case SDT_MEMROD:  /* memory read only expand dwn limit */
+- 		case SDT_MEMRODA: /* memory read only expand dwn lim accessed */
+- 		case SDT_MEMRWD:  /* memory read write expand dwn limit */  
+- 		case SDT_MEMRWDA: /* memory read write expand dwn lim acessed */
+- 		case SDT_MEME:    /* memory execute only */ 
+- 		case SDT_MEMEA:   /* memory execute only accessed */
+- 		case SDT_MEMER:   /* memory execute read */
+- 		case SDT_MEMERA:  /* memory execute read accessed */
++		case SDT_SYS286TSS: /* system 286 TSS available */
++		case SDT_SYSLDT:    /* system local descriptor table */
++		case SDT_SYS286BSY: /* system 286 TSS busy */
++		case SDT_SYSTASKGT: /* system task gate */
++		case SDT_SYS286IGT: /* system 286 interrupt gate */
++		case SDT_SYS286TGT: /* system 286 trap gate */
++		case SDT_SYSNULL2:  /* undefined by Intel */ 
++		case SDT_SYS386TSS: /* system 386 TSS available */
++		case SDT_SYSNULL3:  /* undefined by Intel */
++		case SDT_SYS386BSY: /* system 386 TSS busy */
++		case SDT_SYSNULL4:  /* undefined by Intel */ 
++		case SDT_SYS386IGT: /* system 386 interrupt gate */
++		case SDT_SYS386TGT: /* system 386 trap gate */
++		case SDT_SYS286CGT: /* system 286 call gate */ 
++		case SDT_SYS386CGT: /* system 386 call gate */
++			/* I can't think of any reason to allow a user proc
++			 * to create a segment of these types.  They are
++			 * for OS use only.
++			 */
++    	    	    	return EACCES;
++
++		/* memory segment types */
++		case SDT_MEMEC:   /* memory execute only conforming */
++		case SDT_MEMEAC:  /* memory execute only accessed conforming */
++		case SDT_MEMERC:  /* memory execute read conforming */
++		case SDT_MEMERAC: /* memory execute read accessed conforming */
++			/* Must be "present" if executable and conforming. */
++			if (desc.sd.sd_p == 0)
++				return (EACCES);
++			break;
++		case SDT_MEMRO:   /* memory read only */
++		case SDT_MEMROA:  /* memory read only accessed */
++		case SDT_MEMRW:   /* memory read write */
++		case SDT_MEMRWA:  /* memory read write accessed */
++		case SDT_MEMROD:  /* memory read only expand dwn limit */
++		case SDT_MEMRODA: /* memory read only expand dwn lim accessed */
++		case SDT_MEMRWD:  /* memory read write expand dwn limit */  
++		case SDT_MEMRWDA: /* memory read write expand dwn lim acessed */
++		case SDT_MEME:    /* memory execute only */ 
++		case SDT_MEMEA:   /* memory execute only accessed */
++		case SDT_MEMER:   /* memory execute read */
++		case SDT_MEMERA:  /* memory execute read accessed */
+ 			break;
+ 		default:
+ 			return(EINVAL);
+ 			/*NOTREACHED*/
+ 		}
+  
+- 		/* Only user (ring-3) descriptors may be present. */
+- 		if ((desc.sd.sd_p != 0) && (desc.sd.sd_dpl != SEL_UPL))
+- 			return (EACCES);
++		/* Only user (ring-3) descriptors may be present. */
++		if ((desc.sd.sd_p != 0) && (desc.sd.sd_dpl != SEL_UPL))
++			return (EACCES);
+ 	}
+ 
+ 	s = splhigh();
+ 
+ 	/* Fill in range */
+- 	error = copyin(uap->desc, 
+- 		 &((union descriptor *)(pcb->pcb_ldt))[uap->start],
+- 		uap->num * sizeof(union descriptor));
+- 	if (!error)
+-  		p->p_retval[0] = uap->start;
++	error = copyin(uap->desc, 
++		 &((union descriptor *)(pcb_ldt->ldt_base))[uap->start],
++		uap->num * sizeof(union descriptor));
++	if (!error)
++ 		p->p_retval[0] = uap->start;
+ 
+ 	splx(s);
+ 	return(error);
+Index: i386/i386/vm_machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/vm_machdep.c,v
+retrieving revision 1.115.2.1
+diff -u -u -r1.115.2.1 vm_machdep.c
+--- vm_machdep.c	1999/08/29 16:05:58	1.115.2.1
++++ vm_machdep.c	1999/09/04 20:36:15
+@@ -57,6 +57,7 @@
+ #include <sys/vmmeter.h>
+ #include <sys/kernel.h>
+ #include <sys/sysctl.h>
++#include <sys/unistd.h>
+ 
+ #include <machine/clock.h>
+ #include <machine/cpu.h>
+@@ -68,6 +69,9 @@
+ #include <machine/pcb_ext.h>
+ #include <machine/vm86.h>
+ #endif
++#ifdef USER_LDT
++#include <machine/pcb_ext.h>
++#endif
+ 
+ #include <vm/vm.h>
+ #include <vm/vm_param.h>
+@@ -113,10 +117,29 @@
+  * ready to run and return to user mode.
+  */
+ void
+-cpu_fork(p1, p2)
++cpu_fork(p1, p2, flags)
+ 	register struct proc *p1, *p2;
++	int flags;
+ {
+-	struct pcb *pcb2 = &p2->p_addr->u_pcb;
++	struct pcb *pcb2;
++ 
++	if ((flags & RFPROC) == 0) {
++#ifdef USER_LDT
++		if ((flags & RFMEM) == 0) {
++			/* unshare user LDT */
++			struct pcb *pcb1 = &p1->p_addr->u_pcb;
++			struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
++			if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
++				pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
++				user_ldt_free(pcb1);
++				pcb1->pcb_ldt = pcb_ldt;
++				if (pcb1 == curpcb)
++					set_user_ldt(pcb1);
++			}
++		}
++#endif
++	        return;
++	}
+ 
+ #if NNPX > 0
+ 	/* Ensure that p1's pcb is up to date. */
+@@ -126,6 +149,7 @@
+ 
+ 	/* Copy p1's pcb. */
+ 	p2->p_addr->u_pcb = p1->p_addr->u_pcb;
++	pcb2 = &p2->p_addr->u_pcb;
+ 
+ 	/*
+ 	 * Create a new fresh stack for the new process.
+@@ -153,7 +177,6 @@
+ 	pcb2->pcb_eip = (int)fork_trampoline;
+ 	/*
+ 	 * pcb2->pcb_ldt:	duplicated below, if necessary.
+-	 * pcb2->pcb_ldt_len:	cloned above.
+ 	 * pcb2->pcb_savefpu:	cloned above.
+ 	 * pcb2->pcb_flags:	cloned above (always 0 here?).
+ 	 * pcb2->pcb_onfault:	cloned above (always NULL here?).
+@@ -172,12 +195,12 @@
+ #ifdef USER_LDT
+         /* Copy the LDT, if necessary. */
+         if (pcb2->pcb_ldt != 0) {
+-                union descriptor *new_ldt;
+-                size_t len = pcb2->pcb_ldt_len * sizeof(union descriptor);
+-
+-                new_ldt = (union descriptor *)kmem_alloc(kernel_map, len);
+-                bcopy(pcb2->pcb_ldt, new_ldt, len);
+-                pcb2->pcb_ldt = (caddr_t)new_ldt;
++		if (flags & RFMEM) {
++			pcb2->pcb_ldt->ldt_refcnt++;
++		} else {
++			pcb2->pcb_ldt = user_ldt_alloc(pcb2,
++				pcb2->pcb_ldt->ldt_len);
++		}
+         }
+ #endif
+ 
+@@ -235,15 +258,7 @@
+ 	}
+ #endif
+ #ifdef USER_LDT
+-	if (pcb->pcb_ldt != 0) {
+-		if (pcb == curpcb) {
+-			lldt(_default_ldt);
+-			currentldt = _default_ldt;
+-		}
+-		kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+-			pcb->pcb_ldt_len * sizeof(union descriptor));
+-		pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
+-	}
++	user_ldt_free(pcb);
+ #endif
+ 	cnt.v_swtch++;
+ 	cpu_switch(p);
+Index: i386/include/pcb.h
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/include/pcb.h,v
+retrieving revision 1.26.2.1
+diff -u -u -r1.26.2.1 pcb.h
+--- pcb.h	1999/08/29 16:06:43	1.26.2.1
++++ pcb.h	1999/09/04 20:36:29
+@@ -53,8 +53,11 @@
+ 	int	pcb_esp;
+ 	int	pcb_ebx;
+ 	int	pcb_eip;
+-	caddr_t	pcb_ldt;		/* per process (user) LDT */
+-	int	pcb_ldt_len;		/* number of LDT entries */
++#ifdef USER_LDT
++	struct  pcb_ldt *pcb_ldt;       /* per process (user) LDT */
++#else
++	struct  pcb_ldt *pcb_ldt_dontuse;
++#endif
+ 	struct	save87	pcb_savefpu;	/* floating point state for 287/387 */
+ 	u_char	pcb_flags;
+ #define	FP_SOFTFP	0x01	/* process using software fltng pnt emulator */
+@@ -71,7 +74,7 @@
+ #else
+ 	struct	pcb_ext	*pcb_ext_dontuse;
+ #endif
+-	u_long	__pcb_spare[1];	/* adjust to avoid core dump size changes */
++	u_long	__pcb_spare[2];	/* adjust to avoid core dump size changes */
+ };
+ 
+ /*
+Index: i386/include/pcb_ext.h
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/include/pcb_ext.h,v
+retrieving revision 1.1.2.1
+diff -u -u -r1.1.2.1 pcb_ext.h
+--- pcb_ext.h	1999/08/29 16:06:44	1.1.2.1
++++ pcb_ext.h	1999/09/04 20:36:29
+@@ -43,4 +43,22 @@
+ 	struct	vm86_kernel ext_vm86;	/* vm86 area */
+ };
+ 
++struct pcb_ldt {
++	caddr_t ldt_base;
++	int     ldt_len;
++	int     ldt_refcnt;
++	u_long  ldt_active;
++	struct  segment_descriptor ldt_sd;
++};
++
++#ifdef KERNEL
++
++#ifdef USER_LDT
++void set_user_ldt __P((struct pcb *));
++struct pcb_ldt *user_ldt_alloc __P((struct pcb *, int));
++void user_ldt_free __P((struct pcb *));
++#endif
++
++#endif
++
+ #endif /* _I386_PCB_EXT_H_ */
+Index: kern/kern_fork.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/kern/kern_fork.c,v
+retrieving revision 1.54.2.4
+diff -u -u -r1.54.2.4 kern_fork.c
+--- kern_fork.c	1999/08/29 16:25:59	1.54.2.4
++++ kern_fork.c	1999/09/04 20:38:06
+@@ -162,16 +162,7 @@
+ 	 */
+ 	if ((flags & RFPROC) == 0) {
+ 
+-		/*
+-		 * Divorce the memory, if it is shared, essentially
+-		 * this changes shared memory amongst threads, into
+-		 * COW locally.
+-		 */
+-		if ((flags & RFMEM) == 0) {
+-			if (p1->p_vmspace->vm_refcnt > 1) {
+-				vmspace_unshare(p1);
+-			}
+-		}
++		vm_fork(p1, 0, flags);
+ 
+ 		/*
+ 		 * Close all file descriptors.
+Index: pc98/i386/machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/pc98/i386/machdep.c,v
+retrieving revision 1.105.2.7
+diff -u -u -r1.105.2.7 machdep.c
+--- machdep.c	1999/08/29 16:31:03	1.105.2.7
++++ machdep.c	1999/09/04 20:41:41
+@@ -830,15 +830,7 @@
+ 
+ #ifdef USER_LDT
+ 	/* was i386_user_cleanup() in NetBSD */
+-	if (pcb->pcb_ldt) {
+-		if (pcb == curpcb) {
+-			lldt(_default_ldt);
+-			currentldt = _default_ldt;
+-		}
+-		kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+-			pcb->pcb_ldt_len * sizeof(union descriptor));
+-		pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
+- 	}
++	user_ldt_free(pcb);
+ #endif
+   
+ 	bzero((char *)regs, sizeof(struct trapframe));
+Index: sys/proc.h
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/sys/proc.h,v
+retrieving revision 1.66.2.5
+diff -u -u -r1.66.2.5 proc.h
+--- proc.h	1999/08/29 16:32:36	1.66.2.5
++++ proc.h	1999/09/04 20:42:43
+@@ -375,7 +375,7 @@
+ 
+ void	cpu_exit __P((struct proc *)) __dead2;
+ void	exit1 __P((struct proc *, int)) __dead2;
+-void	cpu_fork __P((struct proc *, struct proc *));
++void	cpu_fork __P((struct proc *, struct proc *, int));
+ int	fork1 __P((struct proc *, int));
+ int	trace_req __P((struct proc *));
+ void	cpu_wait __P((struct proc *));
+Index: vm/vm_glue.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/vm/vm_glue.c,v
+retrieving revision 1.80.2.3
+diff -u -u -r1.80.2.3 vm_glue.c
+--- vm_glue.c	1999/08/29 16:33:31	1.80.2.3
++++ vm_glue.c	1999/09/04 20:43:01
+@@ -208,6 +208,21 @@
+ {
+ 	register struct user *up;
+ 
++	if ((flags & RFPROC) == 0) {
++		/*
++		 * Divorce the memory, if it is shared, essentially
++		 * this changes shared memory amongst threads, into
++		 * COW locally.
++		 */
++		if ((flags & RFMEM) == 0) {
++			if (p1->p_vmspace->vm_refcnt > 1) {
++				vmspace_unshare(p1);
++			}
++		}
++		cpu_fork(p1, p2, flags);
++		return;
++	}
++
+ 	if (flags & RFMEM) {
+ 		p2->p_vmspace = p1->p_vmspace;
+ 		p1->p_vmspace->vm_refcnt++;
+@@ -259,7 +274,7 @@
+ 	 * cpu_fork will copy and update the pcb, set up the kernel stack,
+ 	 * and make the child ready to run.
+ 	 */
+-	cpu_fork(p1, p2);
++	cpu_fork(p1, p2, flags);
+ }
+ 
+ /*
--- /dev/null	Sat Sep 25 20:08:17 1999
+++ files/patch-3.3-sys-sigtrap	Fri Sep 10 16:44:29 1999
@@ -0,0 +1,30 @@
+Index: i386/i386/trap.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/trap.c,v
+retrieving revision 1.133.2.1
+diff -u -u -r1.133.2.1 trap.c
+--- trap.c	1999/08/29 16:05:56	1.133.2.1
++++ trap.c	1999/09/10 14:42:21
+@@ -1041,6 +1084,7 @@
+ 	int error;
+ 	int args[8];
+ 	u_int code;
++	int tracedsyscall = ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM));
+ 
+ #ifdef DIAGNOSTIC
+ 	if (ISPL(frame.tf_cs) != SEL_UPL)
+@@ -1135,10 +1179,12 @@
+ 		break;
+ 	}
+ 
+-	if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM)) {
++	if (tracedsyscall) {
+ 		/* Traced syscall. */
+ 		frame.tf_eflags &= ~PSL_T;
+-		trapsignal(p, SIGTRAP, 0);
++		/* tell the signal handler this is a trace trap */
++		frame.tf_trapno = T_TRCTRAP;
++		trapsignal(p, SIGTRAP, T_TRCTRAP);
+ 	}
+ 
+ 	userret(p, &frame, sticks);
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-ba	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,25 @@
+Index: Make.rules.in
+===================================================================
+RCS file: /home/wine/wine/Make.rules.in,v
+retrieving revision 1.17
+diff -u -u -r1.17 Make.rules.in
+--- Make.rules.in	1999/08/15 12:45:53	1.17
++++ Make.rules.in	1999/09/24 23:39:10
+@@ -21,7 +21,7 @@
+ CC        = @CC@
+ CPP       = @CPP@
+ CFLAGS    = @CFLAGS@
+-OPTIONS   = @OPTIONS@ -D_REENTRANT
++OPTIONS   = @OPTIONS@ -D_REENTRANT -D_THREAD_SAFE
+ X_CFLAGS  = @X_CFLAGS@
+ X_LIBS    = @X_LIBS@
+ XLIB      = @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
+@@ -81,7 +81,7 @@
+ 
+ # Implicit rules
+ 
+-.SUFFIXES:
++#.SUFFIXES:
+ .SUFFIXES: .rc .res .spec .spec.c .spec.o .glue.c $(SUFFIXES)
+ 
+ .c.o:
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-bd	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,42 @@
+Index: dlls/ntdll/exception.c
+===================================================================
+RCS file: /home/wine/wine/dlls/ntdll/exception.c,v
+retrieving revision 1.12
+diff -u -u -r1.12 exception.c
+--- dlls/ntdll/exception.c	1999/09/22 15:25:45	1.12
++++ dlls/ntdll/exception.c	1999/09/24 23:39:25
+@@ -31,6 +31,34 @@
+ # define GET_IP(context) ((LPVOID)0)
+ #endif  /* __i386__ */
+ 
++#ifdef __FreeBSD__
++/* translate BSD's sigcontext sc_trapno for TRAP_sig */
++int xlatebsdtrapno(int t)
++{
++    switch (t)
++    {
++	case T_PRIVINFLT: return 6;
++	case T_BPTFLT:	return 3;
++	case T_ARITHTRAP: return 16;
++	case T_PROTFLT:	return 13;
++	case T_TRCTRAP:	return 1;
++	case T_PAGEFLT:	return 14;
++	case T_ALIGNFLT: return 17;
++	case T_DIVIDE:	return 0;
++	case T_NMI:	return 2;
++	case T_OFLOW:	return 4;
++	case T_BOUND:	return 5;
++	case T_DNA:	return 7;
++	case T_FPOPFLT:	return 9;
++	case T_TSSFLT:	return 10;
++	case T_SEGNPFLT: return 11;
++	case T_STKFLT:	return 12;
++	case T_RESERVED: return 15;
++	default:	return 18;
++    }
++}
++#endif
++
+ /* Default hook for built-in debugger */
+ static DWORD default_hook( EXCEPTION_RECORD *rec, CONTEXT *ctx, BOOL first )
+ {
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-bf	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,16 @@
+Index: include/sig_context.h
+===================================================================
+RCS file: /home/wine/wine/include/sig_context.h,v
+retrieving revision 1.15
+diff -u -u -r1.15 sig_context.h
+--- include/sig_context.h	1999/09/05 16:26:12	1.15
++++ include/sig_context.h	1999/09/24 23:39:26
+@@ -171,6 +171,8 @@
+ #define EFL_sig(context)     ((context)->sc_efl)
+ /* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge  */
+ #define CR2_sig(context)     ((context)->sc_err)
++int xlatebsdtrapno(int t);
++#define TRAP_sig(context)    ((long)xlatebsdtrapno((context)->sc_trapno))
+ #endif                      
+ 
+ 
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-bg	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,48 @@
+Index: loader/signal.c
+===================================================================
+RCS file: /home/wine/wine/loader/signal.c,v
+retrieving revision 1.16
+diff -u -u -r1.16 signal.c
+--- loader/signal.c	1999/08/01 14:54:16	1.16
++++ loader/signal.c	1999/09/24 23:39:26
+@@ -84,11 +84,7 @@
+ }
+ #endif /* linux && __i386__ */
+ 
+-/* Signal stack */
+ 
+-static char SIGNAL_Stack[16384];
+-
+-
+ /**********************************************************************
+  *		SIGNAL_SetHandler
+  */
+@@ -98,6 +94,9 @@
+ 
+ #if defined(linux) && defined(__i386__)
+ 
++    /* Signal stack */
++    static char SIGNAL_Stack[16384];
++
+     struct kernel_sigaction sig_act;
+     sig_act.sa_handler = func;
+     sig_act.sa_flags   = SA_RESTART | SA_NOMASK;
+@@ -140,18 +139,6 @@
+  */
+ BOOL SIGNAL_Init(void)
+ {
+-#ifdef HAVE_WORKING_SIGALTSTACK
+-    struct sigaltstack ss;
+-    ss.ss_sp    = SIGNAL_Stack;
+-    ss.ss_size  = sizeof(SIGNAL_Stack);
+-    ss.ss_flags = 0;
+-    if (sigaltstack(&ss, NULL) < 0)
+-    {
+-        perror("sigaltstack");
+-	/* fall through on error and try it differently */
+-    }
+-#endif  /* HAVE_SIGALTSTACK */
+-    
+     /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead  */
+     signal (SIGPIPE, SIG_IGN);
+     /* automatic child reaping to avoid zombies */
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-bi	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,35 @@
+Index: scheduler/sysdeps.c
+===================================================================
+RCS file: /home/wine/wine/scheduler/sysdeps.c,v
+retrieving revision 1.16
+diff -u -u -r1.16 sysdeps.c
+--- scheduler/sysdeps.c	1999/09/05 12:32:06	1.16
++++ scheduler/sysdeps.c	1999/09/24 23:39:29
+@@ -112,6 +112,9 @@
+  */
+ void SYSDEPS_SetCurThread( TEB *teb )
+ {
++#ifdef HAVE_WORKING_SIGALTSTACK
++    struct sigaltstack ss;
++#endif  /* HAVE_SIGALTSTACK */
+ #if defined(__i386__)
+     /* On the i386, the current thread is in the %fs register */
+     SET_FS( teb->teb_sel );
+@@ -117,6 +125,17 @@
+     /* On non-i386 Solaris, we use the LWP private pointer */
+     _lwp_setprivate( teb );
+ #endif
++#ifdef HAVE_WORKING_SIGALTSTACK
++    if ((ss.ss_sp = teb->signal_stack)) {
++	ss.ss_size  = SIGNAL_STACK_SIZE;
++	ss.ss_flags = 0;
++	if (sigaltstack(&ss, NULL) < 0)
++	{
++	    perror("SYSDEPS_SetCurThread sigaltstack");
++	    /* fall through on error and try it differently */
++	}
++    }
++#endif  /* HAVE_SIGALTSTACK */
+ 
+     init_done = 1;  /* now we can use threading routines */
+ }
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-bj	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,16 @@
+Index: scheduler/thread.c
+===================================================================
+RCS file: /home/wine/wine/scheduler/thread.c,v
+retrieving revision 1.44
+diff -u -u -r1.44 thread.c
+--- scheduler/thread.c	1999/09/20 18:45:28	1.44
++++ scheduler/thread.c	1999/09/24 23:39:30
+@@ -194,6 +194,8 @@
+ 
+     if (CLIENT_InitThread()) return NULL;
+     if (!THREAD_InitTEB( &initial_teb, 0, TRUE, NULL )) return NULL;
++    /* call this again so it can set the signal stack (allocated by THREAD_InitTEB) */
++    SYSDEPS_SetCurThread( &initial_teb );
+     return &initial_teb;
+ }
+ 
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-cb	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,36 @@
+Index: controls/button.c
+===================================================================
+RCS file: /home/wine/wine/controls/button.c,v
+retrieving revision 1.29
+diff -u -u -r1.29 button.c
+--- controls/button.c	1999/09/13 16:06:17	1.29
++++ controls/button.c	1999/09/24 23:39:12
+@@ -150,11 +150,12 @@
+         SetCapture( hWnd );
+         SetFocus( hWnd );
+         SendMessageA( hWnd, BM_SETSTATE, TRUE, 0 );
++        infoPtr->state |= BUTTON_BTNPRESSED;
+         break;
+ 
+     case WM_LBUTTONUP:
+-	/* FIXME: real windows uses extra flags in the status for this */
+-        if (GetCapture() != hWnd) break;
++        if (!(infoPtr->state & BUTTON_BTNPRESSED)) break;
++        infoPtr->state &= BUTTON_NSTATES;
+         ReleaseCapture();
+         if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
+         SendMessageA( hWnd, BM_SETSTATE, FALSE, 0 );
+@@ -188,6 +189,13 @@
+             SendMessageA( hWnd, BM_SETSTATE, PtInRect(&rect, pt), 0 );
+         }
+         break;
++    
++    case WM_CAPTURECHANGED:
++        if (!(infoPtr->state & BUTTON_BTNPRESSED)) break;
++        infoPtr->state &= BUTTON_NSTATES;
++        if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
++        SendMessageA( hWnd, BM_SETSTATE, FALSE, 0 );
++	break;
+ 
+     case WM_NCHITTEST:
+         if(style == BS_GROUPBOX) return HTTRANSPARENT;
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-ce	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,19 @@
+Index: include/button.h
+===================================================================
+RCS file: /home/wine/wine/include/button.h,v
+retrieving revision 1.4
+diff -u -u -r1.4 button.h
+--- include/button.h	1999/04/15 15:49:36	1.4
++++ include/button.h	1999/09/24 23:39:25
+@@ -26,6 +26,11 @@
+ #define BUTTON_3STATE          0x02
+ #define BUTTON_HIGHLIGHTED     0x04
+ #define BUTTON_HASFOCUS        0x08
++#define BUTTON_NSTATES         0x0F
++  /* undocumented flags */
++#define BUTTON_BTNPRESSED      0x40
++#define BUTTON_UNKNOWN2        0x20
++#define BUTTON_UNKNOWN3        0x10
+ 
+ #define BUTTON_STATE(hwnd)     ((WIN_FindWndPtr(hwnd))->wExtra[0])
+ 
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-ch	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,325 @@
+Index: objects/brush.c
+===================================================================
+RCS file: /home/wine/wine/objects/brush.c,v
+retrieving revision 1.16
+diff -u -u -r1.16 brush.c
+--- objects/brush.c	1999/05/23 10:25:26	1.16
++++ objects/brush.c	1999/09/24 23:39:28
+@@ -14,56 +14,103 @@
+ 
+ 
+ /***********************************************************************
+- *           CreateBrushIndirect16    (GDI.50)
++ *           BRUSH_CopyDIB   (internal - do the Dib creation)
+  */
+-HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
++BOOL BRUSH_CopyDIB( LOGBRUSH * logbrush, BITMAPINFO *info, UINT coloruse)
++{
++    BITMAPINFO *newInfo;
++    INT size;
++
++    logbrush->lbStyle = BS_DIBPATTERN;
++    logbrush->lbColor = coloruse;
++    logbrush->lbHatch = 0;
++
++      /* Make a copy of the bitmap */
++
++    if (info->bmiHeader.biCompression)
++        size = info->bmiHeader.biSizeImage;
++    else
++	size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
++				    info->bmiHeader.biHeight,
++				    info->bmiHeader.biBitCount);
++    size += DIB_BitmapInfoSize( info, coloruse );
++
++    if (!(logbrush->lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
++    {
++	return FALSE;
++    }
++    newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush->lbHatch );
++    memcpy( newInfo, info, size );
++    GlobalUnlock16( (HGLOBAL16)logbrush->lbHatch );
++    return TRUE;
++}
++
++/***********************************************************************
++ *           BRUSH_CreateBrush (internal; called by brush creation functions)
++ *                               do the actual gdi object creation
++ */
++HBRUSH BRUSH_CreateBrush( const LOGBRUSH * brush )
+ {
+     BRUSHOBJ * brushPtr;
+-    HBRUSH16 hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
++    HBRUSH hbrush;
++    hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
+     if (!hbrush) return 0;
+     brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush );
+     brushPtr->logbrush.lbStyle = brush->lbStyle;
+     brushPtr->logbrush.lbColor = brush->lbColor;
+     brushPtr->logbrush.lbHatch = brush->lbHatch;
++    TRACE("created : %08x style=%x lbHatch=%x\n", hbrush, brush->lbStyle, brush->lbHatch);
+     GDI_HEAP_UNLOCK( hbrush );
+-    TRACE("%04x\n", hbrush);
+     return hbrush;
+ }
+ 
+ 
+ /***********************************************************************
++ *           BRUSH_CreateBitmapBrush (internal; do the bitmap duplication)
++ */
++HBRUSH BRUSH_CreateBitmapBrush( LOGBRUSH * brush )
++{
++    if (brush->lbStyle == BS_PATTERN)
++    {
++        brush->lbHatch = (INT)BITMAP_CopyBitmap( brush->lbHatch );
++        if (!brush->lbHatch)
++           return 0;
++    }
++    return BRUSH_CreateBrush( brush );
++}
++
++/***********************************************************************
+  *           CreateBrushIndirect32    (GDI32.27)
+  */
+ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
+ {
+-    BRUSHOBJ * brushPtr;
+-    HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
+-    if (!hbrush) return 0;
+-    brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush );
+-    brushPtr->logbrush.lbStyle = brush->lbStyle;
+-    brushPtr->logbrush.lbColor = brush->lbColor;
+-    brushPtr->logbrush.lbHatch = brush->lbHatch;
+-    GDI_HEAP_UNLOCK( hbrush );
+-    TRACE("%08x\n", hbrush);
+-    return hbrush;
++    LOGBRUSH logbrush;
++    logbrush.lbStyle = brush->lbStyle;
++    logbrush.lbColor = brush->lbColor;
++    logbrush.lbHatch = brush->lbHatch;
++    return BRUSH_CreateBitmapBrush( &logbrush );
+ }
+ 
+ 
+ /***********************************************************************
+- *           CreateHatchBrush16    (GDI.58)
++ *           CreateBrushIndirect16    (GDI.50)
+  */
+-HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
++HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
+ {
+-    LOGBRUSH logbrush;
+-
+-    TRACE("%d %06lx\n", style, color );
++    LOGBRUSH logbrush = { 0, 0, 0 };
++    logbrush.lbStyle = brush->lbStyle;
++    logbrush.lbColor = brush->lbColor;
++    logbrush.lbHatch = brush->lbHatch;
++    return (HBRUSH16) BRUSH_CreateBitmapBrush( &logbrush );
++}
+ 
+-    logbrush.lbStyle = BS_HATCHED;
+-    logbrush.lbColor = color;
+-    logbrush.lbHatch = style;
+ 
+-    if ((style < 0) || (style >= NB_HATCH_STYLES)) return 0;
+-    return CreateBrushIndirect( &logbrush );
++/***********************************************************************
++ *           CreateHatchBrush16    (GDI.58)
++ */
++HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
++{
++return (HBRUSH16) CreateHatchBrush((INT) style, color);
+ }
+ 
+ 
+@@ -81,7 +128,7 @@
+     logbrush.lbHatch = style;
+ 
+     if ((style < 0) || (style >= NB_HATCH_STYLES)) return 0;
+-    return CreateBrushIndirect( &logbrush );
++    return BRUSH_CreateBrush( &logbrush );
+ }
+ 
+ 
+@@ -90,7 +137,7 @@
+  */
+ HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
+ {
+-    return (HBRUSH16)CreatePatternBrush( hbitmap );
++    return (HBRUSH16)CreatePatternBrush( (HBITMAP) hbitmap );
+ }
+ 
+ 
+@@ -100,53 +147,31 @@
+ HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
+ {
+     LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
+-    TRACE("%04x\n", hbitmap );
+-
+-    logbrush.lbHatch = (INT)BITMAP_CopyBitmap( hbitmap );
+-    if(!logbrush.lbHatch)
+-        return 0;
+-    else
+-        return CreateBrushIndirect( &logbrush );
++    TRACE("%04x\n", hbitmap);
++   
++    logbrush.lbHatch =  hbitmap ;
++    return BRUSH_CreateBitmapBrush( &logbrush );
+ }
+ 
+ 
++
+ /***********************************************************************
+  *           CreateDIBPatternBrush16    (GDI.445)
+  */
+ HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
+ {
+     LOGBRUSH logbrush;
+-    BITMAPINFO *info, *newInfo;
+-    INT size;
++    BITMAPINFO *info;
++    BOOL ret;
+ 
+     TRACE("%04x\n", hbitmap );
+ 
+-    logbrush.lbStyle = BS_DIBPATTERN;
+-    logbrush.lbColor = coloruse;
+-    logbrush.lbHatch = 0;
+-  
+-      /* Make a copy of the bitmap */
+-
+     if (!(info = (BITMAPINFO *)GlobalLock16( hbitmap ))) return 0;
+-
+-    if (info->bmiHeader.biCompression)
+-        size = info->bmiHeader.biSizeImage;
+-    else
+-	size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
+-				    info->bmiHeader.biHeight,
+-				    info->bmiHeader.biBitCount);
+-    size += DIB_BitmapInfoSize( info, coloruse );
+-
+-    if (!(logbrush.lbHatch = (INT16)GlobalAlloc16( GMEM_MOVEABLE, size )))
+-    {
+-	GlobalUnlock16( hbitmap );
+-	return 0;
+-    }
+-    newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch );
+-    memcpy( newInfo, info, size );
+-    GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch );
++    ret = BRUSH_CopyDIB( &logbrush, info, coloruse );
+     GlobalUnlock16( hbitmap );
+-    return CreateBrushIndirect( &logbrush );
++
++    if (!ret) return 0;
++    return BRUSH_CreateBrush( &logbrush );
+ }
+ 
+ 
+@@ -165,42 +190,23 @@
+  *	
+  */
+ HBRUSH WINAPI CreateDIBPatternBrush( 
+-		HGLOBAL hbitmap, 		/* Global object containg BITMAPINFO structure */
++		HGLOBAL hbitmap, 		/* Global object containing BITMAPINFO structure */
+ 		UINT coloruse 		/* Specifies color format, if provided */
+ )
+ {
+     LOGBRUSH logbrush;
+-    BITMAPINFO *info, *newInfo;
+-    INT size;
+-    
++    BITMAPINFO *info;
++    BOOL ret;
++ 
+     TRACE("%04x\n", hbitmap );
+ 
+-    logbrush.lbStyle = BS_DIBPATTERN;
+-    logbrush.lbColor = coloruse;
+-    logbrush.lbHatch = 0;
+-
+-      /* Make a copy of the bitmap */
+-
+     if (!(info = (BITMAPINFO *)GlobalLock( hbitmap ))) return 0;
++    ret = BRUSH_CopyDIB( &logbrush, info, coloruse );
++    GlobalUnlock( hbitmap );
+ 
+-    if (info->bmiHeader.biCompression)
+-        size = info->bmiHeader.biSizeImage;
+-    else
+-	size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
+-				    info->bmiHeader.biHeight,
+-				    info->bmiHeader.biBitCount);
+-    size += DIB_BitmapInfoSize( info, coloruse );
++    if (!ret) return 0;
++    return BRUSH_CreateBrush( &logbrush );
+ 
+-    if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
+-    {
+-	GlobalUnlock16( hbitmap );
+-	return 0;
+-    }
+-    newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch );
+-    memcpy( newInfo, info, size );
+-    GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch );
+-    GlobalUnlock( hbitmap );
+-    return CreateBrushIndirect( &logbrush );
+ }
+ 
+ 
+@@ -223,35 +229,12 @@
+ {
+     BITMAPINFO *info=(BITMAPINFO*)data;
+     LOGBRUSH logbrush;
+-    BITMAPINFO  *newInfo;
+-    INT size;
+     
+     TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
+ 	  info->bmiHeader.biHeight,  info->bmiHeader.biBitCount);
+-
+-    logbrush.lbStyle = BS_DIBPATTERN;
+-    logbrush.lbColor = coloruse;
+-    logbrush.lbHatch = 0;
+ 
+-      /* Make a copy of the bitmap */
+-
+-
+-    if (info->bmiHeader.biCompression)
+-        size = info->bmiHeader.biSizeImage;
+-    else
+-	size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
+-				    info->bmiHeader.biHeight,
+-				    info->bmiHeader.biBitCount);
+-    size += DIB_BitmapInfoSize( info, coloruse );
+-
+-    if (!(logbrush.lbHatch = (INT)GlobalAlloc16( GMEM_MOVEABLE, size )))
+-    {
+-	return 0;
+-    }
+-    newInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)logbrush.lbHatch );
+-    memcpy( newInfo, info, size );
+-    GlobalUnlock16( (HGLOBAL16)logbrush.lbHatch );
+-    return CreateBrushIndirect( &logbrush );
++    if (!BRUSH_CopyDIB( &logbrush, info, coloruse )) return 0;
++    return BRUSH_CreateBrush( &logbrush );
+ }
+ 
+ 
+@@ -268,7 +251,7 @@
+     logbrush.lbColor = color;
+     logbrush.lbHatch = 0;
+ 
+-    return CreateBrushIndirect( &logbrush );
++    return BRUSH_CreateBrush( &logbrush );
+ }
+ 
+ 
+@@ -285,7 +268,7 @@
+     logbrush.lbColor = color;
+     logbrush.lbHatch = 0;
+ 
+-    return CreateBrushIndirect( &logbrush );
++    return BRUSH_CreateBrush( &logbrush );
+ }
+ 
+ 
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-cj	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,29 @@
+Index: controls/edit.c
+===================================================================
+RCS file: /home/wine/wine/controls/edit.c,v
+retrieving revision 1.29
+diff -u -u -r1.29 edit.c
+--- controls/edit.c	1999/09/10 13:58:34	1.29
++++ controls/edit.c	1999/09/24 23:39:15
+@@ -3031,14 +3034,14 @@
+ 	if (e == s)
+ 		return;
+ 	ORDER_INT(s, e);
+-	hdst = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(e - s + 1));
+-	dst = GlobalLock(hdst);
++	hdst = GlobalAlloc16(GMEM_MOVEABLE, (DWORD)(e - s + 1));
++	dst = GlobalLock16(hdst);
+ 	lstrcpynA(dst, es->text + s, e - s + 1);
+-	GlobalUnlock(hdst);
+-	OpenClipboard(wnd->hwndSelf);
+-	EmptyClipboard();
+-	SetClipboardData(CF_TEXT, hdst);
+-	CloseClipboard();
++	GlobalUnlock16(hdst);
++	OpenClipboard16(wnd->hwndSelf);
++	EmptyClipboard16();
++	SetClipboardData16(CF_TEXT, hdst);
++	CloseClipboard16();
+ }
+ 
+ 
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-ck	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,192 @@
+Index: windows/clipboard.c
+===================================================================
+RCS file: /home/wine/wine/windows/clipboard.c,v
+retrieving revision 1.16
+diff -u -u -r1.16 clipboard.c
+--- windows/clipboard.c	1999/09/20 15:42:48	1.16
++++ windows/clipboard.c	1999/09/24 23:39:31
+@@ -171,8 +171,20 @@
+  */
+ VOID CALLBACK CLIPBOARD_GlobalFreeProc( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime )
+ {
+-    /* idEvent is the HGLOBAL to be deleted */
+-    GlobalFree( (HGLOBAL)idEvent );
++    HANDLE16 hGlobal16 = (HGLOBAL16)idEvent;
++    HANDLE * pGlobalData = (HANDLE *)GlobalLock16( hGlobal16 );
++    int nElements = GlobalSize16(hGlobal16) / sizeof(HANDLE);
++    int i;
++
++    /* Free the list of HGLOBAL's */
++    for (i = 0; i < nElements; i++)
++    {
++        if (pGlobalData[i])
++            GlobalFree( pGlobalData[i] );
++    }
++    
++    GlobalUnlock16( hGlobal16 );
++    GlobalFree16( hGlobal16 );
+ }
+ 
+ /**************************************************************************
+@@ -180,6 +192,9 @@
+  */
+ void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange)
+ {
++    HANDLE16 hGlobal16 = 0;
++    HANDLE * pGlobalData = 0;
++        
+     if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
+ 	 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
+     {
+@@ -193,17 +208,22 @@
+       if (lpFormat->hData32)
+       {
+         DeleteMetaFile( ((METAFILEPICT *)GlobalLock( lpFormat->hData32 ))->hMF );
++        GlobalUnlock(lpFormat->hData32);
++
++        /* Release lpFormat->hData32 in the context of the process which created it.
++         * See CLIPBOARD_GlobalFreeProc for more details about this technique.
++         * GlobalFree(lpFormat->hDataSrc32);
++         */
++
++        /* hGlobal16 contains an array of HGLOBAL's to be free'd */
++        hGlobal16 = GlobalAlloc16(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(HANDLE) * 2);
++        pGlobalData = (HANDLE *)GlobalLock16(hGlobal16);
++        pGlobalData[0] = lpFormat->hData32;
++        pGlobalData[1] = lpFormat->hDataSrc32;
++        GlobalUnlock16(hGlobal16);
++        
+         PostMessageA(hWndClipOwner, WM_TIMER,
+-                     (WPARAM)lpFormat->hData32, (LPARAM)CLIPBOARD_GlobalFreeProc);
+-        if (lpFormat->hDataSrc32)
+-        {
+-          /* Release lpFormat->hData32 in the context of the process which created it.
+-           * See CLIPBOARD_GlobalFreeProc for more details about this technique.
+-           * GlobalFree(lpFormat->hDataSrc32);
+-           */
+-          PostMessageA(hWndClipOwner, WM_TIMER,
+-                       (WPARAM)lpFormat->hDataSrc32, (LPARAM)CLIPBOARD_GlobalFreeProc);
+-        }
++                     (WPARAM)hGlobal16, (LPARAM)CLIPBOARD_GlobalFreeProc);
+           
+ 	if (lpFormat->hData16)
+ 	  /* HMETAFILE16 and HMETAFILE32 are apparently the same thing, 
+@@ -222,22 +242,20 @@
+     {
+       if (lpFormat->hData32)
+       {
++        /* hGlobal16 contains an array of HGLOBAL's to be free'd */
++        hGlobal16 = GlobalAlloc16(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(HANDLE) * 2);
++        pGlobalData = (HANDLE *)GlobalLock16(hGlobal16);
++        pGlobalData[0] = lpFormat->hData32;
++        pGlobalData[1] = lpFormat->hDataSrc32;
++        GlobalUnlock16(hGlobal16);
++        
+         /* Release lpFormat->hData32 in the context of the process which created it.
+          * See CLIPBOARD_GlobalFreeProc for more details about this technique.
+          * GlobalFree( lpFormat->hData32 );
+          */
+         PostMessageA(hWndClipOwner, WM_TIMER,
+-                     (WPARAM)lpFormat->hData32, (LPARAM)CLIPBOARD_GlobalFreeProc);
++                     (WPARAM)hGlobal16, (LPARAM)CLIPBOARD_GlobalFreeProc);
+       }
+-      if (lpFormat->hDataSrc32)
+-      {
+-        /* Release lpFormat->hData32 in the context of the process which created it.
+-         * See CLIPBOARD_GlobalFreeProc for more details about this technique.
+-         * GlobalFree(lpFormat->hDataSrc32);
+-         */
+-        PostMessageA(hWndClipOwner, WM_TIMER,
+-                     (WPARAM)lpFormat->hDataSrc32, (LPARAM)CLIPBOARD_GlobalFreeProc);
+-      }
+       if (lpFormat->hData16)
+ 	GlobalFree16(lpFormat->hData16);
+     }
+@@ -431,7 +449,7 @@
+  * FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
+  *
+  */
+-static LPWINE_CLIPFORMAT CLIPBOARD_RenderText( UINT wFormat )
++static LPWINE_CLIPFORMAT CLIPBOARD_RenderText( UINT wFormat, BOOL b16Bit )
+ {
+     LPWINE_CLIPFORMAT lpSource = ClipFormats; 
+     LPWINE_CLIPFORMAT lpTarget;
+@@ -486,10 +504,18 @@
+         if( !lpstrS ) return NULL;
+         TRACE("\tconverting from '%s' to '%s', %i chars\n",
+                                           lpSource->Name, lpTarget->Name, size);
+-    
+-        lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT, size);
+-        lpstrT = (LPSTR)GlobalLock(lpTarget->hData32);
+-    
++
++        if (b16Bit)
++        {
++            lpTarget->hData16 = GlobalAlloc16(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, size);
++            lpstrT = (LPSTR)GlobalLock16(lpTarget->hData16);
++        }
++        else
++        {
++            lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, size);
++            lpstrT = (LPSTR)GlobalLock(lpTarget->hData32);
++        }
++        
+         if( lpstrT )
+         {
+             if( lpSource->wFormatID == CF_TEXT )
+@@ -497,10 +523,15 @@
+             else
+                 OemToCharBuffA(lpstrS, lpstrT, size);
+             TRACE("\tgot %s\n", lpstrT);
+-            GlobalUnlock(lpTarget->hData32);
++
++            /* Unlock target */
++            if (b16Bit)
++                GlobalUnlock16(lpTarget->hData16);
++            else
++                GlobalUnlock(lpTarget->hData32);
+         }
+         else
+-            lpTarget->hData32 = 0;
++            lpTarget->hData16 = lpTarget->hData32 = 0;
+ 
+         /* Unlock source */
+         if (lpSource->hData32)
+@@ -780,7 +811,7 @@
+ 
+     if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
+     {
+-	lpRender = CLIPBOARD_RenderText(wFormat);
++	lpRender = CLIPBOARD_RenderText(wFormat, TRUE);
+         if ( !lpRender ) return 0;
+     }
+     else
+@@ -790,7 +821,8 @@
+     }
+    
+     /* Convert between 32 -> 16 bit data, if necessary */
+-    if( lpRender->hData32 && !lpRender->hData16 )
++    if( lpRender->hData32 && !lpRender->hData16
++        && CLIPBOARD_IsMemoryObject(wFormat) )
+     {
+       int size;
+       if( lpRender->wFormatID == CF_METAFILEPICT )
+@@ -846,7 +878,7 @@
+ 
+     if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
+     {
+-	lpRender = CLIPBOARD_RenderText(wFormat);
++	lpRender = CLIPBOARD_RenderText(wFormat, FALSE);
+         if ( !lpRender ) return 0;
+     }
+     else
+@@ -856,7 +888,8 @@
+     }
+    
+     /* Convert between 16 -> 32 bit data, if necessary */
+-    if( lpRender->hData16 && !lpRender->hData32 )
++    if( lpRender->hData16 && !lpRender->hData32
++        && CLIPBOARD_IsMemoryObject(wFormat) )
+     {
+       int size;
+       if( lpRender->wFormatID == CF_METAFILEPICT )
--- /dev/null	Sat Sep 25 20:06:59 1999
+++ patches/patch-cl	Sat Sep 25 19:34:53 1999
@@ -0,0 +1,25 @@
+Index: windows/winproc.c
+===================================================================
+RCS file: /home/wine/wine/windows/winproc.c,v
+retrieving revision 1.27
+diff -u -u -r1.27 winproc.c
+--- windows/winproc.c	1999/08/15 12:45:02	1.27
++++ windows/winproc.c	1999/09/24 23:39:33
+@@ -2329,8 +2329,16 @@
+ {
+     WINDOWPROC *proc = WINPROC_GetPtr( func );
+ 
+-    if (!proc)
++    if (!proc) {
++	extern VOID CALLBACK CLIPBOARD_GlobalFreeProc( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime );
++	if (msg == WM_TIMER && func == (WNDPROC16)CLIPBOARD_GlobalFreeProc)
++	    /*
++	     * this is a 32bit timer proc that is not a WINDOWPROC *,
++	     * don't call it as 16bit (see windows/clipboard.c)
++	     */
++	    return WINPROC_CallWndProc((WNDPROC) func, hwnd, msg, wParam, lParam );
+         return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
++    }
+ 
+ #if testing
+     func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
--- /dev/null	Sat Sep 25 20:08:54 1999
+++ pkg/MESSAGE	Thu Sep  9 23:27:58 1999
@@ -0,0 +1,4 @@
+In order to use wine you need to build and install a new kernel with
+options USER_LDT, SYSVSHM, SYSVSEM, and SYSVMSG.  Before you do that
+you might want to apply the patches in /usr/local/share/wine to your
+kernel sources, see the README.patch there.

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199909252047.WAA56452>