src/events/SDL_keyboard.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 19 Aug 2007 14:52:52 +0000
changeset 2268 4baee598306d
parent 2229 22342048bcb8
child 2295 dbc6d1893869
permissions -rw-r--r--
Date: Thu, 05 Jul 2007 14:02:33 -0700
From: Sam Lantinga
Subject: SDL 1.3 keyboard plan

After lots of discussion with Christian, this is what we came up with:

> So, to sum up...
> SDLK_* become the physical keys, starting at > (1<<21)
> We create a macro SDLK_INDEX(X)
> We have two functions SDL_GetLayoutKey(SDLKey) and SDL_GetKeyName()
> SDL_GetLayoutKey maps to UCS4 for printable characters, and SDLK* for
non-printable characters
> and does so based on the OS's current keyboard layout
> SDL_GetKeyName() handles both SDLK_* and UCS4, converting UCS4 to UTF-8 and
converting SDLK_* into our names, which are UTF-8 for printable characters.
> WASD folks use SDLK_*, and 'I' folks use SDL_GetLayoutKey(SDLK_*)

Here is the patch he came up with, and his e-mail about it:

Date: Fri, 17 Aug 2007 19:50:28 +0200
From: Christian Walther
Subject: Re: SDL 1.3 keyboard plan

> Sounds great, go ahead and send me a patch.

Here goes! Thanks for having a look. Don't hesitate to comment if
anything does not conform to your ideas.

One caveat: Committing this now may break compilability of some video
drivers - specifically, if they use any of the SDLK_* codes that were
obsoleted and moved into SDL_compat.h. I only tried Cocoa (which did
break, but is already fixed) and X11 (which didn't, but then its key
handling is #iffed out). If that's a problem, it may need to go into
a branch.

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