movie player configuration options, by Anders Holst
[enigma2.git] / lib / python / Screens / InfoBarGenerics.py
index f1744fed053708b9da96e18d31ad39a4ec5f7bae..3bc8a419b220f083203e3a05b188c3725fa0f4d8 100644 (file)
@@ -5,17 +5,12 @@ from Components.ActionMap import NumberActionMap
 from Components.BlinkingPixmap import BlinkingPixmapConditional
 from Components.Harddisk import harddiskmanager
 from Components.Input import Input
 from Components.BlinkingPixmap import BlinkingPixmapConditional
 from Components.Harddisk import harddiskmanager
 from Components.Input import Input
-from Components.Label import *
-from Components.Pixmap import Pixmap, PixmapConditional
+from Components.Label import Label
+from Components.Pixmap import Pixmap
 from Components.PluginComponent import plugins
 from Components.PluginComponent import plugins
-from Components.ProgressBar import *
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.ServiceEventTracker import ServiceEventTracker
-from Components.Sources.CurrentService import CurrentService
-from Components.Sources.EventInfo import EventInfo
-from Components.Sources.FrontendStatus import FrontendStatus
+from Components.Sources.Source import ObsoleteSource
 from Components.Sources.Boolean import Boolean
 from Components.Sources.Boolean import Boolean
-from Components.Sources.Clock import Clock
-from Components.TimerList import TimerEntryComponent
 from Components.config import config, ConfigBoolean, ConfigClock
 from EpgSelection import EPGSelection
 from Plugins.Plugin import PluginDescriptor
 from Components.config import config, ConfigBoolean, ConfigClock
 from EpgSelection import EPGSelection
 from Plugins.Plugin import PluginDescriptor
@@ -51,7 +46,6 @@ from Menu import MainMenu, mdom
 class InfoBarDish:
        def __init__(self):
                self.dishDialog = self.session.instantiateDialog(Dish)
 class InfoBarDish:
        def __init__(self):
                self.dishDialog = self.session.instantiateDialog(Dish)
-               self.onLayoutFinish.append(self.dishDialog.show)
 
 class InfoBarShowHide:
        """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
 
 class InfoBarShowHide:
        """ InfoBar show/hide control, accepts toggleShow and hide actions, might start
@@ -77,7 +71,7 @@ class InfoBarShowHide:
                self.__locked = 0
 
                self.hideTimer = eTimer()
                self.__locked = 0
 
                self.hideTimer = eTimer()
-               self.hideTimer.timeout.get().append(self.doTimerHide)
+               self.hideTimer.callback.append(self.doTimerHide)
                self.hideTimer.start(5000, True)
 
                self.onShow.append(self.__onShow)
                self.hideTimer.start(5000, True)
 
                self.onShow.append(self.__onShow)
@@ -160,7 +154,7 @@ class NumberZap(Screen):
 
                self["number"] = Label(self.field)
 
 
                self["number"] = Label(self.field)
 
-               self["actions"] = NumberActionMap( [ "SetupActions" ], 
+               self["actions"] = NumberActionMap( [ "SetupActions" ],
                        {
                                "cancel": self.quit,
                                "ok": self.keyOK,
                        {
                                "cancel": self.quit,
                                "ok": self.keyOK,
@@ -177,7 +171,7 @@ class NumberZap(Screen):
                        })
 
                self.Timer = eTimer()
                        })
 
                self.Timer = eTimer()
-               self.Timer.timeout.get().append(self.keyOK)
+               self.Timer.callback.append(self.keyOK)
                self.Timer.start(3000, True)
 
 class InfoBarNumberZap:
                self.Timer.start(3000, True)
 
 class InfoBarNumberZap:
@@ -200,9 +194,13 @@ class InfoBarNumberZap:
        def keyNumberGlobal(self, number):
 #              print "You pressed number " + str(number)
                if number == 0:
        def keyNumberGlobal(self, number):
 #              print "You pressed number " + str(number)
                if number == 0:
-                       self.servicelist.recallPrevService()
+                       if isinstance(self, InfoBarPiP) and self.pipHandles0Action():
+                               self.pipDoHandle0Action()
+                       else:
+                               self.servicelist.recallPrevService()
                else:
                else:
-                       self.session.openWithCallback(self.numberEntered, NumberZap, number)
+                       if self.has_key("TimeshiftActions") and not self.timeshift_enabled:
+                               self.session.openWithCallback(self.numberEntered, NumberZap, number)
 
        def numberEntered(self, retval):
 #              print self.servicelist
 
        def numberEntered(self, retval):
 #              print self.servicelist
@@ -250,7 +248,7 @@ class InfoBarNumberZap:
 config.misc.initialchannelselection = ConfigBoolean(default = True)
 
 class InfoBarChannelSelection:
 config.misc.initialchannelselection = ConfigBoolean(default = True)
 
 class InfoBarChannelSelection:
-       """ ChannelSelection - handles the channelSelection dialog and the initial 
+       """ ChannelSelection - handles the channelSelection dialog and the initial
        channelChange actions which open the channelSelection dialog """
        def __init__(self):
                #instantiate forever
        channelChange actions which open the channelSelection dialog """
        def __init__(self):
                #instantiate forever
@@ -342,7 +340,7 @@ class InfoBarChannelSelection:
 class InfoBarMenu:
        """ Handles a menu action, to open the (main) menu """
        def __init__(self):
 class InfoBarMenu:
        """ Handles a menu action, to open the (main) menu """
        def __init__(self):
-               self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions", 
+               self["MenuActions"] = HelpableActionMap(self, "InfobarMenuActions",
                        {
                                "mainMenu": (self.mainMenu, _("Enter main menu...")),
                        })
                        {
                                "mainMenu": (self.mainMenu, _("Enter main menu...")),
                        })
@@ -403,9 +401,10 @@ class InfoBarEPG:
                self.dlg_stack = [ ]
                self.bouquetSel = None
                self.eventView = None
                self.dlg_stack = [ ]
                self.bouquetSel = None
                self.eventView = None
-               self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions", 
+               self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
                        {
                                "showEventInfo": (self.openEventView, _("show EPG...")),
                        {
                                "showEventInfo": (self.openEventView, _("show EPG...")),
+                               "showSingleServiceEPG": (self.openSingleServiceEPG, _("show single service EPG...")),
                                "showInfobarOrEpgWhenInfobarAlreadyVisible": self.showEventInfoWhenNotVisible,
                        })
 
                                "showInfobarOrEpgWhenInfobarAlreadyVisible": self.showEventInfoWhenNotVisible,
                        })
 
@@ -483,7 +482,7 @@ class InfoBarEPG:
                                self.dlg_stack.append(self.bouquetSel)
                        else:
                                self.bouquetSel = self.session.open(BouquetSelector, bouquets, self.openBouquetEPG, enableWrapAround=True)
                                self.dlg_stack.append(self.bouquetSel)
                        else:
                                self.bouquetSel = self.session.open(BouquetSelector, bouquets, self.openBouquetEPG, enableWrapAround=True)
