Merge branch 'bug_474_fix_multicontent_clear'
authorghost <andreas.monzner@multimedia-labs.de>
Wed, 6 Oct 2010 09:48:14 +0000 (11:48 +0200)
committerghost <andreas.monzner@multimedia-labs.de>
Wed, 6 Oct 2010 09:48:14 +0000 (11:48 +0200)
219 files changed:
Makefile.am
Navigation.py
RecordTimer.py [changed mode: 0644->0755]
ServiceReference.py
configure.ac
data/defaults/Dream/Makefile.am
data/defaults/Dream/dm500hd.info
data/defaults/Dream/dm7025.info
data/defaults/Dream/dm800.info
data/defaults/Dream/dm8000.info
data/defaults/Dream/hdbouquets/Makefile.am [new file with mode: 0644]
data/defaults/Dream/hdbouquets/userbouquet.favourites.tv [new file with mode: 0644]
data/defaults/Dream/sdbouquets/Makefile.am [new file with mode: 0644]
data/defaults/Dream/sdbouquets/userbouquet.favourites.tv [new file with mode: 0644]
data/defaults/Dream/userbouquet.favourites.tv [deleted file]
data/encoding.conf
data/menu.xml
data/setup.xml [changed mode: 0644->0755]
data/skin.xml
data/skin_default.xml
data/skin_default/icons/Makefile.am [changed mode: 0644->0755]
data/skin_default/icons/input_keyboard-configured.png [new file with mode: 0644]
data/skin_default/icons/input_keyboard.png [new file with mode: 0644]
data/skin_default/icons/input_mouse-configured.png [new file with mode: 0644]
data/skin_default/icons/input_mouse.png [new file with mode: 0644]
data/skin_default/icons/input_rcnew-configured.png [new file with mode: 0644]
data/skin_default/icons/input_rcnew.png [new file with mode: 0644]
data/skin_default/icons/input_rcold-configured.png [new file with mode: 0644]
data/skin_default/icons/input_rcold.png [new file with mode: 0644]
data/skin_default/icons/network_wired-active.png [new file with mode: 0755]
data/skin_default/icons/network_wired-inactive.png [new file with mode: 0755]
data/skin_default/icons/network_wired.png [new file with mode: 0755]
data/skin_default/icons/network_wireless-active.png [new file with mode: 0755]
data/skin_default/icons/network_wireless-inactive.png [new file with mode: 0755]
data/skin_default/icons/network_wireless.png [new file with mode: 0755]
doc/TPM [new file with mode: 0644]
lib/base/Makefile.am
lib/base/console.cpp
lib/base/ebase.cpp
lib/base/ebase.h
lib/base/eptrlist.h
lib/base/estring.cpp
lib/base/etpm.cpp [new file with mode: 0644]
lib/base/etpm.h [new file with mode: 0644]
lib/driver/rcinput.cpp
lib/dvb/decoder.cpp
lib/dvb/dvb.cpp
lib/dvb/dvbtime.cpp
lib/dvb/epgcache.cpp
lib/dvb/frontend.cpp
lib/dvb/frontend.h
lib/dvb/idvb.h
lib/dvb/scan.cpp
lib/dvb/scan.h
lib/dvb/sec.cpp
lib/gdi/accel.cpp
lib/gdi/bcm.cpp
lib/gdi/font.cpp
lib/gdi/font.h
lib/gdi/region.cpp
lib/gui/elistboxcontent.cpp
lib/python/Components/About.py [changed mode: 0644->0755]
lib/python/Components/Converter/ServiceInfo.py
lib/python/Components/Converter/TemplatedMultiContent.py [changed mode: 0644->0755]
lib/python/Components/DreamInfoHandler.py
lib/python/Components/FanControl.py
lib/python/Components/Harddisk.py
lib/python/Components/InputDevice.py [changed mode: 0644->0755]
lib/python/Components/Network.py
lib/python/Components/NimManager.py
lib/python/Components/RecordingConfig.py [changed mode: 0644->0755]
lib/python/Components/Renderer/Listbox.py [changed mode: 0644->0755]
lib/python/Components/Sources/List.py
lib/python/Components/Task.py
lib/python/Components/TimerList.py
lib/python/Components/VolumeControl.py
lib/python/Components/config.py
lib/python/Plugins/DemoPlugins/Makefile.am
lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am [new file with mode: 0644]
lib/python/Plugins/DemoPlugins/TPMDemo/README [new file with mode: 0644]
lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py [new file with mode: 0644]
lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py [new file with mode: 0644]
lib/python/Plugins/Extensions/CutListEditor/meta/Makefile.am
lib/python/Plugins/Extensions/CutListEditor/meta/plugin_cutlisteditor.xml
lib/python/Plugins/Extensions/DVDBurn/DVDProject.py
lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py
lib/python/Plugins/Extensions/DVDBurn/Process.py
lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py
lib/python/Plugins/Extensions/DVDBurn/TitleList.py
lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
lib/python/Plugins/Extensions/DVDBurn/meta/Makefile.am
lib/python/Plugins/Extensions/DVDBurn/meta/plugin_dvdburn.xml
lib/python/Plugins/Extensions/DVDBurn/plugin.py
lib/python/Plugins/Extensions/DVDPlayer/Makefile.am
lib/python/Plugins/Extensions/DVDPlayer/meta/Makefile.am
lib/python/Plugins/Extensions/DVDPlayer/meta/plugin_dvdplayer.xml
lib/python/Plugins/Extensions/DVDPlayer/plugin.py
lib/python/Plugins/Extensions/DVDPlayer/src/Makefile.am
lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.h
lib/python/Plugins/Extensions/GraphMultiEPG/meta/Makefile.am
lib/python/Plugins/Extensions/GraphMultiEPG/meta/plugin_graphmultiepg.xml
lib/python/Plugins/Extensions/MediaPlayer/meta/Makefile.am
lib/python/Plugins/Extensions/MediaPlayer/meta/plugin_mediaplayer.xml
lib/python/Plugins/Extensions/MediaScanner/meta/Makefile.am
lib/python/Plugins/Extensions/MediaScanner/meta/plugin_mediascanner.xml
lib/python/Plugins/Extensions/PicturePlayer/meta/Makefile.am
lib/python/Plugins/Extensions/PicturePlayer/meta/plugin_pictureplayer.xml
lib/python/Plugins/Extensions/SocketMMI/Makefile.am
lib/python/Plugins/Extensions/SocketMMI/meta/Makefile.am
lib/python/Plugins/Extensions/SocketMMI/meta/plugin_socketmmi.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/SocketMMI/src/Makefile.am
lib/python/Plugins/Extensions/TuxboxPlugins/meta/Makefile.am
lib/python/Plugins/Extensions/TuxboxPlugins/meta/plugin_tuxboxplugins.xml [changed mode: 0644->0755]
lib/python/Plugins/Makefile.am
lib/python/Plugins/SystemPlugins/CleanupWizard/meta/Makefile.am
lib/python/Plugins/SystemPlugins/CleanupWizard/meta/plugin_cleanupwizard.xml
lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/meta/Makefile.am
lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/meta/plugin_commoninterfaceassignment.xml
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/meta/Makefile.am
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/meta/plugin_crashlogautosubmit.xml
lib/python/Plugins/SystemPlugins/DefaultServicesScanner/meta/Makefile.am
lib/python/Plugins/SystemPlugins/DefaultServicesScanner/meta/plugin_defaultservicesscanner.xml
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/Makefile.am
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/plugin_diseqctester.xml
lib/python/Plugins/SystemPlugins/FrontprocessorUpgrade/meta/Makefile.am
lib/python/Plugins/SystemPlugins/FrontprocessorUpgrade/meta/plugin_frontprocessorupgrade.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/Hotplug/meta/Makefile.am
lib/python/Plugins/SystemPlugins/Hotplug/meta/plugin_hotplug.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py
lib/python/Plugins/SystemPlugins/NFIFlash/meta/Makefile.am
lib/python/Plugins/SystemPlugins/NFIFlash/meta/plugin_nfiflash.xml
lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml
lib/python/Plugins/SystemPlugins/PositionerSetup/meta/Makefile.am
lib/python/Plugins/SystemPlugins/PositionerSetup/meta/plugin_positionersetup.xml
lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/meta/Makefile.am
lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/meta/plugin_satelliteequipmentcontrol.xml
lib/python/Plugins/SystemPlugins/Satfinder/meta/Makefile.am
lib/python/Plugins/SystemPlugins/Satfinder/meta/plugin_satfinder.xml
lib/python/Plugins/SystemPlugins/SkinSelector/meta/Makefile.am
lib/python/Plugins/SystemPlugins/SkinSelector/meta/plugin_skinselector.xml
lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml
lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
lib/python/Plugins/SystemPlugins/TempFanControl/LICENSE [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/TempFanControl/Makefile.am [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/TempFanControl/meta/Makefile.am [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/TempFanControl/meta/plugin_tempfancontrol.xml [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/TempFanControl/plugin.py [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/Makefile.am
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/plugin_videoenhancement.xml
lib/python/Plugins/SystemPlugins/VideoTune/meta/Makefile.am
lib/python/Plugins/SystemPlugins/VideoTune/meta/plugin_videotune.xml
lib/python/Plugins/SystemPlugins/Videomode/meta/Makefile.am
lib/python/Plugins/SystemPlugins/Videomode/meta/plugin_videomode.xml
lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am
lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py
lib/python/Plugins/SystemPlugins/WirelessLan/flags.py [deleted file]
lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py [deleted file]
lib/python/Plugins/SystemPlugins/WirelessLan/meta/Makefile.am
lib/python/Plugins/SystemPlugins/WirelessLan/meta/plugin_wirelesslan.xml
lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py
lib/python/Screens/ChannelSelection.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/InputDeviceSetup.py [new file with mode: 0755]
lib/python/Screens/Ipkg.py
lib/python/Screens/Makefile.am
lib/python/Screens/NetworkSetup.py
lib/python/Screens/RecordPaths.py
lib/python/Screens/Satconfig.py
lib/python/Screens/ScanSetup.py
lib/python/Screens/ServiceScan.py
lib/python/Screens/TaskView.py
lib/python/Screens/TimerEntry.py
lib/python/Screens/Wizard.py
lib/python/Tools/NumericalTextInput.py
lib/python/enigma_python.i
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.cpp
po/Makefile.am
po/ar.po
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/en.po
po/enigma2.pot
po/es.po
po/et.po
po/fi.po
po/fr.po
po/fy.po
po/hr.po
po/hu.po
po/is.po
po/it.po
po/lt.po
po/lv.po
po/nl.po
po/no.po
po/pl.po
po/pt.po
po/ru.po
po/sk.po
po/sl.po
po/sr.po
po/sv.po
po/tr.po
po/uk.po
tools/create_picon_links.py
tools/genmetaindex.py

index c517d9c..bc1770b 100755 (executable)
@@ -7,12 +7,8 @@ install_PYTHON = \
        keyids.py keymapparser.py mytest.py skin.py timer.py tools.py GlobalActions.py \
        e2reactor.py
 
-LANGS := $(shell cat $(srcdir)/po/LINGUAS)
-
 install-exec-hook:
-       for lang in $(LANGS); do \
-               $(PYTHON) $(srcdir)/tools/genmetaindex.py $$lang $(DESTDIR)$(datadir)/meta/plugin_*.xml > $(DESTDIR)$(datadir)/meta/index-enigma2_$$lang.xml; \
-       done
+               $(PYTHON) $(srcdir)/tools/genmetaindex.py $(DESTDIR)$(datadir)/meta/plugin_*.xml > $(DESTDIR)$(datadir)/meta/index-enigma2.xml
 
 uninstall-hook:
-       $(RM) $(DESTDIR)$(datadir)/meta/index-enigma2_*.xml
+       $(RM) $(DESTDIR)$(datadir)/meta/index-enigma2.xml
index 2437bbf..a905da1 100644 (file)
@@ -53,7 +53,7 @@ class Navigation:
        def playService(self, ref, checkParentalControl = True, forceRestart = False):
                oldref = self.currentlyPlayingServiceReference
                if ref and oldref and ref == oldref and not forceRestart:
-                       print "ignore request to play already running service"
+                       print "ignore request to play already running service(1)"
                        return 0
                print "playing", ref and ref.toString()
                if ref is None:
@@ -64,6 +64,10 @@ class Navigation:
                                if not oldref:
                                        oldref = eServiceReference()
                                playref = getBestPlayableServiceReference(ref, oldref)
+                               print "playref", playref
+                               if playref and oldref and playref == oldref and not forceRestart:
+                                       print "ignore request to play already running service(2)"
+                                       return 0
                                if not playref or (checkParentalControl and not parentalControl.isServicePlayable(playref, boundFunction(self.playService, checkParentalControl = False))):
                                        self.stopService()
                                        return 0
old mode 100644 (file)
new mode 100755 (executable)
index f670417..4ece9c5
@@ -102,7 +102,10 @@ class RecordTimerEntry(timer.TimerEntry, object):
                
                assert isinstance(serviceref, ServiceReference)
                
-               self.service_ref = serviceref
+               if serviceref.isRecordable():
+                       self.service_ref = serviceref
+               else:
+                       self.service_ref = ServiceReference(None)
                self.eit = eit
                self.dontSave = False
                self.name = name
@@ -129,6 +132,7 @@ class RecordTimerEntry(timer.TimerEntry, object):
        def calculateFilename(self):
                service_name = self.service_ref.getServiceName()
                begin_date = strftime("%Y%m%d %H%M", localtime(self.begin))
+               begin_shortdate = strftime("%Y%m%d", localtime(self.begin))
                
                print "begin_date: ", begin_date
                print "service_name: ", service_name
@@ -137,7 +141,15 @@ class RecordTimerEntry(timer.TimerEntry, object):
                
                filename = begin_date + " - " + service_name
                if self.name:
-                       filename += " - " + self.name
+                       if config.usage.setup_level.index >= 2: # expert+
+                               if config.recording.filename_composition.value == "short":
+                                       filename = begin_shortdate + " - " + self.name
+                               elif config.recording.filename_composition.value == "long":
+                                       filename += " - " + self.name + " - " + self.description
+                               else:
+                                       filename += " - " + self.name # standard
+                       else:
+                               filename += " - " + self.name
 
                if config.recording.ascii_filenames.value:
                        filename = ASCIItranslit.legacyEncode(filename)
index 11e2878..4907fa2 100644 (file)
@@ -10,7 +10,7 @@ class ServiceReference(eServiceReference):
 
        def __str__(self):
                return self.ref.toString()
-       
+
        def getServiceName(self):
                info = self.info()
                return info and info.getName(self.ref) or ""
@@ -20,3 +20,16 @@ class ServiceReference(eServiceReference):
 
        def list(self):
                return self.serviceHandler.list(self.ref)
+
+       def getType(self):
+               return self.ref.type
+
+       def getPath(self):
+               return self.ref.getPath()
+
+       def getFlags(self):
+               return self.ref.flags
+
+       def isRecordable(self):
+               ref = self.ref
+               return ref.flags & eServiceReference.isGroup or (ref.type == eServiceReference.idDVB and ref.getPath() == "")
\ No newline at end of file
index aa2fa3e..35fad77 100755 (executable)
@@ -90,6 +90,8 @@ data/fonts/Makefile
 data/countries/Makefile
 data/defaults/Makefile
 data/defaults/Dream/Makefile
+data/defaults/Dream/hdbouquets/Makefile
+data/defaults/Dream/sdbouquets/Makefile
 data/extensions/Makefile
 data/skin_default/Makefile
 data/skin_default/menu/Makefile
@@ -116,6 +118,7 @@ lib/python/Components/Sources/Makefile
 lib/python/Screens/Makefile
 lib/python/Plugins/Makefile
 lib/python/Plugins/DemoPlugins/Makefile
+lib/python/Plugins/DemoPlugins/TPMDemo/Makefile
 lib/python/Plugins/DemoPlugins/TestPlugin/Makefile
 lib/python/Plugins/Extensions/CutListEditor/Makefile
 lib/python/Plugins/Extensions/CutListEditor/meta/Makefile
@@ -156,6 +159,7 @@ lib/python/Plugins/SystemPlugins/Hotplug/Makefile
 lib/python/Plugins/SystemPlugins/Hotplug/meta/Makefile
 lib/python/Plugins/SystemPlugins/Makefile
 lib/python/Plugins/SystemPlugins/TempFanControl/Makefile
+lib/python/Plugins/SystemPlugins/TempFanControl/meta/Makefile
 lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile
 lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile
 lib/python/Plugins/SystemPlugins/NFIFlash/Makefile
index 113442c..31ba1c6 100644 (file)
@@ -1,3 +1,5 @@
+SUBDIRS = hdbouquets sdbouquets
+
 installdir = $(pkgdatadir)/defaults/Dream
 
 dist_install_DATA = \
@@ -9,5 +11,4 @@ dist_install_DATA = \
        settings.500hd \
        settings.7025 \
        settings.800 \
-       settings.8000 \
-       userbouquet.favourites.tv
+       settings.8000
index fbf7888..b1b4d53 100644 (file)
@@ -20,7 +20,7 @@
                        </prerequisites>
                </file-->
                <file type="favourites" directory="" name="bouquets.tv" />              
-               <file type="favourites" directory="" name="userbouquet.favourites.tv" />
+               <file type="favourites" directory="hdbouquets/" name="userbouquet.favourites.tv" />
                <!--file type="package" directory="packages/" name="small-test_1.0_mipsel.ipk" /-->
        </files>
 </default>
index 0461b68..a1585cf 100644 (file)
@@ -20,7 +20,7 @@
                        </prerequisites>
                </file-->
                <file type="favourites" directory="" name="bouquets.tv" />              
-               <file type="favourites" directory="" name="userbouquet.favourites.tv" />
+               <file type="favourites" directory="sdbouquets/" name="userbouquet.favourites.tv" />
                <!--file type="package" directory="packages/" name="small-test_1.0_mipsel.ipk" /-->
        </files>
 </default>
index 8c68349..4793bd8 100644 (file)
@@ -20,7 +20,7 @@
                        </prerequisites>
                </file-->
                <file type="favourites" directory="" name="bouquets.tv" />              
-               <file type="favourites" directory="" name="userbouquet.favourites.tv" />
+               <file type="favourites" directory="hdbouquets/" name="userbouquet.favourites.tv" />
                <!--file type="package" directory="packages/" name="small-test_1.0_mipsel.ipk" /-->
        </files>
 </default>
index 8b11946..2ef2013 100644 (file)
@@ -20,7 +20,7 @@
                        </prerequisites>
                </file-->
                <file type="favourites" directory="" name="bouquets.tv" />              
-               <file type="favourites" directory="" name="userbouquet.favourites.tv" />
+               <file type="favourites" directory="hdbouquets/" name="userbouquet.favourites.tv" />
                <!--file type="package" directory="packages/" name="small-test_1.0_mipsel.ipk" /-->
        </files>
 </default>
diff --git a/data/defaults/Dream/hdbouquets/Makefile.am b/data/defaults/Dream/hdbouquets/Makefile.am
new file mode 100644 (file)
index 0000000..843a07d
--- /dev/null
@@ -0,0 +1,4 @@
+installdir = $(pkgdatadir)/defaults/Dream/hdbouquets
+
+dist_install_DATA = \
+       userbouquet.favourites.tv
diff --git a/data/defaults/Dream/hdbouquets/userbouquet.favourites.tv b/data/defaults/Dream/hdbouquets/userbouquet.favourites.tv
new file mode 100644 (file)
index 0000000..b6bc62f
--- /dev/null
@@ -0,0 +1,130 @@
+#NAME Favourites (TV)\r
+#SERVICE 1:0:19:2B5C:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B66:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DCC:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2EE3:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445C:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2EF4:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445D:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445E:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:33:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:701:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F1C:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D6E:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:308:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:2FC:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:F98:454:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B70:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D67:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7031:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7032:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7033:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E46:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DCE:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DD1:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DCF:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E42:431:1:C00000:0:0:0:\r
+#SERVICE 1:64:B:0:0:0:0:0:0:0::Doku/Wissen/Themen\r
+#DESCRIPTION Doku/Wissen/Themen\r
+#SERVICE 1:0:1:6F47:445:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D6B:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2775:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:293:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D70:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:49:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:332D:45B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3139:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F5A:454:1:C00000:0:0:0:\r
+#SERVICE 1:64:A:0:0:0:0:0:0:0::Sport\r
+#DESCRIPTION Sport\r
+#SERVICE 1:0:1:384:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:79E0:443:1:C00000:0:0:0:\r
+#SERVICE 1:64:1:0:0:0:0:0:0:0::Kinder\r
+#DESCRIPTION Kinder\r
+#SERVICE 1:0:1:2F08:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D68:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7008:436:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6FE0:443:1:C00000:0:0:0:\r
+#SERVICE 1:64:2:0:0:0:0:0:0:0::Nachrichten\r
+#DESCRIPTION Nachrichten\r
+#SERVICE 1:0:1:2F3A:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445F:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:79F4:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2753:402:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7035:41B:1:C00000:0:0:0:\r
+#SERVICE 1:64:3:0:0:0:0:0:0:0::Regional\r
+#DESCRIPTION Regional\r
+#SERVICE 1:0:1:3146:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:300:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:2778:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:277A:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2779:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2777:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:32D6:45D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:277D:444:1:C00000:0:0:0:\r
+#SERVICE 1:64:4:0:0:0:0:0:0:0::Musik\r
+#DESCRIPTION Musik\r
+#SERVICE 1:0:1:2774:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7004:436:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7001:436:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6FE1:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2FD:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:32D5:45D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:332E:45B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:304:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:702:5:85:C00000:0:0:0:\r
+#SERVICE 1:64:5:0:0:0:0:0:0:0::Reisen\r
+#DESCRIPTION Reisen\r
+#SERVICE 1:0:1:20:21:85:C00000:0:0:0:\r
+#SERVICE 1:64:9:0:0:0:0:0:0:0::Beratung\r
+#DESCRIPTION Beratung\r
+#SERVICE 1:0:1:295:21:85:C00000:0:0:0:\r
+#SERVICE 1:64:6:0:0:0:0:0:0:0::Einkaufen\r
+#DESCRIPTION Einkaufen\r
+#SERVICE 1:0:1:301:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:28:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:79EA:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F44:454:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3148:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:36:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:307:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:296:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:383:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:313C:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3159:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2E:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:381:21:85:C00000:0:0:0:\r
+#SERVICE 1:64:7:0:0:0:0:0:0:0::High Definition\r
+#DESCRIPTION High Definition\r
+#SERVICE 1:0:19:6EEC:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:EF12:421:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:EF13:421:1:C00000:0:0:0:\r
+#SERVICE 1:64:0:0:0:0:0:0:0:0::Alternativen\r
+#DESCRIPTION Alternativen\r
+#SERVICE 1:0:1:6DCB:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E44:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E45:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E41:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E40:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E43:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6EE1:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E2D:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E2E:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F46:445:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E47:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F76:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E92:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E93:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F78:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F79:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E94:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F77:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6EEB:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E97:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E96:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E95:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:64:8:0:0:0:0:0:0:0::Alternative SD services\r
+#DESCRIPTION Alternative SD services\r
+#SERVICE 1:0:1:6DCA:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D66:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7034:41B:1:C00000:0:0:0:\r
diff --git a/data/defaults/Dream/sdbouquets/Makefile.am b/data/defaults/Dream/sdbouquets/Makefile.am
new file mode 100644 (file)
index 0000000..50328e5
--- /dev/null
@@ -0,0 +1,4 @@
+installdir = $(pkgdatadir)/defaults/Dream/sdbouquets
+
+dist_install_DATA = \
+       userbouquet.favourites.tv
diff --git a/data/defaults/Dream/sdbouquets/userbouquet.favourites.tv b/data/defaults/Dream/sdbouquets/userbouquet.favourites.tv
new file mode 100644 (file)
index 0000000..1cea366
--- /dev/null
@@ -0,0 +1,128 @@
+#NAME Favourites (TV)\r
+#SERVICE 1:0:1:6DCA:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D66:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DCC:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2EE3:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445C:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2EF4:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445D:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445E:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:33:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:701:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F1C:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D6E:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:308:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:2FC:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:F98:454:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7034:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D67:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7031:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7032:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7033:41B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E46:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DCE:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DD1:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6DCF:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E42:431:1:C00000:0:0:0:\r
+#SERVICE 1:64:B:0:0:0:0:0:0:0::Doku/Wissen/Themen\r
+#DESCRIPTION Doku/Wissen/Themen\r
+#SERVICE 1:0:1:6F47:445:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D6B:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2775:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:293:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D70:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:49:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:332D:45B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3139:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F5A:454:1:C00000:0:0:0:\r
+#SERVICE 1:64:A:0:0:0:0:0:0:0::Sport\r
+#DESCRIPTION Sport\r
+#SERVICE 1:0:1:384:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:79E0:443:1:C00000:0:0:0:\r
+#SERVICE 1:64:1:0:0:0:0:0:0:0::Kinder\r
+#DESCRIPTION Kinder\r
+#SERVICE 1:0:1:2F08:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6D68:437:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7008:436:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6FE0:443:1:C00000:0:0:0:\r
+#SERVICE 1:64:2:0:0:0:0:0:0:0::Nachrichten\r
+#DESCRIPTION Nachrichten\r
+#SERVICE 1:0:1:2F3A:441:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:445F:453:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:79F4:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2753:402:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7035:41B:1:C00000:0:0:0:\r
+#SERVICE 1:64:3:0:0:0:0:0:0:0::Regional\r
+#DESCRIPTION Regional\r
+#SERVICE 1:0:1:3146:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:300:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:2778:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:277A:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2779:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2777:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:32D6:45D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:277D:444:1:C00000:0:0:0:\r
+#SERVICE 1:64:4:0:0:0:0:0:0:0::Musik\r
+#DESCRIPTION Musik\r
+#SERVICE 1:0:1:2774:444:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7004:436:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:7001:436:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6FE1:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2FD:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:32D5:45D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:332E:45B:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:304:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:702:5:85:C00000:0:0:0:\r
+#SERVICE 1:64:5:0:0:0:0:0:0:0::Reisen\r
+#DESCRIPTION Reisen\r
+#SERVICE 1:0:1:20:21:85:C00000:0:0:0:\r
+#SERVICE 1:64:9:0:0:0:0:0:0:0::Beratung\r
+#DESCRIPTION Beratung\r
+#SERVICE 1:0:1:295:21:85:C00000:0:0:0:\r
+#SERVICE 1:64:6:0:0:0:0:0:0:0::Einkaufen\r
+#DESCRIPTION Einkaufen\r
+#SERVICE 1:0:1:301:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:28:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:79EA:443:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2F44:454:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3148:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:36:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:307:7:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:296:5:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:383:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:313C:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:3159:459:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:2E:21:85:C00000:0:0:0:\r
+#SERVICE 1:0:1:381:21:85:C00000:0:0:0:\r
+#SERVICE 1:64:7:0:0:0:0:0:0:0::High Definition\r
+#DESCRIPTION High Definition\r
+#SERVICE 1:0:19:2B5C:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B66:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:2B70:3F3:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:6EEC:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:EF12:421:1:C00000:0:0:0:\r
+#SERVICE 1:0:19:EF13:421:1:C00000:0:0:0:\r
+#SERVICE 1:64:0:0:0:0:0:0:0:0::Alternativen\r
+#DESCRIPTION Alternativen\r
+#SERVICE 1:0:1:6DCB:44D:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E44:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E45:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E41:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E40:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E43:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6EE1:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E2D:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E2E:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F46:445:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E47:431:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F76:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E92:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E93:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F78:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F79:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E94:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6F77:457:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6EEB:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E97:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E96:4B1:1:C00000:0:0:0:\r
+#SERVICE 1:0:1:6E95:4B1:1:C00000:0:0:0:\r
diff --git a/data/defaults/Dream/userbouquet.favourites.tv b/data/defaults/Dream/userbouquet.favourites.tv
deleted file mode 100644 (file)
index 5f89c48..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#NAME Favourites (TV)\r
-#SERVICE 1:0:1:6DCA:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6D66:437:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6DCC:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2EE3:441:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:445C:453:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2EF4:441:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:445D:453:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:445E:453:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:33:21:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:701:5:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:2F1C:441:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6D6E:437:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2FC:5:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:F98:454:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7034:41B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6D67:437:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7031:41B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7032:41B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7033:41B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E46:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6DCE:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6DD1:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6DCF:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E42:431:1:C00000:0:0:0:\r
-#SERVICE 1:64:B:0:0:0:0:0:0:0::Doku/Wissen/Themen\r
-#DESCRIPTION Doku/Wissen/Themen\r
-#SERVICE 1:0:1:6DD0:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6D6B:437:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2775:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:293:5:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:6D70:437:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:277B:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:332D:45B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:3139:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2F5A:454:1:C00000:0:0:0:\r
-#SERVICE 1:64:A:0:0:0:0:0:0:0::Sport\r
-#DESCRIPTION Sport\r
-#SERVICE 1:0:1:384:21:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:79E0:443:1:C00000:0:0:0:\r
-#SERVICE 1:64:1:0:0:0:0:0:0:0::Kinder\r
-#DESCRIPTION Kinder\r
-#SERVICE 1:0:1:2F08:441:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6D68:437:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7008:436:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6FE0:443:1:C00000:0:0:0:\r
-#SERVICE 1:64:2:0:0:0:0:0:0:0::Nachrichten\r
-#DESCRIPTION Nachrichten\r
-#SERVICE 1:0:1:2F3A:441:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:445F:453:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:79F4:443:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2753:402:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7035:41B:1:C00000:0:0:0:\r
-#SERVICE 1:64:3:0:0:0:0:0:0:0::Regional\r
-#DESCRIPTION Regional\r
-#SERVICE 1:0:1:3146:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:300:7:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:2778:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:277A:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2779:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2777:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:32D6:45D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:277D:444:1:C00000:0:0:0:\r
-#SERVICE 1:64:4:0:0:0:0:0:0:0::Musik\r
-#DESCRIPTION Musik\r
-#SERVICE 1:0:1:2774:444:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7004:436:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:7001:436:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6FE1:443:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2FD:7:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:32D5:45D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:332E:45B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:304:5:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:702:5:85:C00000:0:0:0:\r
-#SERVICE 1:64:5:0:0:0:0:0:0:0::Reisen\r
-#DESCRIPTION Reisen\r
-#SERVICE 1:0:1:20:21:85:C00000:0:0:0:\r
-#SERVICE 1:64:9:0:0:0:0:0:0:0::Beratung\r
-#DESCRIPTION Beratung\r
-#SERVICE 1:0:1:295:21:85:C00000:0:0:0:\r
-#SERVICE 1:64:6:0:0:0:0:0:0:0::Einkaufen\r
-#DESCRIPTION Einkaufen\r
-#SERVICE 1:0:1:301:7:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:28:21:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:79EA:443:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2F44:454:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:3148:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:36:7:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:307:7:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:296:5:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:383:21:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:313C:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:3159:459:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:2E:21:85:C00000:0:0:0:\r
-#SERVICE 1:0:1:381:21:85:C00000:0:0:0:\r
-#SERVICE 1:64:7:0:0:0:0:0:0:0::High Definition\r
-#DESCRIPTION High Definition\r
-#SERVICE 1:0:19:2B5C:3F3:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:2B66:3F3:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:2B70:3F3:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:6EEC:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:EF12:421:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:EF13:421:1:C00000:0:0:0:\r
-#SERVICE 1:64:0:0:0:0:0:0:0:0::Alternativen\r
-#DESCRIPTION Alternativen\r
-#SERVICE 1:0:1:6DCB:44D:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E44:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E45:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E41:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E40:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E43:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6EE1:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E2D:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E2E:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6F46:445:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E47:431:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6F76:457:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E92:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E93:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6F78:457:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6F79:457:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E94:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6F77:457:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6EEB:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E97:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E96:4B1:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:6E95:4B1:1:C00000:0:0:0:\r
index 3f09b56..a3cefe6 100644 (file)
@@ -6,6 +6,10 @@ gre ISO8859-7
 pol ISO8859-2
 rus ISO8859-5
 bul ISO8859-5
+cze ISO6397
+ces ISO6397
+slo ISO6397
+slk ISO6397
 #Sorry for that.. in DVB Spec this is the default behavior 
 #when no other encoding is given in dvb-texts..
 #but this breaks too much providers yet.. 
index fbc5295..6507bfe 100755 (executable)
@@ -62,8 +62,9 @@
                                </menu>
                                <!--<item text="Remote Control"><setup id="rc" /></item>-->
                                <!--<item text="OSD"><setup id="osd" /></item>-->
-                               <item requires="Display"><setup level="1" id="lcd" /></item>
                                <item level="0" text="Network" entryID="network_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection" /></item>
+                               <item level="1" text="Input devices" entryID="input_device_setup"><screen module="InputDeviceSetup" screen="InputDeviceSelection" /></item>
+                               <item requires="Display"><setup level="1" id="lcd" /></item>
                                <item text="Keyboard"><setup id="keyboard" /></item>
                                <!--<menu level="1" text="Network..." entryID="network_setup">
                                        <id val="network" />
                        <item weight="10" level="1" text="Common Interface" entryID="ci_setup" requires="CommonInterface"><screen module="Ci" screen="CiSelection" /></item>
                        <item weight="15" level="0" text="Parental control" entryID="parental_setup"><screen module="ParentalControlSetup" screen="ParentalControlSetup" /></item>
                        <!--item level="0" text="Startwizard" entryID="startwizzard"><screen module="StartWizard" screen="StartWizard" /></item-->
-                       <item weight="20" level="0" text="Default settings" entryID="default_wizard">
-                               <code>
-from Screens.DefaultWizard import DefaultWizard
-self.session.open(DefaultWizard, silent = False)
-</code>
-                       </item>
                        <item weight="25" level="0" text="Factory reset" entryID="factory_reset">
                                <code>
 from Screens.FactoryReset import FactoryReset
old mode 100644 (file)
new mode 100755 (executable)
index 9425afd..2333825
@@ -70,6 +70,7 @@
                        <item level="2" text="Behavior of 0 key in PiP-mode">config.usage.pip_zero_button</item>
                        <item level="2" text="Alternative services tuner priority">config.usage.alternatives_priority</item>
                        <item level="2" text="Limited character set for recording filenames">config.recording.ascii_filenames</item>
+                       <item level="2" text="Composition of the recording filenames">config.recording.filename_composition</item>
                </setup>
                <setup key="harddisk" title="Harddisk setup" >
                        <item level="0" text="Harddisk standby after">config.usage.hdd_standby</item>
index d5fe01e..32adb2b 100755 (executable)
                </widget>
                <!-- Remaining time -->
                <widget source="session.CurrentService" render="Label" position="576,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
-                       <convert type="ServicePosition">Remaining</convert>
+                       <convert type="ServicePosition">Remaining,Negate</convert>
                </widget>
        </screen>
 </skin>
index 56d53dc..497d33a 100755 (executable)
@@ -577,7 +577,19 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y()))
                <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
                <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
                <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
-               <widget name="list" position="5,50" size="550,280" scrollbarMode="showOnDemand" zPosition="10"/>
+               <widget source="list" render="Listbox" position="5,50" size="550,280" zPosition="10" scrollbarMode="showOnDemand">
+                       <convert type="TemplatedMultiContent"> <!--  iface, name, description, interfacepng, defaultpng, activepng, divpng  -->
+                               {"template": [
+                                               MultiContentEntryText(pos = (85, 6), size = (440, 28), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_TOP, text = 1), # index 1 is the interfacename
+                                               MultiContentEntryText(pos = (85, 43), size = (440, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_BOTTOM, text = 2), # index 2 is the description
+                                               MultiContentEntryPixmapAlphaTest(pos = (2, 8), size = (54, 54), png = 3), # index 3 is the interface pixmap
+                                               MultiContentEntryPixmapAlphaTest(pos = (63, 46), size = (15, 16), png = 4), # index 4 is the default pixmap
+                                       ],
+                               "fonts": [gFont("Regular", 28),gFont("Regular", 20)],
+                               "itemHeight": 70
+                               }
+                       </convert>
+               </widget>
                <ePixmap pixmap="skin_default/div-h.png" position="0,340" zPosition="1" size="560,2" />
                <widget source="introduction" render="Label" position="0,350" size="560,50" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
        </screen>
@@ -626,14 +638,14 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y()))
        </screen>
        <!-- Nim selection -->
        <screen name="NimSelection" position="center,center" size="400,330" title="Choose Tuner">
-               <widget source="nimlist" render="Listbox" position="0,0" size="380,300" scrollbarMode="showOnDemand">
+               <widget source="nimlist" render="Listbox" position="0,0" size="380,360" scrollbarMode="showOnDemand">
                        <convert type="TemplatedMultiContent">
                                {"template": [
                                                MultiContentEntryText(pos = (10, 5), size = (360, 30), flags = RT_HALIGN_LEFT, text = 1), # index 1 is the nim name,
-                                               MultiContentEntryText(pos = (50, 30), size = (320, 30), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
+                                               MultiContentEntryText(pos = (50, 30), size = (320, 50), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is a description of the nim settings,
                                        ],
                                 "fonts": [gFont("Regular", 20), gFont("Regular", 15)],
-                                "itemHeight": 70
+                                "itemHeight": 80
                                }
                        </convert>
                </widget>
old mode 100644 (file)
new mode 100755 (executable)
index 8e2052b..c6cb269
@@ -27,13 +27,27 @@ dist_install_DATA = \
        icon_view.png \
        input_error.png \
        input_info.png \
+       input_keyboard-configured.png \
+       input_keyboard.png \
+       input_mouse-configured.png \
+       input_mouse.png \
        input_question.png \
+       input_rcnew-configured.png \
+       input_rcnew.png \
+       input_rcold-configured.png \
+       input_rcold.png \
        lock_error.png \
        lock_off.png \
        lock_on.png \
        lock.png \
        marker.png \
        mp_buttons.png \
+       network_wired.png \
+       network_wired-active.png \
+       network_wired-inactive.png \    
+       network_wireless.png \
+       network_wireless-active.png \
+       network_wireless-inactive.png \ 
        plugin.png \
        rass_logo.png \
        rass_page1.png \
@@ -48,3 +62,4 @@ dist_install_DATA = \
        scan-s.png \
        scan-t.png \
        selectioncross.png
+
diff --git a/data/skin_default/icons/input_keyboard-configured.png b/data/skin_default/icons/input_keyboard-configured.png
new file mode 100644 (file)
index 0000000..c6623a5
Binary files /dev/null and b/data/skin_default/icons/input_keyboard-configured.png differ
diff --git a/data/skin_default/icons/input_keyboard.png b/data/skin_default/icons/input_keyboard.png
new file mode 100644 (file)
index 0000000..a922c89
Binary files /dev/null and b/data/skin_default/icons/input_keyboard.png differ
diff --git a/data/skin_default/icons/input_mouse-configured.png b/data/skin_default/icons/input_mouse-configured.png
new file mode 100644 (file)
index 0000000..3db9447
Binary files /dev/null and b/data/skin_default/icons/input_mouse-configured.png differ
diff --git a/data/skin_default/icons/input_mouse.png b/data/skin_default/icons/input_mouse.png
new file mode 100644 (file)
index 0000000..f70c84e
Binary files /dev/null and b/data/skin_default/icons/input_mouse.png differ
diff --git a/data/skin_default/icons/input_rcnew-configured.png b/data/skin_default/icons/input_rcnew-configured.png
new file mode 100644 (file)
index 0000000..6b16d39
Binary files /dev/null and b/data/skin_default/icons/input_rcnew-configured.png differ
diff --git a/data/skin_default/icons/input_rcnew.png b/data/skin_default/icons/input_rcnew.png
new file mode 100644 (file)
index 0000000..19cdeea
Binary files /dev/null and b/data/skin_default/icons/input_rcnew.png differ
diff --git a/data/skin_default/icons/input_rcold-configured.png b/data/skin_default/icons/input_rcold-configured.png
new file mode 100644 (file)
index 0000000..8d62685
Binary files /dev/null and b/data/skin_default/icons/input_rcold-configured.png differ
diff --git a/data/skin_default/icons/input_rcold.png b/data/skin_default/icons/input_rcold.png
new file mode 100644 (file)
index 0000000..ef8680b
Binary files /dev/null and b/data/skin_default/icons/input_rcold.png differ
diff --git a/data/skin_default/icons/network_wired-active.png b/data/skin_default/icons/network_wired-active.png
new file mode 100755 (executable)
index 0000000..d8efc9c
Binary files /dev/null and b/data/skin_default/icons/network_wired-active.png differ
diff --git a/data/skin_default/icons/network_wired-inactive.png b/data/skin_default/icons/network_wired-inactive.png
new file mode 100755 (executable)
index 0000000..18f2c70
Binary files /dev/null and b/data/skin_default/icons/network_wired-inactive.png differ
diff --git a/data/skin_default/icons/network_wired.png b/data/skin_default/icons/network_wired.png
new file mode 100755 (executable)
index 0000000..db695ad
Binary files /dev/null and b/data/skin_default/icons/network_wired.png differ
diff --git a/data/skin_default/icons/network_wireless-active.png b/data/skin_default/icons/network_wireless-active.png
new file mode 100755 (executable)
index 0000000..07a2187
Binary files /dev/null and b/data/skin_default/icons/network_wireless-active.png differ
diff --git a/data/skin_default/icons/network_wireless-inactive.png b/data/skin_default/icons/network_wireless-inactive.png
new file mode 100755 (executable)
index 0000000..5bd69f9
Binary files /dev/null and b/data/skin_default/icons/network_wireless-inactive.png differ
diff --git a/data/skin_default/icons/network_wireless.png b/data/skin_default/icons/network_wireless.png
new file mode 100755 (executable)
index 0000000..629a05a
Binary files /dev/null and b/data/skin_default/icons/network_wireless.png differ
diff --git a/doc/TPM b/doc/TPM
new file mode 100644 (file)
index 0000000..20c0230
--- /dev/null
+++ b/doc/TPM
@@ -0,0 +1,27 @@
+The TPM check is currently to be considered a beta version. So please expect
+code changes in the future.
+
+If you'd like to write your own plugins and honor the efforts, Dream Multimedia
+puts into developing Enigma 2, you can protect your plugin against execution
+on Non-Dream Multimedia Hardware by implementing a TPM (Trusted Platform Module)
+check into your plugin.
+For ease of use we provide a demo plugin in lib/python/Plugins/DemoPlugins/TPMDemo.
+
+The main TPM check is implemented into the "main" function. You need to provide
+this code yourself in your plugin. So copy&paste the code into your own as well
+as the needed functions
+- bin2long
+- long2bin
+- rsa_pub1024
+- decrypt_block
+- validate_cert
+- read_random
+Importing the functions from somewhere else would spoil the security model. So
+you need to provide the code with your plugin.
+You can either use the given method using the main function (which will run the
+TPM check each time the plugin is called) or directly use it in the
+Plugins(**kwargs) function and not return the Plugins-list if the TPM check failes
+(which will prevent the plugin from showing up at all). You can also implement
+a warning message for all possible TPM failure scenarios.
+  
index 6ea9d03..0508563 100644 (file)
@@ -8,5 +8,5 @@ libenigma_base_a_SOURCES = \
        init.cpp message.cpp thread.cpp \
        smartptr.cpp estring.cpp connection.cpp \
        filepush.cpp encoding.cpp console.cpp rawfile.cpp \
-       nconfig.cpp ioprio.cpp
+       nconfig.cpp ioprio.cpp etpm.cpp
 
index add8706..43f9f61 100644 (file)
@@ -516,18 +516,15 @@ eConsolePy_write(eConsolePy* self, PyObject *args)
 {
        int len;
        char *data;
-       if (PyArg_ParseTuple(args, "si", &data, &len))
-               ;
-       else
+       int ret = -1;
+       Py_ssize_t argc = PyTuple_Size(args);
+       if (argc > 1)
+               ret = PyArg_ParseTuple(args, "si", &data, &len);
+       else if (argc == 1)
        {
                PyObject *ob;
-               if (!PyArg_ParseTuple(args, "O", &ob) || !PyString_Check(ob))
-               {
-                       PyErr_SetString(PyExc_TypeError,
-                               "1st arg must be a string, optionaly 2nd arg can be the string length");
-                       return NULL;
-               }
-               else
+               ret = !PyArg_ParseTuple(args, "O", &ob) || !PyString_Check(ob);
+               if (!ret)
                {
                        Py_ssize_t length;
                        if (!PyString_AsStringAndSize(ob, &data, &length))
@@ -536,6 +533,12 @@ eConsolePy_write(eConsolePy* self, PyObject *args)
                                len = 0;
                }
        }
+       if (ret)
+       {
+               PyErr_SetString(PyExc_TypeError,
+                       "1st arg must be a string, optionaly 2nd arg can be the string length");
+               return NULL;
+       }
        self->cont->write(data, len);
        Py_RETURN_NONE;
 }
index 5bafe73..700cce3 100644 (file)
@@ -26,8 +26,11 @@ void eSocketNotifier::start()
        if (state)
                stop();
 
-       context.addSocketNotifier(this);
-       state=2;  // running but not in poll yet
+       if (eMainloop::isValid(&context))
+       {
+               context.addSocketNotifier(this);
+               state=2;  // running but not in poll yet
+       }
 }
 
 void eSocketNotifier::stop()
@@ -46,29 +49,35 @@ void eTimer::start(long msek, bool singleShot)
        if (bActive)
                stop();
 
-       bActive = true;
-       bSingleShot = singleShot;
-       interval = msek;
-       clock_gettime(CLOCK_MONOTONIC, &nextActivation);
-//     eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_nsec, msek);
-       nextActivation += (msek<0 ? 0 : msek);
-//     eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
-       context.addTimer(this);
+       if (eMainloop::isValid(&context))
+       {
+               bActive = true;
+               bSingleShot = singleShot;
+               interval = msek;
+               clock_gettime(CLOCK_MONOTONIC, &nextActivation);
+//             eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_nsec, msek);
+               nextActivation += (msek<0 ? 0 : msek);
+//             eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
+               context.addTimer(this);
+       }
 }
 
-void eTimer::startLongTimer( int seconds )
+void eTimer::startLongTimer(int seconds)
 {
        if (bActive)
                stop();
 
-       bActive = bSingleShot = true;
-       interval = 0;
-       clock_gettime(CLOCK_MONOTONIC, &nextActivation);
-//     eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_nsec, seconds);
-       if ( seconds > 0 )
-               nextActivation.tv_sec += seconds;
-//     eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
-       context.addTimer(this);
+       if (eMainloop::isValid(&context))
+       {
+               bActive = bSingleShot = true;
+               interval = 0;
+               clock_gettime(CLOCK_MONOTONIC, &nextActivation);
+//             eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_nsec, seconds);
+               if ( seconds > 0 )
+                       nextActivation.tv_sec += seconds;
+//             eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
+               context.addTimer(this);
+       }
 }
 
 void eTimer::stop()
@@ -114,6 +123,11 @@ void eTimer::activate()   // Internal Funktion... called from eApplication
 // mainloop
 ePtrList<eMainloop> eMainloop::existing_loops;
 
+bool eMainloop::isValid(eMainloop *ml)
+{
+       return std::find(existing_loops.begin(), existing_loops.end(), ml) != existing_loops.end();
+}
+
 eMainloop::~eMainloop()
 {
        existing_loops.remove(this);
@@ -151,7 +165,7 @@ void eMainloop::removeSocketNotifier(eSocketNotifier *sn)
                return;
        }
        for (i = notifiers.begin(); i != notifiers.end(); ++i)
-               eDebug("fd=%d, sn=%d", i->second->getFD(), (void*)i->second);
+               eDebug("fd=%d, sn=%p", i->second->getFD(), (void*)i->second);
        eFatal("removed socket notifier which is not present, fd=%d", fd);
 }
 
@@ -229,14 +243,9 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
 
        if (this == eApp)
        {
-               gOpcode op;
-               op.dc = 0;
-               op.opcode = gOpcode::flush;
-               gRC::getInstance()->submit(op);
                Py_BEGIN_ALLOW_THREADS
                ret = ::poll(pfd, fdcount, poll_timeout);
                Py_END_ALLOW_THREADS
-               
        } else
                ret = ::poll(pfd, fdcount, poll_timeout);
 
index c69133f..f6fc07d 100644 (file)
@@ -205,11 +205,9 @@ class eMainloop
        void removeSocketNotifier(eSocketNotifier *sn);
        void addTimer(eTimer* e);
        void removeTimer(eTimer* e);
-public:
-#ifndef SWIG
        static ePtrList<eMainloop> existing_loops;
-#endif
-
+       static bool isValid(eMainloop *);
+public:
        eMainloop()
                :app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_idle_count(0), m_inActivate(0), m_interrupt_requested(0)
        {
index 7512305..0da46da 100644 (file)
@@ -164,7 +164,7 @@ public:
                // returns a pointer to this new vector ( the reserved memory must deletet from the receiver !! )
                std::vector<T>* v=new std::vector<T>();
                v->reserve( std::list<T>::size() );
-    for ( std_list_T_iterator it( std::list<T*>::begin() ); it != std::list<T*>::end(); it++)
+               for ( std_list_T_iterator it( std::list<T*>::begin() ); it != std::list<T*>::end(); it++)
                        v->push_back( **it );
 
                return v;
index e7dc2be..f2ac732 100644 (file)
@@ -424,7 +424,7 @@ std::string convertDVBUTF8(const unsigned char *data, int len, int table, int ts
                        break;
        }
 
-       bool useTwoCharMapping = !table || tsidonid && encodingHandler.getTransponderUseTwoCharMapping(tsidonid);
+       bool useTwoCharMapping = !table || (tsidonid && encodingHandler.getTransponderUseTwoCharMapping(tsidonid));
 
        if (useTwoCharMapping && table == 5) { // i hope this dont break other transponders which realy use ISO8859-5 and two char byte mapping...
 //             eDebug("Cyfra / Cyfrowy Polsat HACK... override given ISO8859-5 with ISO6397");
diff --git a/lib/base/etpm.cpp b/lib/base/etpm.cpp
new file mode 100644 (file)
index 0000000..c264272
--- /dev/null
@@ -0,0 +1,161 @@
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <lib/base/etpm.h>
+
+DEFINE_REF(eTPM);
+
+eTPM::eTPM()
+{
+       struct sockaddr_un addr;
+       unsigned char buf[8];
+       unsigned int tag, len;
+       unsigned char *val;
+
+       level2_cert_read = level3_cert_read = false;
+
+       addr.sun_family = AF_UNIX;
+       strcpy(addr.sun_path, TPMD_SOCKET);
+
+       fd = socket(PF_UNIX, SOCK_STREAM, 0);
+       if (fd < 0) {
+               eDebug("[eTPM] socket error");
+               return;
+       }
+
+       if (connect(fd, (const struct sockaddr *)&addr, SUN_LEN(&addr)) < 0) {
+               eDebug("[eTPM] connect error");
+               return;
+       }
+
+       buf[0] = TPMD_DT_LEVEL2_CERT;
+       buf[1] = TPMD_DT_LEVEL3_CERT;
+       if (!send_cmd(TPMD_CMD_GET_DATA, buf, 2))
+       {
+               return;
+       }
+
+       val = (unsigned char*)recv_cmd(&tag, &len);
+       if (val == NULL)
+       {
+               return;
+       }
+
+       parse_data(val, len);
+       free(val);
+}
+
+eTPM::~eTPM()
+{
+
+}
+
+bool eTPM::send_cmd(enum tpmd_cmd cmd, const void *data, unsigned int len)
+{
+       unsigned char buf[len + 4];
+
+       buf[0] = (cmd >> 8) & 0xff;
+       buf[1] = (cmd >> 0) & 0xff;
+       buf[2] = (len >> 8) & 0xff;
+       buf[3] = (len >> 0) & 0xff;
+       memcpy(&buf[4], data, len);
+
+       if (write(fd, buf, sizeof(buf)) != (ssize_t)sizeof(buf)) {
+               fprintf(stderr, "%s: incomplete write\n", __func__);
+               return false;
+       }
+
+       return true;
+}
+
+void* eTPM::recv_cmd(unsigned int *tag, unsigned int *len)
+{
+       unsigned char buf[4];
+       void *val;
+
+       if (read(fd, buf, 4) != 4) {
+               fprintf(stderr, "%s: incomplete read\n", __func__);
+               return NULL;
+       }
+
+       *tag = (buf[0] << 8) | buf[1];
+       *len = (buf[2] << 8) | buf[3];
+
+       val = malloc(*len);
+       if (val == NULL)
+               return NULL;
+
+       if (read(fd, val, *len) != (ssize_t)*len) {
+               fprintf(stderr, "%s: incomplete read\n", __func__);
+               free(val);
+               return NULL;
+       }
+
+       return val;
+}
+
+void eTPM::parse_data(const unsigned char *data, unsigned int datalen)
+{
+       unsigned int i;
+       unsigned int tag;
+       unsigned int len;
+       const unsigned char *val;
+
+       for (i = 0; i < datalen; i += len) {
+               tag = data[i++];
+               len = data[i++];
+               val = &data[i];
+
+               switch (tag) {
+               case TPMD_DT_LEVEL2_CERT:
+                       if (len != 210)
+                               break;
+                       memcpy(level2_cert, val, 210);
+                       level2_cert_read = true;
+                       break;
+               case TPMD_DT_LEVEL3_CERT:
+                       if (len != 210)
+                               break;
+                       memcpy(level3_cert, val, 210);
+                       level3_cert_read = true;
+                       break;
+               }
+       }
+}
+
+PyObject *eTPM::getCert(cert_type type)
+{
+       if (type == TPMD_DT_LEVEL2_CERT && level2_cert_read)
+               return PyBuffer_FromMemory(level2_cert, 210);
+       else if (type == TPMD_DT_LEVEL3_CERT && level3_cert_read)
+               return PyBuffer_FromMemory(level3_cert, 210);
+       return Py_None;
+
+}
+
+PyObject *eTPM::challenge(PyObject* rnd)
+{
+       if (PyString_Check(rnd) && PyString_Size(rnd) == 8)
+       {
+               char* buf = PyString_AsString(rnd);
+               if (!send_cmd(TPMD_CMD_COMPUTE_SIGNATURE, buf, 8))
+                       return Py_None;
+
+               unsigned int tag, len;
+               unsigned char *val = (unsigned char*)recv_cmd(&tag, &len);
+
+               if (tag != TPMD_CMD_COMPUTE_SIGNATURE)
+                       return Py_None;
+
+               return PyBuffer_FromMemory(val, len);
+       }
+       else
+               return Py_None;
+}
diff --git a/lib/base/etpm.h b/lib/base/etpm.h
new file mode 100644 (file)
index 0000000..3728249
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __lib_base_etpm_h
+#define __lib_base_etpm_h
+
+#include <lib/base/object.h>
+#include <lib/python/python.h>
+
+#ifndef SWIG
+#define TPMD_SOCKET "/var/run/tpmd_socket"
+#endif
+
+class eTPM: public Object, public iObject
+{
+       DECLARE_REF(eTPM);
+#ifndef SWIG
+       int fd;
+       unsigned char level2_cert[210];
+       unsigned char level3_cert[210];
+       bool level2_cert_read;
+       bool level3_cert_read;
+
+       enum tpmd_cmd {
+               TPMD_CMD_RESERVED               = 0x0000,
+               TPMD_CMD_GET_DATA               = 0x0001,
+               TPMD_CMD_APDU                   = 0x0002,
+               TPMD_CMD_COMPUTE_SIGNATURE      = 0x0003,
+               TPMD_CMD_APP_CERT               = 0x0004,
+       };
+
+       bool send_cmd(enum tpmd_cmd cmd, const void *data, unsigned int len);
+       void *recv_cmd(unsigned int *tag, unsigned int *len);
+       void parse_data(const unsigned char *data, unsigned int datalen);
+
+#endif
+public:
+       eTPM();
+       ~eTPM();
+
+       enum cert_type {
+               TPMD_DT_LEVEL2_CERT = 0x04,
+               TPMD_DT_LEVEL3_CERT = 0x05
+       };
+       PyObject *getCert(cert_type type);
+       PyObject *challenge(PyObject *rnd);
+};
+
+#endif // __lib_base_etpm_h
index 2bfeefa..f30ba8c 100644 (file)
@@ -73,16 +73,8 @@ void eRCDeviceInputDev::handleCode(long rccode)
 eRCDeviceInputDev::eRCDeviceInputDev(eRCInputEventDriver *driver)
        :eRCDevice(driver->getDeviceName(), driver), iskeyboard(false)
 {
-       int len=id.length();
-       int idx=0;
-       while(idx <= len-8)
-       {
-               if (!strncasecmp(&id[idx++], "KEYBOARD", 8))
-               {
-                       iskeyboard=true;
-                       break;
-               }
-       }
+       if (strcasestr(id.c_str(), "keyboard") != NULL)
+               iskeyboard = true;
        setExclusive(true);
        eDebug("Input device \"%s\" is %sa keyboard.", id.c_str(), iskeyboard ? "" : "not ");
 }
index ef8dadc..88cd3ee 100644 (file)
@@ -601,7 +601,7 @@ RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEve
        return 0;
 }
 
-static int readMpegProc(char *str, int decoder)
+static int readMpegProc(const char *str, int decoder)
 {
        int val = -1;
        char tmp[64];
index 6eaadb0..17712dd 100644 (file)
@@ -1324,16 +1324,6 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                return;
        }
 
-       m_cue->m_lock.RdLock();
-       if (!m_cue->m_decoding_demux)
-       {
-               start = current_offset;
-               size = max;
-               eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
-               m_cue->m_lock.Unlock();
-               return;
-       }
-
        if (m_skipmode_n)
        {
                eDebug("skipmode %d:%d (x%d)", m_skipmode_m, m_skipmode_n, m_skipmode_frames);
@@ -1341,7 +1331,6 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
        }
 
        eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
-       
        int frame_skip_success = 0;
 
        if (m_skipmode_m)
@@ -1386,6 +1375,8 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                }
        }
 
