mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-21 20:28:28 +00:00
linux: Distinguish between "device with keys" and a full keyboard
udev distinguishes between ID_INPUT_KEY, a device with any keyboard keys at all (including for example USB numeric keypads, Bluetooth headsets with volume control buttons, and some game controllers; and ID_INPUT_KEYBOARD, a reasonably fully-featured keyboard that you could use for general-purpose text entry. If we do the same here, then it's useful input to our heuristics for identifying devices: for example, a device with ID_INPUT_KEY could reasonably be a gamepad, but a device with ID_INPUT_KEYBOARD certainly isn't. Resolves: https://github.com/libsdl-org/SDL/issues/7827 Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
9b7a9ca666
commit
fa0ca3d41e
5 changed files with 36 additions and 31 deletions
|
@ -245,7 +245,7 @@ static void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_cl
|
||||||
|
|
||||||
switch (udev_event) {
|
switch (udev_event) {
|
||||||
case SDL_UDEV_DEVICEADDED:
|
case SDL_UDEV_DEVICEADDED:
|
||||||
if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD | SDL_UDEV_DEVICE_TOUCHSCREEN | SDL_UDEV_DEVICE_TOUCHPAD))) {
|
if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_HAS_KEYS | SDL_UDEV_DEVICE_TOUCHSCREEN | SDL_UDEV_DEVICE_TOUCHPAD))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,14 +131,15 @@ SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_ev[NBITS(EV_MAX)],
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found > 0) {
|
if (found > 0) {
|
||||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEY */
|
devclass |= SDL_UDEV_DEVICE_HAS_KEYS; /* ID_INPUT_KEY */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the first 32 bits are ESC, numbers, and Q to D; if we have any of
|
/* the first 32 bits are ESC, numbers, and Q to D, so if we have all of
|
||||||
* those, consider it a keyboard device; do not test KEY_RESERVED, though */
|
* those, consider it to be a fully-featured keyboard;
|
||||||
|
* do not test KEY_RESERVED, though */
|
||||||
keyboard_mask = 0xFFFFFFFE;
|
keyboard_mask = 0xFFFFFFFE;
|
||||||
if ((bitmask_key[0] & keyboard_mask) != 0) {
|
if ((bitmask_key[0] & keyboard_mask) == keyboard_mask) {
|
||||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */
|
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ typedef enum
|
||||||
SDL_UDEV_DEVICE_SOUND = 0x0008,
|
SDL_UDEV_DEVICE_SOUND = 0x0008,
|
||||||
SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010,
|
SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010,
|
||||||
SDL_UDEV_DEVICE_ACCELEROMETER = 0x0020,
|
SDL_UDEV_DEVICE_ACCELEROMETER = 0x0020,
|
||||||
SDL_UDEV_DEVICE_TOUCHPAD = 0x0040
|
SDL_UDEV_DEVICE_TOUCHPAD = 0x0040,
|
||||||
|
SDL_UDEV_DEVICE_HAS_KEYS = 0x0080,
|
||||||
} SDL_UDEV_deviceclass;
|
} SDL_UDEV_deviceclass;
|
||||||
|
|
||||||
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
||||||
|
|
|
@ -435,6 +435,11 @@ static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
|
||||||
Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
|
Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
|
||||||
*/
|
*/
|
||||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
|
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
|
||||||
|
if (val != NULL && SDL_strcmp(val, "1") == 0) {
|
||||||
|
devclass |= SDL_UDEV_DEVICE_HAS_KEYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD");
|
||||||
if (val != NULL && SDL_strcmp(val, "1") == 0) {
|
if (val != NULL && SDL_strcmp(val, "1") == 0) {
|
||||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD;
|
devclass |= SDL_UDEV_DEVICE_KEYBOARD;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +453,7 @@ static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
|
||||||
} else if (SDL_strcmp(val, "mouse") == 0) {
|
} else if (SDL_strcmp(val, "mouse") == 0) {
|
||||||
devclass = SDL_UDEV_DEVICE_MOUSE;
|
devclass = SDL_UDEV_DEVICE_MOUSE;
|
||||||
} else if (SDL_strcmp(val, "kbd") == 0) {
|
} else if (SDL_strcmp(val, "kbd") == 0) {
|
||||||
devclass = SDL_UDEV_DEVICE_KEYBOARD;
|
devclass = SDL_UDEV_DEVICE_HAS_KEYS | SDL_UDEV_DEVICE_KEYBOARD;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ static const struct
|
||||||
}
|
}
|
||||||
CLS(MOUSE),
|
CLS(MOUSE),
|
||||||
CLS(KEYBOARD),
|
CLS(KEYBOARD),
|
||||||
|
CLS(HAS_KEYS),
|
||||||
CLS(JOYSTICK),
|
CLS(JOYSTICK),
|
||||||
CLS(SOUND),
|
CLS(SOUND),
|
||||||
CLS(TOUCHSCREEN),
|
CLS(TOUCHSCREEN),
|
||||||
|
@ -351,7 +352,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x045e,
|
.vendor_id = 0x045e,
|
||||||
.product_id = 0x0b22,
|
.product_id = 0x0b22,
|
||||||
.version = 0x0517,
|
.version = 0x0517,
|
||||||
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY, ABS, FF */
|
/* SYN, KEY, ABS, FF */
|
||||||
.ev = { 0x0b, 0x00, 0x20 },
|
.ev = { 0x0b, 0x00, 0x20 },
|
||||||
/* Android-style mapping:
|
/* Android-style mapping:
|
||||||
|
@ -638,7 +639,8 @@ static const GuessTest guess_tests[] =
|
||||||
.bus_type = 0x0003,
|
.bus_type = 0x0003,
|
||||||
.vendor_id = 0x28de,
|
.vendor_id = 0x28de,
|
||||||
.product_id = 0x1142,
|
.product_id = 0x1142,
|
||||||
.expected = (SDL_UDEV_DEVICE_KEYBOARD
|
.expected = (SDL_UDEV_DEVICE_HAS_KEYS
|
||||||
|
| SDL_UDEV_DEVICE_KEYBOARD
|
||||||
| SDL_UDEV_DEVICE_MOUSE),
|
| SDL_UDEV_DEVICE_MOUSE),
|
||||||
/* SYN, KEY, REL, MSC, LED, REP */
|
/* SYN, KEY, REL, MSC, LED, REP */
|
||||||
.ev = { 0x17, 0x00, 0x12 },
|
.ev = { 0x17, 0x00, 0x12 },
|
||||||
|
@ -1087,7 +1089,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x045e,
|
.vendor_id = 0x045e,
|
||||||
.product_id = 0x02e0,
|
.product_id = 0x02e0,
|
||||||
.version = 0x0903,
|
.version = 0x0903,
|
||||||
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY, ABS, MSC, FF */
|
/* SYN, KEY, ABS, MSC, FF */
|
||||||
.ev = { 0x1b, 0x00, 0x20 },
|
.ev = { 0x1b, 0x00, 0x20 },
|
||||||
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
|
/* X, Y, Z, RX, RY, RZ, HAT0X, HAT0Y */
|
||||||
|
@ -1132,7 +1134,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x18d1,
|
.vendor_id = 0x18d1,
|
||||||
.product_id = 0x9400,
|
.product_id = 0x9400,
|
||||||
.version = 0x0100,
|
.version = 0x0100,
|
||||||
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.ev = { 0x0b },
|
.ev = { 0x0b },
|
||||||
/* XYZ, RZ, gas, brake, hat0 */
|
/* XYZ, RZ, gas, brake, hat0 */
|
||||||
.abs = { 0x27, 0x06, 0x03 },
|
.abs = { 0x27, 0x06, 0x03 },
|
||||||
|
@ -1166,7 +1168,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x045e,
|
.vendor_id = 0x045e,
|
||||||
.product_id = 0x0b12,
|
.product_id = 0x0b12,
|
||||||
.version = 0x050f,
|
.version = 0x050f,
|
||||||
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.ev = { 0x0b },
|
.ev = { 0x0b },
|
||||||
/* X, Y, Z, RX, RY, RZ, hat 0 */
|
/* X, Y, Z, RX, RY, RZ, hat 0 */
|
||||||
.abs = { 0x3f, 0x00, 0x03 },
|
.abs = { 0x3f, 0x00, 0x03 },
|
||||||
|
@ -1189,7 +1191,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x045e,
|
.vendor_id = 0x045e,
|
||||||
.product_id = 0x0b13,
|
.product_id = 0x0b13,
|
||||||
.version = 0x0515,
|
.version = 0x0515,
|
||||||
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_JOYSTICK | SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.ev = { 0x0b },
|
.ev = { 0x0b },
|
||||||
/* XYZ, RZ, gas, brake, hat0 */
|
/* XYZ, RZ, gas, brake, hat0 */
|
||||||
.abs = { 0x27, 0x06, 0x03 },
|
.abs = { 0x27, 0x06, 0x03 },
|
||||||
|
@ -1214,8 +1216,8 @@ static const GuessTest guess_tests[] =
|
||||||
/* This one is a bit weird because some of the buttons are mapped
|
/* This one is a bit weird because some of the buttons are mapped
|
||||||
* to the arrow, page up and page down keys, so it's a joystick
|
* to the arrow, page up and page down keys, so it's a joystick
|
||||||
* with a subset of a keyboard attached. */
|
* with a subset of a keyboard attached. */
|
||||||
/* TODO: Should this be JOYSTICK, or even JOYSTICK|KEYBOARD? */
|
/* TODO: Should this be JOYSTICK, or even JOYSTICK|HAS_KEYS? */
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY, FF */
|
/* SYN, KEY, FF */
|
||||||
.ev = { 0x03, 0x00, 0x20 },
|
.ev = { 0x03, 0x00, 0x20 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1296,9 +1298,9 @@ static const GuessTest guess_tests[] =
|
||||||
{
|
{
|
||||||
.name = "Wiimote - Classic Controller",
|
.name = "Wiimote - Classic Controller",
|
||||||
.eviocgname = "Nintendo Wii Remote Classic Controller",
|
.eviocgname = "Nintendo Wii Remote Classic Controller",
|
||||||
/* TODO: Should this be JOYSTICK, or maybe JOYSTICK|KEYBOARD?
|
/* TODO: Should this be JOYSTICK, or maybe JOYSTICK|HAS_KEYS?
|
||||||
* It's unusual in the same ways as the Wiimote */
|
* It's unusual in the same ways as the Wiimote */
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY, ABS */
|
/* SYN, KEY, ABS */
|
||||||
.ev = { 0x0b },
|
.ev = { 0x0b },
|
||||||
/* Hat 1-3 X and Y */
|
/* Hat 1-3 X and Y */
|
||||||
|
@ -1422,8 +1424,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x17aa,
|
.vendor_id = 0x17aa,
|
||||||
.product_id = 0x5054,
|
.product_id = 0x5054,
|
||||||
.version = 0x4101,
|
.version = 0x4101,
|
||||||
/* SDL treats this as a keyboard because it has a power button */
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
|
||||||
/* SYN, KEY, MSC, SW */
|
/* SYN, KEY, MSC, SW */
|
||||||
.ev = { 0x33 },
|
.ev = { 0x33 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1446,7 +1447,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x17aa,
|
.vendor_id = 0x17aa,
|
||||||
.product_id = 0x5054,
|
.product_id = 0x5054,
|
||||||
.version = 0x4101,
|
.version = 0x4101,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY, MSC, SW */
|
/* SYN, KEY, MSC, SW */
|
||||||
.ev = { 0x33 },
|
.ev = { 0x33 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1507,7 +1508,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x0001,
|
.vendor_id = 0x0001,
|
||||||
.product_id = 0x0001,
|
.product_id = 0x0001,
|
||||||
.version = 0xab54,
|
.version = 0xab54,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS | SDL_UDEV_DEVICE_KEYBOARD,
|
||||||
/* SYN, KEY, MSC, LED, REP */
|
/* SYN, KEY, MSC, LED, REP */
|
||||||
.ev = { 0x13, 0x00, 0x12 },
|
.ev = { 0x13, 0x00, 0x12 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1524,8 +1525,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x0000,
|
.vendor_id = 0x0000,
|
||||||
.product_id = 0x0003,
|
.product_id = 0x0003,
|
||||||
.version = 0x0000,
|
.version = 0x0000,
|
||||||
/* SDL treats KEY_SLEEP as indicating a keyboard */
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
|
||||||
/* SYN, KEY */
|
/* SYN, KEY */
|
||||||
.ev = { 0x03 },
|
.ev = { 0x03 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1553,8 +1553,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x0000,
|
.vendor_id = 0x0000,
|
||||||
.product_id = 0x0001,
|
.product_id = 0x0001,
|
||||||
.version = 0x0000,
|
.version = 0x0000,
|
||||||
/* SDL treats KEY_POWER as indicating a keyboard */
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
|
||||||
/* SYN, KEY */
|
/* SYN, KEY */
|
||||||
.ev = { 0x03 },
|
.ev = { 0x03 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1570,8 +1569,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x0000,
|
.vendor_id = 0x0000,
|
||||||
.product_id = 0x0006,
|
.product_id = 0x0006,
|
||||||
.version = 0x0000,
|
.version = 0x0000,
|
||||||
/* SDL treats brightness control, etc. as keyboard keys */
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
|
||||||
/* SYN, KEY */
|
/* SYN, KEY */
|
||||||
.ev = { 0x03 },
|
.ev = { 0x03 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1591,7 +1589,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x04f2,
|
.vendor_id = 0x04f2,
|
||||||
.product_id = 0xb604,
|
.product_id = 0xb604,
|
||||||
.version = 0x0027,
|
.version = 0x0027,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY */
|
/* SYN, KEY */
|
||||||
.ev = { 0x03 },
|
.ev = { 0x03 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1608,7 +1606,7 @@ static const GuessTest guess_tests[] =
|
||||||
.vendor_id = 0x17aa,
|
.vendor_id = 0x17aa,
|
||||||
.product_id = 0x5054,
|
.product_id = 0x5054,
|
||||||
.version = 0x4101,
|
.version = 0x4101,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY */
|
/* SYN, KEY */
|
||||||
.ev = { 0x03 },
|
.ev = { 0x03 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1632,7 +1630,7 @@ static const GuessTest guess_tests[] =
|
||||||
.bus_type = 0x0003,
|
.bus_type = 0x0003,
|
||||||
.vendor_id = 0x17ef,
|
.vendor_id = 0x17ef,
|
||||||
.product_id = 0x6009,
|
.product_id = 0x6009,
|
||||||
.expected = SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_HAS_KEYS | SDL_UDEV_DEVICE_KEYBOARD,
|
||||||
/* SYN, KEY, MSC, LED, REP */
|
/* SYN, KEY, MSC, LED, REP */
|
||||||
.ev = { 0x13, 0x00, 0x12 },
|
.ev = { 0x13, 0x00, 0x12 },
|
||||||
.keys = {
|
.keys = {
|
||||||
|
@ -1656,7 +1654,7 @@ static const GuessTest guess_tests[] =
|
||||||
/* For some reason the special keys like mute and wlan toggle
|
/* For some reason the special keys like mute and wlan toggle
|
||||||
* show up here instead of, or in addition to, as part of
|
* show up here instead of, or in addition to, as part of
|
||||||
* the keyboard - so both udev and SDL report this as having keys too. */
|
* the keyboard - so both udev and SDL report this as having keys too. */
|
||||||
.expected = SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD,
|
.expected = SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_HAS_KEYS,
|
||||||
/* SYN, KEY, REL, MSC, LED */
|
/* SYN, KEY, REL, MSC, LED */
|
||||||
.ev = { 0x17, 0x00, 0x02 },
|
.ev = { 0x17, 0x00, 0x02 },
|
||||||
/* X, Y */
|
/* X, Y */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue