Index: uspace/lib/ui/src/paint.c
===================================================================
--- uspace/lib/ui/src/paint.c	(revision 06176e1f247c6c0450877aea38262568fcb8b9d7)
+++ uspace/lib/ui/src/paint.c	(revision 0366d09d1929d3cd61f8f612f9ea15794bc5650c)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -632,14 +632,17 @@
 }
 
-/** Paint a text box.
+/** Paint a custom text box.
+ *
+ * Paint a text box using user-provided box chars.
  *
  * @param resource UI resource
  * @param rect Rectangle inside which to paint the box
  * @param style Box style
+ * @param boxc Box characters
  * @param color Color
  * @return EOK on success or an error code
  */
-errno_t ui_paint_text_box(ui_resource_t *resource, gfx_rect_t *rect,
-    ui_box_style_t style, gfx_color_t *color)
+errno_t ui_paint_text_box_custom(ui_resource_t *resource, gfx_rect_t *rect,
+    ui_box_chars_t *boxc, gfx_color_t *color)
 {
 	errno_t rc;
@@ -653,5 +656,4 @@
 	gfx_coord_t y;
 	char *str = NULL;
-	ui_box_chars_t *boxc = NULL;
 
 	gfx_rect_points_sort(rect, &srect);
@@ -661,4 +663,93 @@
 	if (dim.x < 2 || dim.y < 2)
 		return EOK;
+
+	gfx_text_fmt_init(&fmt);
+	fmt.font = resource->font;
+	fmt.color = color;
+
+	bufsz = str_size(boxc->c[0][0]) +
+	    str_size(boxc->c[0][1]) * (dim.x - 2) +
+	    str_size(boxc->c[0][2]) + 1;
+
+	str = malloc(bufsz);
+	if (str == NULL)
+		return ENOMEM;
+
+	/* Top edge and corners */
+
+	str_cpy(str, bufsz, boxc->c[0][0]);
+	off = str_size(boxc->c[0][0]);
+
+	for (i = 1; i < dim.x - 1; i++) {
+		str_cpy(str + off, bufsz - off, boxc->c[0][1]);
+		off += str_size(boxc->c[0][1]);
+	}
+
+	str_cpy(str + off, bufsz - off, boxc->c[0][2]);
+	off += str_size(boxc->c[0][2]);
+	str[off] = '\0';
+
+	pos = rect->p0;
+	rc = gfx_puttext(&pos, &fmt, str);
+	if (rc != EOK)
+		goto error;
+
+	/* Vertical edges */
+	for (y = rect->p0.y + 1; y < rect->p1.y - 1; y++) {
+		pos.y = y;
+
+		pos.x = rect->p0.x;
+		rc = gfx_puttext(&pos, &fmt, boxc->c[1][0]);
+		if (rc != EOK)
+			goto error;
+
+		pos.x = rect->p1.x - 1;
+		rc = gfx_puttext(&pos, &fmt, boxc->c[1][2]);
+		if (rc != EOK)
+			goto error;
+	}
+
+	/* Bottom edge and corners */
+
+	str_cpy(str, bufsz, boxc->c[2][0]);
+	off = str_size(boxc->c[2][0]);
+
+	for (i = 1; i < dim.x - 1; i++) {
+		str_cpy(str + off, bufsz - off, boxc->c[2][1]);
+		off += str_size(boxc->c[2][1]);
+	}
+
+	str_cpy(str + off, bufsz - off, boxc->c[2][2]);
+	off += str_size(boxc->c[2][2]);
+	str[off] = '\0';
+
+	pos.x = rect->p0.x;
+	pos.y = rect->p1.y - 1;
+	rc = gfx_puttext(&pos, &fmt, str);
+	if (rc != EOK)
+		goto error;
+
+	free(str);
+	return EOK;
+error:
+	if (str != NULL)
+		free(str);
+	return rc;
+}
+
+/** Paint a text box.
+ *
+ * Paint a text box with the specified style.
+ *
+ * @param resource UI resource
+ * @param rect Rectangle inside which to paint the box
+ * @param style Box style
+ * @param color Color
+ * @return EOK on success or an error code
+ */
+errno_t ui_paint_text_box(ui_resource_t *resource, gfx_rect_t *rect,
+    ui_box_style_t style, gfx_color_t *color)
+{
+	ui_box_chars_t *boxc = NULL;
 
 	switch (style) {
@@ -674,76 +765,5 @@
 		return EINVAL;
 
-	gfx_text_fmt_init(&fmt);
-	fmt.font = resource->font;
-	fmt.color = color;
-
-	bufsz = str_size(boxc->c[0][0]) +
-	    str_size(boxc->c[0][1]) * (dim.x - 2) +
-	    str_size(boxc->c[0][2]) + 1;
-
-	str = malloc(bufsz);
-	if (str == NULL)
-		return ENOMEM;
-
-	/* Top edge and corners */
-
-	str_cpy(str, bufsz, boxc->c[0][0]);
-	off = str_size(boxc->c[0][0]);
-
-	for (i = 1; i < dim.x - 1; i++) {
-		str_cpy(str + off, bufsz - off, boxc->c[0][1]);
-		off += str_size(boxc->c[0][1]);
-	}
-
-	str_cpy(str + off, bufsz - off, boxc->c[0][2]);
-	off += str_size(boxc->c[0][2]);
-	str[off] = '\0';
-
-	pos = rect->p0;
-	rc = gfx_puttext(&pos, &fmt, str);
-	if (rc != EOK)
-		goto error;
-
-	/* Vertical edges */
-	for (y = rect->p0.y + 1; y < rect->p1.y - 1; y++) {
-		pos.y = y;
-
-		pos.x = rect->p0.x;
-		rc = gfx_puttext(&pos, &fmt, boxc->c[1][0]);
-		if (rc != EOK)
-			goto error;
-
-		pos.x = rect->p1.x - 1;
-		rc = gfx_puttext(&pos, &fmt, boxc->c[1][2]);
-		if (rc != EOK)
-			goto error;
-	}
-
-	/* Bottom edge and corners */
-
-	str_cpy(str, bufsz, boxc->c[2][0]);
-	off = str_size(boxc->c[2][0]);
-
-	for (i = 1; i < dim.x - 1; i++) {
-		str_cpy(str + off, bufsz - off, boxc->c[2][1]);
-		off += str_size(boxc->c[2][1]);
-	}
-
-	str_cpy(str + off, bufsz - off, boxc->c[2][2]);
-	off += str_size(boxc->c[2][2]);
-	str[off] = '\0';
-
-	pos.x = rect->p0.x;
-	pos.y = rect->p1.y - 1;
-	rc = gfx_puttext(&pos, &fmt, str);
-	if (rc != EOK)
-		goto error;
-
-	free(str);
-	return EOK;
-error:
-	if (str != NULL)
-		free(str);
-	return rc;
+	return ui_paint_text_box_custom(resource, rect, boxc, color);
 }
 
