mirror of
https://github.com/VARCem/PDCurses.git
synced 2026-09-24 07:45:21 +00:00
Implement proper text input through the SDL2 TextInput API
Input using SDL_KEYDOWN was limited to characters with a dedicated US-layout keyboard key (e.g. shift-2 produced 2 instead of @). Textual input is now handled through the SDL_TEXTINPUT event, giving the proper character for the current keyboard layout. This includes Unicode input support for WIDE builds.
This commit is contained in:
@@ -123,9 +123,48 @@ bool PDC_check_key(void)
|
||||
return haveevent;
|
||||
}
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
static int _utf8_to_unicode(char *chstr)
|
||||
{
|
||||
int i, bytes, unicode;
|
||||
unsigned char byte = chstr[0];
|
||||
|
||||
if (byte > 0xf0)
|
||||
{
|
||||
bytes = 4;
|
||||
unicode = byte & 0x7;
|
||||
}
|
||||
else if (byte > 0xe0)
|
||||
{
|
||||
bytes = 3;
|
||||
unicode = byte & 0xf;
|
||||
}
|
||||
else if (byte > 0xc0)
|
||||
{
|
||||
bytes = 2;
|
||||
unicode = byte & 0x1f;
|
||||
}
|
||||
else if (byte > 0x80) {
|
||||
/* starts with a continuation byte; invalid character */
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = 1;
|
||||
unicode = byte;
|
||||
}
|
||||
|
||||
for (i = 1; i < bytes; i++)
|
||||
unicode = (unicode << 6) + (chstr[i] & 0x3f);
|
||||
|
||||
return unicode;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _process_key_event(void)
|
||||
{
|
||||
int i, key = 0;
|
||||
unsigned long old_modifiers = pdc_key_modifiers;
|
||||
|
||||
pdc_key_modifiers = 0L;
|
||||
SP->key_code = FALSE;
|
||||
@@ -155,6 +194,16 @@ static int _process_key_event(void)
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if (event.type == SDL_TEXTINPUT)
|
||||
{
|
||||
pdc_key_modifiers = old_modifiers;
|
||||
#ifdef PDC_WIDE
|
||||
return _utf8_to_unicode(event.text.text);
|
||||
#else
|
||||
key = (unsigned char)event.text.text[0];
|
||||
return key > 0x7f ? -1 : key;
|
||||
#endif
|
||||
}
|
||||
|
||||
oldkey = event.key.keysym.sym;
|
||||
|
||||
@@ -235,6 +284,11 @@ static int _process_key_event(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Textual input is handled by the SDL_TEXTINPUT event */
|
||||
if (' ' <= key && key <= '~') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return key ? key : -1;
|
||||
}
|
||||
|
||||
@@ -380,6 +434,7 @@ int PDC_get_key(void)
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_TEXTINPUT:
|
||||
PDC_mouse_set();
|
||||
return _process_key_event();
|
||||
}
|
||||
|
||||
@@ -223,6 +223,11 @@ int PDC_scr_open(int argc, char **argv)
|
||||
return ERR;
|
||||
}
|
||||
SDL_SetWindowIcon(pdc_window, pdc_icon);
|
||||
|
||||
/* Events must be pumped before calling SDL_GetWindowSurface, or
|
||||
initial modifiers (e.g. numlock) will be ignored and out-of-sync. */
|
||||
SDL_PumpEvents();
|
||||
|
||||
pdc_screen = SDL_GetWindowSurface(pdc_window);
|
||||
if (pdc_screen == NULL)
|
||||
{
|
||||
@@ -266,6 +271,8 @@ int PDC_scr_open(int argc, char **argv)
|
||||
pdc_mapped[i] = SDL_MapRGB(pdc_screen->format, pdc_color[i].r,
|
||||
pdc_color[i].g, pdc_color[i].b);
|
||||
|
||||
SDL_StartTextInput();
|
||||
|
||||
PDC_mouse_set();
|
||||
|
||||
if (pdc_own_window)
|
||||
|
||||
Reference in New Issue
Block a user