From fce04ebed510a97e17f019a35c327dce78b6d916 Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Wed, 7 Jun 2006 15:31:51 +0000 Subject: [PATCH] more work on keyboard support --- data/keymap.xml | 4 +++ keyids.py | 1 + lib/actions/action.cpp | 8 ++--- lib/driver/rcconsole.cpp | 20 +++++------ lib/driver/rcinput.cpp | 51 +++++++++++++++++++++++++- lib/driver/rcinput.h | 1 + lib/gui/einput.cpp | 81 ++++++++++++++++++++++++++---------------- lib/gui/einput.h | 13 +++++-- lib/python/Components/Input.py | 13 +++++-- lib/python/Screens/InputBox.py | 16 +++++++-- lib/python/enigma_python.i | 2 ++ main/enigma.cpp | 21 +++++++++-- 12 files changed, 173 insertions(+), 58 deletions(-) diff --git a/data/keymap.xml b/data/keymap.xml index f98a42c..9752966 100644 --- a/data/keymap.xml +++ b/data/keymap.xml @@ -97,6 +97,10 @@ + + + + diff --git a/keyids.py b/keyids.py index 58159ee..e85cb19 100644 --- a/keyids.py +++ b/keyids.py @@ -293,6 +293,7 @@ KEYIDS = { "KEY_DEL_EOS": 449, "KEY_INS_LINE": 450, "KEY_DEL_LINE": 451, +"KEY_ASCII": 510, "KEY_MAX": 511, "BTN_0": 256, "BTN_1": 257, diff --git a/lib/actions/action.cpp b/lib/actions/action.cpp index 5468484..ec169a5 100644 --- a/lib/actions/action.cpp +++ b/lib/actions/action.cpp @@ -128,9 +128,9 @@ struct call_entry { PyObject *m_fnc, *m_arg; eWidget *m_widget; - void *m_widget_arg; + void *m_widget_arg, *m_widget_arg2; call_entry(PyObject *fnc, PyObject *arg): m_fnc(fnc), m_arg(arg), m_widget(0), m_widget_arg(0) { } - call_entry(eWidget *widget, void *arg): m_fnc(0), m_arg(0), m_widget(widget), m_widget_arg(arg) { } + call_entry(eWidget *widget, void *arg, void *arg2): m_fnc(0), m_arg(0), m_widget(widget), m_widget_arg(arg), m_widget_arg2(arg2) { } }; void eActionMap::keyPressed(int device, int key, int flags) @@ -158,7 +158,7 @@ void eActionMap::keyPressed(int device, int key, int flags) // (k->second.m_device == m_device) && (k->second.m_key == key) && (k->second.m_flags & (1<second.m_widget, (void*)k->second.m_action)); + call_list.push_back(call_entry(i->second.m_widget, (void*)i->second.m_id, (void*)k->second.m_action)); } } else { @@ -214,7 +214,7 @@ void eActionMap::keyPressed(int device, int key, int flags) } else if (i->m_widget) { if (!res) - res = i->m_widget->event(eWidget::evtAction, 0, (void*)i->m_widget_arg); + res = i->m_widget->event(eWidget::evtAction, (void*)i->m_widget_arg, (void*)i->m_widget_arg2 ); } } } diff --git a/lib/driver/rcconsole.cpp b/lib/driver/rcconsole.cpp index eaeeb58..0c70244 100644 --- a/lib/driver/rcconsole.cpp +++ b/lib/driver/rcconsole.cpp @@ -41,32 +41,30 @@ void eRCConsoleDriver::keyPressed(int) char data[16]; char *d = data; int num = read(handle, data, 16); - int code; + int code=-1; int km = input->getKeyboardMode(); while (num--) { +// eDebug("console code %02x\n", *d++); if (km == eRCInput::kmAll) code = *d++; else { if (*d == 27) // escape code { - /* skip all this stuff */ - return; - -/* while (num) + while (num) { num--; if (*++d != '[') break; } - code = -1; */ + code = -1; } else code = *d; ++d; - + if (code < 32) /* control characters */ code = -1; if (code == 0x7F) /* delete */ @@ -76,15 +74,15 @@ void eRCConsoleDriver::keyPressed(int) if (code != -1) for (std::list::iterator i(listeners.begin()); i!=listeners.end(); ++i) { - eDebug("ascii %08x", code); - (*i)->handleCode(code | 0x8000); +// eDebug("ascii %08x", code); + (*i)->handleCode(/*0x8000|*/code); } } } void eRCConsole::handleCode(int code) { - input->keyPressed(eRCKey(this, code, 0)); + input->keyPressed(eRCKey(this, code, eRCKey::flagAscii)); } eRCConsole::eRCConsole(eRCDriver *driver) @@ -112,7 +110,7 @@ class eRCConsoleInit eRCConsoleDriver driver; eRCConsole device; public: - eRCConsoleInit(): driver("/dev/stdin"), device(&driver) + eRCConsoleInit(): driver("/dev/vc/0"), device(&driver) { } }; diff --git a/lib/driver/rcinput.cpp b/lib/driver/rcinput.cpp index a5b1c71..256d07e 100644 --- a/lib/driver/rcinput.cpp +++ b/lib/driver/rcinput.cpp @@ -16,7 +16,43 @@ void eRCDeviceInputDev::handleCode(int rccode) struct input_event *ev = (struct input_event *)rccode; if (ev->type!=EV_KEY) return; + // eDebug("%x %x %x", ev->value, ev->code, ev->type); + + if (ev->type!=EV_KEY) + return; + + int km = iskeyboard ? input->getKeyboardMode() : eRCInput::kmNone; + +// eDebug("keyboard mode %d", km); + + if (km == eRCInput::kmAll) + return; + + if (km == eRCInput::kmAscii) + { +// eDebug("filtering.. %d", ev->code); + bool filtered = ( ev->code > 0 && ev->code < 61 ); + switch (ev->code) + { + case KEY_RESERVED: + case KEY_ESC: + case KEY_TAB: + case KEY_BACKSPACE: + case KEY_ENTER: + case KEY_LEFTCTRL: + case KEY_RIGHTSHIFT: + case KEY_LEFTALT: + case KEY_CAPSLOCK: + filtered=false; + default: + break; + } + if (filtered) + return; +// eDebug("passed!"); + } + switch (ev->value) { case 0: @@ -31,8 +67,21 @@ void eRCDeviceInputDev::handleCode(int rccode) } } -eRCDeviceInputDev::eRCDeviceInputDev(eRCInputEventDriver *driver): eRCDevice(driver->getDeviceName(), driver) +eRCDeviceInputDev::eRCDeviceInputDev(eRCInputEventDriver *driver) + :eRCDevice(driver->getDeviceName(), driver), iskeyboard(false) { + int len=id.length(); + int idx=0; + while(idx < len) + { + if (!strncasecmp(&id[idx++], "KEYBOARD", 8)) + { + iskeyboard=true; + break; + } + } + eDebug("Input device \"%s\" is %sa keyboard.", id.c_str(), iskeyboard ? "" : "not "); + } const char *eRCDeviceInputDev::getDescription() const diff --git a/lib/driver/rcinput.h b/lib/driver/rcinput.h index 6c18017..2e288ba 100644 --- a/lib/driver/rcinput.h +++ b/lib/driver/rcinput.h @@ -5,6 +5,7 @@ class eRCDeviceInputDev: public eRCDevice { + int iskeyboard; public: void handleCode(int code); eRCDeviceInputDev(eRCInputEventDriver *driver); diff --git a/lib/gui/einput.cpp b/lib/gui/einput.cpp index 7d411f9..62a77c5 100644 --- a/lib/gui/einput.cpp +++ b/lib/gui/einput.cpp @@ -94,34 +94,54 @@ int eInput::event(int event, void *data, void *data2) case evtAction: if (isVisible()) { - switch((int)data2) + if ((int)data == ASCII_ACTIONS) { - case moveLeft: - m_content->moveCursor(eInputContent::dirLeft); - break; - case moveRight: - m_content->moveCursor(eInputContent::dirRight); - break; - case moveHome: - m_content->moveCursor(eInputContent::dirHome); - break; - case moveEnd: - m_content->moveCursor(eInputContent::dirEnd); - break; - case deleteForward: - m_content->deleteChar(eInputContent::deleteForward); - break; - case deleteBackward: - m_content->deleteChar(eInputContent::deleteBackward); - break; - case toggleOverwrite: - setOverwriteMode(!m_mode); - break; - case accept: - changed(); - mayKillFocus(); + if ((int)data2 == gotAsciiCode) + { + if (m_content) + { + extern int getPrevAsciiCode(); // defined in enigma.cpp + return m_content->haveKey(getPrevAsciiCode(), m_mode); + } + } + } + else if ((int)data == INPUT_ACTIONS) + { + switch((int)data2) + { + case moveLeft: + if (m_content) + m_content->moveCursor(eInputContent::dirLeft); + break; + case moveRight: + if (m_content) + m_content->moveCursor(eInputContent::dirRight); + break; + case moveHome: + if (m_content) + m_content->moveCursor(eInputContent::dirHome); + break; + case moveEnd: + if (m_content) + m_content->moveCursor(eInputContent::dirEnd); + break; + case deleteForward: + if (m_content) + m_content->deleteChar(eInputContent::deleteForward); + break; + case deleteBackward: + if (m_content) + m_content->deleteChar(eInputContent::deleteBackward); + break; + case toggleOverwrite: + setOverwriteMode(!m_mode); + break; + case accept: + changed(); + mayKillFocus(); + } + return 1; } - return 1; } return 0; case evtKey: @@ -137,9 +157,8 @@ int eInput::event(int event, void *data, void *data2) eDebug("focus got in %p", this); ePtr ptr; eActionMap::getInstance(ptr); - ptr->bindAction("InputActions", 0, 0, this); - // bind all keys - ptr->bindAction("", 0, 1, this); + ptr->bindAction("InputActions", 0, INPUT_ACTIONS, this); + ptr->bindAction("AsciiActions", 0, ASCII_ACTIONS, this); m_have_focus = 1; eRCInput::getInstance()->setKeyboardMode(eRCInput::kmAscii); // fixme. we should use a style for this. @@ -152,8 +171,8 @@ int eInput::event(int event, void *data, void *data2) eDebug("focus lostin %p", this); ePtr ptr; eActionMap::getInstance(ptr); - ptr->unbindAction(this, 0); - ptr->unbindAction(this, 1); + ptr->unbindAction(this, INPUT_ACTIONS); + ptr->unbindAction(this, ASCII_ACTIONS); m_have_focus = 0; if (m_content) m_content->validate(); diff --git a/lib/gui/einput.h b/lib/gui/einput.h index 7c65cc1..ae83897 100644 --- a/lib/gui/einput.h +++ b/lib/gui/einput.h @@ -14,7 +14,12 @@ public: PSignal0 changed; int m_cursor; - + + enum { + INPUT_ACTIONS, + ASCII_ACTIONS + }; + enum InputActions { moveLeft, moveRight, @@ -25,7 +30,11 @@ public: toggleOverwrite, accept }; - + + enum AsciiActions { + gotAsciiCode + }; + void setContent(eInputContent *cnt); void setOverwriteMode(int o); diff --git a/lib/python/Components/Input.py b/lib/python/Components/Input.py index 0bd1305..311e42a 100644 --- a/lib/python/Components/Input.py +++ b/lib/python/Components/Input.py @@ -50,8 +50,9 @@ class Input(VariableText, HTMLComponent, GUIComponent): self.update() def left(self): - self.currPos -= 1 - self.update() + if self.currPos > 0: + self.currPos -= 1 + self.update() def up(self): if self.text[self.currPos] == "9" or self.text[self.currPos] == " ": @@ -73,7 +74,13 @@ class Input(VariableText, HTMLComponent, GUIComponent): def delete(self): self.text = self.text[:self.currPos] + self.text[self.currPos + 1:] self.update() - + + def handleAscii(self, code): + newChar = chr(code) + self.text = self.text[0:self.currPos] + newChar + self.text[self.currPos + 1:] + self.right() + self.update() + def number(self, number): if self.type == self.TEXT: newChar = self.numericalTextInput.getKey(number) diff --git a/lib/python/Screens/InputBox.py b/lib/python/Screens/InputBox.py index 47b800d..f3f9775 100644 --- a/lib/python/Screens/InputBox.py +++ b/lib/python/Screens/InputBox.py @@ -15,8 +15,9 @@ class InputBox(Screen): self["text"] = Label(title) self["input"] = Input(**kwargs) - self["actions"] = NumberActionMap(["WizardActions", "InputBoxActions"], + self["actions"] = NumberActionMap(["WizardActions", "InputBoxActions", "AsciiActions"], { + "gotAsciiCode": self.gotAsciiCode, "ok": self.go, "back": self.cancel, "left": self.keyLeft, @@ -33,7 +34,12 @@ class InputBox(Screen): "9": self.keyNumberGlobal, "0": self.keyNumberGlobal }, -1) - + rcinput = eRCInput.getInstance() + rcinput.setKeyboardMode(rcinput.kmAscii) + + def gotAsciiCode(self): + self["input"].handleAscii(getPrevAsciiCode()) + def keyLeft(self): self["input"].left() @@ -47,7 +53,11 @@ class InputBox(Screen): self["input"].delete() def go(self): + rcinput = eRCInput.getInstance() + rcinput.setKeyboardMode(rcinput.kmNone) self.close(self["input"].getText()) def cancel(self): - self.close(None) \ No newline at end of file + rcinput = eRCInput.getInstance() + rcinput.setKeyboardMode(rcinput.kmNone) + self.close(None) diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index ce77632..06d8447 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -94,6 +94,7 @@ extern void quitMainloop(int exit_code); extern eApplication *getApplication(); extern PSignal1 &keyPressedSignal(); +extern int getPrevAsciiCode(); %} %feature("ref") iObject "$this->AddRef(); /* eDebug(\"AddRef (%s:%d)!\", __FILE__, __LINE__); */ " @@ -254,6 +255,7 @@ void addFont(const char *filename, const char *alias, int scale_factor, int is_r /************** debug **************/ +int getPrevAsciiCode(); void runMainloop(); void quitMainloop(int exit_code); eApplication *getApplication(); diff --git a/main/enigma.cpp b/main/enigma.cpp index f9b88e7..96b4cef 100644 --- a/main/enigma.cpp +++ b/main/enigma.cpp @@ -53,13 +53,28 @@ PSignal1 &keyPressedSignal() return keyPressed; } +static int prev_ascii_code; + +int getPrevAsciiCode() +{ + int ret = prev_ascii_code; + prev_ascii_code = 0; + return ret; +} + void keyEvent(const eRCKey &key) { ePtr ptr; eActionMap::getInstance(ptr); - ptr->keyPressed(0, key.code, key.flags); -// if (!key.flags) -// keyPressed(key.code); + if (key.flags & eRCKey::flagAscii) + { + prev_ascii_code = key.code; + ptr->keyPressed(0, 510 /* faked KEY_ASCII */, 0); + } + else + ptr->keyPressed(0, key.code, key.flags); + if (!key.flags) + keyPressed(key.code); } /************************************************/ -- 2.7.4