Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ kernel/Makefile	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -196,4 +196,5 @@
 	generic/src/console/chardev.c \
 	generic/src/console/console.c \
+	generic/src/console/prompt.c \
 	generic/src/cpu/cpu.c \
 	generic/src/ddi/ddi.c \
Index: kernel/generic/include/console/prompt.h
===================================================================
--- kernel/generic/include/console/prompt.h	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
+++ kernel/generic/include/console/prompt.h	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 genericconsole
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_CONSOLE_PROMPT_H_
+#define KERN_CONSOLE_PROMPT_H_
+
+#include <console/chardev.h>
+
+#define MAX_TAB_HINTS 37
+
+extern bool console_prompt_display_all_hints(indev_t *, size_t);
+extern bool console_prompt_more_hints(indev_t *, size_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ kernel/generic/include/debug.h	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -37,5 +37,5 @@
 
 #include <panic.h>
-#include <symtab.h>
+#include <symtab_lookup.h>
 
 #define CALLER  ((uintptr_t) __builtin_return_address(0))
Index: kernel/generic/include/symtab.h
===================================================================
--- kernel/generic/include/symtab.h	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ kernel/generic/include/symtab.h	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -36,27 +36,9 @@
 #define KERN_SYMTAB_H_
 
-#include <typedefs.h>
+#include <symtab_lookup.h>
+#include <console/chardev.h>
 
-#define MAX_SYMBOL_NAME  64
-
-struct symtab_entry {
-	uint64_t address_le;
-	char symbol_name[MAX_SYMBOL_NAME];
-};
-
-extern int symtab_name_lookup(uintptr_t, const char **, uintptr_t *);
-extern const char *symtab_fmt_name_lookup(uintptr_t);
-extern int symtab_addr_lookup(const char *, uintptr_t *);
 extern void symtab_print_search(const char *);
-extern int symtab_compl(char *, size_t);
-
-#ifdef CONFIG_SYMTAB
-
-/** Symtable linked together by build process
- *
- */
-extern struct symtab_entry symbol_table[];
-
-#endif /* CONFIG_SYMTAB */
+extern int symtab_compl(char *, size_t, indev_t *);
 
 #endif
Index: kernel/generic/include/symtab_lookup.h
===================================================================
--- kernel/generic/include/symtab_lookup.h	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
+++ kernel/generic/include/symtab_lookup.h	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Ondrej Palkovsky
+ * 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 generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_SYMTAB_LOOKUP_H_
+#define KERN_SYMTAB_LOOKUP_H_
+
+#include <typedefs.h>
+
+#define MAX_SYMBOL_NAME  64
+
+struct symtab_entry {
+	uint64_t address_le;
+	char symbol_name[MAX_SYMBOL_NAME];
+};
+
+extern int symtab_name_lookup(uintptr_t, const char **, uintptr_t *);
+extern const char *symtab_fmt_name_lookup(uintptr_t);
+extern int symtab_addr_lookup(const char *, uintptr_t *);
+
+#ifdef CONFIG_SYMTAB
+
+/** Symtable linked together by build process
+ *
+ */
+extern struct symtab_entry symbol_table[];
+
+#endif /* CONFIG_SYMTAB */
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ kernel/generic/src/console/kconsole.c	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -43,4 +43,5 @@
 #include <console/chardev.h>
 #include <console/cmd.h>
+#include <console/prompt.h>
 #include <print.h>
 #include <panic.h>
@@ -201,12 +202,20 @@
  *
  */
-NO_TRACE static int cmdtab_compl(char *input, size_t size)
+NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t * indev)
 {
 	const char *name = input;
 	
 	size_t found = 0;
+	/* Maximum Match Length : Length of longest matching common substring in
+	   case more than one match is found */
+	size_t max_match_len = size;
+	size_t max_match_len_tmp = size;
+	size_t input_len = str_length(input);
 	link_t *pos = NULL;
 	const char *hint;
 	char *output = malloc(MAX_CMDLINE, 0);
+	size_t hints_to_show = MAX_TAB_HINTS - 1;
+	size_t total_hints_shown = 0;
+	bool continue_showing_hints = true;
 	
 	output[0] = 0;
@@ -218,4 +227,10 @@
 		pos = pos->next;
 		found++;
+	}
+	
+	/* If possible completions are more than MAX_TAB_HINTS, ask user whether to display them or not. */
+	if (found > MAX_TAB_HINTS) {
+		printf("\n");
+		continue_showing_hints = console_prompt_display_all_hints(indev, found);
 	}
 	
