From 1cdf6cb021fcaa6548b90ba7b6765cf1e8b8b37b Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 25 Feb 2005 01:46:44 +0000 Subject: [PATCH] - work on actions - changed time when screens are acutally constructed - added service name (not working atm) and event info (now&next) --- components.py | 98 ++++++++++++++- configure.ac | 1 + keyids.py | 297 +++++++++++++++++++++++++++++++++++++++++++++ keymap.xml | 26 ++++ keymapparser.py | 68 +++++++++++ lib/Makefile.am | 2 +- lib/base/smartptr.h | 8 ++ lib/components/scan.cpp | 26 ++-- lib/components/scan.h | 2 +- lib/driver/rcconsole.cpp | 2 +- lib/dvb/scan.cpp | 6 + lib/dvb/scan.h | 2 +- lib/gui/elistbox.cpp | 16 +++ lib/gui/elistbox.h | 14 ++- lib/gui/ewidget.h | 2 + lib/gui/ewindowstyle.cpp | 28 +++-- lib/nav/core.cpp | 28 ++++- lib/nav/core.h | 4 +- lib/nav/pcore.cpp | 27 +++++ lib/nav/pcore.h | 19 ++- lib/python/enigma_python.i | 19 ++- lib/service/event.h | 6 +- lib/service/iservice.h | 10 +- lib/service/servicedvb.cpp | 6 +- lib/service/servicedvb.h | 1 + main/Makefile.am | 1 + main/enigma.cpp | 11 +- mytest.py | 37 +++--- screens.py | 68 ++++++++--- skin.py | 3 + 30 files changed, 754 insertions(+), 84 deletions(-) create mode 100644 keyids.py create mode 100644 keymap.xml create mode 100644 keymapparser.py diff --git a/components.py b/components.py index 63e5669..219e4f5 100644 --- a/components.py +++ b/components.py @@ -86,7 +86,13 @@ class GUIComponent: def __init__(self): pass + + def execBegin(self): + pass + def execEnd(self): + pass + class VariableText: """VariableText can be used for components which have a variable text, based on any widget with setText call""" @@ -322,4 +328,94 @@ class ServiceScan: def fix(self): self.scan.statusChanged.get().remove(self.scanStatusChanged) - \ No newline at end of file + +class ActionMap: + def __init__(self, context, actions = { }, prio=0): + self.actions = actions + self.context = context + self.prio = prio + self.p = eActionMapPtr() + eActionMap.getInstance(self.p) + + def execBegin(self): + self.p.bindAction(self.context, self.prio, self.action) + + def execEnd(self): + self.p.unbindAction(self.context, self.action) + + def action(self, context, action): + try: + self.actions[action]() + except KeyError: + print "unknown action %s/%s! typo in keymap?" % (context, action) + +class PerServiceDisplay(GUIComponent, VariableText): + """Mixin for building components which display something which changes on navigation events, for example "service name" """ + + def __init__(self, navcore, eventmap): + GUIComponent.__init__(self) + VariableText.__init__(self) + self.eventmap = eventmap + navcore.m_event.get().append(self.event) + self.navcore = navcore + + # start with stopped state, so simulate that + self.event(pNavigation.evStopService) + + def event(self, ev): + # loop up if we need to handle this event + if self.eventmap.has_key(ev): + # call handler + self.eventmap[ev]() + + def createWidget(self, parent, skindata): + # by default, we use a label to display our data. + g = eLabel(parent) + return g + +class EventInfo(PerServiceDisplay): + Now = 0 + Next = 1 + def __init__(self, navcore, now_or_next): + # listen to evUpdatedEventInfo and evStopService + # note that evStopService will be called once to establish a known state + PerServiceDisplay.__init__(self, navcore, + { + pNavigation.evUpdatedEventInfo: self.ourEvent, + pNavigation.evStopService: self.stopEvent + }) + self.now_or_next = now_or_next + + def ourEvent(self): + info = iServiceInformationPtr() + service = iPlayableServicePtr() + + if not self.navcore.getCurrentService(service): + if not service.info(info): + print "got info !" + ev = eServiceEventPtr() + info.getEvent(ev, self.now_or_next) + self.setText(ev.m_event_name) + print "new event info in EventInfo! yeah!" + + def stopEvent(self): + self.setText("waiting for event data..."); + +class ServiceName(PerServiceDisplay): + def __init__(self, navcore): + PerServiceDisplay.__init__(self, navcore, + { + pNavigation.evNewService: self.newService, + pNavigation.evStopService: self.stopEvent + }) + + def newService(self): + info = iServiceInformationPtr() + service = iPlayableServicePtr() + + if not self.navcore.getCurrentService(service): + if not service.info(info): + self.setText("no name known, but it should be here :)") + + def stopEvent(self): + self.setText(""); diff --git a/configure.ac b/configure.ac index ca7a706..3b67b4c 100644 --- a/configure.ac +++ b/configure.ac @@ -29,6 +29,7 @@ TUXBOX_APPS_GETTEXT AC_OUTPUT([ Makefile lib/Makefile +lib/actions/Makefile lib/base/Makefile lib/driver/Makefile lib/dvb/Makefile diff --git a/keyids.py b/keyids.py new file mode 100644 index 0000000..fab9345 --- /dev/null +++ b/keyids.py @@ -0,0 +1,297 @@ +KEYIDS = { +"KEY_RESERVED": 0, +"KEY_ESC": 1, +"KEY_1": 2, +"KEY_2": 3, +"KEY_3": 4, +"KEY_4": 5, +"KEY_5": 6, +"KEY_6": 7, +"KEY_7": 8, +"KEY_8": 9, +"KEY_9": 10, +"KEY_0": 11, +"KEY_MINUS": 12, +"KEY_EQUAL": 13, +"KEY_BACKSPACE": 14, +"KEY_TAB": 15, +"KEY_Q": 16, +"KEY_W": 17, +"KEY_E": 18, +"KEY_R": 19, +"KEY_T": 20, +"KEY_Y": 21, +"KEY_U": 22, +"KEY_I": 23, +"KEY_O": 24, +"KEY_P": 25, +"KEY_LEFTBRACE": 26, +"KEY_RIGHTBRACE": 27, +"KEY_ENTER": 28, +"KEY_LEFTCTRL": 29, +"KEY_A": 30, +"KEY_S": 31, +"KEY_D": 32, +"KEY_F": 33, +"KEY_G": 34, +"KEY_H": 35, +"KEY_J": 36, +"KEY_K": 37, +"KEY_L": 38, +"KEY_SEMICOLON": 39, +"KEY_APOSTROPHE": 40, +"KEY_GRAVE": 41, +"KEY_LEFTSHIFT": 42, +"KEY_BACKSLASH": 43, +"KEY_Z": 44, +"KEY_X": 45, +"KEY_C": 46, +"KEY_V": 47, +"KEY_B": 48, +"KEY_N": 49, +"KEY_M": 50, +"KEY_COMMA": 51, +"KEY_DOT": 52, +"KEY_SLASH": 53, +"KEY_RIGHTSHIFT": 54, +"KEY_KPASTERISK": 55, +"KEY_LEFTALT": 56, +"KEY_SPACE": 57, +"KEY_CAPSLOCK": 58, +"KEY_F1": 59, +"KEY_F2": 60, +"KEY_F3": 61, +"KEY_F4": 62, +"KEY_F5": 63, +"KEY_F6": 64, +"KEY_F7": 65, +"KEY_F8": 66, +"KEY_F9": 67, +"KEY_F10": 68, +"KEY_NUMLOCK": 69, +"KEY_SCROLLLOCK": 70, +"KEY_KP7": 71, +"KEY_KP8": 72, +"KEY_KP9": 73, +"KEY_KPMINUS": 74, +"KEY_KP4": 75, +"KEY_KP5": 76, +"KEY_KP6": 77, +"KEY_KPPLUS": 78, +"KEY_KP1": 79, +"KEY_KP2": 80, +"KEY_KP3": 81, +"KEY_KP0": 82, +"KEY_KPDOT": 83, +"KEY_103RD": 84, +"KEY_F13": 85, +"KEY_102ND": 86, +"KEY_F11": 87, +"KEY_F12": 88, +"KEY_F14": 89, +"KEY_F15": 90, +"KEY_F16": 91, +"KEY_F17": 92, +"KEY_F18": 93, +"KEY_F19": 94, +"KEY_F20": 95, +"KEY_KPENTER": 96, +"KEY_RIGHTCTRL": 97, +"KEY_KPSLASH": 98, +"KEY_SYSRQ": 99, +"KEY_RIGHTALT": 100, +"KEY_LINEFEED": 101, +"KEY_HOME": 102, +"KEY_UP": 103, +"KEY_PAGEUP": 104, +"KEY_LEFT": 105, +"KEY_RIGHT": 106, +"KEY_END": 107, +"KEY_DOWN": 108, +"KEY_PAGEDOWN": 109, +"KEY_INSERT": 110, +"KEY_DELETE": 111, +"KEY_MACRO": 112, +"KEY_MUTE": 113, +"KEY_VOLUMEDOWN": 114, +"KEY_VOLUMEUP": 115, +"KEY_POWER": 116, +"KEY_KPEQUAL": 117, +"KEY_KPPLUSMINUS": 118, +"KEY_PAUSE": 119, +"KEY_F21": 120, +"KEY_F22": 121, +"KEY_F23": 122, +"KEY_F24": 123, +"KEY_KPCOMMA": 124, +"KEY_LEFTMETA": 125, +"KEY_RIGHTMETA": 126, +"KEY_COMPOSE": 127, +"KEY_STOP": 128, +"KEY_AGAIN": 129, +"KEY_PROPS": 130, +"KEY_UNDO": 131, +"KEY_FRONT": 132, +"KEY_COPY": 133, +"KEY_OPEN": 134, +"KEY_PASTE": 135, +"KEY_FIND": 136, +"KEY_CUT": 137, +"KEY_HELP": 138, +"KEY_MENU": 139, +"KEY_CALC": 140, +"KEY_SETUP": 141, +"KEY_SLEEP": 142, +"KEY_WAKEUP": 143, +"KEY_FILE": 144, +"KEY_SENDFILE": 145, +"KEY_DELETEFILE": 146, +"KEY_XFER": 147, +"KEY_PROG1": 148, +"KEY_PROG2": 149, +"KEY_WWW": 150, +"KEY_MSDOS": 151, +"KEY_COFFEE": 152, +"KEY_DIRECTION": 153, +"KEY_CYCLEWINDOWS": 154, +"KEY_MAIL": 155, +"KEY_BOOKMARKS": 156, +"KEY_COMPUTER": 157, +"KEY_BACK": 158, +"KEY_FORWARD": 159, +"KEY_CLOSECD": 160, +"KEY_EJECTCD": 161, +"KEY_EJECTCLOSECD": 162, +"KEY_NEXTSONG": 163, +"KEY_PLAYPAUSE": 164, +"KEY_PREVIOUSSONG": 165, +"KEY_STOPCD": 166, +"KEY_RECORD": 167, +"KEY_REWIND": 168, +"KEY_PHONE": 169, +"KEY_ISO": 170, +"KEY_CONFIG": 171, +"KEY_HOMEPAGE": 172, +"KEY_REFRESH": 173, +"KEY_EXIT": 174, +"KEY_MOVE": 175, +"KEY_EDIT": 176, +"KEY_SCROLLUP": 177, +"KEY_SCROLLDOWN": 178, +"KEY_KPLEFTPAREN": 179, +"KEY_KPRIGHTPAREN": 180, +"KEY_INTL1": 181, +"KEY_INTL2": 182, +"KEY_INTL3": 183, +"KEY_INTL4": 184, +"KEY_INTL5": 185, +"KEY_INTL6": 186, +"KEY_INTL7": 187, +"KEY_INTL8": 188, +"KEY_INTL9": 189, +"KEY_LANG1": 190, +"KEY_LANG2": 191, +"KEY_LANG3": 192, +"KEY_LANG4": 193, +"KEY_LANG5": 194, +"KEY_LANG6": 195, +"KEY_LANG7": 196, +"KEY_LANG8": 197, +"KEY_LANG9": 198, +"KEY_PLAYCD": 200, +"KEY_PAUSECD": 201, +"KEY_PROG3": 202, +"KEY_PROG4": 203, +"KEY_SUSPEND": 205, +"KEY_CLOSE": 206, +"KEY_PLAY": 207, +"KEY_FASTFORWARD": 208, +"KEY_BASSBOOST": 209, +"KEY_PRINT": 210, +"KEY_HP": 211, +"KEY_CAMERA": 212, +"KEY_SOUND": 213, +"KEY_QUESTION": 214, +"KEY_EMAIL": 215, +"KEY_CHAT": 216, +"KEY_SEARCH": 217, +"KEY_CONNECT": 218, +"KEY_FINANCE": 219, +"KEY_SPORT": 220, +"KEY_SHOP": 221, +"KEY_ALTERASE": 222, +"KEY_CANCEL": 223, +"KEY_BRIGHTNESSDOWN": 224, +"KEY_BRIGHTNESSUP": 225, +"KEY_MEDIA": 226, +"KEY_UNKNOWN": 240, +"KEY_OK": 352, +"KEY_SELECT": 353, +"KEY_GOTO": 354, +"KEY_CLEAR": 355, +"KEY_POWER2": 356, +"KEY_OPTION": 357, +"KEY_INFO": 358, +"KEY_TIME": 359, +"KEY_VENDOR": 360, +"KEY_ARCHIVE": 361, +"KEY_PROGRAM": 362, +"KEY_CHANNEL": 363, +"KEY_FAVORITES": 364, +"KEY_EPG": 365, +"KEY_PVR": 366, +"KEY_MHP": 367, +"KEY_LANGUAGE": 368, +"KEY_TITLE": 369, +"KEY_SUBTITLE": 370, +"KEY_ANGLE": 371, +"KEY_ZOOM": 372, +"KEY_MODE": 373, +"KEY_KEYBOARD": 374, +"KEY_SCREEN": 375, +"KEY_PC": 376, +"KEY_TV": 377, +"KEY_TV2": 378, +"KEY_VCR": 379, +"KEY_VCR2": 380, +"KEY_SAT": 381, +"KEY_SAT2": 382, +"KEY_CD": 383, +"KEY_TAPE": 384, +"KEY_RADIO": 385, +"KEY_TUNER": 386, +"KEY_PLAYER": 387, +"KEY_TEXT": 388, +"KEY_DVD": 389, +"KEY_AUX": 390, +"KEY_MP3": 391, +"KEY_AUDIO": 392, +"KEY_VIDEO": 393, +"KEY_DIRECTORY": 394, +"KEY_LIST": 395, +"KEY_MEMO": 396, +"KEY_CALENDAR": 397, +"KEY_RED": 398, +"KEY_GREEN": 399, +"KEY_YELLOW": 400, +"KEY_BLUE": 401, +"KEY_CHANNELUP": 402, +"KEY_CHANNELDOWN": 403, +"KEY_FIRST": 404, +"KEY_LAST": 405, +"KEY_AB": 406, +"KEY_NEXT": 407, +"KEY_RESTART": 408, +"KEY_SLOW": 409, +"KEY_SHUFFLE": 410, +"KEY_BREAK": 411, +"KEY_PREVIOUS": 412, +"KEY_DIGITS": 413, +"KEY_TEEN": 414, +"KEY_TWEN": 415, +"KEY_DEL_EOL": 448, +"KEY_DEL_EOS": 449, +"KEY_INS_LINE": 450, +"KEY_DEL_LINE": 451, +"KEY_MAX": 511, +} diff --git a/keymap.xml b/keymap.xml new file mode 100644 index 0000000..a17aebb --- /dev/null +++ b/keymap.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/keymapparser.py b/keymapparser.py new file mode 100644 index 0000000..510a47a --- /dev/null +++ b/keymapparser.py @@ -0,0 +1,68 @@ +import xml.dom.minidom +import enigma + +from keyids import KEYIDS; + +def readKeymap(): + + p = enigma.eActionMapPtr() + enigma.eActionMap.getInstance(p) + assert p + + filename = "keymap.xml" + + try: + source = open(filename) + except: + raise "couldn't open keymap.xml!" + + try: + dom = xml.dom.minidom.parse(source) + except: + raise "keymap not well-formed." + + try: + keymap = dom.getElementsByTagName("keymap")[0] + except: + raise "no keymap defined." + + maps = keymap.getElementsByTagName("map") + + for cmap in maps: + context = str(cmap.getAttribute("context")) + assert context != "", "map must have context" + + def parseKeys(device, keys): + for x in keys.getElementsByTagName("key"): + mapto = str(x.getAttribute("mapto")) + id = x.getAttribute("id") + flags = x.getAttribute("flags") + + flag_ascii_to_id = lambda x: {'m':1,'r':2,'b':4}[x] + +# try: + flags = sum(map(flag_ascii_to_id, flags)) + print "-> " + str(flags) +# except: +# raise str("%s: illegal flags '%s' specificed in context %s, id '%s'" % (filename, flags, context, id)) + + assert mapto != "", "%s: must specify mapto in context %s, id '%s'" % (filename, context, id) + assert id != "", "%s: must specify id in context %s, mapto '%s'" % (filename, context, mapto) + assert flags != 0, "%s: must specify at least one flag in context %s, id '%s'" % (filename, context, id) + + if len(id) == 1: + keyid = ord(id) | 0x8000 + else: + try: + keyid = KEYIDS[id] + except: + raise "key id '" + str(id) + "' is illegal" + + print context + "::" + mapto + " -> " + device + "." + hex(keyid) + p.bindKey(device, keyid, 7, context, mapto) + + parseKeys("generic", cmap) + + for device in cmap.getElementsByTagName("device"): + parseKeys(str(device.getAttribute("name")), device) + diff --git a/lib/Makefile.am b/lib/Makefile.am index 72efc40..72679b6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1 +1 @@ -SUBDIRS = base dvb dvb_si gdi network service driver nav gui python components +SUBDIRS = actions base components dvb dvb_si gdi network service driver nav gui python diff --git a/lib/base/smartptr.h b/lib/base/smartptr.h index 906bba6..159eeb2 100644 --- a/lib/base/smartptr.h +++ b/lib/base/smartptr.h @@ -4,6 +4,14 @@ #include "object.h" #include +#ifdef SWIG +#define TEMPLATE_TYPEDEF(x, y) \ +%template(y) x; \ +typedef x y +#else +#define TEMPLATE_TYPEDEF(x, y) typedef x y +#endif + template class ePtr { diff --git a/lib/components/scan.cpp b/lib/components/scan.cpp index 4d8d8b7..8fb60b5 100644 --- a/lib/components/scan.cpp +++ b/lib/components/scan.cpp @@ -20,23 +20,29 @@ void eComponentScan::scanEvent(int evt) if ((err = eDVBResourceManager::getInstance(res)) != 0) { eDebug("no resource manager"); - return; - } - if ((err = res->getChannelList(db)) != 0) + m_failed = 2; + } else if ((err = res->getChannelList(db)) != 0) { + m_failed = 3; eDebug("no channel list"); - return; + } else + { + m_scan->insertInto(db); + eDebug("scan done!"); } - - m_scan->insertInto(db); - - eDebug("scan done!"); + } + + if (evt == eDVBScan::evtFail) + { + eDebug("scan failed."); + m_failed = 1; + m_done = 1; } statusChanged(); } -eComponentScan::eComponentScan(): m_done(-1) +eComponentScan::eComponentScan(): m_done(-1), m_failed(0) { } @@ -77,8 +83,8 @@ int eComponentScan::start() list.push_back(fe); m_scan = new eDVBScan(channel); - m_scan->start(list); m_scan->connectEvent(slot(*this, &eComponentScan::scanEvent), m_scan_event_connection); + m_scan->start(list); return 0; } diff --git a/lib/components/scan.h b/lib/components/scan.h index afa6868..073919c 100644 --- a/lib/components/scan.h +++ b/lib/components/scan.h @@ -13,7 +13,7 @@ private: ePtr m_scan_event_connection; ePtr m_scan; - int m_done; + int m_done, m_failed; public: eComponentScan(); ~eComponentScan(); diff --git a/lib/driver/rcconsole.cpp b/lib/driver/rcconsole.cpp index f662b2b..3b5397b 100644 --- a/lib/driver/rcconsole.cpp +++ b/lib/driver/rcconsole.cpp @@ -78,7 +78,7 @@ void eRCConsoleDriver::keyPressed(int) #endif if (code != -1) for (std::list::iterator i(listeners.begin()); i!=listeners.end(); ++i) - (*i)->handleCode(code); + (*i)->handleCode(code | 0x8000); } } diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp index 65eb053..b6d0575 100644 --- a/lib/dvb/scan.cpp +++ b/lib/dvb/scan.cpp @@ -96,11 +96,17 @@ RESULT eDVBScan::nextChannel() m_ch_toScan.pop_front(); if (m_channel->getFrontend(fe)) + { + m_event(evtFail); return -ENOTSUP; + } m_channel_state = iDVBChannel::state_idle; if (fe->tune(*m_ch_current)) + { + m_event(evtFail); return -EINVAL; + } m_event(evtUpdate); return 0; diff --git a/lib/dvb/scan.h b/lib/dvb/scan.h index 3556eb2..96264e8 100644 --- a/lib/dvb/scan.h +++ b/lib/dvb/scan.h @@ -65,7 +65,7 @@ public: void start(const std::list > &known_transponders); - enum { evtUpdate, evtFinish }; + enum { evtUpdate, evtFinish, evtFail }; RESULT connectEvent(const Slot1 &event, ePtr &connection); void insertInto(iDVBChannelList *db); diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp index 361d7b9..1dae137 100644 --- a/lib/gui/elistbox.cpp +++ b/lib/gui/elistbox.cpp @@ -1,9 +1,22 @@ #include #include +#include eListbox::eListbox(eWidget *parent): eWidget(parent) { setContent(new eListboxStringContent()); + + ePtr ptr; + eActionMap::getInstance(ptr); + + ptr->bindAction("ListboxActions", 0, 0, this); +} + +eListbox::~eListbox() +{ + ePtr ptr; + eActionMap::getInstance(ptr); + ptr->unbindAction(this, 0); } void eListbox::setContent(iListboxContent *content) @@ -108,6 +121,9 @@ int eListbox::event(int event, void *data, void *data2) return 0; } + case evtAction: + moveSelection((int)data2); + return 1; default: return eWidget::event(event, data, data2); } diff --git a/lib/gui/elistbox.h b/lib/gui/elistbox.h index 9ec9466..78e0fbe 100644 --- a/lib/gui/elistbox.h +++ b/lib/gui/elistbox.h @@ -50,14 +50,26 @@ class eListbox: public eWidget { public: eListbox(eWidget *parent); + ~eListbox(); void setContent(iListboxContent *content); +/* enum Movement { + moveUp, + moveDown, + moveTop, + moveEnd, + justCheck + }; */ + void moveSelection(int how); - enum { + + enum ListboxActions { moveUp, moveDown, moveTop, moveEnd, + pageUp, + pageDown, justCheck }; protected: diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h index fa8cd8c..12d2e74 100644 --- a/lib/gui/ewidget.h +++ b/lib/gui/ewidget.h @@ -73,6 +73,8 @@ public: evtWillChangePosition, /* new size is eRect *data */ evtWillChangeSize, + evtAction, + evtUserWidget, }; virtual int event(int event, void *data = 0, void *data2 = 0); diff --git a/lib/gui/ewindowstyle.cpp b/lib/gui/ewindowstyle.cpp index a5ace37..ccf7299 100644 --- a/lib/gui/ewindowstyle.cpp +++ b/lib/gui/ewindowstyle.cpp @@ -10,16 +10,16 @@ DEFINE_REF(eWindowStyleSimple); eWindowStyleSimple::eWindowStyleSimple() { - m_border_left = m_border_right = m_border_bottom = 1; + m_border_left = m_border_right = m_border_bottom = 2; m_border_top = 30; m_fnt = new gFont("Arial", 25); - m_border_color_tl = gColor(0x14); - m_border_color_br = gColor(0x1c); + m_border_color_tl = gColor(0x1f); + m_border_color_br = gColor(0x14); m_title_color_back = gColor(0x20); m_title_color = gColor(0x2f); - m_background_color = gColor(0x18); + m_background_color = gColor(0x19); } void eWindowStyleSimple::handleNewSize(eWindow *wnd, const eSize &size) @@ -36,19 +36,27 @@ void eWindowStyleSimple::handleNewSize(eWindow *wnd, const eSize &size) void eWindowStyleSimple::paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title) { + painter.setForegroundColor(m_title_color_back); + painter.fill(eRect(2, 2, wnd->size().width() - 4, m_border_top - 4)); painter.setBackgroundColor(m_title_color_back); painter.setForegroundColor(m_title_color); - painter.clear(); painter.setFont(m_fnt); - painter.renderText(eRect(1, 1, wnd->size().width() - 2, m_border_top - 2), title); + painter.renderText(eRect(3, 3, wnd->size().width() - 6, m_border_top - 6), title); eRect frame(ePoint(0, 0), wnd->size()); - painter.setForegroundColor(m_border_color_tl); + + painter.setForegroundColor(m_background_color); painter.line(frame.topLeft1(), frame.topRight1()); - painter.line(frame.topRight1(), frame.bottomRight1()); + painter.line(frame.topLeft1(), frame.bottomLeft1()); + painter.setForegroundColor(m_border_color_tl); + painter.line(frame.topLeft1()+eSize(1,1), frame.topRight1()+eSize(0,1)); + painter.line(frame.topLeft1()+eSize(1,1), frame.bottomLeft1()+eSize(1,0)); + painter.setForegroundColor(m_border_color_br); - painter.line(frame.bottomRight1(), frame.bottomLeft1()); - painter.line(frame.bottomLeft1(), frame.topLeft1()); + painter.line(frame.bottomLeft()+eSize(1,-1), frame.bottomRight()+eSize(0,-1)); + painter.line(frame.topRight1()+eSize(-1,1), frame.bottomRight1()+eSize(-1, 0)); + painter.line(frame.bottomLeft()+eSize(1,-2), frame.bottomRight()+eSize(0,-2)); + painter.line(frame.topRight1()+eSize(-0,1), frame.bottomRight1()+eSize(-0, 0)); } void eWindowStyleSimple::paintBackground(gPainter &painter, const ePoint &offset, const eSize &size) diff --git a/lib/nav/core.cpp b/lib/nav/core.cpp index 10d18e3..99dcf2e 100644 --- a/lib/nav/core.cpp +++ b/lib/nav/core.cpp @@ -14,11 +14,10 @@ void eNavigation::serviceEvent(iPlayableService* service, int event) case iPlayableService::evEnd: assert(m_playlist); /* we need to have a playlist */ - /* at first, kill the running service */ - m_event(this, evStopService); - m_runningService = 0; - m_service_event_conn = 0; - /* our running main service stopped. identify what to do next. */ + /* at first, kill the running service */ + stopService(); + + /* our running main service stopped. identify what to do next. */ /* unless the playlist current position is invalid (because there was */ /* playlist, for example when the service was engaged with playService */ @@ -41,6 +40,9 @@ void eNavigation::serviceEvent(iPlayableService* service, int event) case iPlayableService::evStart: m_event(this, evNewService); break; + case iPlayableService::evUpdatedEventInfo: + m_event(this, evUpdatedEventInfo); + break; default: break; } @@ -48,6 +50,8 @@ void eNavigation::serviceEvent(iPlayableService* service, int event) RESULT eNavigation::playService(const eServiceReference &service) { + stopService(); + assert(m_servicehandler); RESULT res = m_servicehandler->play(service, m_runningService); if (m_runningService) @@ -97,6 +101,20 @@ RESULT eNavigation::getPlaylist(ePtr &playlist) return 0; } +RESULT eNavigation::stopService(void) +{ + /* check if there is a running service... */ + if (!m_runningService) + return 1; + /* send stop event */ + m_event(this, evStopService); + + /* kill service. */ + m_runningService = 0; + m_service_event_conn = 0; + return 0; +} + RESULT eNavigation::pause(int dop) { if (!m_runningService) diff --git a/lib/nav/core.h b/lib/nav/core.h index db43841..c049e43 100644 --- a/lib/nav/core.h +++ b/lib/nav/core.h @@ -23,7 +23,8 @@ public: evStopService, /** the "current" service was just stopped and likes to be deallocated (clear refs!) */ evNewService, /** a new "current" service was just started */ evPlayFailed, /** the next service (in playlist) or the one given in playService failed to play */ - evPlaylistDone /** the last service in the playlist was just played */ + evPlaylistDone, /** the last service in the playlist was just played */ + evUpdatedEventInfo /** the "currently running" event info was updated */ }; RESULT playService(const eServiceReference &service); @@ -32,6 +33,7 @@ public: /* int connectServiceEvent(const Slot1 &event, ePtr &connection); */ RESULT getCurrentService(ePtr &service); RESULT getPlaylist(ePtr &playlist); + RESULT stopService(void); RESULT pause(int p); eNavigation(iServiceHandler *serviceHandler); diff --git a/lib/nav/pcore.cpp b/lib/nav/pcore.cpp index 7b61ce5..2d036a1 100644 --- a/lib/nav/pcore.cpp +++ b/lib/nav/pcore.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include DEFINE_REF(pNavigation); @@ -10,6 +12,8 @@ pNavigation::pNavigation() assert(service_center); m_core = new eNavigation(service_center); + + m_core->connectEvent(slot(*this, &pNavigation::navEvent), m_nav_event_connection); } RESULT pNavigation::playService(const eServiceReference &service) @@ -36,3 +40,26 @@ RESULT pNavigation::pause(int p) { return m_core->pause(p); } + +void pNavigation::navEvent(eNavigation *nav, int event) +{ + /* just relay the events here. */ + switch (event) + { + case eNavigation::evStopService: + m_event(evStopService); + break; + case eNavigation::evNewService: + m_event(evNewService); + break; + case eNavigation::evPlayFailed: + m_event(evPlayFailed); + break; + case eNavigation::evPlaylistDone: + m_event(evPlaylistDone); + break; + case eNavigation::evUpdatedEventInfo: + m_event(evUpdatedEventInfo); + break; + } +} diff --git a/lib/nav/pcore.h b/lib/nav/pcore.h index 3bb8f4e..004bab2 100644 --- a/lib/nav/pcore.h +++ b/lib/nav/pcore.h @@ -6,13 +6,20 @@ /* a subset of eNavigation */ -class pNavigation: public iObject +class pNavigation: public iObject, public Object { DECLARE_REF; -private: - ePtr m_core; public: - PSignal1 event; + PSignal1 m_event; + + enum + { + evStopService, /** the "current" service was just stopped and likes to be deallocated (clear refs!) */ + evNewService, /** a new "current" service was just started */ + evPlayFailed, /** the next service (in playlist) or the one given in playService failed to play */ + evPlaylistDone, /** the last service in the playlist was just played */ + evUpdatedEventInfo /** the "currently running" event info was updated */ + }; pNavigation(); @@ -22,6 +29,10 @@ public: RESULT getPlaylist(ePtr &playlist); RESULT pause(int p); +private: + ePtr m_core; + ePtr m_nav_event_connection; + void navEvent(eNavigation *nav, int event); }; #endif diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 3562c3e..33fc0a1 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -29,8 +29,7 @@ Oh, things like "operator= is private in this context" etc. -is usually caused by not marking PSignals as immutable. - +is usually caused by not marking PSignals as immutable. */ %define RefCount(...) @@ -48,6 +47,7 @@ is usually caused by not marking PSignals as immutable. #include #include #include +#include #include #include @@ -61,6 +61,7 @@ is usually caused by not marking PSignals as immutable. #include #include #include +#include extern void runMainloop(); extern void quitMainloop(); @@ -73,6 +74,7 @@ RefCount(eListboxServiceContent) RefCount(eComponentScan) #define DEBUG +%include "typemaps.i" %include "stl.i" %include %include @@ -81,12 +83,13 @@ RefCount(eComponentScan) %include %include %template(eServiceCenterPtr) ePtr; +%include // TODO: embed these... %immutable eButton::selected; %immutable eComponentScan::statusChanged; -%immutable pNavigation::event; +%immutable pNavigation::m_event; %include %include @@ -103,6 +106,16 @@ RefCount(eComponentScan) %include %include %include +%include + +/************** eptr **************/ + +%template(eActionMapPtr) ePtr; +RefCount(eActionMap) +%apply eActionMapPtr OUTPUT { eActionMapPtr &ptr } +%apply eActionMap* *OUTPUT { eActionMap **ptr } + +/************** signals **************/ template class PSignal0 { diff --git a/lib/service/event.h b/lib/service/event.h index 967f9ef..094b080 100644 --- a/lib/service/event.h +++ b/lib/service/event.h @@ -1,5 +1,5 @@ -#ifndef __service_ievent_h -#define __service_ievent_h +#ifndef __lib_service_event_h +#define __lib_service_event_h #include #include @@ -18,4 +18,6 @@ public: RESULT parseFrom(Event *evt); }; +TEMPLATE_TYPEDEF(ePtr, eServiceEventPtr); + #endif diff --git a/lib/service/iservice.h b/lib/service/iservice.h index f699bdb..c58421e 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -6,14 +6,6 @@ #include #include -#ifdef SWIG -#define TEMPLATE_TYPEDEF(x, y) \ -%template(y) x; \ -typedef x y -#else -#define TEMPLATE_TYPEDEF(x, y) typedef x y -#endif - class eServiceReference { public: @@ -184,7 +176,7 @@ public: evEnd, // when iServiceInformation is implemented: - evNewEvent + evUpdatedEventInfo }; virtual RESULT connectEvent(const Slot2 &event, ePtr &connection)=0; virtual RESULT start()=0; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 06b6d97..48d00d6 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -146,6 +146,7 @@ eDVBServicePlay::~eDVBServicePlay() void eDVBServicePlay::gotNewEvent() { +#if 0 // debug only ePtr m_event_now, m_event_next; getEvent(m_event_now, 0); @@ -155,6 +156,8 @@ void eDVBServicePlay::gotNewEvent() eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration); if (m_event_next) eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration); +#endif + m_event((iPlayableService*)this, evUpdatedEventInfo); } void eDVBServicePlay::serviceEvent(int event) @@ -254,7 +257,8 @@ RESULT eDVBServicePlay::stop() RESULT eDVBServicePlay::connectEvent(const Slot2 &event, ePtr &connection) { - return -1; + connection = new eConnection((iPlayableService*)this, m_event.connect(event)); + return 0; } RESULT eDVBServicePlay::pause(ePtr &ptr) diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index 941ad7b..2e8d899 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -51,6 +51,7 @@ private: void gotNewEvent(); void serviceEvent(int event); + Signal2 m_event; public: virtual ~eDVBServicePlay(); diff --git a/main/Makefile.am b/main/Makefile.am index a8ecca4..1fdf8c3 100644 --- a/main/Makefile.am +++ b/main/Makefile.am @@ -8,6 +8,7 @@ enigma2_SOURCES = \ enigma.cpp enigma2_LDADD_WHOLE = \ + $(top_builddir)/lib/actions/libenigma_actions.a \ $(top_builddir)/lib/base/libenigma_base.a \ $(top_builddir)/lib/components/libenigma_components.a \ $(top_builddir)/lib/driver/libenigma_driver.a \ diff --git a/main/enigma.cpp b/main/enigma.cpp index b055619..6bf0bb9 100644 --- a/main/enigma.cpp +++ b/main/enigma.cpp @@ -25,6 +25,8 @@ #include +#include + #ifdef OBJECT_DEBUG int object_total_remaining; @@ -71,8 +73,11 @@ PSignal1 &keyPressedSignal() void keyEvent(const eRCKey &key) { - if (!key.flags) - keyPressed(key.code); + ePtr ptr; + eActionMap::getInstance(ptr); + ptr->keyPressed(0, key.code, key.flags); +// if (!key.flags) +// keyPressed(key.code); } /************************************************/ @@ -163,8 +168,10 @@ int main(int argc, char **argv) eRCInput::getInstance()->keyEvent.connect(slot(keyEvent)); printf("executing main\n"); + python.execute("mytest", "__main__"); + // eApp->exec(); return 0; diff --git a/mytest.py b/mytest.py index 388fcda..8015888 100644 --- a/mytest.py +++ b/mytest.py @@ -1,6 +1,7 @@ from enigma import * from tools import * + import sys import time @@ -57,38 +58,44 @@ class Session: self.dialogStack = [ ] def processDelay(self): + self.execEnd() self.currentDialog.doClose() - if self.currentWindow != None: - self.currentWindow.hide() del self.currentDialog del self.currentWindow if len(self.dialogStack): (self.currentDialog, self.currentWindow) = self.dialogStack.pop() + self.execBegin() + + def execBegin(self): + self.currentDialog.execBegin() self.currentWindow.show() + + def execEnd(self): + self.currentDialog.execEnd() + self.currentWindow.hide() + + def create(self, screen, arguments): + return screen(self, *arguments) - def open(self, screen): + def open(self, screen, *arguments): if self.currentDialog: self.dialogStack.append((self.currentDialog, self.currentWindow)) - self.currentWindow.hide() + self.execEnd() - self.currentDialog = screen - screen.session = self + self.currentDialog = self.create(screen, arguments) if self.desktop != None: - self.currentWindow = wnd = eWindow(self.desktop) -# wnd.setTitle("Screen from python!") -# wnd.move(ePoint(300, 100)) -# wnd.resize(eSize(300, 300)) + self.currentWindow = eWindow(self.desktop) gui = GUIOutputDevice() - gui.parent = wnd + gui.parent = self.currentWindow gui.create(self.currentDialog) - applyGUIskin(self.currentDialog, wnd, None, screen.__class__.__name__) + applyGUIskin(self.currentDialog, self.currentWindow, None, self.currentDialog.skinName) - wnd.show() + self.execBegin() else: self.currentWindow = None @@ -115,7 +122,7 @@ def runScreenTest(): session.nav = pNavigation() - session.open(infoBar()) + session.open(infoBar) CONNECT(keyPressedSignal(), session.keyEvent) @@ -123,6 +130,8 @@ def runScreenTest(): return 0 +import keymapparser +keymapparser.readKeymap() # first, setup a screen runScreenTest() diff --git a/screens.py b/screens.py index 39b4265..cf0daae 100644 --- a/screens.py +++ b/screens.py @@ -8,6 +8,19 @@ def doGlobal(screen): class Screen(dict, HTMLSkin, GUISkin): """ bla """ + + def __init__(self, session): + self.skinName = self.__class__.__name__ + self.session = session + GUISkin.__init__(self) + + def execBegin(self): + for (name, val) in self.items(): + val.execBegin() + + def execEnd(self): + for (name, val) in self.items(): + val.execEnd() # never call this directly - it will be called from the session! def doClose(self): @@ -15,7 +28,7 @@ class Screen(dict, HTMLSkin, GUISkin): def close(self, retval=None): self.session.close() - + class mainMenu(Screen): def goEmu(self): @@ -28,19 +41,24 @@ class mainMenu(Screen): self["title"].setText("HDTV GREEN FLASHES: ENABLED") def goScan(self): - self.session.open(serviceScan()) + self.session.open(serviceScan) def goClock(self): - self.session.open(clockDisplay(Clock())) + self.session.open(clockDisplay, Clock()) def okbuttonClick(self): selection = self["menu"].getCurrent() selection[1]() - - def __init__(self): - GUISkin.__init__(self) + + def __init__(self, session): + Screen.__init__(self, session) b = Button("ok") + self["actions"] = ActionMap("MainMenuActions", + { + "selected": self.okbuttonClick + }) + b.onClick = [ self.okbuttonClick ] self["okbutton"] = b self["title"] = Header("Main Menu! - press ok to leave!") @@ -64,38 +82,54 @@ class mainMenu(Screen): # self["okbutton"].onClick = [ self.close ] class channelSelection(Screen): - def __init__(self): - GUISkin.__init__(self) + def __init__(self, session): + Screen.__init__(self, session) self["list"] = ServiceList() self["list"].setRoot(eServiceReference("1:0:1:0:0:0:0:0:0:0:PREMIERE")) - self["okbutton"] = Button("ok", [self.channelSelected, self.close]) + self["okbutton"] = Button("ok", [self.channelSelected]) + + self["actions"] = ActionMap("ChannelSelectActions", + { + "selectChannel": self.channelSelected, + }) def channelSelected(self): self.session.nav.playService(self["list"].getCurrent()) + self.close() pass class infoBar(Screen): - def __init__(self): - GUISkin.__init__(self) + def __init__(self, session): + Screen.__init__(self, session) + self["actions"] = ActionMap("InfobarActions", + { + "switchChannel": self.switchChannel, + "mainMenu": self.mainMenu + }) self["channelSwitcher"] = Button("switch Channel", [self.switchChannel]) self["okbutton"] = Button("mainMenu", [self.mainMenu]) + + self["ServiceName"] = ServiceName(self.session.nav) + + self["Event_Now"] = EventInfo(self.session.nav, EventInfo.Now) + self["Event_Next"] = EventInfo(self.session.nav, EventInfo.Next) def mainMenu(self): - self.session.open(mainMenu()) + self.session.open(mainMenu) def switchChannel(self): - self.session.open(channelSelection()) + self.session.open(channelSelection) # a clock display dialog class clockDisplay(Screen): def okbutton(self): self.session.close() - def __init__(self, clock): - GUISkin.__init__(self) + def __init__(self, session, clock): + Screen.__init__(self, session) self["theClock"] = clock b = Button("bye") b.onClick = [ self.okbutton ] @@ -108,8 +142,8 @@ class serviceScan(Screen): if self["scan"].isDone(): self.close() - def __init__(self): - GUISkin.__init__(self) + def __init__(self, session): + Screen.__init__(self, session) self["scan_progress"] = ProgressBar() self["scan_state"] = Label("scan state") diff --git a/skin.py b/skin.py index 5684c58..46a1429 100644 --- a/skin.py +++ b/skin.py @@ -25,6 +25,9 @@ dom = xml.dom.minidom.parseString( + + + -- 2.7.4