Initial support for hotplugging mice and keyboards
This commit is contained in:
parent
c33e4c998d
commit
2fe1a6a279
44 changed files with 961 additions and 321 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue