src/events/SDL_keyboard.c
author Bob Pendleton <bob@pendleton.com>
Tue, 08 Jan 2008 00:10:46 +0000
changeset 2295 dbc6d1893869
parent 2268 4baee598306d
child 2300 c97ad1abe05b
permissions -rw-r--r--
Checking in Christian Walther's patch for x11 keyboard input. Minor code tweaks by Bob.
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@2268
    30
#include "SDL_keynames.h"
slouken@0
    31
slouken@0
    32
slouken@1895
    33
/* Global keyboard information */
slouken@0
    34
int SDL_TranslateUNICODE = 0;
slouken@1895
    35
static int SDL_num_keyboards;
slouken@1895
    36
static int SDL_current_keyboard;
slouken@1895
    37
static SDL_Keyboard **SDL_keyboards;
slouken@0
    38
bob@2295
    39
/* Taken from SDL_iconv() */
bob@2295
    40
static char *
bob@2295
    41
encodeUtf8(Uint32 ch, char *dst)
bob@2295
    42
{
bob@2295
    43
    Uint8 *p = (Uint8 *) dst;
bob@2295
    44
    if (ch <= 0x7F) {
bob@2295
    45
        *p = (Uint8) ch;
bob@2295
    46
        ++dst;
bob@2295
    47
    } else if (ch <= 0x7FF) {
bob@2295
    48
        p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F);
bob@2295
    49
        p[1] = 0x80 | (Uint8) (ch & 0x3F);
bob@2295
    50
        dst += 2;
bob@2295
    51
    } else if (ch <= 0xFFFF) {
bob@2295
    52
        p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F);
bob@2295
    53
        p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
bob@2295
    54
        p[2] = 0x80 | (Uint8) (ch & 0x3F);
bob@2295
    55
        dst += 3;
bob@2295
    56
    } else if (ch <= 0x1FFFFF) {
bob@2295
    57
        p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07);
bob@2295
    58
        p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
bob@2295
    59
        p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
bob@2295
    60
        p[3] = 0x80 | (Uint8) (ch & 0x3F);
bob@2295
    61
        dst += 4;
bob@2295
    62
    } else if (ch <= 0x3FFFFFF) {
bob@2295
    63
        p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03);
bob@2295
    64
        p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
bob@2295
    65
        p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
bob@2295
    66
        p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
bob@2295
    67
        p[4] = 0x80 | (Uint8) (ch & 0x3F);
bob@2295
    68
        dst += 5;
bob@2295
    69
    } else {
bob@2295
    70
        p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01);
bob@2295
    71
        p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F);
bob@2295
    72
        p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
bob@2295
    73
        p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
bob@2295
    74
        p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
bob@2295
    75
        p[5] = 0x80 | (Uint8) (ch & 0x3F);
bob@2295
    76
        dst += 6;
bob@2295
    77
    }
bob@2295
    78
    return dst;
bob@2295
    79
}
bob@2295
    80
slouken@0
    81
/* Public functions */
slouken@1895
    82
int
slouken@1895
    83
SDL_KeyboardInit(void)
slouken@0
    84
{
slouken@1895
    85
    /* Set default mode of UNICODE translation */
slouken@1895
    86
    SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION);
slouken@0
    87
slouken@1895
    88
    return (0);
slouken@1123
    89
}
slouken@0
    90
slouken@1895
    91
SDL_Keyboard *
slouken@1895
    92
SDL_GetKeyboard(int index)
slouken@0
    93
{
slouken@1895
    94
    if (index < 0 || index >= SDL_num_keyboards) {
slouken@1895
    95
        return NULL;
slouken@1895
    96
    }
slouken@1895
    97
    return SDL_keyboards[index];
slouken@0
    98
}
slouken@0
    99
slouken@1895
   100
int
slouken@1895
   101
