Commit 0e59ffc8 authored by Sam Lantinga's avatar Sam Lantinga

Added support for keyboard repeat (only tested on Windows so far)

parent 871f3256
...@@ -132,7 +132,7 @@ typedef struct SDL_KeyboardEvent ...@@ -132,7 +132,7 @@ typedef struct SDL_KeyboardEvent
Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
Uint32 windowID; /**< The window with keyboard focus, if any */ Uint32 windowID; /**< The window with keyboard focus, if any */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 padding1; Uint8 repeat; /**< Non-zero if this is a key repeat */
Uint8 padding2; Uint8 padding2;
Uint8 padding3; Uint8 padding3;
SDL_keysym keysym; /**< The key that was pressed or released */ SDL_keysym keysym; /**< The key that was pressed or released */
......
...@@ -566,7 +566,7 @@ SDL_ResetKeyboard(void) ...@@ -566,7 +566,7 @@ SDL_ResetKeyboard(void)
for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) { for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
if (keyboard->keystate[scancode] == SDL_PRESSED) { if (keyboard->keystate[scancode] == SDL_PRESSED) {
SDL_SendKeyboardKey(SDL_RELEASED, scancode); SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
} }
} }
} }
...@@ -627,7 +627,7 @@ SDL_SetKeyboardFocus(SDL_Window * window) ...@@ -627,7 +627,7 @@ SDL_SetKeyboardFocus(SDL_Window * window)
} }
int int
SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode) SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat)
{ {
SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Keyboard *keyboard = &SDL_keyboard;
int posted; int posted;
...@@ -732,7 +732,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode) ...@@ -732,7 +732,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode)
} }
/* Drop events that don't change state */ /* Drop events that don't change state */
if (keyboard->keystate[scancode] == state) { if (keyboard->keystate[scancode] == state && !repeat) {
#if 0 #if 0
printf("Keyboard event didn't change state - dropped!\n"); printf("Keyboard event didn't change state - dropped!\n");
#endif #endif
...@@ -748,6 +748,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode) ...@@ -748,6 +748,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode)
SDL_Event event; SDL_Event event;
event.key.type = type; event.key.type = type;
event.key.state = state; event.key.state = state;
event.key.repeat = repeat ? 1 : 0;
event.key.keysym.scancode = scancode; event.key.keysym.scancode = scancode;
event.key.keysym.sym = keyboard->keymap[scancode]; event.key.keysym.sym = keyboard->keymap[scancode];
event.key.keysym.mod = modstate; event.key.keysym.mod = modstate;
......
...@@ -49,7 +49,7 @@ extern void SDL_SetScancodeName(SDL_scancode scancode, const char *name); ...@@ -49,7 +49,7 @@ extern void SDL_SetScancodeName(SDL_scancode scancode, const char *name);
extern void SDL_SetKeyboardFocus(SDL_Window * window); extern void SDL_SetKeyboardFocus(SDL_Window * window);
/* Send a keyboard key event */ /* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode); extern int SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat);
/* Send keyboard text input */ /* Send keyboard text input */
extern int SDL_SendKeyboardText(const char *text); extern int SDL_SendKeyboardText(const char *text);
......
...@@ -219,14 +219,14 @@ DoUnsidedModifiers(unsigned short scancode, ...@@ -219,14 +219,14 @@ DoUnsidedModifiers(unsigned short scancode,
if (oldMask && oldMask != newMask) { /* modifier up event */ if (oldMask && oldMask != newMask) { /* modifier up event */
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask) { if (bit == NSAlphaShiftKeyMask) {
SDL_SendKeyboardKey(SDL_PRESSED, mapping[i]); SDL_SendKeyboardKey(SDL_PRESSED, mapping[i], SDL_FALSE);
} }
SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]); SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE);
} else if (newMask && oldMask != newMask) { /* modifier down event */ } else if (newMask && oldMask != newMask) { /* modifier down event */
SDL_SendKeyboardKey(SDL_PRESSED, mapping[i]); SDL_SendKeyboardKey(SDL_PRESSED, mapping[i], SDL_FALSE);
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask) { if (bit == NSAlphaShiftKeyMask) {
SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]); SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE);
} }
} }
} }
...@@ -251,9 +251,9 @@ HandleNonDeviceModifier(unsigned int device_independent_mask, ...@@ -251,9 +251,9 @@ HandleNonDeviceModifier(unsigned int device_independent_mask,
newMask = newMods & device_independent_mask; newMask = newMods & device_independent_mask;
if (oldMask && oldMask != newMask) { if (oldMask && oldMask != newMask) {
SDL_SendKeyboardKey(SDL_RELEASED, scancode); SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
} else if (newMask && oldMask != newMask) { } else if (newMask && oldMask != newMask) {
SDL_SendKeyboardKey(SDL_PRESSED, scancode); SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE);
} }
} }
...@@ -278,9 +278,9 @@ HandleModifierOneSide(unsigned int oldMods, unsigned int newMods, ...@@ -278,9 +278,9 @@ HandleModifierOneSide(unsigned int oldMods, unsigned int newMods,
* find out which it is. * find out which it is.
*/ */
if (new_dep_mask && old_dep_mask != new_dep_mask) { if (new_dep_mask && old_dep_mask != new_dep_mask) {
SDL_SendKeyboardKey(SDL_PRESSED, scancode); SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE);
} else { } else {
SDL_SendKeyboardKey(SDL_RELEASED, scancode); SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
} }
} }
...@@ -351,7 +351,7 @@ ReleaseModifierSide(unsigned int device_independent_mask, ...@@ -351,7 +351,7 @@ ReleaseModifierSide(unsigned int device_independent_mask,
/* In this case, we can't detect the keyboard, so use the left side /* In this case, we can't detect the keyboard, so use the left side
* to represent both, and release it. * to represent both, and release it.
*/ */
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode); SDL_SendKeyboardKey(SDL_RELEASED, left_scancode, SDL_FALSE);
return; return;
} }
...@@ -362,10 +362,10 @@ ReleaseModifierSide(unsigned int device_independent_mask, ...@@ -362,10 +362,10 @@ ReleaseModifierSide(unsigned int device_independent_mask,
* so I hope this doesn't cause other problems. * so I hope this doesn't cause other problems.
*/ */
if ( left_device_dependent_mask & oldMods ) { if ( left_device_dependent_mask & oldMods ) {
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode); SDL_SendKeyboardKey(SDL_RELEASED, left_scancode, SDL_FALSE);
} }
if ( right_device_dependent_mask & oldMods ) { if ( right_device_dependent_mask & oldMods ) {
SDL_SendKeyboardKey(SDL_RELEASED, right_scancode); SDL_SendKeyboardKey(SDL_RELEASED, right_scancode, SDL_FALSE);
} }
} }
...@@ -382,16 +382,16 @@ HandleCapsLock(unsigned short scancode, ...@@ -382,16 +382,16 @@ HandleCapsLock(unsigned short scancode,
newMask = newMods & NSAlphaShiftKeyMask; newMask = newMods & NSAlphaShiftKeyMask;
if (oldMask != newMask) { if (oldMask != newMask) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE);
} }
oldMask = oldMods & NSNumericPadKeyMask; oldMask = oldMods & NSNumericPadKeyMask;
newMask = newMods & NSNumericPadKeyMask; newMask = newMods & NSNumericPadKeyMask;
if (oldMask != newMask) { if (oldMask != newMask) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE);
} }
} }
...@@ -670,6 +670,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event) ...@@ -670,6 +670,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
unsigned short scancode = [event keyCode]; unsigned short scancode = [event keyCode];
SDL_scancode code; SDL_scancode code;
SDL_bool repeat;
#if 0 #if 0
const char *text; const char *text;
#endif #endif
...@@ -688,17 +689,18 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event) ...@@ -688,17 +689,18 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
switch ([event type]) { switch ([event type]) {
case NSKeyDown: case NSKeyDown:
if (![event isARepeat]) { repeat = [event isARepeat] ? SDL_TRUE : SDL_FALSE;
if (!repeat) {
/* See if we need to rebuild the keyboard layout */ /* See if we need to rebuild the keyboard layout */
UpdateKeymap(data); UpdateKeymap(data);
}
SDL_SendKeyboardKey(SDL_PRESSED, code); SDL_SendKeyboardKey(SDL_PRESSED, code, repeat);
#if 1 #if 1
if (code == SDL_SCANCODE_UNKNOWN) { if (code == SDL_SCANCODE_UNKNOWN) {
fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode); fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
}
#endif
} }
#endif
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
/* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */
[data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
...@@ -712,7 +714,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event) ...@@ -712,7 +714,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
} }
break; break;
case NSKeyUp: case NSKeyUp:
SDL_SendKeyboardKey(SDL_RELEASED, code); SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE);
break; break;
case NSFlagsChanged: case NSFlagsChanged:
/* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */ /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
......
...@@ -245,8 +245,8 @@ ...@@ -245,8 +245,8 @@
if ([string length] == 0) { if ([string length] == 0) {
/* it wants to replace text with nothing, ie a delete */ /* it wants to replace text with nothing, ie a delete */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE); SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE); SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE, SDL_FALSE);
} }
else { else {
/* go through all the characters in the string we've been sent /* go through all the characters in the string we've been sent
...@@ -272,14 +272,14 @@ ...@@ -272,14 +272,14 @@
if (mod & KMOD_SHIFT) { if (mod & KMOD_SHIFT) {
/* If character uses shift, press shift down */ /* If character uses shift, press shift down */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDL_FALSE);
} }
/* send a keydown and keyup even for the character */ /* send a keydown and keyup even for the character */
SDL_SendKeyboardKey(SDL_PRESSED, code); SDL_SendKeyboardKey(SDL_PRESSED, code, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, code); SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE);
if (mod & KMOD_SHIFT) { if (mod & KMOD_SHIFT) {
/* If character uses shift, press shift back up */ /* If character uses shift, press shift back up */
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDL_FALSE);
} }
} }
} }
......
...@@ -201,10 +201,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -201,10 +201,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYDOWN: case WM_KEYDOWN:
{ {
/* Ignore repeated keys */ SDL_bool repeat;
if (lParam & REPEATED_KEYMASK) { if (lParam & REPEATED_KEYMASK) {
returnCode = 0; repeat = SDL_TRUE;
break; } else {
repeat = SDL_FALSE;
} }
wParam = RemapVKEY(wParam, lParam); wParam = RemapVKEY(wParam, lParam);
...@@ -244,7 +246,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -244,7 +246,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} }
if (wParam < 256) { if (wParam < 256) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SendKeyboardKey(SDL_PRESSED,
data->videodata->key_layout[wParam]); data->videodata->key_layout[wParam],
repeat);
} }
} }
returnCode = 0; returnCode = 0;
...@@ -294,11 +297,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -294,11 +297,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
&& SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
SDL_RELEASED) { SDL_RELEASED) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SendKeyboardKey(SDL_PRESSED,
data->videodata->key_layout[wParam]); data->videodata->key_layout[wParam],
SDL_FALSE);
} }
if (wParam < 256) { if (wParam < 256) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SendKeyboardKey(SDL_RELEASED,
data->videodata->key_layout[wParam]); data->videodata->key_layout[wParam],
SDL_FALSE);
} }
} }
returnCode = 0; returnCode = 0;
......
...@@ -182,7 +182,8 @@ X11_DispatchEvent(_THIS) ...@@ -182,7 +182,8 @@ X11_DispatchEvent(_THIS)
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif #endif
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); /* FIXME: How do we tell if this was a key repeat? */
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode], SDL_FALSE);
#if 1 #if 1
if (videodata->key_layout[keycode] == SDLK_UNKNOWN) { if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
int min_keycode, max_keycode; int min_keycode, max_keycode;
...@@ -217,7 +218,7 @@ X11_DispatchEvent(_THIS) ...@@ -217,7 +218,7 @@ X11_DispatchEvent(_THIS)
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif #endif
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]); SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode], SDL_FALSE);
} }
break; break;
......
...@@ -53,7 +53,7 @@ print_modifiers(void) ...@@ -53,7 +53,7 @@ print_modifiers(void)
} }
static void static void
PrintKey(SDL_keysym * sym, int pressed) PrintKey(SDL_keysym * sym, SDL_bool pressed, SDL_bool repeat)
{ {
/* Print the keycode, name and state */ /* Print the keycode, name and state */
if (sym->sym) { if (sym->sym) {
...@@ -87,6 +87,9 @@ PrintKey(SDL_keysym * sym, int pressed) ...@@ -87,6 +87,9 @@ PrintKey(SDL_keysym * sym, int pressed)
} }
} }
print_modifiers(); print_modifiers();
if (repeat) {
printf(" (repeat)");
}
printf("\n"); printf("\n");
} }
...@@ -134,10 +137,8 @@ main(int argc, char *argv[]) ...@@ -134,10 +137,8 @@ main(int argc, char *argv[])
SDL_WaitEvent(&event); SDL_WaitEvent(&event);
switch (event.type) { switch (event.type) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
PrintKey(&event.key.keysym, 1);
break;
case SDL_KEYUP: case SDL_KEYUP:
PrintKey(&event.key.keysym, 0); PrintKey(&event.key.keysym, event.key.state, event.key.repeat);
break; break;
case SDL_TEXTINPUT: case SDL_TEXTINPUT:
PrintText(event.text.text); PrintText(event.text.text);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment