diff --git a/console/interface.c b/console/interface.c index 57db6e934d7..1cfb1a9e027 100644 --- a/console/interface.c +++ b/console/interface.c @@ -150,6 +150,14 @@ void CONSOLE_Refresh() driver.refresh(); } +int CONSOLE_AllocColor(int color) +{ + if (driver.allocColor) + return driver.allocColor(color); + else + return 0; +} + /* This function is only at the CONSOLE level. */ /* Admittably, calling the variable norefresh might be a bit dumb...*/ void CONSOLE_SetRefresh(int setting) @@ -201,6 +209,12 @@ void CONSOLE_NotifyResizeScreen(int x, int y) driver.notifyResizeScreen(x, y); } +void CONSOLE_SetBackgroundColor(int fg, int bg) +{ + if (driver.setBackgroundColor) + driver.setBackgroundColor(fg, bg); +} + void CONSOLE_WriteRawString(char *str) { /* This is a special function that is only for internal use and diff --git a/console/ncurses.c b/console/ncurses.c index 593361f15f3..868127d06ae 100644 --- a/console/ncurses.c +++ b/console/ncurses.c @@ -31,6 +31,8 @@ SCREEN *ncurses_screen; +static int get_color_pair(int fg_color, int bg_color); + void NCURSES_Start() { /* This should be the root driver so we can ignore anything @@ -45,6 +47,8 @@ void NCURSES_Start() driver.getCursorPosition = NCURSES_GetCursorPosition; driver.getCharacterAtCursor = NCURSES_GetCharacterAtCursor; driver.clearScreen = NCURSES_ClearScreen; + driver.allocColor = NCURSES_AllocColor; + driver.setBackgroundColor = NCURSES_SetBackgroundColor; #ifdef HAVE_RESIZETERM driver.notifyResizeScreen = NCURSES_NotifyResizeScreen; #endif @@ -60,10 +64,11 @@ void NCURSES_Init() ncurses_screen = newterm("xterm", driver.console_out, driver.console_in); set_term(ncurses_screen); - cbreak(); + start_color(); + raw(); noecho(); nonl(); - intrflush(stdscr, FALSE); +/* intrflush(stdscr, FALSE); */ keypad(stdscr, TRUE); nodelay(stdscr, TRUE); } @@ -71,9 +76,17 @@ void NCURSES_Init() void NCURSES_Write(char output, int fg, int bg, int attribute) { char row, col; + int pair; + + if (!fg) + fg = COLOR_WHITE; /* Default */ - /* We can discard all extended information. */ - if (waddch(stdscr, output) == ERR) + if (!bg) + bg = COLOR_BLACK; /* Default */ + + pair = get_color_pair(fg, bg); + + if (waddch(stdscr, output | COLOR_PAIR(pair)) == ERR) { NCURSES_GetCursorPosition(&row, &col); FIXME(console, "NCURSES: waddch() failed at %d, %d.\n", row, col); @@ -150,6 +163,36 @@ void NCURSES_ClearScreen() werase(stdscr); } +int NCURSES_AllocColor(int color) +{ + /* Currently support only internal colors */ + switch (color) + { + case WINE_BLACK: return COLOR_BLACK; + case WINE_WHITE: return COLOR_WHITE; + case WINE_RED: return COLOR_RED; + case WINE_GREEN: return COLOR_GREEN; + case WINE_YELLOW: return COLOR_YELLOW; + case WINE_BLUE: return COLOR_BLUE; + case WINE_MAGENTA: return COLOR_MAGENTA; + case WINE_CYAN: return COLOR_CYAN; + } + + FIXME(console, "Unable to allocate color %d\n", color); + + /* Don't allocate a color... yet */ + return 0; +} + +void NCURSES_SetBackgroundColor(int fg, int bg) +{ + int pair; + + pair = get_color_pair(fg, bg); + + bkgdset(COLOR_PAIR(pair)); +} + #ifdef HAVE_RESIZETERM void NCURSES_NotifyResizeScreen(int x, int y) @@ -161,6 +204,37 @@ void NCURSES_NotifyResizeScreen(int x, int y) resizeterm(y, x); } -#endif +#endif /* HAVE_RESIZETERM */ + +static int get_color_pair(int fg_color, int bg_color) +{ + /* ncurses internally uses "color pairs" in addition to the "pallet" */ + /* This isn't the best way to do this. Or even close */ + + static int current = 0; + static int fg[255]; /* 16 x 16 is enough */ + static int bg[255]; + int x; + + /* The first pair is hardwired into ncurses */ + fg[0] = COLOR_WHITE; + bg[0] = COLOR_BLACK; + + for (x = 0; x <= current; x++) + { + if ((fg_color == fg[x]) && (bg_color == bg[x])) + { + TRACE(console, "Color pair: already allocated\n"); + return x; + } + } + + /* Need to allocate new color */ + current++; + fg[current] = fg_color; + bg[current] = bg_color; + TRACE(console, "Color pair: allocated.\n"); + return init_pair(current, fg_color, bg_color); +} #endif /* WINE_NCURSES */ diff --git a/include/console.h b/include/console.h index 949fe65c364..da96d6fabb7 100644 --- a/include/console.h +++ b/include/console.h @@ -35,8 +35,12 @@ typedef struct CONSOLE_DRIVER void (*getCharacterAtCursor)(char *, int *, int *, int *); void (*clearScreen)(); + /* Color-control functions */ + int (*allocColor)(int color); + void (*setBackgroundColor)(int fg, int bg); + /* Keyboard Functions */ - int (*checkForKeystroke)(char *, char *); + int (*checkForKeystroke)(char *, char *); void (*getKeystroke)(char *, char *); /* Windowing Functions */ @@ -83,6 +87,8 @@ char CONSOLE_GetCharacter(); void CONSOLE_ResizeScreen(); void CONSOLE_NotifyResizeScreen(); void CONSOLE_WriteRawString(char *); +int CONSOLE_AllocColor(int); +void CONSOLE_SetBackgroundColor(int fg, int bg); /* Generic Defines */ void GENERIC_Start(); @@ -111,6 +117,8 @@ void NCURSES_GetCharacterAtCursor(char *, int *, int *, int *); void NCURSES_Refresh(); void NCURSES_ClearScreen(); void NCURSES_NotifyResizeScreen(int x, int y); +int NCURSES_AllocColor(int); +void NCURSES_SetBackgroundColor(int fg, int bg); #endif /* WINE_NCURSES */ @@ -120,4 +128,23 @@ void XTERM_Close(); void XTERM_Init(); void XTERM_ResizeScreen(int x, int y); +/* Color defines */ +/* These will eventually be hex triples for dynamic allocation */ +#define WINE_BLACK 1 +#define WINE_BLUE 2 +#define WINE_GREEN 3 +#define WINE_CYAN 4 +#define WINE_MAGENTA 5 +#define WINE_BROWN 6 +#define WINE_RED 7 +#define WINE_LIGHT_GRAY 8 +#define WINE_DARK_GRAY 9 +#define WINE_LIGHT_BLUE 10 +#define WINE_LIGHT_GREEN 11 +#define WINE_LIGHT_RED 12 +#define WINE_LIGHT_MAGENTA 13 +#define WINE_LIGHT_CYAN 14 +#define WINE_YELLOW 15 +#define WINE_WHITE 16 + #endif /* CONSOLE_H */ diff --git a/msdos/int10.c b/msdos/int10.c index 23d3763e185..d4464d36768 100644 --- a/msdos/int10.c +++ b/msdos/int10.c @@ -9,14 +9,15 @@ #include "debug.h" #include "console.h" -static int conv_text_mode_attribute_attribute(char attribute); -static int conv_text_mode_attribute_fg_color(char attribute); -static int conv_text_mode_attribute_bg_color(char attribute); +static void conv_text_mode_attributes(char attribute, int *fg, int *bg, + int *wattribute); static void write_char_attribute_at_cursor(char output, char page_num, char attribute, short times); static void scroll_window(int direction, char lines, char row1, char col1, char row2, char col2, char attribute); +static int color_pallet[16]; + #define SCROLL_UP 1 #define SCROLL_DOWN 2 @@ -48,23 +49,53 @@ static void scroll_window(int direction, char lines, char row1, void WINAPI INT_Int10Handler( CONTEXT *context ) { + static int registered_colors = FALSE; + static int video_mode = 7; + static int video_columns = 80; + + if (!registered_colors) + { + /* Colors: + 0000b black 1000b dark gray + 0001b blue 1001b light blue + 0010b green 1010b light green + 0011b cyan 1011b light cyan + 0100b red 1100b light red + 0101b magenta 1101b light magenta + 0110b brown 1110b yellow + 0111b light gray 1111b white + */ + + color_pallet[0] = CONSOLE_AllocColor(WINE_BLACK); + color_pallet[1] = CONSOLE_AllocColor(WINE_BLUE); + color_pallet[2] = CONSOLE_AllocColor(WINE_GREEN); + color_pallet[3] = CONSOLE_AllocColor(WINE_CYAN); + color_pallet[4] = CONSOLE_AllocColor(WINE_RED); + color_pallet[5] = CONSOLE_AllocColor(WINE_MAGENTA); + color_pallet[6] = CONSOLE_AllocColor(WINE_BROWN); + color_pallet[7] = CONSOLE_AllocColor(WINE_LIGHT_GRAY); + color_pallet[8] = CONSOLE_AllocColor(WINE_DARK_GRAY); + color_pallet[9] = CONSOLE_AllocColor(WINE_LIGHT_BLUE); + color_pallet[10] = CONSOLE_AllocColor(WINE_LIGHT_GREEN); + color_pallet[11] = CONSOLE_AllocColor(WINE_LIGHT_CYAN); + color_pallet[12] = CONSOLE_AllocColor(WINE_LIGHT_RED); + color_pallet[13] = CONSOLE_AllocColor(WINE_LIGHT_MAGENTA); + color_pallet[14] = CONSOLE_AllocColor(WINE_YELLOW); + color_pallet[15] = CONSOLE_AllocColor(WINE_WHITE); + } + switch(AH_reg(context)) { case 0x00: /* SET VIDEO MODE */ - /* Text Modes: (can xterm or similar change text rows/cols?) */ - /* Answer: Yes. We can add that later. */ - /* Er, maybe. I thought resizeterm() did it, I was wrong. */ + /* Text Modes: */ /* (mode) (text rows/cols) 0x00 - 40x25 0x01 - 40x25 0x02 - 80x25 - 0x03 - 80x25 or 80x43 or 80x50 + 0x03 - 80x25 or 80x43 or 80x50 (assume 80x25) 0x07 - 80x25 */ - /* We may or may not want to do a refresh between the resize and - the clear... */ - switch (AL_reg(context)) { case 0x00: /* 40x25 */ case 0x01: @@ -73,6 +104,8 @@ void WINAPI INT_Int10Handler( CONTEXT *context ) AL_reg(context)); CONSOLE_ResizeScreen(40, 25); CONSOLE_ClearScreen(); + video_mode = AL_reg(context); + video_columns = 40; break; case 0x02: case 0x03: @@ -82,10 +115,13 @@ void WINAPI INT_Int10Handler( CONTEXT *context ) AL_reg(context)); CONSOLE_ResizeScreen(80, 25); CONSOLE_ClearScreen(); + video_mode = AL_reg(context); + video_columns = 80; break; case 0x13: TRACE(int10, "Setting VGA 320x200 256-color mode\n"); VGA_SetMode(320,200,8); + video_mode = AL_reg(context); break; default: FIXME(int10, "Set Video Mode (0x%x) - Not Supported\n", @@ -184,7 +220,8 @@ void WINAPI INT_Int10Handler( CONTEXT *context ) case 0x0b: switch BH_reg(context) { case 0x00: /* SET BACKGROUND/BORDER COLOR */ - FIXME(int10, "Set Background/Border Color - Not Supported\n"); + /* In text modes, this sets only the border */ + TRACE(int10, "Set Background/Border Color - Ignored\n"); break; case 0x01: /* SET PALETTE */ FIXME(int10, "Set Palette - Not Supported\n"); @@ -214,8 +251,8 @@ void WINAPI INT_Int10Handler( CONTEXT *context ) case 0x0f: /* GET CURRENT VIDEO MODE */ TRACE(int10, "Get Current Video Mode\n"); /* Note: This should not be a constant value. */ - AL_reg(context) = 0x07; /* 80x25 text mode */ - AH_reg(context) = 80; /* 80 columns */ + AL_reg(context) = video_mode; + AH_reg(context) = video_columns; BH_reg(context) = 0; /* Display page 0 */ break; @@ -421,9 +458,10 @@ static void write_char_attribute_at_cursor(char output, char page_num, return; } - wattribute = conv_text_mode_attribute_attribute(attribute); - fg_color = conv_text_mode_attribute_fg_color(attribute); - bg_color = conv_text_mode_attribute_bg_color(attribute); + conv_text_mode_attributes(attribute, &fg_color, &bg_color, + &wattribute); + + TRACE(int10, "Fore: %d Back: %d\n", fg_color, bg_color); CONSOLE_GetCursorPosition(&x, &y); @@ -436,65 +474,29 @@ static void write_char_attribute_at_cursor(char output, char page_num, CONSOLE_MoveCursor(x, y); } -static int conv_text_mode_attribute_fg_color(char attribute) +static void conv_text_mode_attributes(char attribute, int *fg, int *bg, + int *wattribute) { - /* This is a local function to convert the color values - in text-mode attributes to Wine's scheme */ - + /* This is a local function to convert the text-mode attributes + to Wine's color and attribute scheme */ + /* Foreground Color is stored in bits 3 through 0 */ - - /* Colors: - 0000b black 1000b dark gray - 0001b blue 1001b light blue - 0010b green 1010b light green - 0011b cyan 1011b light cyan - 0100b red 1100b light red - 0101b magenta 1101b light magenta - 0110b brown 1110b yellow - 0111b light gray 1111b white - */ - - /* FIXME - We need color values for those and some generic constants */ - - return 0; /* Bogus, temporary data. */ -} - -static int conv_text_mode_attribute_bg_color(char attribute) -{ - /* This is a local function to convert the color values - in text-mode attributes to Wine's scheme */ - /* Background Color is stored in bits 6 through 4 */ - - /* Colors same as above, but only the left column */ - - /* FIXME - We need color values for those and some generic constants */ - - return 0; /* Bogus, temporary data. */ -} - -static int conv_text_mode_attribute_attribute(char attribute) -{ - /* This is a local function to convert the attribute values - in text-mode attributes to Wine's scheme */ - /* If this has bit 7 set, then we need to blink */ - if (255 && attribute) - { - /* return TEXT_ATTRIBUTE_BLINK; */ - } - - return 0; /* Bogus data */ + *fg = color_pallet[attribute & 15]; + *bg = color_pallet[(attribute & 112) / 16]; + *wattribute = attribute & 128; + } static void scroll_window(int direction, char lines, char row1, char col1, char row2, char col2, char attribute) { - int wattribute, bg_color; + int wattribute, bg_color, fg_color; - wattribute = conv_text_mode_attribute_attribute(attribute); - bg_color = conv_text_mode_attribute_bg_color(attribute); + conv_text_mode_attributes(attribute, &fg_color, &bg_color, + &wattribute); if (!lines) /* Actually, clear the window */ {