src/events/SDL_keyboard.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 29 Jan 2006 07:57:13 +0000
changeset 1282 217f5d5a49e5
parent 1123 28ac87a38c17
child 1283 f214b6fae45a
permissions -rw-r--r--
Date: Sat, 15 Jan 2005 02:01:51 +0000 (UTC)
From: jimrandomh
Subject: [SDL] Re: Modifier keys pressed during initialization stick

I wrote a simple test program which initializes SDL, prints the SDL
version number, then prints any keydown and keyup events with their
modifiers. (Source code below). Compilation was done using Visual
Studio 6, release mode.

My test sequence was:
Start a command prompt. Type the name of the test program.
shift down
enter down (program starts)
Wait for window to appear
enter up
shift up
spacebar down
spacebar up

Under Windows 98, the output was correct:
SDL 1.2.8
left shift down
shift-return down
shift-return up
left shift up
space down
space up

Under Windows 2000 and under Windows XP, the output was:
SDL 1.2.8
shift-space down
shift-space up

Since shift was not held at the time space was pressed, this is
incorrect. Similar results were observed with launching in different
ways (including double-clicking in Windows Explorer), so it does not
depend on the launching terminal.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* General keyboard handling code for SDL */
    29 
    30 #include <stdio.h>
    31 #include <ctype.h>
    32 #include <stdlib.h>
    33 #include <string.h>
    34 
    35 #include "SDL_error.h"
    36 #include "SDL_events.h"
    37 #include "SDL_timer.h"
    38 #include "SDL_events_c.h"
    39 #include "SDL_sysevents.h"
    40 
    41 
    42 /* Global keystate information */
    43 static Uint8  SDL_KeyState[SDLK_LAST];
    44 static SDLMod SDL_ModState;
    45 int SDL_TranslateUNICODE = 0;
    46 
    47 static char *keynames[SDLK_LAST];	/* Array of keycode names */
    48 
    49 /*
    50  * jk 991215 - added
    51  */
    52 struct {
    53 	int firsttime;    /* if we check against the delay or repeat value */
    54 	int delay;        /* the delay before we start repeating */
    55 	int interval;     /* the delay between key repeat events */
    56 	Uint32 timestamp; /* the time the first keydown event occurred */
    57 
    58 	SDL_Event evt;    /* the event we are supposed to repeat */
    59 } SDL_KeyRepeat;
    60 
    61 /* Public functions */
    62 int SDL_KeyboardInit(void)
    63 {
    64 	SDL_VideoDevice *video = current_video;
    65 	SDL_VideoDevice *this  = current_video;
    66 	Uint16 i;
    67 
    68 	/* Set default mode of UNICODE translation */
    69 	SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION);
    70 
    71 	/* Initialize the tables */
    72 	SDL_ModState = KMOD_NONE;
    73 	for ( i=0; i<SDL_TABLESIZE(keynames); ++i )
    74 		keynames[i] = NULL;
    75 	for ( i=0; i<SDL_TABLESIZE(SDL_KeyState); ++i )
    76 		SDL_KeyState[i] = SDL_RELEASED;
    77 	video->InitOSKeymap(this);
    78 
    79 	SDL_EnableKeyRepeat(0, 0);
    80 
    81 	/* Fill in the blanks in keynames */
    82 	keynames[SDLK_BACKSPACE] = "backspace";
    83 	keynames[SDLK_TAB] = "tab";
    84 	keynames[SDLK_CLEAR] = "clear";
    85 	keynames[SDLK_RETURN] = "return";
    86 	keynames[SDLK_PAUSE] = "pause";
    87 	keynames[SDLK_ESCAPE] = "escape";
    88 	keynames[SDLK_SPACE] = "space";
    89 	keynames[SDLK_EXCLAIM]  = "!";
    90 	keynames[SDLK_QUOTEDBL]  = "\"";
    91 	keynames[SDLK_HASH]  = "#";
    92 	keynames[SDLK_DOLLAR]  = "$";
    93 	keynames[SDLK_AMPERSAND]  = "&";
    94 	keynames[SDLK_QUOTE] = "'";
    95 	keynames[SDLK_LEFTPAREN] = "(";
    96 	keynames[SDLK_RIGHTPAREN] = ")";
    97 	keynames[SDLK_ASTERISK] = "*";
    98 	keynames[SDLK_PLUS] = "+";
    99 	keynames[SDLK_COMMA] = ",";
   100 	keynames[SDLK_MINUS] = "-";
   101 	keynames[SDLK_PERIOD] = ".";
   102 	keynames[SDLK_SLASH] = "/";
   103 	keynames[SDLK_0] = "0";
   104 	keynames[SDLK_1] = "1";
   105 	keynames[SDLK_2] = "2";
   106 	keynames[SDLK_3] = "3";
   107 	keynames[SDLK_4] = "4";
   108 	keynames[SDLK_5] = "5";
   109 	keynames[SDLK_6] = "6";
   110 	keynames[SDLK_7] = "7";
   111 	keynames[SDLK_8] = "8";
   112 	keynames[SDLK_9] = "9";
   113 	keynames[SDLK_COLON] = ":";
   114 	keynames[SDLK_SEMICOLON] = ";";
   115 	keynames[SDLK_LESS] = "<";
   116 	keynames[SDLK_EQUALS] = "=";
   117 	keynames[SDLK_GREATER] = ">";
   118 	keynames[SDLK_QUESTION] = "?";
   119 	keynames[SDLK_AT] = "@";
   120 	keynames[SDLK_LEFTBRACKET] = "[";
   121 	keynames[SDLK_BACKSLASH] = "\\";
   122 	keynames[SDLK_RIGHTBRACKET] = "]";
   123 	keynames[SDLK_CARET] = "^";
   124 	keynames[SDLK_UNDERSCORE] = "_";
   125 	keynames[SDLK_BACKQUOTE] = "`";
   126 	keynames[SDLK_a] = "a";
   127 	keynames[SDLK_b] = "b";
   128 	keynames[SDLK_c] = "c";
   129 	keynames[SDLK_d] = "d";
   130 	keynames[SDLK_e] = "e";
   131 	keynames[SDLK_f] = "f";
   132 	keynames[SDLK_g] = "g";
   133 	keynames[SDLK_h] = "h";
   134 	keynames[SDLK_i] = "i";
   135 	keynames[SDLK_j] = "j";
   136 	keynames[SDLK_k] = "k";
   137 	keynames[SDLK_l] = "l";
   138 	keynames[SDLK_m] = "m";
   139 	keynames[SDLK_n] = "n";
   140 	keynames[SDLK_o] = "o";
   141 	keynames[SDLK_p] = "p";
   142 	keynames[SDLK_q] = "q";
   143 	keynames[SDLK_r] = "r";
   144 	keynames[SDLK_s] = "s";
   145 	keynames[SDLK_t] = "t";
   146 	keynames[SDLK_u] = "u";
   147 	keynames[SDLK_v] = "v";
   148 	keynames[SDLK_w] = "w";
   149 	keynames[SDLK_x] = "x";
   150 	keynames[SDLK_y] = "y";
   151 	keynames[SDLK_z] = "z";
   152 	keynames[SDLK_DELETE] = "delete";
   153 
   154 	keynames[SDLK_WORLD_0] = "world 0";
   155 	keynames[SDLK_WORLD_1] = "world 1";
   156 	keynames[SDLK_WORLD_2] = "world 2";
   157 	keynames[SDLK_WORLD_3] = "world 3";
   158 	keynames[SDLK_WORLD_4] = "world 4";
   159 	keynames[SDLK_WORLD_5] = "world 5";
   160 	keynames[SDLK_WORLD_6] = "world 6";
   161 	keynames[SDLK_WORLD_7] = "world 7";
   162 	keynames[SDLK_WORLD_8] = "world 8";
   163 	keynames[SDLK_WORLD_9] = "world 9";
   164 	keynames[SDLK_WORLD_10] = "world 10";
   165 	keynames[SDLK_WORLD_11] = "world 11";
   166 	keynames[SDLK_WORLD_12] = "world 12";
   167 	keynames[SDLK_WORLD_13] = "world 13";
   168 	keynames[SDLK_WORLD_14] = "world 14";
   169 	keynames[SDLK_WORLD_15] = "world 15";
   170 	keynames[SDLK_WORLD_16] = "world 16";
   171 	keynames[SDLK_WORLD_17] = "world 17";
   172 	keynames[SDLK_WORLD_18] = "world 18";
   173 	keynames[SDLK_WORLD_19] = "world 19";
   174 	keynames[SDLK_WORLD_20] = "world 20";
   175 	keynames[SDLK_WORLD_21] = "world 21";
   176 	keynames[SDLK_WORLD_22] = "world 22";
   177 	keynames[SDLK_WORLD_23] = "world 23";
   178 	keynames[SDLK_WORLD_24] = "world 24";
   179 	keynames[SDLK_WORLD_25] = "world 25";
   180 	keynames[SDLK_WORLD_26] = "world 26";
   181 	keynames[SDLK_WORLD_27] = "world 27";
   182 	keynames[SDLK_WORLD_28] = "world 28";
   183 	keynames[SDLK_WORLD_29] = "world 29";
   184 	keynames[SDLK_WORLD_30] = "world 30";
   185 	keynames[SDLK_WORLD_31] = "world 31";
   186 	keynames[SDLK_WORLD_32] = "world 32";
   187 	keynames[SDLK_WORLD_33] = "world 33";
   188 	keynames[SDLK_WORLD_34] = "world 34";
   189 	keynames[SDLK_WORLD_35] = "world 35";
   190 	keynames[SDLK_WORLD_36] = "world 36";
   191 	keynames[SDLK_WORLD_37] = "world 37";
   192 	keynames[SDLK_WORLD_38] = "world 38";
   193 	keynames[SDLK_WORLD_39] = "world 39";
   194 	keynames[SDLK_WORLD_40] = "world 40";
   195 	keynames[SDLK_WORLD_41] = "world 41";
   196 	keynames[SDLK_WORLD_42] = "world 42";
   197 	keynames[SDLK_WORLD_43] = "world 43";
   198 	keynames[SDLK_WORLD_44] = "world 44";
   199 	keynames[SDLK_WORLD_45] = "world 45";
   200 	keynames[SDLK_WORLD_46] = "world 46";
   201 	keynames[SDLK_WORLD_47] = "world 47";
   202 	keynames[SDLK_WORLD_48] = "world 48";
   203 	keynames[SDLK_WORLD_49] = "world 49";
   204 	keynames[SDLK_WORLD_50] = "world 50";
   205 	keynames[SDLK_WORLD_51] = "world 51";
   206 	keynames[SDLK_WORLD_52] = "world 52";
   207 	keynames[SDLK_WORLD_53] = "world 53";
   208 	keynames[SDLK_WORLD_54] = "world 54";
   209 	keynames[SDLK_WORLD_55] = "world 55";
   210 	keynames[SDLK_WORLD_56] = "world 56";
   211 	keynames[SDLK_WORLD_57] = "world 57";
   212 	keynames[SDLK_WORLD_58] = "world 58";
   213 	keynames[SDLK_WORLD_59] = "world 59";
   214 	keynames[SDLK_WORLD_60] = "world 60";
   215 	keynames[SDLK_WORLD_61] = "world 61";
   216 	keynames[SDLK_WORLD_62] = "world 62";
   217 	keynames[SDLK_WORLD_63] = "world 63";
   218 	keynames[SDLK_WORLD_64] = "world 64";
   219 	keynames[SDLK_WORLD_65] = "world 65";
   220 	keynames[SDLK_WORLD_66] = "world 66";
   221 	keynames[SDLK_WORLD_67] = "world 67";
   222 	keynames[SDLK_WORLD_68] = "world 68";
   223 	keynames[SDLK_WORLD_69] = "world 69";
   224 	keynames[SDLK_WORLD_70] = "world 70";
   225 	keynames[SDLK_WORLD_71] = "world 71";
   226 	keynames[SDLK_WORLD_72] = "world 72";
   227 	keynames[SDLK_WORLD_73] = "world 73";
   228 	keynames[SDLK_WORLD_74] = "world 74";
   229 	keynames[SDLK_WORLD_75] = "world 75";
   230 	keynames[SDLK_WORLD_76] = "world 76";
   231 	keynames[SDLK_WORLD_77] = "world 77";
   232 	keynames[SDLK_WORLD_78] = "world 78";
   233 	keynames[SDLK_WORLD_79] = "world 79";
   234 	keynames[SDLK_WORLD_80] = "world 80";
   235 	keynames[SDLK_WORLD_81] = "world 81";
   236 	keynames[SDLK_WORLD_82] = "world 82";
   237 	keynames[SDLK_WORLD_83] = "world 83";
   238 	keynames[SDLK_WORLD_84] = "world 84";
   239 	keynames[SDLK_WORLD_85] = "world 85";
   240 	keynames[SDLK_WORLD_86] = "world 86";
   241 	keynames[SDLK_WORLD_87] = "world 87";
   242 	keynames[SDLK_WORLD_88] = "world 88";
   243 	keynames[SDLK_WORLD_89] = "world 89";
   244 	keynames[SDLK_WORLD_90] = "world 90";
   245 	keynames[SDLK_WORLD_91] = "world 91";
   246 	keynames[SDLK_WORLD_92] = "world 92";
   247 	keynames[SDLK_WORLD_93] = "world 93";
   248 	keynames[SDLK_WORLD_94] = "world 94";
   249 	keynames[SDLK_WORLD_95] = "world 95";
   250 
   251 	keynames[SDLK_KP0] = "[0]";
   252 	keynames[SDLK_KP1] = "[1]";
   253 	keynames[SDLK_KP2] = "[2]";
   254 	keynames[SDLK_KP3] = "[3]";
   255 	keynames[SDLK_KP4] = "[4]";
   256 	keynames[SDLK_KP5] = "[5]";
   257 	keynames[SDLK_KP6] = "[6]";
   258 	keynames[SDLK_KP7] = "[7]";
   259 	keynames[SDLK_KP8] = "[8]";
   260 	keynames[SDLK_KP9] = "[9]";
   261 	keynames[SDLK_KP_PERIOD] = "[.]";
   262 	keynames[SDLK_KP_DIVIDE] = "[/]";
   263 	keynames[SDLK_KP_MULTIPLY] = "[*]";
   264 	keynames[SDLK_KP_MINUS] = "[-]";
   265 	keynames[SDLK_KP_PLUS] = "[+]";
   266 	keynames[SDLK_KP_ENTER] = "enter";
   267 	keynames[SDLK_KP_EQUALS] = "equals";
   268 
   269 	keynames[SDLK_UP] = "up";
   270 	keynames[SDLK_DOWN] = "down";
   271 	keynames[SDLK_RIGHT] = "right";
   272 	keynames[SDLK_LEFT] = "left";
   273 	keynames[SDLK_DOWN] = "down";
   274 	keynames[SDLK_INSERT] = "insert";
   275 	keynames[SDLK_HOME] = "home";
   276 	keynames[SDLK_END] = "end";
   277 	keynames[SDLK_PAGEUP] = "page up";
   278 	keynames[SDLK_PAGEDOWN] = "page down";
   279 
   280 	keynames[SDLK_F1] = "f1";
   281 	keynames[SDLK_F2] = "f2";
   282 	keynames[SDLK_F3] = "f3";
   283 	keynames[SDLK_F4] = "f4";
   284 	keynames[SDLK_F5] = "f5";
   285 	keynames[SDLK_F6] = "f6";
   286 	keynames[SDLK_F7] = "f7";
   287 	keynames[SDLK_F8] = "f8";
   288 	keynames[SDLK_F9] = "f9";
   289 	keynames[SDLK_F10] = "f10";
   290 	keynames[SDLK_F11] = "f11";
   291 	keynames[SDLK_F12] = "f12";
   292 	keynames[SDLK_F13] = "f13";
   293 	keynames[SDLK_F14] = "f14";
   294 	keynames[SDLK_F15] = "f15";
   295 
   296 	keynames[SDLK_NUMLOCK] = "numlock";
   297 	keynames[SDLK_CAPSLOCK] = "caps lock";
   298 	keynames[SDLK_SCROLLOCK] = "scroll lock";
   299 	keynames[SDLK_RSHIFT] = "right shift";
   300 	keynames[SDLK_LSHIFT] = "left shift";
   301 	keynames[SDLK_RCTRL] = "right ctrl";
   302 	keynames[SDLK_LCTRL] = "left ctrl";
   303 	keynames[SDLK_RALT] = "right alt";
   304 	keynames[SDLK_LALT] = "left alt";
   305 	keynames[SDLK_RMETA] = "right meta";
   306 	keynames[SDLK_LMETA] = "left meta";
   307 	keynames[SDLK_LSUPER] = "left super";	/* "Windows" keys */
   308 	keynames[SDLK_RSUPER] = "right super";	
   309 	keynames[SDLK_MODE] = "alt gr";
   310 	keynames[SDLK_COMPOSE] = "compose";
   311 
   312 	keynames[SDLK_HELP] = "help";
   313 	keynames[SDLK_PRINT] = "print screen";
   314 	keynames[SDLK_SYSREQ] = "sys req";
   315 	keynames[SDLK_BREAK] = "break";
   316 	keynames[SDLK_MENU] = "menu";
   317 	keynames[SDLK_POWER] = "power";
   318 	keynames[SDLK_EURO] = "euro";
   319 	keynames[SDLK_UNDO] = "undo";
   320 
   321 	/* Done.  Whew. */
   322 	return(0);
   323 }
   324 void SDL_KeyboardQuit(void)
   325 {
   326 }
   327 
   328 /* We lost the keyboard, so post key up messages for all pressed keys */
   329 void SDL_ResetKeyboard(void)
   330 {
   331 	SDL_keysym keysym;
   332 	SDLKey key;
   333 
   334 	memset(&keysym, 0, (sizeof keysym));
   335 	for ( key=SDLK_FIRST; key<SDLK_LAST; ++key ) {
   336 		if ( SDL_KeyState[key] == SDL_PRESSED ) {
   337 			keysym.sym = key;
   338 			SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
   339 		}
   340 	}
   341 	SDL_KeyRepeat.timestamp = 0;
   342 }
   343 
   344 int SDL_EnableUNICODE(int enable)
   345 {
   346 	int old_mode;
   347 
   348 	old_mode = SDL_TranslateUNICODE;
   349 	if ( enable >= 0 ) {
   350 		SDL_TranslateUNICODE = enable;
   351 	}
   352 	return(old_mode);
   353 }
   354 
   355 Uint8 * SDL_GetKeyState (int *numkeys)
   356 {
   357 	if ( numkeys != (int *)0 )
   358 		*numkeys = SDLK_LAST;
   359 	return(SDL_KeyState);
   360 }
   361 SDLMod SDL_GetModState (void)
   362 {
   363 	return(SDL_ModState);
   364 }
   365 void SDL_SetModState (SDLMod modstate)
   366 {
   367 	SDL_ModState = modstate;
   368 }
   369 
   370 char *SDL_GetKeyName(SDLKey key)
   371 {
   372 	char *keyname;
   373 
   374 	keyname = NULL;
   375 	if ( key < SDLK_LAST ) {
   376 		keyname = keynames[key];
   377 	}
   378 	if ( keyname == NULL ) {
   379 		keyname = "unknown key";
   380 	}
   381 	return(keyname);
   382 }
   383 
   384 /* These are global for SDL_eventloop.c */
   385 int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *keysym)
   386 {
   387 	SDL_Event event;
   388 	int posted, repeatable;
   389 	Uint16 modstate;
   390 
   391 	memset(&event, 0, sizeof(event));
   392 
   393 #if 0
   394 printf("The '%s' key has been %s\n", SDL_GetKeyName(keysym->sym), 
   395 				state == SDL_PRESSED ? "pressed" : "released");
   396 #endif
   397 	/* Set up the keysym */
   398 	modstate = (Uint16)SDL_ModState;
   399 
   400 	repeatable = 0;
   401 
   402 	if ( state == SDL_PRESSED ) {
   403 		keysym->mod = (SDLMod)modstate;
   404 		switch (keysym->sym) {
   405 			case SDLK_NUMLOCK:
   406 				modstate ^= KMOD_NUM;
   407 				if ( ! (modstate&KMOD_NUM) )
   408 					state = SDL_RELEASED;
   409 				keysym->mod = (SDLMod)modstate;
   410 				break;
   411 			case SDLK_CAPSLOCK:
   412 				modstate ^= KMOD_CAPS;
   413 				if ( ! (modstate&KMOD_CAPS) )
   414 					state = SDL_RELEASED;
   415 				keysym->mod = (SDLMod)modstate;
   416 				break;
   417 			case SDLK_LCTRL:
   418 				modstate |= KMOD_LCTRL;
   419 				break;
   420 			case SDLK_RCTRL:
   421 				modstate |= KMOD_RCTRL;
   422 				break;
   423 			case SDLK_LSHIFT:
   424 				modstate |= KMOD_LSHIFT;
   425 				break;
   426 			case SDLK_RSHIFT:
   427 				modstate |= KMOD_RSHIFT;
   428 				break;
   429 			case SDLK_LALT:
   430 				modstate |= KMOD_LALT;
   431 				break;
   432 			case SDLK_RALT:
   433 				modstate |= KMOD_RALT;
   434 				break;
   435 			case SDLK_LMETA:
   436 				modstate |= KMOD_LMETA;
   437 				break;
   438 			case SDLK_RMETA:
   439 				modstate |= KMOD_RMETA;
   440 				break;
   441 			case SDLK_MODE:
   442 				modstate |= KMOD_MODE;
   443 				break;
   444 			default:
   445 				repeatable = 1;
   446 				break;
   447 		}
   448 	} else {
   449 		switch (keysym->sym) {
   450 			case SDLK_NUMLOCK:
   451 			case SDLK_CAPSLOCK:
   452 				/* Only send keydown events */
   453 				return(0);
   454 			case SDLK_LCTRL:
   455 				modstate &= ~KMOD_LCTRL;
   456 				break;
   457 			case SDLK_RCTRL:
   458 				modstate &= ~KMOD_RCTRL;
   459 				break;
   460 			case SDLK_LSHIFT:
   461 				modstate &= ~KMOD_LSHIFT;
   462 				break;
   463 			case SDLK_RSHIFT:
   464 				modstate &= ~KMOD_RSHIFT;
   465 				break;
   466 			case SDLK_LALT:
   467 				modstate &= ~KMOD_LALT;
   468 				break;
   469 			case SDLK_RALT:
   470 				modstate &= ~KMOD_RALT;
   471 				break;
   472 			case SDLK_LMETA:
   473 				modstate &= ~KMOD_LMETA;
   474 				break;
   475 			case SDLK_RMETA:
   476 				modstate &= ~KMOD_RMETA;
   477 				break;
   478 			case SDLK_MODE:
   479 				modstate &= ~KMOD_MODE;
   480 				break;
   481 			default:
   482 				break;
   483 		}
   484 		keysym->mod = (SDLMod)modstate;
   485 	}
   486 
   487 	/* Figure out what type of event this is */
   488 	switch (state) {
   489 		case SDL_PRESSED:
   490 			event.type = SDL_KEYDOWN;
   491 			break;
   492 		case SDL_RELEASED:
   493 			event.type = SDL_KEYUP;
   494 			/*
   495 			 * jk 991215 - Added
   496 			 */
   497 			if ( SDL_KeyRepeat.timestamp &&
   498 			     SDL_KeyRepeat.evt.key.keysym.sym == keysym->sym ) {
   499 				SDL_KeyRepeat.timestamp = 0;
   500 			}
   501 			break;
   502 		default:
   503 			/* Invalid state -- bail */
   504 			return(0);
   505 	}
   506 
   507 	/* Drop events that don't change state */
   508 	if ( SDL_KeyState[keysym->sym] == state ) {
   509 #if 0
   510 printf("Event didn't change state - dropped!\n");
   511 #endif
   512 		return(0);
   513 	}
   514 
   515 	/* Update internal keyboard state */
   516 	SDL_ModState = (SDLMod)modstate;
   517 	SDL_KeyState[keysym->sym] = state;
   518 
   519 	/* Post the event, if desired */
   520 	posted = 0;
   521 	if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
   522 		event.key.state = state;
   523 		event.key.keysym = *keysym;
   524 		/*
   525 		 * jk 991215 - Added
   526 		 */
   527 		if (repeatable && (SDL_KeyRepeat.delay != 0)) {
   528 			SDL_KeyRepeat.evt = event;
   529 			SDL_KeyRepeat.firsttime = 1;
   530 			SDL_KeyRepeat.timestamp=SDL_GetTicks();
   531 		}
   532 		if ( (SDL_EventOK == NULL) || SDL_EventOK(&event) ) {
   533 			posted = 1;
   534 			SDL_PushEvent(&event);
   535 		}
   536 	}
   537 	return(posted);
   538 }
   539 
   540 /*
   541  * jk 991215 - Added
   542  */
   543 void SDL_CheckKeyRepeat(void)
   544 {
   545 	if ( SDL_KeyRepeat.timestamp ) {
   546 		Uint32 now, interval;
   547 
   548 		now = SDL_GetTicks();
   549 		interval = (now - SDL_KeyRepeat.timestamp);
   550 		if ( SDL_KeyRepeat.firsttime ) {
   551 			if ( interval > (Uint32)SDL_KeyRepeat.delay ) {
   552 				SDL_KeyRepeat.timestamp = now;
   553 				SDL_KeyRepeat.firsttime = 0;
   554 			}
   555 		} else {
   556 			if ( interval > (Uint32)SDL_KeyRepeat.interval ) {
   557 				SDL_KeyRepeat.timestamp = now;
   558 				if ( (SDL_EventOK == NULL) || SDL_EventOK(&SDL_KeyRepeat.evt) ) {
   559 					SDL_PushEvent(&SDL_KeyRepeat.evt);
   560 				}
   561 			}
   562 		}
   563 	}
   564 }
   565 
   566 int SDL_EnableKeyRepeat(int delay, int interval)
   567 {
   568 	if ( (delay < 0) || (interval < 0) ) {
   569 		SDL_SetError("keyboard repeat value less than zero");
   570 		return(-1);
   571 	}
   572 	SDL_KeyRepeat.firsttime = 0;
   573 	SDL_KeyRepeat.delay = delay;
   574 	SDL_KeyRepeat.interval = interval;
   575 	SDL_KeyRepeat.timestamp = 0;
   576 	return(0);
   577 }
   578