From: hschang Date: Thu, 24 Nov 2016 03:50:07 +0000 (+0900) Subject: Support Uno4k/Ultimo4k X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=4911a0121954f6b6657ba28fab8d9dd9031d9a59 Support Uno4k/Ultimo4k - Fix FCC for uno4k/ultimo4k - Fix APIs to support 1080p skin - Support HDMI colordepth (VideoMode) - Support TT2L08 automatic scan --- diff --git a/ServiceReference.py b/ServiceReference.py index 0a46992..401e47a 100644 --- a/ServiceReference.py +++ b/ServiceReference.py @@ -32,4 +32,4 @@ class ServiceReference(eServiceReference): def isRecordable(self): ref = self.ref - return ref.flags & eServiceReference.isGroup or (ref.type == eServiceReference.idDVB) \ No newline at end of file + return ref.flags & eServiceReference.isGroup or (ref.type == eServiceReference.idDVB) or (ref.type == 0x2000) \ No newline at end of file diff --git a/configure.ac b/configure.ac index 7c52d00..00a4bd2 100644 --- a/configure.ac +++ b/configure.ac @@ -308,6 +308,8 @@ lib/python/Plugins/SystemPlugins/Solo4kMiscControl/Makefile lib/python/Plugins/SystemPlugins/Solo4kMiscControl/meta/Makefile lib/python/Plugins/SystemPlugins/FastChannelChange/Makefile lib/python/Plugins/SystemPlugins/FastChannelChange/meta/Makefile +lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/Makefile +lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/Makefile lib/python/Tools/Makefile lib/service/Makefile lib/components/Makefile diff --git a/data/startwizard.xml b/data/startwizard.xml index db04392..5ed6413 100755 --- a/data/startwizard.xml +++ b/data/startwizard.xml @@ -48,8 +48,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 2 and not nimmanager.nim_slots[2].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[2]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 2 and not nimmanager.nim_slots[2].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[2].slot) @@ -62,8 +62,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 3 and not nimmanager.nim_slots[3].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[3]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 3 and not nimmanager.nim_slots[3].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[3].slot) @@ -76,8 +76,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 4 and not nimmanager.nim_slots[4].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[4]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 4 and not nimmanager.nim_slots[4].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[4].slot) @@ -90,8 +90,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 5 and not nimmanager.nim_slots[5].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[5]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 5 and not nimmanager.nim_slots[5].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[5].slot) @@ -104,8 +104,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 6 and not nimmanager.nim_slots[6].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[6]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 6 and not nimmanager.nim_slots[6].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[6].slot) @@ -118,8 +118,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 7 and not nimmanager.nim_slots[7].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[7]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 7 and not nimmanager.nim_slots[7].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[7].slot) @@ -132,8 +132,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 8 and not nimmanager.nim_slots[8].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[8]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 8 and not nimmanager.nim_slots[8].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[8].slot) @@ -146,8 +146,8 @@ self.selectKey("RIGHT") from Components.NimManager import nimmanager -from Screens.Satconfig import isFBCLink -self.condition = len(nimmanager.nim_slots) > 9 and not nimmanager.nim_slots[9].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[9]) +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 9 and not nimmanager.nim_slots[9].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[9].slot) @@ -157,6 +157,34 @@ self.selectKey("LEFT") self.selectKey("RIGHT") + + +from Components.NimManager import nimmanager +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 16 and not nimmanager.nim_slots[16].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[16].slot) + + + + +self.clearSelectedKeys() +self.selectKey("LEFT") +self.selectKey("RIGHT") + + + + +from Components.NimManager import nimmanager +from enigma import isFBCLink +self.condition = len(nimmanager.nim_slots) > 17 and not nimmanager.nim_slots[17].empty and config.misc.startwizard.shownimconfig.value and not isFBCLink(nimmanager.nim_slots[17].slot) + + + + +self.clearSelectedKeys() +self.selectKey("LEFT") +self.selectKey("RIGHT") + + diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index e3d97af..2c8044b 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -42,6 +42,13 @@ #define VIDEO_GET_PTS _IOR('o', 57, __u64) #endif +#ifndef VIDEO_SOURCE_HDMI +#define VIDEO_SOURCE_HDMI 2 +#endif +#ifndef AUDIO_SOURCE_HDMI +#define AUDIO_SOURCE_HDMI 2 +#endif + DEFINE_REF(eDVBAudio); eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev) @@ -51,19 +58,31 @@ eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev) #if HAVE_DVB_API_VERSION < 3 sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev); #else - sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev); + sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux ? demux->adapter : 0, dev); #endif m_fd = ::open(filename, O_RDWR); if (m_fd < 0) eWarning("%s: %m", filename); + if (demux) + { #if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); + sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); #else - sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); + sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); #endif - m_fd_demux = ::open(filename, O_RDWR); - if (m_fd_demux < 0) - eWarning("%s: %m", filename); + m_fd_demux = ::open(filename, O_RDWR); + if (m_fd_demux < 0) + eWarning("%s: %m", filename); + } + else + { + m_fd_demux = -1; + } + + if (m_fd >= 0) + { + ::ioctl(m_fd, AUDIO_SELECT_SOURCE, demux ? AUDIO_SOURCE_DEMUX : AUDIO_SOURCE_HDMI); + } } #if HAVE_DVB_API_VERSION < 3 @@ -160,89 +179,101 @@ int eDVBAudio::setAVSync(int val) #else int eDVBAudio::startPid(int pid, int type) { - if ((m_fd < 0) || (m_fd_demux < 0)) - return -1; - dmx_pes_filter_params pes; - - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */ - pes.flags = 0; - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) - { - eDebug("failed (%m)"); - return -errno; - } - eDebug("ok"); - eDebugNoNewLine("DEMUX_START - audio - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) + if (m_fd_demux >= 0) { - eDebug("failed (%m)"); - return -errno; + dmx_pes_filter_params pes; + + pes.pid = pid; + pes.input = DMX_IN_FRONTEND; + pes.output = DMX_OUT_DECODER; + pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */ + pes.flags = 0; + eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid); + if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); + eDebugNoNewLine("DEMUX_START - audio - "); + if (::ioctl(m_fd_demux, DMX_START) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); } - eDebug("ok"); - int bypass = 0; - switch (type) + if (m_fd >= 0) { - case aMPEG: - bypass = 1; - break; - case aAC3: - bypass = 0; - break; - case aDTS: - bypass = 2; - break; - case aAAC: - bypass = 8; - break; - case aAACHE: - bypass = 9; - break; - case aLPCM: - bypass = 6; - break; - case aDTSHD: - bypass = 0x10; - break; - case aDDP: - bypass = 0x22; - break; + int bypass = 0; - } + switch (type) + { + case aMPEG: + bypass = 1; + break; + case aAC3: + bypass = 0; + break; + case aDTS: + bypass = 2; + break; + case aAAC: + bypass = 8; + break; + case aAACHE: + bypass = 9; + break; + case aLPCM: + bypass = 6; + break; + case aDTSHD: + bypass = 0x10; + break; + case aDDP: + bypass = 0x22; + break; - eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass); - if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState - eDebugNoNewLine("AUDIO_PLAY - "); - if (::ioctl(m_fd, AUDIO_PLAY) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); + } + + eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass); + if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState + eDebugNoNewLine("AUDIO_PLAY - "); + if (::ioctl(m_fd, AUDIO_PLAY) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + } return 0; } #endif void eDVBAudio::stop() { - eDebugNoNewLine("AUDIO_STOP - "); - if (::ioctl(m_fd, AUDIO_STOP) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); + if (m_fd >= 0) + { + eDebugNoNewLine("AUDIO_STOP - "); + if (::ioctl(m_fd, AUDIO_STOP) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + } + + if (m_fd_demux >= 0) + { #if HAVE_DVB_API_VERSION > 2 - eDebugNoNewLine("DEMUX_STOP - audio - "); - if (::ioctl(m_fd_demux, DMX_STOP) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); + eDebugNoNewLine("DEMUX_STOP - audio - "); + if (::ioctl(m_fd_demux, DMX_STOP) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); #endif + } } void eDVBAudio::flush() @@ -317,7 +348,7 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev, bool fcc_enable) if (m_fd_video < 0) eWarning("/dev/video: %m"); #else - sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev); + sprintf(filename, "/dev/dvb/adapter%d/video%d", demux ? demux->adapter : 0, dev); #endif m_fd = ::open(filename, O_RDWR); if (m_fd < 0) @@ -328,15 +359,30 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev, bool fcc_enable) CONNECT(m_sn->activated, eDVBVideo::video_event); } eDebug("Video Device: %s", filename); + + + + if (demux) + { #if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); + sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); #else - sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); + sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); #endif - m_fd_demux = ::open(filename, O_RDWR); - if (m_fd_demux < 0) - eWarning("%s: %m", filename); - eDebug("demux device: %s", filename); + m_fd_demux = ::open(filename, O_RDWR); + if (m_fd_demux < 0) + eWarning("%s: %m", filename); + eDebug("demux device: %s", filename); + } + else + { + m_fd_demux = -1; + } + + if (m_fd >= 0) + { + ::ioctl(m_fd, VIDEO_SELECT_SOURCE, demux ? VIDEO_SOURCE_DEMUX : VIDEO_SOURCE_HDMI); + } } // not finally values i think.. !! @@ -408,71 +454,79 @@ int eDVBVideo::stopPid() #else int eDVBVideo::startPid(int pid, int type) { - int streamtype = VIDEO_STREAMTYPE_MPEG2; - if (m_fcc_enable) return 0; - if ((m_fd < 0) || (m_fd_demux < 0)) - return -1; - dmx_pes_filter_params pes; - - switch(type) + if (m_fd >= 0) { - default: - case MPEG2: - break; - case MPEG4_H264: - streamtype = VIDEO_STREAMTYPE_MPEG4_H264; - break; - case MPEG1: - streamtype = VIDEO_STREAMTYPE_MPEG1; - break; - case MPEG4_Part2: - streamtype = VIDEO_STREAMTYPE_MPEG4_Part2; - break; - case VC1: - streamtype = VIDEO_STREAMTYPE_VC1; - break; - case VC1_SM: - streamtype = VIDEO_STREAMTYPE_VC1_SM; - break; - case H265_HEVC: - streamtype = VIDEO_STREAMTYPE_H265_HEVC; - break; - } + int streamtype = VIDEO_STREAMTYPE_MPEG2; + switch(type) + { + default: + case MPEG2: + break; + case MPEG4_H264: + streamtype = VIDEO_STREAMTYPE_MPEG4_H264; + break; + case MPEG1: + streamtype = VIDEO_STREAMTYPE_MPEG1; + break; + case MPEG4_Part2: + streamtype = VIDEO_STREAMTYPE_MPEG4_Part2; + break; + case VC1: + streamtype = VIDEO_STREAMTYPE_VC1; + break; + case VC1_SM: + streamtype = VIDEO_STREAMTYPE_VC1_SM; + break; + case H265_HEVC: + streamtype = VIDEO_STREAMTYPE_H265_HEVC; + break; + } - eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype); - if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); + eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype); + if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + + } - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */ - pes.flags = 0; - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + if (m_fd_demux >= 0) { - eDebug("failed (%m)"); - return -errno; + dmx_pes_filter_params pes; + + pes.pid = pid; + pes.input = DMX_IN_FRONTEND; + pes.output = DMX_OUT_DECODER; + pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */ + pes.flags = 0; + eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid); + if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); + eDebugNoNewLine("DEMUX_START - video - "); + if (::ioctl(m_fd_demux, DMX_START) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); } - eDebug("ok"); - eDebugNoNewLine("DEMUX_START - video - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) + + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; + freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState + eDebugNoNewLine("VIDEO_PLAY - "); + if (::ioctl(m_fd, VIDEO_PLAY) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - eDebug("ok"); - freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState - eDebugNoNewLine("VIDEO_PLAY - "); - if (::ioctl(m_fd, VIDEO_PLAY) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); return 0; } #endif @@ -482,18 +536,25 @@ void eDVBVideo::stop() if (m_fcc_enable) return; + if (m_fd_demux >= 0) + { #if HAVE_DVB_API_VERSION > 2 - eDebugNoNewLine("DEMUX_STOP - video - "); - if (::ioctl(m_fd_demux, DMX_STOP) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); + eDebugNoNewLine("DEMUX_STOP - video - "); + if (::ioctl(m_fd_demux, DMX_STOP) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); #endif - eDebugNoNewLine("VIDEO_STOP - "); - if (::ioctl(m_fd, VIDEO_STOP, 1) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); + } + + if (m_fd >= 0) + { + eDebugNoNewLine("VIDEO_STOP - "); + if (::ioctl(m_fd, VIDEO_STOP, 1) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + } } void eDVBVideo::flush() @@ -1113,7 +1174,10 @@ eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder) m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp)), m_fcc_fd(-1), m_fcc_enable(false), m_fcc_state(fcc_state_stop), m_fcc_feid(-1), m_fcc_vpid(-1), m_fcc_vtype(-1), m_fcc_pcrpid(-1) { - demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); + if (m_demux) + { + demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); + } CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic); m_state = stateStop; } diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index b677275..1af2a10 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -58,12 +58,10 @@ typedef enum { #include "crc32.h" #include -#include #include #include #include #include -#include eDVBDemux::eDVBDemux(int adapter, int demux): adapter(adapter), demux(demux) { @@ -151,9 +149,9 @@ RESULT eDVBDemux::createTSRecorder(ePtr &recorder) return 0; } -RESULT eDVBDemux::getMPEGDecoder(ePtr &decoder, int primary) +RESULT eDVBDemux::getMPEGDecoder(ePtr &decoder, int index) { - decoder = new eTSMPEGDecoder(this, primary ? 0 : 1); + decoder = new eTSMPEGDecoder(this, index); return 0; } @@ -447,26 +445,6 @@ RESULT eDVBPESReader::connectRead(const Slot2 &r, ePtr #include +#include +#include class eDVBDemux: public iDVBDemux { @@ -83,7 +85,25 @@ public: RESULT connectRead(const Slot2 &read, ePtr &conn); }; -class eDVBRecordFileThread; +class eDVBRecordFileThread: public eFilePushThread +{ +public: + eDVBRecordFileThread(); + void setTimingPID(int pid, int type); + + void startSaveMetaInformation(const std::string &filename); + void stopSaveMetaInformation(); + void enableAccessPoints(bool enable); + int getLastPTS(pts_t &pts); +protected: + int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining); +private: + eMPEGStreamParserTS m_ts_parser; + eMPEGStreamInformation m_stream_info; + off_t m_current_offset; + pts_t m_last_pcr; /* very approximate.. */ + int m_pid; +}; class eDVBTSRecorder: public iDVBTSRecorder, public Object { diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp old mode 100755 new mode 100644 index 012a834..756c685 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -34,7 +34,7 @@ eDVBAllocatedFrontend::~eDVBAllocatedFrontend() eFBCTunerManager* fbcmng = eFBCTunerManager::getInstance(); if (fbcmng) { - fbcmng->unset(m_fe); + fbcmng->unLink(m_fe); } } } @@ -126,6 +126,8 @@ eDVBResourceManager::eDVBResourceManager() eDVBCAService::registerChannelCallback(this); + m_fbc_mng = new eFBCTunerManager(this); + CONNECT(m_releaseCachedChannelTimer->timeout, eDVBResourceManager::releaseCachedChannel); } @@ -433,26 +435,34 @@ void eDVBResourceManager::setFrontendType(int index, const char *type) RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, ePtr &feparm, bool simulate) { eSmartPtrList &frontends = simulate ? m_simulate_frontend : m_frontend; -// ePtr best; eDVBRegisteredFrontend *best = NULL; int bestval = 0; int foundone = 0; - int check_fbc_linked = 0; + int check_fbc_leaf_linkable = 0; + int current_fbc_setid = -1; eDVBRegisteredFrontend *fbc_fe = NULL; eDVBRegisteredFrontend *best_fbc_fe = NULL; - eFBCTunerManager* fbcmng = eFBCTunerManager::getInstance(); for (eSmartPtrList::iterator i(frontends.begin()); i != frontends.end(); ++i) { int c = 0; fbc_fe = NULL; - if (!check_fbc_linked && i->m_frontend->is_FBCTuner() && fbcmng && fbcmng->canLink(*i)) + if (i->m_frontend->is_FBCTuner() && m_fbc_mng->canLink(*i)) { - check_fbc_linked = 1; - c = fbcmng->isCompatibleWith(feparm, *i, fbc_fe, simulate); + int fbc_setid = m_fbc_mng->getFBCSetID(i->m_frontend->getSlotID()); + if (fbc_setid != current_fbc_setid) + { + current_fbc_setid = fbc_setid; + check_fbc_leaf_linkable = 0; + } -// eDebug("[eDVBResourceManager::allocateFrontend] fbcmng->isCompatibleWith slotid : %p (%d), fbc_fe : %p (%d), score : %d", (eDVBRegisteredFrontend *)*i, i->m_frontend->getSlotID(), fbc_fe, fbc_fe?fbc_fe->m_frontend->getSlotID():-1, c); + if (!check_fbc_leaf_linkable) + { + c = m_fbc_mng->isCompatibleWith(feparm, *i, fbc_fe, simulate); + check_fbc_leaf_linkable = 1; + eDebug("[eDVBResourceManager::allocateFrontend] m_fbc_mng->isCompatibleWith slotid : %p (%d), fbc_fe : %p (%d), score : %d", (eDVBRegisteredFrontend *)*i, i->m_frontend->getSlotID(), fbc_fe, fbc_fe?fbc_fe->m_frontend->getSlotID():-1, c); + } } else { @@ -464,18 +474,17 @@ RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, eP if (!i->m_inuse) { -// eDebug("Slot %d, score %d", i->m_frontend->getSlotID(), c); + eDebug("Slot %d, score %d", i->m_frontend->getSlotID(), c); if (c > bestval) { bestval = c; -// best = i; best = *i; best_fbc_fe = fbc_fe; } } else { -// eDebug("Slot %d, score %d... but BUSY!!!!!!!!!!!", i->m_frontend->getSlotID(), c); + eDebug("Slot %d, score %d... but BUSY!!!!!!!!!!!", i->m_frontend->getSlotID(), c); } eDVBRegisteredFrontend *tmp = *i; @@ -483,9 +492,9 @@ RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, eP if (best) { - if (fbcmng && best_fbc_fe) + if (best_fbc_fe) { - fbcmng->addLink(best, best_fbc_fe, simulate); + m_fbc_mng->addLink(best, best_fbc_fe, simulate); } fe = new eDVBAllocatedFrontend(best); @@ -911,18 +920,29 @@ int eDVBResourceManager::canAllocateFrontend(ePtr &fepar eSmartPtrList &frontends = simulate ? m_simulate_frontend : m_frontend; ePtr best; int bestval = 0; - int check_fbc_link = 0; - eFBCTunerManager *fbcmng = eFBCTunerManager::getInstance(); + int check_fbc_leaf_linkable = 0; + int current_fbc_setid = -1; for (eSmartPtrList::iterator i(frontends.begin()); i != frontends.end(); ++i) { if (!i->m_inuse) { int c = 0; - if(fbcmng && i->m_frontend->is_FBCTuner() && fbcmng->canLink(*i) && !check_fbc_link) + if (i->m_frontend->is_FBCTuner() && m_fbc_mng->canLink(*i)) { - check_fbc_link = 1; - c = fbcmng->isCompatibleWith(feparm, *i, simulate); + int fbc_setid = m_fbc_mng->getFBCSetID(i->m_frontend->getSlotID()); + if (fbc_setid != current_fbc_setid) + { + current_fbc_setid = fbc_setid; + check_fbc_leaf_linkable = 0; + } + + if (!check_fbc_leaf_linkable) + { + eDVBRegisteredFrontend *dummy; + c = m_fbc_mng->isCompatibleWith(feparm, *i, dummy, simulate); + check_fbc_leaf_linkable = 1; + } } else { diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index fa1e8a1..c0acc4f 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -159,6 +159,8 @@ class eDVBResourceManager: public iObject, public Object ePtr m_list; ePtr m_sec; static eDVBResourceManager *instance; + + ePtr m_fbc_mng; friend class eDVBChannel; friend class eFBCTunerManager; diff --git a/lib/dvb/fbc.cpp b/lib/dvb/fbc.cpp index dc70c05..9dd66b0 100644 --- a/lib/dvb/fbc.cpp +++ b/lib/dvb/fbc.cpp @@ -7,8 +7,6 @@ #include #include -#define FE_SLOT_ID(fe) fe->m_frontend->getSlotID() - //#define FBC_DEBUG #ifdef FBC_DEBUG @@ -17,132 +15,241 @@ #define eFecDebug(arg...) #endif +static int getProcData(const char* filename) +{ + int res = -1; + FILE *fp = fopen(filename,"r"); + if(fp) + { + fscanf(fp, "%d", &res); + fclose(fp); + } + else + { + eFecDebug("[*][eFBCTunerManager::getProcData] open failed, %s: %m", filename); + } + return res; +} -DEFINE_REF(eFBCTunerManager); - -bool eFBCTunerManager::isDestroyed = false; - -eFBCTunerManager::eFBCTunerManager() +static void setProcData(const char* filename, int value) { - ePtr res_mgr; - eDVBResourceManager::getInstance(res_mgr); - m_res_mgr = res_mgr; + eDebug("[*] setProcData %s -> %d", filename, value); + FILE *fp = fopen(filename, "w"); + if(fp) + { + fprintf(fp, "%d", value); + fclose(fp); + } + else + { + eFecDebug("[*][eFBCTunerManager::setProcData] open failed, %s: %m", filename); + } +} - /* num of fbc tuner in one set */ - m_fbc_tuner_num = getFBCTunerNum(); - procInit(); +static void loadConnectChoices(const char* filename, bool *connect_choices) +{ + FILE *fp = fopen(filename,"r"); + if(fp) + { + int c; + while(EOF != (c = fgetc(fp))) + { + if(isdigit(c)) + connect_choices[c - '0'] = true; + } + fclose(fp); + } + else + { + eFecDebug("[*][eFBCTunerManager::LoadFbcRootChoices] open failed, %s: %m", filename); + } } -eFBCTunerManager::~eFBCTunerManager() + +DEFINE_REF(eFBCTunerManager); + +eFBCTunerManager* eFBCTunerManager::m_instance = (eFBCTunerManager*)0; + +eFBCTunerManager* eFBCTunerManager::getInstance() { - isDestroyed = true; + return m_instance; } -void eFBCTunerManager::procInit() +eFBCTunerManager::eFBCTunerManager(ePtr res_mgr) + :m_res_mgr(res_mgr) { + if (!m_instance) + m_instance = this; + eSmartPtrList &frontends = m_res_mgr->m_frontend; - /* 1 FBC set has 8 tuners. */ - /* 1st set : 0, 1, 2, 3, 4, 5, 6, 7 */ - /* 2nd set : 8, 9, 10, 11, 12, 13, 14, 15 */ - /* 1st, 2nd frontend is top on a set */ + /* each FBC set has 8 tuners. */ + /* first set : 0, 1, 2, 3, 4, 5, 6, 7 */ + /* second set : 8, 9, 10, 11, 12, 13, 14, 15 */ + /* first, second frontend is top on a set */ + + bool isRoot; + int fbcSetID = -1; + int fbcIndex = 0; + int initFbcId = -1; + int prevFbcSetID = -1; + char tmp[128]; + std::string proc_fe; + bool connect_choices[32] = {false}; for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) { - if (!it->m_frontend->is_FBCTuner()) + // continue for DVB-C FBC Tuner + if (!(it->m_frontend->supportsDeliverySystem(SYS_DVBS, false) || it->m_frontend->supportsDeliverySystem(SYS_DVBS2, false))) continue; - if (isRootFe(*it)) + int fe_id = feSlotID(it); + snprintf(tmp, sizeof(tmp), "/proc/stb/frontend/%d", fe_id); + proc_fe = tmp; + fbcSetID = getProcData(std::string(proc_fe + "/fbc_set_id").c_str()); + if (fbcSetID != -1) { - setProcFBCID(FE_SLOT_ID(it), getFBCID(FE_SLOT_ID(it))); + if (prevFbcSetID != fbcSetID) + { + prevFbcSetID = fbcSetID; + memset(connect_choices, 0, sizeof(connect_choices)); + loadConnectChoices(std::string(proc_fe + "/fbc_connect_choices").c_str(), connect_choices); + fbcIndex =0; // reset + } + + isRoot = false; + if (fbcIndex < sizeof(connect_choices)/sizeof(connect_choices[0])) + { + isRoot = connect_choices[fbcIndex]; + } + + initFbcId = isRoot ? fbcIndex : 0; + + FBC_TUNER elem = {fbcSetID, fbcIndex, isRoot, initFbcId}; + m_fbc_tuners[fe_id] = elem; + + /* set default fbc ID */ + setProcFBCID(fe_id, initFbcId, false); + + /* enable fbc tuner */ + it->m_frontend->setFBCTuner(true); + + fbcIndex++; } } } -int eFBCTunerManager::getFBCTunerNum() +eFBCTunerManager::~eFBCTunerManager() { - char tmp[255]; - int fbc_tuner_num = 2; - int fd = open("/proc/stb/info/chipset", O_RDONLY); - if(fd < 0) { - eDebug("open failed, /proc/stb/info/chipset!"); - fbc_tuner_num = 2; - } - else - { - read(fd, tmp, 255); - close(fd); - - if (!!strstr(tmp, "7376")) - fbc_tuner_num = 2; - } - return fbc_tuner_num; + if (m_instance == this) + m_instance = 0; } -int eFBCTunerManager::setProcFBCID(int fe_id, int fbc_id) +int eFBCTunerManager::setProcFBCID(int fe_id, int fbc_connect, bool is_linked) { - eFecDebug("[*][eFBCTunerManager::setProcFBCID] %d -> %d %s", fe_id, fbc_id, !isRootFeSlot(fe_id)?"(linked)":""); + eFecDebug("[*][eFBCTunerManager::setProcFBCID] %d -> %d", fe_id, fbc_connect); char filename[128]; - char data[4]; - sprintf(filename, "/proc/stb/frontend/%d/fbc_id", fe_id); - int fd = open(filename, O_RDWR); - if(fd < 0) { - eDebug("[*][eFBCTunerManager::setProcFBCID] open failed, %s: %m", filename); - return -1; - } - else - { - if(isLinkedByIndex(fe_id)) - fbc_id += 0x10; // 0x10 : isLinked, 0x01 : fbc_id - sprintf(data, "%x", fbc_id); - write(fd, data, strlen(data)); - close(fd); - } + /* set root */ + sprintf(filename, "/proc/stb/frontend/%d/fbc_connect", fe_id); + setProcData(filename, fbc_connect); + + /* set linked */ + sprintf(filename, "/proc/stb/frontend/%d/fbc_link", fe_id); + setProcData(filename, (int)is_linked); + return 0; } -bool eFBCTunerManager::isRootFeSlot(int fe_slot_id) + +int eFBCTunerManager::feSlotID(const eDVBRegisteredFrontend *fe) const { - return (fe_slot_id%8 < m_fbc_tuner_num) ? true : false; + return fe->m_frontend->getSlotID(); } +void eFBCTunerManager::setDefaultFBCID(eDVBRegisteredFrontend *fe) +{ + int fe_id = feSlotID(fe); + setProcFBCID(fe_id, getDefaultFBCID(fe_id), isLinked(fe)); +} -bool eFBCTunerManager::isRootFe(eDVBRegisteredFrontend *fe) +void eFBCTunerManager::updateFBCID(eDVBRegisteredFrontend *next_fe, eDVBRegisteredFrontend *prev_fe) +{ + setProcFBCID(feSlotID(next_fe), getFBCID(feSlotID(getTop(prev_fe))), isLinked(next_fe)); +} + +bool eFBCTunerManager::isLinked(eDVBRegisteredFrontend *fe) const { - return isRootFeSlot(FE_SLOT_ID(fe)); + + long linked_prev_ptr = -1; + fe->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, linked_prev_ptr); + return (linked_prev_ptr != -1); +} + +bool eFBCTunerManager::isUnicable(eDVBRegisteredFrontend *fe) const +{ + int slot_idx = feSlotID(fe); + bool is_unicable = false; + + ePtr sec = eDVBSatelliteEquipmentControl::getInstance(); + for (int idx=0; idx <= sec->m_lnbidx; ++idx ) + { + eDVBSatelliteLNBParameters &lnb_param = sec->m_lnbs[idx]; + if ( lnb_param.m_slot_mask & (1 << slot_idx) ) + { + is_unicable = lnb_param.SatCR_idx != -1; + break; + } + } + return is_unicable; } -bool eFBCTunerManager::isSameFbcSet(int a, int b) +bool eFBCTunerManager::isFeUsed(eDVBRegisteredFrontend *fe, bool a_simulate) const { - return (a/8) == (b/8) ? true : false; + if (fe->m_inuse > 0) + return true; + + bool simulate = !a_simulate; + + eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; + for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) + { + if (feSlotID(it) == feSlotID(fe)) + { + return (it->m_inuse >0); + } + } + + eDebug("[*][eFBCTunerManager::isFeUsed] ERROR! can not found fe ptr (feid : %d, simulate : %d)", feSlotID(fe), simulate); + return false; } -bool eFBCTunerManager::isSupportDVBS(eDVBRegisteredFrontend *fe) +bool eFBCTunerManager::isSameFbcSet(int fe_a, int fe_b) { - return (fe->m_frontend->supportsDeliverySystem(SYS_DVBS, true) || fe->m_frontend->supportsDeliverySystem(SYS_DVBS2, true)) ? true : false; + return m_fbc_tuners[fe_a].fbcSetID == m_fbc_tuners[fe_b].fbcSetID; } -int eFBCTunerManager::getFBCID(int top_fe_id) +bool eFBCTunerManager::isRootFe(eDVBRegisteredFrontend *fe) { - return 2*top_fe_id/8 + top_fe_id%8; /* (0,1,8,9,16,17...) -> (0,1,2,3,4,5...)*/ + return m_fbc_tuners[feSlotID(fe)].isRoot; } -int eFBCTunerManager::setDefaultFBCID(eDVBRegisteredFrontend *fe) +int eFBCTunerManager::getFBCID(int fe_id) { - if (!isRootFe(fe)) - return -1; + return m_fbc_tuners[fe_id].fbcIndex; +} - return setProcFBCID(FE_SLOT_ID(fe), getFBCID(FE_SLOT_ID(fe))); +int eFBCTunerManager::getDefaultFBCID(int fe_id) +{ + return m_fbc_tuners[fe_id].initFbcId; } -void eFBCTunerManager::updateFBCID(eDVBRegisteredFrontend *next_fe, eDVBRegisteredFrontend *prev_fe) +int eFBCTunerManager::getFBCSetID(int fe_id) { - eDVBRegisteredFrontend *top_fe = getTop(prev_fe); - setProcFBCID(FE_SLOT_ID(next_fe), getFBCID(FE_SLOT_ID(top_fe))); + return m_fbc_tuners[fe_id].fbcSetID; } -eDVBRegisteredFrontend *eFBCTunerManager::getPrev(eDVBRegisteredFrontend *fe) +eDVBRegisteredFrontend *eFBCTunerManager::getPrev(eDVBRegisteredFrontend *fe) const { eDVBRegisteredFrontend *prev_fe = NULL; long linked_prev_ptr = -1; @@ -152,7 +259,7 @@ eDVBRegisteredFrontend *eFBCTunerManager::getPrev(eDVBRegisteredFrontend *fe) return prev_fe; } -eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe) +eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe) const { eDVBRegisteredFrontend *next_fe = NULL; long linked_next_ptr = -1; @@ -162,7 +269,7 @@ eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe) return next_fe; } -eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe) +eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe) const { eDVBRegisteredFrontend *prev_fe = fe; long linked_prev_ptr = -1; @@ -175,7 +282,7 @@ eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe) return prev_fe; } -eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe) +eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe) const { eDVBRegisteredFrontend *next_fe = fe; long linked_next_ptr = -1; @@ -188,371 +295,53 @@ eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe) return next_fe; } -bool eFBCTunerManager::isLinked(eDVBRegisteredFrontend *fe) +eDVBRegisteredFrontend *eFBCTunerManager::getSimulFe(eDVBRegisteredFrontend *fe) const { - return getPrev(fe) ? true:false; -} + eSmartPtrList &frontends = m_res_mgr->m_simulate_frontend; -bool eFBCTunerManager::isLinkedByIndex(int fe_idx) -{ - bool linked = false; - eSmartPtrList &frontends = m_res_mgr->m_frontend; + for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); it++) + if (feSlotID(*it) == feSlotID(fe)) + return(*it); - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (FE_SLOT_ID(it) == fe_idx) - { - linked = isLinked(*it); - break; - } - } - return linked; + return((eDVBRegisteredFrontend *)0); } -bool eFBCTunerManager::checkTop(eDVBRegisteredFrontend *fe) +void eFBCTunerManager::connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate) { - return getPrev(fe) ? false:true; -} - -int eFBCTunerManager::connectLinkByIndex(int link_fe_index, int prev_fe_index, int next_fe_index, bool simulate) -{ - eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; - - eFecDebug(" [*][eFBCTunerManager::connectLinkByIndex] try to link %d->%d->%d %s", prev_fe_index, link_fe_index, next_fe_index, simulate?"(simulate)":""); - - eDVBRegisteredFrontend *link_fe=NULL; - eDVBRegisteredFrontend *prev_fe=NULL; - eDVBRegisteredFrontend *next_fe=NULL; - - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (FE_SLOT_ID(it) == prev_fe_index) - { - prev_fe = *it; - } - else if (FE_SLOT_ID(it) == next_fe_index) - { - next_fe = *it; - } - else if (FE_SLOT_ID(it) == link_fe_index) - { - link_fe = *it; - } - } + if (next_fe) + eFecDebug(" [*][eFBCTunerManager::connectLink] connect %d->%d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), feSlotID(next_fe), simulate?"(simulate)":""); + else + eFecDebug(" [*][eFBCTunerManager::connectLink] connect %d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), simulate?"(simulate)":""); - if (prev_fe && next_fe && link_fe) + prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe); + link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); + if (next_fe) { - /* enable linked fe */ - link_fe->m_frontend->setEnabled(true); - - /* connect */ - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)next_fe); next_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)link_fe); } - else - { - eDebug(" [*][eFBCTunerManager::connectLinkByIndex] connect failed! (prev_fe : %p, next_fe : %p, link_fe : %p, %s)", prev_fe, next_fe, link_fe, simulate?"simulate":""); - return -1; - } - - return 0; } -int eFBCTunerManager::connectLinkByIndex(int link_fe_index, int prev_fe_index, bool simulate) +void eFBCTunerManager::disconnectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate) { - eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; - - eFecDebug(" [*][eFBCTunerManager::connectLinkByIndex] try to link %d->%d %s", prev_fe_index, link_fe_index, simulate?"(simulate)":""); - - eDVBRegisteredFrontend *link_fe=NULL; - eDVBRegisteredFrontend *prev_fe=NULL; - - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (FE_SLOT_ID(it) == prev_fe_index) - { - prev_fe = *it; - } - else if (FE_SLOT_ID(it) == link_fe_index) - { - link_fe = *it; - } - } - - if (prev_fe && link_fe) - { - /* enable linked fe */ - link_fe->m_frontend->setEnabled(true); - - /* connect */ - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); - } + if (next_fe) + eFecDebug(" [*][eFBCTunerManager::disconnectLink] disconnect %d->%d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), feSlotID(next_fe), simulate?"(simulate)":""); else - { - eDebug(" [*][eFBCTunerManager::connectLinkByIndex] connect failed! (prev_fe : %p, link_fe : %p, %s)", prev_fe, link_fe, simulate?"simulate":""); - return -1; - } - - return 0; -} - -int eFBCTunerManager::disconnectLinkByIndex(int link_fe_index, int prev_fe_index, int next_fe_index, bool simulate) -{ - eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; - - eFecDebug(" [*][eFBCTunerManager::connectLinkByIndex] try to unlink %d->%d->%d %s", prev_fe_index, link_fe_index, next_fe_index, simulate?"(simulate)":""); - - eDVBRegisteredFrontend *link_fe=NULL; - eDVBRegisteredFrontend *prev_fe=NULL; - eDVBRegisteredFrontend *next_fe=NULL; + eFecDebug(" [*][eFBCTunerManager::disconnectLink] disconnect %d->%d %s", feSlotID(prev_fe), feSlotID(link_fe), simulate?"(simulate)":""); - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (FE_SLOT_ID(it) == prev_fe_index) - { - prev_fe = *it; - } - else if (FE_SLOT_ID(it) == next_fe_index) - { - next_fe = *it; - } - else if (FE_SLOT_ID(it) == link_fe_index) - { - link_fe = *it; - } - } - - if (prev_fe && next_fe && link_fe) + if (next_fe) { - /* disconnect */ prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)next_fe); next_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1); link_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1); - - /* enable linked fe */ - link_fe->m_frontend->setEnabled(false); - } - else - { - eDebug(" [*][eFBCTunerManager::disconnectLinkByIndex] disconnect failed! (prev_fe : %p, next_fe : %p, link_fe : %p, %s)", prev_fe, next_fe, link_fe, simulate?"simulate":""); - return -1; - } - - return 0; -} -int eFBCTunerManager::disconnectLinkByIndex(int link_fe_index, int prev_fe_index, bool simulate) -{ - eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; - - eFecDebug(" [*][eFBCTunerManager::connectLinkByIndex] try to unlink %d->%d %s", prev_fe_index, link_fe_index, simulate?"(simulate)":""); - - eDVBRegisteredFrontend *link_fe=NULL; - eDVBRegisteredFrontend *prev_fe=NULL; - - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (FE_SLOT_ID(it) == prev_fe_index) - { - prev_fe = *it; - } - else if (FE_SLOT_ID(it) == link_fe_index) - { - link_fe = *it; - } - } - - if (prev_fe && link_fe) - { - /* disconnect */ - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1); - - /* enable linked fe */ - link_fe->m_frontend->setEnabled(false); } else { - eDebug(" [*][eFBCTunerManager::disconnectLinkByIndex] disconnect failed! (prev_fe : %p, link_fe : %p, %s)", prev_fe, link_fe, simulate?"simulate":""); - return -1; - } - - return 0; -} - -int eFBCTunerManager::connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate) -{ - eFecDebug(" [*][eFBCTunerManager::connectLink] try to link %d->%d->%d %s", FE_SLOT_ID(prev_fe), FE_SLOT_ID(link_fe), FE_SLOT_ID(next_fe), simulate?"(simulate)":""); - int ret = connectLinkByIndex(FE_SLOT_ID(link_fe), FE_SLOT_ID(prev_fe), FE_SLOT_ID(next_fe), !simulate); - if(!ret) - { - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); - - link_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)next_fe); - next_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)link_fe); - - /* enable linked fe */ - link_fe->m_frontend->setEnabled(true); - } - - return ret; -} - -int eFBCTunerManager::connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, bool simulate) -{ - eFecDebug(" [*][eFBCTunerManager::connectLink] try to link %d->%d %s", FE_SLOT_ID(prev_fe), FE_SLOT_ID(link_fe), simulate?"(simulate)":""); - int ret = connectLinkByIndex(FE_SLOT_ID(link_fe), FE_SLOT_ID(prev_fe), !simulate); - if(!ret) - { - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); - - /* enable linked fe */ - link_fe->m_frontend->setEnabled(true); - } - - return ret; -} - -int eFBCTunerManager::disconnectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate) -{ - eFecDebug(" [*][eFBCTunerManager::disconnectLink] disconnect %d->%d->%d %s", FE_SLOT_ID(prev_fe), FE_SLOT_ID(link_fe), FE_SLOT_ID(next_fe), simulate?"(simulate)":""); - int ret = disconnectLinkByIndex(FE_SLOT_ID(link_fe), FE_SLOT_ID(prev_fe), FE_SLOT_ID(next_fe), !simulate); - if(!ret) - { - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)next_fe); - next_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)prev_fe); - - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1); - - link_fe->m_frontend->setEnabled(false); - } - - return ret; -} - -int eFBCTunerManager::disconnectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, bool simulate) -{ - eFecDebug(" [*][eFBCTunerManager::disconnectLink] disconnect %d->%d %s", FE_SLOT_ID(prev_fe), FE_SLOT_ID(link_fe), simulate?"(simulate)":""); - int ret = disconnectLinkByIndex(FE_SLOT_ID(link_fe), FE_SLOT_ID(prev_fe), !simulate); - if(!ret) - { prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1); link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1); - - link_fe->m_frontend->setEnabled(false); - } - - return ret; -} - -/* no set pair simulate fe */ -/* no set proc fbc_id */ -void eFBCTunerManager::connectLinkNoSimulate(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe) -{ - eDVBRegisteredFrontend *last_fe = getLast(top_fe); - - last_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)link_fe); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)last_fe); - - /* enable linked fe */ - link_fe->m_frontend->setEnabled(true); - - /* add slot mask*/ - updateLNBSlotMask(FE_SLOT_ID(link_fe), FE_SLOT_ID(top_fe), false); -} - -/* no set pair simulate fe */ -/* no set proc fbc_id */ -void eFBCTunerManager::disconnectLinkNoSimulate(eDVBRegisteredFrontend *link_fe) -{ - if(getNext(link_fe)) - { - eFecDebug("[*][eFBCTunerManager::disconnectLinkNoSimulate] link fe is no last."); - return; - } - - eDVBRegisteredFrontend *prev_fe = getPrev(link_fe); - - if(!prev_fe) - { - eFecDebug("[*][eFBCTunerManager::disconnectLinkNoSimulate] can not found prev fe."); - return; - } - - prev_fe->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)-1); - link_fe->m_frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)-1); - - /* enable linked fe */ - link_fe->m_frontend->setEnabled(false); - - /* add slot mask*/ - updateLNBSlotMask(FE_SLOT_ID(link_fe), FE_SLOT_ID(prev_fe), true); -} - -bool eFBCTunerManager::checkUsed(eDVBRegisteredFrontend *fe, bool a_simulate) -{ - if (fe->m_inuse > 0) - return true; - - bool simulate = !a_simulate; - - eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (FE_SLOT_ID(it) == FE_SLOT_ID(fe)) - { - return (it->m_inuse >0)?true:false; - } } - - eDebug("[*][eFBCTunerManager::checkUsed] ERROR! can not found fe ptr (feid : %d, simulate : %d)", FE_SLOT_ID(fe), simulate); - return false; -} - -bool eFBCTunerManager::canLink(eDVBRegisteredFrontend *fe) -{ - if(isRootFe(fe)) - return false; - - if(getPrev(fe) || getNext(fe)) - return false; - - if(isUnicable(fe)) - return false; - - return true; -} - -bool eFBCTunerManager::isUnicable(eDVBRegisteredFrontend *fe) -{ - int slot_idx = FE_SLOT_ID(fe); - bool is_unicable = false; - - ePtr sec = eDVBSatelliteEquipmentControl::getInstance(); - for (int idx=0; idx <= sec->m_lnbidx; ++idx ) - { - eDVBSatelliteLNBParameters &lnb_param = sec->m_lnbs[idx]; - if ( lnb_param.m_slot_mask & (1 << slot_idx) ) - { - is_unicable = lnb_param.SatCR_idx != -1; - break; - } - } - return is_unicable; -} - -int eFBCTunerManager::isCompatibleWith(ePtr &feparm, eDVBRegisteredFrontend *link_fe, bool simulate) -{ - eDVBRegisteredFrontend *best_fbc_fe; - return isCompatibleWith(feparm, link_fe, best_fbc_fe, simulate); } int eFBCTunerManager::isCompatibleWith(ePtr &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate) @@ -571,7 +360,7 @@ int eFBCTunerManager::isCompatibleWith(ePtr &feparm, eDV if(!it->m_frontend->getEnabled()) continue; - if(!isSameFbcSet(FE_SLOT_ID(link_fe), FE_SLOT_ID(it))) + if(!isSameFbcSet(feSlotID(link_fe), feSlotID(it))) continue; if(it->m_inuse == 0) // No link to a fe not in use. @@ -583,174 +372,158 @@ int eFBCTunerManager::isCompatibleWith(ePtr &feparm, eDV if(isUnicable(*it)) continue; + eDVBRegisteredFrontend *top_fe = *it; + eDVBRegisteredFrontend *prev_fe = getLast(top_fe); + /* connect link */ - connectLinkNoSimulate(link_fe, *it); + connectLink(link_fe, prev_fe, NULL, simulate); + + /* enable linked fe */ + link_fe->m_frontend->setEnabled(true); + + /* add slot mask*/ + updateLNBSlotMask(feSlotID(link_fe), feSlotID(*it), false); /* get score */ int c = link_fe->m_frontend->isCompatibleWith(feparm); - eFecDebug("[*][eFBCTunerManager::isCompatibleWith] score : %d (%d->%d)", c, FE_SLOT_ID(it), FE_SLOT_ID(link_fe)); if (c > best_score) { best_score = c; fbc_fe = (eDVBRegisteredFrontend *)*it; } + eFecDebug("[*][eFBCTunerManager::isCompatibleWith] score : %d (%d->%d)", c, feSlotID(it), feSlotID(link_fe)); + + ASSERT(!getNext(link_fe)); + ASSERT(getPrev(link_fe)); + ASSERT(getLast(top_fe) == link_fe); + /* disconnect link */ - disconnectLinkNoSimulate(link_fe); + disconnectLink(link_fe, prev_fe, NULL, simulate); + + /* disable linked fe */ + link_fe->m_frontend->setEnabled(false); + + /* remove slot mask*/ + updateLNBSlotMask(feSlotID(link_fe), feSlotID(top_fe), true); } - eFecDebug("[*][eFBCTunerManager::isCompatibleWith] fe : %p(%d), score : %d %s", link_fe, FE_SLOT_ID(link_fe), best_score, simulate?"(simulate)":""); + eFecDebug("[*][eFBCTunerManager::isCompatibleWith] fe : %p(%d), score : %d %s", link_fe, feSlotID(link_fe), best_score, simulate?"(simulate)":""); return best_score; } -void eFBCTunerManager::connectSortedLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate) +/* attach link_fe to tail of fe linked list */ +void eFBCTunerManager::addLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate) { - int link_fe_id = FE_SLOT_ID(link_fe); - int top_fe_id = FE_SLOT_ID(top_fe); - int prev_fe_id = link_fe_id - 1; + //printLinks(link_fe); - eFecDebug(" [*][eFBCTunerManager::connectSortedLink] link_id : %d, top_id : %d %s", link_fe_id, top_fe_id, simulate?"(simulate)":""); + eFecDebug(" [*][eFBCTunerManager::addLink] addLink : %p(%d)->%p(%d) %s", top_fe, feSlotID(top_fe), link_fe, feSlotID(link_fe), simulate?"(simulate)":""); - if (prev_fe_id < 0) - { - eFecDebug(" [*][eFBCTunerManager::connectSortedLink] link failed! link_id : %d, top_id : %d %s", link_fe_id, top_fe_id, simulate?"(simulate)":""); + eDVBRegisteredFrontend *next_fe = NULL; + eDVBRegisteredFrontend *prev_fe = NULL; + + if(isRootFe(link_fe) || !isRootFe(top_fe)) return; - } - /* serach prev fe */ - eDVBRegisteredFrontend *next_fe = top_fe; - long linked_next_ptr = -1; - top_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); - while(linked_next_ptr != -1) + /* search prev/next fe */ + next_fe = top_fe; + while(true) { - next_fe = (eDVBRegisteredFrontend *)linked_next_ptr; - next_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); - if (FE_SLOT_ID(next_fe) == prev_fe_id) + prev_fe = next_fe; + next_fe = getNext(prev_fe); + if ((next_fe == NULL) || (feSlotID(next_fe) > feSlotID(link_fe))) break; } - eDVBRegisteredFrontend *prev_fe = next_fe; + /* connect */ + connectLink(link_fe, prev_fe, next_fe, simulate); - /* get next fe */ - next_fe = getNext(prev_fe); + /* enable linked fe */ + link_fe->m_frontend->setEnabled(true); - /* connect */ - if (next_fe) - { - int res = connectLink(link_fe, prev_fe, next_fe, simulate); - if (res) - { - eDebug("[*][eFBCTunerManager::connectSortedLink] ERROR! connect link failed! (%d->%d->%d)", FE_SLOT_ID(prev_fe), FE_SLOT_ID(link_fe), FE_SLOT_ID(next_fe)); - return; - } - } - else + /* simulate connect */ + if (!simulate) { - int res = connectLink(link_fe, prev_fe, simulate); - if (res) - { - eDebug("[*][eFBCTunerManager::connectSortedLink] ERROR! connect link failed! (%d->%d)", FE_SLOT_ID(prev_fe), FE_SLOT_ID(link_fe)); - return; - } - } + eDVBRegisteredFrontend *simulate_prev_fe = NULL; + eDVBRegisteredFrontend *simulate_link_fe = NULL; + eDVBRegisteredFrontend *simulate_next_fe = NULL; - /* set proc fbc_id */ - setProcFBCID(link_fe_id, getFBCID(top_fe_id)); + simulate_prev_fe = getSimulFe(prev_fe); + simulate_link_fe = getSimulFe(link_fe); - /* add slot mask*/ - updateLNBSlotMask(link_fe_id, top_fe_id, false); -} + if (next_fe) + simulate_next_fe = getSimulFe(next_fe); -/* attach link_fe to tail of fe linked list */ -void eFBCTunerManager::addLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate) -{ - eFecDebug(" [*][eFBCTunerManager::addLink] addLink : %p(%d)->%p(%d) %s", top_fe, FE_SLOT_ID(top_fe), link_fe, FE_SLOT_ID(link_fe), simulate?"(simulate)":""); + eFecDebug(" [*][eFBCTunerManager::addLink] simulate fe : %p -> %p -> %p", simulate_prev_fe, simulate_link_fe, simulate_next_fe); - if (!isRootFe(top_fe)) - return; + connectLink(simulate_link_fe, simulate_prev_fe, simulate_next_fe, !simulate); -// eDVBRegisteredFrontend *top_fe = a_top_fe; -// if (!checkTop(top_fe)) -// top_fe = getTop(top_fe); + /* enable simulate linked fe */ + simulate_link_fe->m_frontend->setEnabled(true); + } + + /* set proc fbc_id */ + if (!simulate) + setProcFBCID(feSlotID(link_fe), getFBCID(feSlotID(top_fe)), isLinked(link_fe)); -// printLinks(top_fe); - connectSortedLink(link_fe, top_fe, simulate); -// printLinks(top_fe); + /* add slot mask*/ + updateLNBSlotMask(feSlotID(link_fe), feSlotID(top_fe), false); + + //printLinks(link_fe); } /* if fe, fe_simulated is unused, unlink current frontend from linked things. */ /* all unused linked fbc fe must be unlinked! */ -void eFBCTunerManager::unset(eDVBRegisteredFrontend *fe) +void eFBCTunerManager::unLink(eDVBRegisteredFrontend *link_fe) { - bool simulate = fe->m_frontend->is_simulate(); + bool simulate = link_fe->m_frontend->is_simulate(); + eFecDebug(" [*][eFBCTunerManager::unLink] fe id : %p(%d) %s", link_fe, feSlotID(link_fe), simulate?"(simulate)":""); - if (isRootFe(fe)) + if (isRootFe(link_fe) || isFeUsed(link_fe, simulate) || isUnicable(link_fe) || !isLinked(link_fe)) + { + eFecDebug(" [*][eFBCTunerManager::unLink] skip.."); return; + } - if(checkUsed(fe, simulate)) - return; + //printLinks(link_fe); - if(isUnicable(fe)) - return; + eDVBRegisteredFrontend *prev_fe = getPrev(link_fe); + eDVBRegisteredFrontend *next_fe = getNext(link_fe); - eFecDebug(" [*][eFBCTunerManager::unset] fe id : %p(%d) %s", fe, FE_SLOT_ID(fe), simulate?"(simulate)":""); + ASSERT(prev_fe); - -// printLinks(fe); + disconnectLink(link_fe, prev_fe, next_fe, simulate); - eDVBRegisteredFrontend *linked_prev_fe = getPrev(fe); - eDVBRegisteredFrontend *linked_next_fe = getNext(fe); + /* disable linked fe */ + link_fe->m_frontend->setEnabled(false); - if (!linked_prev_fe) + /* simulate disconnect */ + if (!simulate) { - eDebug("[*][eFBCTunerManager::unset] ERROR! can not found prev linked frontend (fe_id : %d)", FE_SLOT_ID(fe)); - return; - } + eDVBRegisteredFrontend *simulate_prev_fe = NULL; + eDVBRegisteredFrontend *simulate_link_fe = NULL; + eDVBRegisteredFrontend *simulate_next_fe = NULL; - if (linked_next_fe) - { - int res = disconnectLink(fe, linked_prev_fe, linked_next_fe, simulate); - if (res) - { - eDebug("[*][eFBCTunerManager::unset] ERROR! disconnect link failed! (%d->%d->%d)", FE_SLOT_ID(linked_prev_fe), FE_SLOT_ID(fe), FE_SLOT_ID(linked_next_fe)); - return; - } - } - else - { - int res = disconnectLink(fe, linked_prev_fe, simulate); - if (res) - { - eDebug("[*][eFBCTunerManager::unset] ERROR! disconnect link failed! (%d->%d)", FE_SLOT_ID(linked_prev_fe), FE_SLOT_ID(fe)); - return; - } - } - - /* set proc fbc_id (skip) */ + simulate_prev_fe = getSimulFe(prev_fe); + simulate_link_fe = getSimulFe(link_fe); - /* remove slot mask*/ - updateLNBSlotMask(FE_SLOT_ID(fe), FE_SLOT_ID(linked_prev_fe), true); + if (next_fe) + simulate_next_fe = getSimulFe(next_fe); -// printLinks(fe); -} + disconnectLink(simulate_link_fe, simulate_prev_fe, simulate_next_fe, !simulate); -bool eFBCTunerManager::canAllocateLink(eDVBRegisteredFrontend *fe, bool simulate) -{ - if (!isRootFe(fe)) - return false; + /* enable simulate linked fe */ + simulate_link_fe->m_frontend->setEnabled(false); + } - if (isLinked(fe)) - return false; + /* set default proc fbc_id */ + //setDefaultFBCID(link_fe); - eSmartPtrList &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend; - for (eSmartPtrList::iterator it(frontends.begin()); it != frontends.end(); ++it) - { - if (it->m_frontend->is_FBCTuner() && !isRootFe(*it) && isSameFbcSet(FE_SLOT_ID(fe), FE_SLOT_ID(it)) && !it->m_frontend->getEnabled() && !isLinked(*it)) - return true; - } + /* remove slot mask*/ + updateLNBSlotMask(feSlotID(link_fe), feSlotID(getTop(prev_fe)), true); - return false; + //printLinks(link_fe); } int eFBCTunerManager::updateLNBSlotMask(int dest_slot, int src_slot, bool remove) @@ -783,7 +556,12 @@ int eFBCTunerManager::updateLNBSlotMask(int dest_slot, int src_slot, bool remove return 0; } -int eFBCTunerManager::getLinkedSlotID(int fe_id) +bool eFBCTunerManager::canLink(eDVBRegisteredFrontend *fe) +{ + return !(isRootFe(fe) || getPrev(fe) || getNext(fe) || isUnicable(fe)); +} + +int eFBCTunerManager::getLinkedSlotID(int fe_id) const { int link = -1; eSmartPtrList &frontends = m_res_mgr->m_frontend; @@ -796,7 +574,7 @@ int eFBCTunerManager::getLinkedSlotID(int fe_id) if (prev_ptr != -1) { eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr; - link = FE_SLOT_ID(prev_fe); + link = feSlotID(prev_fe); } break; } @@ -807,7 +585,18 @@ int eFBCTunerManager::getLinkedSlotID(int fe_id) return link; } -void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe) +bool eFBCTunerManager::isFBCLink(int fe_id) +{ + bool res = false; + std::map::iterator it = m_fbc_tuners.find(fe_id); + if (it != m_fbc_tuners.end()) + { + res = !it->second.isRoot; + } + return res; +} + +void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe) const { long linked_prev_ptr = -1; eDVBRegisteredFrontend *linked_prev_fe = fe; @@ -820,12 +609,12 @@ void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe) long linked_next_ptr = -1; eDVBRegisteredFrontend *linked_next_fe = linked_prev_fe; - eFecDebug(" [*][eFBCTunerManager::printLinks] fe id : %d (%p), inuse : %d, enabled : %d, fbc : %d", FE_SLOT_ID(linked_next_fe), linked_next_fe, linked_next_fe->m_inuse, linked_next_fe->m_frontend->getEnabled(), linked_next_fe->m_frontend->is_FBCTuner()); + eFecDebug(" [*][eFBCTunerManager::printLinks] fe id : %d (%p), inuse : %d, enabled : %d, fbc : %d", feSlotID(linked_next_fe), linked_next_fe, linked_next_fe->m_inuse, linked_next_fe->m_frontend->getEnabled(), linked_next_fe->m_frontend->is_FBCTuner()); linked_prev_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, linked_next_ptr); while (linked_next_ptr != -1) { linked_next_fe = (eDVBRegisteredFrontend*) linked_next_ptr; - eFecDebug(" [*][eFBCTunerManager::printLinks] fe id : %d (%p), inuse : %d, enabled : %d, fbc : %d", FE_SLOT_ID(linked_next_fe), linked_next_fe, linked_next_fe->m_inuse, linked_next_fe->m_frontend->getEnabled(), linked_next_fe->m_frontend->is_FBCTuner()); + eFecDebug(" [*][eFBCTunerManager::printLinks] fe id : %d (%p), inuse : %d, enabled : %d, fbc : %d", feSlotID(linked_next_fe), linked_next_fe, linked_next_fe->m_inuse, linked_next_fe->m_frontend->getEnabled(), linked_next_fe->m_frontend->is_FBCTuner()); linked_next_fe->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, (long&)linked_next_ptr); } @@ -841,16 +630,16 @@ void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe) if (prev_ptr != -1) { eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr; - prev = FE_SLOT_ID(prev_fe); + prev = feSlotID(prev_fe); } if (next_ptr != -1) { eDVBRegisteredFrontend *next_fe = (eDVBRegisteredFrontend *)next_ptr; - next = FE_SLOT_ID(next_fe); + next = feSlotID(next_fe); } - eFecDebug(" [*][eFBCTunerManager::printLinks] fe_id : %d, inuse : %d, enabled : %d, fbc : %d, prev : %d, next : %d", FE_SLOT_ID(it), it->m_inuse, it->m_frontend->getEnabled(), it->m_frontend->is_FBCTuner(), prev, next); + eFecDebug(" [*][eFBCTunerManager::printLinks] fe_id : %2d, inuse : %d, enabled : %d, fbc : %d, prev : %2d, cur : %2d, next : %2d", feSlotID(it), it->m_inuse, it->m_frontend->getEnabled(), it->m_frontend->is_FBCTuner(), prev, feSlotID(it), next); } eSmartPtrList &simulate_frontends = m_res_mgr->m_simulate_frontend; @@ -865,16 +654,16 @@ void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe) if (prev_ptr != -1) { eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr; - prev = FE_SLOT_ID(prev_fe); + prev = feSlotID(prev_fe); } if (next_ptr != -1) { eDVBRegisteredFrontend *next_fe = (eDVBRegisteredFrontend *)next_ptr; - next = FE_SLOT_ID(next_fe); + next = feSlotID(next_fe); } - eFecDebug(" [*][eFBCTunerManager::printLinks] fe_id : %2d, inuse : %d, enabled : %d, fbc : %d, prev : %2d, cur : %2d, next : %2d (simulate)", FE_SLOT_ID(it), it->m_inuse, it->m_frontend->getEnabled(), it->m_frontend->is_FBCTuner(), prev, FE_SLOT_ID(it), next); + eFecDebug(" [*][eFBCTunerManager::printLinks] fe_id : %2d, inuse : %d, enabled : %d, fbc : %d, prev : %2d, cur : %2d, next : %2d (simulate)", feSlotID(it), it->m_inuse, it->m_frontend->getEnabled(), it->m_frontend->is_FBCTuner(), prev, feSlotID(it), next); } } diff --git a/lib/dvb/fbc.h b/lib/dvb/fbc.h index 5f1afc1..f4899f0 100644 --- a/lib/dvb/fbc.h +++ b/lib/dvb/fbc.h @@ -6,75 +6,63 @@ #include #include #include +#include class eDVBResourceManager; class eDVBRegisteredFrontend; +typedef struct fbc_tuner +{ + int fbcSetID; + int fbcIndex; + bool isRoot; + int initFbcId; +}FBC_TUNER; + + class eFBCTunerManager: public iObject, public Object { private: DECLARE_REF(eFBCTunerManager); ePtr m_res_mgr; - int m_fbc_tuner_num; - static bool isDestroyed; + static eFBCTunerManager *m_instance; + std::map m_fbc_tuners; - int getFBCTunerNum(); - void procInit(); - bool isSameFbcSet(int a, int b); - bool isSupportDVBS(eDVBRegisteredFrontend *fe); - int getFBCID(int root_fe_id); + int setProcFBCID(int fe_id, int root_idx, bool is_linked); + int feSlotID(const eDVBRegisteredFrontend *fe) const; + bool isLinked(eDVBRegisteredFrontend *fe) const; + bool isUnicable(eDVBRegisteredFrontend *fe) const; + bool isFeUsed(eDVBRegisteredFrontend *fe, bool a_simulate) const; + bool isSameFbcSet(int fe_id_a, int fe_id_b); + bool isRootFe(eDVBRegisteredFrontend *fe); + int getFBCID(int fe_id); + int getDefaultFBCID(int fe_id); - eDVBRegisteredFrontend *getPrev(eDVBRegisteredFrontend *fe); - eDVBRegisteredFrontend *getNext(eDVBRegisteredFrontend *fe); - eDVBRegisteredFrontend *getTop(eDVBRegisteredFrontend *fe); - eDVBRegisteredFrontend *getLast(eDVBRegisteredFrontend *fe); - bool isLinked(eDVBRegisteredFrontend *fe); - bool isLinkedByIndex(int fe_idx); - bool checkTop(eDVBRegisteredFrontend *fe); - int connectLinkByIndex(int link_fe_index, int prev_fe_index, int next_fe_index, bool simulate); - int connectLinkByIndex(int link_fe_index, int prev_fe_index, bool simulate); - int disconnectLinkByIndex(int link_fe_index, int prev_fe_index, int next_fe_index, bool simulate); - int disconnectLinkByIndex(int link_fe_index, int prev_fe_index, bool simulate); - int connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate); - int connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, bool simulate); - int disconnectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate); - int disconnectLink(eDVBRegisteredFrontend *linkable_fe, eDVBRegisteredFrontend *top_fe, bool simulate); - void connectLinkNoSimulate(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe); - void disconnectLinkNoSimulate(eDVBRegisteredFrontend *link_fe); + eDVBRegisteredFrontend *getPrev(eDVBRegisteredFrontend *fe) const; + eDVBRegisteredFrontend *getNext(eDVBRegisteredFrontend *fe) const; + eDVBRegisteredFrontend *getTop(eDVBRegisteredFrontend *fe) const; + eDVBRegisteredFrontend *getLast(eDVBRegisteredFrontend *fe) const; + eDVBRegisteredFrontend *getSimulFe(eDVBRegisteredFrontend *fe) const; - bool checkUsed(eDVBRegisteredFrontend *fe, bool a_simulate); - void connectSortedLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate); + void connectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate); + void disconnectLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *prev_fe, eDVBRegisteredFrontend *next_fe, bool simulate); int updateLNBSlotMask(int dest_slot, int src_slot, bool remove); - void printLinks(eDVBRegisteredFrontend *fe); + void printLinks(eDVBRegisteredFrontend *fe) const; public: - eFBCTunerManager(); + static eFBCTunerManager* getInstance(); + eFBCTunerManager(ePtr res_mgr); virtual ~eFBCTunerManager(); - int setProcFBCID(int fe_id, int fbc_id); - int setDefaultFBCID(eDVBRegisteredFrontend *fe); + void setDefaultFBCID(eDVBRegisteredFrontend *fe); void updateFBCID(eDVBRegisteredFrontend *next_fe, eDVBRegisteredFrontend *prev_fe); - bool isRootFeSlot(int fe_slot_id); - bool isRootFe(eDVBRegisteredFrontend *fe); - bool canLink(eDVBRegisteredFrontend *fe); - bool isUnicable(eDVBRegisteredFrontend *fe); - int isCompatibleWith(ePtr &feparm, eDVBRegisteredFrontend *link_fe, bool simulate); int isCompatibleWith(ePtr &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate); void addLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate); - void unset(eDVBRegisteredFrontend *fe); - bool canAllocateLink(eDVBRegisteredFrontend *fe, bool simulate); - - static eFBCTunerManager* getInstance() - { - if (isDestroyed == true) - { - eDebug("eFBCTunerManager is already destroyed!"); - return 0; - } - static eFBCTunerManager instance; - return &instance; - } - - int getLinkedSlotID(int feid); + void unLink(eDVBRegisteredFrontend *link_fe); + bool canLink(eDVBRegisteredFrontend *fe); + int getLinkedSlotID(int feid) const; + int getFBCSetID(int fe_id); + bool isFBCLink(int fe_id); }; -#endif /* __dvb_fbc_h */ \ No newline at end of file +#endif /* __dvb_fbc_h */ + diff --git a/lib/dvb/fcc.cpp b/lib/dvb/fcc.cpp index 614340b..e83dbc8 100644 --- a/lib/dvb/fcc.cpp +++ b/lib/dvb/fcc.cpp @@ -326,7 +326,7 @@ bool eFCCServiceManager::checkAvailable(const eServiceReference &ref) int serviceType = ref.getData(0); eFCCServiceManager *fcc_mng = eFCCServiceManager::getInstance(); - if (ref.path.empty() && (serviceType != 2) && (serviceType != 10) && fcc_mng) // no PVR, streaming, radio channel.. + if ((ref.type == 1) && ref.path.empty() && (serviceType != 2) && (serviceType != 10) && fcc_mng) // no PVR, streaming, radio channel.. return fcc_mng->isEnable(); return false; } diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index fa36653..2892fe4 100755 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -525,11 +525,6 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFronten m_idleInputpower[0]=m_idleInputpower[1]=0; - char fileName[32] = {0}; - sprintf(fileName, "/proc/stb/frontend/%d/fbc_id", m_slotid); - if (access(fileName, F_OK) == 0) - m_fbc = true; - ok = !openFrontend(); closeFrontend(); } diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h index aceb856..41dc311 100644 --- a/lib/dvb/frontend.h +++ b/lib/dvb/frontend.h @@ -160,6 +160,7 @@ public: const char *getDescription() const { return m_description; } bool is_simulate() const { return m_simulate; } bool is_FBCTuner() { return m_fbc; } + void setFBCTuner(bool enable) { m_fbc = enable; } bool getEnabled() { return m_enabled; } void setEnabled(bool enable) { m_enabled = enable; } bool isLoopTimerActive() { return m_tuneTimer->isActive(); } diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp index c13114e..a73cfdb 100644 --- a/lib/gui/elistbox.cpp +++ b/lib/gui/elistbox.cpp @@ -480,6 +480,11 @@ void eListbox::entryReset(bool selectionHome) invalidate(); } +void eListbox::setFont(gFont *font) +{ + m_style.m_font = font; +} + void eListbox::setBackgroundColor(gRGB &col) { m_style.m_background_color = col; diff --git a/lib/gui/elistbox.h b/lib/gui/elistbox.h index 0073653..7334e48 100644 --- a/lib/gui/elistbox.h +++ b/lib/gui/elistbox.h @@ -71,6 +71,7 @@ struct eListboxStyle {1 x 0} use transparent background {1 x p} use transparent background picture */ + ePtr m_font; }; #endif @@ -127,6 +128,7 @@ public: void setForegroundColorSelected(gRGB &col); void setBackgroundPicture(ePtr &pixmap); void setSelectionPicture(ePtr &pixmap); + void setFont(gFont *font); #ifndef SWIG struct eListboxStyle *getLocalStyle(void); diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp index ba0794e..3dcea7b 100644 --- a/lib/gui/elistboxcontent.cpp +++ b/lib/gui/elistboxcontent.cpp @@ -138,7 +138,7 @@ void eListboxPythonStringContent::setSize(const eSize &size) void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { - ePtr fnt = new gFont("Regular", 20); + ePtr fnt; painter.clip(eRect(offset, m_itemsize)); style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal); @@ -151,6 +151,7 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, if (local_style) { + fnt = local_style->m_font; if (selected) { /* if we have a local background color set, use that. */ @@ -170,6 +171,7 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, painter.setForegroundColor(local_style->m_foreground_color); } } + if (!fnt) fnt = new gFont("Regular", 20); /* if we have no transparent background */ if (!local_style || !local_style->m_transparent_background) @@ -273,8 +275,8 @@ void eListboxPythonStringContent::invalidate() void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { - ePtr fnt = new gFont("Regular", 20); - ePtr fnt2 = new gFont("Regular", 16); + ePtr fnt; + ePtr fnt2; eRect itemrect(offset, m_itemsize); eListboxStyle *local_style = 0; bool cursorValid = this->cursorValid(); @@ -288,6 +290,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, if (local_style) { + fnt = local_style->m_font; if (selected) { /* if we have a local background color set, use that. */ @@ -308,6 +311,16 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, } } + if (fnt) + { + fnt2 = new gFont(fnt->family, fnt->pointSize - fnt->pointSize/5); + } + else + { + fnt = new gFont("Regular", 20); + fnt2 = new gFont("Regular", 16); + } + if (!local_style || !local_style->m_transparent_background) /* if we have no transparent background */ { diff --git a/lib/nav/core.cpp b/lib/nav/core.cpp index 2e54d87..cfb132f 100644 --- a/lib/nav/core.cpp +++ b/lib/nav/core.cpp @@ -36,6 +36,7 @@ RESULT eNavigation::playService(const eServiceReference &service) if (m_runningService) { + m_runningService->setTarget(m_decoder); m_runningService->connectEvent(slot(*this, &eNavigation::serviceEvent), m_service_event_conn); res = m_runningService->start(); } @@ -154,10 +155,11 @@ RESULT eNavigation::pause(int dop) return p->unpause(); } -eNavigation::eNavigation(iServiceHandler *serviceHandler) +eNavigation::eNavigation(iServiceHandler *serviceHandler, int decoder) { ASSERT(serviceHandler); m_servicehandler = serviceHandler; + m_decoder = decoder; m_fccmgr = new eFCCServiceManager(this); } diff --git a/lib/nav/core.h b/lib/nav/core.h index a4906c1..b055bc8 100644 --- a/lib/nav/core.h +++ b/lib/nav/core.h @@ -11,6 +11,7 @@ class eNavigation: public iObject, public Object { DECLARE_REF(eNavigation); + int m_decoder; ePtr m_servicehandler; ePtr m_runningService; @@ -41,7 +42,7 @@ public: PyObject *getRecordings(bool simulate=false); RESULT pause(int p); - eNavigation(iServiceHandler *serviceHandler); + eNavigation(iServiceHandler *serviceHandler, int decoder = 0); virtual ~eNavigation(); }; diff --git a/lib/python/Components/ChoiceList.py b/lib/python/Components/ChoiceList.py index 33868d6..af93399 100755 --- a/lib/python/Components/ChoiceList.py +++ b/lib/python/Components/ChoiceList.py @@ -2,25 +2,30 @@ from MenuList import MenuList from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, gFont from Tools.LoadPixmap import LoadPixmap +import skin def ChoiceEntryComponent(key = "", text = ["--"]): res = [ text ] if text[0] == "--": - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 00, 800, 25, 0, RT_HALIGN_LEFT, "-"*200)) + x, y, w, h = skin.parameters.get("ChoicelistDash",(0, 0, 800, 25)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, "-"*200)) else: - res.append((eListboxPythonMultiContent.TYPE_TEXT, 45, 00, 800, 25, 0, RT_HALIGN_LEFT, text[0])) + x, y, w, h = skin.parameters.get("ChoicelistName",(45, 0, 800, 25)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, text[0])) png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/buttons/key_" + key + ".png")) if png is not None: - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 5, 0, 35, 25, png)) + x, y, w, h = skin.parameters.get("ChoicelistIcon",(5, 0, 35, 25)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, x, y, w, h, png)) return res class ChoiceList(MenuList): def __init__(self, list, selection = 0, enableWrapAround=False): MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent) - self.l.setFont(0, gFont("Regular", 20)) - self.l.setItemHeight(25) + font = skin.fonts.get("ChoiceList", ("Regular", 20, 25)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) self.selection = selection def postWidgetCreate(self, instance): diff --git a/lib/python/Components/ConfigList.py b/lib/python/Components/ConfigList.py index 24f917f..fd638d7 100755 --- a/lib/python/Components/ConfigList.py +++ b/lib/python/Components/ConfigList.py @@ -4,12 +4,14 @@ from config import KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_0, KEY_DELETE, KE from Components.ActionMap import NumberActionMap, ActionMap from enigma import eListbox, eListboxPythonConfigContent, eRCInput, eTimer from Screens.MessageBox import MessageBox +import skin class ConfigList(HTMLComponent, GUIComponent, object): def __init__(self, list, session = None): GUIComponent.__init__(self) self.l = eListboxPythonConfigContent() - self.l.setSeperation(200) + seperation, = skin.parameters.get("ConfigListSeperator", (200, )) + self.l.setSeperation(seperation) self.timer = eTimer() self.list = list self.onSelectionChanged = [ ] diff --git a/lib/python/Components/EpgList.py b/lib/python/Components/EpgList.py index 41cd1b2..1440d60 100755 --- a/lib/python/Components/EpgList.py +++ b/lib/python/Components/EpgList.py @@ -9,6 +9,7 @@ from Tools.LoadPixmap import LoadPixmap from time import localtime, time from ServiceReference import ServiceReference from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN +import skin EPG_TYPE_SINGLE = 0 EPG_TYPE_MULTI = 1 @@ -43,8 +44,10 @@ class EPGList(HTMLComponent, GUIComponent): GUIComponent.__init__(self) self.type=type self.l = eListboxPythonMultiContent() - self.l.setFont(0, gFont("Regular", 22)) - self.l.setFont(1, gFont("Regular", 16)) + font = skin.fonts.get("EPGList0", ("Regular", 22)) + self.l.setFont(0, gFont(font[0], font[1])) + font = skin.fonts.get("EPGList1", ("Regular", 16)) + self.l.setFont(1, gFont(font[0], font[1])) if type == EPG_TYPE_SINGLE: self.l.setBuildFunc(self.buildSingleEntry) elif type == EPG_TYPE_MULTI: diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py index 4c5b98d..542a135 100755 --- a/lib/python/Components/FileList.py +++ b/lib/python/Components/FileList.py @@ -8,6 +8,7 @@ from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename, fileExists from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \ eServiceReference, eServiceCenter, gFont from Tools.LoadPixmap import LoadPixmap +import skin EXTENSIONS = { "m4a": "music", @@ -42,7 +43,8 @@ EXTENSIONS = { def FileEntryComponent(name, absolute = None, isDir = False): res = [ (absolute, isDir) ] - res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 470, 20, 0, RT_HALIGN_LEFT, name)) + x, y, w, h = skin.parameters.get("FileListName",(35, 1, 470, 20)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, name)) if isDir: png = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "extensions/directory.png")) else: @@ -53,7 +55,8 @@ def FileEntryComponent(name, absolute = None, isDir = False): else: png = None if png is not None: - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 10, 2, 20, 20, png)) + x, y, w, h = skin.parameters.get("FileListIcon",(10, 2, 20, 20)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, x, y, w, h, png)) return res @@ -76,8 +79,9 @@ class FileList(MenuList): self.refreshMountpoints() self.changeDir(directory) - self.l.setFont(0, gFont("Regular", 18)) - self.l.setItemHeight(23) + font = skin.fonts.get("FileList", ("Regular", 18, 23)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) self.serviceHandler = eServiceCenter.getInstance() def refreshMountpoints(self): @@ -269,7 +273,8 @@ class FileList(MenuList): def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected = False): res = [ (absolute, isDir, selected, name) ] - res.append((eListboxPythonMultiContent.TYPE_TEXT, 55, 1, 470, 20, 0, RT_HALIGN_LEFT, name)) + x, y, w, h = skin.parameters.get("FileListMultiName",(55, 0, 470, 25)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, name)) if isDir: png = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "extensions/directory.png")) else: @@ -280,7 +285,8 @@ def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected else: png = None if png is not None: - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 30, 2, 20, 20, png)) + x, y, w, h = skin.parameters.get("FileListMultiIcon",(30, 2, 20, 20)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, x, y, w, h, png)) if not name.startswith('<'): if selected is False: @@ -288,7 +294,8 @@ def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon)) else: icon = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/lock_on.png")) - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon)) + x, y, w, h = skin.parameters.get("FileListMultiLock",(2, 0, 25, 25)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, x, y, w, h, icon)) return res @@ -300,8 +307,9 @@ class MultiFileSelectList(FileList): self.selectedFiles = [] FileList.__init__(self, directory, showMountpoints = showMountpoints, matchingPattern = matchingPattern, showDirectories = showDirectories, showFiles = showFiles, useServiceRef = useServiceRef, inhibitDirs = inhibitDirs, inhibitMounts = inhibitMounts, isTop = isTop, enableWrapAround = enableWrapAround, additionalExtensions = additionalExtensions) self.changeDir(directory) - self.l.setItemHeight(25) - self.l.setFont(0, gFont("Regular", 20)) + font = skin.fonts.get("FileListMulti", ("Regular", 20, 25)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) self.onSelectionChanged = [ ] def selectionChanged(self): diff --git a/lib/python/Components/HelpMenuList.py b/lib/python/Components/HelpMenuList.py index 66139df..c997395 100755 --- a/lib/python/Components/HelpMenuList.py +++ b/lib/python/Components/HelpMenuList.py @@ -2,6 +2,7 @@ from GUIComponent import GUIComponent from enigma import eListboxPythonMultiContent, eListbox, gFont from Tools.KeyBindings import queryKeyBinding, getKeyDescription +import skin #getKeyPositions # [ ( actionmap, context, [(action, help), (action, help), ...] ), (actionmap, ... ), ... ] @@ -39,23 +40,30 @@ class HelpMenuList(GUIComponent): if isinstance(help, list): self.extendedHelp = True print "extendedHelpEntry found" + x, y, w, h = skin.parameters.get("HelpMenuListExtHlp0",(0, 0, 400, 26)) + x1, y1, w1, h1 = skin.parameters.get("HelpMenuListExtHlp1",(0, 28, 400, 20)) entry.extend(( - (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 400, 26, 0, 0, help[0]), - (eListboxPythonMultiContent.TYPE_TEXT, 0, 28, 400, 20, 1, 0, help[1]) + (eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, 0, help[0]), + (eListboxPythonMultiContent.TYPE_TEXT, x1, y1, w1, h1, 1, 0, help[1]) )) else: - entry.append( (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 400, 28, 0, 0, help) ) + x, y, w, h = skin.parameters.get("HelpMenuListHlp",(0, 0, 400, 28)) + entry.append( (eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, 0, help) ) l.append(entry) self.l.setList(l) if self.extendedHelp is True: - self.l.setFont(0, gFont("Regular", 24)) - self.l.setFont(1, gFont("Regular", 18)) - self.l.setItemHeight(50) + + font = skin.fonts.get("HelpMenuListExt0", ("Regular", 24, 50)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) + font = skin.fonts.get("HelpMenuListExt1", ("Regular", 18)) + self.l.setFont(1, gFont(font[0], font[1])) else: - self.l.setFont(0, gFont("Regular", 24)) - self.l.setItemHeight(38) + font = skin.fonts.get("HelpMenuList", ("Regular", 24, 38)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) def ok(self): # a list entry has a "private" tuple as first entry... diff --git a/lib/python/Components/InputDevice.py b/lib/python/Components/InputDevice.py index d675ca3..965a27f 100755 --- a/lib/python/Components/InputDevice.py +++ b/lib/python/Components/InputDevice.py @@ -8,8 +8,8 @@ from os import path as os_path, listdir, open as os_open, close as os_close, wri # asm-generic/ioctl.h IOC_NRBITS = 8L IOC_TYPEBITS = 8L -IOC_SIZEBITS = 13L -IOC_DIRBITS = 3L +IOC_SIZEBITS = 14L +IOC_DIRBITS = 2L IOC_NRSHIFT = 0L IOC_TYPESHIFT = IOC_NRSHIFT+IOC_NRBITS @@ -33,6 +33,9 @@ class inputDevices: devices = listdir("/dev/input/") for evdev in devices: + if not evdev.startswith("event"): + continue + try: buffer = "\0"*512 self.fd = os_open("/dev/input/" + evdev, O_RDWR | O_NONBLOCK) diff --git a/lib/python/Components/MediaPlayer.py b/lib/python/Components/MediaPlayer.py index 5583b22..35fdce1 100755 --- a/lib/python/Components/MediaPlayer.py +++ b/lib/python/Components/MediaPlayer.py @@ -6,6 +6,7 @@ from os import path from enigma import eListboxPythonMultiContent, RT_VALIGN_CENTER, gFont, eServiceCenter from Tools.LoadPixmap import LoadPixmap +import skin STATE_PLAY = 0 STATE_PAUSE = 1 @@ -25,7 +26,8 @@ def PlaylistEntryComponent(serviceref, state): text = serviceref.getName() if text is "": text = path.split(serviceref.getPath().split('/')[-1])[1] - res.append((eListboxPythonMultiContent.TYPE_TEXT,25, 1, 470, 22, 0, RT_VALIGN_CENTER, text)) + x, y, w, h = skin.parameters.get("PlayListName",(25, 1, 470, 22)) + res.append((eListboxPythonMultiContent.TYPE_TEXT,x, y, w, h, 0, RT_VALIGN_CENTER, text)) png = None if state == STATE_PLAY: png = PlayIcon @@ -39,15 +41,17 @@ def PlaylistEntryComponent(serviceref, state): png = ForwardIcon if png is not None: - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 5, 3, 16, 16, png)) + x, y, w, h = skin.parameters.get("PlayListIcon",(5, 3, 16, 16)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, x, y, w, h, png)) return res class PlayList(MenuList): def __init__(self, enableWrapAround = False): MenuList.__init__(self, [], enableWrapAround, eListboxPythonMultiContent) - self.l.setFont(0, gFont("Regular", 18)) - self.l.setItemHeight(23) + font = skin.fonts.get("PlayList", ("Regular", 18, 23)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) self.currPlaying = -1 self.oldCurrPlaying = -1 self.serviceHandler = eServiceCenter.getInstance() diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index 5c98e4b..3df3bf2 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -25,6 +25,15 @@ class MovieList(GUIComponent): self.descr_state = descr_state or self.HIDE_DESCRIPTION self.sort_type = sort_type or self.SORT_RECORDED + self.fontName = "Regular" + self.fontSizesOriginal = (22,18,16) + self.fontSizesCompact = (20,14) + self.fontSizesMinimal = (20,16) + self.itemHeights = (75,37,25) + self.columnsOriginal = (180,200) + self.columnsCompactDescription = (120,154,58) + self.compactColumn = (75,200) + self.l = eListboxPythonMultiContent() self.tags = set() @@ -57,20 +66,63 @@ class MovieList(GUIComponent): def setSortType(self, type): self.sort_type = type + def applySkin(self, desktop, parent): + def warningWrongSkinParameter(string): + print "[MovieList] wrong '%s' skin parameters" % string + def fontName(value): + self.fontName = value + def fontSizesOriginal(value): + self.fontSizesOriginal = map(int, value.split(",")) + if len(self.fontSizesOriginal) != 3: + warningWrongSkinParameter(attrib) + def fontSizesCompact(value): + self.fontSizesCompact = map(int, value.split(",")) + if len(self.fontSizesCompact) != 2: + warningWrongSkinParameter(attrib) + def fontSizesMinimal(value): + self.fontSizesMinimal = map(int, value.split(",")) + if len(self.fontSizesMinimal) != 2: + warningWrongSkinParameter(attrib) + def itemHeights(value): + self.itemHeights = map(int, value.split(",")) + if len(self.itemHeights) != 3: + warningWrongSkinParameter(attrib) + def columnsOriginal(value): + self.columnsOriginal = map(int, value.split(",")) + if len(self.columnsOriginal) != 2: + warningWrongSkinParameter(attrib) + def columnsCompactDescription(value): + self.columnsCompactDescription = map(int, value.split(",")) + if len(self.columnsCompactDescription) != 3: + warningWrongSkinParameter(attrib) + def compactColumn(value): + self.compactColumn = map(int, value.split(",")) + if len(self.compactColumn) != 2: + warningWrongSkinParameter(attrib) + for (attrib, value) in self.skinAttributes[:]: + try: + locals().get(attrib)(value) + self.skinAttributes.remove((attrib, value)) + except: + pass + self.redrawList() + return GUIComponent.applySkin(self, desktop, parent) + def redrawList(self): if self.list_type == MovieList.LISTTYPE_ORIGINAL: - self.l.setFont(0, gFont("Regular", 22)) - self.l.setFont(1, gFont("Regular", 18)) - self.l.setFont(2, gFont("Regular", 16)) - self.l.setItemHeight(75) + for i in range(3): + self.l.setFont(i, gFont(self.fontName, self.fontSizesOriginal[i])) + self.itemHeight = self.itemHeights[0] elif self.list_type == MovieList.LISTTYPE_COMPACT_DESCRIPTION or self.list_type == MovieList.LISTTYPE_COMPACT: - self.l.setFont(0, gFont("Regular", 20)) - self.l.setFont(1, gFont("Regular", 14)) self.l.setItemHeight(37) + for i in range(2): + self.l.setFont(i, gFont(self.fontName, self.fontSizesCompact[i])) + self.itemHeight = self.itemHeights[1] else: - self.l.setFont(0, gFont("Regular", 20)) - self.l.setFont(1, gFont("Regular", 16)) - self.l.setItemHeight(25) + for i in range(2): + self.l.setFont(i, gFont(self.fontName, self.fontSizesMinimal[i])) + self.itemHeight = self.itemHeights[2] + self.l.setItemHeight(self.itemHeight) # # | name of movie | @@ -106,45 +158,54 @@ class MovieList(GUIComponent): if begin > 0: t = FuzzyTime(begin) begin_string = t[0] + ", " + t[1] - + ih = self.itemHeight if self.list_type == MovieList.LISTTYPE_ORIGINAL: - res.append(MultiContentEntryText(pos=(0, 0), size=(width-182, 30), font = 0, flags = RT_HALIGN_LEFT, text=txt)) + fc, sc = self.columnsOriginal[0], self.columnsOriginal[1] + ih1 = (ih * 2) / 5 # 75 -> 30 + ih2 = (ih * 2) / 3 # 75 -> 50 + res.append(MultiContentEntryText(pos=(0, 0), size=(width-fc-2, ih1), font = 0, flags = RT_HALIGN_LEFT, text=txt)) if self.tags: - res.append(MultiContentEntryText(pos=(width-180, 0), size=(180, 30), font = 2, flags = RT_HALIGN_RIGHT, text = tags)) + res.append(MultiContentEntryText(pos=(width-fc, 0), size=(fc, ih1), font = 2, flags = RT_HALIGN_RIGHT, text = tags)) if service is not None: - res.append(MultiContentEntryText(pos=(200, 50), size=(200, 20), font = 1, flags = RT_HALIGN_LEFT, text = service.getServiceName())) + res.append(MultiContentEntryText(pos=(sc, ih2), size=(sc, ih2-ih1), font = 1, flags = RT_HALIGN_LEFT, text = service.getServiceName())) else: if service is not None: - res.append(MultiContentEntryText(pos=(width-180, 0), size=(180, 30), font = 2, flags = RT_HALIGN_RIGHT, text = service.getServiceName())) - res.append(MultiContentEntryText(pos=(0, 30), size=(width, 20), font=1, flags=RT_HALIGN_LEFT, text=description)) - res.append(MultiContentEntryText(pos=(0, 50), size=(200, 20), font=1, flags=RT_HALIGN_LEFT, text=begin_string)) - res.append(MultiContentEntryText(pos=(width-200, 50), size=(198, 20), font=1, flags=RT_HALIGN_RIGHT, text=len)) + res.append(MultiContentEntryText(pos=(width-fc, 0), size=(fc, ih1), font = 2, flags = RT_HALIGN_RIGHT, text = service.getServiceName())) + res.append(MultiContentEntryText(pos=(0, ih1), size=(width, ih2-ih1), font=1, flags=RT_HALIGN_LEFT, text=description)) + res.append(MultiContentEntryText(pos=(0, ih2), size=(sc, ih2-ih1), font=1, flags=RT_HALIGN_LEFT, text=begin_string)) + res.append(MultiContentEntryText(pos=(width-sc, ih2), size=(sc-2, ih2-ih1), font=1, flags=RT_HALIGN_RIGHT, text=len)) elif self.list_type == MovieList.LISTTYPE_COMPACT_DESCRIPTION: - res.append(MultiContentEntryText(pos=(0, 0), size=(width-120, 20), font = 0, flags = RT_HALIGN_LEFT, text = txt)) - res.append(MultiContentEntryText(pos=(0, 20), size=(width-212, 17), font=1, flags=RT_HALIGN_LEFT, text=description)) - res.append(MultiContentEntryText(pos=(width-120, 6), size=(120, 20), font=1, flags=RT_HALIGN_RIGHT, text=begin_string)) + ih1 = ((ih * 8) + 14) / 15 # 37 -> 20, round up + fc, sc, lc = self.columnsCompactDescription[0], self.columnsCompactDescription[1], self.columnsCompactDescription[2] + res.append(MultiContentEntryText(pos=(0, 0), size=(width-fc, ih1), font = 0, flags = RT_HALIGN_LEFT, text = txt)) + res.append(MultiContentEntryText(pos=(0, ih1), size=(width-sc-lc, ih-ih1), font=1, flags=RT_HALIGN_LEFT, text=description)) + res.append(MultiContentEntryText(pos=(width-fc, 6), size=(fc, ih1), font=1, flags=RT_HALIGN_RIGHT, text=begin_string)) if service is not None: - res.append(MultiContentEntryText(pos=(width-212, 20), size=(154, 17), font = 1, flags = RT_HALIGN_RIGHT, text = service.getServiceName())) - res.append(MultiContentEntryText(pos=(width-58, 20), size=(58, 20), font=1, flags=RT_HALIGN_RIGHT, text=len)) + res.append(MultiContentEntryText(pos=(width-sc-lc, ih1), size=(sc, ih-ih1), font = 1, flags = RT_HALIGN_RIGHT, text = service.getServiceName())) + res.append(MultiContentEntryText(pos=(width-lc, ih1), size=(lc, ih1), font=1, flags=RT_HALIGN_RIGHT, text=len)) elif self.list_type == MovieList.LISTTYPE_COMPACT: - res.append(MultiContentEntryText(pos=(0, 0), size=(width-77, 20), font = 0, flags = RT_HALIGN_LEFT, text = txt)) + ih1 = ((ih * 8) + 14) / 15 # 37 -> 20, round up + lc, col = self.compactColumn[0], self.compactColumn[1] + res.append(MultiContentEntryText(pos=(0, 0), size=(width-lc-2, ih1), font = 0, flags = RT_HALIGN_LEFT, text = txt)) if self.tags: - res.append(MultiContentEntryText(pos=(width-200, 20), size=(200, 17), font = 1, flags = RT_HALIGN_RIGHT, text = tags)) + res.append(MultiContentEntryText(pos=(width-col, ih1), size=(col, ih-ih1), font = 1, flags = RT_HALIGN_RIGHT, text = tags)) if service is not None: - res.append(MultiContentEntryText(pos=(200, 20), size=(200, 17), font = 1, flags = RT_HALIGN_LEFT, text = service.getServiceName())) + res.append(MultiContentEntryText(pos=(col, ih1), size=(col, ih-ih1), font = 1, flags = RT_HALIGN_LEFT, text = service.getServiceName())) else: if service is not None: - res.append(MultiContentEntryText(pos=(width-200, 20), size=(200, 17), font = 1, flags = RT_HALIGN_RIGHT, text = service.getServiceName())) - res.append(MultiContentEntryText(pos=(0, 20), size=(200, 17), font=1, flags=RT_HALIGN_LEFT, text=begin_string)) - res.append(MultiContentEntryText(pos=(width-75, 0), size=(75, 20), font=0, flags=RT_HALIGN_RIGHT, text=len)) + res.append(MultiContentEntryText(pos=(width-col, ih1), size=(col, ih-ih1), font = 1, flags = RT_HALIGN_RIGHT, text = service.getServiceName())) + res.append(MultiContentEntryText(pos=(0, ih1), size=(col, ih-ih1), font=1, flags=RT_HALIGN_LEFT, text=begin_string)) + res.append(MultiContentEntryText(pos=(width-lc, 0), size=(lc, ih1), font=0, flags=RT_HALIGN_RIGHT, text=len)) else: assert(self.list_type == MovieList.LISTTYPE_MINIMAL) if self.descr_state == MovieList.SHOW_DESCRIPTION: - res.append(MultiContentEntryText(pos=(0, 0), size=(width-146, 20), font = 0, flags = RT_HALIGN_LEFT, text = txt)) - res.append(MultiContentEntryText(pos=(width-145, 4), size=(145, 20), font=1, flags=RT_HALIGN_RIGHT, text=begin_string)) + dateSize = ih * 145 / 20 # 20 -> 145 + res.append(MultiContentEntryText(pos=(0, 0), size=(width-dateSize, ih), font = 0, flags = RT_HALIGN_LEFT, text = txt)) + res.append(MultiContentEntryText(pos=(width-dateSize, 4), size=(dateSize, ih), font=1, flags=RT_HALIGN_RIGHT, text=begin_string)) else: - res.append(MultiContentEntryText(pos=(0, 0), size=(width-77, 20), font = 0, flags = RT_HALIGN_LEFT, text = txt)) - res.append(MultiContentEntryText(pos=(width-75, 0), size=(75, 20), font=0, flags=RT_HALIGN_RIGHT, text=len)) + lenSize = ih * 75 / 20 # 20 -> 75 + res.append(MultiContentEntryText(pos=(0, 0), size=(width-lenSize-2, ih), font = 0, flags = RT_HALIGN_LEFT, text = txt)) + res.append(MultiContentEntryText(pos=(width-lenSize, 0), size=(lenSize, ih), font=0, flags=RT_HALIGN_RIGHT, text=len)) return res diff --git a/lib/python/Components/ParentalControlList.py b/lib/python/Components/ParentalControlList.py index 0e65257..e6425b7 100644 --- a/lib/python/Components/ParentalControlList.py +++ b/lib/python/Components/ParentalControlList.py @@ -4,6 +4,7 @@ from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT from Tools.LoadPixmap import LoadPixmap +import skin #Now there is a list of pictures instead of one... entryPicture = {} @@ -28,8 +29,9 @@ def ParentalControlEntryComponent(service, name, protectionType): class ParentalControlList(MenuList): def __init__(self, list, enableWrapAround = False): MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent) - self.l.setFont(0, gFont("Regular", 20)) - self.l.setItemHeight(32) + font = skin.fonts.get("ParentalControlList", ("Regular", 20, 32)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) def toggleSelectedLock(self): from Components.ParentalControl import parentalControl diff --git a/lib/python/Components/PluginList.py b/lib/python/Components/PluginList.py index 39c60ff..fee11ef 100644 --- a/lib/python/Components/PluginList.py +++ b/lib/python/Components/PluginList.py @@ -5,44 +5,55 @@ from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixm from enigma import eListboxPythonMultiContent, gFont from Tools.LoadPixmap import LoadPixmap +import skin -def PluginEntryComponent(plugin): +def PluginEntryComponent(plugin, width=440): if plugin.icon is None: png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/plugin.png")) else: png = plugin.icon + nx, ny, nh = skin.parameters.get("PluginBrowserName",(120, 5, 25)) + dx, dy, dh = skin.parameters.get("PluginBrowserDescr",(120, 26, 17)) + ix, iy, iw, ih = skin.parameters.get("PluginBrowserIcon",(10, 5, 100, 40)) return [ plugin, - MultiContentEntryText(pos=(120, 5), size=(320, 25), font=0, text=plugin.name), - MultiContentEntryText(pos=(120, 26), size=(320, 17), font=1, text=plugin.description), - MultiContentEntryPixmapAlphaTest(pos=(10, 5), size=(100, 40), png = png) + MultiContentEntryText(pos=(nx, ny), size=(width-nx, nh), font=0, text=plugin.name), + MultiContentEntryText(pos=(dx, dy), size=(width-dx, dh), font=1, text=plugin.description), + MultiContentEntryPixmapAlphaTest(pos=(ix, iy), size=(iw, ih), png = png) ] -def PluginCategoryComponent(name, png): +def PluginCategoryComponent(name, png, width=440): + x, y, h = skin.parameters.get("PluginBrowserDownloadName",(120, 5, 25)) + ix, iy, iw, ih = skin.parameters.get("PluginBrowserDownloadIcon",(10, 0, 100, 50)) return [ name, - MultiContentEntryText(pos=(120, 5), size=(320, 25), font=0, text=name), - MultiContentEntryPixmapAlphaTest(pos=(10, 0), size=(100, 50), png = png) + MultiContentEntryText(pos=(x, y), size=(width-x, h), font=0, text=name), + MultiContentEntryPixmapAlphaTest(pos=(ix, iy), size=(iw, ih), png = png) ] -def PluginDownloadComponent(plugin, name): +def PluginDownloadComponent(plugin, name, width=440): if plugin.icon is None: png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/plugin.png")) else: png = plugin.icon + x, y, h = skin.parameters.get("PluginBrowserDownloadName",(120, 5, 25)) + dx, dy, dh = skin.parameters.get("PluginBrowserDownloadDescr",(120, 26, 17)) + ix, iy, iw, ih = skin.parameters.get("PluginBrowserDownloadIcon",(10, 0, 100, 50)) return [ plugin, - MultiContentEntryText(pos=(120, 5), size=(320, 25), font=0, text=name), - MultiContentEntryText(pos=(120, 26), size=(320, 17), font=1, text=plugin.description), - MultiContentEntryPixmapAlphaTest(pos=(10, 0), size=(100, 50), png = png) + MultiContentEntryText(pos=(x, y), size=(width-x, h), font=0, text=name), + MultiContentEntryText(pos=(dx, dy), size=(width-dx, dh), font=1, text=plugin.description), + MultiContentEntryPixmapAlphaTest(pos=(ix, iy), size=(iw, ih), png = png) ] class PluginList(MenuList): def __init__(self, list, enableWrapAround=False): MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent) - self.l.setFont(0, gFont("Regular", 20)) - self.l.setFont(1, gFont("Regular", 14)) - self.l.setItemHeight(50) + font = skin.fonts.get("PluginBrowser0", ("Regular", 20, 50)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) + font = skin.fonts.get("PluginBrowser1", ("Regular", 14)) + self.l.setFont(1, gFont(font[0], font[1])) diff --git a/lib/python/Components/SelectionList.py b/lib/python/Components/SelectionList.py index 1c5423f..030f7c5 100755 --- a/lib/python/Components/SelectionList.py +++ b/lib/python/Components/SelectionList.py @@ -2,6 +2,7 @@ from MenuList import MenuList from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT from Tools.LoadPixmap import LoadPixmap +import skin selectionpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/selectioncross.png")) @@ -17,8 +18,9 @@ def SelectionEntryComponent(description, value, index, selected): class SelectionList(MenuList): def __init__(self, list = None, enableWrapAround = False): MenuList.__init__(self, list or [], enableWrapAround, content = eListboxPythonMultiContent) - self.l.setFont(0, gFont("Regular", 20)) - self.l.setItemHeight(30) + font = skin.fonts.get("SelectionList", ("Regular", 20, 30)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) def addSelection(self, description, value, index, selected = True): self.list.append(SelectionEntryComponent(description, value, index, selected)) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index f9c4065..67f2e75 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -29,3 +29,6 @@ SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs() SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0") SystemInfo["FrontpanelDisplayGrayscale"] = fileExists("/dev/dbox/oled0") SystemInfo["DeepstandbySupport"] = HardwareInfo().get_device_name() != "dm800" +SystemInfo["HdmiInSupport"] = HardwareInfo().get_vu_device_name() == "ultimo4k" +SystemInfo["WOWLSupport"] = HardwareInfo().get_vu_device_name() == "ultimo4k" + diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index 30097c9..f895bd8 100755 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -1,5 +1,6 @@ from HTMLComponent import HTMLComponent from GUIComponent import GUIComponent +from skin import parseFont from Tools.FuzzyDate import FuzzyTime @@ -17,8 +18,14 @@ class TimerList(HTMLComponent, GUIComponent, object): def buildTimerEntry(self, timer, processed): width = self.l.getItemSize().width() res = [ None ] - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.service_ref.getServiceName())) - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 30, width, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.name)) + print "timer.service_ref.getServiceName() : ", timer.service_ref.getServiceName() + print "timer.name : ", timer.name + ih = self.itemHeight + ih1 = ih * 30 / 70 # 70 -> 30 + ih2 = ih * 20 / 70 # 70 -> 20 + stateSize = ih * 150 / 70 # 20 -> 145 + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, ih1, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.service_ref.getServiceName())) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1, width, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.name)) repeatedtext = "" days = ( _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun") ) @@ -34,19 +41,19 @@ class TimerList(HTMLComponent, GUIComponent, object): flags = flags >> 1 if timer.justplay: if timer.end - timer.begin < 4: # rounding differences - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.begin)[1])))) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1+ih2, width-stateSize, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.begin)[1])))) else: - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ") ") % (FuzzyTime(timer.begin)[1], FuzzyTime(timer.end)[1], (timer.end - timer.begin) / 60)) + _("(ZAP)"))) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1+ih2, width-stateSize, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ") ") % (FuzzyTime(timer.begin)[1], FuzzyTime(timer.end)[1], (timer.end - timer.begin) / 60)) + _("(ZAP)"))) else: - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin)[1], FuzzyTime(timer.end)[1], (timer.end - timer.begin) / 60)))) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1+ih2, width-stateSize, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin)[1], FuzzyTime(timer.end)[1], (timer.end - timer.begin) / 60)))) else: if timer.justplay: if timer.end - timer.begin < 4: - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s " + _("(ZAP)")) % (FuzzyTime(timer.begin))))) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1+ih2, width-stateSize, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s " + _("(ZAP)")) % (FuzzyTime(timer.begin))))) else: - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ") ") % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:] + ((timer.end - timer.begin) / 60,))) + _("(ZAP)"))) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1+ih2, width-stateSize, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ") ") % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:] + ((timer.end - timer.begin) / 60,))) + _("(ZAP)"))) else: - res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:] + ((timer.end - timer.begin) / 60,))))) + res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, ih1+ih2, width-stateSize, ih2, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:] + ((timer.end - timer.begin) / 60,))))) if not processed: if timer.state == TimerEntry.StateWaiting: @@ -68,21 +75,41 @@ class TimerList(HTMLComponent, GUIComponent, object): if timer.disabled: state = _("disabled") - res.append((eListboxPythonMultiContent.TYPE_TEXT, width-150, 50, 150, 20, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, width-stateSize, ih1+ih2, stateSize, ih2, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state)) if timer.disabled: + iconPosX = width * 490 / 740 png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/redx.png")) - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 490, 5, 40, 40, png)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, iconPosX, 5, 40, 40, png)) return res def __init__(self, list): GUIComponent.__init__(self) self.l = eListboxPythonMultiContent() self.l.setBuildFunc(self.buildTimerEntry) - self.l.setFont(0, gFont("Regular", 20)) - self.l.setFont(1, gFont("Regular", 18)) - self.l.setItemHeight(70) + self.serviceNameFont = gFont("Regular", 20) + self.font = gFont("Regular", 18) + self.itemHeight = 70 self.l.setList(list) + + def applySkin(self, desktop, parent): + def itemHeight(value): + self.itemHeight = int(value) + def setServiceNameFont(value): + self.serviceNameFont = parseFont(value, ((1,1),(1,1))) + def setFont(value): + self.font = parseFont(value, ((1,1),(1,1))) + + for (attrib, value) in list(self.skinAttributes): + try: + locals().get(attrib)(value) + self.skinAttributes.remove((attrib, value)) + except: + pass + self.l.setFont(0, self.serviceNameFont) + self.l.setFont(1, self.font) + self.l.setItemHeight(self.itemHeight) + return GUIComponent.applySkin(self, desktop, parent) def getCurrent(self): cur = self.l.getCurrentSelection() diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py index 1d621f4..1f081e6 100755 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py @@ -1,4 +1,4 @@ -from skin import parseColor +from skin import parseColor, parseFont, parseSize from Components.config import config, ConfigClock, ConfigInteger from Components.Pixmap import Pixmap from Components.Button import Button @@ -36,7 +36,6 @@ class EPGList(HTMLComponent, GUIComponent): self.onSelChanged.append(selChangedCB) GUIComponent.__init__(self) self.l = eListboxPythonMultiContent() - self.l.setItemHeight(54); self.l.setBuildFunc(self.buildEntry) if overjump_empty: self.l.setSelectableFunc(self.isSelectable) @@ -58,28 +57,41 @@ class EPGList(HTMLComponent, GUIComponent): self.backColorSelected = 0x808080 self.foreColorService = None self.backColorService = None + self.serviceFont = gFont("Regular", 20) + self.entryFont = gFont("Regular", 14) + self.itemHeight = 54 def applySkin(self, desktop, screen): - if self.skinAttributes is not None: - attribs = [ ] - for (attrib, value) in self.skinAttributes: - if attrib == "EntryForegroundColor": - self.foreColor = parseColor(value).argb() - elif attrib == "EntryForegroundColorSelected": - self.foreColorSelected = parseColor(value).argb() - elif attrib == "EntryBorderColor": - self.borderColor = parseColor(value).argb() - elif attrib == "EntryBackgroundColor": - self.backColor = parseColor(value).argb() - elif attrib == "EntryBackgroundColorSelected": - self.backColorSelected = parseColor(value).argb() - elif attrib == "ServiceNameForegroundColor": - self.foreColorService = parseColor(value).argb() - elif attrib == "ServiceNameBackgroundColor": - self.backColorService = parseColor(value).argb() - else: - attribs.append((attrib,value)) - self.skinAttributes = attribs + def EntryForegroundColor(value): + self.foreColor = parseColor(value).argb() + def EntryForegroundColorSelected(value): + self.foreColorSelected = parseColor(value).argb() + def EntryBackgroundColor(value): + self.backColor = parseColor(value).argb() + def EntryBackgroundColorSelected(value): + self.backColorSelected = parseColor(value).argb() + def EntryBorderColor(value): + self.borderColor = parseColor(value).argb() + def EntryItemHeight(value): + self.itemHeight = int(value) + def ServiceNameForegroundColor(value): + self.foreColorService = parseColor(value).argb() + def ServiceNameBackgroundColor(value): + self.backColorService = parseColor(value).argb() + def ServiceFont(value): + self.serviceFont = parseFont(value, ((1,1),(1,1)) ) + def EntryFont(value): + self.entryFont = parseFont(value, ((1,1),(1,1)) ) + + for (attrib, value) in list(self.skinAttributes): + try: + locals().get(attrib)(value) + self.skinAttributes.remove((attrib, value)) + except: + pass + self.l.setFont(0, self.serviceFont) + self.l.setFont(1, self.entryFont) + self.l.setItemHeight(self.itemHeight) return GUIComponent.applySkin(self, desktop, screen) def isSelectable(self, service, sname, event_list): @@ -190,8 +202,6 @@ class EPGList(HTMLComponent, GUIComponent): instance.setWrapAround(True) instance.selectionChanged.get().append(self.serviceChanged) instance.setContent(self.l) - self.l.setFont(0, gFont("Regular", 20)) - self.l.setFont(1, gFont("Regular", 14)) self.l.setSelectionClip(eRect(0,0,0,0), False) def preWidgetRemove(self, instance): @@ -382,21 +392,44 @@ class TimelineText(HTMLComponent, GUIComponent): GUIComponent.__init__(self) self.l = eListboxPythonMultiContent() self.l.setSelectionClip(eRect(0,0,0,0)) - self.l.setItemHeight(25); - self.l.setFont(0, gFont("Regular", 20)) + self.foreColor = 0xffc000 + self.backColor = 0x000000 + self.font = gFont("Regular", 20) + self.itemHeight = 25 GUI_WIDGET = eListbox + def applySkin(self, desktop, screen): + def foregroundColor(value): + self.foreColor = parseColor(value).argb() + def backgroundColor(value): + self.backColor = parseColor(value).argb() + def font(value): + self.font = parseFont(value, ((1, 1), (1, 1)) ) + def itemHeight(value): + self.itemHeight = int(value) + for (attrib, value) in list(self.skinAttributes): + try: + locals().get(attrib)(value) + self.skinAttributes.remove((attrib, value)) + except: + pass + self.l.setFont(0, self.font) + self.l.setItemHeight(self.itemHeight); + return GUIComponent.applySkin(self, desktop, screen) + def postWidgetCreate(self, instance): instance.setContent(self.l) def setEntries(self, entries): + ih = self.itemHeight + width = ih * 60 / 25 res = [ None ] # no private data needed for x in entries: tm = x[0] xpos = x[1] str = strftime("%H:%M", localtime(tm)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, xpos-30, 0, 60, 25, 0, RT_HALIGN_CENTER|RT_VALIGN_CENTER, str)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, xpos-30, 0, width, ih, 0, RT_HALIGN_CENTER|RT_VALIGN_CENTER, str)) self.l.setList([res]) config.misc.graph_mepg_prev_time=ConfigClock(default = time()) diff --git a/lib/python/Plugins/SystemPlugins/Makefile.am b/lib/python/Plugins/SystemPlugins/Makefile.am index 950b50e..a5c65be 100755 --- a/lib/python/Plugins/SystemPlugins/Makefile.am +++ b/lib/python/Plugins/SystemPlugins/Makefile.am @@ -8,7 +8,7 @@ SUBDIRS = SoftwareManager FrontprocessorUpgrade PositionerSetup Satfinder \ Blindscan RemoteControlCode UI3DSetup UIPositionSetup HDMICEC LEDBrightnessSetup \ FirmwareUpgrade CrashReport 3GModemManager WirelessAccessPoint ZappingModeSelection \ DeviceManager TransCodingSetup WOLSetup NetDrive AudioEffect AnimationSetup \ - BoxModeConfig Solo4kMiscControl FastChannelChange + BoxModeConfig Solo4kMiscControl FastChannelChange Ultimo4kMiscControl install_PYTHON = \ __init__.py diff --git a/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/Makefile.am b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/Makefile.am new file mode 100644 index 0000000..c7cc202 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/Makefile.am @@ -0,0 +1,7 @@ +installdir = $(pkglibdir)/python/Plugins/SystemPlugins/Ultimo4kMiscControl + +SUBDIRS = meta + +install_PYTHON = \ + __init__.py \ + plugin.py diff --git a/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/__init__.py b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/__init__.py new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/__init__.py @@ -0,0 +1 @@ + diff --git a/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/Makefile.am b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/Makefile.am new file mode 100644 index 0000000..e23527e --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/Makefile.am @@ -0,0 +1,3 @@ +installdir = $(datadir)/meta + +dist_install_DATA = plugin_ultimo4kmisccontrol.xml diff --git a/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/plugin_ultimo4kmisccontrol.xml b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/plugin_ultimo4kmisccontrol.xml new file mode 100644 index 0000000..7440ede --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/plugin_ultimo4kmisccontrol.xml @@ -0,0 +1,16 @@ + + + + + + hschang + Ultimo4kMiscControl + enigma2-plugin-systemplugins-ultimo4kmisccontrol + set Ultimo4K LNB Power and etc.. + Control LNB Power and ToneBurst,CI delay for Ultimo4K. + + + + + + diff --git a/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/plugin.py b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/plugin.py new file mode 100644 index 0000000..d9cd261 --- /dev/null +++ b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/plugin.py @@ -0,0 +1,116 @@ +from Screens.Screen import Screen +from Components.ConfigList import ConfigListScreen +from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigSelection +from Components.ActionMap import ActionMap +from Screens.MessageBox import MessageBox +from Components.Sources.StaticText import StaticText +from Plugins.Plugin import PluginDescriptor +from Tools.Directories import fileExists + +config.plugins.ultimo4kMiscControl = ConfigSubsection() +config.plugins.ultimo4kMiscControl.forceLnbPower = ConfigSelection(default = "off", choices = [ ("on", _("Yes")), ("off", _("No"))] ) +config.plugins.ultimo4kMiscControl.forceToneBurst = ConfigSelection(default = "disable", choices = [ ("enable", _("Yes")), ("disable", _("No"))] ) +config.plugins.ultimo4kMiscControl.dvbCiDelay = ConfigSelection(default = "256", choices = [ ("16", _("16")), ("32", _("32")), ("64", _("64")), ("128", _("128")), ("256", _("256"))] ) + +PROC_FORCE_LNBPOWER = "/proc/stb/frontend/fbc/force_lnbon" +PROC_FORCE_TONEBURST = "/proc/stb/frontend/fbc/force_toneburst" +PROC_DVB_CI_DELAY = "/proc/stb/tsmux/rmx_delay" + +def setProcValueOnOff(value, procPath): + try: + print "[ultimo4kMiscControl] set %s : %s" % (procPath, value) + fd = open(procPath,'w') + fd.write(value) + fd.close() + return 0 + except Exception, e: + print "[ultimo4kMiscControl] proc write Error", e + return -1 + + +from enigma import eTimer +class checkDriverSupport: + def __init__(self): + self.onLayoutFinish.append(self.procCheck) + self.dispErrorTimer = eTimer() + self.dispErrorTimer.callback.append(self.dispErrorMsg) + + def procCheck(self): + if not (fileExists(PROC_FORCE_LNBPOWER) and fileExists(PROC_FORCE_TONEBURST) and fileExists(PROC_DVB_CI_DELAY)): + self.dispErrorTimer.start(0, True) + + def dispErrorMsg(self): + self.session.openWithCallback(self.close ,MessageBox, _("Driver is not supported."), MessageBox.TYPE_ERROR) + +class ultimo4kMiscControl(Screen, ConfigListScreen, checkDriverSupport): + skin = """ + + + + + + + + """ + + def __init__(self,session): + Screen.__init__(self,session) + self.session = session + self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions" ], + { + "ok": self.keySave, + "cancel": self.keyCancel, + "red": self.keyCancel, + "green": self.keySave, + }, -2) + self.list = [] + ConfigListScreen.__init__(self, self.list,session = self.session) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Ok")) + self.createSetup() + + checkDriverSupport.__init__(self) + + def createSetup(self): + self.list = [] + self.lnbPowerEntry = getConfigListEntry(_("Force LNB Power"), config.plugins.ultimo4kMiscControl.forceLnbPower) + self.toneBurstEntry = getConfigListEntry(_("Force ToneBurst"), config.plugins.ultimo4kMiscControl.forceToneBurst) + self.ciDelayEntry = getConfigListEntry(_("DVB CI Delay"), config.plugins.ultimo4kMiscControl.dvbCiDelay) + self.list.append( self.lnbPowerEntry ) + self.list.append( self.toneBurstEntry ) + self.list.append( self.ciDelayEntry ) + self["config"].list = self.list + self["config"].l.setList(self.list) + + def keySave(self): + res = setProcValueOnOff(config.plugins.ultimo4kMiscControl.forceLnbPower.value, PROC_FORCE_LNBPOWER) + if res == 0: + res = setProcValueOnOff(config.plugins.ultimo4kMiscControl.forceToneBurst.value, PROC_FORCE_TONEBURST) + if res == 0: + res = setProcValueOnOff(config.plugins.ultimo4kMiscControl.dvbCiDelay.value, PROC_DVB_CI_DELAY) + + if res == -1: + self.resetConfig() + self.session.openWithCallback(self.close, MessageBox, _("SET FAILED!\n"), MessageBox.TYPE_ERROR) + else: + self.saveAll() + self.close() + + def resetConfig(self): + for x in self["config"].list: + x[1].cancel() + +def main(session, **kwargs): + session.open(ultimo4kMiscControl) + +def OnSessionStart(session, **kwargs): + setProcValueOnOff(config.plugins.ultimo4kMiscControl.forceLnbPower.value, PROC_FORCE_LNBPOWER) + setProcValueOnOff(config.plugins.ultimo4kMiscControl.forceToneBurst.value, PROC_FORCE_TONEBURST) + setProcValueOnOff(config.plugins.ultimo4kMiscControl.dvbCiDelay.value, PROC_DVB_CI_DELAY) + +def Plugins(**kwargs): + pList = [] + pList.append( PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, fnc=OnSessionStart) ) + pList.append( PluginDescriptor(name=_("Ultimo4K Misc. Control"), description="set Ultimo4K LNB Power and etc..", where = PluginDescriptor.WHERE_PLUGINMENU, needsRestart = False, fnc=main) ) + return pList + diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index 8781659..6b5d4d7 100644 --- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py +++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py @@ -62,10 +62,10 @@ class VideoHardware: } widescreen_modes = set(["720p", "1080i", "1080p", "2160p"]) - hdmi_hw_types = set(["dm500", "dm800se", "dm7020hd", "bm750", "solo", "uno", "ultimo", "solo2", "duo2", "solose", "zero", "solo4k"]) - hdmi_pc_hw_types = set(["dm500", "dm800se", "dm7020hd", "bm750", "solo", "uno", "ultimo", "solo2", "duo2", "solose", "zero", "solo4k"]) - noscart_hw_types = set(["zero", "solo4k"]) - noypbpr_hw_types = set(["solose", "zero", "solo4k"]) + hdmi_hw_types = set(["dm500", "dm800se", "dm7020hd", "bm750", "solo", "uno", "ultimo", "solo2", "duo2", "solose", "zero", "solo4k", "ultimo4k", "uno4k"]) + hdmi_pc_hw_types = set(["dm500", "dm800se", "dm7020hd", "bm750", "solo", "uno", "ultimo", "solo2", "duo2", "solose", "zero", "solo4k", "ultimo4k", "uno4k"]) + noscart_hw_types = set(["zero", "solo4k", "ultimo4k", "uno4k"]) + noypbpr_hw_types = set(["solose", "zero", "solo4k", "ultimo4k", "uno4k"]) def getDeviceName(self): device_name = "unknown" @@ -80,10 +80,10 @@ class VideoHardware: return device_name def isVumodel(self, hw_type): - return hw_type in set(["bm750", "solo", "uno", "ultimo", "solo2", "duo2", "solose", "zero", "solo4k"]) + return hw_type in set(["bm750", "solo", "uno", "ultimo", "solo2", "duo2", "solose", "zero", "solo4k", "ultimo4k", "uno4k"]) def isVumodel4K(self, hw_type): - return hw_type in set(["solo4k"]) + return hw_type in set(["solo4k", "ultimo4k", "uno4k"]) # re-define AVSwitch.getOutputAspect def getOutputAspect(self): diff --git a/lib/python/Plugins/SystemPlugins/WOLSetup/plugin.py b/lib/python/Plugins/SystemPlugins/WOLSetup/plugin.py index bf29218..6d285fd 100644 --- a/lib/python/Plugins/SystemPlugins/WOLSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/WOLSetup/plugin.py @@ -9,10 +9,12 @@ from Screens.ChoiceBox import ChoiceBox from Screens.MessageBox import MessageBox from Screens.Standby import TryQuitMainloop +from Components.SystemInfo import SystemInfo from Components.PluginComponent import plugins from Components.ConfigList import ConfigListScreen from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigSelection +from Components.Network import iNetwork import os @@ -24,6 +26,8 @@ _flagSupportWol = _flagForceEnable and True or os.path.exists(_deviseWOL) _tryQuitTable = {"deepstandby":1, "reboot":2, "guirestart":3} _ethDevice = "eth0" +if SystemInfo.get("WOWLSupport", False): + _ethDevice = "wlan3" config.plugins.wolconfig = ConfigSubsection() config.plugins.wolconfig.activate = ConfigYesNo(default = False) @@ -46,7 +50,7 @@ class NetTool: class WOLSetup(ConfigListScreen, Screen): skin = """ - + @@ -98,7 +102,13 @@ class WOLSetup(ConfigListScreen, Screen): self.configlist.append(getConfigListEntry(_("WakeOnLan Enable"), config.plugins.wolconfig.activate)) if config.plugins.wolconfig.activate.value: self.configlist.append(getConfigListEntry(_("Location"), config.plugins.wolconfig.location)) - macaddr = "HWaddr of %s is %s" % (_ethDevice, NetTool.GetHardwareAddr(_ethDevice)) + if SystemInfo.get("WOWLSupport", False): + if iNetwork.getAdapterAttribute(_ethDevice, 'up'): + macaddr = "HWaddr of %s is %s" % (_ethDevice, NetTool.GetHardwareAddr(_ethDevice)) + else: + macaddr = "Wireless lan is not activated." + else: + macaddr = "HWaddr of %s is %s" % (_ethDevice, NetTool.GetHardwareAddr(_ethDevice)) else: macaddr = "Wake on Lan disabled" self["introduction"].setText(macaddr) diff --git a/lib/python/Plugins/SystemPlugins/WirelessAccessPoint/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessAccessPoint/plugin.py index f4dce00..5b34d8f 100755 --- a/lib/python/Plugins/SystemPlugins/WirelessAccessPoint/plugin.py +++ b/lib/python/Plugins/SystemPlugins/WirelessAccessPoint/plugin.py @@ -173,6 +173,8 @@ class WirelessAccessPoint(Screen,ConfigListScreen): for x in iNetwork.getInstalledAdapters(): if x.startswith('eth') or x.startswith('br') or x.startswith('mon'): continue + elif os_path.exists("/tmp/bcm/%s"%x): + continue wlanIfaces.append(x) description=self.getAdapterDescription(x) if description == "Unknown network adapter": @@ -181,7 +183,7 @@ class WirelessAccessPoint(Screen,ConfigListScreen): self.wlanDeviceList.append(( x, description + " (%s)"%x )) if len(self.wlanDeviceList) == 0: - self.msg = "Wireless Lan Device is not detected." + self.msg = "Can not find wireless lan devices that support AP mode." return -1 apModeConfig.wirelessdevice = ConfigSelection( choices = self.wlanDeviceList ) diff --git a/lib/python/Plugins/SystemPlugins/WirelessLanSetup/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessLanSetup/plugin.py index 7f53647..0ff7c4f 100755 --- a/lib/python/Plugins/SystemPlugins/WirelessLanSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/WirelessLanSetup/plugin.py @@ -136,6 +136,8 @@ class WlanSelection(Screen,HelpableScreen): return str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter") else: return _("Unknown network adapter") + elif os_path.exists("/tmp/bcm/%s"%iface): + return _("BroadCom WLAN adapter") else: return _("Unknown network adapter") @@ -300,20 +302,20 @@ class WlanSetup(Screen,HelpableScreen): self.session.openWithCallback(self.checklist, WlanConfig, self.iface) def restartLan(self, ret = False): - if (ret == True): + if ret: iNetwork.restartNetwork(self.restartLanDataAvail) self.restartLanRef = self.session.openWithCallback(self.restartfinishedCB, MessageBox, _("Please wait while your network is restarting..."), type = MessageBox.TYPE_INFO, enable_input = False) def restartLanDataAvail(self, data): - if data is True: + if data: iNetwork.getInterfaces(self.getInterfacesDataAvail) def getInterfacesDataAvail(self, data): - if data is True: + if data: self.restartLanRef.close(True) def restartfinishedCB(self,data): - if data is True: + if data: self.session.open(MessageBox, _("Finished restarting your network"), type = MessageBox.TYPE_INFO, timeout = 5, default = False) def cleanup(self): @@ -383,6 +385,8 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): self.updateInterfaces(self.updateInterfaceCB) self.onClose.append(self.cleanup) + self.useWlCommand = os_path.exists("/tmp/bcm/%s"%iface) + def updateInterfaces(self,callback = None): iNetwork.config_ready = False iNetwork.msgPlugins() @@ -395,6 +399,45 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): self.createConfig() self.createSetup() + def getWlConfName(self, iface): + return "/etc/wl.conf.%s" % iface + + def readWlConf(self): + wsconf = {} + wsconf["ssid"] = "Vuplus AP" + wsconf["hidden_ssid"] = False # not used + wsconf["encrypt_mothod"] = "wpa2" + wsconf["wep_keytype"] = "ascii" # not used + wsconf["key"] = "XXXXXXXX" + + wlConfName = self.getWlConfName(self.iface) + + if fileExists(wlConfName): + fd = open(wlConfName, "r") + lines = fd.readlines() + fd.close() + + for line in lines: + try: + (key, value) = line.strip().split('=',1) + except: + continue + + if key == 'ssid': + wsconf["ssid"] = value.strip() + if key == 'method': + wsconf["encrypt_mothod"] = value.strip() + elif key == 'key': + wsconf["key"] = value.strip() + else: + continue + + print "" + for (k,v) in wsconf.items(): + print "[wsconf][%s] %s" % (k , v) + + return wsconf + def getWpaSupplicantName(self, iface): return "/etc/wpa_supplicant.conf.%s" % iface @@ -527,11 +570,16 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): self.displayIP("DNS1", self.primaryDNS) self.displayIP("DNS2", self.secondaryDNS) -# readWPASupplicantConf - wsconf = self.readWpaSupplicantConf() +# read old configuration + if self.useWlCommand: + wsconf = self.readWlConf() + else: + wsconf = self.readWpaSupplicantConf() # method setup - encryptionChoices = [("wep", _("WEP")), ("wpa", _("WPA")), ("wpa2", _("WPA2")), ("wpa/wpa2", _("WPA/WPA2")), ("None", _("No Encrypt")) ] + encryptionChoices = [("wep", _("WEP")), ("wpa", _("WPA")), ("wpa2", _("WPA2")), ("None", _("No Encrypt")) ] + if not self.useWlCommand: + encryptionChoices.append( ("wpa/wpa2", _("WPA/WPA2")) ) self.methodConfigEntry = NoSave(ConfigSelection(default = wsconf["encrypt_mothod"], choices = encryptionChoices)) # key type setup @@ -559,9 +607,11 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): self.usedeviceEntry = getConfigListEntry(_("Use Device"), self.activateInterfaceEntry) self.usedhcpEntry = getConfigListEntry(_("Use DHCP"), self.usedhcpConfigEntry) self.essidEntry = getConfigListEntry(_("SSID"), self.ssidConfigEntry) - self.hiddenessidEntry = getConfigListEntry(_("Hidden Network"), self.hiddenssidConfigEntry) + if not self.useWlCommand: + self.hiddenessidEntry = getConfigListEntry(_("Hidden Network"), self.hiddenssidConfigEntry) self.methodEntry = getConfigListEntry(_("Encrypt Method"), self.methodConfigEntry) - self.keytypeEntry = getConfigListEntry(_("Key Type"), self.keytypeConfigEntry) + if not self.useWlCommand: + self.keytypeEntry = getConfigListEntry(_("Key Type"), self.keytypeConfigEntry) self.keyEntry = getConfigListEntry(_("KEY"), self.keyConfigEntry) self.ipEntry = getConfigListEntry(_("IP"), self.IPConfigEntry) @@ -596,12 +646,16 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): self.configList.append(self.primaryDNSConfigEntry) self.configList.append(self.secondaryDNSConfigEntry) - self.configList.append( self.hiddenessidEntry ) + if not self.useWlCommand: + self.configList.append( self.hiddenessidEntry ) + self.configList.append( self.essidEntry ) self.configList.append( self.methodEntry ) if self.methodConfigEntry.value =="wep": - self.configList.append( self.keytypeEntry ) + if not self.useWlCommand: + self.configList.append( self.keytypeEntry ) + if self.methodConfigEntry.value != "None": self.configList.append( self.keyEntry ) @@ -702,10 +756,47 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): iNetwork.setAdapterAttribute(interface, "up", False) iNetwork.deactivateInterface(interface) - if not self.isWPAMethod(self.methodConfigEntry.value): - self.writeWpasupplicantConf() + plainpwd = None + psk = None + + if self.isWPAMethod(self.methodConfigEntry.value) and (not self.useWlCommand): + (psk, plainpwd) = self.getWpaPhrase() + + res = False + if self.useWlCommand: + res = self.writeWlConf() else: - self.getWpaPhrase() + res = self.writeWpasupplicantConf(psk, plainpwd) + + if res: + self.writeNetConfig() + + def writeWlConf(self): + wsconf = {} + wsconf["ssid"] = "Vuplus AP" + wsconf["hidden_ssid"] = False # not used + wsconf["encrypt_mothod"] = "None" + wsconf["wep_keytype"] = "ascii" # not used + wsconf["key"] = "XXXXXXXX" + + wlConfName = self.getWlConfName(self.iface) + + try: + fd = open(wlConfName, "w") + except: + self.session.open(MessageBox, _("%s open error." % wlConfName ), type = MessageBox.TYPE_ERROR, timeout = 10) + return False + + contents = "" + contents += "ssid="+self.ssidConfigEntry.value+"\n" + contents += "method="+self.methodConfigEntry.value+"\n" + contents += "key="+self.keyConfigEntry.value+"\n" + + print "content = \n"+contents + fd.write(contents) + fd.close() + + return True def getWpaPhrase(self): cmd = "wpa_passphrase '%s' '%s'" % (self.ssidConfigEntry.value, self.keyConfigEntry.value) @@ -724,7 +815,8 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): plainpwd = line elif key == 'psk': psk = line - self.writeWpasupplicantConf(psk, plainpwd) + + return (psk, plainpwd) def writeWpasupplicantConf(self, passphrasekey=None, plainpwd=None): wpaSupplicantName = self.getWpaSupplicantName(self.iface) @@ -732,7 +824,7 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): wpafd = open(wpaSupplicantName, "w") except: self.session.open(MessageBox, _("%s open error." % wpaSupplicantName ), type = MessageBox.TYPE_ERROR, timeout = 10) - return + return False contents = "#WPA Supplicant Configuration by STB\n" contents += "ctrl_interface=/var/run/wpa_supplicant\n" @@ -788,7 +880,8 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): # print "content = \n"+contents wpafd.write(contents) wpafd.close() - self.writeNetConfig() + + return True def writeNetConfig(self): if self.activateInterfaceEntry.value is True: @@ -812,9 +905,13 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen): iNetwork.setAdapterAttribute(self.iface, "up", False) iNetwork.deactivateInterface(self.iface) - wpaSupplicantName = self.getWpaSupplicantName(self.iface) - contents = "\tpre-up wpa_supplicant -i"+self.iface+" -c%s -B -D" % (wpaSupplicantName) +iNetwork.detectWlanModule(self.iface)+"\n" - contents += "\tpost-down wpa_cli terminate\n" + if self.useWlCommand: + contents = '\tpre-up wl-config.sh -m %s -k %s -s "%s" \n' % (self.methodConfigEntry.value, self.keyConfigEntry.value, self.ssidConfigEntry.value) + contents += '\tpost-down wl-down.sh\n' + else: + wpaSupplicantName = self.getWpaSupplicantName(self.iface) + contents = "\tpre-up wpa_supplicant -i"+self.iface+" -c%s -B -D" % (wpaSupplicantName) +iNetwork.detectWlanModule(self.iface)+"\n" + contents += "\tpost-down wpa_cli terminate\n" iNetwork.setAdapterAttribute(self.iface, "configStrings", contents) iNetwork.writeNetworkConfig() iNetwork.restartNetwork(self.updateCurrentInterfaces) @@ -967,6 +1064,8 @@ class WlanScanAp(Screen,HelpableScreen): self.onClose.append(self.__onClose) self.onShown.append(lambda: self.startupTimer.start(10, True)) + self.useWlCommand = os_path.exists("/tmp/bcm/%s"%iface) + def startup(self): if self.oldInterfaceState is not True: self["Status"].setText(("Please wait for activating interface...")) @@ -977,6 +1076,10 @@ class WlanScanAp(Screen,HelpableScreen): def activateIface(self): os_system("ifconfig "+self.iface+" up") iNetwork.setAdapterAttribute(self.iface, "up", True) + + if self.useWlCommand: + os_system("wl up") + self.updateStatusTimer.start(10, True) @@ -1118,6 +1221,9 @@ class WlanScanAp(Screen,HelpableScreen): os_system("ifconfig "+self.iface+" down") iNetwork.setAdapterAttribute(self.iface, "up", False) + if self.useWlCommand: + os_system("wl down") + class NetworkAdapterTest(Screen): def __init__(self, session,iface): Screen.__init__(self, session) diff --git a/lib/python/Screens/InfoBar.py b/lib/python/Screens/InfoBar.py index 4145722..8fec85c 100755 --- a/lib/python/Screens/InfoBar.py +++ b/lib/python/Screens/InfoBar.py @@ -16,7 +16,8 @@ from Screens.InfoBarGenerics import InfoBarShowHide, \ InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift, \ InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \ InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \ - InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman + InfoBarSubtitleSupport, InfoBarPiP, InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarJobman, \ + InfoBarHDMI profile("LOAD:InitBar_Components") from Components.ActionMap import HelpableActionMap @@ -33,7 +34,7 @@ class InfoBar(InfoBarBase, InfoBarShowHide, InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman, - Screen): + InfoBarHDMI, Screen): ALLOW_SUSPEND = True instance = None @@ -57,7 +58,7 @@ class InfoBar(InfoBarBase, InfoBarShowHide, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, \ InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, \ InfoBarTeletextPlugin, InfoBarExtensions, InfoBarPiP, InfoBarSubtitleSupport, InfoBarJobman, \ - InfoBarPlugins, InfoBarServiceErrorPopupSupport: + InfoBarPlugins, InfoBarServiceErrorPopupSupport, InfoBarHDMI: x.__init__(self) self.helpList.append((self["actions"], "InfobarActions", [("showMovies", _("view recordings..."))])) @@ -133,7 +134,7 @@ class MoviePlayer(InfoBarBase, InfoBarShowHide, \ InfoBarSeek, InfoBarShowMovies, InfoBarAudioSelection, HelpableScreen, InfoBarNotifications, InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, Screen, InfoBarTeletextPlugin, - InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP): + InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP, InfoBarHDMI): ENABLE_RESUME_SUPPORT = True ALLOW_SUSPEND = True diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index a6d25d5..2bf91fd 100755 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -2329,3 +2329,47 @@ class InfoBarServiceErrorPopupSupport: Notifications.AddPopup(text = error, type = MessageBox.TYPE_ERROR, timeout = 5, id = "ZapError") else: Notifications.RemovePopup(id = "ZapError") + +class InfoBarHDMI: + def __init__(self): + self.hdmiInServiceRef = eServiceReference('8192:0:1:0:0:0:0:0:0:0:') + if SystemInfo.get("HdmiInSupport", False): + self.addExtension((self.getShowHdmiInName, self.HDMIIn, lambda: True), None) + self.addExtension((self.getShowHdmiInPIPName, self.HDMIInPIP, self.pipShown), None) + + def getShowHdmiInName(self): + curref = self.session.nav.getCurrentlyPlayingServiceReference() + if curref and curref.type == 8192: + name = _("Disable HDMI-IN on Main Screen") + else: + name = _("Enable HDMI-IN on Main Screen") + + return name + + def getShowHdmiInPIPName(self): + curref = self.session.pip.getCurrentService() + if curref and curref.type == 8192: + name = _("Disable HDMI-IN on PIP") + else: + name = _("Enable HDMI-IN on PIP") + + return name + + def getCurrentServiceRef(self): + slist = self.servicelist + currentServiceSref = slist.servicelist.getCurrent() + return currentServiceSref + + def HDMIIn(self): + curref = self.session.nav.getCurrentlyPlayingServiceReference() + if curref and curref.type == 8192: + self.session.nav.playService(self.getCurrentServiceRef()) + else: + self.session.nav.playService(self.hdmiInServiceRef) + + def HDMIInPIP(self): + curref = self.session.pip.getCurrentService() + if curref and curref.type == 8192: + self.session.pip.playService(self.getCurrentServiceRef()) + else: + self.session.pip.playService(self.hdmiInServiceRef) \ No newline at end of file diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py index d423f46..0f7148a 100755 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -46,6 +46,12 @@ class PluginBrowser(Screen): self["SoftwareActions"].setEnabled(False) self.onFirstExecBegin.append(self.checkWarnings) self.onShown.append(self.updateList) + self.onLayoutFinish.append(self.saveListsize) + + def saveListsize(self): + listsize = self["list"].instance.size() + self.listWidth = listsize.width() + self.listHeight = listsize.height() def checkWarnings(self): if len(plugins.warnings): @@ -64,7 +70,7 @@ class PluginBrowser(Screen): def updateList(self): self.pluginlist = plugins.getPlugins(PluginDescriptor.WHERE_PLUGINMENU) - self.list = [PluginEntryComponent(plugin) for plugin in self.pluginlist] + self.list = [PluginEntryComponent(plugin, self.listWidth) for plugin in self.pluginlist] self["list"].l.setList(self.list) if fileExists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/plugin.py")): self["red"].setText(_("Manage extensions")) @@ -172,7 +178,10 @@ class PluginDownloadBrowser(Screen): self.container.execute("opkg list enigma2-plugin-*") def startRun(self): + listsize = self["list"].instance.size() self["list"].instance.hide() + self.listWidth = listsize.width() + self.listHeight = listsize.height() if self.type == self.DOWNLOAD: if not PluginDownloadBrowser.lastDownloadDate or (time() - PluginDownloadBrowser.lastDownloadDate) > 3600: # Only update from internet once per hour @@ -256,10 +265,10 @@ class PluginDownloadBrowser(Screen): for x in self.plugins.keys(): if x in self.expanded: - list.append(PluginCategoryComponent(x, expandedIcon)) - list.extend([PluginDownloadComponent(plugin[0], plugin[1]) for plugin in self.plugins[x]]) + list.append(PluginCategoryComponent(x, expandedIcon, self.listWidth)) + list.extend([PluginDownloadComponent(plugin[0], plugin[1], self.listWidth) for plugin in self.plugins[x]]) else: - list.append(PluginCategoryComponent(x, expandableIcon)) + list.append(PluginCategoryComponent(x, expandableIcon, self.listWidth)) self.list = list self["list"].l.setList(list) diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py index 58f5494..564541b 100644 --- a/lib/python/Screens/Satconfig.py +++ b/lib/python/Screens/Satconfig.py @@ -1,4 +1,4 @@ -from enigma import eDVBDB +from enigma import eDVBDB, getLinkedSlotID, isFBCLink from Screen import Screen from Components.SystemInfo import SystemInfo from Components.ActionMap import ActionMap @@ -18,21 +18,6 @@ from datetime import datetime from Components.PluginComponent import plugins from Plugins.Plugin import PluginDescriptor -def isFBCTuner(nim): - if nim.description.find("FBC") == -1: - return False - return True - -def isFBCRoot(nim): - if nim.slot %8 < 2: - return True - return False - -def isFBCLink(nim): - if isFBCTuner(nim) and not isFBCRoot(nim): - return True - return False - class NimSetup(Screen, ConfigListScreen, ServiceStopScreen): def createSimpleSetup(self, list, mode): nim = self.nimConfig @@ -88,7 +73,7 @@ class NimSetup(Screen, ConfigListScreen, ServiceStopScreen): choices["satposdepends"] = _("second cable of motorized LNB") if len(nimmanager.canConnectTo(self.slotid)) > 0: choices["loopthrough"] = _("loopthrough to") - if isFBCLink(self.nim): + if isFBCLink(self.nim.slot): choices = { "nothing": _("not configured"), "advanced": _("advanced")} self.nimConfig.configMode.setChoices(choices, default = "nothing") @@ -268,7 +253,7 @@ class NimSetup(Screen, ConfigListScreen, ServiceStopScreen): self.list.append(self.advancedLnbsEntry) if currLnb: - if isFBCLink(self.nim): + if isFBCLink(self.nim.slot): if currLnb.lof.value != "unicable": currLnb.lof.value = "unicable" @@ -336,7 +321,7 @@ class NimSetup(Screen, ConfigListScreen, ServiceStopScreen): for id in connectable: choices.append((str(id), nimmanager.getNimDescription(id))) if len(choices): - if isFBCLink(self.nim): + if isFBCLink(self.nim.slot): if self.nimConfig.advanced.unicableconnected.value != True: self.nimConfig.advanced.unicableconnected.value = True @@ -512,7 +497,7 @@ class NimSetup(Screen, ConfigListScreen, ServiceStopScreen): self.createSetup() def keyLeft(self): - if isFBCLink(self.nim): + if isFBCLink(self.nim.slot): checkList = (self.advancedLof, self.advancedConnected) curEntry = self["config"].getCurrent() if curEntry in checkList: @@ -522,7 +507,7 @@ class NimSetup(Screen, ConfigListScreen, ServiceStopScreen): self.newConfig() def keyRight(self): - if isFBCLink(self.nim): + if isFBCLink(self.nim.slot): checkList = (self.advancedLof, self.advancedConnected) curEntry = self["config"].getCurrent() if curEntry in checkList: @@ -587,8 +572,7 @@ class NimSelection(Screen): configMode = nimConfig.configMode.value if self.showNim(x): if x.isCompatible("DVB-S"): - if isFBCLink(x) and configMode != "advanced": - from enigma import getLinkedSlotID + if isFBCLink(x.slot) and configMode != "advanced": link = getLinkedSlotID(x.slot) if link == -1: @@ -605,7 +589,7 @@ class NimSelection(Screen): nim = nim and nim[3] nimConfig = nimmanager.getNimConfig(nim.slot) - if isFBCLink(nim) and nimConfig.configMode.value == "loopthrough": + if isFBCLink(nim.slot) and nimConfig.configMode.value == "loopthrough": return if nim is not None and not nim.empty and nim.isSupported(): @@ -664,7 +648,7 @@ class NimSelection(Screen): text = _("simple") elif nimConfig.configMode.value == "advanced": text = _("advanced") - if isFBCLink(x) and nimConfig.configMode.value != "advanced": + if isFBCLink(x.slot) and nimConfig.configMode.value != "advanced": text += _("\n") elif x.isCompatible("DVB-T") or x.isCompatible("DVB-C"): if nimConfig.configMode.value == "nothing": diff --git a/lib/python/Screens/ScanSetup.py b/lib/python/Screens/ScanSetup.py index 6fdeb53..079bdef 100644 --- a/lib/python/Screens/ScanSetup.py +++ b/lib/python/Screens/ScanSetup.py @@ -101,13 +101,16 @@ cable_bands = { cable_autoscan_nimtype = { 'SSH108' : 'ssh108', 'TT3L10' : 'tt3l10', -'TURBO' : 'vuplus_turbo_c' +'TURBO' : 'vuplus_turbo_c', +'TT2L08' : 'tt2l08', +'BCM3148' : 'bcm3148' } terrestrial_autoscan_nimtype = { 'SSH108' : 'ssh108_t2_scan', 'TT3L10' : 'tt3l10_t2_scan', -'TURBO' : 'vuplus_turbo_t' +'TURBO' : 'vuplus_turbo_t', +'TT2L08' : 'tt2l08_t2_scan' } def GetDeviceId(filter, nim_idx): diff --git a/lib/python/Screens/ServiceInfo.py b/lib/python/Screens/ServiceInfo.py index da534ec..ffd288f 100644 --- a/lib/python/Screens/ServiceInfo.py +++ b/lib/python/Screens/ServiceInfo.py @@ -6,6 +6,7 @@ from Components.Label import Label from ServiceReference import ServiceReference from enigma import eListboxPythonMultiContent, eListbox, gFont, iServiceInformation, eServiceCenter from Tools.Transponder import ConvertToHumanReadable +import skin RT_HALIGN_LEFT = 0 @@ -30,11 +31,14 @@ def ServiceInfoListEntry(a, b, valueType=TYPE_TEXT, param=4): else: b = str(b) + x, y, w, h = skin.parameters.get("ServiceInfo",(0, 0, 200, 30)) + xa, ya, wa, ha = skin.parameters.get("ServiceInfoLeft",(0, 0, 200, 25)) + xb, yb, wb, hb = skin.parameters.get("ServiceInfoRight",(220, 0, 350, 25)) return [ #PyObject *type, *px, *py, *pwidth, *pheight, *pfnt, *pstring, *pflags; - (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 200, 30, 0, RT_HALIGN_LEFT, ""), - (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 200, 25, 0, RT_HALIGN_LEFT, a), - (eListboxPythonMultiContent.TYPE_TEXT, 220, 0, 350, 25, 0, RT_HALIGN_LEFT, b) + (eListboxPythonMultiContent.TYPE_TEXT, x, y, w, h, 0, RT_HALIGN_LEFT, ""), + (eListboxPythonMultiContent.TYPE_TEXT, xa, ya, wa, ha, 0, RT_HALIGN_LEFT, a), + (eListboxPythonMultiContent.TYPE_TEXT, xb, yb, wb, hb, 0, RT_HALIGN_LEFT, b) ] class ServiceInfoList(HTMLComponent, GUIComponent): @@ -43,8 +47,9 @@ class ServiceInfoList(HTMLComponent, GUIComponent): self.l = eListboxPythonMultiContent() self.list = source self.l.setList(self.list) - self.l.setFont(0, gFont("Regular", 23)) - self.l.setItemHeight(25) + font = skin.fonts.get("ServiceInfo", ("Regular", 23, 25)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) GUI_WIDGET = eListbox diff --git a/lib/python/Screens/VirtualKeyBoard.py b/lib/python/Screens/VirtualKeyBoard.py index 174ffdd..36d8e7c 100755 --- a/lib/python/Screens/VirtualKeyBoard.py +++ b/lib/python/Screens/VirtualKeyBoard.py @@ -10,12 +10,14 @@ from Components.MenuList import MenuList from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN from Tools.LoadPixmap import LoadPixmap +import skin class VirtualKeyBoardList(MenuList): def __init__(self, list, enableWrapAround=False): MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent) - self.l.setFont(0, gFont("Regular", 28)) - self.l.setItemHeight(45) + font = skin.fonts.get("VirtualKeyboard", ("Regular", 28, 45)) + self.l.setFont(0, gFont(font[0], font[1])) + self.l.setItemHeight(font[2]) def VirtualKeyBoardEntryComponent(keys, selectedKey,shiftMode=False): key_backspace = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/vkey_backspace.png")) diff --git a/lib/python/Tools/HardwareInfo.py b/lib/python/Tools/HardwareInfo.py index e72d291..da7b9db 100644 --- a/lib/python/Tools/HardwareInfo.py +++ b/lib/python/Tools/HardwareInfo.py @@ -1,5 +1,8 @@ +import os + class HardwareInfo: device_name = None + vu_device_name = None def __init__(self): if HardwareInfo.device_name is not None: @@ -30,5 +33,13 @@ class HardwareInfo: except: pass + HardwareInfo.vu_device_name = "unknown" + vumodel_path = "/proc/stb/info/vumodel" + if os.access(vumodel_path, os.F_OK): + HardwareInfo.vu_device_name = open(vumodel_path, "r").read().strip() + def get_device_name(self): return HardwareInfo.device_name + + def get_vu_device_name(self): + return HardwareInfo.vu_device_name diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 158c986..e9a8161 100755 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -356,6 +356,16 @@ void setFCCEnable(int enable) } %} +bool isFBCLink(int); +%{ +bool isFBCLink(int fe) +{ + eFBCTunerManager *mgr = eFBCTunerManager::getInstance(); + if (mgr) return mgr->isFBCLink(fe); + return false; +} +%} + /************** temp *****************/ /* need a better place for this, i agree. */ diff --git a/lib/service/Makefile.am b/lib/service/Makefile.am index 2df1dd9..07d69d0 100644 --- a/lib/service/Makefile.am +++ b/lib/service/Makefile.am @@ -18,7 +18,8 @@ libenigma_service_a_SOURCES = \ servicedvbfcc.cpp \ servicefs.cpp \ servicemp3.cpp \ - servicem2ts.cpp + servicem2ts.cpp \ + servicehdmi.cpp serviceincludedir = $(pkgincludedir)/lib/service serviceinclude_HEADERS = \ @@ -31,7 +32,8 @@ serviceinclude_HEADERS = \ servicedvbfcc.h \ servicefs.h \ servicemp3.h \ - servicem2ts.h + servicem2ts.h \ + servicehdmi.h if HAVE_LIBXINE libenigma_service_a_SOURCES += \ diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 086f595..acc998a 100755 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -945,6 +945,7 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0) { m_is_primary = 1; + m_decoder_index = 0; m_is_stream = m_reference.path.substr(0, 7) == "http://"; m_is_pvr = (!m_reference.path.empty() && !m_is_stream); @@ -1268,6 +1269,7 @@ RESULT eDVBServicePlay::stop() RESULT eDVBServicePlay::setTarget(int target) { m_is_primary = !target; + m_decoder_index = target; return 0; } @@ -2577,7 +2579,7 @@ void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged) h.getDecodeDemux(m_decode_demux); if (m_decode_demux) { - m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary); + m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index); if (m_decoder) m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection); if (m_is_primary) diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index 7ded16a..eafc96d 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -192,6 +192,7 @@ protected: ePtr m_dvb_service; ePtr m_decoder; + int m_decoder_index; int m_is_primary; int m_have_video_pid; int m_tune_state; diff --git a/lib/service/servicedvbfcc.cpp b/lib/service/servicedvbfcc.cpp index 972e73e..7cabb03 100644 --- a/lib/service/servicedvbfcc.cpp +++ b/lib/service/servicedvbfcc.cpp @@ -236,7 +236,7 @@ void eDVBServiceFCCPlay::updateFCCDecoder(bool sendSeekableStateChanged) h.getDecodeDemux(m_decode_demux); if (m_decode_demux) { - m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary); + m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index); if (m_decoder) m_decoder->connectVideoEvent(slot(*this, &eDVBServiceFCCPlay::video_event), m_video_event_connection); } diff --git a/lib/service/servicehdmi.cpp b/lib/service/servicehdmi.cpp new file mode 100644 index 0000000..2767982 --- /dev/null +++ b/lib/service/servicehdmi.cpp @@ -0,0 +1,352 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define HDMI_IN_REC_ENCODER_INDEX 0 +#define HDMI_IN_REC_DECODER_INDEX 2 + +eServiceFactoryHDMI::eServiceFactoryHDMI() +{ + ePtr sc; + + eServiceCenter::getPrivInstance(sc); + if (sc) + { + std::list extensions; + sc->addServiceFactory(eServiceFactoryHDMI::id, this, extensions); + } + + m_service_info = new eStaticServiceHDMIInfo(); +} + +eServiceFactoryHDMI::~eServiceFactoryHDMI() +{ + ePtr sc; + + eServiceCenter::getPrivInstance(sc); + if (sc) + { + sc->removeServiceFactory(eServiceFactoryHDMI::id); + } +} + +DEFINE_REF(eServiceFactoryHDMI) + +RESULT eServiceFactoryHDMI::play(const eServiceReference &ref, ePtr &ptr) +{ + ptr = new eServiceHDMI(ref); + return 0; +} + +RESULT eServiceFactoryHDMI::record(const eServiceReference &ref, ePtr &ptr) +{ + ePtr nav_instance; + getNavInstance(nav_instance); + ptr = new eServiceHDMIRecord(ref, nav_instance); + return 0; +} + +RESULT eServiceFactoryHDMI::list(const eServiceReference &, ePtr &ptr) +{ + ptr = 0; + return -1; +} + +RESULT eServiceFactoryHDMI::info(const eServiceReference &ref, ePtr &ptr) +{ + ptr = m_service_info; + return 0; +} + +RESULT eServiceFactoryHDMI::offlineOperations(const eServiceReference &, ePtr &ptr) +{ + ptr = 0; + return -1; +} + +void eServiceFactoryHDMI::getNavInstance(ePtr &nav_instance) +{ + if (!m_nav_instance) + { + ePtr service_center; + eServiceCenter::getInstance(service_center); + m_nav_instance = new eNavigation(service_center, HDMI_IN_REC_DECODER_INDEX); + } + nav_instance = m_nav_instance; +} + +DEFINE_REF(eStaticServiceHDMIInfo) + +eStaticServiceHDMIInfo::eStaticServiceHDMIInfo() +{ +} + +RESULT eStaticServiceHDMIInfo::getName(const eServiceReference &ref, std::string &name) +{ + if (ref.name.length()) + { + name = ref.name; + } + else + { + name = "HDMI IN"; + } + return 0; +} + +int eStaticServiceHDMIInfo::getLength(const eServiceReference &ref) +{ + return -1; +} + +int eStaticServiceHDMIInfo::getInfo(const eServiceReference &ref, int w) +{ + return iServiceInformation::resNA; +} + +long long eStaticServiceHDMIInfo::getFileSize(const eServiceReference &ref) +{ + return 0; +} + +eServiceHDMI::eServiceHDMI(eServiceReference ref) + : m_ref(ref), m_decoder_index(0) +{ + +} + +eServiceHDMI::~eServiceHDMI() +{ +} + +DEFINE_REF(eServiceHDMI); + +RESULT eServiceHDMI::connectEvent(const Slot2 &event, ePtr &connection) +{ + connection = new eConnection((iPlayableService*)this, m_event.connect(event)); + return 0; +} + +RESULT eServiceHDMI::start() +{ + m_decoder = new eTSMPEGDecoder(NULL, m_decoder_index); + m_decoder->setVideoPID(1, 0); + m_decoder->setAudioPID(1, 0); + m_decoder->play(); + m_event(this, evStart); + return 0; +} + +RESULT eServiceHDMI::stop() +{ + m_decoder = NULL; + m_event(this, evStopped); + return 0; +} + +RESULT eServiceHDMI::setTarget(int target) +{ + m_decoder_index = target; + return 0; +} + +RESULT eServiceHDMI::info(ePtr &i) +{ + i = this; + return 0; +} + +RESULT eServiceHDMI::getName(std::string &name) +{ + if (m_ref.name.length()) + { + name = m_ref.name; + } + else + { + name = "HDMI IN"; + } + return 0; +} + +int eServiceHDMI::getInfo(int w) +{ + return resNA; +} + +std::string eServiceHDMI::getInfoString(int w) +{ + return ""; +} + +PyObject* eServiceHDMI::getInfoObject(int w) +{ + Py_RETURN_NONE; +} + +DEFINE_REF(eServiceHDMIRecord); + +eServiceHDMIRecord::eServiceHDMIRecord(const eServiceReference &ref, ePtr &nav_instance) +{ + m_ref = ref; + m_state = stateIdle; + m_target_fd = -1; + m_error = 0; + m_encoder_fd = -1; + m_thread = NULL; + m_nav_instance = nav_instance; +} + +RESULT eServiceHDMIRecord::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags) +{ + m_filename = filename; + + if (m_state == stateIdle) + { + return doPrepare(); + } + return -1; +} + +RESULT eServiceHDMIRecord::prepareStreaming() +{ + return -1; +} + +RESULT eServiceHDMIRecord::start(bool simulate) +{ + m_simulate = simulate; + m_event((iRecordableService*)this, evStart); + return doRecord(); +} + +RESULT eServiceHDMIRecord::stop() +{ + if (!m_simulate) + eDebug("[eServiceHDMIRecord] stop recording!"); + if (m_state == stateRecording) + { + if (m_thread) + { + m_thread->stop(); + m_thread->stopSaveMetaInformation(); + } + if (m_target_fd >= 0) + { + ::close(m_target_fd); + m_target_fd = -1; + } + + m_state = statePrepared; + } else if (!m_simulate) + eDebug("[eServiceHDMIRecord] (was not recording)"); + if (m_state == statePrepared) + { + delete m_thread; + m_thread = NULL; + m_nav_instance->stopService(); + if (m_encoder_fd >= 0) + { + ::close(m_encoder_fd); + m_encoder_fd = -1; + } + m_state = stateIdle; + } + m_event((iRecordableService*)this, evRecordStopped); + return 0; +} + +int eServiceHDMIRecord::doPrepare() +{ + if (!m_simulate && m_encoder_fd < 0) + { + if (m_nav_instance->playService(m_ref) >= 0) + { + char filename[128]; + snprintf(filename, sizeof(filename), "/dev/encoder%d", HDMI_IN_REC_ENCODER_INDEX); + m_encoder_fd = open(filename, O_RDONLY); + } + if (m_encoder_fd < 0) + return -1; + } + m_state = statePrepared; + return 0; +} + +int eServiceHDMIRecord::doRecord() +{ + int err = doPrepare(); + if (err) + { + m_error = errTuneFailed; + m_event((iRecordableService*)this, evRecordFailed); + return err; + } + + if (!m_thread && !m_simulate) + { + eDebug("[eServiceHDMIRecord] Recording to %s...", m_filename.c_str()); + ::remove(m_filename.c_str()); + int fd = ::open(m_filename.c_str(), O_WRONLY | O_CREAT | O_LARGEFILE | O_CLOEXEC, 0666); + if (fd < 0) + { + eDebug("[eServiceHDMIRecord] can't open recording file: %m"); + m_error = errOpenRecordFile; + m_event((iRecordableService*)this, evRecordFailed); + return errOpenRecordFile; + } + + m_thread = new eDVBRecordFileThread(); + m_target_fd = fd; + } + + eDebug("[eServiceHDMIRecord] start recording..."); + + if (m_state != stateRecording) + { + if (m_thread && m_encoder_fd >= 0) + { + m_thread->startSaveMetaInformation(m_filename); + m_thread->start(m_encoder_fd, m_target_fd); + } + m_state = stateRecording; + } + + m_error = 0; + m_event((iRecordableService*)this, evRecordRunning); + return 0; +} + +RESULT eServiceHDMIRecord::stream(ePtr &ptr) +{ + ptr = NULL; + return -1; +} + +RESULT eServiceHDMIRecord::subServices(ePtr &ptr) +{ + ptr = NULL; + return -1; +} + +RESULT eServiceHDMIRecord::frontendInfo(ePtr &ptr) +{ + ptr = this; + return 0; +} + +RESULT eServiceHDMIRecord::connectEvent(const Slot2 &event, ePtr &connection) +{ + connection = new eConnection((iRecordableService*)this, m_event.connect(event)); + return 0; +} + +eAutoInitPtr init_eServiceFactoryHDMI(eAutoInitNumbers::service + 1, "eServiceFactoryHDMI"); diff --git a/lib/service/servicehdmi.h b/lib/service/servicehdmi.h new file mode 100644 index 0000000..6db9c43 --- /dev/null +++ b/lib/service/servicehdmi.h @@ -0,0 +1,127 @@ +#ifndef __servicehdmi_h +#define __servicehdmi_h + +#include +#include +#include +#include + +class eStaticServiceHDMIInfo; + +class eServiceFactoryHDMI: public iServiceHandler +{ + DECLARE_REF(eServiceFactoryHDMI); +public: + eServiceFactoryHDMI(); + virtual ~eServiceFactoryHDMI(); + enum { id = 0x2000 }; + + RESULT play(const eServiceReference &, ePtr &ptr); + RESULT record(const eServiceReference &, ePtr &ptr); + RESULT list(const eServiceReference &, ePtr &ptr); + RESULT info(const eServiceReference &, ePtr &ptr); + RESULT offlineOperations(const eServiceReference &, ePtr &ptr); + void getNavInstance(ePtr &nav_instance); +private: + ePtr m_service_info; + ePtr m_nav_instance; +}; + +class eStaticServiceHDMIInfo: public iStaticServiceInformation +{ + DECLARE_REF(eStaticServiceHDMIInfo); + friend class eServiceFactoryHDMI; + eStaticServiceHDMIInfo(); +public: + RESULT getName(const eServiceReference &ref, std::string &name); + int getLength(const eServiceReference &ref); + int getInfo(const eServiceReference &ref, int w); + int isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { return 1; } + long long getFileSize(const eServiceReference &ref); +}; + +class eServiceHDMI: public iPlayableService, public iServiceInformation, public Object +{ + DECLARE_REF(eServiceHDMI); +public: + virtual ~eServiceHDMI(); + + RESULT connectEvent(const Slot2 &event, ePtr &connection); + RESULT start(); + RESULT stop(); + RESULT setTarget(int target); + + RESULT pause(ePtr &ptr) { ptr = 0; return -1; } + RESULT seek(ePtr &ptr) { ptr = 0; return -1; } + RESULT audioTracks(ePtr &ptr) { ptr = 0; return -1; } + RESULT audioChannel(ePtr &ptr) { ptr = 0; return -1; } + RESULT subtitle(ePtr &ptr) { ptr = 0; return -1; } + RESULT audioDelay(ePtr &ptr) { ptr = 0; return -1; } + + RESULT frontendInfo(ePtr &ptr) { ptr = 0; return -1; } + RESULT subServices(ePtr &ptr) { ptr = 0; return -1; } + RESULT timeshift(ePtr &ptr) { ptr = 0; return -1; } + RESULT cueSheet(ePtr &ptr) { ptr = 0; return -1; } + + RESULT rdsDecoder(ePtr &ptr) { ptr = 0; return -1; } + RESULT keys(ePtr &ptr) { ptr = 0; return -1; } + RESULT stream(ePtr &ptr) { ptr = 0; return -1; } + RESULT streamed(ePtr &ptr) { ptr = 0; return -1; } + + RESULT info(ePtr&); + + RESULT getName(std::string &name); + int getInfo(int w); + std::string getInfoString(int w); + PyObject *getInfoObject(int w); + +private: + friend class eServiceFactoryHDMI; + eServiceHDMI(eServiceReference ref); + Signal2 m_event; + eServiceReference m_ref; + int m_decoder_index; + ePtr m_decoder; +}; + +class eServiceHDMIRecord: public eDVBServiceBase, public iRecordableService, public Object +{ + DECLARE_REF(eServiceHDMIRecord); +public: + eServiceHDMIRecord(const eServiceReference &ref, ePtr &nav_instance); + RESULT connectEvent(const Slot2 &event, ePtr &connection); + RESULT prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags); + RESULT prepareStreaming(); + RESULT start(bool simulate=false); + RESULT stop(); + RESULT getError(int &error) { error = m_error; return 0; } + RESULT frontendInfo(ePtr &ptr); + RESULT stream(ePtr &ptr); + RESULT subServices(ePtr &ptr); + +private: + enum { stateIdle, statePrepared, stateRecording }; + bool m_simulate; + int m_state; + eDVBRecordFileThread *m_thread; + eServiceReference m_ref; + + int m_recording, m_error; + std::string m_filename; + + int m_target_fd; + int m_encoder_fd; + int m_decoder; + ePtr m_nav_instance; + + int doPrepare(); + int doRecord(); + + /* events */ + Signal2 m_event; + + /* recorder events */ + void recordEvent(int event); +}; + +#endif diff --git a/skin.py b/skin.py index a0190f1..f763dd0 100755 --- a/skin.py +++ b/skin.py @@ -15,6 +15,13 @@ from Tools.LoadPixmap import LoadPixmap colorNames = dict() +fonts = { + "Body": ("Regular", 18, 22, 16), + "ChoiceList": ("Regular", 20, 24, 18), +} + +parameters = {} + def dump(x, i=0): print " " * i + str(x) try: @@ -70,6 +77,31 @@ profile("LoadSkinDefault") loadSkin('skin_default.xml') profile("LoadSkinDefaultDone") +def parseCoordinate(str, e, size = 0): + str = str.strip() + if str == "center": + val = (e - size)/2 + else: + sl = len(str) + l = 1 + + if str[0] is 'e': + val = e + elif str[0] is 'c': + val = e/2 + else: + val = 0; + l = 0 + + if sl - l > 0: + if str[sl-1] is '%': + val += e * int(str[l:sl-1]) / 100 + else: + val += int(str[l:sl]) + if val < 0: + val = 0 + return val + def evalPos(pos, wsize, ssize, scale): if pos == "center": pos = (ssize - wsize) / 2 @@ -96,8 +128,13 @@ def parseSize(str, scale): x, y = str.split(',') return eSize(int(x) * scale[0][0] / scale[0][1], int(y) * scale[1][0] / scale[1][1]) -def parseFont(str, scale): - name, size = str.split(';') +def parseFont(s, scale): + try: + f = fonts[s] + name = f[0] + size = f[1] + except: + name, size = s.split(';') return gFont(name, int(size) * scale[0][0] / scale[0][1]) def parseColor(str): @@ -108,18 +145,34 @@ def parseColor(str): raise SkinError("color '%s' must be #aarrggbb or valid named color" % (str)) return gRGB(int(str[1:], 0x10)) -def collectAttributes(skinAttributes, node, skin_path_prefix=None, ignore=[]): +def collectAttributes(skinAttributes, node, context, skin_path_prefix=None, ignore=[]): # walk all attributes - for a in node.items(): - #print a - attrib = a[0] - value = a[1] - - if attrib in ("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap"): - value = resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix) - + size = None + pos = None + for attrib, value in node.items(): if attrib not in ignore: - skinAttributes.append((attrib, value.encode("utf-8"))) + if attrib in ("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap"): + value = resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix) + + # Bit of a hack this, really. When a window has a flag (e.g. wfNoBorder) + # it needs to be set at least before the size is set, in order for the + # window dimensions to be calculated correctly in all situations. + # If wfNoBorder is applied after the size has been set, the window will fail to clear the title area. + # Similar situation for a scrollbar in a listbox; when the scrollbar setting is applied after + # the size, a scrollbar will not be shown until the selection moves for the first time + + if attrib == 'size': + size = value.encode("utf-8") + elif attrib == 'position': + pos = value.encode("utf-8") + else: + skinAttributes.append((attrib, value.encode("utf-8"))) + + if pos is not None: + pos, size = context.parse(pos, size) + skinAttributes.append(('position', pos)) + if size is not None: + skinAttributes.append(('size', size)) def loadPixmap(path, desktop): cached = False @@ -133,136 +186,164 @@ def loadPixmap(path, desktop): raise SkinError("pixmap file %s not found!" % (path)) return ptr -def applySingleAttribute(guiObject, desktop, attrib, value, scale = ((1,1),(1,1))): - # and set attributes - try: - if attrib == 'position': - guiObject.move(parsePosition(value, scale, desktop, guiObject.csize())) - elif attrib == 'size': - guiObject.resize(parseSize(value, scale)) - elif attrib == 'animationPaused': - pass - elif attrib == 'animationMode': - guiObject.setAnimationMode( - { "disable": 0x00, - "off": 0x00, - "offshow": 0x10, - "offhide": 0x01, - "onshow": 0x01, - "onhide": 0x10, +class AttributeParser: + def __init__(self, guiObject, desktop, scale = ((1,1),(1,1))): + self.guiObject = guiObject + self.desktop = desktop + self.scale = scale + def applyOne(self, attrib, value): + try: + getattr(self, attrib)(value) + except AttributeError: + print "[Skin] Attribute not implemented:", attrib, "value:", value + except SkinError, ex: + print "[Skin] Error:", ex + def applyAll(self, attrs): + for attrib, value in attrs: + try: + getattr(self, attrib)(value) + except AttributeError: + print "[Skin] Attribute not implemented:", attrib, "value:", value + except SkinError, ex: + print "[Skin] Error:", ex + def position(self, value): + if isinstance(value, tuple): + self.guiObject.move(ePoint(*value)) + else: + self.guiObject.move(parsePosition(value, self.scale, self.desktop, self.guiObject.csize())) + def size(self, value): + if isinstance(value, tuple): + self.guiObject.resize(eSize(*value)) + else: + self.guiObject.resize(parseSize(value, self.scale)) + def animationPaused(self, value): + pass + def animationPaused(self, value): + self.guiObject.setAnimationMode( + { "disable": 0x00, + "off": 0x00, + "offshow": 0x10, + "offhide": 0x01, + "onshow": 0x01, + "onhide": 0x10, + }[value]) + def title(self, value): + self.guiObject.setTitle(_(value)) + def text(self, value): + self.guiObject.setText(_(value)) + def font(self, value): + self.guiObject.setFont(parseFont(value, self.scale)) + def zPosition(self, value): + self.guiObject.setZPosition(int(value)) + def itemHeight(self, value): + self.guiObject.setItemHeight(int(value)) + def pixmap(self, value): + ptr = loadPixmap(value, self.desktop) + self.guiObject.setPixmap(ptr) + def backgroundPixmap(self, value): + ptr = loadPixmap(value, self.desktop) + self.guiObject.setBackgroundPicture(ptr) + def selectionPixmap(self, value): + ptr = loadPixmap(value, self.desktop) + self.guiObject.setSelectionPicture(ptr) + def itemHeight(self, value): + self.guiObject.setItemHeight(int(value)) + def alphatest(self, value): + self.guiObject.setAlphatest( + { "on": 1, + "off": 0, + "blend": 2, + }[value]) + def scale(self, value): + self.guiObject.setScale(1) + def orientation(self, value): + try: + self.guiObject.setOrientation(* + { "orVertical": (self.guiObject.orVertical, False), + "orTopToBottom": (self.guiObject.orVertical, False), + "orBottomToTop": (self.guiObject.orVertical, True), + "orHorizontal": (self.guiObject.orHorizontal, False), + "orLeftToRight": (self.guiObject.orHorizontal, False), + "orRightToLeft": (self.guiObject.orHorizontal, True), }[value]) - elif attrib == 'title': - guiObject.setTitle(_(value)) - elif attrib == 'text': - guiObject.setText(_(value)) - elif attrib == 'font': - guiObject.setFont(parseFont(value, scale)) - elif attrib == 'zPosition': - guiObject.setZPosition(int(value)) - elif attrib == 'itemHeight': - guiObject.setItemHeight(int(value)) - elif attrib in ("pixmap", "backgroundPixmap", "selectionPixmap"): - ptr = loadPixmap(value, desktop) # this should already have been filename-resolved. - if attrib == "pixmap": - guiObject.setPixmap(ptr) - elif attrib == "backgroundPixmap": - guiObject.setBackgroundPicture(ptr) - elif attrib == "selectionPixmap": - guiObject.setSelectionPicture(ptr) - # guiObject.setPixmapFromFile(value) - elif attrib == "alphatest": # used by ePixmap - guiObject.setAlphatest( - { "on": 1, - "off": 0, - "blend": 2, + except KeyError: + print "oprientation must be either orVertical or orHorizontal!" + def valign(self, value): + try: + self.guiObject.setVAlign( + { "top": self.guiObject.alignTop, + "center": self.guiObject.alignCenter, + "bottom": self.guiObject.alignBottom }[value]) - elif attrib == "scale": - guiObject.setScale(1) - elif attrib == "orientation": # used by eSlider - try: - guiObject.setOrientation(* - { "orVertical": (guiObject.orVertical, False), - "orTopToBottom": (guiObject.orVertical, False), - "orBottomToTop": (guiObject.orVertical, True), - "orHorizontal": (guiObject.orHorizontal, False), - "orLeftToRight": (guiObject.orHorizontal, False), - "orRightToLeft": (guiObject.orHorizontal, True), - }[value]) - except KeyError: - print "oprientation must be either orVertical or orHorizontal!" - elif attrib == "valign": - try: - guiObject.setVAlign( - { "top": guiObject.alignTop, - "center": guiObject.alignCenter, - "bottom": guiObject.alignBottom - }[value]) - except KeyError: - print "valign must be either top, center or bottom!" - elif attrib == "halign": + except KeyError: + print "valign must be either top, center or bottom!" + def halign(self, value): + try: + self.guiObject.setHAlign( + { "left": self.guiObject.alignLeft, + "center": self.guiObject.alignCenter, + "right": self.guiObject.alignRight, + "block": self.guiObject.alignBlock + }[value]) + except KeyError: + print "halign must be either left, center, right or block!" + def flags(self, value): + flags = value.split(',') + for f in flags: try: - guiObject.setHAlign( - { "left": guiObject.alignLeft, - "center": guiObject.alignCenter, - "right": guiObject.alignRight, - "block": guiObject.alignBlock - }[value]) + fv = eWindow.__dict__[f] + self.guiObject.setFlag(fv) except KeyError: - print "halign must be either left, center, right or block!" - elif attrib == "flags": - flags = value.split(',') - for f in flags: - try: - fv = eWindow.__dict__[f] - guiObject.setFlag(fv) - except KeyError: - print "illegal flag %s!" % f - elif attrib == "backgroundColor": - guiObject.setBackgroundColor(parseColor(value)) - elif attrib == "backgroundColorSelected": - guiObject.setBackgroundColorSelected(parseColor(value)) - elif attrib == "foregroundColor": - guiObject.setForegroundColor(parseColor(value)) - elif attrib == "foregroundColorSelected": - guiObject.setForegroundColorSelected(parseColor(value)) - elif attrib == "shadowColor": - guiObject.setShadowColor(parseColor(value)) - elif attrib == "selectionDisabled": - guiObject.setSelectionEnable(0) - elif attrib == "transparent": - guiObject.setTransparent(int(value)) - elif attrib == "borderColor": - guiObject.setBorderColor(parseColor(value)) - elif attrib == "borderWidth": - guiObject.setBorderWidth(int(value)) - elif attrib == "scrollbarMode": - guiObject.setScrollbarMode( - { "showOnDemand": guiObject.showOnDemand, - "showAlways": guiObject.showAlways, - "showNever": guiObject.showNever - }[value]) - elif attrib == "enableWrapAround": - guiObject.setWrapAround(True) - elif attrib == "pointer" or attrib == "seek_pointer": - (name, pos) = value.split(':') - pos = parsePosition(pos, scale) - ptr = loadPixmap(name, desktop) - guiObject.setPointer({"pointer": 0, "seek_pointer": 1}[attrib], ptr, pos) - elif attrib == 'shadowOffset': - guiObject.setShadowOffset(parsePosition(value, scale)) - elif attrib == 'noWrap': - guiObject.setNoWrap(1) - elif attrib == 'id': - pass - else: - raise SkinError("unsupported attribute " + attrib + "=" + value) - except int: -# AttributeError: - print "widget %s (%s) doesn't support attribute %s!" % ("", guiObject.__class__.__name__, attrib) + print "illegal flag %s!" % f + def backgroundColor(self, value): + self.guiObject.setBackgroundColor(parseColor(value)) + def backgroundColorSelected(self, value): + self.guiObject.setBackgroundColorSelected(parseColor(value)) + def foregroundColor(self, value): + self.guiObject.setForegroundColor(parseColor(value)) + def foregroundColorSelected(self, value): + self.guiObject.setForegroundColorSelected(parseColor(value)) + def shadowColor(self, value): + self.guiObject.setShadowColor(parseColor(value)) + def selectionDisabled(self, value): + self.guiObject.setSelectionEnable(0) + def transparent(self, value): + self.guiObject.setTransparent(int(value)) + def borderColor(self, value): + self.guiObject.setBorderColor(parseColor(value)) + def borderWidth(self, value): + self.guiObject.setBorderWidth(int(value)) + def scrollbarMode(self, value): + self.guiObject.setScrollbarMode( + { "showOnDemand": self.guiObject.showOnDemand, + "showAlways": self.guiObject.showAlways, + "showNever": self.guiObject.showNever + }[value]) + def enableWrapAround(self, value): + self.guiObject.setWrapAround(True) + def pointer(self, value): + (name, pos) = value.split(':') + pos = parsePosition(pos, self.scale) + ptr = loadPixmap(name, self.desktop) + self.guiObject.setPointer(0, ptr, pos) + def seek_pointer(self, value): + (name, pos) = value.split(':') + pos = parsePosition(pos, self.scale) + ptr = loadPixmap(name, self.desktop) + self.guiObject.setPointer(1, ptr, pos) + def shadowOffset(self, value): + self.guiObject.setShadowOffset(parsePosition(value, self.scale)) + def noWrap(self, value): + self.guiObject.setNoWrap(1) + def id(self, value): + pass + +def applySingleAttribute(guiObject, desktop, attrib, value, scale = ((1,1),(1,1))): + # Someone still using applySingleAttribute? + AttributeParser(guiObject, desktop, scale).applyOne(attrib, value) def applyAllAttributes(guiObject, desktop, attributes, scale): - for (attrib, value) in attributes: - applySingleAttribute(guiObject, desktop, attrib, value, scale) + AttributeParser(guiObject, desktop, scale).applyAll(attributes) def loadSingleSkinData(desktop, skin, path_prefix): """loads skin data like colors, windowstyle etc.""" @@ -332,6 +413,29 @@ def loadSingleSkinData(desktop, skin, path_prefix): addFont(resolved_font, name, scale, is_replacement) #print "Font: ", resolved_font, name, scale, is_replacement + for alias in c.findall("alias"): + get = alias.attrib.get + try: + name = get("name") + font = get("font") + size = int(get("size")) + height = int(get("height", size)) # to be calculated some day + width = int(get("width", size)) + global fonts + fonts[name] = (font, size, height, width) + except Exception, ex: + print "[SKIN] bad font alias", ex + + for c in skin.findall("parameters"): + for parameter in c.findall("parameter"): + get = parameter.attrib.get + try: + name = get("name") + value = get("value") + parameters[name] = map(int, value.split(",")) + except Exception, ex: + print "[SKIN] bad parameter", ex + for c in skin.findall("subtitles"): from enigma import eWidget, eSubtitleWidget scale = ((1,1),(1,1)) @@ -402,27 +506,148 @@ def loadSingleSkinData(desktop, skin, path_prefix): x = eWindowStyleManager.getInstance() x.setStyle(id, style) +display_skin_id = 1 +dom_screens = {} + def loadSkinData(desktop): + global dom_skins, dom_screens, display_skin_id skins = dom_skins[:] skins.reverse() for (path, dom_skin) in skins: loadSingleSkinData(desktop, dom_skin, path) + for elem in dom_skin: + if elem.tag == 'screen': + name = elem.attrib.get('name', None) + if name: + sid = elem.attrib.get('id', None) + if sid and (int(sid) != display_skin_id): + # not for this display + elem.clear() + continue + if name in dom_screens: + # Kill old versions, save memory + dom_screens[name][0].clear() + dom_screens[name] = (elem, path) + else: + # without name, it's useless! + elem.clear() + else: + # non-screen element, no need for it any longer + elem.clear() + # no longer needed, we know where the screens are now. + del dom_skins + def lookupScreen(name, style_id): - for (path, skin) in dom_skins: - # first, find the corresponding screen element - for x in skin.findall("screen"): - if x.attrib.get('name', '') == name: - screen_style_id = x.attrib.get('id', '-1') - if screen_style_id == '-1' and name.find('ummary') > 0: - screen_style_id = '1' - if (style_id != 2 and int(screen_style_id) == -1) or int(screen_style_id) == style_id: - return x, path + if dom_screens.has_key(name): + elem, path = dom_screens[name] + screen_style_id = elem.attrib.get('id', '-1') + if screen_style_id == '-1' and name.find('ummary') > 0: + screen_style_id = '1' + if (style_id != 2 and int(screen_style_id) == -1) or int(screen_style_id) == style_id: + return elem, path + return None, None class additionalWidget: pass +# Class that makes a tuple look like something else. Some plugins just assume +# that size is a string and try to parse it. This class makes that work. +class SizeTuple(tuple): + def split(self, *args): + return (str(self[0]), str(self[1])) + def strip(self, *args): + return '%s,%s' % self + def __str__(self): + return '%s,%s' % self + +class SkinContext: + def __init__(self, parent=None, pos=None, size=None): + if parent is not None: + if pos is not None: + pos, size = parent.parse(pos, size) + self.x, self.y = pos + self.w, self.h = size + else: + self.x = None + self.y = None + self.w = None + self.h = None + def __str__(self): + return "Context (%s,%s)+(%s,%s) " % (self.x, self.y, self.w, self.h) + def parse(self, pos, size): + if pos == "fill": + pos = (self.x, self.y) + size = (self.w, self.h) + self.w = 0 + self.h = 0 + elif pos == "bottom": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y + self.h - h) + size = (self.w, h) + self.h -= h + elif pos == "top": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y) + size = (self.w, h) + self.h -= h + self.y += h + elif pos == "left": + w,h = size.split(',') + w = int(w) + pos = (self.x, self.y) + size = (w, self.h) + self.x += w + self.w -= w + elif pos == "right": + w,h = size.split(',') + w = int(w) + pos = (self.x + self.w - w, self.y) + size = (w, self.h) + self.w -= w + else: + size = size.split(',') + size = (parseCoordinate(size[0], self.w), parseCoordinate(size[1], self.h)) + pos = pos.split(',') + pos = (self.x + parseCoordinate(pos[0], self.w, size[0]), self.y + parseCoordinate(pos[1], self.h, size[1])) + return (SizeTuple(pos), SizeTuple(size)) + +class SkinContextStack(SkinContext): + # A context that stacks things instead of aligning them + def parse(self, pos, size): + if pos == "fill": + pos = (self.x, self.y) + size = (self.w, self.h) + elif pos == "bottom": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y + self.h - h) + size = (self.w, h) + elif pos == "top": + w,h = size.split(',') + h = int(h) + pos = (self.x, self.y) + size = (self.w, h) + elif pos == "left": + w,h = size.split(',') + w = int(w) + pos = (self.x, self.y) + size = (w, self.h) + elif pos == "right": + w,h = size.split(',') + w = int(w) + pos = (self.x + self.w - w, self.y) + size = (w, self.h) + else: + size = size.split(',') + size = (parseCoordinate(size[0], self.w), parseCoordinate(size[1], self.h)) + pos = pos.split(',') + pos = (self.x + parseCoordinate(pos[0], self.w, size[0]), self.y + parseCoordinate(pos[1], self.h, size[1])) + return (SizeTuple(pos), SizeTuple(size)) + def readSkin(screen, skin, names, desktop): if not isinstance(names, list): names = [names] @@ -466,15 +691,30 @@ def readSkin(screen, skin, names, desktop): skin_path_prefix = getattr(screen, "skin_path", path) - collectAttributes(screen.skinAttributes, myscreen, skin_path_prefix, ignore=["name"]) +# collectAttributes(screen.skinAttributes, myscreen, skin_path_prefix, ignore=["name"]) + + context = SkinContext() + s = desktop.size() + context.x = 0 + context.y = 0 + context.w = s.width() + context.h = s.height() + del s + collectAttributes(screen.skinAttributes, myscreen, context, skin_path_prefix, ignore=("name",)) + context = SkinContext(context, myscreen.attrib.get('position'), myscreen.attrib.get('size')) + +# screen.additionalWidgets = [ ] screen.renderer = [ ] visited_components = set() - # now walk all widgets - for widget in myscreen.findall("widget"): + # now walk all widgets and stuff + def process_none(widget, context): + pass + + def process_widget(widget, context): get_attr = widget.attrib.get # ok, we either have 1:1-mapped widgets ('old style'), or 1:n-mapped # widgets (source->renderer). @@ -484,7 +724,7 @@ def readSkin(screen, skin, names, desktop): if wname is None and wsource is None: print "widget has no name and no source!" - continue + return if wname: #print "Widget name=", wname @@ -500,7 +740,7 @@ def readSkin(screen, skin, names, desktop): # assert screen[wname] is not Source # and collect attributes for this - collectAttributes(attributes, widget, skin_path_prefix, ignore=['name']) + collectAttributes(attributes, widget, context, skin_path_prefix, ignore=['name']) elif wsource: # get corresponding source #print "Widget source=", wsource @@ -575,55 +815,98 @@ def readSkin(screen, skin, names, desktop): renderer.connect(source) # connect to source attributes = renderer.skinAttributes = [ ] - collectAttributes(attributes, widget, skin_path_prefix, ignore=['render', 'source']) + collectAttributes(attributes, widget, context, skin_path_prefix, ignore=['render', 'source']) screen.renderer.append(renderer) - from Components.GUIComponent import GUIComponent - nonvisited_components = [x for x in set(screen.keys()) - visited_components if isinstance(x, GUIComponent)] - assert not nonvisited_components, "the following components in %s don't have a skin entry: %s" % (name, ', '.join(nonvisited_components)) + def process_applet(widget, context): + try: + codeText = widget.text.strip() + except: + codeText = "" - # now walk additional objects - for widget in myscreen.getchildren(): - w_tag = widget.tag + #print "Found code:" + #print codeText + widgetType = widget.attrib.get('type') - if w_tag == "widget": - continue + code = compile(codeText, "skin applet", "exec") - if w_tag == "applet": - try: - codeText = widget.text.strip() - except: - codeText = "" + if widgetType == "onLayoutFinish": + screen.onLayoutFinish.append(code) + #print "onLayoutFinish = ", codeText + else: + raise SkinError("applet type '%s' unknown!" % widgetType) + #print "applet type '%s' unknown!" % type + + def process_elabel(widget, context): + w = additionalWidget() + w.widget = eLabel + w.skinAttributes = [ ] + collectAttributes(w.skinAttributes, widget, context, skin_path_prefix, ignore=['name']) + screen.additionalWidgets.append(w) + + def process_epixmap(widget, context): + w = additionalWidget() + w.widget = ePixmap + w.skinAttributes = [ ] + collectAttributes(w.skinAttributes, widget, context, skin_path_prefix, ignore=['name']) + screen.additionalWidgets.append(w) - #print "Found code:" - #print codeText - widgetType = widget.attrib.get('type') + def process_screen(widget, context): + for w in widget.findall("widget"): + process_widget(w, context) + + for w in widget.getchildren(): + if w.tag == "widget": + continue - code = compile(codeText, "skin applet", "exec") + p = processors.get(w.tag, process_none) + p(w, context) - if widgetType == "onLayoutFinish": - screen.onLayoutFinish.append(code) - #print "onLayoutFinish = ", codeText + def process_panel(widget, context): + n = widget.attrib.get('name') + if n: + try: + s = dom_screens.get(n, None) + except KeyError: + print "[SKIN] Unable to find screen '%s' referred in screen '%s'" % (n, name) else: - raise SkinError("applet type '%s' unknown!" % widgetType) - #print "applet type '%s' unknown!" % type + process_screen(s[0], context) + + layout = widget.attrib.get('layout') + if layout == 'stack': + cc = SkinContextStack + else: + cc = SkinContext + try: + c = cc(context, widget.attrib.get('position'), widget.attrib.get('size')) + except Exception, ex: + raise SkinError("Failed to create skincontext (%s,%s) in %s: %s" % (widget.attrib.get('position'), widget.attrib.get('size'), context, ex) ) - continue + process_screen(widget, c) - w = additionalWidget() + processors = { + None: process_none, + "widget": process_widget, + "applet": process_applet, + "eLabel": process_elabel, + "ePixmap": process_epixmap, + "panel": process_panel + } - if w_tag == "eLabel": - w.widget = eLabel - elif w_tag == "ePixmap": - w.widget = ePixmap - else: - raise SkinError("unsupported stuff : %s" % w_tag) - #print "unsupported stuff : %s" % widget.tag + try: + context.x = 0 # reset offsets, all components are relative to screen + context.y = 0 # coordinates. + process_screen(myscreen, context) + except SkinError, e: + print "[Skin] SKIN ERROR:", e - w.skinAttributes = [ ] - collectAttributes(w.skinAttributes, widget, skin_path_prefix, ignore=['name']) + from Components.GUIComponent import GUIComponent + nonvisited_components = [x for x in set(screen.keys()) - visited_components if isinstance(x, GUIComponent)] + assert not nonvisited_components, "the following components in %s don't have a skin entry: %s" % (name, ', '.join(nonvisited_components)) + # This may look pointless, but it unbinds 'screen' from the nested scope. A better + # solution is to avoid the nested scope above and use the context object to pass + # things around. + screen = None + visited_components = None - # applyAttributes(guiObject, widget, desktop) - # guiObject.thisown = 0 - screen.additionalWidgets.append(w)