|
@@ -29,10 +29,7 @@
|
|
|
* The evtest application is also useful to debug the protocol
|
|
|
*/
|
|
|
|
|
|
-
|
|
|
#include "SDL_evdev.h"
|
|
|
-#define _THIS SDL_EVDEV_PrivateData *_this
|
|
|
-static _THIS = NULL;
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
#include <unistd.h>
|
|
@@ -43,18 +40,8 @@ static _THIS = NULL;
|
|
|
#ifdef SDL_INPUT_LINUXKD
|
|
|
#include <linux/kd.h>
|
|
|
#include <linux/keyboard.h>
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-/* We need this to prevent keystrokes from appear in the console */
|
|
|
-#ifndef KDSKBMUTE
|
|
|
-#define KDSKBMUTE 0x4B51
|
|
|
-#endif
|
|
|
-#ifndef KDSKBMODE
|
|
|
-#define KDSKBMODE 0x4B45
|
|
|
-#endif
|
|
|
-#ifndef K_OFF
|
|
|
-#define K_OFF 0x04
|
|
|
+#include <linux/vt.h>
|
|
|
+#include <linux/tiocl.h> /* for TIOCL_GETSHIFTSTATE */
|
|
|
#endif
|
|
|
|
|
|
#include "SDL.h"
|
|
@@ -63,273 +50,71 @@ static _THIS = NULL;
|
|
|
#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 *devpath);
|
|
|
+static int SDL_EVDEV_device_removed(const char *dev_path);
|
|
|
|
|
|
#if SDL_USE_LIBUDEV
|
|
|
-static int SDL_EVDEV_device_added(const char *devpath);
|
|
|
-void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
|
|
|
+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 SDL_Scancode EVDEV_Keycodes[] = {
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_RESERVED 0 */
|
|
|
- SDL_SCANCODE_ESCAPE, /* KEY_ESC 1 */
|
|
|
- SDL_SCANCODE_1, /* KEY_1 2 */
|
|
|
- SDL_SCANCODE_2, /* KEY_2 3 */
|
|
|
- SDL_SCANCODE_3, /* KEY_3 4 */
|
|
|
- SDL_SCANCODE_4, /* KEY_4 5 */
|
|
|
- SDL_SCANCODE_5, /* KEY_5 6 */
|
|
|
- SDL_SCANCODE_6, /* KEY_6 7 */
|
|
|
- SDL_SCANCODE_7, /* KEY_7 8 */
|
|
|
- SDL_SCANCODE_8, /* KEY_8 9 */
|
|
|
- SDL_SCANCODE_9, /* KEY_9 10 */
|
|
|
- SDL_SCANCODE_0, /* KEY_0 11 */
|
|
|
- SDL_SCANCODE_MINUS, /* KEY_MINUS 12 */
|
|
|
- SDL_SCANCODE_EQUALS, /* KEY_EQUAL 13 */
|
|
|
- SDL_SCANCODE_BACKSPACE, /* KEY_BACKSPACE 14 */
|
|
|
- SDL_SCANCODE_TAB, /* KEY_TAB 15 */
|
|
|
- SDL_SCANCODE_Q, /* KEY_Q 16 */
|
|
|
- SDL_SCANCODE_W, /* KEY_W 17 */
|
|
|
- SDL_SCANCODE_E, /* KEY_E 18 */
|
|
|
- SDL_SCANCODE_R, /* KEY_R 19 */
|
|
|
- SDL_SCANCODE_T, /* KEY_T 20 */
|
|
|
- SDL_SCANCODE_Y, /* KEY_Y 21 */
|
|
|
- SDL_SCANCODE_U, /* KEY_U 22 */
|
|
|
- SDL_SCANCODE_I, /* KEY_I 23 */
|
|
|
- SDL_SCANCODE_O, /* KEY_O 24 */
|
|
|
- SDL_SCANCODE_P, /* KEY_P 25 */
|
|
|
- SDL_SCANCODE_LEFTBRACKET, /* KEY_LEFTBRACE 26 */
|
|
|
- SDL_SCANCODE_RIGHTBRACKET, /* KEY_RIGHTBRACE 27 */
|
|
|
- SDL_SCANCODE_RETURN, /* KEY_ENTER 28 */
|
|
|
- SDL_SCANCODE_LCTRL, /* KEY_LEFTCTRL 29 */
|
|
|
- SDL_SCANCODE_A, /* KEY_A 30 */
|
|
|
- SDL_SCANCODE_S, /* KEY_S 31 */
|
|
|
- SDL_SCANCODE_D, /* KEY_D 32 */
|
|
|
- SDL_SCANCODE_F, /* KEY_F 33 */
|
|
|
- SDL_SCANCODE_G, /* KEY_G 34 */
|
|
|
- SDL_SCANCODE_H, /* KEY_H 35 */
|
|
|
- SDL_SCANCODE_J, /* KEY_J 36 */
|
|
|
- SDL_SCANCODE_K, /* KEY_K 37 */
|
|
|
- SDL_SCANCODE_L, /* KEY_L 38 */
|
|
|
- SDL_SCANCODE_SEMICOLON, /* KEY_SEMICOLON 39 */
|
|
|
- SDL_SCANCODE_APOSTROPHE, /* KEY_APOSTROPHE 40 */
|
|
|
- SDL_SCANCODE_GRAVE, /* KEY_GRAVE 41 */
|
|
|
- SDL_SCANCODE_LSHIFT, /* KEY_LEFTSHIFT 42 */
|
|
|
- SDL_SCANCODE_BACKSLASH, /* KEY_BACKSLASH 43 */
|
|
|
- SDL_SCANCODE_Z, /* KEY_Z 44 */
|
|
|
- SDL_SCANCODE_X, /* KEY_X 45 */
|
|
|
- SDL_SCANCODE_C, /* KEY_C 46 */
|
|
|
- SDL_SCANCODE_V, /* KEY_V 47 */
|
|
|
- SDL_SCANCODE_B, /* KEY_B 48 */
|
|
|
- SDL_SCANCODE_N, /* KEY_N 49 */
|
|
|
- SDL_SCANCODE_M, /* KEY_M 50 */
|
|
|
- SDL_SCANCODE_COMMA, /* KEY_COMMA 51 */
|
|
|
- SDL_SCANCODE_PERIOD, /* KEY_DOT 52 */
|
|
|
- SDL_SCANCODE_SLASH, /* KEY_SLASH 53 */
|
|
|
- SDL_SCANCODE_RSHIFT, /* KEY_RIGHTSHIFT 54 */
|
|
|
- SDL_SCANCODE_KP_MULTIPLY, /* KEY_KPASTERISK 55 */
|
|
|
- SDL_SCANCODE_LALT, /* KEY_LEFTALT 56 */
|
|
|
- SDL_SCANCODE_SPACE, /* KEY_SPACE 57 */
|
|
|
- SDL_SCANCODE_CAPSLOCK, /* KEY_CAPSLOCK 58 */
|
|
|
- SDL_SCANCODE_F1, /* KEY_F1 59 */
|
|
|
- SDL_SCANCODE_F2, /* KEY_F2 60 */
|
|
|
- SDL_SCANCODE_F3, /* KEY_F3 61 */
|
|
|
- SDL_SCANCODE_F4, /* KEY_F4 62 */
|
|
|
- SDL_SCANCODE_F5, /* KEY_F5 63 */
|
|
|
- SDL_SCANCODE_F6, /* KEY_F6 64 */
|
|
|
- SDL_SCANCODE_F7, /* KEY_F7 65 */
|
|
|
- SDL_SCANCODE_F8, /* KEY_F8 66 */
|
|
|
- SDL_SCANCODE_F9, /* KEY_F9 67 */
|
|
|
- SDL_SCANCODE_F10, /* KEY_F10 68 */
|
|
|
- SDL_SCANCODE_NUMLOCKCLEAR, /* KEY_NUMLOCK 69 */
|
|
|
- SDL_SCANCODE_SCROLLLOCK, /* KEY_SCROLLLOCK 70 */
|
|
|
- SDL_SCANCODE_KP_7, /* KEY_KP7 71 */
|
|
|
- SDL_SCANCODE_KP_8, /* KEY_KP8 72 */
|
|
|
- SDL_SCANCODE_KP_9, /* KEY_KP9 73 */
|
|
|
- SDL_SCANCODE_KP_MINUS, /* KEY_KPMINUS 74 */
|
|
|
- SDL_SCANCODE_KP_4, /* KEY_KP4 75 */
|
|
|
- SDL_SCANCODE_KP_5, /* KEY_KP5 76 */
|
|
|
- SDL_SCANCODE_KP_6, /* KEY_KP6 77 */
|
|
|
- SDL_SCANCODE_KP_PLUS, /* KEY_KPPLUS 78 */
|
|
|
- SDL_SCANCODE_KP_1, /* KEY_KP1 79 */
|
|
|
- SDL_SCANCODE_KP_2, /* KEY_KP2 80 */
|
|
|
- SDL_SCANCODE_KP_3, /* KEY_KP3 81 */
|
|
|
- SDL_SCANCODE_KP_0, /* KEY_KP0 82 */
|
|
|
- SDL_SCANCODE_KP_PERIOD, /* KEY_KPDOT 83 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* 84 */
|
|
|
- SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU 85 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_102ND 86 */
|
|
|
- SDL_SCANCODE_F11, /* KEY_F11 87 */
|
|
|
- SDL_SCANCODE_F12, /* KEY_F12 88 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_RO 89 */
|
|
|
- SDL_SCANCODE_LANG3, /* KEY_KATAKANA 90 */
|
|
|
- SDL_SCANCODE_LANG4, /* KEY_HIRAGANA 91 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_HENKAN 92 */
|
|
|
- SDL_SCANCODE_LANG3, /* KEY_KATAKANAHIRAGANA 93 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_MUHENKAN 94 */
|
|
|
- SDL_SCANCODE_KP_COMMA, /* KEY_KPJPCOMMA 95 */
|
|
|
- SDL_SCANCODE_KP_ENTER, /* KEY_KPENTER 96 */
|
|
|
- SDL_SCANCODE_RCTRL, /* KEY_RIGHTCTRL 97 */
|
|
|
- SDL_SCANCODE_KP_DIVIDE, /* KEY_KPSLASH 98 */
|
|
|
- SDL_SCANCODE_SYSREQ, /* KEY_SYSRQ 99 */
|
|
|
- SDL_SCANCODE_RALT, /* KEY_RIGHTALT 100 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED 101 */
|
|
|
- SDL_SCANCODE_HOME, /* KEY_HOME 102 */
|
|
|
- SDL_SCANCODE_UP, /* KEY_UP 103 */
|
|
|
- SDL_SCANCODE_PAGEUP, /* KEY_PAGEUP 104 */
|
|
|
- SDL_SCANCODE_LEFT, /* KEY_LEFT 105 */
|
|
|
- SDL_SCANCODE_RIGHT, /* KEY_RIGHT 106 */
|
|
|
- SDL_SCANCODE_END, /* KEY_END 107 */
|
|
|
- SDL_SCANCODE_DOWN, /* KEY_DOWN 108 */
|
|
|
- SDL_SCANCODE_PAGEDOWN, /* KEY_PAGEDOWN 109 */
|
|
|
- SDL_SCANCODE_INSERT, /* KEY_INSERT 110 */
|
|
|
- SDL_SCANCODE_DELETE, /* KEY_DELETE 111 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_MACRO 112 */
|
|
|
- SDL_SCANCODE_MUTE, /* KEY_MUTE 113 */
|
|
|
- SDL_SCANCODE_VOLUMEDOWN, /* KEY_VOLUMEDOWN 114 */
|
|
|
- SDL_SCANCODE_VOLUMEUP, /* KEY_VOLUMEUP 115 */
|
|
|
- SDL_SCANCODE_POWER, /* KEY_POWER 116 SC System Power Down */
|
|
|
- SDL_SCANCODE_KP_EQUALS, /* KEY_KPEQUAL 117 */
|
|
|
- SDL_SCANCODE_KP_MINUS, /* KEY_KPPLUSMINUS 118 */
|
|
|
- SDL_SCANCODE_PAUSE, /* KEY_PAUSE 119 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SCALE 120 AL Compiz Scale (Expose) */
|
|
|
- SDL_SCANCODE_KP_COMMA, /* KEY_KPCOMMA 121 */
|
|
|
- SDL_SCANCODE_LANG1, /* KEY_HANGEUL,KEY_HANGUEL 122 */
|
|
|
- SDL_SCANCODE_LANG2, /* KEY_HANJA 123 */
|
|
|
- SDL_SCANCODE_INTERNATIONAL3,/* KEY_YEN 124 */
|
|
|
- SDL_SCANCODE_LGUI, /* KEY_LEFTMETA 125 */
|
|
|
- SDL_SCANCODE_RGUI, /* KEY_RIGHTMETA 126 */
|
|
|
- SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE 127 */
|
|
|
- SDL_SCANCODE_STOP, /* KEY_STOP 128 AC Stop */
|
|
|
- SDL_SCANCODE_AGAIN, /* KEY_AGAIN 129 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PROPS 130 AC Properties */
|
|
|
- SDL_SCANCODE_UNDO, /* KEY_UNDO 131 AC Undo */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_FRONT 132 */
|
|
|
- SDL_SCANCODE_COPY, /* KEY_COPY 133 AC Copy */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_OPEN 134 AC Open */
|
|
|
- SDL_SCANCODE_PASTE, /* KEY_PASTE 135 AC Paste */
|
|
|
- SDL_SCANCODE_FIND, /* KEY_FIND 136 AC Search */
|
|
|
- SDL_SCANCODE_CUT, /* KEY_CUT 137 AC Cut */
|
|
|
- SDL_SCANCODE_HELP, /* KEY_HELP 138 AL Integrated Help Center */
|
|
|
- SDL_SCANCODE_MENU, /* KEY_MENU 139 Menu (show menu) */
|
|
|
- SDL_SCANCODE_CALCULATOR, /* KEY_CALC 140 AL Calculator */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SETUP 141 */
|
|
|
- SDL_SCANCODE_SLEEP, /* KEY_SLEEP 142 SC System Sleep */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP 143 System Wake Up */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_FILE 144 AL Local Machine Browser */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE 145 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE 146 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_XFER 147 */
|
|
|
- SDL_SCANCODE_APP1, /* KEY_PROG1 148 */
|
|
|
- SDL_SCANCODE_APP1, /* KEY_PROG2 149 */
|
|
|
- SDL_SCANCODE_WWW, /* KEY_WWW 150 AL Internet Browser */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS 151 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE,KEY_SCREENLOCK 152 AL Terminal Lock/Screensaver */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION 153 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS 154 */
|
|
|
- SDL_SCANCODE_MAIL, /* KEY_MAIL 155 */
|
|
|
- SDL_SCANCODE_AC_BOOKMARKS, /* KEY_BOOKMARKS 156 AC Bookmarks */
|
|
|
- SDL_SCANCODE_COMPUTER, /* KEY_COMPUTER 157 */
|
|
|
- SDL_SCANCODE_AC_BACK, /* KEY_BACK 158 AC Back */
|
|
|
- SDL_SCANCODE_AC_FORWARD, /* KEY_FORWARD 159 AC Forward */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD 160 */
|
|
|
- SDL_SCANCODE_EJECT, /* KEY_EJECTCD 161 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_EJECTCLOSECD 162 */
|
|
|
- SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG 163 */
|
|
|
- SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE 164 */
|
|
|
- SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG 165 */
|
|
|
- SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD 166 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_RECORD 167 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_REWIND 168 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PHONE 169 Media Select Telephone */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_ISO 170 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG 171 AL Consumer Control Configuration */
|
|
|
- SDL_SCANCODE_AC_HOME, /* KEY_HOMEPAGE 172 AC Home */
|
|
|
- SDL_SCANCODE_AC_REFRESH, /* KEY_REFRESH 173 AC Refresh */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_EXIT 174 AC Exit */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_MOVE 175 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_EDIT 176 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP 177 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN 178 */
|
|
|
- SDL_SCANCODE_KP_LEFTPAREN, /* KEY_KPLEFTPAREN 179 */
|
|
|
- SDL_SCANCODE_KP_RIGHTPAREN, /* KEY_KPRIGHTPAREN 180 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_NEW 181 AC New */
|
|
|
- SDL_SCANCODE_AGAIN, /* KEY_REDO 182 AC Redo/Repeat */
|
|
|
- SDL_SCANCODE_F13, /* KEY_F13 183 */
|
|
|
- SDL_SCANCODE_F14, /* KEY_F14 184 */
|
|
|
- SDL_SCANCODE_F15, /* KEY_F15 185 */
|
|
|
- SDL_SCANCODE_F16, /* KEY_F16 186 */
|
|
|
- SDL_SCANCODE_F17, /* KEY_F17 187 */
|
|
|
- SDL_SCANCODE_F18, /* KEY_F18 188 */
|
|
|
- SDL_SCANCODE_F19, /* KEY_F19 189 */
|
|
|
- SDL_SCANCODE_F20, /* KEY_F20 190 */
|
|
|
- SDL_SCANCODE_F21, /* KEY_F21 191 */
|
|
|
- SDL_SCANCODE_F22, /* KEY_F22 192 */
|
|
|
- SDL_SCANCODE_F23, /* KEY_F23 193 */
|
|
|
- SDL_SCANCODE_F24, /* KEY_F24 194 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* 195 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* 196 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* 197 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* 198 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* 199 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PLAYCD 200 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD 201 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 202 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PROG4 203 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_DASHBOARD 204 AL Dashboard */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SUSPEND 205 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CLOSE 206 AC Close */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PLAY 207 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_FASTFORWARD 208 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BASSBOOST 209 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_PRINT 210 AC Print */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_HP 211 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA 212 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SOUND 213 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_QUESTION 214 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_EMAIL 215 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CHAT 216 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SEARCH 217 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CONNECT 218 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_FINANCE 219 AL Checkbook/Finance */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SPORT 220 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SHOP 221 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_ALTERASE 222 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_CANCEL 223 AC Cancel */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSDOWN 224 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSUP 225 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA 226 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SWITCHVIDEOMODE 227 Cycle between available video outputs (Monitor/LCD/TV-out/etc) */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMTOGGLE 228 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMDOWN 229 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMUP 230 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SEND 231 AC Send */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_REPLY 232 AC Reply */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL 233 AC Forward Msg */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_SAVE 234 AC Save */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS 235 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY 236 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BLUETOOTH 237 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_WLAN 238 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_UWB 239 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_UNKNOWN 240 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_NEXT 241 drive next video source */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_PREV 242 drive previous video source */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_CYCLE 243 brightness up, after max is min */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_ZERO 244 brightness off, use ambient */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAY_OFF 245 display device to off state */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_WIMAX 246 */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_RFKILL 247 Key that controls all radios */
|
|
|
- SDL_SCANCODE_UNKNOWN, /* KEY_MICMUTE 248 Mute / unmute the microphone */
|
|
|
-};
|
|
|
-
|
|
|
static Uint8 EVDEV_MouseButtons[] = {
|
|
|
SDL_BUTTON_LEFT, /* BTN_LEFT 0x110 */
|
|
|
SDL_BUTTON_RIGHT, /* BTN_RIGHT 0x111 */
|
|
@@ -342,134 +127,113 @@ static Uint8 EVDEV_MouseButtons[] = {
|
|
|
};
|
|
|
|
|
|
static const char* EVDEV_consoles[] = {
|
|
|
- "/proc/self/fd/0",
|
|
|
+ /* "/proc/self/fd/0",
|
|
|
"/dev/tty",
|
|
|
- "/dev/tty0",
|
|
|
+ "/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"
|
|
|
};
|
|
|
|
|
|
-#define IS_CONSOLE(fd) isatty (fd) && ioctl(fd, KDGKBTYPE, &arg) == 0 && ((arg == KB_101) || (arg == KB_84))
|
|
|
-
|
|
|
-static int SDL_EVDEV_get_console_fd(void)
|
|
|
-{
|
|
|
- int fd, i;
|
|
|
- char arg = 0;
|
|
|
-
|
|
|
- /* Try a few consoles to see which one we have read access to */
|
|
|
-
|
|
|
- for(i = 0; i < SDL_arraysize(EVDEV_consoles); i++) {
|
|
|
- fd = open(EVDEV_consoles[i], O_RDONLY);
|
|
|
- if (fd >= 0) {
|
|
|
- if (IS_CONSOLE(fd)) return fd;
|
|
|
- close(fd);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Try stdin, stdout, stderr */
|
|
|
+static int SDL_EVDEV_is_console( int fd ) {
|
|
|
+ int type;
|
|
|
|
|
|
- for(fd = 0; fd < 3; fd++) {
|
|
|
- if (IS_CONSOLE(fd)) return fd;
|
|
|
- }
|
|
|
-
|
|
|
- /* We won't be able to send SDL_TEXTINPUT events */
|
|
|
- return -1;
|
|
|
+ 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, int *kb_mode)
|
|
|
+static int SDL_EVDEV_mute_keyboard( int tty_fd, int* old_kb_mode )
|
|
|
{
|
|
|
- char arg;
|
|
|
+ if( !SDL_EVDEV_is_console( tty_fd ) ) {
|
|
|
+ return SDL_SetError( "Tried to mute an invalid tty" );
|
|
|
+ }
|
|
|
|
|
|
- *kb_mode = 0; /* FIXME: Is this a sane default in case KDGKBMODE fails? */
|
|
|
- if (!IS_CONSOLE(tty)) {
|
|
|
- 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" );
|
|
|
}
|
|
|
- ioctl(tty, KDGKBMODE, kb_mode); /* It's not fatal if this fails */
|
|
|
- if (ioctl(tty, KDSKBMUTE, 1) && ioctl(tty, KDSKBMODE, K_OFF)) {
|
|
|
- return SDL_SetError("EVDEV: Failed muting keyboard");
|
|
|
+
|
|
|
+ /* 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, int kb_mode)
|
|
|
+static void SDL_EVDEV_unmute_keyboard( int tty_fd, int kb_mode )
|
|
|
{
|
|
|
- if (ioctl(tty, KDSKBMUTE, 0) && ioctl(tty, KDSKBMODE, kb_mode)) {
|
|
|
- SDL_Log("EVDEV: Failed restoring keyboard mode");
|
|
|
+ /* read above */
|
|
|
+ /*
|
|
|
+ if( ioctl( tty_fd, KDSKBMODE, kb_mode ) < 0 ) {
|
|
|
+ SDL_Log( "Failed to unmute keyboard" );
|
|
|
}
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
-/* Read /sys/class/tty/tty0/active and open the tty */
|
|
|
static int SDL_EVDEV_get_active_tty()
|
|
|
-{
|
|
|
- int fd, len;
|
|
|
- char ttyname[NAME_MAX + 1];
|
|
|
- char ttypath[PATH_MAX+1] = "/dev/";
|
|
|
- char arg;
|
|
|
+{
|
|
|
+ int i, fd, ret, tty = 0;
|
|
|
+ char tiocl;
|
|
|
+ struct vt_stat vt_state;
|
|
|
+ char path[PATH_MAX + 1];
|
|
|
|
|
|
- fd = open("/sys/class/tty/tty0/active", O_RDONLY);
|
|
|
- if (fd < 0) {
|
|
|
- return SDL_SetError("Could not determine which tty is active");
|
|
|
- }
|
|
|
-
|
|
|
- len = read(fd, ttyname, NAME_MAX);
|
|
|
- close(fd);
|
|
|
-
|
|
|
- if (len <= 0) {
|
|
|
- return SDL_SetError("Could not read which tty is active");
|
|
|
- }
|
|
|
-
|
|
|
- if (ttyname[len-1] == '\n') {
|
|
|
- ttyname[len-1] = '\0';
|
|
|
- }
|
|
|
- else {
|
|
|
- ttyname[len] = '\0';
|
|
|
- }
|
|
|
-
|
|
|
- SDL_strlcat(ttypath, ttyname, PATH_MAX);
|
|
|
- fd = open(ttypath, O_RDWR | O_NOCTTY);
|
|
|
- if (fd < 0) {
|
|
|
- return SDL_SetError("Could not open tty: %s", ttypath);
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (!IS_CONSOLE(fd)) {
|
|
|
- close(fd);
|
|
|
- return SDL_SetError("Invalid tty obtained: %s", ttypath);
|
|
|
- }
|
|
|
-
|
|
|
- return fd;
|
|
|
+ return SDL_SetError( "Failed to determine active tty" );
|
|
|
}
|
|
|
|
|
|
int
|
|
|
SDL_EVDEV_Init(void)
|
|
|
{
|
|
|
- int retval = 0;
|
|
|
-
|
|
|
- if (_this == NULL) {
|
|
|
-
|
|
|
- _this = (SDL_EVDEV_PrivateData *) SDL_calloc(1, sizeof(*_this));
|
|
|
- if(_this == NULL) {
|
|
|
+ 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);
|
|
|
+ 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_EVDEV_Quit();
|
|
|
+ SDL_UDEV_Quit();
|
|
|
+ SDL_free( _this );
|
|
|
+ _this = NULL;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -479,109 +243,165 @@ SDL_EVDEV_Init(void)
|
|
|
/* 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_console_fd();
|
|
|
+ /* 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 */
|
|
|
- _this->tty = STDIN_FILENO;
|
|
|
- if (SDL_EVDEV_mute_keyboard(_this->tty, &_this->kb_mode) < 0) {
|
|
|
- /* stdin is not a tty, probably we were launched remotely, so we try to disable the active tty */
|
|
|
- _this->tty = SDL_EVDEV_get_active_tty();
|
|
|
- if (_this->tty >= 0) {
|
|
|
- if (SDL_EVDEV_mute_keyboard(_this->tty, &_this->kb_mode) < 0) {
|
|
|
- close(_this->tty);
|
|
|
- _this->tty = -1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ /* 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 retval;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
SDL_EVDEV_Quit(void)
|
|
|
{
|
|
|
- if (_this == NULL) {
|
|
|
+ if( _this == NULL ) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
_this->ref_count -= 1;
|
|
|
|
|
|
- if (_this->ref_count < 1) {
|
|
|
-
|
|
|
+ if( _this->ref_count < 1 ) {
|
|
|
#if SDL_USE_LIBUDEV
|
|
|
- SDL_UDEV_DelCallback(SDL_EVDEV_udev_callback);
|
|
|
+ SDL_UDEV_DelCallback( SDL_EVDEV_udev_callback );
|
|
|
SDL_UDEV_Quit();
|
|
|
#endif /* SDL_USE_LIBUDEV */
|
|
|
|
|
|
- if (_this->console_fd >= 0) {
|
|
|
- close(_this->console_fd);
|
|
|
- }
|
|
|
-
|
|
|
- if (_this->tty >= 0) {
|
|
|
- SDL_EVDEV_unmute_keyboard(_this->tty, _this->kb_mode);
|
|
|
- close(_this->tty);
|
|
|
+ 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_EVDEV_device_removed( _this->first->path );
|
|
|
}
|
|
|
|
|
|
- SDL_assert(_this->first == NULL);
|
|
|
- SDL_assert(_this->last == NULL);
|
|
|
- SDL_assert(_this->numdevices == 0);
|
|
|
+ SDL_assert( _this->first == NULL );
|
|
|
+ SDL_assert( _this->last == NULL );
|
|
|
+ SDL_assert( _this->num_devices == 0 );
|
|
|
|
|
|
- SDL_free(_this);
|
|
|
+ SDL_free( _this );
|
|
|
_this = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#if SDL_USE_LIBUDEV
|
|
|
-void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
|
|
+void SDL_EVDEV_udev_callback( SDL_UDEV_deviceevent udev_event, int udev_class,
|
|
|
+ const char* dev_path )
|
|
|
{
|
|
|
- if (devpath == NULL) {
|
|
|
+ if( dev_path == NULL ) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- switch(udev_type) {
|
|
|
+ switch( udev_event ) {
|
|
|
case SDL_UDEV_DEVICEADDED:
|
|
|
- if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE|SDL_UDEV_DEVICE_KEYBOARD))) {
|
|
|
+ if( !( udev_class & ( SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD |
|
|
|
+ SDL_UDEV_DEVICE_TOUCHSCREEN ) ) )
|
|
|
return;
|
|
|
- }
|
|
|
- SDL_EVDEV_device_added(devpath);
|
|
|
- break;
|
|
|
-
|
|
|
+
|
|
|
+ SDL_EVDEV_device_added( dev_path, udev_class );
|
|
|
+ break;
|
|
|
case SDL_UDEV_DEVICEREMOVED:
|
|
|
- SDL_EVDEV_device_removed(devpath);
|
|
|
+ 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, len;
|
|
|
+ int i, j, len;
|
|
|
SDL_evdevlist_item *item;
|
|
|
SDL_Scancode scan_code;
|
|
|
int mouse_button;
|
|
|
SDL_Mouse *mouse;
|
|
|
-#ifdef SDL_INPUT_LINUXKD
|
|
|
- Uint16 modstate;
|
|
|
- struct kbentry kbe;
|
|
|
- static char keysym[8];
|
|
|
- char *end;
|
|
|
- Uint32 kval;
|
|
|
-#endif
|
|
|
+ float norm_x, norm_y;
|
|
|
|
|
|
if (!_this) {
|
|
|
return;
|
|
@@ -597,6 +417,13 @@ SDL_EVDEV_Poll(void)
|
|
|
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)) {
|
|
@@ -614,57 +441,55 @@ SDL_EVDEV_Poll(void)
|
|
|
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 */) {
|
|
|
+ } else if( events[i].value == 1 || events[i].value == 2 /* key repeated */ ) {
|
|
|
SDL_SendKeyboardKey(SDL_PRESSED, scan_code);
|
|
|
#ifdef SDL_INPUT_LINUXKD
|
|
|
- if (_this->console_fd >= 0) {
|
|
|
- kbe.kb_index = events[i].code;
|
|
|
- /* Convert the key to an UTF-8 char */
|
|
|
- /* Ref: http://www.linuxjournal.com/article/2783 */
|
|
|
- modstate = SDL_GetModState();
|
|
|
- kbe.kb_table = 0;
|
|
|
-
|
|
|
- /* Ref: http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching */
|
|
|
- kbe.kb_table |= -((modstate & KMOD_LCTRL) != 0) & (1 << KG_CTRLL | 1 << KG_CTRL);
|
|
|
- kbe.kb_table |= -((modstate & KMOD_RCTRL) != 0) & (1 << KG_CTRLR | 1 << KG_CTRL);
|
|
|
- kbe.kb_table |= -((modstate & KMOD_LSHIFT) != 0) & (1 << KG_SHIFTL | 1 << KG_SHIFT);
|
|
|
- kbe.kb_table |= -((modstate & KMOD_RSHIFT) != 0) & (1 << KG_SHIFTR | 1 << KG_SHIFT);
|
|
|
- kbe.kb_table |= -((modstate & KMOD_LALT) != 0) & (1 << KG_ALT);
|
|
|
- kbe.kb_table |= -((modstate & KMOD_RALT) != 0) & (1 << KG_ALTGR);
|
|
|
-
|
|
|
- if (ioctl(_this->console_fd, KDGKBENT, (unsigned long)&kbe) == 0 &&
|
|
|
- ((KTYP(kbe.kb_value) == KT_LATIN) || (KTYP(kbe.kb_value) == KT_ASCII) || (KTYP(kbe.kb_value) == KT_LETTER)))
|
|
|
- {
|
|
|
- kval = KVAL(kbe.kb_value);
|
|
|
-
|
|
|
- /* While there's a KG_CAPSSHIFT symbol, it's not useful to build the table index with it
|
|
|
- * because 1 << KG_CAPSSHIFT overflows the 8 bits of kb_table
|
|
|
- * So, we do the CAPS LOCK logic here. Note that isalpha depends on the locale!
|
|
|
- */
|
|
|
- if (modstate & KMOD_CAPS && isalpha(kval)) {
|
|
|
- if (isupper(kval)) {
|
|
|
- kval = tolower(kval);
|
|
|
- } else {
|
|
|
- kval = toupper(kval);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Convert to UTF-8 and send */
|
|
|
- end = SDL_UCS4ToUTF8(kval, keysym);
|
|
|
- *end = '\0';
|
|
|
- SDL_SendKeyboardText(keysym);
|
|
|
- }
|
|
|
- }
|
|
|
+ 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:
|
|
@@ -691,7 +516,41 @@ SDL_EVDEV_Poll(void)
|
|
|
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:
|
|
@@ -705,34 +564,230 @@ SDL_EVDEV_Poll(void)
|
|
|
}
|
|
|
|
|
|
static SDL_Scancode
|
|
|
-SDL_EVDEV_translate_keycode(int keycode)
|
|
|
+SDL_EVDEV_translate_keycode( int keycode )
|
|
|
{
|
|
|
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
|
|
|
|
|
|
- if (keycode < SDL_arraysize(EVDEV_Keycodes)) {
|
|
|
- scancode = EVDEV_Keycodes[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);
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
+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)
|
|
|
{
|
|
|
- /* TODO: get full state of device and report whatever is required */
|
|
|
+ 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 ) {
|
|
|
+ SDL_Log( "Failed to sync device" );
|
|
|
+ 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 );
|
|
|
+ SDL_Log( "Failed to sync device" );
|
|
|
+ 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 );
|
|
|
+ SDL_Log( "Failed to sync device" );
|
|
|
+ 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 );
|
|
|
+ SDL_Log( "Failed to sync device" );
|
|
|
+ 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 );
|
|
|
+ SDL_Log( "Failed to sync device" );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ item->touchscreen_data->current_slot = abs_info.value;
|
|
|
+
|
|
|
+ SDL_free( mt_req_code );
|
|
|
}
|
|
|
|
|
|
#if SDL_USE_LIBUDEV
|
|
|
static int
|
|
|
-SDL_EVDEV_device_added(const char *devpath)
|
|
|
+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(devpath, item->path) == 0) {
|
|
|
+ if (SDL_strcmp(dev_path, item->path) == 0) {
|
|
|
return -1; /* already have this one */
|
|
|
}
|
|
|
}
|
|
@@ -742,21 +797,28 @@ SDL_EVDEV_device_added(const char *devpath)
|
|
|
return SDL_OutOfMemory();
|
|
|
}
|
|
|
|
|
|
- item->fd = open(devpath, O_RDONLY, 0);
|
|
|
+ item->fd = open( dev_path, O_RDONLY | O_NONBLOCK );
|
|
|
if (item->fd < 0) {
|
|
|
SDL_free(item);
|
|
|
- return SDL_SetError("Unable to open %s", devpath);
|
|
|
+ return SDL_SetError("Unable to open %s", dev_path);
|
|
|
}
|
|
|
|
|
|
- item->path = SDL_strdup(devpath);
|
|
|
+ item->path = SDL_strdup(dev_path);
|
|
|
if (item->path == NULL) {
|
|
|
close(item->fd);
|
|
|
SDL_free(item);
|
|
|
return SDL_OutOfMemory();
|
|
|
}
|
|
|
|
|
|
- /* Non blocking read mode */
|
|
|
- fcntl(item->fd, F_SETFL, O_NONBLOCK);
|
|
|
+ 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;
|
|
@@ -767,19 +829,19 @@ SDL_EVDEV_device_added(const char *devpath)
|
|
|
|
|
|
SDL_EVDEV_sync_device(item);
|
|
|
|
|
|
- return _this->numdevices++;
|
|
|
+ return _this->num_devices++;
|
|
|
}
|
|
|
#endif /* SDL_USE_LIBUDEV */
|
|
|
|
|
|
static int
|
|
|
-SDL_EVDEV_device_removed(const char *devpath)
|
|
|
+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(devpath, item->path) == 0) {
|
|
|
+ if (SDL_strcmp(dev_path, item->path) == 0) {
|
|
|
if (prev != NULL) {
|
|
|
prev->next = item->next;
|
|
|
} else {
|
|
@@ -789,10 +851,13 @@ SDL_EVDEV_device_removed(const char *devpath)
|
|
|
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->numdevices--;
|
|
|
+ _this->num_devices--;
|
|
|
return 0;
|
|
|
}
|
|
|
prev = item;
|
|
@@ -805,4 +870,3 @@ SDL_EVDEV_device_removed(const char *devpath)
|
|
|
#endif /* SDL_INPUT_LINUXEV */
|
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
-
|