⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.c

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 C
字号:
/* graphics.c - graphics mode support for GRUB *//* Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based * on a patch by Paulo C閟ar Pereira de Andrade <pcpa@conectiva.com.br> *//* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 2001,2002  Red Hat, Inc. *  Portions copyright (C) 2000  Conectiva, Inc. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#ifdef SUPPORT_GRAPHICS#include <term.h>#include <shared.h>#include <graphics.h>static int saved_videomode = 0;static unsigned char *font8x16 = 0;int outline = 0;int disable_space_highlight = 0;int graphics_inited = 0;char splashimage[64];#define VSHADOW VSHADOW1/* 8x16 dot array, total chars = 80*30. plano size = 80*30*16 = 38400 bytes */static unsigned char *VSHADOW1 = (unsigned char *)0x3A0000;	//unsigned char VSHADOW1[38400];static unsigned char *VSHADOW2 = (unsigned char *)0x3A9600;	//unsigned char VSHADOW2[38400];static unsigned char *VSHADOW4 = (unsigned char *)0x3B2C00;	//unsigned char VSHADOW4[38400];static unsigned char *VSHADOW8 = (unsigned char *)0x3BC200;	//unsigned char VSHADOW8[38400];/* text buffer has to be kept around so that we can write things as we * scroll and the like *///static unsigned short text[80 * 30];static unsigned long *text = (unsigned char *)0x3C5800; // length in bytes = 80*30*4/* constants to define the viewable area */const int x0 = 0;const int x1 = 80;const int y0 = 0;const int y1 = 30;/* why do these have to be kept here? */int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;/* current position */static int fontx = 0;static int fonty = 0;/* global state so that we don't try to recursively scroll or cursor */static int no_scroll = 0;/* color state */static int graphics_standard_color = A_NORMAL;static int graphics_normal_color = A_NORMAL;static int graphics_highlight_color = A_REVERSE;static int graphics_current_color = A_NORMAL;static color_state graphics_color_state = COLOR_STATE_STANDARD;/* graphics local functions */static void graphics_setxy (int col, int row);static void graphics_scroll (void);static int read_image (char *s);/* FIXME: where do these really belong? */static inline void outb(unsigned short port, unsigned char val){    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));}static void MapMask(int value) {    outb(0x3c4, 2);    outb(0x3c5, value);}/* bit mask register */static void BitMask(int value) {    outb(0x3ce, 8);    outb(0x3cf, value);}///* Set the splash image *///void graphics_set_splash(char *splashfile) {//    grub_strcpy(splashimage, splashfile);//}///* Get the current splash image *///char *graphics_get_splash(void) {//    return splashimage;//}/* Initialize a vga16 graphics display with the palette based off of * the image in splashimage.  If the image doesn't exist, leave graphics * mode.  */intgraphics_init (void){    if (! graphics_inited)    {        saved_videomode = set_videomode (0x12);    }    if (! read_image (splashimage))    {        set_videomode (saved_videomode);        grub_printf("failed to read image\n");        return 0;    }    font8x16 = (unsigned char *) graphics_get_font (); /* code in asm.S */    graphics_inited = 1;    /* make sure that the highlight color is set correctly */    graphics_highlight_color = ((graphics_normal_color >> 4) | 				((graphics_normal_color & 0xf) << 4));    return 1;}/* Leave graphics mode */voidgraphics_end (void){    if (graphics_inited)    {        set_videomode (saved_videomode);        graphics_inited = 0;    }}/* Print ch on the screen.  Handle any needed scrolling or the like */voidgraphics_putchar (int ch){    ch &= 0xff;    graphics_cursor(0);    if (ch == '\n') {        if (fonty + 1 < y1)            graphics_setxy(fontx, fonty + 1);        else            graphics_scroll();        graphics_cursor(1);        return;    } else if (ch == '\r') {        graphics_setxy(x0, fonty);        graphics_cursor(1);        return;    }    graphics_cursor(0);    text[fonty * 80 + fontx] = ch;    text[fonty * 80 + fontx] &= 0x00ff;    if (graphics_current_color & 0xf0)        text[fonty * 80 + fontx] |= 0x10000;//0x100;    graphics_cursor(0);    if ((fontx + 1) >= x1) {        graphics_setxy(x0, fonty);        if (fonty + 1 < y1)            graphics_setxy(x0, fonty + 1);        else            graphics_scroll();    } else {        graphics_setxy(fontx + 1, fonty);    }    graphics_cursor(1);}/* get the current location of the cursor */intgraphics_getxy(void){    return (fontx << 8) | fonty;}voidgraphics_gotoxy (int x, int y){    graphics_cursor(0);    graphics_setxy(x, y);    graphics_cursor(1);}voidgraphics_cls (void){    int i;    unsigned char *mem, *s1, *s2, *s4, *s8;    graphics_cursor(0);    graphics_gotoxy(x0, y0);    mem = (unsigned char*)VIDEOMEM;    s1 = (unsigned char*)VSHADOW1;    s2 = (unsigned char*)VSHADOW2;    s4 = (unsigned char*)VSHADOW4;    s8 = (unsigned char*)VSHADOW8;    for (i = 0; i < 80 * 30; i++)        text[i] = ' ';    graphics_cursor(1);    BitMask(0xff);    /* plano 1 */    MapMask(1);    grub_memcpy(mem, s1, 38400);    /* plano 2 */    MapMask(2);    grub_memcpy(mem, s2, 38400);    /* plano 3 */    MapMask(4);    grub_memcpy(mem, s4, 38400);    /* plano 4 */    MapMask(8);    grub_memcpy(mem, s8, 38400);    MapMask(15); }voidgraphics_setcolorstate (color_state state){    switch (state)    {	case COLOR_STATE_STANDARD:		graphics_current_color = graphics_standard_color;		break;	case COLOR_STATE_NORMAL:		graphics_current_color = graphics_normal_color;		break;	case COLOR_STATE_HIGHLIGHT:		graphics_current_color = graphics_highlight_color;		break;	default:		graphics_current_color = graphics_standard_color;		break;    }    graphics_color_state = state;}voidgraphics_setcolor (int normal_color, int highlight_color){    graphics_normal_color = normal_color;    graphics_highlight_color = highlight_color;    graphics_setcolorstate (graphics_color_state);}intgraphics_setcursor (int on){    /* FIXME: we don't have a cursor in graphics */    return 0;}/* Read in the splashscreen image and set the palette up appropriately. * Format of splashscreen is an xpm (can be gzipped) with 16 colors and * 640x480. */static intread_image (char *s){    char buf[32], pal[16];    unsigned char c, base, mask;    unsigned i, len, idx, colors, x, y, width, height;    unsigned char *s1 = (unsigned char*)VSHADOW1;    unsigned char *s2 = (unsigned char*)VSHADOW2;    unsigned char *s4 = (unsigned char*)VSHADOW4;    unsigned char *s8 = (unsigned char*)VSHADOW8;    if (! grub_open(s))    {	errnum = 0;	//graphics_set_palette(1, 0, 0, 0);		for (i = 0; i < 38400 / 4; i++)		((long *)s1)[i] = ((long *)s2)[i] = ((long *)s4)[i] = ((long *)s8)[i] = 0;	//for (y = 0, len = 0; y < 480; y++, len += 80) {	//    for (x = 0; x < 640; x++) {	//	s1[len + (x >> 3)] |= 0x80 >> (x & 7);	//    }	//}        goto set_palette;	//return 0;    }    /* read header */    if (! grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {        grub_close();        return 0;    }        /* parse info */    while (grub_read((char *)&c, 1)) {        if (c == '"')            break;    }    while (grub_read((char *)&c, 1) && (c == ' ' || c == '\t'))        ;    i = 0;    width = c - '0';    while (grub_read((char *)&c, 1)) {        if (c >= '0' && c <= '9')            width = width * 10 + c - '0';        else            break;    }    while (grub_read((char *)&c, 1) && (c == ' ' || c == '\t'))        ;    height = c - '0';    while (grub_read((char *)&c, 1)) {        if (c >= '0' && c <= '9')            height = height * 10 + c - '0';        else            break;    }    while (grub_read((char *)&c, 1) && (c == ' ' || c == '\t'))        ;    colors = c - '0';    while (grub_read((char *)&c, 1)) {        if (c >= '0' && c <= '9')            colors = colors * 10 + c - '0';        else            break;    }    base = 0;    while (grub_read((char *)&c, 1) && c != '"')        ;    /* palette */    for (i = 0, idx = 1; i < colors; i++) {        len = 0;        while (grub_read((char *)&c, 1) && c != '"')            ;        grub_read((char *)&c, 1);       /* char */        base = c;        grub_read(buf, 4);      /* \t c # */        while (grub_read((char *)&c, 1) && c != '"') {            if (len < sizeof(buf))                buf[len++] = c;        }        if (len == 6 && idx < 15) {            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;            pal[idx] = base;            graphics_set_palette(idx, r, g, b);            ++idx;        }    }    x = y = len = 0;    for (i = 0; i < 38400 / 4; i++)	((long *)s1)[i] = ((long *)s2)[i] = ((long *)s4)[i] = ((long *)s8)[i] = 0;    /* parse xpm data */    while (y < height) {        while (1) {            if (!grub_read((char *)&c, 1)) {                grub_close();                return 0;            }            if (c == '"')                break;        }        while (grub_read((char *)&c, 1) && c != '"') {            for (i = 1; i < 15; i++)                if (pal[i] == c) {                    c = i;                    break;                }            mask = 0x80 >> (x & 7);            if (c & 1)                s1[len + (x >> 3)] |= mask;            if (c & 2)                s2[len + (x >> 3)] |= mask;            if (c & 4)                s4[len + (x >> 3)] |= mask;            if (c & 8)                s8[len + (x >> 3)] |= mask;            if (++x >= 640) {                x = 0;                if (y < 480)                    len += 80;                ++y;            }        }    }    grub_close();set_palette:    graphics_set_palette(0, (background >> 16), (background >> 8) & 63,                 background & 63);    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,                 foreground & 63);    graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63,                          border & 63);    return 1;}/* Convert a character which is a hex digit to the appropriate integer */inthex (int v){    if (v >= 'A' && v <= 'F')        return (v - 'A' + 10);    if (v >= 'a' && v <= 'f')        return (v - 'a' + 10);    return (v - '0');}/* move the graphics cursor location to col, row */static voidgraphics_setxy (int col, int row){    if (col >= x0 && col < x1)    {        fontx = col;        cursorX = col << 3;    }    if (row >= y0 && row < y1)    {        fonty = row;        cursorY = row << 4;    }}/* scroll the screen */static voidgraphics_scroll (void){    int i, j;    /* we don't want to scroll recursively... that would be bad */    if (no_scroll)        return;    no_scroll = 1;    /* move everything up a line */    for (j = y0 + 1; j < y1; j++)    {        graphics_gotoxy (x0, j - 1);        for (i = x0; i < x1; i++)       	{            graphics_putchar (text[j * 80 + i]);        }    }    /* last line should be blank */    graphics_gotoxy (x0, y1 - 1);    for (i = x0; i < x1; i++)        graphics_putchar (' ');    graphics_setxy (x0, y1 - 1);    no_scroll = 0;}static unsigned char chr[16 << 2];static unsigned char mask[16];static voidgraphics_cursor (int set){    unsigned char *pat, *mem, *ptr;    int i, ch, offset;    int invert = 0;    if (set && no_scroll)        return;    offset = cursorY * 80 + fontx;    ch = text[fonty * 80 + fontx] & 0xff;    if (ch != ' ' || ! disable_space_highlight)	invert = (text[fonty * 80 + fontx] & /*0xff00*/ 0xffff0000) != 0;    pat = font8x16 + (ch << 4);    mem = (unsigned char*)VIDEOMEM + offset;    if (set)    {        MapMask(15);        ptr = mem;        for (i = 0; i < 16; i++, ptr += 80)       	{            cursorBuf[i] = pat[i];            *ptr = ~pat[i];        }        return;    }    if (outline)      for (i = 0; i < 16; i++)      {        mask[i] = pat[i];	if (i < 15)		mask[i] |= pat[i+1];	if (i > 0)		mask[i] |= pat[i-1];        mask[i] |= (mask[i] << 1) | (mask[i] >> 1);	mask[i] = ~(mask[i]);      }    for (i = 0; i < 16; i++, offset += 80)    {	unsigned char m, p, c1, c2, c4, c8;	p = pat[i];	if (invert)	{		p = ~p;		chr[i     ] = p;		chr[16 + i] = p;		chr[32 + i] = p;		chr[48 + i] = p;		continue;	}	c1 = ((unsigned char*)VSHADOW1)[offset];	c2 = ((unsigned char*)VSHADOW2)[offset];	c4 = ((unsigned char*)VSHADOW4)[offset];	c8 = ((unsigned char*)VSHADOW8)[offset];	if (outline)	{		m = mask[i];		c1 &= m;		c2 &= m;		c4 &= m;		c8 &= m;	}		c1 |= p;	c2 |= p;	c4 |= p;	c8 |= p;#if 0	        if (invert)	{		c1 = ~c1;		c2 = ~c2;		c4 = ~c4;		c8 = ~c8;	}#endif	chr[i     ] = c1;	chr[16 + i] = c2;	chr[32 + i] = c4;	chr[48 + i] = c8;    }    offset = 0;    for (i = 1; i < 16; i <<= 1, offset += 16)    {        int j;        MapMask(i);        ptr = mem;        for (j = 0; j < 16; j++, ptr += 80)            *ptr = chr[j + offset];    }    MapMask(15);}#endif /* SUPPORT_GRAPHICS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -