Apply this after the 'common patch'.

diff -pru H:\get\illya.vaes4\tk4.1\os2.my/stubs.c os2/stubs.c
--- H:/get/illya.vaes4/tk4.1/os2.my/stubs.c	Thu Feb 20 20:42:08 1997
+++ os2/stubs.c	Wed Jun 25 18:29:16 1997
@@ -295,10 +295,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;
 {
 }
@@ -454,3 +454,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.vaes4\tk4.1\os2.my/tkOS2Clipboard.c os2/tkOS2Clipboard.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Clipboard.c	Tue Mar 25 20:55:38 1997
+++ os2/tkOS2Clipboard.c	Sun Jun 22 19:50:24 1997
@@ -44,7 +44,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. */
 {
@@ -71,7 +71,8 @@ printf("TkSelGetSelection\n");
 		}
 		*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.vaes4\tk4.1\os2.my/tkOS2Cursor.c os2/tkOS2Cursor.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Cursor.c	Wed Jun 25 18:26:06 1997
+++ os2/tkOS2Cursor.c	Sun Jun 22 22:04:10 1997
@@ -149,14 +149,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.vaes4\tk4.1\os2.my/tkOS2Font.c os2/tkOS2Font.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Font.c	Wed Jun 25 18:26:06 1997
+++ os2/tkOS2Font.c	Wed Jun 25 18:05:00 1997
@@ -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
@@ -59,15 +60,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
@@ -78,7 +80,6 @@ printf("    Tcl_SplitList failed\n");
 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;
     }
 
@@ -117,8 +118,7 @@ nameLen);
      * 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 = pointSize / 10;
@@ -128,55 +128,64 @@ nameLen);
      * Apply any style modifiers.
      */
 	