@@ -225,7 +240,22 @@
 		while (cmdtab_search_one(name, &pos)) {
 			cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
-			printf("%s (%s)\n", hlp->name, hlp->description);
+
+			if (continue_showing_hints) {
+				printf("%s (%s)\n", hlp->name, hlp->description);
+				--hints_to_show;
+				++total_hints_shown;
+
+				if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
+					continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
+				}
+			}
+
 			pos = pos->next;
-		}
+			for(max_match_len_tmp = 0; output[max_match_len_tmp] == hlp->name[input_len + max_match_len_tmp]
+					&& max_match_len_tmp < max_match_len; ++max_match_len_tmp);
+			max_match_len = max_match_len_tmp;
+		}
+		/* keep only the characters common in all completions */
+		output[max_match_len] = 0;
 	}
 	
@@ -294,23 +324,15 @@
 			if (beg == 0) {
 				/* Command completion */
-				found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
+				found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
 			} else {
 				/* Symbol completion */
-				found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
+				found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
 			}
 			
 			if (found == 0)
 				continue;
-			
-			if (found > 1) {
-				/* No unique hint, list was printed */
-				printf("%s> ", prompt);
-				printf("%ls", current);
-				print_cc('\b', wstr_length(current) - position);
-				continue;
-			}
-			
-			/* We have a hint */
-			
+
+			/* We have hints, may be many. In case of more than one hint,
+			   tmp will contain the common prefix. */
 			size_t off = 0;
 			size_t i = 0;
@@ -320,4 +342,15 @@
 				i++;
 			}
+			
+			if (found > 1) {
+				/* No unique hint, list was printed */
+				printf("%s> ", prompt);
+				printf("%ls", current);
+				position += str_length(tmp);
+				print_cc('\b', wstr_length(current) - position);
+				continue;
+			}
+			
+			/* We have a hint */
 			
 			printf("%ls", current + position);
@@ -540,5 +573,5 @@
 /** Parse command line.
  *
- * @param cmdline Command line as read from input device. 
+ * @param cmdline Command line as read from input device.
  * @param size    Size (in bytes) of the string.
  *
Index: kernel/generic/src/console/prompt.c
===================================================================
--- kernel/generic/src/console/prompt.c	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
+++ kernel/generic/src/console/prompt.c	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012 Sandeep Kumar
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 genericconsole
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Kernel console special prompts.
+ */
+
+#include <console/prompt.h>
+
+/** Display the <i>display all possibilities</i> prompt and wait for answer.
+ *
+ * @param indev Where to read characters from.
+ * @param hints Number of hints that would be displayed.
+ * @return Whether to print all hints.
+ */
+bool console_prompt_display_all_hints(indev_t *indev, size_t hints)
+{
+	ASSERT(indev);
+	ASSERT(hints > 0);
+
+	printf("Display all %zu possibilities? (y or n)", hints);
+
+	while (true) {
+		wchar_t answer = indev_pop_character(indev);
+
+		if (answer == 'y' || answer == 'Y') {
+			printf(" y");
+			return true;
+		}
+
+		if (answer == 'n' || answer == 'N') {
+			printf(" n");
+			return false;
+		}
+	}
+}
+
+/** Display the <i>--more--</i> prompt and wait for answer.
+ *
+ * When the function returns false, @p display_hints is set to zero.
+ *
+ * @param[in] indev Where to read characters from.
+ * @param[out] display_hints How many hints to display.
+ * @return Whether to display more hints.
+ */
+bool console_prompt_more_hints(indev_t *indev, size_t *display_hints)
+{
+	ASSERT(indev);
+	ASSERT(display_hints != NULL);
+
+	printf("--More--");
+	while (true) {
+		wchar_t continue_showing_hints = indev_pop_character(indev);
+		/* Display a full page again? */
+		if (continue_showing_hints == 'y'
+		    || continue_showing_hints == 'Y'
+		    || continue_showing_hints == ' ') {
+			*display_hints = MAX_TAB_HINTS - 1;
+			break;
+		}
+
+		/* Stop displaying hints? */
+		if (continue_showing_hints == 'n'
+		    || continue_showing_hints == 'N'
+		    || continue_showing_hints == 'q'
+		    || continue_showing_hints == 'Q') {
+			*display_hints = 0;
+			break;
+		}
+
+		/* Show one more hint? */
+		if (continue_showing_hints == '\n') {
+			*display_hints = 1;
+			break;
+		}
+	}
+
+	/* Delete the --More-- option */
+	printf("\r         \r");
+
+	return *display_hints > 0;
+}
+
+/** @}
+ */
Index: kernel/generic/src/debug/symtab.c
===================================================================
--- kernel/generic/src/debug/symtab.c	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ kernel/generic/src/debug/symtab.c	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -43,4 +43,5 @@
 #include <typedefs.h>
 #include <errno.h>
