From 84670d3dc9c9dc29fd3af42b2f25092b3b6c2a09 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Thu, 27 Jan 2005 06:25:40 +0000 Subject: [PATCH] - add rcconsole key input (for now) - very basic method of delivering keys into python (will be changed, of course) --- lib/driver/Makefile.am | 3 +- lib/driver/rcconsole.cpp | 120 +++++++++++++++++++++++++++++++++++++ lib/driver/rcconsole.h | 45 ++++++++++++++ lib/python/enigma_python.i | 4 ++ main/enigma.cpp | 17 ++++++ mytest.py | 25 ++++++-- screens.py | 1 - 7 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 lib/driver/rcconsole.cpp create mode 100644 lib/driver/rcconsole.h diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am index eff4486f..a8a1f49b 100644 --- a/lib/driver/Makefile.am +++ b/lib/driver/Makefile.am @@ -4,4 +4,5 @@ INCLUDES = \ noinst_LIBRARIES = libenigma_driver.a libenigma_driver_a_SOURCES = \ - rc.cpp rcinput.cpp \ No newline at end of file + rc.cpp rcinput.cpp rcconsole.cpp + \ No newline at end of file diff --git a/lib/driver/rcconsole.cpp b/lib/driver/rcconsole.cpp new file mode 100644 index 00000000..ec759164 --- /dev/null +++ b/lib/driver/rcconsole.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + +eRCConsoleDriver::eRCConsoleDriver(const char *filename): eRCDriver(eRCInput::getInstance()) +{ + handle=open(filename, O_RDONLY|O_NONBLOCK); + if (handle<0) + { + eDebug("failed to open %s", filename); + sn=0; + } else + { + sn=new eSocketNotifier(eApp, handle, eSocketNotifier::Read); + CONNECT(sn->activated, eRCConsoleDriver::keyPressed); + eRCInput::getInstance()->setFile(handle); + } + + /* set console mode */ + struct termios t,ot; + tcgetattr(handle, &t); + t.c_lflag &= ~(ECHO | ICANON | ECHOK | ECHOE | ECHONL); + ot = t; + tcsetattr(handle, TCSANOW,&t); +} + +eRCConsoleDriver::~eRCConsoleDriver() +{ + tcsetattr(handle,TCSANOW, &ot); + if (handle>=0) + close(handle); + if (sn) + delete sn; +} + +void eRCConsoleDriver::keyPressed(int) +{ + char data[16]; + char *d = data; + int num = read(handle, data, 16); + int code; +#if 0 + int km = input->getKeyboardMode(); + + if (km == eRCInput::kmNone) + return; +#endif + while (num--) + { +#if 0 + if (km == eRCInput::kmAll) +#endif + code = *d++; +#if 0 + else + { + if (*d == 27) // escape code + { + while (num) + { + num--; + if (*++d != '[') + break; + } + code = -1; + } else + code = *d; + ++d; + + if (code < 32) /* control characters */ + code = -1; + if (code == 0x7F) /* delete */ + code = -1; + } +#endif + if (code != -1) + for (std::list::iterator i(listeners.begin()); i!=listeners.end(); ++i) + (*i)->handleCode(code); + } +} + +void eRCConsole::handleCode(int code) +{ + input->keyPressed(eRCKey(this, code, 0)); +} + +eRCConsole::eRCConsole(eRCDriver *driver) + : eRCDevice("Console", driver) +{ +} + +const char *eRCConsole::getDescription() const +{ + return "Console"; +} + +const char *eRCConsole::getKeyDescription(const eRCKey &key) const +{ + return 0; +} + +int eRCConsole::getKeyCompatibleCode(const eRCKey &key) const +{ + return key.code; // | KEY_ASCII; +} + +class eRCConsoleInit +{ + eRCConsoleDriver driver; + eRCConsole device; +public: + eRCConsoleInit(): driver("/dev/vc/0"), device(&driver) + { + } +}; + +eAutoInitP0 init_rcconsole(eAutoInitNumbers::rc+1, "Console RC Driver"); diff --git a/lib/driver/rcconsole.h b/lib/driver/rcconsole.h new file mode 100644 index 00000000..0c1dd636 --- /dev/null +++ b/lib/driver/rcconsole.h @@ -0,0 +1,45 @@ +#ifndef __lib_driver_rcconsole_h +#define __lib_driver_rcconsole_h + +#include +#include + +class eRCConsoleDriver: public eRCDriver +{ + struct termios ot; +protected: + int handle; + eSocketNotifier *sn; + void keyPressed(int); +public: + eRCConsoleDriver(const char *filename); + ~eRCConsoleDriver(); + void flushBuffer() const + { + char data[16]; + if (handle != -1) + while ( ::read(handle, data, 16) == 16 ); + } + void lock() const + { + if ( sn ) + sn->stop(); + } + void unlock() const + { + if ( sn ) + sn->start(); + } +}; + +class eRCConsole: public eRCDevice +{ +public: + void handleCode(int code); + eRCConsole(eRCDriver *driver); + const char *getDescription() const; + const char *getKeyDescription(const eRCKey &key) const; + int getKeyCompatibleCode(const eRCKey &key) const; +}; + +#endif diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index c621bb62..367d8f8e 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -53,6 +53,8 @@ is usually caused by not marking PSignals as immutable. #include extern void runMainloop(); + +extern PSignal1 &keyPressedSignal(); %} #define DEBUG @@ -127,3 +129,5 @@ public: /************** debug **************/ void runMainloop(); +%immutable keyPressed; +PSignal1 &keyPressedSignal(); diff --git a/main/enigma.cpp b/main/enigma.cpp index 92982e5b..df28bcd7 100644 --- a/main/enigma.cpp +++ b/main/enigma.cpp @@ -21,6 +21,8 @@ #include #include +#include + #ifdef OBJECT_DEBUG int object_total_remaining; @@ -69,6 +71,19 @@ void print(int i) printf("C++ says: it's a %d!!!\n", i); } +PSignal1 keyPressed; + +PSignal1 &keyPressedSignal() +{ + return keyPressed; +} + +void keyEvent(const eRCKey &key) +{ + if (!key.flags) + keyPressed(key.code); +} + int main(int argc, char **argv) { #ifdef OBJECT_DEBUG @@ -112,6 +127,8 @@ int main(int argc, char **argv) /* redrawing is done in an idle-timer, so we have to set the context */ dsk.setRedrawTask(main); + eRCInput::getInstance()->keyEvent.connect(slot(keyEvent)); + ePython python; printf("executing main\n"); diff --git a/mytest.py b/mytest.py index c0967d78..b3d1701c 100644 --- a/mytest.py +++ b/mytest.py @@ -6,6 +6,13 @@ import time from screens import * from skin import applyGUIskin + +def CONNECT(slot, fnc): + slot.get().append(fnc) + +def DISCONNECT(slot, fnc): + slot.get().remove(fnc) + # A screen is a function which instanciates all components of a screen into a temporary component. # Thus, the global stuff is a screen, too. # In a screen, components can either be instanciated from the class-tree, cloned (copied) or @@ -92,6 +99,9 @@ class Session: else: self.currentWindow = None + def keyEvent(self, code): + self.currentDialog.data["okbutton"]["instance"].push() + def close(self): self.delayTimer.start(0, 1) @@ -106,12 +116,15 @@ def runScreenTest(): # active "okbutton", even when we changed the dialog # # more complicated reason: we don't want to hold a reference. - def blub(): - session.currentDialog.data["okbutton"]["instance"].push() - - tmr = eTimer() - tmr.timeout.get().append(blub) - tmr.start(4000, 0) +# def blub(): +# session.currentDialog.data["okbutton"]["instance"].push() +# session.currentDialog["okbutton"].setText("hello!") +# +# tmr = eTimer() +# CONNECT(tmr.timeout, blub) +# tmr.start(4000, 0) +# + CONNECT(keyPressedSignal(), session.keyEvent) runMainloop() diff --git a/screens.py b/screens.py index f0b06bda..a44f825e 100644 --- a/screens.py +++ b/screens.py @@ -14,7 +14,6 @@ class Screen(dict, HTMLSkin, GUISkin): # a test dialog class testDialog(Screen): def testDialogClick(self): - print "test dialog clicked!" if self.tries == 0: self["title"].setText("Hihi - no, this doesn't work!") else: -- 2.30.2