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