+       m_cue->m_lock.RdLock();
+
        while (!m_cue->m_seek_requests.empty())
        {
                std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
@@ -1410,6 +1401,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                                eDebug("decoder getPTS failed, can't seek relative");
                                continue;
                        }
+                       if (!m_cue->m_decoding_demux)
+                       {
+                               eDebug("getNextSourceSpan, no decoding demux. couldn't seek to %llx... ignore request!", pts);
+                               start = current_offset;
+                               size = max;
+                               continue;
+                       }
                        if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
                        {
                                eDebug("seekTo: getCurrentPosition failed!");
index bb6b94b..26b6767 100644 (file)
@@ -111,7 +111,7 @@ void TDT::ready(int error)
 
 int TDT::createTable(unsigned int nr, const __u8 *data, unsigned int max)
 {
-       if ( data && data[0] == 0x70 || data[0] == 0x73 )
+       if ( data && (data[0] == 0x70 || data[0] == 0x73 ))
        {
                int length = ((data[1] & 0x0F) << 8) | data[2];
                if ( length >= 5 )
index 48cbfbf..119223a 100644 (file)
@@ -1457,7 +1457,7 @@ void eEPGCache::channel_data::readData( const __u8 *data)
        }
        tidMap &seenSections = this->seenSections[map];
        tidMap &calcedSections = this->calcedSections[map];
-       if ( state == 1 && calcedSections == seenSections || state > 1 )
+       if ( (state == 1 && calcedSections == seenSections) || state > 1 )
        {
                eDebugNoNewLine("[EPGC] ");
                switch (source)
@@ -2562,7 +2562,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler)
                                                                {
                                                                        __u8 buffer[10];
                                                                        (*desc)->writeToBuffer(buffer);
-                                                                       if (!strncmp((unsigned char*)buffer+2, "EPGDATA", 7))
+                                                                       if (!strncmp((const char *)buffer+2, "EPGDATA", 7))
                                                                        {
                                                                                eServiceReferenceDVB ref;
                                                                                if (!pmthandler->getServiceReference(ref))
@@ -2571,7 +2571,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler)
                                                                                        messages.send(Message(Message::got_mhw2_channel_pid, ref, pid));
                                                                                }
                                                                        }
-                                                                       else if(!strncmp((unsigned char*)buffer+2, "FICHAS", 6))
+                                                                       else if(!strncmp((const char *)buffer+2, "FICHAS", 6))
                                                                        {
                                                                                eServiceReferenceDVB ref;
                                                                                if (!pmthandler->getServiceReference(ref))
@@ -2580,7 +2580,7 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler)
                                                                                        messages.send(Message(Message::got_mhw2_summary_pid, ref, pid));
                                                                                }
                                                                        }
