Begin reimplemented TTY-style status
This commit is contained in:
committed by
Pasi Kallinen
parent
cd493962b1
commit
c2b4ee53e5
+287
-4
@@ -98,6 +98,7 @@
|
||||
|
||||
static int condcolor(long, unsigned long *);
|
||||
static int condattr(long, unsigned long *);
|
||||
#if 0 /*RLC*/
|
||||
static void HiliteField(Widget, int, int, int, XFontStruct **);
|
||||
static void PrepStatusField(int, Widget, const char *);
|
||||
static void DisplayCond(int, unsigned long *);
|
||||
@@ -107,6 +108,7 @@ static void tt_reset_color(int, int, unsigned long *);
|
||||
#endif
|
||||
static void tt_status_fixup(void);
|
||||
static Widget create_tty_status_field(int, int, Widget, Widget);
|
||||
#endif /*RLC*/
|
||||
static Widget create_tty_status(Widget, Widget);
|
||||
static void stat_resized(Widget, XtPointer, XtPointer);
|
||||
static void update_fancy_status_field(int, int, int);
|
||||
@@ -119,6 +121,9 @@ static void destroy_status_window_fancy(struct xwindow *);
|
||||
static void destroy_status_window_tty(struct xwindow *);
|
||||
static void adjust_status_fancy(struct xwindow *, const char *);
|
||||
static void adjust_status_tty(struct xwindow *, const char *);
|
||||
static void tty_status_exposed(Widget, XtPointer, XtPointer);
|
||||
static void tty_status_redraw(Widget);
|
||||
static int tty_render_text(Widget, int, int, const char *, int, int, boolean);
|
||||
|
||||
extern const char *status_fieldfmt[MAXBLSTATS];
|
||||
extern char *status_vals[MAXBLSTATS];
|
||||
@@ -131,7 +136,9 @@ static int X11_status_colors[MAXBLSTATS],
|
||||
static int hpbar_percent, hpbar_color;
|
||||
/* Number of conditions displayed during this update and last update.
|
||||
When the last update had more, the excess need to be erased. */
|
||||
#if 0 /*RLC*/
|
||||
static int next_cond_indx = 0, prev_cond_indx = 0;
|
||||
#endif /*RLC*/
|
||||
|
||||
/* TODO: support statuslines:3 in addition to 2 for the tty-style status */
|
||||
#define X11_NUM_STATUS_LINES 2
|
||||
@@ -191,11 +198,26 @@ static const char *const fancy_status_hilite_colors[] = {
|
||||
"white",
|
||||
};
|
||||
|
||||
struct tty_status_field {
|
||||
char *text;
|
||||
int color;
|
||||
int chg;
|
||||
int percent;
|
||||
};
|
||||
|
||||
struct tty_cond_field {
|
||||
const char *text;
|
||||
int color;
|
||||
unsigned attrs;
|
||||
};
|
||||
|
||||
static Widget X11_status_widget;
|
||||
static Widget X11_status_labels[MAXBLSTATS];
|
||||
static Widget X11_cond_labels[32]; /* Ugh */
|
||||
static struct tty_status_field X11_status_labels[MAXBLSTATS];
|
||||
static struct tty_cond_field X11_cond_labels[32]; /* Ugh */
|
||||
#if 0 /*RLC*/
|
||||
static XFontStruct *X11_status_font;
|
||||
static Pixel X11_status_fg, X11_status_bg;
|
||||
#endif /*RLC*/
|
||||
|
||||
struct xwindow *xw_status_win;
|
||||
|
||||
@@ -274,6 +296,11 @@ void
|
||||
X11_status_enablefield(int fieldidx, const char *nm,
|
||||
const char *fmt, boolean enable)
|
||||
{
|
||||
if (X11_status_widget && !enable && 0 <= fieldidx && fieldidx < MAXBLSTATS) {
|
||||
free(X11_status_labels[fieldidx].text);
|
||||
X11_status_labels[fieldidx].text = NULL;
|
||||
tty_status_redraw(X11_status_widget);
|
||||
}
|
||||
genl_status_enablefield(fieldidx, nm, fmt, enable);
|
||||
}
|
||||
|
||||
@@ -290,6 +317,7 @@ cond_bm2idx(unsigned long bm)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /*RLC*/
|
||||
/* highlight a tty-style status field (or condition) */
|
||||
static void
|
||||
HiliteField(Widget label,
|
||||
@@ -650,6 +678,7 @@ tt_status_fixup(void)
|
||||
XtGetValues(xw_status_win->w, args, ONE);
|
||||
}
|
||||
}
|
||||
#endif /*RLC*/
|
||||
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
@@ -659,11 +688,65 @@ static void
|
||||
X11_status_update_tty(
|
||||
int fld,
|
||||
genericptr_t ptr,
|
||||
int chg UNUSED,
|
||||
int chg,
|
||||
int percent,
|
||||
int color,
|
||||
unsigned long *colormasks) /* bitmask of highlights for conditions */
|
||||
{
|
||||
printf("fld=%d\n", fld); fflush(stdout);
|
||||
switch (fld) {
|
||||
case BL_RESET:
|
||||
case BL_FLUSH:
|
||||
tty_status_redraw(X11_status_widget);
|
||||
break;
|
||||
|
||||
case BL_CONDITION:
|
||||
{
|
||||
unsigned long cond = *(unsigned long const *)ptr;
|
||||
for (unsigned j = 0; j < SIZE(tt_condorder); ++j) {
|
||||
struct tty_cond_field *fldp = &X11_cond_labels[j];
|
||||
fldp->color = NO_COLOR;
|
||||
fldp->attrs = 0;
|
||||
if ((cond & tt_condorder[j].mask) != 0) {
|
||||
fldp->text = tt_condorder[j].text;
|
||||
} else {
|
||||
fldp->text = NULL;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < CLR_MAX; ++i) {
|
||||
unsigned long mask = colormasks[i];
|
||||
for (unsigned j = 0; j < SIZE(tt_condorder); ++j) {
|
||||
if ((mask & tt_condorder[j].mask) != 0) {
|
||||
struct tty_cond_field *fldp = &X11_cond_labels[j];
|
||||
fldp->color = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = CLR_MAX; i < BL_ATTCLR_MAX; ++i) {
|
||||
unsigned long mask = colormasks[i];
|
||||
for (unsigned j = 0; j < SIZE(tt_condorder); ++j) {
|
||||
if ((mask & tt_condorder[j].mask) != 0) {
|
||||
struct tty_cond_field *fldp = &X11_cond_labels[j];
|
||||
fldp->attrs |= 0x1 << (i - CLR_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (0 <= fld && fld < SIZE(X11_status_labels)) {
|
||||
struct tty_status_field *fldp = &X11_status_labels[fld];
|
||||
const char *str = (const char *) ptr;
|
||||
free(fldp->text);
|
||||
fldp->text = dupstr(str);
|
||||
fldp->chg = chg;
|
||||
fldp->percent = percent;
|
||||
fldp->color = color;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if 0 /*RLC*/
|
||||
static int xtra_space[MAXBLSTATS];
|
||||
static unsigned long *cond_colormasks = (unsigned long *) 0;
|
||||
|
||||
@@ -832,6 +915,7 @@ X11_status_update_tty(
|
||||
/* this probably doesn't buy us anything but it isn't a sure thing
|
||||
that nethack will immediately ask for input (triggering auto-flush) */
|
||||
(void) XFlush(XtDisplay(X11_status_labels[0]));
|
||||
#endif /*RLC*/
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
@@ -951,6 +1035,7 @@ X11_status_update(
|
||||
X11_status_update_tty(fld, ptr, chg, percent, color, colormasks);
|
||||
}
|
||||
|
||||
#if 0 /*RLC*/
|
||||
/* create a widget for a particular status field or potential condition */
|
||||
static Widget
|
||||
create_tty_status_field(int fld, int condindx, Widget above, Widget left)
|
||||
@@ -991,6 +1076,7 @@ create_tty_status_field(int fld, int condindx, Widget above, Widget left)
|
||||
return XtCreateManagedWidget(labelname, labelWidgetClass,
|
||||
X11_status_widget, args, num_args);
|
||||
}
|
||||
#endif /*RLC*/
|
||||
|
||||
/* create an overall status widget (X11_status_widget) and also
|
||||
separate widgets for all status fields and potential conditions */
|
||||
@@ -998,10 +1084,14 @@ static Widget
|
||||
create_tty_status(Widget parent, Widget top)
|
||||
{
|
||||
Widget form; /* viewport that holds the form that surrounds everything */
|
||||
#if 0 /*RLC*/
|
||||
Widget w, over_w, prev_w;
|
||||
#endif /*RLC*/
|
||||
Arg args[6];
|
||||
Cardinal num_args;
|
||||
#if 0 /*RLC*/
|
||||
int x, y, i, fld;
|
||||
#endif /*RLC*/
|
||||
|
||||
(void) memset((genericptr_t) args, 0, sizeof args);
|
||||
num_args = 0;
|
||||
@@ -1019,9 +1109,13 @@ create_tty_status(Widget parent, Widget top)
|
||||
num_args = 0;
|
||||
XtSetArg(args[num_args], XtNwidth, 400); num_args++;
|
||||
XtSetArg(args[num_args], XtNheight, 100); num_args++;
|
||||
X11_status_widget = XtCreateManagedWidget("status_form", formWidgetClass,
|
||||
X11_status_widget = XtCreateManagedWidget("status_form", windowWidgetClass,
|
||||
form, args, num_args);
|
||||
|
||||
XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed,
|
||||
(XtPointer) 0);
|
||||
|
||||
#if 0 /*RLC*/
|
||||
for (y = 0; y < X11_NUM_STATUS_LINES; y++) {
|
||||
fld = (y > 0) ? X11_fieldorder[y - 1][0] : 0; /* temp, for over_w */
|
||||
/* for row(s) beyond the first, pick a widget in the previous
|
||||
@@ -1045,9 +1139,198 @@ create_tty_status(Widget parent, Widget top)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*RLC*/
|
||||
return X11_status_widget;
|
||||
}
|
||||
|
||||
/*
|
||||
* TTY status window expose callback.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
tty_status_exposed(Widget w, XtPointer client_data, /* unused */
|
||||
XtPointer widget_data) /* expose event from Window widget */
|
||||
{
|
||||
tty_status_redraw(w);
|
||||
nhUse(client_data);
|
||||
nhUse(widget_data);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_status_redraw(Widget w)
|
||||
{
|
||||
static struct stat_fmt {
|
||||
const char *pre;
|
||||
const char *post;
|
||||
} formats[MAXBLSTATS] = {
|
||||
/*@@@*/[BL_TITLE] = { NULL, NULL },
|
||||
/*@@@*/[BL_STR] = { "St:", NULL },
|
||||
/*@@@*/[BL_DX] = { "Dx:", NULL },
|
||||
/*@@@*/[BL_CO] = { "Co:", NULL },
|
||||
/*@@@*/[BL_IN] = { "In:", NULL },
|
||||
/*@@@*/[BL_WI] = { "Wi:", NULL },
|
||||
/*@@@*/[BL_CH] = { "Ch:", NULL },
|
||||
/*@@@*/[BL_ALIGN] = { NULL, NULL },
|
||||
/*@@@*/[BL_SCORE] = { "S:", NULL },
|
||||
/*@@@*/[BL_CAP] = { NULL, NULL },
|
||||
/*@@@*/[BL_GOLD] = { NULL, NULL },
|
||||
/*@@@*/[BL_ENE] = { "Pw:", NULL },
|
||||
/*@@@*/[BL_ENEMAX] = { "(", ")" },
|
||||
/*@@@*/[BL_XP] = { "Xp:", NULL },
|
||||
/*@@@*/[BL_AC] = { "AC:", NULL },
|
||||
/*@@@*/[BL_HD] = { "HD:", NULL },
|
||||
/*@@@*/[BL_TIME] = { "T:", NULL },
|
||||
/*@@@*/[BL_HUNGER] = { NULL, NULL },
|
||||
/*@@@*/[BL_HP] = { "HP:", NULL },
|
||||
/*@@@*/[BL_HPMAX] = { "(", ")" },
|
||||
/*@@@*/[BL_LEVELDESC] = { NULL, NULL },
|
||||
/*@@@*/[BL_EXP] = { "/", NULL },
|
||||
/*@@@*/[BL_CONDITION] = { NULL, NULL },
|
||||
[BL_WEAPON] = { NULL, NULL }, /* not in 2-line */
|
||||
[BL_ARMOR] = { NULL, NULL }, /* not in 2-line */
|
||||
[BL_TERRAIN] = { NULL, NULL }, /* not in 2-line */
|
||||
/*@@@*/[BL_VERS] = { NULL, NULL },
|
||||
};
|
||||
Arg args[5];
|
||||
int num_args;
|
||||
XFontStruct *font;
|
||||
Dimension width;
|
||||
|
||||
/* Get the height of the font and the width of the widget */
|
||||
num_args = 0;
|
||||
XtSetArg(args[num_args], XtNfont, &font); num_args++;
|
||||
XtSetArg(args[num_args], XtNwidth, &width); num_args++;
|
||||
XtGetValues(w, args, num_args);
|
||||
int height = font->max_bounds.ascent + font->max_bounds.descent;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
XClearWindow(XtDisplay(w), XtWindow(w));
|
||||
for (unsigned row = 0; row < X11_NUM_STATUS_LINES; ++row) {
|
||||
for (unsigned i = 0; i < X11_NUM_STATUS_FIELD; ++i) {
|
||||
enum statusfields fld = X11_fieldorder[row][i];
|
||||
switch (fld) {
|
||||
case BL_FLUSH:
|
||||
break;
|
||||
|
||||
case BL_CONDITION:
|
||||
for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) {
|
||||
struct tty_cond_field const *fldp = &X11_cond_labels[j];
|
||||
if (fldp->text != NULL) {
|
||||
x += tty_render_text(w, x, y, " ", NO_COLOR, 0, FALSE);
|
||||
x += tty_render_text(w, x, y, fldp->text, fldp->color, fldp->attrs, FALSE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
struct tty_status_field const *fldp = &X11_status_labels[fld];
|
||||
if (fldp->text != NULL && fldp->text[0] != '\0') {
|
||||
if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) {
|
||||
x += tty_render_text(w, x, y, " ", NO_COLOR, 0, FALSE);
|
||||
}
|
||||
if (formats[fld].pre != NULL) {
|
||||
x += tty_render_text(w, x, y, formats[fld].pre, NO_COLOR, 0, FALSE);
|
||||
}
|
||||
x += tty_render_text(w, x, y, fldp->text, fldp->color,
|
||||
fldp->chg ? HL_INVERSE : 0, fld == BL_GOLD);
|
||||
if (formats[fld].post != NULL) {
|
||||
x += tty_render_text(w, x, y, formats[fld].post, NO_COLOR, 0, FALSE);
|
||||
}
|
||||
/* @@@TODO: do the percent field */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
x = 0;
|
||||
y += height;
|
||||
}
|
||||
}
|
||||
|
||||
/* Render text as part of the TTY status */
|
||||
static int
|
||||
tty_render_text(Widget w, int x, int y, const char *text, int color, int attr,
|
||||
boolean is_gold)
|
||||
{
|
||||
Arg args[5];
|
||||
Cardinal num_args;
|
||||
XGCValues values;
|
||||
Pixel fgpixel, bgpixel;
|
||||
XFontStruct *font;
|
||||
int goldwidth = 0;
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
XFontStruct *unifont = NULL;
|
||||
#endif
|
||||
|
||||
/* Get default foreground and background colors, and font */
|
||||
num_args = 0;
|
||||
XtSetArg(args[num_args], XtNforeground, &fgpixel); num_args++;
|
||||
XtSetArg(args[num_args], XtNbackground, &bgpixel); num_args++;
|
||||
XtSetArg(args[num_args], XtNfont, &font); num_args++;
|
||||
XtGetValues(w, args, num_args);
|
||||
|
||||
/* Get a graphics context */
|
||||
if (attr & HL_INVERSE) {
|
||||
values.foreground = bgpixel;
|
||||
values.background = fgpixel;
|
||||
} else {
|
||||
values.foreground = fgpixel;
|
||||
values.background = bgpixel;
|
||||
}
|
||||
values.font = font->fid;
|
||||
values.function = GXcopy;
|
||||
GC ggc = XtGetGC(w,
|
||||
GCFunction | GCForeground | GCBackground | GCFont,
|
||||
&values);
|
||||
|
||||
/* Gold will begin with a glyph string. Convert this to the proper
|
||||
character, which might possibly be Unicode */
|
||||
if (is_gold && memcmp(text, "\\G", 2) == 0) {
|
||||
char *end;
|
||||
unsigned long glyphcode = strtoul(text+2, &end, 16);
|
||||
if ((glyphcode >> 16) == svc.context.rndencode && *end == ':') {
|
||||
/* We have a proper glyph code */
|
||||
glyph_info glyphinfo;
|
||||
glyphcode &= 0xFFFF;
|
||||
map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo);
|
||||
{
|
||||
char goldstr[2];
|
||||
goldstr[0] = glyphinfo.ttychar;
|
||||
goldstr[1] = 0;
|
||||
goldwidth = XTextWidth(font, goldstr, strlen(goldstr));
|
||||
|
||||
/* Render the string */
|
||||
XDrawImageString(XtDisplay(w), XtWindow(w), ggc,
|
||||
x, y + font->max_bounds.ascent,
|
||||
goldstr, strlen(goldstr));
|
||||
}
|
||||
|
||||
text = end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the width of the rendered string */
|
||||
int width = XTextWidth(font, text, strlen(text));
|
||||
|
||||
/* Render the string */
|
||||
XDrawImageString(XtDisplay(w), XtWindow(w), ggc,
|
||||
x + goldwidth, y + font->max_bounds.ascent,
|
||||
text, strlen(text));
|
||||
|
||||
/* Release resources */
|
||||
XtReleaseGC(w, ggc);
|
||||
#ifdef ENHANCED_SYMBOLS
|
||||
if (unifont != NULL) {
|
||||
XFreeFont(XtDisplay(w), unifont);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Caller will advance x by the width */
|
||||
return goldwidth + width;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
create_status_window_tty(struct xwindow *wp, /* window pointer */
|
||||
|
||||
Reference in New Issue
Block a user