diff -r fff17080daf9 -r 92200ee9f558 XWorkstation.st --- a/XWorkstation.st Fri Jan 26 13:09:47 1996 +0100 +++ b/XWorkstation.st Fri Jan 26 13:49:01 1996 +0100 @@ -454,6 +454,12 @@ ^ nil ! +controlMask +%{ /* NOCONTEXT */ + RETURN (__MKSMALLINT(ControlMask)); +%} +! + defaultEventMask "return a mask to enable some events by default." @@ -533,6 +539,12 @@ " ! +shiftMask +%{ /* NOCONTEXT */ + RETURN (__MKSMALLINT(ShiftMask)); +%} +! + translatePoint:aPoint from:windowId1 to:windowId2 "given a point in window1, return the coordinate in window2. This expects a device coordinate (relative to the first views origin) @@ -2420,7 +2432,7 @@ } fail: ; if (mustFree) - free(points); + free(points); %}. "badGC, badDrawable or coordinates not integer" self primitiveFailed @@ -2728,8 +2740,8 @@ RETURN ( self ); fail: ; - if (mustFree) - free(points); + if (mustFree) + free(points); } %}. "badGC, badDrawable or coordinates not integer" @@ -2869,6 +2881,178 @@ ^ false ! ! +!XWorkstation methodsFor:'event sending'! + +simulateKeyboardInput:aCharacterOrString inViewId:viewId + "send input to some other view, by simulating keyPress/keyRelease + events. Notice: not all alien views allow this kind of synthetic input; + some simply ignore it." + + |shifted control code state| + + aCharacterOrString isString ifTrue:[ + aCharacterOrString do:[:char | + self simulateKeyboardInput:char inViewId:viewId + ]. + ^ self + ]. + + shifted := false. + control := false. + code := aCharacterOrString asciiValue. + + (aCharacterOrString between:$A and:$Z) ifTrue:[ + "/ shifted + shifted := true + ] ifFalse:[ + (aCharacterOrString between:$a and:$z) ifTrue:[ + "/ unshifted alpha + code := code - $a asciiValue + $A asciiValue + ] + ]. + + shifted ifTrue:[ + state := self shiftMask + ] ifFalse:[ + state := 0 + ]. + control ifTrue:[ + state := state bitOr:(self controlMask) + ]. + + self sendKeyEvent:#keyPress x:0 y:0 key:code state:state toViewId:viewId. + self sendKeyEvent:#keyRelease x:0 y:0 key:code state:state toViewId:viewId + + " + sending input to some (possibly alien) view: + + |point id| + + point := Display pointFromUser. + id := Display viewIdFromPoint:point. + Display simulateKeyboardInput:'hello' inViewId:id + " +! + +sendKeyEvent:typeSymbol x:xPos y:yPos key:keySymCode state:stateMask toViewId:targetId + "send a keyPress/keyRelease event to some (possibly alien) view. + TypeSymbol must be one of: #keyPress / #keyRelease. + keySymCode can be either a symbol (as listen in X's keySyms or a numeric keysym) + This is the lowlevel entry, where state must include any shift/ctrl information + (not very user friendly)" + +%{ /* NOCONTEXT */ + Display *dpy = myDpy; + int type; + + if (ISCONNECTED + && __isSmallInteger(xPos) && __isSmallInteger(yPos) + && __isSmallInteger(keySymCode) && __isSmallInteger(stateMask) + && (__isExternalAddress(targetId) || __isInteger(targetId))) { + XEvent ev; + Window target; + Status result; + KeySym keySym; + int screen = _intVal(_INST(screen)); + + ev.xkey.x = __intVal(xPos); + ev.xkey.y = __intVal(yPos); + if (__isSymbol(keySymCode)) { + keySym = XStringToKeysym(__stringVal(keySymCode)); + } else { + keySym = (KeySym) __intVal(keySymCode); + } + ev.xkey.keycode = XKeysymToKeycode(dpy, keySym); + ev.xkey.state = __intVal(stateMask); + ev.xkey.time = CurrentTime; + + if (typeSymbol == @symbol(keyPress)) + ev.xkey.type = KeyPress; + else if (typeSymbol == @symbol(keyRelease)) + ev.xkey.type = KeyRelease; + else { + DPRINTF(("invalid sendEvent typeSymbol\n")); + RETURN (false); + } + + if (__isExternalAddress(targetId)) { + target = _WindowVal(targetId); + } else { + target = (Window) __longIntVal(targetId); + } + ev.xkey.window = target; + ev.xkey.same_screen = 1; + ev.xkey.subwindow = 0; + ev.xkey.root = RootWindow(myDpy, screen); + + result = XSendEvent(dpy, target, False, 0 , &ev); + if ((result == BadValue) || (result == BadWindow)) { + DPRINTF(("bad status\n")); + RETURN ( false ) + } + RETURN (true) + } +%}. + self primitiveFailed. + ^ false +! + +sendButtonEvent:typeSymbol x:xPos y:yPos button:buttonNr state:stateMask toViewId:targetId + "send a buttonPress/buttonRelease event to some (possibly alien) view. + TypeSymbol must be one of: #buttonPress / #buttonRelease. + This is the lowlevel entry, where state must include any shift/ctrl information + (not very user friendly)" + +%{ /* NOCONTEXT */ + Display *dpy = myDpy; + int type; + + if (ISCONNECTED + && __isSmallInteger(xPos) && __isSmallInteger(yPos) + && __isSmallInteger(buttonNr) && __isSmallInteger(stateMask) + && (__isExternalAddress(targetId) || __isInteger(targetId))) { + XEvent ev; + Window target; + Status result; + int screen = _intVal(_INST(screen)); + + ev.xbutton.x = __intVal(xPos); + ev.xbutton.y = __intVal(yPos); + ev.xbutton.button = __intVal(buttonNr); + ev.xbutton.state = __intVal(stateMask); + ev.xbutton.time = CurrentTime; + + if (typeSymbol == @symbol(buttonPress)) + ev.xbutton.type = ButtonPress; + else if (typeSymbol == @symbol(buttonRelease)) + ev.xbutton.type = ButtonRelease; + else { + DPRINTF(("invalid sendEvent typeSymbol\n")); + RETURN (false); + } + + if (__isExternalAddress(targetId)) { + target = _WindowVal(targetId); + } else { + target = (Window) __longIntVal(targetId); + } + ev.xbutton.window = target; + ev.xbutton.same_screen = 1; + ev.xbutton.subwindow = 0; + ev.xbutton.root = RootWindow(myDpy, screen); + + result = XSendEvent(dpy, target, False, 0 , &ev); + if ((result == BadValue) || (result == BadWindow)) { + DPRINTF(("bad status\n")); + RETURN ( false ) + } + RETURN (true) + } +%}. + self primitiveFailed. + ^ false +! ! + !XWorkstation methodsFor:'event handling'! dispatchEventFor:aViewIdOrNil withMask:eventMask @@ -6350,12 +6534,13 @@ result = XSendEvent(dpy, requestor, False, 0 , &ev); if ((result == BadValue) || (result == BadWindow)) { DPRINTF(("bad status\n")); + RETURN (false); } - RETURN (self ) - } -%} -. - self primitiveFailed + RETURN (true) + } +%}. + self primitiveFailed. + ^ false ! setLengthProperty:propertyID value:aNumber for:aWindowID @@ -7103,6 +7288,6 @@ !XWorkstation class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.101 1996-01-24 22:05:18 cg Exp $' + ^ '$Header: /cvs/stx/stx/libview/XWorkstation.st,v 1.102 1996-01-26 12:49:01 ah Exp $' ! ! XWorkstation initialize!