vidcontrol.c revision 99705
12089Ssos/*- 216565Ssos * Copyright (c) 1994-1996 S�ren Schmidt 32089Ssos * All rights reserved. 42089Ssos * 52089Ssos * Redistribution and use in source and binary forms, with or without 62089Ssos * modification, are permitted provided that the following conditions 72089Ssos * are met: 82089Ssos * 1. Redistributions of source code must retain the above copyright 95994Ssos * notice, this list of conditions and the following disclaimer, 105994Ssos * in this position and unchanged. 112089Ssos * 2. Redistributions in binary form must reproduce the above copyright 122089Ssos * notice, this list of conditions and the following disclaimer in the 132089Ssos * documentation and/or other materials provided with the distribution. 142089Ssos * 3. The name of the author may not be used to endorse or promote products 1597748Sschweikh * derived from this software without specific prior written permission 162089Ssos * 172089Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 182089Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 192089Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 202089Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 212089Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 222089Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232089Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242089Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252089Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 262089Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272089Ssos */ 282089Ssos 2930764Scharnier#ifndef lint 3030764Scharnierstatic const char rcsid[] = 3150479Speter "$FreeBSD: head/usr.sbin/vidcontrol/vidcontrol.c 99705 2002-07-10 03:31:25Z dd $"; 3230764Scharnier#endif /* not lint */ 3330764Scharnier 342089Ssos#include <ctype.h> 3530764Scharnier#include <err.h> 3655849Syokota#include <limits.h> 372089Ssos#include <stdio.h> 3823457Sbrian#include <stdlib.h> 3930764Scharnier#include <string.h> 4023702Speter#include <unistd.h> 4166834Sphk#include <sys/fbio.h> 4266834Sphk#include <sys/consio.h> 432089Ssos#include <sys/errno.h> 4475344Ssobomax#include <sys/types.h> 4575344Ssobomax#include <sys/stat.h> 462089Ssos#include "path.h" 4723457Sbrian#include "decode.h" 482089Ssos 4971642Ssobomax#define _VESA_800x600_DFL_COLS 80 5071642Ssobomax#define _VESA_800x600_DFL_ROWS 25 5171642Ssobomax#define _VESA_800x600_DFL_FNSZ 16 5271642Ssobomax 5376845Ssobomax#define DUMP_RAW 0 5476845Ssobomax#define DUMP_TXT 1 5576845Ssobomax 5676845Ssobomax#define DUMP_FMT_REV 1 5776845Ssobomax 582089Ssoschar legal_colors[16][16] = { 592089Ssos "black", "blue", "green", "cyan", 602089Ssos "red", "magenta", "brown", "white", 612089Ssos "grey", "lightblue", "lightgreen", "lightcyan", 622089Ssos "lightred", "lightmagenta", "yellow", "lightwhite" 636628Ssos}; 642089Ssosint hex = 0; 656047Ssosint number; 6671642Ssobomaxint vesa_cols = _VESA_800x600_DFL_COLS; 6771642Ssobomaxint vesa_rows = _VESA_800x600_DFL_ROWS; 682089Ssoschar letter; 692089Ssosstruct vid_info info; 702089Ssos 712089Ssos 7230764Scharnierstatic void 736628Ssosusage() 746628Ssos{ 7555849Syokota fprintf(stderr, "%s\n%s\n%s\n%s\n", 7677329Sdes"usage: vidcontrol [-CdLPpx] [-b color] [-c appearance] [-f [size] file]", 7777329Sdes" [-g geometry] [-h size] [-i adapter | mode] [-l screen_map]", 7877329Sdes" [-m on | off] [-M char] [-r foreground background] [-s num]", 7999705Sdd" [-S on | off] [-t N | off] [mode] [foreground [background]] [show]"); 8030764Scharnier exit(1); 816628Ssos} 826628Ssos 832089Ssoschar * 8475344Ssobomaxnextarg(int ac, char **av, int *indp, int oc, int strict) 852089Ssos{ 862089Ssos if (*indp < ac) 872089Ssos return(av[(*indp)++]); 8875344Ssobomax if (strict != 0) 8975344Ssobomax errx(1, "option requires two arguments -- %c", oc); 9075344Ssobomax return(NULL); 912089Ssos} 922089Ssos 9392460SsobomaxFILE * 9492460Ssobomaxopenguess(char *a[], char *b[], char *c[], char *d[], char **name) 952089Ssos{ 9692460Ssobomax FILE *f; 9792460Ssobomax int i, j, k, l; 982089Ssos 9992460Ssobomax for (i = 0; a[i] != NULL; i++) { 10092460Ssobomax for (j = 0; b[j] != NULL; j++) { 10192460Ssobomax for (k = 0; c[k] != NULL; k++) { 10292460Ssobomax for (l = 0; d[l] != NULL; l++) { 10392460Ssobomax asprintf(name, "%s%s%s%s", a[i], b[j], 10492460Ssobomax c[k], d[l]); 10592460Ssobomax f = fopen(*name, "r"); 10692460Ssobomax if (f != NULL) 10792460Ssobomax return (f); 10892460Ssobomax free(*name); 10992460Ssobomax } 11092460Ssobomax } 11192460Ssobomax } 11252262Sbillf } 11392460Ssobomax return (NULL); 1142089Ssos} 1152089Ssos 1162089Ssosvoid 1172089Ssosload_scrnmap(char *filename) 1182089Ssos{ 11992460Ssobomax FILE *fd; 12092460Ssobomax int size; 1212089Ssos char *name; 1222089Ssos scrmap_t scrnmap; 12392460Ssobomax char *a[] = {"", SCRNMAP_PATH, NULL}; 12492460Ssobomax char *b[] = {filename, NULL}; 12592460Ssobomax char *c[] = {"", ".scm", NULL}; 12692460Ssobomax char *d[] = {"", NULL}; 1272089Ssos 12892460Ssobomax fd = openguess(a, b, c, d, &name); 1292089Ssos if (fd == NULL) { 13030764Scharnier warn("screenmap file not found"); 1312089Ssos return; 1322089Ssos } 1332089Ssos size = sizeof(scrnmap); 13475344Ssobomax if (decode(fd, (char *)&scrnmap, size) != size) { 1352089Ssos rewind(fd); 1362089Ssos if (fread(&scrnmap, 1, size, fd) != size) { 13730764Scharnier warnx("bad screenmap file"); 13823457Sbrian fclose(fd); 1392089Ssos return; 1402089Ssos } 1412089Ssos } 1422089Ssos if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 14330764Scharnier warn("can't load screenmap"); 14423457Sbrian fclose(fd); 1452089Ssos} 1462089Ssos 1472089Ssosvoid 1482089Ssosload_default_scrnmap() 1492089Ssos{ 1506628Ssos scrmap_t scrnmap; 1512089Ssos int i; 1522089Ssos 1532089Ssos for (i=0; i<256; i++) 1542089Ssos *((char*)&scrnmap + i) = i; 1552089Ssos if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) 15630764Scharnier warn("can't load default screenmap"); 1572089Ssos} 1582089Ssos 1592089Ssosvoid 1602089Ssosprint_scrnmap() 1612089Ssos{ 1622089Ssos unsigned char map[256]; 1632089Ssos int i; 1642089Ssos 1652089Ssos if (ioctl(0, GIO_SCRNMAP, &map) < 0) { 16630764Scharnier warn("getting screenmap"); 1672089Ssos return; 1682089Ssos } 1692089Ssos for (i=0; i<sizeof(map); i++) { 1702089Ssos if (i > 0 && i % 16 == 0) 1712089Ssos fprintf(stdout, "\n"); 1722089Ssos if (hex) 1738857Srgrimes fprintf(stdout, " %02x", map[i]); 1742089Ssos else 1752089Ssos fprintf(stdout, " %03d", map[i]); 1762089Ssos } 1772089Ssos fprintf(stdout, "\n"); 1782089Ssos 1792089Ssos} 1802089Ssos 18175344Ssobomaxint 18275344Ssobomaxfsize(FILE *file) 18375344Ssobomax{ 18475344Ssobomax struct stat sb; 18575344Ssobomax 18675344Ssobomax if (fstat(fileno(file), &sb) == 0) 18775344Ssobomax return sb.st_size; 18875344Ssobomax else 18975344Ssobomax return -1; 19075344Ssobomax} 19175344Ssobomax 19275344Ssobomax#define DATASIZE(x) ((x).w * (x).h * 256 / 8) 19375344Ssobomax 1948857Srgrimesvoid 1952089Ssosload_font(char *type, char *filename) 1962089Ssos{ 19792460Ssobomax FILE *fd; 19875344Ssobomax int h, i, size, w; 19975344Ssobomax unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */ 20092460Ssobomax char *name, *fontmap, size_sufx[6]; 20192460Ssobomax char *a[] = {"", FONT_PATH, NULL}; 20292460Ssobomax char *b[] = {filename, NULL}; 20392460Ssobomax char *c[] = {"", size_sufx, NULL}; 20492460Ssobomax char *d[] = {"", ".fnt", NULL}; 20592460Ssobomax vid_info_t info; 2062089Ssos 20775344Ssobomax struct sizeinfo { 20875344Ssobomax int w; 20975344Ssobomax int h; 21075344Ssobomax unsigned long io; 21175344Ssobomax } sizes[] = {{8, 16, PIO_FONT8x16}, 21275344Ssobomax {8, 14, PIO_FONT8x14}, 21375344Ssobomax {8, 8, PIO_FONT8x8}, 21475344Ssobomax {0, 0, 0}}; 21575344Ssobomax 21692460Ssobomax info.size = sizeof(info); 21792460Ssobomax if (ioctl(0, CONS_GETINFO, &info) == -1) { 21892460Ssobomax warn("failed to obtain current video mode parameters"); 21992460Ssobomax return; 2202089Ssos } 22192460Ssobomax snprintf(size_sufx, sizeof(size_sufx), "-8x%d", info.font_size); 22292460Ssobomax fd = openguess(a, b, c, d, &name); 2232089Ssos if (fd == NULL) { 22475344Ssobomax warn("%s: can't load font file", filename); 2252089Ssos return; 2262089Ssos } 22775344Ssobomax if (type != NULL) { 22875344Ssobomax size = 0; 22975344Ssobomax if (sscanf(type, "%dx%d", &w, &h) == 2) 23075344Ssobomax for (i = 0; sizes[i].w != 0; i++) 23175344Ssobomax if (sizes[i].w == w && sizes[i].h == h) { 23275344Ssobomax size = DATASIZE(sizes[i]); 23375344Ssobomax io = sizes[i].io; 23475344Ssobomax } 23575344Ssobomax 23675344Ssobomax if (size == 0) { 23775344Ssobomax warnx("%s: bad font size specification", type); 23875344Ssobomax fclose(fd); 23975344Ssobomax return; 24075344Ssobomax } 24175344Ssobomax } else { 24275344Ssobomax /* Apply heuristics */ 24375344Ssobomax int j; 24475344Ssobomax int dsize[2]; 24575344Ssobomax 24675344Ssobomax size = DATASIZE(sizes[0]); 24775344Ssobomax fontmap = (char*) malloc(size); 24875344Ssobomax dsize[0] = decode(fd, fontmap, size); 24975344Ssobomax dsize[1] = fsize(fd); 25075344Ssobomax free(fontmap); 25175344Ssobomax 25275344Ssobomax size = 0; 25375344Ssobomax for (j = 0; j < 2; j++) 25475344Ssobomax for (i = 0; sizes[i].w != 0; i++) 25575344Ssobomax if (DATASIZE(sizes[i]) == dsize[j]) { 25675344Ssobomax size = dsize[j]; 25775344Ssobomax io = sizes[i].io; 25875344Ssobomax j = 2; /* XXX */ 25975344Ssobomax break; 26075344Ssobomax } 26175344Ssobomax 26275344Ssobomax if (size == 0) { 26375344Ssobomax warnx("%s: can't guess font size", filename); 26475344Ssobomax fclose(fd); 26575344Ssobomax return; 26675344Ssobomax } 26775344Ssobomax rewind(fd); 2682089Ssos } 26975344Ssobomax 2702089Ssos fontmap = (char*) malloc(size); 27175344Ssobomax if (decode(fd, fontmap, size) != size) { 2722089Ssos rewind(fd); 27375344Ssobomax if (fsize(fd) != size || fread(fontmap, 1, size, fd) != size) { 27475344Ssobomax warnx("%s: bad font file", filename); 27523457Sbrian fclose(fd); 2762089Ssos free(fontmap); 2772089Ssos return; 2782089Ssos } 2792089Ssos } 2802089Ssos if (ioctl(0, io, fontmap) < 0) 28130764Scharnier warn("can't load font"); 28223457Sbrian fclose(fd); 2832089Ssos free(fontmap); 2842089Ssos} 2852089Ssos 2862089Ssosvoid 2872089Ssosset_screensaver_timeout(char *arg) 2882089Ssos{ 2892089Ssos int nsec; 2902089Ssos 2912089Ssos if (!strcmp(arg, "off")) 2922089Ssos nsec = 0; 2932089Ssos else { 2942089Ssos nsec = atoi(arg); 2952089Ssos if ((*arg == '\0') || (nsec < 1)) { 29630764Scharnier warnx("argument must be a positive number"); 2972089Ssos return; 2982089Ssos } 2992089Ssos } 3002089Ssos if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) 30130764Scharnier warn("setting screensaver period"); 3022089Ssos} 3032089Ssos 3042089Ssosvoid 3055536Ssosset_cursor_type(char *appearence) 3062089Ssos{ 3075536Ssos int type; 3082089Ssos 3096230Ssos if (!strcmp(appearence, "normal")) 3106230Ssos type = 0; 3116230Ssos else if (!strcmp(appearence, "blink")) 3125536Ssos type = 1; 3136230Ssos else if (!strcmp(appearence, "destructive")) 3146230Ssos type = 3; 3155536Ssos else { 31630764Scharnier warnx("argument to -c must be normal, blink or destructive"); 3172089Ssos return; 3182089Ssos } 3195536Ssos ioctl(0, CONS_CURSORTYPE, &type); 3202089Ssos} 3212089Ssos 32223457Sbrianvoid 3232089Ssosvideo_mode(int argc, char **argv, int *index) 3242089Ssos{ 32539592Syokota static struct { 32639592Syokota char *name; 32739592Syokota unsigned long mode; 32839592Syokota } modes[] = { 32939592Syokota { "80x25", SW_TEXT_80x25 }, 33039592Syokota { "80x30", SW_TEXT_80x30 }, 33139592Syokota { "80x43", SW_TEXT_80x43 }, 33239592Syokota { "80x50", SW_TEXT_80x50 }, 33339592Syokota { "80x60", SW_TEXT_80x60 }, 33439592Syokota { "132x25", SW_TEXT_132x25 }, 33539592Syokota { "132x30", SW_TEXT_132x30 }, 33639592Syokota { "132x43", SW_TEXT_132x43 }, 33739592Syokota { "132x50", SW_TEXT_132x50 }, 33839592Syokota { "132x60", SW_TEXT_132x60 }, 33939592Syokota { "VGA_40x25", SW_VGA_C40x25 }, 34039592Syokota { "VGA_80x25", SW_VGA_C80x25 }, 34139592Syokota { "VGA_80x30", SW_VGA_C80x30 }, 34239592Syokota { "VGA_80x50", SW_VGA_C80x50 }, 34339592Syokota { "VGA_80x60", SW_VGA_C80x60 }, 34448105Syokota#ifdef SW_VGA_C90x25 34548105Syokota { "VGA_90x25", SW_VGA_C90x25 }, 34648105Syokota { "VGA_90x30", SW_VGA_C90x30 }, 34748105Syokota { "VGA_90x43", SW_VGA_C90x43 }, 34848105Syokota { "VGA_90x50", SW_VGA_C90x50 }, 34948105Syokota { "VGA_90x60", SW_VGA_C90x60 }, 35048105Syokota#endif 35139592Syokota { "VGA_320x200", SW_VGA_CG320 }, 35239592Syokota { "EGA_80x25", SW_ENH_C80x25 }, 35339592Syokota { "EGA_80x43", SW_ENH_C80x43 }, 35439592Syokota { "VESA_132x25", SW_VESA_C132x25 }, 35539592Syokota { "VESA_132x43", SW_VESA_C132x43 }, 35639592Syokota { "VESA_132x50", SW_VESA_C132x50 }, 35739592Syokota { "VESA_132x60", SW_VESA_C132x60 }, 35839592Syokota { "VESA_800x600", SW_VESA_800x600 }, 35939592Syokota { NULL }, 36039592Syokota }; 36142605Smjacob unsigned long mode = 0; 36248105Syokota int cur_mode; 36348105Syokota int ioerr; 36439287Ssos int size[3]; 36539592Syokota int i; 3662089Ssos 36748105Syokota if (ioctl(0, CONS_GET, &cur_mode) < 0) 36848105Syokota err(1, "cannot get the current video mode"); 3692089Ssos if (*index < argc) { 37039592Syokota for (i = 0; modes[i].name != NULL; ++i) { 37139592Syokota if (!strcmp(argv[*index], modes[i].name)) { 37239592Syokota mode = modes[i].mode; 37339592Syokota break; 37439592Syokota } 37539592Syokota } 37639592Syokota if (modes[i].name == NULL) 3772089Ssos return; 3782089Ssos if (ioctl(0, mode, NULL) < 0) 37930764Scharnier warn("cannot set videomode"); 38039287Ssos if (mode == SW_VESA_800x600) { 38171642Ssobomax /* columns */ 38271642Ssobomax if ((vesa_cols * 8 > 800) || (vesa_cols <= 0)) { 38371642Ssobomax warnx("incorrect number of columns: %d", 38471642Ssobomax vesa_cols); 38571642Ssobomax size[0] = _VESA_800x600_DFL_COLS; 38671642Ssobomax } else { 38771642Ssobomax size[0] = vesa_cols; 38871642Ssobomax } 38971642Ssobomax /* rows */ 39071642Ssobomax if ((vesa_rows * _VESA_800x600_DFL_FNSZ > 600) || 39171642Ssobomax (vesa_rows <=0)) { 39271642Ssobomax warnx("incorrect number of rows: %d", 39371642Ssobomax vesa_rows); 39471642Ssobomax size[1] = _VESA_800x600_DFL_ROWS; 39571642Ssobomax } else { 39671642Ssobomax size[1] = vesa_rows; 39771642Ssobomax } 39871642Ssobomax /* font size */ 39971642Ssobomax size[2] = _VESA_800x600_DFL_FNSZ; 40048105Syokota if (ioctl(0, KDRASTER, size)) { 40148105Syokota ioerr = errno; 40248105Syokota if (cur_mode >= M_VESA_BASE) 40380148Syokota ioctl(0, 40480148Syokota _IO('V', cur_mode - M_VESA_BASE), 40580148Syokota NULL); 40648105Syokota else 40748105Syokota ioctl(0, _IO('S', cur_mode), NULL); 40848105Syokota warnc(ioerr, "cannot activate raster display"); 40948105Syokota } 41039287Ssos } 4112089Ssos (*index)++; 4122089Ssos } 4132089Ssos return; 4142089Ssos} 4158857Srgrimes 4162089Ssosint 4172089Ssosget_color_number(char *color) 4182089Ssos{ 4192089Ssos int i; 4202089Ssos 4212089Ssos for (i=0; i<16; i++) 4222089Ssos if (!strcmp(color, legal_colors[i])) 4232089Ssos return i; 4242089Ssos return -1; 4252089Ssos} 4262089Ssos 42723457Sbrianvoid 4282089Ssosset_normal_colors(int argc, char **argv, int *index) 4292089Ssos{ 4302089Ssos int color; 4312089Ssos 4322089Ssos if (*index < argc && (color = get_color_number(argv[*index])) != -1) { 4332089Ssos (*index)++; 4342089Ssos fprintf(stderr, "[=%dF", color); 4358857Srgrimes if (*index < argc 4368857Srgrimes && (color = get_color_number(argv[*index])) != -1 4372089Ssos && color < 8) { 4382089Ssos (*index)++; 4392089Ssos fprintf(stderr, "[=%dG", color); 4402089Ssos } 4412089Ssos } 4422089Ssos} 4432089Ssos 44423457Sbrianvoid 4452089Ssosset_reverse_colors(int argc, char **argv, int *index) 4462089Ssos{ 4472089Ssos int color; 4482089Ssos 4492089Ssos if ((color = get_color_number(argv[*(index)-1])) != -1) { 4502089Ssos fprintf(stderr, "[=%dH", color); 4518857Srgrimes if (*index < argc 4528857Srgrimes && (color = get_color_number(argv[*index])) != -1 4532089Ssos && color < 8) { 4542089Ssos (*index)++; 4552089Ssos fprintf(stderr, "[=%dI", color); 4562089Ssos } 4572089Ssos } 4582089Ssos} 4592089Ssos 46023457Sbrianvoid 46123457Sbrianset_console(char *arg) 46223457Sbrian{ 46323457Sbrian int n; 46423457Sbrian 46523457Sbrian if( !arg || strspn(arg,"0123456789") != strlen(arg)) { 46630764Scharnier warnx("bad console number"); 46723457Sbrian return; 46823457Sbrian } 46923457Sbrian 47023457Sbrian n = atoi(arg); 47151393Syokota if (n < 1 || n > 16) { 47230764Scharnier warnx("console number out of range"); 47342605Smjacob } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1) 47430764Scharnier warn("ioctl(VT_ACTIVATE)"); 47523457Sbrian} 47623457Sbrian 47723457Sbrianvoid 4782089Ssosset_border_color(char *arg) 4792089Ssos{ 4802089Ssos int color; 4812089Ssos 4822089Ssos if ((color = get_color_number(arg)) != -1) { 4832089Ssos fprintf(stderr, "[=%dA", color); 4842089Ssos } 4852089Ssos else 4868857Srgrimes usage(); 4872089Ssos} 4882089Ssos 48916565Ssosvoid 49055849Syokotaset_mouse_char(char *arg) 49155849Syokota{ 49255849Syokota struct mouse_info mouse; 49355849Syokota long l; 49455849Syokota 49555849Syokota l = strtol(arg, NULL, 0); 49675788Sache if ((l < 0) || (l > UCHAR_MAX - 3)) { 49775788Sache warnx("argument to -M must be 0 through %d", UCHAR_MAX - 3); 49855849Syokota return; 49955849Syokota } 50055849Syokota mouse.operation = MOUSE_MOUSECHAR; 50155849Syokota mouse.u.mouse_char = (int)l; 50255849Syokota ioctl(0, CONS_MOUSECTL, &mouse); 50355849Syokota} 50455849Syokota 50555849Syokotavoid 50616565Ssosset_mouse(char *arg) 50716565Ssos{ 50816565Ssos struct mouse_info mouse; 50916565Ssos 51016565Ssos if (!strcmp(arg, "on")) 51116565Ssos mouse.operation = MOUSE_SHOW; 51216565Ssos else if (!strcmp(arg, "off")) 51316565Ssos mouse.operation = MOUSE_HIDE; 51416565Ssos else { 51530764Scharnier warnx("argument to -m must either on or off"); 51616565Ssos return; 51716565Ssos } 51816565Ssos ioctl(0, CONS_MOUSECTL, &mouse); 51916565Ssos} 52016565Ssos 52199705Sddvoid 52299705Sddset_lockswitch(char *arg) 52399705Sdd{ 52499705Sdd int data; 52599705Sdd 52699705Sdd if (!strcmp(arg, "off")) 52799705Sdd data = 0x01; 52899705Sdd else if (!strcmp(arg, "on")) 52999705Sdd data = 0x02; 53099705Sdd else { 53199705Sdd warnx("argument to -S must either on or off"); 53299705Sdd return; 53399705Sdd } 53499705Sdd if (ioctl(0, VT_LOCKSWITCH, &data) == -1) 53599705Sdd warn("ioctl(VT_LOCKSWITCH)"); 53699705Sdd} 53799705Sdd 53839287Ssosstatic char 53939287Ssos*adapter_name(int type) 54039287Ssos{ 54139287Ssos static struct { 54239287Ssos int type; 54339287Ssos char *name; 54439287Ssos } names[] = { 54539287Ssos { KD_MONO, "MDA" }, 54639287Ssos { KD_HERCULES, "Hercules" }, 54739287Ssos { KD_CGA, "CGA" }, 54839287Ssos { KD_EGA, "EGA" }, 54939287Ssos { KD_VGA, "VGA" }, 55039287Ssos { KD_PC98, "PC-98xx" }, 55148105Syokota { KD_TGA, "TGA" }, 55239287Ssos { -1, "Unknown" }, 55339287Ssos }; 55439287Ssos int i; 55539287Ssos 55639287Ssos for (i = 0; names[i].type != -1; ++i) 55739287Ssos if (names[i].type == type) 55839287Ssos break; 55939287Ssos return names[i].name; 56039287Ssos} 56139287Ssos 56223457Sbrianvoid 56339287Ssosshow_adapter_info(void) 56439287Ssos{ 56542505Syokota struct video_adapter_info ad; 56639287Ssos 56739287Ssos ad.va_index = 0; 56839287Ssos if (ioctl(0, CONS_ADPINFO, &ad)) { 56939287Ssos warn("failed to obtain adapter information"); 57039287Ssos return; 57139287Ssos } 57239287Ssos 57342505Syokota printf("fb%d:\n", ad.va_index); 57442505Syokota printf(" %.*s%d, type:%s%s (%d), flags:0x%x\n", 57542505Syokota (int)sizeof(ad.va_name), ad.va_name, ad.va_unit, 57639287Ssos (ad.va_flags & V_ADP_VESA) ? "VESA " : "", 57742505Syokota adapter_name(ad.va_type), ad.va_type, ad.va_flags); 57839287Ssos printf(" initial mode:%d, current mode:%d, BIOS mode:%d\n", 57939287Ssos ad.va_initial_mode, ad.va_mode, ad.va_initial_bios_mode); 58048105Syokota printf(" frame buffer window:0x%x, buffer size:0x%x\n", 58148105Syokota ad.va_window, ad.va_buffer_size); 58248105Syokota printf(" window size:0x%x, origin:0x%x\n", 58348105Syokota ad.va_window_size, ad.va_window_orig); 58448105Syokota printf(" display start address (%d, %d), scan line width:%d\n", 58548105Syokota ad.va_disp_start.x, ad.va_disp_start.y, ad.va_line_width); 58648105Syokota printf(" reserved:0x%x\n", ad.va_unused0); 58739287Ssos} 58839287Ssos 58939287Ssosvoid 59039287Ssosshow_mode_info(void) 59139287Ssos{ 59239287Ssos struct video_info info; 59339287Ssos char buf[80]; 59439287Ssos int mode; 59539287Ssos int c; 59639287Ssos 59739287Ssos printf(" mode# flags type size " 59839287Ssos "font window linear buffer\n"); 59939287Ssos printf("---------------------------------------" 60039287Ssos "---------------------------------------\n"); 60139287Ssos for (mode = 0; mode < M_VESA_MODE_MAX; ++mode) { 60239287Ssos info.vi_mode = mode; 60339287Ssos if (ioctl(0, CONS_MODEINFO, &info)) 60439287Ssos continue; 60548105Syokota if (info.vi_mode != mode) 60648105Syokota continue; 60739287Ssos 60839287Ssos printf("%3d (0x%03x)", mode, mode); 60939287Ssos printf(" 0x%08x", info.vi_flags); 61039287Ssos if (info.vi_flags & V_INFO_GRAPHICS) { 61139287Ssos c = 'G'; 61239287Ssos snprintf(buf, sizeof(buf), "%dx%dx%d %d", 61339287Ssos info.vi_width, info.vi_height, 61439287Ssos info.vi_depth, info.vi_planes); 61539287Ssos } else { 61639287Ssos c = 'T'; 61739287Ssos snprintf(buf, sizeof(buf), "%dx%d", 61839287Ssos info.vi_width, info.vi_height); 61939287Ssos } 62039287Ssos printf(" %c %-15s", c, buf); 62139287Ssos snprintf(buf, sizeof(buf), "%dx%d", 62239287Ssos info.vi_cwidth, info.vi_cheight); 62339287Ssos printf(" %-5s", buf); 62439287Ssos printf(" 0x%05x %2dk %2dk", 62543186Sdfr info.vi_window, (int)info.vi_window_size/1024, 62643186Sdfr (int)info.vi_window_gran/1024); 62748105Syokota printf(" 0x%08x %dk\n", 62843186Sdfr info.vi_buffer, (int)info.vi_buffer_size/1024); 62939287Ssos } 63039287Ssos} 63139287Ssos 63239287Ssosvoid 63339287Ssosshow_info(char *arg) 63439287Ssos{ 63539287Ssos if (!strcmp(arg, "adapter")) 63639287Ssos show_adapter_info(); 63739287Ssos else if (!strcmp(arg, "mode")) 63839287Ssos show_mode_info(); 63939287Ssos else { 64039287Ssos warnx("argument to -i must either adapter or mode"); 64139287Ssos return; 64239287Ssos } 64339287Ssos} 64439287Ssos 64539287Ssosvoid 6462089Ssostest_frame() 6472089Ssos{ 6482089Ssos int i; 6492089Ssos 6502089Ssos fprintf(stdout, "[=0G\n\n"); 6512089Ssos for (i=0; i<8; i++) { 6522089Ssos fprintf(stdout, "[=15F[=0G %2d [=%dF%-16s" 6532089Ssos "[=15F[=0G %2d [=%dF%-16s " 6542089Ssos "[=15F %2d [=%dGBACKGROUND[=0G\n", 6558857Srgrimes i, i, legal_colors[i], i+8, i+8, 6568857Srgrimes legal_colors[i+8], i, i); 6572089Ssos } 6582089Ssos fprintf(stdout, "[=%dF[=%dG[=%dH[=%dI\n", 6598857Srgrimes info.mv_norm.fore, info.mv_norm.back, 6602089Ssos info.mv_rev.fore, info.mv_rev.back); 6612089Ssos} 6622089Ssos 66376845Ssobomax/* 66476845Ssobomax * Snapshot the video memory of that terminal, using the CONS_SCRSHOT 66576845Ssobomax * ioctl, and writes the results to stdout either in the special 66676845Ssobomax * binary format (see manual page for details), or in the plain 66776845Ssobomax * text format. 66876845Ssobomax */ 66976845Ssobomaxvoid 67076845Ssobomaxdump_screen(int mode) 67176845Ssobomax{ 67276845Ssobomax scrshot_t shot; 67376845Ssobomax vid_info_t info; 67476845Ssobomax 67576845Ssobomax info.size = sizeof(info); 67676845Ssobomax if (ioctl(0, CONS_GETINFO, &info) == -1) { 67776845Ssobomax warn("failed to obtain current video mode parameters"); 67876845Ssobomax return; 67976845Ssobomax } 68076845Ssobomax 68176845Ssobomax shot.buf = alloca(info.mv_csz * info.mv_rsz * sizeof(u_int16_t)); 68276845Ssobomax if (shot.buf == NULL) { 68376845Ssobomax warn("failed to allocate memory for dump"); 68476845Ssobomax return; 68576845Ssobomax } 68676845Ssobomax 68776845Ssobomax shot.xsize = info.mv_csz; 68876845Ssobomax shot.ysize = info.mv_rsz; 68976845Ssobomax if (ioctl(0, CONS_SCRSHOT, &shot) == -1) { 69076845Ssobomax warn("failed to get dump of the screen"); 69176845Ssobomax return; 69276845Ssobomax } 69376845Ssobomax 69476845Ssobomax if (mode == DUMP_RAW) { 69576845Ssobomax printf("SCRSHOT_%c%c%c%c", DUMP_FMT_REV, 2, 69676845Ssobomax shot.xsize, shot.ysize); 69776845Ssobomax fflush(stdout); 69876845Ssobomax 69976845Ssobomax (void)write(STDOUT_FILENO, shot.buf, 70076845Ssobomax shot.xsize * shot.ysize * sizeof(u_int16_t)); 70176845Ssobomax } else { 70276845Ssobomax char *line; 70376845Ssobomax int x, y; 70476845Ssobomax u_int16_t ch; 70576845Ssobomax 70676845Ssobomax line = alloca(shot.xsize + 1); 70776845Ssobomax if (line == NULL) { 70876845Ssobomax warn("failed to allocate memory for line buffer"); 70976845Ssobomax return; 71076845Ssobomax } 71176845Ssobomax 71276845Ssobomax for (y = 0; y < shot.ysize; y++) { 71376845Ssobomax for (x = 0; x < shot.xsize; x++) { 71476845Ssobomax ch = shot.buf[x + (y * shot.xsize)]; 71576845Ssobomax ch &= 0xff; 71676845Ssobomax if (isprint(ch) == 0) 71776845Ssobomax ch = ' '; 71876845Ssobomax line[x] = (char)ch; 71976845Ssobomax } 72076845Ssobomax 72176845Ssobomax /* Trim trailing spaces */ 72276845Ssobomax do { 72376845Ssobomax line[x--] = '\0'; 72476845Ssobomax } while (line[x] == ' ' && x != 0); 72576845Ssobomax 72676845Ssobomax puts(line); 72776845Ssobomax } 72876845Ssobomax fflush(stdout); 72976845Ssobomax } 73076845Ssobomax 73176845Ssobomax return; 73276845Ssobomax} 73376845Ssobomax 73477329Sdesvoid 73577329Sdesset_history(char *opt) 73677329Sdes{ 73777329Sdes int size; 73877329Sdes 73977329Sdes size = atoi(opt); 74077329Sdes if ((*opt == '\0') || size < 0) { 74177329Sdes warnx("argument must be a positive number"); 74277329Sdes return; 74377329Sdes } 74477329Sdes if (ioctl(0, CONS_HISTORY, &size) == -1) 74577329Sdes warn("setting history buffer size"); 74677329Sdes} 74777329Sdes 74877329Sdesvoid 74977329Sdesclear_history() 75077329Sdes{ 75177329Sdes 75277329Sdes if (ioctl(0, CONS_CLRHIST) == -1) 75377329Sdes warn("clear history buffer"); 75477329Sdes} 75577329Sdes 75623457Sbrianint 7572089Ssosmain(int argc, char **argv) 7582089Ssos{ 75975344Ssobomax char *font, *type; 76075344Ssobomax int opt; 7612089Ssos 7628857Srgrimes 7632089Ssos info.size = sizeof(info); 76476897Ssobomax if (argc == 1) 76576897Ssobomax usage(); 76676897Ssobomax /* Not reached */ 76730764Scharnier if (ioctl(0, CONS_GETINFO, &info) < 0) 76830764Scharnier err(1, "must be on a virtual console"); 76999705Sdd while((opt = getopt(argc, argv, "b:Cc:df:g:h:i:l:LM:m:pPr:S:s:t:x")) != -1) 7702089Ssos switch(opt) { 77177329Sdes case 'b': 77277329Sdes set_border_color(optarg); 77377329Sdes break; 77477329Sdes case 'C': 77577329Sdes clear_history(); 77677329Sdes break; 77777329Sdes case 'c': 77877329Sdes set_cursor_type(optarg); 77977329Sdes break; 78077329Sdes case 'd': 78177329Sdes print_scrnmap(); 78277329Sdes break; 78377329Sdes case 'f': 78477329Sdes type = optarg; 78577329Sdes font = nextarg(argc, argv, &optind, 'f', 0); 78677329Sdes if (font == NULL) { 78777329Sdes type = NULL; 78877329Sdes font = optarg; 78977329Sdes } 79077329Sdes load_font(type, font); 79177329Sdes break; 79277329Sdes case 'g': 79377329Sdes if (sscanf(optarg, "%dx%d", &vesa_cols, 79477329Sdes &vesa_rows) != 2) { 79577329Sdes warnx("incorrect geometry: %s", optarg); 7962089Ssos usage(); 79777329Sdes } 79877329Sdes break; 79977329Sdes case 'h': 80077329Sdes set_history(optarg); 80177329Sdes break; 80277329Sdes case 'i': 80377329Sdes show_info(optarg); 80477329Sdes break; 80577329Sdes case 'l': 80677329Sdes load_scrnmap(optarg); 80777329Sdes break; 80877329Sdes case 'L': 80977329Sdes load_default_scrnmap(); 81077329Sdes break; 81177329Sdes case 'M': 81277329Sdes set_mouse_char(optarg); 81377329Sdes break; 81477329Sdes case 'm': 81577329Sdes set_mouse(optarg); 81677329Sdes break; 81777329Sdes case 'p': 81877329Sdes dump_screen(DUMP_RAW); 81977329Sdes break; 82077329Sdes case 'P': 82177329Sdes dump_screen(DUMP_TXT); 82277329Sdes break; 82377329Sdes case 'r': 82477329Sdes set_reverse_colors(argc, argv, &optind); 82577329Sdes break; 82699705Sdd case 'S': 82799705Sdd set_lockswitch(optarg); 82899705Sdd break; 82977329Sdes case 's': 83077329Sdes set_console(optarg); 83177329Sdes break; 83277329Sdes case 't': 83377329Sdes set_screensaver_timeout(optarg); 83477329Sdes break; 83577329Sdes case 'x': 83677329Sdes hex = 1; 83777329Sdes break; 83877329Sdes default: 83977329Sdes usage(); 8402089Ssos } 84123457Sbrian video_mode(argc, argv, &optind); 84223457Sbrian set_normal_colors(argc, argv, &optind); 8432089Ssos if (optind < argc && !strcmp(argv[optind], "show")) { 8442089Ssos test_frame(); 8452089Ssos optind++; 8462089Ssos } 84730764Scharnier if ((optind != argc) || (argc == 1)) 8482089Ssos usage(); 84923457Sbrian return 0; 8502089Ssos} 8512089Ssos 852