1 from Screens.Screen import Screen
2 from Plugins.Plugin import PluginDescriptor
4 from enigma import eTimer
6 from Components.ActionMap import ActionMap
7 from Components.Label import Label
8 from Components.Pixmap import Pixmap
9 from Screens.MessageBox import MessageBox
10 from Components.ConfigList import ConfigListScreen
11 from Components.config import getConfigListEntry, config, ConfigNothing, ConfigSelection, ConfigSubDict
13 from Tools.CList import CList
15 # The "VideoHardware" is the interface to /proc/stb/video.
16 # It generates hotplug events, and gives you the list of
17 # available and preferred modes, as well as handling the currently
18 # selected mode. No other strict checking is done.
20 rates = { } # high-level, use selectable modes.
22 modes = { } # a list of (high-level) modes for a certain port.
24 rates["PAL"] = { "50Hz": { 50: "pal", 60: "pal"},
25 "60Hz": { 50: "pal60", 60: "pal60"},
26 "multi": { 50: "pal", 60: "pal60"} }
27 rates["NTSC"] = { "60Hz": { 50: "ntsc", 60: "ntsc"} }
28 rates["Multi"] = { "multi": { 50: "pal", 60: "ntsc"} }
29 rates["720p"] = { "50Hz": { 50: "720p50", 60: "720p50"},
30 "60Hz": { 50: "720p", 60: "720p"},
31 "multi": { 50: "720p50", 60: "720p"} }
32 rates["1080i"] = { "50Hz": { 50: "1080i50", 60: "1080i50"},
33 "60Hz": { 50: "1080i", 60: "1080i"},
34 "multi": { 50: "1080i50", 60: "1080i"} }
36 "1024x768": { 60: "1024x768"}, # not possible on DM7025
37 "800x600" : { 60: "800x600"}, # also not possible
38 "720x480" : { 60: "720x480"},
39 "720x576" : { 60: "720x576"},
40 "1280x720": { 60: "1280x720"},
41 "1280x720 multi": { 50: "1280x720_50", 60: "1280x720"},
42 "1920x1080": { 60: "1920x1080"},
43 "1920x1080 multi": { 50: "1920x1080", 60: "1920x1080_50"},
44 "1280x1024" : { 60: "1280x1024"},
45 "640x480" : { 60: "640x480"}
48 modes["Scart"] = ["PAL", "NTSC", "Multi"]
49 modes["YPrPb"] = ["720p", "1080i"]
50 modes["DVI"] = ["720p", "1080i", "PC"]
53 self.last_modes_preferred = [ ]
54 self.on_hotplug = CList()
56 self.on_hotplug.append(self.createConfig)
57 self.ignore_preferred = False # "edid override"
59 self.readAvailableModes()
60 self.readPreferredModes()
62 # until we have the hotplug poll socket
64 self.timer.timeout.get().append(self.readAvailableModes)
65 self.timer.start(1000)
67 def readAvailableModes(self):
69 modes = open("/proc/stb/video/videomode_choices").read()[:-1]
71 print "couldn't read available videomodes."
72 self.modes_available = [ ]
74 self.modes_available = modes.split(' ')
76 def readPreferredModes(self):
78 modes = open("/proc/stb/video/videomode_preferred").read()[:-1]
79 self.modes_preferred = modes.split(' ')
81 print "reading preferred modes failed, using all modes"
82 self.modes_preferred = self.modes_available
84 if self.modes_preferred != self.last_modes_preferred:
85 self.last_modes_preferred = self.modes_preferred
86 self.on_hotplug("DVI") # must be DVI
88 # check if a high-level mode with a given rate is available.
89 def isModeAvailable(self, port, mode, rate):
90 rate = self.rates[mode][rate]
91 for mode in rate.values():
92 # DVI modes must be in "modes_preferred"
94 if mode not in self.modes_preferred and not self.ignore_preferred:
96 if mode not in self.modes_available:
100 def setMode(self, port, mode, rate):
101 # we can ignore "port"
102 self.current_mode = mode
103 modes = self.rates[mode][rate]
105 mode_50 = modes.get(50)
106 mode_60 = modes.get(60)
113 open("/proc/stb/video/videomode_60hz", "w").write(mode_50)
114 open("/proc/stb/video/videomode_50hz", "w").write(mode_60)
117 # fallback if no possibility to setup 50/60 hz mode
118 open("/proc/stb/video/videomode", "w").write(mode_50)
120 print "setting videomode failed."
122 def isPortAvailable(self, port):
126 def getPortList(self):
127 return [port for port in self.modes if self.isPortAvailable(port)]
129 # get a list with all modes, with all rates, for a given port.
130 def getModeList(self, port):
132 for mode in self.modes[port]:
133 # list all rates which are completely valid
134 rates = [rate for rate in self.rates[mode] if self.isModeAvailable(port, mode, rate)]
136 # if at least one rate is ok, add this mode
138 res.append( (mode, rates) )
141 def createConfig(self, *args):
142 # create list of output ports
143 portlist = self.getPortList()
145 # create list of available modes
146 config.av.videoport = ConfigSelection(choices = [(port, _(port)) for port in portlist])
147 config.av.videomode = ConfigSubDict()
148 config.av.videorate = ConfigSubDict()
150 for port in portlist:
151 modes = self.getModeList(port)
153 config.av.videomode[port] = ConfigSelection(choices = [mode for (mode, rates) in modes])
154 for (mode, rates) in modes:
155 config.av.videorate[mode] = ConfigSelection(choices = rates)
157 video_hw = VideoHardware()
159 class VideoSetup(Screen, ConfigListScreen):
160 def __init__(self, session, hw):
161 Screen.__init__(self, session)
162 self.skinName = "Setup"
165 # handle hotplug by re-creating setup
166 self.onShow.append(self.startHotplug)
167 self.onHide.append(self.stopHotplug)
170 ConfigListScreen.__init__(self, self.list)
172 self["actions"] = ActionMap(["SetupActions"],
174 "cancel": self.keyCancel,
178 self["title"] = Label(_("Video-Setup"))
180 self["oktext"] = Label(_("OK"))
181 self["canceltext"] = Label(_("Cancel"))
182 self["ok"] = Pixmap()
183 self["cancel"] = Pixmap()
186 self.grabLastGoodMode()
188 def startHotplug(self):
189 self.hw.on_hotplug.append(self.createSetup)
191 def stopHotplug(self):
192 self.hw.on_hotplug.remove(self.createSetup)
194 def createSetup(self):
196 self.list.append(getConfigListEntry(_("Output Type"), config.av.videoport))
198 # if we have modes for this port:
199 if config.av.videoport.value in config.av.videomode:
200 # add mode- and rate-selection:
201 self.list.append(getConfigListEntry(_("Mode"), config.av.videomode[config.av.videoport.value]))
202 self.list.append(getConfigListEntry(_("Rate"), config.av.videorate[config.av.videomode[config.av.videoport.value].value]))
204 self["config"].list = self.list
205 self["config"].l.setList(self.list)
208 ConfigListScreen.keyLeft(self)
212 ConfigListScreen.keyRight(self)
215 def confirm(self, confirmed):
217 self.hw.setMode(*self.last_good)
221 def grabLastGoodMode(self):
222 port = config.av.videoport.value
223 mode = config.av.videomode[port].value
224 rate = config.av.videorate[mode].value
225 self.last_good = (port, mode, rate)
228 port = config.av.videoport.value
229 mode = config.av.videomode[port].value
230 rate = config.av.videorate[mode].value
231 if (port, mode, rate) != self.last_good or True:
232 self.hw.setMode(port, mode, rate)
233 self.session.openWithCallback(self.confirm, MessageBox, "Is this videomode ok?", MessageBox.TYPE_YESNO, timeout = 5, default = False)
237 #class VideomodeHotplug:
238 # def __init__(self, hw):
240 # self.hw.on_hotplug.append(self.hotplug)
242 # def hotplug(self, what):
243 # print "hotplug detected on port '%s'" % (what)
248 #def startHotplug(self):
250 # hotplug = VideomodeHotplug()
253 #def stopHotplug(self):
258 #def autostart(reason, session = None, **kwargs):
259 # if session is not None:
260 # global my_global_session
261 # my_global_session = session
269 def videoSetupMain(session, **kwargs):
270 session.open(VideoSetup, video_hw)
272 def startSetup(menuid):
273 if menuid != "system":
276 return [(_("Video Setup"), videoSetupMain, "video_setup", None)]
278 def Plugins(**kwargs):
280 # PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart),
281 PluginDescriptor(name=_("Video Setup"), description=_("Advanced Video Setup"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup)