src/events/SDL_keyboard.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 14 Jun 2006 06:26:35 +0000
branchSDL-1.3
changeset 1679 153477a6cc31
parent 1674 7688a73b25b1
child 1720 a1ebb17f9c52
permissions -rw-r--r--
More compile fixes
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* General keyboard handling code for SDL */
slouken@0
    25
slouken@1358
    26
#include "SDL_timer.h"
slouken@0
    27
#include "SDL_events.h"
slouken@0
    28
#include "SDL_events_c.h"
slouken@0
    29
#include "SDL_sysevents.h"
slouken@0
    30
slouken@0
    31
slouken@1673
    32
/* Global keyboard information */
slouken@1674
    33
int SDL_TranslateUNICODE = 0;
slouken@1673
    34
static int SDL_num_keyboards;
slouken@1673
    35
static int SDL_current_keyboard;
slouken@1673
    36
static SDL_Keyboard **SDL_keyboards;
slouken@0
    37
slouken@1673
    38
static const char *SDL_keynames[SDLK_LAST];     /* Array of keycode names */
slouken@0
    39
slouken@0
    40
/* Public functions */
slouken@1662
    41
int
slouken@1668
    42
SDL_KeyboardInit(void)
slouken@0
    43
{
slouken@1673
    44
    int i;
slouken@0
    45
slouken@1662
    46
    /* Set default mode of UNICODE translation */
slouken@1668
    47
    SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION);
slouken@0
    48
slouken@1673
    49
    /* Initialize the tables */
