331 lines
17 KiB
Text
331 lines
17 KiB
Text
|
|
/*
|
||
|
|
Crafter®.Graphics
|
||
|
|
Copyright (C) 2026 Catcrafts®
|
||
|
|
Catcrafts.net
|
||
|
|
|
||
|
|
This library is free software; you can redistribute it and/or
|
||
|
|
modify it under the terms of the GNU Lesser General Public
|
||
|
|
License as published by the Free Software Foundation; either
|
||
|
|
version 3.0 of the License, or (at your option) any later version.
|
||
|
|
|
||
|
|
This library is distributed in the hope that it will be useful,
|
||
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
|
Lesser General Public License for more details.
|
||
|
|
|
||
|
|
You should have received a copy of the GNU Lesser General Public
|
||
|
|
License along with this library; if not, write to the Free Software
|
||
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
|
*/
|
||
|
|
module;
|
||
|
|
#ifdef CRAFTER_GRAPHICS_WINDOW_WAYLAND
|
||
|
|
#include <linux/input-event-codes.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
export module Crafter.Graphics:Keys;
|
||
|
|
import std;
|
||
|
|
import :Types;
|
||
|
|
|
||
|
|
// Compile-time translation from the abstract `CrafterKeys` enum to the raw
|
||
|
|
// platform key code that the runtime actually stores and compares. The whole
|
||
|
|
// point: bindings, events, and InputField never carry the abstract enum at
|
||
|
|
// runtime — they carry the raw integer the platform delivers. `Key(...)` is
|
||
|
|
// `consteval` so every call from source folds to an immediate operand; user
|
||
|
|
// code stays cross-platform (`Key(CrafterKeys::Space)`) without any `#ifdef`
|
||
|
|
// at the call site.
|
||
|
|
//
|
||
|
|
// Domain of the returned KeyCode:
|
||
|
|
// Win32: bits 0..7 = PS/2 set-1 scancode byte. Bit 8 = extended-key flag
|
||
|
|
// (the 0xE0-prefixed variants — RightCtrl, RightAlt, the keypad's
|
||
|
|
// Enter and /, the cursor cluster's arrows/Home/End/etc., the
|
||
|
|
// Windows keys). At runtime, WndProc OR-s in 0x100 when lParam
|
||
|
|
// bit 24 is set, so a saved binding for "RightCtrl" (0x11D) survives
|
||
|
|
// round-trip with the actual hardware event.
|
||
|
|
// Wayland/Linux: kernel input-event-codes (KEY_*) directly. The +8 X11
|
||
|
|
// offset is stripped at the wl_keyboard.key boundary so the
|
||
|
|
// runtime values match the table here.
|
||
|
|
//
|
||
|
|
// Keys with no clean scancode encoding (Pause, some keys without standard
|
||
|
|
// physical position) return 0. 0 is documented as "unmapped"; binding to it
|
||
|
|
// will never match a real keypress.
|
||
|
|
|
||
|
|
export namespace Crafter {
|
||
|
|
using KeyCode = std::uint32_t;
|
||
|
|
|
||
|
|
consteval KeyCode Key(CrafterKeys k) {
|
||
|
|
#ifdef CRAFTER_GRAPHICS_WINDOW_WIN32
|
||
|
|
// PS/2 set-1 scancodes. Extended keys carry 0x100 so the runtime
|
||
|
|
// path can disambiguate by OR-ing in 0x100 when lParam bit 24 is set.
|
||
|
|
switch (k) {
|
||
|
|
// Alphabetic
|
||
|
|
case CrafterKeys::A: return 0x1E;
|
||
|
|
case CrafterKeys::B: return 0x30;
|
||
|
|
case CrafterKeys::C: return 0x2E;
|
||
|
|
case CrafterKeys::D: return 0x20;
|
||
|
|
case CrafterKeys::E: return 0x12;
|
||
|
|
case CrafterKeys::F: return 0x21;
|
||
|
|
case CrafterKeys::G: return 0x22;
|
||
|
|
case CrafterKeys::H: return 0x23;
|
||
|
|
case CrafterKeys::I: return 0x17;
|
||
|
|
case CrafterKeys::J: return 0x24;
|
||
|
|
case CrafterKeys::K: return 0x25;
|
||
|
|
case CrafterKeys::L: return 0x26;
|
||
|
|
case CrafterKeys::M: return 0x32;
|
||
|
|
case CrafterKeys::N: return 0x31;
|
||
|
|
case CrafterKeys::O: return 0x18;
|
||
|
|
case CrafterKeys::P: return 0x19;
|
||
|
|
case CrafterKeys::Q: return 0x10;
|
||
|
|
case CrafterKeys::R: return 0x13;
|
||
|
|
case CrafterKeys::S: return 0x1F;
|
||
|
|
case CrafterKeys::T: return 0x14;
|
||
|
|
case CrafterKeys::U: return 0x16;
|
||
|
|
case CrafterKeys::V: return 0x2F;
|
||
|
|
case CrafterKeys::W: return 0x11;
|
||
|
|
case CrafterKeys::X: return 0x2D;
|
||
|
|
case CrafterKeys::Y: return 0x15;
|
||
|
|
case CrafterKeys::Z: return 0x2C;
|
||
|
|
// Numeric (top row)
|
||
|
|
case CrafterKeys::_1: return 0x02;
|
||
|
|
case CrafterKeys::_2: return 0x03;
|
||
|
|
case CrafterKeys::_3: return 0x04;
|
||
|
|
case CrafterKeys::_4: return 0x05;
|
||
|
|
case CrafterKeys::_5: return 0x06;
|
||
|
|
case CrafterKeys::_6: return 0x07;
|
||
|
|
case CrafterKeys::_7: return 0x08;
|
||
|
|
case CrafterKeys::_8: return 0x09;
|
||
|
|
case CrafterKeys::_9: return 0x0A;
|
||
|
|
case CrafterKeys::_0: return 0x0B;
|
||
|
|
// Function keys
|
||
|
|
case CrafterKeys::F1: return 0x3B;
|
||
|
|
case CrafterKeys::F2: return 0x3C;
|
||
|
|
case CrafterKeys::F3: return 0x3D;
|
||
|
|
case CrafterKeys::F4: return 0x3E;
|
||
|
|
case CrafterKeys::F5: return 0x3F;
|
||
|
|
case CrafterKeys::F6: return 0x40;
|
||
|
|
case CrafterKeys::F7: return 0x41;
|
||
|
|
case CrafterKeys::F8: return 0x42;
|
||
|
|
case CrafterKeys::F9: return 0x43;
|
||
|
|
case CrafterKeys::F10: return 0x44;
|
||
|
|
case CrafterKeys::F11: return 0x57;
|
||
|
|
case CrafterKeys::F12: return 0x58;
|
||
|
|
// Control keys
|
||
|
|
case CrafterKeys::Escape: return 0x01;
|
||
|
|
case CrafterKeys::Tab: return 0x0F;
|
||
|
|
case CrafterKeys::Enter: return 0x1C;
|
||
|
|
case CrafterKeys::Space: return 0x39;
|
||
|
|
case CrafterKeys::Backspace: return 0x0E;
|
||
|
|
case CrafterKeys::Delete: return 0x153; // extended
|
||
|
|
case CrafterKeys::Insert: return 0x152; // extended
|
||
|
|
case CrafterKeys::Home: return 0x147; // extended
|
||
|
|
case CrafterKeys::End: return 0x14F; // extended
|
||
|
|
case CrafterKeys::PageUp: return 0x149; // extended
|
||
|
|
case CrafterKeys::PageDown: return 0x151; // extended
|
||
|
|
case CrafterKeys::CapsLock: return 0x3A;
|
||
|
|
case CrafterKeys::NumLock: return 0x45;
|
||
|
|
case CrafterKeys::ScrollLock: return 0x46;
|
||
|
|
// Modifiers
|
||
|
|
case CrafterKeys::LeftShift: return 0x2A;
|
||
|
|
case CrafterKeys::RightShift: return 0x36;
|
||
|
|
case CrafterKeys::LeftCtrl: return 0x1D;
|
||
|
|
case CrafterKeys::RightCtrl: return 0x11D; // extended
|
||
|
|
case CrafterKeys::LeftAlt: return 0x38;
|
||
|
|
case CrafterKeys::RightAlt: return 0x138; // extended
|
||
|
|
case CrafterKeys::LeftSuper: return 0x15B; // extended
|
||
|
|
case CrafterKeys::RightSuper: return 0x15C; // extended
|
||
|
|
// Arrows (all extended on Win32 — the cursor cluster, not the keypad)
|
||
|
|
case CrafterKeys::Up: return 0x148;
|
||
|
|
case CrafterKeys::Down: return 0x150;
|
||
|
|
case CrafterKeys::Left: return 0x14B;
|
||
|
|
case CrafterKeys::Right: return 0x14D;
|
||
|
|
// Keypad
|
||
|
|
case CrafterKeys::keypad_0: return 0x52;
|
||
|
|
case CrafterKeys::keypad_1: return 0x4F;
|
||
|
|
case CrafterKeys::keypad_2: return 0x50;
|
||
|
|
case CrafterKeys::keypad_3: return 0x51;
|
||
|
|
case CrafterKeys::keypad_4: return 0x4B;
|
||
|
|
case CrafterKeys::keypad_5: return 0x4C;
|
||
|
|
case CrafterKeys::keypad_6: return 0x4D;
|
||
|
|
case CrafterKeys::keypad_7: return 0x47;
|
||
|
|
case CrafterKeys::keypad_8: return 0x48;
|
||
|
|
case CrafterKeys::keypad_9: return 0x49;
|
||
|
|
case CrafterKeys::keypad_enter: return 0x11C; // extended
|
||
|
|
case CrafterKeys::keypad_plus: return 0x4E;
|
||
|
|
case CrafterKeys::keypad_minus: return 0x4A;
|
||
|
|
case CrafterKeys::keypad_multiply: return 0x37;
|
||
|
|
case CrafterKeys::keypad_divide: return 0x135; // extended
|
||
|
|
case CrafterKeys::keypad_decimal: return 0x53;
|
||
|
|
// Punctuation
|
||
|
|
case CrafterKeys::grave: return 0x29;
|
||
|
|
case CrafterKeys::minus: return 0x0C;
|
||
|
|
case CrafterKeys::equal: return 0x0D;
|
||
|
|
case CrafterKeys::bracket_left: return 0x1A;
|
||
|
|
case CrafterKeys::bracket_right: return 0x1B;
|
||
|
|
case CrafterKeys::backslash: return 0x2B;
|
||
|
|
case CrafterKeys::semicolon: return 0x27;
|
||
|
|
case CrafterKeys::quote: return 0x28;
|
||
|
|
case CrafterKeys::comma: return 0x33;
|
||
|
|
case CrafterKeys::period: return 0x34;
|
||
|
|
case CrafterKeys::slash: return 0x35;
|
||
|
|
case CrafterKeys::print_screen: return 0x137; // extended
|
||
|
|
case CrafterKeys::pause: return 0; // unmapped — multi-byte sequence
|
||
|
|
case CrafterKeys::menu: return 0x15D; // extended (App key)
|
||
|
|
// Multimedia / browser / launch keys (all extended on Win32)
|
||
|
|
case CrafterKeys::volume_up: return 0x130;
|
||
|
|
case CrafterKeys::volume_down: return 0x12E;
|
||
|
|
case CrafterKeys::volume_mute: return 0x120;
|
||
|
|
case CrafterKeys::media_play: return 0x122;
|
||
|
|
case CrafterKeys::media_stop: return 0x124;
|
||
|
|
case CrafterKeys::media_prev: return 0x110;
|
||
|
|
case CrafterKeys::media_next: return 0x119;
|
||
|
|
case CrafterKeys::browser_back: return 0x16A;
|
||
|
|
case CrafterKeys::browser_forward: return 0x169;
|
||
|
|
case CrafterKeys::browser_refresh: return 0x167;
|
||
|
|
case CrafterKeys::browser_stop: return 0x168;
|
||
|
|
case CrafterKeys::browser_search: return 0x165;
|
||
|
|
case CrafterKeys::browser_home: return 0x132;
|
||
|
|
case CrafterKeys::launch_mail: return 0x16C;
|
||
|
|
case CrafterKeys::launch_calculator: return 0x121;
|
||
|
|
case CrafterKeys::launch_media_player: return 0x16D;
|
||
|
|
case CrafterKeys::CrafterKeysMax: return 0;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef CRAFTER_GRAPHICS_WINDOW_WAYLAND
|
||
|
|
// Linux kernel input-event-codes. The Wayland keyboard handler strips
|
||
|
|
// the +8 X11 offset before delivery so these match wl_keyboard.key
|
||
|
|
// values directly.
|
||
|
|
switch (k) {
|
||
|
|
// Alphabetic
|
||
|
|
case CrafterKeys::A: return KEY_A;
|
||
|
|
case CrafterKeys::B: return KEY_B;
|
||
|
|
case CrafterKeys::C: return KEY_C;
|
||
|
|
case CrafterKeys::D: return KEY_D;
|
||
|
|
case CrafterKeys::E: return KEY_E;
|
||
|
|
case CrafterKeys::F: return KEY_F;
|
||
|
|
case CrafterKeys::G: return KEY_G;
|
||
|
|
case CrafterKeys::H: return KEY_H;
|
||
|
|
case CrafterKeys::I: return KEY_I;
|
||
|
|
case CrafterKeys::J: return KEY_J;
|
||
|
|
case CrafterKeys::K: return KEY_K;
|
||
|
|
case CrafterKeys::L: return KEY_L;
|
||
|
|
case CrafterKeys::M: return KEY_M;
|
||
|
|
case CrafterKeys::N: return KEY_N;
|
||
|
|
case CrafterKeys::O: return KEY_O;
|
||
|
|
case CrafterKeys::P: return KEY_P;
|
||
|
|
case CrafterKeys::Q: return KEY_Q;
|
||
|
|
case CrafterKeys::R: return KEY_R;
|
||
|
|
case CrafterKeys::S: return KEY_S;
|
||
|
|
case CrafterKeys::T: return KEY_T;
|
||
|
|
case CrafterKeys::U: return KEY_U;
|
||
|
|
case CrafterKeys::V: return KEY_V;
|
||
|
|
case CrafterKeys::W: return KEY_W;
|
||
|
|
case CrafterKeys::X: return KEY_X;
|
||
|
|
case CrafterKeys::Y: return KEY_Y;
|
||
|
|
case CrafterKeys::Z: return KEY_Z;
|
||
|
|
// Numeric
|
||
|
|
case CrafterKeys::_0: return KEY_0;
|
||
|
|
case CrafterKeys::_1: return KEY_1;
|
||
|
|
case CrafterKeys::_2: return KEY_2;
|
||
|
|
case CrafterKeys::_3: return KEY_3;
|
||
|
|
case CrafterKeys::_4: return KEY_4;
|
||
|
|
case CrafterKeys::_5: return KEY_5;
|
||
|
|
case CrafterKeys::_6: return KEY_6;
|
||
|
|
case CrafterKeys::_7: return KEY_7;
|
||
|
|
case CrafterKeys::_8: return KEY_8;
|
||
|
|
case CrafterKeys::_9: return KEY_9;
|
||
|
|
// Function keys
|
||
|
|
case CrafterKeys::F1: return KEY_F1;
|
||
|
|
case CrafterKeys::F2: return KEY_F2;
|
||
|
|
case CrafterKeys::F3: return KEY_F3;
|
||
|
|
case CrafterKeys::F4: return KEY_F4;
|
||
|
|
case CrafterKeys::F5: return KEY_F5;
|
||
|
|
case CrafterKeys::F6: return KEY_F6;
|
||
|
|
case CrafterKeys::F7: return KEY_F7;
|
||
|
|
case CrafterKeys::F8: return KEY_F8;
|
||
|
|
case CrafterKeys::F9: return KEY_F9;
|
||
|
|
case CrafterKeys::F10: return KEY_F10;
|
||
|
|
case CrafterKeys::F11: return KEY_F11;
|
||
|
|
case CrafterKeys::F12: return KEY_F12;
|
||
|
|
// Control keys
|
||
|
|
case CrafterKeys::Escape: return KEY_ESC;
|
||
|
|
case CrafterKeys::Tab: return KEY_TAB;
|
||
|
|
case CrafterKeys::Enter: return KEY_ENTER;
|
||
|
|
case CrafterKeys::Space: return KEY_SPACE;
|
||
|
|
case CrafterKeys::Backspace: return KEY_BACKSPACE;
|
||
|
|
case CrafterKeys::Delete: return KEY_DELETE;
|
||
|
|
case CrafterKeys::Insert: return KEY_INSERT;
|
||
|
|
case CrafterKeys::Home: return KEY_HOME;
|
||
|
|
case CrafterKeys::End: return KEY_END;
|
||
|
|
case CrafterKeys::PageUp: return KEY_PAGEUP;
|
||
|
|
case CrafterKeys::PageDown: return KEY_PAGEDOWN;
|
||
|
|
case CrafterKeys::CapsLock: return KEY_CAPSLOCK;
|
||
|
|
case CrafterKeys::NumLock: return KEY_NUMLOCK;
|
||
|
|
case CrafterKeys::ScrollLock: return KEY_SCROLLLOCK;
|
||
|
|
// Modifiers
|
||
|
|
case CrafterKeys::LeftShift: return KEY_LEFTSHIFT;
|
||
|
|
case CrafterKeys::RightShift: return KEY_RIGHTSHIFT;
|
||
|
|
case CrafterKeys::LeftCtrl: return KEY_LEFTCTRL;
|
||
|
|
case CrafterKeys::RightCtrl: return KEY_RIGHTCTRL;
|
||
|
|
case CrafterKeys::LeftAlt: return KEY_LEFTALT;
|
||
|
|
case CrafterKeys::RightAlt: return KEY_RIGHTALT;
|
||
|
|
case CrafterKeys::LeftSuper: return KEY_LEFTMETA;
|
||
|
|
case CrafterKeys::RightSuper: return KEY_RIGHTMETA;
|
||
|
|
// Arrows
|
||
|
|
case CrafterKeys::Up: return KEY_UP;
|
||
|
|
case CrafterKeys::Down: return KEY_DOWN;
|
||
|
|
case CrafterKeys::Left: return KEY_LEFT;
|
||
|
|
case CrafterKeys::Right: return KEY_RIGHT;
|
||
|
|
// Keypad
|
||
|
|
case CrafterKeys::keypad_0: return KEY_KP0;
|
||
|
|
case CrafterKeys::keypad_1: return KEY_KP1;
|
||
|
|
case CrafterKeys::keypad_2: return KEY_KP2;
|
||
|
|
case CrafterKeys::keypad_3: return KEY_KP3;
|
||
|
|
case CrafterKeys::keypad_4: return KEY_KP4;
|
||
|
|
case CrafterKeys::keypad_5: return KEY_KP5;
|
||
|
|
case CrafterKeys::keypad_6: return KEY_KP6;
|
||
|
|
case CrafterKeys::keypad_7: return KEY_KP7;
|
||
|
|
case CrafterKeys::keypad_8: return KEY_KP8;
|
||
|
|
case CrafterKeys::keypad_9: return KEY_KP9;
|
||
|
|
case CrafterKeys::keypad_enter: return KEY_KPENTER;
|
||
|
|
case CrafterKeys::keypad_plus: return KEY_KPPLUS;
|
||
|
|
case CrafterKeys::keypad_minus: return KEY_KPMINUS;
|
||
|
|
case CrafterKeys::keypad_multiply: return KEY_KPASTERISK;
|
||
|
|
case CrafterKeys::keypad_divide: return KEY_KPSLASH;
|
||
|
|
case CrafterKeys::keypad_decimal: return KEY_KPDOT;
|
||
|
|
// Punctuation
|
||
|
|
case CrafterKeys::grave: return KEY_GRAVE;
|
||
|
|
case CrafterKeys::minus: return KEY_MINUS;
|
||
|
|
case CrafterKeys::equal: return KEY_EQUAL;
|
||
|
|
case CrafterKeys::bracket_left: return KEY_LEFTBRACE;
|
||
|
|
case CrafterKeys::bracket_right: return KEY_RIGHTBRACE;
|
||
|
|
case CrafterKeys::backslash: return KEY_BACKSLASH;
|
||
|
|
case CrafterKeys::semicolon: return KEY_SEMICOLON;
|
||
|
|
case CrafterKeys::quote: return KEY_APOSTROPHE;
|
||
|
|
case CrafterKeys::comma: return KEY_COMMA;
|
||
|
|
case CrafterKeys::period: return KEY_DOT;
|
||
|
|
case CrafterKeys::slash: return KEY_SLASH;
|
||
|
|
case CrafterKeys::print_screen: return KEY_SYSRQ;
|
||
|
|
case CrafterKeys::pause: return KEY_PAUSE;
|
||
|
|
case CrafterKeys::menu: return KEY_COMPOSE;
|
||
|
|
// Multimedia / browser / launch keys
|
||
|
|
case CrafterKeys::volume_up: return KEY_VOLUMEUP;
|
||
|
|
case CrafterKeys::volume_down: return KEY_VOLUMEDOWN;
|
||
|
|
case CrafterKeys::volume_mute: return KEY_MUTE;
|
||
|
|
case CrafterKeys::media_play: return KEY_PLAYPAUSE;
|
||
|
|
case CrafterKeys::media_stop: return KEY_STOPCD;
|
||
|
|
case CrafterKeys::media_prev: return KEY_PREVIOUSSONG;
|
||
|
|
case CrafterKeys::media_next: return KEY_NEXTSONG;
|
||
|
|
case CrafterKeys::browser_back: return KEY_BACK;
|
||
|
|
case CrafterKeys::browser_forward: return KEY_FORWARD;
|
||
|
|
case CrafterKeys::browser_refresh: return KEY_REFRESH;
|
||
|
|
case CrafterKeys::browser_stop: return KEY_STOP;
|
||
|
|
case CrafterKeys::browser_search: return KEY_SEARCH;
|
||
|
|
case CrafterKeys::browser_home: return KEY_HOMEPAGE;
|
||
|
|
case CrafterKeys::launch_mail: return KEY_MAIL;
|
||
|
|
case CrafterKeys::launch_calculator: return KEY_CALC;
|
||
|
|
case CrafterKeys::launch_media_player: return KEY_MEDIA;
|
||
|
|
case CrafterKeys::CrafterKeysMax: return 0;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|