1 #include "config.h"
2 #ifdef HAVE_ZVBI
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <errno.h>
10 #include <math.h>
11 #include <time.h>
12 #include <fcntl.h>
13 #include <iconv.h>
14 #include <assert.h>
15 #include <pthread.h>
16
17 #include <X11/Intrinsic.h>
18
19 #include "vbi-data.h"
20 #include "vbi-sim.c"
21
22 char *vbi_colors[8] = { "black", "red", "green", "yellow",
23 "blue", "magenta", "cyan", "white" };
24 struct vbi_rect vbi_fullrect = {
25 x1: 0, y1: 0, x2: 41, y2: 25,
26 };
27
28 /*---------------------------------------------------------------------*/
29
30 struct vbi_state*
31 vbi_open(char *dev, int debug, int sim)
32 {
33 struct vbi_state *vbi;
34 int services = VBI_SLICED_VBI_525 | VBI_SLICED_VBI_625
35 | VBI_SLICED_TELETEXT_B | VBI_SLICED_CAPTION_525
36 | VBI_SLICED_CAPTION_625 | VBI_SLICED_VPS
37 | VBI_SLICED_WSS_625 | VBI_SLICED_WSS_CPR1204;
38 int p[2];
39
40 /* init vbi */
41 vbi = malloc(sizeof(*vbi));
42 if (NULL == vbi)
43 goto oops;
44 memset(vbi,0,sizeof(*vbi));
45 vbi->debug = debug;
46 vbi->sim = sim;
47 vbi->dec = vbi_decoder_new();
48 if (NULL == vbi->dec)
49 goto oops;
50
51 if (vbi->sim) {
52 vbi->par = init_sim(625,services);
53 /* simulation for select */
54 pipe(p);
55 switch (fork()) {
56 case -1:
57 perror("fork");
58 exit(1);
59 case 0:
60 close(p[0]);
61 for (;;) {
62 if (1 != write(p[1],"x",1))
63 exit(0);
64 usleep(100*1000);
65 }
66 default:
67 vbi->fd = p[0];
68 close(p[1]);
69 };
70 } else {
71 vbi->cap = vbi_capture_v4l2_new(dev,16,&services,-1,&vbi->err,debug);
72 if (NULL == vbi->cap) {
73 vbi->cap = vbi_capture_v4l_new(dev,16,&services,-1,&vbi->err,debug);
74 if (NULL == vbi->cap)
75 goto oops;
76 }
77 vbi->par = vbi_capture_parameters(vbi->cap);
78 vbi->fd = vbi_capture_fd(vbi->cap);
79 }
80 vbi->lines = (vbi->par->count[0] + vbi->par->count[1]);
81 vbi->raw = malloc(vbi->lines * vbi->par->bytes_per_line);
82 if (NULL == vbi->raw)
83 goto oops;
84 vbi->sliced = malloc(vbi->lines * sizeof(vbi_sliced));
85 if (NULL == vbi->sliced)
86 goto oops;
87 vbi->tv.tv_sec = 1;
88 vbi->tv.tv_usec = 0;
89 return vbi;
90
91 oops:
92 if (vbi) {
93 if (vbi->sliced)
94 free(vbi->sliced);
95 if (vbi->raw)
96 free(vbi->raw);
97 if (vbi->cap)
98 vbi_capture_delete(vbi->cap);
99 if (vbi->dec)
100 vbi_decoder_delete(vbi->dec);
101 free(vbi);
102 }
103 fprintf(stderr,"vbi: open failed [%s]\n",dev);
104 return NULL;
105 }
106
107 int
108 vbi_hasdata(struct vbi_state *vbi)
109 {
110 char buf[1];
111 int rc;
112
113 if (vbi->sim) {
114 read(vbi->fd,buf,1);
115 read_sim(vbi->raw, vbi->sliced, &vbi->lines, &vbi->ts);
116 rc = 1;
117 } else {
118 rc = vbi_capture_read(vbi->cap, vbi->raw, vbi->sliced,
119 &vbi->lines, &vbi->ts, &vbi->tv);
120 }
121 vbi_decode(vbi->dec, vbi->sliced, vbi->lines, vbi->ts);
122 return rc;
123 }
124
125 void
126 vbi_close(struct vbi_state *vbi)
127 {
128 if (vbi) {
129 if (vbi->sliced)
130 free(vbi->sliced);
131 if (vbi->raw)
132 free(vbi->raw);
133 if (vbi->cap)
134 vbi_capture_delete(vbi->cap);
135 if (vbi->dec)
136 vbi_decoder_delete(vbi->dec);
137 free(vbi);
138 }
139 }
140
141 void
142 vbi_dump_event(struct vbi_event *ev, void *user)
143 {
144 switch (ev->type) {
145 case VBI_EVENT_TTX_PAGE:
146 fprintf(stderr,"vbi ev: ttx page %03x.%02x \r",
147 ev->ev.ttx_page.pgno,
148 ev->ev.ttx_page.subno);
149 break;
150 case VBI_EVENT_CLOSE:
151 fprintf(stderr,"vbi ev: close \n");
152 break;
153 case VBI_EVENT_CAPTION:
154 fprintf(stderr,"vbi ev: caption \n");
155 break;
156 case VBI_EVENT_NETWORK:
157 fprintf(stderr,"vbi ev: network id=%d name=\"%s\" call=\"%s\"\n",
158 ev->ev.network.nuid,
159 ev->ev.network.name,
160 ev->ev.network.call);
161 break;
162 case VBI_EVENT_TRIGGER:
163 switch (ev->ev.trigger->type) {
164 case VBI_LINK_NONE:
165 fprintf(stderr,"vbi ev: trigger none \n");
166 break;
167 case VBI_LINK_MESSAGE:
168 fprintf(stderr,"vbi ev: trigger message \n");
169 break;
170 case VBI_LINK_PAGE:
171 fprintf(stderr,"vbi ev: trigger page [%03x.%02x]\n",
172 ev->ev.trigger->pgno,
173 ev->ev.trigger->subno);
174 break;
175 case VBI_LINK_SUBPAGE:
176 fprintf(stderr,"vbi ev: trigger subpage \n");
177 break;
178 case VBI_LINK_HTTP:
179 fprintf(stderr,"vbi ev: trigger http [%s]\n",
180 ev->ev.trigger->url);
181 break;
182 case VBI_LINK_FTP:
183 fprintf(stderr,"vbi ev: trigger ftp \n");
184 break;
185 case VBI_LINK_EMAIL:
186 fprintf(stderr,"vbi ev: trigger email \n");
187 break;
188 case VBI_LINK_LID:
189 fprintf(stderr,"vbi ev: trigger lid \n");
190 break;
191 case VBI_LINK_TELEWEB:
192 fprintf(stderr,"vbi ev: trigger teleweb \n");
193 break;
194 }
195 break;
196 case VBI_EVENT_ASPECT:
197 fprintf(stderr,"vbi ev: aspect \n");
198 break;
199 case VBI_EVENT_PROG_INFO:
200 fprintf(stderr,"vbi ev: prog info \n");
201 break;
202 default:
203 fprintf(stderr,"vbi ev: UNKNOWN[0x%x] \n",ev->type);
204 break;
205 }
206 }
207
208 int vbi_calc_page(int pagenr, int offset)
209 {
210 int result;
211
212 result = pagenr + offset;
213 if (offset < 0) {
214 while ((result & 0x0f) > 0x09)
215 result -= 0x01;
216 while ((result & 0xf0) > 0x90)
217 result -= 0x10;
218 if (result < 0x100)
219 result = 0x100;
220 }
221 if (offset > 0) {
222 while ((result & 0x0f) > 0x09)
223 result += 0x01;
224 while ((result & 0xf0) > 0x90)
225 result += 0x10;
226 if (result > 0x899)
227 result = 0x899;
228 }
229 return result;
230 }
231
232 int vbi_calc_subpage(vbi_decoder *dec, int pgno, int subno, int offset)
233 {
234 vbi_page pg;
235 int newno;
236
237 for (newno = subno+offset; newno != subno;) {
238 if (vbi_fetch_vt_page(dec,&pg,pgno,newno,
239 VBI_WST_LEVEL_1,0,0))
240 break;
241 if (offset < 0) {
242 newno--;
243 if (newno < 0)
244 newno += VBI_MAX_SUBPAGES;
245 while ((newno & 0x0f) > 0x09)
246 newno -= 0x01;
247 }
248 if (offset > 0) {
249 newno++;
250 while ((newno & 0x0f) > 0x09)
251 newno += 0x01;
252 if (newno >= VBI_MAX_SUBPAGES)
253 newno = 0;
254 }
255 }
256 return newno;
257 }
258
259 int vbi_export_txt(char *dest, char *charset, int size,
260 vbi_page *pg, struct vbi_rect *rect,
261 enum vbi_txt_colors color)
262 {
263 int x,y,rc;
264 size_t olen,ilen;
265 int fg,bg,len=0;
266 char *ibuf, *obuf;
267 vbi_char *ch;
268 wchar_t wch;
269 iconv_t ic;
270
271 ic = iconv_open(charset,"WCHAR_T");
272 if (NULL == ic)
273 return -1;
274
275 obuf = dest;
276 olen = size;
277 for (y = rect->y1; y < rect->y2; y++) {
278 ch = pg->text + 41*y;
279 fg = -1;
280 bg = -1;
281 for (x = rect->x1; x <= rect->x2; x++) {
282 if (x < rect->x2) {
283 wch = ch[x].unicode;
284 if (ch[x].size > VBI_DOUBLE_SIZE)
285 wch = ' ';
286 if (ch[x].conceal)
287 wch = ' ';
288 } else {
289 wch = '\n';
290 }
291 if (fg != ch[x].foreground || bg != ch[x].background) {
292 fg = ch[x].foreground;
293 bg = ch[x].background;
294 switch (color) {
295 case VBI_ANSICOLOR:
296 len = sprintf(obuf,"\033[%d;%dm",
297 30 + (fg & 7), 40 + (bg & 7));
298 break;
299 case VBI_NOCOLOR:
300 len = 0;
301 break;
302 }
303 olen -= len;
304 obuf += len;
305 }
306 ibuf = (char*)(&wch);
307 ilen = sizeof(wch);
308 retry:
309 rc = iconv(ic,&ibuf,&ilen,&obuf,&olen);
310 if (-1 == rc && EILSEQ == errno && wch != '?') {
311 if (vbi_is_gfx(wch))
312 wch = '#';
313 else
314 wch = '?';
315 goto retry;
316 }
317 if (-1 == rc)
318 goto done;
319 }
320 switch (color) {
321 case VBI_ANSICOLOR:
322 len = sprintf(obuf,"\033[0m");
323 break;
324 case VBI_NOCOLOR:
325 len = 0;
326 break;
327 }
328 olen -= len;
329 obuf += len;
330 }
331
332 done:
333 return obuf - dest;
334 }
335
336 void vbi_find_subtitle(vbi_page *pg, struct vbi_rect *rect)
337 {
338 int x,y,showline;
339 vbi_char *ch;
340
341 *rect = vbi_fullrect;
342
343 for (y = 1; y < 25; y++) {
344 showline = 0;
345 ch = pg->text + 41*y;
346 for (x = 0; x <= 40; x++)
347 if (ch[x].unicode != ' ')
348 showline = 1;
349 if (showline)
350 break;
351 }
352 rect->y1 = y;
353
354 for (y = 25; y >= rect->y1; y--) {
355 showline = 0;
356 ch = pg->text + 41*y;
357 for (x = 0; x <= 40; x++)
358 if (ch[x].unicode != ' ')
359 showline = 1;
360 if (showline)
361 break;
362 }
363 rect->y2 = y+1;
364 }
365
366 #endif /* HAVE_ZVBI */
367
|
This page was automatically generated by the
LXR engine.
|