-                                                                       else if(!strncmp((unsigned char*)buffer+2, "GENEROS", 7))
+                                                                       else if(!strncmp((const char *)buffer+2, "GENEROS", 7))
                                                                        {
                                                                                eServiceReferenceDVB ref;
                                                                                if (!pmthandler->getServiceReference(ref))
index f85a37f..519b5fe 100644 (file)
@@ -483,6 +483,13 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate)
        closeFrontend();
 }
 
+void eDVBFrontend::reopenFrontend()
+{
+       sleep(1);
+       m_type = -1;
+       openFrontend();
+}
+
 int eDVBFrontend::openFrontend()
 {
        if (m_state != stateClosed)
@@ -1046,6 +1053,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &
        case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
        default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
        }
+       PutToDict(dict, "fec_inner", tmp);
 
        switch (p[0].u.data)
        {
@@ -1094,7 +1102,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &
        PutToDict(dict, "orbital_position", orb_pos);
        PutToDict(dict, "polarization", polarization);
 
-       switch(parm_u_qpsk_fec_inner)
+       switch((int)parm_u_qpsk_fec_inner)
        {
        case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
        case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
@@ -1428,9 +1436,11 @@ int eDVBFrontend::readInputpower()
                return 0;
        int power=m_slotid;  // this is needed for read inputpower from the correct tuner !
        char proc_name[64];
-       sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid);
-       FILE *f=fopen(proc_name, "r");
-       if (f)
+       char proc_name2[64];
+       sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
+       sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
+       FILE *f;
+       if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
        {
                if (fscanf(f, "%d", &power) != 1)
                        eDebug("read %s failed!! (%m)", proc_name);
index 4cf0508..bc31755 100644 (file)
@@ -146,6 +146,7 @@ public:
        static void setTypePriorityOrder(int val) { PriorityOrder = val; }
        static int getTypePriorityOrder() { return PriorityOrder; }
 
+       void reopenFrontend();
        int openFrontend();
        int closeFrontend(bool force=false);
        const char *getDescription() const { return m_description; }
index 4ef7efa..d20829b 100644 (file)
@@ -459,6 +459,8 @@ class iDVBFrontend: public iDVBFrontend_ENUMS, public iObject
 public:
        virtual RESULT getFrontendType(int &SWIG_OUTPUT)=0;
        virtual RESULT tune(const iDVBFrontendParameters &where)=0;
+       virtual int closeFrontend(bool force = false)=0;
+       virtual void reopenFrontend()=0;
 #ifndef SWIG
        virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
 #endif
index fd29617..b37aa71 100644 (file)
@@ -12,6 +12,7 @@
 #include <lib/dvb/frontend.h>
 #include <lib/base/eerror.h>
 #include <lib/base/estring.h>
+#include <lib/python/python.h>
 #include <errno.h>
 
 #define SCAN_eDebug(x...) do { if (m_scan_debug) eDebug(x); } while(0)
@@ -23,37 +24,118 @@ eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug)
        :m_channel(channel), m_channel_state(iDVBChannel::state_idle)
        ,m_ready(0), m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT)
        ,m_pmt_running(false), m_abort_current_pmt(false), m_flags(0)
-       ,m_usePAT(usePAT), m_scan_debug(debug)
+       ,m_usePAT(usePAT), m_scan_debug(debug), m_show_add_tsid_onid_check_failed_msg(true)
 {
        if (m_channel->getDemux(m_demux))
                SCAN_eDebug("scan: failed to allocate demux!");
        m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection);
+       FILE *f = fopen("/etc/enigma2/scan_tp_valid_check.py", "r");
+       if (f)
+       {
+               char code[16384];
+               size_t rd = fread(code, 1, 16383, f);
+               if (rd)
+               {
+                       code[rd]=0;
+                       m_additional_tsid_onid_check_func = Py_CompileString(code, "/etc/enigma2/scan_tp_valid_check.py", Py_file_input);
+               }
+               fclose(f);
+       }
 }
 
 eDVBScan::~eDVBScan()
 {
+       if (m_additional_tsid_onid_check_func)
+               Py_DECREF(m_additional_tsid_onid_check_func);
 }
 
 int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTransportStreamID tsid)
 {
+       int ret;
        switch (onid.get())
        {
        case 0:
        case 0x1111:
-               return 0;
+               ret=0;
+               break;
        case 0x13E:  // workaround for 11258H and 11470V on hotbird with same ONID/TSID (0x13E/0x578)
-               return orbital_position != 130 || tsid != 0x578;
+               ret = orbital_position != 130 || tsid != 0x578;
+               break;
        case 1:
-               return orbital_position == 192;
+               ret = orbital_position == 192;
+               break;
        case 0x00B1:
-               return tsid != 0x00B0;
+               ret = tsid != 0x00B0;
+               break;
        case 0x00eb:
-               return tsid != 0x4321;
+               ret = tsid != 0x4321;
+               break;
        case 0x0002:
-               return abs(orbital_position-282) < 6;
+               ret = abs(orbital_position-282) < 6 && tsid != 2019;
+               // 12070H and 10936V have same tsid/onid.. but even the same services are provided
+               break;
+       case 0x2000:
+               ret = tsid != 0x1000;
+               break;
+       case 0x5E: // Sirius 4.8E 12322V and 12226H
+               ret = abs(orbital_position-48) < 3 && tsid != 1;
+               break;
+       case 10100: // Eutelsat W7 36.0E 11644V and 11652V
+               ret = orbital_position != 360 || tsid != 10187;
+               break;
+       case 42: // Tuerksat 42.0E
+               ret = orbital_position != 420 || (
+                   tsid != 8 && // 11830V 12729V
+                   tsid != 5 && // 12679V 12685H
+                   tsid != 2 && // 11096V 12015H
+                   tsid != 55); // 11996V 11716V
+               break;
+       case 100: // Intelsat 10 68.5E 3808V 3796V 4012V, Amos 4.0W 10723V 11571H
+               ret = (orbital_position != 685 && orbital_position != 3560) || tsid != 1;
+               break;
+       case 70: // Thor 0.8W 11862H 12341V
+               ret = abs(orbital_position-3592) < 3 && tsid != 46;
+               break;
+       case 32: // NSS 806 (40.5W) 4059R, 3774L
+               ret = orbital_position != 3195 || tsid != 21;
+               break;
        default:
-               return onid.get() < 0xFF00;
+               ret = onid.get() < 0xFF00;
+               break;
+       }
+       if (ret && m_additional_tsid_onid_check_func)
+       {
+               bool failed = true;
+               ePyObject dict = PyDict_New();
+               extern void PutToDict(ePyObject &, const char *, long);
+               PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
+               PutToDict(dict, "orbpos", orbital_position);
+               PutToDict(dict, "tsid", tsid.get());
+               PutToDict(dict, "onid", onid.get());
+               ePyObject r = PyEval_EvalCode((PyCodeObject*)(PyObject*)m_additional_tsid_onid_check_func, dict, dict);
+               if (r)
+               {
+                       ePyObject o = PyDict_GetItemString(dict, "ret");
+                       if (o)
+                       {
+                               if (PyInt_Check(o))
+                               {
+                                       ret = PyInt_AsLong(o);
+                                       failed = false;
+                               }
+                       }
+                       Py_DECREF(r);
+               }
+               if (failed && m_show_add_tsid_onid_check_failed_msg)
+               {
+                       eDebug("execing /etc/enigma2/scan_tp_valid_check failed!\n"
+                               "usable global variables in scan_tp_valid_check.py are 'orbpos', 'tsid', 'onid'\n"
+                               "the return value must be stored in a global var named 'ret'");
+                       m_show_add_tsid_onid_check_failed_msg=false;
+               }
+               Py_DECREF(dict);
        }
+       return ret;
 }
 
 eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
