Now gets correct keyboard state when starting up on X11
authorSam Lantinga <slouken@lokigames.com>
Sat, 14 Jul 2001 20:37:24 +0000
changeset 11153e3d8ba4321
parent 110 7edee9f0f2cc
child 112 9ef74357a5fb
Now gets correct keyboard state when starting up on X11
docs.html
src/video/x11/SDL_x11events.c
     1.1 --- a/docs.html	Sat Jul 14 19:11:26 2001 +0000
     1.2 +++ b/docs.html	Sat Jul 14 20:37:24 2001 +0000
     1.3 @@ -16,6 +16,7 @@
     1.4  Major changes since SDL 1.0.0:
     1.5  </H2>
     1.6  <UL>
     1.7 +	<LI> 1.2.2: Now gets correct keyboard state when starting up on X11
     1.8  	<LI> 1.2.2: Improved the DGA 2.0 and framebuffer console drivers
     1.9  	<LI> 1.2.2: Improved the OpenBSD port (native audio default, etc.)
    1.10  	<LI> 1.2.2: Improved OSS audio driver support, thanks to 4Front Tech.
     2.1 --- a/src/video/x11/SDL_x11events.c	Sat Jul 14 19:11:26 2001 +0000
     2.2 +++ b/src/video/x11/SDL_x11events.c	Sat Jul 14 20:37:24 2001 +0000
     2.3 @@ -843,6 +843,10 @@
     2.4  	KeyCode xcode[SDLK_LAST];
     2.5  	Uint8 new_kstate[SDLK_LAST];
     2.6  	Uint8 *kstate = SDL_GetKeyState(NULL);
     2.7 +	SDLMod modstate;
     2.8 +	Window junk_window;
     2.9 +	int x, y;
    2.10 +	unsigned int mask;
    2.11  
    2.12  	/* The first time the window is mapped, we initialize key state */
    2.13  	if ( ! key_vec ) {
    2.14 @@ -850,11 +854,31 @@
    2.15  		XQueryKeymap(display, keys_return);
    2.16  		gen_event = 0;
    2.17  	} else {
    2.18 +#if 1 /* We no longer generate key down events, just update state */
    2.19 +		gen_event = 0;
    2.20 +#else
    2.21  		gen_event = 1;
    2.22 +#endif
    2.23  	}
    2.24  
    2.25 -	/* Zero the new state and generate it */
    2.26 -	memset(new_kstate, 0, sizeof(new_kstate));
    2.27 +	/* Get the keyboard modifier state */
    2.28 +	modstate = 0;
    2.29 +	get_modifier_masks(display);
    2.30 +	if ( XQueryPointer(display, DefaultRootWindow(display),
    2.31 +		&junk_window, &junk_window, &x, &y, &x, &y, &mask) ) {
    2.32 +		if ( mask & LockMask ) {
    2.33 +			modstate |= KMOD_CAPS;
    2.34 +		}
    2.35 +		if ( mask & mode_switch_mask ) {
    2.36 +			modstate |= KMOD_MODE;
    2.37 +		}
    2.38 +		if ( mask & num_mask ) {
    2.39 +			modstate |= KMOD_NUM;
    2.40 +		}
    2.41 +	}
    2.42 +
    2.43 +	/* Zero the new keyboard state and generate it */
    2.44 +	memset(new_kstate, SDL_RELEASED, sizeof(new_kstate));
    2.45  	/*
    2.46  	 * An obvious optimisation is to check entire longwords at a time in
    2.47  	 * both loops, but we can't be sure the arrays are aligned so it's not
    2.48 @@ -869,17 +893,47 @@
    2.49  				SDL_keysym sk;
    2.50  				KeyCode kc = i << 3 | j;
    2.51  				X11_TranslateKey(display, NULL, kc, &sk);
    2.52 -				new_kstate[sk.sym] = 1;
    2.53 +				new_kstate[sk.sym] = SDL_PRESSED;
    2.54  				xcode[sk.sym] = kc;
    2.55  			}
    2.56  		}
    2.57  	}
    2.58  	for(i = SDLK_FIRST+1; i < SDLK_LAST; i++) {
    2.59 -		int st;
    2.60 -		SDL_keysym sk;
    2.61 +		int state = new_kstate[i];
    2.62  
    2.63 -		if(kstate[i] == new_kstate[i])
    2.64 +		if ( state == SDL_PRESSED ) {
    2.65 +			switch (i) {
    2.66 +				case SDLK_LSHIFT:
    2.67 +					modstate |= KMOD_LSHIFT;
    2.68 +					break;
    2.69 +				case SDLK_RSHIFT:
    2.70 +					modstate |= KMOD_RSHIFT;
    2.71 +					break;
    2.72 +				case SDLK_LCTRL:
    2.73 +					modstate |= KMOD_LCTRL;
    2.74 +					break;
    2.75 +				case SDLK_RCTRL:
    2.76 +					modstate |= KMOD_RCTRL;
    2.77 +					break;
    2.78 +				case SDLK_LALT:
    2.79 +					modstate |= KMOD_LALT;
    2.80 +					break;
    2.81 +				case SDLK_RALT:
    2.82 +					modstate |= KMOD_RALT;
    2.83 +					break;
    2.84 +				case SDLK_LMETA:
    2.85 +					modstate |= KMOD_LMETA;
    2.86 +					break;
    2.87 +				case SDLK_RMETA:
    2.88 +					modstate |= KMOD_RMETA;
    2.89 +					break;
    2.90 +				default:
    2.91 +					break;
    2.92 +			}
    2.93 +		}
    2.94 +		if ( kstate[i] == state )
    2.95  			continue;
    2.96 +
    2.97  		/*
    2.98  		 * Send a fake keyboard event correcting the difference between
    2.99  		 * SDL's keyboard state and the actual. Note that there is no
   2.100 @@ -887,16 +941,31 @@
   2.101  		 * keys are released when focus is lost only keypresses should
   2.102  		 * be sent here
   2.103  		 */
   2.104 -		st = new_kstate[i] ? SDL_PRESSED : SDL_RELEASED;
   2.105 -		memset(&sk, 0, sizeof(sk));
   2.106 -		sk.sym = i;
   2.107 -		sk.scancode = xcode[i];		/* only valid for key press */
   2.108  		if ( gen_event ) {
   2.109 -			SDL_PrivateKeyboard(st, &sk);
   2.110 +			SDL_keysym sk;
   2.111 +			memset(&sk, 0, sizeof(sk));
   2.112 +			sk.sym = i;
   2.113 +			sk.scancode = xcode[i];	/* only valid for key press */
   2.114 +			SDL_PrivateKeyboard(state, &sk);
   2.115  		} else {
   2.116 -			kstate[i] = new_kstate[i];
   2.117 +			kstate[i] = state;
   2.118  		}
   2.119  	}
   2.120 +
   2.121 +	/* Hack - set toggle key state */
   2.122 +	if ( modstate & KMOD_CAPS ) {
   2.123 +		kstate[SDLK_CAPSLOCK] = SDL_PRESSED;
   2.124 +	} else {
   2.125 +		kstate[SDLK_CAPSLOCK] = SDL_RELEASED;
   2.126 +	}
   2.127 +	if ( modstate & KMOD_NUM ) {
   2.128 +		kstate[SDLK_NUMLOCK] = SDL_PRESSED;
   2.129 +	} else {
   2.130 +		kstate[SDLK_NUMLOCK] = SDL_RELEASED;
   2.131 +	}
   2.132 +
   2.133 +	/* Set the final modifier state */
   2.134 +	SDL_SetModState(modstate);
   2.135  }
   2.136  
   2.137  void X11_InitOSKeymap(_THIS)