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