From c76e9137b77301823dd9310f7d1f524062873842 Mon Sep 17 00:00:00 2001 From: Jesse Talavera-Greenberg Date: Wed, 3 Jan 2024 18:20:32 -0500 Subject: [PATCH 01/13] First crack at light sensor support for Linux --- input/common/linux_common.c | 123 +++++++++++++++++++++++++++++++++++- input/common/linux_common.h | 17 +++++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index a29d0561565..fba8c65fc16 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -14,22 +14,38 @@ * If not, see . */ +#include #include - +#include #include +#include +#include #include #include #include #include #include "linux_common.h" +#include "verbosity.h" + +#include + +#define IIO_DEVICES_DIR "/sys/bus/iio/devices" +#define IIO_ILLUMINANCE_SENSOR "in_illuminance_input" /* TODO/FIXME - static globals */ static struct termios old_term, new_term; static long old_kbmd = 0xffff; static bool linux_stdin_claimed = false; +struct linux_illuminance_sensor +{ + /* This is a Linux-specific struct, so we can rely on FILE* here. + I don't want to introduce abstraction where it isn't needed. */ + FILE* file; +}; + void linux_terminal_restore_input(void) { if (old_kbmd == 0xffff) @@ -121,3 +137,108 @@ bool linux_terminal_disable_input(void) return true; } + +linux_illuminance_sensor_t *linux_open_illuminance_sensor() +{ + DIR *devices = opendir(IIO_DEVICES_DIR); + struct dirent *d = NULL; + linux_illuminance_sensor_t *sensor = malloc(sizeof(*sensor)); + + if (!sensor) + goto error; + + if (!devices) + { /* If we couldn't find the IIO device directory... */ + char errmesg[PATH_MAX]; + strerror_r(errno, errmesg, sizeof(errmesg)); + RARCH_ERR("Failed to open " IIO_DEVICES_DIR ": %s\n", errmesg); + goto error; + } + + errno = 0; + for (d = readdir(devices); d != NULL; d = readdir(devices)) + { /* For each IIO device... */ + /* First ensure that the readdir call succeeded... */ + int err = errno; + char pathbuf[PATH_MAX]; + FILE *sensorfile = NULL; + + if (err != 0) + { + char errmesg[PATH_MAX]; + strerror_r(err, errmesg, sizeof(errmesg)); + RARCH_ERR("readdir(" IIO_DEVICES_DIR ") failed: %s\n", errmesg); + goto error; + } + + /* If that worked out, look to see if this device represents an illuminance sensor */ + snprintf(pathbuf, sizeof(pathbuf), IIO_DEVICES_DIR "/%s/" IIO_ILLUMINANCE_SENSOR, d->d_name); + + sensorfile = fopen(pathbuf, "r"); + if (sensorfile != NULL) + { /* If we found an illuminance sensor... */ + sensor->file = sensorfile; + RARCH_LOG("Opened illuminance sensor at %s\n", pathbuf); + goto done; + } + } + +error: + RARCH_ERR("Failed to find an illuminance sensor\n"); + if (devices) + closedir(devices); + + free(sensor); + + return NULL; +done: + if (devices) + closedir(devices); + + return sensor; +} + +void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor) +{ + if (!sensor) + return; + + if (sensor->file) + fclose(sensor->file); + + free(sensor); +} + +float linux_read_illuminance_sensor(linux_illuminance_sensor_t *sensor) +{ + char buffer[256]; + float illuminance = 0.0f; + char errmesg[PATH_MAX]; + int err; + if (!sensor || !sensor->file) + return -1.0f; + + /* The illuminance will always be updated even if the file handle remains open, + * but the seek position won't be reset. + * So we have to do that before each read. */ + rewind(sensor->file); + if (!fgets(buffer, sizeof(buffer), sensor->file)) + { /* Read the illuminance value from the file. If that fails... */ + strerror_r(errno, errmesg, sizeof(errmesg)); + RARCH_ERR("Illuminance sensor read failed: %s\n", errmesg); + return -1.0f; + } + + /* TODO: This may be locale-sensitive */ + errno = 0; + illuminance = strtof(buffer, NULL); + err = errno; + if (err != 0) + { + strerror_r(err, errmesg, sizeof(errmesg)); + RARCH_ERR("Failed to parse input \"%s\" into a floating-point value: %s", buffer, errmesg); + return -1.0f; + } + + return illuminance; +} diff --git a/input/common/linux_common.h b/input/common/linux_common.h index b530b71c433..47919c13c5f 100644 --- a/input/common/linux_common.h +++ b/input/common/linux_common.h @@ -27,4 +27,21 @@ bool linux_terminal_grab_stdin(void *data); bool linux_terminal_disable_input(void); +/** + * Corresponds to the illuminance sensor exposed via the IIO interface. + * @see https://github.com/torvalds/linux/blob/master/Documentation/ABI/testing/sysfs-bus-iio + */ +typedef struct linux_illuminance_sensor linux_illuminance_sensor_t; + +/** + * Iterates through /sys/bus/iio/devices and returns the first illuminance sensor found, + * or NULL if none was found. + */ +linux_illuminance_sensor_t *linux_open_illuminance_sensor(); + +void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor); + +/** Returns the light sensor's reading in lux, or a negative number on error. */ +float linux_read_illuminance_sensor(linux_illuminance_sensor_t *sensor); + #endif From 81bdd73874760ce53cb271181c377dab812100a0 Mon Sep 17 00:00:00 2001 From: Jesse Talavera-Greenberg Date: Wed, 3 Jan 2024 22:00:26 -0500 Subject: [PATCH 02/13] Add light-sensor support to most Linux input drivers --- input/drivers/linuxraw_input.c | 54 ++++++++++++++++++++++-- input/drivers/sdl_input.c | 76 +++++++++++++++++++++++++++++++--- input/drivers/udev_input.c | 54 +++++++++++++++++++++++- input/drivers/x11_input.c | 71 ++++++++++++++++++++++++++----- 4 files changed, 235 insertions(+), 20 deletions(-) diff --git a/input/drivers/linuxraw_input.c b/input/drivers/linuxraw_input.c index 3df3886a1f0..189acdb4a6e 100644 --- a/input/drivers/linuxraw_input.c +++ b/input/drivers/linuxraw_input.c @@ -38,6 +38,7 @@ typedef struct linuxraw_input { bool state[0x80]; + linux_illuminance_sensor_t *illuminance_sensor; } linuxraw_input_t; static void *linuxraw_input_init(const char *joypad_driver) @@ -166,9 +167,56 @@ static void linuxraw_input_free(void *data) return; linux_terminal_restore_input(); + linux_close_illuminance_sensor(linuxraw->illuminance_sensor); free(data); } +static bool linuxraw_input_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned rate) +{ + linuxraw_input_t *linuxraw = (linuxraw_input_t*)data; + + if (!linuxraw) + return false; + + switch (action) + { + case RETRO_SENSOR_ILLUMINANCE_DISABLE: + /* If already disabled, then do nothing */ + linux_close_illuminance_sensor(linuxraw->illuminance_sensor); /* noop if NULL */ + linuxraw->illuminance_sensor = NULL; + case RETRO_SENSOR_GYROSCOPE_DISABLE: + case RETRO_SENSOR_ACCELEROMETER_DISABLE: + /** Unimplemented sensor actions that probably shouldn't fail */ + return true; + + case RETRO_SENSOR_ILLUMINANCE_ENABLE: + if (!linuxraw->illuminance_sensor) + /* If the light sensor isn't already open... */ + linuxraw->illuminance_sensor = linux_open_illuminance_sensor(); + + return linuxraw->illuminance_sensor != NULL; + default: + return false; + } +} + +static float linuxraw_input_get_sensor_input(void *data, unsigned port, unsigned id) +{ + linuxraw_input_t *linuxraw = (linuxraw_input_t*)data; + + if (!linuxraw) + return 0.0f; + + switch (id) + { + case RETRO_SENSOR_ILLUMINANCE: + if (linuxraw->illuminance_sensor) + return linux_read_illuminance_sensor(linuxraw->illuminance_sensor); + default: + return 0.0f; + } +} + static void linuxraw_input_poll(void *data) { uint8_t c; @@ -195,7 +243,7 @@ static void linuxraw_input_poll(void *data) static uint64_t linuxraw_get_capabilities(void *data) { - return (1 << RETRO_DEVICE_JOYPAD) + return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); } @@ -204,8 +252,8 @@ input_driver_t input_linuxraw = { linuxraw_input_poll, linuxraw_input_state, linuxraw_input_free, - NULL, - NULL, + linuxraw_input_set_sensor_state, + linuxraw_input_get_sensor_input, linuxraw_get_capabilities, "linuxraw", NULL, /* grab_mouse */ diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 3774c824212..f3a3b6fd8f1 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -30,6 +30,10 @@ #include "../../retroarch.h" #include "../../tasks/tasks_internal.h" +#ifdef __linux__ +#include "../common/linux_common.h" +#endif + #ifdef HAVE_SDL2 #include "../../gfx/common/sdl2_common.h" #endif @@ -57,6 +61,10 @@ typedef struct sdl_input int mouse_wd; int mouse_wl; int mouse_wr; +#ifdef __linux__ + /* Light sensors aren't exposed through SDL, and they're not usually part of controllers */ + linux_illuminance_sensor_t *illuminance_sensor; +#endif } sdl_input_t; #ifdef WEBOS @@ -238,7 +246,7 @@ static int16_t sdl_input_state( if (idx == 0) { struct video_viewport vp; - bool screen = device == + bool screen = device == RARCH_DEVICE_POINTER_SCREEN; const int edge_detect = 32700; bool inside = false; @@ -264,7 +272,7 @@ static int16_t sdl_input_state( res_y = res_screen_y; } - inside = (res_x >= -edge_detect) + inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect); @@ -326,9 +334,67 @@ static void sdl_input_free(void *data) while (SDL_PollEvent(&event)); #endif +#ifdef __linux__ + linux_close_illuminance_sensor(sdl->illuminance_sensor); /* noop if NULL */ +#endif + free(data); } +static bool sdl_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned rate) +{ + sdl_input_t *sdl = (sdl_input_t*)data; + + if (!sdl) + return false; + + switch (action) + { + case RETRO_SENSOR_ILLUMINANCE_DISABLE: +#ifdef __linux__ + /* If already disabled, then do nothing */ + linux_close_illuminance_sensor(sdl->illuminance_sensor); /* noop if NULL */ + sdl->illuminance_sensor = NULL; +#endif + case RETRO_SENSOR_GYROSCOPE_DISABLE: + case RETRO_SENSOR_ACCELEROMETER_DISABLE: + /** Unimplemented sensor actions that probably shouldn't fail */ + return true; + + case RETRO_SENSOR_ILLUMINANCE_ENABLE: +#ifdef __linux__ + if (!sdl->illuminance_sensor) + /* If the light sensor isn't already open... */ + sdl->illuminance_sensor = linux_open_illuminance_sensor(); + + return sdl->illuminance_sensor != NULL; +#endif + /* Unsupported on non-Linux platforms */ + default: + return false; + } +} + +static float sdl_get_sensor_input(void *data, unsigned port, unsigned id) +{ + sdl_input_t *sdl = (sdl_input_t*)data; + + if (!sdl) + return 0.0f; + + switch (id) + { + case RETRO_SENSOR_ILLUMINANCE: +#ifdef __linux__ + if (sdl->illuminance_sensor) + return linux_read_illuminance_sensor(sdl->illuminance_sensor); +#endif + /* Unsupported on non-Linux platforms */ + default: + return 0.0f; + } +} + #ifdef HAVE_SDL2 static void sdl2_grab_mouse(void *data, bool state) { @@ -387,7 +453,7 @@ static void sdl_input_poll(void *data) switch ((int) event.key.keysym.scancode) { case SDL_WEBOS_SCANCODE_BACK: - /* Because webOS is sending DOWN/UP at the same time, + /* Because webOS is sending DOWN/UP at the same time, we save this flag for later */ sdl_webos_special_keymap[sdl_webos_spkey_back] |= event.type == SDL_KEYDOWN; code = RETROK_BACKSPACE; @@ -463,8 +529,8 @@ input_driver_t input_sdl = { sdl_input_poll, sdl_input_state, sdl_input_free, - NULL, - NULL, + sdl_set_sensor_state, + sdl_get_sensor_input, sdl_get_capabilities, #ifdef HAVE_SDL2 "sdl2", diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index e80c7fb9596..3441ba1342d 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -569,6 +569,8 @@ typedef struct udev_input #ifdef UDEV_XKB_HANDLING bool xkb_handling; #endif + + linux_illuminance_sensor_t *illuminance_sensor; } udev_input_t; #ifdef UDEV_XKB_HANDLING @@ -4026,9 +4028,57 @@ static void udev_input_free(void *data) udev_input_kb_free(udev); + linux_close_illuminance_sensor(udev->illuminance_sensor); + free(udev); } +static bool udev_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned rate) +{ + udev_input_t *udev = (udev_input_t*)data; + + if (!udev) + return false; + + switch (action) + { + case RETRO_SENSOR_ILLUMINANCE_DISABLE: + /* If already disabled, then do nothing */ + linux_close_illuminance_sensor(udev->illuminance_sensor); /* noop if NULL */ + udev->illuminance_sensor = NULL; + case RETRO_SENSOR_GYROSCOPE_DISABLE: + case RETRO_SENSOR_ACCELEROMETER_DISABLE: + /** Unimplemented sensor actions that probably shouldn't fail */ + return true; + + case RETRO_SENSOR_ILLUMINANCE_ENABLE: + if (!udev->illuminance_sensor) + /* If the light sensor isn't already open... */ + udev->illuminance_sensor = linux_open_illuminance_sensor(); + + return udev->illuminance_sensor != NULL; + default: + return false; + } +} + +static float udev_get_sensor_input(void *data, unsigned port, unsigned id) +{ + udev_input_t *udev = (udev_input_t*)data; + + if (!udev) + return 0.0f; + + switch (id) + { + case RETRO_SENSOR_ILLUMINANCE: + if (udev->illuminance_sensor) + return linux_read_illuminance_sensor(udev->illuminance_sensor); + default: + return 0.0f; + } +} + static bool open_devices(udev_input_t *udev, enum udev_input_dev_type type, device_handle_cb cb) { @@ -4240,8 +4290,8 @@ input_driver_t input_udev = { udev_input_poll, udev_input_state, udev_input_free, - NULL, - NULL, + udev_set_sensor_state, + udev_get_sensor_input, udev_input_get_capabilities, "udev", udev_input_grab_mouse, diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index b519beaa242..a2492a6e7f1 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -27,6 +27,7 @@ #include "../input_keymaps.h" #include "../common/input_x11_common.h" +#include "../common/linux_common.h" #include "../../configuration.h" #include "../../retroarch.h" @@ -45,6 +46,7 @@ typedef struct x11_input bool mouse_l; bool mouse_r; bool mouse_m; + linux_illuminance_sensor_t *illuminance_sensor; } x11_input_t; /* Public global variable */ @@ -196,9 +198,9 @@ static int16_t x_input_state( if (binds[port][id].valid) { if ( - ((binds[port][id].key < RETROK_LAST) && - x_keyboard_pressed(x11, binds[port][id].key)) - && (( id == RARCH_GAME_FOCUS_TOGGLE) + ((binds[port][id].key < RETROK_LAST) && + x_keyboard_pressed(x11, binds[port][id].key)) + && (( id == RARCH_GAME_FOCUS_TOGGLE) || !keyboard_mapping_blocked) ) return 1; @@ -347,7 +349,7 @@ static int16_t x_input_state( x11->mouse_x, x11->mouse_y, &res_x, &res_y, &res_screen_x, &res_screen_y)) { - inside = (res_x >= -edge_detect) + inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect); @@ -396,7 +398,7 @@ static int16_t x_input_state( const uint32_t joyaxis = (bind_joyaxis != AXIS_NONE) ? bind_joyaxis : autobind_joyaxis; if (!keyboard_mapping_blocked) - if ((binds[port][new_id].key < RETROK_LAST) + if ((binds[port][new_id].key < RETROK_LAST) && x_keyboard_pressed(x11, binds[port] [new_id].key) ) return 1; @@ -406,7 +408,7 @@ static int16_t x_input_state( joyport, (uint16_t)joykey)) return 1; if (joyaxis != AXIS_NONE && - ((float)abs(joypad->axis(joyport, joyaxis)) + ((float)abs(joypad->axis(joyport, joyaxis)) / 0x8000) > axis_threshold) return 1; else if (settings->uints.input_mouse_index[port] == 0) @@ -436,7 +438,56 @@ static void x_input_free(void *data) x11_input_t *x11 = (x11_input_t*)data; if (x11) + { + linux_close_illuminance_sensor(x11->illuminance_sensor); free(x11); + } +} + +static bool x_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned rate) +{ + x11_input_t *x11 = (x11_input_t*)data; + + if (!x11) + return false; + + switch (action) + { + case RETRO_SENSOR_ILLUMINANCE_DISABLE: + /* If already disabled, then do nothing */ + linux_close_illuminance_sensor(x11->illuminance_sensor); /* noop if NULL */ + x11->illuminance_sensor = NULL; + case RETRO_SENSOR_GYROSCOPE_DISABLE: + case RETRO_SENSOR_ACCELEROMETER_DISABLE: + /** Unimplemented sensor actions that probably shouldn't fail */ + return true; + + case RETRO_SENSOR_ILLUMINANCE_ENABLE: + if (!x11->illuminance_sensor) + /* If the light sensor isn't already open... */ + x11->illuminance_sensor = linux_open_illuminance_sensor(); + + return x11->illuminance_sensor != NULL; + default: + return false; + } +} + +static float x_get_sensor_input(void *data, unsigned port, unsigned id) +{ + x11_input_t *x11 = (x11_input_t*)data; + + if (!x11) + return 0.0f; + + switch (id) + { + case RETRO_SENSOR_ILLUMINANCE: + if (x11->illuminance_sensor) + return linux_read_illuminance_sensor(x11->illuminance_sensor); + default: + return 0.0f; + } } static void x_input_poll(void *data) @@ -542,13 +593,13 @@ static void x_input_poll(void *data) x11->mouse_y += x11->mouse_delta_y; /* Clamp X */ - if (x11->mouse_x < 0) + if (x11->mouse_x < 0) x11->mouse_x = 0; if (x11->mouse_x >= win_attr.width) x11->mouse_x = (win_attr.width - 1); /* Clamp Y */ - if (x11->mouse_y < 0) + if (x11->mouse_y < 0) x11->mouse_y = 0; if (x11->mouse_y >= win_attr.height) x11->mouse_y = (win_attr.height - 1); @@ -608,8 +659,8 @@ input_driver_t input_x = { x_input_poll, x_input_state, x_input_free, - NULL, - NULL, + x_set_sensor_state, + x_get_sensor_input, x_input_get_capabilities, "x", x_grab_mouse, From c063422c9b4373af11aa86dafb8276792390dc39 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Thu, 24 Oct 2024 17:24:01 -0400 Subject: [PATCH 03/13] Fix a compiler error - Whoops, forgot to declare `sdl` --- input/drivers/sdl_input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 7ec0f9d85b2..480a2a51dfb 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -333,6 +333,7 @@ static void sdl_input_free(void *data) #ifndef HAVE_SDL2 SDL_Event event; #endif + sdl_input_t *sdl = (sdl_input_t*)data; if (!data) return; From 23fa651e7d93207578702cc5224916a3cbbe1857 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Sun, 24 Nov 2024 22:33:10 -0500 Subject: [PATCH 04/13] Refactor linux_illuminance_sensor_t - Allow the poll rate to be specified - Poll the sensor on a separate thread - Open a file handle each time we poll the sensor, since sysfs doesn't update the contents of an existing handle --- input/common/linux_common.c | 150 +++++++++++++++++++++++++++------ input/common/linux_common.h | 10 ++- input/drivers/linuxraw_input.c | 10 ++- input/drivers/sdl_input.c | 10 ++- input/drivers/udev_input.c | 10 ++- input/drivers/x11_input.c | 27 +++++- 6 files changed, 170 insertions(+), 47 deletions(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index fba8c65fc16..abc9f0b4bfd 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -28,11 +28,15 @@ #include "linux_common.h" #include "verbosity.h" +#include +#include +#include #include #define IIO_DEVICES_DIR "/sys/bus/iio/devices" #define IIO_ILLUMINANCE_SENSOR "in_illuminance_input" +#define DEFAULT_POLL_RATE 5 /* TODO/FIXME - static globals */ static struct termios old_term, new_term; @@ -41,10 +45,23 @@ static bool linux_stdin_claimed = false; struct linux_illuminance_sensor { - /* This is a Linux-specific struct, so we can rely on FILE* here. - I don't want to introduce abstraction where it isn't needed. */ - FILE* file; + sthread_t *thread; + + /* Poll rate in Hz (i.e. in queries per second) */ + volatile unsigned poll_rate; + + /* We store the lux reading in millilux (as an int) + * so that we can make the access atomic and avoid locks. + * A little bit of precision is lost, but not enough to matter. + */ + volatile int millilux; + + /* If true, the associated thread must finish its work and exit. */ + volatile bool done; + + char path[PATH_MAX]; }; +static double linux_read_illuminance_sensor(const linux_illuminance_sensor_t *sensor); void linux_terminal_restore_input(void) { @@ -138,7 +155,27 @@ bool linux_terminal_disable_input(void) return true; } -linux_illuminance_sensor_t *linux_open_illuminance_sensor() +static void linux_poll_illuminance_sensor(void *data) +{ + linux_illuminance_sensor_t *sensor = data; + + if (!data) + return; + + while (!sensor->done) + { /* Aligned int reads are atomic on most CPUs */ + double lux = linux_read_illuminance_sensor(sensor); + int millilux = (int)(lux * 1000.0); + unsigned poll_rate = sensor->poll_rate; + retro_assert(poll_rate != 0); + + sensor->millilux = millilux; + + retro_sleep(1000 / poll_rate); + } +} + +linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) { DIR *devices = opendir(IIO_DEVICES_DIR); struct dirent *d = NULL; @@ -147,6 +184,11 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor() if (!sensor) goto error; + sensor->millilux = 0; + sensor->poll_rate = rate ? rate : DEFAULT_POLL_RATE; + sensor->thread = NULL; /* We'll spawn a thread later, once we find a sensor */ + sensor->done = false; + if (!devices) { /* If we couldn't find the IIO device directory... */ char errmesg[PATH_MAX]; @@ -155,13 +197,19 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor() goto error; } + /* + * Must clear errno at the start of each iteration, + * as an error code that came from one run of the loop + * can leak into the next iteration and hide serious errors. + * (Ex: trying to open a file that doesn't exist, + * which we handle here.) + */ errno = 0; - for (d = readdir(devices); d != NULL; d = readdir(devices)) + for (d = readdir(devices); d != NULL; errno = 0, d = readdir(devices)) { /* For each IIO device... */ /* First ensure that the readdir call succeeded... */ int err = errno; - char pathbuf[PATH_MAX]; - FILE *sensorfile = NULL; + double lux; if (err != 0) { @@ -172,13 +220,22 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor() } /* If that worked out, look to see if this device represents an illuminance sensor */ - snprintf(pathbuf, sizeof(pathbuf), IIO_DEVICES_DIR "/%s/" IIO_ILLUMINANCE_SENSOR, d->d_name); + snprintf(sensor->path, sizeof(sensor->path), IIO_DEVICES_DIR "/%s/" IIO_ILLUMINANCE_SENSOR, d->d_name); + + lux = linux_read_illuminance_sensor(sensor); + if (lux > 0) + { /* If we found an illuminance sensor that works... */ + sensor->millilux = (int)(lux * 1000.0); /* Set the first reading */ + sensor->thread = sthread_create(linux_poll_illuminance_sensor, sensor); + + if (!sensor->thread) + { + RARCH_ERR("Failed to spawn thread for illuminance sensor\n"); + goto error; + } + + RARCH_LOG("Opened illuminance sensor at %s, polling at %u Hz\n", sensor->path, sensor->poll_rate); - sensorfile = fopen(pathbuf, "r"); - if (sensorfile != NULL) - { /* If we found an illuminance sensor... */ - sensor->file = sensorfile; - RARCH_LOG("Opened illuminance sensor at %s\n", pathbuf); goto done; } } @@ -203,42 +260,79 @@ void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor) if (!sensor) return; - if (sensor->file) - fclose(sensor->file); + if (sensor->thread) + sthread_join(sensor->thread); + /* sthread_join will free the thread */ free(sensor); } -float linux_read_illuminance_sensor(linux_illuminance_sensor_t *sensor) +float linux_get_illuminance_reading(const linux_illuminance_sensor_t *sensor) +{ + int millilux; + if (!sensor) + return -1.0f; + + /* Reading an int is atomic on most CPUs */ + millilux = sensor->millilux; + + return (float)millilux / 1000.0f; +} + + +void linux_set_illuminance_sensor_rate(linux_illuminance_sensor_t *sensor, unsigned rate) +{ + if (!sensor) + return; + + sensor->poll_rate = rate; +} + +static double linux_read_illuminance_sensor(const linux_illuminance_sensor_t *sensor) { char buffer[256]; - float illuminance = 0.0f; - char errmesg[PATH_MAX]; + double illuminance = 0.0; int err; - if (!sensor || !sensor->file) - return -1.0f; + FILE* in_illuminance_input = NULL; + + if (!sensor || sensor->path[0] == '\0') + return -1.0; - /* The illuminance will always be updated even if the file handle remains open, - * but the seek position won't be reset. - * So we have to do that before each read. */ - rewind(sensor->file); - if (!fgets(buffer, sizeof(buffer), sensor->file)) + in_illuminance_input = fopen(sensor->path, "r"); + if (!in_illuminance_input) + { + char errmesg[PATH_MAX]; + strerror_r(errno, errmesg, sizeof(errmesg)); + RARCH_ERR("Failed to open %s: %s\n", sensor->path, errmesg); + illuminance = -1.0; + goto done; + } + + if (!fgets(buffer, sizeof(buffer), in_illuminance_input)) { /* Read the illuminance value from the file. If that fails... */ + char errmesg[PATH_MAX]; strerror_r(errno, errmesg, sizeof(errmesg)); RARCH_ERR("Illuminance sensor read failed: %s\n", errmesg); - return -1.0f; + illuminance = -1.0; + goto done; } /* TODO: This may be locale-sensitive */ errno = 0; - illuminance = strtof(buffer, NULL); + illuminance = strtod(buffer, NULL); err = errno; if (err != 0) { + char errmesg[PATH_MAX]; strerror_r(err, errmesg, sizeof(errmesg)); RARCH_ERR("Failed to parse input \"%s\" into a floating-point value: %s", buffer, errmesg); - return -1.0f; + illuminance = -1.0; + goto done; } +done: + if (in_illuminance_input) + fclose(in_illuminance_input); + return illuminance; } diff --git a/input/common/linux_common.h b/input/common/linux_common.h index 47919c13c5f..3b3df499d8f 100644 --- a/input/common/linux_common.h +++ b/input/common/linux_common.h @@ -36,12 +36,16 @@ typedef struct linux_illuminance_sensor linux_illuminance_sensor_t; /** * Iterates through /sys/bus/iio/devices and returns the first illuminance sensor found, * or NULL if none was found. + * + * @param rate The rate at which to poll the sensor, in Hz. */ -linux_illuminance_sensor_t *linux_open_illuminance_sensor(); +linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate); void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor); -/** Returns the light sensor's reading in lux, or a negative number on error. */ -float linux_read_illuminance_sensor(linux_illuminance_sensor_t *sensor); +/** Returns the light sensor's most recent reading in lux, or a negative number on error. */ +float linux_get_illuminance_reading(const linux_illuminance_sensor_t *sensor); + +void linux_set_illuminance_sensor_rate(linux_illuminance_sensor_t *sensor, unsigned rate); #endif diff --git a/input/drivers/linuxraw_input.c b/input/drivers/linuxraw_input.c index 14e65abebbf..3acb718c9f5 100644 --- a/input/drivers/linuxraw_input.c +++ b/input/drivers/linuxraw_input.c @@ -189,9 +189,11 @@ static bool linuxraw_input_set_sensor_state(void *data, unsigned port, enum retr return true; case RETRO_SENSOR_ILLUMINANCE_ENABLE: - if (!linuxraw->illuminance_sensor) - /* If the light sensor isn't already open... */ - linuxraw->illuminance_sensor = linux_open_illuminance_sensor(); + if (linuxraw->illuminance_sensor) + /* If the light sensor is already open, just set the rate */ + linux_set_illuminance_sensor_rate(linuxraw->illuminance_sensor, rate); + else + linuxraw->illuminance_sensor = linux_open_illuminance_sensor(rate); return linuxraw->illuminance_sensor != NULL; default: @@ -210,7 +212,7 @@ static float linuxraw_input_get_sensor_input(void *data, unsigned port, unsigned { case RETRO_SENSOR_ILLUMINANCE: if (linuxraw->illuminance_sensor) - return linux_read_illuminance_sensor(linuxraw->illuminance_sensor); + return linux_get_illuminance_reading(linuxraw->illuminance_sensor); default: return 0.0f; } diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 480a2a51dfb..70d7f8e7216 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -374,9 +374,11 @@ static bool sdl_set_sensor_state(void *data, unsigned port, enum retro_sensor_ac case RETRO_SENSOR_ILLUMINANCE_ENABLE: #ifdef __linux__ - if (!sdl->illuminance_sensor) - /* If the light sensor isn't already open... */ - sdl->illuminance_sensor = linux_open_illuminance_sensor(); + if (sdl->illuminance_sensor) + /* If we already have a sensor, just set the rate */ + linux_set_illuminance_sensor_rate(sdl->illuminance_sensor, rate); + else + sdl->illuminance_sensor = linux_open_illuminance_sensor(rate); return sdl->illuminance_sensor != NULL; #endif @@ -398,7 +400,7 @@ static float sdl_get_sensor_input(void *data, unsigned port, unsigned id) case RETRO_SENSOR_ILLUMINANCE: #ifdef __linux__ if (sdl->illuminance_sensor) - return linux_read_illuminance_sensor(sdl->illuminance_sensor); + return linux_get_illuminance_reading(sdl->illuminance_sensor); #endif /* Unsupported on non-Linux platforms */ default: diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index 4cf56a6bcc6..4c2b1416f76 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -4039,9 +4039,11 @@ static bool udev_set_sensor_state(void *data, unsigned port, enum retro_sensor_a return true; case RETRO_SENSOR_ILLUMINANCE_ENABLE: - if (!udev->illuminance_sensor) - /* If the light sensor isn't already open... */ - udev->illuminance_sensor = linux_open_illuminance_sensor(); + if (udev->illuminance_sensor) + /* If we already have a sensor, just set the rate */ + linux_set_illuminance_sensor_rate(udev->illuminance_sensor, rate); + else + udev->illuminance_sensor = linux_open_illuminance_sensor(rate); return udev->illuminance_sensor != NULL; default: @@ -4060,7 +4062,7 @@ static float udev_get_sensor_input(void *data, unsigned port, unsigned id) { case RETRO_SENSOR_ILLUMINANCE: if (udev->illuminance_sensor) - return linux_read_illuminance_sensor(udev->illuminance_sensor); + return linux_get_illuminance_reading(udev->illuminance_sensor); default: return 0.0f; } diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index e7638bfb770..33fcf0dd6cb 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -46,7 +46,10 @@ typedef struct x11_input bool mouse_l; bool mouse_r; bool mouse_m; +#ifdef __linux__ + /* X11 is mostly used on Linux, but not exclusively. */ linux_illuminance_sensor_t *illuminance_sensor; +#endif } x11_input_t; /* Public global variable */ @@ -434,7 +437,9 @@ static void x_input_free(void *data) if (x11) { +#ifdef __linux__ linux_close_illuminance_sensor(x11->illuminance_sensor); +#endif free(x11); } } @@ -450,19 +455,25 @@ static bool x_set_sensor_state(void *data, unsigned port, enum retro_sensor_acti { case RETRO_SENSOR_ILLUMINANCE_DISABLE: /* If already disabled, then do nothing */ +#ifdef __linux__ linux_close_illuminance_sensor(x11->illuminance_sensor); /* noop if NULL */ x11->illuminance_sensor = NULL; +#endif case RETRO_SENSOR_GYROSCOPE_DISABLE: case RETRO_SENSOR_ACCELEROMETER_DISABLE: /** Unimplemented sensor actions that probably shouldn't fail */ return true; +#ifdef __linux__ case RETRO_SENSOR_ILLUMINANCE_ENABLE: - if (!x11->illuminance_sensor) - /* If the light sensor isn't already open... */ - x11->illuminance_sensor = linux_open_illuminance_sensor(); + if (x11->illuminance_sensor) + /* If we already have a sensor, just set the rate */ + linux_set_illuminance_sensor_rate(x11->illuminance_sensor, rate); + else + x11->illuminance_sensor = linux_open_illuminance_sensor(rate); return x11->illuminance_sensor != NULL; +#endif default: return false; } @@ -477,9 +488,11 @@ static float x_get_sensor_input(void *data, unsigned port, unsigned id) switch (id) { +#ifdef __linux__ case RETRO_SENSOR_ILLUMINANCE: if (x11->illuminance_sensor) - return linux_read_illuminance_sensor(x11->illuminance_sensor); + return linux_get_illuminance_reading(x11->illuminance_sensor); +#endif default: return 0.0f; } @@ -655,8 +668,14 @@ input_driver_t input_x = { x_input_poll, x_input_state, x_input_free, +#ifdef __linux__ + /* Right now this driver only supports the illuminance sensor on Linux. */ x_set_sensor_state, x_get_sensor_input, +#else + NULL, + NULL, +#endif x_input_get_capabilities, "x", x_grab_mouse, From 371b87e808c1d858e74ff0120b422e6368245d1a Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Mon, 25 Nov 2024 17:03:18 -0500 Subject: [PATCH 05/13] Set the `done` flag when closing the light sensor - Whoops --- input/common/linux_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index abc9f0b4bfd..c28de5c4261 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -261,8 +261,11 @@ void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor) return; if (sensor->thread) + { + sensor->done = true; sthread_join(sensor->thread); - /* sthread_join will free the thread */ + /* sthread_join will free the thread */ + } free(sensor); } From e5a688a2ad8231e9e82e163a5920dde699a05473 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Mon, 25 Nov 2024 17:41:47 -0500 Subject: [PATCH 06/13] Avoid a division by zero when updating the poll rate of an existing sensor --- input/common/linux_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index c28de5c4261..a3c6d82b085 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -288,6 +288,9 @@ void linux_set_illuminance_sensor_rate(linux_illuminance_sensor_t *sensor, unsig if (!sensor) return; + /* Set a default rate of 5 Hz if none is provided */ + rate = rate ? rate : DEFAULT_POLL_RATE; + sensor->poll_rate = rate; } From cf20f9c2aa4d9cf55ebb0c6593f1afdabfb3ee5e Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 29 Nov 2024 14:44:08 -0500 Subject: [PATCH 07/13] Don't try to open illuminance sensors from ".", "..", or hidden files --- input/common/linux_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index a3c6d82b085..706f7ad77e0 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -219,6 +219,10 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) goto error; } + if (d->d_name[0] == '.') + /* Skip hidden files, ".", and ".." */ + continue; + /* If that worked out, look to see if this device represents an illuminance sensor */ snprintf(sensor->path, sizeof(sensor->path), IIO_DEVICES_DIR "/%s/" IIO_ILLUMINANCE_SENSOR, d->d_name); From bd6a58bc5473f9278b5122ca7d4f3c8f3051b3ad Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 29 Nov 2024 20:41:26 -0500 Subject: [PATCH 08/13] Never mind --- input/common/linux_common.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index 706f7ad77e0..a3c6d82b085 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -219,10 +219,6 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) goto error; } - if (d->d_name[0] == '.') - /* Skip hidden files, ".", and ".." */ - continue; - /* If that worked out, look to see if this device represents an illuminance sensor */ snprintf(sensor->path, sizeof(sensor->path), IIO_DEVICES_DIR "/%s/" IIO_ILLUMINANCE_SENSOR, d->d_name); From dd19882b858f98c086b046763573ff4a19959add Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 29 Nov 2024 21:02:53 -0500 Subject: [PATCH 09/13] Fix some silly mistakes --- input/common/linux_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index a3c6d82b085..a4417926ab0 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -177,7 +177,7 @@ static void linux_poll_illuminance_sensor(void *data) linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) { - DIR *devices = opendir(IIO_DEVICES_DIR); + DIR *devices = NULL; struct dirent *d = NULL; linux_illuminance_sensor_t *sensor = malloc(sizeof(*sensor)); @@ -189,6 +189,7 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) sensor->thread = NULL; /* We'll spawn a thread later, once we find a sensor */ sensor->done = false; + devices = opendir(IIO_DEVICES_DIR); if (!devices) { /* If we couldn't find the IIO device directory... */ char errmesg[PATH_MAX]; @@ -223,7 +224,7 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) snprintf(sensor->path, sizeof(sensor->path), IIO_DEVICES_DIR "/%s/" IIO_ILLUMINANCE_SENSOR, d->d_name); lux = linux_read_illuminance_sensor(sensor); - if (lux > 0) + if (lux >= 0) { /* If we found an illuminance sensor that works... */ sensor->millilux = (int)(lux * 1000.0); /* Set the first reading */ sensor->thread = sthread_create(linux_poll_illuminance_sensor, sensor); From 676afb27d6696139a46ddbefb5c1e6ffa661abbb Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 29 Nov 2024 21:49:55 -0500 Subject: [PATCH 10/13] Skip hidden files, ".", and ".." --- input/common/linux_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index a4417926ab0..b357e69a067 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -212,6 +212,10 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) int err = errno; double lux; + if (d->d_name[0] == '.') + /* Skip hidden files, ".", and ".." */ + continue; + if (err != 0) { char errmesg[PATH_MAX]; From 465a990c97941380f1b88e86bac368026d5bf4ba Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 29 Nov 2024 22:04:25 -0500 Subject: [PATCH 11/13] Cancel the sensor poll thread mid-sleep when closing it - POSIX says it's fine --- input/common/linux_common.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index b357e69a067..b8e10672782 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -32,6 +32,8 @@ #include #include +/* We can assume that pthreads are available on Linux. */ +#include #include #define IIO_DEVICES_DIR "/sys/bus/iio/devices" @@ -164,15 +166,31 @@ static void linux_poll_illuminance_sensor(void *data) while (!sensor->done) { /* Aligned int reads are atomic on most CPUs */ - double lux = linux_read_illuminance_sensor(sensor); - int millilux = (int)(lux * 1000.0); + double lux; + int millilux; unsigned poll_rate = sensor->poll_rate; + + /* Don't allow cancellation inside the critical section, + * as it opens up a file; we don't want to leak it! */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + lux = linux_read_illuminance_sensor(sensor); + millilux = (int)(lux * 1000.0); retro_assert(poll_rate != 0); sensor->millilux = millilux; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + /* Allow cancellation here so that the main thread doesn't block + * while waiting for this thread to wake up and exit. */ retro_sleep(1000 / poll_rate); + if (errno == EINTR) + { + RARCH_ERR("Illuminance sensor thread interrupted\n"); + break; + } } + + RARCH_DBG("Illuminance sensor thread for %s exiting\n", sensor->path); } linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) @@ -267,7 +285,17 @@ void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor) if (sensor->thread) { + pthread_t thread = sthread_get_thread_id(sensor->thread); sensor->done = true; + + if (pthread_cancel(thread) != 0) + { + int err = errno; + char errmesg[PATH_MAX]; + strerror_r(err, errmesg, sizeof(errmesg)); + RARCH_ERR("Failed to cancel illuminance sensor thread: %s\n", errmesg); + } + sthread_join(sensor->thread); /* sthread_join will free the thread */ } From bdefdc428f884a677fa03c0e57ffc50a77071ddb Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 29 Nov 2024 22:07:25 -0500 Subject: [PATCH 12/13] Add to CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 55bf4046901..87fea157f7f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,7 @@ - INPUT: Enable Caps, Num, Scroll Lock modifiers on multiple platforms - INPUT: Autoconfig extension with alternative name/vid/pid - INPUT/HID: Fix crash on macOS when disconnecting the controller a second time +- INPUT/LINUX: Add illuminance sensor support to the linuxraw, sdl2, udev, and x11 input drivers - INPUT/Remaps: Sort and apply remaps based on the specific connected controller - INPUT/UDEV: Enable mouse buttons 4 and 5 - INPUT/WAYLAND: Enable horizontal scroll and mouse buttons 4 and 5 From 4988dc2eb2a809229c8e77ae8443b8ee056bf7f7 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Sun, 1 Dec 2024 18:15:00 -0500 Subject: [PATCH 13/13] Address feedback given on PR --- input/common/linux_common.c | 14 +++++++------- input/drivers/linuxraw_input.c | 8 ++++++-- input/drivers/sdl_input.c | 10 +++++++--- input/drivers/udev_input.c | 8 ++++++-- input/drivers/x11_input.c | 8 ++++++-- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/input/common/linux_common.c b/input/common/linux_common.c index b8e10672782..784da46f860 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -61,7 +61,7 @@ struct linux_illuminance_sensor /* If true, the associated thread must finish its work and exit. */ volatile bool done; - char path[PATH_MAX]; + char path[PATH_MAX_LENGTH]; }; static double linux_read_illuminance_sensor(const linux_illuminance_sensor_t *sensor); @@ -210,7 +210,7 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) devices = opendir(IIO_DEVICES_DIR); if (!devices) { /* If we couldn't find the IIO device directory... */ - char errmesg[PATH_MAX]; + char errmesg[NAME_MAX_LENGTH]; strerror_r(errno, errmesg, sizeof(errmesg)); RARCH_ERR("Failed to open " IIO_DEVICES_DIR ": %s\n", errmesg); goto error; @@ -236,7 +236,7 @@ linux_illuminance_sensor_t *linux_open_illuminance_sensor(unsigned rate) if (err != 0) { - char errmesg[PATH_MAX]; + char errmesg[NAME_MAX_LENGTH]; strerror_r(err, errmesg, sizeof(errmesg)); RARCH_ERR("readdir(" IIO_DEVICES_DIR ") failed: %s\n", errmesg); goto error; @@ -291,7 +291,7 @@ void linux_close_illuminance_sensor(linux_illuminance_sensor_t *sensor) if (pthread_cancel(thread) != 0) { int err = errno; - char errmesg[PATH_MAX]; + char errmesg[NAME_MAX_LENGTH]; strerror_r(err, errmesg, sizeof(errmesg)); RARCH_ERR("Failed to cancel illuminance sensor thread: %s\n", errmesg); } @@ -340,7 +340,7 @@ static double linux_read_illuminance_sensor(const linux_illuminance_sensor_t *se in_illuminance_input = fopen(sensor->path, "r"); if (!in_illuminance_input) { - char errmesg[PATH_MAX]; + char errmesg[NAME_MAX_LENGTH]; strerror_r(errno, errmesg, sizeof(errmesg)); RARCH_ERR("Failed to open %s: %s\n", sensor->path, errmesg); illuminance = -1.0; @@ -349,7 +349,7 @@ static double linux_read_illuminance_sensor(const linux_illuminance_sensor_t *se if (!fgets(buffer, sizeof(buffer), in_illuminance_input)) { /* Read the illuminance value from the file. If that fails... */ - char errmesg[PATH_MAX]; + char errmesg[NAME_MAX_LENGTH]; strerror_r(errno, errmesg, sizeof(errmesg)); RARCH_ERR("Illuminance sensor read failed: %s\n", errmesg); illuminance = -1.0; @@ -362,7 +362,7 @@ static double linux_read_illuminance_sensor(const linux_illuminance_sensor_t *se err = errno; if (err != 0) { - char errmesg[PATH_MAX]; + char errmesg[NAME_MAX_LENGTH]; strerror_r(err, errmesg, sizeof(errmesg)); RARCH_ERR("Failed to parse input \"%s\" into a floating-point value: %s", buffer, errmesg); illuminance = -1.0; diff --git a/input/drivers/linuxraw_input.c b/input/drivers/linuxraw_input.c index 3acb718c9f5..1788c1f283c 100644 --- a/input/drivers/linuxraw_input.c +++ b/input/drivers/linuxraw_input.c @@ -197,8 +197,10 @@ static bool linuxraw_input_set_sensor_state(void *data, unsigned port, enum retr return linuxraw->illuminance_sensor != NULL; default: - return false; + break; } + + return false; } static float linuxraw_input_get_sensor_input(void *data, unsigned port, unsigned id) @@ -214,8 +216,10 @@ static float linuxraw_input_get_sensor_input(void *data, unsigned port, unsigned if (linuxraw->illuminance_sensor) return linux_get_illuminance_reading(linuxraw->illuminance_sensor); default: - return 0.0f; + break; } + + return 0.0f; } static void linuxraw_input_poll(void *data) diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 70d7f8e7216..83c9419fe32 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -374,6 +374,7 @@ static bool sdl_set_sensor_state(void *data, unsigned port, enum retro_sensor_ac case RETRO_SENSOR_ILLUMINANCE_ENABLE: #ifdef __linux__ + /* Unsupported on non-Linux platforms */ if (sdl->illuminance_sensor) /* If we already have a sensor, just set the rate */ linux_set_illuminance_sensor_rate(sdl->illuminance_sensor, rate); @@ -382,10 +383,11 @@ static bool sdl_set_sensor_state(void *data, unsigned port, enum retro_sensor_ac return sdl->illuminance_sensor != NULL; #endif - /* Unsupported on non-Linux platforms */ default: - return false; + break; } + + return false; } static float sdl_get_sensor_input(void *data, unsigned port, unsigned id) @@ -404,8 +406,10 @@ static float sdl_get_sensor_input(void *data, unsigned port, unsigned id) #endif /* Unsupported on non-Linux platforms */ default: - return 0.0f; + break; } + + return 0.0f; } #ifdef HAVE_SDL2 diff --git a/input/drivers/udev_input.c b/input/drivers/udev_input.c index 4c2b1416f76..bfa5f6afabc 100644 --- a/input/drivers/udev_input.c +++ b/input/drivers/udev_input.c @@ -4047,8 +4047,10 @@ static bool udev_set_sensor_state(void *data, unsigned port, enum retro_sensor_a return udev->illuminance_sensor != NULL; default: - return false; + break; } + + return false; } static float udev_get_sensor_input(void *data, unsigned port, unsigned id) @@ -4064,8 +4066,10 @@ static float udev_get_sensor_input(void *data, unsigned port, unsigned id) if (udev->illuminance_sensor) return linux_get_illuminance_reading(udev->illuminance_sensor); default: - return 0.0f; + break; } + + return 0.0f; } static bool open_devices(udev_input_t *udev, diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index 33fcf0dd6cb..8c6bcad13f3 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -475,8 +475,10 @@ static bool x_set_sensor_state(void *data, unsigned port, enum retro_sensor_acti return x11->illuminance_sensor != NULL; #endif default: - return false; + break; } + + return false; } static float x_get_sensor_input(void *data, unsigned port, unsigned id) @@ -494,8 +496,10 @@ static float x_get_sensor_input(void *data, unsigned port, unsigned id) return linux_get_illuminance_reading(x11->illuminance_sensor); #endif default: - return 0.0f; + break; } + + return 0.0f; } static void x_input_poll(void *data)