slouken@1673
    50
    for (i = 0; i < SDL_arraysize(SDL_keynames); ++i) {
slouken@1673
    51
        switch (i) {
slouken@1673
    52
        case SDLK_BACKSPACE:
slouken@1673
    53
            SDL_keynames[i] = "backspace";
slouken@1673
    54
            break;
slouken@1673
    55
        case SDLK_TAB:
slouken@1673
    56
            SDL_keynames[i] = "tab";
slouken@1673
    57
            break;
slouken@1673
    58
        case SDLK_CLEAR:
slouken@1673
    59
            SDL_keynames[i] = "clear";
slouken@1673
    60
            break;
slouken@1673
    61
        case SDLK_RETURN:
slouken@1673
    62
            SDL_keynames[i] = "return";
slouken@1673
    63
            break;
slouken@1673
    64
        case SDLK_PAUSE:
slouken@1673
    65
            SDL_keynames[i] = "pause";
slouken@1673
    66
            break;
slouken@1673
    67
        case SDLK_ESCAPE:
slouken@1673
    68
            SDL_keynames[i] = "escape";
slouken@1673
    69
            break;
slouken@1673
    70
        case SDLK_SPACE:
slouken@1673
    71
            SDL_keynames[i] = "space";
slouken@1673
    72
            break;
slouken@0
    73
slouken@1673
    74
        case SDLK_KP0:
slouken@1673
    75
            SDL_keynames[i] = "[0]";
slouken@1673
    76
            break;
slouken@1673
    77
        case SDLK_KP1:
slouken@1673
    78
            SDL_keynames[i] = "[1]";
slouken@1673
    79
            break;
slouken@1673
    80
        case SDLK_KP2:
slouken@1673
    81
            SDL_keynames[i] = "[2]";
slouken@1673
    82
            break;
slouken@1673
    83
        case SDLK_KP3:
slouken@1673
    84
            SDL_keynames[i] = "[3]";
slouken@1673
    85
            break;
slouken@1673
    86
        case SDLK_KP4:
slouken@1673
    87
            SDL_keynames[i] = "[4]";
slouken@1673
    88
            break;
slouken@1673
    89
        case SDLK_KP5:
slouken@1673
    90
            SDL_keynames[i] = "[5]";
slouken@1673
    91
            break;
slouken@1673
    92
        case SDLK_KP6:
slouken@1673
    93
            SDL_keynames[i] = "[6]";
slouken@1673
    94
            break;
slouken@1673
    95
        case SDLK_KP7:
slouken@1673
    96
            SDL_keynames[i] = "[7]";
slouken@1673
    97
            break;
slouken@1673
    98
        case SDLK_KP8:
slouken@1673
    99
            SDL_keynames[i] = "[8]";
slouken@1673
   100
            break;
slouken@1673
   101
        case SDLK_KP9:
slouken@1673
   102
            SDL_keynames[i] = "[9]";
slouken@1673
   103
            break;
slouken@1673
   104
        case SDLK_KP_PERIOD:
slouken@1673
   105
            SDL_keynames[i] = "[.]";
slouken@1673
   106
            break;
slouken@1673
   107
        case SDLK_KP_DIVIDE:
slouken@1673
   108
            SDL_keynames[i] = "[/]";
slouken@1673
   109
            break;
slouken@1673
   110
        case SDLK_KP_MULTIPLY:
slouken@1673
   111
            SDL_keynames[i] = "[*]";
slouken@1673
   112
            break;
slouken@1673
   113
        case SDLK_KP_MINUS:
slouken@1673
   114
            SDL_keynames[i] = "[-]";
slouken@1673
   115
            break;
slouken@1673
   116
        case SDLK_KP_PLUS:
slouken@1673
   117
            SDL_keynames[i] = "[+]";
slouken@1673
   118
            break;
slouken@1673
   119
        case SDLK_KP_ENTER:
slouken@1673
   120
            SDL_keynames[i] = "enter";
slouken@1673
   121
            break;
slouken@1673
   122
        case SDLK_KP_EQUALS:
slouken@1673
   123
            SDL_keynames[i] = "equals";
slouken@1673
   124
            break;
slouken@0
   125
slouken@1673
   126
        case SDLK_UP:
slouken@1673
   127
            SDL_keynames[i] = "up";
slouken@1673
   128
            break;
slouken@1673
   129
        case SDLK_DOWN:
slouken@1673
   130
            SDL_keynames[i] = "down";
slouken@1673
   131
            break;
slouken@1673
   132
        case SDLK_RIGHT:
slouken@1673
   133
            SDL_keynames[i] = "right";
slouken@1673
   134
            break;
slouken@1673
   135
        case SDLK_LEFT:
slouken@1673
   136
            SDL_keynames[i] = "left";
slouken@1673
   137
            break;
slouken@1673
   138
        case SDLK_INSERT:
slouken@1673
   139
            SDL_keynames[i] = "insert";
slouken@1673
   140
            break;
slouken@1673
   141
        case SDLK_HOME:
slouken@1673
   142
            SDL_keynames[i] = "home";
slouken@1673
   143
            break;
slouken@1673
   144
        case SDLK_END:
slouken@1673
   145
            SDL_keynames[i] = "end";
slouken@1673
   146
            break;
slouken@1673
   147
        case SDLK_PAGEUP:
slouken@1673
   148
            SDL_keynames[i] = "page up";
slouken@1673
   149
            break;
slouken@1673
   150
        case SDLK_PAGEDOWN:
slouken@1673
   151
            SDL_keynames[i] = "page down";
slouken@1673
   152
            break;
slouken@0
   153
slouken@1673
   154
        case SDLK_F1:
slouken@1673
   155
            SDL_keynames[i] = "f1";
slouken@1673
   156
            break;
slouken@1673
   157
        case SDLK_F2:
slouken@1673
   158
            SDL_keynames[i] = "f2";
slouken@1673
   159
            break;
slouken@1673
   160
        case SDLK_F3:
slouken@1673
   161
            SDL_keynames[i] = "f3";
slouken@1673
   162
            break;
slouken@1673
   163
        case SDLK_F4:
slouken@1673
   164
            SDL_keynames[i] = "f4";
slouken@1673
   165
            break;
slouken@1673
   166
        case SDLK_F5:
slouken@1673
   167
            SDL_keynames[i] = "f5";
slouken@1673
   168
            break;
slouken@1673
   169
        case SDLK_F6:
slouken@1673
   170
            SDL_keynames[i] = "f6";
slouken@1673
   171
            break;
slouken@1673
   172
        case SDLK_F7:
slouken@1673
   173
            SDL_keynames[i] = "f7";
slouken@1673
   174
            break;
slouken@1673
   175
        case SDLK_F8:
slouken@1673
   176
            SDL_keynames[i] = "f8";
slouken@1673
   177
            break;
slouken@1673
   178
        case SDLK_F9:
slouken@1673
   179
            SDL_keynames[i] = "f9";
slouken@1673
   180
            break;
slouken@1673
   181
        case SDLK_F10:
slouken@1673
   182
            SDL_keynames[i] = "f10";
slouken@1673
   183
            break;
slouken@1673
   184
        case SDLK_F11:
slouken@1673
   185
            SDL_keynames[i] = "f11";
slouken@1673
   186
            break;
slouken@1673
   187
        case SDLK_F12:
slouken@1673
   188
            SDL_keynames[i] = "f12";
slouken@1673
   189
            break;
slouken@1673
   190
        case SDLK_F13:
slouken@1673
   191
            SDL_keynames[i] = "f13";
slouken@1673
   192
            break;
slouken@1673
   193
        case SDLK_F14:
slouken@1673
   194
            SDL_keynames[i] = "f14";
slouken@1673
   195
            break;
slouken@1673
   196
        case SDLK_F15:
slouken@1673
   197
            SDL_keynames[i] = "f15";
slouken@1673
   198
            break;
slouken@0
   199
slouken@1673
   200
        case SDLK_NUMLOCK:
slouken@1673
   201
            SDL_keynames[i] = "numlock";
slouken@1673
   202
            break;
slouken@1673
   203
        case SDLK_CAPSLOCK:
slouken@1673
   204
            SDL_keynames[i] = "caps lock";
slouken@1673
   205
            break;
slouken@1673
   206
        case SDLK_SCROLLOCK:
slouken@1673
   207
            SDL_keynames[i] = "scroll lock";
slouken@1673
   208
            break;
slouken@1673
   209
        case SDLK_RSHIFT:
slouken@1673
   210
            SDL_keynames[i] = "right shift";
slouken@1673
   211
            break;
slouken@1673
   212
        case SDLK_LSHIFT:
slouken@1673
   213
            SDL_keynames[i] = "left shift";
slouken@1673
   214
            break;
slouken@1673
   215
        case SDLK_RCTRL:
slouken@1673
   216
            SDL_keynames[i] = "right ctrl";
slouken@1673
   217
            break;
slouken@1673
   218
        case SDLK_LCTRL:
slouken@1673
   219
            SDL_keynames[i] = "left ctrl";
slouken@1673
   220
            break;
slouken@1673
   221
        case SDLK_RALT:
slouken@1673
   222
            SDL_keynames[i] = "right alt";
slouken@1673
   223
            break;
slouken@1673
   224
        case SDLK_LALT:
slouken@1673
   225
            SDL_keynames[i] = "left alt";
slouken@1673
   226
            break;
slouken@1673
   227
        case SDLK_RMETA:
slouken@1673
   228
            SDL_keynames[i] = "right meta";
slouken@1673
   229
            break;
slouken@1673
   230
        case SDLK_LMETA:
slouken@1673
   231
            SDL_keynames[i] = "left meta";
slouken@1673
   232
            break;
slouken@1673
   233
        case SDLK_LSUPER:
slouken@1673
   234
            SDL_keynames[i] = "left super";     /* "Windows" keys */
slouken@1673
   235
            break;
slouken@1673
   236
        case SDLK_RSUPER:
slouken@1673
   237
            SDL_keynames[i] = "right super";
slouken@1673
   238
            break;
slouken@1673
   239
        case SDLK_MODE:
slouken@1673
   240
            SDL_keynames[i] = "alt gr";
slouken@1673
   241
            break;
slouken@1673
   242
        case SDLK_COMPOSE:
slouken@1673
   243
            SDL_keynames[i] = "compose";
slouken@1673
   244
            break;
slouken@0
   245
slouken@1673
   246
        case SDLK_HELP:
slouken@1673
   247
            SDL_keynames[i] = "help";
slouken@1673
   248
            break;
slouken@1673
   249
        case SDLK_PRINT:
slouken@1673
   250
            SDL_keynames[i] = "print screen";
slouken@1673
   251
            break;
slouken@1673
   252
        case SDLK_SYSREQ:
slouken@1673
   253
            SDL_keynames[i] = "sys req";
slouken@1673
   254
            break;
slouken@1673
   255
        case SDLK_BREAK:
slouken@1673
   256
            SDL_keynames[i] = "break";
slouken@1673
   257
            break;
slouken@1673
   258
        case SDLK_MENU:
slouken@1673
   259
            SDL_keynames[i] = "menu";
slouken@1673
   260
            break;
slouken@1673
   261
        case SDLK_POWER:
slouken@1673
   262
            SDL_keynames[i] = "power";
slouken@1673
   263
            break;
slouken@1673
   264
        case SDLK_EURO:
slouken@1673
   265
            SDL_keynames[i] = "euro";
slouken@1673
   266
            break;
slouken@1673
   267
        case SDLK_UNDO:
slouken@1673
   268
            SDL_keynames[i] = "undo";
slouken@1673
   269
            break;
slouken@0
   270
slouken@1673
   271
        default:
slouken@1673
   272
            SDL_keynames[i] = NULL;
slouken@1673
   273
            break;
slouken@1673
   274
        }
slouken@1673
   275
    }
