src/events/SDL_keyboard.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 03 Jan 2005 00:24:44 +0000
changeset 1021 ddd058103e28
parent 769 b8d311d90021
child 1123 28ac87a38c17
permissions -rw-r--r--
Date: Sun, 2 Jan 2005 18:36:09 +0100
From: Jon Daniel
Subject: [SDL] KeyRepeat fix

If you switch keys very fast and hold the last one it
doesn't get repeated because the key release of the first key
occured after the key press of the second key.
Unfortunatly the key release of the first key sets
SDL_KeyRepeat.timestamp = 0; causing the the second key not to repeat.

This should be always reproducable. I've only checked this on x86-64
X11.

To fix this I just added another condition to make sure the sym of the
released key matches SDL_KeyRepeat.key.keysym.sym.
     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 
   325 /* We lost the keyboard, so post key up messages for all pressed keys */
   326 void SDL_ResetKeyboard(void)
   327 {
   328 	SDL_keysym keysym;
   329 	SDLKey key;
   330 
   331 	memset(&keysym, 0, (sizeof keysym));
   332 	for ( key=SDLK_FIRST; key<SDLK_LAST; ++key ) {
   333 		if ( SDL_KeyState[key] == SDL_PRESSED ) {
   334 			keysym.sym = key;
   335 			SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
   336 		}
   337 	}
   338 	SDL_KeyRepeat.timestamp = 0;
   339 }
   340 
   341 int SDL_EnableUNICODE(int enable)
   342 {
   343 	int old_mode;
   344 
   345 	old_mode = SDL_TranslateUNICODE;
   346 	if ( enable >= 0 ) {
   347 		SDL_TranslateUNICODE = enable;
   348 	}
   349 	return(old_mode);
   350 }
   351 
   352 Uint8 * SDL_GetKeyState (int *numkeys)
   353 {
   354 	if ( numkeys != (int *)0 )
   355 		*numkeys = SDLK_LAST;
   356 	return(SDL_KeyState);
   357 }
   358 SDLMod SDL_GetModState (void)
   359 {
   360 	return(SDL_ModState);
   361 }
   362 void SDL_SetModState (SDLMod modstate)
   363 {
   364 	SDL_ModState = modstate;
   365 }
   366 
   367 char *SDL_GetKeyName(SDLKey key)
   368 {
   369 	char *keyname;
   370 
   371 	keyname = NULL;
   372 	if ( key < SDLK_LAST ) {
   373 		keyname = keynames[key];
   374 	}
   375 	if ( keyname == NULL ) {
   376 		keyname = "unknown key";
   377 	}
   378 	return(keyname);
   379 }
   380 
   381 /* These are global for SDL_eventloop.c */
   382 int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *keysym)
   383 {
   384 	SDL_Event event;
   385 	int posted, repeatable;
   386 	Uint16 modstate;
   387 
   388 	memset(&event, 0, sizeof(event));
   389 
   390 #if 0
   391 printf("The '%s' key has been %s\n", SDL_GetKeyName(keysym->sym), 
   392 				state == SDL_PRESSED ? "pressed" : "released");
   393 #endif
   394 	/* Set up the keysym */
   395 	modstate = (Uint16)SDL_ModState;
   396 
   397 	repeatable = 0;
   398 
   399 	if ( state == SDL_PRESSED ) {
   400 		keysym->mod = (SDLMod)modstate;
   401 		switch (keysym->sym) {
   402 			case SDLK_NUMLOCK:
   403 				modstate ^= KMOD_NUM;
   404 				if ( ! (modstate&KMOD_NUM) )
   405 					state = SDL_RELEASED;
   406 				keysym->mod = (SDLMod)modstate;
   407 				break;
   408 			case SDLK_CAPSLOCK:
   409 				modstate ^= KMOD_CAPS;
   410 				if ( ! (modstate&KMOD_CAPS) )
   411 					state = SDL_RELEASED;
   412 				keysym->mod = (SDLMod)modstate;
   413 				break;
   414 			case SDLK_LCTRL:
   415 				modstate |= KMOD_LCTRL;
   416 				break;
   417 			case SDLK_RCTRL:
   418 				modstate |= KMOD_RCTRL;
   419 				break;
   420 			case SDLK_LSHIFT:
   421 				modstate |= KMOD_LSHIFT;
   422 				break;
   423 			case SDLK_RSHIFT:
   424 				modstate |= KMOD_RSHIFT;
   425 				break;
   426 			case SDLK_LALT:
   427 				modstate |= KMOD_LALT;
   428 				break;
   429 			case SDLK_RALT:
   430 				modstate |= KMOD_RALT;
   431 				break;
   432 			case SDLK_LMETA:
   433 				modstate |= KMOD_LMETA;
   434 				break;
   435 			case SDLK_RMETA:
   436 				modstate |= KMOD_RMETA;
   437 				break;
   438 			case SDLK_MODE:
   439 				modstate |= KMOD_MODE;
   440 				break;
   441 			default:
   442 				repeatable = 1;
   443 				break;
   444 		}
   445 	} else {
   446 		switch (keysym->sym) {
   447 			case SDLK_NUMLOCK:
   448 			case SDLK_CAPSLOCK:
   449 				/* Only send keydown events */
   450 				return(0);
   451 			case SDLK_LCTRL:
   452 				modstate &= ~KMOD_LCTRL;
   453 				break;
   454 			case SDLK_RCTRL:
   455 				modstate &= ~KMOD_RCTRL;
   456 				break;
   457 			case SDLK_LSHIFT:
   458 				modstate &= ~KMOD_LSHIFT;
   459 				break;
   460 			case SDLK_RSHIFT:
   461 				modstate &= ~KMOD_RSHIFT;
   462 				break;
   463 			case SDLK_LALT:
   464 				modstate &= ~KMOD_LALT;
   465 				break;
   466 			case SDLK_RALT:
   467 				modstate &= ~KMOD_RALT;
   468 				break;
   469 			case SDLK_LMETA:
   470 				modstate &= ~KMOD_LMETA;
   471 				break;
   472 			case SDLK_RMETA:
   473 				modstate &= ~KMOD_RMETA;
   474 				break;
   475 			case SDLK_MODE:
   476 				modstate &= ~KMOD_MODE;
   477 				break;
   478 			default:
   479 				break;
   480 		}
   481 		keysym->mod = (SDLMod)modstate;
   482 	}
   483 
   484 	/* Figure out what type of event this is */
   485 	switch (state) {
   486 		case SDL_PRESSED:
   487 			event.type = SDL_KEYDOWN;
   488 			break;
   489 		case SDL_RELEASED:
   490 			event.type = SDL_KEYUP;
   491 			/*
   492 			 * jk 991215 - Added
   493 			 */
   494 			if ( SDL_KeyRepeat.timestamp &&
   495 			     SDL_KeyRepeat.evt.key.keysym.sym == keysym->sym ) {
   496 				SDL_KeyRepeat.timestamp = 0;
   497 			}
   498 			break;
   499 		default:
   500 			/* Invalid state -- bail */
   501 			return(0);
   502 	}
   503 
   504 	/* Drop events that don't change state */
   505 	if ( SDL_KeyState[keysym->sym] == state ) {
   506 		return(0);
   507 	}
   508 
   509 	/* Update internal keyboard state */
   510 	SDL_ModState = (SDLMod)modstate;
   511 	SDL_KeyState[keysym->sym] = state;
   512 
   513 	/* Post the event, if desired */
   514 	posted = 0;
   515 	if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
   516 		event.key.state = state;
   517 		event.key.keysym = *keysym;
   518 		/*
   519 		 * jk 991215 - Added
   520 		 */
   521 		if (repeatable && (SDL_KeyRepeat.delay != 0)) {
   522 			SDL_KeyRepeat.evt = event;
   523 			SDL_KeyRepeat.firsttime = 1;
   524 			SDL_KeyRepeat.timestamp=SDL_GetTicks();
   525 		}
   526 		if ( (SDL_EventOK == NULL) || SDL_EventOK(&event) ) {
   527 			posted = 1;
   528 			SDL_PushEvent(&event);
   529 		}
   530 	}
   531 	return(posted);
   532 }
   533 
   534 /*
   535  * jk 991215 - Added
   536  */
   537 void SDL_CheckKeyRepeat(void)
   538 {
   539 	if ( SDL_KeyRepeat.timestamp ) {
   540 		Uint32 now, interval;
   541 
   542 		now = SDL_GetTicks();
   543 		interval = (now - SDL_KeyRepeat.timestamp);
   544 		if ( SDL_KeyRepeat.firsttime ) {
   545 			if ( interval > (Uint32)SDL_KeyRepeat.delay ) {
   546 				SDL_KeyRepeat.timestamp = now;
   547 				SDL_KeyRepeat.firsttime = 0;
   548 			}
   549 		} else {
   550 			if ( interval > (Uint32)SDL_KeyRepeat.interval ) {
   551 				SDL_KeyRepeat.timestamp = now;
   552 				if ( (SDL_EventOK == NULL) || SDL_EventOK(&SDL_KeyRepeat.evt) ) {
   553 					SDL_PushEvent(&SDL_KeyRepeat.evt);
   554 				}
   555 			}
   556 		}
   557 	}
   558 }
   559 
   560 int SDL_EnableKeyRepeat(int delay, int interval)
   561 {
   562 	if ( (delay < 0) || (interval < 0) ) {
   563 		SDL_SetError("keyboard repeat value less than zero");
   564 		return(-1);
   565 	}
   566 	SDL_KeyRepeat.firsttime = 0;
   567 	SDL_KeyRepeat.delay = delay;
   568 	SDL_KeyRepeat.interval = interval;
   569 	SDL_KeyRepeat.timestamp = 0;
   570 	return(0);
   571 }
   572