Mercurial > games > semicongine
changeset 1454:eaad5e0443f8 main
add: support for text-input, windows support still missing
author | sam <sam@basx.dev> |
---|---|
date | Fri, 21 Mar 2025 18:16:24 +0700 |
parents | 60a709362440 |
children | 4a06e29d1a27 |
files | semicongine/core/types.nim semicongine/input.nim semicongine/platform/linux/rendering.nim semicongine/platform/linux/types.nim semicongine/platform/windows/rendering.nim |
diffstat | 5 files changed, 44 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/semicongine/core/types.nim Sun Mar 16 22:33:35 2025 +0700 +++ b/semicongine/core/types.nim Fri Mar 21 18:16:24 2025 +0700 @@ -300,6 +300,7 @@ case eventType*: EventType of KeyPressed, KeyReleased: key*: Key + char*: Rune of MousePressed, MouseReleased: button*: MouseButton of MouseWheel: @@ -466,6 +467,7 @@ windowIsMinimized*: bool = false lockMouse*: bool = false hasFocus*: bool = false + characterInput*: Rune ActionMap* = object keyActions*: Table[string, set[Key]]
--- a/semicongine/input.nim Sun Mar 16 22:33:35 2025 +0700 +++ b/semicongine/input.nim Fri Mar 21 18:16:24 2025 +0700 @@ -1,4 +1,5 @@ import std/strutils +import std/unicode import std/tables import ./core @@ -14,6 +15,7 @@ engine().input.mouseWheel = 0 engine().input.mouseMove = vec2i(0, 0) engine().input.windowWasResized = false + engine().input.characterInput = default(Rune) let newMousePos = getMousePosition(engine().vulkan.window) engine().input.mouseMove = newMousePos - engine().input.mousePosition @@ -33,6 +35,9 @@ of KeyPressed: engine().input.keyWasPressed.incl event.key engine().input.keyIsDown.incl event.key + # exclude control characters for text input + if not (0x00'i32 <= int32(event.char) and int32(event.char) <= 0x1F'i32): + engine().input.characterInput = event.char of KeyReleased: engine().input.keyWasReleased.incl event.key engine().input.keyIsDown.excl event.key @@ -67,6 +72,9 @@ proc keyWasReleased*(key: Key): bool = key in engine().input.keyWasReleased +proc characterInput*(): Rune = + engine().input.characterInput + proc mouseIsDown*(button: MouseButton): bool = button in engine().input.mouseIsDown
--- a/semicongine/platform/linux/rendering.nim Sun Mar 16 22:33:35 2025 +0700 +++ b/semicongine/platform/linux/rendering.nim Fri Mar 21 18:16:24 2025 +0700 @@ -1,4 +1,5 @@ import std/options +import std/unicode import std/tables import ../../thirdparty/x11/xlib @@ -165,7 +166,14 @@ var empty_cursor = display.XCreatePixmapCursor(pixmap, pixmap, addr(color), addr(color), 0, 0) checkXlibResult display.XFreePixmap(pixmap) - return NativeWindow(display: display, window: window, emptyCursor: empty_cursor) + + # get an input context, to allow encoding of key-events to characters + let im = XOpenIM(display, nil, nil, nil) + let ic = XCreateIC( + im, XNInputStyle, XIMPreeditNothing or XIMStatusNothing, XNClientWindow, window, nil + ) + return + NativeWindow(display: display, window: window, emptyCursor: empty_cursor, ic: ic) proc destroyWindow*(window: NativeWindow) = checkXlibResult XDestroyWindow(window.display, window.window) @@ -214,6 +222,9 @@ discard XGetWindowAttributes(window.display, window.window, addr(attribs)) vec2i(attribs.width, attribs.height) +# buffer to save utf8-data from keyboard events +var unicodeData = newString(16) + proc pendingEvents*(window: NativeWindow): seq[Event] = var event: XEvent while window.display.XPending() > 0: @@ -225,9 +236,17 @@ of KeyPress: let keyevent = cast[PXKeyEvent](addr(event)) let xkey = int(keyevent.keycode) - result.add Event( - eventType: KeyPressed, key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN) + var e = + Event(eventType: KeyPressed, key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN)) + let len = Xutf8LookupString( + window.ic, keyevent, unicodeData, unicodeData.len.cint, nil, nil ) + if len > 0: + unicodeData.setLen(len) + for r in unicodeData.runes(): + e.char = r + break + result.add e of KeyRelease: let keyevent = cast[PXKeyEvent](addr(event)) let xkey = int(keyevent.keycode)
--- a/semicongine/platform/linux/types.nim Sun Mar 16 22:33:35 2025 +0700 +++ b/semicongine/platform/linux/types.nim Fri Mar 21 18:16:24 2025 +0700 @@ -5,6 +5,7 @@ display*: ptr xlib.Display window*: x11.Window emptyCursor*: Cursor + ic*: XIC # alsa API type
--- a/semicongine/platform/windows/rendering.nim Sun Mar 16 22:33:35 2025 +0700 +++ b/semicongine/platform/windows/rendering.nim Fri Mar 21 18:16:24 2025 +0700 @@ -134,6 +134,17 @@ currentEvents.add( Event(eventType: KeyPressed, key: KeyTypeMap.getOrDefault(key, Key.UNKNOWN)) ) + #[ + proc ToUnicodeEx*( + wVirtKey: UINT, + wScanCode: UINT, + lpKeyState: ptr BYTE, + pwszBuff: LPWSTR, + cchBuff: int32, + wFlags: UINT, + dwhkl: HKL, + ): int32 {.winapi, stdcall, dynlib: "user32", importc.} + ]# of WM_KEYUP, WM_SYSKEYUP: let key = mapLeftRightKeys(INT(wParam), lParam) currentEvents.add(