changeset 65:a44e3ae52139

fix: input mapping
author Sam <sam@basx.dev>
date Sun, 05 Feb 2023 00:15:31 +0700
parents e766d138cc5d
children 44bae6c72834
files src/semicongine/events.nim src/semicongine/platform/linux/symkey_map.nim src/semicongine/platform/linux/xlib.nim src/semicongine/platform/windows/virtualkey_map.nim
diffstat 4 files changed, 62 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/events.nim	Sat Feb 04 02:24:41 2023 +0700
+++ b/src/semicongine/events.nim	Sun Feb 05 00:15:31 2023 +0700
@@ -7,14 +7,17 @@
   Key* {.size: sizeof(cint), pure.} = enum
     UNKNOWN
     Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12
-    NumberRowExtra1, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `0`, NumberRowExtra2, NumberRowExtra3 # tilde, minus, plus
+    NumberRowExtra1, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `0`,
+        NumberRowExtra2, NumberRowExtra3                 # tilde, minus, plus
     A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
-    Tab, CapsLock, ShiftL, ShiftR, CtrlL, CtrlR, SuperL, SuperR, AltL, AltR, Space, Enter, Backspace
-    LetterRow1Extra1, LetterRow1Extra2, LetterRow1Extra3 # open bracket, close brackt, backslash
-    LetterRow2Extra1, LetterRow2Extra2 # semicolon, quote
+    Tab, CapsLock, ShiftL, ShiftR, CtrlL, CtrlR, SuperL, SuperR, AltL, AltR,
+        Space, Enter, Backspace
+    LetterRow1Extra1, LetterRow1Extra2 # open bracket, close brackt, backslash
+    LetterRow2Extra1, LetterRow2Extra2, LetterRow2Extra3 # semicolon, quote
     LetterRow3Extra1, LetterRow3Extra2, LetterRow3Extra3 # comma, period, slash
     Up, Down, Left, Right
     PageUp, PageDown, Home, End, Insert, Delete
+    PrintScreen, ScrollLock, Pause
   MouseButton* {.size: sizeof(cint), pure.} = enum
     UNKNOWN, Mouse1, Mouse2, Mouse3
   Event* = object
