# HG changeset patch # User Sam Lantinga # Date 1279693524 25200 # Node ID 95352c671a6ec10ec2faf6c787bc6c7ba8446b63 # Parent f8c3870af5a242702326d104121ba494a35fbbd3 Added support for keyboard repeat (only tested on Windows so far) diff -r f8c3870af5a2 -r 95352c671a6e include/SDL_events.h --- a/include/SDL_events.h Tue Jul 20 00:57:01 2010 -0700 +++ b/include/SDL_events.h Tue Jul 20 23:25:24 2010 -0700 @@ -132,7 +132,7 @@ Uint32 type; /**< ::SDL_KEYDOWN or ::SDL_KEYUP */ Uint32 windowID; /**< The window with keyboard focus, if any */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ - Uint8 padding1; + Uint8 repeat; /**< Non-zero if this is a key repeat */ Uint8 padding2; Uint8 padding3; SDL_keysym keysym; /**< The key that was pressed or released */ diff -r f8c3870af5a2 -r 95352c671a6e src/events/SDL_keyboard.c --- a/src/events/SDL_keyboard.c Tue Jul 20 00:57:01 2010 -0700 +++ b/src/events/SDL_keyboard.c Tue Jul 20 23:25:24 2010 -0700 @@ -566,7 +566,7 @@ for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) { if (keyboard->keystate[scancode] == SDL_PRESSED) { - SDL_SendKeyboardKey(SDL_RELEASED, scancode); + SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE); } } } @@ -627,7 +627,7 @@ } int -SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode) +SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat) { SDL_Keyboard *keyboard = &SDL_keyboard; int posted; @@ -732,7 +732,7 @@ } /* Drop events that don't change state */ - if (keyboard->keystate[scancode] == state) { + if (keyboard->keystate[scancode] == state && !repeat) { #if 0 printf("Keyboard event didn't change state - dropped!\n"); #endif @@ -748,6 +748,7 @@ SDL_Event event; event.key.type = type; event.key.state = state; + event.key.repeat = repeat ? 1 : 0; event.key.keysym.scancode = scancode; event.key.keysym.sym = keyboard->keymap[scancode]; event.key.keysym.mod = modstate; diff -r f8c3870af5a2 -r 95352c671a6e src/events/SDL_keyboard_c.h --- a/src/events/SDL_keyboard_c.h Tue Jul 20 00:57:01 2010 -0700 +++ b/src/events/SDL_keyboard_c.h Tue Jul 20 23:25:24 2010 -0700 @@ -49,7 +49,7 @@ extern void SDL_SetKeyboardFocus(SDL_Window * window); /* 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 */ extern int SDL_SendKeyboardText(const char *text); diff -r f8c3870af5a2 -r 95352c671a6e src/video/cocoa/SDL_cocoakeyboard.m --- a/src/video/cocoa/SDL_cocoakeyboard.m Tue Jul 20 00:57:01 2010 -0700 +++ b/src/video/cocoa/SDL_cocoakeyboard.m Tue Jul 20 23:25:24 2010 -0700 @@ -219,14 +219,14 @@ if (oldMask && oldMask != newMask) { /* modifier up event */ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */ 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 */ - 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 (bit == NSAlphaShiftKeyMask) { - SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]); + SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE); } } } @@ -251,9 +251,9 @@ newMask = newMods & device_independent_mask; if (oldMask && oldMask != newMask) { - SDL_SendKeyboardKey(SDL_RELEASED, scancode); + SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE); } else if (newMask && oldMask != newMask) { - SDL_SendKeyboardKey(SDL_PRESSED, scancode); + SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE); } } @@ -278,9 +278,9 @@ * find out which it is. */ if (new_dep_mask && old_dep_mask != new_dep_mask) { - SDL_SendKeyboardKey(SDL_PRESSED, scancode); + SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE); } else { - SDL_SendKeyboardKey(SDL_RELEASED, scancode); + SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE); } } @@ -351,7 +351,7 @@ /* In this case, we can't detect the keyboard, so use the left side * to represent both, and release it. */ - SDL_SendKeyboardKey(SDL_RELEASED, left_scancode); + SDL_SendKeyboardKey(SDL_RELEASED, left_scancode, SDL_FALSE); return; } @@ -362,10 +362,10 @@ * so I hope this doesn't cause other problems. */ 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 ) { - SDL_SendKeyboardKey(SDL_RELEASED, right_scancode); + SDL_SendKeyboardKey(SDL_RELEASED, right_scancode, SDL_FALSE); } } @@ -382,16 +382,16 @@ newMask = newMods & NSAlphaShiftKeyMask; if (oldMask != newMask) { - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE); } oldMask = oldMods & NSNumericPadKeyMask; newMask = newMods & NSNumericPadKeyMask; if (oldMask != newMask) { - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE); } } @@ -670,6 +670,7 @@ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; unsigned short scancode = [event keyCode]; SDL_scancode code; + SDL_bool repeat; #if 0 const char *text; #endif @@ -688,17 +689,18 @@ switch ([event type]) { case NSKeyDown: - if (![event isARepeat]) { + repeat = [event isARepeat] ? SDL_TRUE : SDL_FALSE; + if (!repeat) { /* See if we need to rebuild the keyboard layout */ UpdateKeymap(data); + } - SDL_SendKeyboardKey(SDL_PRESSED, code); + SDL_SendKeyboardKey(SDL_PRESSED, code, repeat); #if 1 - 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 or to Christian Walther . Mac virtual key code is %d.\n", scancode); - } + 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 or to Christian Walther . Mac virtual key code is %d.\n", scancode); + } #endif - } 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. */ [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; @@ -712,7 +714,7 @@ } break; case NSKeyUp: - SDL_SendKeyboardKey(SDL_RELEASED, code); + SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE); break; case NSFlagsChanged: /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */ diff -r f8c3870af5a2 -r 95352c671a6e src/video/uikit/SDL_uikitview.m --- a/src/video/uikit/SDL_uikitview.m Tue Jul 20 00:57:01 2010 -0700 +++ b/src/video/uikit/SDL_uikitview.m Tue Jul 20 23:25:24 2010 -0700 @@ -245,8 +245,8 @@ if ([string length] == 0) { /* it wants to replace text with nothing, ie a delete */ - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE, SDL_FALSE); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE, SDL_FALSE); } else { /* go through all the characters in the string we've been sent @@ -272,14 +272,14 @@ if (mod & KMOD_SHIFT) { /* 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 */ - SDL_SendKeyboardKey(SDL_PRESSED, code); - SDL_SendKeyboardKey(SDL_RELEASED, code); + SDL_SendKeyboardKey(SDL_PRESSED, code, SDL_FALSE); + SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE); if (mod & KMOD_SHIFT) { /* If character uses shift, press shift back up */ - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDL_FALSE); } } } diff -r f8c3870af5a2 -r 95352c671a6e src/video/win32/SDL_win32events.c --- a/src/video/win32/SDL_win32events.c Tue Jul 20 00:57:01 2010 -0700 +++ b/src/video/win32/SDL_win32events.c Tue Jul 20 23:25:24 2010 -0700 @@ -201,10 +201,12 @@ case WM_SYSKEYDOWN: case WM_KEYDOWN: { - /* Ignore repeated keys */ + SDL_bool repeat; + if (lParam & REPEATED_KEYMASK) { - returnCode = 0; - break; + repeat = SDL_TRUE; + } else { + repeat = SDL_FALSE; } wParam = RemapVKEY(wParam, lParam); @@ -244,7 +246,8 @@ } if (wParam < 256) { SDL_SendKeyboardKey(SDL_PRESSED, - data->videodata->key_layout[wParam]); + data->videodata->key_layout[wParam], + repeat); } } returnCode = 0; @@ -294,11 +297,13 @@ && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == SDL_RELEASED) { SDL_SendKeyboardKey(SDL_PRESSED, - data->videodata->key_layout[wParam]); + data->videodata->key_layout[wParam], + SDL_FALSE); } if (wParam < 256) { SDL_SendKeyboardKey(SDL_RELEASED, - data->videodata->key_layout[wParam]); + data->videodata->key_layout[wParam], + SDL_FALSE); } } returnCode = 0; diff -r f8c3870af5a2 -r 95352c671a6e src/video/x11/SDL_x11events.c --- a/src/video/x11/SDL_x11events.c Tue Jul 20 00:57:01 2010 -0700 +++ b/src/video/x11/SDL_x11events.c Tue Jul 20 23:25:24 2010 -0700 @@ -182,7 +182,8 @@ #ifdef DEBUG_XEVENTS printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode); #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 (videodata->key_layout[keycode] == SDLK_UNKNOWN) { int min_keycode, max_keycode; @@ -217,7 +218,7 @@ #ifdef DEBUG_XEVENTS printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); #endif - SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]); + SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode], SDL_FALSE); } break; diff -r f8c3870af5a2 -r 95352c671a6e test/checkkeys.c --- a/test/checkkeys.c Tue Jul 20 00:57:01 2010 -0700 +++ b/test/checkkeys.c Tue Jul 20 23:25:24 2010 -0700 @@ -53,7 +53,7 @@ } static void -PrintKey(SDL_keysym * sym, int pressed) +PrintKey(SDL_keysym * sym, SDL_bool pressed, SDL_bool repeat) { /* Print the keycode, name and state */ if (sym->sym) { @@ -87,6 +87,9 @@ } } print_modifiers(); + if (repeat) { + printf(" (repeat)"); + } printf("\n"); } @@ -134,10 +137,8 @@ SDL_WaitEvent(&event); switch (event.type) { case SDL_KEYDOWN: - PrintKey(&event.key.keysym, 1); - break; case SDL_KEYUP: - PrintKey(&event.key.keysym, 0); + PrintKey(&event.key.keysym, event.key.state, event.key.repeat); break; case SDL_TEXTINPUT: PrintText(event.text.text);