slouken@0
   276
slouken@1662
   277
    /* Done.  Whew. */
slouken@1662
   278
    return (0);
slouken@0
   279
}
slouken@1662
   280
slouken@1673
   281
SDL_Keyboard *
slouken@1673
   282
SDL_GetKeyboard(int index)
slouken@1673
   283
{
slouken@1673
   284
    if (index < 0 || index >= SDL_num_keyboards) {
slouken@1673
   285
        return NULL;
slouken@1673
   286
    }
slouken@1673
   287
    return SDL_keyboards[index];
slouken@1673
   288
}
slouken@1673
   289
slouken@1673
   290
int
slouken@1673
   291
SDL_AddKeyboard(const SDL_Keyboard * keyboard, int index)
slouken@1673
   292
{
slouken@1673
   293
    SDL_Keyboard **keyboards;
slouken@1673
   294
    SDL_Cursor *cursor;
slouken@1673
   295
    int selected_keyboard;
slouken@1673
   296
slouken@1673
   297
    /* Add the keyboard to the list of keyboards */
slouken@1673
   298
    if (index < 0 || index >= SDL_num_keyboards || SDL_keyboards[index]) {
slouken@1673
   299
        keyboards =
slouken@1673
   300
            (SDL_Keyboard **) SDL_realloc(SDL_keyboards,
slouken@1673
   301
                                          (SDL_num_keyboards +
slouken@1673
   302
                                           1) * sizeof(*keyboards));
slouken@1673
   303
        if (!keyboards) {
slouken@1673
   304
            SDL_OutOfMemory();
slouken@1673
   305
            return -1;
slouken@1673
   306
        }
slouken@1673
   307
slouken@1673
   308
        SDL_keyboards = keyboards;
slouken@1673
   309
        index = SDL_num_keyboards++;
slouken@1673
   310
    }
slouken@1673
   311
    SDL_keyboards[index] =
slouken@1673
   312
        (SDL_Keyboard *) SDL_malloc(sizeof(*SDL_keyboards[index]));
slouken@1673
   313
    if (!SDL_keyboards[index]) {
slouken@1673
   314
        SDL_OutOfMemory();
slouken@1673
   315
        return -1;
slouken@1673
   316
    }
slouken@1673
   317
    *SDL_keyboards[index] = *keyboard;
slouken@1673
   318
slouken@1673
   319
    return index;
slouken@1673
   320
}
slouken@1673
   321
