graphics.c revision 3d393ee6c37fa10ac512ed6d36109ad616dc7c1a
/* 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�sar Pereira de Andrade <pcpa@conectiva.com.br>
*/
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2001,2002 Red Hat, Inc.
* Portions copyright (C) 2000 Conectiva, Inc.
*
* 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>
#ifdef OVERLAY_LOGO
#endif /* OVERLAY_LOGO */
int saved_videomode;
unsigned char *font8x16;
int graphics_inited = 0;
#define PALETTE_REDSHIFT 16
#define PALETTE_GREENSHIFT 8
#define PALETTE_COLORMASK 63
#define PALETTE_NCOLORS 16
static char splashimage[64];
static int splash_palette[PALETTE_NCOLORS];
#define HPIXELS 640
#define VPIXELS 480
#define HPIXELSPERBYTE 8
unsigned char VSHADOW1[SCREENBYTES];
unsigned char VSHADOW2[SCREENBYTES];
unsigned char VSHADOW4[SCREENBYTES];
unsigned char VSHADOW8[SCREENBYTES];
/* constants to define the viewable area */
const int x0 = 0;
const int y0 = 0;
const int y1 = 30;
/* text buffer has to be kept around so that we can write things as we
* scroll and the like */
/* why do these have to be kept here? */
/* 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;
/* graphics local functions */
static void graphics_scroll(void);
static int read_image(char *);
#ifdef OVERLAY_LOGO
static void draw_xbmlogo(void);
#endif /* OVERLAY_LOGO */
/* FIXME: where do these really belong? */
{
}
}
/* bit mask register */
}
/* Set the splash image */
void graphics_set_splash(char *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. */
int graphics_init()
{
if (!graphics_inited) {
}
font8x16 = (unsigned char*)graphics_get_font();
/*
* Set VGA palette color 0 to be the system background color, 15 to be the
* system foreground color, and 17 to be the system border color.
*
* If the splashimage was read successfully, program the palette with
* its new colors; if not, set them to the background color.
*/
}
#ifdef OVERLAY_LOGO
draw_xbmlogo();
#endif /* OVERLAY_LOGO */
graphics_inited = 1;
/* make sure that the highlight color is set correctly */
return 1;
}
/* Leave graphics mode */
void graphics_end(void)
{
if (graphics_inited) {
graphics_inited = 0;
}
}
/* Print ch on the screen. Handle any needed scrolling or the like */
void graphics_putchar(int ch) {
ch &= 0xff;
graphics_cursor(0);
if (ch == '\n') {
else
graphics_cursor(1);
return;
} else if (ch == '\r') {
graphics_cursor(1);
return;
}
graphics_cursor(0);
if (graphics_current_color & 0xf0)
graphics_cursor(0);
else
} else {
}
graphics_cursor(1);
}
/* get the current location of the cursor */
int graphics_getxy(void) {
}
void graphics_gotoxy(int x, int y) {
graphics_cursor(0);
graphics_setxy(x, y);
graphics_cursor(1);
}
void graphics_cls(void) {
int i;
unsigned char *mem;
graphics_cursor(0);
for (i = 0; i < ROWBYTES * 30; i++)
text[i] = ' ';
graphics_cursor(1);
BitMask(0xff);
/* plane 1 */
MapMask(1);
/* plane 2 */
MapMask(2);
/* plane 3 */
MapMask(4);
/* plane 4 */
MapMask(8);
MapMask(15);
}
switch (state) {
case COLOR_STATE_STANDARD:
break;
case COLOR_STATE_NORMAL:
break;
case COLOR_STATE_HIGHLIGHT:
break;
default:
break;
}
}
}
int graphics_setcursor (int on) {
/* FIXME: we don't have a cursor in graphics */
return 1;
}
#ifdef OVERLAY_LOGO
static void draw_xbmlogo(void)
{
unsigned char mask;
/*
* Place the logo such that the right hand side will be four pixels from
* the right hand edge of the screen and the bottom will be two pixels
* from the bottom edge.
*/
/*
* If a bit is clear in the bitmap, draw it onto the
* framebuffer in the default foreground color.
*/
/* system default foreground color */
}
}
}
}
#endif /* OVERLAY_LOGO */
/*
* Read in the splashscreen image and set the palette up appropriately.
*
* Format of splashscreen is an XPM (can be gzipped) with up to 15 colors and
* is assumed to be of the proper screen dimensions.
*/
static int read_image(char *s)
{
if (!grub_open(s))
return 0;
/* read XPM header - must match memcmp string PRECISELY. */
errnum = ERR_NOTXPM;
grub_close();
return 0;
}
/* skip characters until we reach an initial '"' */
while (grub_read(&c, 1)) {
if (c == '"')
break;
}
/* skip whitespace */
;
/*
* Format here should be four integers:
*
* Width Height NumberOfColors CharactersPerPixel
*/
i = 0;
width = c - '0';
while (grub_read(&c, 1)) {
if (c >= '0' && c <= '9')
else
break;
}
/* skip whitespace to advance to next digit */
;
height = c - '0';
while (grub_read(&c, 1)) {
if (c >= '0' && c <= '9')
else
break;
}
/* skip whitespace to advance to next digit */
colors = c - '0';
while (grub_read(&c, 1)) {
if (c >= '0' && c <= '9')
else
break;
}
/* eat rest of line - assumes chars per pixel is one */
;
/*
* Parse the XPM palette - the format is:
*
* identifier colorspace #RRGGBB
*
* The identifier is simply a single character; the colorspace identifier
* is skipped as it's assumed to be "c" denoting RGB color.
*
* The six digits after the "#" are assumed to be a six digit RGB color
* identifier as defined in X11's rgb.txt file.
*/
len = 0;
;
base = c;
}
/*
* The RGB hex digits should be six characters in length.
*
* If the color field contains anything other than six
* characters, such as "None" to denote a transparent color,
* ignore it.
*/
if (len == 6) {
if (idx > 14) {
grub_close();
return 0;
}
splash_palette[idx++] =
((r & PALETTE_COLORMASK) << PALETTE_REDSHIFT) |
((g & PALETTE_COLORMASK) << PALETTE_GREENSHIFT) |
(b & PALETTE_COLORMASK);
}
}
x = y = len = 0;
/* clear (zero out) all four planes of the framebuffer */
for (i = 0; i < SCREENBYTES; i++)
/* parse the XPM data */
while (y < height) {
/* exit on EOF, otherwise skip characters until an initial '"' */
while (1) {
if (!grub_read(&c, 1)) {
grub_close();
return 0;
}
if (c == '"')
break;
}
/* read characters until we hit an EOF or a terminating '"' */
int pixel = 0;
/*
* Look up the specified pixel color in the palette; the
* pixel will not be drawn if its color cannot be found or
* if no colors were specified in the XPM image itself.
*/
for (i = 1; i <= colors; i++)
if (pal[i] == c) {
pixel = i;
break;
}
/*
* A bit is set in each of the "planes" of the frame buffer to
* denote a pixel drawn in each color of the palette.
*
* The planes are a binary representation of the palette, so a
* pixel in color "1" of the palette would be denoted by setting a
* bit in plane "s1"; a pixel in color "15" of the palette would
* set the same bit in each of the four planes.
*
* Pixels are represented by set bits in a byte, in the order
* left-to-right (e.g. pixel 0 is 0x80, pixel 7 is 1.)
*/
if (pixel != 0) {
if (pixel & 1)
if (pixel & 2)
if (pixel & 4)
if (pixel & 8)
}
/*
* Increment "x"; if we hit pixel HPIXELS, wrap to the start of the
* next horizontal line if we haven't yet reached the bottom of
* the screen.
*/
if (++x >= HPIXELS) {
x = 0;
if (y++ < VPIXELS)
else
break;
}
}
}
grub_close();
return 1;
}
/* Convert a character which is a hex digit to the appropriate integer */
int hex(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 */
}
}
}
/* scroll the screen */
static void graphics_scroll() {
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 */
}
}
/* last line should be blank */
graphics_putchar(' ');
no_scroll = 0;
}
void graphics_cursor(int set) {
return;
if (!set) {
for (i = 0; i < 16; i++) {
if (!invert) {
/* FIXME: if (shade) */
if (1) {
}
}
}
}
}
else {
}
}
}
else {
MapMask(15);
}
return;
}
offset = 0;
int j;
MapMask(i);
}
MapMask(15);
}
#endif /* SUPPORT_GRAPHICS */