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