On Aug 27, 2004 01:59:50 am +0000, Deng XueFeng wrote: > First to thanks Sascha Wildner <saw_at_online.de>. > he hack syscons to make dfbsd support 1024x768(16/24/32) syscons, > then I ported that to current. and it works well with my ati MOBILITY > 7500[T31]/9200 [NX7000]. > To make console support 1024x768; just type > #vidcontrol MODE_279 > > The originer patch can be get from dfbsd's maillist. here it is :) http://leaf.dragonflybsd.org/mailarchive/submit/2004-08/msg00074.html > and the attachment is against with FreeBSD CURRENT and 5.3 > enjoy it! > > NOTE: > current-vidcontrol.1 current-vidcontrol.c is taken from dfbsd. which > is include > Sascha's patch. Hi, I don't know why, but your patch set doesn't apply cleanly against -current ! so, I merged it in manually. also, take care while importing things to -current from DFBSD, since DFBSD is a fork from -stable. in other words, your patch set backout some change done in -current. the following patch set take care of this. I also tried to reduce the diff against -current whenever possible and made some style(9) changes (#define<tab> and <space>...<space> to <tab>). thanks anyway and good luck. PS : the following patch set applies and compiles cleanly against -current. however, I didn't have tested it yet since I can't reboot right now. Index: sys/dev/syscons/scvesactl.c =================================================================== RCS file: /home/ncvs/src/sys/dev/syscons/scvesactl.c,v retrieving revision 1.20 diff -u -I$Id.*$ -I$.+BSD.*$ -r1.20 scvesactl.c --- sys/dev/syscons/scvesactl.c 16 Jun 2004 09:46:58 -0000 1.20 +++ sys/dev/syscons/scvesactl.c 28 Aug 2004 01:12:21 -0000 _at__at_ -105,6 +105,17 _at__at_ return ENODEV; mode = (cmd & 0xff) + M_VESA_BASE; return sc_set_graphics_mode(scp, tp, mode); + default: + if (IOCGROUP(cmd) == 'V') { + if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + + mode = (cmd & 0xff) + M_VESA_BASE; + + if ((mode > M_VESA_FULL_1280) && + (mode < M_VESA_MODE_MAX)) + return sc_set_graphics_mode(scp, tp, mode); + } } if (prev_user_ioctl) Index: sys/dev/syscons/scvgarndr.c =================================================================== RCS file: /home/ncvs/src/sys/dev/syscons/scvgarndr.c,v retrieving revision 1.15 diff -u -I$Id.*$ -I$.+BSD.*$ -r1.15 scvgarndr.c --- sys/dev/syscons/scvgarndr.c 30 May 2004 20:08:42 -0000 1.15 +++ sys/dev/syscons/scvgarndr.c 28 Aug 2004 00:59:19 -0000 _at__at_ -47,7 +47,7 _at__at_ #include <isa/isareg.h> #ifndef SC_RENDER_DEBUG -#define SC_RENDER_DEBUG 0 +#define SC_RENDER_DEBUG 0 #endif static vr_clear_t vga_txtclear; _at__at_ -59,7 +59,7 _at__at_ #ifndef SC_NO_CUTPASTE static vr_draw_mouse_t vga_txtmouse; #else -#define vga_txtmouse (vr_draw_mouse_t *)vga_nop +#define vga_txtmouse (vr_draw_mouse_t *)vga_nop #endif #ifdef SC_PIXEL_MODE _at__at_ -73,7 +73,7 _at__at_ #ifndef SC_NO_CUTPASTE static vr_draw_mouse_t vga_pxlmouse; #else -#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop +#define vga_pxlmouse (vr_draw_mouse_t *)vga_nop #endif #endif /* SC_PIXEL_MODE */ _at__at_ -155,6 +155,37 _at__at_ #endif #endif +#ifdef SC_PIXEL_MODE +static uint32_t vga_palette32[16] = { + 0x000000, 0x0000ad, 0x00ad00, 0x00adad, + 0xad0000, 0xad00ad, 0xad5200, 0xadadad, + 0x525252, 0x5252ff, 0x52ff52, 0x52ffff, + 0xff5252, 0xff52ff, 0xffff52, 0xffffff +}; + +static uint16_t vga_palette16[16] = { + 0x0000, 0x0016, 0x0560, 0x0576, 0xb000, 0xb016, 0xb2a0, 0xb576, + 0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff +}; + +static uint16_t vga_palette15[16] = { + 0x0000, 0x0016, 0x02c0, 0x02d6, 0x5800, 0x5816, 0x5940, 0x5ad6, + 0x294a, 0x295f, 0x2bea, 0x2bff, 0x7d4a, 0x7d5f, 0x7fea, 0x7fff +}; + +#define VIDEO_MEMORY_POS(scp, pos, x) \ + scp->sc->adp->va_window + \ + x * scp->xoff + \ + scp->yoff * scp->font_size * scp->sc->adp->va_line_width + \ + x * (pos % scp->xsize) + \ + scp->font_size * scp->sc->adp->va_line_width * (pos / scp->xsize) + +#ifndef SC_NO_CUTPASTE +static uint32_t mouse_buf32[256]; +static uint16_t mouse_buf16[256]; +#endif +#endif + static void vga_nop(scr_stat *scp, ...) { _at__at_ -359,8 +390,8 _at__at_ yoffset = y%scp->font_size; for (i = 0; i < 16; ++i) { cursor[i + yoffset] = - (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) - | (mouse_or_mask[i] >> xoffset); + (cursor[i + yoffset] & ~(mouse_and_mask[i] >> xoffset)) + | (mouse_or_mask[i] >> xoffset); } for (i = 0; i < scp->font_size; ++i) { font_buf[i] = (cursor[i] & 0xff00) >> 8; _at__at_ -431,7 +462,29 _at__at_ /* pixel (raster text) mode renderer */ static void -vga_pxlclear(scr_stat *scp, int c, int attr) +vga_pxlclear_direct(scr_stat *scp, int c, int attr) +{ + vm_offset_t p; + int line_width; + int pixel_size; + int lines; + int i; + + line_width = scp->sc->adp->va_line_width; + pixel_size = scp->sc->adp->va_info.vi_pixel_size; + lines = scp->ysize * scp->font_size; + p = scp->sc->adp->va_window + + line_width * scp->yoff * scp->font_size + + scp->xoff * 8 * pixel_size; + + for (i = 0; i < lines; ++i) { + bzero_io((void *)p, scp->xsize * 8 * pixel_size); + p += line_width; + } +} + +static void +vga_pxlclear_planar(scr_stat *scp, int c, int attr) { vm_offset_t p; int line_width; _at__at_ -456,8 +509,121 _at__at_ outw(GDCIDX, 0x0001); /* set/reset enable */ } +vga_pxlclear(scr_stat *scp, int c, int attr) +{ + switch (scp->sc->adp->va_info.vi_mem_model) { + case V_INFO_MM_DIRECT: + vga_pxlclear_direct(scp, c, attr); + break; + case V_INFO_MM_PLANAR: + vga_pxlclear_planar(scp, c, attr); + break; + } +} + static void -vga_pxlborder(scr_stat *scp, int color) +vga_pxlborder_direct(scr_stat *scp, int color, int bpp) +{ + vm_offset_t s; + vm_offset_t e; + vm_offset_t f; + int line_width; + int pixel_size; + int x; + int y; + int i; + + line_width = scp->sc->adp->va_line_width; + pixel_size = scp->sc->adp->va_info.vi_pixel_size; + + if (scp->yoff > 0) { + s = scp->sc->adp->va_window; + e = s + line_width * scp->yoff * scp->font_size; + + for (f = s; f < e; f += pixel_size) { + switch (bpp) { + case 32: + writel(f, vga_palette32[color]); + break; + case 16: + writew(f, vga_palette16[color]); + break; + case 15: + writew(f, vga_palette15[color]); + break; + } + } + } + + y = (scp->yoff + scp->ysize) * scp->font_size; + + if (scp->ypixel > y) { + s = scp->sc->adp->va_window + line_width * y; + e = s + line_width * (scp->ypixel - y); + + for (f = s; f < e; f += pixel_size) { + switch (bpp) { + case 32: + writel(f, vga_palette32[color]); + break; + case 16: + writew(f, vga_palette16[color]); + break; + case 15: + writew(f, vga_palette15[color]); + break; + } + } + } + + y = scp->yoff * scp->font_size; + x = scp->xpixel / 8 - scp->xoff - scp->xsize; + + for (i = 0; i < scp->ysize * scp->font_size; ++i) { + if (scp->xoff > 0) { + s = scp->sc->adp->va_window + line_width * (y + i); + e = s + scp->xoff * 8 * pixel_size; + + for (f = s; f < e; f += pixel_size) { + switch (bpp) { + case 32: + writel(f, vga_palette32[color]); + break; + case 16: + writew(f, vga_palette16[color]); + break; + case 15: + writew(f, vga_palette15[color]); + break; + } + } + } + + if (x > 0) { + s = scp->sc->adp->va_window + line_width * (y + i) + + scp->xoff * 8 * pixel_size + + scp->xsize * 8 * pixel_size; + e = s + x * 8 * pixel_size; + + for (f = s; f < e; f += pixel_size) { + switch (bpp) { + case 32: + writel(f, vga_palette32[color]); + break; + case 16: + writew(f, vga_palette16[color]); + break; + case 15: + writew(f, vga_palette15[color]); + break; + } + } + } + } +} + +static void +vga_pxlborder_planar(scr_stat *scp, int color) { vm_offset_t p; int line_width; _at__at_ -492,6 +658,27 _at__at_ outw(GDCIDX, 0x0001); /* set/reset enable */ } +static void +vga_pxlborder(scr_stat *scp, int color) +{ + int bpp; + + switch (scp->sc->adp->va_info.vi_mem_model) { + case V_INFO_MM_DIRECT: + bpp = scp->sc->adp->va_info.vi_depth; + + if ((bpp == 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) + bpp = 15; + + vga_pxlborder_direct(scp, color, bpp); + break; + case V_INFO_MM_PLANAR: + vga_pxlborder_planar(scp, color); + break; + } +} + static void vga_egadraw(scr_stat *scp, int from, int count, int flip) { _at__at_ -506,11 +693,7 _at__at_ u_char c; line_width = scp->sc->adp->va_line_width; - d = scp->sc->adp->va_window - + scp->xoff - + scp->yoff*scp->font_size*line_width - + (from%scp->xsize) - + scp->font_size*line_width*(from/scp->xsize); + d = VIDEO_MEMORY_POS(scp, from, 1); outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ outw(GDCIDX, 0x0003); /* data rotate/function select */ _at__at_ -541,7 +724,7 _at__at_ f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); for (j = 0; j < scp->font_size; ++j, ++f) { outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ - writeb(e, 0); + writeb(e, 0); e += line_width; } ++d; _at__at_ -554,8 +737,87 _at__at_ outw(GDCIDX, 0xff08); /* bit mask */ } -static void -vga_vgadraw(scr_stat *scp, int from, int count, int flip) +static void +vga_vgadraw_direct(scr_stat *scp, int from, int count, int flip, int bpp) +{ + vm_offset_t d = 0; + vm_offset_t e; + u_char *f; + u_short col1, col2, idx; + int line_width; + int i, j, k; + int a; + + line_width = scp->sc->adp->va_line_width; + + switch (bpp) { + case 32: + d = VIDEO_MEMORY_POS(scp, from, 32); + break; + case 16: + /* FALLTHROUGH */ + case 15: + d = VIDEO_MEMORY_POS(scp, from, 16); + break; + } + + if (from + count > scp->xsize * scp->ysize) + count = scp->xsize * scp->ysize - from; + + for (i = from; count-- > 0; ++i) { + a = sc_vtb_geta(&scp->vtb, i); + + if (flip) { + col1 = (((a & 0x7000) >> 4) | (a & 0x0800)) >> 8; + col2 = (((a & 0x8000) >> 4) | (a & 0x0700)) >> 8; + } else { + col1 = (a & 0x0f00) >> 8; + col2 = (a & 0xf000) >> 12; + } + + e = d; + f = &(scp->font[sc_vtb_getc(&scp->vtb, i) * scp->font_size]); + + for (j = 0; j < scp->font_size; ++j, ++f) { + for (k = 7; k >= 0; --k) { + idx = *f & (1 << (7 - k)) ? + col1 : col2; + + switch (bpp) { + case 32: + writel(e + 4 * k, vga_palette32[idx]); + break; + case 16: + writew(e + 2 * k, vga_palette16[idx]); + break; + case 15: + writew(e + 2 * k, vga_palette15[idx]); + break; + } + } + + e += line_width; + } + + switch (bpp) { + case 32: + d += 32; + break; + case 16: + /* FALLTHROUGH */ + case 15: + d += 16; + break; + } + + if ((i % scp->xsize) == scp->xsize - 1) + d += scp->xoff * 16 * scp->sc->adp->va_info.vi_pixel_size + + (scp->font_size - 1) * line_width; + } +} + +static void +vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip) { vm_offset_t d; vm_offset_t e; _at__at_ -568,11 +830,7 _at__at_ u_char c; line_width = scp->sc->adp->va_line_width; - d = scp->sc->adp->va_window - + scp->xoff - + scp->yoff*scp->font_size*line_width - + (from%scp->xsize) - + scp->font_size*line_width*(from/scp->xsize); + d = VIDEO_MEMORY_POS(scp, from, 1); outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ outw(GDCIDX, 0x0003); /* data rotate/function select */ _at__at_ -604,7 +862,7 _at__at_ e = d; f = &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); for (j = 0; j < scp->font_size; ++j, ++f) { - writeb(e, *f); + writeb(e, *f); e += line_width; } ++d; _at__at_ -617,6 +875,27 _at__at_ outw(GDCIDX, 0x0001); /* set/reset enable */ } +static void +vga_vgadraw(scr_stat *scp, int from, int count, int flip) +{ + int bpp; + + switch (scp->sc->adp->va_info.vi_mem_model) { + case V_INFO_MM_DIRECT: + bpp = scp->sc->adp->va_info.vi_depth; + + if ((bpp == 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) + bpp = 15; + + vga_vgadraw_direct(scp, from, count, flip, bpp); + break; + case V_INFO_MM_PLANAR: + vga_vgadraw_planar(scp, from, count, flip); + break; + } +} + static void vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) { _at__at_ -629,8 +908,69 _at__at_ #endif } -static void -draw_pxlcursor(scr_stat *scp, int at, int on, int flip) +draw_pxlcursor_direct(scr_stat *scp, int at, int on, int flip, int bpp) +{ + vm_offset_t d = 0; + u_char *f; + int line_width; + int height; + int col1, col2, idx; + int a; + int i, j; + + line_width = scp->sc->adp->va_line_width; + + switch (bpp) { + case 32: + d = VIDEO_MEMORY_POS(scp, at, 32) + + (scp->font_size - scp->curs_attr.base - 1) * line_width; + break; + case 16: + /* FALLTHROUGH */ + case 15: + d = VIDEO_MEMORY_POS(scp, at, 16) + + (scp->font_size - scp->curs_attr.base - 1) * line_width; + break; + } + + a = sc_vtb_geta(&scp->vtb, at); + + if (flip) { + col1 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; + col2 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; + } else { + col1 = ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; + col2 = ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; + } + + f = &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size + + scp->font_size - scp->curs_attr.base - 1]); + + height = imin(scp->curs_attr.height, scp->font_size); + + for (i = 0; i < height; ++i, --f) { + for (j = 7; j >= 0; --j) { + idx = *f & (1 << (7 - j)) ? col1 : col2; + + switch (bpp) { + case 32: + writel(d + 4 * j, vga_palette32[idx]); + break; + case 16: + writew(d + 2 * j, vga_palette16[idx]); + break; + case 15: + writew(d + 2 * j, vga_palette15[idx]); + break; + } + } + + d -= line_width; + } +} + +static void +draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip) { vm_offset_t d; u_char *f; _at__at_ -642,12 +982,8 _at__at_ u_char c; line_width = scp->sc->adp->va_line_width; - d = scp->sc->adp->va_window - + scp->xoff - + scp->yoff*scp->font_size*line_width - + (at%scp->xsize) - + scp->font_size*line_width*(at/scp->xsize) - + (scp->font_size - scp->curs_attr.base - 1)*line_width; + d = VIDEO_MEMORY_POS(scp, at, 1) + + (scp->font_size - scp->curs_attr.base - 1) * line_width; outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ outw(GDCIDX, 0x0003); /* data rotate/function select */ _at__at_ -673,7 +1009,7 _at__at_ height = imin(scp->curs_attr.height, scp->font_size); for (i = 0; i < height; ++i, --f) { outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ - writeb(d, 0); + writeb(d, 0); d -= line_width; } outw(GDCIDX, 0x0000); /* set/reset */ _at__at_ -681,6 +1017,27 _at__at_ outw(GDCIDX, 0xff08); /* bit mask */ } +static void +draw_pxlcursor(scr_stat *scp, int at, int on, int flip) +{ + int bpp; + + switch (scp->sc->adp->va_info.vi_mem_model) { + case V_INFO_MM_DIRECT: + bpp = scp->sc->adp->va_info.vi_depth; + + if ((bpp == 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) + bpp = 15; + + draw_pxlcursor_direct(scp, at, on, flip, bpp); + break; + case V_INFO_MM_PLANAR: + draw_pxlcursor_planar(scp, at, on, flip); + break; + } +} + static int pxlblinkrate = 0; static void _at__at_ -725,8 +1082,87 _at__at_ #ifndef SC_NO_CUTPASTE +draw_pxlmouse_direct(scr_stat *scp, int x, int y, int bpp) +{ + vm_offset_t p; + int line_width, pixel_size; + int xend, yend; + static int x_old = 0, xend_old = 0; + static int y_old = 0, yend_old = 0; + int i, j; + uint32_t *u32; + uint16_t *u16; + + line_width = scp->sc->adp->va_line_width; + pixel_size = scp->sc->adp->va_info.vi_pixel_size; + + xend = imin(x + 16, scp->xpixel); + yend = imin(y + 16, scp->ypixel); + + p = scp->sc->adp->va_window + y_old * line_width + x_old * pixel_size; + + for (i = 0; i < (yend_old - y_old); i++) { + for (j = (xend_old - x_old - 1); j >= 0; j--) { + switch (bpp) { + case 32: + u32 = (uint32_t*)(p + j * pixel_size); + writel(u32, mouse_buf32[i * 16 + j]); + break; + case 16: + /* FALLTHROUGH */ + case 15: + u16 = (uint16_t*)(p + j * pixel_size); + writew(u16, mouse_buf16[i * 16 + j]); + break; + } + } + + p += line_width; + } + + p = scp->sc->adp->va_window + y * line_width + x * pixel_size; + + for (i = 0; i < (yend - y); i++) { + for (j = (xend - x - 1); j >= 0; j--) { + switch (bpp) { + case 32: + u32 = (uint32_t*)(p + j * pixel_size); + mouse_buf32[i * 16 + j] = *u32; + if (mouse_or_mask[i] & (1 << (15 - j))) + writel(u32, vga_palette32[15]); + else if (mouse_and_mask[i] & (1 << (15 - j))) + writel(u32, 0); + break; + case 16: + u16 = (uint16_t*)(p + j * pixel_size); + mouse_buf16[i * 16 + j] = *u16; + if (mouse_or_mask[i] & (1 << (15 - j))) + writew(u16, vga_palette16[15]); + else if (mouse_and_mask[i] & (1 << (15 - j))) + writew(u16, 0); + break; + case 15: + u16 = (uint16_t*)(p + j * pixel_size); + mouse_buf16[i * 16 + j] = *u16; + if (mouse_or_mask[i] & (1 << (15 - j))) + writew(u16, vga_palette15[15]); + else if (mouse_and_mask[i] & (1 << (15 - j))) + writew(u16, 0); + break; + } + } + + p += line_width; + } + + x_old = x; + y_old = y; + xend_old = xend; + yend_old = yend; +} + static void -draw_pxlmouse(scr_stat *scp, int x, int y) +draw_pxlmouse_planar(scr_stat *scp, int x, int y) { vm_offset_t p; int line_width; _at__at_ -800,8 +1236,28 _at__at_ outw(GDCIDX, 0x0003); /* data rotate/function select */ } +draw_pxlmouse(scr_stat *scp, int x, int y) +{ + int bpp; + + switch (scp->sc->adp->va_info.vi_mem_model) { + case V_INFO_MM_DIRECT: + bpp = scp->sc->adp->va_info.vi_depth; + + if ((bpp == 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] == 5)) + bpp = 15; + + draw_pxlmouse_direct(scp, x, y, bpp); + break; + case V_INFO_MM_PLANAR: + draw_pxlmouse_planar(scp, x, y); + break; + } +} + static void -remove_pxlmouse(scr_stat *scp, int x, int y) +remove_pxlmouse_planar(scr_stat *scp, int x, int y) { vm_offset_t p; int col, row; _at__at_ -857,6 +1313,18 _at__at_ outw(GDCIDX, 0x0001); /* set/reset enable */ } +static void +remove_pxlmouse(scr_stat *scp, int x, int y) +{ + switch (scp->sc->adp->va_info.vi_mem_model) { + case V_INFO_MM_PLANAR: + remove_pxlmouse_planar(scp, x, y); + break; + default: + break; + } +} + static void vga_pxlmouse(scr_stat *scp, int x, int y, int on) { Index: sys/dev/syscons/scvidctl.c =================================================================== RCS file: /home/ncvs/src/sys/dev/syscons/scvidctl.c,v retrieving revision 1.32 diff -u -I$Id.*$ -I$.+BSD.*$ -r1.32 scvidctl.c --- sys/dev/syscons/scvidctl.c 13 Jul 2004 16:06:19 -0000 1.32 +++ sys/dev/syscons/scvidctl.c 27 Aug 2004 11:25:53 -0000 _at__at_ -367,16 +367,28 _at__at_ if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) return EINVAL; - /* only 16 color, 4 plane modes are supported XXX */ - if ((info.vi_depth != 4) || (info.vi_planes != 4)) - return ENODEV; - /* - * set_pixel_mode() currently does not support video modes whose - * memory size is larger than 64K. Because such modes require - * bank switching to access the entire screen. XXX + * We currently support the following graphic modes: + * + * - 800x600 16 color planar mode + * - 16 and 32 bit linear modes */ - if (info.vi_width*info.vi_height/8 > info.vi_window_size) + if (info.vi_mem_model == V_INFO_MM_PLANAR) { + if (info.vi_planes != 4) + return ENODEV; + + /* + * set_pixel_mode() currently does not support video modes whose + * memory size is larger than 64K. Because such modes require + * bank switching to access the entire screen. XXX + */ + + if (info.vi_width * info.vi_height / 8 > info.vi_window_size) + return ENODEV; + } else if (info.vi_mem_model == V_INFO_MM_DIRECT) { + if ((info.vi_depth != 16) && (info.vi_depth != 32)) + return ENODEV; + } else return ENODEV; /* stop screen saver, etc */ Index: usr.sbin/vidcontrol/vidcontrol.1 =================================================================== RCS file: /home/ncvs/src/usr.sbin/vidcontrol/vidcontrol.1,v retrieving revision 1.55 diff -u -I$Id.*$ -I$.+BSD.*$ -r1.55 vidcontrol.1 --- usr.sbin/vidcontrol/vidcontrol.1 2 Mar 2003 21:04:21 -0000 1.55 +++ usr.sbin/vidcontrol/vidcontrol.1 28 Aug 2004 01:05:13 -0000 _at__at_ -21,7 +21,7 _at__at_ .Nd system console control and configuration utility .Sh SYNOPSIS .Nm -.Op Fl CdLHPpx +.Op Fl CdHLPpx .Op Fl b Ar color .Op Fl c Ar appearance .Oo _at__at_ -88,7 +88,13 _at__at_ The raster text mode .Ar VESA_800x600 can also be chosen. -See +Alternatively, a mode can be specified with its number by using a mode name +of +the form +.Ar MODE_<NUMBER> . +A list of valid mode numbers can be obtained with the +.Fl i Cm mode +option. See .Sx Video Mode Support below. .It Ar foreground Op Ar background _at__at_ -230,7 +236,7 _at__at_ (The default is to permit vty switching.) This protection can be easily bypassed when the kernel is compiled with the -.Dv DDB +.Dv KDB option. However, you probably should not compile the kernel debugger on a box which is supposed to be physically secure. _at__at_ -292,9 +298,8 _at__at_ when the system starts up. See below. .Pp -If you want to use the raster text mode -.Ar VESA_800x600 , -you need to recompile your kernel with the +If you want to use any of the raster text modes you need to recompile your +kernel with the .Dv SC_PIXEL_MODE option. See _at__at_ -531,3 +536,4 _at__at_ .Sh CONTRIBUTORS .An Maxim Sobolev Aq sobomax_at_FreeBSD.org , .An Nik Clayton Aq nik_at_FreeBSD.org +.An Sascha Wildner Aq saw_at_online.de Index: usr.sbin/vidcontrol/vidcontrol.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/vidcontrol/vidcontrol.c,v retrieving revision 1.47 diff -u -I$Id.*$ -I$.+BSD.*$ -r1.47 vidcontrol.c --- usr.sbin/vidcontrol/vidcontrol.c 18 Sep 2003 16:20:32 -0000 1.47 +++ usr.sbin/vidcontrol/vidcontrol.c 28 Aug 2004 01:09:02 -0000 _at__at_ -46,18 +46,16 _at__at_ #include "path.h" #include "decode.h" -#define _VESA_800x600_DFL_COLS 80 -#define _VESA_800x600_DFL_ROWS 25 -#define _VESA_800x600_DFL_FNSZ 16 +#define DATASIZE(x) ((x).w * (x).h * 256 / 8) /* Screen dump modes */ -#define DUMP_FMT_RAW 1 -#define DUMP_FMT_TXT 2 +#define DUMP_FMT_RAW 1 +#define DUMP_FMT_TXT 2 /* Screen dump options */ -#define DUMP_FBF 0 -#define DUMP_ALL 1 +#define DUMP_FBF 0 +#define DUMP_ALL 1 /* Screen dump file format revision */ -#define DUMP_FMT_REV 1 +#define DUMP_FMT_REV 1 char legal_colors[16][16] = { "black", "blue", "green", "cyan", _at__at_ -65,16 +63,113 _at__at_ "grey", "lightblue", "lightgreen", "lightcyan", "lightred", "lightmagenta", "yellow", "lightwhite" }; + +struct { + int active_vty; + vid_info_t console_info; + unsigned char screen_map[256]; + int video_mode_number; + struct video_info video_mode_info; +} cur_info; + int hex = 0; int number; -int vesa_cols = _VESA_800x600_DFL_COLS; -int vesa_rows = _VESA_800x600_DFL_ROWS; +int vesa_cols; +int vesa_rows; +int font_height; +int colors_changed; +int video_mode_changed; +int normal_fore_color, normal_back_color; +int revers_fore_color, revers_back_color; char letter; struct vid_info info; +struct video_info new_mode_info; + +/* + * Initialize revert data. + * + * NOTE: the following parameters are not yet saved/restored: + * + * screen saver timeout + * cursor type + * mouse character and mouse show/hide state + * vty switching on/off state + * history buffer size + * history contents + * font maps + */ + +void +init(void) +{ + if (ioctl(0, VT_GETACTIVE, &cur_info.active_vty) == -1) + errc(1, errno, "getting active vty"); + + cur_info.console_info.size = sizeof(cur_info.console_info); + + if (ioctl(0, CONS_GETINFO, &cur_info.console_info) == -1) + errc(1, errno, "getting console information"); + + if (ioctl(0, GIO_SCRNMAP, &cur_info.screen_map) == -1) + errc(1, errno, "getting screen map"); + + if (ioctl(0, CONS_GET, &cur_info.video_mode_number) == -1) + errc(1, errno, "getting video mode number"); + + cur_info.video_mode_info.vi_mode = cur_info.video_mode_number; + + if (ioctl(0, CONS_MODEINFO, &cur_info.video_mode_info) == -1) + errc(1, errno, "getting video mode parameters"); + + normal_fore_color = cur_info.console_info.mv_norm.fore; + normal_back_color = cur_info.console_info.mv_norm.back; + revers_fore_color = cur_info.console_info.mv_rev.fore; + revers_back_color = cur_info.console_info.mv_rev.back; +} + +/* + * If something goes wrong along the way we call revert() to go back to the + * console state we came from (which is assumed to be working). + * + * NOTE: please also read the comments of init(). + */ + +void +revert(void) +{ + int size[3]; + + ioctl(0, VT_ACTIVATE, (caddr_t) (long)cur_info.active_vty); + + fprintf(stderr, "ESC[=%dA", cur_info.console_info.mv_ovscan); + fprintf(stderr, "ESC[=%dF", cur_info.console_info.mv_norm.fore); + fprintf(stderr, "ESC[=%dG", cur_info.console_info.mv_norm.back); + fprintf(stderr, "ESC[=%dH", cur_info.console_info.mv_rev.fore); + fprintf(stderr, "ESC[=%dI", cur_info.console_info.mv_rev.back); + + ioctl(0, PIO_SCRNMAP, &cur_info.screen_map); + + if (cur_info.video_mode_number >= M_VESA_BASE) + ioctl(0, _IO('V', cur_info.video_mode_number - M_VESA_BASE), NULL); + else + ioctl(0, _IO('S', cur_info.video_mode_number), NULL); + + if (cur_info.video_mode_info.vi_flags & V_INFO_GRAPHICS) { + size[0] = cur_info.video_mode_info.vi_width / 8; + size[1] = cur_info.video_mode_info.vi_height / + cur_info.console_info.font_size; + size[2] = cur_info.console_info.font_size; + + ioctl(0, KDRASTER, size); + } +} +/* + * Print a short usage string describing all options, then exit. + */ static void -usage() +usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", "usage: vidcontrol [-CdHLPpx] [-b color] [-c appearance] [-f [size] file]", _at__at_ -85,16 +180,28 _at__at_ exit(1); } +/* + * Retrieve the next argument from the command line (for options that require + * more than one argument). + */ + char * nextarg(int ac, char **av, int *indp, int oc, int strict) { if (*indp < ac) return(av[(*indp)++]); - if (strict != 0) + if (strict != 0) { + revert(); errx(1, "option requires two arguments -- %c", oc); + } return(NULL); } +/* + * Guess which file to open. Try to open each combination of a specified set + * of file name components. + */ + FILE * openguess(char *a[], char *b[], char *c[], char *d[], char **name) { _at__at_ -118,6 +225,10 _at__at_ return (NULL); } +/* + * Load a screenmap from a file and set it. + */ + void load_scrnmap(char *filename) { _at__at_ -132,44 +243,56 _at__at_ fd = openguess(a, b, c, d, &name); if (fd == NULL) { - warn("screenmap file not found"); - return; + revert(); + errx(1, "screenmap file not found"); } size = sizeof(scrnmap); if (decode(fd, (char *)&scrnmap, size) != size) { rewind(fd); if (fread(&scrnmap, 1, size, fd) != size) { - warnx("bad screenmap file"); fclose(fd); - return; + revert(); + errx(1, "bad screenmap file"); } } - if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) - warn("can't load screenmap"); fclose(fd); + if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) { + revert(); + errc(1, errno, "can't load screenmap"); + } } +/* + * Set the default screenmap. + */ + void -load_default_scrnmap() +load_default_scrnmap(void) { scrmap_t scrnmap; int i; for (i=0; i<256; i++) *((char*)&scrnmap + i) = i; - if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) - warn("can't load default screenmap"); + if (ioctl(0, PIO_SCRNMAP, &scrnmap) < 0) { + revert(); + errc(1, errno, "can't load default screenmap"); + } } +/* + * Print the current screenmap to stdout. + */ + void -print_scrnmap() +print_scrnmap(void) { unsigned char map[256]; int i; if (ioctl(0, GIO_SCRNMAP, &map) < 0) { - warn("getting screenmap"); - return; + revert(); + errc(1, errno, "getting screenmap"); } for (i=0; i<sizeof(map); i++) { if (i > 0 && i % 16 == 0) _at__at_ -180,9 +303,12 _at__at_ fprintf(stdout, " %03d", map[i]); } fprintf(stdout, "\n"); - } +/* + * Determine a file's size. + */ + int fsize(FILE *file) { _at__at_ -194,7 +320,9 _at__at_ return -1; } -#define DATASIZE(x) ((x).w * (x).h * 256 / 8) +/* + * Load a font from file and set it. + */ void load_font(char *type, char *filename) _at__at_ -220,14 +348,15 _at__at_ info.size = sizeof(info); if (ioctl(0, CONS_GETINFO, &info) == -1) { - warn("failed to obtain current video mode parameters"); - return; + revert(); + errc(1, errno, + "failed to obtain current video mode parameters"); } snprintf(size_sufx, sizeof(size_sufx), "-8x%d", info.font_size); fd = openguess(a, b, c, d, &name); if (fd == NULL) { - warn("%s: can't load font file", filename); - return; + revert(); + errx(1, "%s: can't load font file", filename); } if (type != NULL) { size = 0; _at__at_ -236,12 +365,13 _at__at_ if (sizes[i].w == w && sizes[i].h == h) { size = DATASIZE(sizes[i]); io = sizes[i].io; + font_height = sizes[i].h; } if (size == 0) { - warnx("%s: bad font size specification", type); fclose(fd); - return; + revert(); + errx(1, "%s: bad font size specification", type); } } else { /* Apply heuristics */ _at__at_ -260,14 +390,15 _at__at_ if (DATASIZE(sizes[i]) == dsize[j]) { size = dsize[j]; io = sizes[i].io; + font_height = sizes[i].h; j = 2; /* XXX */ break; } if (size == 0) { - warnx("%s: can't guess font size", filename); fclose(fd); - return; + revert(); + errx(1, "%s: can't guess font size", filename); } rewind(fd); } _at__at_ -276,18 +407,25 _at__at_ if (decode(fd, fontmap, size) != size) { rewind(fd); if (fsize(fd) != size || fread(fontmap, 1, size, fd) != size) { - warnx("%s: bad font file", filename); fclose(fd); free(fontmap); - return; + revert(); + errx(1, "%s: bad font file", filename); } } - if (ioctl(0, io, fontmap) < 0) - warn("can't load font"); fclose(fd); + if (ioctl(0, io, fontmap) < 0) { + free(fontmap); + revert(); + errc(1, errno, "can't load font"); + } free(fontmap); } +/* + * Set the timeout for the screensaver. + */ + void set_screensaver_timeout(char *arg) { _at__at_ -298,14 +436,20 _at__at_ else { nsec = atoi(arg); if ((*arg == '\0') || (nsec < 1)) { - warnx("argument must be a positive number"); - return; + revert(); + errx(1, "argument must be a positive number"); } } - if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) - warn("setting screensaver period"); + if (ioctl(0, CONS_BLANKTIME, &nsec) == -1) { + revert(); + errc(1, errno, "setting screensaver period"); + } } +/* + * Set the cursor's shape/type. + */ + void set_cursor_type(char *appearence) { _at__at_ -318,13 +462,20 _at__at_ else if (!strcmp(appearence, "destructive")) type = 3; else { - warnx("argument to -c must be normal, blink or destructive"); - return; + revert(); + errx(1, "argument to -c must be normal, blink or destructive"); + } + if (ioctl(0, CONS_CURSORTYPE, &type) == -1) { + revert(); + errc(1, errno, "setting cursor type"); } - ioctl(0, CONS_CURSORTYPE, &type); } -int +/* + * Set the video mode. + */ + +void video_mode(int argc, char **argv, int *index) { static struct { _at__at_ -363,64 +514,81 _at__at_ { "VESA_800x600", SW_VESA_800x600 }, { NULL }, }; + int new_mode_num = 0; unsigned long mode = 0; - int cur_mode; int ioerr; int size[3]; int i; - if (ioctl(0, CONS_GET, &cur_mode) < 0) - err(1, "cannot get the current video mode"); if (*index < argc) { - for (i = 0; modes[i].name != NULL; ++i) { - if (!strcmp(argv[*index], modes[i].name)) { - mode = modes[i].mode; - break; + if (!strncmp(argv[*index], "MODE_", 5)) { + if (!isnumber(argv[*index][5])) + errx(1, "invalid video mode number"); + + new_mode_num = atoi(&argv[*index][5]); + } else { + for (i = 0; modes[i].name != NULL; ++i) { + if (!strcmp(argv[*index], modes[i].name)) { + new_mode_num = modes[i].mode; + break; + } } + if (modes[i].name == NULL) + errx(1, "invalid video mode name"); } - if (modes[i].name == NULL) - return EXIT_FAILURE; - if (ioctl(0, mode, NULL) < 0) { - warn("cannot set videomode"); - return EXIT_FAILURE; - } - if (mode == SW_VESA_800x600) { - /* columns */ - if ((vesa_cols * 8 > 800) || (vesa_cols <= 0)) { - warnx("incorrect number of columns: %d", - vesa_cols); - size[0] = _VESA_800x600_DFL_COLS; - } else { + /* Collect enough information about the new video mode... */ + new_mode_info.vi_mode = new_mode_num; + if (ioctl(0, CONS_MODEINFO, &new_mode_info) == -1) { + revert(); + errc(1, errno, "obtaining new video mode parameters"); + } + if (mode == 0) { + if (new_mode_num >= M_VESA_BASE) + mode = _IO('V', new_mode_num - M_VESA_BASE); + else + mode = _IO('S', new_mode_num); + } + /* Try setting the new mode. */ + if (ioctl(0, mode, NULL) == -1) { + revert(); + errc(1, errno, "cannot set videomode"); + } + /* + * For raster modes it's not enough to just set the mode. + * We also need to explicitly set the raster mode. + */ + if (new_mode_info.vi_flags & V_INFO_GRAPHICS) { + /* font size */ + if (font_height == 0) + font_height = cur_info.console_info.font_size; + size[2] = font_height; + /* adjust columns */ + if ((vesa_cols * 8 > new_mode_info.vi_width) || + (vesa_cols <= 0)) + size[0] = new_mode_info.vi_width / 8; + else size[0] = vesa_cols; - } - /* rows */ - if ((vesa_rows * _VESA_800x600_DFL_FNSZ > 600) || - (vesa_rows <=0)) { - warnx("incorrect number of rows: %d", - vesa_rows); - size[1] = _VESA_800x600_DFL_ROWS; - } else { + /* adjust rows */ + if ((vesa_rows * font_height > new_mode_info.vi_height) + || (vesa_rows <= 0)) + size[1] = new_mode_info.vi_height / font_height; + else size[1] = vesa_rows; - } - /* font size */ - size[2] = _VESA_800x600_DFL_FNSZ; + /* set raster mode */ if (ioctl(0, KDRASTER, size)) { - ioerr = errno; - if (cur_mode >= M_VESA_BASE) - ioctl(0, - _IO('V', cur_mode - M_VESA_BASE), - NULL); - else - ioctl(0, _IO('S', cur_mode), NULL); - warnc(ioerr, "cannot activate raster display"); - return EXIT_FAILURE; + revert(); + errc(1, errno, "activating raster display"); } } + video_mode_changed = 1; (*index)++; } - return EXIT_SUCCESS; } +/* + * Return the number for a specified color name. + */ + int get_color_number(char *color) { _at__at_ -432,56 +600,88 _at__at_ return -1; } +/* + * Get normal text and background colors. + */ + void -set_normal_colors(int argc, char **argv, int *index) +get_normal_colors(int argc, char **argv, int *index) { int color; if (*index < argc && (color = get_color_number(argv[*index])) != -1) { (*index)++; - fprintf(stderr, "[=%dF", color); - if (*index < argc - && (color = get_color_number(argv[*index])) != -1 - && color < 8) { + normal_fore_color = color; + colors_changed = 1; + if (*index < argc && + (color = get_color_number(argv[*index])) != -1) { (*index)++; - fprintf(stderr, "[=%dG", color); + normal_back_color = color; } } } +/* + * Get reverse text and background colors. + */ + void -set_reverse_colors(int argc, char **argv, int *index) +get_reverse_colors(int argc, char **argv, int *index) { int color; if ((color = get_color_number(argv[*(index)-1])) != -1) { - fprintf(stderr, "[=%dH", color); - if (*index < argc - && (color = get_color_number(argv[*index])) != -1 - && color < 8) { + revers_fore_color = color; + colors_changed = 1; + if (*index < argc && + (color = get_color_number(argv[*index])) != -1) { (*index)++; - fprintf(stderr, "[=%dI", color); + revers_back_color = color; } } } +/* + * Set normal and reverse foreground and background colors. + */ + +void +set_colors(void) +{ + fprintf(stderr, "ESC[=%dF", normal_fore_color); + fprintf(stderr, "ESC[=%dG", normal_back_color); + fprintf(stderr, "ESC[=%dH", revers_fore_color); + fprintf(stderr, "ESC[=%dI", revers_back_color); +} + +/* + * Switch to virtual terminal #arg. + */ + void set_console(char *arg) { int n; if( !arg || strspn(arg,"0123456789") != strlen(arg)) { - warnx("bad console number"); - return; + revert(); + errx(1, "bad console number"); } n = atoi(arg); if (n < 1 || n > 16) { - warnx("console number out of range"); - } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1) - warn("ioctl(VT_ACTIVATE)"); + revert(); + errx(1, "console number out of range"); + } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) == -1) { + revert(); + errc(1, errno, "ioctl(VT_ACTIVATE)"); + } } +/* + * Sets the border color. + */ + void set_border_color(char *arg) { _at__at_ -494,6 +694,10 _at__at_ usage(); } +/* + * Set the mouse characer. + */ + void set_mouse_char(char *arg) { _at__at_ -502,14 +706,21 _at__at_ l = strtol(arg, NULL, 0); if ((l < 0) || (l > UCHAR_MAX - 3)) { - warnx("argument to -M must be 0 through %d", UCHAR_MAX - 3); - return; + revert(); + errx(1, "argument to -M must be 0 through %d", UCHAR_MAX - 3); } mouse.operation = MOUSE_MOUSECHAR; mouse.u.mouse_char = (int)l; - ioctl(0, CONS_MOUSECTL, &mouse); + if (ioctl(0, CONS_MOUSECTL, &mouse) == -1) { + revert(); + errc(1, errno, "setting mouse character"); + } } +/* + * Show/hide the mouse. + */ + void set_mouse(char *arg) { _at__at_ -520,10 +731,14 _at__at_ else if (!strcmp(arg, "off")) mouse.operation = MOUSE_HIDE; else { - warnx("argument to -m must be either on or off"); - return; + revert(); + errx(1, "argument to -m must be either on or off"); + } + if (ioctl(0, CONS_MOUSECTL, &mouse) == -1) { + revert(); + errc(1, errno, "%sing the mouse", + mouse.operation == MOUSE_SHOW ? "show" : "hid"); } - ioctl(0, CONS_MOUSECTL, &mouse); } void _at__at_ -536,13 +751,20 _at__at_ else if (!strcmp(arg, "on")) data = 0x02; else { - warnx("argument to -S must be either on or off"); - return; + revert(); + errx(1, "argument to -S must be either on or off"); + } + if (ioctl(0, VT_LOCKSWITCH, &data) == -1) { + revert(); + errc(1, errno, "turning %s vty switching", + data == 0x01 ? "off" : "on"); } - if (ioctl(0, VT_LOCKSWITCH, &data) == -1) - warn("ioctl(VT_LOCKSWITCH)"); } +/* + * Return the adapter name for a specified type. + */ + static char *adapter_name(int type) { _at__at_ -567,6 +789,10 _at__at_ return names[i].name; } +/* + * Show graphics adapter information. + */ + void show_adapter_info(void) { _at__at_ -574,8 +800,8 _at__at_ ad.va_index = 0; if (ioctl(0, CONS_ADPINFO, &ad)) { - warn("failed to obtain adapter information"); - return; + revert(); + errc(1, errno, "failed to obtain adapter information"); } printf("fb%d:\n", ad.va_index); _at__at_ -594,6 +820,10 _at__at_ printf(" reserved:0x%x\n", ad.va_unused0); } +/* + * Show video mode information. + */ + void show_mode_info(void) { _at__at_ -645,13 +875,13 _at__at_ else if (!strcmp(arg, "mode")) show_mode_info(); else { - warnx("argument to -i must be either adapter or mode"); - return; + revert(); + errx(1, "argument to -i must be either adapter or mode"); } } void -test_frame() +test_frame(void) { int i; _at__at_ -682,8 +912,9 _at__at_ info.size = sizeof(info); if (ioctl(0, CONS_GETINFO, &info) == -1) { - warn("failed to obtain current video mode parameters"); - return; + revert(); + errc(1, errno, + "failed to obtain current video mode parameters"); } shot.x = shot.y = 0; _at__at_ -694,13 +925,13 _at__at_ shot.buf = alloca(shot.xsize * shot.ysize * sizeof(u_int16_t)); if (shot.buf == NULL) { - warn("failed to allocate memory for dump"); - return; + revert(); + errx(1, "failed to allocate memory for dump"); } if (ioctl(0, CONS_SCRSHOT, &shot) == -1) { - warn("failed to get dump of the screen"); - return; + revert(); + errc(1, errno, "failed to get dump of the screen"); } if (mode == DUMP_FMT_RAW) { _at__at_ -717,8 +948,8 _at__at_ line = alloca(shot.xsize + 1); if (line == NULL) { - warn("failed to allocate memory for line buffer"); - return; + revert(); + errx(1, "failed to allocate memory for line buffer"); } for (y = 0; y < shot.ysize; y++) { _at__at_ -743,6 +974,10 _at__at_ return; } +/* + * Set the console history buffer size. + */ + void set_history(char *opt) { _at__at_ -750,19 +985,27 _at__at_ size = atoi(opt); if ((*opt == '\0') || size < 0) { - warnx("argument must be a positive number"); - return; + revert(); + errx(1, "argument must be a positive number"); + } + if (ioctl(0, CONS_HISTORY, &size) == -1) { + revert(); + errc(1, errno, "setting history buffer size"); } - if (ioctl(0, CONS_HISTORY, &size) == -1) - warn("setting history buffer size"); } +/* + * Clear the console history buffer. + */ + void -clear_history() +clear_history(void) { - if (ioctl(0, CONS_CLRHIST) == -1) - warn("clear history buffer"); + if (ioctl(0, CONS_CLRHIST) == -1) { + revert(); + errc(1, errno, "clear history buffer"); + } } int _at__at_ -770,12 +1013,11 _at__at_ { char *font, *type; int dumpmod, dumpopt, opt; - int reterr; - info.size = sizeof(info); if (argc == 1) usage(); - /* Not reached */ + init(); + info.size = sizeof(info); if (ioctl(0, CONS_GETINFO, &info) < 0) err(1, "must be on a virtual console"); dumpmod = 0; _at__at_ -806,6 +1048,7 _at__at_ case 'g': if (sscanf(optarg, "%dx%d", &vesa_cols, &vesa_rows) != 2) { + revert(); warnx("incorrect geometry: %s", optarg); usage(); } _at__at_ -838,7 +1081,7 _at__at_ dumpmod = DUMP_FMT_TXT; break; case 'r': - set_reverse_colors(argc, argv, &optind); + get_reverse_colors(argc, argv, &optind); break; case 'S': set_lockswitch(optarg); _at__at_ -857,14 +1100,26 _at__at_ } if (dumpmod != 0) dump_screen(dumpmod, dumpopt); - reterr = video_mode(argc, argv, &optind); - set_normal_colors(argc, argv, &optind); + video_mode(argc, argv, &optind); + get_normal_colors(argc, argv, &optind); + if (colors_changed || video_mode_changed) { + if (!(new_mode_info.vi_flags & V_INFO_GRAPHICS)) { + if ((normal_back_color < 8) && (revers_back_color < 8)) { + set_colors(); + } else { + revert(); + errx(1, "background colors for text video modes must be < 8"); + } + } else { + set_colors(); + } + } if (optind < argc && !strcmp(argv[optind], "show")) { test_frame(); optind++; } if ((optind != argc) || (argc == 1)) usage(); - return reterr; + return(EXIT_SUCCESS); } Cyrille Lefevre -- mailto:cyrille.lefevre_at_laposte.netReceived on Sat Aug 28 2004 - 00:45:55 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:09 UTC