Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Now gets correct keyboard state when starting up on X11
  • Loading branch information
Sam Lantinga committed Jul 14, 2001
1 parent 340c83b commit ad8bed1
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs.html
Expand Up @@ -16,6 +16,7 @@ <H2>
Major changes since SDL 1.0.0:
</H2>
<UL>
<LI> 1.2.2: Now gets correct keyboard state when starting up on X11
<LI> 1.2.2: Improved the DGA 2.0 and framebuffer console drivers
<LI> 1.2.2: Improved the OpenBSD port (native audio default, etc.)
<LI> 1.2.2: Improved OSS audio driver support, thanks to 4Front Tech.
Expand Down
95 changes: 82 additions & 13 deletions src/video/x11/SDL_x11events.c
Expand Up @@ -843,18 +843,42 @@ void X11_SetKeyboardState(Display *display, const char *key_vec)
KeyCode xcode[SDLK_LAST];
Uint8 new_kstate[SDLK_LAST];
Uint8 *kstate = SDL_GetKeyState(NULL);
SDLMod modstate;
Window junk_window;
int x, y;
unsigned int mask;

/* The first time the window is mapped, we initialize key state */
if ( ! key_vec ) {
key_vec = keys_return;
XQueryKeymap(display, keys_return);
gen_event = 0;
} else {
#if 1 /* We no longer generate key down events, just update state */
gen_event = 0;
#else
gen_event = 1;
#endif
}

/* Zero the new state and generate it */
memset(new_kstate, 0, sizeof(new_kstate));
/* Get the keyboard modifier state */
modstate = 0;
get_modifier_masks(display);
if ( XQueryPointer(display, DefaultRootWindow(display),
&junk_window, &junk_window, &x, &y, &x, &y, &mask) ) {
if ( mask & LockMask ) {
modstate |= KMOD_CAPS;
}
if ( mask & mode_switch_mask ) {
modstate |= KMOD_MODE;
}
if ( mask & num_mask ) {
modstate |= KMOD_NUM;
}
}

/* Zero the new keyboard state and generate it */
memset(new_kstate, SDL_RELEASED, sizeof(new_kstate));
/*
* An obvious optimisation is to check entire longwords at a time in
* both loops, but we can't be sure the arrays are aligned so it's not
Expand All @@ -869,34 +893,79 @@ void X11_SetKeyboardState(Display *display, const char *key_vec)
SDL_keysym sk;
KeyCode kc = i << 3 | j;
X11_TranslateKey(display, NULL, kc, &sk);
new_kstate[sk.sym] = 1;
new_kstate[sk.sym] = SDL_PRESSED;
xcode[sk.sym] = kc;
}
}
}
for(i = SDLK_FIRST+1; i < SDLK_LAST; i++) {
int st;
SDL_keysym sk;

if(kstate[i] == new_kstate[i])
int state = new_kstate[i];

if ( state == SDL_PRESSED ) {
switch (i) {
case SDLK_LSHIFT:
modstate |= KMOD_LSHIFT;
break;
case SDLK_RSHIFT:
modstate |= KMOD_RSHIFT;
break;
case SDLK_LCTRL:
modstate |= KMOD_LCTRL;
break;
case SDLK_RCTRL:
modstate |= KMOD_RCTRL;
break;
case SDLK_LALT:
modstate |= KMOD_LALT;
break;
case SDLK_RALT:
modstate |= KMOD_RALT;
break;
case SDLK_LMETA:
modstate |= KMOD_LMETA;
break;
case SDLK_RMETA:
modstate |= KMOD_RMETA;
break;
default:
break;
}
}
if ( kstate[i] == state )
continue;

/*
* Send a fake keyboard event correcting the difference between
* SDL's keyboard state and the actual. Note that there is no
* way to find out the scancode for key releases, but since all
* keys are released when focus is lost only keypresses should
* be sent here
*/
st = new_kstate[i] ? SDL_PRESSED : SDL_RELEASED;
memset(&sk, 0, sizeof(sk));
sk.sym = i;
sk.scancode = xcode[i]; /* only valid for key press */
if ( gen_event ) {
SDL_PrivateKeyboard(st, &sk);
SDL_keysym sk;
memset(&sk, 0, sizeof(sk));
sk.sym = i;
sk.scancode = xcode[i]; /* only valid for key press */
SDL_PrivateKeyboard(state, &sk);
} else {
kstate[i] = new_kstate[i];
kstate[i] = state;
}
}

/* Hack - set toggle key state */
if ( modstate & KMOD_CAPS ) {
kstate[SDLK_CAPSLOCK] = SDL_PRESSED;
} else {
kstate[SDLK_CAPSLOCK] = SDL_RELEASED;
}
if ( modstate & KMOD_NUM ) {
kstate[SDLK_NUMLOCK] = SDL_PRESSED;
} else {
kstate[SDLK_NUMLOCK] = SDL_RELEASED;
}

/* Set the final modifier state */
SDL_SetModState(modstate);
}

void X11_InitOSKeymap(_THIS)
Expand Down

0 comments on commit ad8bed1

Please sign in to comment.