mirror of
https://github.com/Oibaf66/frodo-wii.git
synced 2025-02-17 04:46:20 +01:00
Handle real keyboard input for the virtual keyboard
This commit is contained in:
parent
2c359032c2
commit
224ec1dbe7
@ -23,6 +23,13 @@ typedef struct virtkey
|
|||||||
bool is_done;
|
bool is_done;
|
||||||
} virtkey_t;
|
} virtkey_t;
|
||||||
|
|
||||||
|
#define INVALID_VIRTKEY ((struct virtkey){NULL, -1, false, false})
|
||||||
|
|
||||||
|
static inline bool IS_INVALID_VIRTKEY(virtkey_t *k)
|
||||||
|
{
|
||||||
|
return k->name == NULL && k->kc == -1 &&
|
||||||
|
k->is_done == false && k->is_shift == false;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
C64 keyboard matrix:
|
C64 keyboard matrix:
|
||||||
|
|
||||||
@ -65,9 +72,9 @@ static virtkey_t keys[KEY_COLS * KEY_ROWS] = {
|
|||||||
|
|
||||||
static const char *shifted_names[KEY_COLS * KEY_ROWS] = {
|
static const char *shifted_names[KEY_COLS * KEY_ROWS] = {
|
||||||
NULL, "!", "\"", "#", "$", "%", "&", "'", "(", ")", NULL, NULL, NULL, NULL, "Clr",
|
NULL, "!", "\"", "#", "$", "%", "&", "'", "(", ")", NULL, NULL, NULL, NULL, "Clr",
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", NULL, NULL, NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "[", "]", NULL, NULL,
|
NULL, NULL, "a", "s", "d", "f", "g", "h", "j", "k", "l", "[", "]", NULL, NULL,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "<", ">", "?", "Up", "Lft",
|
NULL, NULL, NULL, "z", "x", "c", "v", "b", "n", "m", "<", ">", "?", "Up", "Lft",
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, "f2", "f4", "f6", "f8", "Ins", NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL, "f2", "f4", "f6", "f8", "Ins", NULL, NULL, NULL, NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,8 +87,10 @@ VirtualKeyboard::VirtualKeyboard(Font *font) : GuiView()
|
|||||||
|
|
||||||
this->is_active = false;
|
this->is_active = false;
|
||||||
this->buf_head = 0;
|
this->buf_head = 0;
|
||||||
|
this->buf_len = 255;
|
||||||
|
this->buf = (struct virtkey*)xmalloc(sizeof(struct virtkey) * this->buf_len);
|
||||||
|
memset(this->buf, 0, sizeof(struct virtkey) * this->buf_len);
|
||||||
|
|
||||||
memset(this->buf, 0, sizeof(this->buf));
|
|
||||||
this->flushListeners();
|
this->flushListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +214,36 @@ int VirtualKeyboard::charToKeycode(char c)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtkey_t VirtualKeyboard::eventToVirtkey(event_t ev)
|
||||||
|
{
|
||||||
|
char c = (char)ev;
|
||||||
|
|
||||||
|
for (int i = 0; i < KEY_COLS * KEY_ROWS; i++)
|
||||||
|
{
|
||||||
|
virtkey_t key = keys[i];
|
||||||
|
|
||||||
|
if (key.name != NULL)
|
||||||
|
{
|
||||||
|
if (strlen(key.name) == 1)
|
||||||
|
{
|
||||||
|
if (key.name[0] == c)
|
||||||
|
return key;
|
||||||
|
if (shifted_names[i] && strlen(shifted_names[i]) == 1 &&
|
||||||
|
shifted_names[i][0] == c)
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK, ugly special cases, but these are pretty important */
|
||||||
|
if ( (c == ' ' && strcmp(key.name, "space") == 0) ||
|
||||||
|
(c == '\n' && strcmp(key.name, "Ret") == 0) )
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return INVALID_VIRTKEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char VirtualKeyboard::keycodeToChar(int kc)
|
const char VirtualKeyboard::keycodeToChar(int kc)
|
||||||
{
|
{
|
||||||
const char *s = this->keycodeToString(kc);
|
const char *s = this->keycodeToString(kc);
|
||||||
@ -253,7 +292,7 @@ void VirtualKeyboard::unregisterListener(KeyboardListener *kl)
|
|||||||
void VirtualKeyboard::activate()
|
void VirtualKeyboard::activate()
|
||||||
{
|
{
|
||||||
this->is_active = true;
|
this->is_active = true;
|
||||||
memset(this->buf, 0, sizeof(this->buf));
|
memset(this->buf, 0, sizeof(struct virtkey) * this->buf_len);
|
||||||
this->buf_head = 0;
|
this->buf_head = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +300,7 @@ void VirtualKeyboard::activate()
|
|||||||
void VirtualKeyboard::runLogic()
|
void VirtualKeyboard::runLogic()
|
||||||
{
|
{
|
||||||
event_t ev;
|
event_t ev;
|
||||||
|
virtkey_t ev_key;
|
||||||
|
|
||||||
if (!this->is_active)
|
if (!this->is_active)
|
||||||
return;
|
return;
|
||||||
@ -269,6 +309,12 @@ void VirtualKeyboard::runLogic()
|
|||||||
if (ev == EVENT_NONE)
|
if (ev == EVENT_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Something was typed on the keyboard */
|
||||||
|
ev_key = this->eventToVirtkey(ev);
|
||||||
|
if ( !IS_INVALID_VIRTKEY(&ev_key) ) {
|
||||||
|
this->pushKey(&ev_key);
|
||||||
|
}
|
||||||
|
|
||||||
if (ev & KEY_UP)
|
if (ev & KEY_UP)
|
||||||
this->selectNext(0, -1);
|
this->selectNext(0, -1);
|
||||||
else if (ev & KEY_DOWN)
|
else if (ev & KEY_DOWN)
|
||||||
@ -288,46 +334,36 @@ void VirtualKeyboard::runLogic()
|
|||||||
|
|
||||||
if (key->is_shift == true)
|
if (key->is_shift == true)
|
||||||
this->toggleShift();
|
this->toggleShift();
|
||||||
else if (key->is_done)
|
else if (key->is_done) /* We're done! */
|
||||||
{
|
this->done();
|
||||||
int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners);
|
|
||||||
|
|
||||||
for (int i = 0; i < n_listeners; i++)
|
|
||||||
{
|
|
||||||
if (this->listeners[i])
|
|
||||||
this->listeners[i]->stringCallback(this->buf);
|
|
||||||
}
|
|
||||||
/* We're done! */
|
|
||||||
this->deactivate();
|
|
||||||
}
|
|
||||||
else if (strcmp(key->name, "Del") == 0)
|
else if (strcmp(key->name, "Del") == 0)
|
||||||
{
|
{
|
||||||
if (this->buf_head > 1)
|
if (this->buf_head > 1)
|
||||||
{
|
{
|
||||||
this->buf[this->buf_head - 1] = ' ';
|
this->buf[this->buf_head - 1] = (struct virtkey){NULL, -1, false, false};
|
||||||
this->buf_head -= 2;
|
this->buf_head -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
this->pushKey(key);
|
||||||
int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners);
|
}
|
||||||
char c;
|
}
|
||||||
|
|
||||||
/* Add to buf */
|
void VirtualKeyboard::pushKey(struct virtkey *vk)
|
||||||
c = this->keycodeToChar( this->shift_on ? key->kc | 0x80 : key->kc );
|
{
|
||||||
|
int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners);
|
||||||
|
|
||||||
this->buf[this->buf_head] = c;
|
/* Add to buf */
|
||||||
|
this->buf[this->buf_head] = *vk;
|
||||||
|
|
||||||
this->buf_head++;
|
this->buf_head++;
|
||||||
if (this->buf_head >= sizeof(this->buf) - 1)
|
if (this->buf_head >= this->buf_len - 1)
|
||||||
this->buf_head = 0; /* OK, not good, but well... */
|
this->buf_head = 0; /* OK, not good, but well... */
|
||||||
for (int i = 0; i < n_listeners; i++)
|
for (int i = 0; i < n_listeners; i++)
|
||||||
{
|
{
|
||||||
if (this->listeners[i])
|
if (this->listeners[i])
|
||||||
this->listeners[i]->keyCallback(this->shift_on,
|
this->listeners[i]->keyCallback(this->shift_on,
|
||||||
key->name);
|
vk->name);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,6 +379,23 @@ void VirtualKeyboard::deactivate()
|
|||||||
Gui::gui->popView();
|
Gui::gui->popView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboard::done()
|
||||||
|
{
|
||||||
|
int n_listeners = sizeof(this->listeners) / sizeof(*this->listeners);
|
||||||
|
char *buf = (char *)xmalloc(this->buf_head + 1);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < this->buf_head; i++)
|
||||||
|
buf[i] = this->keycodeToChar(this->buf[i].kc);
|
||||||
|
|
||||||
|
for (int i = 0; i < n_listeners; i++)
|
||||||
|
{
|
||||||
|
if (this->listeners[i])
|
||||||
|
this->listeners[i]->stringCallback(buf);
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
this->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualKeyboard::draw(SDL_Surface *where)
|
void VirtualKeyboard::draw(SDL_Surface *where)
|
||||||
{
|
{
|
||||||
this->draw(where, 20, 240, 600, 240);
|
this->draw(where, 20, 240, 600, 240);
|
||||||
@ -353,6 +406,36 @@ void VirtualKeyboard::updateTheme()
|
|||||||
this->setFont(Gui::gui->small_font);
|
this->setFont(Gui::gui->small_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VirtualKeyboard::pushEvent(SDL_Event *ev)
|
||||||
|
{
|
||||||
|
switch(ev->type)
|
||||||
|
{
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
switch (ev->key.keysym.sym)
|
||||||
|
{
|
||||||
|
case SDLK_UP:
|
||||||
|
case SDLK_DOWN:
|
||||||
|
case SDLK_LEFT:
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
case SDLK_PAGEDOWN:
|
||||||
|
case SDLK_PAGEUP:
|
||||||
|
case SDLK_RETURN:
|
||||||
|
case SDLK_HOME:
|
||||||
|
case SDLK_ESCAPE:
|
||||||
|
/* Handle via the standard widget implementation (except for space) */
|
||||||
|
Widget::pushEvent(ev);
|
||||||
|
return;
|
||||||
|
case SDLK_SPACE ... SDLK_z:
|
||||||
|
Widget::pushEvent((event_t)(ev->key.keysym.sym));
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The singleton */
|
/* The singleton */
|
||||||
VirtualKeyboard *VirtualKeyboard::kbd;
|
VirtualKeyboard *VirtualKeyboard::kbd;
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
const char keycodeToChar(int kc);
|
const char keycodeToChar(int kc);
|
||||||
int charToKeycode(char c);
|
int charToKeycode(char c);
|
||||||
int stringToKeycode(const char *str);
|
int stringToKeycode(const char *str);
|
||||||
|
struct virtkey eventToVirtkey(event_t ev);
|
||||||
|
|
||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
@ -71,14 +72,21 @@ public:
|
|||||||
|
|
||||||
void draw(SDL_Surface *where, int x, int y, int w, int h);
|
void draw(SDL_Surface *where, int x, int y, int w, int h);
|
||||||
|
|
||||||
|
void pushEvent(SDL_Event *ev);
|
||||||
|
|
||||||
/* Singleton object */
|
/* Singleton object */
|
||||||
static VirtualKeyboard *kbd;
|
static VirtualKeyboard *kbd;
|
||||||
private:
|
private:
|
||||||
KeyboardListener *listeners[8];
|
KeyboardListener *listeners[8];
|
||||||
|
|
||||||
void selectNext(int dx, int dy);
|
void selectNext(int dx, int dy);
|
||||||
|
|
||||||
void toggleShift();
|
void toggleShift();
|
||||||
|
|
||||||
|
void pushKey(struct virtkey *vk);
|
||||||
|
|
||||||
|
void done();
|
||||||
|
|
||||||
void flushListeners();
|
void flushListeners();
|
||||||
|
|
||||||
Font *font;
|
Font *font;
|
||||||
@ -87,8 +95,9 @@ private:
|
|||||||
bool shift_on;
|
bool shift_on;
|
||||||
|
|
||||||
bool is_active;
|
bool is_active;
|
||||||
char buf[255];
|
struct virtkey *buf;
|
||||||
unsigned buf_head;
|
unsigned buf_head;
|
||||||
|
size_t buf_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __VIRTUAL_KEYBORD_HH__ */
|
#endif /* __VIRTUAL_KEYBORD_HH__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user