# https://invisible-island.net/archives/xterm/patches/xterm-384.patch.gz
# patch by Thomas E. Dickey <dickey@invisible-island.net>
# created  Mon Jul 10 23:18:08 UTC 2023
# ------------------------------------------------------------------------------
# MANIFEST                 |    2 
# charproc.c               |    5 +
# fontutils.c              |    6 +-
# graphics.c               |   88 +++++++++++++++++++++++++++++++---
# graphics.h               |    9 ++-
# graphics_regis.c         |  116 +++++++++++++++++++++++++++++++++------------
# graphics_regis.h         |    8 +--
# package/debian/changelog |    6 ++
# package/freebsd/Makefile |    4 -
# package/pkgsrc/Makefile  |    2 
# package/xterm.spec       |    4 -
# util.c                   |   18 +++---
# version.h                |    6 +-
# xterm.appdata.xml        |    2 
# xterm.log.html           |   30 +++++++++++
# 15 files changed, 239 insertions(+), 67 deletions(-)
# ------------------------------------------------------------------------------
Index: MANIFEST
--- xterm-383+/MANIFEST	2023-05-31 17:04:55.000000000 +0000
+++ xterm-384/MANIFEST	2023-06-29 22:22:58.000000000 +0000
@@ -1,4 +1,4 @@
-MANIFEST for xterm, version xterm-383
+MANIFEST for xterm, version xterm-384
 --------------------------------------------------------------------------------
 MANIFEST                        this file
 256colres.h                     resource-definitions for 256-color mode
