Support Uno4k/Ultimo4k
authorhschang <chang@dev3>
Thu, 24 Nov 2016 03:50:07 +0000 (12:50 +0900)
committerhschang <chang@dev3>
Thu, 24 Nov 2016 03:50:07 +0000 (12:50 +0900)
  - Fix FCC for uno4k/ultimo4k
  - Fix APIs to support 1080p skin
  - Support HDMI colordepth (VideoMode)
  - Support TT2L08 automatic scan

58 files changed:
ServiceReference.py
configure.ac
data/startwizard.xml
lib/dvb/decoder.cpp
lib/dvb/demux.cpp
lib/dvb/demux.h
lib/dvb/dvb.cpp [changed mode: 0755->0644]
lib/dvb/dvb.h
lib/dvb/fbc.cpp
lib/dvb/fbc.h
lib/dvb/fcc.cpp
lib/dvb/frontend.cpp
lib/dvb/frontend.h
lib/gui/elistbox.cpp
lib/gui/elistbox.h
lib/gui/elistboxcontent.cpp
lib/nav/core.cpp
lib/nav/core.h
lib/python/Components/ChoiceList.py
lib/python/Components/ConfigList.py
lib/python/Components/EpgList.py
lib/python/Components/FileList.py
lib/python/Components/HelpMenuList.py
lib/python/Components/InputDevice.py
lib/python/Components/MediaPlayer.py
lib/python/Components/MovieList.py
lib/python/Components/ParentalControlList.py
lib/python/Components/PluginList.py
lib/python/Components/SelectionList.py
lib/python/Components/SystemInfo.py
lib/python/Components/TimerList.py
lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py
lib/python/Plugins/SystemPlugins/Makefile.am
lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/Makefile.am [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/__init__.py [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/Makefile.am [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/meta/plugin_ultimo4kmisccontrol.xml [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/plugin.py [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
lib/python/Plugins/SystemPlugins/WOLSetup/plugin.py
lib/python/Plugins/SystemPlugins/WirelessAccessPoint/plugin.py
lib/python/Plugins/SystemPlugins/WirelessLanSetup/plugin.py
lib/python/Screens/InfoBar.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/PluginBrowser.py
lib/python/Screens/Satconfig.py
lib/python/Screens/ScanSetup.py
lib/python/Screens/ServiceInfo.py
lib/python/Screens/VirtualKeyBoard.py
lib/python/Tools/HardwareInfo.py
lib/python/enigma_python.i
lib/service/Makefile.am
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicedvbfcc.cpp
lib/service/servicehdmi.cpp [new file with mode: 0644]
lib/service/servicehdmi.h [new file with mode: 0644]
skin.py

index 0a46992..401e47a 100644 (file)
@@ -32,4 +32,4 @@ class ServiceReference(eServiceReference):
 
        def isRecordable(self):
                ref = self.ref
 
        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
index 7c52d00..00a4bd2 100644 (file)
@@ -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/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
 lib/python/Tools/Makefile
 lib/service/Makefile
 lib/components/Makefile
index db04392..5ed6413 100755 (executable)
@@ -48,8 +48,8 @@ self.selectKey("RIGHT")
                <step id="nimc">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimc">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner C" />
                        <config screen="NimSetup" module="Satconfig" args="2" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner C" />
                        <config screen="NimSetup" module="Satconfig" args="2" type="ConfigList" />
@@ -62,8 +62,8 @@ self.selectKey("RIGHT")
                <step id="nimd">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimd">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner D" />
                        <config screen="NimSetup" module="Satconfig" args="3" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner D" />
                        <config screen="NimSetup" module="Satconfig" args="3" type="ConfigList" />
@@ -76,8 +76,8 @@ self.selectKey("RIGHT")
                <step id="nime">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nime">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner E" />
                        <config screen="NimSetup" module="Satconfig" args="4" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner E" />
                        <config screen="NimSetup" module="Satconfig" args="4" type="ConfigList" />
@@ -90,8 +90,8 @@ self.selectKey("RIGHT")
                <step id="nimf">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimf">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner F" />
                        <config screen="NimSetup" module="Satconfig" args="5" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner F" />
                        <config screen="NimSetup" module="Satconfig" args="5" type="ConfigList" />
@@ -104,8 +104,8 @@ self.selectKey("RIGHT")
                <step id="nimg">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimg">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner G" />
                        <config screen="NimSetup" module="Satconfig" args="6" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner G" />
                        <config screen="NimSetup" module="Satconfig" args="6" type="ConfigList" />
@@ -118,8 +118,8 @@ self.selectKey("RIGHT")
                <step id="nimh">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimh">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner H" />
                        <config screen="NimSetup" module="Satconfig" args="7" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner H" />
                        <config screen="NimSetup" module="Satconfig" args="7" type="ConfigList" />
@@ -132,8 +132,8 @@ self.selectKey("RIGHT")
                <step id="nimi">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimi">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner I" />
                        <config screen="NimSetup" module="Satconfig" args="8" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner I" />
                        <config screen="NimSetup" module="Satconfig" args="8" type="ConfigList" />
@@ -146,8 +146,8 @@ self.selectKey("RIGHT")
                <step id="nimj">
                        <condition>
 from Components.NimManager import nimmanager
                <step id="nimj">
                        <condition>
 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)
                        </condition>
                        <text value="Please set up tuner J" />
                        <config screen="NimSetup" module="Satconfig" args="9" type="ConfigList" />
                        </condition>
                        <text value="Please set up tuner J" />
                        <config screen="NimSetup" module="Satconfig" args="9" type="ConfigList" />
@@ -157,6 +157,34 @@ self.selectKey("LEFT")
 self.selectKey("RIGHT")
                        </code>
                </step>
 self.selectKey("RIGHT")
                        </code>
                </step>
+               <step id="nimq">
+                       <condition>
+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)
+                       </condition>
+                       <text value="Please set up tuner Q" />
+                       <config screen="NimSetup" module="Satconfig" args="16" type="ConfigList" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("LEFT")
+self.selectKey("RIGHT")
+                       </code>
+               </step>
+               <step id="nimr">
+                       <condition>
+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)
+                       </condition>
+                       <text value="Please set up tuner R" />
+                       <config screen="NimSetup" module="Satconfig" args="17" type="ConfigList" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("LEFT")
+self.selectKey("RIGHT")
+                       </code>
+               </step>
                <step id="satlistsquestion">
                        <text value="Do you want to install default sat lists?" />
                        <condition>
                <step id="satlistsquestion">
                        <text value="Do you want to install default sat lists?" />
                        <condition>
index e3d97af..2c8044b 100644 (file)
 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
 #endif
 
 #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)
 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
 #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);
 #endif
        m_fd = ::open(filename, O_RDWR);
        if (m_fd < 0)
                eWarning("%s: %m", filename);
+       if (demux)
+       {
 #if HAVE_DVB_API_VERSION < 3
 #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
 #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
 #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
 }
 
 #if HAVE_DVB_API_VERSION < 3
@@ -160,89 +179,101 @@ int eDVBAudio::setAVSync(int val)
 #else
 int eDVBAudio::startPid(int pid, int type)
 {
 #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()
 {
        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
 #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
 #endif
+       }
 }
 
 void eDVBAudio::flush()
 }
 
 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
        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)
 #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);
                CONNECT(m_sn->activated, eDVBVideo::video_event);
        }
        eDebug("Video Device: %s", filename);
+
+
+
+       if (demux)
+       {
 #if HAVE_DVB_API_VERSION < 3
 #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
 #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
 #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.. !!
 }
 
 // not finally values i think.. !!
@@ -408,71 +454,79 @@ int eDVBVideo::stopPid()
 #else
 int eDVBVideo::startPid(int pid, int type)
 {
 #else
 int eDVBVideo::startPid(int pid, int type)
 {
-       int streamtype = VIDEO_STREAMTYPE_MPEG2;
-
        if (m_fcc_enable)
                return 0;
 
        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
        return 0;
 }
 #endif
@@ -482,18 +536,25 @@ void eDVBVideo::stop()
        if (m_fcc_enable)
                return;
 
        if (m_fcc_enable)
                return;
 
+       if (m_fd_demux >= 0)
+       {
 #if HAVE_DVB_API_VERSION > 2
 #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
 #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()
 }
 
 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)
 {
                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;
 }
        CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
        m_state = stateStop;
 }
index b677275..1af2a10 100644 (file)
@@ -58,12 +58,10 @@ typedef enum {
 #include "crc32.h"
 
 #include <lib/base/eerror.h>
 #include "crc32.h"
 
 #include <lib/base/eerror.h>
-#include <lib/base/filepush.h>
 #include <lib/dvb/idvb.h>
 #include <lib/dvb/demux.h>
 #include <lib/dvb/esection.h>
 #include <lib/dvb/decoder.h>
 #include <lib/dvb/idvb.h>
 #include <lib/dvb/demux.h>
 #include <lib/dvb/esection.h>
 #include <lib/dvb/decoder.h>
-#include <lib/dvb/pvrparse.h>
 
 eDVBDemux::eDVBDemux(int adapter, int demux): adapter(adapter), demux(demux)
 {
 
 eDVBDemux::eDVBDemux(int adapter, int demux): adapter(adapter), demux(demux)
 {
@@ -151,9 +149,9 @@ RESULT eDVBDemux::createTSRecorder(ePtr<iDVBTSRecorder> &recorder)
        return 0;
 }
 
        return 0;
 }
 
-RESULT eDVBDemux::getMPEGDecoder(ePtr<iTSMPEGDecoder> &decoder, int primary)
+RESULT eDVBDemux::getMPEGDecoder(ePtr<iTSMPEGDecoder> &decoder, int index)
 {
 {
-       decoder = new eTSMPEGDecoder(this, primary ? 0 : 1);
+       decoder = new eTSMPEGDecoder(this, index);
        return 0;
 }
 
        return 0;
 }
 
@@ -447,26 +445,6 @@ RESULT eDVBPESReader::connectRead(const Slot2<void,const __u8*,int> &r, ePtr<eCo
        return 0;
 }
 
        return 0;
 }
 
-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 &current_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;
-};
-
 eDVBRecordFileThread::eDVBRecordFileThread()
        :eFilePushThread(IOPRIO_CLASS_RT, 7), m_ts_parser(m_stream_info)
 {
 eDVBRecordFileThread::eDVBRecordFileThread()
        :eFilePushThread(IOPRIO_CLASS_RT, 7), m_ts_parser(m_stream_info)
 {
index b34ad27..015115a 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <lib/dvb/idvb.h>
 #include <lib/dvb/idemux.h>
 
 #include <lib/dvb/idvb.h>
 #include <lib/dvb/idemux.h>
+#include <lib/dvb/pvrparse.h>
+#include <lib/base/filepush.h>
 
 class eDVBDemux: public iDVBDemux
 {
 
 class eDVBDemux: public iDVBDemux
 {
@@ -83,7 +85,25 @@ public:
        RESULT connectRead(const Slot2<void,const __u8*, int> &read, ePtr<eConnection> &conn);
 };
 
        RESULT connectRead(const Slot2<void,const __u8*, int> &read, ePtr<eConnection> &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 &current_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
 {
 
 class eDVBTSRecorder: public iDVBTSRecorder, public Object
 {
old mode 100755 (executable)
new mode 100644 (file)
index 012a834..756c685
@@ -34,7 +34,7 @@ eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
                eFBCTunerManager* fbcmng = eFBCTunerManager::getInstance();
                if (fbcmng)
                {
                eFBCTunerManager* fbcmng = eFBCTunerManager::getInstance();
                if (fbcmng)
                {
-                       fbcmng->unset(m_fe);
+                       fbcmng->unLink(m_fe);
                }
        }
 }
                }
        }
 }
@@ -126,6 +126,8 @@ eDVBResourceManager::eDVBResourceManager()
 
        eDVBCAService::registerChannelCallback(this);
 
 
        eDVBCAService::registerChannelCallback(this);
 
+       m_fbc_mng = new eFBCTunerManager(this);
+
        CONNECT(m_releaseCachedChannelTimer->timeout, eDVBResourceManager::releaseCachedChannel);
 }
 
        CONNECT(m_releaseCachedChannelTimer->timeout, eDVBResourceManager::releaseCachedChannel);
 }
 
@@ -433,26 +435,34 @@ void eDVBResourceManager::setFrontendType(int index, const char *type)
 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm, bool simulate)
 {
        eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm, bool simulate)
 {
        eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
-//     ePtr<eDVBRegisteredFrontend> best;
        eDVBRegisteredFrontend *best = NULL;
        int bestval = 0;
        int foundone = 0;
 
        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;
        eDVBRegisteredFrontend *fbc_fe = NULL;
        eDVBRegisteredFrontend *best_fbc_fe = NULL;
-       eFBCTunerManager* fbcmng = eFBCTunerManager::getInstance();
 
        for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
        {
                int c = 0;
                fbc_fe = NULL;
 
        for (eSmartPtrList<eDVBRegisteredFrontend>::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
                {
                }
                else
                {
@@ -464,18 +474,17 @@ RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, eP
 
                if (!i->m_inuse)
                {
 
                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;
                        if (c > bestval)
                        {
                                bestval = c;
-//                             best = i;
                                best = *i;
                                best_fbc_fe = fbc_fe;
                        }
                }
                else
                {
                                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;
                }
 
                eDVBRegisteredFrontend *tmp = *i;
@@ -483,9 +492,9 @@ RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, eP
 
        if (best)
        {
 
        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);
                }
 
                fe = new eDVBAllocatedFrontend(best);
@@ -911,18 +920,29 @@ int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &fepar
        eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
        ePtr<eDVBRegisteredFrontend> best;
        int bestval = 0;
        eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
        ePtr<eDVBRegisteredFrontend> 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<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
        {
                if (!i->m_inuse)
                {
                        int c = 0;
 
        for (eSmartPtrList<eDVBRegisteredFrontend>::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
                        {
                        }
                        else
                        {
index fa1e8a1..c0acc4f 100644 (file)
@@ -159,6 +159,8 @@ class eDVBResourceManager: public iObject, public Object
        ePtr<iDVBChannelList> m_list;
        ePtr<iDVBSatelliteEquipmentControl> m_sec;
        static eDVBResourceManager *instance;
        ePtr<iDVBChannelList> m_list;
        ePtr<iDVBSatelliteEquipmentControl> m_sec;
        static eDVBResourceManager *instance;
+
+       ePtr<eFBCTunerManager> m_fbc_mng;
  
        friend class eDVBChannel;
        friend class eFBCTunerManager;
  
        friend class eDVBChannel;
        friend class eFBCTunerManager;
index dc70c05..9dd66b0 100644 (file)
@@ -7,8 +7,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 
 #include <unistd.h>
 #include <fcntl.h>
 
-#define FE_SLOT_ID(fe) fe->m_frontend->getSlotID()
-
 //#define FBC_DEBUG
 
 #ifdef FBC_DEBUG
 //#define FBC_DEBUG
 
 #ifdef FBC_DEBUG
 #define eFecDebug(arg...)
 #endif
 
 #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<eDVBResourceManager> 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<eDVBResourceManager> res_mgr)
+       :m_res_mgr(res_mgr)
 {
 {
+       if (!m_instance)
+               m_instance = this;
+
        eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_frontend;
 
        eSmartPtrList<eDVBRegisteredFrontend> &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<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); ++it)
        {
 
        for (eSmartPtrList<eDVBRegisteredFrontend>::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;
 
                        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 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;
 }
 
        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<eDVBSatelliteEquipmentControl> 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<eDVBRegisteredFrontend> &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend;
+       for (eSmartPtrList<eDVBRegisteredFrontend>::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;
 {
        eDVBRegisteredFrontend *prev_fe = NULL;
        long linked_prev_ptr = -1;
@@ -152,7 +259,7 @@ eDVBRegisteredFrontend *eFBCTunerManager::getPrev(eDVBRegisteredFrontend *fe)
        return prev_fe;
 }
 
        return prev_fe;
 }
 
-eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe)
+eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe) const
 {
        eDVBRegisteredFrontend *next_fe = NULL;
        long linked_next_ptr = -1;
 {
        eDVBRegisteredFrontend *next_fe = NULL;
        long linked_next_ptr = -1;
@@ -162,7 +269,7 @@ eDVBRegisteredFrontend *eFBCTunerManager::getNext(eDVBRegisteredFrontend *fe)
        return next_fe;
 }
 
        return next_fe;
 }
 
-eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe)
+eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe) const
 {
        eDVBRegisteredFrontend *prev_fe = fe;
        long linked_prev_ptr = -1;
 {
        eDVBRegisteredFrontend *prev_fe = fe;
        long linked_prev_ptr = -1;
@@ -175,7 +282,7 @@ eDVBRegisteredFrontend *eFBCTunerManager::getTop(eDVBRegisteredFrontend *fe)
        return prev_fe;
 }
 
        return prev_fe;
 }
 
-eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe)
+eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe) const
 {
        eDVBRegisteredFrontend *next_fe = fe;
        long linked_next_ptr = -1;
 {
        eDVBRegisteredFrontend *next_fe = fe;
        long linked_next_ptr = -1;
@@ -188,371 +295,53 @@ eDVBRegisteredFrontend *eFBCTunerManager::getLast(eDVBRegisteredFrontend *fe)
        return next_fe;
 }
 
        return next_fe;
 }
 
-bool eFBCTunerManager::isLinked(eDVBRegisteredFrontend *fe)
+eDVBRegisteredFrontend *eFBCTunerManager::getSimulFe(eDVBRegisteredFrontend *fe) const
 {
 {
-       return getPrev(fe) ? true:false;
-}
+       eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_simulate_frontend;
 
 
-bool eFBCTunerManager::isLinkedByIndex(int fe_idx)
-{
-       bool linked = false;
-       eSmartPtrList<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_frontend;
+       for (eSmartPtrList<eDVBRegisteredFrontend>::iterator it(frontends.begin()); it != frontends.end(); it++)
+               if (feSlotID(*it) == feSlotID(fe))
+                       return(*it);
 
 
-       for (eSmartPtrList<eDVBRegisteredFrontend>::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<eDVBRegisteredFrontend> &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<eDVBRegisteredFrontend>::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);
        }
                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<eDVBRegisteredFrontend> &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<eDVBRegisteredFrontend>::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
        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<eDVBRegisteredFrontend> &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<eDVBRegisteredFrontend>::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);
                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<eDVBRegisteredFrontend> &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<eDVBRegisteredFrontend>::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
        {
        }
        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);
                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<eDVBRegisteredFrontend> &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend;
-       for (eSmartPtrList<eDVBRegisteredFrontend>::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<eDVBSatelliteEquipmentControl> 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<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, bool simulate)
-{
-       eDVBRegisteredFrontend *best_fbc_fe;
-       return isCompatibleWith(feparm, link_fe, best_fbc_fe, simulate);
 }
 
 int eFBCTunerManager::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate)
 }
 
 int eFBCTunerManager::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate)
@@ -571,7 +360,7 @@ int eFBCTunerManager::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDV
                if(!it->m_frontend->getEnabled())
                        continue;
 
                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.
                        continue;
 
                if(it->m_inuse == 0) // No link to a fe not in use.
@@ -583,174 +372,158 @@ int eFBCTunerManager::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDV
                if(isUnicable(*it))
                        continue;
 
                if(isUnicable(*it))
                        continue;
 