index 2f3ac34..8f64abe 100644 (file)
@@ -92,6 +92,8 @@ class eDVBScan: public Object, public iObject
        int m_flags;
        bool m_usePAT;
        bool m_scan_debug;
+       ePyObject m_additional_tsid_onid_check_func;
+       bool m_show_add_tsid_onid_check_failed_msg;
 public:
        eDVBScan(iDVBChannel *channel, bool usePAT=true, bool debug=true );
        ~eDVBScan();
index 8b6bc49..0e3e7e0 100644 (file)
@@ -189,6 +189,7 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                                        else
                                                                ret += 10;
                                                }
+                                               eSecDebugNoSimulate("ret3 %d", ret);
                                        }
                                        else // current fe is dependent of another tuner ... (so this fe can't turn the rotor!)
                                        {
@@ -200,12 +201,8 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                                        ret = 0;
                                                }
                                        }
-                                       eSecDebugNoSimulate("ret3 %d", ret);
+                                       eSecDebugNoSimulate("ret4 %d", ret);
                                }
-                               else if (!direct_connected)
-                                       ret = 0;
-
-                               eSecDebugNoSimulate("ret4 %d", ret);
 
                                if (ret && rotor && rotor_pos != -1)
                                        ret -= abs(rotor_pos-sat.orbital_position);
index 5e489eb..9450ecc 100644 (file)
@@ -32,7 +32,7 @@ extern void bcm_accel_blit(
                int dst_addr, int dst_width, int dst_height, int dst_stride,
                int src_x, int src_y, int width, int height,
                int dst_x, int dst_y, int dwidth, int dheight,
-               int pal_addr);
+               int pal_addr, int flags);
 extern void bcm_accel_fill(
                int dst_addr, int dst_width, int dst_height, int dst_stride,
                int x, int y, int width, int height,
@@ -122,7 +122,7 @@ int gAccel::blit(gSurface *dst, const gSurface *src, const eRect &p, const eRect
                        dst->data_phys, dst->x, dst->y, dst->stride, 
                        area.left(), area.top(), area.width(), area.height(),
                        p.x(), p.y(), p.width(), p.height(),
-                       pal_addr);
+                       pal_addr, flags);
                return 0;
        }
 #endif
index 3beb677..12b5f22 100644 (file)
@@ -64,7 +64,7 @@ void bcm_accel_blit(
                int dst_addr, int dst_width, int dst_height, int dst_stride,
                int src_x, int src_y, int width, int height,
                int dst_x, int dst_y, int dwidth, int dheight,
-               int pal_addr)
+               int pal_addr, int flags)
 {
        C(0x43); // reset source
        C(0x53); // reset dest
index dfac144..967c1df 100644 (file)
@@ -341,6 +341,8 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly
                                i->x-=offset.x();
                                i->y-=offset.y();
                                i->bbox.moveBy(-offset.x(), -offset.y());
+                               --lineChars.back();
+                               ++charCount;
                        } while (i-- != glyphs.rbegin()); // rearrange them into the next line
                        cursor+=ePoint(linelength, 0);  // put the cursor after that line
                } else
@@ -363,7 +365,7 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly
        }
 
        pGlyph ng;
-       ng.bbox.setLeft( (flags&GS_ISFIRST|cursor.x()-1)+glyph->left );
+       ng.bbox.setLeft( ((flags&GS_ISFIRST)|(cursor.x()-1))+glyph->left );
        ng.bbox.setTop( cursor.y() - glyph->top );
        ng.bbox.setWidth( glyph->width );
        ng.bbox.setHeight( glyph->height );
@@ -378,6 +380,7 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly
        ng.glyph_index = glyphIndex;
        ng.flags = flags;
        glyphs.push_back(ng);
+       ++charCount;
 
                /* when we have a SHY, don't xadvance. It will either be the last in the line (when used for breaking), or not displayed. */
        if (!(flags & GS_SOFTHYPHEN))
@@ -425,7 +428,13 @@ void eTextPara::newLine(int flags)
        cursor.setX(left);
        previous=0;
        int linegap=current_face->size->metrics.height-(current_face->size->metrics.ascender+current_face->size->metrics.descender);
+
+       lineOffsets.push_back(cursor.y());
+       lineChars.push_back(charCount);
+       charCount=0;
+
        cursor+=ePoint(0, (current_face->size->metrics.ascender+current_face->size->metrics.descender+linegap)>>6);
+
        if (maximum.height()<cursor.y())
                maximum.setHeight(cursor.y());
        previous=0;
@@ -595,22 +604,20 @@ int eTextPara::renderString(const char *string, int rflags)
        shape(uc_shape, uc_string);
        
                // now do the usual logical->visual reordering
-#ifdef HAVE_FRIBIDI    
+       int size=uc_shape.size();
+#ifdef HAVE_FRIBIDI
        FriBidiCharType dir=FRIBIDI_TYPE_ON;
-       {
-               int size=uc_shape.size();
-               uc_visual.resize(size);
-               // gaaanz lahm, aber anders geht das leider nicht, sorry.
-               FriBidiChar array[size], target[size];
-               std::copy(uc_shape.begin(), uc_shape.end(), array);
-               fribidi_log2vis(array, size, &dir, target, 0, 0, 0);
-               uc_visual.assign(target, target+size);
-       }
+       uc_visual.resize(size);
+       // gaaanz lahm, aber anders geht das leider nicht, sorry.
+       FriBidiChar array[size], target[size];
+       std::copy(uc_shape.begin(), uc_shape.end(), array);
+       fribidi_log2vis(array, size, &dir, target, 0, 0, 0);
+       uc_visual.assign(target, target+size);
 #else
        uc_visual=uc_shape;
 #endif
 
-       glyphs.reserve(uc_visual.size());
+       glyphs.reserve(size);
        
        int nextflags = 0;
        
@@ -704,8 +711,19 @@ nprint:    isprintable=0;
        calc_bbox();
 #ifdef HAVE_FRIBIDI
        if (dir & FRIBIDI_MASK_RTL)
+       {
                realign(dirRight);
+               doTopBottomReordering=true;
+       }
 #endif
+
+       if (charCount)
+       {
+               lineOffsets.push_back(cursor.y());
+               lineChars.push_back(charCount);
+               charCount=0;
+       }
+
        return 0;
 }
 
@@ -796,11 +814,21 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
        gRegion clip = dc.getClip() & area;
 
        int buffer_stride=surface->stride;
-       
+
        for (unsigned int c = 0; c < clip.rects.size(); ++c)
        {
-               for (glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i)
+               std::list<int>::reverse_iterator line_offs_it(lineOffsets.rbegin());
+               std::list<int>::iterator line_chars_it(lineChars.begin());
+               int line_offs=0;
+               int line_chars=0;
+               for (glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i, --line_chars)
                {
+                       while(!line_chars)
+                       {
+                               line_offs = *(line_offs_it++);
+                               line_chars = *(line_chars_it++);
+                       }
+
                        if (i->flags & GS_SOFTHYPHEN)
                                continue;
 
@@ -813,13 +841,13 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
                                lookup8 = lookup8_invert;
                                lookup32 = lookup32_invert;
                        }
-               
+
                        static FTC_SBit glyph_bitmap;
                        if (fontRenderClass::instance->getGlyphBitmap(&i->font->font, i->glyph_index, &glyph_bitmap))
                                continue;
                        int rx=i->x+glyph_bitmap->left + offset.x();
-                       int ry=i->y-glyph_bitmap->top  + offset.y();
-               
+                       int ry=(doTopBottomReordering ? line_offs : i->y) - glyph_bitmap->top + offset.y();
+
                        __u8 *d=(__u8*)(surface->data)+buffer_stride*ry+rx*surface->bypp;
                        __u8 *s=glyph_bitmap->buffer;
                        register int sx=glyph_bitmap->width;
index 2643fda..7dd9f89 100644 (file)
@@ -14,6 +14,7 @@ typedef FTC_ImageTypeRec FTC_Image_Desc;
 typedef FTC_SBitCache FTC_SBit_Cache;
 #endif
 #include <vector>
+#include <list>
 
 #include <lib/gdi/fb.h>
 #include <lib/gdi/esize.h>
@@ -113,6 +114,10 @@ class eTextPara: public iObject
        eSize maximum;
        int left;
        glyphString glyphs;
+       std::list<int> lineOffsets;
+       std::list<int> lineChars;
+       int charCount;
+       bool doTopBottomReordering;
 
        int appendGlyph(Font *current_font, FT_Face current_face, FT_UInt glyphIndex, int flags, int rflags);
        void newLine(int flags);
@@ -120,10 +125,12 @@ class eTextPara: public iObject
        eRect boundBox;
        void calc_bbox();
        int bboxValid;
+       void clear();
 public:
        eTextPara(eRect area, ePoint start=ePoint(-1, -1))
-               : current_font(0), replacement_font(0), current_face(0), replacement_face(0),
-                       area(area), cursor(start), maximum(0, 0), left(start.x()), bboxValid(0)
+               :current_font(0), replacement_font(0), current_face(0), replacement_face(0)
+               ,area(area), cursor(start), maximum(0, 0), left(start.x()), charCount(0)
+               ,doTopBottomReordering(false), bboxValid(0)
        {
        }
        virtual ~eTextPara();
@@ -134,7 +141,7 @@ public:
        void setFont(const gFont *font);
        int renderString(const char *string, int flags=0);
 
-       void clear();
+
 
        void blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground);
 
index 1208c97..73d9ac2 100644 (file)
@@ -428,7 +428,7 @@ void gRegion::moveBy(ePoint offset)
 
 void gRegion::scale(int x_n, int x_d, int y_n, int y_d)
 {
-       int i;
+       unsigned int i;
        for (i=0; i<rects.size(); ++i)
                rects[i].scale(x_n, x_d, y_n, y_d);
 }
index 4465d84..1c671fa 100644 (file)
@@ -49,7 +49,8 @@ int iListboxContent::currentCursorSelectable()
 
 DEFINE_REF(eListboxPythonStringContent);
 
-eListboxPythonStringContent::eListboxPythonStringContent(): m_itemheight(25), m_cursor(0)
+eListboxPythonStringContent::eListboxPythonStringContent()
+       :m_cursor(0), m_itemheight(25)
 {
 }
 
@@ -81,7 +82,7 @@ int eListboxPythonStringContent::cursorMove(int count)
 
 int eListboxPythonStringContent::cursorValid()
 {
-       return ((unsigned int)m_cursor) < size();
+       return m_cursor < size();
 }
 
 int eListboxPythonStringContent::cursorSet(int n)
@@ -342,7 +343,6 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
                if (PyTuple_Check(item))
                {
                                /* handle left part. get item from tuple, convert to string, display. */
-
                        text = PyTuple_GET_ITEM(item, 0);
                        text = PyObject_Str(text); /* creates a new object - old object was borrowed! */
                        const char *string = (text && PyString_Check(text)) ? PyString_AsString(text) : "<not-a-string>";
@@ -356,7 +356,9 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
                        int value_alignment_left = !*string;
 
                                /* now, handle the value. get 2nd part from tuple*/
-                       value = PyTuple_GET_ITEM(item, 1);
+                       if (PyTuple_Size(item) >= 2) // when no 2nd entry is in tuple this is a non selectable entry without config part
+                               value = PyTuple_GET_ITEM(item, 1);
+
                        if (value)
                        {
                                ePyObject args = PyTuple_New(1);
@@ -467,7 +469,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
                                        }
                                }
                                        /* type is borrowed */
-                       } else
+                       } else if (value)
                                eWarning("eListboxPythonConfigContent: second value of tuple is not a tuple.");
                        if (value)
                                Py_DECREF(value);
old mode 100644 (file)
new mode 100755 (executable)
index 8e332e3..6b322c9
@@ -1,5 +1,6 @@
 from Tools.Directories import resolveFilename, SCOPE_SYSETC
 from enigma import getEnigmaVersionString
+from os import popen
 
 class About:
        def __init__(self):
@@ -43,4 +44,14 @@ class About:
        def getEnigmaVersionString(self):
                return getEnigmaVersionString()
 
+       def getKernelVersionString(self):
+               try:
+                       result = popen("uname -r","r").read().strip("\n").split('-')
+                       kernel_version = result[0]
+                       return kernel_version
+               except:
+                       pass
+
+               return "unknown"
+
 about = About()
index 5014fde..fa3518c 100644 (file)
@@ -19,6 +19,7 @@ class ServiceInfo(Converter, object):
        ONID = 13
        SID = 14
        FRAMERATE = 15
+       TRANSFERBPS = 16
        
 
        def __init__(self, type):
@@ -40,6 +41,7 @@ class ServiceInfo(Converter, object):
                                "OnId": (self.ONID, (iPlayableService.evUpdatedInfo,)),
                                "Sid": (self.SID, (iPlayableService.evUpdatedInfo,)),
                                "Framerate": (self.FRAMERATE, (iPlayableService.evVideoSizeChanged,iPlayableService.evUpdatedInfo,)),
+                               "TransferBPS": (self.TRANSFERBPS, (iPlayableService.evUpdatedInfo,)),
                        }[type]
 
        def getServiceInfoString(self, info, what, convert = lambda x: "%d" % x):
@@ -112,6 +114,8 @@ class ServiceInfo(Converter, object):
                        return self.getServiceInfoString(info, iServiceInformation.sSID)
                elif self.type == self.FRAMERATE:
                        return self.getServiceInfoString(info, iServiceInformation.sFrameRate, lambda x: "%d fps" % ((x+500)/1000))
+               elif self.type == self.TRANSFERBPS:
+                       return self.getServiceInfoString(info, iServiceInformation.sTransferBPS, lambda x: "%d kB/s" % (x/1024))
                return ""
 
        text = property(getText)
old mode 100644 (file)
new mode 100755 (executable)
index b86d94b..b1d89f5
@@ -10,8 +10,8 @@ class TemplatedMultiContent(StringList):
                del l["self"] # cleanup locals a bit
                del l["args"]
 
-               self.template = eval(args, {}, l)
                self.active_style = None
+               self.template = eval(args, {}, l)
                assert "fonts" in self.template
                assert "itemHeight" in self.template
                assert "template" in self.template or "templates" in self.template
@@ -25,7 +25,6 @@ class TemplatedMultiContent(StringList):
                if not self.content:
                        from enigma import eListboxPythonMultiContent
                        self.content = eListboxPythonMultiContent()
-                       self.setTemplate()
 
                        # also setup fonts (also given by source)
                        index = 0
@@ -35,30 +34,37 @@ class TemplatedMultiContent(StringList):
 
                # if only template changed, don't reload list
                if what[0] == self.CHANGED_SPECIFIC and what[1] == "style":
-                       self.setTemplate()
-                       return
-
-               if self.source:
+                       pass
+               elif self.source:
                        self.content.setList(self.source.list)
-                       self.setTemplate()
 
+               self.setTemplate()
                self.downstream_elements.changed(what)
 
        def setTemplate(self):
                if self.source:
                        style = self.source.style
+
                        if style == self.active_style:
-                               return # style did not change
+                               return
 
                        # if skin defined "templates", that means that it defines multiple styles in a dict. template should still be a default
                        templates = self.template.get("templates")
                        template = self.template.get("template")
                        itemheight = self.template["itemHeight"]
+                       selectionEnabled = self.template.get("selectionEnabled", True)
+                       scrollbarMode = self.template.get("scrollbarMode", "showOnDemand")
 
                        if templates and style and style in templates: # if we have a custom style defined in the source, and different templates in the skin, look it up
                                template = templates[style][1]
                                itemheight = templates[style][0]
+                               if len(templates[style]) > 2:
+                                       selectionEnabled = templates[style][2]
+                               if len(templates[style]) > 3:
+                                       scrollbarMode = templates[style][3]
 
                        self.content.setTemplate(template)
-
                        self.content.setItemHeight(itemheight)
+                       self.selectionEnabled = selectionEnabled
+                       self.scrollbarMode = scrollbarMode
+                       self.active_style = style
index 85e2b53..03d5215 100755 (executable)
@@ -16,7 +16,7 @@ class InfoHandlerParseError(Exception):
                return repr(self.value)
 
 class InfoHandler(xml.sax.ContentHandler):
-       def __init__(self, prerequisiteMet, directory, language = None):
+       def __init__(self, prerequisiteMet, directory):
                self.attributes = {}
                self.directory = directory
                self.list = []
@@ -26,9 +26,6 @@ class InfoHandler(xml.sax.ContentHandler):
                self.validFileTypes = ["skin", "config", "services", "favourites", "package"]
                self.prerequisitesMet = prerequisiteMet
                self.data = ""
-               self.language = language
-               self.translatedPackageInfos = {}
-               self.foundTranslation = None
 
        def printError(self, error):
                print "Error in defaults xml files:", error
@@ -52,15 +49,6 @@ class InfoHandler(xml.sax.ContentHandler):
                if name == "info":
                        self.foundTranslation = None
                        self.data = ""
-                       if not attrs.has_key("language"):
-                                       print "info tag with no language attribute"
-                       else:
-                               if attrs["language"] == 'en': # read default translations
-                                       self.foundTranslation = False
-                                       self.data = ""
-                               elif attrs["language"] == self.language:
-                                       self.foundTranslation = True
-                                       self.data = ""
 
                if name == "files":
                        if attrs.has_key("type"):
@@ -91,20 +79,17 @@ class InfoHandler(xml.sax.ContentHandler):
                        if attrs.has_key("details"):
                                self.attributes["details"] = str(attrs["details"])
                        if attrs.has_key("name"):
-                               self.attributes["name"] = str(attrs["name"].encode("utf-8"))
+                               self.attributes["name"] = str(attrs["name"])
                        if attrs.has_key("packagename"):
-                               self.attributes["packagename"] = str(attrs["packagename"].encode("utf-8"))
+                               self.attributes["packagename"] = str(attrs["packagename"])
                        if attrs.has_key("packagetype"):
-                               self.attributes["packagetype"] = str(attrs["packagetype"].encode("utf-8"))
+                               self.attributes["packagetype"] = str(attrs["packagetype"])
                        if attrs.has_key("shortdescription"):
-                               self.attributes["shortdescription"] = str(attrs["shortdescription"].encode("utf-8"))
+                               self.attributes["shortdescription"] = str(attrs["shortdescription"])
 
                if name == "screenshot":
                        if attrs.has_key("src"):
-                               if self.foundTranslation is False:
-                                       self.attributes["screenshot"] = str(attrs["src"])
-                               elif self.foundTranslation is True:
-                                       self.translatedPackageInfos["screenshot"] = str(attrs["src"])
+                               self.attributes["screenshot"] = str(attrs["src"])
 
        def endElement(self, name):
                #print "endElement", name
@@ -124,7 +109,7 @@ class InfoHandler(xml.sax.ContentHandler):
                                self.attributes[self.filetype].append({ "name": str(self.fileattrs["name"]), "directory": directory })
 
                if name in ( "default", "package" ):
-                       self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites ,"translation": self.translatedPackageInfos})
+                       self.list.append({"attributes": self.attributes, 'prerequisites': self.globalprerequisites})
                        self.attributes = {}
                        self.globalprerequisites = {}
 
@@ -133,30 +118,13 @@ class InfoHandler(xml.sax.ContentHandler):
                        self.attributes["author"] = str(data)
                if self.elements[-1] == "name":
                        self.attributes["name"] = str(data)
-               if self.foundTranslation is False:
-                       if self.elements[-1] == "author":
-                               self.attributes["author"] = str(data)
-                       if self.elements[-1] == "name":
-                               self.attributes["name"] = str(data)
-                       if self.elements[-1] == "packagename":
-                               self.attributes["packagename"] = str(data.encode("utf-8"))
-                       if self.elements[-1] == "shortdescription":
-                               self.attributes["shortdescription"] = str(data.encode("utf-8"))
-                       if self.elements[-1] == "description":
-                               self.data += data.strip()
-                               self.attributes["description"] = str(self.data.encode("utf-8"))
-               elif self.foundTranslation is True:
-                       if self.elements[-1] == "author":
-                               self.translatedPackageInfos["author"] = str(data)
-                       if self.elements[-1] == "name":
-                               self.translatedPackageInfos["name"] = str(data)
-                       if self.elements[-1] == "description":
-                               self.data += data.strip()
-                               self.translatedPackageInfos["description"] = str(self.data.encode("utf-8"))
-                       if self.elements[-1] == "name":
-                               self.translatedPackageInfos["name"] = str(data.encode("utf-8"))
-                       if self.elements[-1] == "shortdescription":
-                               self.translatedPackageInfos["shortdescription"] = str(data.encode("utf-8"))
+               if self.elements[-1] == "packagename":
+                       self.attributes["packagename"] = str(data)
+               if self.elements[-1] == "shortdescription":
+                       self.attributes["shortdescription"] = str(data)
+               if self.elements[-1] == "description":
+                       self.data += data.strip()
+                       self.attributes["description"] = str(self.data)
                #print "characters", data
 
 
@@ -166,13 +134,12 @@ class DreamInfoHandler:
        STATUS_ERROR = 2
        STATUS_INIT = 4
 
-       def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None, language = None):
+       def __init__(self, statusCallback, blocking = False, neededTag = None, neededFlag = None):
                self.hardware_info = HardwareInfo()
                self.directory = "/"
 
                self.neededTag = neededTag
                self.neededFlag = neededFlag
-               self.language = language
 
                # caution: blocking should only be used, if further execution in enigma2 depends on the outcome of
                # the installer!
@@ -203,8 +170,8 @@ class DreamInfoHandler:
                #print handler.list
 
        def readIndex(self, directory, file):
-               print "Reading .xml meta index file", file
-               handler = InfoHandler(self.prerequisiteMet, directory, self.language)
+               print "Reading .xml meta index file", directory, file
+               handler = InfoHandler(self.prerequisiteMet, directory)
                try:
                        xml.sax.parse(file, handler)
                        for entry in handler.list:
@@ -216,7 +183,7 @@ class DreamInfoHandler:
        def readDetails(self, directory, file):
                self.packageDetails = []
                print "Reading .xml meta details file", file
-               handler = InfoHandler(self.prerequisiteMet, directory, self.language)
+               handler = InfoHandler(self.prerequisiteMet, directory)
                try:
                        xml.sax.parse(file, handler)
                        for entry in handler.list:
@@ -225,7 +192,6 @@ class DreamInfoHandler:
                        print "file", file, "ignored due to errors in the file"
                #print handler.list
 
-
        # prerequisites = True: give only packages matching the prerequisites
        def fillPackagesList(self, prerequisites = True):
                self.packageslist = []
@@ -254,20 +220,16 @@ class DreamInfoHandler:
                        self.directory = [self.directory]
 
                for indexfile in os.listdir(self.directory[0]):
-                       if indexfile.startswith("index"):
-                               if indexfile.endswith("_en.xml"): #we first catch all english indexfiles
-                                       indexfileList.append(os.path.splitext(indexfile)[0][:-3])
-
+                       if indexfile.startswith("index-"):
+                               if indexfile.endswith(".xml"):
+                                       if indexfile[-7:-6] == "_":
+                                               continue
+                                       indexfileList.append(indexfile)
                if len(indexfileList):
                        for file in indexfileList:
                                neededFile = self.directory[0] + "/" + file
-                               if self.language is not None:
-                                       if os.path.exists(neededFile + '_' + self.language + '.xml' ):
-                                               #print "translated index file found",neededFile + '_' + self.language + '.xml'
-                                               self.readIndex(self.directory[0] + "/", neededFile + '_' + self.language + '.xml')
-                                       else:
-                                               #print "reading original index file"
-                                               self.readIndex(self.directory[0] + "/", neededFile + '_en.xml')
+                               if os.path.isfile(neededFile):
+                                       self.readIndex(self.directory[0] + "/" , neededFile)
 
                if prerequisites:
                        for package in self.packagesIndexlist[:]:
index cee0523..a993c39 100644 (file)
@@ -3,6 +3,9 @@ import os
 from Components.config import config, ConfigSubList, ConfigSubsection, ConfigSlider
 from Tools.BoundFunction import boundFunction
 
+import NavigationInstance
+from enigma import iRecordableService
+
 class FanControl:
        # ATM there's only support for one fan
        def __init__(self):
@@ -13,18 +16,42 @@ class FanControl:
                self.createConfig()
                config.misc.standbyCounter.addNotifier(self.standbyCounterChanged, initial_call = False)
 
-       def leaveStandby(self):
+       def setVoltage_PWM(self):
                for fanid in range(self.getFanCount()):
                        cfg = self.getConfig(fanid)
                        self.setVoltage(fanid, cfg.vlt.value)
                        self.setPWM(fanid, cfg.pwm.value)
+                       print "[FanControl]: setting fan values: fanid = %d, voltage = %d, pwm = %d" % (fanid, cfg.vlt.value, cfg.pwm.value)
+
+       def setVoltage_PWM_Standby(self):
+               for fanid in range(self.getFanCount()):
+                       cfg = self.getConfig(fanid)
+                       self.setVoltage(fanid, cfg.vlt_standby.value)
+                       self.setPWM(fanid, cfg.pwm_standby.value)
+                       print "[FanControl]: setting fan values (standby mode): fanid = %d, voltage = %d, pwm = %d" % (fanid, cfg.vlt_standby.value, cfg.pwm_standby.value)
+
+       def getRecordEvent(self, recservice, event):
+               recordings = len(NavigationInstance.instance.getRecordings())
+               if event == iRecordableService.evEnd:
+                       if recordings == 0:
+                               self.setVoltage_PWM_Standby()
+               elif event == iRecordableService.evStart:
+                       if recordings == 1:
+                               self.setVoltage_PWM()
+
+       def leaveStandby(self):
+               NavigationInstance.instance.record_event.remove(self.getRecordEvent)
+               recordings = NavigationInstance.instance.getRecordings()
+               if not recordings:
+                       self.setVoltage_PWM()
 
        def standbyCounterChanged(self, configElement):
                from Screens.Standby import inStandby
                inStandby.onClose.append(self.leaveStandby)
-               for fanid in range(self.getFanCount()):
-                       self.setVoltage(fanid, 0)
-                       self.setPWM(fanid, 0)
+               recordings = NavigationInstance.instance.getRecordings()
+               NavigationInstance.instance.record_event.append(self.getRecordEvent)
+               if not recordings:
+                       self.setVoltage_PWM_Standby()
 
        def createConfig(self):
                def setVlt(fancontrol, fanid, configElement):
@@ -35,12 +62,14 @@ class FanControl:
                config.fans = ConfigSubList()
                for fanid in range(self.getFanCount()):
                        fan = ConfigSubsection()
-                       fan.vlt = ConfigSlider(default = 16, increment = 5, limits = (0, 255))
+                       fan.vlt = ConfigSlider(default = 15, increment = 5, limits = (0, 255))
                        fan.pwm = ConfigSlider(default = 0, increment = 5, limits = (0, 255))
+                       fan.vlt_standby = ConfigSlider(default = 5, increment = 5, limits = (0, 255))
+                       fan.pwm_standby = ConfigSlider(default = 0, increment = 5, limits = (0, 255))
                        fan.vlt.addNotifier(boundFunction(setVlt, self, fanid))
                        fan.pwm.addNotifier(boundFunction(setPWM, self, fanid))
                        config.fans.append(fan)
-                       
+       
        def getConfig(self, fanid):
                return config.fans[fanid]
        
@@ -85,4 +114,4 @@ class FanControl:
                f.write("%x" % value)
                f.close()
        
-fancontrol = FanControl()
\ No newline at end of file
+fancontrol = FanControl()
index 03f574f..e8e612a 100755 (executable)
@@ -166,7 +166,7 @@ class Harddisk:
                lines = mounts.readlines()
                mounts.close()
 
-               cmd = "/bin/umount"
+               cmd = "umount"
 
                for line in lines:
                        parts = line.strip().split(" ")
@@ -177,12 +177,12 @@ class Harddisk:
                return (res >> 8)
 
        def createPartition(self):
-               cmd = 'printf "0,\n;\n;\n;\ny\n" | /sbin/sfdisk -f ' + self.disk_path
+               cmd = 'printf "0,\n;\n;\n;\ny\n" | sfdisk -f ' + self.disk_path
                res = system(cmd)
                return (res >> 8)
 
        def mkfs(self):
-               cmd = "/sbin/mkfs.ext3 "
+               cmd = "mkfs.ext3 "
                if self.diskSize() > 4 * 1024:
                        cmd += "-T largefile "
                cmd += "-m0 -O dir_index " + self.partitionPath("1")
@@ -202,7 +202,7 @@ class Harddisk:
                for line in lines:
                        parts = line.strip().split(" ")
                        if path.realpath(parts[0]) == self.partitionPath("1"):
-                               cmd = "/bin/mount -t ext3 " + parts[0]
+                               cmd = "mount -t ext3 " + parts[0]
                                res = system(cmd)
                                break
 
@@ -218,7 +218,7 @@ class Harddisk:
        def fsck(self):
                # We autocorrect any failures
                # TODO: we could check if the fs is actually ext3
-               cmd = "/sbin/fsck.ext3 -f -p " + self.partitionPath("1")
+               cmd = "fsck.ext3 -f -p " + self.partitionPath("1")
                res = system(cmd)
                return (res >> 8)
 
@@ -226,7 +226,7 @@ class Harddisk:
                part = self.partitionPath(n)
 
                if access(part, 0):
-                       cmd = '/bin/dd bs=512 count=3 if=/dev/zero of=' + part
+                       cmd = 'dd bs=512 count=3 if=/dev/zero of=' + part
                        res = system(cmd)
                else:
                        res = 0
old mode 100644 (file)
new mode 100755 (executable)
index 3c3bd7a..d675ca3
-from config import config, ConfigSlider, ConfigSubsection
+# coding: utf-8
+from config import config, configfile, ConfigSlider, ConfigSubsection, ConfigYesNo, ConfigText
+
+import struct, sys, time, errno
+from fcntl import ioctl
+from os import path as os_path, listdir, open as os_open, close as os_close, write as os_write, read as os_read, O_RDWR, O_NONBLOCK
+
+# asm-generic/ioctl.h
+IOC_NRBITS = 8L
+IOC_TYPEBITS = 8L
+IOC_SIZEBITS = 13L
+IOC_DIRBITS = 3L
+
+IOC_NRSHIFT = 0L
+IOC_TYPESHIFT = IOC_NRSHIFT+IOC_NRBITS
+IOC_SIZESHIFT = IOC_TYPESHIFT+IOC_TYPEBITS
+IOC_DIRSHIFT = IOC_SIZESHIFT+IOC_SIZEBITS
+
+IOC_READ = 2L
+
+def EVIOCGNAME(length):
+       return (IOC_READ<<IOC_DIRSHIFT)|(length<<IOC_SIZESHIFT)|(0x45<<IOC_TYPESHIFT)|(0x06<<IOC_NRSHIFT)
+
 
 class inputDevices:
+
+       def __init__(self):
+               self.Devices = {}
+               self.currentDevice = ""
+               self.getInputDevices()
+       
+       def getInputDevices(self):
+               devices = listdir("/dev/input/")
+
+               for evdev in devices:
+                       try:
+                               buffer = "\0"*512
+                               self.fd = os_open("/dev/input/" + evdev, O_RDWR | O_NONBLOCK)
+                               self.name = ioctl(self.fd, EVIOCGNAME(256), buffer)
+                               self.name = self.name[:self.name.find("\0")]
+                               os_close(self.fd)
+                       except (IOError,OSError), err:
+                               print '[iInputDevices] getInputDevices  <ERROR: ioctl(EVIOCGNAME): ' + str(err) + ' >'
+                               self.name = None
+                       
+                       if self.name:
+                               if self.name == 'dreambox front panel':
+                                       continue
+                               if self.name == "dreambox advanced remote control (native)" and config.misc.rcused.value != 0:
+                                       continue
+                               if self.name == "dreambox remote control (native)" and config.misc.rcused.value == 0:
+                                       continue
+                               self.Devices[evdev] = {'name': self.name, 'type': self.getInputDeviceType(self.name),'enabled': False, 'configuredName': None }
+       
+
+       def getInputDeviceType(self,name):
+               if name.find("remote control") != -1:
+                       return "remote"
+               elif name.find("keyboard") != -1:
+                       return "keyboard"
+               elif name.find("mouse") != -1:
+                       return "mouse"
+               else:
+                       print "Unknown device type:",name
+                       return None
+                       
+       def getDeviceName(self, x):
+               if x in self.Devices.keys():
+                       return self.Devices[x].get("name", x)
+               else:
+                       return "Unknown device name"
+
+       def getDeviceList(self):
+               return sorted(self.Devices.iterkeys())
+
+       def getDefaultRCdeviceName(self):
+               if config.misc.rcused.value == 0:
+                       for device in self.Devices.iterkeys():
+                               if self.Devices[device]["name"] == "dreambox advanced remote control (native)":
+                                       return device
+               else:
+                       for device in self.Devices.iterkeys():
+                               if self.Devices[device]["name"] == "dreambox remote control (native)":
+                                       return device
+
+       def setDeviceAttribute(self, device, attribute, value):
+               #print "[iInputDevices] setting for device", device, "attribute", attribute, " to value", value
+               if self.Devices.has_key(device):
+                       self.Devices[device][attribute] = value
+                       
+       def getDeviceAttribute(self, device, attribute):
+               if self.Devices.has_key(device):
+                       if self.Devices[device].has_key(attribute):
+                               return self.Devices[device][attribute]
+               return None
+                       
+       def setEnabled(self, device, value):
+               oldval = self.getDeviceAttribute(device, 'enabled')
+               #print "[iInputDevices] setEnabled for device %s to %s from %s" % (device,value,oldval)
+               self.setDeviceAttribute(device, 'enabled', value)
+               if oldval is True and value is False:
+                       self.setDefaults(device)
+
+       def setName(self, device, value):
+               #print "[iInputDevices] setName for device %s to %s" % (device,value)
+               self.setDeviceAttribute(device, 'configuredName', value)
+               
+       #struct input_event {
+       #       struct timeval time;    -> ignored
+       #       __u16 type;             -> EV_REP (0x14)
+       #       __u16 code;             -> REP_DELAY (0x00) or REP_PERIOD (0x01)
+       #       __s32 value;            -> DEFAULTS: 700(REP_DELAY) or 100(REP_PERIOD)
+       #}; -> size = 16
+
+       def setDefaults(self, device):
+               print "[iInputDevices] setDefaults for device %s" % (device)
+               self.setDeviceAttribute(device, 'configuredName', None)
+               event_repeat = struct.pack('iihhi', 0, 0, 0x14, 0x01, 100)
+               event_delay = struct.pack('iihhi', 0, 0, 0x14, 0x00, 700)
+               fd = os_open("/dev/input/" + device, O_RDWR)
+               os_write(fd, event_repeat)
+               os_write(fd, event_delay)
+               os_close(fd)
+
+       def setRepeat(self, device, value): #REP_PERIOD
+               if self.getDeviceAttribute(device, 'enabled') == True:
+                       print "[iInputDevices] setRepeat for device %s to %d ms" % (device,value)
+                       event = struct.pack('iihhi', 0, 0, 0x14, 0x01, int(value))
+                       fd = os_open("/dev/input/" + device, O_RDWR)
+                       os_write(fd, event)
+                       os_close(fd)
+
+       def setDelay(self, device, value): #REP_DELAY
+               if self.getDeviceAttribute(device, 'enabled') == True:
+                       print "[iInputDevices] setDelay for device %s to %d ms" % (device,value)
+                       event = struct.pack('iihhi', 0, 0, 0x14, 0x00, int(value))
+                       fd = os_open("/dev/input/" + device, O_RDWR)
+                       os_write(fd, event)
+                       os_close(fd)
+
+
+class InitInputDevices:
+       
        def __init__(self):
-               pass
-       def setRepeat(self, value):
-               #print "setup rc repeat"
-               pass
-       def setDelay(self, value):
-               #print "setup rc delay"
-               pass
-
-def InitInputDevices():
-       config.inputDevices = ConfigSubsection();
-       config.inputDevices.repeat = ConfigSlider(default=5, limits=(1, 10))
-       config.inputDevices.delay = ConfigSlider(default=4, limits=(1, 10))
-
-       #this instance anywhere else needed?    
-       iDevices = inputDevices();      
+               self.currentDevice = ""
+               self.createConfig()
        
-       def inputDevicesRepeatChanged(configElement):
-               iDevices.setRepeat(configElement.value);
+       def createConfig(self, *args):
+               config.inputDevices = ConfigSubsection()
+               for device in sorted(iInputDevices.Devices.iterkeys()):
+                       self.currentDevice = device
+                       #print "[InitInputDevices] -> creating config entry for device: %s -> %s  " % (self.currentDevice, iInputDevices.Devices[device]["name"])
+                       self.setupConfigEntries(self.currentDevice)
+                       self.currentDevice = ""
+
+       def inputDevicesEnabledChanged(self,configElement):
+               if self.currentDevice != "" and iInputDevices.currentDevice == "":
+                       iInputDevices.setEnabled(self.currentDevice, configElement.value)
+               elif iInputDevices.currentDevice != "":
+                       iInputDevices.setEnabled(iInputDevices.currentDevice, configElement.value)
+
+       def inputDevicesNameChanged(self,configElement):
+               if self.currentDevice != "" and iInputDevices.currentDevice == "":
+                       iInputDevices.setName(self.currentDevice, configElement.value)
+                       if configElement.value != "":
+                               devname = iInputDevices.getDeviceAttribute(self.currentDevice, 'name')
+                               if devname != configElement.value:
+                                       cmd = "config.inputDevices." + self.currentDevice + ".enabled.value = False"
+                                       exec (cmd)
+                                       cmd = "config.inputDevices." + self.currentDevice + ".enabled.save()"
+                                       exec (cmd)
+               elif iInputDevices.currentDevice != "":
+                       iInputDevices.setName(iInputDevices.currentDevice, configElement.value)
+
+       def inputDevicesRepeatChanged(self,configElement):
+               if self.currentDevice != "" and iInputDevices.currentDevice == "":
+                       iInputDevices.setRepeat(self.currentDevice, configElement.value)
+               elif iInputDevices.currentDevice != "":
+                       iInputDevices.setRepeat(iInputDevices.currentDevice, configElement.value)
+               
+       def inputDevicesDelayChanged(self,configElement):
+               if self.currentDevice != "" and iInputDevices.currentDevice == "":
+                       iInputDevices.setDelay(self.currentDevice, configElement.value)
+               elif iInputDevices.currentDevice != "":
+                       iInputDevices.setDelay(iInputDevices.currentDevice, configElement.value)
+
+       def setupConfigEntries(self,device):
+               cmd = "config.inputDevices." + device + " = ConfigSubsection()"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".enabled = ConfigYesNo(default = False)"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".enabled.addNotifier(self.inputDevicesEnabledChanged,config.inputDevices." + device + ".enabled)"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + '.name = ConfigText(default="")'
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".name.addNotifier(self.inputDevicesNameChanged,config.inputDevices." + device + ".name)"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".repeat = ConfigSlider(default=100, increment = 10, limits=(0, 500))"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".repeat.addNotifier(self.inputDevicesRepeatChanged,config.inputDevices." + device + ".repeat)"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".delay = ConfigSlider(default=700, increment = 100, limits=(0, 5000))"
+               exec (cmd)
+               cmd = "config.inputDevices." + device + ".delay.addNotifier(self.inputDevicesDelayChanged,config.inputDevices." + device + ".delay)"
+               exec (cmd)
 
-       def inputDevicesDelayChanged(configElement):
-               iDevices.setDelay(configElement.value);
 
-       # this will call the "setup-val" initial
-       config.inputDevices.repeat.addNotifier(inputDevicesRepeatChanged);
-       config.inputDevices.delay.addNotifier(inputDevicesDelayChanged);
+iInputDevices = inputDevices()
index 4b0213d..e980cb8 100755 (executable)
@@ -4,6 +4,7 @@ from socket import *
 from enigma import eConsoleAppContainer
 from Components.Console import Console
 from Components.PluginComponent import plugins
+from Components.About import about
 from Plugins.Plugin import PluginDescriptor
 
 class Network:
@@ -14,7 +15,7 @@ class Network:
                self.NetworkState = 0
                self.DnsState = 0
                self.nameservers = []
-               self.ethtool_bin = "/usr/sbin/ethtool"
+               self.ethtool_bin = "ethtool"
                self.container = eConsoleAppContainer()
                self.Console = Console()
                self.LinkConsole = Console()
@@ -26,6 +27,9 @@ class Network:
                self.DnsConsole = Console()
                self.PingConsole = Console()
                self.config_ready = None
+               self.friendlyNames = {}
+               self.lan_interfaces = []
+               self.wlan_interfaces = []
                self.getInterfaces()
 
        def onRemoteRootFS(self):
@@ -309,13 +313,49 @@ class Network:
                return len(self.ifaces)
 
        def getFriendlyAdapterName(self, x):
-               # maybe this needs to be replaced by an external list.
-               friendlyNames = {
-                       "eth0": _("Integrated Ethernet"),
-                       "wlan0": _("Wireless"),
-                       "ath0": _("Integrated Wireless")
-               }
-               return friendlyNames.get(x, x) # when we have no friendly name, use adapter name
+               if x in self.friendlyNames.keys():
+                       return self.friendlyNames.get(x, x)
+               else:
+                       self.friendlyNames[x] = self.getFriendlyAdapterNaming(x)
+                       return self.friendlyNames.get(x, x) # when we have no friendly name, use adapter name
+
+       def getFriendlyAdapterNaming(self, iface):
+               if iface.startswith('eth'):
+                       if iface not in self.lan_interfaces and len(self.lan_interfaces) == 0:
+                               self.lan_interfaces.append(iface)
+                               return _("LAN connection")
+                       elif iface not in self.lan_interfaces and len(self.lan_interfaces) >= 1:
+                               self.lan_interfaces.append(iface)
+                               return _("LAN connection") + " " + str(len(self.lan_interfaces))
+               else:
+                       if iface not in self.wlan_interfaces and len(self.wlan_interfaces) == 0:
+                               self.wlan_interfaces.append(iface)
+                               return _("WLAN connection")
+                       elif iface not in self.wlan_interfaces and len(self.wlan_interfaces) >= 1:
+                               self.wlan_interfaces.append(iface)
+                               return _("WLAN connection") + " " + str(len(self.wlan_interfaces))
+
+       def getFriendlyAdapterDescription(self, iface):
+               if iface == 'eth0':
+                       return _("Internal LAN adapter.")
+               else:
+                       classdir = "/sys/class/net/" + iface + "/device/"
+                       driverdir = "/sys/class/net/" + iface + "/device/driver/"
+                       if os_path.exists(classdir):
+                               files = listdir(classdir)
+                               if 'driver' in files:
+                                       if os_path.realpath(driverdir).endswith('ath_pci'):
+                                               return _("Atheros")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") 
+                                       elif os_path.realpath(driverdir).endswith('zd1211b'):
+                                               return _("Zydas")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") 
+                                       elif os_path.realpath(driverdir).endswith('rt73'):
+                                               return _("Ralink")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") 
+                                       elif os_path.realpath(driverdir).endswith('rt73usb'):
+                                               return _("Ralink")+ " " + str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") 
+                                       else:
+                                               return str(os_path.basename(os_path.realpath(driverdir))) + " " + _("WLAN adapter.") 
+                               else:
+                                       return _("Unknown network adapter.")
 
        def getAdapterName(self, iface):
                return iface
@@ -569,24 +609,39 @@ class Network:
                                if callback is not None:
                                        callback(True)
 
-       def detectWlanModule(self):
+       def detectWlanModule(self, iface = None):
                self.wlanmodule = None
-               rt73_dir = "/sys/bus/usb/drivers/rt73/"
-               zd1211b_dir = "/sys/bus/usb/drivers/zd1211b/"
-               madwifi_dir = "/sys/bus/pci/drivers/ath_pci/"
-               if os_path.exists(madwifi_dir):
-                       files = listdir(madwifi_dir)
-                       if len(files) >= 1:
-                               self.wlanmodule = 'madwifi'
-               if os_path.exists(rt73_dir):
-                       rtfiles = listdir(rt73_dir)
-                       if len(rtfiles) == 2:
-                               self.wlanmodule = 'ralink'
-               if os_path.exists(zd1211b_dir):
-                       zdfiles = listdir(zd1211b_dir)
-                       if len(zdfiles) == 1:
-                               self.wlanmodule = 'zydas'
-               return self.wlanmodule
+               classdir = "/sys/class/net/" + iface + "/device/"
+               driverdir = "/sys/class/net/" + iface + "/device/driver/"
+               if os_path.exists(classdir):
+                       classfiles = listdir(classdir)
+                       driver_found = False
+                       nl80211_found = False
+                       for x in classfiles:
+                               if x == 'driver':
+                                       driver_found = True
+                               if x.startswith('ieee80211:'):
+                                       nl80211_found = True
+
+                       if driver_found and nl80211_found:
+                               #print about.getKernelVersionString()
+                               self.wlanmodule = "nl80211"
+                       else:
+                               if driver_found and not nl80211_found:
+                                       driverfiles = listdir(driverdir)
+                                       if os_path.realpath(driverdir).endswith('ath_pci'):
+                                               if len(driverfiles) >= 1:
+                                                       self.wlanmodule = 'madwifi'
+                                       if os_path.realpath(driverdir).endswith('rt73'):
+                                               if len(driverfiles) == 2 or len(driverfiles) == 5:
+                                                       self.wlanmodule = 'ralink'                                      
+                                       if os_path.realpath(driverdir).endswith('zd1211b'):
+                                               if len(driverfiles) == 1 or len(driverfiles) == 5:
+                                                       self.wlanmodule = 'zydas'
+                       if self.wlanmodule is None:
+                               self.wlanmodule = "wext"
+                       print 'Using "%s" as wpa-supplicant driver' % (self.wlanmodule)
+                       return self.wlanmodule
        
        def calc_netmask(self,nmask):
                from struct import pack, unpack
index 00d0609..a69df00 100644 (file)
@@ -1,4 +1,5 @@
 from Tools.HardwareInfo import HardwareInfo
+from Tools.BoundFunction import boundFunction
 
 from config import config, ConfigSubsection, ConfigSelection, ConfigFloat, \
        ConfigSatlist, ConfigYesNo, ConfigInteger, ConfigSubList, ConfigNothing, \
@@ -13,6 +14,7 @@ from enigma import eDVBSatelliteEquipmentControl as secClass, \
 
 from time import localtime, mktime
 from datetime import datetime
+from Tools.BoundFunction import boundFunction
 
 def getConfigSatlist(orbpos, satlist):
        default_orbpos = None
@@ -444,7 +446,7 @@ class SecConfigure:
                self.update()
 
 class NIM(object):
-       def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None):
+       def __init__(self, slot, type, description, has_outputs = True, internally_connectable = None, multi_type = {}):
                self.slot = slot
 
                if type not in ("DVB-S", "DVB-C", "DVB-T", "DVB-S2", None):
@@ -455,6 +457,7 @@ class NIM(object):
                self.description = description
                self.has_outputs = has_outputs
                self.internally_connectable = internally_connectable
+               self.multi_type = multi_type
 
        def isCompatible(self, what):
                compatible = {
@@ -466,6 +469,9 @@ class NIM(object):
                        }
                return what in compatible[self.type]
        