SDL_AddKeyboard(const SDL_Keyboard * keyboard, int index)
slouken@0
   102
{
slouken@1895
   103
    SDL_Keyboard **keyboards;
slouken@0
   104
slouken@1895
   105
    /* Add the keyboard to the list of keyboards */
slouken@1895
   106
    if (index < 0 || index >= SDL_num_keyboards || SDL_keyboards[index]) {
slouken@1895
   107
        keyboards =
slouken@1895
   108
            (SDL_Keyboard **) SDL_realloc(SDL_keyboards,
slouken@1895
   109
                                          (SDL_num_keyboards +
slouken@1895
   110
                                           1) * sizeof(*keyboards));
slouken@1895
   111
        if (!keyboards) {
slouken@1895
   112
            SDL_OutOfMemory();
slouken@1895
   113
            return -1;
slouken@1895
   114
        }
slouken@1895
   115
slouken@1895
   116
        SDL_keyboards = keyboards;
slouken@1895
   117
        index = SDL_num_keyboards++;
slouken@1895
   118
    }
slouken@1895
   119
    SDL_keyboards[index] =
slouken@1895
   120
        (SDL_Keyboard *) SDL_malloc(sizeof(*SDL_keyboards[index]));
slouken@1895
   121
    if (!SDL_keyboards[index]) {
slouken@1895
   122
        SDL_OutOfMemory();
slouken@1895
   123
        return -1;
slouken@1895
   124
    }
slouken@1895
   125
    *SDL_keyboards[index] = *keyboard;
slouken@1895
   126
slouken@1895
   127
    return index;
slouken@0
   128
}
slouken@0
   129
slouken@1895
   130
void
slouken@1895
   131
SDL_DelKeyboard(int index)
slouken@0
   132
{
slouken@1895
   133
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@1895
   134
slouken@1895
   135
    if (!keyboard) {
slouken@1895
   136
        return;
slouken@1895
   137
    }
slouken@1895
   138
slouken@1895
   139
    if (keyboard->FreeKeyboard) {
slouken@1895
   140
        keyboard->FreeKeyboard(keyboard);
slouken@1895
   141
    }
slouken@1895
   142
    SDL_free(keyboard);
slouken@1895
   143
slouken@1895
   144
    SDL_keyboards[index] = NULL;
slouken@0
   145
}
slouken@0
   146
slouken@1895
   147
void
slouken@1895
   148
SDL_ResetKeyboard(int index)
slouken@0
   149
{
slouken@1895
   150
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@2268
   151
    int key;
slouken@0
   152
slouken@1895
   153
    if (!keyboard) {
slouken@1895
   154
        return;
slouken@1895
   155
    }
slouken@1895
   156
slouken@1895
   157
    for (key = SDLK_FIRST; key < SDLK_LAST; ++key) {
slouken@1895
   158
        if (keyboard->keystate[key] == SDL_PRESSED) {
slouken@2268
   159
            SDL_SendKeyboardKey(index, SDL_RELEASED, 0,
slouken@2268
   160
                                key | SDL_KEY_CAN_BE_PHYSICAL_BIT);
slouken@1895
   161
        }
slouken@1895
   162
    }
slouken@0
   163
}
slouken@0
   164
slouken@1895
   165
void
slouken@1895
   166
SDL_KeyboardQuit(void)
slouken@0
   167
{
slouken@1895
   168
    int i;
slouken@0
   169
slouken@1895
   170
    for (i = 0; i < SDL_num_keyboards; ++i) {
slouken@1895
   171
        SDL_DelKeyboard(i);
slouken@1895
   172
    }
slouken@1895
   173
    SDL_num_keyboards = 0;
slouken@1895
   174
    SDL_current_keyboard = 0;
slouken@0
   175
slouken@1895
   176
    if (SDL_keyboards) {
slouken@1895
   177
        SDL_free(SDL_keyboards);
slouken@1895
   178
        SDL_keyboards = NULL;
slouken@1895
   179
    }
slouken@1895
   180
}
slouken@1895
   181
slouken@1895
   182
int
slouken@1895
   183
SDL_GetNumKeyboards(void)
slouken@1895
   184
{
slouken@1895
   185
    return SDL_num_keyboards;
slouken@1895
   186
}
slouken@1895
   187
slouken@1895
   188
int
slouken@1895
   189
SDL_SelectKeyboard(int index)
slouken@1895
   190
{
slouken@1895
   191
    if (index >= 0 && index < SDL_num_keyboards) {
slouken@1895
   192
        SDL_current_keyboard = index;
slouken@1895
   193
    }
slouken@1895
   194
    return SDL_current_keyboard;
slouken@1895
   195
}
slouken@1895
   196
slouken@1895
   197
int
slouken@1895
   198