+               eDVBRegisteredFrontend *top_fe = *it;
+               eDVBRegisteredFrontend *prev_fe = getLast(top_fe);
+
                /* connect link */
                /* 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);
 
                /* 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;
                }
 
                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 */
                /* 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;
 }
 
 
        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;
                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;
        }
 
                        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! */
 }
 
 /* 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;
                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<eDVBRegisteredFrontend> &frontends = simulate ? m_res_mgr->m_simulate_frontend : m_res_mgr->m_frontend;
-       for (eSmartPtrList<eDVBRegisteredFrontend>::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)
 }
 
 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;
 }
 
        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<eDVBRegisteredFrontend> &frontends = m_res_mgr->m_frontend;
 {
        int link = -1;
        eSmartPtrList<eDVBRegisteredFrontend> &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;
                        if (prev_ptr != -1)
                        {
                                eDVBRegisteredFrontend *prev_fe = (eDVBRegisteredFrontend *)prev_ptr;
-                               link = FE_SLOT_ID(prev_fe);
+                               link = feSlotID(prev_fe);
                        }
                        break;
                }
                        }
                        break;
                }
@@ -807,7 +585,18 @@ int eFBCTunerManager::getLinkedSlotID(int fe_id)
        return link;
 }
 
        return link;
 }
 
-void eFBCTunerManager::printLinks(eDVBRegisteredFrontend *fe)
+bool eFBCTunerManager::isFBCLink(int fe_id)
+{
+       bool res = false;
+       std::map<int, FBC_TUNER>::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;
 {
        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;
 
        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;
        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);
        }
 
                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;
                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;
                }
 
                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<eDVBRegisteredFrontend> &simulate_frontends = m_res_mgr->m_simulate_frontend;
        }
 
        eSmartPtrList<eDVBRegisteredFrontend> &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;
                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;
                }
 
                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);
        }
 }
 
        }
 }
 
index 5f1afc1..f4899f0 100644 (file)
@@ -6,75 +6,63 @@
 #include <lib/base/object.h>
 #include <lib/base/eptrlist.h>
 #include <lib/dvb/idvb.h>
 #include <lib/base/object.h>
 #include <lib/base/eptrlist.h>
 #include <lib/dvb/idvb.h>
+#include <map>
 
 class eDVBResourceManager;
 class eDVBRegisteredFrontend;
 
 
 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<eDVBResourceManager> m_res_mgr;
 class eFBCTunerManager: public iObject, public Object
 {
 private:
        DECLARE_REF(eFBCTunerManager);
        ePtr<eDVBResourceManager> m_res_mgr;
-       int m_fbc_tuner_num;
-       static bool isDestroyed;
+       static eFBCTunerManager *m_instance;
+       std::map<int, FBC_TUNER> 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);
        int updateLNBSlotMask(int dest_slot, int src_slot, bool remove);
-       void printLinks(eDVBRegisteredFrontend *fe);
+       void printLinks(eDVBRegisteredFrontend *fe) const;
 
 public:
 
 public:
-       eFBCTunerManager();
+       static eFBCTunerManager* getInstance();
+       eFBCTunerManager(ePtr<eDVBResourceManager> res_mgr);
        virtual ~eFBCTunerManager();
        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);
        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<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, bool simulate);
        int isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm, eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *&fbc_fe, bool simulate);
        void addLink(eDVBRegisteredFrontend *link_fe, eDVBRegisteredFrontend *top_fe, bool simulate);
        int isCompatibleWith(ePtr<iDVBFrontendParameters> &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 */
+
index 614340b..e83dbc8 100644 (file)
@@ -326,7 +326,7 @@ bool eFCCServiceManager::checkAvailable(const eServiceReference &ref)
        int serviceType = ref.getData(0);
        eFCCServiceManager *fcc_mng = eFCCServiceManager::getInstance();
 
        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;
 }
                return fcc_mng->isEnable();
        return false;
 }
index fa36653..2892fe4 100755 (executable)
@@ -525,11 +525,6 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFronten
 
        m_idleInputpower[0]=m_idleInputpower[1]=0;
 
 
        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();
 }
        ok = !openFrontend();
        closeFrontend();
 }
index aceb856..41dc311 100644 (file)
@@ -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; }
        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(); }
        bool getEnabled() { return m_enabled; }
        void setEnabled(bool enable) { m_enabled = enable; }
        bool isLoopTimerActive() { return m_tuneTimer->isActive(); }
index c13114e..a73cfdb 100644 (file)
@@ -480,6 +480,11 @@ void eListbox::entryReset(bool selectionHome)
        invalidate();
 }
 
        invalidate();
 }
 
+void eListbox::setFont(gFont *font)
+{
+       m_style.m_font = font;
+}
+
 void eListbox::setBackgroundColor(gRGB &col)
 {
        m_style.m_background_color = col;
 void eListbox::setBackgroundColor(gRGB &col)
 {
        m_style.m_background_color = col;
index 0073653..7334e48 100644 (file)
@@ -71,6 +71,7 @@ struct eListboxStyle
                        {1 x 0} use transparent background
                        {1 x p} use transparent background picture
                */
                        {1 x 0} use transparent background
                        {1 x p} use transparent background picture
                */
+       ePtr<gFont> m_font;
 };
 #endif
 
 };
 #endif
 
@@ -127,6 +128,7 @@ public:
        void setForegroundColorSelected(gRGB &col);
        void setBackgroundPicture(ePtr<gPixmap> &pixmap);
        void setSelectionPicture(ePtr<gPixmap> &pixmap);
        void setForegroundColorSelected(gRGB &col);
        void setBackgroundPicture(ePtr<gPixmap> &pixmap);
        void setSelectionPicture(ePtr<gPixmap> &pixmap);
+       void setFont(gFont *font);
 
 #ifndef SWIG
        struct eListboxStyle *getLocalStyle(void);
 
 #ifndef SWIG
        struct eListboxStyle *getLocalStyle(void);
index ba0794e..3dcea7b 100644 (file)
@@ -138,7 +138,7 @@ void eListboxPythonStringContent::setSize(const eSize &size)
 
 void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
 {
 
 void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
 {
-       ePtr<gFont> fnt = new gFont("Regular", 20);
+       ePtr<gFont> fnt;
        painter.clip(eRect(offset, m_itemsize));
        style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
 
        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)
        {
 
        if (local_style)
        {
+               fnt = local_style->m_font;
                if (selected)
                {
                        /* if we have a local background color set, use that. */
                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);
                }
        }
                                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)
 
        /* 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)
 {
 
 void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
 {
-       ePtr<gFont> fnt = new gFont("Regular", 20);
-       ePtr<gFont> fnt2 = new gFont("Regular", 16);
+       ePtr<gFont> fnt;
+       ePtr<gFont> fnt2;
        eRect itemrect(offset, m_itemsize);
        eListboxStyle *local_style = 0;
        bool cursorValid = this->cursorValid();
        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)
        {
 
        if (local_style)
        {
+               fnt = local_style->m_font;
                if (selected)
                {
                        /* if we have a local background color set, use that. */
                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 */
        {
        if (!local_style || !local_style->m_transparent_background)
                /* if we have no transparent background */
        {
index 2e54d87..cfb132f 100644 (file)
@@ -36,6 +36,7 @@ RESULT eNavigation::playService(const eServiceReference &service)
 
        if (m_runningService)
        {
 
        if (m_runningService)
        {
+               m_runningService->setTarget(m_decoder);
                m_runningService->connectEvent(slot(*this, &eNavigation::serviceEvent), m_service_event_conn);
                res = m_runningService->start();
        }
                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();
 }
 
                return p->unpause();
 }
 
-eNavigation::eNavigation(iServiceHandler *serviceHandler)
+eNavigation::eNavigation(iServiceHandler *serviceHandler, int decoder)
 {
        ASSERT(serviceHandler);
        m_servicehandler = serviceHandler;
 {
        ASSERT(serviceHandler);
        m_servicehandler = serviceHandler;
+       m_decoder = decoder;
        m_fccmgr = new eFCCServiceManager(this);
 }
 
        m_fccmgr = new eFCCServiceManager(this);
 }
 
index a4906c1..b055bc8 100644 (file)
@@ -11,6 +11,7 @@
 class eNavigation: public iObject, public Object
 {
        DECLARE_REF(eNavigation);
 class eNavigation: public iObject, public Object
 {
        DECLARE_REF(eNavigation);
+       int m_decoder;
        ePtr<iServiceHandler> m_servicehandler;
 
        ePtr<iPlayableService> m_runningService;
        ePtr<iServiceHandler> m_servicehandler;
 
        ePtr<iPlayableService> m_runningService;
@@ -41,7 +42,7 @@ public:
        PyObject *getRecordings(bool simulate=false);
        
        RESULT pause(int p);
        PyObject *getRecordings(bool simulate=false);
        
        RESULT pause(int p);
-       eNavigation(iServiceHandler *serviceHandler);
+       eNavigation(iServiceHandler *serviceHandler, int decoder = 0);
        virtual ~eNavigation();
 };
 
        virtual ~eNavigation();
 };
 
index 33868d6..af93399 100755 (executable)
@@ -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
 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] == "--":
 
 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:
        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:
        
                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)
        
        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):
                self.selection = selection
 
        def postWidgetCreate(self, instance):
