_keyboard_event.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. # -*- coding: utf-8 -*-
  2. from time import time as now
  3. try:
  4. basestring
  5. except NameError:
  6. basestring = str
  7. KEY_DOWN = 'down'
  8. KEY_UP = 'up'
  9. class KeyboardEvent(object):
  10. event_type = None
  11. scan_code = None
  12. name = None
  13. time = None
  14. def __init__(self, event_type, scan_code, name=None, time=None, device=None, is_keypad=None):
  15. self.event_type = event_type
  16. self.scan_code = scan_code
  17. self.time = now() if time is None else time
  18. self.device = device
  19. self.is_keypad = is_keypad
  20. if name:
  21. self.name = normalize_name(name)
  22. def __repr__(self):
  23. return 'KeyboardEvent({} {})'.format(self.name or 'Unknown {}'.format(self.scan_code), self.event_type)
  24. # TODO: add values from https://svn.apache.org/repos/asf/xmlgraphics/commons/tags/commons-1_0/src/java/org/apache/xmlgraphics/fonts/Glyphs.java
  25. canonical_names = {
  26. 'escape': 'esc',
  27. 'return': 'enter',
  28. 'del': 'delete',
  29. 'control': 'ctrl',
  30. 'altgr': 'alt gr',
  31. 'left arrow': 'left',
  32. 'up arrow': 'up',
  33. 'down arrow': 'down',
  34. 'right arrow': 'right',
  35. ' ': 'space', # Prefer to spell out keys that would be hard to read.
  36. '\x1b': 'esc',
  37. '\x08': 'backspace',
  38. '\n': 'enter',
  39. '\t': 'tab',
  40. '\r': 'enter',
  41. 'scrlk': 'scroll lock',
  42. 'prtscn': 'print screen',
  43. 'prnt scrn': 'print screen',
  44. 'snapshot': 'print screen',
  45. 'ins': 'insert',
  46. 'pause break': 'pause',
  47. 'ctrll lock': 'caps lock',
  48. 'capslock': 'caps lock',
  49. 'number lock': 'num lock',
  50. 'numlock:': 'num lock',
  51. 'space bar': 'space',
  52. 'spacebar': 'space',
  53. 'linefeed': 'enter',
  54. 'win': 'windows',
  55. # Mac keys
  56. 'command': 'windows',
  57. 'control': 'ctrl',
  58. 'option': 'alt',
  59. 'app': 'menu',
  60. 'apps': 'menu',
  61. 'application': 'menu',
  62. 'applications': 'menu',
  63. 'pagedown': 'page down',
  64. 'pageup': 'page up',
  65. 'pgdown': 'page down',
  66. 'pgup': 'page up',
  67. 'next': 'page down', # This looks wrong, but this is how Linux reports.
  68. 'prior': 'page up',
  69. 'underscore': '_',
  70. 'equal': '=',
  71. 'minplus': '+',
  72. 'plus': '+',
  73. 'add': '+',
  74. 'subtract': '-',
  75. 'minus': '-',
  76. 'multiply': '*',
  77. 'asterisk': '*',
  78. 'divide': '/',
  79. 'question': '?',
  80. 'exclam': '!',
  81. 'slash': '/',
  82. 'bar': '|',
  83. 'backslash': '\\',
  84. 'braceleft': '{',
  85. 'braceright': '}',
  86. 'bracketleft': '[',
  87. 'bracketright': ']',
  88. 'parenleft': '(',
  89. 'parenright': ')',
  90. 'period': '.',
  91. 'dot': '.',
  92. 'comma': ',',
  93. 'semicolon': ';',
  94. 'colon': ':',
  95. 'less': '<',
  96. 'greater': '>',
  97. 'ampersand': '&',
  98. 'at': '@',
  99. 'numbersign': '#',
  100. 'hash': '#',
  101. 'hashtag': '#',
  102. 'dollar': '$',
  103. 'sterling': '£',
  104. 'pound': '£',
  105. 'yen': '¥',
  106. 'euro': '€',
  107. 'cent': '¢',
  108. 'currency': '¤',
  109. 'registered': '®',
  110. 'copyright': '©',
  111. 'notsign': '¬',
  112. 'percent': '%',
  113. 'diaeresis': '"',
  114. 'quotedbl': '"',
  115. 'onesuperior': '¹',
  116. 'twosuperior': '²',
  117. 'threesuperior': '³',
  118. 'onehalf': '½',
  119. 'onequarter': '¼',
  120. 'threequarters': '¾',
  121. 'paragraph': '¶',
  122. 'section': '§',
  123. 'ssharp': '§',
  124. 'division': '÷',
  125. 'questiondown': '¿',
  126. 'exclamdown': '¡',
  127. 'degree': '°',
  128. 'guillemotright': '»',
  129. 'guillemotleft': '«',
  130. 'acute': '´',
  131. 'agudo': '´',
  132. 'grave': '`',
  133. 'tilde': '~',
  134. 'asciitilde': '~',
  135. 'til': '~',
  136. 'cedilla': ',',
  137. 'circumflex': '^',
  138. 'apostrophe': '\'',
  139. 'adiaeresis': 'ä',
  140. 'udiaeresis': 'ü',
  141. 'odiaeresis': 'ö',
  142. 'oe': 'Œ',
  143. 'oslash': 'ø',
  144. 'ooblique': 'Ø',
  145. 'ccedilla': 'ç',
  146. 'ntilde': 'ñ',
  147. 'eacute': 'é',
  148. 'uacute': 'ú',
  149. 'oacute': 'ó',
  150. 'thorn': 'þ',
  151. 'ae': 'æ',
  152. 'eth': 'ð',
  153. 'masculine': 'º',
  154. 'feminine': 'ª',
  155. 'iacute': 'í',
  156. 'aacute': 'á',
  157. 'mu': 'Μ',
  158. 'aring': 'å',
  159. 'zero': '0',
  160. 'one': '1',
  161. 'two': '2',
  162. 'three': '3',
  163. 'four': '4',
  164. 'five': '5',
  165. 'six': '6',
  166. 'seven': '7',
  167. 'eight': '8',
  168. 'nine': '9',
  169. 'play/pause': 'play/pause media',
  170. 'num multiply': '*',
  171. 'num divide': '/',
  172. 'num add': '+',
  173. 'num plus': '+',
  174. 'num minus': '-',
  175. 'num sub': '-',
  176. 'num enter': 'enter',
  177. 'num 0': '0',
  178. 'num 1': '1',
  179. 'num 2': '2',
  180. 'num 3': '3',
  181. 'num 4': '4',
  182. 'num 5': '5',
  183. 'num 6': '6',
  184. 'num 7': '7',
  185. 'num 8': '8',
  186. 'num 9': '9',
  187. 'left win': 'left windows',
  188. 'right win': 'right windows',
  189. 'left control': 'left ctrl',
  190. 'right control': 'right ctrl',
  191. 'left menu': 'left alt', # Windows...
  192. }
  193. def normalize_name(name):
  194. if not name:
  195. return 'unknown'
  196. if not isinstance(name, basestring):
  197. raise ValueError('Can only normalize string names. Unexpected '+ repr(name))
  198. name = name.lower()
  199. if name != '_':
  200. name = name.replace('_', ' ')
  201. return canonical_names.get(name, name)