diff options
-rw-r--r-- | console-client/vga-dynafont.c | 13 | ||||
-rw-r--r-- | console-client/vga-dynafont.h | 2 | ||||
-rw-r--r-- | console-client/vga-hw.h | 5 | ||||
-rw-r--r-- | console-client/vga-support.c | 45 | ||||
-rw-r--r-- | console-client/vga.c | 12 |
5 files changed, 66 insertions, 11 deletions
diff --git a/console-client/vga-dynafont.c b/console-client/vga-dynafont.c index 6745e88a..5e3bc6d1 100644 --- a/console-client/vga-dynafont.c +++ b/console-client/vga-dynafont.c @@ -87,6 +87,9 @@ struct dynafont /* The size of the VGA font (256 or 512). Must be a power of 2! */ int size; + /* The width of the VGA font (8 or 9). */ + int width; + /* A hash containing a pointer to a struct mapped_character for each UCS-4 character we map to a VGA font index. */ struct hurd_ihash charmap; @@ -467,7 +470,8 @@ add_gnu_head (bdf_font_t font) Code Page 437). */ error_t dynafont_new (bdf_font_t font, bdf_font_t font_italic, bdf_font_t font_bold, - bdf_font_t font_bold_italic, int size, dynafont_t *dynafont) + bdf_font_t font_bold_italic, int size, int width, + dynafont_t *dynafont) { dynafont_t df; struct bdf_glyph *glyph = NULL; @@ -490,6 +494,9 @@ dynafont_new (bdf_font_t font, bdf_font_t font_italic, bdf_font_t font_bold, df->font_bold = font_bold; df->font_bold_italic = font_bold_italic; df->size = size; + if (!width) + width = df->font->bbox.width; + df->width = width; df->cursor_standout = 0; df->charmap_data = calloc (size, sizeof (struct mapped_character)); @@ -509,7 +516,7 @@ dynafont_new (bdf_font_t font, bdf_font_t font_italic, bdf_font_t font_bold, hurd_ihash_init (&df->charmap, offsetof (struct mapped_character, locp)); - if (df->font->bbox.width == 9) + if (width == 9) { /* 32 from 256 font slots are for horizontal line graphic characters. */ @@ -985,7 +992,7 @@ dynafont_activate (dynafont_t df) display problems for the user if we don't also program the video mode timings. The standard font height for 80x25 is 16. */ vga_set_font_height (height); - vga_set_font_width (df->font->bbox.width % 8 ? 9 : 8); + vga_set_font_width (df->width); active_dynafont = df; dynafont_set_cursor (df, df->cursor_standout); diff --git a/console-client/vga-dynafont.h b/console-client/vga-dynafont.h index c2bab700..0e80e047 100644 --- a/console-client/vga-dynafont.h +++ b/console-client/vga-dynafont.h @@ -45,7 +45,7 @@ typedef struct dynafont *dynafont_t; the font is changed with dynafont_change_font. */ error_t dynafont_new (bdf_font_t font, bdf_font_t font_italic, bdf_font_t font_bold, bdf_font_t font_bold_italic, - int size, dynafont_t *dynafont); + int size, int width, dynafont_t *dynafont); /* Release a dynafont object and its associated resources. */ void dynafont_free (dynafont_t df); diff --git a/console-client/vga-hw.h b/console-client/vga-hw.h index 7275b03e..b4212e62 100644 --- a/console-client/vga-hw.h +++ b/console-client/vga-hw.h @@ -132,6 +132,11 @@ #define VGA_ATTR_ADDR_DATA_REG 0x3c0 #define VGA_ATTR_DATA_READ_REG 0x3c1 +/* The Attribute Mode Control subregister. */ +#define VGA_ATTR_MODE_ADDR 0x10 +#define VGA_ATTR_MODE_LGE 0x04 + +#define VGA_ATTR_ENABLE_ADDR 0x20 /* Other junk. */ #define VGA_INPUT_STATUS_1_REG 0x3da diff --git a/console-client/vga-support.c b/console-client/vga-support.c index ce4d7354..ce339e19 100644 --- a/console-client/vga-support.c +++ b/console-client/vga-support.c @@ -53,6 +53,8 @@ struct vga_state unsigned char crt_cursor_high; unsigned char crt_cursor_low; + unsigned char attr_mode; + char videomem[2 * 80 * 25]; unsigned char fontmem[2 * VGA_FONT_SIZE * VGA_FONT_HEIGHT]; }; @@ -124,6 +126,18 @@ vga_init (void) outb (VGA_CRT_CURSOR_LOW, VGA_CRT_ADDR_REG); vga_state->crt_cursor_low = inb (VGA_CRT_DATA_REG); + /* Side effect of reading the input status #1 register is to + reset the attribute mixed address/data register so that the + next write it expects is the address, not the data. */ + inb (VGA_INPUT_STATUS_1_REG); + outb (VGA_ATTR_MODE_ADDR, VGA_ATTR_ADDR_DATA_REG); + vga_state->attr_mode = inb (VGA_ATTR_DATA_READ_REG); + + /* Re-enable the screen. */ + inb (VGA_INPUT_STATUS_1_REG); + outb (VGA_ATTR_ENABLE_ADDR, VGA_ATTR_ADDR_DATA_REG); + outb (0x00, VGA_ATTR_ADDR_DATA_REG); + /* Read/write in interleaved mode. */ outb (VGA_GFX_MISC_ADDR, VGA_GFX_ADDR_REG); outb (VGA_GFX_MISC_CHAINOE | VGA_GFX_MISC_B8TOBF, VGA_GFX_DATA_REG); @@ -180,6 +194,15 @@ vga_fini (void) outb (VGA_CRT_CURSOR_LOW, VGA_CRT_ADDR_REG); outb (vga_state->crt_cursor_low, VGA_CRT_DATA_REG); + inb (VGA_INPUT_STATUS_1_REG); + outb (VGA_ATTR_MODE_ADDR, VGA_ATTR_ADDR_DATA_REG); + outb (vga_state->attr_mode, VGA_ATTR_DATA_READ_REG); + + /* Re-enable the screen. */ + inb (VGA_INPUT_STATUS_1_REG); + outb (VGA_ATTR_ENABLE_ADDR, VGA_ATTR_ADDR_DATA_REG); + outb (0x00, VGA_ATTR_ADDR_DATA_REG); + ioperm (VGA_MIN_REG, VGA_MAX_REG - VGA_MIN_REG + 1, 0); munmap (vga_videomem, VGA_VIDEO_MEM_LENGTH); } @@ -308,6 +331,20 @@ vga_set_font_width (int width) else saved &= ~VGA_SEQ_CLOCK_MODE_8; outb (saved, VGA_SEQ_DATA_REG); + + inb (VGA_INPUT_STATUS_1_REG); + outb (VGA_ATTR_MODE_ADDR, VGA_ATTR_ADDR_DATA_REG); + saved = inb (VGA_ATTR_DATA_READ_REG); + if (width == 8) + saved |= ~VGA_ATTR_MODE_LGE; + else + saved &= VGA_ATTR_MODE_LGE; + outb (saved, VGA_ATTR_ADDR_DATA_REG); + + /* Re-enable the screen. */ + inb (VGA_INPUT_STATUS_1_REG); + outb (VGA_ATTR_ENABLE_ADDR, VGA_ATTR_ADDR_DATA_REG); + outb (0x00, VGA_ATTR_ADDR_DATA_REG); } @@ -423,12 +460,8 @@ vga_exchange_palette_attributes (unsigned char index, { unsigned char attr; - /* Side effect of reading the input status #1 register is to - reset the attribute mixed address/data register so that the - next write it expects is the address, not the data. */ - inb (VGA_INPUT_STATUS_1_REG); - /* Set the address. */ + inb (VGA_INPUT_STATUS_1_REG); outb (index++, VGA_ATTR_ADDR_DATA_REG); attr = inb (VGA_ATTR_DATA_READ_REG); outb ((attr & ~077) | (*palette_attr & 077), VGA_ATTR_ADDR_DATA_REG); @@ -438,6 +471,6 @@ vga_exchange_palette_attributes (unsigned char index, /* Re-enable the screen, which was blanked during the palette operation. */ inb (VGA_INPUT_STATUS_1_REG); - outb (0x20, VGA_ATTR_ADDR_DATA_REG); + outb (VGA_ATTR_ENABLE_ADDR, VGA_ATTR_ADDR_DATA_REG); outb (0x00, VGA_ATTR_ADDR_DATA_REG); } diff --git a/console-client/vga.c b/console-client/vga.c index 8a3260bf..cf6c8c35 100644 --- a/console-client/vga.c +++ b/console-client/vga.c @@ -65,6 +65,9 @@ static char *vga_display_font_bold_italic; /* If false use all colors, else use double font slots. */ static int vga_display_max_glyphs; +/* width of glyphs. */ +static int vga_display_font_width; + /* The timer used for flashing the screen. */ static struct timer_list vga_display_timer; @@ -107,6 +110,7 @@ struct vga_display /* The VGA font for this display. */ dynafont_t df; int df_size; + int df_width; /* The color palette. */ dynacolor_t dc; @@ -209,6 +213,7 @@ static const struct argp_option options[] = "Prefer a lot of colors above a lot of glyphs"}, {"max-glyphs", 'g', 0 , 0, "Prefer a lot of glyphs above a lot of colors"}, + {"font-width", 'w', "NUM" , 0, "Force using NUM pixel-wide glyphs"}, { 0 } }; @@ -251,6 +256,10 @@ parse_opt (int key, char *arg, struct argp_state *state) vga_display_max_glyphs = 1; break; + case 'w': + vga_display_font_width = atoi (arg); + break; + case ARGP_KEY_END: break; @@ -292,6 +301,7 @@ vga_display_init (void **handle, int no_exit, int argc, char *argv[], return ENOMEM; disp->df_size = vga_display_max_glyphs ? 512 : 256; + disp->df_width = vga_display_font_width; disp->width = VGA_DISP_WIDTH; disp->height = VGA_DISP_HEIGHT; @@ -338,7 +348,7 @@ vga_display_start (void *handle) LOAD_FONT (font_bold_italic, FONT_BOLD_ITALIC); err = dynafont_new (font, font_italic, font_bold, font_bold_italic, - disp->df_size, &disp->df); + disp->df_size, disp->df_width, &disp->df); if (err) { free (disp); |