Merge branch 'X11-bug-fixes' of https://github.com/chasonr/NetHack into NetHack-5.0
This commit is contained in:
+20
-9
@@ -1952,9 +1952,11 @@ wiz_custom(void)
|
|||||||
|
|
||||||
win = create_nhwindow(NHW_MENU);
|
win = create_nhwindow(NHW_MENU);
|
||||||
start_menu(win, MENU_BEHAVE_STANDARD);
|
start_menu(win, MENU_BEHAVE_STANDARD);
|
||||||
add_menu_heading(win,
|
const char *heading = iflags.menu_tab_sep
|
||||||
" glyph glyph identifier "
|
? "glyph\tglyph identifier\tsym\tclr\tcustomcolor\tunicode\tutf8"
|
||||||
" sym clr customcolor unicode utf8");
|
: " glyph glyph identifier "
|
||||||
|
" sym clr customcolor unicode utf8";
|
||||||
|
add_menu_heading(win, heading);
|
||||||
Sprintf(bufa, "%s: colorcount=%ld %s", wizcustom,
|
Sprintf(bufa, "%s: colorcount=%ld %s", wizcustom,
|
||||||
(long) iflags.colorcount,
|
(long) iflags.colorcount,
|
||||||
gs.symset[PRIMARYSET].name ? gs.symset[PRIMARYSET].name
|
gs.symset[PRIMARYSET].name ? gs.symset[PRIMARYSET].name
|
||||||
@@ -2001,26 +2003,35 @@ wizcustom_callback(winid win, int glyphnum, char *id)
|
|||||||
cgm->u ||
|
cgm->u ||
|
||||||
#endif
|
#endif
|
||||||
cgm->customcolor != 0) {
|
cgm->customcolor != 0) {
|
||||||
Sprintf(bufa, "[%04d] %-44s", glyphnum, id);
|
if (iflags.menu_tab_sep) {
|
||||||
Sprintf(bufb, "'\\%03d' %02d",
|
Sprintf(bufa, "[%04d]\t%s\t", glyphnum, id);
|
||||||
gs.showsyms[cgm->sym.symidx], cgm->sym.color);
|
Sprintf(bufb, "'\\%03d'\t%02d\t",
|
||||||
Sprintf(bufc, "%011lx", (unsigned long) cgm->customcolor);
|
gs.showsyms[cgm->sym.symidx], cgm->sym.color);
|
||||||
|
Sprintf(bufc, "%011lx\t", (unsigned long) cgm->customcolor);
|
||||||
|
} else {
|
||||||
|
Sprintf(bufa, "[%04d] %-45s", glyphnum, id);
|
||||||
|
Sprintf(bufb, "'\\%03d' %02d ",
|
||||||
|
gs.showsyms[cgm->sym.symidx], cgm->sym.color);
|
||||||
|
Sprintf(bufc, "%011lx ", (unsigned long) cgm->customcolor);
|
||||||
|
}
|
||||||
bufu[0] = '\0';
|
bufu[0] = '\0';
|
||||||
#ifdef ENHANCED_SYMBOLS
|
#ifdef ENHANCED_SYMBOLS
|
||||||
if (cgm->u && cgm->u->utf8str) {
|
if (cgm->u && cgm->u->utf8str) {
|
||||||
uint8 *cp;
|
uint8 *cp;
|
||||||
|
char sep = iflags.menu_tab_sep ? '\t' : ' ';
|
||||||
Sprintf(bufu, "U+%04lx", (unsigned long) cgm->u->utf32ch);
|
Sprintf(bufu, "U+%04lx", (unsigned long) cgm->u->utf32ch);
|
||||||
cp = cgm->u->utf8str;
|
cp = cgm->u->utf8str;
|
||||||
while (*cp) {
|
while (*cp) {
|
||||||
char bufd[BUFSZ];
|
char bufd[BUFSZ];
|
||||||
Sprintf(bufd, " <%d>", (int) *cp);
|
Sprintf(bufd, "%c<%d>", sep, (int) *cp);
|
||||||
Strcat(bufu, bufd);
|
Strcat(bufu, bufd);
|
||||||
cp++;
|
cp++;
|
||||||
|
sep = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
any.a_int = glyphnum + 1; /* avoid 0 */
|
any.a_int = glyphnum + 1; /* avoid 0 */
|
||||||
Snprintf(buf, sizeof buf, "%s %s %s %s", bufa, bufb, bufc, bufu);
|
Snprintf(buf, sizeof buf, "%s%s%s%s", bufa, bufb, bufc, bufu);
|
||||||
add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf,
|
add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf,
|
||||||
MENU_ITEMFLAGS_NONE);
|
MENU_ITEMFLAGS_NONE);
|
||||||
}
|
}
|
||||||
|
|||||||
+76
-7
@@ -54,6 +54,7 @@ enum { font_bold = 1, font_italic = 2 };
|
|||||||
static boolean check_label(Widget);
|
static boolean check_label(Widget);
|
||||||
static void delete_callback(Widget, XtPointer, XtPointer);
|
static void delete_callback(Widget, XtPointer, XtPointer);
|
||||||
static void update_label(Widget, WidgetData *);
|
static void update_label(Widget, WidgetData *);
|
||||||
|
static void set_tab_stops(Widget, WidgetData *, const char *);
|
||||||
static void allocate_font(Widget, WidgetData *, unsigned);
|
static void allocate_font(Widget, WidgetData *, unsigned);
|
||||||
static void free_fonts(Widget, WidgetData *);
|
static void free_fonts(Widget, WidgetData *);
|
||||||
|
|
||||||
@@ -242,6 +243,11 @@ update_label(Widget w, WidgetData *data)
|
|||||||
attrs |= HL_DIM;
|
attrs |= HL_DIM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the tab stops if needed */
|
||||||
|
if (data->columns == NULL && strchr(label, '\t') != NULL) {
|
||||||
|
set_tab_stops(w, data, label);
|
||||||
|
}
|
||||||
|
|
||||||
/* Dimensions of pixmap */
|
/* Dimensions of pixmap */
|
||||||
Dimension width;
|
Dimension width;
|
||||||
Dimension height;
|
Dimension height;
|
||||||
@@ -496,6 +502,66 @@ update_label(Widget w, WidgetData *data)
|
|||||||
data->pixmap = new_pixmap;
|
data->pixmap = new_pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set tab stops for text window */
|
||||||
|
static void
|
||||||
|
set_tab_stops(Widget w, WidgetData *data, const char *label)
|
||||||
|
{
|
||||||
|
/* Count columns */
|
||||||
|
unsigned col = 0;
|
||||||
|
unsigned num_cols = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
while (label[i] != '\0') {
|
||||||
|
size_t len = strcspn(label + i, "\t\n");
|
||||||
|
++col;
|
||||||
|
i += len;
|
||||||
|
if (label[i] != '\t') {
|
||||||
|
/* The last column on its line */
|
||||||
|
num_cols = max(num_cols, col);
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
if (label[i] != '\0') {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int *columns = (int *) alloc(num_cols * sizeof(columns[0]));
|
||||||
|
memset(columns, 0, num_cols * sizeof(columns[0]));
|
||||||
|
|
||||||
|
/* Determine column sizes */
|
||||||
|
col = 0;
|
||||||
|
i = 0;
|
||||||
|
Display *display = XtDisplay(w);
|
||||||
|
while (label[i] != '\0') {
|
||||||
|
size_t len = strcspn(label + i, "\t\n");
|
||||||
|
if (label[i+len] == '\t') {
|
||||||
|
/* A column from label+i to label+i+len */
|
||||||
|
int width = X11_column_width(display, data->font[0], label + i, len);
|
||||||
|
columns[col] = max(columns[col], width);
|
||||||
|
++col;
|
||||||
|
} else {
|
||||||
|
/* Last column of the line */
|
||||||
|
/* This does not participate in sizing the column */
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
i += len;
|
||||||
|
if (label[i] != '\0') {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert to column positions */
|
||||||
|
int pos = 0;
|
||||||
|
for (unsigned j = 0; j < num_cols; ++j) {
|
||||||
|
int rpos = pos + columns[j];
|
||||||
|
columns[j] = pos;
|
||||||
|
pos = rpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data->columns);
|
||||||
|
data->columns = columns;
|
||||||
|
data->num_cols = num_cols;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a bold or italic font */
|
/* Allocate a bold or italic font */
|
||||||
static void
|
static void
|
||||||
allocate_font(Widget w, WidgetData *data, unsigned font_idx)
|
allocate_font(Widget w, WidgetData *data, unsigned font_idx)
|
||||||
@@ -610,9 +676,9 @@ typedef struct WidgetBucket {
|
|||||||
WidgetData *data;
|
WidgetData *data;
|
||||||
} WidgetBucket;
|
} WidgetBucket;
|
||||||
|
|
||||||
#define MAX_WIDGETS 1024
|
static WidgetBucket *widget_table = NULL;
|
||||||
static WidgetBucket widget_table[MAX_WIDGETS];
|
static unsigned num_widgets = 0;
|
||||||
static unsigned num_widgets;
|
static unsigned max_widgets = 0;
|
||||||
|
|
||||||
/* bsearch compare function to search widget-table */
|
/* bsearch compare function to search widget-table */
|
||||||
static int
|
static int
|
||||||
@@ -653,9 +719,12 @@ get_widget_data(Widget w)
|
|||||||
static WidgetData *
|
static WidgetData *
|
||||||
add_widget(Widget w)
|
add_widget(Widget w)
|
||||||
{
|
{
|
||||||
/* Panic rather than overflow the array */
|
/* If the array is full (or unallocated), add some new space to it */
|
||||||
if (num_widgets >= MAX_WIDGETS) {
|
if (num_widgets >= max_widgets) {
|
||||||
panic("Widget table is full\n");
|
max_widgets = num_widgets + 1024;
|
||||||
|
widget_table = (WidgetBucket *) re_alloc(
|
||||||
|
(long *) widget_table,
|
||||||
|
max_widgets * sizeof(widget_table[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the widget into the table, maintaining its order */
|
/* Insert the widget into the table, maintaining its order */
|
||||||
@@ -688,7 +757,7 @@ delete_widget(Widget w)
|
|||||||
|
|
||||||
/* Remove the widget from the table */
|
/* Remove the widget from the table */
|
||||||
for (unsigned i = (unsigned)(bucket - widget_table);
|
for (unsigned i = (unsigned)(bucket - widget_table);
|
||||||
i + 1 < MAX_WIDGETS;
|
i + 1 < num_widgets;
|
||||||
++i) {
|
++i) {
|
||||||
widget_table[i] = widget_table[i+1];
|
widget_table[i] = widget_table[i+1];
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -1320,12 +1320,10 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu)
|
|||||||
|
|
||||||
/* Does any line have a selector? */
|
/* Does any line have a selector? */
|
||||||
boolean any_canpick = FALSE;
|
boolean any_canpick = FALSE;
|
||||||
if (how != PICK_NONE) {
|
for (curr = curr_menu->base; curr; curr = curr->next) {
|
||||||
for (curr = curr_menu->base; curr; curr = curr->next) {
|
if (curr->identifier.a_void != NULL) {
|
||||||
if (curr->identifier.a_void != NULL) {
|
any_canpick = TRUE;
|
||||||
any_canpick = TRUE;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1342,7 +1340,7 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu)
|
|||||||
String str = (String) curr->str;
|
String str = (String) curr->str;
|
||||||
int attr = ATR_NONE;
|
int attr = ATR_NONE;
|
||||||
int color = NO_COLOR;
|
int color = NO_COLOR;
|
||||||
boolean canpick = (how != PICK_NONE && curr->identifier.a_void);
|
boolean canpick = curr->identifier.a_void != NULL;
|
||||||
|
|
||||||
/* Add tabs if needed to align non-selector lines with selector lines */
|
/* Add tabs if needed to align non-selector lines with selector lines */
|
||||||
if (any_canpick && !canpick) {
|
if (any_canpick && !canpick) {
|
||||||
|
|||||||
+32
-6
@@ -520,16 +520,42 @@ redraw_message_window(struct xwindow *wp)
|
|||||||
|
|
||||||
for (y_base = row = 0, curr = mesg_info->head; row < mesg_info->num_lines;
|
for (y_base = row = 0, curr = mesg_info->head; row < mesg_info->num_lines;
|
||||||
row++, y_base += mesg_info->char_height, curr = curr->next) {
|
row++, y_base += mesg_info->char_height, curr = curr->next) {
|
||||||
#ifdef USE_XFT
|
if (curr->line == NULL) {
|
||||||
if (curr->line != NULL) {
|
continue;
|
||||||
XftDrawString8(draw, &fgcolor, font,
|
|
||||||
mesg_info->char_lbearing, mesg_info->char_ascent + y_base,
|
|
||||||
(const FcChar8 *) curr->line, curr->str_length);
|
|
||||||
}
|
}
|
||||||
|
/* Deal with any tabs in the output. These will just be single strings,
|
||||||
|
* not needing to align columns, so just convert to spaces */
|
||||||
|
const char *str = curr->line;
|
||||||
|
int str_length = curr->str_length;
|
||||||
|
char buf[BUFSZ];
|
||||||
|
if (memchr(str, '\t', str_length) != NULL) {
|
||||||
|
int i2 = 0;
|
||||||
|
for (int i1 = 0; i1 < str_length; ++i1) {
|
||||||
|
if (str[i1] == '\t') {
|
||||||
|
if (i2 + 4 > BUFSZ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(buf + i2, " ", 4);
|
||||||
|
i2 += 4;
|
||||||
|
} else {
|
||||||
|
if (i2 >= BUFSZ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[i2++] = str[i1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* buf does not need to be null terminated */
|
||||||
|
str = buf;
|
||||||
|
str_length = i2;
|
||||||
|
}
|
||||||
|
#ifdef USE_XFT
|
||||||
|
XftDrawString8(draw, &fgcolor, font,
|
||||||
|
mesg_info->char_lbearing, mesg_info->char_ascent + y_base,
|
||||||
|
(const FcChar8 *) str, str_length);
|
||||||
#else /* !USE_XFT */
|
#else /* !USE_XFT */
|
||||||
XDrawString(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc,
|
XDrawString(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc,
|
||||||
mesg_info->char_lbearing, mesg_info->char_ascent + y_base,
|
mesg_info->char_lbearing, mesg_info->char_ascent + y_base,
|
||||||
curr->line, curr->str_length);
|
str, str_length);
|
||||||
#endif /* ?USE_XFT */
|
#endif /* ?USE_XFT */
|
||||||
/*
|
/*
|
||||||
* This draws a line at the _top_ of the line of text pointed to by
|
* This draws a line at the _top_ of the line of text pointed to by
|
||||||
|
|||||||
+2
-2
@@ -170,7 +170,7 @@ display_text_window(struct xwindow *wp, boolean blocking)
|
|||||||
XtSetArg(args[num_args], XtNlabel, text_info->text.text);
|
XtSetArg(args[num_args], XtNlabel, text_info->text.text);
|
||||||
num_args++;
|
num_args++;
|
||||||
XtSetValues(wp->w, args, num_args);
|
XtSetValues(wp->w, args, num_args);
|
||||||
X11_update_label_if_Xft(wp->w);
|
X11_update_label(wp->w);
|
||||||
|
|
||||||
#ifdef TRANSIENT_TEXT
|
#ifdef TRANSIENT_TEXT
|
||||||
XtRealizeWidget(wp->popup);
|
XtRealizeWidget(wp->popup);
|
||||||
@@ -259,7 +259,7 @@ create_text_window(struct xwindow *wp)
|
|||||||
form, /* parent widget */
|
form, /* parent widget */
|
||||||
args, /* set some values */
|
args, /* set some values */
|
||||||
num_args); /* number of values to set */
|
num_args); /* number of values to set */
|
||||||
X11_wrap_widget_if_Xft(wp->w, NHW_TEXT);
|
X11_wrap_widget(wp->w, NHW_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user