14 #include "../src/SDL_internal.h"
21 #if HAVE_LIBUDEV_H || defined(SDL_JOYSTICK_LINUX)
27 #include "../src/core/linux/SDL_evdev_capabilities.h"
28 #include "../src/core/linux/SDL_evdev_capabilities.c"
37 { SDL_UDEV_DEVICE_ ## x, #x }
56 uint8_t keys[(KEY_MAX + 1) / 8];
73 #define ZEROx4 0, 0, 0, 0
74 #define ZEROx8 ZEROx4, ZEROx4
75 #define FFx4 0xff, 0xff, 0xff, 0xff
76 #define FFx8 FFx4, FFx4
79 static const GuessTest guess_tests[] =
82 .name =
"Xbox 360 wired USB controller",
86 .expected = SDL_UDEV_DEVICE_JOYSTICK,
88 .ev = { 0x0b, 0x00, 0x20 },
90 .abs = { 0x3f, 0x00, 0x03 },
92 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
94 ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
98 .name =
"X-Box One Elite",
101 .product_id = 0x02e3,
102 .expected = SDL_UDEV_DEVICE_JOYSTICK,
106 .abs = { 0x3f, 0x00, 0x03 },
108 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
110 ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
114 .name =
"X-Box One S via Bluetooth",
117 .product_id = 0x02e0,
119 .expected = SDL_UDEV_DEVICE_JOYSTICK,
123 .abs = { 0x3f, 0x00, 0x03 },
125 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
127 ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
131 .name =
"X-Box One S wired",
134 .product_id = 0x02ea,
136 .expected = SDL_UDEV_DEVICE_JOYSTICK,
140 .abs = { 0x3f, 0x00, 0x03 },
142 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
144 ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
148 .name =
"DualShock 4 - gamepad",
151 .product_id = 0x09cc,
152 .expected = SDL_UDEV_DEVICE_JOYSTICK,
156 .ev = { 0x1b, 0x00, 0x20 },
158 .abs = { 0x3f, 0x00, 0x03 },
160 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
163 ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
167 .name =
"DualShock 4 - gamepad via Bluetooth",
170 .product_id = 0x09cc,
171 .expected = SDL_UDEV_DEVICE_JOYSTICK,
175 .abs = { 0x3f, 0x00, 0x03 },
177 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
180 ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
184 .name =
"DualShock 4 - touchpad",
187 .product_id = 0x09cc,
190 .expected = SDL_UDEV_DEVICE_UNKNOWN,
194 .abs = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x02 },
196 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
198 0x00, 0x00, 0x01, 0x00, ZEROx4,
200 0x20, 0x24, 0x00, 0x00
206 .name =
"DualShock 4 - accelerometer",
209 .product_id = 0x09cc,
210 .expected = SDL_UDEV_DEVICE_ACCELEROMETER,
219 .name =
"DualShock 4 via USB dongle",
222 .product_id = 0x0ba0,
224 .expected = SDL_UDEV_DEVICE_JOYSTICK,
228 .abs = { 0x3f, 0x00, 0x03 },
230 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
233 ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
237 .name =
"DualShock 3 - gamepad",
240 .product_id = 0x0268,
241 .expected = SDL_UDEV_DEVICE_JOYSTICK,
243 .ev = { 0x1b, 0x00, 0x20 },
247 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
250 ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
255 ZEROx4, 0x0f, 0x00, 0x00, 0x00,
259 .name =
"DualShock 3 - accelerometer",
262 .product_id = 0x0268,
263 .expected = SDL_UDEV_DEVICE_ACCELEROMETER,
272 .name =
"Steam Controller - gamepad",
275 .product_id = 0x1142,
276 .expected = SDL_UDEV_DEVICE_JOYSTICK,
280 .abs = { 0x1b, 0x00, 0x33 },
282 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
285 ZEROx4, 0x06, 0x00, 0xdb, 0x7f,
287 0x00, 0x00, 0x03, 0x00, ZEROx4,
291 ZEROx4, 0x0f, 0x00, 0x00, 0x00,
297 .name =
"Steam Controller - dongle",
300 .product_id = 0x1142,
301 .expected = (SDL_UDEV_DEVICE_KEYBOARD
302 | SDL_UDEV_DEVICE_MOUSE),
304 .ev = { 0x17, 0x00, 0x12 },
306 .rel = { 0x03, 0x09 },
308 0xfe, 0xff, 0xff, 0xff, FFx4,
309 0xff, 0xff, 0xcf, 0x01, 0xdf, 0xff, 0x80, 0xe0,
312 0x00, 0x00, 0x1f, 0x00, ZEROx4,
316 .name =
"Guitar Hero for PS3",
319 .product_id = 0x0100,
321 .expected = SDL_UDEV_DEVICE_JOYSTICK,
325 .abs = { 0x27, 0x00, 0x03 },
327 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
329 ZEROx4, 0x00, 0x00, 0xff, 0x1f,
333 .name =
"G27 Racing Wheel, 0003:046d:c29b v0111",
336 .product_id = 0xc29b,
338 .expected = SDL_UDEV_DEVICE_JOYSTICK,
342 .abs = { 0x27, 0x00, 0x03 },
344 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
347 ZEROx4, 0xff, 0xff, 0x00, 0x00,
359 .name =
"Logitech Driving Force, 0003:046d:c294 v0100",
362 .product_id = 0xc294,
364 .expected = SDL_UDEV_DEVICE_JOYSTICK,
368 .abs = { 0x23, 0x00, 0x03 },
370 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
373 ZEROx4, 0xff, 0x0f, 0x00, 0x00,
377 .name =
"Logitech Dual Action",
380 .product_id = 0xc216,
387 .expected = SDL_UDEV_DEVICE_JOYSTICK,
391 .abs = { 0x27, 0x00, 0x03 },
393 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
396 ZEROx4, 0xff, 0x0f, 0x00, 0x00,
400 .name =
"Saitek ST290 Pro flight stick",
403 .product_id = 0x0160,
405 .expected = SDL_UDEV_DEVICE_JOYSTICK,
409 .abs = { 0x27, 0x00, 0x03 },
411 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
413 ZEROx4, 0x3f, 0x00, 0x00, 0x00,
417 .name =
"Saitek X52 Pro Flight Control System",
420 .product_id = 0x0762,
422 .expected = SDL_UDEV_DEVICE_JOYSTICK,
425 .abs = { 0x7f, 0x00, 0x03, 0x00, 0x00, 0x03 },
427 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
430 ZEROx4, 0xff, 0xff, 0x00, 0x00,
442 .name =
"Logitech Extreme 3D",
445 .product_id = 0xc215,
447 .expected = SDL_UDEV_DEVICE_JOYSTICK,
451 .abs = { 0x63, 0x00, 0x03 },
453 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
456 ZEROx4, 0xff, 0x0f, 0x00, 0x00,
460 .name =
"Hori Real Arcade Pro VX-SA",
463 .product_id = 0x5501,
465 .expected = SDL_UDEV_DEVICE_JOYSTICK,
469 .abs = { 0x3f, 0x00, 0x03 },
471 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
473 ZEROx4, 0x00, 0x00, 0xdb, 0x7c,
477 .name =
"Switch Pro Controller via Bluetooth",
480 .product_id = 0x2009,
482 .expected = SDL_UDEV_DEVICE_JOYSTICK,
486 .abs = { 0x1b, 0x00, 0x03 },
488 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
491 ZEROx4, 0xff, 0xff, 0x00, 0x00,
503 .name =
"Switch Pro Controller via USB",
506 .product_id = 0x2009,
508 .expected = SDL_UDEV_DEVICE_JOYSTICK,
512 .abs = { 0x27, 0x00, 0x03 },
514 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
518 .name =
"Thrustmaster Racing Wheel FFB",
524 .product_id = 0xb66d,
526 .expected = SDL_UDEV_DEVICE_JOYSTICK,
529 .abs = { 0x3f, 0x00, 0x03 },
531 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
534 ZEROx4, 0x00, 0x00, 0xff, 0x3f,
538 .name =
"Thrustmaster T.Flight Hotas X",
541 .product_id = 0xb108,
543 .expected = SDL_UDEV_DEVICE_JOYSTICK,
546 .abs = { 0x67, 0x00, 0x03 },
548 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
555 .name =
"8BitDo N30 Pro 2",
558 .product_id = 0x9015,
561 .expected = SDL_UDEV_DEVICE_JOYSTICK,
564 .abs = { 0x27, 0x06, 0x03 },
566 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
569 ZEROx4, 0x00, 0x00, 0xff, 0x7f,
573 .name =
"Retro Power SNES-style controller, 0003:0079:0011 v0110",
576 .product_id = 0x0011,
578 .expected = SDL_UDEV_DEVICE_JOYSTICK,
583 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
586 ZEROx4, 0xff, 0x03, 0x00, 0x00,
590 .name =
"Wiimote - buttons",
593 .product_id = 0x0306,
599 .expected = SDL_UDEV_DEVICE_UNKNOWN,
605 ZEROx4, 0x80, 0x16, 0x00, 0x00,
609 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10,
612 0x00, 0x00, 0x80, 0x10, ZEROx4,
616 .name =
"Wiimote - Motion Plus or accelerometer",
619 .product_id = 0x0306,
621 .expected = SDL_UDEV_DEVICE_ACCELEROMETER,
628 .name =
"Wiimote - IR positioning",
631 .product_id = 0x0306,
633 .expected = SDL_UDEV_DEVICE_UNKNOWN,
637 .abs = { 0x00, 0x1f },
640 .name =
"Wiimote - Nunchuck",
643 .product_id = 0x0306,
646 .expected = SDL_UDEV_DEVICE_UNKNOWN,
650 .abs = { 0x38, 0x00, 0x03 },
652 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
654 ZEROx4, 0x00, 0x00, 0x24, 0x00,
659 .name =
"Wiimote - Classic Controller",
662 .expected = SDL_UDEV_DEVICE_UNKNOWN,
666 .abs = { 0x00, 0x1c },
670 ZEROx4, 0x80, 0x16, 0x00, 0x00,
674 ZEROx4, 0x00, 0x13, 0xdb, 0x10,
677 0x00, 0x00, 0x80, 0x10, ZEROx4,
682 .name =
"Wiimote - Balance Board",
684 .expected = SDL_UDEV_DEVICE_UNKNOWN,
688 .abs = { 0x00, 0x0f },
690 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
692 ZEROx4, 0x00, 0x00, 0x01, 0x00,
697 .name =
"Wiimote - Wii U Pro Controller",
698 .expected = SDL_UDEV_DEVICE_JOYSTICK,
704 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
707 ZEROx4, 0x00, 0x00, 0xdb, 0x7f,
712 ZEROx4, 0x0f, 0x00, 0x00, 0x00,
716 .name =
"Synaptics TM3381-002 (Thinkpad X280 trackpad)",
719 .product_id = 0x0000,
723 .expected = SDL_UDEV_DEVICE_UNKNOWN,
727 .abs = { 0x03, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x06 },
729 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
731 0x00, 0x00, 0x01, 0x00, ZEROx4,
739 .name =
"TPPS/2 Elan TrackPoint (Thinkpad X280)",
742 .product_id = 0x000a,
744 .expected = SDL_UDEV_DEVICE_MOUSE,
750 ZEROx8, ZEROx8, ZEROx8, ZEROx8,
758 .name =
"Thinkpad ACPI buttons",
759 .expected = SDL_UDEV_DEVICE_UNKNOWN,
764 ZEROx4, 0x00, 0x00, 0x0e, 0x01,
765 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0,
766 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00,
768 ZEROx4, 0x00, 0x00, 0x50, 0x00,
770 0x00, 0x00, 0x04, 0x18, ZEROx4,
772 0x40, 0x00, 0x01, 0x00, ZEROx4,
776 .name =
"PC speaker",
779 .product_id = 0x0001,
781 .expected = SDL_UDEV_DEVICE_UNKNOWN,
783 .ev = { 0x01, 0x00, 0x04 },
786 .name =
"ALSA headphone detection, etc.",
789 .product_id = 0x0000,
791 .expected = SDL_UDEV_DEVICE_UNKNOWN,
797 .name =
"Thinkpad T520 and X280 keyboards",
800 .product_id = 0x0001,
802 .expected = SDL_UDEV_DEVICE_KEYBOARD,
804 .ev = { 0x13, 0x00, 0x12 },
806 0xfe, 0xff, 0xff, 0xff, FFx4,
807 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xff, 0xfe,
808 0x01, 0xd0, 0x00, 0xf8, 0x78, 0x30, 0x80, 0x03,
809 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00,
813 .name =
"Thinkpad X280 sleep button",
816 .product_id = 0x0003,
818 .expected = SDL_UDEV_DEVICE_UNKNOWN,
829 .name =
"Thinkpad X280 lid switch",
832 .product_id = 0x0005,
834 .expected = SDL_UDEV_DEVICE_UNKNOWN,
839 .name =
"Thinkpad X280 power button",
842 .product_id = 0x0001,
844 .expected = SDL_UDEV_DEVICE_UNKNOWN,
850 ZEROx4, 0x00, 0x00, 0x10, 0x00,
854 .name =
"Thinkpad X280 video bus",
857 .product_id = 0x0006,
859 .expected = SDL_UDEV_DEVICE_UNKNOWN,
867 ZEROx4, 0x0b, 0x00, 0x3e, 0x00,
871 .name =
"Thinkpad X280 extra buttons",
874 .product_id = 0x5054,
876 .expected = SDL_UDEV_DEVICE_UNKNOWN,
881 ZEROx4, 0x00, 0x00, 0x0e, 0x01,
882 0x00, 0x50, 0x11, 0x51, 0x00, 0x28, 0x00, 0xc0,
883 0x04, 0x20, 0x10, 0x02, 0x1b, 0x70, 0x01, 0x00,
885 ZEROx4, 0x00, 0x00, 0x50, 0x00,
887 0x00, 0x00, 0x04, 0x18, ZEROx4,
889 0x40, 0x00, 0x01, 0x00, ZEROx4,
893 .name =
"Thinkpad USB keyboard with Trackpoint - keyboard",
896 .product_id = 0x6009,
897 .expected = SDL_UDEV_DEVICE_KEYBOARD,
899 .ev = { 0x13, 0x00, 0x12 },
901 0xfe, 0xff, 0xff, 0xff, FFx4,
902 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xbe, 0xfe,
903 0xff, 0x57, 0x40, 0xc1, 0x7a, 0x20, 0x9f, 0xff,
904 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
908 .name =
"Thinkpad USB keyboard with Trackpoint - Trackpoint",
911 .product_id = 0x6009,
916 .expected = SDL_UDEV_DEVICE_MOUSE,
918 .ev = { 0x17, 0x00, 0x02 },
923 ZEROx4, 0x00, 0x00, 0x1e, 0x00,
924 0x00, 0xcc, 0x11, 0x01, 0x78, 0x40, 0x00, 0xc0,
925 0x00, 0x20, 0x10, 0x00, 0x0b, 0x50, 0x00, 0x00,
927 0x00, 0x00, 0x87, 0x68, ZEROx4,
928 ZEROx4, 0x00, 0x00, 0x10, 0x00,
929 ZEROx4, 0x00, 0x00, 0x40, 0x00,
933 .name =
"No information",
934 .expected = SDL_UDEV_DEVICE_UNKNOWN,
938 #if ULONG_MAX == 0xFFFFFFFFUL
939 # define SwapLongLE(X) SDL_SwapLE32(X)
942 # define SwapLongLE(X) SDL_SwapLE64(X)
952 const GuessTest *
t = &guess_tests[
i];
956 unsigned long ev[NBITS(EV_MAX)];
957 unsigned long abs[NBITS(ABS_MAX)];
958 unsigned long keys[NBITS(KEY_MAX)];
959 unsigned long rel[NBITS(REL_MAX)];
962 printf(
"%s...\n",
t->name);
964 memset(&caps,
'\0',
sizeof(caps));
965 memcpy(caps.ev,
t->ev,
sizeof(
t->ev));
966 memcpy(caps.keys,
t->keys,
sizeof(
t->keys));
967 memcpy(caps.abs,
t->abs,
sizeof(
t->abs));
968 memcpy(caps.rel,
t->rel,
sizeof(
t->rel));
971 caps.ev[
j] = SwapLongLE(caps.ev[
j]);
975 caps.keys[
j] = SwapLongLE(caps.keys[
j]);
979 caps.abs[
j] = SwapLongLE(caps.abs[
j]);
983 caps.rel[
j] = SwapLongLE(caps.rel[
j]);
986 actual = SDL_EVDEV_GuessDeviceClass(caps.ev, caps.abs, caps.keys,
989 if (actual ==
t->expected) {
993 printf(
"\tExpected 0x%08x\n",
t->expected);
995 for (
j = 0; device_classes[
j].code != 0;
j++) {
996 if (
t->expected & device_classes[
j].code) {
997 printf(
"\t\t%s\n", device_classes[
j].
name);
1001 printf(
"\tGot 0x%08x\n", actual);
1003 for (
j = 0; device_classes[
j].code != 0;
j++) {
1004 if (actual & device_classes[
j].code) {
1005 printf(
"\t\t%s\n", device_classes[
j].
name);
1021 printf(
"SDL compiled without evdev capability check.\n");
GLenum GLuint GLsizei const GLenum * props
GLuint const GLchar * name
#define SDL_arraysize(array)
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)
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 int in j)
int main(int argc, char *argv[])
static int run_test(void)