diff options
Diffstat (limited to 'sys/dev/syscons/scvgarndr.c')
-rw-r--r-- | sys/dev/syscons/scvgarndr.c | 225 |
1 files changed, 196 insertions, 29 deletions
diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c index 7cecae9db1cb..09586fb446f5 100644 --- a/sys/dev/syscons/scvgarndr.c +++ b/sys/dev/syscons/scvgarndr.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/fbio.h> #include <sys/consio.h> +#include <sys/sysctl.h> #include <machine/bus.h> @@ -149,24 +150,136 @@ RENDERER_MODULE(vga, vga_set); struct mousedata { u_short md_border[16]; u_short md_interior[16]; - u_short md_width; - u_short md_height; + u_char md_width; + u_char md_height; + u_char md_baspect; + u_char md_iaspect; + const char *md_name; }; -static const struct mousedata mouse9x13 = { { - 0xc000, 0xa000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x9780, - 0xf200, 0x1200, 0x1900, 0x0900, 0x0f00, 0x0000, 0x0000, 0x0000, }, { - 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x6800, - 0x0c00, 0x0c00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, - 9, 13, +static const struct mousedata mouse10x16_50 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8200, + 0x8400, 0x8400, 0x8400, 0x9200, 0xB200, 0xA900, 0xC900, 0x8600, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7C00, + 0x7800, 0x7800, 0x7800, 0x6C00, 0x4C00, 0x4600, 0x0600, 0x0000, }, + 10, 16, 49, 52, "mouse10x16_50", }; -static const struct mousedata mouse10x16 = { { - 0xc000, 0xa000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, - 0x8040, 0x83c0, 0x9200, 0xa900, 0xc900, 0x0480, 0x0480, 0x0300, }, { - 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7c00, 0x7e00, 0x7f00, - 0x7f80, 0x7c00, 0x6c00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0000, }, - 10, 16, +static const struct mousedata mouse8x14_67 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8700, + 0x8400, 0x9200, 0xB200, 0xA900, 0xC900, 0x0600, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x7800, 0x6C00, 0x4C00, 0x4600, 0x0600, 0x0000, 0x0000, 0x0000, }, + 8, 14, 64, 65, "mouse8x14_67", +}; + +static const struct mousedata mouse8x13_75 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8600, 0x8400, + 0xB200, 0xD200, 0x0900, 0x0900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7800, 0x7800, + 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 8, 13, 75, 80, "mouse8x13_75", +}; + +static const struct mousedata mouse10x16_75 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8700, + 0x8400, 0x9200, 0xB200, 0xC900, 0x0900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x7800, 0x6C00, 0x4C00, 0x0600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 72, 75, "mouse10x16_75", +}; + +static const struct mousedata mouse9x13_90 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8780, + 0x9200, 0xB200, 0xD900, 0x8900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x6C00, 0x4C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 9, 13, 89, 89, "mouse9x13_90", +}; + +static const struct mousedata mouse10x16_90 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x8040, 0x83E0, 0x8200, 0x9900, 0xA900, 0xC480, 0x8480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x7C00, 0x7C00, 0x6600, 0x4600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 89, 89, "mouse10x16_90", +}; + +static const struct mousedata mouse9x13_100 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8780, + 0xB200, 0xD200, 0x8900, 0x0900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7800, + 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 9, 13, 106, 113, "mouse9x13_100", +}; + +static const struct mousedata mouse10x16_100 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x8040, 0x83C0, 0x9200, 0xA900, 0xC900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x7C00, 0x6C00, 0x4600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 96, 106, "mouse10x16_100", +}; + +static const struct mousedata mouse10x14_120 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x97C0, 0xB200, 0xF200, 0xC900, 0x8900, 0x0600, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x6800, 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, }, + 10, 14, 120, 124, "mouse10x14_120", +}; + +static const struct mousedata mouse10x16_120 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x97C0, 0xB200, 0xF200, 0xC900, 0x8900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x6800, 0x4C00, 0x0C00, 0x0600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 120, 124, "mouse10x16_120", +}; + +static const struct mousedata mouse9x13_133 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x9780, 0xB200, 0xC900, 0x0900, 0x0600, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x6800, 0x4C00, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, }, + 9, 13, 142, 124, "mouse9x13_133", +}; + +static const struct mousedata mouse10x16_133 = { { + 0xC000, 0xA000, 0x9000, 0x8800, 0x8400, 0x8200, 0x8100, 0x8080, + 0x8040, 0x93E0, 0xB200, 0xC900, 0x8900, 0x0480, 0x0480, 0x0300, }, { + 0x0000, 0x4000, 0x6000, 0x7000, 0x7800, 0x7C00, 0x7E00, 0x7F00, + 0x7F80, 0x6C00, 0x4C00, 0x0600, 0x0600, 0x0300, 0x0300, 0x0000, }, + 10, 16, 120, 133, "mouse10x16_133", +}; + +static const struct mousedata mouse14x10_240 = { { + 0xF800, 0xCE00, 0xC380, 0xC0E0, 0xC038, 0xC1FC, 0xDCC0, 0xF660, + 0xC330, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, { + 0x0000, 0x3000, 0x3C00, 0x3F00, 0x3FC0, 0x3E00, 0x2300, 0x0180, + 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }, + 14, 10, 189, 189, "mouse14x10_240", +}; + +static const struct mousedata * const mouselarge[] = { + &mouse10x16_50, + &mouse8x14_67, + &mouse10x16_75, + &mouse10x16_90, + &mouse10x16_100, + &mouse10x16_120, + &mouse10x16_133, + &mouse14x10_240, +}; + +static const struct mousedata * const mousesmall[] = { + &mouse8x14_67, + &mouse8x13_75, + &mouse9x13_90, + &mouse9x13_100, + &mouse10x14_120, + &mouse9x13_133, + &mouse14x10_240, }; #endif #endif @@ -227,6 +340,69 @@ static uint16_t vga_palette15[16] = { }; #endif +static int vga_aspect_scale= 100; +SYSCTL_INT(_machdep, OID_AUTO, vga_aspect_scale, CTLFLAG_RW, + &vga_aspect_scale, 0, "Aspect scale ratio (3:4):actual times 100"); + +static void +vga_setmdp(scr_stat *scp) +{ +#if !defined(SC_NO_CUTPASTE) && \ + (!defined(SC_ALT_MOUSE_IMAGE) || defined(SC_PIXEL_MODE)) + const struct mousedata *mdp; + const struct mousedata * const *mdpp; + int aspect, best_i, best_v, i, n, v, wb, wi, xpixel, ypixel; + + xpixel = scp->xpixel; + ypixel = scp->ypixel; + if (scp->sc->adp->va_flags & V_ADP_CWIDTH9) + xpixel = xpixel * 9 / 8; + + /* If 16:9 +-1%, assume square pixels, else scale to 4:3 or full. */ + aspect = xpixel * 900 / ypixel / 16; + if (aspect < 99 || aspect > 100) + aspect = xpixel * 300 / ypixel / 4 * vga_aspect_scale / 100; + + /* + * Use 10x16 cursors except even with 8x8 fonts except in ~200- + * line modes where pixels are very large and in text mode where + * even 13 pixels high is really 4 too many. Clipping a 16-high + * cursor at 9-high gives a variable tail which looks better than + * a smaller cursor with a constant tail. + * + * XXX: the IS*SC() macros don't work when this is called at the + * end of a mode switch since UNKNOWN_SC is still set. + */ + if (scp->font_size <= 8 && + (ypixel < 300 || !(scp->status & PIXEL_MODE))) { + mdpp = &mousesmall[0]; + n = nitems(mousesmall); + } else { + mdpp = &mouselarge[0]; + n = nitems(mouselarge); + } + if (scp->status & PIXEL_MODE) { + wb = 1024; + wi = 256; + } else { + wb = 256; + wi = 1024; + } + best_i = 0; + best_v = 0x7fffffff; + for (i = 0; i < n; i++) { + v = (wb * abs(mdpp[i]->md_baspect - aspect) + + wi * abs(mdpp[i]->md_iaspect - aspect)) / aspect; + if (best_v > v) { + best_v = v; + best_i = i; + } + } + mdp = mdpp[best_i]; + scp->mouse_data = mdp; +#endif /* !SC_NO_CUTPASTE && (!SC_ALT_MOUSE_IMAGE || SC_PIXEL_MODE) */ +} + static void vga_nop(scr_stat *scp) { @@ -272,13 +448,10 @@ vga_txtdraw(scr_stat *scp, int from, int count, int flip) static void vga_txtcursor_shape(scr_stat *scp, int base, int height, int blink) { + vga_setmdp(scp); if (base < 0 || base >= scp->font_size) return; /* the caller may set height <= 0 in order to disable the cursor */ -#if 0 - scp->curs_attr.base = base; - scp->curs_attr.height = height; -#endif vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size, blink); } @@ -407,7 +580,7 @@ draw_txtmouse(scr_stat *scp, int x, int y) int crtc_addr; int i; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; /* prepare mousepointer char's bitmaps */ pos = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; @@ -807,13 +980,7 @@ vga_vgadraw_planar(scr_stat *scp, int from, int count, int flip) static void vga_pxlcursor_shape(scr_stat *scp, int base, int height, int blink) { - if (base < 0 || base >= scp->font_size) - return; - /* the caller may set height <= 0 in order to disable the cursor */ -#if 0 - scp->curs_attr.base = base; - scp->curs_attr.height = height; -#endif + vga_setmdp(scp); } static void @@ -1003,7 +1170,7 @@ draw_pxlmouse_planar(scr_stat *scp, int x, int y) int i, j, k; uint8_t m1; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; line_width = scp->sc->adp->va_line_width; xoff = (x - scp->xoff*8)%8; yoff = y - rounddown(y, line_width); @@ -1070,7 +1237,7 @@ remove_pxlmouse_planar(scr_stat *scp, int x, int y) vm_offset_t p; int bx, by, i, line_width, xend, xoff, yend, yoff; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; /* * It is only necessary to remove the mouse image where it overlaps @@ -1109,7 +1276,7 @@ vga_pxlmouse_direct(scr_stat *scp, int x, int y, int on) int xend, yend; int i, j; - mdp = (scp->font_size < 14) ? &mouse9x13 : &mouse10x16; + mdp = scp->mouse_data; /* * Determine overlap with the border and then if removing, do nothing |