Index: mmon/adt/prodcons.c
===================================================================
--- common/adt/prodcons.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,72 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <adt/prodcons.h>
-#include <adt/list.h>
-#include <fibril_synch.h>
-
-void prodcons_initialize(prodcons_t *pc)
-{
-	list_initialize(&pc->list);
-	fibril_mutex_initialize(&pc->mtx);
-	fibril_condvar_initialize(&pc->cv);
-}
-
-void prodcons_produce(prodcons_t *pc, link_t *item)
-{
-	fibril_mutex_lock(&pc->mtx);
-
-	list_append(item, &pc->list);
-	fibril_condvar_signal(&pc->cv);
-
-	fibril_mutex_unlock(&pc->mtx);
-}
-
-link_t *prodcons_consume(prodcons_t *pc)
-{
-	fibril_mutex_lock(&pc->mtx);
-
-	while (list_empty(&pc->list))
-		fibril_condvar_wait(&pc->cv, &pc->mtx);
-
-	link_t *head = list_first(&pc->list);
-	list_remove(head);
-
-	fibril_mutex_unlock(&pc->mtx);
-
-	return head;
-}
-
-/** @}
- */
Index: mmon/include/adt/prodcons.h
===================================================================
--- common/include/adt/prodcons.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_PRODCONS_H_
-#define _LIBC_PRODCONS_H_
-
-#include <adt/list.h>
-#include <fibril_synch.h>
-
-typedef struct {
-	fibril_mutex_t mtx;
-	fibril_condvar_t cv;
-	list_t list;
-} prodcons_t;
-
-extern void prodcons_initialize(prodcons_t *);
-extern void prodcons_produce(prodcons_t *, link_t *);
-extern link_t *prodcons_consume(prodcons_t *);
-
-#endif
-
-/** @}
- */
Index: meson/arch/ia64/meson.build
===================================================================
--- meson/arch/ia64/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ meson/arch/ia64/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -36,4 +36,7 @@
 arch_boot_c_args = [ '-D__LE__', '-fno-unwind-tables', '-mfixed-range=f32-f127', '-mno-pic', '-mno-sdata' ]
 
+# work around GCC bug 112604
+arch_uspace_c_args += ['-fno-unswitch-loops']
+
 arch_uspace_link_args = [ '-nostdlib', '-lgcc' ]
 arch_kernel_link_args = [ '-nostdlib', '-Wl,-EL', '-Wl,--no-warn-rwx-segments']
Index: uspace/app/corecfg/meson.build
===================================================================
--- uspace/app/corecfg/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/corecfg/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2013 Jiri Svoboda
+# Copyright (c) 2023 Jiri Svoboda
 # All rights reserved.
 #
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'corecfg' ]
 src = files('corecfg.c')
Index: uspace/app/hbench/meson.build
===================================================================
--- uspace/app/hbench/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/hbench/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2018 Jiri Svoboda
+# Copyright (c) 2023 Jiri Svoboda
 # All rights reserved.
 #
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'math' ]
+deps = [ 'math', 'ipctest' ]
 src = files(
 	'benchlist.c',
Index: uspace/app/mkbd/meson.build
===================================================================
--- uspace/app/mkbd/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/mkbd/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'usb', 'usbdev', 'usbhid', 'drv' ]
+deps = [ 'usb', 'usbdev', 'usbhid', 'drv', 'console' ]
 src = files('main.c')
Index: uspace/app/modplay/meson.build
===================================================================
--- uspace/app/modplay/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/modplay/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'trackmod', 'hound', 'pcm' ]
+deps = [ 'trackmod', 'hound', 'pcm', 'console' ]
 src = files('modplay.c')
 
Index: uspace/app/netecho/meson.build
===================================================================
--- uspace/app/netecho/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/netecho/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'inet' ]
+deps = [ 'inet', 'console' ]
 src = files('comm.c', 'netecho.c')
Index: uspace/app/nterm/meson.build
===================================================================
--- uspace/app/nterm/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/nterm/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'inet' ]
+deps = [ 'inet', 'console' ]
 src = files('conn.c', 'nterm.c')
Index: uspace/app/ping/meson.build
===================================================================
--- uspace/app/ping/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/ping/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'inet' ]
+deps = [ 'inet', 'console' ]
 src = files('ping.c')
Index: uspace/app/taskbar-cfg/smeedit.c
===================================================================
--- uspace/app/taskbar-cfg/smeedit.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/taskbar-cfg/smeedit.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -41,4 +41,5 @@
 #include "taskbar-cfg.h"
 #include "smeedit.h"
+#include "startmenu.h"
 
 static void wnd_close(ui_window_t *, void *);
@@ -111,4 +112,5 @@
 	}
 
+	smee->startmenu = smenu;
 	smee->smentry = smentry;
 
@@ -361,5 +363,5 @@
 
 	(void)smenu_entry_save(smee->smentry->entry);
-
+	startmenu_entry_update(smee->smentry);
 	smeedit_destroy(smee);
 }
Index: uspace/app/taskbar-cfg/startmenu.c
===================================================================
--- uspace/app/taskbar-cfg/startmenu.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/taskbar-cfg/startmenu.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -349,6 +349,4 @@
 	smentry->entry = entry;
 
-	printf("startmenu_insert: smentry=%p entry=%p\n",
-	    smentry, entry);
 	ui_list_entry_attr_init(&attr);
 	attr.caption = smenu_entry_get_caption(entry);
@@ -390,5 +388,4 @@
 	smentry = startmenu_get_selected(smenu);
 
-	printf("smeedit_create:entry=%p\n", smentry);
 	rc = smeedit_create(smenu, smentry, &smee);
 	if (rc != EOK)
@@ -398,4 +395,17 @@
 }
 
