From owner-freebsd-ports Mon Nov 1 18:10:26 1999 Delivered-To: freebsd-ports@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 5035E15332 for ; Mon, 1 Nov 1999 18:10:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id SAA55714; Mon, 1 Nov 1999 18:10:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from blaubaer.kn-bremen.de (blaubaer.kn-bremen.de [195.37.179.254]) by hub.freebsd.org (Postfix) with ESMTP id 3D63215100 for ; Mon, 1 Nov 1999 18:07:21 -0800 (PST) (envelope-from nox@saturn.kn-bremen.de) Received: from saturn.kn-bremen.de (uucp@localhost) by blaubaer.kn-bremen.de (8.9.1/8.9.1) with UUCP id DAA26291 for FreeBSD-gnats-submit@freebsd.org; Tue, 2 Nov 1999 03:06:13 +0100 Received: (from nox@localhost) by saturn.kn-bremen.de (8.9.3/8.8.5) id DAA25570; Tue, 2 Nov 1999 03:04:58 +0100 (MET) Message-Id: <199911020204.DAA25570@saturn.kn-bremen.de> Date: Tue, 2 Nov 1999 03:04:58 +0100 (MET) From: Juergen Lock Reply-To: nox@jelal.kn-bremen.de To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: ports/14652: update emulators/wine to 991031 (supersedes ports/13952) Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >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 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 + + # + +@@ -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 ) = 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + + #include + #include +@@ -68,6 +69,9 @@ + #include + #include + #endif ++#ifdef USER_LDT ++#include ++#endif + + #include + #include +@@ -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 + #include + #include ++#include + + #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 + #include + #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