mirror of
https://github.com/libretro/RetroArch
synced 2025-03-20 10:20:51 +00:00
Merge pull request #410 from libretro/rgui-search
Add experimental RGUI keyboard search feature.
This commit is contained in:
commit
14a6c01a14
1
Makefile
1
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 \
|
||||
|
@ -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 \
|
||||
|
@ -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.
|
||||
|
40
compat/strcasestr.h
Normal file
40
compat/strcasestr.h
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RARCH_STRCASESTR_H
|
||||
#define RARCH_STRCASESTR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
|
1
driver.h
1
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.
|
||||
|
34
file_list.c
34
file_list.c
@ -17,6 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -280,6 +280,7 @@ FONTS
|
||||
INPUT
|
||||
============================================================ */
|
||||
#include "../input/input_common.c"
|
||||
#include "../input/keyboard_line.c"
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
#include "../input/overlay.c"
|
||||
|
@ -1209,3 +1209,4 @@ void input_config_autoconfigure_joypad(unsigned index, const char *name, const c
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
130
input/keyboard_line.c
Normal file
130
input/keyboard_line.c
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "keyboard_line.h"
|
||||
#include "../general.h"
|
||||
#include "../driver.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
54
input/keyboard_line.h
Normal file
54
input/keyboard_line.h
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEYBOARD_LINE_H__
|
||||
#define KEYBOARD_LINE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../boolean.h"
|
||||
#include "../libretro.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// 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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
10
retroarch.c
10
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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user