index 24f917f..fd638d7 100755 (executable)
@@ -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
 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()
 
 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 = [ ]
                self.timer = eTimer()
                self.list = list
                self.onSelectionChanged = [ ]
index 41cd1b2..1440d60 100755 (executable)
@@ -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
 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
 
 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()
                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:
                if type == EPG_TYPE_SINGLE:
                        self.l.setBuildFunc(self.buildSingleEntry)
                elif type == EPG_TYPE_MULTI:
index 4c5b98d..542a135 100755 (executable)
@@ -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
 from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \
        eServiceReference, eServiceCenter, gFont
 from Tools.LoadPixmap import LoadPixmap
+import skin
 
 EXTENSIONS = {
                "m4a": "music",
 
 EXTENSIONS = {
                "m4a": "music",
@@ -42,7 +43,8 @@ EXTENSIONS = {
 
 def FileEntryComponent(name, absolute = None, isDir = False):
        res = [ (absolute, isDir) ]
 
 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:
        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:
                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
 
        
        return res
 
@@ -76,8 +79,9 @@ class FileList(MenuList):
 
                self.refreshMountpoints()
                self.changeDir(directory)
 
                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):
                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) ]
 
 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:
        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:
                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:
 
        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))
                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
 
        
        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.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):
                self.onSelectionChanged = [ ]
 
        def selectionChanged(self):
index 66139df..c997395 100755 (executable)
@@ -2,6 +2,7 @@ from GUIComponent import GUIComponent
 
 from enigma import eListboxPythonMultiContent, eListbox, gFont
 from Tools.KeyBindings import queryKeyBinding, getKeyDescription
 
 from enigma import eListboxPythonMultiContent, eListbox, gFont
 from Tools.KeyBindings import queryKeyBinding, getKeyDescription
+import skin
 #getKeyPositions
 
 # [ ( actionmap, context, [(action, help), (action, help), ...] ), (actionmap, ... ), ... ]
 #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"
                                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((
                                        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:
                                        ))
                                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:
                                        
                                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:
                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...
 
        def ok(self):
                # a list entry has a "private" tuple as first entry...
index d675ca3..965a27f 100755 (executable)
@@ -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
 # 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
 
 IOC_NRSHIFT = 0L
 IOC_TYPESHIFT = IOC_NRSHIFT+IOC_NRBITS
@@ -33,6 +33,9 @@ class inputDevices:
                devices = listdir("/dev/input/")
 
                for evdev in devices:
                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)
                        try:
                                buffer = "\0"*512
                                self.fd = os_open("/dev/input/" + evdev, O_RDWR | O_NONBLOCK)
index 5583b22..35fdce1 100755 (executable)
@@ -6,6 +6,7 @@ from os import path
 from enigma import eListboxPythonMultiContent, RT_VALIGN_CENTER, gFont, eServiceCenter
 
 from Tools.LoadPixmap import LoadPixmap
 from enigma import eListboxPythonMultiContent, RT_VALIGN_CENTER, gFont, eServiceCenter
 
 from Tools.LoadPixmap import LoadPixmap
+import skin
 
 STATE_PLAY = 0
 STATE_PAUSE = 1
 
 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]
        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
        png = None
        if state == STATE_PLAY:
                png = PlayIcon
@@ -39,15 +41,17 @@ def PlaylistEntryComponent(serviceref, state):
                png = ForwardIcon
 
        if png is not None:
                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)
 
        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()
                self.currPlaying = -1
                self.oldCurrPlaying = -1
                self.serviceHandler = eServiceCenter.getInstance()
index 5c98e4b..3df3bf2 100644 (file)
@@ -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.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()
                
                self.l = eListboxPythonMultiContent()
                self.tags = set()
                
@@ -57,20 +66,63 @@ class MovieList(GUIComponent):
        def setSortType(self, type):
                self.sort_type = type
 
        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:
        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:
                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)
                        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:
                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              |
 
        #
        # | name of movie              |
@@ -106,45 +158,54 @@ class MovieList(GUIComponent):
                if begin > 0:
                        t = FuzzyTime(begin)
                        begin_string = t[0] + ", " + t[1]
                if begin > 0:
                        t = FuzzyTime(begin)
                        begin_string = t[0] + ", " + t[1]
-               
+               ih = self.itemHeight
                if self.list_type == MovieList.LISTTYPE_ORIGINAL:
                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:
                        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:
                                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:
                        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:
                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:
                        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:
                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:
                        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:
                                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:
                        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:
                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:
                        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
 
                
                return res
 
index 0e65257..e6425b7 100644 (file)
@@ -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
 
 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 = {}
 
 #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)
 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
 
        def toggleSelectedLock(self):
                from Components.ParentalControl import parentalControl
index 39c60ff..fee11ef 100644 (file)
@@ -5,44 +5,55 @@ from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixm
 
 from enigma import eListboxPythonMultiContent, gFont
 from Tools.LoadPixmap import LoadPixmap
 
 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
 
        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,
        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,
        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
 
        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,
        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)
        ]
        
 
 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]))
index 1c5423f..030f7c5 100755 (executable)
@@ -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
 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"))
 
 
 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)
 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))
 
        def addSelection(self, description, value, index, selected = True):
                self.list.append(SelectionEntryComponent(description, value, index, selected))
index f9c4065..67f2e75 100644 (file)
@@ -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["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"
+
index 30097c9..f895bd8 100755 (executable)
@@ -1,5 +1,6 @@
 from HTMLComponent import HTMLComponent
 from GUIComponent import GUIComponent
 from HTMLComponent import HTMLComponent
 from GUIComponent import GUIComponent
+from skin import parseFont
 
 from Tools.FuzzyDate import FuzzyTime
 
 
 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 ]
        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") )
 
                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
                                        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:
                                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:
                        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:
                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:
                                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:
                        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:
 
                if not processed:
                        if timer.state == TimerEntry.StateWaiting:
@@ -68,21 +75,41 @@ class TimerList(HTMLComponent, GUIComponent, object):
                if timer.disabled:
                        state = _("disabled")
 
                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:
 
                if timer.disabled:
+                       iconPosX = width * 490 / 740
                        png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/redx.png"))
                        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)
                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)
                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()
        
        def getCurrent(self):
                cur = self.l.getCurrentSelection()
index 1d621f4..1f081e6 100755 (executable)
@@ -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
 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.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)
                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.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):
 
        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):
                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)
                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):
                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))
                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
 
 
        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):
        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 = [ 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())
                self.l.setList([res])
 
 config.misc.graph_mepg_prev_time=ConfigClock(default = time())
index 950b50e..a5c65be 100755 (executable)
@@ -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 \
        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
 
 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 (file)
index 0000000..c7cc202
--- /dev/null
@@ -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 (file)
index 0000000..8d1c8b6
--- /dev/null
@@ -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 (file)
index 0000000..e23527e
--- /dev/null
@@ -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 (file)
index 0000000..7440ede
--- /dev/null
@@ -0,0 +1,16 @@
+<default>
+         <prerequisites>
+                    <tag type="System" />
+         </prerequisites>
+          <info>
+                    <author>hschang</author>
+                    <name>Ultimo4kMiscControl</name>
+                    <packagename>enigma2-plugin-systemplugins-ultimo4kmisccontrol</packagename>
+                    <shortdescription>set Ultimo4K LNB Power and etc..</shortdescription>
+                    <description>Control LNB Power and ToneBurst,CI delay for Ultimo4K.</description>
+          </info>
+
+         <files type="package"> <!-- without version, without .ipk -->
+               <file type="package" name="enigma2-plugin-systemplugins-ultimo4kmisccontrol" />
+       </files>
+</default>
diff --git a/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/plugin.py b/lib/python/Plugins/SystemPlugins/Ultimo4kMiscControl/plugin.py
new file mode 100644 (file)
index 0000000..d9cd261
--- /dev/null
@@ -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 =  """
+               <screen position="center,center" size="400,250" title="Ultimo4K Misc. Control" >
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="30,10" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="230,10" size="140,40" alphatest="on" />
+                       <widget source="key_red" render="Label" position="30,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
+                       <widget source="key_green" render="Label" position="230,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
+                       <widget name="config" zPosition="2" position="5,70" size="380,180" scrollbarMode="showOnDemand" transparent="1" />
+               </screen>
+               """
+
+       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
+
index 8781659..6b5d4d7 100644 (file)
@@ -62,10 +62,10 @@ class VideoHardware:
        }
 
        widescreen_modes = set(["720p", "1080i", "1080p", "2160p"])
        }
 
        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"
 
        def getDeviceName(self):
                device_name = "unknown"
@@ -80,10 +80,10 @@ class VideoHardware:
                return device_name
 
        def isVumodel(self, hw_type):
                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):
 
        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):
 
        # re-define AVSwitch.getOutputAspect
        def getOutputAspect(self):
index bf29218..6d285fd 100644 (file)
@@ -9,10 +9,12 @@ from Screens.ChoiceBox import ChoiceBox
 from Screens.MessageBox import MessageBox
 from Screens.Standby import TryQuitMainloop
 
 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.PluginComponent import plugins
 
 from Components.ConfigList import ConfigListScreen
 from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigSelection
+from Components.Network import iNetwork
 
 import os
 
 
 import os
 
@@ -24,6 +26,8 @@ _flagSupportWol = _flagForceEnable and True or os.path.exists(_deviseWOL)
 _tryQuitTable = {"deepstandby":1, "reboot":2, "guirestart":3}
 
 _ethDevice = "eth0"
 _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)
 
 config.plugins.wolconfig = ConfigSubsection()
 config.plugins.wolconfig.activate = ConfigYesNo(default = False)
@@ -46,7 +50,7 @@ class NetTool:
 
 class WOLSetup(ConfigListScreen, Screen):
        skin =  """
 
 class WOLSetup(ConfigListScreen, Screen):
        skin =  """
-               <screen name="WOLSetup" position="center,120" size="600,390" title="WakeOnLan Setup">
+               <screen name="WOLSetup" position="center,center" size="600,390" title="WakeOnLan Setup">
                        <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/red.png" position="5,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/green.png" position="155,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,0" size="140,40" alphatest="on" />
@@ -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))
                        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)
 
                        else:   macaddr = "Wake on Lan disabled"
                        self["introduction"].setText(macaddr)
 
index f4dce00..5b34d8f 100755 (executable)
@@ -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
                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":
                        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.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 )
                        return -1
 
                apModeConfig.wirelessdevice = ConfigSelection( choices = self.wlanDeviceList )
index 7f53647..0ff7c4f 100755 (executable)
@@ -136,6 +136,8 @@ class WlanSelection(Screen,HelpableScreen):
                                        return str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter")
                        else:
                                return _("Unknown network adapter")
                                        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")
 
                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):
                        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):
                        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):
                        iNetwork.getInterfaces(self.getInterfacesDataAvail)
 
        def getInterfacesDataAvail(self, data):
-               if data is True:
+               if data:
                        self.restartLanRef.close(True)
 
        def restartfinishedCB(self,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):
                        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.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()
        def updateInterfaces(self,callback = None):
                iNetwork.config_ready = False
                iNetwork.msgPlugins()
@@ -395,6 +399,45 @@ class WlanConfig(Screen, ConfigListScreen, HelpableScreen):
                self.createConfig()
                self.createSetup()
 
                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
 
        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)
 
                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
 
 # 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
                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.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.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)
                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.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.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 )
 
                        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)
 
                                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:
                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)
 
        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
                                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)
 
        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)
                        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"
 
                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()
 #              print "content = \n"+contents
                wpafd.write(contents)
                wpafd.close()
-               self.writeNetConfig()
+
+               return True
 
        def writeNetConfig(self):
                if self.activateInterfaceEntry.value is 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)
 
                        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)
                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.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..."))
        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)
        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)
                
 
                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)
 
                        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)
 class NetworkAdapterTest(Screen):
        def __init__(self, session,iface):
                Screen.__init__(self, session)
index 4145722..8fec85c 100755 (executable)
@@ -16,7 +16,8 @@ from Screens.InfoBarGenerics import InfoBarShowHide, \
        InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift,  \
        InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \
        InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \
        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
 
 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,
        InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek,
        InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions,
        InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman,
-       Screen):
+       InfoBarHDMI, Screen):
        
        ALLOW_SUSPEND = True
        instance = None
        
        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, \
                                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..."))]))
                        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,
                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
 
        ENABLE_RESUME_SUPPORT = True
        ALLOW_SUSPEND = True
index a6d25d5..2bf91fd 100755 (executable)
@@ -2329,3 +2329,47 @@ class InfoBarServiceErrorPopupSupport:
                        Notifications.AddPopup(text = error, type = MessageBox.TYPE_ERROR, timeout = 5, id = "ZapError")
                else:
                        Notifications.RemovePopup(id = "ZapError")
                        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
index d423f46..0f7148a 100755 (executable)
@@ -46,6 +46,12 @@ class PluginBrowser(Screen):
                self["SoftwareActions"].setEnabled(False)
                self.onFirstExecBegin.append(self.checkWarnings)
                self.onShown.append(self.updateList)
                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):
        
        def checkWarnings(self):
                if len(plugins.warnings):
@@ -64,7 +70,7 @@ class PluginBrowser(Screen):
                
        def updateList(self):
                self.pluginlist = plugins.getPlugins(PluginDescriptor.WHERE_PLUGINMENU)
                
        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"))
                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):
                self.container.execute("opkg list enigma2-plugin-*")
 
        def startRun(self):
