diff options
author | 2023-02-26 19:40:37 +0100 | |
---|---|---|
committer | 2023-02-27 05:40:37 +1100 | |
commit | bd59a0d447b861982429905f186dee8b12f2e777 (patch) | |
tree | dc6341c8fb098818039127f758cf3eb0fade986a /3rdparty/SDL2/src/core/linux/SDL_evdev.c | |
parent | 28b03e92a84daf79eb3cef75c51c014b2f57807b (diff) |
Removed local copy of SDL source and update Android build support. (#10899)
* Removed SDL2 source.
* Updated gradle.
* Updated SDL2 Java support glue code.
* Increased minimum supported Android API version to 24.
* Updated required asset files for Android app.
* Added proper tag for Android logging.
* Added SDL2 hint to make BGFX work on Android.
Diffstat (limited to '3rdparty/SDL2/src/core/linux/SDL_evdev.c')
-rw-r--r-- | 3rdparty/SDL2/src/core/linux/SDL_evdev.c | 873 |
1 files changed, 0 insertions, 873 deletions
diff --git a/3rdparty/SDL2/src/core/linux/SDL_evdev.c b/3rdparty/SDL2/src/core/linux/SDL_evdev.c deleted file mode 100644 index 4761f3e464c..00000000000 --- a/3rdparty/SDL2/src/core/linux/SDL_evdev.c +++ /dev/null @@ -1,873 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#ifdef SDL_INPUT_LINUXEV - -/* This is based on the linux joystick driver */ -/* References: https://www.kernel.org/doc/Documentation/input/input.txt - * https://www.kernel.org/doc/Documentation/input/event-codes.txt - * /usr/include/linux/input.h - * The evtest application is also useful to debug the protocol - */ - -#include "SDL_evdev.h" - -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <limits.h> /* For the definition of PATH_MAX */ -#include <linux/input.h> -#ifdef SDL_INPUT_LINUXKD -#include <linux/kd.h> -#include <linux/keyboard.h> -#include <linux/vt.h> -#include <linux/tiocl.h> /* for TIOCL_GETSHIFTSTATE */ -#endif - -#include "SDL.h" -#include "SDL_assert.h" -#include "SDL_endian.h" -#include "../../core/linux/SDL_udev.h" -#include "SDL_scancode.h" -#include "../../events/SDL_events_c.h" -#include "../../events/scancodes_linux.h" /* adds linux_scancode_table */ - -/* This isn't defined in older Linux kernel headers */ -#ifndef SYN_DROPPED -#define SYN_DROPPED 3 -#endif - -typedef struct SDL_evdevlist_item -{ - char *path; - int fd; - - /* TODO: use this for every device, not just touchscreen */ - int out_of_sync; - - /* TODO: expand on this to have data for every possible class (mouse, - keyboard, touchpad, etc.). Also there's probably some things in here we - can pull out to the SDL_evdevlist_item i.e. name */ - int is_touchscreen; - struct { - char* name; - - int min_x, max_x, range_x; - int min_y, max_y, range_y; - - int max_slots; - int current_slot; - struct { - enum { - EVDEV_TOUCH_SLOTDELTA_NONE = 0, - EVDEV_TOUCH_SLOTDELTA_DOWN, - EVDEV_TOUCH_SLOTDELTA_UP, - EVDEV_TOUCH_SLOTDELTA_MOVE - } delta; - int tracking_id; - int x, y; - } * slots; - } * touchscreen_data; - - struct SDL_evdevlist_item *next; -} SDL_evdevlist_item; - -typedef struct SDL_EVDEV_PrivateData -{ - SDL_evdevlist_item *first; - SDL_evdevlist_item *last; - int num_devices; - int ref_count; - int console_fd; - int kb_mode; -} SDL_EVDEV_PrivateData; - -#define _THIS SDL_EVDEV_PrivateData *_this -static _THIS = NULL; - -static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode); -static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item); -static int SDL_EVDEV_device_removed(const char *dev_path); - -#if SDL_USE_LIBUDEV -static int SDL_EVDEV_device_added(const char *dev_path, int udev_class); -void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, - const char *dev_path); -#endif /* SDL_USE_LIBUDEV */ - -static Uint8 EVDEV_MouseButtons[] = { - SDL_BUTTON_LEFT, /* BTN_LEFT 0x110 */ - SDL_BUTTON_RIGHT, /* BTN_RIGHT 0x111 */ - SDL_BUTTON_MIDDLE, /* BTN_MIDDLE 0x112 */ - SDL_BUTTON_X1, /* BTN_SIDE 0x113 */ - SDL_BUTTON_X2, /* BTN_EXTRA 0x114 */ - SDL_BUTTON_X2 + 1, /* BTN_FORWARD 0x115 */ - SDL_BUTTON_X2 + 2, /* BTN_BACK 0x116 */ - SDL_BUTTON_X2 + 3 /* BTN_TASK 0x117 */ -}; - -static const char* EVDEV_consoles[] = { - /* "/proc/self/fd/0", - "/dev/tty", - "/dev/tty0", */ /* the tty ioctl's prohibit these */ - "/dev/tty1", - "/dev/tty2", - "/dev/tty3", - "/dev/tty4", - "/dev/tty5", - "/dev/tty6", - "/dev/tty7", /* usually X is spawned in tty7 */ - "/dev/vc/0", - "/dev/console" -}; - -static int SDL_EVDEV_is_console(int fd) { - int type; - - return isatty(fd) && ioctl(fd, KDGKBTYPE, &type) == 0 && - (type == KB_101 || type == KB_84); -} - -/* Prevent keystrokes from reaching the tty */ -static int SDL_EVDEV_mute_keyboard(int tty_fd, int* old_kb_mode) -{ - if (!SDL_EVDEV_is_console(tty_fd)) { - return SDL_SetError("Tried to mute an invalid tty"); - } - - if (ioctl(tty_fd, KDGKBMODE, old_kb_mode) < 0) { - return SDL_SetError("Failed to get keyboard mode during muting"); - } - - /* FIXME: atm this absolutely ruins the vt, and KDSKBMUTE isn't implemented - in the kernel */ - /* - if (ioctl(tty_fd, KDSKBMODE, K_OFF) < 0) { - return SDL_SetError("Failed to set keyboard mode during muting"); - } - */ - - return 0; -} - -/* Restore the keyboard mode for given tty */ -static void SDL_EVDEV_unmute_keyboard(int tty_fd, int kb_mode) -{ - /* read above */ - /* - if (ioctl(tty_fd, KDSKBMODE, kb_mode) < 0) { - SDL_Log("Failed to unmute keyboard"); - } - */ -} - -static int SDL_EVDEV_get_active_tty() -{ - int i, fd, ret, tty = 0; - char tiocl; - struct vt_stat vt_state; - char path[PATH_MAX + 1]; - - for(i = 0; i < SDL_arraysize(EVDEV_consoles); i++) { - fd = open(EVDEV_consoles[i], O_RDONLY); - - if (fd < 0 && !SDL_EVDEV_is_console(fd)) - break; - - tiocl = TIOCL_GETFGCONSOLE; - if ((ret = ioctl(fd, TIOCLINUX, &tiocl)) >= 0) - tty = ret + 1; - else if (ioctl(fd, VT_GETSTATE, &vt_state) == 0) - tty = vt_state.v_active; - - close(fd); - - if (tty) { - sprintf(path, "/dev/tty%u", tty); - fd = open(path, O_RDONLY); - if (fd >= 0 && SDL_EVDEV_is_console(fd)) - return fd; - } - } - - return SDL_SetError("Failed to determine active tty"); -} - -int -SDL_EVDEV_Init(void) -{ - if (_this == NULL) { - _this = (SDL_EVDEV_PrivateData*)SDL_calloc(1, sizeof(*_this)); - if (_this == NULL) { - return SDL_OutOfMemory(); - } - -#if SDL_USE_LIBUDEV - if (SDL_UDEV_Init() < 0) { - SDL_free(_this); - _this = NULL; - return -1; - } - - /* Set up the udev callback */ - if (SDL_UDEV_AddCallback(SDL_EVDEV_udev_callback) < 0) { - SDL_UDEV_Quit(); - SDL_free(_this); - _this = NULL; - return -1; - } - - /* Force a scan to build the initial device list */ - SDL_UDEV_Scan(); -#else - /* TODO: Scan the devices manually, like a caveman */ -#endif /* SDL_USE_LIBUDEV */ - - /* We need a physical terminal (not PTS) to be able to translate key - code to symbols via the kernel tables */ - _this->console_fd = SDL_EVDEV_get_active_tty(); - - /* Mute the keyboard so keystrokes only generate evdev events and do not - leak through to the console */ - SDL_EVDEV_mute_keyboard(_this->console_fd, &_this->kb_mode); - } - - _this->ref_count += 1; - - return 0; -} - -void -SDL_EVDEV_Quit(void) -{ - if (_this == NULL) { - return; - } - - _this->ref_count -= 1; - - if (_this->ref_count < 1) { -#if SDL_USE_LIBUDEV - SDL_UDEV_DelCallback(SDL_EVDEV_udev_callback); - SDL_UDEV_Quit(); -#endif /* SDL_USE_LIBUDEV */ - - if (_this->console_fd >= 0) { - SDL_EVDEV_unmute_keyboard(_this->console_fd, _this->kb_mode); - close(_this->console_fd); - } - - /* Remove existing devices */ - while(_this->first != NULL) { - SDL_EVDEV_device_removed(_this->first->path); - } - - SDL_assert(_this->first == NULL); - SDL_assert(_this->last == NULL); - SDL_assert(_this->num_devices == 0); - - SDL_free(_this); - _this = NULL; - } -} - -#if SDL_USE_LIBUDEV -void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_class, - const char* dev_path) -{ - if (dev_path == NULL) { - return; - } - - switch(udev_event) { - case SDL_UDEV_DEVICEADDED: - if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD | - SDL_UDEV_DEVICE_TOUCHSCREEN))) - return; - - SDL_EVDEV_device_added(dev_path, udev_class); - break; - case SDL_UDEV_DEVICEREMOVED: - SDL_EVDEV_device_removed(dev_path); - break; - default: - break; - } -} -#endif /* SDL_USE_LIBUDEV */ - -#ifdef SDL_INPUT_LINUXKD -/* this logic is pulled from kbd_keycode() in drivers/tty/vt/keyboard.c in the - Linux kernel source */ -static void SDL_EVDEV_do_text_input(unsigned short keycode) { - char shift_state; - int locks_state; - struct kbentry kbe; - unsigned char type; - char text[2] = { 0 }; - - if (_this->console_fd < 0) - return; - - shift_state = TIOCL_GETSHIFTSTATE; - if (ioctl(_this->console_fd, TIOCLINUX, &shift_state) < 0) { - /* TODO: error */ - return; - } - - kbe.kb_table = shift_state; - kbe.kb_index = keycode; - - if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) { - /* TODO: error */ - return; - } - - type = KTYP(kbe.kb_value); - - if (type < 0xf0) { - /* - * FIXME: keysyms with a type below 0xf0 represent a unicode character - * which requires special handling due to dead characters, diacritics, - * etc. For perfect input a proper way to deal with such characters - * should be implemented. - * - * For reference, the only place I was able to find out about this - * special 0xf0 value was in an unused? couple of patches listed below. - * - * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-keyboard.diff - * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-console.diff - */ - - return; - } - - type -= 0xf0; - - /* if type is KT_LETTER then it can be affected by Caps Lock */ - if (type == KT_LETTER) { - type = KT_LATIN; - - if (ioctl(_this->console_fd, KDGKBLED, &locks_state) < 0) { - /* TODO: error */ - return; - } - - if (locks_state & K_CAPSLOCK) { - kbe.kb_table = shift_state ^ (1 << KG_SHIFT); - - if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) { - /* TODO: error */ - return; - } - } - } - - /* TODO: convert values >= 0x80 from ISO-8859-1? to UTF-8 */ - if (type != KT_LATIN || KVAL(kbe.kb_value) >= 0x80) - return; - - *text = KVAL(kbe.kb_value); - SDL_SendKeyboardText(text); -} -#endif /* SDL_INPUT_LINUXKD */ - -void -SDL_EVDEV_Poll(void) -{ - struct input_event events[32]; - int i, j, len; - SDL_evdevlist_item *item; - SDL_Scancode scan_code; - int mouse_button; - SDL_Mouse *mouse; - float norm_x, norm_y; - - if (!_this) { - return; - } - -#if SDL_USE_LIBUDEV - SDL_UDEV_Poll(); -#endif - - mouse = SDL_GetMouse(); - - for (item = _this->first; item != NULL; item = item->next) { - while ((len = read(item->fd, events, (sizeof events))) > 0) { - len /= sizeof(events[0]); - for (i = 0; i < len; ++i) { - /* special handling for touchscreen, that should eventually be - used for all devices */ - if (item->out_of_sync && item->is_touchscreen && - events[i].type == EV_SYN && events[i].code != SYN_REPORT) { - break; - } - - switch (events[i].type) { - case EV_KEY: - if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) { - mouse_button = events[i].code - BTN_MOUSE; - if (events[i].value == 0) { - SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]); - } else if (events[i].value == 1) { - SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]); - } - break; - } - - /* Probably keyboard */ - scan_code = SDL_EVDEV_translate_keycode(events[i].code); - if (scan_code != SDL_SCANCODE_UNKNOWN) { - if (events[i].value == 0) { - SDL_SendKeyboardKey(SDL_RELEASED, scan_code); - } else if (events[i].value == 1 || events[i].value == 2 /* key repeated */) { - SDL_SendKeyboardKey(SDL_PRESSED, scan_code); -#ifdef SDL_INPUT_LINUXKD - SDL_EVDEV_do_text_input(events[i].code); -#endif /* SDL_INPUT_LINUXKD */ - } - } - break; - case EV_ABS: - switch(events[i].code) { - case ABS_MT_SLOT: - if (!item->is_touchscreen) /* FIXME: temp hack */ - break; - item->touchscreen_data->current_slot = events[i].value; - break; - case ABS_MT_TRACKING_ID: - if (!item->is_touchscreen) /* FIXME: temp hack */ - break; - if (events[i].value >= 0) { - item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = events[i].value; - item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; - } else { - item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_UP; - } - break; - case ABS_MT_POSITION_X: - if (!item->is_touchscreen) /* FIXME: temp hack */ - break; - item->touchscreen_data->slots[item->touchscreen_data->current_slot].x = events[i].value; - if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { - item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; - } - break; - case ABS_MT_POSITION_Y: - if (!item->is_touchscreen) /* FIXME: temp hack */ - break; - item->touchscreen_data->slots[item->touchscreen_data->current_slot].y = events[i].value; - if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { - item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; - } - break; - case ABS_X: - if (item->is_touchscreen) /* FIXME: temp hack */ - break; - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, events[i].value, mouse->y); - break; - case ABS_Y: - if (item->is_touchscreen) /* FIXME: temp hack */ - break; - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, mouse->x, events[i].value); - break; - default: - break; - } - break; - case EV_REL: - switch(events[i].code) { - case REL_X: - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, events[i].value, 0); - break; - case REL_Y: - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value); - break; - case REL_WHEEL: - SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL); - break; - case REL_HWHEEL: - SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); - break; - default: - break; - } - break; - case EV_SYN: - switch (events[i].code) { - case SYN_REPORT: - if (!item->is_touchscreen) /* FIXME: temp hack */ - break; - - for(j = 0; j < item->touchscreen_data->max_slots; j++) { - norm_x = (float)(item->touchscreen_data->slots[j].x - item->touchscreen_data->min_x) / - (float)item->touchscreen_data->range_x; - norm_y = (float)(item->touchscreen_data->slots[j].y - item->touchscreen_data->min_y) / - (float)item->touchscreen_data->range_y; - - switch(item->touchscreen_data->slots[j].delta) { - case EVDEV_TOUCH_SLOTDELTA_DOWN: - SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_TRUE, norm_x, norm_y, 1.0f); - item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; - break; - case EVDEV_TOUCH_SLOTDELTA_UP: - SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_FALSE, norm_x, norm_y, 1.0f); - item->touchscreen_data->slots[j].tracking_id = -1; - item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; - break; - case EVDEV_TOUCH_SLOTDELTA_MOVE: - SDL_SendTouchMotion(item->fd, item->touchscreen_data->slots[j].tracking_id, norm_x, norm_y, 1.0f); - item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; - break; - default: - break; - } - } - - if (item->out_of_sync) - item->out_of_sync = 0; - break; - case SYN_DROPPED: - if (item->is_touchscreen) - item->out_of_sync = 1; - SDL_EVDEV_sync_device(item); - break; - default: - break; - } - break; - } - } - } - } -} - -static SDL_Scancode -SDL_EVDEV_translate_keycode(int keycode) -{ - SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; - - if (keycode < SDL_arraysize(linux_scancode_table)) - scancode = linux_scancode_table[keycode]; - - if (scancode == SDL_SCANCODE_UNKNOWN) { - 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); - } - - return scancode; -} - -#ifdef SDL_USE_LIBUDEV -static int -SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) -{ - int ret, i; - char name[64]; - struct input_absinfo abs_info; - - if (!item->is_touchscreen) - return 0; - - item->touchscreen_data = SDL_calloc(1, sizeof(*item->touchscreen_data)); - if (item->touchscreen_data == NULL) - return SDL_OutOfMemory(); - - ret = ioctl(item->fd, EVIOCGNAME(sizeof(name)), name); - if (ret < 0) { - SDL_free(item->touchscreen_data); - return SDL_SetError("Failed to get evdev touchscreen name"); - } - - item->touchscreen_data->name = SDL_strdup(name); - if (item->touchscreen_data->name == NULL) { - SDL_free(item->touchscreen_data); - return SDL_OutOfMemory(); - } - - ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_info); - if (ret < 0) { - SDL_free(item->touchscreen_data->name); - SDL_free(item->touchscreen_data); - return SDL_SetError("Failed to get evdev touchscreen limits"); - } - item->touchscreen_data->min_x = abs_info.minimum; - item->touchscreen_data->max_x = abs_info.maximum; - item->touchscreen_data->range_x = abs_info.maximum - abs_info.minimum; - - ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_info); - if (ret < 0) { - SDL_free(item->touchscreen_data->name); - SDL_free(item->touchscreen_data); - return SDL_SetError("Failed to get evdev touchscreen limits"); - } - item->touchscreen_data->min_y = abs_info.minimum; - item->touchscreen_data->max_y = abs_info.maximum; - item->touchscreen_data->range_y = abs_info.maximum - abs_info.minimum; - - ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info); - if (ret < 0) { - SDL_free(item->touchscreen_data->name); - SDL_free(item->touchscreen_data); - return SDL_SetError("Failed to get evdev touchscreen limits"); - } - item->touchscreen_data->max_slots = abs_info.maximum + 1; - - item->touchscreen_data->slots = SDL_calloc( - item->touchscreen_data->max_slots, - sizeof(*item->touchscreen_data->slots)); - if (item->touchscreen_data->slots == NULL) { - SDL_free(item->touchscreen_data->name); - SDL_free(item->touchscreen_data); - return SDL_OutOfMemory(); - } - - for(i = 0; i < item->touchscreen_data->max_slots; i++) { - item->touchscreen_data->slots[i].tracking_id = -1; - } - - ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */ - item->touchscreen_data->name); - if (ret < 0) { - SDL_free(item->touchscreen_data->slots); - SDL_free(item->touchscreen_data->name); - SDL_free(item->touchscreen_data); - return ret; - } - - return 0; -} -#endif /* SDL_USE_LIBUDEV */ - -static void -SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item* item) { - if (!item->is_touchscreen) - return; - - SDL_DelTouch(item->fd); - SDL_free(item->touchscreen_data->slots); - SDL_free(item->touchscreen_data->name); - SDL_free(item->touchscreen_data); -} - -static void -SDL_EVDEV_sync_device(SDL_evdevlist_item *item) -{ -#ifdef EVIOCGMTSLOTS - int i, ret; - struct input_absinfo abs_info; - /* - * struct input_mt_request_layout { - * __u32 code; - * __s32 values[num_slots]; - * }; - * - * this is the structure we're trying to emulate - */ - __u32* mt_req_code; - __s32* mt_req_values; - size_t mt_req_size; - - /* TODO: sync devices other than touchscreen */ - if (!item->is_touchscreen) - return; - - mt_req_size = sizeof(*mt_req_code) + - sizeof(*mt_req_values) * item->touchscreen_data->max_slots; - - mt_req_code = SDL_calloc(1, mt_req_size); - if (mt_req_code == NULL) { - return; - } - - mt_req_values = (__s32*)mt_req_code + 1; - - *mt_req_code = ABS_MT_TRACKING_ID; - ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); - if (ret < 0) { - SDL_free(mt_req_code); - return; - } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { - /* - * This doesn't account for the very edge case of the user removing their - * finger and replacing it on the screen during the time we're out of sync, - * which'll mean that we're not going from down -> up or up -> down, we're - * going from down -> down but with a different tracking id, meaning we'd - * have to tell SDL of the two events, but since we wait till SYN_REPORT in - * SDL_EVDEV_Poll to tell SDL, the current structure of this code doesn't - * allow it. Lets just pray to God it doesn't happen. - */ - if (item->touchscreen_data->slots[i].tracking_id < 0 && - mt_req_values[i] >= 0) { - item->touchscreen_data->slots[i].tracking_id = mt_req_values[i]; - item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; - } else if (item->touchscreen_data->slots[i].tracking_id >= 0 && - mt_req_values[i] < 0) { - item->touchscreen_data->slots[i].tracking_id = -1; - item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP; - } - } - - *mt_req_code = ABS_MT_POSITION_X; - ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); - if (ret < 0) { - SDL_free(mt_req_code); - return; - } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { - if (item->touchscreen_data->slots[i].tracking_id >= 0 && - item->touchscreen_data->slots[i].x != mt_req_values[i]) { - item->touchscreen_data->slots[i].x = mt_req_values[i]; - if (item->touchscreen_data->slots[i].delta == - EVDEV_TOUCH_SLOTDELTA_NONE) { - item->touchscreen_data->slots[i].delta = - EVDEV_TOUCH_SLOTDELTA_MOVE; - } - } - } - - *mt_req_code = ABS_MT_POSITION_Y; - ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); - if (ret < 0) { - SDL_free(mt_req_code); - return; - } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { - if (item->touchscreen_data->slots[i].tracking_id >= 0 && - item->touchscreen_data->slots[i].y != mt_req_values[i]) { - item->touchscreen_data->slots[i].y = mt_req_values[i]; - if (item->touchscreen_data->slots[i].delta == - EVDEV_TOUCH_SLOTDELTA_NONE) { - item->touchscreen_data->slots[i].delta = - EVDEV_TOUCH_SLOTDELTA_MOVE; - } - } - } - - ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info); - if (ret < 0) { - SDL_free(mt_req_code); - return; - } - item->touchscreen_data->current_slot = abs_info.value; - - SDL_free(mt_req_code); - -#endif /* EVIOCGMTSLOTS */ -} - -#if SDL_USE_LIBUDEV -static int -SDL_EVDEV_device_added(const char *dev_path, int udev_class) -{ - int ret; - SDL_evdevlist_item *item; - - /* Check to make sure it's not already in list. */ - for (item = _this->first; item != NULL; item = item->next) { - if (SDL_strcmp(dev_path, item->path) == 0) { - return -1; /* already have this one */ - } - } - - item = (SDL_evdevlist_item *) SDL_calloc(1, sizeof (SDL_evdevlist_item)); - if (item == NULL) { - return SDL_OutOfMemory(); - } - - item->fd = open(dev_path, O_RDONLY | O_NONBLOCK); - if (item->fd < 0) { - SDL_free(item); - return SDL_SetError("Unable to open %s", dev_path); - } - - item->path = SDL_strdup(dev_path); - if (item->path == NULL) { - close(item->fd); - SDL_free(item); - return SDL_OutOfMemory(); - } - - if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) { - item->is_touchscreen = 1; - - if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) { - close(item->fd); - SDL_free(item); - return ret; - } - } - - if (_this->last == NULL) { - _this->first = _this->last = item; - } else { - _this->last->next = item; - _this->last = item; - } - - SDL_EVDEV_sync_device(item); - - return _this->num_devices++; -} -#endif /* SDL_USE_LIBUDEV */ - -static int -SDL_EVDEV_device_removed(const char *dev_path) -{ - SDL_evdevlist_item *item; - SDL_evdevlist_item *prev = NULL; - - for (item = _this->first; item != NULL; item = item->next) { - /* found it, remove it. */ - if (SDL_strcmp(dev_path, item->path) == 0) { - if (prev != NULL) { - prev->next = item->next; - } else { - SDL_assert(_this->first == item); - _this->first = item->next; - } - if (item == _this->last) { - _this->last = prev; - } - if (item->is_touchscreen) { - SDL_EVDEV_destroy_touchscreen(item); - } - close(item->fd); - SDL_free(item->path); - SDL_free(item); - _this->num_devices--; - return 0; - } - prev = item; - } - - return -1; -} - - -#endif /* SDL_INPUT_LINUXEV */ - -/* vi: set ts=4 sw=4 expandtab: */ |