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