Index: uspace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision e49b799749611ec0efd1eb1a09379f3b62d0d269)
+++ uspace/srv/hid/display/display.c	(revision c11ee60568a19bcfd518a78ce1353442a1120e77)
@@ -65,4 +65,5 @@
 	}
 
+	fibril_mutex_initialize(&disp->lock);
 	list_initialize(&disp->clients);
 	disp->next_wnd_id = 1;
@@ -84,4 +85,25 @@
 	gfx_color_delete(disp->bg_color);
 	free(disp);
+}
+
+/** Lock display.
+ *
+ * This should be called in any thread that wishes to access the display
+ * or its child objects (e.g. windows).
+ *
+ * @param disp Display
+ */
+void ds_display_lock(ds_display_t *disp)
+{
+	fibril_mutex_lock(&disp->lock);
+}
+
+/** Unlock display.
+ *
+ * @param disp Display
+ */
+void ds_display_unlock(ds_display_t *disp)
+{
+	fibril_mutex_unlock(&disp->lock);
 }
 
Index: uspace/srv/hid/display/display.h
===================================================================
--- uspace/srv/hid/display/display.h	(revision e49b799749611ec0efd1eb1a09379f3b62d0d269)
+++ uspace/srv/hid/display/display.h	(revision c11ee60568a19bcfd518a78ce1353442a1120e77)
@@ -50,4 +50,6 @@
 extern errno_t ds_display_create(gfx_context_t *, ds_display_t **);
 extern void ds_display_destroy(ds_display_t *);
+extern void ds_display_lock(ds_display_t *);
+extern void ds_display_unlock(ds_display_t *);
 extern void ds_display_get_info(ds_display_t *, display_info_t *);
 extern void ds_display_add_client(ds_display_t *, ds_client_t *);
Index: uspace/srv/hid/display/dsops.c
===================================================================
--- uspace/srv/hid/display/dsops.c	(revision e49b799749611ec0efd1eb1a09379f3b62d0d269)
+++ uspace/srv/hid/display/dsops.c	(revision c11ee60568a19bcfd518a78ce1353442a1120e77)
@@ -76,8 +76,12 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_create()");
 
+	ds_display_lock(client->display);
+
 	rc = ds_window_create(client, params, &wnd);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_create() - ds_window_create -> %d", rc);
-	if (rc != EOK)
+	if (rc != EOK) {
+		ds_display_unlock(client->display);
 		return rc;
+	}
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_create() -> EOK, id=%zu",
@@ -92,4 +96,6 @@
 	(void) ds_display_paint(wnd->display, NULL);
 
+	ds_display_unlock(client->display);
+
 	*rwnd_id = wnd->id;
 	return EOK;
@@ -101,11 +107,16 @@
 	ds_window_t *wnd;
 
-	wnd = ds_client_find_window(client, wnd_id);
-	if (wnd == NULL)
-		return ENOENT;
+	ds_display_lock(client->display);
+
+	wnd = ds_client_find_window(client, wnd_id);
+	if (wnd == NULL) {
+		ds_display_unlock(client->display);
+		return ENOENT;
+	}
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_destroy()");
 	ds_client_remove_window(wnd);
 	ds_window_destroy(wnd);
+	ds_display_unlock(client->display);
 	return EOK;
 }
@@ -117,10 +128,15 @@
 	ds_window_t *wnd;
 
-	wnd = ds_client_find_window(client, wnd_id);
-	if (wnd == NULL)
-		return ENOENT;
+	ds_display_lock(client->display);
+
+	wnd = ds_client_find_window(client, wnd_id);
+	if (wnd == NULL) {
+		ds_display_unlock(client->display);
+		return ENOENT;
+	}
 
 	log_msg(LVL_NOTE, LVL_DEBUG, "disp_window_move_req()");
 	ds_window_move_req(wnd, pos);
+	ds_display_unlock(client->display);
 	return EOK;
 }
@@ -131,10 +147,15 @@
 	ds_window_t *wnd;
 
-	wnd = ds_client_find_window(client, wnd_id);
-	if (wnd == NULL)
-		return ENOENT;
+	ds_display_lock(client->display);
+
+	wnd = ds_client_find_window(client, wnd_id);
+	if (wnd == NULL) {
+		ds_display_unlock(client->display);
+		return ENOENT;
+	}
 
 	log_msg(LVL_NOTE, LVL_DEBUG, "disp_window_move()");
 	ds_window_move(wnd, pos);
+	ds_display_unlock(client->display);
 	return EOK;
 }
@@ -146,10 +167,15 @@
 	ds_window_t *wnd;
 
-	wnd = ds_client_find_window(client, wnd_id);
-	if (wnd == NULL)
-		return ENOENT;
+	ds_display_lock(client->display);
+
+	wnd = ds_client_find_window(client, wnd_id);
+	if (wnd == NULL) {
+		ds_display_unlock(client->display);
+		return ENOENT;
+	}
 
 	log_msg(LVL_NOTE, LVL_DEBUG, "disp_window_resize_req()");
 	ds_window_resize_req(wnd, rsztype, pos);
+	ds_display_unlock(client->display);
 	return EOK;
 }
@@ -160,11 +186,18 @@
 	ds_client_t *client = (ds_client_t *) arg;
 	ds_window_t *wnd;
-
-	wnd = ds_client_find_window(client, wnd_id);
-	if (wnd == NULL)
-		return ENOENT;
+	errno_t rc;
+
+	ds_display_lock(client->display);
+
+	wnd = ds_client_find_window(client, wnd_id);
+	if (wnd == NULL) {
+		ds_display_unlock(client->display);
+		return ENOENT;
+	}
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "disp_window_resize()");
-	return ds_window_resize(wnd, offs, nbound);
+	rc = ds_window_resize(wnd, offs, nbound);
+	ds_display_unlock(client->display);
+	return rc;
 }
 
@@ -178,9 +211,14 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_get_event()");
 
+	ds_display_lock(client->display);
+
 	rc = ds_client_get_event(client, &wnd, event);
-	if (rc != EOK)
+	if (rc != EOK) {
+		ds_display_unlock(client->display);
 		return rc;
+	}
 
 	*wnd_id = wnd->id;
+	ds_display_unlock(client->display);
 	return EOK;
 }
@@ -192,5 +230,7 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_get_info()");
 
+	ds_display_lock(client->display);
 	ds_display_get_info(client->display, info);
+	ds_display_unlock(client->display);
 	return EOK;
 }
Index: uspace/srv/hid/display/input.c
===================================================================
--- uspace/srv/hid/display/input.c	(revision e49b799749611ec0efd1eb1a09379f3b62d0d269)
+++ uspace/srv/hid/display/input.c	(revision c11ee60568a19bcfd518a78ce1353442a1120e77)
@@ -73,4 +73,5 @@
 	ds_display_t *disp = (ds_display_t *) input->user;
 	kbd_event_t event;
+	errno_t rc;
 
 	event.type = type;
@@ -79,5 +80,8 @@
 	event.c = c;
 
-	return ds_display_post_kbd_event(disp, &event);
+	ds_display_lock(disp);
+	rc = ds_display_post_kbd_event(disp, &event);
+	ds_display_unlock(disp);
+	return rc;
 }
 
@@ -86,4 +90,5 @@
 	ds_display_t *disp = (ds_display_t *) input->user;
 	ptd_event_t event;
+	errno_t rc;
 
 	event.type = PTD_MOVE;
@@ -91,5 +96,8 @@
 	event.dmove.y = dy;
 
-	return ds_display_post_ptd_event(disp, &event);
+	ds_display_lock(disp);
+	rc = ds_display_post_ptd_event(disp, &event);
+	ds_display_unlock(disp);
+	return rc;
 }
 
@@ -99,4 +107,5 @@
 	ds_display_t *disp = (ds_display_t *) input->user;
 	ptd_event_t event;
+	errno_t rc;
 
 	event.type = PTD_ABS_MOVE;
@@ -108,5 +117,8 @@
 	event.abounds.p1.y = max_y + 1;
 
-	return ds_display_post_ptd_event(disp, &event);
+	ds_display_lock(disp);
+	rc = ds_display_post_ptd_event(disp, &event);
+	ds_display_unlock(disp);
+	return rc;
 }
 
@@ -115,4 +127,5 @@
 	ds_display_t *disp = (ds_display_t *) input->user;
 	ptd_event_t event;
+	errno_t rc;
 
 	event.type = bpress ? PTD_PRESS : PTD_RELEASE;
@@ -121,5 +134,8 @@
 	event.dmove.y = 0;
 
-	return ds_display_post_ptd_event(disp, &event);
+	ds_display_lock(disp);
+	rc = ds_display_post_ptd_event(disp, &event);
+	ds_display_unlock(disp);
+	return rc;
 }
 
Index: uspace/srv/hid/display/types/display/display.h
===================================================================
--- uspace/srv/hid/display/types/display/display.h	(revision e49b799749611ec0efd1eb1a09379f3b62d0d269)
+++ uspace/srv/hid/display/types/display/display.h	(revision c11ee60568a19bcfd518a78ce1353442a1120e77)
@@ -38,4 +38,5 @@
 
 #include <adt/list.h>
+#include <fibril_synch.h>
 #include <gfx/color.h>
 #include <gfx/coord.h>
@@ -45,4 +46,6 @@
 /** Display server display */
 typedef struct ds_display {
+	/** Synchronize access to display */
+	fibril_mutex_t lock;
 	/** Clients (of ds_client_t) */
 	list_t clients;