Index: charproc.c
--- xterm-383+/charproc.c	2023-06-26 22:28:07.000000000 +0000
+++ xterm-384/charproc.c	2023-07-10 15:53:46.000000000 +0000
@@ -1,4 +1,4 @@
-/* $XTermId: charproc.c,v 1.1957 2023/06/26 22:28:07 tom Exp $ */
+/* $XTermId: charproc.c,v 1.1958 2023/07/10 15:53:46 tom Exp $ */
 
 /*
  * Copyright 1999-2022,2023 by Thomas E. Dickey
@@ -11220,6 +11220,9 @@
 	free(last->windowName);
 	free(last);
     }
+#if OPT_STATUS_LINE
+    free(screen->status_fmt);
+#endif
 #ifndef NO_ACTIVE_ICON
     TRACE_FREE_LEAK(xw->misc.active_icon_s);
 #endif
Index: fontutils.c
--- xterm-383+/fontutils.c	2023-06-13 21:45:38.000000000 +0000
+++ xterm-384/fontutils.c	2023-07-10 19:01:33.000000000 +0000
@@ -1,4 +1,4 @@
-/* $XTermId: fontutils.c,v 1.775 2023/06/13 21:45:38 tom Exp $ */
+/* $XTermId: fontutils.c,v 1.776 2023/07/10 19:01:33 tom Exp $ */
 
 /*
  * Copyright 1998-2022,2023 by Thomas E. Dickey
@@ -4134,7 +4134,9 @@
 			   CapProjecting,
 			   JoinMiter);
 
-    if (ch == 1) {		/* diamond */
+    if (ch == 32) {		/* space! */
+	;			/* boxing a missing space is pointless */
+    } else if (ch == 1) {	/* diamond */
 	XPoint points[5];
 	int npoints = 5, n;
 
Index: graphics.c
--- xterm-383+/graphics.c	2022-05-16 23:35:50.000000000 +0000
+++ xterm-384/graphics.c	2023-07-10 00:22:25.000000000 +0000
@@ -1,8 +1,8 @@
-/* $XTermId: graphics.c,v 1.118 2022/05/16 23:35:50 tom Exp $ */
+/* $XTermId: graphics.c,v 1.122 2023/07/10 00:22:25 tom Exp $ */
 
 /*
- * Copyright 2013-2021,2022 by Ross Combs
- * Copyright 2013-2021,2022 by Thomas E. Dickey
+ * Copyright 2013-2022,2023 by Ross Combs
+ * Copyright 2013-2022,2023 by Thomas E. Dickey
  *
  *                         All Rights Reserved
  *
@@ -43,6 +43,10 @@
 #include <assert.h>
 #include <graphics.h>
 
+#if OPT_REGIS_GRAPHICS
+#include <graphics_regis.h>
+#endif
+
 #undef DUMP_BITMAP
 #undef DUMP_COLORS
 #undef DEBUG_PALETTE
@@ -413,6 +417,26 @@
 }
 
 void
+fetch_color_register(Graphic *graphic,
+		     unsigned color,
+		     ColorRegister *reg)
+{
+    assert(color < MAX_COLOR_REGISTERS);
+
+    reg->r = -1;
+    reg->g = -1;
+    reg->b = -1;
+
+    if (graphic->color_registers_used[color]) {
+	if (graphic->private_colors) {
+	    *reg = graphic->private_color_registers[color];
+	} else {
+	    *reg = getSharedRegisters()[color];
+	}
+    }
+}
+
+void
 update_color_register(Graphic *graphic,
 		      unsigned color,
 		      int r,
@@ -944,6 +968,8 @@
 	   holes, total, out_of_range));
 }
 
+#define MAX_RGB 100.		/* use this rather than 255 */
+
 /*
  * Primary color hues:
  *  blue:    0 degrees
@@ -954,8 +980,8 @@
 hls2rgb(int h, int l, int s, short *r, short *g, short *b)
 {
     const int hs = ((h + 240) / 60) % 6;
-    const double lv = l / 100.0;
-    const double sv = s / 100.0;
+    const double lv = l / MAX_RGB;
+    const double sv = s / MAX_RGB;
     double c, x, m, c2;
     double r1, g1, b1;
 
@@ -1010,9 +1036,9 @@
 	return;
     }
 
-    *r = (short) ((r1 + m) * 100.0 + 0.5);
-    *g = (short) ((g1 + m) * 100.0 + 0.5);
-    *b = (short) ((b1 + m) * 100.0 + 0.5);
+    *r = (short) ((r1 + m) * MAX_RGB + 0.5);
+    *g = (short) ((g1 + m) * MAX_RGB + 0.5);
+    *b = (short) ((b1 + m) * MAX_RGB + 0.5);
 
     if (*r < 0)
 	*r = 0;
@@ -1029,6 +1055,49 @@
 }
 
 void
+rgb2hls(int r, int g, int b, short *h, short *l, short *s)
+{
+    const double scaled_r = (r / MAX_RGB);
+    const double scaled_g = (g / MAX_RGB);
+    const double scaled_b = (b / MAX_RGB);
+
+    const double min_scale = Min(Min(scaled_r, scaled_g), scaled_b);
+    const double max_scale = Max(Max(scaled_r, scaled_g), scaled_b);
+    const double dif_scale = max_scale - min_scale;
+
+    double h_work = 0.;
+    double s_work = 0.;
+    double l_work = ((max_scale + min_scale) / 2.);
+
+    if (dif_scale != 0.) {
+	if (l_work < 0.5f) {
+	    s_work = (dif_scale / (max_scale + min_scale));
+	} else {
+	    s_work = (dif_scale / (2. - max_scale - min_scale));
+	}
+
+	if (scaled_r == max_scale) {
+	    h_work = (scaled_g - scaled_b) / dif_scale;
+	} else if (scaled_g == max_scale) {
+	    h_work = 2. + (scaled_b - scaled_r) / dif_scale;
+	} else if (scaled_b == max_scale) {
+	    h_work = 4. + (scaled_r - scaled_g) / dif_scale;
+	}
+    }
+
+    h_work *= 60.;
+    if (h_work < 0)
+	h_work += 360.;
+
+    s_work *= MAX_RGB;
+    l_work *= MAX_RGB;
+
+    *h = (short) h_work;
+    *s = (short) s_work;
+    *l = (short) l_work;
+}
+
+void
 dump_graphic(Graphic const *graphic)
 {
 #if defined(DUMP_COLORS) || defined(DUMP_BITMAP)
@@ -1754,6 +1823,9 @@
 	FOR_EACH_SLOT(ii) {
 	    deactivateSlot(ii);
 	}
+#if OPT_REGIS_GRAPHICS
+	reset_regis();
+#endif
     }
 }
 
Index: graphics.h
--- xterm-383+/graphics.h	2022-02-22 23:36:19.000000000 +0000
+++ xterm-384/graphics.h	2023-07-09 21:23:28.000000000 +0000
@@ -1,8 +1,8 @@
-/* $XTermId: graphics.h,v 1.29 2022/02/22 23:36:19 tom Exp $ */
+/* $XTermId: graphics.h,v 1.31 2023/07/09 21:23:28 tom Exp $ */
 
 /*
- * Copyright 2013-2016,2022 by Ross Combs
- * Copyright 2013-2016,2022 by Thomas E. Dickey
+ * Copyright 2013-2022,2023 by Ross Combs
+ * Copyright 2013-2022,2023 by Thomas E. Dickey
  *
  *                         All Rights Reserved
  *
@@ -93,8 +93,10 @@
 extern void draw_solid_rectangle(Graphic */* graphic */, int /* x1 */, int /* y1 */, int /* x2 */, int /* y2 */, unsigned /* color */);
 extern void copy_overlapping_area(Graphic */* graphic */, int /* src_x */, int /* src_y */, int /* dst_x */, int /* dst_y */, unsigned /* w */, unsigned /* h */, unsigned /* default_color */);
 extern void hls2rgb(int /* h */, int /* l */, int /* s */, short */* r */, short */* g */, short */* b */);
