use special refresh rate selection for DVI ports
[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.on_hotplug.append(self.createConfig)
61
62                 self.readAvailableModes()
63                 self.readPreferredModes()
64
65                 # until we have the hotplug poll socket
66 #               self.timer = eTimer()
67 #               self.timer.timeout.get().append(self.readPreferredModes)
68 #               self.timer.start(1000)
69
70         def readAvailableModes(self):
71                 try:
72                         modes = open("/proc/stb/video/videomode_choices").read()[:-1]
73                 except IOError:
74                         print "couldn't read available videomodes."
75                         self.modes_available = [ ]
76                         return
77                 self.modes_available = modes.split(' ')
78
79         def readPreferredModes(self):
80                 try:
81                         modes = open("/proc/stb/video/videomode_preferred").read()[:-1]
82                         self.modes_preferred = modes.split(' ')
83                 except IOError:
84                         print "reading preferred modes failed, using all modes"
85                         self.modes_preferred = self.modes_available
86
87                 if self.modes_preferred != self.last_modes_preferred:
88                         self.last_modes_preferred = self.modes_preferred
89                         print "hotplug on dvi"
90                         self.on_hotplug("DVI") # must be DVI
91
92         # check if a high-level mode with a given rate is available.
93         def isModeAvailable(self, port, mode, rate):
94                 rate = self.rates[mode][rate]
95                 for mode in rate.values():
96                         # DVI modes must be in "modes_preferred"
97 #                       if port == "DVI":
98 #                               if mode not in self.modes_preferred and not config.av.edid_override.value:
99 #                                       print "no, not preferred"
100 #                                       return False
101                         if mode not in self.modes_available:
102                                 return False
103                 return True
104
105         def setMode(self, port, mode, rate, force = None):
106                 # we can ignore "port"
107                 self.current_mode = mode
108                 modes = self.rates[mode][rate]
109
110                 mode_50 = modes.get(50)
111                 mode_60 = modes.get(60)
112                 if mode_50 is None or force == 60:
113                         mode_50 = mode_60
114                 if mode_60 is None or force == 50: 
115                         mode_60 = mode_50
116
117                 try:
118                         open("/proc/stb/video/videomode_60hz", "w").write(mode_50)
119                         open("/proc/stb/video/videomode_50hz", "w").write(mode_60)
120                 except IOError:
121                         try:
122                                 # fallback if no possibility to setup 50/60 hz mode
123                                 open("/proc/stb/video/videomode", "w").write(mode_50)
124                         except IOError:
125                                 print "setting videomode failed."
126
127         def isPortAvailable(self, port):
128                 # fixme
129                 return True
130
131         def isPortUsed(self, port):
132                 if port == "DVI":
133                         self.readPreferredModes()
134                         return len(self.modes_preferred) != 0
135                 else:
136                         return True
137
138         def getPortList(self):
139                 return [port for port in self.modes if self.isPortAvailable(port)]
140
141         # get a list with all modes, with all rates, for a given port.
142         def getModeList(self, port):
143                 res = [ ]
144                 for mode in self.modes[port]:
145                         # list all rates which are completely valid
146                         rates = [rate for rate in self.rates[mode] if self.isModeAvailable(port, mode, rate)]
147
148                         # if at least one rate is ok, add this mode
149                         if len(rates):
150                                 res.append( (mode, rates) )
151                 return res
152
153         def createConfig(self, *args):
154                 # create list of output ports
155                 portlist = self.getPortList()
156
157                 # create list of available modes
158                 config.av.videoport = ConfigSelection(choices = [(port, _(port)) for port in portlist])
159                 config.av.videomode = ConfigSubDict()
160                 config.av.videorate = ConfigSubDict()
161
162                 for port in portlist:
163                         modes = self.getModeList(port)
164                         if len(modes):
165                                 config.av.videomode[port] = ConfigSelection(choices = [mode for (mode, rates) in modes])
166                         for (mode, rates) in modes:
167                                 config.av.videorate[mode] = ConfigSelection(choices = rates)
168
169 config.av.edid_override = ConfigYesNo(default = False)
170 video_hw = VideoHardware()