From c3d1037665c1b058d3c1f99d7aa0372145a938dd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 23 Mar 2014 09:44:04 -0700 Subject: [PATCH] Better keyboard detection when some of the keys are remapped, thanks to Lewis Wall --- src/video/x11/SDL_x11keyboard.c | 42 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 36034606e..5014b7181 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -207,14 +207,20 @@ X11_InitKeyboard(_THIS) } fingerprint[] = { { SDL_SCANCODE_HOME, XK_Home, 0 }, { SDL_SCANCODE_PAGEUP, XK_Prior, 0 }, - { SDL_SCANCODE_PAGEDOWN, XK_Next, 0 }, + { SDL_SCANCODE_UP, XK_Up, 0 }, + { SDL_SCANCODE_LEFT, XK_Left, 0 }, + { SDL_SCANCODE_DELETE, XK_Delete, 0 }, + { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 }, }; - SDL_bool fingerprint_detected; + int best_distance; + int best_index; + int distance; X11_XAutoRepeatOn(data->display); /* Try to determine which scancodes are being used based on fingerprint */ - fingerprint_detected = SDL_FALSE; + best_distance = SDL_arraysize(fingerprint) + 1; + best_index = -1; X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode); for (i = 0; i < SDL_arraysize(fingerprint); ++i) { fingerprint[i].value = @@ -226,28 +232,28 @@ X11_InitKeyboard(_THIS) if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) { continue; } + distance = 0; for (j = 0; j < SDL_arraysize(fingerprint); ++j) { if (fingerprint[j].value < 0 || fingerprint[j].value >= scancode_set[i].table_size) { - break; - } - if (scancode_set[i].table[fingerprint[j].value] != - fingerprint[j].scancode) { - break; + distance += 1; + } else if (scancode_set[i].table[fingerprint[j].value] != fingerprint[j].scancode) { + distance += 1; } } - if (j == SDL_arraysize(fingerprint)) { -#ifdef DEBUG_KEYBOARD - printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", i, min_keycode, max_keycode, scancode_set[i].table_size); -#endif - SDL_memcpy(&data->key_layout[min_keycode], scancode_set[i].table, - sizeof(SDL_Scancode) * scancode_set[i].table_size); - fingerprint_detected = SDL_TRUE; - break; + if (distance < best_distance) { + best_distance = distance; + best_index = i; } } - - if (!fingerprint_detected) { + if (best_index >= 0 && best_distance <= 2) { +#ifdef DEBUG_KEYBOARD + printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", best_index, min_keycode, max_keycode, scancode_set[best_index].table_size); +#endif + SDL_memcpy(&data->key_layout[min_keycode], scancode_set[best_index].table, + sizeof(SDL_Scancode) * scancode_set[best_index].table_size); + } + else { SDL_Keycode keymap[SDL_NUM_SCANCODES]; printf