Index: uspace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision 79949f3bee22fb5dbb32d3b1d9a742ac2f7b12b1)
+++ uspace/srv/hid/display/display.c	(revision 24cf391ab7bf79bde5200b1cd912d7966b81d8b5)
@@ -164,4 +164,27 @@
 }
 
+/** Find window by display position.
+ *
+ * @param display Display
+ * @param pos Display position
+ */
+ds_window_t *ds_display_window_by_pos(ds_display_t *display, gfx_coord2_t *pos)
+{
+	ds_window_t *wnd;
+
+	wnd = ds_display_first_window(display);
+	while (wnd != NULL) {
+		// XXX Need to know window dimensions
+		if (pos->x >= wnd->dpos.x && pos->y >= wnd->dpos.y &&
+		    pos->x <= wnd->dpos.x + 100 && pos->y <= wnd->dpos.y + 100) {
+			return wnd;
+		}
+
+		wnd = ds_display_next_window(wnd);
+	}
+
+	return NULL;
+}
+
 /** Add window to display.
  *
@@ -239,4 +262,35 @@
 }
 
+/** Post position event to a display.
+ *
+ * @param display Display
+ * @param event Event
+ */
+errno_t ds_display_post_pos_event(ds_display_t *display, pos_event_t *event)
+{
+	gfx_coord2_t pos;
+	ds_window_t *wnd;
+	ds_seat_t *seat;
+
+	/* Focus window on button press */
+	if (event->type == POS_PRESS) {
+		printf("Button press\n");
+		pos.x = event->hpos;
+		pos.y = event->vpos;
+
+		wnd = ds_display_window_by_pos(display, &pos);
+		if (wnd != NULL) {
+			seat = ds_display_first_seat(display);
+			if (seat == NULL)
+				return EOK;
+
+			ds_seat_set_focus(seat, wnd);
+			return EOK;
+		}
+	}
+
+	return EOK;
+}
+
 /** Add seat to display.
  *
Index: uspace/srv/hid/display/display.h
===================================================================
--- uspace/srv/hid/display/display.h	(revision 79949f3bee22fb5dbb32d3b1d9a742ac2f7b12b1)
+++ uspace/srv/hid/display/display.h	(revision 24cf391ab7bf79bde5200b1cd912d7966b81d8b5)
@@ -40,4 +40,5 @@
 #include <gfx/context.h>
 #include <io/kbd_event.h>
+#include <io/pos_event.h>
 #include "types/display/client.h"
 #include "types/display/display.h"
@@ -51,4 +52,5 @@
 extern ds_client_t *ds_display_next_client(ds_client_t *);
 extern ds_window_t *ds_display_find_window(ds_display_t *, ds_wnd_id_t);
+extern ds_window_t *ds_display_window_by_pos(ds_display_t *, gfx_coord2_t *);
 extern void ds_display_add_window(ds_display_t *, ds_window_t *);
 extern void ds_display_remove_window(ds_window_t *);
@@ -56,4 +58,5 @@
 extern ds_window_t *ds_display_next_window(ds_window_t *);
 extern errno_t ds_display_post_kbd_event(ds_display_t *, kbd_event_t *);
+extern errno_t ds_display_post_pos_event(ds_display_t *, pos_event_t *);
 extern void ds_display_add_seat(ds_display_t *, ds_seat_t *);
 extern void ds_display_remove_seat(ds_seat_t *);
Index: uspace/srv/hid/display/main.c
===================================================================
--- uspace/srv/hid/display/main.c	(revision 79949f3bee22fb5dbb32d3b1d9a742ac2f7b12b1)
+++ uspace/srv/hid/display/main.c	(revision 24cf391ab7bf79bde5200b1cd912d7966b81d8b5)
@@ -40,4 +40,6 @@
 #include <str_error.h>
 #include <io/log.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
 #include <ipc/services.h>
 #include <ipcgfx/server.h>
@@ -64,6 +66,12 @@
 	ds_display_t *disp = (ds_display_t *) arg;
 
-	printf("display_kbd_event\n");
 	ds_display_post_kbd_event(disp, event);
+}
+
+static void display_pos_event(void *arg, pos_event_t *event)
+{
+	ds_display_t *disp = (ds_display_t *) arg;
+
+	ds_display_post_pos_event(disp, event);
 }
 
@@ -93,5 +101,6 @@
 		goto error;
 
-	rc = output_init(display_kbd_event, (void *) disp, &gc);
+	rc = output_init(display_kbd_event, (void *) disp,
+	    display_pos_event, (void *) disp, &gc);
 	if (rc != EOK)
 		goto error;
Index: uspace/srv/hid/display/output.c
===================================================================
--- uspace/srv/hid/display/output.c	(revision 79949f3bee22fb5dbb32d3b1d9a742ac2f7b12b1)
+++ uspace/srv/hid/display/output.c	(revision 24cf391ab7bf79bde5200b1cd912d7966b81d8b5)
@@ -37,4 +37,6 @@
 #include <gfx/context.h>
 #include <guigfx/canvas.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -44,4 +46,6 @@
 static void (*kbd_ev_handler)(void *, kbd_event_t *);
 static void *kbd_ev_arg;
+static void (*pos_ev_handler)(void *, pos_event_t *);
+static void *pos_ev_arg;
 
 static void on_keyboard_event(widget_t *widget, void *data)
@@ -51,6 +55,12 @@
 }
 
+static void on_position_event(widget_t *widget, void *data)
+{
+	pos_ev_handler(pos_ev_arg, (pos_event_t *) data);
+}
+
 errno_t output_init(void (*kbd_event_handler)(void *, kbd_event_t *),
-    void *arg, gfx_context_t **rgc)
+    void *karg, void (*pos_event_handler)(void *, pos_event_t *),
+    void *parg, gfx_context_t **rgc)
 {
 	canvas_gc_t *cgc = NULL;
@@ -64,5 +74,8 @@
 	printf("Init canvas..\n");
 	kbd_ev_handler = kbd_event_handler;
-	kbd_ev_arg = arg;
+	kbd_ev_arg = karg;
+
+	pos_ev_handler = pos_event_handler;
+	pos_ev_arg = parg;
 
 	window = window_open("comp:0/winreg", NULL,
@@ -96,4 +109,5 @@
 
 	sig_connect(&canvas->keyboard_event, NULL, on_keyboard_event);
+	sig_connect(&canvas->position_event, NULL, on_position_event);
 
 	window_resize(window, 0, 0, vw + 10, vh + 30, WINDOW_PLACEMENT_ANY);
Index: uspace/srv/hid/display/output.h
===================================================================
--- uspace/srv/hid/display/output.h	(revision 79949f3bee22fb5dbb32d3b1d9a742ac2f7b12b1)
+++ uspace/srv/hid/display/output.h	(revision 24cf391ab7bf79bde5200b1cd912d7966b81d8b5)
@@ -38,6 +38,9 @@
 
 #include <gfx/context.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
 
 extern errno_t output_init(void (*)(void *, kbd_event_t *), void *,
+    void (*)(void *, pos_event_t *), void *,
     gfx_context_t **);
 
Index: uspace/srv/hid/display/test/display.c
===================================================================
--- uspace/srv/hid/display/test/display.c	(revision 79949f3bee22fb5dbb32d3b1d9a742ac2f7b12b1)
+++ uspace/srv/hid/display/test/display.c	(revision 24cf391ab7bf79bde5200b1cd912d7966b81d8b5)
@@ -140,4 +140,49 @@
 }
 
+/** Test ds_display_window_by_pos(). */
+PCUT_TEST(display_window_by_pos)
+{
+	ds_display_t *disp;
+	ds_client_t *client;
+	ds_window_t *w0;
+	ds_window_t *w1;
+	ds_window_t *wnd;
+	gfx_coord2_t pos;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_window_create(client, &w0);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_window_create(client, &w1);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	w0->dpos.x = 10;
+	w0->dpos.y = 10;
+
+	w1->dpos.x = 400;
+	w1->dpos.y = 400;
+
+	pos.x = 10;
+	pos.y = 10;
+	wnd = ds_display_window_by_pos(disp, &pos);
+	PCUT_ASSERT_EQUALS(w0, wnd);
+
+	pos.x = 400;
+	pos.y = 400;
+	wnd = ds_display_window_by_pos(disp, &pos);
+	PCUT_ASSERT_EQUALS(w1, wnd);
+
+	ds_window_destroy(w0);
+	ds_window_destroy(w1);
+	ds_client_destroy(client);
+	ds_display_destroy(disp);
+}
+
 /** Basic seat operation. */
 PCUT_TEST(display_seat)
