22 #include "../../SDL_internal.h"
24 #include "../linux/SDL_evdev_kbd.h"
27 #ifdef SDL_INPUT_FBSDKBIO
33 #include <sys/ioctl.h>
35 #include <sys/consio.h>
39 #include "../../events/SDL_events_c.h"
52 unsigned long old_kbd_mode;
53 unsigned short **key_maps;
55 keyboard_info_t* kbInfo;
56 unsigned char shift_down[4];
62 unsigned char lockstate;
63 unsigned char ledflagstate;
66 unsigned int text_len;
71 return (ioctl(kbd->keyboard_fd, GIO_KEYMAP, kbd->key_map) >= 0);
75 static int kbd_cleanup_sigactions_installed = 0;
76 static int kbd_cleanup_atexit_installed = 0;
78 static struct sigaction old_sigaction[NSIG];
80 static int fatal_signals[] =
83 SIGHUP, SIGQUIT, SIGILL, SIGABRT,
84 SIGFPE, SIGSEGV, SIGPIPE, SIGBUS,
88 static void kbd_cleanup(
void)
94 kbd_cleanup_state =
NULL;
96 ioctl(kbd->keyboard_fd, KDSKBMODE, kbd->old_kbd_mode);
97 if (kbd->keyboard_fd != kbd->console_fd) close(kbd->keyboard_fd);
98 ioctl(kbd->console_fd, CONS_SETKBD, (
unsigned long)(kbd->kbInfo->kb_index));
102 SDL_EVDEV_kbd_reraise_signal(
int sig)
107 siginfo_t* SDL_EVDEV_kdb_cleanup_siginfo =
NULL;
108 void* SDL_EVDEV_kdb_cleanup_ucontext =
NULL;
110 static void kbd_cleanup_signal_action(
int signum, siginfo_t* info,
void* ucontext)
112 struct sigaction* old_action_p = &(old_sigaction[signum]);
116 sigaction(signum, old_action_p,
NULL);
119 sigemptyset(&sigset);
120 sigaddset(&sigset, signum);
121 sigprocmask(SIG_UNBLOCK, &sigset,
NULL);
124 SDL_EVDEV_kdb_cleanup_siginfo = info;
125 SDL_EVDEV_kdb_cleanup_ucontext = ucontext;
131 SDL_EVDEV_kbd_reraise_signal(signum);
134 static void kbd_unregister_emerg_cleanup()
138 kbd_cleanup_state =
NULL;
140 if (!kbd_cleanup_sigactions_installed) {
143 kbd_cleanup_sigactions_installed = 0;
145 for (tabidx = 0; tabidx <
sizeof(fatal_signals) /
sizeof(fatal_signals[0]); ++tabidx) {
146 struct sigaction* old_action_p;
147 struct sigaction cur_action;
148 signum = fatal_signals[tabidx];
149 old_action_p = &(old_sigaction[signum]);
152 if (sigaction(signum,
NULL, &cur_action))
156 if (!(cur_action.sa_flags & SA_SIGINFO)
157 || cur_action.sa_sigaction != &kbd_cleanup_signal_action)
161 sigaction(signum, old_action_p,
NULL);
165 static void kbd_cleanup_atexit(
void)
171 kbd_unregister_emerg_cleanup();
178 if (kbd_cleanup_state !=
NULL) {
181 kbd_cleanup_state = kbd;
183 if (!kbd_cleanup_atexit_installed) {
188 atexit(kbd_cleanup_atexit);
189 kbd_cleanup_atexit_installed = 1;
192 if (kbd_cleanup_sigactions_installed) {
195 kbd_cleanup_sigactions_installed = 1;
197 for (tabidx = 0; tabidx <
sizeof(fatal_signals) /
sizeof(fatal_signals[0]); ++tabidx) {
198 struct sigaction* old_action_p;
199 struct sigaction new_action;
200 signum = fatal_signals[tabidx];
201 old_action_p = &(old_sigaction[signum]);
202 if (sigaction(signum,
NULL, old_action_p))
208 if ((signum == SIGHUP || signum == SIGPIPE)
209 && (old_action_p->sa_handler != SIG_DFL
210 || (
void (*)(
int))old_action_p->sa_sigaction != SIG_DFL))
213 new_action = *old_action_p;
214 new_action.sa_flags |= SA_SIGINFO;
215 new_action.sa_sigaction = &kbd_cleanup_signal_action;
216 sigaction(signum, &new_action,
NULL);
235 kbd->keyboard_fd = kbd->console_fd = open(
"/dev/tty", O_RDONLY);
237 kbd->shift_state = 0;
239 kbd->accents =
SDL_calloc(
sizeof(accentmap_t), 1);
240 kbd->key_map =
SDL_calloc(
sizeof(keymap_t), 1);
241 kbd->kbInfo =
SDL_calloc(
sizeof(keyboard_info_t), 1);
243 ioctl(kbd->console_fd, KDGKBINFO, kbd->kbInfo);
245 if (ioctl(kbd->console_fd, KDGKBSTATE, &flag_state) == 0) {
246 kbd->ledflagstate = flag_state;
249 if (ioctl(kbd->console_fd, GIO_DEADKEYMAP, kbd->accents) < 0)
255 if (ioctl(kbd->console_fd, KDGKBMODE, &kbd->old_kbd_mode) == 0) {
257 ioctl(kbd->console_fd, KDSKBMODE, (
unsigned long)(K_XLATE));
258 if(!SDL_EVDEV_kbd_load_keymaps(kbd))
264 if (getenv(
"SDL_INPUT_FREEBSD_KEEP_KBD") ==
NULL) {
268 ioctl(kbd->console_fd, CONS_RELKBD, 1ul);
269 asprintf(&devicePath,
"/dev/kbd%d", kbd->kbInfo->kb_index);
270 kbd->keyboard_fd = open(devicePath, O_WRONLY);
271 if (kbd->keyboard_fd == -1)
274 ioctl(kbd->console_fd, CONS_SETKBD, (
unsigned long)(kbd->kbInfo->kb_index));
275 kbd->keyboard_fd = kbd->console_fd;
282 kbd_register_emerg_cleanup(kbd);
286 else kbd->keyboard_fd = kbd->console_fd;
299 kbd_unregister_emerg_cleanup();
301 if (kbd->keyboard_fd >= 0) {
303 ioctl(kbd->keyboard_fd, KDSKBMODE, kbd->old_kbd_mode);
305 close(kbd->keyboard_fd);
306 if (kbd->console_fd != kbd->keyboard_fd && kbd->console_fd >= 0)
309 ioctl(kbd->console_fd, CONS_SETKBD, (
unsigned long)(kbd->kbInfo->kb_index));
311 kbd->console_fd = kbd->keyboard_fd = -1;
323 if (kbd->text_len < (
sizeof(kbd->text)-1)) {
324 kbd->text[kbd->text_len++] = (char)
c;
333 else if (
c < 0x800) {
335 put_queue(kbd, 0xc0 | (
c >> 6));
336 put_queue(kbd, 0x80 | (
c & 0x3f));
337 }
else if (
c < 0x10000) {
338 if (
c >= 0xD800 &&
c < 0xE000)
343 put_queue(kbd, 0xe0 | (
c >> 12));
344 put_queue(kbd, 0x80 | ((
c >> 6) & 0x3f));
345 put_queue(kbd, 0x80 | (
c & 0x3f));
346 }
else if (
c < 0x110000) {
348 put_queue(kbd, 0xf0 | (
c >> 18));
349 put_queue(kbd, 0x80 | ((
c >> 12) & 0x3f));
350 put_queue(kbd, 0x80 | ((
c >> 6) & 0x3f));
351 put_queue(kbd, 0x80 | (
c & 0x3f));
364 unsigned int d = kbd->diacr;
369 for (
i = 0;
i < kbd->accents->n_accs;
i++) {
370 if (kbd->accents->acc[
i].accchar ==
d)
372 for (
j = 0;
j < NUM_ACCENTCHARS; ++
j) {
373 if (kbd->accents->acc[
i].map[
j][0] == 0)
375 if (kbd->accents->acc[
i].map[
j][0] == ch)
376 return kbd->accents->acc[
i].map[
j][1];
381 if (ch ==
' ' || ch ==
d) {
392 return (kbd->ledflagstate & flag) != 0;
397 kbd->ledflagstate ^= flag;
398 ioctl(kbd->keyboard_fd, KDSKBSTATE, (
unsigned long)(kbd->ledflagstate));
413 if (kbd->dead_key_next) {
418 put_utf8(kbd,
value);
426 kbd->diacr = (kbd->diacr ? handle_diacr(kbd,
value) :
value);
431 int old_state = kbd->shift_state;
441 if (kbd->shift_down[
value])
442 kbd->shift_down[
value]--;
444 kbd->shift_down[
value]++;
446 if (kbd->shift_down[
value])
447 kbd->shift_state |= (1 <<
value);
449 kbd->shift_state &= ~(1 <<
value);
452 if (up_flag && kbd->shift_state != old_state && kbd->npadch != -1) {
453 put_utf8(kbd, kbd->npadch);
462 struct keyent_t keysym;
463 unsigned int final_key_state;
464 unsigned int map_from_key_sym;
466 key_map = *kbd->key_map;
472 kbd->rep = (down == 2);
474 if (keycode < NUM_KEYS) {
475 if (keycode >= 89 && keycode <= 95) {
481 if (vc_kbd_led(kbd, ALKED) || (kbd->shift_state & 0x8))
483 keycode += ALTGR_OFFSET;
485 keysym = key_map.key[keycode];
490 final_key_state = kbd->shift_state & 0x7;
491 if ((keysym.flgs & FLAG_LOCK_C) && vc_kbd_led(kbd, LED_CAP))
492 final_key_state ^= 0x1;
493 if ((keysym.flgs & FLAG_LOCK_N) && vc_kbd_led(kbd, LED_NUM))
494 final_key_state ^= 0x1;
496 map_from_key_sym = keysym.map[final_key_state];
497 if ((keysym.spcl & (0x80 >> final_key_state)) || (map_from_key_sym & SPCLKEY)) {
499 if (map_from_key_sym == 0)
501 if (map_from_key_sym & SPCLKEY)
502 map_from_key_sym &= ~SPCLKEY;
503 if (map_from_key_sym >= F_ACC && map_from_key_sym <= L_ACC) {
505 unsigned int accent_index = map_from_key_sym - F_ACC;
506 if (kbd->accents->acc[accent_index].accchar != 0) {
507 k_deadunicode(kbd, kbd->accents->acc[accent_index].accchar, !down);
510 switch(map_from_key_sym) {
512 k_shift(kbd, 3, down == 0);
516 if (down == 0) chg_vc_kbd_led(kbd, ALKED);
519 k_shift(kbd, 0, down == 0);
523 if (down == 0) chg_vc_kbd_led(kbd, ALKED);
526 k_shift(kbd, 1, down == 0);
530 if (down == 0) chg_vc_kbd_led(kbd, ALKED);
533 k_shift(kbd, 2, down == 0);
536 if (down == 1) chg_vc_kbd_led(kbd, ALKED);
539 if (down == 1) chg_vc_kbd_led(kbd, CLKED);
542 if (down == 1) chg_vc_kbd_led(kbd, NLKED);
545 if (down == 1) chg_vc_kbd_led(kbd, SLKED);
552 if (map_from_key_sym ==
'\n' || map_from_key_sym ==
'\r') {
558 if (map_from_key_sym >=
' ' && map_from_key_sym != 127) {
559 k_self(kbd, map_from_key_sym, !down);
563 if (kbd->text_len > 0) {
564 kbd->text[kbd->text_len] =
'\0';
#define SDL_GetHintBoolean
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
SDL_EVDEV_keyboard_state * SDL_EVDEV_kbd_init(void)
void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state)
void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down)
struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state
static keymap_t keymap_default_us_acc
static accentmap_t accentmap_default_us_acc
#define SDL_HINT_NO_SIGNAL_HANDLERS
Tell SDL not to catch the SIGINT or SIGTERM signals.
int SDL_SendKeyboardText(const char *text)
GLsizei const GLfloat * value
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
static char text[MAX_TEXT_LENGTH]
typedef int(__stdcall *FARPROC)()