The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
This patch is already applied to files in Tk-OS2 distribution!


diff -pru Tk402.003/basic_demo Tk402.003.db/basic_demo
--- Tk402.003/basic_demo	Sat Feb  7 01:18:42 1998
+++ Tk402.003.db/basic_demo	Thu Feb 26 02:09:58 1998
@@ -348,8 +348,8 @@ $top->property("set",MYPROP,AREA,32,[1,2
 
 $top->update("idletasks");
 
-if (open(Gibberish, $^O eq 'os2' ? '<&STDIN' : "</dev/tty") 
-    and ($^O ne 'os2' or not -t Gibberish))	# XFree86-OS/2 and PM quirks
+$| = 1;
+if (open(Gibberish, $^O eq 'os2' ? '<&STDIN' : "</dev/tty"))
  {
   $top->fileevent(Gibberish,'readable',[sub { my ($fh) = @_; print "stdin:",scalar <$fh> },\*Gibberish]);
  }
diff -pru Tk402.003/pTk/Lang.h Tk402.003.db/pTk/Lang.h
--- Tk402.003/pTk/Lang.h	Sat Aug  2 07:42:02 1997
+++ Tk402.003.db/pTk/Lang.h	Thu Feb 26 01:28:38 1998
@@ -23,7 +23,7 @@
 #endif
 
 #ifdef __EMX__
-typedef long fd_mask;
+typedef char fd_mask;
 #   define strncasecmp strnicmp
 #   define strcasecmp stricmp
 #endif
diff -pru Tk402.003/pTk/mTk/open32/dllMain.c Tk402.003.db/pTk/mTk/open32/dllMain.c
--- Tk402.003/pTk/mTk/open32/dllMain.c	Tue Feb  3 21:11:54 1998
+++ Tk402.003.db/pTk/mTk/open32/dllMain.c	Thu Feb 26 02:30:46 1998
@@ -34,10 +34,6 @@
 #define _System
 #include <stdio.h>
 
-struct Tcl_Time;
-extern int (*Tcl_WaitForEventProc)(int, long *, struct Tcl_Time *);
-extern int OS2Tcl_WaitForEvent(int, long *, struct Tcl_Time *);
-
 int _CRT_init(void);
 void _CRT_term(void);
 void __ctordtorInit(void);
@@ -90,7 +86,6 @@ unsigned long _System _DLL_InitTerm(unsi
        * (NOTE: this assumes the DLL entry point is a function called
        *        DllEntryPoint)
        */
-      Tcl_WaitForEventProc = &OS2Tcl_WaitForEvent;
       init = 1;
 #ifdef __WIN32__
       return DllEntryPoint((HANDLE) handle, DLL_PROCESS_ATTACH, &reserved) != 0;
diff -pru Tk402.003/pTk/mTk/open32/tkWinOS2.c Tk402.003.db/pTk/mTk/open32/tkWinOS2.c
--- Tk402.003/pTk/mTk/open32/tkWinOS2.c	Wed Feb  4 15:43:24 1998
+++ Tk402.003.db/pTk/mTk/open32/tkWinOS2.c	Thu Feb 26 02:04:50 1998
@@ -12,8 +12,180 @@ HWND tmpParent;
 static int ignoreEvents = 0;
 #endif
 
+#include <sys/builtin.h>
+#include <sys/fmutex.h>
+
+#define WM_SELECT_FINISHED (WM_USER+2)
+#define MASK_SIZE sizeof(fd_set)/sizeof(fd_mask)	/* Hardcoded, do not want to
+					   include unix.h */
+/* #define DEBUG */
+
+#define LOCK_(mt) if ((rc = _fmutex_request(&(mt),0))) 		     \
+		sprintf(buff, "l.%d,_fmutex_request(%#lx,%d): %#x\n",__LINE__,(mt).hev,(int)(mt).fs,rc), \
+		putbuff(), exit(1)
+#define UNLOCK_(mt)    if ((rc = _fmutex_release(&(mt))))		     \
+		sprintf(buff, "l.%d,_fmutex_release(%#lx,%d): %#x\n",__LINE__,(mt).hev,(int)(mt).fs,rc), \
+		putbuff(), exit(1)
+#define LOCK_FDS	LOCK_(mt_answer)
+#define UNLOCK_FDS	UNLOCK_(mt_answer)
+
+#define LOCK_DELIVER	LOCK_(mt_deliver)
+#define UNLOCK_DELIVER	UNLOCK_(mt_deliver)
+
 extern char StashedKey;
 char StashedKey = 0;	/* fake for PM */
+
+static int pipes[2] = {0, 0};
+
+#if 0
+static _fmutex mt;
+#endif 
+
+static _fmutex mt_answer = {0};
+static _fmutex mt_deliver = {0};
+
+static fd_mask checkMasks[3*MASK_SIZE] = {0};
+				/* This array contains masks which
+				   initiated the current code to select. */
+static fd_mask readyMasks[3*MASK_SIZE] = {0};
+				/* This array contains actual masks which
+				   select() is using. */
+static fd_mask answerMasks[3*MASK_SIZE] = {0};
+				/* This array contains the results of last
+				   select(). */
+static fd_mask questionMasks[3*MASK_SIZE] = {0};
+				/* This array contains the querys of last
+				   select(). */
+static int numFdBits = 0;		/* Number of valid bits in checkMasks
+				 * (one more than highest fd for which
+				 * Tcl_WatchFile has been called). */
+static int selecter_tid = 0;
+static int selecter_n = 0;
+
+static char buff[1024];
+
+static void
+putbuff(void)
+{
+    write(2,buff,strlen(buff));
+}
+
+static void
+selecter(void *arg)
+{
+    char c;
+    int numFound, event;
+    unsigned int rc;
+
+    while (1) {
+	/* Wait indefinitely: */
+	LOCK_FDS;
+	memcpy((VOID *) questionMasks, (VOID *) readyMasks,
+	       3*MASK_SIZE*sizeof(fd_mask));
+	UNLOCK_FDS;
+
+#ifdef DEBUG
+	sprintf(buff, "doing select(%d,%#lx,%#lx,%#lx,NULL)...\n",
+			numFdBits, questionMasks[0], questionMasks[1], questionMasks[2]),putbuff();
+#endif 
+
+	numFound = select(numFdBits, (SELECT_MASK *) &questionMasks[0],
+	    (SELECT_MASK *) &questionMasks[MASK_SIZE],
+	    (SELECT_MASK *) &questionMasks[2*MASK_SIZE], NULL);
+	
+#ifdef DEBUG
+	sprintf(buff, "select gave (%d,%#lx,%#lx,%#lx)...\n",
+			numFound, questionMasks[0], questionMasks[1], questionMasks[2]),putbuff();
+#endif 
+
+	if (FD_ISSET(pipes[0], (SELECT_MASK *) &questionMasks[0])) {
+#ifdef DEBUG
+	    sprintf(buff, "select needs update...\n"),putbuff();
+#endif 
+	    /* Need to renew the masks */
+	    FD_CLR(pipes[0], (SELECT_MASK *) &questionMasks[0]);
+	    numFound--;
+	    /* Update the position */
+	    if (read(pipes[0], &c, 1) != 1)
+		perror("selecter,read: "), exit(1);
+#if 0
+	    if ((rc = _fmutex_release(&mt)))
+		sprintf(buff, "selecter,_fmutex_release: %#x\n",rc),putbuff(), exit(1);
+#endif 
+	    /* The caller does not want us to inform on old fds, let
+	       us hope that the next select() will not lose the info: */
+	    continue;
+	} 
+	if (!numFound)
+	    continue;		/* Does not worth informing, the
+				   default value is good enough.  */
+	/* Now inform the message loop that something happened: */
+	LOCK_FDS;
+	memcpy((VOID *) answerMasks, (VOID *) questionMasks,
+	       3*MASK_SIZE*sizeof(fd_mask));
+	UNLOCK_FDS;
+#ifdef __WIN32__
+	????
+#else
+	if (!WinPostQueueMsg(hmq, WM_SELECT_FINISHED, 0, 0)) {
+	    perror("selecter,WinPostQueueMsg: "), exit(1);
+	}
+#endif 
+	LOCK_DELIVER;			/* No sense to repeat select
+					   until the result may be used. */
+    }    
+}
+
+static int
+start_selecter(void)
+{
+    int res;
+    unsigned int rc;
+    
+    if ((rc = _fmutex_create(&mt_answer, 0)))
+	sprintf(buff, "selecter_answer,_fmutex_create: %#x\n",rc),putbuff(), exit(1);
+#if 0
+    if ((rc = _fmutex_create(&mt, 0)))
+	sprintf(buff, "selecter,_fmutex_create: %#x\n",rc),putbuff(), exit(1);
+    if ((rc = _fmutex_request(&mt,0)))
+	sprintf(buff, "selecter,_fmutex_request0: %#x\n",rc),putbuff(), exit(1);
+#endif 
+    if ((rc = _fmutex_create(&mt_deliver, 0)))
+	sprintf(buff, "selecter,_fmutex_create: %#x\n",rc),putbuff(), exit(1);
+    LOCK_DELIVER;			/* Nothing delivered so far. */
+    if ((res = _beginthread(&selecter, NULL, 32000, NULL)) == -1)
+	perror("selecter,_beginthread: "), exit(1);
+#ifdef DEBUG
+    sprintf(buff, "started thread %d.\n", res),putbuff();
+#endif 
+    return res;
+}
+
+static void
+pre_start_selecter(void)
+{
+    int res;
+    unsigned int rc;
+    
+    if (pipe(pipes))
+	perror("selecter,pipe: "), exit(1);
+}
+
+static void
+inform_selecter(void)
+{
+    unsigned int rc;
+#ifdef DEBUG
+    sprintf(buff, "informing... pipe=%d\n",pipes[1]),putbuff();
+#endif 
+    if (write(pipes[1], ".", 1) != 1)
+	perror("selecter,write: "), exit(1);
+#if 0
+    if ((rc = _fmutex_request(&mt,0)))
+	sprintf(buff, "selecter,_fmutex_request: %#x\n",rc),putbuff(), exit(1);
+#endif
+}
+
 /*
  *----------------------------------------------------------------------
  *
@@ -51,6 +223,7 @@ OS2Tcl_WaitForEvent(n, maskPtr, timePtr)
     QMSG msg;
 #endif
     int foundEvent = 1;
+    unsigned int rc;
 
     /*
      * If we are ignoring events from the system, just return immediately.
@@ -60,6 +233,50 @@ OS2Tcl_WaitForEvent(n, maskPtr, timePtr)
 	return 0;
     }
 #endif
+    /* Update select() masks if required */
+    if (n || numFdBits) {
+	/* Check whether we need to stop the running select(), or
+	   start selecter. */
+	if (n != selecter_n 
+	    || memcmp((VOID *) checkMasks, (VOID *) maskPtr, 
+		      3*MASK_SIZE*sizeof(fd_mask))
+	    || !selecter_tid) {
+
+	    memcpy((VOID *) checkMasks, (VOID *) maskPtr,
+		   3*MASK_SIZE*sizeof(fd_mask)); /* Not modified */
+	    if (!selecter_tid)
+		pre_start_selecter();	/* Need to know the pipe number
+					   before starting it. */
+	    if (selecter_tid) {
+		LOCK_FDS;
+	    }
+	    memcpy((VOID *) readyMasks, (VOID *) maskPtr,
+		   3*MASK_SIZE*sizeof(fd_mask));
+	    FD_SET(pipes[0], (SELECT_MASK *) &readyMasks[0]);
+	    numFdBits = (pipes[0] + 1) > n ? (pipes[0] + 1) : n ;
+	    if (selecter_tid) {
+		UNLOCK_FDS;
+	    }
+	    selecter_n = n;
+#ifdef DEBUG
+	    sprintf(buff, "need  select(%d,%#lx,%#lx,%#lx,NULL) pipe=%d...\n",
+		    n, checkMasks[0], checkMasks[1],
+		    checkMasks[2], pipes[0]),putbuff();
+#endif 
+	    /* Start the fileevent thread if needed: */
+	    if (!selecter_tid) {
+#ifdef DEBUG
+		sprintf(buff, "starting...\n"),putbuff();
+#endif 
+		selecter_tid = start_selecter();
+	    } else
+		inform_selecter();	/* Now the old select() is stopped. */
+	}
+    }
+
+    /* Mark as not ready: */
+    memset((VOID *) maskPtr, 0, 3*MASK_SIZE*sizeof(fd_mask));
+
     /*
      * Set up the asynchronous select handlers for any sockets we
      * are watching.
@@ -112,16 +329,32 @@ OS2Tcl_WaitForEvent(n, maskPtr, timePtr)
      */
 
     if (foundEvent) {
+	int type;
+	
 #ifdef __WIN32__
-	if (msg.message == WM_QUIT) {
+	type = msg.message;
+#else
+	type = msg.msg;
+#endif
+	if (type == WM_QUIT)
 	    Tcl_Exit(0);
+	else if (type == WM_SELECT_FINISHED) {
+	    /* Now answerMask contains valid values of masks some time
+	       ago.  */
+#ifdef DEBUG
+	    sprintf(buff, "message gave (%#lx,%#lx,%#lx)...\n",
+			answerMasks[0], answerMasks[1], answerMasks[2]),putbuff();
+#endif 
+	    LOCK_FDS;
+	    memcpy((VOID *) maskPtr, (VOID *) answerMasks,
+		   3*MASK_SIZE*sizeof(fd_mask));
+	    UNLOCK_FDS;
+	    UNLOCK_DELIVER;		/* Let it select() again. */
 	}
+#ifdef __WIN32__
 	TranslateMessage(&msg);
 	DispatchMessage(&msg);
 #else
-	if (msg.msg == WM_QUIT) {
-	    Tcl_Exit(0);
-	}
 	WinDispatchMsg(hab, &msg);
 #endif
     }
diff -pru Tk402.003/pTk/mTk/open32/tkWinOS2.c~ Tk402.003.db/pTk/mTk/open32/tkWinOS2.c~
--- Tk402.003/pTk/mTk/open32/tkWinOS2.c~	Tue Feb  3 21:10:04 1998
+++ Tk402.003.db/pTk/mTk/open32/tkWinOS2.c~	Tue Feb 24 04:38:34 1998
@@ -12,8 +12,111 @@ HWND tmpParent;
 static int ignoreEvents = 0;
 #endif
 
+#include <sys/builtin.h>
+#include <sys/fmutex.h>
+
+#define WM_SELECT_FINISHED (WM_USER+2)
+#define MASK_SIZE 1			/* Hardcoded, do not want to
+					   include unix.h */
+
 extern char StashedKey;
 char StashedKey = 0;	/* fake for PM */
+
+static int pipes[2];
+static _fmutex mt;
+static _fmutex mt_answer;
+
+static fd_mask checkMasks[3*MASK_SIZE];
+				/* This array contains masks which
+				   initiated the current code to select. */
+static fd_mask readyMasks[3*MASK_SIZE];
+				/* This array contains actual masks which
+				   select() is using. */
+static fd_mask answerMasks[3*MASK_SIZE];
+				/* This array contains the results of last
+				   select(). */
+static int numFdBits;		/* Number of valid bits in checkMasks
+				 * (one more than highest fd for which
+				 * Tcl_WatchFile has been called). */
+static int selecter_tid;
+static int selecter_n;
+
+static void
+selecter(void *arg)
+{
+    char c;
+    int numFound, event;
+    unsigned int rc;
+    
+    while (1) {
+	/* Wait indefinitely: */
+
+	printf( "doing select(%d,%#x,%#x,%#x,NULL)...\n",
+			numFdBits, readyMasks[0], readyMasks[1], readyMasks[2]);
+
+	numFound = select(numFdBits, (SELECT_MASK *) &readyMasks[0],
+	    (SELECT_MASK *) &readyMasks[MASK_SIZE],
+	    (SELECT_MASK *) &readyMasks[2*MASK_SIZE], NULL);
+	
+	printf( "select gave (%d,%#x,%#x,%#x)...\n",
+			numFound, readyMasks[0], readyMasks[1], readyMasks[2]);
+
+	if (FD_ISSET(pipes[0], (SELECT_MASK *) &readyMasks[0])) {
+	    /* Need to renew the masks */
+	    FD_CLR(pipes[0], (SELECT_MASK *) &readyMasks[0]);
+	    numFound--;
+	    /* Update the position */
+	    if (read(pipes[0], &c, 1) != 1)
+		perror("selecter,read: "), exit(1);
+	    if ((rc = _fmutex_release(&mt)))
+		printf( "selecter,_fmutex_release: %#x\n",rc), exit(1);
+	} 
+	if (!numFound)
+	    continue;		/* Does not worth informing, the
+				   default value is good enough.  */
+	/* Now inform the message loop that something happened: */
+	if ((rc = _fmutex_request(&mt_answer,0)))
+	    printf( "selecter_answer2,_fmutex_request: %#x\n",rc), exit(1);
+	memcpy((VOID *) answerMasks, (VOID *) readyMasks,
+	       3*MASK_SIZE*sizeof(fd_mask));
+	if ((rc = _fmutex_release(&mt_answer)))
+	    printf( "selecter_answer2,_fmutex_release: %#x\n",rc), exit(1);
+	if (!WinPostQueueMsg(hmq, WM_SELECT_FINISHED, 0, 0)) {
+	    perror("selecter,WinPostQueueMsg: "), exit(1);
+	}
+    }    
+}
+
+int
+start_selecter(void)
+{
+    int res;
+    unsigned int rc;
+    
+    if (pipe(pipes))
+	perror("selecter,pipe: "), exit(1);
+    if ((rc = _fmutex_create(&mt, 0)))
+	printf( "selecter,_fmutex_create: %#x\n",rc), exit(1);
+    if ((rc = _fmutex_create(&mt_answer, 0)))
+	printf( "selecter_answer,_fmutex_create: %#x\n",rc), exit(1);
+    if ((rc = _fmutex_request(&mt,0)))
+	printf( "selecter,_fmutex_request0: %#x\n",rc), exit(1);
+    if ((res = _beginthread(&selecter, NULL, 32000, NULL)) == -1)
+	perror("selecter,_beginthread: "), exit(1);
+    return res;
+}
+
+void
+inform_selecter(void)
+{
+    unsigned int rc;
+    printf( "informing...\n");
+    if (write(pipes[1], ".", 1) != 1)
+	perror("selecter,write: "), exit(1);
+    if ((rc = _fmutex_request(&mt,0)))
+	printf( "selecter,_fmutex_request: %#x\n",rc), exit(1);
+}
+
 /*
  *----------------------------------------------------------------------
  *
@@ -51,6 +154,7 @@ OS2Tcl_WaitForEvent(n, maskPtr, timePtr)
     QMSG msg;
 #endif
     int foundEvent = 1;
+    unsigned int rc;
 
     /*
      * If we are ignoring events from the system, just return immediately.
@@ -60,6 +164,34 @@ OS2Tcl_WaitForEvent(n, maskPtr, timePtr)
 	return 0;
     }
 #endif
+    /* Update select() masks if required */
+    if (n || numFdBits) {
+	/* Check whether we need to stop the running select(), or
+	   start selecter. */
+	if (n != selecter_n 
+	    || memcmp((VOID *) checkMasks, (VOID *) maskPtr, 
+		      3*MASK_SIZE*sizeof(fd_mask))
+	    || !selecter_tid) {
+
+	    memcpy((VOID *) readyMasks, (VOID *) maskPtr,
+		   3*MASK_SIZE*sizeof(fd_mask));
+	    memcpy((VOID *) checkMasks, (VOID *) maskPtr,
+		   3*MASK_SIZE*sizeof(fd_mask)); /* Not modified */
+	    FD_SET(pipes[0], (SELECT_MASK *) &readyMasks[0]);
+	    numFdBits = pipes[0] > n ? pipes[0] : n ;
+	    selecter_n = n;
+	    printf( "need  select(%d,%#x,%#x,%#x,NULL)...\n",
+			n, readyMasks[0], readyMasks[1], readyMasks[2]);
+	    /* Start the fileevent thread if needed: */
+	    if (!selecter_tid) {
+		printf( "starting...\n");
+		selecter_tid = start_selecter();
+	    } else
+		inform_selecter();	/* Now the old select() is stopped. */
+	}
+	/* Mark as not ready: */
+	memset((VOID *) maskPtr, 0, 3*MASK_SIZE*sizeof(fd_mask));
+    }
     /*
      * Set up the asynchronous select handlers for any sockets we
      * are watching.
@@ -112,16 +244,29 @@ OS2Tcl_WaitForEvent(n, maskPtr, timePtr)
      */
 
     if (foundEvent) {
+	int type;
+	
 #ifdef __WIN32__
-	if (msg.message == WM_QUIT) {
+	type = msg.message;
+#else
+	type = msg.msg;
+#endif
+	if (type == WM_QUIT)
 	    Tcl_Exit(0);
+	else if (type == WM_SELECT_FINISHED) {
+	    /* Now answerMask contains valid values of masks some time
+	       ago.  */
+	    if ((rc = _fmutex_request(&mt_answer,0)))
+		printf( "selecter_answer1,_fmutex_request: %#x\n",rc), exit(1);
+	    memcpy((VOID *) maskPtr, (VOID *) answerMasks,
+		   3*MASK_SIZE*sizeof(fd_mask));
+	    if ((rc = _fmutex_release(&mt_answer)))
+		printf( "selecter_answer1,_fmutex_release: %#x\n",rc), exit(1);
 	}
+#ifdef __WIN32__
 	TranslateMessage(&msg);
 	DispatchMessage(&msg);
 #else
-	if (msg.msg == WM_QUIT) {
-	    Tcl_Exit(0);
-	}
 	WinDispatchMsg(hab, &msg);
 #endif
     }
@@ -516,6 +661,49 @@ TixpXpmDisplay(clientData, display, draw
     CopyTransparent(display, dataPtr->bitmapDC, drawable,
 	imageX, imageY, width, height,
 	drawableX, drawableY, dataPtr->maskDC);
+}
+
+/*----------------------------------------------------------------------
+ * TixpDrawAnchorLines --
+ *
+ *	See comments near Tix_DrawAnchorLines.
+ *----------------------------------------------------------------------
+ */
+					/* Stolen from tixUnix */
+void TixpDrawAnchorLines(display, drawable, gc, x, y, w, h)
+    Display *display;
+    Drawable drawable;
+    GC gc;
+    int x;
+    int y;
+    int w;
+    int h;
+{
+    XPoint points[4];
+
+    if (w < 1) {
+	w = 1;
+    }
+    if (h < 1) {
+	h = 1;
+    }
+
+    XDrawRectangle(display, drawable, gc, x, y, w-1, h-1);
+#if 0
+    /*
+     * Draw these points so that the corners will not be rounded
+     */
+    points[0].x = x;
+    points[0].y = y;
+    points[1].x = x + w - 1;
+    points[1].y = y;
+    points[2].x = x;
+    points[2].y = y + h - 1;
+    points[3].x = x + w - 1;
+    points[3].y = y + h - 1;
+
+    XDrawPoints(display, drawable, gc, points, 4, CoordModeOrigin);
+#endif 
 }
 
 static void
diff -pru Tk402.003/pTk/mTk/os2/tkOS2Init.c Tk402.003.db/pTk/mTk/os2/tkOS2Init.c
--- Tk402.003/pTk/mTk/os2/tkOS2Init.c	Tue Feb  3 00:32:00 1998
+++ Tk402.003.db/pTk/mTk/os2/tkOS2Init.c	Thu Feb 26 02:31:12 1998
@@ -345,6 +345,10 @@ TkOS2ExitPM (void)
     hmq= hab= 0;
 }
 
+struct Tcl_Time;
+extern int (*Tcl_WaitForEventProc)(int, long *, struct Tcl_Time *);
+extern int OS2Tcl_WaitForEvent(int, long *, struct Tcl_Time *);
+
 void
 Register_MQ(void)
 {
@@ -364,6 +368,7 @@ Register_MQ(void)
 	    _exit(188);			/* Panic can try to create a window. */
 	panic("Cannot create a message queue, am I a PM application?");
     }
+    Tcl_WaitForEventProc = &OS2Tcl_WaitForEvent;
 }
 
 void
@@ -372,5 +377,6 @@ Deregister_MQ(void)
     if (hmq) {
 	WinDestroyMsgQueue(hmq);
     }
+    Tcl_WaitForEventProc = NULL;
 }
 
diff -pru Tk402.003/pTk/mTk/tclGeneric/tclEvent.c Tk402.003.db/pTk/mTk/tclGeneric/tclEvent.c
--- Tk402.003/pTk/mTk/tclGeneric/tclEvent.c	Sat Aug  2 07:42:22 1997
+++ Tk402.003.db/pTk/mTk/tclGeneric/tclEvent.c	Tue Feb 24 05:52:34 1998
@@ -378,11 +378,8 @@ Tcl_CreateFileHandler(file, mask, proc, 
     } else {
 	filePtr->clientData = (ClientData) LangCopyCallback((LangCallback *) clientData);
     }
-#ifdef OS2
+#ifdef __EMX__
     {
-/*	FileHandle *handlePtr = (FileHandle *) handle;
-	int fd = handlePtr->key.osHandle;
-*/
 	int type;
 	int fd = (int)Tcl_GetFileInfo(file, &type);
 	struct termio tio;
diff -pru Tk402.003/pTk/mTk/tclUnix/tclUnixNotfy.c Tk402.003.db/pTk/mTk/tclUnix/tclUnixNotfy.c
--- Tk402.003/pTk/mTk/tclUnix/tclUnixNotfy.c	Sat Aug  2 07:42:30 1997
+++ Tk402.003.db/pTk/mTk/tclUnix/tclUnixNotfy.c	Thu Feb 26 01:59:10 1998
@@ -350,6 +350,16 @@ Tcl_Sleep(ms)
 		|| ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
 	    break;
 	}
+#if defined(__EMX__) && (defined(__WIN32__) || defined(__PM__))
+	if (Tcl_WaitForEventProc) {
+	    Tcl_Time time;
+
+	    time.sec = delay.tv_sec;
+	    time.usec = delay.tv_usec;
+	    memset((VOID *) readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
+	    (*Tcl_WaitForEventProc)(0, readyMasks, &time);
+	} else
+#endif
 	(void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0,
 		(SELECT_MASK *) 0, &delay);
 	TclpGetTime(&before);