Index: abi/include/_bits/uchar.h
===================================================================
--- abi/include/_bits/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ abi/include/_bits/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020 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 bits
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _BITS_UCHAR_H_
+#define _BITS_UCHAR_H_
+
+#include <stdint.h>
+
+typedef uint8_t char8_t;
+typedef uint32_t char32_t;
+
+#endif
+
+/** @}
+ */
Index: abi/include/_bits/wchar_limits.h
===================================================================
--- abi/include/_bits/wchar_limits.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ abi/include/_bits/wchar_limits.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,14 +38,14 @@
  */
 
-#ifndef _BITS_WCHAR_MIN_H_
-#define _BITS_WCHAR_MIN_H_
+#ifndef _BITS_WCHAR_LIMITS_H_
+#define _BITS_WCHAR_LIMITS_H_
 
-/* wchar_t should always be signed int in HelenOS. */
+/* wchar_t should always be int32_t in HelenOS. */
 
 #include <_bits/wchar_t.h>
 
 #ifndef __cplusplus
-_Static_assert(((wchar_t)-1) < 0, "wchar_t is not int");
-_Static_assert(sizeof(wchar_t) == 4, "wchar_t is not int");
+_Static_assert(((wchar_t) -1) < 0, "wchar_t is not int32_t");
+_Static_assert(sizeof(wchar_t) == 4, "wchar_t is not int32_t");
 #endif
 
Index: abi/include/inttypes.h
===================================================================
--- abi/include/inttypes.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ abi/include/inttypes.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,4 +43,5 @@
 #include <stdint.h>
 #include <_bits/wchar_t.h>
+#include <_bits/uchar.h>
 #include <_bits/decls.h>
 
@@ -337,10 +338,12 @@
 } imaxdiv_t;
 
-intmax_t imaxabs(intmax_t);
-imaxdiv_t imaxdiv(intmax_t, intmax_t);
-intmax_t strtoimax(const char *__restrict__, char **__restrict__, int);
-uintmax_t strtoumax(const char *__restrict__, char **__restrict__, int);
-intmax_t wcstoimax(const wchar_t *__restrict__, wchar_t **__restrict__, int);
-uintmax_t wcstoumax(const wchar_t *__restrict__, wchar_t **__restrict__, int);
+extern intmax_t imaxabs(intmax_t);
+extern imaxdiv_t imaxdiv(intmax_t, intmax_t);
+extern intmax_t strtoimax(const char *__restrict__, char **__restrict__, int);
+extern uintmax_t strtoumax(const char *__restrict__, char **__restrict__, int);
+extern intmax_t wcstoimax(const wchar_t *__restrict__, wchar_t **__restrict__,
+    int);
+extern uintmax_t wcstoumax(const wchar_t *__restrict__, wchar_t **__restrict__,
+    int);
 
 __C_DECLS_END;
