30 #ifdef SDL_USE_LIBUDEV 32 #include <linux/input.h> 37 #include "../unix/SDL_poll.h" 39 static const char *SDL_UDEV_LIBS[] = {
"libudev.so.1",
"libudev.so.0" };
41 #define _THIS SDL_UDEV_PrivateData *_this 44 static SDL_bool SDL_UDEV_load_sym(
const char *fn,
void **
addr);
45 static int SDL_UDEV_load_syms(
void);
46 static SDL_bool SDL_UDEV_hotplug_update_available(
void);
47 static void device_event(SDL_UDEV_deviceevent
type,
struct udev_device *dev);
50 SDL_UDEV_load_sym(
const char *fn,
void **
addr)
62 SDL_UDEV_load_syms(
void)
65 #define SDL_UDEV_SYM(x) \ 66 if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1 68 SDL_UDEV_SYM(udev_device_get_action);
69 SDL_UDEV_SYM(udev_device_get_devnode);
70 SDL_UDEV_SYM(udev_device_get_subsystem);
71 SDL_UDEV_SYM(udev_device_get_parent_with_subsystem_devtype);
72 SDL_UDEV_SYM(udev_device_get_property_value);
73 SDL_UDEV_SYM(udev_device_get_sysattr_value);
74 SDL_UDEV_SYM(udev_device_new_from_syspath);
75 SDL_UDEV_SYM(udev_device_unref);
76 SDL_UDEV_SYM(udev_enumerate_add_match_property);
77 SDL_UDEV_SYM(udev_enumerate_add_match_subsystem);
78 SDL_UDEV_SYM(udev_enumerate_get_list_entry);
79 SDL_UDEV_SYM(udev_enumerate_new);
80 SDL_UDEV_SYM(udev_enumerate_scan_devices);
81 SDL_UDEV_SYM(udev_enumerate_unref);
82 SDL_UDEV_SYM(udev_list_entry_get_name);
83 SDL_UDEV_SYM(udev_list_entry_get_next);
84 SDL_UDEV_SYM(udev_monitor_enable_receiving);
85 SDL_UDEV_SYM(udev_monitor_filter_add_match_subsystem_devtype);
86 SDL_UDEV_SYM(udev_monitor_get_fd);
87 SDL_UDEV_SYM(udev_monitor_new_from_netlink);
88 SDL_UDEV_SYM(udev_monitor_receive_device);
89 SDL_UDEV_SYM(udev_monitor_unref);
90 SDL_UDEV_SYM(udev_new);
91 SDL_UDEV_SYM(udev_unref);
92 SDL_UDEV_SYM(udev_device_new_from_devnum);
93 SDL_UDEV_SYM(udev_device_get_devnum);
100 SDL_UDEV_hotplug_update_available(
void)
103 const int fd =
_this->udev_monitor_get_fd(
_this->udev_mon);
123 retval = SDL_UDEV_LoadLibrary();
139 _this->udev_mon =
_this->udev_monitor_new_from_netlink(
_this->udev,
"udev");
142 return SDL_SetError(
"udev_monitor_new_from_netlink() failed");
145 _this->udev_monitor_filter_add_match_subsystem_devtype(
_this->udev_mon,
"input",
NULL);
146 _this->udev_monitor_filter_add_match_subsystem_devtype(
_this->udev_mon,
"sound",
NULL);
147 _this->udev_monitor_enable_receiving(
_this->udev_mon);
154 _this->ref_count += 1;
162 SDL_UDEV_CallbackList *item;
168 _this->ref_count -= 1;
170 if (
_this->ref_count < 1) {
188 SDL_UDEV_UnloadLibrary();
197 struct udev_enumerate *enumerate =
NULL;
198 struct udev_list_entry *devs =
NULL;
199 struct udev_list_entry *item =
NULL;
205 enumerate =
_this->udev_enumerate_new(
_this->udev);
206 if (enumerate ==
NULL) {
212 _this->udev_enumerate_add_match_subsystem(enumerate,
"input");
213 _this->udev_enumerate_add_match_subsystem(enumerate,
"sound");
215 _this->udev_enumerate_scan_devices(enumerate);
216 devs =
_this->udev_enumerate_get_list_entry(enumerate);
217 for (item = devs; item; item =
_this->udev_list_entry_get_next(item)) {
218 const char *
path =
_this->udev_list_entry_get_name(item);
219 struct udev_device *dev =
_this->udev_device_new_from_syspath(
_this->udev, path);
221 device_event(SDL_UDEV_DEVICEADDED, dev);
222 _this->udev_device_unref(dev);
226 _this->udev_enumerate_unref(enumerate);
231 SDL_UDEV_UnloadLibrary(
void)
244 SDL_UDEV_LoadLibrary(
void)
253 if (SDL_UDEV_load_syms() == 0) {
257 #ifdef SDL_UDEV_DYNAMIC 262 retval = SDL_UDEV_load_syms();
264 SDL_UDEV_UnloadLibrary();
274 retval = SDL_UDEV_load_syms();
276 SDL_UDEV_UnloadLibrary();
293 #define BITS_PER_LONG (sizeof(unsigned long) * 8) 294 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) 295 #define OFF(x) ((x)%BITS_PER_LONG) 296 #define LONG(x) ((x)/BITS_PER_LONG) 297 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) 299 static void get_caps(
struct udev_device *dev,
struct udev_device *pdev,
const char *attr,
unsigned long *bitmask,
size_t bitmask_len)
307 SDL_memset(bitmask, 0, bitmask_len*
sizeof(*bitmask));
308 value =
_this->udev_device_get_sysattr_value(pdev, attr);
317 if (i < bitmask_len) {
324 if (i < bitmask_len) {
330 guess_device_class(
struct udev_device *dev)
333 struct udev_device *pdev;
334 unsigned long bitmask_ev[NBITS(EV_MAX)];
335 unsigned long bitmask_abs[NBITS(ABS_MAX)];
336 unsigned long bitmask_key[NBITS(KEY_MAX)];
337 unsigned long bitmask_rel[NBITS(REL_MAX)];
338 unsigned long keyboard_mask;
343 while (pdev && !
_this->udev_device_get_sysattr_value(pdev,
"capabilities/ev")) {
344 pdev =
_this->udev_device_get_parent_with_subsystem_devtype(pdev,
"input",
NULL);
350 get_caps(dev, pdev,
"capabilities/ev", bitmask_ev,
SDL_arraysize(bitmask_ev));
351 get_caps(dev, pdev,
"capabilities/abs", bitmask_abs,
SDL_arraysize(bitmask_abs));
352 get_caps(dev, pdev,
"capabilities/rel", bitmask_rel,
SDL_arraysize(bitmask_rel));
353 get_caps(dev, pdev,
"capabilities/key", bitmask_key,
SDL_arraysize(bitmask_key));
355 if (test_bit(EV_ABS, bitmask_ev) &&
356 test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) {
357 if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
359 }
else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
361 }
else if (test_bit(BTN_MOUSE, bitmask_key)) {
362 devclass |= SDL_UDEV_DEVICE_MOUSE;
363 }
else if (test_bit(BTN_TOUCH, bitmask_key)) {
366 devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
369 if (test_bit(BTN_TRIGGER, bitmask_key) ||
370 test_bit(BTN_A, bitmask_key) ||
371 test_bit(BTN_1, bitmask_key) ||
372 test_bit(ABS_RX, bitmask_abs) ||
373 test_bit(ABS_RY, bitmask_abs) ||
374 test_bit(ABS_RZ, bitmask_abs) ||
375 test_bit(ABS_THROTTLE, bitmask_abs) ||
376 test_bit(ABS_RUDDER, bitmask_abs) ||
377 test_bit(ABS_WHEEL, bitmask_abs) ||
378 test_bit(ABS_GAS, bitmask_abs) ||
379 test_bit(ABS_BRAKE, bitmask_abs)) {
380 devclass |= SDL_UDEV_DEVICE_JOYSTICK;
384 if (test_bit(EV_REL, bitmask_ev) &&
385 test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) &&
386 test_bit(BTN_MOUSE, bitmask_key)) {
387 devclass |= SDL_UDEV_DEVICE_MOUSE;
392 keyboard_mask = 0xFFFFFFFE;
393 if ((bitmask_key[0] & keyboard_mask) != 0)
394 devclass |= SDL_UDEV_DEVICE_KEYBOARD;
400 device_event(SDL_UDEV_deviceevent
type,
struct udev_device *dev)
402 const char *subsystem;
406 SDL_UDEV_CallbackList *item;
408 path =
_this->udev_device_get_devnode(dev);
413 subsystem =
_this->udev_device_get_subsystem(dev);
415 devclass = SDL_UDEV_DEVICE_SOUND;
416 }
else if (
SDL_strcmp(subsystem,
"input") == 0) {
419 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_JOYSTICK");
421 devclass |= SDL_UDEV_DEVICE_JOYSTICK;
424 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_MOUSE");
426 devclass |= SDL_UDEV_DEVICE_MOUSE;
429 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_TOUCHSCREEN");
431 devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
440 val =
_this->udev_device_get_property_value(dev,
"ID_INPUT_KEY");
442 devclass |= SDL_UDEV_DEVICE_KEYBOARD;
447 val =
_this->udev_device_get_property_value(dev,
"ID_CLASS");
450 devclass = SDL_UDEV_DEVICE_JOYSTICK;
452 devclass = SDL_UDEV_DEVICE_MOUSE;
454 devclass = SDL_UDEV_DEVICE_KEYBOARD;
460 devclass = guess_device_class(dev);
468 for (item =
_this->first; item !=
NULL; item = item->next) {
469 item->callback(type, devclass, path);
476 struct udev_device *dev =
NULL;
477 const char *action =
NULL;
483 while (SDL_UDEV_hotplug_update_available()) {
484 dev =
_this->udev_monitor_receive_device(
_this->udev_mon);
488 action =
_this->udev_device_get_action(dev);
494 device_event(SDL_UDEV_DEVICEADDED, dev);
495 }
else if (
SDL_strcmp(action,
"remove") == 0) {
496 device_event(SDL_UDEV_DEVICEREMOVED, dev);
499 _this->udev_device_unref(dev);
504 SDL_UDEV_AddCallback(SDL_UDEV_Callback cb)
506 SDL_UDEV_CallbackList *item;
507 item = (SDL_UDEV_CallbackList *)
SDL_calloc(1,
sizeof (SDL_UDEV_CallbackList));
517 _this->last->next = item;
525 SDL_UDEV_DelCallback(SDL_UDEV_Callback cb)
527 SDL_UDEV_CallbackList *item;
528 SDL_UDEV_CallbackList *prev =
NULL;
530 for (item =
_this->first; item !=
NULL; item = item->next) {
532 if (item->callback == cb) {
534 prev->next = item->next;
537 _this->first = item->next;
539 if (item ==
_this->last) {
int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS)
static SDL_VideoDevice * _this
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]
GLuint GLuint GLsizei GLenum type
#define SDL_arraysize(array)
GLsizei const GLchar *const * path
void * SDL_LoadFunction(void *handle, const char *name)