21 #include "../../SDL_internal.h" 23 #ifdef SDL_INPUT_LINUXEV 34 #define _THIS SDL_EVDEV_PrivateData *_this 40 #include <sys/ioctl.h> 42 #include <linux/input.h> 43 #ifdef SDL_INPUT_LINUXKD 45 #include <linux/keyboard.h> 51 #define KDSKBMUTE 0x4B51 54 #define KDSKBMODE 0x4B45 63 #include "../../core/linux/SDL_udev.h" 65 #include "../../events/SDL_events_c.h" 72 static SDL_Scancode SDL_EVDEV_translate_keycode(
int keycode);
73 static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item);
74 static int SDL_EVDEV_device_removed(
const char *devpath);
77 static int SDL_EVDEV_device_added(
const char *devpath);
78 void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type,
int udev_class,
const char *devpath);
333 static Uint8 EVDEV_MouseButtons[] = {
344 static const char* EVDEV_consoles[] = {
358 #define IS_CONSOLE(fd) isatty (fd) && ioctl(fd, KDGKBTYPE, &arg) == 0 && ((arg == KB_101) || (arg == KB_84)) 360 static int SDL_EVDEV_get_console_fd(
void)
368 fd = open(EVDEV_consoles[i], O_RDONLY);
370 if (IS_CONSOLE(fd))
return fd;
377 for(fd = 0; fd < 3; fd++) {
378 if (IS_CONSOLE(fd))
return fd;
386 static int SDL_EVDEV_mute_keyboard(
int tty,
int *kb_mode)
391 if (!IS_CONSOLE(tty)) {
394 ioctl(tty, KDGKBMODE, kb_mode);
395 if (ioctl(tty, KDSKBMUTE, 1) && ioctl(tty, KDSKBMODE, K_OFF)) {
403 static void SDL_EVDEV_unmute_keyboard(
int tty,
int kb_mode)
405 if (ioctl(tty, KDSKBMUTE, 0) && ioctl(tty, KDSKBMODE, kb_mode)) {
406 SDL_Log(
"EVDEV: Failed restoring keyboard mode");
411 static int SDL_EVDEV_get_active_tty()
414 char ttyname[NAME_MAX + 1];
415 char ttypath[PATH_MAX+1] =
"/dev/";
418 fd = open(
"/sys/class/tty/tty0/active", O_RDONLY);
420 return SDL_SetError(
"Could not determine which tty is active");
423 len = read(fd, ttyname, NAME_MAX);
427 return SDL_SetError(
"Could not read which tty is active");
430 if (ttyname[len-1] ==
'\n') {
431 ttyname[len-1] =
'\0';
438 fd = open(ttypath, O_RDWR | O_NOCTTY);
443 if (!IS_CONSOLE(fd)) {
445 return SDL_SetError(
"Invalid tty obtained: %s", ttypath);
464 if (SDL_UDEV_Init() < 0) {
471 if (SDL_UDEV_AddCallback(SDL_EVDEV_udev_callback) < 0) {
483 _this->console_fd = SDL_EVDEV_get_console_fd();
486 _this->tty = STDIN_FILENO;
487 if (SDL_EVDEV_mute_keyboard(
_this->tty, &
_this->kb_mode) < 0) {
489 _this->tty = SDL_EVDEV_get_active_tty();
490 if (
_this->tty >= 0) {
491 if (SDL_EVDEV_mute_keyboard(
_this->tty, &
_this->kb_mode) < 0) {
499 _this->ref_count += 1;
511 _this->ref_count -= 1;
513 if (
_this->ref_count < 1) {
516 SDL_UDEV_DelCallback(SDL_EVDEV_udev_callback);
520 if (
_this->console_fd >= 0) {
521 close(
_this->console_fd);
524 if (
_this->tty >= 0) {
525 SDL_EVDEV_unmute_keyboard(
_this->tty,
_this->kb_mode);
531 SDL_EVDEV_device_removed(
_this->first->path);
544 void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type,
int udev_class,
const char *devpath)
546 if (devpath ==
NULL) {
551 case SDL_UDEV_DEVICEADDED:
552 if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE|SDL_UDEV_DEVICE_KEYBOARD))) {
555 SDL_EVDEV_device_added(devpath);
558 case SDL_UDEV_DEVICEREMOVED:
559 SDL_EVDEV_device_removed(devpath);
572 struct input_event
events[32];
574 SDL_evdevlist_item *item;
578 #ifdef SDL_INPUT_LINUXKD 581 static char keysym[8];
596 for (item =
_this->first; item !=
NULL; item = item->next) {
597 while ((len = read(item->fd,
events, (
sizeof events))) > 0) {
599 for (i = 0; i <
len; ++
i) {
603 mouse_button =
events[
i].code - BTN_MOUSE;
613 scan_code = SDL_EVDEV_translate_keycode(
events[i].code);
619 #ifdef SDL_INPUT_LINUXKD 620 if (
_this->console_fd >= 0) {
628 kbe.kb_table |= -((modstate &
KMOD_LCTRL) != 0) & (1 << KG_CTRLL | 1 << KG_CTRL);
629 kbe.kb_table |= -((modstate &
KMOD_RCTRL) != 0) & (1 << KG_CTRLR | 1 << KG_CTRL);
630 kbe.kb_table |= -((modstate &
KMOD_LSHIFT) != 0) & (1 << KG_SHIFTL | 1 << KG_SHIFT);
631 kbe.kb_table |= -((modstate &
KMOD_RSHIFT) != 0) & (1 << KG_SHIFTR | 1 << KG_SHIFT);
632 kbe.kb_table |= -((modstate &
KMOD_LALT) != 0) & (1 << KG_ALT);
633 kbe.kb_table |= -((modstate &
KMOD_RALT) != 0) & (1 << KG_ALTGR);
635 if (ioctl(
_this->console_fd, KDGKBENT, (
unsigned long)&kbe) == 0 &&
636 ((KTYP(kbe.kb_value) == KT_LATIN) || (KTYP(kbe.kb_value) == KT_ASCII) || (KTYP(kbe.kb_value) == KT_LETTER)))
638 kval = KVAL(kbe.kb_value);
644 if (modstate &
KMOD_CAPS && isalpha(kval)) {
646 kval = tolower(kval);
648 kval = toupper(kval);
695 SDL_EVDEV_sync_device(item);
708 SDL_EVDEV_translate_keycode(
int keycode)
713 scancode = EVDEV_Keycodes[keycode];
716 SDL_Log(
"The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> EVDEV KeyCode %d \n", keycode);
722 SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
729 SDL_EVDEV_device_added(
const char *devpath)
731 SDL_evdevlist_item *item;
734 for (item =
_this->first; item !=
NULL; item = item->next) {
740 item = (SDL_evdevlist_item *)
SDL_calloc(1,
sizeof (SDL_evdevlist_item));
745 item->fd = open(devpath, O_RDONLY, 0);
752 if (item->path ==
NULL) {
759 fcntl(item->fd, F_SETFL, O_NONBLOCK);
764 _this->last->next = item;
768 SDL_EVDEV_sync_device(item);
770 return _this->numdevices++;
775 SDL_EVDEV_device_removed(
const char *devpath)
777 SDL_evdevlist_item *item;
778 SDL_evdevlist_item *prev =
NULL;
780 for (item =
_this->first; item !=
NULL; item = item->next) {
784 prev->next = item->next;
787 _this->first = item->next;
789 if (item ==
_this->last) {
SDL_Mouse * SDL_GetMouse(void)
uint32_t Uint32
An unsigned 32-bit integer type.
static SDL_Event events[EVENT_BUF_SIZE]
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
static SDL_VideoDevice * _this
GLuint GLuint GLsizei GLenum type
void * SDL_calloc(size_t nmemb, size_t size)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
GLsizei const GLfloat * value
uint8_t Uint8
An unsigned 8-bit integer type.
int SDL_SendKeyboardText(const char *text)
#define SDL_BUTTON_MIDDLE
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)
#define SDL_assert(condition)
#define SDL_OutOfMemory()
char * SDL_UCS4ToUTF8(Uint32 ch, char *dst)
uint16_t Uint16
An unsigned 16-bit integer type.
#define SDL_arraysize(array)
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction)
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
SDL_Scancode
The SDL keyboard scancode representation.