~ubuntu-branches/debian/lenny/italc/lenny

« back to all changes in this revision

Viewing changes to ica/x11/x11vnc/v4l.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-06-17 13:46:54 UTC
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20080617134654-2y5m7ki93r5c1ysf
Tags: upstream-1.0.9~rc3
ImportĀ upstreamĀ versionĀ 1.0.9~rc3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -- v4l.c -- */
 
2
 
 
3
#include "x11vnc.h"
 
4
#include "cleanup.h"
 
5
#include "scan.h"
 
6
#include "xinerama.h"
 
7
#include "screen.h"
 
8
#include "connections.h"
 
9
#include "keyboard.h"
 
10
#include "allowed_input_t.h"
 
11
 
 
12
#if LIBVNCSERVER_HAVE_LINUX_VIDEODEV_H
 
13
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
 
14
#include <sys/ioctl.h>
 
15
#define CONFIG_VIDEO_V4L1_COMPAT
 
16
#include <linux/videodev.h>
 
17
#define V4L_OK
 
18
#endif
 
19
#endif
 
20
 
 
21
char *v4l_guess(char *str, int *fd);
 
22
void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
 
23
void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client);
 
24
 
 
25
static int v4l1_val(int pct);
 
26
static int v4l1_width(int w);
 
27
static int v4l1_height(int h);
 
28
static int v4l1_resize(int fd, int w, int h);
 
29
static void v4l1_setfreq(int fd, unsigned long freq, int verb);
 
30
static void v4l1_set_input(int fd, int which);
 
31
static int v4l1_setfmt(int fd, char *fmt);
 
32
static void apply_settings(char *dev, char *settings, int *fd);
 
33
static int v4l1_dpct(int old, int d);
 
34
static void v4l_requery(void);
 
35
static void v4l_br(int b);
 
36
static void v4l_hu(int b);
 
37
static void v4l_co(int b);
 
38
static void v4l_cn(int b);
 
39
static void v4l_sz(int b);
 
40
static void v4l_sta(int sta);
 
41
static void v4l_inp(int inp);
 
42
static void v4l_fmt(char *fmt);
 
43
static int colon_n(char *line);
 
44
static char *colon_str(char *line);
 
45
static char *colon_tag(char *line);
 
46
static void lookup_rgb(char *g_fmt, int *g_b, int *mask_rev);
 
47
static char *v4l1_lu_palette(unsigned short palette);
 
48
static unsigned short v4l1_lu_palette_str(char *name, int *bits, int *rev);
 
49
static char *v4l2_lu_palette(unsigned int palette);
 
50
static unsigned int v4l2_lu_palette_str(char *name, int *bits, int *rev);
 
51
static int v4l1_query(int fd, int verbose);
 
52
static int v4l2_query(int fd, int verbose);
 
53
static int open_dev(char *dev);
 
54
static char *guess_via_v4l(char *dev, int *fd);
 
55
static char *guess_via_v4l_info(char *dev, int *fd);
 
56
static void parse_str(char *str, char **dev, char **settings, char **atparms);
 
57
static unsigned long lookup_freqtab(int sta);
 
58
static unsigned long lookup_freq(int sta);
 
59
static int lookup_station(unsigned long freq);
 
60
static void init_freqtab(char *file);
 
61
static void init_freqs(void);
 
62
static void init_ntsc_cable(void);
 
63
 
 
64
#define C_VIDEO_CAPTURE 1
 
65
#define C_PICTURE       2
 
66
#define C_WINDOW        3 
 
67
 
 
68
#ifdef V4L_OK
 
69
static struct video_capability  v4l1_capability;
 
70
static struct video_channel     v4l1_channel;
 
71
static struct video_tuner       v4l1_tuner;
 
72
static struct video_picture     v4l1_picture;
 
73
static struct video_window      v4l1_window;
 
74
 
 
75
#if HAVE_V4L2
 
76
static struct v4l2_capability   v4l2_capability;
 
77
static struct v4l2_input        v4l2_input;
 
78
static struct v4l2_tuner        v4l2_tuner;
 
79
static struct v4l2_fmtdesc      v4l2_fmtdesc;
 
80
static struct v4l2_format       v4l2_format;
 
81
/*static struct v4l2_framebuffer  v4l2_fbuf; */
 
82
/*static struct v4l2_queryctrl    v4l2_qctrl; */
 
83
#endif
 
84
#endif
 
85
 
 
86
static int v4l1_cap = -1;
 
87
static int v4l2_cap = -1;
 
88
#define V4L1_MAX 65535
 
89
 
 
90
#define CHANNEL_MAX 500
 
91
static unsigned long ntsc_cable[CHANNEL_MAX];
 
92
static unsigned long custom_freq[CHANNEL_MAX];
 
93
 
 
94
static unsigned long last_freq = 0;
 
95
static int last_channel = 0;
 
96
 
 
97
static int v4l1_val(int pct) {
 
98
        /* pct is % */
 
99
        int val, max = V4L1_MAX; 
 
100
        if (pct < 0) {
 
101
                return 0;
 
102
        } else if (pct > 100) {
 
103
                return max;
 
104
        }
 
105
        val = (pct * max)/100;
 
106
 
 
107
        return val;
 
108
}
 
109
static int v4l1_width(int w) {
 
110
#ifdef V4L_OK
 
111
        int min = v4l1_capability.minwidth;
 
112
        int max = v4l1_capability.maxwidth;
 
113
        if (w < min) {
 
114
                w = min;
 
115
        }
 
116
        if (w > max) {
 
117
                w = max;
 
118
        }
 
119
#endif
 
120
        return w;
 
121
}
 
122
static int v4l1_height(int h) {
 
123
#ifdef V4L_OK
 
124
        int min = v4l1_capability.minheight;
 
125
        int max = v4l1_capability.maxheight;
 
126
        if (h < min) {
 
127
                h = min;
 
128
        }
 
129
        if (h > max) {
 
130
                h = max;
 
131
        }
 
132
#endif
 
133
        return h;
 
134
}
 
135
 
 
136
static int v4l1_resize(int fd, int w, int h) {
 
137
#ifdef V4L_OK
 
138
        int dowin = 0;
 
139
 
 
140
        memset(&v4l1_window, 0, sizeof(v4l1_window));
 
141
        if (ioctl(fd, VIDIOCGWIN, &v4l1_window) == -1) {
 
142
                return 0;
 
143
        }
 
144
 
 
145
        if (w > 0) w = v4l1_width(w);
 
146
 
 
147
        if (w > 0 && w != (int) v4l1_window.width) {
 
148
                dowin = 1;
 
149
        }
 
150
 
 
151
        if (h > 0) h = v4l1_height(h);
 
152
 
 
153
        if (h > 0 && h != (int) v4l1_window.height) {
 
154
                dowin = 1;
 
155
        }
 
156
 
 
157
        if (dowin) {
 
158
                v4l1_window.x = 0;
 
159
                v4l1_window.y = 0;
 
160
                ioctl(fd, VIDIOCSWIN, &v4l1_window);
 
161
                if (w > 0) v4l1_window.width = w;
 
162
                if (h > 0) v4l1_window.height = h;
 
163
                fprintf(stderr, "calling V4L_1: VIDIOCSWIN\n");
 
164
                fprintf(stderr, "trying new size %dx%d\n",
 
165
                    v4l1_window.width, v4l1_window.height);
 
166
                if (ioctl(fd, VIDIOCSWIN, &v4l1_window) == -1) {
 
167
                        perror("ioctl VIDIOCSWIN");
 
168
                        return 0;
 
169
                }
 
170
        }
 
171
#else
 
172
        if (!fd || !w || !h) {}
 
173
#endif
 
174
        return 1;
 
175
}
 
176
 
 
177
static void v4l1_setfreq(int fd, unsigned long freq, int verb) {
 
178
#ifdef V4L_OK
 
179
        unsigned long f0, f1;
 
180
        f1 = (freq * 16) / 1000;
 
181
        ioctl(fd, VIDIOCGFREQ, &f0);
 
182
        if (verb) fprintf(stderr, "read freq: %d\n", (int) f0);
 
183
        if (freq > 0) {
 
184
                if (ioctl(fd, VIDIOCSFREQ, &f1) == -1) {
 
185
                        perror("ioctl VIDIOCSFREQ");
 
186
                } else {
 
187
                        ioctl(fd, VIDIOCGFREQ, &f0);
 
188
                        if (verb) fprintf(stderr, "read freq: %d\n", (int) f0);
 
189
                        last_freq = freq;
 
190
                }
 
191
        }
 
192
#else
 
193
        if (!fd || !freq || !verb) {}
 
194
#endif
 
195
}
 
196
 
 
197
static void v4l1_set_input(int fd, int which) {
 
198
#ifdef V4L_OK
 
199
        if (which != -1) {
 
200
                memset(&v4l1_channel, 0, sizeof(v4l1_channel));
 
201
                v4l1_channel.channel = which;
 
202
                if (ioctl(fd, VIDIOCGCHAN, &v4l1_channel) != -1) {
 
203
                        v4l1_channel.channel = which;
 
204
                        fprintf(stderr, "setting input channel to %d: %s\n",
 
205
                            which, v4l1_channel.name);
 
206
                        last_channel = which;
 
207
                        ioctl(fd, VIDIOCSCHAN, &v4l1_channel);
 
208
                }
 
209
        }
 
210
#else
 
211
        if (!fd || !which) {}
 
212
#endif
 
213
}
 
