diff --git a/Makefile b/Makefile index c37ecb1876..0df3f12180 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ OBJ = frontend/frontend.o \ rewind.o \ gfx/gfx_common.o \ input/input_common.o \ + input/keyboard_line.o \ input/overlay.o \ patch.o \ fifo_buffer.o \ diff --git a/Makefile.win b/Makefile.win index c661001431..6b5d3168e9 100644 --- a/Makefile.win +++ b/Makefile.win @@ -17,6 +17,7 @@ OBJ = frontend/frontend.o \ movie.o \ gfx/gfx_common.o \ input/input_common.o \ + input/keyboard_line.o \ input/autoconf/builtin_win.o \ core_options.o \ patch.o \ diff --git a/compat/compat.c b/compat/compat.c index b1ed3dd547..469ec6e228 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -202,6 +202,39 @@ int getopt_long(int argc, char *argv[], #endif +#ifndef HAVE_STRCASESTR +// Pretty much strncasecmp. +static int casencmp(const char *a, const char *b, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + { + int a_lower = tolower(a[i]); + int b_lower = tolower(b[i]); + if (a_lower != b_lower) + return a_lower - b_lower; + } + + return 0; +} + +char *strcasestr_rarch__(const char *haystack, const char *needle) +{ + size_t i; + size_t hay_len = strlen(haystack); + size_t needle_len = strlen(needle); + if (needle_len > hay_len) + return NULL; + + size_t search_off = hay_len - needle_len; + for (i = 0; i <= search_off; i++) + if (!casencmp(haystack + i, needle, needle_len)) + return (char*)haystack + i; + + return NULL; +} +#endif + #ifndef HAVE_STRL // Implementation of strlcpy()/strlcat() based on OpenBSD. diff --git a/compat/strcasestr.h b/compat/strcasestr.h new file mode 100644 index 0000000000..7bd9113326 --- /dev/null +++ b/compat/strcasestr.h @@ -0,0 +1,40 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef RARCH_STRCASESTR_H +#define RARCH_STRCASESTR_H + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_STRCASESTR + +#ifdef __cplusplus +extern "C" { +#endif +// Avoid possible naming collisions during link since we prefer to use the actual name. +#define strcasestr(haystack, needle) strcasestr_rarch__(haystack, needle) + +char *strcasestr(const char *haystack, const char *needle); +#ifdef __cplusplus +} +#endif +#endif + +#endif + diff --git a/driver.h b/driver.h index d3c1396e54..4791dcb004 100644 --- a/driver.h +++ b/driver.h @@ -492,6 +492,7 @@ typedef struct driver #endif bool stdin_claimed; bool block_hotkey; + bool block_input; bool nonblock_state; // Opaque handles to currently running window. diff --git a/file_list.c b/file_list.c index b241e5ecff..9a62c881f0 100644 --- a/file_list.c +++ b/file_list.c @@ -17,6 +17,7 @@ #include #include #include "file_list.h" +#include "compat/strcasestr.h" struct item_file { @@ -26,11 +27,9 @@ struct item_file size_t directory_ptr; }; -void file_list_push(void *userdata, +void file_list_push(file_list_t *list, const char *path, unsigned type, size_t directory_ptr) { - file_list_t *list = (file_list_t*)userdata; - if (!list) return; @@ -120,3 +119,32 @@ void file_list_get_last(const file_list_t *list, if (list->size) file_list_get_at_offset(list, list->size - 1, path, file_type); } + +bool file_list_search(const file_list_t *list, const char *needle, size_t *index) +{ + size_t i; + const char *alt; + bool ret = false; + for (i = 0; i < list->size; i++) + { + file_list_get_alt_at_offset(list, i, &alt); + if (!alt) + continue; + + const char *str = strcasestr(alt, needle); + if (str == alt) // Found match with first chars, best possible match. + { + *index = i; + ret = true; + break; + } + else if (str) // Found mid-string match, but try to find a match with first chars before we settle. + { + *index = i; + ret = true; + } + } + + return ret; +} + diff --git a/file_list.h b/file_list.h index ee0b2d52d2..8438860477 100644 --- a/file_list.h +++ b/file_list.h @@ -21,6 +21,8 @@ extern "C" { #endif +#include "boolean.h" + struct item_file; typedef struct file_list { @@ -32,7 +34,7 @@ typedef struct file_list void file_list_free(file_list_t *list); -void file_list_push(void *userdata, const char *path, +void file_list_push(file_list_t *userdata, const char *path, unsigned type, size_t current_directory_ptr); void file_list_pop(file_list_t *list, size_t *directory_ptr); void file_list_clear(file_list_t *list); @@ -50,6 +52,8 @@ void file_list_get_alt_at_offset(const file_list_t *list, size_t index, void file_list_sort_on_alt(file_list_t *list); +bool file_list_search(const file_list_t *list, const char *needle, size_t *index); + #ifdef __cplusplus } #endif diff --git a/frontend/menu/disp/rgui.c b/frontend/menu/disp/rgui.c index e607b10931..ef8612026c 100644 --- a/frontend/menu/disp/rgui.c +++ b/frontend/menu/disp/rgui.c @@ -510,6 +510,16 @@ static void rgui_render(void *data) rgui_render_messagebox(rgui, message_queue); #endif + + if (rgui->keyboard.display) + { + char msg[1024]; + const char *str = *rgui->keyboard.buffer; + if (!str) + str = ""; + snprintf(msg, sizeof(msg), "%s\n%s", rgui->keyboard.label, str); + rgui_render_messagebox(rgui, msg); + } } static void *rgui_init(void) diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 383679d05b..d29214ca7f 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -28,6 +28,7 @@ #include "../../file.h" #include "../../file_ext.h" #include "../../input/input_common.h" +#include "../../input/keyboard_line.h" #include "../../compat/posix_string.h" @@ -1382,6 +1383,7 @@ bool menu_iterate(void) rgui->old_input_state |= 1ULL << RARCH_MENU_TOGGLE; } + rarch_check_block_hotkey(); rarch_input_poll(); #ifdef HAVE_OVERLAY rarch_check_overlay(); @@ -1423,6 +1425,9 @@ bool menu_iterate(void) rgui->delay_count++; rgui->old_input_state = input_state; + if (driver.block_input) + rgui->trigger_state = 0; + action = RGUI_ACTION_NOOP; // don't run anything first frame, only capture held inputs for old_input_state @@ -1718,13 +1723,29 @@ bool menu_poll_find_trigger(struct rgui_bind_state *state, struct rgui_bind_stat return false; } -void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers) +static void menu_search_callback(void *userdata, const char *str) +{ + rgui_handle_t *rgui = (rgui_handle_t*)userdata; + + if (str && *str) + file_list_search(rgui->selection_buf, str, &rgui->selection_ptr); + rgui->keyboard.display = false; + rgui->keyboard.label = NULL; + rgui->old_input_state = -1ULL; // Avoid triggering states on pressing return. +} + +void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t mod) { - // TODO: Do something with this. Stub for now. (void)down; (void)keycode; - (void)character; - (void)key_modifiers; + (void)mod; + + if (character == '/') + { + rgui->keyboard.display = true; + rgui->keyboard.label = "Search:"; + rgui->keyboard.buffer = input_keyboard_start_line(rgui, menu_search_callback); + } } static inline int menu_list_get_first_char(file_list_t *buf, unsigned offset) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index b3cbc42fe4..8a4447f3c7 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -324,6 +324,12 @@ typedef struct rarch_time_t last_time; // Used to throttle RGUI in case VSync is broken. struct rgui_bind_state binds; + struct + { + const char **buffer; + const char *label; + bool display; + } keyboard; } rgui_handle_t; extern rgui_handle_t *rgui; @@ -368,10 +374,11 @@ int menu_settings_toggle_setting(void *data, unsigned setting, unsigned action, int menu_set_settings(void *data, unsigned setting, unsigned action); void menu_set_settings_label(char *type_str, size_t type_str_size, unsigned *w, unsigned type); -void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); void menu_populate_entries(void *data, unsigned menu_type); unsigned menu_type_is(unsigned type); +void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); + extern const menu_ctx_driver_t *menu_ctx; #ifdef __cplusplus diff --git a/general.h b/general.h index a1695f223d..4182cc5048 100644 --- a/general.h +++ b/general.h @@ -678,6 +678,7 @@ void rarch_init_msg_queue(void); void rarch_deinit_msg_queue(void); void rarch_input_poll(void); void rarch_check_overlay(void); +void rarch_check_block_hotkey(void); void rarch_init_rewind(void); void rarch_deinit_rewind(void); void rarch_set_fullscreen(bool fullscreen); diff --git a/gfx/context/win32_common.c b/gfx/context/win32_common.c index de1c33833b..734815f658 100644 --- a/gfx/context/win32_common.c +++ b/gfx/context/win32_common.c @@ -14,7 +14,7 @@ */ #include "../../general.h" -#include "../../input/input_common.h" +#include "../../input/keyboard_line.h" #include "win32_common.h" LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) @@ -32,8 +32,7 @@ LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPAR // Seems to be hard to synchronize WM_CHAR and WM_KEYDOWN properly. case WM_CHAR: { - if (g_extern.system.key_event) - g_extern.system.key_event(true, RETROK_UNKNOWN, wparam, mod); + input_keyboard_event(true, RETROK_UNKNOWN, wparam, mod); return TRUE; } @@ -42,8 +41,7 @@ LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPAR // DirectInput uses scancodes directly. unsigned scancode = (lparam >> 16) & 0xff; unsigned keycode = input_translate_keysym_to_rk(scancode); - if (g_extern.system.key_event) - g_extern.system.key_event(true, keycode, 0, mod); + input_keyboard_event(true, keycode, 0, mod); return 0; } @@ -52,8 +50,7 @@ LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPAR // DirectInput uses scancodes directly. unsigned scancode = (lparam >> 16) & 0xff; unsigned keycode = input_translate_keysym_to_rk(scancode); - if (g_extern.system.key_event) - g_extern.system.key_event(false, keycode, 0, mod); + input_keyboard_event(false, keycode, 0, mod); return 0; } @@ -61,8 +58,7 @@ LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPAR { unsigned scancode = (lparam >> 16) & 0xff; unsigned keycode = input_translate_keysym_to_rk(scancode); - if (g_extern.system.key_event) - g_extern.system.key_event(false, keycode, 0, mod); + input_keyboard_event(false, keycode, 0, mod); return 0; } @@ -70,8 +66,7 @@ LRESULT win32_handle_keyboard_event(HWND hwnd, UINT message, WPARAM wparam, LPAR { unsigned scancode = (lparam >> 16) & 0xff; unsigned keycode = input_translate_keysym_to_rk(scancode); - if (g_extern.system.key_event) - g_extern.system.key_event(true, keycode, 0, mod); + input_keyboard_event(true, keycode, 0, mod); switch (wparam) { diff --git a/gfx/context/x11_common.c b/gfx/context/x11_common.c index 10dcf086fb..516849b783 100644 --- a/gfx/context/x11_common.c +++ b/gfx/context/x11_common.c @@ -21,6 +21,7 @@ #include "../image.h" #include "../../general.h" #include "../../input/input_common.h" +#include "../../input/keyboard_line.h" static void x11_hide_mouse(Display *dpy, Window win) { @@ -343,9 +344,6 @@ static size_t conv_utf8_utf32(uint32_t *out, size_t out_chars, const char *in, s void x11_handle_key_event(XEvent *event, XIC ic, bool filter) { - if (!g_extern.system.key_event) - return; - int i; char keybuf[32] = {0}; uint32_t chars[32] = {0}; @@ -383,8 +381,8 @@ void x11_handle_key_event(XEvent *event, XIC ic, bool filter) mod |= (state & Mod1Mask) ? RETROKMOD_ALT : 0; mod |= (state & Mod4Mask) ? RETROKMOD_META : 0; - g_extern.system.key_event(down, key, chars[0], mod); + input_keyboard_event(down, key, chars[0], mod); for (i = 1; i < num; i++) - g_extern.system.key_event(down, RETROK_UNKNOWN, chars[i], mod); + input_keyboard_event(down, RETROK_UNKNOWN, chars[i], mod); } diff --git a/griffin/griffin.c b/griffin/griffin.c index 459655624f..9dfbaf74a8 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -280,6 +280,7 @@ FONTS INPUT ============================================================ */ #include "../input/input_common.c" +#include "../input/keyboard_line.c" #ifdef HAVE_OVERLAY #include "../input/overlay.c" diff --git a/input/input_common.c b/input/input_common.c index a66ae67fbc..f72494fd57 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -1209,3 +1209,4 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c } #endif + diff --git a/input/keyboard_line.c b/input/keyboard_line.c new file mode 100644 index 0000000000..a23b974927 --- /dev/null +++ b/input/keyboard_line.c @@ -0,0 +1,130 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include "keyboard_line.h" +#include "../general.h" +#include "../driver.h" +#include +#include +#include +#include + +struct input_keyboard_line +{ + char *buffer; + size_t ptr; + size_t size; + + input_keyboard_line_complete_t cb; + void *userdata; +}; + +void input_keyboard_line_free(input_keyboard_line_t *state) +{ + if (!state) + return; + + free(state->buffer); + free(state); +} + +input_keyboard_line_t *input_keyboard_line_new(void *userdata, + input_keyboard_line_complete_t cb) +{ + input_keyboard_line_t *state = (input_keyboard_line_t*)calloc(1, sizeof(*state)); + if (!state) + return NULL; + + state->cb = cb; + state->userdata = userdata; + return state; +} + +bool input_keyboard_line_event(input_keyboard_line_t *state, uint32_t character) +{ + // Treat extended chars as ? as we cannot support printable characters for unicode stuff. + char c = character >= 128 ? '?' : character; + if (c == '\r' || c == '\n') + { + state->cb(state->userdata, state->buffer); + return true; + } + + if (c == '\b') + { + if (state->ptr) + { + memmove(state->buffer + state->ptr - 1, state->buffer + state->ptr, + state->size - state->ptr + 1); + state->ptr--; + state->size--; + } + } + // Handle left/right here when suitable + else if (isprint(c)) + { + char *newbuf = (char*)realloc(state->buffer, state->size + 2); + if (!newbuf) + return false; + + memmove(newbuf + state->ptr + 1, newbuf + state->ptr, state->size - state->ptr + 1); + newbuf[state->ptr] = c; + state->ptr++; + state->size++; + newbuf[state->size] = '\0'; + + state->buffer = newbuf; + } + + return false; +} + +const char **input_keyboard_line_get_buffer(const input_keyboard_line_t *state) +{ + return (const char**)&state->buffer; +} + +static input_keyboard_line_t *g_keyboard_line; + +const char **input_keyboard_start_line(void *userdata, input_keyboard_line_complete_t cb) +{ + if (g_keyboard_line) + input_keyboard_line_free(g_keyboard_line); + + g_keyboard_line = input_keyboard_line_new(userdata, cb); + // While reading keyboard line input, we have to block all hotkeys. + driver.block_input = true; + + return input_keyboard_line_get_buffer(g_keyboard_line); +} + +void input_keyboard_event(bool down, unsigned code, uint32_t character, uint16_t mod) +{ + if (g_keyboard_line) + { + if (input_keyboard_line_event(g_keyboard_line, character)) + { + // Line is complete, can free it now. + input_keyboard_line_free(g_keyboard_line); + g_keyboard_line = NULL; + + // Unblock all hotkeys. + driver.block_input = false; + } + } + else if (g_extern.system.key_event) + g_extern.system.key_event(down, code, character, mod); +} + diff --git a/input/keyboard_line.h b/input/keyboard_line.h new file mode 100644 index 0000000000..2afce3b91b --- /dev/null +++ b/input/keyboard_line.h @@ -0,0 +1,54 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef KEYBOARD_LINE_H__ +#define KEYBOARD_LINE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../boolean.h" +#include "../libretro.h" +#include + +// Keyboard line reader. Handles textual input in a direct fashion. +typedef struct input_keyboard_line input_keyboard_line_t; + +// Calls back after return is pressed with the completed line. +// line can be NULL. +typedef void (*input_keyboard_line_complete_t)(void *userdata, const char *line); + +input_keyboard_line_t *input_keyboard_line_new(void *userdata, + input_keyboard_line_complete_t cb); + +// Called on every keyboard character event. +bool input_keyboard_line_event(input_keyboard_line_t *state, uint32_t character); + +// Returns pointer to string. The underlying buffer can be reallocated at any time (or be NULL), but the pointer to it remains constant throughout the objects lifetime. +const char **input_keyboard_line_get_buffer(const input_keyboard_line_t *state); +void input_keyboard_line_free(input_keyboard_line_t *state); + +// Keyboard event utils. Called by drivers when keyboard events are fired. +// This interfaces with the global driver struct and libretro callbacks. +void input_keyboard_event(bool down, unsigned code, uint32_t character, uint16_t mod); +const char **input_keyboard_start_line(void *userdata, input_keyboard_line_complete_t cb); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/input/udev_input.c b/input/udev_input.c index 84496a92ff..15a9821c44 100644 --- a/input/udev_input.c +++ b/input/udev_input.c @@ -14,6 +14,7 @@ */ #include "input_common.h" +#include "keyboard_line.h" #include "../general.h" #include "../conf/config_file.h" #include "../file_path.h" @@ -138,9 +139,9 @@ static void handle_xkb(udev_input_t *udev, int code, int value) if (udev->mod_map[i].index != XKB_MOD_INVALID) mod |= xkb_state_mod_index_is_active(udev->xkb_state, udev->mod_map[i].index, XKB_STATE_MODS_EFFECTIVE) > 0 ? udev->mod_map[i].bit : 0; - g_extern.system.key_event(value, input_translate_keysym_to_rk(code), num_syms ? xkb_keysym_to_utf32(syms[0]) : 0, mod); + input_keyboard_event(value, input_translate_keysym_to_rk(code), num_syms ? xkb_keysym_to_utf32(syms[0]) : 0, mod); for (i = 1; i < num_syms; i++) - g_extern.system.key_event(value, RETROK_UNKNOWN, xkb_keysym_to_utf32(syms[i]), mod); + input_keyboard_event(value, RETROK_UNKNOWN, xkb_keysym_to_utf32(syms[i]), mod); } #endif @@ -155,7 +156,7 @@ static void udev_handle_keyboard(udev_input_t *udev, const struct input_event *e clear_bit(udev->key_state, event->code); #ifdef HAVE_XKBCOMMON - if (udev->xkb_state && g_extern.system.key_event) + if (udev->xkb_state) handle_xkb(udev, event->code, event->value); #endif break; @@ -369,12 +370,12 @@ static void handle_hotplug(udev_input_t *udev) bool is_mouse = val_mouse && !strcmp(val_mouse, "1") && devnode; bool is_touchpad = val_touchpad && !strcmp(val_touchpad, "1") && devnode; - if (!is_keyboard && !is_mouse && !is_touchpad) - goto end; - device_handle_cb cb = NULL; const char *devtype = NULL; + if (!is_keyboard && !is_mouse && !is_touchpad) + goto end; + if (is_keyboard) { cb = udev_handle_keyboard; @@ -522,7 +523,7 @@ static int16_t udev_input_state(void *data, const struct retro_keybind **binds, return ret; case RETRO_DEVICE_KEYBOARD: - return id < RETROK_LAST && get_bit(udev->key_state, input_translate_rk_to_keysym(id)); + return id < RETROK_LAST && get_bit(udev->key_state, input_translate_rk_to_keysym((enum retro_key)id)); case RETRO_DEVICE_MOUSE: return udev_mouse_state(udev, id); diff --git a/qb/config.libs.sh b/qb/config.libs.sh index fb8e3455d7..031fd76c16 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -251,6 +251,7 @@ fi check_pkgconf UDEV libudev check_lib STRL -lc strlcpy +check_lib STRCASESTR -lc strcasestr check_lib MMAP -lc mmap check_pkgconf PYTHON python3 @@ -261,6 +262,6 @@ add_define_make OS "$OS" # Creates config.mk and config.h. add_define_make GLOBAL_CONFIG_DIR "$GLOBAL_CONFIG_DIR" -VARS="RGUI ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL OMAP GLES VG EGL KMS GBM DRM DYLIB GETOPT_LONG THREADS CG LIBXML2 SDL_IMAGE ZLIB DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE FREETYPE XKBCOMMON XVIDEO X11 XEXT XF86VM XINERAMA NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL MMAP PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 BSV_MOVIE VIDEOCORE NEON FLOATHARD FLOATSOFTFP UDEV V4L2" +VARS="RGUI ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL OMAP GLES VG EGL KMS GBM DRM DYLIB GETOPT_LONG THREADS CG LIBXML2 SDL_IMAGE ZLIB DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE FREETYPE XKBCOMMON XVIDEO X11 XEXT XF86VM XINERAMA NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL STRCASESTR MMAP PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 BSV_MOVIE VIDEOCORE NEON FLOATHARD FLOATSOFTFP UDEV V4L2" create_config_make config.mk $VARS create_config_header config.h $VARS diff --git a/retroarch.c b/retroarch.c index c965af2c9f..4be598231b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2690,17 +2690,17 @@ static void check_netplay_flip(void) } #endif -static void check_block_hotkey(void) +void rarch_check_block_hotkey(void) { - driver.block_hotkey = false; + driver.block_hotkey = driver.block_input; // If we haven't bound anything to this, // always allow hotkeys. static const struct retro_keybind *bind = &g_settings.input.binds[0][RARCH_ENABLE_HOTKEY]; - if (bind->key == RETROK_UNKNOWN && bind->joykey == NO_BTN && bind->joyaxis == AXIS_NONE) + if (!driver.block_hotkey && bind->key == RETROK_UNKNOWN && bind->joykey == NO_BTN && bind->joyaxis == AXIS_NONE) return; - driver.block_hotkey = !input_key_pressed_func(RARCH_ENABLE_HOTKEY); + driver.block_hotkey = driver.block_input || !input_key_pressed_func(RARCH_ENABLE_HOTKEY); } #ifdef HAVE_OVERLAY @@ -2743,7 +2743,7 @@ static void check_grab_mouse_toggle(void) static void do_state_checks(void) { - check_block_hotkey(); + rarch_check_block_hotkey(); #if defined(HAVE_SCREENSHOTS) && !defined(_XBOX) check_screenshot();