Retroarch: (Linux) Internationalized-Keyboards issues (tested x11/sdl)

Created on 19 Jan 2019  路  22Comments  路  Source: libretro/RetroArch

Description

The input system is not ready for Internationalized keyboards on linux, tested with x11 and SDL2.

X11

XKeysymToKeycode is not ready to get localized input.
Info: https://web.archive.org/web/20080914170322/http://www.sbin.org:80/doc/Xlib/chapt_11.html

SDL2

...


The missed keycodes:
keycode 21 (keysym 0xa1, exclamdown)
keycode 34 (keysym 0xfe50, dead_grave)
keycode 47 (keysym 0xf1, ntilde) (in spanish keyboard)
keycode 48 (keysym 0xfe51, dead_acute)
keycode 51 (keysym 0xe7, ccedilla) (in spanish keyboard)

I'm trying to subscribe with the callback to the poll to debug and just get:

Down: yes, Code: 0, Char: 0, Mod: 16.
Down: no, Code: 0, Char: 0, Mod: 16.

Using x11+input_state_cb I get two keycodes when i push:
keycode 19 (keysym 0x30, 0) (RETROK_0)

Debug print:

Down: yes, Code: 48, Char: 48, Mod: 0.
catch: 48 
catch: 61 
catch: 48 
catch: 61 
catch: 48 
catch: 61 
catch: 48 
catch: 61 
Down: no, Code: 48, Char: 0, Mod: 0.

And in screen appear:
imagen

Code

tested on libretro-cap32 and libretro-dosbox

  unsigned int lastdown,lastup,lastchar;

static void keyboard_cb(bool down, unsigned keycode, uint32_t character, uint16_t mod)
{

  printf( "Down: %s, Code: %d, Char: %u, Mod: %u.\n", down ? "yes" : "no", keycode, character, mod);

  if(down)lastdown=keycode;
  else lastup=keycode;

  lastchar=character;

}

And for catch i use a simple code to debug:

for (i=0;i<320; i++)
   if(input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0,i)) printf("catch: %d \n",i);

Amstrad CPC is too buggy with keyboard

libretro-cap32 use input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, key) to get keys that generates another two bugs (see below) and dosbox-libretro with the callback that ignore some keys...

We need keycode 34 (dead_grave) in Amstrad emulator to allow change unit from disk to tape, example: "|TAPE"

Expected behavior

When I press referred keys we need his keycode send correctly to the core.

Actual behavior

Missed some keycodes.
I think we filter this keys in the driver.
I try to find the bug with two keycodes send in input_state_cb but I didn't have any luck...

Steps to reproduce the bug

  1. get lastest libretro-cap uncomment line ~1020 in libretro/libretro-core.c
  2. add catch code to Core_Processkey() in libretro/nukleargui/app.c
  3. start RA and select x11 driver.
  4. start emulation (no game need it in linux), and press 0.
  5. test the other keycodes.

Version/Commit

  • RetroArch: [version/commit]
    tested from 1.4.1 to current commit dc6b148b174a9cdc31d5563fa6d15d3d1c191fa0

Environment information

  • OS: Linux UBUNTU 4.19.11-041911-generic #201812191931 SMP Wed Dec 19 19:33:33 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Compiler: 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
input sdl2

All 22 comments

DOSBOX Keyboard tests pressing from top to down following keys:

imagen
(I press space after each row completed and "game focus" is ON.

BUGS: Some keycodes missing.

LINUX

imagen

debug log/code: https://gist.github.com/DSkywalk/a36ed8b695e8d868608f603321641e0a

WINDOWS

imagen

CAPRICE32 keyboard tests, pressing from top to down the following keys:

imagen
(I press space after each row completed and "game focus" is ON.

BUGS: double keycodes send with "coma" and "zero" and missing keycodes.

LINUX

imagen

debug log: https://gist.github.com/DSkywalk/e6d25f7ab40edd291c1697b971a596a2

imagen

WINDOWS

imagen
_in windows ntilde generates ":"_
_yes missed some keys but is core related, see dosbox screen_

Could you also try udev or linuxraw?

udev is totally broken with english/spanish layout.

imagen

FRAME: 0 - K:98 c:48 m:0 (49)
FRAME: 1 - K:98 c:0 m:0 (49)
FRAME: 2 - K:59 c:39 m:0 (49)
FRAME: 3 - K:59 c:0 m:0 (49)
FRAME: 4 - K:0 c:161 m:0 (49)
FRAME: 5 - K:0 c:0 m:0 (49)
FRAME: 6 - K:100 c:32 m:0 (49)
FRAME: 7 - K:100 c:0 m:0 (49)
FRAME: 8 - K:0 c:112 m:0 (49)
FRAME: 9 - K:0 c:0 m:0 (49)
FRAME: 10 - K:0 c:0 m:0 (49)
FRAME: 11 - K:0 c:0 m:0 (49)
FRAME: 12 - K:0 c:0 m:0 (49)
FRAME: 13 - K:92 c:0 m:0 (49)
FRAME: 14 - K:100 c:32 m:0 (49)
FRAME: 15 - K:100 c:0 m:0 (49)
FRAME: 16 - K:0 c:241 m:0 (49)
FRAME: 17 - K:0 c:0 m:0 (49)
FRAME: 18 - K:0 c:0 m:0 (49)
FRAME: 19 - K:0 c:0 m:0 (49)
FRAME: 20 - K:0 c:0 m:0 (49)
FRAME: 21 - K:0 c:0 m:0 (49)
FRAME: 22 - K:100 c:32 m:0 (49)
FRAME: 23 - K:100 c:0 m:0 (49)
FRAME: 24 - K:122 c:44 m:0 (49)
FRAME: 25 - K:122 c:0 m:0 (49)
FRAME: 26 - K:99 c:46 m:0 (49)
FRAME: 27 - K:99 c:0 m:0 (49)
FRAME: 28 - K:120 c:45 m:0 (49)
FRAME: 29 - K:120 c:0 m:0 (49)
FRAME: 30 - K:100 c:32 m:0 (49)
FRAME: 31 - K:100 c:0 m:0 (49)
FRAME: 32 - K:0 c:0 m:0 (49)
FRAME: 33 - K:0 c:0 m:1 (49)

Thanks, hopefully someone that understands how to fix this better can spend time fixing it...

@orbea with linuxraw i get an error:

[ERROR] [Video]: Cannot initialize input driver. Exiting ...
[ERROR] Fatal error received in: "video_driver_init_input()"

RA compiled with:
./configure --disable-kms --disable-sdl --disable-jack --disable-qt --disable-wayland --disable-x11

Because x11 input-driver do not allow use any other driver (cfg setup is ignored on linux).

@orbea who calls this functions? I would like to debug them:
retro_keyboard_callback ...
input_state_cb( int, RETRO_DEVICE_KEYBOARD, int, key)

but the dynamic initialization disturbs me :_D

It seems --disable-x11 breaks the linuxraw input driver, I'll try investigating that later. As for the other questions I don't think I am be the best person to help here...

Because x11 input-driver do not allow use any other driver (cfg setup is ignored on linux).

Could you elaborate? I am not sure what you mean? Switching input drivers works fine here.

Could you elaborate? I am not sure what you mean? Switching input drivers works fine here.

Try to switch from x11 to sdl2 (to see changes add an string in sdl_input_init...
imagen

SDL input driver is just ignored and RA use x11 driver...

A simple code to debug x11 init...
imagen

It seems --disable-x11 breaks the linuxraw input driver, I'll try investigating that later.

Compiled with:
./configure --disable-jack --disable-qt

and get the same error

[INFO] [X11]: Suspending screensaver (X11, xdg-screensaver).
[INFO] [Video]: Graphics driver did not initialize an input driver. Attempting to pick a suitable driver.
[ERROR] [Video]: Cannot initialize input driver. Exiting ...
[ERROR] Fatal error received in: "video_driver_init_input()"

sorry for my engrish :_

I understand now...

It never actually uses the sdl_input_init function unless --disable-x11 is used. It also defaults to a kms context here unless --disable-kms is also used... Seems like a mess...

There really should be new issue reports for these configure problems as they are not directly related to the international keyboard issue.

@DSkywalk I have a potential fix for the --disable-kms issue in PR https://github.com/libretro/RetroArch/pull/8047.

As for sdl_input_init, I'm not sure what can be done about that, but I think the x context driver forces either the x or udev input drivers to at least some degree?

I get some advances with this bug, in x11_common.c
comment this line ~500 -> filter = XFilterEvent(&event, g_x11_win);

DEBUG CODE in x11_handle_key_event _(see above the FRAME debug code in dosbox)_

printf("key: [%u]-%lu [%d] %d %lu %lu (%u)\n",key, keysym, event->xkey.keycode,event->xkey.state, event->xkey.time, event->xkey.serial, (int) filter);

Removing filter i get the correct keycodes:

[INFO] Game focus is: : on.
down key: [13]-65293 [36] 16 116640492 91564 (0)
FRAME: 58 - K:13 c:13 m:0 (13)
key: [13]-65293 [36] 16 116640558 91592 (0)
FRAME: 59 - K:13 c:0 m:0 (13)
down key: [13]-65293 [36] 16 116641572 92012 (0)
FRAME: 60 - K:13 c:13 m:0 (13)
key: [13]-65293 [36] 16 116641642 92047 (0)
FRAME: 61 - K:13 c:0 m:0 (13)
down key: [13]-65293 [36] 16 116642102 92236 (0)
FRAME: 62 - K:13 c:13 m:0 (13)
key: [13]-65293 [36] 16 116642162 92264 (0)
FRAME: 63 - K:13 c:0 m:0 (13)
down key: [13]-65293 [36] 16 116642628 92460 (0)
FRAME: 64 - K:13 c:13 m:0 (13)
key: [13]-65293 [36] 16 116642696 92488 (0)
FRAME: 65 - K:13 c:0 m:0 (13)
down key: [13]-65293 [36] 16 116645983 93868 (0)
FRAME: 66 - K:13 c:13 m:0 (13)
key: [13]-65293 [36] 16 116646048 93889 (0)
FRAME: 67 - K:13 c:0 m:0 (13)
down key: [13]-65293 [36] 16 116646640 94141 (0)
FRAME: 68 - K:13 c:13 m:0 (13)
key: [13]-65293 [36] 16 116646702 94169 (0)
FRAME: 69 - K:13 c:0 m:0 (13)
down key: [0]-161 [21] 16 116649330 95269 (0)
FRAME: 70 - K:0 c:161 m:0
key: [0]-161 [21] 16 116649400 95304 (0)
FRAME: 71 - K:0 c:0 m:0
down key: [39]-39 [20] 16 116649733 95444 (0)
FRAME: 72 - K:39 c:39 m:0 (39)
key: [39]-39 [20] 16 116649803 95472 (0)
FRAME: 73 - K:39 c:0 m:0 (39)
down key: [48]-48 [19] 16 116650130 95605 (0)
FRAME: 74 - K:48 c:48 m:0 (48)
key: [48]-48 [19] 16 116650205 95640 (0)
FRAME: 75 - K:48 c:0 m:0 (48)
down key: [32]-32 [65] 16 116650602 95801 (0)
FRAME: 76 - K:32 c:32 m:0 (32)
key: [32]-32 [65] 16 116650699 95843 (0)
FRAME: 77 - K:32 c:0 m:0 (32)
down key: [43]-43 [35] 16 116651451 96165 (0)
FRAME: 78 - K:43 c:43 m:0
key: [43]-43 [35] 16 116651521 96193 (0)
FRAME: 79 - K:43 c:0 m:0
down key: [0]-65104 [34] 16 116651772 96298 (0)
FRAME: 80 - K:0 c:0 m:0
key: [0]-65104 [34] 16 116651845 96326 (0)
FRAME: 81 - K:0 c:0 m:0
down key: [112]-112 [33] 16 116652169 96466 (0)
FRAME: 82 - K:112 c:112 m:0 (112)
key: [112]-112 [33] 16 116652253 96494 (0)
FRAME: 83 - K:112 c:0 m:0 (112)
down key: [32]-32 [65] 16 116652859 96753 (0)
FRAME: 84 - K:32 c:32 m:0 (32)
key: [32]-32 [65] 16 116652944 96788 (0)
FRAME: 85 - K:32 c:0 m:0 (32)
down key: [0]-231 [51] 16 116653451 96999 (0)
FRAME: 86 - K:0 c:231 m:0
key: [0]-231 [51] 16 116653516 97027 (0)
FRAME: 87 - K:0 c:0 m:0
down key: [0]-65105 [48] 16 116653764 97132 (0)
FRAME: 88 - K:0 c:0 m:0
key: [0]-65105 [48] 16 116653838 97167 (0)
FRAME: 89 - K:0 c:0 m:0
down key: [0]-241 [47] 16 116654149 97293 (0)
FRAME: 90 - K:0 c:241 m:0
key: [0]-241 [47] 16 116654222 97328 (0)
FRAME: 91 - K:0 c:0 m:0
down key: [32]-32 [65] 16 116655652 97923 (0)
FRAME: 92 - K:32 c:32 m:0 (32)
key: [32]-32 [65] 16 116655726 97958 (0)
FRAME: 93 - K:32 c:0 m:0 (32)
[INFO] Game focus is: : off.

actual behavior (using filter)
imagen
_pressing this key two times_

down key: [0]-0 [34] 16 117139479 1589 (1)
FRAME: 0 - K:0 c:0 m:0
key: [0]-65104 [34] 16 117139556 1619 (0)
FRAME: 1 - K:0 c:0 m:0
down key: [0]-0 [0] 16 117152591 6309 (1)
FRAME: 2 - K:0 c:0 m:0
down key: [96]-96 [0] 16 117152591 6309 (0)
FRAME: 3 - K:96 c:96 m:0 (96)
key: [0]-65104 [34] 16 117152659 6333 (0)
FRAME: 4 - K:0 c:0 m:0

generates some ghosts keycodes and emulation problems:
imagen

without the filter:

down key: [0]-65104 [34] 16 119746689 1007 (0)
FRAME: 0 - K:0 c:0 m:0
key: [0]-65104 [34] 16 119746760 1037 (0)
FRAME: 1 - K:0 c:0 m:0
down key: [0]-65104 [34] 16 119747489 1295 (0)
FRAME: 2 - K:0 c:0 m:0
key: [0]-65104 [34] 16 119747568 1325 (0)
FRAME: 3 - K:0 c:0 m:0

I talked with other x11 developers and they use keycodes (not keysym) and filter after capture the keycode.
I could send a PR if the team are agree.

thanks!

the original code comes from https://github.com/libretro/RetroArch/commit/ac6813dc7f0b219b7c52b5684168c9c39feb7ad7#diff-37c63d58f60aaaca9e8cd6bc44b3686c
by @twinaphex and @Themaister

I think the X11 problem in is when convert keysyms to keys and ascii/utf8 text (see x11_handle_key_event function in x11_common.c). We filter correct keys send it to our window if the key is an accent (see above). Maybe two functions (once to convert the keycodes (not keysyms) before the filter and other to get_the_text after the filter) It could be a good solution.

Thanks, and sorry for my english :_)

If you can fix this please do send a PR, thanks! If it fixes the problem while avoiding regressions I doubt anyone would complain.

Since SDL2 is still affected I'll reopen this, please correct me if I'm mistaken?

@orbea SDL2 with international keyb, is broken on both sytems windows and linux.

FAILED: win+sdl2-input/sdl2-video
imagen

FAILED: linux+sdl2-input/sdl2-video
imagen

OK: render in win+dinput
imagen

OK: render in linux+x11
imagen

In SDL we are forced to use keysyms and it depends of the layout, ex:
In English keyboard - keysym 59 (SDLK_SEMICOLON) => RETROK_SEMICOLON
In Spanish keyboard - keysym 241 (undefined in SDL) it would need to generate the same => RETROK_SEMICOLON.

Is not easy fix this bug because input_keymaps_translate_keysym_to_rk / rarch_keysym_lut not allow duplicates RETROK_* values...

any ideas? :walking_man:

more info:
https://github.com/rofl0r/caprice32/blob/master/cap32.cpp#L4556 (caprice uses multilanguage keyb)
http://nukep.github.io/glium-sdl2/src/sdl2_sys/keycode.rs.html#39

@orbea as @Zlika points us on issue #8303 maybe we could fix SDL driver using scancodes instead.

doc: https://wiki.libsdl.org/SDL_Keysym

libsdl1 don't have the SDL_Scancode enum

typedef struct SDL_keysym {
    Uint8 scancode;         /**< hardware specific scancode */
    SDLKey sym;         /**< SDL virtual keysym */
    SDLMod mod;         /**< current key modifiers */
    Uint16 unicode;         /**< translated character */
} SDL_keysym;

but maybe it could be compatible.

OK: render in sdl2+sdl2_input
imagen

just need test SDL1 :dancer:

SDL1 need another solution because doesn't have scancodes...

Was this page helpful?
0 / 5 - 0 ratings