kern/71142: vesa [1024x768] mode support
Cyrille Lefevre
cyrille.lefevre at laposte.net
Mon Aug 30 02:20:24 PDT 2004
Note: There was a bad value `no=20' for the field `>Confidential:'.
It was set to the default value of `yes'.
>Number: 71142
>Category: kern
>Synopsis: vesa [1024x768] mode support
>Confidential: yes
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Mon Aug 30 09:20:23 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Cyrille Lefevre
>Release: FreeBSD 5.2-CURRENT i386
>Organization:
ACME
>Environment:
System: FreeBSD gits 5.2-CURRENT FreeBSD 5.2-CURRENT #0: Mon Aug 23 04:03:3=
2 CEST 2004 root at gits.gits.invalid:/disk1/freebsd/current/obj/disk3/freebsd=
/current/src/sys/CUSTOM i386
>Description:
see the following thread entitled "[PATCH TO TEST] VESA [1024x768] mode sup=
port
for FreeBSD-CURRENT" started on "Fri, 27 Aug 2004 01:59:50 +0000" for detai=
ls :
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=3D2790218+0+/usr/local/www/db/=
text/2004/freebsd-current/20040829.freebsd-current
>How-To-Repeat:
vidcontrol MODE_259
>Fix:
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.*$ -u -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.*$ -u -r1.15 scvgarndr.c
--- sys/dev/syscons/scvgarndr.c 30 May 2004 20:08:42 -0000 1.15
+++ sys/dev/syscons/scvgarndr.c 29 Aug 2004 17:07:28 -0000
@@ -47,7 +47,7 @@
#include <isa/isareg.h>
=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;
@@ -457,7 +510,121 @@
}
=20
static void
-vga_pxlborder(scr_stat *scp, int color)
+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_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 +659,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 +694,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 +725,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 +738,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 +831,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 +863,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 +876,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 +909,70 @@
#endif
}
=20
-static void=20
-draw_pxlcursor(scr_stat *scp, int at, int on, int flip)
+static void
+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 +984,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 +1011,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 +1019,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
@@ -726,7 +1085,87 @@
#ifndef SC_NO_CUTPASTE
=20
static void
-draw_pxlmouse(scr_stat *scp, int x, int y)
+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_planar(scr_stat *scp, int x, int y)
{
vm_offset_t p;
int line_width;
@@ -801,7 +1240,28 @@
}
=20
static void
-remove_pxlmouse(scr_stat *scp, int x, int y)
+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_planar(scr_stat *scp, int x, int y)
{
vm_offset_t p;
int col, row;
@@ -857,6 +1317,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.*$ -u -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.*$ -u -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_<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
@@ -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 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
=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.*$ -u -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<sizeof(map); i++) {
if (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
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list