Fixed key repeat detection on X11, and simplified the code for everyone else.
authorSam Lantinga <slouken@libsdl.org>
Wed, 21 Jul 2010 21:47:12 -0700
changeset 4565e2d46c5c7483
parent 4563 ffd169948438
child 4566 40c833d951a1
Fixed key repeat detection on X11, and simplified the code for everyone else.
src/events/SDL_keyboard.c
src/events/SDL_keyboard_c.h
src/video/cocoa/SDL_cocoakeyboard.m
src/video/uikit/SDL_uikitview.m
src/video/win32/SDL_win32events.c
src/video/x11/SDL_x11events.c
     1.1 --- a/src/events/SDL_keyboard.c	Wed Jul 21 00:11:56 2010 -0700
     1.2 +++ b/src/events/SDL_keyboard.c	Wed Jul 21 21:47:12 2010 -0700
     1.3 @@ -566,7 +566,7 @@
     1.4  
     1.5      for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
     1.6          if (keyboard->keystate[scancode] == SDL_PRESSED) {
     1.7 -            SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
     1.8 +            SDL_SendKeyboardKey(SDL_RELEASED, scancode);
     1.9          }
    1.10      }
    1.11  }
    1.12 @@ -627,12 +627,13 @@
    1.13  }
    1.14  
    1.15  int
    1.16 -SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat)
    1.17 +SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode)
    1.18  {
    1.19      SDL_Keyboard *keyboard = &SDL_keyboard;
    1.20      int posted;
    1.21      Uint16 modstate;
    1.22      Uint32 type;
    1.23 +    Uint8 repeat;
    1.24  
    1.25      if (!scancode) {
    1.26          return 0;
    1.27 @@ -732,6 +733,7 @@
    1.28      }
    1.29  
    1.30      /* Drop events that don't change state */
    1.31 +    repeat = (state && keyboard->keystate[scancode]);
    1.32      if (keyboard->keystate[scancode] == state && !repeat) {
    1.33  #if 0
    1.34          printf("Keyboard event didn't change state - dropped!\n");
    1.35 @@ -748,7 +750,7 @@
    1.36          SDL_Event event;
    1.37          event.key.type = type;
    1.38          event.key.state = state;
    1.39 -        event.key.repeat = repeat ? 1 : 0;
    1.40 +        event.key.repeat = repeat;
    1.41          event.key.keysym.scancode = scancode;
    1.42          event.key.keysym.sym = keyboard->keymap[scancode];
    1.43          event.key.keysym.mod = modstate;
     2.1 --- a/src/events/SDL_keyboard_c.h	Wed Jul 21 00:11:56 2010 -0700
     2.2 +++ b/src/events/SDL_keyboard_c.h	Wed Jul 21 21:47:12 2010 -0700
     2.3 @@ -49,7 +49,7 @@
     2.4  extern void SDL_SetKeyboardFocus(SDL_Window * window);
     2.5  
     2.6  /* Send a keyboard key event */
     2.7 -extern int SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat);
     2.8 +extern int SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode);
     2.9  
    2.10  /* Send keyboard text input */
    2.11  extern int SDL_SendKeyboardText(const char *text);
     3.1 --- a/src/video/cocoa/SDL_cocoakeyboard.m	Wed Jul 21 00:11:56 2010 -0700
     3.2 +++ b/src/video/cocoa/SDL_cocoakeyboard.m	Wed Jul 21 21:47:12 2010 -0700
     3.3 @@ -219,14 +219,14 @@
     3.4          if (oldMask && oldMask != newMask) {        /* modifier up event */
     3.5              /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
     3.6              if (bit == NSAlphaShiftKeyMask) {
     3.7 -                SDL_SendKeyboardKey(SDL_PRESSED, mapping[i], SDL_FALSE);
     3.8 +                SDL_SendKeyboardKey(SDL_PRESSED, mapping[i]);
     3.9              }
    3.10 -            SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE);
    3.11 +            SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]);
    3.12          } else if (newMask && oldMask != newMask) { /* modifier down event */
    3.13 -            SDL_SendKeyboardKey(SDL_PRESSED, mapping[i], SDL_FALSE);
    3.14 +            SDL_SendKeyboardKey(SDL_PRESSED, mapping[i]);
    3.15              /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
    3.16              if (bit == NSAlphaShiftKeyMask) {
    3.17 -                SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE);
    3.18 +                SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]);
    3.19              }
    3.20          }
    3.21      }
    3.22 @@ -251,9 +251,9 @@
    3.23      newMask = newMods & device_independent_mask;
    3.24      
    3.25      if (oldMask && oldMask != newMask) {
    3.26 -        SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
    3.27 +        SDL_SendKeyboardKey(SDL_RELEASED, scancode);
    3.28      } else if (newMask && oldMask != newMask) {
    3.29 -        SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE);
    3.30 +        SDL_SendKeyboardKey(SDL_PRESSED, scancode);
    3.31      }
    3.32  }
    3.33  
    3.34 @@ -278,9 +278,9 @@
    3.35       * find out which it is.
    3.36       */
    3.37      if (new_dep_mask && old_dep_mask != new_dep_mask) {
    3.38 -        SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE);
    3.39 +        SDL_SendKeyboardKey(SDL_PRESSED, scancode);
    3.40      } else {
    3.41 -        SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
    3.42 +        SDL_SendKeyboardKey(SDL_RELEASED, scancode);
    3.43      }
    3.44  }
    3.45  
    3.46 @@ -351,7 +351,7 @@
    3.47          /* In this case, we can't detect the keyboard, so use the left side 
    3.48           * to represent both, and release it. 
    3.49           */
    3.50 -        SDL_SendKeyboardKey(SDL_RELEASED, left_scancode, SDL_FALSE);
    3.51 +        SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
    3.52          return;
    3.53      }
    3.54  
    3.55 @@ -362,10 +362,10 @@
    3.56       * so I hope this doesn't cause other problems.
    3.57       */
    3.58      if ( left_device_dependent_mask & oldMods ) {
    3.59 -        SDL_SendKeyboardKey(SDL_RELEASED, left_scancode, SDL_FALSE);
    3.60 +        SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
    3.61      }
    3.62      if ( right_device_dependent_mask & oldMods ) {
    3.63 -        SDL_SendKeyboardKey(SDL_RELEASED, right_scancode, SDL_FALSE);
    3.64 +        SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
    3.65      }
    3.66  }
    3.67  
    3.68 @@ -382,16 +382,16 @@
    3.69      newMask = newMods & NSAlphaShiftKeyMask;
    3.70  
    3.71      if (oldMask != newMask) {
    3.72 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE);
    3.73 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE);
    3.74 +        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
    3.75 +        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
    3.76      }
    3.77  
    3.78      oldMask = oldMods & NSNumericPadKeyMask;
    3.79      newMask = newMods & NSNumericPadKeyMask;
    3.80  
    3.81      if (oldMask != newMask) {
    3.82 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE);
    3.83 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE);
    3.84 +        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
    3.85 +        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
    3.86      }
    3.87  }
    3.88  
    3.89 @@ -670,7 +670,6 @@
    3.90      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    3.91      unsigned short scancode = [event keyCode];
    3.92      SDL_scancode code;
    3.93 -    SDL_bool repeat;
    3.94  #if 0
    3.95      const char *text;
    3.96  #endif
    3.97 @@ -689,13 +688,12 @@
    3.98  
    3.99      switch ([event type]) {
   3.100      case NSKeyDown:
   3.101 -        repeat = [event isARepeat] ? SDL_TRUE : SDL_FALSE;
   3.102 -        if (!repeat) {
   3.103 +        if (![event isARepeat]) {
   3.104              /* See if we need to rebuild the keyboard layout */
   3.105              UpdateKeymap(data);
   3.106          }
   3.107  
   3.108 -        SDL_SendKeyboardKey(SDL_PRESSED, code, repeat);
   3.109 +        SDL_SendKeyboardKey(SDL_PRESSED, code);
   3.110  #if 1
   3.111          if (code == SDL_SCANCODE_UNKNOWN) {
   3.112              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);
   3.113 @@ -714,7 +712,7 @@
   3.114          }
   3.115          break;
   3.116      case NSKeyUp:
   3.117 -        SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE);
   3.118 +        SDL_SendKeyboardKey(SDL_RELEASED, code);
   3.119          break;
   3.120      case NSFlagsChanged:
   3.121          /* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
     4.1 --- a/src/video/uikit/SDL_uikitview.m	Wed Jul 21 00:11:56 2010 -0700
     4.2 +++ b/src/video/uikit/SDL_uikitview.m	Wed Jul 21 21:47:12 2010 -0700
     4.3 @@ -245,8 +245,8 @@
     4.4  	
     4.5  	if ([string length] == 0) {
     4.6  		/* it wants to replace text with nothing, ie a delete */
     4.7 -		SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE, SDL_FALSE);
     4.8 -		SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE, SDL_FALSE);
     4.9 +		SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE);
    4.10 +		SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE);
    4.11  	}
    4.12  	else {
    4.13  		/* go through all the characters in the string we've been sent
    4.14 @@ -272,14 +272,14 @@
    4.15  			
    4.16  			if (mod & KMOD_SHIFT) {
    4.17  				/* If character uses shift, press shift down */
    4.18 -				SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDL_FALSE);
    4.19 +				SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
    4.20  			}
    4.21  			/* send a keydown and keyup even for the character */
    4.22 -			SDL_SendKeyboardKey(SDL_PRESSED, code, SDL_FALSE);
    4.23 -			SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE);
    4.24 +			SDL_SendKeyboardKey(SDL_PRESSED, code);
    4.25 +			SDL_SendKeyboardKey(SDL_RELEASED, code);
    4.26  			if (mod & KMOD_SHIFT) {
    4.27  				/* If character uses shift, press shift back up */
    4.28 -				SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDL_FALSE);
    4.29 +				SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
    4.30  			}			
    4.31  		}
    4.32  	}
     5.1 --- a/src/video/win32/SDL_win32events.c	Wed Jul 21 00:11:56 2010 -0700
     5.2 +++ b/src/video/win32/SDL_win32events.c	Wed Jul 21 21:47:12 2010 -0700
     5.3 @@ -205,14 +205,6 @@
     5.4      case WM_SYSKEYDOWN:
     5.5      case WM_KEYDOWN:
     5.6          {
     5.7 -            SDL_bool repeat;
     5.8 -
     5.9 -            if (lParam & REPEATED_KEYMASK) {
    5.10 -                repeat = SDL_TRUE;
    5.11 -            } else {
    5.12 -                repeat = SDL_FALSE;
    5.13 -            }
    5.14 -
    5.15              wParam = RemapVKEY(wParam, lParam);
    5.16              switch (wParam) {
    5.17              case VK_CONTROL:
    5.18 @@ -250,8 +242,7 @@
    5.19              }
    5.20              if (wParam < 256) {
    5.21                  SDL_SendKeyboardKey(SDL_PRESSED,
    5.22 -                                    data->videodata->key_layout[wParam],
    5.23 -                                    repeat);
    5.24 +                                    data->videodata->key_layout[wParam]);
    5.25              }
    5.26          }
    5.27          returnCode = 0;
    5.28 @@ -301,13 +292,11 @@
    5.29                  && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
    5.30                  SDL_RELEASED) {
    5.31                  SDL_SendKeyboardKey(SDL_PRESSED,
    5.32 -                                    data->videodata->key_layout[wParam],
    5.33 -                                    SDL_FALSE);
    5.34 +                                    data->videodata->key_layout[wParam]);
    5.35              }
    5.36              if (wParam < 256) {
    5.37                  SDL_SendKeyboardKey(SDL_RELEASED,
    5.38 -                                    data->videodata->key_layout[wParam],
    5.39 -                                    SDL_FALSE);
    5.40 +                                    data->videodata->key_layout[wParam]);
    5.41              }
    5.42          }
    5.43          returnCode = 0;
     6.1 --- a/src/video/x11/SDL_x11events.c	Wed Jul 21 00:11:56 2010 -0700
     6.2 +++ b/src/video/x11/SDL_x11events.c	Wed Jul 21 21:47:12 2010 -0700
     6.3 @@ -36,6 +36,24 @@
     6.4  
     6.5  /*#define DEBUG_XEVENTS*/
     6.6  
     6.7 +/* Check to see if this is a repeated key.
     6.8 +   (idea shamelessly lifted from GII -- thanks guys! :)
     6.9 + */
    6.10 +static SDL_bool X11_KeyRepeat(Display *display, XEvent *event)
    6.11 +{
    6.12 +    XEvent peekevent;
    6.13 +
    6.14 +    if (XPending(display)) {
    6.15 +        XPeekEvent(display, &peekevent);
    6.16 +        if ((peekevent.type == KeyPress) &&
    6.17 +            (peekevent.xkey.keycode == event->xkey.keycode) &&
    6.18 +            ((peekevent.xkey.time-event->xkey.time) < 2)) {
    6.19 +            return SDL_TRUE;
    6.20 +        }
    6.21 +    }
    6.22 +    return SDL_FALSE;
    6.23 +}
    6.24 +
    6.25  static void
    6.26  X11_DispatchEvent(_THIS)
    6.27  {
    6.28 @@ -176,14 +194,14 @@
    6.29      case KeyPress:{
    6.30              KeyCode keycode = xevent.xkey.keycode;
    6.31              KeySym keysym = NoSymbol;
    6.32 +            SDL_scancode scancode;
    6.33              char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
    6.34              Status status = 0;
    6.35  
    6.36  #ifdef DEBUG_XEVENTS
    6.37              printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
    6.38  #endif
    6.39 -            /* FIXME: How do we tell if this was a key repeat? */
    6.40 -            SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode], SDL_FALSE);
    6.41 +            SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
    6.42  #if 1
    6.43              if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
    6.44                  int min_keycode, max_keycode;
    6.45 @@ -218,7 +236,11 @@
    6.46  #ifdef DEBUG_XEVENTS
    6.47              printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
    6.48  #endif
    6.49 -            SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode], SDL_FALSE);
    6.50 +            if (X11_KeyRepeat(display, &xevent)) {
    6.51 +                /* We're about to get a repeated key down, ignore the key up */
    6.52 +                break;
    6.53 +            }
    6.54 +            SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
    6.55          }
    6.56          break;
    6.57