From 56507d7ac27d0562689ea7c505fa026ecc38494f Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 2 May 2020 16:55:13 +0200 Subject: Implement keyboard output for wininput --- backends/wininput.c | 148 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 31 deletions(-) (limited to 'backends/wininput.c') diff --git a/backends/wininput.c b/backends/wininput.c index 352be66..46151d4 100644 --- a/backends/wininput.c +++ b/backends/wininput.c @@ -4,6 +4,55 @@ #include #include "wininput.h" +static key_info keys[] = { + {VK_LBUTTON, "lmb", button}, {VK_RBUTTON, "rmb", button}, {VK_MBUTTON, "mmb", button}, + {VK_XBUTTON1, "xmb1", button}, {VK_XBUTTON2, "xmb2", button}, + {VK_BACK, "backspace"}, + {VK_TAB, "tab"}, + {VK_CLEAR, "clear"}, + {VK_RETURN, "enter"}, + {VK_SHIFT, "shift"}, + {VK_CONTROL, "control"}, {VK_MENU, "alt"}, + {VK_CAPITAL, "capslock"}, + {VK_ESCAPE, "escape"}, + {VK_SPACE, "space"}, + {VK_PRIOR, "pageup"}, {VK_NEXT, "pagedown"}, + {VK_END, "end"}, {VK_HOME, "home"}, + {VK_PAUSE, "pause"}, {VK_NUMLOCK, "numlock"}, {VK_SCROLL, "scrolllock"}, + {VK_INSERT, "insert"}, {VK_DELETE, "delete"}, {VK_SNAPSHOT, "printscreen"}, + {VK_LEFT, "left"}, {VK_UP, "up"}, {VK_RIGHT, "right"}, {VK_DOWN, "down"}, + {VK_SELECT, "select"}, + {VK_PRINT, "print"}, + {VK_EXECUTE, "execute"}, + {VK_HELP, "help"}, + {VK_APPS, "apps"}, + {VK_SLEEP, "sleep"}, + {VK_NUMPAD0, "num0"}, {VK_NUMPAD1, "num1"}, {VK_NUMPAD2, "num2"}, {VK_NUMPAD3, "num3"}, + {VK_NUMPAD4, "num4"}, {VK_NUMPAD5, "num5"}, {VK_NUMPAD6, "num6"}, {VK_NUMPAD7, "num7"}, + {VK_NUMPAD8, "num8"}, {VK_NUMPAD9, "num9"}, {VK_MULTIPLY, "multiply"}, {VK_ADD, "plus"}, + {VK_SEPARATOR, "comma"}, {VK_SUBTRACT, "minus"}, {VK_DECIMAL, "dot"}, {VK_DIVIDE, "divide"}, + {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_F13, "f13"}, {VK_F14, "f14"}, {VK_F15, "f15"}, + {VK_F16, "f16"}, {VK_F17, "f17"}, {VK_F18, "f18"}, {VK_F19, "f19"}, {VK_F20, "f20"}, + {VK_F21, "f21"}, {VK_F22, "f22"}, {VK_F23, "f23"}, {VK_F24, "f24"}, + {VK_LWIN, "lwin"}, {VK_RWIN, "rwin"}, + {VK_LSHIFT, "lshift"}, {VK_RSHIFT, "rshift"}, + {VK_LCONTROL, "lctrl"}, {VK_RCONTROL, "rctrl"}, + {VK_LMENU, "lmenu"}, {VK_RMENU, "rmenu"}, + {VK_BROWSER_BACK, "previous"}, {VK_BROWSER_FORWARD, "next"}, {VK_BROWSER_REFRESH, "refresh"}, + {VK_BROWSER_STOP, "stop"}, {VK_BROWSER_SEARCH, "search"}, {VK_BROWSER_FAVORITES, "favorites"}, + {VK_BROWSER_HOME, "homepage"}, + {VK_VOLUME_MUTE, "mute"}, {VK_VOLUME_DOWN, "voldown"}, {VK_VOLUME_UP, "volup"}, + {VK_MEDIA_NEXT_TRACK, "nexttrack"}, {VK_MEDIA_PREV_TRACK, "prevtrack"}, + {VK_MEDIA_STOP, "stopmedia"}, {VK_MEDIA_PLAY_PAUSE, "togglemedia"}, + {VK_LAUNCH_MEDIA_SELECT, "mediaselect"}, + {VK_LAUNCH_MAIL, "mail"}, {VK_LAUNCH_APP1, "app1"}, {VK_LAUNCH_APP2, "app2"}, + {VK_OEM_PLUS, "plus"}, {VK_OEM_COMMA, "comma"}, + {VK_OEM_MINUS, "minus"}, {VK_OEM_PERIOD, "period"}, + {VK_ZOOM, "zoom"} +}; + MM_PLUGIN_API int init(){ backend wininput = { .name = BACKEND_NAME, @@ -52,6 +101,8 @@ static int wininput_instance(instance* inst){ } static channel* wininput_channel(instance* inst, char* spec, uint8_t flags){ + size_t u; + uint16_t scancode = 0; char* token = spec; wininput_channel_ident ident = { .label = 0 @@ -68,33 +119,62 @@ static channel* wininput_channel(instance* inst, char* spec, uint8_t flags){ ident.fields.channel = position; ident.fields.control = 1; } - else if(!strcmp(token, "lmb")){ - ident.fields.channel = button; - } - else if(!strcmp(token, "rmb")){ - ident.fields.channel = button; - ident.fields.control = 1; - } - else if(!strcmp(token, "mmb")){ - ident.fields.channel = button; - ident.fields.control = 2; - } - else if(!strcmp(token, "xmb1")){ - ident.fields.channel = button; - ident.fields.control = 3; - } - else if(!strcmp(token, "xmb2")){ - ident.fields.channel = button; - ident.fields.control = 4; - } else{ - LOGPF("Unknown control %s", token); - return NULL; + //check the buttons + for(u = 0; u < sizeof(keys) / sizeof(keys[0]); u++){ + if(keys[u].channel == button && !strcmp(keys[u].name, token)){ + DBGPF("Using keymap %" PRIsize_t " (%d) for spec %s", u, keys[u].keycode, token); + ident.fields.channel = button; + ident.fields.control = keys[u].keycode; + break; + } + } } } - else if(!strncmp(spec, "keyboard.", 9)){ - token += 9; - //TODO + else if(!strncmp(spec, "key.", 4)){ + token += 4; + ident.fields.type = keyboard; + ident.fields.channel = keypress; + + for(u = 0; u < sizeof(keys) / sizeof(keys[0]); u++){ + if(keys[u].channel == keypress && !strcmp(keys[u].name, token)){ + DBGPF("Using keymap %" PRIsize_t " (%d) for spec %s", u, keys[u].keycode, token); + ident.fields.control = keys[u].keycode; + break; + } + } + + //no entry in translation table + if(u == sizeof(keys) / sizeof(keys[0])){ + if(strlen(token) == 1){ + //try to translate + scancode = VkKeyScan(token[0]); + if(scancode != 0x7f7f){ + DBGPF("Using keyscan result %02X (via %04X) for spec %s", scancode & 0xFF, scancode, token); + ident.fields.type = keyboard; + ident.fields.channel = keypress; + ident.fields.control = scancode & 0xFF; + } + else{ + LOGPF("Invalid channel specification %s", token); + return NULL; + } + } + else if(strlen(token) > 1){ + //try to use as literal + scancode = strtoul(token, NULL, 0); + if(!scancode){ + LOGPF("Invalid channel specification %s", token); + return NULL; + } + DBGPF("Using direct conversion %d for spec %s", scancode & 0xFF, token); + ident.fields.control = scancode & 0xFF; + } + else{ + LOGPF("Invalid channel specification %s", spec); + return NULL; + } + } } else{ LOGPF("Unknown channel spec %s", spec); @@ -126,21 +206,21 @@ static INPUT wininput_event_mouse(wininput_instance_data* data, uint8_t channel, } if(channel == button){ switch(control){ - case 0: + case VK_LBUTTON: flags_up |= MOUSEEVENTF_LEFTUP; flags_down |= MOUSEEVENTF_LEFTDOWN; break; - case 1: + case VK_RBUTTON: flags_up |= MOUSEEVENTF_RIGHTUP; flags_down |= MOUSEEVENTF_RIGHTDOWN; break; - case 2: + case VK_MBUTTON: flags_up |= MOUSEEVENTF_MIDDLEUP; flags_down |= MOUSEEVENTF_MIDDLEDOWN; break; - case 3: - case 4: - ev.mi.mouseData = (control == 3) ? XBUTTON1 : XBUTTON2; + case VK_XBUTTON1: + case VK_XBUTTON2: + ev.mi.mouseData = (control == VK_XBUTTON1) ? XBUTTON1 : XBUTTON2; flags_up |= MOUSEEVENTF_XUP; flags_down |= MOUSEEVENTF_XDOWN; break; @@ -162,6 +242,13 @@ static INPUT wininput_event_keyboard(wininput_instance_data* data, uint8_t chann .type = INPUT_KEYBOARD }; + if(channel == keypress){ + ev.ki.wVk = control; + if(value < 0.9){ + ev.ki.dwFlags |= KEYEVENTF_KEYUP; + } + } + return ev; } @@ -173,7 +260,6 @@ static int wininput_set(instance* inst, size_t num, channel** c, channel_value* size_t n = 0, offset = 0; INPUT events[500]; - //FIXME might want to coalesce mouse events if(num > sizeof(events) / sizeof(events[0])){ LOGPF("Truncating output on %s to the last %" PRIsize_t " events, please notify the developers", inst->name, sizeof(events) / sizeof(events[0])); offset = num - sizeof(events) / sizeof(events[0]); -- cgit v1.2.3