Index: boot/arch/arm32/src/putchar.c
===================================================================
--- boot/arch/arm32/src/putchar.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/arm32/src/putchar.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -193,7 +193,8 @@
 /** Display a character
  *
- * @param ch	Character to display
- */
-void putwchar(const wchar_t ch)
+ * @param ch Character to display
+ *
+ */
+void putuchar(const char32_t ch)
 {
 	if (ch == '\n')
Index: boot/arch/arm64/src/main.c
===================================================================
--- boot/arch/arm64/src/main.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/arm64/src/main.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -99,6 +99,7 @@
  *
  * @param ch Character to display.
- */
-void putwchar(wchar_t ch)
+ *
+ */
+void putuchar(char32_t ch)
 {
 	if (ch == '\n')
Index: boot/arch/ia64/src/putchar.c
===================================================================
--- boot/arch/ia64/src/putchar.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/ia64/src/putchar.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -33,5 +33,5 @@
 #include <arch/ski.h>
 
-void putwchar(const wchar_t ch)
+void putuchar(const char32_t ch)
 {
 #ifdef MACHINE_ski
Index: boot/arch/mips32/src/putchar.c
===================================================================
--- boot/arch/mips32/src/putchar.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/mips32/src/putchar.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -57,5 +57,5 @@
 #endif
 
-void putwchar(const wchar_t ch)
+void putuchar(const char32_t ch)
 {
 	if (ascii_check(ch))
Index: boot/arch/ppc32/src/ofw.c
===================================================================
--- boot/arch/ppc32/src/ofw.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/ppc32/src/ofw.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -39,5 +39,5 @@
 }
 
-void putwchar(wchar_t ch)
+void putuchar(char32_t ch)
 {
 	if (ch == '\n')
Index: boot/arch/riscv64/src/putchar.c
===================================================================
--- boot/arch/riscv64/src/putchar.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/riscv64/src/putchar.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -33,5 +33,5 @@
 #include <arch/ucb.h>
 
-void putwchar(wchar_t ch)
+void putuchar(char32_t ch)
 {
 	if (ascii_check(ch))
Index: boot/arch/sparc64/src/ofw.c
===================================================================
--- boot/arch/sparc64/src/ofw.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/arch/sparc64/src/ofw.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 #include <str.h>
 
-void putwchar(wchar_t ch)
+void putuchar(char32_t ch)
 {
 	if (ch == '\n')
Index: boot/generic/include/putchar.h
===================================================================
--- boot/generic/include/putchar.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/generic/include/putchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -37,6 +37,7 @@
 
 #include <stddef.h>
+#include <uchar.h>
 
-extern void putwchar(wchar_t);
+extern void putuchar(char32_t);
 
 #endif
Index: boot/generic/include/str.h
===================================================================
--- boot/generic/include/str.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/generic/include/str.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,13 +38,14 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <uchar.h>
 
 /* Common Unicode characters */
-#define U_SPECIAL      '?'
+#define U_SPECIAL  '?'
 
 /** No size limit constant */
 #define STR_NO_LIMIT  ((size_t) -1)
 
-extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
-extern errno_t chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
+extern char32_t str_decode(const char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(char32_t ch, char *str, size_t *offset, size_t sz);
 
 extern size_t str_size(const char *str);
@@ -52,6 +53,6 @@
 extern size_t str_length(const char *str);
 
-extern bool ascii_check(wchar_t ch);
-extern bool chr_check(wchar_t ch);
+extern bool ascii_check(char32_t ch);
+extern bool chr_check(char32_t ch);
 
 extern int str_cmp(const char *s1, const char *s2);
Index: boot/generic/include/tar.h
===================================================================
--- boot/generic/include/tar.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/generic/include/tar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -33,6 +33,6 @@
  */
 
-#ifndef TAR_H_
-#define TAR_H_
+#ifndef BOOT_TAR_H_
+#define BOOT_TAR_H_
 
 #include <stdbool.h>
Index: boot/generic/include/uchar.h
===================================================================
--- boot/generic/include/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ boot/generic/include/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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 kernel_generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef BOOT_UCHAR_H_
+#define BOOT_UCHAR_H_
+
+#include <_bits/uchar.h>
+
+#endif
+
+/** @}
+ */
Index: boot/generic/src/printf_core.c
===================================================================
--- boot/generic/src/printf_core.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/generic/src/printf_core.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -504,5 +504,5 @@
 	while (true) {
 		i = nxt;
-		wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+		char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
 
 		if (uc == 0)
Index: boot/generic/src/str.c
===================================================================
--- boot/generic/src/str.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/generic/src/str.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,5 +38,5 @@
  * strings, called just strings are encoded in UTF-8. Wide strings (encoded
  * in UTF-32) are supported to a limited degree. A single character is
- * represented as wchar_t.@n
+ * represented as char32_t.@n
  *
  * Overview of the terminology:@n
@@ -46,6 +46,6 @@
  *  byte                  8 bits stored in uint8_t (unsigned 8 bit integer)
  *
- *  character             UTF-32 encoded Unicode character, stored in wchar_t
- *                        (signed 32 bit integer), code points 0 .. 1114111
+ *  character             UTF-32 encoded Unicode character, stored in char32_t
+ *                        (unsigned 32 bit integer), code points 0 .. 1114111
  *                        are valid
  *
@@ -57,5 +57,5 @@
  *
  *  wide string           UTF-32 encoded NULL-terminated Unicode string,
- *                        wchar_t *
+ *                        char32_t *
  *
  *  [wide] string size    number of BYTES in a [wide] string (excluding
@@ -96,5 +96,5 @@
  * A specific character inside a [wide] string can be referred to by:@n
  *
- *  pointer (char *, wchar_t *)
+ *  pointer (char *, char32_t *)
  *  byte offset (size_t)
  *  character index (size_t)
@@ -109,11 +109,4 @@
 #include <stdint.h>
 
-/** Check the condition if wchar_t is signed */
-#ifdef __WCHAR_UNSIGNED__
-#define WCHAR_SIGNED_CHECK(cond)  (true)
-#else
-#define WCHAR_SIGNED_CHECK(cond)  (cond)
-#endif
-
 /** Byte mask consisting of lowest @n bits (out of 8) */
 #define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
@@ -143,5 +136,5 @@
  *
  */
-wchar_t str_decode(const char *str, size_t *offset, size_t size)
+char32_t str_decode(const char *str, size_t *offset, size_t size)
 {
 	if (*offset + 1 > size)
@@ -180,5 +173,5 @@
 		return U_SPECIAL;
 
-	wchar_t ch = b0 & LO_MASK_8(b0_bits);
+	char32_t ch = b0 & LO_MASK_8(b0_bits);
 
 	/* Decode continuation bytes */
@@ -191,5 +184,5 @@
 
 		/* Shift data bits to ch */
-		ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+		ch = (ch << CONT_BITS) | (char32_t) (b & LO_MASK_8(CONT_BITS));
 		cbytes--;
 	}
@@ -213,5 +206,5 @@
  *         code was invalid.
  */
-errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const char32_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -340,7 +333,7 @@
  *
  */
-bool ascii_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+bool ascii_check(char32_t ch)
+{
+	if (ch <= 127)
 		return true;
 
@@ -353,7 +346,7 @@
  *
  */
-bool chr_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+bool chr_check(char32_t ch)
+{
+	if (ch <= 1114111)
 		return true;
 
@@ -381,6 +374,6 @@
 int str_cmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -421,5 +414,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
Index: boot/generic/src/vprintf.c
===================================================================
--- boot/generic/src/vprintf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ boot/generic/src/vprintf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
 
 	while (offset < size) {
-		putwchar(str_decode(str, &offset, size));
+		putuchar(str_decode(str, &offset, size));
 		chars++;
 	}
@@ -53,12 +53,12 @@
 	size_t offset = 0;
 	size_t chars = 0;
-	wchar_t uc;
+	char32_t uc;
 
 	while ((uc = str_decode(str, &offset, STR_NO_LIMIT)) != 0) {
-		putwchar(uc);
+		putuchar(uc);
 		chars++;
 	}
 
-	putwchar('\n');
+	putuchar('\n');
 	return chars;
 }
Index: contrib/tools/font/bdf2c.pl
===================================================================
--- contrib/tools/font/bdf2c.pl	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ contrib/tools/font/bdf2c.pl	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -106,5 +106,5 @@
 
 print "\n";
-print "uint16_t fb_font_glyph(const wchar_t ch)\n";
+print "uint16_t fb_font_glyph(const char32_t ch)\n";
 print "{\n";
 print "\tif (ch == 0x0000)\n";
Index: kernel/arch/abs32le/src/abs32le.c
===================================================================
--- kernel/arch/abs32le/src/abs32le.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/abs32le/src/abs32le.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -136,5 +136,5 @@
 }
 
-void early_putwchar(wchar_t ch)
+void early_putuchar(char32_t ch)
 {
 }
Index: kernel/arch/amd64/src/asm.S
===================================================================
--- kernel/arch/amd64/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/amd64/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -409,5 +409,5 @@
  *
  */
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 
 #if (defined(CONFIG_L4RE_UVMM_EARLY_PRINT))
@@ -447,9 +447,9 @@
 	/* Sanity check for the cursor on screen */
 	cmp $2000, %ax
-	jb early_putwchar_cursor_ok
+	jb early_putuchar_cursor_ok
 
 		movw $1998, %ax
 
-	early_putwchar_cursor_ok:
+	early_putuchar_cursor_ok:
 
 	movw %ax, %bx
@@ -460,5 +460,5 @@
 
 	cmp $0x0a, %al
-	jne early_putwchar_backspace
+	jne early_putuchar_backspace
 
 		/* Interpret newline */
@@ -474,20 +474,20 @@
 		subw %dx, %bx
 
-		jmp early_putwchar_skip
-
-	early_putwchar_backspace:
+		jmp early_putuchar_skip
+
+	early_putuchar_backspace:
 
 		cmp $0x08, %al
-		jne early_putwchar_print
+		jne early_putuchar_print
 
 		/* Interpret backspace */
 
 		cmp $0x0000, %bx
-		je early_putwchar_skip
+		je early_putuchar_skip
 
 		dec %bx
-		jmp early_putwchar_skip
-
-	early_putwchar_print:
+		jmp early_putuchar_skip
+
+	early_putuchar_print:
 
 		/* Print character */
@@ -497,9 +497,9 @@
 		inc %bx
 
-	early_putwchar_skip:
+	early_putuchar_skip:
 
 	/* Sanity check for the cursor on the last line */
 	cmp $2000, %bx
-	jb early_putwchar_no_scroll
+	jb early_putuchar_no_scroll
 
 		/* Scroll the screen (24 rows) */
@@ -517,5 +517,5 @@
 		movw $1920, %bx
 
-	early_putwchar_no_scroll:
+	early_putuchar_no_scroll:
 
 	/* Write bits 8 - 15 of the cursor address */
@@ -544,3 +544,3 @@
 
 	ret
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/arm32/src/asm.S
===================================================================
--- kernel/arch/arm32/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/arm32/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -98,5 +98,5 @@
 	ldmia sp!, {r4, r5, pc}
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	mov pc, lr
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/arm64/src/asm.S
===================================================================
--- kernel/arch/arm64/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/arm64/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -56,7 +56,7 @@
 FUNCTION_END(memcpy_to_uspace_failover_address)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	ret
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
 
 /* Static checks for the istate_t save/load. */
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/ia32/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -451,5 +451,5 @@
  *
  */
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 
 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
@@ -484,9 +484,9 @@
 	/* Sanity check for the cursor on screen */
 	cmp $2000, %ax
-	jb early_putwchar_cursor_ok
+	jb early_putuchar_cursor_ok
 
 		movw $1998, %ax
 
-	early_putwchar_cursor_ok:
+	early_putuchar_cursor_ok:
 
 	movw %ax, %bx
@@ -497,5 +497,5 @@
 
 	cmp $0x0a, %al
-	jne early_putwchar_backspace
+	jne early_putuchar_backspace
 
 		/* Interpret newline */
@@ -511,20 +511,20 @@
 		subw %dx, %bx
 
-		jmp early_putwchar_skip
-
-	early_putwchar_backspace:
+		jmp early_putuchar_skip
+
+	early_putuchar_backspace:
 
 		cmp $0x08, %al
-		jne early_putwchar_print
+		jne early_putuchar_print
 
 		/* Interpret backspace */
 
 		cmp $0x0000, %bx
-		je early_putwchar_skip
+		je early_putuchar_skip
 
 		dec %bx
-		jmp early_putwchar_skip
-
-	early_putwchar_print:
+		jmp early_putuchar_skip
+
+	early_putuchar_print:
 
 		/* Print character */
@@ -534,9 +534,9 @@
 		inc %bx
 
-	early_putwchar_skip:
+	early_putuchar_skip:
 
 	/* Sanity check for the cursor on the last line */
 	cmp $2000, %bx
-	jb early_putwchar_no_scroll
+	jb early_putuchar_no_scroll
 
 		/* Scroll the screen (24 rows) */
@@ -554,5 +554,5 @@
 		movw $1920, %bx
 
-	early_putwchar_no_scroll:
+	early_putuchar_no_scroll:
 
 	/* Write bits 8 - 15 of the cursor address */
@@ -583,4 +583,4 @@
 
 	ret
-FUNCTION_END(early_putwchar)
-
+FUNCTION_END(early_putuchar)
+
Index: kernel/arch/ia64/src/asm.S
===================================================================
--- kernel/arch/ia64/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/ia64/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -191,5 +191,5 @@
 FUNCTION_END(switch_to_userspace)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	br.ret.sptk.many b0
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -60,8 +60,8 @@
 };
 
-static void ski_putwchar(outdev_t *, const wchar_t);
+static void ski_putuchar(outdev_t *, const char32_t);
 
 static outdev_operations_t skidev_ops = {
-	.write = ski_putwchar,
+	.write = ski_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
@@ -82,5 +82,5 @@
  *
  */
-static wchar_t ski_getchar(void)
+static char32_t ski_getchar(void)
 {
 	uint64_t ch;
@@ -96,5 +96,5 @@
 	);
 
-	return (wchar_t) ch;
+	return (char32_t) ch;
 }
 
@@ -111,5 +111,5 @@
 
 	while (count > 0) {
-		wchar_t ch = ski_getchar();
+		char32_t ch = ski_getchar();
 
 		if (ch == '\0')
@@ -203,5 +203,5 @@
  *
  */
-static void ski_putwchar(outdev_t *dev, wchar_t ch)
+static void ski_putuchar(outdev_t *dev, char32_t ch)
 {
 	if (ski_parea.mapped && !console_override)
Index: kernel/arch/mips32/src/asm.S
===================================================================
--- kernel/arch/mips32/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/mips32/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -296,6 +296,6 @@
 FUNCTION_END(fpu_context_restore)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	j $ra
 	nop
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/ppc32/src/asm.S
===================================================================
--- kernel/arch/ppc32/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/ppc32/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -265,5 +265,5 @@
 	blr
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	blr
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/riscv64/include/arch/drivers/ucb.h
===================================================================
--- kernel/arch/riscv64/include/arch/drivers/ucb.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/riscv64/include/arch/drivers/ucb.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
 extern void htif_init(volatile uint64_t *, volatile uint64_t *);
 extern outdev_t *htifout_init(void);
-extern void htif_putwchar(outdev_t *, const wchar_t);
+extern void htif_putuchar(outdev_t *, const char32_t);
 
 #endif
Index: kernel/arch/riscv64/src/asm.S
===================================================================
--- kernel/arch/riscv64/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/riscv64/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -35,7 +35,7 @@
 FUNCTION_END(asm_delay_loop)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	ret
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
 
 FUNCTION_BEGIN(cpu_halt)
Index: kernel/arch/riscv64/src/drivers/ucb.c
===================================================================
--- kernel/arch/riscv64/src/drivers/ucb.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/riscv64/src/drivers/ucb.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
 
 static outdev_operations_t htifdev_ops = {
-	.write = htif_putwchar,
+	.write = htif_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
@@ -85,5 +85,5 @@
 }
 
-void htif_putwchar(outdev_t *dev, const wchar_t ch)
+void htif_putuchar(outdev_t *dev, const char32_t ch)
 {
 	if (ascii_check(ch))
Index: kernel/arch/sparc64/src/asm.S
===================================================================
--- kernel/arch/sparc64/src/asm.S	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/sparc64/src/asm.S	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -189,6 +189,6 @@
 	mov %g0, %o0  /* return 0 on failure */
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	retl
 	nop
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/sparc64/src/drivers/niagara.c
===================================================================
--- kernel/arch/sparc64/src/drivers/niagara.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -57,9 +57,9 @@
 static niagara_instance_t *instance = NULL;
 
-static void niagara_putwchar(outdev_t *, const wchar_t);
+static void niagara_putuchar(outdev_t *, const char32_t);
 
 /** Character device operations */
 static outdev_operations_t niagara_ops = {
-	.write = niagara_putwchar,
+	.write = niagara_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
@@ -103,5 +103,5 @@
 
 /** Write a single character to the standard output. */
-static void niagara_putwchar(outdev_t *dev, wchar_t ch)
+static void niagara_putuchar(outdev_t *dev, char32_t ch)
 {
 	if ((!outbuf_parea.mapped) || (console_override)) {
Index: kernel/genarch/include/genarch/fb/font-8x16.h
===================================================================
--- kernel/genarch/include/genarch/fb/font-8x16.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/include/genarch/fb/font-8x16.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
 #include <typedefs.h>
 
-extern uint16_t fb_font_glyph(const wchar_t ch);
+extern uint16_t fb_font_glyph(const char32_t ch);
 extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
Index: kernel/genarch/include/genarch/kbrd/scanc.h
===================================================================
--- kernel/genarch/include/genarch/kbrd/scanc.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/include/genarch/kbrd/scanc.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -41,6 +41,6 @@
 #define SCANCODES  128
 
-extern wchar_t sc_primary_map[SCANCODES];
-extern wchar_t sc_secondary_map[SCANCODES];
+extern char32_t sc_primary_map[SCANCODES];
+extern char32_t sc_secondary_map[SCANCODES];
 
 #endif
Index: kernel/genarch/src/drivers/dsrln/dsrlnout.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -49,5 +49,5 @@
 } dsrlnout_instance_t;
 
-static void dsrlnout_putwchar(outdev_t *dev, const wchar_t ch)
+static void dsrlnout_putuchar(outdev_t *dev, const char32_t ch)
 {
 	dsrlnout_instance_t *instance = (dsrlnout_instance_t *) dev->data;
@@ -62,5 +62,5 @@
 
 static outdev_operations_t dsrlndev_ops = {
-	.write = dsrlnout_putwchar,
+	.write = dsrlnout_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -71,9 +71,9 @@
 } ega_instance_t;
 
-static void ega_putwchar(outdev_t *, wchar_t);
+static void ega_putuchar(outdev_t *, char32_t);
 static void ega_redraw(outdev_t *);
 
 static outdev_operations_t egadev_ops = {
-	.write = ega_putwchar,
+	.write = ega_putuchar,
 	.redraw = ega_redraw,
 	.scroll_up = NULL,
@@ -81,7 +81,7 @@
 };
 
-static uint16_t ega_oem_glyph(const wchar_t ch)
-{
-	if ((ch >= 0x0000) && (ch <= 0x007f))
+static uint16_t ega_oem_glyph(const char32_t ch)
+{
+	if (ch <= 0x007f)
 		return ch;
 
@@ -515,5 +515,5 @@
 }
 
-static void ega_display_wchar(ega_instance_t *instance, wchar_t ch)
+static void ega_display_wchar(ega_instance_t *instance, char32_t ch)
 {
 	uint16_t index = ega_oem_glyph(ch);
@@ -538,5 +538,5 @@
 }
 
-static void ega_putwchar(outdev_t *dev, wchar_t ch)
+static void ega_putuchar(outdev_t *dev, char32_t ch)
 {
 	ega_instance_t *instance = (ega_instance_t *) dev->data;
Index: kernel/genarch/src/drivers/ns16550/ns16550.c
===================================================================
--- kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -112,5 +112,5 @@
 }
 
-static void ns16550_putwchar(outdev_t *dev, wchar_t ch)
+static void ns16550_putuchar(outdev_t *dev, char32_t ch)
 {
 	ns16550_instance_t *instance = (ns16550_instance_t *) dev->data;
@@ -128,5 +128,5 @@
 
 static outdev_operations_t ns16550_ops = {
-	.write = ns16550_putwchar,
+	.write = ns16550_putuchar,
 	.redraw = NULL
 };
Index: kernel/genarch/src/drivers/omap/uart.c
===================================================================
--- kernel/genarch/src/drivers/omap/uart.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/drivers/omap/uart.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -49,5 +49,5 @@
 }
 
-static void omap_uart_putwchar(outdev_t *dev, wchar_t ch)
+static void omap_uart_putuchar(outdev_t *dev, char32_t ch)
 {
 	omap_uart_t *uart = dev->data;
@@ -62,5 +62,5 @@
 
 static outdev_operations_t omap_uart_ops = {
-	.write = omap_uart_putwchar,
+	.write = omap_uart_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -56,5 +56,5 @@
 }
 
-static void pl011_uart_putwchar(outdev_t *dev, wchar_t ch)
+static void pl011_uart_putuchar(outdev_t *dev, char32_t ch)
 {
 	pl011_uart_t *uart = dev->data;
@@ -74,5 +74,5 @@
 
 static outdev_operations_t pl011_uart_ops = {
-	.write = pl011_uart_putwchar,
+	.write = pl011_uart_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/drivers/s3c24xx/uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx/uart.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/drivers/s3c24xx/uart.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -61,5 +61,5 @@
 }
 
-static void s3c24xx_uart_putwchar(outdev_t *dev, wchar_t ch)
+static void s3c24xx_uart_putuchar(outdev_t *dev, char32_t ch)
 {
 	s3c24xx_uart_t *uart =
@@ -94,5 +94,5 @@
 
 static outdev_operations_t s3c24xx_uart_ops = {
-	.write = s3c24xx_uart_putwchar,
+	.write = s3c24xx_uart_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/fb/fb.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -123,5 +123,5 @@
 } fb_instance_t;
 
-static void fb_putwchar(outdev_t *, wchar_t);
+static void fb_putuchar(outdev_t *, char32_t);
 static void fb_redraw(outdev_t *);
 static void fb_scroll_up(outdev_t *);
@@ -129,5 +129,5 @@
 
 static outdev_operations_t fbdev_ops = {
-	.write = fb_putwchar,
+	.write = fb_putuchar,
 	.redraw = fb_redraw,
 	.scroll_up = fb_scroll_up,
@@ -418,5 +418,5 @@
  *
  */
-static void fb_putwchar(outdev_t *dev, wchar_t ch)
+static void fb_putuchar(outdev_t *dev, char32_t ch)
 {
 	fb_instance_t *instance = (fb_instance_t *) dev->data;
Index: kernel/genarch/src/fb/font-8x16.c
===================================================================
--- kernel/genarch/src/fb/font-8x16.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/fb/font-8x16.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
  * mark glyph if no specific glyph exists.
  */
-uint16_t fb_font_glyph(const wchar_t ch)
+uint16_t fb_font_glyph(const char32_t ch)
 {
 	if (ch == 0x0000)
Index: kernel/genarch/src/kbrd/kbrd.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/kbrd/kbrd.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -76,5 +76,5 @@
  * @param sc Scancode of the key being released.
  */
-static void key_released(kbrd_instance_t *instance, wchar_t sc)
+static void key_released(kbrd_instance_t *instance, char32_t sc)
 {
 	spinlock_lock(&instance->keylock);
@@ -103,10 +103,10 @@
  * @param sc Scancode of the key being pressed.
  */
-static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
+static void key_pressed(kbrd_instance_t *instance, char32_t sc)
 {
 	bool letter;
 	bool shift;
 	bool capslock;
-	wchar_t ch;
+	char32_t ch;
 
 	spinlock_lock(&instance->keylock);
@@ -158,5 +158,5 @@
 
 	while (true) {
-		wchar_t sc = indev_pop_character(&instance->raw);
+		char32_t sc = indev_pop_character(&instance->raw);
 
 		if (sc == IGNORE_CODE)
Index: kernel/genarch/src/kbrd/kbrd_at.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd_at.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/kbrd/kbrd_at.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -59,5 +59,5 @@
 #define AT_SCROLL_SCAN_CODE	0x7E
 
-static bool is_lock_key(wchar_t);
+static bool is_lock_key(char32_t);
 
 static indev_operations_t kbrd_raw_ops = {
@@ -69,5 +69,5 @@
  * @param sc Scancode of the key being released.
  */
-static void key_released(kbrd_instance_t *instance, wchar_t sc)
+static void key_released(kbrd_instance_t *instance, char32_t sc)
 {
 	spinlock_lock(&instance->keylock);
@@ -96,5 +96,5 @@
  * @param sc Scancode of the key being pressed.
  */
-static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
+static void key_pressed(kbrd_instance_t *instance, char32_t sc)
 {
 	bool letter;
@@ -140,5 +140,5 @@
 
 	while (true) {
-		wchar_t sc = indev_pop_character(&instance->raw);
+		char32_t sc = indev_pop_character(&instance->raw);
 
 		if (sc == AT_KEY_RELEASE) {
@@ -203,5 +203,5 @@
 }
 
-static bool is_lock_key(wchar_t sc)
+static bool is_lock_key(char32_t sc)
 {
 	return ((sc == AT_CAPS_SCAN_CODE) || (sc == AT_NUM_SCAN_CODE) ||
Index: kernel/genarch/src/kbrd/scanc_at.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_at.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/kbrd/scanc_at.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -39,5 +39,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[] = {
+char32_t sc_primary_map[] = {
 	U_NULL, /* 0x00 */
 	U_SPECIAL, /* 0x01 - F9 */
@@ -135,5 +135,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[] = {
+char32_t sc_secondary_map[] = {
 	U_NULL, /* 0x00 */
 	U_SPECIAL, /* 0x01 - F9 */
Index: kernel/genarch/src/kbrd/scanc_mac.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_mac.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/kbrd/scanc_mac.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -40,5 +40,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[SCANCODES] = {
+char32_t sc_primary_map[SCANCODES] = {
 	[0x00] = 'a',
 	[0x01] = 's',
@@ -172,5 +172,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[SCANCODES] = {
+char32_t sc_secondary_map[SCANCODES] = {
 	[0x00] = 'A',
 	[0x01] = 'S',
Index: kernel/genarch/src/kbrd/scanc_pc.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_pc.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/kbrd/scanc_pc.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -40,5 +40,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[SCANCODES] = {
+char32_t sc_primary_map[SCANCODES] = {
 	U_NULL,         /* 0x00 - undefined */
 	U_ESCAPE,       /* 0x01 - Esc */
@@ -129,5 +129,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[SCANCODES] = {
+char32_t sc_secondary_map[SCANCODES] = {
 	U_NULL,         /* 0x00 - undefined */
 	U_ESCAPE,       /* 0x01 - Esc */
Index: kernel/genarch/src/kbrd/scanc_sun.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_sun.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/kbrd/scanc_sun.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -40,5 +40,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[SCANCODES] = {
+char32_t sc_primary_map[SCANCODES] = {
 	[0x00] = U_SPECIAL,
 	[0x01] = U_SPECIAL,
@@ -172,5 +172,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[SCANCODES] = {
+char32_t sc_secondary_map[SCANCODES] = {
 	[0x00] = U_SPECIAL,
 	[0x01] = U_SPECIAL,
Index: kernel/genarch/src/srln/srln.c
===================================================================
--- kernel/genarch/src/srln/srln.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/genarch/src/srln/srln.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -56,5 +56,5 @@
 
 	while (true) {
-		wchar_t ch = indev_pop_character(&instance->raw);
+		char32_t ch = indev_pop_character(&instance->raw);
 
 		/* ANSI escape sequence processing */
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/include/console/chardev.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -55,5 +55,5 @@
 typedef struct {
 	/** Read character directly from device, assume interrupts disabled. */
-	wchar_t (*poll)(struct indev *);
+	char32_t (*poll)(struct indev *);
 
 	/** Signal out-of-band condition. */
@@ -68,5 +68,5 @@
 	/** Protects everything below. */
 	IRQ_SPINLOCK_DECLARE(lock);
-	wchar_t buffer[INDEV_BUFLEN];
+	char32_t buffer[INDEV_BUFLEN];
 	size_t counter;
 
@@ -82,5 +82,5 @@
 typedef struct {
 	/** Write character to output. */
-	void (*write)(struct outdev *, wchar_t);
+	void (*write)(struct outdev *, char32_t);
 
 	/** Redraw any previously cached characters. */
@@ -112,6 +112,6 @@
 extern void indev_initialize(const char *, indev_t *,
     indev_operations_t *);
-extern void indev_push_character(indev_t *, wchar_t);
-extern wchar_t indev_pop_character(indev_t *);
+extern void indev_push_character(indev_t *, char32_t);
+extern char32_t indev_pop_character(indev_t *);
 extern void indev_signal(indev_t *, indev_signal_t);
 
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/include/console/console.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -57,5 +57,5 @@
 extern outdev_t *stdout;
 
-extern void early_putwchar(wchar_t);
+extern void early_putuchar(char32_t);
 
 extern indev_t *stdin_wire(void);
@@ -66,8 +66,8 @@
 extern void kio_update(void *);
 extern void kio_flush(void);
-extern void kio_push_char(const wchar_t);
+extern void kio_push_char(const char32_t);
 SPINLOCK_EXTERN(kio_lock);
 
-extern wchar_t getc(indev_t *indev);
+extern char32_t getc(indev_t *indev);
 extern size_t gets(indev_t *indev, char *buf, size_t buflen);
 extern sys_errno_t sys_kio(int cmd, uspace_addr_t buf, size_t size);
Index: kernel/generic/include/printf/printf_core.h
===================================================================
--- kernel/generic/include/printf/printf_core.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/include/printf/printf_core.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,4 +38,5 @@
 #include <stdarg.h>
 #include <stddef.h>
+#include <uchar.h>
 
 /** Structure for specifying output methods for different printf clones. */
@@ -45,5 +46,5 @@
 
 	/* Wide string output function, returns number of printed characters or EOF */
-	int (*wstr_write)(const wchar_t *, size_t, void *);
+	int (*wstr_write)(const char32_t *, size_t, void *);
 
 	/* User data - output stream specification, state, locks, etc. */
Index: kernel/generic/include/putchar.h
===================================================================
--- kernel/generic/include/putchar.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/include/putchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -36,7 +36,7 @@
 #define KERN_PUTCHAR_H_
 
-#include <stddef.h>
+#include <uchar.h>
 
-extern void putwchar(wchar_t);
+extern void putuchar(char32_t);
 
 #endif
Index: kernel/generic/include/str.h
===================================================================
--- kernel/generic/include/str.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/include/str.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -44,5 +44,5 @@
 
 /* Common Unicode characters */
-#define U_SPECIAL      '?'
+#define U_SPECIAL  '?'
 
 #define U_LEFT_ARROW   0x2190
@@ -69,36 +69,36 @@
 #define STR_BOUNDS(length)  ((length) << 2)
 
-extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
-extern errno_t chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
+extern char32_t str_decode(const char *, size_t *, size_t);
+extern errno_t chr_encode(char32_t, char *, size_t *, size_t);
 
-extern size_t str_size(const char *str);
-extern size_t wstr_size(const wchar_t *str);
+extern size_t str_size(const char *);
+extern size_t wstr_size(const char32_t *);
 
-extern size_t str_lsize(const char *str, size_t max_len);
-extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
+extern size_t str_lsize(const char *, size_t);
+extern size_t wstr_lsize(const char32_t *, size_t);
 
-extern size_t str_length(const char *str);
-extern size_t wstr_length(const wchar_t *wstr);
+extern size_t str_length(const char *);
+extern size_t wstr_length(const char32_t *);
 
-extern size_t str_nlength(const char *str, size_t size);
-extern size_t wstr_nlength(const wchar_t *str, size_t size);
+extern size_t str_nlength(const char *, size_t);
+extern size_t wstr_nlength(const char32_t *, size_t);
 
-extern bool ascii_check(wchar_t ch);
-extern bool chr_check(wchar_t ch);
+extern bool ascii_check(char32_t);
+extern bool chr_check(char32_t);
 
-extern int str_cmp(const char *s1, const char *s2);
-extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
+extern int str_cmp(const char *, const char *);
+extern int str_lcmp(const char *, const char *, size_t);
 
-extern void str_cpy(char *dest, size_t size, const char *src);
-extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
-extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
+extern void str_cpy(char *, size_t, const char *);
+extern void str_ncpy(char *, size_t, const char *, size_t);
+extern void wstr_to_str(char *, size_t, const char32_t *);
 
-extern char *str_chr(const char *str, wchar_t ch);
+extern char *str_chr(const char *, char32_t);
 
-extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
-extern bool wstr_remove(wchar_t *str, size_t pos);
+extern bool wstr_linsert(char32_t *, char32_t, size_t, size_t);
+extern bool wstr_remove(char32_t *, size_t);
 
-extern char *str_dup(const char *src);
-extern char *str_ndup(const char *src, size_t n);
+extern char *str_dup(const char *);
+extern char *str_ndup(const char *, size_t);
 
 extern errno_t str_uint64_t(const char *, char **, unsigned int, bool,
@@ -108,6 +108,6 @@
 extern void bin_order_suffix(const uint64_t, uint64_t *, const char **, bool);
 
-extern const char *str_error(errno_t err);
-extern const char *str_error_name(errno_t err);
+extern const char *str_error(errno_t);
+extern const char *str_error_name(errno_t);
 
 #endif
Index: kernel/generic/include/uchar.h
===================================================================
--- kernel/generic/include/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ kernel/generic/include/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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 kernel_generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _KERN_UCHAR_H_
+#define _KERN_UCHAR_H_
+
+#include <_bits/uchar.h>
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/console/chardev.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -65,5 +65,5 @@
  *
  */
-void indev_push_character(indev_t *indev, wchar_t ch)
+void indev_push_character(indev_t *indev, char32_t ch)
 {
 	assert(indev);
@@ -92,5 +92,5 @@
  *
  */
-wchar_t indev_pop_character(indev_t *indev)
+char32_t indev_pop_character(indev_t *indev)
 {
 	if (atomic_load(&haltstate)) {
@@ -117,5 +117,5 @@
 	waitq_sleep(&indev->wq);
 	irq_spinlock_lock(&indev->lock, true);
-	wchar_t ch = indev->buffer[(indev->index - indev->counter) %
+	char32_t ch = indev->buffer[(indev->index - indev->counter) %
 	    INDEV_BUFLEN];
 	indev->counter--;
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/console/console.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -59,8 +59,8 @@
 
 #define KIO_PAGES    8
-#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t))
+#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(char32_t))
 
 /** Kernel log cyclic buffer */
-wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
+char32_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
 
 /** Kernel log initialized */
@@ -95,5 +95,5 @@
 };
 
-static void stdout_write(outdev_t *, wchar_t);
+static void stdout_write(outdev_t *, char32_t);
 static void stdout_redraw(outdev_t *);
 static void stdout_scroll_up(outdev_t *);
@@ -148,5 +148,5 @@
 }
 
-static void stdout_write(outdev_t *dev, wchar_t ch)
+static void stdout_write(outdev_t *dev, char32_t ch)
 {
 	list_foreach(dev->list, link, outdev_t, sink) {
@@ -261,12 +261,12 @@
 	buf[offset] = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = indev_pop_character(indev)) != '\n') {
 		if (ch == '\b') {
 			if (count > 0) {
 				/* Space, backspace, space */
-				putwchar('\b');
-				putwchar(' ');
-				putwchar('\b');
+				putuchar('\b');
+				putuchar(' ');
+				putuchar('\b');
 
 				count--;
@@ -277,5 +277,5 @@
 
 		if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
-			putwchar(ch);
+			putuchar(ch);
 			count++;
 			buf[offset] = 0;
@@ -287,8 +287,8 @@
 
 /** Get character from input device & echo it to screen */
-wchar_t getc(indev_t *indev)
-{
-	wchar_t ch = indev_pop_character(indev);
-	putwchar(ch);
+char32_t getc(indev_t *indev)
+{
+	char32_t ch = indev_pop_character(indev);
+	putuchar(ch);
 	return ch;
 }
@@ -324,5 +324,5 @@
 	/* Print characters that weren't printed earlier */
 	while (kio_stored > 0) {
-		wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
+		char32_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
 		kio_stored--;
 
@@ -344,5 +344,5 @@
  * The caller is required to hold kio_lock
  */
-void kio_push_char(const wchar_t ch)
+void kio_push_char(const char32_t ch)
 {
 	kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
@@ -360,5 +360,5 @@
 }
 
-void putwchar(const wchar_t ch)
+void putuchar(const char32_t ch)
 {
 	bool ordy = ((stdout) && (stdout->op->write));
@@ -377,10 +377,10 @@
 		 * for possible future output.
 		 *
-		 * The early_putwchar() function is used to output
+		 * The early_putuchar() function is used to output
 		 * the character for low-level debugging purposes.
 		 * Note that the early_putc() function might be
 		 * a no-op on certain hardware configurations.
 		 */
-		early_putwchar(ch);
+		early_putuchar(ch);
 	}
 
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/console/kconsole.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -86,5 +86,5 @@
 LIST_INITIALIZE(cmd_list);      /**< Command list. */
 
-static wchar_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = { };
+static char32_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = { };
 static size_t history_pos = 0;
 
@@ -156,9 +156,9 @@
 
 /** Print count times a character */
-_NO_TRACE static void print_cc(wchar_t ch, size_t count)
+_NO_TRACE static void print_cc(char32_t ch, size_t count)
 {
 	size_t i;
 	for (i = 0; i < count; i++)
-		putwchar(ch);
+		putuchar(ch);
 }
 
@@ -290,5 +290,5 @@
 }
 
-_NO_TRACE static cmd_info_t *parse_cmd(const wchar_t *cmdline)
+_NO_TRACE static cmd_info_t *parse_cmd(const char32_t *cmdline)
 {
 	size_t start = 0;
@@ -331,5 +331,5 @@
 }
 
-_NO_TRACE static wchar_t *clever_readline(const char *prompt, indev_t *indev,
+_NO_TRACE static char32_t *clever_readline(const char *prompt, indev_t *indev,
     char *tmp)
 {
@@ -337,13 +337,13 @@
 
 	size_t position = 0;
-	wchar_t *current = history[history_pos];
+	char32_t *current = history[history_pos];
 	current[0] = 0;
 
 	while (true) {
-		wchar_t ch = indev_pop_character(indev);
+		char32_t ch = indev_pop_character(indev);
 
 		if (ch == '\n') {
 			/* Enter */
-			putwchar(ch);
+			putuchar(ch);
 			break;
 		}
@@ -356,5 +356,5 @@
 			if (wstr_remove(current, position - 1)) {
 				position--;
-				putwchar('\b');
+				putuchar('\b');
 				printf("%ls ", current + position);
 				print_cc('\b', wstr_length(current) - position + 1);
@@ -369,5 +369,5 @@
 			for (; (current[position] != 0) && (!isspace(current[position]));
 			    position++)
-				putwchar(current[position]);
+				putuchar(current[position]);
 
 			/*
@@ -464,5 +464,5 @@
 			/* Left */
 			if (position > 0) {
-				putwchar('\b');
+				putuchar('\b');
 				position--;
 			}
@@ -473,5 +473,5 @@
 			/* Right */
 			if (position < wstr_length(current)) {
-				putwchar(current[position]);
+				putuchar(current[position]);
 				position++;
 			}
@@ -646,5 +646,5 @@
 	size_t offset = *start;
 	size_t prev = *start;
-	wchar_t ch;
+	char32_t ch;
 
 	while ((ch = str_decode(cmdline, &offset, size)) != 0) {
@@ -825,5 +825,5 @@
 
 	while (true) {
-		wchar_t *tmp = clever_readline((char *) prompt, stdin, buffer);
+		char32_t *tmp = clever_readline((char *) prompt, stdin, buffer);
 		size_t len = wstr_length(tmp);
 		if (!len)
Index: kernel/generic/src/console/prompt.c
===================================================================
--- kernel/generic/src/console/prompt.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/console/prompt.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -56,5 +56,5 @@
 
 	while (true) {
-		wchar_t answer = indev_pop_character(indev);
+		char32_t answer = indev_pop_character(indev);
 
 		if ((answer == 'y') || (answer == 'Y')) {
@@ -87,5 +87,5 @@
 	printf("--More--");
 	while (true) {
-		wchar_t continue_showing_hints = indev_pop_character(indev);
+		char32_t continue_showing_hints = indev_pop_character(indev);
 		/* Display a full page again? */
 		if ((continue_showing_hints == 'y') ||
Index: kernel/generic/src/lib/str.c
===================================================================
--- kernel/generic/src/lib/str.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/lib/str.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
  * strings, called just strings are encoded in UTF-8. Wide strings (encoded
  * in UTF-32) are supported to a limited degree. A single character is
- * represented as wchar_t.@n
+ * represented as char32_t.@n
  *
  * Overview of the terminology:@n
@@ -50,6 +50,6 @@
  *  byte                  8 bits stored in uint8_t (unsigned 8 bit integer)
  *
- *  character             UTF-32 encoded Unicode character, stored in wchar_t
- *                        (signed 32 bit integer), code points 0 .. 1114111
+ *  character             UTF-32 encoded Unicode character, stored in char32_t
+ *                        (unsigned 32 bit integer), code points 0 .. 1114111
  *                        are valid
  *
@@ -61,5 +61,5 @@
  *
  *  wide string           UTF-32 encoded NULL-terminated Unicode string,
- *                        wchar_t *
+ *                        char32_t *
  *
  *  [wide] string size    number of BYTES in a [wide] string (excluding
@@ -100,5 +100,5 @@
  * A specific character inside a [wide] string can be referred to by:@n
  *
- *  pointer (char *, wchar_t *)
+ *  pointer (char *, char32_t *)
  *  byte offset (size_t)
  *  character index (size_t)
@@ -118,11 +118,4 @@
 #include <macros.h>
 
-/** Check the condition if wchar_t is signed */
-#ifdef __WCHAR_UNSIGNED__
-#define WCHAR_SIGNED_CHECK(cond)  (true)
-#else
-#define WCHAR_SIGNED_CHECK(cond)  (cond)
-#endif
-
 /** Byte mask consisting of lowest @n bits (out of 8) */
 #define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
@@ -152,5 +145,5 @@
  *
  */
-wchar_t str_decode(const char *str, size_t *offset, size_t size)
+char32_t str_decode(const char *str, size_t *offset, size_t size)
 {
 	if (*offset + 1 > size)
@@ -189,5 +182,5 @@
 		return U_SPECIAL;
 
-	wchar_t ch = b0 & LO_MASK_8(b0_bits);
+	char32_t ch = b0 & LO_MASK_8(b0_bits);
 
 	/* Decode continuation bytes */
@@ -200,5 +193,5 @@
 
 		/* Shift data bits to ch */
-		ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+		ch = (ch << CONT_BITS) | (char32_t) (b & LO_MASK_8(CONT_BITS));
 		cbytes--;
 	}
@@ -222,5 +215,5 @@
  *         code was invalid.
  */
-errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const char32_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -308,7 +301,7 @@
  *
  */
-size_t wstr_size(const wchar_t *str)
-{
-	return (wstr_length(str) * sizeof(wchar_t));
+size_t wstr_size(const char32_t *str)
+{
+	return (wstr_length(str) * sizeof(char32_t));
 }
 
@@ -354,7 +347,7 @@
  *
  */
-size_t wstr_lsize(const wchar_t *str, size_t max_len)
-{
-	return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
+size_t wstr_lsize(const char32_t *str, size_t max_len)
+{
+	return (wstr_nlength(str, max_len * sizeof(char32_t)) * sizeof(char32_t));
 }
 
@@ -384,5 +377,5 @@
  *
  */
-size_t wstr_length(const wchar_t *wstr)
+size_t wstr_length(const char32_t *wstr)
 {
 	size_t len = 0;
@@ -421,13 +414,13 @@
  *
  */
-size_t wstr_nlength(const wchar_t *str, size_t size)
+size_t wstr_nlength(const char32_t *str, size_t size)
 {
 	size_t len = 0;
-	size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
+	size_t limit = ALIGN_DOWN(size, sizeof(char32_t));
 	size_t offset = 0;
 
 	while ((offset < limit) && (*str++ != 0)) {
 		len++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
@@ -440,7 +433,7 @@
  *
  */
-bool ascii_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+bool ascii_check(char32_t ch)
+{
+	if (ch <= 127)
 		return true;
 
@@ -453,7 +446,7 @@
  *
  */
-bool chr_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+bool chr_check(char32_t ch)
+{
+	if (ch <= 1114111)
 		return true;
 
@@ -481,6 +474,6 @@
 int str_cmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -528,6 +521,6 @@
 int str_lcmp(const char *s1, const char *s2, size_t max_len)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -580,5 +573,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -613,5 +606,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, n)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -628,11 +621,11 @@
  * written will always be well-formed.
  *
- * @param dest	Destination buffer.
- * @param size	Size of the destination buffer.
- * @param src	Source wide string.
- */
-void wstr_to_str(char *dest, size_t size, const wchar_t *src)
-{
-	wchar_t ch;
+ * @param dest Destination buffer.
+ * @param size Size of the destination buffer.
+ * @param src  Source wide string.
+ */
+void wstr_to_str(char *dest, size_t size, const char32_t *src)
+{
+	char32_t ch;
 	size_t src_idx;
 	size_t dest_off;
@@ -659,7 +652,7 @@
  * @return Pointer to character in @a str or NULL if not found.
  */
-char *str_chr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
+char *str_chr(const char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t last = 0;
@@ -688,5 +681,5 @@
  *
  */
-bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
+bool wstr_linsert(char32_t *str, char32_t ch, size_t pos, size_t max_pos)
 {
 	size_t len = wstr_length(str);
@@ -716,5 +709,5 @@
  *
  */
-bool wstr_remove(wchar_t *str, size_t pos)
+bool wstr_remove(char32_t *str, size_t pos)
 {
 	size_t len = wstr_length(str);
Index: kernel/generic/src/log/log.c
===================================================================
--- kernel/generic/src/log/log.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/log/log.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -214,5 +214,5 @@
 }
 
-static int log_printf_wstr_write(const wchar_t *wstr, size_t size, void *data)
+static int log_printf_wstr_write(const char32_t *wstr, size_t size, void *data)
 {
 	char buffer[16];
@@ -220,5 +220,5 @@
 	size_t chars = 0;
 
-	for (offset = 0; offset < size; offset += sizeof(wchar_t), chars++) {
+	for (offset = 0; offset < size; offset += sizeof(char32_t), chars++) {
 		kio_push_char(wstr[chars]);
 
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/printf/printf_core.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -139,5 +139,5 @@
  *
  */
-static int printf_wputnchars(const wchar_t *buf, size_t size,
+static int printf_wputnchars(const char32_t *buf, size_t size,
     printf_spec_t *ps)
 {
@@ -185,10 +185,10 @@
  *
  */
-static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
+static int printf_putuchar(const char32_t ch, printf_spec_t *ps)
 {
 	if (!chr_check(ch))
 		return ps->str_write((void *) &invalch, 1, ps->data);
 
-	return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
+	return ps->wstr_write(&ch, sizeof(char32_t), ps->data);
 }
 
@@ -240,5 +240,5 @@
  *
  */
-static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
+static int print_wchar(const char32_t ch, int width, uint32_t flags, printf_spec_t *ps)
 {
 	size_t counter = 0;
@@ -254,5 +254,5 @@
 	}
 
-	if (printf_putwchar(ch, ps) > 0)
+	if (printf_putuchar(ch, ps) > 0)
 		counter++;
 
@@ -326,5 +326,5 @@
  * @return Number of wide characters printed, negative value on failure.
  */
-static int print_wstr(wchar_t *str, int width, unsigned int precision,
+static int print_wstr(char32_t *str, int width, unsigned int precision,
     uint32_t flags, printf_spec_t *ps)
 {
@@ -576,5 +576,5 @@
  *  - "l"  Signed or unsigned long int.@n
  *         If conversion is "c", the character is wint_t (wide character).@n
- *         If conversion is "s", the string is wchar_t * (wide string).@n
+ *         If conversion is "s", the string is char32_t * (UTF-32 string).@n
  *  - "ll" Signed or unsigned long long int.@n
  *  - "z"  Signed or unsigned ssize_t or site_t.@n
@@ -630,5 +630,5 @@
 	while (true) {
 		i = nxt;
-		wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+		char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
 
 		if (uc == 0)
@@ -789,5 +789,5 @@
 			case 's':
 				if (qualifier == PrintfQualifierLong)
-					retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
+					retval = print_wstr(va_arg(ap, char32_t *), width, precision, flags, ps);
 				else
 					retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
Index: kernel/generic/src/printf/vprintf.c
===================================================================
--- kernel/generic/src/printf/vprintf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/printf/vprintf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -47,5 +47,5 @@
 
 	while (offset < size) {
-		putwchar(str_decode(str, &offset, size));
+		putuchar(str_decode(str, &offset, size));
 		chars++;
 	}
@@ -54,5 +54,5 @@
 }
 
-static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+static int vprintf_wstr_write(const char32_t *str, size_t size, void *data)
 {
 	size_t offset = 0;
@@ -60,7 +60,7 @@
 
 	while (offset < size) {
-		putwchar(str[chars]);
+		putuchar(str[chars]);
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
@@ -72,12 +72,12 @@
 	size_t offset = 0;
 	size_t chars = 0;
-	wchar_t uc;
+	char32_t uc;
 
 	while ((uc = str_decode(str, &offset, STR_NO_LIMIT)) != 0) {
-		putwchar(uc);
+		putuchar(uc);
 		chars++;
 	}
 
-	putwchar('\n');
+	putuchar('\n');
 	return chars;
 }
Index: kernel/generic/src/printf/vsnprintf.c
===================================================================
--- kernel/generic/src/printf/vsnprintf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ kernel/generic/src/printf/vsnprintf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -88,5 +88,5 @@
 
 		while (index < size) {
-			wchar_t uc = str_decode(str, &index, size);
+			char32_t uc = str_decode(str, &index, size);
 
 			if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
@@ -133,9 +133,9 @@
  *
  */
-static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
+static int vsnprintf_wstr_write(const char32_t *str, size_t size, vsnprintf_data_t *data)
 {
 	size_t index = 0;
 
-	while (index < (size / sizeof(wchar_t))) {
+	while (index < (size / sizeof(char32_t))) {
 		size_t left = data->size - data->len;
 
@@ -177,5 +177,5 @@
 	printf_spec_t ps = {
 		(int (*) (const char *, size_t, void *)) vsnprintf_str_write,
-		(int (*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
+		(int (*) (const char32_t *, size_t, void *)) vsnprintf_wstr_write,
 		&data
 	};
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -154,5 +154,5 @@
 }
 
-static void paged_char(wchar_t c)
+static void paged_char(char32_t c)
 {
 	if (last_char_was_newline && number) {
@@ -160,5 +160,5 @@
 		printf("%6u  ", lineno);
 	}
-	putwchar(c);
+	putuchar(c);
 	last_char_was_newline = c == '\n';
 	if (paging_enabled) {
@@ -269,5 +269,5 @@
 					paged_char(((count + i + 1) & 0xf) == 0 ? '\n' : ' ');
 				} else {
-					wchar_t c = str_decode(buff, &offset, bytes);
+					char32_t c = str_decode(buff, &offset, bytes);
 					if (c == 0) {
 						/* Reached end of string */
Index: uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mkdir/mkdir.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/bdsh/cmds/modules/mkdir/mkdir.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -108,5 +108,5 @@
 		while (true) {
 			size_t prev_off = off;
-			wchar_t cur_char = str_decode(path, &off, STR_NO_LIMIT);
+			char32_t cur_char = str_decode(path, &off, STR_NO_LIMIT);
 			if ((cur_char == 0) || (cur_char == U_SPECIAL)) {
 				break;
Index: uspace/app/bdsh/cmds/modules/printf/printf.c
===================================================================
--- uspace/app/bdsh/cmds/modules/printf/printf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/bdsh/cmds/modules/printf/printf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -68,5 +68,5 @@
  * @param arg string with data to print.
  */
-static int print_arg(wchar_t ch, const char *arg)
+static int print_arg(char32_t ch, const char *arg)
 {
 	switch (ch) {
@@ -93,5 +93,5 @@
  * @param ch  Control character.
  */
-static int process_ctl(wchar_t ch)
+static int process_ctl(char32_t ch)
 {
 	switch (ch) {
@@ -120,5 +120,5 @@
 	char *fmt;
 	size_t pos, fmt_sz;
-	wchar_t ch;
+	char32_t ch;
 	bool esc_flag = false;
 	unsigned int carg;     // Current argument
@@ -170,9 +170,9 @@
 				break;
 			}
-			putwchar(ch);
+			putuchar(ch);
 			break;
 
 		emit:
-			putwchar(ch);
+			putuchar(ch);
 			esc_flag = false;
 		}
Index: uspace/app/bdsh/compl.c
===================================================================
--- uspace/app/bdsh/compl.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/bdsh/compl.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -44,5 +44,5 @@
 #include "util.h"
 
-static errno_t compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
+static errno_t compl_init(char32_t *text, size_t pos, size_t *cstart, void **state);
 static errno_t compl_get_next(void *state, char **compl);
 static void compl_fini(void *state);
@@ -94,5 +94,5 @@
  * Set up iterators in completion object, based on current token.
  */
-static errno_t compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state)
+static errno_t compl_init(char32_t *text, size_t pos, size_t *cstart, void **state)
 {
 	compl_t *cs = NULL;
Index: uspace/app/bdsh/tok.c
===================================================================
--- uspace/app/bdsh/tok.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/bdsh/tok.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -36,7 +36,7 @@
 
 /* Forward declarations of static functions */
-static wchar_t tok_get_char(tokenizer_t *);
-static wchar_t tok_look_char(tokenizer_t *);
-static errno_t tok_push_char(tokenizer_t *, wchar_t);
+static char32_t tok_get_char(tokenizer_t *);
+static char32_t tok_look_char(tokenizer_t *);
+static errno_t tok_push_char(tokenizer_t *, char32_t);
 static errno_t tok_push_token(tokenizer_t *);
 static bool tok_pending_chars(tokenizer_t *);
@@ -92,5 +92,5 @@
 {
 	errno_t rc;
-	wchar_t next_char;
+	char32_t next_char;
 
 	/* Read the input line char by char and append tokens */
@@ -182,5 +182,5 @@
 {
 	errno_t rc;
-	wchar_t next_char;
+	char32_t next_char;
 
 	while ((next_char = tok_look_char(tok)) != 0) {
@@ -214,5 +214,5 @@
 
 /** Get a char from input, advancing the input position */
-wchar_t tok_get_char(tokenizer_t *tok)
+char32_t tok_get_char(tokenizer_t *tok)
 {
 	tok->in_char_offset++;
@@ -221,9 +221,9 @@
 
 /** Get a char from input, while staying on the same input position */
-wchar_t tok_look_char(tokenizer_t *tok)
+char32_t tok_look_char(tokenizer_t *tok)
 {
 	size_t old_offset = tok->in_offset;
 	size_t old_char_offset = tok->in_char_offset;
-	wchar_t ret = tok_get_char(tok);
+	char32_t ret = tok_get_char(tok);
 	tok->in_offset = old_offset;
 	tok->in_char_offset = old_char_offset;
@@ -232,5 +232,5 @@
 
 /** Append a char to the end of the current token */
-errno_t tok_push_char(tokenizer_t *tok, wchar_t ch)
+errno_t tok_push_char(tokenizer_t *tok, char32_t ch)
 {
 	return chr_encode(ch, tok->outbuf, &tok->outbuf_offset, tok->outbuf_size);
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/edit/edit.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -147,5 +147,5 @@
 static void pane_caret_display(void);
 
-static void insert_char(wchar_t c);
+static void insert_char(char32_t c);
 static void delete_char_before(void);
 static void delete_char_after(void);
@@ -630,5 +630,5 @@
 	kbd_event_t *kev;
 	char *str;
-	wchar_t buffer[INFNAME_MAX_LEN + 1];
+	char32_t buffer[INFNAME_MAX_LEN + 1];
 	int max_len;
 	int nc;
@@ -670,5 +670,5 @@
 				default:
 					if (kev->c >= 32 && nc < max_len) {
-						putwchar(kev->c);
+						putuchar(kev->c);
 						console_flush(con);
 						buffer[nc++] = kev->c;
@@ -696,5 +696,5 @@
 {
 	FILE *f;
-	wchar_t c;
+	char32_t c;
 	char buf[BUF_SIZE];
 	int bcnt;
@@ -850,5 +850,5 @@
 	coord_t rbc, rec;
 	char row_buf[ROW_BUF_SIZE];
-	wchar_t c;
+	char32_t c;
 	size_t pos, size;
 	int s_column;
@@ -1055,5 +1055,5 @@
 
 /** Insert a character at caret position. */
-static void insert_char(wchar_t c)
+static void insert_char(char32_t c)
 {
 	spt_t pt;
@@ -1285,5 +1285,5 @@
 
 /* Search operations */
-static errno_t search_spt_producer(void *data, wchar_t *ret)
+static errno_t search_spt_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1294,5 +1294,5 @@
 }
 
-static errno_t search_spt_reverse_producer(void *data, wchar_t *ret)
+static errno_t search_spt_reverse_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1513,5 +1513,5 @@
 	char *str;
 	size_t off;
-	wchar_t c;
+	char32_t c;
 	errno_t rc;
 
@@ -1609,5 +1609,5 @@
 }
 
-static wchar_t get_first_wchar(const char *str)
+static char32_t get_first_wchar(const char *str)
 {
 	size_t offset = 0;
@@ -1630,5 +1630,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ' ':
@@ -1656,5 +1656,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ',':
Index: uspace/app/edit/search.c
===================================================================
--- uspace/app/edit/search.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/edit/search.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -50,5 +50,5 @@
 		return NULL;
 
-	wchar_t *p = str_to_awstr(pattern);
+	char32_t *p = str_to_awstr(pattern);
 	if (p == NULL) {
 		free(search);
@@ -63,5 +63,5 @@
 		half = search->pattern_length / 2;
 		for (pos = 0; pos < half; pos++) {
-			wchar_t tmp = p[pos];
+			char32_t tmp = p[pos];
 			p[pos] = p[search->pattern_length - pos - 1];
 			p[search->pattern_length - pos - 1] = tmp;
@@ -107,5 +107,5 @@
 	search_equals_fn eq = s->ops.equals;
 
-	wchar_t cur_char;
+	char32_t cur_char;
 	errno_t rc = EOK;
 	while ((rc = s->ops.producer(s->client_data, &cur_char)) == EOK && cur_char > 0) {
@@ -141,5 +141,5 @@
 }
 
-bool char_exact_equals(const wchar_t a, const wchar_t b)
+bool char_exact_equals(const char32_t a, const char32_t b)
 {
 	return a == b;
Index: uspace/app/edit/search.h
===================================================================
--- uspace/app/edit/search.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/edit/search.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,6 +42,6 @@
 struct search;
 typedef struct search search_t;
-typedef bool (*search_equals_fn)(const wchar_t, const wchar_t);
-typedef errno_t (*search_producer_fn)(void *, wchar_t *);
+typedef bool (*search_equals_fn)(const char32_t, const char32_t);
+typedef errno_t (*search_producer_fn)(void *, char32_t *);
 typedef errno_t (*search_mark_fn)(void *, void **);
 typedef void (*search_mark_free_fn)(void *);
@@ -59,5 +59,5 @@
 } search_ops_t;
 
-extern bool char_exact_equals(const wchar_t, const wchar_t);
+extern bool char_exact_equals(const char32_t, const char32_t);
 extern search_t *search_init(const char *, void *, search_ops_t, bool);
 extern errno_t search_next_match(search_t *, match_t *);
Index: uspace/app/edit/search_impl.h
===================================================================
--- uspace/app/edit/search_impl.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/edit/search_impl.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 	/* Note: This structure is opaque for the user. */
 
-	wchar_t *pattern;
+	char32_t *pattern;
 	size_t pattern_length;
 	ssize_t *back_table;
Index: uspace/app/edit/sheet.c
===================================================================
--- uspace/app/edit/sheet.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/edit/sheet.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -195,5 +195,5 @@
 	size_t copy_sz;
 	size_t off, prev;
-	wchar_t c;
+	char32_t c;
 
 	spp = sh->data + spos->b_off;
@@ -222,5 +222,5 @@
 {
 	size_t cur_pos, prev_pos;
-	wchar_t c;
+	char32_t c;
 	coord_t cc;
 
@@ -291,5 +291,5 @@
 	size_t off;
 	coord_t cc;
-	wchar_t c;
+	char32_t c;
 	sheet_t *sh;
 
@@ -320,7 +320,7 @@
 
 /** Get a character at spt and return next spt */
-wchar_t spt_next_char(spt_t spt, spt_t *next)
-{
-	wchar_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_next_char(spt_t spt, spt_t *next)
+{
+	char32_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (next)
 		*next = spt;
@@ -328,7 +328,7 @@
 }
 
-wchar_t spt_prev_char(spt_t spt, spt_t *prev)
-{
-	wchar_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_prev_char(spt_t spt, spt_t *prev)
+{
+	char32_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (prev)
 		*prev = spt;
Index: uspace/app/edit/sheet.h
===================================================================
--- uspace/app/edit/sheet.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/edit/sheet.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -101,6 +101,6 @@
 extern void spt_get_coord(spt_t const *, coord_t *);
 extern bool spt_equal(spt_t const *, spt_t const *);
-extern wchar_t spt_next_char(spt_t, spt_t *);
-extern wchar_t spt_prev_char(spt_t, spt_t *);
+extern char32_t spt_next_char(spt_t, spt_t *);
+extern char32_t spt_prev_char(spt_t, spt_t *);
 
 extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/kio/kio.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -56,5 +56,5 @@
 	link_t link;
 	size_t length;
-	wchar_t *data;
+	char32_t *data;
 } item_t;
 
@@ -62,5 +62,5 @@
 
 /* Pointer to kio area */
-static wchar_t *kio = (wchar_t *) AS_AREA_ANY;
+static char32_t *kio = (char32_t *) AS_AREA_ANY;
 static size_t kio_length;
 
@@ -77,5 +77,5 @@
  *
  */
-static void producer(size_t length, wchar_t *data)
+static void producer(size_t length, char32_t *data)
 {
 	item_t *item = (item_t *) malloc(sizeof(item_t));
@@ -83,6 +83,6 @@
 		return;
 
-	size_t sz = sizeof(wchar_t) * length;
-	wchar_t *buf = (wchar_t *) malloc(sz);
+	size_t sz = sizeof(char32_t) * length;
+	char32_t *buf = (char32_t *) malloc(sz);
 	if (buf == NULL) {
 		free(item);
@@ -121,9 +121,9 @@
 
 		for (size_t i = 0; i < item->length; i++)
-			putwchar(item->data[i]);
+			putuchar(item->data[i]);
 
 		if (log != NULL) {
 			for (size_t i = 0; i < item->length; i++)
-				fputwc(item->data[i], log);
+				fputuc(item->data[i], log);
 
 			fflush(log);
@@ -202,5 +202,5 @@
 
 	size_t size = pages * PAGE_SIZE;
-	kio_length = size / sizeof(wchar_t);
+	kio_length = size / sizeof(char32_t);
 
 	rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/netecho/netecho.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -71,5 +71,5 @@
 }
 
-static void send_char(wchar_t c)
+static void send_char(char32_t c)
 {
 	char cbuf[STR_BOUNDS(1)];
Index: uspace/app/nterm/nterm.c
===================================================================
--- uspace/app/nterm/nterm.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/nterm/nterm.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -58,5 +58,5 @@
 }
 
-static void send_char(wchar_t c)
+static void send_char(char32_t c)
 {
 	char cbuf[STR_BOUNDS(1)];
Index: uspace/app/sbi/src/builtin/bi_char.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_char.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/sbi/src/builtin/bi_char.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -90,5 +90,5 @@
 	}
 
-	str = os_chr_to_astr((wchar_t) char_val);
+	str = os_chr_to_astr((char32_t) char_val);
 
 	/* Ownership of str is transferred. */
Index: uspace/app/sbi/src/os/helenos.c
===================================================================
--- uspace/app/sbi/src/os/helenos.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/sbi/src/os/helenos.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -94,5 +94,5 @@
 	size_t i;
 	size_t size;
-	wchar_t c;
+	char32_t c;
 
 	assert(start + length <= str_length(str));
@@ -155,5 +155,5 @@
 	size_t offset;
 	int i;
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	if (index < 0)
@@ -178,5 +178,5 @@
  * @return		Newly allocated string.
  */
-char *os_chr_to_astr(wchar_t chr)
+char *os_chr_to_astr(char32_t chr)
 {
 	char *str;
Index: uspace/app/sbi/src/os/os.h
===================================================================
--- uspace/app/sbi/src/os/os.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/sbi/src/os/os.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,5 +38,5 @@
 size_t os_str_length(const char *str);
 errno_t os_str_get_char(const char *str, int index, int *out_char);
-char *os_chr_to_astr(wchar_t chr);
+char *os_chr_to_astr(char32_t chr);
 void os_input_disp_help(void);
 errno_t os_input_line(const char *prompt, char **ptr);
Index: uspace/app/sbi/src/os/posix.c
===================================================================
--- uspace/app/sbi/src/os/posix.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/sbi/src/os/posix.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -164,5 +164,5 @@
  * @return		Newly allocated string.
  */
-char *os_chr_to_astr(wchar_t chr)
+char *os_chr_to_astr(char32_t chr)
 {
 	char *str;
Index: uspace/app/sysinfo/sysinfo.c
===================================================================
--- uspace/app/sysinfo/sysinfo.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/sysinfo/sysinfo.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -56,5 +56,5 @@
 
 	while (offset < size) {
-		wchar_t c = str_decode(data, &offset, size);
+		char32_t c = str_decode(data, &offset, size);
 		printf("%lc", (wint_t) c);
 	}
Index: uspace/app/tester/print/print4.c
===================================================================
--- uspace/app/tester/print/print4.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/tester/print/print4.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -29,5 +29,5 @@
 #include <stdio.h>
 #include <stddef.h>
-#include <wchar.h>
+#include <uchar.h>
 #include "../tester.h"
 
Index: uspace/app/tetris/scores.c
===================================================================
--- uspace/app/tetris/scores.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/tetris/scores.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -154,5 +154,5 @@
 		if (kev->key == KC_BACKSPACE) {
 			if (i > 0) {
-				wchar_t uc;
+				char32_t uc;
 
 				--i;
Index: uspace/app/tetris/screen.c
===================================================================
--- uspace/app/tetris/screen.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/tetris/screen.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -371,5 +371,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
@@ -393,5 +393,5 @@
 int twait(void)
 {
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/app/top/screen.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -551,5 +551,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/dist/src/c/demos/edit/edit.c
===================================================================
--- uspace/dist/src/c/demos/edit/edit.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/edit/edit.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -147,5 +147,5 @@
 static void pane_caret_display(void);
 
-static void insert_char(wchar_t c);
+static void insert_char(char32_t c);
 static void delete_char_before(void);
 static void delete_char_after(void);
@@ -630,5 +630,5 @@
 	kbd_event_t *kev;
 	char *str;
-	wchar_t buffer[INFNAME_MAX_LEN + 1];
+	char32_t buffer[INFNAME_MAX_LEN + 1];
 	int max_len;
 	int nc;
@@ -670,5 +670,5 @@
 				default:
 					if (kev->c >= 32 && nc < max_len) {
-						putwchar(kev->c);
+						putuchar(kev->c);
 						console_flush(con);
 						buffer[nc++] = kev->c;
@@ -696,5 +696,5 @@
 {
 	FILE *f;
-	wchar_t c;
+	char32_t c;
 	char buf[BUF_SIZE];
 	int bcnt;
@@ -847,5 +847,5 @@
 	coord_t rbc, rec;
 	char row_buf[ROW_BUF_SIZE];
-	wchar_t c;
+	char32_t c;
 	size_t pos, size;
 	int s_column;
@@ -1052,5 +1052,5 @@
 
 /** Insert a character at caret position. */
-static void insert_char(wchar_t c)
+static void insert_char(char32_t c)
 {
 	spt_t pt;
@@ -1282,5 +1282,5 @@
 
 /* Search operations */
-static errno_t search_spt_producer(void *data, wchar_t *ret)
+static errno_t search_spt_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1291,5 +1291,5 @@
 }
 
-static errno_t search_spt_reverse_producer(void *data, wchar_t *ret)
+static errno_t search_spt_reverse_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1510,5 +1510,5 @@
 	char *str;
 	size_t off;
-	wchar_t c;
+	char32_t c;
 	errno_t rc;
 
@@ -1606,5 +1606,5 @@
 }
 
-static wchar_t get_first_wchar(const char *str)
+static char32_t get_first_wchar(const char *str)
 {
 	size_t offset = 0;
@@ -1627,5 +1627,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ' ':
@@ -1653,5 +1653,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ',':
Index: uspace/dist/src/c/demos/edit/search.c
===================================================================
--- uspace/dist/src/c/demos/edit/search.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/edit/search.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -49,5 +49,5 @@
 		return NULL;
 
-	wchar_t *p = str_to_awstr(pattern);
+	char32_t *p = str_to_awstr(pattern);
 	if (p == NULL) {
 		free(search);
@@ -62,5 +62,5 @@
 		half = search->pattern_length / 2;
 		for (pos = 0; pos < half; pos++) {
-			wchar_t tmp = p[pos];
+			char32_t tmp = p[pos];
 			p[pos] = p[search->pattern_length - pos - 1];
 			p[search->pattern_length - pos - 1] = tmp;
@@ -106,5 +106,5 @@
 	search_equals_fn eq = s->ops.equals;
 
-	wchar_t cur_char;
+	char32_t cur_char;
 	errno_t rc = EOK;
 	while ((rc = s->ops.producer(s->client_data, &cur_char)) == EOK && cur_char > 0) {
@@ -140,5 +140,5 @@
 }
 
-bool char_exact_equals(const wchar_t a, const wchar_t b)
+bool char_exact_equals(const char32_t a, const char32_t b)
 {
 	return a == b;
Index: uspace/dist/src/c/demos/edit/search.h
===================================================================
--- uspace/dist/src/c/demos/edit/search.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/edit/search.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -41,6 +41,6 @@
 struct search;
 typedef struct search search_t;
-typedef bool (*search_equals_fn)(const wchar_t, const wchar_t);
-typedef errno_t (*search_producer_fn)(void *, wchar_t *);
+typedef bool (*search_equals_fn)(const char32_t, const char32_t);
+typedef errno_t (*search_producer_fn)(void *, char32_t *);
 typedef errno_t (*search_mark_fn)(void *, void **);
 typedef void (*search_mark_free_fn)(void *);
@@ -58,5 +58,5 @@
 } search_ops_t;
 
-extern bool char_exact_equals(const wchar_t, const wchar_t);
+extern bool char_exact_equals(const char32_t, const char32_t);
 extern search_t *search_init(const char *, void *, search_ops_t, bool);
 extern errno_t search_next_match(search_t *, match_t *);
Index: uspace/dist/src/c/demos/edit/search_impl.h
===================================================================
--- uspace/dist/src/c/demos/edit/search_impl.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/edit/search_impl.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 	/* Note: This structure is opaque for the user. */
 
-	const wchar_t *pattern;
+	const char32_t *pattern;
 	size_t pattern_length;
 	ssize_t *back_table;
Index: uspace/dist/src/c/demos/edit/sheet.c
===================================================================
--- uspace/dist/src/c/demos/edit/sheet.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/edit/sheet.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -193,5 +193,5 @@
 	size_t copy_sz;
 	size_t off, prev;
-	wchar_t c;
+	char32_t c;
 
 	spp = sh->data + spos->b_off;
@@ -220,5 +220,5 @@
 {
 	size_t cur_pos, prev_pos;
-	wchar_t c;
+	char32_t c;
 	coord_t cc;
 
@@ -289,5 +289,5 @@
 	size_t off;
 	coord_t cc;
-	wchar_t c;
+	char32_t c;
 	sheet_t *sh;
 
@@ -318,7 +318,7 @@
 
 /** Get a character at spt and return next spt */
-wchar_t spt_next_char(spt_t spt, spt_t *next)
-{
-	wchar_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_next_char(spt_t spt, spt_t *next)
+{
+	char32_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (next)
 		*next = spt;
@@ -326,7 +326,7 @@
 }
 
-wchar_t spt_prev_char(spt_t spt, spt_t *prev)
-{
-	wchar_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_prev_char(spt_t spt, spt_t *prev)
+{
+	char32_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (prev)
 		*prev = spt;
Index: uspace/dist/src/c/demos/edit/sheet.h
===================================================================
--- uspace/dist/src/c/demos/edit/sheet.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/edit/sheet.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -101,6 +101,6 @@
 extern void spt_get_coord(spt_t const *, coord_t *);
 extern bool spt_equal(spt_t const *, spt_t const *);
-extern wchar_t spt_next_char(spt_t, spt_t *);
-extern wchar_t spt_prev_char(spt_t, spt_t *);
+extern char32_t spt_next_char(spt_t, spt_t *);
+extern char32_t spt_prev_char(spt_t, spt_t *);
 
 extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
Index: uspace/dist/src/c/demos/tetris/scores.c
===================================================================
--- uspace/dist/src/c/demos/tetris/scores.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/tetris/scores.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -155,5 +155,5 @@
 		if (kev->key == KC_BACKSPACE) {
 			if (i > 0) {
-				wchar_t uc;
+				char32_t uc;
 
 				--i;
Index: uspace/dist/src/c/demos/tetris/screen.c
===================================================================
--- uspace/dist/src/c/demos/tetris/screen.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/tetris/screen.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -371,5 +371,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
@@ -393,5 +393,5 @@
 errno_t twait(void)
 {
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/dist/src/c/demos/top/screen.c
===================================================================
--- uspace/dist/src/c/demos/top/screen.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/dist/src/c/demos/top/screen.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -553,5 +553,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/lib/bithenge/src/helenos/common.h
===================================================================
--- uspace/lib/bithenge/src/helenos/common.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/bithenge/src/helenos/common.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -47,5 +47,5 @@
 	const char *string;
 	size_t offset;
-	wchar_t ch;
+	char32_t ch;
 } string_iterator_t;
 
@@ -64,5 +64,5 @@
 }
 
-static inline errno_t string_iterator_next(string_iterator_t *i, wchar_t *out)
+static inline errno_t string_iterator_next(string_iterator_t *i, char32_t *out)
 {
 	*out = i->ch;
Index: uspace/lib/bithenge/src/linux/common.h
===================================================================
--- uspace/lib/bithenge/src/linux/common.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/bithenge/src/linux/common.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -37,5 +37,5 @@
 #include <stdlib.h>
 #include <string.h>
-#include <wchar.h>
+#include <uchar.h>
 
 #define max(aleph, bet) ((aleph) > (bet) ? (aleph) : (bet))
@@ -55,8 +55,8 @@
 }
 
-static inline errno_t string_iterator_next(string_iterator_t *i, wchar_t *out)
+static inline errno_t string_iterator_next(string_iterator_t *i, char32_t *out)
 {
 	wint_t rc = btowc(*(*i)++); // TODO
-	*out = (wchar_t) rc;
+	*out = (char32_t) rc;
 	return rc == WEOF ? EILSEQ : EOK;
 }
@@ -72,5 +72,5 @@
 }
 
-static inline const char *str_chr(const char *string, wchar_t ch)
+static inline const char *str_chr(const char *string, char32_t ch)
 {
 	return strchr(string, wctob(ch)); // TODO
Index: uspace/lib/bithenge/src/print.c
===================================================================
--- uspace/lib/bithenge/src/print.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/bithenge/src/print.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -40,5 +40,5 @@
 #include <stdarg.h>
 #include <stdio.h>
-#include <wchar.h>
+#include <uchar.h>
 #include <bithenge/blob.h>
 #include <bithenge/print.h>
@@ -164,5 +164,5 @@
 	string_iterator_t i = string_iterator(value);
 	while (!string_iterator_done(&i)) {
-		wchar_t ch;
+		char32_t ch;
 		errno_t rc = string_iterator_next(&i, &ch);
 		if (rc != EOK)
Index: uspace/lib/c/generic/io/asprintf.c
===================================================================
--- uspace/lib/c/generic/io/asprintf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/asprintf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -46,5 +46,5 @@
 }
 
-static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused)
+static int asprintf_wstr_write(const char32_t *str, size_t count, void *unused)
 {
 	return wstr_nlength(str, count);
Index: uspace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/chargrid.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -140,5 +140,5 @@
  *
  */
-sysarg_t chargrid_putwchar(chargrid_t *scrbuf, wchar_t ch, bool update)
+sysarg_t chargrid_putuchar(chargrid_t *scrbuf, char32_t ch, bool update)
 {
 	assert(scrbuf->col < scrbuf->cols);
@@ -199,5 +199,5 @@
 
 	for (sysarg_t i = 0; i < spaces; i++)
-		flush += chargrid_putwchar(scrbuf, ' ', true) - 1;
+		flush += chargrid_putuchar(scrbuf, ' ', true) - 1;
 
 	return flush;
@@ -228,10 +228,10 @@
 		scrbuf->row--;
 
-		chargrid_putwchar(scrbuf, ' ', false);
+		chargrid_putuchar(scrbuf, ' ', false);
 		return 2;
 	}
 
 	scrbuf->col--;
-	chargrid_putwchar(scrbuf, ' ', false);
+	chargrid_putuchar(scrbuf, ' ', false);
 	return 1;
 }
Index: uspace/lib/c/generic/io/input.c
===================================================================
--- uspace/lib/c/generic/io/input.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/input.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -109,5 +109,5 @@
 	keycode_t key;
 	keymod_t mods;
-	wchar_t c;
+	char32_t c;
 	errno_t rc;
 
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/io.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -48,4 +48,5 @@
 #include <adt/list.h>
 #include <wchar.h>
+#include <uchar.h>
 #include "../private/io.h"
 #include "../private/stdio.h"
@@ -749,7 +750,29 @@
 }
 
+wint_t fputuc(char32_t wc, FILE *stream)
+{
+	char buf[STR_BOUNDS(1)];
+	size_t sz = 0;
+
+	if (chr_encode(wc, buf, &sz, STR_BOUNDS(1)) != EOK) {
+		errno = EILSEQ;
+		return WEOF;
+	}
+
+	size_t wr = fwrite(buf, 1, sz, stream);
+	if (wr < sz)
+		return WEOF;
+
+	return wc;
+}
+
 wint_t putwchar(wchar_t wc)
 {
 	return fputwc(wc, stdout);
+}
+
+wint_t putuchar(char32_t wc)
+{
+	return fputuc(wc, stdout);
 }
 
Index: uspace/lib/c/generic/io/kio.c
===================================================================
--- uspace/lib/c/generic/io/kio.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/kio.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -140,5 +140,5 @@
 }
 
-static int kio_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+static int kio_vprintf_wstr_write(const char32_t *str, size_t size, void *data)
 {
 	size_t offset = 0;
@@ -154,5 +154,5 @@
 
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
Index: uspace/lib/c/generic/io/printf_core.c
===================================================================
--- uspace/lib/c/generic/io/printf_core.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/printf_core.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -47,5 +47,5 @@
 #include <assert.h>
 #include <macros.h>
-#include <wchar.h>
+#include <uchar.h>
 
 /** show prefixes 0x or 0 */
@@ -187,5 +187,5 @@
  *
  */
-static int printf_wputnchars(const wchar_t *buf, size_t size,
+static int printf_wputnchars(const char32_t *buf, size_t size,
     printf_spec_t *ps)
 {
@@ -233,10 +233,10 @@
  *
  */
-static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
+static int printf_putuchar(const char32_t ch, printf_spec_t *ps)
 {
 	if (!chr_check(ch))
 		return ps->str_write((void *) &invalch, 1, ps->data);
 
-	return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
+	return ps->wstr_write(&ch, sizeof(char32_t), ps->data);
 }
 
@@ -288,5 +288,5 @@
  *
  */
-static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
+static int print_wchar(const char32_t ch, int width, uint32_t flags, printf_spec_t *ps)
 {
 	size_t counter = 0;
@@ -302,5 +302,5 @@
 	}
 
-	if (printf_putwchar(ch, ps) > 0)
+	if (printf_putuchar(ch, ps) > 0)
 		counter++;
 
@@ -375,5 +375,5 @@
  * @return Number of wide characters printed, negative value on failure.
  */
-static int print_wstr(wchar_t *str, int width, unsigned int precision,
+static int print_wstr(char32_t *str, int width, unsigned int precision,
     uint32_t flags, printf_spec_t *ps)
 {
@@ -1276,5 +1276,5 @@
  *  - "l"  Signed or unsigned long int.@n
  *         If conversion is "c", the character is wint_t (wide character).@n
- *         If conversion is "s", the string is wchar_t * (wide string).@n
+ *         If conversion is "s", the string is char32_t * (wide string).@n
  *  - "ll" Signed or unsigned long long int.@n
  *  - "z"  Signed or unsigned ssize_t or site_t.@n
@@ -1330,5 +1330,5 @@
 	while (true) {
 		i = nxt;
-		wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+		char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
 
 		if (uc == 0)
@@ -1493,5 +1493,5 @@
 
 				if (qualifier == PrintfQualifierLong)
-					retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
+					retval = print_wstr(va_arg(ap, char32_t *), width, precision, flags, ps);
 				else
 					retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
Index: uspace/lib/c/generic/io/vprintf.c
===================================================================
--- uspace/lib/c/generic/io/vprintf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/vprintf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -48,5 +48,5 @@
 }
 
-static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream)
+static int vprintf_wstr_write(const char32_t *str, size_t size, void *stream)
 {
 	size_t offset = 0;
@@ -54,9 +54,9 @@
 
 	while (offset < size) {
-		if (fputwc(str[chars], (FILE *) stream) <= 0)
+		if (fputuc(str[chars], (FILE *) stream) <= 0)
 			break;
 
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
Index: uspace/lib/c/generic/io/vsnprintf.c
===================================================================
--- uspace/lib/c/generic/io/vsnprintf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/io/vsnprintf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -88,5 +88,5 @@
 
 		while (index < size) {
-			wchar_t uc = str_decode(str, &index, size);
+			char32_t uc = str_decode(str, &index, size);
 
 			if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
@@ -133,9 +133,9 @@
  *
  */
-static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
+static int vsnprintf_wstr_write(const char32_t *str, size_t size, vsnprintf_data_t *data)
 {
 	size_t index = 0;
 
-	while (index < (size / sizeof(wchar_t))) {
+	while (index < (size / sizeof(char32_t))) {
 		size_t left = data->size - data->len;
 
@@ -177,5 +177,5 @@
 	printf_spec_t ps = {
 		(int (*) (const char *, size_t, void *)) vsnprintf_str_write,
-		(int (*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
+		(int (*) (const char32_t *, size_t, void *)) vsnprintf_wstr_write,
 		&data
 	};
Index: uspace/lib/c/generic/stdio/sstream.c
===================================================================
--- uspace/lib/c/generic/stdio/sstream.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/stdio/sstream.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -37,5 +37,5 @@
 #include <errno.h>
 #include <adt/list.h>
-#include <wchar.h>
+#include <uchar.h>
 #include "../private/stdio.h"
 #include "../private/sstream.h"
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/generic/str.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
  * strings, called just strings are encoded in UTF-8. Wide strings (encoded
  * in UTF-32) are supported to a limited degree. A single character is
- * represented as wchar_t.@n
+ * represented as char32_t.@n
  *
  * Overview of the terminology:@n
@@ -50,6 +50,6 @@
  *  byte                  8 bits stored in uint8_t (unsigned 8 bit integer)
  *
- *  character             UTF-32 encoded Unicode character, stored in wchar_t
- *                        (signed 32 bit integer), code points 0 .. 1114111
+ *  character             UTF-32 encoded Unicode character, stored in char32_t
+ *                        (unsigned 32 bit integer), code points 0 .. 1114111
  *                        are valid
  *
@@ -61,5 +61,5 @@
  *
  *  wide string           UTF-32 encoded NULL-terminated Unicode string,
- *                        wchar_t *
+ *                        char32_t *
  *
  *  [wide] string size    number of BYTES in a [wide] string (excluding
@@ -100,5 +100,5 @@
  * A specific character inside a [wide] string can be referred to by:@n
  *
- *  pointer (char *, wchar_t *)
+ *  pointer (char *, char32_t *)
  *  byte offset (size_t)
  *  character index (size_t)
@@ -119,11 +119,4 @@
 #include <mem.h>
 
-/** Check the condition if wchar_t is signed */
-#ifdef __WCHAR_UNSIGNED__
-#define WCHAR_SIGNED_CHECK(cond)  (true)
-#else
-#define WCHAR_SIGNED_CHECK(cond)  (cond)
-#endif
-
 /** Byte mask consisting of lowest @n bits (out of 8) */
 #define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
@@ -153,5 +146,5 @@
  *
  */
-wchar_t str_decode(const char *str, size_t *offset, size_t size)
+char32_t str_decode(const char *str, size_t *offset, size_t size)
 {
 	if (*offset + 1 > size)
@@ -190,5 +183,5 @@
 		return U_SPECIAL;
 
-	wchar_t ch = b0 & LO_MASK_8(b0_bits);
+	char32_t ch = b0 & LO_MASK_8(b0_bits);
 
 	/* Decode continuation bytes */
@@ -201,5 +194,5 @@
 
 		/* Shift data bits to ch */
-		ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+		ch = (ch << CONT_BITS) | (char32_t) (b & LO_MASK_8(CONT_BITS));
 		cbytes--;
 	}
@@ -223,5 +216,5 @@
  *
  */
-wchar_t str_decode_reverse(const char *str, size_t *offset, size_t size)
+char32_t str_decode_reverse(const char *str, size_t *offset, size_t size)
 {
 	if (*offset == 0)
@@ -266,5 +259,5 @@
  *         code was invalid.
  */
-errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const char32_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -352,7 +345,7 @@
  *
  */
-size_t wstr_size(const wchar_t *str)
-{
-	return (wstr_length(str) * sizeof(wchar_t));
+size_t wstr_size(const char32_t *str)
+{
+	return (wstr_length(str) * sizeof(char32_t));
 }
 
@@ -417,7 +410,7 @@
  *
  */
-size_t wstr_nsize(const wchar_t *str, size_t max_size)
-{
-	return (wstr_nlength(str, max_size) * sizeof(wchar_t));
+size_t wstr_nsize(const char32_t *str, size_t max_size)
+{
+	return (wstr_nlength(str, max_size) * sizeof(char32_t));
 }
 
@@ -435,7 +428,7 @@
  *
  */
-size_t wstr_lsize(const wchar_t *str, size_t max_len)
-{
-	return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
+size_t wstr_lsize(const char32_t *str, size_t max_len)
+{
+	return (wstr_nlength(str, max_len * sizeof(char32_t)) * sizeof(char32_t));
 }
 
@@ -465,5 +458,5 @@
  *
  */
-size_t wstr_length(const wchar_t *wstr)
+size_t wstr_length(const char32_t *wstr)
 {
 	size_t len = 0;
@@ -502,13 +495,13 @@
  *
  */
-size_t wstr_nlength(const wchar_t *str, size_t size)
+size_t wstr_nlength(const char32_t *str, size_t size)
 {
 	size_t len = 0;
-	size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
+	size_t limit = ALIGN_DOWN(size, sizeof(char32_t));
 	size_t offset = 0;
 
 	while ((offset < limit) && (*str++ != 0)) {
 		len++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
@@ -521,5 +514,5 @@
  * @return	Width of character in cells.
  */
-size_t chr_width(wchar_t ch)
+size_t chr_width(char32_t ch)
 {
 	return 1;
@@ -535,5 +528,5 @@
 	size_t width = 0;
 	size_t offset = 0;
-	wchar_t ch;
+	char32_t ch;
 
 	while ((ch = str_decode(str, &offset, STR_NO_LIMIT)) != 0)
@@ -548,7 +541,7 @@
  *
  */
-bool ascii_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+bool ascii_check(char32_t ch)
+{
+	if (ch <= 127)
 		return true;
 
@@ -561,7 +554,7 @@
  *
  */
-bool chr_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+bool chr_check(char32_t ch)
+{
+	if (ch <= 1114111)
 		return true;
 
@@ -589,6 +582,6 @@
 int str_cmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -636,6 +629,6 @@
 int str_lcmp(const char *s1, const char *s2, size_t max_len)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -688,6 +681,6 @@
 int str_casecmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -736,6 +729,6 @@
 int str_lcasecmp(const char *s1, const char *s2, size_t max_len)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -780,6 +773,6 @@
 bool str_test_prefix(const char *s, const char *p)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -850,5 +843,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -883,5 +876,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, n)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -987,7 +980,7 @@
  * @param src	Source wide string.
  */
-void wstr_to_str(char *dest, size_t size, const wchar_t *src)
-{
-	wchar_t ch;
+void wstr_to_str(char *dest, size_t size, const char32_t *src)
+{
+	char32_t ch;
 	size_t src_idx;
 	size_t dest_off;
@@ -1022,5 +1015,5 @@
 {
 	size_t idx = 0, dest_off = 0;
-	wchar_t ch;
+	char32_t ch;
 	errno_t rc = EOK;
 
@@ -1066,5 +1059,5 @@
 	size_t offset = 0;
 	size_t idx = 0;
-	wchar_t c;
+	char32_t c;
 
 	assert(dlen > 0);
@@ -1123,9 +1116,9 @@
  * @return	New string.
  */
-char *wstr_to_astr(const wchar_t *src)
+char *wstr_to_astr(const char32_t *src)
 {
 	char dbuf[STR_BOUNDS(1)];
 	char *str;
-	wchar_t ch;
+	char32_t ch;
 
 	size_t src_idx;
@@ -1173,9 +1166,9 @@
  * @param src	Source string.
  */
-void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
+void str_to_wstr(char32_t *dest, size_t dlen, const char *src)
 {
 	size_t offset;
 	size_t di;
-	wchar_t c;
+	char32_t c;
 
 	assert(dlen > 0);
@@ -1202,9 +1195,9 @@
  * @param src	Source string.
  */
-wchar_t *str_to_awstr(const char *str)
+char32_t *str_to_awstr(const char *str)
 {
 	size_t len = str_length(str);
 
-	wchar_t *wstr = calloc(len + 1, sizeof(wchar_t));
+	char32_t *wstr = calloc(len + 1, sizeof(char32_t));
 	if (wstr == NULL)
 		return NULL;
@@ -1221,7 +1214,7 @@
  * @return Pointer to character in @a str or NULL if not found.
  */
-char *str_chr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
+char *str_chr(const char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t last = 0;
@@ -1263,9 +1256,9 @@
  * @param ch  Character to remove.
  */
-void str_rtrim(char *str, wchar_t ch)
+void str_rtrim(char *str, char32_t ch)
 {
 	size_t off = 0;
 	size_t pos = 0;
-	wchar_t c;
+	char32_t c;
 	bool update_last_chunk = true;
 	char *last_chunk = NULL;
@@ -1291,7 +1284,7 @@
  * @param ch  Character to remove.
  */
-void str_ltrim(char *str, wchar_t ch)
-{
-	wchar_t acc;
+void str_ltrim(char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t pos = 0;
@@ -1319,7 +1312,7 @@
  * @return Pointer to character in @a str or NULL if not found.
  */
-char *str_rchr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
+char *str_rchr(const char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t last = 0;
@@ -1349,5 +1342,5 @@
  *
  */
-bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
+bool wstr_linsert(char32_t *str, char32_t ch, size_t pos, size_t max_pos)
 {
 	size_t len = wstr_length(str);
@@ -1377,5 +1370,5 @@
  *
  */
-bool wstr_remove(wchar_t *str, size_t pos)
+bool wstr_remove(char32_t *str, size_t pos)
 {
 	size_t len = wstr_length(str);
@@ -1474,5 +1467,5 @@
 	size_t cur;
 	size_t tmp;
-	wchar_t ch;
+	char32_t ch;
 
 	/* Skip over leading delimiters. */
Index: uspace/lib/c/include/io/charfield.h
===================================================================
--- uspace/lib/c/include/io/charfield.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/io/charfield.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,5 +38,5 @@
 
 #include <stdbool.h>
-#include <wchar.h>
+#include <uchar.h>
 #include <io/color.h>
 #include <io/style.h>
@@ -77,5 +77,5 @@
 
 typedef struct {
-	wchar_t ch;
+	char32_t ch;
 	char_attrs_t attrs;
 	char_flags_t flags;
Index: uspace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/io/chargrid.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -79,5 +79,5 @@
 extern sysarg_t chargrid_get_top_row(chargrid_t *);
 
-extern sysarg_t chargrid_putwchar(chargrid_t *, wchar_t, bool);
+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);
Index: uspace/lib/c/include/io/input.h
===================================================================
--- uspace/lib/c/include/io/input.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/io/input.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -50,5 +50,5 @@
 	errno_t (*active)(input_t *);
 	errno_t (*deactive)(input_t *);
-	errno_t (*key)(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
+	errno_t (*key)(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
 	errno_t (*move)(input_t *, int, int);
 	errno_t (*abs_move)(input_t *, unsigned, unsigned, unsigned, unsigned);
Index: uspace/lib/c/include/io/kbd_event.h
===================================================================
--- uspace/lib/c/include/io/kbd_event.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/io/kbd_event.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -59,5 +59,5 @@
 
 	/** The character that was generated or '\0' for none. */
-	wchar_t c;
+	char32_t c;
 } kbd_event_t;
 
Index: uspace/lib/c/include/io/printf_core.h
===================================================================
--- uspace/lib/c/include/io/printf_core.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/io/printf_core.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,4 +38,5 @@
 #include <stddef.h>
 #include <stdarg.h>
+#include <uchar.h>
 
 /** Structure for specifying output methods for different printf clones. */
@@ -45,5 +46,5 @@
 
 	/* Wide string output function, returns number of printed characters or EOF */
-	int (*wstr_write)(const wchar_t *, size_t, void *);
+	int (*wstr_write)(const char32_t *, size_t, void *);
 
 	/* User data - output stream specification, state, locks, etc. */
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/stdio.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,4 +42,5 @@
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/uchar.h>
 #include <_bits/wint_t.h>
 #include <_bits/decls.h>
@@ -123,4 +124,7 @@
 extern wint_t fputwc(wchar_t, FILE *);
 extern wint_t putwchar(wchar_t);
+
+extern wint_t fputuc(char32_t, FILE *);
+extern wint_t putuchar(char32_t);
 
 /* Formatted string output functions */
Index: uspace/lib/c/include/stdlib.h
===================================================================
--- uspace/lib/c/include/stdlib.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/stdlib.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -38,4 +38,5 @@
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/uchar.h>
 #include <_bits/decls.h>
 #include <bsearch.h>
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/include/str.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -67,28 +67,28 @@
 __HELENOS_DECLS_BEGIN;
 
-extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
-extern wchar_t str_decode_reverse(const char *str, size_t *offset, size_t sz);
-extern errno_t chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
+extern char32_t str_decode(const char *str, size_t *offset, size_t sz);
+extern char32_t str_decode_reverse(const char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(char32_t ch, char *str, size_t *offset, size_t sz);
 
 extern size_t str_size(const char *str);
-extern size_t wstr_size(const wchar_t *str);
+extern size_t wstr_size(const char32_t *str);
 
 extern size_t str_nsize(const char *str, size_t max_size);
-extern size_t wstr_nsize(const wchar_t *str, size_t max_size);
+extern size_t wstr_nsize(const char32_t *str, size_t max_size);
 
 extern size_t str_lsize(const char *str, size_t max_len);
-extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
+extern size_t wstr_lsize(const char32_t *str, size_t max_len);
 
 extern size_t str_length(const char *str);
-extern size_t wstr_length(const wchar_t *wstr);
+extern size_t wstr_length(const char32_t *wstr);
 
 extern size_t str_nlength(const char *str, size_t size);
-extern size_t wstr_nlength(const wchar_t *str, size_t size);
+extern size_t wstr_nlength(const char32_t *str, size_t size);
 
-extern size_t chr_width(wchar_t ch);
+extern size_t chr_width(char32_t ch);
 extern size_t str_width(const char *str);
 
-extern bool ascii_check(wchar_t ch);
-extern bool chr_check(wchar_t ch);
+extern bool ascii_check(char32_t ch);
+extern bool chr_check(char32_t ch);
 
 extern int str_cmp(const char *s1, const char *s2);
@@ -105,21 +105,21 @@
 
 extern errno_t spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
-extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
-extern char *wstr_to_astr(const wchar_t *src);
-extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
-extern wchar_t *str_to_awstr(const char *src);
+extern void wstr_to_str(char *dest, size_t size, const char32_t *src);
+extern char *wstr_to_astr(const char32_t *src);
+extern void str_to_wstr(char32_t *dest, size_t dlen, const char *src);
+extern char32_t *str_to_awstr(const char *src);
 extern errno_t utf16_to_str(char *dest, size_t size, const uint16_t *src);
 extern errno_t str_to_utf16(uint16_t *dest, size_t dlen, const char *src);
 extern size_t utf16_wsize(const uint16_t *ustr);
 
-extern char *str_chr(const char *str, wchar_t ch);
-extern char *str_rchr(const char *str, wchar_t ch);
+extern char *str_chr(const char *str, char32_t ch);
+extern char *str_rchr(const char *str, char32_t ch);
 extern char *str_str(const char *hs, const char *n);
 
-extern void str_rtrim(char *str, wchar_t ch);
-extern void str_ltrim(char *str, wchar_t ch);
+extern void str_rtrim(char *str, char32_t ch);
+extern void str_ltrim(char *str, char32_t ch);
 
-extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
-extern bool wstr_remove(wchar_t *str, size_t pos);
+extern bool wstr_linsert(char32_t *str, char32_t ch, size_t pos, size_t max_pos);
+extern bool wstr_remove(char32_t *str, size_t pos);
 
 extern char *str_dup(const char *src);
Index: uspace/lib/c/include/uchar.h
===================================================================
--- uspace/lib/c/include/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
+++ uspace/lib/c/include/uchar.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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_UCHAR_H_
+#define _LIBC_UCHAR_H_
+
+#include <_bits/uchar.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/test/stdlib.c
===================================================================
--- uspace/lib/c/test/stdlib.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/c/test/stdlib.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -48,6 +48,6 @@
 	(void) sz;
 
-	/* Make sure wchar_t is defined */
-	wchar_t wc = L'\0';
+	/* Make sure char32_t is defined */
+	char32_t wc = L'\0';
 	(void) wc;
 
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/clui/tinput.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -113,5 +113,5 @@
 static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad)
 {
-	wchar_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(wchar_t));
+	char32_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(char32_t));
 	if (!dbuf)
 		return;
@@ -126,5 +126,5 @@
 	size_t p = start;
 	if (p < sa) {
-		memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t));
+		memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(char32_t));
 		dbuf[sa - p] = '\0';
 		printf("%ls", dbuf);
@@ -137,5 +137,5 @@
 
 		memcpy(dbuf, ti->buffer + p,
-		    (sb - p) * sizeof(wchar_t));
+		    (sb - p) * sizeof(char32_t));
 		dbuf[sb - p] = '\0';
 		printf("%ls", dbuf);
@@ -148,5 +148,5 @@
 	if (p < ti->nc) {
 		memcpy(dbuf, ti->buffer + p,
-		    (ti->nc - p) * sizeof(wchar_t));
+		    (ti->nc - p) * sizeof(char32_t));
 		dbuf[ti->nc - p] = '\0';
 		printf("%ls", dbuf);
@@ -154,5 +154,5 @@
 
 	for (p = 0; p < pad; p++)
-		putwchar(' ');
+		putuchar(' ');
 
 	console_flush(ti->console);
@@ -192,5 +192,5 @@
 	tinput_console_set_lpos(ti, ti->text_coord + ti->nc);
 	console_flush(ti->console);
-	putwchar('\n');
+	putuchar('\n');
 }
 
@@ -212,5 +212,5 @@
 }
 
-static void tinput_insert_char(tinput_t *ti, wchar_t c)
+static void tinput_insert_char(tinput_t *ti, char32_t c)
 {
 	if (ti->nc == INPUT_MAX_SIZE)
@@ -263,5 +263,5 @@
 	size_t i = 0;
 	while (i < ilen) {
-		wchar_t c = str_decode(str, &off, STR_NO_LIMIT);
+		char32_t c = str_decode(str, &off, STR_NO_LIMIT);
 		if (c == '\0')
 			break;
@@ -506,5 +506,5 @@
 
 	memmove(ti->buffer + sa, ti->buffer + sb,
-	    (ti->nc - sb) * sizeof(wchar_t));
+	    (ti->nc - sb) * sizeof(char32_t));
 
 	ti->pos = ti->sel_start = sa;
@@ -526,5 +526,5 @@
 
 	if (sb < ti->nc) {
-		wchar_t tmp_c = ti->buffer[sb];
+		char32_t tmp_c = ti->buffer[sb];
 		ti->buffer[sb] = '\0';
 		str = wstr_to_astr(ti->buffer + sa);
@@ -602,5 +602,5 @@
 	size_t i;
 	size_t a_off, b_off;
-	wchar_t ca, cb;
+	char32_t ca, cb;
 
 	i = 0;
Index: uspace/lib/clui/tinput.h
===================================================================
--- uspace/lib/clui/tinput.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/clui/tinput.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -63,5 +63,5 @@
  * @return		EOK on success, error code on failure.
  */
-typedef errno_t (*tinput_compl_init_fn)(wchar_t *text, size_t pos, size_t *cstart,
+typedef errno_t (*tinput_compl_init_fn)(char32_t *text, size_t pos, size_t *cstart,
     void **state);
 
@@ -111,5 +111,5 @@
 
 	/** Buffer holding text currently being edited */
-	wchar_t buffer[INPUT_MAX_SIZE + 1];
+	char32_t buffer[INPUT_MAX_SIZE + 1];
 
 	/** Linear position on screen where the prompt starts */
Index: uspace/lib/draw/font.c
===================================================================
--- uspace/lib/draw/font.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/font.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -64,5 +64,5 @@
 }
 
-errno_t font_resolve_glyph(font_t *font, wchar_t c, glyph_id_t *glyph_id)
+errno_t font_resolve_glyph(font_t *font, char32_t c, glyph_id_t *glyph_id)
 {
 	return font->backend->resolve_glyph(font->backend_data, c, glyph_id);
@@ -95,5 +95,5 @@
 	size_t off = 0;
 	while (true) {
-		wchar_t c = str_decode(text, &off, STR_NO_LIMIT);
+		char32_t c = str_decode(text, &off, STR_NO_LIMIT);
 		if (c == 0)
 			break;
@@ -138,5 +138,5 @@
 	size_t off = 0;
 	while (true) {
-		wchar_t c = str_decode(text, &off, STR_NO_LIMIT);
+		char32_t c = str_decode(text, &off, STR_NO_LIMIT);
 		if (c == 0)
 			break;
Index: uspace/lib/draw/font/bitmap_backend.c
===================================================================
--- uspace/lib/draw/font/bitmap_backend.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/font/bitmap_backend.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -67,5 +67,5 @@
 }
 
-static errno_t bb_resolve_glyph(void *backend_data, wchar_t c, glyph_id_t *glyph_id)
+static errno_t bb_resolve_glyph(void *backend_data, char32_t c, glyph_id_t *glyph_id)
 {
 	bitmap_backend_data_t *data = (bitmap_backend_data_t *) backend_data;
Index: uspace/lib/draw/font/embedded.c
===================================================================
--- uspace/lib/draw/font/embedded.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/font/embedded.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 #include <draw/drawctx.h>
 
-static errno_t fde_resolve_glyph(void *unused, const wchar_t chr,
+static errno_t fde_resolve_glyph(void *unused, const char32_t chr,
     glyph_id_t *glyph_id)
 {
Index: uspace/lib/draw/font/pcf.c
===================================================================
--- uspace/lib/draw/font/pcf.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/font/pcf.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -143,5 +143,5 @@
 }
 
-static errno_t pcf_resolve_glyph(void *opaque_data, const wchar_t chr,
+static errno_t pcf_resolve_glyph(void *opaque_data, const char32_t chr,
     glyph_id_t *glyph_id)
 {
Index: uspace/lib/draw/gfx/font-8x16.c
===================================================================
--- uspace/lib/draw/gfx/font-8x16.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/gfx/font-8x16.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -47,5 +47,5 @@
  *
  */
-uint16_t fb_font_glyph(const wchar_t ch, bool *found)
+uint16_t fb_font_glyph(const char32_t ch, bool *found)
 {
 	if (found)
Index: uspace/lib/draw/include/draw/font.h
===================================================================
--- uspace/lib/draw/include/draw/font.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/include/draw/font.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -97,5 +97,5 @@
 typedef struct {
 	errno_t (*get_font_metrics)(void *, font_metrics_t *);
-	errno_t (*resolve_glyph)(void *, wchar_t, glyph_id_t *);
+	errno_t (*resolve_glyph)(void *, char32_t, glyph_id_t *);
 	errno_t (*get_glyph_metrics)(void *, glyph_id_t, glyph_metrics_t *);
 	errno_t (*render_glyph)(void *, drawctx_t *, source_t *, sysarg_t,
@@ -110,5 +110,5 @@
 
 typedef struct {
-	errno_t (*resolve_glyph)(void *, const wchar_t, glyph_id_t *);
+	errno_t (*resolve_glyph)(void *, const char32_t, glyph_id_t *);
 	errno_t (*load_glyph_surface)(void *, glyph_id_t, surface_t **);
 	errno_t (*load_glyph_metrics)(void *, glyph_id_t, glyph_metrics_t *);
@@ -118,5 +118,5 @@
 extern font_t *font_create(font_backend_t *, void *);
 extern errno_t font_get_metrics(font_t *, font_metrics_t *);
-extern errno_t font_resolve_glyph(font_t *, wchar_t, glyph_id_t *);
+extern errno_t font_resolve_glyph(font_t *, char32_t, glyph_id_t *);
 extern errno_t font_get_glyph_metrics(font_t *, glyph_id_t, glyph_metrics_t *);
 extern errno_t font_render_glyph(font_t *, drawctx_t *, source_t *,
Index: uspace/lib/draw/include/draw/gfx.h
===================================================================
--- uspace/lib/draw/include/draw/gfx.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/draw/include/draw/gfx.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -40,4 +40,5 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <uchar.h>
 
 #define CURSOR_WIDTH   11
@@ -52,5 +53,5 @@
 extern uint8_t cursor_mask[];
 
-extern uint16_t fb_font_glyph(const wchar_t, bool *);
+extern uint16_t fb_font_glyph(const char32_t, bool *);
 extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
Index: uspace/lib/ext4/src/superblock.c
===================================================================
--- uspace/lib/ext4/src/superblock.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/ext4/src/superblock.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -889,5 +889,5 @@
 	size_t i;
 	size_t wi;
-	wchar_t ch;
+	char32_t ch;
 	errno_t rc;
 
@@ -896,5 +896,5 @@
 	while (sb->volume_name[i] != '\0' && i < sizeof(sb->volume_name)) {
 		/* ISO 8859-1 codes map to identical Unicode code points */
-		ch = (wchar_t)(uint8_t)sb->volume_name[i];
+		ch = (char32_t)(uint8_t)sb->volume_name[i];
 		rc = chr_encode(ch, buf, &wi, bufsz - 1);
 		if (rc != EOK)
@@ -917,5 +917,5 @@
 {
 	size_t off;
-	wchar_t ch;
+	char32_t ch;
 	size_t wi;
 
Index: uspace/lib/fmtutil/fmtutil.c
===================================================================
--- uspace/lib/fmtutil/fmtutil.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/fmtutil/fmtutil.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -62,8 +62,8 @@
 
 /** Line consumer that prints the lines aligned according to spec */
-static errno_t print_line(wchar_t *wstr, size_t chars, bool last, void *data)
+static errno_t print_line(char32_t *wstr, size_t chars, bool last, void *data)
 {
 	printmode_t *pm = (printmode_t *) data;
-	wchar_t old_char = wstr[chars];
+	char32_t old_char = wstr[chars];
 	wstr[chars] = 0;
 	errno_t rc = print_aligned_w(wstr, pm->width, last, pm->alignment);
@@ -78,5 +78,5 @@
 	pm.newline_always = false;
 	pm.width = width;
-	wchar_t *wstr = str_to_awstr(str);
+	char32_t *wstr = str_to_awstr(str);
 	if (wstr == NULL) {
 		return ENOMEM;
@@ -87,5 +87,5 @@
 }
 
-errno_t print_aligned_w(const wchar_t *wstr, size_t width, bool last,
+errno_t print_aligned_w(const char32_t *wstr, size_t width, bool last,
     align_mode_t mode)
 {
@@ -95,14 +95,14 @@
 		for (i = 0; i < width; i++) {
 			if (i < len)
-				putwchar(wstr[i]);
+				putuchar(wstr[i]);
 			else
-				putwchar(' ');
+				putuchar(' ');
 		}
 	} else if (mode == ALIGN_RIGHT) {
 		for (i = 0; i < width; i++) {
 			if (i < width - len)
-				putwchar(' ');
+				putuchar(' ');
 			else
-				putwchar(wstr[i - (width - len)]);
+				putuchar(wstr[i - (width - len)]);
 		}
 	} else if (mode == ALIGN_CENTER) {
@@ -110,7 +110,7 @@
 		for (i = 0; i < width; i++) {
 			if ((i < padding) || ((i - padding) >= len))
-				putwchar(' ');
+				putuchar(' ');
 			else
-				putwchar(wstr[i - padding]);
+				putuchar(wstr[i - padding]);
 		}
 	} else if (mode == ALIGN_JUSTIFY) {
@@ -146,10 +146,10 @@
 				    (words - 1)));
 				for (j = 0; j < spaces; j++) {
-					putwchar(' ');
+					putuchar(' ');
 				}
 				done_chars += spaces;
 			}
 			while (i < len && wstr[i] != ' ') {
-				putwchar(wstr[i++]);
+				putuchar(wstr[i++]);
 				done_chars++;
 			}
@@ -158,5 +158,5 @@
 	skip_words:
 		while (done_chars < width) {
-			putwchar(' ');
+			putuchar(' ');
 			done_chars++;
 		}
@@ -169,5 +169,5 @@
 errno_t print_aligned(const char *str, size_t width, bool last, align_mode_t mode)
 {
-	wchar_t *wstr = str_to_awstr(str);
+	char32_t *wstr = str_to_awstr(str);
 	if (wstr == NULL) {
 		return ENOMEM;
@@ -178,5 +178,5 @@
 }
 
-errno_t wrap(wchar_t *wstr, size_t width, line_consumer_fn consumer, void *data)
+errno_t wrap(char32_t *wstr, size_t width, line_consumer_fn consumer, void *data)
 {
 	size_t word_start = 0;
Index: uspace/lib/fmtutil/fmtutil.h
===================================================================
--- uspace/lib/fmtutil/fmtutil.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/fmtutil/fmtutil.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -44,7 +44,7 @@
  * @returns EOK on success or an error code on failure
  */
-typedef errno_t (*line_consumer_fn)(wchar_t *, size_t, bool, void *);
+typedef errno_t (*line_consumer_fn)(char32_t *, size_t, bool, void *);
 
-extern errno_t print_aligned_w(const wchar_t *, size_t, bool, align_mode_t);
+extern errno_t print_aligned_w(const char32_t *, size_t, bool, align_mode_t);
 extern errno_t print_aligned(const char *, size_t, bool, align_mode_t);
 extern errno_t print_wrapped(const char *, size_t, align_mode_t);
@@ -58,3 +58,3 @@
  * @param data user data to pass to the consumer function
  */
-extern errno_t wrap(wchar_t *, size_t, line_consumer_fn, void *);
+extern errno_t wrap(char32_t *, size_t, line_consumer_fn, void *);
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/gui/terminal.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -419,5 +419,5 @@
 			if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS &&
 			    event->ev.key.c != 0) {
-				wchar_t tmp[2] = {
+				char32_t tmp[2] = {
 					event->ev.key.c,
 					0
@@ -436,5 +436,5 @@
 }
 
-static void term_write_char(terminal_t *term, wchar_t ch)
+static void term_write_char(terminal_t *term, char32_t ch)
 {
 	sysarg_t updated = 0;
@@ -455,5 +455,5 @@
 		break;
 	default:
-		updated = chargrid_putwchar(term->frontbuf, ch, true);
+		updated = chargrid_putuchar(term->frontbuf, ch, true);
 	}
 
Index: uspace/lib/posix/src/stdio.c
===================================================================
--- uspace/lib/posix/src/stdio.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/posix/src/stdio.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -249,5 +249,5 @@
  * @return The number of written characters.
  */
-static int _dprintf_wstr_write(const wchar_t *str, size_t size, void *fd)
+static int _dprintf_wstr_write(const char32_t *str, size_t size, void *fd)
 {
 	size_t offset = 0;
@@ -268,5 +268,5 @@
 
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/lib/usbdev/src/request.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -756,5 +756,5 @@
 	/* Prepare dynamically allocated variables. */
 	uint8_t *string = NULL;
-	wchar_t *string_chars = NULL;
+	char32_t *string_chars = NULL;
 
 	/* Get the actual descriptor. */
@@ -783,5 +783,5 @@
 
 	const size_t string_char_count = string_size / 2;
-	string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
+	string_chars = malloc(sizeof(char32_t) * (string_char_count + 1));
 	if (string_chars == NULL) {
 		rc = ENOMEM;
Index: uspace/srv/fs/exfat/exfat_dentry.c
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/fs/exfat/exfat_dentry.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -110,5 +110,5 @@
 }
 
-bool exfat_valid_char(wchar_t ch)
+bool exfat_valid_char(char32_t ch)
 {
 	if (ch >= 0x01 && ch <= 0x1F)
@@ -134,5 +134,5 @@
 {
 	size_t off = 0;
-	wchar_t ch;
+	char32_t ch;
 
 	while ((ch = str_decode(name, &off, STR_NO_LIMIT)) != 0) {
Index: uspace/srv/fs/exfat/exfat_dentry.h
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/fs/exfat/exfat_dentry.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -37,4 +37,5 @@
 #include <stdint.h>
 #include <stdbool.h>
+#include <uchar.h>
 
 #define EXFAT_FILENAME_LEN	255
@@ -156,5 +157,5 @@
     uint16_t *);
 
-extern bool exfat_valid_char(wchar_t);
+extern bool exfat_valid_char(char32_t);
 extern bool exfat_valid_name(const char *);
 
Index: uspace/srv/fs/fat/fat_dentry.c
===================================================================
--- uspace/srv/fs/fat/fat_dentry.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/fs/fat/fat_dentry.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -360,5 +360,5 @@
 void str_to_ascii(char *dst, const char *src, size_t count, uint8_t pad)
 {
-	wchar_t ch;
+	char32_t ch;
 	size_t off = 0;
 	size_t i = 0;
@@ -381,5 +381,5 @@
 bool fat_valid_name(const char *name)
 {
-	wchar_t ch;
+	char32_t ch;
 	size_t offset = 0;
 	bool result = true;
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/compositor/compositor.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -156,5 +156,5 @@
 static errno_t comp_active(input_t *);
 static errno_t comp_deactive(input_t *);
-static errno_t comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
+static errno_t comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
 static errno_t comp_mouse_move(input_t *, int, int);
 static errno_t comp_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
@@ -1863,5 +1863,5 @@
 
 static errno_t comp_key_press(input_t *input, kbd_event_type_t type, keycode_t key,
-    keymod_t mods, wchar_t c)
+    keymod_t mods, char32_t c)
 {
 	bool win_transform = (mods & KM_ALT) &&
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/console/console.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -105,5 +105,5 @@
 static errno_t input_ev_active(input_t *);
 static errno_t input_ev_deactive(input_t *);
-static errno_t input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
+static errno_t input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
 static errno_t input_ev_move(input_t *, int, int);
 static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
@@ -250,5 +250,5 @@
 
 static errno_t input_ev_key(input_t *input, kbd_event_type_t type, keycode_t key,
-    keymod_t mods, wchar_t c)
+    keymod_t mods, char32_t c)
 {
 	if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) &&
@@ -293,5 +293,5 @@
 
 /** Process a character from the client (TTY emulation). */
-static void cons_write_char(console_t *cons, wchar_t ch)
+static void cons_write_char(console_t *cons, char32_t ch)
 {
 	sysarg_t updated = 0;
@@ -312,5 +312,5 @@
 		break;
 	default:
-		updated = chargrid_putwchar(cons->frontbuf, ch, true);
+		updated = chargrid_putuchar(cons->frontbuf, ch, true);
 	}
 
@@ -371,5 +371,5 @@
 			/* Accept key presses of printable chars only. */
 			if ((event->type == KEY_PRESS) && (event->c != 0)) {
-				wchar_t tmp[2] = { event->c, 0 };
+				char32_t tmp[2] = { event->c, 0 };
 				wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp);
 				cons->char_remains_len = str_size(cons->char_remains);
Index: uspace/srv/hid/input/layout.c
===================================================================
--- uspace/srv/hid/input/layout.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -69,5 +69,5 @@
 
 /** Parse keyboard event. */
-wchar_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
+char32_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
 {
 	return (*layout->ops->parse_ev)(layout, ev);
Index: uspace/srv/hid/input/layout.h
===================================================================
--- uspace/srv/hid/input/layout.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -53,5 +53,5 @@
 	errno_t (*create)(layout_t *);
 	void (*destroy)(layout_t *);
-	wchar_t (*parse_ev)(layout_t *, kbd_event_t *);
+	char32_t (*parse_ev)(layout_t *, kbd_event_t *);
 } layout_ops_t;
 
@@ -64,5 +64,5 @@
 extern layout_t *layout_create(layout_ops_t *);
 extern void layout_destroy(layout_t *);
-extern wchar_t layout_parse_ev(layout_t *, kbd_event_t *);
+extern char32_t layout_parse_ev(layout_t *, kbd_event_t *);
 
 #endif
Index: uspace/srv/hid/input/layout/ar.c
===================================================================
--- uspace/srv/hid/input/layout/ar.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout/ar.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -44,5 +44,5 @@
 static errno_t ar_create(layout_t *);
 static void ar_destroy(layout_t *);
-static wchar_t ar_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t ar_parse_ev(layout_t *, kbd_event_t *ev);
 
 layout_ops_t ar_ops = {
@@ -52,5 +52,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = L'ذ',
 
@@ -110,5 +110,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_BACKTICK] = L'ّ',
 
@@ -168,5 +168,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -181,5 +181,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -196,5 +196,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -212,7 +212,7 @@
 }
 
-static wchar_t ar_parse_ev(layout_t *state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t ar_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -220,12 +220,12 @@
 		return 0;
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -233,5 +233,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/input/layout/cz.c
===================================================================
--- uspace/srv/hid/input/layout/cz.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout/cz.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -45,5 +45,5 @@
 static errno_t cz_create(layout_t *);
 static void cz_destroy(layout_t *);
-static wchar_t cz_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t cz_parse_ev(layout_t *, kbd_event_t *ev);
 
 enum m_state {
@@ -63,5 +63,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_Q] = 'q',
 	[KC_W] = 'w',
@@ -94,5 +94,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_Q] = 'Q',
 	[KC_W] = 'W',
@@ -125,5 +125,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = ';',
 
@@ -141,5 +141,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_1] = '1',
 	[KC_2] = '2',
@@ -167,5 +167,5 @@
 };
 
-static wchar_t map_ns_nocaps[] = {
+static char32_t map_ns_nocaps[] = {
 	[KC_2] = L'ě',
 	[KC_3] = L'š',
@@ -182,5 +182,5 @@
 };
 
-static wchar_t map_ns_caps[] = {
+static char32_t map_ns_caps[] = {
 	[KC_2] = L'Ě',
 	[KC_3] = L'Š',
@@ -197,5 +197,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -210,5 +210,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -225,5 +225,5 @@
 };
 
-static wchar_t map_hacek_lcase[] = {
+static char32_t map_hacek_lcase[] = {
 	[KC_E] = L'ě',
 	[KC_R] = L'ř',
@@ -239,5 +239,5 @@
 };
 
-static wchar_t map_hacek_ucase[] = {
+static char32_t map_hacek_ucase[] = {
 	[KC_E] = L'Ě',
 	[KC_R] = L'Ř',
@@ -253,5 +253,5 @@
 };
 
-static wchar_t map_carka_lcase[] = {
+static char32_t map_carka_lcase[] = {
 	[KC_E] = L'é',
 	[KC_U] = L'ú',
@@ -264,5 +264,5 @@
 };
 
-static wchar_t map_carka_ucase[] = {
+static char32_t map_carka_ucase[] = {
 	[KC_E] = L'É',
 	[KC_U] = L'Ú',
@@ -275,5 +275,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -282,7 +282,7 @@
 }
 
-static wchar_t parse_ms_hacek(layout_cz_t *cz_state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t parse_ms_hacek(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	cz_state->mstate = ms_start;
@@ -293,14 +293,14 @@
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(char32_t));
 
 	return c;
 }
 
-static wchar_t parse_ms_carka(layout_cz_t *cz_state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t parse_ms_carka(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	cz_state->mstate = ms_start;
@@ -311,14 +311,14 @@
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(char32_t));
 
 	return c;
 }
 
-static wchar_t parse_ms_start(layout_cz_t *cz_state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t parse_ms_start(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -335,5 +335,5 @@
 	}
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
@@ -341,7 +341,7 @@
 	if ((ev->mods & KM_SHIFT) == 0) {
 		if ((ev->mods & KM_CAPS_LOCK) != 0)
-			c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
+			c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(char32_t));
 		else
-			c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
+			c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(char32_t));
 
 		if (c != 0)
@@ -350,7 +350,7 @@
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char32_t));
 
 	if (c != 0)
@@ -358,7 +358,7 @@
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -366,5 +366,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
@@ -409,5 +409,5 @@
 }
 
-static wchar_t cz_parse_ev(layout_t *state, kbd_event_t *ev)
+static char32_t cz_parse_ev(layout_t *state, kbd_event_t *ev)
 {
 	layout_cz_t *cz_state = (layout_cz_t *) state->layout_priv;
Index: uspace/srv/hid/input/layout/fr_azerty.c
===================================================================
--- uspace/srv/hid/input/layout/fr_azerty.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout/fr_azerty.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 static errno_t fr_azerty_create (layout_t *);
 static void fr_azerty_destroy (layout_t *);
-static wchar_t fr_azerty_parse_ev (layout_t *, kbd_event_t *);
+static char32_t fr_azerty_parse_ev (layout_t *, kbd_event_t *);
 
 layout_ops_t fr_azerty_ops = {
@@ -51,5 +51,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_Q] = 'a',
 	[KC_W] = 'z',
@@ -82,5 +82,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_Q] = 'A',
 	[KC_W] = 'Z',
@@ -117,5 +117,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = L'²',
 
@@ -146,5 +146,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_M] = '?',
 	[KC_BACKTICK] = '~',
@@ -176,5 +176,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -189,5 +189,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -204,5 +204,5 @@
 };
 
-static wchar_t translate (unsigned int key, wchar_t *map, size_t map_len)
+static char32_t translate (unsigned int key, char32_t *map, size_t map_len)
 {
 	if (key >= map_len)
@@ -221,17 +221,17 @@
 }
 
-static wchar_t fr_azerty_parse_ev (layout_t *s, kbd_event_t *e)
+static char32_t fr_azerty_parse_ev (layout_t *s, kbd_event_t *e)
 {
 	if ((e->mods & (KM_CTRL | KM_ALT)))
 		return 0; // Produce no characters when Ctrl or Alt is pressed
 
-	wchar_t c = translate (e->key, map_neutral, sizeof (map_neutral) / sizeof (wchar_t));
+	char32_t c = translate (e->key, map_neutral, sizeof (map_neutral) / sizeof (char32_t));
 	if (c)
 		return c;
 
 	if ((e->mods & KM_SHIFT))
-		c = translate (e->key, map_shifted, sizeof (map_shifted) / sizeof (wchar_t));
+		c = translate (e->key, map_shifted, sizeof (map_shifted) / sizeof (char32_t));
 	else
-		c = translate (e->key, map_not_shifted, sizeof (map_not_shifted) / sizeof (wchar_t));
+		c = translate (e->key, map_not_shifted, sizeof (map_not_shifted) / sizeof (char32_t));
 
 	if (c)
@@ -239,7 +239,7 @@
 
 	if (((e->mods & KM_SHIFT)) ^ ((e->mods & KM_CAPS_LOCK)))
-		c = translate (e->key, map_ucase, sizeof (map_ucase) / sizeof (wchar_t));
+		c = translate (e->key, map_ucase, sizeof (map_ucase) / sizeof (char32_t));
 	else
-		c = translate (e->key, map_lcase, sizeof (map_lcase) / sizeof (wchar_t));
+		c = translate (e->key, map_lcase, sizeof (map_lcase) / sizeof (char32_t));
 
 	if (c)
@@ -247,5 +247,5 @@
 
 	if ((e->mods & KM_NUM_LOCK))
-		c = translate (e->key, map_numeric, sizeof (map_numeric) / sizeof (wchar_t));
+		c = translate (e->key, map_numeric, sizeof (map_numeric) / sizeof (char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/input/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/input/layout/us_dvorak.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout/us_dvorak.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 static errno_t us_dvorak_create(layout_t *);
 static void us_dvorak_destroy(layout_t *);
-static wchar_t us_dvorak_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t us_dvorak_parse_ev(layout_t *, kbd_event_t *ev);
 
 layout_ops_t us_dvorak_ops = {
@@ -51,5 +51,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_R] = 'p',
 	[KC_T] = 'y',
@@ -84,5 +84,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_R] = 'P',
 	[KC_T] = 'Y',
@@ -117,5 +117,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = '`',
 
@@ -147,5 +147,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_BACKTICK] = '~',
 
@@ -177,5 +177,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -190,5 +190,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -205,5 +205,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -221,7 +221,7 @@
 }
 
-static wchar_t us_dvorak_parse_ev(layout_t *state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t us_dvorak_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -229,12 +229,12 @@
 		return 0;
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char32_t));
 
 	if (c != 0)
@@ -242,7 +242,7 @@
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -250,5 +250,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/input/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/input/layout/us_qwerty.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/input/layout/us_qwerty.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -43,5 +43,5 @@
 static errno_t us_qwerty_create(layout_t *);
 static void us_qwerty_destroy(layout_t *);
-static wchar_t us_qwerty_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t us_qwerty_parse_ev(layout_t *, kbd_event_t *ev);
 
 layout_ops_t us_qwerty_ops = {
@@ -51,5 +51,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_Q] = 'q',
 	[KC_W] = 'w',
@@ -82,5 +82,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_Q] = 'Q',
 	[KC_W] = 'W',
@@ -113,5 +113,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = '`',
 
@@ -142,5 +142,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_BACKTICK] = '~',
 
@@ -171,5 +171,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -184,5 +184,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -199,5 +199,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -215,7 +215,7 @@
 }
 
-static wchar_t us_qwerty_parse_ev(layout_t *state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t us_qwerty_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -223,12 +223,12 @@
 		return 0;
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char32_t));
 
 	if (c != 0)
@@ -236,7 +236,7 @@
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -244,5 +244,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/output/ctl/serial.c
===================================================================
--- uspace/srv/hid/output/ctl/serial.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/ctl/serial.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -57,5 +57,5 @@
 	vt100_goto(state, col, row);
 	vt100_set_attr(state, field->attrs);
-	vt100_putwchar(state, field->ch);
+	vt100_putuchar(state, field->ch);
 }
 
@@ -122,9 +122,9 @@
 };
 
-errno_t serial_init(vt100_putwchar_t putwchar_fn,
+errno_t serial_init(vt100_putuchar_t putuchar_fn,
     vt100_control_puts_t control_puts_fn, vt100_flush_t flush_fn)
 {
 	vt100_state_t *state =
-	    vt100_state_create(SERIAL_COLS, SERIAL_ROWS, putwchar_fn,
+	    vt100_state_create(SERIAL_COLS, SERIAL_ROWS, putuchar_fn,
 	    control_puts_fn, flush_fn);
 	if (state == NULL)
Index: uspace/srv/hid/output/ctl/serial.h
===================================================================
--- uspace/srv/hid/output/ctl/serial.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/ctl/serial.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -37,5 +37,5 @@
 #include "../proto/vt100.h"
 
-extern errno_t serial_init(vt100_putwchar_t, vt100_control_puts_t, vt100_flush_t);
+extern errno_t serial_init(vt100_putuchar_t, vt100_control_puts_t, vt100_flush_t);
 
 #endif
Index: uspace/srv/hid/output/gfx/font-8x16.c
===================================================================
--- uspace/srv/hid/output/gfx/font-8x16.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/gfx/font-8x16.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -45,5 +45,5 @@
  *
  */
-uint16_t fb_font_glyph(const wchar_t ch)
+uint16_t fb_font_glyph(const char32_t ch)
 {
 	if (ch == 0x0000)
Index: uspace/srv/hid/output/gfx/font-8x16.h
===================================================================
--- uspace/srv/hid/output/gfx/font-8x16.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/gfx/font-8x16.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -42,5 +42,5 @@
 #define FONT_SCANLINES  16
 
-extern uint16_t fb_font_glyph(const wchar_t);
+extern uint16_t fb_font_glyph(const char32_t);
 extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
Index: uspace/srv/hid/output/port/chardev.c
===================================================================
--- uspace/srv/hid/output/port/chardev.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/port/chardev.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -78,5 +78,5 @@
 }
 
-static void chardev_putwchar(wchar_t ch)
+static void chardev_putuchar(char32_t ch)
 {
 	if (chardev_bused == chardev_buf_size)
@@ -93,5 +93,5 @@
 	p = str;
 	while (*p != '\0')
-		chardev_putwchar(*p++);
+		chardev_putuchar(*p++);
 }
 
@@ -199,5 +199,5 @@
 	}
 
-	serial_init(chardev_putwchar, chardev_control_puts, chardev_flush);
+	serial_init(chardev_putuchar, chardev_control_puts, chardev_flush);
 
 	discovery_finished = true;
Index: uspace/srv/hid/output/port/kfb.c
===================================================================
--- uspace/srv/hid/output/port/kfb.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/port/kfb.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -79,5 +79,5 @@
 
 /** Function to draw a character. */
-typedef void (*draw_char_t)(sysarg_t, sysarg_t, bool, wchar_t, pixel_t,
+typedef void (*draw_char_t)(sysarg_t, sysarg_t, bool, char32_t, pixel_t,
     pixel_t);
 
@@ -287,5 +287,5 @@
  *
  */
-static void draw_char_aligned(sysarg_t x, sysarg_t y, bool inverted, wchar_t ch,
+static void draw_char_aligned(sysarg_t x, sysarg_t y, bool inverted, char32_t ch,
     pixel_t bgcolor, pixel_t fgcolor)
 {
@@ -350,5 +350,5 @@
  */
 static void draw_char_fallback(sysarg_t x, sysarg_t y, bool inverted,
-    wchar_t ch, pixel_t bgcolor, pixel_t fgcolor)
+    char32_t ch, pixel_t bgcolor, pixel_t fgcolor)
 {
 	/* Character glyph */
Index: uspace/srv/hid/output/proto/vt100.c
===================================================================
--- uspace/srv/hid/output/proto/vt100.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/proto/vt100.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -140,5 +140,5 @@
 
 vt100_state_t *vt100_state_create(sysarg_t cols, sysarg_t rows,
-    vt100_putwchar_t putwchar_fn, vt100_control_puts_t control_puts_fn,
+    vt100_putuchar_t putuchar_fn, vt100_control_puts_t control_puts_fn,
     vt100_flush_t flush_fn)
 {
@@ -147,5 +147,5 @@
 		return NULL;
 
-	state->putwchar = putwchar_fn;
+	state->putuchar = putuchar_fn;
 	state->control_puts = control_puts_fn;
 	state->flush = flush_fn;
@@ -220,7 +220,7 @@
 }
 
-void vt100_putwchar(vt100_state_t *state, wchar_t ch)
-{
-	state->putwchar(ch == 0 ? ' ' : ch);
+void vt100_putuchar(vt100_state_t *state, char32_t ch)
+{
+	state->putuchar(ch == 0 ? ' ' : ch);
 	state->cur_col++;
 
Index: uspace/srv/hid/output/proto/vt100.h
===================================================================
--- uspace/srv/hid/output/proto/vt100.h	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/output/proto/vt100.h	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -36,5 +36,5 @@
 #include <io/charfield.h>
 
-typedef void (*vt100_putwchar_t)(wchar_t ch);
+typedef void (*vt100_putuchar_t)(char32_t ch);
 typedef void (*vt100_control_puts_t)(const char *str);
 typedef void (*vt100_flush_t)(void);
@@ -48,10 +48,10 @@
 	char_attrs_t cur_attrs;
 
-	vt100_putwchar_t putwchar;
+	vt100_putuchar_t putuchar;
 	vt100_control_puts_t control_puts;
 	vt100_flush_t flush;
 } vt100_state_t;
 
-extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putwchar_t,
+extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putuchar_t,
     vt100_control_puts_t, vt100_flush_t);
 extern void vt100_state_destroy(vt100_state_t *);
@@ -64,5 +64,5 @@
 extern void vt100_set_attr(vt100_state_t *, char_attrs_t);
 extern void vt100_cursor_visibility(vt100_state_t *, bool);
-extern void vt100_putwchar(vt100_state_t *, wchar_t);
+extern void vt100_putuchar(vt100_state_t *, char32_t);
 extern void vt100_flush(vt100_state_t *);
 
Index: uspace/srv/hid/remcons/user.c
===================================================================
--- uspace/srv/hid/remcons/user.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/hid/remcons/user.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -218,5 +218,5 @@
  * @param c Pressed character.
  */
-static kbd_event_t *new_kbd_event(kbd_event_type_t type, wchar_t c)
+static kbd_event_t *new_kbd_event(kbd_event_type_t type, char32_t c)
 {
 	kbd_event_t *event = malloc(sizeof(kbd_event_t));
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/locsrv/locsrv.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -125,5 +125,5 @@
 	size_t offset = 0;
 	size_t offset_prev = 0;
-	wchar_t c;
+	char32_t c;
 
 	while ((c = str_decode(fqsn, &offset, STR_NO_LIMIT)) != 0) {
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision 4f663f3eb077aa3ae5993134d3a7ec64ffa4f316)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision 28a5ebdea900783081bd23e40f685b6b0479c63d)
@@ -97,5 +97,5 @@
 {
 	size_t off;
-	wchar_t c;
+	char32_t c;
 	size_t lsize;
 	size_t pi, di;