-               elif cnt == 1: 
+               elif cnt == 1:
                        self.openBouquetEPG(bouquets[0][1], withCallback)
 
        def openSingleServiceEPG(self):
                        self.openBouquetEPG(bouquets[0][1], withCallback)
 
        def openSingleServiceEPG(self):
@@ -542,13 +541,13 @@ class InfoBarEPG:
 class InfoBarTuner:
        """provides a snr/agc/ber display"""
        def __init__(self):
 class InfoBarTuner:
        """provides a snr/agc/ber display"""
        def __init__(self):
-               self["FrontendStatus"] = FrontendStatus(service_source = self.session.nav.getCurrentService)
+               self["FrontendStatus"] = ObsoleteSource(new_source = "session.FrontendStatus", removal_date = "2008-01")
 
 class InfoBarEvent:
        """provides a current/next event info display"""
        def __init__(self):
 
 class InfoBarEvent:
        """provides a current/next event info display"""
        def __init__(self):
-               self["Event_Now"] = EventInfo(self.session.nav, EventInfo.NOW)
-               self["Event_Next"] = EventInfo(self.session.nav, EventInfo.NEXT)
+               self["Event_Now"] = ObsoleteSource(new_source = "session.Event_Now", removal_date = "2008-01")
+               self["Event_Next"] = ObsoleteSource(new_source = "session.Event_Next", removal_date = "2008-01")
 
 class InfoBarRdsDecoder:
        """provides RDS and Rass support/display"""
 
 class InfoBarRdsDecoder:
        """provides RDS and Rass support/display"""
@@ -600,30 +599,13 @@ class InfoBarRdsDecoder:
 
 class InfoBarServiceName:
        def __init__(self):
 
 class InfoBarServiceName:
        def __init__(self):
-               self["CurrentService"] = CurrentService(self.session.nav)
+               self["CurrentService"] = ObsoleteSource(new_source = "session.CurrentService", removal_date = "2008-01")
 
 class InfoBarSeek:
        """handles actions like seeking, pause"""
 
 
 class InfoBarSeek:
        """handles actions like seeking, pause"""
 
-       # ispause, isff, issm
        SEEK_STATE_PLAY = (0, 0, 0, ">")
        SEEK_STATE_PAUSE = (1, 0, 0, "||")
        SEEK_STATE_PLAY = (0, 0, 0, ">")
        SEEK_STATE_PAUSE = (1, 0, 0, "||")
-       SEEK_STATE_FF_2X = (0, 2, 0, ">> 2x")
-       SEEK_STATE_FF_4X = (0, 4, 0, ">> 4x")
-       SEEK_STATE_FF_8X = (0, 8, 0, ">> 8x")
-       SEEK_STATE_FF_32X = (0, 32, 0, ">> 32x")
-       SEEK_STATE_FF_64X = (0, 64, 0, ">> 64x")
-       SEEK_STATE_FF_128X = (0, 128, 0, ">> 128x")
-
-       SEEK_STATE_BACK_16X = (0, -16, 0, "<< 16x")
-       SEEK_STATE_BACK_32X = (0, -32, 0, "<< 32x")
-       SEEK_STATE_BACK_64X = (0, -64, 0, "<< 64x")
-       SEEK_STATE_BACK_128X = (0, -128, 0, "<< 128x")
-
-       SEEK_STATE_SM_HALF = (0, 0, 2, "/2")
-       SEEK_STATE_SM_QUARTER = (0, 0, 4, "/4")
-       SEEK_STATE_SM_EIGHTH = (0, 0, 8, "/8")
-
        SEEK_STATE_EOF = (1, 0, 0, "END")
 
        def __init__(self, actionmap = "InfobarSeekActions"):
        SEEK_STATE_EOF = (1, 0, 0, "END")
 
        def __init__(self, actionmap = "InfobarSeekActions"):
@@ -635,6 +617,13 @@ class InfoBarSeek:
                                iPlayableService.evEOF: self.__evEOF,
                                iPlayableService.evSOF: self.__evSOF,
                        })
                                iPlayableService.evEOF: self.__evEOF,
                                iPlayableService.evSOF: self.__evSOF,
                        })
+               self.eofState = 0
+               self.eofTimer = eTimer()
+               self.eofTimer.timeout.get().append(self.doEof)
+               self.eofInhibitTimer = eTimer()
+               self.eofInhibitTimer.timeout.get().append(self.inhibitEof)
+
+               self.minSpeedBackward = 16
 
                class InfoBarSeekActionMap(HelpableActionMap):
                        def __init__(self, screen, *args, **kwargs):
 
                class InfoBarSeekActionMap(HelpableActionMap):
                        def __init__(self, screen, *args, **kwargs):
@@ -645,13 +634,19 @@ class InfoBarSeek:
                                print "action:", action
                                if action[:5] == "seek:":
                                        time = int(action[5:])
                                print "action:", action
                                if action[:5] == "seek:":
                                        time = int(action[5:])
-                                       self.screen.seekRelative(time * 90000)
-                                       self.screen.showAfterSeek()
+                                       self.screen.doSeekRelative(time * 90000)
                                        return 1
                                        return 1
+                               elif action[:8] == "seekdef:":
+                                       key = int(action[8:])
+                                       time = [-config.seek.selfdefined_13.value, False, config.seek.selfdefined_13.value,
+                                               -config.seek.selfdefined_46.value, False, config.seek.selfdefined_46.value,
+                                               -config.seek.selfdefined_79.value, False, config.seek.selfdefined_79.value][key-1]
+                                       self.screen.doSeekRelative(time * 90000)
+                                       return 1                                        
                                else:
                                        return HelpableActionMap.action(self, contexts, action)
 
                                else:
                                        return HelpableActionMap.action(self, contexts, action)
 
-               self["SeekActions"] = InfoBarSeekActionMap(self, actionmap, 
+               self["SeekActions"] = InfoBarSeekActionMap(self, actionmap,
                        {
                                "playpauseService": self.playpauseService,
                                "pauseService": (self.pauseService, _("pause")),
                        {
                                "playpauseService": self.playpauseService,
                                "pauseService": (self.pauseService, _("pause")),
@@ -660,16 +655,14 @@ class InfoBarSeek:
                                "seekFwd": (self.seekFwd, _("skip forward")),
                                "seekFwdManual": (self.seekFwdManual, _("skip forward (enter time)")),
                                "seekBack": (self.seekBack, _("skip backward")),
                                "seekFwd": (self.seekFwd, _("skip forward")),
                                "seekFwdManual": (self.seekFwdManual, _("skip forward (enter time)")),
                                "seekBack": (self.seekBack, _("skip backward")),
-                               "seekBackManual": (self.seekBackManual, _("skip backward (enter time)")),
-                               
-                               "seekFwdDef": (self.seekFwdDef, _("skip forward (self defined)")),
-                               "seekBackDef": (self.seekBackDef, _("skip backward (self defined)"))
+                               "seekBackManual": (self.seekBackManual, _("skip backward (enter time)"))
                        }, prio=-1)
                        # give them a little more priority to win over color buttons
 
                self["SeekActions"].setEnabled(False)
 
                self.seekstate = self.SEEK_STATE_PLAY
                        }, prio=-1)
                        # give them a little more priority to win over color buttons
 
                self["SeekActions"].setEnabled(False)
 
                self.seekstate = self.SEEK_STATE_PLAY
+               self.lastseekstate = self.SEEK_STATE_PLAY
 
                self.onPlayStateChanged = [ ]
 
 
                self.onPlayStateChanged = [ ]
 
@@ -677,6 +670,53 @@ class InfoBarSeek:
 
                self.__seekableStatusChanged()
 
 
                self.__seekableStatusChanged()
 
+       def makeStateForward(self, n):
+               minspeed = config.seek.stepwise_minspeed.value
+               repeat = int(config.seek.stepwise_repeat.value)
+               if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+                       return (0, n * repeat, repeat, ">> %dx" % n)
+               else:
+                       return (0, n, 0, ">> %dx" % n)
+
+       def makeStateBackward(self, n):
+               minspeed = config.seek.stepwise_minspeed.value
+               repeat = int(config.seek.stepwise_repeat.value)
+               if n < self.minSpeedBackward:
+                       r = (self.minSpeedBackward - 1)/ n + 1
+                       if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+                               r = max(r, repeat)
+                       return (0, -n * r, r, "<< %dx" % n)
+               elif minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+                       return (0, -n * repeat, repeat, "<< %dx" % n)
+               else:
+                       return (0, -n, 0, "<< %dx" % n)
+
+       def makeStateSlowMotion(self, n):
+               return (0, 0, n, "/%d" % n)
+
+       def isStateForward(self, state):
+               return state[1] > 1
+
+       def isStateBackward(self, state):
+               return state[1] < 0
+
+       def isStateSlowMotion(self, state):
+               return state[1] == 0 and state[2] > 1
+
+       def getHigher(self, n, lst):
+               for x in lst:
+                       if x > n:
+                               return x
+               return False
+
+       def getLower(self, n, lst):
+               lst = lst+[]
+               lst.reverse()
+               for x in lst:
+                       if x < n:
+                               return x
+               return False
+
        def showAfterSeek(self):
                if isinstance(self, InfoBarShowHide):
                        self.doShow()
        def showAfterSeek(self):
                if isinstance(self, InfoBarShowHide):
                        self.doShow()
@@ -717,6 +757,9 @@ class InfoBarSeek:
        def __serviceStarted(self):
                self.seekstate = self.SEEK_STATE_PLAY
                self.__seekableStatusChanged()
        def __serviceStarted(self):
                self.seekstate = self.SEEK_STATE_PLAY
                self.__seekableStatusChanged()
+               if self.eofState != 0:
+                       self.eofTimer.stop()
+               self.eofState = 0
 
        def setSeekState(self, state):
                service = self.session.nav.getCurrentService()
 
        def setSeekState(self, state):
                service = self.session.nav.getCurrentService()
@@ -756,14 +799,16 @@ class InfoBarSeek:
 
        def pauseService(self):
                if self.seekstate == self.SEEK_STATE_PAUSE:
 
        def pauseService(self):
                if self.seekstate == self.SEEK_STATE_PAUSE:
-                       print "pause, but in fact unpause"
-                       self.unPauseService()
+                       if config.seek.on_pause.value == "play":
+                               self.unPauseService()
+                       elif config.seek.on_pause.value == "step":
+                               self.doSeekRelative(0)
+                       elif config.seek.on_pause.value == "last":
+                               self.setSeekState(self.lastseekstate)
+                               self.lastseekstate = self.SEEK_STATE_PLAY
                else:
                else:
-                       if self.seekstate == self.SEEK_STATE_PLAY:
-                               print "yes, playing."
-                       else:
-                               print "no", self.seekstate
-                       print "pause"
+                       if self.seekstate != self.SEEK_STATE_EOF:
+                               self.lastseekstate = self.seekstate
                        self.setSeekState(self.SEEK_STATE_PAUSE);
 
        def unPauseService(self):
                        self.setSeekState(self.SEEK_STATE_PAUSE);
 
        def unPauseService(self):
@@ -772,100 +817,117 @@ class InfoBarSeek:
                        return 0
                self.setSeekState(self.SEEK_STATE_PLAY)
 
                        return 0
                self.setSeekState(self.SEEK_STATE_PLAY)
 
-       def doSeek(self, seektime):
-               print "doseek", seektime
-               service = self.session.nav.getCurrentService()
-               if service is None:
+       def doSeek(self, pts):
+               seekable = self.getSeek()
+               if seekable is None:
                        return
                        return
+               prevstate = self.seekstate
+               if self.eofState == 1:
+                       self.eofState = 2
+                       self.inhibitEof()
+               if self.seekstate == self.SEEK_STATE_EOF:
+                       if prevstate == self.SEEK_STATE_PAUSE:
+                               self.setSeekState(self.SEEK_STATE_PAUSE)
+                       else:
+                               self.setSeekState(self.SEEK_STATE_PLAY)
+               self.eofInhibitTimer.start(200, True)
+               seekable.seekTo(pts)
 
 
+       def doSeekRelative(self, pts):
                seekable = self.getSeek()
                if seekable is None:
                        return
                seekable = self.getSeek()
                if seekable is None:
                        return
-
-               seekable.seekTo(90 * seektime)
+               prevstate = self.seekstate
+               if self.eofState == 1:
+                       self.eofState = 2
+                       self.inhibitEof()
+               if self.seekstate == self.SEEK_STATE_EOF:
+                       if prevstate == self.SEEK_STATE_PAUSE:
+                               self.setSeekState(self.SEEK_STATE_PAUSE)
+                       else:
+                               self.setSeekState(self.SEEK_STATE_PLAY)
+               self.eofInhibitTimer.start(200, True)
+               seekable.seekRelative(pts<0 and -1 or 1, abs(pts))
+               if abs(pts) > 100 and config.usage.show_infobar_on_skip.value:
+                       self.showAfterSeek()
 
        def seekFwd(self):
 
        def seekFwd(self):