slouken@1673
   322
void
slouken@1673
   323
SDL_DelKeyboard(int index)
slouken@1673
   324
{
slouken@1673
   325
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@1673
   326
slouken@1673
   327
    if (!keyboard) {
slouken@1673
   328
        return;
slouken@1673
   329
    }
slouken@1673
   330
slouken@1673
   331
    if (keyboard->FreeKeyboard) {
slouken@1673
   332
        keyboard->FreeKeyboard(keyboard);
slouken@1673
   333
    }
slouken@1673
   334
    SDL_free(keyboard);
slouken@1673
   335
slouken@1673
   336
    SDL_keyboards[index] = NULL;
slouken@1673
   337
}
slouken@1673
   338
slouken@1673
   339
void
slouken@1673
   340
SDL_ResetKeyboard(int index)
slouken@1673
   341
{
slouken@1673
   342
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@1673
   343
    SDL_keysym keysym;
slouken@1674
   344
    Uint16 key;
slouken@1673
   345
slouken@1673
   346
    if (!keyboard) {
slouken@1673
   347
        return;
slouken@1673
   348
    }
slouken@1673
   349
slouken@1673
   350
    SDL_memset(&keysym, 0, (sizeof keysym));
slouken@1673
   351
    for (key = SDLK_FIRST; key < SDLK_LAST; ++key) {
slouken@1673
   352
        if (keyboard->keystate[key] == SDL_PRESSED) {
slouken@1673
   353
            keysym.sym = key;
slouken@1674
   354
            SDL_SendKeyboardKey(index, 0, SDL_RELEASED, &keysym);
slouken@1673
   355
        }
slouken@1673
   356
    }
slouken@1674
   357
    keyboard->repeat.timestamp = 0;
slouken@1673
   358
}
slouken@1673
   359
slouken@1662
   360
void
slouken@1668
   361