+extern void rgb2hls(int /* r */, int /* g */, int /* b */, short */* h */, short */* l */, short */* s */);
 extern void dump_graphic(Graphic const */* graphic */);
 extern unsigned get_color_register_count(TScreen const */* screen */);
+extern void fetch_color_register(Graphic */* graphic */, unsigned /* color */, ColorRegister* /* reg */);
 extern void update_color_register(Graphic */* graphic */, unsigned /* color */, int /* r */, int /* g */, int /* b */);
 extern RegisterNum find_color_register(ColorRegister const */* color_registers */, int /* r */, int /* g */, int /* b */);
 extern void chararea_clear_displayed_graphics(TScreen const */* screen */, int /* leftcol */, int /* toprow */, int /* ncols */, int /* nrows */);
@@ -117,6 +119,7 @@
 #define draw_solid_rectangle(graphic, x1, y1, x2, y2, color) /* nothing */
 #define copy_overlapping_area(graphic, src_x, src_y, dst_x, dst_y, w, h, default_color) /* nothing */
 #define hls2rgb(h, l, s, r, g, b) /* nothing */
+#define rgb2hls(r, g, b, h, l, s) /* nothing */
 #define dump_graphic(graphic) /* nothing */
 #define get_color_register_count(screen) /* nothing */
 #define update_color_register(graphic, color, r, g, b) /* nothing */
Index: graphics_regis.c
--- xterm-383+/graphics_regis.c	2023-03-08 01:06:03.000000000 +0000
+++ xterm-384/graphics_regis.c	2023-07-10 00:09:54.000000000 +0000
@@ -1,4 +1,4 @@
-/* $XTermId: graphics_regis.c,v 1.139 2023/03/08 01:06:03 tom Exp $ */
+/* $XTermId: graphics_regis.c,v 1.142 2023/07/10 00:09:54 tom Exp $ */
 
 /*
  * Copyright 2014-2022,2023 by Ross Combs
@@ -3460,33 +3460,56 @@
     return 1;
 }
 
+#define spec_H xBIT(0)
+#define spec_L xBIT(1)
+#define spec_S xBIT(2)
+
+#define spec_HLS (spec_H | spec_L | spec_S)
+
+#define spec_R xBIT(3)
+#define spec_G xBIT(4)
+#define spec_B xBIT(5)
+
+#define spec_RGB (spec_R | spec_G | spec_B)
+
 static int
 load_regis_colorspec(RegisGraphicsContext const *context,
 		     RegisDataFragment const *input,
-		     short *r_out, short *g_out, short *b_out)
+		     ColorRegister *colors)
 {
     RegisDataFragment colorspec;
-    short r = -1, g = -1, b = -1;
+    short r = colors->r;
+    short g = colors->g;
+    short b = colors->b;
     short l = -1;
     int simple;
+    unsigned len;
+    unsigned spec = 0;
 
     assert(context);
     assert(input);
-    assert(r_out);
-    assert(g_out);
-    assert(b_out);
+    assert(colors);
 
     copy_fragment(&colorspec, input);
     TRACE(("colorspec option: \"%s\"\n", fragment_to_tempstr(&colorspec)));
 
     skip_regis_whitespace(&colorspec);
     simple = 0;
-    if (fragment_remaining(&colorspec) == 1U) {
+    if ((len = fragment_remaining(&colorspec)) == 1U) {
 	simple = 1;
-    } else if (fragment_remaining(&colorspec) > 1U) {
-	char after = get_fragment(&colorspec, 1U);
-	if (IsSpace(after))
-	    simple = 1;
+    } else if (len > 1U) {
+	unsigned n;
+	for (n = 1; n < len; ++n) {
+	    char after = get_fragment(&colorspec, n);
+	    /* if no parameters, we might see a right-parenthesis, but on error
+	     * we can anything */
+	    if (strchr("[(,)]", after) != NULL) {
+		simple = 1;
+		break;
+	    } else if (!IsSpace(after)) {
+		break;
+	    }
+	}
     }
     if (simple) {
 	char ch = pop_fragment(&colorspec);
@@ -3628,38 +3651,56 @@
 	    switch (comp) {
 	    case 'H':
 		h = (short) val;
+		spec |= spec_H;
 		break;
 	    case 'L':
 		l = (short) val;
+		spec |= spec_L;
 		break;
 	    case 'S':
 		s = (short) val;
+		spec |= spec_S;
 		break;
 	    case 'R':
 		r = (short) val;
+		spec |= spec_R;
 		break;
 	    case 'G':
 		g = (short) val;
+		spec |= spec_G;
 		break;
 	    case 'B':
 		b = (short) val;
+		spec |= spec_B;
 		break;
 	    }
 	}
 
