XWorkstation.st
changeset 3238 542bbbf55014
parent 3234 41d2d6dc8fa9
child 3245 b548dcf4993f
--- a/XWorkstation.st	Wed Jul 19 13:32:19 2000 +0200
+++ b/XWorkstation.st	Mon Jul 24 12:23:18 2000 +0200
@@ -4733,7 +4733,25 @@
     "/ aView resizeRequest
 !
 
-selectionClear:selectionID view:aView
+selectionClear:aView atom:selectionID time:time
+    "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
+
+!
+
+selectionClear:aView selection:selectionID time:time
     "sent when another X-client has created a selection.
      This is a very X-specific mechanism."
 
@@ -4750,6 +4768,65 @@
     "/ aView selectionClear:selectionID
 !
 
+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:aView selection:selectionID  target:targetID property:propertyID requestor:requestorID time:time
+    "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 atomIDOfSTRING 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
+        ]
+    ]
+!
+
 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."
@@ -4790,6 +4867,79 @@
     ]
 !
 
+selectionRequest:aView requestor:requestorID selection:selectionID target:targetID property:propertyID time:time
+    "sent by some other X-client to ask for the selection.
+     This is a very X-specific mechanism."
+
+    |o s stream|
+
+"/targetID printCR.
+
+    targetID == (self atomIDOfLENGTH) 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
+    ].
+
+    (targetID == self atomIDOfSTRING 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:self atomIDOfSTRING "/ 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
+    ].
+
+!
+
 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."
@@ -5165,7 +5315,7 @@
             goto circulate;
 
         case CirculateRequest:
-            __ArrayInstPtr(eventArr)->a_element[2] = @symbol(circulateNotify:place:);
+            __ArrayInstPtr(eventArr)->a_element[2] = @symbol(circulateRequest:place:);
             /* fall into */
         circulate:
             switch (cie->place) {
@@ -5201,7 +5351,7 @@
             break;
 
         case SelectionClear:
-            __ArrayInstPtr(eventArr)->a_element[2] = @symbol(propertyChange:atom:time:);
+            __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionClear:atom:time:);
             __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(sce->selection); __STORE(eventArr, t);
             __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(sce->time);      __STORE(eventArr, t);
             RETURN (true);
@@ -5223,11 +5373,13 @@
             /*
              * returned selection value (answer from SelectionRequest)
              */
-            __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionNotify:selection:target:property:time:);
-            __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(ev->xselectionrequest.selection); __STORE(eventArr, t);
-            __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ev->xselectionrequest.target);    __STORE(eventArr, t);
-            __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(ev->xselectionrequest.property);  __STORE(eventArr, t);
-            __ArrayInstPtr(eventArr)->a_element[6] = t = __MKUINT(ev->xselectionrequest.time);      __STORE(eventArr, t);
+            __ArrayInstPtr(eventArr)->a_element[2] = @symbol(selectionNotify:selection:target:property:requestor:time:);
+            __ArrayInstPtr(eventArr)->a_element[3] = t = __MKUINT(ev->xselection.selection); __STORE(eventArr, t);
+            __ArrayInstPtr(eventArr)->a_element[4] = t = __MKUINT(ev->xselection.target);    __STORE(eventArr, t);
+            __ArrayInstPtr(eventArr)->a_element[5] = t = __MKUINT(ev->xselection.property);  __STORE(eventArr, t);
+            __ArrayInstPtr(eventArr)->a_element[6] = t = __MKEXTERNALADDRESS(ev->xselection.requestor); __STORE(eventArr, t);
+            __ArrayInstPtr(eventArr)->a_element[7] = t = __MKUINT(ev->xselection.time); __STORE(eventArr, t);
+
             RETURN (true);
 
         case ColormapNotify:
@@ -5315,11 +5467,6 @@
     ^ true
 !
 
-decomposeLastEventInto:eventArr
-    ^ self decomposeEventBuffer:eventBuffer into:eventArr
-
-!
-
 defaultEventMask
     "return a mask to enable some events by default."
 
@@ -6399,7 +6546,7 @@
     |arr|
 
     arr := Array new:13.
-    self decomposeLastEventInto:arr.
+    self decomposeEventBuffer:eventBuffer into:arr.
     (self dispatchLastEvent:arr) ifFalse:[
         self dispatchLastEvent
     ]
@@ -9592,54 +9739,58 @@
      && __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 {
-	    window = DefaultRootWindow(dpy);
-	}
-
-	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));
-		}
-	    }
-	}
-	DPRINTF(("changeProp win=%x prop=%x type=%x\n", window, prop, type));
-	RETURN (true);
+         || __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);
+        }
+
+        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));
+                }
+            }
+        }
+        DPRINTF(("changeProp win=%x prop=%x type=%x\n", window, prop, type));
+        RETURN (true);
     }
 %}.
     ^ false
@@ -10150,55 +10301,82 @@
 
 %{  /* NOCONTEXT */
     if (__isAtomID(propertyID)
-     && __isExternalAddress(requestorID)
      && ISCONNECTED
      && __isAtomID(targetID)
      && __isAtomID(selectionID)) {
-	Display *dpy = myDpy;
-	XEvent ev;
-	Window requestor = _WindowVal(requestorID);
-	Atom property = _AtomVal(propertyID);
-	Atom target = _AtomVal(targetID);
-	Atom selection = _AtomVal(selectionID);
-	Status result;
-
-	ev.xselection.type = SelectionNotify;
-	ev.xselection.display = dpy;
-	ev.xselection.selection = selection;
-	ev.xselection.target = target;
-	if (__isExternalAddress(windowID))
-	    ev.xselection.requestor = _WindowVal(windowID);
-	else
-	    ev.xselection.requestor = DefaultRootWindow(dpy);
-	if (__isExternalAddress(t)) {
-	    ev.xselection.time = (INT)(__externalAddressVal(t));
-	} else {
-	    ev.xselection.time = CurrentTime;
-	}
-	if (property == None)
-	    ev.xselection.property = target;
-	else
-	    ev.xselection.property = property;
-
-	DPRINTF(("sending SelectionNotify sel=%x prop=%x target=%x requestor=%x to %x\n",
-		ev.xselection.selection,
-		ev.xselection.property,
-		ev.xselection.target,
-		ev.xselection.requestor,
-		requestor));
-
-	ENTER_XLIB();
-	result = XSendEvent(dpy, requestor, False, 0 , &ev);
-	LEAVE_XLIB();
-
-	if ((result == BadValue) || (result == BadWindow)) {
-	    DPRINTF(("bad status\n"));
-	    RETURN (false);
-	}
-	ENTER_XLIB();
-	XFlush(dpy);
-	LEAVE_XLIB();
-	RETURN (true)
+        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)) {
+            requestor = _WindowVal(requestorID);
+        } else if (__isSmallInteger(requestorID)) {
+            requestor = (Window)__smallIntegerVal(requestorID);
+        } else if (requestorID == nil) {
+            requestor = DefaultRootWindow(dpy);
+        } else {
+            requestor = (Window)__unsignedLongIntVal(requestorID);
+        }
+        if (__isExternalAddress(windowID)) {
+            originator = _WindowVal(windowID);
+        } else if (__isSmallInteger(windowID)) {
+            originator = (Window)__smallIntegerVal(windowID);
+        } else if (windowID == nil) {
+            originator = DefaultRootWindow(dpy);
+        } else {
+            originator = (Window)__unsignedLongIntVal(windowID);
+        }
+
+        ev.xselection.type = SelectionNotify;
+        ev.xselection.display = dpy;
+        ev.xselection.selection = selection;
+        ev.xselection.target = target;
+        ev.xselection.requestor = originator;
+
+        if (__isExternalAddress(t)) {
+            ev.xselection.time = (INT)(__externalAddressVal(t));
+        } else if (__isSmallInteger(t)) {
+            ev.xselection.time = __smallIntegerVal(t);
+        } else if (t == nil) {
+            ev.xselection.time = CurrentTime;
+        } else {
+            ev.xselection.time = (INT)__unsignedLongIntVal(t);
+        }
+#if 0
+        printf("ev.xselection.selection: %x\n", ev.xselection.selection);
+        printf("ev.xselection.target: %x\n", ev.xselection.target);
+        printf("ev.xselection.requestor: %x\n", ev.xselection.requestor);
+        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;
+
+        DPRINTF(("sending SelectionNotify sel=%x prop=%x target=%x requestor=%x to %x\n",
+                ev.xselection.selection,
+                ev.xselection.property,
+                ev.xselection.target,
+                ev.xselection.requestor,
+                requestor));
+
+        ENTER_XLIB();
+        result = XSendEvent(dpy, requestor, False, 0 , &ev);
+        LEAVE_XLIB();
+
+        if ((result == BadValue) || (result == BadWindow)) {
+            DPRINTF(("bad status\n"));
+            RETURN (false);
+        }
+        ENTER_XLIB();
+        XFlush(dpy);
+        LEAVE_XLIB();
+        RETURN (true)
     }
 %}.
     self primitiveFailed.
@@ -11242,6 +11420,6 @@
 !XWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.364 2000-07-13 12:06:51 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.365 2000-07-24 10:23:18 cg Exp $'
 ! !
 XWorkstation initialize!