Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Fixed key repeat detection on X11, and simplified the code for everyo…
Browse files Browse the repository at this point in the history
…ne else.
  • Loading branch information
slouken committed Jul 22, 2010
1 parent 61042ca commit a44d403
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 47 deletions.
8 changes: 5 additions & 3 deletions src/events/SDL_keyboard.c
Expand Up @@ -566,7 +566,7 @@ SDL_ResetKeyboard(void)

for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) {
if (keyboard->keystate[scancode] == SDL_PRESSED) {
SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
}
}
Expand Down Expand Up @@ -627,12 +627,13 @@ SDL_SetKeyboardFocus(SDL_Window * window)
}

int
SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat)
SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
int posted;
Uint16 modstate;
Uint32 type;
Uint8 repeat;

if (!scancode) {
return 0;
Expand Down Expand Up @@ -732,6 +733,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat)
}

/* Drop events that don't change state */
repeat = (state && keyboard->keystate[scancode]);
if (keyboard->keystate[scancode] == state && !repeat) {
#if 0
printf("Keyboard event didn't change state - dropped!\n");
Expand All @@ -748,7 +750,7 @@ SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat)
SDL_Event event;
event.key.type = type;
event.key.state = state;
event.key.repeat = repeat ? 1 : 0;
event.key.repeat = repeat;
event.key.keysym.scancode = scancode;
event.key.keysym.sym = keyboard->keymap[scancode];
event.key.keysym.mod = modstate;
Expand Down
2 changes: 1 addition & 1 deletion src/events/SDL_keyboard_c.h
Expand Up @@ -49,7 +49,7 @@ extern void SDL_SetScancodeName(SDL_scancode scancode, const char *name);
extern void SDL_SetKeyboardFocus(SDL_Window * window);

/* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode, SDL_bool repeat);
extern int SDL_SendKeyboardKey(Uint8 state, SDL_scancode scancode);

/* Send keyboard text input */
extern int SDL_SendKeyboardText(const char *text);
Expand Down
38 changes: 18 additions & 20 deletions src/video/cocoa/SDL_cocoakeyboard.m
Expand Up @@ -219,14 +219,14 @@ - (NSArray *) validAttributesForMarkedText
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_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, mapping[i]);
}
SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]);
} else if (newMask && oldMask != newMask) { /* modifier down event */
SDL_SendKeyboardKey(SDL_PRESSED, mapping[i], SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, mapping[i]);
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask) {
SDL_SendKeyboardKey(SDL_RELEASED, mapping[i], SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, mapping[i]);
}
}
}
Expand All @@ -251,9 +251,9 @@ - (NSArray *) validAttributesForMarkedText
newMask = newMods & device_independent_mask;

if (oldMask && oldMask != newMask) {
SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
} else if (newMask && oldMask != newMask) {
SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
}
}

Expand All @@ -278,9 +278,9 @@ - (NSArray *) validAttributesForMarkedText
* find out which it is.
*/
if (new_dep_mask && old_dep_mask != new_dep_mask) {
SDL_SendKeyboardKey(SDL_PRESSED, scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
} else {
SDL_SendKeyboardKey(SDL_RELEASED, scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
}

Expand Down Expand Up @@ -351,7 +351,7 @@ - (NSArray *) validAttributesForMarkedText
/* 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_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
return;
}

Expand All @@ -362,10 +362,10 @@ - (NSArray *) validAttributesForMarkedText
* so I hope this doesn't cause other problems.
*/
if ( left_device_dependent_mask & oldMods ) {
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
}
if ( right_device_dependent_mask & oldMods ) {
SDL_SendKeyboardKey(SDL_RELEASED, right_scancode, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
}
}

Expand All @@ -382,16 +382,16 @@ - (NSArray *) validAttributesForMarkedText
newMask = newMods & NSAlphaShiftKeyMask;

if (oldMask != newMask) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
}

oldMask = oldMods & NSNumericPadKeyMask;
newMask = newMods & NSNumericPadKeyMask;

if (oldMask != newMask) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
}
}

Expand Down Expand Up @@ -670,7 +670,6 @@ - (NSArray *) validAttributesForMarkedText
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
unsigned short scancode = [event keyCode];
SDL_scancode code;
SDL_bool repeat;
#if 0
const char *text;
#endif
Expand All @@ -689,13 +688,12 @@ - (NSArray *) validAttributesForMarkedText