SDL_EnableUNICODE(int enable)
slouken@1895
   199
{
slouken@1895
   200
    int old_mode;
slouken@1895
   201
slouken@1895
   202
    old_mode = SDL_TranslateUNICODE;
slouken@1895
   203
    if (enable >= 0) {
slouken@1895
   204
        SDL_TranslateUNICODE = enable;
slouken@1895
   205
    }
slouken@1895
   206
    return (old_mode);
slouken@1895
   207
}
slouken@1895
   208
slouken@1895
   209
Uint8 *
slouken@1895
   210
SDL_GetKeyState(int *numkeys)
slouken@1895
   211
{
slouken@1895
   212
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1895
   213
slouken@1895
   214
    if (numkeys != (int *) 0) {
slouken@1895
   215
        *numkeys = SDLK_LAST;
slouken@1895
   216
    }
slouken@1895
   217
slouken@1895
   218
    if (!keyboard) {
slouken@1895
   219
        return NULL;
slouken@1895
   220
    }
slouken@1895
   221
    return keyboard->keystate;
slouken@1895
   222
}
slouken@1895
   223
slouken@1895
   224
SDLMod
slouken@1895
   225
SDL_GetModState(void)
slouken@1895
   226
{
slouken@1895
   227
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1895
   228
slouken@1895
   229
    if (!keyboard) {
slouken@1895
   230
        return KMOD_NONE;
slouken@1895
   231
    }
slouken@1895
   232
    return keyboard->modstate;
slouken@1895
   233
}
slouken@1895
   234
slouken@1895
   235
void
slouken@1895
   236
SDL_SetModState(SDLMod modstate)
slouken@1895
   237
{
slouken@1895
   238
    SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard);
slouken@1895
   239
slouken@1895
   240
    if (!keyboard) {
slouken@1895
   241
        return;
slouken@1895
   242
    }
slouken@1895
   243
    keyboard->modstate = modstate;
slouken@1895
   244
}
slouken@1895
   245
slouken@2268
   246
SDLKey
slouken@2268
   247
SDL_GetLayoutKey(SDLKey physicalKey)
slouken@2268
   248
{
slouken@2268
   249
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@2268
   250
    if (_this && _this->GetLayoutKey) {
slouken@2268
   251
        return _this->GetLayoutKey(_this, physicalKey)
slouken@2268
   252
            | (physicalKey & SDL_KEY_KEYPAD_BIT);
slouken@2268
   253
    } else {
slouken@2268
   254
        return physicalKey;
slouken@2268
   255
    }
slouken@2268
   256
}
slouken@2268
   257
slouken@1895
   258
const char *
slouken@2268
   259
SDL_GetKeyName(SDLKey layoutKey)
slouken@1895
   260
{
slouken@2268
   261
    const char *keyname = NULL;
slouken@1895
   262
slouken@2268
   263
    if ((layoutKey & SDL_KEY_LAYOUT_SPECIAL_BIT) != 0) {
slouken@2268
   264
        SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@2268
   265
        if (_this && _this->GetSpecialKeyName) {
slouken@2268
   266
            keyname = _this->GetSpecialKeyName(_this, layoutKey);
slouken@2268
   267
        }
slouken@2268
   268
    } else if ((layoutKey & SDL_KEY_CAN_BE_PHYSICAL_BIT) == 0) {
slouken@2268
   269
        /* SDLK_INDEX(layoutKey) is the unicode code point of the character generated by the key */
slouken@2268
   270
        static char buffer[9];  /* 6 (maximal UTF-8 char length) + 2 ([] for keypad) + 1 (null teminator) */
slouken@2268
   271
        char *bufferPtr = &buffer[1];
slouken@2268
   272
        Uint32 codepoint = SDLK_INDEX(layoutKey);
slouken@2268
   273
slouken@2268
   274
        /* Unaccented letter keys on latin keyboards are normally labeled in upper case (and probably on others like Greek or Cyrillic too, so if you happen to know for sure, please adapt this). */
slouken@2268
   275
        if (codepoint >= 'a' && codepoint <= 'z') {
slouken@2268
   276
            codepoint -= 32;
slouken@2268
   277
        }
slouken@2268
   278
bob@2295
   279
        bufferPtr = encodeUtf8(codepoint, bufferPtr);
slouken@2268
   280
        *bufferPtr = '\0';
slouken@2268
   281
slouken@2268
   282
        if ((layoutKey & SDL_KEY_KEYPAD_BIT) != 0) {
slouken@2268
   283
            buffer[0] = '[';
slouken@2268
   284
            *bufferPtr++ = ']';
slouken@2268
   285
            *bufferPtr = '\0';
slouken@2268
   286
            keyname = buffer;
slouken@2268
   287
        } else {
slouken@2268
   288
            keyname = &buffer[1];
slouken@2268
   289
        }
slouken@1895
   290
    } else {
slouken@2268
   291
        /* SDLK_INDEX(layoutKey) is a physical key number */
slouken@2268
   292
        if (SDLK_INDEX(layoutKey) < SDL_arraysize(SDL_keynames)) {
slouken@2268
   293
            keyname = SDL_keynames[SDLK_INDEX(layoutKey)];
slouken@1895
   294
        }
slouken@1895
   295
    }
slouken@2268
   296
slouken@2268
   297
    if (keyname == NULL) {
slouken@2268
   298
        keyname = SDL_keynames[SDLK_INDEX(SDLK_UNKNOWN)];
slouken@2268
   299
    }
slouken@2268
   300
slouken@1895
   301
    return keyname;
slouken@1895
   302
}
slouken@1895
   303
