diff --git a/Makefile.common b/Makefile.common index 596e285a55..77eba22261 100644 --- a/Makefile.common +++ b/Makefile.common @@ -2294,6 +2294,10 @@ ifeq ($(HAVE_RPILED), 1) OBJ += led/drivers/led_rpi.o endif +ifneq ($(findstring Win32,$(OS)),) + OBJ += led/drivers/led_keyboard.o +endif + ifeq ($(HAVE_MATH_NEON), 1) DEFINES += -DHAVE_MATH_NEON INCLUDE_DIRS += -I$(DEPS_DIR)/math-neon/source diff --git a/led/drivers/led_keyboard.c b/led/drivers/led_keyboard.c new file mode 100644 index 0000000000..73f4cf896d --- /dev/null +++ b/led/drivers/led_keyboard.c @@ -0,0 +1,153 @@ +#include +#include "../led_driver.h" +#include "../led_defines.h" + +#include "../../configuration.h" +#include "../../retroarch.h" + +#undef MAX_LEDS +#define MAX_LEDS 3 + +#ifdef _WIN32 +#include +#endif + +static void key_translate(int *key) +{ +#ifdef _WIN32 + switch (*key) + { + case RETROK_NUMLOCK: + *key = VK_NUMLOCK; + break; + case RETROK_CAPSLOCK: + *key = VK_CAPITAL; + break; + case RETROK_SCROLLOCK: + *key = VK_SCROLL; + break; + } +#endif +} + +void led_set(int key, int state) +{ +#ifdef _WIN32 + BYTE keyState[256]; +#endif + + key_translate(&key); + +#ifdef _WIN32 + GetKeyboardState((LPBYTE)&keyState); + if ((state && !(keyState[key] & 1)) || + (!state && (keyState[key] & 1))) + { + keybd_event(key, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0); + keybd_event(key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + } +#endif +} + +int led_get(int key) +{ + short status; + key_translate(&key); + +#ifdef _WIN32 + status = GetKeyState(key); +#endif + return status; +} + +typedef struct +{ + int setup[MAX_LEDS]; + int map[MAX_LEDS]; +} keyboard_led_t; + +/* TODO/FIXME - static globals */ +static keyboard_led_t curins; +static keyboard_led_t *cur = &curins; + +static void keyboard_init(void) +{ + int i; + settings_t *settings = config_get_ptr(); + + if (!settings) + return; + + for (i = 0; i < MAX_LEDS; i++) + { + cur->setup[i] = -1; + cur->map[i] = settings->uints.led_map[i]; + if (cur->map[i] < 0) + cur->map[i] = i; + + switch (i) + { + case 0: + cur->setup[i] = led_get(RETROK_NUMLOCK); + break; + case 1: + cur->setup[i] = led_get(RETROK_CAPSLOCK); + break; + case 2: + cur->setup[i] = led_get(RETROK_SCROLLOCK); + break; + } + } +} + +static void keyboard_free(void) +{ + int i; + + for (i = 0; i < MAX_LEDS; i++) + { + if (cur->setup[i] < 0) + continue; + + switch (i) + { + case 0: + led_set(RETROK_NUMLOCK, cur->setup[i]); + break; + case 1: + led_set(RETROK_CAPSLOCK, cur->setup[i]); + break; + case 2: + led_set(RETROK_SCROLLOCK, cur->setup[i]); + break; + } + + cur->setup[i] = -1; + } +} + +static void keyboard_set(int led, int state) +{ + if ((led < 0) || (led >= MAX_LEDS)) + return; + + switch (cur->map[led]) + { + case 0: + led_set(RETROK_NUMLOCK, state); + break; + case 1: + led_set(RETROK_CAPSLOCK, state); + break; + case 2: + led_set(RETROK_SCROLLOCK, state); + break; + } +} + +const led_driver_t keyboard_led_driver = { + keyboard_init, + keyboard_free, + keyboard_set, + "Keyboard" +}; diff --git a/led/led_driver.c b/led/led_driver.c index 3cd4b61fb7..78416664a2 100644 --- a/led/led_driver.c +++ b/led/led_driver.c @@ -44,11 +44,16 @@ void led_driver_init(const char *led_driver) current_led_driver = &overlay_led_driver; #endif -#if HAVE_RPILED +#ifdef HAVE_RPILED if (string_is_equal("rpi", drivername)) current_led_driver = &rpi_led_driver; #endif +#ifdef _WIN32 + if (string_is_equal("keyboard", drivername)) + current_led_driver = &keyboard_led_driver; +#endif + if (current_led_driver) (*current_led_driver->init)(); } diff --git a/led/led_driver.h b/led/led_driver.h index b91e7db0dc..cd04a5cfc0 100644 --- a/led/led_driver.h +++ b/led/led_driver.h @@ -43,6 +43,7 @@ void led_driver_set_led(int led, int value); extern const led_driver_t overlay_led_driver; extern const led_driver_t rpi_led_driver; +extern const led_driver_t keyboard_led_driver; RETRO_END_DECLS