-	if (h >= 0 && l >= 0 && s >= 0 && r < 0 && g < 0 && b < 0) {
+	if ((spec & spec_HLS) && (spec & spec_RGB)) {
+	    TRACE(("DATA_ERROR: conflicting colorspec format\n"));
+	    return 0;
+	} else if (spec == spec_HLS) {
 	    TRACE(("found HLS colorspec to be converted: %hd,%hd,%hd\n",
 		   h, l, s));
 	    hls2rgb(h, l, s, &r, &g, &b);
 	    TRACE(("converted to RGB: %hd,%hd,%hd\n", r, g, b));
-	} else if (h < 0 && l < 0 && s < 0 && r >= 0 && g >= 0 && b >= 0) {
+	} else if (spec == spec_RGB) {
 	    TRACE(("found RGB colorspec: %hd,%hd,%hd\n", r, g, b));
 	    l = (short) ((MIN3(r, g, b) + MAX3(r, g, b)) / 2);
 	    TRACE(("calculated L: %d\n", l));
-	} else if (h < 0 && l >= 0 && s < 0 && r < 0 && g < 0 && b < 0) {
-	    TRACE(("found L colorspec to be converted: %hd,%hd,%hd\n",
+	} else if ((spec & spec_HLS)) {
+	    short old_h, old_l, old_s;
+	    TRACE(("using partial HLS %hd,%hd,%hd\n", h, l, s));
+	    rgb2hls(r, g, b, &old_h, &old_l, &old_s);
+	    if (h < 0)
+		h = old_h;
+	    if (l < 0)
+		l = old_l;
+	    if (s < 0)
+		s = old_s;
+	    TRACE(("resulting HLS colorspec to convert: %hd,%hd,%hd\n",
 		   h, l, s));
-	    hls2rgb(0, l, 0, &r, &g, &b);
+	    hls2rgb(h, l, s, &r, &g, &b);
 	    TRACE(("converted to RGB: %hd,%hd,%hd\n", r, g, b));
 	} else {
 	    TRACE(("DATA_ERROR: unrecognized colorspec format\n"));
@@ -3675,9 +3716,9 @@
 	TRACE(("converted to grayscale: %hd,%hd,%hd\n", r, g, b));
     }
 
-    *r_out = r;
-    *g_out = g;
-    *b_out = b;
+    colors->r = r;
+    colors->g = g;
+    colors->b = b;
 
     skip_regis_whitespace(&colorspec);
     if (!fragment_consumed(&colorspec)) {
@@ -3744,15 +3785,16 @@
     }
 
     if (extract_regis_parenthesized_data(&colorspec, &coloroption)) {
-	short r, g, b;
+	ColorRegister find_reg =
+	{-1, -1, -1};
 
-	if (!load_regis_colorspec(context, &coloroption, &r, &g, &b)) {
+	if (!load_regis_colorspec(context, &coloroption, &find_reg)) {
 	    TRACE(("unable to parse colorspec\n"));
 	    return 0;
 	}
 
 	*out = find_color_register(context->destination_graphic->color_registers,
-				   r, g, b);
+				   find_reg.r, find_reg.g, find_reg.b);
 	TRACE(("colorspec maps to closest register %u\n", *out));
 
 	return 1;
@@ -6087,7 +6129,7 @@
 		    if (extract_regis_num(&optionarg, &regnum)) {
 			int register_num;
 			int color_only;
-			short r, g, b;
+			ColorRegister my_reg;
 
 			if (!regis_num_to_int(&regnum, &register_num)) {
 			    TRACE(("DATA_ERROR: unable to parse int in screen color register mapping option: \"%s\"\n",
@@ -6120,10 +6162,17 @@
 			    break;
 			}
 
-			TRACE(("mapping register %d to color spec: \"%s\"\n",
-			       register_num, fragment_to_tempstr(&colorspec)));
-			if (!load_regis_colorspec(context, &colorspec,
-						  &r, &g, &b)) {
+			fetch_color_register(context->destination_graphic,
+					     (RegisterNum) register_num,
+					     &my_reg);
+
+			TRACE(("mapping register %d %d,%d,%d to color spec: \"%s\"\n",
+			       register_num,
+			       my_reg.r,
+			       my_reg.g,
+			       my_reg.b,
+			       fragment_to_tempstr(&colorspec)));
+			if (!load_regis_colorspec(context, &colorspec, &my_reg)) {
 			    TRACE(("DATA_ERROR: unable to use colorspec for mapping of register %d\n",
 				   register_num));
 			    return 1;
@@ -6133,13 +6182,13 @@
 			    (context->graphics_termid == 240 ||
 			     context->graphics_termid == 330)) {
 			    TRACE(("NOT setting color register %d to %hd,%hd,%hd\n",
-				   register_num, r, g, b));
+				   register_num, my_reg.r, my_reg.g, my_reg.b));
 			} else {
 			    TRACE(("setting color register %d to %hd,%hd,%hd\n",
-				   register_num, r, g, b));
+				   register_num, my_reg.r, my_reg.g, my_reg.b));
 			    update_color_register(context->destination_graphic,
 						  (RegisterNum) register_num,
-						  r, g, b);
+						  my_reg.r, my_reg.g, my_reg.b);
 			}
 			continue;
 		    } {
@@ -7609,6 +7658,13 @@
 }
 
 void
+reset_regis(void)
+{
+    persistent_context.width = 0;
+    persistent_context.height = 0;
+}
+
+void
 parse_regis(XtermWidget xw, ANSI *params, char const *string)
 {
     TScreen *screen = TScreenOf(xw);
Index: graphics_regis.h
--- xterm-383+/graphics_regis.h	2016-05-29 16:34:47.000000000 +0000
+++ xterm-384/graphics_regis.h	2023-07-07 20:10:32.000000000 +0000
@@ -1,8 +1,8 @@
-/* $XTermId: graphics_regis.h,v 1.2 2016/05/29 16:34:47 tom Exp $ */
+/* $XTermId: graphics_regis.h,v 1.3 2023/07/07 20:10:32 tom Exp $ */
 
 /*
- * Copyright 2014,2016 by Ross Combs
- * Copyright 2014,2016 by Thomas E. Dickey
+ * Copyright 2014-2016,2023 by Ross Combs
+ * Copyright 2014-2016,2023 by Thomas E. Dickey
  *
  *                         All Rights Reserved
  *
@@ -38,8 +38,10 @@
 #include <ptyx.h>
 
 #if OPT_REGIS_GRAPHICS
+extern void reset_regis(void);
 extern void parse_regis(XtermWidget /* xw */, ANSI */* params */, char const */* string */);
 #else
+#define reset_regis() /* nothing */
 #define parse_regis(xw, params, string) /* nothing */
 #endif
 
Index: package/debian/changelog
--- xterm-383+/package/debian/changelog	2023-05-31 17:04:55.000000000 +0000
+++ xterm-384/package/debian/changelog	2023-07-01 09:53:42.000000000 +0000
@@ -1,3 +1,9 @@
+xterm-dev (384) unstable; urgency=low
+
+  * maintenance updates
+
+ -- Thomas E. Dickey <dickey@invisible-island.net>  Thu, 29 Jun 2023 18:22:58 -0400
+
 xterm-dev (383) unstable; urgency=low
 
   * maintenance updates
Index: package/freebsd/Makefile
--- xterm-383+/package/freebsd/Makefile	2023-05-31 17:04:55.000000000 +0000
+++ xterm-384/package/freebsd/Makefile	2023-07-01 09:53:42.000000000 +0000
@@ -1,4 +1,4 @@
-# $XTermId: Makefile,v 1.104 2023/05/31 17:04:55 tom Exp $
+# $XTermId: Makefile,v 1.105 2023/07/01 09:53:42 tom Exp $
 # $FreeBSD: head/x11/xterm/Makefile 492827 2019-02-13 06:43:36Z ehaupt $
 
 # This is adapted from the FreeBSD port, installing as "xterm-dev" with
@@ -7,7 +7,7 @@
 # and "make makesum".
 
 PORTNAME=	xterm
-PORTVERSION=	383
+PORTVERSION=	384
 CATEGORIES=	x11
 MASTER_SITES=	ftp://ftp.invisible-island.net/xterm/:src1 \
 		https://invisible-mirror.net/archives/xterm/:src1
Index: package/pkgsrc/Makefile
--- xterm-383+/package/pkgsrc/Makefile	2023-05-31 17:04:55.000000000 +0000
+++ xterm-384/package/pkgsrc/Makefile	2023-07-01 09:53:42.000000000 +0000
@@ -1,6 +1,6 @@
 # $NetBSD: Makefile,v 1.117 2018/03/12 11:18:00 wiz Exp $
 
-DISTNAME=	xterm-383
+DISTNAME=	xterm-384
 PKGREVISION=	1
 CATEGORIES=	x11
 MASTER_SITES=	ftp://ftp.invisible-island.net/xterm/
Index: package/xterm.spec
--- xterm-383+/package/xterm.spec	2023-05-31 17:04:55.000000000 +0000
+++ xterm-384/package/xterm.spec	2023-07-01 09:53:42.000000000 +0000
@@ -1,11 +1,11 @@
-# $XTermId: xterm.spec,v 1.162 2023/05/31 17:04:55 tom Exp $
+# $XTermId: xterm.spec,v 1.163 2023/07/01 09:53:42 tom Exp $
 Summary: X terminal emulator (development version)
 %global my_middle xterm
 %global my_suffix -dev
 %global fullname %{my_middle}%{my_suffix}
 %global my_class XTermDev
 Name: %{fullname}
-Version: 383
+Version: 384
 Release: 1
 License: X11
 Group: User Interface/X
Index: util.c
--- xterm-383+/util.c	2023-05-29 18:16:51.000000000 +0000
+++ xterm-384/util.c	2023-07-10 19:01:33.000000000 +0000
@@ -1,4 +1,4 @@
-/* $XTermId: util.c,v 1.933 2023/05/29 18:16:51 tom Exp $ */
+/* $XTermId: util.c,v 1.936 2023/07/10 19:01:33 tom Exp $ */
 
 /*
  * Copyright 1999-2022,2023 by Thomas E. Dickey
@@ -3864,6 +3864,7 @@
 	/*
 	 * X11 bitmap-fonts are limited to 16-bits.
 	 */
+	assert(ch != HIDDEN_CHAR);
 	if (
 #if OPT_WIDER_ICHAR
 	       (ch > NARROW_ICHAR) ||
@@ -4661,7 +4662,7 @@
 			&& okFont(NormalWFont(screen)))) {
 		    needWide = True;
 		}
-		++dst;
+		mapped[dst++] = ch;
 	    }
 	}
 
