Update upstream source from tag 'upstream/2.3.0'
Update to upstream version '2.3.0'
with Debian dir fec82820a9a500923b2d44000a2ac8b46240340c
Tobias Grimm
2 years ago
0 | 0 | VDR Plugin 'osdteletext' Revision History |
1 | 1 | ----------------------------------------- |
2 | 2021-12-09: version 2.3.0 | |
3 | - [pbiering] add support for half bright standard colors and ETSI colors 16-31 | |
4 | - [pbiering] extend 24-Line-Toggle with a 3rd option to display hint lines for standard keys | |
5 | - [pbiering] long option fix "key-levels", add-missing "osd-preset" | |
6 | - [pbiering] limit DrawMessage box to maximum box size | |
7 | ||
8 | 2021-08-06: version 2.2.1 | |
9 | - [pbiering] fix frame in case reaching OSD limits | |
10 | - [pbiering] honor frame value in case of 100% width or height | |
11 | ||
12 | 2021-05-30: version 2.2.0 | |
13 | - [pbiering] adjust range check for "jump to page" | |
14 | ||
15 | 2021-05-22: | |
16 | - [pbiering] fix range check bug related to Hotkey "jump to page" config | |
17 | - [pbiering] fix not working Hotkey level feature in case only 2 levels are active | |
18 | ||
19 | 2021-05-12: | |
20 | - [pbiering] fix in setup changed but not applied to current background transparency | |
21 | ||
22 | 2021-05-11: | |
23 | - [pbiering] fix in OSD config changed but not remembered background transparency | |
24 | ||
25 | 2021-04-22: | |
26 | - [pbiering] remove obsolete setup options suspendReceiving, inactivityTimeout | |
27 | - [pbiering] drop setup option configuredClrBackground and change to "BackTrans" (with multi-preset support) and proper 0-255 logic (not inverted as before) | |
28 | ||
29 | 2021-04-18: | |
30 | - [pbiering] implement optional OSD Hotkey level feature (max. 9 levels with limiter) | |
31 | - [pbiering] implement optional OSD Preset feature (max. 9 presets with limiter) | |
32 | - [pbiering] rework dynamic menu creation related to 'jump to' to fix 'not working on last config entry' issue | |
33 | ||
34 | 2021-04-27: version 2.1.1 | |
35 | - [pbiering] release receiver on live channel switch earlier in sequence to use even on 2-tuner systems by default only one tuner | |
36 | - [pbiering] release device on non-live -> non-live channel switch earlier to avoid locking on 2-tuner systems | |
37 | ||
38 | 2021-04-19: version 2.1.0 | |
39 | - [pbiering] catch case where in tuned mode channel switch is triggered on selected device and switch into cached mode | |
40 | ||
41 | 2021-04-15: | |
42 | - [pbiering] finally catch and handle proper switching from tuned to live channel by outside trigger (e.g. RCU) | |
43 | ||
44 | 2021-04-14: | |
45 | - [pbiering] replace all sleeps related to messages with a delay method, review/catch cases when a channel switch message should be displayed | |
46 | - [pbiering] include channel number in 'invalid channel' message | |
47 | - [pbiering] ChannelSwitch now supports receiving other channels from same transponder or even other transponder (aka "tuned" mode) | |
48 | - [pbiering] various cosmetic fixes | |
49 | ||
50 | 2021-04-11: version 2.0.2 | |
51 | - [pbiering] fixes/cleanup translations of key assignment setup menu | |
52 | ||
53 | 2021-04-11: version 2.0.1 | |
54 | - [pbiering] fix warnings reported by clang | |
55 | - [pbiering] display channel switch message only in case OSD is active | |
56 | - [pbiering] fix G0 character without diacritical mark | |
57 | - [pbiering] bring storage system "packed" back to default | |
58 | ||
59 | 2021-04-11: version 2.0.0 | |
60 | - [pbiering] additional fixes found during regression tests related to translations and others | |
61 | ||
62 | 2021-04-09: | |
63 | - [pbiering] clear teletext page on channel switch | |
64 | ||
65 | 2021-04-08: | |
66 | - [pbiering] many fixes found during regression tests related to MessageBox, too often CleanDisplay calls, ... | |
67 | - [pbiering] display PageId always in case OSD was restarted (useful e.g. for subtitle pages) | |
68 | - [pbiering] selected background color kept on OSD restart | |
69 | ||
70 | 2021-04-07: | |
71 | - [pbiering] cached pages of non-live channel: display page IDs in different color and a 'c' mark, do not trigger useless 'Pause' | |
72 | - [pbiering] channel switch: display message, on empty OK return to live channel | |
73 | - [pbiering] draw bi-colored message frame, increase frame on high resolution, change font on high resolution | |
74 | ||
75 | 2021-04-06: | |
76 | - [pbiering] stop updating clock and blink in case of page update was stopped | |
77 | - [pbiering] display sender name in case page is not found | |
78 | - [pbiering] blacklist Italic and Oblique fonts from being selectable (which causes anyhow issues on displaying because of kerning) | |
79 | - [pbiering] improve font scaling | |
80 | ||
81 | 2021-04-04: | |
82 | - [pbiering] add "Text Font" option to OSD config | |
83 | ||
84 | 2021-04-03: | |
85 | - [pbiering] add support for "G0 character with diacritical mark" by implementation related support of X/26 | |
86 | - [pbiering] introduce new page cache storage format VTXV5 to cover X/25-28 and M/29 extension | |
87 | - [pbiering] fix not working selection of cache-system 'legacy' | |
88 | ||
89 | 2021-03-28: version 1.1.1 | |
90 | - [pbiering] fix missing implementation of graphics char 0x7f (filled rectangle) | |
91 | - [pbiering] implement 'Paused' toggle | |
92 | ||
93 | 2021-03-27: | |
94 | - [pbiering] add backgorund transparency to OSD config mode | |
95 | - [pbiering] remember background color when toggling through 'Half' mode | |
96 | ||
97 | 2021-03-25: | |
98 | - [pbiering] fix/enable toggle support for concealed chars and hint after page number if concealed chars exist, do not display concealed chars by default | |
99 | ||
100 | 2021-03-25: version 1.1.0 | |
101 | - [pbiering] fix related to boxed chars in case page is not boxed itself | |
102 | ||
103 | 2021-03-24: | |
104 | - [pbiering] add 24-line-mode as optional key action toggle | |
105 | ||
106 | 2021-03-23: | |
107 | - [pbiering] implement OSD config mode | |
108 | ||
109 | 2021-03-22: | |
110 | - [pbiering] implement optional black frame | |
111 | - [pbiering] extend half mode with top instead bottom placement | |
112 | - [pbiering] replace bottom black line by button hint line | |
113 | ||
114 | 2021-03-21: | |
115 | - [pbiering] fix broken support of 'blink' | |
116 | - [pbiering] hide clock on boxed pages | |
117 | - [pbiering] show PageId only until 1st update on boxed pages | |
118 | ||
119 | 2021-03-20: | |
120 | - [pbiering] extend README with hints to reference pages (hint from https://www.vdr-portal.de/forum/index.php?thread/134254-osdteletext-1-0-0-released/&postID=1338016#post1338016) | |
121 | ||
122 | 2021-03-12: version 1.0.7 | |
123 | - [pbiering] decrease thread priority to "low" | |
124 | - [pbiering] add info log for thread start/stop (incl. some statistics) | |
125 | - [pbiering] add optional debug log for cTxtReceiver::DecodeTXT | |
126 | ||
127 | 2021-02-28: | |
128 | - [pbiering] align plugin prefix in log, cleanup some EOL code | |
129 | - [pbiering] fix OSD background rectangle size | |
130 | - [pbiering] fix char rectangle size | |
131 | ||
132 | 2021-02-28: version 1.0.6 | |
133 | - [pbiering] fix for 'half' and 'zoom' mode in combination with 24-line mode | |
134 | ||
135 | 2021-02-27: version 1.0.5 | |
136 | - [pbiering] some fixes related to 24-line mode option and double call of CleanDisplay | |
137 | ||
138 | 2021-02-27: version 1.0.4 | |
139 | - [pbiering] add 24-line mode option | |
140 | ||
141 | 2021-02-26: version 1.0.3 | |
142 | - [pbiering] fix 'half' mode | |
143 | ||
144 | 2021-02-25: version 1.0.2 | |
145 | - [pbiering] replace percent based vertical/horizontal center option by top/left (re-add dropped feature) | |
146 | ||
147 | 2021-02-25: version 1.0.1 | |
148 | - [pbiering] add percent based vertical/horizontal center option | |
149 | ||
150 | 2021-02-23: version 1.0.0 | |
151 | - [pbiering] replace OSD sizing options by percent values and always-centric | |
152 | - [pbiering] scale "Text Vertical Offset" according to reduced size | |
153 | ||
154 | 2021-02-19: version 0.9.9 | |
155 | - [pbiering] add fallback to 8 bpp in case OSD is not supporting TrueColor | |
156 | ||
157 | 2021-02-04: | |
158 | - [pbiering] fix obsolete use of readdir_r (credits to ua0lnj) | |
159 | https://github.com/vdr-projects/vdr-plugin-osdteletext/issues/5 | |
160 | ||
161 | 2021-02-01: version 0.9.8 | |
162 | - [pbiering] introduce setup option "Text Vertical Offset" ("5" looks good on softhddevice) | |
163 | - [pbiering] fix out-of-bounds message by using new way to calculated x/y position for ClearMessage | |
164 | - [pbiering] merge fix for issues found with OpenGL | |
165 | https://www.vdr-portal.de/forum/index.php?thread/133952-softhddevice-bug-in-opengl-osd-bug-mit-osdteletext/ | |
166 | - [pbiering] merge fix for annoying blank lines in graphics characters | |
167 | https://www.vdr-portal.de/index.php?attachment/41771-osdteletext-0-9-7-patch/ | |
168 | https://www.vdr-portal.de/forum/index.php?thread/131627-gel%C3%B6st-vdr-plugin-osdteletxt-0-9-7/&postID=1303329#post1303329 | |
169 | - [pbiering] add configurable 4bpp color mode base on hardcoded patch: | |
170 | https://www.vdr-portal.de/index.php?attachment/41884-osdteletext-4bpp-diff/ | |
171 | https://www.vdr-portal.de/forum/index.php?thread/131627-gel%C3%B6st-vdr-plugin-osdteletxt-0-9-7/&postID=1304681#post1304681 | |
2 | 172 | |
3 | 173 | 2018-02-24: version 0.9.7 |
4 | 174 | - Added teletext2.ttf |
10 | 10 | ### The version number of this plugin (taken from the main source file): |
11 | 11 | |
12 | 12 | VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') |
13 | ||
14 | ### switch compiler | |
15 | ifeq ($(CLANG), 1) | |
16 | CC="clang" | |
17 | CXX="clang++" | |
18 | endif | |
13 | 19 | |
14 | 20 | ### The directory environment: |
15 | 21 | |
25 | 31 | |
26 | 32 | export CFLAGS = $(call PKGCFG,cflags) |
27 | 33 | export CXXFLAGS = $(call PKGCFG,cxxflags) |
34 | ||
35 | ifeq ($(CLANG), 1) | |
36 | $(info ORG CFLAGS=$(CFLAGS)) | |
37 | $(info ORG CXXFLAGS=$(CXXFLAGS)) | |
38 | # remove not supported options (at least Fedora 33) | |
39 | CFLAGS_PKGCFG = $(call PKGCFG,cflags) | |
40 | CXXFLAGS_PKGCFG = $(call PKGCFG,cxxflags) | |
41 | CFLAGS_1 = $(subst -ffat-lto-objects,,$(CFLAGS_PKGCFG)) | |
42 | CXXFLAGS_1 = $(subst -ffat-lto-objects,,$(CXXFLAGS_PKGCFG)) | |
43 | CFLAGS_2 = $(subst -flto=auto,,$(CFLAGS_1)) | |
44 | CXXFLAGS_2 = $(subst -flto=auto,,$(CXXFLAGS_1)) | |
45 | CFLAGS_3 = $(subst -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1,,$(CFLAGS_2)) | |
46 | CXXFLAGS_3 = $(subst -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1,,$(CXXFLAGS_2)) | |
47 | CFLAGS_4 = $(subst -specs=/usr/lib/rpm/redhat/redhat-hardened-ld,,$(CFLAGS_3)) | |
48 | CXXFLAGS_4 = $(subst -specs=/usr/lib/rpm/redhat/redhat-hardened-ld,,$(CXXFLAGS_3)) | |
49 | CFLAGS_5 = $(subst -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1,,$(CFLAGS_4)) | |
50 | CXXFLAGS_5 = $(subst -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1,,$(CXXFLAGS_4)) | |
51 | export CFLAGS = $(CFLAGS_5) | |
52 | export CXXFLAGS = $(CXXFLAGS_5) | |
53 | $(info MOD CFLAGS=$(CFLAGS)) | |
54 | $(info MOD CXXFLAGS=$(CXXFLAGS)) | |
55 | endif | |
28 | 56 | |
29 | 57 | ### The version number of VDR's plugin API: |
30 | 58 | |
51 | 79 | |
52 | 80 | ### The object files (add further files here): |
53 | 81 | |
54 | OBJS = $(PLUGIN).o menu.o txtfont.o txtrecv.o txtrender.o displaybase.o display.o storage.o legacystorage.o packedstorage.o rootdir.o | |
82 | OBJS = $(PLUGIN).o menu.o txtfont.o txtrecv.o txtrender.o displaybase.o display.o storage.o legacystorage.o packedstorage.o rootdir.o setup.o | |
55 | 83 | |
56 | 84 | ### The main target: |
57 | 85 | |
82 | 110 | %.mo: %.po |
83 | 111 | msgfmt -c -o $@ $< |
84 | 112 | |
85 | $(I18Npot): $(wildcard *.c) | |
113 | $(I18Npot): $(wildcard *.c) $(wildcard *.h) | |
86 | 114 | xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^` |
87 | 115 | |
88 | 116 | %.po: $(I18Npot) |
0 | 0 | This is a "plugin" for the Video Disk Recorder (VDR). |
1 | 1 | |
2 | Written by: Marcel Wiesweg <marcel.wiesweg@gmx.de> | |
3 | ||
4 | Project's homepage: http://www.wiesweg-online.de/linux/vdr | |
5 | ||
6 | Latest version available at: http://projects.vdr-developer.org/projects/show/plg-osdteletext | |
2 | Initially Written by: Marcel Wiesweg <marcel.wiesweg@gmx.de> | |
3 | ||
4 | Original Project's homepage (EOSL): http://www.wiesweg-online.de/linux/vdr | |
5 | ||
6 | Latest version available at: https://github.com/vdr-projects/vdr-plugin-osdteletext | |
7 | 7 | |
8 | 8 | See the file COPYING for license information. |
9 | 9 | |
37 | 37 | Have a look at the plugin's setup page to learn the current assignment |
38 | 38 | and adapt it to your needs. |
39 | 39 | |
40 | Available Keys: Blue, Red, Yellow, Green, Play, Stop, FastFwd, FastRwd | |
41 | Actions: "Zoom", "Half page", "Switch channel", "Switch background", | |
40 | Available Keys: | |
41 | Blue, Red, Yellow, Green, | |
42 | Stop, FastFwd, FastRwd, Ok | |
43 | ||
44 | Actions: | |
45 | "Zoom", "Half page", "Switch channel", "Switch background", | |
46 | "Config", "24-Line-Mode", "Answer", "Pause" | |
47 | "Hotkey Level+", "Hotkey Level-" | |
48 | "OSD Preset+", "OSD Preset-" | |
42 | 49 | "Jump to..." a specific page. |
43 | 50 | |
44 | 51 | Description of the actions: |
45 | 52 | Zoom: Zoom to upper half/lower half/back to full page |
53 | ||
46 | 54 | Half Page: Reduce OSD window to the lower half of the screen and |
47 | 55 | display upper half/lower half/back to full size |
56 | ||
48 | 57 | Switch channel:Show pages of a channel different from the one currently |
49 | tuned to. This does _not_ include any tuning or channel | |
50 | switching with vdr's core. You must have tuned to the | |
51 | channel chosen some time before so that the pages have | |
52 | been stored on disk. When you press the key associated | |
58 | tuned to. In case a channel is on same transponder or | |
59 | an additional free tuner is availabe it will change the | |
60 | receiver ("tuned" mode). If not, it stays in "chached" | |
61 | mode and only display pages which were received during | |
62 | tuning to selected channel in the past and pages are stored | |
63 | on disk already. When you press the key associated | |
53 | 64 | with that action, you are asked for the channel number. |
54 | 65 | Press OK after you entered it with the number keys. |
66 | Without providing a channel, OK switches back to live channel | |
67 | ||
55 | 68 | Jump to...: Jumps to the page you configure. |
69 | ||
56 | 70 | Switch background: Toggles background transparency between a value |
57 | 71 | configured in setup, fully black, and fully transparent. |
72 | ||
73 | Config: Enter OSD configuration mode, currently supported | |
74 | Left,Top +/- | |
75 | Width,Height +/- | |
76 | Frame +/- | |
77 | Text Vertical Offset +/- | |
78 | Background Transparency +/- | |
79 | ||
80 | 24-Line-Mode: Toggle Hotkey line (line 25) or add even Hints lines (line 26+27) | |
81 | ||
82 | Answer : Display concealed chars (toggle) | |
83 | OSD will display yellow '?' in case page contains concealed chars | |
84 | OSD will display green '!' while concealed chars are displayed | |
85 | ||
86 | Pause : Stop updating page (toggle) | |
87 | OSD will display red '!' while paused | |
88 | OSD will display green '>' after release (until next page update) | |
89 | ||
90 | ** if enabled/active ** | |
91 | Hotkey Level+ : Change to next Hotkey level (incl. rollover) | |
92 | Hotkey Level- : Change to previous Hotkey level (incl. rollover) | |
93 | Recommended assignment: | |
94 | FastFwd: Hotkey Level+ | |
95 | FastRwd: Hotkey Level- | |
96 | ||
97 | OSD Preset+ : Change to next OSD preset (incl. rollover) | |
98 | OSD Preset- : Change to previous OSD preset (incl. rollover) | |
58 | 99 | |
59 | 100 | How to configure the key bindings: |
60 | 101 | In the plugins setup menu, you can assign one of actions to each key. |
65 | 106 | |
66 | 107 | |
67 | 108 | Other Setup options: |
68 | Background transparency: | |
69 | number between 0 (transparent) and 255 (black). Default is 127 | |
70 | (also used by VDR) | |
71 | 109 | Show Clock: Toggles whether an additional clock is drawn approximately |
72 | 110 | every second. |
73 | 111 | The clock shows the current system time, not any time broadcast |
76 | 114 | Auto-update pages: |
77 | 115 | Continuously checks whether a page has changed and updates it |
78 | 116 | if yes. |
79 | OSD width, OSD height: | |
80 | Adjusts the width and height of the OSD independent from VDR's | |
81 | settings. The valid range is 40 to 56 for the width and 12 to | |
82 | 21 for the height. | |
117 | Color Mode 4bpp: | |
118 | Enforce 16-color mode (for some older DVB cards) | |
119 | 24-line mode | |
120 | Display (and scale for) only 24 lines | |
83 | 121 | Minimum user inactivity: |
84 | 122 | Sets a timeout (in minutes) for user inactivity. When this |
85 | 123 | timespan has elapsed and the user did not press any keys, the |
86 | 124 | plugin will be closed. Set to 0 to disable this. Note that |
87 | 125 | disabling timeout will also effectively disable VDR's |
88 | 126 | auto-shutdown feature as long as the plugin is active. |
127 | ||
128 | ** optional with multi-preset support ** | |
129 | OSD Presets visible | |
130 | Limit maximum visible presets | |
131 | ||
132 | OSD left, OSD top: | |
133 | Adjusts the left and top edge of the OSD independent from VDR's | |
134 | settings. The valid range is 0% to 90% | |
135 | OSD width, OSD height: | |
136 | Adjusts the width and height of the OSD independent from VDR's | |
137 | settings. The valid range is 10% to 100% | |
138 | Frame: | |
139 | Adjust black surrounding frame sized by amount of pixel | |
140 | Font: | |
141 | Select the font to display text | |
142 | Text Vertical Offset: | |
143 | Adjust the vertical offset by amount of (scaled) pixels | |
144 | The valid range is -10 to 10 (and depending on selected font) | |
145 | Background transparency: | |
146 | number between 0 (black) and 255 (transparency). Default is 128 | |
147 | ||
148 | Hotkey (color key) bindings: See above, optional with multi-level support | |
149 | ||
89 | 150 | Key bindings: See above. |
90 | 151 | |
91 | 152 | Command line options: |
107 | 168 | one-file-for-a-few-pages system. |
108 | 169 | -t --toptext Store top text pages at cache. |
109 | 170 | (unviewable pages) |
171 | -k --key-levels=NUM Maximum amount of Hotkey levels selectable and stored | |
172 | default: 1 (which deactivate this feature) | |
173 | maximum: 9 levels | |
174 | -o --osd-presets=NUM Maximum amount of OSD presets selectable and stored | |
175 | default: 1 (which deactivate this feature) | |
176 | maximum: 9 presets | |
177 | -P|--debugpage <int|hexint> Specify page to debug (int: autoconvert internally to hex) | |
178 | -S|--debugpsub <int|hexint> Specify sub-page to debug (int: autoconvert internally to hex) | |
179 | -L|--debugline <int> Specify line of page to debug | |
180 | -D|--debugmask <int|hexint> Enable debugmask (see logging.h for details) | |
181 | ||
110 | 182 | |
111 | 183 | Colors: |
112 | 184 | On all sorts of output devices which are not limited as to color depth |
117 | 189 | The mapping is currently optimized for German ARD, ZDF and RTL. If you are |
118 | 190 | for some reason really and definitely not satisfied with my choices, edit |
119 | 191 | colormapping.h and recompile. |
192 | ||
193 | ||
194 | Testpages for verification | |
195 | Page | Reference | |
196 | ||
197 | Channel: 3sat | |
198 | 109 | https://blog.3sat.de/ttx/index.php?p=109_0001&c=0 ('@' char) | |
199 | 898-01 | https://blog.3sat.de/ttx/index.php?p=898_0001&c=0 | |
200 | 898-02 | https://blog.3sat.de/ttx/index.php?p=898_0002&c=0 | |
201 | 899-01 | https://blog.3sat.de/ttx/index.php?p=899_0001&c=0 | |
202 | 899-02 | https://blog.3sat.de/ttx/index.php?p=899_0002&c=0 | |
203 | ||
204 | Channel: arte | |
205 | 199-01 | |
206 | ||
207 | Channel: rbb | |
208 | 199-01 | |
209 | 199-02 | |
210 | ||
211 | Channel: ORF2 | |
212 | 886-00 | |
213 | ||
214 | Channel: ARD https://www.ard-text.de/index.php?page=<NUM> | |
215 | (currently none) | |
216 | ||
217 | Channel: ZDFinfo | |
218 | 199-01 | |
219 | 199-02 | |
220 | 199-03 | |
221 | ||
222 | Subtitle pages for verification | |
223 | ||
224 | Channel: DasErste / BR Fernsehen | |
225 | 150 | |
226 | ||
227 | Channel: 3sat | |
228 | 777 |
15 | 15 | Man kann z.B. einstellen, das die man mit der Taste Rot auf die Seite 100 springt. |
16 | 16 | Bei dieser Einstellung wäre die Aktion "Springe zu 100" der Taste Rot zugeordnet. |
17 | 17 | |
18 | Verfügbare Tasten: Blau, Rot, Gelb, Grün, Play, Stop, Schneller Vorlauf, Schn. Rücklauf | |
18 | Verfügbare Tasten: Blau, Rot, Gelb, Grün, Stop, Schneller Vorlauf, Schn. Rücklauf, OK | |
19 | 19 | Aktionen: "Vergrößern", "Halbe Seite", "Kanal wechseln", |
20 | "Hotkey Ebene+", "Hotkey Ebene-" | |
21 | "OSD Voreinstellung+", "OSD Voreinstellung-" | |
20 | 22 | "Hintergrund wechseln", "Springe zu..." einer bestimmten Seite |
21 | 23 | |
22 | 24 | Beschreibung der Aktionen: |
23 | 25 | Vergrößern: Obere / untere Hälfte vergrößern / zurück zur ganzen Seite |
26 | ||
24 | 27 | Halbe Seite: OSD-Fenster nur noch in unterer Hälfte des Bildschirms zeigen |
25 | 28 | und obere / untere Hälfte anzeigen bzw. zurück |
29 | ||
26 | 30 | Kanal wechseln:Seiten eines anderen Senders als des gerade eingestellten anzeigen. |
27 | Dabei wird keine Frequenz gewechselt oder mit VDR ein anderer Kanal eingestellt. | |
28 | Damit Seiten verfügbar sind, muss irgendwann vorher der gewählte | |
29 | Kanal eingestellt gewesen sein. Bei Aufruf der Aktion wird nach der Kanalnummer | |
31 | Falls der Sender auf dem selben Transponder oder mittels eines freien | |
32 | Tuners verfügbar ist, wird der Empfänger umgeschaltet. Andernfalls sind | |
33 | nur Seiten verfügbar, die vorher gespeichert wurden, als der Kanal | |
34 | ausgewählt wurde. Bei Aufruf der Aktion wird nach der Kanalnummer | |
30 | 35 | gefragt. Die Nummer mit den Zifferntasten eingeben und OK drücken. |
36 | Falls keine Nummer eingegeben wurde, wird zum Live-Kanal gewechselt. | |
37 | ||
31 | 38 | Springe zu...: Springt zu der entsprechenden Seite |
39 | ||
32 | 40 | Hintergrund wechseln: Ändert die im Setup einstellbare Hintergrundfarbe sofort zu Schwarz |
33 | 41 | und nach erneutem Aufruf wieder zurück. |
42 | ||
43 | Konfiguration: Aktiviere den OSD Konfigurations-Modus, aktuell unterstützt | |
44 | Links,Oben +/- | |
45 | Breite,Höhe +/- | |
46 | Rahmen +/- | |
47 | Zeichensatz | |
48 | Text Vertikaer Offset +/- | |
49 | Hintergrund Transparenz +/- | |
50 | ||
51 | 24-Zeilen-Modus: Umschalten Hotkey Zeile (Zeile 25) oder zusätzliche Hinweiszeilen (line 26+27) | |
52 | ||
53 | Antwort : Zeige versteckte Zeichen (Umschalter) | |
54 | OSD zeigt ein gelbes '?' im Fall daß die Seite versteckte Zeichen enthält | |
55 | OSD zeigt ein grünes '!' während versteckte Zeichen angezeigt werden | |
56 | ||
57 | Pause : Stoppt Aktualisierung der Seite (Umschalter) | |
58 | OSD zeigt rotes '!' während die Aktualisierug pausiert | |
59 | OSD zeigt green '>' nachdem die Pause deaktiviert wurde (bis zur nächsten Aktualisierung der Seite) | |
60 | ||
61 | ** falls eingeschaltet/aktiv ** | |
62 | OSD Preset+ : Wechsle zur nächsten OSD Voreinstellung (incl. Rollover) | |
63 | OSD Preset- : Wechsle zur vorherigen OSD Voreinstellung (incl. rollover) | |
64 | ||
65 | ** falls eingeschaltet/aktiv ** | |
66 | Hotkey Ebene+ : Wechsle zur nächsten Hotkey Ebene (incl. Rollover) | |
67 | Hotkey Ebene- : Wechsle zur vorherigen Hotkey Ebene (incl. Rollover) | |
68 | Empfohlene Zuweisung: | |
69 | FastFwd: Hotkey Ebene+ | |
70 | FastRwd: Hotkey Ebene- | |
34 | 71 | |
35 | 72 | Wie man Tasten Aktionen zuordnet: |
36 | 73 | Im Einstellungsmenü des Plugins kann jeder Taste eine Aktion zugeordnet werden. |
40 | 77 | angegeben. |
41 | 78 | |
42 | 79 | Andere Optionen: |
43 | Hintergrund-Transparenz: Zahl zwischen 0 (transparent) und 255 (schwarz). Vorgegeben ist 127 (wie auch von VDR) | |
44 | 80 | Zeige Uhr: Diese Option bestimmt, ob etwa im Sekundenabstand zusätzlich eine Uhr angezeigt wird. |
45 | 81 | Die Uhr zeigt die aktuelle Systemzeit, nicht die mit dem Videotext ausgestrahlte Zeit. |
46 | 82 | Um genaue Werte zu haben, kann VDR die Systemzeit von einem Transponder einstellen. |
47 | 83 | Automatisch aktualisieren: |
48 | 84 | Überprüft ständig, ob sich die Seite geändert hat und aktualisiert sie wenn nötig |
49 | OSD-Breite, OSD-Höhe: | |
50 | Hier kann die Breite des OSD unabhängig von den Einstellungen für VDR | |
51 | bestimmt werden. Für die Breite liegt die Zahl zwischen 40 und 56, | |
52 | für die Höhe zwischen 12 und 21. | |
85 | 16-Farben-Modus: | |
86 | Benutze nur 16 Farben (4-Bit) (für ältere DVB Karten) | |
53 | 87 | Mindest Benutzer-Inaktivität: |
54 | 88 | Bestimmt die Zeit (in Minuten), nach der das Plugin automatisch geschlossen wird, wenn |
55 | 89 | der Benutzer solange keine Taste betätigt hat. Das kann durch setzen des Wertes auf 0 |
56 | verhindert werden. Dann wird jedoch auch das automatische Abschalten von VDR effektiv | |
90 | verhindert werden. Dann wird jedoch auch das automatische Abschalten von VDR effektiv | |
57 | 91 | außer Kraft gesetzt, solange das Plugin geöffnet ist. |
92 | ||
93 | ** optional mit Unterstützung mehrerer Voreinstellungen ** | |
94 | ||
95 | OSD-Breite, OSD-Höhe: | |
96 | Hier kann die Größe des OSD unabhängig von den Einstellungen für VDR | |
97 | bestimmt werden. Valider Bereich zwischen 10% und 100% | |
98 | OSD Links, OSD Oben: | |
99 | Hier kann die linke/obere Ecke des OSD unabhängig von den Einstellungen für VDR | |
100 | bestimmt werden. Valider Bereich zwischen 0% und 90% | |
101 | Zeichensatz: | |
102 | Hier kann der Zeichensatz ausgewählt werden | |
103 | Vertikaler Text Offset: | |
104 | Justage des vertikalen Offsets für Textdarstellung bei einer (skalierten) Anzahl von Pixels | |
105 | Valider Bereich zwischen -10 und 10 (und abhängig vom ausgewählten Font) | |
106 | Hintergrund-Transparenz: Zahl zwischen 0 (schwarz) und 255 (transparenz). Vorgegeben ist 128 (wie auch von VDR) | |
107 | ||
108 | Hotkey (Farb-)Tasten einrichten: siehe oben, optional mit multi-Ebenen-Unterstützung | |
109 | ||
58 | 110 | Tasten einrichten: siehe oben |
59 | 111 | |
60 | 112 | Kommandozeilen-Optionen: |
74 | 126 | Voreinstellung ist "packed" für ein System, das |
75 | 127 | in eine Datei mehrere Seiten speichert. |
76 | 128 | -t --toptext Speichere TopText Seiten (nich anzeigbar) |
129 | -k --key-levels=NUM Maximale Anzahl von Hot Key Ebenen für Auswahl und Speicherung | |
130 | Standard: 1 (deaktiviert diese Erweiterung) | |
131 | Maximum: 9 Ebenen | |
132 | -o --osd-presets=NUM Maximale Anzahl von OSD Voreinstellungen für Auswahl und Speicherung | |
133 | Standard: 1 (deaktiviert diese Erweiterung) | |
134 | Maximum: 9 Voreinstellungen | |
135 | -P|--debugpage <int|hexint> Spezifiziere Seite für Debugging (int: intern automatisch konvertiert nach hex) | |
136 | -S|--debugpsub <int|hexint> Spezifiziere Unterseite für Debugging (int: intern automatisch konvertiert nach hex) | |
137 | -L|--debugline <int> Spezifiziere Zeile für Debugging | |
138 | -D|--debugmask <int|hexint> Aktiviere Debug-Maske (siehe logging.h für Details) | |
77 | 139 | |
78 | 140 | Farben: |
79 | 141 | Auf allen Ausgabegeräten, die nicht in der Farbtiefe des OSD beschränkt sind, |
0 | - in case "show clock" is disabled but teletext page provides clock, update related regions automatically | |
1 | Channel 3sat incl. blinking ":" | |
2 | ||
3 | - extend UTF8toTeletextChar with further mappings | |
4 | ||
5 | - extend X/26 support |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) 2005 by Udo Richter * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * display.c - Actual implementation of OSD display variants and * |
3 | 5 | * Display:: namespace that encapsulates a single cDisplay. * |
7 | 9 | * the Free Software Foundation; either version 2 of the License, or * |
8 | 10 | * (at your option) any later version. * |
9 | 11 | * * |
10 | * Changelog: * | |
11 | * 2005-03 initial version (c) Udo Richter * | |
12 | * * | |
13 | 12 | ***************************************************************************/ |
14 | 13 | |
15 | 14 | #include <strings.h> |
16 | 15 | #include <vdr/config.h> |
16 | #include <vdr/skins.h> | |
17 | 17 | #include "setup.h" |
18 | 18 | #include "display.h" |
19 | 19 | #include "txtfont.h" |
20 | #include "logging.h" | |
20 | 21 | |
21 | 22 | // Static variables of Display:: namespace |
22 | 23 | Display::Mode Display::mode=Display::Full; |
23 | 24 | cDisplay *Display::display=NULL; |
24 | 25 | |
25 | 26 | |
26 | void Display::SetMode(Display::Mode NewMode) { | |
27 | void Display::SetMode(Display::Mode NewMode, tColor clrBackground) { | |
28 | // Background is optional and default predefined in display.h | |
29 | int hChars = 40; | |
30 | int vLines = TT_DISPLAY_LINES; | |
31 | int OSDwidth; | |
32 | int OSDheight; | |
33 | int OSDleftFrame = 0; | |
34 | int OSDrightFrame = 0; | |
35 | int OSDtopFrame = 0; | |
36 | int OSDbottomFrame = 0; | |
37 | int x0 = cOsd::OsdLeft(); // start with general OSD offset | |
38 | int y0 = cOsd::OsdTop(); // start with general OSD offset | |
39 | ||
27 | 40 | // (re-)set display mode. |
28 | 41 | |
29 | if (display!=NULL && NewMode==mode) return; | |
30 | // No change, nothing to do | |
31 | ||
32 | // OSD origin, centered on VDR OSD | |
33 | int x0=Setup.OSDLeft+(Setup.OSDWidth-ttSetup.OSDwidth)*ttSetup.OSDHAlign/100; | |
34 | int y0=Setup.OSDTop +(Setup.OSDHeight-ttSetup.OSDheight)*ttSetup.OSDVAlign/100; | |
42 | if (display!=NULL && NewMode==mode) return; // No change, nothing to do | |
43 | ||
44 | // calculate from percentage and OSD maximum | |
45 | OSDwidth = (cOsd::OsdWidth() * TTSETUPPRESET(Width) ) / 100; | |
46 | OSDheight = (cOsd::OsdHeight() * TTSETUPPRESET(Height)) / 100; | |
47 | ||
48 | // align with hChars/vLines | |
49 | if ((OSDwidth % hChars) > 0) OSDwidth = (OSDwidth / hChars) * hChars; | |
50 | if ((OSDheight % vLines) > 0) OSDheight = (OSDheight / vLines) * vLines; | |
51 | ||
52 | if (TTSETUPPRESET(Width) < 100) { | |
53 | if (TTSETUPPRESET(Left) > 0) { | |
54 | // check offset not exceeding maximum possible | |
55 | if ((TTSETUPPRESET(Width) + TTSETUPPRESET(Left)) > 100) { | |
56 | // shift to maximum | |
57 | x0 += cOsd::OsdWidth() - OSDwidth; | |
58 | } else { | |
59 | // add configured offset | |
60 | x0 += (cOsd::OsdWidth() * TTSETUPPRESET(Left)) / 100; | |
61 | ||
62 | // add 50% of alignment offset to center proper | |
63 | x0 += ((cOsd::OsdWidth() * TTSETUPPRESET(Width)) / 100 - OSDwidth) / 2; | |
64 | }; | |
65 | }; | |
66 | ||
67 | if (TTSETUPPRESET(Frame) > 0) { | |
68 | OSDleftFrame = TTSETUPPRESET(Frame); | |
69 | OSDrightFrame = TTSETUPPRESET(Frame); | |
70 | ||
71 | x0 -= OSDleftFrame; | |
72 | if (x0 < cOsd::OsdLeft()) { | |
73 | OSDleftFrame += x0 - cOsd::OsdLeft(); | |
74 | x0 = cOsd::OsdLeft(); | |
75 | }; | |
76 | if (OSDleftFrame < 0) OSDleftFrame = 0; | |
77 | ||
78 | if (x0 + OSDwidth + OSDrightFrame + OSDleftFrame > cOsd::OsdWidth() + cOsd::OsdLeft()) { | |
79 | // limit right frame instead drawing out-of-area | |
80 | OSDrightFrame = cOsd::OsdWidth() - OSDwidth - x0 - OSDleftFrame + cOsd::OsdLeft(); | |
81 | if (OSDrightFrame < 0) OSDrightFrame = 0; | |
82 | }; | |
83 | }; | |
84 | } else { | |
85 | // horizontal center with black frame left/right | |
86 | OSDleftFrame = (cOsd::OsdWidth() - OSDwidth) / 2; | |
87 | OSDrightFrame = cOsd::OsdWidth() - OSDwidth - OSDleftFrame; | |
88 | ||
89 | if ((OSDleftFrame > 0) && (OSDleftFrame > TTSETUPPRESET(Frame))) { | |
90 | x0 += OSDleftFrame - TTSETUPPRESET(Frame); | |
91 | OSDleftFrame = TTSETUPPRESET(Frame); | |
92 | }; | |
93 | ||
94 | if ((OSDrightFrame > 0) && (OSDrightFrame > TTSETUPPRESET(Frame))) { | |
95 | OSDrightFrame = TTSETUPPRESET(Frame); | |
96 | }; | |
97 | }; | |
98 | ||
99 | if (TTSETUPPRESET(Height) < 100) { | |
100 | if (TTSETUPPRESET(Top) > 0) { | |
101 | // check offset not exceeding maximum possible | |
102 | if ((TTSETUPPRESET(Height) + TTSETUPPRESET(Top)) > 100) { | |
103 | // shift to maximum | |
104 | y0 += cOsd::OsdHeight() - OSDheight; | |
105 | } else { | |
106 | // add configured offset | |
107 | y0 += (cOsd::OsdHeight() * TTSETUPPRESET(Top)) / 100; | |
108 | ||
109 | // add 50% of alignment offset to center proper | |
110 | y0 += ((cOsd::OsdHeight() * TTSETUPPRESET(Height)) / 100 - OSDheight) / 2; | |
111 | }; | |
112 | }; | |
113 | ||
114 | if (TTSETUPPRESET(Frame) > 0) { | |
115 | OSDtopFrame = TTSETUPPRESET(Frame); | |
116 | OSDbottomFrame = TTSETUPPRESET(Frame); | |
117 | ||
118 | y0 -= OSDtopFrame; | |
119 | if (y0 < cOsd::OsdTop()) { | |
120 | OSDtopFrame += y0 - cOsd::OsdTop(); | |
121 | y0 = cOsd::OsdTop(); | |
122 | }; | |
123 | if (OSDtopFrame < 0) OSDtopFrame = 0; | |
124 | ||
125 | if (y0 + OSDheight + OSDtopFrame + OSDbottomFrame > cOsd::OsdHeight() + cOsd::OsdTop()) { | |
126 | // limit bottom frame instead drawing out-of-area | |
127 | OSDbottomFrame = cOsd::OsdHeight() - OSDheight - y0 - OSDtopFrame + cOsd::OsdTop(); | |
128 | if (OSDbottomFrame < 0) OSDbottomFrame = 0; | |
129 | }; | |
130 | }; | |
131 | } else { | |
132 | // vertical center with black frame top/bottom | |
133 | OSDtopFrame = (cOsd::OsdHeight() - OSDheight) / 2; | |
134 | OSDbottomFrame = cOsd::OsdHeight() - OSDheight - OSDtopFrame; | |
135 | ||
136 | if ((OSDtopFrame > 0) && (OSDtopFrame > TTSETUPPRESET(Frame))) { | |
137 | y0 += OSDtopFrame - TTSETUPPRESET(Frame); | |
138 | OSDtopFrame = TTSETUPPRESET(Frame); | |
139 | }; | |
140 | ||
141 | if ((OSDbottomFrame > 0) && (OSDbottomFrame > TTSETUPPRESET(Frame))) { | |
142 | OSDbottomFrame = TTSETUPPRESET(Frame); | |
143 | }; | |
144 | }; | |
145 | ||
146 | DEBUG_OT_AREA("osdteletext: OSD area calculated by percent values: OL=%d OT=%d OW=%d OH=%d OwP=%d%% OhP=%d%% OlP=%d%% OtP=%d%% OfPx=%d lineMode24=%d => x0=%d y0=%d Ow=%d Oh=%d OlF=%d OrF=%d OtF=%d ObF=%d" | |
147 | , cOsd::OsdLeft(), cOsd::OsdTop(), cOsd::OsdWidth(), cOsd::OsdHeight() | |
148 | , TTSETUPPRESET(Width), TTSETUPPRESET(Height), TTSETUPPRESET(Left), TTSETUPPRESET(Top) | |
149 | , TTSETUPPRESET(Frame) | |
150 | , ttSetup.lineMode24 | |
151 | , x0, y0 | |
152 | , OSDwidth, OSDheight | |
153 | , OSDleftFrame, OSDrightFrame | |
154 | , OSDtopFrame, OSDbottomFrame | |
155 | ); | |
35 | 156 | |
36 | 157 | switch (NewMode) { |
37 | case Display::Full: | |
38 | // Need to re-initialize *display: | |
158 | case Display::Full: | |
159 | // Need to re-initialize *display: | |
160 | DEBUG_OT_DBFC("osdteletext: OSD 'full' Full->reinit display"); | |
39 | 161 | Delete(); |
40 | 162 | // Try 32BPP display first: |
41 | display=new cDisplay32BPP(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight); | |
42 | break; | |
43 | case Display::HalfUpper: | |
163 | display=new cDisplay32BPP(x0,y0,OSDwidth,OSDheight,OSDleftFrame,OSDrightFrame,OSDtopFrame,OSDbottomFrame,clrBackground); | |
164 | break; | |
165 | case Display::HalfUpper: | |
44 | 166 | // Shortcut to switch from HalfUpper to HalfLower: |
45 | 167 | if (mode==Display::HalfLower) { |
168 | DEBUG_OT_DBFC("osdteletext: OSD 'half' shortcut HalfUpper->HalfLower"); | |
46 | 169 | // keep instance. |
170 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Upper); | |
47 | 171 | ((cDisplay32BPPHalf*)display)->SetUpper(true); |
172 | ((cDisplay32BPPHalf*)display)->SetTop(false); | |
48 | 173 | break; |
49 | 174 | } |
50 | 175 | // Need to re-initialize *display: |
51 | Delete(); | |
52 | display=new cDisplay32BPPHalf(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight,true); | |
53 | break; | |
54 | case Display::HalfLower: | |
176 | DEBUG_OT_DBFC("osdteletext: OSD 'half' HalfUpper->reinit display"); | |
177 | Delete(); | |
178 | display=new cDisplay32BPPHalf(x0,y0,OSDwidth,OSDheight,OSDleftFrame,OSDrightFrame,OSDtopFrame,OSDbottomFrame,true,false,clrBackground); | |
179 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Upper); | |
180 | break; | |
181 | case Display::HalfUpperTop: | |
182 | // Shortcut to switch from HalfUpperTop to HalfLowerTop: | |
183 | if (mode==Display::HalfLowerTop) { | |
184 | // keep instance. | |
185 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Upper); | |
186 | ((cDisplay32BPPHalf*)display)->SetUpper(true); | |
187 | ((cDisplay32BPPHalf*)display)->SetTop(true); | |
188 | break; | |
189 | } | |
190 | // Need to re-initialize *display: | |
191 | DEBUG_OT_DBFC("osdteletext: OSD 'half' HalfUpperTop->reinit display"); | |
192 | Delete(); | |
193 | display=new cDisplay32BPPHalf(x0,y0,OSDwidth,OSDheight,OSDleftFrame,OSDrightFrame,OSDtopFrame,OSDbottomFrame,true,true,clrBackground); | |
194 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Upper); | |
195 | break; | |
196 | case Display::HalfLower: | |
55 | 197 | // Shortcut to switch from HalfUpper to HalfLower: |
56 | 198 | if (mode==Display::HalfUpper) { |
199 | DEBUG_OT_DBFC("osdteletext: OSD 'half' shortcut HalfLower->HalfUpper"); | |
57 | 200 | // keep instance. |
201 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Lower); | |
58 | 202 | ((cDisplay32BPPHalf*)display)->SetUpper(false); |
203 | ((cDisplay32BPPHalf*)display)->SetTop(false); | |
59 | 204 | break; |
60 | 205 | } |
61 | 206 | // Need to re-initialize *display: |
62 | Delete(); | |
63 | display=new cDisplay32BPPHalf(x0,y0,ttSetup.OSDwidth,ttSetup.OSDheight,false); | |
207 | DEBUG_OT_DBFC("osdteletext: OSD 'half' HalfLower->reinit display"); | |
208 | Delete(); | |
209 | display=new cDisplay32BPPHalf(x0,y0,OSDwidth,OSDheight,OSDleftFrame,OSDrightFrame,OSDtopFrame,OSDbottomFrame,false,false,clrBackground); | |
210 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Lower); | |
211 | break; | |
212 | case Display::HalfLowerTop: | |
213 | // Shortcut to switch from HalfUpperTop to HalfLowerTop: | |
214 | if (mode==Display::HalfUpperTop) { | |
215 | DEBUG_OT_DBFC("osdteletext: OSD 'half' shortcut HalfUpperTop->HalfLowerTop"); | |
216 | // keep instance. | |
217 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Lower); | |
218 | ((cDisplay32BPPHalf*)display)->SetUpper(false); | |
219 | ((cDisplay32BPPHalf*)display)->SetTop(true); | |
220 | break; | |
221 | } | |
222 | // Need to re-initialize *display: | |
223 | DEBUG_OT_DBFC("osdteletext: OSD 'half' HalfLowerTop->reinit display"); | |
224 | Delete(); | |
225 | display=new cDisplay32BPPHalf(x0,y0,OSDwidth,OSDheight,OSDleftFrame,OSDrightFrame,OSDtopFrame,OSDbottomFrame,false,true,clrBackground); | |
226 | ((cDisplay32BPPHalf*)display)->SetZoom(cDisplay::Zoom_Lower); | |
64 | 227 | break; |
65 | 228 | } |
66 | 229 | mode=NewMode; |
67 | 230 | // If display is invalid, clean up immediately: |
68 | 231 | if (!display->Valid()) Delete(); |
69 | // Pass through OSD black transparency | |
70 | SetBackgroundColor((tColor)ttSetup.configuredClrBackground); | |
71 | 232 | } |
72 | 233 | |
73 | 234 | void Display::ShowUpperHalf() { |
79 | 240 | } |
80 | 241 | |
81 | 242 | |
82 | cDisplay32BPP::cDisplay32BPP(int x0, int y0, int width, int height) | |
243 | cDisplay32BPP::cDisplay32BPP(int x0, int y0, int width, int height, int leftFrame, int rightFrame, int topFrame, int bottomFrame, tColor clrBackground) | |
83 | 244 | : cDisplay(width,height) { |
84 | 245 | // 32BPP display for True Color OSD providers |
85 | 246 | |
86 | 247 | osd = cOsdProvider::NewOsd(x0, y0); |
87 | 248 | if (!osd) return; |
88 | 249 | |
250 | Background = clrBackground; | |
251 | ||
89 | 252 | width=(width+1)&~1; |
90 | 253 | // Width has to end on byte boundary, so round up |
91 | 254 | |
92 | tArea Areas[] = { { 0, 0, width - 1, height - 1, 32 } }; | |
255 | int bpp = 32; | |
256 | if (ttSetup.colorMode4bpp == true) { | |
257 | bpp = 4; | |
258 | dsyslog("osdteletext: OSD config forced to bpp=%d", bpp); | |
259 | }; | |
260 | tArea Areas[] = { { 0, 0, width - 1 + leftFrame + rightFrame, height - 1 + topFrame + bottomFrame, bpp } }; | |
261 | if (bpp == 32 && (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk)) { | |
262 | bpp = 8; | |
263 | Areas[0].bpp = 8; | |
264 | DEBUG_OT_AREA("osdteletext: OSD is not providing TrueColor, fallback to bpp=%d", bpp); | |
265 | } | |
93 | 266 | if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk) { |
94 | 267 | DELETENULL(osd); |
268 | esyslog("osdteletext: can't create requested OSD area with x0=%d y0=%d width=%d height=%d bpp=%d osdPreset=%d", x0, y0, width, height, bpp | |
269 | , ttSetup.osdPreset | |
270 | ); | |
271 | Skins.Message(mtError, "OSD-Teletext can't request OSD area, check plugin settings"); | |
95 | 272 | return; |
96 | 273 | } |
97 | 274 | osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); |
98 | 275 | |
99 | 276 | setOutputWidth(width); |
100 | 277 | setOutputHeight(Height); |
101 | ||
102 | #if defined(APIVERSNUM) && APIVERSNUM >= 20107 | |
103 | Width = 480; | |
104 | Height = 250; | |
105 | #endif | |
106 | ||
107 | esyslog("OSD-Teletext: 32BPP"); | |
278 | setLeftFrame(leftFrame); | |
279 | setRightFrame(rightFrame); | |
280 | setTopFrame(topFrame); | |
281 | setBottomFrame(bottomFrame); | |
282 | ||
283 | isyslog("osdteletext: OSD area successful requested with x0=%d y0=%d width=%d height=%d bpp=%d lF=%d rF=%d tF=%d bF=%d bg=0x%08x osdPreset=%d" | |
284 | , x0, y0, width, height, bpp | |
285 | , leftFrame, rightFrame, topFrame, bottomFrame | |
286 | , clrBackground | |
287 | , ttSetup.osdPreset | |
288 | ); | |
108 | 289 | |
109 | 290 | InitScaler(); |
110 | 291 | |
111 | 292 | CleanDisplay(); |
112 | } | |
113 | ||
114 | ||
115 | cDisplay32BPPHalf::cDisplay32BPPHalf(int x0, int y0, int width, int height, bool upper) | |
116 | : cDisplay(width,height), Upper(upper), OsdX0(x0), OsdY0(y0) | |
293 | Dirty=true; | |
294 | DirtyAll=true; | |
295 | } | |
296 | ||
297 | ||
298 | cDisplay32BPPHalf::cDisplay32BPPHalf(int x0, int y0, int width, int height, int leftFrame, int rightFrame, int topFrame, int bottomFrame, bool upper, bool top, tColor clrBackground) | |
299 | : cDisplay(width,height), leftFrame(leftFrame) | |
300 | , rightFrame(rightFrame), topFrame(topFrame), bottomFrame(bottomFrame) | |
301 | , Upper(upper), Top(top), OsdX0(x0), OsdY0(y0) | |
117 | 302 | { |
118 | 303 | osd=NULL; |
119 | 304 | |
305 | Background = clrBackground; | |
306 | ||
120 | 307 | // Redirect all real init work to method |
121 | 308 | InitOSD(); |
122 | 309 | } |
123 | 310 | |
124 | 311 | void cDisplay32BPPHalf::InitOSD() { |
125 | 312 | delete osd; |
126 | osd = cOsdProvider::NewOsd(OsdX0, OsdY0); | |
313 | int x0 = OsdX0; | |
314 | ||
315 | int height = Height / 2; // half heigth | |
316 | int vLines = TT_DISPLAY_LINES; | |
317 | if ((height % vLines) > 0) height = (height / vLines) * vLines; // alignment | |
318 | ||
319 | int y0 = OsdY0; | |
320 | if (!Top) | |
321 | y0 += Height - height; // calculate y-offset | |
322 | ||
323 | osd = cOsdProvider::NewOsd(x0, y0); | |
127 | 324 | if (!osd) return; |
128 | 325 | |
129 | int width=(Width+1)&~1; | |
130 | // Width has to end on byte boundary, so round up | |
131 | ||
132 | tArea Areas[] = { { 0, 0, width - 1, Height - 1, 32 } }; | |
326 | int width=(Width+1)&~1; // Width has to end on byte boundary, so round up | |
327 | ||
328 | int bpp = 32; | |
329 | if (ttSetup.colorMode4bpp == true) { | |
330 | bpp = 4; | |
331 | dsyslog("osdteletext: OSD config forced to bpp=%d", bpp); | |
332 | }; | |
333 | tArea Areas[] = { { 0, 0, width - 1 + leftFrame + rightFrame, height - 1 + topFrame + bottomFrame, bpp } }; | |
334 | if (bpp == 32 && (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk)) { | |
335 | bpp = 8; | |
336 | Areas[0].bpp = 8; | |
337 | DEBUG_OT_AREA("osdteletext: OSD is not providing TrueColor, fallback to bpp=%d", bpp); | |
338 | } | |
339 | if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk) { | |
340 | DELETENULL(osd); | |
341 | esyslog("osdteletext: can't create requested OSD 'half' area with x0=%d y0=%d width=%d height=%d bpp=%d", x0, y0, width, height, bpp); | |
342 | Skins.Message(mtError, "OSD-Teletext can't request OSD 'half' area, check plugin settings"); | |
343 | return; | |
344 | } | |
345 | /* | |
133 | 346 | // Try full-size area first |
134 | ||
135 | 347 | while (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) != oeOk) { |
136 | 348 | // Out of memory, so shrink |
137 | 349 | if (Upper) { |
154 | 366 | } else { |
155 | 367 | Areas[0].y1=Areas[0].y1+10; |
156 | 368 | } |
157 | ||
369 | */ | |
158 | 370 | osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); |
159 | 371 | |
372 | isyslog("osdteletext: OSD 'half' area successful requested x0=%d y0=%d width=%d height=%d bpp=%d lF=%d rF=%d tF=%d bF=%d Upper=%s Top=%s" | |
373 | , x0, y0, width, height, bpp | |
374 | , leftFrame, rightFrame, topFrame, bottomFrame | |
375 | , (Upper == true) ? "yes" : "no" | |
376 | , (Top == true) ? "yes" : "no" | |
377 | ); | |
378 | ||
160 | 379 | setOutputWidth(width); |
161 | setOutputHeight(Height); | |
162 | ||
163 | #if defined(APIVERSNUM) && APIVERSNUM >= 20107 | |
164 | Width = 480; | |
165 | Height = 250; | |
166 | #endif | |
380 | setOutputHeight(height); | |
381 | setLeftFrame(leftFrame); | |
382 | setRightFrame(rightFrame); | |
383 | setTopFrame(topFrame); | |
384 | setBottomFrame(bottomFrame); | |
167 | 385 | |
168 | 386 | InitScaler(); |
169 | 387 | |
388 | // In case we switched on the fly, do a full redraw | |
170 | 389 | CleanDisplay(); |
171 | ||
172 | // In case we switched on the fly, do a full redraw | |
173 | 390 | Dirty=true; |
174 | 391 | DirtyAll=true; |
175 | 392 | Flush(); |
176 | 393 | } |
394 | ||
395 | // vim: ts=4 sw=4 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) 2005 by Udo Richter * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * display.h - Actual implementation of OSD display variants and * |
3 | 5 | * Display:: namespace that encapsulates a single cDisplay. * |
6 | 8 | * it under the terms of the GNU General Public License as published by * |
7 | 9 | * the Free Software Foundation; either version 2 of the License, or * |
8 | 10 | * (at your option) any later version. * |
9 | * * | |
10 | * Changelog: * | |
11 | * 2005-03 initial version (c) Udo Richter * | |
12 | 11 | * * |
13 | 12 | ***************************************************************************/ |
14 | 13 | |
23 | 22 | // and allows NULL-safe access to display members. |
24 | 23 | // Additionally, selects via mode the actually used instance for *display. |
25 | 24 | |
26 | enum Mode { Full, HalfUpper, HalfLower }; | |
25 | enum Mode { Full, HalfUpper, HalfLower, HalfUpperTop, HalfLowerTop }; | |
27 | 26 | // Full mode: 2BPP or 4BPP full screen display, depending on memory constrains |
28 | 27 | // HalfUpper: 4BPP display of upper half, drop lower half if out of memory |
29 | 28 | // HalfLower: 4BPP display of lower half, drop upper half if out of memory |
29 | // *Top: display top of screen (default: bottom) | |
30 | 30 | |
31 | 31 | extern Mode mode; |
32 | 32 | extern cDisplay *display; |
33 | 33 | |
34 | 34 | // Access to display mode: |
35 | void SetMode(Display::Mode mode); | |
35 | void SetMode(Display::Mode mode, tColor clrBackground = TTSETUPPRESET_TCOLOR(BackTrans)); | |
36 | 36 | inline void Delete() |
37 | 37 | { if (display) { DELETENULL(display); } } |
38 | 38 | |
45 | 45 | inline bool GetBlink() |
46 | 46 | { if (display) return display->GetBlink(); else return false; } |
47 | 47 | inline bool SetBlink(bool blink) |
48 | { if (display) display->SetBlink(blink); else return false; } | |
48 | { if (display) return display->SetBlink(blink); else return false; } | |
49 | 49 | inline bool GetConceal() |
50 | 50 | { if (display) return display->GetConceal(); else return false; } |
51 | 51 | inline bool SetConceal(bool conceal) |
52 | { if (display) display->SetConceal(conceal); else return false; } | |
52 | { if (display) return display->SetConceal(conceal); else return false; } | |
53 | inline bool GetPaused() | |
54 | { if (display) return display->GetPaused(); else return false; } | |
55 | inline void SetPaused(bool paused) | |
56 | { if (display) return display->SetPaused(paused); else return; } | |
57 | inline bool HasConceal() | |
58 | { if (display) return display->HasConceal(); else return false; } | |
53 | 59 | inline cDisplay::enumZoom GetZoom() |
54 | 60 | { if (display) return display->GetZoom(); else return cDisplay::Zoom_Off; } |
55 | 61 | inline void SetZoom(cDisplay::enumZoom zoom) |
71 | 77 | |
72 | 78 | inline void DrawClock() |
73 | 79 | { if (display) display->DrawClock(); } |
80 | ||
74 | 81 | inline void DrawPageId(const char *text) |
75 | 82 | { if (display) display->DrawPageId(text); } |
83 | inline void DrawPageId(const char *text, const enumTeletextColor cText) | |
84 | { if (display) display->DrawPageId(text, cText); } | |
85 | inline void DrawPageId(const char *text, const enumTeletextColor cText, const bool boxedAlwaysOn) | |
86 | { if (display) display->DrawPageId(text, cText, boxedAlwaysOn); } | |
87 | ||
88 | inline void DrawHotkey(const char *textRed, const char *textGreen, const char* textYellow, const char *textBlue, const HotkeyFlags flag) | |
89 | { if (display) display->DrawHotkey(textRed, textGreen, textYellow, textBlue, flag); } | |
90 | ||
91 | inline void DrawHints(const char *textH1, const char *textH2, const char* textH3, const char *textH4, const char *textH5, const HintsFlags flag) | |
92 | { if (display) display->DrawHints(textH1, textH2, textH3, textH4, textH5, flag); } | |
93 | ||
76 | 94 | inline void DrawMessage(const char *txt) |
77 | { if (display) display->DrawMessage(txt); } | |
95 | { if (display) display->DrawMessage(txt, NULL); } | |
96 | inline void DrawMessage(const char *txt, const char *txt2) | |
97 | { if (display) display->DrawMessage(txt, txt2); } | |
98 | ||
99 | inline void DrawMessage(const char *txt, const enumTeletextColor cFrame) | |
100 | { if (display) display->DrawMessage(txt, NULL, cFrame); } | |
101 | inline void DrawMessage(const char *txt, const char *txt2, const enumTeletextColor cFrame) | |
102 | { if (display) display->DrawMessage(txt, txt2, cFrame); } | |
103 | ||
104 | inline void DrawMessage(const char *txt, const enumTeletextColor cFrame, const enumTeletextColor cText) | |
105 | { if (display) display->DrawMessage(txt, NULL, cFrame, cText); } | |
106 | inline void DrawMessage(const char *txt, const char *txt2, const enumTeletextColor cFrame, const enumTeletextColor cText) | |
107 | { if (display) display->DrawMessage(txt, txt2, cFrame, cText); } | |
108 | ||
109 | inline void DrawMessage(const char *txt, const enumTeletextColor cFrame, const enumTeletextColor cText, const enumTeletextColor cBackground) | |
110 | { if (display) display->DrawMessage(txt, NULL, cFrame, cText, cBackground); } | |
111 | inline void DrawMessage(const char *txt, const char *txt2, const enumTeletextColor cFrame, const enumTeletextColor cText, const enumTeletextColor cBackground) | |
112 | { if (display) display->DrawMessage(txt, txt2, cFrame, cText, cBackground); } | |
113 | ||
78 | 114 | inline void ClearMessage() |
79 | 115 | { if (display) display->ClearMessage(); } |
116 | inline void ClearPage() | |
117 | { if (display) display->ClearPage(); } | |
80 | 118 | } |
81 | 119 | |
82 | 120 | |
85 | 123 | // No need for color mapping |
86 | 124 | // Uses cPixmap instead of cBitmap |
87 | 125 | public: |
88 | cDisplay32BPP(int x0, int y0, int width, int height); | |
126 | cDisplay32BPP(int x0, int y0, int width, int height, int leftFrame, int rightFrame, int topFrame, int bottomFrame, tColor clrBackground); | |
89 | 127 | }; |
90 | 128 | |
91 | 129 | |
92 | 130 | |
93 | 131 | class cDisplay32BPPHalf : public cDisplay { |
132 | int leftFrame, rightFrame, topFrame, bottomFrame; | |
133 | // frame border | |
134 | ||
94 | 135 | // 32BPP (true color) OSD display with auto size reduction on memory constrains |
95 | 136 | // Automatically tries to make visible area as big as possible |
96 | 137 | // No need for color mapping |
97 | 138 | bool Upper; |
98 | 139 | // Prefer to show upper half or lower half? |
140 | bool Top; | |
141 | // Prefer to show half on top or bottom? | |
99 | 142 | |
100 | 143 | int OsdX0,OsdY0; |
101 | 144 | // Needed to re-initialize osd |
102 | 145 | |
103 | 146 | public: |
104 | cDisplay32BPPHalf(int x0, int y0, int width, int height, bool upper); | |
147 | cDisplay32BPPHalf(int x0, int y0, int width, int height, int leftFrame, int rightFrame, int topFrame, int bottomFrame, bool upper, bool top, tColor clrBackground); | |
105 | 148 | bool GetUpper() { return Upper; } |
106 | 149 | void SetUpper(bool upper) |
107 | { if (Upper!=upper) { Upper=upper; InitOSD(); } } | |
150 | { if (Upper!=upper) { Upper=upper; } } | |
151 | void SetTop(bool top) | |
152 | { if (Top!=top) { Top=top; } } | |
108 | 153 | protected: |
109 | 154 | void InitOSD(); |
110 | 155 | }; |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) 2005 by Udo Richter * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * displaybase.c - Base class for rendering a teletext cRenderPage to * |
3 | 5 | * an actual VDR OSD. * |
7 | 9 | * the Free Software Foundation; either version 2 of the License, or * |
8 | 10 | * (at your option) any later version. * |
9 | 11 | * * |
10 | * Changelog: * | |
11 | * 2005-03 initial version (c) Udo Richter * | |
12 | * * | |
13 | 12 | ***************************************************************************/ |
14 | 13 | |
15 | 14 | #include <strings.h> |
18 | 17 | #include "displaybase.h" |
19 | 18 | #include "txtfont.h" |
20 | 19 | #include <iostream> |
21 | ||
22 | std::string cDisplay::GFXFontFootprint = ""; | |
20 | #include "logging.h" | |
21 | ||
23 | 22 | std::string cDisplay::TXTFontFootprint = ""; |
24 | int cDisplay::realFontWidths[8] = {0}; | |
23 | int cDisplay::realFontWidths[5] = {0}; | |
24 | int cDisplay::realFontHeights[5] = {0}; | |
25 | 25 | |
26 | 26 | cDisplay::cDisplay(int width, int height) |
27 | : Zoom(Zoom_Off), Concealed(false), Blinked(false), FlushLock(0), | |
27 | : Zoom(Zoom_Off), Concealed(true), Blinked(false), FlushLock(0), | |
28 | 28 | Boxed(false), Width(width), Height(height), Background(clrGray50), |
29 | osd(NULL), outputWidth(0), outputScaleX(1.0), | |
30 | outputHeight(0), outputScaleY(1.0), | |
31 | ScaleX(1), ScaleY(1), OffsetX(0), OffsetY(0), | |
29 | Paused(false), | |
30 | PageIdDisplayedEver(false), | |
31 | osd(NULL), | |
32 | outputWidth(0), outputHeight(0), | |
33 | leftFrame(0), rightFrame(0), topFrame(0), bottomFrame(0), | |
32 | 34 | MessageFont(cFont::GetFont(fontSml)), MessageX(0), MessageY(0), |
33 | 35 | MessageW(0), MessageH(0), |
34 | GFXFont(0), GFXDblWFont(0), GFXDblHFont(0), GFXDblHWFont(0), | |
35 | TXTFont(0), TXTDblWFont(0), TXTDblHFont(0), TXTDblHWFont(0) | |
36 | TXTFont(0), TXTDblWFont(0), TXTDblHFont(0), TXTDblHWFont(0), TXTHlfHFont(0) | |
36 | 37 | { |
37 | 38 | } |
38 | 39 | |
39 | 40 | cDisplay::~cDisplay() { |
40 | 41 | DELETENULL(osd); |
41 | DELETENULL(GFXFont); | |
42 | DELETENULL(GFXDblWFont); | |
43 | DELETENULL(GFXDblHFont); | |
44 | DELETENULL(GFXDblHWFont); | |
45 | 42 | DELETENULL(TXTFont); |
46 | 43 | DELETENULL(TXTDblWFont); |
47 | 44 | DELETENULL(TXTDblHFont); |
48 | 45 | DELETENULL(TXTDblHWFont); |
49 | } | |
50 | ||
51 | // This is an ugly hack, any ideas on how to get font size with characters (glyphs) of specified width/height? | |
46 | DELETENULL(TXTHlfHFont); | |
47 | } | |
48 | ||
49 | // This is an improved detection mechanism (still ugly hack, any ideas on how to get font size with characters (glyphs) of specified width/height?) | |
50 | // TODO: shrinking in case of italic fonts | |
52 | 51 | cFont *cDisplay::GetFont(const char *name, int fontIndex, int height, int width) { |
52 | const int heightOrig = height; | |
53 | const int widthOrig = width; | |
54 | DEBUG_OT_FONT("called with font %s index %d with requested w=%3d h=%3d", name, fontIndex, widthOrig, heightOrig); | |
53 | 55 | cFont *font = cFont::CreateFont(name, height, width); |
54 | 56 | if (font != NULL) { |
55 | int realWidth = font->Width(' '); | |
56 | for (int i = width * width / realWidth; i < width * 4; i++) { | |
57 | DELETENULL(font); | |
58 | font = cFont::CreateFont(name, height, i); | |
59 | if (font != NULL) { | |
60 | realWidth = font->Width(' '); | |
61 | if (realWidth > width) { | |
62 | DELETENULL(font); | |
63 | width = i - 1; | |
64 | font = cFont::CreateFont(name, height, width); | |
65 | realFontWidths[fontIndex] = width; | |
66 | break; | |
57 | int realWidth = font->Width('W'); | |
58 | int realHeight = font->Height(); | |
59 | DEBUG_OT_FONT("INITIAL fontWidth =%3d -> realWidth =%3d requestedWidth =%3d", width, realWidth, widthOrig); | |
60 | if (realWidth > 0) { | |
61 | for (int i = (width * width) / realWidth; i < width * 4; i++) { | |
62 | DELETENULL(font); | |
63 | font = cFont::CreateFont(name, heightOrig, i); | |
64 | if (font != NULL) { | |
65 | realWidth = font->Width('W'); | |
66 | DEBUG_OT_FONT("TEST result fontWidth =%3d -> realWidth =%3d %s requestedWidth =%3d" | |
67 | , i, realWidth | |
68 | , (realWidth > widthOrig) ? "> " : "<=" | |
69 | , widthOrig); | |
70 | if (realWidth > widthOrig) { | |
71 | // too large, select last one and finish | |
72 | width = i - 1; | |
73 | realFontWidths[fontIndex] = width; // store in cache | |
74 | break; | |
75 | } | |
67 | 76 | } |
68 | 77 | } |
78 | } else { | |
79 | esyslog("osdteletext: font %s returned realWidth of 0 (should not happen, please try a different font)", name); | |
69 | 80 | } |
70 | } | |
81 | ||
82 | DEBUG_OT_FONT("INITIAL fontHeight=%3d -> realHeight=%3d requestedHeight=%3d", height, realHeight, heightOrig); | |
83 | if (realHeight > 0) { | |
84 | for (int i = height * height / realHeight; i < height * 4; i++) { | |
85 | DELETENULL(font); | |
86 | font = cFont::CreateFont(name, i, widthOrig); | |
87 | if (font != NULL) { | |
88 | realHeight = font->Height(); | |
89 | DEBUG_OT_FONT("TEST result fontHeight=%3d -> realHeight=%3d %s requestedHeight=%3d" | |
90 | , i, realHeight | |
91 | , (realHeight > heightOrig) ? "> " : "<=" | |
92 | , heightOrig); | |
93 | if (realHeight > heightOrig) { | |
94 | // too large, select last one and finish | |
95 | height = i - 1; | |
96 | realFontHeights[fontIndex] = height; // store in cache | |
97 | break; | |
98 | } | |
99 | } | |
100 | } | |
101 | } else { | |
102 | esyslog("osdteletext: font %s returned realHeight of 0 (should not happen, please try a different font)", name); | |
103 | } | |
104 | } | |
105 | ||
106 | DELETENULL(font); | |
107 | font = cFont::CreateFont(name, height, width); // recreate with final height and width from above | |
108 | ||
109 | DEBUG_OT_FONT("font %s index %d with requested w=%3d h=%3d => probed size w=%3d h=%3d", name, fontIndex, widthOrig, heightOrig, width, height); | |
71 | 110 | return font; |
72 | 111 | } |
73 | 112 | |
79 | 118 | // Set up the scaling factors. Also do zoom mode by |
80 | 119 | // scaling differently. |
81 | 120 | |
82 | outputScaleX = (double)outputWidth/480.0; | |
83 | outputScaleY = (double)outputHeight/250.0; | |
84 | ||
85 | int height=Height-6; | |
86 | int width=Width-6; | |
87 | OffsetX=3; | |
88 | OffsetY=3; | |
89 | ||
90 | switch (Zoom) { | |
91 | case Zoom_Upper: | |
92 | height=height*2; | |
93 | break; | |
94 | case Zoom_Lower: | |
95 | OffsetY=OffsetY-height; | |
96 | height=height*2; | |
97 | break; | |
98 | default:; | |
99 | } | |
100 | ||
101 | ScaleX=(480<<16)/width; | |
102 | ScaleY=(250<<16)/height; | |
103 | ||
104 | fontWidth = outputWidth * 2 / 40; | |
121 | fontWidth = (outputWidth * 2 / 40) & 0xfffe; | |
105 | 122 | if (Zoom == Zoom_Off) { |
106 | fontHeight = outputHeight * 2 / 25; | |
123 | fontHeight = (outputHeight * 2 / TT_DISPLAY_LINES) & 0xfffe; | |
107 | 124 | } else { |
108 | fontHeight = outputHeight * 2 / 13; | |
109 | } | |
110 | ||
111 | int gfxFontWidth = fontWidth; | |
112 | int gfxFontHeight = fontHeight; | |
113 | const char *gfxFontName = "teletext2:Medium"; | |
114 | std::string footprint = GetFontFootprint(gfxFontName); | |
115 | ||
116 | if (footprint.compare(GFXFontFootprint) == 0) { | |
117 | GFXFont = cFont::CreateFont(gfxFontName, gfxFontHeight / 2, realFontWidths[0]); | |
118 | GFXDblWFont = cFont::CreateFont(gfxFontName, gfxFontHeight / 2, realFontWidths[1]); | |
119 | GFXDblHFont = cFont::CreateFont(gfxFontName, gfxFontHeight , realFontWidths[2]); | |
120 | GFXDblHWFont = cFont::CreateFont(gfxFontName, gfxFontHeight, realFontWidths[3]); | |
121 | } else { | |
122 | GFXFontFootprint = footprint; | |
123 | GFXFont = GetFont(gfxFontName, 0, gfxFontHeight / 2, gfxFontWidth / 2); | |
124 | GFXDblWFont = GetFont(gfxFontName, 1, gfxFontHeight / 2, gfxFontWidth); | |
125 | GFXDblHFont = GetFont(gfxFontName, 2, gfxFontHeight , gfxFontWidth / 2); | |
126 | GFXDblHWFont = GetFont(gfxFontName, 3, gfxFontHeight, gfxFontWidth); | |
127 | } | |
128 | ||
125 | fontHeight = (outputHeight * 2 * 2 / TT_DISPLAY_LINES) & 0xfffe; | |
126 | } | |
127 | // use even font size for double sized characters (prevents rounding errors during character display) | |
128 | fontWidth &= 0xfffe; | |
129 | fontHeight &= 0xfffe; | |
130 | ||
131 | DEBUG_OT_SCALER("osdteletext: InitScaler width=%d height=%d fontWidth*2=%d fontHeight=%d lineMode24=%d Zoom=%d", outputWidth, outputHeight, fontWidth, fontHeight, ttSetup.lineMode24, Zoom); | |
129 | 132 | |
130 | 133 | int txtFontWidth = fontWidth; |
131 | 134 | int txtFontHeight = fontHeight; |
132 | const char *txtFontName = ttSetup.txtFontName; | |
133 | footprint = GetFontFootprint(txtFontName); | |
134 | ||
135 | const char *txtFontName = TTSETUPPRESET_FONTNAME(Font); | |
136 | std::string footprint = GetFontFootprint(txtFontName); | |
135 | 137 | if (footprint.compare(TXTFontFootprint) == 0) { |
136 | TXTFont = cFont::CreateFont(txtFontName, txtFontHeight / 2, realFontWidths[4]); | |
137 | TXTDblWFont = cFont::CreateFont(txtFontName, txtFontHeight / 2, realFontWidths[5]); | |
138 | TXTDblHFont = cFont::CreateFont(txtFontName, txtFontHeight, realFontWidths[6]); | |
139 | TXTDblHWFont = cFont::CreateFont(txtFontName, txtFontHeight, realFontWidths[7]); | |
138 | // cached | |
139 | DEBUG_OT_FONT("call cFont::CreateFont for: %s", txtFontName); | |
140 | TXTFont = cFont::CreateFont(txtFontName, realFontHeights[0], realFontWidths[0]); | |
141 | TXTDblWFont = cFont::CreateFont(txtFontName, realFontHeights[1], realFontWidths[1]); | |
142 | TXTDblHFont = cFont::CreateFont(txtFontName, realFontHeights[2], realFontWidths[2]); | |
143 | TXTDblHWFont = cFont::CreateFont(txtFontName, realFontHeights[3], realFontWidths[3]); | |
144 | TXTHlfHFont = cFont::CreateFont(txtFontName, realFontHeights[4], realFontWidths[4]); | |
140 | 145 | } else { |
141 | 146 | TXTFontFootprint = footprint; |
142 | TXTFont = GetFont(txtFontName, 4, txtFontHeight / 2, txtFontWidth / 2); | |
143 | TXTDblWFont = GetFont(txtFontName, 5, txtFontHeight / 2, txtFontWidth); | |
144 | TXTDblHFont = GetFont(txtFontName, 6, txtFontHeight, txtFontWidth / 2); | |
145 | TXTDblHWFont = GetFont(txtFontName, 7, txtFontHeight, txtFontWidth); | |
147 | DEBUG_OT_FONT("call GetFont for: %s", txtFontName); | |
148 | TXTFont = GetFont(txtFontName, 0, txtFontHeight / 2, txtFontWidth / 2); | |
149 | TXTDblWFont = GetFont(txtFontName, 1, txtFontHeight / 2, txtFontWidth); | |
150 | TXTDblHFont = GetFont(txtFontName, 2, txtFontHeight, txtFontWidth / 2); | |
151 | TXTDblHWFont = GetFont(txtFontName, 3, txtFontHeight, txtFontWidth); | |
152 | TXTHlfHFont = GetFont(txtFontName, 4, txtFontHeight / 4, txtFontWidth / 2); | |
146 | 153 | } |
147 | 154 | } |
148 | 155 | |
149 | 156 | bool cDisplay::SetBlink(bool blink) { |
157 | DEBUG_OT_BLINK("called with blink=%d", blink); | |
150 | 158 | int x,y; |
151 | 159 | bool Change=false; |
152 | 160 | |
192 | 200 | return Change; |
193 | 201 | } |
194 | 202 | |
203 | bool cDisplay::HasConceal() { | |
204 | int x,y; | |
205 | bool HasConceal=false; | |
206 | ||
207 | // check all concealed chars | |
208 | for (y=0;y<25;y++) { | |
209 | for (x=0;x<40;x++) { | |
210 | if (Page[x][y].GetConceal()) { | |
211 | HasConceal=true; | |
212 | } | |
213 | } | |
214 | } | |
215 | ||
216 | return HasConceal; | |
217 | } | |
218 | ||
195 | 219 | void cDisplay::SetZoom(enumZoom zoom) { |
220 | DEBUG_OT_DBFC("called: zoom=%d", zoom); | |
196 | 221 | |
197 | 222 | if (!osd) return; |
198 | 223 | if (Zoom==zoom) return; |
201 | 226 | // Re-initialize scaler to let zoom take effect |
202 | 227 | InitScaler(); |
203 | 228 | |
204 | // Clear screen - mainly clear border | |
205 | CleanDisplay(); | |
229 | Dirty=true; | |
230 | DirtyAll=true; | |
206 | 231 | |
207 | 232 | Flush(); |
208 | 233 | } |
209 | 234 | |
210 | 235 | void cDisplay::SetBackgroundColor(tColor c) { |
236 | DEBUG_OT_DBFC("called: tColor=0x%08x", c); | |
211 | 237 | Background=c; |
212 | 238 | CleanDisplay(); |
213 | 239 | Flush(); |
214 | 240 | } |
215 | 241 | |
216 | 242 | void cDisplay::CleanDisplay() { |
217 | enumTeletextColor bgc=(Boxed)?(ttcTransparent):(ttcBlack); | |
243 | tColor bgc; | |
244 | ||
218 | 245 | if (!osd) return; |
219 | 246 | |
220 | osd->DrawRectangle(0, 0, Width, Height, GetColorRGB(bgc,0)); | |
247 | if (Boxed) | |
248 | bgc = GetColorRGB(ttcTransparent,0); | |
249 | else if (m_debugmask & DEBUG_MASK_OT_ACT_OSD_BACK_RED) | |
250 | bgc = GetColorRGB(ttcRed,0); | |
251 | else | |
252 | bgc = Background; | |
253 | ||
254 | DEBUG_OT_RENCLN("called: outputWidth=%d outputHeight=%d boxed=%s color=0x%08x", outputWidth, outputHeight, BOOLTOTEXT(Boxed), bgc); | |
255 | osd->DrawRectangle(0, 0, outputWidth - 1 + leftFrame + rightFrame, outputHeight - 1 + topFrame + bottomFrame, bgc); | |
221 | 256 | |
222 | 257 | // repaint all |
223 | 258 | Dirty=true; |
224 | 259 | DirtyAll=true; |
225 | 260 | } |
226 | 261 | |
262 | // AARRGGBB | |
263 | #define COLOR_HALF(clr) ((clr & 0xff000000) | ((clr & 0x00fe0000) >> 1) | ((clr & 0x0000fe00) >> 1) | ((clr & 0x000000fe) >> 1)) | |
227 | 264 | |
228 | 265 | tColor cDisplay::GetColorRGB(enumTeletextColor ttc, int Area) { |
229 | 266 | switch (ttc) { |
230 | case ttcBlack: return Background; | |
231 | case ttcRed: return clrRed; | |
232 | case ttcGreen: return clrGreen; | |
233 | case ttcYellow: return clrYellow; | |
234 | case ttcBlue: return clrBlue; | |
235 | case ttcMagenta: return clrMagenta; | |
236 | case ttcCyan: return clrCyan; | |
237 | case ttcWhite: return clrWhite; | |
238 | case ttcTransparent: return clrTransparent; | |
239 | default: return Background; | |
267 | case ttcBlack: return Background; | |
268 | case ttcRed: return clrRed; | |
269 | case ttcGreen: return clrGreen; | |
270 | case ttcYellow: return clrYellow; | |
271 | case ttcBlue: return clrBlue; | |
272 | case ttcMagenta: return clrMagenta; | |
273 | case ttcCyan: return clrCyan; | |
274 | case ttcWhite: return clrWhite; | |
275 | case ttcTransparent: return clrTransparent; | |
276 | case ttcHalfRed: return COLOR_HALF(clrRed); | |
277 | case ttcHalfGreen: return COLOR_HALF(clrGreen); | |
278 | case ttcHalfYellow: return COLOR_HALF(clrYellow); | |
279 | case ttcHalfBlue: return COLOR_HALF(clrBlue); | |
280 | case ttcHalfMagenta: return COLOR_HALF(clrMagenta); | |
281 | case ttcHalfCyan: return COLOR_HALF(clrCyan); | |
282 | case ttcGrey: return COLOR_HALF(clrWhite); | |
283 | // 16-31 according to ETSI EN 300 706 V1.2.1 (2003-012.4) 12.4 | |
284 | case ttcColor16: return 0xFFFC005C; | |
285 | case ttcColor17: return 0xFFFC7C00; | |
286 | case ttcColor18: return 0xFF00FC7C; | |
287 | case ttcColor19: return 0xFFFCFCBC; | |
288 | case ttcColor20: return 0xFFFCFCBC; | |
289 | case ttcColor21: return 0xFF00CCAC; | |
290 | case ttcColor22: return 0xFF5C0000; | |
291 | case ttcColor23: return 0xFF6C5C2C; | |
292 | case ttcColor24: return 0xFFCC7C7C; | |
293 | case ttcColor25: return 0xFF3C3C3C; // grey25 | |
294 | case ttcColor26: return 0xFFFC7C7C; | |
295 | case ttcColor27: return 0xFF7CFC7C; | |
296 | case ttcColor28: return 0xFFFCFC7C; | |
297 | case ttcColor29: return 0xFF7C7CFC; | |
298 | case ttcColor30: return 0xFF7CFCFC; | |
299 | case ttcColor31: return 0xFFDCDCDC; // grey75 | |
300 | default: return Background; | |
240 | 301 | } |
241 | 302 | } |
242 | 303 | |
243 | 304 | tColor cDisplay::GetColorRGBAlternate(enumTeletextColor ttc, int Area) { |
305 | // TODO implement ?? | |
244 | 306 | return GetColorRGB(ttc,Area); |
245 | 307 | } |
246 | 308 | |
247 | 309 | void cDisplay::RenderTeletextCode(unsigned char *PageCode) { |
248 | 310 | // Interprete teletext code referenced by PageCode |
249 | 311 | // and draw the whole page content into OSD. |
250 | // PageCode must be a 40*24+12 bytes buffer | |
312 | // PageCode must be a buffer containing TelePageData structure (see storage.h) | |
251 | 313 | |
252 | 314 | HoldFlush(); |
253 | 315 | |
254 | 316 | cRenderPage::ReadTeletextHeader(PageCode); |
255 | 317 | |
318 | DEBUG_OT_RENCLN("called with Boxed=%s Flags=0x%02x", BOOLTOTEXT(Boxed), Flags); | |
319 | ||
256 | 320 | if (!Boxed && (Flags&0x60)!=0) { |
321 | DEBUG_OT_RENCLN("Toggle Boxed: false->true"); | |
257 | 322 | Boxed=true; |
258 | 323 | CleanDisplay(); |
259 | 324 | } else if (Boxed && (Flags&0x60)==0) { |
325 | DEBUG_OT_RENCLN("Toggle Boxed: true->false"); | |
260 | 326 | Boxed=false; |
261 | 327 | CleanDisplay(); |
262 | 328 | } |
263 | 329 | |
330 | if (memcmp(PageCode, "VTXV5", 5) != 0) { | |
331 | esyslog("osdteletext: cDisplay::RenderTeletextCode called with PageCode which is not starting with 'VTXV5' (not supported)"); | |
332 | return; | |
333 | }; | |
334 | ||
264 | 335 | cRenderPage::RenderTeletextCode(PageCode+12); |
265 | 336 | |
266 | 337 | ReleaseFlush(); |
269 | 340 | |
270 | 341 | |
271 | 342 | void cDisplay::DrawDisplay() { |
343 | DEBUG_OT_DD("called with Blinked=%d Concealed=%d Dirty=%s DirtyAll=%s IsDirty()=%s", Blinked, Concealed, BOOLTOTEXT(Dirty), BOOLTOTEXT(DirtyAll), BOOLTOTEXT(IsDirty())); | |
272 | 344 | int x,y; |
273 | int cnt=0; | |
274 | ||
275 | if (!IsDirty()) return; | |
276 | // nothing to do | |
277 | ||
278 | for (y=0;y<25;y++) { | |
345 | ||
346 | if (!IsDirty()) return; // nothing to do | |
347 | ||
348 | for (y = 0; y < TT_DISPLAY_LINES; y++) { | |
279 | 349 | for (x=0;x<40;x++) { |
280 | 350 | if (IsDirty(x,y)) { |
281 | 351 | // Need to draw char to osd |
282 | cnt++; | |
283 | 352 | cTeletextChar c=Page[x][y]; |
284 | 353 | c.SetDirty(false); |
285 | 354 | if ((Blinked && c.GetBlink()) || (Concealed && c.GetConceal())) { |
355 | DEBUG_OT_BLINK("blink by replacing char %08x with ' ' on x=%d y=%d", c.GetC(), x, y); | |
286 | 356 | c.SetChar(0x20); |
287 | 357 | c.SetCharset(CHARSET_LATIN_G0_DE); |
288 | 358 | } |
289 | 359 | DrawChar(x,y,c); |
290 | Page[x][y]=c; | |
291 | 360 | } |
292 | 361 | } |
293 | 362 | } |
322 | 391 | enumTeletextColor ttfg=c.GetFGColor(); |
323 | 392 | enumTeletextColor ttbg=c.GetBGColor(); |
324 | 393 | |
325 | if (c.GetBoxedOut()) { | |
394 | static int cache_txtVoffset = 0; | |
395 | static int cache_outputHeight = 0; | |
396 | static int cache_OsdHeight = 0; | |
397 | static int cache_Vshift = 0; | |
398 | static int cache_valid = 0; | |
399 | ||
400 | if (!osd) return; | |
401 | ||
402 | if (Boxed && c.GetBoxedOut()) { | |
326 | 403 | ttbg=ttcTransparent; |
327 | 404 | ttfg=ttcTransparent; |
328 | 405 | } |
329 | ||
330 | if (!osd) return; | |
331 | 406 | |
332 | 407 | tColor fg=GetColorRGB(ttfg, 0); |
333 | 408 | tColor bg=GetColorRGB(ttbg, 0); |
337 | 412 | int tl = Utf8CharSet(t, buf); |
338 | 413 | buf[tl] = 0; |
339 | 414 | |
340 | const cFont *font; | |
415 | const cFont *font = TXTFont; // FIXED: -Wmaybe-uninitialized | |
341 | 416 | int charset = c.GetCharset(); |
342 | 417 | int fontType = 0; |
343 | int w = fontWidth / 2; | |
418 | int w = fontWidth / 2; | |
344 | 419 | int h = fontHeight / 2; |
345 | 420 | if (c.GetDblWidth() != dblw_Normal) { |
346 | 421 | fontType |= 1; |
352 | 427 | h = fontHeight; |
353 | 428 | } |
354 | 429 | |
430 | bool isGraphicsChar; | |
355 | 431 | if (charset == CHARSET_GRAPHICS_G1 || charset == CHARSET_GRAPHICS_G1_SEP) { |
356 | switch(fontType) { | |
357 | case 0: | |
358 | font = GFXFont; | |
359 | break; | |
360 | case 1: | |
361 | font = GFXDblWFont; | |
362 | break; | |
363 | case 2: | |
364 | font = GFXDblHFont; | |
365 | break; | |
366 | case 3: | |
367 | font = GFXDblHWFont; | |
368 | break; | |
369 | } | |
432 | isGraphicsChar = true; | |
370 | 433 | } else { |
434 | if (c.GetChar() == 0x7f) // filled rectangle | |
435 | isGraphicsChar = true; | |
436 | else | |
437 | isGraphicsChar = false; | |
371 | 438 | switch(fontType) { |
372 | 439 | case 0: |
373 | 440 | font = TXTFont; |
384 | 451 | } |
385 | 452 | } |
386 | 453 | |
454 | bool h_scale_div2 = false; | |
455 | int lines_div2 = 0; | |
456 | ||
387 | 457 | if (Zoom == Zoom_Lower) { |
388 | y -= 11; | |
389 | } | |
390 | ||
391 | int vx = x * fontWidth / 2; | |
392 | int vy = y * fontHeight / 2; | |
458 | y -= 12; | |
459 | if (y < 0 || y > 11) { | |
460 | if ((ttSetup.lineMode24 != 1) && (y >= 12)) { | |
461 | // display special line >= 25 in half height | |
462 | h /= 2; | |
463 | h_scale_div2 = true; | |
464 | font = TXTHlfHFont; | |
465 | lines_div2 = y - 12; | |
466 | } else { | |
467 | // display only line 12-23 (12 lines) | |
468 | return; | |
469 | }; | |
470 | }; | |
471 | }; | |
472 | ||
473 | if (Zoom == Zoom_Upper) { | |
474 | if (y > 11) { | |
475 | if ((ttSetup.lineMode24 != 1) && (y >= 24)) { | |
476 | // display special line >= 25 in half height | |
477 | y -= 12; | |
478 | h /= 2; | |
479 | h_scale_div2 = true; | |
480 | font = TXTHlfHFont; | |
481 | lines_div2 = y - 12; | |
482 | } else { | |
483 | // display only line 0-11 (12 lines) | |
484 | return; | |
485 | }; | |
486 | }; | |
487 | }; | |
488 | ||
489 | if ((m_debugmask & DEBUG_MASK_OT_ACT_LIMIT_LINES) && (y > 8)) return; | |
490 | ||
491 | int vx = x * fontWidth / 2; | |
492 | int vy = y * fontHeight / 2 - lines_div2 * h; | |
393 | 493 | |
394 | 494 | bool drawChar = true; |
395 | 495 | if (c.GetDblWidth() == dblw_Right) { |
400 | 500 | } |
401 | 501 | |
402 | 502 | if (drawChar) { |
403 | osd->DrawRectangle(vx, vy, vx + w, vy + h, bg); | |
404 | osd->DrawText(vx, vy, buf, fg, bg, font); | |
405 | } | |
406 | ||
407 | } | |
408 | ||
409 | void cDisplay::DrawText(int x, int y, const char *text, int len) { | |
503 | if (isGraphicsChar) { | |
504 | unsigned int buffer[10]; | |
505 | unsigned int *charmap; | |
506 | ||
507 | // Get character face: | |
508 | charmap=GetFontChar(c,buffer); | |
509 | if (!charmap) { | |
510 | // invalid - clear buffer | |
511 | bzero(&buffer,sizeof buffer); | |
512 | charmap=buffer; | |
513 | } | |
514 | ||
515 | cBitmap charBm(w, h, 24); | |
516 | if (m_debugmask & DEBUG_MASK_OT_ACT_CHAR_BACK_BLUE) | |
517 | charBm.DrawRectangle(0, 0, w - 1, h - 1, GetColorRGB(ttcBlue,0)); | |
518 | else | |
519 | charBm.DrawRectangle(0, 0, w - 1, h - 1, bg); | |
520 | ||
521 | // draw scaled graphics char | |
522 | int virtY = 0; | |
523 | while (virtY<=h) { | |
524 | int bitline; | |
525 | bitline=charmap[virtY * 10 / h / ((h_scale_div2 == true) ? 2 : 1)]; | |
526 | ||
527 | int virtX=0; | |
528 | while (virtX < w) { | |
529 | int bit=(virtX * 12 / w); | |
530 | if (bitline&(0x8000>>bit)) { | |
531 | charBm.DrawPixel(virtX,virtY,fg); | |
532 | // } else { | |
533 | // charBm.DrawPixel(virtX,virtY,bg); | |
534 | } | |
535 | virtX++; | |
536 | } | |
537 | virtY++; | |
538 | } | |
539 | ||
540 | osd->DrawBitmap(vx + leftFrame, vy + topFrame, charBm); | |
541 | ||
542 | } else { | |
543 | cBitmap charBm(w, h, 24); | |
544 | if (m_debugmask & DEBUG_MASK_OT_ACT_CHAR_BACK_BLUE) | |
545 | charBm.DrawRectangle(0, 0, w - 1, h - 1, GetColorRGB(ttcBlue,0)); | |
546 | else | |
547 | charBm.DrawRectangle(0, 0, w - 1, h - 1, bg); | |
548 | // charBm.DrawText(0, 0, buf, fg, bg, font); | |
549 | if ( | |
550 | (cache_valid == 0) || ( | |
551 | (cache_txtVoffset != TTSETUPPRESET(Voffset)) | |
552 | || (cache_outputHeight != outputHeight ) | |
553 | || (cache_OsdHeight != cOsd::OsdHeight() ) | |
554 | ) | |
555 | ) { | |
556 | cache_valid = 1; | |
557 | cache_txtVoffset = TTSETUPPRESET(Voffset); | |
558 | cache_outputHeight = outputHeight; | |
559 | cache_OsdHeight = cOsd::OsdHeight(); | |
560 | cache_Vshift = (cache_txtVoffset * cache_outputHeight) / cache_OsdHeight; | |
561 | DEBUG_OT_DTXT("osdteletext: DrawText vertical shift cache updated: txtVoffset=%d outputHeight=%d OsdHeight=%d => Vshift=%d", cache_txtVoffset, cache_outputHeight, cache_OsdHeight, cache_Vshift); | |
562 | }; | |
563 | ||
564 | if ((m_debugline >= 0) && (y == m_debugline)) { | |
565 | DEBUG_OT_DCHR("y=%2d x=%2d vy=%4d vx=%4d w=%d h=%d cache_Vshift=%d ttfg=%d fg=0x%08x ttbg=%d bg=0x%08x BoxedOut=%d text charset=0x%04x char='%s'", y, x, vy, vx, w, h, cache_Vshift, ttfg, fg, ttbg, bg, c.GetBoxedOut(), charset, buf); | |
566 | }; | |
567 | ||
568 | charBm.DrawText(0, cache_Vshift, buf, fg, 0, font, 0, 0); | |
569 | ||
570 | if (m_debugmask & DEBUG_MASK_OT_DCHR) { | |
571 | // draw a bunch of markers into bitmap | |
572 | tColor color = GetColorRGB(ttcRed,0); | |
573 | if(((x % 2 != 0) && ((y % 2) == 0)) || ((x % 2 == 0) && ((y % 2) != 0))) | |
574 | color = GetColorRGB(ttcBlue,0); | |
575 | for (int i = 0; i < w; i++) { | |
576 | charBm.DrawPixel(i , 0 , color); // horizontal top | |
577 | charBm.DrawPixel(i , h - 1, color); // horizontal bottom | |
578 | if ((h > 2) && ((i % 5) == 0)) { | |
579 | // mark at 5 | |
580 | charBm.DrawPixel(i , 0 + 1, color); // horizontal top | |
581 | charBm.DrawPixel(i , h - 2, color); // horizontal bottom | |
582 | }; | |
583 | if ((h > 4) && ((i % 10) == 0)) { | |
584 | // mark at 10 | |
585 | charBm.DrawPixel(i , 0 + 2, color); // horizontal top | |
586 | charBm.DrawPixel(i , 0 + 3, color); // horizontal top | |
587 | charBm.DrawPixel(i , h - 2, color); // horizontal bottom | |
588 | charBm.DrawPixel(i , h - 3, color); // horizontal bottom | |
589 | }; | |
590 | }; | |
591 | for (int i = 0; i < h; i++) { | |
592 | charBm.DrawPixel(0 , i, color); // vertical left | |
593 | charBm.DrawPixel(w - 1 , i, color); // vertical right | |
594 | if ((w > 2) && ((i % 5) == 0)) { | |
595 | // mark at 5 | |
596 | charBm.DrawPixel(0 + 1 , i, color); // vertical left | |
597 | charBm.DrawPixel(w - 1 , i, color); // vertical right | |
598 | }; | |
599 | if ((w > 4) && ((i % 10) == 0)) { | |
600 | // mark at 10 | |
601 | charBm.DrawPixel(0 + 2 , i, color); // vertical left | |
602 | charBm.DrawPixel(0 + 3 , i, color); // vertical left | |
603 | charBm.DrawPixel(w - 2 , i, color); // vertical right | |
604 | charBm.DrawPixel(w - 3 , i, color); // vertical right | |
605 | }; | |
606 | }; | |
607 | }; | |
608 | ||
609 | osd->DrawBitmap(vx + leftFrame, vy + topFrame, charBm); | |
610 | } | |
611 | } | |
612 | } | |
613 | ||
614 | uint8_t UTF8toTeletextChar(const uint8_t c1, const uint8_t c2, enumCharsets *TeletextCharset) { | |
615 | // Convert UTF char into TeletextChar and set related TeletextCharset | |
616 | uint8_t TeletextChar = '?'; // default "unknown" | |
617 | *TeletextCharset = CHARSET_LATIN_G0; // default | |
618 | ||
619 | switch (c1) { | |
620 | case 0xc3: | |
621 | switch (c2) { | |
622 | // CHARSET_LATIN_G0_DE | |
623 | case 0x84: // LATIN CAPITAL LETTER A WITH DIAERESIS | |
624 | TeletextChar = 0x5b; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
625 | break; | |
626 | case 0x96: // LATIN CAPITAL LETTER O WITH DIAERESIS | |
627 | TeletextChar = 0x5c; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
628 | break; | |
629 | case 0x9c: // LATIN CAPITAL LETTER U WITH DIAERESIS | |
630 | TeletextChar = 0x7d; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
631 | break; | |
632 | case 0xa4: // LATIN SMALL LETTER A WITH DIAERESIS | |
633 | TeletextChar = 0x7b; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
634 | break; | |
635 | case 0xb6: // LATIN SMALL LETTER O WITH DIAERESIS | |
636 | TeletextChar = 0x7c; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
637 | break; | |
638 | case 0xbc: // LATIN SMALL LETTER U WITH DIAERESIS | |
639 | TeletextChar = 0x7d; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
640 | break; | |
641 | case 0x9f: // LATIN SMALL LETTER SHARP S | |
642 | TeletextChar = 0x7e; *TeletextCharset = CHARSET_LATIN_G0_DE; | |
643 | break; | |
644 | } | |
645 | // TODO: implement other required mapping | |
646 | } | |
647 | return (TeletextChar); | |
648 | } | |
649 | ||
650 | void cDisplay::DrawTextExtended(const int x, const int y, const char *text, const int len, const enumAlignment alignment, const enumTeletextColor ttcFg, enumTeletextColor const ttcBg) { | |
651 | // Copy text to teletext page with alignment and foreground/background color | |
652 | int len_text_utf8 = Utf8StrLen(text); | |
653 | int len_text = strlen(text); | |
654 | ||
655 | DEBUG_OT_DTXT("called with x=%d y=%d len=%d alignment=%d ttcFg=%d ttcBg=%d text='%s' strlen(text)=%d utf8len(text)=%d", x, y, len, alignment, ttcFg, ttcBg, text, len_text, len_text_utf8); | |
656 | ||
657 | int fill_left = 0; | |
658 | ||
659 | if (len_text_utf8 < len) { | |
660 | if (alignment == AlignmentRight) { | |
661 | fill_left = len - len_text_utf8; | |
662 | } else if (alignment == AlignmentCenter) { | |
663 | fill_left = (len - len_text_utf8) / 2; | |
664 | }; | |
665 | }; | |
666 | ||
667 | cTeletextChar c; | |
668 | c.SetFGColor(ttcFg); | |
669 | c.SetBGColor(ttcBg); | |
670 | ||
671 | int j = 0; | |
672 | for (int i = 0; i < len; i++) { | |
673 | if (i < fill_left) { | |
674 | // fill left with space | |
675 | c.SetChar(' '); | |
676 | } else if (i > fill_left + len_text_utf8) { | |
677 | // fill right with space | |
678 | c.SetChar(' '); | |
679 | } else { | |
680 | c.SetCharset(CHARSET_LATIN_G0); // default | |
681 | uint8_t c1 = text[j]; | |
682 | if (j +1 < len_text) { | |
683 | // check for UTF-8 | |
684 | if ((text[j + 1] & 0xC0) == 0x80) { | |
685 | // unicode | |
686 | uint8_t c2 = text[j + 1]; | |
687 | enumCharsets Charset; | |
688 | uint8_t Char = UTF8toTeletextChar(c1, c2, &Charset); | |
689 | DEBUG_OT_DTXT("unicode mapped i=%d c1=%x c2=%x -> c=%02x cs=%04x", i, c1, c2, Char, Charset); | |
690 | c.SetCharset(Charset); | |
691 | c1 = Char; | |
692 | j++; | |
693 | } | |
694 | }; | |
695 | c.SetChar(c1); | |
696 | j++; | |
697 | }; | |
698 | SetChar(x+i, y, c); | |
699 | }; | |
700 | ||
701 | Flush(); | |
702 | }; | |
703 | ||
704 | void cDisplay::DrawText(int x, int y, const char *text, int len, const enumTeletextColor cText) { | |
410 | 705 | // Copy text to teletext page |
706 | DEBUG_OT_DTXT("called with x=%d y=%d len=%d text='%s' strlen(text)=%d", x, y, len, text, (int) strlen(text)); | |
411 | 707 | |
412 | 708 | cTeletextChar c; |
413 | c.SetFGColor(ttcWhite); | |
709 | c.SetFGColor(cText); // default ttcWhite | |
414 | 710 | c.SetBGColor(ttcBlack); |
415 | 711 | c.SetCharset(CHARSET_LATIN_G0); |
416 | 712 | |
434 | 730 | Flush(); |
435 | 731 | } |
436 | 732 | |
733 | ||
734 | void cDisplay::ClearPage(void) { | |
735 | // Clear Teletext Page on OSD | |
736 | cTeletextChar c; | |
737 | c.SetFGColor(ttcTransparent); // no char | |
738 | c.SetBGColor(ttcBlack); // pass selected background | |
739 | c.SetChar(' '); | |
740 | ||
741 | // reset 40x24 area with space | |
742 | for (int y = 0; y < 24; y++) | |
743 | for (int x = 0; x < 40; x++) | |
744 | SetChar(x, y, c); | |
745 | ||
746 | return; | |
747 | }; | |
748 | ||
749 | ||
750 | void cDisplay::DrawPageId(const char *text, const enumTeletextColor cText, const bool boxedAlwaysOn) { | |
751 | // Draw Page ID string to OSD | |
752 | // In case of "Boxed" page: only until 1st page update unless "boxedAlwaysOn" is set | |
753 | // "boxedAlwaysOn" also unhides the 1st line completly | |
754 | static char text_last[9] = ""; // remember | |
755 | static bool paused_last = false; | |
756 | cTeletextChar c; | |
757 | ||
758 | DEBUG_OT_DRPI("called with text='%s' text_last='%s' Boxed=%d HasConceal=%d GetConceal=%d boxedAlwaysOn=%s", text, text_last, Boxed, HasConceal(), GetConceal(), BOOLTOTEXT(boxedAlwaysOn)); | |
759 | ||
760 | if ((! GetPaused()) && Boxed && (! boxedAlwaysOn) && PageIdDisplayedEver && (strcmp(text, text_last) == 0)) { | |
761 | // don't draw PageId a 2nd time on boxed pages | |
762 | for (int i = 0; i < 8; i++) { | |
763 | c.SetFGColor(ttcTransparent); | |
764 | c.SetBGColor(ttcTransparent); | |
765 | c.SetChar(0); | |
766 | SetChar(i,0,c); | |
767 | }; | |
768 | return; | |
769 | }; | |
770 | ||
771 | if (Boxed && boxedAlwaysOn) { | |
772 | for (int x = 8; x < 40; x++) { | |
773 | // de-boxing of 1st line in case OSD is not matching live channel | |
774 | c = GetChar(x, 0); | |
775 | c.SetBoxedOut(false); | |
776 | SetChar(x, 0, c); | |
777 | }; | |
778 | }; | |
779 | ||
780 | DrawText(0,0,text,8, cText); | |
781 | strncpy(text_last, text, sizeof(text_last) - 1); | |
782 | PageIdDisplayedEver = true; | |
783 | ||
784 | if (HasConceal()) { | |
785 | c.SetBGColor(ttcBlack); | |
786 | if (GetConceal()) { | |
787 | c.SetFGColor(ttcYellow); | |
788 | c.SetChar('?'); | |
789 | } else { | |
790 | c.SetFGColor(ttcGreen); | |
791 | c.SetChar('!'); | |
792 | }; | |
793 | DEBUG_OT_DRPI("trigger SetChar for Conceiled hint ttfg=%x ttbg=%x", c.GetFGColor(), c.GetBGColor()); | |
794 | SetChar(6, 0, c); | |
795 | }; | |
796 | ||
797 | if (GetPaused()) { | |
798 | paused_last = true; | |
799 | c.SetBGColor(ttcBlack); | |
800 | c.SetFGColor(ttcRed); | |
801 | c.SetChar('!'); | |
802 | DEBUG_OT_DRPI("trigger SetChar for Paused hint ttfg=%x ttbg=%x", c.GetFGColor(), c.GetBGColor()); | |
803 | SetChar(3, 0, c); | |
804 | } else if (paused_last == true) { | |
805 | paused_last = false; | |
806 | c.SetBGColor(ttcBlack); | |
807 | c.SetFGColor(ttcGreen); | |
808 | c.SetChar('>'); | |
809 | DEBUG_OT_DRPI("trigger SetChar for Paused finished hint ttfg=%x ttbg=%x", c.GetFGColor(), c.GetBGColor()); | |
810 | SetChar(3, 0, c); | |
811 | }; | |
812 | } | |
813 | ||
814 | void cDisplay::DrawHotkey(const char *textRed, const char *textGreen, const char* textYellow, const char *textBlue, const HotkeyFlags flag) { | |
815 | if (Boxed) return; // don't draw hotkey on boxed pages | |
816 | ||
817 | switch(flag) { | |
818 | case HotkeyNormal: | |
819 | DrawTextExtended( 0, 24, textRed , 10, AlignmentCenter, ttcWhite, ttcRed ); | |
820 | DrawTextExtended(10, 24, textGreen , 10, AlignmentCenter, ttcBlack, ttcGreen ); | |
821 | DrawTextExtended(20, 24, textYellow, 10, AlignmentCenter, ttcBlack, ttcYellow ); | |
822 | DrawTextExtended(30, 24, textBlue , 10, AlignmentCenter, ttcWhite, ttcBlue ); | |
823 | break; | |
824 | ||
825 | case HotkeyYellowValue: | |
826 | DrawTextExtended( 0, 24, textRed , 10, AlignmentCenter, ttcWhite, ttcRed ); | |
827 | DrawTextExtended(10, 24, textGreen , 10, AlignmentCenter, ttcBlack, ttcGreen ); | |
828 | DrawTextExtended(20, 24, textYellow, 10, AlignmentCenter, ttcWhite, ttcMagenta); | |
829 | DrawTextExtended(30, 24, textBlue , 10, AlignmentCenter, ttcWhite, ttcBlue ); | |
830 | break; | |
831 | ||
832 | case HotkeyGreenYellowValue: | |
833 | DrawTextExtended( 0, 24, textRed , 10, AlignmentCenter, ttcWhite, ttcRed ); | |
834 | DrawTextExtended(10, 24, textGreen , 20, AlignmentCenter, ttcWhite, ttcMagenta); | |
835 | DrawTextExtended(30, 24, textBlue , 10, AlignmentCenter, ttcWhite, ttcBlue ); | |
836 | break; | |
837 | }; | |
838 | } | |
839 | ||
840 | void cDisplay::DrawHints(const char *textH1, const char *textH2, const char* textH3, const char *textH4, const char *textH5, const HintsFlags flag) { | |
841 | if (Boxed) return; // don't draw hints on boxed pages | |
842 | ||
843 | switch(flag) { | |
844 | case HintsKey: | |
845 | DrawTextExtended( 0, 25, textH1, 8, AlignmentCenter, ttcHalfCyan, ttcGrey ); | |
846 | DrawTextExtended( 8, 25, textH2, 8, AlignmentCenter, ttcHalfCyan, ttcColor25); | |
847 | DrawTextExtended(16, 25, textH3, 8, AlignmentCenter, ttcHalfCyan, ttcGrey ); | |
848 | DrawTextExtended(24, 25, textH4, 8, AlignmentCenter, ttcHalfCyan, ttcColor25); | |
849 | DrawTextExtended(32, 25, textH5, 8, AlignmentCenter, ttcHalfCyan, ttcGrey ); | |
850 | break; | |
851 | ||
852 | case HintsValue: | |
853 | DrawTextExtended( 0, 26, textH1, 8, AlignmentCenter, ttcColor25 , ttcGrey ); | |
854 | DrawTextExtended( 8, 26, textH2, 8, AlignmentCenter, ttcColor31 , ttcColor25); | |
855 | DrawTextExtended(16, 26, textH3, 8, AlignmentCenter, ttcColor25 , ttcGrey ); | |
856 | DrawTextExtended(24, 26, textH4, 8, AlignmentCenter, ttcColor31 , ttcColor25); | |
857 | DrawTextExtended(32, 26, textH5, 8, AlignmentCenter, ttcColor25 , ttcGrey ); | |
858 | break; | |
859 | }; | |
860 | } | |
861 | ||
437 | 862 | void cDisplay::DrawClock() { |
863 | if (Boxed) return; // don't draw Clock in on boxed pages | |
864 | ||
438 | 865 | char text[9]; |
439 | 866 | time_t t=time(0); |
440 | 867 | struct tm loct; |
445 | 872 | DrawText(32,0,text,8); |
446 | 873 | } |
447 | 874 | |
448 | void cDisplay::DrawMessage(const char *txt) { | |
449 | const int border=5; | |
875 | void cDisplay::DrawMessage(const char *txt1, const char *txt2, const enumTeletextColor cFrame, const enumTeletextColor cText, const enumTeletextColor cBackground) { | |
876 | int border=6; // minimum | |
877 | if (outputWidth > 720) { | |
878 | // increase border | |
879 | border = ((border * outputWidth) / 720) & 0xfffe; // always even number | |
880 | }; | |
881 | if (outputWidth > 1280) { | |
882 | // select larger font | |
883 | MessageFont = cFont::GetFont(fontOsd); | |
884 | }; | |
450 | 885 | |
451 | 886 | if (!osd) return; |
452 | 887 | |
459 | 894 | if (IsDirty()) DrawDisplay(); |
460 | 895 | // Make sure all characters are out, so we can draw on top |
461 | 896 | |
462 | int w=MessageFont->Width(txt)+4*border; | |
463 | int h=MessageFont->Height(txt)+4*border; | |
464 | int x=(outputWidth-w)/2; | |
465 | int y=(outputHeight-h)/2; | |
897 | // text w/h | |
898 | int w1 = MessageFont->Width(txt1); | |
899 | int h1 = MessageFont->Height(txt1); | |
900 | int w2 = 0; | |
901 | int h2 = 0; | |
902 | ||
903 | // remember for later | |
904 | int w1_orig = w1; | |
905 | int w2_orig = w2; | |
906 | ||
907 | // box w/h | |
908 | int w = w1; | |
909 | int h = h1; | |
910 | ||
911 | // text offset | |
912 | int o1 = 0; | |
913 | int o2 = 0; | |
914 | ||
915 | if (txt2 != NULL) { | |
916 | // 2nd line active | |
917 | w2 = MessageFont->Width(txt2); | |
918 | h2 = MessageFont->Height(txt2); | |
919 | ||
920 | h += h2 + border / 2; // increase height | |
921 | ||
922 | if (w2 > w1) { | |
923 | // 2nd line is longer | |
924 | w = w2; | |
925 | o1 = (w2 - w1) / 2; | |
926 | } else if (w2 < w1) { | |
927 | // 1st line is longer | |
928 | o2 = (w1 - w2) / 2; | |
929 | }; | |
930 | } | |
931 | ||
932 | w += 4 * border; | |
933 | h += 4 * border; | |
934 | ||
935 | // limit to maximum | |
936 | if (w > outputWidth) w = outputWidth; | |
937 | if (h > outputHeight) h = outputHeight; | |
938 | ||
939 | // center box | |
940 | int x = (outputWidth -w)/2 + leftFrame; | |
941 | int y = (outputHeight-h)/2 + topFrame; | |
466 | 942 | |
467 | 943 | // Get local color mapping |
468 | tColor fg=GetColorRGB(ttcWhite,0); | |
469 | tColor bg=GetColorRGB(ttcBlack,0); | |
470 | if (fg==bg) bg=GetColorRGBAlternate(ttcBlack,0); | |
471 | ||
472 | // Draw framed box | |
473 | osd->DrawRectangle(x ,y ,x+w-1 ,y+border-1 ,fg); | |
474 | osd->DrawRectangle(x ,y+h-border,x+w-1 ,y+h-1 ,fg); | |
475 | osd->DrawRectangle(x ,y ,x+border-1 ,y+h-1 ,fg); | |
476 | osd->DrawRectangle(x+w-border,y ,x+w-1 ,y+h-1 ,fg); | |
477 | osd->DrawRectangle(x+border ,y+border ,x+w-border-1,y+h-border-1,bg); | |
944 | tColor fg=GetColorRGB(cText,0); | |
945 | tColor bg=GetColorRGB(cBackground,0); | |
946 | tColor fr=GetColorRGB(cFrame,0); | |
947 | if (fg==bg) bg=GetColorRGBAlternate(cBackground,0); | |
948 | ||
949 | // Draw framed box (2 outer pixel always background) | |
950 | osd->DrawRectangle(x , y , x+w-1 , y+h-1 , bg); // outer rectangle | |
951 | osd->DrawRectangle(x+(border/2), y+(border/2), x+w-1-border/2, y+h-1-border/2, fr); // inner rectangle | |
952 | osd->DrawRectangle(x+border , y+border , x+w-1-border , y+h-1-border , bg); // background for text | |
953 | ||
954 | // Remember box | |
955 | MessageW = w; | |
956 | MessageH = h; | |
957 | MessageX = x; | |
958 | MessageY = y; | |
959 | ||
960 | // limit width | |
961 | if ((w - 4 * border) < w1) { | |
962 | w1 = w - 4 * border; | |
963 | wsyslog_ot("text too long for box, apply width limit (%d->%d) for txt1='%s'", w1_orig, w1, txt1); | |
964 | }; | |
965 | if (txt2 != NULL) { | |
966 | if ((w - 4 * border) < w2) { | |
967 | w2 = w - 4 * border; | |
968 | wsyslog_ot("text too long for box, apply width limit (%d->%d) for txt2='%s'", w2_orig, w2, txt2); | |
969 | }; | |
970 | }; | |
478 | 971 | |
479 | 972 | // Draw text |
480 | osd->DrawText(x+2*border,y+2*border,txt, fg, bg, MessageFont); | |
481 | ||
482 | ||
483 | // Remember box | |
484 | MessageW=w; | |
485 | MessageH=h; | |
486 | MessageX=x; | |
487 | MessageY=y; | |
973 | if (txt2 == NULL) { | |
974 | osd->DrawText(x + 2 * border + o1, y + 2 * border, txt1, fg, bg, MessageFont, w1, h1); | |
975 | DEBUG_OT_MSG("MX=%d MY=%d MW=%d MH=%d OW=%d OH=%d w1=%d h1=%d txt1='%s'", MessageX, MessageY, MessageW, MessageH, outputWidth, outputHeight, w1, h1, txt1); | |
976 | } else { | |
977 | osd->DrawText(x + 2 * border + o1, y + 2 * border , txt1, fg, bg, MessageFont, w1, h1); | |
978 | osd->DrawText(x + 2 * border + o2, y + 2 * border + h1 + border / 2, txt2, fg, bg, MessageFont, w2, h2); | |
979 | DEBUG_OT_MSG("MX=%d MY=%d MW=%d MH=%d OW=%d OH=%d w1=%d h1=%d w2=%d w2=%d txt1='%s' txt2='%s'", MessageX, MessageY, MessageW, MessageH, outputWidth, outputHeight, w1, h1, w2, h2, txt1, txt2); | |
980 | }; | |
488 | 981 | |
489 | 982 | // And flush all changes |
490 | 983 | ReleaseFlush(); |
494 | 987 | if (!osd) return; |
495 | 988 | if (MessageW==0 || MessageH==0) return; |
496 | 989 | |
497 | // map OSD pixel to virtual coordinate, use center of pixel | |
498 | int x0=(MessageX-OffsetX)*ScaleX+ScaleX/2; | |
499 | int y0=(MessageY-OffsetY)*ScaleY+ScaleY/2; | |
500 | int x1=(MessageX+MessageW-1-OffsetX)*ScaleX+ScaleX/2; | |
501 | int y1=(MessageY+MessageH-1-OffsetY)*ScaleY+ScaleY/2; | |
502 | ||
503 | // map to character | |
504 | x0=x0/(12<<16); | |
505 | y0=y0/(10<<16); | |
506 | x1=(x1+(12<<16)-1)/(12<<16); | |
507 | y1=(y1+(10<<16)-1)/(10<<16); | |
508 | ||
990 | // NEW, reverse calculation based on how DrawChar | |
991 | // map to character x/y | |
992 | int x0 = (MessageX - leftFrame) / (fontWidth / 2); | |
993 | int y0 = (MessageY - topFrame ) / (fontHeight / 2); | |
994 | int x1 = (MessageX + MessageW - 1 - leftFrame) / (fontWidth / 2); | |
995 | int y1 = (MessageY + MessageH - 1 - topFrame ) / (fontHeight / 2); | |
996 | ||
997 | DEBUG_OT_MSG("MX=%d MY=%d MW=%d MH=%d => x0=%d/y0=%d x1=%d/y1=%d", MessageX, MessageY, MessageW, MessageH, x0, y0, x1, y1); | |
998 | ||
999 | #define TESTOORX(X) (X < 0 || X >= 40) | |
1000 | #define TESTOORY(Y) (Y < 0 || Y >= 25) | |
1001 | if ( TESTOORX(x0) || TESTOORX(x1) || TESTOORY(y0) || TESTOORY(y1) ) { | |
1002 | // something out-of-range | |
1003 | esyslog("osdteletext: %s out-of-range detected(crop) MessageX=%d MessageY=%d MessageW=%d MessageH=%d => x0=%d%s y0=%d%s x1=%d%s y1=%d%s", __FUNCTION__, MessageX, MessageY, MessageW, MessageH, | |
1004 | x0, TESTOORX(x0) ? "!" : "", | |
1005 | y0, TESTOORY(y0) ? "!" : "", | |
1006 | x1, TESTOORX(x1) ? "!" : "", | |
1007 | y1, TESTOORY(y1) ? "!" : "" | |
1008 | ); | |
1009 | // crop to limits | |
1010 | if (x0 < 0) x0 = 0; | |
1011 | if (x1 < 0) x1 = 0; | |
1012 | if (y0 < 0) y0 = 0; | |
1013 | if (y1 < 0) y1 = 0; | |
1014 | if TESTOORX(x0) x0 = 40 - 1; | |
1015 | if TESTOORX(x1) x1 = 40 - 1; | |
1016 | if TESTOORY(y0) y0 = 25 - 1; | |
1017 | if TESTOORY(y1) y1 = 25 - 1; | |
1018 | } | |
1019 | ||
1020 | HoldFlush(); | |
1021 | ||
1022 | // DEBUG_OT_MSG("call MakeDirty with area x0=%d/y0=%d <-> x1=%d/y1=%d", x0, y0, x1, y1); | |
509 | 1023 | for (int x=x0;x<=x1;x++) { |
510 | 1024 | for (int y=y0;y<=y1;y++) { |
511 | 1025 | MakeDirty(x,y); |
515 | 1029 | MessageW=0; |
516 | 1030 | MessageH=0; |
517 | 1031 | |
518 | Flush(); | |
519 | } | |
1032 | ReleaseFlush(); | |
1033 | } | |
1034 | ||
1035 | // vim: ts=4 sw=4 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) 2005 by Udo Richter * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * displaybase.h - Base class for rendering a teletext cRenderPage to * |
3 | 5 | * an actual VDR OSD. * |
7 | 9 | * the Free Software Foundation; either version 2 of the License, or * |
8 | 10 | * (at your option) any later version. * |
9 | 11 | * * |
10 | * Changelog: * | |
11 | * 2005-03 initial version (c) Udo Richter * | |
12 | * * | |
13 | 12 | ***************************************************************************/ |
14 | 13 | |
15 | 14 | #ifndef OSDTELETEXT_DISPLAYBASE_H_ |
19 | 18 | #include "setup.h" |
20 | 19 | #include <vdr/osd.h> |
21 | 20 | #include <string> |
21 | ||
22 | // #define dsyslog_osdteletext(format, arg...) dsyslog(format, ## arg) | |
23 | #define dsyslog_osdteletext(format, arg...) { } | |
22 | 24 | |
23 | 25 | class cDisplay : public cRenderPage { |
24 | 26 | // Class that extends the virtual cRenderPage with the capability |
34 | 36 | Zoom_Lower |
35 | 37 | } Zoom; |
36 | 38 | |
39 | enum enumAlignment { AlignmentLeft, AlignmentCenter, AlignmentRight } Alignment; | |
40 | ||
37 | 41 | protected: |
38 | 42 | bool Concealed; |
39 | 43 | // Hidden text internal state |
55 | 59 | // Color to be used for black background |
56 | 60 | // - allow transparency |
57 | 61 | |
62 | bool Paused; | |
63 | // Paused internal state | |
64 | ||
65 | bool PageIdDisplayedEver; | |
66 | // Flag whether the PageId was ever displayed so far | |
67 | ||
58 | 68 | cOsd *osd; |
59 | 69 | // The osd object. If creation fails, may be NULL |
60 | 70 | |
61 | 71 | int outputWidth; |
62 | double outputScaleX; | |
63 | 72 | int outputHeight; |
64 | double outputScaleY; | |
65 | 73 | // for 32bpp true color, If creation fails, may be NULL |
66 | 74 | |
67 | int ScaleX,ScaleY; | |
68 | int OffsetX,OffsetY; | |
69 | // Virtual coordinate system, see InitScaler | |
75 | int leftFrame, rightFrame, topFrame, bottomFrame; | |
76 | // frame border | |
70 | 77 | |
71 | 78 | const cFont *MessageFont; |
72 | 79 | int MessageX,MessageY,MessageW,MessageH; |
73 | // Message overlay window, position and font | |
74 | ||
75 | const cFont *GFXFont; | |
76 | const cFont *GFXDblWFont; | |
77 | const cFont *GFXDblHFont; | |
78 | const cFont *GFXDblHWFont; | |
80 | ||
79 | 81 | const cFont *TXTFont; |
80 | 82 | const cFont *TXTDblWFont; |
81 | 83 | const cFont *TXTDblHFont; |
82 | 84 | const cFont *TXTDblHWFont; |
85 | const cFont *TXTHlfHFont; | |
83 | 86 | int fontHeight; |
84 | 87 | int fontWidth; |
85 | 88 | |
86 | static int realFontWidths[8]; | |
87 | ||
89 | static int realFontWidths[5]; | |
90 | static int realFontHeights[5]; | |
88 | 91 | |
89 | 92 | class cBox { |
90 | 93 | // helper class. Represents a character's box in virtual coordinates |
114 | 117 | |
115 | 118 | void setOutputWidth(int w) { outputWidth = w; }; |
116 | 119 | void setOutputHeight(int h) { outputHeight = h; }; |
120 | void setLeftFrame (int lF) { leftFrame = lF; }; | |
121 | void setRightFrame (int rF) { rightFrame = rF; }; | |
122 | void setTopFrame (int tF) { topFrame = tF; }; | |
123 | void setBottomFrame(int bF) { bottomFrame = bF; }; | |
117 | 124 | |
118 | 125 | static std::string GFXFontFootprint; |
119 | 126 | static std::string TXTFontFootprint; |
132 | 139 | |
133 | 140 | // ScaleX,ScaleY represent the (virtual) width and height of a |
134 | 141 | // physical OSD pixel. |
135 | // OffsetX,OffsetY default to 3,3 to represent the border offset, | |
136 | // but may be used differently. | |
137 | 142 | |
138 | 143 | public: |
139 | 144 | bool GetBlink() { return Blinked; } |
145 | 150 | bool SetConceal(bool conceal); |
146 | 151 | // Hidden text. Set to true to see hidden text. |
147 | 152 | // Returns true if there are concealed characters. |
153 | bool HasConceal(); | |
154 | // Returns true if there are concealed characters. | |
155 | ||
156 | void SetPaused(bool paused) { Paused = paused; return; }; | |
157 | bool GetPaused() { return Paused; }; | |
158 | // Returns true if paused | |
148 | 159 | |
149 | 160 | enumZoom GetZoom() { return Zoom; } |
150 | 161 | void SetZoom(enumZoom zoom); |
203 | 214 | // and draw the whole page content into OSD. |
204 | 215 | // PageCode must be a 40*24+12 bytes buffer |
205 | 216 | |
206 | void DrawText(int x, int y, const char *text, int len); | |
217 | void DrawText(int x, int y, const char *text, int len, const enumTeletextColor cText = ttcWhite); | |
207 | 218 | // Draw some characters in teletext page. |
208 | 219 | // Max len chars, fill up with spaces |
209 | 220 | |
221 | void DrawTextExtended(const int x, const int y, const char *text, int len, const enumAlignment alignment, const enumTeletextColor ttcFg, const enumTeletextColor ttcBg); | |
222 | // Draw some characters in teletext page. | |
223 | // Max len chars, fill up with spaces | |
224 | // with alignment, foreground and background color | |
225 | ||
226 | void DrawHotkey(const char *textRed, const char *textGreen, const char* textYellow, const char *textBlue, const HotkeyFlags flag); | |
227 | // Draw hotkey to OSD | |
228 | ||
229 | void DrawHints(const char *textH1, const char *textH2, const char* textH3, const char *textH4, const char *textH5, const HintsFlags flag); | |
230 | // Draw hint line to OSD | |
231 | ||
210 | 232 | void DrawClock(); |
211 | 233 | // Draw current time to OSD |
212 | 234 | |
213 | void DrawPageId(const char *text) | |
214 | { DrawText(0,0,text,8); } | |
215 | // Draw Page ID string to OSD | |
216 | ||
217 | void DrawMessage(const char *txt); | |
218 | // Draw a framed, centered message box to OSD | |
235 | void DrawPageId(const char *text, const enumTeletextColor cText = ttcWhite, const bool boxedAlwaysOn = false); | |
236 | // Draw Page ID string to OSD with optional text color and optional always in boxed mode | |
237 | ||
238 | void DrawMessage(const char *txt1, const char *txt2 = NULL, const enumTeletextColor cFrame = ttcWhite, const enumTeletextColor cText = ttcWhite, const enumTeletextColor cBackground = ttcBlack); | |
239 | // Draw a framed, centered message box to OSD with optional(default) color definition for frame(white), text(white), background(black) and a 2nd line | |
219 | 240 | |
220 | 241 | void ClearMessage(); |
221 | 242 | // Remove message box and redraw hidden content |
222 | 243 | |
244 | void ClearPage(void); | |
245 | // Clear Teletext Page on OSD | |
223 | 246 | |
224 | 247 | private: |
225 | 248 | cFont *GetFont(const char *name, int index, int height, int width); |
226 | 249 | std::string GetFontFootprint(const char *name); |
227 | 250 | }; |
228 | ||
229 | 251 | |
230 | 252 | |
231 | 253 | inline void cDisplay::cBox::SetToCharacter(int x, int y) { |
236 | 258 | YMax=YMin+(10<<16)-1; |
237 | 259 | } |
238 | 260 | |
239 | inline void cDisplay::cVirtualCoordinate::VirtualToPixel(cDisplay *Display, int x, int y) { | |
240 | // Map virtual coordinate to OSD pixel | |
241 | OsdX=x/Display->ScaleX+Display->OffsetX; | |
242 | OsdY=y/Display->ScaleY+Display->OffsetY; | |
243 | ||
244 | // map OSD pixel back to virtual coordinate, use center of pixel | |
245 | VirtX=(OsdX-Display->OffsetX)*Display->ScaleX+Display->ScaleX/2; | |
246 | VirtY=(OsdY-Display->OffsetY)*Display->ScaleY+Display->ScaleY/2; | |
247 | } | |
248 | ||
249 | inline void cDisplay::cVirtualCoordinate::IncPixelX(cDisplay *Display) { | |
250 | // Move one OSD pixel | |
251 | OsdX++; | |
252 | VirtX+=Display->ScaleX; | |
253 | } | |
254 | inline void cDisplay::cVirtualCoordinate::IncPixelY(cDisplay *Display) { | |
255 | // Move one OSD pixel | |
256 | OsdY++; | |
257 | VirtY+=Display->ScaleY; | |
258 | } | |
259 | ||
260 | 261 | #endif |
44 | 44 | void LegacyStorage::initMaxStorage(int maxMB) { |
45 | 45 | struct statfs fs; |
46 | 46 | if (statfs(getRootDir(), &fs)!=0) { |
47 | esyslog("OSD-Teletext: Error statfs'ing root directory \"%s\": %s, cache size uncontrolled", getRootDir(), strerror(errno)); | |
47 | esyslog("osdteletext: Error statfs'ing root directory \"%s\": %s, cache size uncontrolled", getRootDir(), strerror(errno)); | |
48 | 48 | return; |
49 | 49 | } |
50 | 50 | fsBlockSize=fs.f_bsize; |
53 | 53 | |
54 | 54 | if (maxMB>=0) { |
55 | 55 | if (maxMB<3) { |
56 | esyslog("OSD-Teletext: Request to use at most %d MB for caching. This is not enough, using 3 MB", maxMB); | |
56 | esyslog("osdteletext: Request to use at most %d MB for caching. This is not enough, using 3 MB", maxMB); | |
57 | 57 | maxMB=3; |
58 | 58 | } |
59 | 59 | maxBytes=MEGABYTE(maxMB); |
68 | 68 | maxBytes=MEGABYTE((int)freeMB); |
69 | 69 | //maxPages= FilesForMegabytes(freeMB, fs.f_bsize); |
70 | 70 | if (freeMB<3.0) { |
71 | esyslog("OSD-Teletext: Less than %.1f MB free on filesystem of root directory \"%s\"!", freeMB, getRootDir()); | |
71 | esyslog("osdteletext: Less than %.1f MB free on filesystem of root directory \"%s\"!", freeMB, getRootDir()); | |
72 | 72 | maxBytes=MEGABYTE(3); |
73 | 73 | } |
74 | 74 | } else { |
117 | 117 | if (!fd && !wroteError) { |
118 | 118 | //report error to syslog - once! |
119 | 119 | wroteError=true; |
120 | esyslog("OSD-Teletext: Error opening teletext file %s: %s", filename, strerror(errno)); | |
120 | esyslog("osdteletext: Error opening teletext file %s: %s", filename, strerror(errno)); | |
121 | 121 | } |
122 | 122 | //make sure newly created files are counted |
123 | 123 | if (fd && !existed) |
133 | 133 | freeSpace(); |
134 | 134 | return ::write((int)stream, ptr, size); |
135 | 135 | case EINTR: |
136 | esyslog("OSD-Teletext: EINTR while writing. Please contact the author and tell him this happened."); | |
136 | esyslog("osdteletext: EINTR while writing. Please contact the author and tell him this happened."); | |
137 | 137 | break; |
138 | 138 | default: |
139 | 139 | break; |
0 | ||
1 | #ifndef LOGGING_H_INCLUDED | |
2 | #define LOGGING_H_INCLUDED | |
3 | ||
4 | #include <vdr/tools.h> | |
5 | ||
6 | extern unsigned int m_debugmask; | |
7 | extern unsigned int m_debugpage; | |
8 | extern unsigned int m_debugpsub; | |
9 | extern int m_debugline; | |
10 | ||
11 | #define BOOLTOTEXT(var) ((var == true) ? "true" : "false") | |
12 | ||
13 | #define DEBUG_MASK_OT 0x00000001 // general | |
14 | #define DEBUG_MASK_OT_CACHE 0x00000002 // Caching System | |
15 | #define DEBUG_MASK_OT_TXTRCVC 0x00000004 // Text Receiver channel related | |
16 | #define DEBUG_MASK_OT_KNONE 0x00000010 // Knone action | |
17 | #define DEBUG_MASK_OT_KEYS 0x00000020 // Keys action | |
18 | #define DEBUG_MASK_OT_NEPG 0x00000100 // new cTelePage | |
19 | #define DEBUG_MASK_OT_COPG 0x00000200 // regular log amount of new cTelePage | |
20 | #define DEBUG_MASK_OT_SETUP 0x00000800 // ttSetup | |
21 | #define DEBUG_MASK_OT_DD 0x00001000 // DrawDisplay | |
22 | #define DEBUG_MASK_OT_MSG 0x00002000 // Draw/Clear Message | |
23 | #define DEBUG_MASK_OT_DRPI 0x00004000 // DrawPageId | |
24 | #define DEBUG_MASK_OT_HOTK 0x00008000 // DrawHotkey | |
25 | #define DEBUG_MASK_OT_FONT 0x00010000 // Font | |
26 | #define DEBUG_MASK_OT_AREA 0x00020000 // Area | |
27 | #define DEBUG_MASK_OT_DBFC 0x00040000 // DisplayBase Function Call | |
28 | #define DEBUG_MASK_OT_SCALER 0x00080000 // Scaler | |
29 | #define DEBUG_MASK_OT_BLINK 0x00100000 // Text Blink | |
30 | #define DEBUG_MASK_OT_DCHR 0x00200000 // DrawChar | |
31 | #define DEBUG_MASK_OT_BOXED 0x00400000 // BoxedOut | |
32 | #define DEBUG_MASK_OT_DTXT 0x00800000 // DrawText | |
33 | #define DEBUG_MASK_OT_TXTRDT 0x01000000 // Text Rendering triplet | |
34 | #define DEBUG_MASK_OT_RENCLN 0x02000000 // Render/Clean | |
35 | #define DEBUG_MASK_OT_TXTRCVD 0x04000000 // Text Receiver dump to stdout (particular page only, see code) | |
36 | #define DEBUG_MASK_OT_TXTRD 0x08000000 // Text Rendering dump to stdout | |
37 | ||
38 | // special action mask | |
39 | #define DEBUG_MASK_OT_ACT_LIMIT_LINES 0x10000000 // Limit Lines (debugging for detecting pixel offset issues) | |
40 | #define DEBUG_MASK_OT_ACT_OSD_BACK_RED 0x20000000 // OSD Background Red (debugging for detecting pixel offset issues) | |
41 | #define DEBUG_MASK_OT_ACT_CHAR_BACK_BLUE 0x40000000 // Char Background Blue (debugging for detecting pixel offset issues) | |
42 | ||
43 | #define dsyslog_ot(format, arg...) dsyslog("osdteletext: DEBUG %s/%s: " format, __FILE__, __FUNCTION__, ## arg) | |
44 | #define wsyslog_ot(format, arg...) esyslog("osdteletext: WARN %s/%s: " format, __FILE__, __FUNCTION__, ## arg) | |
45 | ||
46 | #define DEBUG_OT if (m_debugmask & DEBUG_MASK_OT) dsyslog_ot | |
47 | #define DEBUG_OT_FONT if (m_debugmask & DEBUG_MASK_OT_FONT) dsyslog_ot | |
48 | #define DEBUG_OT_DBFC if (m_debugmask & DEBUG_MASK_OT_DBFC) dsyslog_ot | |
49 | #define DEBUG_OT_NEPG if (m_debugmask & DEBUG_MASK_OT_NEPG) dsyslog_ot | |
50 | #define DEBUG_OT_COPG if (m_debugmask & DEBUG_MASK_OT_COPG) dsyslog_ot | |
51 | #define DEBUG_OT_AREA if (m_debugmask & DEBUG_MASK_OT_AREA) dsyslog_ot | |
52 | #define DEBUG_OT_SCALER if (m_debugmask & DEBUG_MASK_OT_SCALER) dsyslog_ot | |
53 | #define DEBUG_OT_BLINK if (m_debugmask & DEBUG_MASK_OT_BLINK) dsyslog_ot | |
54 | #define DEBUG_OT_SETUP if (m_debugmask & DEBUG_MASK_OT_SETUP) dsyslog_ot | |
55 | #define DEBUG_OT_DD if (m_debugmask & DEBUG_MASK_OT_DD) dsyslog_ot | |
56 | #define DEBUG_OT_KNONE if (m_debugmask & DEBUG_MASK_OT_KNONE) dsyslog_ot | |
57 | #define DEBUG_OT_KEYS if (m_debugmask & DEBUG_MASK_OT_KEYS) dsyslog_ot | |
58 | #define DEBUG_OT_MSG if (m_debugmask & DEBUG_MASK_OT_MSG) dsyslog_ot | |
59 | #define DEBUG_OT_DRPI if (m_debugmask & DEBUG_MASK_OT_DRPI) dsyslog_ot | |
60 | #define DEBUG_OT_HOTK if (m_debugmask & DEBUG_MASK_OT_HOTK) dsyslog_ot | |
61 | #define DEBUG_OT_DCHR if (m_debugmask & DEBUG_MASK_OT_DCHR) dsyslog_ot | |
62 | #define DEBUG_OT_BOXED if (m_debugmask & DEBUG_MASK_OT_BOXED) dsyslog_ot | |
63 | #define DEBUG_OT_DTXT if (m_debugmask & DEBUG_MASK_OT_DTXT ) dsyslog_ot | |
64 | #define DEBUG_OT_CACHE if (m_debugmask & DEBUG_MASK_OT_CACHE) dsyslog_ot | |
65 | #define DEBUG_OT_TXTRDT if (m_debugmask & DEBUG_MASK_OT_TXTRDT) dsyslog_ot | |
66 | #define DEBUG_OT_RENCLN if (m_debugmask & DEBUG_MASK_OT_RENCLN) dsyslog_ot | |
67 | #define DEBUG_OT_TXTRCVC if (m_debugmask & DEBUG_MASK_OT_TXTRCVC) dsyslog_ot | |
68 | #define DEBUG_OT_TXTRCVD if (m_debugmask & DEBUG_MASK_OT_TXTRCVD) dsyslog_ot | |
69 | #define DEBUG_OT_TXTRD if (m_debugmask & DEBUG_MASK_OT_TXTRD) dsyslog_ot | |
70 | ||
71 | #endif |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | 1 | * Copyright (c) 2003,2004 by Marcel Wiesweg * |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
2 | 3 | * * |
3 | 4 | * This program is free software; you can redistribute it and/or modify * |
4 | 5 | * it under the terms of the GNU General Public License as published by * |
9 | 10 | |
10 | 11 | #include <map> |
11 | 12 | #include <time.h> |
12 | ||
13 | ||
13 | 14 | #include <vdr/interface.h> |
14 | 15 | #include <vdr/config.h> |
15 | 16 | |
17 | 18 | #include "display.h" |
18 | 19 | #include "setup.h" |
19 | 20 | #include "txtrecv.h" |
21 | #include "logging.h" | |
20 | 22 | |
21 | 23 | #define GET_HUNDREDS(x) ( ( (x) - ((x)%256) ) /256 ) |
22 | 24 | #define GET_TENS(x) ( (( (x) - ((x)%16) )%256 ) /16 ) |
30 | 32 | |
31 | 33 | using namespace std; |
32 | 34 | |
33 | int Stretch = true; | |
34 | 35 | typedef map<int,int> IntMap; |
35 | 36 | IntMap channelPageMap; |
36 | 37 | |
38 | 39 | int TeletextBrowser::currentPage=0x100; //Believe it or not, the teletext numbers are somehow hexadecimal |
39 | 40 | int TeletextBrowser::currentSubPage=0; |
40 | 41 | tChannelID TeletextBrowser::channel; |
42 | cChannel TeletextBrowser::channelClass; | |
41 | 43 | int TeletextBrowser::currentChannelNumber=0; |
44 | int TeletextBrowser::liveChannelNumber=0; | |
45 | bool TeletextBrowser::switchChannelInProgress = false; | |
46 | eChannelInfo TeletextBrowser::ChannelInfo; | |
42 | 47 | TeletextBrowser* TeletextBrowser::self=0; |
43 | ||
48 | tColor clrBackground; | |
49 | bool clrBackgroundInit = false; | |
50 | ||
51 | extern int maxOsdPreset; | |
52 | extern int maxHotkeyLevel; | |
53 | ||
54 | eTeletextActionConfig configMode = LastActionConfig; | |
44 | 55 | |
45 | 56 | TeletextBrowser::TeletextBrowser(cTxtStatus *txtSt,Storage *s) |
46 | 57 | : cursorPos(0), pageFound(true), selectingChannel(false), |
58 | hotkeyLevel(0), | |
59 | delayClearMessage(0), | |
47 | 60 | needClearMessage(false), selectingChannelNumber(-1), txtStatus(txtSt), |
48 | 61 | suspendedReceiving(false), previousPage(currentPage), |
49 | 62 | previousSubPage(currentSubPage), pageBeforeNumberInput(currentPage), |
50 | 63 | lastActivity(time(NULL)), inactivityTimeout(-1), storage(s) |
51 | 64 | { |
65 | if (!clrBackgroundInit) { | |
66 | clrBackground = TTSETUPPRESET_TCOLOR(BackTrans); // default | |
67 | clrBackgroundInit = true; | |
68 | }; | |
69 | ||
70 | ttSetup.osdPreset = 0; // default preset | |
71 | ||
52 | 72 | self=this; |
53 | //if (txtStatus) | |
54 | // txtStatus->ForceReceiving(true); | |
55 | 73 | } |
56 | 74 | |
57 | 75 | |
59 | 77 | Display::Delete(); |
60 | 78 | |
61 | 79 | self=0; |
62 | /*if (txtStatus) { | |
63 | if (suspendedReceiving) | |
64 | txtStatus->ForceSuspending(false); | |
65 | txtStatus->ForceReceiving(false); | |
66 | }*/ | |
67 | 80 | } |
68 | 81 | |
69 | 82 | void TeletextBrowser::Show(void) { |
70 | Display::SetMode(Display::mode); | |
83 | Display::SetMode(Display::mode, clrBackground); | |
71 | 84 | ShowPage(); |
72 | 85 | } |
73 | 86 | |
80 | 93 | #endif |
81 | 94 | } |
82 | 95 | |
83 | void TeletextBrowser::ChannelSwitched(int ChannelNumber) { | |
96 | void TeletextBrowser::ChannelSwitched(int ChannelNumber, const eChannelInfo info) { | |
97 | static eChannelInfo infoLast = ChannelIsLive; | |
98 | static int ChannelNumberLast = 0; | |
99 | DEBUG_OT_TXTRCVC("called with ChNu=%d ChNuLa=%d liChNu=%d info=%d infoLa=%d switchChannelInProgress=%s", ChannelNumber, ChannelNumberLast, liveChannelNumber, info, infoLast, BOOLTOTEXT(switchChannelInProgress)); | |
84 | 100 | #if defined(APIVERSNUM) && APIVERSNUM >= 20301 |
85 | 101 | LOCK_CHANNELS_READ; |
86 | 102 | const cChannel *chan=Channels->GetByNumber(ChannelNumber); |
92 | 108 | return; |
93 | 109 | |
94 | 110 | tChannelID chid=chan->GetChannelID(); |
95 | if (chid==channel || chid==tChannelID::InvalidID) | |
111 | if (chid==tChannelID::InvalidID) | |
96 | 112 | return; |
97 | 113 | |
98 | 114 | channel=chid; |
115 | channelClass = *chan; // remember for later to display channel name | |
116 | ||
117 | if (info == ChannelIsLive) | |
118 | liveChannelNumber= ChannelNumber; // remember active live channel | |
119 | ||
120 | ChannelInfo = info; // store info | |
99 | 121 | |
100 | 122 | //store page number of current channel |
101 | 123 | IntMap::iterator it; |
102 | 124 | channelPageMap[currentChannelNumber] = currentPage; |
103 | 125 | currentChannelNumber=ChannelNumber; |
104 | ||
126 | ||
105 | 127 | currentPage=0x100; |
106 | 128 | currentSubPage=0; |
107 | ||
129 | ||
108 | 130 | //see if last page number on this channel was stored |
109 | 131 | it=channelPageMap.find(ChannelNumber); |
110 | 132 | if (it != channelPageMap.end()) { //found |
111 | 133 | currentPage=(*it).second; |
112 | 134 | } |
113 | ||
135 | ||
114 | 136 | //on the one hand this must work in background mode, when the plugin is not active. |
115 | 137 | //on the other hand, if active, the page should be shown. |
116 | 138 | //so this self-Pointer. |
117 | 139 | if (self) { |
118 | self->ShowPage(); | |
119 | } | |
120 | } | |
140 | char str[80] = ""; | |
141 | char str2[80] = ""; | |
142 | Display::ClearPage(); | |
143 | enumTeletextColor color = ttcBlue; | |
144 | snprintf(str2, sizeof(str2), "%d: %s", channelClass.Number(), channelClass.Name()); | |
145 | ||
146 | self->delayClearMessage = 1; // default | |
147 | ||
148 | if (info == ChannelHasNoTeletext) { | |
149 | snprintf(str, sizeof(str), "%s %s (%s %s)", tr("Switch to"), tr("Channel"), tr("without"), tr("Teletext")); | |
150 | color = ttcRed; | |
151 | } | |
152 | else if (info == ChannelIsLive) { | |
153 | if (infoLast == ChannelIsLive) { | |
154 | // don't display message during zapping | |
155 | } else { | |
156 | snprintf(str, sizeof(str), "%s %s %s", tr("Switch to"), tr("live"), tr("Channel")); | |
157 | }; | |
158 | } | |
159 | else if (info == ChannelIsTuned) { | |
160 | if (liveChannelNumber == currentChannelNumber) { | |
161 | snprintf(str, sizeof(str), "%s %s", tr("Switch back to live"), tr("Channel")); | |
162 | ChannelInfo = ChannelIsLive; | |
163 | } else { | |
164 | snprintf(str, sizeof(str), "%s - %s", tr("Tuner available"), tr("display current pages")); | |
165 | color = ttcMagenta; | |
166 | }; | |
167 | } | |
168 | else if (info == ChannelWasTunedNewChannelIsLive) { | |
169 | // received trigger that TUNED channel has no longer a receiver but new would be a LIVE channel | |
170 | // suppress a message which will be shortly overwritten anyhow by starting receiver on new channel | |
171 | ChannelInfo = ChannelIsCached; // new status | |
172 | } | |
173 | else if (info == ChannelWasTuned) { | |
174 | // received trigger that TUNED channel has no longer a receiver | |
175 | if (! switchChannelInProgress) { | |
176 | // but no channel switch action in progress -> display message | |
177 | snprintf(str, sizeof(str), "%s - %s", tr("Tuner busy"), tr("display cached pages")); | |
178 | color = ttcCyan; | |
179 | } else { | |
180 | // suppress a message which will be shortly overwritten anyhow by starting receiver on new channel | |
181 | }; | |
182 | ChannelInfo = ChannelIsCached; // new status | |
183 | } | |
184 | else if (info == ChannelIsCached) { | |
185 | snprintf(str, sizeof(str), "%s %s %s", tr("Switch to"), tr("cached"), tr("Channel")); | |
186 | color = ttcCyan; | |
187 | } | |
188 | else { | |
189 | // all cases catched | |
190 | }; | |
191 | ||
192 | self->ShowPage((strlen(str) > 0)); | |
193 | ||
194 | if (strlen(str) > 0) { | |
195 | self->needClearMessage=true; | |
196 | Display::DrawMessage(str, str2, color); | |
197 | }; | |
198 | } | |
199 | ||
200 | // store for acting related on next call | |
201 | infoLast = info; | |
202 | ChannelNumberLast = ChannelNumber; | |
203 | ||
204 | // clear status | |
205 | switchChannelInProgress = false; | |
206 | } | |
207 | ||
208 | ||
209 | bool TeletextBrowser::TriggerChannelSwitch(const int channelNumber) { | |
210 | bool result = false; | |
211 | ||
212 | // switch to new channel | |
213 | #if defined(APIVERSNUM) && APIVERSNUM >= 20301 | |
214 | LOCK_CHANNELS_READ; | |
215 | const cChannel* newChannel = Channels->GetByNumber(channelNumber); | |
216 | #else | |
217 | const cChannel* newChannel = Channels.GetByNumber(channelNumber); | |
218 | #endif | |
219 | if (!newChannel) return false; | |
220 | ||
221 | if (txtStatus->receiver) { | |
222 | // receiver is already running | |
223 | if (txtStatus->receiver->Live()) { | |
224 | if (channelNumber == liveChannelNumber) { | |
225 | DEBUG_OT_TXTRCVC("requested channel %d is LIVE channel, running receiver found on LIVE channel %d - not action required", channelNumber, liveChannelNumber); | |
226 | } else { | |
227 | DEBUG_OT_TXTRCVC("requested channel %d is NON-LIVE channel, running receiver found on LIVE channel %d - action will be triggered later", channelNumber, liveChannelNumber); | |
228 | }; | |
229 | } else { | |
230 | if (channelNumber == liveChannelNumber) { | |
231 | DEBUG_OT_TXTRCVC("requested channel %d is LIVE channel, running receiver found on NON-LIVE channel %d - action will be triggered later", channelNumber, liveChannelNumber); | |
232 | } else { | |
233 | DEBUG_OT_TXTRCVC("requested channel %d is NON-LIVE channel, running receiver found on NON-LIVE channel %d - stop receiver to release device", channelNumber, liveChannelNumber); | |
234 | switchChannelInProgress = true; | |
235 | DELETENULL(txtStatus->receiver); | |
236 | }; | |
237 | }; | |
238 | }; | |
239 | ||
240 | cDevice *device = cDevice::GetDeviceForTransponder(newChannel, TRANSFERPRIORITY - 1); | |
241 | if (device != NULL) { | |
242 | needClearMessage = true; | |
243 | switchChannelInProgress = true; | |
244 | if (device->SwitchChannel(newChannel, (channelNumber == liveChannelNumber) ? true : false)) { | |
245 | if (1 == 0) { | |
246 | // too verbose - disabled | |
247 | Display::DrawMessage(tr("Channel Tuning Successful"), ttcGreen); | |
248 | }; | |
249 | result = true; | |
250 | DEBUG_OT_TXTRCVC("DVB %d successful tuned to channel %d (live=%s)", device->DeviceNumber(), channelNumber, BOOLTOTEXT(channelNumber == liveChannelNumber)); | |
251 | } else { | |
252 | needClearMessage = true; | |
253 | delayClearMessage = 5; | |
254 | Display::DrawMessage(tr("Channel Tuning Not Successful"), ttcRed); | |
255 | DEBUG_OT_TXTRCVC("DVB %d cannot tune to channel %d", device->DeviceNumber(), channelNumber); | |
256 | }; | |
257 | } else { | |
258 | if (1 == 0) { | |
259 | // too verbose - disabled | |
260 | needClearMessage = true; | |
261 | delayClearMessage = 2; | |
262 | Display::DrawMessage(tr("No Free Tuner Found - Use Cache Only"), ttcYellow); | |
263 | }; | |
264 | DEBUG_OT_TXTRCVC("no free tuner available to tune to channel %d (use cache)", channelNumber); | |
265 | ChannelSwitched(channelNumber, ChannelIsCached); | |
266 | }; | |
267 | ||
268 | return (result); | |
269 | }; | |
121 | 270 | |
122 | 271 | |
123 | 272 | eOSState TeletextBrowser::ProcessKey(eKeys Key) { |
273 | cDisplay::enumZoom zoomR; | |
274 | Display::Mode modeR; | |
275 | tColor bgcR, bgcSetup = TTSETUPPRESET_TCOLOR(BackTrans); | |
276 | bool changedConfig = false; | |
277 | ||
124 | 278 | if (Key != kNone) |
125 | 279 | lastActivity = time(NULL); |
126 | ||
280 | ||
281 | if (Key != kNone) DEBUG_OT_KEYS("called with Key=%d", Key); | |
282 | ||
127 | 283 | switch (Key) { |
128 | 284 | case k1: SetNumber(1);break; |
129 | 285 | case k2: SetNumber(2);break; |
148 | 304 | } else |
149 | 305 | SetNumber(0); |
150 | 306 | break; |
307 | ||
151 | 308 | case kOk: |
152 | 309 | if (selectingChannel) { |
153 | 310 | selectingChannel=false; |
154 | 311 | Display::ClearMessage(); |
155 | 312 | if (selectingChannelNumber>0) { |
156 | if (CheckIsValidChannel(selectingChannelNumber)) | |
157 | ChannelSwitched(selectingChannelNumber); | |
313 | if (CheckIsValidChannel(selectingChannelNumber)) { | |
314 | if (selectingChannelNumber != liveChannelNumber) { | |
315 | DEBUG_OT_KEYS("trigger switch to channel %d", selectingChannelNumber); | |
316 | txtStatus->SetNonLiveChannelNumber(selectingChannelNumber); // preload next channel switch with a non-live channel (-> TUNED) | |
317 | TriggerChannelSwitch(selectingChannelNumber); | |
318 | } else { | |
319 | // nothing todo | |
320 | DEBUG_OT_KEYS("no need to trigger switch to channel %d because currently running as live channel", selectingChannelNumber); | |
321 | ChannelSwitched(liveChannelNumber, ChannelIsLive); | |
322 | }; | |
323 | } | |
158 | 324 | else { |
159 | 325 | needClearMessage=true; |
160 | Display::DrawMessage(trVDR("*** Invalid Channel ***")); | |
326 | delayClearMessage = 3; | |
327 | char str[9]; | |
328 | snprintf(str, sizeof(str), "%d", selectingChannelNumber); | |
329 | Display::DrawMessage(trVDR("*** Invalid Channel ***"), str, ttcRed); | |
161 | 330 | } |
162 | 331 | } else { |
163 | ShowPage(); | |
332 | if (selectingChannelNumber != liveChannelNumber) { | |
333 | txtStatus->SetNonLiveChannelNumber(0); // clear non-live channel for next channel switch | |
334 | DEBUG_OT_KEYS("trigger switch to channel %d", liveChannelNumber); | |
335 | TriggerChannelSwitch(liveChannelNumber); | |
336 | selectingChannelNumber = liveChannelNumber; | |
337 | } else { | |
338 | // nothing todo | |
339 | DEBUG_OT_KEYS("no need to trigger switch to channel because unchanged"); | |
340 | }; | |
164 | 341 | } |
165 | } | |
342 | } else { | |
343 | ExecuteAction(TranslateKey(Key)); | |
344 | }; | |
166 | 345 | break; |
346 | ||
167 | 347 | case kBack: return osEnd; |
348 | ||
168 | 349 | case kNone: //approx. every second |
350 | DEBUG_OT_KNONE("section 'kNone' reached with GetPaused=%s needClearMessage=%s delayClearMessage=%d", BOOLTOTEXT(Display::GetPaused()), BOOLTOTEXT(needClearMessage), delayClearMessage); | |
169 | 351 | //checking if page changed |
170 | if ( pageFound && ttSetup.autoUpdatePage && cursorPos==0 && !selectingChannel && (PageCheckSum() != checkSum) ) { | |
352 | if ((delayClearMessage == 0) && ! Display::GetPaused() && pageFound && ttSetup.autoUpdatePage && cursorPos==0 && !selectingChannel && (PageCheckSum() != checkSum) ) { | |
353 | DEBUG_OT_KNONE("section 'kNone' detected: 'page change'"); | |
171 | 354 | ShowPage(); |
172 | 355 | //check if page was previously not found and is available now |
173 | } else if (!pageFound && CheckFirstSubPage(0)) { | |
356 | } else if ((delayClearMessage == 0) && !pageFound && CheckFirstSubPage(0)) { | |
357 | DEBUG_OT_KNONE("section 'kNone' detected: 'previous not found page is now available'"); | |
174 | 358 | ShowPage(); |
175 | 359 | } else { |
360 | DEBUG_OT_KNONE("section 'kNone' default"); | |
176 | 361 | if (needClearMessage) { |
177 | needClearMessage=false; | |
178 | Display::ClearMessage(); | |
179 | } | |
180 | //updating clock | |
181 | UpdateClock(); | |
362 | if (delayClearMessage > 0) { | |
363 | delayClearMessage--; | |
364 | } else { | |
365 | needClearMessage=false; | |
366 | Display::ClearMessage(); | |
367 | if (!pageFound) | |
368 | // (re-)display "not found" information | |
369 | ShowPage(); | |
370 | }; | |
371 | } else { | |
372 | delayClearMessage = 0; // reset | |
373 | }; | |
374 | if (! selectingChannel && pageFound) { | |
375 | //updating clock | |
376 | if (! Display::GetPaused()) | |
377 | UpdateClock(); | |
378 | ||
379 | //updating hotkey | |
380 | UpdateHotkey(); | |
381 | ||
382 | //trigger blink | |
383 | if (! Display::GetPaused()) | |
384 | Display::SetBlink(not(Display::GetBlink())); | |
385 | }; | |
182 | 386 | } |
183 | 387 | //check for activity timeout |
184 | if (ttSetup.inactivityTimeout && (time(NULL) - lastActivity > ttSetup.inactivityTimeout*60)) | |
388 | if (Setup.MinUserInactivity && ((time(NULL) - lastActivity) > (Setup.MinUserInactivity * 60))) | |
185 | 389 | return osEnd; |
186 | 390 | break; |
391 | ||
187 | 392 | case kUp: |
188 | 393 | if (selectingChannel) { |
189 | 394 | selectingChannel=false; |
198 | 403 | Display::ShowUpperHalf(); |
199 | 404 | ShowPage(); |
200 | 405 | break; |
406 | ||
201 | 407 | case kDown: |
202 | 408 | if (selectingChannel) { |
203 | 409 | selectingChannel=false; |
211 | 417 | Display::ShowUpperHalf(); |
212 | 418 | ShowPage(); |
213 | 419 | break; |
420 | ||
214 | 421 | case kRight: |
215 | 422 | if (selectingChannel) { |
216 | 423 | selectingChannel=false; |
223 | 430 | ChangeSubPageRelative(DirectionForward); |
224 | 431 | Display::ShowUpperHalf(); |
225 | 432 | ShowPage(); |
226 | break; | |
433 | break; | |
434 | ||
227 | 435 | case kLeft: |
228 | 436 | if (selectingChannel) { |
229 | 437 | selectingChannel=false; |
239 | 447 | ShowPage(); |
240 | 448 | break; |
241 | 449 | |
242 | ||
243 | 450 | case kRed: |
451 | if (configMode != LastActionConfig) { // catch config mode | |
452 | changedConfig = ExecuteActionConfig(configMode, -1); // decrement | |
453 | break; | |
454 | }; | |
455 | // continue below | |
456 | ||
244 | 457 | case kGreen: |
458 | if (configMode != LastActionConfig) { // catch config mode | |
459 | changedConfig = ExecuteActionConfig(configMode, +1); // increment | |
460 | break; | |
461 | }; | |
462 | // continue below | |
463 | ||
464 | case kYellow: | |
465 | if (configMode != LastActionConfig) { // key is inactive in config mode (displaying value) | |
466 | break; | |
467 | }; | |
468 | // continue below | |
469 | ||
245 | 470 | case kBlue: |
246 | case kYellow: | |
247 | //case kUser1:case kUser2:case kUser3:case kUser4:case kUser5: | |
248 | //case kUser6:case kUser7:case kUser8:case kUser9: | |
249 | case kPlay:case kPause:case kStop: case kRecord:case kFastFwd:case kFastRew: | |
471 | if (configMode != LastActionConfig) { // catch config mode | |
472 | ExecuteAction(Config); | |
473 | break; | |
474 | }; | |
475 | // continue below | |
476 | ||
477 | case kPlay: | |
478 | //case kPause: // not passed into plugin somehow | |
479 | case kStop: | |
480 | //case kRecord: // not passed into plugin somehow | |
481 | case kFastFwd: | |
482 | case kFastRew: | |
250 | 483 | if (cursorPos != 0) { |
251 | 484 | //fully reset |
252 | 485 | SetNumber(-3); |
253 | 486 | } |
254 | 487 | ExecuteAction(TranslateKey(Key)); |
255 | 488 | break; |
256 | default: break; | |
257 | } | |
489 | ||
490 | default: | |
491 | break; | |
492 | } | |
493 | ||
494 | if (changedConfig) { | |
495 | zoomR = Display::GetZoom(); // remember zoom | |
496 | modeR = Display::mode; // remember mode | |
497 | if (TTSETUPPRESET_TCOLOR(BackTrans) != bgcSetup) { | |
498 | bgcR = TTSETUPPRESET_TCOLOR(BackTrans); // color was changed during config | |
499 | clrBackground = bgcR; // set globally | |
500 | DEBUG_OT_KEYS("osdteletext: recreate display with remembered mode=%d zoom=%d and setup configured bgc=%08x", modeR, zoomR, bgcR); | |
501 | } else { | |
502 | bgcR = Display::GetBackgroundColor(); // remember color | |
503 | DEBUG_OT_KEYS("osdteletext: recreate display with remembered mode=%d zoom=%d bgc=%08x", modeR, zoomR, bgcR); | |
504 | }; | |
505 | Display::Delete(); | |
506 | Display::SetMode(modeR, bgcR); // new with remembered mode and background color | |
507 | Display::SetZoom(zoomR); // apply remembered zoom | |
508 | ShowPage(); | |
509 | }; | |
510 | ||
258 | 511 | return osContinue; |
259 | 512 | } |
260 | 513 | |
514 | bool TeletextBrowser::ExecuteActionConfig(eTeletextActionConfig e, int delta) { | |
515 | bool changedConfig = false; | |
516 | ||
517 | #define COND_ADJ_VALUE(value, min, max, delta) \ | |
518 | if (((value + delta) >= min) && ((value + delta) <= max)) { \ | |
519 | value += delta; \ | |
520 | changedConfig = true; \ | |
521 | } else if ((value + delta) < min) { \ | |
522 | value = min; \ | |
523 | changedConfig = true; \ | |
524 | } else if ((value + delta) > max) { \ | |
525 | value = max; \ | |
526 | changedConfig = true; \ | |
527 | }; | |
528 | ||
529 | switch (configMode) { | |
530 | case Left: | |
531 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), OSDleftPctMin, OSDleftPctMax, delta); | |
532 | break; | |
533 | ||
534 | case Top: | |
535 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), OSDtopPctMin, OSDtopPctMax, delta); | |
536 | break; | |
537 | ||
538 | case Width: | |
539 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), OSDwidthPctMin, OSDwidthPctMax, delta); | |
540 | break; | |
541 | ||
542 | case Height: | |
543 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), OSDheightPctMin, OSDheightPctMax, delta); | |
544 | break; | |
545 | ||
546 | case Frame: | |
547 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), OSDframePixMin, OSDframePixMax, delta); | |
548 | break; | |
549 | ||
550 | case Font: | |
551 | TTSETUPPRESET(configMode)++; | |
552 | if (TTSETUPPRESET(configMode) >= ttSetup.txtFontNames.Size()) TTSETUPPRESET(configMode) = 0; // rollover | |
553 | changedConfig = true; | |
554 | break; | |
555 | ||
556 | case Voffset: | |
557 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), txtVoffsetMin, txtVoffsetMax, delta); | |
558 | break; | |
559 | ||
560 | case BackTrans: | |
561 | DEBUG_OT_KEYS("key action: 'Config->BackTrans' BackTrans=%d BackTransMin=%d BackTransMax=%d delta=%d", TTSETUPPRESET(configMode), BackTransMin, BackTransMax, delta * 8); | |
562 | COND_ADJ_VALUE(TTSETUPPRESET(configMode), BackTransMin, BackTransMax, delta * 8); | |
563 | break; | |
564 | ||
565 | default: | |
566 | // nothing todo | |
567 | break; | |
568 | }; | |
569 | return (changedConfig); | |
570 | }; | |
571 | ||
261 | 572 | void TeletextBrowser::ExecuteAction(eTeletextAction e) { |
262 | switch (e) { | |
263 | case Zoom: | |
264 | if (selectingChannel) { | |
265 | selectingChannel=false; | |
266 | Display::ClearMessage(); | |
267 | } | |
573 | cDisplay::enumZoom zoomR; | |
574 | Display::Mode modeR; | |
575 | ||
576 | switch (e) { | |
577 | case Zoom: | |
578 | DEBUG_OT_KEYS("key action: 'Zoom' Display::GetZoom=%d", Display::GetZoom()); | |
579 | if (selectingChannel) { | |
580 | selectingChannel=false; | |
581 | Display::ClearMessage(); | |
582 | } | |
268 | 583 | |
269 | switch (Display::GetZoom()) { | |
584 | switch (Display::GetZoom()) { | |
270 | 585 | case cDisplay::Zoom_Off: |
271 | 586 | Display::SetZoom(cDisplay::Zoom_Upper); |
272 | 587 | break; |
276 | 591 | case cDisplay::Zoom_Lower: |
277 | 592 | Display::SetZoom(cDisplay::Zoom_Off); |
278 | 593 | break; |
279 | } | |
280 | ||
594 | } | |
595 | break; | |
596 | ||
597 | case HalfPage: | |
598 | DEBUG_OT_KEYS("key action: 'Half Page' Display::mode=%d clrBackground=%08x", Display::mode, clrBackground); | |
599 | if (selectingChannel) { | |
600 | selectingChannel=false; | |
601 | Display::ClearMessage(); | |
602 | } | |
603 | ||
604 | switch (Display::mode) { | |
605 | case Display::HalfUpper: | |
606 | Display::SetMode(Display::HalfLower, clrBackground); | |
281 | 607 | break; |
282 | case HalfPage: | |
283 | if (selectingChannel) { | |
284 | selectingChannel=false; | |
285 | Display::ClearMessage(); | |
286 | } | |
287 | ||
288 | switch (Display::mode) { | |
289 | case Display::HalfUpper: | |
290 | Display::SetMode(Display::HalfLower); | |
291 | break; | |
292 | case Display::HalfLower: | |
293 | Display::SetMode(Display::Full); | |
294 | break; | |
295 | case Display::Full: | |
296 | Display::SetMode(Display::HalfUpper); | |
297 | break; | |
298 | } | |
299 | ShowPage(); | |
608 | case Display::HalfLower: | |
609 | Display::SetMode(Display::HalfUpperTop, clrBackground); | |
300 | 610 | break; |
301 | case SwitchChannel: | |
302 | selectingChannelNumber=0; | |
303 | selectingChannel=true; | |
304 | ShowAskForChannel(); | |
611 | case Display::HalfUpperTop: | |
612 | Display::SetMode(Display::HalfLowerTop, clrBackground); | |
305 | 613 | break; |
306 | /*case SuspendReceiving: | |
307 | if (!txtStatus) | |
308 | break; | |
309 | //if (suspendedReceiving) | |
310 | // txtStatus->ForceSuspending(false); | |
311 | //else | |
312 | // txtStatus->ForceSuspending(true); | |
313 | //suspendedReceiving=(!suspendedReceiving); | |
314 | break;*/ | |
315 | case DarkScreen: | |
316 | ChangeBackground(); | |
614 | case Display::HalfLowerTop: | |
615 | Display::SetMode(Display::Full, clrBackground); | |
317 | 616 | break; |
617 | case Display::Full: | |
618 | Display::SetMode(Display::HalfUpper, clrBackground); | |
619 | break; | |
620 | } | |
621 | ShowPage(); | |
622 | break; | |
623 | ||
624 | case SwitchChannel: | |
625 | DEBUG_OT_KEYS("key action: 'SwitchChannel'"); | |
626 | if (!selectingChannel) { | |
627 | selectingChannelNumber=0; | |
628 | selectingChannel=true; | |
629 | ShowAskForChannel(); | |
630 | } else { | |
631 | selectingChannel=false; | |
632 | Display::ClearMessage(); | |
633 | }; | |
634 | break; | |
635 | ||
636 | /*case SuspendReceiving: | |
637 | if (!txtStatus) | |
638 | break; | |
639 | //if (suspendedReceiving) | |
640 | // txtStatus->ForceSuspending(false); | |
641 | //else | |
642 | // txtStatus->ForceSuspending(true); | |
643 | //suspendedReceiving=(!suspendedReceiving); | |
644 | break;*/ | |
645 | ||
646 | case DarkScreen: | |
647 | DEBUG_OT_KEYS("key action: 'DarkScreen'"); | |
648 | ChangeBackground(); | |
649 | break; | |
650 | ||
651 | case LineMode24: | |
652 | DEBUG_OT_KEYS("key action: 'LineMode24' lineMode24=%d", ttSetup.lineMode24); | |
653 | // toggle LineMode24: 0 -> 2 -> 1 -> 0 | |
654 | // 0: 25 lines / Hotkeys only | |
655 | // 1: 24 lines / No Hotkeys+Hints | |
656 | // 2: 27 lines / Hotkeys+Hints | |
657 | if (ttSetup.lineMode24 == 2) { | |
658 | ttSetup.lineMode24 = 1; | |
659 | } else if (ttSetup.lineMode24 == 1) { | |
660 | ttSetup.lineMode24 = 0; | |
661 | } else { | |
662 | ttSetup.lineMode24 = 2; | |
663 | }; | |
664 | zoomR = Display::GetZoom(); // remember zoom | |
665 | modeR = Display::mode; // remember mode | |
666 | Display::Delete(); | |
667 | Display::SetMode(modeR, clrBackground); // new with remembered mode and background color | |
668 | Display::SetZoom(zoomR); // apply remembered zoom | |
669 | ShowPage(); | |
670 | break; | |
671 | ||
672 | case Config: | |
673 | DEBUG_OT_KEYS("key action: 'Config' lineMode24=%d configMode=%d", ttSetup.lineMode24, configMode); | |
674 | if (ttSetup.lineMode24 == 1) { | |
675 | // config mode is only supported in 25/27-line mode | |
676 | needClearMessage=true; | |
677 | delayClearMessage = 3; | |
678 | Display::DrawMessage(tr("*** Config mode is not supported in 24-line mode ***"), ttcYellow); | |
679 | break; | |
680 | }; | |
681 | switch(configMode) { | |
682 | case LastActionConfig : configMode = Left ; break; // start config mode | |
683 | case Left : configMode = Top ; break; | |
684 | case Top : configMode = Width ; break; | |
685 | case Width : configMode = Height ; break; | |
686 | case Height : configMode = Frame ; break; | |
687 | case Frame : configMode = Font ; break; | |
688 | case Font : configMode = Voffset ; break; | |
689 | case Voffset : configMode = BackTrans; break; | |
690 | case BackTrans : configMode = LastActionConfig; break; // stop config mode | |
691 | }; | |
692 | ShowPage(); | |
693 | break; | |
694 | ||
695 | case HotkeyLevelPlus: | |
696 | case HotkeyLevelMinus: | |
697 | if (ttSetup.lineMode24 == 1) { | |
698 | // HotkeyLevel switch mode is only supported in 25/27-line mode | |
699 | // otherwise one can get lost and has to enter plugin setup menu to disable 24-line mode there | |
700 | needClearMessage=true; | |
701 | delayClearMessage = 3; | |
702 | Display::DrawMessage(tr("Hotkey level change is not supported in 24-line mode"), ttcYellow); | |
703 | break; | |
704 | }; | |
705 | ||
706 | if (maxHotkeyLevel <= 1) { | |
707 | // HotkeyLevel disabled by command line option limit to 1 or default | |
708 | needClearMessage=true; | |
709 | delayClearMessage = 3; | |
710 | Display::DrawMessage(tr("Hotkey levels are disabled"), ttcRed); | |
711 | break; | |
712 | }; | |
713 | ||
714 | if (ttSetup.hotkeyLevelMax < 2) { | |
715 | // HotkeyLevel not active by setup limit to 1 | |
716 | needClearMessage=true; | |
717 | delayClearMessage = 3; | |
718 | Display::DrawMessage(tr("Hotkey levels are not active"), ttcYellow); | |
719 | break; | |
720 | }; | |
721 | ||
722 | switch(e) { | |
723 | case HotkeyLevelPlus: | |
724 | DEBUG_OT_KEYS("key action: 'HotkeyLevelPlus' current hotkeyLevel=%d ttSetup.hotkeyLevelMax=%d", hotkeyLevel, ttSetup.hotkeyLevelMax); | |
725 | hotkeyLevel++; | |
726 | if (hotkeyLevel == ttSetup.hotkeyLevelMax) | |
727 | hotkeyLevel = 0; // rollover to minimum | |
728 | break; | |
729 | ||
730 | case HotkeyLevelMinus: | |
731 | DEBUG_OT_KEYS("key action: 'HotkeyLevelMinus' current hotkeyLevel=%d ttSetup.hotkeyLevelMax=%d", hotkeyLevel, ttSetup.hotkeyLevelMax); | |
732 | hotkeyLevel--; | |
733 | if (hotkeyLevel < 0) | |
734 | hotkeyLevel = ttSetup.hotkeyLevelMax - 1; // rollover to maximum | |
735 | break; | |
736 | ||
318 | 737 | default: |
319 | //In osdteletext.c, numbers are thought to be decimal, the setup page | |
320 | //entries will display them in this way. It is a lot easier to do the | |
321 | //conversion to hexadecimal here. | |
322 | //This means, we convert the number to what it would be if the string | |
323 | //had been parsed with hexadecimal base. | |
324 | int pageNr=PSEUDO_HEX_TO_DECIMAL((int)e); | |
325 | if (0x100<=pageNr && pageNr<=0x899) { | |
326 | if (selectingChannel) { | |
327 | selectingChannel=false; | |
328 | Display::ClearMessage(); | |
329 | } | |
330 | SetPreviousPage(currentPage, currentSubPage, pageNr); | |
331 | currentPage=pageNr; | |
332 | cursorPos=0; | |
333 | currentSubPage=0; | |
334 | ||
335 | Display::ShowUpperHalf(); | |
336 | ShowPage(); | |
337 | } | |
738 | // will not reached but avoids compiler warning | |
338 | 739 | break; |
740 | }; | |
741 | ShowPage(); | |
742 | break; | |
743 | ||
744 | ||
745 | case OsdPresetPlus: | |
746 | case OsdPresetMinus: | |
747 | if (maxOsdPreset <= 1) { | |
748 | // OSD Preset disabled by command line option limit to 1 or default | |
749 | needClearMessage=true; | |
750 | delayClearMessage = 3; | |
751 | Display::DrawMessage(tr("OSD presets are disabled"), ttcRed); | |
752 | break; | |
753 | }; | |
754 | ||
755 | if (ttSetup.osdPresetMax <= 2) { | |
756 | // HotkeyLevel not active by setup limit to 1 | |
757 | needClearMessage=true; | |
758 | delayClearMessage = 3; | |
759 | Display::DrawMessage(tr("OSD presets are not active"), ttcYellow); | |
760 | break; | |
761 | }; | |
762 | ||
763 | switch(e) { | |
764 | case OsdPresetPlus: | |
765 | DEBUG_OT_KEYS("key action: 'OsdPresetPlus' current ttSetup.osdPreset=%d ttSetup.osdPresetMax=%d", ttSetup.osdPreset, ttSetup.osdPresetMax); | |
766 | ttSetup.osdPreset++; | |
767 | if (ttSetup.osdPreset == ttSetup.osdPresetMax) | |
768 | ttSetup.osdPreset = 0; // rollover to minimum | |
769 | break; | |
770 | ||
771 | case OsdPresetMinus: | |
772 | DEBUG_OT_KEYS("key action: 'HotkeyLevelMinus' current ttSetup.osdPreset=%d ttSetup.ttSetup.osdPresetMax=%d", ttSetup.osdPreset, ttSetup.osdPresetMax); | |
773 | ttSetup.osdPreset--; | |
774 | if (ttSetup.osdPreset < 0) | |
775 | ttSetup.osdPreset = ttSetup.osdPresetMax - 1; // rollover to maximum | |
776 | break; | |
777 | ||
778 | default: | |
779 | // will not reached but avoids compiler warning | |
780 | break; | |
781 | }; | |
782 | ||
783 | Display::Delete(); | |
784 | Display::SetMode(Display::Full, TTSETUPPRESET_TCOLOR(BackTrans)); | |
785 | ShowPage(); | |
786 | break; | |
787 | ||
788 | ||
789 | case ToggleConceal: | |
790 | DEBUG_OT_KEYS("key action: 'ToggleConceal' Concealed=%d -> %d", Display::GetConceal(), not(Display::GetConceal())); | |
791 | Display::SetConceal(not(Display::GetConceal())); | |
792 | ShowPage(); | |
793 | break; | |
794 | ||
795 | case TogglePause: | |
796 | if ((ChannelInfo == ChannelIsLive) || (ChannelInfo == ChannelIsTuned)) { | |
797 | DEBUG_OT_KEYS("key action: 'TogglePause' paused=%d -> %d", Display::GetPaused(), not(Display::GetPaused())); | |
798 | // toggle paused status only if LIVE or TUNED channel (otherwise useless) | |
799 | Display::SetPaused(not(Display::GetPaused())); | |
800 | ShowPage(); | |
801 | } else { | |
802 | DEBUG_OT_KEYS("key action: 'TogglePause' useless, currently not a LIVE or TUNED channel on OSD"); | |
803 | }; | |
804 | break; | |
805 | ||
806 | default: | |
807 | //In osdteletext.c, numbers are thought to be decimal, the setup page | |
808 | //entries will display them in this way. It is a lot easier to do the | |
809 | //conversion to hexadecimal here. | |
810 | //This means, we convert the number to what it would be if the string | |
811 | //had been parsed with hexadecimal base. | |
812 | int pageNr=PSEUDO_HEX_TO_DECIMAL((int)e); | |
813 | if (0x100<=pageNr && pageNr<=0x899) { | |
814 | if (selectingChannel) { | |
815 | selectingChannel=false; | |
816 | Display::ClearMessage(); | |
817 | } | |
818 | SetPreviousPage(currentPage, currentSubPage, pageNr); | |
819 | currentPage=pageNr; | |
820 | cursorPos=0; | |
821 | currentSubPage=0; | |
822 | ||
823 | Display::ShowUpperHalf(); | |
824 | ShowPage(); | |
339 | 825 | } |
826 | break; | |
827 | } | |
340 | 828 | } |
341 | 829 | |
342 | 830 | // 3-state toggling between configured->transparent->black. |
343 | 831 | // If configured is black or transparent, do 2-state transparent->black only. |
344 | 832 | void TeletextBrowser::ChangeBackground() |
345 | 833 | { |
346 | tColor clrConfig = (tColor)ttSetup.configuredClrBackground; | |
347 | tColor clrCurrent = Display::GetBackgroundColor(); | |
834 | tColor clrConfig = TTSETUPPRESET_TCOLOR(BackTrans); | |
835 | tColor clrCurrent = clrBackground; | |
348 | 836 | |
349 | 837 | if (clrCurrent == clrConfig) |
350 | 838 | if (clrConfig == clrTransparent) |
351 | Display::SetBackgroundColor(clrBlack); | |
839 | clrBackground = clrBlack; | |
352 | 840 | else |
353 | Display::SetBackgroundColor(clrTransparent); | |
841 | clrBackground = clrTransparent; | |
354 | 842 | else if (clrCurrent == clrBlack) |
355 | 843 | if (clrConfig == clrBlack) |
356 | Display::SetBackgroundColor(clrTransparent); | |
844 | clrBackground = clrTransparent; | |
357 | 845 | else |
358 | Display::SetBackgroundColor(clrConfig); | |
846 | clrBackground = clrConfig; | |
359 | 847 | else // clrCurrent == clrTransparent |
360 | Display::SetBackgroundColor(clrBlack); | |
848 | clrBackground = clrBlack; | |
849 | ||
850 | Display::SetBackgroundColor(clrBackground); | |
361 | 851 | } |
362 | 852 | |
363 | 853 | eTeletextAction TeletextBrowser::TranslateKey(eKeys Key) { |
364 | 854 | switch(Key) { |
365 | case kRed: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyRed]; | |
366 | case kGreen: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyGreen]; | |
367 | case kYellow: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyYellow]; | |
368 | case kBlue: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyBlue]; | |
369 | case kPlay: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyPlay]; | |
370 | //case kPause: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyPause]; | |
371 | case kStop: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyStop]; | |
372 | //case kRecord: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyRecord]; | |
373 | case kFastFwd: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyFastFwd]; | |
374 | case kFastRew: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyFastRew]; | |
375 | default: return (eTeletextAction)100; //just to keep gcc quiet | |
855 | case kRed: return (eTeletextAction)ttSetup.mapHotkeyToAction[ActionHotkeyRed] [hotkeyLevel]; | |
856 | case kGreen: return (eTeletextAction)ttSetup.mapHotkeyToAction[ActionHotkeyGreen] [hotkeyLevel]; | |
857 | case kYellow: return (eTeletextAction)ttSetup.mapHotkeyToAction[ActionHotkeyYellow][hotkeyLevel]; | |
858 | case kBlue: return (eTeletextAction)ttSetup.mapHotkeyToAction[ActionHotkeyBlue] [hotkeyLevel]; | |
859 | case kPlay: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyPlay]; | |
860 | //case kPause: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyPause]; // not passed into plugin somehow | |
861 | case kOk: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyOk]; | |
862 | case kStop: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyStop]; | |
863 | //case kRecord: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyRecord]; // not passed into plugin somehow | |
864 | case kFastFwd: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyFastFwd]; | |
865 | case kFastRew: return (eTeletextAction)ttSetup.mapKeyToAction[ActionKeyFastRew]; | |
866 | default: return (eTeletextAction)100; //just to keep gcc quiet | |
376 | 867 | } |
377 | 868 | } |
378 | 869 | |
545 | 1036 | |
546 | 1037 | |
547 | 1038 | |
548 | void TeletextBrowser::ShowPage() { | |
549 | if ((pageFound=DecodePage())) { | |
1039 | void TeletextBrowser::ShowPage(bool suppressMessage) { | |
1040 | if ((pageFound=DecodePage(suppressMessage))) { | |
550 | 1041 | if (ttSetup.autoUpdatePage) |
551 | 1042 | checkSum=PageCheckSum(); |
552 | 1043 | } |
553 | 1044 | } |
554 | 1045 | |
555 | 1046 | void TeletextBrowser::ShowPageNumber() { |
556 | char str[8]; | |
557 | sprintf(str, "%3x-%02x", currentPage, currentSubPage); | |
1047 | DEBUG_OT_DRPI("called with currentPage=%03x currentSubPage=%02x", currentPage, currentSubPage); | |
1048 | char str[9]; | |
1049 | snprintf(str, sizeof(str), "%3x-%02x ", currentPage, currentSubPage); | |
558 | 1050 | if (cursorPos>0) { |
559 | 1051 | str[2]='*'; |
560 | 1052 | if (cursorPos==1) |
561 | 1053 | str[1]='*'; |
562 | 1054 | } |
563 | Display::DrawPageId(str); | |
1055 | ||
1056 | if (ChannelInfo == ChannelIsTuned) { | |
1057 | str[7]='t'; | |
1058 | Display::DrawPageId(str, ttcMagenta, true); // colored | |
1059 | } | |
1060 | else if (liveChannelNumber != currentChannelNumber) { | |
1061 | str[7]='c'; | |
1062 | Display::DrawPageId(str, ttcCyan, true); // colored | |
1063 | } | |
1064 | else | |
1065 | Display::DrawPageId(str); | |
564 | 1066 | } |
565 | 1067 | |
566 | 1068 | void TeletextBrowser::ShowAskForChannel() { |
567 | 1069 | if (selectingChannel) { |
568 | 1070 | cString str = cString::sprintf(selectingChannelNumber > 0 ? "%s%d" : "%s", tr("Channel (press OK): "), selectingChannelNumber); |
569 | Display::DrawMessage(str); | |
1071 | Display::DrawMessage(str, ttcBlue); | |
570 | 1072 | } |
571 | 1073 | } |
572 | 1074 | |
573 | 1075 | //this is taken and adapted from the teletext plugin since it uses its data |
574 | bool TeletextBrowser::DecodePage() { | |
1076 | bool TeletextBrowser::DecodePage(bool suppressMessage) { | |
575 | 1077 | // Load the page and decodes it |
576 | unsigned char cache[40*24+12]; | |
1078 | unsigned char cache[sizeof(TelePageData)]; | |
577 | 1079 | StorageHandle fd; |
578 | 1080 | // Take a look if there is a xxx-00 page |
579 | 1081 | if (currentSubPage==0) { |
597 | 1099 | Display::RenderTeletextCode(cache); |
598 | 1100 | ShowPageNumber(); |
599 | 1101 | UpdateClock(); |
1102 | UpdateHotkey(); | |
600 | 1103 | Display::ReleaseFlush(); |
601 | 1104 | } else { |
602 | 1105 | // page doesn't exist |
603 | 1106 | currentSubPage--; |
604 | 1107 | |
605 | 1108 | Display::HoldFlush(); |
606 | ShowPageNumber(); | |
607 | 1109 | char str[80]; |
608 | snprintf(str,80, "%s %3x-%02x %s",tr("Page"),currentPage, currentSubPage,tr("not found")); | |
609 | Display::DrawMessage(str); | |
1110 | char str2[80]; | |
1111 | snprintf(str2, sizeof(str2), "%d: %s", channelClass.Number(), channelClass.Name()); | |
1112 | enumTeletextColor color = ttcYellow; | |
1113 | if (ChannelInfo == ChannelHasNoTeletext) { | |
1114 | snprintf(str, sizeof(str), "%s %s (%s %s)", tr("Switch to"), tr("Channel"), tr("without"), tr("Teletext")); | |
1115 | color = ttcRed; | |
1116 | } else { | |
1117 | ShowPageNumber(); | |
1118 | snprintf(str, sizeof(str), "%s %3x-%02x%s%s %s%s%s%s",tr("Page"),currentPage, currentSubPage | |
1119 | , (ChannelInfo == ChannelIsCached) ? " " : "" | |
1120 | , (ChannelInfo == ChannelIsCached) ? tr("in cache") : "" | |
1121 | , tr("not found") | |
1122 | , ((ChannelInfo == ChannelIsTuned) || (ChannelInfo == ChannelIsLive)) ? " (" : "" | |
1123 | , ((ChannelInfo == ChannelIsTuned) || (ChannelInfo == ChannelIsLive)) ? tr("please wait") : "" | |
1124 | , ((ChannelInfo == ChannelIsTuned) || (ChannelInfo == ChannelIsLive)) ? ")" : "" | |
1125 | ); | |
1126 | if (ChannelInfo == ChannelIsTuned) { | |
1127 | color = ttcMagenta; | |
1128 | } else if (ChannelInfo == ChannelIsCached) { | |
1129 | color = ttcRed; | |
1130 | }; | |
1131 | }; | |
1132 | if (! suppressMessage) { | |
1133 | needClearMessage = false; | |
1134 | Display::DrawMessage(str, str2, color); | |
1135 | }; | |
1136 | UpdateHotkey(); | |
610 | 1137 | Display::ReleaseFlush(); |
611 | 1138 | |
612 | 1139 | return false; |
639 | 1166 | Display::DrawClock(); |
640 | 1167 | } |
641 | 1168 | |
1169 | // convert action to text | |
1170 | // implant hotkeyLevel number for related action | |
1171 | // implant ttSetup.osdPreset number for related actions if maximum is > 1 | |
1172 | // implant hotkeyLevel/osdPreset +/- in case of text length is above limit-2 | |
1173 | #define CONVERT_ACTION_TO_TEXT(text, mode, limit) \ | |
1174 | if ((mode == HotkeyLevelPlus) || (mode == HotkeyLevelMinus)) { \ | |
1175 | snprintf(text, sizeof(text), "%-40s", tr(st_modesHotkey[mode])); \ | |
1176 | if (strlen(tr(st_modesHotkey[mode])) > limit - 1) text[limit - 2] = (mode == HotkeyLevelPlus) ? '+' : '-'; \ | |
1177 | text[limit - 1] = '0' + (int) hotkeyLevel + 1; \ | |
1178 | text[limit] = '\0'; \ | |
1179 | } else if ((mode == OsdPresetPlus) || (mode == OsdPresetMinus)) { \ | |
1180 | snprintf(text, sizeof(text), "%-40s", tr(st_modesHotkey[mode])); \ | |
1181 | if (strlen(tr(st_modesHotkey[mode])) > limit - 1) text[limit - 2] = (mode == OsdPresetPlus) ? '+' : '-'; \ | |
1182 | text[limit - 1] = '0' + (int) ttSetup.osdPreset + 1; \ | |
1183 | text[limit] = '\0'; \ | |
1184 | } else if ((mode == Config) && (ttSetup.osdPresetMax > 1) && (configMode != LastActionConfig)) { \ | |
1185 | snprintf(text, sizeof(text), "%-40s", tr(st_modesHotkey[mode])); \ | |
1186 | text[limit - 2] = ' '; \ | |
1187 | text[limit - 1] = '0' + (int) ttSetup.osdPreset + 1; \ | |
1188 | text[limit] = '\0'; \ | |
1189 | } else if ((int) mode < 100) { \ | |
1190 | snprintf(text, sizeof(text), "%s", tr(st_modesHotkey[mode])); \ | |
1191 | } else if ((int) mode < 999) { \ | |
1192 | snprintf(text, sizeof(text), "-> %03d", mode); \ | |
1193 | } else { \ | |
1194 | snprintf(text, sizeof(text), "ERROR"); \ | |
1195 | }; \ | |
1196 | ||
1197 | ||
1198 | void TeletextBrowser::UpdateHotkey() { | |
1199 | DEBUG_OT_HOTK("called with lineMode24=%d", ttSetup.lineMode24); | |
1200 | ||
1201 | if (ttSetup.lineMode24 == 1) return; // nothing to do | |
1202 | ||
1203 | char textRed[81]= "", textGreen[81] = "", textYellow[81] = "", textBlue[81] = ""; // 40x UTF-8 char + \0 | |
1204 | HotkeyFlags flag = HotkeyNormal; // default | |
1205 | eTeletextActionValueType valueType = None; | |
1206 | ||
1207 | if (configMode == LastActionConfig) { | |
1208 | eTeletextAction AkRed = TranslateKey(kRed); | |
1209 | eTeletextAction AkGreen = TranslateKey(kGreen); | |
1210 | eTeletextAction AkYellow = TranslateKey(kYellow); | |
1211 | eTeletextAction AkBlue = TranslateKey(kBlue); | |
1212 | DEBUG_OT_HOTK("AkRed=%d AkGreen=%d AkYellow=%d AkBlue=%d", AkRed, AkGreen, AkYellow, AkBlue); | |
1213 | ||
1214 | CONVERT_ACTION_TO_TEXT(textRed , AkRed , 10); | |
1215 | CONVERT_ACTION_TO_TEXT(textGreen , AkGreen , 10); | |
1216 | CONVERT_ACTION_TO_TEXT(textYellow, AkYellow, 10); | |
1217 | CONVERT_ACTION_TO_TEXT(textBlue , AkBlue , 10); | |
1218 | } else { | |
1219 | switch (configMode) { | |
1220 | case Left: | |
1221 | case Top: | |
1222 | case Width: | |
1223 | case Height: | |
1224 | case Frame: | |
1225 | case Voffset: | |
1226 | case BackTrans: | |
1227 | snprintf(textRed , sizeof(textRed) , "%s-", tr(config_modes[configMode])); // <mode>- | |
1228 | snprintf(textGreen , sizeof(textGreen) , "%s+", tr(config_modes[configMode])); // <mode>+ | |
1229 | flag = HotkeyYellowValue; | |
1230 | break; | |
1231 | ||
1232 | case Font: | |
1233 | snprintf(textRed , sizeof(textRed) , "%s" , tr(config_modes[configMode])); // <mode> | |
1234 | DEBUG_OT_HOTK("txtFontIndex=%d txtFontNames[%d]='%s'", TTSETUPPRESET(Font), TTSETUPPRESET(Font), ttSetup.txtFontNames[TTSETUPPRESET(Font)]); | |
1235 | snprintf(textGreen, sizeof(textGreen) , "%s", ttSetup.txtFontNames[TTSETUPPRESET(Font)]); // FontName | |
1236 | flag = HotkeyGreenYellowValue; | |
1237 | break; | |
1238 | ||
1239 | default: | |
1240 | break; | |
1241 | }; | |
1242 | ||
1243 | int valueInt = 0; | |
1244 | char *valueStr = NULL; | |
1245 | switch (configMode) { | |
1246 | case Left: | |
1247 | case Top: | |
1248 | case Width: | |
1249 | case Height: | |
1250 | valueInt = TTSETUPPRESET(configMode); | |
1251 | valueType = Pct; | |
1252 | break; | |
1253 | ||
1254 | case Frame: | |
1255 | case Voffset: | |
1256 | valueInt = TTSETUPPRESET(configMode); | |
1257 | valueType = Pix; | |
1258 | break; | |
1259 | ||
1260 | case BackTrans: | |
1261 | valueInt = TTSETUPPRESET(configMode); | |
1262 | valueType = Int; | |
1263 | break; | |
1264 | ||
1265 | default: | |
1266 | break; | |
1267 | }; | |
1268 | ||
1269 | switch(valueType) { | |
1270 | case Pct: | |
1271 | snprintf(textYellow, sizeof(textYellow), "%d %%", valueInt); | |
1272 | break; | |
1273 | ||
1274 | case Pix: | |
1275 | snprintf(textYellow, sizeof(textYellow), "%d Px", valueInt); | |
1276 | break; | |
1277 | ||
1278 | case Int: | |
1279 | snprintf(textYellow, sizeof(textYellow), "%d", valueInt); | |
1280 | break; | |
1281 | ||
1282 | case Str: | |
1283 | if (valueStr != NULL) | |
1284 | snprintf(textYellow, sizeof(textYellow), "%s", valueStr); | |
1285 | else | |
1286 | snprintf(textYellow, sizeof(textYellow), "%s", "ERROR-STR"); // should not happen | |
1287 | break; | |
1288 | ||
1289 | case None: | |
1290 | // handled above directly | |
1291 | break; | |
1292 | ||
1293 | default: | |
1294 | snprintf(textYellow, sizeof(textYellow), "%s", "ERROR"); // should not happen | |
1295 | break; | |
1296 | }; | |
1297 | ||
1298 | CONVERT_ACTION_TO_TEXT(textBlue, Config, 10); // option itself with optional preset number | |
1299 | }; | |
1300 | ||
1301 | DEBUG_OT_HOTK("textRed='%s' textGreen='%s' text Yellow='%s' textBlue='%s' flag=%d", textRed, textGreen, textYellow, textBlue, flag); | |
1302 | Display::DrawHotkey(textRed, textGreen, textYellow, textBlue, flag); | |
1303 | ||
1304 | if (ttSetup.lineMode24 != 2) return; // nothing more to do | |
1305 | ||
1306 | // Hint lines | |
1307 | char textH1[81]= "FastRew", textH2[81] = "Stop", textH3[81] = "OK", textH4[81] = "Play", textH5[81] = "FastFwd"; // 40x UTF-8 char + \0 | |
1308 | ||
1309 | Display::DrawHints(textH1, textH2, textH3, textH4, textH5, HintsKey); | |
1310 | ||
1311 | eTeletextAction AkFastRew = TranslateKey(kFastRew); | |
1312 | eTeletextAction AkFastFwd = TranslateKey(kFastFwd); | |
1313 | eTeletextAction AkStop = TranslateKey(kStop); | |
1314 | eTeletextAction AkOk = TranslateKey(kOk); | |
1315 | eTeletextAction AkPlay = TranslateKey(kPlay); | |
1316 | DEBUG_OT_HOTK("AkFastRew=%d AkStop=%d AkOk=%d AkPlay=%d AkFastFwd=%d", AkFastRew, AkStop, AkOk, AkPlay, AkFastFwd); | |
1317 | ||
1318 | CONVERT_ACTION_TO_TEXT(textH1, AkFastRew, 8); | |
1319 | CONVERT_ACTION_TO_TEXT(textH2, AkStop , 8); | |
1320 | CONVERT_ACTION_TO_TEXT(textH3, AkOk , 8); | |
1321 | CONVERT_ACTION_TO_TEXT(textH4, AkPlay , 8); | |
1322 | CONVERT_ACTION_TO_TEXT(textH5, AkFastFwd, 8); | |
1323 | Display::DrawHints(textH1, textH2, textH3, textH4, textH5, HintsValue); | |
1324 | } | |
1325 | ||
642 | 1326 | TeletextSetup ttSetup; |
643 | 1327 | |
644 | 1328 | TeletextSetup::TeletextSetup() |
645 | 1329 | //Set default values for setup options |
646 | : configuredClrBackground(clrGray50), showClock(true), | |
647 | suspendReceiving(false), autoUpdatePage(true), | |
648 | //OSDHeight+width default values given in Start() | |
649 | OSDHAlign(50), OSDVAlign(50), | |
650 | //use the value set for VDR's min user inactivity. | |
651 | //Initially this value could be changed via the plugin's setup, but I removed that | |
652 | //because there is no advantage, but a possible problem when VDR's value is change | |
653 | //after the plugin has stored its own value. | |
654 | inactivityTimeout(Setup.MinUserInactivity), | |
1330 | : | |
1331 | migrationFlag_2_2(false), | |
1332 | showClock(true), | |
1333 | autoUpdatePage(true), | |
1334 | osdPresetMax(1), | |
1335 | hotkeyLevelMax(1), | |
655 | 1336 | HideMainMenu(false), |
656 | txtFontName("teletext2:Medium") | |
1337 | colorMode4bpp(false), | |
1338 | lineMode24(0) | |
657 | 1339 | { |
1340 | // init osdConfig | |
1341 | int p = 0; | |
1342 | ||
1343 | // Preset "default" | |
1344 | osdConfig[Left] [p] = 15; | |
1345 | osdConfig[Top] [p] = 5; | |
1346 | osdConfig[Width] [p] = 70; | |
1347 | osdConfig[Height] [p] = 90; | |
1348 | osdConfig[Frame] [p] = 0; | |
1349 | osdConfig[Font] [p] = 0; | |
1350 | osdConfig[Voffset] [p] = 0; | |
1351 | osdConfig[BackTrans][p] = 128; | |
1352 | ||
1353 | // Preset "2" .. "5" 50% in corners | |
1354 | for (p = 1; p < 5; p++) { | |
1355 | if (p < OSD_PRESET_MAX_LIMIT) { | |
1356 | if ((p == 1) || (p == 4)) | |
1357 | osdConfig[Left] [p] = 0; | |
1358 | else | |
1359 | osdConfig[Left] [p] = 50; | |
1360 | if ((p == 1) || (p == 2)) | |
1361 | osdConfig[Top] [p] = 0; | |
1362 | else | |
1363 | osdConfig[Top] [p] = 50; | |
1364 | osdConfig[Width] [p] = 50; | |
1365 | osdConfig[Height] [p] = 50; | |
1366 | osdConfig[Frame] [p] = 8; | |
1367 | osdConfig[Font] [p] = 0; | |
1368 | osdConfig[Voffset] [p] = 0; | |
1369 | if (p == 1) | |
1370 | osdConfig[BackTrans][p] = 0; | |
1371 | else if (p == 2) | |
1372 | osdConfig[BackTrans][p] = 64; | |
1373 | else if (p == 3) | |
1374 | osdConfig[BackTrans][p] = 192; | |
1375 | else if (p == 4) | |
1376 | osdConfig[BackTrans][p] = 255; | |
1377 | }; | |
1378 | }; | |
1379 | ||
1380 | // Preset "6" .. "9" 25% in corners | |
1381 | for (p = 5; p < 9; p++) { | |
1382 | if (p < OSD_PRESET_MAX_LIMIT) { | |
1383 | if ((p == 5) || (p == 8)) | |
1384 | osdConfig[Left] [p] = 0; | |
1385 | else | |
1386 | osdConfig[Left] [p] = 75; | |
1387 | if ((p == 5) || (p == 6)) | |
1388 | osdConfig[Top] [p] = 0; | |
1389 | else | |
1390 | osdConfig[Top] [p] = 75; | |
1391 | osdConfig[Width] [p] = 25; | |
1392 | osdConfig[Height] [p] = 25; | |
1393 | osdConfig[Frame] [p] = 4; | |
1394 | osdConfig[Font] [p] = 0; | |
1395 | osdConfig[Voffset] [p] = 0; | |
1396 | if (p == 5) | |
1397 | osdConfig[BackTrans][p] = 0; | |
1398 | else if (p == 6) | |
1399 | osdConfig[BackTrans][p] = 64; | |
1400 | else if (p == 7) | |
1401 | osdConfig[BackTrans][p] = 192; | |
1402 | else if (p == 8) | |
1403 | osdConfig[BackTrans][p] = 255; | |
1404 | }; | |
1405 | }; | |
1406 | ||
658 | 1407 | //init key bindings |
659 | for (int i=0;i<10;i++) | |
660 | mapKeyToAction[0]=(eTeletextAction)0; | |
661 | mapKeyToAction[3]=Zoom; | |
662 | mapKeyToAction[2]=HalfPage; | |
663 | mapKeyToAction[0]=SwitchChannel; | |
664 | } | |
1408 | for (int i=0; i < LastActionKey; i++) | |
1409 | mapKeyToAction[i]=(eTeletextAction)0; | |
1410 | ||
1411 | mapKeyToAction[ActionKeyStop]=Config; | |
1412 | mapKeyToAction[ActionKeyFastRew]=LineMode24; | |
1413 | mapKeyToAction[ActionKeyFastFwd]=ToggleConceal; | |
1414 | mapKeyToAction[ActionKeyOk]=TogglePause; | |
1415 | ||
1416 | // init Hotkey bindings | |
1417 | for (int i=0; i < LastActionHotkey; i++) | |
1418 | for (int l = 0; l < HOTKEY_LEVEL_MAX_LIMIT; l++) | |
1419 | mapHotkeyToAction[i][l]=(eTeletextAction)0; | |
1420 | ||
1421 | int l = 0; | |
1422 | // hot key mapping for level 1 (default) | |
1423 | if (l < HOTKEY_LEVEL_MAX_LIMIT) { | |
1424 | mapHotkeyToAction[ActionHotkeyRed] [l] = DarkScreen; | |
1425 | mapHotkeyToAction[ActionHotkeyGreen] [l] = (eTeletextAction) 100; // page 100 | |
1426 | mapHotkeyToAction[ActionHotkeyYellow][l] = HalfPage; | |
1427 | mapHotkeyToAction[ActionHotkeyBlue] [l] = Zoom; | |
1428 | }; | |
1429 | ||
1430 | // hot key mapping for level 2 | |
1431 | l++; | |
1432 | if (l < HOTKEY_LEVEL_MAX_LIMIT) { | |
1433 | mapHotkeyToAction[ActionHotkeyRed] [l] = SwitchChannel; | |
1434 | mapHotkeyToAction[ActionHotkeyGreen] [l] = ToggleConceal; | |
1435 | mapHotkeyToAction[ActionHotkeyYellow][l] = TogglePause; | |
1436 | mapHotkeyToAction[ActionHotkeyBlue] [l] = HotkeyLevelPlus; | |
1437 | }; | |
1438 | ||
1439 | // hot key mapping for level 3 | |
1440 | l++; | |
1441 | if (l < HOTKEY_LEVEL_MAX_LIMIT) { | |
1442 | mapHotkeyToAction[ActionHotkeyRed] [l] = LineMode24; | |
1443 | mapHotkeyToAction[ActionHotkeyGreen] [l] = (eTeletextAction) 150; // page 150 ARD Subtitle | |
1444 | mapHotkeyToAction[ActionHotkeyYellow][l] = (eTeletextAction) 777; // page 777 3sat Subtitle | |
1445 | mapHotkeyToAction[ActionHotkeyBlue] [l] = HotkeyLevelPlus; | |
1446 | }; | |
1447 | ||
1448 | // hot key mapping for level 4 | |
1449 | l++; | |
1450 | if (l < HOTKEY_LEVEL_MAX_LIMIT) { | |
1451 | mapHotkeyToAction[ActionHotkeyRed] [l] = HotkeyLevelMinus; | |
1452 | mapHotkeyToAction[ActionHotkeyGreen] [l] = (eTeletextAction) 200; // page 200 | |
1453 | mapHotkeyToAction[ActionHotkeyYellow][l] = (eTeletextAction) 300; // page 300 | |
1454 | mapHotkeyToAction[ActionHotkeyBlue] [l] = HotkeyLevelPlus; | |
1455 | }; | |
1456 | ||
1457 | // hot key mapping for level 5 | |
1458 | l++; | |
1459 | if (l < HOTKEY_LEVEL_MAX_LIMIT) { | |
1460 | mapHotkeyToAction[ActionHotkeyRed] [l] = (eTeletextAction) 898; // page 898 3sat Test#1 | |
1461 | mapHotkeyToAction[ActionHotkeyGreen] [l] = (eTeletextAction) 199; // page 199 ARD/ZDF Test | |
1462 | mapHotkeyToAction[ActionHotkeyYellow][l] = (eTeletextAction) 886; // page 886 ORF2 Test | |
1463 | mapHotkeyToAction[ActionHotkeyBlue] [l] = HotkeyLevelPlus; | |
1464 | }; | |
1465 | ||
1466 | // default for other levels | |
1467 | l++; | |
1468 | while (l < HOTKEY_LEVEL_MAX_LIMIT) { | |
1469 | mapHotkeyToAction[ActionHotkeyRed] [l] = (eTeletextAction) 100 + l; // page 100 + l | |
1470 | mapHotkeyToAction[ActionHotkeyGreen] [l] = (eTeletextAction) 200 + l; // page 200 + l | |
1471 | mapHotkeyToAction[ActionHotkeyYellow][l] = (eTeletextAction) 300 + l; // page 300 + l | |
1472 | mapHotkeyToAction[ActionHotkeyBlue] [l] = HotkeyLevelPlus; | |
1473 | l++; | |
1474 | } | |
1475 | } | |
1476 | ||
1477 | // vim: ts=3 sw=3 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | 1 | * Copyright (c) 2003,2004 by Marcel Wiesweg * |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
2 | 3 | * * |
3 | 4 | * This program is free software; you can redistribute it and/or modify * |
4 | 5 | * it under the terms of the GNU General Public License as published by * |
19 | 20 | #include "txtrecv.h" |
20 | 21 | #include "setup.h" |
21 | 22 | |
22 | extern int Stretch; | |
23 | // status of current channel | |
24 | enum eChannelInfo { | |
25 | ChannelIsLive, | |
26 | ChannelIsTuned, | |
27 | ChannelIsCached, | |
28 | ChannelWasTuned, | |
29 | ChannelWasTunedNewChannelIsLive, | |
30 | ChannelHasNoTeletext | |
31 | }; | |
23 | 32 | |
24 | 33 | class TeletextBrowser : public cOsdObject { |
25 | 34 | public: |
26 | 35 | TeletextBrowser(cTxtStatus *txtSt,Storage *s); |
27 | 36 | ~TeletextBrowser(); |
28 | 37 | void Show(void); |
29 | static void ChannelSwitched(int ChannelNumber); | |
38 | static void ChannelSwitched(int ChannelNumber, const eChannelInfo info); | |
30 | 39 | virtual eOSState ProcessKey(eKeys Key); |
31 | 40 | protected: |
32 | 41 | enum Direction { DirectionForward, DirectionBackward }; |
33 | 42 | void SetNumber(int i); |
34 | void ShowPage(); | |
43 | void ShowPage(bool suppressMessage = false); | |
35 | 44 | void UpdateClock(); |
36 | bool DecodePage(); | |
45 | void UpdateHotkey(); | |
46 | bool DecodePage(bool suppressMessage = false); | |
37 | 47 | void ChangePageRelative(Direction direction); |
38 | 48 | void ChangeSubPageRelative(Direction direction); |
39 | 49 | bool CheckPage(); |
44 | 54 | int PageCheckSum(); |
45 | 55 | void ShowPageNumber(); |
46 | 56 | void ExecuteAction(eTeletextAction e); |
57 | bool ExecuteActionConfig(eTeletextActionConfig e, int delta); | |
47 | 58 | int nextValidPageNumber(int start, Direction direction); |
59 | bool TriggerChannelSwitch(const int channelNumber); | |
48 | 60 | char fileName[PATH_MAX]; |
49 | 61 | char page[40][24]; |
50 | 62 | int cursorPos; |
51 | 63 | eTeletextAction TranslateKey(eKeys Key); |
52 | 64 | bool pageFound; |
53 | 65 | bool selectingChannel; |
66 | static eChannelInfo ChannelInfo; | |
67 | int hotkeyLevel; | |
68 | int delayClearMessage; | |
54 | 69 | bool needClearMessage; |
55 | 70 | int selectingChannelNumber; |
56 | 71 | int checkSum; |
57 | 72 | cTxtStatus *txtStatus; |
73 | bool paused; | |
58 | 74 | bool suspendedReceiving; |
59 | 75 | int previousPage; |
60 | 76 | int previousSubPage; |
63 | 79 | int inactivityTimeout; |
64 | 80 | static int currentPage; |
65 | 81 | static int currentSubPage; |
66 | static tChannelID channel; | |
82 | static tChannelID channel; // TODO: rename to channelId | |
83 | static cChannel channelClass; | |
67 | 84 | static int currentChannelNumber; |
85 | static int liveChannelNumber; | |
86 | static bool switchChannelInProgress; | |
68 | 87 | static TeletextBrowser* self; |
69 | 88 | Storage *storage; |
70 | 89 | private: |
74 | 93 | |
75 | 94 | #endif |
76 | 95 | |
96 | // vim: ts=3 sw=3 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | 1 | * Copyright (c) 2003,2004 by Marcel Wiesweg * |
2 | * (autogenerated code (c) Klaus Schmidinger) | |
2 | * (autogenerated code (c) Klaus Schmidinger) * | |
3 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
3 | 4 | * * |
4 | 5 | * This program is free software; you can redistribute it and/or modify * |
5 | 6 | * it under the terms of the GNU General Public License as published by * |
22 | 23 | #include "setup.h" |
23 | 24 | #include "legacystorage.h" |
24 | 25 | #include "packedstorage.h" |
26 | #include "logging.h" | |
25 | 27 | |
26 | 28 | #if defined(APIVERSNUM) && APIVERSNUM < 10739 |
27 | 29 | #error "VDR-1.7.39 API version or greater is required!" |
29 | 31 | |
30 | 32 | #define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0])) |
31 | 33 | |
32 | static const char *VERSION = "0.9.7"; | |
34 | static const char *VERSION = "2.3.0"; | |
33 | 35 | static const char *DESCRIPTION = trNOOP("Displays teletext on the OSD"); |
34 | 36 | static const char *MAINMENUENTRY = trNOOP("Teletext"); |
37 | ||
38 | extern tColor clrBackground; | |
39 | ||
40 | unsigned int m_debugmask = 0; | |
41 | unsigned int m_debugpage = 0; | |
42 | unsigned int m_debugpsub = 0; | |
43 | int maxOsdPreset = 1; | |
44 | int maxHotkeyLevel = 1; | |
45 | int m_debugline = -1; | |
35 | 46 | |
36 | 47 | class cPluginTeletextosd : public cPlugin { |
37 | 48 | private: |
43 | 54 | int maxStorage; |
44 | 55 | void initTexts(); |
45 | 56 | Storage::StorageSystem storageSystem; |
57 | ||
46 | 58 | public: |
47 | 59 | cPluginTeletextosd(void); |
48 | 60 | virtual ~cPluginTeletextosd(); |
60 | 72 | }; |
61 | 73 | |
62 | 74 | class cTeletextSetupPage; |
75 | ||
76 | // macro for creating setup string with given text and conditional index+1 suffix | |
77 | #define CREATE_SETUP_STRING_COND_SUFFIX(index, text) \ | |
78 | if (index == 0) \ | |
79 | snprintf(str, sizeof(str), "%s", text); \ | |
80 | else \ | |
81 | snprintf(str, sizeof(str), "%s%d", text, index + 1); | |
82 | ||
63 | 83 | class ActionEdit { |
64 | 84 | public: |
65 | 85 | void Init(cTeletextSetupPage*, int, cMenuEditIntItem *, cMenuEditStraItem *); |
86 | void Init(cTeletextSetupPage*, int, int, bool, cMenuEditIntItem *, cMenuEditStraItem *); | |
66 | 87 | cMenuEditStraItem *action; |
67 | 88 | cMenuEditIntItem *number; |
68 | bool visible; | |
69 | 89 | }; |
70 | 90 | |
71 | 91 | struct ActionKeyName { |
75 | 95 | |
76 | 96 | class cTeletextSetupPage : public cMenuSetupPage { |
77 | 97 | friend class ActionEdit; |
98 | friend class cPluginTeletextosd; | |
78 | 99 | private: |
79 | 100 | TeletextSetup temp; |
101 | int osdPreset; | |
102 | int hotkeyLevel; | |
80 | 103 | int tempPageNumber[LastActionKey]; |
81 | int tempConfiguredClrBackground; //must be a signed int | |
104 | int tempPageNumberHotkey[LastActionHotkey][HOTKEY_LEVEL_MAX_LIMIT]; | |
105 | cOsdItem *osdPresetMaxItem; | |
106 | cOsdItem *osdPresetItem; | |
107 | cString osdPresetString; | |
108 | cOsdItem *osdPresetConfigItem[LastActionConfig][OSD_PRESET_MAX_LIMIT]; // array of supported configuration items | |
109 | cOsdItem *menuSectionKeysItem; | |
110 | cOsdItem *hotkeyLevelMaxItem; | |
111 | cOsdItem *hotkeyLevelItem; | |
112 | cString hotkeyLevelString; | |
82 | 113 | protected: |
83 | 114 | virtual void Store(void); |
115 | int osdConfig[LastActionConfig][OSD_PRESET_MAX_LIMIT]; // matrix of supported presets | |
84 | 116 | ActionEdit ActionEdits[LastActionKey]; |
117 | ActionEdit ActionEditsHotkey[LastActionHotkey][HOTKEY_LEVEL_MAX_LIMIT]; | |
118 | void SetupRefreshKeys(void); | |
119 | void SetupRefreshHotkeys(void); | |
120 | void SetupRefreshOsdConfig(void); | |
85 | 121 | virtual eOSState ProcessKey(eKeys Key); |
86 | 122 | public: |
87 | 123 | cTeletextSetupPage(void); |
88 | 124 | static const ActionKeyName *actionKeyNames; |
125 | static const ActionKeyName *actionHotkeyNames; | |
89 | 126 | static const char **modes; |
90 | 127 | //~cTeletextSetupPage(void); |
91 | 128 | //void SetItemVisible(cOsdItem *Item, bool visible, bool callDisplay=false); |
92 | 129 | }; |
93 | 130 | |
94 | 131 | const ActionKeyName *cTeletextSetupPage::actionKeyNames = 0; |
132 | const ActionKeyName *cTeletextSetupPage::actionHotkeyNames = 0; | |
95 | 133 | const char **cTeletextSetupPage::modes = 0; |
96 | 134 | |
97 | 135 | /*class MenuEditActionItem : public cMenuEditStraItem { |
107 | 145 | |
108 | 146 | cPluginTeletextosd::cPluginTeletextosd(void) |
109 | 147 | : txtStatus(0), startReceiver(true), storage(NULL), maxStorage(-1) |
148 | , storageSystem(Storage::StorageSystemPacked) | |
110 | 149 | { |
111 | 150 | // Initialize any member variables here. |
112 | 151 | // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL |
113 | 152 | // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! |
114 | } | |
153 | ||
154 | initTexts(); | |
155 | ||
156 | // read available fonts into Vector | |
157 | cFont::GetAvailableFontNames(&ttSetup.txtFontNames, true); | |
158 | ||
159 | // run through available fonts backwards and delete blacklisted ones | |
160 | for (int i = ttSetup.txtFontNames.Size() -1; i >= 0; i--) { | |
161 | if ( (strcasestr(ttSetup.txtFontNames[i], "Italic" ) != NULL) | |
162 | || (strcasestr(ttSetup.txtFontNames[i], "Oblique") != NULL) | |
163 | ) { | |
164 | DEBUG_OT_FONT("available font='%s' BLACKLISTED", ttSetup.txtFontNames[i]); | |
165 | ttSetup.txtFontNames.Remove(i); | |
166 | } else { | |
167 | DEBUG_OT_FONT("available font='%s' WHITELISTED", ttSetup.txtFontNames[i]); | |
168 | }; | |
169 | }; | |
170 | ||
171 | // display selectable fonts | |
172 | for (int i = 0; i < ttSetup.txtFontNames.Size(); i++) { | |
173 | if (ttSetup.txtFontNames[i] != NULL) { | |
174 | DEBUG_OT_FONT("selectable font[%d]='%s'", i, ttSetup.txtFontNames[i]); | |
175 | }; | |
176 | }; | |
177 | ||
178 | ttSetup.configuredClrBackground = -1; // flag for check whether it's still in setup.conf | |
179 | }; | |
115 | 180 | |
116 | 181 | cPluginTeletextosd::~cPluginTeletextosd() |
117 | 182 | { |
121 | 186 | const char *cPluginTeletextosd::CommandLineHelp(void) |
122 | 187 | { |
123 | 188 | // Return a string that describes all known command line options. |
124 | return " -d --directory=DIR The directory where the temporary\n" | |
125 | " files will be stored.\n" | |
126 | " (default: /var/cache/vdr/vtx)\n" | |
127 | " Ensure that the directory exists and is writable.\n" | |
189 | return " -d --directory=DIR The directory where the temporary files will be stored.\n" | |
190 | " default: /var/cache/vdr/vtx\n" | |
191 | " Ensure that the directory exists and is writable.\n" | |
128 | 192 | " -n --max-cache=NUM Maximum size in megabytes of cache used\n" |
129 | " to store the pages on the harddisk.\n" | |
130 | " (default: a calculated value below 50 MB)\n" | |
193 | " to store the pages on the harddisk.\n" | |
194 | " default: a calculated value below 50 MB\n" | |
131 | 195 | " -s --cache-system=SYS Set the cache system to be used.\n" |
132 | " Choose \"legacy\" for the traditional\n" | |
133 | " one-file-per-page system.\n" | |
134 | " Default is \"packed\" for the \n" | |
135 | " one-file-for-a-few-pages system.\n" | |
136 | " -t, --toptext Store top text pages at cache. (unviewable pages)\n"; | |
196 | " Choose \"legacy\" for the traditional\n" | |
197 | " one-file-per-page system.\n" | |
198 | " Default is \"packed\" for the \n" | |
199 | " one-file-for-a-few-pages system.\n" | |
200 | " -t, --toptext Store top text pages at cache. (unviewable pages)\n" | |
201 | " -k --key-levels=NUM Maximum amount of Hotkey levels selectable and stored\n" | |
202 | " default: 1 (which deactivate this feature)\n" | |
203 | " maximum: " HOTKEY_LEVEL_MAX_LIMIT_STRING " levels\n" | |
204 | " -o --osd-presets=NUM Maximum amount of OSD presets selectable and stored\n" | |
205 | " default: 1 (which deactivate this feature)\n" | |
206 | " maximum: " OSD_PRESET_MAX_LIMIT_STRING " presets\n" | |
207 | " -P|--debugpage <int|hexint> Specify page to debug (int: autoconvert internally to hex)\n" | |
208 | " -S|--debugpsub <int|hexint> Specify sub-page to debug (int: autoconvert internally to hex)\n" | |
209 | " -L|--debugline <int> Specify line of page to debug\n" | |
210 | " -D|--debugmask <int|hexint> Enable debugmask (see logging.h for details)\n"; | |
137 | 211 | } |
138 | 212 | |
139 | 213 | bool cPluginTeletextosd::ProcessArgs(int argc, char *argv[]) |
144 | 218 | { "max-cache", required_argument, NULL, 'n' }, |
145 | 219 | { "cache-system", required_argument, NULL, 's' }, |
146 | 220 | { "toptext", no_argument, NULL, 't' }, |
221 | { "key-levels", required_argument, NULL, 'k' }, | |
222 | { "osd-presets", required_argument, NULL, 'o' }, | |
223 | { "debugmask", required_argument, NULL, 'D' }, | |
224 | { "debugpage", required_argument, NULL, 'P' }, | |
225 | { "debugpsub", required_argument, NULL, 'S' }, | |
226 | { "debugline", required_argument, NULL, 'L' }, | |
147 | 227 | { NULL } |
148 | 228 | }; |
149 | 229 | |
150 | 230 | int c; |
151 | while ((c = getopt_long(argc, argv, "s:d:n:t", long_options, NULL)) != -1) { | |
231 | while ((c = getopt_long(argc, argv, "o:k:s:d:n:tD:", long_options, NULL)) != -1) { | |
152 | 232 | switch (c) { |
153 | 233 | case 's': |
154 | 234 | if (!optarg) |
167 | 247 | break; |
168 | 248 | case 't': storeTopText=true; |
169 | 249 | break; |
250 | case 'k': if (isnumber(optarg)) { | |
251 | int n = atoi(optarg); | |
252 | if (n < 1) { | |
253 | maxHotkeyLevel = 1; | |
254 | esyslog("osdteletext: maximum key-level value (-k %s) below 1 (ignore and use minimum)", optarg); | |
255 | } else if ((n > HOTKEY_LEVEL_MAX_LIMIT)) { | |
256 | maxHotkeyLevel = HOTKEY_LEVEL_MAX_LIMIT; | |
257 | esyslog("osdteletext: maximum key-level value (-k %s) above limit of %d (ignore and use maximum)", optarg, HOTKEY_LEVEL_MAX_LIMIT); | |
258 | } else { | |
259 | maxHotkeyLevel = n; | |
260 | }; | |
261 | } | |
262 | break; | |
263 | case 'o': if (isnumber(optarg)) { | |
264 | int n = atoi(optarg); | |
265 | if (n < 1) { | |
266 | maxOsdPreset = 1; | |
267 | esyslog("osdteletext: maximum OSD-preset value (-o %s) below 1 (ignore and use minimum)", optarg); | |
268 | } else if ((n > OSD_PRESET_MAX_LIMIT)) { | |
269 | maxOsdPreset = OSD_PRESET_MAX_LIMIT; | |
270 | esyslog("osdteletext: maximum OSD-preset value (-o %s) above limit of %d (ignore and use maximum)", optarg, OSD_PRESET_MAX_LIMIT); | |
271 | } else { | |
272 | maxOsdPreset = n; | |
273 | }; | |
274 | } | |
275 | break; | |
276 | case 'D': | |
277 | if ((strlen(optarg) > 2) && (strncasecmp(optarg, "0x", 2) == 0)) { | |
278 | // hex conversion | |
279 | if (sscanf(optarg + 2, "%x", &m_debugmask) == 0) { | |
280 | esyslog("osdteletext: can't parse hexadecimal debug mask (skip): %s", optarg); | |
281 | }; | |
282 | } else { | |
283 | m_debugmask = atoi(optarg); | |
284 | }; | |
285 | dsyslog("osdteletext: enable debug mask: %d (0x%08x)", m_debugmask, m_debugmask); | |
286 | break; | |
287 | ||
288 | case 'P': | |
289 | if ((strlen(optarg) > 2) && (strncasecmp(optarg, "0x", 2) == 0)) { | |
290 | // hex conversion | |
291 | if (sscanf(optarg + 2, "%x", &m_debugpage) == 0) { | |
292 | esyslog("osdteletext: can't parse hexadecimal debug page (skip): %s", optarg); | |
293 | }; | |
294 | } else { | |
295 | // hex conversion | |
296 | if (sscanf(optarg, "%x", &m_debugpage) == 0) { | |
297 | esyslog("osdteletext: can't parse hexadecimal debug page (skip): %s", optarg); | |
298 | }; | |
299 | }; | |
300 | dsyslog("osdteletext: enable debug page: %03x", m_debugpage); | |
301 | break; | |
302 | ||
303 | case 'S': | |
304 | if ((strlen(optarg) > 2) && (strncasecmp(optarg, "0x", 2) == 0)) { | |
305 | // hex conversion | |
306 | if (sscanf(optarg + 2, "%x", &m_debugpsub) == 0) { | |
307 | esyslog("osdteletext: can't parse hexadecimal debug sub-page (skip): %s", optarg); | |
308 | }; | |
309 | } else { | |
310 | // hex conversion | |
311 | if (sscanf(optarg, "%x", &m_debugpsub) == 0) { | |
312 | esyslog("osdteletext: can't parse hexadecimal debug sub-page (skip): %s", optarg); | |
313 | }; | |
314 | }; | |
315 | dsyslog("osdteletext: enable debug sub-page: %03x", m_debugpsub); | |
316 | break; | |
317 | ||
318 | case 'L': | |
319 | m_debugline = atoi(optarg); | |
320 | dsyslog("osdteletext: enable debug page line: %d", m_debugline); | |
321 | break; | |
170 | 322 | } |
171 | 323 | } |
172 | 324 | return true; |
179 | 331 | //perhaps due to a crash they have not been deleted. |
180 | 332 | switch (storageSystem) { |
181 | 333 | case Storage::StorageSystemLegacy: |
182 | storage = new LegacyStorage(maxStorage); | |
334 | isyslog("osdteletext: selected storage system: legacy"); | |
335 | storage = new LegacyStorage(maxStorage); | |
336 | break; | |
183 | 337 | case Storage::StorageSystemPacked: |
184 | 338 | default: |
185 | storage = new PackedStorage(maxStorage); | |
339 | isyslog("osdteletext: selected storage system: packed"); | |
340 | storage = new PackedStorage(maxStorage); | |
341 | break; | |
186 | 342 | } |
187 | 343 | |
188 | initTexts(); | |
189 | 344 | if (startReceiver) |
190 | 345 | txtStatus=new cTxtStatus(storeTopText, storage); |
191 | if (ttSetup.OSDheight<=100) ttSetup.OSDheight=Setup.OSDHeight; | |
192 | if (ttSetup.OSDwidth<=100) ttSetup.OSDwidth=Setup.OSDWidth; | |
346 | ||
347 | if (maxOsdPreset > 1) | |
348 | isyslog("osdteletext: OSD multiple preset feature enabled with maximum of presets: %d", maxOsdPreset); | |
349 | else | |
350 | isyslog("osdteletext: OSD multiple preset feature not activated"); | |
351 | ||
352 | if (maxHotkeyLevel > 1) | |
353 | isyslog("osdteletext: OSD menu Hotkey multi-level feature enabled with maximum of levels: %d", maxHotkeyLevel); | |
354 | else | |
355 | isyslog("osdteletext: OSD menu Hotkey multi-level feature not activated"); | |
356 | ||
357 | ttSetup.osdPreset = 0; // default | |
358 | ||
359 | // legacy migration handling | |
360 | if ((ttSetup.migrationFlag_2_2 == false) && (ttSetup.configuredClrBackground >= 0)) { | |
361 | // BackTrans(1) not found, but configuredClrBackground found in setup.conf | |
362 | // overtake value from legacy TODO remove >= 2.3.0 | |
363 | ttSetup.osdConfig[BackTrans][0] = ttSetup.configuredClrBackground; | |
364 | dsyslog("osdteletext: overtake into 'OSDbackTrans' (preset 1) from setup.conf: configuredClrBackground: %d -> %d" , 255 - ttSetup.configuredClrBackground, ttSetup.osdConfig[BackTrans][0]); | |
365 | }; | |
193 | 366 | |
194 | 367 | return true; |
195 | 368 | } |
196 | 369 | |
197 | 370 | void cPluginTeletextosd::Stop(void) |
198 | 371 | { |
372 | char str[40]; | |
373 | ||
374 | // TODO: deduplicate code, see also cTeletextSetupPage::Store | |
375 | // Question: how to share that code beteen cTeletextSetupPage and cPluginTeletextosd | |
376 | // store OSD presets | |
377 | // preset "1" (internally 0) without digit suffix for backwards compatibility | |
378 | for (int p = 0; p < maxOsdPreset; p++) { | |
379 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDleftPct") | |
380 | SetupStore(str, ttSetup.osdConfig[Left][p]); | |
381 | ||
382 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDtopPct") | |
383 | SetupStore(str, ttSetup.osdConfig[Top][p]); | |
384 | ||
385 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDwidthPct") | |
386 | SetupStore(str, ttSetup.osdConfig[Width][p]); | |
387 | ||
388 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDheightPct") | |
389 | SetupStore(str, ttSetup.osdConfig[Height][p]); | |
390 | ||
391 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDframePix") | |
392 | SetupStore(str, ttSetup.osdConfig[Frame][p]); | |
393 | ||
394 | CREATE_SETUP_STRING_COND_SUFFIX(p, "txtVoffset") | |
395 | SetupStore(str, ttSetup.osdConfig[Voffset][p]); | |
396 | ||
397 | CREATE_SETUP_STRING_COND_SUFFIX(p, "txtFontName") | |
398 | SetupStore(str, ttSetup.txtFontNames[ttSetup.osdConfig[Font][p]]); // convert into name | |
399 | ||
400 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDbackTrans") | |
401 | SetupStore(str, ttSetup.osdConfig[BackTrans][p]); | |
402 | }; | |
403 | ||
404 | // legacy TODO remove >= 2.3.0 | |
405 | if (ttSetup.configuredClrBackground >= 0) { | |
406 | // found in setup.conf during read, so store it back in legacy format | |
407 | SetupStore("configuredClrBackground", 255 - ttSetup.osdConfig[BackTrans][0]); | |
408 | }; | |
409 | ||
199 | 410 | DELETENULL(txtStatus); |
200 | 411 | if (storage) { |
201 | 412 | storage->cleanUp(); |
206 | 417 | void cPluginTeletextosd::initTexts() { |
207 | 418 | if (cTeletextSetupPage::actionKeyNames) |
208 | 419 | return; |
209 | //TODO: rewrite this in the xy[0].cd="fg"; form | |
420 | ||
210 | 421 | static const ActionKeyName st_actionKeyNames[] = |
422 | { | |
423 | { "Action_kFastRew", trVDR("Key$FastRew") }, | |
424 | { "Action_kFastFwd", trVDR("Key$FastFwd") }, | |
425 | { "Action_kStop", trVDR("Key$Stop") }, | |
426 | { "Action_kOk", trVDR("Key$Ok") }, | |
427 | { "Action_kPlay", trVDR("Key$Play") }, | |
428 | }; | |
429 | ||
430 | cTeletextSetupPage::actionKeyNames = st_actionKeyNames; | |
431 | ||
432 | ||
433 | static const ActionKeyName st_actionHotkeyNames[] = | |
211 | 434 | { |
212 | 435 | { "Action_kRed", trVDR("Key$Red") }, |
213 | 436 | { "Action_kGreen", trVDR("Key$Green") }, |
214 | 437 | { "Action_kYellow", trVDR("Key$Yellow") }, |
215 | 438 | { "Action_kBlue", trVDR("Key$Blue") }, |
216 | { "Action_kPlay", trVDR("Key$Play") }, | |
217 | { "Action_kStop", trVDR("Key$Stop") }, | |
218 | { "Action_kFastFwd", trVDR("Key$FastFwd") }, | |
219 | { "Action_kFastRew", trVDR("Key$FastRew") } | |
220 | }; | |
221 | ||
222 | cTeletextSetupPage::actionKeyNames = st_actionKeyNames; | |
439 | }; | |
440 | ||
441 | cTeletextSetupPage::actionHotkeyNames = st_actionHotkeyNames; | |
442 | ||
223 | 443 | |
224 | 444 | static const char *st_modes[] = |
225 | 445 | { |
446 | // 1:1 relation between st_modes[] in osdteletext.c + eTeletextAction in setup.h + st_modesHotkey in setup.c | |
226 | 447 | tr("Zoom"), |
227 | 448 | tr("Half page"), |
228 | 449 | tr("Change channel"), |
229 | 450 | tr("Switch background"), |
230 | 451 | //tr("Suspend receiving"), |
231 | tr("Jump to...") | |
452 | tr("Config"), | |
453 | tr("24-LineMode"), | |
454 | tr("Answer"), | |
455 | tr("Pause"), | |
456 | tr("Hotkey Level+"), | |
457 | tr("Hotkey Level-"), | |
458 | tr("OSD Preset+"), | |
459 | tr("OSD Preset-"), | |
460 | tr("Jump to...") // has to stay always as the last one | |
232 | 461 | }; |
233 | 462 | |
234 | 463 | cTeletextSetupPage::modes = st_modes; |
256 | 485 | return new cTeletextSetupPage; |
257 | 486 | } |
258 | 487 | |
488 | /* index extraction macro */ | |
489 | #define CHECK_SETUP_STRING_COND_SUFFIX(name, text, index, limit) \ | |
490 | index = -1; \ | |
491 | if (! strcasecmp(name, text)) { \ | |
492 | index = 0; \ | |
493 | } else { \ | |
494 | if (! strncasecmp(name, text, strlen(text))) { \ | |
495 | if ((strlen(name) - 1) != strlen(text)) { \ | |
496 | esyslog("osdteletext: ignore entry with too long suffix in setup.conf: osdteletext.%s", name); \ | |
497 | return false; /* invalid option, only 1 digit is supported */ \ | |
498 | } \ | |
499 | /* extract digit suffix */ \ | |
500 | index = atoi(name + strlen(text)) - 1; /* last char digit */ \ | |
501 | if ((index < 1) || (index >= limit)) { \ | |
502 | /* ignore out-of-range suffix */ \ | |
503 | esyslog("osdteletext: ignore entry with out-of-range digit in setup.conf: osdteletext.%s (detected index=%d)", name, index); \ | |
504 | return false; \ | |
505 | }; \ | |
506 | }; \ | |
507 | }; \ | |
508 | if (index >= 0) { DEBUG_OT_SETUP("found setup config: Name=%s Text=%s Index=%d Value='%s'\n", name, text, index, Value); }; | |
509 | ||
510 | /* value check/store macro */ | |
511 | #define CHECK_STORE_INT_VALUE(store, value, min, max) \ | |
512 | store = atoi(value); \ | |
513 | if (store < min) store = min; \ | |
514 | else if (store > max) store = max; | |
515 | ||
516 | /* ignore obsolete options */ | |
517 | #define DSYSLOG_IGNORE_OPTION(info) dsyslog("osdteletext: ignore obsolete option in setup.conf: osdteletext.%s (%s)", Name, info); | |
259 | 518 | |
260 | 519 | bool cPluginTeletextosd::SetupParse(const char *Name, const char *Value) |
261 | 520 | { |
262 | 521 | initTexts(); |
522 | ||
263 | 523 | // Parse your own setup parameters and store their values. |
264 | //Stretch=true; | |
265 | if (!strcasecmp(Name, "configuredClrBackground")) ttSetup.configuredClrBackground=( ((unsigned int)atoi(Value)) << 24); | |
524 | if (!strcasecmp(Name, "HideMainMenu")) ttSetup.HideMainMenu=atoi(Value); | |
266 | 525 | else if (!strcasecmp(Name, "showClock")) ttSetup.showClock=atoi(Value); |
267 | //currently not used | |
268 | else if (!strcasecmp(Name, "suspendReceiving")) ttSetup.suspendReceiving=atoi(Value); | |
269 | 526 | else if (!strcasecmp(Name, "autoUpdatePage")) ttSetup.autoUpdatePage=atoi(Value); |
270 | else if (!strcasecmp(Name, "OSDheight")) ttSetup.OSDheight=atoi(Value); | |
271 | else if (!strcasecmp(Name, "OSDwidth")) ttSetup.OSDwidth=atoi(Value); | |
272 | else if (!strcasecmp(Name, "OSDHAlign")) ttSetup.OSDHAlign=atoi(Value); | |
273 | else if (!strcasecmp(Name, "OSDVAlign")) ttSetup.OSDVAlign=atoi(Value); | |
274 | else if (!strcasecmp(Name, "inactivityTimeout")) /*ttSetup.inactivityTimeout=atoi(Value)*/; | |
275 | else if (!strcasecmp(Name, "HideMainMenu")) ttSetup.HideMainMenu=atoi(Value); | |
276 | else if (!strcasecmp(Name, "txtFontName")) ttSetup.txtFontName=strdup(Value); | |
277 | 527 | else if (!strcasecmp(Name, "txtG0Block")) ttSetup.txtG0Block=atoi(Value); |
278 | 528 | else if (!strcasecmp(Name, "txtG2Block")) ttSetup.txtG2Block=atoi(Value); |
529 | else if (!strcasecmp(Name, "colorMode4bpp")) ttSetup.colorMode4bpp=atoi(Value); | |
530 | else if (!strcasecmp(Name, "lineMode24")) ttSetup.lineMode24=atoi(Value); | |
531 | else if (!strcasecmp(Name, "OSDHAlign" )) { DSYSLOG_IGNORE_OPTION("<1.0.0") } | |
532 | else if (!strcasecmp(Name, "OSDVAlign" )) { DSYSLOG_IGNORE_OPTION("<1.0.0") } | |
533 | else if (!strcasecmp(Name, "OSDheight" )) { DSYSLOG_IGNORE_OPTION("<1.0.0") } | |
534 | else if (!strcasecmp(Name, "OSDwidth" )) { DSYSLOG_IGNORE_OPTION("<1.0.0") } | |
535 | else if (!strcasecmp(Name, "OSDhcentPct")) { DSYSLOG_IGNORE_OPTION("1.0.0-1.0.4") } | |
536 | else if (!strcasecmp(Name, "OSDvcentPct")) { DSYSLOG_IGNORE_OPTION("1.0.0-1.0.4") } | |
537 | else if (!strcasecmp(Name, "OSDframePct")) { DSYSLOG_IGNORE_OPTION(">1.0.6 && <1.0.7") } | |
538 | else if (!strcasecmp(Name, "suspendReceiving")) { DSYSLOG_IGNORE_OPTION("<0.8.0") } | |
539 | else if (!strcasecmp(Name, "inactivityTimeout")) { DSYSLOG_IGNORE_OPTION("<0.8.0") } | |
540 | else if (!strcasecmp(Name, "configuredClrBackground")) { | |
541 | // DSYSLOG_IGNORE_OPTION("<2.2.0") TODO >= 2.3.0 | |
542 | ttSetup.configuredClrBackground = 255 - atoi(Value); // legacy setting, map already to new internal value handling | |
543 | if (ttSetup.configuredClrBackground < 0) | |
544 | ttSetup.configuredClrBackground = 0; | |
545 | else if (ttSetup.configuredClrBackground > 255) | |
546 | ttSetup.configuredClrBackground = 255; | |
547 | } | |
548 | else if (!strcasecmp(Name, "osdPresetMax")) { | |
549 | ttSetup.osdPresetMax = atoi(Value); | |
550 | if (ttSetup.osdPresetMax > maxOsdPreset) { | |
551 | // limit by command line option maximum | |
552 | ttSetup.osdPresetMax = maxOsdPreset; | |
553 | } else if (ttSetup.osdPresetMax < 1) { | |
554 | // minimum is 1 | |
555 | ttSetup.osdPresetMax = 1; | |
556 | }; | |
557 | } | |
558 | else if (!strcasecmp(Name, "hotkeyLevelMax")) { | |
559 | ttSetup.hotkeyLevelMax = atoi(Value); | |
560 | if (ttSetup.hotkeyLevelMax > maxHotkeyLevel) { | |
561 | // limit by command line option maximum | |
562 | ttSetup.hotkeyLevelMax = maxHotkeyLevel; | |
563 | } else if (ttSetup.hotkeyLevelMax < 1) { | |
564 | // minimum is 1 | |
565 | ttSetup.hotkeyLevelMax = 1; | |
566 | }; | |
567 | } | |
279 | 568 | else { |
569 | // parse setup related to OSD with preset | |
570 | int p; | |
571 | ||
572 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "OSDleftPct", p, OSD_PRESET_MAX_LIMIT); | |
573 | if (p >= 0) { | |
574 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[Left][p], Value, OSDleftPctMin, OSDleftPctMax) | |
575 | return true; | |
576 | }; | |
577 | ||
578 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "OSDtopPct", p, OSD_PRESET_MAX_LIMIT); | |
579 | if (p >= 0) { | |
580 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[Top][p], Value, OSDtopPctMin, OSDtopPctMax); | |
581 | return true; | |
582 | }; | |
583 | ||
584 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "OSDwidthPct", p, OSD_PRESET_MAX_LIMIT); | |
585 | if (p >= 0) { | |
586 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[Width][p], Value, OSDwidthPctMin, OSDwidthPctMax); | |
587 | return true; | |
588 | }; | |
589 | ||
590 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "OSDheightPct", p, OSD_PRESET_MAX_LIMIT); | |
591 | if (p >= 0) { | |
592 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[Height][p], Value, OSDheightPctMin, OSDheightPctMax); | |
593 | return true; | |
594 | }; | |
595 | ||
596 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "OSDframePix", p, OSD_PRESET_MAX_LIMIT); | |
597 | if (p >= 0) { | |
598 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[Frame][p], Value, OSDframePixMin, OSDframePixMax); | |
599 | return true; | |
600 | }; | |
601 | ||
602 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "txtVoffset", p, OSD_PRESET_MAX_LIMIT); | |
603 | if (p >= 0) { | |
604 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[Voffset][p], Value, txtVoffsetMin, txtVoffsetMax); | |
605 | return true; | |
606 | }; | |
607 | ||
608 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "OSDbackTrans", p, OSD_PRESET_MAX_LIMIT); | |
609 | if (p >= 0) { | |
610 | CHECK_STORE_INT_VALUE(ttSetup.osdConfig[BackTrans][p], Value, BackTransMin, BackTransMax); | |
611 | if (p == 0) ttSetup.migrationFlag_2_2 = true; // set migration flag for 2.2.0 (configuredClrBackground) | |
612 | return true; | |
613 | }; | |
614 | ||
615 | CHECK_SETUP_STRING_COND_SUFFIX(Name, "txtFontName", p, OSD_PRESET_MAX_LIMIT); | |
616 | if (p >= 0) { | |
617 | // font name to index conversion | |
618 | int i = ttSetup.txtFontNames.Find(Value); | |
619 | if (i < 0) i = 0; // not found -> default is 1st one | |
620 | ttSetup.osdConfig[Font][p] = i; | |
621 | DEBUG_OT_SETUP("map setup config: Name=%s Index=%d Value='%s' to FontIndex=%d\n", Name, p, Value, i); | |
622 | return true; | |
623 | }; | |
624 | ||
625 | // parse setup related to keys | |
280 | 626 | for (int i=0;i<LastActionKey;i++) { |
627 | // DEBUG_OT_SETUP("compare i=%d internalName=%s\n", i, cTeletextSetupPage::actionKeyNames[i].internalName); | |
281 | 628 | if (!strcasecmp(Name, cTeletextSetupPage::actionKeyNames[i].internalName)) { |
282 | 629 | ttSetup.mapKeyToAction[i]=(eTeletextAction)atoi(Value); |
283 | ||
284 | //for migration to 0.4 | |
285 | if (ttSetup.mapKeyToAction[i]<100 && ttSetup.mapKeyToAction[i]>=LastAction) | |
286 | ttSetup.mapKeyToAction[i]=LastAction-1; | |
287 | ||
288 | 630 | return true; |
289 | 631 | } |
290 | 632 | } |
291 | 633 | |
292 | //for migration to 0.4 | |
293 | char act[7]; | |
294 | strncpy(act, Name, 7); | |
295 | if (!strcasecmp(act, "Action_")) | |
296 | return true; | |
634 | // parse setup related to Hotkey with levels | |
635 | for (int i = 0; i < LastActionHotkey; i++) { | |
636 | int l; | |
637 | int v; | |
638 | CHECK_SETUP_STRING_COND_SUFFIX(Name, cTeletextSetupPage::actionHotkeyNames[i].internalName, l, HOTKEY_LEVEL_MAX_LIMIT); | |
639 | if (l >= 0) { | |
640 | CHECK_STORE_INT_VALUE(v, Value, 0, 899); | |
641 | if ((v < 100) && (v >= (int) LastAction)) { | |
642 | esyslog("osdteletext: ignore entry with out-of-range value in setup.conf: osdteletext.%s (%d)", Name, v); | |
643 | return true; | |
644 | }; | |
645 | ttSetup.mapHotkeyToAction[i][l] = (eTeletextAction) v; | |
646 | return true; | |
647 | }; | |
648 | }; | |
297 | 649 | |
298 | 650 | return false; |
299 | 651 | } |
300 | 652 | return true; |
301 | 653 | } |
302 | 654 | |
655 | ||
303 | 656 | void cTeletextSetupPage::Store(void) { |
304 | //copy table | |
657 | char str[40]; | |
658 | ||
659 | // copy temporary preset table | |
660 | for (int p = 0; p < OSD_PRESET_MAX_LIMIT; p++) { | |
661 | for (int t = 0; t < LastActionConfig; t++) { | |
662 | ttSetup.osdConfig[t][p] = temp.osdConfig[t][p]; | |
663 | }; | |
664 | }; | |
665 | ||
666 | ttSetup.osdPresetMax=temp.osdPresetMax; | |
667 | ||
668 | // copy key table | |
305 | 669 | for (int i=0;i<LastActionKey;i++) { |
306 | 670 | if (temp.mapKeyToAction[i] >= LastAction) //jump to page selected |
307 | 671 | ttSetup.mapKeyToAction[i]=(eTeletextAction)tempPageNumber[i]; |
308 | 672 | else //one of the other modes selected |
309 | 673 | ttSetup.mapKeyToAction[i]=temp.mapKeyToAction[i]; |
310 | 674 | } |
311 | ttSetup.configuredClrBackground=( ((unsigned int)tempConfiguredClrBackground) << 24); | |
675 | ||
676 | // copy Hotkey table | |
677 | for (int l = 0; l < HOTKEY_LEVEL_MAX_LIMIT; l++) { | |
678 | for (int i = 0;i < LastActionHotkey; i++) { | |
679 | if (temp.mapHotkeyToAction[i][l] >= LastAction) //jump to page selected | |
680 | ttSetup.mapHotkeyToAction[i][l] = (eTeletextAction)tempPageNumberHotkey[i][l]; | |
681 | else //one of the other modes selected | |
682 | ttSetup.mapHotkeyToAction[i][l] = temp.mapHotkeyToAction[i][l]; | |
683 | } | |
684 | } | |
685 | ||
686 | ttSetup.hotkeyLevelMax=temp.hotkeyLevelMax; | |
687 | ||
312 | 688 | ttSetup.showClock=temp.showClock; |
313 | ttSetup.suspendReceiving=temp.suspendReceiving; | |
314 | 689 | ttSetup.autoUpdatePage=temp.autoUpdatePage; |
315 | ttSetup.OSDheight=temp.OSDheight; | |
316 | ttSetup.OSDwidth=temp.OSDwidth; | |
317 | ttSetup.OSDHAlign=temp.OSDHAlign; | |
318 | ttSetup.OSDVAlign=temp.OSDVAlign; | |
319 | 690 | ttSetup.HideMainMenu=temp.HideMainMenu; |
320 | ttSetup.txtFontName=temp.txtFontNames[temp.txtFontIndex]; | |
321 | 691 | ttSetup.txtG0Block=temp.txtG0Block; |
322 | 692 | ttSetup.txtG2Block=temp.txtG2Block; |
323 | //ttSetup.inactivityTimeout=temp.inactivityTimeout; | |
324 | ||
693 | ttSetup.colorMode4bpp=temp.colorMode4bpp; | |
694 | ttSetup.lineMode24=temp.lineMode24; | |
695 | ||
696 | // store key table | |
325 | 697 | for (int i=0;i<LastActionKey;i++) { |
326 | 698 | SetupStore(actionKeyNames[i].internalName, ttSetup.mapKeyToAction[i]); |
327 | 699 | } |
328 | SetupStore("configuredClrBackground", (int)(ttSetup.configuredClrBackground >> 24)); | |
700 | ||
701 | // store Hotkey table (maximum given by command line: maxHotkeyLevel) | |
702 | // hotkeyLevel "1" (interally 0) without digit for backwards compatibility | |
703 | for (int l = 0; l < maxHotkeyLevel; l++) { | |
704 | for (int i = 0; i < LastActionHotkey;i++) { | |
705 | CREATE_SETUP_STRING_COND_SUFFIX(l, actionHotkeyNames[i].internalName) | |
706 | SetupStore(str, ttSetup.mapHotkeyToAction[i][l]); | |
707 | }; | |
708 | }; | |
709 | ||
710 | SetupStore("hotkeyLevelMax", ttSetup.hotkeyLevelMax); // store currently configured maximum | |
711 | ||
712 | // store OSD presets | |
713 | // preset "1" (internally 0) without digit suffix for backwards compatibility | |
714 | for (int p = 0; p < maxOsdPreset; p++) { | |
715 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDleftPct") | |
716 | SetupStore(str, ttSetup.osdConfig[Left][p]); | |
717 | ||
718 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDtopPct") | |
719 | SetupStore(str, ttSetup.osdConfig[Top][p]); | |
720 | ||
721 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDwidthPct") | |
722 | SetupStore(str, ttSetup.osdConfig[Width][p]); | |
723 | ||
724 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDheightPct") | |
725 | SetupStore(str, ttSetup.osdConfig[Height][p]); | |
726 | ||
727 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDframePix") | |
728 | SetupStore(str, ttSetup.osdConfig[Frame][p]); | |
729 | ||
730 | CREATE_SETUP_STRING_COND_SUFFIX(p, "txtVoffset") | |
731 | SetupStore(str, ttSetup.osdConfig[Voffset][p]); | |
732 | ||
733 | CREATE_SETUP_STRING_COND_SUFFIX(p, "txtFontName") | |
734 | SetupStore(str, ttSetup.txtFontNames[ttSetup.osdConfig[Font][p]]); // convert into name | |
735 | ||
736 | CREATE_SETUP_STRING_COND_SUFFIX(p, "OSDbackTrans") | |
737 | SetupStore(str, ttSetup.osdConfig[BackTrans][p]); | |
738 | }; | |
739 | ||
740 | SetupStore("osdPresetMax", ttSetup.osdPresetMax); // store currently configured maximum | |
741 | ||
742 | ||
743 | // legacy TODO remove >= 2.3.0 | |
744 | if (ttSetup.configuredClrBackground >= 0) { | |
745 | // found in setup.conf during read, so store it back in legacy format | |
746 | SetupStore("configuredClrBackground", 255 - ttSetup.osdConfig[BackTrans][0]); | |
747 | }; | |
748 | ||
749 | // Global | |
329 | 750 | SetupStore("showClock", ttSetup.showClock); |
330 | //currently not used | |
331 | //SetupStore("suspendReceiving", ttSetup.suspendReceiving); | |
332 | 751 | SetupStore("autoUpdatePage", ttSetup.autoUpdatePage); |
333 | SetupStore("OSDheight", ttSetup.OSDheight); | |
334 | SetupStore("OSDwidth", ttSetup.OSDwidth); | |
335 | SetupStore("OSDHAlign", ttSetup.OSDHAlign); | |
336 | SetupStore("OSDVAlign", ttSetup.OSDVAlign); | |
337 | 752 | SetupStore("HideMainMenu", ttSetup.HideMainMenu); |
338 | SetupStore("txtFontName", ttSetup.txtFontName); | |
339 | 753 | SetupStore("txtG0Block", ttSetup.txtG0Block); |
340 | 754 | SetupStore("txtG2Block", ttSetup.txtG2Block); |
341 | //SetupStore("inactivityTimeout", ttSetup.inactivityTimeout); | |
342 | } | |
343 | ||
755 | SetupStore("colorMode4bpp", ttSetup.colorMode4bpp); | |
756 | SetupStore("lineMode24", ttSetup.lineMode24); | |
757 | ||
758 | if (clrBackground != TTSETUPPRESET_TCOLOR(BackTrans)) { | |
759 | clrBackground = TTSETUPPRESET_TCOLOR(BackTrans); | |
760 | }; | |
761 | } | |
344 | 762 | |
345 | 763 | cTeletextSetupPage::cTeletextSetupPage(void) { |
346 | 764 | cString buf; |
358 | 776 | temp.txtBlock[9] = tr("Reserved"); |
359 | 777 | temp.txtBlock[10] = tr("Hebrew"); |
360 | 778 | |
361 | //init tables | |
779 | temp.lineMode[0] = tr("Hotkeys"); | |
780 | temp.lineMode[1] = tr("No Hotkeys+Hints"); | |
781 | temp.lineMode[2] = tr("Hotkeys+Hints"); | |
782 | ||
783 | osdPreset = 1; | |
784 | temp.osdPresetMax = ttSetup.osdPresetMax; | |
785 | ||
786 | // init temporary preset table | |
787 | for (int p = 0; p < OSD_PRESET_MAX_LIMIT; p++) { | |
788 | for (int t = 0; t < LastActionConfig; t++) { | |
789 | temp.osdConfig[t][p] = ttSetup.osdConfig[t][p]; | |
790 | }; | |
791 | }; | |
792 | ||
793 | hotkeyLevel = 1; | |
794 | temp.hotkeyLevelMax = ttSetup.hotkeyLevelMax; | |
795 | ||
796 | // init key tables | |
362 | 797 | for (int i=0;i<LastActionKey;i++) { |
363 | 798 | if (ttSetup.mapKeyToAction[i] >= LastAction) {//jump to page selected |
364 | 799 | temp.mapKeyToAction[i]=LastAction; //to display the last string |
368 | 803 | tempPageNumber[i]=100; |
369 | 804 | } |
370 | 805 | } |
371 | tempConfiguredClrBackground=(ttSetup.configuredClrBackground >> 24); | |
806 | ||
807 | // init Hotkey tables | |
808 | for (int l = 0; l < HOTKEY_LEVEL_MAX_LIMIT; l++) { | |
809 | for (int i = 0; i < LastActionHotkey; i++) { | |
810 | if (ttSetup.mapHotkeyToAction[i][l] >= LastAction) {//jump to page selected | |
811 | temp.mapHotkeyToAction[i][l] = LastAction; //to display the last string | |
812 | tempPageNumberHotkey[i][l] = ttSetup.mapHotkeyToAction[i][l]; | |
813 | } else { //one of the other modes selected | |
814 | temp.mapHotkeyToAction[i][l] = ttSetup.mapHotkeyToAction[i][l]; | |
815 | tempPageNumberHotkey[i][l] = 100; | |
816 | } | |
817 | } | |
818 | } | |
819 | ||
372 | 820 | temp.showClock=ttSetup.showClock; |
373 | temp.suspendReceiving=ttSetup.suspendReceiving; | |
374 | 821 | temp.autoUpdatePage=ttSetup.autoUpdatePage; |
375 | temp.OSDheight=ttSetup.OSDheight; | |
376 | temp.OSDwidth=ttSetup.OSDwidth; | |
377 | temp.OSDHAlign=ttSetup.OSDHAlign; | |
378 | temp.OSDVAlign=ttSetup.OSDVAlign; | |
822 | temp.osdPresetMax=ttSetup.osdPresetMax; | |
823 | temp.hotkeyLevelMax=ttSetup.hotkeyLevelMax; | |
379 | 824 | temp.HideMainMenu=ttSetup.HideMainMenu; |
380 | temp.txtFontName=ttSetup.txtFontName; | |
381 | 825 | temp.txtG0Block=ttSetup.txtG0Block; |
382 | 826 | temp.txtG2Block=ttSetup.txtG2Block; |
383 | //temp.inactivityTimeout=ttSetup.inactivityTimeout; | |
384 | ||
385 | cFont::GetAvailableFontNames(&temp.txtFontNames, true); | |
386 | temp.txtFontIndex = temp.txtFontNames.Find(ttSetup.txtFontName); | |
387 | if (temp.txtFontIndex < 0) { | |
388 | temp.txtFontIndex = 0; | |
389 | } | |
390 | ||
391 | Add(new cMenuEditIntItem(tr("Background transparency"), &tempConfiguredClrBackground, 0, 255)); | |
827 | temp.colorMode4bpp=ttSetup.colorMode4bpp; | |
828 | temp.lineMode24=ttSetup.lineMode24; | |
829 | ||
830 | Add(new cMenuEditBoolItem(tr("Hide mainmenu entry"), &temp.HideMainMenu)); | |
392 | 831 | |
393 | 832 | Add(new cMenuEditBoolItem(tr("Show clock"), &temp.showClock )); |
394 | 833 | |
395 | //Add(new cMenuEditBoolItem(tr("Setup$Suspend receiving"), &temp.suspendReceiving )); | |
396 | ||
397 | 834 | Add(new cMenuEditBoolItem(tr("Auto-update pages"), &temp.autoUpdatePage )); |
398 | ||
399 | Add(new cMenuEditIntItem(tr("OSD height"), &temp.OSDheight, 250, MAXOSDHEIGHT)); | |
400 | Add(new cMenuEditIntItem(tr("OSD width"), &temp.OSDwidth, 320, MAXOSDWIDTH)); | |
401 | ||
402 | Add(new cMenuEditIntItem(tr("OSD horizontal align"), &temp.OSDHAlign, 0, 100)); | |
403 | Add(new cMenuEditIntItem(tr("OSD vertical align"), &temp.OSDVAlign, 0, 100)); | |
404 | Add(new cMenuEditBoolItem(tr("Hide mainmenu entry"), &temp.HideMainMenu)); | |
405 | Add(new cMenuEditStraItem(tr("Text Font"), &temp.txtFontIndex, temp.txtFontNames.Size(), &temp.txtFontNames[0])); | |
406 | 835 | Add(new cMenuEditStraItem(tr("G0 code block"), &temp.txtG0Block, NUMELEMENTS(temp.txtBlock), temp.txtBlock)); |
407 | 836 | Add(new cMenuEditStraItem(tr("G2 code block"), &temp.txtG2Block, NUMELEMENTS(temp.txtBlock), temp.txtBlock)); |
408 | ||
409 | //Using same string as VDR's setup menu | |
410 | //Add(new cMenuEditIntItem(tr("Setup.Miscellaneous$Min. user inactivity (min)"), &temp.inactivityTimeout)); | |
411 | ||
412 | buf = cString::sprintf("%s:", tr("Key bindings")); | |
837 | Add(new cMenuEditBoolItem(tr("16-Color Mode"), &temp.colorMode4bpp)); | |
838 | Add(new cMenuEditStraItem(tr("24-Line Mode"), &temp.lineMode24, NUMELEMENTS(temp.lineMode), temp.lineMode)); | |
839 | ||
840 | // OSD presets | |
841 | if (maxOsdPreset > 1) | |
842 | buf = cString::sprintf("OSD %s (%s %s %d/%d):", tr("Config"), tr("max"), tr("Presets"), maxOsdPreset, OSD_PRESET_MAX_LIMIT); | |
843 | else | |
844 | buf = cString::sprintf("OSD %s", tr("Config")); | |
413 | 845 | item = new cOsdItem(*buf); |
414 | 846 | item->SetSelectable(false); |
415 | 847 | Add(item); |
848 | ||
849 | if (maxOsdPreset > 1) { | |
850 | // maximum given by command line option: maxOsdPreset | |
851 | cString buf2 = cString::sprintf("OSD %s %s", tr("Presets"), tr("visible")); | |
852 | osdPresetMaxItem = new cMenuEditIntItem(buf2, &temp.osdPresetMax, 1, maxOsdPreset); | |
853 | Add(osdPresetMaxItem); | |
854 | ||
855 | osdPresetString = cString::sprintf("OSD %s %s", tr("Presets"), tr("Config")); // remember string for refresh | |
856 | osdPresetItem = new cMenuEditIntItem(osdPresetString, &osdPreset, 1, temp.osdPresetMax); | |
857 | Add(osdPresetItem); | |
858 | } else { | |
859 | // hide option but remember for hook later the section entry from above | |
860 | osdPresetItem = item; | |
861 | }; | |
862 | ||
863 | for (int p = 0; p < OSD_PRESET_MAX_LIMIT; p++) { | |
864 | // precreate all menu entries | |
865 | osdPresetConfigItem[Left] [p] = new cMenuEditIntItem(tr("OSD left (%)" ), &temp.osdConfig[Left] [p], OSDleftPctMin , OSDleftPctMax ); | |
866 | osdPresetConfigItem[Top] [p] = new cMenuEditIntItem(tr("OSD top (%)" ), &temp.osdConfig[Top] [p], OSDtopPctMin , OSDtopPctMax ); | |
867 | osdPresetConfigItem[Width] [p] = new cMenuEditIntItem(tr("OSD width (%)" ), &temp.osdConfig[Width] [p], OSDwidthPctMin , OSDwidthPctMax ); | |
868 | osdPresetConfigItem[Height] [p] = new cMenuEditIntItem(tr("OSD height (%)" ), &temp.osdConfig[Height] [p], OSDheightPctMin, OSDheightPctMax); | |
869 | osdPresetConfigItem[Frame] [p] = new cMenuEditIntItem(tr("OSD frame pixel" ), &temp.osdConfig[Frame] [p], OSDframePixMin , OSDframePixMax ); | |
870 | osdPresetConfigItem[Font] [p] = new cMenuEditStraItem(tr("Text Font" ), &temp.osdConfig[Font] [p], ttSetup.txtFontNames.Size(), &ttSetup.txtFontNames[0]); | |
871 | osdPresetConfigItem[Voffset] [p] = new cMenuEditIntItem(tr("Text Vertical Offset" ), &temp.osdConfig[Voffset] [p], txtVoffsetMin , txtVoffsetMax ); | |
872 | osdPresetConfigItem[BackTrans][p] = new cMenuEditIntItem(tr("Background transparency"), &temp.osdConfig[BackTrans][p], BackTransMin , BackTransMax ); | |
873 | }; | |
874 | ||
875 | SetupRefreshOsdConfig(); | |
876 | ||
877 | // Hotkey bindings | |
878 | if (maxHotkeyLevel > 1) | |
879 | buf = cString::sprintf("%s Hotkey (%s %s %d/%d):", tr("Key bindings"), tr("max"), tr("Levels"), maxHotkeyLevel, HOTKEY_LEVEL_MAX_LIMIT); | |
880 | else | |
881 | buf = cString::sprintf("%s Hotkey:", tr("Key bindings")); | |
882 | item = new cOsdItem(*buf); | |
883 | item->SetSelectable(false); | |
884 | Add(item); | |
885 | ||
886 | if (maxHotkeyLevel > 1) { | |
887 | // maximum given by command line option: maxHotkeyLevel | |
888 | cString buf2 = cString::sprintf("OSD Hotkey %s %s", tr("Levels"), tr("visible")); | |
889 | hotkeyLevelMaxItem = new cMenuEditIntItem(buf2, &temp.hotkeyLevelMax, 1, maxHotkeyLevel); | |
890 | Add(hotkeyLevelMaxItem); | |
891 | ||
892 | hotkeyLevelString = cString::sprintf("OSD Hotkey %s %s", tr("Level"), tr("Config")); // remember string for refresh | |
893 | hotkeyLevelItem = new cMenuEditIntItem(hotkeyLevelString, &hotkeyLevel, 1, temp.hotkeyLevelMax); | |
894 | Add(hotkeyLevelItem); | |
895 | } else { | |
896 | // hide option but remember for hook later the section entry from above | |
897 | hotkeyLevelItem = item; | |
898 | }; | |
899 | ||
900 | for (int l = 0; l < maxHotkeyLevel; l++) { | |
901 | for (int i = 0; i < LastActionHotkey; i++) { | |
902 | ActionEditsHotkey[i][l].Init(this, i, l | |
903 | , (l == (hotkeyLevel - 1)) | |
904 | , new cMenuEditIntItem(tr(" Page number"), &tempPageNumberHotkey[i][l], 100, 899) | |
905 | , new cMenuEditStraItem(actionHotkeyNames[i].userName, (int*)&temp.mapHotkeyToAction[i][l], LastAction+1, modes) | |
906 | ); | |
907 | }; | |
908 | } | |
909 | ||
910 | // Standard Key bindings | |
911 | buf = cString::sprintf("%s:", tr("Key bindings")); | |
912 | menuSectionKeysItem = new cOsdItem(*buf); | |
913 | menuSectionKeysItem->SetSelectable(false); | |
914 | Add(menuSectionKeysItem); | |
416 | 915 | |
417 | 916 | for (int i=0;i<LastActionKey;i++) { |
418 | 917 | ActionEdits[i].Init(this, i, new cMenuEditIntItem(tr(" Page number"), &tempPageNumber[i], 100, 899), |
420 | 919 | } |
421 | 920 | } |
422 | 921 | |
922 | void cTeletextSetupPage::SetupRefreshOsdConfig(void) { | |
923 | // delete all entry if existing | |
924 | #define DELETE_IF_EXISTING(item) if (cList<cOsdItem>::Contains(item)) cList<cOsdItem>::Del(item, false); | |
925 | ||
926 | // remove all entries | |
927 | for (int t = 0; t < LastActionConfig; t++) | |
928 | for (int p = 0; p < OSD_PRESET_MAX_LIMIT; p++) | |
929 | DELETE_IF_EXISTING(osdPresetConfigItem[t][p]); | |
930 | ||
931 | int p = osdPreset - 1; | |
932 | ||
933 | DEBUG_OT_SETUP("display setup menu for OSD preset: %d\n", osdPreset); | |
934 | ||
935 | for (int t = 0; t < LastActionConfig; t++) { | |
936 | if (t == Left) { | |
937 | // using hook from section or preset switch | |
938 | Add(osdPresetConfigItem[t][p], false, osdPresetItem); | |
939 | } else { | |
940 | // use previous hook | |
941 | Add(osdPresetConfigItem[t][p] , false, osdPresetConfigItem[t - 1][p]); | |
942 | } | |
943 | }; | |
944 | }; | |
945 | ||
946 | void cTeletextSetupPage::SetupRefreshKeys(void) { | |
947 | // recreate key setup without sophisticated and issue causing dynamic Insert+Add (e.g. last line 'Jump to' is not working) | |
948 | ||
949 | // delete all key entry if existing | |
950 | for (int i = 0; i < LastActionKey; i++) { | |
951 | if (cList<cOsdItem>::Contains(ActionEdits[i].action)) | |
952 | cList<cOsdItem>::Del(ActionEdits[i].action, false); | |
953 | if (cList<cOsdItem>::Contains(ActionEdits[i].number)) | |
954 | cList<cOsdItem>::Del(ActionEdits[i].number, false); | |
955 | }; | |
956 | ||
957 | // add selected ones | |
958 | cOsdItem *hook = menuSectionKeysItem; | |
959 | for (int i = 0; i < LastActionKey; i++) { | |
960 | DEBUG_OT_KEYS("key assigment menu i=%d action=%d (main)", i, temp.mapKeyToAction[i]); | |
961 | Add(ActionEdits[i].action, false, hook); | |
962 | hook = ActionEdits[i].action; | |
963 | ||
964 | if (temp.mapKeyToAction[i] == LastAction) { | |
965 | // insert number if selected | |
966 | DEBUG_OT_KEYS("key assigment menu i=%d action=%d pagenumber=%d", i, temp.mapKeyToAction[i], tempPageNumber[i]); | |
967 | Add(ActionEdits[i].number, false, hook); | |
968 | hook = ActionEdits[i].number; | |
969 | }; | |
970 | }; | |
971 | } | |
972 | ||
973 | void cTeletextSetupPage::SetupRefreshHotkeys(void) { | |
974 | // recreate hot key setup without sophisticated and issue causing dynamic Insert+Add (e.g. last line 'Jump to' is not working) | |
975 | ||
976 | // Hotkey assignment | |
977 | int l = hotkeyLevel - 1; | |
978 | ||
979 | // delete all hot key entry if existing | |
980 | for (int l = 0; l < HOTKEY_LEVEL_MAX_LIMIT; l++) { | |
981 | for (int i = 0; i < LastActionHotkey; i++) { | |
982 | if (cList<cOsdItem>::Contains(ActionEditsHotkey[i][l].action)) | |
983 | cList<cOsdItem>::Del(ActionEditsHotkey[i][l].action, false); | |
984 | if (cList<cOsdItem>::Contains(ActionEditsHotkey[i][l].number)) | |
985 | cList<cOsdItem>::Del(ActionEditsHotkey[i][l].number, false); | |
986 | }; | |
987 | }; | |
988 | ||
989 | // add selected ones | |
990 | cOsdItem *hook = hotkeyLevelItem; | |
991 | for (int i = 0; i < LastActionHotkey; i++) { | |
992 | DEBUG_OT_KEYS("hot key assigment menu i=%d hotkeyLevel=%d action=%d (main)", i, hotkeyLevel, temp.mapHotkeyToAction[i][l]); | |
993 | Add(ActionEditsHotkey[i][l].action, false, hook); | |
994 | hook = ActionEditsHotkey[i][l].action; | |
995 | ||
996 | if (temp.mapHotkeyToAction[i][l] == LastAction) { | |
997 | // insert number if selected | |
998 | DEBUG_OT_KEYS("hot key assigment menu i=%d hotkeyLevel=%d action=%d pagenumber=%d", i, hotkeyLevel, temp.mapHotkeyToAction[i][l], tempPageNumberHotkey[i][l]); | |
999 | Add(ActionEditsHotkey[i][l].number, false, hook); | |
1000 | hook = ActionEditsHotkey[i][l].number; | |
1001 | }; | |
1002 | }; | |
1003 | ||
1004 | } | |
1005 | ||
423 | 1006 | eOSState cTeletextSetupPage::ProcessKey(eKeys Key) { |
1007 | if (Key != kNone) DEBUG_OT_KEYS("called with Key=%d", Key); | |
424 | 1008 | eOSState state = cMenuSetupPage::ProcessKey(Key); |
425 | 1009 | if (Key != kRight && Key!=kLeft) |
426 | 1010 | return state; |
427 | 1011 | cOsdItem *item = Get(Current()); |
1012 | ||
1013 | // OSD config preset | |
1014 | if (item == osdPresetMaxItem) { | |
1015 | // change of OSD preset max | |
1016 | DEBUG_OT_KEYS("osdPresetMaxItem changed osdPresetMax=%d (osdPreset=%d)", temp.osdPresetMax, osdPreset); | |
1017 | ||
1018 | if (osdPreset > temp.osdPresetMax) { | |
1019 | osdPreset = temp.osdPresetMax; | |
1020 | // recreate OSD config with reduced osdPreset (e.g. switch from >max to max) | |
1021 | SetupRefreshOsdConfig(); | |
1022 | }; | |
1023 | ||
1024 | // replace entry with new maximum | |
1025 | cList<cOsdItem>::Del(osdPresetItem); | |
1026 | osdPresetItem = new cMenuEditIntItem(osdPresetString, &osdPreset, 1, temp.osdPresetMax); | |
1027 | Add(osdPresetItem, false, osdPresetMaxItem); | |
1028 | ||
1029 | Display(); | |
1030 | return state; | |
1031 | }; | |
1032 | ||
1033 | if (item == osdPresetItem) { | |
1034 | // change between configs | |
1035 | DEBUG_OT_KEYS("osdPresetItem changed osdPreset=%d", osdPreset); | |
1036 | SetupRefreshOsdConfig(); | |
1037 | Display(); | |
1038 | return state; | |
1039 | }; | |
1040 | ||
1041 | // OSD hotkey | |
1042 | if (item == hotkeyLevelMaxItem) { | |
1043 | // change of OSD menu level max | |
1044 | DEBUG_OT_KEYS("hotkeyLevelMaxItem changed hotkeyLevelMax=%d (hotkeyLevel=%d)", temp.hotkeyLevelMax, hotkeyLevel); | |
1045 | ||
1046 | if (hotkeyLevel > temp.hotkeyLevelMax) { | |
1047 | hotkeyLevel = temp.hotkeyLevelMax; | |
1048 | // recreate Hotkey with reduced hotkeyLevel (e.g. switch from >max to max) | |
1049 | SetupRefreshHotkeys(); | |
1050 | }; | |
1051 | ||
1052 | // replace entry with new maximum | |
1053 | cList<cOsdItem>::Del(hotkeyLevelItem); | |
1054 | hotkeyLevelItem = new cMenuEditIntItem(hotkeyLevelString, &hotkeyLevel, 1, temp.hotkeyLevelMax); | |
1055 | Add(hotkeyLevelItem, false, hotkeyLevelMaxItem); | |
1056 | ||
1057 | Display(); | |
1058 | return state; | |
1059 | }; | |
1060 | ||
1061 | if (item == hotkeyLevelItem) { | |
1062 | // change between menu levels | |
1063 | DEBUG_OT_KEYS("hotkeyLevelItem changed hotkeyLevel=%d", hotkeyLevel); | |
1064 | SetupRefreshHotkeys(); | |
1065 | Display(); | |
1066 | return state; | |
1067 | }; | |
1068 | ||
1069 | // Standard Key change handling for 'Jump to' | |
428 | 1070 | for (int i=0;i<LastActionKey;i++) { |
429 | 1071 | if (ActionEdits[i].action==item) { //we have a key left/right and one of our items as current |
430 | //eOSState state = item->ProcessKey(Key); | |
431 | //if (state != osUnknown) { //really should not return osUnknown I think | |
432 | if (temp.mapKeyToAction[i] == LastAction && !ActionEdits[i].visible) { | |
433 | //need to make it visible | |
434 | if (i+1<LastActionKey) | |
435 | //does not work for i==LastAction-1 | |
436 | Ins( ActionEdits[i].number, false, ActionEdits[i+1].action); | |
437 | else | |
438 | Add( ActionEdits[i].number, false ); | |
439 | ||
440 | ActionEdits[i].visible=true; | |
441 | Display(); | |
442 | } else if (temp.mapKeyToAction[i] != LastAction && ActionEdits[i].visible) { | |
443 | //need to hide it | |
444 | cList<cOsdItem>::Del(ActionEdits[i].number, false); | |
445 | ActionEdits[i].visible=false; | |
446 | Display(); | |
447 | } | |
448 | break; | |
449 | //return state; | |
450 | //} | |
451 | } | |
1072 | SetupRefreshKeys(); | |
1073 | Display(); | |
1074 | } | |
452 | 1075 | } |
1076 | ||
1077 | // Hotkey change handling for 'Jump to' | |
1078 | int l = hotkeyLevel - 1; | |
1079 | for (int i=0; i < LastActionHotkey; i++) { | |
1080 | DEBUG_OT_KEYS("hot key assigment menu i=%d hotkeyLevel=%d action=%d (pagenumber)", i, hotkeyLevel, temp.mapHotkeyToAction[i][l]); | |
1081 | if (ActionEditsHotkey[i][l].action == item) { //we have a key left/right and one of our items as current | |
1082 | SetupRefreshHotkeys(); | |
1083 | Display(); | |
1084 | }; | |
1085 | }; | |
453 | 1086 | |
454 | 1087 | return state; |
455 | 1088 | //return cMenuSetupPage::ProcessKey(Key); |
462 | 1095 | s->Add(action); |
463 | 1096 | if (s->temp.mapKeyToAction[num] == LastAction) { |
464 | 1097 | s->Add(number); |
465 | visible=true; | |
466 | } else | |
467 | visible=false; | |
468 | } | |
469 | ||
470 | ||
1098 | }; | |
1099 | } | |
1100 | ||
1101 | void ActionEdit::Init(cTeletextSetupPage* s, int num, int level, bool active, cMenuEditIntItem *p, cMenuEditStraItem * a) { | |
1102 | action=a; | |
1103 | number=p; | |
1104 | if (!active) return; | |
1105 | s->Add(action); | |
1106 | if (s->temp.mapHotkeyToAction[num][level] == LastAction) { | |
1107 | s->Add(number); | |
1108 | }; | |
1109 | } | |
471 | 1110 | |
472 | 1111 | |
473 | 1112 | VDRPLUGINCREATOR(cPluginTeletextosd); // Don't touch this! |
1113 | ||
1114 | // vim: ts=3 sw=3 et |
72 | 72 | } |
73 | 73 | |
74 | 74 | void PackedStorage::getFilename(char *buffer, int bufLength, PageID page) { |
75 | //This is a different scheme: page 576_07 will have the name 570s.vtx, the same as e.g. 571_01 or 575_00 | |
75 | //This is a different scheme: page 576_07 will have the name 570s.vtx5, the same as e.g. 571_01 or 575_00 | |
76 | 76 | //Think of "the five hundred seventies" |
77 | snprintf(buffer, bufLength, "%s/%s/%03xs.vtx", getRootDir(), | |
77 | snprintf(buffer, bufLength, "%s/%s/%03xs.vtx5", getRootDir(), | |
78 | 78 | *page.channel.ToString(), (page.page & 0xFF0)); |
79 | 79 | } |
80 | 80 | |
101 | 101 | if (desc==-1 && !wroteError) { |
102 | 102 | //report error to syslog - once! |
103 | 103 | wroteError=true; |
104 | esyslog("OSD-Teletext: Error opening teletext file %s: %s", filename, strerror(errno)); | |
104 | esyslog("osdteletext: Error opening teletext file %s: %s", filename, strerror(errno)); | |
105 | 105 | } |
106 | 106 | |
107 | 107 | if (desc==-1) |
25 | 25 | { return page==id.page && subPage==id.subPage; } |
26 | 26 | void operator=(const PageID &id) |
27 | 27 | { page=id.page; subPage=id.subPage; } |
28 | int page; | |
29 | int subPage; | |
28 | unsigned int page; | |
29 | unsigned int subPage; | |
30 | 30 | }; |
31 | 31 | bool seekTo(PageID page, int fd, bool create); |
32 | 32 | void registerFile(PageID page); |
23 | 23 | PageID(tChannelID id, int p, int s) { set(id, p, s); } |
24 | 24 | void set(tChannelID id, int p, int s) { channel=id; page=p; subPage=s; } |
25 | 25 | tChannelID channel; |
26 | int page; | |
27 | int subPage; | |
26 | unsigned int page; | |
27 | unsigned int subPage; | |
28 | 28 | }; |
29 | 29 | |
30 | 30 | #endif |
8 | 8 | msgstr "" |
9 | 9 | "Project-Id-Version: VDR 1.5.7\n" |
10 | 10 | "Report-Msgid-Bugs-To: <see README>\n" |
11 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
11 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
12 | 12 | "PO-Revision-Date: 2008-05-04 15:33+0200\n" |
13 | 13 | "Last-Translator: Jordi Vilà <jvila@tinet.org>\n" |
14 | 14 | "Language-Team: Catalan <vdr@linuxtv.org>\n" |
17 | 17 | "Content-Type: text/plain; charset=UTF-8\n" |
18 | 18 | "Content-Transfer-Encoding: 8bit\n" |
19 | 19 | |
20 | msgid "Switch to" | |
21 | msgstr "" | |
22 | ||
23 | msgid "Channel" | |
24 | msgstr "" | |
25 | ||
26 | msgid "without" | |
27 | msgstr "" | |
28 | ||
29 | msgid "Teletext" | |
30 | msgstr "Teletext" | |
31 | ||
32 | msgid "live" | |
33 | msgstr "" | |
34 | ||
35 | msgid "Switch back to live" | |
36 | msgstr "" | |
37 | ||
38 | msgid "Tuner available" | |
39 | msgstr "" | |
40 | ||
41 | msgid "display current pages" | |
42 | msgstr "" | |
43 | ||
44 | msgid "Tuner busy" | |
45 | msgstr "" | |
46 | ||
47 | msgid "display cached pages" | |
48 | msgstr "" | |
49 | ||
50 | msgid "cached" | |
51 | msgstr "" | |
52 | ||
53 | msgid "Channel Tuning Successful" | |
54 | msgstr "" | |
55 | ||
56 | msgid "Channel Tuning Not Successful" | |
57 | msgstr "" | |
58 | ||
59 | msgid "No Free Tuner Found - Use Cache Only" | |
60 | msgstr "" | |
61 | ||
62 | msgid "*** Config mode is not supported in 24-line mode ***" | |
63 | msgstr "" | |
64 | ||
65 | msgid "Hotkey level change is not supported in 24-line mode" | |
66 | msgstr "" | |
67 | ||
68 | msgid "Hotkey levels are disabled" | |
69 | msgstr "" | |
70 | ||
71 | msgid "Hotkey levels are not active" | |
72 | msgstr "" | |
73 | ||
74 | msgid "OSD presets are disabled" | |
75 | msgstr "" | |
76 | ||
77 | msgid "OSD presets are not active" | |
78 | msgstr "" | |
79 | ||
20 | 80 | msgid "Channel (press OK): " |
21 | 81 | msgstr "Canal (premi OK):" |
22 | 82 | |
23 | 83 | msgid "Page" |
24 | 84 | msgstr "Pàgina" |
25 | 85 | |
86 | msgid "in cache" | |
87 | msgstr "" | |
88 | ||
26 | 89 | msgid "not found" |
27 | 90 | msgstr "no trobada" |
28 | 91 | |
92 | msgid "please wait" | |
93 | msgstr "" | |
94 | ||
29 | 95 | msgid "Displays teletext on the OSD" |
30 | 96 | msgstr "Visualitza el teletext en l'OSD" |
31 | 97 | |
32 | msgid "Teletext" | |
33 | msgstr "Teletext" | |
34 | ||
35 | 98 | msgid "Zoom" |
36 | 99 | msgstr "Zoom" |
37 | 100 | |
44 | 107 | msgid "Switch background" |
45 | 108 | msgstr "Canvia el fons" |
46 | 109 | |
110 | msgid "Config" | |
111 | msgstr "" | |
112 | ||
113 | msgid "24-LineMode" | |
114 | msgstr "" | |
115 | ||
116 | msgid "Answer" | |
117 | msgstr "" | |
118 | ||
119 | msgid "Pause" | |
120 | msgstr "" | |
121 | ||
122 | msgid "Hotkey Level+" | |
123 | msgstr "" | |
124 | ||
125 | msgid "Hotkey Level-" | |
126 | msgstr "" | |
127 | ||
128 | msgid "OSD Preset+" | |
129 | msgstr "" | |
130 | ||
131 | msgid "OSD Preset-" | |
132 | msgstr "" | |
133 | ||
47 | 134 | msgid "Jump to..." |
48 | 135 | msgstr "Salta a..." |
49 | 136 | |
74 | 161 | msgid "Hebrew" |
75 | 162 | msgstr "" |
76 | 163 | |
164 | msgid "Hotkeys" | |
165 | msgstr "" | |
166 | ||
167 | msgid "No Hotkeys+Hints" | |
168 | msgstr "" | |
169 | ||
170 | msgid "Hotkeys+Hints" | |
171 | msgstr "" | |
172 | ||
173 | msgid "Hide mainmenu entry" | |
174 | msgstr "" | |
175 | ||
176 | msgid "Show clock" | |
177 | msgstr "Visualitza l'hora" | |
178 | ||
179 | msgid "Auto-update pages" | |
180 | msgstr "Actualització pàgines automàtica" | |
181 | ||
182 | msgid "G0 code block" | |
183 | msgstr "" | |
184 | ||
185 | msgid "G2 code block" | |
186 | msgstr "" | |
187 | ||
188 | msgid "16-Color Mode" | |
189 | msgstr "" | |
190 | ||
191 | msgid "24-Line Mode" | |
192 | msgstr "" | |
193 | ||
194 | msgid "max" | |
195 | msgstr "" | |
196 | ||
197 | msgid "Presets" | |
198 | msgstr "" | |
199 | ||
200 | msgid "visible" | |
201 | msgstr "" | |
202 | ||
203 | msgid "OSD left (%)" | |
204 | msgstr "" | |
205 | ||
206 | msgid "OSD top (%)" | |
207 | msgstr "" | |
208 | ||
209 | msgid "OSD width (%)" | |
210 | msgstr "" | |
211 | ||
212 | msgid "OSD height (%)" | |
213 | msgstr "" | |
214 | ||
215 | msgid "OSD frame pixel" | |
216 | msgstr "" | |
217 | ||
218 | msgid "Text Font" | |
219 | msgstr "" | |
220 | ||
221 | msgid "Text Vertical Offset" | |
222 | msgstr "" | |
223 | ||
77 | 224 | msgid "Background transparency" |
78 | 225 | msgstr "Transparència del fons" |
79 | 226 | |
80 | msgid "Show clock" | |
81 | msgstr "Visualitza l'hora" | |
82 | ||
83 | msgid "Auto-update pages" | |
84 | msgstr "Actualització pàgines automàtica" | |
85 | ||
86 | msgid "OSD height" | |
87 | msgstr "Altura OSD" | |
88 | ||
89 | msgid "OSD width" | |
90 | msgstr "Amplària OSD" | |
91 | ||
92 | msgid "OSD horizontal align" | |
93 | msgstr "" | |
94 | ||
95 | msgid "OSD vertical align" | |
96 | msgstr "" | |
97 | ||
98 | msgid "Hide mainmenu entry" | |
99 | msgstr "" | |
100 | ||
101 | msgid "Text Font" | |
102 | msgstr "" | |
103 | ||
104 | msgid "G0 code block" | |
105 | msgstr "" | |
106 | ||
107 | msgid "G2 code block" | |
108 | msgstr "" | |
109 | ||
110 | 227 | msgid "Key bindings" |
228 | msgstr "" | |
229 | ||
230 | msgid "Levels" | |
231 | msgstr "" | |
232 | ||
233 | msgid "Level" | |
111 | 234 | msgstr "" |
112 | 235 | |
113 | 236 | msgid " Page number" |
114 | 237 | msgstr " Nombre de pàgina" |
238 | ||
239 | msgid "Half Page" | |
240 | msgstr "" | |
241 | ||
242 | msgid "ChangeChan" | |
243 | msgstr "" | |
244 | ||
245 | msgid "SwitchBack" | |
246 | msgstr "" | |
247 | ||
248 | msgid "24LineMode" | |
249 | msgstr "" | |
250 | ||
251 | msgid "HkLevel+" | |
252 | msgstr "" | |
253 | ||
254 | msgid "HkLevel-" | |
255 | msgstr "" | |
256 | ||
257 | msgid "Preset+" | |
258 | msgstr "" | |
259 | ||
260 | msgid "Preset-" | |
261 | msgstr "" | |
262 | ||
263 | msgid "Left" | |
264 | msgstr "" | |
265 | ||
266 | msgid "Top" | |
267 | msgstr "" | |
268 | ||
269 | msgid "Width" | |
270 | msgstr "" | |
271 | ||
272 | msgid "Height" | |
273 | msgstr "" | |
274 | ||
275 | msgid "Frame" | |
276 | msgstr "" | |
277 | ||
278 | msgid "TxVoffset" | |
279 | msgstr "" | |
280 | ||
281 | msgid "BackTrans" | |
282 | msgstr "" | |
283 | ||
284 | #~ msgid "OSD height" | |
285 | #~ msgstr "Altura OSD" | |
286 | ||
287 | #~ msgid "OSD width" | |
288 | #~ msgstr "Amplària OSD" |
4 | 4 | # |
5 | 5 | msgid "" |
6 | 6 | msgstr "" |
7 | "Project-Id-Version: VDR 1.5.7\n" | |
7 | "Project-Id-Version: VDR 2.4.4\n" | |
8 | 8 | "Report-Msgid-Bugs-To: <see README>\n" |
9 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
9 | "POT-Creation-Date: 2021-12-09 06:06+0100\n" | |
10 | 10 | "PO-Revision-Date: 2008-05-04 15:33+0200\n" |
11 | "Last-Translator: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>\n" | |
11 | "Last-Translator: Peter Bieringer <pb@bieringer.de>\n" | |
12 | 12 | "Language-Team: German <vdr@linuxtv.org>\n" |
13 | 13 | "Language: de\n" |
14 | 14 | "MIME-Version: 1.0\n" |
15 | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | |
18 | msgid "Switch to" | |
19 | msgstr "Wechsle zu" | |
20 | ||
21 | msgid "Channel" | |
22 | msgstr "Kanal" | |
23 | ||
24 | msgid "without" | |
25 | msgstr "ohne" | |
26 | ||
27 | msgid "Teletext" | |
28 | msgstr "Videotext" | |
29 | ||
30 | msgid "live" | |
31 | msgstr "aktuellem" | |
32 | ||
33 | msgid "Switch back to live" | |
34 | msgstr "Wechsle zurück zu laufendem" | |
35 | ||
36 | msgid "Tuner available" | |
37 | msgstr "Tuner frei" | |
38 | ||
39 | msgid "display current pages" | |
40 | msgstr "zeige aktuelle Seiten an" | |
41 | ||
42 | msgid "Tuner busy" | |
43 | msgstr "Tuner belegt" | |
44 | ||
45 | msgid "display cached pages" | |
46 | msgstr "zeige gespeicherte Seiten an" | |
47 | ||
48 | msgid "cached" | |
49 | msgstr "gespeicherten" | |
50 | ||
51 | msgid "Channel Tuning Successful" | |
52 | msgstr "Kanal erfolgreich eingestellt" | |
53 | ||
54 | msgid "Channel Tuning Not Successful" | |
55 | msgstr "Kanal nicht erfolgreich eingestellt" | |
56 | ||
57 | msgid "No Free Tuner Found - Use Cache Only" | |
58 | msgstr "Keinen freien Tuner gefunden - benutze nur gespeicherte Seiten" | |
59 | ||
60 | msgid "*** Config mode is not supported in 24-line mode ***" | |
61 | msgstr "*** Konfig-Modus ist im 24-Zeilen-Modus nicht unterstützt ***" | |
62 | ||
63 | msgid "Hotkey level change is not supported in 24-line mode" | |
64 | msgstr "Hotkey Ebenen-Änderung ist im 24-Zeilen-Modus nicht unterstützt" | |
65 | ||
66 | msgid "Hotkey levels are disabled" | |
67 | msgstr "Hotkey Ebenen sind deaktiviert" | |
68 | ||
69 | msgid "Hotkey levels are not active" | |
70 | msgstr "Hotkey Ebenen sind nicht aktiv" | |
71 | ||
72 | msgid "OSD presets are disabled" | |
73 | msgstr "OSD Voreinstellungen sind abgeschaltet" | |
74 | ||
75 | msgid "OSD presets are not active" | |
76 | msgstr "OSD Voreinstellungen sind nicht aktiv" | |
77 | ||
18 | 78 | msgid "Channel (press OK): " |
19 | 79 | msgstr "Sender (OK drücken): " |
20 | 80 | |
21 | 81 | msgid "Page" |
22 | 82 | msgstr "Seite" |
23 | 83 | |
84 | msgid "in cache" | |
85 | msgstr "im Speicher" | |
86 | ||
24 | 87 | msgid "not found" |
25 | 88 | msgstr "nicht gefunden" |
26 | 89 | |
90 | msgid "please wait" | |
91 | msgstr "bitte warten" | |
92 | ||
27 | 93 | msgid "Displays teletext on the OSD" |
28 | 94 | msgstr "Zeigt den Videotext auf dem OSD an" |
29 | 95 | |
30 | msgid "Teletext" | |
31 | msgstr "Videotext" | |
32 | ||
33 | 96 | msgid "Zoom" |
34 | 97 | msgstr "Vergrößern" |
35 | 98 | |
42 | 105 | msgid "Switch background" |
43 | 106 | msgstr "Hintergrund ändern" |
44 | 107 | |
108 | msgid "Config" | |
109 | msgstr "Konfig" | |
110 | ||
111 | msgid "24-LineMode" | |
112 | msgstr "24-ZeilenModus" | |
113 | ||
114 | msgid "Answer" | |
115 | msgstr "Antwort" | |
116 | ||
117 | msgid "Pause" | |
118 | msgstr "Pause" | |
119 | ||
120 | msgid "Hotkey Level+" | |
121 | msgstr "Hotkey Ebene+" | |
122 | ||
123 | msgid "Hotkey Level-" | |
124 | msgstr "Hotkey Ebene-" | |
125 | ||
126 | msgid "OSD Preset+" | |
127 | msgstr "OSD Preset+" | |
128 | ||
129 | msgid "OSD Preset-" | |
130 | msgstr "OSD Preset-" | |
131 | ||
45 | 132 | msgid "Jump to..." |
46 | 133 | msgstr "Springe zu..." |
47 | 134 | |
61 | 148 | msgstr "" |
62 | 149 | |
63 | 150 | msgid "Reserved" |
64 | msgstr "" | |
151 | msgstr "Reserviert" | |
65 | 152 | |
66 | 153 | msgid "Greek" |
67 | 154 | msgstr "" |
71 | 158 | |
72 | 159 | msgid "Hebrew" |
73 | 160 | msgstr "" |
161 | ||
162 | msgid "Hotkeys" | |
163 | msgstr "Hotkeys" | |
164 | ||
165 | msgid "No Hotkeys+Hints" | |
166 | msgstr "Keine Hotkeys+Hinweise" | |
167 | ||
168 | msgid "Hotkeys+Hints" | |
169 | msgstr "Hotkeys+Hinweise" | |
170 | ||
171 | msgid "Hide mainmenu entry" | |
172 | msgstr "Hauptmenüeintrag verstecken" | |
173 | ||
174 | msgid "Show clock" | |
175 | msgstr "Uhr anzeigen" | |
176 | ||
177 | msgid "Auto-update pages" | |
178 | msgstr "Seiten aktualisieren" | |
179 | ||
180 | msgid "G0 code block" | |
181 | msgstr "" | |
182 | ||
183 | msgid "G2 code block" | |
184 | msgstr "" | |
185 | ||
186 | msgid "16-Color Mode" | |
187 | msgstr "16-Farben Modus" | |
188 | ||
189 | msgid "24-Line Mode" | |
190 | msgstr "24-Zeilen Modus" | |
191 | ||
192 | msgid "max" | |
193 | msgstr "max" | |
194 | ||
195 | msgid "Presets" | |
196 | msgstr "Voreinstellungen" | |
197 | ||
198 | msgid "visible" | |
199 | msgstr "sichtbar" | |
200 | ||
201 | msgid "OSD left (%)" | |
202 | msgstr "OSD Links (%)" | |
203 | ||
204 | msgid "OSD top (%)" | |
205 | msgstr "OSD Oben (%)" | |
206 | ||
207 | msgid "OSD width (%)" | |
208 | msgstr "OSD Breite (%)" | |
209 | ||
210 | msgid "OSD height (%)" | |
211 | msgstr "OSD Höhe (%)" | |
212 | ||
213 | msgid "OSD frame pixel" | |
214 | msgstr "OSD Rahmen Pixel" | |
215 | ||
216 | msgid "Text Font" | |
217 | msgstr "Zeichensatz" | |
218 | ||
219 | msgid "Text Vertical Offset" | |
220 | msgstr "Text vertikaler Offset" | |
74 | 221 | |
75 | 222 | msgid "Background transparency" |
76 | 223 | msgstr "Hintergrund-Transparenz" |
77 | 224 | |
78 | msgid "Show clock" | |
79 | msgstr "Uhr anzeigen" | |
80 | ||
81 | msgid "Auto-update pages" | |
82 | msgstr "Seiten aktualisieren" | |
83 | ||
84 | msgid "OSD height" | |
85 | msgstr "OSD-Höhe" | |
86 | ||
87 | msgid "OSD width" | |
88 | msgstr "OSD-Breite" | |
89 | ||
90 | msgid "OSD horizontal align" | |
91 | msgstr "OSD horizontale Anordnung" | |
92 | ||
93 | msgid "OSD vertical align" | |
94 | msgstr "OSD vertikale Anordnung" | |
95 | ||
96 | msgid "Hide mainmenu entry" | |
97 | msgstr "Hauptmenüeintrag verstecken" | |
98 | ||
99 | msgid "Text Font" | |
100 | msgstr "" | |
101 | ||
102 | msgid "G0 code block" | |
103 | msgstr "" | |
104 | ||
105 | msgid "G2 code block" | |
106 | msgstr "" | |
107 | ||
108 | 225 | msgid "Key bindings" |
109 | 226 | msgstr "Tastenzuweisung" |
110 | 227 | |
228 | msgid "Levels" | |
229 | msgstr "Ebenen" | |
230 | ||
231 | msgid "Level" | |
232 | msgstr "Ebene" | |
233 | ||
111 | 234 | msgid " Page number" |
112 | 235 | msgstr " Seitenzahl" |
236 | ||
237 | msgid "Half Page" | |
238 | msgstr "HalbeSeite" | |
239 | ||
240 | msgid "ChangeChan" | |
241 | msgstr "KanalWechs" | |
242 | ||
243 | msgid "SwitchBack" | |
244 | msgstr "Hintergrund" | |
245 | ||
246 | msgid "24LineMode" | |
247 | msgstr "24ZeilenMod" | |
248 | ||
249 | msgid "HkLevel+" | |
250 | msgstr "HkEbene+" | |
251 | ||
252 | msgid "HkLevel-" | |
253 | msgstr "HKEbene-" | |
254 | ||
255 | msgid "Preset+" | |
256 | msgstr "Voreinst+" | |
257 | ||
258 | msgid "Preset-" | |
259 | msgstr "Voreinst-" | |
260 | ||
261 | msgid "Left" | |
262 | msgstr "Links" | |
263 | ||
264 | msgid "Top" | |
265 | msgstr "Oben" | |
266 | ||
267 | msgid "Width" | |
268 | msgstr "Breite" | |
269 | ||
270 | msgid "Height" | |
271 | msgstr "Höhe" | |
272 | ||
273 | msgid "Frame" | |
274 | msgstr "Rahmen" | |
275 | ||
276 | msgid "TxVoffset" | |
277 | msgstr "TxVoffset" | |
278 | ||
279 | msgid "BackTrans" | |
280 | msgstr "HintGrTra" |
6 | 6 | msgstr "" |
7 | 7 | "Project-Id-Version: VDR 1.5.7\n" |
8 | 8 | "Report-Msgid-Bugs-To: <see README>\n" |
9 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
9 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
10 | 10 | "PO-Revision-Date: 2008-05-04 15:33+0200\n" |
11 | 11 | "Last-Translator: Ruben Nunez Francisco <ruben.nunez@tang-it.com>\n" |
12 | 12 | "Language-Team: Spanish <vdr@linuxtv.org>\n" |
15 | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | |
18 | msgid "Switch to" | |
19 | msgstr "" | |
20 | ||
21 | msgid "Channel" | |
22 | msgstr "" | |
23 | ||
24 | msgid "without" | |
25 | msgstr "" | |
26 | ||
27 | msgid "Teletext" | |
28 | msgstr "Teletexto" | |
29 | ||
30 | msgid "live" | |
31 | msgstr "" | |
32 | ||
33 | msgid "Switch back to live" | |
34 | msgstr "" | |
35 | ||
36 | msgid "Tuner available" | |
37 | msgstr "" | |
38 | ||
39 | msgid "display current pages" | |
40 | msgstr "" | |
41 | ||
42 | msgid "Tuner busy" | |
43 | msgstr "" | |
44 | ||
45 | msgid "display cached pages" | |
46 | msgstr "" | |
47 | ||
48 | msgid "cached" | |
49 | msgstr "" | |
50 | ||
51 | msgid "Channel Tuning Successful" | |
52 | msgstr "" | |
53 | ||
54 | msgid "Channel Tuning Not Successful" | |
55 | msgstr "" | |
56 | ||
57 | msgid "No Free Tuner Found - Use Cache Only" | |
58 | msgstr "" | |
59 | ||
60 | msgid "*** Config mode is not supported in 24-line mode ***" | |
61 | msgstr "" | |
62 | ||
63 | msgid "Hotkey level change is not supported in 24-line mode" | |
64 | msgstr "" | |
65 | ||
66 | msgid "Hotkey levels are disabled" | |
67 | msgstr "" | |
68 | ||
69 | msgid "Hotkey levels are not active" | |
70 | msgstr "" | |
71 | ||
72 | msgid "OSD presets are disabled" | |
73 | msgstr "" | |
74 | ||
75 | msgid "OSD presets are not active" | |
76 | msgstr "" | |
77 | ||
18 | 78 | msgid "Channel (press OK): " |
19 | 79 | msgstr "Canal (pulse OK):" |
20 | 80 | |
21 | 81 | msgid "Page" |
22 | 82 | msgstr "Página" |
23 | 83 | |
84 | msgid "in cache" | |
85 | msgstr "" | |
86 | ||
24 | 87 | msgid "not found" |
25 | 88 | msgstr "no encontrada" |
26 | 89 | |
90 | msgid "please wait" | |
91 | msgstr "" | |
92 | ||
27 | 93 | msgid "Displays teletext on the OSD" |
28 | 94 | msgstr "Visualiza el teletexto en el OSD" |
29 | 95 | |
30 | msgid "Teletext" | |
31 | msgstr "Teletexto" | |
32 | ||
33 | 96 | msgid "Zoom" |
34 | 97 | msgstr "Zoom" |
35 | 98 | |
42 | 105 | msgid "Switch background" |
43 | 106 | msgstr "Cambia el fondo" |
44 | 107 | |
108 | msgid "Config" | |
109 | msgstr "" | |
110 | ||
111 | msgid "24-LineMode" | |
112 | msgstr "" | |
113 | ||
114 | msgid "Answer" | |
115 | msgstr "" | |
116 | ||
117 | msgid "Pause" | |
118 | msgstr "" | |
119 | ||
120 | msgid "Hotkey Level+" | |
121 | msgstr "" | |
122 | ||
123 | msgid "Hotkey Level-" | |
124 | msgstr "" | |
125 | ||
126 | msgid "OSD Preset+" | |
127 | msgstr "" | |
128 | ||
129 | msgid "OSD Preset-" | |
130 | msgstr "" | |
131 | ||
45 | 132 | msgid "Jump to..." |
46 | 133 | msgstr "Salta a..." |
47 | 134 | |
72 | 159 | msgid "Hebrew" |
73 | 160 | msgstr "" |
74 | 161 | |
162 | msgid "Hotkeys" | |
163 | msgstr "" | |
164 | ||
165 | msgid "No Hotkeys+Hints" | |
166 | msgstr "" | |
167 | ||
168 | msgid "Hotkeys+Hints" | |
169 | msgstr "" | |
170 | ||
171 | msgid "Hide mainmenu entry" | |
172 | msgstr "" | |
173 | ||
174 | msgid "Show clock" | |
175 | msgstr "Visualiza el reloj" | |
176 | ||
177 | msgid "Auto-update pages" | |
178 | msgstr "" | |
179 | ||
180 | msgid "G0 code block" | |
181 | msgstr "" | |
182 | ||
183 | msgid "G2 code block" | |
184 | msgstr "" | |
185 | ||
186 | msgid "16-Color Mode" | |
187 | msgstr "" | |
188 | ||
189 | msgid "24-Line Mode" | |
190 | msgstr "" | |
191 | ||
192 | msgid "max" | |
193 | msgstr "" | |
194 | ||
195 | msgid "Presets" | |
196 | msgstr "" | |
197 | ||
198 | msgid "visible" | |
199 | msgstr "" | |
200 | ||
201 | msgid "OSD left (%)" | |
202 | msgstr "" | |
203 | ||
204 | msgid "OSD top (%)" | |
205 | msgstr "" | |
206 | ||
207 | msgid "OSD width (%)" | |
208 | msgstr "" | |
209 | ||
210 | msgid "OSD height (%)" | |
211 | msgstr "" | |
212 | ||
213 | msgid "OSD frame pixel" | |
214 | msgstr "" | |
215 | ||
216 | msgid "Text Font" | |
217 | msgstr "" | |
218 | ||
219 | msgid "Text Vertical Offset" | |
220 | msgstr "" | |
221 | ||
75 | 222 | msgid "Background transparency" |
76 | 223 | msgstr "Transparencia del fondo" |
77 | 224 | |
78 | msgid "Show clock" | |
79 | msgstr "Visualiza el reloj" | |
80 | ||
81 | msgid "Auto-update pages" | |
82 | msgstr "" | |
83 | ||
84 | msgid "OSD height" | |
85 | msgstr "Altura OSD" | |
86 | ||
87 | msgid "OSD width" | |
88 | msgstr "Anchura OSD" | |
89 | ||
90 | msgid "OSD horizontal align" | |
91 | msgstr "" | |
92 | ||
93 | msgid "OSD vertical align" | |
94 | msgstr "" | |
95 | ||
96 | msgid "Hide mainmenu entry" | |
97 | msgstr "" | |
98 | ||
99 | msgid "Text Font" | |
100 | msgstr "" | |
101 | ||
102 | msgid "G0 code block" | |
103 | msgstr "" | |
104 | ||
105 | msgid "G2 code block" | |
106 | msgstr "" | |
107 | ||
108 | 225 | msgid "Key bindings" |
226 | msgstr "" | |
227 | ||
228 | msgid "Levels" | |
229 | msgstr "" | |
230 | ||
231 | msgid "Level" | |
109 | 232 | msgstr "" |
110 | 233 | |
111 | 234 | msgid " Page number" |
112 | 235 | msgstr " Número de página" |
236 | ||
237 | msgid "Half Page" | |
238 | msgstr "" | |
239 | ||
240 | msgid "ChangeChan" | |
241 | msgstr "" | |
242 | ||
243 | msgid "SwitchBack" | |
244 | msgstr "" | |
245 | ||
246 | msgid "24LineMode" | |
247 | msgstr "" | |
248 | ||
249 | msgid "HkLevel+" | |
250 | msgstr "" | |
251 | ||
252 | msgid "HkLevel-" | |
253 | msgstr "" | |
254 | ||
255 | msgid "Preset+" | |
256 | msgstr "" | |
257 | ||
258 | msgid "Preset-" | |
259 | msgstr "" | |
260 | ||
261 | msgid "Left" | |
262 | msgstr "" | |
263 | ||
264 | msgid "Top" | |
265 | msgstr "" | |
266 | ||
267 | msgid "Width" | |
268 | msgstr "" | |
269 | ||
270 | msgid "Height" | |
271 | msgstr "" | |
272 | ||
273 | msgid "Frame" | |
274 | msgstr "" | |
275 | ||
276 | msgid "TxVoffset" | |
277 | msgstr "" | |
278 | ||
279 | msgid "BackTrans" | |
280 | msgstr "" | |
281 | ||
282 | #~ msgid "OSD height" | |
283 | #~ msgstr "Altura OSD" | |
284 | ||
285 | #~ msgid "OSD width" | |
286 | #~ msgstr "Anchura OSD" |
6 | 6 | msgstr "" |
7 | 7 | "Project-Id-Version: VDR 1.5.7\n" |
8 | 8 | "Report-Msgid-Bugs-To: <see README>\n" |
9 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
9 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
10 | 10 | "PO-Revision-Date: 2008-05-04 15:33+0200\n" |
11 | 11 | "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n" |
12 | 12 | "Language-Team: Finnish <vdr@linuxtv.org>\n" |
15 | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | |
18 | msgid "Switch to" | |
19 | msgstr "" | |
20 | ||
21 | msgid "Channel" | |
22 | msgstr "" | |
23 | ||
24 | msgid "without" | |
25 | msgstr "" | |
26 | ||
27 | msgid "Teletext" | |
28 | msgstr "Teksti-TV" | |
29 | ||
30 | msgid "live" | |
31 | msgstr "" | |
32 | ||
33 | msgid "Switch back to live" | |
34 | msgstr "" | |
35 | ||
36 | msgid "Tuner available" | |
37 | msgstr "" | |
38 | ||
39 | msgid "display current pages" | |
40 | msgstr "" | |
41 | ||
42 | msgid "Tuner busy" | |
43 | msgstr "" | |
44 | ||
45 | msgid "display cached pages" | |
46 | msgstr "" | |
47 | ||
48 | msgid "cached" | |
49 | msgstr "" | |
50 | ||
51 | msgid "Channel Tuning Successful" | |
52 | msgstr "" | |
53 | ||
54 | msgid "Channel Tuning Not Successful" | |
55 | msgstr "" | |
56 | ||
57 | msgid "No Free Tuner Found - Use Cache Only" | |
58 | msgstr "" | |
59 | ||
60 | msgid "*** Config mode is not supported in 24-line mode ***" | |
61 | msgstr "" | |
62 | ||
63 | msgid "Hotkey level change is not supported in 24-line mode" | |
64 | msgstr "" | |
65 | ||
66 | msgid "Hotkey levels are disabled" | |
67 | msgstr "" | |
68 | ||
69 | msgid "Hotkey levels are not active" | |
70 | msgstr "" | |
71 | ||
72 | msgid "OSD presets are disabled" | |
73 | msgstr "" | |
74 | ||
75 | msgid "OSD presets are not active" | |
76 | msgstr "" | |
77 | ||
18 | 78 | msgid "Channel (press OK): " |
19 | 79 | msgstr "Kanava (paina OK):" |
20 | 80 | |
21 | 81 | msgid "Page" |
22 | 82 | msgstr "Sivua" |
23 | 83 | |
84 | msgid "in cache" | |
85 | msgstr "" | |
86 | ||
24 | 87 | msgid "not found" |
25 | 88 | msgstr "ei löydy" |
26 | 89 | |
90 | msgid "please wait" | |
91 | msgstr "" | |
92 | ||
27 | 93 | msgid "Displays teletext on the OSD" |
28 | 94 | msgstr "Teksti-TV (OSD)" |
29 | 95 | |
30 | msgid "Teletext" | |
31 | msgstr "Teksti-TV" | |
32 | ||
33 | 96 | msgid "Zoom" |
34 | 97 | msgstr "Suurenna" |
35 | 98 | |
42 | 105 | msgid "Switch background" |
43 | 106 | msgstr "Vaihda tausta" |
44 | 107 | |
108 | msgid "Config" | |
109 | msgstr "" | |
110 | ||
111 | msgid "24-LineMode" | |
112 | msgstr "" | |
113 | ||
114 | msgid "Answer" | |
115 | msgstr "" | |
116 | ||
117 | msgid "Pause" | |
118 | msgstr "" | |
119 | ||
120 | msgid "Hotkey Level+" | |
121 | msgstr "" | |
122 | ||
123 | msgid "Hotkey Level-" | |
124 | msgstr "" | |
125 | ||
126 | msgid "OSD Preset+" | |
127 | msgstr "" | |
128 | ||
129 | msgid "OSD Preset-" | |
130 | msgstr "" | |
131 | ||
45 | 132 | msgid "Jump to..." |
46 | 133 | msgstr "Siirry sivulle..." |
47 | 134 | |
72 | 159 | msgid "Hebrew" |
73 | 160 | msgstr "hebrea" |
74 | 161 | |
162 | msgid "Hotkeys" | |
163 | msgstr "" | |
164 | ||
165 | msgid "No Hotkeys+Hints" | |
166 | msgstr "" | |
167 | ||
168 | msgid "Hotkeys+Hints" | |
169 | msgstr "" | |
170 | ||
171 | msgid "Hide mainmenu entry" | |
172 | msgstr "Piilota valinta päävalikosta" | |
173 | ||
174 | msgid "Show clock" | |
175 | msgstr "Näytä kello" | |
176 | ||
177 | msgid "Auto-update pages" | |
178 | msgstr "Automaattinen sivupäivitys" | |
179 | ||
180 | msgid "G0 code block" | |
181 | msgstr "G0-koodilohko" | |
182 | ||
183 | msgid "G2 code block" | |
184 | msgstr "G2-koodilohko" | |
185 | ||
186 | msgid "16-Color Mode" | |
187 | msgstr "" | |
188 | ||
189 | msgid "24-Line Mode" | |
190 | msgstr "" | |
191 | ||
192 | msgid "max" | |
193 | msgstr "" | |
194 | ||
195 | msgid "Presets" | |
196 | msgstr "" | |
197 | ||
198 | msgid "visible" | |
199 | msgstr "" | |
200 | ||
201 | msgid "OSD left (%)" | |
202 | msgstr "" | |
203 | ||
204 | msgid "OSD top (%)" | |
205 | msgstr "" | |
206 | ||
207 | msgid "OSD width (%)" | |
208 | msgstr "" | |
209 | ||
210 | msgid "OSD height (%)" | |
211 | msgstr "" | |
212 | ||
213 | msgid "OSD frame pixel" | |
214 | msgstr "" | |
215 | ||
216 | msgid "Text Font" | |
217 | msgstr "Käytä kirjasinta" | |
218 | ||
219 | msgid "Text Vertical Offset" | |
220 | msgstr "" | |
221 | ||
75 | 222 | msgid "Background transparency" |
76 | 223 | msgstr "Taustan läpinäkyvyys" |
77 | 224 | |
78 | msgid "Show clock" | |
79 | msgstr "Näytä kello" | |
80 | ||
81 | msgid "Auto-update pages" | |
82 | msgstr "Automaattinen sivupäivitys" | |
83 | ||
84 | msgid "OSD height" | |
85 | msgstr "Korkeus" | |
86 | ||
87 | msgid "OSD width" | |
88 | msgstr "Leveys" | |
89 | ||
90 | msgid "OSD horizontal align" | |
91 | msgstr "Pystykeskitys" | |
92 | ||
93 | msgid "OSD vertical align" | |
94 | msgstr "Vaakakeskitys" | |
95 | ||
96 | msgid "Hide mainmenu entry" | |
97 | msgstr "Piilota valinta päävalikosta" | |
98 | ||
99 | msgid "Text Font" | |
100 | msgstr "Käytä kirjasinta" | |
101 | ||
102 | msgid "G0 code block" | |
103 | msgstr "G0-koodilohko" | |
104 | ||
105 | msgid "G2 code block" | |
106 | msgstr "G2-koodilohko" | |
107 | ||
108 | 225 | msgid "Key bindings" |
109 | 226 | msgstr "Näppäintoiminnot" |
110 | 227 | |
228 | msgid "Levels" | |
229 | msgstr "" | |
230 | ||
231 | msgid "Level" | |
232 | msgstr "" | |
233 | ||
111 | 234 | msgid " Page number" |
112 | 235 | msgstr " Sivunumero" |
236 | ||
237 | msgid "Half Page" | |
238 | msgstr "" | |
239 | ||
240 | msgid "ChangeChan" | |
241 | msgstr "" | |
242 | ||
243 | msgid "SwitchBack" | |
244 | msgstr "" | |
245 | ||
246 | msgid "24LineMode" | |
247 | msgstr "" | |
248 | ||
249 | msgid "HkLevel+" | |
250 | msgstr "" | |
251 | ||
252 | msgid "HkLevel-" | |
253 | msgstr "" | |
254 | ||
255 | msgid "Preset+" | |
256 | msgstr "" | |
257 | ||
258 | msgid "Preset-" | |
259 | msgstr "" | |
260 | ||
261 | msgid "Left" | |
262 | msgstr "" | |
263 | ||
264 | msgid "Top" | |
265 | msgstr "" | |
266 | ||
267 | msgid "Width" | |
268 | msgstr "" | |
269 | ||
270 | msgid "Height" | |
271 | msgstr "" | |
272 | ||
273 | msgid "Frame" | |
274 | msgstr "" | |
275 | ||
276 | msgid "TxVoffset" | |
277 | msgstr "" | |
278 | ||
279 | msgid "BackTrans" | |
280 | msgstr "" | |
281 | ||
282 | #~ msgid "OSD height" | |
283 | #~ msgstr "Korkeus" | |
284 | ||
285 | #~ msgid "OSD width" | |
286 | #~ msgstr "Leveys" | |
287 | ||
288 | #~ msgid "OSD horizontal align" | |
289 | #~ msgstr "Pystykeskitys" | |
290 | ||
291 | #~ msgid "OSD vertical align" | |
292 | #~ msgstr "Vaakakeskitys" |
9 | 9 | msgstr "" |
10 | 10 | "Project-Id-Version: VDR 1.5.7\n" |
11 | 11 | "Report-Msgid-Bugs-To: <see README>\n" |
12 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
12 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
13 | 13 | "PO-Revision-Date: 2009-01-10 19:32+0100\n" |
14 | 14 | "Last-Translator: Nival Michaël\n" |
15 | 15 | "Language-Team: French <vdr@linuxtv.org>\n" |
18 | 18 | "Content-Type: text/plain; charset=UTF-8\n" |
19 | 19 | "Content-Transfer-Encoding: 8bit\n" |
20 | 20 | |
21 | msgid "Switch to" | |
22 | msgstr "" | |
23 | ||
24 | msgid "Channel" | |
25 | msgstr "" | |
26 | ||
27 | msgid "without" | |
28 | msgstr "" | |
29 | ||
30 | msgid "Teletext" | |
31 | msgstr "Teletexte" | |
32 | ||
33 | msgid "live" | |
34 | msgstr "" | |
35 | ||
36 | msgid "Switch back to live" | |
37 | msgstr "" | |
38 | ||
39 | msgid "Tuner available" | |
40 | msgstr "" | |
41 | ||
42 | msgid "display current pages" | |
43 | msgstr "" | |
44 | ||
45 | msgid "Tuner busy" | |
46 | msgstr "" | |
47 | ||
48 | msgid "display cached pages" | |
49 | msgstr "" | |
50 | ||
51 | msgid "cached" | |
52 | msgstr "" | |
53 | ||
54 | msgid "Channel Tuning Successful" | |
55 | msgstr "" | |
56 | ||
57 | msgid "Channel Tuning Not Successful" | |
58 | msgstr "" | |
59 | ||
60 | msgid "No Free Tuner Found - Use Cache Only" | |
61 | msgstr "" | |
62 | ||
63 | msgid "*** Config mode is not supported in 24-line mode ***" | |
64 | msgstr "" | |
65 | ||
66 | msgid "Hotkey level change is not supported in 24-line mode" | |
67 | msgstr "" | |
68 | ||
69 | msgid "Hotkey levels are disabled" | |
70 | msgstr "" | |
71 | ||
72 | msgid "Hotkey levels are not active" | |
73 | msgstr "" | |
74 | ||
75 | msgid "OSD presets are disabled" | |
76 | msgstr "" | |
77 | ||
78 | msgid "OSD presets are not active" | |
79 | msgstr "" | |
80 | ||
21 | 81 | msgid "Channel (press OK): " |
22 | 82 | msgstr "Chaine (Appuyer sur OK): " |
23 | 83 | |
24 | 84 | msgid "Page" |
25 | 85 | msgstr "Page" |
26 | 86 | |
87 | msgid "in cache" | |
88 | msgstr "" | |
89 | ||
27 | 90 | msgid "not found" |
28 | 91 | msgstr "pas trouvé" |
29 | 92 | |
93 | msgid "please wait" | |
94 | msgstr "" | |
95 | ||
30 | 96 | msgid "Displays teletext on the OSD" |
31 | 97 | msgstr "Affiche le télétexte sur l'OSD" |
32 | 98 | |
33 | msgid "Teletext" | |
34 | msgstr "Teletexte" | |
35 | ||
36 | 99 | msgid "Zoom" |
37 | 100 | msgstr "Zoom" |
38 | 101 | |
45 | 108 | msgid "Switch background" |
46 | 109 | msgstr "Change le fond d'écran" |
47 | 110 | |
111 | msgid "Config" | |
112 | msgstr "" | |
113 | ||
114 | msgid "24-LineMode" | |
115 | msgstr "" | |
116 | ||
117 | msgid "Answer" | |
118 | msgstr "" | |
119 | ||
120 | msgid "Pause" | |
121 | msgstr "" | |
122 | ||
123 | msgid "Hotkey Level+" | |
124 | msgstr "" | |
125 | ||
126 | msgid "Hotkey Level-" | |
127 | msgstr "" | |
128 | ||
129 | msgid "OSD Preset+" | |
130 | msgstr "" | |
131 | ||
132 | msgid "OSD Preset-" | |
133 | msgstr "" | |
134 | ||
48 | 135 | msgid "Jump to..." |
49 | 136 | msgstr "Aller à..." |
50 | 137 | |
75 | 162 | msgid "Hebrew" |
76 | 163 | msgstr "" |
77 | 164 | |
165 | msgid "Hotkeys" | |
166 | msgstr "" | |
167 | ||
168 | msgid "No Hotkeys+Hints" | |
169 | msgstr "" | |
170 | ||
171 | msgid "Hotkeys+Hints" | |
172 | msgstr "" | |
173 | ||
174 | msgid "Hide mainmenu entry" | |
175 | msgstr "" | |
176 | ||
177 | msgid "Show clock" | |
178 | msgstr "Afficher l'heure" | |
179 | ||
180 | msgid "Auto-update pages" | |
181 | msgstr "Mise à jour des pages" | |
182 | ||
183 | msgid "G0 code block" | |
184 | msgstr "" | |
185 | ||
186 | msgid "G2 code block" | |
187 | msgstr "" | |
188 | ||
189 | msgid "16-Color Mode" | |
190 | msgstr "" | |
191 | ||
192 | msgid "24-Line Mode" | |
193 | msgstr "" | |
194 | ||
195 | msgid "max" | |
196 | msgstr "" | |
197 | ||
198 | msgid "Presets" | |
199 | msgstr "" | |
200 | ||
201 | msgid "visible" | |
202 | msgstr "" | |
203 | ||
204 | msgid "OSD left (%)" | |
205 | msgstr "" | |
206 | ||
207 | msgid "OSD top (%)" | |
208 | msgstr "" | |
209 | ||
210 | msgid "OSD width (%)" | |
211 | msgstr "" | |
212 | ||
213 | msgid "OSD height (%)" | |
214 | msgstr "" | |
215 | ||
216 | msgid "OSD frame pixel" | |
217 | msgstr "" | |
218 | ||
219 | msgid "Text Font" | |
220 | msgstr "" | |
221 | ||
222 | msgid "Text Vertical Offset" | |
223 | msgstr "" | |
224 | ||
78 | 225 | msgid "Background transparency" |
79 | 226 | msgstr "Fond transparent" |
80 | 227 | |
81 | msgid "Show clock" | |
82 | msgstr "Afficher l'heure" | |
83 | ||
84 | msgid "Auto-update pages" | |
85 | msgstr "Mise à jour des pages" | |
86 | ||
87 | msgid "OSD height" | |
88 | msgstr "Hauteur OSD" | |
89 | ||
90 | msgid "OSD width" | |
91 | msgstr "Largeur OSD" | |
92 | ||
93 | msgid "OSD horizontal align" | |
94 | msgstr "Alignement horizontal de l'OSD" | |
95 | ||
96 | msgid "OSD vertical align" | |
97 | msgstr "Alignement vertical de l'OSD" | |
98 | ||
99 | msgid "Hide mainmenu entry" | |
100 | msgstr "" | |
101 | ||
102 | msgid "Text Font" | |
103 | msgstr "" | |
104 | ||
105 | msgid "G0 code block" | |
106 | msgstr "" | |
107 | ||
108 | msgid "G2 code block" | |
109 | msgstr "" | |
110 | ||
111 | 228 | msgid "Key bindings" |
112 | 229 | msgstr "Attribution des touches" |
113 | 230 | |
231 | msgid "Levels" | |
232 | msgstr "" | |
233 | ||
234 | msgid "Level" | |
235 | msgstr "" | |
236 | ||
114 | 237 | msgid " Page number" |
115 | 238 | msgstr " Nombre de pages" |
239 | ||
240 | msgid "Half Page" | |
241 | msgstr "" | |
242 | ||
243 | msgid "ChangeChan" | |
244 | msgstr "" | |
245 | ||
246 | msgid "SwitchBack" | |
247 | msgstr "" | |
248 | ||
249 | msgid "24LineMode" | |
250 | msgstr "" | |
251 | ||
252 | msgid "HkLevel+" | |
253 | msgstr "" | |
254 | ||
255 | msgid "HkLevel-" | |
256 | msgstr "" | |
257 | ||
258 | msgid "Preset+" | |
259 | msgstr "" | |
260 | ||
261 | msgid "Preset-" | |
262 | msgstr "" | |
263 | ||
264 | msgid "Left" | |
265 | msgstr "" | |
266 | ||
267 | msgid "Top" | |
268 | msgstr "" | |
269 | ||
270 | msgid "Width" | |
271 | msgstr "" | |
272 | ||
273 | msgid "Height" | |
274 | msgstr "" | |
275 | ||
276 | msgid "Frame" | |
277 | msgstr "" | |
278 | ||
279 | msgid "TxVoffset" | |
280 | msgstr "" | |
281 | ||
282 | msgid "BackTrans" | |
283 | msgstr "" | |
284 | ||
285 | #~ msgid "OSD height" | |
286 | #~ msgstr "Hauteur OSD" | |
287 | ||
288 | #~ msgid "OSD width" | |
289 | #~ msgstr "Largeur OSD" | |
290 | ||
291 | #~ msgid "OSD horizontal align" | |
292 | #~ msgstr "Alignement horizontal de l'OSD" | |
293 | ||
294 | #~ msgid "OSD vertical align" | |
295 | #~ msgstr "Alignement vertical de l'OSD" |
10 | 10 | msgstr "" |
11 | 11 | "Project-Id-Version: VDR 1.5.7\n" |
12 | 12 | "Report-Msgid-Bugs-To: <see README>\n" |
13 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
13 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
14 | 14 | "PO-Revision-Date: 2010-11-06 19:59+0100\n" |
15 | 15 | "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" |
16 | 16 | "Language-Team: Italian <vdr@linuxtv.org>\n" |
22 | 22 | "X-Poedit-Country: ITALY\n" |
23 | 23 | "X-Poedit-SourceCharset: utf-8\n" |
24 | 24 | |
25 | msgid "Switch to" | |
26 | msgstr "" | |
27 | ||
28 | msgid "Channel" | |
29 | msgstr "" | |
30 | ||
31 | msgid "without" | |
32 | msgstr "" | |
33 | ||
34 | msgid "Teletext" | |
35 | msgstr "Teletext" | |
36 | ||
37 | msgid "live" | |
38 | msgstr "" | |
39 | ||
40 | msgid "Switch back to live" | |
41 | msgstr "" | |
42 | ||
43 | msgid "Tuner available" | |
44 | msgstr "" | |
45 | ||
46 | msgid "display current pages" | |
47 | msgstr "" | |
48 | ||
49 | msgid "Tuner busy" | |
50 | msgstr "" | |
51 | ||
52 | msgid "display cached pages" | |
53 | msgstr "" | |
54 | ||
55 | msgid "cached" | |
56 | msgstr "" | |
57 | ||
58 | msgid "Channel Tuning Successful" | |
59 | msgstr "" | |
60 | ||
61 | msgid "Channel Tuning Not Successful" | |
62 | msgstr "" | |
63 | ||
64 | msgid "No Free Tuner Found - Use Cache Only" | |
65 | msgstr "" | |
66 | ||
67 | msgid "*** Config mode is not supported in 24-line mode ***" | |
68 | msgstr "" | |
69 | ||
70 | msgid "Hotkey level change is not supported in 24-line mode" | |
71 | msgstr "" | |
72 | ||
73 | msgid "Hotkey levels are disabled" | |
74 | msgstr "" | |
75 | ||
76 | msgid "Hotkey levels are not active" | |
77 | msgstr "" | |
78 | ||
79 | msgid "OSD presets are disabled" | |
80 | msgstr "" | |
81 | ||
82 | msgid "OSD presets are not active" | |
83 | msgstr "" | |
84 | ||
25 | 85 | msgid "Channel (press OK): " |
26 | 86 | msgstr "Canale (premi OK): " |
27 | 87 | |
28 | 88 | msgid "Page" |
29 | 89 | msgstr "Pagina" |
30 | 90 | |
91 | msgid "in cache" | |
92 | msgstr "" | |
93 | ||
31 | 94 | msgid "not found" |
32 | 95 | msgstr "non trovata" |
33 | 96 | |
97 | msgid "please wait" | |
98 | msgstr "" | |
99 | ||
34 | 100 | msgid "Displays teletext on the OSD" |
35 | 101 | msgstr "Mostra il teletext in OSD" |
36 | 102 | |
37 | msgid "Teletext" | |
38 | msgstr "Teletext" | |
39 | ||
40 | 103 | msgid "Zoom" |
41 | 104 | msgstr "Ingrandisci" |
42 | 105 | |
49 | 112 | msgid "Switch background" |
50 | 113 | msgstr "Cambia sfondo" |
51 | 114 | |
115 | msgid "Config" | |
116 | msgstr "" | |
117 | ||
118 | msgid "24-LineMode" | |
119 | msgstr "" | |
120 | ||
121 | msgid "Answer" | |
122 | msgstr "" | |
123 | ||
124 | msgid "Pause" | |
125 | msgstr "" | |
126 | ||
127 | msgid "Hotkey Level+" | |
128 | msgstr "" | |
129 | ||
130 | msgid "Hotkey Level-" | |
131 | msgstr "" | |
132 | ||
133 | msgid "OSD Preset+" | |
134 | msgstr "" | |
135 | ||
136 | msgid "OSD Preset-" | |
137 | msgstr "" | |
138 | ||
52 | 139 | msgid "Jump to..." |
53 | 140 | msgstr "Vai a..." |
54 | 141 | |
79 | 166 | msgid "Hebrew" |
80 | 167 | msgstr "" |
81 | 168 | |
169 | msgid "Hotkeys" | |
170 | msgstr "" | |
171 | ||
172 | msgid "No Hotkeys+Hints" | |
173 | msgstr "" | |
174 | ||
175 | msgid "Hotkeys+Hints" | |
176 | msgstr "" | |
177 | ||
178 | msgid "Hide mainmenu entry" | |
179 | msgstr "Nascondi voce menu principale" | |
180 | ||
181 | msgid "Show clock" | |
182 | msgstr "Mostra orologio" | |
183 | ||
184 | msgid "Auto-update pages" | |
185 | msgstr "Aggiorn. automatico pagine" | |
186 | ||
187 | msgid "G0 code block" | |
188 | msgstr "" | |
189 | ||
190 | msgid "G2 code block" | |
191 | msgstr "" | |
192 | ||
193 | msgid "16-Color Mode" | |
194 | msgstr "" | |
195 | ||
196 | msgid "24-Line Mode" | |
197 | msgstr "" | |
198 | ||
199 | msgid "max" | |
200 | msgstr "" | |
201 | ||
202 | msgid "Presets" | |
203 | msgstr "" | |
204 | ||
205 | msgid "visible" | |
206 | msgstr "" | |
207 | ||
208 | msgid "OSD left (%)" | |
209 | msgstr "" | |
210 | ||
211 | msgid "OSD top (%)" | |
212 | msgstr "" | |
213 | ||
214 | msgid "OSD width (%)" | |
215 | msgstr "" | |
216 | ||
217 | msgid "OSD height (%)" | |
218 | msgstr "" | |
219 | ||
220 | msgid "OSD frame pixel" | |
221 | msgstr "" | |
222 | ||
223 | msgid "Text Font" | |
224 | msgstr "" | |
225 | ||
226 | msgid "Text Vertical Offset" | |
227 | msgstr "" | |
228 | ||
82 | 229 | msgid "Background transparency" |
83 | 230 | msgstr "Trasparenza sfondo" |
84 | 231 | |
85 | msgid "Show clock" | |
86 | msgstr "Mostra orologio" | |
87 | ||
88 | msgid "Auto-update pages" | |
89 | msgstr "Aggiorn. automatico pagine" | |
90 | ||
91 | msgid "OSD height" | |
92 | msgstr "Altezza OSD" | |
93 | ||
94 | msgid "OSD width" | |
95 | msgstr "Larghezza OSD" | |
96 | ||
97 | msgid "OSD horizontal align" | |
98 | msgstr "Allineamento orizzontale OSD" | |
99 | ||
100 | msgid "OSD vertical align" | |
101 | msgstr "Allineamento verticale OSD" | |
102 | ||
103 | msgid "Hide mainmenu entry" | |
104 | msgstr "Nascondi voce menu principale" | |
105 | ||
106 | msgid "Text Font" | |
107 | msgstr "" | |
108 | ||
109 | msgid "G0 code block" | |
110 | msgstr "" | |
111 | ||
112 | msgid "G2 code block" | |
113 | msgstr "" | |
114 | ||
115 | 232 | msgid "Key bindings" |
116 | 233 | msgstr "Tasti associati" |
117 | 234 | |
235 | msgid "Levels" | |
236 | msgstr "" | |
237 | ||
238 | msgid "Level" | |
239 | msgstr "" | |
240 | ||
118 | 241 | msgid " Page number" |
119 | 242 | msgstr " Numero pagina" |
243 | ||
244 | msgid "Half Page" | |
245 | msgstr "" | |
246 | ||
247 | msgid "ChangeChan" | |
248 | msgstr "" | |
249 | ||
250 | msgid "SwitchBack" | |
251 | msgstr "" | |
252 | ||
253 | msgid "24LineMode" | |
254 | msgstr "" | |
255 | ||
256 | msgid "HkLevel+" | |
257 | msgstr "" | |
258 | ||
259 | msgid "HkLevel-" | |
260 | msgstr "" | |
261 | ||
262 | msgid "Preset+" | |
263 | msgstr "" | |
264 | ||
265 | msgid "Preset-" | |
266 | msgstr "" | |
267 | ||
268 | msgid "Left" | |
269 | msgstr "" | |
270 | ||
271 | msgid "Top" | |
272 | msgstr "" | |
273 | ||
274 | msgid "Width" | |
275 | msgstr "" | |
276 | ||
277 | msgid "Height" | |
278 | msgstr "" | |
279 | ||
280 | msgid "Frame" | |
281 | msgstr "" | |
282 | ||
283 | msgid "TxVoffset" | |
284 | msgstr "" | |
285 | ||
286 | msgid "BackTrans" | |
287 | msgstr "" | |
288 | ||
289 | #~ msgid "OSD height" | |
290 | #~ msgstr "Altezza OSD" | |
291 | ||
292 | #~ msgid "OSD width" | |
293 | #~ msgstr "Larghezza OSD" | |
294 | ||
295 | #~ msgid "OSD horizontal align" | |
296 | #~ msgstr "Allineamento orizzontale OSD" | |
297 | ||
298 | #~ msgid "OSD vertical align" | |
299 | #~ msgstr "Allineamento verticale OSD" |
6 | 6 | msgstr "" |
7 | 7 | "Project-Id-Version: VDR 1.5.7\n" |
8 | 8 | "Report-Msgid-Bugs-To: <see README>\n" |
9 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
9 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
10 | 10 | "PO-Revision-Date: 2008-05-04 15:33+0200\n" |
11 | 11 | "Last-Translator: Chris Silva <hudokkow@gmail.com>\n" |
12 | 12 | "Language-Team: Portuguese <vdr@linuxtv.org>\n" |
15 | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | |
18 | msgid "Switch to" | |
19 | msgstr "" | |
20 | ||
21 | msgid "Channel" | |
22 | msgstr "" | |
23 | ||
24 | msgid "without" | |
25 | msgstr "" | |
26 | ||
27 | msgid "Teletext" | |
28 | msgstr "Teletexto" | |
29 | ||
30 | msgid "live" | |
31 | msgstr "" | |
32 | ||
33 | msgid "Switch back to live" | |
34 | msgstr "" | |
35 | ||
36 | msgid "Tuner available" | |
37 | msgstr "" | |
38 | ||
39 | msgid "display current pages" | |
40 | msgstr "" | |
41 | ||
42 | msgid "Tuner busy" | |
43 | msgstr "" | |
44 | ||
45 | msgid "display cached pages" | |
46 | msgstr "" | |
47 | ||
48 | msgid "cached" | |
49 | msgstr "" | |
50 | ||
51 | msgid "Channel Tuning Successful" | |
52 | msgstr "" | |
53 | ||
54 | msgid "Channel Tuning Not Successful" | |
55 | msgstr "" | |
56 | ||
57 | msgid "No Free Tuner Found - Use Cache Only" | |
58 | msgstr "" | |
59 | ||
60 | msgid "*** Config mode is not supported in 24-line mode ***" | |
61 | msgstr "" | |
62 | ||
63 | msgid "Hotkey level change is not supported in 24-line mode" | |
64 | msgstr "" | |
65 | ||
66 | msgid "Hotkey levels are disabled" | |
67 | msgstr "" | |
68 | ||
69 | msgid "Hotkey levels are not active" | |
70 | msgstr "" | |
71 | ||
72 | msgid "OSD presets are disabled" | |
73 | msgstr "" | |
74 | ||
75 | msgid "OSD presets are not active" | |
76 | msgstr "" | |
77 | ||
18 | 78 | msgid "Channel (press OK): " |
19 | 79 | msgstr "Sender (Prima OK): " |
20 | 80 | |
21 | 81 | msgid "Page" |
22 | 82 | msgstr "Página" |
23 | 83 | |
84 | msgid "in cache" | |
85 | msgstr "" | |
86 | ||
24 | 87 | msgid "not found" |
25 | 88 | msgstr "Não encontrado" |
26 | 89 | |
90 | msgid "please wait" | |
91 | msgstr "" | |
92 | ||
27 | 93 | msgid "Displays teletext on the OSD" |
28 | 94 | msgstr "Mostra o teletexto no OSD" |
29 | 95 | |
30 | msgid "Teletext" | |
31 | msgstr "Teletexto" | |
32 | ||
33 | 96 | msgid "Zoom" |
34 | 97 | msgstr "Zoom" |
35 | 98 | |
42 | 105 | msgid "Switch background" |
43 | 106 | msgstr "Mudar fundo" |
44 | 107 | |
108 | msgid "Config" | |
109 | msgstr "" | |
110 | ||
111 | msgid "24-LineMode" | |
112 | msgstr "" | |
113 | ||
114 | msgid "Answer" | |
115 | msgstr "" | |
116 | ||
117 | msgid "Pause" | |
118 | msgstr "" | |
119 | ||
120 | msgid "Hotkey Level+" | |
121 | msgstr "" | |
122 | ||
123 | msgid "Hotkey Level-" | |
124 | msgstr "" | |
125 | ||
126 | msgid "OSD Preset+" | |
127 | msgstr "" | |
128 | ||
129 | msgid "OSD Preset-" | |
130 | msgstr "" | |
131 | ||
45 | 132 | msgid "Jump to..." |
46 | 133 | msgstr "Ir para" |
47 | 134 | |
72 | 159 | msgid "Hebrew" |
73 | 160 | msgstr "" |
74 | 161 | |
162 | msgid "Hotkeys" | |
163 | msgstr "" | |
164 | ||
165 | msgid "No Hotkeys+Hints" | |
166 | msgstr "" | |
167 | ||
168 | msgid "Hotkeys+Hints" | |
169 | msgstr "" | |
170 | ||
171 | msgid "Hide mainmenu entry" | |
172 | msgstr "" | |
173 | ||
174 | msgid "Show clock" | |
175 | msgstr "Mostrar Relógio" | |
176 | ||
177 | msgid "Auto-update pages" | |
178 | msgstr "Auto actualizar páginas" | |
179 | ||
180 | msgid "G0 code block" | |
181 | msgstr "" | |
182 | ||
183 | msgid "G2 code block" | |
184 | msgstr "" | |
185 | ||
186 | msgid "16-Color Mode" | |
187 | msgstr "" | |
188 | ||
189 | msgid "24-Line Mode" | |
190 | msgstr "" | |
191 | ||
192 | msgid "max" | |
193 | msgstr "" | |
194 | ||
195 | msgid "Presets" | |
196 | msgstr "" | |
197 | ||
198 | msgid "visible" | |
199 | msgstr "" | |
200 | ||
201 | msgid "OSD left (%)" | |
202 | msgstr "" | |
203 | ||
204 | msgid "OSD top (%)" | |
205 | msgstr "" | |
206 | ||
207 | msgid "OSD width (%)" | |
208 | msgstr "" | |
209 | ||
210 | msgid "OSD height (%)" | |
211 | msgstr "" | |
212 | ||
213 | msgid "OSD frame pixel" | |
214 | msgstr "" | |
215 | ||
216 | msgid "Text Font" | |
217 | msgstr "" | |
218 | ||
219 | msgid "Text Vertical Offset" | |
220 | msgstr "" | |
221 | ||
75 | 222 | msgid "Background transparency" |
76 | 223 | msgstr "Transparência do Fundo" |
77 | 224 | |
78 | msgid "Show clock" | |
79 | msgstr "Mostrar Relógio" | |
80 | ||
81 | msgid "Auto-update pages" | |
82 | msgstr "Auto actualizar páginas" | |
83 | ||
84 | msgid "OSD height" | |
85 | msgstr "Altura do OSD" | |
86 | ||
87 | msgid "OSD width" | |
88 | msgstr "Largura do OSD" | |
89 | ||
90 | msgid "OSD horizontal align" | |
91 | msgstr "Alinhamento Horizontal do OSD" | |
92 | ||
93 | msgid "OSD vertical align" | |
94 | msgstr "Alinhamento Vertical do OSD" | |
95 | ||
96 | msgid "Hide mainmenu entry" | |
97 | msgstr "" | |
98 | ||
99 | msgid "Text Font" | |
100 | msgstr "" | |
101 | ||
102 | msgid "G0 code block" | |
103 | msgstr "" | |
104 | ||
105 | msgid "G2 code block" | |
106 | msgstr "" | |
107 | ||
108 | 225 | msgid "Key bindings" |
109 | 226 | msgstr "Tecla alocada" |
110 | 227 | |
228 | msgid "Levels" | |
229 | msgstr "" | |
230 | ||
231 | msgid "Level" | |
232 | msgstr "" | |
233 | ||
111 | 234 | msgid " Page number" |
112 | 235 | msgstr " Número de Página" |
236 | ||
237 | msgid "Half Page" | |
238 | msgstr "" | |
239 | ||
240 | msgid "ChangeChan" | |
241 | msgstr "" | |
242 | ||
243 | msgid "SwitchBack" | |
244 | msgstr "" | |
245 | ||
246 | msgid "24LineMode" | |
247 | msgstr "" | |
248 | ||
249 | msgid "HkLevel+" | |
250 | msgstr "" | |
251 | ||
252 | msgid "HkLevel-" | |
253 | msgstr "" | |
254 | ||
255 | msgid "Preset+" | |
256 | msgstr "" | |
257 | ||
258 | msgid "Preset-" | |
259 | msgstr "" | |
260 | ||
261 | msgid "Left" | |
262 | msgstr "" | |
263 | ||
264 | msgid "Top" | |
265 | msgstr "" | |
266 | ||
267 | msgid "Width" | |
268 | msgstr "" | |
269 | ||
270 | msgid "Height" | |
271 | msgstr "" | |
272 | ||
273 | msgid "Frame" | |
274 | msgstr "" | |
275 | ||
276 | msgid "TxVoffset" | |
277 | msgstr "" | |
278 | ||
279 | msgid "BackTrans" | |
280 | msgstr "" | |
281 | ||
282 | #~ msgid "OSD height" | |
283 | #~ msgstr "Altura do OSD" | |
284 | ||
285 | #~ msgid "OSD width" | |
286 | #~ msgstr "Largura do OSD" | |
287 | ||
288 | #~ msgid "OSD horizontal align" | |
289 | #~ msgstr "Alinhamento Horizontal do OSD" | |
290 | ||
291 | #~ msgid "OSD vertical align" | |
292 | #~ msgstr "Alinhamento Vertical do OSD" |
7 | 7 | msgstr "" |
8 | 8 | "Project-Id-Version: VDR 1.5.7\n" |
9 | 9 | "Report-Msgid-Bugs-To: <see README>\n" |
10 | "POT-Creation-Date: 2017-06-10 21:01+1000\n" | |
10 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
11 | 11 | "PO-Revision-Date: 2008-12-30 13:52+0100\n" |
12 | 12 | "Last-Translator: Andrey Pridvorov <ua0lnj@bk.ru>\n" |
13 | 13 | "Language-Team: Russian <vdr@linuxtv.org>\n" |
16 | 16 | "Content-Type: text/plain; charset=UTF-8\n" |
17 | 17 | "Content-Transfer-Encoding: 8bit\n" |
18 | 18 | |
19 | msgid "Switch to" | |
20 | msgstr "" | |
21 | ||
22 | msgid "Channel" | |
23 | msgstr "" | |
24 | ||
25 | msgid "without" | |
26 | msgstr "" | |
27 | ||
28 | msgid "Teletext" | |
29 | msgstr "Телетекст" | |
30 | ||
31 | msgid "live" | |
32 | msgstr "" | |
33 | ||
34 | msgid "Switch back to live" | |
35 | msgstr "" | |
36 | ||
37 | msgid "Tuner available" | |
38 | msgstr "" | |
39 | ||
40 | msgid "display current pages" | |
41 | msgstr "" | |
42 | ||
43 | msgid "Tuner busy" | |
44 | msgstr "" | |
45 | ||
46 | msgid "display cached pages" | |
47 | msgstr "" | |
48 | ||
49 | msgid "cached" | |
50 | msgstr "" | |
51 | ||
52 | msgid "Channel Tuning Successful" | |
53 | msgstr "" | |
54 | ||
55 | msgid "Channel Tuning Not Successful" | |
56 | msgstr "" | |
57 | ||
58 | msgid "No Free Tuner Found - Use Cache Only" | |
59 | msgstr "" | |
60 | ||
61 | msgid "*** Config mode is not supported in 24-line mode ***" | |
62 | msgstr "" | |
63 | ||
64 | msgid "Hotkey level change is not supported in 24-line mode" | |
65 | msgstr "" | |
66 | ||
67 | msgid "Hotkey levels are disabled" | |
68 | msgstr "" | |
69 | ||
70 | msgid "Hotkey levels are not active" | |
71 | msgstr "" | |
72 | ||
73 | msgid "OSD presets are disabled" | |
74 | msgstr "" | |
75 | ||
76 | msgid "OSD presets are not active" | |
77 | msgstr "" | |
78 | ||
19 | 79 | msgid "Channel (press OK): " |
20 | 80 | msgstr "Канал (Нажмите ОК)" |
21 | 81 | |
22 | 82 | msgid "Page" |
23 | 83 | msgstr "Страница" |
24 | 84 | |
85 | msgid "in cache" | |
86 | msgstr "" | |
87 | ||
25 | 88 | msgid "not found" |
26 | 89 | msgstr "не найдена" |
27 | 90 | |
91 | msgid "please wait" | |
92 | msgstr "" | |
93 | ||
28 | 94 | msgid "Displays teletext on the OSD" |
29 | 95 | msgstr "Показ телетекста в OSD" |
30 | 96 | |
31 | msgid "Teletext" | |
32 | msgstr "Телетекст" | |
33 | ||
34 | 97 | msgid "Zoom" |
35 | 98 | msgstr "увеличить" |
36 | 99 | |
43 | 106 | msgid "Switch background" |
44 | 107 | msgstr "Переключить фон" |
45 | 108 | |
109 | msgid "Config" | |
110 | msgstr "" | |
111 | ||
112 | msgid "24-LineMode" | |
113 | msgstr "" | |
114 | ||
115 | msgid "Answer" | |
116 | msgstr "" | |
117 | ||
118 | msgid "Pause" | |
119 | msgstr "" | |
120 | ||
121 | msgid "Hotkey Level+" | |
122 | msgstr "" | |
123 | ||
124 | msgid "Hotkey Level-" | |
125 | msgstr "" | |
126 | ||
127 | msgid "OSD Preset+" | |
128 | msgstr "" | |
129 | ||
130 | msgid "OSD Preset-" | |
131 | msgstr "" | |
132 | ||
46 | 133 | msgid "Jump to..." |
47 | 134 | msgstr "перейти к..." |
48 | 135 | |
73 | 160 | msgid "Hebrew" |
74 | 161 | msgstr "Иврит" |
75 | 162 | |
163 | msgid "Hotkeys" | |
164 | msgstr "" | |
165 | ||
166 | msgid "No Hotkeys+Hints" | |
167 | msgstr "" | |
168 | ||
169 | msgid "Hotkeys+Hints" | |
170 | msgstr "" | |
171 | ||
172 | msgid "Hide mainmenu entry" | |
173 | msgstr "Скрыть в главном меню" | |
174 | ||
175 | msgid "Show clock" | |
176 | msgstr "Показывать часы" | |
177 | ||
178 | msgid "Auto-update pages" | |
179 | msgstr "Автообновление страниц" | |
180 | ||
181 | msgid "G0 code block" | |
182 | msgstr "G0 кодировка" | |
183 | ||
184 | msgid "G2 code block" | |
185 | msgstr "G2 кодировка" | |
186 | ||
187 | msgid "16-Color Mode" | |
188 | msgstr "" | |
189 | ||
190 | msgid "24-Line Mode" | |
191 | msgstr "" | |
192 | ||
193 | msgid "max" | |
194 | msgstr "" | |
195 | ||
196 | msgid "Presets" | |
197 | msgstr "" | |
198 | ||
199 | msgid "visible" | |
200 | msgstr "" | |
201 | ||
202 | msgid "OSD left (%)" | |
203 | msgstr "" | |
204 | ||
205 | msgid "OSD top (%)" | |
206 | msgstr "" | |
207 | ||
208 | msgid "OSD width (%)" | |
209 | msgstr "" | |
210 | ||
211 | msgid "OSD height (%)" | |
212 | msgstr "" | |
213 | ||
214 | msgid "OSD frame pixel" | |
215 | msgstr "" | |
216 | ||
217 | msgid "Text Font" | |
218 | msgstr "Шрифт" | |
219 | ||
220 | msgid "Text Vertical Offset" | |
221 | msgstr "" | |
222 | ||
76 | 223 | msgid "Background transparency" |
77 | 224 | msgstr "Прозрачность фона" |
78 | 225 | |
79 | msgid "Show clock" | |
80 | msgstr "Показывать часы" | |
81 | ||
82 | msgid "Auto-update pages" | |
83 | msgstr "Автообновление страниц" | |
84 | ||
85 | msgid "OSD height" | |
86 | msgstr "Высота меню" | |
87 | ||
88 | msgid "OSD width" | |
89 | msgstr "Ширина меню" | |
90 | ||
91 | msgid "OSD horizontal align" | |
92 | msgstr "Горизонтальное положение OSD" | |
93 | ||
94 | msgid "OSD vertical align" | |
95 | msgstr "Вертикальное положение OSD" | |
96 | ||
97 | msgid "Hide mainmenu entry" | |
98 | msgstr "Скрыть в главном меню" | |
99 | ||
100 | msgid "Text Font" | |
101 | msgstr "Шрифт" | |
102 | ||
103 | msgid "G0 code block" | |
104 | msgstr "G0 кодировка" | |
105 | ||
106 | msgid "G2 code block" | |
107 | msgstr "G2 кодировка" | |
108 | ||
109 | 226 | msgid "Key bindings" |
110 | 227 | msgstr "Привязка кнопок" |
111 | 228 | |
229 | msgid "Levels" | |
230 | msgstr "" | |
231 | ||
232 | msgid "Level" | |
233 | msgstr "" | |
234 | ||
112 | 235 | msgid " Page number" |
113 | 236 | msgstr " Номер страницы" |
237 | ||
238 | msgid "Half Page" | |
239 | msgstr "" | |
240 | ||
241 | msgid "ChangeChan" | |
242 | msgstr "" | |
243 | ||
244 | msgid "SwitchBack" | |
245 | msgstr "" | |
246 | ||
247 | msgid "24LineMode" | |
248 | msgstr "" | |
249 | ||
250 | msgid "HkLevel+" | |
251 | msgstr "" | |
252 | ||
253 | msgid "HkLevel-" | |
254 | msgstr "" | |
255 | ||
256 | msgid "Preset+" | |
257 | msgstr "" | |
258 | ||
259 | msgid "Preset-" | |
260 | msgstr "" | |
261 | ||
262 | msgid "Left" | |
263 | msgstr "" | |
264 | ||
265 | msgid "Top" | |
266 | msgstr "" | |
267 | ||
268 | msgid "Width" | |
269 | msgstr "" | |
270 | ||
271 | msgid "Height" | |
272 | msgstr "" | |
273 | ||
274 | msgid "Frame" | |
275 | msgstr "" | |
276 | ||
277 | msgid "TxVoffset" | |
278 | msgstr "" | |
279 | ||
280 | msgid "BackTrans" | |
281 | msgstr "" | |
282 | ||
283 | #~ msgid "OSD height" | |
284 | #~ msgstr "Высота меню" | |
285 | ||
286 | #~ msgid "OSD width" | |
287 | #~ msgstr "Ширина меню" | |
288 | ||
289 | #~ msgid "OSD horizontal align" | |
290 | #~ msgstr "Горизонтальное положение OSD" | |
291 | ||
292 | #~ msgid "OSD vertical align" | |
293 | #~ msgstr "Вертикальное положение OSD" |
6 | 6 | msgstr "" |
7 | 7 | "Project-Id-Version: osdteletext-0.9.0\n" |
8 | 8 | "Report-Msgid-Bugs-To: <see README>\n" |
9 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
9 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
10 | 10 | "PO-Revision-Date: 2011-02-15 21:11+0100\n" |
11 | 11 | "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n" |
12 | 12 | "Language-Team: Slovak <hrala.milan@gmail.com>\n" |
15 | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | |
18 | msgid "Switch to" | |
19 | msgstr "" | |
20 | ||
21 | msgid "Channel" | |
22 | msgstr "" | |
23 | ||
24 | msgid "without" | |
25 | msgstr "" | |
26 | ||
27 | msgid "Teletext" | |
28 | msgstr "Teletext" | |
29 | ||
30 | msgid "live" | |
31 | msgstr "" | |
32 | ||
33 | msgid "Switch back to live" | |
34 | msgstr "" | |
35 | ||
36 | msgid "Tuner available" | |
37 | msgstr "" | |
38 | ||
39 | msgid "display current pages" | |
40 | msgstr "" | |
41 | ||
42 | msgid "Tuner busy" | |
43 | msgstr "" | |
44 | ||
45 | msgid "display cached pages" | |
46 | msgstr "" | |
47 | ||
48 | msgid "cached" | |
49 | msgstr "" | |
50 | ||
51 | msgid "Channel Tuning Successful" | |
52 | msgstr "" | |
53 | ||
54 | msgid "Channel Tuning Not Successful" | |
55 | msgstr "" | |
56 | ||
57 | msgid "No Free Tuner Found - Use Cache Only" | |
58 | msgstr "" | |
59 | ||
60 | msgid "*** Config mode is not supported in 24-line mode ***" | |
61 | msgstr "" | |
62 | ||
63 | msgid "Hotkey level change is not supported in 24-line mode" | |
64 | msgstr "" | |
65 | ||
66 | msgid "Hotkey levels are disabled" | |
67 | msgstr "" | |
68 | ||
69 | msgid "Hotkey levels are not active" | |
70 | msgstr "" | |
71 | ||
72 | msgid "OSD presets are disabled" | |
73 | msgstr "" | |
74 | ||
75 | msgid "OSD presets are not active" | |
76 | msgstr "" | |
77 | ||
18 | 78 | msgid "Channel (press OK): " |
19 | 79 | msgstr "Kanál (stlačte OK): " |
20 | 80 | |
21 | 81 | msgid "Page" |
22 | 82 | msgstr "Strana" |
23 | 83 | |
84 | msgid "in cache" | |
85 | msgstr "" | |
86 | ||
24 | 87 | msgid "not found" |
25 | 88 | msgstr "nenájdená" |
26 | 89 | |
90 | msgid "please wait" | |
91 | msgstr "" | |
92 | ||
27 | 93 | msgid "Displays teletext on the OSD" |
28 | 94 | msgstr "Zobrazí teletext na OSD" |
29 | 95 | |
30 | msgid "Teletext" | |
31 | msgstr "Teletext" | |
32 | ||
33 | 96 | msgid "Zoom" |
34 | 97 | msgstr "Zväčšenie" |
35 | 98 | |
42 | 105 | msgid "Switch background" |
43 | 106 | msgstr "Prepnúť na pozadí" |
44 | 107 | |
108 | msgid "Config" | |
109 | msgstr "" | |
110 | ||
111 | msgid "24-LineMode" | |
112 | msgstr "" | |
113 | ||
114 | msgid "Answer" | |
115 | msgstr "" | |
116 | ||
117 | msgid "Pause" | |
118 | msgstr "" | |
119 | ||
120 | msgid "Hotkey Level+" | |
121 | msgstr "" | |
122 | ||
123 | msgid "Hotkey Level-" | |
124 | msgstr "" | |
125 | ||
126 | msgid "OSD Preset+" | |
127 | msgstr "" | |
128 | ||
129 | msgid "OSD Preset-" | |
130 | msgstr "" | |
131 | ||
45 | 132 | msgid "Jump to..." |
46 | 133 | msgstr "Skoč na..." |
47 | 134 | |
72 | 159 | msgid "Hebrew" |
73 | 160 | msgstr "" |
74 | 161 | |
162 | msgid "Hotkeys" | |
163 | msgstr "" | |
164 | ||
165 | msgid "No Hotkeys+Hints" | |
166 | msgstr "" | |
167 | ||
168 | msgid "Hotkeys+Hints" | |
169 | msgstr "" | |
170 | ||
171 | msgid "Hide mainmenu entry" | |
172 | msgstr "Schovať položku v hlavnom menu" | |
173 | ||
174 | msgid "Show clock" | |
175 | msgstr "Zobraziť hodiny" | |
176 | ||
177 | msgid "Auto-update pages" | |
178 | msgstr "Aktualizácia stránok" | |
179 | ||
180 | msgid "G0 code block" | |
181 | msgstr "" | |
182 | ||
183 | msgid "G2 code block" | |
184 | msgstr "" | |
185 | ||
186 | msgid "16-Color Mode" | |
187 | msgstr "" | |
188 | ||
189 | msgid "24-Line Mode" | |
190 | msgstr "" | |
191 | ||
192 | msgid "max" | |
193 | msgstr "" | |
194 | ||
195 | msgid "Presets" | |
196 | msgstr "" | |
197 | ||
198 | msgid "visible" | |
199 | msgstr "" | |
200 | ||
201 | msgid "OSD left (%)" | |
202 | msgstr "" | |
203 | ||
204 | msgid "OSD top (%)" | |
205 | msgstr "" | |
206 | ||
207 | msgid "OSD width (%)" | |
208 | msgstr "" | |
209 | ||
210 | msgid "OSD height (%)" | |
211 | msgstr "" | |
212 | ||
213 | msgid "OSD frame pixel" | |
214 | msgstr "" | |
215 | ||
216 | msgid "Text Font" | |
217 | msgstr "" | |
218 | ||
219 | msgid "Text Vertical Offset" | |
220 | msgstr "" | |
221 | ||
75 | 222 | msgid "Background transparency" |
76 | 223 | msgstr "Priesvitnosť pozadia" |
77 | 224 | |
78 | msgid "Show clock" | |
79 | msgstr "Zobraziť hodiny" | |
80 | ||
81 | msgid "Auto-update pages" | |
82 | msgstr "Aktualizácia stránok" | |
83 | ||
84 | msgid "OSD height" | |
85 | msgstr "OSD výška" | |
86 | ||
87 | msgid "OSD width" | |
88 | msgstr "OSD šírka" | |
89 | ||
90 | msgid "OSD horizontal align" | |
91 | msgstr "OSD vodorovné zarovnanie" | |
92 | ||
93 | msgid "OSD vertical align" | |
94 | msgstr "OSD zvyslé zarovnanie" | |
95 | ||
96 | msgid "Hide mainmenu entry" | |
97 | msgstr "Schovať položku v hlavnom menu" | |
98 | ||
99 | msgid "Text Font" | |
100 | msgstr "" | |
101 | ||
102 | msgid "G0 code block" | |
103 | msgstr "" | |
104 | ||
105 | msgid "G2 code block" | |
106 | msgstr "" | |
107 | ||
108 | 225 | msgid "Key bindings" |
109 | 226 | msgstr "Klávesové skratky" |
110 | 227 | |
228 | msgid "Levels" | |
229 | msgstr "" | |
230 | ||
231 | msgid "Level" | |
232 | msgstr "" | |
233 | ||
111 | 234 | msgid " Page number" |
112 | 235 | msgstr " Číslo strany" |
236 | ||
237 | msgid "Half Page" | |
238 | msgstr "" | |
239 | ||
240 | msgid "ChangeChan" | |
241 | msgstr "" | |
242 | ||
243 | msgid "SwitchBack" | |
244 | msgstr "" | |
245 | ||
246 | msgid "24LineMode" | |
247 | msgstr "" | |
248 | ||
249 | msgid "HkLevel+" | |
250 | msgstr "" | |
251 | ||
252 | msgid "HkLevel-" | |
253 | msgstr "" | |
254 | ||
255 | msgid "Preset+" | |
256 | msgstr "" | |
257 | ||
258 | msgid "Preset-" | |
259 | msgstr "" | |
260 | ||
261 | msgid "Left" | |
262 | msgstr "" | |
263 | ||
264 | msgid "Top" | |
265 | msgstr "" | |
266 | ||
267 | msgid "Width" | |
268 | msgstr "" | |
269 | ||
270 | msgid "Height" | |
271 | msgstr "" | |
272 | ||
273 | msgid "Frame" | |
274 | msgstr "" | |
275 | ||
276 | msgid "TxVoffset" | |
277 | msgstr "" | |
278 | ||
279 | msgid "BackTrans" | |
280 | msgstr "" | |
281 | ||
282 | #~ msgid "OSD height" | |
283 | #~ msgstr "OSD výška" | |
284 | ||
285 | #~ msgid "OSD width" | |
286 | #~ msgstr "OSD šírka" | |
287 | ||
288 | #~ msgid "OSD horizontal align" | |
289 | #~ msgstr "OSD vodorovné zarovnanie" | |
290 | ||
291 | #~ msgid "OSD vertical align" | |
292 | #~ msgstr "OSD zvyslé zarovnanie" |
6 | 6 | msgstr "" |
7 | 7 | "Project-Id-Version: VDR 1.5.7\n" |
8 | 8 | "Report-Msgid-Bugs-To: <see README>\n" |
9 | "POT-Creation-Date: 2018-01-31 22:27+0200\n" | |
9 | "POT-Creation-Date: 2021-12-09 07:58+0100\n" | |
10 | 10 | "PO-Revision-Date: 2009-05-25 20:33+0200\n" |
11 | 11 | "Last-Translator: Yarema P. aka Knedlyk <yupadmin@gmail.com>\n" |
12 | 12 | "Language-Team: Ukrainian <vdr@linuxtv.org>\n" |
15 | 15 | "Content-Type: text/plain; charset=utf-8\n" |
16 | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | 17 | |
18 | msgid "Switch to" | |
19 | msgstr "" | |
20 | ||
21 | msgid "Channel" | |
22 | msgstr "" | |
23 | ||
24 | msgid "without" | |
25 | msgstr "" | |
26 | ||
27 | msgid "Teletext" | |
28 | msgstr "Телетекст" | |
29 | ||
30 | msgid "live" | |
31 | msgstr "" | |
32 | ||
33 | msgid "Switch back to live" | |
34 | msgstr "" | |
35 | ||
36 | msgid "Tuner available" | |
37 | msgstr "" | |
38 | ||
39 | msgid "display current pages" | |
40 | msgstr "" | |
41 | ||
42 | msgid "Tuner busy" | |
43 | msgstr "" | |
44 | ||
45 | msgid "display cached pages" | |
46 | msgstr "" | |
47 | ||
48 | msgid "cached" | |
49 | msgstr "" | |
50 | ||
51 | msgid "Channel Tuning Successful" | |
52 | msgstr "" | |
53 | ||
54 | msgid "Channel Tuning Not Successful" | |
55 | msgstr "" | |
56 | ||
57 | msgid "No Free Tuner Found - Use Cache Only" | |
58 | msgstr "" | |
59 | ||
60 | msgid "*** Config mode is not supported in 24-line mode ***" | |
61 | msgstr "" | |
62 | ||
63 | msgid "Hotkey level change is not supported in 24-line mode" | |
64 | msgstr "" | |
65 | ||
66 | msgid "Hotkey levels are disabled" | |
67 | msgstr "" | |
68 | ||
69 | msgid "Hotkey levels are not active" | |
70 | msgstr "" | |
71 | ||
72 | msgid "OSD presets are disabled" | |
73 | msgstr "" | |
74 | ||
75 | msgid "OSD presets are not active" | |
76 | msgstr "" | |
77 | ||
18 | 78 | msgid "Channel (press OK): " |
19 | 79 | msgstr "Канал (натисніть ОК): " |
20 | 80 | |
21 | 81 | msgid "Page" |
22 | 82 | msgstr "Сторінка" |
23 | 83 | |
84 | msgid "in cache" | |
85 | msgstr "" | |
86 | ||
24 | 87 | msgid "not found" |
25 | 88 | msgstr "не знайдена" |
26 | 89 | |
90 | msgid "please wait" | |
91 | msgstr "" | |
92 | ||
27 | 93 | msgid "Displays teletext on the OSD" |
28 | 94 | msgstr "Показувати телетекст в меню" |
29 | 95 | |
30 | msgid "Teletext" | |
31 | msgstr "Телетекст" | |
32 | ||
33 | 96 | msgid "Zoom" |
34 | 97 | msgstr "Збільшити" |
35 | 98 | |
42 | 105 | msgid "Switch background" |
43 | 106 | msgstr "Переключити фон" |
44 | 107 | |
108 | msgid "Config" | |
109 | msgstr "" | |
110 | ||
111 | msgid "24-LineMode" | |
112 | msgstr "" | |
113 | ||
114 | msgid "Answer" | |
115 | msgstr "" | |
116 | ||
117 | msgid "Pause" | |
118 | msgstr "" | |
119 | ||
120 | msgid "Hotkey Level+" | |
121 | msgstr "" | |
122 | ||
123 | msgid "Hotkey Level-" | |
124 | msgstr "" | |
125 | ||
126 | msgid "OSD Preset+" | |
127 | msgstr "" | |
128 | ||
129 | msgid "OSD Preset-" | |
130 | msgstr "" | |
131 | ||
45 | 132 | msgid "Jump to..." |
46 | 133 | msgstr "Перейти до..." |
47 | 134 | |
72 | 159 | msgid "Hebrew" |
73 | 160 | msgstr "" |
74 | 161 | |
162 | msgid "Hotkeys" | |
163 | msgstr "" | |
164 | ||
165 | msgid "No Hotkeys+Hints" | |
166 | msgstr "" | |
167 | ||
168 | msgid "Hotkeys+Hints" | |
169 | msgstr "" | |
170 | ||
171 | msgid "Hide mainmenu entry" | |
172 | msgstr "" | |
173 | ||
174 | msgid "Show clock" | |
175 | msgstr "Показувати годинник" | |
176 | ||
177 | msgid "Auto-update pages" | |
178 | msgstr "Автооновлення сторінок" | |
179 | ||
180 | msgid "G0 code block" | |
181 | msgstr "" | |
182 | ||
183 | msgid "G2 code block" | |
184 | msgstr "" | |
185 | ||
186 | msgid "16-Color Mode" | |
187 | msgstr "" | |
188 | ||
189 | msgid "24-Line Mode" | |
190 | msgstr "" | |
191 | ||
192 | msgid "max" | |
193 | msgstr "" | |
194 | ||
195 | msgid "Presets" | |
196 | msgstr "" | |
197 | ||
198 | msgid "visible" | |
199 | msgstr "" | |
200 | ||
201 | msgid "OSD left (%)" | |
202 | msgstr "" | |
203 | ||
204 | msgid "OSD top (%)" | |
205 | msgstr "" | |
206 | ||
207 | msgid "OSD width (%)" | |
208 | msgstr "" | |
209 | ||
210 | msgid "OSD height (%)" | |
211 | msgstr "" | |
212 | ||
213 | msgid "OSD frame pixel" | |
214 | msgstr "" | |
215 | ||
216 | msgid "Text Font" | |
217 | msgstr "" | |
218 | ||
219 | msgid "Text Vertical Offset" | |
220 | msgstr "" | |
221 | ||
75 | 222 | msgid "Background transparency" |
76 | 223 | msgstr "Ступінь прозорості фону" |
77 | 224 | |
78 | msgid "Show clock" | |
79 | msgstr "Показувати годинник" | |
80 | ||
81 | msgid "Auto-update pages" | |
82 | msgstr "Автооновлення сторінок" | |
83 | ||
84 | msgid "OSD height" | |
85 | msgstr "Висота OSD" | |
86 | ||
87 | msgid "OSD width" | |
88 | msgstr "Ширина OSD" | |
89 | ||
90 | msgid "OSD horizontal align" | |
91 | msgstr "Горизонтальне положення OSD" | |
92 | ||
93 | msgid "OSD vertical align" | |
94 | msgstr "Вертикальне положення OSD" | |
95 | ||
96 | msgid "Hide mainmenu entry" | |
97 | msgstr "" | |
98 | ||
99 | msgid "Text Font" | |
100 | msgstr "" | |
101 | ||
102 | msgid "G0 code block" | |
103 | msgstr "" | |
104 | ||
105 | msgid "G2 code block" | |
106 | msgstr "" | |
107 | ||
108 | 225 | msgid "Key bindings" |
109 | 226 | msgstr "Призначення клавіш" |
110 | 227 | |
228 | msgid "Levels" | |
229 | msgstr "" | |
230 | ||
231 | msgid "Level" | |
232 | msgstr "" | |
233 | ||
111 | 234 | msgid " Page number" |
112 | 235 | msgstr " Номер сторінки" |
236 | ||
237 | msgid "Half Page" | |
238 | msgstr "" | |
239 | ||
240 | msgid "ChangeChan" | |
241 | msgstr "" | |
242 | ||
243 | msgid "SwitchBack" | |
244 | msgstr "" | |
245 | ||
246 | msgid "24LineMode" | |
247 | msgstr "" | |
248 | ||
249 | msgid "HkLevel+" | |
250 | msgstr "" | |
251 | ||
252 | msgid "HkLevel-" | |
253 | msgstr "" | |
254 | ||
255 | msgid "Preset+" | |
256 | msgstr "" | |
257 | ||
258 | msgid "Preset-" | |
259 | msgstr "" | |
260 | ||
261 | msgid "Left" | |
262 | msgstr "" | |
263 | ||
264 | msgid "Top" | |
265 | msgstr "" | |
266 | ||
267 | msgid "Width" | |
268 | msgstr "" | |
269 | ||
270 | msgid "Height" | |
271 | msgstr "" | |
272 | ||
273 | msgid "Frame" | |
274 | msgstr "" | |
275 | ||
276 | msgid "TxVoffset" | |
277 | msgstr "" | |
278 | ||
279 | msgid "BackTrans" | |
280 | msgstr "" | |
281 | ||
282 | #~ msgid "OSD height" | |
283 | #~ msgstr "Висота OSD" | |
284 | ||
285 | #~ msgid "OSD width" | |
286 | #~ msgstr "Ширина OSD" | |
287 | ||
288 | #~ msgid "OSD horizontal align" | |
289 | #~ msgstr "Горизонтальне положення OSD" | |
290 | ||
291 | #~ msgid "OSD vertical align" | |
292 | #~ msgstr "Вертикальне положення OSD" |
0 | /*************************************************************** -*- c++ -*- | |
1 | * Copyright (c) < 2021 by TODO * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
3 | * * | |
4 | * This program is free software; you can redistribute it and/or modify * | |
5 | * it under the terms of the GNU General Public License as published by * | |
6 | * the Free Software Foundation; either version 2 of the License, or * | |
7 | * (at your option) any later version. * | |
8 | * * | |
9 | ***************************************************************************/ | |
10 | ||
11 | #include "setup.h" | |
12 | ||
13 | const char *st_modesHotkey[] = | |
14 | { | |
15 | // 1:1 relation between st_modes[] in osdteletext.c + eTeletextAction in setup.h + st_modesHotkey in setup.c | |
16 | // maximum 10 chars used in line25 hotkey // | |
17 | trNOOP("Zoom"), | |
18 | trNOOP("Half Page"), | |
19 | trNOOP("ChangeChan"), | |
20 | trNOOP("SwitchBack"), | |
21 | //trNOOP("SuspendRecv"), | |
22 | trNOOP("Config"), | |
23 | trNOOP("24LineMode"), | |
24 | trNOOP("Answer"), | |
25 | trNOOP("Pause"), | |
26 | trNOOP("HkLevel+"), | |
27 | trNOOP("HkLevel-"), | |
28 | trNOOP("Preset+"), | |
29 | trNOOP("Preset-"), | |
30 | trNOOP("Jump to...") // has to stay always the last one | |
31 | }; | |
32 | ||
33 | const char *config_modes[] = | |
34 | { | |
35 | // maximum 9 chars, 10th is -/+ | |
36 | trNOOP("Left"), | |
37 | trNOOP("Top"), | |
38 | trNOOP("Width"), | |
39 | trNOOP("Height"), | |
40 | trNOOP("Frame"), | |
41 | trNOOP("Text Font"), | |
42 | trNOOP("TxVoffset"), | |
43 | trNOOP("BackTrans"), | |
44 | }; | |
45 | ||
46 | // vim: ts=3 sw=3 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) < 2021 by TODO * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * This program is free software; you can redistribute it and/or modify * |
3 | 5 | * it under the terms of the GNU General Public License as published by * |
10 | 12 | #ifndef __SETUP_H |
11 | 13 | #define __SETUP_H |
12 | 14 | |
15 | #include <vdr/config.h> | |
13 | 16 | |
14 | //There are two places to be kept in sync with these enums: | |
15 | //TeletextBrowser::TranslateKey and | |
16 | //the constants in cPluginTeletextosd::initTexts | |
17 | enum eTeletextAction { Zoom, HalfPage, SwitchChannel, | |
18 | DarkScreen, /*SuspendReceiving,*/ LastAction }; //and 100-899 => jump to page | |
17 | // max for setup | |
18 | #define HOTKEY_LEVEL_MAX_LIMIT 9 // maximum supported by SetupStore parser: 9, required minimum: 1 | |
19 | #define HOTKEY_LEVEL_MAX_LIMIT_STRING "9" // as string to be displayed in online help | |
20 | ||
21 | #define OSD_PRESET_MAX_LIMIT 9 // maximum supported by SetupStore parser: 9, required minimum: 1 | |
22 | #define OSD_PRESET_MAX_LIMIT_STRING "9" // as string to be displayed in online help | |
23 | ||
24 | // min/max for setup | |
25 | #define OSDleftPctMin 0 | |
26 | #define OSDleftPctMax 90 | |
27 | #define OSDtopPctMin 0 | |
28 | #define OSDtopPctMax 90 | |
29 | #define OSDwidthPctMin 10 | |
30 | #define OSDwidthPctMax 100 | |
31 | #define OSDheightPctMin 10 | |
32 | #define OSDheightPctMax 100 | |
33 | #define OSDframePixMin 0 | |
34 | #define OSDframePixMax 100 | |
35 | #define txtVoffsetMin -10 | |
36 | #define txtVoffsetMax +10 | |
37 | #define BackTransMin 0 | |
38 | #define BackTransMax 255 | |
39 | ||
40 | // There are two places to be kept in sync with these enums: | |
41 | // TeletextBrowser::TranslateKey and | |
42 | // 1:1 relation between st_modes[] in osdteletext.c + eTeletextAction in setup.h + st_modesHotkey in setup.c | |
43 | enum eTeletextAction { | |
44 | Zoom, | |
45 | HalfPage, | |
46 | SwitchChannel, | |
47 | DarkScreen, | |
48 | /*SuspendReceiving,*/ | |
49 | Config, | |
50 | LineMode24, | |
51 | ToggleConceal, | |
52 | TogglePause, | |
53 | HotkeyLevelPlus, | |
54 | HotkeyLevelMinus, | |
55 | OsdPresetPlus, | |
56 | OsdPresetMinus, | |
57 | LastAction // has to stay always as the last one (special flag for 'jump to pages') | |
58 | }; //and 100-899 => jump to page | |
59 | ||
60 | enum eTeletextActionConfig { | |
61 | Left, | |
62 | Top, | |
63 | Width, | |
64 | Height, | |
65 | Frame, | |
66 | Font, | |
67 | Voffset, | |
68 | BackTrans, | |
69 | LastActionConfig, // has to stay always the last one | |
70 | }; | |
71 | ||
72 | enum eTeletextActionValueType { | |
73 | Pct, | |
74 | Pix, | |
75 | Int, | |
76 | Str, | |
77 | None, | |
78 | }; | |
79 | ||
80 | ||
81 | // values stored in setup.c: | |
82 | extern const char *st_modesHotkey[]; | |
83 | extern const char *config_modes[]; | |
19 | 84 | |
20 | 85 | enum ActionKeys { |
21 | ActionKeyRed, | |
22 | ActionKeyGreen, | |
23 | ActionKeyYellow, | |
24 | ActionKeyBlue, | |
25 | ActionKeyPlay, | |
26 | ActionKeyStop, | |
27 | ActionKeyFastFwd, | |
28 | ActionKeyFastRew, | |
86 | // keep in sync: static const ActionKeyName st_actionKeyNames in osdteletext.c | |
87 | ActionKeyFastRew, | |
88 | ActionKeyFastFwd, | |
89 | ActionKeyStop, | |
90 | ActionKeyOk, | |
91 | ActionKeyPlay, | |
29 | 92 | |
30 | LastActionKey | |
93 | LastActionKey | |
94 | }; | |
95 | ||
96 | enum ActionHotkeys { | |
97 | // keep in sync: static const ActionKeyName st_actionHotkeyNames in osdteletext.c | |
98 | ActionHotkeyRed, | |
99 | ActionHotkeyGreen, | |
100 | ActionHotkeyYellow, | |
101 | ActionHotkeyBlue, | |
102 | ||
103 | LastActionHotkey | |
104 | }; | |
105 | ||
106 | enum HotkeyFlags { | |
107 | HotkeyNormal, | |
108 | HotkeyYellowValue, | |
109 | HotkeyGreenYellowValue | |
110 | }; | |
111 | ||
112 | enum HintsFlags { | |
113 | HintsKey, | |
114 | HintsValue | |
31 | 115 | }; |
32 | 116 | |
33 | 117 | //Default values are set in menu.c, setup menu, parsing and storing can be found in osdteletext.c |
34 | 118 | class TeletextSetup { |
35 | 119 | public: |
36 | 120 | TeletextSetup(); |
37 | int mapKeyToAction[10]; //4 color keys + kPlay, kPause etc. | |
38 | unsigned int configuredClrBackground; | |
121 | bool migrationFlag_2_2; | |
122 | int osdConfig[(int) eTeletextActionConfig::LastActionConfig][OSD_PRESET_MAX_LIMIT]; | |
123 | int mapKeyToAction[(int) ActionKeys::LastActionKey]; // see enum ActionKeys | |
124 | int mapHotkeyToAction[(int) ActionHotkeys::LastActionHotkey][HOTKEY_LEVEL_MAX_LIMIT]; // see enum ActionHotkeys and HotkeyLevelMax | |
125 | int configuredClrBackground; // legacy TODO remove >= 2.3.0 | |
39 | 126 | int showClock; |
40 | int suspendReceiving; | |
41 | 127 | int autoUpdatePage; |
42 | int OSDheight; | |
43 | int OSDwidth; | |
44 | int OSDHAlign; | |
45 | int OSDVAlign; | |
46 | int inactivityTimeout; | |
128 | int osdPresetMax; | |
129 | int hotkeyLevelMax; | |
47 | 130 | int HideMainMenu; |
48 | cString txtFontName; | |
49 | 131 | cStringList txtFontNames; |
50 | int txtFontIndex; | |
51 | 132 | int txtG0Block; |
52 | 133 | int txtG2Block; |
53 | const char *txtBlock[11]; | |
134 | const char *txtBlock[11]; // see osdteletext.c | |
135 | int colorMode4bpp; | |
136 | int lineMode24; | |
137 | const char *lineMode[3]; // see osdteletext.c | |
138 | ||
139 | // current value of osdPreset | |
140 | int osdPreset; | |
54 | 141 | }; |
142 | ||
143 | // shortcut to OSD config value of current preset | |
144 | #define TTSETUPPRESET(type) ttSetup.osdConfig[type][ttSetup.osdPreset] | |
145 | ||
146 | // shortcut to OSD config value of current preset converted to TCOLOR value incl. negate | |
147 | #define TTSETUPPRESET_TCOLOR(type) ((tColor) (((uint32_t) (255 - (ttSetup.osdConfig[type][ttSetup.osdPreset] & 0xff))) << 24)) | |
148 | ||
149 | // shortcut to OSD config value of current preset converted to font name | |
150 | #define TTSETUPPRESET_FONTNAME(type) ttSetup.txtFontNames[TTSETUPPRESET(type)] | |
151 | ||
152 | // Teletext display lines | |
153 | // ttSetup.lineMode24 == 0: 25 | |
154 | // ttSetup.lineMode24 == 1: 24 | |
155 | // ttSetup.lineMode24 == 2: 27 | |
156 | #define TT_DISPLAY_LINES ((ttSetup.lineMode24 == 1) ? 24 : ((ttSetup.lineMode24 == 0) ? 25 : 27)) | |
157 | ||
55 | 158 | |
56 | 159 | extern TeletextSetup ttSetup; |
57 | 160 | |
58 | 161 | #endif |
162 | ||
163 | // vim: ts=3 sw=3 et |
13 | 13 | DIR *top=opendir(root); |
14 | 14 | int pagesDeleted=0; |
15 | 15 | if (top) { |
16 | struct dirent *chandir, path; | |
16 | struct dirent *chandir; | |
17 | 17 | struct stat chandirstat; |
18 | 18 | char fullPath[PATH_MAX]; |
19 | while ( (!readdir_r(top, &path, &chandir) && chandir != NULL) ) { | |
19 | while ((chandir = readdir(top)) != NULL) { | |
20 | 20 | if (strcmp(chandir->d_name, "..")==0 || strcmp(chandir->d_name, ".")==0) |
21 | 21 | continue; |
22 | 22 | snprintf(fullPath, PATH_MAX, "%s/%s", root, chandir->d_name); |
28 | 28 | } |
29 | 29 | closedir(top); |
30 | 30 | } else { |
31 | esyslog("OSD-Teletext: Error opening teletext storage directory \"%s\": %s", root, strerror(errno)); | |
31 | esyslog("osdteletext: Error opening teletext storage directory \"%s\": %s", root, strerror(errno)); | |
32 | 32 | } |
33 | 33 | return pagesDeleted; |
34 | 34 | } |
39 | 39 | bool hadError=false; |
40 | 40 | int bytesDeleted=0; |
41 | 41 | if (d) { |
42 | struct dirent *txtfile, path; | |
42 | struct dirent *txtfile; | |
43 | 43 | struct stat txtfilestat; |
44 | 44 | char fullPath[PATH_MAX]; |
45 | 45 | int filesize; |
46 | while ( (!readdir_r(d, &path, &txtfile) && txtfile != NULL) ) { | |
46 | while ((txtfile = readdir(d)) != NULL) { | |
47 | 47 | int len=strlen(txtfile->d_name); |
48 | //check that the file end with .vtx to avoid accidents and disasters | |
49 | if (strcmp(txtfile->d_name+len-4, ".vtx")==0) { | |
48 | //check that the file end with .vtx5 to avoid accidents and disasters | |
49 | if (strcmp(txtfile->d_name+len-5, ".vtx5")==0) { | |
50 | 50 | snprintf(fullPath, PATH_MAX, "%s/%s", dir, txtfile->d_name); |
51 | 51 | stat(fullPath, &txtfilestat); |
52 | 52 | filesize=actualFileSize(txtfilestat.st_size); |
61 | 61 | rmdir(dir); |
62 | 62 | } else { |
63 | 63 | if (!reportedError) { |
64 | esyslog("OSD-Teletext: Error opening teletext storage subdirectory \"%s\": %s", dir, strerror(errno)); | |
64 | esyslog("osdteletext: Error opening teletext storage subdirectory \"%s\": %s", dir, strerror(errno)); | |
65 | 65 | reportedError=true; |
66 | 66 | } |
67 | 67 | } |
68 | 68 | |
69 | 69 | if (hadError && !reportedError) { |
70 | esyslog("OSD-Teletext: Error removing teletext storage subdirectory \"%s\": %s", dir, strerror(hadError)); | |
70 | esyslog("osdteletext: Error removing teletext storage subdirectory \"%s\": %s", dir, strerror(hadError)); | |
71 | 71 | reportedError=true; |
72 | 72 | } |
73 | 73 | return bytesDeleted; |
94 | 94 | DIR *top=opendir(getRootDir()); |
95 | 95 | if (top) { |
96 | 96 | int haveDir=0; |
97 | struct dirent *chandir, path; | |
97 | struct dirent *chandir; | |
98 | 98 | struct stat chandirstat; |
99 | while ( (!readdir_r(top, &path, &chandir) && chandir != NULL) ) { | |
99 | while ((chandir = readdir(top)) != NULL) { | |
100 | 100 | if (strcmp(chandir->d_name, "..")==0 || strcmp(chandir->d_name, ".")==0) |
101 | 101 | continue; |
102 | 102 | snprintf(fullPath, PATH_MAX, "%s/%s", getRootDir(), chandir->d_name); |
126 | 126 | } |
127 | 127 | |
128 | 128 | void Storage::getFilename(char *buffer, int bufLength, PageID page) { |
129 | snprintf(buffer, bufLength, "%s/%s/%03x_%02x.vtx", getRootDir(), | |
129 | snprintf(buffer, bufLength, "%s/%s/%03x_%02x.vtx5", getRootDir(), | |
130 | 130 | *page.channel.ToString(), page.page, page.subPage); |
131 | 131 | } |
132 | 132 | |
133 | 133 | void Storage::prepareDirectory(tChannelID chan) { |
134 | 134 | currentDir = cString::sprintf("%s/%s", root, *chan.ToString()); |
135 | 135 | if (!MakeDirs(currentDir, 1)) { |
136 | esyslog("OSD-Teletext: Error preparing directory for channel \"%s\"", | |
136 | esyslog("osdteletext: Error preparing directory for channel \"%s\"", | |
137 | 137 | *chan.ToString()); |
138 | 138 | return; |
139 | 139 | } |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | 1 | * Copyright (c) 2003,2004 by Marcel Wiesweg * |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
2 | 3 | * * |
3 | 4 | * This program is free software; you can redistribute it and/or modify * |
4 | 5 | * it under the terms of the GNU General Public License as published by * |
13 | 14 | #include "rootdir.h" |
14 | 15 | #include "pageid.h" |
15 | 16 | |
16 | #define TELETEXT_PAGESIZE 972 | |
17 | #define TELETEXT_PAGESIZE sizeof(TelePageData) | |
17 | 18 | |
18 | 19 | struct StorageHandle { |
19 | 20 | public: |
26 | 27 | operator int() const { return handle; } |
27 | 28 | private: |
28 | 29 | int handle; |
30 | }; | |
31 | ||
32 | struct TelePageData { | |
33 | unsigned char pageheader[12]; // 12 chars (extracted from 8 chars of line X/0) | |
34 | unsigned char pagebuf[25*40]; // 25 lines with 40 chars X/0-24 | |
35 | unsigned char pagebuf_X25[40]; // 1 line with 40 chars (since 2.0.0 / VTX5) | |
36 | unsigned char pagebuf_X26[16*40]; // max 16 lines with 40 chars (since 2.0.0 / VTX5) | |
37 | unsigned char pagebuf_X27[16*40]; // max 16 lines with 40 chars (since 2.0.0 / VTX5) | |
38 | unsigned char pagebuf_X28[16*40]; // max 16 lines with 40 chars (since 2.0.0 / VTX5) | |
39 | unsigned char pagebuf_M29[16*40]; // max 16 lines with 40 chars (since 2.0.0 / VTX5) | |
29 | 40 | }; |
30 | 41 | |
31 | 42 | enum StorageSystem { StorageSystemLegacy, StorageSystemPacked }; |
0 | // -*- c++ -*- | |
0 | /*************************************************************** -*- c++ -*- | |
1 | * Copyright (c) < 2021 by TODO * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
3 | * * | |
4 | * This program is free software; you can redistribute it and/or modify * | |
5 | * it under the terms of the GNU General Public License as published by * | |
6 | * the Free Software Foundation; either version 2 of the License, or * | |
7 | * (at your option) any later version. * | |
8 | * * | |
9 | ***************************************************************************/ | |
1 | 10 | |
2 | 11 | #include "txtfont.h" |
3 | 12 | |
6575 | 6584 | }; |
6576 | 6585 | |
6577 | 6586 | |
6578 | #if 0 | |
6579 | 6587 | int NationalOptionSubsetG0Default[13]= |
6580 | {0x23,0x94,0x80,0 ,0 ,0 ,0x5e,0x5f,0 ,0 ,0 ,0 ,0 }; | |
6588 | {0x23,0xa4,0x40,0 ,0 ,0 ,0x5e,0x5f,0 ,0 ,0 ,0 ,0 }; | |
6581 | 6589 | |
6582 | 6590 | int NationalOptionSubsetCZ_SK[13]= |
6583 | 6591 | {0x23,0x84,0x85,0x95,0x93,0x92,0xed,0x87,0x91,0xeb,0x8f,0xef,0x86}; |
6592 | ||
6584 | 6593 | int NationalOptionSubsetEN[13]= |
6585 | 6594 | {0x83,0x24,0x80,0x8b,0x8c,0x8d,0x8e,0x23,0x81,0x82,0x88,0x89,0x8a}; |
6595 | ||
6586 | 6596 | int NationalOptionSubsetEE[13]= |
6587 | 6597 | {0x23,0xc6,0 ,0x5b,0x5c,0 ,0x5d,0xd6,0 ,0x7b,0x7c,0 ,0x7d}; |
6598 | ||
6588 | 6599 | int NationalOptionSubsetFR[13]= |
6589 | {0xd3,0xd4,0xd0,0xdb,0xdc,0xc1,0xde,0x23,0xd1,0xd2,0xd8,0xd9,0xcc}; | |
6600 | {0xe9,0xef,0xe0,0xeb,0xea,0xf9,0xee,0x23,0xe8,0xe2,0xf4,0xfb,0xe7}; | |
6601 | ||
6590 | 6602 | int NationalOptionSubsetDE[13]= |
6591 | {0x23,0x24,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x7b,0x7c,0x7d,0x7e}; | |
6603 | {0x23,0x24,0xa7,0xc4,0xd6,0xdc,0x5e,0x5f,0xb0,0xe4,0xf6,0xfc,0xdf}; | |
6604 | ||
6592 | 6605 | int NationalOptionSubsetIT[13]= |
6593 | {0x83,0x24,0xd3,0x60,0xcc,0x8d,0x8e,0x23,0xdd,0xc1,0xc8,0xc9,0xca}; | |
6606 | {0xa3,0x24,0xe9,0xb0,0xe7,0x8d,0x8e,0x23,0xf9,0xe0,0xf2,0xe8,0xec}; // no arrows as max char is 0xff | |
6607 | ||
6594 | 6608 | int NationalOptionSubsetLV_LT[13]= |
6595 | 6609 | {0x23,0x24,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 }; |
6610 | ||
6596 | 6611 | int NationalOptionSubsetPL[13]= |
6597 | 6612 | {0x23,0 ,0 ,0 ,0 ,0 ,0 ,0xee,0 ,0 ,0 ,0 ,0 }; |
6613 | ||
6598 | 6614 | int NationalOptionSubsetPT_ES[13]= |
6599 | {0xcc,0x24,0xe0,0xeb,0xec,0xed,0xee,0xef,0xe1,0x7d,0xe8,0xc9,0xc2}; | |
6615 | {0x23,0x24,0xa1,0xe1,0xe9,0xed,0xf3,0xfa,0xbf,0xfc,0xf1,0xe8,0xe0}; | |
6616 | ||
6600 | 6617 | int NationalOptionSubsetRO[13]= |
6601 | 6618 | {0x23,0x94,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0xd2,0 ,0 ,0xde}; |
6619 | ||
6602 | 6620 | int NationalOptionSubsetSR_HR_SL[13]= |
6603 | 6621 | {0x23,0 ,0 ,0 ,0 ,0xfb,0 ,0xdb,0 ,0 ,0 ,0 ,0 }; |
6622 | ||
6604 | 6623 | int NationalOptionSubsetSV_FI[13]= |
6605 | {0x23,0x94,0x90,0x5b,0x5c,0x9d,0x5d,0x5f,0x91,0x7b,0x7c,0x99,0x7d}; | |
6624 | {0x23,0xa4,0xc9,0xc4,0xd6,0xc5,0xdc,0x5f,0xe9,0xe4,0xf6,0xe5,0xfc}; | |
6625 | ||
6606 | 6626 | int NationalOptionSubsetTR[13]= |
6607 | 6627 | {0 ,0 ,0 ,0 ,0x5c,0xd7,0x5d,0 ,0 ,0 ,0x7c,0xcc,0x7d}; |
6608 | #else | |
6609 | int NationalOptionSubsetG0Default[13]= | |
6610 | {0x23,0xa4,0x40,0 ,0 ,0 ,0x5e,0x5f,0 ,0 ,0 ,0 ,0 }; | |
6611 | ||
6612 | int NationalOptionSubsetCZ_SK[13]= | |
6613 | {0x23,0x84,0x85,0x95,0x93,0x92,0xed,0x87,0x91,0xeb,0x8f,0xef,0x86}; | |
6614 | int NationalOptionSubsetEN[13]= | |
6615 | {0x83,0x24,0x80,0x8b,0x8c,0x8d,0x8e,0x23,0x81,0x82,0x88,0x89,0x8a}; | |
6616 | int NationalOptionSubsetEE[13]= | |
6617 | {0x23,0xc6,0 ,0x5b,0x5c,0 ,0x5d,0xd6,0 ,0x7b,0x7c,0 ,0x7d}; | |
6618 | int NationalOptionSubsetFR[13]= | |
6619 | {0xd3,0xd4,0xd0,0xdb,0xdc,0xc1,0xde,0x23,0xd1,0xd2,0xd8,0xd9,0xcc}; | |
6620 | int NationalOptionSubsetDE[13]= | |
6621 | {0x23,0x24,0xa7,0xc4,0xd6,0xdc,0x5e,0x5f,0x60,0xe4,0xf6,0xfc,0xdf}; | |
6622 | int NationalOptionSubsetIT[13]= | |
6623 | {0x83,0x24,0xd3,0x60,0xcc,0x8d,0x8e,0x23,0xdd,0xc1,0xc8,0xc9,0xca}; | |
6624 | int NationalOptionSubsetLV_LT[13]= | |
6625 | {0x23,0x24,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 }; | |
6626 | int NationalOptionSubsetPL[13]= | |
6627 | {0x23,0 ,0 ,0 ,0 ,0 ,0 ,0xee,0 ,0 ,0 ,0 ,0 }; | |
6628 | int NationalOptionSubsetPT_ES[13]= | |
6629 | {0xcc,0x24,0xe0,0xeb,0xec,0xed,0xee,0xef,0xe1,0x7d,0xe8,0xc9,0xc2}; | |
6630 | int NationalOptionSubsetRO[13]= | |
6631 | {0x23,0x94,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0xd2,0 ,0 ,0xde}; | |
6632 | int NationalOptionSubsetSR_HR_SL[13]= | |
6633 | {0x23,0 ,0 ,0 ,0 ,0xfb,0 ,0xdb,0 ,0 ,0 ,0 ,0 }; | |
6634 | int NationalOptionSubsetSV_FI[13]= | |
6635 | {0x23,0xa4,0xc9,0xc4,0xd6,0xc5,0xdc,0x5f,0xe9,0xe4,0xf6,0xe5,0xfc}; | |
6636 | int NationalOptionSubsetTR[13]= | |
6637 | {0 ,0 ,0 ,0 ,0x5c,0xd7,0x5d,0 ,0 ,0 ,0x7c,0xcc,0x7d}; | |
6638 | #endif | |
6639 | 6628 | |
6640 | 6629 | int CyrillicOptionRU_BG[96] = |
6641 | 6630 | {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x44b,0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, |
6901 | 6890 | } |
6902 | 6891 | |
6903 | 6892 | unsigned int GetVTXChar(cTeletextChar c) { |
6904 | // convert character for character/charset to utf8 | |
6893 | // convert character for character/charset to utf8 | |
6905 | 6894 | int convertedChar = 0; |
6906 | 6895 | enumCharsets font = c.GetCharset(); |
6907 | 6896 | int chr = c.GetChar(); |
6914 | 6903 | convertedChar = NationalOptionSubsetG0Default[NationalOption]; |
6915 | 6904 | } else { |
6916 | 6905 | if (chr>=0x20 && chr<0x80) { |
6906 | convertedChar = chr; | |
6907 | } | |
6908 | if (chr>=0xa0 && chr<0xff) { | |
6909 | // pass ISO-8859-1 converted from "X/26 G0 character with diacritical mark" | |
6917 | 6910 | convertedChar = chr; |
6918 | 6911 | } |
6919 | 6912 | } |
7035 | 7028 | } |
7036 | 7029 | return convertedChar; |
7037 | 7030 | } |
7031 | ||
7032 | ||
7033 | /* X/26 "G0 character with diacritical mark" mapping */ | |
7034 | // extract from G2 column 4: | |
7035 | // 0: no modification | |
7036 | // 1: GRAVE (GRAVIS) | |
7037 | // 2: ACUTE (AKUT) | |
7038 | // 3: CIRCUMFLEX (ZIRKUMFLEX) | |
7039 | // 4: TILDE (TILDE) | |
7040 | // 8: DIAERESIS (TREMA) | |
7041 | // A: RING ABOVE (RING DARÜBER) | |
7042 | // B: CEDILLA (CEDILLE) | |
7043 | uint8_t X26_G0_CharWithDiacritcalMarkMapping(uint8_t c, uint8_t mark) { | |
7044 | uint8_t m = c; // default unmodified char | |
7045 | ||
7046 | switch(c) { | |
7047 | case 0x41: // A 0xc0...0xc5 | |
7048 | case 0x61: // a 0xe0...0xe5 | |
7049 | switch(mark) { | |
7050 | case 0x1: m = 0xc0 + c - 0x41; break; // GRAVE | |
7051 | case 0x2: m = 0xc1 + c - 0x41; break; // ACUTE | |
7052 | case 0x3: m = 0xc2 + c - 0x41; break; // CIRCUMFLEX | |
7053 | case 0x4: m = 0xc3 + c - 0x41; break; // TILDE | |
7054 | case 0x8: m = 0xc4 + c - 0x41; break; // DIAERESIS | |
7055 | case 0xa: m = 0xc5 + c - 0x41; break; // RING ABOVE | |
7056 | }; | |
7057 | break; | |
7058 | ||
7059 | // UNSUPPORTED "AE" 0xc6 0xe6 | |
7060 | ||
7061 | case 0x43: // C 0xc7 | |
7062 | case 0x63: // c 0xe7 | |
7063 | switch(mark) { | |
7064 | case 0xb: m = 0xc7 + c - 0x43; break; // CEDILLA | |
7065 | }; | |
7066 | break; | |
7067 | ||
7068 | case 0x45: // E 0xc8...0xcb | |
7069 | case 0x65: // e 0xe8...0xeb | |
7070 | switch(mark) { | |
7071 | case 0x1: m = 0xc8 + c - 0x45; break; // GRAVE | |
7072 | case 0x2: m = 0xc9 + c - 0x45; break; // ACUTE | |
7073 | case 0x3: m = 0xca + c - 0x45; break; // CIRCUMFLEX | |
7074 | case 0x8: m = 0xcb + c - 0x45; break; // DIAERESIS | |
7075 | }; | |
7076 | break; | |
7077 | ||
7078 | case 0x49: // I 0xcc...0xcf | |
7079 | case 0x69: // i 0xec...0xef | |
7080 | switch(mark) { | |
7081 | case 0x1: m = 0xcc + c - 0x49; break; // GRAVE | |
7082 | case 0x2: m = 0xcd + c - 0x49; break; // ACUTE | |
7083 | case 0x3: m = 0xce + c - 0x49; break; // CIRCUMFLEX | |
7084 | case 0x8: m = 0xcf + c - 0x49; break; // DIAERESIS | |
7085 | }; | |
7086 | break; | |
7087 | ||
7088 | // UNSUPPORTED "ETH" 0xd0 0xf0 | |
7089 | ||
7090 | case 0x4e: // N 0xd1 | |
7091 | case 0x6e: // n 0xf1 | |
7092 | switch(mark) { | |
7093 | case 0x4: m = 0xd1 + c - 0x4e; break; // TILDE | |
7094 | }; | |
7095 | break; | |
7096 | ||
7097 | case 0x4f: // O 0xd2...0xd6 | |
7098 | case 0x6f: // o 0xf2...0xf6 | |
7099 | switch(mark) { | |
7100 | case 0x1: m = 0xd2 + c - 0x4f; break; // GRAVE | |
7101 | case 0x2: m = 0xd3 + c - 0x4f; break; // ACUTE | |
7102 | case 0x3: m = 0xd4 + c - 0x4f; break; // CIRCUMFLEX | |
7103 | case 0x4: m = 0xd5 + c - 0x4f; break; // TILDE | |
7104 | case 0x8: m = 0xd6 + c - 0x4f; break; // DIAERESIS | |
7105 | }; | |
7106 | break; | |
7107 | ||
7108 | // UNSUPPORTED "MULTIPLICATION SIGN" 0xd7 | |
7109 | // UNSUPPORTED "DIVISION SIGN" 0xf7 | |
7110 | // UNSUPPORTED "O WITH STROKE" 0xd8 0xf8 | |
7111 | ||
7112 | case 0x55: // U 0xd9...0xdc | |
7113 | case 0x75: // u 0xf9...0xfc | |
7114 | switch(mark) { | |
7115 | case 0x1: m = 0xd9 + c - 0x55; break; // GRAVE | |
7116 | case 0x2: m = 0xda + c - 0x55; break; // ACUTE | |
7117 | case 0x3: m = 0xdb + c - 0x55; break; // CIRCUMFLEX | |
7118 | case 0x8: m = 0xdc + c - 0x55; break; // DIAERESIS | |
7119 | }; | |
7120 | break; | |
7121 | ||
7122 | case 0x59: // Y 0xdd | |
7123 | case 0x79: // y 0xfd | |
7124 | switch(mark) { | |
7125 | case 0x2: m = 0xdd + c - 0x59; break; // ACUTE | |
7126 | }; | |
7127 | break; | |
7128 | ||
7129 | // UNSUPPORTED "SHARP S" 0xdf | |
7130 | // UNSUPPORTED "THRON" 0xff | |
7131 | default: | |
7132 | break; | |
7133 | }; | |
7134 | ||
7135 | return m; | |
7136 | }; | |
7137 | ||
7138 | // vim: ts=4 sw=4 et |
0 | // -*- c++ -*- | |
0 | /*************************************************************** -*- c++ -*- | |
1 | * Copyright (c) < 2021 by TODO * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
3 | * * | |
4 | * This program is free software; you can redistribute it and/or modify * | |
5 | * it under the terms of the GNU General Public License as published by * | |
6 | * the Free Software Foundation; either version 2 of the License, or * | |
7 | * (at your option) any later version. * | |
8 | * * | |
9 | ***************************************************************************/ | |
1 | 10 | |
2 | 11 | #ifndef __TXTFONT_H |
3 | 12 | #define __TXTFONT_H |
4 | 13 | |
5 | 14 | #include "txtrender.h" |
6 | 15 | |
16 | unsigned int* GetFontChar(cTeletextChar c, unsigned int *buffer); | |
17 | ||
7 | 18 | unsigned int GetVTXChar(cTeletextChar c); |
8 | 19 | |
20 | uint8_t X26_G0_CharWithDiacritcalMarkMapping(uint8_t c, uint8_t mark); | |
21 | ||
9 | 22 | #endif |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | 1 | * Copyright (c) 2003,2004 by Marcel Wiesweg * |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
2 | 3 | * * |
3 | 4 | * This program is free software; you can redistribute it and/or modify * |
4 | 5 | * it under the terms of the GNU General Public License as published by * |
13 | 14 | #include "tables.h" |
14 | 15 | #include "setup.h" |
15 | 16 | #include "menu.h" |
17 | #include "logging.h" | |
16 | 18 | |
17 | 19 | #include <vdr/channels.h> |
18 | 20 | #include <vdr/device.h> |
29 | 31 | cTelePage::cTelePage(PageID t_page, uchar t_flags, uchar t_lang,int t_mag, Storage *s) |
30 | 32 | : mag(t_mag), flags(t_flags), lang(t_lang), page(t_page), storage(s) |
31 | 33 | { |
32 | memset(pagebuf,' ',26*40); | |
34 | memset(pagedata.pagebuf ,' ',25 * 40); // clear X/0-24 buffer with spaces | |
35 | memset(pagedata.pagebuf_X25, 0, 1 * 40); // clear X25 buffer | |
36 | memset(pagedata.pagebuf_X26, 0, 16 * 40); // clear X26 buffer | |
37 | memset(pagedata.pagebuf_X27, 0, 16 * 40); // clear X27 buffer | |
38 | memset(pagedata.pagebuf_X28, 0, 16 * 40); // clear X28 buffer | |
39 | memset(pagedata.pagebuf_M29, 0, 16 * 40); // clear M29 buffer | |
33 | 40 | } |
34 | 41 | |
35 | 42 | cTelePage::~cTelePage() { |
36 | 43 | } |
37 | 44 | |
38 | void cTelePage::SetLine(int line, uchar *myptr) | |
39 | { | |
40 | memcpy(pagebuf+40*line,myptr,40); | |
45 | ||
46 | void cTelePage::SetLine(const int line, uchar *myptr, const char *debugPrefix) | |
47 | { | |
48 | unsigned char *buf = NULL; | |
49 | int dc = 0; | |
50 | ||
51 | if (strlen(debugPrefix) > 0) { | |
52 | printf("DEBUG: %s#%02d <:", debugPrefix, line); | |
53 | for (int i = 0; i < 40; i++) { | |
54 | printf(" %02x", myptr[i]); | |
55 | }; | |
56 | printf("\n"); | |
57 | }; | |
58 | ||
59 | switch(line) { | |
60 | case 0: | |
61 | // VTX header | |
62 | buf = pagedata.pagebuf; | |
63 | memcpy(buf, myptr, 8); // copy first 8 bytes raw | |
64 | // copy 32 VTX | |
65 | for (int i = 8; i < 40; i++) { | |
66 | buf[i] = myptr[i] & 0x7f; // clear of parity bit | |
67 | }; | |
68 | break; | |
69 | ||
70 | case 1 ... 24: | |
71 | // standard VTX, clear parity bit | |
72 | buf = pagedata.pagebuf + 40 * line; | |
73 | for (int i = 0; i < 40; i++) { | |
74 | buf[i] = myptr[i] & 0x7f; // clear of parity bit | |
75 | }; | |
76 | break; | |
77 | ||
78 | case 25: | |
79 | buf = pagedata.pagebuf_X25; | |
80 | for (int i = 0; i < 40; i++) { | |
81 | buf[i] = myptr[i] & 0x7f; // clear of parity bit | |
82 | }; | |
83 | break; | |
84 | ||
85 | case 26: | |
86 | buf = pagedata.pagebuf_X26; | |
87 | // further handling below | |
88 | break; | |
89 | ||
90 | case 27: | |
91 | buf = pagedata.pagebuf_X27; | |
92 | // further handling below | |
93 | break; | |
94 | ||
95 | case 28: | |
96 | buf = pagedata.pagebuf_X28; | |
97 | // further handling below | |
98 | break; | |
99 | ||
100 | case 29: | |
101 | buf = pagedata.pagebuf_M29; | |
102 | // further handling below | |
103 | break; | |
104 | ||
105 | default: | |
106 | // esyslog("osdteletext: cTelePage::SetLine called with unsupported line=%d (code issue)\n", line); | |
107 | break; | |
108 | }; | |
109 | ||
110 | switch(line) { | |
111 | case 26 ... 29: | |
112 | // line 26-29 contain DesignationCode | |
113 | dc = unhamtab[myptr[0]] & 0x0f; | |
114 | buf += dc * 40; // shift buffer start to DesignationCode row | |
115 | buf[0] = dc | 0x80; // store unhammed DesignationCode | 0x80 (shows "used") | |
116 | break; | |
117 | }; | |
118 | ||
119 | switch(line) { | |
120 | case 26: | |
121 | case 28: | |
122 | case 29: | |
123 | // unhamming 24/18 triplet | |
124 | for (int triplet = 0; triplet < 13; triplet++) { | |
125 | switch(line) { | |
126 | case 26: | |
127 | // ETSI 8.3 unhamming 24/18 | |
128 | // 1 2 3 4 5 6 7 8 | 9 10 11 12 13 14 15 16 | 17 18 19 20 21 22 23 24 | |
129 | // P1 P2 D1 P3 D2 D3 D4 P4 | D5 D6 D7 D8 D9 D10 D11 P5 | D12 D13 D14 D15 D16 D17 D18 P6 | |
130 | // ETSI 12.3.1 X/26 address / mode / data | |
131 | // A0 A1 A2 A3 | A4 A5 M0 M1 M2 M3 M4 | D0 D1 D2 D3 D4 D5 D6 | |
132 | buf[triplet*3 + 1] = ((myptr[triplet*3 + 1] & 0x04) >> 2) // A0 mask 3 and shift to 1 | |
133 | | ((myptr[triplet*3 + 1] & 0x70) >> 3) // A1-3 mask 5-7 and shift to 2-4 | |
134 | | ((myptr[triplet*3 + 2] & 0x03) << 4); // A4-5 mask 1-2 (9-10) and shift to 5-6 | |
135 | buf[triplet*3 + 2] = ((myptr[triplet*3 + 2] & 0x7c) >> 2); // M0-4 mask 3-7 (11-15) and shift to 1-5 | |
136 | buf[triplet*3 + 3] = ((myptr[triplet*3 + 3] & 0x7f) ); // D0-6 mask 1-7 and nothing to shift | |
137 | #if 0 | |
138 | if (strlen(debugPrefix) > 0) | |
139 | printf("DEBUG: %s#%02d T: t=%d i1=%02x i2=%02x i3=%02x -> o1=%02x o2=%02x o3=%02x\n", debugPrefix, line, triplet | |
140 | , myptr[1 + triplet*3], myptr[2 + triplet*3], myptr[3 + triplet*3] | |
141 | , buf[triplet*3 + 1], buf[triplet*3 + 2], buf[triplet*3 + 3] | |
142 | ); | |
143 | #endif | |
144 | break; | |
145 | ||
146 | case 28: | |
147 | // TODO implement | |
148 | break; | |
149 | case 29: | |
150 | // TODO implement | |
151 | break; | |
152 | }; | |
153 | }; | |
154 | break; | |
155 | ||
156 | case 27: | |
157 | // line 27 contain only a 16-bit CRC at the end | |
158 | memcpy(buf + 40 * dc + 1, myptr + 1, 39); // store byte 2-40 | |
159 | break; | |
160 | ||
161 | default: | |
162 | // no storage | |
163 | break; | |
164 | }; | |
165 | ||
166 | if (strlen(debugPrefix) > 0) { | |
167 | if (buf != NULL) { | |
168 | printf("DEBUG: %s#%02d >:", debugPrefix, line); | |
169 | for (int i = 0; i < 40; i++) { | |
170 | printf(" %02x", buf[i]); | |
171 | }; | |
172 | printf("\n"); | |
173 | } else { | |
174 | printf("DEBUG: %s#%02d >: NOT-SELECTED-TO-STORE\n", debugPrefix, line); | |
175 | }; | |
176 | }; | |
41 | 177 | } |
42 | 178 | |
43 | 179 | void cTelePage::save() |
45 | 181 | unsigned char buf; |
46 | 182 | StorageHandle fd; |
47 | 183 | if ( (fd=storage->openForWriting(page)) ) { |
48 | storage->write("VTXV4",5,fd); | |
49 | buf=0x01; storage->write(&buf,1,fd); | |
50 | buf=mag; storage->write(&buf,1,fd); | |
51 | buf=page.page; storage->write(&buf,1,fd); | |
52 | buf=flags; storage->write(&buf,1,fd); | |
53 | buf=lang; storage->write(&buf,1,fd); | |
54 | buf=0x00; storage->write(&buf,1,fd); | |
55 | buf=0x00; storage->write(&buf,1,fd); | |
56 | storage->write(pagebuf,24*40,fd); | |
184 | // page header (12) | |
185 | memcpy(pagedata.pageheader, "VTXV5", 5); // prefix (5) "VTXV4" < 2.0.0 | |
186 | buf=0x01; pagedata.pageheader[5] = buf; // fixed 0x01 (1) | |
187 | buf=mag; pagedata.pageheader[6] = buf; // mag (1) | |
188 | buf=page.page; pagedata.pageheader[7] = buf; // page (1) | |
189 | buf=flags; pagedata.pageheader[8] = buf; // flags (1) | |
190 | buf=lang; pagedata.pageheader[9] = buf; // lang (1) | |
191 | buf=0x00; pagedata.pageheader[10] = buf; // fixed 0x00 (1) | |
192 | buf=0x00; pagedata.pageheader[11] = buf; // fixed 0x00 (1) | |
193 | storage->write(&pagedata, sizeof(TelePageData), fd); | |
57 | 194 | storage->close(fd); |
58 | 195 | } |
59 | 196 | } |
65 | 202 | |
66 | 203 | cTxtStatus::cTxtStatus(bool storeTopText, Storage* storage) |
67 | 204 | : receiver(NULL), storeTopText(storeTopText), storage(storage) |
205 | , NonLiveChannelNumber(0) | |
68 | 206 | { |
69 | 207 | } |
70 | 208 | |
75 | 213 | |
76 | 214 | void cTxtStatus::ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView) |
77 | 215 | { |
78 | // Disconnect receiver if channel is 0, will reconnect to new | |
79 | // receiver after channel change. | |
80 | if (LiveView && ChannelNumber == 0) | |
81 | DELETENULL(receiver); | |
82 | ||
83 | 216 | // ignore if channel is 0 |
84 | if (ChannelNumber == 0) return; | |
217 | if (ChannelNumber == 0) { | |
218 | if (LiveView && receiver) { | |
219 | if (receiver->Live()) { | |
220 | DEBUG_OT_TXTRCVC("STOPRC channel=0 switch on DVB %d for channel %d LiveView=%s (receiver is attached to LIVE channel)\n", Device->DeviceNumber(), ChannelNumber, BOOLTOTEXT(LiveView)); | |
221 | DELETENULL(receiver); | |
222 | return; | |
223 | } else { | |
224 | DEBUG_OT_TXTRCVC("IGNORE channel=0 switch on DVB %d for channel %d LiveView=%s (receiver is attached to NON-LIVE channel)\n", Device->DeviceNumber(), ChannelNumber, BOOLTOTEXT(LiveView)); | |
225 | return; | |
226 | }; | |
227 | } else { | |
228 | DEBUG_OT_TXTRCVC("IGNORE channel=0 switch on DVB %d for channel %d LiveView=%s\n", Device->DeviceNumber(), ChannelNumber, BOOLTOTEXT(LiveView)); | |
229 | }; | |
230 | return; | |
231 | }; | |
85 | 232 | |
86 | 233 | // ignore if channel is invalid (highly unlikely, this will ever |
87 | 234 | // be the case, but defensive coding rules!) |
88 | 235 | #if defined(APIVERSNUM) && APIVERSNUM >= 20301 |
89 | 236 | LOCK_CHANNELS_READ; |
90 | const cChannel* newLiveChannel = Channels->GetByNumber(ChannelNumber); | |
237 | const cChannel* newChannel = Channels->GetByNumber(ChannelNumber); | |
91 | 238 | #else |
92 | const cChannel* newLiveChannel = Channels.GetByNumber(ChannelNumber); | |
239 | const cChannel* newChannel = Channels.GetByNumber(ChannelNumber); | |
93 | 240 | #endif |
94 | if (newLiveChannel == NULL) return; | |
95 | ||
96 | // ignore non-live-channel-switching | |
97 | if (!LiveView || ChannelNumber != cDevice::CurrentChannel()) return; | |
98 | ||
99 | // live channel was changed | |
100 | // now re-attach the receiver to the new live channel | |
101 | ||
241 | if (newChannel == NULL) { | |
242 | DEBUG_OT_TXTRCVC("IGNORE invalid channel on DVB %d for channel %d LiveView=%s\n", Device->DeviceNumber(), ChannelNumber, BOOLTOTEXT(LiveView)); | |
243 | return; | |
244 | }; | |
245 | ||
246 | if (!LiveView) { | |
247 | if ((NonLiveChannelNumber > 0) && (NonLiveChannelNumber == ChannelNumber)) { | |
248 | // don't ignore non-live-channel-switching in case of NonLiveChannelNumber was hit | |
249 | DEBUG_OT_TXTRCVC("PASSED selected NON-LIVE channel switch detected on DVB %d for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
250 | } else if ( | |
251 | (NonLiveChannelNumber > 0) // currently on tuned channel | |
252 | && (NonLiveChannelNumber != ChannelNumber) // channel is not matching | |
253 | && (receiver) // receiver is active | |
254 | ) { | |
255 | if (receiver->device->DeviceNumber() == Device->DeviceNumber()) { // device matching | |
256 | // don't ignore non-live-channel-switching in case of Device was hit | |
257 | DEBUG_OT_TXTRCVC("STOPRC not matching NON-LIVE channel switch detected on DVB %d (currently used by receiver) for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
258 | DELETENULL(receiver); | |
259 | return; | |
260 | } else { | |
261 | DEBUG_OT_TXTRCVC("IGNORE not matching NON-LIVE channel switch on DVB %d (not used by receiver) for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
262 | return; | |
263 | }; | |
264 | } else { | |
265 | // ignore other non-live-channel-switching | |
266 | DEBUG_OT_TXTRCVC("IGNORE not matching NON-LIVE channel switch on DVB %d for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
267 | return; | |
268 | }; | |
269 | } else { | |
270 | // ignore non-live-channel-switching | |
271 | if (ChannelNumber != cDevice::CurrentChannel()) { | |
272 | DEBUG_OT_TXTRCVC("IGNORE not current device LIVE channel switch on DVB %d for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
273 | return; | |
274 | }; | |
275 | ||
276 | // process live channel switch | |
277 | DEBUG_OT_TXTRCVC("PASSED LIVE channel switch detected on DVB %d for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
278 | }; | |
279 | ||
280 | // now re-attach the receiver to the new channel | |
281 | int TPid = newChannel->Tpid(); | |
282 | ||
283 | if (LiveView && TPid && receiver) { | |
284 | // tell still running receiver thread that it will be deleted and new channel is live | |
285 | // will be used during deleting the receiver to signal that status via TeletextBrowser::ChannelSwitched | |
286 | receiver->SetFlagStopByLiveChannelSwitch(true); | |
287 | }; | |
288 | ||
289 | // channel was changed, delete the running receiver if still running | |
102 | 290 | DELETENULL(receiver); |
103 | 291 | |
104 | int TPid = newLiveChannel->Tpid(); | |
105 | ||
106 | 292 | if (TPid) { |
107 | receiver = new cTxtReceiver(newLiveChannel, storeTopText, storage); | |
108 | cDevice::ActualDevice()->AttachReceiver(receiver); | |
293 | if (LiveView) { | |
294 | // attach to actual device | |
295 | receiver = new cTxtReceiver(cDevice::ActualDevice(), LiveView, newChannel, storeTopText, storage); | |
296 | cDevice::ActualDevice()->AttachReceiver(receiver); | |
297 | DEBUG_OT_TXTRCVC("ATTACH receiver to DVB %d for LIVE channel %d '%s'\n", cDevice::ActualDevice()->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
298 | TeletextBrowser::ChannelSwitched(ChannelNumber, ChannelIsLive); | |
299 | NonLiveChannelNumber = 0; // clear non-live channel number | |
300 | } else { | |
301 | cDevice *device = cDevice::GetDevice(Device->DeviceNumber()); | |
302 | receiver = new cTxtReceiver(device, LiveView, newChannel, storeTopText, storage); | |
303 | device->AttachReceiver(receiver); | |
304 | DEBUG_OT_TXTRCVC("ATTACH receiver to DVB %d for TUNED channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
305 | TeletextBrowser::ChannelSwitched(ChannelNumber, ChannelIsTuned); | |
306 | }; | |
307 | } else { | |
308 | DEBUG_OT_TXTRCVC("NOOP do not attach receiver (MISSING teletext) on DVB %d for channel %d '%s'\n", Device->DeviceNumber(), newChannel->Number(), newChannel->Name()); | |
309 | TeletextBrowser::ChannelSwitched(ChannelNumber, ChannelHasNoTeletext); | |
109 | 310 | } |
110 | ||
111 | TeletextBrowser::ChannelSwitched(ChannelNumber); | |
112 | } | |
113 | ||
114 | ||
115 | cTxtReceiver::cTxtReceiver(const cChannel* chan, bool storeTopText, Storage* storage) | |
116 | : cReceiver(chan, -1), cThread("osdteletext-receiver"), | |
311 | } | |
312 | ||
313 | ||
314 | cTxtReceiver::cTxtReceiver(const cDevice *dev, const bool live, const cChannel* chan, bool storeTopText, Storage* storage) | |
315 | : cReceiver(chan, -1), cThread("osdteletext-receiver", true), | |
117 | 316 | TxtPage(0), storeTopText(storeTopText), buffer((188+60)*75), storage(storage) |
118 | { | |
317 | , device(dev) | |
318 | , live(live) | |
319 | , flagStopByLiveChannelSwitch(false) | |
320 | , channel(chan), statTxtReceiverPageCount(0) | |
321 | { | |
322 | isyslog("osdteletext: cTxtReceiver started on DVB %d for channel %d '%s' ID=%s storeTopText=%s LiveView=%s\n", device->DeviceNumber(), channel->Number(), channel->Name(), *ChannelID().ToString(), BOOLTOTEXT(storeTopText), BOOLTOTEXT(live)); | |
119 | 323 | SetPids(NULL); |
120 | 324 | AddPid(chan->Tpid()); |
121 | 325 | storage->prepareDirectory(ChannelID()); |
326 | time(&statTxtReceiverTimeStart); // record start time | |
122 | 327 | |
123 | 328 | // 10 ms timeout on getting TS frames |
124 | 329 | buffer.SetTimeouts(0, 10); |
131 | 336 | Activate(false); |
132 | 337 | buffer.Clear(); |
133 | 338 | delete TxtPage; |
339 | ||
340 | // calculate and log statistics | |
341 | time_t statTxtReceiverTimeStop; | |
342 | time(&statTxtReceiverTimeStop); | |
343 | double time_diff = difftime(statTxtReceiverTimeStop, statTxtReceiverTimeStart); | |
344 | isyslog("osdteletext: cTxtReceiver stopped after %.0lf sec: cTelePage received on DVB %d for channel %d '%s' ID=%s: %ld (%.3lf/sec)\n", time_diff, device->DeviceNumber(), channel->Number(), channel->Name(), *ChannelID().ToString(), statTxtReceiverPageCount, statTxtReceiverPageCount / time_diff); | |
345 | ||
346 | if (!live) { | |
347 | // tuned channel | |
348 | if (flagStopByLiveChannelSwitch == false) { | |
349 | TeletextBrowser::ChannelSwitched(channel->Number(), ChannelWasTuned); // trigger TeletextBrowser that channel is no longer tuned | |
350 | } else { | |
351 | TeletextBrowser::ChannelSwitched(channel->Number(), ChannelWasTunedNewChannelIsLive); // trigger TeletextBrowser that channel is no longer tuned but new channel is live | |
352 | }; | |
353 | }; | |
134 | 354 | } |
135 | 355 | |
136 | 356 | void cTxtReceiver::Stop() |
247 | 467 | line = (hdr>>3) & 0x1f; |
248 | 468 | ptr = &TXT_buf[10]; |
249 | 469 | |
250 | switch (line) { | |
251 | case 0: | |
252 | { | |
470 | static int stat_pagecount = 0; | |
471 | static long int stat_pagecount_total = 0; | |
472 | static time_t stat_time_last; | |
473 | static time_t stat_time_start; | |
474 | static int init = 0; | |
475 | if (init == 0) { | |
476 | time(&stat_time_last); | |
477 | time(&stat_time_start); | |
478 | init = 1; | |
479 | } | |
480 | time_t stat_time_now; | |
481 | double stat_time_diff_last; | |
482 | double stat_time_diff_start; | |
483 | ||
484 | static char debugPrefix[16]; | |
485 | ||
486 | if (line == 0) { | |
253 | 487 | unsigned char b1, b2, b3, b4; |
254 | 488 | int pgno, subno; |
255 | 489 | b1 = unham16 (ptr); |
256 | 490 | // Page no, 10- and 1-digit |
257 | 491 | |
258 | if (b1 == 0xff) break; | |
492 | if (b1 == 0xff) return; | |
493 | ||
259 | 494 | SaveAndDeleteTxtPage(); |
495 | snprintf(debugPrefix, sizeof(debugPrefix), "%s", ""); // clear debug status | |
260 | 496 | |
261 | 497 | b2 = unham16 (ptr+2); // Sub-code 0..6 + C4 |
262 | 498 | b3 = unham16 (ptr+4); // Sub-code 8..13 + C5,C6 |
280 | 516 | subno = (b2 + b3 * 256) & 0x3f7f; // Sub Page Number |
281 | 517 | |
282 | 518 | TxtPage = new cTelePage(PageID(ChannelID(), pgno, subno), flags, lang, mag, storage); |
283 | TxtPage->SetLine((int)line,(uchar *)ptr); | |
284 | break; | |
285 | } | |
286 | case 1 ... 25: | |
287 | { | |
288 | if (TxtPage) TxtPage->SetLine((int)line,(uchar *)ptr); | |
289 | break; | |
290 | } | |
291 | /*case 23: | |
292 | { | |
293 | SaveAndDeleteTxtPage(); | |
294 | break; | |
295 | }*/ | |
296 | default: | |
297 | break; | |
298 | } | |
299 | } | |
519 | DEBUG_OT_NEPG("new cTelePage pgno=%03x subno=%02x flags=0x%02x lang=0x%02x\n", pgno, subno, flags, lang); | |
520 | stat_pagecount++; | |
521 | stat_pagecount_total++; | |
522 | statTxtReceiverPageCount++; | |
523 | time(&stat_time_now); | |
524 | stat_time_diff_last = difftime(stat_time_now, stat_time_last); | |
525 | if (stat_time_diff_last >= 10) { // every 10 seconds | |
526 | stat_time_diff_start = difftime(stat_time_now, stat_time_start); | |
527 | DEBUG_OT_COPG("received on DVB %d channel %d '%s' cTelePages: %d in %.0lf sec (total: %ld in %.0lf sec -> %.3lf/sec)\n" | |
528 | , device->DeviceNumber() | |
529 | , channel->Number() | |
530 | , channel->Name() | |
531 | , stat_pagecount | |
532 | , stat_time_diff_last | |
533 | , stat_pagecount_total | |
534 | , stat_time_diff_start | |
535 | , stat_pagecount_total / stat_time_diff_start | |
536 | ); | |
537 | stat_pagecount = 0; | |
538 | stat_time_last = stat_time_now; | |
539 | }; | |
540 | ||
541 | if (m_debugmask & DEBUG_MASK_OT_TXTRCVD) { | |
542 | if (m_debugpsub == 0) { | |
543 | if (m_debugpage == TxtPage->page.page) { | |
544 | // select debug for all sub-pages | |
545 | snprintf(debugPrefix, sizeof(debugPrefix), "p=%03x*%02x", TxtPage->page.page, TxtPage->page.subPage); | |
546 | } else if (m_debugline >= 0) { | |
547 | // all pages, but specific line only | |
548 | snprintf(debugPrefix, sizeof(debugPrefix), "p=%03x!%02x", TxtPage->page.page, TxtPage->page.subPage); | |
549 | }; | |
550 | } else { | |
551 | if ((m_debugpage == TxtPage->page.page) && (m_debugpsub == TxtPage->page.subPage)) { | |
552 | if ((m_debugline < 0) || (m_debugline == line)) { | |
553 | // select debug only for matching sub-page | |
554 | snprintf(debugPrefix, sizeof(debugPrefix), "p=%03x-%02x", TxtPage->page.page, TxtPage->page.subPage); | |
555 | }; | |
556 | }; | |
557 | }; | |
558 | }; | |
559 | }; | |
560 | ||
561 | if (TxtPage) { | |
562 | if ((strlen(debugPrefix) > 0) && ((m_debugline < 0) || (m_debugline == line))) { | |
563 | TxtPage->SetLine(line,(uchar *)ptr, debugPrefix); | |
564 | } else { | |
565 | TxtPage->SetLine(line,(uchar *)ptr, ""); | |
566 | }; | |
567 | }; | |
568 | } | |
569 | ||
570 | // vim: ts=3 sw=3 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | 1 | * Copyright (c) 2003,2004 by Marcel Wiesweg * |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
2 | 3 | * * |
3 | 4 | * This program is free software; you can redistribute it and/or modify * |
4 | 5 | * it under the terms of the GNU General Public License as published by * |
25 | 26 | int mag; |
26 | 27 | unsigned char flags; |
27 | 28 | unsigned char lang; |
29 | public: | |
28 | 30 | PageID page; |
29 | unsigned char pagebuf[27*40]; | |
31 | private: | |
32 | TelePageData pagedata; | |
30 | 33 | Storage* storage; |
31 | 34 | public: |
32 | 35 | cTelePage(PageID page, uchar flags, uchar lang, int mag, Storage *s); |
33 | 36 | ~cTelePage(); |
34 | void SetLine(int, uchar*); | |
37 | void SetLine(int, uchar*, const char*); | |
35 | 38 | void save(); |
36 | 39 | bool IsTopTextPage(); |
37 | 40 | }; |
53 | 56 | bool storeTopText; |
54 | 57 | cRingTxtFrames buffer; |
55 | 58 | Storage *storage; |
59 | public: | |
60 | const cDevice *device; | |
61 | private: | |
62 | const bool live; | |
63 | bool flagStopByLiveChannelSwitch; | |
64 | const cChannel* channel; | |
65 | long int statTxtReceiverPageCount; | |
66 | time_t statTxtReceiverTimeStart; | |
56 | 67 | protected: |
57 | 68 | virtual void Activate(bool On); |
58 | 69 | #if defined(APIVERSNUM) && APIVERSNUM >= 20301 |
62 | 73 | #endif |
63 | 74 | virtual void Action(); |
64 | 75 | public: |
65 | cTxtReceiver(const cChannel* chan, bool storeTopText, Storage* storage); | |
76 | cTxtReceiver(const cDevice *dev, const bool live, const cChannel* chan, bool storeTopText, Storage* storage); | |
66 | 77 | virtual ~cTxtReceiver(); |
67 | 78 | virtual void Stop(); |
79 | void SetFlagStopByLiveChannelSwitch(bool flag) { flagStopByLiveChannelSwitch = flag; }; | |
80 | bool Live() { return live; }; | |
81 | bool ChannelNumber() { return channel->Number(); }; | |
68 | 82 | }; |
69 | 83 | |
70 | 84 | class cTxtStatus : public cStatus { |
85 | public: | |
86 | cTxtReceiver *receiver; | |
71 | 87 | private: |
72 | cTxtReceiver *receiver; | |
73 | 88 | bool storeTopText; |
74 | 89 | Storage* storage; |
90 | int NonLiveChannelNumber; | |
75 | 91 | protected: |
76 | 92 | virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView); |
77 | 93 | public: |
78 | 94 | cTxtStatus(bool storeTopText, Storage* storage); |
95 | void SetNonLiveChannelNumber(const int ChannelNumber) { NonLiveChannelNumber = ChannelNumber; return; }; | |
79 | 96 | ~cTxtStatus(); |
80 | 97 | }; |
81 | 98 |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) 2005 by Udo Richter * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * txtrender.c - Teletext display abstraction and teletext code * |
3 | 5 | * renderer * |
7 | 9 | * the Free Software Foundation; either version 2 of the License, or * |
8 | 10 | * (at your option) any later version. * |
9 | 11 | * * |
10 | * Changelog: * | |
11 | * 2005-03 initial version (c) Udo Richter * | |
12 | * * | |
13 | 12 | ***************************************************************************/ |
14 | 13 | |
15 | 14 | #include <strings.h> |
16 | 15 | #include "txtrender.h" |
17 | 16 | #include "menu.h" |
17 | #include "logging.h" | |
18 | #include "txtfont.h" | |
18 | 19 | |
19 | 20 | // Font tables |
20 | 21 | |
233 | 234 | sizeDoubleSize |
234 | 235 | }; |
235 | 236 | |
236 | /* | |
237 | 237 | // Debug only: List of teletext spacing code short names |
238 | 238 | const char *(names[0x20])={ |
239 | 239 | "AlBk","AlRd","AlGr","AlYl","AlBl","AlMg","AlCy","AlWh", |
240 | 240 | "Flsh","Stdy","EnBx","StBx","SzNo","SzDh","SzDw","SzDs", |
241 | 241 | "MoBk","MoRd","MoGr","MoYl","MoBl","MoMg","MoCy","MoWh", |
242 | 242 | "Conc","GrCn","GrSp","ESC", "BkBl","StBk","HoMo","ReMo"}; |
243 | */ | |
244 | 243 | |
245 | 244 | void cRenderPage::ReadTeletextHeader(unsigned char *Header) { |
246 | // Format of buffer: | |
247 | // 0 String "VTXV4" | |
245 | // Format of buffer, see also structure TelePageData in storage.h | |
246 | // Header: 12 bytes (0-11) | |
247 | // 0 String "VTXV5" | |
248 | 248 | // 5 always 0x01 |
249 | 249 | // 6 magazine number |
250 | 250 | // 7 page number |
252 | 252 | // 9 lang |
253 | 253 | // 10 always 0x00 |
254 | 254 | // 11 always 0x00 |
255 | // 12 teletext data, 40x24 bytes | |
255 | // Teletext base data starting from byte 12 | |
256 | // 12 teletext data, 25x40 bytes | |
257 | // VTXV5 extension | |
258 | // X25 ( 1x40) | |
259 | // X26 (16x40) | |
260 | // X27 (16x40) | |
261 | // X28 (16x40) | |
262 | // M29 (16x40) | |
256 | 263 | // Format of flags: |
257 | 264 | // 0x80 C4 - Erase page |
258 | 265 | // 0x40 C5 - News flash |
270 | 277 | |
271 | 278 | void cRenderPage::RenderTeletextCode(unsigned char *PageCode) { |
272 | 279 | int x,y; |
273 | bool EmptyNextLine=false; | |
274 | // Skip one line, in case double height chars were/will be used | |
280 | bool EmptyNextLine=false; // Skip one line, in case double height chars were/will be used | |
275 | 281 | |
276 | 282 | // Get code pages: |
277 | 283 | int LocalG0CodePage=(FirstG0CodePage & 0x78) |
281 | 287 | enumCharsets SecondG0=GetG0Charset(SecondG0CodePage); |
282 | 288 | // Reserved for later use: |
283 | 289 | // enumCharsets FirstG2=GetG2Charset(LocalG0CodePage); |
284 | ||
290 | ||
285 | 291 | for (y=0;y<24;(EmptyNextLine?y+=2:y++)) { |
286 | 292 | // Start of line: Set start of line defaults |
287 | 293 | |
294 | if (m_debugmask & DEBUG_MASK_OT_TXTRD) { | |
295 | printf("y=%02d ", y); | |
296 | }; | |
297 | ||
288 | 298 | // Hold Mosaics mode: Remember last mosaic char/charset |
289 | 299 | // for next spacing code |
290 | 300 | bool HoldMosaics=false; |
311 | 321 | c.SetCharset(FirstG0); |
312 | 322 | |
313 | 323 | if (y==0 && (Flags&0x10)) { |
324 | DEBUG_OT_BOXED("set c.SetBoxed(true) Flags=%02x x=%d y=%d", Flags, x, y); | |
314 | 325 | c.SetBoxedOut(true); |
315 | 326 | } |
316 | 327 | if (Flags&0x60) { |
328 | DEBUG_OT_BOXED("set c.SetBoxed(true) Flags=%02x x=%d y=%d", Flags, x, y); | |
317 | 329 | c.SetBoxedOut(true); |
318 | 330 | } |
319 | 331 | |
326 | 338 | |
327 | 339 | // Move through line |
328 | 340 | for (x=0;x<40;x++) { |
329 | unsigned char ttc=PageCode[x+40*y] & 0x7f; | |
330 | // skip parity check | |
341 | unsigned char ttc=PageCode[x+40*y]; | |
331 | 342 | |
332 | 343 | if (y==0 && x<8) continue; |
333 | 344 | // no displayable data here... |
334 | ||
335 | /* // Debug only: Output line data and spacing codes | |
336 | if (y==6) { | |
345 | ||
346 | if (m_debugmask & DEBUG_MASK_OT_TXTRD) { | |
347 | // Debug only: Output line data and spacing codes | |
337 | 348 | if (ttc<0x20) |
338 | printf("%s ",names[ttc]); | |
349 | printf("%s(%02x) ",names[ttc], ttc); | |
339 | 350 | else |
340 | 351 | printf("%02x ",ttc); |
341 | 352 | if (x==39) printf("\n"); |
342 | } | |
343 | */ | |
353 | }; | |
344 | 354 | |
345 | 355 | // Handle all 'Set-At' spacing codes |
346 | 356 | switch (ttc) { |
347 | 357 | case 0x09: // Steady |
358 | DEBUG_OT_BLINK("set bc.SetBlink(false) ttc=%d x=%d y=%d", ttc, x, y); | |
348 | 359 | c.SetBlink(false); |
349 | 360 | break; |
350 | 361 | case 0x0C: // Normal Size |
472 | 483 | c.SetConceal(false); |
473 | 484 | break; |
474 | 485 | case 0x08: // Flash |
486 | DEBUG_OT_BLINK("set c.SetBlink(true) ttc=%02x x=%d y=%d", ttc, x, y); | |
475 | 487 | c.SetBlink(true); |
476 | 488 | break; |
477 | 489 | case 0x0A: // End Box |
490 | DEBUG_OT_BOXED("set c.SetBoxed(true) End Box ttc=%02x x=%d y=%d", ttc, x, y); | |
478 | 491 | c.SetBoxedOut(true); |
479 | 492 | break; |
480 | 493 | case 0x0B: // Start Box |
494 | DEBUG_OT_BOXED("set c.SetBoxed(false) StartBox ttc=%02x x=%d y=%d", ttc, x, y); | |
481 | 495 | c.SetBoxedOut(false); |
482 | 496 | break; |
483 | 497 | case 0x0D: // Double Height |
524 | 538 | } // end for y |
525 | 539 | |
526 | 540 | for (x=0;x<40;x++) { |
527 | // Clean out last line | |
541 | // Clean out last lines | |
528 | 542 | cTeletextChar c; |
529 | 543 | c.SetFGColor(ttcWhite); |
530 | 544 | c.SetBGColor(ttcBlack); |
531 | 545 | c.SetCharset(FirstG0); |
532 | 546 | c.SetChar(' '); |
533 | 547 | if (Flags&0x60) { |
548 | DEBUG_OT_BOXED("set c.SetBoxed(true) Flags=%02x ttc=(space) x=%d y=%d", Flags, x, y); | |
534 | 549 | c.SetBoxedOut(true); |
535 | 550 | } |
536 | 551 | SetChar(x,24,c); |
537 | } | |
552 | SetChar(x,25,c); | |
553 | SetChar(x,26,c); | |
554 | } | |
555 | ||
556 | /* VTXV5 handling starts here */ | |
557 | ||
558 | DEBUG_OT_TXTRDT("start X/26 handling"); /* X/26 */ | |
559 | x = -1; y = -1; // reset x/y | |
560 | unsigned char* PageCode_X26 = PageCode + 25*40 + 40; // X/1-24 + X/25 | |
561 | for (int row = 0; row <= 15; row++) { | |
562 | // convert X/26/0-15 into triplets | |
563 | if (PageCode_X26[row*40] == 0) { | |
564 | // row empty | |
565 | continue; | |
566 | } else if ((PageCode_X26[row*40] & 0x80) != 0x80) { | |
567 | DEBUG_OT_TXTRDT("invalid X/26 row (DesignationCode flag not valid)"); | |
568 | continue; | |
569 | }; | |
570 | for (int triplet = 0; triplet < 13; triplet++) { | |
571 | uint8_t addr = PageCode_X26[row*40 + 1 + triplet*3]; | |
572 | uint8_t mode = PageCode_X26[row*40 + 2 + triplet*3]; | |
573 | uint8_t data = PageCode_X26[row*40 + 3 + triplet*3]; | |
574 | ||
575 | int found = 0; | |
576 | const char* info; | |
577 | ||
578 | if ((mode == 0x04) && (addr >= 40) && (addr <= 63)) { | |
579 | // 0x04 = 0b00100 | |
580 | // "Set Active Position" | |
581 | found = 1; | |
582 | if (addr == 40) { | |
583 | y = 24; | |
584 | } else { | |
585 | y = addr - 40; | |
586 | }; | |
587 | x = data; | |
588 | DEBUG_OT_TXTRDT("X/26 triplet found: row=%d triplet=%d SetActivePosition y=%d x=%d\n", row, triplet, y, x); | |
589 | } else if ((mode == 0x04) && (addr >= 0) && (addr <= 39)) { | |
590 | // 0x04 = 0b00100 | |
591 | // RESERVED | |
592 | found = 1; | |
593 | } else if ((mode == 0x1f) && (addr == 0x3f)) { | |
594 | // 0x1f = 0b11111 | |
595 | // "Termination Marker" | |
596 | found = 1; | |
597 | if (m_debugmask & DEBUG_MASK_OT_TXTRDT) { | |
598 | switch(data & 0x07) { | |
599 | case 0x00: // 0b000 | |
600 | info = "Intermediate (G)POP sub-page. End of object, more objects follow on this page."; | |
601 | break; | |
602 | case 0x01: // 0b001 | |
603 | info = "Intermediate (G)POP sub-page. End of last object on this page."; | |
604 | break; | |
605 | case 0x02: // 0b010 | |
606 | info = "Last (G)POP sub-page. End of object, more objects follow on this page."; | |
607 | break; | |
608 | case 0x03: // 0b011 | |
609 | info = "Last (G)POP sub-page. End of last object on this page."; | |
610 | break; | |
611 | case 0x04: // 0b100 | |
612 | info = "Local Object definitions. End of object, more objects follow on this page."; | |
613 | break; | |
614 | case 0x05: // 0b101 | |
615 | info = "Local Object definitions. End of last object on this page."; | |
616 | break; | |
617 | case 0x06: // 0b110 | |
618 | info = "Local enhancement data. End of enhancement data, Local Object definitions follow."; | |
619 | break; | |
620 | case 0x07: // 0b111 | |
621 | info = "Local enhancement data. End of enhancement data, no Local Object definitions follow."; | |
622 | break; | |
623 | }; | |
624 | DEBUG_OT_TXTRDT("X/26 triplet found: row=%d triplet=%d TerminationMarker: %s\n", row, triplet, info); | |
625 | }; | |
626 | } else if (((mode & 0x10) == 0x10) && (addr >= 0) && (addr <= 39)) { | |
627 | // 0x1x = 0b1xxxx | |
628 | // G0 Characters Including Diacritical Marks | |
629 | ||
630 | if (y == -1) { | |
631 | // "Set Active Position" not seen so far -> no y known so far -> SKIP | |
632 | DEBUG_OT_TXTRDT("misplaced X/26 triplet 'G0 Characters Including Diacritical Marks' misses 'Set Active Position' in advance"); | |
633 | continue; | |
634 | }; | |
635 | ||
636 | x = addr; | |
637 | cTeletextChar c = GetChar(x, y); | |
638 | if (mode == 0x10) { | |
639 | // 0x10 = 0b10000 | |
640 | info = "G0 character without diacritical mark"; | |
641 | // No diacritical mark exists for mode description value 0b10000. An unmodified G0 character is then displayed unless the 7 bits of the data field have the value 0b0101010 (2/A) when the symbol "@" shall be displayed. | |
642 | if (data == 0x2a) { | |
643 | // set char to '@' | |
644 | c.SetCharset(CHARSET_LATIN_G0); | |
645 | c.SetChar(0x80); | |
646 | } else { | |
647 | c.SetCharset(CHARSET_LATIN_G0); | |
648 | c.SetChar(data); | |
649 | }; | |
650 | DEBUG_OT_TXTRDT("X/26 triplet found: row=%d triplet=%d: %s (data=0x%02x)\n", row, triplet, info, data); | |
651 | found = 1; | |
652 | } else { | |
653 | info = "G0 character with diacritical mark"; | |
654 | found = 1; | |
655 | uint8_t mark = mode & 0x0f; | |
656 | DEBUG_OT_TXTRDT("X/26 triplet found: row=%d triplet=%d: %s x=%d mark=%d data=0x%02x\n", row, triplet, info, x, mark, data); | |
657 | if (data >= 0x20) { | |
658 | DEBUG_OT_TXTRDT("X/26 triplet exec : y=%02d x=%02d change Char=0x%02x Charset=0x%04x mark=%x => Char=0x%02x Charset=0x%04x\n", y, x, c.GetChar(), c.GetCharset(), mark, X26_G0_CharWithDiacritcalMarkMapping(data, mark), CHARSET_LATIN_G0); | |
659 | c.SetCharset(CHARSET_LATIN_G0); | |
660 | c.SetChar(X26_G0_CharWithDiacritcalMarkMapping(data, mark)); | |
661 | } else { | |
662 | // ignore: Data field values < 20 hex are reserved but decoders should still set the column co-ordinate of the Active Position to the value of the address field. | |
663 | }; | |
664 | }; | |
665 | SetChar(x, y, c); | |
666 | }; | |
667 | ||
668 | if (found == 0) | |
669 | DEBUG_OT_TXTRDT("X/26 triplet found: row=%d triplet=%d UNSUPPORTED addr=0x%02x mode=0x%02x data=0x%02x\n", row, triplet, addr, mode, data); | |
670 | }; | |
671 | }; | |
538 | 672 | } |
539 | 673 | |
540 | ||
674 | // vim: ts=4 sw=4 et |
0 | 0 | /*************************************************************** -*- c++ -*- |
1 | * Copyright (c) 2005 by Udo Richter * | |
2 | * Copyright (c) 2021 by Peter Bieringer (extenions) * | |
1 | 3 | * * |
2 | 4 | * txtrender.h - Teletext display abstraction and teletext code * |
3 | 5 | * renderer * |
7 | 9 | * the Free Software Foundation; either version 2 of the License, or * |
8 | 10 | * (at your option) any later version. * |
9 | 11 | * * |
10 | * Changelog: * | |
11 | * 2005-03 initial version (c) Udo Richter * | |
12 | * * | |
13 | 12 | ***************************************************************************/ |
14 | 13 | |
15 | 14 | #ifndef OSDTELETEXT_TXTRENDER_H_ |
16 | 15 | #define OSDTELETEXT_TXTRENDER_H_ |
17 | 16 | |
18 | 17 | #include <stdio.h> |
18 | #include <vdr/tools.h> | |
19 | 19 | |
20 | 20 | |
21 | 21 | // Teletext character sets |
224 | 224 | // 'dirty' flag on each character |
225 | 225 | |
226 | 226 | protected: |
227 | cTeletextChar Page[40][25]; | |
228 | ||
227 | cTeletextChar Page[40][27]; | |
228 | ||
229 | 229 | int Flags; |
230 | 230 | // 0x80 C4 - Erase page |
231 | 231 | // 0x40 C5 - News flash |
249 | 249 | public: |
250 | 250 | cRenderPage(); |
251 | 251 | |
252 | #define CHECK_XY_LIMIT(x,y) ((x < 0) || (x >= 40) || (y < 0) || (y >= 27)) | |
253 | ||
252 | 254 | cTeletextChar GetChar(int x, int y) { |
253 | 255 | // Read character content from page |
254 | if (x<0 || x>=40 || y<0 || y>=25) { | |
255 | printf("Warning: out of bounds read access to teletext page\n"); | |
256 | if (CHECK_XY_LIMIT(x,y)) { | |
257 | esyslog("osdteletext: WARN: out of bounds access to teletext page (GetChar x=%d y=%d)", x, y); | |
256 | 258 | return cTeletextChar(); |
257 | 259 | } |
258 | 260 | return Page[x][y].ToDirty(false); |
265 | 267 | |
266 | 268 | bool IsDirty(int x, int y) { |
267 | 269 | // local dirty status |
268 | if (x<0 || x>=40 || y<0 || y>=25) { | |
269 | printf("Warning: out of bounds read access to teletext page\n"); | |
270 | if (CHECK_XY_LIMIT(x,y)) { | |
271 | esyslog("osdteletext: WARN: out of bounds access to teletext page (IsDirty x=%d y=%d)", x, y); | |
270 | 272 | return false; |
271 | 273 | } |
272 | 274 | return Page[x][y].GetDirty() | DirtyAll; |
274 | 276 | |
275 | 277 | void MakeDirty(int x, int y) { |
276 | 278 | // force one character dirty |
277 | if (x<0 || x>=40 || y<0 || y>=25) { | |
278 | printf("Warning: out of bounds write access to teletext page\n"); | |
279 | if (CHECK_XY_LIMIT(x,y)) { | |
280 | esyslog("osdteletext: WARN: out of bounds access to teletext page (MakeDirty x=%d y=%d)", x, y); | |
279 | 281 | return; |
280 | 282 | } |
281 | 283 | Page[x][y].SetDirty(true); |
285 | 287 | void SetChar(int x, int y, cTeletextChar c) { |
286 | 288 | // Set character at given location |
287 | 289 | |
288 | if (x<0 || x>=40 || y<0 || y>=25) { | |
289 | printf("Warning: out of bounds write access to teletext page\n"); | |
290 | if (CHECK_XY_LIMIT(x,y)) { | |
291 | esyslog("osdteletext: WARN: out of bounds access to teletext page (SetChar x=%d y=%d c=%x)", x, y, c.GetC()); | |
290 | 292 | return; |
291 | 293 | } |
292 | 294 | if (GetChar(x,y) != c) { |
302 | 304 | void RenderTeletextCode(unsigned char *PageCode); |
303 | 305 | // Interprete teletext code referenced by PageCode |
304 | 306 | // and draw the whole page content into this object |
305 | // PageCode must be a 40*24 bytes buffer | |
307 | // PageCode must be a buffer containing TelePageData structure (see storage.h) | |
306 | 308 | }; |
307 | 309 | |
308 | 310 |