28
28
#ifdef HAVE_CONFIG_H
33
33
#include <stdlib.h>
34
34
#include <stdarg.h>
39
#include <sys/ioctl.h>
35
#ifdef HAVE_GETOPT_LONG
40
38
#include <sys/stat.h>
41
39
#include <assert.h>
43
43
#include "zapping_setup_fb.h"
45
#define ZSFB_VERSION "zapping_setup_fb 0.11"
46
#define MAX_VERBOSITY 3
45
static const char * zsfb_version = "zapping_setup_fb 0.12";
46
static const char * default_device_name = "/dev/video0";
47
static const int max_verbosity = 3;
48
49
#ifndef HAVE_PROGRAM_INVOCATION_NAME
49
50
char * program_invocation_name;
50
51
char * program_invocation_short_name;
57
/* Frame buffer parameters */
67
fprintf_symbolic (FILE * fp,
72
unsigned int i, j = 0;
78
unsigned int n[2] = { 0, 0 };
82
for (i = 0; (s = va_arg (ap, const char *)); i++) {
83
v = va_arg (ap, unsigned long);
84
n[((v & (v - 1)) == 0)]++; /* single bit */
87
mode = 1 + (n[1] > n[0]); /* 1-enum, 2-flags */
94
for (i = 0; (s = va_arg (ap, const char *)); i++) {
95
v = va_arg (ap, unsigned long);
96
if (2 == mode || v == value) {
97
fprintf (fp, "%s%s%s", j++ ? "|" : "",
98
(2 == mode && 0 == (v & value)) ? "!" : "", s);
104
fprintf (fp, "%s0x%lx", j ? "|" : "", value);
118
if (3 <= verbosity && (_IOC_DIR (cmd) & _IOC_WRITE))
120
assert (sizeof (buf) >= _IOC_SIZE (cmd));
121
memcpy (buf, arg, _IOC_SIZE (cmd));
124
do err = ioctl (fd, cmd, arg);
125
while (-1 == err && EINTR == errno);
127
if (3 <= verbosity && NULL != fn)
133
fprintf (stderr, "%d = ", err);
134
fn (stderr, cmd, NULL);
137
if (_IOC_DIR(cmd) & _IOC_WRITE)
138
fn (stderr, cmd, &buf);
142
if ((_IOC_READ | _IOC_WRITE) == _IOC_DIR(cmd))
143
fputs (") -> (", stderr);
145
if (_IOC_DIR(cmd) & _IOC_READ)
146
fn (stderr, cmd, arg);
148
fputs (")\n", stderr);
152
fprintf (stderr, "), errno = %d, %s\n",
153
errno, strerror (errno));
57
/* legacy verbosity value, used in libtv/screen.c */
61
#include "common/device.c" /* generic device access routines */
163
64
# define major(dev) (((dev) >> 8) & 0xff)
167
dev_open (const char * device_name,
68
device_open_safer (const char * device_name,
189
if (-1 == stat (device_name, &st))
191
errmsg ("Cannot stat device '%s'", device_name);
195
if (!S_ISCHR (st.st_mode))
197
message (1, "'%s' is not a character device file.\n", device_name);
201
if (major_number != major (st.st_rdev))
203
message (1, "'%s' has suspect major number %d, expected %d.\n",
204
device_name, major (st.st_rdev), major_number);
90
if (major_number != 0)
92
if (-1 == stat (device_name, &st))
94
errmsg ("Cannot stat device '%s'", device_name);
98
if (!S_ISCHR (st.st_mode))
100
message (1, "'%s' is not a character device file.\n", device_name);
104
if (major_number != major (st.st_rdev))
106
message (1, "'%s' has suspect major number %d, expected %d.\n",
107
device_name, major (st.st_rdev), major_number);
208
112
message (2, "Opening device '%s'.\n", device_name);
210
if (-1 == (fd = open (device_name, flags)))
114
if (-1 == (fd = device_open (log_fp, device_name, flags, 0600)))
212
116
errmsg ("Cannot open device '%s'", device_name);
226
129
if (-1 == seteuid (uid))
228
131
errmsg ("Cannot drop root privileges "
229
"despite uid=%d, euid=%d", uid, euid);
132
"despite uid=%d, euid=%d\nAborting.", uid, euid);
136
else if (ROOT_UID == uid)
138
#if 0 /* cannot distinguish between root and consolehelper */
139
message (1, "You should not run %s as root,\n"
140
"better use consolehelper, sudo, su or set the "
141
"SUID flag with chmod +s.\n",
142
program_invocation_name);
238
restore_root_privileges (int uid,
148
restore_root_privileges (void)
241
150
if (ROOT_UID == euid && ROOT_UID != uid)
256
static const char * short_options = "d:D:b:vqh?V";
166
short_options [] = "b:d:D:hqS:vV";
168
#ifdef HAVE_GETOPT_LONG
258
170
static const struct option
259
171
long_options [] =
173
{ "bpp", required_argument, 0, 'b' },
261
174
{ "device", required_argument, 0, 'd' },
262
175
{ "display", required_argument, 0, 'D' },
263
{ "bpp", required_argument, 0, 'b' },
264
{ "verbose", no_argument, 0, 'v' },
176
{ "help", no_argument, 0, 'h' },
265
177
{ "quiet", no_argument, 0, 'q' },
266
{ "help", no_argument, 0, 'h' },
178
{ "screen", required_argument, 0, 'S' },
267
179
{ "usage", no_argument, 0, 'h' },
180
{ "verbose", no_argument, 0, 'v' },
268
181
{ "version", no_argument, 0, 'V' },
186
# define getopt_long(ac, av, s, l, i) getopt (ac, av, s)
275
" %s [OPTIONS], where OPTIONS can be\n"
276
" -d, --device name - The video device to open, default /dev/video0\n"
277
" -D, --display name - The X display to use\n"
278
" -b, --bpp x - Color depth, bits per pixel on said display\n"
279
" -v, --verbose - Increment verbosity level\n"
280
" -q, --quiet - Decrement verbosity level\n"
281
" -h, --help, --usage - Show this message\n"
282
" -V, --version - Print the program version and exit\n"
283
"", program_invocation_name);
194
"Usage: %s [OPTIONS]\n"
195
"Available options:\n"
196
" -b, --bpp x - Color depth, bits per pixel on "
198
" -d, --device name - The video device to open, default %s\n"
199
" -D, --display name - The X display to use\n"
200
" -h, --help, --usage - Show this message\n"
201
" -q, --quiet - Decrement verbosity level\n"
202
" -S, --screen number - X screen to use (Xinerama)\n"
203
" -v, --verbose - Increment verbosity level\n"
204
" -V, --version - Print the program version and exit\n"
206
program_invocation_name,
207
default_device_name);
214
const char *device_name;
215
const char *display_name;
295
221
#ifndef HAVE_PROGRAM_INVOCATION_NAME
296
program_invocation_name =
222
program_invocation_name = argv[0];
297
223
program_invocation_short_name = argv[0];
301
* Make sure fd's 0 1 2 are open, otherwise
302
* we might end up sending error messages to
226
/* Make sure fd's 0 1 2 are open, otherwise
227
we might end up sending error messages to
316
240
euid = geteuid ();
318
if (!drop_root_privileges (uid, euid))
242
drop_root_privileges ();
321
244
/* Parse arguments */
323
device_name = "/dev/video0";
246
device_name = default_device_name;
324
247
display_name = getenv ("DISPLAY");
248
screen_number = -1; /* default */
330
int c = getopt_long (argc, argv, short_options, long_options, NULL);
256
c = getopt_long (argc, argv, short_options, long_options, NULL);
338
device_name = strdup (optarg);
342
display_name = strdup (optarg);
346
263
bpp_arg = strtol (optarg, NULL, 0);
358
message (1, "Invalid bpp argument %d. Expected\n"
359
"color depth 8, 15, 16, 24 or 32.\n", bpp_arg);
272
message (1, "Invalid bpp argument %d. Expected "
273
"24 or 32.\n", bpp_arg);
366
if (verbosity < MAX_VERBOSITY)
280
device_name = strdup (optarg);
284
display_name = strdup (optarg);
371
292
if (verbosity > 0)
297
screen_number = strtol (optarg, NULL, 0);
301
if (verbosity < max_verbosity)
376
message (0, "%s\n", ZSFB_VERSION);
306
message (0, "%s\n", zsfb_version);
381
307
exit (EXIT_SUCCESS);
384
310
/* getopt_long prints option name when unknown or arg missing */
390
message (1, "(C) 2000-2003 I�aki G. Etxebarria, Michael H. Schimek.\n"
317
debug_msg = 1; /* log X access */
320
log_fp = stderr; /* log ioctls */
322
message (1, "(C) 2000-2004 Iñaki G. Etxebarria, Michael H. Schimek.\n"
391
323
"This program is freely redistributable under the terms\n"
392
324
"of the GNU General Public License.\n\n");
394
message (1, "Using video device '%s', display '%s'.\n",
395
device_name, display_name);
397
if (1 != query_dga (display_name, bpp_arg))
400
/* OK, the DGA is working and we have its info,
401
set up the overlay */
403
err = setup_v4l25 (device_name);
407
err = setup_v4l2 (device_name);
326
message (1, "Using video device '%s', display '%s', screen %d.\n",
327
device_name, display_name, screen_number);
329
message (1, "Querying frame buffer parameters from X server.\n");
331
screens = tv_screen_list_new (display_name, bpp_arg);
334
message (1, "No screens found.\n");
338
for (xs = screens; xs; xs = xs->next)
340
message (2, "Screen %d:\n"
341
" position %u, %u - %u, %u\n"
342
" frame buffer address 0x%lx\n"
343
" frame buffer size %ux%u pixels, 0x%x bytes\n"
344
" bytes per line %u bytes\n"
352
xs->target.format.width,
353
xs->target.format.height,
354
xs->target.format.size,
355
xs->target.format.bytes_per_line[0],
356
tv_pixfmt_name (xs->target.format.pixel_format->pixfmt));
359
if (-1 == screen_number)
363
display = XOpenDisplay (display_name);
411
err = setup_v4l (device_name);
369
screen_number = XDefaultScreen (display);
371
XCloseDisplay (display);
374
for (xs = screens; xs; xs = xs->next)
375
if (xs->screen_number == screen_number)
380
message (1, "Screen %d not found.\n",
385
if (!tv_screen_is_target (xs))
387
message (1, "DMA not possible on screen %d.\n",
394
if (1 == setup_v4l25 (device_name, &xs->target))
397
if (1 == setup_v4l2 (device_name, &xs->target))
400
if (1 == setup_v4l (device_name, &xs->target))
418
407
message (1, "Setup completed.\n");
420
409
return EXIT_SUCCESS;
423
message (1, "Setup failed.\n");
412
message (1, "Setup failed. %s\n",
413
(verbosity <= 1) ? "Try -vv for details." : "");
425
415
return EXIT_FAILURE;