30 #ifdef SDL_USE_LIBUDEV 32 #include <linux/input.h> 36 static const char* SDL_UDEV_LIBS[] = {
"libudev.so.1",
"libudev.so.0" };
38 #define _THIS SDL_UDEV_PrivateData *_this 41 static SDL_bool SDL_UDEV_load_sym(
const char *fn,
void **
addr);
42 static int SDL_UDEV_load_syms(
void);
43 static SDL_bool SDL_UDEV_hotplug_update_available(
void);
44 static void device_event(SDL_UDEV_deviceevent
type,
struct udev_device *dev);
47 SDL_UDEV_load_sym(
const char *fn,
void **
addr)
59 SDL_UDEV_load_syms(
void)
62 #define SDL_UDEV_SYM(x) \ 63 if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1 65 SDL_UDEV_SYM(udev_device_get_action);
66 SDL_UDEV_SYM(udev_device_get_devnode);
67 SDL_UDEV_SYM(udev_device_get_subsystem);
68 SDL_UDEV_SYM(udev_device_get_parent_with_subsystem_devtype);
69 SDL_UDEV_SYM(udev_device_get_property_value);
70 SDL_UDEV_SYM(udev_device_get_sysattr_value);
71 SDL_UDEV_SYM(udev_device_new_from_syspath);
72 SDL_UDEV_SYM(udev_device_unref);
73 SDL_UDEV_SYM(udev_enumerate_add_match_property);
74 SDL_UDEV_SYM(udev_enumerate_add_match_subsystem);
75 SDL_UDEV_SYM(udev_enumerate_get_list_entry);
76 SDL_UDEV_SYM(udev_enumerate_new);
77 SDL_UDEV_SYM(udev_enumerate_scan_devices);
78 SDL_UDEV_SYM(udev_enumerate_unref);
79 SDL_UDEV_SYM(udev_list_entry_get_name);
80 SDL_UDEV_SYM(udev_list_entry_get_next);
81 SDL_UDEV_SYM(udev_monitor_enable_receiving);
82 SDL_UDEV_SYM(udev_monitor_filter_add_match_subsystem_devtype);
83 SDL_UDEV_SYM(udev_monitor_get_fd);
84 SDL_UDEV_SYM(udev_monitor_new_from_netlink);
85 SDL_UDEV_SYM(udev_monitor_receive_device);
86 SDL_UDEV_SYM(udev_monitor_unref);
87 SDL_UDEV_SYM(udev_new);
88 SDL_UDEV_SYM(udev_unref);
89 SDL_UDEV_SYM(udev_device_new_from_devnum);
90 SDL_UDEV_SYM(udev_device_get_devnum);
97 SDL_UDEV_hotplug_update_available(
void)
100 const int fd =
_this->udev_monitor_get_fd(
_this->udev_mon);
108 if ((select(fd+1, &fds,
NULL,
NULL, &tv) > 0) && (FD_ISSET(fd, &fds))) {
127 retval = SDL_UDEV_LoadLibrary();
143 _this->udev_mon =
_this->udev_monitor_new_from_netlink(
_this->udev,
"udev");
146 return SDL_SetError(
"udev_monitor_new_from_netlink() failed");
149 _this->udev_monitor_filter_add_match_subsystem_devtype(
_this->udev_mon,
"input",
NULL);
150 _this->udev_monitor_filter_add_match_subsystem_devtype(
_this->udev_mon,
"sound",
NULL);
151 _this->udev_monitor_enable_receiving(
_this->udev_mon);
158 _this->ref_count += 1;
166 SDL_UDEV_CallbackList *item;
172 _this->ref_count -= 1;
174 if (
_this->ref_count < 1) {
192 SDL_UDEV_UnloadLibrary();
201 struct udev_enumerate *enumerate =
NULL;
202 struct udev_list_entry *devs =
NULL;
203 struct udev_list_entry *item =
NULL;
209 enumerate =
_this->udev_enumerate_new(
_this->udev);
210 if (enumerate ==
NULL) {
216 _this->udev_enumerate_add_match_subsystem(enumerate,
"input");
217 _this->udev_enumerate_add_match_subsystem(enumerate,
"sound");
219 _this->udev_enumerate_scan_devices(enumerate);
220 devs =
_this->udev_enumerate_get_list_entry(enumerate);
221 for (item = devs; item; item =
_this->udev_list_entry_get_next(item)) {
222 const char *
path =
_this->udev_list_entry_get_name(item);
223 struct udev_device *dev =
_this->udev_device_new_from_syspath(
_this->udev, path);
225 device_event(SDL_UDEV_DEVICEADDED, dev);
226 _this->udev_device_unref(dev);
230 _this->udev_enumerate_unref(enumerate);
235 SDL_UDEV_UnloadLibrary(
void)
248 SDL_UDEV_LoadLibrary(
void)
261 retval = SDL_UDEV_load_syms();
263 SDL_UDEV_UnloadLibrary();
280 #define BITS_PER_LONG (sizeof(unsigned long) * 8) 281 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) 282 #define OFF(x) ((x)%BITS_PER_LONG) 283 #define BIT(x) (1UL<<OFF(x)) 284 #define LONG(x) ((x)/BITS_PER_LONG) 285 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) 287 static void get_caps(
struct udev_device *dev,
struct udev_device *pdev,
const char *attr,
unsigned long *bitmask,
size_t bitmask_len)
295 SDL_memset(bitmask, 0, bitmask_len*
sizeof(*bitmask));
296 value =
_this->udev_device_get_sysattr_value(pdev, attr);
305 if (i < bitmask_len) {
312 if (i < bitmask_len) {
318 guess_device_class(
struct udev_device *dev)
321 struct udev_device *pdev;
322 unsigned long bitmask_ev[NBITS(EV_MAX)];
323 unsigned long bitmask_abs[NBITS(ABS_MAX)];
324 unsigned long bitmask_key[NBITS(KEY_MAX)];
325 unsigned long bitmask_rel[NBITS(REL_MAX)];
326 unsigned long keyboard_mask;
331 while (pdev && !
_this->udev_device_get_sysattr_value(pdev,
"capabilities/ev")) {
332 pdev =
_this->udev_device_get_parent_with_subsystem_devtype(pdev,
"input",
NULL);
338 get_caps(dev, pdev,
"capabilities/ev", bitmask_ev,
SDL_arraysize(bitmask_ev));
339 get_caps(dev, pdev,
"capabilities/abs", bitmask_abs,
SDL_arraysize(bitmask_abs));
340 get_caps(dev, pdev,
"capabilities/rel", bitmask_rel,
SDL_arraysize(bitmask_rel));
341 get_caps(dev, pdev,
"capabilities/key", bitmask_key,
SDL_arraysize(bitmask_key));
343 if (test_bit(EV_ABS, bitmask_ev) &&
344 test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) {
345 if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
347 }
else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
349 }
else if (test_bit(BTN_MOUSE, bitmask_key)) {
350 devclass |= SDL_UDEV_DEVICE_MOUSE;
351 }
else if (test_bit(BTN_TOUCH, bitmask_key)) {
354 devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
357 if (test_bit(BTN_TRIGGER, bitmask_key) ||
358 test_bit(BTN_A, bitmask_key) ||
359 test_bit(BTN_1, bitmask_key) ||
360 test_bit(ABS_RX, bitmask_abs) ||
361 test_bit(ABS_RY, bitmask_abs) ||
362 test_bit(ABS_RZ, bitmask_abs) ||
363 test_bit(ABS_THROTTLE, bitmask_abs) ||
364 test_bit(ABS_RUDDER, bitmask_abs) ||
365 test_bit(ABS_WHEEL, bitmask_abs) ||
366 test_bit(ABS_GAS, bitmask_abs) ||
367 test_bit(ABS_BRAKE, bitmask_abs)) {
368 devclass |= SDL_UDEV_DEVICE_JOYSTICK;
372 if (test_bit(EV_REL, bitmask_ev) &&
373 test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) &&
374 test_bit(BTN_MOUSE, bitmask_key)) {
375 devclass |= SDL_UDEV_DEVICE_MOUSE;
380 keyboard_mask = 0xFFFFFFFE;
381 if ((bitmask_key[0] & keyboard_mask) != 0)
382 devclass |= SDL_UDEV_DEVICE_KEYBOARD;
388 device_event(SDL_UDEV_deviceevent
type,
struct udev_device *dev)
390 const char *subsystem;
394 SDL_UDEV_CallbackList *item;
396 path =
_this->udev_device_get_devnode(dev);
401 subsystem =
_this->udev_device_get_subsystem(dev);
403 devclass = SDL_UDEV_DEVICE_SOUND;
404 }
else if (
SDL_strcmp(subsystem,
"input") == 0) {
407 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_JOYSTICK");
409 devclass |= SDL_UDEV_DEVICE_JOYSTICK;
412 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_MOUSE");
414 devclass |= SDL_UDEV_DEVICE_MOUSE;
417 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_TOUCHSCREEN");
419 devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
428 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_KEY");
430 devclass |= SDL_UDEV_DEVICE_KEYBOARD;
435 val =
_this->udev_device_get_property_value(dev,
"ID_CLASS");
438 devclass = SDL_UDEV_DEVICE_JOYSTICK;
440 devclass = SDL_UDEV_DEVICE_MOUSE;
442 devclass = SDL_UDEV_DEVICE_KEYBOARD;
448 devclass = guess_device_class(dev);
456 for (item =
_this->first; item !=
NULL; item = item->next) {
457 item->callback(type, devclass, path);
464 struct udev_device *dev =
NULL;
465 const char *action =
NULL;
471 while (SDL_UDEV_hotplug_update_available()) {
472 dev =
_this->udev_monitor_receive_device(
_this->udev_mon);
476 action =
_this->udev_device_get_action(dev);
482 device_event(SDL_UDEV_DEVICEADDED, dev);
483 }
else if (
SDL_strcmp(action,
"remove") == 0) {
484 device_event(SDL_UDEV_DEVICEREMOVED, dev);
487 _this->udev_device_unref(dev);
492 SDL_UDEV_AddCallback(SDL_UDEV_Callback cb)
494 SDL_UDEV_CallbackList *item;
495 item = (SDL_UDEV_CallbackList *)
SDL_calloc(1,
sizeof (SDL_UDEV_CallbackList));
505 _this->last->next = item;
513 SDL_UDEV_DelCallback(SDL_UDEV_Callback cb)
515 SDL_UDEV_CallbackList *item;
516 SDL_UDEV_CallbackList *prev =
NULL;
518 for (item =
_this->first; item !=
NULL; item = item->next) {
520 if (item->callback == cb) {
522 prev->next = item->next;
525 _this->first = item->next;
527 if (item ==
_this->last) {
static SDL_VideoDevice * _this
GLuint GLuint GLsizei GLenum type
void * SDL_calloc(size_t nmemb, size_t size)
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)
#define SDL_assert(condition)
#define SDL_OutOfMemory()
static char text[MAX_TEXT_LENGTH]
#define SDL_arraysize(array)
GLsizei const GLchar *const * path
void * SDL_LoadFunction(void *handle, const char *name)