SDL_KeyboardQuit(void)
slouken@1123
   362
{
slouken@1673
   363
    int i;
slouken@1673
   364
slouken@1673
   365
    for (i = 0; i < SDL_num_keyboards; ++i) {
slouken@1673
   366
        SDL_DelKeyboard(i);
slouken@1673
   367
    }
slouken@1673
   368
    SDL_num_keyboards = 0;
slouken@1673
   369
    SDL_current_keyboard = 0;
slouken@1673
   370
slouken@1673
   371
    if (SDL_keyboards) {
slouken@1673
   372
        SDL_free(SDL_keyboards);
slouken@1673
   373
        SDL_keyboards = NULL;
slouken@1673
   374
    }
slouken@1123
   375
}
slouken@0
   376
slouken@1673
   377
int
slouken@1673
   378
SDL_GetNumKeyboards(void)
slouken@0
   379
{
slouken@1673
   380
    return SDL_num_keyboards;
slouken@1673
   381
}
slouken@0
   382
slouken@1673
   383
int
slouken@1673
   384
SDL_SelectKeyboard(int index)
slouken@1673
   385
{
slouken@1673
   386
    if (index >= 0 && index < SDL_num_keyboards) {
slouken@1673
   387
        SDL_current_keyboard = index;
slouken@1662
   388
    }
slouken@1673
   389
    return SDL_current_keyboard;
slouken@0
   390
}
slouken@0
   391
slouken@1662
   392
int
slouken@1668
   393
SDL_EnableUNICODE(int enable)
slouken@0
   394
{
slouken@1662
   395
    int old_mode;
slouken@0
   396
slouken@1662
   397
    old_mode = SDL_TranslateUNICODE;
slouken@1662
   398
    if (enable >= 0) {
slouken@1662
   399
        SDL_TranslateUNICODE = enable;
slouken@1662
   400
    }
slouken@1662
   401
    return (old_mode);
slouken@0
   402
}
slouken@0
   403
slouken@1662
   404
Uint8 *
slouken@1668
   405
SDL_GetKeyState(int *numkeys)
slouken@0
   406
{
slouken@1674
   407
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1674
   408
slouken@1674
   409
    if (numkeys != (int *) 0) {
slouken@1662
   410
        *numkeys = SDLK_LAST;
slouken@1674
   411
    }
slouken@1674
   412
slouken@1674
   413
    if (!keyboard) {
slouken@1674
   414
        return NULL;
slouken@1674
   415
    }
slouken@1674
   416
    return keyboard->keystate;
slouken@0
   417
}
slouken@0
   418
slouken@1662
   419
SDLMod
slouken@1668
   420
SDL_GetModState(void)
slouken@0
   421
{
slouken@1674
   422
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1673
   423
slouken@1673
   424
    if (!keyboard) {
slouken@1673
   425
        return KMOD_NONE;
slouken@1673
   426
    }
slouken@1673
   427
    return keyboard->modstate;
slouken@1662
   428
}
slouken@0
   429
slouken@1662
   430
void
slouken@1668
   431
SDL_SetModState(SDLMod modstate)
slouken@1662
   432
{
slouken@1674
   433
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1673
   434
slouken@1673
   435
    if (!keyboard) {
slouken@1673
   436
        return;
slouken@1673
   437
    }
slouken@1673
   438
    keyboard->modstate = modstate;
slouken@1662
   439
}
slouken@1662
   440
slouken@1673
   441
const char *
slouken@1668
   442
SDL_GetKeyName(SDLKey key)
slouken@1662
   443
{
slouken@1662
   444
    const char *keyname;
slouken@1662
   445
slouken@1679
   446
    if (key < SDL_arraysize(SDL_keynames)) {
slouken@1674
   447
        keyname = SDL_keynames[key];
slouken@1674
   448
    } else {
slouken@1674
   449
        keyname = NULL;
slouken@1674
   450
    }
slouken@1673
   451
    if (keyname == NULL) {
slouken@1673
   452
        if (key < 256) {
slouken@1673
   453
            static char temp[4];
slouken@1674
   454
            char *cvt;
slouken@1674
   455
            temp[0] = (char) key;
slouken@1674
   456
            temp[1] = '\0';
slouken@1674
   457
            cvt = SDL_iconv_string("UTF-8", "LATIN1", temp, 1);
slouken@1674
   458
            SDL_strlcpy(temp, cvt, SDL_arraysize(temp));
slouken@1674
   459
            SDL_free(cvt);
slouken@1674
   460
            keyname = temp;
slouken@1673
   461
        } else {
slouken@1673
   462
            keyname = "unknown key";
slouken@1673
   463
        }
slouken@1662
   464
    }
slouken@1673
   465
    return keyname;
slouken@0
   466
}
slouken@0
   467
