20 #ifdef HID_KBD_MAP_CFG_SUPPORT
37 static int mouse_delta_x;
38 static int mouse_delta_y;
39 static unsigned int hid_state;
41 #define MAX_JOYSTICKS 16
46 #define JOYSTATE_DOWN 2
47 #define JOYSTATE_LEFT 4
48 #define JOYSTATE_RIGHT 8
49 #define JOYSTATE_BUTTON 16
50 #define MOUSESTATE_BUTTON_LEFT 32
51 #define MOUSESTATE_BUTTON_RIGHT 64
54 static Uint8 virtual_shift_pos = 0;
57 static int release_this_key_on_first_event = -1;
60 #define HID_MAX_CUSTOM_CALLBACKS 3
68 release_this_key_on_first_event = key;
76 OSD(-1, -1,
"Key %s <%s>", pressed ?
"press " :
"release", SDL_GetScancodeName(key));
86 case SDL_SCANCODE_RGUI:
88 default: sel = -1;
break;
98 while (map->
pos >= 0) {
99 if (map->
scan == key) {
102 release_this_key_on_first_event = -1;
104 if (map->
pos > 0xFF) {
148 while (map->
pos >= 0) {
149 if (map->
pos == matrix_pos) {
150 SDL_Event sdlevent = {};
151 sdlevent.type = is_press ? SDL_KEYDOWN : SDL_KEYUP;
152 sdlevent.key.repeat = 0;
154 sdlevent.key.state = is_press ? SDL_PRESSED : SDL_RELEASED;
155 sdlevent.key.keysym.scancode = map->
scan;
156 SDL_PushEvent(&sdlevent);
181 #ifdef HID_KBD_MAP_CFG_SUPPORT
183 #define CLEARALLMAPPING "CLEARALLMAPPING"
185 static const char *HID_ERR_STR_UNKNOWN_HOST_KEYNAME =
"Unknown host keyname";
186 static const char *HID_ERR_STR_UNKNOWN_EMU_KEYNAME =
"Unknown emu keyname";
188 static const char *scan_name_unknown =
"Unknown";
190 const char *hid_keymap_add_mapping (
const char *emu_key_name,
const char *host_key_name )
193 if (strcmp(host_key_name, scan_name_unknown)) {
194 scan = SDL_GetScancodeFromName(host_key_name);
195 if (
scan == SDL_SCANCODE_UNKNOWN)
196 return HID_ERR_STR_UNKNOWN_HOST_KEYNAME;
198 scan = SDL_SCANCODE_UNKNOWN;
202 for (source = 0 ;; source++) {
203 if (key_map_default[source].
pos < 0)
204 return HID_ERR_STR_UNKNOWN_EMU_KEYNAME;
205 if (key_map_default[source].
name && (!strcmp(key_map_default[source].
name, emu_key_name))) {
207 pos = key_map_default[source].
pos;
213 for (
int a = 0; key_map[a].
pos >= 0 ; a++) {
214 if (key_map[a].
pos ==
pos && key_map[a].
set != source) {
215 if (key_map[a].
scan !=
scan && key_map[a].
set != -2) {
216 DEBUGPRINT(
"HID: altering keyboard mapping for \"%s\" from \"%s\" to \"%s\" at array index #%d" NL,
217 emu_key_name, SDL_GetScancodeName(key_map[a].
scan), host_key_name, a
221 key_map[a].
set = source;
229 const char *hid_keymap_add_mapping_from_config_line (
const char *p,
int *
num_of_items )
232 while (*p <= 0x20 && *p)
234 if (*p ==
'\0' || *p ==
'#')
236 const char *emu_p = p;
239 if (*p ==
'\0' || *p ==
'#' || p - emu_p >=
sizeof(emu_name))
241 memcpy(emu_name, emu_p, p - emu_p);
242 emu_name[p - emu_p] = 0;
243 if (!strcmp(emu_name, CLEARALLMAPPING)) {
244 for (
int a = 0; key_map[a].
pos >= 0; a++) {
250 while (*p <= 32 && *p)
252 if (*p == 0 || *p ==
'#')
254 const char *host_p = p;
255 while (*p && *p != 13 && *p != 10 && *p !=
'#')
258 while (p[-1] <= 0x20 && p > host_p)
264 const char *res = hid_keymap_add_mapping(emu_name,
host_name);
266 DEBUGPRINT(
"HID: error on keymap user config: emu_name=[%s] host_key=<%s>: %s\n", emu_name,
host_name, res);
270 while (*p != 10 && *p != 13 && *p)
276 void hid_keymap_from_config_file (
const char *
fn )
281 DEBUGPRINT(
"HID: cannot open keymap user config file (maybe does not exist), ignoring: %s" NL,
fn);
283 DEBUGPRINT(
"HID: cannot read keymap user config file (maybe too large file), ignoring: %s" NL,
fn);
286 const char *p = kbdcfg;
287 for (a = 0; key_map[a].
pos >= 0; a++) {
293 p = hid_keymap_add_mapping_from_config_line(p, &
num_of_items);
303 DEBUGPRINT(
"HID: warning, hid_init() was called key_map_in=NULL. This seems to be a FreeBSD specific bug, as far as I can tell from experience." NL);
307 sdl_keyboard_event_cbs[a] = NULL;
308 sdl_textediting_event_cbs[a] = NULL;
309 sdl_textinput_event_cbs[a] = NULL;
311 #ifdef HID_KBD_MAP_CFG_SUPPORT
313 char *kp = kbdcfg + sprintf(kbdcfg,
314 "# default settings for keyboard mapping" NL
315 "# copy this file to filename '%s' in the same directory, and customize (this file is OVERWRITTEN every time, you must copy and customize that one!)" NL
316 "# you can also use the -keymap option of the emulator to specify a keymap file to load (if the specific Xemu emulator supports, use -h to get help)" NL
317 "# Syntax is: EMU-KEY-NAME PC-KEY-NAME" NL
318 "# one assignment per line (EMU-KEY-NAME is always uppercase and one word, while PC-KEY-NAME is case/space/etc sensitive, must be put as is!)" NL
319 "# EMU-KEY-NAME ends in '*' means that it's a virtual key, it is emulated by emulating pressed shift key at the same time" NL
320 "# special line " CLEARALLMAPPING
" can be put to clear all existing mappings, it make sense only as the first statement" NL
321 "# without " CLEARALLMAPPING
", only maps are modified which are part of the keymap config file, the rest is left at their default state" NL
322 "# PC-KEY-NAME Unknown means that the certain feature for the emulated keyboard is not mapped to a PC key" NL
323 "# EMU-KEY-NAME strings starting with XEMU- are special Xemu related 'hot keys'" NL
326 (KEYMAP_USER_FILENAME) + 1
331 FATAL(
"Too long default keymapping table for hid_init()");
332 key_map[a].
pos = key_map_in[a].
pos;
333 key_map[a].
scan = key_map_in[a].
scan;
335 if (key_map[a].
pos < 0) {
336 #ifdef HID_KBD_MAP_CFG_SUPPORT
337 int fd =
xemu_open_file(KEYMAP_DEFAULT_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, NULL, NULL);
343 DEBUGPRINT(
"HID: %d key bindings has been added as the default built-in configuration" NL, a);
346 #ifdef HID_KBD_MAP_CFG_SUPPORT
347 register const char *scan_name = (key_map_in[a].
scan == SDL_SCANCODE_UNKNOWN ? scan_name_unknown : SDL_GetScancodeName(key_map_in[a].
scan));
348 if (scan_name && *scan_name && key_map_in[a].
name && key_map_in[a].
name[0])
349 kp += sprintf(kp,
"%s %s" NL, key_map_in[a].
name, scan_name);
351 DEBUGPRINT(
"HID: skipping keyboard entry on writing default map: scan <%s> name <%s>" NL, scan_name ? scan_name :
"NULL", key_map_in[a].
name ? key_map_in[a].
name :
"NULL");
355 key_map_default = key_map_in;
356 virtual_shift_pos = virtual_shift_pos_in;
357 SDL_GameControllerEventState(SDL_DISABLE);
358 SDL_JoystickEventState(joy_enable);
368 mouse_delta_x += xrel;
369 mouse_delta_y += yrel;
370 DEBUG(
"HID: mouse motion %d:%d, collected data is now %d:%d" NL, xrel, yrel, mouse_delta_x, mouse_delta_y);
377 if (
button == SDL_BUTTON_LEFT)
379 else if (
button == SDL_BUTTON_RIGHT)
395 if (joysticks[which])
397 joysticks[which] = SDL_JoystickOpen(which);
398 if (joysticks[which])
399 DEBUGPRINT(
"HID: joystick device #%d \"%s\" has been added." NL, which, SDL_JoystickName(joysticks[which]));
401 DEBUGPRINT(
"HID: joystick device #%d problem, cannot be opened on 'add' event: %s." NL, which, SDL_GetError());
403 if (joysticks[which]) {
404 SDL_JoystickClose(joysticks[which]);
405 joysticks[which] = NULL;
406 DEBUGPRINT(
"HID: joystick device #%d has been removed." NL, which);
420 else if (
value > 10000)
426 else if (
value > 10000)
444 if (
value & SDL_HAT_UP)
446 if (
value & SDL_HAT_DOWN)
448 if (
value & SDL_HAT_LEFT)
450 if (
value & SDL_HAT_RIGHT)
487 int result = mouse_delta_x;
491 else if (result > max)
499 int result = mouse_delta_y;
503 else if (result > max)
521 #define TRY_CUSTOM_CALLBACKS(cbs,par) do { \
522 for (int i = 0; i < HID_MAX_CUSTOM_CALLBACKS; i++) \
523 if (cbs[i] && !cbs[i](par)) \
531 switch (event->type) {
532 #ifdef CONFIG_DROPFILE_CALLBACK
534 if (event->drop.file && event->drop.file[0]) {
536 SDL_free(event->drop.file);
542 #ifdef CONFIG_QUIT_CALLBACK
551 event->key.keysym.scancode != SDL_SCANCODE_UNKNOWN
552 #ifdef CONFIG_KBD_SELECT_FOCUS
553 && (event->key.windowID ==
sdl_winid || event->key.windowID == 0)
555 #ifdef CONFIG_KBD_AVOID_LALTTAB
559 && !(event->key.keysym.scancode == SDL_SCANCODE_TAB && (event->key.keysym.mod & KMOD_LALT))
565 #ifndef CONFIG_KBD_ALSO_REPEATS
566 if (event->key.repeat == 0)
568 hid_key_event(event->key.keysym.scancode, event->key.state == SDL_PRESSED);
571 case SDL_JOYDEVICEADDED:
572 case SDL_JOYDEVICEREMOVED:
575 case SDL_JOYBUTTONDOWN:
576 case SDL_JOYBUTTONUP:
579 case SDL_JOYHATMOTION:
582 case SDL_JOYAXISMOTION:
583 if (event->jaxis.axis < 2)
586 case SDL_MOUSEMOTION:
590 case SDL_MOUSEBUTTONDOWN:
591 case SDL_MOUSEBUTTONUP:
595 emu_callback_key(-2, 0, event->type == SDL_MOUSEBUTTONDOWN, event->button.button);
597 case SDL_TEXTEDITING:
616 while (SDL_PollEvent(&event) != 0)
623 sdl_keyboard_event_cbs[level] = cb;
628 sdl_textediting_event_cbs[level] = cb;
633 sdl_textinput_event_cbs[level] = cb;