slouken@1895
   304
void
slouken@2268
   305
SDL_SetKeyName(SDLKey physicalKey, const char *name)
slouken@2268
   306
{
slouken@2268
   307
    physicalKey = SDLK_INDEX(physicalKey);
slouken@2268
   308
    if (physicalKey < SDL_arraysize(SDL_keynames)) {
slouken@2268
   309
        SDL_keynames[physicalKey] = name;
slouken@2268
   310
    }
slouken@2268
   311
}
slouken@2268
   312
slouken@2268
   313
void
slouken@1895
   314
SDL_SetKeyboardFocus(int index, SDL_WindowID windowID)
slouken@1895
   315
{
slouken@1895
   316
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@1895
   317
    int i;
slouken@1895
   318
    SDL_bool focus;
slouken@1895
   319
slouken@1895
   320
    if (!keyboard || (keyboard->focus == windowID)) {
slouken@1895
   321
        return;
slouken@1895
   322
    }
slouken@1895
   323
slouken@1895
   324
    /* See if the current window has lost focus */
slouken@1895
   325
    if (keyboard->focus) {
slouken@1895
   326
        focus = SDL_FALSE;
slouken@1895
   327
        for (i = 0; i < SDL_num_keyboards; ++i) {
slouken@1895
   328
            SDL_Keyboard *check;
slouken@1895
   329
            if (i != index) {
slouken@1895
   330
                check = SDL_GetKeyboard(i);
slouken@1895
   331
                if (check && check->focus == keyboard->focus) {
slouken@1895
   332
                    focus = SDL_TRUE;
slouken@1895
   333
                    break;
slouken@1895
   334
                }
slouken@1895
   335
            }
slouken@1895
   336
        }
slouken@1895
   337
        if (!focus) {
slouken@1895
   338
            SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST,
slouken@1895
   339
                                0, 0);
slouken@1895
   340
        }
slouken@1895
   341
    }
slouken@1895
   342
slouken@1895
   343
    keyboard->focus = windowID;
slouken@1895
   344
slouken@1895
   345
    if (keyboard->focus) {
slouken@1895
   346
        focus = SDL_FALSE;
slouken@1895
   347
        for (i = 0; i < SDL_num_keyboards; ++i) {
slouken@1895
   348
            SDL_Keyboard *check;
slouken@1895
   349
            if (i != index) {
slouken@1895
   350
                check = SDL_GetKeyboard(i);
slouken@1895
   351
                if (check && check->focus == keyboard->focus) {
slouken@1895
   352
                    focus = SDL_TRUE;
slouken@1895
   353
                    break;
slouken@1895
   354
                }
slouken@1895
   355
            }
slouken@1895
   356
        }
slouken@1895
   357
        if (!focus) {
slouken@1895
   358
            SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED,
slouken@1895
   359
                                0, 0);
slouken@1895
   360
        }
slouken@1895
   361
    }
slouken@1895
   362
}
slouken@1895
   363
slouken@1895
   364
int
slouken@2268
   365
SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode,
slouken@2268
   366
                    SDLKey physicalKey)
