One needs to collect files 
	tk*/os/tkOS2*.[ch] and tk*/os2/stubs.c
into a separate directory before applying this patch.

--- Tk402.003/pTk/mTk/os2/pTk.exc~	Tue Feb  3 00:13:16 1998
+++ Tk402.003/pTk/mTk/os2/pTk.exc	Sat Nov 29 17:58:00 1997
@@ -0,0 +1,6 @@
+windows.h
+tkWinInt.h
+dllMain.c
+tkMain.c
+tkImgPhoto.c
+testMain.c
diff -pru H:\get\illya.vaes.release\tk4.1\os2/stubs.c Tk402.003.prev/pTk/mTk/os2/stubs.c
--- os2/stubs.c	Thu Dec 11 15:12:30 1997
+++ Tk402.003.prev/pTk/mTk/os2/stubs.c	Tue Feb  3 00:32:00 1998
@@ -290,10 +290,10 @@ XSendEvent(display, w, propagate, event_
 }
 
 void
-XSetCommand(display, w, argv, argc)
+XSetCommand(display, w, args, argc)
     Display* display;
     Window w;
-    char** argv;
+    char** args;
     int argc;
 {
 }
@@ -449,3 +449,142 @@ XGetWindowProperty(display, w, property,
     *prop_return = NULL;
     return 0;			/* failure */
 }
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_FreeXId --
+ *
+ *	This inteface is not needed under OS/2.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_FreeXId(display, xid)
+    Display *display;
+    XID xid;
+{
+}
+
+/* ========================================================================= */
+/* Dummy code */
+
+void XDrawPoints(display, d, gc, points, npoints, mode)
+    Display*		display;
+    Drawable		d;
+    GC			gc;
+    XPoint*		points;
+    int			npoints;
+    int			mode;
+{
+    int i;
+
+    for (i=0; i<npoints; i++) {
+	XDrawLine(display, d, gc, points[i].x, points[i].y,
+	    points[i].x, points[i].y);
+    }
+}
+
+void
+XLowerWindow(display, w)
+    Display* display;
+    Window w;
+{
+    panic("Not implemented: XLowerWindow");
+}
+
+void 
+XChangeGC(
+    Display*		display ,
+    GC			gc,
+    unsigned long	valuemask,
+    XGCValues*		values
+    ) 
+{
+    panic("Not implemented: XChangeGC");
+}
+
+extern Window XCreateWindow(
+    Display*		display,
+    Window		parent,
+    int			x,
+    int			y,
+    unsigned int	width,
+    unsigned int	height,
+    unsigned int	border_width,
+    int			depth,
+    unsigned int	class,
+    Visual*		visual,
+    unsigned long	valuemask,
+    XSetWindowAttributes*	attributes
+    ) 
+{
+    panic("Not implemented: XCreateWindow");
+    return NULL;
+}
+
+/* Used in some new cases in tk*Wm. */
+
+void XReparentWindow(
+    Display*		display,
+    Window		w,
+    Window		parent,
+    int			x,
+    int			y
+    ) {
+    panic("Not implemented: XReparentWindow");
+}
+
+Atom *XListProperties(
+    Display*		display,
+    Window		w,
+    int*		num_prop_return
+    ) {
+    *num_prop_return = 0;
+    return NULL;
+}
+
+Window XGetSelectionOwner(
+    Display*		display,
+    Atom		selection
+    ) {
+    return NULL;
+}
+
+int
+TkSelCvtToX(propPtr, string, type, tkwin, maxBytes)
+    long *propPtr;
+    char *string;		/* String representation of selection. */
+    Atom type;			/* Atom specifying the X format that is
+				 * desired for the selection.  Should not
+				 * be XA_STRING (if so, don't bother calling
+				 * this procedure at all). */
+    Tk_Window tkwin;		/* Window that governs atom conversion. */
+    int maxBytes;		/* Number of 32-bit words contained in the
+				 * result. */
+{
+    panic("Not implemented: TkSelCvtToX");
+    return 0;
+}
+
+char *
+TkSelCvtFromX(propPtr, numValues, type, tkwin)
+    register long *propPtr;	/* Property value from X. */
+    int numValues;		/* Number of 32-bit values in property. */
+    Atom type;			/* Type of property  Should not be
+				 * XA_STRING (if so, don't bother calling
+				 * this procedure at all). */
+    Tk_Window tkwin;		/* Window to use for atom conversion. */
+{
+    panic("Not implemented: TkSelCvtFromX");
+    return NULL;
+}
+
+
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Clipboard.c Tk402.003.prev/pTk/mTk/os2/tkOS2Clipboard.c
--- os2/tkOS2Clipboard.c	Mon Dec 22 15:39:28 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Clipboard.c	Tue Feb  3 00:32:00 1998
@@ -48,7 +48,7 @@ TkSelGetSelection(interp, tkwin, selecti
     Atom selection;		/* Selection to retrieve. */
     Atom target;		/* Desired form in which selection
 				 * is to be returned. */
-    Tk_GetSelProc *proc;	/* Procedure to call to process the
+    Tk_GetXSelProc *proc;	/* Procedure to call to process the
 				 * selection, once it has been retrieved. */
     ClientData clientData;	/* Arbitrary value to pass to proc. */
 {
@@ -80,7 +80,8 @@ TkSelGetSelection(interp, tkwin, selecti
 		}
 		*destPtr = '\0';
 		WinCloseClipbrd(hab);
-		result = (*proc)(clientData, interp, buffer);
+		result = (*proc)(clientData, interp, (long*)buffer,
+				 destPtr - buffer, 8, XA_STRING, NULL);
 		ckfree(buffer);
 		return result;
 	    }
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Cursor.c Tk402.003.prev/pTk/mTk/os2/tkOS2Cursor.c
--- os2/tkOS2Cursor.c	Sat Oct 25 11:10:30 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Cursor.c	Tue Feb  3 00:32:00 1998
@@ -151,14 +151,15 @@ static struct CursorName {
  */
 
 TkCursor *
-TkGetCursorByName(interp, tkwin, string)
+TkGetCursorByName(interp, tkwin, arg)
     Tcl_Interp *interp;		/* Interpreter to use for error reporting. */
     Tk_Window tkwin;		/* Window in which cursor will be used. */
-    Tk_Uid string;		/* Description of cursor.  See manual entry
+    Arg arg;			/* Description of cursor.  See manual entry
 				 * for details on legal syntax. */
 {
     struct CursorName *namePtr;
     TkOS2Cursor *cursorPtr;
+    char *string = LangString(arg);
 
 #ifdef DEBUG
     printf("TkGetCursorByName %s\n", string);
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Font.c Tk402.003.prev/pTk/mTk/os2/tkOS2Font.c
--- os2/tkOS2Font.c	Mon Dec 22 14:49:20 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Font.c	Tue Feb  3 00:54:48 1998
@@ -20,6 +20,7 @@
  */
 static int		NameToFont (_Xconst char *name, TkOS2Font *logfont);
 static int		XNameToFont (_Xconst char *name, TkOS2Font *logfont);
+static char *lastname;
 
 /*
  * Code pages used in this file, 1004 is Windows compatible, 65400 must be
@@ -91,15 +92,16 @@ NameToFont(name, logfont)
     TkOS2Font *logfont;
 {
     int argc, argc2;
-    char **argv, **argv2;
+    Arg *args, *args2;
     int nameLen, i, pointSize = 0;
     Tcl_Interp *dummy = Tcl_CreateInterp();
+    LangFreeProc *freeProc = NULL, *freeProc2 = NULL;
 
 #ifdef DEBUG
     printf("NameToFont %s\n", name);
 #endif
 
-    if (Tcl_SplitList(dummy, (char *) name, &argc, &argv) != TCL_OK) {
+    if (Lang_SplitString(dummy, name, &argc, &args, &freeProc) != TCL_OK) {
 #ifdef DEBUG
     printf("    Tcl_SplitList failed\n");
 #endif
@@ -110,7 +112,6 @@ NameToFont(name, logfont)
         printf("    not 3 args\n");
         for (i=0;i<argc;i++) { printf("    arg[%d]=[%s]\n", i, argv[i]);}
 #endif
-	ckfree((char *) argv);
 	goto nomatch;
     }
 
@@ -149,8 +150,7 @@ NameToFont(name, logfont)
      * Determine the font size.
      */
 
-    if (Tcl_GetInt(dummy, argv[1], &pointSize) != TCL_OK) {
-	ckfree((char *) argv);
+    if (Tcl_GetInt(dummy, args[1], &pointSize) != TCL_OK) {
 	goto nomatch;
     }
     logfont->fattrs.lMaxBaselineExt = POINTTOPIX(pointSize);
@@ -164,41 +164,51 @@ NameToFont(name, logfont)
      * Apply any style modifiers.
      */
 	
-    if (Tcl_SplitList(dummy, (char *) argv[2], &argc2, &argv2) != TCL_OK) {
+    if (Lang_SplitString(dummy, LangString(args[2]), &argc2, &args2, &freeProc2) != TCL_OK) {
 	ckfree((char*) argv);
 	goto nomatch;
     }
     for (i = 0; i < argc2; i++) {
-	if (stricmp(argv2[i], "bold") == 0) {
+	char *s = LangString(args2[i]);
+	if (stricmp(s, "bold") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_BOLD;
-	} else if (stricmp(argv2[i], "heavy") == 0) {
+	} else if (stricmp(s, "heavy") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_BOLD;
-	} else if (stricmp(argv2[i], "semibold") == 0) {
+	} else if (stricmp(s, "semibold") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_BOLD;
-	} else if (stricmp(argv2[i], "extrabold") == 0) {
+	} else if (stricmp(s, "extrabold") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_BOLD;
-	} else if (stricmp(argv2[i], "italic") == 0) {
+	} else if (stricmp(s, "italic") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_ITALIC;
-	} else if (stricmp(argv2[i], "oblique") == 0) {
+	} else if (stricmp(s, "oblique") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_ITALIC;
-	} else if (stricmp(argv2[i], "underline") == 0) {
+	} else if (stricmp(s, "underline") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_UNDERSCORE;
-	} else if (stricmp(argv2[i], "strikeout") == 0) {
+	} else if (stricmp(s, "strikeout") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_STRIKEOUT;
 	} else {
 	    /* ignore for now */
 	}
     }
 
-    ckfree((char *) argv);
-    ckfree((char *) argv2);
+    if (freeProc2) {
+       (*freeProc2)(argc2,args2);
+    }
+    if (freeProc) {
+       (*freeProc)(argc,args);
+    }
     return True;
 
     nomatch:
 #ifdef DEBUG
     printf("NameToFont: nomatch\n");
 #endif
-    Tcl_DeleteInterp(dummy);
+    if (freeProc2) {
+       (*freeProc2)(argc2,args2);
+    }
+    if (freeProc) {
+       (*freeProc)(argc,args);
+    }
     return False;
 }
 
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Image.c Tk402.003.prev/pTk/mTk/os2/tkOS2Image.c
--- os2/tkOS2Image.c	Mon Oct 27 16:17:10 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Image.c	Tue Feb  3 00:32:00 1998
@@ -55,6 +55,14 @@ PutPixel(image, x, y, pixel)
     return 0;
 }
 
+static int
+imfree(XImage *ximage)
+{
+    if (ximage->data) ckfree(ximage->data);
+    ckfree(ximage);
+    return 1;				/* XXXX ???? */
+}
+
 /*
  *----------------------------------------------------------------------
  *
@@ -125,7 +133,7 @@ XCreateImage(display, visual, depth, for
         imagePtr->green_mask = visual->green_mask;
         imagePtr->blue_mask = visual->blue_mask;
         imagePtr->f.create_image = NULL;
-        imagePtr->f.destroy_image = NULL;
+        imagePtr->f.destroy_image = &imfree;
         imagePtr->f.get_pixel = NULL;
         imagePtr->f.sub_image = NULL;
         imagePtr->f.add_pixel = NULL;
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Init.c Tk402.003.prev/pTk/mTk/os2/tkOS2Init.c
--- os2/tkOS2Init.c	Tue Dec 23 15:19:24 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Init.c	Tue Feb  3 00:32:00 1998
@@ -38,6 +38,7 @@ TkOS2Font	logfonts[255];		/* List of log
 LONG		nextColor;		/* Next free index in color table */
 LONG		rc;			/* For checking return values */
 
+#if 0
 /*
  * The following string is the startup script executed in new
  * interpreters.  It looks on disk in several different directories
@@ -75,6 +76,8 @@ static char *initScript =
     error $msg\n\
 }\n\
 init";
+
+#endif 
 
 /*
  *----------------------------------------------------------------------
@@ -146,12 +149,24 @@ TkPlatformInit(interp)
      * tk.dll library.
      */
 
+#ifdef _LANG				/* Perl */
+    Var variable;
+
+    variable = LangFindVar( interp, NULL,  "tk_library");
+    libDir = LangString(Tcl_GetVar(interp, variable, TCL_GLOBAL_ONLY));
+    if (libDir == NULL || *libDir == '\0') {
+       Tcl_SetVar(interp, variable, TK_LIBRARY, TCL_GLOBAL_ONLY);
+    }
+    LangFreeVar(variable);
+    return TCL_OK;
+#else
     libDir = Tcl_GetVar(interp, "tk_library", TCL_GLOBAL_ONLY);
     if (libDir == NULL) {
         Tcl_SetVar(interp, "tk_library", ".", TCL_GLOBAL_ONLY);
     }
 
     return Tcl_Eval(interp, initScript);
+#endif
 }
 
 /*
@@ -187,7 +202,11 @@ TkOS2InitPM (void)
     hab = WinInitialize (0);
 
     /* Create message queue, increased size from 10 */
-    hmq= WinCreateMsgQueue (hab, 64);
+#ifdef REGISTER_MQ
+    /* Postponed until windows are created */
+#else
+    hmq = WinCreateMsgQueue (hab, 64);
+#endif 
 
     /* Determine system values */
     xScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
@@ -317,7 +336,41 @@ TkOS2ExitPM (void)
     GpiSetBitmap(globalPS, NULLHANDLE);
     GpiDestroyPS(globalPS);
     DevCloseDC(hScreenDC);
+#ifdef DEREGISTER_MQ
+    DEREGISTER_MQ;
+#else
     WinDestroyMsgQueue(hmq);
+#endif
     WinTerminate(hab);
     hmq= hab= 0;
 }
+
+void
+Register_MQ(void)
+{
+    PPIB pib;
+    PTIB tib;
+
+    if (hmq)
+	return;
+    DosGetInfoBlocks(&tib, &pib);
+    /* Try morphing into a PM application. */
+    if (pib->pib_ultype == 2)		/* VIO */
+	pib->pib_ultype = 3;
+    hmq = WinCreateMsgQueue (hab, 64);
+    if (!hmq) {
+	static int cnt;
+	if (cnt++)
+	    _exit(188);			/* Panic can try to create a window. */
+	panic("Cannot create a message queue, am I a PM application?");
+    }
+}
+
+void
+Deregister_MQ(void)
+{
+    if (hmq) {
+	WinDestroyMsgQueue(hmq);
+    }
+}
+
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Int.h Tk402.003.prev/pTk/mTk/os2/tkOS2Int.h
--- os2/tkOS2Int.h	Thu Dec 18 15:11:18 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Int.h	Tue Feb  3 00:32:00 1998
@@ -28,6 +28,26 @@
 #define OS2
 #endif
 
+#ifdef __PM_WIN__		/* A file expects Win32 interface. */
+typedef HDC HDC_os2;			/* Now can redefine. */
+#    define WORD unsigned short
+#    define TkWinDrawable TkOS2Drawable
+#    define TWD_BITMAP	TOD_BITMAP
+#    define DeleteObject	GpiDeleteBitmap
+#    define HDC		HPS
+#    define SelectObject	GpiSetBitmap
+#    define DeleteDC		WinReleasePS
+#    define TkWinGetDrawableDC		TkOS2GetDrawablePS
+#    define TkWinReleaseDrawableDC	TkOS2ReleaseDrawablePS
+#    define TkWinDCState	TkOS2PSState
+#endif
+
+typedef struct BITMAPINFOHEADER2_2colors  {
+    BITMAPINFOHEADER2 header;
+    RGB2 colors[2];
+} BITMAPINFOHEADER2_2colors;
+
+
 /*
  * A data structure of the following type holds information for
  * each window manager protocol (such as WM_DELETE_WINDOW) for
@@ -42,17 +62,15 @@ typedef struct ProtocolHandler {
 				 * the same top-level window, or NULL for
 				 * end of list. */
     Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
-    char command[4];		/* Tcl command to invoke when a client
-				 * message for this protocol arrives. 
-				 * The actual size of the structure varies
-				 * to accommodate the needs of the actual
-				 * command. THIS MUST BE THE LAST FIELD OF
-				 * THE STRUCTURE. */
+    LangCallback *command;	/* command to invoke when a client
+				 * message for this protocol arrives. */
 } ProtocolHandler;
 
 #define HANDLER_SIZE(cmdLength) \
     ((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))
 
+void ProtocolFree _ANSI_ARGS_((char *clientData));
+
 /*
  * A data structure of the following type holds window-manager-related
  * information for each top-level window in an application.
@@ -175,6 +193,7 @@ typedef struct TkWmInfo {
 				 * property, or NULL. */
     int flags;			/* Miscellaneous flags, defined below. */
     struct TkWmInfo *nextPtr;	/* Next in list of all top-level windows. */
+    Arg  cmdArg;
 } WmInfo;
 
 /*
@@ -427,5 +446,14 @@ extern TkOS2Font logfonts[];	/* List of 
 extern LONG nextColor;		/* Next free index in color table */
 extern LONG rc;			/* For checking return values */
 extern unsigned long dllHandle;	/* Handle of the Tk DLL */