-               lookup = {
-                               self.SEEK_STATE_PLAY: self.SEEK_STATE_FF_2X,
-                               self.SEEK_STATE_PAUSE: self.SEEK_STATE_SM_EIGHTH,
-                               self.SEEK_STATE_FF_2X: self.SEEK_STATE_FF_4X,
-                               self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_8X,
-                               self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_32X,
-                               self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_64X,
-                               self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_128X,
-                               self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_128X,
-                               self.SEEK_STATE_BACK_16X: self.SEEK_STATE_PLAY,
-                               self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_16X,
-                               self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_32X,
-                               self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_64X,
-                               self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_HALF,
-                               self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_HALF,
-                               self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_SM_QUARTER,
-                               self.SEEK_STATE_EOF: self.SEEK_STATE_EOF,
-                       }
-               self.setSeekState(lookup[self.seekstate])
+               if self.seekstate == self.SEEK_STATE_PLAY:
+                       self.setSeekState(self.makeStateForward(int(config.seek.enter_forward.value)))
+               elif self.seekstate == self.SEEK_STATE_PAUSE:
+                       if config.seek.speeds_slowmotion:
+                               self.setSeekState(self.makeStateSlowMotion(config.seek.speeds_slowmotion.value[-1]))
+                       else:
+                               self.setSeekState(self.makeStateForward(int(config.seek.enter_forward.value)))
+               elif self.seekstate == self.SEEK_STATE_EOF:
+                       pass
+               elif self.isStateForward(self.seekstate):
+                       speed = self.seekstate[1]
+                       if self.seekstate[2]:
+                               speed /= self.seekstate[2]
+                       speed = self.getHigher(speed, config.seek.speeds_forward.value) or config.seek.speeds_forward.value[-1]
+                       self.setSeekState(self.makeStateForward(speed))
+               elif self.isStateBackward(self.seekstate):
+                       speed = -self.seekstate[1]
+                       if self.seekstate[2]:
+                               speed /= self.seekstate[2]
+                       speed = self.getLower(speed, config.seek.speeds_backward.value)
+                       if speed:
+                               self.setSeekState(self.makeStateBackward(speed))
+                       else:
+                               self.setSeekState(self.SEEK_STATE_PLAY)
+               elif self.isStateSlowMotion(self.seekstate):
+                       speed = self.getLower(self.seekstate[2], config.seek.speeds_slowmotion.value) or config.seek.speeds_slowmotion.value[0]
+                       self.setSeekState(self.makeStateSlowMotion(speed))
 
        def seekBack(self):
 
        def seekBack(self):
-               lookup = {
-                               self.SEEK_STATE_PLAY: self.SEEK_STATE_BACK_16X,
-                               self.SEEK_STATE_PAUSE: self.SEEK_STATE_PAUSE,
-                               self.SEEK_STATE_FF_2X: self.SEEK_STATE_PLAY,
-                               self.SEEK_STATE_FF_4X: self.SEEK_STATE_FF_2X,
-                               self.SEEK_STATE_FF_8X: self.SEEK_STATE_FF_4X,
-                               self.SEEK_STATE_FF_32X: self.SEEK_STATE_FF_8X,
-                               self.SEEK_STATE_FF_64X: self.SEEK_STATE_FF_32X,
-                               self.SEEK_STATE_FF_128X: self.SEEK_STATE_FF_64X,
-                               self.SEEK_STATE_BACK_16X: self.SEEK_STATE_BACK_32X,
-                               self.SEEK_STATE_BACK_32X: self.SEEK_STATE_BACK_64X,
-                               self.SEEK_STATE_BACK_64X: self.SEEK_STATE_BACK_128X,
-                               self.SEEK_STATE_BACK_128X: self.SEEK_STATE_BACK_128X,
-                               self.SEEK_STATE_SM_HALF: self.SEEK_STATE_SM_QUARTER,
-                               self.SEEK_STATE_SM_QUARTER: self.SEEK_STATE_SM_EIGHTH,
-                               self.SEEK_STATE_SM_EIGHTH: self.SEEK_STATE_PAUSE,
-                               self.SEEK_STATE_EOF: self.SEEK_STATE_BACK_16X,
-                       }
-               self.setSeekState(lookup[self.seekstate])
-
-               if self.seekstate == self.SEEK_STATE_PAUSE:
-                       seekable = self.getSeek()
-                       if seekable is not None:
-                               seekable.seekRelative(-1, 3)
+               if self.seekstate == self.SEEK_STATE_PLAY:
+                       self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
+               elif self.seekstate == self.SEEK_STATE_EOF:
+                       self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
+                       self.doSeekRelative(-6)
+               elif self.seekstate == self.SEEK_STATE_PAUSE:
+                       self.doSeekRelative(-3)
+               elif self.isStateForward(self.seekstate):
+                       speed = self.seekstate[1]
+                       if self.seekstate[2]:
+                               speed /= self.seekstate[2]
+                       speed = self.getLower(speed, config.seek.speeds_forward.value)
+                       if speed:
+                               self.setSeekState(self.makeStateForward(speed))
+                       else:
+                               self.setSeekState(self.SEEK_STATE_PLAY)
+               elif self.isStateBackward(self.seekstate):
+                       speed = -self.seekstate[1]
+                       if self.seekstate[2]:
+                               speed /= self.seekstate[2]
+                       speed = self.getHigher(speed, config.seek.speeds_backward.value) or config.seek.speeds_backward.value[-1]
+                       self.setSeekState(self.makeStateBackward(speed))
+               elif self.isStateSlowMotion(self.seekstate):
+                       speed = self.getHigher(self.seekstate[2], config.seek.speeds_slowmotion.value)
+                       if speed:
+                               self.setSeekState(self.makeStateSlowMotion(speed))
+                       else:
+                               self.setSeekState(self.SEEK_STATE_PAUSE)
 
 
-       def seekFwdDef(self):
-               seconds = config.usage.self_defined_seek.value
-               print "Seek", seconds, "seconds self defined forward"
-               seekable = self.getSeek()
-               if seekable is not None:
-                       seekable.seekRelative(1, seconds * 90000)
-               
-       def seekBackDef(self):
-               seconds = config.usage.self_defined_seek.value
-               print "Seek", seconds, "seconds self defined backward"
-               seekable = self.getSeek()
-               if seekable is not None:
-                       seekable.seekRelative(1, 0 - seconds * 90000)
-               
        def seekFwdManual(self):
                self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
 
        def fwdSeekTo(self, minutes):
                print "Seek", minutes, "minutes forward"
        def seekFwdManual(self):
                self.session.openWithCallback(self.fwdSeekTo, MinuteInput)
 
        def fwdSeekTo(self, minutes):
                print "Seek", minutes, "minutes forward"
-               if minutes != 0:
-                       seekable = self.getSeek()
-                       if seekable is not None:
-                               seekable.seekRelative(1, minutes * 60 * 90000)
+               self.doSeekRelative(minutes * 60 * 90000)
 
        def seekBackManual(self):
                self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
 
        def rwdSeekTo(self, minutes):
                print "rwdSeekTo"
 
        def seekBackManual(self):
                self.session.openWithCallback(self.rwdSeekTo, MinuteInput)
 
        def rwdSeekTo(self, minutes):
                print "rwdSeekTo"
-               self.fwdSeekTo(0 - minutes)
+               self.doSeekRelative(-minutes * 60 * 90000)
 
        def checkSkipShowHideLock(self):
                wantlock = self.seekstate != self.SEEK_STATE_PLAY
 
 
        def checkSkipShowHideLock(self):
                wantlock = self.seekstate != self.SEEK_STATE_PLAY
 
-               if config.usage.show_infobar_on_zap.value:
+               if config.usage.show_infobar_on_skip.value:
                        if self.lockedBecauseOfSkipping and not wantlock:
                                self.unlockShow()
                                self.lockedBecauseOfSkipping = False
                        if self.lockedBecauseOfSkipping and not wantlock:
                                self.unlockShow()
                                self.lockedBecauseOfSkipping = False
