Mercurial > mplayer.hg
comparison TOOLS/TVout/fbset/fbset.c @ 12940:b205f8ca892a
Moved to the TOOLS directory.
author | diego |
---|---|
date | Tue, 03 Aug 2004 00:45:55 +0000 |
parents | TVout/fbset/fbset.c@3b5f5d1c5041 |
children |
comparison
equal
deleted
inserted
replaced
12939:9b44f32dae3f | 12940:b205f8ca892a |
---|---|
1 /* | |
2 * Linux Frame Buffer Device Configuration | |
3 * | |
4 * © Copyright 1995-1999 by Geert Uytterhoeven | |
5 * (Geert.Uytterhoeven@cs.kuleuven.ac.be) | |
6 * | |
7 * -------------------------------------------------------------------------- | |
8 * | |
9 * This file is subject to the terms and conditions of the GNU General Public | |
10 * License. See the file COPYING in the main directory of the Linux | |
11 * distribution for more details. | |
12 * | |
13 * Petr Vandrovec <vandrove@vc.cvut.cz>: | |
14 * -grayscale, -rgba, -nonstd, VGA modes reporting | |
15 * | |
16 * Brad Midgley <brad@exodus.pht.com>: | |
17 * -match | |
18 * | |
19 */ | |
20 | |
21 | |
22 #include <stdarg.h> | |
23 #include <stdlib.h> | |
24 #include <unistd.h> | |
25 #include <string.h> | |
26 #include <fcntl.h> | |
27 #include <errno.h> | |
28 #include <sys/ioctl.h> | |
29 #include <ctype.h> | |
30 #include <sys/stat.h> | |
31 | |
32 struct file; | |
33 struct inode; | |
34 | |
35 #include "fb.h" | |
36 | |
37 #include "fbset.h" | |
38 | |
39 | |
40 /* | |
41 * Default Frame Buffer Special Device Node | |
42 */ | |
43 | |
44 #define DEFAULT_FRAMEBUFFER "/dev/fb0" | |
45 | |
46 | |
47 /* | |
48 * Default Video Mode Database File | |
49 */ | |
50 | |
51 #define DEFAULT_MODEDBFILE "/etc/fb.modes" | |
52 | |
53 | |
54 /* | |
55 * Command Line Options | |
56 */ | |
57 | |
58 static const char *ProgramName; | |
59 | |
60 static int Opt_test = 0; | |
61 static int Opt_show = 0; | |
62 static int Opt_info = 0; | |
63 static int Opt_version = 0; | |
64 static int Opt_verbose = 0; | |
65 static int Opt_xfree86 = 0; | |
66 static int Opt_change = 0; | |
67 static int Opt_all = 0; | |
68 | |
69 static const char *Opt_fb = NULL; | |
70 const char *Opt_modedb = DEFAULT_MODEDBFILE; | |
71 static const char *Opt_xres = NULL; | |
72 static const char *Opt_yres = NULL; | |
73 static const char *Opt_vxres = NULL; | |
74 static const char *Opt_vyres = NULL; | |
75 static const char *Opt_depth = NULL; | |
76 static const char *Opt_pixclock = NULL; | |
77 static const char *Opt_left = NULL; | |
78 static const char *Opt_right = NULL; | |
79 static const char *Opt_upper = NULL; | |
80 static const char *Opt_lower = NULL; | |
81 static const char *Opt_hslen = NULL; | |
82 static const char *Opt_vslen = NULL; | |
83 static const char *Opt_accel = NULL; | |
84 static const char *Opt_hsync = NULL; | |
85 static const char *Opt_vsync = NULL; | |
86 static const char *Opt_csync = NULL; | |
87 static const char *Opt_gsync = NULL; | |
88 static const char *Opt_extsync = NULL; | |
89 static const char *Opt_bcast = NULL; | |
90 static const char *Opt_laced = NULL; | |
91 static const char *Opt_double = NULL; | |
92 static const char *Opt_move = NULL; | |
93 static const char *Opt_step = NULL; | |
94 static const char *Opt_modename = NULL; | |
95 static const char *Opt_rgba = NULL; | |
96 static const char *Opt_nonstd = NULL; | |
97 static const char *Opt_grayscale = NULL; | |
98 static const char *Opt_matchyres = NULL; | |
99 | |
100 static struct { | |
101 const char *name; | |
102 const char **value; | |
103 const int change; | |
104 } Options[] = { | |
105 { "-fb", &Opt_fb, 0 }, | |
106 { "-db", &Opt_modedb, 0 }, | |
107 { "-xres", &Opt_xres, 1 }, | |
108 { "-yres", &Opt_yres, 1 }, | |
109 { "-vxres", &Opt_vxres, 1 }, | |
110 { "-vyres", &Opt_vyres, 1 }, | |
111 { "-depth", &Opt_depth, 1 }, | |
112 { "-nonstd", &Opt_nonstd, 1}, | |
113 { "-pixclock", &Opt_pixclock, 1 }, | |
114 { "-left", &Opt_left, 1 }, | |
115 { "-right", &Opt_right, 1 }, | |
116 { "-upper", &Opt_upper, 1 }, | |
117 { "-lower", &Opt_lower, 1 }, | |
118 { "-hslen", &Opt_hslen, 1 }, | |
119 { "-vslen", &Opt_vslen, 1 }, | |
120 { "-accel", &Opt_accel, 1 }, | |
121 { "-hsync", &Opt_hsync, 1 }, | |
122 { "-vsync", &Opt_vsync, 1 }, | |
123 { "-csync", &Opt_csync, 1 }, | |
124 { "-gsync", &Opt_gsync, 1 }, | |
125 { "-extsync", &Opt_extsync, 1 }, | |
126 { "-bcast", &Opt_bcast, 1 }, | |
127 { "-laced", &Opt_laced, 1 }, | |
128 { "-double", &Opt_double, 1 }, | |
129 { "-move", &Opt_move, 1 }, | |
130 { "-step", &Opt_step, 1 }, | |
131 { "-rgba", &Opt_rgba, 1 }, | |
132 { "-grayscale", &Opt_grayscale, 1 }, | |
133 { NULL, NULL, 0 } | |
134 }; | |
135 | |
136 | |
137 /* | |
138 * Video Mode Database | |
139 */ | |
140 | |
141 struct VideoMode *VideoModes = NULL; | |
142 | |
143 | |
144 /* | |
145 * Hardware Text Modes | |
146 */ | |
147 | |
148 static struct textentry { | |
149 __u32 id; | |
150 const char *name; | |
151 } Textmodes[] = { | |
152 { FB_AUX_TEXT_MDA, "Monochrome text" }, | |
153 { FB_AUX_TEXT_CGA, "CGA/EGA/VGA Color text" }, | |
154 { FB_AUX_TEXT_S3_MMIO, "S3 MMIO fasttext" }, | |
155 { FB_AUX_TEXT_MGA_STEP16, "MGA Millennium I step 16 text" }, | |
156 { FB_AUX_TEXT_MGA_STEP8, "MGA step 8 text" }, | |
157 }; | |
158 | |
159 static struct textentry VGAModes[] = { | |
160 { FB_AUX_VGA_PLANES_VGA4, "VGA 16 colors in 4 planes" }, | |
161 { FB_AUX_VGA_PLANES_CFB4, "VGA 16 colors in 1 plane" }, | |
162 { FB_AUX_VGA_PLANES_CFB8, "VGA 256 colors in 4 planes" }, | |
163 /* last entry has name == NULL */ | |
164 { 0, NULL} | |
165 }; | |
166 | |
167 /* | |
168 * Hardware Accelerators | |
169 */ | |
170 | |
171 static struct accelentry { | |
172 __u32 id; | |
173 const char *name; | |
174 } Accelerators[] = { | |
175 { FB_ACCEL_NONE, "No" }, | |
176 { FB_ACCEL_ATARIBLITT, "Atari Blitter" }, | |
177 { FB_ACCEL_AMIGABLITT, "Amiga Blitter" }, | |
178 { FB_ACCEL_S3_TRIO64, "S3 Trio64" }, | |
179 { FB_ACCEL_NCR_77C32BLT, "NCR 77C32BLT" }, | |
180 { FB_ACCEL_S3_VIRGE, "S3 ViRGE" }, | |
181 { FB_ACCEL_ATI_MACH64GX, "ATI Mach64GX" }, | |
182 { FB_ACCEL_DEC_TGA, "DEC 21030 TGA" }, | |
183 { FB_ACCEL_ATI_MACH64CT, "ATI Mach64CT" }, | |
184 { FB_ACCEL_ATI_MACH64VT, "ATI Mach64VT" }, | |
185 { FB_ACCEL_ATI_MACH64GT, "ATI Mach64GT" }, | |
186 { FB_ACCEL_SUN_CREATOR, "Sun Creator/Creator3D" }, | |
187 { FB_ACCEL_SUN_CGSIX, "Sun cg6" }, | |
188 { FB_ACCEL_SUN_LEO, "Sun leo/zx" }, | |
189 { FB_ACCEL_IMS_TWINTURBO, "IMS Twin Turbo" }, | |
190 { FB_ACCEL_3DLABS_PERMEDIA2, "3Dlabs Permedia 2" }, | |
191 { FB_ACCEL_MATROX_MGA2064W, "Matrox MGA2064W (Millennium)" }, | |
192 { FB_ACCEL_MATROX_MGA1064SG, "Matrox MGA1064SG (Mystique)" }, | |
193 { FB_ACCEL_MATROX_MGA2164W, "Matrox MGA2164W (Millennium II)" }, | |
194 { FB_ACCEL_MATROX_MGA2164W_AGP, "Matrox MGA2164W (Millennium II AGP)" }, | |
195 { FB_ACCEL_MATROX_MGAG100, "Matrox G100 (Productiva G100)" }, | |
196 { FB_ACCEL_MATROX_MGAG200, "Matrox G200 (Millennium, Mystique)" }, | |
197 { FB_ACCEL_SUN_CG14, "Sun cg14" }, | |
198 { FB_ACCEL_SUN_BWTWO, "Sun bw2" }, | |
199 { FB_ACCEL_SUN_CGTHREE, "Sun cg3" }, | |
200 { FB_ACCEL_SUN_TCX, "Sun tcx" }, | |
201 { FB_ACCEL_MATROX_MGAG400, "Matrox G400" }, | |
202 }; | |
203 | |
204 | |
205 /* | |
206 * Current Video Mode | |
207 */ | |
208 | |
209 struct VideoMode Current; | |
210 | |
211 | |
212 /* | |
213 * Function Prototypes | |
214 */ | |
215 | |
216 int OpenFrameBuffer(const char *name); | |
217 void CloseFrameBuffer(int fh); | |
218 void GetVarScreenInfo(int fh, struct fb_var_screeninfo *var); | |
219 void SetVarScreenInfo(int fh, struct fb_var_screeninfo *var); | |
220 void GetFixScreenInfo(int fh, struct fb_fix_screeninfo *fix); | |
221 static void ConvertFromVideoMode(const struct VideoMode *vmode, | |
222 struct fb_var_screeninfo *var); | |
223 static void ConvertToVideoMode(const struct fb_var_screeninfo *var, | |
224 struct VideoMode *vmode); | |
225 static int atoboolean(const char *var); | |
226 static void ReadModeDB(void); | |
227 static struct VideoMode *FindVideoMode(const char *name); | |
228 static void ModifyVideoMode(struct VideoMode *vmode); | |
229 static void DisplayVModeInfo(struct VideoMode *vmode); | |
230 static void DisplayFBInfo(struct fb_fix_screeninfo *fix); | |
231 static int FillScanRates(struct VideoMode *vmode); | |
232 static void Usage(void) __attribute__ ((noreturn)); | |
233 int main(int argc, char *argv[]); | |
234 | |
235 | |
236 /* | |
237 * Print an Error Message and Exit | |
238 */ | |
239 | |
240 void Die(const char *fmt, ...) | |
241 { | |
242 va_list ap; | |
243 | |
244 fflush(stdout); | |
245 va_start(ap, fmt); | |
246 vfprintf(stderr, fmt, ap); | |
247 va_end(ap); | |
248 exit(1); | |
249 } | |
250 | |
251 | |
252 /* | |
253 * Open the Frame Buffer Device | |
254 */ | |
255 | |
256 int OpenFrameBuffer(const char *name) | |
257 { | |
258 int fh; | |
259 | |
260 if (Opt_verbose) | |
261 printf("Opening frame buffer device `%s'\n", name); | |
262 | |
263 if ((fh = open(name, O_RDONLY)) == -1) | |
264 Die("open %s: %s\n", name, strerror(errno)); | |
265 return fh; | |
266 } | |
267 | |
268 | |
269 /* | |
270 * Close the Frame Buffer Device | |
271 */ | |
272 | |
273 void CloseFrameBuffer(int fh) | |
274 { | |
275 close(fh); | |
276 } | |
277 | |
278 /* | |
279 * Get the Variable Part of the Screen Info | |
280 */ | |
281 | |
282 void GetVarScreenInfo(int fh, struct fb_var_screeninfo *var) | |
283 { | |
284 if (ioctl(fh, FBIOGET_VSCREENINFO, var)) | |
285 Die("ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); | |
286 } | |
287 | |
288 | |
289 /* | |
290 * Set (and Get) the Variable Part of the Screen Info | |
291 */ | |
292 | |
293 void SetVarScreenInfo(int fh, struct fb_var_screeninfo *var) | |
294 { | |
295 if (ioctl(fh, FBIOPUT_VSCREENINFO, var)) | |
296 Die("ioctl FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); | |
297 } | |
298 | |
299 | |
300 /* | |
301 * Get the Fixed Part of the Screen Info | |
302 */ | |
303 | |
304 void GetFixScreenInfo(int fh, struct fb_fix_screeninfo *fix) | |
305 { | |
306 if (ioctl(fh, FBIOGET_FSCREENINFO, fix)) | |
307 Die("ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno)); | |
308 } | |
309 | |
310 | |
311 /* | |
312 * Conversion Routines | |
313 */ | |
314 | |
315 static void ConvertFromVideoMode(const struct VideoMode *vmode, | |
316 struct fb_var_screeninfo *var) | |
317 { | |
318 memset(var, 0, sizeof(struct fb_var_screeninfo)); | |
319 var->xres = vmode->xres; | |
320 var->yres = vmode->yres; | |
321 var->xres_virtual = vmode->vxres; | |
322 var->yres_virtual = vmode->vyres; | |
323 var->bits_per_pixel = vmode->depth; | |
324 var->nonstd = vmode->nonstd; | |
325 if (Opt_test) | |
326 var->activate = FB_ACTIVATE_TEST; | |
327 else | |
328 var->activate = FB_ACTIVATE_NOW; | |
329 if (Opt_all) | |
330 var->activate = FB_ACTIVATE_ALL; | |
331 var->accel_flags = vmode->accel_flags; | |
332 var->pixclock = vmode->pixclock; | |
333 var->left_margin = vmode->left; | |
334 var->right_margin = vmode->right; | |
335 var->upper_margin = vmode->upper; | |
336 var->lower_margin = vmode->lower; | |
337 var->hsync_len = vmode->hslen; | |
338 var->vsync_len = vmode->vslen; | |
339 if (vmode->hsync == HIGH) | |
340 var->sync |= FB_SYNC_HOR_HIGH_ACT; | |
341 if (vmode->vsync == HIGH) | |
342 var->sync |= FB_SYNC_VERT_HIGH_ACT; | |
343 if (vmode->csync == HIGH) | |
344 var->sync |= FB_SYNC_COMP_HIGH_ACT; | |
345 if (vmode->gsync == HIGH) | |
346 var->sync |= FB_SYNC_ON_GREEN; | |
347 if (vmode->extsync == TRUE) | |
348 var->sync |= FB_SYNC_EXT; | |
349 if (vmode->bcast == TRUE) | |
350 var->sync |= FB_SYNC_BROADCAST; | |
351 if (vmode->laced == TRUE) | |
352 var->vmode = FB_VMODE_INTERLACED; | |
353 else if (vmode->dblscan == TRUE) | |
354 var->vmode = FB_VMODE_DOUBLE; | |
355 else | |
356 var->vmode = FB_VMODE_NONINTERLACED; | |
357 var->vmode |= FB_VMODE_CONUPDATE; | |
358 var->red.length = vmode->red.length; | |
359 var->red.offset = vmode->red.offset; | |
360 var->green.length = vmode->green.length; | |
361 var->green.offset = vmode->green.offset; | |
362 var->blue.length = vmode->blue.length; | |
363 var->blue.offset = vmode->blue.offset; | |
364 var->transp.length = vmode->transp.length; | |
365 var->transp.offset = vmode->transp.offset; | |
366 var->grayscale = vmode->grayscale; | |
367 } | |
368 | |
369 | |
370 static void ConvertToVideoMode(const struct fb_var_screeninfo *var, | |
371 struct VideoMode *vmode) | |
372 { | |
373 vmode->name = NULL; | |
374 vmode->xres = var->xres; | |
375 vmode->yres = var->yres; | |
376 vmode->vxres = var->xres_virtual; | |
377 vmode->vyres = var->yres_virtual; | |
378 vmode->depth = var->bits_per_pixel; | |
379 vmode->nonstd = var->nonstd; | |
380 vmode->accel_flags = var->accel_flags; | |
381 vmode->pixclock = var->pixclock; | |
382 vmode->left = var->left_margin; | |
383 vmode->right = var->right_margin; | |
384 vmode->upper = var->upper_margin; | |
385 vmode->lower = var->lower_margin; | |
386 vmode->hslen = var->hsync_len; | |
387 vmode->vslen = var->vsync_len; | |
388 vmode->hsync = var->sync & FB_SYNC_HOR_HIGH_ACT ? HIGH : LOW; | |
389 vmode->vsync = var->sync & FB_SYNC_VERT_HIGH_ACT ? HIGH : LOW; | |
390 vmode->csync = var->sync & FB_SYNC_COMP_HIGH_ACT ? HIGH : LOW; | |
391 vmode->gsync = var->sync & FB_SYNC_ON_GREEN ? TRUE : FALSE; | |
392 vmode->extsync = var->sync & FB_SYNC_EXT ? TRUE : FALSE; | |
393 vmode->bcast = var->sync & FB_SYNC_BROADCAST ? TRUE : FALSE; | |
394 vmode->grayscale = var->grayscale; | |
395 vmode->laced = FALSE; | |
396 vmode->dblscan = FALSE; | |
397 switch (var->vmode & FB_VMODE_MASK) { | |
398 case FB_VMODE_INTERLACED: | |
399 vmode->laced = TRUE; | |
400 break; | |
401 case FB_VMODE_DOUBLE: | |
402 vmode->dblscan = TRUE; | |
403 break; | |
404 } | |
405 vmode->red.length = var->red.length; | |
406 vmode->red.offset = var->red.offset; | |
407 vmode->green.length = var->green.length; | |
408 vmode->green.offset = var->green.offset; | |
409 vmode->blue.length = var->blue.length; | |
410 vmode->blue.offset = var->blue.offset; | |
411 vmode->transp.length = var->transp.length; | |
412 vmode->transp.offset = var->transp.offset; | |
413 FillScanRates(vmode); | |
414 } | |
415 | |
416 | |
417 static int atoboolean(const char *var) | |
418 { | |
419 int value = 0; | |
420 | |
421 if (!strcasecmp(var, "false") || !strcasecmp(var, "low") || | |
422 !strcasecmp(var, "no") || !strcasecmp(var, "off") || | |
423 !strcmp(var, "0")) | |
424 value = 0; | |
425 else if (!strcasecmp(var, "true") || !strcasecmp(var, "high") || | |
426 !strcasecmp(var, "yes") || !strcasecmp(var, "on") || | |
427 !strcmp(var, "1")) | |
428 value = 1; | |
429 else | |
430 Die("Invalid value `%s'\n", var); | |
431 | |
432 return value; | |
433 } | |
434 | |
435 | |
436 void AddVideoMode(const struct VideoMode *vmode) | |
437 { | |
438 struct VideoMode *vmode2; | |
439 | |
440 if (FindVideoMode(vmode->name)) | |
441 Die("%s:%d: Duplicate mode name `%s'\n", Opt_modedb, line, | |
442 vmode->name); | |
443 vmode2 = malloc(sizeof(struct VideoMode)); | |
444 *vmode2 = *vmode; | |
445 if (!FillScanRates(vmode2)) | |
446 Die("%s:%d: Bad video mode `%s'\n", Opt_modedb, line, vmode2->name); | |
447 vmode2->next = VideoModes; | |
448 VideoModes = vmode2; | |
449 } | |
450 | |
451 | |
452 /* | |
453 * Read the Video Mode Database | |
454 */ | |
455 | |
456 static void ReadModeDB(void) | |
457 { | |
458 if (Opt_verbose) | |
459 printf("Reading mode database from file `%s'\n", Opt_modedb); | |
460 | |
461 if (!(yyin = fopen(Opt_modedb, "r"))) | |
462 Die("fopen %s: %s\n", Opt_modedb, strerror(errno)); | |
463 yyparse(); | |
464 fclose(yyin); | |
465 } | |
466 | |
467 | |
468 static void getColor(struct color *color, const char** opt) | |
469 { | |
470 char* ptr; | |
471 | |
472 color->length = 0; | |
473 color->offset = 0; | |
474 ptr = (char*)(*opt); | |
475 if (!ptr) | |
476 return; | |
477 color->length = strtoul(ptr, &ptr, 0); | |
478 if (!ptr) | |
479 return; | |
480 if (*ptr == '/') | |
481 color->offset = strtoul(ptr+1, &ptr, 0); | |
482 if (ptr) { | |
483 while (*ptr && isspace(*ptr)) | |
484 ptr++; | |
485 if (*ptr == ',') { | |
486 ptr++; | |
487 } else if (*ptr) | |
488 Die("Bad RGBA syntax, rL/rO,gL/gO,bL/bO,tL/tO or rL,gL,bL,tL\n"); | |
489 } | |
490 *opt = ptr; | |
491 return; | |
492 } | |
493 | |
494 void makeRGBA(struct VideoMode *vmode, const char* opt) | |
495 { | |
496 getColor(&vmode->red, &opt); | |
497 getColor(&vmode->green, &opt); | |
498 getColor(&vmode->blue, &opt); | |
499 getColor(&vmode->transp, &opt); | |
500 } | |
501 | |
502 /* | |
503 * Find a Video Mode | |
504 */ | |
505 | |
506 static struct VideoMode *FindVideoMode(const char *name) | |
507 { | |
508 struct VideoMode *vmode; | |
509 | |
510 for (vmode = VideoModes; vmode; vmode = vmode->next) | |
511 if (!strcmp(name, vmode->name)) | |
512 break; | |
513 | |
514 return vmode; | |
515 } | |
516 | |
517 | |
518 /* | |
519 * Modify a Video Mode | |
520 */ | |
521 | |
522 static void ModifyVideoMode(struct VideoMode *vmode) | |
523 { | |
524 u_int hstep = 8, vstep = 2; | |
525 | |
526 if (Opt_xres) | |
527 vmode->xres = strtoul(Opt_xres, NULL, 0); | |
528 if (Opt_yres) | |
529 vmode->yres = strtoul(Opt_yres, NULL, 0); | |
530 if (Opt_vxres) | |
531 vmode->vxres = strtoul(Opt_vxres, NULL, 0); | |
532 if (Opt_vyres) | |
533 vmode->vyres = strtoul(Opt_vyres, NULL, 0); | |
534 if (Opt_depth) | |
535 vmode->depth = strtoul(Opt_depth, NULL, 0); | |
536 if (Opt_nonstd) | |
537 vmode->nonstd = strtoul(Opt_nonstd, NULL, 0); | |
538 if (Opt_accel) | |
539 vmode->accel_flags = atoboolean(Opt_accel) ? FB_ACCELF_TEXT : 0; | |
540 if (Opt_pixclock) | |
541 vmode->pixclock = strtoul(Opt_pixclock, NULL, 0); | |
542 if (Opt_left) | |
543 vmode->left = strtoul(Opt_left, NULL, 0); | |
544 if (Opt_right) | |
545 vmode->right = strtoul(Opt_right, NULL, 0); | |
546 if (Opt_upper) | |
547 vmode->upper = strtoul(Opt_upper, NULL, 0); | |
548 if (Opt_lower) | |
549 vmode->lower = strtoul(Opt_lower, NULL, 0); | |
550 if (Opt_hslen) | |
551 vmode->hslen = strtoul(Opt_hslen, NULL, 0); | |
552 if (Opt_vslen) | |
553 vmode->vslen = strtoul(Opt_vslen, NULL, 0); | |
554 if (Opt_hsync) | |
555 vmode->hsync = atoboolean(Opt_hsync); | |
556 if (Opt_vsync) | |
557 vmode->vsync = atoboolean(Opt_vsync); | |
558 if (Opt_csync) | |
559 vmode->csync = atoboolean(Opt_csync); | |
560 if (Opt_gsync) | |
561 vmode->gsync = atoboolean(Opt_gsync); | |
562 if (Opt_extsync) | |
563 vmode->extsync = atoboolean(Opt_extsync); | |
564 if (Opt_bcast) | |
565 vmode->bcast = atoboolean(Opt_bcast); | |
566 if (Opt_laced) | |
567 vmode->laced = atoboolean(Opt_laced); | |
568 if (Opt_double) | |
569 vmode->dblscan = atoboolean(Opt_double); | |
570 if (Opt_grayscale) | |
571 vmode->grayscale = atoboolean(Opt_grayscale); | |
572 if (Opt_step) | |
573 hstep = vstep = strtoul(Opt_step, NULL, 0); | |
574 if (Opt_matchyres) | |
575 vmode->vyres = vmode->yres; | |
576 if (Opt_move) { | |
577 if (!strcasecmp(Opt_move, "left")) { | |
578 if (hstep > vmode->left) | |
579 Die("The left margin cannot be negative\n"); | |
580 vmode->left -= hstep; | |
581 vmode->right += hstep; | |
582 } else if (!strcasecmp(Opt_move, "right")) { | |
583 if (hstep > vmode->right) | |
584 Die("The right margin cannot be negative\n"); | |
585 vmode->left += hstep; | |
586 vmode->right -= hstep; | |
587 } else if (!strcasecmp(Opt_move, "up")) { | |
588 if (vstep > vmode->upper) | |
589 Die("The upper margin cannot be negative\n"); | |
590 vmode->upper -= vstep; | |
591 vmode->lower += vstep; | |
592 } else if (!strcasecmp(Opt_move, "down")) { | |
593 if (vstep > vmode->lower) | |
594 Die("The lower margin cannot be negative\n"); | |
595 vmode->upper += vstep; | |
596 vmode->lower -= vstep; | |
597 } else | |
598 Die("Invalid direction `%s'\n", Opt_move); | |
599 } | |
600 if (Opt_rgba) { | |
601 makeRGBA(vmode, Opt_rgba); | |
602 } | |
603 if (!FillScanRates(vmode)) | |
604 Die("Bad video mode\n"); | |
605 } | |
606 | |
607 | |
608 /* | |
609 * Display the Video Mode Information | |
610 */ | |
611 | |
612 static void DisplayVModeInfo(struct VideoMode *vmode) | |
613 { | |
614 u_int res, sstart, send, total; | |
615 | |
616 puts(""); | |
617 if (!Opt_xfree86) { | |
618 printf("mode \"%dx%d", vmode->xres, vmode->yres); | |
619 if (vmode->pixclock) { | |
620 printf("-%d\"\n", (int)(vmode->vrate+0.5)); | |
621 printf(" # D: %5.3f MHz, H: %5.3f kHz, V: %5.3f Hz\n", | |
622 vmode->drate/1E6, vmode->hrate/1E3, vmode->vrate); | |
623 } else | |
624 puts("\""); | |
625 printf(" geometry %d %d %d %d %d\n", vmode->xres, vmode->yres, | |
626 vmode->vxres, vmode->vyres, vmode->depth); | |
627 printf(" timings %d %d %d %d %d %d %d\n", vmode->pixclock, | |
628 vmode->left, vmode->right, vmode->upper, vmode->lower, | |
629 vmode->hslen, vmode->vslen); | |
630 if (vmode->hsync) | |
631 puts(" hsync high"); | |
632 if (vmode->vsync) | |
633 puts(" vsync high"); | |
634 if (vmode->csync) | |
635 puts(" csync high"); | |
636 if (vmode->gsync) | |
637 puts(" gsync true"); | |
638 if (vmode->extsync) | |
639 puts(" extsync true"); | |
640 if (vmode->bcast) | |
641 puts(" bcast true"); | |
642 if (vmode->laced) | |
643 puts(" laced true"); | |
644 if (vmode->dblscan) | |
645 puts(" double true"); | |
646 if (vmode->nonstd) | |
647 printf(" nonstd %u\n", vmode->nonstd); | |
648 if (vmode->accel_flags) | |
649 puts(" accel true"); | |
650 if (vmode->grayscale) | |
651 puts(" grayscale true"); | |
652 printf(" rgba %u/%u,%u/%u,%u/%u,%u/%u\n", | |
653 vmode->red.length, vmode->red.offset, vmode->green.length, | |
654 vmode->green.offset, vmode->blue.length, vmode->blue.offset, | |
655 vmode->transp.length, vmode->transp.offset); | |
656 puts("endmode\n"); | |
657 } else { | |
658 printf("Mode \"%dx%d\"\n", vmode->xres, vmode->yres); | |
659 if (vmode->pixclock) { | |
660 printf(" # D: %5.3f MHz, H: %5.3f kHz, V: %5.3f Hz\n", | |
661 vmode->drate/1E6, vmode->hrate/1E3, vmode->vrate); | |
662 printf(" DotClock %5.3f\n", vmode->drate/1E6+0.001); | |
663 } else | |
664 puts(" DotClock Unknown"); | |
665 res = vmode->xres; | |
666 sstart = res+vmode->right; | |
667 send = sstart+vmode->hslen; | |
668 total = send+vmode->left; | |
669 printf(" HTimings %d %d %d %d\n", res, sstart, send, total); | |
670 res = vmode->yres; | |
671 sstart = res+vmode->lower; | |
672 send = sstart+vmode->vslen; | |
673 total = send+vmode->upper; | |
674 printf(" VTimings %d %d %d %d\n", res, sstart, send, total); | |
675 printf(" Flags "); | |
676 if (vmode->laced) | |
677 printf(" \"Interlace\""); | |
678 if (vmode->dblscan) | |
679 printf(" \"DoubleScan\""); | |
680 if (vmode->hsync) | |
681 printf(" \"+HSync\""); | |
682 else | |
683 printf(" \"-HSync\""); | |
684 if (vmode->vsync) | |
685 printf(" \"+VSync\""); | |
686 else | |
687 printf(" \"-VSync\""); | |
688 if (vmode->csync) | |
689 printf(" \"Composite\""); | |
690 if (vmode->extsync) | |
691 puts(" # Warning: XFree86 doesn't support extsync\n"); | |
692 if (vmode->bcast) | |
693 printf(" \"bcast\""); | |
694 if (vmode->accel_flags) | |
695 puts(" # Warning: XFree86 doesn't support accel\n"); | |
696 if (vmode->grayscale) | |
697 puts(" # Warning: XFree86 doesn't support grayscale\n"); | |
698 puts("\nEndMode\n"); | |
699 } | |
700 } | |
701 | |
702 | |
703 /* | |
704 * Display the Frame Buffer Device Information | |
705 */ | |
706 | |
707 static void DisplayFBInfo(struct fb_fix_screeninfo *fix) | |
708 { | |
709 int i; | |
710 | |
711 puts("Frame buffer device information:"); | |
712 printf(" Name : %s\n", fix->id); | |
713 printf(" Address : %p\n", fix->smem_start); | |
714 printf(" Size : %d\n", fix->smem_len); | |
715 printf(" Type : "); | |
716 switch (fix->type) { | |
717 case FB_TYPE_PACKED_PIXELS: | |
718 puts("PACKED PIXELS"); | |
719 break; | |
720 case FB_TYPE_PLANES: | |
721 puts("PLANES"); | |
722 break; | |
723 case FB_TYPE_INTERLEAVED_PLANES: | |
724 printf("INTERLEAVED PLANES (%d bytes interleave)\n", | |
725 fix->type_aux); | |
726 break; | |
727 case FB_TYPE_TEXT: | |
728 for (i = 0; i < sizeof(Textmodes)/sizeof(*Textmodes); i++) | |
729 if (fix->type_aux == Textmodes[i].id) | |
730 break; | |
731 if (i < sizeof(Textmodes)/sizeof(*Textmodes)) | |
732 puts(Textmodes[i].name); | |
733 else | |
734 printf("Unknown text (%d)\n", fix->type_aux); | |
735 break; | |
736 case FB_TYPE_VGA_PLANES: | |
737 { | |
738 struct textentry *t; | |
739 | |
740 for (t = VGAModes; t->name; t++) | |
741 if (fix->type_aux == t->id) | |
742 break; | |
743 if (t->name) | |
744 puts(t->name); | |
745 else | |
746 printf("Unknown VGA mode (%d)\n", fix->type_aux); | |
747 } | |
748 break; | |
749 default: | |
750 printf("%d (UNKNOWN)\n", fix->type); | |
751 printf(" Type_aux : %d\n", fix->type_aux); | |
752 break; | |
753 } | |
754 printf(" Visual : "); | |
755 switch (fix->visual) { | |
756 case FB_VISUAL_MONO01: | |
757 puts("MONO01"); | |
758 break; | |
759 case FB_VISUAL_MONO10: | |
760 puts("MONO10"); | |
761 break; | |
762 case FB_VISUAL_TRUECOLOR: | |
763 puts("TRUECOLOR"); | |
764 break; | |
765 case FB_VISUAL_PSEUDOCOLOR: | |
766 puts("PSEUDOCOLOR"); | |
767 break; | |
768 case FB_VISUAL_DIRECTCOLOR: | |
769 puts("DIRECTCOLOR"); | |
770 break; | |
771 case FB_VISUAL_STATIC_PSEUDOCOLOR: | |
772 puts("STATIC PSEUDOCOLOR"); | |
773 break; | |
774 default: | |
775 printf("%d (UNKNOWN)\n", fix->visual); | |
776 break; | |
777 } | |
778 printf(" XPanStep : %d\n", fix->xpanstep); | |
779 printf(" YPanStep : %d\n", fix->ypanstep); | |
780 printf(" YWrapStep : %d\n", fix->ywrapstep); | |
781 printf(" LineLength : %d\n", fix->line_length); | |
782 if (fix->mmio_len) { | |
783 printf(" MMIO Address: %p\n", fix->mmio_start); | |
784 printf(" MMIO Size : %d\n", fix->mmio_len); | |
785 } | |
786 printf(" Accelerator : "); | |
787 for (i = 0; i < sizeof(Accelerators)/sizeof(*Accelerators); i++) | |
788 if (fix->accel == Accelerators[i].id) | |
789 break; | |
790 if (i < sizeof(Accelerators)/sizeof(*Accelerators)) | |
791 puts(Accelerators[i].name); | |
792 else | |
793 printf("Unknown (%d)\n", fix->accel); | |
794 } | |
795 | |
796 | |
797 /* | |
798 * Calculate the Scan Rates for a Video Mode | |
799 */ | |
800 | |
801 static int FillScanRates(struct VideoMode *vmode) | |
802 { | |
803 u_int htotal = vmode->left+vmode->xres+vmode->right+vmode->hslen; | |
804 u_int vtotal = vmode->upper+vmode->yres+vmode->lower+vmode->vslen; | |
805 | |
806 if (vmode->dblscan) | |
807 vtotal <<= 2; | |
808 else if (!vmode->laced) | |
809 vtotal <<= 1; | |
810 | |
811 if (!htotal || !vtotal) | |
812 return 0; | |
813 | |
814 if (vmode->pixclock) { | |
815 vmode->drate = 1E12/vmode->pixclock; | |
816 vmode->hrate = vmode->drate/htotal; | |
817 vmode->vrate = vmode->hrate/vtotal*2; | |
818 } else { | |
819 vmode->drate = 0; | |
820 vmode->hrate = 0; | |
821 vmode->vrate = 0; | |
822 } | |
823 | |
824 return 1; | |
825 } | |
826 | |
827 | |
828 /* | |
829 * Print the Usage Template and Exit | |
830 */ | |
831 | |
832 static void Usage(void) | |
833 { | |
834 puts(VERSION); | |
835 Die("\nUsage: %s [options] [mode]\n\n" | |
836 "Valid options:\n" | |
837 " General options:\n" | |
838 " -h, --help : display this usage information\n" | |
839 " --test : don't change, just test whether the mode is " | |
840 "valid\n" | |
841 " -s, --show : display video mode settings\n" | |
842 " -i, --info : display all frame buffer information\n" | |
843 " -v, --verbose : verbose mode\n" | |
844 " -V, --version : print version information\n" | |
845 " -x, --xfree86 : XFree86 compatibility mode\n" | |
846 " -a, --all : change all virtual consoles on this device\n" | |
847 " Frame buffer special device nodes:\n" | |
848 " -fb <device> : processed frame buffer device\n" | |
849 " (default is " DEFAULT_FRAMEBUFFER ")\n" | |
850 " Video mode database:\n" | |
851 " -db <file> : video mode database file\n" | |
852 " (default is " DEFAULT_MODEDBFILE ")\n" | |
853 " Display geometry:\n" | |
854 " -xres <value> : horizontal resolution (in pixels)\n" | |
855 " -yres <value> : vertical resolution (in pixels)\n" | |
856 " -vxres <value> : virtual horizontal resolution (in pixels)\n" | |
857 " -vyres <value> : virtual vertical resolution (in pixels)\n" | |
858 " -depth <value> : display depth (in bits per pixel)\n" | |
859 " -nonstd <value> : select nonstandard video mode\n" | |
860 " -g, --geometry ... : set all geometry parameters at once\n" | |
861 " -match : set virtual vertical resolution by virtual resolution\n" | |
862 " Display timings:\n" | |
863 " -pixclock <value> : pixel clock (in picoseconds)\n" | |
864 " -left <value> : left margin (in pixels)\n" | |
865 " -right <value> : right margin (in pixels)\n" | |
866 " -upper <value> : upper margin (in pixel lines)\n" | |
867 " -lower <value> : lower margin (in pixel lines)\n" | |
868 " -hslen <value> : horizontal sync length (in pixels)\n" | |
869 " -vslen <value> : vertical sync length (in pixel lines)\n" | |
870 " -t, --timings ... : set all timing parameters at once\n" | |
871 " Display flags:\n" | |
872 " -accel <value> : hardware text acceleration enable (false or " | |
873 "true)\n" | |
874 " -hsync <value> : horizontal sync polarity (low or high)\n" | |
875 " -vsync <value> : vertical sync polarity (low or high)\n" | |
876 " -csync <value> : composite sync polarity (low or high)\n" | |
877 " -gsync <value> : synch on green (false or true)\n" | |
878 " -extsync <value> : external sync enable (false or true)\n" | |
879 " -bcast <value> : broadcast enable (false or true)\n" | |
880 " -laced <value> : interlace enable (false or true)\n" | |
881 " -double <value> : doublescan enable (false or true)\n" | |
882 " -rgba <r,g,b,a> : recommended length of color entries\n" | |
883 " -grayscale <value> : grayscale enable (false or true)\n" | |
884 " Display positioning:\n" | |
885 " -move <direction> : move the visible part (left, right, up or " | |
886 "down)\n" | |
887 " -step <value> : step increment (in pixels or pixel lines)\n" | |
888 " (default is 8 horizontal, 2 vertical)\n", | |
889 ProgramName); | |
890 } | |
891 | |
892 | |
893 /* | |
894 * Main Routine | |
895 */ | |
896 | |
897 int main(int argc, char *argv[]) | |
898 { | |
899 struct VideoMode *vmode; | |
900 struct fb_var_screeninfo var; | |
901 struct fb_fix_screeninfo fix; | |
902 int fh = -1, i; | |
903 | |
904 ProgramName = argv[0]; | |
905 | |
906 /* | |
907 * Parse the Options | |
908 */ | |
909 | |
910 while (--argc > 0) { | |
911 argv++; | |
912 if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) | |
913 Usage(); | |
914 else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--verbose")) | |
915 Opt_verbose = 1; | |
916 else if (!strcmp(argv[0], "-V") || !strcmp(argv[0], "--version")) | |
917 Opt_version = 1; | |
918 else if (!strcmp(argv[0], "--test")) | |
919 Opt_test = 1; | |
920 else if (!strcmp(argv[0], "-s") || !strcmp(argv[0], "--show")) | |
921 Opt_show = 1; | |
922 else if (!strcmp(argv[0], "-i") || !strcmp(argv[0], "--info")) { | |
923 Opt_show = 1; | |
924 Opt_info = 1; | |
925 } else if (!strcmp(argv[0], "-x") || !strcmp(argv[0], "--xfree86")) | |
926 Opt_xfree86 = 1; | |
927 else if (!strcmp(argv[0], "-a") || !strcmp(argv[0], "--all")) | |
928 Opt_all = 1; | |
929 else if (!strcmp(argv[0], "-g") || !strcmp(argv[0], "--geometry")) { | |
930 if (argc > 5) { | |
931 Opt_xres = argv[1]; | |
932 Opt_yres = argv[2]; | |
933 Opt_vxres = argv[3]; | |
934 Opt_vyres = argv[4]; | |
935 Opt_depth = argv[5]; | |
936 Opt_change = 1; | |
937 argc -= 5; | |
938 argv += 5; | |
939 } else | |
940 Usage(); | |
941 } else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--timings")) { | |
942 if (argc > 7) { | |
943 Opt_pixclock = argv[1]; | |
944 Opt_left = argv[2]; | |
945 Opt_right = argv[3]; | |
946 Opt_upper = argv[4]; | |
947 Opt_lower = argv[5]; | |
948 Opt_hslen = argv[6]; | |
949 Opt_vslen = argv[7]; | |
950 Opt_change = 1; | |
951 argc -= 7; | |
952 argv += 7; | |
953 } else | |
954 Usage(); | |
955 } else if (!strcmp(argv[0], "-match")) { | |
956 Opt_matchyres = argv[0]; | |
957 Opt_change = 1; | |
958 } else { | |
959 for (i = 0; Options[i].name; i++) | |
960 if (!strcmp(argv[0], Options[i].name)) | |
961 break; | |
962 if (Options[i].name) { | |
963 if (argc-- > 1) { | |
964 *Options[i].value = argv[1]; | |
965 Opt_change |= Options[i].change; | |
966 argv++; | |
967 } else | |
968 Usage(); | |
969 } else if (!Opt_modename) { | |
970 Opt_modename = argv[0]; | |
971 Opt_change = 1; | |
972 } else | |
973 Usage(); | |
974 } | |
975 } | |
976 | |
977 if (Opt_version || Opt_verbose) | |
978 puts(VERSION); | |
979 | |
980 if (!Opt_fb) | |
981 Opt_fb = DEFAULT_FRAMEBUFFER; | |
982 | |
983 /* | |
984 * Open the Frame Buffer Device | |
985 */ | |
986 | |
987 fh = OpenFrameBuffer(Opt_fb); | |
988 | |
989 /* | |
990 * Get the Video Mode | |
991 */ | |
992 | |
993 if (Opt_modename) { | |
994 | |
995 /* | |
996 * Read the Video Mode Database | |
997 */ | |
998 | |
999 ReadModeDB(); | |
1000 | |
1001 if (!(vmode = FindVideoMode(Opt_modename))) | |
1002 Die("Unknown video mode `%s'\n", Opt_modename); | |
1003 | |
1004 Current = *vmode; | |
1005 if (Opt_verbose) | |
1006 printf("Using video mode `%s'\n", Opt_modename); | |
1007 } else { | |
1008 GetVarScreenInfo(fh, &var); | |
1009 ConvertToVideoMode(&var, &Current); | |
1010 if (Opt_verbose) | |
1011 printf("Using current video mode from `%s'\n", Opt_fb); | |
1012 } | |
1013 | |
1014 if (Opt_change) { | |
1015 | |
1016 /* | |
1017 * Optionally Modify the Video Mode | |
1018 */ | |
1019 | |
1020 ModifyVideoMode(&Current); | |
1021 | |
1022 /* | |
1023 * Set the Video Mode | |
1024 */ | |
1025 | |
1026 ConvertFromVideoMode(&Current, &var); | |
1027 if (Opt_verbose) | |
1028 printf("Setting video mode to `%s'\n", Opt_fb); | |
1029 SetVarScreenInfo(fh, &var); | |
1030 ConvertToVideoMode(&var, &Current); | |
1031 } | |
1032 | |
1033 /* | |
1034 * Display some Video Mode Information | |
1035 */ | |
1036 | |
1037 if (Opt_show || !Opt_change) | |
1038 DisplayVModeInfo(&Current); | |
1039 | |
1040 if (Opt_info) { | |
1041 if (Opt_verbose) | |
1042 puts("Getting further frame buffer information"); | |
1043 GetFixScreenInfo(fh, &fix); | |
1044 DisplayFBInfo(&fix); | |
1045 } | |
1046 | |
1047 /* | |
1048 * Close the Frame Buffer Device | |
1049 */ | |
1050 | |
1051 CloseFrameBuffer(fh); | |
1052 | |
1053 exit(0); | |
1054 } |