Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/app/init/init.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -50,4 +50,5 @@
 #include <vfs/vfs.h>
 #include <vol.h>
+#include <ipc/services.h>
 #include "untar.h"
 #include "init.h"
@@ -70,5 +71,5 @@
 #define SRV_DISPLAY  "/srv/hid/display"
 
-#define HID_INPUT              "hid/input"
+#define HID_INPUT              SERVICE_NAME_HID_INPUT
 #define HID_OUTPUT             "hid/output"
 
Index: uspace/lib/c/include/ipc/input.h
===================================================================
--- uspace/lib/c/include/ipc/input.h	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/lib/c/include/ipc/input.h	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -39,5 +39,7 @@
 
 typedef enum {
-	INPUT_ACTIVATE = IPC_FIRST_USER_METHOD
+	INPUT_ACTIVATE = IPC_FIRST_USER_METHOD,
+	INPUT_CHANGE_LAYOUT,
+	INPUT_GET_LAYOUT
 } input_request_t;
 
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/lib/c/include/ipc/services.h	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -59,4 +59,5 @@
 #define SERVICE_NAME_INET     "net/inet"
 #define SERVICE_NAME_IPC_TEST "ipc-test"
+#define SERVICE_NAME_HID_INPUT    "hid/input"
 #define SERVICE_NAME_NETCONF  "net/netconf"
 #define SERVICE_NAME_UDP      "net/udp"
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/input.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -66,5 +66,7 @@
 #include "serial.h"
 
-#define NUM_LAYOUTS 5
+static layout_ops_t *layout_active = &us_qwerty_ops;
+
+#define NUM_LAYOUTS  5
 
 static layout_ops_t *layout[NUM_LAYOUTS] = {
@@ -107,4 +109,59 @@
 
 static FIBRIL_MUTEX_INITIALIZE(discovery_lock);
+
+/* changes all kb devices to the given layout */
+static void layout_change(layout_ops_t *layout)
+{
+	list_foreach(kbd_devs, link, kbd_dev_t, kdev) {
+		layout_t *ret = layout_create(layout);
+		if (ret != NULL) {
+			layout_destroy(kdev->active_layout);
+			kdev->active_layout = ret;
+		}
+	}
+}
+
+/* similiar like layout_change but takes as an argument the name of the layout */
+static errno_t layout_load(const char *layout_name)
+{
+	/* TODO: change this into a loader for kb layout maps */
+	for (int i = 0; i < NUM_LAYOUTS; i++) {
+		if (str_cmp(layout[i]->name, layout_name) == 0) {
+			layout_active = layout[i];
+			layout_change(layout_active);
+			return EOK;
+		}
+	}
+
+	return ENOTSUP;
+}
+
+/* Handler for IPC call INPUT_CHANGE_LAYOUT */
+static void client_change_layout_handler(ipc_call_t *call)
+{
+	void *layout_name;
+	errno_t ret = async_data_write_accept(&layout_name, true, 0, 0, 0, 0);
+	if (ret != EOK) {
+		async_answer_0(call, ret);
+		return;
+	}
+
+	errno_t retval = layout_load((char *)layout_name);
+	free(layout_name);
+	async_answer_0(call, retval);
+}
+
+/* Handler for IPC call INPUT_GET_LAYOUT */
+static void client_get_layout_handler(ipc_call_t *call)
+{
+	const char *layout_name = layout_active->name;
+	size_t length = str_size(layout_name) + 1;
+	ipc_call_t id;
+
+	async_answer_1(call, EOK, length);
+	if (async_data_read_receive(&id, NULL)) {
+		async_data_read_finalize(&id, layout_name, length);
+	}
+}
 
 static void *client_data_create(void)
@@ -212,22 +269,17 @@
 		switch (key) {
 		case KC_F1:
-			layout_destroy(kdev->active_layout);
-			kdev->active_layout = layout_create(layout[0]);
+			layout_change(layout[0]);
 			break;
 		case KC_F2:
-			layout_destroy(kdev->active_layout);
-			kdev->active_layout = layout_create(layout[1]);
+			layout_change(layout[1]);
 			break;
 		case KC_F3:
-			layout_destroy(kdev->active_layout);
-			kdev->active_layout = layout_create(layout[2]);
+			layout_change(layout[2]);
 			break;
 		case KC_F4:
-			layout_destroy(kdev->active_layout);
-			kdev->active_layout = layout_create(layout[3]);
+			layout_change(layout[3]);
 			break;
 		case KC_F5:
-			layout_destroy(kdev->active_layout);
-			kdev->active_layout = layout_create(layout[4]);
+			layout_change(layout[4]);
 			break;
 		default: // default: is here to avoid compiler warning about unhandled cases
@@ -367,4 +419,10 @@
 				async_answer_0(&call, EOK);
 				break;
+			case INPUT_CHANGE_LAYOUT:
+				client_change_layout_handler(&call);
+				break;
+			case INPUT_GET_LAYOUT:
+				client_get_layout_handler(&call);
+				break;
 			default:
 				async_answer_0(&call, EINVAL);
@@ -400,5 +458,5 @@
 	kdev->mods = KM_NUM_LOCK;
 	kdev->lock_keys = 0;
-	kdev->active_layout = layout_create(layout[0]);
+	kdev->active_layout = layout_create(layout_active);
 
 	return kdev;
Index: uspace/srv/hid/input/input.h
===================================================================
--- uspace/srv/hid/input/input.h	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/input.h	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -41,6 +41,7 @@
 #include <stdbool.h>
 #include <async.h>
+#include <ipc/services.h>
 
-#define NAME  "input"
+#define NAME SERVICE_NAME_HID_INPUT
 
 extern bool irc_service;
Index: uspace/srv/hid/input/layout.h
===================================================================
--- uspace/srv/hid/input/layout.h	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/layout.h	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -54,4 +54,5 @@
 	void (*destroy)(layout_t *);
 	char32_t (*parse_ev)(layout_t *, kbd_event_t *);
+	const char *name;
 } layout_ops_t;
 
Index: uspace/srv/hid/input/layout/ar.c
===================================================================
--- uspace/srv/hid/input/layout/ar.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/layout/ar.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -49,5 +49,6 @@
 	.create = ar_create,
 	.destroy = ar_destroy,
-	.parse_ev = ar_parse_ev
+	.parse_ev = ar_parse_ev,
+	.name = "ar"
 };
 