slouken@1662
   468
int
slouken@1674
   469
SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state,
slouken@1674
   470
                    SDL_keysym * keysym)
slouken@0
   471
{
slouken@1674
   472
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@1662
   473
    int posted, repeatable;
slouken@1662
   474
    Uint16 modstate;
slouken@1674
   475
    Uint8 type;
slouken@0
   476
slouken@1674
   477
    if (!keyboard) {
slouken@1674
   478
        return 0;
slouken@1674
   479
    }
slouken@0
   480
slouken@1674
   481
    if (windowID) {
slouken@1674
   482
        keyboard->focus = windowID;
slouken@1674
   483
    }
slouken@0
   484
#if 0
slouken@1668
   485
    printf("The '%s' key has been %s\n", SDL_GetKeyName(keysym->sym),
slouken@1668
   486
           state == SDL_PRESSED ? "pressed" : "released");
slouken@0
   487
#endif
slouken@1662
   488
    /* Set up the keysym */
slouken@1674
   489
    modstate = keyboard->modstate;
slouken@0
   490
slouken@1662
   491
    repeatable = 0;
slouken@0
   492
slouken@1662
   493
    if (state == SDL_PRESSED) {
slouken@1674
   494
        keysym->mod = modstate;
slouken@1662
   495
        switch (keysym->sym) {
slouken@1662
   496
        case SDLK_UNKNOWN:
slouken@1662
   497
            break;
slouken@1662
   498
        case SDLK_NUMLOCK:
slouken@1662
   499
            modstate ^= KMOD_NUM;
slouken@1662
   500
            if (!(modstate & KMOD_NUM))
slouken@1662
   501
                state = SDL_RELEASED;
slouken@1674
   502
            keysym->mod = modstate;
slouken@1662
   503
            break;
slouken@1662
   504
        case SDLK_CAPSLOCK:
slouken@1662
   505
            modstate ^= KMOD_CAPS;
slouken@1662
   506
            if (!(modstate & KMOD_CAPS))
slouken@1662
   507
                state = SDL_RELEASED;
slouken@1674
   508
            keysym->mod = modstate;
slouken@1662
   509
            break;
slouken@1662
   510
        case SDLK_LCTRL:
slouken@1662
   511
            modstate |= KMOD_LCTRL;
slouken@1662
   512
            break;
slouken@1662
   513
        case SDLK_RCTRL:
slouken@1662
   514
            modstate |= KMOD_RCTRL;
slouken@1662
   515
            break;
slouken@1662
   516
        case SDLK_LSHIFT:
slouken@1662
   517
            modstate |= KMOD_LSHIFT;
slouken@1662
   518
            break;
slouken@1662
   519
        case SDLK_RSHIFT:
slouken@1662
   520
            modstate |= KMOD_RSHIFT;
slouken@1662
   521
            break;
slouken@1662
   522
        case SDLK_LALT:
slouken@1662
   523
            modstate |= KMOD_LALT;
slouken@1662
   524
            break;
slouken@1662
   525
        case SDLK_RALT:
slouken@1662
   526
            modstate |= KMOD_RALT;
slouken@1662
   527
            break;
slouken@1662
   528
        case SDLK_LMETA:
slouken@1662
   529
            modstate |= KMOD_LMETA;
slouken@1662
   530
            break;
slouken@1662
   531
        case SDLK_RMETA:
slouken@1662
   532
            modstate |= KMOD_RMETA;
slouken@1662
   533
            break;
slouken@1662
   534
        case SDLK_MODE:
slouken@1662
   535
            modstate |= KMOD_MODE;
slouken@1662
   536
            break;
slouken@1662
   537
        default:
slouken@1662
   538
            repeatable = 1;
slouken@1662
   539
            break;
slouken@1662
   540
        }
slouken@1662
   541
    } else {
slouken@1662
   542
        switch (keysym->sym) {
slouken@1662
   543
        case SDLK_UNKNOWN:
slouken@1662
   544
            break;
slouken@1662
   545
        case SDLK_NUMLOCK:
slouken@1662
   546
        case SDLK_CAPSLOCK:
slouken@1662
   547
            /* Only send keydown events */
slouken@1662
   548
            return (0);
slouken@1662
   549
        case SDLK_LCTRL:
slouken@1662
   550
            modstate &= ~KMOD_LCTRL;
slouken@1662
   551
            break;
slouken@1662
   552
        case SDLK_RCTRL:
slouken@1662
   553
            modstate &= ~KMOD_RCTRL;
slouken@1662
   554
            break;
slouken@1662
   555
        case SDLK_LSHIFT:
slouken@1662
   556
            modstate &= ~KMOD_LSHIFT;
slouken@1662
   557
            break;
slouken@1662
   558
        case SDLK_RSHIFT:
slouken@1662
   559
            modstate &= ~KMOD_RSHIFT;
slouken@1662
   560
            break;
slouken@1662
   561
        case SDLK_LALT:
slouken@1662
   562
            modstate &= ~KMOD_LALT;
slouken@1662
   563
            break;
slouken@1662
   564
        case SDLK_RALT:
slouken@1662
   565
            modstate &= ~KMOD_RALT;
slouken@1662
   566
            break;
slouken@1662
   567
        case SDLK_LMETA:
slouken@1662
   568
            modstate &= ~KMOD_LMETA;
slouken@1662
   569
            break;
slouken@1662
   570
        case SDLK_RMETA:
slouken@1662
   571
            modstate &= ~KMOD_RMETA;
slouken@1662
   572
            break;
slouken@1662
   573
        case SDLK_MODE:
slouken@1662
   574
            modstate &= ~KMOD_MODE;
slouken@1662
   575
            break;
slouken@1662
   576
        default:
slouken@1662
   577
            break;
slouken@1662
   578
        }
slouken@1674
   579
        keysym->mod = modstate;
slouken@1662
   580
    }
slouken@0
   581
slouken@1662
   582
    /* Figure out what type of event this is */
slouken@1662
   583
    switch (state) {
slouken@1662
   584
    case SDL_PRESSED:
slouken@1674
   585
        type = SDL_KEYDOWN;
slouken@1662
   586
        break;
slouken@1662
   587
    case SDL_RELEASED:
slouken@1674
   588
        type = SDL_KEYUP;
slouken@1662
   589
        /*
slouken@1662
   590
         * jk 991215 - Added
slouken@1662
   591
         */
slouken@1674
   592
        if (keyboard->repeat.timestamp &&
slouken@1674
   593
            keyboard->repeat.evt.key.keysym.sym == keysym->sym) {
slouken@1674
   594
            keyboard->repeat.timestamp = 0;
slouken@1662
   595
        }
slouken@1662
   596
        break;
slouken@1662
   597
    default:
slouken@1662
   598
        /* Invalid state -- bail */
slouken@1674
   599
        return 0;
slouken@1662
   600
    }
slouken@0
   601
slouken@1662
   602
    if (keysym->sym != SDLK_UNKNOWN) {
slouken@1662
   603
        /* Drop events that don't change state */
slouken@1674
   604
        if (keyboard->keystate[keysym->sym] == state) {
slouken@1282
   605
#if 0
slouken@1668
   606
            printf("Keyboard event didn't change state - dropped!\n");
slouken@1282
   607
#endif
slouken@1674
   608
            return 0;
slouken@1662
   609
        }
slouken@1327
   610
slouken@1662
   611
        /* Update internal keyboard state */
slouken@1674
   612
        keyboard->modstate = modstate;
slouken@1674
   613
        keyboard->keystate[keysym->sym] = state;
slouken@1662
   614
    }
slouken@0
   615
slouken@1662
   616
    /* Post the event, if desired */
slouken@1662
   617
    posted = 0;
slouken@1674
   618
    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
slouken@1674
   619
        SDL_Event event;
slouken@1674
   620
        event.key.type = type;
slouken@1674
   621
        event.key.which = (Uint8) index;
slouken@1662
   622
        event.key.state = state;
slouken@1662
   623
        event.key.keysym = *keysym;
slouken@1674
   624
        event.key.windowID = keyboard->focus;
slouken@1662
   625
        /*
slouken@1662
   626
         * jk 991215 - Added
slouken@1662
   627
         */
slouken@1674
   628
        if (repeatable && (keyboard->repeat.delay != 0)) {
slouken@1674
   629
            Uint32 timestamp = SDL_GetTicks();
slouken@1674
   630
            if (!timestamp) {
slouken@1674
   631
                timestamp = 1;
slouken@1674
   632
            }
slouken@1674
   633
            keyboard->repeat.evt = event;
slouken@1674
   634
            keyboard->repeat.firsttime = 1;
slouken@1674
   635
            keyboard->repeat.timestamp = 1;
slouken@1662
   636
        }
slouken@1668
   637
        if ((SDL_EventOK == NULL) || SDL_EventOK(&event)) {
slouken@1662
   638
            posted = 1;
slouken@1668
   639
            SDL_PushEvent(&event);
slouken@1662
   640
        }
slouken@1662
   641
    }
