Preliminary color console support.
diff --git a/console/interface.c b/console/interface.c
index 57db6e9..1cfb1a9 100644
--- a/console/interface.c
+++ b/console/interface.c
@@ -150,6 +150,14 @@
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 @@
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 593361f..868127d 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 @@
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 @@
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_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 @@
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 @@
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 949fe65..da96d6f 100644
--- a/include/console.h
+++ b/include/console.h
@@ -35,8 +35,12 @@
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 @@
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_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_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 23d3763..d4464d3 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 */
{