Index: uspace/srv/hid/input/layout/cz.c
===================================================================
--- uspace/srv/hid/input/layout/cz.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/layout/cz.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -60,5 +60,6 @@
 	.create = cz_create,
 	.destroy = cz_destroy,
-	.parse_ev = cz_parse_ev
+	.parse_ev = cz_parse_ev,
+	.name = "cz"
 };
 
Index: uspace/srv/hid/input/layout/fr_azerty.c
===================================================================
--- uspace/srv/hid/input/layout/fr_azerty.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/layout/fr_azerty.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -48,5 +48,6 @@
 	.create = fr_azerty_create,
 	.destroy = fr_azerty_destroy,
-	.parse_ev = fr_azerty_parse_ev
+	.parse_ev = fr_azerty_parse_ev,
+	.name = "fr_azerty"
 };
 
Index: uspace/srv/hid/input/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/input/layout/us_dvorak.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/layout/us_dvorak.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -48,5 +48,6 @@
 	.create = us_dvorak_create,
 	.destroy = us_dvorak_destroy,
-	.parse_ev = us_dvorak_parse_ev
+	.parse_ev = us_dvorak_parse_ev,
+	.name = "us_dvorak"
 };
 
Index: uspace/srv/hid/input/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/input/layout/us_qwerty.c	(revision e037cf3733f322897cbfc63ce44277485f52af9b)
+++ uspace/srv/hid/input/layout/us_qwerty.c	(revision 11e394f9d494211274c7ab598fe773604068e733)
@@ -48,5 +48,6 @@
 	.create = us_qwerty_create,
 	.destroy = us_qwerty_destroy,
-	.parse_ev = us_qwerty_parse_ev
+	.parse_ev = us_qwerty_parse_ev,
+	.name = "us_qwerty"
 };
 