+#include <console/prompt.h>
 
 /** Get name of a symbol that seems most likely to correspond to address.
@@ -209,5 +210,5 @@
  *
  */
-int symtab_compl(char *input, size_t size)
+int symtab_compl(char *input, size_t size, indev_t * indev)
 {
 #ifdef CONFIG_SYMTAB
@@ -226,6 +227,21 @@
 	const char *hint;
 	char output[MAX_SYMBOL_NAME];
+	/* Maximum Match Length : Length of longest matching common substring in
+	   case more than one match is found */
+	size_t max_match_len = size;
+	size_t max_match_len_tmp = size;
+	size_t input_len = str_length(input);
+	char *sym_name;
+	size_t hints_to_show = MAX_TAB_HINTS - 1;
+	size_t total_hints_shown = 0;
+	bool continue_showing_hints = true;
 	
 	output[0] = 0;
+
+	while ((hint = symtab_search_one(name, &pos))) {
+		++pos;
+	}
+
+	pos = 0;
 	
 	while ((hint = symtab_search_one(name, &pos))) {
@@ -235,4 +251,10 @@
 		pos++;
 		found++;
+	}
+	
+	/* If possible completions are more than MAX_TAB_HINTS, ask user whether to display them or not. */
+	if (found > MAX_TAB_HINTS) {
+		printf("\n");
+		continue_showing_hints = console_prompt_display_all_hints(indev, found);
 	}
 	
@@ -241,7 +263,23 @@
 		pos = 0;
 		while (symtab_search_one(name, &pos)) {
-			printf("%s\n", symbol_table[pos].symbol_name);
+			sym_name = symbol_table[pos].symbol_name;
 			pos++;
+
+			if (continue_showing_hints) { /* We are still showing hints */
+				printf("%s\n", sym_name);
+				--hints_to_show;
+				++total_hints_shown;
+
+				if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
+					continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
+				}
+			}
+
+			for(max_match_len_tmp = 0; output[max_match_len_tmp] == sym_name[input_len + max_match_len_tmp]
+					&& max_match_len_tmp < max_match_len; ++max_match_len_tmp);
+			max_match_len = max_match_len_tmp;
 		}
+		/* keep only the characters common in all completions */
+		output[max_match_len] = 0;
 	}
 	
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -62,4 +62,5 @@
 static sysarg_t console_rows = 0;
 static bool should_quit = false;
+static bool dash_represents_stdin = false;
 
 static console_ctrl_t *console = NULL;
@@ -73,4 +74,5 @@
 	{ "more", no_argument, 0, 'm' },
 	{ "hex", no_argument, 0, 'x' },
+	{ "stdin", no_argument, 0, 's' },
 	{ 0, 0, 0, 0 }
 };
@@ -93,4 +95,5 @@
 		"  -m, --more       Pause after each screen full\n"
 		"  -x, --hex        Print bytes as hex values\n"
+		"  -s  --stdin      Treat `-' in file list as standard input\n"
 		"Currently, %s is under development, some options don't work.\n",
 		cmdname, cmdname);
@@ -172,5 +175,13 @@
 	off64_t file_size = 0, length = 0;
 
