From 0ee7eef3eff49650d8d17642d8a6446db2261533 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Tue, 11 Aug 2026 12:25:02 -0400 Subject: [PATCH] Implement a hit point bar --- include/winX.h | 2 ++ win/X11/winlabel.c | 36 +++++++++++++++++++++++++++++---- win/X11/winstat.c | 50 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/include/winX.h b/include/winX.h index 2bd73d679..5c97ee5ff 100644 --- a/include/winX.h +++ b/include/winX.h @@ -523,5 +523,7 @@ extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); /* Functions for management of enhanced labels */ extern void X11_wrap_widget(Widget); extern void X11_update_label(Widget); +extern void X11_set_attrs(Widget, unsigned); +extern void X11_set_percent(Widget, unsigned, Pixel); #endif /* WINX_H */ diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c index 476bedcdd..a9e56d915 100644 --- a/win/X11/winlabel.c +++ b/win/X11/winlabel.c @@ -85,8 +85,6 @@ X11_wrap_widget(Widget w) /* Create the pixmap for the first time */ update_label(w, data); - - return w; } /* Callback when the widget is deleted */ @@ -124,8 +122,29 @@ check_label(Widget w) void X11_update_label(Widget w) { - if (check_label(w)) { - WidgetData *data = get_widget_data(w); + WidgetData *data = get_widget_data(w); + if (data != NULL) { + update_label(w, data); + } +} + +void +X11_set_attrs(Widget w, unsigned attrs) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->attrs = attrs; + update_label(w, data); + } +} + +void +X11_set_percent(Widget w, unsigned percent, Pixel color) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->percent = percent; + data->bar_color = color; update_label(w, data); } } @@ -216,6 +235,15 @@ update_label(Widget w, WidgetData *data) width = max(width, 1); height = max(height, 1); + /* Use the full width of the widget if a percentage bar is set */ + if (data->percent != 0) { + Dimension wwidth; + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + width = max(width, wwidth); + } + /* Create the pixmap */ new_pixmap = XCreatePixmap(display, RootWindowOfScreen(screen), width, height, depth); diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 304be9579..64ca38a02 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -110,6 +110,7 @@ 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 set_percent(int, int, int); static void tty_status_exposed(Widget, XtPointer, XtPointer); #ifdef STATUS_HILITES static void tty_status_blink(XtPointer client_data, XtIntervalId *timer); @@ -390,7 +391,7 @@ static void X11_status_update_fancy( int fld, genericptr_t ptr, - int chg UNUSED, int percent UNUSED, + int chg UNUSED, int percent, int colrattr, unsigned long *colormasks UNUSED) { @@ -480,6 +481,11 @@ X11_status_update_fancy( update_fancy_status_field(bl_to_fancyfield[i].ff, colr, attr); break; } + + /* Hit point bar */ + if (fld == BL_HP) { + set_percent(F_NAME, iflags.wc2_hitpointbar ? percent : 0, colr); + } } } @@ -1221,6 +1227,7 @@ static void hilight_label(Widget); static void update_val(struct X_status_value *, long); static void skip_cond_val(struct X_status_value *); static void update_color(struct X_status_value *, int); +static Pixel color_to_pixel(Widget, int); static boolean name_widget_has_label(struct X_status_value *); static void apply_hilite_attributes(struct X_status_value *, int); static const char *width_string(int); @@ -1667,8 +1674,6 @@ update_color(struct X_status_value *sv, int color) { Pixel pixel = 0; Arg args[1]; - XrmValue source; - XrmValue dest; Widget w = (sv->type == SV_LABEL || sv->type == SV_NAME) ? sv->w : get_value_widget(sv->w); @@ -1677,12 +1682,8 @@ update_color(struct X_status_value *sv, int color) pixel = sv->default_fg; sv->colr = NO_COLOR; } else { - source.addr = (XPointer) fancy_status_hilite_colors[color]; - source.size = (unsigned int) strlen((const char *) source.addr) + 1; - dest.size = (unsigned int) sizeof (Pixel); - dest.addr = (XPointer) &pixel; - if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) - sv->colr = color; + pixel = color_to_pixel(w, color); + sv->colr = color; } if (pixel != 0) { char *arg_name = (sv->set || sv->inverted_hilite) ? XtNbackground @@ -1694,6 +1695,30 @@ update_color(struct X_status_value *sv, int color) } } +static Pixel +color_to_pixel(Widget w, int color) +{ + Pixel pixel; + + if (fancy_status_hilite_colors[color][0] != '\0') { + XrmValue source; + XrmValue dest; + source.addr = (XPointer) fancy_status_hilite_colors[color]; + source.size = (unsigned int) strlen((const char *) source.addr) + 1; + dest.size = (unsigned int) sizeof (Pixel); + dest.addr = (XPointer) &pixel; + if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) { + return pixel; + } + } + + pixel = 0xFFFFFF; + Arg args[1]; + XtSetArg(args[0], XtNforeground, &pixel); + XtGetValues(toplevel, args, ONE); + return pixel; +} + static boolean name_widget_has_label(struct X_status_value *sv) { @@ -1728,6 +1753,13 @@ apply_hilite_attributes(struct X_status_value *sv, int attributes) and each other attribute into its own to keep the code clean. */ } +static void +set_percent(int index, int percent, int color) +{ + Widget w = shown_stats[index].w; + X11_set_percent(w, percent, color_to_pixel(w, color)); +} + /* * Update the displayed status. The current code in botl.c updates * two lines of information. Both lines are always updated one after