switch ([event type]) {
case NSKeyDown:
repeat = [event isARepeat] ? SDL_TRUE : SDL_FALSE;
if (!repeat) {
if (![event isARepeat]) {
/* See if we need to rebuild the keyboard layout */
UpdateKeymap(data);
}

SDL_SendKeyboardKey(SDL_PRESSED, code, repeat);
SDL_SendKeyboardKey(SDL_PRESSED, code);
#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 <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
Expand All @@ -714,7 +712,7 @@ - (NSArray *) validAttributesForMarkedText
}
break;
case NSKeyUp:
SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, code);
break;
case NSFlagsChanged:
/* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
Expand Down
12 changes: 6 additions & 6 deletions src/video/uikit/SDL_uikitview.m
Expand Up @@ -245,8 +245,8 @@ - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRan

if ([string length] == 0) {
/* it wants to replace text with nothing, ie a delete */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE);
}
else {
/* go through all the characters in the string we've been sent
Expand All @@ -272,14 +272,14 @@ - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRan

if (mod & KMOD_SHIFT) {
/* If character uses shift, press shift down */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
}
/* send a keydown and keyup even for the character */
SDL_SendKeyboardKey(SDL_PRESSED, code, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, code, SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, code);
SDL_SendKeyboardKey(SDL_RELEASED, code);
if (mod & KMOD_SHIFT) {
/* If character uses shift, press shift back up */
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDL_FALSE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
}
}
}
Expand Down
17 changes: 3 additions & 14 deletions src/video/win32/SDL_win32events.c
Expand Up @@ -205,14 +205,6 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
{
SDL_bool repeat;

if (lParam & REPEATED_KEYMASK) {
repeat = SDL_TRUE;
} else {
repeat = SDL_FALSE;
}

wParam = RemapVKEY(wParam, lParam);
switch (wParam) {
case VK_CONTROL:
Expand Down Expand Up @@ -250,8 +242,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
if (wParam < 256) {
SDL_SendKeyboardKey(SDL_PRESSED,
data->videodata->key_layout[wParam],
repeat);
data->videodata->key_layout[wParam]);
}
}
returnCode = 0;
Expand Down Expand Up @@ -301,13 +292,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
&& SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
SDL_RELEASED) {
SDL_SendKeyboardKey(SDL_PRESSED,
data->videodata->key_layout[wParam],
SDL_FALSE);
data->videodata->key_layout[wParam]);
}
if (wParam < 256) {
SDL_SendKeyboardKey(SDL_RELEASED,
data->videodata->key_layout[wParam],
SDL_FALSE);
data->videodata->key_layout[wParam]);
}
}
returnCode = 0;
Expand Down
28 changes: 25 additions & 3 deletions src/video/x11/SDL_x11events.c
Expand Up @@ -36,6 +36,24 @@

/*#define DEBUG_XEVENTS*/

/* Check to see if this is a repeated key.
(idea shamelessly lifted from GII -- thanks guys! :)
*/
static SDL_bool X11_KeyRepeat(Display *display, XEvent *event)
{
XEvent peekevent;

if (XPending(display)) {
XPeekEvent(display, &peekevent);
if ((peekevent.type == KeyPress) &&
(peekevent.xkey.keycode == event->xkey.keycode) &&
((peekevent.xkey.time-event->xkey.time) < 2)) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}

static void
X11_DispatchEvent(_THIS)
{
Expand Down Expand Up @@ -176,14 +194,14 @@ X11_DispatchEvent(_THIS)
case KeyPress:{
KeyCode keycode = xevent.xkey.keycode;
KeySym keysym = NoSymbol;
SDL_scancode scancode;
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
Status status = 0;

#ifdef DEBUG_XEVENTS
printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
/* FIXME: How do we tell if this was a key repeat? */
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode], SDL_FALSE);
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
#if 1
if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
int min_keycode, max_keycode;
Expand Down Expand Up @@ -218,7 +236,11 @@ X11_DispatchEvent(_THIS)
#ifdef DEBUG_XEVENTS
printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
#endif
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode], SDL_FALSE);
if (X11_KeyRepeat(display, &xevent)) {
/* We're about to get a repeated key down, ignore the key up */
break;
}
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
}
break;

Expand Down

0 comments on commit a44d403

Please sign in to comment.