Curses: implement the windowcolors option

Allow changing the curses windows foreground and background colors,
for example:

OPTIONS=windowcolor:menu #8000F0/20F080 message grey/blue
This commit is contained in:
Pasi Kallinen
2024-03-17 18:41:52 +02:00
parent 9dbab97a1e
commit 4030ef13a0
17 changed files with 214 additions and 32 deletions
+1 -1
View File
@@ -4996,7 +4996,7 @@ plus widen each inventory line by two columns.
.lp windowcolors .lp windowcolors
If NetHack can, it should display windows with the specified If NetHack can, it should display windows with the specified
foreground/background colors. foreground/background colors.
Windows GUI only. Windows GUI and curses windowport only.
The format is The format is
.si .si
.lp "OPTION=windowcolors:wintype foreground/background" .lp "OPTION=windowcolors:wintype foreground/background"
+1 -1
View File
@@ -5513,7 +5513,7 @@ plus widen each inventory line by two columns.
\item[\ib{windowcolors}] \item[\ib{windowcolors}]
If {\it NetHack\/} can, it should display windows with the specified If {\it NetHack\/} can, it should display windows with the specified
foreground/background colors. foreground/background colors.
Windows GUI only. Windows GUI and curses windowport only.
The format is The format is
\begin{verbatim} \begin{verbatim}
OPTION=windowcolors:wintype foreground/background OPTION=windowcolors:wintype foreground/background
+1
View File
@@ -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 curses: if a message is marked urgent, override message suppression initiated
by user having typed ESC at previous More>> prompt by user having typed ESC at previous More>> prompt
curses: implement a dialog for the windowborders option 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" Qt: the "paper doll" inventory subset can be controlled via the "Qt Settings"
dialog box ("Preferences..." on macOS) dialog box ("Preferences..." on macOS)
Qt: draw a border around each tile in the paper doll inventory; when BUC is Qt: draw a border around each tile in the paper doll inventory; when BUC is
+8 -2
View File
@@ -32,7 +32,9 @@ extern WINDOW *activemenu; /* curses window for menu requesting a
#define STATUS_WIN 2 #define STATUS_WIN 2
#define MAP_WIN 3 #define MAP_WIN 3
#define INV_WIN 4 #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) #if !defined(__APPLE__) || !defined(NCURSES_VERSION)
# define USE_DARKGRAY /* Allow "bright" black; delete if not visible */ # define USE_DARKGRAY /* Allow "bright" black; delete if not visible */
#endif /* !__APPLE__ && !PDCURSES */ #endif /* !__APPLE__ && !PDCURSES */
@@ -117,7 +119,9 @@ extern win_request_info *curses_ctrl_nhwindow(winid, int, win_request_info *);
/* curswins.c */ /* 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 void curses_destroy_win(WINDOW *win);
extern WINDOW *curses_get_nhwin(winid wid); extern WINDOW *curses_get_nhwin(winid wid);
extern void curses_add_nhwin(winid wid, int height, int width, int y, 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 */ /* cursinit.c */
extern void curses_create_main_windows(void); 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_init_nhcolors(void);
extern void curses_choose_character(void); extern void curses_choose_character(void);
extern int curses_character_dialog(const char **choices, const char *prompt); extern int curses_character_dialog(const char **choices, const char *prompt);
+4 -4
View File
@@ -446,7 +446,7 @@ endif
#========================================== #==========================================
# #
ifeq "$(ADD_CURSES)" "Y" 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 ifdef WANT_DOSVGA
CURSESDEF += -DCURSES_UNICODE -DPDC_WIDE CURSESDEF += -DCURSES_UNICODE -DPDC_WIDE
endif endif
@@ -538,13 +538,13 @@ $(OBJ)/%.o : $(WCURSES)/%.c
#========================================== #==========================================
$(OBJ)/%.o : $(PDCURSES_TOP)/%.c $(OBJ)/%.o : $(PDCURSES_TOP)/%.c
$(CC) $(cflags) -o$@ $< $(CC) $(cflags) -o$@ $<
$(OBJ)/%.o : $(PDCSRC)/%.c $(OBJ)/%.o : $(PDCSRC)/%.c
$(CC) $(cflags) -o$@ $< $(CC) $(cflags) -o$@ $<
$(OBJ)/%.o : $(PDCDOS)/%.c $(OBJ)/%.o : $(PDCDOS)/%.c
$(CC) $(cflags) -o$@ $< $(CC) $(cflags) -o$@ $<
#========================================== #==========================================
# Rules for LUA files # Rules for LUA files
+1 -1
View File
@@ -50,7 +50,7 @@ ifdef WANT_DOSVGA
PDCPORT = $(PDCTOP)/dosvga PDCPORT = $(PDCTOP)/dosvga
PDCURSESDEF= -I$(PDCTOP) -I$(PDCPORT) \ PDCURSESDEF= -I$(PDCTOP) -I$(PDCPORT) \
-D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" \ -D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" \
-D"PDC_WIDE" -D"CURSES_UNICODE" -D"PDC_WIDE" -D"PDC_RGB" -D"CURSES_UNICODE"
else else
PDCPORT = $(PDCTOP)/dos PDCPORT = $(PDCTOP)/dos
PDCURSESDEF= -I$(PDCTOP) -I$(PDCPORT) \ PDCURSESDEF= -I$(PDCTOP) -I$(PDCPORT) \
+1 -1
View File
@@ -118,7 +118,7 @@ GIT_AVAILABLE=Y
endif endif
PDCURSES=pdcursesmod PDCURSES=pdcursesmod
PDCURSESFLAGS = -DPDC_WIDE PDCURSESFLAGS = -DPDC_WIDE -DPDC_RGB
# #
#============================================================================== #==============================================================================
+1 -1
View File
@@ -602,7 +602,7 @@ WINDHDR = $(MSWSYS)\win10.h $(MSWSYS)\winos.h $(MSWSYS)\win32api.h
# #
!IF "$(ADD_CURSES)" == "Y" !IF "$(ADD_CURSES)" == "Y"
PDCURSESFLAGS = -DPDC_WIDE PDCURSESFLAGS = -DPDC_WIDE -DPDC_RGB
CURSESOBJ= $(OTTY)cursdial.o $(OTTY)cursinit.o $(OTTY)cursinvt.o \ CURSESOBJ= $(OTTY)cursdial.o $(OTTY)cursinit.o $(OTTY)cursinvt.o \
$(OTTY)cursmain.o $(OTTY)cursmesg.o $(OTTY)cursmisc.o \ $(OTTY)cursmain.o $(OTTY)cursmesg.o $(OTTY)cursmisc.o \
$(OTTY)cursstat.o $(OTTY)curswins.o $(OTTY)cursstat.o $(OTTY)curswins.o
+4 -4
View File
@@ -90,14 +90,14 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -105,7 +105,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -117,7 +117,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_LIB;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -84,14 +84,14 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -99,7 +99,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -111,7 +111,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;PDC_WIDE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_LIB;PDC_WIDE;PDC_RGB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
+16 -7
View File
@@ -6,6 +6,9 @@
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
#include "wincurs.h" #include "wincurs.h"
#include "cursinit.h"
#include "curswins.h"
#include "cursmisc.h"
#include "cursdial.h" #include "cursdial.h"
#include "func_tab.h" #include "func_tab.h"
#include <ctype.h> #include <ctype.h>
@@ -151,8 +154,9 @@ curses_line_input_dialog(
free(tmpstr); free(tmpstr);
} }
bwin = curses_create_window(prompt_width, height, bwin = curses_create_window(TEXT_WIN, prompt_width, height,
iflags.window_inited ? UP : CENTER); iflags.window_inited ? UP : CENTER);
curses_set_wid_colors(TEXT_WIN, bwin);
wrefresh(bwin); wrefresh(bwin);
getbegyx(bwin, winy, winx); getbegyx(bwin, winy, winx);
askwin = newwin(height, prompt_width, winy + 1, winx + 1); 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*/) { 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; activemenu = askwin;
for (count = 0; count < prompt_height; count++) { for (count = 0; count < prompt_height; count++) {
@@ -286,6 +290,7 @@ curses_character_input_dialog(
free(linestr); free(linestr);
} }
curses_set_wid_colors(TEXT_WIN, askwin);
wrefresh(askwin); wrefresh(askwin);
} else { } else {
/* TODO: add SUPPRESS_HISTORY flag, then after getting a response, /* 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 */ if (iflags.wc_popup_dialog) { /* Prompt in popup window */
int x0, y0, w, h; /* bounding coords of popup */ 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); wrefresh(extwin2);
/* create window inside window to prevent overwriting of border */ /* create window inside window to prevent overwriting of border */
getbegyx(extwin2, y0, x0); getbegyx(extwin2, y0, x0);
@@ -784,13 +790,14 @@ curses_display_nhmenu(
/* Display pre and post-game menus centered */ /* Display pre and post-game menus centered */
if ((gm.moves <= 1 && !gi.invent) || gp.program_state.gameover) { 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); current_menu->height, CENTER);
} else { /* Display during-game menus on the right out of the way */ } 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); current_menu->height, RIGHT);
} }
curses_set_wid_colors(wid, win);
num_chosen = menu_get_selections(win, current_menu, how); num_chosen = menu_get_selections(win, current_menu, how);
curses_destroy_win(win); 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, 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); 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); wrefresh(win);
} }
+32
View File
@@ -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 */ /* Initialize curses colors to colors used by NetHack */
void void
curses_init_nhcolors(void) curses_init_nhcolors(void)
@@ -335,6 +365,8 @@ curses_init_nhcolors(void)
} }
} }
#endif #endif
colors_used = maxc;
pairs_used = (maxc * 8) + 16 + 1;
} }
#if 0 /* curses_choose_character + curses_character_dialog no longer used */ #if 0 /* curses_choose_character + curses_character_dialog no longer used */
+2
View File
@@ -9,6 +9,8 @@
/* Global declarations */ /* Global declarations */
void curses_create_main_windows(void); 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_init_nhcolors(void);
void curses_choose_character(void); void curses_choose_character(void);
int curses_character_dialog(const char **choices, const char *prompt); int curses_character_dialog(const char **choices, const char *prompt);
+5 -1
View File
@@ -54,7 +54,7 @@ static char *dummy_get_color_string(void);
struct window_procs curses_procs = { struct window_procs curses_procs = {
WPID(curses), WPID(curses),
(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_INVERSE (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) */ #ifdef NCURSES_MOUSE_VERSION /* (this macro name works for PDCURSES too) */
| WC_MOUSE_SUPPORT | WC_MOUSE_SUPPORT
#endif #endif
@@ -426,6 +426,10 @@ curses_create_nhwindow(int type)
{ {
winid wid = curses_get_wid(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)) { if (curses_is_menu(wid) || curses_is_text(wid)) {
curses_start_menu(wid, MENU_BEHAVE_STANDARD); curses_start_menu(wid, MENU_BEHAVE_STANDARD);
curses_add_wid(wid); curses_add_wid(wid);
+8
View File
@@ -7,6 +7,7 @@
#include "hack.h" #include "hack.h"
#include "wincurs.h" #include "wincurs.h"
#include "cursmesg.h" #include "cursmesg.h"
#include "curswins.h"
#include <ctype.h> #include <ctype.h>
/* defined in sys/<foo>/<foo>tty.c or cursmain.c as last resort; /* defined in sys/<foo>/<foo>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. */ 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); curses_get_window_size(MESSAGE_WIN, &height, &width);
border_space = (border ? 1 : 0); border_space = (border ? 1 : 0);
if (mx < border_space) if (mx < border_space)
@@ -322,6 +324,7 @@ curses_block(
} }
moreattr = !iflags.wc2_guicolor ? (int) A_REVERSE : NONE; moreattr = !iflags.wc2_guicolor ? (int) A_REVERSE : NONE;
curses_toggle_color_attr(win, MORECOLOR, moreattr, ON); curses_toggle_color_attr(win, MORECOLOR, moreattr, ON);
curses_set_wid_colors(MESSAGE_WIN, NULL);
if (blink) { if (blink) {
wattron(win, A_BLINK); wattron(win, A_BLINK);
mvwprintw(win, my, mx, ">"), mx += 1; mvwprintw(win, my, mx, ">"), mx += 1;
@@ -331,6 +334,7 @@ curses_block(
mvwprintw(win, my, mx, ">>"), mx += 2; mvwprintw(win, my, mx, ">>"), mx += 2;
} }
curses_toggle_color_attr(win, MORECOLOR, moreattr, OFF); curses_toggle_color_attr(win, MORECOLOR, moreattr, OFF);
curses_set_wid_colors(MESSAGE_WIN, NULL);
wrefresh(win); wrefresh(win);
/* cancel mesg suppression; all messages will have had chance to be read */ /* 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); WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
turn_lines = 0; turn_lines = 0;
curses_set_wid_colors(MESSAGE_WIN, NULL);
curses_get_window_size(MESSAGE_WIN, &mh, &mw); curses_get_window_size(MESSAGE_WIN, &mh, &mw);
if (mh == 1) { if (mh == 1) {
@@ -413,6 +418,7 @@ curses_last_messages(void)
int border = curses_window_has_border(MESSAGE_WIN) ? 1 : 0; int border = curses_window_has_border(MESSAGE_WIN) ? 1 : 0;
WINDOW *win = curses_get_nhwin(MESSAGE_WIN); WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
curses_set_wid_colors(MESSAGE_WIN, NULL);
curses_get_window_size(MESSAGE_WIN, &height, &width); curses_get_window_size(MESSAGE_WIN, &height, &width);
werase(win); werase(win);
mx = my = border; 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 */ but not for dolook's autodescribe when it refers to a named monster */
if (!countwin) if (!countwin)
countwin = newwin(1, messagew, winy, winx); countwin = newwin(1, messagew, winy, winx);
curses_set_wid_colors(MESSAGE_WIN, NULL);
werase(countwin); werase(countwin);
mvwprintw(countwin, 0, 0, "%s", count_text); mvwprintw(countwin, 0, 0, "%s", count_text);
@@ -880,6 +887,7 @@ directional_scroll(winid wid, int nlines)
boolean border = curses_window_has_border(wid); boolean border = curses_window_has_border(wid);
WINDOW *win = curses_get_nhwin(wid); WINDOW *win = curses_get_nhwin(wid);
curses_set_wid_colors(wid, NULL);
curses_get_window_size(wid, &wh, &ww); curses_get_window_size(wid, &wh, &ww);
if (wh == 1) { if (wh == 1) {
curses_clear_nhwin(wid); curses_clear_nhwin(wid);
+120 -4
View File
@@ -9,7 +9,10 @@
#include "curses.h" #include "curses.h"
#include "hack.h" #include "hack.h"
#include "wincurs.h" #include "wincurs.h"
#include "cursinit.h"
#include "cursmisc.h"
#include "curswins.h" #include "curswins.h"
#include "cursstat.h"
/* Window handling for curses interface */ /* Window handling for curses interface */
@@ -23,6 +26,9 @@ typedef struct nhw {
int x; /* start of window on terminal (left) */ int x; /* start of window on terminal (left) */
int y; /* start of window on terminal (top) */ int y; /* start of window on terminal (top) */
int orientation; /* Placement of window relative to map */ 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 */ boolean border; /* Whether window has a visible border */
} nethack_window; } nethack_window;
@@ -52,7 +58,7 @@ static void clear_map(void);
/* Create a window with the specified size and orientation */ /* Create a window with the specified size and orientation */
WINDOW * 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 mapx = 0, mapy = 0, maph = 0, mapw = 0;
int startx = 0; int startx = 0;
@@ -142,12 +148,48 @@ curses_create_window(int width, int height, orient orientation)
} }
win = newwin(height, width, starty, startx); 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); 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; 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 */ /* Erase and delete curses window, and refresh standard windows */
@@ -183,6 +225,7 @@ curses_refresh_nethack_windows(void)
refresh(); refresh();
} else { } else {
if (status_window != NULL) { if (status_window != NULL) {
curses_set_wid_colors(STATUS_WIN, NULL);
touchwin(status_window); touchwin(status_window);
wnoutrefresh(status_window); wnoutrefresh(status_window);
} }
@@ -191,6 +234,7 @@ curses_refresh_nethack_windows(void)
wnoutrefresh(map_window); wnoutrefresh(map_window);
} }
if (message_window != NULL) { if (message_window != NULL) {
curses_set_wid_colors(MESSAGE_WIN, NULL);
touchwin(message_window); touchwin(message_window);
wnoutrefresh(message_window); wnoutrefresh(message_window);
} }
@@ -217,6 +261,67 @@ curses_get_nhwin(winid wid)
return nhwins[wid].curwin; 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 */ /* 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].x = x;
nhwins[wid].y = y; nhwins[wid].y = y;
nhwins[wid].orientation = orientation; nhwins[wid].orientation = orientation;
nhwins[wid].fg = nhwins[wid].bg = 0;
nhwins[wid].colorpair = -1;
nhwins[wid].clr_inited = 0;
if (border) { if (border) {
real_width += 2; /* leave room for bounding box */ 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); win = newwin(real_height, real_width, y, x);
nhwins[wid].curwin = win;
switch (wid) { switch (wid) {
case MESSAGE_WIN: case MESSAGE_WIN:
messagewin = win; messagewin = win;
curses_parse_wid_colors(wid, iflags.wc_foregrnd_message, iflags.wc_backgrnd_message);
curses_set_wid_colors(wid, NULL);
break; break;
case STATUS_WIN: case STATUS_WIN:
statuswin = win; statuswin = win;
curses_parse_wid_colors(wid, iflags.wc_foregrnd_status, iflags.wc_backgrnd_status);
curses_set_wid_colors(wid, NULL);
break; break;
case MAP_WIN: case MAP_WIN:
mapwin = win; mapwin = win;
@@ -266,7 +379,6 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x,
box(win, 0, 0); box(win, 0, 0);
} }
nhwins[wid].curwin = win;
} }
@@ -301,6 +413,7 @@ curses_add_wid(winid wid)
void void
curses_refresh_nhwin(winid wid) curses_refresh_nhwin(winid wid)
{ {
curses_set_wid_colors(wid, NULL);
wnoutrefresh(curses_get_nhwin(wid)); wnoutrefresh(curses_get_nhwin(wid));
doupdate(); doupdate();
} }
@@ -523,6 +636,7 @@ curses_puts(winid wid, int attr, const char *text)
} }
#endif #endif
curses_set_wid_colors(wid, NULL);
if (curses_is_menu(wid) || curses_is_text(wid)) { if (curses_is_menu(wid) || curses_is_text(wid)) {
if (!curses_menu_exists(wid)) { if (!curses_menu_exists(wid)) {
impossible( impossible(
@@ -553,6 +667,7 @@ curses_clear_nhwin(winid wid)
clear_map(); clear_map();
} }
curses_set_wid_colors(wid, NULL);
werase(win); werase(win);
if (border) { if (border) {
@@ -568,6 +683,7 @@ curses_alert_win_border(winid wid, boolean onoff)
if (!win || !curses_window_has_border(wid)) if (!win || !curses_window_has_border(wid))
return; return;
curses_set_wid_colors(wid, NULL);
if (onoff) if (onoff)
curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON); curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON);
box(win, 0, 0); box(win, 0, 0);
+5 -1
View File
@@ -9,11 +9,15 @@
/* Global declarations */ /* 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_destroy_win(WINDOW * win);
void curses_refresh_nethack_windows(void); void curses_refresh_nethack_windows(void);
WINDOW *curses_get_nhwin(winid wid); 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, void curses_add_nhwin(winid wid, int height, int width, int y, int x,
orient orientation, boolean border); orient orientation, boolean border);
void curses_add_wid(winid wid); void curses_add_wid(winid wid);