+               listsize = self["list"].instance.size()
                self["list"].instance.hide()
                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
                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:
                        
                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:
                        else:
-                               list.append(PluginCategoryComponent(x, expandableIcon))
+                               list.append(PluginCategoryComponent(x, expandableIcon, self.listWidth))
                self.list = list
                self["list"].l.setList(list)
 
                self.list = list
                self["list"].l.setList(list)
 
index 58f5494..564541b 100644 (file)
@@ -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
 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
 
 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
 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")
                                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")
                                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:
                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"
 
                                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):
                                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
 
                                                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):
                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:
                        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):
                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:
                        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"):
                        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:
                                                link = getLinkedSlotID(x.slot)
 
                                                if link == -1:
@@ -605,7 +589,7 @@ class NimSelection(Screen):
                nim = nim and nim[3]
 
                nimConfig = nimmanager.getNimConfig(nim.slot)
                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():
                        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")
                                                        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<This tuner is configured automatically>")
                                elif x.isCompatible("DVB-T") or x.isCompatible("DVB-C"):
                                        if nimConfig.configMode.value == "nothing":
                                                text += _("\n<This tuner is configured automatically>")
                                elif x.isCompatible("DVB-T") or x.isCompatible("DVB-C"):
                                        if nimConfig.configMode.value == "nothing":
index 6fdeb53..079bdef 100644 (file)
@@ -101,13 +101,16 @@ cable_bands = {
 cable_autoscan_nimtype = {
 'SSH108' : 'ssh108',
 'TT3L10' : 'tt3l10',
 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',
 }
 
 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):
 }
 
 def GetDeviceId(filter, nim_idx):
index da534ec..ffd288f 100644 (file)
@@ -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
 from ServiceReference import ServiceReference
 from enigma import eListboxPythonMultiContent, eListbox, gFont, iServiceInformation, eServiceCenter
 from Tools.Transponder import ConvertToHumanReadable
+import skin
 
 RT_HALIGN_LEFT = 0
 
 
 RT_HALIGN_LEFT = 0
 
@@ -30,11 +31,14 @@ def ServiceInfoListEntry(a, b, valueType=TYPE_TEXT, param=4):
                else:
                        b = str(b)
 
                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;
        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):
        ]
 
 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 = 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
 
 
        GUI_WIDGET = eListbox
 
index 174ffdd..36d8e7c 100755 (executable)
@@ -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
 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)
 
 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"))
 
 def VirtualKeyBoardEntryComponent(keys, selectedKey,shiftMode=False):
        key_backspace = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/vkey_backspace.png"))
index e72d291..da7b9db 100644 (file)
@@ -1,5 +1,8 @@
+import os
+
 class HardwareInfo:
        device_name = None
 class HardwareInfo:
        device_name = None
+       vu_device_name = None
 
        def __init__(self):
                if HardwareInfo.device_name is not None:
 
        def __init__(self):
                if HardwareInfo.device_name is not None:
@@ -30,5 +33,13 @@ class HardwareInfo:
                        except:
                                pass
 
                        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_device_name(self):
                return HardwareInfo.device_name
+
+       def get_vu_device_name(self):
+               return HardwareInfo.vu_device_name
index 158c986..e9a8161 100755 (executable)
@@ -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. */
 /************** temp *****************/
 
        /* need a better place for this, i agree. */
index 2df1dd9..07d69d0 100644 (file)
@@ -18,7 +18,8 @@ libenigma_service_a_SOURCES = \
        servicedvbfcc.cpp \
        servicefs.cpp \
        servicemp3.cpp \
        servicedvbfcc.cpp \
        servicefs.cpp \
        servicemp3.cpp \
-       servicem2ts.cpp
+       servicem2ts.cpp \
+       servicehdmi.cpp
 
 serviceincludedir = $(pkgincludedir)/lib/service
 serviceinclude_HEADERS = \
 
 serviceincludedir = $(pkgincludedir)/lib/service
 serviceinclude_HEADERS = \
@@ -31,7 +32,8 @@ serviceinclude_HEADERS = \
        servicedvbfcc.h \
        servicefs.h \
        servicemp3.h \
        servicedvbfcc.h \
        servicefs.h \
        servicemp3.h \
-       servicem2ts.h
+       servicem2ts.h \
+       servicehdmi.h
 
 if HAVE_LIBXINE
 libenigma_service_a_SOURCES += \
 
 if HAVE_LIBXINE
 libenigma_service_a_SOURCES += \
index 086f595..acc998a 100755 (executable)
@@ -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_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);
 
        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;
 RESULT eDVBServicePlay::setTarget(int target)
 {
        m_is_primary = !target;
+       m_decoder_index = target;
        return 0;
 }
 
        return 0;
 }
 
@@ -2577,7 +2579,7 @@ void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
                h.getDecodeDemux(m_decode_demux);
                if (m_decode_demux)
                {
                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)
                        if (m_decoder)
                                m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
                        if (m_is_primary)
index 7ded16a..eafc96d 100644 (file)
@@ -192,6 +192,7 @@ protected:
        ePtr<eDVBService> m_dvb_service;
        
        ePtr<iTSMPEGDecoder> m_decoder;
        ePtr<eDVBService> m_dvb_service;
        
        ePtr<iTSMPEGDecoder> m_decoder;
+       int m_decoder_index;
        int m_is_primary;
        int m_have_video_pid;
        int m_tune_state;
        int m_is_primary;
        int m_have_video_pid;
        int m_tune_state;
index 972e73e..7cabb03 100644 (file)
@@ -236,7 +236,7 @@ void eDVBServiceFCCPlay::updateFCCDecoder(bool sendSeekableStateChanged)
                h.getDecodeDemux(m_decode_demux);
                if (m_decode_demux)
                {
                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);
                }
                        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 (file)
