diff --git a/input/input_keyboard.c b/input/input_keyboard.c index 8a0058088d..b9cb896b75 100644 --- a/input/input_keyboard.c +++ b/input/input_keyboard.c @@ -21,6 +21,8 @@ #include "input_keyboard.h" +#include + #include "../configuration.h" #include "../runloop.h" @@ -48,6 +50,46 @@ static void *g_keyboard_press_data; static bool return_pressed; +static unsigned osk_last_codepoint = 0; +static unsigned osk_last_codepoint_len = 0; + +static void osk_update_last_codepoint(const char *word) +{ + const char *letter = word; + const char *pos = letter; + + if (letter[0] == 0) + { + osk_last_codepoint = 0; + osk_last_codepoint_len = 0; + return; + } + + for (;;) + { + unsigned codepoint = utf8_walk(&letter); + unsigned len = letter - pos; + + if (letter[0] == 0) + { + osk_last_codepoint = codepoint; + osk_last_codepoint_len = len; + break; + } + + pos = letter; + } +} + +static void osk_update_last_char(const char c) +{ + char array[2] = {0}; + + array[0] = c; + + osk_update_last_codepoint(array); +} + bool input_keyboard_return_pressed() { return return_pressed; @@ -123,12 +165,14 @@ static bool input_keyboard_line_event( input_keyboard_line_t *state, uint32_t character) { char c = character >= 128 ? '?' : character; + /* Treat extended chars as ? as we cannot support * printable characters for unicode stuff. */ if (c == '\r' || c == '\n') { state->cb(state->userdata, state->buffer); + osk_update_last_char(c); return true; } @@ -136,12 +180,20 @@ static bool input_keyboard_line_event( { if (state->ptr) { - memmove(state->buffer + state->ptr - 1, - state->buffer + state->ptr, - state->size - state->ptr + 1); - state->ptr--; - state->size--; + unsigned i; + + for (i = 0; i < osk_last_codepoint_len; i++) + { + memmove(state->buffer + state->ptr - 1, + state->buffer + state->ptr, + state->size - state->ptr + 1); + state->ptr--; + state->size--; + } + + osk_update_last_codepoint(state->buffer); } + } else if (isprint((int)c)) { @@ -161,6 +213,8 @@ static bool input_keyboard_line_event( newbuf[state->size] = '\0'; state->buffer = newbuf; + + osk_update_last_char(c); } return false; @@ -191,6 +245,8 @@ bool input_keyboard_line_append(const char *word) g_keyboard_line->buffer = newbuf; + osk_update_last_codepoint(word); + return false; } diff --git a/menu/menu_event.c b/menu/menu_event.c index ebf86d640d..e6e8a511d5 100644 --- a/menu/menu_event.c +++ b/menu/menu_event.c @@ -25,6 +25,7 @@ #endif #include +#include #include "widgets/menu_entry.h" #include "widgets/menu_input_dialog.h" @@ -114,33 +115,21 @@ void menu_event_osk_append(int ptr) { if (ptr >= 0) { - if (!strcmp(osk_grid[ptr],"⇦")) - { + if (string_is_equal(osk_grid[ptr],"⇦")) input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); - } - else if (!strcmp(osk_grid[ptr],"⏎")) - { + else if (string_is_equal(osk_grid[ptr],"⏎")) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); - } - else if (!strcmp(osk_grid[ptr],"⇧")) - { + else if (string_is_equal(osk_grid[ptr],"⇧")) osk_idx = OSK_UPPERCASE_LATIN; - } - else if (!strcmp(osk_grid[ptr],"⇩")) - { + else if (string_is_equal(osk_grid[ptr],"⇩")) osk_idx = OSK_LOWERCASE_LATIN; - } - else if (!strcmp(osk_grid[ptr],"⊕")) - { + else if (string_is_equal(osk_grid[ptr],"⊕")) if (osk_idx < OSK_TYPE_LAST - 1) osk_idx = (enum osk_type)(osk_idx + 1); else osk_idx = (enum osk_type)(OSK_TYPE_UNKNOWN + 1); - } else - { input_keyboard_line_append(osk_grid[ptr]); - } } } @@ -288,17 +277,17 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input) memcpy(osk_grid, katakana_page2_grid, sizeof(katakana_page2_grid)); break; } - case OSK_LOWERCASE_LATIN: - { - memcpy(osk_grid, lowercase_grid, sizeof(lowercase_grid)); - break; - } case OSK_UPPERCASE_LATIN: - default: { memcpy(osk_grid, uppercase_grid, sizeof(uppercase_grid)); break; } + case OSK_LOWERCASE_LATIN: + default: + { + memcpy(osk_grid, lowercase_grid, sizeof(lowercase_grid)); + break; + } } if (trigger_input & (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN))