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