Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
emutools_hid.c
Go to the documentation of this file.
1 /* Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
2  Copyright (C)2016-2022 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17 
18 #include "xemu/emutools.h"
19 #include "xemu/emutools_hid.h"
20 #ifdef HID_KBD_MAP_CFG_SUPPORT
21 #include "xemu/emutools_files.h"
22 #endif
23 
24 
25 /* Note: HID stands for "Human Input Devices" or something like that :)
26  That is: keyboard, joystick, mouse.
27  TODO: positional mapping stuff for keys _ONLY_
28  TODO: no precise joy emu (multiple joys/axes/buttons/whatsoever)
29  TODO: mouse emulation is unfinished
30 */
31 
32 
33 Uint8 kbd_matrix[16]; // keyboard matrix state, 16 * 8 bits at max currently (not compulsory to use all positions!)
35 int hid_joy_on_cursor_keys = 0; // working mode to have cursor keys as joystick not regular key emu
36 
37 static int mouse_delta_x;
38 static int mouse_delta_y;
39 static unsigned int hid_state;
40 
41 #define MAX_JOYSTICKS 16
42 
43 static SDL_Joystick *joysticks[MAX_JOYSTICKS];
44 
45 #define JOYSTATE_UP 1
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
52 
53 //static const struct KeyMappingUsed *key_map = NULL;
54 static Uint8 virtual_shift_pos = 0;
55 static struct KeyMappingUsed key_map[0x100];
56 static const struct KeyMappingDefault *key_map_default;
57 static int release_this_key_on_first_event = -1;
58 
59 // Custom callbacks
60 #define HID_MAX_CUSTOM_CALLBACKS 3
61 static hid_sdl_keyboard_event_callback_t sdl_keyboard_event_cbs[HID_MAX_CUSTOM_CALLBACKS];
62 static hid_sdl_textediting_event_callback_t sdl_textediting_event_cbs[HID_MAX_CUSTOM_CALLBACKS];
63 static hid_sdl_textinput_event_callback_t sdl_textinput_event_cbs[HID_MAX_CUSTOM_CALLBACKS];
64 
65 
66 void hid_set_autoreleased_key ( int key )
67 {
68  release_this_key_on_first_event = key;
69 }
70 
71 
72 int hid_key_event ( SDL_Scancode key, int pressed )
73 {
74  const struct KeyMappingUsed *map = key_map;
76  OSD(-1, -1, "Key %s <%s>", pressed ? "press " : "release", SDL_GetScancodeName(key));
78  // hid_joy_on_cursor_keys signals a special mode to emulate joystick with cursor-keys if enabled,
79  // instead of the normal functionality of those keys. Right-CTRL is fire.
80  int sel;
81  switch (key) {
82  case SDL_SCANCODE_UP: sel = JOYSTATE_UP; break;
83  case SDL_SCANCODE_DOWN: sel = JOYSTATE_DOWN; break;
84  case SDL_SCANCODE_LEFT: sel = JOYSTATE_LEFT; break;
85  case SDL_SCANCODE_RIGHT:sel = JOYSTATE_RIGHT; break;
86  case SDL_SCANCODE_RGUI: // Mac does not seem to have right CTRL. Use this too, right-GUI key is right-command (or right-windows key on PC or wtf ...)
87  case SDL_SCANCODE_RCTRL:sel = JOYSTATE_BUTTON; break;
88  default: sel = -1; break;
89  }
90  if (sel >= 0) {
91  if (pressed)
92  hid_state |= sel;
93  else
94  hid_state &= ~sel;
95  return 1;
96  }
97  }
98  while (map->pos >= 0) {
99  if (map->scan == key) {
100  if (XEMU_UNLIKELY(release_this_key_on_first_event > 0)) {
101  KBD_RELEASE_KEY(release_this_key_on_first_event);
102  release_this_key_on_first_event = -1;
103  }
104  if (map->pos > 0xFF) { // special emulator key!
105  switch (map->pos) { // handle "built-in" events, if emulator target uses them at all ...
106  case XEMU_EVENT_EXIT:
108  exit(0);
109  break;
111  if (pressed) hid_state |= JOYSTATE_UP; else hid_state &= ~JOYSTATE_UP;
112  break;
114  if (pressed) hid_state |= JOYSTATE_DOWN; else hid_state &= ~JOYSTATE_DOWN;
115  break;
117  if (pressed) hid_state |= JOYSTATE_LEFT; else hid_state &= ~JOYSTATE_LEFT;
118  break;
120  if (pressed) hid_state |= JOYSTATE_RIGHT; else hid_state &= ~JOYSTATE_RIGHT;
121  break;
123  if (pressed) hid_state |= JOYSTATE_BUTTON; else hid_state &= ~JOYSTATE_BUTTON;
124  break;
126  if (pressed)
128  break;
129  default:
130  return emu_callback_key(map->pos, key, pressed, 0);
131  }
132  return emu_callback_key(map->pos, key, pressed, 1);
133  }
134  if (map->pos & 8) // shifted key emu?
135  KBD_SET_KEY(virtual_shift_pos, pressed); // maintain the shift key
136  KBD_SET_KEY(map->pos, pressed);
137  return emu_callback_key(map->pos, key, pressed, 1);
138  }
139  map++;
140  }
141  return emu_callback_key(-1, key, pressed, 0);
142 }
143 
144 
145 void hid_sdl_synth_key_event ( int matrix_pos, int is_press )
146 {
147  const struct KeyMappingUsed *map = key_map;
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;
153  sdlevent.key.windowID = sdl_winid;
154  sdlevent.key.state = is_press ? SDL_PRESSED : SDL_RELEASED;
155  sdlevent.key.keysym.scancode = map->scan;
156  SDL_PushEvent(&sdlevent);
157  return;
158  }
159  map++;
160  }
161 }
162 
163 
164 
165 // Reset all HID events.
166 // Ie: it's usefull for initialization, and in the case when the emulator pops a window,
167 // in this case SDL may detect the event used to ack the window causing problems. So those
168 // functions should call this as well to reset events. It also uses some "burning SDL
169 // events" scheme to skip the possible received stuffs.
170 void hid_reset_events ( int burn )
171 {
172  KBD_CLEAR_MATRIX(); // set keyboard matrix to default state (unpressed for all positions)
173  mouse_delta_x = 0;
174  mouse_delta_y = 0;
175  hid_state = 0;
176  if (burn)
178 }
179 
180 
181 #ifdef HID_KBD_MAP_CFG_SUPPORT
182 
183 #define CLEARALLMAPPING "CLEARALLMAPPING"
184 
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";
187 
188 static const char *scan_name_unknown = "Unknown";
189 
190 const char *hid_keymap_add_mapping ( const char *emu_key_name, const char *host_key_name )
191 {
192  SDL_Scancode scan;
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;
197  } else
198  scan = SDL_SCANCODE_UNKNOWN;
199  // Look up matrix position from the default mapping given to hid_init() which also carries the "emu key names"
200  int pos;
201  int source;
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))) {
206  //DEBUGPRINT("FOUND KEY: %s for %s" NL, key_map_default[source].name, emu_key_name);
207  pos = key_map_default[source].pos;
208  break;
209  }
210  }
211  // At this point we have the SDL scancode, and the "matrix position" ...
212  // We change all mappings' scan code to the desired ones (maybe more PC keys is mapped to a single emulated key!)
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
218  );
219  }
220  key_map[a].scan = scan;
221  key_map[a].set = source;
222  break;
223  }
224  }
225  return NULL;
226 }
227 
228 
229 const char *hid_keymap_add_mapping_from_config_line ( const char *p, int *num_of_items )
230 {
231  char emu_name[64], host_name[64];
232  while (*p <= 0x20 && *p)
233  p++;
234  if (*p == '\0' || *p == '#')
235  goto skip_rest;
236  const char *emu_p = p;
237  while (*p > 32)
238  p++;
239  if (*p == '\0' || *p == '#' || p - emu_p >= sizeof(emu_name))
240  goto skip_rest;
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++) {
245  key_map[a].set = -2;
246  key_map[a].scan = 0;
247  }
248  goto skip_rest;
249  }
250  while (*p <= 32 && *p)
251  p++;
252  if (*p == 0 || *p == '#')
253  goto skip_rest;
254  const char *host_p = p;
255  while (*p && *p != 13 && *p != 10 && *p != '#')
256  p++;
257  //p--;
258  while (p[-1] <= 0x20 && p > host_p)
259  p--;
260  if (p - host_p >= sizeof(host_name))
261  goto skip_rest;
262  memcpy(host_name, host_p, p - host_p);
263  host_name[p - host_p] = 0;
264  const char *res = hid_keymap_add_mapping(emu_name, host_name);
265  if (res)
266  DEBUGPRINT("HID: error on keymap user config: emu_name=[%s] host_key=<%s>: %s\n", emu_name, host_name, res);
267  else
268  (*num_of_items)++;
269 skip_rest:
270  while (*p != 10 && *p != 13 && *p)
271  p++;
272  return p;
273 }
274 
275 
276 void hid_keymap_from_config_file ( const char *fn )
277 {
278  char kbdcfg[8192];
279  int a = xemu_load_file(fn, kbdcfg, 1, sizeof(kbdcfg) - 1, NULL);
280  if (a == -1)
281  DEBUGPRINT("HID: cannot open keymap user config file (maybe does not exist), ignoring: %s" NL, fn);
282  else if (a < 1)
283  DEBUGPRINT("HID: cannot read keymap user config file (maybe too large file), ignoring: %s" NL, fn);
284  else {
285  kbdcfg[a] = 0;
286  const char *p = kbdcfg;
287  for (a = 0; key_map[a].pos >= 0; a++) {
288  key_map[a].set = -1;
289  //key_map[a].scan = 0;
290  }
291  int num_of_items = 0;
292  while (*p) {
293  p = hid_keymap_add_mapping_from_config_line(p, &num_of_items);
294  }
295  DEBUGPRINT("HID: keymap configuration from file %s has been processed (%d successfull mappings)." NL, fn, num_of_items);
296  }
297 }
298 #endif
299 
300 void hid_init ( const struct KeyMappingDefault *key_map_in, Uint8 virtual_shift_pos_in, int joy_enable )
301 {
302  if (!key_map_in) {
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);
304  return;
305  }
306  for (int a = 0; a < HID_MAX_CUSTOM_CALLBACKS; a++) {
307  sdl_keyboard_event_cbs[a] = NULL;
308  sdl_textediting_event_cbs[a] = NULL;
309  sdl_textinput_event_cbs[a] = NULL;
310  }
311 #ifdef HID_KBD_MAP_CFG_SUPPORT
312  char kbdcfg[8192];
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
324  NL
325  ,
326  (KEYMAP_USER_FILENAME) + 1
327  );
328 #endif
329  for (int a = 0;;) {
330  if (a >= 0x100)
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;
334  key_map[a].set = 0;
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);
338  if (fd >= 0) {
339  xemu_safe_write(fd, kbdcfg, kp - kbdcfg);
340  close(fd);
341  }
342 #endif
343  DEBUGPRINT("HID: %d key bindings has been added as the default built-in configuration" NL, a);
344  break;
345  }
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);
350  else
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");
352 #endif
353  a++;
354  }
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);
359  hid_reset_events(0);
360  for (int a = 0; a < MAX_JOYSTICKS; a++)
361  joysticks[a] = NULL;
362 }
363 
364 
365 
366 void hid_mouse_motion_event ( int xrel, int yrel )
367 {
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);
371 }
372 
373 
374 void hid_mouse_button_event ( int button, int pressed )
375 {
376  int mask;
377  if (button == SDL_BUTTON_LEFT)
379  else if (button == SDL_BUTTON_RIGHT)
381  else
382  return;
383  if (pressed)
384  hid_state |= mask;
385  else
386  hid_state &= ~mask;
387 }
388 
389 
390 void hid_joystick_device_event ( int which , int is_attach )
391 {
392  if (which >= MAX_JOYSTICKS)
393  return;
394  if (is_attach) {
395  if (joysticks[which])
396  hid_joystick_device_event(which, 0);
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]));
400  else
401  DEBUGPRINT("HID: joystick device #%d problem, cannot be opened on 'add' event: %s." NL, which, SDL_GetError());
402  } else {
403  if (joysticks[which]) {
404  SDL_JoystickClose(joysticks[which]);
405  joysticks[which] = NULL;
406  DEBUGPRINT("HID: joystick device #%d has been removed." NL, which);
407  // This is needed to avoid "stuck" joystick state if removed in that state ...
409  }
410  }
411 }
412 
413 
414 void hid_joystick_motion_event ( int is_vertical, int value )
415 {
416  if (is_vertical) {
417  hid_state &= ~(JOYSTATE_UP | JOYSTATE_DOWN);
418  if (value < -10000)
419  hid_state |= JOYSTATE_UP;
420  else if (value > 10000)
421  hid_state |= JOYSTATE_DOWN;
422  } else {
423  hid_state &= ~(JOYSTATE_LEFT | JOYSTATE_RIGHT);
424  if (value < -10000)
425  hid_state |= JOYSTATE_LEFT;
426  else if (value > 10000)
427  hid_state |= JOYSTATE_RIGHT;
428  }
429 }
430 
431 
432 void hid_joystick_button_event ( int pressed )
433 {
434  if (pressed)
435  hid_state |= JOYSTATE_BUTTON;
436  else
437  hid_state &= ~JOYSTATE_BUTTON;
438 }
439 
440 
442 {
444  if (value & SDL_HAT_UP)
445  hid_state |= JOYSTATE_UP;
446  if (value & SDL_HAT_DOWN)
447  hid_state |= JOYSTATE_DOWN;
448  if (value & SDL_HAT_LEFT)
449  hid_state |= JOYSTATE_LEFT;
450  if (value & SDL_HAT_RIGHT)
451  hid_state |= JOYSTATE_RIGHT;
452 }
453 
454 
455 int hid_read_joystick_up ( int on, int off )
456 {
457  return (hid_state & JOYSTATE_UP) ? on : off;
458 }
459 
460 
461 int hid_read_joystick_down ( int on, int off )
462 {
463  return (hid_state & JOYSTATE_DOWN) ? on : off;
464 }
465 
466 
467 int hid_read_joystick_left ( int on, int off )
468 {
469  return (hid_state & JOYSTATE_LEFT) ? on : off;
470 }
471 
472 
473 int hid_read_joystick_right ( int on, int off )
474 {
475  return (hid_state & JOYSTATE_RIGHT) ? on : off;
476 }
477 
478 
479 int hid_read_joystick_button ( int on, int off )
480 {
481  return (hid_state & JOYSTATE_BUTTON) ? on : off;
482 }
483 
484 
485 int hid_read_mouse_rel_x ( int min, int max )
486 {
487  int result = mouse_delta_x;
488  mouse_delta_x = 0;
489  if (result < min)
490  result = min;
491  else if (result > max)
492  result = max;
493  return result;
494 }
495 
496 
497 int hid_read_mouse_rel_y ( int min, int max )
498 {
499  int result = mouse_delta_y;
500  mouse_delta_y = 0;
501  if (result < min)
502  result = min;
503  else if (result > max)
504  result = max;
505  return result;
506 }
507 
508 
509 int hid_read_mouse_button_left ( int on, int off )
510 {
511  return (hid_state & MOUSESTATE_BUTTON_LEFT) ? on : off;
512 }
513 
514 
515 int hid_read_mouse_button_right ( int on, int off )
516 {
517  return (hid_state & MOUSESTATE_BUTTON_RIGHT) ? on : off;
518 }
519 
520 
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)) \
524  goto give_up; \
525 } while(0)
526 
527 
528 int hid_handle_one_sdl_event ( SDL_Event *event )
529 {
530  int handled = 1;
531  switch (event->type) {
532 #ifdef CONFIG_DROPFILE_CALLBACK
533  case SDL_DROPFILE:
534  if (event->drop.file && event->drop.file[0]) {
535  emu_dropfile_callback(event->drop.file);
536  SDL_free(event->drop.file);
537  }
538  break;
539 #endif
540  case SDL_QUIT:
542 #ifdef CONFIG_QUIT_CALLBACK
544 #endif
545  exit(0);
546  }
547  break;
548  case SDL_KEYUP:
549  case SDL_KEYDOWN:
550  if (
551  event->key.keysym.scancode != SDL_SCANCODE_UNKNOWN
552 #ifdef CONFIG_KBD_SELECT_FOCUS
553  && (event->key.windowID == sdl_winid || event->key.windowID == 0)
554 #endif
555 #ifdef CONFIG_KBD_AVOID_LALTTAB
556  /* ALT-TAB is usually used by the OS, and it can be ignored to "leak" this event into Xemu
557  * so if it's requested, we filter out. NOTE: it's only for LALT (left ALT), right ALT maybe
558  * used for other emulation purposes ... */
559  && !(event->key.keysym.scancode == SDL_SCANCODE_TAB && (event->key.keysym.mod & KMOD_LALT))
560 #endif
561  ) {
562  // Note: if this one is requested, it is fired even on key repeats, while the normal
563  // HID callback may NOT!
564  TRY_CUSTOM_CALLBACKS(sdl_keyboard_event_cbs, &event->key);
565 #ifndef CONFIG_KBD_ALSO_REPEATS
566  if (event->key.repeat == 0)
567 #endif
568  hid_key_event(event->key.keysym.scancode, event->key.state == SDL_PRESSED);
569  }
570  break;
571  case SDL_JOYDEVICEADDED:
572  case SDL_JOYDEVICEREMOVED:
573  hid_joystick_device_event(event->jdevice.which, event->type == SDL_JOYDEVICEADDED);
574  break;
575  case SDL_JOYBUTTONDOWN:
576  case SDL_JOYBUTTONUP:
577  hid_joystick_button_event(event->type == SDL_JOYBUTTONDOWN);
578  break;
579  case SDL_JOYHATMOTION:
580  hid_joystick_hat_event(event->jhat.value);
581  break;
582  case SDL_JOYAXISMOTION:
583  if (event->jaxis.axis < 2)
584  hid_joystick_motion_event(event->jaxis.axis, event->jaxis.value);
585  break;
586  case SDL_MOUSEMOTION:
587  if (is_mouse_grab())
588  hid_mouse_motion_event(event->motion.xrel, event->motion.yrel);
589  break;
590  case SDL_MOUSEBUTTONDOWN:
591  case SDL_MOUSEBUTTONUP:
592  if (is_mouse_grab())
593  hid_mouse_button_event(event->button.button, event->type == SDL_MOUSEBUTTONDOWN);
594  else
595  emu_callback_key(-2, 0, event->type == SDL_MOUSEBUTTONDOWN, event->button.button);
596  break;
597  case SDL_TEXTEDITING:
598  TRY_CUSTOM_CALLBACKS(sdl_textediting_event_cbs, &event->edit);
599  break;
600  case SDL_TEXTINPUT:
601  TRY_CUSTOM_CALLBACKS(sdl_textinput_event_cbs, &event->text);
602  break;
603  default:
604  handled = 0;
605  break;
606  }
607 give_up:
608  return handled;
609 }
610 
611 
612 // For simple emulators it's even enough to call regularly this function for all HID stuffs!
614 {
615  SDL_Event event;
616  while (SDL_PollEvent(&event) != 0)
617  hid_handle_one_sdl_event(&event);
618 }
619 
620 
622 {
623  sdl_keyboard_event_cbs[level] = cb;
624 }
625 
627 {
628  sdl_textediting_event_cbs[level] = cb;
629 }
630 
632 {
633  sdl_textinput_event_cbs[level] = cb;
634 }
XEMU_EVENT_FAKE_JOY_LEFT
#define XEMU_EVENT_FAKE_JOY_LEFT
Definition: emutools_hid.h:103
KeyMappingUsed::scan
SDL_Scancode scan
Definition: emutools_hid.h:30
XEMU_EVENT_TOGGLE_FULLSCREEN
#define XEMU_EVENT_TOGGLE_FULLSCREEN
Definition: emutools_hid.h:106
hid_read_joystick_down
int hid_read_joystick_down(int on, int off)
Definition: emutools_hid.c:461
emutools.h
xemu_open_file
int xemu_open_file(const char *filename, int mode, int *mode2, char *filepath_back)
Definition: emutools_files.c:469
JOYSTATE_UP
#define JOYSTATE_UP
Definition: emutools_hid.c:45
hid_read_mouse_button_right
int hid_read_mouse_button_right(int on, int off)
Definition: emutools_hid.c:515
hid_read_mouse_rel_x
int hid_read_mouse_rel_x(int min, int max)
Definition: emutools_hid.c:485
XEMU_EVENT_FAKE_JOY_DOWN
#define XEMU_EVENT_FAKE_JOY_DOWN
Definition: emutools_hid.h:102
fd
int fd
Definition: hdos.c:62
hid_sdl_textediting_event_callback_t
int(* hid_sdl_textediting_event_callback_t)(SDL_TextEditingEvent *)
Definition: emutools_hid.h:64
hid_read_mouse_button_left
int hid_read_mouse_button_left(int on, int off)
Definition: emutools_hid.c:509
i_am_sure_override
int i_am_sure_override
Definition: emutools.c:74
KBD_CLEAR_MATRIX
#define KBD_CLEAR_MATRIX()
Definition: emutools_hid.h:45
hid_sdl_textinput_event_callback_t
int(* hid_sdl_textinput_event_callback_t)(SDL_TextInputEvent *)
Definition: emutools_hid.h:65
is_mouse_grab
SDL_bool is_mouse_grab(void)
Definition: emutools.c:145
hid_show_osd_keys
int hid_show_osd_keys
Definition: emutools_hid.c:34
hid_read_mouse_rel_y
int hid_read_mouse_rel_y(int min, int max)
Definition: emutools_hid.c:497
MOUSESTATE_BUTTON_RIGHT
#define MOUSESTATE_BUTTON_RIGHT
Definition: emutools_hid.c:51
emu_callback_key
int emu_callback_key(int pos, SDL_Scancode key, int pressed, int handled)
Definition: commodore_65.c:807
fn
const char * fn
Definition: roms.c:42
MOUSESTATE_BUTTON_LEFT
#define MOUSESTATE_BUTTON_LEFT
Definition: emutools_hid.c:50
hid_handle_all_sdl_events
void hid_handle_all_sdl_events(void)
Definition: emutools_hid.c:613
xemu_drop_events
#define xemu_drop_events
Definition: gui.c:19
hid_read_joystick_left
int hid_read_joystick_left(int on, int off)
Definition: emutools_hid.c:467
hid_init
void hid_init(const struct KeyMappingDefault *key_map_in, Uint8 virtual_shift_pos_in, int joy_enable)
Definition: emutools_hid.c:300
hid_reset_events
void hid_reset_events(int burn)
Definition: emutools_hid.c:170
Uint8
uint8_t Uint8
Definition: fat32.c:51
xemu_set_full_screen
void xemu_set_full_screen(int setting)
Definition: emutools.c:311
hid_sdl_synth_key_event
void hid_sdl_synth_key_event(int matrix_pos, int is_press)
Definition: emutools_hid.c:145
hid_sdl_keyboard_event_callback_t
int(* hid_sdl_keyboard_event_callback_t)(SDL_KeyboardEvent *)
Definition: emutools_hid.h:63
JOYSTATE_BUTTON
#define JOYSTATE_BUTTON
Definition: emutools_hid.c:49
XEMU_EVENT_FAKE_JOY_UP
#define XEMU_EVENT_FAKE_JOY_UP
Definition: emutools_hid.h:101
hid_mouse_button_event
void hid_mouse_button_event(int button, int pressed)
Definition: emutools_hid.c:374
emutools_files.h
num_of_items
int num_of_items
Definition: gui_win.c:31
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
kbd_matrix
Uint8 kbd_matrix[16]
Definition: emutools_hid.c:33
hid_mouse_motion_event
void hid_mouse_motion_event(int xrel, int yrel)
Definition: emutools_hid.c:366
KeyMappingDefault::scan
SDL_Scancode scan
Definition: emutools_hid.h:25
hid_joystick_button_event
void hid_joystick_button_event(int pressed)
Definition: emutools_hid.c:432
hid_key_event
int hid_key_event(SDL_Scancode key, int pressed)
Definition: emutools_hid.c:72
XEMU_EVENT_FAKE_JOY_RIGHT
#define XEMU_EVENT_FAKE_JOY_RIGHT
Definition: emutools_hid.h:104
KBD_SET_KEY
#define KBD_SET_KEY(a, state)
Definition: emutools_hid.h:48
hid_register_sdl_textinput_event_callback
void hid_register_sdl_textinput_event_callback(const unsigned int level, hid_sdl_textinput_event_callback_t cb)
Definition: emutools_hid.c:631
NL
#define NL
Definition: fat32.c:37
hid_joy_on_cursor_keys
int hid_joy_on_cursor_keys
Definition: emutools_hid.c:35
KeyMappingDefault
Definition: emutools_hid.h:24
xemu_load_file
int xemu_load_file(const char *filename, void *store_to, int min_size, int max_size, const char *cry)
Definition: emutools_files.c:674
HID_MAX_CUSTOM_CALLBACKS
#define HID_MAX_CUSTOM_CALLBACKS
Definition: emutools_hid.c:60
TRY_CUSTOM_CALLBACKS
#define TRY_CUSTOM_CALLBACKS(cbs, par)
Definition: emutools_hid.c:521
hid_joystick_motion_event
void hid_joystick_motion_event(int is_vertical, int value)
Definition: emutools_hid.c:414
host_name
char host_name[13]
Definition: cpmfs.c:37
ARE_YOU_SURE_DEFAULT_YES
#define ARE_YOU_SURE_DEFAULT_YES
Definition: emutools.h:125
hid_set_autoreleased_key
void hid_set_autoreleased_key(int key)
Definition: emutools_hid.c:66
hid_joystick_device_event
void hid_joystick_device_event(int which, int is_attach)
Definition: emutools_hid.c:390
KeyMappingUsed::pos
int pos
Definition: emutools_hid.h:31
emu_dropfile_callback
void emu_dropfile_callback(const char *fn)
Definition: primo.c:675
JOYSTATE_LEFT
#define JOYSTATE_LEFT
Definition: emutools_hid.c:47
ARE_YOU_SURE
int ARE_YOU_SURE(const char *s, int flags)
Definition: emutools.c:1202
emu_quit_callback
void emu_quit_callback(void)
Definition: primo.c:483
KBD_RELEASE_KEY
#define KBD_RELEASE_KEY(a)
Definition: emutools_hid.h:47
hid_read_joystick_button
int hid_read_joystick_button(int on, int off)
Definition: emutools_hid.c:479
hid_read_joystick_up
int hid_read_joystick_up(int on, int off)
Definition: emutools_hid.c:455
OSD
#define OSD(...)
Definition: xep128.h:100
JOYSTATE_RIGHT
#define JOYSTATE_RIGHT
Definition: emutools_hid.c:48
hid_joystick_hat_event
void hid_joystick_hat_event(int value)
Definition: emutools_hid.c:441
hid_register_sdl_textediting_event_callback
void hid_register_sdl_textediting_event_callback(const unsigned int level, hid_sdl_textediting_event_callback_t cb)
Definition: emutools_hid.c:626
str_are_you_sure_to_exit
const char * str_are_you_sure_to_exit
Definition: emutools.c:75
mask
int mask
Definition: dma65.c:83
XEMU_EVENT_EXIT
#define XEMU_EVENT_EXIT
Definition: emutools_hid.h:100
value
int value
Definition: dma65.c:90
emutools_hid.h
name
const char * name
Definition: joystick.c:46
hid_register_sdl_keyboard_event_callback
void hid_register_sdl_keyboard_event_callback(const unsigned int level, hid_sdl_keyboard_event_callback_t cb)
Definition: emutools_hid.c:621
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
hid_handle_one_sdl_event
int hid_handle_one_sdl_event(SDL_Event *event)
Definition: emutools_hid.c:528
xemu_safe_write
ssize_t xemu_safe_write(int fd, const void *buffer, size_t length)
Definition: emutools_files.c:563
FATAL
#define FATAL(...)
Definition: xep128.h:117
KeyMappingUsed::set
int set
Definition: emutools_hid.h:32
KeyMappingDefault::pos
int pos
Definition: emutools_hid.h:26
button
Uint32 button
Definition: joystick.c:43
MAX_JOYSTICKS
#define MAX_JOYSTICKS
Definition: emutools_hid.c:41
JOYSTATE_DOWN
#define JOYSTATE_DOWN
Definition: emutools_hid.c:46
KeyMappingUsed
Definition: emutools_hid.h:29
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
hid_read_joystick_right
int hid_read_joystick_right(int on, int off)
Definition: emutools_hid.c:473
sdl_winid
Uint32 sdl_winid
Definition: screen.c:49
XEMU_EVENT_FAKE_JOY_FIRE
#define XEMU_EVENT_FAKE_JOY_FIRE
Definition: emutools_hid.h:105