set video mode on bootup, set /etc/videomode for bootup script
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / Videomode / VideoHardware.py
1 from Screens.Screen import Screen
2 from Plugins.Plugin import PluginDescriptor
3
4 from enigma import eTimer
5
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 Screens.Setup import SetupSummary
11 from Components.ConfigList import ConfigListScreen
12 from Components.config import getConfigListEntry, config, ConfigSelection, ConfigSubDict, ConfigYesNo
13
14 from Tools.CList import CList
15
16 # The "VideoHardware" is the interface to /proc/stb/video.
17 # It generates hotplug events, and gives you the list of 
18 # available and preferred modes, as well as handling the currently
19 # selected mode. No other strict checking is done.
20 class VideoHardware:
21         rates = { } # high-level, use selectable modes.
22
23         modes = { }  # a list of (high-level) modes for a certain port.
24
25         rates["PAL"] =                  { "50Hz":               { 50: "pal", 60: "pal"},
26                                                                                                 "60Hz":         { 50: "pal60", 60: "pal60"},
27                                                                                                 "multi":        { 50: "pal", 60: "pal60"} }
28         rates["NTSC"] =                 { "60Hz":       { 50: "ntsc", 60: "ntsc"} }
29         rates["Multi"] =                { "multi":      { 50: "pal", 60: "ntsc"} }
30         rates["720p"] =                 {       "50Hz":         { 50: "720p50", 60: "720p50"},
31                                                                                                 "60Hz":         { 50: "720p", 60: "720p"},
32                                                                                                 "multi":        { 50: "720p50", 60: "720p"} }
33         rates["1080i"] =                { "50Hz":               { 50: "1080i50", 60: "1080i50"},
34                                                                                                 "60Hz":         { 50: "1080i", 60: "1080i"},
35                                                                                                 "multi":        { 50: "1080i50", 60: "1080i"} }
36         rates["PC"] = { 
37                 "1024x768": { 60: "1024x768"}, # not possible on DM7025
38                 "800x600" : { 60: "800x600"},  # also not possible
39                 "720x480" : { 60: "720x480"},
40                 "720x576" : { 60: "720x576"},
41                 "1280x720": { 60: "1280x720"},
42                 "1280x720 multi": { 50: "1280x720_50", 60: "1280x720"},
43                 "1920x1080": { 60: "1920x1080"},
44                 "1920x1080 multi": { 50: "1920x1080", 60: "1920x1080_50"},
45                 "1280x1024" : { 60: "1280x1024"},
46                 "1366x768" : { 60: "1366x768"},
47                 "1366x768 multi" : { 50: "1366x768", 60: "1366x768_50"},
48                 "1280x768": { 60: "1280x768"},
49                 "640x480" : { 60: "640x480"} 
50         }
51
52         modes["Scart"] = ["PAL", "NTSC", "Multi"]
53         modes["YPbPr"] = ["720p", "1080i"]
54         modes["DVI"] = ["720p", "1080i", "PC"]
55
56         def __init__(self):
57                 self.last_modes_preferred =  [ ]
58                 self.on_hotplug = CList()
59
60                 self.readAvailableModes()
61
62                 self.createConfig()
63 #               self.on_hotplug.append(self.createConfig)
64
65                 self.readPreferredModes()
66
67                 # until we have the hotplug poll socket
68 #               self.timer = eTimer()
69 #               self.timer.timeout.get().append(self.readPreferredModes)
70 #               self.timer.start(1000)
71
72         def readAvailableModes(self):
73                 try:
74                         modes = open("/proc/stb/video/videomode_choices").read()[:-1]
75                 except IOError:
76                         print "couldn't read available videomodes."
77                         self.modes_available = [ ]
78                         return
79                 self.modes_available = modes.split(' ')
80
81         def readPreferredModes(self):
82                 try:
83                         modes = open("/proc/stb/video/videomode_preferred").read()[:-1]
84                         self.modes_preferred = modes.split(' ')
85                 except IOError:
86                         print "reading preferred modes failed, using all modes"
87                         self.modes_preferred = self.modes_available
88
89                 if self.modes_preferred != self.last_modes_preferred:
90                         self.last_modes_preferred = self.modes_preferred
91                         print "hotplug on dvi"
92                         self.on_hotplug("DVI") # must be DVI
93
94         # check if a high-level mode with a given rate is available.
95         def isModeAvailable(self, port, mode, rate):
96                 rate = self.rates[mode][rate]
97                 for mode in rate.values():
98                         # DVI modes must be in "modes_preferred"
99 #                       if port == "DVI":
100 #                               if mode not in self.modes_preferred and not config.av.edid_override.value:
101 #                                       print "no, not preferred"
102 #                                       return False
103                         if mode not in self.modes_available:
104                                 return False
105                 return True
106
107         def setMode(self, port, mode, rate, force = None):
108                 # we can ignore "port"
109                 self.current_mode = mode
110                 modes = self.rates[mode][rate]
111
112                 mode_50 = modes.get(50)
113                 mode_60 = modes.get(60)
114                 if mode_50 is None or force == 60:
115                         mode_50 = mode_60
116                 if mode_60 is None or force == 50: 
117                         mode_60 = mode_50
118
119                 try:
120                         open("/proc/stb/video/videomode_60hz", "w").write(mode_50)
121                         open("/proc/stb/video/videomode_50hz", "w").write(mode_60)
122                 except IOError:
123                         try:
124                                 # fallback if no possibility to setup 50/60 hz mode
125                                 open("/proc/stb/video/videomode", "w").write(mode_50)
126                         except IOError:
127                                 print "setting videomode failed."
128
129                 try:
130                         open("/etc/videomode", "w").write(mode_50) # use 50Hz mode (if available) for booting
131                 except IOError:
132                         print "writing initial videomode to /etc/videomode failed."
133
134         def isPortAvailable(self, port):
135                 # fixme
136                 return True
137
138         def isPortUsed(self, port):
139                 if port == "DVI":
140                         self.readPreferredModes()
141                         return len(self.modes_preferred) != 0
142                 else:
143                         return True
144
145         def getPortList(self):
146                 return [port for port in self.modes if self.isPortAvailable(port)]
147
148         # get a list with all modes, with all rates, for a given port.
149         def getModeList(self, port):
150                 res = [ ]
151                 for mode in self.modes[port]:
152                         # list all rates which are completely valid
153                         rates = [rate for rate in self.rates[mode] if self.isModeAvailable(port, mode, rate)]
154
155                         # if at least one rate is ok, add this mode
156                         if len(rates):
157                                 res.append( (mode, rates) )
158                 return res
159
160         def createConfig(self, *args):
161                 # create list of output ports
162                 portlist = self.getPortList()
163
164                 # create list of available modes
165                 config.av.videoport = ConfigSelection(choices = [(port, _(port)) for port in portlist])
166                 config.av.videomode = ConfigSubDict()
167                 config.av.videorate = ConfigSubDict()
168
169                 for port in portlist:
170                         modes = self.getModeList(port)
171                         if len(modes):
172                                 config.av.videomode[port] = ConfigSelection(choices = [mode for (mode, rates) in modes])
173                         for (mode, rates) in modes:
174                                 config.av.videorate[mode] = ConfigSelection(choices = rates)
175
176         def setConfiguredMode(self):
177                 port = config.av.videoport.value
178                 if port not in config.av.videomode:
179                         print "current port not available, not setting videomode"
180                         return
181
182                 mode = config.av.videomode[port].value
183
184                 if mode not in config.av.videorate:
185                         print "current mode not available, not setting videomode"
186                         return
187
188                 rate = config.av.videorate[mode].value
189                 self.setMode(port, mode, rate)
190
191 config.av.edid_override = ConfigYesNo(default = False)
192 video_hw = VideoHardware()
193 video_hw.setConfiguredMode()