Merge commit 'origin/translations' into experimental
authoracid-burn <acid-burn@opendreambox.org>
Wed, 31 Mar 2010 09:10:31 +0000 (11:10 +0200)
committeracid-burn <acid-burn@opendreambox.org>
Wed, 31 Mar 2010 09:10:31 +0000 (11:10 +0200)
258 files changed:
Navigation.py
RecordTimer.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 [moved from data/defaults/Dream/userbouquet.favourites.tv with 91% similarity]
data/defaults/Dream/sdbouquets/Makefile.am [new file with mode: 0644]
data/defaults/Dream/sdbouquets/userbouquet.favourites.tv [new file with mode: 0644]
data/encoding.conf
data/keymap.xml
data/menu.xml [changed mode: 0644->0755]
data/setup.xml
data/skin.xml
data/skin_default.xml
data/skin_default/Makefile.am [changed mode: 0644->0755]
data/skin_default/border_menu_350.png [new file with mode: 0755]
data/skin_default/celserviceeventprogressbar.png [new file with mode: 0644]
data/skin_default/div-h.png [changed mode: 0644->0755]
data/skin_default/icons/dish.png
data/skin_default/lock.png [new file with mode: 0644]
data/skin_default/lockBouquet.png [new file with mode: 0644]
data/skin_default/unhandled-key.png [new file with mode: 0644]
data/skin_default/unlock.png [new file with mode: 0644]
data/skin_default/unlockBouquet.png [new file with mode: 0644]
doc/DEFAULTS
lib/actions/action.cpp
lib/base/ebase.cpp
lib/base/ebase.h
lib/base/elock.h
lib/base/filepush.cpp
lib/base/ioprio.cpp
lib/driver/rc.cpp
lib/driver/rc.h
lib/driver/rcconsole.cpp
lib/driver/rcinput.cpp
lib/driver/rcinput.h
lib/dvb/decoder.cpp
lib/dvb/decoder.h
lib/dvb/dvb.cpp
lib/dvb/epgcache.cpp
lib/dvb/epgcache.h
lib/dvb/frontend.cpp
lib/dvb/frontend.h
lib/dvb/idvb.h
lib/dvb/lowlevel/mhw.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/dvb/pvrparse.cpp
lib/dvb/scan.cpp
lib/dvb/scan.h
lib/dvb/sec.cpp
lib/dvb/tstools.cpp
lib/dvb/tstools.h
lib/gdi/grc.cpp
lib/gdi/grc.h
lib/gui/elistboxcontent.cpp
lib/python/Components/About.py
lib/python/Components/ChoiceList.py [changed mode: 0644->0755]
lib/python/Components/ConfigList.py [changed mode: 0644->0755]
lib/python/Components/Converter/Makefile.am
lib/python/Components/Converter/SensorToText.py [new file with mode: 0644]
lib/python/Components/Converter/ServiceInfo.py
lib/python/Components/Converter/TemplatedMultiContent.py [changed mode: 0644->0755]
lib/python/Components/EpgList.py [changed mode: 0644->0755]
lib/python/Components/FanControl.py [new file with mode: 0644]
lib/python/Components/FileList.py
lib/python/Components/Harddisk.py
lib/python/Components/Ipkg.py
lib/python/Components/Lcd.py
lib/python/Components/Makefile.am
lib/python/Components/MediaPlayer.py [changed mode: 0644->0755]
lib/python/Components/Network.py
lib/python/Components/NimManager.py
lib/python/Components/ParentalControl.py
lib/python/Components/ParentalControlList.py
lib/python/Components/PluginComponent.py
lib/python/Components/Renderer/Listbox.py [changed mode: 0644->0755]
lib/python/Components/SelectionList.py [changed mode: 0644->0755]
lib/python/Components/Sensors.py [new file with mode: 0644]
lib/python/Components/ServiceList.py
lib/python/Components/Sources/List.py
lib/python/Components/Sources/Makefile.am
lib/python/Components/Sources/Sensor.py [new file with mode: 0644]
lib/python/Components/SystemInfo.py
lib/python/Components/Task.py
lib/python/Components/TimerList.py [changed mode: 0644->0755]
lib/python/Components/TuneTest.py
lib/python/Components/UsageConfig.py
lib/python/Components/config.py
lib/python/Plugins/Extensions/CutListEditor/meta/plugin_cutlisteditor.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/CutListEditor/plugin.py
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/dvdburn_de.jpg [new file with mode: 0755]
lib/python/Plugins/Extensions/DVDBurn/meta/dvdburn_en.jpg [new file with mode: 0755]
lib/python/Plugins/Extensions/DVDBurn/meta/plugin_dvdburn.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/DVDBurn/plugin.py
lib/python/Plugins/Extensions/DVDPlayer/Makefile.am
lib/python/Plugins/Extensions/DVDPlayer/meta/plugin_dvdplayer.xml [changed mode: 0644->0755]
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/GraphMultiEpg.py [changed mode: 0644->0755]
lib/python/Plugins/Extensions/GraphMultiEPG/meta/graphmultiepg_de.jpg [changed mode: 0644->0755]
lib/python/Plugins/Extensions/GraphMultiEPG/meta/graphmultiepg_en.jpg [changed mode: 0644->0755]
lib/python/Plugins/Extensions/GraphMultiEPG/meta/plugin_graphmultiepg.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/MediaPlayer/meta/mediaplayer_de.jpg [changed mode: 0644->0755]
lib/python/Plugins/Extensions/MediaPlayer/meta/mediaplayer_en.jpg [changed mode: 0644->0755]
lib/python/Plugins/Extensions/MediaPlayer/meta/plugin_mediaplayer.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/MediaPlayer/plugin.py [changed mode: 0644->0755]
lib/python/Plugins/Extensions/MediaScanner/meta/Makefile.am
lib/python/Plugins/Extensions/MediaScanner/meta/mediascanner_de.jpg [new file with mode: 0755]
lib/python/Plugins/Extensions/MediaScanner/meta/mediascanner_en.jpg [new file with mode: 0755]
lib/python/Plugins/Extensions/MediaScanner/meta/plugin_mediascanner.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/PicturePlayer/meta/plugin_pictureplayer.xml [changed mode: 0644->0755]
lib/python/Plugins/Extensions/SocketMMI/Makefile.am
lib/python/Plugins/Extensions/SocketMMI/src/Makefile.am
lib/python/Plugins/Plugin.py
lib/python/Plugins/SystemPlugins/CleanupWizard/meta/Makefile.am
lib/python/Plugins/SystemPlugins/CleanupWizard/meta/cleanupwizard_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/CleanupWizard/meta/cleanupwizard_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/CleanupWizard/meta/plugin_cleanupwizard.xml
lib/python/Plugins/SystemPlugins/CleanupWizard/plugin.py
lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/meta/ciassignment.jpg [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/meta/plugin_commoninterfaceassignment.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/meta/Makefile.am
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/meta/crashlogautosubmit_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/meta/crashlogautosubmit_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/meta/plugin_crashlogautosubmit.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/CrashlogAutoSubmit/plugin.py
lib/python/Plugins/SystemPlugins/DefaultServicesScanner/meta/defaultservicescanner.jpg [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/DefaultServicesScanner/meta/plugin_defaultservicesscanner.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/Makefile.am
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/diseqctester.jpg [deleted file]
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/diseqctester_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/diseqctester_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/DiseqcTester/meta/plugin_diseqctester.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/Makefile.am
lib/python/Plugins/SystemPlugins/NFIFlash/meta/Makefile.am
lib/python/Plugins/SystemPlugins/NFIFlash/meta/nfiflash.jpg [deleted file]
lib/python/Plugins/SystemPlugins/NFIFlash/meta/nfiflash_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NFIFlash/meta/nfiflash_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NFIFlash/meta/plugin_nfiflash.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/NFIFlash/plugin.py [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/networkwizard_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/networkwizard_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml
lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml
lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py
lib/python/Plugins/SystemPlugins/PositionerSetup/meta/plugin_positionersetup.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/PositionerSetup/meta/positionersetup.jpg [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/meta/plugin_satelliteequipmentcontrol.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/meta/satcontrol.jpg [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/Satfinder/meta/plugin_satfinder.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/Satfinder/meta/satfinder.jpg [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/SkinSelector/meta/Makefile.am
lib/python/Plugins/SystemPlugins/SkinSelector/meta/plugin_skinselector.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/SkinSelector/meta/skinselector.jpg [deleted file]
lib/python/Plugins/SystemPlugins/SkinSelector/meta/skinselector_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SkinSelector/meta/skinselector_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py
lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softmanager.jpg [deleted file]
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
lib/python/Plugins/SystemPlugins/TempFanControl/Makefile.am [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/TempFanControl/__init__.py [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/TempFanControl/plugin.py [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/Makefile.am
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/plugin_videoenhancement.xml
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/videoenhancement.jpg [deleted file]
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/videoenhancement_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/VideoEnhancement/meta/videoenhancement_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/VideoTune/meta/plugin_videotune.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/Videomode/HDMI.png [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Videomode/Makefile.am
lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
lib/python/Plugins/SystemPlugins/Videomode/lcd_HDMI.png [new file with mode: 0644]
lib/python/Plugins/SystemPlugins/Videomode/meta/Makefile.am
lib/python/Plugins/SystemPlugins/Videomode/meta/plugin_videomode.xml [changed mode: 0644->0755]
lib/python/Plugins/SystemPlugins/Videomode/meta/videomode.jpg [deleted file]
lib/python/Plugins/SystemPlugins/Videomode/meta/videomode_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/Videomode/meta/videomode_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/Videomode/plugin.py
lib/python/Plugins/SystemPlugins/Videomode/videowizard.xml
lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am
lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py
lib/python/Plugins/SystemPlugins/WirelessLan/meta/Makefile.am [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/meta/plugin_wirelesslan.xml [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/meta/wirelesslan_de.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/meta/wirelesslan_en.jpg [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py
lib/python/Plugins/newplugin.py
lib/python/Screens/ChannelSelection.py
lib/python/Screens/EpgSelection.py
lib/python/Screens/EventView.py
lib/python/Screens/InfoBar.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/LanguageSelection.py [changed mode: 0644->0755]
lib/python/Screens/LocationBox.py
lib/python/Screens/Makefile.am
lib/python/Screens/Menu.py [changed mode: 0644->0755]
lib/python/Screens/MessageBox.py
lib/python/Screens/MovieSelection.py
lib/python/Screens/NetworkSetup.py
lib/python/Screens/ParentalControlSetup.py [changed mode: 0755->0644]
lib/python/Screens/PluginBrowser.py
lib/python/Screens/RdsDisplay.py [changed mode: 0644->0755]
lib/python/Screens/RecordPaths.py [new file with mode: 0644]
lib/python/Screens/Satconfig.py
lib/python/Screens/ScanSetup.py
lib/python/Screens/Scart.py
lib/python/Screens/Screen.py
lib/python/Screens/ServiceStopScreen.py [new file with mode: 0644]
lib/python/Screens/SleepTimerEdit.py
lib/python/Screens/Standby.py
lib/python/Screens/TaskView.py
lib/python/Screens/TimerEdit.py
lib/python/Screens/TimerEntry.py
lib/python/Screens/UnhandledKey.py [new file with mode: 0644]
lib/python/Screens/VirtualKeyBoard.py
lib/python/Screens/Wizard.py
lib/python/Tools/Directories.py
lib/python/Tools/HardwareInfo.py
lib/service/iservice.h
lib/service/listboxservice.cpp
lib/service/listboxservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.cpp
lib/service/servicemp3.h
lib/service/servicexine.cpp
main/Makefile.am
main/enigma.cpp
mytest.py
po/Makefile.am
po/enigma2_rel25.pot [deleted file]
po/xml2po.py
skin.py [changed mode: 0644->0755]
tools/genmetaindex.py

index 2ca87f6..a905da1 100644 (file)
@@ -50,10 +50,10 @@ class Navigation:
                for x in self.record_event:
                        x(rec_service, event)
 
-       def playService(self, ref, checkParentalControl = True):
+       def playService(self, ref, checkParentalControl = True, forceRestart = False):
                oldref = self.currentlyPlayingServiceReference
-               if ref and oldref and ref == oldref:
-                       print "ignore request to play already running service"
+               if ref and oldref and ref == oldref and not forceRestart:
+                       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
index 4907f64..f670417 100644 (file)
@@ -2,6 +2,7 @@ from enigma import eEPGCache, getBestPlayableServiceReference, \
        eServiceReference, iRecordableService, quitMainloop
 
 from Components.config import config
+from Components.UsageConfig import defaultMoviePath
 from Components.TimerSanityCheck import TimerSanityCheck
 
 from Screens.MessageBox import MessageBox
@@ -141,11 +142,13 @@ class RecordTimerEntry(timer.TimerEntry, object):
                if config.recording.ascii_filenames.value:
                        filename = ASCIItranslit.legacyEncode(filename)
 
-               if self.dirname and not Directories.fileExists(self.dirname, 'w'):
-                       self.dirnameHadToFallback = True
-                       self.Filename = Directories.getRecordingFilename(filename, None)
+               if not self.dirname or not Directories.fileExists(self.dirname, 'w'):
+                       if self.dirname:
+                               self.dirnameHadToFallback = True
+                       dirname = defaultMoviePath()
                else:
-                       self.Filename = Directories.getRecordingFilename(filename, self.dirname)
+                       dirname = self.dirname
+               self.Filename = Directories.getRecordingFilename(filename, dirname)
                self.log(0, "Filename calculated as: '%s'" % self.Filename)
                #begin_date + " - " + service_name + description)
 
index 5e403de..d1b1d27 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
@@ -155,6 +157,7 @@ lib/python/Plugins/SystemPlugins/FrontprocessorUpgrade/meta/Makefile
 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/NetworkWizard/Makefile
 lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile
 lib/python/Plugins/SystemPlugins/NFIFlash/Makefile
@@ -176,6 +179,7 @@ lib/python/Plugins/SystemPlugins/VideoTune/meta/Makefile
 lib/python/Plugins/SystemPlugins/Videomode/Makefile
 lib/python/Plugins/SystemPlugins/Videomode/meta/Makefile
 lib/python/Plugins/SystemPlugins/WirelessLan/Makefile
+lib/python/Plugins/SystemPlugins/WirelessLan/meta/Makefile
 lib/python/Tools/Makefile
 lib/service/Makefile
 lib/components/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
@@ -1,6 +1,6 @@
 #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: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: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:7005:436: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: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: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:6D6E:437: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:3138:459:1: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
@@ -77,8 +75,6 @@
 #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:0:1:3339:45B:1:C00000:0:0:0:\r
-#SERVICE 1:0:1:27B9:444:1: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
@@ -92,7 +88,6 @@
 #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:2791:444:1: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: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:1324:3EF:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:1325:3EF:1:C00000:0:0:0:\r
-#SERVICE 1:0:19:2B84:3F3: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: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..5f89c48
--- /dev/null
@@ -0,0 +1,127 @@
+#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 14eeaef..a3cefe6 100644 (file)
@@ -1,28 +1,36 @@
 #Fallback encoding when in dvb-text no encoding table is given
 #Countycode ISO8859-X or ISO6397
+ara ISO8859-6
 tur ISO8859-9
 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.. 
 #so our default is ISO8859-1 without two char byte encoding
 #So all transponders which needs this must be listed here
 #TSID ONID
-0x447 0x1 #ASTRA 19.2 UPC Direct
-0x427 0x1 #ASTRA 19.2 UPC Direct
-0x44b 0x1 #ASTRA 19.2 UPC Direct
-0x4ff 0x1 #ASTRA 19.2 UPC Direct
-0x407 0x1 #ASTRA 19.2 UPC Direct
-0x436 0x1 #ASTRA 19.2 MTV Euro - MTV Networks
-0x42a 0x1 #ASTRA 19.2 VH1 Classic - MTV Networks
-0xbc6 0x3 #ASTRA 23.5 Cslink, Skylink
-0xc85 0x3 #ASTRA 23.5 Cslink, Skylink
-0xc89 0x3 #ASTRA 23.5 Cslink, Skylink
-0xc8f 0x3 #ASTRA 23.5 Cslink, Skylink
-0xbc7 0x3 #ASTRA 23.5 Cslink, Skylink
+0x447 0x1 # Astra 19.2°E 12.304 H - UPC Direct 
+0x427 0x1 # Astra 19.2°E 10.920 H - UPC Direct 
+0x44b 0x1 # Astra 19.2°E 12.382 H - UPC Direct
+0x4ff 0x1 # Astra 19.2°E 11.992 H - UPC Direct 
+0x407 0x1 # Astra 19.2°E 11.671 H - UPC Direct 
+0x436 0x1 # Astra 19.2°E 11.973 V - MTV Networks Europe
+0x42a 0x1 # Astra 19.2°E 11.739 V - MTV Networks Europe
+0xc23 0x3 # Astra 23.5°E 10.803 H - CS Link / SkyLink
+0xc85 0x3 # Astra 23.5°E 11.797 H - CS Link / SkyLink
+0xc89 0x3 # Astra 23.5°E 11.876 H - CS Link / SkyLink
+0xc8f 0x3 # Astra 23.5°E 11.992 H - CS Link / SkyLink
+0xc93 0x3 # Astra 23.5°E 12.070 H - CS Link / SkyLink
+0xc95 0x3 # Astra 23.5°E 12.109 H - SkyLink
+0xbc6 0x3 # Astra 23.5°E 12.525 V - CS Link / SkyLink
+0xbc7 0x3 # Astra 23.5°E 12.565 H - SkyLink
 400 318 #Hotbird 13.0 Cyfra+
 1000 318 #Hotbird 13.0 Grupa ITI
 1500 318 #Hotbird 13.0 Cyfra+
index 25538f8..9461d50 100755 (executable)
                <key id="KEY_BLUE" mapto="extensions" flags="b" />
        </map>
        
+       <map context="SatlistShortcutAction">
+               <key id="KEY_BLUE" mapto="nothingconnected" flags="b" />
+       </map>
+       
        <map context="InfobarChannelSelection">
                <key id="KEY_LEFT" mapto="zapUp" flags="mr" />
                <key id="KEY_RIGHT" mapto="zapDown" flags="mr" />
old mode 100644 (file)
new mode 100755 (executable)
index c7fb889..b437fbc
@@ -24,7 +24,7 @@
                <menu level="0" text="Information" entryID="info_screen">
                        <id val="information" />
                        <item level="1" text="Service" entryID="service_info_screen"><screen module="ServiceInfo" screen="ServiceInfo"/></item>
-                       <item level="0" text="About..." entryID="about_screen"><screen module="About" /></item>
+                       <item level="0" text="About" entryID="about_screen"><screen module="About" /></item>
                </menu>
 
                <item level="1" text="Plugins" entryID="plugin_selection"><screen module="PluginBrowser" screen="PluginBrowser" /></item>
@@ -48,7 +48,7 @@
                        </menu>
                        <menu weight="5" level="0" text="System" entryID="system_selection">
                                <id val="system" />
-                               <item level="0" text="Language..." entryID="language_setup"><screen module="LanguageSelection" /></item>
+                               <item level="0" text="Language" entryID="language_setup"><screen module="LanguageSelection" /></item>
                                <item level="0" entryID="usage_setup"><setup id="usage" /></item>
                                <item level="0" entryID="timezone_setup"><setup id="timezone"/></item>
                                <item level="0" entryID="av_setup"><setup id="avsetup"/></item>
                                <menu level="0" text="Harddisk" entryID="hardisk_selection" requires="Harddisk">
                                        <id val="harddisk" />
                                        <item level="1" entryID="harddisk_setup"><setup id="harddisk"/></item>
-                                       <item level="0" text="Initialization..." entryID="harddisk_init"><screen module="HarddiskSetup" screen="HarddiskSelection"/></item>
-                                       <item level="0" text="Filesystem Check..." entryID="harddisk_check"><screen module="HarddiskSetup" screen="HarddiskFsckSelection"/></item>
+                                       <item level="0" text="Initialization" entryID="harddisk_init"><screen module="HarddiskSetup" screen="HarddiskSelection"/></item>
+                                       <item level="0" text="Filesystem Check" entryID="harddisk_check"><screen module="HarddiskSetup" screen="HarddiskFsckSelection"/></item>
                                </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="0" text="Network" entryID="network_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection" /></item>
                                <item text="Keyboard"><setup id="keyboard" /></item>
                                <!--<menu level="1" text="Network..." entryID="network_setup">
                                        <id val="network" />
                                        <item level="1" text="Device Setup..." entryID="device_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection"/></item>
                                        <item level="1" text="Nameserver Setup..." entryID="dns_setup"><screen module="NetworkSetup" screen="NameserverSetup"/></item>
                                </menu>-->
-                               <item level="2" text="Timeshift path..." entryId="timeshift_path"><screen module="LocationBox" screen="TimeshiftLocationBox" /></item>
+                               <item level="2" text="Recording paths" entryId="RecordPaths"><screen module="RecordPaths" screen="RecordPathsSettings" /></item>
                        </menu>
                        <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
@@ -104,6 +98,7 @@ self.session.openWithCallback(msgClosed, FactoryReset)
                        <item text="Standby" entryID="standby"><screen module="Standby" screen="Standby"/></item>
                        <item text="Restart" entryID="restart"><screen module="Standby" screen="TryQuitMainloop">2</screen></item>
                        <item level="2" text="Restart GUI" entryID="restart_enigma"><screen module="Standby" screen="TryQuitMainloop">3</screen></item>
-                       <item text="Deep Standby" entryID="deep_standby"><screen module="Standby" screen="TryQuitMainloop">1</screen></item>
+                       <item text="Deep Standby" requires="DeepstandbySupport" entryID="deep_standby"><screen module="Standby" screen="TryQuitMainloop">1</screen></item>
+                       <item text="Shutdown" requires="!DeepstandbySupport" entryID="deep_standby"><screen module="Standby" screen="TryQuitMainloop">1</screen></item>
                </menu>
 </menu>
index 9425afd..705eaf3 100644 (file)
                        <item level="1" text="Change bouquets in quickzap">config.usage.quickzap_bouquet_change</item>
                        <item level="1" text="Alternative radio mode">config.usage.e1like_radio_mode</item>
                        <item level="1" text="Action on long powerbutton press">config.usage.on_long_powerpress</item>
+                       <item level="1" text="Action on short powerbutton press">config.usage.on_short_powerpress</item>
                        <item level="0" text="Infobar timeout">config.usage.infobar_timeout</item>
                        <item level="1" text="12V output" requires="12V_Output">config.usage.output_12V</item>
+                       <item level="0" text="Show event-progress in channel selection">config.usage.show_event_progress_in_servicelist</item>
                        <item level="2" text="Show infobar on channel change">config.usage.show_infobar_on_zap</item>
                        <item level="2" text="Show infobar on skip forward/backward">config.usage.show_infobar_on_skip</item>
                        <item level="2" text="Show infobar on event change">config.usage.show_infobar_on_event_change</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 16504ab..0114349 100755 (executable)
@@ -43,7 +43,9 @@
                <widget source="Adaptertext" render="Label" position="10,355" size="120,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
                <widget source="Adapter" render="Label" position="120,355" size="400,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
                <widget source="introduction2" render="Label" position="10,380" size="540,21" zPosition="10" font="Regular;21" halign="center" valign="center" backgroundColor="#25062748" transparent="1"/>
-               <widget name="VKeyIcon" pixmap="skin_default/buttons/key_text.png" position="10,380" zPosition="10" size="35,25" transparent="1" alphatest="on" />
+               <widget source="VKeyIcon" render="Pixmap" pixmap="skin_default/buttons/key_text.png" position="10,380" zPosition="10" size="35,25" transparent="1" alphatest="on" >
+                       <convert type="ConditionalShowHide" />
+               </widget>
                <widget name="HelpWindow" pixmap="skin_default/vkey_icon.png" position="160,315" zPosition="1" size="1,1" transparent="1" alphatest="on" />
        </screen>
 
@@ -68,8 +70,8 @@
                <widget name="menu" position="10,10" size="290,225" scrollbarMode="showOnDemand" />
        </screen>
        <!-- Channel context menu -->
-       <screen name="ChannelContextMenu" position="center,center" size="300,255" title="Channellist menu">
-               <widget name="menu" position="10,10" size="290,230" scrollbarMode="showOnDemand" />
+       <screen name="ChannelContextMenu" position="center,center" size="350,255" title="Channellist menu">
+               <widget name="menu" position="10,10" size="340,230" scrollbarMode="showOnDemand" />
        </screen>
        <!-- Channel selection - TV -->
        <screen name="ChannelSelection" position="center,center" size="560,430" title="Channel Selection">
@@ -248,9 +250,13 @@ self.instance.move(ePoint((720-wsizex)/2, (576-wsizey)/(count &gt; 7 and 2 or 3)
                        <widget name="arrowup2" pixmap="skin_default/arrowup.png" position="-100,-100" zPosition="11" size="37,70" transparent="1" alphatest="on"/>
        </screen>
        <!-- Dish -->
-       <screen name="Dish" flags="wfNoBorder" position="300,100" size="130,160" title="Dish" zPosition="-1" backgroundColor="transparent">
+       <screen name="Dish" flags="wfNoBorder" position="300,100" size="130,160" title="Dish" zPosition="100" backgroundColor="transparent">
                <widget name="Dishpixmap" pixmap="skin_default/icons/dish.png" position="0,0" size="130,160" alphatest="off" />
        </screen>
+       <!-- unhandled key pressed -->
+       <screen name="UnhandledKey" flags="wfNoBorder" position="620,50" size="34,45" title="UnhandledKey" zPosition="100" backgroundColor="transparent">
+               <widget name="UnhandledKeyPixmap" pixmap="skin_default/unhandled-key.png" position="0,0" size="34,45" alphatest="off" />
+       </screen>
        <!-- EPG Selection - Single -->
        <screen name="EPGSelection" position="center,center" size="560,430" title="EPG Selection">
                <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
@@ -566,9 +572,11 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y()))
                <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 name="list" position="5,50" size="550,280" scrollbarMode="showOnDemand" zPosition="10"/>
                <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" />
@@ -618,14 +626,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 e2d2abc..6038c2e
@@ -15,6 +15,7 @@ dist_install_DATA = \
        border_eventinfo.png \
        border_info.png \
        border_menu_300.png \
+       border_menu_350.png \
        border_menu.png \
        border_multiepg.png \
        bottombar.png \
@@ -22,6 +23,7 @@ dist_install_DATA = \
        b_tl.png \
        b_t.png \
        b_tr.png \
+       celserviceeventprogressbar.png \
        div-h.png \
        div-v.png \
        epg_more.png \
@@ -31,6 +33,8 @@ dist_install_DATA = \
        expanded-plugins.png \
        info-bg_mp.png \
        info-bg.png \
+       lock.png \
+       lockBouquet.png \
        mediaplayer_bg.png \
        mute.png \
        nim_active.png \
@@ -50,6 +54,9 @@ dist_install_DATA = \
        sleeptimer.png \
        timeline-now.png \
        timeline.png \
+       unhandled-key.png \
+       unlock.png \
+       unlockBouquet.png \
        verticalline-plugins.png \
        vkey_backspace.png \
        vkey_bg.png \
diff --git a/data/skin_default/border_menu_350.png b/data/skin_default/border_menu_350.png
new file mode 100755 (executable)
index 0000000..4f6f49c
Binary files /dev/null and b/data/skin_default/border_menu_350.png differ
diff --git a/data/skin_default/celserviceeventprogressbar.png b/data/skin_default/celserviceeventprogressbar.png
new file mode 100644 (file)
index 0000000..7bf5c65
Binary files /dev/null and b/data/skin_default/celserviceeventprogressbar.png differ
old mode 100644 (file)
new mode 100755 (executable)
index d6fcc7f..9ab4ff4
Binary files a/data/skin_default/div-h.png and b/data/skin_default/div-h.png differ
index f3c6548..6148e07 100644 (file)
Binary files a/data/skin_default/icons/dish.png and b/data/skin_default/icons/dish.png differ
diff --git a/data/skin_default/lock.png b/data/skin_default/lock.png
new file mode 100644 (file)
index 0000000..d0ae7f6
Binary files /dev/null and b/data/skin_default/lock.png differ
diff --git a/data/skin_default/lockBouquet.png b/data/skin_default/lockBouquet.png
new file mode 100644 (file)
index 0000000..d503dd2
Binary files /dev/null and b/data/skin_default/lockBouquet.png differ
diff --git a/data/skin_default/unhandled-key.png b/data/skin_default/unhandled-key.png
new file mode 100644 (file)
index 0000000..8e54349
Binary files /dev/null and b/data/skin_default/unhandled-key.png differ
diff --git a/data/skin_default/unlock.png b/data/skin_default/unlock.png
new file mode 100644 (file)
index 0000000..bd4486e
Binary files /dev/null and b/data/skin_default/unlock.png differ
diff --git a/data/skin_default/unlockBouquet.png b/data/skin_default/unlockBouquet.png
new file mode 100644 (file)
index 0000000..c5d146d
Binary files /dev/null and b/data/skin_default/unlockBouquet.png differ
index b61696f..669652e 100644 (file)
@@ -92,7 +92,7 @@ So this would only install the lamedb.192 file, if you have a DVB-S NIM in your
 - "image default"
   An image default is stored in /usr/share/enigma2/defaults. You can have several defaults at the same time, but you should keep
   in mind, that these defaults are all installed without user interaction. So defaults with contrary contents should be avoided
-  (e.g. setting a default parameter in one settings file an setting another setting for the same parameter in another could lead
+  (e.g. setting a default parameter in one settings file and setting another setting for the same parameter in another could lead
   to unexpected behaviour, since the installation order is undetermined and completely random. so use prerequisites insted)
   The "image default" is also used to set box specific config elements (for example show the new RC on a dm8000) and install the
   default bouquets.
index 0eb4cdb..a2d85ff 100644 (file)
@@ -208,7 +208,7 @@ void eActionMap::keyPressed(const std::string &device, int key, int flags)
                                }
                        } else
                        {
-                               eDebug("wildcard.");
+//                             eDebug("wildcard.");
                                ePyObject pArgs = PyTuple_New(2);
                                PyTuple_SET_ITEM(pArgs, 0, PyInt_FromLong(key));
                                PyTuple_SET_ITEM(pArgs, 1, PyInt_FromLong(flags));
index 313732a..5bafe73 100644 (file)
@@ -225,6 +225,7 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
        }
 
        m_is_idle = 1;
+       ++m_idle_count;
 
        if (this == eApp)
        {
index 524052b..c69133f 100644 (file)
@@ -195,6 +195,7 @@ class eMainloop
        int processOneEvent(unsigned int user_timeout, PyObject **res=0, ePyObject additional=ePyObject());
        int retval;
        int m_is_idle;
+       int m_idle_count;
        eSocketNotifier *m_inActivate;
 
        int m_interrupt_requested;
@@ -210,7 +211,7 @@ public:
 #endif
 
        eMainloop()
-               :app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_inActivate(0), m_interrupt_requested(0)
+               :app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_idle_count(0), m_inActivate(0), m_interrupt_requested(0)
        {
                existing_loops.push_back(this);
        }
@@ -240,6 +241,7 @@ public:
 
                /* m_is_idle needs to be atomic, but it doesn't really matter much, as it's read-only from outside */
        int isIdle() { return m_is_idle; }
+       int idleCount() { return m_idle_count; }
 };
 
 /**
index 51582e6..0175718 100644 (file)
@@ -83,9 +83,18 @@ class eSingleLock
        pthread_mutex_t m_lock;
        eSingleLock(eSingleLock &);
 public:
-       eSingleLock()
+       eSingleLock(bool recursive=false)
        {
-               pthread_mutex_init(&m_lock, 0);
+               if (recursive)
+               {
+                       pthread_mutexattr_t attr;
+                       pthread_mutexattr_init(&attr);
+                       pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+                       pthread_mutex_init(&m_lock, &attr);
+                       pthread_mutexattr_destroy(&attr);
+               }
+               else
+                       pthread_mutex_init(&m_lock, 0);
        }
        ~eSingleLock()
        {
index 3412c84..91f24ba 100644 (file)
@@ -37,7 +37,6 @@ void eFilePushThread::thread()
        
        size_t written_since_last_sync = 0;
 
-       int already_empty = 0;
        eDebug("FILEPUSH THREAD START");
        
                /* we set the signal to not restart syscalls, so we can detect our signal. */
@@ -186,21 +185,23 @@ void eFilePushThread::thread()
                if (m_buf_end == 0)
                {
                                /* on EOF, try COMMITting once. */
-                       if (m_send_pvr_commit && !already_empty)
+                       if (m_send_pvr_commit)
                        {
-                               eDebug("sending PVR commit");
-                               
                                struct pollfd pfd;
                                pfd.fd = m_fd_dest;
                                pfd.events = POLLIN;
-                               poll(&pfd, 1, 10000);
-                               sleep(5); /* HACK to allow ES buffer to drain */
-                               already_empty = 1;
-//                             if (::ioctl(m_fd_dest, PVR_COMMIT) < 0 && errno == EINTR)
-//                                     continue;
-                               eDebug("commit done");
-                                               /* well check again */
-                               continue;
+                               switch (poll(&pfd, 1, 250)) // wait for 250ms
+                               {
+                                       case 0:
+                                               eDebug("wait for driver eof timeout");
+                                               continue;
+                                       case 1:
+                                               eDebug("wait for driver eof ok");
+                                               break;
+                                       default:
+                                               eDebug("wait for driver eof aborted by signal");
+                                               continue;
+                               }
                        }
                        
                                /* in stream_mode, we are sending EOF events 
@@ -230,7 +231,6 @@ void eFilePushThread::thread()
                        bytes_read += m_buf_end;
                        if (m_sg)
                                current_span_remaining -= m_buf_end;
-                       already_empty = 0;
                }
 //             printf("FILEPUSH: read %d bytes\n", m_buf_end);
        }
index fb25740..3117b5e 100644 (file)
 extern "C" int sys_ioprio_set(int, int, int);
 extern "C" int sys_ioprio_get(int, int);
 
-#if defined(__i386__)
-#define __NR_ioprio_set                289
-#define __NR_ioprio_get                290
-#elif defined(__ppc__) || defined(__powerpc__)
-#define __NR_ioprio_set                273
-#define __NR_ioprio_get                274
-#elif defined(__x86_64__)
-#define __NR_ioprio_set                251
-#define __NR_ioprio_get                252
-#elif defined(__ia64__)
-#define __NR_ioprio_set                1274
-#define __NR_ioprio_get                1275
-#elif defined(__mips__)
-#define __NR_ioprio_set                4284
-#define __NR_ioprio_get                4285
-#else
-#error "Unsupported arch"
+#ifndef __NR_ioprio_set
+       #if defined(__i386__)
+               #define __NR_ioprio_set         289
+               #define __NR_ioprio_get         290
+       #elif defined(__ppc__) || defined(__powerpc__)
+               #define __NR_ioprio_set         273
+               #define __NR_ioprio_get         274
+       #elif defined(__x86_64__)
+               #define __NR_ioprio_set         251
+               #define __NR_ioprio_get         252
+       #elif defined(__ia64__)
+               #define __NR_ioprio_set         1274
+               #define __NR_ioprio_get         1275
+       #elif defined(__mips__)
+               #define __NR_ioprio_set         4284
+               #define __NR_ioprio_get         4285
+       #else
+               #error "Unsupported arch"
+       #endif
 #endif
 
 #if defined(_syscall3) && defined(_syscall2)
index c7acd11..c1ff13e 100644 (file)
@@ -81,7 +81,6 @@ eRCShortDriver::eRCShortDriver(const char *filename): eRCDriver(eRCInput::getIns
        {
                sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
                CONNECT(sn->activated, eRCShortDriver::keyPressed);
-               eRCInput::getInstance()->setFile(handle);
        }
 }
 
@@ -115,7 +114,6 @@ eRCInputEventDriver::eRCInputEventDriver(const char *filename): eRCDriver(eRCInp
        {
                sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
                CONNECT(sn->activated, eRCInputEventDriver::keyPressed);
-               eRCInput::getInstance()->setFile(handle);
        }
 }
 
@@ -127,6 +125,19 @@ std::string eRCInputEventDriver::getDeviceName()
        return name;
 }
 
+void eRCInputEventDriver::setExclusive(bool b)
+{
+       if (handle >= 0)
+       {
+               long evbits;
+               int grab = b;
+               if (::ioctl(handle, EVIOCGBIT(0, EV_MAX+1), &evbits) < 0)
+                       perror("EVIOCGBIT");
+               else if ((evbits & (1 << 0x1E)) && ::ioctl(handle, EVIOCGRAB, grab) < 0)
+                       perror("EVIOCGRAB");
+       }
+}
+
 eRCInputEventDriver::~eRCInputEventDriver()
 {
        if (handle>=0)
@@ -165,7 +176,6 @@ eRCInput::eRCInput()
 {
        ASSERT( !instance);
        instance=this;
-       handle = -1;
        locked = 0;
        keyboardMode = kmNone;
 }
@@ -183,21 +193,18 @@ bool eRCInput::open()
        return false;
 }
 
-int eRCInput::lock()
+void eRCInput::lock()
 {
        locked=1;
-       return handle;
+       for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
+               i->second->setExclusive(false);
 }
 
 void eRCInput::unlock()
 {
-       if (locked)
-               locked=0;
-}
-
-void eRCInput::setFile(int newh)
-{
-       handle=newh;
+       locked=0;
+       for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
+               i->second->setExclusive(true);
 }
 
 void eRCInput::addDevice(const std::string &id, eRCDevice *dev)
@@ -216,7 +223,7 @@ eRCDevice *eRCInput::getDevice(const std::string &id)
        if (i == devices.end())
        {
                eDebug("failed, possible choices are:");
-               for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)     
+               for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
                        eDebug("%s", i->first.c_str());
                return 0;
        }
index 9708ea7..5290946 100644 (file)
@@ -53,6 +53,7 @@ public:
         * \param key The key to get the description for.
         * \result User readable description of given key.
         */
+       virtual void setExclusive(bool b) { };
 };
 
 /**
@@ -89,6 +90,7 @@ public:
        ~eRCDriver();
        
        void enable(int en) { enabled=en; }
+       virtual void setExclusive(bool) { }
 };
 
 class eRCShortDriver: public eRCDriver
@@ -112,6 +114,7 @@ public:
        std::string getDeviceName();
        eRCInputEventDriver(const char *filename);
        ~eRCInputEventDriver();
+       void setExclusive(bool b); // in exclusive mode data is not carried to console device
 };
 
 class eRCKey
@@ -173,7 +176,6 @@ public:
 class eRCInput: public Object
 {
        int locked;     
-       int handle;
        static eRCInput *instance;
        int keyboardMode;
 #ifdef SWIG
@@ -199,8 +201,6 @@ public:
        void close();
        bool open();
 
-       void setFile(int handle);
-
        /* This is only relevant for "keyboard"-styled input devices,
           i.e. not plain remote controls. It's up to the input device
           driver to decide wheter an input device is a keyboard or
@@ -237,7 +237,7 @@ public:
        void setKeyboardMode(int mode) { keyboardMode = mode; }
        int  getKeyboardMode() { return keyboardMode; }
        static eRCInput *getInstance() { return instance; }
-       int lock();
+       void lock();
        void unlock();
        int islocked() { return locked; }
 };
index bcce560..eb5aee3 100644 (file)
@@ -16,7 +16,6 @@ eRCConsoleDriver::eRCConsoleDriver(const char *filename): eRCDriver(eRCInput::ge
        {
                sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
                CONNECT(sn->activated, eRCConsoleDriver::keyPressed);
-               eRCInput::getInstance()->setFile(handle);
        }
        
                /* set console mode */
index d10d94f..2bfeefa 100644 (file)
@@ -83,8 +83,14 @@ eRCDeviceInputDev::eRCDeviceInputDev(eRCInputEventDriver *driver)
                        break;
                }
        }
+       setExclusive(true);
        eDebug("Input device \"%s\" is %sa keyboard.", id.c_str(), iskeyboard ? "" : "not ");
+}
 
+void eRCDeviceInputDev::setExclusive(bool b)
+{
+       if (!iskeyboard)
+               driver->setExclusive(b);
 }
 
 const char *eRCDeviceInputDev::getDescription() const
index c7f5697..3b4579c 100644 (file)
@@ -10,6 +10,7 @@ public:
        void handleCode(long code);
        eRCDeviceInputDev(eRCInputEventDriver *driver);
        const char *getDescription() const;
+       void setExclusive(bool);
 };
 
 #endif
index 90bf19e..ef8dadc 100644 (file)
@@ -222,9 +222,6 @@ int eDVBAudio::startPid(int pid, int type)
 
 void eDVBAudio::stop()
 {
-#if HAVE_DVB_API_VERSION > 2
-       flush();
-#endif
        eDebugNoNewLine("AUDIO_STOP - ");
        if (::ioctl(m_fd, AUDIO_STOP) < 0)
                eDebug("failed (%m)");
@@ -1048,9 +1045,9 @@ int eTSMPEGDecoder::setState()
 int eTSMPEGDecoder::m_pcm_delay=-1,
        eTSMPEGDecoder::m_ac3_delay=-1;
 
-RESULT eTSMPEGDecoder::setPCMDelay(int delay)
+RESULT eTSMPEGDecoder::setHwPCMDelay(int delay)
 {
-       if (m_decoder == 0 && delay != m_pcm_delay )
+       if (delay != m_pcm_delay )
        {
                FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
                if (fp)
@@ -1064,9 +1061,9 @@ RESULT eTSMPEGDecoder::setPCMDelay(int delay)
        return -1;
 }
 
-RESULT eTSMPEGDecoder::setAC3Delay(int delay)
+RESULT eTSMPEGDecoder::setHwAC3Delay(int delay)
 {
-       if ( m_decoder == 0 && delay != m_ac3_delay )
+       if ( delay != m_ac3_delay )
        {
                FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
                if (fp)
@@ -1080,6 +1077,17 @@ RESULT eTSMPEGDecoder::setAC3Delay(int delay)
        return -1;
 }
 
+
+RESULT eTSMPEGDecoder::setPCMDelay(int delay)
+{
+       return m_decoder == 0 ? setHwPCMDelay(delay) : -1;
+}
+
+RESULT eTSMPEGDecoder::setAC3Delay(int delay)
+{
+       return m_decoder == 0 ? setHwAC3Delay(delay) : -1;
+}
+
 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder)
        : m_demux(demux), 
                m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1),
index b53638b..3a0fbac 100644 (file)
@@ -193,6 +193,8 @@ public:
        int getVideoProgressive();
        int getVideoFrameRate();
        int getVideoAspect();
+       static RESULT setHwPCMDelay(int delay);
+       static RESULT setHwAC3Delay(int delay);
 };
 
 #endif
index 894287e..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!");
@@ -1462,12 +1460,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                        continue;
                }
                
-               size_t iframe_len;
-                       /* try to align to iframe */
-               int direction = pts < 0 ? -1 : 1;
-               m_tstools.findFrame(offset, iframe_len, direction);
-
-               eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
+               eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
                current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
        }
 
@@ -1771,6 +1764,8 @@ RESULT eDVBChannel::playFile(const char *file)
        m_pvr_thread->setStreamMode(1);
        m_pvr_thread->setScatterGather(this);
 
+       m_event(this, evtPreStart);
+
        if (m_pvr_thread->start(file, m_pvr_fd_dst))
        {
                delete m_pvr_thread;
index f80e177..48cbfbf 100644 (file)
@@ -255,6 +255,11 @@ void eEPGCache::DVBChannelAdded(eDVBChannel *chan)
 #ifdef ENABLE_PRIVATE_EPG
                data->m_PrivatePid = -1;
 #endif
+#ifdef ENABLE_MHW_EPG
+               data->m_mhw2_channel_pid = 0x231; // defaults for astra 19.2 D+
+               data->m_mhw2_title_pid = 0x234; // defaults for astra 19.2 D+
+               data->m_mhw2_summary_pid = 0x236; // defaults for astra 19.2 D+
+#endif
                singleLock s(channel_map_lock);
                m_knownChannels.insert( std::pair<iDVBChannel*, channel_data* >(chan, data) );
                chan->connectStateChange(slot(*this, &eEPGCache::DVBChannelStateChanged), data->m_stateChangedConn);
@@ -880,6 +885,62 @@ void eEPGCache::gotMessage( const Message &msg )
                        break;
                }
 #endif
+#ifdef ENABLE_MHW_EPG
+               case Message::got_mhw2_channel_pid:
+               {
+                       singleLock s(channel_map_lock);
+                       for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
+                       {
+                               eDVBChannel *channel = (eDVBChannel*) it->first;
+                               channel_data *data = it->second;
+                               eDVBChannelID chid = channel->getChannelID();
+                               if ( chid.transport_stream_id.get() == msg.service.tsid &&
+                                       chid.original_network_id.get() == msg.service.onid )
+                               {
+                                       data->m_mhw2_channel_pid = msg.pid;
+                                       eDebug("[EPGC] got mhw2 channel pid %04x", msg.pid);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case Message::got_mhw2_title_pid:
+               {
+                       singleLock s(channel_map_lock);
+                       for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
+                       {
+                               eDVBChannel *channel = (eDVBChannel*) it->first;
+                               channel_data *data = it->second;
+                               eDVBChannelID chid = channel->getChannelID();
+                               if ( chid.transport_stream_id.get() == msg.service.tsid &&
+                                       chid.original_network_id.get() == msg.service.onid )
+                               {
+                                       data->m_mhw2_title_pid = msg.pid;
+                                       eDebug("[EPGC] got mhw2 title pid %04x", msg.pid);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case Message::got_mhw2_summary_pid:
+               {
+                       singleLock s(channel_map_lock);
+                       for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
+                       {
+                               eDVBChannel *channel = (eDVBChannel*) it->first;
+                               channel_data *data = it->second;
+                               eDVBChannelID chid = channel->getChannelID();
+                               if ( chid.transport_stream_id.get() == msg.service.tsid &&
+                                       chid.original_network_id.get() == msg.service.onid )
+                               {
+                                       data->m_mhw2_summary_pid = msg.pid;
+                                       eDebug("[EPGC] got mhw2 summary pid %04x", msg.pid);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+#endif
                case Message::timeChanged:
                        cleanLoop();
                        break;
@@ -1175,7 +1236,7 @@ void eEPGCache::channel_data::startEPG()
        isRunning |= MHW;
        memcpy(&m_MHWFilterMask, &mask, sizeof(eDVBSectionFilterMask));
 
-       mask.pid = 0x231;
+       mask.pid = m_mhw2_channel_pid;
        mask.data[0] = 0xC8;
        mask.mask[0] = 0xFF;
        mask.data[1] = 0;
@@ -1186,6 +1247,7 @@ void eEPGCache::channel_data::startEPG()
        memcpy(&m_MHWFilterMask2, &mask, sizeof(eDVBSectionFilterMask));
        mask.data[1] = 0;
        mask.mask[1] = 0;
+       m_MHWTimeoutet=false;
 #endif
 
        mask.pid = 0x12;
@@ -1717,6 +1779,7 @@ void fillTuple(ePyObject tuple, const char *argstring, int argcount, ePyObject s
                                ++argcount;
                                continue;
                        default:  // ignore unknown
+                               tmp = ePyObject();
                                eDebug("fillTuple unknown '%c'... insert 'None' in result", c);
                }
                if (!tmp)
@@ -2061,6 +2124,7 @@ void fillTuple2(ePyObject tuple, const char *argstring, int argcount, eventData
                                inc_refcount = true;
                                break;
                        default:  // ignore unknown
+                               tmp = ePyObject();
                                eDebug("fillTuple2 unknown '%c'... insert None in Result", argstring[pos]);
                }
                if (!tmp)
@@ -2487,6 +2551,50 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler)
                                int tmp=0;
                                switch ((*es)->getType())
                                {
+                               case 0xC1: // user private
+                                       for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
+                                               desc != (*es)->getDescriptors()->end(); ++desc)
+                                       {
+                                               switch ((*desc)->getTag())
+                                               {
+                                                       case 0xC2: // user defined
+                                                               if ((*desc)->getLength() == 8) 
+                                                               {
+                                                                       __u8 buffer[10];
+                                                                       (*desc)->writeToBuffer(buffer);
+                                                                       if (!strncmp((unsigned char*)buffer+2, "EPGDATA", 7))
+                                                                       {
+                                                                               eServiceReferenceDVB ref;
+                                                                               if (!pmthandler->getServiceReference(ref))
+                                                                               {
+                                                                                       int pid = (*es)->getPid();
+                                                                                       messages.send(Message(Message::got_mhw2_channel_pid, ref, pid));
+                                                                               }
+                                                                       }
+                                                                       else if(!strncmp((unsigned char*)buffer+2, "FICHAS", 6))
+                                                                       {
+                                                                               eServiceReferenceDVB ref;
+                                                                               if (!pmthandler->getServiceReference(ref))
+                                                                               {
+                                                                                       int pid = (*es)->getPid();
+                                                                                       messages.send(Message(Message::got_mhw2_summary_pid, ref, pid));
+                                                                               }
+                                                                       }
+                                                                       else if(!strncmp((unsigned char*)buffer+2, "GENEROS", 7))
+                                                                       {
+                                                                               eServiceReferenceDVB ref;
+                                                                               if (!pmthandler->getServiceReference(ref))
+                                                                               {
+                                                                                       int pid = (*es)->getPid();
+                                                                                       messages.send(Message(Message::got_mhw2_title_pid, ref, pid));
+                                                                               }
+                                                                       }
+                                                               }
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+                                       }
                                case 0x05: // private
                                        for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
                                                desc != (*es)->getDescriptors()->end(); ++desc)
@@ -2891,7 +2999,7 @@ void eEPGCache::channel_data::storeTitle(std::map<__u32, mhw_title_t>::iterator
        packet->segment_last_table_id = 0x50;
 
        __u8 *title = isMHW2 ? ((__u8*)(itTitle->second.title))-4 : (__u8*)itTitle->second.title;
-       std::string prog_title = (char *) delimitName( title, name, isMHW2 ? 33 : 23 );
+       std::string prog_title = (char *) delimitName( title, name, isMHW2 ? 35 : 23 );
        int prog_title_length = prog_title.length();
 
        int packet_length = EIT_SIZE + EIT_LOOP_SIZE + EIT_SHORT_EVENT_DESCRIPTOR_SIZE +
@@ -3220,14 +3328,14 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
        {
                eDebug("[EPGC] mhw2 aborted %d", state);
        }
-       else if (m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
+       else if (m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
        // Channels table
        {
-               int num_channels = data[119];
+               int num_channels = data[120];
                m_channels.resize(num_channels);
-               if(dataLen > 119)
+               if(dataLen > 120)
                {
-                       int ptr = 120 + 8 * num_channels;
+                       int ptr = 121 + 8 * num_channels;
                        if( dataLen > ptr )
                        {
                                for( int chid = 0; chid < num_channels; ++chid )
@@ -3243,7 +3351,7 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
                else
                        goto abort;
                // data seems consistent...
-               const __u8 *tmp = data+120;
+               const __u8 *tmp = data+121;
                for (int i=0; i < num_channels; ++i)
                {
                        mhw_channel_name_t channel;
@@ -3254,6 +3362,7 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
                        channel.channel_id_hi = *(tmp++);
                        channel.channel_id_lo = *(tmp++);
                        m_channels[i]=channel;
+//                     eDebug("%d(%02x) %04x: %02x %02x", i, i, (channel.channel_id_hi << 8) | channel.channel_id_lo, *tmp, *(tmp+1));
                        tmp+=2;
                }
                for (int i=0; i < num_channels; ++i)
@@ -3264,83 +3373,86 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
                        for (; x < channel_name_len; ++x)
                                channel.name[x]=*(tmp++);
                        channel.name[x+1]=0;
+//                     eDebug("%d(%02x) %s", i, i, channel.name);
                }
                haveData |= MHW;
                eDebug("[EPGC] mhw2 %d channels found", m_channels.size());
        }
-       else if (m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
+       else if (m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
        {
                // Themes table
                eDebug("[EPGC] mhw2 themes nyi");
        }
-       else if (m_MHWFilterMask2.pid == 0x234 && m_MHWFilterMask2.data[0] == 0xe6)
+       else if (m_MHWFilterMask2.pid == m_mhw2_title_pid && m_MHWFilterMask2.data[0] == 0xe6)
        // Titles table
        {
                int pos=18;
-               bool valid=true;
-               int len = ((data[1]&0xf)<<8) + data[2] - 16;
+               bool valid=false;
                bool finish=false;
-               if(data[dataLen-1] != 0xff)
-                       return;
-               while( pos < dataLen )
+
+//             eDebug("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+//                     data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10],
+//                     data[11], data[12], data[13], data[14], data[15], data[16], data[17] );
+
+               while( pos < dataLen && !valid)
                {
-                       valid = false;
-                       pos += 7;
-                       if( pos < dataLen )
-                       {
-                               pos += 3;
-                               if( pos < dataLen )
-                               {
-                                       if( data[pos] > 0xc0 )
-                                       {
-                                               pos += ( data[pos] - 0xc0 );
-                                               pos += 4;
-                                               if( pos < dataLen )
-                                               {
-                                                       if( data[pos] == 0xff )
-                                                       {
-                                                               ++pos;
-                                                               valid = true;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if( !valid )
-                       {
-                               if (checkTimeout())
-                                       goto start_summary;
-                               return;
-                       }
+                       pos += 18;
+                       pos += (data[pos] & 0x3F) + 4;
+                       if( pos == dataLen )
+                               valid = true;
                }
+
+               if (!valid)
+               {
+                       if (dataLen > 18)
+                               eDebug("mhw2 title table invalid!!");
+                       if (checkTimeout())
+                               goto abort;
+                       if (!m_MHWTimeoutTimer->isActive())
+                               startTimeout(5000);
+                       return; // continue reading
+               }
+
                // data seems consistent...
                mhw_title_t title;
                pos = 18;
-               while (pos < len)
+               while (pos < dataLen)
                {
+//                     eDebugNoNewLine("    [%02x] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x [%02x %02x %02x %02x %02x %02x %02x] LL - DESCR - ",
+//                             data[pos], data[pos+1], data[pos+2], data[pos+3], data[pos+4], data[pos+5], data[pos+6], data[pos+7], 
+//                             data[pos+8], data[pos+9], data[pos+10], data[pos+11], data[pos+12], data[pos+13], data[pos+14], data[pos+15], data[pos+16], data[pos+17]);
                        title.channel_id = data[pos]+1;
-                       title.program_id_ml = data[pos+1];
-                       title.program_id_lo = data[pos+2];
-                       title.mhw2_mjd_hi = data[pos+3];
-                       title.mhw2_mjd_lo = data[pos+4];
-                       title.mhw2_hours = data[pos+5];
-                       title.mhw2_minutes = data[pos+6];
-                       title.mhw2_seconds = data[pos+7];
-                       int duration = ((data[pos+8] << 8)|data[pos+9]) >> 4;
+                       title.mhw2_mjd_hi = data[pos+11];
+                       title.mhw2_mjd_lo = data[pos+12];
+                       title.mhw2_hours = data[pos+13];
+                       title.mhw2_minutes = data[pos+14];
+                       title.mhw2_seconds = data[pos+15];
+                       int duration = ((data[pos+16] << 8)|data[pos+17]) >> 4;
                        title.mhw2_duration_hi = (duration&0xFF00) >> 8;
                        title.mhw2_duration_lo = duration&0xFF;
-                       __u8 slen = data[pos+10] & 0x3f;
+
+                       // Create unique key per title
+                       __u32 title_id = (data[pos+7] << 24) | (data[pos+8] << 16) | (data[pos+9] << 8) | data[pos+10];
+
+                       __u8 slen = data[pos+18] & 0x3f;
                        __u8 *dest = ((__u8*)title.title)-4;
-                       memcpy(dest, &data[pos+11], slen>33 ? 33 : slen);
-                       memset(dest+slen, 0, 33-slen);
-                       pos += 11 + slen;
+                       memcpy(dest, &data[pos+19], slen>35 ? 35 : slen);
+                       memset(dest+slen, 0, 35-slen);
+                       pos += 19 + slen;
+//                     eDebug("%02x [%02x %02x]: %s", data[pos], data[pos+1], data[pos+2], dest);
+
 //                     not used theme id (data[7] & 0x3f) + (data[pos] & 0x3f);
                        __u32 summary_id = (data[pos+1] << 8) | data[pos+2];
 
-                       // Create unique key per title
-                       __u32 title_id = (title.channel_id<<16) | (title.program_id_ml<<8) | title.program_id_lo;
+//                     if (title.channel_id > m_channels.size())
+//                             eDebug("channel_id(%d %02x) to big!!", title.channel_id);
+
+//                     eDebug("pos %d prog_id %02x %02x chid %02x summary_id %04x dest %p len %d\n",
+//                             pos, title.program_id_ml, title.program_id_lo, title.channel_id, summary_id, dest, slen);
 
-                       pos += 4;
+//                     eDebug("title_id %08x -> summary_id %04x\n", title_id, summary_id);
+
+                       pos += 3;
 
                        std::map<__u32, mhw_title_t>::iterator it = m_titles.find( title_id );
                        if ( it == m_titles.end() )
@@ -3379,7 +3491,7 @@ start_summary:
                        {
                                // Titles table has been read, there are summaries to read.
                                // Start reading summaries, store corresponding titles on the fly.
-                               startMHWReader2(0x236, 0x96);
+                               startMHWReader2(m_mhw2_summary_pid, 0x96);
                                startTimeout(15000);
                                return;
                        }
@@ -3387,7 +3499,7 @@ start_summary:
                else
                        return;
        }
-       else if (m_MHWFilterMask2.pid == 0x236 && m_MHWFilterMask2.data[0] == 0x96)
+       else if (m_MHWFilterMask2.pid == m_mhw2_summary_pid && m_MHWFilterMask2.data[0] == 0x96)
        // Summaries table
        {
                if (!checkTimeout())
@@ -3421,10 +3533,13 @@ start_summary:
                        }
                        else
                                return;  // continue reading
+
                        if (valid)
                        {
                                // data seems consistent...
                                __u32 summary_id = (data[3]<<8)|data[4];
+//                             eDebug ("summary id %04x\n", summary_id);
+//                             eDebug("[%02x %02x] %02x %02x %02x %02x %02x %02x %02x %02x XX\n", data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13] );
 
                                // ugly workaround to convert const __u8* to char*
                                char *tmp=0;
@@ -3442,7 +3557,7 @@ start_summary:
                                        len += lenline + 1;
                                }
                                if( len > 0 )
-                                   tmp[pos+len] = 0;
+                                       tmp[pos+len] = 0;
                                else
                                        tmp[pos+1] = 0;
 
@@ -3458,8 +3573,11 @@ start_summary:
                                        startTimeout(15000);
                                        std::string the_text = (char *) (data + pos + 1);
 
+//                                     eDebug ("summary id %04x : %s\n", summary_id, data+pos+1);
+
                                        while( itProgId != m_program_ids.end() && itProgId->first == summary_id )
                                        {
+//                                             eDebug(".");
                                                // Find corresponding title, store title and summary in epgcache.
                                                std::map<__u32, mhw_title_t>::iterator itTitle( m_titles.find( itProgId->second ) );
                                                if ( itTitle != m_titles.end() )
@@ -3479,16 +3597,16 @@ start_summary:
        }
        if (isRunning & eEPGCache::MHW)
        {
-               if ( m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
+               if ( m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
                {
                        // Channels table has been read, start reading the themes table.
-                       startMHWReader2(0x231, 0xC8, 1);
+                       startMHWReader2(m_mhw2_channel_pid, 0xC8, 1);
                        return;
                }
-               else if ( m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
+               else if ( m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
                {
                        // Themes table has been read, start reading the titles table.
-                       startMHWReader2(0x234, 0xe6);
+                       startMHWReader2(m_mhw2_title_pid, 0xe6);
                        return;
                }
                else
index 7d1b163..4d45d87 100644 (file)
@@ -202,6 +202,7 @@ class eEPGCache: public eMainloop, private eThread, public Object
                ePtr<iDVBSectionReader> m_MHWReader, m_MHWReader2;
                eDVBSectionFilterMask m_MHWFilterMask, m_MHWFilterMask2;
                ePtr<eTimer> m_MHWTimeoutTimer;
+               __u16 m_mhw2_channel_pid, m_mhw2_title_pid, m_mhw2_summary_pid;
                bool m_MHWTimeoutet;
                void MHWTimeout() { m_MHWTimeoutet=true; }
                void readMHWData(const __u8 *data);
@@ -242,6 +243,9 @@ public:
                        leaveChannel,
                        quit,
                        got_private_pid,
+                       got_mhw2_channel_pid,
+                       got_mhw2_title_pid,
+                       got_mhw2_summary_pid,
                        timeChanged
                };
                int type;
index c0263fb..8216eea 100644 (file)
@@ -455,7 +455,7 @@ int eDVBFrontend::PriorityOrder=0;
 
 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate)
        :m_simulate(simulate), m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe)
-       ,m_fd(-1), m_need_rotor_workaround(false), m_can_handle_dvbs2(false)
+       ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false)
        ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
 #if HAVE_DVB_API_VERSION < 3
        ,m_secfd(-1)
@@ -483,6 +483,13 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate)
        closeFrontend();
 }
 
+void eDVBFrontend::reopenFrontend()
+{
+       closeFrontend();
+       m_type = -1;
+       openFrontend();
+}
+
 int eDVBFrontend::openFrontend()
 {
        if (m_state != stateClosed)
@@ -692,7 +699,8 @@ void eDVBFrontend::feEvent(int w)
                        {
                                eDebug("stateLostLock");
                                state = stateLostLock;
-                               sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
+                               if (!m_rotor_mode)
+                                       sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
                        }
                }
                if (m_state != state)
@@ -2343,6 +2351,20 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
                        res = -EINVAL;
                        goto tune_error;
                }
+               if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
+               {
+                       eDVBFrontend *sec_fe = this;
+                       long tmp = m_data[LINKED_PREV_PTR];
+                       while (tmp != -1)
+                       {
+                               eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
+                               sec_fe = linked_fe->m_frontend;
+                               sec_fe->getData(LINKED_NEXT_PTR, tmp);
+                       }
+                       eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
+                       sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = sec_fe->m_data[ROTOR_CMD] = sec_fe->m_data[ROTOR_POS] = -1; // reset diseqc
+               }
+               m_rotor_mode = feparm.no_rotor_command_on_tune;
                if (!m_simulate)
                        m_sec->setRotorMoving(m_slotid, false);
                res=prepare_sat(feparm, timeout);
index bac2753..bc31755 100644 (file)
@@ -75,6 +75,7 @@ private:
        int m_dvbid;
        int m_slotid;
        int m_fd;
+       bool m_rotor_mode;
        bool m_need_rotor_workaround;
        bool m_can_handle_dvbs2;
        char m_filename[128];
@@ -145,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 cff4dbb..a3e87e3 100644 (file)
@@ -459,6 +459,7 @@ class iDVBFrontend: public iDVBFrontend_ENUMS, public iObject
 public:
        virtual RESULT getFrontendType(int &SWIG_OUTPUT)=0;
        virtual RESULT tune(const iDVBFrontendParameters &where)=0;
+       virtual void reopenFrontend()=0;
 #ifndef SWIG
        virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
 #endif
@@ -522,7 +523,7 @@ public:
        virtual RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &)=0;
        enum 
        {
-               evtEOF, evtSOF, evtFailed
+               evtPreStart, evtEOF, evtSOF, evtFailed
        };
        virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
        virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
index 0b4904f..f06c86e 100644 (file)
@@ -78,9 +78,9 @@ typedef struct {
    u_char ppv_id_ml                              :8;
    u_char ppv_id_lo                              :8;
    u_char program_id_hi                          :8;
-   u_char program_id_mh                          :8; // mhw2_title end (33chars max)
+   u_char program_id_mh                          :8;
    u_char program_id_ml                          :8;
-   u_char program_id_lo                          :8;
+   u_char program_id_lo                          :8; // mhw2_title end (35chars max)
    u_char mhw2_mjd_hi                            :8;
    u_char mhw2_mjd_lo                            :8;
    u_char mhw2_duration_hi                       :8;
index 9bd065b..ee89a3a 100644 (file)
@@ -75,6 +75,9 @@ void eDVBServicePMTHandler::channelEvent(iDVBChannel *channel, int event)
 {
        switch (event)
        {
+       case iDVBChannel::evtPreStart:
+               serviceEvent(eventPreStart);
+               break;
        case iDVBChannel::evtEOF:
                serviceEvent(eventEOF);
                break;
index a9ca23f..483c06b 100644 (file)
@@ -123,6 +123,7 @@ public:
                eventNewProgramInfo, // we just received a PMT
                eventTuned,        // a channel was sucessfully (re-)tuned in, you may start additional filters now
                
+               eventPreStart,     // before start filepush thread
                eventSOF,          // seek pre start
                eventEOF,          // a file playback did end
                
index 1393bf7..5cdecbd 100644 (file)
@@ -244,6 +244,7 @@ off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg)
        off_t last = 0;
        off_t last2 = 0;
        pts_t lastc = 0;
+       ts += 1; // Add rounding error margin
        for (std::map<off_t, pts_t>::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i)
        {
                pts_t delta = getDelta(i->first);
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 9124688..0e3e7e0 100644 (file)
@@ -156,6 +156,11 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                        ret = 15000;
                                }
 
+                               if (sat.no_rotor_command_on_tune && !rotor) {
+                                       eSecDebugNoSimulate("no rotor but no_rotor_command_on_tune is set.. ignore lnb %d", idx);
+                                       continue;
+                               }
+
                                eSecDebugNoSimulate("ret1 %d", ret);
 
                                if (linked_in_use)
@@ -170,21 +175,6 @@ int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite
                                        else
                                                ret += 15;
                                        eSecDebugNoSimulate("ret2 %d", ret);
-                                       if (ret) // special case when this tuner is linked to a satpos dependent tuner
-                                       {
-                                               fe->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, satpos_depends_ptr);
-                                               if (satpos_depends_ptr != -1)
-                                               {
-                                                       eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) satpos_depends_ptr;
-                                                       satpos_depends_to_fe->m_frontend->getData(eDVBFrontend::ROTOR_POS, rotor_pos);
-                                                       if (!rotor || rotor_pos == -1 /* we dont know the rotor position yet */
-                                                               || rotor_pos != sat.orbital_position ) // not the same orbital position?
-                                                       {
-                                                               ret = 0;
-                                                       }
-                                               }
-                                       }
-                                       eSecDebugNoSimulate("ret3 %d", ret);
                                }
                                else if (satpos_depends_ptr != -1)
                                {
@@ -199,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!)
                                        {
index a9eef40..d5ad249 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 
 eDVBTSTools::eDVBTSTools()
+       :m_file_lock(true)
 {
        m_pid = -1;
        m_maxrange = 256*1024;
@@ -47,6 +48,7 @@ int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
        
        m_samples_taken = 0;
 
+       eSingleLocker l(m_file_lock);
        if (m_file.open(filename, 1) < 0)
                return -1;
        return 0;
@@ -54,6 +56,7 @@ int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
 
 void eDVBTSTools::closeFile()
 {
+       eSingleLocker l(m_file_lock);
        m_file.close();
 }
 
@@ -78,7 +81,8 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                return -1;
 
        offset -= offset % 188;
-       
+
+       eSingleLocker l(m_file_lock);
        if (m_file.lseek(offset, SEEK_SET) < 0)
        {
                eDebug("lseek failed");
@@ -134,7 +138,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                                        pts |= ((unsigned long long)(packet[ 9]&0xFF)) << 1;
                                        pts |= ((unsigned long long)(packet[10]&0x80)) >> 7;
                                        offset -= 188;
-                                       eDebug("PCR  found at %llx: %16llx", offset, pts);
+                                       eDebug("PCR %16llx found at %lld pid %02x (%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)", pts, offset, pid, packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9], packet[10]);
                                        if (fixed && fixupPTS(offset, pts))
                                                return -1;
                                        return 0;
@@ -144,24 +148,83 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                } else
                        payload = packet + 4;
 
-               
 /*             if (m_pid >= 0)
                        if (pid != m_pid)
                                continue; */
                if (!pusi)
                        continue;
-               
-               
+
                        /* somehow not a startcode. (this is invalid, since pusi was set.) ignore it. */
                if (payload[0] || payload[1] || (payload[2] != 1))
                        continue;
-               
+
+               if (payload[3] == 0xFD)
+               { // stream use extension mechanism defined in ISO 13818-1 Amendment 2
+                       if (payload[7] & 1) // PES extension flag
+                       {
+                               int offs = 0;
+                               if (payload[7] & 0x80) // pts avail
+                                       offs += 5;
+                               if (payload[7] & 0x40) // dts avail
+                                       offs += 5;
+                               if (payload[7] & 0x20) // escr avail
+                                       offs += 6;
+                               if (payload[7] & 0x10) // es rate
+                                       offs += 3;
+                               if (payload[7] & 0x8) // dsm trickmode
+                                       offs += 1;
+                               if (payload[7] & 0x4) // additional copy info
+                                       offs += 1;
+                               if (payload[7] & 0x2) // crc
+                                       offs += 2;
+                               if (payload[8] < offs)
+                                       continue;
+                               uint8_t pef = payload[9+offs++]; // pes extension field
+                               if (pef & 1) // pes extension flag 2
+                               {
+                                       if (pef & 0x80) // private data flag
+                                               offs += 16;
+                                       if (pef & 0x40) // pack header field flag
+                                               offs += 1;
+                                       if (pef & 0x20) // program packet sequence counter flag
+                                               offs += 2;
+                                       if (pef & 0x10) // P-STD buffer flag
+                                               offs += 2;
+                                       if (payload[8] < offs)
+                                               continue;
+                                       uint8_t stream_id_extension_len = payload[9+offs++] & 0x7F;
+                                       if (stream_id_extension_len >= 1)
+                                       {
+                                               if (payload[8] < (offs + stream_id_extension_len) )
+                                                       continue;
+                                               if (payload[9+offs] & 0x80) // stream_id_extension_bit (should not set)
+                                                       continue;
+                                               switch (payload[9+offs])
+                                               {
+                                               case 0x55 ... 0x5f: // VC-1
+                                                       break;
+                                               case 0x71: // AC3 / DTS
+                                                       break;
+                                               default:
+                                                       eDebug("skip unknwn stream_id_extension %02x\n", payload[9+offs]);
+                                                       continue;
+                                               }
+                                       }
+                                       else
+                                               continue;
+                               }
+                               else
+                                       continue;
+                       }
+                       else
+                               continue;
+               }
                        /* drop non-audio, non-video packets because other streams
                           can be non-compliant.*/
-               if (((payload[3] & 0xE0) != 0xC0) &&  // audio
-                   ((payload[3] & 0xF0) != 0xE0))    // video
+               else if (((payload[3] & 0xE0) != 0xC0) &&  // audio
+                       ((payload[3] & 0xF0) != 0xE0)) // video
                        continue;
-               
+
                if (payload[7] & 0x80) /* PTS */
                {
                        pts  = ((unsigned long long)(payload[ 9]&0xE))  << 29;
@@ -171,11 +234,11 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                        pts |= ((unsigned long long)(payload[13]&0xFE)) >> 1;
                        offset -= 188;
 
-//                     eDebug("found pts %08llx at %08llx pid %02x stream: %02x", pts, offset, pid, payload[3]);
-                       
+                       eDebug("PTS %16llx found at %lld pid %02x stream: %02x", pts, offset, pid, payload[3]);
+
                                /* convert to zero-based */
                        if (fixed && fixupPTS(offset, pts))
-                                       return -1;
+                               return -1;
                        return 0;
                }
        }
@@ -212,10 +275,13 @@ int eDVBTSTools::fixupPTS(const off_t &offset, pts_t &now)
                        now -= pos;
                return 0;
        }
+       eDebug("eDVBTSTools::fixupPTS failed!");
+       return -1;
 }
 
 int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg)
 {
+       eDebug("getOffset for pts 0x%llx", pts);
        if (m_use_streaminfo)
        {
                if (pts >= m_pts_end && marg > 0 && m_end_valid)
@@ -355,7 +421,8 @@ void eDVBTSTools::calcEnd()
 {
        if (!m_file.valid())
                return;
-       
+
+       eSingleLocker l(m_file_lock);
        off_t end = m_file.lseek(0, SEEK_END);
        
        if (llabs(end - m_last_filelength) > 1*1024*1024)
@@ -440,6 +507,8 @@ void eDVBTSTools::takeSamples()
        m_samples_taken = 1;
        m_samples.clear();
        pts_t dummy;
+       int retries=2;
+
        if (calcLen(dummy) == -1)
                return;
        
@@ -449,21 +518,27 @@ void eDVBTSTools::takeSamples()
                bytes_per_sample = 40*1024*1024;
 
        bytes_per_sample -= bytes_per_sample % 188;
-       
-       for (off_t offset = m_offset_begin; offset < m_offset_end; offset += bytes_per_sample)
+
+       eDebug("samples step %lld, pts begin %llx, pts end %llx, offs begin %lld, offs end %lld:",
+               bytes_per_sample, m_pts_begin, m_pts_end, m_offset_begin, m_offset_end);
+
+       for (off_t offset = m_offset_begin; offset < m_offset_end;)
        {
                pts_t p;
-               takeSample(offset, p);
+               if (takeSample(offset, p) && retries--)
+                       continue;
+               retries = 2;
+               offset += bytes_per_sample;
        }
        m_samples[0] = m_offset_begin;
        m_samples[m_pts_end - m_pts_begin] = m_offset_end;
-       
-//     eDebug("begin, end: %llx %llx", m_offset_begin, m_offset_end); 
 }
 
        /* returns 0 when a sample was taken. */
 int eDVBTSTools::takeSample(off_t off, pts_t &p)
 {
+       off_t offset_org = off;
+
        if (!eDVBTSTools::getPTS(off, p, 1))
        {
                        /* as we are happily mixing PTS and PCR values (no comment, please), we might
@@ -481,18 +556,18 @@ int eDVBTSTools::takeSample(off_t off, pts_t &p)
                        {
                                if ((l->second > off) || (u->second < off))
                                {
-                                       eDebug("ignoring sample %llx %llx %llx (%lld %lld %lld)",
+                                       eDebug("ignoring sample %lld %lld %lld (%llx %llx %llx)",
                                                l->second, off, u->second, l->first, p, u->first);
                                        return 1;
                                }
                        }
                }
 
-               
+               eDebug("adding sample %lld: pts 0x%llx -> pos %lld (diff %lld bytes)", offset_org, p, off, off-offset_org);
                m_samples[p] = off;
                return 0;
        }
-       return 1;
+       return -1;
 }
 
 int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
@@ -504,6 +579,7 @@ int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
                return -1;
        }
 
+       eSingleLocker l(m_file_lock);
        if (m_file.lseek(0, SEEK_SET) < 0)
        {
                eDebug("seek failed");
@@ -652,18 +728,23 @@ int eDVBTSTools::findFrame(off_t &_offset, size_t &len, int &direction, int fram
 
 int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int frame_types)
 {
-       int nr_frames = 0;
+       int nr_frames, direction;
 //     eDebug("trying to move %d frames at %llx", distance, offset);
        
        frame_types = frametypeI; /* TODO: intelligent "allow IP frames when not crossing an I-Frame */
 
-       int direction = distance > 0 ? 0 : -1;
-       distance = abs(distance);
-       
        off_t new_offset = offset;
        size_t new_len = len;
        int first = 1;
 
+       if (distance > 0) {
+               direction = 0;
+                nr_frames = 0;
+        } else {
+               direction = -1;
+                nr_frames = -1;
+               distance = -distance+1;
+        }      
        while (distance > 0)
        {
                int dir = direction;
@@ -677,12 +758,18 @@ int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int
                
 //             eDebug("we moved %d, %d to go frames (now at %llx)", dir, distance, new_offset);
 
-               if (distance >= 0 || first)
+               if (distance >= 0 || direction == 0)
                {
                        first = 0;
                        offset = new_offset;
                        len = new_len;
                        nr_frames += abs(dir);
+               } 
+               else if (first) {
+                       first = 0;
+                       offset = new_offset;
+                       len = new_len;
+                       nr_frames += abs(dir) + distance; // never jump forward during rewind
                }
        }
 
index c230a34..ed8b924 100644 (file)
@@ -4,6 +4,7 @@
 #include <sys/types.h>
 #include <lib/dvb/pvrparse.h>
 #include <lib/base/rawfile.h>
+#include <lib/base/elock.h>
 
 /*
  * Note: we're interested in PTS values, not STC values.
@@ -75,9 +76,10 @@ public:
 private:
        int m_pid;
        int m_maxrange;
-       
+
+       eSingleLock m_file_lock;
        eRawFile m_file;
-       
+
        int m_begin_valid, m_end_valid;
        pts_t m_pts_begin, m_pts_end;
        off_t m_offset_begin, m_offset_end;
index 1f1b06a..dff6b05 100644 (file)
@@ -164,7 +164,13 @@ void *gRC::thread()
                                if (pthread_cond_timedwait(&cond, &mutex, &timeout) == ETIMEDOUT)
                                {
                                        if (eApp && !eApp->isIdle())
-                                               idle = 0;
+                                       {
+                                               int idle_count = eApp->idleCount();
+                                               if (idle_count == m_prev_idle_count)
+                                                       idle = 0;
+                                               else
+                                                       m_prev_idle_count = idle_count;
+                                       }
                                }
 
                                if (!idle)
index 5d0106b..3b8201a 100644 (file)
@@ -176,6 +176,7 @@ class gRC: public iObject, public Object
        
        ePtr<gCompositingData> m_compositing;
 
+       int m_prev_idle_count;
 public:
        gRC();
        virtual ~gRC();
index 4b4b58c..4465d84 100644 (file)
@@ -514,7 +514,7 @@ void eListboxPythonMultiContent::setSelectionClip(eRect &rect, bool update)
                m_listbox->entryChanged(m_cursor);
 }
 
-static void clearRegionHelper(gPainter &painter, eListboxStyle *local_style, const ePoint &offset, ePyObject &pbackColor, bool cursorValid)
+static void clearRegionHelper(gPainter &painter, eListboxStyle *local_style, const ePoint &offset, ePyObject &pbackColor, bool cursorValid, bool clear=true)
 {
        if (pbackColor)
        {
@@ -536,10 +536,11 @@ static void clearRegionHelper(gPainter &painter, eListboxStyle *local_style, con
                else if (local_style->m_transparent_background)
                        return;
        }
-       painter.clear();
+       if (clear)
+               painter.clear();
 }
 
-static void clearRegionSelectedHelper(gPainter &painter, eListboxStyle *local_style, const ePoint &offset, ePyObject &pbackColorSelected, bool cursorValid)
+static void clearRegionSelectedHelper(gPainter &painter, eListboxStyle *local_style, const ePoint &offset, ePyObject &pbackColorSelected, bool cursorValid, bool clear=true)
 {
        if (pbackColorSelected)
        {
@@ -559,10 +560,11 @@ static void clearRegionSelectedHelper(gPainter &painter, eListboxStyle *local_st
                        return;
                }
        }
-       painter.clear();
+       if (clear)
+               painter.clear();
 }
 
-static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *local_style, ePyObject pforeColor, ePyObject pforeColorSelected, ePyObject pbackColor, ePyObject pbackColorSelected, int selected, gRegion &rc, eRect &sel_clip, const ePoint &offset, bool cursorValid)
+static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *local_style, ePyObject pforeColor, ePyObject pforeColorSelected, ePyObject pbackColor, ePyObject pbackColorSelected, int selected, gRegion &rc, eRect &sel_clip, const ePoint &offset, bool cursorValid, bool clear=true)
 {
        if (selected && sel_clip.valid())
        {
@@ -571,7 +573,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
                {
                        painter.clip(part);
                        style.setStyle(painter, eWindowStyle::styleListboxNormal);
-                       clearRegionHelper(painter, local_style, offset, pbackColor, cursorValid);
+                       clearRegionHelper(painter, local_style, offset, pbackColor, cursorValid, clear);
                        painter.clippop();
                        selected = 0;
                }
@@ -580,7 +582,7 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
                {
                        painter.clip(part);
                        style.setStyle(painter, eWindowStyle::styleListboxSelected);
-                       clearRegionSelectedHelper(painter, local_style, offset, pbackColorSelected, cursorValid);
+                       clearRegionSelectedHelper(painter, local_style, offset, pbackColorSelected, cursorValid, clear);
                        painter.clippop();
                        selected = 1;
                }
@@ -588,14 +590,14 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
        else if (selected)
        {
                style.setStyle(painter, eWindowStyle::styleListboxSelected);
-               clearRegionSelectedHelper(painter, local_style, offset, pbackColorSelected, cursorValid);
+               clearRegionSelectedHelper(painter, local_style, offset, pbackColorSelected, cursorValid, clear);
                if (local_style && local_style->m_selection)
                        painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHATEST);
        }
        else
        {
                style.setStyle(painter, eWindowStyle::styleListboxNormal);
-               clearRegionHelper(painter, local_style, offset, pbackColor, cursorValid);
+               clearRegionHelper(painter, local_style, offset, pbackColor, cursorValid, clear);
        }
 
        if (selected)
@@ -818,7 +820,8 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
 
                                {
                                        gRegion rc(rect);
-                                       clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid);
+                                       bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor);
+                                       clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear);
                                }
 
                                painter.setFont(m_font[fnt]);
@@ -921,7 +924,8 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
 
                                {
                                        gRegion rc(rect);
-                                       clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid);
+                                       bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor);
+                                       clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear);
                                }
 
                                // border
@@ -995,7 +999,8 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
 
                                {
                                        gRegion rc(rect);
-                                       clearRegion(painter, style, local_style, ePyObject(), ePyObject(), pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid);
+                                       bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor);
+                                       clearRegion(painter, style, local_style, ePyObject(), ePyObject(), pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear);
                                }
 
                                painter.blit(pixmap, rect.topLeft(), rect, (type == TYPE_PIXMAP_ALPHATEST) ? gPainter::BT_ALPHATEST : (type == TYPE_PIXMAP_ALPHABLEND) ? gPainter::BT_ALPHABLEND : 0);
index bb2d756..8e332e3 100644 (file)
@@ -19,11 +19,21 @@ class About:
                                        #0120 2005 11 29 01 16
                                        #0123 4567 89 01 23 45
                                        version = splitted[1]
+                                       image_type = version[0] # 0 = release, 1 = experimental
+                                       major = version[1]
+                                       minor = version[2]
+                                       revision = version[3]
                                        year = version[4:8]
                                        month = version[8:10]
                                        day = version[10:12]
-
-                                       return '-'.join(("dev", year, month, day))
+                                       date = '-'.join((year, month, day))
+                                       if image_type == '0':
+                                               image_type = "Release"
+                                               version = '.'.join((major, minor, revision))
+                                               return ' '.join((image_type, version, date))
+                                       else:
+                                               image_type = "Experimental"
+                                               return ' '.join((image_type, date))
                        file.close()
                except IOError:
                        pass
old mode 100644 (file)
new mode 100755 (executable)
index fe505c2..33868d6
@@ -1,16 +1,16 @@
 from MenuList import MenuList
-from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
+from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename
 from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, gFont
 from Tools.LoadPixmap import LoadPixmap
 
-def ChoiceEntryComponent(key, text):
+def ChoiceEntryComponent(key = "", text = ["--"]):
        res = [ text ]
        if text[0] == "--":
                res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 00, 800, 25, 0, RT_HALIGN_LEFT, "-"*200))
        else:
                res.append((eListboxPythonMultiContent.TYPE_TEXT, 45, 00, 800, 25, 0, RT_HALIGN_LEFT, text[0]))
        
-               png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/buttons/key_" + key + ".png"))
+               png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/buttons/key_" + key + ".png"))
                if png is not None:
                        res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 5, 0, 35, 25, png))
        
old mode 100644 (file)
new mode 100755 (executable)
index 00949e2..418a1b6
@@ -1,7 +1,7 @@
 from HTMLComponent import HTMLComponent
 from GUIComponent import GUIComponent
-from config import KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_0, KEY_DELETE, KEY_BACKSPACE, KEY_OK, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT, KEY_NUMBERS, ConfigElement
-from Components.ActionMap import NumberActionMap
+from config import KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_0, KEY_DELETE, KEY_BACKSPACE, KEY_OK, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT, KEY_NUMBERS, ConfigElement, ConfigText, ConfigPassword
+from Components.ActionMap import NumberActionMap, ActionMap
 from enigma import eListbox, eListboxPythonConfigContent, eRCInput, eTimer
 from Screens.MessageBox import MessageBox
 
@@ -66,6 +66,7 @@ class ConfigList(HTMLComponent, GUIComponent, object):
                self.current = self.getCurrent()
                if self.current:
                        self.current[1].onSelect(self.session)
+
                for x in self.onSelectionChanged:
                        x()
 
@@ -127,13 +128,52 @@ class ConfigListScreen:
                        "9": self.keyNumberGlobal,
                        "0": self.keyNumberGlobal
                }, -1) # to prevent left/right overriding the listbox
+
+               self["VirtualKB"] = ActionMap(["VirtualKeyboardActions"],
+               {
+                       "showVirtualKeyboard": self.KeyText,
+               }, -2)
+               self["VirtualKB"].setEnabled(False)
                
                self["config"] = ConfigList(list, session = session)
+               
                if on_change is not None:
                        self.__changed = on_change
                else:
                        self.__changed = lambda: None
-
+               
+               if not self.handleInputHelpers in self["config"].onSelectionChanged:
+                       self["config"].onSelectionChanged.append(self.handleInputHelpers)
+
+       def handleInputHelpers(self):
+               if self["config"].getCurrent() is not None:
+                       if isinstance(self["config"].getCurrent()[1], ConfigText) or isinstance(self["config"].getCurrent()[1], ConfigPassword):
+                               if self.has_key("VKeyIcon"):
+                                       self["VirtualKB"].setEnabled(True)
+                                       self["VKeyIcon"].boolean = True
+                               if self.has_key("HelpWindow"):
+                                       if self["config"].getCurrent()[1].help_window.instance is not None:
+                                               helpwindowpos = self["HelpWindow"].getPosition()
+                                               from enigma import ePoint
+                                               self["config"].getCurrent()[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1]))
+                       else:
+                               if self.has_key("VKeyIcon"):
+                                       self["VirtualKB"].setEnabled(False)
+                                       self["VKeyIcon"].boolean = False
+               else:
+                       if self.has_key("VKeyIcon"):
+                               self["VirtualKB"].setEnabled(False)
+                               self["VKeyIcon"].boolean = False
+
+       def KeyText(self):
+               from Screens.VirtualKeyBoard import VirtualKeyBoard
+               self.session.openWithCallback(self.VirtualKeyBoardCallback, VirtualKeyBoard, title = self["config"].getCurrent()[0], text = self["config"].getCurrent()[1].getValue())
+
+       def VirtualKeyBoardCallback(self, callback = None):
+               if callback is not None and len(callback):
+                       self["config"].getCurrent()[1].setValue(callback)
+                       self["config"].invalidate(self["config"].getCurrent())
+                       
        def keyOK(self):
                self["config"].handleKey(KEY_OK)
 
index 75c8a08..3b6fd3e 100644 (file)
@@ -6,4 +6,4 @@ install_PYTHON = \
        ConditionalShowHide.py ServicePosition.py ValueRange.py RdsInfo.py Streaming.py \
        StaticMultiList.py ServiceTime.py MovieInfo.py MenuEntryCompare.py StringListSelection.py \
        ValueBitTest.py TunerInfo.py ConfigEntryTest.py TemplatedMultiContent.py ProgressToText.py \
-       Combine.py
+       Combine.py SensorToText.py
diff --git a/lib/python/Components/Converter/SensorToText.py b/lib/python/Components/Converter/SensorToText.py
new file mode 100644 (file)
index 0000000..fb156fa
--- /dev/null
@@ -0,0 +1,14 @@
+from Components.Converter.Converter import Converter
+
+class SensorToText(Converter, object):
+       def __init__(self, arguments):
+               Converter.__init__(self, arguments)
+        
+       def getText(self):
+               if self.source.getValue() is None:
+                       return ""
+               return "%d %s" % (self.source.getValue(), self.source.getUnit())
+       
+       text = property(getText)
+        
+        
\ No newline at end of file
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
old mode 100644 (file)
new mode 100755 (executable)
index 59f9262..41cd1b2
@@ -8,7 +8,7 @@ from Tools.LoadPixmap import LoadPixmap
 
 from time import localtime, time
 from ServiceReference import ServiceReference
-from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
+from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
 
 EPG_TYPE_SINGLE = 0
 EPG_TYPE_MULTI = 1
@@ -53,11 +53,11 @@ class EPGList(HTMLComponent, GUIComponent):
                        assert(type == EPG_TYPE_SIMILAR)
                        self.l.setBuildFunc(self.buildSimilarEntry)
                self.epgcache = eEPGCache.getInstance()
-               self.clock_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock.png'))
-               self.clock_add_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_add.png'))
-               self.clock_pre_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_pre.png'))
-               self.clock_post_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_post.png'))
-               self.clock_prepost_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_prepost.png'))
+               self.clock_pixmap = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'skin_default/icons/epgclock.png'))
+               self.clock_add_pixmap = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'skin_default/icons/epgclock_add.png'))
+               self.clock_pre_pixmap = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'skin_default/icons/epgclock_pre.png'))
+               self.clock_post_pixmap = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'skin_default/icons/epgclock_post.png'))
+               self.clock_prepost_pixmap = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'skin_default/icons/epgclock_prepost.png'))
 
        def getEventFromId(self, service, eventid):
                event = None
diff --git a/lib/python/Components/FanControl.py b/lib/python/Components/FanControl.py
new file mode 100644 (file)
index 0000000..a993c39
--- /dev/null
@@ -0,0 +1,117 @@
+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):
+               if os.path.exists("/proc/stb/fp/fan_vlt") or os.path.exists("/proc/stb/fp/fan_pwm") or os.path.exists("/proc/stb/fp/fan_speed"):
+                       self.fancount = 1
+               else:
+                       self.fancount = 0
+               self.createConfig()
+               config.misc.standbyCounter.addNotifier(self.standbyCounterChanged, initial_call = False)
+
+       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)
+               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):
+                       fancontrol.setVoltage(fanid, configElement.value)
+               def setPWM(fancontrol, fanid, configElement):
+                       fancontrol.setPWM(fanid, configElement.value)
+               
+               config.fans = ConfigSubList()
+               for fanid in range(self.getFanCount()):
+                       fan = ConfigSubsection()
+                       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]
+       
+       def getFanCount(self):
+               return self.fancount
+       
+       def hasRPMSensor(self, fanid):
+               return os.path.exists("/proc/stb/fp/fan_speed")
+       
+       def hasFanControl(self, fanid):
+               return os.path.exists("/proc/stb/fp/fan_vlt") or os.path.exists("/proc/stb/fp/fan_pwm")
+       
+       def getFanSpeed(self, fanid):
+               f = open("/proc/stb/fp/fan_speed", "r")
+               value = int(f.readline().strip()[:-4])
+               f.close()
+               return value
+       
+       def getVoltage(self, fanid):
+               f = open("/proc/stb/fp/fan_vlt", "r")
+               value = int(f.readline().strip(), 16)
+               f.close()
+               return value
+       
+       def setVoltage(self, fanid, value):
+               if value > 255:
+                       return
+               f = open("/proc/stb/fp/fan_vlt", "w")
+               f.write("%x" % value)
+               f.close()
+               
+       def getPWM(self, fanid):
+               f = open("/proc/stb/fp/fan_pwm", "r")
+               value = int(f.readline().strip(), 16)
+               f.close()
+               return value
+       
+       def setPWM(self, fanid, value):
+               if value > 255:
+                       return
+               f = open("/proc/stb/fp/fan_pwm", "w")
+               f.write("%x" % value)
+               f.close()
+       
+fancontrol = FanControl()
index 38b0854..841a2fe 100755 (executable)
@@ -3,7 +3,7 @@ from os import path as os_path, listdir
 from MenuList import MenuList
 from Components.Harddisk import harddiskmanager
 
-from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
+from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename, fileExists
 
 from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \
        eServiceReference, eServiceCenter, gFont
@@ -35,12 +35,12 @@ def FileEntryComponent(name, absolute = None, isDir = False):
        res = [ (absolute, isDir) ]
        res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 470, 20, 0, RT_HALIGN_LEFT, name))
        if isDir:
-               png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/directory.png"))
+               png = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "extensions/directory.png"))
        else:
                extension = name.split('.')
                extension = extension[-1].lower()
                if EXTENSIONS.has_key(extension):
-                       png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/" + EXTENSIONS[extension] + ".png"))
+                       png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "extensions/" + EXTENSIONS[extension] + ".png"))
                else:
                        png = None
        if png is not None:
@@ -160,8 +160,11 @@ class FileList(MenuList):
                        directories.sort()
                        files.sort()
                else:
-                       if os_path.exists(directory):
-                               files = listdir(directory)
+                       if fileExists(directory):
+                               try:
+                                       files = listdir(directory)
+                               except:
+                                       files = []
                                files.sort()
                                tmpfiles = files[:]
                                for x in tmpfiles:
@@ -256,12 +259,12 @@ def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected
        res = [ (absolute, isDir, selected, name) ]
        res.append((eListboxPythonMultiContent.TYPE_TEXT, 55, 1, 470, 20, 0, RT_HALIGN_LEFT, name))
        if isDir:
-               png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/directory.png"))
+               png = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "extensions/directory.png"))
        else:
                extension = name.split('.')
                extension = extension[-1].lower()
                if EXTENSIONS.has_key(extension):
-                       png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/" + EXTENSIONS[extension] + ".png"))
+                       png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "extensions/" + EXTENSIONS[extension] + ".png"))
                else:
                        png = None
        if png is not None:
@@ -269,10 +272,10 @@ def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected
 
        if not name.startswith('<'):
                if selected is False:
-                       icon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_off.png"))
+                       icon = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/lock_off.png"))
                        res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon))
                else:
-                       icon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_on.png"))
+                       icon = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/lock_on.png"))
                        res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon))
        
        return res
@@ -374,8 +377,11 @@ class MultiFileSelectList(FileList):
                        directories.sort()
                        files.sort()
                else:
-                       if os_path.exists(directory):
-                               files = listdir(directory)
+                       if fileExists(directory):
+                               try:
+                                       files = listdir(directory)
+                               except:
+                                       files = []
                                files.sort()
                                tmpfiles = files[:]
                                for x in tmpfiles:
index 2efdb68..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
@@ -290,7 +290,10 @@ class Harddisk:
        # any access has been made to the disc. If there has been no access over a specifed time,
        # we set the hdd into standby.
        def readStats(self):
-               l = readFile("/sys/block/%s/stat" % self.device)
+               try:
+                       l = open("/sys/block/%s/stat" % self.device).read()
+               except IOError:
+                       return -1,-1
                (nr_read, _, _, _, nr_write) = l.split()[:5]
                return int(nr_read), int(nr_write)
 
@@ -319,7 +322,7 @@ class Harddisk:
                l = sum(stats)
                print "sum", l, "prev_sum", self.last_stat
 
-               if l != self.last_stat: # access
+               if l != self.last_stat and l >= 0: # access
                        print "hdd was accessed since previous check!"
                        self.last_stat = l
                        self.last_access = t
index 0ba1165..7144777 100755 (executable)
@@ -1,4 +1,5 @@
 from enigma import eConsoleAppContainer
+from Tools.Directories import fileExists
 
 class IpkgComponent:
        EVENT_INSTALL = 0
@@ -20,7 +21,7 @@ class IpkgComponent:
        
        def __init__(self, ipkg = '/usr/bin/ipkg'):
                self.ipkg = ipkg
-               
+               self.opkgAvail = fileExists('/usr/bin/opkg')
                self.cmd = eConsoleAppContainer()
                self.cache = None
                self.callbackList = []
@@ -89,7 +90,10 @@ class IpkgComponent:
                        if data.find('Downloading') == 0:
                                self.callCallbacks(self.EVENT_DOWNLOAD, data.split(' ', 5)[1].strip())
                        elif data.find('Upgrading') == 0:
-                               self.callCallbacks(self.EVENT_UPGRADE, data.split('    ', 1)[1].split(' ')[0])
+                               if self.opkgAvail:
+                                       self.callCallbacks(self.EVENT_UPGRADE, data.split(' ', 1)[1].split(' ')[0])
+                               else:
+                                       self.callCallbacks(self.EVENT_UPGRADE, data.split('    ', 1)[1].split(' ')[0])
                        elif data.find('Installing') == 0:
                                self.callCallbacks(self.EVENT_INSTALL, data.split(' ', 1)[1].split(' ')[0])
                        elif data.find('Removing') == 0:
index 0e50123..dde158b 100644 (file)
@@ -28,6 +28,14 @@ class LCD:
        def isOled(self):
                return eDBoxLCD.getInstance().isOled()
 
+def leaveStandby():
+       config.lcd.bright.apply()
+
+def standbyCounterChanged(configElement):
+       from Screens.Standby import inStandby
+       inStandby.onClose.append(leaveStandby)
+       config.lcd.standby.apply()
+
 def InitLcd():
        detected = eDBoxLCD.getInstance().detected()
        SystemInfo["Display"] = detected
@@ -42,9 +50,18 @@ def InitLcd():
                def setLCDinverted(configElement):
                        ilcd.setInverted(configElement.value);
 
+               standby_default = 0
+
                ilcd = LCD()
 
-               config.lcd.standby = ConfigSlider(default=0, limits=(0, 10))
+               if not ilcd.isOled():
+                       config.lcd.contrast = ConfigSlider(default=5, limits=(0, 20))
+                       config.lcd.contrast.addNotifier(setLCDcontrast);
+               else:
+                       config.lcd.contrast = ConfigNothing()
+                       standby_default = 1
+
+               config.lcd.standby = ConfigSlider(default=standby_default, limits=(0, 10))
                config.lcd.standby.addNotifier(setLCDbright);
                config.lcd.standby.apply = lambda : setLCDbright(config.lcd.standby)
 
@@ -53,12 +70,6 @@ def InitLcd():
                config.lcd.bright.apply = lambda : setLCDbright(config.lcd.bright)
                config.lcd.bright.callNotifiersOnSaveAndCancel = True
 
-               if not ilcd.isOled():
-                       config.lcd.contrast = ConfigSlider(default=5, limits=(0, 20))
-                       config.lcd.contrast.addNotifier(setLCDcontrast);
-               else:
-                       config.lcd.contrast = ConfigNothing()
-
                config.lcd.invert = ConfigYesNo(default=False)
                config.lcd.invert.addNotifier(setLCDinverted);
        else:
@@ -69,3 +80,6 @@ def InitLcd():
                config.lcd.standby = ConfigNothing()
                config.lcd.bright.apply = lambda : doNothing()
                config.lcd.standby.apply = lambda : doNothing()
+
+       config.misc.standbyCounter.addNotifier(standbyCounterChanged, initial_call = False)
+
index 34710fa..b5ef068 100755 (executable)
@@ -19,4 +19,4 @@ install_PYTHON = \
        Element.py Playlist.py ParentalControl.py ParentalControlList.py \
        Ipkg.py SelectionList.py Scanner.py SystemInfo.py DreamInfoHandler.py \
        Task.py language_cache.py Console.py ResourceManager.py TuneTest.py \
-       Keyboard.py
+       Keyboard.py Sensors.py FanControl.py
old mode 100644 (file)
new mode 100755 (executable)
index 12f2727..5583b22
@@ -1,6 +1,6 @@
 from MenuList import MenuList
 
-from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
+from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename
 from os import path
 
 from enigma import eListboxPythonMultiContent, RT_VALIGN_CENTER, gFont, eServiceCenter
@@ -14,11 +14,11 @@ STATE_REWIND = 3
 STATE_FORWARD = 4
 STATE_NONE = 5
 
-PlayIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/ico_mp_play.png"))
-PauseIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/ico_mp_pause.png"))
-StopIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/ico_mp_stop.png"))
-RewindIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/ico_mp_rewind.png"))
-ForwardIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/ico_mp_forward.png"))
+PlayIcon = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/ico_mp_play.png"))
+PauseIcon = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/ico_mp_pause.png"))
+StopIcon = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/ico_mp_stop.png"))
+RewindIcon = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/ico_mp_rewind.png"))
+ForwardIcon = LoadPixmap(path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/ico_mp_forward.png"))
 
 def PlaylistEntryComponent(serviceref, state):
        res = [ serviceref ]
index f65d609..b9da48d 100755 (executable)
@@ -14,7 +14,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()
@@ -24,6 +24,7 @@ class Network:
                self.activateConsole = Console()
                self.resetNetworkConsole = Console()
                self.DnsConsole = Console()
+               self.PingConsole = Console()
                self.config_ready = None
                self.getInterfaces()
 
@@ -233,7 +234,7 @@ class Network:
                                self.configuredNetworkAdapters = self.configuredInterfaces
                                # load ns only once     
                                self.loadNameserverConfig()
-                               print "read configured interfac:", ifaces
+                               print "read configured interface:", ifaces
                                print "self.ifaces after loading:", self.ifaces
                                self.config_ready = True
                                self.msgPlugins()
@@ -424,6 +425,7 @@ class Network:
 
        def checkNetworkState(self,statecallback):
                # www.dream-multimedia-tv.de, www.heise.de, www.google.de
+               self.NetworkState = 0
                cmd1 = "ping -c 1 82.149.226.170"
                cmd2 = "ping -c 1 193.99.144.85"
                cmd3 = "ping -c 1 209.85.135.103"
@@ -475,10 +477,17 @@ class Network:
 
        def getLinkStateFinished(self, result, retval,extra_args):
                (callback) = extra_args
+
                if self.LinkConsole is not None:
                        if len(self.LinkConsole.appContainers) == 0:
                                callback(result)
                        
+       def stopPingConsole(self):
+               if self.PingConsole is not None:
+                       if len(self.PingConsole.appContainers):
+                               for name in self.PingConsole.appContainers.keys():
+                                       self.PingConsole.kill(name)
+
        def stopLinkStateConsole(self):
                if self.LinkConsole is not None:
                        if len(self.LinkConsole.appContainers):
@@ -571,11 +580,11 @@ class Network:
                                self.wlanmodule = 'madwifi'
                if os_path.exists(rt73_dir):
                        rtfiles = listdir(rt73_dir)
-                       if len(rtfiles) == 2:
+                       if len(rtfiles) == 2 or len(rtfiles) == 5:
                                self.wlanmodule = 'ralink'
                if os_path.exists(zd1211b_dir):
                        zdfiles = listdir(zd1211b_dir)
-                       if len(zdfiles) == 1:
+                       if len(zdfiles) == 1 or len(zdfiles) == 5:
                                self.wlanmodule = 'zydas'
                return self.wlanmodule
        
index 05204a7..6af4c52 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'
@@ -899,7 +928,7 @@ def InitSecParams():
        x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
        config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
 
-       x = ConfigInteger(default=750, limits = (0, 9999))
+       x = ConfigInteger(default=900, limits = (0, 9999))
        x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
        config.sec.delay_after_enable_voltage_before_motor_command = x
 
@@ -938,16 +967,22 @@ 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"),
-#              "unicable": _("Unicable"),
+               "unicable": _("Unicable"),
                "c_band": _("C-Band"),
                "user_defined": _("User defined")}
 
@@ -1213,10 +1248,49 @@ def InitNimManager(nimmgr):
                                tmp.lnb = lnb
                                nim.advanced.sat[x] = tmp
 
+       def toneAmplitudeChanged(configElement):
+               fe_id = configElement.fe_id
+               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)
+               open("/proc/stb/frontend/%d/mode" % (fe_id), "w").write(configElement.value)
+               frontend = eDVBResourceManager.getInstance().allocateRawChannel(fe_id).getFrontend()
+               frontend.reopenFrontend()
+               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
+                       nim.toneAmplitude.slot_id = x
+                       nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
                        nim.diseqc13V = ConfigYesNo(False)
                        nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
                        nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
@@ -1306,6 +1380,7 @@ def InitNimManager(nimmgr):
                        nim.terrestrial = ConfigSelection(choices = list)
                        nim.terrestrial_5V = ConfigOnOff()
                else:
+                       empty_slots += 1
                        nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
                        if slot.type is not None:
                                print "pls add support for this frontend type!", slot.type
index d68e01f..9942bca 100644 (file)
@@ -1,19 +1,34 @@
-from Components.config import config, ConfigSubsection, ConfigSelection, ConfigPIN, ConfigYesNo, ConfigSubList, ConfigInteger
+from Components.config import config, ConfigSubsection, ConfigSelection, ConfigPIN, ConfigText, ConfigYesNo, ConfigSubList, ConfigInteger
+#from Screens.ChannelSelection import service_types_tv
 from Screens.InputBox import PinInput
 from Screens.MessageBox import MessageBox
 from Tools.BoundFunction import boundFunction
 from ServiceReference import ServiceReference
 from Tools import Notifications
 from Tools.Directories import resolveFilename, SCOPE_CONFIG
+from enigma import eTimer
+import time
+
+TYPE_SERVICE = "SERVICE"
+TYPE_BOUQUETSERVICE = "BOUQUETSERVICE"
+TYPE_BOUQUET = "BOUQUET"
+LIST_BLACKLIST = "blacklist"
+LIST_WHITELIST = "whitelist"
+
+IMG_WHITESERVICE = LIST_WHITELIST + "-" + TYPE_SERVICE
+IMG_WHITEBOUQUET = LIST_WHITELIST + "-" + TYPE_BOUQUET
+IMG_BLACKSERVICE = LIST_BLACKLIST + "-" + TYPE_SERVICE
+IMG_BLACKBOUQUET = LIST_BLACKLIST + "-" + TYPE_BOUQUET
 
 def InitParentalControl():
        config.ParentalControl = ConfigSubsection()
        config.ParentalControl.configured = ConfigYesNo(default = False)
        config.ParentalControl.mode = ConfigSelection(default = "simple", choices = [("simple", _("simple")), ("complex", _("complex"))])
-       config.ParentalControl.storeservicepin = ConfigSelection(default = "never", choices = [("never", _("never")), ("5_minutes", _("5 minutes")), ("30_minutes", _("30 minutes")), ("60_minutes", _("60 minutes")), ("restart", _("until restart"))])
+       config.ParentalControl.storeservicepin = ConfigSelection(default = "never", choices = [("never", _("never")), ("5", _("5 minutes")), ("30", _("30 minutes")), ("60", _("60 minutes")), ("standby", _("until standby/restart"))])
+       config.ParentalControl.storeservicepincancel = ConfigSelection(default = "never", choices = [("never", _("never")), ("5", _("5 minutes")), ("30", _("30 minutes")), ("60", _("60 minutes")), ("standby", _("until standby/restart"))])
        config.ParentalControl.servicepinactive = ConfigYesNo(default = False)
        config.ParentalControl.setuppinactive = ConfigYesNo(default = False)
-       config.ParentalControl.type = ConfigSelection(default = "blacklist", choices = [("whitelist", _("whitelist")), ("blacklist", _("blacklist"))])
+       config.ParentalControl.type = ConfigSelection(default = "blacklist", choices = [(LIST_WHITELIST, _("whitelist")), (LIST_BLACKLIST, _("blacklist"))])
        config.ParentalControl.setuppin = ConfigPIN(default = -1)
        
        config.ParentalControl.retries = ConfigSubsection()
@@ -39,40 +54,58 @@ def InitParentalControl():
 
 class ParentalControl:
        def __init__(self):
-               self.open()
+               #Do not call open on init, because bouquets are not ready at that moment 
+#              self.open()
                self.serviceLevel = {}
-               
-       def addWhitelistService(self, service):
-               self.whitelist.append(service)
+               #Instead: Use Flags to see, if we already initialized config and called open
+               self.configInitialized = False
+               self.filesOpened = False
+               #This is the timer that is used to see, if the time for caching the pin is over
+               #Of course we could also work without a timer and compare the times every
+               #time we call isServicePlayable. But this might probably slow down zapping, 
+               #That's why I decided to use a timer
+               self.sessionPinTimer = eTimer()
+               self.sessionPinTimer.callback.append(self.resetSessionPin)
        
-       def addBlacklistService(self, service):
-               self.blacklist.append(service)
-
-       def setServiceLevel(self, service, level):
-               self.serviceLevel[service] = level
-
-       def deleteWhitelistService(self, service):
-               self.whitelist.remove(service)
-               if self.serviceLevel.has_key(service):
-                       self.serviceLevel.remove(service)
+       def serviceMethodWrapper(self, service, method, *args):
+               #This method is used to call all functions that need a service as Parameter: 
+               #It takes either a Service- Reference or a Bouquet- Reference and passes 
+               #Either the service or all services contained in the bouquet to the method given
+               #That way all other functions do not need to distinguish between service and bouquet. 
+               if "FROM BOUQUET" in service:
+                       method( service , TYPE_BOUQUET , *args )
+                       servicelist = self.readServicesFromBouquet(service,"C")
+                       for ref in servicelist:
+                               sRef = str(ref[0])
+                               method( sRef , TYPE_BOUQUETSERVICE , *args )
+               else:
+                       ref = ServiceReference(service)
+                       sRef = str(ref)
+                       method( sRef , TYPE_SERVICE , *args )
        
-       def deleteBlacklistService(self, service):
-               self.blacklist.remove(service)
-               if self.serviceLevel.has_key(service):
-                       self.serviceLevel.remove(service)
+       def setServiceLevel(self, service, type, level):
+               self.serviceLevel[service] = level
 
        def isServicePlayable(self, ref, callback):
                if not config.ParentalControl.configured.value or not config.ParentalControl.servicepinactive.value:
                        return True
-               #print "whitelist:", self.whitelist
-               #print "blacklist:", self.blacklist
-               #print "config.ParentalControl.type.value:", config.ParentalControl.type.value
-               #print "not in whitelist:", (service not in self.whitelist)
-               #print "checking parental control for service:", ref.toString()
+               #Check if we already read the whitelists and blacklists. If not: call open
+               if self.filesOpened == False:
+                       self.open()
+               #Check if configuration has already been read or if the significant values have changed.
+               #If true: read the configuration 
+               if self.configInitialized == False or self.storeServicePin != config.ParentalControl.storeservicepin.value or self.storeServicePinCancel != config.ParentalControl.storeservicepincancel.value:
+                       self.getConfigValues()
                service = ref.toCompareString()
-               if (config.ParentalControl.type.value == "whitelist" and service not in self.whitelist) or (config.ParentalControl.type.value == "blacklist" and service in self.blacklist):
+               if (config.ParentalControl.type.value == LIST_WHITELIST and not self.whitelist.has_key(service)) or (config.ParentalControl.type.value == LIST_BLACKLIST and self.blacklist.has_key(service)):
+                       #Check if the session pin is cached and return the cached value, if it is.
+                       if self.sessionPinCached == True:
+                               #As we can cache successful pin- entries as well as canceled pin- entries,
+                               #We give back the last action 
+                               return self.sessionPinCachedValue
                        self.callback = callback
-                       #print "service:", ServiceReference(service).getServiceName()
+                       #Someone started to implement different levels of protection. Seems they were never completed
+                       #I did not throw out this code, although it is of no use at the moment
                        levelNeeded = 0
                        if self.serviceLevel.has_key(service):
                                levelNeeded = self.serviceLevel[service]
@@ -83,103 +116,217 @@ class ParentalControl:
                        return True
                
        def protectService(self, service):
-               #print "protect"
-               #print "config.ParentalControl.type.value:", config.ParentalControl.type.value
-               if config.ParentalControl.type.value == "whitelist":
-                       if service in self.whitelist:
-                               self.deleteWhitelistService(service)
+               if config.ParentalControl.type.value == LIST_WHITELIST:
+                       if self.whitelist.has_key(service):
+                               self.serviceMethodWrapper(service, self.removeServiceFromList, self.whitelist)
+                               #self.deleteWhitelistService(service)
                else: # blacklist
-                       if service not in self.blacklist:
-                               self.addBlacklistService(service)
+                       if not self.blacklist.has_key(service):
+                               self.serviceMethodWrapper(service, self.addServiceToList, self.blacklist)
+                               #self.addBlacklistService(service)
                #print "whitelist:", self.whitelist
                #print "blacklist:", self.blacklist
 
-                               
        def unProtectService(self, service):
                #print "unprotect"
                #print "config.ParentalControl.type.value:", config.ParentalControl.type.value
-               if config.ParentalControl.type.value == "whitelist":
-                       if service not in self.whitelist:
-                               self.addWhitelistService(service)
+               if config.ParentalControl.type.value == LIST_WHITELIST:
+                       if not self.whitelist.has_key(service):
+                               self.serviceMethodWrapper(service, self.addServiceToList, self.whitelist)
+                               #self.addWhitelistService(service)
                else: # blacklist
-                       if service in self.blacklist:
-                               self.deleteBlacklistService(service)
+                       if self.blacklist.has_key(service):
+                               self.serviceMethodWrapper(service, self.removeServiceFromList, self.blacklist)
+                               #self.deleteBlacklistService(service)
                #print "whitelist:", self.whitelist
                #print "blacklist:", self.blacklist
 
        def getProtectionLevel(self, service):
-               if (config.ParentalControl.type.value == "whitelist" and service not in self.whitelist) or (config.ParentalControl.type.value == "blacklist" and service in self.blacklist):
+               if (config.ParentalControl.type.value == LIST_WHITELIST and not self.whitelist.has_key(service)) or (config.ParentalControl.type.value == LIST_BLACKLIST and self.blacklist.has_key(service)):
                        if self.serviceLevel.has_key(service):
                                return self.serviceLevel[service]
                        else:
                                return 0
                else:
                        return -1
+
+       def getProtectionType(self, service):
+               #New method used in ParentalControlList: This method does not only return
+               #if a service is protected or not, it also returns, why (whitelist or blacklist, service or bouquet)
+               if self.filesOpened == False:
+                       self.open()
+               sImage = ""
+               if (config.ParentalControl.type.value == LIST_WHITELIST):
+                       if self.whitelist.has_key(service):
+                               if TYPE_SERVICE in self.whitelist[service]:
+                                       sImage = IMG_WHITESERVICE
+                               else:
+                                       sImage = IMG_WHITEBOUQUET
+               elif (config.ParentalControl.type.value == LIST_BLACKLIST):
+                       if self.blacklist.has_key(service):
+                               if TYPE_SERVICE in self.blacklist[service]:
+                                       sImage = IMG_BLACKSERVICE
+                               else:
+                                       sImage = IMG_BLACKBOUQUET
+               bLocked = self.getProtectionLevel(service) != -1
+               return (bLocked,sImage)
+       
+       def getConfigValues(self):      
+               #Read all values from configuration 
+               self.checkPinInterval = False
+               self.checkPinIntervalCancel = False
+               self.checkSessionPin = False
+               self.checkSessionPinCancel = False
+               
+               self.sessionPinCached = False
+               self.pinIntervalSeconds = 0
+               self.pinIntervalSecondsCancel = 0
+
+               self.storeServicePin = config.ParentalControl.storeservicepin.value
+               self.storeServicePinCancel = config.ParentalControl.storeservicepincancel.value
+               
+               if self.storeServicePin == "never":
+                       pass
+               elif self.storeServicePin == "standby":
+                       self.checkSessionPin = True
+               else:
+                       self.checkPinInterval = True
+                       iMinutes = float(self.storeServicePin)
+                       iSeconds = iMinutes*60
+                       self.pinIntervalSeconds = iSeconds
+       
+               if self.storeServicePinCancel == "never":
+                       pass
+               elif self.storeServicePinCancel == "standby":
+                       self.checkSessionPinCancel = True
+               else:
+                       self.checkPinIntervalCancel = True
+                       iMinutes = float(self.storeServicePinCancel)
+                       iSeconds = iMinutes*60
+                       self.pinIntervalSecondsCancel = iSeconds
        
+               self.configInitialized = True
+               # Reset PIN cache on standby: Use StandbyCounter- Config- Callback
+               config.misc.standbyCounter.addNotifier(self.standbyCounterCallback, initial_call = False)
+
+       def standbyCounterCallback(self, configElement):
+               self.resetSessionPin()
+               
+       def resetSessionPin(self):
+               #Reset the session pin, stop the timer
+               self.sessionPinCached = False
+               self.sessionPinTimer.stop()
+
+       def getCurrentTimeStamp(self):
+               return time.time()
+
        def getPinList(self):
                return [ x.value for x in config.ParentalControl.servicepin ]
-       
+               
        def servicePinEntered(self, service, result):
-#              levelNeeded = 0
-               #if self.serviceLevel.has_key(service):
-                       #levelNeeded = self.serviceLevel[service]
-#              
-               #print "getPinList():", self.getPinList()
-               #pinList = self.getPinList()[:levelNeeded + 1]
-               #print "pinList:", pinList
-#              
-#              print "pin entered for service", service, "and pin was", pin
-               #if pin is not None and int(pin) in pinList:
+
                if result is not None and result:
-                       #print "pin ok, playing service"
+                       #This is the new function of caching the service pin
+                       #save last session and time of last entered pin...
+                       if self.checkSessionPin == True:
+                               self.sessionPinCached = True
+                               self.sessionPinCachedValue = True
+                       if self.checkPinInterval == True:
+                               self.sessionPinCached = True
+                               self.sessionPinCachedValue = True
+                               self.sessionPinTimer.start(self.pinIntervalSeconds*1000,1)
                        self.callback(ref = service)
                else:
+                       #This is the new function of caching cancelling of service pin
                        if result is not None:
                                Notifications.AddNotification(MessageBox,  _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
-                       #print "wrong pin entered"
+                       else:
+                               if self.checkSessionPinCancel == True:
+                                       self.sessionPinCached = True
+                                       self.sessionPinCachedValue = False
+                               if self.checkPinIntervalCancel == True:
+                                       self.sessionPinCached = True
+                                       self.sessionPinCachedValue = False
+                                       self.sessionPinTimer.start(self.pinIntervalSecondsCancel*1000,1) 
                        
-       def saveWhitelist(self):
-               file = open(resolveFilename(SCOPE_CONFIG, "whitelist"), 'w')
-               for x in self.whitelist:
-                       file.write(x + "\n")
-               file.close
-       
-       def openWhitelist(self):
-               self.whitelist = []
-               try:
-                       file = open(resolveFilename(SCOPE_CONFIG, "whitelist"), 'r')
-                       lines = file.readlines()
-                       for x in lines:
-                               ref = ServiceReference(x.strip())
-                               self.whitelist.append(str(ref))
-                       file.close
-               except:
-                       pass
-               
-       def saveBlacklist(self):
-               file = open(resolveFilename(SCOPE_CONFIG, "blacklist"), 'w')
-               for x in self.blacklist:
-                       file.write(x + "\n")
+       def saveListToFile(self,sWhichList):
+               #Replaces saveWhiteList and saveBlackList: 
+               #I don't like to have two functions with identical code...
+               if sWhichList == LIST_BLACKLIST:
+                       vList = self.blacklist
+               else:
+                       vList = self.whitelist
+               file = open(resolveFilename(SCOPE_CONFIG, sWhichList), 'w')
+               for sService,sType in vList.iteritems():
+                       #Only Services that are selected directly and Bouqets are saved. 
+                       #Services that are added by a bouquet are not saved. 
+                       #This is the reason for the change in self.whitelist and self.blacklist
+                       if TYPE_SERVICE in sType or TYPE_BOUQUET in sType:
+                               file.write(str(sService) + "\n")
                file.close
 
-       def openBlacklist(self):
-               self.blacklist = []
+       def openListFromFile(self,sWhichList):
+               #Replaces openWhiteList and openBlackList: 
+               #I don't like to have two functions with identical code...
+               if sWhichList == LIST_BLACKLIST:
+                       self.blacklist = {}
+                       vList = self.blacklist
+               else:
+                       self.whitelist = {}
+                       vList = self.whitelist
                try:
-                       file = open(resolveFilename(SCOPE_CONFIG, "blacklist"), 'r')
+                       file = open(resolveFilename(SCOPE_CONFIG, sWhichList ), 'r')
                        lines = file.readlines()
                        for x in lines:
-                               ref = ServiceReference(x.strip())
-                               self.blacklist.append(str(ref))
+                               sPlain = x.strip()
+                               self.serviceMethodWrapper(sPlain, self.addServiceToList, vList)
                        file.close
                except:
                        pass
+       
+       def addServiceToList(self, service, type, vList):
+               #Replaces addWhitelistService and addBlacklistService
+               #The lists are not only lists of service references any more. 
+               #They are named lists with the service as key and an array of types as value:
+               
+               if vList.has_key(service):
+                       if not type in vList[service]:
+                               vList[service].append(type)
+               else:
+                       vList[service] = [type]
+       
+       def removeServiceFromList(self, service, type, vList):
+               #Replaces deleteWhitelistService and deleteBlacklistService
+               if vList.has_key(service):
+                       if type in vList[service]:
+                               vList[service].remove(type)
+                       if not vList[service]:
+                               del vList[service]
+               if self.serviceLevel.has_key(service):
+                       self.serviceLevel.remove(service)
+               
+       def readServicesFromBouquet(self,sBouquetSelection,formatstring):
+               #This method gives back a list of services for a given bouquet
+               from enigma import eServiceCenter, eServiceReference
+               from Screens.ChannelSelection import service_types_tv
+               serviceHandler = eServiceCenter.getInstance()
+               refstr = sBouquetSelection
+               root = eServiceReference(refstr)
+               list = serviceHandler.list(root)
+               if list is not None:
+                       services = list.getContent("CN", True) #(servicecomparestring, name)
+                       return services
                
        def save(self):
-               self.saveBlacklist()
-               self.saveWhitelist()
+               # we need to open the files in case we havent's read them yet
+               if not self.filesOpened:
+                       self.open()
+               self.saveListToFile(LIST_BLACKLIST)
+               self.saveListToFile(LIST_WHITELIST)
                
        def open(self):
-               self.openBlacklist()
-               self.openWhitelist()
+               self.openListFromFile(LIST_BLACKLIST)
+               self.openListFromFile(LIST_WHITELIST)
+               self.filesOpened = True
 
 parentalControl = ParentalControl()
index 128e6d3..797ea39 100644 (file)
@@ -1,19 +1,28 @@
 from MenuList import MenuList
-from Components.ParentalControl import parentalControl
+from Components.ParentalControl import parentalControl, IMG_WHITESERVICE, IMG_WHITEBOUQUET, IMG_BLACKSERVICE, IMG_BLACKBOUQUET
 from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
 
 from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
 from Tools.LoadPixmap import LoadPixmap
 
-lockPicture = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock.png"))
+#Now there is a list of pictures instead of one...
+entryPicture = {}
 
-def ParentalControlEntryComponent(service, name, locked = True):
+entryPicture[IMG_BLACKSERVICE] = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock.png"))
+entryPicture[IMG_BLACKBOUQUET] = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lockBouquet.png"))
+entryPicture[IMG_WHITESERVICE] = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/unlock.png"))
+entryPicture[IMG_WHITEBOUQUET] = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/unlockBouquet.png"))
+
+def ParentalControlEntryComponent(service, name, protectionType):
+       locked = protectionType[0]
+       sImage = protectionType[1]
        res = [
                (service, name, locked),
                (eListboxPythonMultiContent.TYPE_TEXT, 80, 5, 300, 50, 0, RT_HALIGN_LEFT, name)
        ]
-       if locked:
-               res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 0, 0, 32, 32, lockPicture))
+       #Changed logic: The image is defined by sImage, not by locked anymore
+       if sImage != "":
+               res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 0, 0, 32, 32, entryPicture[sImage]))
        return res
 
 class ParentalControlList(MenuList):
@@ -25,9 +34,11 @@ class ParentalControlList(MenuList):
        def toggleSelectedLock(self):
                print "self.l.getCurrentSelection():", self.l.getCurrentSelection()
                print "self.l.getCurrentSelectionIndex():", self.l.getCurrentSelectionIndex()
-               self.list[self.l.getCurrentSelectionIndex()] = ParentalControlEntryComponent(self.l.getCurrentSelection()[0][0], self.l.getCurrentSelection()[0][1], not self.l.getCurrentSelection()[0][2]);
-               if self.l.getCurrentSelection()[0][2]:
-                       parentalControl.protectService(self.l.getCurrentSelection()[0][0])
+               curSel = self.l.getCurrentSelection()
+               if curSel[0][2]:
+                       parentalControl.unProtectService(self.l.getCurrentSelection()[0][0])
                else:
-                       parentalControl.unProtectService(self.l.getCurrentSelection()[0][0])    
+                       parentalControl.protectService(self.l.getCurrentSelection()[0][0])      
+               #Instead of just negating the locked- flag, now I call the getProtectionType every time...
+               self.list[self.l.getCurrentSelectionIndex()] = ParentalControlEntryComponent(curSel[0][0], curSel[0][1], parentalControl.getProtectionType(curSel[0][0]))
                self.l.setList(self.list)
index c91d6ad..5e439fd 100755 (executable)
@@ -46,7 +46,7 @@ class PluginComponent:
                        for pluginname in os_listdir(directory_category):
                                path = directory_category + "/" + pluginname
                                if os_path.isdir(path):
-                                       if fileExists(path + "/plugin.pyc") or fileExists(path + "/plugin.py"):
+                                       if fileExists(path + "/plugin.pyc") or fileExists(path + "/plugin.pyo") or fileExists(path + "/plugin.py"):
                                                try:
                                                        plugin = my_import('.'.join(["Plugins", c, pluginname, "plugin"]))
 
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):
old mode 100644 (file)
new mode 100755 (executable)
index 08af7d0..1c5423f
@@ -1,9 +1,9 @@
 from MenuList import MenuList
-from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
+from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
 from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT
 from Tools.LoadPixmap import LoadPixmap
 
-selectionpng = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/selectioncross.png"))
+selectionpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/selectioncross.png"))
 
 def SelectionEntryComponent(description, value, index, selected):
        res = [
diff --git a/lib/python/Components/Sensors.py b/lib/python/Components/Sensors.py
new file mode 100644 (file)
index 0000000..8898a03
--- /dev/null
@@ -0,0 +1,72 @@
+from Components.FanControl import fancontrol
+
+class Sensors:
+       # (type, name, unit, directory)
+       TYPE_TEMPERATURE = 0
+       # (type, name, unit, fanid)
+       TYPE_FAN_RPM = 1
+       
+       def __init__(self):
+               # (type, name, unit, sensor_specific_dict/list)
+               self.sensors_list = []
+               self.addSensors()
+               
+       def getSensorsCount(self, type = None):
+               if type is None:
+                       return len(self.sensors_list)
+               count = 0
+               for sensor in self.sensors_list:
+                       if sensor[0] == type:
+                               count += 1
+               return count
+       
+       # returns a list of sensorids of type "type"
+       def getSensorsList(self, type = None):
+               if type is None:
+                       return range(len(self.sensors_list))
+               list = []
+               for sensorid in range(len(self.sensors_list)):
+                       if self.sensors_list[sensorid][0] == type:
+                               list.append(sensorid)
+               return list
+       
+       
+       def getSensorType(self, sensorid):
+               return self.sensors_list[sensorid][0]
+       
+       def getSensorName(self, sensorid):
+               return self.sensors_list[sensorid][1]
+       
+       def getSensorValue(self, sensorid):
+               value = -1
+               sensor = self.sensors_list[sensorid]
+               if sensor[0] == self.TYPE_TEMPERATURE:
+                       f = open("%s/value" % sensor[3], "r")
+                       value = int(f.readline().strip())
+                       f.close()
+               elif sensor[0] == self.TYPE_FAN_RPM:
+                       value = fancontrol.getFanSpeed(sensor[3])
+               return value
+       
+       def getSensorUnit(self, sensorid):
+               return self.sensors_list[sensorid][2]
+
+       def addSensors(self):
+               import os
+               if os.path.exists("/proc/stb/sensors"):
+                       for dirname in os.listdir("/proc/stb/sensors"):
+                               if dirname.find("temp", 0, 4) == 0:
+                                       f = open("/proc/stb/sensors/%s/name" % dirname, "r")
+                                       name = f.readline().strip()
+                                       f.close()
+                                       
+                                       f = open("/proc/stb/sensors/%s/unit" % dirname, "r")
+                                       unit = f.readline().strip()
+                                       f.close()
+                                       
+                                       self.sensors_list.append((self.TYPE_TEMPERATURE, name, unit, "/proc/stb/sensors/%s" % dirname))
+               for fanid in range(fancontrol.getFanCount()):
+                       if fancontrol.hasRPMSensor(fanid):
+                               self.sensors_list.append((self.TYPE_FAN_RPM, _("Fan %d") % (fanid + 1), "rpm", fanid))
+       
+sensors = Sensors()
\ No newline at end of file
index b0283c1..cd055a8 100644 (file)
@@ -5,7 +5,9 @@ from skin import parseColor, parseFont
 from enigma import eListboxServiceContent, eListbox, eServiceCenter, eServiceReference, gFont, eRect
 from Tools.LoadPixmap import LoadPixmap
 
-from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
+from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
+
+from Components.config import config
 
 class ServiceList(HTMLComponent, GUIComponent):
        MODE_NORMAL = 0
@@ -15,27 +17,27 @@ class ServiceList(HTMLComponent, GUIComponent):
                GUIComponent.__init__(self)
                self.l = eListboxServiceContent()
 
-               pic = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/folder.png"))
+               pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/folder.png"))
                if pic:
                        self.l.setPixmap(self.l.picFolder, pic)
 
-               pic = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/marker.png"))
+               pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/marker.png"))
                if pic:
                        self.l.setPixmap(self.l.picMarker, pic)
 
-               pic = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "ico_dvb_s-fs8.png"))
+               pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "ico_dvb_s-fs8.png"))
                if pic:
                        self.l.setPixmap(self.l.picDVB_S, pic)
 
-               pic = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "ico_dvb_c-fs8.png"))
+               pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "ico_dvb_c-fs8.png"))
                if pic:
                        self.l.setPixmap(self.l.picDVB_C, pic)
 
-               pic = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "ico_dvb_t-fs8.png"))
+               pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "ico_dvb_t-fs8.png"))
                if pic:
                        self.l.setPixmap(self.l.picDVB_T, pic)
 
-               pic = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "ico_service_group-fs8.png"))
+               pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "ico_service_group-fs8.png"))
                if pic:
                        self.l.setPixmap(self.l.picServiceGroup, pic)
 
@@ -62,6 +64,22 @@ class ServiceList(HTMLComponent, GUIComponent):
                                        self.l.setColor(eListboxServiceContent.markedBackgroundSelected, parseColor(value))
                                elif attrib == "foregroundColorServiceNotAvail":
                                        self.l.setColor(eListboxServiceContent.serviceNotAvail, parseColor(value))
+                               elif attrib == "colorEventProgressbar":
+                                       self.l.setColor(eListboxServiceContent.serviceEventProgressbarColor, parseColor(value))
+                               elif attrib == "colorEventProgressbarSelected":
+                                       self.l.setColor(eListboxServiceContent.serviceEventProgressbarColorSelected, parseColor(value))
+                               elif attrib == "colorEventProgressbarBorder":
+                                       self.l.setColor(eListboxServiceContent.serviceEventProgressbarBorderColor, parseColor(value))
+                               elif attrib == "colorEventProgressbarBorderSelected":
+                                       self.l.setColor(eListboxServiceContent.serviceEventProgressbarBorderColorSelected, parseColor(value))
+                               elif attrib == "colorServiceDescription":
+                                       self.l.setColor(eListboxServiceContent.serviceDescriptionColor, parseColor(value))
+                               elif attrib == "colorServiceDescriptionSelected":
+                                       self.l.setColor(eListboxServiceContent.serviceDescriptionColorSelected, parseColor(value))
+                               elif attrib == "picServiceEventProgressbar":
+                                       pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value))
+                                       if pic:
+                                               self.l.setPixmap(self.l.picServiceEventProgressbar, pic)
                                elif attrib == "serviceItemHeight":
                                        self.ItemHeight = int(value)
                                elif attrib == "serviceNameFont":
@@ -213,17 +231,24 @@ class ServiceList(HTMLComponent, GUIComponent):
 
        def setMode(self, mode):
                self.mode = mode
+               self.l.setItemHeight(self.ItemHeight)
+               self.l.setVisualMode(eListboxServiceContent.visModeComplex)
                if mode == self.MODE_NORMAL:
-                       self.l.setItemHeight(self.ItemHeight)
-                       self.l.setVisualMode(eListboxServiceContent.visModeComplex)
+                       if config.usage.show_event_progress_in_servicelist.value:
+                               self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 52, self.ItemHeight))
+                       else:
+                               self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 0, 0))
                        self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont)
                        self.l.setElementPosition(self.l.celServiceName, eRect(0, 0, self.instance.size().width(), self.ItemHeight))
                        self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont)
                else:
-                       self.l.setItemHeight(self.ItemHeight)
-                       self.l.setVisualMode(eListboxServiceContent.visModeComplex)
+                       if config.usage.show_event_progress_in_servicelist.value:
+                               self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(60, 0, 52, self.ItemHeight))
+                       else:
+                               self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(60, 0, 0, 0))
                        self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont)
                        self.l.setElementPosition(self.l.celServiceNumber, eRect(0, 0, 50, self.ItemHeight))
                        self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont)
                        self.l.setElementPosition(self.l.celServiceName, eRect(60, 0, self.instance.size().width()-60, self.ItemHeight))
                        self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont)
+
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 6ef8cac..436d31b 100644 (file)
@@ -4,4 +4,4 @@ install_PYTHON = \
        __init__.py Clock.py EventInfo.py Source.py List.py CurrentService.py \
        FrontendStatus.py Boolean.py Config.py ServiceList.py RdsDecoder.py StreamService.py \
        StaticText.py CanvasSource.py ServiceEvent.py Event.py FrontendInfo.py TunerInfo.py \
-       RecordState.py Progress.py
+       RecordState.py Progress.py Sensor.py
diff --git a/lib/python/Components/Sources/Sensor.py b/lib/python/Components/Sources/Sensor.py
new file mode 100644 (file)
index 0000000..e927bbf
--- /dev/null
@@ -0,0 +1,31 @@
+from Components.Sensors import sensors
+
+from enigma import eTimer
+
+from Source import Source
+
+class SensorSource(Source):
+       def __init__(self, update_interval = 500, sensorid = None):
+               self.update_interval = update_interval
+               self.sensorid = sensorid
+               Source.__init__(self)
+
+               if sensorid is not None:
+                       self.update_timer = eTimer()
+                       self.update_timer.callback.append(self.updateValue)
+                       self.update_timer.start(self.update_interval)
+
+       def getValue(self):
+               if self.sensorid is not None:
+                       return sensors.getSensorValue(self.sensorid)
+               return None
+       
+       def getUnit(self):
+               return sensors.getSensorUnit(self.sensorid)
+
+       def updateValue(self):
+               self.changed((self.CHANGED_POLL,))
+
+       def destroy(self):
+               if self.sensorid is not None:
+                       self.update_timer.callback.remove(self.updateValue)
index d2b405a..f9c4065 100644 (file)
@@ -1,5 +1,6 @@
 from enigma import eDVBResourceManager
 from Tools.Directories import fileExists
+from Tools.HardwareInfo import HardwareInfo
 
 SystemInfo = { }
 
@@ -27,3 +28,4 @@ def countFrontpanelLEDs():
 SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs()
 SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0")
 SystemInfo["FrontpanelDisplayGrayscale"] = fileExists("/dev/dbox/oled0")
+SystemInfo["DeepstandbySupport"] = HardwareInfo().get_device_name() != "dm800"
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)
old mode 100644 (file)
new mode 100755 (executable)
index 44a7eb4..30097c9
@@ -7,7 +7,7 @@ from enigma import eListboxPythonMultiContent, eListbox, gFont, \
        RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER
 from Tools.LoadPixmap import LoadPixmap
 from timer import TimerEntry
-from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
+from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN
 
 class TimerList(HTMLComponent, GUIComponent, object):
 #
@@ -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,)))))
 
@@ -65,7 +71,7 @@ class TimerList(HTMLComponent, GUIComponent, object):
                res.append((eListboxPythonMultiContent.TYPE_TEXT, width-150, 50, 150, 20, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state))
 
                if timer.disabled:
-                       png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/redx.png"))
+                       png = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/icons/redx.png"))
                        res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 490, 5, 40, 40, png))
                return res
 
index f9ab3ed..44b1909 100644 (file)
@@ -1,8 +1,9 @@
 from enigma import eDVBFrontendParametersSatellite, eDVBFrontendParameters, eDVBResourceManager, eTimer
 
 class Tuner:
-       def __init__(self, frontend):
+       def __init__(self, frontend, ignore_rotor=False):
                self.frontend = frontend
+               self.ignore_rotor = ignore_rotor
 
        # transponder = (frequency, symbolrate, polarisation, fec, inversion, orbpos, system, modulation, rolloff, pilot, tsid, onid)
        #                    0         1             2         3       4         5       6        7          8       9      10    11
@@ -21,7 +22,7 @@ class Tuner:
                        parm.rolloff = transponder[8]
                        parm.pilot = transponder[9]
                        feparm = eDVBFrontendParameters()
-                       feparm.setDVBS(parm)
+                       feparm.setDVBS(parm, self.ignore_rotor)
                        self.lastparm = feparm
                        self.frontend.tune(feparm)
 
index 6fcab8b..b86c1a1 100644 (file)
@@ -1,12 +1,13 @@
 from Components.Harddisk import harddiskmanager
 from config import ConfigSubsection, ConfigYesNo, config, ConfigSelection, ConfigText, ConfigNumber, ConfigSet, ConfigLocations
+from Tools.Directories import resolveFilename, SCOPE_HDD
 from enigma import Misc_Options, setTunerTypePriorityOrder;
 from SystemInfo import SystemInfo
 import os
 
 def InitUsageConfig():
        config.usage = ConfigSubsection();
-       config.usage.showdish = ConfigYesNo(default = False)
+       config.usage.showdish = ConfigYesNo(default = True)
        config.usage.multibouquet = ConfigYesNo(default = False)
        config.usage.quickzap_bouquet_change = ConfigYesNo(default = False)
        config.usage.e1like_radio_mode = ConfigYesNo(default = False)
@@ -30,8 +31,11 @@ def InitUsageConfig():
                ("standard", _("standard")), ("swap", _("swap PiP and main picture")),
                ("swapstop", _("move PiP to main picture")), ("stop", _("stop PiP")) ])
 
+       config.usage.default_path = ConfigText(default = resolveFilename(SCOPE_HDD))
+       config.usage.timer_path = ConfigText(default = "<default>")
+       config.usage.instantrec_path = ConfigText(default = "<default>")
+       config.usage.timeshift_path = ConfigText(default = "/media/hdd/")
        config.usage.allowed_timeshift_paths = ConfigLocations(default = ["/media/hdd/"])
-       config.usage.timeshift_path = ConfigText(default = "/media/hdd")
 
        config.usage.on_movie_start = ConfigSelection(default = "ask", choices = [
                ("ask", _("Ask user")), ("resume", _("Resume from last position")), ("beginning", _("Start from the beginning")) ])
@@ -47,7 +51,14 @@ def InitUsageConfig():
 
        config.usage.on_long_powerpress = ConfigSelection(default = "show_menu", choices = [
                ("show_menu", _("show shutdown menu")),
-               ("shutdown", _("immediate shutdown")) ] )
+               ("shutdown", _("immediate shutdown")),
+               ("standby", _("Standby")) ] )
+       
+       config.usage.on_short_powerpress = ConfigSelection(default = "standby", choices = [
+               ("show_menu", _("show shutdown menu")),
+               ("shutdown", _("immediate shutdown")),
+               ("standby", _("Standby")) ] )
+
 
        config.usage.alternatives_priority = ConfigSelection(default = "0", choices = [
                ("0", "DVB-S/-C/-T"),
@@ -57,6 +68,8 @@ def InitUsageConfig():
                ("4", "DVB-T/-C/-S"),
                ("5", "DVB-T/-S/-C") ])
 
+       config.usage.show_event_progress_in_servicelist = ConfigYesNo(default = False)
+
        config.usage.blinking_display_clock_during_recording = ConfigYesNo(default = False)
 
        config.usage.show_message_when_recording_starts = ConfigYesNo(default = True)
@@ -65,19 +78,19 @@ def InitUsageConfig():
        
        def TunerTypePriorityOrderChanged(configElement):
                setTunerTypePriorityOrder(int(configElement.value))
-       config.usage.alternatives_priority.addNotifier(TunerTypePriorityOrderChanged)
+       config.usage.alternatives_priority.addNotifier(TunerTypePriorityOrderChanged, immediate_feedback=False)
 
        def setHDDStandby(configElement):
                for hdd in harddiskmanager.HDDList():
                        hdd[1].setIdleTime(int(configElement.value))
-       config.usage.hdd_standby.addNotifier(setHDDStandby)
+       config.usage.hdd_standby.addNotifier(setHDDStandby, immediate_feedback=False)
 
        def set12VOutput(configElement):
                if configElement.value == "on":
                        Misc_Options.getInstance().set_12V_output(1)
                elif configElement.value == "off":
                        Misc_Options.getInstance().set_12V_output(0)
-       config.usage.output_12V.addNotifier(set12VOutput)
+       config.usage.output_12V.addNotifier(set12VOutput, immediate_feedback=False)
 
        SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output()
 
@@ -128,3 +141,23 @@ def updateChoices(sel, choices):
                                        defval = str(x)
                                        break
                sel.setChoices(map(str, choices), defval)
+
+def preferredPath(path):
+       if config.usage.setup_level.index < 2 or path == "<default>":
+               return None  # config.usage.default_path.value, but delay lookup until usage
+       elif path == "<current>":
+               return config.movielist.last_videodir.value
+       elif path == "<timer>":
+               return config.movielist.last_timer_videodir.value
+       else:
+               return path
+
+def preferredTimerPath():
+       return preferredPath(config.usage.timer_path.value)
+
+def preferredInstantRecordPath():
+       return preferredPath(config.usage.instantrec_path.value)
+
+def defaultMoviePath():
+       return config.usage.default_path.value
+
index 789ec32..471b59e 100755 (executable)
@@ -1,6 +1,6 @@
 from enigma import getPrevAsciiCode
 from Tools.NumericalTextInput import NumericalTextInput
-from Tools.Directories import resolveFilename, SCOPE_CONFIG
+from Tools.Directories import resolveFilename, SCOPE_CONFIG, fileExists
 from Components.Harddisk import harddiskmanager
 from copy import copy as copy_copy
 from os import path as os_path
@@ -1034,13 +1034,13 @@ class ConfigSelectionNumber(ConfigSelection):
                        step += stepwidth
                
                ConfigSelection.__init__(self, choices, default)
-               
+
        def getValue(self):
-               return int(self.text)
+               return int(ConfigSelection.getValue(self))
 
        def setValue(self, val):
-               self.text = str(val)
-               
+               ConfigSelection.setValue(self, str(val))
+
        def handleKey(self, key):
                if not self.wraparound:
                        if key == KEY_RIGHT:
@@ -1050,8 +1050,6 @@ class ConfigSelectionNumber(ConfigSelection):
                                if self.choices.index(self.value) == 0:
                                        return
                ConfigSelection.handleKey(self, key)
-                               
-                               
 
 class ConfigNumber(ConfigText):
        def __init__(self, default = 0):
@@ -1140,6 +1138,9 @@ class ConfigDirectory(ConfigText):
                else:
                        return ConfigText.getMulti(self, selected)
 
+       def onSelect(self, session):
+               self.allmarked = (self.value != "")
+
 # a slider.
 class ConfigSlider(ConfigElement):
        def __init__(self, default = 0, increment = 1, limits = (0, 100)):
@@ -1285,7 +1286,6 @@ class ConfigLocations(ConfigElement):
                self.default = default
                self.locations = []
                self.mountpoints = []
-               harddiskmanager.on_partition_list_change.append(self.mountpointsChanged)
                self.value = default[:]
 
        def setValue(self, value):
@@ -1322,7 +1322,7 @@ class ConfigLocations(ConfigElement):
                locations = [[x, None, False, False] for x in tmp]
                self.refreshMountpoints()
                for x in locations:
-                       if os_path.exists(x[0]):
+                       if fileExists(x[0]):
                                x[1] = self.getMountpoint(x[0])
                                x[2] = True
                self.locations = locations
@@ -1341,20 +1341,11 @@ class ConfigLocations(ConfigElement):
                        return False
                return self.tostring([x[0] for x in locations]) != sv
 
-       def mountpointsChanged(self, action, dev):
-               print "Mounts changed: ", action, dev
-               mp = dev.mountpoint+"/"
-               if action == "add":
-                       self.addedMount(mp)
-               elif action == "remove":
-                       self.removedMount(mp)
-               self.refreshMountpoints()
-
        def addedMount(self, mp):
                for x in self.locations:
                        if x[1] == mp:
                                x[2] = True
-                       elif x[1] == None and os_path.exists(x[0]):
+                       elif x[1] == None and fileExists(x[0]):
                                x[1] = self.getMountpoint(x[0])
                                x[2] = True
 
@@ -1364,7 +1355,7 @@ class ConfigLocations(ConfigElement):
                                x[2] = False
 
        def refreshMountpoints(self):
-               self.mountpoints = [p.mountpoint + "/" for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
+               self.mountpoints = [p.mountpoint for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
                self.mountpoints.sort(key = lambda x: -len(x))
 
        def checkChangedMountpoints(self):
old mode 100644 (file)
new mode 100755 (executable)
index 23edc8e..1431caf
@@ -8,7 +8,7 @@
                     <packagename>enigma2-plugin-extensions-cutlisteditor</packagename>
                     <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/cutlisteditor.jpg&quo