On Fri Jun 19 10:03:12 2026 +0000, Rémi Bernon wrote:
Well I'm still not sure it's worth keeping code for such very specific use case, if tightvncserver is the only X server we've found that doesn't use evdev-compatible scancodes (for the low value range), and if it's been broken because of XShape errors and been like this for a while without anybody complaining. Note that in addition to it being broken because of XShape, it seems that tightvncserver simply doesn't support XKB at all, and perhaps this is simply the source of our troubles. The Xkb xlib calls we do seem to mostly cope with the missing extension, but we could probably use that information to special case this scenario, if we really want to keep support for it. With the idea of getting rid of the fuzzy layout detection, it seems possible to treat all missing XKB support under a unique workaround. For instance a fallback keycode -> scancode mapping table like this seems to do the trick for me: ``` static WORD default_keyc2scan[0x100]; static BOOL use_xkb; static void init_default_keyc2scan( Display *display ) { static const WORD keysyms[] = { 0, XK_Escape, XK_1, XK_2, XK_3, XK_4, XK_5, XK_6, XK_7, XK_8, XK_9, XK_0, XK_minus, XK_equal, XK_BackSpace, XK_Tab, XK_q, XK_w, XK_e, XK_r, XK_t, XK_y, XK_u, XK_i, XK_o, XK_p, XK_braceleft, XK_braceright, XK_Return, XK_Control_L, XK_a, XK_s, XK_d, XK_f, XK_g, XK_h, XK_j, XK_k, XK_l, XK_semicolon, XK_apostrophe, XK_grave, XK_Shift_L, XK_backslash, XK_z, XK_x, XK_c, XK_v, XK_b, XK_n, XK_m, XK_comma, XK_period, XK_slash, XK_Shift_R, XK_asterisk, XK_Alt_L, XK_space, XK_Caps_Lock, XK_F1, XK_F2, XK_F3, XK_F4, XK_F5, XK_F6, XK_F7, XK_F8, XK_F9, XK_F10, XK_Num_Lock, XK_Scroll_Lock, XK_KP_7, XK_KP_8, XK_KP_9, XK_KP_Subtract, XK_KP_4, XK_KP_5, XK_KP_6, XK_KP_Add, XK_KP_1, XK_KP_2, XK_KP_3, XK_KP_0, XK_KP_Decimal, [0x5a] = XK_ISO_Level3_Shift, [KEY_RIGHTCTRL] = XK_Control_R, [KEY_LEFTMETA] = XK_Meta_L, [KEY_RIGHTMETA] = XK_Meta_R, [KEY_RIGHTALT] = XK_Alt_R, [KEY_HOME] = XK_Home, [KEY_END] = XK_End, [KEY_PAGEUP] = XK_Page_Up, [KEY_PAGEDOWN] = XK_Page_Down, [KEY_UP] = XK_Up, [KEY_DOWN] = XK_Down, [KEY_LEFT] = XK_Left, [KEY_RIGHT] = XK_Right, [KEY_F11] = XK_F11, [KEY_F12] = XK_F12, [KEY_DELETE] = XK_Delete, [KEY_KPENTER] = XK_KP_Enter, }; for (unsigned int keyc = min_keycode; keyc <= max_keycode; keyc++) { XKeyEvent event = { .display = display, .keycode = keyc }; unsigned int k; KeySym keysym; if (!(keysym = XLookupKeysym( &event, 0 ))) continue; for (k = 1; k < ARRAY_SIZE(keysyms); k++) if (keysyms[k] == keysym) break; if (k < ARRAY_SIZE(keysyms)) default_keyc2scan[keyc - min_keycode] = k; else WARN( "Failed to map keyc %#x keysym %#lx\n", keyc, keysym ); } } static WORD keyc2scan( unsigned int keycode, unsigned int state ) { unsigned int key = keycode - 8; if (!use_xkb) return default_keyc2scan[keycode - min_keycode]; /* ... */ /* in init_keyboard_layouts */ if (!use_xkb) init_default_keyc2scan( display ); /* ... */ /* in x11drv_init_keyboard */ use_xkb = XkbUseExtension( display, NULL, NULL ); ``` Yes, that's what I meant with "room for further cleanup and simplification". I guess it depends on what we want to support exactly and where we draw the line. @julliard?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10963#note_143607