-	fd = open(fname, O_RDONLY);
+	bool reading_stdin = dash_represents_stdin && (str_cmp(fname, "-") == 0);
+
+	if (reading_stdin) {
+		fd = fileno(stdin);
+		/* Allow storing the whole UTF-8 character. */
+		blen = STR_BOUNDS(1);
+	} else {
+		fd = open(fname, O_RDONLY);
+	}
 	if (fd < 0) {
 		printf("Unable to open %s\n", fname);
@@ -207,8 +218,16 @@
 
 	do {
-		bytes = read(fd, buff + copied_bytes, (
-			(length != CAT_FULL_FILE && length - (off64_t)count <= (off64_t)(blen - copied_bytes)) ?
-			(size_t)(length - count) :
-			(blen - copied_bytes) ) );
+		size_t bytes_to_read;
+		if (reading_stdin) {
+			bytes_to_read = 1;
+		} else {
+			if ((length != CAT_FULL_FILE)
+			    && (length - (off64_t)count <= (off64_t)(blen - copied_bytes))) {
+				bytes_to_read = (size_t) (length - count);
+			} else {
+				bytes_to_read = blen - copied_bytes;
+			}
+		}
+		bytes = read(fd, buff + copied_bytes, bytes_to_read);
 		bytes += copied_bytes;
 		copied_bytes = 0;
@@ -242,4 +261,8 @@
 			reads++;
 		}
+
+		if (reading_stdin) {
+			fflush(stdout);
+		}
 	} while (bytes > 0 && !should_quit && (count < length || length == CAT_FULL_FILE));
 
@@ -284,5 +307,5 @@
 
 	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
-		c = getopt_long(argc, argv, "xhvmH:t:b:", long_options, &opt_ind);
+		c = getopt_long(argc, argv, "xhvmH:t:b:s", long_options, &opt_ind);
 		switch (c) {
 		case 'h':
@@ -318,4 +341,7 @@
 			hex = true;
 			break;
+		case 's':
+			dash_represents_stdin = true;
+			break;
 		}
 	}
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 33fc3aeab329e1c9379060b6ba8f5568ad21d9fa)
+++ uspace/srv/hid/console/console.c	(revision f0348c863ad29320e7b4b9db7ab172034510a554)
@@ -76,7 +76,11 @@
 } console_state_t;
 
+#define UTF8_CHAR_BUFFER_SIZE (STR_BOUNDS(1) + 1)
+
 typedef struct {
 	atomic_t refcnt;           /**< Connection reference count */
 	prodcons_t input_pc;       /**< Incoming keyboard events */
+	char char_remains[UTF8_CHAR_BUFFER_SIZE]; /**< Not yet sent bytes of last char event. */
+	size_t char_remains_len;   /**< Number of not yet sent bytes. */
 	
 	fibril_mutex_t mtx;        /**< Lock protecting mutable fields */
@@ -613,14 +617,35 @@
 	
 	size_t pos = 0;
+
+	/*
+	 * Read input from keyboard and copy it to the buffer.
+	 * We need to handle situation when wchar is split by 2 following
+	 * reads.
+	 */
 	while (pos < size) {
-		link_t *link = prodcons_consume(&cons->input_pc);
-		kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
-		
-		if (event->type == KEY_PRESS) {
-			buf[pos] = event->c;
+		/* Copy to the buffer remaining characters. */
+		while ((pos < size) && (cons->char_remains_len > 0)) {
+			buf[pos] = cons->char_remains[0];
 			pos++;
-		}
-		
-		free(event);
+			/* Unshift the array. */
+			for (size_t i = 1; i < cons->char_remains_len; i++) {
+				cons->char_remains[i - 1] = cons->char_remains[i];
+			}
+			cons->char_remains_len--;
+		}
+		/* Still not enough? Then get another key from the queue. */
+		if (pos < size) {
+			link_t *link = prodcons_consume(&cons->input_pc);
+			kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
+
+			/* Accept key presses of printable chars only. */
+			if ((event->type == KEY_PRESS) && (event->c != 0)) {
+				wchar_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);
+			}
+
+			free(event);
+		}
 	}
 	
@@ -930,4 +955,5 @@
 		fibril_mutex_initialize(&consoles[i].mtx);
 		prodcons_initialize(&consoles[i].input_pc);
+		consoles[i].char_remains_len = 0;
 		
 		if (graphics_state == GRAPHICS_FULL) {
