OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 import re | 7 import re |
8 import select | 8 import select |
9 import time | 9 import time |
10 | 10 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 '"': 'quotedbl', | 86 '"': 'quotedbl', |
87 '\'': 'apostrophe', | 87 '\'': 'apostrophe', |
88 ',': 'comma', | 88 ',': 'comma', |
89 '<': 'less', | 89 '<': 'less', |
90 '.': 'period', | 90 '.': 'period', |
91 '>': 'greater', | 91 '>': 'greater', |
92 '/': 'slash', | 92 '/': 'slash', |
93 '?': 'question', | 93 '?': 'question', |
94 } | 94 } |
95 | 95 |
| 96 # python-xlib doesn't know about these keysyms, so we hardcode the |
| 97 # constants from (the real) Xlib's /usr/include/X11/XF86keysym.h. |
| 98 __extra_keysyms = { |
| 99 'XF86AudioLowerVolume': 0x1008ff11, |
| 100 'XF86AudioMute': 0x1008ff12, |
| 101 'XF86AudioRaiseVolume': 0x1008ff13, |
| 102 } |
| 103 |
96 class Error(Exception): | 104 class Error(Exception): |
97 """Base exception class for AutoX.""" | 105 """Base exception class for AutoX.""" |
98 pass | 106 pass |
99 | 107 |
100 class RuntimeError(Error): | 108 class RuntimeError(Error): |
101 """Error caused by a (possibly temporary) condition at runtime.""" | 109 """Error caused by a (possibly temporary) condition at runtime.""" |
102 pass | 110 pass |
103 | 111 |
104 class InputError(Error): | 112 class InputError(Error): |
105 """Error caused by invalid input from the caller.""" | 113 """Error caused by invalid input from the caller.""" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 146 |
139 def __init__(self, display_name=None): | 147 def __init__(self, display_name=None): |
140 self.__display = Xlib.display.Display(display_name) | 148 self.__display = Xlib.display.Display(display_name) |
141 self.__root = self.__display.screen().root | 149 self.__root = self.__display.screen().root |
142 self.__windows = {} | 150 self.__windows = {} |
143 | 151 |
144 # Make sure that we get notified about property changes on the root | 152 # Make sure that we get notified about property changes on the root |
145 # window, since the caller may wait on conditions that use them. | 153 # window, since the caller may wait on conditions that use them. |
146 self.__root.change_attributes(event_mask=X.PropertyChangeMask) | 154 self.__root.change_attributes(event_mask=X.PropertyChangeMask) |
147 | 155 |
| 156 def __get_keysym_num_for_keysym(self, keysym_str): |
| 157 """Get the keysym number corresponding to a keysym's name. |
| 158 |
| 159 Args: |
| 160 keysym_str: keysym name as str |
| 161 |
| 162 Returns: |
| 163 integer keysym number, or XK.NoSymbol if invalid |
| 164 """ |
| 165 if keysym_str in AutoX.__extra_keysyms: |
| 166 return AutoX.__extra_keysyms[keysym_str] |
| 167 return XK.string_to_keysym(keysym_str) |
| 168 |
148 def __get_keycode_for_keysym(self, keysym): | 169 def __get_keycode_for_keysym(self, keysym): |
149 """Get the keycode corresponding to a keysym. | 170 """Get the keycode corresponding to a keysym. |
150 | 171 |
151 Args: | 172 Args: |
152 keysym: keysym name as str | 173 keysym: keysym name as str |
153 | 174 |
154 Returns: | 175 Returns: |
155 integer keycode | 176 integer keycode |
156 | 177 |
157 Raises: | 178 Raises: |
158 InvalidKeySymError: keysym name isn't an actual keycode | 179 InvalidKeySymError: keysym name isn't an actual keycode |
159 RuntimeError: unable to map the keysym to a keycode (maybe it | 180 RuntimeError: unable to map the keysym to a keycode (maybe it |
160 isn't present in the current keymap) | 181 isn't present in the current keymap) |
161 """ | 182 """ |
162 keysym_num = XK.string_to_keysym(keysym) | 183 keysym_num = self.__get_keysym_num_for_keysym(keysym) |
163 if keysym_num == XK.NoSymbol: | 184 if keysym_num == XK.NoSymbol: |
164 raise self.InvalidKeySymError(keysym) | 185 raise self.InvalidKeySymError(keysym) |
165 keycode = self.__display.keysym_to_keycode(keysym_num) | 186 keycode = self.__display.keysym_to_keycode(keysym_num) |
166 if not keycode: | 187 if not keycode: |
167 raise self.RuntimeError( | 188 raise self.RuntimeError( |
168 'Unable to map keysym "%s" to a keycode' % keysym) | 189 'Unable to map keysym "%s" to a keycode' % keysym) |
169 return keycode | 190 return keycode |
170 | 191 |
171 def __keysym_requires_shift(self, keysym): | 192 def __keysym_requires_shift(self, keysym): |
172 """Does a keysym require that a shift key be held down? | 193 """Does a keysym require that a shift key be held down? |
173 | 194 |
174 Args: | 195 Args: |
175 keysym: keysym name as str | 196 keysym: keysym name as str |
176 | 197 |
177 Returns: | 198 Returns: |
178 True or False | 199 True or False |
179 | 200 |
180 Raises: | 201 Raises: |
181 InvalidKeySymError: keysym name isn't an actual keycode | 202 InvalidKeySymError: keysym name isn't an actual keycode |
182 RuntimeError: unable to map the keysym to a keycode (maybe it | 203 RuntimeError: unable to map the keysym to a keycode (maybe it |
183 isn't present in the current keymap) | 204 isn't present in the current keymap) |
184 """ | 205 """ |
185 keysym_num = XK.string_to_keysym(keysym) | 206 keysym_num = self.__get_keysym_num_for_keysym(keysym) |
186 if keysym_num == XK.NoSymbol: | 207 if keysym_num == XK.NoSymbol: |
187 raise self.InvalidKeySymError(keysym) | 208 raise self.InvalidKeySymError(keysym) |
188 # This gives us a list of (keycode, index) tuples, sorted by index and | 209 # This gives us a list of (keycode, index) tuples, sorted by index and |
189 # then by keycode. Index 0 is without any modifiers, 1 is with Shift, | 210 # then by keycode. Index 0 is without any modifiers, 1 is with Shift, |
190 # 2 is with Mode_switch, and 3 is Mode_switch and Shift. | 211 # 2 is with Mode_switch, and 3 is Mode_switch and Shift. |
191 keycodes = self.__display.keysym_to_keycodes(keysym_num) | 212 keycodes = self.__display.keysym_to_keycodes(keysym_num) |
192 if not keycodes: | 213 if not keycodes: |
193 raise self.RuntimeError( | 214 raise self.RuntimeError( |
194 'Unable to map keysym "%s" to a keycode' % keysym) | 215 'Unable to map keysym "%s" to a keycode' % keysym) |
195 # We don't use Mode_switch for anything, at least currently, so just | 216 # We don't use Mode_switch for anything, at least currently, so just |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 return reply.value[0] | 617 return reply.value[0] |
597 | 618 |
598 def get_screen_size(self): | 619 def get_screen_size(self): |
599 """Get the current dimensions of the root window. | 620 """Get the current dimensions of the root window. |
600 | 621 |
601 Returns: | 622 Returns: |
602 tuple with two ints: (width, height) | 623 tuple with two ints: (width, height) |
603 """ | 624 """ |
604 reply = self.__root.get_geometry() | 625 reply = self.__root.get_geometry() |
605 return (reply.width, reply.height) | 626 return (reply.width, reply.height) |
OLD | NEW |