From 7bc28b3a60253500a7a672e079421c5bd9ad8f8a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 11 Jun 2006 05:27:10 +0000 Subject: [PATCH] Finishing up keyboard code revamp, at least for now... --- include/SDL_keyboard.h | 5 +- src/events/SDL_events_c.h | 14 +-- src/events/SDL_keyboard.c | 187 ++++++++++++++++++++++++------------ src/events/SDL_keyboard_c.h | 18 +++- src/events/SDL_mouse.c | 3 +- 5 files changed, 142 insertions(+), 85 deletions(-) diff --git a/include/SDL_keyboard.h b/include/SDL_keyboard.h index a6c7e31b6..09335337a 100644 --- a/include/SDL_keyboard.h +++ b/include/SDL_keyboard.h @@ -49,8 +49,9 @@ extern "C" { typedef struct SDL_keysym { Uint8 scancode; /**< keyboard specific scancode */ - SDLKey sym; /**< SDL virtual keysym */ - SDLMod mod; /**< current key modifiers */ + Uint8 padding[3]; /**< alignment padding */ + Uint16 sym; /**< SDL virtual keysym */ + Uint16 mod; /**< current key modifiers */ } SDL_keysym; /* Function prototypes */ diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 0dc3fef69..37fd34eee 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -24,6 +24,7 @@ /* Useful functions and variables from SDL_events.c */ #include "SDL_events.h" #include "SDL_mouse_c.h" +#include "SDL_keyboard_c.h" /* Start and stop the event processing loop */ extern int SDL_StartEventLoop(Uint32 flags); @@ -34,10 +35,6 @@ extern void SDL_Lock_EventThread(void); extern void SDL_Unlock_EventThread(void); extern Uint32 SDL_EventThreadID(void); -extern int SDL_KeyboardInit(void); -extern int SDL_SendKeyboard(Uint8 state, SDL_keysym * key); -extern void SDL_KeyboardQuit(void); - extern int SDL_QuitInit(void); extern int SDL_SendQuit(void); extern void SDL_QuitQuit(void); @@ -53,13 +50,4 @@ extern SDL_EventFilter SDL_EventOK; /* The array of event processing states */ extern Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; -/* Used by the event loop to queue pending keyboard repeat events */ -extern void SDL_CheckKeyRepeat(void); - -/* Used by the OS keyboard code to detect whether or not to do UNICODE */ -#ifndef DEFAULT_UNICODE_TRANSLATION -#define DEFAULT_UNICODE_TRANSLATION 0 /* Default off because of overhead */ -#endif -extern int SDL_TranslateUNICODE; - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 210abf10e..993182747 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -30,10 +30,10 @@ /* Global keyboard information */ +int SDL_TranslateUNICODE = 0; static int SDL_num_keyboards; static int SDL_current_keyboard; static SDL_Keyboard **SDL_keyboards; -int SDL_TranslateUNICODE = 0; static const char *SDL_keynames[SDLK_LAST]; /* Array of keycode names */ @@ -46,9 +46,6 @@ SDL_KeyboardInit(void) /* Set default mode of UNICODE translation */ SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION); - /* Set default keyboard repeat setting */ - SDL_EnableKeyRepeat(0, 0); - /* Initialize the tables */ for (i = 0; i < SDL_arraysize(SDL_keynames); ++i) { switch (i) { @@ -138,9 +135,6 @@ SDL_KeyboardInit(void) case SDLK_LEFT: SDL_keynames[i] = "left"; break; - case SDLK_DOWN: - SDL_keynames[i] = "down"; - break; case SDLK_INSERT: SDL_keynames[i] = "insert"; break; @@ -347,7 +341,7 @@ SDL_ResetKeyboard(int index) { SDL_Keyboard *keyboard = SDL_GetKeyboard(index); SDL_keysym keysym; - SDLKey key; + Uint16 key; if (!keyboard) { return; @@ -357,10 +351,10 @@ SDL_ResetKeyboard(int index) for (key = SDLK_FIRST; key < SDLK_LAST; ++key) { if (keyboard->keystate[key] == SDL_PRESSED) { keysym.sym = key; - SDL_SendKeyboardKey(index, SDL_RELEASED, &keysym); + SDL_SendKeyboardKey(index, 0, SDL_RELEASED, &keysym); } } - keyboard->keyrepeat.timestamp = 0; + keyboard->repeat.timestamp = 0; } void @@ -410,15 +404,22 @@ SDL_EnableUNICODE(int enable) Uint8 * SDL_GetKeyState(int *numkeys) { - if (numkeys != (int *) 0) + SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard); + + if (numkeys != (int *) 0) { *numkeys = SDLK_LAST; - return (SDL_KeyState); + } + + if (!keyboard) { + return NULL; + } + return keyboard->keystate; } SDLMod SDL_GetModState(void) { - SDL_Keyboard *keyboard = SDL_GetKeyboard(index); + SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard); if (!keyboard) { return KMOD_NONE; @@ -429,7 +430,7 @@ SDL_GetModState(void) void SDL_SetModState(SDLMod modstate) { - SDL_Keyboard *keyboard = SDL_GetKeyboard(index); + SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard); if (!keyboard) { return; @@ -442,11 +443,21 @@ SDL_GetKeyName(SDLKey key) { const char *keyname; - keyname = keynames[key]; + if (key < SDL_tablesize(SDL_keynames)) { + keyname = SDL_keynames[key]; + } else { + keyname = NULL; + } if (keyname == NULL) { if (key < 256) { static char temp[4]; - FIXME:Convert to UTF - 8 keyname = temp; + char *cvt; + temp[0] = (char) key; + temp[1] = '\0'; + cvt = SDL_iconv_string("UTF-8", "LATIN1", temp, 1); + SDL_strlcpy(temp, cvt, SDL_arraysize(temp)); + SDL_free(cvt); + keyname = temp; } else { keyname = "unknown key"; } @@ -454,27 +465,33 @@ SDL_GetKeyName(SDLKey key) return keyname; } -/* These are global for SDL_eventloop.c */ int -SDL_SendKeyboardKey(int index, Uint8 state, const SDL_keysym * keysym) +SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, + SDL_keysym * keysym) { - SDL_Event event; + SDL_Keyboard *keyboard = SDL_GetKeyboard(index); int posted, repeatable; Uint16 modstate; + Uint8 type; - SDL_memset(&event, 0, sizeof(event)); + if (!keyboard) { + return 0; + } + if (windowID) { + keyboard->focus = windowID; + } #if 0 printf("The '%s' key has been %s\n", SDL_GetKeyName(keysym->sym), state == SDL_PRESSED ? "pressed" : "released"); #endif /* Set up the keysym */ - modstate = (Uint16) SDL_ModState; + modstate = keyboard->modstate; repeatable = 0; if (state == SDL_PRESSED) { - keysym->mod = (SDLMod) modstate; + keysym->mod = modstate; switch (keysym->sym) { case SDLK_UNKNOWN: break; @@ -482,13 +499,13 @@ SDL_SendKeyboardKey(int index, Uint8 state, const SDL_keysym * keysym) modstate ^= KMOD_NUM; if (!(modstate & KMOD_NUM)) state = SDL_RELEASED; - keysym->mod = (SDLMod) modstate; + keysym->mod = modstate; break; case SDLK_CAPSLOCK: modstate ^= KMOD_CAPS; if (!(modstate & KMOD_CAPS)) state = SDL_RELEASED; - keysym->mod = (SDLMod) modstate; + keysym->mod = modstate; break; case SDLK_LCTRL: modstate |= KMOD_LCTRL; @@ -559,55 +576,63 @@ SDL_SendKeyboardKey(int index, Uint8 state, const SDL_keysym * keysym) default: break; } - keysym->mod = (SDLMod) modstate; + keysym->mod = modstate; } /* Figure out what type of event this is */ switch (state) { case SDL_PRESSED: - event.type = SDL_KEYDOWN; + type = SDL_KEYDOWN; break; case SDL_RELEASED: - event.type = SDL_KEYUP; + type = SDL_KEYUP; /* * jk 991215 - Added */ - if (SDL_KeyRepeat.timestamp && - SDL_KeyRepeat.evt.key.keysym.sym == keysym->sym) { - SDL_KeyRepeat.timestamp = 0; + if (keyboard->repeat.timestamp && + keyboard->repeat.evt.key.keysym.sym == keysym->sym) { + keyboard->repeat.timestamp = 0; } break; default: /* Invalid state -- bail */ - return (0); + return 0; } if (keysym->sym != SDLK_UNKNOWN) { /* Drop events that don't change state */ - if (SDL_KeyState[keysym->sym] == state) { + if (keyboard->keystate[keysym->sym] == state) { #if 0 printf("Keyboard event didn't change state - dropped!\n"); #endif - return (0); + return 0; } /* Update internal keyboard state */ - SDL_ModState = (SDLMod) modstate; - SDL_KeyState[keysym->sym] = state; + keyboard->modstate = modstate; + keyboard->keystate[keysym->sym] = state; } /* Post the event, if desired */ posted = 0; - if (SDL_ProcessEvents[event.type] == SDL_ENABLE) { + if (SDL_ProcessEvents[type] == SDL_ENABLE) { + SDL_Event event; + event.key.type = type; + event.key.which = (Uint8) index; event.key.state = state; event.key.keysym = *keysym; + event.key.windowID = keyboard->focus; /* * jk 991215 - Added */ - if (repeatable && (SDL_KeyRepeat.delay != 0)) { - SDL_KeyRepeat.evt = event; - SDL_KeyRepeat.firsttime = 1; - SDL_KeyRepeat.timestamp = SDL_GetTicks(); + if (repeatable && (keyboard->repeat.delay != 0)) { + Uint32 timestamp = SDL_GetTicks(); + if (!timestamp) { + timestamp = 1; + } + keyboard->repeat.evt = event; + keyboard->repeat.firsttime = 1; + keyboard->repeat.timestamp = 1; } if ((SDL_EventOK == NULL) || SDL_EventOK(&event)) { posted = 1; @@ -623,22 +648,32 @@ SDL_SendKeyboardKey(int index, Uint8 state, const SDL_keysym * keysym) void SDL_CheckKeyRepeat(void) { - if (SDL_KeyRepeat.timestamp) { - Uint32 now, interval; - - now = SDL_GetTicks(); - interval = (now - SDL_KeyRepeat.timestamp); - if (SDL_KeyRepeat.firsttime) { - if (interval > (Uint32) SDL_KeyRepeat.delay) { - SDL_KeyRepeat.timestamp = now; - SDL_KeyRepeat.firsttime = 0; - } - } else { - if (interval > (Uint32) SDL_KeyRepeat.interval) { - SDL_KeyRepeat.timestamp = now; - if ((SDL_EventOK == NULL) - || SDL_EventOK(&SDL_KeyRepeat.evt)) { - SDL_PushEvent(&SDL_KeyRepeat.evt); + int i; + + for (i = 0; i < SDL_num_keyboards; ++i) { + SDL_Keyboard *keyboard = SDL_keyboards[i]; + + if (!keyboard) { + continue; + } + + if (keyboard->repeat.timestamp) { + Uint32 now, interval; + + now = SDL_GetTicks(); + interval = (now - keyboard->repeat.timestamp); + if (keyboard->repeat.firsttime) { + if (interval > (Uint32) keyboard->repeat.delay) { + keyboard->repeat.timestamp = now; + keyboard->repeat.firsttime = 0; + } + } else { + if (interval > (Uint32) keyboard->repeat.interval) { + keyboard->repeat.timestamp = now; + if ((SDL_EventOK == NULL) + || SDL_EventOK(&keyboard->repeat.evt)) { + SDL_PushEvent(&keyboard->repeat.evt); + } } } } @@ -648,22 +683,46 @@ SDL_CheckKeyRepeat(void) int SDL_EnableKeyRepeat(int delay, int interval) { + SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard); + + if (!keyboard) { + SDL_SetError("No keyboard is currently selected"); + return -1; + } + if ((delay < 0) || (interval < 0)) { SDL_SetError("keyboard repeat value less than zero"); - return (-1); + return -1; } - SDL_KeyRepeat.firsttime = 0; - SDL_KeyRepeat.delay = delay; - SDL_KeyRepeat.interval = interval; - SDL_KeyRepeat.timestamp = 0; - return (0); + + keyboard->repeat.firsttime = 0; + keyboard->repeat.delay = delay; + keyboard->repeat.interval = interval; + keyboard->repeat.timestamp = 0; + + return 0; } void SDL_GetKeyRepeat(int *delay, int *interval) { - *delay = SDL_KeyRepeat.delay; - *interval = SDL_KeyRepeat.interval; + SDL_Keyboard *keyboard = SDL_GetKeyboard(SDL_current_keyboard); + + if (!keyboard) { + if (delay) { + *delay = 0; + } + if (interval) { + *interval = 0; + } + return; + } + if (delay) { + *delay = keyboard->repeat.delay; + } + if (interval) { + *interval = keyboard->repeat.interval; + } } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index 02436fd32..af4a20bcb 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -31,7 +31,9 @@ struct SDL_Keyboard /* Free the keyboard when it's time */ void (*FreeKeyboard) (SDL_Keyboard * keyboard); - SDLMod modstate; + /* Data common to all keyboards */ + SDL_WindowID focus; + Uint16 modstate; Uint8 keystate[SDLK_LAST]; struct @@ -42,11 +44,16 @@ struct SDL_Keyboard Uint32 timestamp; /* the time the first keydown event occurred */ SDL_Event evt; /* the event we are supposed to repeat */ - } keyrepeat; + } repeat; void *driverdata; }; +/* Used by the OS keyboard code to detect whether or not to do UNICODE */ +#ifndef DEFAULT_UNICODE_TRANSLATION +#define DEFAULT_UNICODE_TRANSLATION 0 /* Default off because of overhead */ +#endif +extern int SDL_TranslateUNICODE; /* Initialize the keyboard subsystem */ extern int SDL_KeyboardInit(void); @@ -66,8 +73,11 @@ extern void SDL_DelKeyboard(int index); extern void SDL_ResetKeyboard(int index); /* Send a keyboard event for a keyboard at an index */ -extern int SDL_SendKeyboardKey(int index, Uint8 state, - const SDL_keysym * keysym); +extern int SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, + SDL_keysym * keysym); + +/* Used by the event loop to queue pending keyboard repeat events */ +extern void SDL_CheckKeyRepeat(void); /* Shutdown the keyboard subsystem */ extern void SDL_KeyboardQuit(void); diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 5f426496e..9e3dee9d4 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -25,7 +25,6 @@ #include "SDL_events.h" #include "SDL_events_c.h" -#include "SDL_mouse_c.h" #include "default_cursor.h" @@ -333,7 +332,7 @@ SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state, event.button.button = button; event.button.x = mouse->x; event.button.y = mouse->y; - event.button.windowID = windowID; + event.button.windowID = mouse->focus; if ((SDL_EventOK == NULL) || (*SDL_EventOK) (&event)) { posted = 1; SDL_PushEvent(&event);