Index: uspace/lib/c/generic/io/asprintf.c
===================================================================
--- uspace/lib/c/generic/io/asprintf.c	(revision ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/asprintf.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/chargrid.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/input.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/io.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/kio.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/printf_core.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/vprintf.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/io/vsnprintf.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/stdio/sstream.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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 ffccdff0fd3f49751202889e457bdf900721bfad)
+++ uspace/lib/c/generic/str.c	(revision 663f445f6ae6d51eff8cb7bcc345d4a411d3ff7e)
@@ -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. */
