]> git.neil.brown.name Git - freerunner.git/blob - tap2/fakeinput.py
Nearly the end of the random stuff...
[freerunner.git] / tap2 / fakeinput.py
1 #!/usr/bin/env python
2
3 # fakeinput.py
4 # based on pykey, see also "crikey" and http://shallowsky.com/blog/tags/crikey/
5
6 import Xlib.display
7 import Xlib.X
8 import Xlib.XK
9 import Xlib.protocol.event
10
11 UseXTest = True
12
13 try :
14     import Xlib.ext.xtest
15 except ImportError:
16     UseXTest = False
17     print "no XTest extension; using XSendEvent"
18
19 import sys, time
20
21 special_X_keysyms = {
22     '\b': "BackSpace",
23     ' ' : "space",
24     '\t' : "Tab",
25     '\n' : "Return",  # for some reason this needs to be cr, not lf
26     '\r' : "Return",
27     '\e' : "Escape",
28     '!' : "exclam",
29     '#' : "numbersign",
30     '%' : "percent",
31     '$' : "dollar",
32     '&' : "ampersand",
33     '"' : "quotedbl",
34     '\'' : "apostrophe",
35     '(' : "parenleft",
36     ')' : "parenright",
37     '*' : "asterisk",
38     '=' : "equal",
39     '+' : "plus",
40     ',' : "comma",
41     '-' : "minus",
42     '.' : "period",
43     '/' : "slash",
44     ':' : "colon",
45     ';' : "semicolon",
46     '<' : "less",
47     '>' : "greater",
48     '?' : "question",
49     '@' : "at",
50     '[' : "bracketleft",
51     ']' : "bracketright",
52     '\\' : "backslash",
53     '^' : "asciicircum",
54     '_' : "underscore",
55     '`' : "grave",
56     '{' : "braceleft",
57     '|' : "bar",
58     '}' : "braceright",
59     '~' : "asciitilde"
60     }
61
62 def get_keysym(ch) :
63     keysym = Xlib.XK.string_to_keysym(ch)
64     if keysym == 0 :
65         # Unfortunately, although this works to get the correct keysym
66         # i.e. keysym for '#' is returned as "numbersign"
67         # the subsequent display.keysym_to_keycode("numbersign") is 0.
68         keysym = Xlib.XK.string_to_keysym(special_X_keysyms[ch])
69     return keysym
70
71 def is_shifted(ch) :
72     if ch.isupper() :
73         return True
74     if "~!@#$%^&*()_+{}|:\"<>?".find(ch) >= 0 :
75         return True
76     return False
77
78 class fakeinput:
79     def __init__(self, display = None):
80         global UseXTest
81         if display:
82             self.display = display
83         else:
84             self.display = Xlib.display.Display()
85
86         self.UseXTest = UseXTest
87         
88         if UseXTest and not self.display.query_extension("XTEST") :
89             self.UseXTest = False
90
91         self.new_window()
92
93     def new_window(self):
94         if not self.UseXTest:
95             self.window = self.display.get_input_focus()._data["focus"];
96
97     def char_to_keycode(self, ch):
98         keysym = get_keysym(ch)
99         keycode = self.display.keysym_to_keycode(keysym)
100         if keycode == 0 :
101             print "fakeinput: Sorry, can't map", ch
102
103         if (is_shifted(ch)) :
104             shift_mask = Xlib.X.ShiftMask
105         else :
106             shift_mask = 0
107
108         return keycode, shift_mask
109
110     def send_char(self, ch, dosync = True) :
111         keycode, shift_mask = self.char_to_keycode(ch)
112         if (self.UseXTest) :
113             if shift_mask != 0 :
114                 Xlib.ext.xtest.fake_input(self.display, Xlib.X.KeyPress, 50)
115             Xlib.ext.xtest.fake_input(self.display, Xlib.X.KeyPress, keycode)
116             Xlib.ext.xtest.fake_input(self.display, Xlib.X.KeyRelease, keycode)
117             if shift_mask != 0 :
118                 Xlib.ext.xtest.fake_input(self.display, Xlib.X.KeyRelease, 50)
119         else :
120             event = Xlib.protocol.event.KeyPress(
121                 time = int(time.time()),
122                 root = self.display.screen().root,
123                 window = self.window,
124                 same_screen = 0, child = Xlib.X.NONE,
125                 root_x = 0, root_y = 0, event_x = 0, event_y = 0,
126                 state = shift_mask,
127                 detail = keycode
128                 )
129             self.window.send_event(event, propagate = True)
130             event = Xlib.protocol.event.KeyRelease(
131                 time = int(time.time()),
132                 root = self.display.screen().root,
133                 window = self.window,
134                 same_screen = 0, child = Xlib.X.NONE,
135                 root_x = 0, root_y = 0, event_x = 0, event_y = 0,
136                 state = shift_mask,
137                 detail = keycode
138                 )
139             self.window.send_event(event, propagate = True)
140         if dosync:
141             self.display.sync()
142
143     def send_str(self, str):
144         for ch in str:
145             self.send_char(ch, dosync = False)
146         self.display.sync()
147