214
 
 
215
static int v4l1_setfmt(int fd, char *fmt) {
 
216
#ifdef V4L_OK
 
217
        unsigned short fnew;
 
218
        int bnew, rnew;
 
219
 
 
220
        fnew = v4l1_lu_palette_str(fmt, &bnew, &rnew);
 
221
        if (fnew) {
 
222
                v4l1_picture.depth = bnew; 
 
223
                v4l1_picture.palette = fnew;
 
224
        }
 
225
        fprintf(stderr, "calling V4L_1: VIDIOCSPICT\n");
 
226
        if (ioctl(fd, VIDIOCSPICT, &v4l1_picture) == -1) {
 
227
                perror("ioctl VIDIOCSPICT");
 
228
                return 0;
 
229
        }
 
230
        if (raw_fb_pixfmt) {
 
231
                free(raw_fb_pixfmt);
 
232
        }
 
233
        raw_fb_pixfmt = strdup(fmt);
 
234
#else
 
235
        if (!fd || !fmt) {}
 
236
#endif
 
237
        return 1;
 
238
}
 
239
 
 
240
static int ignore_all = 0;
 
241
 
 
242
static void apply_settings(char *dev, char *settings, int *fd) {
 
243
#ifdef V4L_OK
 
244
        char *str, *p, *fmt = NULL, *tun = NULL, *inp = NULL;
 
245
        int br = -1, co = -1, cn = -1, hu = -1;
 
246
        int w = -1, h = -1, b = -1;
 
247
        int sta = -1;
 
248
        int setcnt = 0;
 
249
        if (! settings || settings[0] == '\0') {
 
250
                return;
 
251
        }
 
252
        str = strdup(settings);
 
253
        p = strtok(str, ",");
 
254
        while (p) {
 
255
                if (strstr(p, "br=") == p) {
 
256
                        br = atoi(p+3);
 
257
                        if (br >= 0) setcnt++;
 
258
                } else if (strstr(p, "co=") == p) {
 
259
                        co = atoi(p+3);
 
260
                        if (co >= 0) setcnt++;
 
261
                } else if (strstr(p, "cn=") == p) {
 
262
                        cn = atoi(p+3);
 
263
                        if (cn >= 0) setcnt++;
 
264
                } else if (strstr(p, "hu=") == p) {
 
265
                        hu = atoi(p+3);
 
266
                        if (hu >= 0) setcnt++;
 
267
                } else if (strstr(p, "w=") == p) {
 
268
                        w = atoi(p+2);
 
269
                        if (w > 0) setcnt++;
 
270
                } else if (strstr(p, "h=") == p) {
 
271
                        h = atoi(p+2);
 
272
                        if (h > 0) setcnt++;
 
273
                } else if (strstr(p, "bpp=") == p) {
 
274
                        b = atoi(p+4);
 
275
                        if (b > 0) setcnt++;
 
276
                } else if (strstr(p, "fmt=") == p) {
 
277
                        fmt = strdup(p+4);
 
278
                        setcnt++;
 
279
                } else if (strstr(p, "tun=") == p) {
 
280
                        tun = strdup(p+4);
 
281
                        setcnt++;
 
282
                } else if (strstr(p, "inp=") == p) {
 
283
                        inp = strdup(p+4);
 
284
                        setcnt++;
 
285
                } else if (strstr(p, "sta=") == p) {
 
286
                        sta = atoi(p+4);
 
287
                        setcnt++;
 
288
                }
 
289
                p = strtok(NULL, ",");
 
290
        }
 
291
        free(str);
 
292
        if (! setcnt) {
 
293
                return;
 
294
        }
 
295
        if (*fd < 0) {
 
296
                *fd = open_dev(dev);
 
297
        }
 
298
        if (*fd < 0) {
 
299
                return;
 
300
        }
 
301
        v4l1_cap = v4l1_query(*fd, 1);
 
302
        v4l2_cap = v4l2_query(*fd, 1);
 
303
 
 
304
        if (v4l1_cap && ! ignore_all) {
 
305
                if (br >= 0) v4l1_picture.brightness = v4l1_val(br);
 
306
                if (hu >= 0) v4l1_picture.hue        = v4l1_val(hu);
 
307
                if (co >= 0) v4l1_picture.colour     = v4l1_val(co);
 
308
                if (cn >= 0) v4l1_picture.contrast   = v4l1_val(cn);
 
309
 
 
310
                fprintf(stderr, "calling V4L_1: VIDIOCSPICT\n");
 
311
                if (ioctl(*fd, VIDIOCSPICT, &v4l1_picture) == -1) {
 
312
                        perror("ioctl VIDIOCSPICT");
 
313
                }
 
314
 
 
315
                if (fmt) {
 
316
                        v4l1_setfmt(*fd, fmt);
 
317
                } else if (b > 0 && b != v4l1_picture.depth) {
 
318
                        if (b == 8) {
 
319
                                v4l1_setfmt(*fd, "HI240");
 
320
                        } else if (b == 16) {
 
321
                                v4l1_setfmt(*fd, "RGB565");
 
322
                        } else if (b == 24) {
 
323
                                v4l1_setfmt(*fd, "RGB24");
 
324
                        } else if (b == 32) {
 
325
                                v4l1_setfmt(*fd, "RGB32");
 
326
                        }
 
327
                }
 
328
 
 
329
                v4l1_resize(*fd, w, h);
 
330
 
 
331
                if (tun) {
 
332
                        int mode = -1;
 
333
                        if (!strcasecmp(tun, "PAL")) {
 
334
                                mode = VIDEO_MODE_PAL;
 
335
                        } else if (!strcasecmp(tun, "NTSC")) {
 
336
                                mode = VIDEO_MODE_NTSC;
 
337
                        } else if (!strcasecmp(tun, "SECAM")) {
 
338
                                mode = VIDEO_MODE_SECAM;
 
339
                        } else if (!strcasecmp(tun, "AUTO")) {
 
340
                                mode = VIDEO_MODE_AUTO;
 
341
                        }
 
342
                        if (mode != -1) {
 
343
                                int i;
 
344
                                for (i=0; i< v4l1_capability.channels; i++) {
 
345
                                        memset(&v4l1_channel, 0, sizeof(v4l1_channel));
 
346
                                        v4l1_channel.channel = i;
 
347
                                        if (ioctl(*fd, VIDIOCGCHAN, &v4l1_channel) == -1) {
 
348
                                                continue;
 
349
                                        }
 
350
                                        if (! v4l1_channel.tuners) {
 
351
                                                continue;
 
352
                                        }
 
353
                                        if (v4l1_channel.norm == mode) {
 
354
                                                continue;
 
355
                                        }
 
356
                                        v4l1_channel.norm = mode;
 
357
                                        ioctl(*fd, VIDIOCSCHAN, &v4l1_channel);
 
358
                                }
 
359
                        }
 
360
                }
 
361
                if (inp) {
 
362
                        char s[2];
 
363
                        int i, chan = -1;
 
364
 
 
365
                        s[0] = inp[0];
 
366
                        s[1] = '\0';
 
367
                        if (strstr("0123456789", s)) {
 
368
                                chan = atoi(inp);
 
369
                        } else {
 
370
                                for (i=0; i< v4l1_capability.channels; i++) {
 
371
                                        memset(&v4l1_channel, 0, sizeof(v4l1_channel));
 
372
                                        v4l1_channel.channel = i;
 
373
                                        if (ioctl(*fd, VIDIOCGCHAN, &v4l1_channel) == -1) {
 
374
                                                continue;
 
375
                                        }
 
376
                                        if (!strcmp(v4l1_channel.name, inp)) {
 
377
                                                chan = i;
 
378
                                                break;
 
379
                                        }
 
380
                                }
 
381
                        }
 
382
                        v4l1_set_input(*fd, chan);
 
383
                }
 
384
                if (sta >= 0) {
 
385
                        unsigned long freq = lookup_freq(sta);
 
386
                        v4l1_setfreq(*fd, freq, 1);
 
387
                }
 
388
        }
 
389
        v4l1_cap = v4l1_query(*fd, 1);
 
390
        v4l2_cap = v4l2_query(*fd, 1);
 
391
#else
 
392
        if (!dev || !settings || !fd) {}
 
393
        return;
 
394
#endif
 
395
}
 
396
 
 
397
static double dval = 0.05;
 
398
 
 
399
static int v4l1_dpct(int old, int d) {
 
400
        int new, max = V4L1_MAX; 
 
401
        
 
402
        /* -1 and 1 are special cases for "small increments" */
 
403
        if (d == -1) {
 
404
                new = old - (int) (dval * max);
 
405
        } else if (d == 1) {
 
406
                new = old + (int) (dval * max);
 
407
        } else {
 
408
                new = (d * max)/100;
 
409
        }
 
410
        if (new < 0) {
 
411
                new = 0;
 
412
        }
 
413
        if (new > max) {
 
414
                new = max;
 
415
        }
 
416
        return new;
 
417
}
 
418
 
 
419
static void v4l_requery(void) {
 
420
        if (raw_fb_fd < 0) {
 
421
                return;
 
422
        }
 
423
        v4l1_cap = v4l1_query(raw_fb_fd, 1);
 
424
        v4l2_cap = v4l2_query(raw_fb_fd, 1);
 
425
}
 
426
        
 
427
static void v4l_br(int b) {
 
428
#ifdef V4L_OK
 
429
        int old = v4l1_picture.brightness;
 
430
 
 
431
        v4l1_picture.brightness = v4l1_dpct(old, b);
 
432
        ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
 
433
        v4l_requery();
 
434
#else
 
435
        if (!b) {}
 
436
#endif
 
437
}
 
438
 
 
439
static void v4l_hu(int b) {
 
440
#ifdef V4L_OK
 
441
        int old = v4l1_picture.hue;
 
442
 
 
443
        v4l1_picture.hue = v4l1_dpct(old, b);
 
444
        ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
 
445
        v4l_requery();
 
446
#else
 
447
        if (!b) {}
 
448
#endif
 
449
}
 
450
 
 
451
static void v4l_co(int b) {
 
452
#ifdef V4L_OK
 
453
        int old = v4l1_picture.colour;
 
454
 
 
455
        v4l1_picture.colour = v4l1_dpct(old, b);
 
456
        ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
 
457
        v4l_requery();
 
458
#else
 
459
        if (!b) {}
 
460
#endif
 
461
}
 
462
 
 
463
static void v4l_cn(int b) {
 
464
#ifdef V4L_OK
 
465
        int old = v4l1_picture.contrast;
 
466
 
 
467
        v4l1_picture.contrast = v4l1_dpct(old, b);
 
468
        ioctl(raw_fb_fd, VIDIOCSPICT, &v4l1_picture);
 
469
        v4l_requery();
 
470
#else
 
471
        if (!b) {}
 
472
#endif
 
473
}
 
474
 
 
475
static void v4l_sz(int b) {
 
476
#ifdef V4L_OK
 
477
        int w_old = v4l1_window.width;
 
478
        int h_old = v4l1_window.height;
 
479
        int w, h;
 
480
 
 
481
        if (w_old == 0) {
 
482
                w_old = 160;
 
483
        }
 
484
        if (h_old == 0) {
 
485
                h_old = 120;
 
486
        }
 
487
 
 
488
        if (b == 1) {
 
489
                w = w_old + (int) (0.15 * w_old); 
 
490
                h = h_old + (int) (0.15 * h_old); 
 
491
        } else if (b == -1) {
 
492
                w = w_old - (int) (0.15 * w_old); 
 
493
                h = h_old - (int) (0.15 * h_old); 
 
494
        } else {
 
495
                return;
 
496
        }
 
497
 
 
498
        if (! v4l1_resize(raw_fb_fd, w, h)) {
 
499
                return;
 
500
        }
 
501
 
 
502
        v4l_requery();
 
503
 
 
504
        push_black_screen(4);
 
505
 
 
506
        ignore_all = 1;
 
507
        do_new_fb(1);
 
508
        ignore_all = 0;
 
509
#else
 
510
        if (!b) {}
 
511
#endif
 
512
}
 
513
 
 
514
static void v4l_sta(int sta) {
 
515
#ifdef V4L_OK
 
516
        unsigned long freq = 0;
 
517
        int cur = lookup_station(last_freq);
 
518
 
 
519
        if (! last_freq) {
 
520
                if (sta == 0 || sta == -1) {
 
521
                        sta = 11;
 
522
                }
 
523
        }
 
524
 
 
525
        if (sta == -1) {
 
526
                while (cur > 0) {
 
527
                        freq = lookup_freq(--cur);
 
528
                        if (freq) {
 
529
                                break;
 
530
                        }
 
531
                }
 
532
        } else if (sta == 0) {
 
533
                while (cur < CHANNEL_MAX - 1) {
 
534
                        freq = lookup_freq(++cur);
 
535
                        if (freq) {
 
536
                                break;
 
537
                        }
 
538
                }
 
539
        } else {
 
540
                freq = lookup_freq(sta);
 
541
                cur = sta;
 
542
        }
 
543
        fprintf(stderr, "to station %d / %d\n", cur, (int) freq);
 
544
        v4l1_setfreq(raw_fb_fd, freq, 0);
 
545
#else
 
546
        if (!sta) {}
 
547
#endif
 
548
}
 
549
 
 
550
static void v4l_inp(int inp) {
 
551
#ifdef V4L_OK
 
552
        int next = -1;
 
553
        if (inp == -1) {
 
554
                inp = last_channel + 1;
 
555
                if (inp >= v4l1_capability.channels) {
 
556
                        inp = 0;
 
557
                }
 
558
                next = inp;
 
559
        } else if (inp == -2) {
 
560
                inp = last_channel - 1;
 
561
                if (inp < 0) {
 
562
                        inp = v4l1_capability.channels - 1;
 
563
                }
 
564
                next = inp;
 
565
        } else {
 
566
                next = inp;
 
567
        }
 
568
        v4l1_set_input(raw_fb_fd, next);
 
569
#else
 
570
        if (!inp) {}
 
571
#endif
 
572
}
 
573
 
 
574
static void v4l_fmt(char *fmt) {
 
575
        if (v4l1_setfmt(raw_fb_fd, fmt)) {
 
576
                v4l_requery();
 
577
 
 
578
                ignore_all = 1;
 
579
                do_new_fb(1);
 
580
                ignore_all = 0;
 
581
        }
 
582
}
 
583
 
 
584
void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
 
585
        allowed_input_t input;
 
586
 
 
587
        if (raw_fb_fd < 0) {
 
588
                return;         
 
589
        }
 
590
        if (! down) {
 
591
                return;
 
592
        }
 
593
        if (view_only) {
 
594
                return;
 
595
        }
 
596
        get_allowed_input(client, &input);
 
597
        if (! input.keystroke) {
 
598
                return;
 
599
        }
 
600
 
 
601
        if (keysym == XK_b) {
 
602
                v4l_br(-1);
 
603
        } else if (keysym == XK_B) {
 
604
                v4l_br(+1);
 
605
        } else if (keysym == XK_h) {
 
606
                v4l_hu(-1);
 
607
        } else if (keysym == XK_H) {
 
608
                v4l_hu(+1);
 
609
        } else if (keysym == XK_c) {
 
610
                v4l_co(-1);
 
611
        } else if (keysym == XK_C) {
 
612
                v4l_co(+1);
 
613
        } else if (keysym == XK_n) {
 
614
                v4l_cn(-1);
 
615
        } else if (keysym == XK_N) {
 
616
                v4l_cn(+1);
 
617
        } else if (keysym == XK_s) {
 
618
                v4l_sz(-1);
 
619
        } else if (keysym == XK_S) {
 
620
                v4l_sz(+1);
 
621
        } else if (keysym == XK_i) {
 
622
                v4l_inp(-1);
 
623
        } else if (keysym == XK_I) {
 
624
                v4l_inp(-2);
 
625
        } else if (keysym == XK_Up) {
 
626
                v4l_sta(+0);
 
627
        } else if (keysym == XK_Down) {
 
628
                v4l_sta(-1);
 
629
        } else if (keysym == XK_F1) {
 
630
                v4l_fmt("HI240");
 
631
        } else if (keysym == XK_F2) {
 
632
                v4l_fmt("RGB565");
 
633
        } else if (keysym == XK_F3) {
 
634
                v4l_fmt("RGB24");
 
635
        } else if (keysym == XK_F4) {
 
636
                v4l_fmt("RGB32");
 
637
        } else if (keysym == XK_F5) {
 
638
                v4l_fmt("RGB555");
 
639
        } else if (keysym == XK_F6) {
 
640
                v4l_fmt("GREY");
 
641
        }
 
642
        if (client) {}
 
643
}
 
644
 
 
645
 
 
646
void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client) {
 
647
        /* do not forget viewonly perms */
 
648
        if (mask || x || y || client) {}
 
649
}
 
650
 
 
651
static int colon_n(char *line) {
 
652
        char *q;
 
653
        int n;
 
654
        q = strrchr(line, ':');
 
655
        if (! q) {
 
656
                return 0;
 
657
        }
 
658
        q = lblanks(q+1);
 
659
        if (sscanf(q, "%d", &n) == 1) {
 
660
                return n;
 
661
        }
 
662
        return 0;
 
663
}
 
664
 
 
665
static char *colon_str(char *line) {
 
666
        char *q, *p, *t;
 
667
        q = strrchr(line, ':');
 
668
        if (! q) {
 
669
                return strdup("");
 
670
        }
 
671
        q = lblanks(q+1);
 
672
        p = strpbrk(q, " \t\n");
 
673
        if (p) {
 
674
                *p = '\0';
 
675
        }
 
676
        t = strdup(q);
 
677
        *p = '\n';
 
678
        return t;
 
679
}
 
680
 
 
681
static char *colon_tag(char *line) {
 
682
        char *q, *p, *t;
 
683
        q = strrchr(line, '[');
 
684
        if (! q) {
 
685
                return strdup("");
 
686
        }
 
687
        q++;
 
688
        p = strrchr(q, ']');
 
689
        if (! p) {
 
690
                return strdup("");
 
691
        }
 
692
        *p = '\0';
 
693
        t = strdup(q);
 
694
        *p = ']';
 
695
        return t;
 
696
}
 
697
 
 
698
static void lookup_rgb(char *fmt, int *bits, int *rev) {
 
699
        int tb, tr;
 
700
 
 
701
        if (v4l2_lu_palette_str(fmt, &tb, &tr)) {
 
702
                *bits = tb;
 
703
                *rev  = tr;
 
704
                return;
 
705
        }
 
706
        if (v4l1_lu_palette_str(fmt, &tb, &tr)) {
 
707
                *bits = tb;
 
708
                *rev  = tr;
 
709
                return;
 
710
        }
 
711
}
 
712
 
 
713
static char *v4l1_lu_palette(unsigned short palette) {
 
714
        switch(palette) {
 
715
#ifdef V4L_OK
 
716
                case VIDEO_PALETTE_GREY:        return "GREY";
 
717
                case VIDEO_PALETTE_HI240:       return "HI240";
 
718
                case VIDEO_PALETTE_RGB565:      return "RGB565";
 
719
                case VIDEO_PALETTE_RGB24:       return "RGB24";
 
720
                case VIDEO_PALETTE_RGB32:       return "RGB32";
 
721
                case VIDEO_PALETTE_RGB555:      return "RGB555";
 
722
                case VIDEO_PALETTE_YUV422:      return "YUV422";
 
723
                case VIDEO_PALETTE_YUYV:        return "YUYV";
 
724
                case VIDEO_PALETTE_UYVY:        return "UYVY";
 
725
                case VIDEO_PALETTE_YUV420:      return "YUV420";
 
726
                case VIDEO_PALETTE_YUV411:      return "YUV411";
 
727
                case VIDEO_PALETTE_RAW:         return "RAW";
 
728
                case VIDEO_PALETTE_YUV422P:     return "YUV422P";
 
729
                case VIDEO_PALETTE_YUV411P:     return "YUV411P";
 
730
                case VIDEO_PALETTE_YUV420P:     return "YUV420P";
 
731
                case VIDEO_PALETTE_YUV410P:     return "YUV410P";
 
732
#endif
 
733
                default:                        return "unknown";
 
734
        }
 
735
}
 