slouken@1895
   367
{
slouken@1895
   368
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@2129
   369
    int posted;
slouken@1895
   370
    Uint16 modstate;
slouken@1895
   371
    Uint8 type;
slouken@1895
   372
slouken@2268
   373
    if (!keyboard || physicalKey == SDLK_NONE) {
slouken@1895
   374
        return 0;
slouken@1895
   375
    }
slouken@0
   376
#if 0
slouken@2268
   377
    printf("The '%s' key has been %s\n", SDL_GetKeyName(physicalKey),
slouken@1895
   378
           state == SDL_PRESSED ? "pressed" : "released");
slouken@0
   379
#endif
slouken@1895
   380
    if (state == SDL_PRESSED) {
slouken@1895
   381
        modstate = keyboard->modstate;
slouken@2268
   382
        switch (physicalKey) {
slouken@1895
   383
        case SDLK_UNKNOWN:
slouken@1895
   384
            break;
slouken@2268
   385
        case SDLK_KP_NUMLOCKCLEAR:
slouken@1895
   386
            keyboard->modstate ^= KMOD_NUM;
slouken@1895
   387
            break;
slouken@1895
   388
        case SDLK_CAPSLOCK:
slouken@1895
   389
            keyboard->modstate ^= KMOD_CAPS;
slouken@1895
   390
            break;
slouken@1895
   391
        case SDLK_LCTRL:
slouken@1895
   392
            keyboard->modstate |= KMOD_LCTRL;
slouken@1895
   393
            break;
slouken@1895
   394
        case SDLK_RCTRL:
slouken@1895
   395
            keyboard->modstate |= KMOD_RCTRL;
slouken@1895
   396
            break;
slouken@1895
   397
        case SDLK_LSHIFT:
slouken@1895
   398
            keyboard->modstate |= KMOD_LSHIFT;
slouken@1895
   399
            break;
slouken@1895
   400
        case SDLK_RSHIFT:
slouken@1895
   401
            keyboard->modstate |= KMOD_RSHIFT;
slouken@1895
   402
            break;
slouken@1895
   403
        case SDLK_LALT:
slouken@1895
   404
            keyboard->modstate |= KMOD_LALT;
slouken@1895
   405
            break;
slouken@1895
   406
        case SDLK_RALT:
slouken@1895
   407
            keyboard->modstate |= KMOD_RALT;
slouken@1895
   408
            break;
slouken@1895
   409
        case SDLK_LMETA:
slouken@1895
   410
            keyboard->modstate |= KMOD_LMETA;
slouken@1895
   411
            break;
slouken@1895
   412
        case SDLK_RMETA:
slouken@1895
   413
            keyboard->modstate |= KMOD_RMETA;
slouken@1895
   414
            break;
slouken@1895
   415
        case SDLK_MODE:
slouken@1895
   416
            keyboard->modstate |= KMOD_MODE;
slouken@1895
   417
            break;
slouken@1895
   418
        default:
slouken@1895
   419
            break;
slouken@1895
   420
        }
slouken@1895
   421
    } else {
slouken@2268
   422
        switch (physicalKey) {
slouken@1895
   423
        case SDLK_UNKNOWN:
slouken@1895
   424
            break;
slouken@2268
   425
        case SDLK_KP_NUMLOCKCLEAR:
slouken@1895
   426
        case SDLK_CAPSLOCK:
slouken@1895
   427
            break;
slouken@1895
   428
        case SDLK_LCTRL:
slouken@1895
   429
            keyboard->modstate &= ~KMOD_LCTRL;
slouken@1895
   430
            break;
slouken@1895
   431
        case SDLK_RCTRL:
slouken@1895
   432
            keyboard->modstate &= ~KMOD_RCTRL;
slouken@1895
   433
            break;
slouken@1895
   434
        case SDLK_LSHIFT:
slouken@1895
   435
            keyboard->modstate &= ~KMOD_LSHIFT;
slouken@1895
   436
            break;
slouken@1895
   437
        case SDLK_RSHIFT:
slouken@1895
   438
            keyboard->modstate &= ~KMOD_RSHIFT;
slouken@1895
   439
            break;
slouken@1895
   440
        case SDLK_LALT:
slouken@1895
   441
            keyboard->modstate &= ~KMOD_LALT;
slouken@1895
   442
            break;
slouken@1895
   443
        case SDLK_RALT:
slouken@1895
   444
            keyboard->modstate &= ~KMOD_RALT;
slouken@1895
   445
            break;
slouken@1895
   446
        case SDLK_LMETA:
slouken@1895
   447
            keyboard->modstate &= ~KMOD_LMETA;
slouken@1895
   448
            break;
slouken@1895
   449
        case SDLK_RMETA:
slouken@1895
   450
            keyboard->modstate &= ~KMOD_RMETA;
slouken@1895
   451
            break;
slouken@1895
   452
        case SDLK_MODE:
slouken@1895
   453
            keyboard->modstate &= ~KMOD_MODE;
slouken@1895
   454
            break;
slouken@1895
   455
        default:
slouken@1895
   456
            break;
slouken@1895
   457
        }
slouken@1895
   458
        modstate = keyboard->modstate;
slouken@1895
   459
    }
slouken@0
   460
slouken@1895
   461
    /* Figure out what type of event this is */
slouken@1895
   462
    switch (state) {
slouken@1895
   463
    case SDL_PRESSED:
slouken@1895
   464
        type = SDL_KEYDOWN;
slouken@1895
   465
        break;
slouken@1895
   466
    case SDL_RELEASED:
slouken@1895
   467
        type = SDL_KEYUP;
slouken@1895
   468
        break;
slouken@1895
   469
    default:
slouken@1895
   470
        /* Invalid state -- bail */
slouken@1895
   471
        return 0;
slouken@1895
   472
    }
slouken@0
   473
slouken@2268
   474
    if (physicalKey != SDLK_UNKNOWN) {
slouken@1895
   475
        /* Drop events that don't change state */
slouken@2268
   476
        if (keyboard->keystate[SDLK_INDEX(physicalKey)] == state) {
slouken@1895
   477
#if 0
slouken@1895
   478
            printf("Keyboard event didn't change state - dropped!\n");
slouken@1895
   479
#endif
slouken@1895
   480
            return 0;
slouken@1895
   481
        }
slouken@0
   482
slouken@1895
   483
        /* Update internal keyboard state */
slouken@2268
   484
        keyboard->keystate[SDLK_INDEX(physicalKey)] = state;
slouken@1895
   485
    }
slouken@0
   486
slouken@1895
   487
    /* Post the event, if desired */
slouken@1895
   488
    posted = 0;
slouken@1895
   489
    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
slouken@1895
   490
        SDL_Event event;
slouken@1895
   491
        event.key.type = type;
slouken@1895
   492
        event.key.which = (Uint8) index;
slouken@1895
   493
        event.key.state = state;
slouken@1895
   494
        event.key.keysym.scancode = scancode;
slouken@2268
   495
        event.key.keysym.sym = physicalKey;
slouken@1895
   496
        event.key.keysym.mod = modstate;
slouken@1895
   497
        event.key.keysym.unicode = 0;
slouken@1895
   498
        event.key.windowID = keyboard->focus;
slouken@1895
   499
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   500
    }
slouken@1895
   501
    return (posted);
slouken@1895
   502
}
slouken@1327
   503
slouken@1895
   504
int
slouken@1895
   505
SDL_SendKeyboardText(int index, const char *text)
slouken@1895
   506
{
slouken@1895
   507
    SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
slouken@1895
   508
    int posted;
slouken@0
   509
slouken@1895
   510
    if (!keyboard) {
slouken@1895
   511
        return 0;
slouken@1895
   512
    }
slouken@1895
   513
slouken@1895
   514
    /* Post the event, if desired */
slouken@1895
   515
    posted = 0;
slouken@1895
   516
    if (SDL_ProcessEvents[SDL_TEXTINPUT] == SDL_ENABLE) {
slouken@1895
   517
        SDL_Event event;
slouken@1895
   518
        event.text.type = SDL_TEXTINPUT;
slouken@1895
   519
        event.text.which = (Uint8) index;
slouken@1895
   520
        SDL_strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
slouken@1959
   521
        event.text.windowID = keyboard->focus;
slouken@1895
   522
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   523
    }
slouken@1895
   524
    return (posted);
slouken@0
   525
}
slouken@0
   526
slouken@1895
   527
/* vi: set ts=4 sw=4 expandtab: */