XWorkstation.st
changeset 6332 792a2b79c651
parent 6328 89f406538cff
child 6335 3148d179a5a5
--- a/XWorkstation.st	Mon Mar 17 20:01:42 2014 +0100
+++ b/XWorkstation.st	Mon Mar 17 20:16:56 2014 +0100
@@ -50,6 +50,13 @@
 	privateIn:XWorkstation
 !
 
+DeviceGraphicsContext subclass:#X11GraphicsContext
+	instanceVariableNames:'useXftFont xftDrawId'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:XWorkstation
+!
+
 !XWorkstation primitiveDefinitions!
 %{
 
@@ -739,6 +746,21 @@
     "Created: / 20-12-2013 / 11:02:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+displayIdOrErrorIfBroken
+    (hasConnectionBroken or:[displayId isNil]) ifTrue:[
+        self primitiveFailedOrClosedConnection.
+        ^ nil.
+    ].
+    ^ displayId
+!
+
+displayIdOrNilIfBroken
+    hasConnectionBroken ifTrue:[
+        ^ nil.
+    ].
+    ^ displayId
+!
+
 maxOperationsUntilFlush
     ^ maxOperationsUntilFlush
 !
@@ -1725,18 +1747,18 @@
 !
 
 createWindowFor:aView type:typeSymbol
-		 origin:origin
-		 extent:extent
-		 minExtent:minExt
-		 maxExtent:maxExt
-		 borderWidth:bWidth
-		 subViewOf:wsuperView
-		 style:wStyle
-		 inputOnly:winputOnly
-		 label:wlabel
-		 owner:wowner
-		 icon:wicon iconMask:wiconMask
-		 iconView:wiconView
+                 origin:origin
+                 extent:extent
+                 minExtent:minExt
+                 maxExtent:maxExt
+                 borderWidth:bWidth
+                 subViewOf:wsuperView
+                 style:wStyle
+                 inputOnly:winputOnly
+                 label:wlabel
+                 owner:wowner
+                 icon:wicon iconMask:wiconMask
+                 iconView:wiconView
 
     <context: #return>
 
@@ -1746,51 +1768,51 @@
      vBgForm deepForm preferredVisual preferredDepth
      wiconId wiconMaskId wiconViewId windowGroupWindowId|
 
-    displayId isNil ifTrue:[
-	self primitiveFailedOrClosedConnection.
-	^ nil
+    self isOpen ifFalse:[
+        self primitiveFailedOrClosedConnection.
+        ^ nil
     ].
 
     origin notNil ifTrue:[
-	xpos := origin x.
-	ypos := origin y.
+        xpos := origin x.
+        ypos := origin y.
     ] ifFalse:[
-	xpos := ypos := 0.
+        xpos := ypos := 0.
     ].
     extent notNil ifTrue:[
-	wwidth := extent x.
-	wheight := extent y.
+        wwidth := extent x.
+        wheight := extent y.
     ] ifFalse:[
-	wwidth := wheight := 100.
+        wwidth := wheight := 100.
     ].
     minExt notNil ifTrue:[
-	minWidth := minExt x.
-	minHeight := minExt y
+        minWidth := minExt x.
+        minHeight := minExt y
     ].
     maxExt notNil ifTrue:[
-	maxWidth := maxExt x.
-	maxHeight := maxExt y
+        maxWidth := maxExt x.
+        maxHeight := maxExt y
     ].
 
     wsuperView notNil ifTrue:[
-	wsuperViewId := wsuperView id
+        wsuperViewId := wsuperView id
     ] ifFalse:[
-	isTopWindow := true.
-	aView class ~~ WindowGroupWindow ifTrue:[
-	    windowGroupWindow isNil ifTrue:[
-		self getWindowGroupWindow.
-	    ].
-	    windowGroupWindowId := windowGroupWindow id.
-	].
-	wicon notNil ifTrue:[
-	    wiconId := wicon id.
-	    wiconMask notNil ifTrue:[
-		wiconMaskId := wiconMask id
-	    ]
-	].
-	wiconView notNil ifTrue:[
-	    wiconViewId := wiconView id
-	].
+        isTopWindow := true.
+        aView class ~~ WindowGroupWindow ifTrue:[
+            windowGroupWindow isNil ifTrue:[
+                self getWindowGroupWindow.
+            ].
+            windowGroupWindowId := windowGroupWindow id.
+        ].
+        wicon notNil ifTrue:[
+            wiconId := wicon id.
+            wiconMask notNil ifTrue:[
+                wiconMaskId := wiconMask id
+            ]
+        ].
+        wiconView notNil ifTrue:[
+            wiconViewId := wiconView id
+        ].
     ].
 
     weventMask := aView eventMask.
@@ -1824,122 +1846,122 @@
     sizehints.y = 0;
 
     if (__bothSmallInteger(wwidth, wheight)) {
-	sizehints.flags |= PSize;
-	sizehints.width = __intVal(wwidth);
-	sizehints.height = __intVal(wheight);
+        sizehints.flags |= PSize;
+        sizehints.width = __intVal(wwidth);
+        sizehints.height = __intVal(wheight);
     }
     if (__bothSmallInteger(xpos, ypos)) {
-	sizehints.flags |= PPosition;
-	sizehints.x = __intVal(xpos);
-	sizehints.y = __intVal(ypos);
+        sizehints.flags |= PPosition;
+        sizehints.x = __intVal(xpos);
+        sizehints.y = __intVal(ypos);
     }
     if (__bothSmallInteger(minWidth, minHeight)) {
-	sizehints.flags |= PMinSize;
-	sizehints.min_width = __intVal(minWidth);
-	sizehints.min_height = __intVal(minHeight);
+        sizehints.flags |= PMinSize;
+        sizehints.min_width = __intVal(minWidth);
+        sizehints.min_height = __intVal(minHeight);
     }
     if (__bothSmallInteger(maxWidth, maxHeight)) {
-	sizehints.flags |= PMaxSize;
-	sizehints.max_width = __intVal(maxWidth);
-	sizehints.max_height = __intVal(maxHeight);
+        sizehints.flags |= PMaxSize;
+        sizehints.max_width = __intVal(maxWidth);
+        sizehints.max_height = __intVal(maxHeight);
     }
 
     bg = WhitePixel(dpy, screen);
 
     if (__isSmallInteger(bWidth)) {
-	bw = __intVal(bWidth);
+        bw = __intVal(bWidth);
     } else {
-	bw = 0;
+        bw = 0;
     }
 
     bd = BlackPixel(dpy, screen);
 
     if (__isExternalAddress(wsuperViewId)) {
-	parentWindow = __WindowVal(wsuperViewId);
+        parentWindow = __WindowVal(wsuperViewId);
     } else {
-	parentWindow = RootWindow(dpy, screen);
+        parentWindow = RootWindow(dpy, screen);
     }
 
     if (wStyle == @symbol(popUp))
-	xswa.override_redirect = 1;
+        xswa.override_redirect = 1;
     else
-	xswa.override_redirect = 0;
+        xswa.override_redirect = 0;
 
     if (winputOnly == true)
-	ioClass = InputOnly;
+        ioClass = InputOnly;
     else
-	ioClass = InputOutput;
+        ioClass = InputOutput;
 
     if (__isSmallInteger(weventMask)) {
-	xswa.event_mask = __intVal(weventMask);
+        xswa.event_mask = __intVal(weventMask);
     } else {
-	xswa.event_mask = 0;
+        xswa.event_mask = 0;
     }
 
     if (ioClass == InputOnly) {
-	bw = 0;
-	depth = 0;
-	flags |= CWEventMask;
+        bw = 0;
+        depth = 0;
+        flags |= CWEventMask;
     } else {
-	depth = DefaultDepth(dpy,screen);
-	flags |= CWEventMask | CWBorderPixel | CWOverrideRedirect;
-
-	if (backPixmap != (Pixmap)0) {
-	    xswa.background_pixmap = backPixmap;
-	    flags |= CWBackPixmap;
-	} else {
-	    xswa.background_pixel = bg;
-	    flags |= CWBackPixel;
-	}
-	xswa.border_pixel = bd;
+        depth = DefaultDepth(dpy,screen);
+        flags |= CWEventMask | CWBorderPixel | CWOverrideRedirect;
+
+        if (backPixmap != (Pixmap)0) {
+            xswa.background_pixmap = backPixmap;
+            flags |= CWBackPixmap;
+        } else {
+            xswa.background_pixel = bg;
+            flags |= CWBackPixel;
+        }
+        xswa.border_pixel = bd;
     }
 
     visual.visualid = CopyFromParent;
     if (__isSmallInteger(preferredDepth)) {
-	depth = __intVal(preferredDepth);
+        depth = __intVal(preferredDepth);
     }
 
 
     if (preferredVisual != nil) {
-	XVisualInfo vi;
-	int cls;
-
-	if (preferredVisual == @symbol(StaticGray))
-	    cls = StaticGray;
-	else if (preferredVisual == @symbol(GrayScale))
-	    cls = GrayScale;
-	else if (preferredVisual == @symbol(StaticColor))
-	    cls = StaticColor;
-	else if (preferredVisual == @symbol(PseudoColor))
-	    cls = PseudoColor;
-	else if (preferredVisual == @symbol(TrueColor))
-	    cls = TrueColor;
-	else if (preferredVisual == @symbol(DirectColor))
-	    cls = DirectColor;
-	else
-	    cls = PseudoColor;
-
-	ENTER_XLIB();
-	if (XMatchVisualInfo(dpy, screen, depth, cls, &vi)) {
-	    visual.visualid = vi.visualid;
+        XVisualInfo vi;
+        int cls;
+
+        if (preferredVisual == @symbol(StaticGray))
+            cls = StaticGray;
+        else if (preferredVisual == @symbol(GrayScale))
+            cls = GrayScale;
+        else if (preferredVisual == @symbol(StaticColor))
+            cls = StaticColor;
+        else if (preferredVisual == @symbol(PseudoColor))
+            cls = PseudoColor;
+        else if (preferredVisual == @symbol(TrueColor))
+            cls = TrueColor;
+        else if (preferredVisual == @symbol(DirectColor))
+            cls = DirectColor;
+        else
+            cls = PseudoColor;
+
+        ENTER_XLIB();
+        if (XMatchVisualInfo(dpy, screen, depth, cls, &vi)) {
+            visual.visualid = vi.visualid;
 /*
-	    console_fprintf(stderr, "visualId=%x\n", vi.visualid);
+            console_fprintf(stderr, "visualId=%x\n", vi.visualid);
 */
-	}
-	LEAVE_XLIB();
+        }
+        LEAVE_XLIB();
     }
 
     ENTER_XLIB2();
     newWindow = XCreateWindow(dpy, parentWindow,
-			   sizehints.x, sizehints.y,
-			   sizehints.width, sizehints.height,
-			   bw, depth, ioClass, &visual,
-			   flags, &xswa);
+                           sizehints.x, sizehints.y,
+                           sizehints.width, sizehints.height,
+                           bw, depth, ioClass, &visual,
+                           flags, &xswa);
     LEAVE_XLIB();
 
 
     if (! newWindow) {
-	RETURN ( nil );
+        RETURN ( nil );
     }
 
 #ifdef COUNT_RESOURCES
@@ -1951,168 +1973,168 @@
      * (only makes sense for topWindows)
      */
     if (isTopWindow == true) {
-	XWMHints wmhints;
-
-	wmhints.flags = 0;
-
-	if (__isExternalAddress(wiconId)) {
-	    wmhints.icon_pixmap = __PixmapVal(wiconId);
-	    wmhints.flags = IconPixmapHint;
-	    if (__isExternalAddress(wiconMaskId)) {
-		wmhints.icon_mask = __PixmapVal(wiconMaskId);
-		wmhints.flags |= IconMaskHint;
-	    }
-	}
-
-	if (__isExternalAddress(windowGroupWindowId)) {
-	    wmhints.window_group = __WindowVal(windowGroupWindowId);
-	    wmhints.flags |= WindowGroupHint;
-	}
-
-	if (__isExternalAddress(wiconViewId)) {
-	    wmhints.flags |= IconWindowHint;
-	    wmhints.icon_window = __WindowVal(wiconViewId);
-	};
+        XWMHints wmhints;
+
+        wmhints.flags = 0;
+
+        if (__isExternalAddress(wiconId)) {
+            wmhints.icon_pixmap = __PixmapVal(wiconId);
+            wmhints.flags = IconPixmapHint;
+            if (__isExternalAddress(wiconMaskId)) {
+                wmhints.icon_mask = __PixmapVal(wiconMaskId);
+                wmhints.flags |= IconMaskHint;
+            }
+        }
+
+        if (__isExternalAddress(windowGroupWindowId)) {
+            wmhints.window_group = __WindowVal(windowGroupWindowId);
+            wmhints.flags |= WindowGroupHint;
+        }
+
+        if (__isExternalAddress(wiconViewId)) {
+            wmhints.flags |= IconWindowHint;
+            wmhints.icon_window = __WindowVal(wiconViewId);
+        };
 
 /*
-	wmhints.flags |= InputHint;
-	wmhints.input = True;
+        wmhints.flags |= InputHint;
+        wmhints.input = True;
 */
-	ENTER_XLIB();
-	XSetWMHints(dpy, newWindow, &wmhints);
-	XSetWMNormalHints(dpy, newWindow, &sizehints);
-	LEAVE_XLIB();
-
-	/*
-	 * get atoms first (if not already known)
-	 */
-	if (__INST(protocolsAtom) == nil) {
-	    ENTER_XLIB();
-	    WmProtocolsAtom = XInternAtom(dpy, "WM_PROTOCOLS", False);
-	    __INST(protocolsAtom) = __MKATOMOBJ(WmProtocolsAtom);
+        ENTER_XLIB();
+        XSetWMHints(dpy, newWindow, &wmhints);
+        XSetWMNormalHints(dpy, newWindow, &sizehints);
+        LEAVE_XLIB();
+
+        /*
+         * get atoms first (if not already known)
+         */
+        if (__INST(protocolsAtom) == nil) {
+            ENTER_XLIB();
+            WmProtocolsAtom = XInternAtom(dpy, "WM_PROTOCOLS", False);
+            __INST(protocolsAtom) = __MKATOMOBJ(WmProtocolsAtom);
 #ifdef USE_SAVEYOURSELF_ATOM
-	    WmSaveYourselfAtom = XInternAtom(dpy, "WM_SAVE_YOURSELF", False);
-	    __INST(saveYourselfAtom) = __MKATOMOBJ(WmSaveYourselfAtom);
+            WmSaveYourselfAtom = XInternAtom(dpy, "WM_SAVE_YOURSELF", False);
+            __INST(saveYourselfAtom) = __MKATOMOBJ(WmSaveYourselfAtom);
 #endif
 #ifdef USE_QUIT_APP_ATOM
-	    WmQuitAppAtom = XInternAtom(dpy, "_WM_QUIT_APP", False);
-	    __INST(quitAppAtom) = __MKATOMOBJ(WmQuitAppAtom);
-#endif
-	    WmDeleteWindowAtom = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-	    __INST(deleteWindowAtom) = __MKATOMOBJ(WmDeleteWindowAtom);
-
-	    UUIDAtom = XInternAtom(dpy, "UUID", False);
-	    __INST(uuidAtom) = __MKATOMOBJ(UUIDAtom);
-	    STXDeviceAtom = XInternAtom(dpy, "STX_DEVICE_ID", False);
-	    __INST(stxDeviceAtom) = __MKATOMOBJ(STXDeviceAtom);
-
-	    LEAVE_XLIB();
-	} else {
+            WmQuitAppAtom = XInternAtom(dpy, "_WM_QUIT_APP", False);
+            __INST(quitAppAtom) = __MKATOMOBJ(WmQuitAppAtom);
+#endif
+            WmDeleteWindowAtom = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+            __INST(deleteWindowAtom) = __MKATOMOBJ(WmDeleteWindowAtom);
+
+            UUIDAtom = XInternAtom(dpy, "UUID", False);
+            __INST(uuidAtom) = __MKATOMOBJ(UUIDAtom);
+            STXDeviceAtom = XInternAtom(dpy, "STX_DEVICE_ID", False);
+            __INST(stxDeviceAtom) = __MKATOMOBJ(STXDeviceAtom);
+
+            LEAVE_XLIB();
+        } else {
 #ifdef USE_QUIT_APP_ATOM
-	    WmQuitAppAtom = __AtomVal(__INST(quitAppAtom));
+            WmQuitAppAtom = __AtomVal(__INST(quitAppAtom));
 #else
-	    WmQuitAppAtom = 0;
-#endif
-	    WmProtocolsAtom = __AtomVal(__INST(protocolsAtom));
-	    WmDeleteWindowAtom = __AtomVal(__INST(deleteWindowAtom));
+            WmQuitAppAtom = 0;
+#endif
+            WmProtocolsAtom = __AtomVal(__INST(protocolsAtom));
+            WmDeleteWindowAtom = __AtomVal(__INST(deleteWindowAtom));
 #ifdef USE_SAVEYOURSELF_ATOM
-	    WmSaveYourselfAtom = __AtomVal(__INST(saveYourselfAtom));
+            WmSaveYourselfAtom = __AtomVal(__INST(saveYourselfAtom));
 #else
-	    WmSaveYourselfAtom = 0;
-#endif
-	    UUIDAtom = __AtomVal(__INST(uuidAtom));;
-	    STXDeviceAtom = __AtomVal(__INST(stxDeviceAtom));;
-	}
-
-	/*
-	 * tell window manager to not kill us but send an event instead
-	 */
-	atoms[0] = WmDeleteWindowAtom; atomCount++;
+            WmSaveYourselfAtom = 0;
+#endif
+            UUIDAtom = __AtomVal(__INST(uuidAtom));;
+            STXDeviceAtom = __AtomVal(__INST(stxDeviceAtom));;
+        }
+
+        /*
+         * tell window manager to not kill us but send an event instead
+         */
+        atoms[0] = WmDeleteWindowAtom; atomCount++;
 #ifdef USE_SAVEYOURSELF_ATOM
-	atoms[atomCount] = WmSaveYourselfAtom; atomCount++;
+        atoms[atomCount] = WmSaveYourselfAtom; atomCount++;
 #endif
 #ifdef USE_QUIT_APP_ATOM
-	atoms[atomCount] = WmQuitAppAtom; atomCount++;
-#endif
-	ENTER_XLIB();
-	XChangeProperty(dpy, newWindow, WmProtocolsAtom, XA_ATOM,
-			32, PropModeReplace, (unsigned char *)atoms, atomCount);
-	LEAVE_XLIB();
-
-	/*
-	 * an optional unique id (to mark stx-windows)
-	 */
-	if (__isBytes(__INST(uniqueDeviceID))) {
-	    int numUUIDBytes = __byteArraySize(__INST(uniqueDeviceID));
-	    unsigned char uuidBytes[32];
-
-	    if (numUUIDBytes <= sizeof(uuidBytes)) {
-		Atom uuidAtom;
-
-		bcopy(__byteArrayVal(__INST(uniqueDeviceID)), uuidBytes, numUUIDBytes);
-
-		ENTER_XLIB();
-		XChangeProperty (dpy, newWindow, STXDeviceAtom, UUIDAtom, 8, PropModeReplace,
-				 uuidBytes, numUUIDBytes );
-		LEAVE_XLIB();
-	    }
-	}
+        atoms[atomCount] = WmQuitAppAtom; atomCount++;
+#endif
+        ENTER_XLIB();
+        XChangeProperty(dpy, newWindow, WmProtocolsAtom, XA_ATOM,
+                        32, PropModeReplace, (unsigned char *)atoms, atomCount);
+        LEAVE_XLIB();
+
+        /*
+         * an optional unique id (to mark stx-windows)
+         */
+        if (__isBytes(__INST(uniqueDeviceID))) {
+            int numUUIDBytes = __byteArraySize(__INST(uniqueDeviceID));
+            unsigned char uuidBytes[32];
+
+            if (numUUIDBytes <= sizeof(uuidBytes)) {
+                Atom uuidAtom;
+
+                bcopy(__byteArrayVal(__INST(uniqueDeviceID)), uuidBytes, numUUIDBytes);
+
+                ENTER_XLIB();
+                XChangeProperty (dpy, newWindow, STXDeviceAtom, UUIDAtom, 8, PropModeReplace,
+                                 uuidBytes, numUUIDBytes );
+                LEAVE_XLIB();
+            }
+        }
 
 #ifdef SUPPORT_MOTIF_WM_HINTS
-	/*
-	 * less decoration
-	 */
-	if ((wStyle == @symbol(undecorated))
-	 || (wStyle == @symbol(dialog2))
-	 || (wStyle == @symbol(notitle))
-	) {
-	    if (__INST(motifWMHintsAtom) == nil) {
-		ENTER_XLIB();
-		MotifWMHintsAtom = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
-		__INST(motifWMHintsAtom) = __MKATOMOBJ(MotifWMHintsAtom);
-		LEAVE_XLIB();
-	    } else {
-		MotifWMHintsAtom = __AtomVal(__INST(motifWMHintsAtom));
-	    }
-
-	    {
-		struct hints {
-		    unsigned long flags;
-		    unsigned long functions;
-		    unsigned long decorations;
-		    long input_mode;
-		    unsigned long status;
-		} mvm_hints;
-
-		if (wStyle == @symbol(undecorated)) {
-		    mvm_hints.decorations = MWM_DECOR_NONE;
-		}
-		if (wStyle == @symbol(dialog2)) {
-		    mvm_hints.decorations = MWM_DECOR_BORDER
-					    | MWM_DECOR_RESIZEH
-					    | MWM_DECOR_TITLE
-					    /* | MWM_DECOR_MENU */
-					    /* | MWM_DECOR_MINIMIZE */
-					    /* | MWM_DECOR_MAXIMIZE */
-					    ;
-		}
-		if (wStyle == @symbol(notitle)) {
-		    mvm_hints.decorations = MWM_DECOR_BORDER
-					    /* | MWM_DECOR_RESIZEH  */
-					    /* | MWM_DECOR_TITLE    */
-					    /* | MWM_DECOR_MENU     */
-					    /* | MWM_DECOR_MINIMIZE */
-					    /* | MWM_DECOR_MAXIMIZE */
-					    ;
-		}
-		mvm_hints.flags =  MWM_HINTS_DECORATIONS;
-		ENTER_XLIB();
-		XChangeProperty (dpy, newWindow, MotifWMHintsAtom,
-				     MotifWMHintsAtom, 32, PropModeReplace,
-				     (unsigned char*)&mvm_hints, 5 );
-		LEAVE_XLIB();
-	    }
-	}
+        /*
+         * less decoration
+         */
+        if ((wStyle == @symbol(undecorated))
+         || (wStyle == @symbol(dialog2))
+         || (wStyle == @symbol(notitle))
+        ) {
+            if (__INST(motifWMHintsAtom) == nil) {
+                ENTER_XLIB();
+                MotifWMHintsAtom = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
+                __INST(motifWMHintsAtom) = __MKATOMOBJ(MotifWMHintsAtom);
+                LEAVE_XLIB();
+            } else {
+                MotifWMHintsAtom = __AtomVal(__INST(motifWMHintsAtom));
+            }
+
+            {
+                struct hints {
+                    unsigned long flags;
+                    unsigned long functions;
+                    unsigned long decorations;
+                    long input_mode;
+                    unsigned long status;
+                } mvm_hints;
+
+                if (wStyle == @symbol(undecorated)) {
+                    mvm_hints.decorations = MWM_DECOR_NONE;
+                }
+                if (wStyle == @symbol(dialog2)) {
+                    mvm_hints.decorations = MWM_DECOR_BORDER
+                                            | MWM_DECOR_RESIZEH
+                                            | MWM_DECOR_TITLE
+                                            /* | MWM_DECOR_MENU */
+                                            /* | MWM_DECOR_MINIMIZE */
+                                            /* | MWM_DECOR_MAXIMIZE */
+                                            ;
+                }
+                if (wStyle == @symbol(notitle)) {
+                    mvm_hints.decorations = MWM_DECOR_BORDER
+                                            /* | MWM_DECOR_RESIZEH  */
+                                            /* | MWM_DECOR_TITLE    */
+                                            /* | MWM_DECOR_MENU     */
+                                            /* | MWM_DECOR_MINIMIZE */
+                                            /* | MWM_DECOR_MAXIMIZE */
+                                            ;
+                }
+                mvm_hints.flags =  MWM_HINTS_DECORATIONS;
+                ENTER_XLIB();
+                XChangeProperty (dpy, newWindow, MotifWMHintsAtom,
+                                     MotifWMHintsAtom, 32, PropModeReplace,
+                                     (unsigned char*)&mvm_hints, 5 );
+                LEAVE_XLIB();
+            }
+        }
 #endif /* SUPPORT_MOTIF_WM_HINTS */
     }
 
@@ -2125,9 +2147,9 @@
 
     (wsuperView isNil "this is a topwindow"
      and:[wlabel notEmptyOrNil]) ifTrue:[
-	self
-	    setIconName:wlabel in:windowId;
-	    setWindowName:wlabel in:windowId.
+        self
+            setIconName:wlabel in:windowId;
+            setWindowName:wlabel in:windowId.
     ].
 
     self addKnownView:aView withId:windowId.
@@ -2198,9 +2220,9 @@
     self primitiveFailed
 !
 
-destroyView:aView withId:aWindowId
-    self primDestroyView:aView withId:aWindowId.
-    self removeKnownView:aView withId:aWindowId.
+destroyView:aViewOrNil withId:aWindowId
+    self primDestroyViewWithId:aWindowId.
+    self removeKnownView:aViewOrNil withId:aWindowId.
 !
 
 dpsContextFor:aDrawableId and:aGCId
@@ -2381,26 +2403,26 @@
 
 !
 
-primDestroyView:aView withId:aWindowId
+primDestroyViewWithId:aWindowId
     <context: #return>
 %{
     if (! ISCONNECTED) {
-	RETURN ( self );
+        RETURN ( self );
     }
 
     if (__isExternalAddress(aWindowId)) {
-	Window win = __WindowVal(aWindowId);
-
-	if (win) {
-
-	    ENTER_XLIB();
-	    XDestroyWindow(myDpy, win);
-	    LEAVE_XLIB();
+        Window win = __WindowVal(aWindowId);
+
+        if (win) {
+
+            ENTER_XLIB();
+            XDestroyWindow(myDpy, win);
+            LEAVE_XLIB();
 #ifdef COUNT_RESOURCES
-	    __cnt_view--;
-#endif
-
-	}
+            __cnt_view--;
+#endif
+
+        }
     }
 %}
 ! !
@@ -9663,6 +9685,20 @@
     self primitiveFailedOrClosedConnection
 !
 
+flushIfAppropriate
+    "flush the device, if necessary"
+
+    operationsUntilFlush notNil ifTrue:[
+        operationsUntilFlush <= 0 ifTrue:[
+            self flush.
+            ^ true.
+        ] ifFalse:[
+            operationsUntilFlush := operationsUntilFlush - 1.
+        ].
+    ].
+    ^ false.
+!
+
 primSync
     "send all buffered drawing to the display AND wait until the display
      has finished drawing it.
@@ -10374,6 +10410,12 @@
     ^ extent * 2 // 3
 !
 
+isOpen
+    "answer true, if device can be used"
+
+    ^ displayId notNil and:[hasConnectionBroken not].
+!
+
 isXineramaActive
 %{  /* NOCONTEXT */
 
@@ -11875,6 +11917,19 @@
     self primitiveFailedOrClosedConnection
 !
 
+newGraphicsContextFor:aGraphicsMedium
+    "create a new graphics context.
+     The defaults is to use the inherited graphics context.
+     Subclasses may redefine this to use their own graphics context"
+
+    ^ aGraphicsMedium.
+"/    |gc|
+"/
+"/    gc := X11GraphicsContext onDevice:self.
+"/    gc font:aGraphicsMedium class defaultFont.
+"/    ^ gc.
+!
+
 parentWindowIdOf:aWindowId
     "return a windows parent-window id.
      Useful with getGeometryOf:, to compute information about the decoration."
@@ -13083,14 +13138,142 @@
     ^ true
 ! !
 
+!XWorkstation::X11GraphicsContext methodsFor:'displaying'!
+
+displayString:aString x:x y:y opaque:opaque
+    "draw a string - if opaque is false, draw foreground only; otherwise, draw both
+     foreground and background characters.
+     If the coordinates are not integers, an error is triggered."
+
+    <context: #return>
+
+    |displayId|
+
+    device flushIfAppropriate.
+    displayId := device displayIdOrErrorIfBroken.
+
+%{
+#if 0
+    GC gc;
+    Window win;
+    char *cp;
+    int n;
+    OBJ cls;
+#   define NLOCALBUFFER 200
+    XChar2b xlatebuffer[NLOCALBUFFER];
+    int nInstBytes;
+
+    if (displayId != nil
+     && __isExternalAddress(__INST(gcId))
+     && __isExternalAddress(__INST(drawableId))
+     && __isNonNilObject(aString)
+     && __bothSmallInteger(x, y)) {
+        int lMax = __intVal(@global(XWorkstation:MaxStringLength));
+        Display *dpy = __DisplayVal(displayId);
+        gc = __GCVal(__INST(gcId));
+        win = __WindowVal(__INST(drawableId));
+
+        cp = (char *) __stringVal(aString);
+
+        if (__isStringLike(aString)) {
+            n = __stringSize(aString);
+            if (n > lMax) n = lMax;
+            ENTER_XLIB();
+            if (opaque == true)
+                XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
+            else
+                XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
+            LEAVE_XLIB();
+            RETURN ( self );
+        }
+
+        cls = __qClass(aString);
+        nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
+        cp += nInstBytes;
+
+        if (__isBytes(aString)) {
+            n = __byteArraySize(aString) - nInstBytes - 1;
+
+            if (n > lMax) n = lMax;
+            ENTER_XLIB();
+            if (opaque == true)
+                XDrawImageString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
+            else
+                XDrawString(dpy, win, gc, __intVal(x), __intVal(y), cp, n);
+            LEAVE_XLIB();
+            RETURN ( self );
+        }
+
+        /* TWOBYTESTRINGS */
+        if (__isWords(aString)) {
+            union {
+                char b[2];
+                unsigned short s;
+            } u;
+            int i;
+            XChar2b *cp2;
+            int mustFree = 0;
+
+            n = (__byteArraySize(aString) - nInstBytes) / 2;
+            if (n > lMax) n = lMax;
+
+#if defined(MSBFIRST) || defined(__MSBFIRST)
+            /*
+             * chars already in correct order
+             */
+#else
+# if ! (defined(LSBFIRST) || defined(__LSBFIRST))
+            /*
+             * ST/X TwoByteStrings store the asciiValue in native byteOrder;
+             * X expects them MSB first
+             * convert as required
+             */
+            u.s = 0x1234;
+            if (u.b[0] != 0x12)
+# endif
+            {
+                if (n <= NLOCALBUFFER) {
+                    cp2 = xlatebuffer;
+                } else {
+                    cp2 = (XChar2b *)(malloc(n * 2));
+                    mustFree = 1;
+                }
+
+                for (i=0; i<n; i++) {
+                    cp2[i].byte1 = (((XChar2b *)cp)[i]).byte2;
+                    cp2[i].byte2 = (((XChar2b *)cp)[i]).byte1;
+                }
+                cp = (char *) cp2;
+            }
+#endif
+            ENTER_XLIB();
+            if (opaque == true)
+                XDrawImageString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, n);
+            else
+                XDrawString16(dpy, win, gc, __intVal(x), __intVal(y), (XChar2b *)cp, n);
+            LEAVE_XLIB();
+
+            if (mustFree) {
+                free(cp2);
+            }
+
+            RETURN ( self );
+        }
+    }
+#undef NLOCALBUFFER
+#endif
+%}.
+    ^ super displayString:aString x:x y:y opaque:opaque
+! !
+
 !XWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.588 2014-03-17 09:21:15 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.589 2014-03-17 19:16:56 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.588 2014-03-17 09:21:15 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.589 2014-03-17 19:16:56 stefan Exp $'
 !
 
 version_SVN