736
 
 
737
static unsigned short v4l1_lu_palette_str(char *name, int *bits, int *rev) {
 
738
#ifdef V4L_OK
 
739
        *rev = 0;
 
740
        if (!strcmp(name, "RGB555")) {
 
741
                *bits = 16;
 
742
                return VIDEO_PALETTE_RGB555;
 
743
        } else if (!strcmp(name, "RGB565")) {
 
744
                *bits = 16;
 
745
                return VIDEO_PALETTE_RGB565;
 
746
        } else if (!strcmp(name, "RGB24")) {
 
747
                *bits = 24;
 
748
                return VIDEO_PALETTE_RGB24;
 
749
        } else if (!strcmp(name, "RGB32")) {
 
750
                *bits = 32;
 
751
                return VIDEO_PALETTE_RGB32;
 
752
        } else if (!strcmp(name, "HI240")) {
 
753
                *bits = 8;
 
754
                return VIDEO_PALETTE_HI240;
 
755
        } else if (!strcmp(name, "GREY")) {
 
756
                *bits = 8;
 
757
                return VIDEO_PALETTE_GREY;
 
758
        }
 
759
#else
 
760
        if (!name || !bits || !rev) {}
 
761
#endif
 
762
        return 0;
 
763
}
 
764
 
 
765
static char *v4l2_lu_palette(unsigned int fmt) {
 
766
        switch(fmt) {
 
767
#if defined(V4L_OK) && HAVE_V4L2
 
768
                case V4L2_PIX_FMT_RGB332:       return "RGB332";
 
769
                case V4L2_PIX_FMT_RGB555:       return "RGB555";
 
770
                case V4L2_PIX_FMT_RGB565:       return "RGB565";
 
771
                case V4L2_PIX_FMT_RGB555X:      return "RGB555X";
 
772
                case V4L2_PIX_FMT_RGB565X:      return "RGB565X";
 
773
                case V4L2_PIX_FMT_BGR24:        return "BGR24";
 
774
                case V4L2_PIX_FMT_RGB24:        return "RGB24";
 
775
                case V4L2_PIX_FMT_BGR32:        return "BGR32";
 
776
                case V4L2_PIX_FMT_RGB32:        return "RGB32";
 
777
                case V4L2_PIX_FMT_GREY:         return "GREY";
 
778
                case V4L2_PIX_FMT_YVU410:       return "YVU410";
 
779
                case V4L2_PIX_FMT_YVU420:       return "YVU420";
 
780
                case V4L2_PIX_FMT_YUYV:         return "YUYV";
 
781
                case V4L2_PIX_FMT_UYVY:         return "UYVY";
 
782
                case V4L2_PIX_FMT_YUV422P:      return "YUV422P";
 
783
                case V4L2_PIX_FMT_YUV411P:      return "YUV411P";
 
784
                case V4L2_PIX_FMT_Y41P:         return "Y41P";
 
785
                case V4L2_PIX_FMT_NV12:         return "NV12";
 
786
                case V4L2_PIX_FMT_NV21:         return "NV21";
 
787
                case V4L2_PIX_FMT_YUV410:       return "YUV410";
 
788
                case V4L2_PIX_FMT_YUV420:       return "YUV420";
 
789
                case V4L2_PIX_FMT_YYUV:         return "YYUV";
 
790
                case V4L2_PIX_FMT_HI240:        return "HI240";
 
791
                case V4L2_PIX_FMT_MJPEG:        return "MJPEG";
 
792
                case V4L2_PIX_FMT_JPEG:         return "JPEG";
 
793
                case V4L2_PIX_FMT_DV:           return "DV";
 
794
                case V4L2_PIX_FMT_MPEG:         return "MPEG";
 
795
#endif
 
796
                default:                        return "unknown";
 
797
        }
 
798
}
 
799
 
 
800
static unsigned int v4l2_lu_palette_str(char *name, int *bits, int *rev) {
 
801
#if defined(V4L_OK) && HAVE_V4L2
 
802
        if (!strcmp(name, "RGB1") || !strcmp(name, "RGB332")) {
 
803
                *bits = 8;
 
804
                *rev = 0;
 
805
                return V4L2_PIX_FMT_RGB332;
 
806
        } else if (!strcmp(name, "RGBO") || !strcmp(name, "RGB555")) {
 
807
                *bits = 16;
 
808
                *rev = 0;
 
809
                return V4L2_PIX_FMT_RGB555;
 
810
        } else if (!strcmp(name, "RGBP") || !strcmp(name, "RGB565")) {
 
811
                *bits = 16;
 
812
                *rev = 0;
 
813
                return V4L2_PIX_FMT_RGB565;
 
814
        } else if (!strcmp(name, "RGBQ") || !strcmp(name, "RGB555X")) {
 
815
                *bits = 16;
 
816
                *rev = 1;
 
817
                return V4L2_PIX_FMT_RGB555X;
 
818
        } else if (!strcmp(name, "RGBR") || !strcmp(name, "RGB565X")) {
 
819
                *bits = 16;
 
820
                *rev = 1;
 
821
                return V4L2_PIX_FMT_RGB565X;
 
822
        } else if (!strcmp(name, "BGR3") || !strcmp(name, "BGR24")) {
 
823
                *bits = 24;
 
824
                *rev = 1;
 
825
                return V4L2_PIX_FMT_BGR24;
 
826
        } else if (!strcmp(name, "RGB3") || !strcmp(name, "RGB24")) {
 
827
                *bits = 24;
 
828
                *rev = 0;
 
829
                return V4L2_PIX_FMT_RGB24;
 
830
        } else if (!strcmp(name, "BGR4") || !strcmp(name, "BGR32")) {
 
831
                *bits = 32;
 
832
                *rev = 1;
 
833
                return V4L2_PIX_FMT_BGR32;
 
834
        } else if (!strcmp(name, "RGB4") || !strcmp(name, "RGB32")) {
 
835
                *bits = 32;
 
836
                *rev = 0;
 
837
                return V4L2_PIX_FMT_RGB32;
 
838
        } else if (!strcmp(name, "GREY")) {
 
839
                *bits = 8;
 
840
                *rev = 0;
 
841
                return V4L2_PIX_FMT_GREY;
 
842
        }
 
843
#else
 
844
        if (!name || !bits || !rev) {}
 
845
#endif
 
846
        return 0;
 
847
}
 
848
 
 
849
static int v4l1_query(int fd, int v) {
 
850
#ifdef V4L_OK
 
851
        unsigned int i;
 
852
 
 
853
        memset(&v4l1_capability, 0, sizeof(v4l1_capability));
 
854
        memset(&v4l1_channel,    0, sizeof(v4l1_channel));
 
855
        memset(&v4l1_tuner,      0, sizeof(v4l1_tuner));
 
856
        memset(&v4l1_picture,    0, sizeof(v4l1_picture));
 
857
        memset(&v4l1_window,     0, sizeof(v4l1_window));
 
858
 
 
859
        if (v) fprintf(stderr, "\nV4L_1 query:\n");
 
860
#ifdef VIDIOCGCAP
 
861
        if (ioctl(fd, VIDIOCGCAP, &v4l1_capability) == -1) {
 
862
                perror("ioctl VIDIOCGCAP");
 
863
                fprintf(stderr, "\n");
 
864
                return 0;
 
865
        }
 
866
#else
 
867
        return 0;
 
868
#endif
 
869
        if (v) fprintf(stderr, "v4l-1 capability:\n");
 
870
        if (v) fprintf(stderr, "     name:      %s\n", v4l1_capability.name);
 
871
        if (v) fprintf(stderr, "     channels:  %d\n", v4l1_capability.channels);
 
872
        if (v) fprintf(stderr, "     audios:    %d\n", v4l1_capability.audios);
 
873
        if (v) fprintf(stderr, "     maxwidth:  %d\n", v4l1_capability.maxwidth);
 
874
        if (v) fprintf(stderr, "     maxheight: %d\n", v4l1_capability.maxheight);
 
875
        if (v) fprintf(stderr, "     minwidth:  %d\n", v4l1_capability.minwidth);
 
876
        if (v) fprintf(stderr, "     minheight: %d\n", v4l1_capability.minheight);
 
877
 
 
878
        for (i=0; (int) i < v4l1_capability.channels; i++) {
 
879
                char *type = "unknown";
 
880
                memset(&v4l1_channel, 0, sizeof(v4l1_channel));
 
881
                v4l1_channel.channel = i;
 
882
                if (ioctl(fd, VIDIOCGCHAN, &v4l1_channel) == -1) {
 
883
                        perror("ioctl VIDIOCGCHAN");
 
884
                        continue;
 
885
                }
 
886
                if (v4l1_channel.type == VIDEO_TYPE_TV) {
 
887
                        type = "TV";
 
888
                } else if (v4l1_channel.type == VIDEO_TYPE_CAMERA) {
 
889
                        type = "CAMERA";
 
890
                }
 
891
                if (v) fprintf(stderr, "     channel[%d]: %s\ttuners: %d norm: %d type: %d  %s\n",
 
892
                    i, v4l1_channel.name, v4l1_channel.tuners, v4l1_channel.norm,
 
893
                    v4l1_channel.type, type);
 
894
        }
 
895
 
 
896
        memset(&v4l1_tuner, 0, sizeof(v4l1_tuner));
 
897
        if (ioctl(fd, VIDIOCGTUNER, &v4l1_tuner) != -1) {
 
898
                char *mode = "unknown";
 
899
                if (v4l1_tuner.mode == VIDEO_MODE_PAL) {
 
900
                        mode = "PAL";
 
901
                } else if (v4l1_tuner.mode == VIDEO_MODE_NTSC) {
 
902
                        mode = "NTSC";
 
903
                } else if (v4l1_tuner.mode == VIDEO_MODE_SECAM) {
 
904
                        mode = "SECAM";
 
905
                } else if (v4l1_tuner.mode == VIDEO_MODE_AUTO) {
 
906
                        mode = "AUTO";
 
907
                }
 
908
 
 
909
                if (v) fprintf(stderr, "     tuner[%d]:   %s\tflags: 0x%x mode: %s\n",
 
910
                    v4l1_tuner.tuner, v4l1_tuner.name, v4l1_tuner.flags, mode);
 
911
                
 
912
        }
 
913
 
 
914
        if (ioctl(fd, VIDIOCGPICT, &v4l1_picture) == -1) {
 
915
                perror("ioctl VIDIOCGCHAN");
 
916
                return 0;
 
917
        }
 
918
        if (v) fprintf(stderr, "v4l-1 picture:\n");
 
919
        if (v) fprintf(stderr, "     brightness:  %d\n", v4l1_picture.brightness);
 
920
        if (v) fprintf(stderr, "     hue:         %d\n", v4l1_picture.hue);
 
921
        if (v) fprintf(stderr, "     colour:      %d\n", v4l1_picture.colour);
 
922
        if (v) fprintf(stderr, "     contrast:    %d\n", v4l1_picture.contrast);
 
923
        if (v) fprintf(stderr, "     whiteness:   %d\n", v4l1_picture.whiteness);
 
924
        if (v) fprintf(stderr, "     depth:       %d\n", v4l1_picture.depth);
 
925
        if (v) fprintf(stderr, "     palette:     %d  %s\n", v4l1_picture.palette,
 
926
            v4l1_lu_palette(v4l1_picture.palette));
 
927
        
 
928
        if (ioctl(fd, VIDIOCGWIN, &v4l1_window) == -1) {
 
929
                perror("ioctl VIDIOCGWIN");
 
930
                if (v) fprintf(stderr, "\n");
 
931
                return 0;
 
932
        }
 
933
        if (v) fprintf(stderr, "v4l-1 window:\n");
 
934
        if (v) fprintf(stderr, "     x:           %d\n", v4l1_window.x);
 
935
        if (v) fprintf(stderr, "     y:           %d\n", v4l1_window.y);
 
936
        if (v) fprintf(stderr, "     width:       %d\n", v4l1_window.width);
 
937
        if (v) fprintf(stderr, "     height:      %d\n", v4l1_window.height);
 
938
        if (v) fprintf(stderr, "     chromakey:   %d\n", v4l1_window.chromakey);
 
939
        if (v) fprintf(stderr, "\n");
 
940
 
 
941
        return 1;
 
942
#else
 
943
        if (!fd || !v) {}
 
944
        return 0;
 
945
#endif  /* V4L_OK */
 
946
 
 
947
}
 
948
static int v4l2_query(int fd, int v) {
 
949
#if defined(V4L_OK) && HAVE_V4L2
 
950
        unsigned int i;
 
951
 
 
952
        memset(&v4l2_capability, 0, sizeof(v4l2_capability));
 
953
        memset(&v4l2_input,      0, sizeof(v4l2_input));
 
954
        memset(&v4l2_tuner,      0, sizeof(v4l2_tuner));
 
955
        memset(&v4l2_fmtdesc,    0, sizeof(v4l2_fmtdesc));
 
956
        memset(&v4l2_format,     0, sizeof(v4l2_format));
 
957
 
 
958
        if (v) fprintf(stderr, "\nV4L_2 query:\n");
 
959
#ifdef VIDIOC_QUERYCAP
 
960
        if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2_capability) == -1) {
 
961
                perror("ioctl VIDIOC_QUERYCAP");
 
962
                if (v) fprintf(stderr, "\n");
 
963
                return 0;
 
964
        }
 
965
#else
 
966
        return 0;
 
967
#endif
 
968
 
 
969
        if (v) fprintf(stderr, "v4l-2 capability:\n");
 
970
        if (v) fprintf(stderr, "    driver:       %s\n", v4l2_capability.driver);
 
971
        if (v) fprintf(stderr, "    card:         %s\n", v4l2_capability.card);
 
972
        if (v) fprintf(stderr, "    bus_info:     %s\n", v4l2_capability.bus_info);
 
973
        if (v) fprintf(stderr, "    version:      %d\n", v4l2_capability.version);
 
974
        if (v) fprintf(stderr, "    capabilities: %u\n", v4l2_capability.capabilities);
 
975
 
 
976
        for (i=0; ; i++) {
 
977
                memset(&v4l2_input, 0, sizeof(v4l2_input));
 
978
                v4l2_input.index = i;
 
979
                if (ioctl(fd, VIDIOC_ENUMINPUT, &v4l2_input) == -1) {
 
980
                        break;
 
981
                }
 
982
                if (v) fprintf(stderr, "    input[%d]: %s\ttype: %d tuner: %d\n",
 
983
                    i, v4l2_input.name, v4l2_input.type, v4l2_input.tuner);
 
984
        }
 
985
        if (v4l2_capability.capabilities & V4L2_CAP_TUNER) {
 
986
                for (i=0; ; i++) {
 
987
                        memset(&v4l2_tuner, 0, sizeof(v4l2_tuner));
 
988
                        v4l2_tuner.index = i;
 
989
                        if (ioctl(fd, VIDIOC_G_TUNER, &v4l2_tuner) == -1) {
 
990
                                break;
 
991
                        }
 
992
                        if (v) fprintf(stderr, "    tuner[%d]: %s\ttype: %d\n",
 
993
                            i, v4l2_tuner.name, v4l2_tuner.type);
 
994
                }
 
995
        }
 
996
        if (v4l2_capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
 
997
                for (i=0; ; i++) {
 
998
                        memset(&v4l2_fmtdesc, 0, sizeof(v4l2_fmtdesc));
 
999
                        v4l2_fmtdesc.index = i;
 
1000
                        v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
1001
                        
 
1002
                        if (ioctl(fd, VIDIOC_ENUM_FMT, &v4l2_fmtdesc) == -1) {
 
1003
                                break;
 
1004
                        }
 
1005
                        if (v) fprintf(stderr, "    fmtdesc[%d]: %s\ttype: %d"
 
1006
                            " pixelformat: %d\n",
 
1007
                            i, v4l2_fmtdesc.description, v4l2_fmtdesc.type,
 
1008
                            v4l2_fmtdesc.pixelformat);
 
1009
                }
 
1010
                v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
1011
                if (ioctl(fd, VIDIOC_G_FMT, &v4l2_format) == -1) {
 
1012
                        perror("ioctl VIDIOC_G_FMT");
 
1013
                } else {
 
1014
                        if (v) fprintf(stderr, "    width:  %d\n", v4l2_format.fmt.pix.width);
 
1015
                        if (v) fprintf(stderr, "    height: %d\n", v4l2_format.fmt.pix.height);
 
1016
                        if (v) fprintf(stderr, "    format: %u %s\n",
 
1017
                            v4l2_format.fmt.pix.pixelformat,
 
1018
                            v4l2_lu_palette(v4l2_format.fmt.pix.pixelformat));
 
1019
                }
 
1020
        }
 
1021
 
 
1022
        return 1;
 
1023
#else
 
1024
        if (!fd || !v) {}
 
1025
        return 0;
 
1026
#endif  /* V4L_OK && HAVE_V4L2 */
 
1027
 
 
1028
}
 
1029
 
 
1030
static int open_dev(char *dev) {
 
1031
        int dfd = -1;
 
1032
        if (! dev) {
 
1033
                return dfd;
 
1034
        }
 
1035
        dfd = open(dev, O_RDWR);
 
1036
        if (dfd < 0) {
 
1037
                rfbLog("failed to rawfb file: %s O_RDWR\n", dev);
 
1038
                rfbLogPerror("open");
 
1039
                dfd = open(dev, O_RDONLY);
 
1040
        }
 
1041
        if (dfd < 0) {
 
1042
                rfbLog("failed to rawfb file: %s\n", dev);
 
1043
                rfbLog("failed to rawfb file: %s O_RDONLY\n", dev);
 
1044
                rfbLogPerror("open");
 
1045
        }
 
1046
        return dfd;
 
1047
}
 
1048
 
 
1049
static char *guess_via_v4l(char *dev, int *fd) {
 
1050
#ifdef V4L_OK
 
1051
        int dfd;
 
1052
        
 
1053
        if (*fd < 0) {
 
1054
                dfd = open_dev(dev);
 
1055
                *fd = dfd;
 
1056
        }
 
1057
        dfd = *fd;
 
1058
        if (dfd < 0) {
 
1059
                return NULL;
 
1060
        }
 
1061
        if (v4l1_cap < 0) {
 
1062
                v4l1_cap = v4l1_query(dfd, 1);
 
1063
        }
 
1064
        if (v4l2_cap < 0) {
 
1065
                v4l2_cap = v4l2_query(dfd, 1);
 
1066
        }
 
1067
 
 
1068
        if (v4l2_cap) {
 
1069
#if HAVE_V4L2
 
1070
                int g_w = v4l2_format.fmt.pix.width;
 
1071
                int g_h = v4l2_format.fmt.pix.height;
 
1072
                int g_d = 0, g_rev;
 
1073
 
 
1074
                if (v4l2_format.fmt.pix.pixelformat) {
 
1075
                        char *str = v4l2_lu_palette(v4l2_format.fmt.pix.pixelformat);
 
1076
                        if (strcmp(str, "unknown")) {
 
1077
                                v4l2_lu_palette_str(str, &g_d, &g_rev);
 
1078
                        }
 
1079
                }
 
1080
                
 
1081
                if (g_w > 0 && g_h > 0 && g_d > 0) {
 
1082
                        char *atparms = (char *) malloc(200);
 
1083
                        char *pal = v4l2_lu_palette(v4l2_format.fmt.pix.pixelformat);
 
1084
                        sprintf(atparms, "%dx%dx%d", g_w, g_h, g_d);
 
1085
                        if (strstr(pal, "RGB555")) {
 
1086
                                strcat(atparms, ":7c00/3e0/1f");
 
1087
                        }
 
1088
                        *fd = dfd;
 
1089
                        return atparms;
 
1090
                }
 
1091
#endif
 
1092
        }
 
1093
        if (v4l1_cap) {
 
1094
                int g_w = v4l1_window.width;
 
1095
                int g_h = v4l1_window.height;
 
1096
                int g_d = v4l1_picture.depth;
 
1097
                int g_rev;
 
1098
                if (g_d == 0) {
 
1099
                        char *str = v4l1_lu_palette(v4l1_picture.palette);
 
1100
                        if (strcmp(str, "unknown")) {
 
1101
                                v4l1_lu_palette_str(str, &g_d, &g_rev);
 
1102
                        }
 
1103
                }
 
1104
if (0) fprintf(stderr, "v4l1: %d %d %d\n", g_w, g_h, g_d);
 
1105
                if (g_w > 0 && g_h > 0 && g_d > 0) {
 
1106
                        char *atparms = (char *) malloc(200);
 
1107
                        char *pal = v4l1_lu_palette(v4l1_picture.palette);
 
1108
                        fprintf(stderr, "palette: %s\n", pal);
 
1109
                        sprintf(atparms, "%dx%dx%d", g_w, g_h, g_d);
 
1110
                        if (strstr(pal, "RGB555")) {
 
1111
                                strcat(atparms, ":7c00/3e0/1f");
 
1112
                        }
 
1113
                        *fd = dfd;
 
1114
                        return atparms;
 
1115
                }
 
1116
        }
 
1117
 
 
1118
        /* failure */
 
1119
        close(dfd);
 
1120
        return NULL;
 
1121
#else
 
1122
        if (!dev || !fd) {}
 
1123
        return NULL;
 
1124
#endif
 
1125
}
 
1126
 
 
1127
static char *guess_via_v4l_info(char *dev, int *fd) {
 
1128
        char *atparms, *cmd;
 
1129
        char line[1024], tmp[] = "/tmp/x11vnc-tmp.XXXXXX";
 
1130
        FILE *out;
 
1131
        int tmp_fd, len, rc, curr = 0;
 
1132
        int g_w = 0, g_h = 0, g_b = 0, mask_rev = 0;
 
1133
        char *g_fmt = NULL;
 
1134
 
 
1135
        if (*fd) {}
 
1136
 
 
1137
        /* v4l-info */
 
1138
        if (no_external_cmds || !cmd_ok("v4l-info")) {
 
1139
                rfbLog("guess_via_v4l_info: cannot run external "
 
1140
                    "command: v4l-info\n");
 
1141
                return NULL;
 
1142
        }
 
1143
 
 
1144
        if (strchr(dev, '\'')) {
 
1145
                rfbLog("guess_via_v4l_info: bad dev string: %s\n", dev);
 
1146
                return NULL;
 
1147
        }
 
1148
 
 
1149
        tmp_fd = mkstemp(tmp);
 
1150
        if (tmp_fd < 0) {
 
1151
                return NULL;
 
1152
        }
 
1153
 
 
1154
        len =  strlen("v4l-info")+1+1+strlen(dev)+1+1+1+1+strlen(tmp)+1; 
 
1155
        cmd = (char *) malloc(len);
 
1156
        rfbLog("guess_via_v4l_info running: v4l-info '%s'\n", dev);
 
1157
        sprintf(cmd, "v4l-info '%s' > %s", dev, tmp);
 
1158
 
 
1159
        close(tmp_fd);
 
1160
        close_exec_fds();
 
1161
        rc = system(cmd);
 
1162
        if (rc != 0) {
 
1163
                unlink(tmp);
 
1164
                return NULL;
 
1165
        }
 
1166
 
 
1167
        out = fopen(tmp, "r");
 
1168
        if (out == NULL) {
 
1169
                unlink(tmp);
 
1170
                return NULL;
 
1171
        }
 
1172
        
 
1173
        curr = 0;
 
1174
        while (fgets(line, 1024, out) != NULL) {
 
1175
                char *lb = lblanks(line);
 
1176
                if (strstr(line, "video capture") == line) {
 
1177
                        curr = C_VIDEO_CAPTURE;
 
1178
                } else if (strstr(line, "picture") == line) {
 
1179
                        curr = C_PICTURE;
 
1180
                } else if (strstr(line, "window") == line) {
 
1181
                        curr = C_WINDOW;
 
1182
                }
 
1183
 
 
1184
if (0) fprintf(stderr, "lb: %s", lb);
 
1185
 
 
1186
                if (curr == C_VIDEO_CAPTURE) {
 
1187
                        if (strstr(lb, "pixelformat ") == lb) {
 
1188
                                fprintf(stderr, "%s", line);
 
1189
                        } else if (strstr(lb, "fmt.pix.width ") == lb) {
 
1190
                                if (! g_w) {
 
1191
                                        g_w = colon_n(line);
 
1192
                                }
 
1193
                        } else if (strstr(lb, "fmt.pix.height ") == lb) {
 
1194
                                if (! g_h) {
 
1195
                                        g_h = colon_n(line);
 
1196
                                }
 
1197
                        } else if (strstr(lb, "fmt.pix.pixelformat ") == lb) {
 
1198
                                if (! g_fmt) {
 
1199
                                        g_fmt = colon_tag(line);
 
1200
                                }
 
1201
                        }
 
1202
                } else if (curr == C_PICTURE) {
 
1203
                        if (strstr(lb, "depth ") == lb) {
 
1204
                                if (! g_b) {
 
1205
                                        g_b = colon_n(line);
 
1206
                                }
 
1207
                        } else if (strstr(lb, "palette ") == lb) {
 
1208
                                if (! g_fmt) {
 
1209
                                        g_fmt = colon_str(line);
 
1210
                                }
 
1211
                        }
 
1212
                } else if (curr == C_WINDOW) {
 
1213
                        if (strstr(lb, "width ") == lb) {
 
1214
                                if (! g_w) {
 
1215
                                        g_w = colon_n(line);
 
1216
                                }
 
1217
                        } else if (strstr(lb, "height ") == lb) {
 
1218
                                if (! g_h) {
 
1219
                                        g_h = colon_n(line);
 
1220
                                }
 
1221
                        }
 
1222
                }
 
1223
        }
 
1224
        fclose(out);
 
1225
        unlink(tmp);
 
1226
 
 
1227
        if (! g_w) {
 
1228
                rfbLog("could not guess device width.\n");
 
1229
                return NULL;
 
1230
        }
 
1231
        rfbLog("guessed device width:  %d\n", g_w);
 
1232
 
 
1233
        if (! g_h) {
 
1234
                rfbLog("could not guess device height.\n");
 
1235
                return NULL;
 
1236
        }
 
1237
        rfbLog("guessed device height: %d\n", g_h);
 
1238
 
 
1239
        if (g_fmt) {
 
1240
                rfbLog("guessed pixel fmt:     %s\n", g_fmt);
 
1241
                lookup_rgb(g_fmt, &g_b, &mask_rev);
 
1242
        }
 
1243
        if (! g_b) {
 
1244
                rfbLog("could not guess device bpp.\n");
 
1245
                return NULL;
 
1246
        }
 
1247
        rfbLog("guessed device bpp:    %d\n", g_b);
 
1248
 
 
1249
        atparms = (char *) malloc(100);
 
1250
        sprintf(atparms, "%dx%dx%d", g_w, g_h, g_b);
 
1251
        return atparms;
 
1252
}
 
1253
 
 
1254
static void parse_str(char *str, char **dev, char **settings, char **atparms) {
 
1255
        char *p, *q, *s = NULL;
 
1256
 
 
1257
        q = strchr(str, '@');
 
1258
        if (q && strlen(q+1) > 0) {
 
1259
                /* ends @WxHXB... */
 
1260
                *atparms = strdup(q+1);
 
1261
                *q = '\0';
 
1262
        }
 
1263
 
 
1264
        q = strchr(str, ':');
 
1265
        if (q && strlen(q+1) > 0) {
 
1266
                /* ends :br=N,w=N... */
 
1267
                s = strdup(q+1);
 
1268
                *settings = s;
 
1269
                *q = '\0';
 
1270
        }
 
1271
 
 
1272
        if (s != NULL) {
 
1273
                /* see if fn=filename */
 
1274
                q = strstr(s, "fn=");
 
1275
                if (q) {
 
1276
                        q += strlen("fn=");
 
1277
                        p = strchr(q, ',');
 
1278
                        if (p) {
 
1279
                                *p = '\0';
 
1280
                                *dev = strdup(q); 
 
1281
                                *p = ',';
 
1282
                        } else {
 
1283
                                *dev = strdup(q); 
 
1284
                        }
 
1285
                        rfbLog("set video device to: '%s'\n", *dev);
 
1286
                }
 
1287
        }
 
1288
 
 
1289
        if (*dev == NULL) {
 
1290
                s = (char *) malloc(strlen("/dev/") + strlen(str) + 1);
 
1291
                if (strstr(str, "/dev/") == str) {
 
1292
                        sprintf(s, "%s", str);
 
1293
                } else {
 
1294
                        sprintf(s, "/dev/%s", str);
 
1295
                }
 
1296
                *dev = s;
 
1297
                rfbLog("set video device to: '%s'\n", *dev);
 
1298
        }
 
1299
}
 
1300
 
 
1301
char *v4l_guess(char *str, int *fd) {
 
1302
        char *dev = NULL, *settings = NULL, *atparms = NULL;
 
1303
 
 
1304
        parse_str(str, &dev, &settings, &atparms);
 
1305
 
 
1306
        init_freqs();
 
1307
 
 
1308
        v4l1_cap = -1;
 
1309
        v4l2_cap = -1;
 
1310
        *fd = -1;
 
1311
 
 
1312
        if (dev == NULL) {
 
1313
                rfbLog("v4l_guess: could not find device in: %s\n", str);
 
1314
                return NULL;
 
1315
        }
 
1316
 
 
1317
        if (settings) {
 
1318
                apply_settings(dev, settings, fd);
 
1319
        }
 
1320
 
 
1321
        if (atparms) {
 
1322
                /* use user's parameters. */
 
1323
                char *t = (char *) malloc(5+strlen(dev)+1+strlen(atparms)+1);
 
1324
                sprintf(t, "snap:%s@%s", dev, atparms);
 
1325
                return t;
 
1326
        }
 
1327
 
 
1328
        /* try to query the device for parameters. */
 
1329
        atparms = guess_via_v4l(dev, fd);
 
1330
        if (atparms == NULL) {
 
1331
                /* try again with v4l-info(1) */
 
1332
                atparms = guess_via_v4l_info(dev, fd);
 
1333
        }
 
1334
 
 
1335
        if (atparms == NULL) {
 
1336
                /* bad news */
 
1337
                if (*fd >= 0) {
 
1338
                        close(*fd);
 
1339
                }
 
1340
                *fd = -1;
 
1341
                return NULL;
 
1342
        } else {
 
1343
                char *t = (char *) malloc(5+strlen(dev)+1+strlen(atparms)+1);
 
1344
                sprintf(t, "snap:%s@%s", dev, atparms);
 
1345
                return t;
 
1346
        }
 
1347
}
 
1348
 
 
1349
static unsigned long lookup_freqtab(int sta) {
 
1350
 
 
1351
        if (sta >= CHANNEL_MAX) {
 
1352
                return (unsigned long) sta;
 
1353
        }
 
1354
        if (sta < 0 || sta >= CHANNEL_MAX) {
 
1355
                return 0;
 
1356
        }
 
1357
        return custom_freq[sta];
 
1358
}
 
1359
 
 
1360
static unsigned long lookup_freq(int sta) {
 
1361
        if (freqtab) {
 
1362
                return lookup_freqtab(sta);
 
1363
        }
 
1364
        if (sta >= CHANNEL_MAX) {
 
1365
                return (unsigned long) sta;
 
1366
        }
 
1367
        if (sta < 1 || sta > 125) {
 
1368
                return 0;
 
1369
        }
 
1370
        return ntsc_cable[sta];
 
1371
}
 
1372
 
 
1373
static int lookup_station(unsigned long freq) {
 
1374
        int i;
 
1375
        if (freqtab) {
 
1376
                for (i = 0; i < CHANNEL_MAX; i++) {
 
1377
if (0) fprintf(stderr, "%lu %lu\n", freq, custom_freq[i]);
 
1378
                        if (freq == custom_freq[i]) {
 
1379
                                return i;
 
1380
                        }
 
1381
                }
 
1382
        } else {
 
1383
                for (i = 1; i <= 125; i++) {
 
1384
                        if (freq == ntsc_cable[i]) {
 
1385
                                return i;
 
1386
                        }
 
1387
                }
 
1388
        }
 
1389
        return 0;
 
1390
}
 
1391
 
 
1392
static void init_freqtab(char *file) {
 
1393
        char *p, *q, *dir, *file2;
 
1394
        char line[1024], inc[1024];
 
1395
        char *text, *str;
 
1396
        int size = 0, maxn, extra, currn;
 
1397
        FILE *in1, *in2;
 
1398
        static int v = 1;
 
1399
        if (quiet) {
 
1400
                v = 0;
 
1401
        }
 
1402
 
 
1403
        /* YUCK */
 
1404
 
 
1405
        dir = strdup(file);
 
1406
        q = strrchr(dir, '/');
 
1407
        if (q) {
 
1408
                *(q+1) = '\0';
 
1409
        } else {
 
1410
                free(dir);
 
1411
                dir = strdup("./");
 
1412
        }
 
1413
        file2 = (char *) malloc(strlen(dir) + 1024 + 1);
 
1414
        in1 = fopen(file, "r");
 
1415
        if (in1 == NULL) {
 
1416
                rfbLog("error opening freqtab: %s\n", file);
 
1417
                clean_up_exit(1);
 
1418
        }
 
1419
        if (v) fprintf(stderr, "loading frequencies from: %s\n", file);
 
1420
        while (fgets(line, 1024, in1) != NULL) {
 
1421
                char *lb;
 
1422
                char line2[1024];
 
1423
                size += strlen(line);
 
1424
                lb = lblanks(line);
 
1425
                if (strstr(lb, "#include") == lb && 
 
1426
                    sscanf(lb, "#include %s", inc) == 1) {
 
1427
                        char *q, *s = inc;
 
1428
                        if (s[0] == '"') {
 
1429
                                s++;
 
1430
                        }
 
1431
                        q = strrchr(s, '"');
 
1432
                        if (q) {
 
1433
                                *q = '\0';
 
1434
                        }
 
1435
                        sprintf(file2, "%s%s", dir, s);
 
1436
                        in2 = fopen(file2, "r");
 
1437
                        if (in2 == NULL) {
 
1438
                                rfbLog("error opening freqtab include: %s %s\n", line, file2);
 
1439
                                clean_up_exit(1);
 
1440
                        }
 
1441
                        if (v) fprintf(stderr, "loading frequencies from: %s\n", file2);
 
1442
                        while (fgets(line2, 1024, in2) != NULL) {
 
1443
                                size += strlen(line2);
 
1444
                        }
 
1445
                        fclose(in2);
 
1446
                }
 
1447
        }
 
1448
        fclose(in1);
 
1449
 
 
1450
        size = 4*(size + 10000);
 
1451
 
 
1452
        text = (char *) malloc(size);
 
1453
 
 
1454
        text[0] = '\0';
 
1455
 
 
1456
        in1 = fopen(file, "r");
 
1457
        if (in1 == NULL) {
 
1458
                rfbLog("error opening freqtab: %s\n", file);
 
1459
                clean_up_exit(1);
 
1460
        }
 
1461
        while (fgets(line, 1024, in1) != NULL) {
 
1462
                char *lb;
 
1463
                char line2[1024];
 
1464
                lb = lblanks(line);
 
1465
                if (lb[0] == '[') {
 
1466
                        strcat(text, lb);
 
1467
                } else if (strstr(lb, "freq")) {
 
1468
                        strcat(text, lb);
 
1469
                } else if (strstr(lb, "#include") == lb && 
 
1470
                    sscanf(lb, "#include %s", inc) == 1) {
 
1471
                        char *lb2;
 
1472
                        char *q, *s = inc;
 
1473
                        if (s[0] == '"') {
 
1474
                                s++;
 
1475
                        }
 
1476
                        q = strrchr(s, '"');
 
1477
                        if (q) {
 
1478
                                *q = '\0';
 
1479
                        }
 
1480
                        sprintf(file2, "%s%s", dir, s);
 
1481
                        in2 = fopen(file2, "r");
 
1482
                        if (in2 == NULL) {
 
1483
                                rfbLog("error opening freqtab include: %s %s\n", line, file2);
 
1484
                                clean_up_exit(1);
 
1485
                        }
 
1486
                        while (fgets(line2, 1024, in2) != NULL) {
 
1487
                                lb2 = lblanks(line2);
 
1488
                                if (lb2[0] == '[') {
 
1489
                                        strcat(text, lb2);
 
1490
                                } else if (strstr(lb2, "freq")) {
 
1491
                                        strcat(text, lb2);
 
1492
                                }
 
1493
                                if ((int) strlen(text) > size/2) {
 
1494
                                        break;
 
1495
                                }
 
1496
                        }
 
1497
                        fclose(in2);
 
1498
                }
 
1499
                if ((int) strlen(text) > size/2) {
 
1500
                        break;
 
1501
                }
 
1502
        }
 
1503
        fclose(in1);
 
1504
 
 
1505
        if (0) fprintf(stderr, "%s", text);
 
1506
 
 
1507
        str = strdup(text);
 
1508
        p = strtok(str, "\n");
 
1509
        maxn = -1;
 
1510
        extra = 0;
 
1511
        while (p) {
 
1512
                if (p[0] == '[') {
 
1513
                        int ok = 1;
 
1514
                        q = p+1;        
 
1515
                        while (*q) {
 
1516
                                if (*q == ']') {
 
1517
                                        break;
 
1518
                                }
 
1519
                                if (! isdigit((unsigned char) (*q))) {
 
1520
                                        if (0) fprintf(stderr, "extra: %s\n", p);
 
1521
                                        extra++;
 
1522
                                        ok = 0;
 
1523
                                        break;
 
1524
                                }
 
1525
                                q++;
 
1526
                        }
 
1527
                        if (ok) {
 
1528
                                int n;
 
1529
                                if (sscanf(p, "[%d]", &n) == 1)  {
 
1530
                                        if (n > maxn) {
 
1531
                                                maxn = n;
 
1532
                                        }
 
1533
                                        if (0) fprintf(stderr, "maxn:  %d %d\n", maxn, n);
 
1534
                                }
 
1535
                        }
 
1536
                        
 
1537
                }
 
1538
                p = strtok(NULL, "\n");
 
1539
        }
 
1540
        free(str);
 
1541
 
 
1542
        str = strdup(text);
 
1543
        p = strtok(str, "\n");
 
1544
        extra = 0;
 
1545
        currn = 0;
 
1546
        if (v) fprintf(stderr, "\nname\tstation\tfreq (KHz)\n");
 
1547
        while (p) {
 
1548
                if (p[0] == '[') {
 
1549
                        int ok = 1;
 
1550
                        strncpy(line, p, 100);
 
1551
                        q = p+1;        
 
1552
                        while (*q) {
 
1553
                                if (*q == ']') {
 
1554
                                        break;
 
1555
                                }
 
1556
                                if (! isdigit((unsigned char) (*q))) {
 
1557
                                        extra++;
 
1558
                                        currn = maxn + extra;
 
1559
                                        ok = 0;
 
1560
                                        break;
 
1561
                                }
 
1562
                                q++;
 
1563
                        }
 
1564
                        if (ok) {
 
1565
                                int n;
 
1566
                                if (sscanf(p, "[%d]", &n) == 1)  {
 
1567
                                        currn = n;
 
1568
                                }
 
1569
                        }
 
1570
                }
 
1571
                if (strstr(p, "freq") && (q = strchr(p, '=')) != NULL) {
 
1572
                        int n;
 
1573
                        q = lblanks(q+1);
 
1574
                        if (sscanf(q, "%d", &n) == 1) {
 
1575
                                if (currn >= 0 && currn < CHANNEL_MAX) {
 
1576
                                        if (v) fprintf(stderr, "%s\t%d\t%d\n", line, currn, n);
 
1577
                                        custom_freq[currn] = (unsigned long) n;
 
1578
                                        if (last_freq == 0) {
 
1579
                                                last_freq = custom_freq[currn];
 
1580
                                        }
 
1581
                                }
 
1582
                        }
 
1583
                }
 
1584
                p = strtok(NULL, "\n");
 
1585
        }
 
1586
        if (v) fprintf(stderr, "\n");
 
1587
        v = 0;
 
1588
        free(str);
 
1589
        free(text);
 
1590
        free(dir);
 
1591
        free(file2);
 
1592
}
 
