From owner-freebsd-current@FreeBSD.ORG Sat Aug 28 02:45:55 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2D41316A4CE for ; Sat, 28 Aug 2004 02:45:55 +0000 (GMT) Received: from ioskeha.hittite.isp.9tel.net (ioskeha.hittite.isp.9tel.net [62.62.156.27]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2072143D1D for ; Sat, 28 Aug 2004 02:45:54 +0000 (GMT) (envelope-from root@gits.dyndns.org) Received: from mail.gits.dyndns.org (78-240-118-80.kaptech.net [80.118.240.78]) by ioskeha.hittite.isp.9tel.net (Postfix) with ESMTP id C201C14B5AD; Sat, 28 Aug 2004 04:58:21 +0200 (CEST) Posted-Date: Sat, 28 Aug 2004 04:43:10 +0200 (CEST) X-Envelope-To: dsnofe@msn.com Received: from mail.gits.dyndns.org (IDENT:ew1e4vdnysydbtx0@localhost [127.0.0.1])i7S2hAAU007931; Sat, 28 Aug 2004 04:43:25 +0200 (CEST) (envelope-from root@gits.dyndns.org) Received: (from root@localhost) by mail.gits.dyndns.org (8.13.1/8.12.11/Submit) id i7S1jqxl096468; Sat, 28 Aug 2004 03:45:52 +0200 (CEST) (envelope-from root) Message-Id: <200408280145.i7S1jqxl096468@mail.gits.dyndns.org> In-Reply-To: To: Deng XueFeng Date: Sat, 28 Aug 2004 03:45:52 +0200 (CEST) From: Cyrille Lefevre X-Face: V|+c;4!|B?E%BE^{E6); aI.[< List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Aug 2004 02:45:55 -0000 On Aug 27, 2004 01:59:50 am +0000, Deng XueFeng wrote: > First to thanks Sascha Wildner . > 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=20 > 7500[T31]/9200 [NX7000]. > To make console support 1024x768; just type > #vidcontrol MODE_279 >=20 > 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! >=20 > NOTE: > current-vidcontrol.1 current-vidcontrol.c is taken from dfbsd. whic= h=20 > 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 -cur= rent 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 and ... to ). 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 @@ -105,6 +105,17 @@ return ENODEV; mode =3D (cmd & 0xff) + M_VESA_BASE; return sc_set_graphics_mode(scp, tp, mode); + default: + if (IOCGROUP(cmd) =3D=3D 'V') { + if (!(scp->sc->adp->va_flags & V_ADP_MODECHANGE)) + return ENODEV; + + mode =3D (cmd & 0xff) + M_VESA_BASE; + + if ((mode > M_VESA_FULL_1280) && + (mode < M_VESA_MODE_MAX)) + return sc_set_graphics_mode(scp, tp, mode); + } } =20 if (prev_user_ioctl) Index: sys/dev/syscons/scvgarndr.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 @@ -47,7 +47,7 @@ #include =20 #ifndef SC_RENDER_DEBUG -#define SC_RENDER_DEBUG 0 +#define SC_RENDER_DEBUG 0 #endif =20 static vr_clear_t vga_txtclear; @@ -59,7 +59,7 @@ #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 =20 #ifdef SC_PIXEL_MODE @@ -73,7 +73,7 @@ #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 */ =20 @@ -155,6 +155,37 @@ #endif #endif =20 +#ifdef SC_PIXEL_MODE +static uint32_t vga_palette32[16] =3D { + 0x000000, 0x0000ad, 0x00ad00, 0x00adad, + 0xad0000, 0xad00ad, 0xad5200, 0xadadad, + 0x525252, 0x5252ff, 0x52ff52, 0x52ffff, + 0xff5252, 0xff52ff, 0xffff52, 0xffffff +}; + +static uint16_t vga_palette16[16] =3D { + 0x0000, 0x0016, 0x0560, 0x0576, 0xb000, 0xb016, 0xb2a0, 0xb576, + 0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff +}; + +static uint16_t vga_palette15[16] =3D { + 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, ...) { @@ -359,8 +390,8 @@ yoffset =3D y%scp->font_size; for (i =3D 0; i < 16; ++i) { cursor[i + yoffset] =3D - (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 =3D 0; i < scp->font_size; ++i) { font_buf[i] =3D (cursor[i] & 0xff00) >> 8; @@ -431,7 +462,29 @@ /* pixel (raster text) mode renderer */ =20 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 =3D scp->sc->adp->va_line_width; + pixel_size =3D scp->sc->adp->va_info.vi_pixel_size; + lines =3D scp->ysize * scp->font_size; + p =3D scp->sc->adp->va_window + + line_width * scp->yoff * scp->font_size + + scp->xoff * 8 * pixel_size; + + for (i =3D 0; i < lines; ++i) { + bzero_io((void *)p, scp->xsize * 8 * pixel_size); + p +=3D line_width; + } +} + +static void +vga_pxlclear_planar(scr_stat *scp, int c, int attr) { vm_offset_t p; int line_width; @@ -456,8 +509,121 @@ outw(GDCIDX, 0x0001); /* set/reset enable */ } =20 +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 =3D scp->sc->adp->va_line_width; + pixel_size =3D scp->sc->adp->va_info.vi_pixel_size; + + if (scp->yoff > 0) { + s =3D scp->sc->adp->va_window; + e =3D s + line_width * scp->yoff * scp->font_size; + + for (f =3D s; f < e; f +=3D 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 =3D (scp->yoff + scp->ysize) * scp->font_size; + + if (scp->ypixel > y) { + s =3D scp->sc->adp->va_window + line_width * y; + e =3D s + line_width * (scp->ypixel - y); + + for (f =3D s; f < e; f +=3D 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 =3D scp->yoff * scp->font_size; + x =3D scp->xpixel / 8 - scp->xoff - scp->xsize; + + for (i =3D 0; i < scp->ysize * scp->font_size; ++i) { + if (scp->xoff > 0) { + s =3D scp->sc->adp->va_window + line_width * (y + i); + e =3D s + scp->xoff * 8 * pixel_size; + + for (f =3D s; f < e; f +=3D 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 =3D scp->sc->adp->va_window + line_width * (y + i) + + scp->xoff * 8 * pixel_size + + scp->xsize * 8 * pixel_size; + e =3D s + x * 8 * pixel_size; + + for (f =3D s; f < e; f +=3D 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; @@ -492,6 +658,27 @@ outw(GDCIDX, 0x0001); /* set/reset enable */ } =20 +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 =3D scp->sc->adp->va_info.vi_depth; + + if ((bpp =3D=3D 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] =3D=3D 5)) + bpp =3D 15; + + vga_pxlborder_direct(scp, color, bpp); + break; + case V_INFO_MM_PLANAR: + vga_pxlborder_planar(scp, color); + break; + } +} + static void=20 vga_egadraw(scr_stat *scp, int from, int count, int flip) { @@ -506,11 +693,7 @@ u_char c; =20 line_width =3D scp->sc->adp->va_line_width; - d =3D scp->sc->adp->va_window - + scp->xoff=20 - + scp->yoff*scp->font_size*line_width=20 - + (from%scp->xsize)=20 - + scp->font_size*line_width*(from/scp->xsize); + d =3D VIDEO_MEMORY_POS(scp, from, 1); =20 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ outw(GDCIDX, 0x0003); /* data rotate/function select */ @@ -541,7 +724,7 @@ f =3D &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); for (j =3D 0; j < scp->font_size; ++j, ++f) { outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ - writeb(e, 0); + writeb(e, 0); e +=3D line_width; } ++d; @@ -554,8 +737,87 @@ outw(GDCIDX, 0xff08); /* bit mask */ } =20 -static void=20 -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 =3D 0; + vm_offset_t e; + u_char *f; + u_short col1, col2, idx; + int line_width; + int i, j, k; + int a; + + line_width =3D scp->sc->adp->va_line_width; + + switch (bpp) { + case 32: + d =3D VIDEO_MEMORY_POS(scp, from, 32); + break; + case 16: + /* FALLTHROUGH */ + case 15: + d =3D VIDEO_MEMORY_POS(scp, from, 16); + break; + } + + if (from + count > scp->xsize * scp->ysize) + count =3D scp->xsize * scp->ysize - from; + + for (i =3D from; count-- > 0; ++i) { + a =3D sc_vtb_geta(&scp->vtb, i); + + if (flip) { + col1 =3D (((a & 0x7000) >> 4) | (a & 0x0800)) >> 8; + col2 =3D (((a & 0x8000) >> 4) | (a & 0x0700)) >> 8; + } else { + col1 =3D (a & 0x0f00) >> 8; + col2 =3D (a & 0xf000) >> 12; + } + + e =3D d; + f =3D &(scp->font[sc_vtb_getc(&scp->vtb, i) * scp->font_size]); + + for (j =3D 0; j < scp->font_size; ++j, ++f) { + for (k =3D 7; k >=3D 0; --k) { + idx =3D *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 +=3D line_width; + } + + switch (bpp) { + case 32: + d +=3D 32; + break; + case 16: + /* FALLTHROUGH */ + case 15: + d +=3D 16; + break; + } + + if ((i % scp->xsize) =3D=3D scp->xsize - 1) + d +=3D 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; @@ -568,11 +830,7 @@ u_char c; =20 line_width =3D scp->sc->adp->va_line_width; - d =3D scp->sc->adp->va_window - + scp->xoff=20 - + scp->yoff*scp->font_size*line_width=20 - + (from%scp->xsize)=20 - + scp->font_size*line_width*(from/scp->xsize); + d =3D VIDEO_MEMORY_POS(scp, from, 1); =20 outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */ outw(GDCIDX, 0x0003); /* data rotate/function select */ @@ -604,7 +862,7 @@ e =3D d; f =3D &(scp->font[sc_vtb_getc(&scp->vtb, i)*scp->font_size]); for (j =3D 0; j < scp->font_size; ++j, ++f) { - writeb(e, *f); + writeb(e, *f); e +=3D line_width; } ++d; @@ -617,6 +875,27 @@ outw(GDCIDX, 0x0001); /* set/reset enable */ } =20 +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 =3D scp->sc->adp->va_info.vi_depth; + + if ((bpp =3D=3D 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] =3D=3D 5)) + bpp =3D 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=20 vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) { @@ -629,8 +908,69 @@ #endif } =20 -static void=20 -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 =3D 0; + u_char *f; + int line_width; + int height; + int col1, col2, idx; + int a; + int i, j; + + line_width =3D scp->sc->adp->va_line_width; + + switch (bpp) { + case 32: + d =3D VIDEO_MEMORY_POS(scp, at, 32) + + (scp->font_size - scp->curs_attr.base - 1) * line_width; + break; + case 16: + /* FALLTHROUGH */ + case 15: + d =3D VIDEO_MEMORY_POS(scp, at, 16) + + (scp->font_size - scp->curs_attr.base - 1) * line_width; + break; + } + + a =3D sc_vtb_geta(&scp->vtb, at); + + if (flip) { + col1 =3D ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; + col2 =3D ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; + } else { + col1 =3D ((on) ? ((a & 0xf000) >> 4) : (a & 0x0f00)) >> 8; + col2 =3D ((on) ? (a & 0x0f00) : ((a & 0xf000) >> 4)) >> 8; + } + + f =3D &(scp->font[sc_vtb_getc(&scp->vtb, at) * scp->font_size + + scp->font_size - scp->curs_attr.base - 1]); + + height =3D imin(scp->curs_attr.height, scp->font_size); + + for (i =3D 0; i < height; ++i, --f) { + for (j =3D 7; j >=3D 0; --j) { + idx =3D *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 -=3D line_width; + } +} + +static void +draw_pxlcursor_planar(scr_stat *scp, int at, int on, int flip) { vm_offset_t d; u_char *f; @@ -642,12 +982,8 @@ u_char c; =20 line_width =3D scp->sc->adp->va_line_width; - d =3D scp->sc->adp->va_window - + scp->xoff=20 - + scp->yoff*scp->font_size*line_width=20 - + (at%scp->xsize)=20 - + scp->font_size*line_width*(at/scp->xsize) - + (scp->font_size - scp->curs_attr.base - 1)*line_width; + d =3D VIDEO_MEMORY_POS(scp, at, 1) + + (scp->font_size - scp->curs_attr.base - 1) * line_width; =20 outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */ outw(GDCIDX, 0x0003); /* data rotate/function select */ @@ -673,7 +1009,7 @@ height =3D imin(scp->curs_attr.height, scp->font_size); for (i =3D 0; i < height; ++i, --f) { outw(GDCIDX, (*f << 8) | 0x08); /* bit mask */ - writeb(d, 0); + writeb(d, 0); d -=3D line_width; } outw(GDCIDX, 0x0000); /* set/reset */ @@ -681,6 +1017,27 @@ outw(GDCIDX, 0xff08); /* bit mask */ } =20 +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 =3D scp->sc->adp->va_info.vi_depth; + + if ((bpp =3D=3D 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] =3D=3D 5)) + bpp =3D 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 =3D 0; =20 static void=20 @@ -725,8 +1082,87 @@ =20 #ifndef SC_NO_CUTPASTE =20 +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 =3D 0, xend_old =3D 0; + static int y_old =3D 0, yend_old =3D 0; + int i, j; + uint32_t *u32; + uint16_t *u16; + + line_width =3D scp->sc->adp->va_line_width; + pixel_size =3D scp->sc->adp->va_info.vi_pixel_size; + + xend =3D imin(x + 16, scp->xpixel); + yend =3D imin(y + 16, scp->ypixel); + + p =3D scp->sc->adp->va_window + y_old * line_width + x_old * pixel_size; + + for (i =3D 0; i < (yend_old - y_old); i++) { + for (j =3D (xend_old - x_old - 1); j >=3D 0; j--) { + switch (bpp) { + case 32: + u32 =3D (uint32_t*)(p + j * pixel_size); + writel(u32, mouse_buf32[i * 16 + j]); + break; + case 16: + /* FALLTHROUGH */ + case 15: + u16 =3D (uint16_t*)(p + j * pixel_size); + writew(u16, mouse_buf16[i * 16 + j]); + break; + } + } + + p +=3D line_width; + } + + p =3D scp->sc->adp->va_window + y * line_width + x * pixel_size; + + for (i =3D 0; i < (yend - y); i++) { + for (j =3D (xend - x - 1); j >=3D 0; j--) { + switch (bpp) { + case 32: + u32 =3D (uint32_t*)(p + j * pixel_size); + mouse_buf32[i * 16 + j] =3D *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 =3D (uint16_t*)(p + j * pixel_size); + mouse_buf16[i * 16 + j] =3D *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 =3D (uint16_t*)(p + j * pixel_size); + mouse_buf16[i * 16 + j] =3D *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 +=3D line_width; + } + + x_old =3D x; + y_old =3D y; + xend_old =3D xend; + yend_old =3D 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; @@ -800,8 +1236,28 @@ outw(GDCIDX, 0x0003); /* data rotate/function select */ } =20 +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 =3D scp->sc->adp->va_info.vi_depth; + + if ((bpp =3D=3D 16) && + (scp->sc->adp->va_info.vi_pixel_fsizes[1] =3D=3D 5)) + bpp =3D 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; @@ -857,6 +1313,18 @@ outw(GDCIDX, 0x0001); /* set/reset enable */ } =20 +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=20 vga_pxlmouse(scr_stat *scp, int x, int y, int on) { Index: sys/dev/syscons/scvidctl.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 @@ -367,16 +367,28 @@ if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize)) return EINVAL; =20 - /* only 16 color, 4 plane modes are supported XXX */ - if ((info.vi_depth !=3D 4) || (info.vi_planes !=3D 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 =3D=3D V_INFO_MM_PLANAR) { + if (info.vi_planes !=3D 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 =3D=3D V_INFO_MM_DIRECT) { + if ((info.vi_depth !=3D 16) && (info.vi_depth !=3D 32)) + return ENODEV; + } else return ENODEV; =20 /* stop screen saver, etc */ Index: usr.sbin/vidcontrol/vidcontrol.1 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 @@ -21,7 +21,7 @@ .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 @@ -88,7 +88,13 @@ 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 nam= e=20 +of +the form +.Ar MODE_ . +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 @@ -230,7 +236,7 @@ (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. @@ -292,9 +298,8 @@ 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 @@ -531,3 +536,4 @@ .Sh CONTRIBUTORS .An Maxim Sobolev Aq sobomax@FreeBSD.org , .An Nik Clayton Aq nik@FreeBSD.org +.An Sascha Wildner Aq saw@online.de Index: usr.sbin/vidcontrol/vidcontrol.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 @@ -46,18 +46,16 @@ #include "path.h" #include "decode.h" =20 -#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) =20 /* 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 =20 char legal_colors[16][16] =3D { "black", "blue", "green", "cyan", @@ -65,16 +63,113 @@ "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 =3D 0; int number; -int vesa_cols =3D _VESA_800x600_DFL_COLS; -int vesa_rows =3D _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) =3D=3D -1) + errc(1, errno, "getting active vty"); +=20 + cur_info.console_info.size =3D sizeof(cur_info.console_info); +=20 + if (ioctl(0, CONS_GETINFO, &cur_info.console_info) =3D=3D -1) + errc(1, errno, "getting console information"); +=20 + if (ioctl(0, GIO_SCRNMAP, &cur_info.screen_map) =3D=3D -1) + errc(1, errno, "getting screen map"); +=20 + if (ioctl(0, CONS_GET, &cur_info.video_mode_number) =3D=3D -1) + errc(1, errno, "getting video mode number"); +=20 + cur_info.video_mode_info.vi_mode =3D cur_info.video_mode_number; +=20 + if (ioctl(0, CONS_MODEINFO, &cur_info.video_mode_info) =3D=3D -1) + errc(1, errno, "getting video mode parameters"); +=20 + normal_fore_color =3D cur_info.console_info.mv_norm.fore; + normal_back_color =3D cur_info.console_info.mv_norm.back; + revers_fore_color =3D cur_info.console_info.mv_rev.fore; + revers_back_color =3D 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]; +=20 + ioctl(0, VT_ACTIVATE, (caddr_t) (long)cur_info.active_vty); +=20 + fprintf(stderr, "ESC[=3D%dA", cur_info.console_info.mv_ovscan); + fprintf(stderr, "ESC[=3D%dF", cur_info.console_info.mv_norm.fore); + fprintf(stderr, "ESC[=3D%dG", cur_info.console_info.mv_norm.back); + fprintf(stderr, "ESC[=3D%dH", cur_info.console_info.mv_rev.fore); + fprintf(stderr, "ESC[=3D%dI", cur_info.console_info.mv_rev.back); +=20 + ioctl(0, PIO_SCRNMAP, &cur_info.screen_map); +=20 + if (cur_info.video_mode_number >=3D 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); +=20 + if (cur_info.video_mode_info.vi_flags & V_INFO_GRAPHICS) { + size[0] =3D cur_info.video_mode_info.vi_width / 8; + size[1] =3D cur_info.video_mode_info.vi_height / + cur_info.console_info.font_size; + size[2] =3D cur_info.console_info.font_size; +=20 + ioctl(0, KDRASTER, size); + } +} =20 +/* + * Print a short usage string describing all options, then exit. + */ =20 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]", @@ -85,16 +180,28 @@ exit(1); } =20 +/* + * Retrieve the next argument from the command line (for options that requ= ire + * more than one argument). + */ + char * nextarg(int ac, char **av, int *indp, int oc, int strict) { if (*indp < ac) return(av[(*indp)++]); - if (strict !=3D 0) + if (strict !=3D 0) { + revert(); errx(1, "option requires two arguments -- %c", oc); + } return(NULL); } =20 +/* + * Guess which file to open. Try to open each combination of a specified s= et + * of file name components. + */ + FILE * openguess(char *a[], char *b[], char *c[], char *d[], char **name) { @@ -118,6 +225,10 @@ return (NULL); } =20 +/* + * Load a screenmap from a file and set it. + */ + void load_scrnmap(char *filename) { @@ -132,44 +243,56 @@ =20 fd =3D openguess(a, b, c, d, &name); if (fd =3D=3D NULL) { - warn("screenmap file not found"); - return; + revert(); + errx(1, "screenmap file not found"); } size =3D sizeof(scrnmap); if (decode(fd, (char *)&scrnmap, size) !=3D size) { rewind(fd); if (fread(&scrnmap, 1, size, fd) !=3D 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"); + } } =20 +/* + * Set the default screenmap. + */ + void -load_default_scrnmap() +load_default_scrnmap(void) { scrmap_t scrnmap; int i; =20 for (i=3D0; i<256; i++) *((char*)&scrnmap + i) =3D 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"); + } } =20 +/* + * Print the current screenmap to stdout. + */ + void -print_scrnmap() +print_scrnmap(void) { unsigned char map[256]; int i; =20 if (ioctl(0, GIO_SCRNMAP, &map) < 0) { - warn("getting screenmap"); - return; + revert(); + errc(1, errno, "getting screenmap"); } for (i=3D0; i 0 && i % 16 =3D=3D 0) @@ -180,9 +303,12 @@ fprintf(stdout, " %03d", map[i]); } fprintf(stdout, "\n"); - } =20 +/* + * Determine a file's size. + */ + int fsize(FILE *file) { @@ -194,7 +320,9 @@ return -1; } =20 -#define DATASIZE(x) ((x).w * (x).h * 256 / 8) +/* + * Load a font from file and set it. + */ =20 void load_font(char *type, char *filename) @@ -220,14 +348,15 @@ =20 info.size =3D sizeof(info); if (ioctl(0, CONS_GETINFO, &info) =3D=3D -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 =3D openguess(a, b, c, d, &name); if (fd =3D=3D NULL) { - warn("%s: can't load font file", filename); - return; + revert(); + errx(1, "%s: can't load font file", filename); } if (type !=3D NULL) { size =3D 0; @@ -236,12 +365,13 @@ if (sizes[i].w =3D=3D w && sizes[i].h =3D=3D h) { size =3D DATASIZE(sizes[i]); io =3D sizes[i].io; + font_height =3D sizes[i].h; } =20 if (size =3D=3D 0) { - warnx("%s: bad font size specification", type); fclose(fd); - return; + revert(); + errx(1, "%s: bad font size specification", type); } } else { /* Apply heuristics */ @@ -260,14 +390,15 @@ if (DATASIZE(sizes[i]) =3D=3D dsize[j]) { size =3D dsize[j]; io =3D sizes[i].io; + font_height =3D sizes[i].h; j =3D 2; /* XXX */ break; } =20 if (size =3D=3D 0) { - warnx("%s: can't guess font size", filename); fclose(fd); - return; + revert(); + errx(1, "%s: can't guess font size", filename); } rewind(fd); } @@ -276,18 +407,25 @@ if (decode(fd, fontmap, size) !=3D size) { rewind(fd); if (fsize(fd) !=3D size || fread(fontmap, 1, size, fd) !=3D 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); } =20 +/* + * Set the timeout for the screensaver. + */ + void set_screensaver_timeout(char *arg) { @@ -298,14 +436,20 @@ else { nsec =3D atoi(arg); if ((*arg =3D=3D '\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) =3D=3D -1) - warn("setting screensaver period"); + if (ioctl(0, CONS_BLANKTIME, &nsec) =3D=3D -1) { + revert(); + errc(1, errno, "setting screensaver period"); + } } =20 +/* + * Set the cursor's shape/type. + */ + void set_cursor_type(char *appearence) { @@ -318,13 +462,20 @@ else if (!strcmp(appearence, "destructive")) type =3D 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) =3D=3D -1) { + revert(); + errc(1, errno, "setting cursor type"); } - ioctl(0, CONS_CURSORTYPE, &type); } =20 -int +/* + * Set the video mode. + */ + +void video_mode(int argc, char **argv, int *index) { static struct { @@ -363,64 +514,81 @@ { "VESA_800x600", SW_VESA_800x600 }, { NULL }, }; + int new_mode_num =3D 0; unsigned long mode =3D 0; - int cur_mode;=20 int ioerr; int size[3]; int i; =20 - if (ioctl(0, CONS_GET, &cur_mode) < 0) - err(1, "cannot get the current video mode"); if (*index < argc) { - for (i =3D 0; modes[i].name !=3D NULL; ++i) { - if (!strcmp(argv[*index], modes[i].name)) { - mode =3D modes[i].mode; - break; + if (!strncmp(argv[*index], "MODE_", 5)) { + if (!isnumber(argv[*index][5])) + errx(1, "invalid video mode number"); +=20 + new_mode_num =3D atoi(&argv[*index][5]); + } else { + for (i =3D 0; modes[i].name !=3D NULL; ++i) { + if (!strcmp(argv[*index], modes[i].name)) { + new_mode_num =3D modes[i].mode; + break; + } } + if (modes[i].name =3D=3D NULL) + errx(1, "invalid video mode name"); } - if (modes[i].name =3D=3D NULL) - return EXIT_FAILURE; - if (ioctl(0, mode, NULL) < 0) { - warn("cannot set videomode"); - return EXIT_FAILURE; - } - if (mode =3D=3D SW_VESA_800x600) { - /* columns */ - if ((vesa_cols * 8 > 800) || (vesa_cols <=3D 0)) { - warnx("incorrect number of columns: %d", - vesa_cols); - size[0] =3D _VESA_800x600_DFL_COLS; - } else { + /* Collect enough information about the new video mode... */ + new_mode_info.vi_mode =3D new_mode_num; + if (ioctl(0, CONS_MODEINFO, &new_mode_info) =3D=3D -1) { + revert(); + errc(1, errno, "obtaining new video mode parameters"); + } + if (mode =3D=3D 0) { + if (new_mode_num >=3D M_VESA_BASE) + mode =3D _IO('V', new_mode_num - M_VESA_BASE); + else + mode =3D _IO('S', new_mode_num); + } + /* Try setting the new mode. */ + if (ioctl(0, mode, NULL) =3D=3D -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 =3D=3D 0) + font_height =3D cur_info.console_info.font_size; + size[2] =3D font_height; + /* adjust columns */ + if ((vesa_cols * 8 > new_mode_info.vi_width) || + (vesa_cols <=3D 0)) + size[0] =3D new_mode_info.vi_width / 8; + else size[0] =3D vesa_cols; - } - /* rows */ - if ((vesa_rows * _VESA_800x600_DFL_FNSZ > 600) || - (vesa_rows <=3D0)) { - warnx("incorrect number of rows: %d", - vesa_rows); - size[1] =3D _VESA_800x600_DFL_ROWS; - } else { + /* adjust rows */ + if ((vesa_rows * font_height > new_mode_info.vi_height) + || (vesa_rows <=3D 0)) + size[1] =3D new_mode_info.vi_height / font_height; + else size[1] =3D vesa_rows; - } - /* font size */ - size[2] =3D _VESA_800x600_DFL_FNSZ; + /* set raster mode */ if (ioctl(0, KDRASTER, size)) { - ioerr =3D errno; - if (cur_mode >=3D 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 =3D 1; (*index)++; } - return EXIT_SUCCESS; } =20 +/* + * Return the number for a specified color name. + */ + int get_color_number(char *color) { @@ -432,56 +600,88 @@ return -1; } =20 +/* + * 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; =20 if (*index < argc && (color =3D get_color_number(argv[*index])) !=3D -1) { (*index)++; - fprintf(stderr, "=1B[=3D%dF", color); - if (*index < argc - && (color =3D get_color_number(argv[*index])) !=3D -1 - && color < 8) { + normal_fore_color =3D color; + colors_changed =3D 1; + if (*index < argc && + (color =3D get_color_number(argv[*index])) !=3D -1) { (*index)++; - fprintf(stderr, "=1B[=3D%dG", color); + normal_back_color =3D color; } } } =20 +/* + * 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; =20 if ((color =3D get_color_number(argv[*(index)-1])) !=3D -1) { - fprintf(stderr, "=1B[=3D%dH", color); - if (*index < argc - && (color =3D get_color_number(argv[*index])) !=3D -1 - && color < 8) { + revers_fore_color =3D color; + colors_changed =3D 1; + if (*index < argc && + (color =3D get_color_number(argv[*index])) !=3D -1) { (*index)++; - fprintf(stderr, "=1B[=3D%dI", color); + revers_back_color =3D color; } } } =20 +/* + * Set normal and reverse foreground and background colors. + */ + +void +set_colors(void) +{ + fprintf(stderr, "ESC[=3D%dF", normal_fore_color); + fprintf(stderr, "ESC[=3D%dG", normal_back_color); + fprintf(stderr, "ESC[=3D%dH", revers_fore_color); + fprintf(stderr, "ESC[=3D%dI", revers_back_color); +} + +/* + * Switch to virtual terminal #arg. + */ + void set_console(char *arg) { int n; =20 if( !arg || strspn(arg,"0123456789") !=3D strlen(arg)) { - warnx("bad console number"); - return; + revert(); + errx(1, "bad console number"); } =20 n =3D atoi(arg); if (n < 1 || n > 16) { - warnx("console number out of range"); - } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) =3D=3D -1) - warn("ioctl(VT_ACTIVATE)"); + revert(); + errx(1, "console number out of range"); + } else if (ioctl(0, VT_ACTIVATE, (caddr_t) (long) n) =3D=3D -1) { + revert(); + errc(1, errno, "ioctl(VT_ACTIVATE)"); + } } =20 +/* + * Sets the border color. + */ + void set_border_color(char *arg) { @@ -494,6 +694,10 @@ usage(); } =20 +/* + * Set the mouse characer. + */ + void set_mouse_char(char *arg) { @@ -502,14 +706,21 @@ =20 l =3D 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 =3D MOUSE_MOUSECHAR; mouse.u.mouse_char =3D (int)l; - ioctl(0, CONS_MOUSECTL, &mouse); + if (ioctl(0, CONS_MOUSECTL, &mouse) =3D=3D -1) { + revert(); + errc(1, errno, "setting mouse character"); + } } =20 +/* + * Show/hide the mouse. + */ + void set_mouse(char *arg) { @@ -520,10 +731,14 @@ else if (!strcmp(arg, "off")) mouse.operation =3D 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) =3D=3D -1) { + revert(); + errc(1, errno, "%sing the mouse", + mouse.operation =3D=3D MOUSE_SHOW ? "show" : "hid"); } - ioctl(0, CONS_MOUSECTL, &mouse); } =20 void @@ -536,13 +751,20 @@ else if (!strcmp(arg, "on")) data =3D 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) =3D=3D -1) { + revert(); + errc(1, errno, "turning %s vty switching", + data =3D=3D 0x01 ? "off" : "on"); } - if (ioctl(0, VT_LOCKSWITCH, &data) =3D=3D -1) - warn("ioctl(VT_LOCKSWITCH)"); } =20 +/* + * Return the adapter name for a specified type. + */ + static char *adapter_name(int type) { @@ -567,6 +789,10 @@ return names[i].name; } =20 +/* + * Show graphics adapter information. + */ + void show_adapter_info(void) { @@ -574,8 +800,8 @@ =20 ad.va_index =3D 0; if (ioctl(0, CONS_ADPINFO, &ad)) { - warn("failed to obtain adapter information"); - return; + revert(); + errc(1, errno, "failed to obtain adapter information"); } =20 printf("fb%d:\n", ad.va_index); @@ -594,6 +820,10 @@ printf(" reserved:0x%x\n", ad.va_unused0); } =20 +/* + * Show video mode information. + */ + void show_mode_info(void) { @@ -645,13 +875,13 @@ 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"); } } =20 void -test_frame() +test_frame(void) { int i; =20 @@ -682,8 +912,9 @@ =20 info.size =3D sizeof(info); if (ioctl(0, CONS_GETINFO, &info) =3D=3D -1) { - warn("failed to obtain current video mode parameters"); - return; + revert(); + errc(1, errno, + "failed to obtain current video mode parameters"); } =20 shot.x =3D shot.y =3D 0; @@ -694,13 +925,13 @@ =20 shot.buf =3D alloca(shot.xsize * shot.ysize * sizeof(u_int16_t)); if (shot.buf =3D=3D NULL) { - warn("failed to allocate memory for dump"); - return; + revert(); + errx(1, "failed to allocate memory for dump"); } =20 if (ioctl(0, CONS_SCRSHOT, &shot) =3D=3D -1) { - warn("failed to get dump of the screen"); - return; + revert(); + errc(1, errno, "failed to get dump of the screen"); } =20 if (mode =3D=3D DUMP_FMT_RAW) { @@ -717,8 +948,8 @@ =20 line =3D alloca(shot.xsize + 1); if (line =3D=3D NULL) { - warn("failed to allocate memory for line buffer"); - return; + revert(); + errx(1, "failed to allocate memory for line buffer"); } =20 for (y =3D 0; y < shot.ysize; y++) { @@ -743,6 +974,10 @@ return; } =20 +/* + * Set the console history buffer size. + */ + void set_history(char *opt) { @@ -750,19 +985,27 @@ =20 size =3D atoi(opt); if ((*opt =3D=3D '\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) =3D=3D -1) { + revert(); + errc(1, errno, "setting history buffer size"); } - if (ioctl(0, CONS_HISTORY, &size) =3D=3D -1) - warn("setting history buffer size"); } =20 +/* + * Clear the console history buffer. + */ + void -clear_history() +clear_history(void) { =20 - if (ioctl(0, CONS_CLRHIST) =3D=3D -1) - warn("clear history buffer"); + if (ioctl(0, CONS_CLRHIST) =3D=3D -1) { + revert(); + errc(1, errno, "clear history buffer"); + } } =20 int @@ -770,12 +1013,11 @@ { char *font, *type; int dumpmod, dumpopt, opt; - int reterr; =20 - info.size =3D sizeof(info); if (argc =3D=3D 1) usage(); - /* Not reached */ + init(); + info.size =3D sizeof(info); if (ioctl(0, CONS_GETINFO, &info) < 0) err(1, "must be on a virtual console"); dumpmod =3D 0; @@ -806,6 +1048,7 @@ case 'g': if (sscanf(optarg, "%dx%d", &vesa_cols, &vesa_rows) !=3D 2) { + revert(); warnx("incorrect geometry: %s", optarg); usage(); } @@ -838,7 +1081,7 @@ dumpmod =3D DUMP_FMT_TXT; break; case 'r': - set_reverse_colors(argc, argv, &optind); + get_reverse_colors(argc, argv, &optind); break; case 'S': set_lockswitch(optarg); @@ -857,14 +1100,26 @@ } if (dumpmod !=3D 0) dump_screen(dumpmod, dumpopt); - reterr =3D 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 !=3D argc) || (argc =3D=3D 1)) usage(); - return reterr; + return(EXIT_SUCCESS); } =20 Cyrille Lefevre --=20 mailto:cyrille.lefevre@laposte.net