@@ -874,48 +936,76 @@ class InfoBarSeek:
                                self.lockShow()
                                self.lockedBecauseOfSkipping = True
 
                                self.lockShow()
                                self.lockedBecauseOfSkipping = True
 
+       def calcRemainingTime(self):
+               seekable = self.getSeek()
+               if seekable is not None:
+                       len = seekable.getLength()
+                       try:
+                               tmp = self.cueGetEndCutPosition()
+                               if tmp:
+                                       len = [False, tmp]
+                       except:
+                               pass
+                       pos = seekable.getPlayPosition()
+                       speednom = self.seekstate[1] or 1
+                       speedden = self.seekstate[2] or 1
+                       if not len[0] and not pos[0]:
+                               if len[1] <= pos[1]:
+                                       return 0
+                               time = (len[1] - pos[1])*speedden/(90*speednom)
+                               return time
+               return False
+               
        def __evEOF(self):
        def __evEOF(self):
+               if self.eofState == 0 and self.seekstate != self.SEEK_STATE_EOF:
+                       self.eofState = 1
+                       time = self.calcRemainingTime()
+                       if not time:
+                               time = 3000   # Failed to calc, use default
+                       elif time == 0:
+                               time = 300    # Passed end, shortest wait
+                       elif time > 15000:
+                               self.eofState = -2  # Too long, block eof
+                               time = 15000
+                       else:
+                               time += 1000  # Add margin
+                       self.eofTimer.start(time, True)
+
+       def inhibitEof(self):
+               if self.eofState >= 1:
+                       self.eofState = -self.eofState
+                       self.eofTimer.stop()
+                       self.doEof()
+
+       def doEof(self):
                if self.seekstate == self.SEEK_STATE_EOF:
                        return
                if self.seekstate == self.SEEK_STATE_EOF:
                        return
-               if self.seekstate[1] < 0: # SEEK_STATE_BACK_*X
-                       print "end of stream while seeking back, ignoring."
+               if self.eofState == -2 or self.isStateBackward(self.seekstate):
+                       self.eofState = 0
                        return
 
                # if we are seeking, we try to end up ~1s before the end, and pause there.
                        return
 
                # if we are seeking, we try to end up ~1s before the end, and pause there.
-               if not self.seekstate in [self.SEEK_STATE_PLAY, self.SEEK_STATE_PAUSE]:
+               eofstate = self.eofState
+               seekstate = self.seekstate
+               self.eofState = 0
+               if not self.seekstate == self.SEEK_STATE_PAUSE:
                        self.setSeekState(self.SEEK_STATE_EOF)
                        self.setSeekState(self.SEEK_STATE_EOF)
-                       self.seekRelativeToEnd(-90000)
+               if eofstate == -1 or not seekstate in [self.SEEK_STATE_PLAY, self.SEEK_STATE_PAUSE]:
+                       seekable = self.getSeek()
+                       if seekable is not None:
+                               seekable.seekTo(-1)
+               if eofstate == 1 and seekstate == self.SEEK_STATE_PLAY:
+                       self.doEofInternal(True)
                else:
                else:
-                       self.setSeekState(self.SEEK_STATE_EOF)
+                       self.doEofInternal(False)
+
+       def doEofInternal(self, playing):
+               pass            # Defined in subclasses
 
        def __evSOF(self):
                self.setSeekState(self.SEEK_STATE_PLAY)
                self.doSeek(0)
 
 
        def __evSOF(self):
                self.setSeekState(self.SEEK_STATE_PLAY)
                self.doSeek(0)
 
-       def seekRelative(self, diff):
-               seekable = self.getSeek()
-               if seekable is not None:
-                       print "seekRelative: res:", seekable.seekRelative(1, diff)
-               else:
-                       print "seek failed!"
-
-       def seekRelativeToEnd(self, diff):
-               assert diff <= 0, "diff is expected to be negative!"
-
-               # might sound like an evil hack, but:
-               # if we seekRelativeToEnd(0), we expect to be at the end, which is what we want,
-               # and we don't get that by passing 0 here (it would seek to begin).
-               if diff == 0:
-                       diff = -1
-
-               # relative-to-end seeking is implemented as absolutes seeks with negative time
-               self.seekAbsolute(diff)
-
-       def seekAbsolute(self, abs):
-               seekable = self.getSeek()
-               if seekable is not None:
-                       seekable.seekTo(abs)
-
 from Screens.PVRState import PVRState, TimeshiftState
 
 class InfoBarPVRState:
 from Screens.PVRState import PVRState, TimeshiftState
 
 class InfoBarPVRState:
@@ -944,11 +1034,11 @@ class InfoBarTimeshiftState(InfoBarPVRState):
 
 class InfoBarShowMovies:
 
 
 class InfoBarShowMovies:
 
-       # i don't really like this class. 
+       # i don't really like this class.
        # it calls a not further specified "movie list" on up/down/movieList,
        # so this is not more than an action map
        def __init__(self):
        # it calls a not further specified "movie list" on up/down/movieList,
        # so this is not more than an action map
        def __init__(self):
