diff -r 8ca406749929 -r 542bbbf55014 XWorkstation.st --- 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!