1593
 
 
1594
static void init_freqs(void) {
 
1595
        int i;
 
1596
        for (i=0; i<CHANNEL_MAX; i++) {
 
1597
                ntsc_cable[i] = 0;
 
1598
                custom_freq[i] = 0;
 
1599
        }
 
1600
 
 
1601
        init_ntsc_cable();
 
1602
        last_freq = ntsc_cable[1];
 
1603
 
 
1604
        if (freqtab) {
 
1605
                init_freqtab(freqtab);
 
1606
        }
 
1607
}
 
1608
 
 
1609
static void init_ntsc_cable(void) {
 
1610
        ntsc_cable[1] = 73250;
 
1611
        ntsc_cable[2] = 55250;
 
1612
        ntsc_cable[3] = 61250;
 
1613
        ntsc_cable[4] = 67250;
 
1614
        ntsc_cable[5] = 77250;
 
1615
        ntsc_cable[6] = 83250;
 
1616
        ntsc_cable[7] = 175250;
 
1617
        ntsc_cable[8] = 181250;
 
1618
        ntsc_cable[9] = 187250;
 
1619
        ntsc_cable[10] = 193250;
 
1620
        ntsc_cable[11] = 199250;
 
1621
        ntsc_cable[12] = 205250;
 
1622
        ntsc_cable[13] = 211250;
 
1623
        ntsc_cable[14] = 121250;
 
1624
        ntsc_cable[15] = 127250;
 
1625
        ntsc_cable[16] = 133250;
 
1626
        ntsc_cable[17] = 139250;
 
1627
        ntsc_cable[18] = 145250;
 
1628
        ntsc_cable[19] = 151250;
 
1629
        ntsc_cable[20] = 157250;
 
1630
        ntsc_cable[21] = 163250;
 
1631
        ntsc_cable[22] = 169250;
 
1632
        ntsc_cable[23] = 217250;
 
1633
        ntsc_cable[24] = 223250;
 
1634
        ntsc_cable[25] = 229250;
 
1635
        ntsc_cable[26] = 235250;
 
1636
        ntsc_cable[27] = 241250;
 
1637
        ntsc_cable[28] = 247250;
 
1638
        ntsc_cable[29] = 253250;
 
1639
        ntsc_cable[30] = 259250;
 
1640
        ntsc_cable[31] = 265250;
 
1641
        ntsc_cable[32] = 271250;
 
1642
        ntsc_cable[33] = 277250;
 
1643
        ntsc_cable[34] = 283250;
 
1644
        ntsc_cable[35] = 289250;
 
1645
        ntsc_cable[36] = 295250;
 
1646
        ntsc_cable[37] = 301250;
 
1647
        ntsc_cable[38] = 307250;
 
1648
        ntsc_cable[39] = 313250;
 
1649
        ntsc_cable[40] = 319250;
 
1650
        ntsc_cable[41] = 325250;
 
1651
        ntsc_cable[42] = 331250;
 
1652
        ntsc_cable[43] = 337250;
 
1653
        ntsc_cable[44] = 343250;
 
1654
        ntsc_cable[45] = 349250;
 
1655
        ntsc_cable[46] = 355250;
 
1656
        ntsc_cable[47] = 361250;
 
1657
        ntsc_cable[48] = 367250;
 
1658
        ntsc_cable[49] = 373250;
 
1659
        ntsc_cable[50] = 379250;
 
1660
        ntsc_cable[51] = 385250;
 
1661
        ntsc_cable[52] = 391250;
 
1662
        ntsc_cable[53] = 397250;
 
1663
        ntsc_cable[54] = 403250;
 
1664
        ntsc_cable[55] = 409250;
 
1665
        ntsc_cable[56] = 415250;
 
1666
        ntsc_cable[57] = 421250;
 
1667
        ntsc_cable[58] = 427250;
 
1668
        ntsc_cable[59] = 433250;
 
1669
        ntsc_cable[60] = 439250;
 
1670
        ntsc_cable[61] = 445250;
 
1671
        ntsc_cable[62] = 451250;
 
1672
        ntsc_cable[63] = 457250;
 
1673
        ntsc_cable[64] = 463250;
 
1674
        ntsc_cable[65] = 469250;
 
1675
        ntsc_cable[66] = 475250;
 
1676
        ntsc_cable[67] = 481250;
 
1677
        ntsc_cable[68] = 487250;
 
1678
        ntsc_cable[69] = 493250;
 
1679
        ntsc_cable[70] = 499250;
 
1680
        ntsc_cable[71] = 505250;
 
1681
        ntsc_cable[72] = 511250;
 
1682
        ntsc_cable[73] = 517250;
 
1683
        ntsc_cable[74] = 523250;
 
1684
        ntsc_cable[75] = 529250;
 
1685
        ntsc_cable[76] = 535250;
 
1686
        ntsc_cable[77] = 541250;
 
1687
        ntsc_cable[78] = 547250;
 
1688
        ntsc_cable[79] = 553250;
 
1689
        ntsc_cable[80] = 559250;
 
1690
        ntsc_cable[81] = 565250;
 
1691
        ntsc_cable[82] = 571250;
 
1692
        ntsc_cable[83] = 577250;
 
1693
        ntsc_cable[84] = 583250;
 
1694
        ntsc_cable[85] = 589250;
 
1695
        ntsc_cable[86] = 595250;
 
1696
        ntsc_cable[87] = 601250;
 
1697
        ntsc_cable[88] = 607250;
 
1698
        ntsc_cable[89] = 613250;
 
1699
        ntsc_cable[90] = 619250;
 
1700
        ntsc_cable[91] = 625250;
 
1701
        ntsc_cable[92] = 631250;
 
1702
        ntsc_cable[93] = 637250;
 
1703
        ntsc_cable[94] = 643250;
 
1704
        ntsc_cable[95] = 91250;
 
1705
        ntsc_cable[96] = 97250;
 
1706
        ntsc_cable[97] = 103250;
 
1707
        ntsc_cable[98] = 109250;
 
1708
        ntsc_cable[99] = 115250;
 
1709
        ntsc_cable[100] = 649250;
 
1710
        ntsc_cable[101] = 655250;
 
1711
        ntsc_cable[102] = 661250;
 
1712
        ntsc_cable[103] = 667250;
 
1713
        ntsc_cable[104] = 673250;
 
1714
        ntsc_cable[105] = 679250;
 
1715
        ntsc_cable[106] = 685250;
 
1716
        ntsc_cable[107] = 691250;
 
1717
        ntsc_cable[108] = 697250;
 
1718
        ntsc_cable[109] = 703250;
 
1719
        ntsc_cable[110] = 709250;
 
1720
        ntsc_cable[111] = 715250;
 
1721
        ntsc_cable[112] = 721250;
 
1722
        ntsc_cable[113] = 727250;
 
1723
        ntsc_cable[114] = 733250;
 
1724
        ntsc_cable[115] = 739250;
 
1725
        ntsc_cable[116] = 745250;
 
1726
        ntsc_cable[117] = 751250;
 
1727
        ntsc_cable[118] = 757250;
 
1728
        ntsc_cable[119] = 763250;
 
1729
        ntsc_cable[120] = 769250;
 
1730
        ntsc_cable[121] = 775250;
 
1731
        ntsc_cable[122] = 781250;
 
1732
        ntsc_cable[123] = 787250;
 
1733
        ntsc_cable[124] = 793250;
 
1734
        ntsc_cable[125] = 799250;
 
1735
}
 
1736