This commit is contained in:
Tomasz Pakuła 2026-06-06 05:23:00 +08:00 committed by GitHub
commit 2f7e2b1876
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 58 additions and 16 deletions

View file

@ -35,6 +35,9 @@
#ifndef KEY_ALS_TOGGLE #ifndef KEY_ALS_TOGGLE
#define KEY_ALS_TOGGLE 0x230 #define KEY_ALS_TOGGLE 0x230
#endif #endif
#ifndef EV_BTN
#define EV_BTN 0x06
#endif
extern int extern int
SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_props[NBITS(INPUT_PROP_MAX)], SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_props[NBITS(INPUT_PROP_MAX)],
@ -58,6 +61,11 @@ SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_props[NBITS(INPUT_PROP_MA
int devclass = 0; int devclass = 0;
unsigned long keyboard_mask; unsigned long keyboard_mask;
// Only Joysticks (and maybe gamepads) have generic buttons
if (test_bit(EV_BTN, bitmask_ev)) {
return SDL_UDEV_DEVICE_JOYSTICK;
}
// If the kernel specifically says it's an accelerometer, believe it // If the kernel specifically says it's an accelerometer, believe it
if (test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props)) { if (test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props)) {
return SDL_UDEV_DEVICE_ACCELEROMETER; return SDL_UDEV_DEVICE_ACCELEROMETER;

View file

@ -57,6 +57,10 @@
#ifndef SYN_DROPPED #ifndef SYN_DROPPED
#define SYN_DROPPED 3 #define SYN_DROPPED 3
#endif #endif
#ifndef EV_BTN
#define EV_BTN 0x06
#define EVIOCGBTNCNT 0
#endif
#ifndef BTN_NORTH #ifndef BTN_NORTH
#define BTN_NORTH 0x133 #define BTN_NORTH 0x133
#endif #endif
@ -1225,6 +1229,7 @@ static bool GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct inp
static void ConfigJoystick(SDL_Joystick *joystick, int fd, int fd_sensor) static void ConfigJoystick(SDL_Joystick *joystick, int fd, int fd_sensor)
{ {
int i, t; int i, t;
unsigned long evbit[NBITS(EV_MAX)] = { 0 };
unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
unsigned long relbit[NBITS(REL_MAX)] = { 0 }; unsigned long relbit[NBITS(REL_MAX)] = { 0 };
@ -1238,27 +1243,40 @@ static void ConfigJoystick(SDL_Joystick *joystick, int fd, int fd_sensor)
// See if this device uses the new unified event API // See if this device uses the new unified event API
if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) && (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
(ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) { (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) &&
(ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) >= 0) ) {
// Get the number of buttons, axes, and other thingamajigs // Get the number of buttons, axes, and other thingamajigs
for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) { if (test_bit(EV_BTN, evbit)) {
if (test_bit(i, keybit)) { unsigned int button_count;
if(ioctl(fd, EVIOCGBTNCNT, &button_count) == 0) {
joystick->hwdata->ev_btn = true;
joystick->nbuttons = button_count;
#ifdef DEBUG_INPUT_EVENTS #ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has button: 0x%x", i); SDL_Log("Joystick has %u buttons", button_count);
#endif #endif
joystick->hwdata->key_map[i] = joystick->nbuttons;
joystick->hwdata->has_key[i] = true;
++joystick->nbuttons;
} }
} }
for (i = 0; i < BTN_JOYSTICK; ++i) { if (!joystick->hwdata->ev_btn) {
if (test_bit(i, keybit)) { for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
if (test_bit(i, keybit)) {
#ifdef DEBUG_INPUT_EVENTS #ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has button: 0x%x", i); SDL_Log("Joystick has button: 0x%x", i);
#endif #endif
joystick->hwdata->key_map[i] = joystick->nbuttons; joystick->hwdata->key_map[i] = joystick->nbuttons;
joystick->hwdata->has_key[i] = true; joystick->hwdata->has_key[i] = true;
++joystick->nbuttons; ++joystick->nbuttons;
}
}
for (i = 0; i < BTN_JOYSTICK; ++i) {
if (test_bit(i, keybit)) {
#ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has button: 0x%x", i);
#endif
joystick->hwdata->key_map[i] = joystick->nbuttons;
joystick->hwdata->has_key[i] = true;
++joystick->nbuttons;
}
} }
} }
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) { for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
@ -1860,7 +1878,8 @@ static void PollAllValues(Uint64 timestamp, SDL_Joystick *joystick)
// Poll all buttons // Poll all buttons
SDL_zeroa(keyinfo); SDL_zeroa(keyinfo);
if (ioctl(joystick->hwdata->fd, EVIOCGKEY(sizeof(keyinfo)), keyinfo) >= 0) { if (ioctl(joystick->hwdata->fd, EVIOCGKEY(sizeof(keyinfo)), keyinfo) >= 0 &&
!joystick->hwdata->ev_btn) {
for (i = 0; i < KEY_MAX; i++) { for (i = 0; i < KEY_MAX; i++) {
if (joystick->hwdata->has_key[i]) { if (joystick->hwdata->has_key[i]) {
bool down = test_bit(i, keyinfo); bool down = test_bit(i, keyinfo);
@ -1906,7 +1925,7 @@ static void PollAllSensors(Uint64 timestamp, SDL_Joystick *joystick)
if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) >= 0) { if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) >= 0) {
values[i] = absinfo.value * (SDL_PI_F / 180.f) / joystick->hwdata->gyro_scale[i]; values[i] = absinfo.value * (SDL_PI_F / 180.f) / joystick->hwdata->gyro_scale[i];
#ifdef DEBUG_INPUT_EVENTS #ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick : Re-read Gyro (axis %d) val= %f", i, data[i]); SDL_Log("Joystick : Re-read Gyro (axis %d) val= %f", i, values[i]);
#endif #endif
} }
} }
@ -1920,7 +1939,7 @@ static void PollAllSensors(Uint64 timestamp, SDL_Joystick *joystick)
if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) >= 0) { if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) >= 0) {
values[i] = absinfo.value * SDL_STANDARD_GRAVITY / joystick->hwdata->accelerometer_scale[i]; values[i] = absinfo.value * SDL_STANDARD_GRAVITY / joystick->hwdata->accelerometer_scale[i];
#ifdef DEBUG_INPUT_EVENTS #ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick : Re-read Accelerometer (axis %d) val= %f", i, data[i]); SDL_Log("Joystick : Re-read Accelerometer (axis %d) val= %f", i, values[i]);
#endif #endif
} }
} }
@ -1963,7 +1982,18 @@ static void HandleInputEvents(SDL_Joystick *joystick)
} }
switch (event->type) { switch (event->type) {
case EV_BTN:
if (!joystick->hwdata->ev_btn)
break;
#ifdef DEBUG_INPUT_EVENTS
SDL_Log("Button %u %s", code, event->value ? "PRESSED" : "RELEASED");
#endif
SDL_SendJoystickButton(SDL_EVDEV_GetEventTimestamp(event), joystick,
code - 1, (event->value != 0));
break;
case EV_KEY: case EV_KEY:
if (joystick->hwdata->ev_btn)
break;
#ifdef DEBUG_INPUT_EVENTS #ifdef DEBUG_INPUT_EVENTS
SDL_Log("Key 0x%.2x %s", code, event->value ? "PRESSED" : "RELEASED"); SDL_Log("Key 0x%.2x %s", code, event->value ? "PRESSED" : "RELEASED");
#endif #endif
@ -2061,6 +2091,7 @@ static void HandleInputEvents(SDL_Joystick *joystick)
} }
switch (event->type) { switch (event->type) {
case EV_BTN:
case EV_KEY: case EV_KEY:
SDL_assert(0); SDL_assert(0);
break; break;

View file

@ -63,6 +63,9 @@ struct joystick_hwdata
bool has_accelerometer; bool has_accelerometer;
bool has_gyro; bool has_gyro;
// Use EV_BTN instead of EV_KEY
bool ev_btn;
// Support for the classic joystick interface // Support for the classic joystick interface
bool classic; bool classic;
Uint16 *key_pam; Uint16 *key_pam;