[TeleText] added new config item "region" to use the proper font.
[enigma2-plugins.git] / teletext / src / plugin.py
1 from __init__ import _, _debug , _log
2
3 from enigma import iServiceInformation, iPlayableService, eSocketNotifier, getDesktop, eConsoleAppContainer, ePoint, eSize
4
5 from Screens.HelpMenu import HelpMenu
6 from Screens.MessageBox import MessageBox
7 from Screens.Screen import Screen
8 from Components.ActionMap import ActionMap, NumberActionMap
9 from Components.ConfigList import ConfigListScreen
10 from Components.Label import Label
11 from Components.Pixmap import Pixmap
12 from Components.ServiceEventTracker import ServiceEventTracker
13 from Components.config import config, configfile, getConfigListEntry, ConfigSubsection, ConfigEnableDisable, ConfigSlider, ConfigSelection, ConfigSequence
14 from GlobalActions import globalActionMap
15 from Plugins.Plugin import PluginDescriptor
16 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
17
18 import array
19 import socket
20 import struct
21
22 from os import unlink
23 from select import POLLIN, POLLPRI, POLLHUP, POLLERR
24
25 from enigma import Teletext as TeletextInterface
26
27 CMD_CTL_CACHE=1
28 CMD_SHOW_PAGE=2
29 CMD_PAGE_NEXT=3
30 CMD_PAGE_PREV=4
31 CMD_SUBP_NEXT=5
32 CMD_SUBP_PREV=6
33 CMD_COLKEY_RD=7
34 CMD_COLKEY_GN=8
35 CMD_COLKEY_YE=9
36 CMD_COLKEY_BL=10
37 CMD_CATCHPAGE=11
38 CMD_CONCEALED=12
39 CMD_SET_BRIGH=13
40 CMD_SET_CONTR=14
41 CMD_RQ_UPDATE=15
42 CMD_RZAP_PAGE=16
43 CMD_OPAQUE=17
44 CMD_TRANSPARENCY=18
45 CMD_FLOF=19
46 CMD_PAGEINPUT=20
47 CMD_EDGE_CUT=21
48 CMD_TEXTLEVEL=22
49 CMD_REGION=23
50 CMD_CLOSE_DMN=99
51
52 SPLIT_MODE_PAT = "pat"
53 SPLIT_MODE_TAP = "tap"
54 SPLIT_MODE_TIP = "tip"
55 splittingModeList = [ (SPLIT_MODE_PAT, _("picture and teletext")), (SPLIT_MODE_TAP, _("teletext and picture")), (SPLIT_MODE_TIP, _("teletext in picture")) ]
56 textlevelModeList = [ ("0", "1.0"), ("1", "1.5"), ("2", "2.5"), ("3", "3.5") ]
57 regionList = [ ("0", _("Western and Central Europe")), ("8", _("Eastern Europe")), ("16", _("Western Europe and Turkey")), ("24", _("Central and Southeast Europe")), ("32", _("Cyrillic")), ("48", _("...")), ("64", _("Arabic")), ("80", _("...")) ]
58
59 HELP_TEXT_POS          = _("Enter values (left, top, right, bottom) or press TEXT to move and resize the teletext graphically.")
60 HELP_TEXT_TIP_POS      = _("Enter values (left, top, right, bottom) or press TEXT to move and resize the teletext graphically.")
61 HELP_TEXT_SPLITTING    = _("Select splitting mode.")
62 HELP_TEXT_BRIGHTNESS   = _("Select brightness.")
63 HELP_TEXT_CONTRAST     = _("Select contrast.")
64 HELP_TEXT_TRANSPARENCY = _("Select transparency.")
65 HELP_TEXT_EDGE_CUT     = _("Display first and last row.")
66 HELP_TEXT_MESSAGES     = _("Show message if no teletext available or exit silently.")
67 HELP_TEXT_DEBUG        = _("Print debug messages to /tmp/dbttcp.log.")
68 HELP_TEXT_TEXTLEVEL    = _("Select teletext version to use.")
69 HELP_TEXT_REGION       = _("Select your region to use the proper font.")
70
71 dsk_size   = getDesktop(0).size()
72 dsk_width  = dsk_size.width()
73 dsk_height = dsk_size.height()  
74
75 MIN_W = 400
76 MIN_H = 300
77
78 NAV_MODE_TEXT          = 0
79 NAV_MODE_SIZE_TEXT     = 1
80 NAV_MODE_SIZE_TIP_TEXT = 2
81
82 config.plugins.TeleText = ConfigSubsection()
83 config.plugins.TeleText.brightness   = ConfigSlider(default=8,  increment=1, limits=(0,15))
84 config.plugins.TeleText.contrast     = ConfigSlider(default=12, increment=1, limits=(0,15))
85 config.plugins.TeleText.transparency = ConfigSlider(default=8,  increment=1, limits=(0,15))
86 config.plugins.TeleText.messages = ConfigEnableDisable(default=True)
87 config.plugins.TeleText.edge_cut = ConfigEnableDisable(default=False)
88 config.plugins.TeleText.splitting_mode = ConfigSelection(splittingModeList, default=SPLIT_MODE_PAT)
89 config.plugins.TeleText.textlevel      = ConfigSelection(textlevelModeList, default="2")
90 config.plugins.TeleText.region   = ConfigSelection(regionList, default="16")
91 config.plugins.TeleText.debug    = ConfigEnableDisable(default=False)
92 config.plugins.TeleText.pos      = ConfigSequence(default=[0, 0, dsk_width, dsk_height], seperator = ",", limits = [(0,dsk_width>>3),(0,dsk_height>>3),(dsk_width-(dsk_width>>3),dsk_width),(dsk_height-(dsk_height>>3),dsk_height)])
93 config.plugins.TeleText.tip_pos  = ConfigSequence(default=[(dsk_width>>1)+(dsk_width>>2), (dsk_height>>1)+(dsk_height>>2), dsk_width, dsk_height], seperator = ",", limits = [(0,dsk_width-MIN_W),(0,dsk_height-MIN_H),(MIN_W,dsk_width),(MIN_H,dsk_height)])
94 # state
95 config.plugins.TeleText.textOnly = ConfigEnableDisable(default=True)
96 config.plugins.TeleText.opaque   = ConfigEnableDisable(default=False)
97
98 # global functions
99
100 def log(message):
101   _log(message)
102   if config.plugins.TeleText.debug.value:
103     _debug(message)
104
105 class TeleText(Screen):
106
107   isDM7025    = False
108   pageInput   = 0
109   hasText     = False
110   catchPage   = False
111   flofValue   = True
112   infoValue   = False
113   edgeValue   = False
114   opaqueValue = False
115   nav_mode    = NAV_MODE_TEXT
116
117   onChangedEntry = [ ]  
118
119   def __init__(self, session):
120     TeleText.skin = """<screen position="0,0" size="%d,%d" title="TeleText" flags="wfNoBorder"/>""" % (dsk_width, dsk_height)
121     Screen.__init__(self, session)
122
123     self.__event_tracker = ServiceEventTracker(screen = self, eventmap={
124       iPlayableService.evStart : self.serviceStarted,
125       iPlayableService.evEnd : self.serviceStopped,
126       iPlayableService.evUpdatedInfo : self.serviceInfoChanged,
127     })
128
129     self["actions"] = NumberActionMap(["OkCancelActions", "TeleTextActions"],
130     {
131       "ok" : self.okPressed,
132       "cancel" : self.cancelPressed,
133       "1" : self.keyNumberGlobal,
134       "2" : self.keyNumberGlobal,
135       "3" : self.keyNumberGlobal,
136       "4" : self.keyNumberGlobal,
137       "5" : self.keyNumberGlobal,
138       "6" : self.keyNumberGlobal,
139       "7" : self.keyNumberGlobal,
140       "8" : self.keyNumberGlobal,
141       "9" : self.keyNumberGlobal,
142       "0" : self.keyNumberGlobal,
143       "red":    self.redPressed,
144       "green":  self.greenPressed,
145       "yellow": self.yellowPressed,
146       "blue":   self.bluePressed,
147       "right":  self.rightPressed,
148       "left":   self.leftPressed,
149       "down":   self.downPressed,
150       "up":     self.upPressed,
151       "info":   self.infoPressed,
152       "tv":     self.tvPressed,
153       "radio":  self.radioPressed,
154       "text":   self.textPressed,
155       "menu":   self.menuPressed,
156       "help":   self.helpPressed,
157       "video":  self.videoPressed,
158       "nextBouquet": self.nextBouquetPressed,
159       "prevBouquet": self.prevBouquetPressed,
160       "volUp":       self.volumeUpPressed,
161       "volDown":     self.volumeDownPressed
162     }, -1)
163     self["actions"].setEnabled(True)
164
165     self.helpList.append((self["actions"], "TeleTextActions", [("1", _("enter page number"))]))
166     self.helpList.append((self["actions"], "TeleTextActions", [("2", _("enter page number"))]))
167     self.helpList.append((self["actions"], "TeleTextActions", [("3", _("enter page number"))]))
168     self.helpList.append((self["actions"], "TeleTextActions", [("4", _("enter page number"))]))
169     self.helpList.append((self["actions"], "TeleTextActions", [("5", _("enter page number"))]))
170     self.helpList.append((self["actions"], "TeleTextActions", [("6", _("enter page number"))]))
171     self.helpList.append((self["actions"], "TeleTextActions", [("7", _("enter page number"))]))
172     self.helpList.append((self["actions"], "TeleTextActions", [("8", _("enter page number"))]))
173     self.helpList.append((self["actions"], "TeleTextActions", [("9", _("enter page number / page 100"))]))
174     self.helpList.append((self["actions"], "TeleTextActions", [("0", _("enter page number / rezap"))]))
175     self.helpList.append((self["actions"], "OkCancelActions", [("cancel", _("exit"))]))
176     self.helpList.append((self["actions"], "OkCancelActions", [("ok", _("start page catching / select page"))]))
177 #    self.helpList.append((self["actions"], "TeleTextActions", [("volUp",_("increase width"))]))
178 #    self.helpList.append((self["actions"], "TeleTextActions", [("volDown",_("decrease width"))]))
179     self.helpList.append((self["actions"], "TeleTextActions", [("nextBouquet",_("increase height"))]))
180     self.helpList.append((self["actions"], "TeleTextActions", [("prevBouquet",_("decrease height"))]))
181     self.helpList.append((self["actions"], "TeleTextActions", [("info", _("toggle info"))]))
182     self.helpList.append((self["actions"], "TeleTextActions", [("menu", _("teletext settings"))]))
183     self.helpList.append((self["actions"], "TeleTextActions", [("up", _("next page / catch page / move"))]))
184     self.helpList.append((self["actions"], "TeleTextActions", [("left", _("prev sub page / move"))]))
185     self.helpList.append((self["actions"], "TeleTextActions", [("right", _("next sub page / move"))]))
186     self.helpList.append((self["actions"], "TeleTextActions", [("down", _("prev page / catch page / move"))]))
187     self.helpList.append((self["actions"], "TeleTextActions", [("video", _("toggle flof"))]))
188     self.helpList.append((self["actions"], "TeleTextActions", [("red", _("red teletext link"))]))
189     self.helpList.append((self["actions"], "TeleTextActions", [("green", _("green teletext link"))]))
190     self.helpList.append((self["actions"], "TeleTextActions", [("yellow", _("yellow teletext link"))]))
191     self.helpList.append((self["actions"], "TeleTextActions", [("blue", _("blue teletext link"))]))
192     self.helpList.append((self["actions"], "TeleTextActions", [("tv", _("split screen"))]))
193     self.helpList.append((self["actions"], "TeleTextActions", [("radio", _("toggle transparency"))]))
194     self.helpList.append((self["actions"], "TeleTextActions", [("text", _("exit"))]))
195
196     self.connected = False
197
198     self.ttx = TeletextInterface()
199
200     self.onLayoutFinish.append(self.__layoutFinished)
201     self.onExecBegin.append(self.__execBegin)
202     self.onClose.append(self.__closed)
203
204     self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
205     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
206     try:
207       unlink('/tmp/dbttcp.socket')
208     except:
209       pass
210     self.socket.bind('/tmp/dbttcp.socket')
211     self.listen_sn = eSocketNotifier(self.socket.fileno(), POLLIN)
212     self.listen_sn.callback.append(self.listen_data_avail)
213     self.socket.listen(1)
214
215   def socketSend(self, buf):
216     log("send %s" % (buf))
217     try:
218       s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
219       s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
220       s.connect('/tmp/dbttcd.socket')
221       s.setblocking(0)
222       s.sendall(buf)
223       s.close()
224     except socket.error, msg:
225       log("couldn't send data to /tmp/dbttcd.socket")
226       log(socket.errno)
227       log(msg)
228 #      self.session.open(MessageBox, _("Daemon not running."), MessageBox.TYPE_ERROR, timeout = 3)
229 #      self.close()
230
231   def listen_data_avail(self, what):
232     conn, addr = self.socket.accept()
233     buf = conn.recv(8, socket.MSG_WAITALL)
234     x = array.array('H')
235     x.fromstring(buf)
236     if (x[0] + x[1] + x[2] + x[3]) == 0:
237       self.catchPage = False
238     else:
239 #      if (x[0] + x[1]) == 0:
240 #        log("recv update %s" % (x))
241       if not self.isDM7025:
242         self.ttx.update(x[0], x[1], x[2], x[3]);
243       conn.close()
244
245   def __execBegin(self):
246     log("execBegin")
247
248     self.updateLayout()
249
250     # send brightness, contrast and transparency...
251     self.sendSettings()
252
253     if self.isDM7025:
254       renderOffset = 0x75488
255       stride = 0xb80
256     else:
257       renderOffset = self.ttx.getRenderBufferOffset()
258       stride = self.ttx.getRenderBufferStride()
259
260     log("framebuffer offset is %08x stride is %08x" % (renderOffset, stride))
261     x = array.array('B', (CMD_RQ_UPDATE, 1, (renderOffset&0xFF000000)>>24, (renderOffset&0xFF0000)>>16, (renderOffset&0xFF00)>>8, renderOffset&0xFF, (stride&0xFF00) >> 8, stride&0xFF))
262     self.socketSend(x)
263
264   def __closed(self):
265     log("__closed")
266     if self.isDM7025:
267       renderOffset = 0x75488
268       stride = 0xb80
269     else:
270       renderOffset = self.ttx.getRenderBufferOffset()
271       stride = self.ttx.getRenderBufferStride()
272     x = array.array('B', (CMD_RQ_UPDATE, 0, (renderOffset&0xFF000000)>>24, (renderOffset&0xFF0000)>>16, (renderOffset&0xFF00)>>8, renderOffset&0xFF, (stride&0xFF00) >> 8, stride&0xFF))
273     self.socketSend(x)
274
275   def __layoutFinished(self):
276     log("__layoutFinished")
277     self.ttx.show(self.instance)
278
279   def keyNumberGlobal(self, number):
280     if self.nav_mode != NAV_MODE_TEXT or self.catchPage:
281       return
282     log("%s pressed" % (number))
283     x = array.array('B')
284     if self.pageInput == 0:
285       if number == 0:
286         x.append(CMD_RZAP_PAGE)
287       elif number == 9:
288         x.fromlist([CMD_SHOW_PAGE, 1, 0, 0])
289       else:
290         x.fromlist([CMD_PAGEINPUT, number])
291         self.pageInput = (self.pageInput + 1) % 3
292     else:
293       x.fromlist([CMD_PAGEINPUT, number])
294       self.pageInput = (self.pageInput + 1) % 3
295     self.socketSend(x)
296
297   def pageSet(self, page):
298     log("pageSet(%d)" % (page))
299     page = int("%d" % (page), 16)
300     x = array.array('B', (CMD_SHOW_PAGE, (page & 0xFF00) >> 8, (page&0xFF), 0))
301     self.socketSend(x)
302
303   def upPressed(self):
304     if self.nav_mode == NAV_MODE_TEXT:
305       if self.pageInput != 0:
306         return
307       log("up pressed")
308       if self.catchPage:
309         x = array.array('B', (CMD_CATCHPAGE, 2, 0))
310       else:
311         x = array.array('B')
312         x.append(CMD_PAGE_NEXT)
313       self.socketSend(x)
314     else:
315       if self.nav_pos[1] > 0 and self.nav_pos[3] > self.nav_config.limits[3][0]:
316         self.nav_pos[1] = self.nav_pos[1] - 1
317         self.nav_pos[3] = self.nav_pos[3] - 1
318       self.updateLayout()
319
320   def downPressed(self):
321     if self.nav_mode == NAV_MODE_TEXT:
322       if self.pageInput != 0:
323         return
324       log("down pressed")
325       if self.catchPage:
326         x = array.array('B', (CMD_CATCHPAGE, 2, 1))
327       else:
328         x = array.array('B')
329         x.append(CMD_PAGE_PREV)
330       self.socketSend(x)
331     else:
332       if self.nav_pos[1] < self.nav_config.limits[1][1] and self.nav_pos[3] < dsk_height:
333         self.nav_pos[1] = self.nav_pos[1] + 1
334         self.nav_pos[3] = self.nav_pos[3] + 1
335         self.updateLayout()
336
337   def leftPressed(self):
338     if self.nav_mode == NAV_MODE_TEXT:
339       if self.catchPage or self.pageInput != 0:
340         return
341       log("left pressed")
342       x = array.array('B')
343       x.append(CMD_SUBP_PREV)
344       self.socketSend(x)
345     else:
346       if self.nav_pos[0] > 0 and self.nav_pos[2] > self.nav_config.limits[2][0]:
347         self.nav_pos[0] = self.nav_pos[0] - 1
348         self.nav_pos[2] = self.nav_pos[2] - 1
349       self.updateLayout()
350
351   def rightPressed(self):
352     if self.nav_mode == NAV_MODE_TEXT:
353       if self.catchPage or self.pageInput != 0:
354         return
355       log("right pressed")
356       x = array.array('B')
357       x.append(CMD_SUBP_NEXT)
358       self.socketSend(x)
359     else:
360       if self.nav_pos[0] < self.nav_config.limits[0][1] and self.nav_pos[2] < dsk_width:
361         self.nav_pos[0] = self.nav_pos[0] + 1
362         self.nav_pos[2] = self.nav_pos[2] + 1
363         self.updateLayout()
364
365   def nextBouquetPressed(self):
366     if self.nav_mode == NAV_MODE_TEXT:
367       return
368     log("bouqet+ pressed")
369     if self.nav_pos[3] < dsk_height:
370       self.nav_pos[3] = self.nav_pos[3] + 1
371     elif self.nav_pos[1] > 0:
372       self.nav_pos[1] = self.nav_pos[1] - 1
373     self.updateLayout()
374
375   def prevBouquetPressed(self):
376     if self.nav_mode == NAV_MODE_TEXT:
377       return
378     log("bouquet- pressed")
379     if self.nav_pos[3] > (self.nav_pos[1] + MIN_H):
380       if self.nav_pos[3] > self.nav_config.limits[3][0]:
381         self.nav_pos[3] = self.nav_pos[3] - 1
382       elif self.nav_pos[1] < self.nav_config.limits[1][1]:
383         self.nav_pos[1] = self.nav_pos[1] + 1
384       self.updateLayout()
385
386   def volumeUpPressed(self):
387     if self.nav_mode == NAV_MODE_TEXT:
388       globalActionMap.action("TeleText", "volumeUp")
389       return
390     log("volume+ pressed")
391     if self.nav_pos[2] < dsk_width:
392       self.nav_pos[2] = self.nav_pos[2] + 1
393     elif self.nav_pos[0] > 0:
394       self.nav_pos[0] = self.nav_pos[0] - 1
395     self.updateLayout()
396
397   def volumeDownPressed(self):
398     if self.nav_mode == NAV_MODE_TEXT:
399       globalActionMap.action("TeleText", "volumeDown")
400       return
401     log("volume- pressed")
402     if self.nav_pos[2] > (self.nav_pos[0] + MIN_W):
403       if self.nav_pos[2] > self.nav_config.limits[2][0]:
404         self.nav_pos[2] = self.nav_pos[2] - 1
405       elif self.nav_pos[0] < self.nav_config.limits[0][1]:
406         self.nav_pos[0] = self.nav_pos[0] + 1
407     self.updateLayout()
408
409   def redPressed(self):
410     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
411       return
412     log("red pressed")
413     x = array.array('B')
414     x.append(CMD_COLKEY_RD)
415     self.socketSend(x)
416
417   def greenPressed(self):
418     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
419       return
420     log("green pressed")
421     x = array.array('B')
422     x.append(CMD_COLKEY_GN)
423     self.socketSend(x)
424
425   def yellowPressed(self):
426     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
427       return
428     log("yellow pressed")
429     x = array.array('B')
430     x.append(CMD_COLKEY_YE)
431     self.socketSend(x)
432
433   def bluePressed(self):
434     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
435       return
436     log("blue pressed")
437     x = array.array('B')
438     x.append(CMD_COLKEY_BL)
439     self.socketSend(x)
440
441   def infoPressed(self):
442     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
443       return
444     log("info pressed")
445     self.infoValue = not self.infoValue
446     for i in self.onChangedEntry:
447       i()
448     x = array.array('B')
449     x.append(CMD_CONCEALED)
450     self.socketSend(x)
451
452   def videoPressed(self):
453     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
454       return
455     log("video pressed")
456     self.flofValue = not self.flofValue
457     for i in self.onChangedEntry:
458       i()
459     x = array.array('B')
460     x.append(CMD_FLOF)
461     self.socketSend(x)
462
463   def tvPressed(self):
464     if self.nav_mode != NAV_MODE_TEXT:
465       return
466     log("tv pressed")
467     if config.plugins.TeleText.textOnly.value:
468       config.plugins.TeleText.textOnly.value = False
469     else:
470       config.plugins.TeleText.textOnly.value = True
471     config.plugins.TeleText.textOnly.save()
472     configfile.save()
473     self.updateLayout()
474
475   def radioPressed(self):
476     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
477       return
478     log("radio pressed")
479     if config.plugins.TeleText.opaque.value:
480       config.plugins.TeleText.opaque.value = False
481     else:
482       config.plugins.TeleText.opaque.value = True
483     config.plugins.TeleText.opaque.save()
484     configfile.save()
485     self.opaqueValue = config.plugins.TeleText.opaque.value
486     x = array.array('B')
487     x.append(CMD_OPAQUE)
488     self.socketSend(x)
489
490   def textPressed(self):
491     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
492       return
493     log("text pressed")
494     self.resetVideo()
495     self.__closed()
496     self.close()
497
498   def menuPressed(self):
499     if self.nav_mode != NAV_MODE_TEXT or self.catchPage or self.pageInput != 0:
500       return
501     log("menu pressed")
502     self.__closed()
503     self.resetVideo()
504     self.session.openWithCallback(self.menuResult, TeleTextMenu)
505
506   def menuResult(self, result):
507     if result is None:
508       return
509     
510     self.nav_text_only = config.plugins.TeleText.textOnly.value
511     self.nav_config = result
512     self.nav_orig_pos   = result.value
513     self.nav_pos    = result.value
514     
515     if result == config.plugins.TeleText.pos:
516       self.nav_mode = NAV_MODE_SIZE_TEXT
517       config.plugins.TeleText.textOnly.value = True
518     elif result == config.plugins.TeleText.tip_pos:
519       self.nav_mode = NAV_MODE_SIZE_TIP_TEXT
520       config.plugins.TeleText.textOnly.value = False
521       config.plugins.TeleText.textOnly.value = SPLIT_MODE_TIP
522     self.updateLayout()
523
524   def updateLayout(self):
525     if self.nav_mode == NAV_MODE_TEXT:
526       pos = config.plugins.TeleText.pos.value
527     else:
528       pos = self.nav_pos
529     right  = pos[2]
530     bottom = pos[3]
531     mode = config.plugins.TeleText.splitting_mode.value
532
533     if config.plugins.TeleText.textOnly.value == True:
534       left  = pos[0]
535       width  = right - left
536       top    = pos[1]
537       height = bottom - top
538       self.resetVideo()
539     elif mode == SPLIT_MODE_PAT:
540       left   = dsk_width>>1
541       width  = right - (dsk_width>>1)
542       top    = pos[1]
543       height = bottom - top
544       log("splitting video")
545       l=open("/proc/stb/vmpeg/0/dst_left","w")
546       l.write("%x" % 0)
547       l.close()
548       w=open("/proc/stb/vmpeg/0/dst_width","w")
549       w.write("%x" % 360)
550       w.close()
551     elif mode == SPLIT_MODE_TAP:
552       left   = pos[0]
553       width  = (dsk_width>>1) - left
554       top    = pos[1]
555       height = bottom - top
556       log("splitting video")
557       l=open("/proc/stb/vmpeg/0/dst_left","w")
558       l.write("%x" % 360)
559       l.close()
560       w=open("/proc/stb/vmpeg/0/dst_width","w")
561       w.write("%x" % 360)
562       w.close()
563     elif mode == SPLIT_MODE_TIP:
564       if self.nav_mode == NAV_MODE_TEXT:
565         pos = config.plugins.TeleText.tip_pos.value
566       left   = pos[0]
567       width  = pos[2] - left
568       top    = pos[1]
569       height = pos[3] - top
570       self.resetVideo()
571
572     log("screen rect %s %s %s %s" % (left, top, width, height))
573     self.instance.move(ePoint(left,top))
574     self.instance.resize(eSize(*(width, height)))
575
576     self.ttx.hide()
577     self.ttx.show(self.instance)
578     self.ttx.update(0,0,492,250)
579
580   def resetVideo(self):
581     log("reset video")
582     l=open("/proc/stb/vmpeg/0/dst_left","w")
583     l.write("%x" % 0)
584     l.close()
585     w=open("/proc/stb/vmpeg/0/dst_width","w")
586     w.write("%x" % 720)
587     w.close()
588
589   def sendSettings(self, result = True):
590     if result:
591       # region
592       x = array.array('B')
593       x.append(CMD_REGION)
594       x.append(int(config.plugins.TeleText.region.value))
595       self.socketSend(x)
596       # Helligkeit
597       x = array.array('B')
598       x.append(CMD_SET_BRIGH)
599       x.append(config.plugins.TeleText.brightness.value<<4)
600       self.socketSend(x)
601       # Kontrast
602       x = array.array('B')
603       x.append(CMD_SET_CONTR)
604       x.append(config.plugins.TeleText.contrast.value<<4)
605       self.socketSend(x)
606       # Transparenz
607       x = array.array('B')
608       x.append(CMD_TRANSPARENCY)
609       x.append(config.plugins.TeleText.transparency.value<<4)
610       self.socketSend(x)
611       # edge cut
612       if self.edgeValue != config.plugins.TeleText.edge_cut.value:
613         self.edgeValue = config.plugins.TeleText.edge_cut.value
614         x = array.array('B')
615         x.append(CMD_EDGE_CUT)
616         self.socketSend(x)
617       # teletext level
618       x = array.array('B')
619       x.append(CMD_TEXTLEVEL)
620       x.append(int(config.plugins.TeleText.textlevel.value))
621       self.socketSend(x)
622       # opaque
623       if self.opaqueValue != config.plugins.TeleText.opaque.value:
624         self.opaqueValue = config.plugins.TeleText.opaque.value
625         x = array.array('B')
626         x.append(CMD_OPAQUE)
627         self.socketSend(x)
628
629   def helpPressed(self):
630     self.__closed()
631     self.resetVideo()
632     self.session.open(HelpMenu, self.helpList)     
633
634   def okPressed(self):
635     if self.nav_mode == NAV_MODE_TEXT:
636       if self.pageInput != 0:
637         return
638       log("ok pressed")
639       if self.catchPage:
640         x = array.array('B', (CMD_CATCHPAGE, 3, 1))
641         self.catchPage = False
642       else:
643         x = array.array('B', (CMD_CATCHPAGE, 1, 0))
644         self.catchPage = True
645       self.socketSend(x)
646     else:
647       if self.nav_mode == NAV_MODE_SIZE_TEXT:
648         config.plugins.TeleText.pos.value = self.nav_pos
649         config.plugins.TeleText.pos.save()
650       else:
651         config.plugins.TeleText.tip_pos.value = self.nav_pos
652         config.plugins.TeleText.tip_pos.save()
653       config.plugins.TeleText.textOnly.value = self.nav_text_only
654       del self.nav_text_only
655       del self.nav_config
656       del self.nav_orig_pos
657       del self.nav_pos
658       self.nav_mode = NAV_MODE_TEXT
659       self.updateLayout()
660
661   def cancelPressed(self):
662     if self.nav_mode == NAV_MODE_TEXT:
663       if self.pageInput != 0:
664         return
665       log("cancel pressed")
666       if self.catchPage:
667         x = array.array('B', (CMD_CATCHPAGE, 3, 0))
668         self.socketSend(x)
669         self.catchPage = False
670       else:
671         self.resetVideo()
672         self.__closed()
673         self.close()
674     else:
675       if self.nav_mode == NAV_MODE_SIZE_TEXT:
676         config.plugins.TeleText.pos.cancel()
677       else:
678         config.plugins.TeleText.tip_pos.cancel()
679       config.plugins.TeleText.textOnly.value = self.nav_text_only
680       del self.nav_text_only
681       del self.nav_config
682       del self.nav_orig_pos
683       del self.nav_pos
684       self.nav_mode = NAV_MODE_TEXT
685       self.updateLayout()
686
687   def serviceStarted(self):
688     log("service started")
689
690   def serviceStopped(self):
691     log("service stopped")
692     x = array.array('B', (CMD_CTL_CACHE, 0, 0, 0))
693     self.socketSend(x)
694
695   def serviceInfoChanged(self):
696     log("serviceInfoChanged")
697     service = self.session.nav.getCurrentService()
698     info = service and service.info()
699     txtpid = info and info.getInfo(iServiceInformation.sTXTPID)
700
701     self.hasText = txtpid is not None and txtpid > -1
702
703     stream = service and service.stream()
704     demux = stream and stream.getStreamingData()
705     demux = demux and demux.get("demux", -1)
706
707     log("TXT PID %s DEMUX %s" % (txtpid, demux))
708
709     if demux > -1 and self.hasText:
710       x = array.array('B', (CMD_CTL_CACHE, (txtpid & 0xFF00) >> 8, (txtpid&0xFF), demux))
711       self.socketSend(x)
712
713   def showMessages(self):
714     return config.plugins.TeleText.messages.value
715
716   # ---- for summary (lcd) ----
717
718   def createSummary(self):
719     return TeleTextSummary
720
721   def flofEnabled(self):
722     return self.flofValue
723     
724   def infoEnabled(self):
725     return self.infoValue
726
727 # ----------------------------------------
728
729 class TeleTextSummary(Screen):
730
731   def __init__(self, session, parent):
732     onPic  = resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/lcd_on.png")
733     offPic = resolveFilename(SCOPE_PLUGINS, "Extensions/TeleText/lcd_off.png")
734
735     TeleTextSummary.skin = """<screen name="TeleTextSummary" position="0,0" size="132,64">
736       <widget name="SetupTitle" position="6,4" size="120,20" font="Regular;20" halign="center"/>
737
738       <widget name="flof_off" position="24,28" size="20,20" pixmap="%s" zPosition="1"/>
739       <widget name="info_off" position="88,28" size="20,20" pixmap="%s" zPosition="1"/>
740       <widget name="flof_on"  position="24,28" size="20,20" pixmap="%s" zPosition="2"/>
741       <widget name="info_on"  position="88,28" size="20,20" pixmap="%s" zPosition="2"/>
742
743       <widget name="flof_txt" position="10,50" size="48,12" font="Regular;12" valign="center" halign="center" zPosition="1"/>
744       <widget name="info_txt" position="74,50" size="48,12" font="Regular;12" valign="center" halign="center" zPosition="1"/> 
745     </screen>""" % (offPic, offPic, onPic, onPic)
746
747     Screen.__init__(self, session, parent = parent)
748     self["SetupTitle"] = Label("TeleText")
749     self["flof_txt"] = Label("FLOF")
750     self["info_txt"] = Label("INFO")
751     self["flof_off"] = Pixmap()
752     self["info_off"] = Pixmap()
753     self["flof_on"]  = Pixmap()
754     self["info_on"]  = Pixmap()
755     self.onShow.append(self.addWatcher)
756     self.onHide.append(self.removeWatcher)
757
758   def addWatcher(self):
759     self.parent.onChangedEntry.append(self.selectionChanged)
760     self.selectionChanged()
761
762   def removeWatcher(self):
763     self.parent.onChangedEntry.remove(self.selectionChanged)
764
765   def selectionChanged(self):
766     if self.parent.flofEnabled():
767       self["flof_off"].hide()
768       self["flof_on"].show()
769     else:
770       self["flof_on"].hide()
771       self["flof_off"].show()
772
773     if self.parent.infoEnabled():
774       self["info_off"].hide()
775       self["info_on"].show()
776     else:
777       self["info_on"].hide()
778       self["info_off"].show()
779
780 # ----------------------------------------
781
782 class TeleTextMenu(ConfigListScreen, Screen):
783
784   onChangedEntry = [ ]
785   isInitialized = False
786
787   def __init__(self, session):
788     width = 492
789     height = 350
790     left = (dsk_width - width)>>1
791     top = (dsk_height - height)>>1
792     log("[menu] screen rect %s %s %s %s" % (left, top, width, height))
793     TeleTextMenu.skin = """<screen position="%d,%d" size="%d,%d" title="%s">
794         <widget name="config" position="0,0"   size="492,275" scrollbarMode="showOnDemand" zPosition="1"/>
795         <ePixmap pixmap="skin_default/div-h.png" position="0,280" zPosition="1" size="492,2" />
796         <widget name="label"  position="0,285" size="492,65" font="Regular;16" zPosition="1" halign="left" valign="top"/>
797       </screen>""" % (left, top, width, height, _("TeleText settings"))
798
799     Screen.__init__(self, session)
800
801     # create config list
802     self.list = [] 
803     ConfigListScreen.__init__(self, self.list) 
804     self.createConfigList()
805
806     self["actions"] = ActionMap(["OkCancelActions", "TeleTextActions"],
807     {
808       "ok"     : self.okPressed,
809       "cancel" : self.cancelPressed,
810       "menu"   : self.cancelPressed,
811       "text"   : self.textPressed
812     }, -2)
813     self["actions"].setEnabled(True)
814
815     self["label"] = Label("Info")
816
817     self.onLayoutFinish.append(self.__layoutFinished)
818
819   def __layoutFinished(self):
820     self.isInitialized = True
821     if not self.selectionChanged in self["config"].onSelectionChanged:
822       self["config"].onSelectionChanged.append(self.selectionChanged)
823     self.selectionChanged()     
824
825   def selectionChanged(self):
826     configele = self["config"].getCurrent()[1]
827     if configele == config.plugins.TeleText.pos:
828       self["label"].setText(HELP_TEXT_POS)
829     elif configele == config.plugins.TeleText.brightness:
830       self["label"].setText(HELP_TEXT_BRIGHTNESS)
831     elif configele == config.plugins.TeleText.contrast:
832       self["label"].setText(HELP_TEXT_CONTRAST)
833     elif configele == config.plugins.TeleText.transparency:
834       self["label"].setText(HELP_TEXT_TRANSPARENCY)
835     elif configele == config.plugins.TeleText.splitting_mode:
836       self["label"].setText(HELP_TEXT_SPLITTING)
837     elif configele == config.plugins.TeleText.tip_pos:
838       self["label"].setText(HELP_TEXT_TIP_POS)
839     elif configele == config.plugins.TeleText.messages:
840       self["label"].setText(HELP_TEXT_MESSAGES)
841     elif configele == config.plugins.TeleText.debug:
842       self["label"].setText(HELP_TEXT_DEBUG)
843     elif configele == config.plugins.TeleText.edge_cut:
844       self["label"].setText(HELP_TEXT_EDGE_CUT)
845     elif configele == config.plugins.TeleText.textlevel:
846       self["label"].setText(HELP_TEXT_TEXTLEVEL)
847     elif configele == config.plugins.TeleText.region:
848       self["label"].setText(HELP_TEXT_REGION)
849
850   def createConfig(self, configele):
851     if not self.isInitialized:
852       return
853     self.createConfigList()
854
855   def createConfigList(self):
856     self.isInitialized = False
857
858     # remove notifiers
859     for x in self["config"].list:
860       x[1].clearNotifiers() 
861
862     self.list = [
863       getConfigListEntry(_("Brightness"),        config.plugins.TeleText.brightness),
864       getConfigListEntry(_("Contrast"),          config.plugins.TeleText.contrast),
865       getConfigListEntry(_("Transparency"),      config.plugins.TeleText.transparency),
866       getConfigListEntry(_("Text level"),        config.plugins.TeleText.textlevel),
867       getConfigListEntry(_("Region"),            config.plugins.TeleText.region),
868       getConfigListEntry(_("Position and size"), config.plugins.TeleText.pos),
869       getConfigListEntry(_("Display edges"),     config.plugins.TeleText.edge_cut),
870       getConfigListEntry(_("Splitting mode"),    config.plugins.TeleText.splitting_mode)
871     ]
872     if config.plugins.TeleText.splitting_mode.value == SPLIT_MODE_TIP:
873       self.list.append(getConfigListEntry("... %s" % _("Position and size"),   config.plugins.TeleText.tip_pos))
874     self.list.append(getConfigListEntry(_("Message"), config.plugins.TeleText.messages))
875     self.list.append(getConfigListEntry(_("Debug"),   config.plugins.TeleText.debug))
876
877     self["config"].list = self.list
878
879     # add notifiers (lcd, info)
880     for x in self["config"].list:
881       x[1].addNotifier(self.changedEntry)
882     # add notifiers (menu)
883     config.plugins.TeleText.splitting_mode.addNotifier(self.createConfig)
884
885     self.isInitialized = True
886
887   def textPressed(self):
888     log("[menu] text pressed")
889     if self["config"].getCurrent()[1] == config.plugins.TeleText.pos:
890       self.close(config.plugins.TeleText.pos)
891     elif self["config"].getCurrent()[1] == config.plugins.TeleText.tip_pos:
892       self.close(config.plugins.TeleText.tip_pos)
893
894   def okPressed(self):
895     log("[menu] ok pressed")
896     self.checkPositionValues(config.plugins.TeleText.pos)
897     self.checkPositionValues(config.plugins.TeleText.tip_pos)
898     for x in self["config"].list:
899       x[1].save()
900     configfile.save()
901     self.close(None) 
902
903   def checkPositionValues(self, configele):
904     pos = configele.value
905     log("... old pos: %s %s %s %s" % (pos[0], pos[1], pos[2], pos[3]))
906     update = False
907     if pos[0] > pos[2]:
908       i = pos[0]
909       pos[0] = pos[2]
910       pos[2] = i
911       update = True
912     if pos[1] > pos[3]:
913       i = pos[1]
914       pos[1] = pos[3]
915       pos[3] = i
916       update = True
917     if (pos[2] - pos[0]) < MIN_W:
918       pos[2] = pos[0] + MIN_W
919       update = True
920     if (pos[3] - pos[1]) < MIN_H:
921       pos[3] = pos[1] + MIN_H
922       update = True
923     if pos[2] > dsk_width:
924       pos[0] = pos[0] + dsk_width - pos[2]
925       pos[2] = dsk_width
926       update = True
927     if pos[3] > dsk_height:
928       pos[1] = pos[1] + dsk_height - pos[3]
929       pos[3] = dsk_height
930       update = True
931     log("... new pos: %s %s %s %s" % (pos[0], pos[1], pos[2], pos[3]))
932       
933     if update:
934       configele.setValue(pos)
935
936   def cancelPressed(self):
937     log("[menu] cancel pressed")
938     confirm = False
939     for x in self["config"].list:
940       confirm = confirm or x[1].isChanged()
941     if confirm:
942       self.session.openWithCallback(self.DiscardConfirm, MessageBox, _("Discard changes?"))
943     else:
944       self.close(None) 
945
946   def DiscardConfirm(self, result):
947     if result:
948       for x in self["config"].list:
949         if x[1].isChanged():
950           x[1].cancel()
951       self.close(None)
952
953   # ---- for summary (lcd) ----
954
955   def changedEntry(self, element=None):
956     for x in self.onChangedEntry:
957       x()
958
959   def getCurrentEntry(self):
960     return self["config"].getCurrent()[0]
961
962   def getCurrentValue(self):
963     return str(self["config"].getCurrent()[1].getText())
964
965   def createSummary(self):
966     return TeleTextMenuSummary
967
968 # ----------------------------------------
969
970 class TeleTextMenuSummary(Screen):
971   skin = """<screen name="TeleTextMenuSummary" position="0,0" size="132,64">
972       <widget name="SetupTitle" position="6,4"  size="120,20" font="Regular;20" halign="center"/>
973       <widget name="SetupEntry" position="6,30" size="120,12" font="Regular;12" halign="left"/>
974       <widget name="SetupValue" position="6,48" size="120,12" font="Regular;12" halign="right"/>
975     </screen>"""
976
977   def __init__(self, session, parent):
978     Screen.__init__(self, session, parent = parent)
979     self["SetupTitle"] = Label("TeleText")
980     self["SetupEntry"] = Label("")
981     self["SetupValue"] = Label("")
982     self.onShow.append(self.addWatcher)
983     self.onHide.append(self.removeWatcher)
984
985   def addWatcher(self):
986     self.parent.onChangedEntry.append(self.selectionChanged)
987     self.parent["config"].onSelectionChanged.append(self.selectionChanged)
988     self.selectionChanged()
989
990   def removeWatcher(self):
991     self.parent.onChangedEntry.remove(self.selectionChanged)
992     self.parent["config"].onSelectionChanged.remove(self.selectionChanged)
993
994   def selectionChanged(self):
995     self["SetupEntry"].text = self.parent.getCurrentEntry()
996     self["SetupValue"].text = self.parent.getCurrentValue() 
997
998 # ----------------------------------------
999
1000 def sessionstart(reason, session):
1001   log("----- sessionstart(%s) -----" % session)
1002   # Daemon starten
1003   container = eConsoleAppContainer()
1004   container.execute("/usr/bin/dbttcd")
1005   # Plugin initialisieren
1006   global ttx_screen;
1007   ttx_screen = session.instantiateDialog(TeleText)
1008
1009 def autostart(reason, **kwargs):
1010   log("autostart(%s, %s)" % (reason, kwargs))
1011   if reason == 0:
1012     pass
1013   elif reason == 1:
1014     pass
1015
1016 def mainText(session, **kwargs):
1017   global ttx_screen
1018   log("mainText")
1019   if ttx_screen.hasText:
1020     session.execDialog(ttx_screen)
1021   else:
1022     if ttx_screen.showMessages():
1023       session.open(MessageBox, _("No teletext available."), MessageBox.TYPE_INFO, timeout = 3)
1024
1025 def mainMenu(session, **kwargs):
1026   global ttx_screen
1027   log("mainMenu")
1028   session.open(TeleTextMenu)
1029
1030 def Plugins(**kwargs):
1031   log("plugins")
1032   return [
1033     PluginDescriptor(name="TeleText", description="teletext", where = PluginDescriptor.WHERE_TELETEXT, fnc=mainText),
1034     PluginDescriptor(needsRestart = False, where = PluginDescriptor.WHERE_SESSIONSTART, fnc=sessionstart),
1035     PluginDescriptor(needsRestart = False, where = PluginDescriptor.WHERE_AUTOSTART, fnc=autostart)
1036     ]
1037
1038 # EOF