XWorkstation.st
changeset 3790 43261db5b846
parent 3789 712d129efee8
child 3792 bec0a7b4c8f6
--- a/XWorkstation.st	Mon Feb 10 17:47:22 2003 +0100
+++ b/XWorkstation.st	Tue Feb 11 14:39:50 2003 +0100
@@ -17,12 +17,11 @@
 		hasMbufExtension hasXVideoExtension hasSaveUnder hasPEXExtension
 		hasImageExtension hasInputExtension ignoreBackingStore blackpixel
 		whitepixel atoms protocolsAtom deleteWindowAtom saveYourselfAtom
-		quitAppAtom primaryAtom cutBuffer0Atom stringAtom lengthAtom
-		wmStateAtom listOfXFonts buttonsPressed eventRootX eventRootY
-		displayName eventTrace dispatchingExpose rgbVisual virtualRootId
-		rootId eventBuffer altModifierMask metaModifierMask
-		multiClickTime deviceIOTimeoutErrorSignal activateOnClick
-		rawKeySymTranslation'
+		quitAppAtom primaryAtom clipboardAtom stringAtom wmStateAtom
+		listOfXFonts buttonsPressed eventRootX eventRootY displayName
+		eventTrace dispatchingExpose rgbVisual virtualRootId rootId
+		eventBuffer altModifierMask metaModifierMask multiClickTime
+		deviceIOTimeoutErrorSignal activateOnClick rawKeySymTranslation'
 	classVariableNames:'RawKeySymTranslation ConservativeSync MaxStringLength
 		SelectionHandlers'
 	poolDictionaries:''
@@ -4584,13 +4583,6 @@
     "sent when another X-client has created a selection.
      This is a very X-specific mechanism."
 
