From 4030ef13a0826455863b847ebd6b7bf16b708ebd Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 17 Mar 2024 18:25:35 +0200 Subject: [PATCH] Curses: implement the windowcolors option Allow changing the curses windows foreground and background colors, for example: OPTIONS=windowcolor:menu #8000F0/20F080 message grey/blue --- doc/Guidebook.mn | 2 +- doc/Guidebook.tex | 2 +- doc/fixes3-7-0.txt | 1 + include/wincurs.h | 10 +- sys/msdos/Makefile.GCC | 8 +- sys/unix/hints/include/cross-pre2.370 | 2 +- sys/windows/Makefile.mingw32 | 2 +- sys/windows/Makefile.nmake | 2 +- sys/windows/vs/PDCurses/PDCurses.vcxproj | 8 +- .../vs/PDCursesGui/pdcursesgui.vcxproj | 8 +- win/curses/cursdial.c | 23 +++- win/curses/cursinit.c | 32 +++++ win/curses/cursinit.h | 2 + win/curses/cursmain.c | 6 +- win/curses/cursmesg.c | 8 ++ win/curses/curswins.c | 124 +++++++++++++++++- win/curses/curswins.h | 6 +- 17 files changed, 214 insertions(+), 32 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 400b0b47e..d392be936 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -4996,7 +4996,7 @@ plus widen each inventory line by two columns. .lp windowcolors If NetHack can, it should display windows with the specified foreground/background colors. -Windows GUI only. +Windows GUI and curses windowport only. The format is .si .lp "OPTION=windowcolors:wintype foreground/background" diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 695893306..07cec032c 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -5513,7 +5513,7 @@ plus widen each inventory line by two columns. \item[\ib{windowcolors}] If {\it NetHack\/} can, it should display windows with the specified foreground/background colors. -Windows GUI only. +Windows GUI and curses windowport only. The format is \begin{verbatim} OPTION=windowcolors:wintype foreground/background diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index fe279631c..9aeacef1a 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2539,6 +2539,7 @@ curses: if panictrace is triggered, reset the terminal before giving backtrace curses: if a message is marked urgent, override message suppression initiated by user having typed ESC at previous More>> prompt curses: implement a dialog for the windowborders option +curses: implement the windowcolors option Qt: the "paper doll" inventory subset can be controlled via the "Qt Settings" dialog box ("Preferences..." on macOS) Qt: draw a border around each tile in the paper doll inventory; when BUC is diff --git a/include/wincurs.h b/include/wincurs.h index ee7c5c5a2..d9042ed2d 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -32,7 +32,9 @@ extern WINDOW *activemenu; /* curses window for menu requesting a #define STATUS_WIN 2 #define MAP_WIN 3 #define INV_WIN 4 -#define NHWIN_MAX 5 +#define TEXT_WIN 5 +#define MENU_WIN 6 +#define NHWIN_MAX 7 #if !defined(__APPLE__) || !defined(NCURSES_VERSION) # define USE_DARKGRAY /* Allow "bright" black; delete if not visible */ #endif /* !__APPLE__ && !PDCURSES */ @@ -117,7 +119,9 @@ extern win_request_info *curses_ctrl_nhwindow(winid, int, win_request_info *); /* curswins.c */ -extern WINDOW *curses_create_window(int width, int height, orient orientation); +extern WINDOW *curses_create_window(int wid, int width, int height, orient orientation); +extern void curses_set_wid_colors(int wid, WINDOW *win); +extern void curses_parse_wid_colors(int wid, char *fg, char *bg); extern void curses_destroy_win(WINDOW *win); extern WINDOW *curses_get_nhwin(winid wid); extern void curses_add_nhwin(winid wid, int height, int width, int y, @@ -211,6 +215,8 @@ extern void curs_add_invt(int, char, attr_t, int, const char *); /* cursinit.c */ extern void curses_create_main_windows(void); +extern int curses_init_rgb(int r, int g, int b); +extern int curses_init_pair(int fg, int bg); extern void curses_init_nhcolors(void); extern void curses_choose_character(void); extern int curses_character_dialog(const char **choices, const char *prompt); diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index eec43acdd..81283f7bc 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -446,7 +446,7 @@ endif #========================================== # ifeq "$(ADD_CURSES)" "Y" -CURSESDEF=-D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" +CURSESDEF=-D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" -DPDC_RGB ifdef WANT_DOSVGA CURSESDEF += -DCURSES_UNICODE -DPDC_WIDE endif @@ -538,13 +538,13 @@ $(OBJ)/%.o : $(WCURSES)/%.c #========================================== $(OBJ)/%.o : $(PDCURSES_TOP)/%.c - $(CC) $(cflags) -o$@ $< + $(CC) $(cflags) -o$@ $< $(OBJ)/%.o : $(PDCSRC)/%.c - $(CC) $(cflags) -o$@ $< + $(CC) $(cflags) -o$@ $< $(OBJ)/%.o : $(PDCDOS)/%.c - $(CC) $(cflags) -o$@ $< + $(CC) $(cflags) -o$@ $< #========================================== # Rules for LUA files diff --git a/sys/unix/hints/include/cross-pre2.370 b/sys/unix/hints/include/cross-pre2.370 index 2b1c9ef91..55294e286 100644 --- a/sys/unix/hints/include/cross-pre2.370 +++ b/sys/unix/hints/include/cross-pre2.370 @@ -50,7 +50,7 @@ ifdef WANT_DOSVGA PDCPORT = $(PDCTOP)/dosvga PDCURSESDEF= -I$(PDCTOP) -I$(PDCPORT) \ -D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" \ - -D"PDC_WIDE" -D"CURSES_UNICODE" + -D"PDC_WIDE" -D"PDC_RGB" -D"CURSES_UNICODE" else PDCPORT = $(PDCTOP)/dos PDCURSESDEF= -I$(PDCTOP) -I$(PDCPORT) \ diff --git a/sys/windows/Makefile.mingw32 b/sys/windows/Makefile.mingw32 index b9227f640..73519fa1a 100644 --- a/sys/windows/Makefile.mingw32 +++ b/sys/windows/Makefile.mingw32 @@ -118,7 +118,7 @@ GIT_AVAILABLE=Y endif PDCURSES=pdcursesmod -PDCURSESFLAGS = -DPDC_WIDE +PDCURSESFLAGS = -DPDC_WIDE -DPDC_RGB # #============================================================================== diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index 2173d95db..0e5b9e0db 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -602,7 +602,7 @@ WINDHDR = $(MSWSYS)\win10.h $(MSWSYS)\winos.h $(MSWSYS)\win32api.h # !IF "$(ADD_CURSES)" == "Y" -PDCURSESFLAGS = -DPDC_WIDE +PDCURSESFLAGS = -DPDC_WIDE -DPDC_RGB CURSESOBJ= $(OTTY)cursdial.o $(OTTY)cursinit.o $(OTTY)cursinvt.o \ $(OTTY)cursmain.o $(OTTY)cursmesg.o $(OTTY)cursmisc.o \ $(OTTY)cursstat.o $(OTTY)curswins.o diff --git a/sys/windows/vs/PDCurses/PDCurses.vcxproj b/sys/windows/vs/PDCurses/PDCurses.vcxproj index bf2ca014c..8b5f7901c 100644 --- a/sys/windows/vs/PDCurses/PDCurses.vcxproj +++ b/sys/windows/vs/PDCurses/PDCurses.vcxproj @@ -90,14 +90,14 @@ Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions) MultiThreadedDebug Disabled - _DEBUG;_LIB;%(PreprocessorDefinitions) + _DEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions) @@ -105,7 +105,7 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions) true @@ -117,7 +117,7 @@ MaxSpeed true true - NDEBUG;_LIB;%(PreprocessorDefinitions) + NDEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions) true diff --git a/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj b/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj index 9f661e18c..e28db5b80 100644 --- a/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj +++ b/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj @@ -84,14 +84,14 @@ Disabled - WIN32;_DEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions) MultiThreadedDebug Disabled - _DEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions) + _DEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions) @@ -99,7 +99,7 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions) true @@ -111,7 +111,7 @@ MaxSpeed true true - NDEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions) + NDEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions) true diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index e2ca1f265..f93707463 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -6,6 +6,9 @@ #include "curses.h" #include "hack.h" #include "wincurs.h" +#include "cursinit.h" +#include "curswins.h" +#include "cursmisc.h" #include "cursdial.h" #include "func_tab.h" #include @@ -151,8 +154,9 @@ curses_line_input_dialog( free(tmpstr); } - bwin = curses_create_window(prompt_width, height, + bwin = curses_create_window(TEXT_WIN, prompt_width, height, iflags.window_inited ? UP : CENTER); + curses_set_wid_colors(TEXT_WIN, bwin); wrefresh(bwin); getbegyx(bwin, winy, winx); askwin = newwin(height, prompt_width, winy + 1, winx + 1); @@ -277,7 +281,7 @@ curses_character_input_dialog( } if (iflags.wc_popup_dialog /*|| curses_stupid_hack*/) { - askwin = curses_create_window(prompt_width, prompt_height, UP); + askwin = curses_create_window(TEXT_WIN, prompt_width, prompt_height, UP); activemenu = askwin; for (count = 0; count < prompt_height; count++) { @@ -286,6 +290,7 @@ curses_character_input_dialog( free(linestr); } + curses_set_wid_colors(TEXT_WIN, askwin); wrefresh(askwin); } else { /* TODO: add SUPPRESS_HISTORY flag, then after getting a response, @@ -392,7 +397,8 @@ curses_ext_cmd(void) if (iflags.wc_popup_dialog) { /* Prompt in popup window */ int x0, y0, w, h; /* bounding coords of popup */ - extwin2 = curses_create_window(25, 1, UP); + extwin2 = curses_create_window(TEXT_WIN, 25, 1, UP); + curses_set_wid_colors(TEXT_WIN, extwin2); wrefresh(extwin2); /* create window inside window to prevent overwriting of border */ getbegyx(extwin2, y0, x0); @@ -784,13 +790,14 @@ curses_display_nhmenu( /* Display pre and post-game menus centered */ if ((gm.moves <= 1 && !gi.invent) || gp.program_state.gameover) { - win = curses_create_window(current_menu->width, + win = curses_create_window(wid, current_menu->width, current_menu->height, CENTER); } else { /* Display during-game menus on the right out of the way */ - win = curses_create_window(current_menu->width, + win = curses_create_window(wid, current_menu->width, current_menu->height, RIGHT); } + curses_set_wid_colors(wid, win); num_chosen = menu_get_selections(win, current_menu, how); curses_destroy_win(win); @@ -1337,9 +1344,11 @@ menu_display_page( curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF); } } - curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON); + if (curses_win_clr_inited(MENU_WIN) < 1) + curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON); box(win, 0, 0); - curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF); + if (curses_win_clr_inited(MENU_WIN) < 1) + curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF); wrefresh(win); } diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 196a56c18..de1811e7f 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -297,6 +297,36 @@ curses_create_main_windows(void) } } +static int pairs_used = 0; +static int colors_used = 0; + +/* create a new color */ +int +curses_init_rgb(int r, int g, int b) +{ + if (!can_change_color()) + return 0; + + if (colors_used < COLORS - 1) { + colors_used++; + init_color(colors_used, r*4, g*4, b*4); + return colors_used; + } + return 0; +} + +/* create a new foreground/background combination */ +int +curses_init_pair(int fg, int bg) +{ + if (pairs_used < COLOR_PAIRS - 1) { + pairs_used++; + init_pair(pairs_used, fg, bg); + return pairs_used; + } + return 0; +} + /* Initialize curses colors to colors used by NetHack */ void curses_init_nhcolors(void) @@ -335,6 +365,8 @@ curses_init_nhcolors(void) } } #endif + colors_used = maxc; + pairs_used = (maxc * 8) + 16 + 1; } #if 0 /* curses_choose_character + curses_character_dialog no longer used */ diff --git a/win/curses/cursinit.h b/win/curses/cursinit.h index ba3b5a7ee..fbc9abe08 100644 --- a/win/curses/cursinit.h +++ b/win/curses/cursinit.h @@ -9,6 +9,8 @@ /* Global declarations */ void curses_create_main_windows(void); +int curses_init_rgb(int r, int g, int b); +int curses_init_pair(int fg, int bg); void curses_init_nhcolors(void); void curses_choose_character(void); int curses_character_dialog(const char **choices, const char *prompt); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 385b1bca0..f2bd12af2 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -54,7 +54,7 @@ static char *dummy_get_color_string(void); struct window_procs curses_procs = { WPID(curses), (WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_INVERSE - | WC_HILITE_PET + | WC_HILITE_PET | WC_WINDOWCOLORS #ifdef NCURSES_MOUSE_VERSION /* (this macro name works for PDCURSES too) */ | WC_MOUSE_SUPPORT #endif @@ -426,6 +426,10 @@ curses_create_nhwindow(int type) { winid wid = curses_get_wid(type); + if (curses_is_menu(wid)) + curses_parse_wid_colors(MENU_WIN, iflags.wc_foregrnd_menu, iflags.wc_backgrnd_menu); + else if (curses_is_text(wid)) + curses_parse_wid_colors(TEXT_WIN, iflags.wc_foregrnd_text, iflags.wc_backgrnd_text); if (curses_is_menu(wid) || curses_is_text(wid)) { curses_start_menu(wid, MENU_BEHAVE_STANDARD); curses_add_wid(wid); diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 3cf16af09..a9649bc33 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -7,6 +7,7 @@ #include "hack.h" #include "wincurs.h" #include "cursmesg.h" +#include "curswins.h" #include /* defined in sys//tty.c or cursmain.c as last resort; @@ -106,6 +107,7 @@ curses_message_win_puts(const char *message, boolean recursed) return; /* user has typed ESC to avoid seeing remaining messages. */ } + curses_set_wid_colors(MESSAGE_WIN, NULL); curses_get_window_size(MESSAGE_WIN, &height, &width); border_space = (border ? 1 : 0); if (mx < border_space) @@ -322,6 +324,7 @@ curses_block( } moreattr = !iflags.wc2_guicolor ? (int) A_REVERSE : NONE; curses_toggle_color_attr(win, MORECOLOR, moreattr, ON); + curses_set_wid_colors(MESSAGE_WIN, NULL); if (blink) { wattron(win, A_BLINK); mvwprintw(win, my, mx, ">"), mx += 1; @@ -331,6 +334,7 @@ curses_block( mvwprintw(win, my, mx, ">>"), mx += 2; } curses_toggle_color_attr(win, MORECOLOR, moreattr, OFF); + curses_set_wid_colors(MESSAGE_WIN, NULL); wrefresh(win); /* cancel mesg suppression; all messages will have had chance to be read */ @@ -379,6 +383,7 @@ curses_clear_unhighlight_message_window(void) WINDOW *win = curses_get_nhwin(MESSAGE_WIN); turn_lines = 0; + curses_set_wid_colors(MESSAGE_WIN, NULL); curses_get_window_size(MESSAGE_WIN, &mh, &mw); if (mh == 1) { @@ -413,6 +418,7 @@ curses_last_messages(void) int border = curses_window_has_border(MESSAGE_WIN) ? 1 : 0; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); + curses_set_wid_colors(MESSAGE_WIN, NULL); curses_get_window_size(MESSAGE_WIN, &height, &width); werase(win); mx = my = border; @@ -605,6 +611,7 @@ curses_count_window(const char *count_text) but not for dolook's autodescribe when it refers to a named monster */ if (!countwin) countwin = newwin(1, messagew, winy, winx); + curses_set_wid_colors(MESSAGE_WIN, NULL); werase(countwin); mvwprintw(countwin, 0, 0, "%s", count_text); @@ -880,6 +887,7 @@ directional_scroll(winid wid, int nlines) boolean border = curses_window_has_border(wid); WINDOW *win = curses_get_nhwin(wid); + curses_set_wid_colors(wid, NULL); curses_get_window_size(wid, &wh, &ww); if (wh == 1) { curses_clear_nhwin(wid); diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 4d2504611..b56a2444f 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -9,7 +9,10 @@ #include "curses.h" #include "hack.h" #include "wincurs.h" +#include "cursinit.h" +#include "cursmisc.h" #include "curswins.h" +#include "cursstat.h" /* Window handling for curses interface */ @@ -23,6 +26,9 @@ typedef struct nhw { int x; /* start of window on terminal (left) */ int y; /* start of window on terminal (top) */ int orientation; /* Placement of window relative to map */ + boolean clr_inited; /* fg/bg/colorpair inited? */ + int fg, bg; /* foreground, background color index */ + int colorpair; /* color pair of fg, bg */ boolean border; /* Whether window has a visible border */ } nethack_window; @@ -52,7 +58,7 @@ static void clear_map(void); /* Create a window with the specified size and orientation */ WINDOW * -curses_create_window(int width, int height, orient orientation) +curses_create_window(int wid, int width, int height, orient orientation) { int mapx = 0, mapy = 0, maph = 0, mapw = 0; int startx = 0; @@ -142,12 +148,48 @@ curses_create_window(int width, int height, orient orientation) } win = newwin(height, width, starty, startx); - curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON); + + if (curses_is_text(wid)) + wid = TEXT_WIN; + else if (curses_is_menu(wid)) + wid = MENU_WIN; + + if (nhwins[wid].clr_inited < 1) + curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON); box(win, 0, 0); - curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF); + if (nhwins[wid].clr_inited < 1) + curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF); return win; } +int +curses_win_clr_inited(int wid) +{ + if (curses_is_text(wid)) { + wid = TEXT_WIN; + } else if (curses_is_menu(wid)) { + wid = MENU_WIN; + } + return nhwins[wid].clr_inited; +} + +void +curses_set_wid_colors(int wid, WINDOW *win) +{ + if (wid == TEXT_WIN || curses_is_text(wid)) { + wid = TEXT_WIN; + if (!nhwins[wid].clr_inited) + curses_parse_wid_colors(wid, iflags.wc_foregrnd_text, iflags.wc_backgrnd_text); + } else if (wid == MENU_WIN || curses_is_menu(wid)) { + wid = MENU_WIN; + if (!nhwins[wid].clr_inited) + curses_parse_wid_colors(wid, iflags.wc_foregrnd_menu, iflags.wc_backgrnd_menu); + } + /* FIXME: colors and nhwins[] entry for perm invent window */ + if (nhwins[wid].clr_inited > 0) { + wbkgd(win ? win : nhwins[wid].curwin, COLOR_PAIR(nhwins[wid].colorpair)); + } +} /* Erase and delete curses window, and refresh standard windows */ @@ -183,6 +225,7 @@ curses_refresh_nethack_windows(void) refresh(); } else { if (status_window != NULL) { + curses_set_wid_colors(STATUS_WIN, NULL); touchwin(status_window); wnoutrefresh(status_window); } @@ -191,6 +234,7 @@ curses_refresh_nethack_windows(void) wnoutrefresh(map_window); } if (message_window != NULL) { + curses_set_wid_colors(MESSAGE_WIN, NULL); touchwin(message_window); wnoutrefresh(message_window); } @@ -217,6 +261,67 @@ curses_get_nhwin(winid wid) return nhwins[wid].curwin; } +boolean +parse_hexstr(char *colorbuf, int *red, int *green, int *blue) +{ + int len = colorbuf ? strlen(colorbuf) : 0; + + if (len == 7 && colorbuf[0] == '#') { + char tmpbuf[16]; + + Sprintf(tmpbuf, "0x%c%c", colorbuf[1], colorbuf[2]); + *red = strtol(tmpbuf, NULL, 0); + Sprintf(tmpbuf, "0x%c%c", colorbuf[3], colorbuf[4]); + *green = strtol(tmpbuf, NULL, 0); + Sprintf(tmpbuf, "0x%c%c", colorbuf[5], colorbuf[6]); + *blue = strtol(tmpbuf, NULL, 0); + return TRUE; + } + return FALSE; +} + +void +curses_parse_wid_colors(int wid, char *fg, char *bg) +{ + + if (curses_is_text(wid)) { + wid = TEXT_WIN; + } else if (curses_is_menu(wid)) { + wid = MENU_WIN; + } + + if (nhwins[wid].clr_inited) + return; + + int nh_fg = fg ? match_str2clr(fg, TRUE) : CLR_MAX; + int nh_bg = bg ? match_str2clr(bg, TRUE) : CLR_MAX; + int r, g, b; + + if (nh_fg == CLR_MAX) { + if (fg && parse_hexstr(fg, &r, &g, &b)) { + nh_fg = curses_init_rgb(r, g, b); + } else { + nh_fg = -1; + } + } + if (nh_bg == CLR_MAX) { + if (bg && parse_hexstr(bg, &r, &g, &b)) { + nh_bg = curses_init_rgb(r, g, b); + } else { + nh_bg = -1; + } + } + + nhwins[wid].fg = nh_fg; + nhwins[wid].bg = nh_bg; + if (nh_fg == -1 || nh_bg == -1) { + nhwins[wid].clr_inited = -1; + } else { + nhwins[wid].colorpair = curses_init_pair(nh_fg, nh_bg); + nhwins[wid].clr_inited = 1; + } +} + /* Add curses window pointer and window info to list for given NetHack winid */ @@ -241,6 +346,9 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x, nhwins[wid].x = x; nhwins[wid].y = y; nhwins[wid].orientation = orientation; + nhwins[wid].fg = nhwins[wid].bg = 0; + nhwins[wid].colorpair = -1; + nhwins[wid].clr_inited = 0; if (border) { real_width += 2; /* leave room for bounding box */ @@ -248,13 +356,18 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x, } win = newwin(real_height, real_width, y, x); + nhwins[wid].curwin = win; switch (wid) { case MESSAGE_WIN: messagewin = win; + curses_parse_wid_colors(wid, iflags.wc_foregrnd_message, iflags.wc_backgrnd_message); + curses_set_wid_colors(wid, NULL); break; case STATUS_WIN: statuswin = win; + curses_parse_wid_colors(wid, iflags.wc_foregrnd_status, iflags.wc_backgrnd_status); + curses_set_wid_colors(wid, NULL); break; case MAP_WIN: mapwin = win; @@ -266,7 +379,6 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x, box(win, 0, 0); } - nhwins[wid].curwin = win; } @@ -301,6 +413,7 @@ curses_add_wid(winid wid) void curses_refresh_nhwin(winid wid) { + curses_set_wid_colors(wid, NULL); wnoutrefresh(curses_get_nhwin(wid)); doupdate(); } @@ -523,6 +636,7 @@ curses_puts(winid wid, int attr, const char *text) } #endif + curses_set_wid_colors(wid, NULL); if (curses_is_menu(wid) || curses_is_text(wid)) { if (!curses_menu_exists(wid)) { impossible( @@ -553,6 +667,7 @@ curses_clear_nhwin(winid wid) clear_map(); } + curses_set_wid_colors(wid, NULL); werase(win); if (border) { @@ -568,6 +683,7 @@ curses_alert_win_border(winid wid, boolean onoff) if (!win || !curses_window_has_border(wid)) return; + curses_set_wid_colors(wid, NULL); if (onoff) curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON); box(win, 0, 0); diff --git a/win/curses/curswins.h b/win/curses/curswins.h index 589e81bb0..5842f52ed 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -9,11 +9,15 @@ /* Global declarations */ -WINDOW *curses_create_window(int width, int height, orient orientation); +WINDOW *curses_create_window(int wid, int width, int height, orient orientation); +int curses_win_clr_inited(int wid); +void curses_set_wid_colors(int wid, WINDOW *win); void curses_destroy_win(WINDOW * win); void curses_refresh_nethack_windows(void); WINDOW *curses_get_nhwin(winid wid); +void curses_parse_wid_colors(int wid, char *fg, char *bg); +boolean parse_hexstr(char *colorbuf, int *red, int *green, int *blue); void curses_add_nhwin(winid wid, int height, int width, int y, int x, orient orientation, boolean border); void curses_add_wid(winid wid);