@@ -4688,12 +4689,9 @@
 	    }
 
 	    if (useBoldFont && FontIsIncomplete(bold)) {
-		for (src = 0; src < (int) len; src++) {
+		for (src = 0; src < dst; src++) {
 		    IChar ch = mapped[src];
 
-		    if (ch == HIDDEN_CHAR)
-			continue;
-
 		    noBold = IsXtermMissingChar(screen, ch, bold);
 		    if (noBold) {
 			noNorm = IsXtermMissingChar(screen, ch, norm);
@@ -4706,8 +4704,8 @@
 	    }
 	}
 
-	/* FIXME This is probably wrong. But it works. */
-	underline_len = len;
+	/* This is probably wrong. But it works. */
+	underline_len = (Cardinal) dst;
 
 	/* Set the drawing font */
 	if (!(recur.draw_flags & (DOUBLEHFONT | DOUBLEWFONT))) {
@@ -4757,11 +4755,13 @@
 		    NormalFont(screen)->max_bounds.width * 2) {
 		    underline_len = real_length = (Cardinal) (dst * 2);
 		} else if (cgsId == gcWide || cgsId == gcWBold) {
+		    int ascent2 = Max(NormalFont(screen)->ascent,
+				      thisFp->ascent);
 		    underline_len = real_length = (Cardinal) (dst * 2);
 		    xtermFillCells(&recur,
 				   gc,
 				   x,
-				   y - thisFp->ascent,
+				   y - ascent2,
 				   real_length);
 		}
 	    }
Index: version.h
--- xterm-383+/version.h	2023-06-27 08:24:48.000000000 +0000
+++ xterm-384/version.h	2023-07-10 21:10:29.000000000 +0000
@@ -1,4 +1,4 @@
-/* $XTermId: version.h,v 1.545 2023/06/27 08:24:48 tom Exp $ */
+/* $XTermId: version.h,v 1.547 2023/07/10 21:10:29 tom Exp $ */
 
 /*
  * Copyright 1998-2022,2023 by Thomas E. Dickey
@@ -38,8 +38,8 @@
  * version of X to which this version of xterm has been built.  The resulting
  * number in parentheses is my patch number (Thomas E. Dickey).
  */
-#define XTERM_PATCH   383
-#define XTERM_DATE    2023-06-27
+#define XTERM_PATCH   384
+#define XTERM_DATE    2023-07-10
 
 #ifndef __vendorversion__
 #define __vendorversion__ "XTerm"
Index: xterm.appdata.xml
--- xterm-383+/xterm.appdata.xml	2023-06-27 20:59:15.000000000 +0000
+++ xterm-384/xterm.appdata.xml	2023-07-10 21:11:27.000000000 +0000
@@ -35,7 +35,7 @@
     <keyword>terminal</keyword>
   </keywords>
   <releases>
-    <release version="383" date="2023-06-27"/>
+    <release version="384" date="2023-07-10"/>
   </releases>
   <url type="homepage">https://invisible-island.net/xterm/</url>
   <update_contact>dickey@invisible-island.net</update_contact>
Index: xterm.log.html
--- xterm-383+/xterm.log.html	2023-06-27 20:58:54.000000000 +0000
+++ xterm-384/xterm.log.html	2023-07-10 21:11:27.000000000 +0000
@@ -30,7 +30,7 @@
  * sale, use or other dealings in this Software without prior written        *
  * authorization.                                                            *
  *****************************************************************************
-  $XTermId: xterm.log.html,v 1.2527 2023/06/27 20:58:54 tom Exp $
+  $XTermId: xterm.log.html,v 1.2535 2023/07/10 21:11:27 tom Exp $
   -->
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html>
@@ -70,6 +70,8 @@
   CHANGELOG</a>).</p>
 
   <ul>
+    <li><a href="#xterm_384">Patch #384 - 2023/07/10</a></li>
+
     <li><a href="#xterm_383">Patch #383 - 2023/06/27</a></li>
 
     <li><a href="#xterm_382">Patch #382 - 2023/05/30</a></li>
@@ -1044,6 +1046,32 @@
     <li><a href="#xterm_01">Patch #1 - 1996/1/6</a></li>
   </ul>
 
+  <h1><a name="xterm_384" id="xterm_384">Patch #384 -
+  2023/07/10</a></h1>
+
+  <ul>
+    <li>exclude ASCII space from <code>showMissingGlyphs</code>,
+    since a few bitmap fonts lack this (report by "SanRemo",
+    Emanuel Haupt).</li>
+
+    <li>correct a step in rendering double-width characters with
+    bitmap-fonts (report by Peter Fabinski, Debian #1039986).</li>
+
+    <li>fixes for ReGIS-related problems (report by Ben Wong):
+      <ul>
+        <li>mimic an undocumented hardware VT340 feature which
+        handles color initialization with incomplete
+        parameters.</li>
+
+        <li>handle whitespace between operator/operands for color
+        values.</li>
+
+        <li>reset ReGIS-context when resetting graphics in
+        <tt>RIS</tt>.</li>
+      </ul>
+    </li>
+  </ul>
+
   <h1><a name="xterm_383" id="xterm_383">Patch #383 -
   2023/06/27</a></h1>
 