+/** Update start menu entry caption.
+ *
+ * When editing an entry the entry's label might change. We need
+ * to update the list entry caption to reflect that.
+ *
+ * @param entry Start menu entry
+ */
+errno_t startmenu_entry_update(startmenu_entry_t *entry)
+{
+	return ui_list_entry_set_caption(entry->lentry,
+	    smenu_entry_get_caption(entry->entry));
+}
+
 /** Entry in entry list is selected.
  *
Index: uspace/app/taskbar-cfg/startmenu.h
===================================================================
--- uspace/app/taskbar-cfg/startmenu.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/taskbar-cfg/startmenu.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -48,4 +48,5 @@
 extern startmenu_entry_t *startmenu_get_selected(startmenu_t *);
 extern void startmenu_edit(startmenu_t *);
+extern errno_t startmenu_entry_update(startmenu_entry_t *);
 
 #endif
Index: uspace/app/tester/meson.build
===================================================================
--- uspace/app/tester/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/tester/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2021 Jiri Svoboda
+# Copyright (c) 2023 Jiri Svoboda
 # Copyright (c) 2005 Martin Decky
 # Copyright (c) 2007 Jakub Jermar
@@ -29,5 +29,5 @@
 #
 
-deps = [ 'block', 'codepage', 'drv', 'math' ]
+deps = [ 'block', 'codepage', 'drv', 'math', 'ipctest', 'console' ]
 src = files(
 	'tester.c',
Index: uspace/app/tetris/meson.build
===================================================================
--- uspace/app/tetris/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/tetris/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,4 +28,5 @@
 #
 
+deps = [ 'console' ]
 src = files(
 	'shapes.c',
Index: uspace/app/top/meson.build
===================================================================
--- uspace/app/top/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/top/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,4 +28,5 @@
 #
 
+deps = [ 'console' ]
 src = files(
 	'top.c',
Index: uspace/app/trace/meson.build
===================================================================
--- uspace/app/trace/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/trace/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,4 +28,5 @@
 #
 
+deps = [ 'console' ]
 src = files(
 	'trace.c',
Index: uspace/app/uidemo/uidemo.c
===================================================================
--- uspace/app/uidemo/uidemo.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/app/uidemo/uidemo.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -288,5 +288,5 @@
 	pos = ui_scrollbar_get_pos(scrollbar);
 	ui_scrollbar_set_pos(scrollbar, pos -
-	    ui_scrollbar_through_length(scrollbar) / 4);
+	    ui_scrollbar_trough_length(scrollbar) / 4);
 
 	pos = ui_scrollbar_get_pos(scrollbar);
@@ -305,5 +305,5 @@
 	pos = ui_scrollbar_get_pos(scrollbar);
 	ui_scrollbar_set_pos(scrollbar, pos +
-	    ui_scrollbar_through_length(scrollbar) / 4);
+	    ui_scrollbar_trough_length(scrollbar) / 4);
 
 	pos = ui_scrollbar_get_pos(scrollbar);
@@ -1270,5 +1270,5 @@
 
 	ui_scrollbar_set_thumb_length(demo.hscrollbar,
-	    ui_scrollbar_through_length(demo.hscrollbar) / 4);
+	    ui_scrollbar_trough_length(demo.hscrollbar) / 4);
 
 	rc = ui_fixed_add(demo.bfixed, ui_scrollbar_ctl(demo.hscrollbar));
@@ -1302,5 +1302,5 @@
 
 	ui_scrollbar_set_thumb_length(demo.vscrollbar,
-	    ui_scrollbar_through_length(demo.vscrollbar) / 4);
+	    ui_scrollbar_trough_length(demo.vscrollbar) / 4);
 
 	rc = ui_fixed_add(demo.bfixed, ui_scrollbar_ctl(demo.vscrollbar));
Index: uspace/drv/hid/adb-kbd/adb-kbd.c
===================================================================
--- uspace/drv/hid/adb-kbd/adb-kbd.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/adb-kbd/adb-kbd.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -34,5 +34,5 @@
 #include <ddf/log.h>
 #include <errno.h>
-#include <io/console.h>
+#include <io/kbd_event.h>
 #include <ipc/adb.h>
 #include <ipc/kbdev.h>
Index: uspace/drv/hid/adb-kbd/ctl.c
===================================================================
--- uspace/drv/hid/adb-kbd/ctl.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/adb-kbd/ctl.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -33,5 +33,5 @@
 
 #include <errno.h>
-#include <io/console.h>
+#include <io/kbd_event.h>
 #include <io/keycode.h>
 
Index: uspace/drv/hid/adb-kbd/meson.build
===================================================================
--- uspace/drv/hid/adb-kbd/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/adb-kbd/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,4 +27,5 @@
 #
 
+deps = [ 'input' ]
 src = files(
 	'main.c',
Index: uspace/drv/hid/adb-mouse/meson.build
===================================================================
--- uspace/drv/hid/adb-mouse/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/adb-mouse/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'input' ]
 src = files('main.c', 'adb-mouse.c')
Index: uspace/drv/hid/atkbd/atkbd.c
===================================================================
--- uspace/drv/hid/atkbd/atkbd.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/atkbd/atkbd.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -38,7 +38,7 @@
 #include <errno.h>
 #include <ddf/log.h>
+#include <io/kbd_event.h>
 #include <io/keycode.h>
 #include <io/chardev.h>
-#include <io/console.h>
 #include <ipc/kbdev.h>
 #include <abi/ipc/methods.h>
Index: uspace/drv/hid/atkbd/meson.build
===================================================================
--- uspace/drv/hid/atkbd/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/atkbd/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'input' ]
 src = files('main.c', 'atkbd.c')
Index: uspace/drv/hid/ps2mouse/meson.build
===================================================================
--- uspace/drv/hid/ps2mouse/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/ps2mouse/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'input' ]
 src = files('main.c', 'ps2mouse.c')
Index: uspace/drv/hid/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/hid/ps2mouse/ps2mouse.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/ps2mouse/ps2mouse.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -40,5 +40,4 @@
 #include <io/keycode.h>
 #include <io/chardev.h>
-#include <io/console.h>
 #include <ipc/mouseev.h>
 #include <abi/ipc/methods.h>
Index: uspace/drv/hid/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/hid/usbhid/kbd/kbddev.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/usbhid/kbd/kbddev.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -41,5 +41,5 @@
 
 #include <io/keycode.h>
-#include <io/console.h>
+#include <io/kbd_event.h>
 #include <abi/ipc/methods.h>
 #include <ipc/kbdev.h>
Index: uspace/drv/hid/usbhid/kbd/kbdrepeat.c
===================================================================
--- uspace/drv/hid/usbhid/kbd/kbdrepeat.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/usbhid/kbd/kbdrepeat.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -36,6 +36,6 @@
 
 #include <fibril_synch.h>
+#include <io/kbd_event.h>
 #include <io/keycode.h>
-#include <io/console.h>
 #include <errno.h>
 
Index: uspace/drv/hid/usbhid/meson.build
===================================================================
--- uspace/drv/hid/usbhid/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/usbhid/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'usbhid', 'usbdev', 'usb' ]
+deps = [ 'usbhid', 'usbdev', 'usb', 'input' ]
 includes += [ include_directories('.') ]
 src = files(
Index: uspace/drv/hid/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/hid/usbhid/mouse/mousedev.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/usbhid/mouse/mousedev.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -46,5 +46,4 @@
 #include <str_error.h>
 #include <ipc/mouseev.h>
-#include <io/console.h>
 
 #include <ipc/kbdev.h>
Index: uspace/drv/hid/usbhid/multimedia/multimedia.c
===================================================================
--- uspace/drv/hid/usbhid/multimedia/multimedia.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/usbhid/multimedia/multimedia.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -51,5 +51,5 @@
 
 #include <ipc/kbdev.h>
-#include <io/console.h>
+#include <io/kbd_event.h>
 
 #define NAME  "multimedia-keys"
Index: uspace/drv/hid/xtkbd/meson.build
===================================================================
--- uspace/drv/hid/xtkbd/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/xtkbd/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'input' ]
 src = files('main.c', 'xtkbd.c')
Index: uspace/drv/hid/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/hid/xtkbd/xtkbd.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/drv/hid/xtkbd/xtkbd.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -39,5 +39,5 @@
 #include <io/keycode.h>
 #include <io/chardev.h>
-#include <io/console.h>
+#include <io/kbd_event.h>
 #include <ipc/kbdev.h>
 #include <abi/ipc/methods.h>
Index: uspace/lib/c/generic/adt/prodcons.c
===================================================================
--- uspace/lib/c/generic/adt/prodcons.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/c/generic/adt/prodcons.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#include <adt/prodcons.h>
+#include <adt/list.h>
+#include <fibril_synch.h>
+
+void prodcons_initialize(prodcons_t *pc)
+{
+	list_initialize(&pc->list);
+	fibril_mutex_initialize(&pc->mtx);
+	fibril_condvar_initialize(&pc->cv);
+}
+
+void prodcons_produce(prodcons_t *pc, link_t *item)
+{
+	fibril_mutex_lock(&pc->mtx);
+
+	list_append(item, &pc->list);
+	fibril_condvar_signal(&pc->cv);
+
+	fibril_mutex_unlock(&pc->mtx);
+}
+
+link_t *prodcons_consume(prodcons_t *pc)
+{
+	fibril_mutex_lock(&pc->mtx);
+
+	while (list_empty(&pc->list))
+		fibril_condvar_wait(&pc->cv, &pc->mtx);
+
+	link_t *head = list_first(&pc->list);
+	list_remove(head);
+
+	fibril_mutex_unlock(&pc->mtx);
+
+	return head;
+}
+
+/** @}
+ */
Index: pace/lib/c/generic/clipboard.c
===================================================================
--- uspace/lib/c/generic/clipboard.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,210 +1,0 @@
-/*
- * Copyright (c) 2009 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 libc
- * @{
- */
-/** @file
- * @brief System clipboard API.
- *
- * The clipboard data is managed by the clipboard service and it is shared by
- * the entire system.
- *
- */
-
-#include <async.h>
-#include <clipboard.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <ipc/clipboard.h>
-#include <ipc/services.h>
-#include <loc.h>
-#include <stdlib.h>
-#include <str.h>
-
-static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
-static async_sess_t *clip_sess = NULL;
-
-/** Start an async exchange on the clipboard session.
- *
- * @return New exchange.
- *
- */
-static async_exch_t *clip_exchange_begin(void)
-{
-	service_id_t sid;
-	errno_t rc;
-
-	fibril_mutex_lock(&clip_mutex);
-
-	while (clip_sess == NULL) {
-		rc = loc_service_get_id(SERVICE_NAME_CLIPBOARD, &sid,
-		    IPC_FLAG_BLOCKING);
-		if (rc != EOK)
-			continue;
-
-		clip_sess = loc_service_connect(sid, INTERFACE_CLIPBOARD,
-		    IPC_FLAG_BLOCKING);
-	}
-
-	fibril_mutex_unlock(&clip_mutex);
-
-	return async_exchange_begin(clip_sess);
-}
-
-/** Finish an async exchange on the clipboard session.
- *
- * @param exch Exchange to be finished.
- *
- */
-static void clip_exchange_end(async_exch_t *exch)
-{
-	async_exchange_end(exch);
-}
-
-/** Copy string to clipboard.
- *
- * Sets the clipboard contents to @a str. Passing an empty string or NULL
- * makes the clipboard empty.
- *
- * @param str String to put to clipboard or NULL.
- *
- * @return Zero on success or an error code.
- *
- */
-errno_t clipboard_put_str(const char *str)
-{
-	size_t size = str_size(str);
-
-	if (size == 0) {
-		async_exch_t *exch = clip_exchange_begin();
-		errno_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
-		    CLIPBOARD_TAG_NONE);
-		clip_exchange_end(exch);
-
-		return (errno_t) rc;
-	} else {
-		async_exch_t *exch = clip_exchange_begin();
-		aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
-		    NULL);
-		errno_t rc = async_data_write_start(exch, (void *) str, size);
-		clip_exchange_end(exch);
-
-		if (rc != EOK) {
-			errno_t rc_orig;
-			async_wait_for(req, &rc_orig);
-			if (rc_orig == EOK)
-				return (errno_t) rc;
-			else
-				return (errno_t) rc_orig;
-		}
-
-		async_wait_for(req, &rc);
-
-		return (errno_t) rc;
-	}
-}
-
-/** Get a copy of clipboard contents.
- *
- * Returns a new string that can be deallocated with free().
- *
- * @param str Here pointer to the newly allocated string is stored.
- *
- * @return Zero on success or an error code.
- *
- */
-errno_t clipboard_get_str(char **str)
-{
-	/* Loop until clipboard read succesful */
-	while (true) {
-		async_exch_t *exch = clip_exchange_begin();
-
-		sysarg_t size;
-		sysarg_t tag;
-		errno_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
-
-		clip_exchange_end(exch);
-
-		if (rc != EOK)
-			return (errno_t) rc;
-
-		char *sbuf;
-
-		switch (tag) {
-		case CLIPBOARD_TAG_NONE:
-			sbuf = malloc(1);
-			if (sbuf == NULL)
-				return ENOMEM;
-
-			sbuf[0] = 0;
-			*str = sbuf;
-			return EOK;
-		case CLIPBOARD_TAG_DATA:
-			sbuf = malloc(size + 1);
-			if (sbuf == NULL)
-				return ENOMEM;
-
-			exch = clip_exchange_begin();
-			aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
-			rc = async_data_read_start(exch, (void *) sbuf, size);
-			clip_exchange_end(exch);
-
-			if ((errno_t) rc == EOVERFLOW) {
-				/*
-				 * The data in the clipboard has changed since
-				 * the last call of CLIPBOARD_CONTENT
-				 */
-				break;
-			}
-
-			if (rc != EOK) {
-				errno_t rc_orig;
-				async_wait_for(req, &rc_orig);
-				if (rc_orig == EOK)
-					return (errno_t) rc;
-				else
-					return (errno_t) rc_orig;
-			}
-
-			async_wait_for(req, &rc);
-
-			if (rc == EOK) {
-				sbuf[size] = 0;
-				*str = sbuf;
-			}
-
-			return rc;
-		default:
-			return EINVAL;
-		}
-	}
-}
-
-/** @}
- */
Index: pace/lib/c/generic/corecfg.c
===================================================================
--- uspace/lib/c/generic/corecfg.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,92 +1,0 @@
-/*
- * Copyright (c) 2013 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.
- */
-
-#include <async.h>
-#include <assert.h>
-#include <corecfg.h>
-#include <errno.h>
-#include <ipc/corecfg.h>
-#include <ipc/services.h>
-#include <loc.h>
-#include <stdlib.h>
-
-static async_sess_t *corecfg_sess = NULL;
-
-errno_t corecfg_init(void)
-{
-	service_id_t corecfg_svc;
-	errno_t rc;
-
-	assert(corecfg_sess == NULL);
-
-	rc = loc_service_get_id(SERVICE_NAME_CORECFG, &corecfg_svc,
-	    IPC_FLAG_BLOCKING);
-	if (rc != EOK)
-		return ENOENT;
-
-	corecfg_sess = loc_service_connect(corecfg_svc, INTERFACE_CORECFG,
-	    IPC_FLAG_BLOCKING);
-	if (corecfg_sess == NULL)
-		return ENOENT;
-
-	return EOK;
-}
-
-/** Get core dump enable status. */
-errno_t corecfg_get_enable(bool *renable)
-{
-	async_exch_t *exch = async_exchange_begin(corecfg_sess);
-	sysarg_t enable;
-
-	errno_t rc = async_req_0_1(exch, CORECFG_GET_ENABLE, &enable);
-
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		return rc;
-
-	*renable = enable;
-	return EOK;
-}
-
-/** Enable or disable core dumps. */
-errno_t corecfg_set_enable(bool enable)
-{
-	async_exch_t *exch = async_exchange_begin(corecfg_sess);
-	errno_t rc = async_req_1_0(exch, CORECFG_SET_ENABLE, (sysarg_t) enable);
-
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,362 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <io/style.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <as.h>
-#include <io/chargrid.h>
-
-/** Create a chargrid.
- *
- * @param[in] cols  Number of columns.
- * @param[in] rows  Number of rows.
- * @param[in] flags Chargrid flags.
- *
- * @return New chargrid.
- * @return NULL on failure.
- *
- */
-chargrid_t *chargrid_create(sysarg_t cols, sysarg_t rows,
-    chargrid_flag_t flags)
-{
-	size_t size =
-	    sizeof(chargrid_t) + cols * rows * sizeof(charfield_t);
-	chargrid_t *scrbuf;
-
-	if ((flags & CHARGRID_FLAG_SHARED) == CHARGRID_FLAG_SHARED) {
-		scrbuf = (chargrid_t *) as_area_create(AS_AREA_ANY, size,
-		    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
-		    AS_AREA_UNPAGED);
-		if (scrbuf == AS_MAP_FAILED)
-			return NULL;
-	} else {
-		scrbuf = (chargrid_t *) malloc(size);
-		if (scrbuf == NULL)
-			return NULL;
-	}
-
-	scrbuf->size = size;
-	scrbuf->flags = flags;
-	scrbuf->cols = cols;
-	scrbuf->rows = rows;
-	scrbuf->cursor_visible = false;
-
-	scrbuf->attrs.type = CHAR_ATTR_STYLE;
-	scrbuf->attrs.val.style = STYLE_NORMAL;
-
-	scrbuf->top_row = 0;
-	chargrid_clear(scrbuf);
-
-	return scrbuf;
-}
-
-void chargrid_destroy(chargrid_t *srcbuf)
-{
-	// TODO
-}
-
-bool chargrid_cursor_at(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
-{
-	return ((scrbuf->cursor_visible) && (scrbuf->col == col) &&
-	    (scrbuf->row == row));
-}
-
-sysarg_t chargrid_get_top_row(chargrid_t *scrbuf)
-{
-	return scrbuf->top_row;
-}
-
-static sysarg_t chargrid_update_rows(chargrid_t *scrbuf)
-{
-	if (scrbuf->row == scrbuf->rows) {
-		scrbuf->row = scrbuf->rows - 1;
-		scrbuf->top_row = (scrbuf->top_row + 1) % scrbuf->rows;
-		chargrid_clear_row(scrbuf, scrbuf->row);
-
-		return scrbuf->rows;
-	}
-
-	return 2;
-}
-
-static sysarg_t chargrid_update_cols(chargrid_t *scrbuf)
-{
-	/* Column overflow */
-	if (scrbuf->col == scrbuf->cols) {
-		scrbuf->col = 0;
-		scrbuf->row++;
-		return chargrid_update_rows(scrbuf);
-	}
-
-	return 1;
-}
-
-/** Store one character to chargrid.
- *
- * Its position is determined by scrbuf->col
- * and scrbuf->row.
- *
- * @param scrbuf Chargrid.
- * @param ch     Character to store.
- * @param update Update coordinates.
- *
- * @return Number of rows which have been affected. In usual
- *         situations this is 1. If the current position was
- *         updated to a new row, this value is 2.
- *
- */
-sysarg_t chargrid_putuchar(chargrid_t *scrbuf, char32_t ch, bool update)
-{
-	assert(scrbuf->col < scrbuf->cols);
-	assert(scrbuf->row < scrbuf->rows);
-
-	charfield_t *field =
-	    chargrid_charfield_at(scrbuf, scrbuf->col, scrbuf->row);
-
-	field->ch = ch;
-	field->attrs = scrbuf->attrs;
-	field->flags |= CHAR_FLAG_DIRTY;
-
-	if (update) {
-		scrbuf->col++;
-		return chargrid_update_cols(scrbuf);
-	}
-
-	return 1;
-}
-
-/** Jump to a new row in chargrid.
- *
- * @param scrbuf Chargrid.
- *
- * @return Number of rows which have been affected. In usual
- *         situations this is 2 (the original row and the new
- *         row).
- *
- */
-sysarg_t chargrid_newline(chargrid_t *scrbuf)
-{
-	assert(scrbuf->col < scrbuf->cols);
-	assert(scrbuf->row < scrbuf->rows);
-
-	scrbuf->col = 0;
-	scrbuf->row++;
-
-	return chargrid_update_rows(scrbuf);
-}
-
-/** Jump to a new row in chargrid.
- *
- * @param scrbuf   Chargrid.
- * @param tab_size Tab size.
- *
- * @return Number of rows which have been affected. In usual
- *         situations this is 1. If the current position was
- *         updated to a new row, this value is 2.
- *
- */
-sysarg_t chargrid_tabstop(chargrid_t *scrbuf, sysarg_t tab_size)
-{
-	assert(scrbuf->col < scrbuf->cols);
-	assert(scrbuf->row < scrbuf->rows);
-
-	sysarg_t spaces = tab_size - scrbuf->cols % tab_size;
-	sysarg_t flush = 1;
-
-	for (sysarg_t i = 0; i < spaces; i++)
-		flush += chargrid_putuchar(scrbuf, ' ', true) - 1;
-
-	return flush;
-}
-
-/** Jump to the previous character in chargrid.
- *
- * Currently no scrollback is supported.
- *
- * @param scrbuf Chargrid.
- *
- * @return Number of rows which have been affected. In usual
- *         situations this is 1. If the current position was
- *         updated to the previous row, this value is 2.
- * @return 0 if no backspace is possible.
- *
- */
-sysarg_t chargrid_backspace(chargrid_t *scrbuf)
-{
-	assert(scrbuf->col < scrbuf->cols);
-	assert(scrbuf->row < scrbuf->rows);
-
-	if ((scrbuf->col == 0) && (scrbuf->row == 0))
-		return 0;
-
-	if (scrbuf->col == 0) {
-		scrbuf->col = scrbuf->cols - 1;
-		scrbuf->row--;
-
-		chargrid_putuchar(scrbuf, ' ', false);
-		return 2;
-	}
-
-	scrbuf->col--;
-	chargrid_putuchar(scrbuf, ' ', false);
-	return 1;
-}
-
-/** Clear the chargrid.
- *
- * @param scrbuf Chargrid.
- *
- */
-void chargrid_clear(chargrid_t *scrbuf)
-{
-	for (size_t pos = 0; pos < (scrbuf->cols * scrbuf->rows); pos++) {
-		scrbuf->data[pos].ch = 0;
-		scrbuf->data[pos].attrs = scrbuf->attrs;
-		scrbuf->data[pos].flags = CHAR_FLAG_DIRTY;
-	}
-
-	scrbuf->col = 0;
-	scrbuf->row = 0;
-}
-
-/** Update current chargrid coordinates
- *
- * @param scrbuf Chargrid.
- * @param col    New column.
- * @param row    New row.
- *
- */
-void chargrid_set_cursor(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
-{
-	if (col >= scrbuf->cols || row >= scrbuf->rows)
-		return;
-
-	scrbuf->col = col;
-	scrbuf->row = row;
-}
-
-void chargrid_set_cursor_visibility(chargrid_t *scrbuf, bool visible)
-{
-	scrbuf->cursor_visible = visible;
-}
-
-/** Get current chargrid coordinates
- *
- * @param scrbuf Chargrid.
- * @param col    Column.
- * @param row    Row.
- *
- */
-void chargrid_get_cursor(chargrid_t *scrbuf, sysarg_t *col,
-    sysarg_t *row)
-{
-	assert(col);
-	assert(row);
-
-	*col = scrbuf->col;
-	*row = scrbuf->row;
-}
-
-bool chargrid_get_cursor_visibility(chargrid_t *scrbuf)
-{
-	return scrbuf->cursor_visible;
-}
-
-/** Clear one buffer row.
- *
- * @param scrbuf Chargrid.
- * @param row    Row to clear.
- *
- */
-void chargrid_clear_row(chargrid_t *scrbuf, sysarg_t row)
-{
-	for (sysarg_t col = 0; col < scrbuf->cols; col++) {
-		charfield_t *field =
-		    chargrid_charfield_at(scrbuf, col, row);
-
-		field->ch = 0;
-		field->attrs = scrbuf->attrs;
-		field->flags |= CHAR_FLAG_DIRTY;
-	}
-}
-
-/** Set chargrid style.
- *
- * @param scrbuf Chargrid.
- * @param style  Style.
- *
- */
-void chargrid_set_style(chargrid_t *scrbuf, console_style_t style)
-{
-	scrbuf->attrs.type = CHAR_ATTR_STYLE;
-	scrbuf->attrs.val.style = style;
-}
-
-/** Set chargrid color.
- *
- * @param scrbuf  Chargrid.
- * @param bgcolor Background color.
- * @param fgcolor Foreground color.
- * @param attr    Color attribute.
- *
- */
-void chargrid_set_color(chargrid_t *scrbuf, console_color_t bgcolor,
-    console_color_t fgcolor, console_color_attr_t attr)
-{
-	scrbuf->attrs.type = CHAR_ATTR_INDEX;
-	scrbuf->attrs.val.index.bgcolor = bgcolor;
-	scrbuf->attrs.val.index.fgcolor = fgcolor;
-	scrbuf->attrs.val.index.attr = attr;
-}
-
-/** Set chargrid RGB color.
- *
- * @param scrbuf  Chargrid.
- * @param bgcolor Background color.
- * @param fgcolor Foreground color.
- *
- */
-void chargrid_set_rgb_color(chargrid_t *scrbuf, pixel_t bgcolor,
-    pixel_t fgcolor)
-{
-	scrbuf->attrs.type = CHAR_ATTR_RGB;
-	scrbuf->attrs.val.rgb.bgcolor = bgcolor;
-	scrbuf->attrs.val.rgb.fgcolor = fgcolor;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/io/con_srv.c
===================================================================
--- uspace/lib/c/generic/io/con_srv.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,539 +1,0 @@
-/*
- * Copyright (c) 2021 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 libc
- * @{
- */
-/**
- * @file
- * @brief Console protocol server stub
- */
-#include <as.h>
-#include <errno.h>
-#include <io/cons_event.h>
-#include <ipc/console.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-#include <io/con_srv.h>
-
-static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *icall)
-{
-	ipc_set_arg1(icall, event->type);
-
-	switch (event->type) {
-	case CEV_KEY:
-		ipc_set_arg2(icall, event->ev.key.type);
-		ipc_set_arg3(icall, event->ev.key.key);
-		ipc_set_arg4(icall, event->ev.key.mods);
-		ipc_set_arg5(icall, event->ev.key.c);
-		break;
-	case CEV_POS:
-		ipc_set_arg2(icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
-		ipc_set_arg3(icall, event->ev.pos.btn_num);
-		ipc_set_arg4(icall, event->ev.pos.hpos);
-		ipc_set_arg5(icall, event->ev.pos.vpos);
-		break;
-	default:
-		return EIO;
-	}
-
-	return EOK;
-}
-
-static void con_read_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	void *buf;
-	size_t size;
-	errno_t rc;
-
-	ipc_call_t call;
-	if (!async_data_read_receive(&call, &size)) {
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	buf = malloc(size);
-	if (buf == NULL) {
-		async_answer_0(&call, ENOMEM);
-		async_answer_0(icall, ENOMEM);
-		return;
-	}
-
-	if (srv->srvs->ops->read == NULL) {
-		async_answer_0(&call, ENOTSUP);
-		async_answer_0(icall, ENOTSUP);
-		free(buf);
-		return;
-	}
-
-	size_t nread;
-	rc = srv->srvs->ops->read(srv, buf, size, &nread);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		free(buf);
-		return;
-	}
-
-	async_data_read_finalize(&call, buf, nread);
-	free(buf);
-
-	async_answer_1(icall, EOK, nread);
-}
-
-static void con_write_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	void *data;
-	size_t size;
-	errno_t rc;
-
-	rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->srvs->ops->write == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	size_t nwritten = 0;
-	rc = srv->srvs->ops->write(srv, data, size, &nwritten);
-	free(data);
-
-	async_answer_1(icall, rc, nwritten);
-}
-
-static void con_sync_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	if (srv->srvs->ops->sync == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->sync(srv);
-	async_answer_0(icall, EOK);
-}
-
-static void con_clear_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	if (srv->srvs->ops->clear == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->clear(srv);
-	async_answer_0(icall, EOK);
-}
-
-static void con_set_pos_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t col;
-	sysarg_t row;
-
-	col = ipc_get_arg1(icall);
-	row = ipc_get_arg2(icall);
-
-	if (srv->srvs->ops->set_pos == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->set_pos(srv, col, row);
-	async_answer_0(icall, EOK);
-}
-
-static void con_get_pos_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	errno_t rc;
-	sysarg_t col;
-	sysarg_t row;
-
-	if (srv->srvs->ops->get_pos == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->srvs->ops->get_pos(srv, &col, &row);
-	async_answer_2(icall, rc, col, row);
-}
-
-static void con_get_size_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	errno_t rc;
-	sysarg_t cols;
-	sysarg_t rows;
-
-	if (srv->srvs->ops->get_size == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->srvs->ops->get_size(srv, &cols, &rows);
-	async_answer_2(icall, rc, cols, rows);
-}
-
-static void con_get_color_cap_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	errno_t rc;
-	console_caps_t ccap;
-
-	if (srv->srvs->ops->get_color_cap == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->srvs->ops->get_color_cap(srv, &ccap);
-	async_answer_1(icall, rc, (sysarg_t)ccap);
-}
-
-static void con_set_style_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	console_style_t style;
-
-	style = ipc_get_arg1(icall);
-
-	if (srv->srvs->ops->set_style == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->set_style(srv, style);
-	async_answer_0(icall, EOK);
-}
-
-static void con_set_color_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	console_color_t bgcolor;
-	console_color_t fgcolor;
-	console_color_attr_t flags;
-
-	bgcolor = ipc_get_arg1(icall);
-	fgcolor = ipc_get_arg2(icall);
-	flags = ipc_get_arg3(icall);
-
-	if (srv->srvs->ops->set_color == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
-	async_answer_0(icall, EOK);
-}
-
-static void con_set_rgb_color_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	pixel_t bgcolor;
-	pixel_t fgcolor;
-
-	bgcolor = ipc_get_arg1(icall);
-	fgcolor = ipc_get_arg2(icall);
-
-	if (srv->srvs->ops->set_rgb_color == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
-	async_answer_0(icall, EOK);
-}
-
-static void con_set_cursor_visibility_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	bool show;
-
-	show = ipc_get_arg1(icall);
-
-	if (srv->srvs->ops->set_cursor_visibility == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->set_cursor_visibility(srv, show);
-	async_answer_0(icall, EOK);
-}
-
-static void con_set_caption_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	char *caption;
-	errno_t rc;
-
-	rc = async_data_write_accept((void **) &caption, true, 0,
-	    CON_CAPTION_MAXLEN, 0, NULL);
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->srvs->ops->set_caption == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->set_caption(srv, caption);
-	free(caption);
-	async_answer_0(icall, EOK);
-}
-
-static void con_get_event_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	errno_t rc;
-	cons_event_t event;
-	ipc_call_t result;
-
-	if (srv->srvs->ops->get_event == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->srvs->ops->get_event(srv, &event);
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	rc = console_ev_encode(&event, &result);
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	async_answer_5(icall, rc, ipc_get_arg1(&result), ipc_get_arg2(&result),
-	    ipc_get_arg3(&result), ipc_get_arg4(&result), ipc_get_arg5(&result));
-}
-
-/** Create shared buffer for efficient rendering */
-static void con_map_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	errno_t rc;
-	charfield_t *buf;
-	sysarg_t cols, rows;
-	ipc_call_t call;
-	size_t size;
-
-	if (srv->srvs->ops->map == NULL || srv->srvs->ops->unmap == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	cols = ipc_get_arg1(icall);
-	rows = ipc_get_arg2(icall);
-
-	if (!async_share_in_receive(&call, &size)) {
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	/* Check size */
-	if (size != PAGES2SIZE(SIZE2PAGES(cols * rows * sizeof(charfield_t)))) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = srv->srvs->ops->map(srv, cols, rows, &buf);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	rc = async_share_in_finalize(&call, buf, AS_AREA_READ |
-	    AS_AREA_WRITE | AS_AREA_CACHEABLE);
-	if (rc != EOK) {
-		srv->srvs->ops->unmap(srv);
-		async_answer_0(icall, EIO);
-		return;
-	}
-
-	async_answer_0(icall, EOK);
-}
-
-/** Delete shared buffer */
-static void con_unmap_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	if (srv->srvs->ops->unmap == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->unmap(srv);
-	async_answer_0(icall, EOK);
-}
-
-/** Update console area from shared buffer */
-static void con_update_srv(con_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t c0, r0, c1, r1;
-
-	c0 = ipc_get_arg1(icall);
-	r0 = ipc_get_arg2(icall);
-	c1 = ipc_get_arg3(icall);
-	r1 = ipc_get_arg4(icall);
-
-	if (srv->srvs->ops->update == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	srv->srvs->ops->update(srv, c0, r0, c1, r1);
-	async_answer_0(icall, EOK);
-}
-
-static con_srv_t *con_srv_create(con_srvs_t *srvs)
-{
-	con_srv_t *srv;
-
-	srv = calloc(1, sizeof(*srv));
-	if (srv == NULL)
-		return NULL;
-
-	srv->srvs = srvs;
-	return srv;
-}
-
-void con_srvs_init(con_srvs_t *srvs)
-{
-	srvs->ops = NULL;
-	srvs->sarg = NULL;
-	srvs->abort_timeout = 0;
-	srvs->aborted = false;
-}
-
-errno_t con_conn(ipc_call_t *icall, con_srvs_t *srvs)
-{
-	con_srv_t *srv;
-	errno_t rc;
-
-	/* Accept the connection */
-	async_accept_0(icall);
-
-	srv = con_srv_create(srvs);
-	if (srv == NULL)
-		return ENOMEM;
-
-	srv->client_sess = NULL;
-
-	rc = srvs->ops->open(srvs, srv);
-	if (rc != EOK)
-		return rc;
-
-	while (true) {
-		ipc_call_t call;
-		bool received = false;
-
-		while (!received) {
-			/* XXX Need to be able to abort immediately */
-			received = async_get_call_timeout(&call,
-			    srvs->abort_timeout);
-
-			if (srv->srvs->aborted) {
-				if (received)
-					async_answer_0(&call, EINTR);
-				break;
-			}
-		}
-
-		if (!received)
-			break;
-
-		sysarg_t method = ipc_get_imethod(&call);
-
-		if (!method) {
-			/* The other side has hung up */
-			async_answer_0(&call, EOK);
-			break;
-		}
-
-		switch (method) {
-		case VFS_OUT_READ:
-			con_read_srv(srv, &call);
-			break;
-		case VFS_OUT_WRITE:
-			con_write_srv(srv, &call);
-			break;
-		case VFS_OUT_SYNC:
-			con_sync_srv(srv, &call);
-			break;
-		case CONSOLE_CLEAR:
-			con_clear_srv(srv, &call);
-			break;
-		case CONSOLE_SET_POS:
-			con_set_pos_srv(srv, &call);
-			break;
-		case CONSOLE_GET_POS:
-			con_get_pos_srv(srv, &call);
-			break;
-		case CONSOLE_GET_SIZE:
-			con_get_size_srv(srv, &call);
-			break;
-		case CONSOLE_GET_COLOR_CAP:
-			con_get_color_cap_srv(srv, &call);
-			break;
-		case CONSOLE_SET_STYLE:
-			con_set_style_srv(srv, &call);
-			break;
-		case CONSOLE_SET_COLOR:
-			con_set_color_srv(srv, &call);
-			break;
-		case CONSOLE_SET_RGB_COLOR:
-			con_set_rgb_color_srv(srv, &call);
-			break;
-		case CONSOLE_SET_CURSOR_VISIBILITY:
-			con_set_cursor_visibility_srv(srv, &call);
-			break;
-		case CONSOLE_SET_CAPTION:
-			con_set_caption_srv(srv, &call);
-			break;
-		case CONSOLE_GET_EVENT:
-			con_get_event_srv(srv, &call);
-			break;
-		case CONSOLE_MAP:
-			con_map_srv(srv, &call);
-			break;
-		case CONSOLE_UNMAP:
-			con_unmap_srv(srv, &call);
-			break;
-		case CONSOLE_UPDATE:
-			con_update_srv(srv, &call);
-			break;
-		default:
-			async_answer_0(&call, ENOTSUP);
-		}
-	}
-
-	rc = srvs->ops->close(srv);
-	free(srv);
-
-	return rc;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,378 +1,0 @@
-/*
- * Copyright (c) 2021 Jiri Svoboda
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2006 Jakub Vana
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <as.h>
-#include <libc.h>
-#include <async.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <str.h>
-#include <vfs/vfs_sess.h>
-#include <io/console.h>
-#include <ipc/console.h>
-
-console_ctrl_t *console_init(FILE *ifile, FILE *ofile)
-{
-	console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t));
-	if (!ctrl)
-		return NULL;
-
-	ctrl->input_sess = vfs_fsession(ifile, INTERFACE_CONSOLE);
-	if (!ctrl->input_sess) {
-		free(ctrl);
-		return NULL;
-	}
-
-	ctrl->output_sess = vfs_fsession(ofile, INTERFACE_CONSOLE);
-	if (!ctrl->output_sess) {
-		free(ctrl);
-		return NULL;
-	}
-
-	ctrl->input = ifile;
-	ctrl->output = ofile;
-	ctrl->input_aid = 0;
-
-	return ctrl;
-}
-
-void console_done(console_ctrl_t *ctrl)
-{
-	free(ctrl);
-}
-
-bool console_kcon(void)
-{
-	return __SYSCALL0(SYS_DEBUG_CONSOLE);
-}
-
-void console_flush(console_ctrl_t *ctrl)
-{
-	fflush(ctrl->output);
-}
-
-void console_clear(console_ctrl_t *ctrl)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	async_req_0_0(exch, CONSOLE_CLEAR);
-	async_exchange_end(exch);
-}
-
-errno_t console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	errno_t rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-void console_set_style(console_ctrl_t *ctrl, uint8_t style)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	async_req_1_0(exch, CONSOLE_SET_STYLE, style);
-	async_exchange_end(exch);
-}
-
-void console_set_color(console_ctrl_t *ctrl, uint8_t bgcolor, uint8_t fgcolor,
-    uint8_t flags)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	async_req_3_0(exch, CONSOLE_SET_COLOR, bgcolor, fgcolor, flags);
-	async_exchange_end(exch);
-}
-
-void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t bgcolor,
-    uint32_t fgcolor)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	async_req_2_0(exch, CONSOLE_SET_RGB_COLOR, bgcolor, fgcolor);
-	async_exchange_end(exch);
-}
-
-void console_cursor_visibility(console_ctrl_t *ctrl, bool show)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	async_req_1_0(exch, CONSOLE_SET_CURSOR_VISIBILITY, (show != false));
-	async_exchange_end(exch);
-}
-
-/** Set console caption.
- *
- * Set caption text for the console (if the console suports captions).
- *
- * @param ctrl Console
- * @param caption Caption text
- * @return EOK on success or an error code
- */
-errno_t console_set_caption(console_ctrl_t *ctrl, const char *caption)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	ipc_call_t answer;
-	aid_t req = async_send_0(exch, CONSOLE_SET_CAPTION, &answer);
-	errno_t retval = async_data_write_start(exch, caption, str_size(caption));
-
-	if (retval != EOK) {
-		async_forget(req);
-		async_exchange_end(exch);
-		return retval;
-	}
-
-	async_wait_for(req, &retval);
-	async_exchange_end(exch);
-	return EOK;
-}
-
-errno_t console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	errno_t rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-errno_t console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	errno_t rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	async_req_2_0(exch, CONSOLE_SET_POS, col, row);
-	async_exchange_end(exch);
-}
-
-static errno_t console_ev_decode(ipc_call_t *call, cons_event_t *event)
-{
-	event->type = ipc_get_arg1(call);
-
-	switch (event->type) {
-	case CEV_KEY:
-		event->ev.key.type = ipc_get_arg2(call);
-		event->ev.key.key = ipc_get_arg3(call);
-		event->ev.key.mods = ipc_get_arg4(call);
-		event->ev.key.c = ipc_get_arg5(call);
-		break;
-	case CEV_POS:
-		event->ev.pos.pos_id = ipc_get_arg2(call) >> 16;
-		event->ev.pos.type = ipc_get_arg2(call) & 0xffff;
-		event->ev.pos.btn_num = ipc_get_arg3(call);
-		event->ev.pos.hpos = ipc_get_arg4(call);
-		event->ev.pos.vpos = ipc_get_arg5(call);
-		break;
-	default:
-		return EIO;
-	}
-
-	return EOK;
-}
-
-/** Get console event.
- *
- * @param ctrl Console
- * @param event Place to store event
- * @return EOK on success, EIO on failure
- */
-errno_t console_get_event(console_ctrl_t *ctrl, cons_event_t *event)
-{
-	if (ctrl->input_aid == 0) {
-		ipc_call_t result;
-
-		async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
-		aid_t aid = async_send_0(exch, CONSOLE_GET_EVENT, &result);
-		async_exchange_end(exch);
-
-		errno_t rc;
-		async_wait_for(aid, &rc);
-
-		if (rc != EOK)
-			return EIO;
-
-		rc = console_ev_decode(&result, event);
-		if (rc != EOK)
-			return EIO;
-	} else {
-		errno_t retval;
-		async_wait_for(ctrl->input_aid, &retval);
-
-		ctrl->input_aid = 0;
-
-		if (retval != EOK)
-			return EIO;
-
-		errno_t rc = console_ev_decode(&ctrl->input_call, event);
-		if (rc != EOK)
-			return EIO;
-	}
-
-	return EOK;
-}
-
-/** Get console event with timeout.
- *
- * @param ctrl Console
- * @param event Place to store event
- * @param timeout Pointer to timeout. This will be updated to reflect
- *                the remaining time in case of timeout.
- * @return EOK on success (event received), ETIMEOUT on time out,
- *         EIO on I/O error (e.g. lost console connection), ENOMEM
- *         if out of memory
- */
-errno_t console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event,
-    usec_t *timeout)
-{
-	struct timespec t0;
-	getuptime(&t0);
-
-	if (ctrl->input_aid == 0) {
-		async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
-		ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT,
-		    &ctrl->input_call);
-		async_exchange_end(exch);
-	}
-
-	errno_t retval;
-	errno_t rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout);
-	if (rc != EOK) {
-		if (rc == ENOMEM)
-			return ENOMEM;
-		*timeout = 0;
-		return ETIMEOUT;
-	}
-
-	ctrl->input_aid = 0;
-
-	if (retval != EOK)
-		return EIO;
-
-	rc = console_ev_decode(&ctrl->input_call, event);
-	if (rc != EOK)
-		return EIO;
-
-	/* Update timeout */
-	struct timespec t1;
-	getuptime(&t1);
-	*timeout -= NSEC2USEC(ts_sub_diff(&t1, &t0));
-
-	return EOK;
-}
-
-/** Create a shared buffer for fast rendering to the console.
- *
- * @param ctrl Console
- * @param cols Number of columns
- * @param rows Number of rows
- * @param rbuf Place to store pointer to the shared buffer
- * @return EOK on success or an error code
- */
-errno_t console_map(console_ctrl_t *ctrl, sysarg_t cols, sysarg_t rows,
-    charfield_t **rbuf)
-{
-	async_exch_t *exch = NULL;
-	void *buf;
-	aid_t req;
-	ipc_call_t answer;
-	size_t asize;
-	errno_t rc;
-
-	exch = async_exchange_begin(ctrl->output_sess);
-	req = async_send_2(exch, CONSOLE_MAP, cols, rows, &answer);
-
-	asize = PAGES2SIZE(SIZE2PAGES(cols * rows * sizeof(charfield_t)));
-
-	rc = async_share_in_start_0_0(exch, asize, &buf);
-	if (rc != EOK) {
-		async_forget(req);
-		goto error;
-	}
-
-	async_exchange_end(exch);
-	exch = NULL;
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		goto error;
-
-	*rbuf = (charfield_t *)buf;
-	return EOK;
-error:
-	if (exch != NULL)
-		async_exchange_end(exch);
-	return rc;
-}
-
-/** Unmap console shared buffer.
- *
- * @param ctrl Console
- * @param buf Buffer
- */
-void console_unmap(console_ctrl_t *ctrl, charfield_t *buf)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	(void) async_req_0_0(exch, CONSOLE_UNMAP);
-	async_exchange_end(exch);
-
-	as_area_destroy(buf);
-}
-
-/** Update console rectangle from shared buffer.
- *
- * @param ctrl Console
- * @param c0 Column coordinate of top-left corner (inclusive)
- * @param r0 Row coordinate of top-left corner (inclusive)
- * @param c1 Column coordinate of bottom-right corner (exclusive)
- * @param r1 Row coordinate of bottom-right corner (exclusive)
- *
- * @return EOK on sucess or an error code
- */
-errno_t console_update(console_ctrl_t *ctrl, sysarg_t c0, sysarg_t r0,
-    sysarg_t c1, sysarg_t r1)
-{
-	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
-	errno_t rc = async_req_4_0(exch, CONSOLE_UPDATE, c0, r0, c1, r1);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/io/input.c
===================================================================
--- uspace/lib/c/generic/io/input.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,229 +1,0 @@
-/*
- * Copyright (c) 2022 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 libc
- * @{
- */
-/**
- * @file
- * @brief Input protocol client stub
- */
-
-#include <async.h>
-#include <assert.h>
-#include <errno.h>
-#include <io/kbd_event.h>
-#include <io/input.h>
-#include <ipc/input.h>
-#include <stdlib.h>
-
-static void input_cb_conn(ipc_call_t *icall, void *arg);
-
-errno_t input_open(async_sess_t *sess, input_ev_ops_t *ev_ops,
-    void *arg, input_t **rinput)
-{
-	input_t *input = calloc(1, sizeof(input_t));
-	if (input == NULL)
-		return ENOMEM;
-
-	input->sess = sess;
-	input->ev_ops = ev_ops;
-	input->user = arg;
-
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	port_id_t port;
-	errno_t rc = async_create_callback_port(exch, INTERFACE_INPUT_CB, 0, 0,
-	    input_cb_conn, input, &port);
-
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		goto error;
-
-	*rinput = input;
-	return EOK;
-
-error:
-	if (input != NULL)
-		free(input);
-
-	return rc;
-}
-
-void input_close(input_t *input)
-{
-	/* XXX Synchronize with input_cb_conn */
-	free(input);
-}
-
-errno_t input_activate(input_t *input)
-{
-	async_exch_t *exch = async_exchange_begin(input->sess);
-	errno_t rc = async_req_0_0(exch, INPUT_ACTIVATE);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-static void input_ev_active(input_t *input, ipc_call_t *call)
-{
-	errno_t rc = input->ev_ops->active(input);
-	async_answer_0(call, rc);
-}
-
-static void input_ev_deactive(input_t *input, ipc_call_t *call)
-{
-	errno_t rc = input->ev_ops->deactive(input);
-	async_answer_0(call, rc);
-}
-
-static void input_ev_key(input_t *input, ipc_call_t *call)
-{
-	unsigned kbd_id;
-	kbd_event_type_t type;
-	keycode_t key;
-	keymod_t mods;
-	char32_t c;
-	errno_t rc;
-
-	kbd_id = ipc_get_arg1(call);
-	type = ipc_get_arg2(call);
-	key = ipc_get_arg3(call);
-	mods = ipc_get_arg4(call);
-	c = ipc_get_arg5(call);
-
-	rc = input->ev_ops->key(input, kbd_id, type, key, mods, c);
-	async_answer_0(call, rc);
-}
-
-static void input_ev_move(input_t *input, ipc_call_t *call)
-{
-	unsigned pos_id;
-	int dx;
-	int dy;
-	errno_t rc;
-
-	pos_id = ipc_get_arg1(call);
-	dx = ipc_get_arg2(call);
-	dy = ipc_get_arg3(call);
-
-	rc = input->ev_ops->move(input, pos_id, dx, dy);
-	async_answer_0(call, rc);
-}
-
-static void input_ev_abs_move(input_t *input, ipc_call_t *call)
-{
-	unsigned pos_id;
-	unsigned x;
-	unsigned y;
-	unsigned max_x;
-	unsigned max_y;
-	errno_t rc;
-
-	pos_id = ipc_get_arg1(call);
-	x = ipc_get_arg2(call);
-	y = ipc_get_arg3(call);
-	max_x = ipc_get_arg4(call);
-	max_y = ipc_get_arg5(call);
-
-	rc = input->ev_ops->abs_move(input, pos_id, x, y, max_x, max_y);
-	async_answer_0(call, rc);
-}
-
-static void input_ev_button(input_t *input, ipc_call_t *call)
-{
-	unsigned pos_id;
-	int bnum;
-	int press;
-	errno_t rc;
-
-	pos_id = ipc_get_arg1(call);
-	bnum = ipc_get_arg2(call);
-	press = ipc_get_arg3(call);
-
-	rc = input->ev_ops->button(input, pos_id, bnum, press);
-	async_answer_0(call, rc);
-}
-
-static void input_ev_dclick(input_t *input, ipc_call_t *call)
-{
-	unsigned pos_id;
-	int bnum;
-	errno_t rc;
-
-	pos_id = ipc_get_arg1(call);
-	bnum = ipc_get_arg2(call);
-
-	rc = input->ev_ops->dclick(input, pos_id, bnum);
-	async_answer_0(call, rc);
-}
-
-static void input_cb_conn(ipc_call_t *icall, void *arg)
-{
-	input_t *input = (input_t *) arg;
-
-	while (true) {
-		ipc_call_t call;
-		async_get_call(&call);
-
-		if (!ipc_get_imethod(&call)) {
-			async_answer_0(&call, EOK);
-			return;
-		}
-
-		switch (ipc_get_imethod(&call)) {
-		case INPUT_EVENT_ACTIVE:
-			input_ev_active(input, &call);
-			break;
-		case INPUT_EVENT_DEACTIVE:
-			input_ev_deactive(input, &call);
-			break;
-		case INPUT_EVENT_KEY:
-			input_ev_key(input, &call);
-			break;
-		case INPUT_EVENT_MOVE:
-			input_ev_move(input, &call);
-			break;
-		case INPUT_EVENT_ABS_MOVE:
-			input_ev_abs_move(input, &call);
-			break;
-		case INPUT_EVENT_BUTTON:
-			input_ev_button(input, &call);
-			break;
-		case INPUT_EVENT_DCLICK:
-			input_ev_dclick(input, &call);
-			break;
-		default:
-			async_answer_0(&call, ENOTSUP);
-		}
-	}
-}
-
-/** @}
- */
Index: pace/lib/c/generic/io/output.c
===================================================================
--- uspace/lib/c/generic/io/output.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,144 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <async.h>
-#include <errno.h>
-#include <as.h>
-#include <ipc/output.h>
-#include <io/concaps.h>
-#include <io/output.h>
-
-errno_t output_yield(async_sess_t *sess)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_0_0(exch, OUTPUT_YIELD);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-errno_t output_claim(async_sess_t *sess)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_0_0(exch, OUTPUT_CLAIM);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-errno_t output_get_dimensions(async_sess_t *sess, sysarg_t *maxx, sysarg_t *maxy)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_0_2(exch, OUTPUT_GET_DIMENSIONS, maxx, maxy);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-errno_t output_get_caps(async_sess_t *sess, console_caps_t *ccaps)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	sysarg_t rv;
-	errno_t ret = async_req_0_1(exch, OUTPUT_GET_CAPS, &rv);
-
-	async_exchange_end(exch);
-
-	if (ret == EOK)
-		*ccaps = (console_caps_t) rv;
-
-	return ret;
-}
-
-frontbuf_handle_t output_frontbuf_create(async_sess_t *sess,
-    chargrid_t *frontbuf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	ipc_call_t answer;
-	aid_t req = async_send_0(exch, OUTPUT_FRONTBUF_CREATE, &answer);
-	errno_t rc = async_share_out_start(exch, frontbuf, AS_AREA_READ |
-	    AS_AREA_WRITE | AS_AREA_CACHEABLE);
-
-	async_exchange_end(exch);
-
-	errno_t ret;
-	async_wait_for(req, &ret);
-
-	if ((rc != EOK) || (ret != EOK))
-		return 0;
-
-	return (frontbuf_handle_t) ipc_get_arg1(&answer);
-}
-
-errno_t output_set_style(async_sess_t *sess, console_style_t style)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_1_0(exch, OUTPUT_SET_STYLE, style);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-errno_t output_cursor_update(async_sess_t *sess, frontbuf_handle_t frontbuf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_1_0(exch, OUTPUT_CURSOR_UPDATE, frontbuf);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-errno_t output_update(async_sess_t *sess, frontbuf_handle_t frontbuf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_1_0(exch, OUTPUT_UPDATE, frontbuf);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-errno_t output_damage(async_sess_t *sess, frontbuf_handle_t frontbuf, sysarg_t col,
-    sysarg_t row, sysarg_t cols, sysarg_t rows)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t ret = async_req_5_0(exch, OUTPUT_DAMAGE, frontbuf, col, row,
-	    cols, rows);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/ipc_test.c
===================================================================
--- uspace/lib/c/generic/ipc_test.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,224 +1,0 @@
-/*
- * Copyright (c) 2018 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 libc
- * @{
- */
-/** @file IPC test service API
- */
-
-#include <abi/ipc/interfaces.h>
-#include <as.h>
-#include <errno.h>
-#include <ipc/services.h>
-#include <ipc/ipc_test.h>
-#include <loc.h>
-#include <stdlib.h>
-#include <ipc_test.h>
-
-/** Create IPC test service session.
- *
- * @param rvol Place to store pointer to volume service session.
- * @return     EOK on success, ENOMEM if out of memory, EIO if service
- *             cannot be contacted.
- */
-errno_t ipc_test_create(ipc_test_t **rtest)
-{
-	ipc_test_t *test;
-	service_id_t test_svcid;
-	errno_t rc;
-
-	test = calloc(1, sizeof(ipc_test_t));
-	if (test == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rc = loc_service_get_id(SERVICE_NAME_IPC_TEST, &test_svcid, 0);
-	if (rc != EOK) {
-		rc = ENOENT;
-		goto error;
-	}
-
-	test->sess = loc_service_connect(test_svcid, INTERFACE_IPC_TEST, 0);
-	if (test->sess == NULL) {
-		rc = EIO;
-		goto error;
-	}
-
-	*rtest = test;
-	return EOK;
-error:
-	free(test);
-	return rc;
-}
-
-/** Destroy IPC test service session.
- *
- * @param test IPC test service session
- */
-void ipc_test_destroy(ipc_test_t *test)
-{
-	if (test == NULL)
-		return;
-
-	async_hangup(test->sess);
-	free(test);
-}
-
-/** Simple ping.
- *
- * @param test IPC test service
- * @return EOK on success or an error code
- */
-errno_t ipc_test_ping(ipc_test_t *test)
-{
-	async_exch_t *exch;
-	errno_t retval;
-
-	exch = async_exchange_begin(test->sess);
-	retval = async_req_0_0(exch, IPC_TEST_PING);
-	async_exchange_end(exch);
-
-	if (retval != EOK)
-		return retval;
-
-	return EOK;
-}
-
-/** Get size of shared read-only memory area.
- *
- * @param test IPC test service
- * @param rsize Place to store size of the shared area
- * @return EOK on success or an error code
- */
-errno_t ipc_test_get_ro_area_size(ipc_test_t *test, size_t *rsize)
-{
-	async_exch_t *exch;
-	errno_t retval;
-	sysarg_t size;
-
-	exch = async_exchange_begin(test->sess);
-	retval = async_req_0_1(exch, IPC_TEST_GET_RO_AREA_SIZE, &size);
-	async_exchange_end(exch);
-
-	if (retval != EOK)
-		return retval;
-
-	*rsize = size;
-	return EOK;
-}
-
-/** Get size of shared read-write memory area.
- *
- * @param test IPC test service
- * @param rsize Place to store size of the shared area
- * @return EOK on success or an error code
- */
-errno_t ipc_test_get_rw_area_size(ipc_test_t *test, size_t *rsize)
-{
-	async_exch_t *exch;
-	errno_t retval;
-	sysarg_t size;
-
-	exch = async_exchange_begin(test->sess);
-	retval = async_req_0_1(exch, IPC_TEST_GET_RW_AREA_SIZE, &size);
-	async_exchange_end(exch);
-
-	if (retval != EOK)
-		return retval;
-
-	*rsize = size;
-	return EOK;
-}
-
-/** Test share-in of read-only area.
- *
- * @param test IPC test service
- * @param size Size of the shared area
- * @param rptr Place to store pointer to the shared-in area
- * @return EOK on success or an error code
- */
-errno_t ipc_test_share_in_ro(ipc_test_t *test, size_t size, const void **rptr)
-{
-	async_exch_t *exch;
-	ipc_call_t answer;
-	aid_t req;
-	void *dst;
-	errno_t rc;
-
-	exch = async_exchange_begin(test->sess);
-	req = async_send_0(exch, IPC_TEST_SHARE_IN_RO, &answer);
-
-	dst = NULL;
-	rc = async_share_in_start_0_0(exch, size, &dst);
-	if (rc != EOK || dst == AS_MAP_FAILED) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return ENOMEM;
-	}
-
-	async_exchange_end(exch);
-	async_wait_for(req, NULL);
-	*rptr = dst;
-	return EOK;
-}
-
-/** Test share-in of read-write area.
- *
- * @param test IPC test service
- * @param size Size of the shared area
- * @param rptr Place to store pointer to the shared-in area
- * @return EOK on success or an error code
- */
-errno_t ipc_test_share_in_rw(ipc_test_t *test, size_t size, void **rptr)
-{
-	async_exch_t *exch;
-	ipc_call_t answer;
-	aid_t req;
-	void *dst;
-	errno_t rc;
-
-	exch = async_exchange_begin(test->sess);
-	req = async_send_0(exch, IPC_TEST_SHARE_IN_RW, &answer);
-
-	rc = async_share_in_start_0_0(exch, size, &dst);
-	if (rc != EOK || dst == AS_MAP_FAILED) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return ENOMEM;
-	}
-
-	async_exchange_end(exch);
-	async_wait_for(req, NULL);
-	*rptr = dst;
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/lib/c/include/adt/prodcons.h
===================================================================
--- uspace/lib/c/include/adt/prodcons.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/c/include/adt/prodcons.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_PRODCONS_H_
+#define _LIBC_PRODCONS_H_
+
+#include <adt/list.h>
+#include <fibril_synch.h>
+
+typedef struct {
+	fibril_mutex_t mtx;
+	fibril_condvar_t cv;
+	list_t list;
+} prodcons_t;
+
+extern void prodcons_initialize(prodcons_t *);
+extern void prodcons_produce(prodcons_t *, link_t *);
+extern link_t *prodcons_consume(prodcons_t *);
+
+#endif
+
+/** @}
+ */
Index: pace/lib/c/include/clipboard.h
===================================================================
--- uspace/lib/c/include/clipboard.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2009 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_CLIPBOARD_H_
-#define _LIBC_CLIPBOARD_H_
-
-#include <errno.h>
-
-extern errno_t clipboard_put_str(const char *);
-extern errno_t clipboard_get_str(char **);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/corecfg.h
===================================================================
--- uspace/lib/c/include/corecfg.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2013 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_CORECFG_H_
-#define _LIBC_CORECFG_H_
-
-#include <errno.h>
-#include <stdbool.h>
-
-extern errno_t corecfg_init(void);
-extern errno_t corecfg_set_enable(bool);
-extern errno_t corecfg_get_enable(bool *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/charfield.h
===================================================================
--- uspace/lib/c/include/io/charfield.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,107 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2011 Petr Koupy
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_CHARFIELD_H_
-#define _LIBC_IO_CHARFIELD_H_
-
-#include <stdbool.h>
-#include <uchar.h>
-#include <io/color.h>
-#include <io/style.h>
-#include <io/pixel.h>
-
-typedef enum {
-	CHAR_FLAG_NONE = 0,
-	CHAR_FLAG_DIRTY = 1
-} char_flags_t;
-
-typedef enum {
-	CHAR_ATTR_STYLE,
-	CHAR_ATTR_INDEX,
-	CHAR_ATTR_RGB
-} char_attr_type_t;
-
-typedef struct {
-	console_color_t bgcolor;
-	console_color_t fgcolor;
-	console_color_attr_t attr;
-} char_attr_index_t;
-
-typedef struct {
-	pixel_t bgcolor;
-	pixel_t fgcolor;
-} char_attr_rgb_t;
-
-typedef union {
-	console_style_t style;
-	char_attr_index_t index;
-	char_attr_rgb_t rgb;
-} char_attr_val_t;
-
-typedef struct {
-	char_attr_type_t type;
-	char_attr_val_t val;
-} char_attrs_t;
-
-typedef struct {
-	char32_t ch;
-	char_attrs_t attrs;
-	char_flags_t flags;
-} charfield_t;
-
-static inline bool attrs_same(char_attrs_t a1, char_attrs_t a2)
-{
-	if (a1.type != a2.type)
-		return false;
-
-	switch (a1.type) {
-	case CHAR_ATTR_STYLE:
-		return (a1.val.style == a2.val.style);
-	case CHAR_ATTR_INDEX:
-		return (a1.val.index.bgcolor == a2.val.index.bgcolor) &&
-		    (a1.val.index.fgcolor == a2.val.index.fgcolor) &&
-		    (a1.val.index.attr == a2.val.index.attr);
-	case CHAR_ATTR_RGB:
-		return (a1.val.rgb.bgcolor == a2.val.rgb.bgcolor) &&
-		    (a1.val.rgb.fgcolor == a2.val.rgb.fgcolor);
-	}
-
-	return false;
-}
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,103 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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 libc
- * @{
- */
-/**
- * @file
- */
-
-#ifndef _LIBC_IO_CHARGRID_H_
-#define _LIBC_IO_CHARGRID_H_
-
-#include <io/charfield.h>
-#include <types/common.h>
-#include <stddef.h>
-
-typedef enum {
-	CHARGRID_FLAG_NONE = 0,
-	CHARGRID_FLAG_SHARED = 1
-} chargrid_flag_t;
-
-typedef struct {
-	size_t size;            /**< Structure size */
-	chargrid_flag_t flags;  /**< Screenbuffer flags */
-
-	sysarg_t cols;          /**< Number of columns */
-	sysarg_t rows;          /**< Number of rows */
-
-	sysarg_t col;           /**< Current column */
-	sysarg_t row;           /**< Current row */
-	bool cursor_visible;    /**< Cursor visibility */
-
-	char_attrs_t attrs;     /**< Current attributes */
-
-	sysarg_t top_row;       /**< The first row in the cyclic buffer */
-	charfield_t data[];     /**< Screen contents (cyclic buffer) */
-} chargrid_t;
-
-static inline charfield_t *chargrid_charfield_at(chargrid_t *chargrid,
-    sysarg_t col, sysarg_t row)
-{
-	return chargrid->data +
-	    ((row + chargrid->top_row) % chargrid->rows) * chargrid->cols +
-	    col;
-}
-
-extern chargrid_t *chargrid_create(sysarg_t, sysarg_t,
-    chargrid_flag_t);
-extern void chargrid_destroy(chargrid_t *);
-
-extern bool chargrid_cursor_at(chargrid_t *, sysarg_t, sysarg_t);
-
-extern sysarg_t chargrid_get_top_row(chargrid_t *);
-
-extern sysarg_t chargrid_putuchar(chargrid_t *, char32_t, bool);
-extern sysarg_t chargrid_newline(chargrid_t *);
-extern sysarg_t chargrid_tabstop(chargrid_t *, sysarg_t);
-extern sysarg_t chargrid_backspace(chargrid_t *);
-
-extern void chargrid_clear(chargrid_t *);
-extern void chargrid_clear_row(chargrid_t *, sysarg_t);
-
-extern void chargrid_set_cursor(chargrid_t *, sysarg_t, sysarg_t);
-extern void chargrid_set_cursor_visibility(chargrid_t *, bool);
-extern bool chargrid_get_cursor_visibility(chargrid_t *);
-
-extern void chargrid_get_cursor(chargrid_t *, sysarg_t *, sysarg_t *);
-
-extern void chargrid_set_style(chargrid_t *, console_style_t);
-extern void chargrid_set_color(chargrid_t *, console_color_t,
-    console_color_t, console_color_attr_t);
-extern void chargrid_set_rgb_color(chargrid_t *, pixel_t, pixel_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/color.h
===================================================================
--- uspace/lib/c/include/io/color.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2008 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_COLOR_H_
-#define _LIBC_IO_COLOR_H_
-
-typedef enum {
-	COLOR_BLACK   = 0,
-	COLOR_BLUE    = 1,
-	COLOR_GREEN   = 2,
-	COLOR_CYAN    = 3,
-	COLOR_RED     = 4,
-	COLOR_MAGENTA = 5,
-	COLOR_YELLOW  = 6,
-	COLOR_WHITE   = 7
-} console_color_t;
-
-typedef enum {
-	CATTR_NORMAL = 0,
-	CATTR_BRIGHT = 8,
-	CATTR_BLINK  = 16
-} console_color_attr_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/con_srv.h
===================================================================
--- uspace/lib/c/include/io/con_srv.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,101 +1,0 @@
-/*
- * Copyright (c) 2021 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_CON_SRV_H_
-#define _LIBC_CON_SRV_H_
-
-#include <adt/list.h>
-#include <async.h>
-#include <fibril_synch.h>
-#include <io/charfield.h>
-#include <io/color.h>
-#include <io/concaps.h>
-#include <io/cons_event.h>
-#include <io/pixel.h>
-#include <io/style.h>
-#include <stdbool.h>
-#include <time.h>
-#include <stddef.h>
-
-typedef struct con_ops con_ops_t;
-
-#define CON_CAPTION_MAXLEN 255
-
-/** Service setup (per sevice) */
-typedef struct {
-	con_ops_t *ops;
-	void *sarg;
-	/** Period to check for abort */
-	usec_t abort_timeout;
-	bool aborted;
-} con_srvs_t;
-
-/** Server structure (per client session) */
-typedef struct {
-	con_srvs_t *srvs;
-	async_sess_t *client_sess;
-	void *carg;
-} con_srv_t;
-
-struct con_ops {
-	errno_t (*open)(con_srvs_t *, con_srv_t *);
-	errno_t (*close)(con_srv_t *);
-	errno_t (*read)(con_srv_t *, void *, size_t, size_t *);
-	errno_t (*write)(con_srv_t *, void *, size_t, size_t *);
-	void (*sync)(con_srv_t *);
-	void (*clear)(con_srv_t *);
-	void (*set_pos)(con_srv_t *, sysarg_t col, sysarg_t row);
-	errno_t (*get_pos)(con_srv_t *, sysarg_t *, sysarg_t *);
-	errno_t (*get_size)(con_srv_t *, sysarg_t *, sysarg_t *);
-	errno_t (*get_color_cap)(con_srv_t *, console_caps_t *);
-	void (*set_style)(con_srv_t *, console_style_t);
-	void (*set_color)(con_srv_t *, console_color_t, console_color_t,
-	    console_color_attr_t);
-	void (*set_rgb_color)(con_srv_t *, pixel_t, pixel_t);
-	void (*set_cursor_visibility)(con_srv_t *, bool);
-	errno_t (*set_caption)(con_srv_t *, const char *);
-	errno_t (*get_event)(con_srv_t *, cons_event_t *);
-	errno_t (*map)(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
-	void (*unmap)(con_srv_t *);
-	void (*update)(con_srv_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
-};
-
-extern void con_srvs_init(con_srvs_t *);
-
-extern errno_t con_conn(ipc_call_t *, con_srvs_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/concaps.h
===================================================================
--- uspace/lib/c/include/io/concaps.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2012 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_CONCAPS_H_
-#define _LIBC_IO_CONCAPS_H_
-
-typedef enum {
-	CONSOLE_CAP_NONE = 0,
-	CONSOLE_CAP_STYLE = 1,
-	CONSOLE_CAP_INDEXED = 2,
-	CONSOLE_CAP_RGB = 4
-} console_caps_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/cons_event.h
===================================================================
--- uspace/lib/c/include/io/cons_event.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/*
- * Copyright (c) 2013 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_CONS_EVENT_H_
-#define _LIBC_IO_CONS_EVENT_H_
-
-#include <adt/list.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-
-typedef enum {
-	/** Key event */
-	CEV_KEY,
-	/** Position event */
-	CEV_POS
-} cons_event_type_t;
-
-/** Console event structure. */
-typedef struct {
-	/** List handle */
-	link_t link;
-
-	/** Event type */
-	cons_event_type_t type;
-
-	union {
-		kbd_event_t key;
-		pos_event_t pos;
-	} ev;
-} cons_event_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/console.h
===================================================================
--- uspace/lib/c/include/io/console.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,99 +1,0 @@
-/*
- * Copyright (c) 2021 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_CONSOLE_H_
-#define _LIBC_IO_CONSOLE_H_
-
-#include <time.h>
-#include <io/charfield.h>
-#include <io/concaps.h>
-#include <io/kbd_event.h>
-#include <io/cons_event.h>
-#include <io/keycode.h>
-#include <async.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-/** Console control structure. */
-typedef struct {
-	/** Console input file */
-	FILE *input;
-
-	/** Console output file */
-	FILE *output;
-
-	/** Console input session */
-	async_sess_t *input_sess;
-
-	/** Console output session */
-	async_sess_t *output_sess;
-
-	/** Input request call with timeout */
-	ipc_call_t input_call;
-
-	/** Input response with timeout */
-	aid_t input_aid;
-} console_ctrl_t;
-
-extern console_ctrl_t *console_init(FILE *, FILE *);
-extern void console_done(console_ctrl_t *);
-extern bool console_kcon(void);
-
-extern void console_flush(console_ctrl_t *);
-extern void console_clear(console_ctrl_t *);
-
-extern errno_t console_get_size(console_ctrl_t *, sysarg_t *, sysarg_t *);
-extern errno_t console_get_pos(console_ctrl_t *, sysarg_t *, sysarg_t *);
-extern void console_set_pos(console_ctrl_t *, sysarg_t, sysarg_t);
-
-extern void console_set_style(console_ctrl_t *, uint8_t);
-extern void console_set_color(console_ctrl_t *, uint8_t, uint8_t, uint8_t);
-extern void console_set_rgb_color(console_ctrl_t *, uint32_t, uint32_t);
-
-extern void console_cursor_visibility(console_ctrl_t *, bool);
-extern errno_t console_set_caption(console_ctrl_t *, const char *);
-extern errno_t console_get_color_cap(console_ctrl_t *, sysarg_t *);
-extern errno_t console_get_event(console_ctrl_t *, cons_event_t *);
-extern errno_t console_get_event_timeout(console_ctrl_t *, cons_event_t *,
-    usec_t *);
-extern errno_t console_map(console_ctrl_t *, sysarg_t, sysarg_t,
-    charfield_t **);
-extern void console_unmap(console_ctrl_t *, charfield_t *);
-extern errno_t console_update(console_ctrl_t *, sysarg_t, sysarg_t, sysarg_t,
-    sysarg_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/input.h
===================================================================
--- uspace/lib/c/include/io/input.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,68 +1,0 @@
-/*
- * Copyright (c) 2022 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_INPUT_H_
-#define _LIBC_IO_INPUT_H_
-
-#include <async.h>
-#include <io/kbd_event.h>
-
-struct input_ev_ops;
-
-typedef struct {
-	async_sess_t *sess;
-	struct input_ev_ops *ev_ops;
-	void *user;
-} input_t;
-
-typedef struct input_ev_ops {
-	errno_t (*active)(input_t *);
-	errno_t (*deactive)(input_t *);
-	errno_t (*key)(input_t *, unsigned, kbd_event_type_t, keycode_t,
-	    keymod_t, char32_t);
-	errno_t (*move)(input_t *, unsigned, int, int);
-	errno_t (*abs_move)(input_t *, unsigned, unsigned, unsigned, unsigned,
-	    unsigned);
-	errno_t (*button)(input_t *, unsigned, int, int);
-	errno_t (*dclick)(input_t *, unsigned, int);
-} input_ev_ops_t;
-
-extern errno_t input_open(async_sess_t *, input_ev_ops_t *, void *, input_t **);
-extern void input_close(input_t *);
-extern errno_t input_activate(input_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/kbd_event.h
===================================================================
--- uspace/lib/c/include/io/kbd_event.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,72 +1,0 @@
-/*
- * Copyright (c) 2022 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_KBD_EVENT_H_
-#define _LIBC_IO_KBD_EVENT_H_
-
-#include <adt/list.h>
-#include <inttypes.h>
-#include <io/keycode.h>
-#include <types/common.h>
-
-typedef enum {
-	KEY_PRESS,
-	KEY_RELEASE
-} kbd_event_type_t;
-
-/** Console event structure. */
-typedef struct {
-	/** List handle */
-	link_t link;
-
-	/** Keyboard device ID */
-	sysarg_t kbd_id;
-
-	/** Press or release event. */
-	kbd_event_type_t type;
-
-	/** Keycode of the key that was pressed or released. */
-	keycode_t key;
-
-	/** Bitmask of modifiers held. */
-	keymod_t mods;
-
-	/** The character that was generated or '\0' for none. */
-	char32_t c;
-} kbd_event_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/keycode.h
===================================================================
--- uspace/lib/c/include/io/keycode.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,223 +1,0 @@
-/*
- * Copyright (c) 2009 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_KEYCODE_H_
-#define _LIBC_IO_KEYCODE_H_
-
-/** Keycode definitions.
- *
- * A keycode identifies a key by its position on the keyboard, rather
- * than by its label. For human readability, key positions are noted
- * with the key label on a keyboard with US layout. This label has
- * nothing to do with the character, that the key produces
- * -- this is determined by the keymap.
- *
- * The keyboard model reflects a standard PC keyboard layout.
- * Non-standard keyboards need to be mapped to this model in some
- * logical way. Scancodes are mapped to keycodes with a scanmap.
- *
- * For easier mapping to the model and to emphasize the nature of keycodes,
- * they really are organized here by position, rather than by label.
- */
-typedef enum {
-
-	/* Main block row 1 */
-
-	KC_BACKTICK = 1,
-
-	KC_1,
-	KC_2,
-	KC_3,
-	KC_4,
-	KC_5,
-	KC_6,
-	KC_7,
-	KC_8,
-	KC_9,
-	KC_0,
-
-	KC_MINUS,
-	KC_EQUALS,
-	KC_BACKSPACE,
-
-	/* Main block row 2 */
-
-	KC_TAB,
-
-	KC_Q,
-	KC_W,
-	KC_E,
-	KC_R,
-	KC_T,
-	KC_Y,
-	KC_U,
-	KC_I,
-	KC_O,
-	KC_P,
-
-	KC_LBRACKET,
-	KC_RBRACKET,
-
-	/* Main block row 3 */
-
-	KC_CAPS_LOCK,
-
-	KC_A,
-	KC_S,
-	KC_D,
-	KC_F,
-	KC_G,
-	KC_H,
-	KC_J,
-	KC_K,
-	KC_L,
-
-	KC_SEMICOLON,
-	KC_QUOTE,
-	KC_BACKSLASH,
-	KC_HASH,
-
-	KC_ENTER,
-
-	/* Main block row 4 */
-
-	KC_LSHIFT,
-
-	KC_Z,
-	KC_X,
-	KC_C,
-	KC_V,
-	KC_B,
-	KC_N,
-	KC_M,
-
-	KC_COMMA,
-	KC_PERIOD,
-	KC_SLASH,
-
-	KC_RSHIFT,
-
-	/* Main block row 5 */
-
-	KC_LCTRL,
-	KC_LALT,
-	KC_SPACE,
-	KC_RALT,
-	KC_RCTRL,
-
-	/* Function keys block */
-
-	KC_ESCAPE,
-
-	KC_F1,
-	KC_F2,
-	KC_F3,
-	KC_F4,
-	KC_F5,
-	KC_F6,
-	KC_F7,
-	KC_F8,
-	KC_F9,
-	KC_F10,
-	KC_F11,
-	KC_F12,
-
-	KC_PRTSCR,
-	KC_SYSREQ,
-	KC_SCROLL_LOCK,
-	KC_PAUSE,
-	KC_BREAK,
-
-	/* Cursor keys block */
-
-	KC_INSERT,
-	KC_HOME,
-	KC_PAGE_UP,
-
-	KC_DELETE,
-	KC_END,
-	KC_PAGE_DOWN,
-
-	KC_UP,
-	KC_LEFT,
-	KC_DOWN,
-	KC_RIGHT,
-
-	/* Numeric block */
-
-	KC_NUM_LOCK,
-	KC_NSLASH,
-	KC_NTIMES,
-	KC_NMINUS,
-
-	KC_NPLUS,
-	KC_NENTER,
-
-	KC_N7,
-	KC_N8,
-	KC_N9,
-
-	KC_N4,
-	KC_N5,
-	KC_N6,
-
-	KC_N1,
-	KC_N2,
-	KC_N3,
-
-	KC_N0,
-	KC_NPERIOD
-
-} keycode_t;
-
-typedef enum {
-	KM_LSHIFT      = 0x001,
-	KM_RSHIFT      = 0x002,
-	KM_LCTRL       = 0x004,
-	KM_RCTRL       = 0x008,
-	KM_LALT        = 0x010,
-	KM_RALT        = 0x020,
-	KM_CAPS_LOCK   = 0x040,
-	KM_NUM_LOCK    = 0x080,
-	KM_SCROLL_LOCK = 0x100,
-
-	KM_SHIFT       = KM_LSHIFT | KM_RSHIFT,
-	KM_CTRL        = KM_LCTRL | KM_RCTRL,
-	KM_ALT         = KM_LALT | KM_RALT
-} keymod_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/output.h
===================================================================
--- uspace/lib/c/include/io/output.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_OUTPUT_H_
-#define _LIBC_IO_OUTPUT_H_
-
-#include <ipc/output.h>
-#include <io/chargrid.h>
-#include <io/console.h>
-
-extern errno_t output_yield(async_sess_t *);
-extern errno_t output_claim(async_sess_t *);
-extern errno_t output_get_dimensions(async_sess_t *, sysarg_t *, sysarg_t *);
-extern errno_t output_get_caps(async_sess_t *, console_caps_t *);
-
-extern frontbuf_handle_t output_frontbuf_create(async_sess_t *, chargrid_t *);
-
-extern errno_t output_cursor_update(async_sess_t *, frontbuf_handle_t);
-extern errno_t output_set_style(async_sess_t *, console_style_t);
-
-extern errno_t output_update(async_sess_t *, frontbuf_handle_t);
-extern errno_t output_damage(async_sess_t *, frontbuf_handle_t,
-    sysarg_t, sysarg_t, sysarg_t, sysarg_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/io/pos_event.h
===================================================================
--- uspace/lib/c/include/io/pos_event.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Copyright (c) 2021 Jiri Svoboda
- * Copyright (c) 2012 Petr Koupy
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IO_POS_EVENT_H_
-#define _LIBC_IO_POS_EVENT_H_
-
-#include <types/common.h>
-
-typedef enum {
-	/** Position update */
-	POS_UPDATE,
-	/** Button press */
-	POS_PRESS,
-	/** Button release */
-	POS_RELEASE,
-	/** Double click */
-	POS_DCLICK
-} pos_event_type_t;
-
-/** Positioning device event */
-typedef struct {
-	sysarg_t pos_id;
-	pos_event_type_t type;
-	sysarg_t btn_num;
-	sysarg_t hpos;
-	sysarg_t vpos;
-} pos_event_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/ipc/clipboard.h
===================================================================
--- uspace/lib/c/include/ipc/clipboard.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2009 Martin Decky
- * 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_CLIPBOARD_H_
-#define _LIBC_IPC_CLIPBOARD_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	CLIPBOARD_PUT_DATA = IPC_FIRST_USER_METHOD,
-	CLIPBOARD_GET_DATA,
-	CLIPBOARD_CONTENT
-} clipboard_request_t;
-
-typedef enum {
-	CLIPBOARD_TAG_NONE,
-	CLIPBOARD_TAG_DATA
-} clipboard_tag_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/ipc/console.h
===================================================================
--- uspace/lib/c/include/ipc/console.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2021 Jiri Svoboda
- * Copyright (c) 2006 Josef Cejka
- * 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_CONSOLE_H_
-#define _LIBC_IPC_CONSOLE_H_
-
-#include <ipc/vfs.h>
-
-typedef enum {
-	CONSOLE_GET_SIZE = VFS_OUT_LAST,
-	CONSOLE_GET_COLOR_CAP,
-	CONSOLE_GET_EVENT,
-	CONSOLE_GET_POS,
-	CONSOLE_SET_POS,
-	CONSOLE_CLEAR,
-	CONSOLE_SET_STYLE,
-	CONSOLE_SET_COLOR,
-	CONSOLE_SET_RGB_COLOR,
-	CONSOLE_SET_CURSOR_VISIBILITY,
-	CONSOLE_SET_CAPTION,
-	CONSOLE_MAP,
-	CONSOLE_UNMAP,
-	CONSOLE_UPDATE
-} console_request_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/ipc/corecfg.h
===================================================================
--- uspace/lib/c/include/ipc/corecfg.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2013 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 libcipc
- * @{
- */
-
-#ifndef _LIBC_IPC_CORECFG_H_
-#define _LIBC_IPC_CORECFG_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	CORECFG_GET_ENABLE = IPC_FIRST_USER_METHOD,
-	CORECFG_SET_ENABLE
-} corecfg_request_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/ipc/input.h
===================================================================
--- uspace/lib/c/include/ipc/input.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2021 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_INPUT_H_
-#define _LIBC_IPC_INPUT_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	INPUT_ACTIVATE = IPC_FIRST_USER_METHOD
-} input_request_t;
-
-typedef enum {
-	INPUT_EVENT_ACTIVE = IPC_FIRST_USER_METHOD,
-	INPUT_EVENT_DEACTIVE,
-	INPUT_EVENT_KEY,
-	INPUT_EVENT_MOVE,
-	INPUT_EVENT_ABS_MOVE,
-	INPUT_EVENT_BUTTON,
-	INPUT_EVENT_DCLICK
-} input_notif_t;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/c/include/ipc/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc/ipc_test.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2018 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_IPC_TEST_H_
-#define _LIBC_IPC_IPC_TEST_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	IPC_TEST_PING = IPC_FIRST_USER_METHOD,
-	IPC_TEST_GET_RO_AREA_SIZE,
-	IPC_TEST_GET_RW_AREA_SIZE,
-	IPC_TEST_SHARE_IN_RO,
-	IPC_TEST_SHARE_IN_RW
-} ipc_test_request_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/ipc/kbdev.h
===================================================================
--- uspace/lib/c/include/ipc/kbdev.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/*
- * Copyright (c) 2011 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_KBDEV_H_
-#define _LIBC_IPC_KBDEV_H_
-
-#include <ipc/common.h>
-#include <ipc/dev_iface.h>
-
-typedef enum {
-	KBDEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
-	KBDEV_RECLAIM,
-	KBDEV_SET_IND
-} kbdev_request_t;
-
-typedef enum {
-	KBDEV_EVENT = IPC_FIRST_USER_METHOD
-} kbdev_notif_t;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/c/include/ipc/mouseev.h
===================================================================
--- uspace/lib/c/include/ipc/mouseev.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- * Copyright (c) 2009 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 libc
- * @brief
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_MOUSEEV_H_
-#define _LIBC_IPC_MOUSEEV_H_
-
-#include <ipc/common.h>
-#include <ipc/dev_iface.h>
-
-typedef enum {
-	MOUSEEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
-	MOUSEEV_RECLAIM
-} mouseev_request_t;
-
-typedef enum {
-	MOUSEEV_MOVE_EVENT = IPC_FIRST_USER_METHOD,
-	MOUSEEV_ABS_MOVE_EVENT,
-	MOUSEEV_BUTTON_EVENT
-} mouseev_notif_t;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/c/include/ipc/output.h
===================================================================
--- uspace/lib/c/include/ipc/output.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Copyright (c) 2012 Martin Decky
- * 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 libcipc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_OUTPUT_H_
-#define _LIBC_IPC_OUTPUT_H_
-
-#include <ipc/common.h>
-
-typedef sysarg_t frontbuf_handle_t;
-
-typedef enum {
-	OUTPUT_YIELD = IPC_FIRST_USER_METHOD,
-	OUTPUT_CLAIM,
-	OUTPUT_GET_DIMENSIONS,
-	OUTPUT_GET_CAPS,
-
-	OUTPUT_FRONTBUF_CREATE,
-	OUTPUT_FRONTBUF_DESTROY,
-
-	OUTPUT_CURSOR_UPDATE,
-	OUTPUT_SET_STYLE,
-	OUTPUT_SET_COLOR,
-	OUTPUT_SET_RGB_COLOR,
-
-	OUTPUT_UPDATE,
-	OUTPUT_DAMAGE
-} output_request_t;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/c/include/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc_test.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2018 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_TEST_H_
-#define _LIBC_IPC_TEST_H_
-
-#include <async.h>
-#include <errno.h>
-
-typedef struct {
-	async_sess_t *sess;
-} ipc_test_t;
-
-extern errno_t ipc_test_create(ipc_test_t **);
-extern void ipc_test_destroy(ipc_test_t *);
-extern errno_t ipc_test_ping(ipc_test_t *);
-extern errno_t ipc_test_get_ro_area_size(ipc_test_t *, size_t *);
-extern errno_t ipc_test_get_rw_area_size(ipc_test_t *, size_t *);
-extern errno_t ipc_test_share_in_ro(ipc_test_t *, size_t, const void **);
-extern errno_t ipc_test_share_in_rw(ipc_test_t *, size_t, void **);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/meson.build
===================================================================
--- uspace/lib/c/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/c/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -49,7 +49,4 @@
 allow_shared = true
 
-# FIXME: symlinks from uspace to kernel will break in future Meson version
-#        we should instead move the duplicated library parts into a shared location.
-
 uspace_lib_devel_install_script_text += 'mkdir -p "${DESTDIR}include/libc"'
 foreach idir : incdirs
@@ -66,5 +63,4 @@
 	'common/adt/hash_table.c',
 	'common/adt/odict.c',
-	'common/adt/prodcons.c',
 	'common/printf/printf_core.c',
 	'common/stdc/ctype.c',
@@ -79,12 +75,11 @@
 
 	'generic/libc.c',
+	'generic/adt/prodcons.c',
 	'generic/as.c',
 	'generic/ddi.c',
 	'generic/perm.c',
 	'generic/capa.c',
-	'generic/clipboard.c',
 	'generic/config.c',
 	'generic/context.c',
-	'generic/corecfg.c',
 	'generic/device/clock_dev.c',
 	'generic/device/hw_res.c',
@@ -99,5 +94,4 @@
 	'generic/errno.c',
 	'generic/inttypes.c',
-	'generic/ipc_test.c',
 	'generic/loc.c',
 	'generic/string.c',
@@ -109,8 +103,5 @@
 	'generic/imath.c',
 	'generic/io/asprintf.c',
-	'generic/io/input.c',
 	'generic/io/io.c',
-	'generic/io/chargrid.c',
-	'generic/io/output.c',
 	'generic/io/printf.c',
 	'generic/io/log.c',
@@ -121,6 +112,4 @@
 	'generic/io/vprintf.c',
 	'generic/io/vsnprintf.c',
-	'generic/io/con_srv.c',
-	'generic/io/console.c',
 	'generic/io/table.c',
 	'generic/irq.c',
Index: uspace/lib/clipboard/doc/doxygroups.h
===================================================================
--- uspace/lib/clipboard/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/clipboard/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,3 @@
+/** @addtogroup libclipboard libclipboard
+ * @ingroup libs
+ */
Index: uspace/lib/clipboard/include/clipboard.h
===================================================================
--- uspace/lib/clipboard/include/clipboard.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/clipboard/include/clipboard.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,46 @@
+/*
+ * 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 libclipboard
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCLIPBOARD_CLIPBOARD_H_
+#define _LIBCLIPBOARD_CLIPBOARD_H_
+
+#include <errno.h>
+
+extern errno_t clipboard_put_str(const char *);
+extern errno_t clipboard_get_str(char **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/clipboard/include/ipc/clipboard.h
===================================================================
--- uspace/lib/clipboard/include/ipc/clipboard.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/clipboard/include/ipc/clipboard.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCLIPBOARD_IPC_CLIPBOARD_H_
+#define _LIBCLIPBOARD_IPC_CLIPBOARD_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	CLIPBOARD_PUT_DATA = IPC_FIRST_USER_METHOD,
+	CLIPBOARD_GET_DATA,
+	CLIPBOARD_CONTENT
+} clipboard_request_t;
+
+typedef enum {
+	CLIPBOARD_TAG_NONE,
+	CLIPBOARD_TAG_DATA
+} clipboard_tag_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/clipboard/meson.build
===================================================================
--- uspace/lib/clipboard/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/clipboard/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+src = files('src/clipboard.c')
Index: uspace/lib/clipboard/src/clipboard.c
===================================================================
--- uspace/lib/clipboard/src/clipboard.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/clipboard/src/clipboard.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,210 @@
+/*
+ * 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 libclipboard
+ * @{
+ */
+/** @file
+ * @brief System clipboard API.
+ *
+ * The clipboard data is managed by the clipboard service and it is shared by
+ * the entire system.
+ *
+ */
+
+#include <async.h>
+#include <clipboard.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <ipc/clipboard.h>
+#include <ipc/services.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <str.h>
+
+static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
+static async_sess_t *clip_sess = NULL;
+
+/** Start an async exchange on the clipboard session.
+ *
+ * @return New exchange.
+ *
+ */
+static async_exch_t *clip_exchange_begin(void)
+{
+	service_id_t sid;
+	errno_t rc;
+
+	fibril_mutex_lock(&clip_mutex);
+
+	while (clip_sess == NULL) {
+		rc = loc_service_get_id(SERVICE_NAME_CLIPBOARD, &sid,
+		    IPC_FLAG_BLOCKING);
+		if (rc != EOK)
+			continue;
+
+		clip_sess = loc_service_connect(sid, INTERFACE_CLIPBOARD,
+		    IPC_FLAG_BLOCKING);
+	}
+
+	fibril_mutex_unlock(&clip_mutex);
+
+	return async_exchange_begin(clip_sess);
+}
+
+/** Finish an async exchange on the clipboard session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+static void clip_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
+}
+
+/** Copy string to clipboard.
+ *
+ * Sets the clipboard contents to @a str. Passing an empty string or NULL
+ * makes the clipboard empty.
+ *
+ * @param str String to put to clipboard or NULL.
+ *
+ * @return Zero on success or an error code.
+ *
+ */
+errno_t clipboard_put_str(const char *str)
+{
+	size_t size = str_size(str);
+
+	if (size == 0) {
+		async_exch_t *exch = clip_exchange_begin();
+		errno_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
+		    CLIPBOARD_TAG_NONE);
+		clip_exchange_end(exch);
+
+		return (errno_t) rc;
+	} else {
+		async_exch_t *exch = clip_exchange_begin();
+		aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
+		    NULL);
+		errno_t rc = async_data_write_start(exch, (void *) str, size);
+		clip_exchange_end(exch);
+
+		if (rc != EOK) {
+			errno_t rc_orig;
+			async_wait_for(req, &rc_orig);
+			if (rc_orig == EOK)
+				return (errno_t) rc;
+			else
+				return (errno_t) rc_orig;
+		}
+
+		async_wait_for(req, &rc);
+
+		return (errno_t) rc;
+	}
+}
+
+/** Get a copy of clipboard contents.
+ *
+ * Returns a new string that can be deallocated with free().
+ *
+ * @param str Here pointer to the newly allocated string is stored.
+ *
+ * @return Zero on success or an error code.
+ *
+ */
+errno_t clipboard_get_str(char **str)
+{
+	/* Loop until clipboard read succesful */
+	while (true) {
+		async_exch_t *exch = clip_exchange_begin();
+
+		sysarg_t size;
+		sysarg_t tag;
+		errno_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
+
+		clip_exchange_end(exch);
+
+		if (rc != EOK)
+			return (errno_t) rc;
+
+		char *sbuf;
+
+		switch (tag) {
+		case CLIPBOARD_TAG_NONE:
+			sbuf = malloc(1);
+			if (sbuf == NULL)
+				return ENOMEM;
+
+			sbuf[0] = 0;
+			*str = sbuf;
+			return EOK;
+		case CLIPBOARD_TAG_DATA:
+			sbuf = malloc(size + 1);
+			if (sbuf == NULL)
+				return ENOMEM;
+
+			exch = clip_exchange_begin();
+			aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
+			rc = async_data_read_start(exch, (void *) sbuf, size);
+			clip_exchange_end(exch);
+
+			if ((errno_t) rc == EOVERFLOW) {
+				/*
+				 * The data in the clipboard has changed since
+				 * the last call of CLIPBOARD_CONTENT
+				 */
+				break;
+			}
+
+			if (rc != EOK) {
+				errno_t rc_orig;
+				async_wait_for(req, &rc_orig);
+				if (rc_orig == EOK)
+					return (errno_t) rc;
+				else
+					return (errno_t) rc_orig;
+			}
+
+			async_wait_for(req, &rc);
+
+			if (rc == EOK) {
+				sbuf[size] = 0;
+				*str = sbuf;
+			}
+
+			return rc;
+		default:
+			return EINVAL;
+		}
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/clui/meson.build
===================================================================
--- uspace/lib/clui/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/clui/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2010 Jiri Svoboda
+# Copyright (c) 2023 Jiri Svoboda
 # All rights reserved.
 #
@@ -27,4 +27,5 @@
 #
 
+deps = [ 'clipboard', 'console' ]
 src = files(
 	'nchoice.c',
Index: uspace/lib/congfx/meson.build
===================================================================
--- uspace/lib/congfx/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/congfx/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'gfx' ]
+deps = [ 'gfx', 'console' ]
 src = files(
 	'src/console.c',
Index: uspace/lib/console/doc/doxygroups.h
===================================================================
--- uspace/lib/console/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,3 @@
+/** @addtogroup libconsole libconsole
+ * @ingroup libs
+ */
Index: uspace/lib/console/include/io/con_srv.h
===================================================================
--- uspace/lib/console/include/io/con_srv.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/include/io/con_srv.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,101 @@
+/*
+ * 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 libconsole
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCONSOLE_IO_CON_SRV_H_
+#define _LIBCONSOLE_IO_CON_SRV_H_
+
+#include <adt/list.h>
+#include <async.h>
+#include <fibril_synch.h>
+#include <io/charfield.h>
+#include <io/color.h>
+#include <io/concaps.h>
+#include <io/cons_event.h>
+#include <io/pixel.h>
+#include <io/style.h>
+#include <stdbool.h>
+#include <time.h>
+#include <stddef.h>
+
+typedef struct con_ops con_ops_t;
+
+#define CON_CAPTION_MAXLEN 255
+
+/** Service setup (per sevice) */
+typedef struct {
+	con_ops_t *ops;
+	void *sarg;
+	/** Period to check for abort */
+	usec_t abort_timeout;
+	bool aborted;
+} con_srvs_t;
+
+/** Server structure (per client session) */
+typedef struct {
+	con_srvs_t *srvs;
+	async_sess_t *client_sess;
+	void *carg;
+} con_srv_t;
+
+struct con_ops {
+	errno_t (*open)(con_srvs_t *, con_srv_t *);
+	errno_t (*close)(con_srv_t *);
+	errno_t (*read)(con_srv_t *, void *, size_t, size_t *);
+	errno_t (*write)(con_srv_t *, void *, size_t, size_t *);
+	void (*sync)(con_srv_t *);
+	void (*clear)(con_srv_t *);
+	void (*set_pos)(con_srv_t *, sysarg_t col, sysarg_t row);
+	errno_t (*get_pos)(con_srv_t *, sysarg_t *, sysarg_t *);
+	errno_t (*get_size)(con_srv_t *, sysarg_t *, sysarg_t *);
+	errno_t (*get_color_cap)(con_srv_t *, console_caps_t *);
+	void (*set_style)(con_srv_t *, console_style_t);
+	void (*set_color)(con_srv_t *, console_color_t, console_color_t,
+	    console_color_attr_t);
+	void (*set_rgb_color)(con_srv_t *, pixel_t, pixel_t);
+	void (*set_cursor_visibility)(con_srv_t *, bool);
+	errno_t (*set_caption)(con_srv_t *, const char *);
+	errno_t (*get_event)(con_srv_t *, cons_event_t *);
+	errno_t (*map)(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
+	void (*unmap)(con_srv_t *);
+	void (*update)(con_srv_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+};
+
+extern void con_srvs_init(con_srvs_t *);
+
+extern errno_t con_conn(ipc_call_t *, con_srvs_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/console/include/io/cons_event.h
===================================================================
--- uspace/lib/console/include/io/cons_event.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/include/io/cons_event.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -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 libconsole
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCONSOLE_IO_CONS_EVENT_H_
+#define _LIBCONSOLE_IO_CONS_EVENT_H_
+
+#include <adt/list.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
+
+typedef enum {
+	/** Key event */
+	CEV_KEY,
+	/** Position event */
+	CEV_POS
+} cons_event_type_t;
+
+/** Console event structure. */
+typedef struct {
+	/** List handle */
+	link_t link;
+
+	/** Event type */
+	cons_event_type_t type;
+
+	union {
+		kbd_event_t key;
+		pos_event_t pos;
+	} ev;
+} cons_event_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/console/include/io/console.h
===================================================================
--- uspace/lib/console/include/io/console.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/include/io/console.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,99 @@
+/*
+ * 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 libconsole
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCONSOLE_IO_CONSOLE_H_
+#define _LIBCONSOLE_IO_CONSOLE_H_
+
+#include <time.h>
+#include <io/charfield.h>
+#include <io/concaps.h>
+#include <io/kbd_event.h>
+#include <io/cons_event.h>
+#include <io/keycode.h>
+#include <async.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+/** Console control structure. */
+typedef struct {
+	/** Console input file */
+	FILE *input;
+
+	/** Console output file */
+	FILE *output;
+
+	/** Console input session */
+	async_sess_t *input_sess;
+
+	/** Console output session */
+	async_sess_t *output_sess;
+
+	/** Input request call with timeout */
+	ipc_call_t input_call;
+
+	/** Input response with timeout */
+	aid_t input_aid;
+} console_ctrl_t;
+
+extern console_ctrl_t *console_init(FILE *, FILE *);
+extern void console_done(console_ctrl_t *);
+extern bool console_kcon(void);
+
+extern void console_flush(console_ctrl_t *);
+extern void console_clear(console_ctrl_t *);
+
+extern errno_t console_get_size(console_ctrl_t *, sysarg_t *, sysarg_t *);
+extern errno_t console_get_pos(console_ctrl_t *, sysarg_t *, sysarg_t *);
+extern void console_set_pos(console_ctrl_t *, sysarg_t, sysarg_t);
+
+extern void console_set_style(console_ctrl_t *, uint8_t);
+extern void console_set_color(console_ctrl_t *, uint8_t, uint8_t, uint8_t);
+extern void console_set_rgb_color(console_ctrl_t *, uint32_t, uint32_t);
+
+extern void console_cursor_visibility(console_ctrl_t *, bool);
+extern errno_t console_set_caption(console_ctrl_t *, const char *);
+extern errno_t console_get_color_cap(console_ctrl_t *, sysarg_t *);
+extern errno_t console_get_event(console_ctrl_t *, cons_event_t *);
+extern errno_t console_get_event_timeout(console_ctrl_t *, cons_event_t *,
+    usec_t *);
+extern errno_t console_map(console_ctrl_t *, sysarg_t, sysarg_t,
+    charfield_t **);
+extern void console_unmap(console_ctrl_t *, charfield_t *);
+extern errno_t console_update(console_ctrl_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/console/include/ipc/console.h
===================================================================
--- uspace/lib/console/include/ipc/console.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/include/ipc/console.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2006 Josef Cejka
+ * 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 libconsole
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCONSOLE_IPC_CONSOLE_H_
+#define _LIBCONSOLE_IPC_CONSOLE_H_
+
+#include <ipc/vfs.h>
+
+typedef enum {
+	CONSOLE_GET_SIZE = VFS_OUT_LAST,
+	CONSOLE_GET_COLOR_CAP,
+	CONSOLE_GET_EVENT,
+	CONSOLE_GET_POS,
+	CONSOLE_SET_POS,
+	CONSOLE_CLEAR,
+	CONSOLE_SET_STYLE,
+	CONSOLE_SET_COLOR,
+	CONSOLE_SET_RGB_COLOR,
+	CONSOLE_SET_CURSOR_VISIBILITY,
+	CONSOLE_SET_CAPTION,
+	CONSOLE_MAP,
+	CONSOLE_UNMAP,
+	CONSOLE_UPDATE
+} console_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/console/meson.build
===================================================================
--- uspace/lib/console/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+deps = [ 'input', 'output' ]
+src = files(
+	'src/con_srv.c',
+	'src/console.c',
+)
Index: uspace/lib/console/src/con_srv.c
===================================================================
--- uspace/lib/console/src/con_srv.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/src/con_srv.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2021 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 libconsole
+ * @{
+ */
+/**
+ * @file
+ * @brief Console protocol server stub
+ */
+#include <as.h>
+#include <errno.h>
+#include <io/cons_event.h>
+#include <ipc/console.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include <io/con_srv.h>
+
+static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *icall)
+{
+	ipc_set_arg1(icall, event->type);
+
+	switch (event->type) {
+	case CEV_KEY:
+		ipc_set_arg2(icall, event->ev.key.type);
+		ipc_set_arg3(icall, event->ev.key.key);
+		ipc_set_arg4(icall, event->ev.key.mods);
+		ipc_set_arg5(icall, event->ev.key.c);
+		break;
+	case CEV_POS:
+		ipc_set_arg2(icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
+		ipc_set_arg3(icall, event->ev.pos.btn_num);
+		ipc_set_arg4(icall, event->ev.pos.hpos);
+		ipc_set_arg5(icall, event->ev.pos.vpos);
+		break;
+	default:
+		return EIO;
+	}
+
+	return EOK;
+}
+
+static void con_read_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	void *buf;
+	size_t size;
+	errno_t rc;
+
+	ipc_call_t call;
+	if (!async_data_read_receive(&call, &size)) {
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	buf = malloc(size);
+	if (buf == NULL) {
+		async_answer_0(&call, ENOMEM);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	if (srv->srvs->ops->read == NULL) {
+		async_answer_0(&call, ENOTSUP);
+		async_answer_0(icall, ENOTSUP);
+		free(buf);
+		return;
+	}
+
+	size_t nread;
+	rc = srv->srvs->ops->read(srv, buf, size, &nread);
+	if (rc != EOK) {
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		free(buf);
+		return;
+	}
+
+	async_data_read_finalize(&call, buf, nread);
+	free(buf);
+
+	async_answer_1(icall, EOK, nread);
+}
+
+static void con_write_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	void *data;
+	size_t size;
+	errno_t rc;
+
+	rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
+	if (rc != EOK) {
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	if (srv->srvs->ops->write == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	size_t nwritten = 0;
+	rc = srv->srvs->ops->write(srv, data, size, &nwritten);
+	free(data);
+
+	async_answer_1(icall, rc, nwritten);
+}
+
+static void con_sync_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	if (srv->srvs->ops->sync == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->sync(srv);
+	async_answer_0(icall, EOK);
+}
+
+static void con_clear_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	if (srv->srvs->ops->clear == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->clear(srv);
+	async_answer_0(icall, EOK);
+}
+
+static void con_set_pos_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	sysarg_t col;
+	sysarg_t row;
+
+	col = ipc_get_arg1(icall);
+	row = ipc_get_arg2(icall);
+
+	if (srv->srvs->ops->set_pos == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->set_pos(srv, col, row);
+	async_answer_0(icall, EOK);
+}
+
+static void con_get_pos_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	errno_t rc;
+	sysarg_t col;
+	sysarg_t row;
+
+	if (srv->srvs->ops->get_pos == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	rc = srv->srvs->ops->get_pos(srv, &col, &row);
+	async_answer_2(icall, rc, col, row);
+}
+
+static void con_get_size_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	errno_t rc;
+	sysarg_t cols;
+	sysarg_t rows;
+
+	if (srv->srvs->ops->get_size == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	rc = srv->srvs->ops->get_size(srv, &cols, &rows);
+	async_answer_2(icall, rc, cols, rows);
+}
+
+static void con_get_color_cap_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	errno_t rc;
+	console_caps_t ccap;
+
+	if (srv->srvs->ops->get_color_cap == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	rc = srv->srvs->ops->get_color_cap(srv, &ccap);
+	async_answer_1(icall, rc, (sysarg_t)ccap);
+}
+
+static void con_set_style_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	console_style_t style;
+
+	style = ipc_get_arg1(icall);
+
+	if (srv->srvs->ops->set_style == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->set_style(srv, style);
+	async_answer_0(icall, EOK);
+}
+
+static void con_set_color_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	console_color_t bgcolor;
+	console_color_t fgcolor;
+	console_color_attr_t flags;
+
+	bgcolor = ipc_get_arg1(icall);
+	fgcolor = ipc_get_arg2(icall);
+	flags = ipc_get_arg3(icall);
+
+	if (srv->srvs->ops->set_color == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->set_color(srv, bgcolor, fgcolor, flags);
+	async_answer_0(icall, EOK);
+}
+
+static void con_set_rgb_color_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	pixel_t bgcolor;
+	pixel_t fgcolor;
+
+	bgcolor = ipc_get_arg1(icall);
+	fgcolor = ipc_get_arg2(icall);
+
+	if (srv->srvs->ops->set_rgb_color == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->set_rgb_color(srv, bgcolor, fgcolor);
+	async_answer_0(icall, EOK);
+}
+
+static void con_set_cursor_visibility_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	bool show;
+
+	show = ipc_get_arg1(icall);
+
+	if (srv->srvs->ops->set_cursor_visibility == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->set_cursor_visibility(srv, show);
+	async_answer_0(icall, EOK);
+}
+
+static void con_set_caption_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	char *caption;
+	errno_t rc;
+
+	rc = async_data_write_accept((void **) &caption, true, 0,
+	    CON_CAPTION_MAXLEN, 0, NULL);
+	if (rc != EOK) {
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	if (srv->srvs->ops->set_caption == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->set_caption(srv, caption);
+	free(caption);
+	async_answer_0(icall, EOK);
+}
+
+static void con_get_event_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	errno_t rc;
+	cons_event_t event;
+	ipc_call_t result;
+
+	if (srv->srvs->ops->get_event == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	rc = srv->srvs->ops->get_event(srv, &event);
+	if (rc != EOK) {
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	rc = console_ev_encode(&event, &result);
+	if (rc != EOK) {
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	async_answer_5(icall, rc, ipc_get_arg1(&result), ipc_get_arg2(&result),
+	    ipc_get_arg3(&result), ipc_get_arg4(&result), ipc_get_arg5(&result));
+}
+
+/** Create shared buffer for efficient rendering */
+static void con_map_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	errno_t rc;
+	charfield_t *buf;
+	sysarg_t cols, rows;
+	ipc_call_t call;
+	size_t size;
+
+	if (srv->srvs->ops->map == NULL || srv->srvs->ops->unmap == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	cols = ipc_get_arg1(icall);
+	rows = ipc_get_arg2(icall);
+
+	if (!async_share_in_receive(&call, &size)) {
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	/* Check size */
+	if (size != PAGES2SIZE(SIZE2PAGES(cols * rows * sizeof(charfield_t)))) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = srv->srvs->ops->map(srv, cols, rows, &buf);
+	if (rc != EOK) {
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	rc = async_share_in_finalize(&call, buf, AS_AREA_READ |
+	    AS_AREA_WRITE | AS_AREA_CACHEABLE);
+	if (rc != EOK) {
+		srv->srvs->ops->unmap(srv);
+		async_answer_0(icall, EIO);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+}
+
+/** Delete shared buffer */
+static void con_unmap_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	if (srv->srvs->ops->unmap == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->unmap(srv);
+	async_answer_0(icall, EOK);
+}
+
+/** Update console area from shared buffer */
+static void con_update_srv(con_srv_t *srv, ipc_call_t *icall)
+{
+	sysarg_t c0, r0, c1, r1;
+
+	c0 = ipc_get_arg1(icall);
+	r0 = ipc_get_arg2(icall);
+	c1 = ipc_get_arg3(icall);
+	r1 = ipc_get_arg4(icall);
+
+	if (srv->srvs->ops->update == NULL) {
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	srv->srvs->ops->update(srv, c0, r0, c1, r1);
+	async_answer_0(icall, EOK);
+}
+
+static con_srv_t *con_srv_create(con_srvs_t *srvs)
+{
+	con_srv_t *srv;
+
+	srv = calloc(1, sizeof(*srv));
+	if (srv == NULL)
+		return NULL;
+
+	srv->srvs = srvs;
+	return srv;
+}
+
+void con_srvs_init(con_srvs_t *srvs)
+{
+	srvs->ops = NULL;
+	srvs->sarg = NULL;
+	srvs->abort_timeout = 0;
+	srvs->aborted = false;
+}
+
+errno_t con_conn(ipc_call_t *icall, con_srvs_t *srvs)
+{
+	con_srv_t *srv;
+	errno_t rc;
+
+	/* Accept the connection */
+	async_accept_0(icall);
+
+	srv = con_srv_create(srvs);
+	if (srv == NULL)
+		return ENOMEM;
+
+	srv->client_sess = NULL;
+
+	rc = srvs->ops->open(srvs, srv);
+	if (rc != EOK)
+		return rc;
+
+	while (true) {
+		ipc_call_t call;
+		bool received = false;
+
+		while (!received) {
+			/* XXX Need to be able to abort immediately */
+			received = async_get_call_timeout(&call,
+			    srvs->abort_timeout);
+
+			if (srv->srvs->aborted) {
+				if (received)
+					async_answer_0(&call, EINTR);
+				break;
+			}
+		}
+
+		if (!received)
+			break;
+
+		sysarg_t method = ipc_get_imethod(&call);
+
+		if (!method) {
+			/* The other side has hung up */
+			async_answer_0(&call, EOK);
+			break;
+		}
+
+		switch (method) {
+		case VFS_OUT_READ:
+			con_read_srv(srv, &call);
+			break;
+		case VFS_OUT_WRITE:
+			con_write_srv(srv, &call);
+			break;
+		case VFS_OUT_SYNC:
+			con_sync_srv(srv, &call);
+			break;
+		case CONSOLE_CLEAR:
+			con_clear_srv(srv, &call);
+			break;
+		case CONSOLE_SET_POS:
+			con_set_pos_srv(srv, &call);
+			break;
+		case CONSOLE_GET_POS:
+			con_get_pos_srv(srv, &call);
+			break;
+		case CONSOLE_GET_SIZE:
+			con_get_size_srv(srv, &call);
+			break;
+		case CONSOLE_GET_COLOR_CAP:
+			con_get_color_cap_srv(srv, &call);
+			break;
+		case CONSOLE_SET_STYLE:
+			con_set_style_srv(srv, &call);
+			break;
+		case CONSOLE_SET_COLOR:
+			con_set_color_srv(srv, &call);
+			break;
+		case CONSOLE_SET_RGB_COLOR:
+			con_set_rgb_color_srv(srv, &call);
+			break;
+		case CONSOLE_SET_CURSOR_VISIBILITY:
+			con_set_cursor_visibility_srv(srv, &call);
+			break;
+		case CONSOLE_SET_CAPTION:
+			con_set_caption_srv(srv, &call);
+			break;
+		case CONSOLE_GET_EVENT:
+			con_get_event_srv(srv, &call);
+			break;
+		case CONSOLE_MAP:
+			con_map_srv(srv, &call);
+			break;
+		case CONSOLE_UNMAP:
+			con_unmap_srv(srv, &call);
+			break;
+		case CONSOLE_UPDATE:
+			con_update_srv(srv, &call);
+			break;
+		default:
+			async_answer_0(&call, ENOTSUP);
+		}
+	}
+
+	rc = srvs->ops->close(srv);
+	free(srv);
+
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/console/src/console.c
===================================================================
--- uspace/lib/console/src/console.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/console/src/console.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2006 Jakub Vana
+ * 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 libconsole
+ * @{
+ */
+/** @file
+ */
+
+#include <as.h>
+#include <libc.h>
+#include <async.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <str.h>
+#include <vfs/vfs_sess.h>
+#include <io/console.h>
+#include <ipc/console.h>
+
+console_ctrl_t *console_init(FILE *ifile, FILE *ofile)
+{
+	console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t));
+	if (!ctrl)
+		return NULL;
+
+	ctrl->input_sess = vfs_fsession(ifile, INTERFACE_CONSOLE);
+	if (!ctrl->input_sess) {
+		free(ctrl);
+		return NULL;
+	}
+
+	ctrl->output_sess = vfs_fsession(ofile, INTERFACE_CONSOLE);
+	if (!ctrl->output_sess) {
+		free(ctrl);
+		return NULL;
+	}
+
+	ctrl->input = ifile;
+	ctrl->output = ofile;
+	ctrl->input_aid = 0;
+
+	return ctrl;
+}
+
+void console_done(console_ctrl_t *ctrl)
+{
+	free(ctrl);
+}
+
+bool console_kcon(void)
+{
+	return __SYSCALL0(SYS_DEBUG_CONSOLE);
+}
+
+void console_flush(console_ctrl_t *ctrl)
+{
+	fflush(ctrl->output);
+}
+
+void console_clear(console_ctrl_t *ctrl)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_req_0_0(exch, CONSOLE_CLEAR);
+	async_exchange_end(exch);
+}
+
+errno_t console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	errno_t rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+void console_set_style(console_ctrl_t *ctrl, uint8_t style)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_req_1_0(exch, CONSOLE_SET_STYLE, style);
+	async_exchange_end(exch);
+}
+
+void console_set_color(console_ctrl_t *ctrl, uint8_t bgcolor, uint8_t fgcolor,
+    uint8_t flags)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_req_3_0(exch, CONSOLE_SET_COLOR, bgcolor, fgcolor, flags);
+	async_exchange_end(exch);
+}
+
+void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t bgcolor,
+    uint32_t fgcolor)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_req_2_0(exch, CONSOLE_SET_RGB_COLOR, bgcolor, fgcolor);
+	async_exchange_end(exch);
+}
+
+void console_cursor_visibility(console_ctrl_t *ctrl, bool show)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_req_1_0(exch, CONSOLE_SET_CURSOR_VISIBILITY, (show != false));
+	async_exchange_end(exch);
+}
+
+/** Set console caption.
+ *
+ * Set caption text for the console (if the console suports captions).
+ *
+ * @param ctrl Console
+ * @param caption Caption text
+ * @return EOK on success or an error code
+ */
+errno_t console_set_caption(console_ctrl_t *ctrl, const char *caption)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, CONSOLE_SET_CAPTION, &answer);
+	errno_t retval = async_data_write_start(exch, caption, str_size(caption));
+
+	if (retval != EOK) {
+		async_forget(req);
+		async_exchange_end(exch);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
+	async_exchange_end(exch);
+	return EOK;
+}
+
+errno_t console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	errno_t rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+errno_t console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	errno_t rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	async_req_2_0(exch, CONSOLE_SET_POS, col, row);
+	async_exchange_end(exch);
+}
+
+static errno_t console_ev_decode(ipc_call_t *call, cons_event_t *event)
+{
+	event->type = ipc_get_arg1(call);
+
+	switch (event->type) {
+	case CEV_KEY:
+		event->ev.key.type = ipc_get_arg2(call);
+		event->ev.key.key = ipc_get_arg3(call);
+		event->ev.key.mods = ipc_get_arg4(call);
+		event->ev.key.c = ipc_get_arg5(call);
+		break;
+	case CEV_POS:
+		event->ev.pos.pos_id = ipc_get_arg2(call) >> 16;
+		event->ev.pos.type = ipc_get_arg2(call) & 0xffff;
+		event->ev.pos.btn_num = ipc_get_arg3(call);
+		event->ev.pos.hpos = ipc_get_arg4(call);
+		event->ev.pos.vpos = ipc_get_arg5(call);
+		break;
+	default:
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/** Get console event.
+ *
+ * @param ctrl Console
+ * @param event Place to store event
+ * @return EOK on success, EIO on failure
+ */
+errno_t console_get_event(console_ctrl_t *ctrl, cons_event_t *event)
+{
+	if (ctrl->input_aid == 0) {
+		ipc_call_t result;
+
+		async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
+		aid_t aid = async_send_0(exch, CONSOLE_GET_EVENT, &result);
+		async_exchange_end(exch);
+
+		errno_t rc;
+		async_wait_for(aid, &rc);
+
+		if (rc != EOK)
+			return EIO;
+
+		rc = console_ev_decode(&result, event);
+		if (rc != EOK)
+			return EIO;
+	} else {
+		errno_t retval;
+		async_wait_for(ctrl->input_aid, &retval);
+
+		ctrl->input_aid = 0;
+
+		if (retval != EOK)
+			return EIO;
+
+		errno_t rc = console_ev_decode(&ctrl->input_call, event);
+		if (rc != EOK)
+			return EIO;
+	}
+
+	return EOK;
+}
+
+/** Get console event with timeout.
+ *
+ * @param ctrl Console
+ * @param event Place to store event
+ * @param timeout Pointer to timeout. This will be updated to reflect
+ *                the remaining time in case of timeout.
+ * @return EOK on success (event received), ETIMEOUT on time out,
+ *         EIO on I/O error (e.g. lost console connection), ENOMEM
+ *         if out of memory
+ */
+errno_t console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event,
+    usec_t *timeout)
+{
+	struct timespec t0;
+	getuptime(&t0);
+
+	if (ctrl->input_aid == 0) {
+		async_exch_t *exch = async_exchange_begin(ctrl->input_sess);
+		ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT,
+		    &ctrl->input_call);
+		async_exchange_end(exch);
+	}
+
+	errno_t retval;
+	errno_t rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout);
+	if (rc != EOK) {
+		if (rc == ENOMEM)
+			return ENOMEM;
+		*timeout = 0;
+		return ETIMEOUT;
+	}
+
+	ctrl->input_aid = 0;
+
+	if (retval != EOK)
+		return EIO;
+
+	rc = console_ev_decode(&ctrl->input_call, event);
+	if (rc != EOK)
+		return EIO;
+
+	/* Update timeout */
+	struct timespec t1;
+	getuptime(&t1);
+	*timeout -= NSEC2USEC(ts_sub_diff(&t1, &t0));
+
+	return EOK;
+}
+
+/** Create a shared buffer for fast rendering to the console.
+ *
+ * @param ctrl Console
+ * @param cols Number of columns
+ * @param rows Number of rows
+ * @param rbuf Place to store pointer to the shared buffer
+ * @return EOK on success or an error code
+ */
+errno_t console_map(console_ctrl_t *ctrl, sysarg_t cols, sysarg_t rows,
+    charfield_t **rbuf)
+{
+	async_exch_t *exch = NULL;
+	void *buf;
+	aid_t req;
+	ipc_call_t answer;
+	size_t asize;
+	errno_t rc;
+
+	exch = async_exchange_begin(ctrl->output_sess);
+	req = async_send_2(exch, CONSOLE_MAP, cols, rows, &answer);
+
+	asize = PAGES2SIZE(SIZE2PAGES(cols * rows * sizeof(charfield_t)));
+
+	rc = async_share_in_start_0_0(exch, asize, &buf);
+	if (rc != EOK) {
+		async_forget(req);
+		goto error;
+	}
+
+	async_exchange_end(exch);
+	exch = NULL;
+
+	async_wait_for(req, &rc);
+	if (rc != EOK)
+		goto error;
+
+	*rbuf = (charfield_t *)buf;
+	return EOK;
+error:
+	if (exch != NULL)
+		async_exchange_end(exch);
+	return rc;
+}
+
+/** Unmap console shared buffer.
+ *
+ * @param ctrl Console
+ * @param buf Buffer
+ */
+void console_unmap(console_ctrl_t *ctrl, charfield_t *buf)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	(void) async_req_0_0(exch, CONSOLE_UNMAP);
+	async_exchange_end(exch);
+
+	as_area_destroy(buf);
+}
+
+/** Update console rectangle from shared buffer.
+ *
+ * @param ctrl Console
+ * @param c0 Column coordinate of top-left corner (inclusive)
+ * @param r0 Row coordinate of top-left corner (inclusive)
+ * @param c1 Column coordinate of bottom-right corner (exclusive)
+ * @param r1 Row coordinate of bottom-right corner (exclusive)
+ *
+ * @return EOK on sucess or an error code
+ */
+errno_t console_update(console_ctrl_t *ctrl, sysarg_t c0, sysarg_t r0,
+    sysarg_t c1, sysarg_t r1)
+{
+	async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
+	errno_t rc = async_req_4_0(exch, CONSOLE_UPDATE, c0, r0, c1, r1);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/corecfg/doc/doxygroups.h
===================================================================
--- uspace/lib/corecfg/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/corecfg/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,3 @@
+/** @addtogroup libcorecfg libcorecfg
+ * @ingroup libs
+ */
Index: uspace/lib/corecfg/include/corecfg.h
===================================================================
--- uspace/lib/corecfg/include/corecfg.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/corecfg/include/corecfg.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,48 @@
+/*
+ * 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 libcorecfg
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBCORECFG_CORECFG_H_
+#define _LIBCORECFG_CORECFG_H_
+
+#include <errno.h>
+#include <stdbool.h>
+
+extern errno_t corecfg_init(void);
+extern errno_t corecfg_set_enable(bool);
+extern errno_t corecfg_get_enable(bool *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/corecfg/include/ipc/corecfg.h
===================================================================
--- uspace/lib/corecfg/include/ipc/corecfg.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/corecfg/include/ipc/corecfg.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,46 @@
+/*
+ * 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 libcorecfg
+ * @{
+ */
+
+#ifndef _LIBCORECFG_IPC_CORECFG_H_
+#define _LIBCORECFG_IPC_CORECFG_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	CORECFG_GET_ENABLE = IPC_FIRST_USER_METHOD,
+	CORECFG_SET_ENABLE
+} corecfg_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/corecfg/meson.build
===================================================================
--- uspace/lib/corecfg/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/corecfg/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+src = files('src/corecfg.c')
Index: uspace/lib/corecfg/src/corecfg.c
===================================================================
--- uspace/lib/corecfg/src/corecfg.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/corecfg/src/corecfg.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013 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.
+ */
+
+#include <async.h>
+#include <assert.h>
+#include <corecfg.h>
+#include <errno.h>
+#include <ipc/corecfg.h>
+#include <ipc/services.h>
+#include <loc.h>
+#include <stdlib.h>
+
+static async_sess_t *corecfg_sess = NULL;
+
+errno_t corecfg_init(void)
+{
+	service_id_t corecfg_svc;
+	errno_t rc;
+
+	assert(corecfg_sess == NULL);
+
+	rc = loc_service_get_id(SERVICE_NAME_CORECFG, &corecfg_svc,
+	    IPC_FLAG_BLOCKING);
+	if (rc != EOK)
+		return ENOENT;
+
+	corecfg_sess = loc_service_connect(corecfg_svc, INTERFACE_CORECFG,
+	    IPC_FLAG_BLOCKING);
+	if (corecfg_sess == NULL)
+		return ENOENT;
+
+	return EOK;
+}
+
+/** Get core dump enable status. */
+errno_t corecfg_get_enable(bool *renable)
+{
+	async_exch_t *exch = async_exchange_begin(corecfg_sess);
+	sysarg_t enable;
+
+	errno_t rc = async_req_0_1(exch, CORECFG_GET_ENABLE, &enable);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK)
+		return rc;
+
+	*renable = enable;
+	return EOK;
+}
+
+/** Enable or disable core dumps. */
+errno_t corecfg_set_enable(bool enable)
+{
+	async_exch_t *exch = async_exchange_begin(corecfg_sess);
+	errno_t rc = async_req_1_0(exch, CORECFG_SET_ENABLE, (sysarg_t) enable);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK)
+		return rc;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/display/meson.build
===================================================================
--- uspace/lib/display/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/display/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'gfx', 'ipcgfx' ]
+deps = [ 'gfx', 'ipcgfx', 'input' ]
 src = files(
 	'src/display.c',
Index: uspace/lib/fmtutil/meson.build
===================================================================
--- uspace/lib/fmtutil/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/fmtutil/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'console' ]
 src = files('fmtutil.c')
Index: uspace/lib/input/doc/doxygroups.h
===================================================================
--- uspace/lib/input/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,3 @@
+/** @addtogroup libinput libinput
+ * @ingroup libs
+ */
Index: uspace/lib/input/include/io/input.h
===================================================================
--- uspace/lib/input/include/io/input.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/io/input.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,68 @@
+/*
+ * 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 libinput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_INPUT_H_
+#define _LIBINPUT_INPUT_H_
+
+#include <async.h>
+#include <io/kbd_event.h>
+
+struct input_ev_ops;
+
+typedef struct {
+	async_sess_t *sess;
+	struct input_ev_ops *ev_ops;
+	void *user;
+} input_t;
+
+typedef struct input_ev_ops {
+	errno_t (*active)(input_t *);
+	errno_t (*deactive)(input_t *);
+	errno_t (*key)(input_t *, unsigned, kbd_event_type_t, keycode_t,
+	    keymod_t, char32_t);
+	errno_t (*move)(input_t *, unsigned, int, int);
+	errno_t (*abs_move)(input_t *, unsigned, unsigned, unsigned, unsigned,
+	    unsigned);
+	errno_t (*button)(input_t *, unsigned, int, int);
+	errno_t (*dclick)(input_t *, unsigned, int);
+} input_ev_ops_t;
+
+extern errno_t input_open(async_sess_t *, input_ev_ops_t *, void *, input_t **);
+extern void input_close(input_t *);
+extern errno_t input_activate(input_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/input/include/io/kbd_event.h
===================================================================
--- uspace/lib/input/include/io/kbd_event.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/io/kbd_event.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022 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 libinput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_IO_KBD_EVENT_H_
+#define _LIBINPUT_IO_KBD_EVENT_H_
+
+#include <adt/list.h>
+#include <inttypes.h>
+#include <io/keycode.h>
+#include <types/common.h>
+
+typedef enum {
+	KEY_PRESS,
+	KEY_RELEASE
+} kbd_event_type_t;
+
+/** Console event structure. */
+typedef struct {
+	/** List handle */
+	link_t link;
+
+	/** Keyboard device ID */
+	sysarg_t kbd_id;
+
+	/** Press or release event. */
+	kbd_event_type_t type;
+
+	/** Keycode of the key that was pressed or released. */
+	keycode_t key;
+
+	/** Bitmask of modifiers held. */
+	keymod_t mods;
+
+	/** The character that was generated or '\0' for none. */
+	char32_t c;
+} kbd_event_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/input/include/io/keycode.h
===================================================================
--- uspace/lib/input/include/io/keycode.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/io/keycode.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2009 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 libinput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_IO_KEYCODE_H_
+#define _LIBINPUT_IO_KEYCODE_H_
+
+/** Keycode definitions.
+ *
+ * A keycode identifies a key by its position on the keyboard, rather
+ * than by its label. For human readability, key positions are noted
+ * with the key label on a keyboard with US layout. This label has
+ * nothing to do with the character, that the key produces
+ * -- this is determined by the keymap.
+ *
+ * The keyboard model reflects a standard PC keyboard layout.
+ * Non-standard keyboards need to be mapped to this model in some
+ * logical way. Scancodes are mapped to keycodes with a scanmap.
+ *
+ * For easier mapping to the model and to emphasize the nature of keycodes,
+ * they really are organized here by position, rather than by label.
+ */
+typedef enum {
+
+	/* Main block row 1 */
+
+	KC_BACKTICK = 1,
+
+	KC_1,
+	KC_2,
+	KC_3,
+	KC_4,
+	KC_5,
+	KC_6,
+	KC_7,
+	KC_8,
+	KC_9,
+	KC_0,
+
+	KC_MINUS,
+	KC_EQUALS,
+	KC_BACKSPACE,
+
+	/* Main block row 2 */
+
+	KC_TAB,
+
+	KC_Q,
+	KC_W,
+	KC_E,
+	KC_R,
+	KC_T,
+	KC_Y,
+	KC_U,
+	KC_I,
+	KC_O,
+	KC_P,
+
+	KC_LBRACKET,
+	KC_RBRACKET,
+
+	/* Main block row 3 */
+
+	KC_CAPS_LOCK,
+
+	KC_A,
+	KC_S,
+	KC_D,
+	KC_F,
+	KC_G,
+	KC_H,
+	KC_J,
+	KC_K,
+	KC_L,
+
+	KC_SEMICOLON,
+	KC_QUOTE,
+	KC_BACKSLASH,
+	KC_HASH,
+
+	KC_ENTER,
+
+	/* Main block row 4 */
+
+	KC_LSHIFT,
+
+	KC_Z,
+	KC_X,
+	KC_C,
+	KC_V,
+	KC_B,
+	KC_N,
+	KC_M,
+
+	KC_COMMA,
+	KC_PERIOD,
+	KC_SLASH,
+
+	KC_RSHIFT,
+
+	/* Main block row 5 */
+
+	KC_LCTRL,
+	KC_LALT,
+	KC_SPACE,
+	KC_RALT,
+	KC_RCTRL,
+
+	/* Function keys block */
+
+	KC_ESCAPE,
+
+	KC_F1,
+	KC_F2,
+	KC_F3,
+	KC_F4,
+	KC_F5,
+	KC_F6,
+	KC_F7,
+	KC_F8,
+	KC_F9,
+	KC_F10,
+	KC_F11,
+	KC_F12,
+
+	KC_PRTSCR,
+	KC_SYSREQ,
+	KC_SCROLL_LOCK,
+	KC_PAUSE,
+	KC_BREAK,
+
+	/* Cursor keys block */
+
+	KC_INSERT,
+	KC_HOME,
+	KC_PAGE_UP,
+
+	KC_DELETE,
+	KC_END,
+	KC_PAGE_DOWN,
+
+	KC_UP,
+	KC_LEFT,
+	KC_DOWN,
+	KC_RIGHT,
+
+	/* Numeric block */
+
+	KC_NUM_LOCK,
+	KC_NSLASH,
+	KC_NTIMES,
+	KC_NMINUS,
+
+	KC_NPLUS,
+	KC_NENTER,
+
+	KC_N7,
+	KC_N8,
+	KC_N9,
+
+	KC_N4,
+	KC_N5,
+	KC_N6,
+
+	KC_N1,
+	KC_N2,
+	KC_N3,
+
+	KC_N0,
+	KC_NPERIOD
+
+} keycode_t;
+
+typedef enum {
+	KM_LSHIFT      = 0x001,
+	KM_RSHIFT      = 0x002,
+	KM_LCTRL       = 0x004,
+	KM_RCTRL       = 0x008,
+	KM_LALT        = 0x010,
+	KM_RALT        = 0x020,
+	KM_CAPS_LOCK   = 0x040,
+	KM_NUM_LOCK    = 0x080,
+	KM_SCROLL_LOCK = 0x100,
+
+	KM_SHIFT       = KM_LSHIFT | KM_RSHIFT,
+	KM_CTRL        = KM_LCTRL | KM_RCTRL,
+	KM_ALT         = KM_LALT | KM_RALT
+} keymod_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/input/include/io/pos_event.h
===================================================================
--- uspace/lib/input/include/io/pos_event.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/io/pos_event.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2012 Petr Koupy
+ * 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 libinput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_IO_POS_EVENT_H_
+#define _LIBINPUT_IO_POS_EVENT_H_
+
+#include <types/common.h>
+
+typedef enum {
+	/** Position update */
+	POS_UPDATE,
+	/** Button press */
+	POS_PRESS,
+	/** Button release */
+	POS_RELEASE,
+	/** Double click */
+	POS_DCLICK
+} pos_event_type_t;
+
+/** Positioning device event */
+typedef struct {
+	sysarg_t pos_id;
+	pos_event_type_t type;
+	sysarg_t btn_num;
+	sysarg_t hpos;
+	sysarg_t vpos;
+} pos_event_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/input/include/ipc/input.h
===================================================================
--- uspace/lib/input/include/ipc/input.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/ipc/input.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,58 @@
+/*
+ * 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 libinput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_IPC_INPUT_H_
+#define _LIBINPUT_IPC_INPUT_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	INPUT_ACTIVATE = IPC_FIRST_USER_METHOD
+} input_request_t;
+
+typedef enum {
+	INPUT_EVENT_ACTIVE = IPC_FIRST_USER_METHOD,
+	INPUT_EVENT_DEACTIVE,
+	INPUT_EVENT_KEY,
+	INPUT_EVENT_MOVE,
+	INPUT_EVENT_ABS_MOVE,
+	INPUT_EVENT_BUTTON,
+	INPUT_EVENT_DCLICK
+} input_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/input/include/ipc/kbdev.h
===================================================================
--- uspace/lib/input/include/ipc/kbdev.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/ipc/kbdev.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,55 @@
+/*
+ * 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 libinput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_IPC_KBDEV_H_
+#define _LIBINPUT_IPC_KBDEV_H_
+
+#include <ipc/common.h>
+#include <ipc/dev_iface.h>
+
+typedef enum {
+	KBDEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
+	KBDEV_RECLAIM,
+	KBDEV_SET_IND
+} kbdev_request_t;
+
+typedef enum {
+	KBDEV_EVENT = IPC_FIRST_USER_METHOD
+} kbdev_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/input/include/ipc/mouseev.h
===================================================================
--- uspace/lib/input/include/ipc/mouseev.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/include/ipc/mouseev.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,57 @@
+/*
+ * 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 libinput
+ * @brief
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBINPUT_IPC_MOUSEEV_H_
+#define _LIBINPUT_IPC_MOUSEEV_H_
+
+#include <ipc/common.h>
+#include <ipc/dev_iface.h>
+
+typedef enum {
+	MOUSEEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
+	MOUSEEV_RECLAIM
+} mouseev_request_t;
+
+typedef enum {
+	MOUSEEV_MOVE_EVENT = IPC_FIRST_USER_METHOD,
+	MOUSEEV_ABS_MOVE_EVENT,
+	MOUSEEV_BUTTON_EVENT
+} mouseev_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/input/meson.build
===================================================================
--- uspace/lib/input/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+src = files(
+	'src/input.c',
+)
Index: uspace/lib/input/src/input.c
===================================================================
--- uspace/lib/input/src/input.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/input/src/input.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,229 @@
+/*
+ * 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 libinput
+ * @{
+ */
+/**
+ * @file
+ * @brief Input protocol client stub
+ */
+
+#include <async.h>
+#include <assert.h>
+#include <errno.h>
+#include <io/kbd_event.h>
+#include <io/input.h>
+#include <ipc/input.h>
+#include <stdlib.h>
+
+static void input_cb_conn(ipc_call_t *icall, void *arg);
+
+errno_t input_open(async_sess_t *sess, input_ev_ops_t *ev_ops,
+    void *arg, input_t **rinput)
+{
+	input_t *input = calloc(1, sizeof(input_t));
+	if (input == NULL)
+		return ENOMEM;
+
+	input->sess = sess;
+	input->ev_ops = ev_ops;
+	input->user = arg;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	port_id_t port;
+	errno_t rc = async_create_callback_port(exch, INTERFACE_INPUT_CB, 0, 0,
+	    input_cb_conn, input, &port);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK)
+		goto error;
+
+	*rinput = input;
+	return EOK;
+
+error:
+	if (input != NULL)
+		free(input);
+
+	return rc;
+}
+
+void input_close(input_t *input)
+{
+	/* XXX Synchronize with input_cb_conn */
+	free(input);
+}
+
+errno_t input_activate(input_t *input)
+{
+	async_exch_t *exch = async_exchange_begin(input->sess);
+	errno_t rc = async_req_0_0(exch, INPUT_ACTIVATE);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+static void input_ev_active(input_t *input, ipc_call_t *call)
+{
+	errno_t rc = input->ev_ops->active(input);
+	async_answer_0(call, rc);
+}
+
+static void input_ev_deactive(input_t *input, ipc_call_t *call)
+{
+	errno_t rc = input->ev_ops->deactive(input);
+	async_answer_0(call, rc);
+}
+
+static void input_ev_key(input_t *input, ipc_call_t *call)
+{
+	unsigned kbd_id;
+	kbd_event_type_t type;
+	keycode_t key;
+	keymod_t mods;
+	char32_t c;
+	errno_t rc;
+
+	kbd_id = ipc_get_arg1(call);
+	type = ipc_get_arg2(call);
+	key = ipc_get_arg3(call);
+	mods = ipc_get_arg4(call);
+	c = ipc_get_arg5(call);
+
+	rc = input->ev_ops->key(input, kbd_id, type, key, mods, c);
+	async_answer_0(call, rc);
+}
+
+static void input_ev_move(input_t *input, ipc_call_t *call)
+{
+	unsigned pos_id;
+	int dx;
+	int dy;
+	errno_t rc;
+
+	pos_id = ipc_get_arg1(call);
+	dx = ipc_get_arg2(call);
+	dy = ipc_get_arg3(call);
+
+	rc = input->ev_ops->move(input, pos_id, dx, dy);
+	async_answer_0(call, rc);
+}
+
+static void input_ev_abs_move(input_t *input, ipc_call_t *call)
+{
+	unsigned pos_id;
+	unsigned x;
+	unsigned y;
+	unsigned max_x;
+	unsigned max_y;
+	errno_t rc;
+
+	pos_id = ipc_get_arg1(call);
+	x = ipc_get_arg2(call);
+	y = ipc_get_arg3(call);
+	max_x = ipc_get_arg4(call);
+	max_y = ipc_get_arg5(call);
+
+	rc = input->ev_ops->abs_move(input, pos_id, x, y, max_x, max_y);
+	async_answer_0(call, rc);
+}
+
+static void input_ev_button(input_t *input, ipc_call_t *call)
+{
+	unsigned pos_id;
+	int bnum;
+	int press;
+	errno_t rc;
+
+	pos_id = ipc_get_arg1(call);
+	bnum = ipc_get_arg2(call);
+	press = ipc_get_arg3(call);
+
+	rc = input->ev_ops->button(input, pos_id, bnum, press);
+	async_answer_0(call, rc);
+}
+
+static void input_ev_dclick(input_t *input, ipc_call_t *call)
+{
+	unsigned pos_id;
+	int bnum;
+	errno_t rc;
+
+	pos_id = ipc_get_arg1(call);
+	bnum = ipc_get_arg2(call);
+
+	rc = input->ev_ops->dclick(input, pos_id, bnum);
+	async_answer_0(call, rc);
+}
+
+static void input_cb_conn(ipc_call_t *icall, void *arg)
+{
+	input_t *input = (input_t *) arg;
+
+	while (true) {
+		ipc_call_t call;
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call)) {
+			async_answer_0(&call, EOK);
+			return;
+		}
+
+		switch (ipc_get_imethod(&call)) {
+		case INPUT_EVENT_ACTIVE:
+			input_ev_active(input, &call);
+			break;
+		case INPUT_EVENT_DEACTIVE:
+			input_ev_deactive(input, &call);
+			break;
+		case INPUT_EVENT_KEY:
+			input_ev_key(input, &call);
+			break;
+		case INPUT_EVENT_MOVE:
+			input_ev_move(input, &call);
+			break;
+		case INPUT_EVENT_ABS_MOVE:
+			input_ev_abs_move(input, &call);
+			break;
+		case INPUT_EVENT_BUTTON:
+			input_ev_button(input, &call);
+			break;
+		case INPUT_EVENT_DCLICK:
+			input_ev_dclick(input, &call);
+			break;
+		default:
+			async_answer_0(&call, ENOTSUP);
+		}
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/ipctest/doc/doxygroups.h
===================================================================
--- uspace/lib/ipctest/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/ipctest/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,3 @@
+/** @addtogroup libipctest libipctest
+ * @ingroup libs
+ */
Index: uspace/lib/ipctest/include/ipc/ipc_test.h
===================================================================
--- uspace/lib/ipctest/include/ipc/ipc_test.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/ipctest/include/ipc/ipc_test.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,51 @@
+/*
+ * 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 libipctest
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBIPCTEST_IPC_IPC_TEST_H_
+#define _LIBIPCTEST_IPC_IPC_TEST_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	IPC_TEST_PING = IPC_FIRST_USER_METHOD,
+	IPC_TEST_GET_RO_AREA_SIZE,
+	IPC_TEST_GET_RW_AREA_SIZE,
+	IPC_TEST_SHARE_IN_RO,
+	IPC_TEST_SHARE_IN_RW
+} ipc_test_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ipctest/include/ipc_test.h
===================================================================
--- uspace/lib/ipctest/include/ipc_test.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/ipctest/include/ipc_test.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,56 @@
+/*
+ * 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 libipctest
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBIPCTEST_H_
+#define _LIBIPCTEST_H_
+
+#include <async.h>
+#include <errno.h>
+
+typedef struct {
+	async_sess_t *sess;
+} ipc_test_t;
+
+extern errno_t ipc_test_create(ipc_test_t **);
+extern void ipc_test_destroy(ipc_test_t *);
+extern errno_t ipc_test_ping(ipc_test_t *);
+extern errno_t ipc_test_get_ro_area_size(ipc_test_t *, size_t *);
+extern errno_t ipc_test_get_rw_area_size(ipc_test_t *, size_t *);
+extern errno_t ipc_test_share_in_ro(ipc_test_t *, size_t, const void **);
+extern errno_t ipc_test_share_in_rw(ipc_test_t *, size_t, void **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/ipctest/meson.build
===================================================================
--- uspace/lib/ipctest/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/ipctest/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+src = files('src/ipc_test.c')
Index: uspace/lib/ipctest/src/ipc_test.c
===================================================================
--- uspace/lib/ipctest/src/ipc_test.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/ipctest/src/ipc_test.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2018 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 libc
+ * @{
+ */
+/** @file IPC test service API
+ */
+
+#include <abi/ipc/interfaces.h>
+#include <as.h>
+#include <errno.h>
+#include <ipc/services.h>
+#include <ipc/ipc_test.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <ipc_test.h>
+
+/** Create IPC test service session.
+ *
+ * @param rvol Place to store pointer to volume service session.
+ * @return     EOK on success, ENOMEM if out of memory, EIO if service
+ *             cannot be contacted.
+ */
+errno_t ipc_test_create(ipc_test_t **rtest)
+{
+	ipc_test_t *test;
+	service_id_t test_svcid;
+	errno_t rc;
+
+	test = calloc(1, sizeof(ipc_test_t));
+	if (test == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = loc_service_get_id(SERVICE_NAME_IPC_TEST, &test_svcid, 0);
+	if (rc != EOK) {
+		rc = ENOENT;
+		goto error;
+	}
+
+	test->sess = loc_service_connect(test_svcid, INTERFACE_IPC_TEST, 0);
+	if (test->sess == NULL) {
+		rc = EIO;
+		goto error;
+	}
+
+	*rtest = test;
+	return EOK;
+error:
+	free(test);
+	return rc;
+}
+
+/** Destroy IPC test service session.
+ *
+ * @param test IPC test service session
+ */
+void ipc_test_destroy(ipc_test_t *test)
+{
+	if (test == NULL)
+		return;
+
+	async_hangup(test->sess);
+	free(test);
+}
+
+/** Simple ping.
+ *
+ * @param test IPC test service
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_ping(ipc_test_t *test)
+{
+	async_exch_t *exch;
+	errno_t retval;
+
+	exch = async_exchange_begin(test->sess);
+	retval = async_req_0_0(exch, IPC_TEST_PING);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	return EOK;
+}
+
+/** Get size of shared read-only memory area.
+ *
+ * @param test IPC test service
+ * @param rsize Place to store size of the shared area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_get_ro_area_size(ipc_test_t *test, size_t *rsize)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	sysarg_t size;
+
+	exch = async_exchange_begin(test->sess);
+	retval = async_req_0_1(exch, IPC_TEST_GET_RO_AREA_SIZE, &size);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	*rsize = size;
+	return EOK;
+}
+
+/** Get size of shared read-write memory area.
+ *
+ * @param test IPC test service
+ * @param rsize Place to store size of the shared area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_get_rw_area_size(ipc_test_t *test, size_t *rsize)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	sysarg_t size;
+
+	exch = async_exchange_begin(test->sess);
+	retval = async_req_0_1(exch, IPC_TEST_GET_RW_AREA_SIZE, &size);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	*rsize = size;
+	return EOK;
+}
+
+/** Test share-in of read-only area.
+ *
+ * @param test IPC test service
+ * @param size Size of the shared area
+ * @param rptr Place to store pointer to the shared-in area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_share_in_ro(ipc_test_t *test, size_t size, const void **rptr)
+{
+	async_exch_t *exch;
+	ipc_call_t answer;
+	aid_t req;
+	void *dst;
+	errno_t rc;
+
+	exch = async_exchange_begin(test->sess);
+	req = async_send_0(exch, IPC_TEST_SHARE_IN_RO, &answer);
+
+	dst = NULL;
+	rc = async_share_in_start_0_0(exch, size, &dst);
+	if (rc != EOK || dst == AS_MAP_FAILED) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return ENOMEM;
+	}
+
+	async_exchange_end(exch);
+	async_wait_for(req, NULL);
+	*rptr = dst;
+	return EOK;
+}
+
+/** Test share-in of read-write area.
+ *
+ * @param test IPC test service
+ * @param size Size of the shared area
+ * @param rptr Place to store pointer to the shared-in area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_share_in_rw(ipc_test_t *test, size_t size, void **rptr)
+{
+	async_exch_t *exch;
+	ipc_call_t answer;
+	aid_t req;
+	void *dst;
+	errno_t rc;
+
+	exch = async_exchange_begin(test->sess);
+	req = async_send_0(exch, IPC_TEST_SHARE_IN_RW, &answer);
+
+	rc = async_share_in_start_0_0(exch, size, &dst);
+	if (rc != EOK || dst == AS_MAP_FAILED) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return ENOMEM;
+	}
+
+	async_exchange_end(exch);
+	async_wait_for(req, NULL);
+	*rptr = dst;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/meson.build
===================================================================
--- uspace/lib/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -53,10 +53,15 @@
 	'inet',
 
+	'input',
+	'output',
+	'console',
 	'device',
 
 	'block',
+	'clipboard',
 	'clui',
 	'codepage',
 	'compress',
+	'corecfg',
 	'cpp',
 	'crypto',
@@ -68,4 +73,5 @@
 	'gfx',
 	'http',
+	'ipctest',
 	'label',
 	'math',
Index: uspace/lib/output/doc/doxygroups.h
===================================================================
--- uspace/lib/output/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/doc/doxygroups.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,3 @@
+/** @addtogroup liboutput liboutput
+ * @ingroup libs
+ */
Index: uspace/lib/output/include/io/charfield.h
===================================================================
--- uspace/lib/output/include/io/charfield.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/include/io/charfield.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 Petr Koupy
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBOUTPUT_IO_CHARFIELD_H_
+#define _LIBOUTPUT_IO_CHARFIELD_H_
+
+#include <stdbool.h>
+#include <uchar.h>
+#include <io/color.h>
+#include <io/style.h>
+#include <io/pixel.h>
+
+typedef enum {
+	CHAR_FLAG_NONE = 0,
+	CHAR_FLAG_DIRTY = 1
+} char_flags_t;
+
+typedef enum {
+	CHAR_ATTR_STYLE,
+	CHAR_ATTR_INDEX,
+	CHAR_ATTR_RGB
+} char_attr_type_t;
+
+typedef struct {
+	console_color_t bgcolor;
+	console_color_t fgcolor;
+	console_color_attr_t attr;
+} char_attr_index_t;
+
+typedef struct {
+	pixel_t bgcolor;
+	pixel_t fgcolor;
+} char_attr_rgb_t;
+
+typedef union {
+	console_style_t style;
+	char_attr_index_t index;
+	char_attr_rgb_t rgb;
+} char_attr_val_t;
+
+typedef struct {
+	char_attr_type_t type;
+	char_attr_val_t val;
+} char_attrs_t;
+
+typedef struct {
+	char32_t ch;
+	char_attrs_t attrs;
+	char_flags_t flags;
+} charfield_t;
+
+static inline bool attrs_same(char_attrs_t a1, char_attrs_t a2)
+{
+	if (a1.type != a2.type)
+		return false;
+
+	switch (a1.type) {
+	case CHAR_ATTR_STYLE:
+		return (a1.val.style == a2.val.style);
+	case CHAR_ATTR_INDEX:
+		return (a1.val.index.bgcolor == a2.val.index.bgcolor) &&
+		    (a1.val.index.fgcolor == a2.val.index.fgcolor) &&
+		    (a1.val.index.attr == a2.val.index.attr);
+	case CHAR_ATTR_RGB:
+		return (a1.val.rgb.bgcolor == a2.val.rgb.bgcolor) &&
+		    (a1.val.rgb.fgcolor == a2.val.rgb.fgcolor);
+	}
+
+	return false;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/output/include/io/chargrid.h
===================================================================
--- uspace/lib/output/include/io/chargrid.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/include/io/chargrid.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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 liboutput
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef _LIBOUTPUT_IO_CHARGRID_H_
+#define _LIBOUTPUT_IO_CHARGRID_H_
+
+#include <io/charfield.h>
+#include <types/common.h>
+#include <stddef.h>
+
+typedef enum {
+	CHARGRID_FLAG_NONE = 0,
+	CHARGRID_FLAG_SHARED = 1
+} chargrid_flag_t;
+
+typedef struct {
+	size_t size;            /**< Structure size */
+	chargrid_flag_t flags;  /**< Screenbuffer flags */
+
+	sysarg_t cols;          /**< Number of columns */
+	sysarg_t rows;          /**< Number of rows */
+
+	sysarg_t col;           /**< Current column */
+	sysarg_t row;           /**< Current row */
+	bool cursor_visible;    /**< Cursor visibility */
+
+	char_attrs_t attrs;     /**< Current attributes */
+
+	sysarg_t top_row;       /**< The first row in the cyclic buffer */
+	charfield_t data[];     /**< Screen contents (cyclic buffer) */
+} chargrid_t;
+
+static inline charfield_t *chargrid_charfield_at(chargrid_t *chargrid,
+    sysarg_t col, sysarg_t row)
+{
+	return chargrid->data +
+	    ((row + chargrid->top_row) % chargrid->rows) * chargrid->cols +
+	    col;
+}
+
+extern chargrid_t *chargrid_create(sysarg_t, sysarg_t,
+    chargrid_flag_t);
+extern void chargrid_destroy(chargrid_t *);
+
+extern bool chargrid_cursor_at(chargrid_t *, sysarg_t, sysarg_t);
+
+extern sysarg_t chargrid_get_top_row(chargrid_t *);
+
+extern sysarg_t chargrid_putuchar(chargrid_t *, char32_t, bool);
+extern sysarg_t chargrid_newline(chargrid_t *);
+extern sysarg_t chargrid_tabstop(chargrid_t *, sysarg_t);
+extern sysarg_t chargrid_backspace(chargrid_t *);
+
+extern void chargrid_clear(chargrid_t *);
+extern void chargrid_clear_row(chargrid_t *, sysarg_t);
+
+extern void chargrid_set_cursor(chargrid_t *, sysarg_t, sysarg_t);
+extern void chargrid_set_cursor_visibility(chargrid_t *, bool);
+extern bool chargrid_get_cursor_visibility(chargrid_t *);
+
+extern void chargrid_get_cursor(chargrid_t *, sysarg_t *, sysarg_t *);
+
+extern void chargrid_set_style(chargrid_t *, console_style_t);
+extern void chargrid_set_color(chargrid_t *, console_color_t,
+    console_color_t, console_color_attr_t);
+extern void chargrid_set_rgb_color(chargrid_t *, pixel_t, pixel_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/output/include/io/color.h
===================================================================
--- uspace/lib/output/include/io/color.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/include/io/color.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,58 @@
+/*
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBOUTPUT_IO_COLOR_H_
+#define _LIBOUTPUT_IO_COLOR_H_
+
+typedef enum {
+	COLOR_BLACK   = 0,
+	COLOR_BLUE    = 1,
+	COLOR_GREEN   = 2,
+	COLOR_CYAN    = 3,
+	COLOR_RED     = 4,
+	COLOR_MAGENTA = 5,
+	COLOR_YELLOW  = 6,
+	COLOR_WHITE   = 7
+} console_color_t;
+
+typedef enum {
+	CATTR_NORMAL = 0,
+	CATTR_BRIGHT = 8,
+	CATTR_BLINK  = 16
+} console_color_attr_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/output/include/io/concaps.h
===================================================================
--- uspace/lib/output/include/io/concaps.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/include/io/concaps.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,48 @@
+/*
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBOUTPUT_IO_CONCAPS_H_
+#define _LIBOUTPUT_IO_CONCAPS_H_
+
+typedef enum {
+	CONSOLE_CAP_NONE = 0,
+	CONSOLE_CAP_STYLE = 1,
+	CONSOLE_CAP_INDEXED = 2,
+	CONSOLE_CAP_RGB = 4
+} console_caps_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/output/include/io/output.h
===================================================================
--- uspace/lib/output/include/io/output.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/include/io/output.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBOUTPUT_IO_OUTPUT_H_
+#define _LIBOUTPUT_IO_OUTPUT_H_
+
+#include <ipc/output.h>
+#include <io/chargrid.h>
+#include <io/concaps.h>
+#include <io/style.h>
+
+extern errno_t output_yield(async_sess_t *);
+extern errno_t output_claim(async_sess_t *);
+extern errno_t output_get_dimensions(async_sess_t *, sysarg_t *, sysarg_t *);
+extern errno_t output_get_caps(async_sess_t *, console_caps_t *);
+
+extern frontbuf_handle_t output_frontbuf_create(async_sess_t *, chargrid_t *);
+
+extern errno_t output_cursor_update(async_sess_t *, frontbuf_handle_t);
+extern errno_t output_set_style(async_sess_t *, console_style_t);
+
+extern errno_t output_update(async_sess_t *, frontbuf_handle_t);
+extern errno_t output_damage(async_sess_t *, frontbuf_handle_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/output/include/ipc/output.h
===================================================================
--- uspace/lib/output/include/ipc/output.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/include/ipc/output.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 Martin Decky
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBOUTPUT_IPC_OUTPUT_H_
+#define _LIBOUTPUT_IPC_OUTPUT_H_
+
+#include <ipc/common.h>
+
+typedef sysarg_t frontbuf_handle_t;
+
+typedef enum {
+	OUTPUT_YIELD = IPC_FIRST_USER_METHOD,
+	OUTPUT_CLAIM,
+	OUTPUT_GET_DIMENSIONS,
+	OUTPUT_GET_CAPS,
+
+	OUTPUT_FRONTBUF_CREATE,
+	OUTPUT_FRONTBUF_DESTROY,
+
+	OUTPUT_CURSOR_UPDATE,
+	OUTPUT_SET_STYLE,
+	OUTPUT_SET_COLOR,
+	OUTPUT_SET_RGB_COLOR,
+
+	OUTPUT_UPDATE,
+	OUTPUT_DAMAGE
+} output_request_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/output/meson.build
===================================================================
--- uspace/lib/output/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+src = files(
+	'src/chargrid.c',
+	'src/output.c',
+)
Index: uspace/lib/output/src/chargrid.c
===================================================================
--- uspace/lib/output/src/chargrid.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/src/chargrid.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#include <io/style.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <as.h>
+#include <io/chargrid.h>
+
+/** Create a chargrid.
+ *
+ * @param[in] cols  Number of columns.
+ * @param[in] rows  Number of rows.
+ * @param[in] flags Chargrid flags.
+ *
+ * @return New chargrid.
+ * @return NULL on failure.
+ *
+ */
+chargrid_t *chargrid_create(sysarg_t cols, sysarg_t rows,
+    chargrid_flag_t flags)
+{
+	size_t size =
+	    sizeof(chargrid_t) + cols * rows * sizeof(charfield_t);
+	chargrid_t *scrbuf;
+
+	if ((flags & CHARGRID_FLAG_SHARED) == CHARGRID_FLAG_SHARED) {
+		scrbuf = (chargrid_t *) as_area_create(AS_AREA_ANY, size,
+		    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
+		    AS_AREA_UNPAGED);
+		if (scrbuf == AS_MAP_FAILED)
+			return NULL;
+	} else {
+		scrbuf = (chargrid_t *) malloc(size);
+		if (scrbuf == NULL)
+			return NULL;
+	}
+
+	scrbuf->size = size;
+	scrbuf->flags = flags;
+	scrbuf->cols = cols;
+	scrbuf->rows = rows;
+	scrbuf->cursor_visible = false;
+
+	scrbuf->attrs.type = CHAR_ATTR_STYLE;
+	scrbuf->attrs.val.style = STYLE_NORMAL;
+
+	scrbuf->top_row = 0;
+	chargrid_clear(scrbuf);
+
+	return scrbuf;
+}
+
+void chargrid_destroy(chargrid_t *srcbuf)
+{
+	// TODO
+}
+
+bool chargrid_cursor_at(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
+{
+	return ((scrbuf->cursor_visible) && (scrbuf->col == col) &&
+	    (scrbuf->row == row));
+}
+
+sysarg_t chargrid_get_top_row(chargrid_t *scrbuf)
+{
+	return scrbuf->top_row;
+}
+
+static sysarg_t chargrid_update_rows(chargrid_t *scrbuf)
+{
+	if (scrbuf->row == scrbuf->rows) {
+		scrbuf->row = scrbuf->rows - 1;
+		scrbuf->top_row = (scrbuf->top_row + 1) % scrbuf->rows;
+		chargrid_clear_row(scrbuf, scrbuf->row);
+
+		return scrbuf->rows;
+	}
+
+	return 2;
+}
+
+static sysarg_t chargrid_update_cols(chargrid_t *scrbuf)
+{
+	/* Column overflow */
+	if (scrbuf->col == scrbuf->cols) {
+		scrbuf->col = 0;
+		scrbuf->row++;
+		return chargrid_update_rows(scrbuf);
+	}
+
+	return 1;
+}
+
+/** Store one character to chargrid.
+ *
+ * Its position is determined by scrbuf->col
+ * and scrbuf->row.
+ *
+ * @param scrbuf Chargrid.
+ * @param ch     Character to store.
+ * @param update Update coordinates.
+ *
+ * @return Number of rows which have been affected. In usual
+ *         situations this is 1. If the current position was
+ *         updated to a new row, this value is 2.
+ *
+ */
+sysarg_t chargrid_putuchar(chargrid_t *scrbuf, char32_t ch, bool update)
+{
+	assert(scrbuf->col < scrbuf->cols);
+	assert(scrbuf->row < scrbuf->rows);
+
+	charfield_t *field =
+	    chargrid_charfield_at(scrbuf, scrbuf->col, scrbuf->row);
+
+	field->ch = ch;
+	field->attrs = scrbuf->attrs;
+	field->flags |= CHAR_FLAG_DIRTY;
+
+	if (update) {
+		scrbuf->col++;
+		return chargrid_update_cols(scrbuf);
+	}
+
+	return 1;
+}
+
+/** Jump to a new row in chargrid.
+ *
+ * @param scrbuf Chargrid.
+ *
+ * @return Number of rows which have been affected. In usual
+ *         situations this is 2 (the original row and the new
+ *         row).
+ *
+ */
+sysarg_t chargrid_newline(chargrid_t *scrbuf)
+{
+	assert(scrbuf->col < scrbuf->cols);
+	assert(scrbuf->row < scrbuf->rows);
+
+	scrbuf->col = 0;
+	scrbuf->row++;
+
+	return chargrid_update_rows(scrbuf);
+}
+
+/** Jump to a new row in chargrid.
+ *
+ * @param scrbuf   Chargrid.
+ * @param tab_size Tab size.
+ *
+ * @return Number of rows which have been affected. In usual
+ *         situations this is 1. If the current position was
+ *         updated to a new row, this value is 2.
+ *
+ */
+sysarg_t chargrid_tabstop(chargrid_t *scrbuf, sysarg_t tab_size)
+{
+	assert(scrbuf->col < scrbuf->cols);
+	assert(scrbuf->row < scrbuf->rows);
+
+	sysarg_t spaces = tab_size - scrbuf->cols % tab_size;
+	sysarg_t flush = 1;
+
+	for (sysarg_t i = 0; i < spaces; i++)
+		flush += chargrid_putuchar(scrbuf, ' ', true) - 1;
+
+	return flush;
+}
+
+/** Jump to the previous character in chargrid.
+ *
+ * Currently no scrollback is supported.
+ *
+ * @param scrbuf Chargrid.
+ *
+ * @return Number of rows which have been affected. In usual
+ *         situations this is 1. If the current position was
+ *         updated to the previous row, this value is 2.
+ * @return 0 if no backspace is possible.
+ *
+ */
+sysarg_t chargrid_backspace(chargrid_t *scrbuf)
+{
+	assert(scrbuf->col < scrbuf->cols);
+	assert(scrbuf->row < scrbuf->rows);
+
+	if ((scrbuf->col == 0) && (scrbuf->row == 0))
+		return 0;
+
+	if (scrbuf->col == 0) {
+		scrbuf->col = scrbuf->cols - 1;
+		scrbuf->row--;
+
+		chargrid_putuchar(scrbuf, ' ', false);
+		return 2;
+	}
+
+	scrbuf->col--;
+	chargrid_putuchar(scrbuf, ' ', false);
+	return 1;
+}
+
+/** Clear the chargrid.
+ *
+ * @param scrbuf Chargrid.
+ *
+ */
+void chargrid_clear(chargrid_t *scrbuf)
+{
+	for (size_t pos = 0; pos < (scrbuf->cols * scrbuf->rows); pos++) {
+		scrbuf->data[pos].ch = 0;
+		scrbuf->data[pos].attrs = scrbuf->attrs;
+		scrbuf->data[pos].flags = CHAR_FLAG_DIRTY;
+	}
+
+	scrbuf->col = 0;
+	scrbuf->row = 0;
+}
+
+/** Update current chargrid coordinates
+ *
+ * @param scrbuf Chargrid.
+ * @param col    New column.
+ * @param row    New row.
+ *
+ */
+void chargrid_set_cursor(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
+{
+	if (col >= scrbuf->cols || row >= scrbuf->rows)
+		return;
+
+	scrbuf->col = col;
+	scrbuf->row = row;
+}
+
+void chargrid_set_cursor_visibility(chargrid_t *scrbuf, bool visible)
+{
+	scrbuf->cursor_visible = visible;
+}
+
+/** Get current chargrid coordinates
+ *
+ * @param scrbuf Chargrid.
+ * @param col    Column.
+ * @param row    Row.
+ *
+ */
+void chargrid_get_cursor(chargrid_t *scrbuf, sysarg_t *col,
+    sysarg_t *row)
+{
+	assert(col);
+	assert(row);
+
+	*col = scrbuf->col;
+	*row = scrbuf->row;
+}
+
+bool chargrid_get_cursor_visibility(chargrid_t *scrbuf)
+{
+	return scrbuf->cursor_visible;
+}
+
+/** Clear one buffer row.
+ *
+ * @param scrbuf Chargrid.
+ * @param row    Row to clear.
+ *
+ */
+void chargrid_clear_row(chargrid_t *scrbuf, sysarg_t row)
+{
+	for (sysarg_t col = 0; col < scrbuf->cols; col++) {
+		charfield_t *field =
+		    chargrid_charfield_at(scrbuf, col, row);
+
+		field->ch = 0;
+		field->attrs = scrbuf->attrs;
+		field->flags |= CHAR_FLAG_DIRTY;
+	}
+}
+
+/** Set chargrid style.
+ *
+ * @param scrbuf Chargrid.
+ * @param style  Style.
+ *
+ */
+void chargrid_set_style(chargrid_t *scrbuf, console_style_t style)
+{
+	scrbuf->attrs.type = CHAR_ATTR_STYLE;
+	scrbuf->attrs.val.style = style;
+}
+
+/** Set chargrid color.
+ *
+ * @param scrbuf  Chargrid.
+ * @param bgcolor Background color.
+ * @param fgcolor Foreground color.
+ * @param attr    Color attribute.
+ *
+ */
+void chargrid_set_color(chargrid_t *scrbuf, console_color_t bgcolor,
+    console_color_t fgcolor, console_color_attr_t attr)
+{
+	scrbuf->attrs.type = CHAR_ATTR_INDEX;
+	scrbuf->attrs.val.index.bgcolor = bgcolor;
+	scrbuf->attrs.val.index.fgcolor = fgcolor;
+	scrbuf->attrs.val.index.attr = attr;
+}
+
+/** Set chargrid RGB color.
+ *
+ * @param scrbuf  Chargrid.
+ * @param bgcolor Background color.
+ * @param fgcolor Foreground color.
+ *
+ */
+void chargrid_set_rgb_color(chargrid_t *scrbuf, pixel_t bgcolor,
+    pixel_t fgcolor)
+{
+	scrbuf->attrs.type = CHAR_ATTR_RGB;
+	scrbuf->attrs.val.rgb.bgcolor = bgcolor;
+	scrbuf->attrs.val.rgb.fgcolor = fgcolor;
+}
+
+/** @}
+ */
Index: uspace/lib/output/src/output.c
===================================================================
--- uspace/lib/output/src/output.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
+++ uspace/lib/output/src/output.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * 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 liboutput
+ * @{
+ */
+/** @file
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <as.h>
+#include <ipc/output.h>
+#include <io/concaps.h>
+#include <io/output.h>
+
+errno_t output_yield(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, OUTPUT_YIELD);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t output_claim(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, OUTPUT_CLAIM);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t output_get_dimensions(async_sess_t *sess, sysarg_t *maxx, sysarg_t *maxy)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_2(exch, OUTPUT_GET_DIMENSIONS, maxx, maxy);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t output_get_caps(async_sess_t *sess, console_caps_t *ccaps)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	sysarg_t rv;
+	errno_t ret = async_req_0_1(exch, OUTPUT_GET_CAPS, &rv);
+
+	async_exchange_end(exch);
+
+	if (ret == EOK)
+		*ccaps = (console_caps_t) rv;
+
+	return ret;
+}
+
+frontbuf_handle_t output_frontbuf_create(async_sess_t *sess,
+    chargrid_t *frontbuf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, OUTPUT_FRONTBUF_CREATE, &answer);
+	errno_t rc = async_share_out_start(exch, frontbuf, AS_AREA_READ |
+	    AS_AREA_WRITE | AS_AREA_CACHEABLE);
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if ((rc != EOK) || (ret != EOK))
+		return 0;
+
+	return (frontbuf_handle_t) ipc_get_arg1(&answer);
+}
+
+errno_t output_set_style(async_sess_t *sess, console_style_t style)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_1_0(exch, OUTPUT_SET_STYLE, style);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t output_cursor_update(async_sess_t *sess, frontbuf_handle_t frontbuf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_1_0(exch, OUTPUT_CURSOR_UPDATE, frontbuf);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t output_update(async_sess_t *sess, frontbuf_handle_t frontbuf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_1_0(exch, OUTPUT_UPDATE, frontbuf);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t output_damage(async_sess_t *sess, frontbuf_handle_t frontbuf, sysarg_t col,
+    sysarg_t row, sysarg_t cols, sysarg_t rows)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_5_0(exch, OUTPUT_DAMAGE, frontbuf, col, row,
+	    cols, rows);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+/** @}
+ */
Index: uspace/lib/posix/meson.build
===================================================================
--- uspace/lib/posix/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/posix/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -66,4 +66,3 @@
 uspace_lib_devel_install_script_text += 'mkdir -p "${DESTDIR}include/libposix"'
 uspace_lib_devel_install_script_text += 'cp -R -L -T "@0@" "${DESTDIR}include/libposix"'.format(_sdir)
-
-# TODO: exports
+uspace_lib_devel_install_script_text += 'ln -s -r "${DESTDIR}include/libc" "${DESTDIR}/include/common"'
Index: uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h
===================================================================
--- uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -38,6 +38,8 @@
 
 #include <errno.h>
+#include <sif.h>
 #include <types/tbarcfg/tbarcfg.h>
 
+extern errno_t tbarcfg_create(const char *, tbarcfg_t **);
 extern errno_t tbarcfg_open(const char *, tbarcfg_t **);
 extern void tbarcfg_close(tbarcfg_t *);
@@ -49,4 +51,6 @@
 extern errno_t smenu_entry_set_cmd(smenu_entry_t *, const char *);
 extern errno_t smenu_entry_save(smenu_entry_t *);
+extern errno_t smenu_entry_create(tbarcfg_t *, const char *, const char *);
+extern errno_t smenu_entry_destroy(smenu_entry_t *);
 
 #endif
Index: uspace/lib/tbarcfg/private/tbarcfg.h
===================================================================
--- uspace/lib/tbarcfg/private/tbarcfg.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/tbarcfg/private/tbarcfg.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -48,4 +48,6 @@
 	/** List of start menu entries (smenu_entry_t) */
 	list_t entries;
+	/** Entries SIF node */
+	sif_node_t *nentries;
 };
 
@@ -64,6 +66,7 @@
 };
 
-extern errno_t smenu_entry_create(tbarcfg_t *, sif_node_t *, const char *,
+extern errno_t smenu_entry_new(tbarcfg_t *, sif_node_t *, const char *,
     const char *);
+extern void smenu_entry_delete(smenu_entry_t *);
 
 #endif
Index: uspace/lib/tbarcfg/src/tbarcfg.c
===================================================================
--- uspace/lib/tbarcfg/src/tbarcfg.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/tbarcfg/src/tbarcfg.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -41,4 +41,58 @@
 #include "../private/tbarcfg.h"
 
+/** Create taskbar configuration.
+ *
+ * @param repopath Pathname of the new menu repository
+ * @param rtbcfg Place to store pointer to taskbar configuration
+ * @return EOK on success or an error code
+ */
+errno_t tbarcfg_create(const char *repopath, tbarcfg_t **rtbcfg)
+{
+	tbarcfg_t *tbcfg;
+	sif_sess_t *repo = NULL;
+	sif_node_t *rnode;
+	errno_t rc;
+	sif_trans_t *trans = NULL;
+
+	tbcfg = calloc(1, sizeof(tbarcfg_t));
+	if (tbcfg == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	list_initialize(&tbcfg->entries);
+
+	rc = sif_create(repopath, &repo);
+	if (rc != EOK)
+		goto error;
+
+	tbcfg->repo = repo;
+
+	rnode = sif_get_root(repo);
+
+	rc = sif_trans_begin(repo, &trans);
+	if (rc != EOK)
+		goto error;
+
+	rc = sif_node_append_child(trans, rnode, "entries", &tbcfg->nentries);
+	if (rc != EOK)
+		goto error;
+
+	rc = sif_trans_end(trans);
+	if (rc != EOK)
+		goto error;
+
+	*rtbcfg = tbcfg;
+	return EOK;
+error:
+	if (trans != NULL)
+		sif_trans_abort(trans);
+	if (repo != NULL)
+		sif_close(repo);
+	if (tbcfg != NULL)
+		free(tbcfg);
+	return rc;
+}
+
 /** Open taskbar configuration.
  *
@@ -52,5 +106,4 @@
 	sif_sess_t *repo = NULL;
 	sif_node_t *rnode;
-	sif_node_t *nentries;
 	sif_node_t *nentry;
 	const char *ntype;
@@ -74,6 +127,6 @@
 
 	rnode = sif_get_root(repo);
-	nentries = sif_node_first_child(rnode);
-	ntype = sif_node_get_type(nentries);
+	tbcfg->nentries = sif_node_first_child(rnode);
+	ntype = sif_node_get_type(tbcfg->nentries);
 	if (str_cmp(ntype, "entries") != 0) {
 		rc = EIO;
@@ -81,5 +134,5 @@
 	}
 
-	nentry = sif_node_first_child(nentries);
+	nentry = sif_node_first_child(tbcfg->nentries);
 	while (nentry != NULL) {
 		ntype = sif_node_get_type(nentry);
@@ -101,5 +154,5 @@
 		}
 
-		rc = smenu_entry_create(tbcfg, nentry, caption, cmd);
+		rc = smenu_entry_new(tbcfg, nentry, caption, cmd);
 		if (rc != EOK)
 			goto error;
@@ -124,5 +177,14 @@
 void tbarcfg_close(tbarcfg_t *tbcfg)
 {
+	smenu_entry_t *entry;
+
+	entry = tbarcfg_smenu_first(tbcfg);
+	while (entry != NULL) {
+		smenu_entry_delete(entry);
+		entry = tbarcfg_smenu_first(tbcfg);
+	}
+
 	(void)sif_close(tbcfg->repo);
+	free(tbcfg);
 }
 
@@ -229,5 +291,5 @@
 errno_t smenu_entry_save(smenu_entry_t *entry)
 {
-	sif_trans_t *trans;
+	sif_trans_t *trans = NULL;
 	errno_t rc;
 
@@ -255,5 +317,5 @@
 }
 
-/** Create a start menu entry and append it to the start menu (internal).
+/** Allocate a start menu entry and append it to the start menu (internal).
  *
  * This only creates the entry in memory, but does not update the repository.
@@ -264,5 +326,5 @@
  * @param cmd Command to run
  */
-errno_t smenu_entry_create(tbarcfg_t *smenu, sif_node_t *nentry,
+errno_t smenu_entry_new(tbarcfg_t *smenu, sif_node_t *nentry,
     const char *caption, const char *cmd)
 {
@@ -305,4 +367,84 @@
 }
 
+/** Delete start menu entry.
+ *
+ * This only deletes the entry from, but does not update the
+ * repository.
+ *
+ * @param entry Start menu entry
+ */
+void smenu_entry_delete(smenu_entry_t *entry)
+{
+	list_remove(&entry->lentries);
+	free(entry->caption);
+	free(entry->cmd);
+	free(entry);
+}
+
+/** Create new start menu entry.
+ *
+ * @param smenu Start menu
+ * @param nentry Backing SIF node
+ * @param caption Caption
+ * @param cmd Command to run
+ */
+errno_t smenu_entry_create(tbarcfg_t *smenu, const char *caption,
+    const char *cmd)
+{
+	sif_node_t *nentry;
+	errno_t rc;
+	sif_trans_t *trans = NULL;
+
+	rc = sif_trans_begin(smenu->repo, &trans);
+	if (rc != EOK)
+		goto error;
+
+	rc = sif_node_append_child(trans, smenu->nentries, "entry",
+	    &nentry);
+	if (rc != EOK)
+		goto error;
+
+	rc = smenu_entry_new(smenu, nentry, caption, cmd);
+	if (rc != EOK)
+		goto error;
+
+	rc = sif_trans_end(trans);
+	if (rc != EOK)
+		goto error;
+
+	return EOK;
+error:
+	if (trans != NULL)
+		sif_trans_abort(trans);
+	return rc;
+}
+
+/** Destroy start menu entry..
+ *
+ * @param entry Start menu entry
+ * @return EOK on success or an error code
+ */
+errno_t smenu_entry_destroy(smenu_entry_t *entry)
+{
+	errno_t rc;
+	sif_trans_t *trans = NULL;
+
+	rc = sif_trans_begin(entry->smenu->repo, &trans);
+	if (rc != EOK)
+		goto error;
+
+	sif_node_destroy(trans, entry->nentry);
+
+	rc = sif_trans_end(trans);
+	if (rc != EOK)
+		goto error;
+
+	smenu_entry_delete(entry);
+error:
+	if (trans != NULL)
+		sif_trans_abort(trans);
+	return rc;
+}
+
 /** @}
  */
Index: uspace/lib/tbarcfg/test/tbarcfg.c
===================================================================
--- uspace/lib/tbarcfg/test/tbarcfg.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/tbarcfg/test/tbarcfg.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -36,25 +36,27 @@
 PCUT_TEST_SUITE(tbarcfg);
 
-/** Opening and closing taskbar configuration */
-PCUT_TEST(open_close)
-{
-	errno_t rc;
-	tbarcfg_t *tbcfg;
-	FILE *f;
-	int rv;
-
-	f = fopen("/tmp/test", "wt");
-	PCUT_ASSERT_NOT_NULL(f);
-
-	rv = fputs("[sif](){[entries](){}}", f);
-	PCUT_ASSERT_TRUE(rv >= 0);
-
-	rv = fclose(f);
-	PCUT_ASSERT_INT_EQUALS(0, rv);
-
-	rc = tbarcfg_open("/tmp/test", &tbcfg);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	tbarcfg_close(tbcfg);
+/** Creating, opening and closing taskbar configuration */
+PCUT_TEST(create_open_close)
+{
+	errno_t rc;
+	tbarcfg_t *tbcfg;
+	char fname[L_tmpnam], *p;
+
+	p = tmpnam(fname);
+	PCUT_ASSERT_NOT_NULL(p);
+
+	/* Create new repository */
+	rc = tbarcfg_create(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	tbarcfg_close(tbcfg);
+
+	/* Re-open the repository */
+
+	rc = tbarcfg_open(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	tbarcfg_close(tbcfg);
+	remove(fname);
 }
 
@@ -64,21 +66,17 @@
 	errno_t rc;
 	tbarcfg_t *tbcfg;
-	smenu_entry_t *e;
-	FILE *f;
-	int rv;
-
-	f = fopen("/tmp/test", "wt");
-	PCUT_ASSERT_NOT_NULL(f);
-
-	rv = fputs("[sif](){[entries](){"
-	    "[entry]([caption]=[A][cmd]=[a]){}"
-	    "[entry]([caption]=[B][cmd]=[b]){}"
-	    "}}", f);
-	PCUT_ASSERT_TRUE(rv >= 0);
-
-	rv = fclose(f);
-	PCUT_ASSERT_INT_EQUALS(0, rv);
-
-	rc = tbarcfg_open("/tmp/test", &tbcfg);
+	char fname[L_tmpnam], *p;
+	smenu_entry_t *e;
+
+	p = tmpnam(fname);
+	PCUT_ASSERT_NOT_NULL(p);
+
+	rc = tbarcfg_create(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = smenu_entry_create(tbcfg, "A", "a");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = smenu_entry_create(tbcfg, "B", "b");
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -91,4 +89,5 @@
 
 	tbarcfg_close(tbcfg);
+	remove(fname);
 }
 
@@ -98,22 +97,16 @@
 	errno_t rc;
 	tbarcfg_t *tbcfg;
+	char fname[L_tmpnam], *p;
 	smenu_entry_t *e;
 	const char *caption;
 	const char *cmd;
-	FILE *f;
-	int rv;
-
-	f = fopen("/tmp/test", "wt");
-	PCUT_ASSERT_NOT_NULL(f);
-
-	rv = fputs("[sif](){[entries](){"
-	    "[entry]([caption]=[A][cmd]=[a]){}"
-	    "}}", f);
-	PCUT_ASSERT_TRUE(rv >= 0);
-
-	rv = fclose(f);
-	PCUT_ASSERT_INT_EQUALS(0, rv);
-
-	rc = tbarcfg_open("/tmp/test", &tbcfg);
+
+	p = tmpnam(fname);
+	PCUT_ASSERT_NOT_NULL(p);
+
+	rc = tbarcfg_create(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = smenu_entry_create(tbcfg, "A", "a");
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -127,4 +120,98 @@
 
 	tbarcfg_close(tbcfg);
+	remove(fname);
+}
+
+/** Setting menu entry properties */
+PCUT_TEST(set_caption_cmd)
+{
+	errno_t rc;
+	tbarcfg_t *tbcfg;
+	char fname[L_tmpnam], *p;
+	smenu_entry_t *e;
+	const char *caption;
+	const char *cmd;
+
+	p = tmpnam(fname);
+	PCUT_ASSERT_NOT_NULL(p);
+
+	rc = tbarcfg_create(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = smenu_entry_create(tbcfg, "A", "a");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	e = tbarcfg_smenu_first(tbcfg);
+	PCUT_ASSERT_NOT_NULL(e);
+
+	caption = smenu_entry_get_caption(e);
+	PCUT_ASSERT_STR_EQUALS("A", caption);
+	cmd = smenu_entry_get_cmd(e);
+	PCUT_ASSERT_STR_EQUALS("a", cmd);
+
+	/* Set properties */
+	rc = smenu_entry_set_caption(e, "B");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	rc = smenu_entry_set_cmd(e, "b");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = smenu_entry_save(e);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/* Check that properties have been set */
+	caption = smenu_entry_get_caption(e);
+	PCUT_ASSERT_STR_EQUALS("B", caption);
+	cmd = smenu_entry_get_cmd(e);
+	PCUT_ASSERT_STR_EQUALS("b", cmd);
+
+	tbarcfg_close(tbcfg);
+
+	/* Re-open repository */
+
+	rc = tbarcfg_open(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	e = tbarcfg_smenu_first(tbcfg);
+	PCUT_ASSERT_NOT_NULL(e);
+
+	/* Check that new values of properties have persisted */
+	caption = smenu_entry_get_caption(e);
+	PCUT_ASSERT_STR_EQUALS("B", caption);
+	cmd = smenu_entry_get_cmd(e);
+	PCUT_ASSERT_STR_EQUALS("b", cmd);
+
+	tbarcfg_close(tbcfg);
+	remove(fname);
+}
+
+/** Create start menu entry */
+PCUT_TEST(entry_create)
+{
+	errno_t rc;
+	tbarcfg_t *tbcfg;
+	char fname[L_tmpnam], *p;
+	smenu_entry_t *e;
+	const char *caption;
+	const char *cmd;
+
+	p = tmpnam(fname);
+	PCUT_ASSERT_NOT_NULL(p);
+
+	rc = tbarcfg_create(fname, &tbcfg);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = smenu_entry_create(tbcfg, "A", "a");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	e = tbarcfg_smenu_first(tbcfg);
+	PCUT_ASSERT_NOT_NULL(e);
+
+	caption = smenu_entry_get_caption(e);
+	PCUT_ASSERT_STR_EQUALS("A", caption);
+	cmd = smenu_entry_get_cmd(e);
+	PCUT_ASSERT_STR_EQUALS("a", cmd);
+
+	tbarcfg_close(tbcfg);
+	remove(fname);
 }
 
Index: uspace/lib/ui/include/ui/list.h
===================================================================
--- uspace/lib/ui/include/ui/list.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/include/ui/list.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -60,4 +60,5 @@
 extern void *ui_list_entry_get_arg(ui_list_entry_t *);
 extern ui_list_t *ui_list_entry_get_list(ui_list_entry_t *);
+extern errno_t ui_list_entry_set_caption(ui_list_entry_t *, const char *);
 extern size_t ui_list_entries_cnt(ui_list_t *);
 extern errno_t ui_list_sort(ui_list_t *);
Index: uspace/lib/ui/include/ui/scrollbar.h
===================================================================
--- uspace/lib/ui/include/ui/scrollbar.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/include/ui/scrollbar.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -54,5 +54,5 @@
 extern void ui_scrollbar_set_rect(ui_scrollbar_t *, gfx_rect_t *);
 extern errno_t ui_scrollbar_paint(ui_scrollbar_t *);
-extern gfx_coord_t ui_scrollbar_through_length(ui_scrollbar_t *);
+extern gfx_coord_t ui_scrollbar_trough_length(ui_scrollbar_t *);
 extern gfx_coord_t ui_scrollbar_move_length(ui_scrollbar_t *);
 extern gfx_coord_t ui_scrollbar_get_pos(ui_scrollbar_t *);
@@ -60,9 +60,9 @@
 extern void ui_scrollbar_set_pos(ui_scrollbar_t *, gfx_coord_t);
 extern void ui_scrollbar_thumb_press(ui_scrollbar_t *, gfx_coord2_t *);
-extern void ui_scrollbar_up_through_press(ui_scrollbar_t *);
-extern void ui_scrollbar_down_through_press(ui_scrollbar_t *);
+extern void ui_scrollbar_upper_trough_press(ui_scrollbar_t *);
+extern void ui_scrollbar_lower_trough_press(ui_scrollbar_t *);
 extern void ui_scrollbar_release(ui_scrollbar_t *, gfx_coord2_t *);
 extern void ui_scrollbar_update(ui_scrollbar_t *, gfx_coord2_t *);
-extern void ui_scrollbar_throughs_update(ui_scrollbar_t *, gfx_coord2_t *);
+extern void ui_scrollbar_troughs_update(ui_scrollbar_t *, gfx_coord2_t *);
 extern void ui_scrollbar_up(ui_scrollbar_t *);
 extern void ui_scrollbar_down(ui_scrollbar_t *);
Index: uspace/lib/ui/meson.build
===================================================================
--- uspace/lib/ui/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'gfx', 'gfxfont', 'memgfx', 'display', 'congfx' ]
+deps = [ 'gfx', 'gfxfont', 'memgfx', 'display', 'congfx', 'clipboard' ]
 src = files(
 	'src/accel.c',
Index: uspace/lib/ui/private/resource.h
===================================================================
--- uspace/lib/ui/private/resource.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/private/resource.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -118,8 +118,8 @@
 	gfx_color_t *entry_sel_text_bg_color;
 
-	/** Scrollbar through color */
-	gfx_color_t *sbar_through_color;
-	/** Scrollbar active through color */
-	gfx_color_t *sbar_act_through_color;
+	/** Scrollbar trough color */
+	gfx_color_t *sbar_trough_color;
+	/** Scrollbar active trough color */
+	gfx_color_t *sbar_act_trough_color;
 
 	/** Expose callback or @c NULL */
Index: uspace/lib/ui/private/scrollbar.h
===================================================================
--- uspace/lib/ui/private/scrollbar.h	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/private/scrollbar.h	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -69,12 +69,12 @@
 	/** Thumb is currently held down */
 	bool thumb_held;
-	/** Up through is currently held down */
-	bool up_through_held;
-	/** Pointer is inside up through */
-	bool up_through_inside;
-	/** Down through is currently held down */
-	bool down_through_held;
-	/** Pointer is inside down through */
-	bool down_through_inside;
+	/** Upper trough is currently held down */
+	bool upper_trough_held;
+	/** Pointer is inside upper trough */
+	bool upper_trough_inside;
+	/** Lower trough is currently held down */
+	bool lower_trough_held;
+	/** Pointer is inside lower trough */
+	bool lower_trough_inside;
 	/** Position where thumb was pressed */
 	gfx_coord2_t press_pos;
@@ -83,5 +83,5 @@
 	/** Thumb position */
 	gfx_coord_t pos;
-	/** Last cursor position (when through is held) */
+	/** Last cursor position (when trough is held) */
 	gfx_coord2_t last_curs_pos;
 };
@@ -94,12 +94,12 @@
 	/** Up button rectangle */
 	gfx_rect_t up_btn_rect;
-	/** Through rectangle */
-	gfx_rect_t through_rect;
-	/** Up through rectangle */
-	gfx_rect_t up_through_rect;
+	/** Trough rectangle */
+	gfx_rect_t trough_rect;
+	/** Upper trough rectangle */
+	gfx_rect_t upper_trough_rect;
 	/** Thumb rectangle */
 	gfx_rect_t thumb_rect;
-	/** Down through rectangle */
-	gfx_rect_t down_through_rect;
+	/** Lower trough rectangle */
+	gfx_rect_t lower_trough_rect;
 	/** Down button rectangle */
 	gfx_rect_t down_btn_rect;
Index: uspace/lib/ui/src/clickmatic.c
===================================================================
--- uspace/lib/ui/src/clickmatic.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/src/clickmatic.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -35,5 +35,5 @@
  * Clickmatic is used to periodically generate events in particular cases
  * when a mouse button is held down, such as when holding the button or
- * through of a scrollbar.
+ * trough of a scrollbar.
  */
 
Index: uspace/lib/ui/src/list.c
===================================================================
--- uspace/lib/ui/src/list.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/src/list.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -800,4 +800,26 @@
 }
 
+/** Change list entry caption.
+ *
+ * @param entry UI list entry
+ * @param caption New caption
+ *
+ * @return EOK on success, ENOMEM if out of memory
+ */
+errno_t ui_list_entry_set_caption(ui_list_entry_t *entry, const char *caption)
+{
+	char *dcaption;
+
+	dcaption = str_dup(caption);
+	if (dcaption == NULL)
+		return ENOMEM;
+
+	free(entry->caption);
+	entry->caption = dcaption;
+
+	(void)ui_list_entry_paint(entry, ui_list_entry_get_idx(entry));
+	return EOK;
+}
+
 /** Clear UI list entry list.
  *
Index: uspace/lib/ui/src/resource.c
===================================================================
--- uspace/lib/ui/src/resource.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/src/resource.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -86,6 +86,6 @@
 	gfx_color_t *entry_sel_text_fg_color = NULL;
 	gfx_color_t *entry_sel_text_bg_color = NULL;
-	gfx_color_t *sbar_through_color = NULL;
-	gfx_color_t *sbar_act_through_color = NULL;
+	gfx_color_t *sbar_trough_color = NULL;
+	gfx_color_t *sbar_act_trough_color = NULL;
 	errno_t rc;
 
@@ -221,10 +221,10 @@
 
 	rc = gfx_color_new_rgb_i16(0xe4e4, 0xe4e4, 0xe4e4,
-	    &sbar_through_color);
+	    &sbar_trough_color);
 	if (rc != EOK)
 		goto error;
 
 	rc = gfx_color_new_rgb_i16(0x5858, 0x5858, 0x5858,
-	    &sbar_act_through_color);
+	    &sbar_act_trough_color);
 	if (rc != EOK)
 		goto error;
@@ -265,6 +265,6 @@
 	resource->entry_sel_text_bg_color = entry_sel_text_bg_color;
 
-	resource->sbar_through_color = sbar_through_color;
-	resource->sbar_act_through_color = sbar_act_through_color;
+	resource->sbar_trough_color = sbar_trough_color;
+	resource->sbar_act_trough_color = sbar_act_trough_color;
 
 	*rresource = resource;
@@ -327,8 +327,8 @@
 		gfx_color_delete(entry_act_bg_color);
 
-	if (sbar_through_color != NULL)
-		gfx_color_delete(sbar_through_color);
-	if (sbar_act_through_color != NULL)
-		gfx_color_delete(sbar_act_through_color);
+	if (sbar_trough_color != NULL)
+		gfx_color_delete(sbar_trough_color);
+	if (sbar_act_trough_color != NULL)
+		gfx_color_delete(sbar_act_trough_color);
 
 	if (tface != NULL)
@@ -376,6 +376,6 @@
 	gfx_color_t *entry_sel_text_bg_color = NULL;
 	gfx_color_t *entry_act_bg_color = NULL;
-	gfx_color_t *sbar_through_color = NULL;
-	gfx_color_t *sbar_act_through_color = NULL;
+	gfx_color_t *sbar_trough_color = NULL;
+	gfx_color_t *sbar_act_trough_color = NULL;
 	errno_t rc;
 
@@ -497,9 +497,9 @@
 		goto error;
 
-	rc = gfx_color_new_ega(0x07, &sbar_through_color);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_color_new_ega(0x07, &sbar_act_through_color);
+	rc = gfx_color_new_ega(0x07, &sbar_trough_color);
+	if (rc != EOK)
+		goto error;
+
+	rc = gfx_color_new_ega(0x07, &sbar_act_trough_color);
 	if (rc != EOK)
 		goto error;
@@ -540,6 +540,6 @@
 	resource->entry_sel_text_bg_color = entry_sel_text_bg_color;
 
-	resource->sbar_through_color = sbar_through_color;
-	resource->sbar_act_through_color = sbar_act_through_color;
+	resource->sbar_trough_color = sbar_trough_color;
+	resource->sbar_act_trough_color = sbar_act_trough_color;
 
 	*rresource = resource;
@@ -601,8 +601,8 @@
 	if (entry_sel_text_bg_color != NULL)
 		gfx_color_delete(entry_sel_text_bg_color);
-	if (sbar_through_color != NULL)
-		gfx_color_delete(sbar_through_color);
-	if (sbar_act_through_color != NULL)
-		gfx_color_delete(sbar_act_through_color);
+	if (sbar_trough_color != NULL)
+		gfx_color_delete(sbar_trough_color);
+	if (sbar_act_trough_color != NULL)
+		gfx_color_delete(sbar_act_trough_color);
 
 	if (tface != NULL)
@@ -665,6 +665,6 @@
 	gfx_color_delete(resource->entry_sel_text_bg_color);
 
-	gfx_color_delete(resource->sbar_through_color);
-	gfx_color_delete(resource->sbar_act_through_color);
+	gfx_color_delete(resource->sbar_trough_color);
+	gfx_color_delete(resource->sbar_act_trough_color);
 
 	gfx_font_close(resource->font);
Index: uspace/lib/ui/src/scrollbar.c
===================================================================
--- uspace/lib/ui/src/scrollbar.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/src/scrollbar.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -35,13 +35,13 @@
  * Anatomy of a horizontal scrollbar:
  *
- *       Up                Down
- *      through           through
- * +---+------+--------+---------+---+
- * | < |      |   |||  |         | > |
- * +---+------+--------+---------+---+
- *  Up           Thumb           Down
- * button                       button
- *
- *     +-------- Through --------+
+ *        Upper             Lower
+ *       trough            trough
+ *  +---+------+--------+---------+---+
+ *  | < |      |   |||  |         | > |
+ *  +---+------+--------+---------+---+
+ *   Up           Thumb           Down
+ * button                        button
+ *
+ *     +-------- Trough --------+
  *
  * Scrollbar uses the same terminology whether it is running in horizontal
@@ -51,8 +51,8 @@
  * The thumb can be dragged to a specific position, resulting in a move
  * event. The up/down buttons generate up/down events. Pressing a mouse
- * button on the up/down through generates page up / page down events.
- *
- * Pressing and holding down mouse button on up / down button or up / down
- * through will auto-scroll (using clickmatic).
+ * button on the upper/lower trough generates page up / page down events.
+ *
+ * Pressing and holding down mouse button on up / down button or upper /
+ * lower trough will auto-scroll (using clickmatic).
  */
 
@@ -360,5 +360,5 @@
 }
 
-/** Determine scrollbar through length.
+/** Determine scrollbar trough length.
  *
  * Return the size of the space within which the thumb can move
@@ -366,7 +366,7 @@
  *
  * @param scrollbar Scrollbar
- * @return Scrollbar through length in pixels
- */
-gfx_coord_t ui_scrollbar_through_length(ui_scrollbar_t *scrollbar)
+ * @return Scrollbar trough length in pixels
+ */
+gfx_coord_t ui_scrollbar_trough_length(ui_scrollbar_t *scrollbar)
 {
 	ui_resource_t *resource;
@@ -396,5 +396,5 @@
 gfx_coord_t ui_scrollbar_move_length(ui_scrollbar_t *scrollbar)
 {
-	return ui_scrollbar_through_length(scrollbar) -
+	return ui_scrollbar_trough_length(scrollbar) -
 	    scrollbar->thumb_len;
 }
@@ -417,5 +417,5 @@
 	    ui_scrollbar_min_thumb_len;
 
-	max_len = ui_scrollbar_through_length(scrollbar);
+	max_len = ui_scrollbar_trough_length(scrollbar);
 	if (len < min_len)
 		len = min_len;
@@ -459,5 +459,5 @@
 		scrollbar->pos = pos;
 		(void) ui_scrollbar_paint(scrollbar);
-		ui_scrollbar_throughs_update(scrollbar,
+		ui_scrollbar_troughs_update(scrollbar,
 		    &scrollbar->last_curs_pos);
 	}
@@ -487,26 +487,26 @@
 		goto error;
 
-	/* Paint scrollbar up through */
+	/* Paint scrollbar upper trough */
 	rc = gfx_set_color(resource->gc,
-	    scrollbar->up_through_held && scrollbar->up_through_inside ?
-	    resource->sbar_act_through_color :
-	    resource->sbar_through_color);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_fill_rect(resource->gc, &geom.up_through_rect);
-	if (rc != EOK)
-		goto error;
-
-	/* Paint scrollbar down through */
+	    scrollbar->upper_trough_held && scrollbar->upper_trough_inside ?
+	    resource->sbar_act_trough_color :
+	    resource->sbar_trough_color);
+	if (rc != EOK)
+		goto error;
+
+	rc = gfx_fill_rect(resource->gc, &geom.upper_trough_rect);
+	if (rc != EOK)
+		goto error;
+
+	/* Paint scrollbar lower trough */
 
 	rc = gfx_set_color(resource->gc,
-	    scrollbar->down_through_held && scrollbar->down_through_inside ?
-	    resource->sbar_act_through_color :
-	    resource->sbar_through_color);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_fill_rect(resource->gc, &geom.down_through_rect);
+	    scrollbar->lower_trough_held && scrollbar->lower_trough_inside ?
+	    resource->sbar_act_trough_color :
+	    resource->sbar_trough_color);
+	if (rc != EOK)
+		goto error;
+
+	rc = gfx_fill_rect(resource->gc, &geom.lower_trough_rect);
 	if (rc != EOK)
 		goto error;
@@ -561,8 +561,8 @@
 	ui_scrollbar_get_geom(scrollbar, &geom);
 
-	/* Paint scrollbar through */
-
-	rc = ui_paint_text_rect(resource, &geom.through_rect,
-	    resource->sbar_through_color, "\u2592");
+	/* Paint scrollbar trough */
+
+	rc = ui_paint_text_rect(resource, &geom.trough_rect,
+	    resource->sbar_trough_color, "\u2592");
 	if (rc != EOK)
 		goto error;
@@ -571,5 +571,5 @@
 
 	rc = ui_paint_text_rect(resource, &geom.thumb_rect,
-	    resource->sbar_through_color, "\u25a0");
+	    resource->sbar_trough_color, "\u25a0");
 	if (rc != EOK)
 		goto error;
@@ -647,9 +647,9 @@
 		geom->up_btn_rect.p1.y = orect.p1.y;
 
-		/* Through */
-		geom->through_rect.p0.x = geom->up_btn_rect.p1.x;
-		geom->through_rect.p0.y = irect.p0.y;
-		geom->through_rect.p1.x = orect.p1.x - btn_len;
-		geom->through_rect.p1.y = irect.p1.y;
+		/* Trough */
+		geom->trough_rect.p0.x = geom->up_btn_rect.p1.x;
+		geom->trough_rect.p0.y = irect.p0.y;
+		geom->trough_rect.p1.x = orect.p1.x - btn_len;
+		geom->trough_rect.p1.y = irect.p1.y;
 
 		/* Thumb */
@@ -661,16 +661,16 @@
 		geom->thumb_rect.p1.y = orect.p1.y;
 
-		/* Up through */
-		geom->up_through_rect.p0 = geom->through_rect.p0;
-		geom->up_through_rect.p1.x = geom->thumb_rect.p0.x;
-		geom->up_through_rect.p1.y = geom->through_rect.p1.y;
-
-		/* Down through */
-		geom->down_through_rect.p0.x = geom->thumb_rect.p1.x;
-		geom->down_through_rect.p0.y = geom->through_rect.p0.y;
-		geom->down_through_rect.p1 = geom->through_rect.p1;
+		/* Upper trough */
+		geom->upper_trough_rect.p0 = geom->trough_rect.p0;
+		geom->upper_trough_rect.p1.x = geom->thumb_rect.p0.x;
+		geom->upper_trough_rect.p1.y = geom->trough_rect.p1.y;
+
+		/* Lower trough */
+		geom->lower_trough_rect.p0.x = geom->thumb_rect.p1.x;
+		geom->lower_trough_rect.p0.y = geom->trough_rect.p0.y;
+		geom->lower_trough_rect.p1 = geom->trough_rect.p1;
 
 		/* Down button */
-		geom->down_btn_rect.p0.x = geom->through_rect.p1.x;
+		geom->down_btn_rect.p0.x = geom->trough_rect.p1.x;
 		geom->down_btn_rect.p0.y = orect.p0.y;
 		geom->down_btn_rect.p1.x = orect.p1.x;
@@ -683,9 +683,9 @@
 		geom->up_btn_rect.p1.y = orect.p0.y + btn_len;
 
-		/* Through */
-		geom->through_rect.p0.x = irect.p0.x;
-		geom->through_rect.p0.y = geom->up_btn_rect.p1.y;
-		geom->through_rect.p1.x = irect.p1.x;
-		geom->through_rect.p1.y = orect.p1.y - btn_len;
+		/* Trough */
+		geom->trough_rect.p0.x = irect.p0.x;
+		geom->trough_rect.p0.y = geom->up_btn_rect.p1.y;
+		geom->trough_rect.p1.x = irect.p1.x;
+		geom->trough_rect.p1.y = orect.p1.y - btn_len;
 
 		/* Thumb */
@@ -697,17 +697,17 @@
 		    scrollbar->thumb_len;
 
-		/* Up through */
-		geom->up_through_rect.p0 = geom->through_rect.p0;
-		geom->up_through_rect.p1.x = geom->through_rect.p1.x;
-		geom->up_through_rect.p1.y = geom->thumb_rect.p0.y;
-
-		/* Down through */
-		geom->down_through_rect.p0.x = geom->through_rect.p0.x;
-		geom->down_through_rect.p0.y = geom->thumb_rect.p1.y;
-		geom->down_through_rect.p1 = geom->through_rect.p1;
+		/* Upper trough */
+		geom->upper_trough_rect.p0 = geom->trough_rect.p0;
+		geom->upper_trough_rect.p1.x = geom->trough_rect.p1.x;
+		geom->upper_trough_rect.p1.y = geom->thumb_rect.p0.y;
+
+		/* Lower trough */
+		geom->lower_trough_rect.p0.x = geom->trough_rect.p0.x;
+		geom->lower_trough_rect.p0.y = geom->thumb_rect.p1.y;
+		geom->lower_trough_rect.p1 = geom->trough_rect.p1;
 
 		/* Down button */
 		geom->down_btn_rect.p0.x = orect.p0.x;
-		geom->down_btn_rect.p0.y = geom->through_rect.p1.y;
+		geom->down_btn_rect.p0.y = geom->trough_rect.p1.y;
 		geom->down_btn_rect.p1.x = orect.p1.x;
 		geom->down_btn_rect.p1.y = orect.p1.y;
@@ -732,14 +732,14 @@
 }
 
-/** Press down scrollbar up through.
- *
- * @param scrollbar Scrollbar
- */
-void ui_scrollbar_up_through_press(ui_scrollbar_t *scrollbar)
+/** Press down scrollbar upper trough.
+ *
+ * @param scrollbar Scrollbar
+ */
+void ui_scrollbar_upper_trough_press(ui_scrollbar_t *scrollbar)
 {
 	ui_clickmatic_t *clickmatic = ui_get_clickmatic(scrollbar->ui);
 
-	scrollbar->up_through_held = true;
-	scrollbar->up_through_inside = true;
+	scrollbar->upper_trough_held = true;
+	scrollbar->upper_trough_inside = true;
 
 	ui_clickmatic_set_cb(clickmatic, &ui_scrollbar_clickmatic_page_up_cb,
@@ -748,14 +748,14 @@
 }
 
-/** Press down scrollbar down through.
- *
- * @param scrollbar Scrollbar
- */
-void ui_scrollbar_down_through_press(ui_scrollbar_t *scrollbar)
+/** Press down scrollbar lower trough.
+ *
+ * @param scrollbar Scrollbar
+ */
+void ui_scrollbar_lower_trough_press(ui_scrollbar_t *scrollbar)
 {
 	ui_clickmatic_t *clickmatic = ui_get_clickmatic(scrollbar->ui);
 
-	scrollbar->down_through_held = true;
-	scrollbar->down_through_inside = true;
+	scrollbar->lower_trough_held = true;
+	scrollbar->lower_trough_inside = true;
 
 	ui_clickmatic_set_cb(clickmatic, &ui_scrollbar_clickmatic_page_down_cb,
@@ -778,11 +778,11 @@
 	}
 
-	if (scrollbar->up_through_held || scrollbar->down_through_held) {
+	if (scrollbar->upper_trough_held || scrollbar->lower_trough_held) {
 		clickmatic = ui_get_clickmatic(scrollbar->ui);
 		ui_clickmatic_release(clickmatic);
 		ui_clickmatic_set_cb(clickmatic, NULL, NULL);
 
-		scrollbar->up_through_held = false;
-		scrollbar->down_through_held = false;
+		scrollbar->upper_trough_held = false;
+		scrollbar->lower_trough_held = false;
 		(void) ui_scrollbar_paint(scrollbar);
 	}
@@ -791,10 +791,10 @@
 /** Update state of scrollbar throuhgs.
  *
- * Update state of scrollbar throughs after mouse cursor or thumb has moved.
+ * Update state of scrollbar troughs after mouse cursor or thumb has moved.
  *
  * @param scrollbar Scrollbar
  * @param pos Mouse cursor position
  */
-void ui_scrollbar_throughs_update(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
+void ui_scrollbar_troughs_update(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
 {
 	ui_scrollbar_geom_t geom;
@@ -804,20 +804,20 @@
 	ui_scrollbar_get_geom(scrollbar, &geom);
 
-	inside_up = gfx_pix_inside_rect(pos, &geom.up_through_rect);
-	inside_down = gfx_pix_inside_rect(pos, &geom.down_through_rect);
-
-	if (inside_up && !scrollbar->up_through_inside) {
-		scrollbar->up_through_inside = true;
+	inside_up = gfx_pix_inside_rect(pos, &geom.upper_trough_rect);
+	inside_down = gfx_pix_inside_rect(pos, &geom.lower_trough_rect);
+
+	if (inside_up && !scrollbar->upper_trough_inside) {
+		scrollbar->upper_trough_inside = true;
 		(void) ui_scrollbar_paint(scrollbar);
-	} else if (!inside_up && scrollbar->up_through_inside) {
-		scrollbar->up_through_inside = false;
+	} else if (!inside_up && scrollbar->upper_trough_inside) {
+		scrollbar->upper_trough_inside = false;
 		(void) ui_scrollbar_paint(scrollbar);
 	}
 
-	if (inside_down && !scrollbar->down_through_inside) {
-		scrollbar->down_through_inside = true;
+	if (inside_down && !scrollbar->lower_trough_inside) {
+		scrollbar->lower_trough_inside = true;
 		(void) ui_scrollbar_paint(scrollbar);
-	} else if (!inside_down && scrollbar->down_through_inside) {
-		scrollbar->down_through_inside = false;
+	} else if (!inside_down && scrollbar->lower_trough_inside) {
+		scrollbar->lower_trough_inside = false;
 		(void) ui_scrollbar_paint(scrollbar);
 	}
@@ -843,5 +843,5 @@
 	}
 
-	ui_scrollbar_throughs_update(scrollbar, pos);
+	ui_scrollbar_troughs_update(scrollbar, pos);
 }
 
@@ -866,5 +866,5 @@
 }
 
-/** Scrollbar up through was pressed.
+/** Scrollbar upper trough was pressed.
  *
  * @param scrollbar Scrollbar
@@ -876,5 +876,5 @@
 }
 
-/** Scrollbar down through was pressed.
+/** Scrollbar lower trough was pressed.
  *
  * @param scrollbar Scrollbar
@@ -927,16 +927,16 @@
 			return ui_claimed;
 		}
-		if (gfx_pix_inside_rect(&pos, &geom.up_through_rect)) {
-			ui_scrollbar_up_through_press(scrollbar);
+		if (gfx_pix_inside_rect(&pos, &geom.upper_trough_rect)) {
+			ui_scrollbar_upper_trough_press(scrollbar);
 			return ui_claimed;
 		}
-		if (gfx_pix_inside_rect(&pos, &geom.down_through_rect)) {
-			ui_scrollbar_down_through_press(scrollbar);
+		if (gfx_pix_inside_rect(&pos, &geom.lower_trough_rect)) {
+			ui_scrollbar_lower_trough_press(scrollbar);
 			return ui_claimed;
 		}
 		break;
 	case POS_RELEASE:
-		if (scrollbar->thumb_held || scrollbar->up_through_held ||
-		    scrollbar->down_through_held) {
+		if (scrollbar->thumb_held || scrollbar->upper_trough_held ||
+		    scrollbar->lower_trough_held) {
 			ui_scrollbar_release(scrollbar, &pos);
 			return ui_claimed;
@@ -1118,5 +1118,5 @@
 }
 
-/** Scrollbar clickmatic up through click event.
+/** Scrollbar clickmatic upper trough click event.
  *
  * @param clickmatic Clickmatic
@@ -1127,9 +1127,9 @@
 	ui_scrollbar_t *scrollbar = (ui_scrollbar_t *)arg;
 
-	if (scrollbar->up_through_inside)
+	if (scrollbar->upper_trough_inside)
 		ui_scrollbar_page_up(scrollbar);
 }
 
-/** Scrollbar clickmatic down through click event.
+/** Scrollbar clickmatic lower trough click event.
  *
  * @param clickmatic Clickmatic
@@ -1140,5 +1140,5 @@
 	ui_scrollbar_t *scrollbar = (ui_scrollbar_t *)arg;
 
-	if (scrollbar->down_through_inside)
+	if (scrollbar->lower_trough_inside)
 		ui_scrollbar_page_down(scrollbar);
 }
Index: uspace/lib/ui/test/list.c
===================================================================
--- uspace/lib/ui/test/list.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/test/list.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1039,4 +1039,47 @@
 }
 
+/** ui_list_entry_set_caption() sets entry captino */
+PCUT_TEST(entry_set_caption)
+{
+	ui_t *ui;
+	ui_window_t *window;
+	ui_wnd_params_t params;
+	ui_list_t *list;
+	ui_list_entry_attr_t attr;
+	ui_list_entry_t *entry;
+	errno_t rc;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Test";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ui_list_create(window, true, &list);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_list_entry_attr_init(&attr);
+
+	/* Append entry and get pointer to it */
+	attr.caption = "a";
+	attr.arg = (void *)1;
+	entry = NULL;
+	rc = ui_list_entry_append(list, &attr, &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(entry);
+
+	/* Change caption */
+	rc = ui_list_entry_set_caption(entry, "b");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_STR_EQUALS("b", entry->caption);
+
+	ui_list_destroy(list);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
 /** ui_list_entries_cnt() returns the number of entries */
 PCUT_TEST(entries_cnt)
Index: uspace/lib/ui/test/scrollbar.c
===================================================================
--- uspace/lib/ui/test/scrollbar.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/lib/ui/test/scrollbar.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -284,6 +284,6 @@
 }
 
-/** ui_scrollbar_through_length() gives correct scrollbar through length */
-PCUT_TEST(through_length)
+/** ui_scrollbar_trough_length() gives correct scrollbar trough length */
+PCUT_TEST(trough_length)
 {
 	ui_t *ui = NULL;
@@ -316,5 +316,5 @@
 	ui_scrollbar_set_rect(scrollbar, &rect);
 
-	length = ui_scrollbar_through_length(scrollbar);
+	length = ui_scrollbar_trough_length(scrollbar);
 
 	/* Total length minus buttons */
@@ -620,6 +620,6 @@
 }
 
-/** Press and release up through */
-PCUT_TEST(up_through_press_release)
+/** Press and release upper trough */
+PCUT_TEST(upper_trough_press_release)
 {
 	ui_t *ui = NULL;
@@ -654,8 +654,8 @@
 	ui_scrollbar_set_cb(scrollbar, &test_scrollbar_cb, &resp);
 
-	PCUT_ASSERT_FALSE(scrollbar->up_through_held);
-
-	ui_scrollbar_up_through_press(scrollbar);
-	PCUT_ASSERT_TRUE(scrollbar->up_through_held);
+	PCUT_ASSERT_FALSE(scrollbar->upper_trough_held);
+
+	ui_scrollbar_upper_trough_press(scrollbar);
+	PCUT_ASSERT_TRUE(scrollbar->upper_trough_held);
 	PCUT_ASSERT_TRUE(resp.page_up);
 
@@ -665,13 +665,13 @@
 
 	ui_scrollbar_release(scrollbar, &pos);
-	PCUT_ASSERT_FALSE(scrollbar->up_through_held);
-
-	ui_scrollbar_destroy(scrollbar);
-	ui_window_destroy(window);
-	ui_destroy(ui);
-}
-
-/** Press and release down through */
-PCUT_TEST(down_through_press_release)
+	PCUT_ASSERT_FALSE(scrollbar->upper_trough_held);
+
+	ui_scrollbar_destroy(scrollbar);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** Press and release lower trough */
+PCUT_TEST(lower_trough_press_release)
 {
 	ui_t *ui = NULL;
@@ -706,8 +706,8 @@
 	ui_scrollbar_set_cb(scrollbar, &test_scrollbar_cb, &resp);
 
-	PCUT_ASSERT_FALSE(scrollbar->down_through_held);
-
-	ui_scrollbar_down_through_press(scrollbar);
-	PCUT_ASSERT_TRUE(scrollbar->down_through_held);
+	PCUT_ASSERT_FALSE(scrollbar->lower_trough_held);
+
+	ui_scrollbar_lower_trough_press(scrollbar);
+	PCUT_ASSERT_TRUE(scrollbar->lower_trough_held);
 	PCUT_ASSERT_TRUE(resp.page_down);
 
@@ -717,13 +717,13 @@
 
 	ui_scrollbar_release(scrollbar, &pos);
-	PCUT_ASSERT_FALSE(scrollbar->down_through_held);
-
-	ui_scrollbar_destroy(scrollbar);
-	ui_window_destroy(window);
-	ui_destroy(ui);
-}
-
-/** Updating state of throughs when cursor or thumb moves */
-PCUT_TEST(throughs_update)
+	PCUT_ASSERT_FALSE(scrollbar->lower_trough_held);
+
+	ui_scrollbar_destroy(scrollbar);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** Updating state of troughs when cursor or thumb moves */
+PCUT_TEST(troughs_update)
 {
 	ui_t *ui = NULL;
@@ -754,11 +754,11 @@
 	ui_scrollbar_set_rect(scrollbar, &rect);
 
-	PCUT_ASSERT_FALSE(scrollbar->down_through_inside);
+	PCUT_ASSERT_FALSE(scrollbar->lower_trough_inside);
 
 	pos.x = 60;
 	pos.y = 22;
 
-	ui_scrollbar_throughs_update(scrollbar, &pos);
-	PCUT_ASSERT_TRUE(scrollbar->down_through_inside);
+	ui_scrollbar_troughs_update(scrollbar, &pos);
+	PCUT_ASSERT_TRUE(scrollbar->lower_trough_inside);
 
 	ui_scrollbar_destroy(scrollbar);
@@ -1082,6 +1082,6 @@
 }
 
-/** ui_scrollbar_pos_event() detects up through press/release */
-PCUT_TEST(pos_event_press_release_up_through)
+/** ui_scrollbar_pos_event() detects upper trough press/release */
+PCUT_TEST(pos_event_press_release_upper_trough)
 {
 	ui_t *ui = NULL;
@@ -1107,5 +1107,5 @@
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
-	PCUT_ASSERT_FALSE(scrollbar->up_through_held);
+	PCUT_ASSERT_FALSE(scrollbar->upper_trough_held);
 
 	rect.p0.x = 20;
@@ -1115,21 +1115,21 @@
 	ui_scrollbar_set_rect(scrollbar, &rect);
 
-	/* Need to move thumb so that up through can be accessed */
+	/* Need to move thumb so that upper trough can be accessed */
 	ui_scrollbar_set_pos(scrollbar, 42);
 
-	/* Press inside up through is claimed and depresses it */
+	/* Press inside upper trough is claimed and depresses it */
 	event.type = POS_PRESS;
 	event.hpos = 50;
 	event.vpos = 20;
 	claim = ui_scrollbar_pos_event(scrollbar, &event);
-	PCUT_ASSERT_TRUE(scrollbar->up_through_held);
+	PCUT_ASSERT_TRUE(scrollbar->upper_trough_held);
 	PCUT_ASSERT_EQUALS(ui_claimed, claim);
 
-	/* Release outside (or anywhere) is claimed and relases up through */
+	/* Release outside (or anywhere) is claimed and relases upper trough */
 	event.type = POS_RELEASE;
 	event.hpos = 41;
 	event.vpos = 32;
 	claim = ui_scrollbar_pos_event(scrollbar, &event);
-	PCUT_ASSERT_FALSE(scrollbar->up_through_held);
+	PCUT_ASSERT_FALSE(scrollbar->upper_trough_held);
 	PCUT_ASSERT_EQUALS(ui_claimed, claim);
 
@@ -1139,6 +1139,6 @@
 }
 
-/** ui_scrollbar_pos_event() detects down through press/release */
-PCUT_TEST(pos_event_press_release_down_through)
+/** ui_scrollbar_pos_event() detects lower trough press/release */
+PCUT_TEST(pos_event_press_release_lower_trough)
 {
 	ui_t *ui = NULL;
@@ -1164,5 +1164,5 @@
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
-	PCUT_ASSERT_FALSE(scrollbar->up_through_held);
+	PCUT_ASSERT_FALSE(scrollbar->upper_trough_held);
 
 	rect.p0.x = 20;
@@ -1172,18 +1172,18 @@
 	ui_scrollbar_set_rect(scrollbar, &rect);
 
-	/* Press inside down through is claimed and depresses it */
+	/* Press inside lower trough is claimed and depresses it */
 	event.type = POS_PRESS;
 	event.hpos = 70;
 	event.vpos = 20;
 	claim = ui_scrollbar_pos_event(scrollbar, &event);
-	PCUT_ASSERT_TRUE(scrollbar->down_through_held);
+	PCUT_ASSERT_TRUE(scrollbar->lower_trough_held);
 	PCUT_ASSERT_EQUALS(ui_claimed, claim);
 
-	/* Release outside (or anywhere) is claimed and relases up through */
+	/* Release outside (or anywhere) is claimed and relases upper trough */
 	event.type = POS_RELEASE;
 	event.hpos = 41;
 	event.vpos = 32;
 	claim = ui_scrollbar_pos_event(scrollbar, &event);
-	PCUT_ASSERT_FALSE(scrollbar->down_through_held);
+	PCUT_ASSERT_FALSE(scrollbar->lower_trough_held);
 	PCUT_ASSERT_EQUALS(ui_claimed, claim);
 
Index: uspace/srv/clipboard/meson.build
===================================================================
--- uspace/srv/clipboard/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/clipboard/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,3 +1,4 @@
 #
+# Copyright (c) 2023 Jiri Svoboda
 # Copyright (c) 2005 Martin Decky
 # Copyright (c) 2007 Jakub Jermar
@@ -28,3 +29,4 @@
 #
 
+deps = [ 'clipboard' ]
 src = files('clipboard.c')
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/console/console.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -37,4 +37,5 @@
 #include <stdio.h>
 #include <adt/prodcons.h>
+#include <io/console.h>
 #include <io/input.h>
 #include <ipc/vfs.h>
Index: uspace/srv/hid/console/meson.build
===================================================================
--- uspace/srv/hid/console/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/console/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,3 +28,4 @@
 #
 
+deps = [ 'console', 'input', 'output' ]
 src = files('console.c')
Index: uspace/srv/hid/display/meson.build
===================================================================
--- uspace/srv/hid/display/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/display/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'ipcgfx', 'memgfx', 'display', 'ddev', 'dispcfg', 'wndmgt' ]
+deps = [ 'ipcgfx', 'memgfx', 'display', 'ddev', 'dispcfg', 'wndmgt', 'input' ]
 
 src = files(
Index: uspace/srv/hid/input/meson.build
===================================================================
--- uspace/srv/hid/input/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/input/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,5 +28,5 @@
 #
 
-deps = [ 'drv' ]
+deps = [ 'drv', 'console', 'input' ]
 src = files(
 	'layout/cz.c',
Index: uspace/srv/hid/isdv4_tablet/meson.build
===================================================================
--- uspace/srv/hid/isdv4_tablet/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/isdv4_tablet/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'drv' ]
+deps = [ 'drv', 'input' ]
 src = files('main.c', 'isdv4.c')
Index: uspace/srv/hid/output/meson.build
===================================================================
--- uspace/srv/hid/output/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/output/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,5 +28,5 @@
 #
 
-deps = [ 'codepage', 'drv', 'fbfont', 'pixconv', 'ddev' ]
+deps = [ 'codepage', 'console', 'drv', 'fbfont', 'pixconv', 'ddev', 'output' ]
 src = files(
 	'ctl/serial.c',
Index: uspace/srv/hid/remcons/meson.build
===================================================================
--- uspace/srv/hid/remcons/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/remcons/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -28,4 +28,4 @@
 #
 
-deps = [ 'inet' ]
+deps = [ 'inet', 'console' ]
 src = files('remcons.c', 'user.c')
Index: uspace/srv/hid/s3c24xx_ts/meson.build
===================================================================
--- uspace/srv/hid/s3c24xx_ts/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/s3c24xx_ts/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'input' ]
 src = files('s3c24xx_ts.c')
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -39,5 +39,4 @@
 #include <ddi.h>
 #include <loc.h>
-#include <io/console.h>
 #include <vfs/vfs.h>
 #include <ipc/mouseev.h>
Index: uspace/srv/taskmon/meson.build
===================================================================
--- uspace/srv/taskmon/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/taskmon/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2010 Jiri Svoboda
+# Copyright (c) 2023 Jiri Svoboda
 # All rights reserved.
 #
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'corecfg' ]
 src = files('taskmon.c')
Index: uspace/srv/test/ipc-test/meson.build
===================================================================
--- uspace/srv/test/ipc-test/meson.build	(revision 56a3c29e88b204aab857b6e159ccf9e553cf0c09)
+++ uspace/srv/test/ipc-test/meson.build	(revision 4f6368c9f43c5e184ce86a446688b4311b0d63f1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2018 Jiri Svoboda
+# Copyright (c) 2023 Jiri Svoboda
 # All rights reserved.
 #
@@ -27,3 +27,4 @@
 #
 
+deps = [ 'ipctest' ]
 src = files('main.c')
