ui/curses: Fix color attribute of monitor for curses

Current text_console_update() writes totally broken color attributes
to console_write_ch(). The format now is writing,

[WRONG]
	bold << 21 | fg << 12 | bg << 8 | char
	fg == 3bits curses color number
	bg == 3bits curses color number

I can't see this format is where come from. Anyway, this doesn't work
at all.

What curses expects is actually (and vga.c is using),

[RIGHT]
	bold << 21 | bg << 11 | fg << 8 | char
	fg == 3bits vga color number
	bg == 3bits vga color number

And curses set COLOR_PAIR() up to match this format, and curses's
chtype. I.e,

	bold | color_pair | char
	color_pair == (bg << 3 | fg)

To fix, this simply uses VGA color number everywhere except curses.c
internal. Then, convert it to above [RIGHT] format to write by
console_write_ch(). And as bonus, this reduces to expose curses define
to other parts (removes COLOR_* from console.c).

[Tested the first line is displayed as white on blue back for monitor
in curses console]

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Message-id: 87r3j95407.fsf@mail.parknet.co.jp
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
master
OGAWA Hirofumi 2015-11-29 22:28:24 +09:00 committed by Gerd Hoffmann
parent a7e00e2536
commit 4083733db5
5 changed files with 76 additions and 62 deletions

View File

@ -233,8 +233,10 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
/* TODO: draw the segments */ /* TODO: draw the segments */
snprintf(buf, 2, "%02hhx\n", s->segments); snprintf(buf, 2, "%02hhx\n", s->segments);
console_write_ch(chardata++, 0x00200100 | buf[0]); console_write_ch(chardata++, ATTR2CHTYPE(buf[0], QEMU_COLOR_BLUE,
console_write_ch(chardata++, 0x00200100 | buf[1]); QEMU_COLOR_BLACK, 1));
console_write_ch(chardata++, ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE,
QEMU_COLOR_BLACK, 1));
dpy_text_update(s->con, 0, 0, 2, 1); dpy_text_update(s->con, 0, 0, 2, 1);
} }

View File

@ -1979,7 +1979,8 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
width = (s->last_width - size) / 2; width = (s->last_width - size) / 2;
dst = chardata + s->last_width + width; dst = chardata + s->last_width + width;
for (i = 0; i < size; i ++) for (i = 0; i < size; i ++)
console_write_ch(dst ++, 0x00200100 | msg_buffer[i]); console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
QEMU_COLOR_BLACK, 1));
dpy_text_update(s->con, 0, 0, s->last_width, height); dpy_text_update(s->con, 0, 0, s->last_width, height);
} }

View File

@ -30,6 +30,21 @@
#define GUI_REFRESH_INTERVAL_DEFAULT 30 #define GUI_REFRESH_INTERVAL_DEFAULT 30
#define GUI_REFRESH_INTERVAL_IDLE 3000 #define GUI_REFRESH_INTERVAL_IDLE 3000
/* Color number is match to standard vga palette */
enum qemu_color_names {
QEMU_COLOR_BLACK = 0,
QEMU_COLOR_BLUE = 1,
QEMU_COLOR_GREEN = 2,
QEMU_COLOR_CYAN = 3,
QEMU_COLOR_RED = 4,
QEMU_COLOR_MAGENTA = 5,
QEMU_COLOR_YELLOW = 6,
QEMU_COLOR_WHITE = 7
};
/* Convert to curses char attributes */
#define ATTR2CHTYPE(c, fg, bg, bold) \
((bold) << 21 | (bg) << 11 | (fg) << 8 | (c))
typedef void QEMUPutKBDEvent(void *opaque, int keycode); typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutLEDEvent(void *opaque, int ledstate); typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state); typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);

View File

