mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-01-24 19:41:01 +00:00
Added support for absolute mice with evdev
This commit is contained in:
parent
8231278817
commit
9cd7cbe134
|
@ -105,6 +105,8 @@ typedef struct SDL_evdevlist_item
|
||||||
SDL_bool relative_mouse;
|
SDL_bool relative_mouse;
|
||||||
int mouse_x, mouse_y;
|
int mouse_x, mouse_y;
|
||||||
int mouse_wheel, mouse_hwheel;
|
int mouse_wheel, mouse_hwheel;
|
||||||
|
int min_x, max_x, range_x;
|
||||||
|
int min_y, max_y, range_y;
|
||||||
|
|
||||||
struct SDL_evdevlist_item *next;
|
struct SDL_evdevlist_item *next;
|
||||||
} SDL_evdevlist_item;
|
} SDL_evdevlist_item;
|
||||||
|
@ -391,7 +393,6 @@ void SDL_EVDEV_Poll(void)
|
||||||
}
|
}
|
||||||
item->touchscreen_data->slots[0].x = events[i].value;
|
item->touchscreen_data->slots[0].x = events[i].value;
|
||||||
} else if (!item->relative_mouse) {
|
} else if (!item->relative_mouse) {
|
||||||
/* FIXME: Normalize to input device's reported input range (EVIOCGABS) */
|
|
||||||
item->mouse_x = events[i].value;
|
item->mouse_x = events[i].value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -402,7 +403,6 @@ void SDL_EVDEV_Poll(void)
|
||||||
}
|
}
|
||||||
item->touchscreen_data->slots[0].y = events[i].value;
|
item->touchscreen_data->slots[0].y = events[i].value;
|
||||||
} else if (!item->relative_mouse) {
|
} else if (!item->relative_mouse) {
|
||||||
/* FIXME: Normalize to input device's reported input range (EVIOCGABS) */
|
|
||||||
item->mouse_y = events[i].value;
|
item->mouse_y = events[i].value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -448,10 +448,20 @@ void SDL_EVDEV_Poll(void)
|
||||||
switch (events[i].code) {
|
switch (events[i].code) {
|
||||||
case SYN_REPORT:
|
case SYN_REPORT:
|
||||||
/* Send mouse axis changes together to ensure consistency and reduce event processing overhead */
|
/* Send mouse axis changes together to ensure consistency and reduce event processing overhead */
|
||||||
|
if (item->relative_mouse) {
|
||||||
if (item->mouse_x != 0 || item->mouse_y != 0) {
|
if (item->mouse_x != 0 || item->mouse_y != 0) {
|
||||||
SDL_SendMouseMotion(mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, item->mouse_x, item->mouse_y);
|
SDL_SendMouseMotion(mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, item->mouse_x, item->mouse_y);
|
||||||
item->mouse_x = item->mouse_y = 0;
|
item->mouse_x = item->mouse_y = 0;
|
||||||
}
|
}
|
||||||
|
} else if (item->range_x > 0 && item->range_y > 0) {
|
||||||
|
/* TODO: test with multiple display scenarios */
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
SDL_GetCurrentDisplayMode(0, &mode);
|
||||||
|
SDL_SendMouseMotion(mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse,
|
||||||
|
(item->mouse_x - item->min_x) * mode.w / item->range_x,
|
||||||
|
(item->mouse_y - item->min_y) * mode.h / item->range_y);
|
||||||
|
}
|
||||||
|
|
||||||
if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) {
|
if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) {
|
||||||
SDL_SendMouseWheel(mouse->focus, (SDL_MouseID)item->fd,
|
SDL_SendMouseWheel(mouse->focus, (SDL_MouseID)item->fd,
|
||||||
item->mouse_hwheel / (item->high_res_hwheel ? 120.0f : 1.0f),
|
item->mouse_hwheel / (item->high_res_hwheel ? 120.0f : 1.0f),
|
||||||
|
@ -643,6 +653,36 @@ static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct input_absinfo abs_info;
|
||||||
|
|
||||||
|
if (item->is_touchscreen) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl(item->fd, EVIOCGABS(ABS_X), &abs_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
// no absolute mode info, continue
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
item->min_x = abs_info.minimum;
|
||||||
|
item->max_x = abs_info.maximum;
|
||||||
|
item->range_x = abs_info.maximum - abs_info.minimum;
|
||||||
|
|
||||||
|
ret = ioctl(item->fd, EVIOCGABS(ABS_Y), &abs_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
// no absolute mode info, continue
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
item->min_y = abs_info.minimum;
|
||||||
|
item->max_y = abs_info.maximum;
|
||||||
|
item->range_y = abs_info.maximum - abs_info.minimum;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item *item)
|
static void SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item *item)
|
||||||
{
|
{
|
||||||
if (!item->is_touchscreen) {
|
if (!item->is_touchscreen) {
|
||||||
|
@ -827,6 +867,14 @@ static int SDL_EVDEV_device_added(const char *dev_path, int udev_class)
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
} else if (udev_class & SDL_UDEV_DEVICE_MOUSE) {
|
||||||
|
ret = SDL_EVDEV_init_mouse(item, udev_class);
|
||||||
|
if (ret < 0) {
|
||||||
|
close(item->fd);
|
||||||
|
SDL_free(item->path);
|
||||||
|
SDL_free(item);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_this->last == NULL) {
|
if (_this->last == NULL) {
|
||||||
|
|
Loading…
Reference in a new issue