slouken@1662
   642
    return (posted);
slouken@0
   643
}
slouken@0
   644
slouken@0
   645
/*
slouken@0
   646
 * jk 991215 - Added
slouken@0
   647
 */
slouken@1662
   648
void
slouken@1668
   649
SDL_CheckKeyRepeat(void)
slouken@0
   650
{
slouken@1674
   651
    int i;
slouken@0
   652
slouken@1674
   653
    for (i = 0; i < SDL_num_keyboards; ++i) {
slouken@1674
   654
        SDL_Keyboard *keyboard = SDL_keyboards[i];
slouken@1674
   655
slouken@1674
   656
        if (!keyboard) {
slouken@1674
   657
            continue;
slouken@1674
   658
        }
slouken@1674
   659
slouken@1674
   660
        if (keyboard->repeat.timestamp) {
slouken@1674
   661
            Uint32 now, interval;
slouken@1674
   662
slouken@1674
   663
            now = SDL_GetTicks();
slouken@1674
   664
            interval = (now - keyboard->repeat.timestamp);
slouken@1674
   665
            if (keyboard->repeat.firsttime) {
slouken@1674
   666
                if (interval > (Uint32) keyboard->repeat.delay) {
slouken@1674
   667
                    keyboard->repeat.timestamp = now;
slouken@1674
   668
                    keyboard->repeat.firsttime = 0;
slouken@1674
   669
                }
slouken@1674
   670
            } else {
slouken@1674
   671
                if (interval > (Uint32) keyboard->repeat.interval) {
slouken@1674
   672
                    keyboard->repeat.timestamp = now;
slouken@1674
   673
                    if ((SDL_EventOK == NULL)
slouken@1674
   674
                        || SDL_EventOK(&keyboard->repeat.evt)) {
slouken@1674
   675
                        SDL_PushEvent(&keyboard->repeat.evt);
slouken@1674
   676
                    }
slouken@1662
   677
                }
slouken@1662
   678
            }
slouken@1662
   679
        }
slouken@1662
   680
    }
slouken@0
   681
}
slouken@0
   682
