--- 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!