Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Nov 1999 03:04:58 +0100 (MET)
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/14652: update emulators/wine to 991031 (supersedes ports/13952)
Message-ID:  <199911020204.DAA25570@saturn.kn-bremen.de>

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

>Number:         14652
>Category:       ports
>Synopsis:       update emulators/wine to 991031 (supersedes ports/13952)
>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:   Mon Nov  1 18:10:01 PST 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 991031 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-991031: (see ChangeLog for details)
	- Reimplementation of Winsock support.
	- Last part of multimedia reorganization in DLLs.
	- Many other multimedia improvements.
	- COM interfaces access cleaned up.
	- More features in common controls.
	- 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-bb,
	patches/patch-cj, patches/patch-ck, patches/patch-cl,
	patches/patch-cm, 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/11/01 23:00:28
@@ -1,14 +1,14 @@
 # New ports collection makefile for:    wine
-# Version required:     980517
+# Version required:     991031
 # 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=		991031
 DISTNAME=	Wine-${DATE}
-PKGNAME=	wine-99.04.26
+PKGNAME=	wine-99.10.31
 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
@@ -31,10 +33,19 @@
 
 do-install:
 	${INSTALL} -c ${WRKSRC}/wine ${PREFIX}/bin
+	${INSTALL} -c ${WRKSRC}/tools/fnt2bdf ${PREFIX}/bin
+	${INSTALL} -c ${WRKSRC}/windows/x11drv/wineclipsrv ${PREFIX}/bin
 	-@${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/11/01 18:33:35
@@ -1 +1 @@
-MD5 (Wine-990426.tar.gz) = ddc5561393b7fedb02b933889658eb7f
+MD5 (Wine-991031.tar.gz) = 80904e8933ac1a72fdf4c0a05f36d6be
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/11/02 01:22:13
@@ -1,3 +1,9 @@
 bin/wine
+bin/fnt2bdf
+bin/wineclipsrv
 etc/wine.conf
 etc/wine.sym
+share/wine/README.patch
+share/wine/patch-3.3-sys-ldtshare
+share/wine/patch-3.3-sys-sigtrap
+@dirrm share/wine
Index: files/README.patch
@@ -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.)
Index: files/patch-3.3-sys-ldtshare
@@ -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);
+ }
+ 
+ /*
Index: files/patch-3.3-sys-sigtrap
@@ -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);
Index: patches/patch-ba
@@ -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:
Index: patches/patch-bb
@@ -0,0 +1,40 @@
+Index: windows/x11drv/clipboard.c
+@@ -53,6 +53,7 @@
+ #include <X11/Xatom.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <fcntl.h>
+ 
+ #include "ts_xlib.h"
+ 
+@@ -240,6 +241,13 @@
+         
+         int dbgClasses = 0;
+         char selMask[8], dbgClassMask[8], clearSelection[8];
++	int i;
++
++	/* Don't inherit wine's X sockets to the wineclipsrv, otherwise
++	 * windows stay around when you have to kill a hanging wine...
++	 */
++	for (i = 3; i < 256; ++i)
++		fcntl(i, F_SETFD, 1);
+ 
+         sprintf(selMask, "%d", selectionAcquired);
+ 
+@@ -255,12 +263,12 @@
+         /* Get the clear selection preference */
+         sprintf(clearSelection, "%d",
+                 PROFILE_GetWineIniInt("Clipboard", "ClearAllSelections", 0));
+-            
++
+         /* Exec the clipboard server passing it the selection and debug class masks */
+-        execl( BINDIR "/wineclipsvr", "wineclipsvr",
++        execl( BINDIR "/wineclipsrv", "wineclipsrv",
+                selMask, dbgClassMask, clearSelection, NULL );
+-        execlp( "wineclipsvr", "wineclipsvr", selMask, dbgClassMask, clearSelection, NULL );
+-        execl( "./windows/x11drv/wineclipsvr", "wineclipsvr",
++        execlp( "wineclipsrv", "wineclipsrv", selMask, dbgClassMask, clearSelection, NULL );
++        execl( "./windows/x11drv/wineclipsrv", "wineclipsrv",
+                selMask, dbgClassMask, clearSelection, NULL );
+ 
+         /* Exec Failed! */
Index: patches/patch-cj
@@ -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();
+ }
+ 
+ 
Index: patches/patch-ck
@@ -0,0 +1,198 @@
+Index: windows/clipboard.c
+===================================================================
+RCS file: /home/wine/wine/windows/clipboard.c,v
+retrieving revision 1.18
+diff -u -u -r1.18 clipboard.c
+--- windows/clipboard.c	1999/10/24 20:22:24	1.18
++++ windows/clipboard.c	1999/11/01 18:08:56
+@@ -24,6 +24,7 @@
+ #include <unistd.h>
+ #include <string.h>
+ #include "winuser.h"
++#include "winproc.h"
+ #include "wine/winuser16.h"
+ #include "wine/winbase16.h"
+ #include "heap.h"
+@@ -54,6 +55,8 @@
+ 
+ static WORD LastRegFormat = CF_REGFORMATBASE;
+ 
++static TIMERPROC globalFreeProc = 0;  /* Really a pointer to a WINDOWPROC */
++    
+ /* Clipboard cache initial data.
+  * WARNING: This data ordering is dependendent on the WINE_CLIPFORMAT structure
+  * declared in clipboard.h
+@@ -171,15 +174,39 @@
+  */
+ 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 );
+ }
+ 
+ /**************************************************************************
+  *			CLIPBOARD_DeleteRecord
+  */
++
+ void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange)
+ {
++    HANDLE16 hGlobal16 = 0;
++    HANDLE * pGlobalData = 0;
++
++    /* We must allocate a WINDOWPROC handle to allow DispatchMessage to correctly
++     * call our globalFreeProc as a 32 bit WndProc, while running either in a 16
++     * or 32 bit context.
++     */
++    if ( !globalFreeProc )
++        globalFreeProc = (TIMERPROC)WINPROC_AllocWinProc( (WNDPROC16)CLIPBOARD_GlobalFreeProc,
++                                                          WIN_PROC_32A, WIN_PROC_TIMER );
++    
+     if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
+ 	 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP 
+ 	    || lpFormat->wFormatID == CF_PALETTE)
+@@ -194,17 +221,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)globalFreeProc);
+           
+ 	if (lpFormat->hData16)
+ 	  /* HMETAFILE16 and HMETAFILE32 are apparently the same thing, 
+@@ -223,22 +255,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)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);
+     }
+@@ -432,7 +462,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;
+@@ -487,10 +517,18 @@
+         if( !lpstrS ) return NULL;
+         TRACE("\tconverting from '%s' to '%s', %i chars\n",
+                                           lpSource->Name, lpTarget->Name, size);
+-    
+-        lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, 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 )
+@@ -498,10 +536,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)
+@@ -781,7 +824,7 @@
+ 
+     if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
+     {
+-	lpRender = CLIPBOARD_RenderText(wFormat);
++	lpRender = CLIPBOARD_RenderText(wFormat, TRUE);
+         if ( !lpRender ) return 0;
+     }
+     else
+@@ -848,7 +891,7 @@
+ 
+     if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
+     {
+-	lpRender = CLIPBOARD_RenderText(wFormat);
++	lpRender = CLIPBOARD_RenderText(wFormat, FALSE);
+         if ( !lpRender ) return 0;
+     }
+     else
Index: patches/patch-cl
@@ -0,0 +1,27 @@
+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/11/01 18:09:02
+@@ -257,8 +257,8 @@
+  *
+  * Allocate a new window procedure.
+  */
+-static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
+-                                         WINDOWPROCUSER user )
++HWINDOWPROC WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
++                                  WINDOWPROCUSER user )
+ {
+     WINDOWPROC *proc, *oldproc;
+ 
+@@ -428,7 +428,7 @@
+             type = proc->type;
+             func = WINPROC_THUNKPROC(proc);
+         }
+-        proc = WINPROC_AllocWinProc( func, type, user );
++        proc = (WINDOWPROC *)WINPROC_AllocWinProc( func, type, user );
+         if (!proc) return FALSE;
+     }
+ 
Index: patches/patch-cm
@@ -0,0 +1,16 @@
+Index: include/winproc.h
+===================================================================
+RCS file: /home/wine/wine/include/winproc.h,v
+retrieving revision 1.4
+diff -u -u -r1.4 winproc.h
+--- include/winproc.h	1999/03/14 16:35:08	1.4
++++ include/winproc.h	1999/11/01 18:08:53
+@@ -41,6 +41,8 @@
+ } MSGPARAM;
+ 
+ extern BOOL WINPROC_Init(void);
++extern HWINDOWPROC WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
++                                         WINDOWPROCUSER user );
+ extern WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type );
+ extern BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
+                                WINDOWPROCTYPE type, WINDOWPROCUSER user );
Index: pkg/MESSAGE
@@ -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?199911020204.DAA25570>