mirror of
https://github.com/mpv-player/mpv
synced 2025-01-11 17:39:38 +00:00
input: allow unicode keys and reassign internal key codes
This moves all key codes above the highest valid unicode code point (which is 0x10FFFF). All key codes below MP_KEY_BASE now directly map to unicode (KEY_ENTER is 13, carriage return). Configuration files (input.conf) can contain unicode characters in UTF-8 to map non-ASCII characters/keys. This shouldn't change anything user visible, except that "direct key codes" (as used in input.conf) will change their meaning. Parts of the bstr functions taken from libavutil's GET_UTF8 and slightly modified.
This commit is contained in:
parent
3e6e80a32c
commit
166a7de4cf
32
bstr.c
32
bstr.c
@ -201,3 +201,35 @@ int bstr_sscanf(struct bstr str, const char *format, ...)
|
||||
talloc_free(ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bstr_parse_utf8_code_length(unsigned char b)
|
||||
{
|
||||
if (b < 128)
|
||||
return 1;
|
||||
int bytes = 7 - av_log2(b ^ 255);
|
||||
return (bytes >= 2 && bytes <= 4) ? bytes : -1;
|
||||
}
|
||||
|
||||
int bstr_decode_utf8(struct bstr s, struct bstr *out_next)
|
||||
{
|
||||
if (s.len == 0)
|
||||
return -1;
|
||||
unsigned int codepoint = s.start[0];
|
||||
s.start++; s.len--;
|
||||
if (codepoint >= 128) {
|
||||
int bytes = bstr_parse_utf8_code_length(codepoint);
|
||||
if (bytes < 0 || s.len < bytes - 1)
|
||||
return -1;
|
||||
codepoint &= 127 >> bytes;
|
||||
for (int n = 1; n < bytes; n++) {
|
||||
int tmp = s.start[0];
|
||||
if ((tmp & 0xC0) != 0x80)
|
||||
return -1;
|
||||
codepoint = (codepoint << 6) | (tmp & ~0xC0);
|
||||
s.start++; s.len--;
|
||||
}
|
||||
}
|
||||
if (out_next)
|
||||
*out_next = s;
|
||||
return codepoint;
|
||||
}
|
||||
|
13
bstr.h
13
bstr.h
@ -69,6 +69,19 @@ double bstrtod(struct bstr str, struct bstr *rest);
|
||||
void bstr_lower(struct bstr str);
|
||||
int bstr_sscanf(struct bstr str, const char *format, ...);
|
||||
|
||||
// Decode the UTF-8 code point at the start of the string,, and return the
|
||||
// character.
|
||||
// After calling this function, *out_next will point to the next character.
|
||||
// out_next can be NULL.
|
||||
// On error, -1 is returned, and *out_next is not modified.
|
||||
int bstr_decode_utf8(struct bstr str, struct bstr *out_next);
|
||||
|
||||
// Return the length of the UTF-8 sequence that starts with the given byte.
|
||||
// Given a string char *s, the next UTF-8 code point is to be expected at
|
||||
// s + bstr_parse_utf8_code_length(s[0])
|
||||
// On error, -1 is returned. On success, it returns a value in the range [1, 4].
|
||||
int bstr_parse_utf8_code_length(unsigned char b);
|
||||
|
||||
static inline struct bstr bstr_cut(struct bstr str, int n)
|
||||
{
|
||||
if (n > str.len)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "keycodes.h"
|
||||
#include "osdep/timer.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "mp_msg.h"
|
||||
#include "m_config.h"
|
||||
#include "m_option.h"
|
||||
@ -649,6 +650,17 @@ static const m_option_t mp_input_opts[] = {
|
||||
|
||||
static int default_cmd_func(int fd, char *buf, int l);
|
||||
|
||||
// Encode the unicode codepoint as UTF-8, and append to the end of the
|
||||
// talloc'ed buffer.
|
||||
static char *append_utf8_buffer(char *buffer, uint32_t codepoint)
|
||||
{
|
||||
char data[8];
|
||||
uint8_t tmp;
|
||||
char *output = data;
|
||||
PUT_UTF8(codepoint, tmp, *output++ = tmp;);
|
||||
return talloc_strndup_append_buffer(buffer, data, output - data);
|
||||
}
|
||||
|
||||
static char *get_key_name(int key, char *ret)
|
||||
{
|
||||
for (int i = 0; modifier_names[i].name; i++) {
|
||||
@ -663,8 +675,9 @@ static char *get_key_name(int key, char *ret)
|
||||
return talloc_asprintf_append_buffer(ret, "%s", key_names[i].name);
|
||||
}
|
||||
|
||||
if (isascii(key))
|
||||
return talloc_asprintf_append_buffer(ret, "%c", key);
|
||||
// printable, and valid unicode range
|
||||
if (key >= 32 && key <= 0x10FFFF)
|
||||
return append_utf8_buffer(ret, key);
|
||||
|
||||
// Print the hex key code
|
||||
return talloc_asprintf_append_buffer(ret, "%#-8x", key);
|
||||
@ -1173,7 +1186,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code)
|
||||
* shift modifier is still kept for special keys like arrow keys.
|
||||
*/
|
||||
int unmod = code & ~KEY_MODIFIER_MASK;
|
||||
if (unmod < 256 && unmod != KEY_ENTER && unmod != KEY_TAB)
|
||||
if (unmod >= 32 && unmod < MP_KEY_BASE)
|
||||
code &= ~KEY_MODIFIER_SHIFT;
|
||||
|
||||
if (code & MP_KEY_DOWN) {
|
||||
@ -1491,10 +1504,15 @@ int mp_input_get_key_from_name(const char *name)
|
||||
found:
|
||||
name = p + 1;
|
||||
}
|
||||
int len = strlen(name);
|
||||
if (len == 1) // Direct key code
|
||||
return (unsigned char)name[0] + modifiers;
|
||||
else if (len > 2 && strncasecmp("0x", name, 2) == 0)
|
||||
|
||||
struct bstr bname = bstr(name);
|
||||
|
||||
struct bstr rest;
|
||||
int code = bstr_decode_utf8(bname, &rest);
|
||||
if (code >= 0 && rest.len == 0)
|
||||
return code + modifiers;
|
||||
|
||||
if (bstr_startswith0(bname, "0x"))
|
||||
return strtol(name, NULL, 16) + modifiers;
|
||||
|
||||
for (int i = 0; key_names[i].name != NULL; i++) {
|
||||
|
@ -21,19 +21,16 @@
|
||||
#ifndef MPLAYER_KEYCODES_H
|
||||
#define MPLAYER_KEYCODES_H
|
||||
|
||||
#define MP_KEY_BASE (1<<21)
|
||||
|
||||
// For appleir.c which includes another header with KEY_ENTER etc defines
|
||||
#ifndef AR_DEFINES_ONLY
|
||||
|
||||
#define KEY_ENTER 13
|
||||
#define KEY_TAB 9
|
||||
|
||||
#define KEY_BASE 0x100
|
||||
|
||||
/* Function keys */
|
||||
#define KEY_F (KEY_BASE+64)
|
||||
|
||||
/* Control keys */
|
||||
#define KEY_CTRL (KEY_BASE)
|
||||
#define KEY_CTRL (MP_KEY_BASE)
|
||||
#define KEY_BACKSPACE (KEY_CTRL+0)
|
||||
#define KEY_DELETE (KEY_CTRL+1)
|
||||
#define KEY_INSERT (KEY_CTRL+2)
|
||||
@ -52,14 +49,14 @@
|
||||
#define KEY_PGDWN KEY_PAGE_DOWN
|
||||
|
||||
/* Cursor movement */
|
||||
#define KEY_CRSR (KEY_BASE+16)
|
||||
#define KEY_CRSR (MP_KEY_BASE+0x10)
|
||||
#define KEY_RIGHT (KEY_CRSR+0)
|
||||
#define KEY_LEFT (KEY_CRSR+1)
|
||||
#define KEY_DOWN (KEY_CRSR+2)
|
||||
#define KEY_UP (KEY_CRSR+3)
|
||||
|
||||
/* Multimedia keyboard/remote keys */
|
||||
#define KEY_MM_BASE (0x100+384)
|
||||
#define KEY_MM_BASE (MP_KEY_BASE+0x20)
|
||||
#define KEY_POWER (KEY_MM_BASE+0)
|
||||
#define KEY_MENU (KEY_MM_BASE+1)
|
||||
#define KEY_PLAY (KEY_MM_BASE+2)
|
||||
@ -74,8 +71,11 @@
|
||||
#define KEY_VOLUME_DOWN (KEY_MM_BASE+11)
|
||||
#define KEY_MUTE (KEY_MM_BASE+12)
|
||||
|
||||
/* Function keys */
|
||||
#define KEY_F (MP_KEY_BASE+0x40)
|
||||
|
||||
/* Keypad keys */
|
||||
#define KEY_KEYPAD (KEY_BASE+32)
|
||||
#define KEY_KEYPAD (MP_KEY_BASE+0x60)
|
||||
#define KEY_KP0 (KEY_KEYPAD+0)
|
||||
#define KEY_KP1 (KEY_KEYPAD+1)
|
||||
#define KEY_KP2 (KEY_KEYPAD+2)
|
||||
@ -93,7 +93,7 @@
|
||||
|
||||
|
||||
// Joystick input module
|
||||
#define JOY_BASE (0x100+128)
|
||||
#define JOY_BASE (MP_KEY_BASE+0x70)
|
||||
#define JOY_AXIS0_PLUS (JOY_BASE+0)
|
||||
#define JOY_AXIS0_MINUS (JOY_BASE+1)
|
||||
#define JOY_AXIS1_PLUS (JOY_BASE+2)
|
||||
@ -115,7 +115,7 @@
|
||||
#define JOY_AXIS9_PLUS (JOY_BASE+18)
|
||||
#define JOY_AXIS9_MINUS (JOY_BASE+19)
|
||||
|
||||
#define JOY_BTN_BASE ((0x100+148)|MP_NO_REPEAT_KEY)
|
||||
#define JOY_BTN_BASE ((MP_KEY_BASE+0x90)|MP_NO_REPEAT_KEY)
|
||||
#define JOY_BTN0 (JOY_BTN_BASE+0)
|
||||
#define JOY_BTN1 (JOY_BTN_BASE+1)
|
||||
#define JOY_BTN2 (JOY_BTN_BASE+2)
|
||||
@ -129,7 +129,7 @@
|
||||
|
||||
|
||||
// Mouse events from VOs
|
||||
#define MOUSE_BASE ((0x100+256)|MP_NO_REPEAT_KEY)
|
||||
#define MOUSE_BASE ((MP_KEY_BASE+0xA0)|MP_NO_REPEAT_KEY)
|
||||
#define MOUSE_BTN0 (MOUSE_BASE+0)
|
||||
#define MOUSE_BTN1 (MOUSE_BASE+1)
|
||||
#define MOUSE_BTN2 (MOUSE_BASE+2)
|
||||
@ -152,7 +152,7 @@
|
||||
#define MOUSE_BTN19 (MOUSE_BASE+19)
|
||||
#define MOUSE_BTN_END (MOUSE_BASE+20)
|
||||
|
||||
#define MOUSE_BASE_DBL (0x300|MP_NO_REPEAT_KEY)
|
||||
#define MOUSE_BASE_DBL ((MP_KEY_BASE+0xC0)|MP_NO_REPEAT_KEY)
|
||||
#define MOUSE_BTN0_DBL (MOUSE_BASE_DBL+0)
|
||||
#define MOUSE_BTN1_DBL (MOUSE_BASE_DBL+1)
|
||||
#define MOUSE_BTN2_DBL (MOUSE_BASE_DBL+2)
|
||||
@ -179,7 +179,7 @@
|
||||
#endif // AR_DEFINES_ONLY
|
||||
|
||||
// Apple Remote input module
|
||||
#define AR_BASE 0x500
|
||||
#define AR_BASE (MP_KEY_BASE+0xE0)
|
||||
#define AR_PLAY (AR_BASE + 0)
|
||||
#define AR_PLAY_HOLD (AR_BASE + 1)
|
||||
#define AR_NEXT (AR_BASE + 2)
|
||||
@ -195,14 +195,14 @@
|
||||
|
||||
|
||||
/* Special keys */
|
||||
#define KEY_INTERN (0x1000)
|
||||
#define KEY_INTERN (MP_KEY_BASE+0x1000)
|
||||
#define KEY_CLOSE_WIN (KEY_INTERN+0)
|
||||
|
||||
/* Modifiers added to individual keys */
|
||||
#define KEY_MODIFIER_SHIFT 0x2000
|
||||
#define KEY_MODIFIER_CTRL 0x4000
|
||||
#define KEY_MODIFIER_ALT 0x8000
|
||||
#define KEY_MODIFIER_META 0x10000
|
||||
#define KEY_MODIFIER_SHIFT (1<<22)
|
||||
#define KEY_MODIFIER_CTRL (1<<23)
|
||||
#define KEY_MODIFIER_ALT (1<<24)
|
||||
#define KEY_MODIFIER_META (1<<25)
|
||||
|
||||
#endif // AR_DEFINES_ONLY
|
||||
|
||||
|
10
mp_fifo.c
10
mp_fifo.c
@ -67,3 +67,13 @@ void mplayer_put_key(struct mp_fifo *fifo, int code)
|
||||
fifo->last_down_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
void mplayer_put_key_utf8(struct mp_fifo *fifo, int mods, struct bstr t)
|
||||
{
|
||||
while (t.len) {
|
||||
int code = bstr_decode_utf8(t, &t);
|
||||
if (code < 0)
|
||||
break;
|
||||
mplayer_put_key(fifo, code | mods);
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,11 @@
|
||||
#ifndef MPLAYER_MP_FIFO_H
|
||||
#define MPLAYER_MP_FIFO_H
|
||||
|
||||
#include "bstr.h"
|
||||
|
||||
struct mp_fifo;
|
||||
void mplayer_put_key(struct mp_fifo *fifo, int code);
|
||||
void mplayer_put_key_utf8(struct mp_fifo *fifo, int mods, struct bstr code);
|
||||
// Can be freed with talloc_free()
|
||||
struct input_ctx;
|
||||
struct MPOpts;
|
||||
|
@ -225,7 +225,7 @@ void getch2(struct mp_fifo *fifo)
|
||||
}
|
||||
if ((c == '[' || c == 'O') && getch2_len >= 3) {
|
||||
int c = getch2_buf[2];
|
||||
const short ctable[] = {
|
||||
const int ctable[] = {
|
||||
KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT, 0,
|
||||
KEY_END, KEY_PGDWN, KEY_HOME, KEY_PGUP, 0, 0, KEY_INS, 0, 0, 0,
|
||||
KEY_F+1, KEY_F+2, KEY_F+3, KEY_F+4};
|
||||
|
Loading…
Reference in New Issue
Block a user