--- a/XWorkstation.st Wed Sep 15 01:03:38 2004 +0200
+++ b/XWorkstation.st Wed Sep 15 01:06:05 2004 +0200
@@ -21,14 +21,24 @@
motifWMHintsAtom listOfXFonts buttonsPressed eventRootX
eventRootY displayName eventTrace dispatchingExpose rgbVisual
virtualRootId rootId altModifierMask metaModifierMask
- multiClickTime deviceIOTimeoutErrorSignal activateOnClick
- rawKeySymTranslation selectionOwner xlibTimeout xlibTimeoutForWindowCreation'
+ lastEventTime lastButtonPressTime deviceIOTimeoutErrorSignal
+ activateOnClick rawKeySymTranslation selectionOwner selectionTime
+ selectionFetchers preWaitAction xlibTimeout
+ xlibTimeoutForWindowCreation'
classVariableNames:'RawKeySymTranslation ConservativeSync MaxStringLength
- SelectionHandlers DefaultXLibTimeout DefaultXLibTimeoutForWindowCreation'
+ DefaultXLibTimeout DefaultXLibTimeoutForWindowCreation'
poolDictionaries:''
category:'Interface-Graphics'
!
+Object subclass:#SelectionFetcher
+ instanceVariableNames:'sema message display drawableID propertyID targetID buffer done
+ incremental'
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:XWorkstation
+!
+
!XWorkstation primitiveDefinitions!
%{
@@ -204,14 +214,14 @@
*/
#define __ENTER_XLIB(whichTimeout) \
{ \
- __blockingPrimitiveTimoutHandler__ = (VOIDFUNC)__XTimeoutErrorHandler; \
- __blockingPrimitiveTimeoutArg__ = (INT)self; \
- __blockingPrimitiveTimeout__ = __intVal(__INST(whichTimeout)) * 50; \
+ __blockingPrimitiveTimoutHandler__ = (VOIDFUNC)__XTimeoutErrorHandler; \
+ __blockingPrimitiveTimeoutArg__ = (INT)self; \
+ __blockingPrimitiveTimeout__ = __intVal(__INST(whichTimeout)) * 50; \
} {
#define LEAVE_XLIB() \
{ \
- __blockingPrimitiveTimeout__ = 0; \
+ __blockingPrimitiveTimeout__ = 0; \
} }
#define ENTER_XLIB() __ENTER_XLIB(xlibTimeout)
@@ -305,22 +315,25 @@
# endif
static
dummyToForceLoading() {
- XCreateSimpleWindow(0, 0, 0, 0, 0, 0, 0, 0, 0);
- XCloseDisplay(0);
- XCreateImage(0, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0);
- XSetWindowColormap(0, 0, 0);
- XQueryColors(0,0,0,0);
+ XCreateSimpleWindow(0, 0, 0, 0, 0, 0, 0, 0, 0);
+ XCloseDisplay(0);
+ XCreateImage(0, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0);
+ XSetWindowColormap(0, 0, 0);
+ XQueryColors(0,0,0,0);
# ifdef SHM
- XShmAttach(0, 0);
- XShmCreateImage(0, 0, 0, 0, 0, 0, 0 ,0);
- XShmDetach(0, 0);
- XShmPutImage(0, 0, 0, 0 , 0,0,0,0,0,0,0);
- shmctl(0,0,0);
- fgetc(0);
+ XShmAttach(0, 0);
+ XShmCreateImage(0, 0, 0, 0, 0, 0, 0 ,0);
+ XShmDetach(0, 0);
+ XShmPutImage(0, 0, 0, 0 , 0,0,0,0,0,0,0);
+ shmctl(0,0,0);
+ fgetc(0);
# endif
}
#endif
+#undef __myInstPtr
+#define __myInstPtr(obj) ((struct __XWorkstation_struct *)(obj))
+
/*
* catch X-errors and forward as errorInterrupt:#DisplayError,
* (which itself invokes my handler and optionally raises an exceptionSignal)
@@ -338,26 +351,26 @@
lastErrorMsg[127] = '\0';
if (lastErrorMsg[0] == '\0') {
- sprintf(lastErrorMsg, "code: %d", event->error_code);
+ sprintf(lastErrorMsg, "code: %d", event->error_code);
}
lastRequestCode = event->request_code;
lastMinorCode = event->minor_code;
lastResource = event->resourceid;
if ((event->error_code == BadWindow) && (lastRequestCode == 4) && (lastMinorCode == 0)) {
- /*
- * this is a BadWindow error for X_DestroyWindow.
- * ignore it here, since it results from the GC freeing windows
- * in non bottom-up window order.
- */
- return 0;
+ /*
+ * this is a BadWindow error for X_DestroyWindow.
+ * ignore it here, since it results from the GC freeing windows
+ * in non bottom-up window order.
+ */
+ return 0;
}
if (@global(ErrorPrinting) == true) {
- fprintf(stderr, "XWorkstation [error]: x-error caught maj=%d (0x%x) min=%d (0x%x) resource=%x\n",
- event->request_code, event->request_code,
- event->minor_code, event->minor_code, event->resourceid);
- fprintf(stderr, "XWorkstation [error]: x-error message is [%d] '%s'\n",
- event->error_code, lastErrorMsg);
+ fprintf(stderr, "XWorkstation [error]: x-error caught maj=%d (0x%x) min=%d (0x%x) resource=%x\n",
+ event->request_code, event->request_code,
+ event->minor_code, event->minor_code, event->resourceid);
+ fprintf(stderr, "XWorkstation [error]: x-error message is [%d] '%s'\n",
+ event->error_code, lastErrorMsg);
}
__errorInterruptWithIDAndParameter__(@symbol(DisplayError), __MKEXTERNALADDRESS(dpy));
@@ -377,10 +390,10 @@
Display *dpy;
{
if (@global(ErrorPrinting) == true) {
- fprintf(stderr, "XWorkstation [error]: I/O error\n");
+ fprintf(stderr, "XWorkstation [error]: I/O error\n");
}
__immediateErrorInterruptWithIDAndParameter__(@symbol(DisplayIOError),
- __MKEXTERNALADDRESS(dpy));
+ __MKEXTERNALADDRESS(dpy));
#if 0
/*
@@ -414,12 +427,12 @@
extern OBJ __GLOBAL_GET_BY_NAME();
if (@global(ErrorPrinting) == true) {
- fprintf(stderr, "XWorkstation [error]: I/O request timeout dpy=%x\n", displayDeviceInst);
+ fprintf(stderr, "XWorkstation [error]: I/O request timeout dpy=%x\n", displayDeviceInst);
}
if ((displayDeviceInst == @global(MainDisplay))
|| (displayDeviceInst == __GLOBAL_GET_BY_NAME("Display"))) { /* cannot use global(Display), because Display is a typedef in Xlib */
- fprintf(stderr, "XWorkstation [error]: keep display connection for master display (no shutdown)\n");
- return;
+ fprintf(stderr, "XWorkstation [error]: keep display connection for master display (no shutdown)\n");
+ return;
}
#if 0
@@ -446,10 +459,10 @@
* if we return from the error interrupt ...
*/
if (__OINST(displayDeviceInst, displayId) != nil) {
- __internalError("unhandled display Timeout error");
-
- __terminateProcess(0); /* soft terminate */
- __terminateProcess(1); /* hard terminate */
+ __internalError("unhandled display Timeout error");
+
+ __terminateProcess(0); /* soft terminate */
+ __terminateProcess(1); /* hard terminate */
}
}
@@ -476,29 +489,29 @@
*/
# if !defined(IRIS) || defined(IRIX5)
if (root) {
- vRootAtom = XInternAtom(dpy, "__SWM_VROOT", True);
- if (vRootAtom != None) {
- if (XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren)) {
- for (i=0; i < numChildren; i++) {
- Atom actual_type;
- int actual_format;
- unsigned long nitems, bytesafter;
- Window* newRoot = (Window*) 0;
-
- if (children[i]) {
- if (XGetWindowProperty(dpy, children[i], vRootAtom,
- 0L, 1L, False, XA_WINDOW,
- &actual_type, &actual_format, &nitems, &bytesafter,
- (unsigned char**) &newRoot) == Success && newRoot) {
- root = *newRoot;
- XFree(newRoot); /* XXX */
- break;
- }
- }
- }
- }
- if (children) XFree( children );
- }
+ vRootAtom = XInternAtom(dpy, "__SWM_VROOT", True);
+ if (vRootAtom != None) {
+ if (XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren)) {
+ for (i=0; i < numChildren; i++) {
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems, bytesafter;
+ Window* newRoot = (Window*) 0;
+
+ if (children[i]) {
+ if (XGetWindowProperty(dpy, children[i], vRootAtom,
+ 0L, 1L, False, XA_WINDOW,
+ &actual_type, &actual_format, &nitems, &bytesafter,
+ (unsigned char**) &newRoot) == Success && newRoot) {
+ root = *newRoot;
+ XFree(newRoot); /* XXX */
+ break;
+ }
+ }
+ }
+ }
+ if (children) XFree( children );
+ }
}
# endif
return root;
@@ -634,22 +647,23 @@
when buffering is on, this may be
an error for a long-ago operation"
- |string requestCode s match line|
+ |string s match line|
string := self errorStringOfLastError.
- requestCode := self requestCodeOfLastError.
"
X specific: search the requestCode in '/usr/lib/X11/XErrorDB',
and append the name of the corresponding X-request
"
+ match := 'XRequest.' , self requestCodeOfLastError printString.
s := '/usr/lib/X11/XErrorDB' asFilename readStreamOrNil.
s notNil ifTrue:[
- match := 'XRequest.' , requestCode printString.
- line := s peekForLineStartingWith:match.
- line notNil ifTrue:[
- string := string , ' in ' , (line copyFrom:(line indexOf:$:)+1)
- ].
- s close.
+ line := s peekForLineStartingWith:match.
+ s close.
+ ].
+ line isNil ifTrue:[
+ string := string, ' in ', match
+ ] ifFalse:[
+ string := string , ' in ' , (line copyFrom:(line indexOf:$:)+1)
].
^ string
!
@@ -669,19 +683,19 @@
!
resourceIdOfLastError
- %{ /* NOCONTEXT */
-
- if (lastResource != 0) {
- RETURN ( __MKEXTERNALADDRESS(lastResource) );
- }
- %}.
-
- ^ nil
-
-
- "
- Screen resourceIdOfLastError
- "
+%{ /* NOCONTEXT */
+
+ if (lastResource != 0) {
+ RETURN ( __MKEXTERNALADDRESS(lastResource) );
+ }
+%}.
+
+ ^ nil
+
+
+ "
+ Screen resourceIdOfLastError
+ "
!
setConnectionTimeOut:seconds
@@ -4417,14 +4431,16 @@
buttonMotion:view state:state x:x y:y rootX:rX rootY:rY time:time
"forward a buttonMotion event for some view"
+ lastEventTime := time.
self buttonMotion:state x:x y:y view:view
!
buttonPress:view button:button state:state x:x y:y rootX:rX rootY:rY time:time
"forward a buttonPress event for some view"
- |logicalButton nextMultiClickTime|
-
+ |logicalButton|
+
+ lastEventTime := time.
altDown := state bitTest:altModifierMask.
metaDown := state bitTest:metaModifierMask.
shiftDown := state bitTest:(self shiftModifierMask).
@@ -4443,32 +4459,29 @@
].
logicalButton isInteger ifTrue:[
- buttonsPressed := buttonsPressed bitOr:(1 bitShift:logicalButton-1).
- ].
-
- multiClickTimeDelta notNil ifTrue:[
- nextMultiClickTime := time + multiClickTimeDelta.
- multiClickTime notNil ifTrue:[
- time < multiClickTime ifTrue:[
- multiClickTime := nextMultiClickTime.
- self buttonMultiPress:logicalButton x:x y:y view:view.
- ^ self.
- ]
- ].
- multiClickTime := nextMultiClickTime.
- ].
+ buttonsPressed := buttonsPressed bitOr:(1 bitShift:logicalButton-1).
+ ].
+
+ (multiClickTimeDelta notNil and:[lastButtonPressTime notNil]) ifTrue:[
+ time < (lastButtonPressTime + multiClickTimeDelta) ifTrue:[
+ lastButtonPressTime := time.
+ self buttonMultiPress:logicalButton x:x y:y view:view.
+ ^ self.
+ ].
+ ].
+ lastButtonPressTime := time.
view isNil ifTrue:[
- "/ event arrived, after I destroyed it myself
- ^ self
+ "/ event arrived, after I destroyed it myself
+ ^ self
].
logicalButton == 1 ifTrue:[
- activateOnClick == true ifTrue:[
- "/ dont raise above an active popup view.
- (activeKeyboardGrab isNil and:[activePointerGrab isNil]) ifTrue:[
- view topView raise.
- ]
- ].
+ activateOnClick == true ifTrue:[
+ "/ dont raise above an active popup view.
+ (activeKeyboardGrab isNil and:[activePointerGrab isNil]) ifTrue:[
+ view topView raise.
+ ]
+ ].
].
super buttonPress:logicalButton x:x y:y view:view
!
@@ -4478,6 +4491,7 @@
|logicalButton|
+ lastEventTime := time.
altDown := state bitTest:altModifierMask.
metaDown := state bitTest:metaModifierMask.
shiftDown := state bitTest:(self shiftModifierMask).
@@ -4495,7 +4509,7 @@
].
logicalButton isInteger ifTrue:[
- buttonsPressed := buttonsPressed bitClear:(1 bitShift:logicalButton-1).
+ buttonsPressed := buttonsPressed bitClear:(1 bitShift:logicalButton-1).
].
self buttonRelease:logicalButton x:x y:y view:view
!
@@ -4539,21 +4553,20 @@
dndMessage:event data:data view:targetView
"handle a DND drag&drop protocol message"
- |sensor dropType dropValue names i1 i2 t|
+ |sensor property dropType dropValue names i1 i2 propertyType|
dropType := data doubleWordAt:1.
"/ see def's in DragAndDropTypes.h
dropType := (self dndDropTypes) at:dropType+1 ifAbsent:#DndNotDnd.
- self
- getProperty:(self atomIDOf:#DndSelection)
- from:rootId
- delete:false
- into:[:type :value |
- t := type.
- dropValue := value
- ].
+ property := self
+ getProperty:(self atomIDOf:#DndSelection)
+ from:rootId
+ delete:false.
+
+ propertyType := property key.
+ dropValue := property value.
"/ preconvert into a collection
"/ of fileNames, string or byteArray
@@ -4564,83 +4577,72 @@
"/ in the default dropMessage handling of SimpleView.
dropType == #DndFiles ifTrue:[
- "/ actually, a list of fileNames
- t ~~ stringAtom ifTrue:[
- 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
- ^ self
- ].
-
- names := OrderedCollection new.
- i1 := 1.
- [i1 ~~ 0] whileTrue:[
- i2 := dropValue indexOf:(Character value:0) startingAt:i1.
- i2 ~~ 0 ifTrue:[
- names add:(dropValue copyFrom:i1 to:(i2-1)).
- i1 := i2 + 1.
- ] ifFalse:[
- i1 := i2
- ].
- ].
- dropValue := names.
- dropValue := dropValue collect:[:nm | nm asFilename].
- dropType := #files.
+ "/ actually, a list of fileNames
+ propertyType ~~ stringAtom ifTrue:[
+ 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
+ ^ self
+ ].
+
+ names := OrderedCollection new.
+ i1 := 1.
+ [i1 ~~ 0] whileTrue:[
+ i2 := dropValue indexOf:(Character value:0) startingAt:i1.
+ i2 ~~ 0 ifTrue:[
+ names add:(dropValue copyFrom:i1 to:(i2-1)).
+ i1 := i2 + 1.
+ ] ifFalse:[
+ i1 := i2
+ ].
+ ].
+ dropValue := names.
+ dropValue := dropValue collect:[:nm | nm asFilename].
+ dropType := #files.
] ifFalse:[ (dropType == #DndFile) ifTrue:[
- t ~~ stringAtom ifTrue:[
- 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
- ^ self
- ].
-
- dropValue := dropValue asFilename.
- dropType := #file.
+ propertyType ~~ stringAtom ifTrue:[
+ 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
+ ^ self
+ ].
+ dropValue := dropValue asFilename.
+ dropType := #file.
] ifFalse:[ (dropType == #DndDir) ifTrue:[
- t ~~ stringAtom ifTrue:[
- 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
- ^ self
- ].
-
- dropValue := dropValue asFilename.
- dropType := #directory.
+ propertyType ~~ stringAtom ifTrue:[
+ 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
+ ^ self
+ ].
+ dropValue := dropValue asFilename.
+ dropType := #directory.
] ifFalse:[ (dropType == #DndText) ifTrue:[
- t ~~ stringAtom ifTrue:[
- 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
- ^ self
- ].
-
- dropValue := dropValue.
- dropType := #text.
+ propertyType ~~ stringAtom ifTrue:[
+ 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
+ ^ self
+ ].
+ dropType := #text.
] ifFalse:[ (dropType == #DndExe) ifTrue:[
- t ~~ stringAtom ifTrue:[
- 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
- ^ self
- ].
-
- dropValue := dropValue.
- dropType := #executable.
+ propertyType ~~ stringAtom ifTrue:[
+ 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
+ ^ self
+ ].
+ dropType := #executable.
] ifFalse:[ (dropType == #DndLink) ifTrue:[
- t ~~ stringAtom ifTrue:[
- 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
- ^ self
- ].
-
- dropValue := dropValue.
- dropType := #link.
+ propertyType ~~ stringAtom ifTrue:[
+ 'XWorkstation [info]: expected a string propertyValue in drop' infoPrintCR.
+ ^ self
+ ].
+ dropType := #link.
] ifFalse:[ (dropType == #DndRawData) ifTrue:[
- dropValue := dropValue.
- dropType := #rawData.
+ dropType := #rawData.
] ifFalse:[
- 'XWorkstation [info]: unsupported dropType: ' infoPrint. dropType infoPrintCR.
- 'XWorkstation [info]: data: ' infoPrint. dropValue infoPrintCR.
-
- dropValue := dropValue.
- dropType := #unknown.
+ 'XWorkstation [info]: unsupported dropType: ' infoPrint. dropType infoPrintCR.
+ 'XWorkstation [info]: data: ' infoPrint. dropValue infoPrintCR.
+ dropType := #unknown.
]]]]]]].
(sensor := targetView sensor) notNil ifTrue:[
- sensor dropMessage:dropType data:dropValue view:targetView
+ sensor dropMessage:dropType data:dropValue view:targetView
] ifFalse:[
- "
- not posted, if there is no sensor ...
- "
+ "
+ not posted, if there is no sensor ...
+ "
]
"Created: 4.4.1997 / 17:59:37 / cg"
@@ -4682,43 +4684,39 @@
keyPress:view key:key code:keyCode state:state x:x y:y rootX:rX rootY:rY time:time
"forward a key-press event for some view"
+ lastEventTime := time.
altDown := state bitTest:altModifierMask.
metaDown := state bitTest:metaModifierMask.
shiftDown := state bitTest:(self shiftModifierMask).
ctrlDown := state bitTest:(self ctrlModifierMask).
key isNil ifTrue:[
- "/ happens sometimes on some systems
- "/ (alt-graph on sun has no keysym)
- ^ self
+ "/ happens sometimes on some systems
+ "/ (alt-graph on sun has no keysym)
+ ^ self
].
eventRootX := rX.
eventRootY := rY.
self keyPress:key x:x y:y view:view.
-
-
!
keyRelease:view key:key code:keyCode state:state x:x y:y rootX:rX rootY:rY time:time
"forward a key-release event for some view"
+ lastEventTime := time.
altDown := state bitTest:altModifierMask.
metaDown := state bitTest:metaModifierMask.
shiftDown := state bitTest:(self shiftModifierMask).
ctrlDown := state bitTest:(self ctrlModifierMask).
key isNil ifTrue:[
- "/ happens sometimes on some systems
- "/ (alt-graph on sun has no keysym)
- ^ self
+ "/ happens sometimes on some systems
+ "/ (alt-graph on sun has no keysym)
+ ^ self
].
eventRootX := rX.
eventRootY := rY.
self keyRelease:key x:x y:y view:view.
-
-
-
-
!
mappingNotify:view request:what event:eB
@@ -4736,6 +4734,7 @@
pointerEnter:view x:x y:y rootX:rX rootY:rY state:state mode:mode detail:detail time:time
"forward a pointer enter event for some view"
+ lastEventTime := time.
altDown := state bitTest:altModifierMask.
metaDown := state bitTest:metaModifierMask.
shiftDown := state bitTest:(self shiftModifierMask).
@@ -4749,6 +4748,7 @@
pointerLeave:view x:x y:y rootX:rX rootY:rY state:state mode:mode detail:detail time:time
"forward a pointer leave event for some view"
+ lastEventTime := time.
altDown := state bitTest:altModifierMask.
metaDown := state bitTest:metaModifierMask.
shiftDown := state bitTest:(self shiftModifierMask).
@@ -4759,29 +4759,34 @@
self pointerLeave:state view:view
!
-propertyChange:aView atom:atom state:aSymbol time:time
+propertyChange:aView property:propertyId state:aSymbol time:time
"sent when an X property changes.
This is a very X-specific mechanism."
+ |selectionFetcher|
+
+ lastEventTime := time.
aView isNil ifTrue:[
- "/ event arrived, after I destroyed it myself
- ^ self
- ].
+ "event arrived, after aView has been destroyed"
+ ^ self
+ ].
+
+"/ 'propertyChange ' infoPrint. (self atomName:propertyId) print. ': ' print. aSymbol printCR.
"/ aView propertyChange:atom state:aSymbol.
-!
-
-selectionClear:aView atom:selectionID time:time
+
+ selectionFetcher := self findSelectionFetcher:aView id.
+ selectionFetcher notNil ifTrue:[
+ selectionFetcher message:thisContext message.
+ ].
+!
+
+selectionClear:aView selection:selectionID time:time
"sent when another X-client has created a selection.
This is a very X-specific mechanism."
+ lastEventTime := time.
self setCopyBuffer:nil.
- SelectionHandlers notNil ifTrue:[
- SelectionHandlers do:[:eachHandler |
- eachHandler selectionClear:selectionID
- ]
- ].
-
"/ noone is interested in that ...
"/ aView selectionClear:selectionID
!
@@ -4790,7 +4795,7 @@
"sent when the server returns an answer from a request for a selection.
This is a very X-specific mechanism."
- |clipBoardContents|
+ |selectionFetcher|
"/ Transcript show:'seletionNotify selID:'.
"/ Transcript show:selectionID; show:' ('; show:(self atomName:selectionID); show:') '.
@@ -4801,51 +4806,56 @@
"/ Transcript showCR:''.
"/ Transcript endEntry.
- clipBoardContents := self getProperty:propertyID type:targetID from:requestorID.
- clipBoardContents notNil ifTrue:[
- aView sensor pasteFromClipBoard:clipBoardContents view:aView
- ]
+ lastEventTime := time.
+
+ aView isNil ifTrue:[
+ "event arrived, after aView has been destroyed"
+ ^ self
+ ].
+ selectionFetcher := self findSelectionFetcher:aView id.
+ selectionFetcher notNil ifTrue:[
+ selectionFetcher message:thisContext message.
+ ].
!
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."
- |selection targetIdOut|
+ |selection property|
"/'Selection: ' print. (self atomName:selectionID) print. ' TargetId: ' print. (self atomName:targetID) print.
"/' Property: ' print. (self atomName:propertyID) print. ' Requestor: ' print. requestorID printCR.
+ lastEventTime := time.
selection := self selectionAs:targetID.
+
+"/'Send selection: ' print. selection printCR.
+
+ property := propertyID.
+
selection isNil ifTrue:[
+ "sending property None tells the client,
+ that I could not convert"
"/ ('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.
+ property := nil.
+ ] ifFalse:[
+ 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:selection
+ for:requestorID.
+ ].
+
+ self sendSelectionNotifySelection:selectionID
+ property:property
+ target:targetID
+ time:time
+ to:requestorID.
!
visibilityNotify:aView state:how
@@ -4978,7 +4988,7 @@
eventArray := Array new:13.
(self getEventFor:aViewIdOrNil withMask:eventMask into:eventArray) ifTrue:[
- AbortSignal handle:[:ex |
+ AbortOperationRequest handle:[:ex |
ex return
] do:[
self dispatchEvent:eventArray.
@@ -5001,16 +5011,13 @@
!
dispatchLoop
- |flushBlock|
-
- flushBlock := [self flush].
-
- Processor addPreWaitAction:flushBlock.
-
+ preWaitAction := [self flush].
+ Processor addPreWaitAction:preWaitAction.
[
super dispatchLoop
] ensure:[
- Processor removePreWaitAction:flushBlock.
+ Processor removePreWaitAction:preWaitAction.
+ preWaitAction := nil.
].
!
@@ -5037,7 +5044,7 @@
eventArray := Array new:13.
[self eventPendingWithSync:false] whileTrue:[
(self getEventFor:nil withMask:nil into:eventArray) ifTrue:[
- AbortSignal handle:[:ex |
+ AbortOperationRequest handle:[:ex |
ex return
] do:[
self dispatchEvent:eventArray.
@@ -5271,11 +5278,11 @@
The event fields are placed them into anEventArray (must be at least size 13):
the fields are:
- 1: windowID
- 2: eventType-ID
- 3: eventTypeSymbol
-
- 4.. args
+ 1: windowID
+ 2: eventType-ID
+ 3: eventTypeSymbol
+
+ 4.. args
Sorry I had to split dispatch into this fetch method and a separate
handler method to allow UNLIMITEDSTACK here.
@@ -5295,11 +5302,10 @@
int i, nchars;
char *keySymString;
char keySymStringBuffer[32];
- unsigned INT nextMultiClickTime;
OBJ arg, sym, t, windowID;
if (! ISCONNECTED) {
- RETURN (false);
+ RETURN (false);
}
dpy = myDpy;
@@ -5307,39 +5313,39 @@
ev.type = 0;
if (__isSmallInteger(eventMask)) {
- evMask = __intVal(eventMask);
+ evMask = __intVal(eventMask);
} else {
- evMask = ~0;
+ evMask = ~0;
}
if (__isExternalAddress(aViewIdOrNil)) {
- wWanted = __WindowVal(aViewIdOrNil);
- returnValue = XCheckWindowEvent(dpy, wWanted, evMask, &ev);
+ wWanted = __WindowVal(aViewIdOrNil);
+ returnValue = XCheckWindowEvent(dpy, wWanted, evMask, &ev);
} else {
- if (evMask == ~0) {
- XNextEvent(dpy, &ev);
- returnValue = 1;
- } else {
- returnValue = XCheckMaskEvent(dpy, evMask, &ev);
- }
+ if (evMask == ~0) {
+ XNextEvent(dpy, &ev);
+ returnValue = 1;
+ } else {
+ returnValue = XCheckMaskEvent(dpy, evMask, &ev);
+ }
}
if (!returnValue) {
- /* there is no event */
- RETURN (false);
+ /* there is no event */
+ RETURN (false);
}
if (anEventArray == nil) {
- /* sender is not interested in the event */
- RETURN(true);
+ /* sender is not interested in the event */
+ RETURN(true);
}
if (!__isArray(anEventArray)) {
- fprintf(stderr, "XWorkstation: bad argument [%d]\n", __LINE__);
- RETURN (false);
+ fprintf(stderr, "XWorkstation: bad argument [%d]\n", __LINE__);
+ RETURN (false);
}
if (__arraySize(anEventArray) < 11) {
- fprintf(stderr, "XWorkstation: bad argument [%d]\n", __LINE__);
- RETURN (false);
+ fprintf(stderr, "XWorkstation: bad argument [%d]\n", __LINE__);
+ RETURN (false);
}
# define ANYBUTTON (Button1MotionMask | Button2MotionMask | Button3MotionMask)
@@ -5365,367 +5371,367 @@
# define cme ((XColormapEvent *)&ev)
if (((t = __INST(lastId)) != nil)
- && __isExternalAddress(t)
- && (__WindowVal(t) == ae->window)) {
- windowID = t;
+ && __isExternalAddress(t)
+ && (__WindowVal(t) == ae->window)) {
+ windowID = t;
} else {
- windowID = __MKEXTERNALADDRESS(ae->window);
+ windowID = __MKEXTERNALADDRESS(ae->window);
}
__ArrayInstPtr(anEventArray)->a_element[0] = windowID; __STORE(anEventArray, windowID);
__ArrayInstPtr(anEventArray)->a_element[1] = __MKSMALLINT(ev.type);
switch (ev.type) {
- case KeyRelease:
- sym = @symbol(keyRelease:key:code:state:x:y:rootX:rootY:time:);
- goto keyPressAndRelease;
-
- case KeyPress:
- sym = @symbol(keyPress:key:code:state:x:y:rootX:rootY:time:);
- /* FALL INTO */
-
- keyPressAndRelease:
- 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 {
- keySymString = XKeysymToString(keySym);
- if (keySymString) {
- arg = __MKSYMBOL(keySymString, 0);
- } else {
- arg = nil;
- }
- }
+ case KeyRelease:
+ sym = @symbol(keyRelease:key:code:state:x:y:rootX:rootY:time:);
+ goto keyPressAndRelease;
+
+ case KeyPress:
+ sym = @symbol(keyPress:key:code:state:x:y:rootX:rootY:time:);
+ /* FALL INTO */
+
+ keyPressAndRelease:
+ 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 {
+ keySymString = XKeysymToString(keySym);
+ if (keySymString) {
+ arg = __MKSYMBOL(keySymString, 0);
+ } else {
+ arg = nil;
+ }
+ }
#ifdef IGNORE_UNKNOWN_KEYCODES
- if (arg == nil) {
- /* happens sometimes (alt-graph on sun has no keysym) */
- RETURN (false);
- }
-#endif
- __ArrayInstPtr(anEventArray)->a_element[2] = sym;
-
- __ArrayInstPtr(anEventArray)->a_element[3] = arg; __STORE(anEventArray, arg);
- __ArrayInstPtr(anEventArray)->a_element[4] = t = __MKUINT(ke->keycode); __STORE(anEventArray, t);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ke->state);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ke->x);
- __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(ke->y);
- __ArrayInstPtr(anEventArray)->a_element[8] = __mkSmallInteger(ke->x_root);
- __ArrayInstPtr(anEventArray)->a_element[9] = __mkSmallInteger(ke->y_root);
- __ArrayInstPtr(anEventArray)->a_element[10] = t = __MKUINT(ke->time); __STORE(anEventArray, t);
- break;
-
- case ButtonPress:
- sym = @symbol(buttonPress:button:state:x:y:rootX:rootY:time:);
- goto buttonPressAndRelease;
-
- case ButtonRelease:
- sym = @symbol(buttonRelease:button:state:x:y:rootX:rootY:time:);
- /* fall into */
-
- buttonPressAndRelease:
- __ArrayInstPtr(anEventArray)->a_element[2] = sym;
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(be->button);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ke->state);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(be->x);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(be->y);
- __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(be->x_root);
- __ArrayInstPtr(anEventArray)->a_element[8] = __mkSmallInteger(be->y_root);
- __ArrayInstPtr(anEventArray)->a_element[9] = t = __MKUINT(be->time); __STORE(anEventArray, t);
- break;
-
- case MotionNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(buttonMotion:state:x:y:rootX:rootY:time:);
-
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(me->state);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(me->x);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(me->y);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(me->x_root);
- __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(me->y_root);
- __ArrayInstPtr(anEventArray)->a_element[8] = t = __MKUINT(me->time); __STORE(anEventArray, t);
- break;
-
- case FocusIn:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(focusIn:mode:detail:);
- goto focusInOut;
-
- case FocusOut:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(focusOut:mode:detail:);
- /* fall into */
-
- focusInOut:
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(fe->mode);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(fe->detail);
- break;
-
- case EnterNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(pointerEnter:x:y:rootX:rootY:state:mode:detail:time:);
- goto enterLeave;
-
- case LeaveNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(pointerLeave:x:y:rootX:rootY:state:mode:detail:time:);
- /* fall into */
-
- enterLeave:
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(ele->x);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ele->y);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ele->x_root);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ele->y_root);
- __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(ele->state);
- __ArrayInstPtr(anEventArray)->a_element[8] = __mkSmallInteger(ele->mode);
- __ArrayInstPtr(anEventArray)->a_element[9] = __mkSmallInteger(ele->detail);
- __ArrayInstPtr(anEventArray)->a_element[10] = t = __MKUINT(ele->time); __STORE(anEventArray, t);
- break;
-
- case Expose:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(expose:x:y:width:height:count:);
- goto expose;
-
- case GraphicsExpose:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(graphicsExpose:x:y:width:height:count:);
- /* fall into */
-
- expose:
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(ee->x);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ee->y);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ee->width);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ee->height);
- __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(ee->count);
- break;
-
- case NoExpose:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(noExposeView:);
- break;
-
- case VisibilityNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(visibilityNotify:state:);
- switch (ve->state) {
- case VisibilityUnobscured:
- __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(unobscured);
- break;
- case VisibilityPartiallyObscured:
- __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(partiallyObscured);
- break;
- case VisibilityFullyObscured:
- __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(fullyObscured);
- break;
- default:
- __ArrayInstPtr(anEventArray)->a_element[3] = __MKSMALLINT(ve->state);
- break;
- }
- break;
-
- case CreateNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(createWindow:x:y:width:height:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(cre->x);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(cre->y);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(cre->width);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(cre->height);
- break;
-
- case DestroyNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(destroyedView:);
- break;
-
- case UnmapNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(unmappedView:);
- break;
-
- case MapNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(mappedView:);
- break;
-
- case ConfigureNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(configure:x:y:width:height:above:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(ce->x);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ce->y);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ce->width);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ce->height);
- __ArrayInstPtr(anEventArray)->a_element[7] = nil;
- if (ce->above != None) {
- __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKEXTERNALADDRESS(ce->above); __STORE(anEventArray, t);
- }
- break;
-
- case GravityNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(gravityNotify:x:y:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(gre->x);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(gre->y);
- break;
-
- case ResizeRequest:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(resizeRequest:width:height:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(rr->width);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(rr->height);
- break;
-
- case ConfigureRequest:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(configureRequest:x:y:width:height:above:detail:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(cr->x);
- __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(cr->y);
- __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(cr->width);
- __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(cr->height);
- __ArrayInstPtr(anEventArray)->a_element[7] = nil;
- if (cr->above != None) {
- __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKEXTERNALADDRESS(cr->above); __STORE(anEventArray, t);
- }
- switch (cr->detail) {
- case Above:
- __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(above);
- break;
- case Below:
- __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(below);
- break;
- case TopIf:
- __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(topIf);
- break;
- case BottomIf:
- __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(bottomIf);
- break;
- case Opposite:
- __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(opposite);
- break;
- default:
- __ArrayInstPtr(anEventArray)->a_element[8] = __MKSMALLINT(cr->detail);
- break;
- }
- break;
-
- case CirculateNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(circulateNotify:place:);
- goto circulate;
-
- case CirculateRequest:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(circulateRequest:place:);
- /* fall into */
- circulate:
- switch (cie->place) {
- case PlaceOnTop:
- __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(placeOnTop);
- break;
- case PlaceOnBottom:
- __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(placeOnBottom);
- break;
- default:
- __ArrayInstPtr(anEventArray)->a_element[3] = __MKSMALLINT(cie->place);
- break;
- }
- break;
-
- case PropertyNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(propertyChange:atom:state:time:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(pe->atom);
- switch (pe->state) {
- case PropertyNewValue:
- __ArrayInstPtr(anEventArray)->a_element[4] = @symbol(newValue);
- break;
- case PropertyDelete:
- __ArrayInstPtr(anEventArray)->a_element[4] = @symbol(deleted);
- break;
- default:
- __ArrayInstPtr(anEventArray)->a_element[4] = __MKSMALLINT(pe->state);
- break;
- }
- __ArrayInstPtr(anEventArray)->a_element[5] = t = __MKUINT(pe->time); __STORE(anEventArray, t);
- break;
-
- case SelectionClear:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(selectionClear:atom:time:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(sce->selection);
- __ArrayInstPtr(anEventArray)->a_element[4] = t = __MKUINT(sce->time); __STORE(anEventArray, t);
- break;
-
- case SelectionRequest:
- /*
- * someone wants the selection
- */
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(selectionRequest:requestor:selection:target:property:time:);
- __ArrayInstPtr(anEventArray)->a_element[3] = t = __MKEXTERNALADDRESS(ev.xselectionrequest.requestor); __STORE(anEventArray, t);
- __ArrayInstPtr(anEventArray)->a_element[4] = __MKATOMOBJ(ev.xselectionrequest.selection);
- __ArrayInstPtr(anEventArray)->a_element[5] = __MKATOMOBJ(ev.xselectionrequest.target);
- __ArrayInstPtr(anEventArray)->a_element[6] = __MKATOMOBJ(ev.xselectionrequest.property);
- __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKUINT(ev.xselectionrequest.time); __STORE(anEventArray, t);
- break;
-
- case SelectionNotify:
- /*
- * returned selection value (answer from SelectionRequest)
- */
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(selectionNotify:selection:target:property:requestor:time:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(ev.xselection.selection);
- __ArrayInstPtr(anEventArray)->a_element[4] = __MKATOMOBJ(ev.xselection.target);
- __ArrayInstPtr(anEventArray)->a_element[5] = __MKATOMOBJ(ev.xselection.property);
- __ArrayInstPtr(anEventArray)->a_element[6] = t = __MKEXTERNALADDRESS(ev.xselection.requestor); __STORE(anEventArray, t);
- __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKUINT(ev.xselection.time); __STORE(anEventArray, t);
- break;
-
- case ColormapNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(colormapNotify:state:);
- __ArrayInstPtr(anEventArray)->a_element[3] = cme->state == ColormapInstalled ? true : false;
- 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)))) {
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(terminateView:);
- break;
- }
- if (ev.xclient.data.l[0] == (int) __AtomVal(__INST(saveYourselfAtom))) {
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(saveAndTerminateView:);
- break;
- }
- }
- /*
- * any other client message
- */
+ if (arg == nil) {
+ /* happens sometimes (alt-graph on sun has no keysym) */
+ RETURN (false);
+ }
+#endif
+ __ArrayInstPtr(anEventArray)->a_element[2] = sym;
+
+ __ArrayInstPtr(anEventArray)->a_element[3] = arg; __STORE(anEventArray, arg);
+ __ArrayInstPtr(anEventArray)->a_element[4] = t = __MKUINT(ke->keycode); __STORE(anEventArray, t);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ke->state);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ke->x);
+ __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(ke->y);
+ __ArrayInstPtr(anEventArray)->a_element[8] = __mkSmallInteger(ke->x_root);
+ __ArrayInstPtr(anEventArray)->a_element[9] = __mkSmallInteger(ke->y_root);
+ __ArrayInstPtr(anEventArray)->a_element[10] = t = __MKUINT(ke->time); __STORE(anEventArray, t);
+ break;
+
+ case ButtonPress:
+ sym = @symbol(buttonPress:button:state:x:y:rootX:rootY:time:);
+ goto buttonPressAndRelease;
+
+ case ButtonRelease:
+ sym = @symbol(buttonRelease:button:state:x:y:rootX:rootY:time:);
+ /* fall into */
+
+ buttonPressAndRelease:
+ __ArrayInstPtr(anEventArray)->a_element[2] = sym;
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(be->button);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ke->state);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(be->x);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(be->y);
+ __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(be->x_root);
+ __ArrayInstPtr(anEventArray)->a_element[8] = __mkSmallInteger(be->y_root);
+ __ArrayInstPtr(anEventArray)->a_element[9] = t = __MKUINT(be->time); __STORE(anEventArray, t);
+ break;
+
+ case MotionNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(buttonMotion:state:x:y:rootX:rootY:time:);
+
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(me->state);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(me->x);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(me->y);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(me->x_root);
+ __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(me->y_root);
+ __ArrayInstPtr(anEventArray)->a_element[8] = t = __MKUINT(me->time); __STORE(anEventArray, t);
+ break;
+
+ case FocusIn:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(focusIn:mode:detail:);
+ goto focusInOut;
+
+ case FocusOut:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(focusOut:mode:detail:);
+ /* fall into */
+
+ focusInOut:
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(fe->mode);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(fe->detail);
+ break;
+
+ case EnterNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(pointerEnter:x:y:rootX:rootY:state:mode:detail:time:);
+ goto enterLeave;
+
+ case LeaveNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(pointerLeave:x:y:rootX:rootY:state:mode:detail:time:);
+ /* fall into */
+
+ enterLeave:
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(ele->x);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ele->y);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ele->x_root);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ele->y_root);
+ __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(ele->state);
+ __ArrayInstPtr(anEventArray)->a_element[8] = __mkSmallInteger(ele->mode);
+ __ArrayInstPtr(anEventArray)->a_element[9] = __mkSmallInteger(ele->detail);
+ __ArrayInstPtr(anEventArray)->a_element[10] = t = __MKUINT(ele->time); __STORE(anEventArray, t);
+ break;
+
+ case Expose:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(expose:x:y:width:height:count:);
+ goto expose;
+
+ case GraphicsExpose:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(graphicsExpose:x:y:width:height:count:);
+ /* fall into */
+
+ expose:
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(ee->x);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ee->y);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ee->width);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ee->height);
+ __ArrayInstPtr(anEventArray)->a_element[7] = __mkSmallInteger(ee->count);
+ break;
+
+ case NoExpose:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(noExposeView:);
+ break;
+
+ case VisibilityNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(visibilityNotify:state:);
+ switch (ve->state) {
+ case VisibilityUnobscured:
+ __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(unobscured);
+ break;
+ case VisibilityPartiallyObscured:
+ __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(partiallyObscured);
+ break;
+ case VisibilityFullyObscured:
+ __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(fullyObscured);
+ break;
+ default:
+ __ArrayInstPtr(anEventArray)->a_element[3] = __MKSMALLINT(ve->state);
+ break;
+ }
+ break;
+
+ case CreateNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(createWindow:x:y:width:height:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(cre->x);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(cre->y);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(cre->width);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(cre->height);
+ break;
+
+ case DestroyNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(destroyedView:);
+ break;
+
+ case UnmapNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(unmappedView:);
+ break;
+
+ case MapNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(mappedView:);
+ break;
+
+ case ConfigureNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(configure:x:y:width:height:above:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(ce->x);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(ce->y);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(ce->width);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(ce->height);
+ __ArrayInstPtr(anEventArray)->a_element[7] = nil;
+ if (ce->above != None) {
+ __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKEXTERNALADDRESS(ce->above); __STORE(anEventArray, t);
+ }
+ break;
+
+ case GravityNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(gravityNotify:x:y:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(gre->x);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(gre->y);
+ break;
+
+ case ResizeRequest:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(resizeRequest:width:height:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(rr->width);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(rr->height);
+ break;
+
+ case ConfigureRequest:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(configureRequest:x:y:width:height:above:detail:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __mkSmallInteger(cr->x);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __mkSmallInteger(cr->y);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __mkSmallInteger(cr->width);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __mkSmallInteger(cr->height);
+ __ArrayInstPtr(anEventArray)->a_element[7] = nil;
+ if (cr->above != None) {
+ __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKEXTERNALADDRESS(cr->above); __STORE(anEventArray, t);
+ }
+ switch (cr->detail) {
+ case Above:
+ __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(above);
+ break;
+ case Below:
+ __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(below);
+ break;
+ case TopIf:
+ __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(topIf);
+ break;
+ case BottomIf:
+ __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(bottomIf);
+ break;
+ case Opposite:
+ __ArrayInstPtr(anEventArray)->a_element[8] = @symbol(opposite);
+ break;
+ default:
+ __ArrayInstPtr(anEventArray)->a_element[8] = __MKSMALLINT(cr->detail);
+ break;
+ }
+ break;
+
+ case CirculateNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(circulateNotify:place:);
+ goto circulate;
+
+ case CirculateRequest:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(circulateRequest:place:);
+ /* fall into */
+ circulate:
+ switch (cie->place) {
+ case PlaceOnTop:
+ __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(placeOnTop);
+ break;
+ case PlaceOnBottom:
+ __ArrayInstPtr(anEventArray)->a_element[3] = @symbol(placeOnBottom);
+ break;
+ default:
+ __ArrayInstPtr(anEventArray)->a_element[3] = __MKSMALLINT(cie->place);
+ break;
+ }
+ break;
+
+ case PropertyNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(propertyChange:property:state:time:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(pe->atom);
+ switch (pe->state) {
+ case PropertyNewValue:
+ __ArrayInstPtr(anEventArray)->a_element[4] = @symbol(newValue);
+ break;
+ case PropertyDelete:
+ __ArrayInstPtr(anEventArray)->a_element[4] = @symbol(deleted);
+ break;
+ default:
+ __ArrayInstPtr(anEventArray)->a_element[4] = __MKSMALLINT(pe->state);
+ break;
+ }
+ __ArrayInstPtr(anEventArray)->a_element[5] = t = __MKUINT(pe->time); __STORE(anEventArray, t);
+ break;
+
+ case SelectionClear:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(selectionClear:selection:time:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(sce->selection);
+ __ArrayInstPtr(anEventArray)->a_element[4] = t = __MKUINT(sce->time); __STORE(anEventArray, t);
+ break;
+
+ case SelectionRequest:
+ /*
+ * someone wants the selection
+ */
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(selectionRequest:requestor:selection:target:property:time:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = t = __MKEXTERNALADDRESS(ev.xselectionrequest.requestor); __STORE(anEventArray, t);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __MKATOMOBJ(ev.xselectionrequest.selection);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __MKATOMOBJ(ev.xselectionrequest.target);
+ __ArrayInstPtr(anEventArray)->a_element[6] = __MKATOMOBJ(ev.xselectionrequest.property);
+ __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKUINT(ev.xselectionrequest.time); __STORE(anEventArray, t);
+ break;
+
+ case SelectionNotify:
+ /*
+ * returned selection value (answer from SelectionRequest)
+ */
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(selectionNotify:selection:target:property:requestor:time:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(ev.xselection.selection);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __MKATOMOBJ(ev.xselection.target);
+ __ArrayInstPtr(anEventArray)->a_element[5] = __MKATOMOBJ(ev.xselection.property);
+ __ArrayInstPtr(anEventArray)->a_element[6] = t = __MKEXTERNALADDRESS(ev.xselection.requestor); __STORE(anEventArray, t);
+ __ArrayInstPtr(anEventArray)->a_element[7] = t = __MKUINT(ev.xselection.time); __STORE(anEventArray, t);
+ break;
+
+ case ColormapNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(colormapNotify:state:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = cme->state == ColormapInstalled ? true : false;
+ 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)))) {
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(terminateView:);
+ break;
+ }
+ if (ev.xclient.data.l[0] == (int) __AtomVal(__INST(saveYourselfAtom))) {
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(saveAndTerminateView:);
+ break;
+ }
+ }
+ /*
+ * any other client message
+ */
printf("clientMessage type:%d format:%d\n", ev.xclient.message_type, ev.xclient.format);
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(clientMessage:type:format:data:);
- __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(ev.xclient.message_type);
- __ArrayInstPtr(anEventArray)->a_element[4] = __MKSMALLINT(ev.xclient.format);
- __ArrayInstPtr(anEventArray)->a_element[5] = t = __MKBYTEARRAY(ev.xclient.data, sizeof(ev.xclient.data)); __STORE(anEventArray, t);
- break;
-
- case MappingNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(mappingNotify:request:event:);
- switch(mape->request) {
- case MappingModifier:
- arg = @symbol(mappingModifier);
- break;
- case MappingKeyboard:
- arg = @symbol(mappingKeyboard);
- break;
- case MappingPointer:
- arg = @symbol(mappingPointer);
- break;
- default:
- arg = __MKSMALLINT(mape->request);
- break;
- }
- __ArrayInstPtr(anEventArray)->a_element[3] = arg;
- __ArrayInstPtr(anEventArray)->a_element[4] = t = __MKBYTEARRAY(&ev, sizeof(*mape));
- __STORE(anEventArray, t);
- break;
-
- case KeymapNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(keymapNotify:);
- break;
-
- case MapRequest:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(mapRequest:);
- break;
-
- case ReparentNotify:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(reparentedView:);
- break;
-
- default:
- __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(unknownX11Event);
- break;
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(clientMessage:type:format:data:);
+ __ArrayInstPtr(anEventArray)->a_element[3] = __MKATOMOBJ(ev.xclient.message_type);
+ __ArrayInstPtr(anEventArray)->a_element[4] = __MKSMALLINT(ev.xclient.format);
+ __ArrayInstPtr(anEventArray)->a_element[5] = t = __MKBYTEARRAY(ev.xclient.data, sizeof(ev.xclient.data)); __STORE(anEventArray, t);
+ break;
+
+ case MappingNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(mappingNotify:request:event:);
+ switch(mape->request) {
+ case MappingModifier:
+ arg = @symbol(mappingModifier);
+ break;
+ case MappingKeyboard:
+ arg = @symbol(mappingKeyboard);
+ break;
+ case MappingPointer:
+ arg = @symbol(mappingPointer);
+ break;
+ default:
+ arg = __MKSMALLINT(mape->request);
+ break;
+ }
+ __ArrayInstPtr(anEventArray)->a_element[3] = arg;
+ __ArrayInstPtr(anEventArray)->a_element[4] = t = __MKBYTEARRAY(&ev, sizeof(*mape));
+ __STORE(anEventArray, t);
+ break;
+
+ case KeymapNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(keymapNotify:);
+ break;
+
+ case MapRequest:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(mapRequest:);
+ break;
+
+ case ReparentNotify:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(reparentedView:);
+ break;
+
+ default:
+ __ArrayInstPtr(anEventArray)->a_element[2] = @symbol(unknownX11Event);
+ break;
}
#undef ae
#undef ee
@@ -8577,10 +8583,23 @@
!
reinitialize
-
+ preWaitAction notNil ifTrue:[
+ Processor removePreWaitAction:preWaitAction.
+ preWaitAction := nil.
+ ].
virtualRootId := rootId := nil.
+ selectionFetchers := nil.
super reinitialize.
dispatchingExpose := nil
+!
+
+releaseDeviceResources
+ preWaitAction notNil ifTrue:[
+ Processor removePreWaitAction:preWaitAction.
+ preWaitAction := nil.
+ ].
+ selectionFetchers := nil.
+ super releaseDeviceResources.
! !
!XWorkstation methodsFor:'keyboard mapping'!
@@ -9256,6 +9275,33 @@
"
! !
+!XWorkstation methodsFor:'private'!
+
+findSelectionFetcher:aDrawableId
+
+ selectionFetchers isNil ifTrue:[
+ ^ nil.
+ ].
+
+ ^ selectionFetchers detect:[:eachFetcher|
+ eachFetcher matchesDrawableId:aDrawableId
+ ] ifNone:[].
+!
+
+registerSelectionFetcher:aSelectionFetcher
+
+ selectionFetchers isNil ifTrue:[
+ selectionFetchers := OrderedCollection new.
+ ].
+
+ selectionFetchers add:aSelectionFetcher.
+!
+
+unregisterSelectionFetcher:aSelectionFetcher
+
+ selectionFetchers remove:aSelectionFetcher.
+! !
+
!XWorkstation methodsFor:'properties'!
deleteProperty:propertyID for:aWindowID
@@ -9291,44 +9337,23 @@
self primitiveFailedOrClosedConnection.
!
-getObjectProperty:propertyID from:aWindowID
- "get an object property from the server; return object or nil"
-
- self
- getProperty:propertyID
- from:aWindowID
- delete:true
- into:
- [:type :value |
- type == stringAtom ifTrue:[
- ^ value
- ].
- (value isMemberOf:ByteArray) ifTrue:[
- ^ (Object readBinaryFrom:(ReadStream on:value) onError:[nil])
- ]
- ].
- ^ nil
-
- "Modified: 6.4.1997 / 13:27:07 / cg"
-!
-
-getProperty:propertySymbolOrAtomID from:aWindowOrWindowIDOrNil delete:doDelete into:aTwoArgBlock
- "get a property, evaluate aTwoArgBlock with typeID and value"
+getProperty:propertySymbolOrAtomID from:aWindowOrWindowIDOrNil delete:doDelete
+ "get a property as an association propertyType->propertyValue"
<context: #return>
|val typeID propertyID windowID|
propertySymbolOrAtomID isString ifTrue:[
- propertyID := self atomIDOf:propertySymbolOrAtomID create:false.
- propertyID isNil ifTrue:[^ false].
+ propertyID := self atomIDOf:propertySymbolOrAtomID create:false.
+ propertyID isNil ifTrue:[^ nil].
] ifFalse:[
- propertyID := propertySymbolOrAtomID.
+ propertyID := propertySymbolOrAtomID.
].
aWindowOrWindowIDOrNil isView ifTrue:[
- windowID := aWindowOrWindowIDOrNil id.
+ windowID := aWindowOrWindowIDOrNil id.
] ifFalse:[
- windowID := aWindowOrWindowIDOrNil.
+ windowID := aWindowOrWindowIDOrNil.
].
%{
@@ -9343,170 +9368,87 @@
# define PROP_SIZE 2048
if (ISCONNECTED) {
- Display *dpy = myDpy;
-
- if (__isAtomID(propertyID)) {
- property = __AtomVal(propertyID);
-
- if (__isExternalAddress(windowID)) {
- window = __WindowVal(windowID);
- } else if (windowID == nil) {
- window = DefaultRootWindow(dpy);
- } else
- goto fail;
-
- nread = 0;
- cp = 0;
+ Display *dpy = myDpy;
+
+ if (__isAtomID(propertyID)) {
+ property = __AtomVal(propertyID);
+
+ if (__isExternalAddress(windowID)) {
+ window = __WindowVal(windowID);
+ } else if (windowID == nil) {
+ window = DefaultRootWindow(dpy);
+ } else
+ goto fail;
+
+ nread = 0;
+ cp = 0;
#ifdef PROPERTY_DEBUG
- fprintf(stderr, "getProperty %x\n", property);
-#endif
-
- do {
- int retVal;
-
- ENTER_XLIB();
- retVal = XGetWindowProperty(dpy, window, property, nread/4, PROP_SIZE,
- doDelete == true,
- AnyPropertyType, &actual_type, &actual_format,
- &nitems, &bytes_after, (unsigned char **)&data);
- LEAVE_XLIB();
- if (retVal != Success) {
+ fprintf(stderr, "getProperty %x\n", property);
+#endif
+
+ do {
+ int retVal;
+
+ ENTER_XLIB();
+ retVal = XGetWindowProperty(dpy, window, property, nread/4, PROP_SIZE,
+ doDelete == true,
+ AnyPropertyType, &actual_type, &actual_format,
+ &nitems, &bytes_after, (unsigned char **)&data);
+ LEAVE_XLIB();
+ if (retVal != Success) {
#ifdef PROPERTY_DEBUG
- fprintf(stderr, "- no success\n");
-#endif
- ok = 0;
- break;
- }
+ fprintf(stderr, "- no success\n");
+#endif
+ ok = 0;
+ break;
+ }
#ifdef PROPERTY_DEBUG
- fprintf(stderr, "- type:%x\n", actual_type);
-#endif
- typeID = __MKATOMOBJ(actual_type);
- if (! cp) {
- cp = cp2 = (char *)malloc(nitems+1);
- } else {
- cp = (char *)realloc(cp, nread + nitems + 1);
- cp2 = cp + nread;
- }
- if (! cp) {
- XFree(data);
- goto fail;
- }
-
- nread += nitems;
- bcopy(data, cp2, nitems);
- XFree(data);
+ fprintf(stderr, "- type:%x\n", actual_type);
+#endif
+ typeID = __MKATOMOBJ(actual_type);
+ if (! cp) {
+ cp = cp2 = (char *)malloc(nitems+1);
+ } else {
+ cp = (char *)realloc(cp, nread + nitems + 1);
+ cp2 = cp + nread;
+ }
+ if (! cp) {
+ XFree(data);
+ goto fail;
+ }
+
+ nread += nitems;
+ bcopy(data, cp2, nitems);
+ XFree(data);
#ifdef PROPERTY_DEBUG
- fprintf(stderr, "- <nitems:%d bytes_after:%d>\n", nitems, bytes_after);
-#endif
- } while (bytes_after > 0);
-
- if (ok) {
- if (actual_type == XA_STRING) {
- cp[nread] = '\0';
- val = __MKSTRING_L(cp, nread);
- } else {
- val = __MKBYTEARRAY(cp, nread);
- }
- }
- if (cp)
- free(cp);
- }
+ fprintf(stderr, "- <nitems:%d bytes_after:%d>\n", nitems, bytes_after);
+#endif
+ } while (bytes_after > 0);
+
+ if (ok) {
+ if (actual_type == XA_STRING) {
+ cp[nread] = '\0';
+ val = __MKSTRING_L(cp, nread);
+ } else {
+ val = __MKBYTEARRAY(cp, nread);
+ }
+ }
+ if (cp)
+ free(cp);
+ }
}
fail: ;
%}.
typeID isNil ifTrue:[
- ^ false
- ].
- aTwoArgBlock value:typeID value:val.
- ^ true
+ ^ nil
+ ].
+ ^ typeID->val
"
Display
- getProperty:#'_DESKTOP_COLORS'
- from:nil
- delete:false
- into:[:a :b | self halt]
- "
-!
-
-getProperty:propertyID type:targetID from:aWindowID
- | value |
-
- targetID == (self atomIDOf:#'ST_OBJECT') ifTrue:[
- "an object"
- ^ self getObjectProperty:propertyID from:aWindowID.
- ].
-
- (targetID == stringAtom
- or:[ targetID == (self atomIDOf:#'UTF8_STRING')
- or:[ targetID == (self atomIDOf:#'COMPOUND_TEXT')
- or:[ targetID == (self atomIDOf:#'TEXT') ]]]) ifTrue:[
- "some kind of string"
- value := self getTextProperty:propertyID from:aWindowID.
- value notNil ifTrue:[
- (value endsWith:Character cr) ifTrue:[
- value := value asStringCollection copyWith:''
- ]
- ].
- ^ value.
- ].
-
- 'XWorkstation [info]: unhandled targetType: ' infoPrint.
- (self atomName:targetID) infoPrintCR.
- ^ nil.
-!
-
-getTextProperty:propertyID from:aWindowID
- "get a text property; return string or nil"
-
- self
- getProperty:propertyID
- from:aWindowID
- delete:true
- into:
- [:type :value |
- |stringClass|
-
- type == stringAtom ifTrue:[
- clipBoardEncoding notNil ifTrue:[
- ^ value decodeFrom:clipBoardEncoding
- ].
- ^ value
- ].
-
- type == (self atomIDOf:#'UTF8_STRING') ifTrue:[
-"/ Transcript show:'UTF8: '; showCR:value storeString.
- ^ CharacterArray fromUTF8Bytes:value
- ].
-
- type == (self atomIDOf:#'TEXT') ifTrue:[
-"/ Transcript show:'TEXT: '; showCR:value storeString.
- ^ value asString
- ].
-
- type == (self atomIDOf:#'COMPOUND_TEXT') ifTrue:[
-"/ Transcript show:'COMPOUND_TEXT: '; showCR:value storeString.
- ^ value asString
- ].
-
- type == (self atomIDOf:#INCR) ifTrue:[
- 'XWorkstation: unimplemented property type: INCR value: ' infoPrint.
- value storeString infoPrintCR.
- ^ nil
- ].
-
- 'XWorkstation: unimplemented property type: ' infoPrint. type infoPrint.
- ' ' infoPrint. (self atomName:type) infoPrint.
- ' value:' infoPrint. value infoPrintCR.
- ^ nil
- ].
- ^ nil
-
- "Modified: 30.6.1997 / 20:54:59 / cg"
-
- "
- Display getTextProperty:#'_KDE_GENERAL' from:nil.
- Display getTextProperty:#'_DESKTOP_FONTS' from:nil.
+ getProperty:#'_NET_WM_ICON_GEOMETRY'
+ from:nil
+ delete:false
"
!
@@ -9519,9 +9461,9 @@
|windowID atoms|
aWindowOrWindowIDOrNil isView ifTrue:[
- windowID := aWindowOrWindowIDOrNil id.
+ windowID := aWindowOrWindowIDOrNil id.
] ifFalse:[
- windowID := aWindowOrWindowIDOrNil.
+ windowID := aWindowOrWindowIDOrNil.
].
%{
@@ -9530,41 +9472,41 @@
int i;
if (ISCONNECTED) {
- Display *dpy = myDpy;
- int numProps = 0;
-
- if (__isExternalAddress(windowID)) {
- window = __WindowVal(windowID);
- } else if (windowID == nil) {
- window = DefaultRootWindow(dpy);
- } else if (__isInteger(windowID)) {
- window = (Window)__unsignedLongIntVal(windowID);
- } else {
- goto fail;
- }
-
- ENTER_XLIB();
- atomListPtr = XListProperties(dpy, window, &numProps);
- LEAVE_XLIB();
-
- if (atomListPtr == NULL) {
- RETURN (nil);
- }
-
- atoms = __ARRAY_NEW_INT(numProps);
-
- if (atoms == nil) {
- goto fail;
- }
-
- for (i=0; i<numProps; i++) {
- OBJ atm;
-
- atm = __MKATOMOBJ(atomListPtr[i]);
- __ArrayInstPtr(atoms)->a_element[i] = atm; __STORE(atoms, atm);
- }
- XFree(atomListPtr);
- RETURN (atoms);
+ Display *dpy = myDpy;
+ int numProps = 0;
+
+ if (__isExternalAddress(windowID)) {
+ window = __WindowVal(windowID);
+ } else if (windowID == nil) {
+ window = DefaultRootWindow(dpy);
+ } else if (__isInteger(windowID)) {
+ window = (Window)__unsignedLongIntVal(windowID);
+ } else {
+ goto fail;
+ }
+
+ ENTER_XLIB();
+ atomListPtr = XListProperties(dpy, window, &numProps);
+ LEAVE_XLIB();
+
+ if (atomListPtr == NULL) {
+ RETURN (nil);
+ }
+
+ atoms = __ARRAY_NEW_INT(numProps);
+
+ if (atoms == nil) {
+ goto fail;
+ }
+
+ for (i=0; i<numProps; i++) {
+ OBJ atm;
+
+ atm = __MKATOMOBJ(atomListPtr[i]);
+ __ArrayInstPtr(atoms)->a_element[i] = atm; __STORE(atoms, atm);
+ }
+ XFree(atomListPtr);
+ RETURN (atoms);
}
fail: ;
%}.
@@ -9572,15 +9514,16 @@
"
Display propertiesOf:nil
+ Display propertiesOf:Transcript view id
"
"
(Display propertiesOf:nil) do:[:atm |
- |v|
-
- Transcript show:(atm printStringLeftPaddedTo:5).
- Transcript show:' '.
- Display getProperty:atm from:nil delete:false into:[:type :val | v := type->val].
- Transcript showCR:v.
+ |v|
+
+ Transcript show:((Display atomName:atm) printStringLeftPaddedTo:5).
+ Transcript show:': '.
+ Display getProperty:atm from:nil delete:false into:[:type :val | v := (Display atomName:type)->val].
+ Transcript showCR:v.
]
"
!
@@ -9596,61 +9539,59 @@
%{ /* UNLIMITEDSTACK */
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));
-#ifdef __integerArrayVal
- } else if (__isIntegerArray(anObject)) {
- /* array of atoms */
- XChangeProperty(dpy, window, prop, type, 32,
- PropModeReplace,
- (char *)__integerArrayVal(anObject),
- __integerArraySize(anObject));
-#endif
- } 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));
+ 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 (__isInteger(anObject)) {
+ unsigned INT value = __longIntVal(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,
+ (char *)__integerArrayVal(anObject),
+ __integerArraySize(anObject));
+ } else if (__isStringLike(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
@@ -10026,18 +9967,11 @@
^ false
! !
-!XWorkstation methodsFor:'selections'!
-
-addSelectionHandler:aHandler
- SelectionHandlers isNil ifTrue:[
- SelectionHandlers := IdentitySet new.
- ].
- SelectionHandlers add:aHandler
-!
+!XWorkstation methodsFor:'selection fetching'!
getSelectionFor:drawableId
- "get the object selection - either immediate, or asynchronous.
- Returns nil, if async request is on its way.
+ "get the object selection.
+ Returns nil, if no selection is available.
Smalltalk puts ST_OBJECT only into the CLIPBOARD"
@@ -10045,69 +9979,58 @@
selectionOwnerWindowId := self getSelectionOwnerOf:clipboardAtom.
selectionOwnerWindowId isNil ifTrue:[
- ^ nil "no selection"
+ ^ nil "no selection"
].
selectionOwnerWindowId == selectionOwner ifTrue:[
- "I still hold the selection, so return my locally buffered data"
- ^ copyBuffer
- ].
-
- self
- requestSelection:clipboardAtom
- property:(self atomIDOf:#'ST_SELECTION')
- type:(self atomIDOf:#'ST_OBJECT')
- for:drawableId.
- ^ nil
-
- "Modified: / 17.6.1998 / 17:11:15 / cg"
+ "I still hold the selection, so return my locally buffered data"
+ ^ copyBuffer
+ ].
+
+ ^ SelectionFetcher
+ requestSelection:clipboardAtom
+ type:(self atomIDOf:#'ST_OBJECT')
+ onDevice:self for:drawableId.
+
+
+ "
+ Display getSelectionFor:Transcript id
+ "
!
getTextSelection:selectionBufferSymbol for:drawableId
- "get the text selection - either immediate, or asynchronous.
- Returns nil, if async request is on its way
- or if no selection is available"
+ "get the text selection.
+ Returns nil, if no selection is available"
|selectionId selectionOwnerWindowId|
selectionBufferSymbol == #selection ifTrue:[
- selectionId := primaryAtom.
+ selectionId := primaryAtom.
] ifFalse:[
- selectionId := clipboardAtom.
+ selectionId := clipboardAtom.
].
selectionOwnerWindowId := self getSelectionOwnerOf:selectionId.
selectionOwnerWindowId isNil ifTrue:[
- ^ nil "no selection"
+ ^ nil "no selection"
].
selectionOwnerWindowId == selectionOwner ifTrue:[
- "I still hold the selection, so return my locally buffered data"
- ^ self selectionAsString.
- ].
-
- self
- requestSelection:selectionId
- property:(self atomIDOf:#'VT_SELECTION')
- type:(self atomIDOf:#'UTF8_STRING')
- for:drawableId.
-
-"/ self
-"/ requestSelection:selectionId
-"/ property:(self atomIDOf:#'VT_SELECTION')
-"/ type:stringAtom
-"/ for:drawableId.
-
- ^ nil.
-!
-
-removeSelectionHandler:aHandler
- SelectionHandlers notNil ifTrue:[
- SelectionHandlers remove:aHandler ifAbsent:nil.
- SelectionHandlers isEmpty ifTrue:[
- SelectionHandlers := nil
- ]
- ].
-!
+ "I still hold the selection, so return my locally buffered data"
+ ^ self selectionAsString.
+ ].
+
+ ^ SelectionFetcher
+ requestSelection:selectionId
+ type:(self atomIDOf:#'UTF8_STRING')
+ onDevice:self for:drawableId.
+
+ "
+ Display getTextSelection:#clipboard for:Transcript id
+ Display getTextSelection:#selection for:Transcript id
+ "
+! !
+
+!XWorkstation methodsFor:'selection sending'!
selectionAs:aTargetAtom
"convert the current selection to the format defined by aTargetAtom.
@@ -10116,66 +10039,51 @@
|stream|
(aTargetAtom == (self atomIDOf:#STRING)) ifTrue:[
- "the other view wants the selection as string"
- ^ self selectionAsString.
+ "the other view wants the selection as string"
+ ^ self selectionAsString.
+ ].
+
+ (aTargetAtom == (self atomIDOf:#UTF8_STRING)) ifTrue:[
+ "the other view wants the selection as utf8 string"
+ ^ self selectionAsString utf8Encoded.
+ ].
+
+ (aTargetAtom == (self atomIDOf:#TIMESTAMP)) ifTrue:[
+ "the other view wants to know when we acquired ownership of the selection"
+ ^ selectionTime.
].
(aTargetAtom == (self atomIDOf:#TARGETS)) ifTrue:[
- "the other view wants to know which targets we support"
- ^ self supportedTargetAtoms.
+ "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.
+ "send the selection in binaryStore format"
+ stream := WriteStream on:(ByteArray new:200).
+ self getCopyBuffer storeBinaryOn:stream.
+ ^ stream contents.
].
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
+ "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
].
"we do not support the requestet target"
^ nil.
!
-sendSelection:something selection:selectionID property:propertyID target:targetID time:t from:windowID to:requestorID
- "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.
We set only the CLIPBOARD selection"
- ^ self setSelectionOwner:aWindowId of:clipboardAtom
+ selectionTime := lastEventTime.
+ ^ self setSelectionOwner:aWindowId of:clipboardAtom time:selectionTime
!
setTextSelection:aString owner:aWindowId
@@ -10185,10 +10093,12 @@
We set both 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.
+ selectionTime := lastEventTime.
+
+ (self setSelectionOwner:aWindowId of:clipboardAtom time:selectionTime) ifFalse:[
+ 'XWorkstation [warning]: selection ownerchange failed' errorPrintCR.
+ ].
+ self setSelectionOwner:aWindowId of:primaryAtom time:selectionTime.
^ true
"Modified: / 17.6.1998 / 19:48:54 / cg"
@@ -10200,11 +10110,11 @@
|supportedTargets numericTargetArray|
- supportedTargets := #(ST_OBJECT STRING TARGETS LENGTH).
+ supportedTargets := #(ST_OBJECT STRING UTF8_STRING TARGETS TIMESTAMP LENGTH).
numericTargetArray := IntegerArray new:supportedTargets size.
supportedTargets keysAndValuesDo:[:index :targetSymbol|
- numericTargetArray at:index put:(self atomIDOf:targetSymbol)
+ numericTargetArray at:index put:(self atomIDOf:targetSymbol)
].
^ numericTargetArray
@@ -10248,31 +10158,45 @@
<context:#return>
-%{
- Atom sel_prop;
- char *cp;
-
- if ((__isExternalAddress(aWindowId) || (aWindowId == nil))
- && ISCONNECTED
+ |anIntegerTimestamp|
+
+ anIntegerTimestamp := lastEventTime.
+
+%{
+
+ if (ISCONNECTED
&& __isAtomID(typeID)
&& __isAtomID(propertyID)
&& __isAtomID(selectionID)) {
- Display *dpy = myDpy;
- Window w;
- Window selectionOwner;
-
- if (__isExternalAddress(aWindowId)) {
- w = __WindowVal(aWindowId);
- } else {
- w = (Window)0;
- }
-
- ENTER_XLIB();
- XConvertSelection(dpy, __AtomVal(selectionID), __AtomVal(typeID),
- __AtomVal(propertyID), w, CurrentTime);
- LEAVE_XLIB();
-
- RETURN (true);
+ Display *dpy = myDpy;
+ Window w;
+ Time time;
+
+ if (__isExternalAddress(aWindowId)) {
+ w = __WindowVal(aWindowId);
+ } else if (aWindowId == nil) {
+ w = (Window)0;
+ } else
+ goto err;
+
+ if (anIntegerTimestamp == nil) {
+ /*
+ * the ICCCM convention says: you should set the time to the time when
+ * the selection was requested and not to CurrentTime
+ */
+ time = CurrentTime;
+ } else if (__isInteger(anIntegerTimestamp)) {
+ time = __unsignedLongIntVal(anIntegerTimestamp);
+ } else
+ goto err;
+
+ ENTER_XLIB();
+ XConvertSelection(dpy, __AtomVal(selectionID), __AtomVal(typeID),
+ __AtomVal(propertyID), w, time);
+ LEAVE_XLIB();
+
+ RETURN (true);
+err:;
}
%}.
self primitiveFailedOrClosedConnection.
@@ -10280,101 +10204,92 @@
"
Display
- requestSelection:(Display atomIDOf:'PRIMARY')
- property:(Display atomIDOf:'VT_SELECTION')
- type:(Display atomIDOf:'STRING')
- for:Transcript id
+ requestSelection:(Display atomIDOf:'PRIMARY')
+ property:(Display atomIDOf:'VT_SELECTION')
+ type:(Display atomIDOf:'STRING')
+ for:Transcript id
"
"
Display
- requestSelection:(Display atomIDOf:'PRIMARY')
- property:(Display atomIDOf:'VT_SELECTION')
- type:(Display atomIDOf:'C_STRING')
- for:Transcript id
- "
-!
-
-sendSelectionNotifySelection:selectionID property:propertyID target:targetID time:t from:windowID to:requestorID
+ requestSelection:(Display atomIDOf:'PRIMARY')
+ property:(Display atomIDOf:'VT_SELECTION')
+ type:(Display atomIDOf:'C_STRING')
+ for:Transcript id
+ "
+!
+
+sendSelectionNotifySelection:selectionID property:propertyID target:targetID time:t to:requestorID
"send a selectionNotify back from a SelectionRequest"
<context: #return>
%{
if (ISCONNECTED
- && (__isAtomID(propertyID) || propertyID == nil)
- && __isAtomID(targetID) && __isAtomID(selectionID)) {
- Display *dpy = myDpy;
- XEvent ev;
- Window requestor, originator;
- 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 = __AtomVal(selectionID);
- ev.xselection.target = __AtomVal(targetID);
- 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);
- }
+ && (__isAtomID(propertyID) || propertyID == nil)
+ && __isAtomID(targetID) && __isAtomID(selectionID)) {
+ Display *dpy = myDpy;
+ XEvent ev;
+ Window requestor;
+ 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);
+ }
+
+ ev.xselection.type = SelectionNotify;
+ ev.xselection.display = dpy;
+ ev.xselection.selection = __AtomVal(selectionID);
+ ev.xselection.target = __AtomVal(targetID);
+ ev.xselection.requestor = requestor;
+
+ 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
-
- /* 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,
- 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)
+ 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
+
+ /* 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,
+ 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 primitiveFailedOrClosedConnection.
@@ -10383,7 +10298,7 @@
"Modified: / 17.6.1998 / 20:23:20 / cg"
!
-setSelectionOwner:aWindowId of:selectionAtomSymbolOrID
+setSelectionOwner:aWindowId of:selectionAtomSymbolOrID time:anIntegerTimestamp
"set the owner of a selection; return false if failed"
<context: #return>
@@ -10397,9 +10312,9 @@
selectionOwner := aWindowId.
selectionAtomSymbolOrID isString ifTrue:[
- selectionAtomID := self atomIDOf:selectionAtomSymbolOrID create:false.
+ selectionAtomID := self atomIDOf:selectionAtomSymbolOrID create:false.
] ifFalse:[
- selectionAtomID := selectionAtomSymbolOrID.
+ selectionAtomID := selectionAtomSymbolOrID.
].
%{
@@ -10408,20 +10323,34 @@
if (__isExternalAddress(aWindowId)
&& __isAtomID(selectionAtomID)
&& ISCONNECTED) {
- Display *dpy = myDpy;
- Window owner;
-
- win = __WindowVal(aWindowId);
- DPRINTF(("setOwner prop=%x win=%x\n", __AtomVal(selectionAtomID), win));
- ENTER_XLIB();
- XSetSelectionOwner(dpy, __AtomVal(selectionAtomID), win, CurrentTime);
- owner = XGetSelectionOwner(dpy, __AtomVal(selectionAtomID));
- LEAVE_XLIB();
- if (owner != win) {
- RETURN (false);
- }
- RETURN (true);
- }
+ Display *dpy = myDpy;
+ Window owner;
+ Time time;
+
+ win = __WindowVal(aWindowId);
+
+ if (anIntegerTimestamp == nil) {
+ /*
+ * the ICCCM convention says: you should set the time to the time when
+ * the selection was acquired and not to CurrentTime
+ */
+ time = CurrentTime;
+ } else if (__isInteger(anIntegerTimestamp)) {
+ time = __unsignedLongIntVal(anIntegerTimestamp);
+ } else
+ goto err;
+
+ DPRINTF(("setOwner prop=%x win=%x\n", __AtomVal(selectionAtomID), win));
+ ENTER_XLIB();
+ XSetSelectionOwner(dpy, __AtomVal(selectionAtomID), win, time);
+ owner = XGetSelectionOwner(dpy, __AtomVal(selectionAtomID));
+ LEAVE_XLIB();
+ if (owner != win) {
+ RETURN (false);
+ }
+ RETURN (true);
+ }
+err:;
%}.
self primitiveFailedOrClosedConnection.
^ false
@@ -11566,10 +11495,201 @@
^ false "/ or true or what ?
! !
+!XWorkstation::SelectionFetcher class methodsFor:'documentation'!
+
+documentation
+"
+ This class is responsible for fetching the clipboard.
+ The X11 clipboard is implemented via asynchonous messages.
+
+ For each fetch operation an instance of this class is created.
+ The asynchronous messages are queued and executed in the
+ process that requests the clipboard.
+
+ [author:]
+ Stefan Vogel (stefan@zwerg)
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!XWorkstation::SelectionFetcher class methodsFor:'selections'!
+
+requestSelection:selectionId type:aTargetId onDevice:aDisplay for:aDrawableId
+ ^ self new requestSelection:selectionId type:aTargetId onDevice:aDisplay for:aDrawableId
+! !
+
+!XWorkstation::SelectionFetcher methodsFor:'accessing'!
+
+getSelection
+ "convert the data in buffer to a selection"
+
+ |selection|
+
+ buffer isNil ifTrue:[
+ ^ nil.
+ ].
+
+ targetID == (display atomIDOf:#STRING) ifTrue:[
+ display clipBoardEncoding notNil ifTrue:[
+ selection := buffer decodeFrom:display clipBoardEncoding
+ ].
+ selection := buffer.
+ ] ifFalse:[targetID == (display atomIDOf:#'UTF8_STRING') ifTrue:[
+"/ Transcript show:'UTF8: '; showCR:buffer storeString.
+ selection := CharacterArray fromUTF8Bytes:buffer
+ ] ifFalse:[targetID == (display atomIDOf:#TEXT) ifTrue:[
+"/ Transcript show:'TEXT: '; showCR:buffer storeString.
+ selection := buffer asString
+ ] ifFalse:[targetID == (display atomIDOf:#'COMPOUND_TEXT') ifTrue:[
+"/ Transcript show:'COMPOUND_TEXT: '; showCR:buffer storeString.
+ selection := buffer asString
+ ]]]].
+
+ selection notNil ifTrue:[
+ (selection endsWith:Character cr) ifTrue:[
+ selection := selection asStringCollection copyWith:''
+ ].
+ ^ selection.
+ ].
+
+ targetID == (display atomIDOf:#'ST_OBJECT') ifTrue:[
+ ^ (Object readBinaryFrom:(ReadStream on:buffer) onError:[nil])
+ ].
+
+ 'XWorkstation: unimplemented property targetID: ' infoPrint. targetID infoPrint.
+ ' ' infoPrint. (display atomName:targetID) infoPrint.
+ ' buffer:' infoPrint. buffer infoPrintCR.
+ ^ ''
+! !
+
+!XWorkstation::SelectionFetcher methodsFor:'event handling'!
+
+message:aMessage
+ "got an asynchronous event from the display.
+ Save and wake up waiters"
+
+ message notNil ifTrue:[
+ 'XWorkstation: message overflow' errorPrintCR.
+ ^ self.
+ ].
+
+ (incremental not and:[aMessage selector == #propertyChange:property:state:time:]) ifTrue:[
+ "ignore propertyChange messages if not in incremental transmission mode"
+ ^ self.
+ ].
+
+ message := aMessage.
+ sema signal.
+!
+
+propertyChange:aView property:aPropertyId state:stateSymbol time:time
+ "this is a forwarded propretyChange event from XWorkstation"
+
+ |property clipBoardContents|
+
+ stateSymbol ~~ #newValue ifTrue:[
+ "I am not interested in delete notifications"
+ ^ self.
+ ].
+
+ property := display getProperty:propertyID from:drawableID delete:true.
+ clipBoardContents := property value.
+ targetID ~= property key ifTrue:[
+ 'XWorkstation: targetID change in incremental select' errorPrintCR.
+ ].
+
+ "property with size 0 signals end of transfer"
+ clipBoardContents size == 0 ifTrue:[
+ done := true.
+ ] ifFalse:[
+ buffer isNil ifTrue:[
+ buffer := clipBoardContents.
+ ] ifFalse:[
+ buffer := buffer, clipBoardContents.
+ ].
+ ].
+!
+
+selectionNotify:aView selection:selectionID target:targetID property:aPropertyID requestor:requestorID time:time
+ "this is a forwarded selectionNotify event from XWorkstation"
+
+ |property propertyKey|
+
+ propertyID == 0 ifTrue:[
+ "could not convert"
+ done := true.
+ ^ self.
+ ].
+
+ property := display getProperty:propertyID from:drawableID delete:true.
+ propertyKey := property key.
+ propertyKey == (display atomIDOf:#INCR) ifTrue:[
+ "this is an incremental transfer.
+ Wait for property change"
+ incremental := true.
+ ] ifFalse:[
+ propertyID := propertyKey.
+ buffer := property value.
+ done := true.
+ ].
+! !
+
+!XWorkstation::SelectionFetcher methodsFor:'selection actions'!
+
+requestSelection:selectionId type:aTargetId onDevice:aDisplay for:aDrawableId
+ "request the selection of type targetId.
+ Wait for next asynchronous message and process it,
+ until done"
+
+ display := aDisplay.
+ drawableID := aDrawableId.
+ propertyID := display atomIDOf:#'VT_SELECTION'.
+ targetID := aTargetId.
+ sema := Semaphore new name:'X11SelectionFetcher'.
+ done := false.
+ incremental := false.
+
+ [
+
+ display registerSelectionFetcher:self.
+
+ display
+ requestSelection:selectionId
+ property:propertyID
+ type:aTargetId
+ for:drawableID.
+
+ [
+ |currentMessage|
+
+ sema wait.
+ currentMessage := message.
+ message := nil.
+ currentMessage sendTo:self.
+ ] doUntil:[done].
+ ] ensure:[
+ display unregisterSelectionFetcher:self.
+ ].
+
+ ^ self getSelection
+! !
+
+!XWorkstation::SelectionFetcher methodsFor:'testing'!
+
+matchesDrawableId:aDrawableId
+ ^ drawableID = aDrawableId
+! !
+
!XWorkstation class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.460 2004-09-14 12:30:34 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.461 2004-09-14 23:06:05 stefan Exp $'
! !
XWorkstation initialize!