index 0000000..2767982
--- /dev/null
@@ -0,0 +1,352 @@
+#include <lib/base/ebase.h>
+#include <lib/base/eerror.h>
+#include <lib/base/init_num.h>
+#include <lib/base/init.h>
+#include <lib/base/nconfig.h>
+#include <lib/base/object.h>
+#include <lib/dvb/decoder.h>
+#include <lib/service/servicehdmi.h>
+#include <lib/service/service.h>
+
+#include <string>
+
+#define HDMI_IN_REC_ENCODER_INDEX 0
+#define HDMI_IN_REC_DECODER_INDEX 2
+
+eServiceFactoryHDMI::eServiceFactoryHDMI()
+{
+       ePtr<eServiceCenter> sc;
+
+       eServiceCenter::getPrivInstance(sc);
+       if (sc)
+       {
+               std::list<std::string> extensions;
+               sc->addServiceFactory(eServiceFactoryHDMI::id, this, extensions);
+       }
+
+       m_service_info = new eStaticServiceHDMIInfo();
+}
+
+eServiceFactoryHDMI::~eServiceFactoryHDMI()
+{
+       ePtr<eServiceCenter> sc;
+
+       eServiceCenter::getPrivInstance(sc);
+       if (sc)
+       {
+               sc->removeServiceFactory(eServiceFactoryHDMI::id);
+       }
+}
+
+DEFINE_REF(eServiceFactoryHDMI)
+
+RESULT eServiceFactoryHDMI::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
+{
+       ptr = new eServiceHDMI(ref);
+       return 0;
+}
+
+RESULT eServiceFactoryHDMI::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
+{
+       ePtr<eNavigation> nav_instance;
+       getNavInstance(nav_instance);
+       ptr = new eServiceHDMIRecord(ref, nav_instance);
+       return 0;
+}
+
+RESULT eServiceFactoryHDMI::list(const eServiceReference &, ePtr<iListableService> &ptr)
+{
+       ptr = 0;
+       return -1;
+}
+
+RESULT eServiceFactoryHDMI::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
+{
+       ptr = m_service_info;
+       return 0;
+}
+
+RESULT eServiceFactoryHDMI::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
+{
+       ptr = 0;
+       return -1;
+}
+
+void eServiceFactoryHDMI::getNavInstance(ePtr<eNavigation> &nav_instance)
+{
+       if (!m_nav_instance)
+       {
+               ePtr<iServiceHandler> 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<void,iPlayableService*,int> &event, ePtr<eConnection> &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<iServiceInformation> &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<eNavigation> &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<iStreamableService> &ptr)
+{
+       ptr = NULL;
+       return -1;
+}
+
+RESULT eServiceHDMIRecord::subServices(ePtr<iSubserviceList> &ptr)
+{
+       ptr = NULL;
+       return -1;
+}
+
+RESULT eServiceHDMIRecord::frontendInfo(ePtr<iFrontendInformation> &ptr)
+{
+       ptr = this;
+       return 0;
+}
+
+RESULT eServiceHDMIRecord::connectEvent(const Slot2<void,iRecordableService*,int> &event, ePtr<eConnection> &connection)
+{
+       connection = new eConnection((iRecordableService*)this, m_event.connect(event));
+       return 0;
+}
+
+eAutoInitPtr<eServiceFactoryHDMI> init_eServiceFactoryHDMI(eAutoInitNumbers::service + 1, "eServiceFactoryHDMI");
diff --git a/lib/service/servicehdmi.h b/lib/service/servicehdmi.h
new file mode 100644 (file)
index 0000000..6db9c43
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef __servicehdmi_h
+#define __servicehdmi_h
+
+#include <lib/base/message.h>
+#include <lib/service/iservice.h>
+#include <lib/service/servicedvb.h>
+#include <lib/nav/core.h>
+
+class eStaticServiceHDMIInfo;
+
+class eServiceFactoryHDMI: public iServiceHandler
+{
+       DECLARE_REF(eServiceFactoryHDMI);
+public:
+       eServiceFactoryHDMI();
+       virtual ~eServiceFactoryHDMI();
+       enum { id = 0x2000 };
+
+       RESULT play(const eServiceReference &, ePtr<iPlayableService> &ptr);
+       RESULT record(const eServiceReference &, ePtr<iRecordableService> &ptr);
+       RESULT list(const eServiceReference &, ePtr<iListableService> &ptr);
+       RESULT info(const eServiceReference &, ePtr<iStaticServiceInformation> &ptr);
+       RESULT offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr);
+       void getNavInstance(ePtr<eNavigation> &nav_instance);
+private:
+       ePtr<eStaticServiceHDMIInfo> m_service_info;
+       ePtr<eNavigation> 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<void, iPlayableService*, int> &event, ePtr<eConnection> &connection);
+       RESULT start();
+       RESULT stop();
+       RESULT setTarget(int target);
+
+       RESULT pause(ePtr<iPauseableService> &ptr) { ptr = 0; return -1; }
+       RESULT seek(ePtr<iSeekableService> &ptr) { ptr = 0; return -1; }
+       RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr) { ptr = 0; return -1; }
+       RESULT audioChannel(ePtr<iAudioChannelSelection> &ptr) { ptr = 0; return -1; }
+       RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
+       RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
+
+       RESULT frontendInfo(ePtr<iFrontendInformation> &ptr) { ptr = 0; return -1; }
+       RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
+       RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
+       RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
+
+       RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
+       RESULT keys(ePtr<iServiceKeys> &ptr) { ptr = 0; return -1; }
+       RESULT stream(ePtr<iStreamableService> &ptr) { ptr = 0; return -1; }
+       RESULT streamed(ePtr<iStreamedService> &ptr) { ptr = 0; return -1; }
+
+       RESULT info(ePtr<iServiceInformation>&);
+
+       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<void,iPlayableService*, int> m_event;
+       eServiceReference m_ref;
+       int m_decoder_index;
+       ePtr<iTSMPEGDecoder> m_decoder;
+};
+
+class eServiceHDMIRecord: public eDVBServiceBase, public iRecordableService, public Object
+{
+       DECLARE_REF(eServiceHDMIRecord);
+public:
+       eServiceHDMIRecord(const eServiceReference &ref, ePtr<eNavigation> &nav_instance);
+       RESULT connectEvent(const Slot2<void,iRecordableService*,int> &event, ePtr<eConnection> &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<iFrontendInformation> &ptr);
+       RESULT stream(ePtr<iStreamableService> &ptr);
+       RESULT subServices(ePtr<iSubserviceList> &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<eNavigation> m_nav_instance;
+
+       int doPrepare();
+       int doRecord();
+
+       /* events */
+       Signal2<void,iRecordableService*,int> m_event;
+
+       /* recorder events */
+       void recordEvent(int event);
+};
+
+#endif
diff --git a/skin.py b/skin.py
index a0190f1..f763dd0 100755 (executable)
--- a/skin.py
+++ b/skin.py
@@ -15,6 +15,13 @@ from Tools.LoadPixmap import LoadPixmap
 
 colorNames = dict()
 
 
 colorNames = dict()
 
+fonts = {
+       "Body": ("Regular", 18, 22, 16),
+       "ChoiceList": ("Regular", 20, 24, 18),
+}
+
+parameters = {}
+
 def dump(x, i=0):
        print " " * i + str(x)
        try:
 def dump(x, i=0):
        print " " * i + str(x)
        try:
@@ -70,6 +77,31 @@ profile("LoadSkinDefault")
 loadSkin('skin_default.xml')
 profile("LoadSkinDefaultDone")
 
 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
 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])
 
        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):
        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))
 
                        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
        # 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:
                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
 
 def loadPixmap(path, desktop):
        cached = False
@@ -133,136 +186,164 @@ def loadPixmap(path, desktop):
                raise SkinError("pixmap file %s not found!" % (path))
        return ptr
 
                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])
                                }[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])
                                }[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:
                        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:
                        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):
 
 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."""
 
 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
 
                        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))
        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)
 
                x = eWindowStyleManager.getInstance()
                x.setStyle(id, style)
 
+display_skin_id = 1
+dom_screens = {}
+
 def loadSkinData(desktop):
 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)
 
        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):
 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
 
        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]
 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)
 
 
        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()
 
 
        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).
                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!"
 
                if wname is None and wsource is None:
                        print "widget has no name and no source!"
-                       continue
+                       return
 
                if wname:
                        #print "Widget name=", wname
 
                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
 #                      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
                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 = [ ]
 
                        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)
 
 
                        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:
                        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)