-               self["MovieListActions"] = HelpableActionMap(self, "InfobarMovieListActions", 
+               self["MovieListActions"] = HelpableActionMap(self, "InfobarMovieListActions",
                        {
                                "movieList": (self.showMovies, _("movie list")),
                                "up": (self.showMovies, _("movie list")),
                        {
                                "movieList": (self.showMovies, _("movie list")),
                                "up": (self.showMovies, _("movie list")),
@@ -985,7 +1075,7 @@ class InfoBarShowMovies:
 
 class InfoBarTimeshift:
        def __init__(self):
 
 class InfoBarTimeshift:
        def __init__(self):
-               self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions", 
+               self["TimeshiftActions"] = HelpableActionMap(self, "InfobarTimeshiftActions",
                        {
                                "timeshiftStart": (self.startTimeshift, _("start timeshift")),  # the "yellow key"
                                "timeshiftStop": (self.stopTimeshift, _("stop timeshift"))      # currently undefined :), probably 'TV'
                        {
                                "timeshiftStart": (self.startTimeshift, _("start timeshift")),  # the "yellow key"
                                "timeshiftStop": (self.stopTimeshift, _("stop timeshift"))      # currently undefined :), probably 'TV'
@@ -999,7 +1089,7 @@ class InfoBarTimeshift:
                self.timeshift_enabled = 0
                self.timeshift_state = 0
                self.ts_rewind_timer = eTimer()
                self.timeshift_enabled = 0
                self.timeshift_state = 0
                self.ts_rewind_timer = eTimer()
-               self.ts_rewind_timer.timeout.get().append(self.rewindService)
+               self.ts_rewind_timer.callback.append(self.rewindService)
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
@@ -1076,13 +1166,15 @@ class InfoBarTimeshift:
                        print "play, ..."
                        ts.activateTimeshift() # activate timeshift will automatically pause
                        self.setSeekState(self.SEEK_STATE_PAUSE)
                        print "play, ..."
                        ts.activateTimeshift() # activate timeshift will automatically pause
                        self.setSeekState(self.SEEK_STATE_PAUSE)
-                       self.seekRelativeToEnd(-90000) # seek approx. 1 sec before end
 
                if back:
 
                if back:
+                       self.doSeek(-5) # seek some gops before end
                        self.ts_rewind_timer.start(200, 1)
                        self.ts_rewind_timer.start(200, 1)
+               else:
+                       self.doSeek(-1) # seek 1 gop before end
 
        def rewindService(self):
 
        def rewindService(self):
-               self.setSeekState(self.SEEK_STATE_BACK_16X)
+               self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
 
        # same as activateTimeshiftEnd, but pauses afterwards.
        def activateTimeshiftEndAndPause(self):
 
        # same as activateTimeshiftEnd, but pauses afterwards.
        def activateTimeshiftEndAndPause(self):
@@ -1197,7 +1289,7 @@ class InfoBarPlugins:
                return list
 
        def runPlugin(self, plugin):
                return list
 
        def runPlugin(self, plugin):
-               plugin(session = self.session)
+               plugin(session = self.session, servicelist = self.servicelist)
 
 # depends on InfoBarExtensions
 class InfoBarSleepTimer:
 
 # depends on InfoBarExtensions
 class InfoBarSleepTimer:
@@ -1228,6 +1320,9 @@ class InfoBarPiP:
        def pipShown(self):
                return self.session.pipshown
 
        def pipShown(self):
                return self.session.pipshown
 
+       def pipHandles0Action(self):
+               return self.pipShown() and config.usage.pip_zero_button.value != "standard"
+
        def getShowHideName(self):
                if self.session.pipshown:
                        return _("Disable Picture in Picture")
        def getShowHideName(self):
                if self.session.pipshown:
                        return _("Disable Picture in Picture")
@@ -1272,10 +1367,20 @@ class InfoBarPiP:
        def movePiP(self):
                self.session.open(PiPSetup, pip = self.session.pip)
 
        def movePiP(self):
                self.session.open(PiPSetup, pip = self.session.pip)
 
+       def pipDoHandle0Action(self):
+               use = config.usage.pip_zero_button.value
+               if "swap" == use:
+                       self.swapPiP()
+               elif "swapstop" == use:
+                       self.swapPiP()
+                       self.showPiP()
+               elif "stop" == use:
+                       self.showPiP()
+
 from RecordTimer import parseEvent
 
 class InfoBarInstantRecord:
 from RecordTimer import parseEvent
 
 class InfoBarInstantRecord:
-       """Instant Record - handles the instantRecord action in order to 
+       """Instant Record - handles the instantRecord action in order to
        start/stop instant records"""
        def __init__(self):
                self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
        start/stop instant records"""
        def __init__(self):
                self["InstantRecordActions"] = HelpableActionMap(self, "InfobarInstantRecord",
@@ -1283,9 +1388,13 @@ class InfoBarInstantRecord:
                                "instantRecord": (self.instantRecord, _("Instant Record...")),
                        })
                self.recording = []
                                "instantRecord": (self.instantRecord, _("Instant Record...")),
                        })
                self.recording = []
+#### DEPRECATED CODE ####
                self["BlinkingPoint"] = BlinkingPixmapConditional()
                self["BlinkingPoint"] = BlinkingPixmapConditional()
-               self["BlinkingPoint"].hide()
                self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
                self["BlinkingPoint"].setConnect(self.session.nav.RecordTimer.isRecording)
+               self["BlinkingPoint"].deprecationInfo = (
+                       "session.RecordState source, Pixmap renderer and "
+                       "ConditionalShowHide/Blink Converter", "2008-02")
+#########################
 
        def stopCurrentRecording(self, entry = -1):
                if entry is not None and entry != -1:
 
        def stopCurrentRecording(self, entry = -1):
                if entry is not None and entry != -1:
@@ -1331,7 +1440,9 @@ class InfoBarInstantRecord:
                recording.dontSave = True
                self.recording.append(recording)
 
                recording.dontSave = True
                self.recording.append(recording)
 
-               #self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
+#### DEPRECATED CODE ####
+               self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
+#########################
 
        def isInstantRecordRunning(self):
                print "self.recording:", self.recording
 
        def isInstantRecordRunning(self):
                print "self.recording:", self.recording
@@ -1352,7 +1463,7 @@ class InfoBarInstantRecord:
                        if not x in self.session.nav.RecordTimer.timer_list:
                                self.recording.remove(x)
                        elif x.dontSave and x.isRunning():
                        if not x in self.session.nav.RecordTimer.timer_list:
                                self.recording.remove(x)
                        elif x.dontSave and x.isRunning():
-                               list.append(TimerEntryComponent(x, False))
+                               list.append((x, False))
 
                if answer[1] == "changeduration":
                        if len(self.recording) == 1:
 
                if answer[1] == "changeduration":
                        if len(self.recording) == 1:
@@ -1363,7 +1474,7 @@ class InfoBarInstantRecord:
                        if len(self.recording) == 1:
                                self.setEndtime(0)
                        else:
                        if len(self.recording) == 1:
                                self.setEndtime(0)
                        else:
-                               self.session.openWithCallback(self.setEndTime, TimerSelection, list)
+                               self.session.openWithCallback(self.setEndtime, TimerSelection, list)
                elif answer[1] == "stop":
                        if len(self.recording) == 1:
                                self.stopCurrentRecording(0)
                elif answer[1] == "stop":
                        if len(self.recording) == 1:
                                self.stopCurrentRecording(0)
@@ -1434,7 +1545,7 @@ from Tools.ISO639 import LanguageCodes
 
 class InfoBarAudioSelection:
        def __init__(self):
 
 class InfoBarAudioSelection:
        def __init__(self):
-               self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions", 
+               self["AudioSelectionAction"] = HelpableActionMap(self, "InfobarAudioSelectionActions",
                        {
                                "audioSelection": (self.audioSelection, _("Audio Options...")),
                        })
                        {
                                "audioSelection": (self.audioSelection, _("Audio Options...")),
                        })
@@ -1446,7 +1557,6 @@ class InfoBarAudioSelection:
                n = audio and audio.getNumberOfTracks() or 0
                keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
                tlist = []
                n = audio and audio.getNumberOfTracks() or 0
                keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
                tlist = []
-               print "tlist:", tlist
                if n > 0:
                        self.audioChannel = service.audioChannel()
 
                if n > 0:
                        self.audioChannel = service.audioChannel()
 
@@ -1465,8 +1575,8 @@ class InfoBarAudioSelection:
 
                                tlist.append((description, x))
 
 
                                tlist.append((description, x))
 
-                       selectedAudio = tlist[0][1]
-                       tlist.sort(lambda x,y : cmp(x[0], y[0]))
+                       selectedAudio = audio.getCurrentTrack()
+                       tlist.sort(key=lambda x: x[0])
 
                        selection = 2
                        for x in tlist:
 
                        selection = 2
                        for x in tlist:
@@ -1622,20 +1732,35 @@ class InfoBarSubserviceSelection:
 
 class InfoBarAdditionalInfo:
        def __init__(self):
 
 class InfoBarAdditionalInfo:
        def __init__(self):
-               self["NimA"] = Pixmap()
-               self["NimB"] = Pixmap()
-               self["NimA_Active"] = Pixmap()
-               self["NimB_Active"] = Pixmap()
 
                self["RecordingPossible"] = Boolean(fixed=harddiskmanager.HDDCount() > 0)
                self["TimeshiftPossible"] = self["RecordingPossible"]
                self["ExtensionsAvailable"] = Boolean(fixed=1)
 
 
                self["RecordingPossible"] = Boolean(fixed=harddiskmanager.HDDCount() > 0)
                self["TimeshiftPossible"] = self["RecordingPossible"]
                self["ExtensionsAvailable"] = Boolean(fixed=1)
 
-               self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
+######### DEPRECATED CODE ##########
+               self["NimA"] = Pixmap()
+               self["NimA"].deprecationInfo = (
+                       "session.TunerInfo source, Pixmap renderer, TunerInfo/UseMask Converter"
+                       ", ValueBitTest(1) Converter and ConditionalShowHide Converter", "2008-02")
+               self["NimB"] = Pixmap()
+               self["NimB"].deprecationInfo = (
+                       "session.TunerInfo source, Pixmap renderer, TunerInfo/UseMask Converter"
+                       ", ValueBitTest(2) Converter and ConditionalShowHide Converter", "2008-02")
+               self["NimA_Active"] = Pixmap()
+               self["NimA_Active"].deprecationInfo = (
+                       "session.FrontendInfo source, Pixmap renderer, FrontendInfo/NUMBER Converter"
+                       ", ValueRange(1,1) Converter and ConditionalShowHide Converter", "2008-02")
+               self["NimB_Active"] = Pixmap()
+               self["NimB_Active"].deprecationInfo = (
+                       "session.FrontendInfo source, Pixmap renderer, FrontendInfo/NUMBER Converter"
+                       ", ValueRange(1,1) Converter and ConditionalShowHide Converter", "2008-02")
+
                res_mgr = eDVBResourceManager.getInstance()
                if res_mgr:
                        res_mgr.frontendUseMaskChanged.get().append(self.tunerUseMaskChanged)
 
                res_mgr = eDVBResourceManager.getInstance()
                if res_mgr:
                        res_mgr.frontendUseMaskChanged.get().append(self.tunerUseMaskChanged)
 
+               self.session.nav.event.append(self.gotServiceEvent) # we like to get service events
+
        def tunerUseMaskChanged(self, mask):
                if mask&1:
                        self["NimA_Active"].show()
        def tunerUseMaskChanged(self, mask):
                if mask&1:
                        self["NimA_Active"].show()
@@ -1663,6 +1788,7 @@ class InfoBarAdditionalInfo:
                service = self.session.nav.getCurrentService()
                if ev == iPlayableService.evUpdatedInfo or ev == iPlayableService.evEnd:
                        self.checkTunerState(service)
                service = self.session.nav.getCurrentService()
                if ev == iPlayableService.evUpdatedInfo or ev == iPlayableService.evEnd:
                        self.checkTunerState(service)
+####################################
 
 class InfoBarNotifications:
        def __init__(self):
 
 class InfoBarNotifications:
        def __init__(self):
@@ -1725,12 +1851,12 @@ class InfoBarCueSheetSupport:
        ENABLE_RESUME_SUPPORT = False
 
        def __init__(self, actionmap = "InfobarCueSheetActions"):
        ENABLE_RESUME_SUPPORT = False
 
        def __init__(self, actionmap = "InfobarCueSheetActions"):
-               self["CueSheetActions"] = HelpableActionMap(self, actionmap, 
+               self["CueSheetActions"] = HelpableActionMap(self, actionmap,
                        {
                                "jumpPreviousMark": (self.jumpPreviousMark, _("jump to previous marked position")),
                                "jumpNextMark": (self.jumpNextMark, _("jump to next marked position")),
                                "toggleMark": (self.toggleMark, _("toggle a cut mark at the current position"))
                        {
                                "jumpPreviousMark": (self.jumpPreviousMark, _("jump to previous marked position")),
                                "jumpNextMark": (self.jumpNextMark, _("jump to next marked position")),
                                "toggleMark": (self.toggleMark, _("toggle a cut mark at the current position"))
-                       }, prio=1) 
+                       }, prio=1)
 
                self.cut_list = [ ]
                self.is_closing = False
 
                self.cut_list = [ ]
                self.is_closing = False
@@ -1754,15 +1880,16 @@ class InfoBarCueSheetSupport:
 
                        if last is not None:
                                self.resume_point = last
 
                        if last is not None:
                                self.resume_point = last
-                               Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?"), timeout=10)
+                               if config.usage.on_movie_start.value == "ask":
+                                       Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Do you want to resume this playback?"), timeout=10)
+                               elif config.usage.on_movie_start.value == "resume":
+                                       Notifications.AddNotificationWithCallback(self.playLastCB, MessageBox, _("Resuming playback"), timeout=2, type=MessageBox.TYPE_INFO)
 
        def playLastCB(self, answer):
                if answer == True:
 
        def playLastCB(self, answer):
                if answer == True:
-                       seekable = self.__getSeekable()
-                       if seekable is not None:
-                               seekable.seekTo(self.resume_point)
+                       self.doSeek(self.resume_point)
                self.hideAfterResume()
                self.hideAfterResume()
-       
+
        def hideAfterResume(self):
                if isinstance(self, InfoBarShowHide):
                        self.hide()
        def hideAfterResume(self):
                if isinstance(self, InfoBarShowHide):
                        self.hide()
@@ -1782,37 +1909,64 @@ class InfoBarCueSheetSupport:
                        return None
                return long(r[1])
 
                        return None
                return long(r[1])
 
-       def jumpPreviousNextMark(self, cmp, alternative=None):
+       def cueGetEndCutPosition(self):
+               ret = False
+               isin = True
+               for cp in self.cut_list:
+                       if cp[1] == self.CUT_TYPE_OUT:
+                               if isin:
+                                       isin = False
+                                       ret = cp[0]
+                       elif cp[1] == self.CUT_TYPE_IN:
+                               isin = True
+               return ret
+               
+       def jumpPreviousNextMark(self, cmp, start=False):
                current_pos = self.cueGetCurrentPosition()
                if current_pos is None:
                current_pos = self.cueGetCurrentPosition()
                if current_pos is None:
-                       return
-               mark = self.getNearestCutPoint(current_pos, cmp=cmp)
+                       return False
+               mark = self.getNearestCutPoint(current_pos, cmp=cmp, start=start)
                if mark is not None:
                        pts = mark[0]
                if mark is not None:
                        pts = mark[0]
-               elif alternative is not None:
-                       pts = alternative
                else:
                else:
-                       return
+                       return False
 
 
-               seekable = self.__getSeekable()
-               if seekable is not None:
-                       seekable.seekTo(pts)
+               self.doSeek(pts)
+               return True
 
        def jumpPreviousMark(self):
                # we add 2 seconds, so if the play position is <2s after
                # the mark, the mark before will be used
 
        def jumpPreviousMark(self):
                # we add 2 seconds, so if the play position is <2s after
                # the mark, the mark before will be used
-               self.jumpPreviousNextMark(lambda x: -x-5*90000, alternative=0)
+               self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True)
 
        def jumpNextMark(self):
 
        def jumpNextMark(self):
-               self.jumpPreviousNextMark(lambda x: x)
+               if not self.jumpPreviousNextMark(lambda x: x):
+                       self.doSeek(-1)
 
 
-       def getNearestCutPoint(self, pts, cmp=abs):
+       def getNearestCutPoint(self, pts, cmp=abs, start=False):
                # can be optimized
                # can be optimized
+               beforecut = False
                nearest = None
                nearest = None
+               if start:
+                       beforecut = True
+                       bestdiff = cmp(0 - pts)
+                       if bestdiff >= 0:
+                               nearest = [0, False]
                for cp in self.cut_list:
                for cp in self.cut_list:
-                       diff = cmp(cp[0] - pts)
-                       if cp[1] == self.CUT_TYPE_MARK and diff >= 0 and (nearest is None or cmp(nearest[0] - pts) > diff):
-                               nearest = cp
+                       if beforecut and cp[1] in [self.CUT_TYPE_IN, self.CUT_TYPE_OUT]:
+                               beforecut = False
+                               if cp[1] == self.CUT_TYPE_IN:  # Start is here, disregard previous marks
+                                       diff = cmp(cp[0] - pts)
+                                       if diff >= 0:
+                                               nearest = cp
+                                               bestdiff = diff
+                                       else:
+                                               nearest = None
+                       if cp[1] in [self.CUT_TYPE_MARK, self.CUT_TYPE_LAST]:
+                               diff = cmp(cp[0] - pts)
+                               if diff >= 0 and (nearest is None or bestdiff > diff):
+                                       nearest = cp
+                                       bestdiff = diff
                return nearest
 
        def toggleMark(self, onlyremove=False, onlyadd=False, tolerance=5*90000, onlyreturn=False):
                return nearest
 
        def toggleMark(self, onlyremove=False, onlyadd=False, tolerance=5*90000, onlyreturn=False):
@@ -1874,18 +2028,28 @@ class InfoBarCueSheetSupport:
 class InfoBarSummary(Screen):
        skin = """
        <screen position="0,0" size="132,64">
 class InfoBarSummary(Screen):
        skin = """
        <screen position="0,0" size="132,64">
-               <widget source="CurrentTime" render="Label" position="56,46" size="82,18" font="Regular;16" >
+               <widget source="global.CurrentTime" render="Label" position="62,46" size="82,18" font="Regular;16" >
                        <convert type="ClockToText">WithSeconds</convert>
                </widget>
                        <convert type="ClockToText">WithSeconds</convert>
                </widget>
-               <widget source="CurrentService" render="Label" position="6,4" size="120,42" font="Regular;18" >
+               <widget source="session.RecordState" render="FixedLabel" text=" " position="62,46" size="82,18" zPosition="1" >
+                       <convert type="ConfigEntryTest">config.usage.blinking_display_clock_during_recording,True,CheckSourceBoolean</convert>
+                       <convert type="ConditionalShowHide">Blink</convert>
+               </widget>
+               <widget source="session.CurrentService" render="Label" position="6,4" size="120,42" font="Regular;18" >
                        <convert type="ServiceName">Name</convert>
                </widget>
                        <convert type="ServiceName">Name</convert>
                </widget>
+               <widget source="session.Event_Now" render="Progress" position="6,46" size="46,18" borderWidth="1" >
+                       <convert type="EventTime">Progress</convert>
+               </widget>
        </screen>"""
 
        </screen>"""
 
+# for picon:  (path="piconlcd" will use LCD picons)
+#              <widget source="session.CurrentService" render="Picon" position="6,0" size="120,64" path="piconlcd" >
+#                      <convert type="ServiceName">Reference</convert>
+#              </widget>
+
        def __init__(self, session, parent):
        def __init__(self, session, parent):
-               Screen.__init__(self, session)
-               self["CurrentService"] = CurrentService(self.session.nav)
-               self["CurrentTime"] = Clock()
+               Screen.__init__(self, session, parent = parent)
 
 class InfoBarSummarySupport:
        def __init__(self):
 
 class InfoBarSummarySupport:
        def __init__(self):
@@ -1894,6 +2058,34 @@ class InfoBarSummarySupport:
        def createSummary(self):
                return InfoBarSummary
 
        def createSummary(self):
                return InfoBarSummary
 
+class InfoBarMoviePlayerSummary(Screen):
+       skin = """
+       <screen position="0,0" size="132,64">
+               <widget source="global.CurrentTime" render="Label" position="62,46" size="64,18" font="Regular;16" halign="right" >
+                       <convert type="ClockToText">WithSeconds</convert>
+               </widget>
+               <widget source="session.RecordState" render="FixedLabel" text=" " position="62,46" size="64,18" zPosition="1" >
+                       <convert type="ConfigEntryTest">config.usage.blinking_display_clock_during_recording,True,CheckSourceBoolean</convert>
+                       <convert type="ConditionalShowHide">Blink</convert>
+               </widget>
+               <widget source="session.CurrentService" render="Label" position="6,4" size="120,42" font="Regular;18" >
+                       <convert type="ServiceName">Name</convert>
+               </widget>
+               <widget source="session.CurrentService" render="Progress" position="6,46" size="56,18" borderWidth="1" >
+                       <convert type="ServicePosition">Position</convert>
+               </widget>
+       </screen>"""
+
+       def __init__(self, session, parent):
+               Screen.__init__(self, session)
+
+class InfoBarMoviePlayerSummarySupport:
+       def __init__(self):
+               pass
+
+       def createSummary(self):
+               return InfoBarMoviePlayerSummary
+
 class InfoBarTeletextPlugin:
        def __init__(self):
                self.teletext_plugin = None
 class InfoBarTeletextPlugin:
        def __init__(self):
                self.teletext_plugin = None
@@ -1996,7 +2188,8 @@ class InfoBarServiceErrorPopupSupport:
                        eDVBServicePMTHandler.eventNewProgramInfo: None,
                        eDVBServicePMTHandler.eventTuned: None,
                        eDVBServicePMTHandler.eventSOF: None,
                        eDVBServicePMTHandler.eventNewProgramInfo: None,
                        eDVBServicePMTHandler.eventTuned: None,
                        eDVBServicePMTHandler.eventSOF: None,
-                       eDVBServicePMTHandler.eventEOF: None
+                       eDVBServicePMTHandler.eventEOF: None,
+                       eDVBServicePMTHandler.eventMisconfiguration: _("Service unavailable!\nCheck tuner configuration!"),
                }
 
                error = errors.get(error) #this returns None when the key not exist in the dict
                }
 
                error = errors.get(error) #this returns None when the key not exist in the dict