slouken@1662
   683
int
slouken@1668
   684
SDL_EnableKeyRepeat(int delay, int interval)
slouken@0
   685
{
slouken@1674
   686
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1674
   687
slouken@1674
   688
    if (!keyboard) {
slouken@1674
   689
        SDL_SetError("No keyboard is currently selected");
slouken@1674
   690
        return -1;
slouken@1674
   691
    }
slouken@1674
   692
slouken@1662
   693
    if ((delay < 0) || (interval < 0)) {
slouken@1668
   694
        SDL_SetError("keyboard repeat value less than zero");
slouken@1674
   695
        return -1;
slouken@1662
   696
    }
slouken@1674
   697
slouken@1674
   698
    keyboard->repeat.firsttime = 0;
slouken@1674
   699
    keyboard->repeat.delay = delay;
slouken@1674
   700
    keyboard->repeat.interval = interval;
slouken@1674
   701
    keyboard->repeat.timestamp = 0;
slouken@1674
   702
slouken@1674
   703
    return 0;
slouken@0
   704
}
slouken@0
   705
slouken@1662
   706
void
slouken@1668
   707
SDL_GetKeyRepeat(int *delay, int *interval)
slouken@1507
   708
{
slouken@1674
   709
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1674
   710
slouken@1674
   711
    if (!keyboard) {
slouken@1674
   712
        if (delay) {
slouken@1674
   713
            *delay = 0;
slouken@1674
   714
        }
slouken@1674
   715
        if (interval) {
slouken@1674
   716
            *interval = 0;
slouken@1674
   717
        }
slouken@1674
   718
        return;
slouken@1674
   719
    }
slouken@1674
   720
    if (delay) {
slouken@1674
   721
        *delay = keyboard->repeat.delay;
slouken@1674
   722
    }
slouken@1674
   723
    if (interval) {
slouken@1674
   724
        *interval = keyboard->repeat.interval;
slouken@1674
   725
    }
slouken@1507
   726
}
slouken@1507
   727
slouken@1662
   728
/* vi: set ts=4 sw=4 expandtab: */