+
+#ifdef _LANG				/* Perl */
+#  define REGISTER_MQ Register_MQ()
+#  define DEREGISTER_MQ Deregister_MQ()
+
+extern void Register_MQ();
+extern void Deregister_MQ();
+
+#endif 
 
 #endif /* _OS2INT */
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Pixmap.c Tk402.003.prev/pTk/mTk/os2/tkOS2Pixmap.c
--- os2/tkOS2Pixmap.c	Tue Dec 23 15:53:04 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Pixmap.c	Tue Feb  3 00:33:04 1998
@@ -18,7 +18,7 @@
 /*
  *----------------------------------------------------------------------
  *
- * XCreatePixmap --
+ * Tk_GetPixmap --
  *
  *	Creates an in memory drawing surface.
  *
@@ -32,12 +32,12 @@
  */
 
 Pixmap
-XCreatePixmap(display, d, width, height, depth)
+Tk_GetPixmap(display, d, width, height, depth)
     Display* display;
     Drawable d;
-    unsigned int width;
-    unsigned int height;
-    unsigned int depth;
+    int width;
+    int height;
+    int depth;
 {
     TkOS2Drawable *newTodPtr, *todPtr;
     BITMAPINFOHEADER2 bmpInfo;
@@ -58,7 +58,7 @@ XCreatePixmap(display, d, width, height,
     todPtr = (TkOS2Drawable *)d;
     if (todPtr->type != TOD_BITMAP) {
 #ifdef DEBUG
-        printf("XCreatePixmap %x, depth %d, parent %x, %dx%d\n", newTodPtr,
+        printf("Tk_GetPixmap %x, depth %d, parent %x, %dx%d\n", newTodPtr,
                depth, todPtr->window.handle, sizl.cx, sizl.cy);
 #endif
         newTodPtr->bitmap.parent = todPtr->window.handle;
@@ -70,14 +70,14 @@ XCreatePixmap(display, d, width, height,
         }
     } else {
 #ifdef DEBUG
-        printf("XCreatePixmap %x, depth %d, parent (bitmap) %x, %dx%d\n",
+        printf("Tk_GetPixmap %x, depth %d, parent (bitmap) %x, %dx%d\n",
                newTodPtr, depth, todPtr->bitmap.parent, sizl.cx, sizl.cy);
 #endif
         newTodPtr->bitmap.colormap = todPtr->bitmap.colormap;
         newTodPtr->bitmap.parent = todPtr->bitmap.parent;
     }
 #ifdef DEBUG
-    printf("XCreatePixmap: colormap %x, parent %x\n",
+    printf("Tk_GetPixmap: colormap %x, parent %x\n",
            newTodPtr->bitmap.colormap, newTodPtr->bitmap.parent);
 #endif
     bmpInfo.cbFix = 16L;
@@ -89,40 +89,40 @@ XCreatePixmap(display, d, width, height,
                                      (PDEVOPENDATA)&dop, NULLHANDLE);
     if (newTodPtr->bitmap.dc == DEV_ERROR) {
 #ifdef DEBUG
-        printf("DevOpenDC failed in XCreatePixmap\n");
+        printf("DevOpenDC failed in Tk_GetPixmap\n");
 #endif
         ckfree((char *) newTodPtr);
         return (Pixmap)None;
     }
 #ifdef DEBUG
-    printf("DevOpenDC in XCreatePixmap returns %x\n", newTodPtr->bitmap.dc);
+    printf("DevOpenDC in Tk_GetPixmap returns %x\n", newTodPtr->bitmap.dc);
 #endif
     newTodPtr->bitmap.hps = GpiCreatePS(hab, newTodPtr->bitmap.dc, &sizl,
                                         PU_PELS | GPIT_MICRO | GPIA_ASSOC);
     if (newTodPtr->bitmap.hps == GPI_ERROR) {
         DevCloseDC(newTodPtr->bitmap.dc);
 #ifdef DEBUG
-        printf("GpiCreatePS failed in XCreatePixmap\n");
+        printf("GpiCreatePS failed in Tk_GetPixmap\n");
 #endif
         ckfree((char *) newTodPtr);
         return (Pixmap)None;
     }
 #ifdef DEBUG
-    printf("GpiCreatePS in XCreatePixmap returns %x\n", newTodPtr->bitmap.hps);
+    printf("GpiCreatePS in Tk_GetPixmap returns %x\n", newTodPtr->bitmap.hps);
 #endif
     newTodPtr->bitmap.handle = GpiCreateBitmap(newTodPtr->bitmap.hps,
                                                &bmpInfo, 0L, NULL, NULL);
 
     if (newTodPtr->bitmap.handle == NULLHANDLE) {
 #ifdef DEBUG
-        printf("GpiCreateBitmap ERROR %x in XCreatePixmap\n",
+        printf("GpiCreateBitmap ERROR %x in Tk_GetPixmap\n",
                WinGetLastError(hab));
 #endif
 	ckfree((char *) newTodPtr);
 	return (Pixmap)None;
     }
 #ifdef DEBUG
-    printf("GpiCreateBitmap in XCreatePixmap returns %x\n",
+    printf("GpiCreateBitmap in Tk_GetPixmap returns %x\n",
            newTodPtr->bitmap.handle);
 #endif
     sizl.cx = width;
@@ -162,7 +162,7 @@ XCreatePixmap(display, d, width, height,
 /*
  *----------------------------------------------------------------------
  *
- * XFreePixmap --
+ * Tk_FreePixmap --
  *
  *	Release the resources associated with a pixmap.
  *
@@ -170,13 +170,13 @@ XCreatePixmap(display, d, width, height,
  *	None.
  *
  * Side effects:
- *	Deletes the bitmap created by XCreatePixmap.
+ *	Deletes the bitmap created by Tk_GetPixmap.
  *
  *----------------------------------------------------------------------
  */
 
 void
-XFreePixmap(display, pixmap)
+Tk_FreePixmap(display, pixmap)
     Display* display;
     Pixmap pixmap;
 {
@@ -184,7 +184,7 @@ XFreePixmap(display, pixmap)
     HBITMAP hbm;
 
 #ifdef DEBUG
-    printf("XFreePixmap %x\n", todPtr);
+    printf("Tk_FreePixmap %x\n", todPtr);
 #endif
 
     display->request++;
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Port.h Tk402.003.prev/pTk/mTk/os2/tkOS2Port.h
--- os2/tkOS2Port.h	Thu Sep 11 15:38:46 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Port.h	Tue Feb  3 00:32:00 1998
@@ -49,6 +49,11 @@
 
 #define REDO_KEYSYM_LOOKUP
 
+/* Newer stuff: */
+#define TkGetNativeProlog(interp) TkGetProlog(interp)
+#define TkFreeWindowId(dispPtr,w)
+#define TkInitXId(dispPtr)
+
 /*
  * The following macro checks to see whether there is buffered
  * input data available for a stdio FILE.
@@ -75,6 +80,13 @@
 #define XSynchronize(display, bool) {display->request++;}
 #define XSync(display, bool) {display->request++;}
 #define XVisualIDFromVisual(visual) (visual->visualid)
+
+#define XPutImage(display, dr, gc, i, a, b, c, d, e, f) \
+      TkPutImage(NULL, 0, display, dr, gc, i, a, b, c, d, e, f)
+#define XDefaultVisual(display, screen) ((screen)->root_visual)
+#define XDefaultScreen(display) ((display)->screens)
+#define XDefaultColormap(display, screen) ((screen)->cmap)
+#define XDefaultDepth(display, screen) ((screen)->root_depth)
 
 #ifndef __EMX__
 
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Window.c Tk402.003.prev/pTk/mTk/os2/tkOS2Window.c
--- os2/tkOS2Window.c	Thu Oct 30 16:16:40 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Window.c	Tue Feb  3 00:32:00 1998
@@ -54,6 +54,10 @@ TkMakeWindow(winPtr, parent)
            winPtr->changes.width, winPtr->changes.height);
 #endif
 
+#ifdef REGISTER_MQ
+    REGISTER_MQ;
+#endif
+
     todPtr = (TkOS2Drawable*) ckalloc(sizeof(TkOS2Drawable));
     if (todPtr == NULL) {
 	return (Window)None;
@@ -153,7 +157,9 @@ XDestroyWindow(display, w)
 #ifdef DEBUG
         printf("    ckfree todPtr %x\n", todPtr);
 #endif
+#if 0			/* Should have been done during WM_DESTROY above */
         ckfree((char *)todPtr);
+#endif
         todPtr= NULL;
     } else if (!(winPtr->flags & TK_PARENT_DESTROYED)) {
         rc = WinDestroyWindow(hwnd);
diff -pru H:\get\illya.vaes.release\tk4.1\os2/tkOS2Wm.c Tk402.003.prev/pTk/mTk/os2/tkOS2Wm.c
--- os2/tkOS2Wm.c	Thu Dec 18 15:54:38 1997
+++ Tk402.003.prev/pTk/mTk/os2/tkOS2Wm.c	Tue Feb  3 01:02:08 1998
@@ -75,6 +75,19 @@ static void	TopLevelEventProc _ANSI_ARGS
 static void	TopLevelReqProc _ANSI_ARGS_((ClientData dummy,
                     Tk_Window tkwin));
 static void	UpdateGeometryInfo _ANSI_ARGS_((ClientData clientData));
+static void TkWmFreeCmd _ANSI_ARGS_((WmInfo *wmPtr));
+static void           IdleMapToplevel _ANSI_ARGS_((ClientData clientData));
+static void           UnmanageGeometry _ANSI_ARGS_((Tk_Window tkwin));
+
+
+void
+ProtocolFree(clientData)
+char *clientData;
+{ProtocolHandler *p = (ProtocolHandler *) clientData;
+ LangFreeCallback(p->command);
+ ckfree(p);
+}
+
 
 /*
  *----------------------------------------------------------------------
@@ -288,6 +301,7 @@ TkWmNewWindow(winPtr)
     wmPtr->flags = WM_NEVER_MAPPED;
     wmPtr->nextPtr = firstWmPtr;
     firstWmPtr = wmPtr;
+    wmPtr->cmdArg = NULL;
 
     /*
      * Tk must monitor structure events for top-level windows, in order
@@ -304,6 +318,23 @@ TkWmNewWindow(winPtr)
 
     Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
 }
+
+static void
+TkWmFreeCmd(wmPtr)
+WmInfo *wmPtr;
+{
+    if (wmPtr->cmdArgv != NULL) {
+	ckfree((char *) wmPtr->cmdArgv);
+        wmPtr->cmdArgv = NULL;
+    }
+    if (wmPtr->cmdArg) {
+        LangFreeArg(wmPtr->cmdArg,TCL_DYNAMIC);
+        wmPtr->cmdArg = NULL;
+    }
+}
+
+
+
 
 /*
  *--------------------------------------------------------------
@@ -350,6 +381,10 @@ TkWmMapWindow(winPtr)
         Tcl_HashEntry *hPtr;
         int new;
 
+#ifdef REGISTER_MQ
+	REGISTER_MQ;
+#endif
+
 	wmPtr->flags &= ~WM_NEVER_MAPPED;
 
 	/*
@@ -550,6 +585,13 @@ TkWmMapWindow(winPtr)
          * Add the window and handle to the window table.
          */
 
+	{
+	   static HPOINTER id;
+	   if (id == 0)
+		id = WinLoadPointer(HWND_DESKTOP, TkOS2GetTkModule(), 0x1000);
+	   WinSendMsg(frame, WM_SETICON, (MPARAM)id, NULL);
+
+	}
         parentPtr->window.handle = frame;
         hPtr = Tcl_CreateHashEntry(&windowTable, (char *)frame, &new);
         if (!new) {
@@ -616,7 +658,7 @@ TkWmMapWindow(winPtr)
 	return;
     } else {
 	if (wmPtr->flags & WM_UPDATE_PENDING) {
-	    Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
+	    Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
 	}
 	UpdateGeometryInfo((ClientData) winPtr);
 
@@ -798,6 +840,7 @@ TkWmUnmapWindow(winPtr)
  *--------------------------------------------------------------
  */
 
+
 void
 TkWmDeadWindow(winPtr)
     TkWindow *winPtr;		/* Top-level window that's being deleted. */
@@ -855,7 +898,7 @@ TkWmDeadWindow(winPtr)
 
 	protPtr = wmPtr->protPtr;
 	wmPtr->protPtr = protPtr->nextPtr;
-	Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
+	Tcl_EventuallyFree((ClientData) protPtr, ProtocolFree);
     }
     if (wmPtr->cmdArgv != NULL) {
 	ckfree((char *) wmPtr->cmdArgv);
@@ -943,13 +986,14 @@ Tk_WmCmd(clientData, interp, argc, argv)
 				 * interpreter. */
     Tcl_Interp *interp;		/* Current interpreter. */
     int argc;			/* Number of arguments. */
-    char **argv;		/* Argument strings. */
+    Arg *args;			/* Argument strings. */
 {
     Tk_Window tkwin = (Tk_Window) clientData;
     TkWindow *winPtr;
     register WmInfo *wmPtr;
     int c;
     size_t length;
+    int i; 
 
 #ifdef DEBUG
     printf("Tk_WmCmd\n");
@@ -988,9 +1032,54 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	return TCL_ERROR;
     }
     if (!(winPtr->flags & TK_TOP_LEVEL)) {
-	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
+	if ((c == 'r') && (strncmp(argv[1], "release", length) == 0)) {
+	    if (winPtr->parentPtr == NULL) {
+		Tcl_AppendResult(interp, "Cannot release main window", NULL);
+		return TCL_ERROR;
+	    }
+
+	    /* detach the window from its gemoetry manager, if any */
+	    UnmanageGeometry(tkwin);
+	    if (winPtr->window == None) {
+		/* Good, the window is not created yet, we still have time
+		 * to make it an legitimate toplevel window
+		 */
+		winPtr->dirtyAtts |= CWBorderPixel;
+		winPtr->atts.event_mask |= StructureNotifyMask;
+
+		winPtr->flags |= TK_TOP_LEVEL;
+		TkWmNewWindow(winPtr);
+		Tcl_DoWhenIdle(IdleMapToplevel, (ClientData) winPtr);
+	    } else {
+		Window parent;
+		XSetWindowAttributes atts;
+
+		atts.event_mask = winPtr->atts.event_mask;
+		atts.event_mask |= StructureNotifyMask;
+
+		Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWEventMask,
+		    &atts);
+
+		if (winPtr->flags & TK_MAPPED) {
+		    Tk_UnmapWindow((Tk_Window)winPtr);
+		}
+		parent = XRootWindow(winPtr->display, winPtr->screenNum);
+		XReparentWindow(winPtr->display, winPtr->window,
+		    parent, 0, 0);
+
+		/* Should flush the events here */
+		winPtr->flags |= TK_TOP_LEVEL;
+		TkWmNewWindow(winPtr);
+
+		Tcl_DoWhenIdle(IdleMapToplevel, (ClientData) winPtr);
+	    }
+	    return TCL_OK;
+	}
+	else {
+	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
 		"\" isn't a top-level window", (char *) NULL);
-	return TCL_ERROR;
+	    return TCL_ERROR;
+	}
     }
     wmPtr = winPtr->wmInfoPtr;
     if ((c == 'a') && (strncmp(argv[1], "aspect", length) == 0)) {
@@ -1031,6 +1120,114 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	    wmPtr->sizeHintsFlags |= PAspect;
 	}
 	goto updateGeom;
+    } else if ((c == 'c') && (strncmp(argv[1], "capture", length) == 0)) {
+#if 0
+	if (winPtr->parentPtr == NULL) {
+	    Tcl_AppendResult(interp, "Cannot capture main window", NULL);
+	    return TCL_ERROR;
+	}
+
+	if ((winPtr->flags & TK_TOP_LEVEL)==0) {
+	    /* Window is already captured */
+	    return TCL_OK;
+	}
+
+	if (winPtr->window == None) {
+	    /* cause this and parent window to exist*/
+	    winPtr->atts.event_mask &= ~StructureNotifyMask;
+	    winPtr->flags &= ~TK_TOP_LEVEL;
+
+	    UnmanageGeometry((Tk_Window) winPtr);
+	    Tk_DeleteEventHandler((Tk_Window)winPtr, StructureNotifyMask,
+	        TopLevelEventProc, (ClientData) winPtr);
+	} else {
+	    XEvent event;
+	    unsigned long serial;
+	    XSetWindowAttributes atts;
+	    int i, done1 = 0, done2 = 0, count = 0;
+
+	    /* wmDontReparent is set to 2 if it is determined that
+	     * the window manager does not do a reparent after 
+	     * "wm capture" does the reparent. If that's the case, we don't
+	     * need to perform the hack
+	     */
+	    static int wmDontReparent = 0;
+
+
+	    /* Hack begins here --
+	     *
+	     * To change a widget from  a toplevel window to a non-toplevel
+	     * window, we reparent it (from the root window) to its
+	     * real (TK) parent. However, after we do that, some window 
+	     * managers (mwm in particular), will reparent the widget, again,
+	     * to its decoration frames. In that case, we need to perform the
+	     * reparenting again.
+	     *
+	     * The following code keeps reparenting the widget to its
+	     * real parent until it detects the stupid move by the window
+	     * manager. After that, it reparents once more and the widget
+	     * will be finally reparented to its real parent.
+	     */
+	    while (done2 == 0) {
+		XUnmapWindow(winPtr->display, winPtr->window);
+		XReparentWindow(winPtr->display, winPtr->window,
+		    winPtr->parentPtr->window, 0, 0);
+		if (wmDontReparent >= 2) {
+		    goto done;
+		}
+
+		do {
+		    if (WaitForEvent(winPtr->display, winPtr->window,
+		    	StructureNotifyMask, &event) != TCL_OK) {
+			goto done;
+		    }
+		    Tk_HandleEvent(&event);
+		} while (event.type != ReparentNotify);
+
+		if (event.xreparent.parent == winPtr->parentPtr->window ) {
+		    if (done1 == 1) {
+			done2 = 1;
+			if (wmTracing) {
+			    printf("tixdebug: done reparenting.\n");
+			}
+		    } else {
+			++ count;
+		    }
+		} else {
+		    if (wmTracing) {
+			printf("tixdebug: wm reparenting, retry ...\n");
+		    }
+		    done1 = 1;
+		}
+		if (count > 15) {
+		    ++ wmDontReparent;
+		    if (wmTracing) {
+			printf("tixdebug: window manager doesn't reparent.\n");
+		    }
+		    goto done;
+		}
+	    }
+	    /* Hack ends here
+	     */
+
+	  done:
+	    /* clear those attributes that non-toplevel windows don't
+	     * possess
+	     */
+	    winPtr->flags &= ~TK_TOP_LEVEL;
+	    atts.event_mask = winPtr->atts.event_mask;
+	    atts.event_mask &= ~StructureNotifyMask;
+	    Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWEventMask,
+		&atts);
+
+	    Tk_DeleteEventHandler((Tk_Window)winPtr, StructureNotifyMask,
+	        TopLevelEventProc, (ClientData) winPtr);
+	    UnmanageGeometry((Tk_Window) winPtr);
+	}
+#else  /* !0 */
+	panic("capture option not supported");
+#endif /* !0 */
+	return TCL_OK;
     } else if ((c == 'c') && (strncmp(argv[1], "client", length) == 0)
 	    && (length >= 2)) {
 	if ((argc != 3) && (argc != 4)) {
@@ -1077,7 +1274,8 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	TkWindow **cmapList;
 	TkWindow *winPtr2;
 	int i, windowArgc, gotToplevel = 0;
-	char **windowArgv;
+	Arg *windowArgs;
+        LangFreeProc *freeProc = NULL;
 
 	if ((argc != 3) && (argc != 4)) {
 	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
@@ -1096,18 +1294,19 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	    }
 	    return TCL_OK;
 	}
-	if (Tcl_SplitList(interp, argv[3], &windowArgc, &windowArgv)
+	if (Lang_SplitList(interp, args[3], &windowArgc, &windowArgs, &freeProc)
 		!= TCL_OK) {
 	    return TCL_ERROR;
 	}
 	cmapList = (TkWindow **) ckalloc((unsigned)
 		((windowArgc+1)*sizeof(TkWindow*)));
 	for (i = 0; i < windowArgc; i++) {
-	    winPtr2 = (TkWindow *) Tk_NameToWindow(interp, windowArgv[i],
+	    winPtr2 = (TkWindow *) Tk_NameToWindow(interp, LangString(windowArgs[i]),
 		    tkwin);
 	    if (winPtr2 == NULL) {
 		ckfree((char *) cmapList);
-		ckfree((char *) windowArgv);
+                if (freeProc)
+                 (*freeProc)(windowArgc,windowArgs); 
 		return TCL_ERROR;
 	    }
 	    if (winPtr2 == winPtr) {
@@ -1131,7 +1330,6 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	}
 	wmPtr->cmapList = cmapList;
 	wmPtr->cmapCount = windowArgc;
-	ckfree((char *) windowArgv);
 
 	/*
 	 * Now we need to force the updated colormaps to be installed.
@@ -1148,11 +1346,14 @@ Tk_WmCmd(clientData, interp, argc, argv)
                                         WM_REALIZEPALETTE, 0);
             }
         }
+        if (freeProc)
+	    (*freeProc)(windowArgc,windowArgs);
 	return TCL_OK;
     } else if ((c == 'c') && (strncmp(argv[1], "command", length) == 0)
 	    && (length >= 3)) {
 	int cmdArgc;
-	char **cmdArgv;
+	Arg *cmdArgs = NULL;
+        LangFreeProc *freeProc = NULL;
 
 	if ((argc != 3) && (argc != 4)) {
 	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
@@ -1161,16 +1362,14 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	    return TCL_ERROR;
 	}
 	if (argc == 3) {
-	    if (wmPtr->cmdArgv != NULL) {
-		interp->result = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);
-		interp->freeProc = TCL_DYNAMIC;
+	    if (wmPtr->cmdArg != NULL) {
+                Tcl_ArgResult(interp,wmPtr->cmdArg);
 	    }
 	    return TCL_OK;
 	}
-	if (argv[3][0] == 0) {
+	if (LangNull(args[3])) {
 	    if (wmPtr->cmdArgv != NULL) {
-		ckfree((char *) wmPtr->cmdArgv);
-		wmPtr->cmdArgv = NULL;
+                TkWmFreeCmd(wmPtr);
 		if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
 		    XDeleteProperty(winPtr->display, winPtr->window,
 			    Tk_InternAtom((Tk_Window) winPtr, "WM_COMMAND"));
@@ -1178,17 +1377,24 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	    }
 	    return TCL_OK;
 	}
-	if (Tcl_SplitList(interp, argv[3], &cmdArgc, &cmdArgv) != TCL_OK) {
+	if (Lang_SplitList(interp, args[3], &cmdArgc, &cmdArgs, &freeProc) != TCL_OK) {
 	    return TCL_ERROR;
 	}
 	if (wmPtr->cmdArgv != NULL) {
-	    ckfree((char *) wmPtr->cmdArgv);
+         TkWmFreeCmd(wmPtr);
 	}
+        wmPtr->cmdArgv = (char **) ckalloc(cmdArgc*sizeof(char *));
 	wmPtr->cmdArgc = cmdArgc;
-	wmPtr->cmdArgv = cmdArgv;
+	wmPtr->cmdArg  = LangCopyArg(args[3]);
+        for (i=0; i < cmdArgc; i++)
+         {
+          wmPtr->cmdArgv[i] = LangString(cmdArgs[i]);
+         }
 	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
-	    XSetCommand(winPtr->display, winPtr->window, cmdArgv, cmdArgc);
+	    XSetCommand(winPtr->display, winPtr->window, wmPtr->cmdArgv, wmPtr->cmdArgc);
 	}
+	if (freeProc)
+	    (*freeProc)(cmdArgc,cmdArgs);
     } else if ((c == 'd') && (strncmp(argv[1], "deiconify", length) == 0)) {
 	if (argc != 3) {
 	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
@@ -1648,6 +1854,31 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	atts.override_redirect = (boolean) ? True : False;
 	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
 		&atts);
+    } else if ((c == 's')
+	    && (strncmp(argv[1], "saveunder", length) == 0)) {
+	int boolean;
+	XSetWindowAttributes atts;
+
+	if ((argc != 3) && (argc != 4)) {
+	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
+		    argv[0], " saveunder window ?boolean?\"",
+		    (char *) NULL);
+	    return TCL_ERROR;
+	}
+	if (argc == 3) {
+	    if (Tk_Attributes((Tk_Window) winPtr)->save_under) {
+		interp->result = "1";
+	    } else {
+		interp->result = "0";
+	    }
+	    return TCL_OK;
+	}
+	if (Tcl_GetBoolean(interp, argv[3], &boolean) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	atts.save_under = (boolean) ? True : False;
+	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWSaveUnder,
+		&atts);
     } else if ((c == 'p') && (strncmp(argv[1], "positionfrom", length) == 0)
 	    && (length >= 2)) {
 	if ((argc != 3) && (argc != 4)) {
@@ -1713,7 +1944,7 @@ Tk_WmCmd(clientData, interp, argc, argv)
 	    for (protPtr = wmPtr->protPtr; protPtr != NULL;
 		    protPtr = protPtr->nextPtr) {
 		if (protPtr->protocol == protocol) {
-		    interp->result = protPtr->command;
+                    Tcl_ArgResult(interp,LangCallbackArg(protPtr->command));
 		    return TCL_OK;
 		}
 	    }
@@ -1734,19 +1965,23 @@ Tk_WmCmd(clientData, interp, argc, argv)
 		} else {
 		    prevPtr->nextPtr = protPtr->nextPtr;
 		}
-		Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
+		Tcl_EventuallyFree((ClientData) protPtr, ProtocolFree);
 		break;
 	    }
 	}
 	cmdLength = strlen(argv[4]);
 	if (cmdLength > 0) {
-	    protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
+	    protPtr = (ProtocolHandler *) ckalloc(sizeof(ProtocolHandler));
 	    protPtr->protocol = protocol;
 	    protPtr->nextPtr = wmPtr->protPtr;
 	    wmPtr->protPtr = protPtr;
 	    protPtr->interp = interp;
-	    strcpy(protPtr->command, argv[4]);
+	    protPtr->command = LangMakeCallback(args[4]);
 	}
+    } else if ((c == 'r') && (strncmp(argv[1], "release", length) == 0)) {
+	Tcl_AppendResult(interp, "Window \"", argv[2],
+	    "\" is already a toplevel", NULL);
+	return TCL_ERROR;
     } else if ((c == 'r') && (strncmp(argv[1], "resizable", length) == 0)) {
         int width, height;
 
@@ -2696,7 +2931,7 @@ Tk_MoveToplevelWindow(tkwin, x, y)
 
     if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
 	if (wmPtr->flags & WM_UPDATE_PENDING) {
-	    Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
+	    Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
 	}
 	UpdateGeometryInfo((ClientData) winPtr);
     }
@@ -2748,7 +2983,7 @@ TkWmProtocolEventProc(winPtr, eventPtr)
 	    Tcl_Preserve((ClientData) protPtr);
             interp = protPtr->interp;
             Tcl_Preserve((ClientData) interp);
-            result = Tcl_GlobalEval(interp, protPtr->command);
+            result = LangDoCallback(protPtr->interp, protPtr->command, 0, 0);
 	    if (result != TCL_OK) {
                 Tcl_AddErrorInfo(interp, "\n    (command for \"");
                 Tcl_AddErrorInfo(interp,
@@ -3459,6 +3694,64 @@ InvalidateSubTree(winPtr, colormap)
              InvalidateSubTree(childPtr, colormap);
          }
      }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IdleMapTopLevel -- stolen from tkFrame.c
+ *
+ *	This procedure is invoked as a when-idle handler to map a
+ *	newly-released toplevel window
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The window given by the clientData argument is mapped.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+IdleMapToplevel(clientData)
+    ClientData clientData;
+{
+    TkWindow * winPtr = (TkWindow *) clientData;
+
+    if (winPtr->flags & TK_TOP_LEVEL) {
+	Tk_MapWindow((Tk_Window)winPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UnmanageGeometry --
+ *
+ *	Since there is a bug in tkGeometry.c, we need this routine to
+ *	replace Tk_ManageGeometry(tkwin, NULL, NULL);
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The window given by the clientData argument is mapped.
+ *
+ *----------------------------------------------------------------------
+ */
+static void UnmanageGeometry(tkwin)
+    Tk_Window tkwin;		/* Window whose geometry is to
+				 * be unmanaged.*/
+{
+    register TkWindow *winPtr = (TkWindow *) tkwin;
+
+    if ((winPtr->geomMgrPtr != NULL) &&
+	(winPtr->geomMgrPtr->lostSlaveProc != NULL)) {
+	(*winPtr->geomMgrPtr->lostSlaveProc)(winPtr->geomData, tkwin);
+    }
+
+    winPtr->geomMgrPtr = NULL;
+    winPtr->geomData = NULL;
 }
 
 /*