-    if (Tcl_SplitList(dummy, (char *) argv[2], &argc2, &argv2) != TCL_OK) {
-	ckfree((char*) argv);
+    if (Lang_SplitList(dummy, args[2], &argc2, &args2, &freeProc2) != TCL_OK) {
 	goto nomatch;
     }
     for (i = 0; i < argc2; i++) {
+	char *s = LangString(args2[i]);
 /*
-	if (stricmp(argv2[i], "normal") == 0) {
+	if (stricmp(s, "normal") == 0) {
 	    logfont->fattrs.fsSelection |= FW_NORMAL;
-	} else if (stricmp(argv2[i], "bold") == 0) {
+	} else if (stricmp(s, "bold") == 0) {
 */
-	if (stricmp(argv2[i], "bold") == 0) {
+	if (stricmp(s, "bold") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_BOLD;
 /*
-	} else if (stricmp(argv2[i], "medium") == 0) {
+	} else if (stricmp(s, "medium") == 0) {
 	    logfont->fattrs.fsSelection |= FW_MEDIUM;
 */
-	} else if (stricmp(argv2[i], "heavy") == 0) {
+	} else if (stricmp(s, "heavy") == 0) {
 	    logfont->fattrs.fsSelection |= FATTR_SEL_BOLD;
 /*
-	} else if (stricmp(argv2[i], "thin") == 0) {
+	} else if (stricmp(s, "thin") == 0) {
 	    logfont->fattrs.fsSelection |= FW_THIN;
-	} else if (stricmp(argv2[i], "extralight") == 0) {
+	} else if (stricmp(s, "extralight") == 0) {
 	    logfont->fattrs.fsSelection |= FW_EXTRALIGHT;
-	} else if (stricmp(argv2[i], "light") == 0) {
+	} else if (stricmp(s, "light") == 0) {
 	    logfont->fattrs.fsSelection |= FW_LIGHT;
 */
-	} 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:
-    Tcl_DeleteInterp(dummy);
+    if (freeProc2) {
+       (*freeProc2)(argc2,args2);
+    }
+    if (freeProc) {
+       (*freeProc)(argc,args);
+    }
     return False;
 }
 
diff -pru H:\get\illya.vaes4\tk4.1\os2.my/tkOS2Image.c os2/tkOS2Image.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Image.c	Mon Apr 28 22:02:06 1997
+++ os2/tkOS2Image.c	Sun Jun 22 19:50:24 1997
@@ -82,6 +82,13 @@ pixel = rgb;
     return 0;
 }
 
+static void
+imfree(XImage *ximage)
+{
+    if (ximage->data) ckfree(ximage->data);
+    ckfree(ximage);
+}
+
 /*
  *----------------------------------------------------------------------
  *
@@ -152,7 +159,7 @@ printf("XCreateImage\n");
         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.vaes4\tk4.1\os2.my/tkOS2Init.c os2/tkOS2Init.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Init.c	Tue Feb 25 21:12:14 1997
+++ os2/tkOS2Init.c	Sun Jun 22 19:50:24 1997
@@ -38,6 +38,7 @@ TkOS2Font logfonts[255];	/* List of logi
 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
@@ -74,6 +75,8 @@ LONG rc;	/* For checking return values *
     error $msg\n\
 }\n\
 init";
+
+#endif 
 
 /*
  *----------------------------------------------------------------------
@@ -141,12 +144,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
 }
 
 /*
diff -pru H:\get\illya.vaes4\tk4.1\os2.my/tkOS2Int.h os2/tkOS2Int.h
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Int.h	Wed Jun 25 18:26:06 1997
+++ os2/tkOS2Int.h	Tue Jun 24 19:25:50 1997
@@ -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;
 
 /*
diff -pru H:\get\illya.vaes4\tk4.1\os2.my/tkOS2Pixmap.c os2/tkOS2Pixmap.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Pixmap.c	Mon Apr 28 20:44:20 1997
+++ os2/tkOS2Pixmap.c	Sun Jun 22 19:48:48 1997
@@ -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;
@@ -61,7 +61,7 @@ sizl.cx = width; sizl.cy = height;
     todPtr = (TkOS2Drawable *)d;
     if (todPtr->type != TOD_BITMAP) {
 #ifdef DEBUG
-printf("XCreatePixmap %x, depth %d, parent %x, %dx%d\n", newTodPtr, depth,
+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;
@@ -73,7 +73,7 @@ todPtr->window.handle, sizl.cx, sizl.cy)
         }
     } else {
 #ifdef DEBUG
-printf("XCreatePixmap %x, depth %d, parent (bitmap) %x, %dx%d\n", newTodPtr,
+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;
@@ -91,39 +91,39 @@ depth, todPtr->bitmap.parent, sizl.cx, s
                                      (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_NORMAL | 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", WinGetLastError(hab));
+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", newTodPtr->bitmap.handle);
+printf("GpiCreateBitmap in Tk_GetPixmap returns %x\n", newTodPtr->bitmap.handle);
 #endif
     sizl.cx = width;
     sizl.cy = height;
@@ -162,7 +162,7 @@ newTodPtr->bitmap.handle, newTodPtr->bit
 /*
  *----------------------------------------------------------------------
  *
- * XFreePixmap --
+ * Tk_FreePixmap --
  *
  *	Release the resources associated with a pixmap.
  *
@@ -170,13 +170,13 @@ newTodPtr->bitmap.handle, newTodPtr->bit
  *	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.vaes4\tk4.1\os2.my/tkOS2Port.h os2/tkOS2Port.h
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Port.h	Thu Feb 20 20:42:10 1997
+++ os2/tkOS2Port.h	Sun Jun 22 19:50:24 1997
@@ -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.vaes4\tk4.1\os2.my/tkOS2Wm.c os2/tkOS2Wm.c
--- H:/get/illya.vaes4/tk4.1/os2.my/tkOS2Wm.c	Mon May 19 21:35:18 1997
+++ os2/tkOS2Wm.c	Sun Jun 22 22:07:22 1997
@@ -83,6 +83,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);
+}
+
 
 /*
  *----------------------------------------------------------------------
@@ -300,6 +313,7 @@ printf("TkWmNewWindow, x %d y %d\n", wmP
     wmPtr->flags = WM_NEVER_MAPPED;
     wmPtr->nextPtr = firstWmPtr;
     firstWmPtr = wmPtr;
+    wmPtr->cmdArg = NULL;
 
     /*
      * Tk must monitor structure events for top-level windows, in order
@@ -316,6 +330,23 @@ printf("TkWmNewWindow, x %d y %d\n", wmP
 
     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;
+    }
+}
+
+
+
 
 /*
  *--------------------------------------------------------------
@@ -567,6 +598,13 @@ createStruct.pszText = wmPtr->titleUid;
 createStruct.pszClass = WC_FRAME;
 createStruct.hwndParent = HWND_DESKTOP;
 WinSendMsg(frame, WM_CREATE, MPFROMP(parentPtr), MPFROMP(&createStruct));
+	{
+	   static HPOINTER id;
+	   if (id == 0)
+		id = WinLoadPointer(HWND_DESKTOP, TkOS2GetTkModule(), 0x1000);
+	   WinSendMsg(frame, WM_SETICON, (MPARAM)id, NULL);
+
+	}
 
 /*	client  = WinCreateWindow(
 /*		frame,		/* Parent */
@@ -658,7 +696,7 @@ printf("    display %x\n", winPtr->displ
 	return;
     } else {
 	if (wmPtr->flags & WM_UPDATE_PENDING) {
-	    Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
+	    Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
 	}
 	UpdateGeometryInfo((ClientData) winPtr);
     }
@@ -775,6 +813,7 @@ printf("TkWmUnmapWindow\n");
  *--------------------------------------------------------------
  */
 
+
 void
 TkWmDeadWindow(winPtr)
     TkWindow *winPtr;		/* Top-level window that's being deleted. */
@@ -832,7 +871,7 @@ printf("TkWmDeadWindow\n");
 
 	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);
