evdev: Add support for REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES

If supported, these come alongside the regular REL_WHEEL and REL_HWHEEL
events so it's important that we only process one or the other.
This commit is contained in:
Cameron Gutman 2021-12-06 22:07:33 -06:00 committed by Sam Lantinga
parent 493d45f00f
commit 2d673e5b56
1 changed files with 26 additions and 2 deletions

View File

@ -57,6 +57,10 @@
#define ABS_MT_TRACKING_ID 0x39 #define ABS_MT_TRACKING_ID 0x39
#define ABS_MT_PRESSURE 0x3a #define ABS_MT_PRESSURE 0x3a
#endif #endif
#ifndef REL_WHEEL_HI_RES
#define REL_WHEEL_HI_RES 0x0b
#define REL_HWHEEL_HI_RES 0x0c
#endif
typedef struct SDL_evdevlist_item typedef struct SDL_evdevlist_item
{ {
@ -92,6 +96,9 @@ typedef struct SDL_evdevlist_item
} * touchscreen_data; } * touchscreen_data;
SDL_bool high_res_wheel;
SDL_bool high_res_hwheel;
struct SDL_evdevlist_item *next; struct SDL_evdevlist_item *next;
} SDL_evdevlist_item; } SDL_evdevlist_item;
@ -378,11 +385,21 @@ SDL_EVDEV_Poll(void)
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value); SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value);
break; break;
case REL_WHEEL: case REL_WHEEL:
if (!item->high_res_wheel)
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL); SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL);
break; break;
case REL_WHEEL_HI_RES:
SDL_assert(item->high_res_wheel);
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value / 120.0f, SDL_MOUSEWHEEL_NORMAL);
break;
case REL_HWHEEL: case REL_HWHEEL:
if (!item->high_res_hwheel)
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
break; break;
case REL_HWHEEL_HI_RES:
SDL_assert(item->high_res_hwheel);
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value / 120.0f, 0, SDL_MOUSEWHEEL_NORMAL);
break;
default: default:
break; break;
} }
@ -715,6 +732,7 @@ SDL_EVDEV_device_added(const char *dev_path, int udev_class)
{ {
int ret; int ret;
SDL_evdevlist_item *item; SDL_evdevlist_item *item;
unsigned long relbit[NBITS(REL_MAX)] = { 0 };
/* Check to make sure it's not already in list. */ /* Check to make sure it's not already in list. */
for (item = _this->first; item != NULL; item = item->next) { for (item = _this->first; item != NULL; item = item->next) {
@ -741,11 +759,17 @@ SDL_EVDEV_device_added(const char *dev_path, int udev_class)
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
if (ioctl(item->fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) {
item->high_res_wheel = test_bit(REL_WHEEL_HI_RES, relbit);
item->high_res_hwheel = test_bit(REL_HWHEEL_HI_RES, relbit);
}
if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) { if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) {
item->is_touchscreen = 1; item->is_touchscreen = 1;
if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) { if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) {
close(item->fd); close(item->fd);
SDL_free(item->path);
SDL_free(item); SDL_free(item);
return ret; return ret;
} }