events: improve keyboard modifiers handling Use remapped key codes (SDL), instead of scan codes, to track modifiers state. --- src/events/SDL_keyboard.c | 134 ++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 77 deletions(-) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index ed4043e..87c272a 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -662,6 +662,8 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) { SDL_Keyboard *keyboard = &SDL_keyboard; int posted; + SDL_Keymod modifier; + SDL_Keycode keycode; Uint16 modstate; Uint32 type; Uint8 repeat; @@ -673,82 +675,6 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode), state == SDL_PRESSED ? "pressed" : "released"); #endif - if (state == SDL_PRESSED) { - modstate = keyboard->modstate; - switch (scancode) { - case SDL_SCANCODE_NUMLOCKCLEAR: - keyboard->modstate ^= KMOD_NUM; - break; - case SDL_SCANCODE_CAPSLOCK: - keyboard->modstate ^= KMOD_CAPS; - break; - case SDL_SCANCODE_LCTRL: - keyboard->modstate |= KMOD_LCTRL; - break; - case SDL_SCANCODE_RCTRL: - keyboard->modstate |= KMOD_RCTRL; - break; - case SDL_SCANCODE_LSHIFT: - keyboard->modstate |= KMOD_LSHIFT; - break; - case SDL_SCANCODE_RSHIFT: - keyboard->modstate |= KMOD_RSHIFT; - break; - case SDL_SCANCODE_LALT: - keyboard->modstate |= KMOD_LALT; - break; - case SDL_SCANCODE_RALT: - keyboard->modstate |= KMOD_RALT; - break; - case SDL_SCANCODE_LGUI: - keyboard->modstate |= KMOD_LGUI; - break; - case SDL_SCANCODE_RGUI: - keyboard->modstate |= KMOD_RGUI; - break; - case SDL_SCANCODE_MODE: - keyboard->modstate |= KMOD_MODE; - break; - default: - break; - } - } else { - switch (scancode) { - case SDL_SCANCODE_NUMLOCKCLEAR: - case SDL_SCANCODE_CAPSLOCK: - break; - case SDL_SCANCODE_LCTRL: - keyboard->modstate &= ~KMOD_LCTRL; - break; - case SDL_SCANCODE_RCTRL: - keyboard->modstate &= ~KMOD_RCTRL; - break; - case SDL_SCANCODE_LSHIFT: - keyboard->modstate &= ~KMOD_LSHIFT; - break; - case SDL_SCANCODE_RSHIFT: - keyboard->modstate &= ~KMOD_RSHIFT; - break; - case SDL_SCANCODE_LALT: - keyboard->modstate &= ~KMOD_LALT; - break; - case SDL_SCANCODE_RALT: - keyboard->modstate &= ~KMOD_RALT; - break; - case SDL_SCANCODE_LGUI: - keyboard->modstate &= ~KMOD_LGUI; - break; - case SDL_SCANCODE_RGUI: - keyboard->modstate &= ~KMOD_RGUI; - break; - case SDL_SCANCODE_MODE: - keyboard->modstate &= ~KMOD_MODE; - break; - default: - break; - } - modstate = keyboard->modstate; - } /* Figure out what type of event this is */ switch (state) { @@ -775,6 +701,60 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) /* Update internal keyboard state */ keyboard->keystate[scancode] = state; + keycode = keyboard->keymap[scancode]; + + /* Update modifiers state if applicable */ + switch (keycode) { + case SDLK_LCTRL: + modifier = KMOD_LCTRL; + break; + case SDLK_RCTRL: + modifier = KMOD_RCTRL; + break; + case SDLK_LSHIFT: + modifier = KMOD_LSHIFT; + break; + case SDLK_RSHIFT: + modifier = KMOD_RSHIFT; + break; + case SDLK_LALT: + modifier = KMOD_LALT; + break; + case SDLK_RALT: + modifier = KMOD_RALT; + break; + case SDLK_LGUI: + modifier = KMOD_LGUI; + break; + case SDLK_RGUI: + modifier = KMOD_RGUI; + break; + case SDLK_MODE: + modifier = KMOD_MODE; + break; + default: + modifier = KMOD_NONE; + break; + } + if (SDL_KEYDOWN == type) { + modstate = keyboard->modstate; + switch (keycode) { + case SDLK_NUMLOCKCLEAR: + keyboard->modstate ^= KMOD_NUM; + break; + case SDLK_CAPSLOCK: + keyboard->modstate ^= KMOD_CAPS; + break; + default: + keyboard->modstate |= modifier; + break; + } + } + else { + keyboard->modstate &= ~modifier; + modstate = keyboard->modstate; + } + /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(type) == SDL_ENABLE) { @@ -783,7 +763,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) event.key.state = state; event.key.repeat = repeat; event.key.keysym.scancode = scancode; - event.key.keysym.sym = keyboard->keymap[scancode]; + event.key.keysym.sym = keycode; event.key.keysym.mod = modstate; event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; posted = (SDL_PushEvent(&event) > 0); -- 2.1.0