@@ -917,13 +956,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");
@@ -962,9 +1002,54 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	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)) {
@@ -1005,6 +1090,114 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	    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)) {
@@ -1050,8 +1243,9 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	    && (length >= 3)) {
 	TkWindow **cmapList;
 	TkWindow *winPtr2;
-	int i, windowArgc, gotToplevel;
-	char **windowArgv;
+	int i, windowArgc, gotToplevel = 0;
+	Arg *windowArgs;
+        LangFreeProc *freeProc = NULL;
 
 	if ((argc != 3) && (argc != 4)) {
 	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
@@ -1070,18 +1264,19 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	    }
 	    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) {
@@ -1105,7 +1300,6 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	}
 	wmPtr->cmapList = cmapList;
 	wmPtr->cmapCount = windowArgc;
-	ckfree((char *) windowArgv);
 
 	/*
 	 * Now we need to force the updated colormaps to be installed.
@@ -1120,11 +1314,14 @@ printf("   %s %s %s\n", argv[0], argv[1]
 /* WM_PALETTECHANGED -> WM_REALIZEPALETTE + focus notification */
                     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 \"",
@@ -1133,16 +1330,14 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	    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"));
@@ -1150,17 +1345,24 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	    }
 	    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 \"",
@@ -1615,6 +1817,31 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	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)) {
@@ -1680,7 +1907,7 @@ printf("   %s %s %s\n", argv[0], argv[1]
 	    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;
 		}
 	    }
@@ -1701,19 +1928,23 @@ printf("   %s %s %s\n", argv[0], argv[1]
 		} 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;
 
@@ -1949,7 +2180,7 @@ printf("Tk_SetGrid\n");
 	    && (wmPtr->widthInc == widthInc)
 	    && (wmPtr->heightInc == heightInc)
 	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
-		    == PBaseSize|PResizeInc)) {
+		    == (PBaseSize|PResizeInc))) {
 	return;
     }
 
@@ -2615,7 +2846,7 @@ printf("Tk_MoveToplevelWindow\n");
 
     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);
     }
@@ -2667,7 +2898,7 @@ printf("TkWmProtocolEventProc\n");
 	    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,
@@ -3377,6 +3608,64 @@ printf("InvalidateSubTree win %x, cmap %
 /***         }
 /***     }
 ***/
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
 }
 
 /*
