ironpython_keysyms.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. # -*- coding: utf-8 -*-
  2. # *****************************************************************************
  3. # Copyright (C) 2003-2006 Gary Bishop.
  4. # Copyright (C) 2006-2020 Jorgen Stenarson. <jorgen.stenarson@bostream.nu>
  5. # Copyright (C) 2020 Bassem Girgis. <brgirgis@gmail.com>
  6. #
  7. # Distributed under the terms of the BSD License. The full license is in
  8. # the file COPYING, distributed as part of this software.
  9. # *****************************************************************************
  10. import System
  11. from .common import KeyPress, make_KeyPress_from_keydescr, validkey
  12. c32 = System.ConsoleKey
  13. Shift = System.ConsoleModifiers.Shift
  14. Control = System.ConsoleModifiers.Control
  15. Alt = System.ConsoleModifiers.Alt
  16. # table for translating virtual keys to X windows key symbols
  17. code2sym_map = {
  18. # c32.CANCEL: 'Cancel',
  19. c32.Backspace: "BackSpace",
  20. c32.Tab: "Tab",
  21. c32.Clear: "Clear",
  22. c32.Enter: "Return",
  23. # c32.Shift: 'Shift_L',
  24. # c32.Control: 'Control_L',
  25. # c32.Menu: 'Alt_L',
  26. c32.Pause: "Pause",
  27. # c32.Capital: 'Caps_Lock',
  28. c32.Escape: "Escape",
  29. # c32.Space: 'space',
  30. c32.PageUp: "Prior",
  31. c32.PageDown: "Next",
  32. c32.End: "End",
  33. c32.Home: "Home",
  34. c32.LeftArrow: "Left",
  35. c32.UpArrow: "Up",
  36. c32.RightArrow: "Right",
  37. c32.DownArrow: "Down",
  38. c32.Select: "Select",
  39. c32.Print: "Print",
  40. c32.Execute: "Execute",
  41. # c32.Snapshot: 'Snapshot',
  42. c32.Insert: "Insert",
  43. c32.Delete: "Delete",
  44. c32.Help: "Help",
  45. c32.F1: "F1",
  46. c32.F2: "F2",
  47. c32.F3: "F3",
  48. c32.F4: "F4",
  49. c32.F5: "F5",
  50. c32.F6: "F6",
  51. c32.F7: "F7",
  52. c32.F8: "F8",
  53. c32.F9: "F9",
  54. c32.F10: "F10",
  55. c32.F11: "F11",
  56. c32.F12: "F12",
  57. c32.F13: "F13",
  58. c32.F14: "F14",
  59. c32.F15: "F15",
  60. c32.F16: "F16",
  61. c32.F17: "F17",
  62. c32.F18: "F18",
  63. c32.F19: "F19",
  64. c32.F20: "F20",
  65. c32.F21: "F21",
  66. c32.F22: "F22",
  67. c32.F23: "F23",
  68. c32.F24: "F24",
  69. # c32.Numlock: 'Num_Lock,',
  70. # c32.Scroll: 'Scroll_Lock',
  71. # c32.Apps: 'VK_APPS',
  72. # c32.ProcesskeY: 'VK_PROCESSKEY',
  73. # c32.Attn: 'VK_ATTN',
  74. # c32.Crsel: 'VK_CRSEL',
  75. # c32.Exsel: 'VK_EXSEL',
  76. # c32.Ereof: 'VK_EREOF',
  77. # c32.Play: 'VK_PLAY',
  78. # c32.Zoom: 'VK_ZOOM',
  79. # c32.Noname: 'VK_NONAME',
  80. # c32.Pa1: 'VK_PA1',
  81. c32.OemClear: "VK_OEM_CLEAR",
  82. c32.NumPad0: "NUMPAD0",
  83. c32.NumPad1: "NUMPAD1",
  84. c32.NumPad2: "NUMPAD2",
  85. c32.NumPad3: "NUMPAD3",
  86. c32.NumPad4: "NUMPAD4",
  87. c32.NumPad5: "NUMPAD5",
  88. c32.NumPad6: "NUMPAD6",
  89. c32.NumPad7: "NUMPAD7",
  90. c32.NumPad8: "NUMPAD8",
  91. c32.NumPad9: "NUMPAD9",
  92. c32.Divide: "Divide",
  93. c32.Multiply: "Multiply",
  94. c32.Add: "Add",
  95. c32.Subtract: "Subtract",
  96. c32.Decimal: "VK_DECIMAL",
  97. }
  98. # function to handle the mapping
  99. def make_keysym(keycode):
  100. try:
  101. sym = code2sym_map[keycode]
  102. except KeyError:
  103. sym = ""
  104. return sym
  105. sym2code_map = {}
  106. for code, sym in code2sym_map.items():
  107. sym2code_map[sym.lower()] = code
  108. def key_text_to_keyinfo(keytext):
  109. """Convert a GNU readline style textual description of a key to keycode with modifiers"""
  110. if keytext.startswith('"'): # "
  111. return keyseq_to_keyinfo(keytext[1:-1])
  112. else:
  113. return keyname_to_keyinfo(keytext)
  114. def char_to_keyinfo(char, control=False, meta=False, shift=False):
  115. vk = ord(char)
  116. if vk & 0xFFFF == 0xFFFF:
  117. print('VkKeyScan("%s") = %x' % (char, vk))
  118. raise ValueError("bad key")
  119. if vk & 0x100:
  120. shift = True
  121. if vk & 0x200:
  122. control = True
  123. if vk & 0x400:
  124. meta = True
  125. return (control, meta, shift, vk & 0xFF)
  126. def keyname_to_keyinfo(keyname):
  127. control = False
  128. meta = False
  129. shift = False
  130. while True:
  131. lkeyname = keyname.lower()
  132. if lkeyname.startswith("control-"):
  133. control = True
  134. keyname = keyname[8:]
  135. elif lkeyname.startswith("ctrl-"):
  136. control = True
  137. keyname = keyname[5:]
  138. elif lkeyname.startswith("meta-"):
  139. meta = True
  140. keyname = keyname[5:]
  141. elif lkeyname.startswith("alt-"):
  142. meta = True
  143. keyname = keyname[4:]
  144. elif lkeyname.startswith("shift-"):
  145. shift = True
  146. keyname = keyname[6:]
  147. else:
  148. if len(keyname) > 1:
  149. return (control, meta, shift, sym2code_map.get(keyname.lower(), " "))
  150. else:
  151. return char_to_keyinfo(keyname, control, meta, shift)
  152. def keyseq_to_keyinfo(keyseq):
  153. res = []
  154. control = False
  155. meta = False
  156. shift = False
  157. while True:
  158. if keyseq.startswith("\\C-"):
  159. control = True
  160. keyseq = keyseq[3:]
  161. elif keyseq.startswith("\\M-"):
  162. meta = True
  163. keyseq = keyseq[3:]
  164. elif keyseq.startswith("\\e"):
  165. res.append(char_to_keyinfo("\033", control, meta, shift))
  166. control = meta = shift = False
  167. keyseq = keyseq[2:]
  168. elif len(keyseq) >= 1:
  169. res.append(char_to_keyinfo(keyseq[0], control, meta, shift))
  170. control = meta = shift = False
  171. keyseq = keyseq[1:]
  172. else:
  173. return res[0]
  174. def make_keyinfo(keycode, state):
  175. control = False
  176. meta = False
  177. shift = False
  178. return (control, meta, shift, keycode)
  179. def make_KeyPress(char, state, keycode):
  180. shift = bool(int(state) & int(Shift))
  181. control = bool(int(state) & int(Control))
  182. meta = bool(int(state) & int(Alt))
  183. keyname = code2sym_map.get(keycode, "").lower()
  184. if control and meta: # equivalent to altgr so clear flags
  185. control = False
  186. meta = False
  187. elif control:
  188. char = str(keycode)
  189. return KeyPress(char, shift, control, meta, keyname)