f3e3c07a6bd171d73e95ee61628528d50670d6df
[enigma2.git] / 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.callback.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                 print "setMode - port:", port, "mode:", mode, "rate:", rate
109                 # we can ignore "port"
110                 self.current_mode = mode
111                 modes = self.rates[mode][rate]
112
113                 mode_50 = modes.get(50)
114                 mode_60 = modes.get(60)
115                 if mode_50 is None or force == 60:
116                         mode_50 = mode_60
117                 if mode_60 is None or force == 50: 
118                         mode_60 = mode_50
119
120                 try:
121                         open("/proc/stb/video/videomode_60hz", "w").write(mode_50)
122                         open("/proc/stb/video/videomode_50hz", "w").write(mode_60)
123                 except IOError:
124                         try:
125                                 # fallback if no possibility to setup 50/60 hz mode
126                                 open("/proc/stb/video/videomode", "w").write(mode_50)
127                         except IOError:
128                                 print "setting videomode failed."
129
130                 try:
131                         open("/etc/videomode", "w").write(mode_50) # use 50Hz mode (if available) for booting
132                 except IOError:
133                         print "writing initial videomode to /etc/videomode failed."
134
135                 # workaround: this should not be set here.
136                 if port != "Scart":
137                         open("/proc/stb/video/aspect", "w").write("any")
138                         open("/proc/stb/video/policy", "w").write("panscan")
139
140         def saveMode(self, port, mode, rate):
141                 config.av.videoport.value = port
142                 config.av.videomode[port].value = mode
143                 config.av.videorate[mode].value = rate
144
145         def isPortAvailable(self, port):
146                 # fixme
147                 return True
148
149         def isPortUsed(self, port):
150                 if port == "DVI":
151                         self.readPreferredModes()
152                         return len(self.modes_preferred) != 0
153                 else:
154                         return True
155
156         def getPortList(self):
157                 return [port for port in self.modes if self.isPortAvailable(port)]
158
159         # get a list with all modes, with all rates, for a given port.
160         def getModeList(self, port):
161                 print "getModeList for port", port
162                 res = [ ]
163                 for mode in self.modes[port]:
164                         # list all rates which are completely valid
165                         rates = [rate for rate in self.rates[mode] if self.isModeAvailable(port, mode, rate)]
166
167                         # if at least one rate is ok, add this mode
168                         if len(rates):
169                                 res.append( (mode, rates) )
170                 return res
171
172         def createConfig(self, *args):
173                 # create list of output ports
174                 portlist = self.getPortList()
175
176                 # create list of available modes
177                 config.av.videoport = ConfigSelection(choices = [(port, _(port)) for port in portlist])
178                 config.av.videomode = ConfigSubDict()
179                 config.av.videorate = ConfigSubDict()
180
181                 for port in portlist:
182                         modes = self.getModeList(port)
183                         if len(modes):
184                                 config.av.videomode[port] = ConfigSelection(choices = [mode for (mode, rates) in modes])
185                         for (mode, rates) in modes:
186                                 config.av.videorate[mode] = ConfigSelection(choices = rates)
187
188         def setConfiguredMode(self):
189                 port = config.av.videoport.value
190                 if port not in config.av.videomode:
191                         print "current port not available, not setting videomode"
192                         return
193
194                 mode = config.av.videomode[port].value
195
196                 if mode not in config.av.videorate:
197                         print "current mode not available, not setting videomode"
198                         return
199
200                 rate = config.av.videorate[mode].value
201                 self.setMode(port, mode, rate)
202                 
203
204 config.av.edid_override = ConfigYesNo(default = False)
205 video_hw = VideoHardware()
206 video_hw.setConfiguredMode()