Index: uspace/lib/ui/include/types/ui/tab.h
===================================================================
--- uspace/lib/ui/include/types/ui/tab.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
+++ uspace/lib/ui/include/types/ui/tab.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Tab
+ */
+
+#ifndef _UI_TYPES_TAB_H
+#define _UI_TYPES_TAB_H
+
+struct ui_menu;
+typedef struct ui_tab ui_tab_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ui/include/types/ui/tabset.h
===================================================================
--- uspace/lib/ui/include/types/ui/tabset.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
+++ uspace/lib/ui/include/types/ui/tabset.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Menu bar
+ */
+
+#ifndef _UI_TYPES_TABSET_H
+#define _UI_TYPES_TABSET_H
+
+struct ui_tab_set;
+typedef struct ui_tab_set ui_tab_set_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ui/include/types/ui/testctl.h
===================================================================
--- uspace/lib/ui/include/types/ui/testctl.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
+++ uspace/lib/ui/include/types/ui/testctl.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Label
+ */
+
+#ifndef _UI_TYPES_TESTCTL_H
+#define _UI_TYPES_TESTCTL_H
+
+struct ui_test_ctl;
+typedef struct ui_test_ctl ui_test_ctl_t;
+
+/** Test control response */
+typedef struct {
+	/** Claim to return */
+	ui_evclaim_t claim;
+	/** Result code to return */
+	errno_t rc;
+
+	/** @c true iff destroy was called */
+	bool destroy;
+
+	/** @c true iff paint was called */
+	bool paint;
+
+	/** @c true iff kbd_event was called */
+	bool kbd;
+	/** Keyboard event that was sent */
+	kbd_event_t kevent;
+
+	/** @c true iff pos_event was called */
+	bool pos;
+	/** Position event that was sent */
+	pos_event_t pevent;
+
+	/** @c true iff unfocus was called */
+	bool unfocus;
+	/** Number of remaining foci that was sent */
+	unsigned unfocus_nfocus;
+} ui_tc_resp_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ui/include/ui/paint.h
===================================================================
--- uspace/lib/ui/include/ui/paint.h	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
+++ uspace/lib/ui/include/ui/paint.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -71,4 +71,6 @@
 extern errno_t ui_paint_unmaxicon(ui_resource_t *, gfx_coord2_t *, gfx_coord_t,
     gfx_coord_t, gfx_coord_t, gfx_coord_t);
+extern errno_t ui_paint_text_box_custom(ui_resource_t *, gfx_rect_t *,
+    ui_box_chars_t *, gfx_color_t *);
 extern errno_t ui_paint_text_box(ui_resource_t *, gfx_rect_t *,
     ui_box_style_t, gfx_color_t *);
Index: uspace/lib/ui/include/ui/tab.h
===================================================================
--- uspace/lib/ui/include/ui/tab.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
+++ uspace/lib/ui/include/ui/tab.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Tab
+ */
+
+#ifndef _UI_TAB_H
+#define _UI_TAB_H
+
+#include <errno.h>
+#include <gfx/coord.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
+#include <stdbool.h>
+#include <types/common.h>
+#include <types/ui/tab.h>
+#include <types/ui/tabset.h>
+#include <types/ui/event.h>
+#include <uchar.h>
+
+extern errno_t ui_tab_create(ui_tab_set_t *, const char *, ui_tab_t **);
+extern void ui_tab_destroy(ui_tab_t *);
+extern ui_tab_t *ui_tab_first(ui_tab_set_t *);
+extern ui_tab_t *ui_tab_next(ui_tab_t *);
+extern ui_tab_t *ui_tab_last(ui_tab_set_t *);
+extern ui_tab_t *ui_tab_prev(ui_tab_t *);
+extern bool ui_tab_is_selected(ui_tab_t *);
+extern void ui_tab_add(ui_tab_t *, ui_control_t *);
+extern void ui_tab_remove(ui_tab_t *, ui_control_t *);
+extern errno_t ui_tab_paint(ui_tab_t *);
+extern ui_evclaim_t ui_tab_kbd_event(ui_tab_t *, kbd_event_t *);
+extern ui_evclaim_t ui_tab_pos_event(ui_tab_t *, pos_event_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ui/include/ui/tabset.h
===================================================================
--- uspace/lib/ui/include/ui/tabset.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
+++ uspace/lib/ui/include/ui/tabset.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Tab set
+ */
+
+#ifndef _UI_TABSET_H
+#define _UI_TABSET_H
+
+#include <errno.h>
+#include <gfx/coord.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
+#include <types/ui/tabset.h>
+#include <types/ui/control.h>
+#include <types/ui/event.h>
+#include <types/ui/resource.h>
+
+extern errno_t ui_tab_set_create(ui_resource_t *, ui_tab_set_t **);
+extern void ui_tab_set_destroy(ui_tab_set_t *);
+extern ui_control_t *ui_tab_set_ctl(ui_tab_set_t *);
+extern void ui_tab_set_set_rect(ui_tab_set_t *, gfx_rect_t *);
+extern errno_t ui_tab_set_paint(ui_tab_set_t *);
+extern ui_evclaim_t ui_tab_set_kbd_event(ui_tab_set_t *, kbd_event_t *);
+extern ui_evclaim_t ui_tab_set_pos_event(ui_tab_set_t *, pos_event_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ui/include/ui/testctl.h
===================================================================
--- uspace/lib/ui/include/ui/testctl.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
+++ uspace/lib/ui/include/ui/testctl.h	(revision 1eaead40ef1e81dc0e203498597d60b2e71fcd27)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libui
+ * @{
+ */
+/**
+ * @file Test control
+ */
+
+#ifndef _UI_TESTCTL_H
+#define _UI_TESTCTL_H
+
+#include <errno.h>
+#include <types/ui/control.h>
+#include <types/ui/testctl.h>
+
+extern errno_t ui_test_ctl_create(ui_tc_resp_t *, ui_test_ctl_t **);
+extern void ui_test_ctl_destroy(ui_test_ctl_t *);
+extern ui_control_t *ui_test_ctl_ctl(ui_test_ctl_t *);
+
+#endif
+
+/** @}
+ */
