diff options
| author | Andreas Monzner <andreas.monzner@multimedia-labs.de> | 2007-11-22 22:18:50 +0000 |
|---|---|---|
| committer | Andreas Monzner <andreas.monzner@multimedia-labs.de> | 2007-11-22 22:18:50 +0000 |
| commit | e6fc6c4c345bee12b57a76392abf95c92b29aa3b (patch) | |
| tree | 153169a8ef29c5fd7be3b4b218d3ac20e0089733 /lib/mmi | |
| parent | 76fe69e113637a200aafdc2d6dede772706e4b09 (diff) | |
| download | enigma2-e6fc6c4c345bee12b57a76392abf95c92b29aa3b.tar.gz enigma2-e6fc6c4c345bee12b57a76392abf95c92b29aa3b.zip | |
make MMI code more reusable
Diffstat (limited to 'lib/mmi')
| -rw-r--r-- | lib/mmi/Makefile.am | 6 | ||||
| -rw-r--r-- | lib/mmi/mmi_ui.cpp | 314 | ||||
| -rw-r--r-- | lib/mmi/mmi_ui.h | 57 |
3 files changed, 377 insertions, 0 deletions
diff --git a/lib/mmi/Makefile.am b/lib/mmi/Makefile.am new file mode 100644 index 00000000..020c988e --- /dev/null +++ b/lib/mmi/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = \ + -I$(top_srcdir)/include + +noinst_LIBRARIES = libenigma_mmi.a + +libenigma_mmi_a_SOURCES = mmi_ui.cpp diff --git a/lib/mmi/mmi_ui.cpp b/lib/mmi/mmi_ui.cpp new file mode 100644 index 00000000..54b220cf --- /dev/null +++ b/lib/mmi/mmi_ui.cpp @@ -0,0 +1,314 @@ +#include <lib/mmi/mmi_ui.h> +#include <lib/dvb_ci/dvbci_session.h> // for parseLengthField + +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +#include <lib/base/init.h> +#include <lib/base/init_num.h> +#include <lib/base/eerror.h> +#include <lib/base/estring.h> + +eMMI_UI::eMMI_UI(int max_slots) + :m_max_slots(max_slots) +{ + slotdata = new slot_ui_data[m_max_slots]; + for(int i=0;i<m_max_slots;++i) + { + slotdata[i].mmiScreenReady=0; + slotdata[i].mmiTuplePos=0; + slotdata[i].state=-1; + } +} + +eMMI_UI::~eMMI_UI() +{ + for(int i=0;i<m_max_slots;++i) + { + if (slotdata[i].mmiScreen) + Py_DECREF(slotdata[i].mmiScreen); + } + delete [] slotdata; +} + +int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *data, int len) +{ + switch (tag[2]) + { + case 0x00: //Tmmi_close + { + unsigned char *d=(unsigned char*)data; + int timeout=0; + if (d[3] == 1) + { + if (len > 4) + timeout = d[4]; + else + { + eDebug("mmi close tag incorrect.. no timeout given.. assume 5 seconds"); + timeout = 5; + } + } + else if (d[3] > 1) + eDebug("mmi close tag incorrect.. byte 4 should be 0 or 1"); + mmiScreenClose(slot_id, timeout); + break; + } + case 0x01: + eDebug("MMI display control"); + if (((unsigned char*)data)[0] != 1) + eDebug("kann ich nicht. aber das sag ich dem modul nicht."); + return 1; + case 0x07: //Tmenu_enq + { + unsigned char *d=(unsigned char*)data; + unsigned char *max=((unsigned char*)d) + len; + int textlen = len - 2; + eDebug("in enq"); + if ((d+2) > max) + break; + int blind = *d++ & 1; + int alen = *d++; + eDebug("%d bytes text", textlen); + if ((d+textlen) > max) + break; + char str[textlen + 1]; + memcpy(str, ((char*)d), textlen); + str[textlen] = '\0'; + eDebug("enq-text: %s",str); + mmiScreenEnq(slot_id, blind, alen, (char*)convertDVBUTF8(str).c_str()); + break; + } + case 0x09: //Tmenu_last + case 0x0c: //Tlist_last + { + unsigned char *d=(unsigned char*)data; + unsigned char *max=((unsigned char*)d) + len; + int pos = 0; + eDebug("Tmenu_last"); + if (d > max) + break; + int n=*d++; + if(tag[2] == 0x09) //menu + mmiScreenBegin(slot_id, 0); + else //list + mmiScreenBegin(slot_id, 1); + if (n == 0xFF) + n=0; + else + n++; + eDebug("%d texts", n); + for (int i=0; i < (n+3); ++i) + { + int textlen; + if ((d+3) > max) + break; + eDebug("text tag: %02x %02x %02x", d[0], d[1], d[2]); + d+=3; + d+=eDVBCISession::parseLengthField(d, textlen); + eDebug("%d bytes text", textlen); + if ((d+textlen) > max) + break; + char str[textlen + 1]; + memcpy(str, ((char*)d), textlen); + str[textlen] = '\0'; + mmiScreenAddText(slot_id, pos++, (char*)convertDVBUTF8(str).c_str()); + while (textlen--) + eDebugNoNewLine("%c", *d++); + eDebug(""); + } + mmiScreenFinish(slot_id); + break; + } + default: + eDebug("unknown APDU tag 9F 88 %02x", tag[2]); + break; + } + return 0; +} + +int eMMI_UI::getState(int slot) +{ + if (slot < m_max_slots) + return slotdata[slot].state; + return 0; +} + +void eMMI_UI::setState(int slot, int newState) +{ + if (slot < m_max_slots) + { + slotdata[slot].state = newState; + stateChanged(slot); + } +} + +std::string eMMI_UI::getAppName(int slot) +{ + if (slot < m_max_slots) + return slotdata[slot].appName; + return ""; +} + +void eMMI_UI::setAppName(int slot, const char *name) +{ + if (slot < m_max_slots) + slotdata[slot].appName = name; +} + +int eMMI_UI::availableMMI(int slot) +{ + if (slot < m_max_slots) + return slotdata[slot].mmiScreenReady; + return false; +} + +int eMMI_UI::mmiScreenClose(int slot, int timeout) +{ + if (slot >= m_max_slots) + return 0; + + slot_ui_data &data = slotdata[slot]; + + data.mmiScreenReady = 0; + + if (data.mmiScreen) + Py_DECREF(data.mmiScreen); + data.mmiScreen = PyList_New(1); + + ePyObject tuple = PyTuple_New(2); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("CLOSE")); + PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(timeout)); + PyList_SET_ITEM(data.mmiScreen, 0, tuple); + data.mmiScreenReady = 1; + stateChanged(slot); + return 0; +} + +int eMMI_UI::mmiScreenEnq(int slot, int blind, int answerLen, char *text) +{ + if (slot >= m_max_slots) + return 0; + + slot_ui_data &data = slotdata[slot]; + + data.mmiScreenReady = 0; + + if (data.mmiScreen) + Py_DECREF(data.mmiScreen); + data.mmiScreen = PyList_New(2); + + ePyObject tuple = PyTuple_New(1); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("ENQ")); + PyList_SET_ITEM(data.mmiScreen, 0, tuple); + + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("PIN")); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(answerLen)); + PyTuple_SET_ITEM(tuple, 2, PyString_FromString(text)); + PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(blind)); + + PyList_SET_ITEM(data.mmiScreen, 1, tuple); + + data.mmiScreenReady = 1; + + stateChanged(slot); + + return 0; +} + +int eMMI_UI::mmiScreenBegin(int slot, int listmenu) +{ + if (slot >= m_max_slots) + return 0; + + eDebug("eMMI_UI::mmiScreenBegin"); + + slot_ui_data &data = slotdata[slot]; + + data.mmiScreenReady = 0; + + if (data.mmiScreen) + Py_DECREF(data.mmiScreen); + + data.mmiScreen = PyList_New(1); + + ePyObject tuple = PyTuple_New(1); + if (listmenu == 0) //menu + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("MENU")); + else //list + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("LIST")); + + PyList_SET_ITEM(data.mmiScreen, 0, tuple); + + data.mmiTuplePos = 1; + + return 0; +} + +int eMMI_UI::mmiScreenAddText(int slot, int type, char *value) +{ + if (slot >= m_max_slots) + return 0; + + eDebug("eMMI_UI::mmiScreenAddText(%s)",value ? value : ""); + + slot_ui_data &data = slotdata[slot]; + + ePyObject tuple = PyTuple_New(3); + + if (type == 0) //title + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("TITLE")); + else if (type == 1) //subtitle + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("SUBTITLE")); + else if (type == 2) //bottom + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("BOTTOM")); + else + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("TEXT")); + + eDebug("addText %s with id %d", value, type); + + PyTuple_SET_ITEM(tuple, 1, PyString_FromString(value)); + + if (type > 2) + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(type-2)); + else + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(-1)); + + PyList_Append(data.mmiScreen, tuple); + Py_DECREF(tuple); + + return 0; +} + +int eMMI_UI::mmiScreenFinish(int slot) +{ + if (slot < m_max_slots) + { + eDebug("eMMI_UI::mmiScreenFinish"); + slotdata[slot].mmiScreenReady = 1; + stateChanged(slot); + } + return 0; +} + +void eMMI_UI::mmiSessionDestroyed(int slot) +{ + stateChanged(slot); +} + +PyObject *eMMI_UI::getMMIScreen(int slot) +{ + if (slot < m_max_slots) + { + slot_ui_data &data = slotdata[slot]; + if (data.mmiScreenReady) + { + data.mmiScreenReady = 0; + Py_INCREF(data.mmiScreen); + return data.mmiScreen; + } + } + Py_RETURN_NONE; +} diff --git a/lib/mmi/mmi_ui.h b/lib/mmi/mmi_ui.h new file mode 100644 index 00000000..d43dc704 --- /dev/null +++ b/lib/mmi/mmi_ui.h @@ -0,0 +1,57 @@ +#ifndef __mmi_ui_h +#define __mmi_ui_h + +#include <string> + /* avoid warnigs :) */ +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#include <lib/python/python.h> + +#ifndef SWIG +struct slot_ui_data +{ + std::string appName; + int state; + ePyObject mmiScreen; + int mmiTuplePos; + int mmiScreenReady; +}; +#endif + +class eMMI_UI: public Object +{ + int m_max_slots; + virtual void stateChanged(int)=0; +protected: + slot_ui_data *slotdata; + eMMI_UI(int max_slots); + virtual ~eMMI_UI(); +public: + int getState(int slot); + void setState(int slot, int state); + std::string getAppName(int slot); + void setAppName(int slot, const char *name); +#ifndef SWIG + virtual void setInit(int slot)=0; + virtual void setReset(int slot)=0; + virtual int startMMI(int slot)=0; + virtual int stopMMI(int slot)=0; + virtual int answerMenu(int slot, int answer)=0; + virtual int answerEnq(int slot, char *val)=0; + virtual int cancelEnq(int slot)=0; + virtual int getMMIState(int slot)=0; +#endif + int availableMMI(int slot); + PyObject *getMMIScreen(int slot); +#ifndef SWIG + int processMMIData(int slot, const unsigned char *tag, const void *data, int len); + int mmiScreenClose(int slot, int timeout); + int mmiScreenEnq(int slot, int blind, int answerLen, char *text); + int mmiScreenBegin(int slot, int listmenu); + int mmiScreenAddText(int slot, int type, char *value); + int mmiScreenFinish(int slot); + void mmiSessionDestroyed(int slot); +#endif +}; + +#endif |