@@ -164,5 +209,6 @@
 }
 
-/** Test ds_display_post_kbd_event(). */
+/** Test ds_display_post_kbd_event() delivers event to client callback.
+ */
 PCUT_TEST(display_post_kbd_event)
 {
@@ -172,5 +218,5 @@
 	ds_window_t *wnd;
 	kbd_event_t event;
-	bool called_cb = NULL;
+	bool called_cb = false;
 	errno_t rc;
 
@@ -206,3 +252,123 @@
 }
 
+/** Test ds_display_post_kbd_event() with Alt-Tab switches focus.
+ */
+PCUT_TEST(display_post_kbd_event_alt_tab)
+{
+	ds_display_t *disp;
+	ds_seat_t *seat;
+	ds_client_t *client;
+	ds_window_t *w0, *w1;
+	kbd_event_t event;
+	bool called_cb = false;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_seat_create(disp, &seat);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_window_create(client, &w0);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_window_create(client, &w1);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ds_seat_set_focus(seat, w0);
+
+	event.type = KEY_PRESS;
+	event.key = KC_TAB;
+	event.mods = KM_ALT;
+	event.c = L'\0';
+
+	PCUT_ASSERT_FALSE(called_cb);
+
+	rc = ds_display_post_kbd_event(disp, &event);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_FALSE(called_cb);
+
+	/* Next window should be focused */
+	PCUT_ASSERT_EQUALS(w1, seat->focus);
+
+	rc = ds_display_post_kbd_event(disp, &event);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_FALSE(called_cb);
+
+	/* Focus should be back to the first window */
+	PCUT_ASSERT_EQUALS(w0, seat->focus);
+
+	ds_window_destroy(w0);
+	ds_window_destroy(w1);
+	ds_client_destroy(client);
+	ds_seat_destroy(seat);
+	ds_display_destroy(disp);
+}
+
+/** Test ds_display_post_pos_event() with click on window switches focus
+ */
+PCUT_TEST(display_post_pos_event_wnd_switch)
+{
+	ds_display_t *disp;
+	ds_seat_t *seat;
+	ds_client_t *client;
+	ds_window_t *w0, *w1;
+	pos_event_t event;
+	bool called_cb = false;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_seat_create(disp, &seat);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_window_create(client, &w0);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_window_create(client, &w1);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	w0->dpos.x = 10;
+	w0->dpos.y = 10;
+
+	w1->dpos.x = 400;
+	w1->dpos.y = 400;
+
+	ds_seat_set_focus(seat, w0);
+
+	event.type = POS_PRESS;
+	event.btn_num = 1;
+
+	PCUT_ASSERT_FALSE(called_cb);
+
+	event.hpos = 400;
+	event.vpos = 400;
+	rc = ds_display_post_pos_event(disp, &event);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_FALSE(called_cb);
+
+	PCUT_ASSERT_EQUALS(w1, seat->focus);
+
+	event.hpos = 10;
+	event.vpos = 10;
+	rc = ds_display_post_pos_event(disp, &event);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_FALSE(called_cb);
+
+	PCUT_ASSERT_EQUALS(w0, seat->focus);
+
+	ds_window_destroy(w0);
+	ds_window_destroy(w1);
+	ds_client_destroy(client);
+	ds_seat_destroy(seat);
+	ds_display_destroy(disp);
+}
+
 PCUT_EXPORT(display);
