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 }