X11SimulateKeyInputImpl.mesa
Copyright Ó 1993 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, April 27, 1993
Christian Jacobi, April 27, 1993 5:35 pm PDT
DIRECTORY
Rope, KeyChars, KeyMapping, KeySyms1, KeySymsKB, KeyTypes, Xl, X11SimulateKeyInput;
X11SimulateKeyInputImpl: CEDAR PROGRAM
IMPORTS KeyChars, KeyMapping, Rope, Xl
EXPORTS X11SimulateKeyInput ~
BEGIN
Send: PUBLIC PROC [c: Xl.Connection, text: Rope.ROPE, time: Xl.TimeStamp ¬ Xl.currentTime] = {
--Tries to send the text to the window with the input focus using simulated key events
--If this collides with real keyboard event this might confuse applications as the keyboard state might make impossible transitions.
--If this collides with real keyboard event this might confuse applications as the keyboard state might make impossible transitions.
connection: Xl.Connection ~ c;
inputFocusWindow: Xl.Window = [[1]];
eDown: Xl.EventRep.keyPress;
eUp: Xl.EventRep.keyRelease;
dest: Xl.Window ¬ inputFocusWindow;
currentFocus: Xl.Window;
screen: Xl.Screen;
Down: PROC [keyCode: KeyTypes.KeyCode] = {
eDown.keyCode ¬ keyCode;
Xl.SendEvent[connection, dest, TRUE, [keyPress: TRUE], eDown];
IF keyCode=shiftKeyCode THEN eDown.state.shift ¬ eUp.state.shift ¬ TRUE;
IF keyCode=ctrlKeyCode THEN eDown.state.control ¬ eUp.state.control ¬ TRUE;
};
Up: PROC [keyCode: KeyTypes.KeyCode] = {
eUp.keyCode ¬ keyCode;
Xl.SendEvent[connection, dest, TRUE, [keyRelease: TRUE], eUp];
IF keyCode=shiftKeyCode THEN eDown.state.shift ¬ eUp.state.shift ¬ FALSE;
IF keyCode=ctrlKeyCode THEN eDown.state.control ¬ eUp.state.control ¬ FALSE;
};
Action: PROC [c: CHAR] RETURNS [quit: BOOL ¬ FALSE] = {
keySym: Xl.KeySym ¬ KeyChars.KeySymFromChar[c];
IF keySym#0 THEN {
keyCode: KeyTypes.KeyCode;
shift: BOOL ¬ FALSE;
ctrl: BOOL ¬ FALSE;
keyCodes ¬ KeyMapping.KeyCodesFromKeySym[map, keySym];
IF keyCodes.n=0 THEN {
IF keySym IN [KeySyms1.a.val..KeySyms1.z.val] THEN {
capSym: Xl.KeySym ¬ [keySym.val - KeySyms1.a.val + KeySyms1.A.val];
keyCodes ¬ KeyMapping.KeyCodesFromKeySym[map, capSym];
};
};
IF keyCodes.n>0 THEN {
keyCode ¬ keyCodes[0].keyCode;
shift ¬ keyCodes[0].glyphIndex=1 OR (keySym.val IN [KeySyms1.A.val..KeySyms1.Z.val]);
};
IF shift THEN Down[shiftKeyCode];
IF ctrl THEN Down[ctrlKeyCode];
Down[keyCode];
Up[keyCode];
IF ctrl THEN Up[ctrlKeyCode];
IF shift THEN Up[shiftKeyCode];
};
};
map: Xl.KeyboardMapping;
keyCodes: KeyMapping.KeyCodes;
shiftKeyCode: KeyTypes.KeyCode ¬ keycode0;
ctrlKeyCode: KeyTypes.KeyCode ¬ keycode0;
Xl.GrabServer[connection];
map ¬ Xl.GetKeyboardMapping[connection];
currentFocus ¬ Xl.GetInputFocus[connection].window;
IF currentFocus=Xl.nullWindow OR currentFocus=Xl.focusPointerRoot
THEN screen ¬ Xl.DefaultScreen[connection]
ELSE screen ¬ Xl.QueryScreen[connection, currentFocus];
--Compute shift and ctrl keycodes
keyCodes ¬ KeyMapping.KeyCodesFromKeySym[map, KeySymsKB.LeftShift];
IF keyCodes.n<=0 THEN
keyCodes ¬ KeyMapping.KeyCodesFromKeySym[map, KeySymsKB.RightShift];
IF keyCodes.n>0 THEN shiftKeyCode ¬ keyCodes[0].keyCode;
keyCodes ¬ KeyMapping.KeyCodesFromKeySym[map, KeySymsKB.LeftControl];
IF keyCodes.n<=0 THEN
keyCodes ¬ KeyMapping.KeyCodesFromKeySym[map, KeySymsKB.RightControl];
IF keyCodes.n>0 THEN ctrlKeyCode ¬ keyCodes[0].keyCode;
--set constant values
eDown.timeStamp ¬ eUp.timeStamp ¬ time;
eDown.root ¬ eUp.root ¬ screen.root;
eDown.eventWindow ¬ eUp.eventWindow ¬ currentFocus;
eDown.child ¬ eUp.child ¬ Xl.nullWindow;
eDown.rootP ¬ eUp.rootP ¬ [0, 0];
eDown.pos ¬ eUp.pos ¬ [0, 0];
eDown.sameScreen ¬ eUp.sameScreen ¬ TRUE;
eDown.state ¬ eUp.state ¬ [];
[] ¬ Rope.Map[base: text, action: Action];
Xl.UngrabServer[connection];
};
END.