Package dogtail :: Module rawinput
[hide private]
[frames] | no frames]

Source Code for Module dogtail.rawinput

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3  Handles raw input using AT-SPI event generation. 
  4   
  5  Note: Think of keyvals as keysyms, and keynames as keystrings. 
  6   
  7  Authors: David Malcolm <dmalcolm@redhat.com>, Zack Cerza <zcerza@redhat.com> 
  8  """ 
  9   
 10  __author__ = """ 
 11  David Malcolm <dmalcolm@redhat.com>, 
 12  Zack Cerza <zcerza@redhat.com> 
 13  """ 
 14  import gi 
 15   
 16  gi.require_version('Gtk', '3.0') 
 17  gi.require_version('Gdk', '3.0') 
 18   
 19  from gi.repository import Gdk 
 20  from config import config 
 21  from utils import doDelay 
 22  from logging import debugLogger as logger 
 23  from pyatspi import Registry as registry 
 24  from pyatspi import (KEY_SYM, KEY_PRESS, KEY_PRESSRELEASE, KEY_RELEASE) 
 25  from exceptions import ValueError 
 26  from __builtin__ import unicode, unichr 
 27   
 28   
29 -def doTypingDelay():
30 doDelay(config.typingDelay)
31 32
33 -def checkCoordinates(x, y):
34 if x < 0 or y < 0: 35 raise ValueError( 36 "Attempting to generate a mouse event at negative coordinates: (%s,%s)" % (x, y))
37 38
39 -def click(x, y, button=1, check=True):
40 """ 41 Synthesize a mouse button click at (x,y) 42 """ 43 if check: 44 checkCoordinates(x, y) 45 logger.log("Mouse button %s click at (%s,%s)" % (button, x, y)) 46 registry.generateMouseEvent(x, y, 'b%sc' % button) 47 doDelay(config.actionDelay)
48 49
50 -def doubleClick(x, y, button=1, check=True):
51 """ 52 Synthesize a mouse button double-click at (x,y) 53 """ 54 if check: 55 checkCoordinates(x, y) 56 logger.log("Mouse button %s doubleclick at (%s,%s)" % (button, x, y)) 57 registry.generateMouseEvent(x, y, 'b%sd' % button) 58 doDelay()
59 60
61 -def press(x, y, button=1, check=True):
62 """ 63 Synthesize a mouse button press at (x,y) 64 """ 65 if check: 66 checkCoordinates(x, y) 67 logger.log("Mouse button %s press at (%s,%s)" % (button, x, y)) 68 registry.generateMouseEvent(x, y, 'b%sp' % button) 69 doDelay()
70 71
72 -def release(x, y, button=1, check=True):
73 """ 74 Synthesize a mouse button release at (x,y) 75 """ 76 if check: 77 checkCoordinates(x, y) 78 logger.log("Mouse button %s release at (%s,%s)" % (button, x, y)) 79 registry.generateMouseEvent(x, y, 'b%sr' % button) 80 doDelay()
81 82
83 -def absoluteMotion(x, y, mouseDelay=None, check=True):
84 """ 85 Synthesize mouse absolute motion to (x,y) 86 """ 87 if check: 88 checkCoordinates(x, y) 89 logger.log("Mouse absolute motion to (%s,%s)" % (x, y)) 90 registry.generateMouseEvent(x, y, 'abs') 91 if mouseDelay: 92 doDelay(mouseDelay) 93 else: 94 doDelay()
95 96
97 -def relativeMotion(x, y, mouseDelay=None):
98 logger.log("Mouse relative motion of (%s,%s)" % (x, y)) 99 registry.generateMouseEvent(x, y, 'rel') 100 if mouseDelay: 101 doDelay(mouseDelay) 102 else: 103 doDelay()
104 105
106 -def drag(fromXY, toXY, button=1, check=True):
107 """ 108 Synthesize a mouse press, drag, and release on the screen. 109 """ 110 logger.log("Mouse button %s drag from %s to %s" % (button, fromXY, toXY)) 111 112 (x, y) = fromXY 113 press(x, y, button, check) 114 # doDelay() 115 116 (x, y) = toXY 117 absoluteMotion(x, y, check=check) 118 doDelay() 119 120 release(x, y, button, check) 121 doDelay()
122 123
124 -def typeText(string):
125 """ 126 Types the specified string, one character at a time. 127 Please note, you may have to set a higher typing delay, 128 if your machine misses/switches the characters typed. 129 Needed sometimes on slow setups/VMs typing non-ASCII utf8 chars. 130 """ 131 if not isinstance(string, unicode): 132 string = string.decode('utf-8') 133 for char in string: 134 pressKey(char)
135 136 keyNameAliases = { 137 'enter': 'Return', 138 'esc': 'Escape', 139 'alt': 'Alt_L', 140 'control': 'Control_L', 141 'ctrl': 'Control_L', 142 'shift': 'Shift_L', 143 'del': 'Delete', 144 'ins': 'Insert', 145 'pageup': 'Page_Up', 146 'pagedown': 'Page_Down', 147 ' ': 'space', 148 '\t': 'Tab', 149 '\n': 'Return' 150 } 151 152 153 # TODO: Dead code
154 -def keySymToUniChar(keySym): # pragma: no cover
155 i = Gdk.keyval_to_unicode(keySym) 156 if i: 157 UniChar = unichr(i) 158 else: 159 UniChar = '' 160 return UniChar 161 162
163 -def uniCharToKeySym(uniChar):
164 # OK, if it's not actually unicode we can fix that, right? 165 if not isinstance(uniChar, unicode): 166 uniChar = unicode(uniChar, 'utf-8') 167 i = ord(uniChar) 168 keySym = Gdk.unicode_to_keyval(i) 169 return keySym
170 171 172 # dead code
173 -def keySymToKeyName(keySym): # pragma: no cover
174 return Gdk.keyval_name(keySym) 175 176
177 -def keyNameToKeySym(keyName):
178 keyName = keyNameAliases.get(keyName.lower(), keyName) 179 keySym = Gdk.keyval_from_name(keyName) 180 # various error 'codes' returned for non-recognized chars in versions of GTK3.X 181 if keySym == 0xffffff or keySym == 0x0 or keySym is None: 182 try: 183 keySym = uniCharToKeySym(keyName) 184 except: # not even valid utf-8 char 185 try: # Last attempt run at a keyName ('Meta_L', 'Dash' ...) 186 keySym = getattr(Gdk, 'KEY_' + keyName) 187 except AttributeError: 188 raise KeyError(keyName) 189 return keySym
190 191
192 -def keyNameToKeyCode(keyName):
193 """ 194 Use GDK to get the keycode for a given keystring. 195 196 Note that the keycode returned by this function is often incorrect when 197 the requested keystring is obtained by holding down the Shift key. 198 199 Generally you should use uniCharToKeySym() and should only need this 200 function for nonprintable keys anyway. 201 """ 202 keymap = Gdk.Keymap.get_for_display(Gdk.Display.get_default()) 203 entries = keymap.get_entries_for_keyval( 204 Gdk.keyval_from_name(keyName)) 205 try: 206 return entries[1][0].keycode 207 except TypeError: 208 pass
209 210
211 -def pressKey(keyName):
212 """ 213 Presses (and releases) the key specified by keyName. 214 keyName is the English name of the key as seen on the keyboard. Ex: 'enter' 215 Names are looked up in Gdk.KEY_ If they are not found there, they are 216 looked up by uniCharToKeySym(). 217 """ 218 keySym = keyNameToKeySym(keyName) 219 registry.generateKeyboardEvent(keySym, None, KEY_SYM) 220 doTypingDelay()
221 222
223 -def keyCombo(comboString):
224 """ 225 Generates the appropriate keyboard events to simulate a user pressing the 226 specified key combination. 227 228 comboString is the representation of the key combo to be generated. 229 e.g. '<Control><Alt>p' or '<Control><Shift>PageUp' or '<Control>q' 230 """ 231 strings = [] 232 for s in comboString.split('<'): 233 if s: 234 for S in s.split('>'): 235 if S: 236 S = keyNameAliases.get(S.lower(), S) 237 strings.append(S) 238 for s in strings: 239 if not hasattr(Gdk, s): 240 if not hasattr(Gdk, 'KEY_' + s): 241 raise ValueError("Cannot find key %s" % s) 242 modifiers = strings[:-1] 243 finalKey = strings[-1] 244 for modifier in modifiers: 245 code = keyNameToKeyCode(modifier) 246 registry.generateKeyboardEvent(code, None, KEY_PRESS) 247 code = keyNameToKeyCode(finalKey) 248 registry.generateKeyboardEvent(code, None, KEY_PRESSRELEASE) 249 for modifier in modifiers: 250 code = keyNameToKeyCode(modifier) 251 registry.generateKeyboardEvent(code, None, KEY_RELEASE) 252 doDelay()
253