Index: uspace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision b3b79981fde01c701df88e2e0c5bb93f62cdcf42)
+++ uspace/srv/hid/display/display.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -105,4 +105,6 @@
 	list_initialize(&disp->ddevs);
 	list_initialize(&disp->idevcfgs);
+	list_initialize(&disp->ievents);
+	fibril_condvar_initialize(&disp->ievent_cv);
 	list_initialize(&disp->seats);
 	list_initialize(&disp->windows);
@@ -129,4 +131,5 @@
 	assert(list_empty(&disp->ddevs));
 	assert(list_empty(&disp->idevcfgs));
+	assert(list_empty(&disp->ievents));
 	assert(list_empty(&disp->seats));
 	assert(list_empty(&disp->windows));
Index: uspace/srv/hid/display/ievent.c
===================================================================
--- uspace/srv/hid/display/ievent.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
+++ uspace/srv/hid/display/ievent.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2024 Jiri Svoboda
+ * 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 display
+ * @{
+ */
+/** @file Input event queue
+ */
+
+#include <adt/list.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/kbd_event.h>
+#include <stdlib.h>
+#include "display.h"
+#include "ievent.h"
+
+/** Post keyboard event to input event queue.
+ *
+ * @param disp Display
+ * @param kbd Keyboard event
+ *
+ * @return EOK on success or an error code
+ */
+errno_t ds_ievent_post_kbd(ds_display_t *disp, kbd_event_t *kbd)
+{
+	ds_ievent_t *ievent;
+
+	ievent = calloc(1, sizeof(ds_ievent_t));
+	if (ievent == NULL)
+		return ENOMEM;
+
+	ievent->display = disp;
+	ievent->etype = det_kbd;
+	ievent->ev.kbd = *kbd;
+
+	list_append(&ievent->lievents, &disp->ievents);
+	fibril_condvar_signal(&disp->ievent_cv);
+
+	return EOK;
+}
+
+/** Post pointing device event to input event queue.
+ *
+ * @param disp Display
+ * @param kbd Keyboard event
+ *
+ * @return EOK on success or an error code
+ */
+errno_t ds_ievent_post_ptd(ds_display_t *disp, ptd_event_t *ptd)
+{
+	ds_ievent_t *ievent;
+	ds_ievent_t *prev;
+	link_t *link;
+
+	ievent = calloc(1, sizeof(ds_ievent_t));
+	if (ievent == NULL)
+		return ENOMEM;
+
+	link = list_last(&disp->ievents);
+	if (link != NULL) {
+		prev = list_get_instance(link, ds_ievent_t, lievents);
+		if (prev->etype == det_ptd && prev->ev.ptd.pos_id ==
+		    ptd->pos_id) {
+			/*
+			 * Previous event is also a pointing device event
+			 * and it is from the same device.
+			 */
+			if (prev->ev.ptd.type == PTD_MOVE &&
+			    ptd->type == PTD_MOVE) {
+				/* Both events are relative move events */
+				gfx_coord2_add(&ptd->dmove, &prev->ev.ptd.dmove,
+				    &prev->ev.ptd.dmove);
+				return EOK;
+			} else if (prev->ev.ptd.type == PTD_ABS_MOVE &&
+			    ptd->type == PTD_ABS_MOVE) {
+				/* Both events are absolute move events */
+				prev->ev.ptd.apos = ptd->apos;
+				prev->ev.ptd.abounds = ptd->abounds;
+				return EOK;
+			}
+		}
+	}
+
+	ievent->display = disp;
+	ievent->etype = det_ptd;
+	ievent->ev.ptd = *ptd;
+
+	list_append(&ievent->lievents, &disp->ievents);
+	fibril_condvar_signal(&disp->ievent_cv);
+
+	return EOK;
+}
+
+/** Input event processing fibril.
+ *
+ * @param arg Argument (ds_display_t *)
+ * @return EOK success
+ */
+static errno_t ds_ievent_fibril(void *arg)
+{
+	ds_display_t *disp = (ds_display_t *)arg;
+	ds_ievent_t *ievent;
+	link_t *link;
+
+	fibril_mutex_lock(&disp->lock);
+
+	while (!disp->ievent_quit) {
+		while (list_empty(&disp->ievents))
+			fibril_condvar_wait(&disp->ievent_cv, &disp->lock);
+
+		link = list_first(&disp->ievents);
+		assert(link != NULL);
+		list_remove(link);
+		ievent = list_get_instance(link, ds_ievent_t, lievents);
+
+		switch (ievent->etype) {
+		case det_kbd:
+			(void)ds_display_post_kbd_event(disp, &ievent->ev.kbd);
+			break;
+		case det_ptd:
+			(void)ds_display_post_ptd_event(disp, &ievent->ev.ptd);
+			break;
+		}
+	}
+
+	/* Signal to ds_ievent_fini() that the event processing fibril quit */
+	disp->ievent_done = true;
+	fibril_condvar_signal(&disp->ievent_cv);
+	fibril_mutex_unlock(&disp->lock);
+
+	return EOK;
+}
+
+/** Initialize input event processing.
+ *
+ * @param disp Display
+ * @return EOK on success or an error code
+ */
+errno_t ds_ievent_init(ds_display_t *disp)
+{
+	assert(disp->ievent_fid == 0);
+
+	disp->ievent_fid = fibril_create(ds_ievent_fibril, (void *)disp);
+	if (disp->ievent_fid == 0)
+		return ENOMEM;
+
+	fibril_add_ready(disp->ievent_fid);
+	return EOK;
+}
+
+/** Deinitialize input event processing.
+ *
+ * @param disp Display
+ */
+void ds_ievent_fini(ds_display_t *disp)
+{
+	ds_ievent_t *ievent;
+	link_t *link;
+
+	if (disp->ievent_fid == 0)
+		return;
+
+	/* Signal event processing fibril to quit. */
+	fibril_mutex_lock(&disp->lock);
+	disp->ievent_quit = true;
+	fibril_condvar_signal(&disp->ievent_cv);
+
+	/* Wait for event processing fibril to quit. */
+	while (!disp->ievent_done)
+		fibril_condvar_wait(&disp->ievent_cv, &disp->lock);
+
+	/* Remove all events from the queue. */
+	while (!list_empty(&disp->ievents)) {
+		link = list_first(&disp->ievents);
+		assert(link != NULL);
+		list_remove(link);
+		ievent = list_get_instance(link, ds_ievent_t, lievents);
+		free(ievent);
+	}
+
+	fibril_mutex_unlock(&disp->lock);
+
+	fibril_detach(disp->ievent_fid);
+	disp->ievent_fid = 0;
+}
+
+/** @}
+ */
Index: uspace/srv/hid/display/ievent.h
===================================================================
--- uspace/srv/hid/display/ievent.h	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
+++ uspace/srv/hid/display/ievent.h	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024 Jiri Svoboda
+ * 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 display
+ * @{
+ */
+/** @file Input event queue
+ */
+
+#ifndef IEVENT_H
+#define IEVENT_H
+
+#include <errno.h>
+#include <io/kbd_event.h>
+#include <io/pos_event.h>
+#include "types/display/display.h"
+#include "types/display/ievent.h"
+
+extern errno_t ds_ievent_post_kbd(ds_display_t *, kbd_event_t *);
+extern errno_t ds_ievent_post_ptd(ds_display_t *, ptd_event_t *);
+extern errno_t ds_ievent_init(ds_display_t *);
+extern void ds_ievent_fini(ds_display_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/hid/display/input.c
===================================================================
--- uspace/srv/hid/display/input.c	(revision b3b79981fde01c701df88e2e0c5bb93f62cdcf42)
+++ uspace/srv/hid/display/input.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,4 +40,5 @@
 #include <str_error.h>
 #include "display.h"
+#include "ievent.h"
 #include "input.h"
 #include "main.h"
@@ -87,5 +88,5 @@
 
 	ds_display_lock(disp);
-	rc = ds_display_post_kbd_event(disp, &event);
+	rc = ds_ievent_post_kbd(disp, &event);
 	ds_display_unlock(disp);
 	return rc;
@@ -104,5 +105,5 @@
 
 	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
+	rc = ds_ievent_post_ptd(disp, &event);
 	ds_display_unlock(disp);
 	return rc;
@@ -126,5 +127,5 @@
 
 	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
+	rc = ds_ievent_post_ptd(disp, &event);
 	ds_display_unlock(disp);
 	return rc;
@@ -145,5 +146,5 @@
 
 	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
+	rc = ds_ievent_post_ptd(disp, &event);
 	ds_display_unlock(disp);
 	return rc;
@@ -163,5 +164,5 @@
 
 	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
+	rc = ds_ievent_post_ptd(disp, &event);
 	ds_display_unlock(disp);
 	return rc;
Index: uspace/srv/hid/display/main.c
===================================================================
--- uspace/srv/hid/display/main.c	(revision b3b79981fde01c701df88e2e0c5bb93f62cdcf42)
+++ uspace/srv/hid/display/main.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -54,4 +54,5 @@
 #include "display.h"
 #include "dsops.h"
+#include "ievent.h"
 #include "input.h"
 #include "main.h"
@@ -156,4 +157,8 @@
 	output->def_display = disp;
 	rc = ds_output_start_discovery(output);
+	if (rc != EOK)
+		goto error;
+
+	rc = ds_ievent_init(disp);
 	if (rc != EOK)
 		goto error;
@@ -211,4 +216,5 @@
 		ds_input_close(disp);
 #endif
+	ds_ievent_fini(disp);
 	if (output != NULL)
 		ds_output_destroy(output);
Index: uspace/srv/hid/display/meson.build
===================================================================
--- uspace/srv/hid/display/meson.build	(revision b3b79981fde01c701df88e2e0c5bb93f62cdcf42)
+++ uspace/srv/hid/display/meson.build	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -41,4 +41,5 @@
 	'dsops.c',
 	'idevcfg.c',
+	'ievent.c',
 	'input.c',
 	'main.c',
@@ -59,4 +60,5 @@
 	'display.c',
 	'idevcfg.c',
+	'ievent.c',
 	'seat.c',
 	'window.c',
@@ -67,4 +69,5 @@
 	'test/cursor.c',
 	'test/display.c',
+	'test/ievent.c',
 	'test/main.c',
 	'test/seat.c',
Index: uspace/srv/hid/display/test/ievent.c
===================================================================
--- uspace/srv/hid/display/test/ievent.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
+++ uspace/srv/hid/display/test/ievent.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2024 Jiri Svoboda
+ * 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.
+ */
+
+#include <errno.h>
+#include <io/kbd_event.h>
+#include <pcut/pcut.h>
+
+#include "../display.h"
+#include "../types/display/ptd_event.h"
+#include "../ievent.h"
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(ievent);
+
+/* Test ds_ievent_init() and ds_ievent_fini() */
+PCUT_TEST(ievent_init_fini)
+{
+	ds_display_t *disp;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, df_none, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_ievent_init(disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ds_ievent_fini(disp);
+	ds_display_destroy(disp);
+}
+
+/* Test ds_ievent_post_kbd() */
+PCUT_TEST(ievent_post_kbd)
+{
+	ds_display_t *disp;
+	kbd_event_t kbd;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, df_none, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_ievent_init(disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	kbd.kbd_id = 0;
+	kbd.type = KEY_PRESS;
+	kbd.key = KC_ENTER;
+	kbd.mods = 0;
+	kbd.c = '\0';
+
+	rc = ds_ievent_post_kbd(disp, &kbd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ds_ievent_fini(disp);
+	ds_display_destroy(disp);
+}
+
+/* Test ds_ievent_post_ptd() */
+PCUT_TEST(ievent_post_ptd)
+{
+	ds_display_t *disp;
+	ptd_event_t ptd;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, df_none, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_ievent_init(disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ptd.pos_id = 0;
+	ptd.type = PTD_MOVE;
+	ptd.dmove.x = 0;
+	ptd.dmove.y = 0;
+	ptd.apos.x = 0;
+	ptd.apos.y = 0;
+	ptd.abounds.p0.x = 0;
+	ptd.abounds.p0.y = 0;
+	ptd.abounds.p1.x = 0;
+	ptd.abounds.p1.y = 0;
+
+	rc = ds_ievent_post_ptd(disp, &ptd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ds_ievent_fini(disp);
+	ds_display_destroy(disp);
+}
+
+PCUT_EXPORT(ievent);
Index: uspace/srv/hid/display/test/main.c
===================================================================
--- uspace/srv/hid/display/test/main.c	(revision b3b79981fde01c701df88e2e0c5bb93f62cdcf42)
+++ uspace/srv/hid/display/test/main.c	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -36,4 +36,5 @@
 PCUT_IMPORT(cursor);
 PCUT_IMPORT(display);
+PCUT_IMPORT(ievent);
 PCUT_IMPORT(seat);
 PCUT_IMPORT(window);
Index: uspace/srv/hid/display/types/display/display.h
===================================================================
--- uspace/srv/hid/display/types/display/display.h	(revision b3b79981fde01c701df88e2e0c5bb93f62cdcf42)
+++ uspace/srv/hid/display/types/display/display.h	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -38,4 +38,5 @@
 
 #include <adt/list.h>
+#include <fibril.h>
 #include <fibril_synch.h>
 #include <gfx/color.h>
@@ -93,4 +94,16 @@
 	list_t idevcfgs;
 
+	/** Queue of input events */
+	list_t ievents;
+
+	/** Input event processing fibril ID */
+	fid_t ievent_fid;
+	/** Input event condition variable */
+	fibril_condvar_t ievent_cv;
+	/** Signal input event fibril to quit */
+	bool ievent_quit;
+	/** Input event fibril terminated */
+	bool ievent_done;
+
 	/** Background color */
 	gfx_color_t *bg_color;
Index: uspace/srv/hid/display/types/display/ievent.h
===================================================================
--- uspace/srv/hid/display/types/display/ievent.h	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
+++ uspace/srv/hid/display/types/display/ievent.h	(revision 6fbd1f92649dc315bb22fc0c055f201464f714d7)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2024 Jiri Svoboda
+ * 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 display
+ * @{
+ */
+/**
+ * @file Display server input event types
+ */
+
+#ifndef TYPES_DISPLAY_IEVENT_H
+#define TYPES_DISPLAY_IEVENT_H
+
+#include <adt/list.h>
+#include <io/kbd_event.h>
+#include "ptd_event.h"
+
+/** Display server input event type */
+typedef enum {
+	/** Keyboard event */
+	det_kbd,
+	/** Pointing device event */
+	det_ptd
+} ds_ievent_type_t;
+
+/** Display server input event */
+typedef struct ds_ievent {
+	/** Parent display */
+	struct ds_display *display;
+	/** Link to display->ievents */
+	link_t lievents;
+	/** Input event type */
+	ds_ievent_type_t etype;
+	/** Event data */
+	union {
+		/** Keyboard event */
+		kbd_event_t kbd;
+		/** Pointing device ievent */
+		ptd_event_t ptd;
+	} ev;
+} ds_ievent_t;
+
+#endif
+
+/** @}
+ */