+       def getType(self):
+               return self.type
+       
        def connectableTo(self):
                connectable = {
                                "DVB-S": ("DVB-S", "DVB-S2"),
@@ -491,6 +497,13 @@ class NIM(object):
        
        def internallyConnectableTo(self):
                return self.internally_connectable
+       
+       def isMultiType(self):
+               return (len(self.multi_type) > 0)
+       
+       # returns dict {<slotid>: <type>}
+       def getMultiTypeList(self):
+               return self.multi_type
 
        slot_id = property(getSlotID)
 
@@ -636,7 +649,15 @@ class NimManager:
                                entries[current_slot]["has_outputs"] = (input == "yes")
                        elif line.strip().startswith("Internally_Connectable:"):
                                input = int(line.strip()[len("Internally_Connectable:") + 1:])
-                               entries[current_slot]["internally_connectable"] = input 
+                               entries[current_slot]["internally_connectable"] = input
+                       elif  line.strip().startswith("Mode"):
+                               # "Mode 0: DVB-T" -> ["Mode 0", " DVB-T"]
+                               split = line.strip().split(":")
+                               # "Mode 0" -> ["Mode, "0"]
+                               split2 = split[0].split(" ")
+                               modes = entries[current_slot].get("multi_type", {})
+                               modes[split2[1]] = split[1].strip()
+                               entries[current_slot]["multi_type"] = modes
                        elif line.strip().startswith("empty"):
                                entries[current_slot]["type"] = None
                                entries[current_slot]["name"] = _("N/A")
@@ -650,12 +671,17 @@ class NimManager:
                                entry["has_outputs"] = True
                        if not (entry.has_key("internally_connectable")):
                                entry["internally_connectable"] = None
-                       self.nim_slots.append(NIM(slot = id, description = entry["name"], type = entry["type"], has_outputs = entry["has_outputs"], internally_connectable = entry["internally_connectable"]))
+                       if not (entry.has_key("multi_type")):
+                               entry["multi_type"] = {}
+                       self.nim_slots.append(NIM(slot = id, description = entry["name"], type = entry["type"], has_outputs = entry["has_outputs"], internally_connectable = entry["internally_connectable"], multi_type = entry["multi_type"]))
 
        def hasNimType(self, chktype):
                for slot in self.nim_slots:
                        if slot.isCompatible(chktype):
                                return True
+                       for type in slot.getMultiTypeList().values():
+                               if chktype == type:
+                                       return True
                return False
        
        def getNimType(self, slotid):
@@ -663,6 +689,9 @@ class NimManager:
        
        def getNimDescription(self, slotid):
                return self.nim_slots[slotid].friendly_full_description
+       
+       def getNimName(self, slotid):
+               return self.nim_slots[slotid].description
 
        def getNimListOfType(self, type, exception = -1):
                # returns a list of indexes for NIMs compatible to the given type, except for 'exception'
@@ -938,12 +967,18 @@ def InitSecParams():
 # the configElement should be only visible when diseqc 1.2 is disabled
 
 def InitNimManager(nimmgr):
-       InitSecParams()
        hw = HardwareInfo()
+       addNimConfig = False
+       try:
+               config.Nims
+       except:
+               addNimConfig = True
 
-       config.Nims = ConfigSubList()
-       for x in range(len(nimmgr.nim_slots)):
-               config.Nims.append(ConfigSubsection())
+       if addNimConfig:
+               InitSecParams()
+               config.Nims = ConfigSubList()
+               for x in range(len(nimmgr.nim_slots)):
+                       config.Nims.append(ConfigSubsection())
 
        lnb_choices = {
                "universal_lnb": _("Universal LNB"),
@@ -1133,7 +1168,7 @@ def InitNimManager(nimmgr):
                        section.latitude = ConfigFloat(default = [50,767], limits = [(0,359),(0,999)])
                        section.latitudeOrientation = ConfigSelection(latitude_orientation_choices, "north")
                        section.powerMeasurement = ConfigYesNo(default=True)
-                       section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
+                       section.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm7025" and 50 or 15, limits=(0, 100))
                        section.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
                        section.fastTurningBegin = ConfigDateTime(default=advanced_lnb_fast_turning_btime, formatstring = _("%H:%M"), increment = 600)
                        section.fastTurningEnd = ConfigDateTime(default=advanced_lnb_fast_turning_etime, formatstring = _("%H:%M"), increment = 600)
@@ -1218,11 +1253,49 @@ def InitNimManager(nimmgr):
                slot_id = configElement.slot_id
                if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
                        open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
-
+                       
+       def tunerTypeChanged(nimmgr, configElement):
+               fe_id = configElement.fe_id
+               print "tunerTypeChanged feid %d to mode %s" % (fe_id, configElement.value)
+               try:
+                       oldvalue = open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "r").readline()
+                       open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write("0")
+               except:
+                       print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
+               frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
+               frontend.closeFrontend()
+               open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
+               frontend.reopenFrontend()
+               try:
+                       open("/sys/module/dvb_core/parameters/dvb_shutdown_timeout", "w").write(oldvalue)
+               except:
+                       print "[info] no /sys/module/dvb_core/parameters/dvb_shutdown_timeout available"
+               nimmgr.enumerateNIMs()
+       
+       empty_slots = 0
+       for slot in nimmgr.nim_slots:
+               x = slot.slot
+               nim = config.Nims[x]
+               addMultiType = False
+               try:
+                       nim.multiType
+               except:
+                       addMultiType = True
+               if slot.isMultiType() and addMultiType:
+                       typeList = []
+                       for id in slot.getMultiTypeList().keys():
+                               type = slot.getMultiTypeList()[id]
+                               typeList.append((id, type))
+                       nim.multiType = ConfigSelection(typeList, "0")
+                       
+                       nim.multiType.fe_id = x - empty_slots
+                       nim.multiType.addNotifier(boundFunction(tunerTypeChanged, nimmgr))
+               
        empty_slots = 0
        for slot in nimmgr.nim_slots:
                x = slot.slot
                nim = config.Nims[x]
+
                if slot.isCompatible("DVB-S"):
                        nim.toneAmplitude = ConfigSelection([("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
                        nim.toneAmplitude.fe_id = x - empty_slots
old mode 100644 (file)
new mode 100755 (executable)
index fe9284d..40dfb2c
@@ -1,4 +1,4 @@
-from config import ConfigNumber, ConfigYesNo, ConfigSubsection, config
+from config import ConfigNumber, ConfigYesNo, ConfigSubsection, ConfigSelection, config
 
 def InitRecordingConfig():
        config.recording = ConfigSubsection();
@@ -8,3 +8,7 @@ def InitRecordingConfig():
        config.recording.margin_after = ConfigNumber(default=0)
        config.recording.debug = ConfigYesNo(default = False)
        config.recording.ascii_filenames = ConfigYesNo(default = False)
+       config.recording.filename_composition = ConfigSelection(default = "standard", choices = [
+               ("standard", _("standard")),
+               ("short", _("Short filenames")),
+               ("long", _("Long filenames")) ] )
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 7a89533..716fe44
@@ -19,6 +19,7 @@ class Listbox(Renderer, object):
                self.__content = None
                self.__wrap_around = False
                self.__selection_enabled = True
+               self.__scrollbarMode = "showOnDemand"
 
        GUI_WIDGET = eListbox
 
@@ -38,6 +39,7 @@ class Listbox(Renderer, object):
                instance.selectionChanged.get().append(self.selectionChanged)
                self.wrap_around = self.wrap_around # trigger
                self.selection_enabled = self.selection_enabled # trigger
+               self.scrollbarMode = self.scrollbarMode # trigger
 
        def preWidgetRemove(self, instance):
                instance.setContent(None)
@@ -76,7 +78,24 @@ class Listbox(Renderer, object):
 
        selection_enabled = property(lambda self: self.__selection_enabled, setSelectionEnabled)
 
+       def setScrollbarMode(self, mode):
+               self.__scrollbarMode = mode
+               if self.instance is not None:
+                       self.instance.setScrollbarMode(int(
+                               { "showOnDemand": 0,
+                                 "showAlways": 1,
+                                 "showNever": 2,
+                               }[mode]))
+
+       scrollbarMode = property(lambda self: self.__scrollbarMode, setScrollbarMode)
+       
        def changed(self, what):
+               if hasattr(self.source, "selectionEnabled"):
+                       self.selection_enabled = self.source.selectionEnabled
+               if hasattr(self.source, "scrollbarMode"):
+                       self.scrollbarMode = self.source.scrollbarMode
+               if len(what) > 1 and isinstance(what[1], str) and what[1] == "style":
+                       return
                self.content = self.source.content
 
        def entry_changed(self, index):
index 1eab32b..6f0670a 100644 (file)
@@ -91,8 +91,9 @@ to generate HTML."""
                return self.__style
 
        def setStyle(self, style):
-               self.__style = style
-               self.changed((self.CHANGED_SPECIFIC, "style"))
+               if self.__style != style:
+                       self.__style = style
+                       self.changed((self.CHANGED_SPECIFIC, "style"))
 
        style = property(getStyle, setStyle)
 
index df94f8a..2e4e757 100644 (file)
@@ -16,6 +16,7 @@ class Job(object):
                self.end = 100
                self.__progress = 0
                self.weightScale = 1
+               self.afterEvent = None
 
                self.state_changed = CList()
 
@@ -370,12 +371,20 @@ class DiskspacePrecondition(Condition):
 class ToolExistsPrecondition(Condition):
        def check(self, task):
                import os
+               
                if task.cmd[0]=='/':
-                       realpath = task.cmd
+                       self.realpath = task.cmd
+                       print "[Task.py][ToolExistsPrecondition] WARNING: usage of absolute paths for tasks should be avoided!" 
+                       return os.access(self.realpath, os.X_OK)
                else:
-                       realpath = task.cwd + '/' + task.cmd
-               self.realpath = realpath
-               return os.access(realpath, os.X_OK)
+                       self.realpath = task.cmd
+                       path = os.environ.get('PATH', '').split(os.pathsep)
+                       path.append(task.cwd + '/')
+                       absolutes = filter(lambda file: os.access(file, os.X_OK), map(lambda directory, file = task.cmd: os.path.join(directory, file), path))
+                       if len(absolutes) > 0:
+                               self.realpath = task.cmd[0]
+                               return True
+               return False 
 
        def getErrorMessage(self, task):
                return _("A required tool (%s) was not found.") % (self.realpath)
index 2a7405d..30097c9 100755 (executable)
@@ -33,12 +33,18 @@ class TimerList(HTMLComponent, GUIComponent, object):
                                                count += 1
                                        flags = flags >> 1
                        if timer.justplay:
-                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.begin)[1]))))
+                               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]))))
+                               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)")))
                        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))))
                else:
                        if timer.justplay:
-                               res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s " + _("(ZAP)")) % (FuzzyTime(timer.begin)))))
+                               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)))))
+                               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)")))
                        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,)))))
 
index 19fb90d..3810292 100644 (file)
@@ -8,6 +8,7 @@ from config import config, ConfigSubsection, ConfigInteger
 profile("VolumeControl")
 #TODO .. move this to a own .py file
 class VolumeControl:
+       instance = None
        """Volume control, handles volUp, volDown, volMute actions and display
        a corresponding dialog"""
        def __init__(self, session):
@@ -16,6 +17,9 @@ class VolumeControl:
                globalActionMap.actions["volumeDown"]=self.volDown
                globalActionMap.actions["volumeMute"]=self.volMute
 
+               assert not VolumeControl.instance, "only one VolumeControl instance is allowed!"
+               VolumeControl.instance = self
+
                config.audio = ConfigSubsection()
                config.audio.volume = ConfigInteger(default = 100, limits = (0, 100))
 
index 471b59e..1afd398 100755 (executable)
@@ -178,7 +178,7 @@ class choicesList(object): # XXX: we might want a better name for this
 
        def __list__(self):
                if self.type == choicesList.LIST_TYPE_LIST:
-                       ret = [not isinstance(x, tuple) and x or x[0] for x in self.choices]
+                       ret = [not isinstance(x, tuple) and x or len(x) > 0 and x[0] or len(x) == 0 and x for x in self.choices]
                else:
                        ret = self.choices.keys()
                return ret or [""]
index aace17c..9e16bfc 100755 (executable)
@@ -1,6 +1,8 @@
 installdir = $(pkglibdir)/python/Plugins/DemoPlugins
 
-SUBDIRS = TestPlugin
+SUBDIRS = TestPlugin TPMDemo
 
 install_PYTHON =       \
-       __init__.py
\ No newline at end of file
+       __init__.py
+
+       
\ No newline at end of file
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am b/lib/python/Plugins/DemoPlugins/TPMDemo/Makefile.am
new file mode 100644 (file)
index 0000000..3ccca98
--- /dev/null
@@ -0,0 +1,5 @@
+installdir = $(LIBDIR)/enigma2/python/Plugins/DemoPlugins/TPMDemo
+
+install_PYTHON = \
+       __init__.py \
+       plugin.py
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/README b/lib/python/Plugins/DemoPlugins/TPMDemo/README
new file mode 100644 (file)
index 0000000..89a972a
--- /dev/null
@@ -0,0 +1 @@
+Please read enigma2/doc/TPM for further instructions on how to integrate this into your own plugins.
\ No newline at end of file
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py b/lib/python/Plugins/DemoPlugins/TPMDemo/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py b/lib/python/Plugins/DemoPlugins/TPMDemo/plugin.py
new file mode 100644 (file)
index 0000000..2c078d3
--- /dev/null
@@ -0,0 +1,87 @@
+from Screens.Screen import Screen
+from Plugins.Plugin import PluginDescriptor
+from enigma import eTPM
+import sha
+
+def bin2long(s):
+       return reduce( lambda x,y:(x<<8L)+y, map(ord, s))
+
+def long2bin(l):
+       res = ""
+       for byte in range(128):
+               res += chr((l >> (1024 - (byte + 1) * 8)) & 0xff)
+       return res
+
+def rsa_pub1024(src, mod):
+       return long2bin(pow(bin2long(src), 65537, bin2long(mod)))
+       
+def decrypt_block(src, mod):
+       if len(src) != 128 and len(src) != 202:
+               return None
+       dest = rsa_pub1024(src[:128], mod)
+       hash = sha.new(dest[1:107])
+       if len(src) == 202:
+               hash.update(src[131:192])       
+       result = hash.digest()
+       if result == dest[107:127]:
+               return dest
+       return None
+
+def validate_cert(cert, key):
+       buf = decrypt_block(cert[8:], key) 
+       if buf is None:
+               return None
+       return buf[36:107] + cert[139:196]
+
+def read_random():
+       try:
+               fd = open("/dev/urandom", "r")
+               buf = fd.read(8)
+               fd.close()
+               return buf
+       except:
+               return None
+
+def main(session, **kwargs):
+       try:
+               device = open("/proc/stb/info/model", "r").readline().strip()
+       except:
+               device = ""     
+       if device != "dm7025":
+               rootkey = ['\x9f', '|', '\xe4', 'G', '\xc9', '\xb4', '\xf4', '#', '&', '\xce', '\xb3', '\xfe', '\xda', '\xc9', 'U', '`', '\xd8', '\x8c', 's', 'o', '\x90', '\x9b', '\\', 'b', '\xc0', '\x89', '\xd1', '\x8c', '\x9e', 'J', 'T', '\xc5', 'X', '\xa1', '\xb8', '\x13', '5', 'E', '\x02', '\xc9', '\xb2', '\xe6', 't', '\x89', '\xde', '\xcd', '\x9d', '\x11', '\xdd', '\xc7', '\xf4', '\xe4', '\xe4', '\xbc', '\xdb', '\x9c', '\xea', '}', '\xad', '\xda', 't', 'r', '\x9b', '\xdc', '\xbc', '\x18', '3', '\xe7', '\xaf', '|', '\xae', '\x0c', '\xe3', '\xb5', '\x84', '\x8d', '\r', '\x8d', '\x9d', '2', '\xd0', '\xce', '\xd5', 'q', '\t', '\x84', 'c', '\xa8', ')', '\x99', '\xdc', '<', '"', 'x', '\xe8', '\x87', '\x8f', '\x02', ';', 'S', 'm', '\xd5', '\xf0', '\xa3', '_', '\xb7', 'T', '\t', '\xde', '\xa7', '\xf1', '\xc9', '\xae', '\x8a', '\xd7', '\xd2', '\xcf', '\xb2', '.', '\x13', '\xfb', '\xac', 'j', '\xdf', '\xb1', '\x1d', ':', '?']
+               
+               etpm = eTPM()
+               l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
+               if l2cert is None:
+                       print "l2cert not found"
+                       return
+       
+               l2key = validate_cert(l2cert, rootkey)
+               if l2key is None:
+                       print "l2cert invalid"
+                       return
+               
+               l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
+               if l3cert is None:
+                       print "l3cert not found (can be fixed by running the genuine dreambox plugin and running the offered update)"
+                       return
+               
+               l3key = validate_cert(l3cert, l2key)
+               if l3key is None:
+                       print "l3cert invalid"
+                       return
+               
+               rnd = read_random()
+               if rnd is None:
+                       print "random error"
+                       return
+               val = etpm.challenge(rnd)
+               result = decrypt_block(val, l3key)
+       if device == "dm7025" or result[80:88] == rnd:
+               print "successfully finished the tpm test"
+                       # would start your plugin here
+
+def Plugins(**kwargs):
+       return [PluginDescriptor(name = "TPM Demo", description = _("A demo plugin for TPM usage."), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = main),
+               PluginDescriptor(name = "TPM Demo", description = _("A demo plugin for TPM usage."), icon = "plugin.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc = main)]
+       
\ No newline at end of file
index ee18898..e926e3f 100755 (executable)
@@ -1,4 +1,4 @@
-installdir = $(datadir)/meta/
+installdir = $(datadir)/meta
 
 dist_install_DATA = plugin_cutlisteditor.xml
 
index 1431caf..7132ba0 100755 (executable)
@@ -2,23 +2,14 @@
          <prerequisites>
                     <tag type="Recording" />
          </prerequisites>
-          <info language="en">
+          <info>
                     <author>Dream Multimedia</author>
                     <name>CutListEditor</name>
                     <packagename>enigma2-plugin-extensions-cutlisteditor</packagename>
-                    <shortdescription>CutListEditor allows you to edit your movies.</shortdescription>
+                    <shortdescription>CutListEditor allows you to edit your movies</shortdescription>
                     <description>CutListEditor allows you to edit your movies.\nSeek to the start of the stuff you want to cut away. Press OK, select 'start cut'.\nThen seek to the end, press OK, select 'end cut'. That's it.</description>
                     <screenshot src="http://www.dreamboxupdate.com/preview/plugin_cutlisteditor.jpg" />
           </info>
-          <info language="de">
-                    <author>Dream Multimedia</author>
-                    <name>Schnitteditor</name>
-                    <packagename>enigma2-plugin-extensions-cutlisteditor</packagename>
-                    <shortdescription>Mit dem Schnitteditor können Sie Ihre Aufnahmen schneiden.</shortdescription>
-                    <description>Mit dem Schnitteditor können Sie Ihre Aufnahmen schneiden.\nSpulen Sie zum Anfang des zu schneidenden Teils der Aufnahme. Drücken Sie dann OK und wählen Sie: 'start cut'.\nDann spulen Sie zum Ende, drücken OK und wählen 'end cut'. Das ist alles.
-                    </description>
-                    <screenshot src="http://www.dreamboxupdate.com/preview/plugin_cutlisteditor.jpg" />
-          </info>
          <files type="package"> <!-- without version, without .ipk -->
                <file type="package" name="enigma2-plugin-extensions-cutlisteditor" />
          </files>
index 8367246..7f755db 100644 (file)
@@ -1,5 +1,7 @@
 from Tools.Directories import fileExists
 from Components.config import config, ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence, ConfigSubList
+import DVDTitle
+import xml.dom.minidom
 
 class ConfigColor(ConfigSequence):
        def __init__(self, default = [128,128,128]):
@@ -10,7 +12,10 @@ class ConfigFilename(ConfigText):
                ConfigText.__init__(self, default = "", fixed_size = True, visible_width = False)
 
        def getMulti(self, selected):
-               filename = (self.text.rstrip("/").rsplit("/",1))[1].encode("utf-8")[:40] + " "
+               if self.text == "":
+                       return ("mtext"[1-selected:], "", 0)
+               cut_len = min(len(self.text),40)
+               filename = (self.text.rstrip("/").rsplit("/",1))[1].encode("utf-8")[:cut_len] + " "
                if self.allmarked:
                        mark = range(0, len(filename))
                else:
@@ -34,10 +39,11 @@ class DVDProject:
                self.settings.vmgm = ConfigFilename()
                self.filekeys = ["vmgm", "isopath", "menutemplate"]
                self.menutemplate = MenuTemplate()
+               self.error = ""
+               self.session = None
 
        def addService(self, service):
-               import DVDTitle
-               title = DVDTitle.DVDTitle()
+               title = DVDTitle.DVDTitle(self)
                title.addService(service)
                self.titles.append(title)
                return title
@@ -100,47 +106,78 @@ class DVDProject:
                return ret
 
        def loadProject(self, filename):
-               import xml.dom.minidom
-               try:
+               #try:
                        if not fileExists(filename):
                                self.error = "xml file not found!"
-                               raise AttributeError
-                       else:
-                               self.error = ""
+                               #raise AttributeError
                        file = open(filename, "r")
                        data = file.read().decode("utf-8").replace('&',"&amp;").encode("ascii",'xmlcharrefreplace')
                        file.close()
                        projectfiledom = xml.dom.minidom.parseString(data)
-                       for project in projectfiledom.childNodes[0].childNodes:
-                         if project.nodeType == xml.dom.minidom.Element.nodeType:
-                           if project.tagName == 'settings':
-                               i = 0
-                               if project.attributes.length < len(self.settings.dict())-1:
-                                       self.error = "project attributes missing"
-                                       raise AttributeError
-                               while i < project.attributes.length:
-                                       item = project.attributes.item(i)
-                                       key = item.name.encode("utf-8")
-                                       try:
-                                               val = eval(item.nodeValue)
-                                       except (NameError, SyntaxError):
-                                               val = item.nodeValue.encode("utf-8")
-                                       try:
-                                               self.settings.dict()[key].setValue(val)
-                                       except (KeyError):
-                                               self.error = "unknown attribute '%s'" % (key)
-                                               raise AttributeError
-                                       i += 1
+                       for node in projectfiledom.childNodes[0].childNodes:
+                         print "node:", node
+                         if node.nodeType == xml.dom.minidom.Element.nodeType:
+                           if node.tagName == 'settings':
+                               self.xmlAttributesToConfig(node, self.settings)
+                           elif node.tagName == 'titles':
+                               self.xmlGetTitleNodeRecursive(node)
+                               
                        for key in self.filekeys:
                                val = self.settings.dict()[key].getValue()
                                if not fileExists(val):
                                        self.error += "\n%s '%s' not found" % (key, val)
-                       if len(self.error):
-                               raise AttributeError
+               #except AttributeError:
+                       #print "loadProject AttributeError", self.error
+                       #self.error += (" in project '%s'") % (filename)
+                       #return False
+                       return True
+
+       def xmlAttributesToConfig(self, node, config):
+               try:
+                       i = 0
+                       #if node.attributes.length < len(config.dict())-1:
+                               #self.error = "project attributes missing"
+                               #raise AttributeError
+                       while i < node.attributes.length:
+                               item = node.attributes.item(i)
+                               key = item.name.encode("utf-8")
+                               try:
+                                       val = eval(item.nodeValue)
+                               except (NameError, SyntaxError):
+                                       val = item.nodeValue.encode("utf-8")
+                               try:
+                                       print "config[%s].setValue(%s)" % (key, val)
+                                       config.dict()[key].setValue(val)
+                               except (KeyError):
+                                       self.error = "unknown attribute '%s'" % (key)
+                                       print "KeyError", self.error
+                                       raise AttributeError
+                               i += 1
                except AttributeError:
-                       self.error += (" in project '%s'") % (filename)
+                       self.error += (" XML attribute error '%s'") % node.toxml()
                        return False
-               return True
+
+       def xmlGetTitleNodeRecursive(self, node, title_idx = -1):
+               print "[xmlGetTitleNodeRecursive]", title_idx, node
+               print node.childNodes
+               for subnode in node.childNodes:
+                 print "xmlGetTitleNodeRecursive subnode:", subnode
+                 if subnode.nodeType == xml.dom.minidom.Element.nodeType:
+                   if subnode.tagName == 'title':
+                       title_idx += 1
+                       title = DVDTitle.DVDTitle(self)
+                       self.titles.append(title)
+                       self.xmlGetTitleNodeRecursive(subnode, title_idx)
+                   if subnode.tagName == 'path':
+                       print "path:", subnode.firstChild.data
+                       filename = subnode.firstChild.data
+                       self.titles[title_idx].addFile(filename.encode("utf-8"))
+                   if subnode.tagName == 'properties':
+                       self.xmlAttributesToConfig(node, self.titles[title_idx].properties)
+                   if subnode.tagName == 'audiotracks':
+                       self.xmlGetTitleNodeRecursive(subnode, title_idx)
+                   if subnode.tagName == 'audiotrack':
+                       print "audiotrack...", subnode.toxml()
 
        def getSize(self):
                totalsize = 0
@@ -187,6 +224,7 @@ class MenuTemplate(DVDProject):
                self.filekeys = ["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"]
                from TitleProperties import languageChoices
                self.settings.menulang = ConfigSelection(choices = languageChoices.choices, default=languageChoices.choices[1][0])
+               self.error = ""
 
        def loadTemplate(self, filename):
                ret = DVDProject.loadProject(self, filename)
index 660005e..6dff00d 100644 (file)
@@ -1,4 +1,5 @@
 from Components.config import config, ConfigSubsection, ConfigSubList, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence, ConfigYesNo
+import TitleCutter
 
 class ConfigFixedText(ConfigText):
        def __init__(self, text, visible_width=60):
@@ -7,17 +8,17 @@ class ConfigFixedText(ConfigText):
                pass
 
 class DVDTitle:
-       def __init__(self):
+       def __init__(self, project):
                self.properties = ConfigSubsection()
                self.properties.menutitle = ConfigText(fixed_size = False, visible_width = 80)
                self.properties.menusubtitle = ConfigText(fixed_size = False, visible_width = 80)
-               self.DVBname = _("Title")
-               self.DVBdescr = _("Description")
-               self.DVBchannel = _("Channel")
                self.properties.aspect = ConfigSelection(choices = [("4:3", _("4:3")), ("16:9", _("16:9"))])
                self.properties.widescreen = ConfigSelection(choices = [("nopanscan", "nopanscan"), ("noletterbox", "noletterbox")])
                self.properties.autochapter = ConfigInteger(default = 0, limits = (0, 60))
                self.properties.audiotracks = ConfigSubList()
+               self.DVBname = _("Title")
+               self.DVBdescr = _("Description")
+               self.DVBchannel = _("Channel")
                self.cuesheet = [ ]
                self.source = None
                self.filesize = 0
@@ -27,6 +28,8 @@ class DVDTitle:
                self.chaptermarks = [ ]
                self.timeCreate = None
                self.VideoType = -1
+               self.project = project
+               self.length = 0
 
        def addService(self, service):
                from os import path
@@ -36,7 +39,7 @@ class DVDTitle:
                self.source = service
                serviceHandler = eServiceCenter.getInstance()
                info = serviceHandler.info(service)
-               sDescr = info and " " + info.getInfoString(service, iServiceInformation.sDescription) or ""
+               sDescr = info and info.getInfoString(service, iServiceInformation.sDescription) or ""
                self.DVBdescr = sDescr
                sTimeCreate = info.getInfo(service, iServiceInformation.sTimeCreate)
                if sTimeCreate > 1:
@@ -49,9 +52,20 @@ class DVDTitle:
                self.filesize = path.getsize(self.inputfile)
                self.estimatedDiskspace = self.filesize
                self.length = info.getLength(service)
+                                               
+       def addFile(self, filename):
+               from enigma import eServiceReference
+               ref = eServiceReference(1, 0, filename)
+               self.addService(ref)
+               self.project.session.openWithCallback(self.titleEditDone, TitleCutter.CutlistReader, self)
+       
+       def titleEditDone(self, cutlist):
+               self.initDVDmenuText(len(self.project.titles))
+               self.cuesheet = cutlist
+               self.produceFinalCuesheet()
 
-       def initDVDmenuText(self, project, track):
-               s = project.menutemplate.settings
+       def initDVDmenuText(self, track):
+               s = self.project.menutemplate.settings
                self.properties.menutitle.setValue(self.formatDVDmenuText(s.titleformat.getValue(), track))
                self.properties.menusubtitle.setValue(self.formatDVDmenuText(s.subtitleformat.getValue(), track))
 
index 642a898..b64541b 100644 (file)
@@ -5,7 +5,7 @@ from Screens.MessageBox import MessageBox
 class png2yuvTask(Task):
        def __init__(self, job, inputfile, outputfile):
                Task.__init__(self, job, "Creating menu video")
-               self.setTool("/usr/bin/png2yuv")
+               self.setTool("png2yuv")
                self.args += ["-n1", "-Ip", "-f25", "-j", inputfile]
                self.dumpFile = outputfile
                self.weighting = 15
@@ -21,7 +21,7 @@ class png2yuvTask(Task):
 class mpeg2encTask(Task):
        def __init__(self, job, inputfile, outputfile):
                Task.__init__(self, job, "Encoding menu video")
-               self.setTool("/usr/bin/mpeg2enc")
+               self.setTool("mpeg2enc")
                self.args += ["-f8", "-np", "-a2", "-o", outputfile]
                self.inputFile = inputfile
                self.weighting = 25
@@ -36,7 +36,7 @@ class mpeg2encTask(Task):
 class spumuxTask(Task):
        def __init__(self, job, xmlfile, inputfile, outputfile):
                Task.__init__(self, job, "Muxing buttons into menu")
-               self.setTool("/usr/bin/spumux")
+               self.setTool("spumux")
                self.args += [xmlfile]
                self.inputFile = inputfile
                self.dumpFile = outputfile
@@ -54,7 +54,7 @@ class spumuxTask(Task):
 class MakeFifoNode(Task):
        def __init__(self, job, number):
                Task.__init__(self, job, "Make FIFO nodes")
-               self.setTool("/bin/mknod")
+               self.setTool("mknod")
                nodename = self.job.workspace + "/dvd_title_%d" % number + ".mpg"
                self.args += [nodename, "p"]
                self.weighting = 10
@@ -62,14 +62,14 @@ class MakeFifoNode(Task):
 class LinkTS(Task):
        def __init__(self, job, sourcefile, link_name):
                Task.__init__(self, job, "Creating symlink for source titles")
-               self.setTool("/bin/ln")
+               self.setTool("ln")
                self.args += ["-s", sourcefile, link_name]
                self.weighting = 10
 
 class CopyMeta(Task):
        def __init__(self, job, sourcefile):
                Task.__init__(self, job, "Copy title meta files")
-               self.setTool("/bin/cp")
+               self.setTool("cp")
                from os import listdir
                path, filename = sourcefile.rstrip("/").rsplit("/",1)
                tsfiles = listdir(path)
@@ -84,7 +84,7 @@ class DemuxTask(Task):
                Task.__init__(self, job, "Demux video into ES")
                title = job.project.titles[job.i]
                self.global_preconditions.append(DiskspacePrecondition(title.estimatedDiskspace))
-               self.setTool("/usr/bin/projectx")
+               self.setTool("projectx")
                self.args += [inputfile, "-demux", "-out", self.job.workspace ]
                self.end = 300
                self.prog_state = 0
@@ -194,7 +194,7 @@ class MplexTask(Task):
                self.weighting = weighting
                self.demux_task = demux_task
                self.postconditions.append(MplexTaskPostcondition())
-               self.setTool("/usr/bin/mplex")
+               self.setTool("mplex")
                self.args += ["-f8", "-o", outputfile, "-v1"]
                if inputfiles:
                        self.args += inputfiles
@@ -222,7 +222,7 @@ class RemoveESFiles(Task):
        def __init__(self, job, demux_task):
                Task.__init__(self, job, "Remove temp. files")
                self.demux_task = demux_task
-               self.setTool("/bin/rm")
+               self.setTool("rm")
                self.weighting = 10
 
        def prepare(self):
@@ -234,7 +234,7 @@ class DVDAuthorTask(Task):
        def __init__(self, job):
                Task.__init__(self, job, "Authoring DVD")
                self.weighting = 20
-               self.setTool("/usr/bin/dvdauthor")
+               self.setTool("dvdauthor")
                self.CWD = self.job.workspace
                self.args += ["-x", self.job.workspace+"/dvdauthor.xml"]
                self.menupreview = job.menupreview
@@ -255,7 +255,7 @@ class DVDAuthorTask(Task):
 class DVDAuthorFinalTask(Task):
        def __init__(self, job):
                Task.__init__(self, job, "dvdauthor finalize")
-               self.setTool("/usr/bin/dvdauthor")
+               self.setTool("dvdauthor")
                self.args += ["-T", "-o", self.job.workspace + "/dvd"]
 
 class WaitForResidentTasks(Task):
@@ -292,7 +292,7 @@ class BurnTaskPostcondition(Condition):
 
 class BurnTask(Task):
        ERROR_NOTWRITEABLE, ERROR_LOAD, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_FILETOOLARGE, ERROR_ISOTOOLARGE, ERROR_MINUSRWBUG, ERROR_UNKNOWN = range(10)
-       def __init__(self, job, extra_args=[], tool="/bin/growisofs"):
+       def __init__(self, job, extra_args=[], tool="growisofs"):
                Task.__init__(self, job, job.name)
                self.weighting = 500
                self.end = 120 # 100 for writing, 10 for buffer flush, 10 for closing disc
@@ -357,7 +357,7 @@ class BurnTask(Task):
 class RemoveDVDFolder(Task):
        def __init__(self, job):
                Task.__init__(self, job, "Remove temp. files")
-               self.setTool("/bin/rm")
+               self.setTool("rm")
                self.args += ["-rf", self.job.workspace]
                self.weighting = 10
 
@@ -882,13 +882,13 @@ class DVDJob(Job):
                        volName = self.project.settings.name.getValue()
                        if output == "dvd":
                                self.name = _("Burn DVD")
-                               tool = "/bin/growisofs"
+                               tool = "growisofs"
                                burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ]
                                if self.project.size/(1024*1024) > self.project.MAX_SL:
                                        burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ]
                        elif output == "iso":
                                self.name = _("Create DVD-ISO")
-                               tool = "/usr/bin/mkisofs"
+                               tool = "genisoimage"
                                isopathfile = getISOfilename(self.project.settings.isopath.getValue(), volName)
                                burnargs = [ "-o", isopathfile ]
                        burnargs += [ "-dvd-video", "-publisher", "Dreambox", "-V", volName, self.workspace + "/dvd" ]
@@ -920,14 +920,14 @@ class DVDdataJob(Job):
 
                output = self.project.settings.output.getValue()
                volName = self.project.settings.name.getValue()
-               tool = "/bin/growisofs"
+               tool = "growisofs"
                if output == "dvd":
                        self.name = _("Burn DVD")
                        burnargs = [ "-Z", "/dev/" + harddiskmanager.getCD(), "-dvd-compat" ]
                        if self.project.size/(1024*1024) > self.project.MAX_SL:
                                burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ]
                elif output == "iso":
-                       tool = "/usr/bin/mkisofs"
+                       tool = "genisoimage"
                        self.name = _("Create DVD-ISO")
                        isopathfile = getISOfilename(self.project.settings.isopath.getValue(), volName)
                        burnargs = [ "-o", isopathfile ]
@@ -959,5 +959,5 @@ class DVDisoJob(Job):
                        if getSize(imagepath)/(1024*1024) > self.project.MAX_SL:
                                burnargs += [ "-use-the-force-luke=4gms", "-speed=1", "-R" ]
                        burnargs += [ "-dvd-video", "-publisher", "Dreambox", "-V", volName, imagepath ]
-               tool = "/bin/growisofs"
+               tool = "growisofs"
                BurnTask(self, burnargs, tool)
index a1c3884..39d7277 100755 (executable)
@@ -92,10 +92,10 @@ class ProjectSettings(Screen,ConfigListScreen):
                        <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
-                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
-                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
-                       <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
-                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
+                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
+                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
                        <widget name="config" position="5,50" size="550,276" scrollbarMode="showOnDemand" />
                        <ePixmap pixmap="skin_default/div-h.png" position="0,350" zPosition="1" size="560,2" />
                        <widget source="info" render="Label" position="10,360" size="550,80" font="Regular;18" halign="center" valign="center" />
@@ -233,10 +233,19 @@ class ProjectSettings(Screen,ConfigListScreen):
                        else:
                                self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
                elif scope == "project":
-                       if self.project.loadProject(path):
-                               self.initConfigList()
+                       self.path = path
+                       print "len(self.titles)", len(self.project.titles)
+                       if len(self.project.titles):
+                               self.session.openWithCallback(self.askLoadCB, MessageBox,text = _("Your current collection will get lost!") + "\n" + _("Do you want to restore your settings?"), type = MessageBox.TYPE_YESNO)
                        else:
-                               self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
+                               self.askLoadCB(True)
                elif scope:
                        configRef.setValue(path)
                        self.initConfigList()
+
+       def askLoadCB(self, answer):
+               if answer is not None and answer:
+                       if self.project.loadProject(self.path):
+                               self.initConfigList()
+                       else:
+                               self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
\ No newline at end of file
index 61152e8..a52fad9 100644 (file)
@@ -52,13 +52,35 @@ class TitleCutter(CutListEditor):
                        CutListEditor.grabFrame(self)
 
        def exit(self):
+               if self.t.VideoType == -1:
+                       self.getPMTInfo()
                self.checkAndGrabThumb()
                self.session.nav.stopService()
                self.close(self.cut_list[:])
 
 class CutlistReader(TitleCutter):
+       skin = """
+               <screen position="0,0" size="720,576">
+               <eLabel position="0,0" size="720,576" zPosition="1" backgroundColor="#000000" />
+               <widget name="Video" position="0,0" size="100,75" />
+               <widget name="SeekState" position="0,0" />
+               <widget source="cutlist" position="0,0" render="Listbox" >
+                       <convert type="TemplatedMultiContent">
+                               {"template": [
+                                               MultiContentEntryText(text = 1),
+                                               MultiContentEntryText(text = 2)
+                                       ],
+                                "fonts": [gFont("Regular", 18)],
+                                "itemHeight": 20
+                               }
+                       </convert>
+               </widget>
+               <widget name="Timeline" position="0,0" />
+       </screen>"""
+
        def __init__(self, session, t):
                TitleCutter.__init__(self, session, t)
+               self.skin = CutlistReader.skin
 
        def getPMTInfo(self):
                TitleCutter.getPMTInfo(self)
index dbc988b..2cbeb63 100755 (executable)
@@ -11,38 +11,46 @@ from Components.Sources.List import List
 from Components.Sources.StaticText import StaticText
 from Components.Sources.Progress import Progress
 from Components.MultiContent import MultiContentEntryText
+from Components.Label import MultiColorLabel
 from enigma import gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT
 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
 
 class TitleList(Screen, HelpableScreen):
        skin = """
-               <screen name="TitleList" position="center,center" size="560,445" title="DVD Tool" >
+               <screen name="TitleList" position="center,center" size="560,470" title="DVD Tool" >
                        <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
-                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
-                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
-                       <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
-                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
+                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
+                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
                        <widget source="title_label" render="Label" position="10,48" size="540,38" font="Regular;18" transparent="1" />
-                       <widget source="error_label" render="Label" position="10,48" size="540,395" zPosition="3" font="Regular;20" transparent="1" />
-                       <widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="540,312" zPosition="3" transparent="1" >
+                       <widget source="error_label" render="Label" position="10,48" size="540,296" zPosition="3" font="Regular;20" transparent="1" />
+                       <widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="546,296" zPosition="3" transparent="1" >
                                <convert type="TemplatedMultiContent">
                                        {"template": [
-                                                       MultiContentEntryText(pos = (0, 0), size = (420, 20), font = 0, flags = RT_HALIGN_LEFT, text = 1), # index 1 Title,
-                                                       MultiContentEntryText(pos = (0, 20), size = (328, 17), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 description,
-                                                       MultiContentEntryText(pos = (420, 6), size = (120, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 3), # index 3 begin time,
-                                                       MultiContentEntryText(pos = (328, 20), size = (154, 17), font = 1, flags = RT_HALIGN_RIGHT, text = 4), # index 4 channel,
-                                                       MultiContentEntryText(pos = (482, 20), size = (58, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 5), # index 4 channel,
+                                                       MultiContentEntryText(pos = (0, 0), size = (360, 20), font = 0, flags = RT_HALIGN_LEFT, text = 1), # index 1 Title,
+                                                       MultiContentEntryText(pos = (0, 20), size = (360, 17), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 description,
+                                                       MultiContentEntryText(pos = (366, 6), size = (152, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 3), # index 3 channel,
+                                                       MultiContentEntryText(pos = (366, 20), size = (102, 17), font = 1, flags = RT_HALIGN_RIGHT, text = 4), # index 4 begin time,
+                                                       MultiContentEntryText(pos = (470, 20), size = (48, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 5), # index 5 duration,
                                                ],
                                        "fonts": [gFont("Regular", 20), gFont("Regular", 14)],
                                        "itemHeight": 37
                                        }
                                </convert>
                        </widget>
-                       <widget source="space_bar" render="Progress" position="10,410" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
-                       <widget source="space_label" render="Label" position="40,414" size="480,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
+                       <ePixmap pixmap="skin_default/div-h.png" position="0,390" zPosition="10" size="560,2" />
+                       <ePixmap pixmap="skin_default/buttons/key_menu.png" position="10,394" size="35,25" alphatest="on" />
+                       <widget source="hint" render="Label" position="50,396" size="540,22" font="Regular;18" halign="left" />
+                       <widget name="medium_label"  position="10,420" size="540,22" font="Regular;18" halign="left" foregroundColors="#FFFFFF,#FFFF00,#FF0000" />
+                       <widget source="space_bar_single" render="Progress" position="10,446" size="270,24" borderWidth="1" zPosition="2" backgroundColor="#254f7497" />
+                       <widget source="space_label_single" render="Label" position="10,449" size="270,22" zPosition="3" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
+                       <widget source="space_bar_dual" render="Progress" position="10,446" size="540,24" borderWidth="1" backgroundColor="#254f7497" />
+                       <widget source="space_label_dual" render="Label" position="10,449" size="540,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
+                       
                </screen>"""
 
        def __init__(self, session, project = None):
@@ -75,17 +83,19 @@ class TitleList(Screen, HelpableScreen):
 
                self["title_label"] = StaticText()
                self["error_label"] = StaticText()
-               self["space_label"] = StaticText()
-               self["space_bar"] = Progress()
+               self["space_label_single"] = StaticText()
+               self["space_label_dual"] = StaticText()
+               self["hint"] = StaticText(_("Advanced Options"))
+               self["medium_label"] = MultiColorLabel()
+               self["space_bar_single"] = Progress()
+               self["space_bar_dual"] = Progress()
 
+               self["titles"] = List([])
+               self.previous_size = 0
                if project is not None:
                        self.project = project
                else:
                        self.newProject()
-
-               self["titles"] = List([])
-               self.updateTitleList()
-               self.previous_size = 0
                self.onLayoutFinish.append(self.layoutFinished)
 
        def layoutFinished(self):
@@ -107,15 +117,16 @@ class TitleList(Screen, HelpableScreen):
                        j = self.backgroundJob
                        menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob))
                menu.append((_("DVD media toolbox"), self.toolbox))
-               menu.append((_("Preview menu"), self.previewMenu))
                if self.project.settings.output.getValue() == "dvd":
                        if len(self["titles"].list):
                                menu.append((_("Burn DVD"), self.burnProject))
                elif self.project.settings.output.getValue() == "iso":
                        menu.append((_("Create DVD-ISO"), self.burnProject))
                menu.append((_("Burn existing image to DVD"), self.selectImage))
-               menu.append((_("Edit chapters of current title"), self.editTitle))
-               menu.append((_("Reset and renumerate title names"), self.resetTitles))
+               if len(self["titles"].list):
+                       menu.append((_("Preview menu"), self.previewMenu))
+                       menu.append((_("Edit chapters of current title"), self.editTitle))
+                       menu.append((_("Reset and renumerate title names"), self.resetTitles))
                menu.append((_("Exit"), self.leave))
                self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
 
@@ -149,9 +160,9 @@ class TitleList(Screen, HelpableScreen):
                                <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
                                <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
                                <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
-                               <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
-                               <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
-                               <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
+                               <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+                               <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+                               <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
                                <widget name="waitingtext" position="0,45" size="560,395" zPosition="4" font="Regular;22" halign="center" valign="center" />
                                <widget name="list" position="5,40" size="550,375" zPosition="2" scrollbarMode="showOnDemand" />
                                <widget name="DescriptionBorder" pixmap="skin_default/border_eventinfo.png" position="0,316" zPosition="1" size="560,103" transparent="1" alphatest="on" />
@@ -197,7 +208,7 @@ class TitleList(Screen, HelpableScreen):
                                        self.close(current)
                self.session.openWithCallback(self.selectedSource, DVDMovieSelection)
 
-       def selectedSource(self, source):
+       def selectedSource(self, source = None):
                if source is None:
                        return None
                if not source.getPath().endswith(".ts"):
@@ -228,7 +239,7 @@ class TitleList(Screen, HelpableScreen):
        def settingsCB(self, update=True):
                if not update:
                        return
-               self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
+               self.updateTitleList()
 
        def loadTemplate(self):
                filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVD.ddvdp.xml"
@@ -281,9 +292,11 @@ class TitleList(Screen, HelpableScreen):
                if len(list):
                        self["key_red"].text = _("Remove title")
                        self["key_yellow"].text = _("Title properties")
+                       self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
                else:
                        self["key_red"].text = ""
                        self["key_yellow"].text = ""
+                       self["title_label"].text = _("Please add titles to the compilation.")
 
        def updateSize(self):
                size = self.project.size/(1024*1024)
@@ -292,20 +305,32 @@ class TitleList(Screen, HelpableScreen):
                print "updateSize:", size, "MAX_DL:", MAX_DL, "MAX_SL:", MAX_SL
                if size > MAX_DL:
                        percent = 100 * size / float(MAX_DL)
-                       self["space_label"].text = "%d MB - " % size + _("exceeds dual layer medium!") + " (%.2f%% " % (100-percent) + _("free") + ")"
-                       self["space_bar"].value = int(percent)
+                       self["space_label_dual"].text = "%d MB (%.2f%%)" % (size, percent)
+                       self["space_bar_dual"].value = int(percent)
+                       self["space_bar_single"].value = 100
+                       self["space_label_single"].text = ""
+                       self["medium_label"].setText(_("Exceeds dual layer medium!"))
+                       self["medium_label"].setForegroundColorNum(2)
                        if self.previous_size < MAX_DL:
-                               self.session.open(MessageBox,text = _("exceeds dual layer medium!"), type = MessageBox.TYPE_ERROR)
+                               self.session.open(MessageBox,text = _("Exceeds dual layer medium!"), type = MessageBox.TYPE_ERROR)
                elif size > MAX_SL:
                        percent = 100 * size / float(MAX_DL)
-                       self["space_label"].text = "%d MB  " % size + _("of a DUAL layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
-                       self["space_bar"].value = int(percent)
+                       self["space_label_dual"].text = "%d MB (%.2f%%)" % (size, percent)
+                       self["space_bar_dual"].value = int(percent)
+                       self["space_bar_single"].value = 100
+                       self["space_label_single"].text = ""
+                       self["medium_label"].setText(_("Required medium type:") + " " + _("DUAL LAYER DVD") + ", %d MB " % (MAX_DL - size) + _("free"))
+                       self["medium_label"].setForegroundColorNum(1)
                        if self.previous_size < MAX_SL:
-                               self.session.open(MessageBox,text = _("Your collection exceeds the size of a single layer medium, you will need a blank dual layer DVD!"), type = MessageBox.TYPE_INFO)
+                               self.session.open(MessageBox, text = _("Your collection exceeds the size of a single layer medium, you will need a blank dual layer DVD!"), timeout = 10, type = MessageBox.TYPE_INFO)
                elif size < MAX_SL:
                        percent = 100 * size / float(MAX_SL)
-                       self["space_label"].text = "%d MB " % size + _("of a SINGLE layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
-                       self["space_bar"].value = int(percent)
+                       self["space_label_single"].text = "%d MB (%.2f%%)" % (size, percent)
+                       self["space_bar_single"].value = int(percent)
+                       self["space_bar_dual"].value = 0
+                       self["space_label_dual"].text = ""
+                       self["medium_label"].setText(_("Required medium type:") + " " + _("SINGLE LAYER DVD") + ", %d MB " % (MAX_SL - size) + _("free"))
+                       self["medium_label"].setForegroundColorNum(0)
                self.previous_size = size
 
        def getCurrentTitle(self):
@@ -323,9 +348,7 @@ class TitleList(Screen, HelpableScreen):
 
        def titleEditDone(self, cutlist):
                t = self.current_edit_title
-               t.initDVDmenuText(self.project,len(self.project.titles))
-               t.cuesheet = cutlist
-               t.produceFinalCuesheet()
+               t.titleEditDone(cutlist)
                if t.VideoType != 0:
                        self.session.openWithCallback(self.DVDformatCB,MessageBox,text = _("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a Dreambox format data DVD (which will not play in stand-alone DVD players) instead?"), type = MessageBox.TYPE_YESNO)
                else:
@@ -335,7 +358,7 @@ class TitleList(Screen, HelpableScreen):
                count = 0
                for title in self.project.titles:
                        count += 1
-                       title.initDVDmenuText(self.project,count)
+                       title.initDVDmenuText(count)
                self.updateTitleList()
 
        def DVDformatCB(self, answer):
@@ -346,5 +369,13 @@ class TitleList(Screen, HelpableScreen):
                else:
                        self.removeTitle(t)
 
-       def leave(self):
-               self.close()
+       def leave(self, close = False):
+               if not len(self["titles"].list) or close:
+                       self.close()
+               else:
+                       self.session.openWithCallback(self.exitCB, MessageBox,text = _("Your current collection will get lost!") + "\n" + _("Do you really want to exit?"), type = MessageBox.TYPE_YESNO)
+
+       def exitCB(self, answer):
+               print "exitCB", answer
+               if answer is not None and answer:
+                       self.close()
\ No newline at end of file
index 0a664eb..956f054 100755 (executable)
@@ -21,10 +21,12 @@ class TitleProperties(Screen,ConfigListScreen):
                <screen name="TitleProperties" position="center,center" size="560,445" title="Properties of current title" >
                        <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
                        <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
-                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
-                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
-                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
+                       <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+                       <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
+                       <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
                        <widget source="serviceinfo" render="Label" position="10,46" size="350,144" font="Regular;18" />
                        <widget name="thumbnail" position="370,46" size="180,144" alphatest="on" />
                        <widget name="config" position="10,206" size="540,228" scrollbarMode="showOnDemand" />
@@ -38,7 +40,8 @@ class TitleProperties(Screen,ConfigListScreen):
 
                self["key_red"] = StaticText(_("Cancel"))
                self["key_green"] = StaticText(_("OK"))
-               self["key_blue"] = StaticText(_("Edit Title"))
+               self["key_yellow"] = StaticText(_("Edit Title"))
+               self["key_blue"] = StaticText()
                self["serviceinfo"] = StaticText()
 
                self["thumbnail"] = Pixmap()
@@ -57,7 +60,7 @@ class TitleProperties(Screen,ConfigListScreen):
                {
                    "green": self.exit,
                    "red": self.cancel,
-                   "blue": self.editTitle,
+                   "yellow": self.editTitle,
                    "cancel": self.cancel,
                    "ok": self.ok,
                }, -2)
index 0b3be7d..1a823b7 100755 (executable)
@@ -1,4 +1,4 @@
-installdir = $(datadir)/meta/
+installdir = $(datadir)/meta
 
 dist_install_DATA = plugin_dvdburn.xml
 
index 647d1cf..c1e202a 100755 (executable)
@@ -3,22 +3,17 @@
                     <tag type="Recording" />
                     <tag type="Software" />
          </prerequisites>
-          <info language="en">
+          <info>
                     <author>Dream Multimedia</author>
                     <name>DVDBurn</name>
                     <packagename>enigma2-plugin-extensions-dvdburn</packagename>
-                    <shortdescription>With DVDBurn you can burn your recordings to a dvd.</shortdescription>
-                    <description>With DVDBurn you can burn your recordings to a dvd.\nArchive all your favorite movies to recordable dvds with menus if wanted.</description>
+                    <shortdescription>Burn your recordings to DVD</shortdescription>
+                    <description>With DVDBurn you can make compilations of records from your Dreambox hard drive.\n
+                   Optionally you can add customizable menus. You can record the compilation to a standard-compliant DVD that can be played on conventinal DVD players.\n
+                   HDTV recordings can only be burned in proprietary dreambox format.</description>
                     <screenshot src="http://www.dreamboxupdate.com/preview/plugin_dvdburn_en.jpg" />
           </info>
-          <info language="de">
-                    <author>Dream Multimedia</author>
-                    <name>DVDBurn</name>
-                    <packagename>enigma2-plugin-extensions-dvdburn</packagename>
-                    <shortdescription>Mit DVDBurn brennen Sie ihre Aufnahmen auf DVD.</shortdescription>
-                    <description>Mit DVDBurn brennen Sie ihre Aufnahmen auf DVD.\nArchivieren Sie Ihre Liblingsfilme auf DVD mit Menus wenn Sie es wünschen.</description>
-                    <screenshot src="http://www.dreamboxupdate.com/preview/plugin_dvdburn_de.jpg" />
-          </info>
+
          <files type="package"> <!-- without version, without .ipk -->
                <file type="package" name="enigma2-plugin-extensions-dvdburn" />
          </files>
index 45f438d..bd856b4 100644 (file)
@@ -12,6 +12,6 @@ def main_add(session, service, **kwargs):
        dvdburn.selectedSource(service)
 
 def Plugins(**kwargs):
-       descr = _("Burn to DVD...")
+       descr = _("Burn to DVD")
        return [PluginDescriptor(name="DVD Burn", description=descr, where = PluginDescriptor.WHERE_MOVIELIST, fnc=main_add, icon="dvdburn.png"),
                PluginDescriptor(name="DVD Burn", description=descr, where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main, icon="dvdburn.png") ]
index d1a995c..71ea714 100644 (file)
@@ -4,7 +4,6 @@ SUBDIRS = src meta
 installdir = $(pkglibdir)/python/Plugins/Extensions/DVDPlayer
 
 install_PYTHON = \
-       src/servicedvd.so \
        __init__.py \
        plugin.py \
        keymap.xml \
index 12d1371..aa22b99 100755 (executable)
@@ -1,4 +1,4 @@
-installdir = $(datadir)/meta/
+installdir = $(datadir)/meta
 
 dist_install_DATA = plugin_dvdplayer.xml
 
index 1353f7d..6fc5a6f 100755 (executable)
@@ -2,23 +2,14 @@
          <prerequisites>
                     <tag type="Multimedia" />
          </prerequisites>
-          <info language="en">
+          <info>
                     <author>Dream Multimedia</author>
                     <name>DVDPlayer</name>
                     <packagename>enigma2-plugin-extensions-dvdplayer</packagename>
-                    <shortdescription>DVDPlayer plays your DVDs on your Dreambox.</shortdescription>
+                    <shortdescription>DVDPlayer plays your DVDs on your Dreambox</shortdescription>
                     <description>DVDPlayer plays your DVDs on your Dreambox.\nWith the DVDPlayer you can play your DVDs on your Dreambox from a DVD or even from an iso file or video_ts folder on your harddisc or network.</description>
                     <screenshot src="http://www.dreamboxupdate.com/preview/plugin_dvdplayer.jpg" />
           </info>
-          <info language="de">
-                    <author>Dream Multimedia</author>
-                    <name>DVDPlayer</name>
-                    <packagename>enigma2-plugin-extensions-dvdplayer</packagename>
-                    <shortdescription>Spielen Sie Ihre DVDs mit dem DVDPlayer auf Ihrer Dreambox ab.</shortdescription>
-                    <description>Spielen Sie Ihre DVDs mit dem DVDPlayer auf Ihrer Dreambox ab.\nMit dem DVDPlayer können Sie Ihre DVDs auf Ihrer Dreambox abspielen. Dabei ist es egal ob Sie von DVD, iso-Datei oder sogar direkt von einer video_ts Ordnerstruktur von Ihrer Festplatte oder dem Netzwerk abspielen.
-                    </description>
-                    <screenshot src="http://www.dreamboxupdate.com/preview/plugin_dvdplayer.jpg" />
-          </info>
          <files type="package"> <!-- without version, without .ipk -->
                <file type="package" name="enigma2-plugin-extensions-dvdplayer" />
          </files>
index 6e4d9cc..e092e82 100755 (executable)
@@ -93,7 +93,7 @@ class DVDSummary(Screen):
                <widget source="session.CurrentService" render="Label" position="5,4" size="120,28" font="Regular;12" transparent="1" >
                        <convert type="ServiceName">Name</convert>
                </widget>
-               <widget name="DVDPlayer" position="5,30" size="66,16" font="Regular;12" transparent="1" />
+               <widget name="DVDPlayer" position="5,30" size="66,16" font="Regular;11" transparent="1" />
                <widget name="Chapter" position="72,30" size="54,16" font="Regular;12" transparent="1" halign="right" />
                <widget source="session.CurrentService" render="Label" position="66,46" size="60,18" font="Regular;16" transparent="1" halign="right" >
                        <convert type="ServicePosition">Position</convert>
index 774871e..27c751c 100644 (file)
@@ -2,6 +2,11 @@ OBJS := servicedvd.cpp
 
 -include $(OBJS:.cpp=.d)
 
+installdir = $(pkglibdir)/python/Plugins/Extensions/DVDPlayer
+
+install_PYTHON = \
+       servicedvd.so
+
 servicedvd.so:
        $(CXX) $(CPPFLAGS) -MD $(CXXFLAGS) $(DEFS) -I$(top_srcdir)/include \
        -Wall -W $(OBJS) -shared -fPIC -Wl,-soname,servicedvd.so -o servicedvd.so \
index 0372c49..2ba5392 100644 (file)
@@ -85,12 +85,9 @@ RESULT eServiceFactoryDVD::offlineOperations(const eServiceReference &, ePtr<iSe
 DEFINE_REF(eServiceDVD);
 
 eServiceDVD::eServiceDVD(eServiceReference ref):
-       m_ref(ref),
-       m_ddvdconfig(ddvd_create()),
-       m_subtitle_widget(0),
-       m_state(stIdle),
-       m_current_trick(0),
-       m_pump(eApp, 1)
+       m_ref(ref), m_ddvdconfig(ddvd_create()), m_subtitle_widget(0), m_state(stIdle),
+       m_current_trick(0), m_pump(eApp, 1), m_width(-1), m_height(-1),
+       m_aspect(-1), m_framerate(-1), m_progressive(-1)
 {
        int aspect = DDVD_16_9;
        int policy = DDVD_PAN_SCAN;
@@ -309,6 +306,32 @@ void eServiceDVD::gotMessage(int /*what*/)
                        m_event(this, evSeekableStatusChanged);
                        m_event(this, evUser+12);
                        break;
+#ifdef DDVD_SUPPORTS_PICTURE_INFO
+               case DDVD_SIZE_CHANGED:
+               {
+                       int changed = m_width != -1 && m_height != -1 && m_aspect != -1;
+                       ddvd_get_last_size(m_ddvdconfig, &m_width, &m_height, &m_aspect);
+                       if (changed)
+                               m_event((iPlayableService*)this, evVideoSizeChanged);
+                       break;
+               }
+               case DDVD_PROGRESSIVE_CHANGED:
+               {
+                       int changed = m_progressive != -1;
+                       ddvd_get_last_progressive(m_ddvdconfig, &m_progressive);
+                       if (changed)
+                               m_event((iPlayableService*)this, evVideoProgressiveChanged);
+                       break;
+               }
+               case DDVD_FRAMERATE_CHANGED:
+               {
+                       int changed = m_framerate != -1;
+                       ddvd_get_last_framerate(m_ddvdconfig, &m_framerate);
+                       if (changed)
+                               m_event((iPlayableService*)this, evVideoFramerateChanged);
+                       break;
+               }
+#endif
                default:
                        break;
        }
@@ -500,6 +523,18 @@ int eServiceDVD::getInfo(int w)
                case sUser+7:
                case sUser+8:
                        return resIsPyObject;
+#ifdef DDVD_SUPPORTS_PICTURE_INFO
+               case sVideoWidth:
+                       return m_width;
+               case sVideoHeight:
+                       return m_height;
+               case sAspect:
+                       return m_aspect;
+               case sProgressive:
+                       return m_progressive;
+               case sFrameRate:
+                       return m_framerate;
+#endif
                default:
                        return resNA;
        }
index c730d50..c751a39 100644 (file)
@@ -127,6 +127,8 @@ private:
 
        void loadCuesheet();
        void saveCuesheet();
+
+       int m_width, m_height, m_aspect, m_framerate, m_progressive;
 };
 
 #endif
index 5766ff3..a11d35d 100755 (executable)
@@ -1,4 +1,4 @@
-installdir = $(datadir)/meta/
+installdir = $(datadir)/meta
 
 dist_install_DATA = plugin_graphmultiepg.xml
 
index a10840d..37d0988 100755 (executable)
@@ -3,23 +3,14 @@
                     <tag type="EPG" />
                     <tag type="Recording" />
          </prerequisites>
-          <info language="en">
+          <info>
                     <author>Dream Multimedia</author>
                     <name>GraphMultiEPG</name>
-                    <packagename>eenigma2-plugin-extensions-graphmultiepg</packagename>
-                    <shortdescription>GraphMultiEPG shows a graphical timeline EPG.</shortdescription>
+                    <packagename>enigma2-plugin-extensions-graphmultiepg</packagename>
+                    <shortdescription>GraphMultiEPG shows a graphical timeline EPG</shortdescription>
                     <description>GraphMultiEPG shows a graphical timeline EPG.\nShows a nice overview of all running und upcoming tv shows.</description>
                     <screenshot src="http://www.dreamboxupdate.com/preview/plugin_graphmultiepg_en.jpg" />
           </info>
-          <info language="de">
-                    <author>Dream Multimedia</author>
-