-    "/
-    "/ workaround a bug in olvwm: it clears selections
-    "/ on window raise.
-    "/ In this case, keep my last own selection.
-    "/
-
-    self setLastCopyBuffer:(self getCopyBuffer).
     self setCopyBuffer:nil.
 
     SelectionHandlers notNil ifTrue:[
@@ -4647,74 +4639,41 @@
     "sent by some other X-client to ask for the selection.
      This is a very X-specific mechanism."
 
-    |o s stream stringAtom|
-
-"/targetID printCR.
-
-    targetID == (self atomIDOf:#LENGTH) ifTrue:[
-	"/
-	"/ the other one wants to know the size of our selection ...
-	"/
-	s := self selectionAsString.
-	self
-	    setLengthProperty:propertyID 
-	    value:s size 
-	    for:requestorID.
-
-	self
-	    sendSelectionNotifySelection:selectionID
-	    property:propertyID
-	    target:targetID
-	    time:time
-	    from:aView id
-	    to:requestorID.
-	^ self
-    ].
-
-    stringAtom := self atomIDOf:#STRING.
-    (targetID == stringAtom or:[
-     targetID == (self atomIDOf:#'COMPOUND_TEXT')]) ifTrue:[
-	"/
-	"/ the other view wants the selection as string
-	"/
-	s := self selectionAsString.
-
-	self
-	    sendSelection:s 
-	    selection:primaryAtom
-	    property:propertyID 
-	    target:stringAtom           "/ targetID, once I can provide compountText as well
-	    time:time
-	    from:requestorID
-	    to:requestorID.
-	^ self
-    ].
-
-"/    (targetID == (self atomIDOf:#'TARGETS')) ifTrue:[
-"/"/ TODO: implement this to avoid netscape paste-delay.
-"/"/
-"/        ^ self
-"/    ].
-
-    (targetID == (self atomIDOf:#'ST_OBJECT')) ifTrue:[
-	"/
-	"/ send the selection in binaryStore format
-	"/ (assuming, that the other view knows how to handle it)
-	"/
-	o := self getCopyBuffer.
-	stream := WriteStream on:(ByteArray new:200).
-	o storeBinaryOn:stream.
-
-	^ self
-	    sendSelection:(stream contents) 
-	    selection:primaryAtom
-	    property:propertyID 
-	    target:targetID 
-	    time:time
-	    from:aView id 
-	    to:requestorID
-    ].
-
+    |selection targetIdOut|
+
+"/'Selection: ' print. (self atomName:selectionID) print. ' TargetId: ' print. (self atomName:targetID) print.
+"/' Property: ' print. (self atomName:propertyID) print. ' Requestor: ' print. requestorID printCR.
+
+    selection := self selectionAs:targetID.
+    selection isNil ifTrue:[
+"/        ('XWorkstation: unsupported selection target ', (self atomName:targetID)) errorPrintCR.
+
+        "sending property None tells client, that i cannot convert"
+        self 
+            sendSelectionNotifySelection:selectionID 
+            property:nil 
+            target:targetID
+            time:time
+"/            from:aView id  BAD: nobody understands this
+            from:requestorID
+            to:requestorID.
+        ^ self
+    ].
+"/'Send selection: ' print. selection printCR.
+
+    targetIdOut := targetID.
+    selection isString ifTrue:[
+        targetIdOut := self atomIDOf:#STRING.
+    ].
+
+    self sendSelection:selection 
+         selection:selectionID 
+         property:propertyID 
+         target:targetIdOut 
+         time:time 
+"/         from:aView id    BAD: nobody understands this
+         from:requestorID 
+         to:requestorID.
 !
 
 visibilityNotify:aView state:how
@@ -4727,7 +4686,7 @@
 !XWorkstation methodsFor:'event handling'!
 
 decomposeEventBuffer:aByteArray into:eventArr
-    "extracet event fields and place them into an array:
+    "extract event fields and place them into an array:
      the fields are:
         1:      windowID
         2:      eventType-ID
@@ -5205,14 +5164,14 @@
      If the argument aMask is nonNil, only events for this eventMask are
      handled.
      WARNING: this may block to wait for an event - you better check for a 
-	      pending event before calling this."
+              pending event before calling this."
 
     (self getEventFor:aViewIdOrNil withMask:eventMask) ifTrue:[
-	AbortSignal handle:[:ex |
-	    ex return
-	] do:[
-	    self newDispatchLastEvent.
-	]
+        AbortSignal handle:[:ex |
+            ex return
+        ] do:[
+            self dispatchLastEvent.
+        ]
     ].
 
     "Modified: 19.8.1997 / 17:10:42 / cg"
@@ -5230,37 +5189,39 @@
     "Modified: 19.8.1997 / 17:10:26 / cg"
 !
 
+dispatchLastEvent
+    |arr|
+
+    arr := Array new:13.
+    (self decomposeEventBuffer:eventBuffer into:arr) ifTrue:[
+        self dispatchLastEvent:arr.
+    ].
+!
+
 dispatchLastEvent:evArray
     |viewId view evType arguments|
 
-    evArray size < 3 ifTrue:[
-'********** bad event:' errorPrintCR.
-evArray errorPrintCR.
-'********** see newDispatchLastEvent' errorPrintCR.
-	^ self.
-    ].
-
     viewId := evArray at:1.
     viewId notNil ifTrue:[
-	viewId = lastId ifTrue:[
-	    view := lastView
-	] ifFalse:[
-	    view := self viewFromId:viewId
-	].
+        viewId = lastId ifTrue:[
+            view := lastView
+        ] ifFalse:[
+            view := self viewFromId:viewId
+        ].
     ].
 
     evType := evArray at:3.
 
     (self respondsTo:evType) ifTrue:[
-	arguments := evArray copyFrom:3 to:(3 + evType numArgs - 1).
-	arguments at:1 put:view.
-
-	self perform:evType withArguments:arguments.
-	^ true.
+        arguments := evArray copyFrom:3 to:(3 + evType numArgs - 1).
+        arguments at:1 put:view.
+
+        self perform:evType withArguments:arguments.
+        ^ true.
     ].
 '********** unhandled event:' errorPrintCR.
 evType errorPrintCR. (evArray at:2) errorPrintCR.
-'********** see newDispatchLastEvent' errorPrintCR.
+'********** see dispatchLastEvent' errorPrintCR.
     ^ false
 !
 
@@ -5289,20 +5250,20 @@
 
     "interested in exposes only ?"
     dispatchingExpose notNil ifTrue:[
-	[self exposeEventPendingFor:dispatchingExpose withSync:false] whileTrue:[
-	    self dispatchExposeEventFor:dispatchingExpose
-	].
-	^ self
+        [self exposeEventPendingFor:dispatchingExpose withSync:false] whileTrue:[
+            self dispatchExposeEventFor:dispatchingExpose
+        ].
+        ^ self
     ].
 
     [self eventPendingWithSync:false] whileTrue:[
-	(self getEventFor:nil withMask:nil) ifTrue:[
-	    AbortSignal handle:[:ex |
-		ex return
-	    ] do:[
-		self newDispatchLastEvent
-	    ]
-	].
+        (self getEventFor:nil withMask:nil) ifTrue:[
+            AbortSignal handle:[:ex |
+                ex return
+            ] do:[
+                self dispatchLastEvent
+            ]
+        ].
     ]
 
     "Modified: 19.8.1997 / 17:11:18 / cg"
@@ -5603,18 +5564,6 @@
     dispatchingExpose := aView id
 !
 
-newDispatchLastEvent
-    |arr|
-
-    arr := Array new:13.
-    (self decomposeEventBuffer:eventBuffer into:arr) ifTrue:[
-	(self dispatchLastEvent:arr) ifFalse:[
-	    "if not implemented in new dispatch, fall back to old dispatch"
-	    self dispatchLastEvent
-	].
-    ].
-!
-
 setEventMask:aMask in:aWindowId
     "tell X that we are only interested in events from aMask, which
      is the bitwise or of the eventMask bits (see 'eventMaskFor:')"
@@ -5678,908 +5627,6 @@
 
 
 
-!
-
-circulateNotifyView:aView
-    "sent, when the stacking order changes.
-     ignored for now."
-
-!
-
-circulateRequestView:aView
-    "sent, when the stacking order is about to change.
-     ignored for now."
-!
-
-clientMessage:event type:type format:format dataOffset:offs view:targetView
-    |sensor data|
-
-    data := event copyFrom:offs + 1.
-
-    "/ DND drag&drop protocol
-    type == (self atomIDOf:#DndProtocol) ifTrue:[
-	format == 32 ifTrue:[
-	    self dndMessage:event data:data view:targetView.
-	    ^ self
-	]
-    ].
-
-    (sensor := targetView sensor) notNil ifTrue:[
-	sensor clientMessage:type format:format eventData:data view:targetView
-    ] ifFalse:[
-	"
-	 not posted, if there is no sensor ...
-	"
-    ]
-
-    "Created: 4.4.1997 / 17:49:26 / cg"
-    "Modified: 4.4.1997 / 18:00:18 / cg"
-!
-
-colorMapChangeView:aView
-    "sent, when another colormap is installed.
-     This is a very X-specific mechanism."
-
-    aView isNil ifTrue:[
-	"/ event arrived, after I destroyed it myself
-	^ self
-    ].
-    "/ not yet implemented
-    "/ aView colorMapChange
-!
-
-configureRequestView:aView
-    "ignored for now"
-
-    "/ aView configureRequest
-!
-
-createdView:aView
-    "ignored for now"
-
-    "/ aView created
-!
-
-dispatchLastEvent
-    |theView symS arg butt sibling 
-     windowID siblingID propertyID selectionID targetID requestorID
-     evTime
-     eventType|
-
-%{  /* STACK: 8000 */
-#   define ANYBUTTON   (Button1MotionMask | Button2MotionMask | Button3MotionMask)
-
-    Display *dpy;
-    OBJ eB;
-    XEvent *ev;
-    int ev_x, ev_y;
-
-#   define ae ((XAnyEvent *)ev)
-#   define ee ((XExposeEvent *)ev)
-#   define ke ((XKeyPressedEvent *)ev)
-#   define be ((XButtonPressedEvent *)ev)
-#   define ce ((XConfigureEvent *)ev)
-#   define me ((XMotionEvent *)ev)
-#   define ewe ((XEnterWindowEvent *)ev)
-#   define lwe ((XLeaveWindowEvent *)ev)
-#   define de ((XDestroyWindowEvent *)ev)
-#   define ve ((XVisibilityEvent *)ev)
-#   define mape ((XMappingEvent *)ev)
-
-    KeySym keySym;
-    unsigned char buffer[10];
-    int i, nchars;
-    char *keySymString;
-    char keySymStringBuffer[32];
-    unsigned INT nextMultiClickTime;
-    OBJ upDown, t;
-
-    struct inlineCache *ipS;
-    static struct inlineCache vid = _ILC1;
-
-    static struct inlineCache expS = _ILC5;
-    static struct inlineCache gexpS = _ILC6;
-    static struct inlineCache nexpS = _ILC1;
-    static struct inlineCache motS = _ILC4;
-    static struct inlineCache bpS = _ILC4;
-    static struct inlineCache bmpS = _ILC4;
-    static struct inlineCache bspS = _ILC4;
-    static struct inlineCache brS = _ILC4;
-    static struct inlineCache focInS = _ILC1;
-    static struct inlineCache focOutS = _ILC1;
-    static struct inlineCache peS = _ILC4;
-    static struct inlineCache plS = _ILC2;
-    static struct inlineCache termS = _ILC1;
-    static struct inlineCache savtermS = _ILC1;
-    static struct inlineCache destrS = _ILC1;
-    static struct inlineCache unmapS = _ILC1;
-    static struct inlineCache mapS = _ILC1;
-    static struct inlineCache confS = _ILC5;
-    static struct inlineCache coveredS = _ILC2;
-    static struct inlineCache clientMsg = _ILC5;
-
-    static struct inlineCache keymap = _ILC0;
-    static struct inlineCache created = _ILC1;
-    static struct inlineCache mapReq = _ILC1;
-    static struct inlineCache repar = _ILC1;
-    static struct inlineCache confReq = _ILC1;
-    static struct inlineCache resReq = _ILC1;
-    static struct inlineCache circReq = _ILC1;
-    static struct inlineCache circNotify = _ILC1;
-    static struct inlineCache gravNotify = _ILC1;
-    static struct inlineCache prop = _ILC1;
-    static struct inlineCache selClear = _ILC2;
-    static struct inlineCache selReq = _ILC6;
-    static struct inlineCache selNotify = _ILC5;
-    static struct inlineCache colormap = _ILC1;
-    static struct inlineCache mapping = _ILC2;
-    static struct inlineCache vis = _ILC1;
-
-    static struct inlineCache skpS = _ILC4;
-    static struct inlineCache skrS = _ILC4;
-
-    if (! ISCONNECTED) {
-	RETURN (false);
-    }
-
-    dpy = myDpy;
-
-    eB = __INST(eventBuffer);
-
-    if (__isByteArray(eB)) {
-	ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-    } else {
-	fprintf(stderr, "XWorkstation: no eventBuffer [%d]\n", __LINE__);
-	RETURN (false);
-    }
-
-    /*
-     * very often, its another event for the same view ...
-     * avoid creation & lookup then.
-     */
-    if ((t = __INST(lastId)) != nil) {
-	if (__isExternalAddress(t)) {
-	    if (__WindowVal(t) == ae->window) {
-		theView = __INST(lastView);
-		if (__isNonNilObject(theView)) {
-		    if (__qClass(theView) == nil) {
-			theView = nil;
-		    }
-		}
-	    }
-	}
-    }
-
-    if (theView == nil) {
-	windowID = __MKEXTERNALADDRESS(ae->window);
-	theView = (*vid.ilc_func)(self, @symbol(viewFromId:), nil, &vid, windowID);
-	/*
-	 * MKEXTERNALADDRESS and/or #viewFromId: could lead to a GC - refetch event ptr
-	 */
-	eB = __INST(eventBuffer);
-	ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-    }
-
-    if ((theView == nil) && (ev->type != MappingNotify)) {
-	RETURN (nil);
-    }
-
-    /*
-     * key, button and pointer events are sent to the sensor,
-     * or (if there is none) to the delegate.
-     * or (if there is none) to the view.
-     *
-     * expose events are sent to the sensor,
-     * or (if there is none) to the view
-     *
-     * sensor and delegate get view as additional argument
-     * all of this has been taken out of here to corresponding methods
-     * in DeviceWorkstation.
-     */
-
-#ifdef DEBUG
-    eventType = __MKSMALLINT(ev->type);
-#endif
-    switch (ev->type) {
-	case KeyRelease:
-	    symS = @symbol(keyRelease:x:y:view:);
-	    ipS = &skrS;
-	    upDown = false;
-	    goto keyPressAndRelease;
-
-	case KeyPress:
-	    symS = @symbol(keyPress:x:y:view:);
-	    ipS = &skpS;
-	    upDown = true;
-	    /* FALL INTO */
-
-	keyPressAndRelease:
-	    __INST(eventRootX) = __MKSMALLINT(ke->x_root);
-	    __INST(eventRootY) = __MKSMALLINT(ke->y_root);
-#ifdef OLD
-	    __INST(altDown) = (ke->state & Mod2Mask) ? true : false;
-	    __INST(metaDown) = (ke->state & Mod1Mask) ? true : false;
-#else
-	    __INST(altDown) = (ke->state & __intVal(__INST(altModifierMask))) ? true : false;
-	    __INST(metaDown) = (ke->state & __intVal(__INST(metaModifierMask))) ? true : false;
-#endif
-	    __INST(shiftDown) = (ke->state & ShiftMask) ? true : false;
-	    __INST(ctrlDown) = (ke->state & ControlMask) ? true : false;
-
-	    ev_x = ke->x;
-	    ev_y = ke->y;
-
-	    arg = nil;
-	    nchars = XLookupString(ke, (char *)buffer, sizeof(buffer), &keySym, NULL);
-	    if (nchars 
-	     && (((buffer[0] >= ' ') && (buffer[0] <= '~'))
-		 || (buffer[0] >= 0x80))) {
-		arg = _MKCHARACTER(buffer[0])/* *_CharacterTable[buffer[0]] */;
-		keySymString = NULL;
-	    } else {
-#ifdef OLD
-		switch (keySym) {
-		    case XK_Control_L:
-		    case XK_Control_R:
-			__INST(ctrlDown) = upDown;
-			break;
-		    case XK_Shift_L:
-		    case XK_Shift_R:
-			__INST(shiftDown) = upDown;
-			break;
-		    case XK_Meta_L:
-		    case XK_Meta_R:
-			__INST(metaDown) = upDown;
-			break;
-		    case XK_Alt_L:
-		    case XK_Alt_R:
-			__INST(altDown) = upDown;
-			break;
-		}
-#endif
-
-		keySymString = XKeysymToString(keySym);
-		if (keySymString) {
-#ifdef OLD
-		    if (keySymString[0] == 'D') {
-			/*
-			 * remove underscore, dont want it in symbols
-			 */
-			if (strcmp(keySymString, "Delete_line") == 0) {
-			    keySymString = "DeleteLine";
-			} else if (strcmp(keySymString, "Delete_word") == 0) {
-			    keySymString = "DeleteWord";
-			}
-		    }
-		    /*
-		     * make names compatible
-		     */
-		    if (strcmp(keySymString, "Down") == 0) {
-			keySymString = "CursorDown";
-		    } else if (strcmp(keySymString, "Up") == 0) {
-			keySymString = "CursorUp";
-		    } else if (strcmp(keySymString, "Left") == 0) {
-			keySymString = "CursorLeft";
-		    } else if (strcmp(keySymString, "Right") == 0) {
-			keySymString = "CursorRight";
-		    }
-		    arg = __MKSYMBOL(keySymString, (OBJ *)0);
-#else
-		    arg = __MKSTRING(keySymString);
-#endif
-		}
-	    }
-
-	    if (arg == nil) {
-		/* happens sometimes (alt-graph on sun has no keysym) */
-		break;
-	    }
-
-	    (*(*ipS).ilc_func)(self, symS, nil, ipS,
-			       arg, 
-			       __MKSMALLINT(ev_x), 
-			       __MKSMALLINT(ev_y),
-			       theView);
-	    break;
-
-	case ButtonPress:
-	    __INST(buttonsPressed) = __MKSMALLINT(__intVal(__INST(buttonsPressed)) | (1 << be->button));
-	    __INST(eventRootX) = __MKSMALLINT(be->x_root);
-	    __INST(eventRootY) = __MKSMALLINT(be->y_root);
-
-	    if (__isSmallInteger(__INST(multiClickTimeDelta)))
-		nextMultiClickTime = be->time + __intVal(__INST(multiClickTimeDelta));
-	    else
-		nextMultiClickTime = 0;
-
-
-	    if ((t = __INST(multiClickTime)) != nil) {
-		INT _multiClickTime;
-
-		_multiClickTime = __longIntVal(t);
-		if (be->time < _multiClickTime) {
-		    __INST(multiClickTime) = t = __MKUINT(nextMultiClickTime); __STORE(self, t);
-		    /*
-		     * MKUINT could lead to a GC - refetch event ptr
-		     */
-		    eB = __INST(eventBuffer);
-		    ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-
-		    ipS = &bmpS;
-		    symS = @symbol(buttonMultiPress:x:y:view:);
-		    goto sendButtonEvent;
-		    break;
-		}
-	    }
-	    __INST(multiClickTime) = t = __MKUINT(nextMultiClickTime); __STORE(self, t);
-	    /*
-	     * MKUINT could lead to a GC - refetch event ptr
-	     */
-	    eB = __INST(eventBuffer);
-	    ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-
-#ifdef NO_LONGER
-	    if (be->state & ShiftMask) {
-		ipS = &bspS;
-		symS = @symbol(buttonShiftPress:x:y:view:);
-		goto sendButtonEvent;
-	    }
-#endif
-	    ipS = &bpS;
-	    symS = @symbol(buttonPress:x:y:view:);
-	    goto sendButtonEvent;
-
-	    /* NOT REACHED */
-
-	case ButtonRelease:
-	    __INST(buttonsPressed) = __MKSMALLINT(__intVal(__INST(buttonsPressed)) & ~(1 << be->button));
-	    __INST(eventRootX) = __MKSMALLINT(be->x_root);
-	    __INST(eventRootY) = __MKSMALLINT(be->y_root);
-	    ipS = &brS;
-	    symS = @symbol(buttonRelease:x:y:view:);
-	    /* fall into */
-
-	sendButtonEvent:
-	    butt = __MKSMALLINT(be->button);
-#ifdef NOTDEF
-	    /*
-	     * this allows operation with single button mouses: meta-click is always Button 2
-	     */
-	    if (__INST(metaDown) == true)
-		butt = __MKSMALLINT(2);
-	    else 
-#endif
-		butt = __AT_(__INST(buttonTranslation), butt);
-	    /*
-	     * #at: could lead to a GC - refetch event ptr
-	     */
-	    eB = __INST(eventBuffer);
-	    ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-
-
-	    (*(*ipS).ilc_func)(self, 
-			       symS, nil, ipS,
-			       butt, 
-			       __MKSMALLINT(ke->x), 
-			       __MKSMALLINT(ke->y),
-			       theView);
-	    break;
-
-	case MotionNotify:
-	    if (__INST(motionEventCompression) != false) {
-		while (XCheckWindowEvent(dpy, me->window, ANYBUTTON, ev)) ;;
-	    }
-
-	    __INST(eventRootX) = __MKSMALLINT(me->x_root);
-	    __INST(eventRootY) = __MKSMALLINT(me->y_root);
-
-#ifdef OLD
-	    __INST(altDown) = (me->state & Mod2Mask) ? true : false;
-	    __INST(metaDown) = (me->state & Mod1Mask) ? true : false;
-#else
-	    __INST(altDown) = (ke->state & __intVal(__INST(altModifierMask))) ? true : false;
-	    __INST(metaDown) = (ke->state & __intVal(__INST(metaModifierMask))) ? true : false;
-#endif
-	    __INST(shiftDown) = (me->state & ShiftMask) ? true : false;
-	    __INST(ctrlDown) = (me->state & ControlMask) ? true : false;
-
-	    (*motS.ilc_func)(self, 
-			     @symbol(buttonMotion:x:y:view:), nil, &motS,
-			     __MKSMALLINT(me->state),
-			     __MKSMALLINT(me->x),
-			     __MKSMALLINT(me->y),
-			     theView);
-	    break;
-
-	case FocusIn:
-	    (*focInS.ilc_func)(self, 
-			       @symbol(focusInView:), nil, &focInS, 
-			       theView);
-	    break;
-
-	case FocusOut:
-	    (*focOutS.ilc_func)(self, 
-				@symbol(focusOutView:), nil, &focOutS, 
-				theView);
-	    break;
-
-	case EnterNotify:
-#ifdef OLD
-	    __INST(altDown) = (ewe->state & Mod2Mask) ? true : false;
-	    __INST(metaDown) = (ewe->state & Mod1Mask) ? true : false;
-#else
-	    __INST(altDown) = (ke->state & __intVal(__INST(altModifierMask))) ? true : false;
-	    __INST(metaDown) = (ke->state & __intVal(__INST(metaModifierMask))) ? true : false;
-#endif
-	    __INST(shiftDown) = (ewe->state & ShiftMask) ? true : false;
-	    __INST(ctrlDown) = (ewe->state & ControlMask) ? true : false;
-
-	    (*peS.ilc_func)(self, 
-			    @symbol(pointerEnter:x:y:view:), nil, &peS,
-			    __MKSMALLINT(ewe->state),
-			    __MKSMALLINT(ewe->x), 
-			    __MKSMALLINT(ewe->y),
-			    theView);
-	    break;
-
-	case LeaveNotify:
-	    (*plS.ilc_func)(self, 
-			    @symbol(pointerLeave:view:), nil, &plS,
-			    __MKSMALLINT(lwe->state), 
-			    theView);
-	    break;
-
-	case GraphicsExpose:
-	    (*gexpS.ilc_func)(self, 
-			      @symbol(graphicsExposeX:y:width:height:final:view:), nil, &gexpS,
-			      __MKSMALLINT(ee->x),
-			      __MKSMALLINT(ee->y),
-			      __MKSMALLINT(ee->width),
-			      __MKSMALLINT(ee->height),
-			      ee->count == 0 ? true : false,
-			      theView);
-
-	    if (ee->count != 0) {
-		break;
-	    }
-	    /* fall into */
-
-	case NoExpose:
-	    (*nexpS.ilc_func)(self, 
-			      @symbol(noExposeView:), nil, &nexpS, 
-			      theView);
-	    break;
-
-	case Expose:
-	    (*expS.ilc_func)(self, 
-			     @symbol(exposeX:y:width:height:view:), nil, &expS,
-			     __MKSMALLINT(ee->x),
-			     __MKSMALLINT(ee->y),
-			     __MKSMALLINT(ee->width),
-			     __MKSMALLINT(ee->height),
-			     theView);
-	    break;
-
-	case ConfigureNotify:
-	    if (ce->above != None) {
-		siblingID = __MKEXTERNALADDRESS(ce->above);
-		sibling = (*vid.ilc_func)(self, @symbol(viewFromId:), nil, &vid, siblingID);
-		/*
-		 * MKEXTERNALADDRESS or #viewFromId: could lead to a GC - refetch event ptr
-		 */
-		eB = __INST(eventBuffer);
-		ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-	    }
-
-	    (*confS.ilc_func)(self, 
-			     @symbol(configureX:y:width:height:view:), nil, &confS,
-			     __MKSMALLINT(ce->x),
-			     __MKSMALLINT(ce->y),
-			     __MKSMALLINT(ce->width),
-			     __MKSMALLINT(ce->height),
-			     theView);
-	    if (sibling != nil) {
-		(*coveredS.ilc_func)(self,
-				    @symbol(coveredBy:view:), nil, &coveredS,
-				    theView,
-				    sibling);
-	    }
-	    break;
-
-	case ClientMessage:
-	    if (ev->xclient.message_type == (int) __AtomVal(__INST(protocolsAtom))) {
-		if ((ev->xclient.data.l[0] == (int) __AtomVal(__INST(quitAppAtom)))
-		 || (ev->xclient.data.l[0] == (int) __AtomVal(__INST(deleteWindowAtom)))) {
-		    (*termS.ilc_func)(self, 
-				      @symbol(terminateView:), nil, &termS, theView);
-		    break;
-		}
-		if (ev->xclient.data.l[0] == (int) __AtomVal(__INST(saveYourselfAtom))) {
-		    (*savtermS.ilc_func)(self, 
-					 @symbol(saveAndTerminateView:)
-					 , nil, &savtermS, theView);
-		    break;
-		}
-	    }
-	    /*
-	     * any other client message
-	     */
-	    i = (char *)(&(ev->xclient.data)) - (char *)ev;
-	    (*clientMsg.ilc_func)(self, 
-				 @symbol(clientMessage:type:format:dataOffset:view:)
-				 , nil, &clientMsg 
-				 , __INST(eventBuffer)
-				 ,__MKSMALLINT(ev->xclient.message_type)
-				 ,__MKSMALLINT(ev->xclient.format)
-				 ,__MKSMALLINT(i), 
-				 theView);
-	    break;
-
-	case DestroyNotify:
-	    (*destrS.ilc_func)(self, @symbol(destroyedView:)
-			       , nil, &destrS, theView);
-	    break;
-
-	case UnmapNotify:
-	    (*unmapS.ilc_func)(self, @symbol(unmappedView:) 
-			       , nil, &unmapS, theView);
-	    break;
-
-	case MapNotify:
-	    (*mapS.ilc_func)(self, 
-			     @symbol(mappedView:) 
-			     , nil, &mapS, theView);
-	    break;
-
-	case KeymapNotify:
-	    (*keymap.ilc_func)(theView, 
-			       @symbol(keyMapChange) 
-			       , nil, &keymap);
-	    break;
-
-	case VisibilityNotify:
-	    switch (ve->state) {
-		case VisibilityUnobscured:
-		    arg = @symbol(unobscured);
-		    break;
-		case VisibilityPartiallyObscured:
-		    arg = @symbol(partiallyObscured);
-		    break;
-		case VisibilityFullyObscured:
-		    arg = @symbol(fullyObscured);
-		    break;
-	    }
-	    (*vis.ilc_func)(theView, @symbol(visibilityChange:), nil, &vis, arg);
-	    break;
-
-	case CreateNotify:
-	    (*created.ilc_func)(self, @symbol(createdView:), nil, &created, theView);
-	    break;
-
-	case MapRequest:
-	    (*mapReq.ilc_func)(self, @symbol(mapRequestView:), nil, &mapReq, theView);
-	    break;
-
-	case ReparentNotify:
-	    (*repar.ilc_func)(self, @symbol(reparentedView:), nil, &repar, theView);
-	    break;
-
-	case ConfigureRequest:
-	    (*confReq.ilc_func)(self, @symbol(configureRequestView:), nil, &confReq, theView);
-	    break;
-
-	case GravityNotify:
-	    (*gravNotify.ilc_func)(self, @symbol(gravityNotifyView:), nil, &resReq, theView);
-	    break;
-
-	case ResizeRequest:
-	    (*resReq.ilc_func)(self, @symbol(resizeRequestView:), nil, &resReq, theView);
-	    break;
-
-	case CirculateNotify:
-	    (*circNotify.ilc_func)(self, @symbol(circulateNotifyView:), nil, &circNotify, theView);
-	    break;
-
-	case CirculateRequest:
-	    (*circReq.ilc_func)(self, @symbol(circulateRequestView:), nil, &circReq, theView);
-	    break;
-
-	case PropertyNotify:
-	    (*prop.ilc_func)(self, 
-			     @symbol(propertyChangeView:) 
-			     , nil, &prop,
-			     theView);
-	    break;
-
-	case SelectionClear:
-	    selectionID = __MKATOMOBJ(ev->xselectionclear.selection);
-	    (*selClear.ilc_func)(self, 
-				 @symbol(selectionClear:view:) 
-				 , nil, &selClear,
-				 selectionID,
-				 theView);
-	    break;
-
-	case SelectionNotify:
-	    /*
-	     * returned selection value (answer from SelectionRequest)
-	     */
-	    DPRINTF(("SelectionNotify prop=%x target=%x selection= %x requestor=%x\n", 
-			ev->xselection.property, ev->xselection.target,
-			ev->xselection.selection, ev->xselection.requestor));
-
-	    {
-		INT _property = ev->xselection.property;
-		INT _target = ev->xselection.target;
-		INT _selection = ev->xselection.selection;
-		INT _requestor = ev->xselection.requestor;
-
-		propertyID = __MKATOMOBJ(_property);
-		targetID = __MKATOMOBJ(_target);
-		selectionID = __MKATOMOBJ(_selection);
-		requestorID = __MKEXTERNALADDRESS(_requestor);
-	    }
-	    /*
-	     * MKATOMOBJ/MKEXTERNALADDRESS could lead to a GC - refetch event ptr
-	     */
-	    eB = __INST(eventBuffer);
-	    ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-
-	    (*selNotify.ilc_func)(self, 
-				  @symbol(selectionNotify:target:selection:from:view:) 
-				  , nil, &selNotify,
-				  propertyID, targetID, selectionID, requestorID,
-				  theView);
-	    break;
-
-	case SelectionRequest:
-	    /*
-	     * someone wants the selection
-	     */
-	    DPRINTF(("SelectionRequest prop=%x target=%x selection=%x requestor=%x\n", 
-			ev->xselectionrequest.property,
-			ev->xselectionrequest.target,
-			ev->xselectionrequest.selection,
-			ev->xselectionrequest.requestor));
-	    {
-		INT _property = ev->xselectionrequest.property;
-		INT _target = ev->xselectionrequest.target;
-		INT _selection = ev->xselectionrequest.selection;
-		INT _requestor = ev->xselectionrequest.requestor;
-		INT _t = ev->xselectionrequest.time;
-
-		propertyID = __MKATOMOBJ(_property);
-		targetID = __MKATOMOBJ(_target);
-		selectionID = __MKATOMOBJ(_selection);
-		requestorID = __MKEXTERNALADDRESS(_requestor);
-		evTime = __MKEXTERNALADDRESS(_t);
-	    }
-	    /*
-	     * MKATOMOBJ/MKEXTERNALADDR could lead to a GC - refetch event ptr
-	     */
-	    eB = __INST(eventBuffer);
-	    ev = (XEvent *)(__ByteArrayInstPtr(eB)->ba_element);
-
-	    (*selReq.ilc_func)(self, 
-			       @symbol(selectionRequest:target:selection:time:from:view:) 
-			       , nil, &selReq,
-			       propertyID, targetID, selectionID, evTime, requestorID,
-			       theView);
-	    break;
-
-	case ColormapNotify:
-	    (*colormap.ilc_func)(self, 
-				 @symbol(colorMapChangeView:) 
-				 , nil, &colormap,
-				 theView);
-	    break;
-
-	case MappingNotify:
-	    switch(mape->request) {
-		case MappingModifier:
-		    arg = @symbol(mappingModifier);
-		    break;
-		case MappingKeyboard:
-		    arg = @symbol(mappingKeyboard);
-		    break;
-		case MappingPointer:
-		    arg = @symbol(mappingPointer);
-		    break;
-		default:
-		    arg = nil;
-		    break;
-	    }
-	    (*mapping.ilc_func)(self, 
-				@symbol(mappingChanged:event:) 
-				, nil, &mapping, arg, eB);
-	    break;
-    }
-#undef ae
-#undef ee
-#undef ke
-#undef be
-#undef ce
-#undef me
-#undef ewe
-#undef lwe
-#undef de
-#undef mape
-%}.
-    ^ true
-!
-
-gravityNotifyView:aView
-    "ignored for now"
-
-    "/ aView gravityNotify
-!
-
-mapRequestView:aView
-    "ignored for now"
-
-    "/ aView mapRequest
-!
-
-mappingChanged:what event:eB
-    "OBSOLETE with newDispatchLastEvent!!
-     One of Keyboard-, Modifier- or PointerMap has change, probably by xmodmap.
-     Tell xlib about the fact."
-
-    (what == #mappingKeyboard or:[what == #mappingModifier]) ifTrue:[
-	self refreshKeyboardMapping:eB.
-	"Maybe some of our modifiers have been changed"
-	self initializeModifierMappings.
-    ].
-
-    "Created: 1.12.1995 / 16:28:23 / stefan"
-!
-
-propertyChangeView:aView
-    "sent when an X property changes.
-     This is a very X-specific mechanism."
-
-    aView isNil ifTrue:[
-	"/ event arrived, after I destroyed it myself
-	^ self
-    ].
-    aView propertyChange
-!
-
-resizeRequestView:aView
-    "ignored for now"
-
-    "/ aView resizeRequest
-!
-
-selectionClear:selectionID view:aView
-    "OBSOLETE - this will vanish"
-
-    "sent when another X-client has created a selection.
-     This is a very X-specific mechanism."
-
-    "/
-    "/ workaround a bug in olvwm: it clears selections
-    "/ on window raise.
-    "/ In this case, keep my last own selection.
-    "/
-
-    self setLastCopyBuffer:(self getCopyBuffer).
-    self setCopyBuffer:nil
-
-    "/ noone is interested in that ...
-    "/ aView selectionClear:selectionID
-!
-
-selectionNotify:propertyID target:targetID selection:selectionID from:requestorID view:aView
-    "sent when the server returns an answer from a request for a selection.
-     This is a very X-specific mechanism."
-
-    |s sensor|
-
-    propertyID == 0 ifTrue:[
-        "invalid olvwm behavior"
-        s := self getLastCopyBuffer
-    ] ifFalse:[
-        targetID == (self atomIDOf:#STRING) ifTrue:[
-            "
-             a returned string
-            "
-            s := self getTextProperty:propertyID from:requestorID.
-            s notNil ifTrue:[
-                (s endsWith:Character cr) ifTrue:[
-                    s := s asStringCollection copyWith:''
-                ]
-            ]
-        ] ifFalse:[
-            "
-             a returned object
-            "
-            s := self getObjectProperty:propertyID from:requestorID.
-        ].
-    ].
-
-    s notNil ifTrue:[
-        (sensor := aView sensor) notNil ifTrue:[
-            sensor pasteFromClipBoard:s view:aView
-        ] ifFalse:[
-            "
-             if there is no sensor ...
-            "
-            aView pasteFromClipBoard:s
-        ]
-    ]
-!
-
-selectionRequest:propertyID target:targetID selection:selectionID time:t from:windowID view:aView
-    "sent by some other X-client to ask for the selection.
-     This is a very X-specific mechanism."
-
-    |o s stream stringAtom|
-
-    targetID == (self atomIDOf:#LENGTH) ifTrue:[
-	"/
-	"/ the other one wants to know the size of our selection ...
-	"/
-	s := self selectionAsString.
-	self
-	    setLengthProperty:propertyID 
-	    value:s size 
-	    for:windowID.
-	self
-	    sendSelectionNotifySelection:selectionID
-	    property:propertyID
-	    target:targetID
-	    time:t
-	    from:aView id
-	    to:windowID.
-	^ self
-    ].
-
-    stringAtom := self atomIDOf:#STRING.
-    (targetID == stringAtom or:[
-     targetID == (self atomIDOf:#'COMPOUND_TEXT')]) ifTrue:[
-	"/
-	"/ the other view wants the selection as string
-	"/
-	s := self selectionAsString.
-	self
-	    sendSelection:s 
-	    selection:primaryAtom
-	    property:propertyID 
-	    target:stringAtom           "/ targetID
-	    time:t
-	    from:windowID
-	    to:windowID.
-	^ self
-    ].
-
-"/    (targetID == (self atomIDOf:#'TARGETS')) ifTrue:[
-"/"/ TODO: implement this to avoid netscape paste-delay.
-"/"/
-"/        ^ self
-"/    ].
-
-    (targetID == (self atomIDOf:#'ST_OBJECT')) ifTrue:[
-	"/
-	"/ send the selection in binaryStore format
-	"/ (assuming, that the other view knows how to handle it)
-	"/
-	o := self getCopyBuffer.
-	stream := WriteStream on:(ByteArray new:200).
-	o storeBinaryOn:stream.
-
-	^ self
-	    sendSelection:(stream contents) 
-	    selection:primaryAtom
-	    property:propertyID 
-	    target:targetID 
-	    time:t
-	    from:windowID 
-	    to:windowID
-    ].
-
-    "Created: / 17.6.1998 / 19:33:10 / cg"
-    "Modified: / 17.6.1998 / 20:24:40 / cg"
 ! !
 
 !XWorkstation methodsFor:'event sending'!
@@ -8654,7 +7701,7 @@
 
     primaryAtom := self atomIDOf:#PRIMARY.
     stringAtom := self atomIDOf:#STRING.
-    cutBuffer0Atom := self atomIDOf:#'CUT_BUFFER0'.
+    clipboardAtom := self atomIDOf:#CLIPBOARD.
 
     altModifierMask := self modifier2Mask.
     metaModifierMask := self modifier1Mask.
@@ -8675,12 +7722,12 @@
     hasColors := hasGreyscales := true.
     (visualType == #StaticGray
     or:[ visualType == #GrayScale]) ifTrue:[
-	hasColors := false.
-	monitorType := #monochrome.
+        hasColors := false.
+        monitorType := #monochrome.
     ].
 
     ncells == 2 ifTrue:[
-	hasColors := hasGreyscales := false.
+        hasColors := hasGreyscales := false.
     ].
 
     masks := self queryRGBMasks.
@@ -8690,13 +7737,13 @@
     bitsPerRGB := masks at:4.
 
     visualType == #TrueColor ifTrue:[
-	redShift := redMask lowBit - 1.
-	greenShift := greenMask lowBit - 1.
-	blueShift := blueMask lowBit - 1.
-
-	bitsRed := redMask highBit - redMask lowBit + 1.
-	bitsGreen := greenMask highBit - greenMask lowBit + 1.
-	bitsBlue := blueMask highBit - blueMask lowBit + 1.
+        redShift := redMask lowBit - 1.
+        greenShift := greenMask lowBit - 1.
+        blueShift := blueMask lowBit - 1.
+
+        bitsRed := redMask highBit - redMask lowBit + 1.
+        bitsGreen := greenMask highBit - greenMask lowBit + 1.
+        bitsBlue := blueMask highBit - blueMask lowBit + 1.
     ].
 
 %{
@@ -8714,33 +7761,33 @@
     int dummy;
 
     if (ISCONNECTED) {
-	dpy = myDpy;
-
-	/*
-	 * look for RGB visual
-	 */
-	nvi = 0;
-	viproto.screen = scr;
-	vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
-	maxRGBDepth = 0;
-	for (i = 0; i < nvi; i++) {
-	    switch (vip[i].class) {
-		case TrueColor:
-		    if (vip[i].depth > maxRGBDepth) {
-			maxRGBDepth = vip[i].depth;
-			rgbRedMask = vip[i].red_mask;
-			rgbGreenMask = vip[i].green_mask;
-			rgbBlueMask = vip[i].blue_mask;
-			rgbVisualID = vip[i].visualid;
-		    }
-		    break;
-	    }
-	}
-	if (vip) XFree ((char *) vip);
-
-	if (maxRGBDepth) {
-	    __INST(rgbVisual) = __MKEXTERNALADDRESS(rgbVisualID); __STORESELF(rgbVisual);
-	}
+        dpy = myDpy;
+
+        /*
+         * look for RGB visual
+         */
+        nvi = 0;
+        viproto.screen = scr;
+        vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
+        maxRGBDepth = 0;
+        for (i = 0; i < nvi; i++) {
+            switch (vip[i].class) {
+                case TrueColor:
+                    if (vip[i].depth > maxRGBDepth) {
+                        maxRGBDepth = vip[i].depth;
+                        rgbRedMask = vip[i].red_mask;
+                        rgbGreenMask = vip[i].green_mask;
+                        rgbBlueMask = vip[i].blue_mask;
+                        rgbVisualID = vip[i].visualid;
+                    }
+                    break;
+            }
+        }
+        if (vip) XFree ((char *) vip);
+
+        if (maxRGBDepth) {
+            __INST(rgbVisual) = __MKEXTERNALADDRESS(rgbVisualID); __STORESELF(rgbVisual);
+        }
     }
 %}.
 !
@@ -10018,118 +9065,83 @@
     "Modified: 30.6.1997 / 20:54:59 / cg"
 !
 
-setLengthProperty:propertyID value:aNumber for:aWindowID
-    "set a size property"
-
-    ^ self 
-	setProperty:propertyID 
-	type:(self atomIDOf:#LENGTH)
-	value:aNumber 
-	for:aWindowID
-
-    "Modified: 6.4.1997 / 13:27:26 / cg"
-!
-
-setObjectProperty:propertyID value:anObject for:aWindowID
-    "set a property to a smalltalk object in the XServer.
-     Non-strings can only be retrieved by another ST/X smalltalk"
-
-    |s|
-
-    (anObject isMemberOf:String) ifTrue:[
-	^ self setTextProperty:propertyID value:anObject for:aWindowID
-    ].
-    s := WriteStream on:(ByteArray new:200).
-    anObject storeBinaryOn:s.
-    ^ self 
-	setProperty:propertyID 
-	type:(self atomIDOf:#'ST_OBJECT') 
-	value:(s contents) 
-	for:aWindowID
-
-    "Modified: / 17.6.1998 / 17:23:49 / cg"
-!
-
 setProperty:propertyID type:typeID value:anObject for:aWindowID
     "set a property in the XServer"
 
     <context: #return>
 
+    |retval|
+
+    retval := false.
+
 %{  /* UNLIMITEDSTACK */
-    if (__isAtomID(propertyID)
-     && __isAtomID(typeID) 
-     && ISCONNECTED
-     && (__isString(anObject) 
-	 || __isSmallInteger(anObject) 
-	 || __isSymbol(anObject) 
-	 || __isByteArray(anObject)
-	 || __isWords(anObject))) {
-
-	Display *dpy = myDpy;
-	Atom prop, type;
-	Window window;
-	unsigned INT value;
-
-	prop = __AtomVal(propertyID);
-	type = __AtomVal(typeID);
-
-	if (__isExternalAddress(aWindowID)) {
-	    window = __WindowVal(aWindowID);
-	} else if (__isSmallInteger(aWindowID)) {
-	    window = (Window)__smallIntegerVal(aWindowID);
-	} else if (aWindowID == nil) {
-	    window = DefaultRootWindow(dpy);
-	} else {
-	    window = (Window)__unsignedLongIntVal(aWindowID);
-	}
-
-	ENTER_XLIB();
-	if (__isSmallInteger(anObject)) {
-	    value = __intVal(anObject);
-	    XChangeProperty(dpy, window, prop, type, 32,
-			    PropModeReplace,
-			    (unsigned char *)(&value), sizeof(unsigned int));
-	} else {
-	    if (__isByteArray(anObject)) {
-		XChangeProperty(dpy, window, prop, type, 8,
-				PropModeReplace,
-				__ByteArrayInstPtr(anObject)->ba_element,
-				__byteArraySize(anObject));
-	    } else {
-		/* string or symbol or wordArray-like (16bit-string) object */
-		if (__isWords(__qClass(anObject))) {
-		    XChangeProperty(dpy, window, prop, type, 16,
-				    PropModeReplace,
-				    __stringVal(anObject),
-				    __wordArraySize(anObject));
-		} else {
-		    /* must be string or symbol */
-		    XChangeProperty(dpy, window, prop, type, 8,
-				    PropModeReplace,
-				    __stringVal(anObject),
-				    __stringSize(anObject));
-		}
-	    }
-	}
-	LEAVE_XLIB();
-
-	DPRINTF(("changeProp win=%x prop=%x type=%x\n", window, prop, type));
-	RETURN (true);
-    }
-%}.
-    ^ false
-!
-
-setTextProperty:propertyID value:aString for:aWindowID
-    "set a property to a stringValue in the XServer"
-
-    ^ self 
-	setProperty:propertyID 
-	type:(self atomIDOf:#STRING) 
-	value:aString 
-	for:aWindowID
-
-    "Modified: 6.4.1997 / 13:26:32 / cg"
+    if (ISCONNECTED && __isAtomID(propertyID) && __isAtomID(typeID)) {
+        Display *dpy = myDpy;
+        Atom prop, type;
+        Window window;
+
+        prop = __AtomVal(propertyID);
+        type = __AtomVal(typeID);
+
+        if (__isExternalAddress(aWindowID)) {
+            window = __WindowVal(aWindowID);
+        } else if (aWindowID == nil) {
+            window = DefaultRootWindow(dpy);
+        } else if (__isInteger(aWindowID)) {
+            window = (Window)__unsignedLongIntVal(aWindowID);
+        } else {
+            RETURN(false);
+        }
+
+        retval = true;
+
+        ENTER_XLIB();
+        if (__isSmallInteger(anObject)) {
+            unsigned INT value = __intVal(anObject);
+            XChangeProperty(dpy, window, prop, type, 32,
+                            PropModeReplace,
+                            (unsigned char *)&value, 1);
+        } else if (__isByteArray(anObject)) {
+            XChangeProperty(dpy, window, prop, type, 8,
+                            PropModeReplace,
+                            __byteArrayVal(anObject),
+                            __byteArraySize(anObject));
+        } else if (__isWords(anObject)) {
+            /* wordArray-like (16bit-string) object */
+            XChangeProperty(dpy, window, prop, type, 16,
+                            PropModeReplace,
+                            __stringVal(anObject),
+                            __wordArraySize(anObject));
+        } else if (__isIntegerArray(anObject)) {
+            /* array of atoms */
+            XChangeProperty(dpy, window, prop, type, 32,
+                            PropModeReplace,
+                            __integerArrayVal(anObject),
+                            __integerArraySize(anObject));
+        } else if (__isString(anObject) || __isSymbol(anObject)) { 
+            XChangeProperty(dpy, window, prop, type, 8,
+                            PropModeReplace,
+                            __stringVal(anObject),
+                            __stringSize(anObject));
+        } else {
+            retval = false;
+        }
+        LEAVE_XLIB();
+
+        DPRINTF(("changeProp win=%x prop=%x type=%x\n", window, prop, type));
+    }
+%}.
+    ^ retval
+! !
+
+!XWorkstation methodsFor:'queries'!
+
+supportedClipboards
+    "answer a collection of symbols with the supported clipboards.
+     X11 additionaly supports a buffer containing the currently selected text 
+     (in xterm) - the PRIMARY selection"
+
+    ^ #(clipboard selection)
 ! !
 
 !XWorkstation methodsFor:'resources'!
@@ -10484,36 +9496,36 @@
 
 getSelectionFor:drawableId
     "get the object selection - either immediate, or asynchronous.
-     Returns nil, if async request is on its way"
-
-    (self getSelectionOwnerOf:primaryAtom) isNil ifTrue:[
-	"no primary selection - use cut buffer"
-	^ self getObjectProperty:cutBuffer0Atom from:nil.
-    ].
-    self requestSelection:primaryAtom 
-		 property:(self atomIDOf:#'ST_SELECTION') 
-		     type:(self atomIDOf:#'ST_OBJECT') 
-		      for:drawableId.
+     Returns nil, if async request is on its way.
+
+     Smalltalk puts ST_OBJECT only into the CLIPBOARD"
+
+    self requestSelection:clipboardAtom 
+                 property:(self atomIDOf:#'ST_SELECTION') 
+                     type:(self atomIDOf:#'ST_OBJECT') 
+                      for:drawableId.
     ^ nil
 
     "Modified: / 17.6.1998 / 17:11:15 / cg"
 !
 
-getTextSelectionFor:drawableId
+getTextSelection:selectionBufferSymbol for:drawableId
     "get the text selection -  either immediate, or asynchronous.
      Returns nil, if async request is on its way"
 
-    (self getSelectionOwnerOf:primaryAtom) isNil ifTrue:[
-	"no primary selection - use cut buffer"
-	^ self getTextProperty:cutBuffer0Atom from:nil.
-    ].
-    self requestSelection:primaryAtom 
-		 property:(self atomIDOf:#'VT_SELECTION') 
-		     type:stringAtom 
-		      for:drawableId.
-    ^ nil
-
-    "Modified: / 17.6.1998 / 17:12:05 / cg"
+    |selectionId|
+
+    selectionBufferSymbol == #selection ifTrue:[
+        selectionId := primaryAtom.
+    ] ifFalse:[
+        selectionId := clipboardAtom.
+    ].
+
+    self requestSelection:selectionId 
+                 property:(self atomIDOf:#'VT_SELECTION') 
+                     type:stringAtom 
+                      for:drawableId.
+    ^ nil.
 !
 
 removeSelectionHandler:aHandler
@@ -10525,47 +9537,105 @@
     ].
 !
 
+selectionAs:aTargetAtom
+    "convert the current selection to the format defined by aTargetAtom.
+     Answer the converted selection"
+
+    |stream|
+
+    aTargetAtom == (self atomIDOf:#LENGTH) ifTrue:[
+        "the other one wants to know the size of our selection.
+         LENGTH is deprecated, since we do not know how the selection is
+         going to be converted. The client must not rely on the length returned"
+
+        ^ self selectionAsString size 
+    ].
+
+    (aTargetAtom == (self atomIDOf:#STRING)) ifTrue:[
+        "the other view wants the selection as string"
+        ^ self selectionAsString. 
+    ].
+
+    (aTargetAtom == (self atomIDOf:#TARGETS)) ifTrue:[
+        "the other view wants to know which targets we support"
+        ^ self supportedTargetAtoms.
+    ].
+
+    (aTargetAtom == (self atomIDOf:#'ST_OBJECT')) ifTrue:[
+        "send the selection in binaryStore format"
+        stream := WriteStream on:(ByteArray new:200).
+        self getCopyBuffer storeBinaryOn:stream.
+        ^ stream contents.
+    ].
+
+    "we do not support the requestet target"
+    ^ nil.
+!
+
 sendSelection:something selection:selectionID property:propertyID target:targetID time:t from:windowID to:requestorID
-    "send aString back from a SelectionRequest"
-
-    self 
-	setProperty:propertyID 
-	type:targetID 
-	value:something 
-	for:requestorID.
-    self 
-	sendSelectionNotifySelection:selectionID 
-	property:propertyID 
-	target:targetID
-	time:t 
-	from:windowID 
-	to:requestorID.
-
-    "Modified: / 17.6.1998 / 17:03:20 / cg"
-    "Created: / 17.6.1998 / 19:44:03 / cg"
+    "send the selection back from a SelectionRequest"
+
+    |property|
+
+    property := propertyID.
+    property == 0 ifTrue:[
+        "Support old (obsolete) clients requesting a None property.
+         Set the propertyID to the targetID"
+
+        property := targetID.
+    ].
+
+    self setProperty:property 
+         type:targetID 
+         value:something 
+         for:requestorID.
+
+    self sendSelectionNotifySelection:selectionID 
+         property:property 
+         target:targetID
+         time:t 
+         from:windowID 
+         to:requestorID.
 !
 
 setSelection:anObject owner:aWindowId
     "set the object selection, and make aWindowId be the owner.
-     This can be used by other Smalltalk(X) applications only."
-
-    (self setSelectionOwner:aWindowId of:primaryAtom) ifFalse:[
-	^ false
-    ].
-"/    ^ self setObjectProperty:cutBuffer0Atom value:anObject for:nil
-    ^ true
+     This can be used by other Smalltalk(X) applications only.
+     We set only the CLIPBOARD selection"
+
+    ^ self setSelectionOwner:aWindowId of:clipboardAtom
 !
 
 setTextSelection:aString owner:aWindowId
     "set the text selection, and make aWindowId be the owner.
-     This can be used by any other X application."
-
-    (self setSelectionOwner:aWindowId of:primaryAtom) ifFalse:[
-	'XWorkstation [warning]: selection ownerchange failed' errorPrintCR.
-    ].
-    ^ self setTextProperty:cutBuffer0Atom value:aString for:rootId.
+     This can be used by any other X application.
+
+     We set poth the PRIMARY and CLIPBOARD, so that you can paste 
+     into xterm."
+
+    (self setSelectionOwner:aWindowId of:clipboardAtom) ifFalse:[
+        'XWorkstation [warning]: selection ownerchange failed' errorPrintCR.
+    ].
+    self setSelectionOwner:aWindowId of:primaryAtom.
+    ^ true
 
     "Modified: / 17.6.1998 / 19:48:54 / cg"
+!
+
+supportedTargetAtoms
+    "answer an integer array containing the list of supported targets
+     i.e. supported clipboard formats"
+
+    |supportedTargets numericTargetArray|
+
+    supportedTargets := #(STRING LENGTH TARGETS ST_OBJECT).
+
+    numericTargetArray := IntegerArray new:supportedTargets size.
+    supportedTargets keysAndValuesDo:[:index :targetSymbol| 
+        numericTargetArray at:index put:(self atomIDOf:targetSymbol)
+    ].
+
+    ^ numericTargetArray
 ! !
 
 !XWorkstation methodsFor:'selections-basic'!
@@ -10576,21 +9646,19 @@
     |selectionAtomID|
 
     selectionAtomSymbolOrID isString ifTrue:[
-	selectionAtomID := self atomIDOf:selectionAtomSymbolOrID create:false.
+        selectionAtomID := self atomIDOf:selectionAtomSymbolOrID create:false.
     ] ifFalse:[
-	selectionAtomID := selectionAtomSymbolOrID.
+        selectionAtomID := selectionAtomSymbolOrID.
     ].
 
 %{  
-    Atom selection;
     Window window;
 
-    if (__isAtomID(selectionAtomID)
-     && ISCONNECTED) {
-	Display *dpy = myDpy;
-
-	window = XGetSelectionOwner(dpy, __AtomVal(selectionAtomID));
-	RETURN ((window == None) ? nil : __MKEXTERNALADDRESS(window));
+    if (__isAtomID(selectionAtomID) && ISCONNECTED) {
+        Display *dpy = myDpy;
+
+        window = XGetSelectionOwner(dpy, __AtomVal(selectionAtomID));
+        RETURN ((window == None) ? nil : __MKEXTERNALADDRESS(window));
     }
 %}.
     self primitiveFailedOrClosedConnection.
@@ -10648,16 +9716,12 @@
 
     <context: #return>
 %{  
-    if (__isAtomID(propertyID)
-     && ISCONNECTED
-     && __isAtomID(targetID)
-     && __isAtomID(selectionID)) {
+    if (ISCONNECTED
+        && (__isAtomID(propertyID) || propertyID == nil)
+        && __isAtomID(targetID) && __isAtomID(selectionID)) {
         Display *dpy = myDpy;
         XEvent ev;
         Window requestor, originator;
-        Atom property = __AtomVal(propertyID);
-        Atom target = __AtomVal(targetID);
-        Atom selection = __AtomVal(selectionID);
         Status result;
 
         if (__isExternalAddress(requestorID)) {
@@ -10681,8 +9745,8 @@
 
         ev.xselection.type = SelectionNotify;
         ev.xselection.display = dpy;
-        ev.xselection.selection = selection;
-        ev.xselection.target = target;
+        ev.xselection.selection = __AtomVal(selectionID);
+        ev.xselection.target = __AtomVal(targetID);
         ev.xselection.requestor = originator;
 
         if (__isExternalAddress(t)) {
@@ -10701,10 +9765,13 @@
         printf("ev.xselection.time: %x\n", ev.xselection.time);
         printf("requestor: %x\n", requestor);
 #endif
-        if (property == None)
-            ev.xselection.property = target;
-        else
-            ev.xselection.property = property;
+
+        /* send nil property if selection cannot be converted */
+        if (propertyID == nil)
+            ev.xselection.property = None;
+        else 
+            ev.xselection.property = __AtomVal(propertyID);
+
 
         DPRINTF(("sending SelectionNotify sel=%x prop=%x target=%x requestor=%x to %x\n",
                 ev.xselection.selection,
@@ -10873,27 +9940,27 @@
     |x y width height depth borderWidth info|
 
 %{  
-    int x_return, y_return;
-    unsigned int width_return, height_return, 
-                 border_width_return, depth_return;
-    Window root_return;
+    int x_ret, y_ret;
+    unsigned int width_ret, height_ret, 
+                 border_width_ret, depth_ret;
+    Window root_ret;
 
     if (ISCONNECTED
      && __isExternalAddress(aWindowId)) {
         ENTER_XLIB();
         XGetGeometry(myDpy, __WindowVal(aWindowId), 
-                     &root_return, 
-                     &x_return, &y_return, 
-                     &width_return, &height_return, &border_width_return,
-                     &depth_return);
+                     &root_ret, 
+                     &x_ret, &y_ret, 
+                     &width_ret, &height_ret, &border_width_ret,
+                     &depth_ret);
         LEAVE_XLIB();
 
-        x = __MKSMALLINT(x_return);
-        y = __MKSMALLINT(y_return);
-        width = __MKSMALLINT(width_return);
-        height = __MKSMALLINT(height_return);
-        depth = __MKSMALLINT(depth_return);
-        borderWidth = __MKSMALLINT(border_width_return);
+        x = __MKSMALLINT(x_ret);
+        y = __MKSMALLINT(y_ret);
+        width = __MKSMALLINT(width_ret);
+        height = __MKSMALLINT(height_ret);
+        depth = __MKSMALLINT(depth_ret);
+        borderWidth = __MKSMALLINT(border_width_ret);
     }
 %}.
     borderWidth isNil ifTrue:[
@@ -11892,7 +10959,7 @@
 !XWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.419 2003-02-10 16:47:22 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.420 2003-02-11 13:39:50 stefan Exp $'
 ! !
 
 XWorkstation initialize!