diff --git a/include/QF/input.h b/include/QF/input.h index 238e342e1..74ce5750b 100644 --- a/include/QF/input.h +++ b/include/QF/input.h @@ -45,6 +45,9 @@ typedef struct in_buttoninfo_s { } in_buttoninfo_t; #ifndef __QFCC__ + +#include + typedef struct { vec3_t angles; vec3_t position; @@ -53,7 +56,14 @@ typedef struct { typedef struct in_driver_s { void (*init) (void *data); void (*shutdown) (void *data); + + // The driver must provide either both or none of add_select and + // chec_select. + void (*add_select) (fd_set *fdset, int *maxfd, void *data); + void (*check_select) (fd_set *fdset, void *data); + // Generally musually exclusive with add_select/check_select void (*process_events) (void *data); + void (*clear_states) (void *data); void (*grab_input) (void *data, int grab); diff --git a/include/evdev/inputlib.h b/include/evdev/inputlib.h index 9e7e35ea5..16f647311 100644 --- a/include/evdev/inputlib.h +++ b/include/evdev/inputlib.h @@ -44,6 +44,8 @@ typedef struct device_s { void (*button_event) (button_t *button, void *data); } device_t; +void inputlib_add_select (fd_set *fdset, int *maxfd); +void inputlib_check_select (fd_set *fdset); int inputlib_check_input (void); void inputlib_close (void); int inputlib_init (void (*dev_add) (device_t *), void (*dev_rem) (device_t *)); diff --git a/libs/input/evdev/inputlib.c b/libs/input/evdev/inputlib.c index d1bf3d06f..3085102b3 100644 --- a/libs/input/evdev/inputlib.c +++ b/libs/input/evdev/inputlib.c @@ -309,6 +309,37 @@ read_device_input (device_t *dev) } } +void +inputlib_add_select (fd_set *fdset, int *maxfd) +{ + inputlib_hotplug_add_select (fdset, maxfd); + + for (device_t *dev = devices; dev; dev = dev->next) { + if (dev->fd < 0) { + continue; + } + FD_SET (dev->fd, fdset); + if (dev->fd > *maxfd) { + *maxfd = dev->fd; + } + } +} + +void +inputlib_check_select (fd_set *fdset) +{ + inputlib_hotplug_check_select (fdset); + + for (device_t *dev = devices; dev; dev = dev->next) { + if (dev->fd < 0) { + continue; + } + if (FD_ISSET (dev->fd, fdset)) { + read_device_input (dev); + } + } +} + int inputlib_check_input (void) { @@ -317,24 +348,13 @@ inputlib_check_input (void) struct timeval *timeout = &_timeout; int res; int maxfd = -1; - device_t *dev; _timeout.tv_sec = 0; _timeout.tv_usec = 0; FD_ZERO (&fdset); - inputlib_hotplug_add_select (&fdset, &maxfd); - - for (dev = devices; dev; dev = dev->next) { - if (dev->fd < 0) { - continue; - } - FD_SET (dev->fd, &fdset); - if (dev->fd > maxfd) { - maxfd = dev->fd; - } - } + inputlib_add_select (&fdset, &maxfd); if (maxfd < 0) { return 0; } @@ -343,16 +363,7 @@ inputlib_check_input (void) return 0; } - inputlib_hotplug_check_select (&fdset); - - for (dev = devices; dev; dev = dev->next) { - if (dev->fd < 0) { - continue; - } - if (FD_ISSET (dev->fd, &fdset)) { - read_device_input (dev); - } - } + inputlib_check_select (&fdset); return 1; } diff --git a/libs/input/in_common.c b/libs/input/in_common.c index fc7f85755..0a90ef7f4 100644 --- a/libs/input/in_common.c +++ b/libs/input/in_common.c @@ -77,6 +77,7 @@ cvar_t *in_mouse_amp; cvar_t *in_mouse_pre_amp; cvar_t *lookstrafe; +int64_t in_timeout = 10000;//10ms default timeout kbutton_t in_mlook, in_klook; kbutton_t in_strafe; kbutton_t in_speed; @@ -265,9 +266,29 @@ IN_UpdateGrab (cvar_t *var) // called from context_*.c void IN_ProcessEvents (void) { + fd_set fdset; + int maxfd = -1; + int64_t timeout = in_timeout; + + FD_ZERO (&fdset); for (size_t i = 0; i < in_drivers.size; i++) { in_regdriver_t *rd = &in_drivers.a[i]; - rd->driver.process_events (rd->data); + if (rd->driver.add_select) { + rd->driver.add_select (&fdset, &maxfd, rd->data); + } + if (rd->driver.process_events) { + rd->driver.process_events (rd->data); + // if a driver can't use select, then we can't block in select + timeout = 0; + } + } + if (maxfd >= 0 && Sys_Select (maxfd, &fdset, timeout) > 0) { + for (size_t i = 0; i < in_drivers.size; i++) { + in_regdriver_t *rd = &in_drivers.a[i]; + if (rd->driver.check_select) { + rd->driver.check_select (&fdset, rd->data); + } + } } } diff --git a/libs/input/in_evdev.c b/libs/input/in_evdev.c index 608dc8682..9eaad7b92 100644 --- a/libs/input/in_evdev.c +++ b/libs/input/in_evdev.c @@ -62,10 +62,15 @@ in_evdev_keydest_callback (keydest_t key_dest, void *data) } static void -in_evdev_process_events (void *data) +in_evdev_add_select (fd_set *fdset, int *maxfd, void *data) { - if (inputlib_check_input ()) { - } + inputlib_add_select (fdset, maxfd); +} + +static void +in_evdev_check_select (fd_set *fdset, void *data) +{ + inputlib_check_select (fdset); } static void @@ -223,7 +228,8 @@ in_evdev_button_info (void *data, void *device, in_buttoninfo_t *buttons, static in_driver_t in_evdev_driver = { .init = in_evdev_init, .shutdown = in_evdev_shutdown, - .process_events = in_evdev_process_events, + .add_select = in_evdev_add_select, + .check_select = in_evdev_check_select, .clear_states = in_evdev_clear_states, .axis_info = in_evdev_axis_info, diff --git a/ruamoko/qwaq/builtins/input.c b/ruamoko/qwaq/builtins/input.c index 5a31d2ffc..316ae8bf3 100644 --- a/ruamoko/qwaq/builtins/input.c +++ b/ruamoko/qwaq/builtins/input.c @@ -464,8 +464,18 @@ term_shutdown (void *_res) { } +#define FD 0 static void -term_process_events (void *_res) +term_add_select (fd_set *fdset, int *maxfd, void *_res) +{ + FD_SET (FD, fdset); + if (*maxfd < FD) { + *maxfd = FD; + } +} + +static void +term_check_select (fd_set *fdset, void *_res) { qwaq_input_resources_t *res = _res; char buf[256]; @@ -482,7 +492,7 @@ term_process_events (void *_res) resize_event (res); } #endif - while (Sys_CheckInput (1, -1)) { + if (FD_ISSET (FD, fdset)) { len = read(0, buf, sizeof (buf)); for (int i = 0; i < len; i++) { process_char (res, buf[i]); @@ -493,7 +503,8 @@ term_process_events (void *_res) static in_driver_t term_driver = { .init = term_init, .shutdown = term_shutdown, - .process_events = term_process_events, + .add_select = term_add_select, + .check_select = term_check_select, }; static int term_driver_handle;