|
@@ -55,6 +55,8 @@ struct SDL_Keyboard
|
|
|
};
|
|
|
|
|
|
static SDL_Keyboard SDL_keyboard;
|
|
|
+static int SDL_keyboard_count;
|
|
|
+static SDL_KeyboardID *SDL_keyboards;
|
|
|
|
|
|
static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
|
|
/* 0 */ SDLK_UNKNOWN,
|
|
@@ -678,6 +680,109 @@ int SDL_InitKeyboard(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys)
|
|
|
+{
|
|
|
+ const int REAL_KEYBOARD_KEY_COUNT = 50;
|
|
|
+ if (num_keys > 0 && num_keys < REAL_KEYBOARD_KEY_COUNT) {
|
|
|
+ return SDL_FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Eventually we'll have a blacklist of devices that enumerate as keyboards but aren't really */
|
|
|
+ return SDL_TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_PrivateKeyboardAdded(SDL_KeyboardID keyboardID)
|
|
|
+{
|
|
|
+ int keyboard_index = -1;
|
|
|
+
|
|
|
+ SDL_assert(keyboardID != 0);
|
|
|
+
|
|
|
+ for (int i = 0; i < SDL_keyboard_count; ++i) {
|
|
|
+ if (keyboardID == SDL_keyboards[i]) {
|
|
|
+ keyboard_index = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (keyboard_index >= 0) {
|
|
|
+ /* We already know about this keyboard */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_KeyboardID *keyboards = (SDL_KeyboardID *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards));
|
|
|
+ if (!keyboards) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ keyboards[SDL_keyboard_count] = keyboardID;
|
|
|
+ SDL_keyboards = keyboards;
|
|
|
+ ++SDL_keyboard_count;
|
|
|
+
|
|
|
+ SDL_Event event;
|
|
|
+ SDL_zero(event);
|
|
|
+ event.type = SDL_EVENT_KEYBOARD_ADDED;
|
|
|
+ event.kdevice.which = keyboardID;
|
|
|
+ SDL_PushEvent(&event);
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_PrivateKeyboardRemoved(SDL_KeyboardID keyboardID)
|
|
|
+{
|
|
|
+ int keyboard_index = -1;
|
|
|
+
|
|
|
+ SDL_assert(keyboardID != 0);
|
|
|
+
|
|
|
+ for (int i = 0; i < SDL_keyboard_count; ++i) {
|
|
|
+ if (keyboardID == SDL_keyboards[i]) {
|
|
|
+ keyboard_index = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (keyboard_index < 0) {
|
|
|
+ /* We don't know about this keyboard */
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (keyboard_index != SDL_keyboard_count - 1) {
|
|
|
+ SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index]));
|
|
|
+ }
|
|
|
+ --SDL_keyboard_count;
|
|
|
+
|
|
|
+ SDL_Event event;
|
|
|
+ SDL_zero(event);
|
|
|
+ event.type = SDL_EVENT_KEYBOARD_REMOVED;
|
|
|
+ event.kdevice.which = keyboardID;
|
|
|
+ SDL_PushEvent(&event);
|
|
|
+}
|
|
|
+
|
|
|
+SDL_bool SDL_HasKeyboard(void)
|
|
|
+{
|
|
|
+ return (SDL_keyboard_count > 0);
|
|
|
+}
|
|
|
+
|
|
|
+SDL_KeyboardID *SDL_GetKeyboards(int *count)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ SDL_KeyboardID *keyboards;
|
|
|
+
|
|
|
+ keyboards = (SDL_JoystickID *)SDL_malloc((SDL_keyboard_count + 1) * sizeof(*keyboards));
|
|
|
+ if (keyboards) {
|
|
|
+ if (count) {
|
|
|
+ *count = SDL_keyboard_count;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < SDL_keyboard_count; ++i) {
|
|
|
+ keyboards[i] = SDL_keyboards[i];
|
|
|
+ }
|
|
|
+ keyboards[i] = 0;
|
|
|
+ } else {
|
|
|
+ if (count) {
|
|
|
+ *count = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return keyboards;
|
|
|
+}
|
|
|
+
|
|
|
void SDL_ResetKeyboard(void)
|
|
|
{
|
|
|
SDL_Keyboard *keyboard = &SDL_keyboard;
|
|
@@ -688,7 +793,7 @@ void SDL_ResetKeyboard(void)
|
|
|
#endif
|
|
|
for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) {
|
|
|
if (keyboard->keystate[scancode] == SDL_PRESSED) {
|
|
|
- SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
|
|
|
+ SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scancode);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -822,7 +927,7 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
|
|
+static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
|
|
{
|
|
|
SDL_Keyboard *keyboard = &SDL_keyboard;
|
|
|
int posted;
|
|
@@ -831,6 +936,13 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 sta
|
|
|
Uint8 repeat = SDL_FALSE;
|
|
|
const Uint8 source = flags & KEYBOARD_SOURCE_MASK;
|
|
|
|
|
|
+ if (keyboardID == 0) {
|
|
|
+ if (source == KEYBOARD_HARDWARE && SDL_keyboard_count > 0) {
|
|
|
+ /* Assume it's from the first keyboard */
|
|
|
+ keyboardID = SDL_keyboards[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
|
|
|
return 0;
|
|
|
}
|
|
@@ -949,6 +1061,7 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 sta
|
|
|
event.key.keysym.sym = keycode;
|
|
|
event.key.keysym.mod = keyboard->modstate;
|
|
|
event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
|
|
+ event.key.which = keyboardID;
|
|
|
posted = (SDL_PushEvent(&event) > 0);
|
|
|
}
|
|
|
|
|
@@ -982,43 +1095,43 @@ int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
|
|
|
|
|
|
if (mod & SDL_KMOD_SHIFT) {
|
|
|
/* If the character uses shift, press shift down */
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
|
|
}
|
|
|
|
|
|
/* Send a keydown and keyup for the character */
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN);
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_PRESSED, code, SDLK_UNKNOWN);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_RELEASED, code, SDLK_UNKNOWN);
|
|
|
|
|
|
if (mod & SDL_KMOD_SHIFT) {
|
|
|
/* If the character uses shift, release shift */
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, state, scancode, SDLK_UNKNOWN);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, state, scancode, SDLK_UNKNOWN);
|
|
|
}
|
|
|
|
|
|
-int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
|
|
+int SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, state, scancode, SDLK_UNKNOWN);
|
|
|
}
|
|
|
|
|
|
-int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
|
|
+int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, keycode);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, state, scancode, keycode);
|
|
|
}
|
|
|
|
|
|
int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, 0, SDL_PRESSED, scancode, SDLK_UNKNOWN);
|
|
|
}
|
|
|
|
|
|
-int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
|
|
+int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, state, scancode, SDLK_UNKNOWN);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, state, scancode, SDLK_UNKNOWN);
|
|
|
}
|
|
|
|
|
|
void SDL_ReleaseAutoReleaseKeys(void)
|
|
@@ -1029,7 +1142,7 @@ void SDL_ReleaseAutoReleaseKeys(void)
|
|
|
if (keyboard->autorelease_pending) {
|
|
|
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
|
|
|
if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
|
|
|
- SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode, SDLK_UNKNOWN);
|
|
|
+ SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, 0, SDL_RELEASED, scancode, SDLK_UNKNOWN);
|
|
|
}
|
|
|
}
|
|
|
keyboard->autorelease_pending = SDL_FALSE;
|
|
@@ -1117,6 +1230,9 @@ int SDL_SendEditingText(const char *text, int start, int length)
|
|
|
|
|
|
void SDL_QuitKeyboard(void)
|
|
|
{
|
|
|
+ SDL_keyboard_count = 0;
|
|
|
+ SDL_free(SDL_keyboards);
|
|
|
+ SDL_keyboards = NULL;
|
|
|
}
|
|
|
|
|
|
const Uint8 *SDL_GetKeyboardState(int *numkeys)
|