--- a/src/semicongine/platform/linux/symkey_map.nim	Sat Feb 04 02:24:41 2023 +0700
+++ b/src/semicongine/platform/linux/symkey_map.nim	Sun Feb 05 00:15:31 2023 +0700
@@ -8,16 +8,24 @@
 
 # got values (keycodes) from xev
 const KeyTypeMap* = {
-  9: Escape, 67: F1, 68: F2, 69: F3, 70: F4, 71: F5, 72: F6, 73: F7, 74: F8, 75: F9, 76: F10, 95: F11, 96: F12,
-  49: NumberRowExtra1, 10: `1`, 11: `2`, 12: `3`, 13: `4`, 14: `5`, 15: `6`, 16: `7`, 17: `8`, 18: `9`, 19: `0`, 20: NumberRowExtra2, 21: NumberRowExtra3,
-  24: Q, 25: W, 26: E, 27: R, 28: T, 29: Y, 30: U, 31: I, 32: O, 33: P, 38: A, 39: S, 40: D, 41: Key.F, 42: G, 43: H, 44: J, 45: K, 46: L, 52: Z, 53: X, 54: C, 55: V, 56: B, 57: N, 58: M,
+  9: Escape, 67: F1, 68: F2, 69: F3, 70: F4, 71: F5, 72: F6, 73: F7, 74: F8,
+  75: F9, 76: F10, 95: F11, 96: F12,
+  49: NumberRowExtra1, 10: `1`, 11: `2`, 12: `3`, 13: `4`, 14: `5`, 15: `6`,
+  16: `7`, 17: `8`, 18: `9`, 19: `0`, 20: NumberRowExtra2, 21: NumberRowExtra3,
+  24: Q, 25: W, 26: E, 27: R, 28: T, 29: Y, 30: U, 31: I, 32: O, 33: P, 38: A,
+  39: S, 40: D, 41: Key.F, 42: G, 43: H, 44: J, 45: K, 46: L, 52: Z, 53: X,
+  54: C, 55: V, 56: B, 57: N, 58: M,
 
-  23: Tab, 66: CapsLock, 50: ShiftL, 62: ShiftR, 37: CtrlL, 105: CtrlR, 133: SuperL, #[ SuperR, ]# 64: AltL, #[ AltR, ]# 65: Space, 36: Enter, 22: Backspace,
-    34: LetterRow1Extra1, 35: LetterRow1Extra2, 51: LetterRow1Extra3,
-    47: LetterRow2Extra1, 48: LetterRow2Extra2,
-    59: LetterRow3Extra1, 60: LetterRow3Extra2, 61: LetterRow3Extra3,
-    111: Up, 116: Down, 113: Left, 114: Right,
-    112: PageUp, 117: PageDown, 110: Home, 115: End, 118: Insert, 119: Delete,
+  23: Tab, 66: CapsLock, 50: ShiftL, 62: ShiftR, 37: CtrlL, 105: CtrlR,
+  133: SuperL, 134: SuperR,
+  64: AltL, 108: AltR,
+  65: Space, 36: Enter, 22: Backspace,
+  34: LetterRow1Extra1, 35: LetterRow1Extra2,
+  47: LetterRow2Extra1, 48: LetterRow2Extra2, 51: LetterRow2Extra3,
+  59: LetterRow3Extra1, 60: LetterRow3Extra2, 61: LetterRow3Extra3,
+  111: Up, 116: Down, 113: Left, 114: Right,
+  112: PageUp, 117: PageDown, 110: Home, 115: End, 118: Insert, 119: Delete,
+  107: PrintScreen, 78: ScrollLock, 127: Pause,
 }.toTable
 
 const MouseButtonTypeMap* = {
--- a/src/semicongine/platform/linux/xlib.nim	Sat Feb 04 02:24:41 2023 +0700
+++ b/src/semicongine/platform/linux/xlib.nim	Sun Feb 05 00:15:31 2023 +0700
@@ -77,7 +77,7 @@
 proc pendingEvents*(window: NativeWindow): seq[Event] =
   var
     event: XEvent
-    serials: Table[culong, seq[Event]]
+    serials: Table[culong, Table[int, seq[Event]]]
   while window.display.XPending() > 0:
     discard window.display.XNextEvent(addr(event))
     case event.theType
@@ -87,16 +87,22 @@
     of KeyPress:
       let keyevent = cast[PXKeyEvent](addr(event))
       let xkey = int(keyevent.keycode)
+      # ugly, but required to catch auto-repeat keys of X11
       if not (keyevent.serial in serials):
-        serials[keyevent.serial] = newSeq[Event]()
-      serials[keyevent.serial].add(Event(eventType: KeyPressed,
+        serials[keyevent.serial] = initTable[int, seq[Event]]()
+      if not (xkey in serials[keyevent.serial]):
+        serials[keyevent.serial][xkey] = newSeq[Event]()
+      serials[keyevent.serial][xkey].add(Event(eventType: KeyPressed,
           key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN)))
     of KeyRelease:
       let keyevent = cast[PXKeyEvent](addr(event))
       let xkey = int(keyevent.keycode)
+      # ugly, but required to catch auto-repeat keys of X11
       if not (keyevent.serial in serials):
-        serials[keyevent.serial] = newSeq[Event]()
-      serials[keyevent.serial].add Event(eventType: KeyReleased,
+        serials[keyevent.serial] = initTable[int, seq[Event]]()
+      if not (xkey in serials[keyevent.serial]):
+        serials[keyevent.serial][xkey] = newSeq[Event]()
+      serials[keyevent.serial][xkey].add Event(eventType: KeyReleased,
           key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN))
     of ButtonPress:
       let button = int(cast[PXButtonEvent](addr(event)).button)
@@ -113,9 +119,11 @@
       result.add Event(eventType: ResizedWindow)
     else:
       discard
-  for (serial, events) in serials.pairs:
-    if events.len == 1:
-      result.add events[0]
+  # little hack to work around X11 auto-repeat keys
+  for (serial, keys) in serials.pairs:
+    for (key, events) in keys.pairs:
+      if events.len == 1:
+        result.add events[0]
 
 
 proc getMousePosition*(window: NativeWindow): Option[Vec2] =
--- a/src/semicongine/platform/windows/virtualkey_map.nim	Sat Feb 04 02:24:41 2023 +0700
+++ b/src/semicongine/platform/windows/virtualkey_map.nim	Sun Feb 05 00:15:31 2023 +0700
@@ -6,13 +6,28 @@
 import ../../events
 
 const KeyTypeMap* = {
-  VK_ESCAPE: Key.Escape, VK_F1: F1, VK_F2: F2, VK_F3: F3, VK_F4: F4, VK_F5: F5, VK_F6: F6, VK_F7: F7, VK_F8: F8, VK_F9: F9, VK_F10: F10, VK_F11: F11, VK_F12: F12,
-  VK_OEM_3: NumberRowExtra1, int('0'): `0`, int('1'): `1`, int('2'): `2`, int('3'): `3`, int('4'): `4`, int('5'): `5`, int('6'): `6`, int('7'): `7`, int('8'): `8`, int('9'): `9`, VK_OEM_MINUS: NumberRowExtra2, VK_OEM_PLUS: NumberRowExtra3,
-  int('A'): A, int('B'): B, int('C'): C, int('D'): D, int('E'): E, int('F'): F, int('G'): G, int('H'): H, int('I'): I, int('J'): J, int('K'): K, int('L'): L, int('M'): M, int('N'): N, int('O'): O, int('P'): P, int('Q'): Q, int('R'): R, int('S'): S, int('T'): T, int('U'): U, int('V'): V, int('W'): W, int('X'): X, int('Y'): Y, int('Z'): Z,
-  VK_TAB: Tab, VK_CAPITAL: CapsLock, VK_LSHIFT: ShiftL, VK_SHIFT: ShiftL, VK_RSHIFT: ShiftR, VK_LCONTROL: CtrlL, VK_CONTROL: CtrlL, VK_RCONTROL: CtrlR, VK_LWIN: SuperL, VK_RWIN: SuperR, VK_LMENU: AltL, VK_RMENU: AltR, VK_SPACE: Space, VK_RETURN: Enter, VK_BACK: Backspace,
-  VK_OEM_4: LetterRow1Extra1, VK_OEM_6: LetterRow1Extra2, VK_OEM_5: LetterRow1Extra3,
+  VK_ESCAPE: Key.Escape, VK_F1: F1, VK_F2: F2, VK_F3: F3, VK_F4: F4, VK_F5: F5,
+  VK_F6: F6, VK_F7: F7, VK_F8: F8, VK_F9: F9, VK_F10: F10, VK_F11: F11,
+  VK_F12: F12,
+  VK_OEM_3: NumberRowExtra1, int('0'): `0`, int('1'): `1`, int('2'): `2`, int(
+      '3'): `3`, int('4'): `4`, int('5'): `5`, int('6'): `6`, int('7'): `7`,
+      int('8'): `8`, int('9'): `9`, VK_OEM_MINUS: NumberRowExtra2,
+      VK_OEM_PLUS: NumberRowExtra3,
+  int('A'): A, int('B'): B, int('C'): C, int('D'): D, int('E'): E, int('F'): F,
+      int('G'): G, int('H'): H, int('I'): I, int('J'): J, int('K'): K, int(
+      'L'): L, int('M'): M, int('N'): N, int('O'): O, int('P'): P, int('Q'): Q,
+      int('R'): R, int('S'): S, int('T'): T, int('U'): U, int('V'): V, int(
+      'W'): W, int('X'): X, int('Y'): Y, int('Z'): Z,
+  VK_TAB: Tab, VK_CAPITAL: CapsLock, VK_LSHIFT: ShiftL, VK_SHIFT: ShiftL,
+      VK_RSHIFT: ShiftR, VK_LCONTROL: CtrlL, VK_CONTROL: CtrlL,
+      VK_RCONTROL: CtrlR, VK_LWIN: SuperL, VK_RWIN: SuperR, VK_LMENU: AltL,
+      VK_RMENU: AltR, VK_SPACE: Space, VK_RETURN: Enter, VK_BACK: Backspace,
+  VK_OEM_4: LetterRow1Extra1, VK_OEM_6: LetterRow1Extra2,
+      VK_OEM_5: LetterRow2Extra3,
   VK_OEM_1: LetterRow2Extra1, VK_OEM_7: LetterRow2Extra2,
-  VK_OEM_COMMA: LetterRow3Extra1, VK_OEM_PERIOD: LetterRow3Extra2, VK_OEM_2: LetterRow3Extra3,
+  VK_OEM_COMMA: LetterRow3Extra1, VK_OEM_PERIOD: LetterRow3Extra2,
+      VK_OEM_2: LetterRow3Extra3,
     VK_UP: Up, VK_DOWN: Down, VK_LEFT: Left, VK_RIGHT: Right,
-    VK_PRIOR: PageUp, VK_NEXT: PageDown, VK_HOME: Home, VK_END: End, VK_INSERT: Insert, VK_DELETE: Key.Delete,
+    VK_PRIOR: PageUp, VK_NEXT: PageDown, VK_HOME: Home, VK_END: End,
+        VK_INSERT: Insert, VK_DELETE: Key.Delete,
 }.toTable