@ -376,42 +376,29 @@ static void vga_bitblt(QemuConsole *con,
#include "vgafont.h" #include "vgafont.h"
#ifndef CONFIG_CURSES
enum color_names {
COLOR_BLACK = 0,
COLOR_RED = 1,
COLOR_GREEN = 2,
COLOR_YELLOW = 3,
COLOR_BLUE = 4,
COLOR_MAGENTA = 5,
COLOR_CYAN = 6,
COLOR_WHITE = 7
};
#endif
#define QEMU_RGB(r, g, b) \ #define QEMU_RGB(r, g, b) \
{ .red = r << 8, .green = g << 8, .blue = b << 8, .alpha = 0xffff } { .red = r << 8, .green = g << 8, .blue = b << 8, .alpha = 0xffff }
static const pixman_color_t color_table_rgb[2][8] = { static const pixman_color_t color_table_rgb[2][8] = {
{ /* dark */ { /* dark */
QEMU_RGB(0x00, 0x00, 0x00), /* black */ [QEMU_COLOR_BLACK] = QEMU_RGB(0x00, 0x00, 0x00), /* black */
QEMU_RGB(0xaa, 0x00, 0x00), /* red */ [QEMU_COLOR_BLUE] = QEMU_RGB(0x00, 0x00, 0xaa), /* blue */
QEMU_RGB(0x00, 0xaa, 0x00), /* green */ [QEMU_COLOR_GREEN] = QEMU_RGB(0x00, 0xaa, 0x00), /* green */
QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */ [QEMU_COLOR_CYAN] = QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */
QEMU_RGB(0x00, 0x00, 0xaa), /* blue */ [QEMU_COLOR_RED] = QEMU_RGB(0xaa, 0x00, 0x00), /* red */
QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */ [QEMU_COLOR_MAGENTA] = QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */
QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */ [QEMU_COLOR_YELLOW] = QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */
QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */ [QEMU_COLOR_WHITE] = QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */
}, },
{ /* bright */ { /* bright */
QEMU_RGB(0x00, 0x00, 0x00), /* black */ [QEMU_COLOR_BLACK] = QEMU_RGB(0x00, 0x00, 0x00), /* black */
QEMU_RGB(0xff, 0x00, 0x00), /* red */ [QEMU_COLOR_BLUE] = QEMU_RGB(0x00, 0x00, 0xff), /* blue */
QEMU_RGB(0x00, 0xff, 0x00), /* green */ [QEMU_COLOR_GREEN] = QEMU_RGB(0x00, 0xff, 0x00), /* green */
QEMU_RGB(0xff, 0xff, 0x00), /* yellow */ [QEMU_COLOR_CYAN] = QEMU_RGB(0x00, 0xff, 0xff), /* cyan */
QEMU_RGB(0x00, 0x00, 0xff), /* blue */ [QEMU_COLOR_RED] = QEMU_RGB(0xff, 0x00, 0x00), /* red */
QEMU_RGB(0xff, 0x00, 0xff), /* magenta */ [QEMU_COLOR_MAGENTA] = QEMU_RGB(0xff, 0x00, 0xff), /* magenta */
QEMU_RGB(0x00, 0xff, 0xff), /* cyan */ [QEMU_COLOR_YELLOW] = QEMU_RGB(0xff, 0xff, 0x00), /* yellow */
QEMU_RGB(0xff, 0xff, 0xff), /* white */ [QEMU_COLOR_WHITE] = QEMU_RGB(0xff, 0xff, 0xff), /* white */
} }
}; };
@ -560,7 +547,7 @@ static void console_refresh(QemuConsole *s)
} }
vga_fill_rect(s, 0, 0, surface_width(surface), surface_height(surface), vga_fill_rect(s, 0, 0, surface_width(surface), surface_height(surface),
color_table_rgb[0][COLOR_BLACK]); color_table_rgb[0][QEMU_COLOR_BLACK]);
y1 = s->y_displayed; y1 = s->y_displayed;
for (y = 0; y < s->height; y++) { for (y = 0; y < s->height; y++) {
c = s->cells + y1 * s->width; c = s->cells + y1 * s->width;
@ -698,53 +685,53 @@ static void console_handle_escape(QemuConsole *s)
break; break;
/* set foreground color */ /* set foreground color */
case 30: case 30:
s->t_attrib.fgcol=COLOR_BLACK; s->t_attrib.fgcol = QEMU_COLOR_BLACK;
break; break;
case 31: case 31:
s->t_attrib.fgcol=COLOR_RED; s->t_attrib.fgcol = QEMU_COLOR_RED;
break; break;
case 32: case 32:
s->t_attrib.fgcol=COLOR_GREEN; s->t_attrib.fgcol = QEMU_COLOR_GREEN;
break; break;
case 33: case 33:
s->t_attrib.fgcol=COLOR_YELLOW; s->t_attrib.fgcol = QEMU_COLOR_YELLOW;
break; break;
case 34: case 34:
s->t_attrib.fgcol=COLOR_BLUE; s->t_attrib.fgcol = QEMU_COLOR_BLUE;
break; break;
case 35: case 35:
s->t_attrib.fgcol=COLOR_MAGENTA; s->t_attrib.fgcol = QEMU_COLOR_MAGENTA;
break; break;
case 36: case 36:
s->t_attrib.fgcol=COLOR_CYAN; s->t_attrib.fgcol = QEMU_COLOR_CYAN;
break; break;
case 37: case 37:
s->t_attrib.fgcol=COLOR_WHITE; s->t_attrib.fgcol = QEMU_COLOR_WHITE;
break; break;
/* set background color */ /* set background color */
case 40: case 40:
s->t_attrib.bgcol=COLOR_BLACK; s->t_attrib.bgcol = QEMU_COLOR_BLACK;
break; break;
case 41: case 41:
s->t_attrib.bgcol=COLOR_RED; s->t_attrib.bgcol = QEMU_COLOR_RED;
break; break;
case 42: case 42:
s->t_attrib.bgcol=COLOR_GREEN; s->t_attrib.bgcol = QEMU_COLOR_GREEN;
break; break;
case 43: case 43:
s->t_attrib.bgcol=COLOR_YELLOW; s->t_attrib.bgcol = QEMU_COLOR_YELLOW;
break; break;
case 44: case 44:
s->t_attrib.bgcol=COLOR_BLUE; s->t_attrib.bgcol = QEMU_COLOR_BLUE;
break; break;
case 45: case 45:
s->t_attrib.bgcol=COLOR_MAGENTA; s->t_attrib.bgcol = QEMU_COLOR_MAGENTA;
break; break;
case 46: case 46:
s->t_attrib.bgcol=COLOR_CYAN; s->t_attrib.bgcol = QEMU_COLOR_CYAN;
break; break;
case 47: case 47:
s->t_attrib.bgcol=COLOR_WHITE; s->t_attrib.bgcol = QEMU_COLOR_WHITE;
break; break;
} }
} }
@ -1165,11 +1152,13 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
src = (s->y_base + s->text_y[0]) * s->width; src = (s->y_base + s->text_y[0]) * s->width;
chardata += s->text_y[0] * s->width; chardata += s->text_y[0] * s->width;
for (i = s->text_y[0]; i <= s->text_y[1]; i ++) for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
for (j = 0; j < s->width; j ++, src ++) for (j = 0; j < s->width; j++, src++) {
console_write_ch(chardata ++, s->cells[src].ch | console_write_ch(chardata ++,
(s->cells[src].t_attrib.fgcol << 12) | ATTR2CHTYPE(s->cells[src].ch,
(s->cells[src].t_attrib.bgcol << 8) | s->cells[src].t_attrib.fgcol,
(s->cells[src].t_attrib.bold << 21)); s->cells[src].t_attrib.bgcol,
s->cells[src].t_attrib.bold));
}
dpy_text_update(s, s->text_x[0], s->text_y[0], dpy_text_update(s, s->text_x[0], s->text_y[0],
s->text_x[1] - s->text_x[0], i - s->text_y[0]); s->text_x[1] - s->text_x[0], i - s->text_y[0]);
s->text_x[0] = s->width; s->text_x[0] = s->width;
@ -1306,8 +1295,8 @@ static DisplaySurface *qemu_create_message_surface(int w, int h,
const char *msg) const char *msg)
{ {
DisplaySurface *surface = qemu_create_displaysurface(w, h); DisplaySurface *surface = qemu_create_displaysurface(w, h);
pixman_color_t bg = color_table_rgb[0][COLOR_BLACK]; pixman_color_t bg = color_table_rgb[0][QEMU_COLOR_BLACK];
pixman_color_t fg = color_table_rgb[0][COLOR_WHITE]; pixman_color_t fg = color_table_rgb[0][QEMU_COLOR_WHITE];
pixman_image_t *glyph; pixman_image_t *glyph;
int len, x, y, i; int len, x, y, i;
@ -1941,8 +1930,8 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->t_attrib_default.blink = 0; s->t_attrib_default.blink = 0;
s->t_attrib_default.invers = 0; s->t_attrib_default.invers = 0;
s->t_attrib_default.unvisible = 0; s->t_attrib_default.unvisible = 0;
s->t_attrib_default.fgcol = COLOR_WHITE; s->t_attrib_default.fgcol = QEMU_COLOR_WHITE;
s->t_attrib_default.bgcol = COLOR_BLACK; s->t_attrib_default.bgcol = QEMU_COLOR_BLACK;
/* set current text attributes to default */ /* set current text attributes to default */
s->t_attrib = s->t_attrib_default; s->t_attrib = s->t_attrib_default;
text_console_resize(s); text_console_resize(s);
@ -1951,7 +1940,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
char msg[128]; char msg[128];
int len; int len;
s->t_attrib.bgcol = COLOR_BLUE; s->t_attrib.bgcol = QEMU_COLOR_BLUE;
len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label);
console_puts(chr, (uint8_t*)msg, len); console_puts(chr, (uint8_t*)msg, len);
s->t_attrib = s->t_attrib_default; s->t_attrib = s->t_attrib_default;

View File

@ -333,8 +333,14 @@ static void curses_atexit(void)
static void curses_setup(void) static void curses_setup(void)
{ {
int i, colour_default[8] = { int i, colour_default[8] = {
COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, [QEMU_COLOR_BLACK] = COLOR_BLACK,
COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, [QEMU_COLOR_BLUE] = COLOR_BLUE,
[QEMU_COLOR_GREEN] = COLOR_GREEN,
[QEMU_COLOR_CYAN] = COLOR_CYAN,
[QEMU_COLOR_RED] = COLOR_RED,
[QEMU_COLOR_MAGENTA] = COLOR_MAGENTA,
[QEMU_COLOR_YELLOW] = COLOR_YELLOW,
[QEMU_COLOR_WHITE] = COLOR_WHITE,
}; };
/* input as raw as possible, let everything be interpreted /* input as raw as possible, let everything be interpreted
@ -343,10 +349,11 @@ static void curses_setup(void)
nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE); nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
start_color(); raw(); scrollok(stdscr, FALSE); start_color(); raw(); scrollok(stdscr, FALSE);
/* Make color pair to match color format (3bits bg:3bits fg) */
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
init_pair(i, colour_default[i & 7], colour_default[i >> 3]); init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
} }
/* Set default color for more than 64. (monitor uses 0x74xx for example) */ /* Set default color for more than 64 for safety. */
for (i = 64; i < COLOR_PAIRS; i++) { for (i = 64; i < COLOR_PAIRS; i++) {
init_pair(i, COLOR_WHITE, COLOR_BLACK); init_pair(i, COLOR_WHITE, COLOR_BLACK);
} }