curses_putmixed() initial attempt
The curses interface was using genl_putmixed() which doesn't
preserve the symbol actually used for a glyph on the display.
This is a first-attempt at implementing curses_putmixed().
On Linux you'll need to distribute the Makefiles again
sh sys/unix/setup.sh sys/unix/hints/linux.370
On macOS, you'll need to distribute the Makefiles again
sh sys/unix/setup.sh sys/unix/hints/macOS.370
This commit is contained in:
@@ -3119,6 +3119,7 @@ extern int hide_privileges(boolean);
|
|||||||
#ifdef ENHANCED_SYMBOLS
|
#ifdef ENHANCED_SYMBOLS
|
||||||
extern int glyphrep(const char *);
|
extern int glyphrep(const char *);
|
||||||
extern char *mixed_to_utf8(char *buf, size_t bufsz, const char *str, int *);
|
extern char *mixed_to_utf8(char *buf, size_t bufsz, const char *str, int *);
|
||||||
|
extern const char *mixed_to_glyphinfo(const char *str, glyph_info *gip);
|
||||||
extern int match_glyph(char *);
|
extern int match_glyph(char *);
|
||||||
extern void dump_all_glyphids(FILE *fp);
|
extern void dump_all_glyphids(FILE *fp);
|
||||||
extern void fill_glyphid_cache(void);
|
extern void fill_glyphid_cache(void);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ extern void curses_display_nhwindow(winid wid, boolean block);
|
|||||||
extern void curses_destroy_nhwindow(winid wid);
|
extern void curses_destroy_nhwindow(winid wid);
|
||||||
extern void curses_curs(winid wid, int x, int y);
|
extern void curses_curs(winid wid, int x, int y);
|
||||||
extern void curses_putstr(winid wid, int attr, const char *text);
|
extern void curses_putstr(winid wid, int attr, const char *text);
|
||||||
|
extern void curses_putmixed(winid window, int attr, const char *str);
|
||||||
extern void curses_display_file(const char *filename, boolean must_exist);
|
extern void curses_display_file(const char *filename, boolean must_exist);
|
||||||
extern void curses_start_menu(winid wid, unsigned long);
|
extern void curses_start_menu(winid wid, unsigned long);
|
||||||
extern void curses_add_menu(winid wid, const glyph_info *,
|
extern void curses_add_menu(winid wid, const glyph_info *,
|
||||||
|
|||||||
@@ -542,6 +542,33 @@ mixed_to_utf8(char *buf, size_t bufsz, const char *str, int *retflags)
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* helper routine if a window port wants to extract the unicode
|
||||||
|
* representation from a glyph representation in the string;
|
||||||
|
* the returned string is the remainder of the string after
|
||||||
|
* extracting the \GNNNNNNNN information.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
mixed_to_glyphinfo(const char *str, glyph_info *gip)
|
||||||
|
{
|
||||||
|
int dcount, ggv;
|
||||||
|
|
||||||
|
if (!str || !gip)
|
||||||
|
return " ";
|
||||||
|
|
||||||
|
*gip = nul_glyphinfo;
|
||||||
|
if (*str == '\\' && *(str + 1) == 'G') {
|
||||||
|
if ((dcount = decode_glyph(str + 2, &ggv))) {
|
||||||
|
map_glyphinfo(0, 0, ggv, 0, gip);
|
||||||
|
/* 'str' is ready for the next loop iteration and
|
||||||
|
'*str' should not be copied at the end of this
|
||||||
|
iteration */
|
||||||
|
str += (dcount + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dump_all_glyphids(FILE *fp)
|
dump_all_glyphids(FILE *fp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ WINCFLAGS += -DNOTTYGRAPHICS
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef WANT_WIN_CURSES
|
ifdef WANT_WIN_CURSES
|
||||||
WINCFLAGS += -DCURSES_GRAPHICS
|
WINCFLAGS += -DCURSES_GRAPHICS -D_XOPEN_SOURCE_EXTENDED=1
|
||||||
WINSRC += $(WINCURSESSRC)
|
WINSRC += $(WINCURSESSRC)
|
||||||
WINOBJ0 += $(WINCURSESOBJ)
|
WINOBJ0 += $(WINCURSESOBJ)
|
||||||
endif
|
endif
|
||||||
|
|||||||
+16
-1
@@ -22,6 +22,8 @@ extern char erase_char, kill_char;
|
|||||||
|
|
||||||
extern long curs_mesg_suppress_seq; /* from cursmesg.c */
|
extern long curs_mesg_suppress_seq; /* from cursmesg.c */
|
||||||
extern boolean curs_mesg_no_suppress; /* ditto */
|
extern boolean curs_mesg_no_suppress; /* ditto */
|
||||||
|
extern int mesg_mixed;
|
||||||
|
extern glyph_info mesg_gi;
|
||||||
|
|
||||||
/* stubs for curses_procs{} */
|
/* stubs for curses_procs{} */
|
||||||
#ifdef POSITIONBAR
|
#ifdef POSITIONBAR
|
||||||
@@ -70,7 +72,7 @@ struct window_procs curses_procs = {
|
|||||||
curses_destroy_nhwindow,
|
curses_destroy_nhwindow,
|
||||||
curses_curs,
|
curses_curs,
|
||||||
curses_putstr,
|
curses_putstr,
|
||||||
genl_putmixed,
|
curses_putmixed,
|
||||||
curses_display_file,
|
curses_display_file,
|
||||||
curses_start_menu,
|
curses_start_menu,
|
||||||
curses_add_menu,
|
curses_add_menu,
|
||||||
@@ -561,6 +563,19 @@ curses_putstr(winid wid, int attr, const char *text)
|
|||||||
curs_mesg_no_suppress = FALSE;
|
curs_mesg_no_suppress = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
curses_putmixed(winid window, int attr, const char *str)
|
||||||
|
{
|
||||||
|
if (window == WIN_MESSAGE) {
|
||||||
|
str = mixed_to_glyphinfo(str, &mesg_gi);
|
||||||
|
mesg_mixed = 1;
|
||||||
|
}
|
||||||
|
/* now send it to the normal putstr */
|
||||||
|
curses_putstr(window, attr, str);
|
||||||
|
if (window == WIN_MESSAGE)
|
||||||
|
mesg_mixed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Display the file named str. Complain about missing files
|
/* Display the file named str. Complain about missing files
|
||||||
iff complain is TRUE.
|
iff complain is TRUE.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+85
-8
@@ -26,10 +26,13 @@ long curs_mesg_suppress_seq = -1L;
|
|||||||
message triggers More>> for the previous message and the player responds
|
message triggers More>> for the previous message and the player responds
|
||||||
with ESC; we need to avoid initiating suppression in that situation */
|
with ESC; we need to avoid initiating suppression in that situation */
|
||||||
boolean curs_mesg_no_suppress = FALSE;
|
boolean curs_mesg_no_suppress = FALSE;
|
||||||
|
/* curses_putmixed() will place information in these next two */
|
||||||
|
int mesg_mixed = 0;
|
||||||
|
glyph_info mesg_gi;
|
||||||
|
|
||||||
/* Message window routines for curses interface */
|
/* Message window routines for curses interface */
|
||||||
|
|
||||||
/* Private declatations */
|
/* Private declarations */
|
||||||
|
|
||||||
typedef struct nhpm {
|
typedef struct nhpm {
|
||||||
char *str; /* Message text */
|
char *str; /* Message text */
|
||||||
@@ -43,6 +46,7 @@ static void unscroll_window(winid wid);
|
|||||||
static void directional_scroll(winid wid, int nlines);
|
static void directional_scroll(winid wid, int nlines);
|
||||||
static void mesg_add_line(const char *mline);
|
static void mesg_add_line(const char *mline);
|
||||||
static nhprev_mesg *get_msg_line(boolean reverse, int mindex);
|
static nhprev_mesg *get_msg_line(boolean reverse, int mindex);
|
||||||
|
static int curscolor(int nhcolor, boolean *boldon);
|
||||||
|
|
||||||
static int turn_lines = 0;
|
static int turn_lines = 0;
|
||||||
static int mx = 0;
|
static int mx = 0;
|
||||||
@@ -61,8 +65,10 @@ curses_message_win_puts(const char *message, boolean recursed)
|
|||||||
int height, width, border_space, linespace;
|
int height, width, border_space, linespace;
|
||||||
char *tmpstr;
|
char *tmpstr;
|
||||||
WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
|
WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
|
||||||
boolean bold, border = curses_window_has_border(MESSAGE_WIN);
|
boolean bold, border = curses_window_has_border(MESSAGE_WIN),
|
||||||
|
have_mixed_leadin = FALSE, adjustbold = FALSE;
|
||||||
int message_length = (int) strlen(message);
|
int message_length = (int) strlen(message);
|
||||||
|
cchar_t mixed_leadin_cchar[2];
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
@@ -110,6 +116,36 @@ curses_message_win_puts(const char *message, boolean recursed)
|
|||||||
/* -2: for leading " " (if combining this message with preceding one) */
|
/* -2: for leading " " (if combining this message with preceding one) */
|
||||||
if (mx > border_space)
|
if (mx > border_space)
|
||||||
linespace -= 2;
|
linespace -= 2;
|
||||||
|
bold = (height > 1 && !last_messages);
|
||||||
|
|
||||||
|
if (mesg_mixed) {
|
||||||
|
wchar_t w[2];
|
||||||
|
int leadin_color;
|
||||||
|
|
||||||
|
leadin_color = curscolor(mesg_gi.gm.sym.color, &adjustbold);
|
||||||
|
/*
|
||||||
|
* curses_putmixed() skipped past the \GNNNNNNNN encoding
|
||||||
|
* in the string, and filled in the mesg_gi glyphinfo. It
|
||||||
|
* flagged that to us by setting mesg_mixed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
w[0] = (wchar_t) mesg_gi.ttychar;
|
||||||
|
#ifdef ENHANCED_SYMBOLS
|
||||||
|
if ((windowprocs.wincap2 & WC2_U_UTF8STR) && SYMHANDLING(H_UTF8)
|
||||||
|
&& mesg_gi.gm.u) {
|
||||||
|
/* FIXME: this won't work with all unicode values (32 bits -> 16
|
||||||
|
* bits on Windows) */
|
||||||
|
w[0] = (wchar_t) mesg_gi.gm.u->utf32ch;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
w[1] = L'\0';
|
||||||
|
if (setcchar(mixed_leadin_cchar, w,
|
||||||
|
(bold || adjustbold) ? A_BOLD : A_NORMAL,
|
||||||
|
leadin_color, 0) == OK) {
|
||||||
|
have_mixed_leadin = TRUE;
|
||||||
|
message_length++; /* account for that additional column */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (linespace < message_length) {
|
if (linespace < message_length) {
|
||||||
if (my - border_space >= height - 1) {
|
if (my - border_space >= height - 1) {
|
||||||
@@ -143,35 +179,76 @@ curses_message_win_puts(const char *message, boolean recursed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bold = (height > 1 && !last_messages);
|
if (bold || adjustbold)
|
||||||
if (bold)
|
|
||||||
curses_toggle_color_attr(win, NONE, A_BOLD, ON);
|
curses_toggle_color_attr(win, NONE, A_BOLD, ON);
|
||||||
|
|
||||||
/* will this message fit as-is or do we need to split it? */
|
/* will this message fit as-is or do we need to split it? */
|
||||||
if (mx == border_space && message_length > width - 3) {
|
if (mx == border_space && message_length > width - 3) {
|
||||||
/* split needed */
|
/* split needed */
|
||||||
tmpstr = curses_break_str(message, (width - 3), 1);
|
tmpstr = curses_break_str(message, (width - 3), 1);
|
||||||
|
if (have_mixed_leadin) {
|
||||||
|
mvwadd_wch(win, my, mx, mixed_leadin_cchar);
|
||||||
|
++mx;
|
||||||
|
message_length--;
|
||||||
|
have_mixed_leadin = FALSE;
|
||||||
|
mesg_mixed = 0;
|
||||||
|
}
|
||||||
mvwprintw(win, my, mx, "%s", tmpstr), mx += (int) strlen(tmpstr);
|
mvwprintw(win, my, mx, "%s", tmpstr), mx += (int) strlen(tmpstr);
|
||||||
/* one space to separate first part of message from rest [is this
|
/* one space to separate first part of message from rest [is this
|
||||||
actually useful?] */
|
actually useful?] */
|
||||||
if (mx < width)
|
if (mx < width)
|
||||||
++mx;
|
++mx;
|
||||||
free(tmpstr);
|
free(tmpstr);
|
||||||
if (bold)
|
if (bold || adjustbold)
|
||||||
curses_toggle_color_attr(win, NONE, A_BOLD, OFF);
|
curses_toggle_color_attr(win, NONE, A_BOLD, OFF);
|
||||||
tmpstr = curses_str_remainder(message, (width - 3), 1);
|
tmpstr = curses_str_remainder(message, (width - 3), 1);
|
||||||
curses_message_win_puts(tmpstr, TRUE);
|
curses_message_win_puts(tmpstr, TRUE);
|
||||||
free(tmpstr);
|
free(tmpstr);
|
||||||
} else {
|
} else {
|
||||||
|
if (have_mixed_leadin) {
|
||||||
|
mvwadd_wch(win, my, mx, mixed_leadin_cchar);
|
||||||
|
++mx;
|
||||||
|
message_length--;
|
||||||
|
have_mixed_leadin = FALSE;
|
||||||
|
mesg_mixed = 0;
|
||||||
|
}
|
||||||
mvwprintw(win, my, mx, "%s", message), mx += message_length;
|
mvwprintw(win, my, mx, "%s", message), mx += message_length;
|
||||||
if (bold)
|
if (bold || adjustbold)
|
||||||
curses_toggle_color_attr(win, NONE, A_BOLD, OFF);
|
curses_toggle_color_attr(win, NONE, A_BOLD, OFF);
|
||||||
}
|
}
|
||||||
wrefresh(win);
|
wrefresh(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
curses_got_input(void)
|
static int
|
||||||
|
curscolor(int nhcolor, boolean *boldon)
|
||||||
|
{
|
||||||
|
int curses_color;
|
||||||
|
|
||||||
|
*boldon = FALSE;
|
||||||
|
if (nhcolor == 0) { /* make black fg visible */
|
||||||
|
#ifdef USE_DARKGRAY
|
||||||
|
if (iflags.wc2_darkgray) {
|
||||||
|
if (COLORS > 16) {
|
||||||
|
/* colorpair for black is already darkgray */
|
||||||
|
} else { /* Use bold for a bright black */
|
||||||
|
*boldon = TRUE;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif /* USE_DARKGRAY */
|
||||||
|
nhcolor = CLR_BLUE;
|
||||||
|
}
|
||||||
|
curses_color = nhcolor + 1;
|
||||||
|
if (COLORS < 16) {
|
||||||
|
if (curses_color > 8 && curses_color < 17)
|
||||||
|
curses_color -= 8;
|
||||||
|
else if (curses_color > (17 + 16))
|
||||||
|
curses_color -= 16;
|
||||||
|
}
|
||||||
|
return curses_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void curses_got_input(void)
|
||||||
{
|
{
|
||||||
/* if messages are being suppressed, reenable them */
|
/* if messages are being suppressed, reenable them */
|
||||||
curs_mesg_suppress_seq = -1L;
|
curs_mesg_suppress_seq = -1L;
|
||||||
|
|||||||
Reference in New Issue
Block a user