21 #include "../../SDL_internal.h" 25 #ifdef SDL_INPUT_LINUXKD 31 #include <sys/ioctl.h> 33 #include <linux/keyboard.h> 35 #include <linux/tiocl.h> 37 #include "../../events/SDL_events_c.h" 43 #define K_UNICODE 0x03 54 k_self, k_fn, k_spec, k_pad,\ 55 k_dead, k_cons, k_cur, k_shift,\ 56 k_meta, k_ascii, k_lock, k_lowercase,\ 57 k_slock, k_dead2, k_brl, k_ignore 60 static k_handler_fn K_HANDLERS;
61 static k_handler_fn *k_handler[16] = { K_HANDLERS };
70 static fn_handler_fn *fn_handler[] =
88 unsigned short **key_maps;
89 unsigned char shift_down[NR_SHIFT];
92 struct kbdiacrs *accents;
95 unsigned char lockstate;
96 unsigned char slockstate;
97 unsigned char ledflagstate;
100 unsigned int text_len;
108 printf(
"static struct kbdiacrs default_accents = {\n");
109 printf(
" %d,\n", kbd->accents->kb_cnt);
111 for (i = 0; i < kbd->accents->kb_cnt; ++
i) {
112 struct kbdiacr *diacr = &kbd->accents->kbdiacr[
i];
113 printf(
" { 0x%.2x, 0x%.2x, 0x%.2x },\n",
114 diacr->diacr, diacr->base, diacr->result);
117 printf(
" { 0x00, 0x00, 0x00 },\n");
130 for (i = 0; i < MAX_NR_KEYMAPS; ++
i) {
131 if (kbd->key_maps[i]) {
132 printf(
"static unsigned short default_key_map_%d[NR_KEYS] = {", i);
133 for (j = 0; j < NR_KEYS; ++
j) {
137 printf(
"0x%.4x, ", kbd->key_maps[i][j]);
143 printf(
"static unsigned short *default_key_maps[MAX_NR_KEYMAPS] = {\n");
144 for (i = 0; i < MAX_NR_KEYMAPS; ++
i) {
145 if (kbd->key_maps[i]) {
146 printf(
" default_key_map_%d,\n", i);
159 kbd->key_maps = (
unsigned short **)
SDL_calloc(MAX_NR_KEYMAPS,
sizeof(
unsigned short *));
160 if (!kbd->key_maps) {
164 for (i = 0; i < MAX_NR_KEYMAPS; ++
i) {
169 if (ioctl(kbd->console_fd, KDGKBENT, &kbe) < 0) {
173 if (kbe.kb_value == K_NOSUCHMAP) {
177 kbd->key_maps[
i] = (
unsigned short *)
SDL_malloc(NR_KEYS *
sizeof(
unsigned short));
178 if (!kbd->key_maps[i]) {
182 for (j = 0; j < NR_KEYS; ++
j) {
185 if (ioctl(kbd->console_fd, KDGKBENT, &kbe) < 0) {
188 kbd->key_maps[
i][
j] = (kbe.kb_value ^ 0xf000);
200 char shift_state[2] = {TIOCL_GETSHIFTSTATE, 0};
210 kbd->console_fd = open(
"/dev/tty", O_RDONLY);
212 if (ioctl(kbd->console_fd, TIOCLINUX, shift_state) == 0) {
213 kbd->shift_state = *shift_state;
216 if (ioctl(kbd->console_fd, KDGKBLED, &flag_state) == 0) {
217 kbd->ledflagstate = flag_state;
221 if (ioctl(kbd->console_fd, KDGKBDIACR, kbd->accents) < 0) {
226 if (ioctl(kbd->console_fd, KDGKBMODE, &kbd->old_kbd_mode) == 0) {
228 ioctl(kbd->console_fd, KDSKBMODE, K_UNICODE);
230 if (SDL_EVDEV_kbd_load_keymaps(kbd) < 0) {
231 for (i = 0; i < MAX_NR_KEYMAPS; ++
i) {
232 if (kbd->key_maps[i]) {
244 ioctl(kbd->console_fd, KDSKBMODE, K_OFF);
248 SDL_EVDEV_dump_accents(kbd);
251 SDL_EVDEV_dump_keymap(kbd);
263 if (kbd->console_fd >= 0) {
265 ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode);
267 close(kbd->console_fd);
268 kbd->console_fd = -1;
273 for (i = 0; i < MAX_NR_KEYMAPS; ++
i) {
274 if (kbd->key_maps[i]) {
290 if (kbd->text_len < (
sizeof(kbd->text)-1)) {
291 kbd->text[kbd->text_len++] = (char)c;
300 else if (c < 0x800) {
302 put_queue(kbd, 0xc0 | (c >> 6));
303 put_queue(kbd, 0x80 | (c & 0x3f));
304 }
else if (c < 0x10000) {
305 if (c >= 0xD800 && c < 0xE000)
310 put_queue(kbd, 0xe0 | (c >> 12));
311 put_queue(kbd, 0x80 | ((c >> 6) & 0x3f));
312 put_queue(kbd, 0x80 | (c & 0x3f));
313 }
else if (c < 0x110000) {
315 put_queue(kbd, 0xf0 | (c >> 18));
316 put_queue(kbd, 0x80 | ((c >> 12) & 0x3f));
317 put_queue(kbd, 0x80 | ((c >> 6) & 0x3f));
318 put_queue(kbd, 0x80 | (c & 0x3f));
331 unsigned int d = kbd->diacr;
336 for (i = 0; i < kbd->accents->kb_cnt; i++) {
337 if (kbd->accents->kbdiacr[i].diacr == d &&
338 kbd->accents->kbdiacr[i].base == ch) {
339 return kbd->accents->kbdiacr[
i].result;
343 if (ch ==
' ' || ch == d)
353 return ((kbd->ledflagstate >> flag) & 1);
358 kbd->ledflagstate |= 1 << flag;
363 kbd->ledflagstate &= ~(1 << flag);
368 kbd->lockstate ^= 1 << flag;
373 kbd->slockstate ^= 1 << flag;
378 kbd->ledflagstate ^= 1 << flag;
388 put_utf8(kbd, kbd->diacr);
398 chg_vc_kbd_led(kbd, K_CAPSLOCK);
406 set_vc_kbd_led(kbd, K_CAPSLOCK);
412 chg_vc_kbd_led(kbd, K_NUMLOCK);
434 if (fn_handler[value])
435 fn_handler[
value](kbd);
448 value = handle_diacr(kbd, value);
450 if (kbd->dead_key_next) {
455 put_utf8(kbd, value);
463 kbd->diacr = (kbd->diacr ? handle_diacr(kbd, value) : value);
468 const unsigned char ret_diacr[NR_DEAD] = {
'`',
'\'',
'^',
'~',
'"',
',' };
470 k_deadunicode(kbd, ret_diacr[value], up_flag);
475 k_deadunicode(kbd, value, up_flag);
492 static const char pad_chars[] =
"0123456789+-*/\015,.?()#";
497 if (!vc_kbd_led(kbd, K_NUMLOCK)) {
502 put_queue(kbd, pad_chars[value]);
507 int old_state = kbd->shift_state;
515 if (value == KVAL(K_CAPSSHIFT)) {
516 value = KVAL(K_SHIFT);
518 clr_vc_kbd_led(kbd, K_CAPSLOCK);
526 if (kbd->shift_down[value])
527 kbd->shift_down[
value]--;
529 kbd->shift_down[
value]++;
531 if (kbd->shift_down[value])
532 kbd->shift_state |= (1 <<
value);
534 kbd->shift_state &= ~(1 <<
value);
537 if (up_flag && kbd->shift_state != old_state && kbd->npadch != -1) {
538 put_utf8(kbd, kbd->npadch);
563 if (kbd->npadch == -1)
566 kbd->npadch = kbd->npadch * base +
value;
571 if (up_flag || kbd->rep)
574 chg_vc_kbd_lock(kbd, value);
579 k_shift(kbd, value, up_flag);
580 if (up_flag || kbd->rep)
583 chg_vc_kbd_slock(kbd, value);
585 if (!kbd->key_maps[kbd->lockstate ^ kbd->slockstate]) {
587 chg_vc_kbd_slock(kbd, value);
598 unsigned char shift_final;
600 unsigned short *key_map;
601 unsigned short keysym;
607 kbd->rep = (down == 2);
609 shift_final = (kbd->shift_state | kbd->slockstate) ^ kbd->lockstate;
610 key_map = kbd->key_maps[shift_final];
616 if (keycode < NR_KEYS) {
617 keysym = key_map[keycode];
626 put_utf8(kbd, keysym);
632 if (type == KT_LETTER) {
635 if (vc_kbd_led(kbd, K_CAPSLOCK)) {
636 key_map = kbd->key_maps[shift_final ^ (1 << KG_SHIFT)];
638 keysym = key_map[keycode];
643 (*k_handler[
type])(kbd, keysym & 0xff, !down);
645 if (type != KT_SLOCK) {
650 if (kbd->text_len > 0) {
651 kbd->text[kbd->text_len] =
'\0';
static struct kbdiacrs default_accents
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
void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state)
int SDL_SendKeyboardText(const char *text)
void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down)
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)
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)
SDL_EVDEV_keyboard_state * SDL_EVDEV_kbd_init(void)
static char text[MAX_TEXT_LENGTH]
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
static unsigned short * default_key_maps[MAX_NR_KEYMAPS]
GLuint GLuint GLsizei GLenum type
#define SDL_arraysize(array)
struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state