Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ HelenOS.config	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -608,10 +608,4 @@
 ! [(PLATFORM=ia32|PLATFORM=amd64|MACHINE=beagleboardxm)&CONFIG_HID_OUT!=none&CONFIG_FB=y] CONFIG_BFB_BPP (choice)
 
-% Display double buffering
-! [CONFIG_FB=y] CONFIG_DISP_DOUBLE_BUF (y/n)
-
-% Window double buffering
-! [CONFIG_FB=y] CONFIG_WIN_DOUBLE_BUF (n/y)
-
 % Start AP processors by the loader
 ! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
Index: abi/include/abi/ipc/interfaces.h
===================================================================
--- abi/include/abi/ipc/interfaces.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ abi/include/abi/ipc/interfaces.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -112,6 +112,10 @@
 	INTERFACE_OUTPUT =
 	    FOURCC_COMPACT('o', 'u', 'd', 'v') | IFACE_EXCHANGE_SERIALIZE,
+	INTERFACE_COMPOSITOR =
+	    FOURCC_COMPACT('c', 'm', 'p', 's') | IFACE_EXCHANGE_SERIALIZE,
 	INTERFACE_HOUND =
 	    FOURCC_COMPACT('h', 'o', 'u', 'n') | IFACE_EXCHANGE_PARALLEL,
+	INTERFACE_VISUALIZER_CB =
+	    FOURCC_COMPACT('v', 's', 'd', 'v') | IFACE_EXCHANGE_PARALLEL | IFACE_MOD_CALLBACK,
 	INTERFACE_LOC_SUPPLIER =
 	    FOURCC_COMPACT('l', 'o', 'c', 's') | IFACE_EXCHANGE_SERIALIZE,
@@ -183,13 +187,5 @@
 	    FOURCC_COMPACT('i', 'p', 'c', 't') | IFACE_EXCHANGE_SERIALIZE,
 	INTERFACE_PCI =
-	    FOURCC_COMPACT('p', 'c', 'i', ' ') | IFACE_EXCHANGE_SERIALIZE,
-	INTERFACE_DDEV =
-	    FOURCC_COMPACT('d', 'd', 'e', 'v') | IFACE_EXCHANGE_SERIALIZE,
-	INTERFACE_DISPLAY =
-	    FOURCC_COMPACT('d', 's', 'p', 'l') | IFACE_EXCHANGE_SERIALIZE,
-	INTERFACE_DISPLAY_CB =
-	    FOURCC_COMPACT('d', 's', 'p', 'l') | IFACE_EXCHANGE_SERIALIZE | IFACE_MOD_CALLBACK,
-	INTERFACE_GC =
-	    FOURCC_COMPACT('g', 'f', 'x', 'c') | IFACE_EXCHANGE_SERIALIZE,
+	    FOURCC_COMPACT('p', 'c', 'i', ' ') | IFACE_EXCHANGE_SERIALIZE
 } iface_t;
 
Index: meson/part/initrd_manifest/meson.build
===================================================================
--- meson/part/initrd_manifest/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ meson/part/initrd_manifest/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -63,5 +63,5 @@
 		'app/vterm',
 
-		'srv/hid/display',
+		'srv/hid/compositor',
 	]
 endif
Index: tools/export.sh
===================================================================
--- tools/export.sh	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ tools/export.sh	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -41,8 +41,5 @@
 	uspace/lib/libmath.a \
 	uspace/lib/libclui.a \
-	uspace/lib/libdisplay.a \
-	uspace/lib/libgfx.a \
 	uspace/lib/libgui.a \
-	uspace/lib/libipcgfx.a \
 	uspace/lib/libdraw.a \
 	uspace/lib/libsoftrend.a \
Index: tools/xcw/bin/helenos-pkg-config
===================================================================
--- tools/xcw/bin/helenos-pkg-config	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ tools/xcw/bin/helenos-pkg-config	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -44,6 +44,6 @@
 libmath_libs="$LIB_DIR/libmath.a"
 
-libgui_cflags="-I$INCLUDE_DIR/libgui -I$INCLUDE_DIR/libdisplay -I$INCLUDE_DIR/libgfx -I$INCLUDE_DIR/libipcgfx"
-libgui_libs="$LIB_DIR/libgui.a $LIB_DIR/libdisplay.a $LIB_DIR/libipcgfx.a $LIB_DIR/libgfx.a"
+libgui_cflags="-I$INCLUDE_DIR/libgui"
+libgui_libs="$LIB_DIR/libgui.a"
 
 libdraw_cflags="-I$INCLUDE_DIR/libdraw"
@@ -55,13 +55,4 @@
 libpcm_cflags="-I$INCLUDE_DIR/libpcm"
 libpcm_libs="$LIB_DIR/libpcm.a"
-
-libgfx_cflags="-I$INCLUDE_DIR/libgfx"
-libgfx_libs="$LIB_DIR/libgfx.a"
-
-libipcgfx_cflags="-I$INCLUDE_DIR/libipcgfx"
-libipcgfx_libs="$LIB_DIR/libipcgfx.a"
-
-libdisplay_cflags="-I$INCLUDE_DIR/libdisplay"
-libdisplay_libs="$LIB_DIR/libdisplay.a"
 
 action=none
@@ -80,7 +71,4 @@
 	    (libhound) ;;
 	    (libpcm) ;;
-	    (libgfx) ;;
-	    (libipcgfx) ;;
-	    (libdisplay) ;;
 	    (*) echo "Unknown package $1" >&2; exit 1;;
 	    esac
Index: pace/app/gfxdemo/doc/doxygroups.h
===================================================================
--- uspace/app/gfxdemo/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup vdemo vdemo
- * @brief Demo application
- * @ingroup apps
- */
Index: pace/app/gfxdemo/gfxdemo.c
===================================================================
--- uspace/app/gfxdemo/gfxdemo.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,646 +1,0 @@
-/*
- * Copyright (c) 2019 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 gfxdemo
- * @{
- */
-/** @file Graphic demo
- */
-
-#include <canvas.h>
-#include <congfx/console.h>
-#include <draw/surface.h>
-#include <display.h>
-#include <fibril.h>
-#include <guigfx/canvas.h>
-#include <gfx/bitmap.h>
-#include <gfx/color.h>
-#include <gfx/render.h>
-#include <io/console.h>
-#include <io/pixelmap.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <str.h>
-#include <task.h>
-#include <window.h>
-
-static void wnd_close_event(void *);
-static void wnd_kbd_event(void *, kbd_event_t *);
-
-static display_wnd_cb_t wnd_cb = {
-	.close_event = wnd_close_event,
-	.kbd_event = wnd_kbd_event
-};
-
-static bool quit = false;
-
-/** Clear screen.
- *
- * @param gc Graphic context
- * @param w Screen width
- * @param h Screen height
- */
-static errno_t clear_scr(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
-{
-	gfx_color_t *color = NULL;
-	gfx_rect_t rect;
-	errno_t rc;
-
-	rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_set_color(gc, color);
-	if (rc != EOK)
-		goto error;
-
-	rect.p0.x = 0;
-	rect.p0.y = 0;
-	rect.p1.x = w;
-	rect.p1.y = h;
-
-	rc = gfx_fill_rect(gc, &rect);
-	if (rc != EOK)
-		goto error;
-
-	gfx_color_delete(color);
-	return EOK;
-error:
-	if (color != NULL)
-		gfx_color_delete(color);
-	return rc;
-}
-
-/** Run rectangle demo on a graphic context.
- *
- * @param gc Graphic context
- * @param w Width
- * @param h Height
- */
-static errno_t demo_rects(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
-{
-	gfx_color_t *color = NULL;
-	gfx_rect_t rect;
-	int i, j;
-	errno_t rc;
-
-	rc = clear_scr(gc, w, h);
-	if (rc != EOK)
-		return rc;
-
-	for (j = 0; j < 10; j++) {
-		rc = gfx_color_new_rgb_i16(rand() % 0x10000, rand() % 0x10000,
-		    rand() % 0x10000, &color);
-		if (rc != EOK)
-			return rc;
-
-		rc = gfx_set_color(gc, color);
-		if (rc != EOK)
-			return rc;
-
-		for (i = 0; i < 10; i++) {
-			rect.p0.x = rand() % (w - 1);
-			rect.p0.y = rand() % (h - 1);
-			rect.p1.x = rect.p0.x + rand() % (w - 1 - rect.p0.x);
-			rect.p1.y = rect.p0.y + rand() % (h - 1 - rect.p0.y);
-
-			rc = gfx_fill_rect(gc, &rect);
-			if (rc != EOK)
-				return rc;
-		}
-
-		gfx_color_delete(color);
-
-		fibril_usleep(500 * 1000);
-
-		if (quit)
-			break;
-	}
-
-	return EOK;
-}
-
-/** Fill bitmap with tartan pattern.
- *
- * @param bitmap Bitmap
- * @param w Bitmap width
- * @param h Bitmap height
- * @return EOK on success or an error code
- */
-static errno_t bitmap_tartan(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
-{
-	int i, j;
-	pixelmap_t pixelmap;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	if (rc != EOK)
-		return rc;
-
-	/* In absence of anything else, use pixelmap */
-	pixelmap.width = w;
-	pixelmap.height = h;
-	pixelmap.data = alloc.pixels;
-
-	for (i = 0; i < w; i++) {
-		for (j = 0; j < h; j++) {
-			pixelmap_put_pixel(&pixelmap, i, j,
-			    PIXEL(255, (i % 30) < 3 ? 255 : 0,
-			    (j % 30) < 3 ? 255 : 0, i / 2));
-		}
-	}
-
-	return EOK;
-}
-
-/** Fill bitmap with moire pattern.
- *
- * @param bitmap Bitmap
- * @param w Bitmap width
- * @param h Bitmap height
- * @return EOK on success or an error code
- */
-static errno_t bitmap_moire(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
-{
-	int i, j;
-	int k;
-	pixelmap_t pixelmap;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	if (rc != EOK)
-		return rc;
-
-	/* In absence of anything else, use pixelmap */
-	pixelmap.width = w;
-	pixelmap.height = h;
-	pixelmap.data = alloc.pixels;
-
-	for (i = 0; i < w; i++) {
-		for (j = 0; j < h; j++) {
-			k = i * i + j * j;
-			pixelmap_put_pixel(&pixelmap, i, j,
-			    PIXEL(255, k, k, k));
-		}
-	}
-
-	return EOK;
-}
-
-/** Render circle to a bitmap.
- *
- * @param bitmap Bitmap
- * @param w Bitmap width
- * @param h Bitmap height
- * @return EOK on success or an error code
- */
-static errno_t bitmap_circle(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
-{
-	int i, j;
-	int k;
-	pixelmap_t pixelmap;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	if (rc != EOK)
-		return rc;
-
-	/* In absence of anything else, use pixelmap */
-	pixelmap.width = w;
-	pixelmap.height = h;
-	pixelmap.data = alloc.pixels;
-
-	for (i = 0; i < w; i++) {
-		for (j = 0; j < h; j++) {
-			k = i * i + j * j;
-			pixelmap_put_pixel(&pixelmap, i, j,
-			    k < w * w / 2 ? PIXEL(255, 0, 255, 0) :
-			    PIXEL(0, 255, 0, 255));
-		}
-	}
-
-	return EOK;
-}
-
-/** Run bitmap demo on a graphic context.
- *
- * @param gc Graphic context
- * @param w Width
- * @param h Height
- */
-static errno_t demo_bitmap(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
-{
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_params_t params;
-	int i, j;
-	gfx_coord2_t offs;
-	gfx_rect_t srect;
-	errno_t rc;
-
-	rc = clear_scr(gc, w, h);
-	if (rc != EOK)
-		return rc;
-
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p1.x = w;
-	params.rect.p1.y = h;
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	if (rc != EOK)
-		return rc;
-
-	rc = bitmap_tartan(bitmap, w, h);
-	if (rc != EOK)
-		goto error;
-
-	for (j = 0; j < 10; j++) {
-		for (i = 0; i < 5; i++) {
-			srect.p0.x = rand() % (w - 40);
-			srect.p0.y = rand() % (h - 20);
-			srect.p1.x = srect.p0.x + rand() % (w - srect.p0.x);
-			srect.p1.y = srect.p0.y + rand() % (h - srect.p0.y);
-			offs.x = 0;
-			offs.y = 0;
-
-			rc = gfx_bitmap_render(bitmap, &srect, &offs);
-			if (rc != EOK)
-				goto error;
-			fibril_usleep(250 * 1000);
-
-			if (quit)
-				break;
-		}
-	}
-
-	gfx_bitmap_destroy(bitmap);
-
-	return EOK;
-error:
-	gfx_bitmap_destroy(bitmap);
-	return rc;
-}
-
-/** Run second bitmap demo on a graphic context.
- *
- * @param gc Graphic context
- * @param w Width
- * @param h Height
- */
-static errno_t demo_bitmap2(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
-{
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_params_t params;
-	int i, j;
-	gfx_coord2_t offs;
-	errno_t rc;
-
-	rc = clear_scr(gc, w, h);
-	if (rc != EOK)
-		return rc;
-
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p1.x = 40;
-	params.rect.p1.y = 20;
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	if (rc != EOK)
-		return rc;
-
-	rc = bitmap_moire(bitmap, 40, 20);
-	if (rc != EOK)
-		goto error;
-
-	for (j = 0; j < 10; j++) {
-		for (i = 0; i < 10; i++) {
-			offs.x = rand() % (w - 40);
-			offs.y = rand() % (h - 20);
-
-			rc = gfx_bitmap_render(bitmap, NULL, &offs);
-			if (rc != EOK)
-				goto error;
-		}
-
-		fibril_usleep(500 * 1000);
-
-		if (quit)
-			break;
-	}
-
-	gfx_bitmap_destroy(bitmap);
-
-	return EOK;
-error:
-	gfx_bitmap_destroy(bitmap);
-	return rc;
-}
-/** Run bitmap color key demo on a graphic context.
- *
- * @param gc Graphic context
- * @param w Width
- * @param h Height
- */
-static errno_t demo_bitmap_kc(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
-{
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_params_t params;
-	int i, j;
-	gfx_coord2_t offs;
-	errno_t rc;
-
-	rc = clear_scr(gc, w, h);
-	if (rc != EOK)
-		return rc;
-
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p1.x = 40;
-	params.rect.p1.y = 40;
-	params.flags = bmpf_color_key;
-	params.key_color = PIXEL(0, 255, 0, 255);
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	if (rc != EOK)
-		return rc;
-
-	rc = bitmap_circle(bitmap, 40, 40);
-	if (rc != EOK)
-		goto error;
-
-	for (j = 0; j < 10; j++) {
-		for (i = 0; i < 10; i++) {
-			offs.x = j * 20 + i * 20;
-			offs.y = i * 20;
-
-			rc = gfx_bitmap_render(bitmap, NULL, &offs);
-			if (rc != EOK)
-				goto error;
-		}
-
-		fibril_usleep(500 * 1000);
-
-		if (quit)
-			break;
-	}
-
-	gfx_bitmap_destroy(bitmap);
-
-	return EOK;
-error:
-	gfx_bitmap_destroy(bitmap);
-	return rc;
-}
-
-/** Run demo loop on a graphic context.
- *
- * @param gc Graphic context
- * @param w Width
- * @param h Height
- */
-static errno_t demo_loop(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
-{
-	errno_t rc;
-
-	while (!quit) {
-		rc = demo_rects(gc, w, h);
-		if (rc != EOK)
-			return rc;
-
-		rc = demo_bitmap(gc, w, h);
-		if (rc != EOK)
-			return rc;
-
-		rc = demo_bitmap2(gc, w, h);
-		if (rc != EOK)
-			return rc;
-
-		rc = demo_bitmap_kc(gc, w, h);
-		if (rc != EOK)
-			return rc;
-	}
-
-	return EOK;
-}
-
-/** Run demo on console. */
-static errno_t demo_console(void)
-{
-	console_ctrl_t *con = NULL;
-	console_gc_t *cgc = NULL;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	printf("Init console..\n");
-	con = console_init(stdin, stdout);
-	if (con == NULL)
-		return EIO;
-
-	printf("Create console GC\n");
-	rc = console_gc_create(con, stdout, &cgc);
-	if (rc != EOK)
-		return rc;
-
-	gc = console_gc_get_ctx(cgc);
-
-	rc = demo_loop(gc, 80, 25);
-	if (rc != EOK)
-		return rc;
-
-	rc = console_gc_delete(cgc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Run demo on canvas. */
-static errno_t demo_canvas(void)
-{
-	canvas_gc_t *cgc = NULL;
-	gfx_context_t *gc;
-	window_t *window = NULL;
-	pixel_t *pixbuf = NULL;
-	surface_t *surface = NULL;
-	canvas_t *canvas = NULL;
-	gfx_coord_t vw, vh;
-	errno_t rc;
-
-	printf("Init canvas..\n");
-
-	window = window_open(DISPLAY_DEFAULT, NULL,
-	    WINDOW_MAIN | WINDOW_DECORATED, "GFX Demo");
-	if (window == NULL) {
-		printf("Error creating window.\n");
-		return -1;
-	}
-
-	vw = 400;
-	vh = 300;
-
-	pixbuf = calloc(vw * vh, sizeof(pixel_t));
-	if (pixbuf == NULL) {
-		printf("Error allocating memory for pixel buffer.\n");
-		return ENOMEM;
-	}
-
-	surface = surface_create(vw, vh, pixbuf, 0);
-	if (surface == NULL) {
-		printf("Error creating surface.\n");
-		return EIO;
-	}
-
-	canvas = create_canvas(window_root(window), NULL, vw, vh,
-	    surface);
-	if (canvas == NULL) {
-		printf("Error creating canvas.\n");
-		return EIO;
-	}
-
-	window_resize(window, 0, 0, vw + 10, vh + 30, WINDOW_PLACEMENT_ANY);
-	window_exec(window);
-
-	printf("Create canvas GC\n");
-	rc = canvas_gc_create(canvas, surface, &cgc);
-	if (rc != EOK)
-		return rc;
-
-	gc = canvas_gc_get_ctx(cgc);
-
-	task_retval(0);
-
-	rc = demo_loop(gc, 400, 300);
-	if (rc != EOK)
-		return rc;
-
-	rc = canvas_gc_delete(cgc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Run demo on display server. */
-static errno_t demo_display(void)
-{
-	display_t *display = NULL;
-	gfx_context_t *gc;
-	display_wnd_params_t params;
-	display_window_t *window = NULL;
-	errno_t rc;
-
-	printf("Init display..\n");
-
-	rc = display_open(DISPLAY_DEFAULT, &display);
-	if (rc != EOK) {
-		printf("Error opening display.\n");
-		return rc;
-	}
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p1.x = 400;
-	params.rect.p1.y = 300;
-
-	rc = display_window_create(display, &params, &wnd_cb, NULL, &window);
-	if (rc != EOK) {
-		printf("Error creating window.\n");
-		return rc;
-	}
-
-	rc = display_window_get_gc(window, &gc);
-	if (rc != EOK) {
-		printf("Error getting graphics context.\n");
-		return rc;
-	}
-
-	task_retval(0);
-
-	rc = demo_loop(gc, 400, 300);
-	if (rc != EOK)
-		return rc;
-
-	rc = gfx_context_delete(gc);
-	if (rc != EOK)
-		return rc;
-
-	display_window_destroy(window);
-	display_close(display);
-
-	return EOK;
-}
-
-static void wnd_close_event(void *arg)
-{
-	printf("Close event\n");
-	quit = true;
-}
-
-static void wnd_kbd_event(void *arg, kbd_event_t *event)
-{
-	printf("Keyboard event type=%d key=%d\n", event->type, event->key);
-	if (event->type == KEY_PRESS)
-		quit = true;
-}
-
-static void print_syntax(void)
-{
-	printf("syntax: gfxdemo {canvas|console|display}\n");
-}
-
-int main(int argc, char *argv[])
-{
-	errno_t rc;
-
-	if (argc < 2 || str_cmp(argv[1], "display") == 0) {
-		rc = demo_display();
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "console") == 0) {
-		rc = demo_console();
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "canvas") == 0) {
-		rc = demo_canvas();
-		if (rc != EOK)
-			return 1;
-	} else {
-		print_syntax();
-		return 1;
-	}
-}
-
-/** @}
- */
Index: pace/app/gfxdemo/meson.build
===================================================================
--- uspace/app/gfxdemo/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,32 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'gfx', 'guigfx', 'congfx', 'ipcgfx', 'display' ]
-src = files(
-	'gfxdemo.c',
-)
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/app/init/init.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -34,5 +34,4 @@
  */
 
-#include <fibril.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -48,5 +47,4 @@
 #include <config.h>
 #include <io/logctl.h>
-#include <vfs/vfs.h>
 #include <vol.h>
 #include "untar.h"
@@ -68,9 +66,9 @@
 #define APP_GETTERM  "/app/getterm"
 
-#define SRV_DISPLAY  "/srv/hid/display"
-#define DISPLAY_SVC  "hid/display"
+#define SRV_COMPOSITOR  "/srv/hid/compositor"
 
 #define HID_INPUT              "hid/input"
 #define HID_OUTPUT             "hid/output"
+#define HID_COMPOSITOR_SERVER  ":0"
 
 #define srv_start(path, ...) \
@@ -273,21 +271,33 @@
 }
 
-static errno_t display_server(void)
-{
-	return srv_start(SRV_DISPLAY);
-}
-
-static int gui_start(const char *app, const char *display_svc)
-{
-	printf("%s: Spawning %s\n", NAME, app);
+static errno_t compositor(const char *isvc, const char *name)
+{
+	/* Wait for the input service to be ready */
+	service_id_t service_id;
+	errno_t rc = loc_service_get_id(isvc, &service_id, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Error waiting on %s (%s)\n", NAME, isvc,
+		    str_error(rc));
+		return rc;
+	}
+
+	return srv_start(SRV_COMPOSITOR, isvc, name);
+}
+
+static int gui_start(const char *app, const char *srv_name)
+{
+	char winreg[50];
+	snprintf(winreg, sizeof(winreg), "%s%s%s", "comp", srv_name, "/winreg");
+
+	printf("%s: Spawning %s %s\n", NAME, app, winreg);
 
 	task_id_t id;
 	task_wait_t wait;
-	errno_t rc = task_spawnl(&id, &wait, app, app, display_svc, NULL);
+	errno_t rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
 	if (rc != EOK) {
 		oom_check(rc, app);
-		printf("%s: Error spawning %s (%s)\n", NAME, app,
-		    str_error(rc));
-		return -1;
+		printf("%s: Error spawning %s %s (%s)\n", NAME, app,
+		    winreg, str_error(rc));
+		return rc;
 	}
 
@@ -470,9 +480,9 @@
 
 	if (!config_key_exists("console")) {
-		rc = display_server();
+		rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
 		if (rc == EOK) {
-			gui_start("/app/barber", DISPLAY_SVC);
-			gui_start("/app/vlaunch", DISPLAY_SVC);
-			gui_start("/app/vterm", DISPLAY_SVC);
+			gui_start("/app/barber", HID_COMPOSITOR_SERVER);
+			gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
+			gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
 		}
 	}
Index: uspace/app/meson.build
===================================================================
--- uspace/app/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/app/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -45,5 +45,4 @@
 	'fontviewer',
 	'getterm',
-	'gfxdemo',
 	'gunzip',
 	'hbench',
Index: uspace/app/vterm/vterm.c
===================================================================
--- uspace/app/vterm/vterm.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/app/vterm/vterm.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -56,6 +56,5 @@
 	}
 
-	window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_TOP |
-	    WINDOW_PLACEMENT_LEFT);
+	window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_ANY);
 	terminal_t *terminal_widget =
 	    create_terminal(window_root(main_window), NULL, 640, 480);
Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -1,4 +1,3 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
  * Copyright (c) 2013 Jan Vesely
  * All rights reserved.
@@ -36,14 +35,9 @@
 
 #include <align.h>
-#include <as.h>
 #include <assert.h>
 #include <errno.h>
-#include <ddev_srv.h>
-#include <ddev/info.h>
-#include <ddf/driver.h>
 #include <ddf/log.h>
 #include <ddi.h>
-#include <gfx/color.h>
-#include <io/pixelmap.h>
+#include <as.h>
 
 #include "amdm37x_dispc.h"
@@ -61,30 +55,20 @@
 #endif
 
-static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned,
-    visual_t);
-
-static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
-static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *);
-
-static errno_t amdm37x_gc_set_color(void *, gfx_color_t *);
-static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t amdm37x_gc_bitmap_destroy(void *);
-static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-ddev_ops_t amdm37x_ddev_ops = {
-	.get_gc = amdm37x_ddev_get_gc,
-	.get_info = amdm37x_ddev_get_info
-};
-
-gfx_context_ops_t amdm37x_gc_ops = {
-	.set_color = amdm37x_gc_set_color,
-	.fill_rect = amdm37x_gc_fill_rect,
-	.bitmap_create = amdm37x_gc_bitmap_create,
-	.bitmap_destroy = amdm37x_gc_bitmap_destroy,
-	.bitmap_render = amdm37x_gc_bitmap_render,
-	.bitmap_get_alloc = amdm37x_gc_bitmap_get_alloc
+static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
+static errno_t handle_damage(visualizer_t *vs,
+    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
+    sysarg_t x_offset, sysarg_t y_offset);
+static errno_t dummy(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static const visualizer_ops_t amdm37x_dispc_vis_ops = {
+	.change_mode = change_mode,
+	.handle_damage = handle_damage,
+	.claim = dummy,
+	.yield = dummy,
+	.suspend = dummy,
+	.wakeup = dummy,
 };
 
@@ -110,7 +94,27 @@
 };
 
-errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun)
-{
-	instance->fun = fun;
+static void mode_init(vslmode_list_element_t *mode,
+    unsigned width, unsigned height, visual_t visual)
+{
+	mode->mode.index = 0;
+	mode->mode.version = 0;
+	mode->mode.refresh_rate = 0;
+	mode->mode.screen_aspect.width = width;
+	mode->mode.screen_aspect.height = height;
+	mode->mode.screen_width = width;
+	mode->mode.screen_height = height;
+	mode->mode.cell_aspect.width = 1;
+	mode->mode.cell_aspect.height = 1;
+	mode->mode.cell_visual.pixel_visual = visual;
+
+	link_initialize(&mode->link);
+
+}
+
+errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
+{
+	assert(instance);
+	assert(vis);
+
 	instance->fb_data = NULL;
 	instance->size = 0;
@@ -141,8 +145,12 @@
 	}
 
-	ret = amdm37x_change_mode(instance, CONFIG_BFB_WIDTH,
-	    CONFIG_BFB_HEIGHT, visual);
-	if (ret != EOK)
-		return EIO;
+	mode_init(&instance->modes[0],
+	    CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, visual);
+
+	/* Handle vis stuff */
+	vis->dev_ctx = instance;
+	vis->def_mode_idx = 0;
+	vis->ops = amdm37x_dispc_vis_ops;
+	list_append(&instance->modes[0].link, &vis->modes);
 
 	return EOK;
@@ -261,10 +269,16 @@
 }
 
-static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x,
-    unsigned y, visual_t visual)
-{
+static errno_t change_mode(visualizer_t *vis, vslmode_t mode)
+{
+	assert(vis);
+	assert(vis->dev_ctx);
+
+	amdm37x_dispc_t *dispc = vis->dev_ctx;
+	const visual_t visual = mode.cell_visual.pixel_visual;
 	assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
 	const unsigned bpp = pixel2visual_table[visual].bpp;
 	pixel2visual_t p2v = pixel2visual_table[visual].func;
+	const unsigned x = mode.screen_width;
+	const unsigned y = mode.screen_height;
 	ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8);
 	const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
@@ -282,4 +296,5 @@
 	dispc->fb_data = buffer;
 	amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa);
+	dispc->active_fb.idx = mode.index;
 	dispc->active_fb.width = x;
 	dispc->active_fb.height = y;
@@ -287,229 +302,43 @@
 	dispc->active_fb.bpp = bpp;
 	dispc->active_fb.pixel2visual = p2v;
-	dispc->rect.p0.x = 0;
-	dispc->rect.p0.y = 0;
-	dispc->rect.p1.x = x;
-	dispc->rect.p1.y = y;
 	dispc->size = size;
-
-	return EOK;
-}
-
-#define FB_POS(d, x, y) \
-    (((y) * ((d)->active_fb.width + (d)->active_fb.pitch) + (x)) \
-    * (d)->active_fb.bpp)
-
-static errno_t amdm37x_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
-{
-	amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
-
-	*arg2 = ddf_fun_get_handle(dispc->fun);
-	*arg3 = 42;
-	return EOK;
-}
-
-static errno_t amdm37x_ddev_get_info(void *arg, ddev_info_t *info)
-{
-	amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
-
-	ddev_info_init(info);
-	info->rect.p0.x = 0;
-	info->rect.p0.y = 0;
-	info->rect.p1.x = dispc->active_fb.width;
-	info->rect.p1.y = dispc->active_fb.height;
-	return EOK;
-}
-
-/** Set color on AMDM37x display controller.
- *
- * Set drawing color on AMDM37x GC.
- *
- * @param arg AMDM37x display controller
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t amdm37x_gc_set_color(void *arg, gfx_color_t *color)
-{
-	amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
-	uint16_t r, g, b;
-
-	gfx_color_get_rgb_i16(color, &r, &g, &b);
-	dispc->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
-	return EOK;
-}
-
-/** Fill rectangle on AMDM37x display controller.
- *
- * @param arg AMDM37x display controller
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t amdm37x_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
-	gfx_rect_t crect;
-	gfx_coord_t x, y;
-
-	/* Make sure we have a sorted, clipped rectangle */
-	gfx_rect_clip(rect, &dispc->rect, &crect);
-
-	for (y = crect.p0.y; y < crect.p1.y; y++) {
-		for (x = crect.p0.x; x < crect.p1.x; x++) {
-			dispc->active_fb.pixel2visual(dispc->fb_data +
-			    FB_POS(dispc, x, y), dispc->color);
-		}
-	}
-
-	return EOK;
-}
-
-/** Create bitmap in AMDM37x GC.
- *
- * @param arg AMDM37x display controller
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t amdm37x_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
-	amdm37x_bitmap_t *dcbm = NULL;
-	gfx_coord2_t dim;
-	errno_t rc;
-
-	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
-		return ENOTSUP;
-
-	dcbm = calloc(1, sizeof(amdm37x_bitmap_t));
-	if (dcbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	dcbm->rect = params->rect;
-
-	if (alloc == NULL) {
-		dcbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		dcbm->alloc.off0 = 0;
-		dcbm->alloc.pixels = malloc(dcbm->alloc.pitch * dim.y);
-		dcbm->myalloc = true;
-
-		if (dcbm->alloc.pixels == NULL) {
-			rc = ENOMEM;
-			goto error;
+	assert(mode.index < 1);
+
+	return EOK;
+}
+
+static errno_t handle_damage(visualizer_t *vs,
+    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
+    sysarg_t x_offset, sysarg_t y_offset)
+{
+	assert(vs);
+	assert(vs->dev_ctx);
+	amdm37x_dispc_t *dispc = vs->dev_ctx;
+	pixelmap_t *map = &vs->cells;
+
+#define FB_POS(x, y) \
+	(((y) * (dispc->active_fb.width + dispc->active_fb.pitch) + (x)) \
+	    * dispc->active_fb.bpp)
+	if (x_offset == 0 && y_offset == 0) {
+		/* Faster damage routine ignoring offsets. */
+		for (sysarg_t y = y0; y < height + y0; ++y) {
+			pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
+			for (sysarg_t x = x0; x < width + x0; ++x) {
+				dispc->active_fb.pixel2visual(
+				    dispc->fb_data + FB_POS(x, y), *pixel++);
+			}
 		}
 	} else {
-		dcbm->alloc = *alloc;
-	}
-
-	dcbm->dispc = dispc;
-	*rbm = (void *)dcbm;
-	return EOK;
-error:
-	if (rbm != NULL)
-		free(dcbm);
-	return rc;
-}
-
-/** Destroy bitmap in AMDM37x GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t amdm37x_gc_bitmap_destroy(void *bm)
-{
-	amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
-	if (dcbm->myalloc)
-		free(dcbm->alloc.pixels);
-	free(dcbm);
-	return EOK;
-}
-
-/** Render bitmap in AMDM37x GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t amdm37x_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
-	amdm37x_dispc_t *dispc = dcbm->dispc;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-	gfx_rect_t skfbrect;
-	gfx_rect_t crect;
-	gfx_coord2_t offs;
-	gfx_coord2_t bmdim;
-	gfx_coord2_t dim;
-	gfx_coord2_t sp;
-	gfx_coord2_t dp;
-	gfx_coord2_t pos;
-	pixelmap_t pbm;
-	pixel_t color;
-
-	/* Clip source rectangle to bitmap bounds */
-
-	if (srect0 != NULL)
-		gfx_rect_clip(srect0, &dcbm->rect, &srect);
-	else
-		srect = dcbm->rect;
-
-	if (offs0 != NULL) {
-		offs = *offs0;
-	} else {
-		offs.x = 0;
-		offs.y = 0;
-	}
-
-	/* Destination rectangle */
-	gfx_rect_translate(&offs, &srect, &drect);
-	gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
-	gfx_coord2_subtract(&dcbm->rect.p1, &dcbm->rect.p0, &bmdim);
-
-	pbm.width = bmdim.x;
-	pbm.height = bmdim.y;
-	pbm.data = dcbm->alloc.pixels;
-
-	/* Transform AMDM37x bounding rectangle back to bitmap coordinate system */
-	gfx_rect_rtranslate(&offs, &dispc->rect, &skfbrect);
-
-	/*
-	 * Make sure we have a sorted source rectangle, clipped so that
-	 * destination lies within AMDM37x bounding rectangle
-	 */
-	gfx_rect_clip(&srect, &skfbrect, &crect);
-
-	// XXX bmpf_color_key
-	for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
-		for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
-			gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
-			gfx_coord2_add(&pos, &offs, &dp);
-
-			color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
-			dispc->active_fb.pixel2visual(dispc->fb_data +
-			    FB_POS(dispc, dp.x, dp.y), color);
+		for (sysarg_t y = y0; y < height + y0; ++y) {
+			for (sysarg_t x = x0; x < width + x0; ++x) {
+				dispc->active_fb.pixel2visual(
+				    dispc->fb_data + FB_POS(x, y),
+				    *pixelmap_pixel_at(map,
+				    (x + x_offset) % map->width,
+				    (y + y_offset) % map->height));
+			}
 		}
 	}
 
-	return EOK;
-}
-
-/** Get allocation info for bitmap in AMDM37x GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t amdm37x_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
-	*alloc = dcbm->alloc;
 	return EOK;
 }
Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -1,4 +1,3 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
  * Copyright (c) 2013 Jan Vesely
  * All rights reserved.
@@ -38,10 +37,6 @@
 #define AMDM37X_DISPC_H_
 
+#include <graph.h>
 #include <abi/fb/visuals.h>
-#include <ddev_srv.h>
-#include <ddf/driver.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <io/pixel.h>
 #include <pixconv.h>
 #include <ddi.h>
@@ -50,5 +45,4 @@
 
 typedef struct {
-	ddf_fun_t *fun;
 	amdm37x_dispc_regs_t *regs;
 
@@ -59,24 +53,15 @@
 		unsigned pitch;
 		unsigned bpp;
+		unsigned idx;
 	} active_fb;
 
-	pixel_t color;
-	gfx_rect_t rect;
 	size_t size;
 	void *fb_data;
+
+	vslmode_list_element_t modes[1];
 } amdm37x_dispc_t;
 
-typedef struct {
-	amdm37x_dispc_t *dispc;
-	gfx_bitmap_alloc_t alloc;
-	gfx_rect_t rect;
-	bool myalloc;
-} amdm37x_bitmap_t;
-
-extern ddev_ops_t amdm37x_ddev_ops;
-extern gfx_context_ops_t amdm37x_gc_ops;
-
-extern errno_t amdm37x_dispc_init(amdm37x_dispc_t *, ddf_fun_t *);
-extern errno_t amdm37x_dispc_fini(amdm37x_dispc_t *);
+errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis);
+errno_t amdm37x_dispc_fini(amdm37x_dispc_t *instance);
 
 #endif
Index: uspace/drv/fb/amdm37x_dispc/main.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/amdm37x_dispc/main.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -1,4 +1,3 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
  * Copyright (c) 2013 Jan Vesely
  * Copyright (c) 2011 Petr Koupy
@@ -36,11 +35,10 @@
  */
 
-#include <ddev_srv.h>
 #include <ddf/driver.h>
 #include <ddf/log.h>
 #include <errno.h>
-#include <ipcgfx/server.h>
 #include <str_error.h>
 #include <stdio.h>
+#include <graph.h>
 
 #include "amdm37x_dispc.h"
@@ -48,39 +46,10 @@
 #define NAME  "amdm37x_dispc"
 
-static void amdm37x_client_conn(ipc_call_t *icall, void *arg)
+static void graph_vsl_connection(ipc_call_t *icall, void *arg)
 {
-	amdm37x_dispc_t *dispc;
-	ddev_srv_t srv;
-	sysarg_t gc_id;
-	gfx_context_t *gc;
-	errno_t rc;
+	visualizer_t *vsl;
 
-	dispc = (amdm37x_dispc_t *) ddf_dev_data_get(
-	    ddf_fun_get_dev((ddf_fun_t *) arg));
-
-	gc_id = ipc_get_arg3(icall);
-
-	if (gc_id == 0) {
-		/* Set up protocol structure */
-		ddev_srv_initialize(&srv);
-		srv.ops = &amdm37x_ddev_ops;
-		srv.arg = dispc;
-
-		/* Handle connection */
-		ddev_conn(icall, &srv);
-	} else {
-		assert(gc_id == 42);
-
-		rc = gfx_context_new(&amdm37x_gc_ops, dispc, &gc);
-		if (rc != EOK)
-			goto error;
-
-		/* GC connection */
-		gc_conn(icall, gc);
-	}
-
-	return;
-error:
-	async_answer_0(icall, rc);
+	vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
+	graph_visualizer_connection(vsl, icall, NULL);
 }
 
@@ -88,13 +57,22 @@
 {
 	assert(dev);
-
-	ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "a");
+	/* Visualizer part */
+	ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "viz");
 	if (!fun) {
-		ddf_log_error("Failed to create display device function.");
+		ddf_log_error("Failed to create visualizer function.");
 		return ENOMEM;
 	}
 
-	ddf_fun_set_conn_handler(fun, &amdm37x_client_conn);
+	visualizer_t *vis = ddf_fun_data_alloc(fun, sizeof(visualizer_t));
+	if (!vis) {
+		ddf_log_error("Failed to allocate visualizer structure.");
+		ddf_fun_destroy(fun);
+		return ENOMEM;
+	}
 
+	graph_init_visualizer(vis);
+	vis->reg_svc_handle = ddf_fun_get_handle(fun);
+
+	ddf_fun_set_conn_handler(fun, graph_vsl_connection);
 	/* Hw part */
 	amdm37x_dispc_t *dispc =
@@ -106,5 +84,5 @@
 	}
 
-	errno_t rc = amdm37x_dispc_init(dispc, fun);
+	errno_t rc = amdm37x_dispc_init(dispc, vis);
 	if (rc != EOK) {
 		ddf_log_error("Failed to init dispc: %s.", str_error(rc));
@@ -122,7 +100,7 @@
 	}
 
-	rc = ddf_fun_add_to_category(fun, "display-device");
+	rc = ddf_fun_add_to_category(fun, "visualizer");
 	if (rc != EOK) {
-		ddf_log_error("Failed to add function: %s to display device "
+		ddf_log_error("Failed to add function: %s to visualizer "
 		    "category.", str_error(rc));
 		amdm37x_dispc_fini(dispc);
Index: uspace/drv/fb/amdm37x_dispc/meson.build
===================================================================
--- uspace/drv/fb/amdm37x_dispc/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/amdm37x_dispc/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -29,4 +29,4 @@
 #
 
-deps = [ 'gfx', 'ipcgfx', 'ddev', 'softrend' ]
+deps = [ 'graph', 'softrend' ]
 src = files('amdm37x_dispc.c', 'main.c')
Index: uspace/drv/fb/kfb/kfb.c
===================================================================
--- uspace/drv/fb/kfb/kfb.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/kfb/kfb.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -36,4 +36,5 @@
 #include <errno.h>
 #include <stdio.h>
+#include <graph.h>
 #include "port.h"
 #include "kfb.h"
Index: uspace/drv/fb/kfb/kfb.h
===================================================================
--- uspace/drv/fb/kfb/kfb.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/kfb/kfb.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -41,4 +41,7 @@
 #define NAME  "kfb"
 
+extern ddf_dev_ops_t graph_vsl_device_ops;
+extern ddf_dev_ops_t graph_rnd_device_ops;
+
 #endif
 
Index: uspace/drv/fb/kfb/meson.build
===================================================================
--- uspace/drv/fb/kfb/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/kfb/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -29,4 +29,4 @@
 #
 
-deps = [ 'gfx', 'ipcgfx', 'ddev', 'softrend' ]
+deps = [ 'graph', 'softrend' ]
 src = files('port.c', 'kfb.c')
Index: uspace/drv/fb/kfb/port.c
===================================================================
--- uspace/drv/fb/kfb/port.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/drv/fb/kfb/port.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -1,4 +1,3 @@
 /*
- * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2006 Jakub Vana
  * Copyright (c) 2006 Ondrej Palkovsky
@@ -39,35 +38,35 @@
 
 #include <abi/fb/visuals.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include <stdlib.h>
+#include <mem.h>
+#include <as.h>
+#include <align.h>
+
+#include <sysinfo.h>
+#include <ddi.h>
+
 #include <adt/list.h>
-#include <align.h>
-#include <as.h>
-#include <ddev_srv.h>
-#include <ddev/info.h>
-#include <ddi.h>
-#include <ddf/log.h>
-#include <errno.h>
-#include <gfx/bitmap.h>
-#include <gfx/color.h>
-#include <gfx/coord.h>
+
 #include <io/mode.h>
 #include <io/pixelmap.h>
-#include <ipcgfx/server.h>
-#include <mem.h>
+#include <io/chargrid.h>
+
 #include <pixconv.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <sysinfo.h>
+
+#include <graph.h>
 
 #include "kfb.h"
 #include "port.h"
 
-#define FB_POS(fb, x, y)  ((y) * (fb)->scanline + (x) * (fb)->pixel_bytes)
+#define FB_POS(x, y)  ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
 
 typedef struct {
-	ddf_fun_t *fun;
-
 	sysarg_t paddr;
-	gfx_rect_t rect;
+	sysarg_t width;
+	sysarg_t height;
 	size_t offset;
 	size_t scanline;
@@ -81,251 +80,54 @@
 	size_t size;
 	uint8_t *addr;
-
-	/** Current drawing color */
-	pixel_t color;
 } kfb_t;
 
-typedef struct {
-	kfb_t *kfb;
-	gfx_bitmap_alloc_t alloc;
-	gfx_rect_t rect;
-	gfx_bitmap_flags_t flags;
-	pixel_t key_color;
-	bool myalloc;
-} kfb_bitmap_t;
-
-static errno_t kfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
-static errno_t kfb_ddev_get_info(void *, ddev_info_t *);
-
-static errno_t kfb_gc_set_color(void *, gfx_color_t *);
-static errno_t kfb_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t kfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t kfb_gc_bitmap_destroy(void *);
-static errno_t kfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t kfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static ddev_ops_t kfb_ddev_ops = {
-	.get_gc = kfb_ddev_get_gc,
-	.get_info = kfb_ddev_get_info
-};
-
-static gfx_context_ops_t kfb_gc_ops = {
-	.set_color = kfb_gc_set_color,
-	.fill_rect = kfb_gc_fill_rect,
-	.bitmap_create = kfb_gc_bitmap_create,
-	.bitmap_destroy = kfb_gc_bitmap_destroy,
-	.bitmap_render = kfb_gc_bitmap_render,
-	.bitmap_get_alloc = kfb_gc_bitmap_get_alloc
-};
-
-static errno_t kfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
-{
-	kfb_t *kfb = (kfb_t *) arg;
-
-	*arg2 = ddf_fun_get_handle(kfb->fun);
-	*arg3 = 42;
-	return EOK;
-}
-
-static errno_t kfb_ddev_get_info(void *arg, ddev_info_t *info)
-{
-	kfb_t *kfb = (kfb_t *) arg;
-
-	ddev_info_init(info);
-	info->rect = kfb->rect;
-	return EOK;
-}
-
-/** Set color on KFB.
- *
- * Set drawing color on KFB GC.
- *
- * @param arg KFB
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t kfb_gc_set_color(void *arg, gfx_color_t *color)
-{
-	kfb_t *kfb = (kfb_t *) arg;
-	uint16_t r, g, b;
-
-	gfx_color_get_rgb_i16(color, &r, &g, &b);
-	kfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
-	return EOK;
-}
-
-/** Fill rectangle on KFB.
- *
- * @param arg KFB
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t kfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	kfb_t *kfb = (kfb_t *) arg;
-	gfx_rect_t crect;
-	gfx_coord_t x, y;
-
-	/* Make sure we have a sorted, clipped rectangle */
-	gfx_rect_clip(rect, &kfb->rect, &crect);
-
-	for (y = crect.p0.y; y < crect.p1.y; y++) {
-		for (x = crect.p0.x; x < crect.p1.x; x++) {
-			kfb->pixel2visual(kfb->addr + FB_POS(kfb, x, y),
-			    kfb->color);
-		}
-	}
-
-	return EOK;
-}
-
-/** Create bitmap in KFB GC.
- *
- * @param arg KFB
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t kfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	kfb_t *kfb = (kfb_t *) arg;
-	kfb_bitmap_t *kfbbm = NULL;
-	gfx_coord2_t dim;
+static kfb_t kfb;
+
+static vslmode_list_element_t pixel_mode;
+
+static errno_t kfb_claim(visualizer_t *vs)
+{
+	return physmem_map(kfb.paddr + kfb.offset,
+	    ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
+}
+
+static errno_t kfb_yield(visualizer_t *vs)
+{
 	errno_t rc;
 
-	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
-		return ENOTSUP;
-
-	kfbbm = calloc(1, sizeof(kfb_bitmap_t));
-	if (kfbbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	kfbbm->rect = params->rect;
-	kfbbm->flags = params->flags;
-	kfbbm->key_color = params->key_color;
-
-	if (alloc == NULL) {
-		kfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		kfbbm->alloc.off0 = 0;
-		kfbbm->alloc.pixels = malloc(kfbbm->alloc.pitch * dim.y);
-		kfbbm->myalloc = true;
-
-		if (kfbbm->alloc.pixels == NULL) {
-			rc = ENOMEM;
-			goto error;
-		}
-	} else {
-		kfbbm->alloc = *alloc;
-	}
-
-	kfbbm->kfb = kfb;
-	*rbm = (void *)kfbbm;
-	return EOK;
-error:
-	if (rbm != NULL)
-		free(kfbbm);
-	return rc;
-}
-
-/** Destroy bitmap in KFB GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t kfb_gc_bitmap_destroy(void *bm)
-{
-	kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
-	if (kfbbm->myalloc)
-		free(kfbbm->alloc.pixels);
-	free(kfbbm);
-	return EOK;
-}
-
-/** Render bitmap in KFB GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t kfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
-	kfb_t *kfb = kfbbm->kfb;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-	gfx_rect_t skfbrect;
-	gfx_rect_t crect;
-	gfx_coord2_t offs;
-	gfx_coord2_t bmdim;
-	gfx_coord2_t dim;
-	gfx_coord2_t sp;
-	gfx_coord2_t dp;
-	gfx_coord2_t pos;
-	pixelmap_t pbm;
-	pixel_t color;
-
-	/* Clip source rectangle to bitmap bounds */
-
-	if (srect0 != NULL)
-		gfx_rect_clip(srect0, &kfbbm->rect, &srect);
-	else
-		srect = kfbbm->rect;
-
-	if (offs0 != NULL) {
-		offs = *offs0;
-	} else {
-		offs.x = 0;
-		offs.y = 0;
-	}
-
-	/* Destination rectangle */
-	gfx_rect_translate(&offs, &srect, &drect);
-	gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
-	gfx_coord2_subtract(&kfbbm->rect.p1, &kfbbm->rect.p0, &bmdim);
-
-	pbm.width = bmdim.x;
-	pbm.height = bmdim.y;
-	pbm.data = kfbbm->alloc.pixels;
-
-	/* Transform KFB bounding rectangle back to bitmap coordinate system */
-	gfx_rect_rtranslate(&offs, &kfb->rect, &skfbrect);
-
-	/*
-	 * Make sure we have a sorted source rectangle, clipped so that
-	 * destination lies within KFB bounding rectangle
-	 */
-	gfx_rect_clip(&srect, &skfbrect, &crect);
-
-	if ((kfbbm->flags & bmpf_color_key) != 0) {
-		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
-			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
-				gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
-				gfx_coord2_add(&pos, &offs, &dp);
-
-				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
-				if (color != kfbbm->key_color) {
-					kfb->pixel2visual(kfb->addr +
-					    FB_POS(kfb, dp.x, dp.y), color);
-				}
+	if (vs->mode_set) {
+		vs->ops.handle_damage = NULL;
+	}
+
+	rc = physmem_unmap(kfb.addr);
+	if (rc != EOK)
+		return rc;
+
+	kfb.addr = NULL;
+	return EOK;
+}
+
+static errno_t kfb_handle_damage_pixels(visualizer_t *vs,
+    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
+    sysarg_t x_offset, sysarg_t y_offset)
+{
+	pixelmap_t *map = &vs->cells;
+
+	if (x_offset == 0 && y_offset == 0) {
+		/* Faster damage routine ignoring offsets. */
+		for (sysarg_t y = y0; y < height + y0; ++y) {
+			pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
+			for (sysarg_t x = x0; x < width + x0; ++x) {
+				kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
 			}
 		}
 	} else {
-		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
-			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
-				gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
-				gfx_coord2_add(&pos, &offs, &dp);
-
-				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
-				kfb->pixel2visual(kfb->addr +
-				    FB_POS(kfb, dp.x, dp.y), color);
+		for (sysarg_t y = y0; y < height + y0; ++y) {
+			for (sysarg_t x = x0; x < width + x0; ++x) {
+				kfb.pixel2visual(kfb.addr + FB_POS(x, y),
+				    *pixelmap_pixel_at(map,
+				    (x + x_offset) % map->width,
+				    (y + y_offset) % map->height));
 			}
 		}
@@ -335,110 +137,53 @@
 }
 
-/** Get allocation info for bitmap in KFB GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t kfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
-	*alloc = kfbbm->alloc;
-	return EOK;
-}
-
-#include <stdio.h>
-static void kfb_client_conn(ipc_call_t *icall, void *arg)
-{
-	kfb_t *kfb;
-	ddev_srv_t srv;
-	sysarg_t gc_id;
-	gfx_context_t *gc;
+static errno_t kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
+{
+	vs->ops.handle_damage = kfb_handle_damage_pixels;
+	return EOK;
+}
+
+static errno_t kfb_suspend(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static errno_t kfb_wakeup(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static visualizer_ops_t kfb_ops = {
+	.claim = kfb_claim,
+	.yield = kfb_yield,
+	.change_mode = kfb_change_mode,
+	.handle_damage = NULL,
+	.suspend = kfb_suspend,
+	.wakeup = kfb_wakeup
+};
+
+static void graph_vsl_connection(ipc_call_t *icall, void *arg)
+{
+	visualizer_t *vsl;
 	errno_t rc;
 
-	kfb = (kfb_t *) ddf_fun_data_get((ddf_fun_t *) arg);
-
-	printf("kfb_client_conn arg2=%lu arg3=%lu arg4=%lu\n",
-	    (unsigned long) ipc_get_arg2(icall),
-	    (unsigned long) ipc_get_arg3(icall),
-	    (unsigned long) ipc_get_arg4(icall));
-
-	gc_id = ipc_get_arg3(icall);
-
-	if (gc_id == 0) {
-		/* Set up protocol structure */
-		ddev_srv_initialize(&srv);
-		srv.ops = &kfb_ddev_ops;
-		srv.arg = kfb;
-
-		/* Handle connection */
-		ddev_conn(icall, &srv);
-	} else {
-		assert(gc_id == 42);
-
-		if (kfb->addr != AS_AREA_ANY) {
-			/* This means there already is a GC connection */
-			async_answer_0(icall, EBUSY);
-			return;
-		}
-
-		rc = physmem_map(kfb->paddr + kfb->offset,
-		    ALIGN_UP(kfb->size, PAGE_SIZE) >> PAGE_WIDTH,
-		    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb->addr);
-		if (rc != EOK)
-			goto error;
-
-		rc = gfx_context_new(&kfb_gc_ops, kfb, &gc);
-		if (rc != EOK)
-			goto error;
-
-		/* GC connection */
-		gc_conn(icall, gc);
-
-		rc = physmem_unmap(kfb->addr);
+	vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
+	graph_visualizer_connection(vsl, icall, NULL);
+
+	if (kfb.addr != NULL) {
+		rc = physmem_unmap(kfb.addr);
 		if (rc == EOK)
-			kfb->addr = AS_AREA_ANY;
-	}
-
-	return;
-error:
-	if (kfb->addr != AS_AREA_ANY) {
-		if (physmem_unmap(kfb->addr) == EOK)
-			kfb->addr = AS_AREA_ANY;
-	}
-
-	async_answer_0(icall, rc);
+			kfb.addr = NULL;
+	}
 }
 
 errno_t port_init(ddf_dev_t *dev)
 {
-	ddf_fun_t *fun = NULL;
-	kfb_t *kfb = NULL;
-	errno_t rc;
-
-	fun = ddf_fun_create(dev, fun_exposed, "kfb");
-	if (fun == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	ddf_fun_set_conn_handler(fun, &kfb_client_conn);
-
-	kfb = ddf_fun_data_alloc(fun, sizeof(kfb_t));
-	if (kfb == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
 	sysarg_t present;
-	rc = sysinfo_get_value("fb", &present);
+	errno_t rc = sysinfo_get_value("fb", &present);
 	if (rc != EOK)
 		present = false;
 
-	if (!present) {
-		ddf_fun_destroy(fun);
-		rc = ENOENT;
-		goto error;
-	}
+	if (!present)
+		return ENOENT;
 
 	sysarg_t kind;
@@ -447,13 +192,11 @@
 		kind = (sysarg_t) -1;
 
-	if (kind != 1) {
-		rc = EINVAL;
-		goto error;
-	}
+	if (kind != 1)
+		return EINVAL;
 
 	sysarg_t paddr;
 	rc = sysinfo_get_value("fb.address.physical", &paddr);
 	if (rc != EOK)
-		goto error;
+		return rc;
 
 	sysarg_t offset;
@@ -465,99 +208,94 @@
 	rc = sysinfo_get_value("fb.width", &width);
 	if (rc != EOK)
-		goto error;
+		return rc;
 
 	sysarg_t height;
 	rc = sysinfo_get_value("fb.height", &height);
 	if (rc != EOK)
-		goto error;
+		return rc;
 
 	sysarg_t scanline;
 	rc = sysinfo_get_value("fb.scanline", &scanline);
 	if (rc != EOK)
-		goto error;
+		return rc;
 
 	sysarg_t visual;
 	rc = sysinfo_get_value("fb.visual", &visual);
 	if (rc != EOK)
-		goto error;
-
-	kfb->fun = fun;
-
-	kfb->rect.p0.x = 0;
-	kfb->rect.p0.y = 0;
-	kfb->rect.p1.x = width;
-	kfb->rect.p1.y = height;
-
-	kfb->paddr = paddr;
-	kfb->offset = offset;
-	kfb->scanline = scanline;
-	kfb->visual = visual;
+		return rc;
+
+	kfb.width = width;
+	kfb.height = height;
+	kfb.paddr = paddr;
+	kfb.offset = offset;
+	kfb.scanline = scanline;
+	kfb.visual = visual;
 
 	switch (visual) {
 	case VISUAL_INDIRECT_8:
-		kfb->pixel2visual = pixel2bgr_323;
-		kfb->visual2pixel = bgr_323_2pixel;
-		kfb->visual_mask = visual_mask_323;
-		kfb->pixel_bytes = 1;
+		kfb.pixel2visual = pixel2bgr_323;
+		kfb.visual2pixel = bgr_323_2pixel;
+		kfb.visual_mask = visual_mask_323;
+		kfb.pixel_bytes = 1;
 		break;
 	case VISUAL_RGB_5_5_5_LE:
-		kfb->pixel2visual = pixel2rgb_555_le;
-		kfb->visual2pixel = rgb_555_le_2pixel;
-		kfb->visual_mask = visual_mask_555;
-		kfb->pixel_bytes = 2;
+		kfb.pixel2visual = pixel2rgb_555_le;
+		kfb.visual2pixel = rgb_555_le_2pixel;
+		kfb.visual_mask = visual_mask_555;
+		kfb.pixel_bytes = 2;
 		break;
 	case VISUAL_RGB_5_5_5_BE:
-		kfb->pixel2visual = pixel2rgb_555_be;
-		kfb->visual2pixel = rgb_555_be_2pixel;
-		kfb->visual_mask = visual_mask_555;
-		kfb->pixel_bytes = 2;
+		kfb.pixel2visual = pixel2rgb_555_be;
+		kfb.visual2pixel = rgb_555_be_2pixel;
+		kfb.visual_mask = visual_mask_555;
+		kfb.pixel_bytes = 2;
 		break;
 	case VISUAL_RGB_5_6_5_LE:
-		kfb->pixel2visual = pixel2rgb_565_le;
-		kfb->visual2pixel = rgb_565_le_2pixel;
-		kfb->visual_mask = visual_mask_565;
-		kfb->pixel_bytes = 2;
+		kfb.pixel2visual = pixel2rgb_565_le;
+		kfb.visual2pixel = rgb_565_le_2pixel;
+		kfb.visual_mask = visual_mask_565;
+		kfb.pixel_bytes = 2;
 		break;
 	case VISUAL_RGB_5_6_5_BE:
-		kfb->pixel2visual = pixel2rgb_565_be;
-		kfb->visual2pixel = rgb_565_be_2pixel;
-		kfb->visual_mask = visual_mask_565;
-		kfb->pixel_bytes = 2;
+		kfb.pixel2visual = pixel2rgb_565_be;
+		kfb.visual2pixel = rgb_565_be_2pixel;
+		kfb.visual_mask = visual_mask_565;
+		kfb.pixel_bytes = 2;
 		break;
 	case VISUAL_RGB_8_8_8:
-		kfb->pixel2visual = pixel2rgb_888;
-		kfb->visual2pixel = rgb_888_2pixel;
-		kfb->visual_mask = visual_mask_888;
-		kfb->pixel_bytes = 3;
+		kfb.pixel2visual = pixel2rgb_888;
+		kfb.visual2pixel = rgb_888_2pixel;
+		kfb.visual_mask = visual_mask_888;
+		kfb.pixel_bytes = 3;
 		break;
 	case VISUAL_BGR_8_8_8:
-		kfb->pixel2visual = pixel2bgr_888;
-		kfb->visual2pixel = bgr_888_2pixel;
-		kfb->visual_mask = visual_mask_888;
-		kfb->pixel_bytes = 3;
+		kfb.pixel2visual = pixel2bgr_888;
+		kfb.visual2pixel = bgr_888_2pixel;
+		kfb.visual_mask = visual_mask_888;
+		kfb.pixel_bytes = 3;
 		break;
 	case VISUAL_RGB_8_8_8_0:
-		kfb->pixel2visual = pixel2rgb_8880;
-		kfb->visual2pixel = rgb_8880_2pixel;
-		kfb->visual_mask = visual_mask_8880;
-		kfb->pixel_bytes = 4;
+		kfb.pixel2visual = pixel2rgb_8880;
+		kfb.visual2pixel = rgb_8880_2pixel;
+		kfb.visual_mask = visual_mask_8880;
+		kfb.pixel_bytes = 4;
 		break;
 	case VISUAL_RGB_0_8_8_8:
-		kfb->pixel2visual = pixel2rgb_0888;
-		kfb->visual2pixel = rgb_0888_2pixel;
-		kfb->visual_mask = visual_mask_0888;
-		kfb->pixel_bytes = 4;
+		kfb.pixel2visual = pixel2rgb_0888;
+		kfb.visual2pixel = rgb_0888_2pixel;
+		kfb.visual_mask = visual_mask_0888;
+		kfb.pixel_bytes = 4;
 		break;
 	case VISUAL_BGR_0_8_8_8:
-		kfb->pixel2visual = pixel2bgr_0888;
-		kfb->visual2pixel = bgr_0888_2pixel;
-		kfb->visual_mask = visual_mask_0888;
-		kfb->pixel_bytes = 4;
+		kfb.pixel2visual = pixel2bgr_0888;
+		kfb.visual2pixel = bgr_0888_2pixel;
+		kfb.visual_mask = visual_mask_0888;
+		kfb.pixel_bytes = 4;
 		break;
 	case VISUAL_BGR_8_8_8_0:
-		kfb->pixel2visual = pixel2bgr_8880;
-		kfb->visual2pixel = bgr_8880_2pixel;
-		kfb->visual_mask = visual_mask_8880;
-		kfb->pixel_bytes = 4;
+		kfb.pixel2visual = pixel2bgr_8880;
+		kfb.visual2pixel = bgr_8880_2pixel;
+		kfb.visual_mask = visual_mask_8880;
+		kfb.pixel_bytes = 4;
 		break;
 	default:
@@ -565,22 +303,59 @@
 	}
 
-	kfb->size = scanline * height;
-	kfb->addr = AS_AREA_ANY;
-
-	rc = ddf_fun_bind(fun);
-	if (rc != EOK)
-		goto error;
-
-	rc = ddf_fun_add_to_category(fun, "display-device");
+	kfb.size = scanline * height;
+	kfb.addr = AS_AREA_ANY;
+
+	ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
+	if (fun_vs == NULL) {
+		as_area_destroy(kfb.addr);
+		return ENOMEM;
+	}
+	ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection);
+
+	visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
+	if (vs == NULL) {
+		as_area_destroy(kfb.addr);
+		return ENOMEM;
+	}
+	graph_init_visualizer(vs);
+
+	pixel_mode.mode.index = 0;
+	pixel_mode.mode.version = 0;
+	pixel_mode.mode.refresh_rate = 0;
+	pixel_mode.mode.screen_aspect.width = width;
+	pixel_mode.mode.screen_aspect.height = height;
+	pixel_mode.mode.screen_width = width;
+	pixel_mode.mode.screen_height = height;
+	pixel_mode.mode.cell_aspect.width = 1;
+	pixel_mode.mode.cell_aspect.height = 1;
+	pixel_mode.mode.cell_visual.pixel_visual = visual;
+
+	link_initialize(&pixel_mode.link);
+	list_append(&pixel_mode.link, &vs->modes);
+
+	vs->def_mode_idx = 0;
+
+	vs->ops = kfb_ops;
+	vs->dev_ctx = NULL;
+
+	rc = ddf_fun_bind(fun_vs);
 	if (rc != EOK) {
-		ddf_fun_unbind(fun);
-		goto error;
-	}
-
-	return EOK;
-error:
-	if (fun != NULL)
-		ddf_fun_destroy(fun);
-	return rc;
+		list_remove(&pixel_mode.link);
+		ddf_fun_destroy(fun_vs);
+		as_area_destroy(kfb.addr);
+		return rc;
+	}
+
+	vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
+	rc = ddf_fun_add_to_category(fun_vs, "visualizer");
+	if (rc != EOK) {
+		list_remove(&pixel_mode.link);
+		ddf_fun_unbind(fun_vs);
+		ddf_fun_destroy(fun_vs);
+		as_area_destroy(kfb.addr);
+		return rc;
+	}
+
+	return EOK;
 }
 
Index: uspace/lib/c/generic/io/visualizer.c
===================================================================
--- uspace/lib/c/generic/io/visualizer.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/c/generic/io/visualizer.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <as.h>
+#include <ipc/graph.h>
+#include <io/visualizer.h>
+
+errno_t visualizer_claim(async_sess_t *sess, sysarg_t notif_callback_id)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_1_0(exch, VISUALIZER_CLAIM, notif_callback_id);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t visualizer_yield(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, VISUALIZER_YIELD);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t visualizer_enumerate_modes(async_sess_t *sess, vslmode_t *mode, sysarg_t nth)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, VISUALIZER_ENUMERATE_MODES, nth, &answer);
+
+	errno_t rc = async_data_read_start(exch, mode, sizeof(vslmode_t));
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK) {
+		return rc;
+	} else if (ret != EOK) {
+		return ret;
+	} else {
+		return EOK;
+	}
+}
+
+errno_t visualizer_get_default_mode(async_sess_t *sess, vslmode_t *mode)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, VISUALIZER_GET_DEFAULT_MODE, &answer);
+
+	errno_t rc = async_data_read_start(exch, mode, sizeof(vslmode_t));
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK) {
+		return rc;
+	} else if (ret != EOK) {
+		return ret;
+	} else {
+		return EOK;
+	}
+}
+
+errno_t visualizer_get_current_mode(async_sess_t *sess, vslmode_t *mode)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, VISUALIZER_GET_CURRENT_MODE, &answer);
+
+	errno_t rc = async_data_read_start(exch, mode, sizeof(vslmode_t));
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK) {
+		return rc;
+	} else if (ret != EOK) {
+		return ret;
+	} else {
+		return EOK;
+	}
+}
+
+errno_t visualizer_get_mode(async_sess_t *sess, vslmode_t *mode, sysarg_t index)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, VISUALIZER_GET_MODE, index, &answer);
+
+	errno_t rc = async_data_read_start(exch, mode, sizeof(vslmode_t));
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK) {
+		return rc;
+	} else if (ret != EOK) {
+		return ret;
+	} else {
+		return EOK;
+	}
+}
+
+errno_t visualizer_set_mode(async_sess_t *sess, sysarg_t index, sysarg_t version, void *cells)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_2(exch, VISUALIZER_SET_MODE, index, version, &answer);
+
+	errno_t rc = async_share_out_start(exch, cells, AS_AREA_READ | AS_AREA_CACHEABLE);
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK) {
+		return rc;
+	} else if (ret != EOK) {
+		return ret;
+	} else {
+		return EOK;
+	}
+}
+
+errno_t visualizer_update_damaged_region(async_sess_t *sess,
+    sysarg_t x, sysarg_t y, sysarg_t width, sysarg_t height,
+    sysarg_t x_offset, sysarg_t y_offset)
+{
+	assert(x_offset <= UINT16_MAX);
+	assert(y_offset <= UINT16_MAX);
+
+	sysarg_t offsets = ((x_offset << 16) | (y_offset & 0x0000ffff));
+
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_5_0(exch, VISUALIZER_UPDATE_DAMAGED_REGION,
+	    x, y, width, height, offsets);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t visualizer_suspend(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, VISUALIZER_SUSPEND);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t visualizer_wakeup(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, VISUALIZER_WAKE_UP);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/io/window.c
===================================================================
--- uspace/lib/c/generic/io/window.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/c/generic/io/window.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012 Petr Koupy
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#include <errno.h>
+#include <as.h>
+#include <ipc/window.h>
+#include <io/window.h>
+
+#include <stdio.h>
+
+errno_t win_register(async_sess_t *sess, window_flags_t flags, service_id_t *in,
+    service_id_t *out)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_1_2(exch, WINDOW_REGISTER, flags, in, out);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t win_get_event(async_sess_t *sess, window_event_t *event)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, WINDOW_GET_EVENT, &answer);
+
+	errno_t rc = async_data_read_start(exch, event, sizeof(window_event_t));
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK) {
+		return rc;
+	} else if (ret != EOK) {
+		return ret;
+	} else {
+		return EOK;
+	}
+}
+
+errno_t win_damage(async_sess_t *sess,
+    sysarg_t x, sysarg_t y, sysarg_t width, sysarg_t height)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_4_0(exch, WINDOW_DAMAGE, x, y, width, height);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t win_grab(async_sess_t *sess, sysarg_t pos_id, sysarg_t grab_flags)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_2_0(exch, WINDOW_GRAB, pos_id, grab_flags);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t win_resize(async_sess_t *sess, sysarg_t x, sysarg_t y, sysarg_t width,
+    sysarg_t height, window_placement_flags_t placement_flags, void *cells)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_5(exch, WINDOW_RESIZE, x, y, width, height,
+	    (sysarg_t) placement_flags, &answer);
+
+	errno_t rc = async_share_out_start(exch, cells, AS_AREA_READ | AS_AREA_CACHEABLE);
+
+	async_exchange_end(exch);
+
+	errno_t ret;
+	async_wait_for(req, &ret);
+
+	if (rc != EOK)
+		return rc;
+	else if (ret != EOK)
+		return ret;
+
+	return EOK;
+}
+
+errno_t win_close(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, WINDOW_CLOSE);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t win_close_request(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_0_0(exch, WINDOW_CLOSE_REQUEST);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/io/kbd_event.h
===================================================================
--- uspace/lib/c/include/io/kbd_event.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/c/include/io/kbd_event.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -37,5 +37,4 @@
 
 #include <adt/list.h>
-#include <inttypes.h>
 #include <io/keycode.h>
 
Index: uspace/lib/c/include/io/visualizer.h
===================================================================
--- uspace/lib/c/include/io/visualizer.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/c/include/io/visualizer.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_IO_VISUALIZER_H_
+#define _LIBC_IO_VISUALIZER_H_
+
+#include <async.h>
+#include <io/mode.h>
+
+extern errno_t visualizer_claim(async_sess_t *, sysarg_t);
+extern errno_t visualizer_yield(async_sess_t *);
+
+extern errno_t visualizer_enumerate_modes(async_sess_t *, vslmode_t *, sysarg_t);
+extern errno_t visualizer_get_default_mode(async_sess_t *, vslmode_t *);
+extern errno_t visualizer_get_current_mode(async_sess_t *, vslmode_t *);
+extern errno_t visualizer_get_mode(async_sess_t *, vslmode_t *, sysarg_t);
+extern errno_t visualizer_set_mode(async_sess_t *, sysarg_t, sysarg_t, void *);
+
+extern errno_t visualizer_update_damaged_region(async_sess_t *,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+
+extern errno_t visualizer_suspend(async_sess_t *);
+extern errno_t visualizer_wakeup(async_sess_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/c/include/io/window.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -36,7 +36,9 @@
 #define _LIBC_IO_WINDOW_H_
 
+#include <stdbool.h>
+#include <async.h>
+#include <loc.h>
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
-#include <types/common.h>
 
 typedef enum {
@@ -111,4 +113,16 @@
 } window_event_t;
 
+extern errno_t win_register(async_sess_t *, window_flags_t, service_id_t *,
+    service_id_t *);
+
+extern errno_t win_get_event(async_sess_t *, window_event_t *);
+
+extern errno_t win_damage(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
+extern errno_t win_grab(async_sess_t *, sysarg_t, sysarg_t);
+extern errno_t win_resize(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t, void *);
+extern errno_t win_close(async_sess_t *);
+extern errno_t win_close_request(async_sess_t *);
+
 #endif
 
Index: uspace/lib/c/include/ipc/graph.h
===================================================================
--- uspace/lib/c/include/ipc/graph.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/c/include/ipc/graph.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_IPC_GRAPH_H_
+#define _LIBC_IPC_GRAPH_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	VISUALIZER_CLAIM = IPC_FIRST_USER_METHOD,
+	VISUALIZER_YIELD,
+
+	VISUALIZER_ENUMERATE_MODES,
+	VISUALIZER_GET_DEFAULT_MODE,
+	VISUALIZER_GET_CURRENT_MODE,
+	VISUALIZER_GET_MODE,
+	VISUALIZER_SET_MODE,
+
+	VISUALIZER_UPDATE_DAMAGED_REGION,
+
+	VISUALIZER_SUSPEND,
+	VISUALIZER_WAKE_UP,
+} visualizer_request_t;
+
+typedef enum {
+	VISUALIZER_MODE_CHANGE = IPC_FIRST_USER_METHOD,
+	VISUALIZER_DISCONNECT
+} visualizer_notif_t;
+
+typedef enum {
+	RENDERER_REQ_NONE = IPC_FIRST_USER_METHOD,
+	// TODO: similar interface as provides libsoftrend
+} renderer_request_t;
+
+typedef enum {
+	RENDERER_NOTIF_NONE = IPC_FIRST_USER_METHOD,
+	// TODO: similar interface as provides libsoftrend
+} renderer_notif_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/c/include/ipc/services.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -54,5 +54,4 @@
 #define SERVICE_NAME_CLIPBOARD "clipboard"
 #define SERVICE_NAME_CORECFG  "corecfg"
-#define SERVICE_NAME_DISPLAY  "hid/display"
 #define SERVICE_NAME_DHCP     "net/dhcp"
 #define SERVICE_NAME_DNSR     "net/dnsr"
Index: uspace/lib/c/meson.build
===================================================================
--- uspace/lib/c/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/c/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -131,4 +131,6 @@
 	'generic/io/console.c',
 	'generic/io/table.c',
+	'generic/io/visualizer.c',
+	'generic/io/window.c',
 	'generic/iplink.c',
 	'generic/iplink_srv.c',
Index: pace/lib/congfx/doc/doxygroups.h
===================================================================
--- uspace/lib/congfx/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libcongfx libcongfx
- * @ingroup libs
- */
Index: pace/lib/congfx/include/congfx/console.h
===================================================================
--- uspace/lib/congfx/include/congfx/console.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2019 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 libcongfx
- * @{
- */
-/**
- * @file GFX console backend
- */
-
-#ifndef _CONGFX_CONSOLE_H
-#define _CONGFX_CONSOLE_H
-
-#include <io/console.h>
-#include <stdio.h>
-#include <types/congfx/console.h>
-#include <types/gfx/context.h>
-#include <types/gfx/ops/context.h>
-
-extern gfx_context_ops_t console_gc_ops;
-
-extern errno_t console_gc_create(console_ctrl_t *, FILE *, console_gc_t **);
-extern errno_t console_gc_delete(console_gc_t *);
-extern gfx_context_t *console_gc_get_ctx(console_gc_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/congfx/include/types/congfx/console.h
===================================================================
--- uspace/lib/congfx/include/types/congfx/console.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2019 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 libcongfx
- * @{
- */
-/**
- * @file GFX console backend
- */
-
-#ifndef _CONGFX_TYPES_CONSOLE_H
-#define _CONGFX_TYPES_CONSOLE_H
-
-struct console_gc;
-typedef struct console_gc console_gc_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/congfx/meson.build
===================================================================
--- uspace/lib/congfx/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,32 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'gfx' ]
-src = files(
-	'src/console.c',
-)
Index: pace/lib/congfx/private/console.h
===================================================================
--- uspace/lib/congfx/private/console.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,81 +1,0 @@
-/*
- * Copyright (c) 2019 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 libcongfx
- * @{
- */
-/**
- * @file GFX console backend structure
- *
- */
-
-#ifndef _CONGFX_PRIVATE_CONSOLE_H
-#define _CONGFX_PRIVATE_CONSOLE_H
-
-#include <gfx/context.h>
-#include <io/console.h>
-#include <io/pixel.h>
-#include <stdio.h>
-
-/** Actual structure of graphics context.
- *
- * This is private to libcongfx. It is not visible to clients nor backends.
- */
-struct console_gc {
-	/** Base graphic context */
-	gfx_context_t *gc;
-	/** Console control structure */
-	console_ctrl_t *con;
-	/** Console bounding rectangle */
-	gfx_rect_t rect;
-	/** File for printing characters */
-	FILE *fout;
-	/** Current drawing color */
-	pixel_t clr;
-};
-
-/** Bitmap in console GC */
-typedef struct {
-	/** Containing console GC */
-	struct console_gc *cgc;
-	/** Allocation info */
-	gfx_bitmap_alloc_t alloc;
-	/** @c true if we allocated the bitmap, @c false if allocated by caller */
-	bool myalloc;
-	/** Rectangle covered by bitmap */
-	gfx_rect_t rect;
-	/** Bitmap flags */
-	gfx_bitmap_flags_t flags;
-	/** Key color */
-	pixel_t key_color;
-} console_gc_bitmap_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/congfx/src/console.c
===================================================================
--- uspace/lib/congfx/src/console.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,353 +1,0 @@
-/*
- * Copyright (c) 2019 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 libcongfx
- * @{
- */
-/**
- * @file GFX console backend
- *
- * This implements a graphics context over a classic console interface.
- * This is just for experimentation purposes. In the end we want the
- * console to actually directly suport GFX interface.
- */
-
-#include <congfx/console.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <gfx/render.h>
-#include <io/pixel.h>
-#include <io/pixelmap.h>
-#include <stdlib.h>
-#include "../private/console.h"
-#include "../private/color.h"
-
-static errno_t console_gc_set_color(void *, gfx_color_t *);
-static errno_t console_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t console_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t console_gc_bitmap_destroy(void *);
-static errno_t console_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t console_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-gfx_context_ops_t console_gc_ops = {
-	.set_color = console_gc_set_color,
-	.fill_rect = console_gc_fill_rect,
-	.bitmap_create = console_gc_bitmap_create,
-	.bitmap_destroy = console_gc_bitmap_destroy,
-	.bitmap_render = console_gc_bitmap_render,
-	.bitmap_get_alloc = console_gc_bitmap_get_alloc
-};
-
-/** Set color on console GC.
- *
- * Set drawing color on console GC.
- *
- * @param arg Console GC
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t console_gc_set_color(void *arg, gfx_color_t *color)
-{
-	console_gc_t *cgc = (console_gc_t *) arg;
-
-	cgc->clr = PIXEL(0, color->r >> 8, color->g >> 8, color->b >> 8);
-	return EOK;
-}
-
-/** Fill rectangle on console GC.
- *
- * @param arg Console GC
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t console_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	console_gc_t *cgc = (console_gc_t *) arg;
-	int rv;
-	gfx_coord_t x, y;
-
-	// XXX We should handle p0.x > p1.x and p0.y > p1.y
-
-	console_set_rgb_color(cgc->con, cgc->clr, cgc->clr);
-
-	for (y = rect->p0.y; y < rect->p1.y; y++) {
-		console_set_pos(cgc->con, rect->p0.x, y);
-
-		for (x = rect->p0.x; x < rect->p1.x; x++) {
-			rv = fputc('X', cgc->fout);
-			if (rv < 0)
-				return EIO;
-		}
-
-		console_flush(cgc->con);
-	}
-
-	return EOK;
-}
-
-/** Create console GC.
- *
- * Create graphics context for rendering into a console.
- *
- * @param con Console object
- * @param fout File to which characters are written (console)
- * @param rgc Place to store pointer to new GC.
- *
- * @return EOK on success or an error code
- */
-errno_t console_gc_create(console_ctrl_t *con, FILE *fout,
-    console_gc_t **rgc)
-{
-	console_gc_t *cgc = NULL;
-	gfx_context_t *gc = NULL;
-	sysarg_t rows;
-	sysarg_t cols;
-	errno_t rc;
-
-	cgc = calloc(1, sizeof(console_gc_t));
-	if (cgc == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rc = console_get_size(con, &cols, &rows);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_context_new(&console_gc_ops, cgc, &gc);
-	if (rc != EOK)
-		goto error;
-
-	cgc->gc = gc;
-	cgc->con = con;
-	cgc->fout = fout;
-	cgc->rect.p0.x = 0;
-	cgc->rect.p0.y = 0;
-	cgc->rect.p1.x = cols;
-	cgc->rect.p1.y = rows - 1; /* make sure we avoid bottom-right corner */
-
-	*rgc = cgc;
-	return EOK;
-error:
-	if (cgc != NULL)
-		free(cgc);
-	gfx_context_delete(gc);
-	return rc;
-}
-
-/** Delete console GC.
- *
- * @param cgc Console GC
- */
-errno_t console_gc_delete(console_gc_t *cgc)
-{
-	errno_t rc;
-
-	rc = gfx_context_delete(cgc->gc);
-	if (rc != EOK)
-		return rc;
-
-	free(cgc);
-	return EOK;
-}
-
-/** Get generic graphic context from console GC.
- *
- * @param cgc Console GC
- * @return Graphic context
- */
-gfx_context_t *console_gc_get_ctx(console_gc_t *cgc)
-{
-	return cgc->gc;
-}
-
-/** Create bitmap in console GC.
- *
- * @param arg console GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t console_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	console_gc_t *cgc = (console_gc_t *) arg;
-	console_gc_bitmap_t *cbm = NULL;
-	gfx_coord2_t dim;
-	errno_t rc;
-
-	/* Check that we support all requested flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
-		return ENOTSUP;
-
-	cbm = calloc(1, sizeof(console_gc_bitmap_t));
-	if (cbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	cbm->rect = params->rect;
-	cbm->flags = params->flags;
-	cbm->key_color = params->key_color;
-
-	if (alloc == NULL) {
-		cbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		cbm->alloc.off0 = 0;
-		cbm->alloc.pixels = calloc(dim.x * dim.y, sizeof(uint32_t));
-		if (cbm->alloc.pixels == NULL) {
-			rc = ENOMEM;
-			goto error;
-		}
-
-		cbm->myalloc = true;
-	} else {
-		cbm->alloc = *alloc;
-	}
-
-	cbm->cgc = cgc;
-	*rbm = (void *)cbm;
-	return EOK;
-error:
-	if (cbm != NULL)
-		free(cbm);
-	return rc;
-}
-
-/** Destroy bitmap in console GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t console_gc_bitmap_destroy(void *bm)
-{
-	console_gc_bitmap_t *cbm = (console_gc_bitmap_t *)bm;
-	if (cbm->myalloc)
-		free(cbm->alloc.pixels);
-	free(cbm);
-	return EOK;
-}
-
-/** Render bitmap in console GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t console_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	console_gc_bitmap_t *cbm = (console_gc_bitmap_t *)bm;
-	gfx_coord_t x, y;
-	int rv;
-	pixel_t clr;
-	pixelmap_t pixelmap;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-	gfx_rect_t crect;
-	gfx_coord2_t offs;
-
-	if (srect0 != NULL)
-		srect = *srect0;
-	else
-		srect = cbm->rect;
-
-	if (offs0 != NULL) {
-		offs = *offs0;
-	} else {
-		offs.x = 0;
-		offs.y = 0;
-	}
-
-	gfx_rect_translate(&offs, &srect, &drect);
-	gfx_rect_clip(&drect, &cbm->cgc->rect, &crect);
-
-	pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x;
-	pixelmap.height = cbm->rect.p1.y = cbm->rect.p1.y;
-	pixelmap.data = cbm->alloc.pixels;
-
-	if ((cbm->flags & bmpf_color_key) == 0) {
-		for (y = crect.p0.y; y < crect.p1.y; y++) {
-			console_set_pos(cbm->cgc->con, crect.p0.x, y);
-
-			for (x = crect.p0.x; x < crect.p1.x; x++) {
-				clr = pixelmap_get_pixel(&pixelmap,
-				    x - offs.x - cbm->rect.p0.x,
-				    y - offs.y - cbm->rect.p0.y);
-				console_set_rgb_color(cbm->cgc->con, clr, clr);
-
-				rv = fputc('X', cbm->cgc->fout);
-				if (rv < 0)
-					return EIO;
-
-				console_flush(cbm->cgc->con);
-			}
-		}
-	} else {
-		for (y = crect.p0.y; y < crect.p1.y; y++) {
-			for (x = crect.p0.x; x < crect.p1.x; x++) {
-
-				clr = pixelmap_get_pixel(&pixelmap,
-				    x - offs.x - cbm->rect.p0.x,
-				    y - offs.y - cbm->rect.p0.y);
-				console_set_rgb_color(cbm->cgc->con, clr, clr);
-
-				if (clr != cbm->key_color) {
-					console_set_pos(cbm->cgc->con, x, y);
-					rv = fputc('X', cbm->cgc->fout);
-					if (rv < 0)
-						return EIO;
-
-					console_flush(cbm->cgc->con);
-				}
-
-			}
-		}
-	}
-
-	return EOK;
-}
-
-/** Get allocation info for bitmap in console GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t console_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	console_gc_bitmap_t *cbm = (console_gc_bitmap_t *)bm;
-	*alloc = cbm->alloc;
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/ddev/doc/doxygroups.h
===================================================================
--- uspace/lib/ddev/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libddev libddev
- * @ingroup libs
- */
Index: pace/lib/ddev/include/ddev.h
===================================================================
--- uspace/lib/ddev/include/ddev.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2019 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 libddev
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDDEV_DDEV_H_
-#define _LIBDDEV_DDEV_H_
-
-#include <ddev/info.h>
-#include <errno.h>
-#include <gfx/context.h>
-#include <stdbool.h>
-#include "types/ddev.h"
-#include "types/ddev/info.h"
-
-extern errno_t ddev_open(const char *, ddev_t **);
-extern void ddev_close(ddev_t *);
-extern errno_t ddev_get_gc(ddev_t *, gfx_context_t **);
-extern errno_t ddev_get_info(ddev_t *, ddev_info_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/ddev/include/ddev/info.h
===================================================================
--- uspace/lib/ddev/include/ddev/info.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2020 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 libddev
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDDEV_DDEV_INFO_H_
-#define _LIBDDEV_DDEV_INFO_H_
-
-#include "types/ddev/info.h"
-
-extern void ddev_info_init(ddev_info_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/ddev/include/ddev_srv.h
===================================================================
--- uspace/lib/ddev/include/ddev_srv.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDDEV_DDEV_SRV_H_
-#define _LIBDDEV_DDEV_SRV_H_
-
-#include <async.h>
-#include <errno.h>
-#include <gfx/context.h>
-#include "types/ddev/info.h"
-
-typedef struct ddev_ops ddev_ops_t;
-
-/** Display device server structure (per client session) */
-typedef struct {
-	async_sess_t *client_sess;
-	ddev_ops_t *ops;
-	void *arg;
-} ddev_srv_t;
-
-struct ddev_ops {
-	errno_t (*get_gc)(void *, sysarg_t *, sysarg_t *);
-	errno_t (*get_info)(void *, ddev_info_t *);
-};
-
-extern void ddev_conn(ipc_call_t *, ddev_srv_t *);
-extern void ddev_srv_initialize(ddev_srv_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/ddev/include/ipc/ddev.h
===================================================================
--- uspace/lib/ddev/include/ipc/ddev.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2019 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 libddev
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_DDEV_H_
-#define _LIBC_IPC_DDEV_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	DDEV_GET_GC = IPC_FIRST_USER_METHOD,
-	DDEV_GET_INFO
-} ddev_request_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ddev/include/types/ddev.h
===================================================================
--- uspace/lib/ddev/include/types/ddev.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2019 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 libddev
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDDEV_TYPES_DDEV_H_
-#define _LIBDDEV_TYPES_DDEV_H_
-
-#include <async.h>
-
-/** Display server session */
-typedef struct {
-	/** Session with display device */
-	async_sess_t *sess;
-} ddev_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ddev/include/types/ddev/info.h
===================================================================
--- uspace/lib/ddev/include/types/ddev/info.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2020 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 libddev
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDDEV_TYPES_DDEV_INFO_H_
-#define _LIBDDEV_TYPES_DDEV_INFO_H_
-
-#include <gfx/coord.h>
-
-/** Display device information */
-typedef struct {
-	/** Bounding rectangle */
-	gfx_rect_t rect;
-} ddev_info_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ddev/meson.build
===================================================================
--- uspace/lib/ddev/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,39 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'gfx', 'ipcgfx' ]
-src = files(
-	'src/ddev.c',
-	'src/ddev_srv.c',
-	'src/info.c',
-)
-
-test_src = files(
-	'test/ddev.c',
-	'test/main.c',
-)
Index: pace/lib/ddev/src/ddev.c
===================================================================
--- uspace/lib/ddev/src/ddev.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,147 +1,0 @@
-/*
- * Copyright (c) 2019 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 <async.h>
-#include <ddev.h>
-#include <errno.h>
-#include <ipc/ddev.h>
-#include <ipc/services.h>
-#include <ipcgfx/client.h>
-#include <loc.h>
-#include <stdlib.h>
-
-/** Open display device.
- *
- * @param ddname Display device service name
- * @param rdisplay Place to store pointer to display session
- * @return EOK on success or an error code
- */
-errno_t ddev_open(const char *ddname, ddev_t **rddev)
-{
-	service_id_t ddev_svc;
-	ddev_t *ddev;
-	errno_t rc;
-
-	ddev = calloc(1, sizeof(ddev_t));
-	if (ddev == NULL)
-		return ENOMEM;
-
-	rc = loc_service_get_id(ddname, &ddev_svc, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		free(ddev);
-		return ENOENT;
-	}
-
-	ddev->sess = loc_service_connect(ddev_svc, INTERFACE_DDEV,
-	    IPC_FLAG_BLOCKING);
-	if (ddev->sess == NULL) {
-		free(ddev);
-		return ENOENT;
-	}
-
-	*rddev = ddev;
-	return EOK;
-}
-
-/** Close display device.
- *
- * @param ddev Display device session
- */
-void ddev_close(ddev_t *ddev)
-{
-	async_hangup(ddev->sess);
-	free(ddev);
-}
-
-/** Create graphics context for drawing to display device.
- *
- * @param ddev Display device
- * @param rgc Place to store pointer to new graphics context
- */
-errno_t ddev_get_gc(ddev_t *ddev, gfx_context_t **rgc)
-{
-	async_sess_t *sess;
-	async_exch_t *exch;
-	sysarg_t arg2;
-	sysarg_t arg3;
-	ipc_gc_t *gc;
-	errno_t rc;
-
-	exch = async_exchange_begin(ddev->sess);
-	rc = async_req_0_2(exch, DDEV_GET_GC, &arg2, &arg3);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-
-	sess = async_connect_me_to(exch, INTERFACE_GC, arg2, arg3, &rc);
-	async_exchange_end(exch);
-
-	if (sess == NULL)
-		return rc;
-
-	rc = ipc_gc_create(sess, &gc);
-	if (rc != EOK) {
-		async_hangup(sess);
-		return ENOMEM;
-	}
-
-	*rgc = ipc_gc_get_ctx(gc);
-	return EOK;
-}
-
-/** Get display device information.
- *
- * @param ddev Display device
- * @param info Place to store information
- */
-errno_t ddev_get_info(ddev_t *ddev, ddev_info_t *info)
-{
-	async_exch_t *exch;
-	errno_t retval;
-	ipc_call_t answer;
-
-	exch = async_exchange_begin(ddev->sess);
-	aid_t req = async_send_0(exch, DDEV_GET_INFO, &answer);
-
-	errno_t rc = async_data_read_start(exch, info, sizeof(ddev_info_t));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &retval);
-	if (retval != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/ddev/src/ddev_srv.c
===================================================================
--- uspace/lib/ddev/src/ddev_srv.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,156 +1,0 @@
-/*
- * Copyright (c) 2019 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 libddev
- * @{
- */
-/**
- * @file
- * @brief Display protocol server stub
- */
-
-#include <ddev_srv.h>
-#include <errno.h>
-#include <io/log.h>
-#include <ipc/ddev.h>
-#include <mem.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-/** Connect to a GC.
- *
- * XXX As a workaround here we tell the client the values of arg2 and arg3
- * needed to connect to the GC using async_connect_me_to(), these need
- * to be provided by the ddev_ops_t.get_gc. Different values are needed
- * for a DDF driver or a regular server. This would not be needed if we
- * had a proper way of creating an endpoint and passing it to our client.
- */
-static void ddev_get_gc_srv(ddev_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t arg2;
-	sysarg_t arg3;
-	errno_t rc;
-
-	if (srv->ops->get_gc == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->get_gc(srv->arg, &arg2, &arg3);
-	async_answer_2(icall, rc, arg2, arg3);
-}
-
-/** Get display device information */
-static void ddev_get_info_srv(ddev_srv_t *srv, ipc_call_t *icall)
-{
-	ddev_info_t info;
-	errno_t rc;
-
-	ipc_call_t call;
-	size_t size;
-	if (!async_data_read_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(ddev_info_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	if (srv->ops->get_info == NULL) {
-		async_answer_0(&call, ENOTSUP);
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->get_info(srv->arg, &info);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	rc = async_data_read_finalize(&call, &info, sizeof(ddev_info_t));
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	async_answer_0(icall, EOK);
-}
-
-void ddev_conn(ipc_call_t *icall, ddev_srv_t *srv)
-{
-	/* Accept the connection */
-	async_accept_0(icall);
-
-	while (true) {
-		ipc_call_t call;
-
-		async_get_call(&call);
-		sysarg_t method = ipc_get_imethod(&call);
-
-		if (!method) {
-			/* The other side has hung up */
-			async_answer_0(&call, EOK);
-			break;
-		}
-
-		switch (method) {
-		case DDEV_GET_GC:
-			ddev_get_gc_srv(srv, &call);
-			break;
-		case DDEV_GET_INFO:
-			ddev_get_info_srv(srv, &call);
-			break;
-		default:
-			async_answer_0(&call, ENOTSUP);
-		}
-	}
-
-	/* Hang up callback session */
-	if (srv->client_sess != NULL) {
-		async_hangup(srv->client_sess);
-		srv->client_sess = NULL;
-	}
-}
-
-/** Initialize display device server structure
- *
- * @param srv Display device server structure to initialize
- */
-void ddev_srv_initialize(ddev_srv_t *srv)
-{
-	memset(srv, 0, sizeof(*srv));
-}
-
-/** @}
- */
Index: pace/lib/ddev/src/info.c
===================================================================
--- uspace/lib/ddev/src/info.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/*
- * Copyright (c) 2020 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 <ddev/info.h>
-#include <mem.h>
-
-/** Initialize display device information structure.
- *
- * @param info Display device information structure
- */
-void ddev_info_init(ddev_info_t *info)
-{
-	memset(info, 0, sizeof(ddev_info_t));
-}
-
-/** @}
- */
Index: pace/lib/ddev/test/ddev.c
===================================================================
--- uspace/lib/ddev/test/ddev.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,320 +1,0 @@
-/*
- * Copyright (c) 2019 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 <async.h>
-#include <errno.h>
-#include <ddev.h>
-#include <ddev_srv.h>
-#include <fibril_synch.h>
-#include <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <ipcgfx/server.h>
-#include <loc.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(ddev);
-
-static const char *test_ddev_server = "test-ddev";
-static const char *test_ddev_svc = "test/ddev";
-
-static void test_ddev_conn(ipc_call_t *, void *);
-
-static errno_t test_get_gc(void *, sysarg_t *, sysarg_t *);
-static errno_t test_get_info(void *, ddev_info_t *);
-static errno_t test_gc_set_color(void *, gfx_color_t *);
-
-static ddev_ops_t test_ddev_ops = {
-	.get_gc = test_get_gc,
-	.get_info = test_get_info
-};
-
-static gfx_context_ops_t test_gc_ops = {
-	.set_color = test_gc_set_color
-};
-
-/** Describes to the server how to respond to our request and pass tracking
- * data back to the client.
- */
-typedef struct {
-	errno_t rc;
-	bool set_color_called;
-	ddev_srv_t *srv;
-	ddev_info_t info;
-} test_response_t;
-
-/** ddev_open(), ddev_close() work for valid display device service */
-PCUT_TEST(open_close)
-{
-	errno_t rc;
-	service_id_t sid;
-	ddev_t *ddev = NULL;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_ddev_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ddev_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ddev_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ddev_open(test_ddev_svc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(ddev);
-
-	ddev_close(ddev);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** ddev_get_gc with server returning failure */
-PCUT_TEST(dev_get_gc_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	ddev_t *ddev = NULL;
-	test_response_t resp;
-	gfx_context_t *gc;
-
-	async_set_fallback_port_handler(test_ddev_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ddev_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ddev_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ddev_open(test_ddev_svc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(ddev);
-
-	gc = NULL;
-	resp.rc = ENOMEM;
-	rc = ddev_get_gc(ddev, &gc);
-	/* async_connect_me_to() does not return specific error */
-	PCUT_ASSERT_ERRNO_VAL(EIO, rc);
-	PCUT_ASSERT_NULL(gc);
-
-	ddev_close(ddev);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** ddev_get_gc with server returning success */
-PCUT_TEST(dev_get_gc_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	ddev_t *ddev = NULL;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_color_t *color;
-
-	async_set_fallback_port_handler(test_ddev_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ddev_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ddev_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ddev_open(test_ddev_svc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(ddev);
-
-	resp.rc = EOK;
-	gc = NULL;
-	rc = ddev_get_gc(ddev, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	resp.set_color_called = false;
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.set_color_called);
-
-	gfx_color_delete(color);
-
-	ddev_close(ddev);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** ddev_get_info with server returning failure */
-PCUT_TEST(dev_get_info_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	ddev_t *ddev = NULL;
-	test_response_t resp;
-	ddev_info_t info;
-
-	async_set_fallback_port_handler(test_ddev_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ddev_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ddev_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ddev_open(test_ddev_svc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(ddev);
-
-	resp.rc = ENOMEM;
-	rc = ddev_get_info(ddev, &info);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-
-	ddev_close(ddev);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** ddev_get_info with server returning success */
-PCUT_TEST(dev_get_info_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	ddev_t *ddev = NULL;
-	test_response_t resp;
-	ddev_info_t info;
-
-	async_set_fallback_port_handler(test_ddev_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ddev_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ddev_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ddev_open(test_ddev_svc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(ddev);
-
-	resp.rc = EOK;
-
-	ddev_info_init(&resp.info);
-	resp.info.rect.p0.x = 1;
-	resp.info.rect.p0.y = 2;
-	resp.info.rect.p1.x = 3;
-	resp.info.rect.p1.y = 4;
-
-	rc = ddev_get_info(ddev, &info);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-
-	PCUT_ASSERT_INT_EQUALS(resp.info.rect.p0.x, info.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(resp.info.rect.p0.y, info.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(resp.info.rect.p1.x, info.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(resp.info.rect.p1.y, info.rect.p1.y);
-
-	ddev_close(ddev);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Test display device connection.
- *
- * This is very similar to connection handler in the display server.
- * XXX This should be folded into display_srv, if possible
- */
-static void test_ddev_conn(ipc_call_t *icall, void *arg)
-{
-	test_response_t *resp = (test_response_t *) arg;
-	ddev_srv_t srv;
-	sysarg_t svc_id;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	svc_id = ipc_get_arg2(icall);
-
-	if (svc_id != 0) {
-		/* Set up protocol structure */
-		ddev_srv_initialize(&srv);
-		srv.ops = &test_ddev_ops;
-		srv.arg = arg;
-		resp->srv = &srv;
-
-		/* Handle connection */
-		ddev_conn(icall, &srv);
-
-		resp->srv = NULL;
-	} else {
-		if (resp->rc != EOK) {
-			async_answer_0(icall, resp->rc);
-			return;
-		}
-
-		rc = gfx_context_new(&test_gc_ops, arg, &gc);
-		if (rc != EOK) {
-			async_answer_0(icall, ENOMEM);
-			return;
-		}
-
-		/* GC connection */
-		gc_conn(icall, gc);
-	}
-}
-
-static errno_t test_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
-{
-	*arg2 = 0;
-	*arg3 = 42;
-	return EOK;
-}
-
-static errno_t test_get_info(void *arg, ddev_info_t *info)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	if (resp->rc != EOK)
-		return resp->rc;
-
-	*info = resp->info;
-	return EOK;
-}
-
-static errno_t test_gc_set_color(void *arg, gfx_color_t *color)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->set_color_called = true;
-	return resp->rc;
-}
-
-PCUT_EXPORT(ddev);
Index: pace/lib/ddev/test/main.c
===================================================================
--- uspace/lib/ddev/test/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,35 +1,0 @@
-/*
- * Copyright (c) 2019 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 <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_IMPORT(ddev);
-
-PCUT_MAIN();
Index: pace/lib/display/doc/doxygroups.h
===================================================================
--- uspace/lib/display/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libdisplay libdisplay
- * @ingroup libs
- */
Index: pace/lib/display/include/disp_srv.h
===================================================================
--- uspace/lib/display/include/disp_srv.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,76 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_DISP_SRV_H_
-#define _LIBDISPLAY_DISP_SRV_H_
-
-#include <async.h>
-#include <errno.h>
-#include <gfx/coord.h>
-#include "display/wndparams.h"
-#include "types/display/cursor.h"
-#include "types/display/event.h"
-#include "types/display/info.h"
-#include "types/display/wndresize.h"
-
-typedef struct display_ops display_ops_t;
-
-/** Display server structure (per client session) */
-typedef struct {
-	async_sess_t *client_sess;
-	display_ops_t *ops;
-	void *arg;
-} display_srv_t;
-
-struct display_ops {
-	errno_t (*window_create)(void *, display_wnd_params_t *, sysarg_t *);
-	errno_t (*window_destroy)(void *, sysarg_t);
-	errno_t (*window_move_req)(void *, sysarg_t, gfx_coord2_t *);
-	errno_t (*window_resize_req)(void *, sysarg_t, display_wnd_rsztype_t,
-	    gfx_coord2_t *);
-	errno_t (*window_move)(void *, sysarg_t, gfx_coord2_t *);
-	errno_t (*window_resize)(void *, sysarg_t, gfx_coord2_t *, gfx_rect_t *);
-	errno_t (*window_set_cursor)(void *, sysarg_t, display_stock_cursor_t);
-	errno_t (*get_event)(void *, sysarg_t *, display_wnd_ev_t *);
-	errno_t (*get_info)(void *, display_info_t *);
-};
-
-extern void display_conn(ipc_call_t *, display_srv_t *);
-extern void display_srv_initialize(display_srv_t *);
-extern void display_srv_ev_pending(display_srv_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/display.h
===================================================================
--- uspace/lib/display/include/display.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,68 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_DISPLAY_H_
-#define _LIBDISPLAY_DISPLAY_H_
-
-#include <errno.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <stdbool.h>
-#include "display/wndparams.h"
-#include "display/wndresize.h"
-#include "types/display.h"
-#include "types/display/cursor.h"
-#include "types/display/info.h"
-
-extern errno_t display_open(const char *, display_t **);
-extern void display_close(display_t *);
-extern errno_t display_get_info(display_t *, display_info_t *);
-
-extern errno_t display_window_create(display_t *, display_wnd_params_t *,
-    display_wnd_cb_t *, void *, display_window_t **);
-extern errno_t display_window_destroy(display_window_t *);
-extern errno_t display_window_get_gc(display_window_t *, gfx_context_t **);
-extern errno_t display_window_move_req(display_window_t *, gfx_coord2_t *);
-extern errno_t display_window_resize_req(display_window_t *,
-    display_wnd_rsztype_t, gfx_coord2_t *);
-extern errno_t display_window_move(display_window_t *, gfx_coord2_t *);
-extern errno_t display_window_resize(display_window_t *,
-    gfx_coord2_t *, gfx_rect_t *);
-extern errno_t display_window_set_cursor(display_window_t *,
-    display_stock_cursor_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/display/event.h
===================================================================
--- uspace/lib/display/include/display/event.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_DISPLAY_EVENT_H_
-#define _LIBDISPLAY_DISPLAY_EVENT_H_
-
-#include <types/display/event.h>
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/display/info.h
===================================================================
--- uspace/lib/display/include/display/info.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2020 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_DISPLAY_INFO_H_
-#define _LIBDISPLAY_DISPLAY_INFO_H_
-
-#include <types/display/info.h>
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/display/wndparams.h
===================================================================
--- uspace/lib/display/include/display/wndparams.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_DISPLAY_WNDPARAMS_H_
-#define _LIBDISPLAY_DISPLAY_WNDPARAMS_H_
-
-#include "../types/display/wndparams.h"
-
-extern void display_wnd_params_init(display_wnd_params_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/display/wndresize.h
===================================================================
--- uspace/lib/display/include/display/wndresize.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2020 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_DISPLAY_WNDRESIZE_H_
-#define _LIBDISPLAY_DISPLAY_WNDRESIZE_H_
-
-#include <stdbool.h>
-#include "../types/display/cursor.h"
-#include "../types/display/wndresize.h"
-
-extern display_stock_cursor_t display_cursor_from_wrsz(display_wnd_rsztype_t);
-extern bool display_wndrsz_valid(display_wnd_rsztype_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/ipc/display.h
===================================================================
--- uspace/lib/display/include/ipc/display.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBC_IPC_DISPLAY_H_
-#define _LIBC_IPC_DISPLAY_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	DISPLAY_CALLBACK_CREATE = IPC_FIRST_USER_METHOD,
-	DISPLAY_WINDOW_CREATE,
-	DISPLAY_WINDOW_DESTROY,
-	DISPLAY_WINDOW_MOVE,
-	DISPLAY_WINDOW_MOVE_REQ,
-	DISPLAY_WINDOW_RESIZE,
-	DISPLAY_WINDOW_RESIZE_REQ,
-	DISPLAY_WINDOW_SET_CURSOR,
-	DISPLAY_GET_EVENT,
-	DISPLAY_GET_INFO
-} display_request_t;
-
-typedef enum {
-	DISPLAY_EV_PENDING = IPC_FIRST_USER_METHOD
-} display_event_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/types/display.h
===================================================================
--- uspace/lib/display/include/types/display.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,95 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_TYPES_DISPLAY_H_
-#define _LIBDISPLAY_TYPES_DISPLAY_H_
-
-#include <async.h>
-#include <fibril_synch.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-#include <stddef.h>
-#include <stdint.h>
-
-/** Use the default display service (argument to display_open() */
-#define DISPLAY_DEFAULT NULL
-
-/** Display server session */
-typedef struct {
-	/** Session with display server */
-	async_sess_t *sess;
-	/** Synchronize access to display object */
-	fibril_mutex_t lock;
-	/** @c true if callback handler terminated */
-	bool cb_done;
-	/** Signalled when cb_done or ev_pending is changed */
-	fibril_condvar_t cv;
-	/** Windows (of display_window_t) */
-	list_t windows;
-} display_t;
-
-/** Display window callbacks */
-typedef struct {
-	/** Close event */
-	void (*close_event)(void *);
-	/** Focus event */
-	void (*focus_event)(void *);
-	/** Keyboard event */
-	void (*kbd_event)(void *, kbd_event_t *);
-	/** Position event */
-	void (*pos_event)(void *, pos_event_t *);
-	/** Resize event */
-	void (*resize_event)(void *, gfx_rect_t *);
-	/** Unfocus event */
-	void (*unfocus_event)(void *);
-} display_wnd_cb_t;
-
-/** Display window */
-typedef struct {
-	/** Display associated with the window */
-	display_t *display;
-	/** Link to @c display->windows */
-	link_t lwindows;
-	/** Window ID */
-	sysarg_t id;
-	/** Callback functions */
-	display_wnd_cb_t *cb;
-	/** Argument to callback functions */
-	void *cb_arg;
-} display_window_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/types/display/cursor.h
===================================================================
--- uspace/lib/display/include/types/display/cursor.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2020 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_TYPES_DISPLAY_CURSOR_H_
-#define _LIBDISPLAY_TYPES_DISPLAY_CURSOR_H_
-
-/** Stock cursor types */
-typedef enum {
-	/** Standard arrow */
-	dcurs_arrow,
-	/** Double arrow pointing up and down */
-	dcurs_size_ud,
-	/** Double arrow pointing left and right */
-	dcurs_size_lr,
-	/** Double arrow pointing up-left and down-right */
-	dcurs_size_uldr,
-	/** Double arrow pointing up-right nad down-left */
-	dcurs_size_urdl
-} display_stock_cursor_t;
-
-enum {
-	/** Number of stock cursor types */
-	dcurs_limit = dcurs_size_urdl + 1
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/types/display/event.h
===================================================================
--- uspace/lib/display/include/types/display/event.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,80 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_TYPES_DISPLAY_EVENT_H_
-#define _LIBDISPLAY_TYPES_DISPLAY_EVENT_H_
-
-#include <gfx/coord.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-
-/** Display window event type */
-typedef enum {
-	/** Request to close window */
-	wev_close,
-	/** Window gained focus */
-	wev_focus,
-	/** Keyboard event */
-	wev_kbd,
-	/** Position event */
-	wev_pos,
-	/** Resize event */
-	wev_resize,
-	/** Window lost focus */
-	wev_unfocus
-} display_wnd_ev_type_t;
-
-/** Display window resize event */
-typedef struct {
-	gfx_rect_t rect;
-} display_wnd_resize_ev_t;
-
-/** Display window event */
-typedef struct {
-	/** Event type */
-	display_wnd_ev_type_t etype;
-	union {
-		/** Keyboard event data */
-		kbd_event_t kbd;
-		/** Position event data */
-		pos_event_t pos;
-		/** Resize event data */
-		display_wnd_resize_ev_t resize;
-	} ev;
-} display_wnd_ev_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/types/display/info.h
===================================================================
--- uspace/lib/display/include/types/display/info.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2020 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_TYPES_DISPLAY_INFO_H_
-#define _LIBDISPLAY_TYPES_DISPLAY_INFO_H_
-
-#include <gfx/coord.h>
-
-/** Display information */
-typedef struct {
-	/** Display bounding rectangle */
-	gfx_rect_t rect;
-} display_info_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/types/display/wndparams.h
===================================================================
--- uspace/lib/display/include/types/display/wndparams.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_TYPES_DISPLAY_WNDPARAMS_H_
-#define _LIBDISPLAY_TYPES_DISPLAY_WNDPARAMS_H_
-
-#include <gfx/coord.h>
-
-/** Parameters for a new window.
- *
- * The window's dimensions are determined by the bounding rectangle,
- * the position of which does not relate to its positon on the display,
- * it just determines which range of logical coordinates is used
- * by the window.
- */
-typedef struct {
-	/** Bounding rectangle */
-	gfx_rect_t rect;
-	/** Minimum size (when being resized) */
-	gfx_coord2_t min_size;
-} display_wnd_params_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/include/types/display/wndresize.h
===================================================================
--- uspace/lib/display/include/types/display/wndresize.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2020 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_TYPES_DISPLAY_WNDRESIZE_H_
-#define _LIBDISPLAY_TYPES_DISPLAY_WNDRESIZE_H_
-
-/** Window resize type */
-typedef enum {
-	display_wr_top = 0x1,
-	display_wr_left = 0x2,
-	display_wr_bottom = 0x4,
-	display_wr_right = 0x8,
-
-	display_wr_top_left = display_wr_top | display_wr_left,
-	display_wr_bottom_left = display_wr_bottom | display_wr_left,
-	display_wr_bottom_right = display_wr_bottom | display_wr_right,
-	display_wr_top_right = display_wr_top | display_wr_right
-} display_wnd_rsztype_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/meson.build
===================================================================
--- uspace/lib/display/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'gfx', 'ipcgfx' ]
-src = files(
-	'src/display.c',
-	'src/disp_srv.c',
-	'src/wndresize.c',
-)
-
-test_src = files(
-	'test/display.c',
-	'test/main.c',
-	'test/wndresize.c',
-)
Index: pace/lib/display/private/params.h
===================================================================
--- uspace/lib/display/private/params.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2020 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 libdisplay
- * @{
- */
-/** @file
- */
-
-#ifndef _LIBDISPLAY_PRIVATE_PARAMS_H_
-#define _LIBDISPLAY_PRIVATE_PARAMS_H_
-
-#include <gfx/coord.h>
-
-/** Window resize arguments. */
-typedef struct {
-	/** Offset */
-	gfx_coord2_t offs;
-	/** New bounding rectangle */
-	gfx_rect_t nrect;
-} display_wnd_resize_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/display/src/disp_srv.c
===================================================================
--- uspace/lib/display/src/disp_srv.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,451 +1,0 @@
-/*
- * Copyright (c) 2019 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 libdisplay
- * @{
- */
-/**
- * @file
- * @brief Display protocol server stub
- */
-
-#include <disp_srv.h>
-#include <display/event.h>
-#include <display/info.h>
-#include <display/wndresize.h>
-#include <errno.h>
-#include <io/log.h>
-#include <ipc/display.h>
-#include <mem.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include "../private/params.h"
-
-static void display_callback_create_srv(display_srv_t *srv, ipc_call_t *call)
-{
-	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
-	if (sess == NULL) {
-		async_answer_0(call, ENOMEM);
-		return;
-	}
-
-	srv->client_sess = sess;
-	async_answer_0(call, EOK);
-}
-
-static void display_window_create_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	ipc_call_t call;
-	display_wnd_params_t params;
-	size_t size;
-	errno_t rc;
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(display_wnd_params_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &params, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->ops->window_create == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_create(srv->arg, &params, &wnd_id);
-	async_answer_1(icall, rc, wnd_id);
-}
-
-static void display_window_destroy_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	errno_t rc;
-
-	wnd_id = ipc_get_arg1(icall);
-
-	if (srv->ops->window_destroy == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_destroy(srv->arg, wnd_id);
-	async_answer_0(icall, rc);
-}
-
-static void display_window_move_req_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	ipc_call_t call;
-	gfx_coord2_t pos;
-	size_t size;
-	errno_t rc;
-
-	wnd_id = ipc_get_arg1(icall);
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(gfx_coord2_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &pos, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->ops->window_move_req == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_move_req(srv->arg, wnd_id, &pos);
-	async_answer_0(icall, rc);
-}
-
-static void display_window_move_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	ipc_call_t call;
-	gfx_coord2_t dpos;
-	size_t size;
-	errno_t rc;
-
-	wnd_id = ipc_get_arg1(icall);
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(gfx_coord2_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &dpos, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->ops->window_move == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_move(srv->arg, wnd_id, &dpos);
-	async_answer_0(icall, rc);
-}
-
-static void display_window_resize_req_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	ipc_call_t call;
-	display_wnd_rsztype_t rsztype;
-	gfx_coord2_t pos;
-	size_t size;
-	errno_t rc;
-
-	wnd_id = ipc_get_arg1(icall);
-	rsztype = (display_wnd_rsztype_t) ipc_get_arg2(icall);
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(gfx_coord2_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &pos, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->ops->window_resize_req == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_resize_req(srv->arg, wnd_id, rsztype, &pos);
-	async_answer_0(icall, rc);
-}
-
-static void display_window_resize_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	ipc_call_t call;
-	display_wnd_resize_t wresize;
-	size_t size;
-	errno_t rc;
-
-	wnd_id = ipc_get_arg1(icall);
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(display_wnd_resize_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &wresize, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	if (srv->ops->window_resize == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_resize(srv->arg, wnd_id, &wresize.offs,
-	    &wresize.nrect);
-	async_answer_0(icall, rc);
-}
-
-static void display_window_set_cursor_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	display_stock_cursor_t cursor;
-	errno_t rc;
-
-	wnd_id = ipc_get_arg1(icall);
-	cursor = ipc_get_arg2(icall);
-
-	if (srv->ops->window_set_cursor == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->window_set_cursor(srv->arg, wnd_id, cursor);
-	async_answer_0(icall, rc);
-}
-
-static void display_get_event_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	sysarg_t wnd_id;
-	display_wnd_ev_t event;
-	ipc_call_t call;
-	size_t size;
-	errno_t rc;
-
-	if (srv->ops->get_event == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	rc = srv->ops->get_event(srv->arg, &wnd_id, &event);
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	/* Transfer event data */
-	if (!async_data_read_receive(&call, &size)) {
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(event)) {
-		async_answer_0(icall, EREFUSED);
-		async_answer_0(&call, EREFUSED);
-		return;
-	}
-
-	rc = async_data_read_finalize(&call, &event, sizeof(event));
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		async_answer_0(&call, rc);
-		return;
-	}
-
-	async_answer_1(icall, EOK, wnd_id);
-}
-
-static void display_get_info_srv(display_srv_t *srv, ipc_call_t *icall)
-{
-	display_info_t info;
-	ipc_call_t call;
-	size_t size;
-	errno_t rc;
-
-	if (srv->ops->get_info == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
-
-	/* Transfer information */
-	if (!async_data_read_receive(&call, &size)) {
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(info)) {
-		async_answer_0(icall, EREFUSED);
-		async_answer_0(&call, EREFUSED);
-		return;
-	}
-
-	rc = srv->ops->get_info(srv->arg, &info);
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		async_answer_0(&call, rc);
-		return;
-	}
-
-	rc = async_data_read_finalize(&call, &info, sizeof(info));
-	if (rc != EOK) {
-		async_answer_0(icall, rc);
-		async_answer_0(&call, rc);
-		return;
-	}
-
-	async_answer_0(icall, EOK);
-}
-
-void display_conn(ipc_call_t *icall, display_srv_t *srv)
-{
-	/* Accept the connection */
-	async_accept_0(icall);
-
-	while (true) {
-		ipc_call_t call;
-
-		async_get_call(&call);
-		sysarg_t method = ipc_get_imethod(&call);
-
-		if (!method) {
-			/* The other side has hung up */
-			async_answer_0(&call, EOK);
-			break;
-		}
-
-		switch (method) {
-		case DISPLAY_CALLBACK_CREATE:
-			display_callback_create_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_CREATE:
-			display_window_create_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_DESTROY:
-			display_window_destroy_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_MOVE_REQ:
-			display_window_move_req_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_MOVE:
-			display_window_move_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_RESIZE_REQ:
-			display_window_resize_req_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_RESIZE:
-			display_window_resize_srv(srv, &call);
-			break;
-		case DISPLAY_WINDOW_SET_CURSOR:
-			display_window_set_cursor_srv(srv, &call);
-			break;
-		case DISPLAY_GET_EVENT:
-			display_get_event_srv(srv, &call);
-			break;
-		case DISPLAY_GET_INFO:
-			display_get_info_srv(srv, &call);
-			break;
-		default:
-			async_answer_0(&call, ENOTSUP);
-		}
-	}
-
-	/* Hang up callback session */
-	if (srv->client_sess != NULL) {
-		async_hangup(srv->client_sess);
-		srv->client_sess = NULL;
-	}
-}
-
-/** Initialize display server structure
- *
- * @param srv Display server structure to initialize
- */
-void display_srv_initialize(display_srv_t *srv)
-{
-	memset(srv, 0, sizeof(*srv));
-}
-
-/** Send 'pending' event to client.
- *
- * @param srv Display server structure
- */
-void display_srv_ev_pending(display_srv_t *srv)
-{
-	async_exch_t *exch;
-
-	exch = async_exchange_begin(srv->client_sess);
-	async_msg_0(exch, DISPLAY_EV_PENDING);
-	async_exchange_end(exch);
-}
-
-/** @}
- */
Index: pace/lib/display/src/display.c
===================================================================
--- uspace/lib/display/src/display.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,637 +1,0 @@
-/*
- * Copyright (c) 2019 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 <async.h>
-#include <display.h>
-#include <display/event.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <ipc/display.h>
-#include <ipc/services.h>
-#include <ipcgfx/client.h>
-#include <loc.h>
-#include <mem.h>
-#include <stdlib.h>
-#include "../private/params.h"
-
-static errno_t display_callback_create(display_t *);
-static void display_cb_conn(ipc_call_t *, void *);
-static errno_t display_get_window(display_t *, sysarg_t, display_window_t **);
-
-/** Open display service.
- *
- * @param dsname Display service name or @c NULL to use default display
- * @param rdisplay Place to store pointer to display session
- * @return EOK on success or an error code
- */
-errno_t display_open(const char *dsname, display_t **rdisplay)
-{
-	service_id_t display_svc;
-	display_t *display;
-	errno_t rc;
-
-	display = calloc(1, sizeof(display_t));
-	if (display == NULL)
-		return ENOMEM;
-
-	fibril_mutex_initialize(&display->lock);
-	fibril_condvar_initialize(&display->cv);
-	list_initialize(&display->windows);
-
-	if (dsname == NULL)
-		dsname = SERVICE_NAME_DISPLAY;
-
-	rc = loc_service_get_id(dsname, &display_svc, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		free(display);
-		return ENOENT;
-	}
-
-	display->sess = loc_service_connect(display_svc, INTERFACE_DISPLAY,
-	    IPC_FLAG_BLOCKING);
-	if (display->sess == NULL) {
-		free(display);
-		return ENOENT;
-	}
-
-	rc = display_callback_create(display);
-	if (rc != EOK) {
-		async_hangup(display->sess);
-		free(display);
-		return EIO;
-	}
-
-	*rdisplay = display;
-	return EOK;
-}
-
-/** Create callback connection from display service.
- *
- * @param display Display session
- * @return EOK on success or an error code
- */
-static errno_t display_callback_create(display_t *display)
-{
-	async_exch_t *exch = async_exchange_begin(display->sess);
-
-	aid_t req = async_send_0(exch, DISPLAY_CALLBACK_CREATE, NULL);
-
-	port_id_t port;
-	errno_t rc = async_create_callback_port(exch, INTERFACE_DISPLAY_CB, 0, 0,
-	    display_cb_conn, display, &port);
-
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		return rc;
-
-	errno_t retval;
-	async_wait_for(req, &retval);
-
-	return retval;
-}
-
-/** Close display service.
- *
- * @param display Display session
- */
-void display_close(display_t *display)
-{
-	fibril_mutex_lock(&display->lock);
-	async_hangup(display->sess);
-	display->sess = NULL;
-
-	/* Wait for callback handler to terminate */
-
-	while (!display->cb_done)
-		fibril_condvar_wait(&display->cv, &display->lock);
-	fibril_mutex_unlock(&display->lock);
-
-	free(display);
-}
-
-/** Initialize window parameters structure.
- *
- * Window parameters structure must always be initialized using this function
- * first.
- *
- * @param params Window parameters structure
- */
-void display_wnd_params_init(display_wnd_params_t *params)
-{
-	memset(params, 0, sizeof(*params));
-}
-
-/** Create a display window.
- *
- * @param display Display
- * @param params Window parameters
- * @param cb Callback functions
- * @param cb_arg Argument to callback functions
- * @param rwindow Place to store pointer to new window
- * @return EOK on success or an error code
- */
-errno_t display_window_create(display_t *display, display_wnd_params_t *params,
-    display_wnd_cb_t *cb, void *cb_arg, display_window_t **rwindow)
-{
-	display_window_t *window;
-	async_exch_t *exch;
-	aid_t req;
-	ipc_call_t answer;
-	errno_t rc;
-
-	window = calloc(1, sizeof(display_window_t));
-	if (window == NULL)
-		return ENOMEM;
-
-	exch = async_exchange_begin(display->sess);
-	req = async_send_0(exch, DISPLAY_WINDOW_CREATE, &answer);
-	rc = async_data_write_start(exch, params, sizeof (display_wnd_params_t));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	window->display = display;
-	window->id = ipc_get_arg1(&answer);
-	window->cb = cb;
-	window->cb_arg = cb_arg;
-
-	list_append(&window->lwindows, &display->windows);
-	*rwindow = window;
-	return EOK;
-}
-
-/** Destroy display window.
- *
- * @param window Window
- * @return EOK on success or an error code. In both cases @a window must
- *         not be accessed anymore
- */
-errno_t display_window_destroy(display_window_t *window)
-{
-	async_exch_t *exch;
-	errno_t rc;
-
-	exch = async_exchange_begin(window->display->sess);
-	rc = async_req_1_0(exch, DISPLAY_WINDOW_DESTROY, window->id);
-
-	async_exchange_end(exch);
-
-	list_remove(&window->lwindows);
-	free(window);
-	return rc;
-}
-
-/** Create graphics context for drawing into a window.
- *
- * @param window Window
- * @param rgc Place to store pointer to new graphics context
- * @return EOK on success or an error code
- */
-errno_t display_window_get_gc(display_window_t *window, gfx_context_t **rgc)
-{
-	async_sess_t *sess;
-	async_exch_t *exch;
-	ipc_gc_t *gc;
-	errno_t rc;
-
-	exch = async_exchange_begin(window->display->sess);
-	sess = async_connect_me_to(exch, INTERFACE_GC, 0, window->id, &rc);
-	if (sess == NULL) {
-		async_exchange_end(exch);
-		return rc;
-	}
-
-	async_exchange_end(exch);
-
-	rc = ipc_gc_create(sess, &gc);
-	if (rc != EOK) {
-		async_hangup(sess);
-		return ENOMEM;
-	}
-
-	*rgc = ipc_gc_get_ctx(gc);
-	return EOK;
-}
-
-/** Request a window move.
- *
- * Request the display service to initiate a user window move operation
- * (i.e. let the user move the window). Used when the client detects
- * mouse press on the title bar or such.
- *
- * @param window Window
- * @param pos Position in the window where the button was pressed
- * @return EOK on success or an error code
- */
-errno_t display_window_move_req(display_window_t *window, gfx_coord2_t *pos)
-{
-	async_exch_t *exch;
-	aid_t req;
-	ipc_call_t answer;
-	errno_t rc;
-
-	exch = async_exchange_begin(window->display->sess);
-	req = async_send_1(exch, DISPLAY_WINDOW_MOVE_REQ, window->id, &answer);
-	rc = async_data_write_start(exch, (void *)pos, sizeof (gfx_coord2_t));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Move display window.
- *
- * Set new display position of a window. Display position determines where
- * the origin of the window coordinate system lies. Note that the top left
- * corner of the window need not coincide with the window's 0,0 point.
- *
- * @param window Window
- * @param dpos New display position
- * @return EOK on success or an error code
- */
-errno_t display_window_move(display_window_t *window, gfx_coord2_t *dpos)
-{
-	async_exch_t *exch;
-	aid_t req;
-	ipc_call_t answer;
-	errno_t rc;
-
-	exch = async_exchange_begin(window->display->sess);
-	req = async_send_1(exch, DISPLAY_WINDOW_MOVE, window->id, &answer);
-	rc = async_data_write_start(exch, dpos, sizeof (gfx_coord2_t));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Request a window resize.
- *
- * Request the display service to initiate a user window resize operation
- * (i.e. let the user resize the window). Used when the client detects
- * mouse press on the window frame or such.
- *
- * @param window Window
- * @param rsztype Resize type (which part of window frame is being dragged)
- * @param pos Position in the window where the button was pressed
- * @return EOK on success or an error code
- */
-errno_t display_window_resize_req(display_window_t *window,
-    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
-{
-	async_exch_t *exch;
-	aid_t req;
-	ipc_call_t answer;
-	errno_t rc;
-
-	exch = async_exchange_begin(window->display->sess);
-	req = async_send_2(exch, DISPLAY_WINDOW_RESIZE_REQ, window->id,
-	    (sysarg_t) rsztype, &answer);
-	rc = async_data_write_start(exch, (void *)pos, sizeof (gfx_coord2_t));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Resize display window.
- *
- * It seems resizing windows should be easy with bounding rectangles.
- * You have an old bounding rectangle and a new bounding rectangle (@a nrect).
- * Change .p0 and top-left corner moves. Change .p1 and bottom-right corner
- * moves. Piece of cake!
- *
- * There's always a catch, though. By series of resizes and moves .p0 could
- * drift outside of the range of @c gfx_coord_t. Now what? @a offs to the
- * rescue! @a offs moves the @em boundaries of the window with respect
- * to the display, while keeping the @em contents of the window in the
- * same place (with respect to the display). In other words, @a offs shifts
- * the window's internal coordinate system.
- *
- * A few examples follow:
- *
- * Enlarge window by moving bottom-right corner 1 right, 1 down:
- *
- *   bound = (0, 0, 10, 10)
- *   offs  = (0, 0)
- *   nrect = (0, 0, 11, 11)
- *
- * Enlarge window by moving top-left corner, 1 up, 1 left, allowing the
- * window-relative coordinate of the top-left corner to drift (undesirable)
- *
- *   bound = (0, 0, 10, 10)
- *   offs  = (0, 0)
- *   nrect = (-1, -1, 10, 10) <- this is the new bounding rectangle
- *
- * Enlarge window by moving top-left corner 1 up, 1 left, keeping top-left
- * corner locked to (0,0) window-relative coordinates (desirable):
- *
- *   bound = (0, 0, 10, 10)
- *   off   = (-1,-1)        <- top-left corner goes 1 up, 1 left
- *   nrect = (0, 0, 11, 11) <- window still starts at 0,0 window-relative
- *
- * @param window Window
- * @param nrect New bounding rectangle
- * @param offs
- * @return EOK on success or an error code
- */
-errno_t display_window_resize(display_window_t *window, gfx_coord2_t *offs,
-    gfx_rect_t *nrect)
-{
-	async_exch_t *exch;
-	aid_t req;
-	ipc_call_t answer;
-	display_wnd_resize_t wresize;
-	errno_t rc;
-
-	wresize.offs = *offs;
-	wresize.nrect = *nrect;
-
-	exch = async_exchange_begin(window->display->sess);
-	req = async_send_1(exch, DISPLAY_WINDOW_RESIZE, window->id, &answer);
-	rc = async_data_write_start(exch, &wresize, sizeof (display_wnd_resize_t));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Set window cursor.
- *
- * Set cursor that is displayed when pointer is over the window. The default
- * is the arrow pointer.
- *
- * @param window Window
- * @param cursor Cursor to display
- * @return EOK on success or an error code
- */
-errno_t display_window_set_cursor(display_window_t *window,
-    display_stock_cursor_t cursor)
-{
-	async_exch_t *exch;
-	errno_t rc;
-
-	exch = async_exchange_begin(window->display->sess);
-	rc = async_req_2_0(exch, DISPLAY_WINDOW_SET_CURSOR, window->id,
-	    cursor);
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Get display event.
- *
- * @param display Display
- * @param rwindow Place to store pointer to window that received event
- * @param event Place to store event
- * @return EOK on success or an error code
- */
-static errno_t display_get_event(display_t *display, display_window_t **rwindow,
-    display_wnd_ev_t *event)
-{
-	async_exch_t *exch;
-	ipc_call_t answer;
-	aid_t req;
-	errno_t rc;
-	sysarg_t wnd_id;
-	display_window_t *window;
-
-	exch = async_exchange_begin(display->sess);
-	req = async_send_0(exch, DISPLAY_GET_EVENT, &answer);
-	rc = async_data_read_start(exch, event, sizeof(*event));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	wnd_id = ipc_get_arg1(&answer);
-	rc = display_get_window(display, wnd_id, &window);
-	if (rc != EOK)
-		return EIO;
-
-	*rwindow = window;
-	return EOK;
-}
-
-/** Get display information.
- *
- * @param display Display
- * @param info Place to store display information
- * @return EOK on success or an error code
- */
-errno_t display_get_info(display_t *display, display_info_t *info)
-{
-	async_exch_t *exch;
-	ipc_call_t answer;
-	aid_t req;
-	errno_t rc;
-
-	exch = async_exchange_begin(display->sess);
-	req = async_send_0(exch, DISPLAY_GET_INFO, &answer);
-	rc = async_data_read_start(exch, info, sizeof(*info));
-	async_exchange_end(exch);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Display events are pending.
- *
- * @param display Display
- * @param icall Call data
- */
-static void display_ev_pending(display_t *display, ipc_call_t *icall)
-{
-	errno_t rc;
-	display_window_t *window = NULL;
-	display_wnd_ev_t event;
-
-	while (true) {
-		fibril_mutex_lock(&display->lock);
-
-		if (display->sess != NULL)
-			rc = display_get_event(display, &window, &event);
-		else
-			rc = ENOENT;
-
-		fibril_mutex_unlock(&display->lock);
-
-		if (rc != EOK)
-			break;
-
-		switch (event.etype) {
-		case wev_close:
-			if (window->cb != NULL && window->cb->close_event != NULL) {
-				window->cb->close_event(window->cb_arg);
-			}
-			break;
-		case wev_focus:
-			if (window->cb != NULL && window->cb->focus_event != NULL) {
-				window->cb->focus_event(window->cb_arg);
-			}
-			break;
-		case wev_kbd:
-			if (window->cb != NULL && window->cb->kbd_event != NULL) {
-				window->cb->kbd_event(window->cb_arg,
-				    &event.ev.kbd);
-			}
-			break;
-		case wev_pos:
-			if (window->cb != NULL && window->cb->pos_event != NULL) {
-				window->cb->pos_event(window->cb_arg,
-				    &event.ev.pos);
-			}
-			break;
-		case wev_resize:
-			if (window->cb != NULL && window->cb->resize_event != NULL) {
-				window->cb->resize_event(window->cb_arg,
-				    &event.ev.resize.rect);
-			}
-			break;
-		case wev_unfocus:
-			if (window->cb != NULL && window->cb->unfocus_event != NULL) {
-				window->cb->unfocus_event(window->cb_arg);
-			}
-			break;
-		}
-	}
-
-	async_answer_0(icall, EOK);
-}
-
-/** Callback connection handler.
- *
- * @param icall Connect call data
- * @param arg   Argument, display_t *
- */
-static void display_cb_conn(ipc_call_t *icall, void *arg)
-{
-	display_t *display = (display_t *) arg;
-
-	while (true) {
-		ipc_call_t call;
-		async_get_call(&call);
-
-		if (!ipc_get_imethod(&call)) {
-			/* Hangup */
-			async_answer_0(&call, EOK);
-			goto out;
-		}
-
-		switch (ipc_get_imethod(&call)) {
-		case DISPLAY_EV_PENDING:
-			display_ev_pending(display, &call);
-			break;
-		default:
-			async_answer_0(&call, ENOTSUP);
-			break;
-		}
-	}
-
-out:
-	fibril_mutex_lock(&display->lock);
-	display->cb_done = true;
-	fibril_mutex_unlock(&display->lock);
-	fibril_condvar_broadcast(&display->cv);
-}
-
-/** Find window by ID.
- *
- * @param display Display
- * @param wnd_id Window ID
- * @param rwindow Place to store pointer to window
- * @return EOK on success, ENOENT if not found
- */
-static errno_t display_get_window(display_t *display, sysarg_t wnd_id,
-    display_window_t **rwindow)
-{
-	link_t *link;
-	display_window_t *window;
-
-	link = list_first(&display->windows);
-	while (link != NULL) {
-		window = list_get_instance(link, display_window_t, lwindows);
-		if (window->id == wnd_id) {
-			*rwindow = window;
-			return EOK;
-		}
-
-		link = list_next(link, &display->windows);
-	}
-
-	return ENOENT;
-}
-
-/** @}
- */
Index: pace/lib/display/src/wndresize.c
===================================================================
--- uspace/lib/display/src/wndresize.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,98 +1,0 @@
-/*
- * Copyright (c) 2020 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 <assert.h>
-#include <display/wndresize.h>
-#include <stdbool.h>
-
-/** Get stock cursor to use for the specified window resize type.
- *
- * The resize type must be valid, otherwise behavior is undefined.
- * Resize type can be validated using @c display_wndrsz_valid().
- *
- * @param rsztype Resize type
- * @return Cursor to use for this resize type
- */
-display_stock_cursor_t display_cursor_from_wrsz(display_wnd_rsztype_t rsztype)
-{
-	switch (rsztype) {
-	case display_wr_top:
-	case display_wr_bottom:
-		return dcurs_size_ud;
-
-	case display_wr_left:
-	case display_wr_right:
-		return dcurs_size_lr;
-
-	case display_wr_top_left:
-	case display_wr_bottom_right:
-		return dcurs_size_uldr;
-
-	case display_wr_top_right:
-	case display_wr_bottom_left:
-		return dcurs_size_urdl;
-
-	default:
-		assert(false);
-		return dcurs_arrow;
-	}
-}
-
-/** Determine if resize type is valid.
- *
- * Determine if the resize type has one of the valid values. This function
- * should be used when the resize type comes from an untrusted source
- * (such as from the client).
- *
- * @param rsztype Resize type
- * @return @c true iff the resize type is valid
- */
-bool display_wndrsz_valid(display_wnd_rsztype_t rsztype)
-{
-	bool valid;
-
-	valid = false;
-
-	switch (rsztype) {
-	case display_wr_top:
-	case display_wr_bottom:
-	case display_wr_left:
-	case display_wr_right:
-	case display_wr_top_left:
-	case display_wr_bottom_right:
-	case display_wr_top_right:
-	case display_wr_bottom_left:
-		valid = true;
-		break;
-	}
-
-	return valid;
-}
-
-/** @}
- */
Index: pace/lib/display/test/display.c
===================================================================
--- uspace/lib/display/test/display.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,1654 +1,0 @@
-/*
- * Copyright (c) 2019 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 <async.h>
-#include <errno.h>
-#include <display.h>
-#include <disp_srv.h>
-#include <fibril_synch.h>
-#include <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <ipcgfx/server.h>
-#include <loc.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(display);
-
-static const char *test_display_server = "test-display";
-static const char *test_display_svc = "test/display";
-
-static void test_display_conn(ipc_call_t *, void *);
-
-static void test_close_event(void *);
-static void test_focus_event(void *);
-static void test_kbd_event(void *, kbd_event_t *);
-static void test_pos_event(void *, pos_event_t *);
-static void test_unfocus_event(void *);
-
-static errno_t test_window_create(void *, display_wnd_params_t *, sysarg_t *);
-static errno_t test_window_destroy(void *, sysarg_t);
-static errno_t test_window_move_req(void *, sysarg_t, gfx_coord2_t *);
-static errno_t test_window_move(void *, sysarg_t, gfx_coord2_t *);
-static errno_t test_window_resize_req(void *, sysarg_t, display_wnd_rsztype_t,
-    gfx_coord2_t *);
-static errno_t test_window_resize(void *, sysarg_t, gfx_coord2_t *,
-    gfx_rect_t *);
-static errno_t test_window_set_cursor(void *, sysarg_t, display_stock_cursor_t);
-static errno_t test_get_event(void *, sysarg_t *, display_wnd_ev_t *);
-static errno_t test_get_info(void *, display_info_t *);
-
-static errno_t test_gc_set_color(void *, gfx_color_t *);
-
-static display_ops_t test_display_srv_ops = {
-	.window_create = test_window_create,
-	.window_destroy = test_window_destroy,
-	.window_move_req = test_window_move_req,
-	.window_move = test_window_move,
-	.window_resize_req = test_window_resize_req,
-	.window_resize = test_window_resize,
-	.window_set_cursor = test_window_set_cursor,
-	.get_event = test_get_event,
-	.get_info = test_get_info
-};
-
-static display_wnd_cb_t test_display_wnd_cb = {
-	.close_event = test_close_event,
-	.focus_event = test_focus_event,
-	.kbd_event = test_kbd_event,
-	.pos_event = test_pos_event,
-	.unfocus_event = test_unfocus_event
-};
-
-static gfx_context_ops_t test_gc_ops = {
-	.set_color = test_gc_set_color
-};
-
-/** Describes to the server how to respond to our request and pass tracking
- * data back to the client.
- */
-typedef struct {
-	errno_t rc;
-	sysarg_t wnd_id;
-	display_wnd_ev_t event;
-	display_wnd_ev_t revent;
-	int event_cnt;
-	bool window_create_called;
-	gfx_rect_t create_rect;
-	gfx_coord2_t create_min_size;
-	bool window_destroy_called;
-	sysarg_t destroy_wnd_id;
-
-	bool window_move_req_called;
-	sysarg_t move_req_wnd_id;
-	gfx_coord2_t move_req_pos;
-
-	bool window_move_called;
-	sysarg_t move_wnd_id;
-	gfx_coord2_t move_dpos;
-
-	bool window_resize_req_called;
-	sysarg_t resize_req_wnd_id;
-	display_wnd_rsztype_t resize_req_rsztype;
-	gfx_coord2_t resize_req_pos;
-
-	bool window_resize_called;
-	gfx_coord2_t resize_offs;
-	gfx_rect_t resize_nbound;
-	sysarg_t resize_wnd_id;
-
-	bool window_set_cursor_called;
-	sysarg_t set_cursor_wnd_id;
-	display_stock_cursor_t set_cursor_cursor;
-
-	bool get_event_called;
-
-	bool get_info_called;
-	gfx_rect_t get_info_rect;
-
-	bool set_color_called;
-	bool close_event_called;
-	bool focus_event_called;
-	bool kbd_event_called;
-	bool pos_event_called;
-	bool unfocus_event_called;
-	fibril_condvar_t event_cv;
-	fibril_mutex_t event_lock;
-	display_srv_t *srv;
-} test_response_t;
-
-/** display_open(), display_close() work for valid display service */
-PCUT_TEST(open_close)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_create() with server returning error response works */
-PCUT_TEST(window_create_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	wnd = NULL;
-	resp.rc = ENOMEM;
-	resp.window_create_called = false;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-	params.min_size.x = 11;
-	params.min_size.y = 12;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_TRUE(resp.window_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.create_rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.create_rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.create_rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.create_rect.p1.y);
-	PCUT_ASSERT_EQUALS(params.min_size.x, resp.create_min_size.x);
-	PCUT_ASSERT_EQUALS(params.min_size.y, resp.create_min_size.y);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_NULL(wnd);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_create() and display_window_destroy() with success
- *
- * with server returning success,
- */
-PCUT_TEST(window_create_destroy_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	resp.window_create_called = false;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_TRUE(resp.window_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.create_rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.create_rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.create_rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.create_rect.p1.y);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.window_destroy_called = false;
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_TRUE(resp.window_destroy_called);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.destroy_wnd_id);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_create() with server returning error response works. */
-PCUT_TEST(window_destroy_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	resp.window_create_called = false;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_TRUE(resp.window_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.create_rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.create_rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.create_rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.create_rect.p1.y);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EIO;
-	resp.window_destroy_called = false;
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_TRUE(resp.window_destroy_called);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.destroy_wnd_id);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_move_req() with server returning error response works. */
-PCUT_TEST(window_move_req_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-	gfx_coord2_t pos;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EIO;
-	resp.window_move_req_called = false;
-
-	pos.x = 42;
-	pos.y = 43;
-
-	rc = display_window_move_req(wnd, &pos);
-	PCUT_ASSERT_TRUE(resp.window_move_req_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_req_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(pos.x, resp.move_req_pos.x);
-	PCUT_ASSERT_INT_EQUALS(pos.y, resp.move_req_pos.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_move_req() with server returning success response works. */
-PCUT_TEST(window_move_req_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-	gfx_coord2_t pos;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EOK;
-	resp.window_move_req_called = false;
-
-	pos.x = 42;
-	pos.y = 43;
-
-	rc = display_window_move_req(wnd, &pos);
-	PCUT_ASSERT_TRUE(resp.window_move_req_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_req_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(pos.x, resp.move_req_pos.x);
-	PCUT_ASSERT_INT_EQUALS(pos.y, resp.move_req_pos.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_move() with server returning error response works. */
-PCUT_TEST(window_move_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	gfx_coord2_t dpos;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EIO;
-	resp.window_move_called = false;
-	dpos.x = 11;
-	dpos.y = 12;
-
-	rc = display_window_move(wnd, &dpos);
-	PCUT_ASSERT_TRUE(resp.window_move_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(dpos.x, resp.move_dpos.x);
-	PCUT_ASSERT_INT_EQUALS(dpos.y, resp.move_dpos.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_move() with server returning success response works. */
-PCUT_TEST(window_move_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	gfx_coord2_t dpos;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EOK;
-	resp.window_move_called = false;
-	dpos.x = 11;
-	dpos.y = 12;
-
-	rc = display_window_move(wnd, &dpos);
-	PCUT_ASSERT_TRUE(resp.window_move_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(dpos.x, resp.move_dpos.x);
-	PCUT_ASSERT_INT_EQUALS(dpos.y, resp.move_dpos.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_resize_req() with server returning error response works. */
-PCUT_TEST(window_resize_req_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-	display_wnd_rsztype_t rsztype;
-	gfx_coord2_t pos;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EIO;
-	resp.window_resize_req_called = false;
-
-	rsztype = display_wr_top_right;
-	pos.x = 42;
-	pos.y = 43;
-
-	rc = display_window_resize_req(wnd, rsztype, &pos);
-	PCUT_ASSERT_TRUE(resp.window_resize_req_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(rsztype, resp.resize_req_rsztype);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.resize_req_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(pos.x, resp.resize_req_pos.x);
-	PCUT_ASSERT_INT_EQUALS(pos.y, resp.resize_req_pos.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_resize_req() with server returning success response works. */
-PCUT_TEST(window_resize_req_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-	display_wnd_rsztype_t rsztype;
-	gfx_coord2_t pos;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EOK;
-	resp.window_resize_req_called = false;
-
-	rsztype = display_wr_top_right;
-	pos.x = 42;
-	pos.y = 43;
-
-	rc = display_window_resize_req(wnd, rsztype, &pos);
-	PCUT_ASSERT_TRUE(resp.window_resize_req_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(rsztype, resp.resize_req_rsztype);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.resize_req_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(pos.x, resp.resize_req_pos.x);
-	PCUT_ASSERT_INT_EQUALS(pos.y, resp.resize_req_pos.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_resize() with server returning error response works. */
-PCUT_TEST(window_resize_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	gfx_coord2_t offs;
-	gfx_rect_t nrect;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EIO;
-	resp.window_resize_called = false;
-	offs.x = 11;
-	offs.y = 12;
-	nrect.p0.x = 13;
-	nrect.p0.y = 14;
-	nrect.p1.x = 15;
-	nrect.p1.y = 16;
-
-	rc = display_window_resize(wnd, &offs, &nrect);
-	PCUT_ASSERT_TRUE(resp.window_resize_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.resize_wnd_id);
-	PCUT_ASSERT_INT_EQUALS(offs.x, resp.resize_offs.x);
-	PCUT_ASSERT_INT_EQUALS(offs.y, resp.resize_offs.y);
-	PCUT_ASSERT_INT_EQUALS(nrect.p0.x, resp.resize_nbound.p0.x);
-	PCUT_ASSERT_INT_EQUALS(nrect.p0.y, resp.resize_nbound.p0.y);
-	PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
-	PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_resize() with server returning success response works. */
-PCUT_TEST(window_resize_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	gfx_coord2_t offs;
-	gfx_rect_t nrect;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EOK;
-	resp.window_resize_called = false;
-	offs.x = 11;
-	offs.y = 12;
-	nrect.p0.x = 13;
-	nrect.p0.y = 14;
-	nrect.p1.x = 15;
-	nrect.p1.y = 16;
-
-	rc = display_window_resize(wnd, &offs, &nrect);
-	PCUT_ASSERT_TRUE(resp.window_resize_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(offs.x, resp.resize_offs.x);
-	PCUT_ASSERT_INT_EQUALS(offs.y, resp.resize_offs.y);
-	PCUT_ASSERT_INT_EQUALS(nrect.p0.x, resp.resize_nbound.p0.x);
-	PCUT_ASSERT_INT_EQUALS(nrect.p0.y, resp.resize_nbound.p0.y);
-	PCUT_ASSERT_INT_EQUALS(nrect.p1.x, resp.resize_nbound.p1.x);
-	PCUT_ASSERT_INT_EQUALS(nrect.p1.y, resp.resize_nbound.p1.y);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_set_cursor() with server returning error response works. */
-PCUT_TEST(window_set_cursor_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EIO;
-	resp.window_set_cursor_called = false;
-
-	rc = display_window_set_cursor(wnd, dcurs_size_ud);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.set_cursor_wnd_id);
-	PCUT_ASSERT_TRUE(resp.window_set_cursor_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_ud, resp.set_cursor_cursor);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_set_cursor() with server returning success response works. */
-PCUT_TEST(window_set_cursor_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.rc = EOK;
-	resp.window_set_cursor_called = false;
-
-	rc = display_window_set_cursor(wnd, dcurs_size_ud);
-	PCUT_ASSERT_INT_EQUALS(wnd->id, resp.set_cursor_wnd_id);
-	PCUT_ASSERT_TRUE(resp.window_set_cursor_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, EOK);
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_ud, resp.set_cursor_cursor);
-
-	display_window_destroy(wnd);
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_get_gc with server returning failure */
-PCUT_TEST(window_get_gc_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-	gfx_context_t *gc;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	gc = NULL;
-	resp.rc = ENOMEM;
-	rc = display_window_get_gc(wnd, &gc);
-	/* async_connect_me_to() does not return specific error */
-	PCUT_ASSERT_ERRNO_VAL(EIO, rc);
-	PCUT_ASSERT_NULL(gc);
-
-	resp.rc = EOK;
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_window_get_gc with server returning success */
-PCUT_TEST(window_get_gc_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_color_t *color;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	gc = NULL;
-	rc = display_window_get_gc(wnd, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	resp.set_color_called = false;
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.set_color_called);
-
-	gfx_color_delete(color);
-
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Close event can be delivered from server to client callback function */
-PCUT_TEST(close_event_deliver)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-	PCUT_ASSERT_NOT_NULL(resp.srv);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.event_cnt = 1;
-	resp.event.etype = wev_close;
-	resp.wnd_id = wnd->id;
-	resp.close_event_called = false;
-	fibril_mutex_initialize(&resp.event_lock);
-	fibril_condvar_initialize(&resp.event_cv);
-	display_srv_ev_pending(resp.srv);
-
-	/* Wait for the event handler to be called. */
-	fibril_mutex_lock(&resp.event_lock);
-	while (!resp.close_event_called) {
-		fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
-	}
-	fibril_mutex_unlock(&resp.event_lock);
-
-	/* Verify that the event was delivered correctly */
-	PCUT_ASSERT_INT_EQUALS(resp.event.etype,
-	    resp.revent.etype);
-
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Focus event can be delivered from server to client callback function */
-PCUT_TEST(focus_event_deliver)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-	PCUT_ASSERT_NOT_NULL(resp.srv);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.event_cnt = 1;
-	resp.event.etype = wev_focus;
-	resp.wnd_id = wnd->id;
-	resp.focus_event_called = false;
-	fibril_mutex_initialize(&resp.event_lock);
-	fibril_condvar_initialize(&resp.event_cv);
-	display_srv_ev_pending(resp.srv);
-
-	/* Wait for the event handler to be called. */
-	fibril_mutex_lock(&resp.event_lock);
-	while (!resp.focus_event_called) {
-		fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
-	}
-	fibril_mutex_unlock(&resp.event_lock);
-
-	/* Verify that the event was delivered correctly */
-	PCUT_ASSERT_INT_EQUALS(resp.event.etype,
-	    resp.revent.etype);
-
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Keyboard event can be delivered from server to client callback function */
-PCUT_TEST(kbd_event_deliver)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-	PCUT_ASSERT_NOT_NULL(resp.srv);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.event_cnt = 1;
-	resp.event.etype = wev_kbd;
-	resp.event.ev.kbd.type = KEY_PRESS;
-	resp.event.ev.kbd.key = KC_ENTER;
-	resp.event.ev.kbd.mods = 0;
-	resp.event.ev.kbd.c = L'\0';
-	resp.wnd_id = wnd->id;
-	resp.kbd_event_called = false;
-	fibril_mutex_initialize(&resp.event_lock);
-	fibril_condvar_initialize(&resp.event_cv);
-	display_srv_ev_pending(resp.srv);
-
-	/* Wait for the event handler to be called. */
-	fibril_mutex_lock(&resp.event_lock);
-	while (!resp.kbd_event_called) {
-		fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
-	}
-	fibril_mutex_unlock(&resp.event_lock);
-
-	/* Verify that the event was delivered correctly */
-	PCUT_ASSERT_INT_EQUALS(resp.event.etype,
-	    resp.revent.etype);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.kbd.type,
-	    resp.revent.ev.kbd.type);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.kbd.key,
-	    resp.revent.ev.kbd.key);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.kbd.mods,
-	    resp.revent.ev.kbd.mods);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.kbd.c,
-	    resp.revent.ev.kbd.c);
-
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Position event can be delivered from server to client callback function */
-PCUT_TEST(pos_event_deliver)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-	PCUT_ASSERT_NOT_NULL(resp.srv);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.event_cnt = 1;
-	resp.event.etype = wev_pos;
-	resp.event.ev.pos.type = POS_PRESS;
-	resp.event.ev.pos.btn_num = 1;
-	resp.event.ev.pos.hpos = 2;
-	resp.event.ev.pos.vpos = 3;
-	resp.wnd_id = wnd->id;
-	resp.pos_event_called = false;
-	fibril_mutex_initialize(&resp.event_lock);
-	fibril_condvar_initialize(&resp.event_cv);
-	display_srv_ev_pending(resp.srv);
-
-	/* Wait for the event handler to be called. */
-	fibril_mutex_lock(&resp.event_lock);
-	while (!resp.pos_event_called) {
-		fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
-	}
-	fibril_mutex_unlock(&resp.event_lock);
-
-	/* Verify that the event was delivered correctly */
-	PCUT_ASSERT_INT_EQUALS(resp.event.etype,
-	    resp.revent.etype);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.pos.type,
-	    resp.revent.ev.pos.type);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.pos.btn_num,
-	    resp.revent.ev.pos.btn_num);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.pos.hpos,
-	    resp.revent.ev.pos.hpos);
-	PCUT_ASSERT_INT_EQUALS(resp.event.ev.pos.vpos,
-	    resp.revent.ev.pos.vpos);
-
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Unfocus event can be delivered from server to client callback function */
-PCUT_TEST(unfocus_event_deliver)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_wnd_params_t params;
-	display_window_t *wnd;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-	PCUT_ASSERT_NOT_NULL(resp.srv);
-
-	wnd = NULL;
-	resp.rc = EOK;
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p0.x = 100;
-	params.rect.p0.y = 100;
-
-	rc = display_window_create(disp, &params, &test_display_wnd_cb,
-	    (void *) &resp, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(wnd);
-
-	resp.event_cnt = 1;
-	resp.event.etype = wev_unfocus;
-	resp.wnd_id = wnd->id;
-	resp.unfocus_event_called = false;
-	fibril_mutex_initialize(&resp.event_lock);
-	fibril_condvar_initialize(&resp.event_cv);
-	display_srv_ev_pending(resp.srv);
-
-	/* Wait for the event handler to be called. */
-	fibril_mutex_lock(&resp.event_lock);
-	while (!resp.unfocus_event_called) {
-		fibril_condvar_wait(&resp.event_cv, &resp.event_lock);
-	}
-	fibril_mutex_unlock(&resp.event_lock);
-
-	/* Verify that the event was delivered correctly */
-	PCUT_ASSERT_INT_EQUALS(resp.event.etype,
-	    resp.revent.etype);
-
-	rc = display_window_destroy(wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_close(disp);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_get_info() with server returning failure response works. */
-PCUT_TEST(get_info_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_info_t info;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = ENOMEM;
-	resp.get_info_called = false;
-
-	rc = display_get_info(disp, &info);
-	PCUT_ASSERT_TRUE(resp.get_info_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** display_get_info() with server returning success response works. */
-PCUT_TEST(get_info_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	display_t *disp = NULL;
-	display_info_t info;
-	test_response_t resp;
-
-	async_set_fallback_port_handler(test_display_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_display_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_display_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = display_open(test_display_svc, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(disp);
-
-	resp.rc = EOK;
-	resp.get_info_called = false;
-	resp.get_info_rect.p0.x = 10;
-	resp.get_info_rect.p0.y = 11;
-	resp.get_info_rect.p1.x = 20;
-	resp.get_info_rect.p1.y = 21;
-
-	rc = display_get_info(disp, &info);
-	PCUT_ASSERT_TRUE(resp.get_info_called);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_INT_EQUALS(resp.get_info_rect.p0.x, info.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(resp.get_info_rect.p0.y, info.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(resp.get_info_rect.p1.x, info.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(resp.get_info_rect.p1.y, info.rect.p1.y);
-
-	display_close(disp);
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Test display service connection.
- *
- * This is very similar to connection handler in the display server.
- * XXX This should be folded into display_srv, if possible
- */
-static void test_display_conn(ipc_call_t *icall, void *arg)
-{
-	test_response_t *resp = (test_response_t *) arg;
-	display_srv_t srv;
-	sysarg_t wnd_id;
-	sysarg_t svc_id;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	svc_id = ipc_get_arg2(icall);
-	wnd_id = ipc_get_arg3(icall);
-
-	if (svc_id != 0) {
-		/* Set up protocol structure */
-		display_srv_initialize(&srv);
-		srv.ops = &test_display_srv_ops;
-		srv.arg = arg;
-		resp->srv = &srv;
-
-		/* Handle connection */
-		display_conn(icall, &srv);
-
-		resp->srv = NULL;
-	} else {
-		(void) wnd_id;
-
-		if (resp->rc != EOK) {
-			async_answer_0(icall, resp->rc);
-			return;
-		}
-
-		rc = gfx_context_new(&test_gc_ops, arg, &gc);
-		if (rc != EOK) {
-			async_answer_0(icall, ENOMEM);
-			return;
-		}
-
-		/* Window GC connection */
-		gc_conn(icall, gc);
-	}
-}
-
-static void test_close_event(void *arg)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->revent.etype = wev_close;
-
-	fibril_mutex_lock(&resp->event_lock);
-	resp->close_event_called = true;
-	fibril_condvar_broadcast(&resp->event_cv);
-	fibril_mutex_unlock(&resp->event_lock);
-}
-
-static void test_focus_event(void *arg)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->revent.etype = wev_focus;
-
-	fibril_mutex_lock(&resp->event_lock);
-	resp->focus_event_called = true;
-	fibril_condvar_broadcast(&resp->event_cv);
-	fibril_mutex_unlock(&resp->event_lock);
-}
-
-static void test_kbd_event(void *arg, kbd_event_t *event)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->revent.etype = wev_kbd;
-	resp->revent.ev.kbd = *event;
-
-	fibril_mutex_lock(&resp->event_lock);
-	resp->kbd_event_called = true;
-	fibril_condvar_broadcast(&resp->event_cv);
-	fibril_mutex_unlock(&resp->event_lock);
-}
-
-static void test_pos_event(void *arg, pos_event_t *event)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->revent.etype = wev_pos;
-	resp->revent.ev.pos = *event;
-
-	fibril_mutex_lock(&resp->event_lock);
-	resp->pos_event_called = true;
-	fibril_condvar_broadcast(&resp->event_cv);
-	fibril_mutex_unlock(&resp->event_lock);
-}
-
-static void test_unfocus_event(void *arg)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->revent.etype = wev_unfocus;
-
-	fibril_mutex_lock(&resp->event_lock);
-	resp->unfocus_event_called = true;
-	fibril_condvar_broadcast(&resp->event_cv);
-	fibril_mutex_unlock(&resp->event_lock);
-}
-
-static errno_t test_window_create(void *arg, display_wnd_params_t *params,
-    sysarg_t *rwnd_id)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_create_called = true;
-	resp->create_rect = params->rect;
-	resp->create_min_size = params->min_size;
-	if (resp->rc == EOK)
-		*rwnd_id = resp->wnd_id;
-
-	return resp->rc;
-}
-
-static errno_t test_window_destroy(void *arg, sysarg_t wnd_id)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_destroy_called = true;
-	resp->destroy_wnd_id = wnd_id;
-	return resp->rc;
-}
-
-static errno_t test_window_move_req(void *arg, sysarg_t wnd_id,
-    gfx_coord2_t *pos)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_move_req_called = true;
-	resp->move_req_wnd_id = wnd_id;
-	resp->move_req_pos = *pos;
-	return resp->rc;
-}
-
-static errno_t test_window_move(void *arg, sysarg_t wnd_id, gfx_coord2_t *dpos)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_move_called = true;
-	resp->move_wnd_id = wnd_id;
-	resp->move_dpos = *dpos;
-	return resp->rc;
-}
-
-static errno_t test_window_resize_req(void *arg, sysarg_t wnd_id,
-    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_resize_req_called = true;
-	resp->resize_req_rsztype = rsztype;
-	resp->resize_req_wnd_id = wnd_id;
-	resp->resize_req_pos = *pos;
-	return resp->rc;
-}
-
-static errno_t test_window_resize(void *arg, sysarg_t wnd_id,
-    gfx_coord2_t *offs, gfx_rect_t *nrect)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_resize_called = true;
-	resp->resize_wnd_id = wnd_id;
-	resp->resize_offs = *offs;
-	resp->resize_nbound = *nrect;
-	return resp->rc;
-}
-
-static errno_t test_window_set_cursor(void *arg, sysarg_t wnd_id,
-    display_stock_cursor_t cursor)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->window_set_cursor_called = true;
-	resp->set_cursor_wnd_id = wnd_id;
-	resp->set_cursor_cursor = cursor;
-
-	return resp->rc;
-}
-
-static errno_t test_get_event(void *arg, sysarg_t *wnd_id,
-    display_wnd_ev_t *event)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->get_event_called = true;
-	if (resp->event_cnt > 0) {
-		--resp->event_cnt;
-		*wnd_id = resp->wnd_id;
-		*event = resp->event;
-		return EOK;
-	}
-
-	return ENOENT;
-}
-
-static errno_t test_get_info(void *arg, display_info_t *info)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->get_info_called = true;
-	info->rect = resp->get_info_rect;
-
-	return resp->rc;
-}
-
-static errno_t test_gc_set_color(void *arg, gfx_color_t *color)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->set_color_called = true;
-	return resp->rc;
-}
-
-PCUT_EXPORT(display);
Index: pace/lib/display/test/main.c
===================================================================
--- uspace/lib/display/test/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,36 +1,0 @@
-/*
- * Copyright (c) 2020 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 <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_IMPORT(display);
-PCUT_IMPORT(wndresize);
-
-PCUT_MAIN();
Index: pace/lib/display/test/wndresize.c
===================================================================
--- uspace/lib/display/test/wndresize.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,91 +1,0 @@
-/*
- * Copyright (c) 2020 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 <display/wndresize.h>
-#include <errno.h>
-#include <limits.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(wndresize);
-
-/** display_cursor_from_wrsz() correctly translates resize type to cursor */
-PCUT_TEST(cursor_from_wrsz)
-{
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_ud,
-	    display_cursor_from_wrsz(display_wr_top));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_ud,
-	    display_cursor_from_wrsz(display_wr_bottom));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_lr,
-	    display_cursor_from_wrsz(display_wr_left));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_lr,
-	    display_cursor_from_wrsz(display_wr_right));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_uldr,
-	    display_cursor_from_wrsz(display_wr_top_left));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_uldr,
-	    display_cursor_from_wrsz(display_wr_bottom_right));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_urdl,
-	    display_cursor_from_wrsz(display_wr_top_right));
-	PCUT_ASSERT_INT_EQUALS(dcurs_size_urdl,
-	    display_cursor_from_wrsz(display_wr_bottom_left));
-}
-
-/** display_wndrsz_valid() correctly verifies window resize type */
-PCUT_TEST(wndrsz_valid)
-{
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(INT_MIN));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(display_wr_top - 1));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_top));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_left));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_bottom));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_right));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_top_left));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_top_right));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_bottom_left));
-	PCUT_ASSERT_TRUE(display_wndrsz_valid(display_wr_bottom_right));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(display_wr_bottom_right + 1));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_top | display_wr_bottom));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_left | display_wr_right));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_top | display_wr_left | display_wr_right));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_bottom | display_wr_left | display_wr_right));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_top | display_wr_bottom | display_wr_left));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_top | display_wr_bottom | display_wr_right));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(
-	    display_wr_top | display_wr_bottom |
-	    display_wr_left | display_wr_right));
-	PCUT_ASSERT_FALSE(display_wndrsz_valid(INT_MAX));
-}
-
-PCUT_EXPORT(wndresize);
Index: pace/lib/gfx/doc/doxygroups.h
===================================================================
--- uspace/lib/gfx/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libgfx libgfx
- * @ingroup libs
- */
Index: pace/lib/gfx/include/gfx/bitmap.h
===================================================================
--- uspace/lib/gfx/include/gfx/bitmap.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Bitmap
- */
-
-#ifndef _GFX_BITMAP_H
-#define _GFX_BITMAP_H
-
-#include <errno.h>
-#include <types/gfx/context.h>
-#include <types/gfx/coord.h>
-#include <types/gfx/bitmap.h>
-
-extern void gfx_bitmap_params_init(gfx_bitmap_params_t *);
-extern errno_t gfx_bitmap_create(gfx_context_t *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, gfx_bitmap_t **);
-extern errno_t gfx_bitmap_destroy(gfx_bitmap_t *);
-extern errno_t gfx_bitmap_render(gfx_bitmap_t *, gfx_rect_t *, gfx_coord2_t *);
-extern errno_t gfx_bitmap_get_alloc(gfx_bitmap_t *, gfx_bitmap_alloc_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/gfx/color.h
===================================================================
--- uspace/lib/gfx/include/gfx/color.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Color operations
- */
-
-#ifndef _GFX_COLOR_H
-#define _GFX_COLOR_H
-
-#include <errno.h>
-#include <stdint.h>
-#include <types/gfx/color.h>
-
-extern errno_t gfx_color_new_rgb_i16(uint16_t, uint16_t,
-    uint16_t, gfx_color_t **);
-extern void gfx_color_delete(gfx_color_t *);
-extern void gfx_color_get_rgb_i16(gfx_color_t *, uint16_t *, uint16_t *,
-    uint16_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/gfx/context.h
===================================================================
--- uspace/lib/gfx/include/gfx/context.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphic context
- *
- * A graphics context is the target of rendering operations. It can carry
- * some additional state (hence context). It is an abstract interface,
- * to be implemented by various backends (drivers).
- */
-
-#ifndef _GFX_CONTEXT_H
-#define _GFX_CONTEXT_H
-
-#include <errno.h>
-#include <types/gfx/context.h>
-#include <types/gfx/ops/context.h>
-
-extern errno_t gfx_context_new(gfx_context_ops_t *, void *,
-    gfx_context_t **);
-extern errno_t gfx_context_delete(gfx_context_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/gfx/coord.h
===================================================================
--- uspace/lib/gfx/include/gfx/coord.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphic coordinates
- */
-
-#ifndef _GFX_COORD_H
-#define _GFX_COORD_H
-
-#include <stdbool.h>
-#include <types/gfx/coord.h>
-
-extern void gfx_coord2_add(gfx_coord2_t *, gfx_coord2_t *, gfx_coord2_t *);
-extern void gfx_coord2_subtract(gfx_coord2_t *, gfx_coord2_t *, gfx_coord2_t *);
-extern void gfx_coord2_clip(gfx_coord2_t *, gfx_rect_t *, gfx_coord2_t *);
-extern void gfx_coord2_project(gfx_coord2_t *, gfx_rect_t *, gfx_rect_t *,
-    gfx_coord2_t *);
-extern void gfx_span_points_sort(gfx_coord_t, gfx_coord_t, gfx_coord_t *,
-    gfx_coord_t *);
-extern void gfx_rect_translate(gfx_coord2_t *, gfx_rect_t *, gfx_rect_t *);
-extern void gfx_rect_rtranslate(gfx_coord2_t *, gfx_rect_t *, gfx_rect_t *);
-extern void gfx_rect_envelope(gfx_rect_t *, gfx_rect_t *, gfx_rect_t *);
-extern void gfx_rect_clip(gfx_rect_t *, gfx_rect_t *, gfx_rect_t *);
-extern void gfx_rect_points_sort(gfx_rect_t *, gfx_rect_t *);
-extern void gfx_rect_dims(gfx_rect_t *, gfx_coord2_t *);
-extern bool gfx_rect_is_empty(gfx_rect_t *);
-extern bool gfx_rect_is_incident(gfx_rect_t *, gfx_rect_t *);
-extern bool gfx_rect_is_inside(gfx_rect_t *, gfx_rect_t *);
-extern bool gfx_pix_inside_rect(gfx_coord2_t *, gfx_rect_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/gfx/render.h
===================================================================
--- uspace/lib/gfx/include/gfx/render.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,50 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Rendering operations
- */
-
-#ifndef _GFX_RENDER_H
-#define _GFX_RENDER_H
-
-#include <errno.h>
-#include <types/gfx/color.h>
-#include <types/gfx/coord.h>
-#include <types/gfx/context.h>
-
-extern errno_t gfx_set_color(gfx_context_t *, gfx_color_t *);
-extern errno_t gfx_fill_rect(gfx_context_t *, gfx_rect_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/types/gfx/bitmap.h
===================================================================
--- uspace/lib/gfx/include/types/gfx/bitmap.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,78 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Color types
- */
-
-#ifndef _GFX_TYPES_BITMAP_H
-#define _GFX_TYPES_BITMAP_H
-
-#include <errno.h>
-#include <io/pixel.h>
-#include <stddef.h>
-#include <types/gfx/coord.h>
-
-struct gfx_bitmap;
-typedef struct gfx_bitmap gfx_bitmap_t;
-
-/** Bitmap flags */
-typedef enum {
-	/** Enable color key */
-	bmpf_color_key = 0x1,
-	/** Directly map GC output into this bitmap */
-	bmpf_direct_output = 0x2
-} gfx_bitmap_flags_t;
-
-/** Bitmap parameters */
-typedef struct {
-	/** Rectangle represented in pixel array */
-	gfx_rect_t rect;
-	/** Bitmap flags */
-	gfx_bitmap_flags_t flags;
-	/** Key color */
-	pixel_t key_color;
-} gfx_bitmap_params_t;
-
-/** Bitmap allocation info */
-typedef struct {
-	/** Byte offset from one successive line to the next */
-	int pitch;
-	/** Byte offset of first pixel */
-	size_t off0;
-	/** Pixel array */
-	void *pixels;
-} gfx_bitmap_alloc_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/types/gfx/color.h
===================================================================
--- uspace/lib/gfx/include/types/gfx/color.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Color types
- */
-
-#ifndef _GFX_TYPES_COLOR_H
-#define _GFX_TYPES_COLOR_H
-
-#include <errno.h>
-#include <stdint.h>
-
-struct gfx_color;
-typedef struct gfx_color gfx_color_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/types/gfx/context.h
===================================================================
--- uspace/lib/gfx/include/types/gfx/context.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphics context
- *
- * A graphics context is the target of rendering operations. It can carry
- * some additional state (hence context). It is an abstract interface,
- * to be implemented by various backends (drivers).
- */
-
-#ifndef _GFX_TYPES_CONTEXT_H
-#define _GFX_TYPES_CONTEXT_H
-
-struct gfx_context;
-typedef struct gfx_context gfx_context_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/types/gfx/coord.h
===================================================================
--- uspace/lib/gfx/include/types/gfx/coord.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphic coordinates
- */
-
-#ifndef _GFX_TYPES_COORD_H
-#define _GFX_TYPES_COORD_H
-
-#include <errno.h>
-#include <stdint.h>
-
-typedef int gfx_coord_t;
-
-typedef struct {
-	gfx_coord_t x;
-	gfx_coord_t y;
-} gfx_coord2_t;
-
-typedef struct {
-	gfx_coord2_t p0;
-	gfx_coord2_t p1;
-} gfx_rect_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/include/types/gfx/ops/context.h
===================================================================
--- uspace/lib/gfx/include/types/gfx/ops/context.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,67 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphics context ops
- *
- * The ops structure describing an implementation of a graphics context.
- */
-
-#ifndef _GFX_TYPES_OPS_CONTEXT_H
-#define _GFX_TYPES_OPS_CONTEXT_H
-
-#include <errno.h>
-#include <types/gfx/bitmap.h>
-#include <types/gfx/color.h>
-#include <types/gfx/coord.h>
-#include <types/gfx/context.h>
-
-/** Graphics context ops */
-typedef struct {
-	/** Set drawing color */
-	errno_t (*set_color)(void *, gfx_color_t *);
-	/** Fill rectangle using the current drawing color */
-	errno_t (*fill_rect)(void *, gfx_rect_t *);
-	/** Create bitmap */
-	errno_t (*bitmap_create)(void *, gfx_bitmap_params_t *,
-	    gfx_bitmap_alloc_t *, void **);
-	/** Destroy bitmap */
-	errno_t (*bitmap_destroy)(void *);
-	/** Render bitmap */
-	errno_t (*bitmap_render)(void *, gfx_rect_t *, gfx_coord2_t *);
-	/** Get bitmap allocation info */
-	errno_t (*bitmap_get_alloc)(void *, gfx_bitmap_alloc_t *);
-} gfx_context_ops_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/meson.build
===================================================================
--- uspace/lib/gfx/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-src = files(
-	'src/bitmap.c',
-	'src/color.c',
-	'src/coord.c',
-	'src/context.c',
-	'src/render.c'
-)
-
-test_src = files(
-	'test/bitmap.c',
-	'test/color.c',
-	'test/coord.c',
-	'test/main.c',
-	'test/render.c',
-)
Index: pace/lib/gfx/private/bitmap.h
===================================================================
--- uspace/lib/gfx/private/bitmap.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Bitmap structure
- *
- */
-
-#ifndef _GFX_PRIVATE_BITMAP_H
-#define _GFX_PRIVATE_BITMAP_H
-
-#include <types/gfx/context.h>
-
-/** Bitmap
- *
- * This is private to libgfx. It is not visible to clients nor backends.
- */
-struct gfx_bitmap {
-	/** Graphics context of the bitmap */
-	gfx_context_t *gc;
-	/** GC-private data */
-	void *gc_priv;
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/private/color.h
===================================================================
--- uspace/lib/gfx/private/color.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Color structure
- *
- */
-
-#ifndef _GFX_PRIVATE_COLOR_H
-#define _GFX_PRIVATE_COLOR_H
-
-/** Actual structure of graphics color.
- *
- * This is private to libgfx. It is not visible to clients nor backends.
- */
-struct gfx_color {
-	uint16_t r;
-	uint16_t g;
-	uint16_t b;
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/private/context.h
===================================================================
--- uspace/lib/gfx/private/context.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphics context structure
- *
- */
-
-#ifndef _GFX_PRIVATE_CONTEXT_H
-#define _GFX_PRIVATE_CONTEXT_H
-
-#include <types/gfx/ops/context.h>
-
-/** Actual structure of graphics context.
- *
- * This is private to libgfx. It is not visible to clients nor backends.
- */
-struct gfx_context {
-	/** Graphics context ops */
-	gfx_context_ops_t *ops;
-	/** Instance argument */
-	void *arg;
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/gfx/src/bitmap.c
===================================================================
--- uspace/lib/gfx/src/bitmap.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,135 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Bitmap
- */
-
-#include <gfx/bitmap.h>
-#include <mem.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include "../private/bitmap.h"
-#include "../private/context.h"
-
-/** Initialize bitmap parameters structure.
- *
- * Bitmap parameters structure must always be initialized using this function
- * first.
- *
- * @param params Bitmap parameters structure
- */
-void gfx_bitmap_params_init(gfx_bitmap_params_t *params)
-{
-	memset(params, 0, sizeof(gfx_bitmap_params_t));
-}
-
-/** Allocate bitmap in a graphics context.
- *
- * @param gc Graphic context
- * @param params Bitmap parameters
- * @param alloc Bitmap allocation info or @c NULL to let GC allocate
- *               pixel storage
- * @param rbitmap Place to store pointer to new bitmap
- *
- * @return EOK on success, EINVAL if parameters are invald,
- *         ENOMEM if insufficient resources, EIO if grahic device connection
- *         was lost
- */
-errno_t gfx_bitmap_create(gfx_context_t *gc, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, gfx_bitmap_t **rbitmap)
-{
-	void *bm_priv;
-	gfx_bitmap_t *bitmap;
-	errno_t rc;
-
-	bitmap = calloc(1, sizeof(gfx_bitmap_t));
-	if (bitmap == NULL)
-		return ENOMEM;
-
-	rc = gc->ops->bitmap_create(gc->arg, params, alloc, &bm_priv);
-	if (rc != EOK) {
-		free(bitmap);
-		return rc;
-	}
-
-	bitmap->gc = gc;
-	bitmap->gc_priv = bm_priv;
-	*rbitmap = bitmap;
-	return EOK;
-}
-
-/** Destroy bitmap from graphics context.
- *
- * @param bitmap Bitmap
- *
- * @return EOK on success, EIO if grahic device connection was lost
- */
-errno_t gfx_bitmap_destroy(gfx_bitmap_t *bitmap)
-{
-	errno_t rc;
-
-	rc = bitmap->gc->ops->bitmap_destroy(bitmap->gc_priv);
-	if (rc != EOK)
-		return rc;
-
-	free(bitmap);
-	return EOK;
-}
-
-/** Render bitmap in graphics context.
- *
- * @param bitmap Bitmap
- * @param srect Source rectangle or @c NULL to render entire bitmap
- * @param offs Bitmap offset or @c NULL for zero offset
- *
- * @return EOK on success, EIO if grahic device connection was lost
- */
-errno_t gfx_bitmap_render(gfx_bitmap_t *bitmap, gfx_rect_t *srect,
-    gfx_coord2_t *offs)
-{
-	return bitmap->gc->ops->bitmap_render(bitmap->gc_priv, srect, offs);
-}
-
-/** Get bitmap allocation info.
- *
- * @param bitmap Bitmap
- * @param alloc Allocation info structure to fill in
- *
- * @return EOK on success, EIO if grahic device connection was lost
- */
-errno_t gfx_bitmap_get_alloc(gfx_bitmap_t *bitmap, gfx_bitmap_alloc_t *alloc)
-{
-	return bitmap->gc->ops->bitmap_get_alloc(bitmap->gc_priv, alloc);
-}
-
-/** @}
- */
Index: pace/lib/gfx/src/color.c
===================================================================
--- uspace/lib/gfx/src/color.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,96 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Color operations
- */
-
-#include <gfx/color.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include "../private/color.h"
-
-/** Create new 16-bit per channel RGB color.
- *
- * Create a new RGB color where the R, G, B components have 16 bits
- * of precision each.
- *
- * @param r Red component
- * @param g Green component
- * @param b Blue component
- * @param rcolor Place to store pointer to new color
- *
- * @return EOK on success or an error code, ENOMEM if out of resources,
- *         EIO if the graphic device connection was lost
- */
-errno_t gfx_color_new_rgb_i16(uint16_t r, uint16_t g, uint16_t b,
-    gfx_color_t **rcolor)
-{
-	gfx_color_t *color;
-
-	color = calloc(1, sizeof(gfx_color_t));
-	if (color == NULL)
-		return ENOMEM;
-
-	color->r = r;
-	color->g = g;
-	color->b = b;
-
-	*rcolor = color;
-	return EOK;
-}
-
-/** Delete color.
- *
- * @param color Color
- */
-void gfx_color_delete(gfx_color_t *color)
-{
-	free(color);
-}
-
-/** Convert color to 16-bit RGB coordinates.
- *
- * @param color Color
- * @param r Place to store red coordinate
- * @param g Place to store green coordinate
- * @param b Place to store blue coordinate
- */
-void gfx_color_get_rgb_i16(gfx_color_t *color, uint16_t *r, uint16_t *g,
-    uint16_t *b)
-{
-	*r = color->r;
-	*g = color->g;
-	*b = color->b;
-}
-
-/** @}
- */
Index: pace/lib/gfx/src/context.c
===================================================================
--- uspace/lib/gfx/src/context.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,78 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Graphics context
- */
-
-#include <gfx/context.h>
-#include <stdlib.h>
-#include "../private/context.h"
-
-/** Create new graphics context.
- *
- * Create new graphics context with the specified ops and argument.
- *
- * @param ops Graphics context ops
- * @param arg Instance argument
- * @param rgc Place to store pointer to new graphics context on success
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t gfx_context_new(gfx_context_ops_t *ops, void *arg,
-    gfx_context_t **rgc)
-{
-	gfx_context_t *gc;
-
-	gc = calloc(1, sizeof(gfx_context_t));
-	if (gc == NULL)
-		return ENOMEM;
-
-	gc->ops = ops;
-	gc->arg = arg;
-	*rgc = gc;
-	return EOK;
-}
-
-/** Delete graphics context.
- *
- * @param gc Graphics context or @c NULL
- */
-errno_t gfx_context_delete(gfx_context_t *gc)
-{
-	if (gc == NULL)
-		return EOK;
-
-	free(gc);
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/gfx/src/coord.c
===================================================================
--- uspace/lib/gfx/src/coord.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,313 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Coordinates
- */
-
-#include <gfx/coord.h>
-#include <macros.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-/** Add two vectors.
- *
- * @param a First vector
- * @param b Second vector
- * @param d Destination
- */
-void gfx_coord2_add(gfx_coord2_t *a, gfx_coord2_t *b, gfx_coord2_t *d)
-{
-	d->x = a->x + b->x;
-	d->y = a->y + b->y;
-}
-
-/** Subtract two vectors.
- *
- * @param a First vector
- * @param b Second vector
- * @param d Destination
- */
-void gfx_coord2_subtract(gfx_coord2_t *a, gfx_coord2_t *b, gfx_coord2_t *d)
-{
-	d->x = a->x - b->x;
-	d->y = a->y - b->y;
-}
-
-/** Clip point coordinates to be within a rectangle.
- *
- * @param a Pixel coordinates
- * @param clip Clipping rectangle
- * @param d Place to store clipped coordinates
- */
-void gfx_coord2_clip(gfx_coord2_t *a, gfx_rect_t *clip, gfx_coord2_t *d)
-{
-	gfx_rect_t sclip;
-	gfx_coord2_t t;
-
-	gfx_rect_points_sort(clip, &sclip);
-
-	t.x = min(a->x, clip->p1.x - 1);
-	t.y = min(a->y, clip->p1.y - 1);
-
-	d->x = max(clip->p0.x, t.x);
-	d->y = max(clip->p0.y, t.y);
-}
-
-/** Transform coordinates via rectangle to rectangle projection.
- *
- * Transform pixel coordinate via a projection that maps one rectangle
- * onto another rectangle. The source rectangle must have both dimensions
- * greater than one.
- *
- * @param a Pixel coordinates
- * @param srect Source rectangle
- * @param drect Destination rectangle
- * @param d Place to store resulting coordinates.
- */
-void gfx_coord2_project(gfx_coord2_t *a, gfx_rect_t *srect, gfx_rect_t *drect,
-    gfx_coord2_t *d)
-{
-	gfx_rect_t sr;
-	gfx_rect_t dr;
-
-	gfx_rect_points_sort(srect, &sr);
-	gfx_rect_points_sort(drect, &dr);
-
-	d->x = dr.p0.x + (a->x - sr.p0.x) * (dr.p1.x - dr.p0.x - 1) /
-	    (sr.p1.x - sr.p0.x - 1);
-	d->y = dr.p0.y + (a->y - sr.p0.y) * (dr.p1.y - dr.p0.y - 1) /
-	    (sr.p1.y - sr.p0.y - 1);
-}
-
-/** Sort points of a span.
- *
- * Sort the begin and end points so that the begin point has the lower
- * coordinate (i.e. if needed, the span is transposed, if not, it is simply
- * copied).
- *
- * @param s0 Source span start point
- * @param s1 Source span end point
- * @param d0 Destination span start point
- * @param d1 Destination span end point
- */
-void gfx_span_points_sort(gfx_coord_t s0, gfx_coord_t s1, gfx_coord_t *d0,
-    gfx_coord_t *d1)
-{
-	if (s0 <= s1) {
-		*d0 = s0;
-		*d1 = s1;
-	} else {
-		*d0 = s1 + 1;
-		*d1 = s0 + 1;
-	}
-}
-
-/** Move (translate) rectangle.
- *
- * @param trans Translation offset
- * @param src Source rectangle
- * @param dest Destination rectangle
- */
-void gfx_rect_translate(gfx_coord2_t *trans, gfx_rect_t *src, gfx_rect_t *dest)
-{
-	gfx_coord2_add(&src->p0, trans, &dest->p0);
-	gfx_coord2_add(&src->p1, trans, &dest->p1);
-}
-
-/** Reverse move (translate) rectangle.
- *
- * @param trans Translation offset
- * @param src Source rectangle
- * @param dest Destination rectangle
- */
-void gfx_rect_rtranslate(gfx_coord2_t *trans, gfx_rect_t *src, gfx_rect_t *dest)
-{
-	gfx_coord2_subtract(&src->p0, trans, &dest->p0);
-	gfx_coord2_subtract(&src->p1, trans, &dest->p1);
-}
-
-/** Compute envelope of two rectangles.
- *
- * Envelope is the minimal rectangle covering all pixels of both rectangles.
- *
- * @param a First rectangle
- * @param b Second rectangle
- * @param dest Place to store enveloping rectangle
- */
-void gfx_rect_envelope(gfx_rect_t *a, gfx_rect_t *b, gfx_rect_t *dest)
-{
-	gfx_rect_t sa, sb;
-
-	if (gfx_rect_is_empty(a)) {
-		*dest = *b;
-		return;
-	}
-
-	if (gfx_rect_is_empty(b)) {
-		*dest = *a;
-		return;
-	}
-
-	/* a and b are both non-empty */
-
-	gfx_rect_points_sort(a, &sa);
-	gfx_rect_points_sort(b, &sb);
-
-	dest->p0.x = min(sa.p0.x, sb.p0.x);
-	dest->p0.y = min(sa.p0.y, sb.p0.y);
-	dest->p1.x = max(sa.p1.x, sb.p1.x);
-	dest->p1.y = max(sa.p1.y, sb.p1.y);
-}
-
-/** Compute intersection of two rectangles.
- *
- * If the two rectangles do not intersect, the result will be an empty
- * rectangle (check with gfx_rect_is_empty()). The resulting rectangle
- * is always sorted. If @a clip is NULL, no clipping is performed.
- *
- * @param rect Source rectangle
- * @param clip Clipping rectangle or @c NULL
- * @param dest Place to store clipped rectangle
- */
-void gfx_rect_clip(gfx_rect_t *rect, gfx_rect_t *clip, gfx_rect_t *dest)
-{
-	gfx_rect_t srect, sclip;
-
-	if (clip == NULL) {
-		*dest = *rect;
-		return;
-	}
-
-	gfx_rect_points_sort(rect, &srect);
-	gfx_rect_points_sort(clip, &sclip);
-
-	dest->p0.x = min(max(srect.p0.x, sclip.p0.x), sclip.p1.x);
-	dest->p0.y = min(max(srect.p0.y, sclip.p0.y), sclip.p1.y);
-	dest->p1.x = max(sclip.p0.x, min(srect.p1.x, sclip.p1.x));
-	dest->p1.y = max(sclip.p0.y, min(srect.p1.y, sclip.p1.y));
-}
-
-/** Sort points of a rectangle.
- *
- * Shuffle around coordinates of a rectangle so that p0.x < p1.x and
- * p0.y < p0.y.
- *
- * @param src Source rectangle
- * @param dest Destination (sorted) rectangle
- */
-void gfx_rect_points_sort(gfx_rect_t *src, gfx_rect_t *dest)
-{
-	gfx_span_points_sort(src->p0.x, src->p1.x, &dest->p0.x, &dest->p1.x);
-	gfx_span_points_sort(src->p0.y, src->p1.y, &dest->p0.y, &dest->p1.y);
-}
-
-/** Determine if rectangle contains no pixels
- *
- * @param rect Rectangle
- * @return @c true iff rectangle contains no pixels
- */
-bool gfx_rect_is_empty(gfx_rect_t *rect)
-{
-	return rect->p0.x == rect->p1.x || rect->p0.y == rect->p1.y;
-}
-
-/** Determine if two rectangles share any pixels
- *
- * @param a First rectangle
- * @param b Second rectangle
- * @return @c true iff rectangles share any pixels
- */
-bool gfx_rect_is_incident(gfx_rect_t *a, gfx_rect_t *b)
-{
-	gfx_rect_t r;
-
-	gfx_rect_clip(a, b, &r);
-	return !gfx_rect_is_empty(&r);
-}
-
-/** Return true if rectangle @a a is contained in rectangle @a b.
- *
- * @param a Inside rectangle
- * @param b Outside rectangle
- * @return @c true iff @a a is (non-strictly) inside @a b
- */
-bool gfx_rect_is_inside(gfx_rect_t *a, gfx_rect_t *b)
-{
-	gfx_rect_t sa;
-	gfx_rect_t sb;
-
-	gfx_rect_points_sort(a, &sa);
-	gfx_rect_points_sort(b, &sb);
-
-	if (sa.p0.x < sb.p0.x || sa.p0.y < sb.p0.y)
-		return false;
-
-	if (sa.p1.x > sb.p1.x || sa.p1.y > sb.p1.y)
-		return false;
-
-	return true;
-}
-
-/** Get rectangle dimensions.
- *
- * Get a vector containing the x, y dimensions of a rectangle. These are
- * always nonnegative.
- *
- * @param rect Rectangle
- * @param dims Place to store dimensions
- */
-void gfx_rect_dims(gfx_rect_t *rect, gfx_coord2_t *dims)
-{
-	gfx_rect_t srect;
-
-	gfx_rect_points_sort(rect, &srect);
-	gfx_coord2_subtract(&srect.p1, &srect.p0, dims);
-}
-
-/** Return true if pixel at coordinate @a coord lies within rectangle @a rect. */
-bool gfx_pix_inside_rect(gfx_coord2_t *coord, gfx_rect_t *rect)
-{
-	gfx_rect_t sr;
-
-	gfx_rect_points_sort(rect, &sr);
-
-	if (coord->x < sr.p0.x || coord->y < sr.p0.y)
-		return false;
-
-	if (coord->x >= sr.p1.x || coord->y >= sr.p1.y)
-		return false;
-
-	return true;
-}
-
-/** @}
- */
Index: pace/lib/gfx/src/render.c
===================================================================
--- uspace/lib/gfx/src/render.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/*
- * Copyright (c) 2019 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 libgfx
- * @{
- */
-/**
- * @file Rendering operations
- */
-
-#include <gfx/render.h>
-#include "../private/context.h"
-
-/** Set drawing color.
- *
- * @param gc Graphic context
- * @param color Color
- *
- * @return EOK on success, ENOMEM if insufficient resources,
- *         EIO if grahic device connection was lost
- */
-errno_t gfx_set_color(gfx_context_t *gc, gfx_color_t *color)
-{
-	return gc->ops->set_color(gc->arg, color);
-}
-
-/** Fill rectangle using the current drawing color.
- *
- * @param gc Graphic context
- * @param rect Rectangle
- *
- * @return EOK on success, ENOMEM if insufficient resources,
- *         EIO if grahic device connection was lost
- */
-errno_t gfx_fill_rect(gfx_context_t *gc, gfx_rect_t *rect)
-{
-	return gc->ops->fill_rect(gc->arg, rect);
-}
-
-/** @}
- */
Index: pace/lib/gfx/test/bitmap.c
===================================================================
--- uspace/lib/gfx/test/bitmap.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,243 +1,0 @@
-/*
- * Copyright (c) 2019 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 <gfx/bitmap.h>
-#include <gfx/context.h>
-#include <mem.h>
-#include <pcut/pcut.h>
-#include <stdbool.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(bitmap);
-
-static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t testgc_bitmap_destroy(void *);
-static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static gfx_context_ops_t ops = {
-	.bitmap_create = testgc_bitmap_create,
-	.bitmap_destroy = testgc_bitmap_destroy,
-	.bitmap_render = testgc_bitmap_render,
-	.bitmap_get_alloc = testgc_bitmap_get_alloc
-};
-
-typedef struct {
-	bool bm_created;
-	bool bm_destroyed;
-	gfx_bitmap_params_t bm_params;
-	void *bm_pixels;
-	gfx_rect_t bm_srect;
-	gfx_coord2_t bm_offs;
-	bool bm_rendered;
-	bool bm_got_alloc;
-} test_gc_t;
-
-typedef struct {
-	test_gc_t *tgc;
-	gfx_bitmap_alloc_t alloc;
-	bool myalloc;
-} testgc_bitmap_t;
-
-enum {
-	alloc_pitch = 42,
-	alloc_off0 = 33
-};
-
-PCUT_TEST(create_destroy)
-{
-	errno_t rc;
-	gfx_context_t *gc = NULL;
-	test_gc_t tgc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap = NULL;
-
-	memset(&tgc, 0, sizeof(tgc));
-	rc = gfx_context_new(&ops, &tgc, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-	PCUT_ASSERT_TRUE(tgc.bm_created);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, tgc.bm_params.rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, tgc.bm_params.rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, tgc.bm_params.rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, tgc.bm_params.rect.p1.y);
-
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(tgc.bm_destroyed);
-
-	rc = gfx_context_delete(gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-PCUT_TEST(render)
-{
-	errno_t rc;
-	gfx_context_t *gc = NULL;
-	test_gc_t tgc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap = NULL;
-	gfx_rect_t srect;
-	gfx_coord2_t offs;
-
-	memset(&tgc, 0, sizeof(tgc));
-	rc = gfx_context_new(&ops, &tgc, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gfx_bitmap_params_init(&params);
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	srect.p0.x = 1;
-	srect.p0.y = 2;
-	srect.p1.x = 3;
-	srect.p1.y = 4;
-	offs.x = 5;
-	offs.y = 6;
-
-	rc = gfx_bitmap_render(bitmap, &srect, &offs);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(tgc.bm_rendered);
-	PCUT_ASSERT_EQUALS(srect.p0.x, tgc.bm_srect.p0.x);
-	PCUT_ASSERT_EQUALS(srect.p0.y, tgc.bm_srect.p0.y);
-	PCUT_ASSERT_EQUALS(srect.p1.x, tgc.bm_srect.p1.x);
-	PCUT_ASSERT_EQUALS(srect.p1.y, tgc.bm_srect.p1.y);
-	PCUT_ASSERT_EQUALS(offs.x, tgc.bm_offs.x);
-	PCUT_ASSERT_EQUALS(offs.y, tgc.bm_offs.y);
-
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_context_delete(gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-PCUT_TEST(get_alloc)
-{
-	errno_t rc;
-	gfx_context_t *gc = NULL;
-	test_gc_t tgc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap = NULL;
-	gfx_bitmap_alloc_t alloc;
-
-	memset(&tgc, 0, sizeof(tgc));
-	rc = gfx_context_new(&ops, &tgc, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gfx_bitmap_params_init(&params);
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(tgc.bm_got_alloc);
-	PCUT_ASSERT_EQUALS(alloc_pitch, alloc.pitch);
-	PCUT_ASSERT_EQUALS(alloc_off0, alloc.off0);
-	PCUT_ASSERT_EQUALS(tgc.bm_pixels, alloc.pixels);
-
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_context_delete(gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	test_gc_t *tgc = (test_gc_t *) arg;
-	testgc_bitmap_t *tbm;
-
-	tbm = calloc(1, sizeof(testgc_bitmap_t));
-	if (tbm == NULL)
-		return ENOMEM;
-
-	if (alloc == NULL) {
-		tbm->alloc.pitch = alloc_pitch;
-		tbm->alloc.off0 = alloc_off0;
-		tbm->alloc.pixels = calloc(1, 420);
-		tbm->myalloc = true;
-		if (tbm->alloc.pixels == NULL) {
-			free(tbm);
-			return ENOMEM;
-		}
-	} else {
-		tbm->alloc = *alloc;
-	}
-
-	tbm->tgc = tgc;
-	tgc->bm_created = true;
-	tgc->bm_params = *params;
-	tgc->bm_pixels = tbm->alloc.pixels;
-	*rbm = (void *)tbm;
-	return EOK;
-}
-
-static errno_t testgc_bitmap_destroy(void *bm)
-{
-	testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
-	if (tbm->myalloc)
-		free(tbm->alloc.pixels);
-	tbm->tgc->bm_destroyed = true;
-	free(tbm);
-	return EOK;
-}
-
-static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
-    gfx_coord2_t *offs)
-{
-	testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
-	tbm->tgc->bm_rendered = true;
-	tbm->tgc->bm_srect = *srect;
-	tbm->tgc->bm_offs = *offs;
-	return EOK;
-}
-
-static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
-	*alloc = tbm->alloc;
-	tbm->tgc->bm_got_alloc = true;
-	return EOK;
-}
-
-PCUT_EXPORT(bitmap);
Index: pace/lib/gfx/test/color.c
===================================================================
--- uspace/lib/gfx/test/color.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2019 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 <gfx/color.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(color);
-
-PCUT_TEST(init_rgb_i16)
-{
-	errno_t rc;
-	gfx_color_t *color;
-
-	/* White */
-	rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gfx_color_delete(color);
-}
-
-PCUT_EXPORT(color);
Index: pace/lib/gfx/test/coord.c
===================================================================
--- uspace/lib/gfx/test/coord.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,921 +1,0 @@
-/*
- * Copyright (c) 2019 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 <gfx/coord.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(coord);
-
-/** gfx_coord2_add should add two coordinate vectors */
-PCUT_TEST(coord2_add)
-{
-	gfx_coord2_t a, b;
-	gfx_coord2_t d;
-
-	a.x = 10;
-	a.y = 11;
-	b.x = 20;
-	b.y = 22;
-
-	gfx_coord2_add(&a, &b, &d);
-
-	PCUT_ASSERT_INT_EQUALS(a.x + b.x, d.x);
-	PCUT_ASSERT_INT_EQUALS(a.y + b.y, d.y);
-}
-
-/** gfx_coord2_subtract should subtract two coordinate vectors */
-PCUT_TEST(coord2_subtract)
-{
-	gfx_coord2_t a, b;
-	gfx_coord2_t d;
-
-	a.x = 10;
-	a.y = 11;
-	b.x = 20;
-	b.y = 22;
-
-	gfx_coord2_subtract(&a, &b, &d);
-
-	PCUT_ASSERT_INT_EQUALS(a.x - b.x, d.x);
-	PCUT_ASSERT_INT_EQUALS(a.y - b.y, d.y);
-}
-
-/** gfx_coord2_clip with point to lower-left of clipping rectangle */
-PCUT_TEST(coord2_clip_ll)
-{
-	gfx_coord2_t p;
-	gfx_coord2_t cp;
-	gfx_rect_t rect;
-
-	p.x = 1;
-	p.y = 2;
-
-	rect.p0.x = 3;
-	rect.p0.y = 4;
-	rect.p1.x = 5;
-	rect.p1.y = 6;
-
-	gfx_coord2_clip(&p, &rect, &cp);
-
-	PCUT_ASSERT_INT_EQUALS(3, cp.x);
-	PCUT_ASSERT_INT_EQUALS(4, cp.y);
-}
-
-/** gfx_coord2_clip with point inside the clipping rectangle */
-PCUT_TEST(coord2_clip_mm)
-{
-	gfx_coord2_t p;
-	gfx_coord2_t cp;
-	gfx_rect_t rect;
-
-	p.x = 2;
-	p.y = 3;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	gfx_coord2_clip(&p, &rect, &cp);
-
-	PCUT_ASSERT_INT_EQUALS(2, cp.x);
-	PCUT_ASSERT_INT_EQUALS(3, cp.y);
-}
-
-/** gfx_coord2_clip with point to upper-right of clipping rectangle */
-PCUT_TEST(coord2_clip_hh)
-{
-	gfx_coord2_t p;
-	gfx_coord2_t cp;
-	gfx_rect_t rect;
-
-	p.x = 5;
-	p.y = 6;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	gfx_coord2_clip(&p, &rect, &cp);
-
-	PCUT_ASSERT_INT_EQUALS(2, cp.x);
-	PCUT_ASSERT_INT_EQUALS(3, cp.y);
-}
-
-/** gfx_coord2_project projects pixel from one rectangle to another  */
-PCUT_TEST(coord2_project)
-{
-	gfx_coord2_t a, d;
-	gfx_rect_t srect, drect;
-
-	srect.p0.x = 10;
-	srect.p0.y = 10;
-	srect.p1.x = 20 + 1;
-	srect.p1.y = 20 + 1;
-
-	drect.p0.x = 100;
-	drect.p0.y = 100;
-	drect.p1.x = 200 + 1;
-	drect.p1.y = 200 + 1;
-
-	a.x = 10;
-	a.y = 10;
-	gfx_coord2_project(&a, &srect, &drect, &d);
-	PCUT_ASSERT_INT_EQUALS(100, d.x);
-	PCUT_ASSERT_INT_EQUALS(100, d.y);
-
-	a.x = 15;
-	a.y = 15;
-	gfx_coord2_project(&a, &srect, &drect, &d);
-	PCUT_ASSERT_INT_EQUALS(150, d.x);
-	PCUT_ASSERT_INT_EQUALS(150, d.y);
-
-	a.x = 12;
-	a.y = 16;
-	gfx_coord2_project(&a, &srect, &drect, &d);
-	PCUT_ASSERT_INT_EQUALS(120, d.x);
-	PCUT_ASSERT_INT_EQUALS(160, d.y);
-
-	a.x = 20;
-	a.y = 20;
-	gfx_coord2_project(&a, &srect, &drect, &d);
-	PCUT_ASSERT_INT_EQUALS(200, d.x);
-	PCUT_ASSERT_INT_EQUALS(200, d.y);
-}
-
-/** gfx_rect_translate should translate rectangle */
-PCUT_TEST(rect_translate)
-{
-	gfx_coord2_t offs;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-
-	offs.x = 5;
-	offs.y = 6;
-
-	srect.p0.x = 10;
-	srect.p0.y = 11;
-	srect.p1.x = 20;
-	srect.p1.y = 22;
-
-	gfx_rect_translate(&offs, &srect, &drect);
-
-	PCUT_ASSERT_INT_EQUALS(offs.x + srect.p0.x, drect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(offs.y + srect.p0.y, drect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(offs.x + srect.p1.x, drect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(offs.y + srect.p1.y, drect.p1.y);
-}
-
-/** gfx_rect_rtranslate should reverse-translate rectangle */
-PCUT_TEST(rect_rtranslate)
-{
-	gfx_coord2_t offs;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-
-	offs.x = 5;
-	offs.y = 6;
-
-	srect.p0.x = 10;
-	srect.p0.y = 11;
-	srect.p1.x = 20;
-	srect.p1.y = 22;
-
-	gfx_rect_rtranslate(&offs, &srect, &drect);
-
-	PCUT_ASSERT_INT_EQUALS(srect.p0.x - offs.x, drect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(srect.p0.y - offs.y, drect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(srect.p1.x - offs.x, drect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(srect.p1.y - offs.y, drect.p1.y);
-}
-
-/** Sorting span with lower start and higher end point results in the same span. */
-PCUT_TEST(span_points_sort_asc)
-{
-	gfx_coord_t a, b;
-
-	gfx_span_points_sort(1, 2, &a, &b);
-	PCUT_ASSERT_INT_EQUALS(1, a);
-	PCUT_ASSERT_INT_EQUALS(2, b);
-}
-
-/** Sorting span with same start and end point results in the same span. */
-PCUT_TEST(span_points_sort_equal)
-{
-	gfx_coord_t a, b;
-
-	gfx_span_points_sort(1, 1, &a, &b);
-	PCUT_ASSERT_INT_EQUALS(1, a);
-	PCUT_ASSERT_INT_EQUALS(1, b);
-}
-
-/** Sorting span with hight start and lower end point results in transposed span. */
-PCUT_TEST(span_points_sort_desc)
-{
-	gfx_coord_t a, b;
-
-	gfx_span_points_sort(1, 0, &a, &b);
-	PCUT_ASSERT_INT_EQUALS(1, a);
-	PCUT_ASSERT_INT_EQUALS(2, b);
-}
-
-/** Rectangle envelope with first rectangle empty should return the second rectangle. */
-PCUT_TEST(rect_envelope_a_empty)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 0;
-	a.p0.y = 0;
-	a.p1.x = 0;
-	a.p1.y = 0;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(2, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(3, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(4, e.p1.y);
-}
-
-/** Rectangle envelope with second rectangle empty should return the first rectangle. */
-PCUT_TEST(rect_envelope_b_empty)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 0;
-	b.p0.y = 0;
-	b.p1.x = 0;
-	b.p1.y = 0;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(2, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(3, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(4, e.p1.y);
-}
-
-/** Rectangle envelope, a has both coordinates lower than b */
-PCUT_TEST(rect_envelope_nonempty_a_lt_b)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 5;
-	b.p0.y = 6;
-	b.p1.x = 7;
-	b.p1.y = 8;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(2, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(7, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(8, e.p1.y);
-}
-
-/** Rectangle envelope, a has both coordinates higher than b */
-PCUT_TEST(rect_envelope_nonempty_a_gt_b)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 5;
-	a.p0.y = 6;
-	a.p1.x = 7;
-	a.p1.y = 8;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(2, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(7, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(8, e.p1.y);
-}
-
-/** Rectangle envelope, a is inside b */
-PCUT_TEST(rect_envelope_nonempty_a_inside_b)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 7;
-	a.p1.y = 8;
-
-	b.p0.x = 3;
-	b.p0.y = 4;
-	b.p1.x = 5;
-	b.p1.y = 6;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(2, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(7, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(8, e.p1.y);
-}
-
-/** Rectangle envelope, b is inside a*/
-PCUT_TEST(rect_envelope_nonempty_b_inside_a)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 3;
-	a.p0.y = 4;
-	a.p1.x = 5;
-	a.p1.y = 6;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 7;
-	b.p1.y = 8;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(2, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(7, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(8, e.p1.y);
-}
-
-/** Rectangle envelope, a and b cross */
-PCUT_TEST(rect_envelope_nonempty_a_crosses_b)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-	gfx_rect_t e;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 4;
-	a.p1.y = 3;
-
-	b.p0.x = 2;
-	b.p0.y = 1;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	gfx_rect_envelope(&a, &b, &e);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.x);
-	PCUT_ASSERT_INT_EQUALS(1, e.p0.y);
-	PCUT_ASSERT_INT_EQUALS(4, e.p1.x);
-	PCUT_ASSERT_INT_EQUALS(4, e.p1.y);
-}
-
-/** Clip rectangle with rect completely inside the clipping rectangle */
-PCUT_TEST(rect_clip_rect_inside)
-{
-	gfx_rect_t rect;
-	gfx_rect_t clip;
-	gfx_rect_t dest;
-
-	rect.p0.x = 3;
-	rect.p0.y = 4;
-	rect.p1.x = 5;
-	rect.p1.y = 6;
-
-	clip.p0.x = 1;
-	clip.p0.y = 2;
-	clip.p1.x = 7;
-	clip.p1.y = 8;
-
-	gfx_rect_clip(&rect, &clip, &dest);
-	PCUT_ASSERT_INT_EQUALS(3, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(4, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(5, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(6, dest.p1.y);
-}
-
-/** Clip rectangle with rect covering the clipping rectangle */
-PCUT_TEST(rect_clip_rect_covering)
-{
-	gfx_rect_t rect;
-	gfx_rect_t clip;
-	gfx_rect_t dest;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 7;
-	rect.p1.y = 8;
-
-	clip.p0.x = 3;
-	clip.p0.y = 4;
-	clip.p1.x = 5;
-	clip.p1.y = 6;
-
-	gfx_rect_clip(&rect, &clip, &dest);
-	PCUT_ASSERT_INT_EQUALS(3, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(4, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(5, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(6, dest.p1.y);
-}
-
-/** Clip rectangle with rect outside, having lower coordinates */
-PCUT_TEST(rect_clip_rect_out_ll)
-{
-	gfx_rect_t rect;
-	gfx_rect_t clip;
-	gfx_rect_t dest;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	clip.p0.x = 5;
-	clip.p0.y = 6;
-	clip.p1.x = 7;
-	clip.p1.y = 8;
-
-	gfx_rect_clip(&rect, &clip, &dest);
-	PCUT_ASSERT_INT_EQUALS(5, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(6, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(5, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(6, dest.p1.y);
-}
-
-/** Clip rectangle with rect outside, having higher coordinates */
-PCUT_TEST(rect_clip_rect_out_hh)
-{
-	gfx_rect_t rect;
-	gfx_rect_t clip;
-	gfx_rect_t dest;
-
-	rect.p0.x = 5;
-	rect.p0.y = 6;
-	rect.p1.x = 7;
-	rect.p1.y = 8;
-
-	clip.p0.x = 1;
-	clip.p0.y = 2;
-	clip.p1.x = 3;
-	clip.p1.y = 4;
-
-	gfx_rect_clip(&rect, &clip, &dest);
-	PCUT_ASSERT_INT_EQUALS(3, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(4, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(3, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(4, dest.p1.y);
-}
-
-/** Clip rectangle with rect partially outside, having lower coordinates */
-PCUT_TEST(rect_clip_rect_ll)
-{
-	gfx_rect_t rect;
-	gfx_rect_t clip;
-	gfx_rect_t dest;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 5;
-	rect.p1.y = 6;
-
-	clip.p0.x = 3;
-	clip.p0.y = 4;
-	clip.p1.x = 7;
-	clip.p1.y = 8;
-
-	gfx_rect_clip(&rect, &clip, &dest);
-	PCUT_ASSERT_INT_EQUALS(3, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(4, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(5, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(6, dest.p1.y);
-}
-
-/** Clip rectangle with rect partially outside, having higher coordinates */
-PCUT_TEST(rect_clip_rect_hh)
-{
-	gfx_rect_t rect;
-	gfx_rect_t clip;
-	gfx_rect_t dest;
-
-	rect.p0.x = 3;
-	rect.p0.y = 4;
-	rect.p1.x = 7;
-	rect.p1.y = 8;
-
-	clip.p0.x = 1;
-	clip.p0.y = 2;
-	clip.p1.x = 5;
-	clip.p1.y = 6;
-
-	gfx_rect_clip(&rect, &clip, &dest);
-	PCUT_ASSERT_INT_EQUALS(3, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(4, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(5, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(6, dest.p1.y);
-}
-
-/** Clip rectangle with no clipping rectangle */
-PCUT_TEST(rect_clip_rect_noclip)
-{
-	gfx_rect_t rect;
-	gfx_rect_t dest;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	gfx_rect_clip(&rect, NULL, &dest);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, dest.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, dest.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, dest.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, dest.p1.y);
-}
-
-/** Sort span points that are already sorted should produde indentical points */
-PCUT_TEST(rect_points_sort_sorted)
-{
-	gfx_coord_t s0, s1;
-
-	gfx_span_points_sort(1, 2, &s0, &s1);
-	PCUT_ASSERT_INT_EQUALS(1, s0);
-	PCUT_ASSERT_INT_EQUALS(2, s1);
-}
-
-/** Sort span points that are reversed should transpose them */
-PCUT_TEST(rect_points_sort_reversed)
-{
-	gfx_coord_t s0, s1;
-
-	gfx_span_points_sort(2, 1, &s0, &s1);
-	PCUT_ASSERT_INT_EQUALS(2, s0);
-	PCUT_ASSERT_INT_EQUALS(3, s1);
-}
-
-/** Rectangle dimensions for straight rectangle are computed correctly */
-PCUT_TEST(rect_dims_straight)
-{
-	gfx_rect_t rect;
-	gfx_coord2_t dims;
-
-	rect.p0.x = 1;
-	rect.p0.y = 10;
-	rect.p1.x = 100;
-	rect.p1.y = 1000;
-
-	gfx_rect_dims(&rect, &dims);
-
-	PCUT_ASSERT_INT_EQUALS(99, dims.x);
-	PCUT_ASSERT_INT_EQUALS(990, dims.y);
-}
-
-/** Rectangle dimensions for reversed rectangle are computed correctly */
-PCUT_TEST(rect_dims_reversed)
-{
-	gfx_rect_t rect;
-	gfx_coord2_t dims;
-
-	rect.p0.x = 1000;
-	rect.p0.y = 100;
-	rect.p1.x = 10;
-	rect.p1.y = 1;
-
-	gfx_rect_dims(&rect, &dims);
-
-	PCUT_ASSERT_INT_EQUALS(990, dims.x);
-	PCUT_ASSERT_INT_EQUALS(99, dims.y);
-}
-
-/** gfx_rect_is_empty for straight rectangle with zero columns returns true */
-PCUT_TEST(rect_is_empty_pos_x)
-{
-	gfx_rect_t rect;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 1;
-	rect.p1.y = 3;
-	PCUT_ASSERT_TRUE(gfx_rect_is_empty(&rect));
-}
-
-/** gfx_rect_is_empty for straight rectangle with zero rows returns true */
-PCUT_TEST(rect_is_empty_pos_y)
-{
-	gfx_rect_t rect;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 2;
-	rect.p1.y = 2;
-	PCUT_ASSERT_TRUE(gfx_rect_is_empty(&rect));
-}
-
-/** gfx_rect_is_empty for straight non-empty rectangle returns false */
-PCUT_TEST(rect_is_empty_neg)
-{
-	gfx_rect_t rect;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 2;
-	rect.p1.y = 3;
-	PCUT_ASSERT_FALSE(gfx_rect_is_empty(&rect));
-}
-
-/** gfx_rect_is_empty for reverse non-empty rectangle returns false */
-PCUT_TEST(rect_is_empty_reverse_neg)
-{
-	gfx_rect_t rect;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 0;
-	rect.p1.y = 1;
-	PCUT_ASSERT_FALSE(gfx_rect_is_empty(&rect));
-}
-
-/** gfx_rect_is_incident for neighboring rectangles returns false */
-PCUT_TEST(rect_is_incident_neighbor)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 3;
-	b.p0.y = 2;
-	b.p1.x = 5;
-	b.p1.y = 6;
-
-	PCUT_ASSERT_FALSE(gfx_rect_is_incident(&a, &b));
-}
-
-/** gfx_rect_is_incident for a inside b returns true */
-PCUT_TEST(rect_is_incident_a_inside_b)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 2;
-	a.p0.y = 3;
-	a.p1.x = 4;
-	a.p1.y = 5;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 5;
-	b.p1.y = 6;
-
-	PCUT_ASSERT_TRUE(gfx_rect_is_incident(&a, &b));
-}
-
-/** gfx_rect_is_incident for b inside a returns true */
-PCUT_TEST(rect_is_incident_b_inside_a)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 5;
-	a.p1.y = 6;
-
-	b.p0.x = 2;
-	b.p0.y = 3;
-	b.p1.x = 4;
-	b.p1.y = 5;
-
-	PCUT_ASSERT_TRUE(gfx_rect_is_incident(&a, &b));
-}
-
-/** gfx_rect_is_incident for a and b sharing corner returns true */
-PCUT_TEST(rect_is_incident_corner)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 2;
-	b.p0.y = 3;
-	b.p1.x = 4;
-	b.p1.y = 5;
-
-	PCUT_ASSERT_TRUE(gfx_rect_is_incident(&a, &b));
-}
-
-/** gfx_rect_is_incident for a == b returns true */
-PCUT_TEST(rect_is_incident_same)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	PCUT_ASSERT_TRUE(gfx_rect_is_incident(&a, &b));
-}
-
-/** gfx_rect_is_inside is true for rectangle strictly inside */
-PCUT_TEST(rect_is_inside_strict)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 2;
-	a.p0.y = 3;
-	a.p1.x = 4;
-	a.p1.y = 5;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 5;
-	b.p1.y = 6;
-
-	PCUT_ASSERT_TRUE(gfx_rect_is_inside(&a, &b));
-}
-
-/** gfx_rect_is_inside is true for two equal rectangles */
-PCUT_TEST(rect_is_inside_same)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	PCUT_ASSERT_TRUE(gfx_rect_is_inside(&a, &b));
-}
-
-/** gfx_rect_is_inside is false for @c a.p0 outside */
-PCUT_TEST(rect_is_inside_p0_outside)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 0;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
-
-	a.p0.x = 1;
-	a.p0.y = 1;
-	a.p1.x = 3;
-	a.p1.y = 4;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
-}
-
-/** gfx_rect_is_inside is false for @c a.p1 outside */
-PCUT_TEST(rect_is_inside_p1_outside)
-{
-	gfx_rect_t a;
-	gfx_rect_t b;
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 4;
-	a.p1.y = 4;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
-
-	a.p0.x = 1;
-	a.p0.y = 2;
-	a.p1.x = 3;
-	a.p1.y = 5;
-
-	b.p0.x = 1;
-	b.p0.y = 2;
-	b.p1.x = 3;
-	b.p1.y = 4;
-
-	PCUT_ASSERT_FALSE(gfx_rect_is_inside(&a, &b));
-}
-
-/** gfx_pix_inside_rect for  */
-PCUT_TEST(pix_inside_rect)
-{
-	gfx_coord2_t coord;
-	gfx_rect_t rect;
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	coord.x = 0;
-	coord.y = 1;
-	PCUT_ASSERT_FALSE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 1;
-	coord.y = 1;
-	PCUT_ASSERT_FALSE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 0;
-	coord.y = 2;
-	PCUT_ASSERT_FALSE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 1;
-	coord.y = 2;
-	PCUT_ASSERT_TRUE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 2;
-	coord.y = 3;
-	PCUT_ASSERT_TRUE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 3;
-	coord.y = 3;
-	PCUT_ASSERT_FALSE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 2;
-	coord.y = 4;
-	PCUT_ASSERT_FALSE(gfx_pix_inside_rect(&coord, &rect));
-
-	coord.x = 3;
-	coord.y = 4;
-	PCUT_ASSERT_FALSE(gfx_pix_inside_rect(&coord, &rect));
-}
-
-PCUT_EXPORT(coord);
Index: pace/lib/gfx/test/main.c
===================================================================
--- uspace/lib/gfx/test/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
- * Copyright (c) 2017 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 <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_IMPORT(bitmap);
-PCUT_IMPORT(color);
-PCUT_IMPORT(coord);
-PCUT_IMPORT(render);
-
-PCUT_MAIN();
Index: pace/lib/gfx/test/render.c
===================================================================
--- uspace/lib/gfx/test/render.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,127 +1,0 @@
-/*
- * Copyright (c) 2019 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 <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <pcut/pcut.h>
-#include <mem.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(render);
-
-static errno_t testgc_set_color(void *, gfx_color_t *);
-static errno_t testgc_fill_rect(void *, gfx_rect_t *);
-
-static gfx_context_ops_t ops = {
-	.set_color = testgc_set_color,
-	.fill_rect = testgc_fill_rect
-};
-
-/** Test graphics context data */
-typedef struct {
-	gfx_color_t *dclr;
-	gfx_rect_t *rect;
-} test_gc_t;
-
-PCUT_TEST(set_color)
-{
-	errno_t rc;
-	gfx_color_t *color;
-	gfx_context_t *gc = NULL;
-	test_gc_t tgc;
-
-	memset(&tgc, 0, sizeof(tgc));
-
-	rc = gfx_context_new(&ops, &tgc, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(color, tgc.dclr);
-	PCUT_ASSERT_NULL(tgc.rect);
-
-	gfx_color_delete(color);
-
-	rc = gfx_context_delete(gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-PCUT_TEST(fill_rect)
-{
-	errno_t rc;
-	gfx_color_t *color;
-	gfx_rect_t rect;
-	gfx_context_t *gc = NULL;
-	test_gc_t tgc;
-
-	memset(&tgc, 0, sizeof(tgc));
-
-	rc = gfx_context_new(&ops, &tgc, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(color, tgc.dclr);
-
-	rc = gfx_fill_rect(gc, &rect);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(&rect, tgc.rect);
-
-	gfx_color_delete(color);
-
-	rc = gfx_context_delete(gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-static errno_t testgc_set_color(void *arg, gfx_color_t *color)
-{
-	test_gc_t *tgc = (test_gc_t *) arg;
-
-	/* Technically we should copy the data */
-	tgc->dclr = color;
-	return EOK;
-}
-
-static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	test_gc_t *tgc = (test_gc_t *) arg;
-
-	/* Technically we should copy the data */
-	tgc->rect = rect;
-	return EOK;
-}
-
-PCUT_EXPORT(render);
Index: uspace/lib/graph/doc/doxygroups.h
===================================================================
--- uspace/lib/graph/doc/doxygroups.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/graph/doc/doxygroups.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,3 @@
+/** @addtogroup graph libgraph
+ * @ingroup libs
+ */
Index: uspace/lib/graph/graph.c
===================================================================
--- uspace/lib/graph/graph.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/graph/graph.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,609 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 graph
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <as.h>
+#include <stdlib.h>
+#include "graph.h"
+
+#define NAMESPACE         "graphemu"
+#define VISUALIZER_NAME   "vsl"
+#define RENDERER_NAME     "rnd"
+
+static sysarg_t namespace_idx = 0;
+static sysarg_t visualizer_idx = 0;
+static sysarg_t renderer_idx = 0;
+
+static LIST_INITIALIZE(visualizer_list);
+static LIST_INITIALIZE(renderer_list);
+
+static FIBRIL_MUTEX_INITIALIZE(visualizer_list_mtx);
+static FIBRIL_MUTEX_INITIALIZE(renderer_list_mtx);
+
+visualizer_t *graph_alloc_visualizer(void)
+{
+	return ((visualizer_t *) malloc(sizeof(visualizer_t)));
+}
+
+renderer_t *graph_alloc_renderer(void)
+{
+	// TODO
+	return ((renderer_t *) malloc(sizeof(renderer_t)));
+}
+
+void graph_init_visualizer(visualizer_t *vs)
+{
+	link_initialize(&vs->link);
+	atomic_flag_clear(&vs->claimed);
+	vs->notif_sess = NULL;
+	fibril_mutex_initialize(&vs->mode_mtx);
+	list_initialize(&vs->modes);
+	vs->mode_set = false;
+	vs->cells.data = NULL;
+	vs->dev_ctx = NULL;
+}
+
+void graph_init_renderer(renderer_t *rnd)
+{
+	// TODO
+	link_initialize(&rnd->link);
+	refcount_init(&rnd->ref_cnt);
+}
+
+errno_t graph_register_visualizer(visualizer_t *vs)
+{
+	char node[LOC_NAME_MAXLEN + 1];
+	snprintf(node, LOC_NAME_MAXLEN, "%s%zu/%s%zu", NAMESPACE,
+	    namespace_idx, VISUALIZER_NAME, visualizer_idx++);
+
+	category_id_t cat;
+	errno_t rc = loc_category_get_id("visualizer", &cat, 0);
+	if (rc != EOK)
+		return rc;
+
+	rc = loc_service_register(node, &vs->reg_svc_handle);
+	if (rc != EOK)
+		return rc;
+
+	rc = loc_service_add_to_cat(vs->reg_svc_handle, cat);
+	if (rc != EOK) {
+		loc_service_unregister(vs->reg_svc_handle);
+		return rc;
+	}
+
+	fibril_mutex_lock(&visualizer_list_mtx);
+	list_append(&vs->link, &visualizer_list);
+	fibril_mutex_unlock(&visualizer_list_mtx);
+
+	return rc;
+}
+
+errno_t graph_register_renderer(renderer_t *rnd)
+{
+	char node[LOC_NAME_MAXLEN + 1];
+	snprintf(node, LOC_NAME_MAXLEN, "%s%zu/%s%zu", NAMESPACE,
+	    namespace_idx, RENDERER_NAME, renderer_idx++);
+
+	category_id_t cat;
+	errno_t rc = loc_category_get_id("renderer", &cat, 0);
+	if (rc != EOK)
+		return rc;
+
+	rc = loc_service_register(node, &rnd->reg_svc_handle);
+	if (rc != EOK)
+		return rc;
+
+	rc = loc_service_add_to_cat(rnd->reg_svc_handle, cat);
+	if (rc != EOK) {
+		loc_service_unregister(rnd->reg_svc_handle);
+		return rc;
+	}
+
+	fibril_mutex_lock(&renderer_list_mtx);
+	list_append(&rnd->link, &renderer_list);
+	fibril_mutex_unlock(&renderer_list_mtx);
+
+	return rc;
+}
+
+visualizer_t *graph_get_visualizer(sysarg_t handle)
+{
+	visualizer_t *vs = NULL;
+
+	fibril_mutex_lock(&visualizer_list_mtx);
+
+	list_foreach(visualizer_list, link, visualizer_t, vcur) {
+		if (vcur->reg_svc_handle == handle) {
+			vs = vcur;
+			break;
+		}
+	}
+
+	fibril_mutex_unlock(&visualizer_list_mtx);
+
+	return vs;
+}
+
+renderer_t *graph_get_renderer(sysarg_t handle)
+{
+	renderer_t *rnd = NULL;
+
+	fibril_mutex_lock(&renderer_list_mtx);
+
+	list_foreach(renderer_list, link, renderer_t, rcur) {
+		if (rcur->reg_svc_handle == handle) {
+			rnd = rcur;
+			break;
+		}
+	}
+
+	if (rnd)
+		refcount_up(&rnd->ref_cnt);
+
+	fibril_mutex_unlock(&renderer_list_mtx);
+
+	return rnd;
+}
+
+errno_t graph_unregister_visualizer(visualizer_t *vs)
+{
+	fibril_mutex_lock(&visualizer_list_mtx);
+	errno_t rc = loc_service_unregister(vs->reg_svc_handle);
+	list_remove(&vs->link);
+	fibril_mutex_unlock(&visualizer_list_mtx);
+
+	return rc;
+}
+
+errno_t graph_unregister_renderer(renderer_t *rnd)
+{
+	fibril_mutex_lock(&renderer_list_mtx);
+	errno_t rc = loc_service_unregister(rnd->reg_svc_handle);
+	list_remove(&rnd->link);
+	fibril_mutex_unlock(&renderer_list_mtx);
+
+	return rc;
+}
+
+void graph_destroy_visualizer(visualizer_t *vs)
+{
+	assert(!atomic_flag_test_and_set(&vs->claimed));
+	assert(vs->notif_sess == NULL);
+	assert(!fibril_mutex_is_locked(&vs->mode_mtx));
+	assert(list_empty(&vs->modes));
+	assert(vs->mode_set == false);
+	assert(vs->cells.data == NULL);
+	assert(vs->dev_ctx == NULL);
+
+	free(vs);
+}
+
+void graph_destroy_renderer(renderer_t *rnd)
+{
+	// TODO
+	if (refcount_down(&rnd->ref_cnt))
+		free(rnd);
+}
+
+errno_t graph_notify_mode_change(async_sess_t *sess, sysarg_t handle, sysarg_t mode_idx)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_2_0(exch, VISUALIZER_MODE_CHANGE, handle, mode_idx);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+errno_t graph_notify_disconnect(async_sess_t *sess, sysarg_t handle)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	errno_t ret = async_req_1_0(exch, VISUALIZER_DISCONNECT, handle);
+	async_exchange_end(exch);
+
+	async_hangup(sess);
+
+	return ret;
+}
+
+static void vs_claim(visualizer_t *vs, ipc_call_t *icall)
+{
+	vs->client_side_handle = ipc_get_arg1(icall);
+	errno_t rc = vs->ops.claim(vs);
+	async_answer_0(icall, rc);
+}
+
+static void vs_yield(visualizer_t *vs, ipc_call_t *icall)
+{
+	/* Deallocate resources for the current mode. */
+	if (vs->mode_set) {
+		if (vs->cells.data != NULL) {
+			as_area_destroy((void *) vs->cells.data);
+			vs->cells.data = NULL;
+		}
+	}
+
+	/* Driver might also deallocate resources for the current mode. */
+	errno_t rc = vs->ops.yield(vs);
+
+	/*
+	 * Now that the driver was given a chance to deallocate resources,
+	 * current mode can be unset.
+	 */
+	if (vs->mode_set)
+		vs->mode_set = false;
+
+	async_answer_0(icall, rc);
+}
+
+static void vs_enumerate_modes(visualizer_t *vs, ipc_call_t *icall)
+{
+	size_t len;
+
+	ipc_call_t call;
+	if (!async_data_read_receive(&call, &len)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	fibril_mutex_lock(&vs->mode_mtx);
+	link_t *link = list_nth(&vs->modes, ipc_get_arg1(icall));
+
+	if (link != NULL) {
+		vslmode_list_element_t *mode_elem =
+		    list_get_instance(link, vslmode_list_element_t, link);
+
+		errno_t rc = async_data_read_finalize(&call, &mode_elem->mode, len);
+		async_answer_0(icall, rc);
+	} else {
+		async_answer_0(&call, ENOENT);
+		async_answer_0(icall, ENOENT);
+	}
+
+	fibril_mutex_unlock(&vs->mode_mtx);
+}
+
+static void vs_get_default_mode(visualizer_t *vs, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t len;
+	if (!async_data_read_receive(&call, &len)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	fibril_mutex_lock(&vs->mode_mtx);
+	vslmode_list_element_t *mode_elem = NULL;
+
+	list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
+		if (cur->mode.index == vs->def_mode_idx) {
+			mode_elem = cur;
+			break;
+		}
+	}
+
+	if (mode_elem != NULL) {
+		errno_t rc = async_data_read_finalize(&call, &mode_elem->mode, len);
+		async_answer_0(icall, rc);
+	} else {
+		fibril_mutex_unlock(&vs->mode_mtx);
+		async_answer_0(&call, ENOENT);
+		async_answer_0(icall, ENOENT);
+	}
+
+	fibril_mutex_unlock(&vs->mode_mtx);
+}
+
+static void vs_get_current_mode(visualizer_t *vs, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t len;
+	if (!async_data_read_receive(&call, &len)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (vs->mode_set) {
+		errno_t rc = async_data_read_finalize(&call, &vs->cur_mode, len);
+		async_answer_0(icall, rc);
+	} else {
+		async_answer_0(&call, ENOENT);
+		async_answer_0(icall, ENOENT);
+	}
+}
+
+static void vs_get_mode(visualizer_t *vs, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t len;
+	if (!async_data_read_receive(&call, &len)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	sysarg_t mode_idx = ipc_get_arg1(icall);
+
+	fibril_mutex_lock(&vs->mode_mtx);
+	vslmode_list_element_t *mode_elem = NULL;
+
+	list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
+		if (cur->mode.index == mode_idx) {
+			mode_elem = cur;
+			break;
+		}
+	}
+
+	if (mode_elem != NULL) {
+		errno_t rc = async_data_read_finalize(&call, &mode_elem->mode, len);
+		async_answer_0(icall, rc);
+	} else {
+		async_answer_0(&call, ENOENT);
+		async_answer_0(icall, ENOENT);
+	}
+
+	fibril_mutex_unlock(&vs->mode_mtx);
+}
+
+static void vs_set_mode(visualizer_t *vs, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t size;
+	unsigned int flags;
+
+	/* Retrieve the shared cell storage for the new mode. */
+	if (!async_share_out_receive(&call, &size, &flags)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	/* Retrieve mode index and version. */
+	sysarg_t mode_idx = ipc_get_arg1(icall);
+	sysarg_t mode_version = ipc_get_arg2(icall);
+
+	/* Find mode in the list. */
+	fibril_mutex_lock(&vs->mode_mtx);
+	vslmode_list_element_t *mode_elem = NULL;
+
+	list_foreach(vs->modes, link, vslmode_list_element_t, cur) {
+		if (cur->mode.index == mode_idx) {
+			mode_elem = cur;
+			break;
+		}
+	}
+
+	if (mode_elem == NULL) {
+		fibril_mutex_unlock(&vs->mode_mtx);
+		async_answer_0(&call, ENOENT);
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+
+	/* Extract mode description from the list node. */
+	vslmode_t new_mode = mode_elem->mode;
+	fibril_mutex_unlock(&vs->mode_mtx);
+
+	/* Check whether the mode is still up-to-date. */
+	if (new_mode.version != mode_version) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	void *new_cell_storage;
+	errno_t rc = async_share_out_finalize(&call, &new_cell_storage);
+	if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	/* Change device internal state. */
+	rc = vs->ops.change_mode(vs, new_mode);
+
+	/* Device driver could not establish new mode. Rollback. */
+	if (rc != EOK) {
+		as_area_destroy(new_cell_storage);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	/*
+	 * Because resources for the new mode were successfully
+	 * claimed, it is finally possible to free resources
+	 * allocated for the old mode.
+	 */
+	if (vs->mode_set) {
+		if (vs->cells.data != NULL) {
+			as_area_destroy((void *) vs->cells.data);
+			vs->cells.data = NULL;
+		}
+	}
+
+	/* Insert new mode into the visualizer. */
+	vs->cells.width = new_mode.screen_width;
+	vs->cells.height = new_mode.screen_height;
+	vs->cells.data = (pixel_t *) new_cell_storage;
+	vs->cur_mode = new_mode;
+	vs->mode_set = true;
+
+	async_answer_0(icall, EOK);
+}
+
+static void vs_update_damaged_region(visualizer_t *vs, ipc_call_t *icall)
+{
+	sysarg_t x_offset = (ipc_get_arg5(icall) >> 16);
+	sysarg_t y_offset = (ipc_get_arg5(icall) & 0x0000ffff);
+
+	errno_t rc = vs->ops.handle_damage(vs,
+	    ipc_get_arg1(icall), ipc_get_arg2(icall),
+	    ipc_get_arg3(icall), ipc_get_arg4(icall),
+	    x_offset, y_offset);
+	async_answer_0(icall, rc);
+}
+
+static void vs_suspend(visualizer_t *vs, ipc_call_t *icall)
+{
+	errno_t rc = vs->ops.suspend(vs);
+	async_answer_0(icall, rc);
+}
+
+static void vs_wakeup(visualizer_t *vs, ipc_call_t *icall)
+{
+	errno_t rc = vs->ops.wakeup(vs);
+	async_answer_0(icall, rc);
+}
+
+void graph_visualizer_connection(visualizer_t *vs, ipc_call_t *icall, void *arg)
+{
+	/* Claim the visualizer. */
+	if (atomic_flag_test_and_set(&vs->claimed)) {
+		async_answer_0(icall, ELIMIT);
+		return;
+	}
+
+	/* Accept the connection. */
+	async_accept_0(icall);
+
+	/* Establish callback session. */
+	ipc_call_t call;
+	async_get_call(&call);
+	vs->notif_sess = async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
+	if (vs->notif_sess != NULL)
+		async_answer_0(&call, EOK);
+	else
+		async_answer_0(&call, ELIMIT);
+
+	/* Enter command loop. */
+	while (true) {
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call)) {
+			async_answer_0(&call, EOK);
+			break;
+		}
+
+		switch (ipc_get_imethod(&call)) {
+		case VISUALIZER_CLAIM:
+			vs_claim(vs, &call);
+			break;
+		case VISUALIZER_YIELD:
+			vs_yield(vs, &call);
+			goto terminate;
+		case VISUALIZER_ENUMERATE_MODES:
+			vs_enumerate_modes(vs, &call);
+			break;
+		case VISUALIZER_GET_DEFAULT_MODE:
+			vs_get_default_mode(vs, &call);
+			break;
+		case VISUALIZER_GET_CURRENT_MODE:
+			vs_get_current_mode(vs, &call);
+			break;
+		case VISUALIZER_GET_MODE:
+			vs_get_mode(vs, &call);
+			break;
+		case VISUALIZER_SET_MODE:
+			vs_set_mode(vs, &call);
+			break;
+		case VISUALIZER_UPDATE_DAMAGED_REGION:
+			vs_update_damaged_region(vs, &call);
+			break;
+		case VISUALIZER_SUSPEND:
+			vs_suspend(vs, &call);
+			break;
+		case VISUALIZER_WAKE_UP:
+			vs_wakeup(vs, &call);
+			break;
+		default:
+			async_answer_0(&call, EINVAL);
+			goto terminate;
+		}
+	}
+
+terminate:
+	async_hangup(vs->notif_sess);
+	vs->notif_sess = NULL;
+	atomic_flag_clear(&vs->claimed);
+}
+
+void graph_renderer_connection(renderer_t *rnd, ipc_call_t *icall, void *arg)
+{
+	// TODO
+
+	/* Accept the connection. */
+	async_accept_0(icall);
+
+	/* Enter command loop. */
+	while (true) {
+		ipc_call_t call;
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call)) {
+			async_answer_0(&call, EOK);
+			break;
+		}
+
+		switch (ipc_get_imethod(&call)) {
+		default:
+			async_answer_0(&call, EINVAL);
+			goto terminate;
+		}
+	}
+
+terminate:
+	graph_destroy_renderer(rnd);
+}
+
+void graph_client_connection(ipc_call_t *icall, void *arg)
+{
+	/* Find the visualizer or renderer with the given service ID. */
+	visualizer_t *vs = graph_get_visualizer(ipc_get_arg2(icall));
+	renderer_t *rnd = graph_get_renderer(ipc_get_arg2(icall));
+
+	if (vs != NULL)
+		graph_visualizer_connection(vs, icall, arg);
+	else if (rnd != NULL)
+		graph_renderer_connection(rnd, icall, arg);
+	else
+		async_answer_0(icall, ENOENT);
+}
+
+/** @}
+ */
Index: uspace/lib/graph/graph.h
===================================================================
--- uspace/lib/graph/graph.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/graph/graph.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 graph
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef GRAPH_GRAPH_H_
+#define GRAPH_GRAPH_H_
+
+#include <stdbool.h>
+#include <loc.h>
+#include <async.h>
+#include <stdatomic.h>
+#include <refcount.h>
+#include <fibril_synch.h>
+#include <adt/list.h>
+#include <io/mode.h>
+#include <io/pixelmap.h>
+#include <ipc/graph.h>
+
+struct visualizer;
+struct renderer;
+
+typedef struct {
+	/**
+	 * Device driver shall allocate any necessary internal structures
+	 * specific for a claimed visualizer.
+	 */
+	errno_t (*claim)(struct visualizer *vs);
+
+	/**
+	 * Device driver shall deallocate any necessary internal structures
+	 * specific for a claimed visualizer. Driver shall also check whether
+	 * the mode is set and if so it shall change its internal state
+	 * accordingly (e.g. deallocate frame buffers).
+	 */
+	errno_t (*yield)(struct visualizer *vs);
+
+	/**
+	 * Device driver shall first try to claim all resources required for
+	 * a new mode (e.g. allocate new framebuffers) and only if successful
+	 * it shall free resources for the old mode. Although such behaviour
+	 * might not be always possible, it is preferable since libgraph tries to
+	 * keep current mode functional if the new mode cannot be set (for any
+	 * reason). If it is convenient for the device driver (e.g. for better
+	 * optimization), the pointer to the handle_damage operation can be
+	 * changed at this point.
+	 */
+	errno_t (*change_mode)(struct visualizer *vs, vslmode_t new_mode);
+
+	/**
+	 * Device driver shall render the cells from damaged region into its
+	 * internal framebuffer. In case the driver use multi-buffering, it
+	 * shall also switch internal buffers (e.g. by pageflip). Offsets
+	 * are intended to support basic vertical and horizontal scrolling on
+	 * the shared backbuffer (i.e. when reading from backbuffer, the offsets
+	 * shall be added to the coordinates and if necessary the result shall be
+	 * wrapped around the edge of the backbuffer).
+	 */
+	errno_t (*handle_damage)(struct visualizer *vs,
+	    sysarg_t x, sysarg_t y, sysarg_t width, sysarg_t height,
+	    sysarg_t x_offset, sysarg_t y_offset);
+
+	/**
+	 * Upper layers of the graphic stack might report inactivity. In such
+	 * case, device driver might enable power saving mode on the device
+	 * corresponding to the visualizer.
+	 */
+	errno_t (*suspend)(struct visualizer *vs);
+
+	/**
+	 * When upper layers detect activity on suspended visualizer, device
+	 * driver shall disable power saving mode on the corresponding device.
+	 */
+	errno_t (*wakeup)(struct visualizer *vs);
+} visualizer_ops_t;
+
+/**
+ * Represents final output device (e.g. monitor connected to the port
+ * on the graphic adapter, serial console, local/remote virtual monitor).
+ */
+typedef struct visualizer {
+	/**
+	 * Link to the list of all visualizers belonging to the graphic device.
+	 * Field is fully managed by libgraph.
+	 */
+	link_t link;
+
+	/**
+	 * When reference count equals 1, visualizer is claimed by a client,
+	 * when equals 0, visualizer is not claimed. At the time, visualizer
+	 * can be claimed only by a single client.
+	 * Field is fully managed by libgraph.
+	 */
+	atomic_flag claimed;
+
+	/**
+	 * Visualizer ID assigned by some particular registration service
+	 * in the system (either location service or device manager). Intended
+	 * for cleanup duties (e.g. unregistering visualizer).
+	 * If the visualizer is registered through libgraph functions, then the
+	 * field is fully managed by libgraph. Otherwise, it is a driver
+	 * responsibility to set and update this field.
+	 */
+	sysarg_t reg_svc_handle;
+
+	/**
+	 * Visualizer ID in the client context. When client gets notified by
+	 * libgraph about some event, it can use this identification to lookup
+	 * data structures corresponding to a particular visualizer (e.g. viewports
+	 * in the compositor).
+	 * Field is fully managed by libgraph. It is assigned when the visualizer
+	 * gets claimed and is valid until it is yielded.
+	 */
+	sysarg_t client_side_handle;
+
+	/**
+	 * Callback session to the client. Established by libgraph during initial
+	 * phase of client connection. Can be used to notify client about
+	 * external asynchronous changes to the output device state
+	 * (e.g. monitor gets disconnected from the graphic adapter, virtual
+	 * monitor is terminated by the user, pivot monitor is rotated by 90
+	 * degrees, virtual monitor is resized by the user).
+	 * Field is fully managed by libgraph. Device driver can use it indirectly
+	 * through notification functions.
+	 */
+	async_sess_t *notif_sess;
+
+	/**
+	 * Mutex protecting the mode list and default mode index. This is required
+	 * for the case when device driver might asynchronously update these
+	 * upon the request from the final output device (e.g. to change mode
+	 * dimensions when virtual monitor is resized).
+	 * Both device driver and libgraph must lock on this mutex when accessing
+	 * modes list or default mode index.
+	 */
+	fibril_mutex_t mode_mtx;
+
+	/**
+	 * List of all modes that can be set by this visualizer. List is populated
+	 * by device driver when creating a new visualizer or when handling the
+	 * request from the final output device to change the available modes.
+	 * When this happens, the device driver is expected to increment version
+	 * numbers in the modified modes. Modes in the list typically represent
+	 * the intersection of modes supported by device driver (graphic adapter)
+	 * and final output device (e.g. monitor).
+	 * Field is fully managed by device driver, libgraph reads it with locked
+	 * mutex.
+	 */
+	list_t modes;
+
+	/**
+	 * Index of the default mode. Might come in handy to the clients that are
+	 * not able to enumerate modes and present the choice to the user
+	 * (either the client does not have such functionality or the client is
+	 * bootstraping without any preliminary knowledge). Device driver shall
+	 * maintain this field at the same time when it is doing any changes to the
+	 * mode list.
+	 * Field is fully managed by device driver, libgraph reads it with locked
+	 * mutex.
+	 */
+	sysarg_t def_mode_idx;
+
+	/**
+	 * Copy of the currently established mode. It is read by both libgraph and
+	 * device driver when deallocating resources for the current mode. Device
+	 * driver can also read it to properly interpret the cell type and its
+	 * internal structures when handling the damage.
+	 * Field is fully managed by libgraph, can be read by device driver.
+	 */
+	vslmode_t cur_mode;
+
+	/**
+	 * Determines whether the visualizer is currently set to some mode or not,
+	 * that is whether cur_mode field contains up-to-date data.
+	 * Field is fully managed by libgraph, can be read by device driver.
+	 */
+	bool mode_set;
+
+	/**
+	 * Device driver function pointers.
+	 * Field is fully managed by device driver, libgraph invokes driver's
+	 * functions through it.
+	 */
+	visualizer_ops_t ops;
+
+	/**
+	 * Backbuffer shared with the client. Sharing is established by libgraph.
+	 * Device driver reads the cells when handling damage. Cells shall be
+	 * interpreted according to the currently set mode.
+	 * Field is fully managed by libgraph, can be read by device driver.
+	 */
+	pixelmap_t cells;
+
+	/**
+	 * Device driver context, completely opaque to the libgraph. Intended to
+	 * contain pointers to frontbuffers or information representing the
+	 * final output device (e.g. hardware port for physical monitor).
+	 * Field is fully managed by device driver.
+	 */
+	void *dev_ctx;
+} visualizer_t;
+
+typedef struct {
+	// TODO
+	int dummy;
+} renderer_ops_t;
+
+/**
+ * NOTE: Following description is just a result of brainstorming on how the
+ *       driver of real physical graphic accelerator could be supported by
+ *       libgraph.
+ *
+ * Renderer represents the hardware graphic accelerator. If the device driver
+ * handles more than one physical accelerator (e.g. graphic cards connected in
+ * SLI mode or single graphic card with two GPUs), it is up to the driver
+ * whether the load balancing will be exposed to the clients (that is the
+ * driver will provide multiple renderers) or not (just a single renderer
+ * handling the load balancing internally).
+ *
+ * At runtime, renderer is represented by scheduling thread and multiple
+ * connection fibrils handling client requests. For each client, there is
+ * command queue, condition variable and device context. Connection fibril puts
+ * the command into the command queue and blocks on the condition variable.
+ * Scheduling thread decides what client to serve, switches corresponding device
+ * context into the accelerator, consumes the command from the command queue and
+ * executes it on the accelerator. When the command execution is finished, the
+ * condition variable si signalled and the connection fibril answers the client.
+ *
+ * Operations that are not implemented in the hardware of the accelerator might
+ * be carried out by worker threads managed by scheduling thread. If the
+ * accelerator physical memory is mapped to the address space of the driver, it
+ * could be extended by allowing scheduling thread to page out the memory and
+ * to handle the page faults.
+ *
+ * NOTE: It is not entirely clear which parts should be implemented in libgraph
+ *       and which in the device driver. As a rough sketch, the connection
+ *       fibril routine, command queue and memory paging should be handled
+ *       by libgraph. The scheduling thread and device context should be
+ *       provided by device driver.
+ */
+typedef struct renderer {
+	// TODO
+	link_t link;
+
+	atomic_refcount_t ref_cnt;
+
+	sysarg_t reg_svc_handle;
+
+	renderer_ops_t ops;
+} renderer_t;
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Fill in the basic visualizer structure. The device driver shall take the
+ * created torso and to complete it by adding its specific structures
+ * (device context, modes).
+ */
+extern void graph_init_visualizer(visualizer_t *);
+
+extern void graph_init_renderer(renderer_t *);
+
+/*----------------------------------------------------------------------------*/
+
+/*
+ * NOTE: All functions in this section are intended to be used only by various
+ *       driver emulators (e.g. compositor client containing emulated driver
+ *       to render the framebuffer of other compositor or console server).
+ *       Driver of the physical hardware shall instead use similar functions
+ *       from libdrv.
+ */
+
+/**
+ * Allocate the visualizer so it can be initialized.
+ */
+extern visualizer_t *graph_alloc_visualizer(void);
+
+/**
+ * Register the completely prepared visualizer to the location service and
+ * add it to the driver visualizer list. After the registration, the visualizer
+ * is considered ready to handle client connection. Since visualizer
+ * list is guarded by the mutex, visualizers might be added even after the
+ * initialialization of the device driver.
+ */
+extern errno_t graph_register_visualizer(visualizer_t *);
+
+/**
+ * Retrieve the visualizer from the visualizer list according to its
+ * service ID.
+ */
+extern visualizer_t *graph_get_visualizer(sysarg_t);
+
+/**
+ * Unregister the visualizer from the location service and remove it
+ * from the driver visualizer list. Function shall be called by device driver
+ * before deallocating the resources for the visualizer.
+ */
+extern errno_t graph_unregister_visualizer(visualizer_t *);
+
+/**
+ * Destroy the rest of the visualizer. Device driver shall call this function
+ * only after it has unregistered the visualizer and deallocated all the
+ * resources for which the driver is responsible.
+ */
+extern void graph_destroy_visualizer(visualizer_t *);
+
+extern renderer_t *graph_alloc_renderer(void);
+extern errno_t graph_register_renderer(renderer_t *);
+extern renderer_t *graph_get_renderer(sysarg_t);
+extern errno_t graph_unregister_renderer(renderer_t *);
+extern void graph_destroy_renderer(renderer_t *);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Device driver can call this function to notify the client through the
+ * callback connection that the visualizer with a specified service ID should
+ * be switched to the mode with the given index.
+ */
+extern errno_t graph_notify_mode_change(async_sess_t *, sysarg_t, sysarg_t);
+
+/**
+ * Device driver can call this function to notify the client through the
+ * callback connection that the visualizer with a specified service ID has
+ * lost its output device (e.g. virtual monitor was closed by a user).
+ */
+extern errno_t graph_notify_disconnect(async_sess_t *, sysarg_t);
+
+/*----------------------------------------------------------------------------*/
+
+/** Shall be registered to libdrv by physical device driver. */
+extern void graph_visualizer_connection(visualizer_t *, ipc_call_t *, void *);
+
+/** Shall be registered to libdrv by physical device driver. */
+extern void graph_renderer_connection(renderer_t *, ipc_call_t *, void *);
+
+/** Shall be registered to location service by emulated device driver. */
+extern void graph_client_connection(ipc_call_t *, void *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/graph/meson.build
===================================================================
--- uspace/lib/graph/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/lib/graph/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2011 Petr Koupy
+# 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.
+#
+
+src = files('graph.c')
Index: uspace/lib/gui/meson.build
===================================================================
--- uspace/lib/gui/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/gui/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'draw' , 'softrend', 'display' ]
+deps = [ 'draw' , 'softrend' , 'graph' ]
 src = files(
 	'common.c',
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/gui/terminal.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -42,5 +42,4 @@
 #include <io/concaps.h>
 #include <io/console.h>
-#include <loc.h>
 #include <task.h>
 #include <adt/list.h>
Index: uspace/lib/gui/terminal.h
===================================================================
--- uspace/lib/gui/terminal.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/gui/terminal.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -42,5 +42,4 @@
 #include <io/chargrid.h>
 #include <io/con_srv.h>
-#include <loc.h>
 #include <adt/list.h>
 #include <adt/prodcons.h>
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/gui/window.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -48,4 +48,5 @@
 #include <adt/list.h>
 
+#include <async.h>
 #include <loc.h>
 
@@ -55,5 +56,4 @@
 #include <draw/drawctx.h>
 #include <draw/surface.h>
-#include <display.h>
 
 #include "common.h"
@@ -67,6 +67,4 @@
 static sysarg_t header_min_width = 40;
 static sysarg_t close_thickness = 20;
-static sysarg_t corner_size = 24;
-static sysarg_t window_initial_size = 1;
 
 static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
@@ -84,28 +82,4 @@
 static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
 static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
-
-static void window_close_event(void *);
-static void window_focus_event(void *);
-static void window_kbd_event(void *, kbd_event_t *);
-static void window_pos_event(void *, pos_event_t *);
-static void window_resize_event(void *, gfx_rect_t *);
-static void window_unfocus_event(void *);
-
-static display_wnd_cb_t window_cb = {
-	.close_event = window_close_event,
-	.focus_event = window_focus_event,
-	.kbd_event = window_kbd_event,
-	.pos_event = window_pos_event,
-	.resize_event = window_resize_event,
-	.unfocus_event = window_unfocus_event
-};
-
-static void set_cursor(window_t *window, display_stock_cursor_t cursor)
-{
-	if (cursor != window->cursor) {
-		(void) display_window_set_cursor(window->dwindow, cursor);
-		window->cursor = cursor;
-	}
-}
 
 static void paint_internal(widget_t *widget)
@@ -284,6 +258,4 @@
 static void root_handle_position_event(widget_t *widget, pos_event_t event)
 {
-	gfx_coord2_t pos;
-
 	if (widget->window->is_decorated) {
 		sysarg_t width = widget->width;
@@ -291,4 +263,6 @@
 
 		bool btn_left = (event.btn_num == 1) && (event.type == POS_PRESS);
+		bool btn_right = (event.btn_num == 2) && (event.type == POS_PRESS);
+		bool allowed_button = btn_left || btn_right;
 
 		bool left = (event.hpos < border_thickness);
@@ -296,11 +270,4 @@
 		bool top = (event.vpos < border_thickness);
 		bool bottom = (event.vpos >= height - border_thickness);
-		bool edge = left || right || top || bottom;
-
-		bool cleft = (event.hpos < corner_size);
-		bool cright = (event.hpos >= width - corner_size);
-		bool ctop = (event.vpos < corner_size);
-		bool cbottom = (event.vpos >= height - corner_size);
-
 		bool header = (event.hpos >= border_thickness) &&
 		    (event.hpos < width - border_thickness) &&
@@ -310,45 +277,53 @@
 		    (event.hpos >= width - border_thickness - close_thickness);
 
-		bool isresize = widget->window->is_resizable;
-		display_wnd_rsztype_t rsztype = 0;
-
-		if (edge && ctop && cleft) {
-			rsztype = display_wr_top_left;
-		} else if (edge && cbottom && cleft) {
-			rsztype = display_wr_bottom_left;
-		} else if (edge && cbottom && cright) {
-			rsztype = display_wr_bottom_right;
-		} else if (edge && ctop && cright) {
-			rsztype = display_wr_top_right;
-		} else if (top) {
-			rsztype = display_wr_top;
-		} else if (left) {
-			rsztype = display_wr_left;
-		} else if (bottom) {
-			rsztype = display_wr_bottom;
-		} else if (right) {
-			rsztype = display_wr_right;
-		} else {
-			isresize = false;
-		}
-
-		if (isresize) {
-			(void) set_cursor(widget->window,
-			    display_cursor_from_wrsz(rsztype));
-		} else {
-			(void) set_cursor(widget->window, dcurs_arrow);
-		}
-
-		pos.x = event.hpos;
-		pos.y = event.vpos;
-
-		if (isresize && btn_left) {
-			(void) display_window_resize_req(
-			    widget->window->dwindow, rsztype, &pos);
+		if (top && left && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= GF_MOVE_X;
+			flags |= GF_MOVE_Y;
+			flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
+			flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (bottom && left && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= GF_MOVE_X;
+			flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
+			flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (bottom && right && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
+			flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (top && right && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= GF_MOVE_Y;
+			flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
+			flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (top && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= GF_MOVE_Y;
+			flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (left && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= GF_MOVE_X;
+			flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (bottom && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
+		} else if (right && allowed_button) {
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
+			win_grab(widget->window->osess, event.pos_id, flags);
 		} else if (close && btn_left) {
-			window_close(widget->window);
+			win_close_request(widget->window->osess);
 		} else if (header && btn_left) {
-			(void) display_window_move_req(widget->window->dwindow,
-			    &pos);
+			window_grab_flags_t flags = GF_EMPTY;
+			flags |= GF_MOVE_X;
+			flags |= GF_MOVE_Y;
+			win_grab(widget->window->osess, event.pos_id, flags);
 		} else {
 			list_foreach(widget->children, link, widget_t, child) {
@@ -395,120 +370,24 @@
     sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
 {
-	gfx_bitmap_params_t params;
-	gfx_bitmap_alloc_t alloc;
-	gfx_bitmap_t *new_bitmap = NULL;
-	gfx_coord2_t offs;
-	gfx_coord2_t dpos;
-	display_info_t dinfo;
-	gfx_rect_t drect;
-	gfx_rect_t nrect;
-	errno_t rc;
-
-	if (width < 2 * border_thickness + header_min_width)
+	if (width < 2 * border_thickness + header_min_width) {
+		win_damage(win->osess, 0, 0, 0, 0);
 		return;
-
-	if (height < 2 * border_thickness + header_height)
+	}
+
+	if (height < 2 * border_thickness + header_height) {
+		win_damage(win->osess, 0, 0, 0, 0);
 		return;
-
+	}
+
+	/* Allocate resources for new surface. */
+	surface_t *new_surface = surface_create(width, height, NULL,
+	    SURFACE_FLAG_SHARED);
+	if (!new_surface)
+		return;
+
+	/* Switch new and old surface. */
 	fibril_mutex_lock(&win->guard);
-
-	/* Deallocate old bitmap. */
-	if (win->bitmap != NULL) {
-		gfx_bitmap_destroy(win->bitmap);
-		win->bitmap = NULL;
-	}
-
-	/* Deallocate old surface. */
-	if (win->surface != NULL) {
-		surface_destroy(win->surface);
-		win->surface = NULL;
-	}
-
-	/* Place window, if appropriate */
-	if (placement_flags != WINDOW_PLACEMENT_ANY) {
-		dpos.x = 0;
-		dpos.y = 0;
-
-		rc = display_get_info(win->display, &dinfo);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&win->guard);
-			return;
-		}
-
-		drect = dinfo.rect;
-
-		if (placement_flags & WINDOW_PLACEMENT_LEFT)
-			dpos.x = drect.p0.x;
-		else if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
-			dpos.x = (drect.p0.x + drect.p1.x - width) / 2;
-		else
-			dpos.x = drect.p1.x - width;
-
-		if (placement_flags & WINDOW_PLACEMENT_TOP)
-			dpos.y = drect.p0.y;
-		else if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
-			dpos.y = (drect.p0.y + drect.p1.y - height) / 2;
-		else
-			dpos.y = drect.p1.y - height;
-
-		(void) display_window_move(win->dwindow, &dpos);
-	}
-
-	/* Resize the display window. */
-	offs.x = offset_x;
-	offs.y = offset_y;
-	nrect.p0.x = 0;
-	nrect.p0.y = 0;
-	nrect.p1.x = width;
-	nrect.p1.y = height;
-
-	rc = display_window_resize(win->dwindow, &offs, &nrect);
-	if (rc != EOK) {
-		fibril_mutex_unlock(&win->guard);
-		return;
-	}
-
-	gfx_bitmap_params_init(&params);
-#ifndef CONFIG_WIN_DOUBLE_BUF
-	params.flags = bmpf_direct_output;
-#else
-	params.flags = 0;
-#endif
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p1.x = width;
-	params.rect.p1.y = height;
-
-	rc = gfx_bitmap_create(win->gc, &params, NULL, &new_bitmap);
-	if (rc != EOK) {
-		if (rc == ENOTSUP) {
-			/* Direct output is not supported */
-			params.flags &= ~bmpf_direct_output;
-			rc = gfx_bitmap_create(win->gc, &params, NULL, &new_bitmap);
-			if (rc != EOK) {
-				fibril_mutex_unlock(&win->guard);
-				return;
-			}
-		}
-	}
-
-	rc = gfx_bitmap_get_alloc(new_bitmap, &alloc);
-	if (rc != EOK) {
-		fibril_mutex_unlock(&win->guard);
-		return;
-	}
-
-	/* Allocate new surface. */
-	surface_t *new_surface = surface_create(width, height, alloc.pixels,
-	    SURFACE_FLAG_SHARED);
-	if (!new_surface) {
-		gfx_bitmap_destroy(new_bitmap);
-		fibril_mutex_unlock(&win->guard);
-		return;
-	}
-
-	/* Switch in new surface and bitmap. */
+	surface_t *old_surface = win->surface;
 	win->surface = new_surface;
-	win->bitmap = new_bitmap;
 	fibril_mutex_unlock(&win->guard);
 
@@ -523,5 +402,35 @@
 	fibril_mutex_unlock(&win->guard);
 
-	(void) gfx_bitmap_render(win->bitmap, NULL, NULL);
+	/* Inform compositor about new surface. */
+	errno_t rc = win_resize(win->osess, offset_x, offset_y, width, height,
+	    placement_flags, surface_direct_access(new_surface));
+
+	if (rc != EOK) {
+		/* Rollback to old surface. Reverse all changes. */
+
+		sysarg_t old_width = 0;
+		sysarg_t old_height = 0;
+		if (old_surface)
+			surface_get_resolution(old_surface, &old_width, &old_height);
+
+		fibril_mutex_lock(&win->guard);
+		new_surface = win->surface;
+		win->surface = old_surface;
+		fibril_mutex_unlock(&win->guard);
+
+		win->root.rearrange(&win->root, 0, 0, old_width, old_height);
+
+		if (win->surface) {
+			fibril_mutex_lock(&win->guard);
+			surface_reset_damaged_region(win->surface);
+			fibril_mutex_unlock(&win->guard);
+		}
+
+		surface_destroy(new_surface);
+	} else {
+		/* Deallocate old surface. */
+		if (old_surface)
+			surface_destroy(old_surface);
+	}
 }
 
@@ -534,5 +443,4 @@
 {
 	sysarg_t x, y, width, height;
-	gfx_rect_t rect;
 	fibril_mutex_lock(&win->guard);
 	surface_get_damaged_region(win->surface, &x, &y, &width, &height);
@@ -541,11 +449,6 @@
 
 	if (width > 0 && height > 0) {
-		rect.p0.x = x;
-		rect.p0.y = y;
-		rect.p1.x = x + width;
-		rect.p1.y = y + height;
-
-		if (win->bitmap != NULL)
-			(void) gfx_bitmap_render(win->bitmap, &rect, NULL);
+		/* Notify compositor. */
+		win_damage(win->osess, x, y, width, height);
 	}
 }
@@ -569,14 +472,7 @@
 	win->focus = NULL;
 
-	gfx_bitmap_destroy(win->bitmap);
-
-	/*
-	 * XXX Here we should properly destroy the IPC GC. We only have
-	 * the generic GC so either it would need to be cast back or
-	 * GC needs a virtual destructor.
-	 */
-
-	display_window_destroy(win->dwindow);
-	display_close(win->display);
+	win_close(win->osess);
+	async_hangup(win->isess);
+	async_hangup(win->osess);
 
 	while (!list_empty(&win->events.list)) {
@@ -610,4 +506,8 @@
 			break;
 		case ET_POSITION_EVENT:
+			if (!win->is_focused) {
+				win->is_focused = true;
+				handle_refresh(win);
+			}
 			deliver_position_event(win, event->data.pos);
 			break;
@@ -659,10 +559,40 @@
 }
 
+/* Input fetcher from compositor. Runs in own dedicated fibril. */
+static errno_t fetch_input(void *arg)
+{
+	errno_t rc;
+	bool terminate = false;
+	window_t *win = (window_t *) arg;
+
+	while (true) {
+		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+
+		if (event) {
+			rc = win_get_event(win->isess, event);
+			if (rc == EOK) {
+				terminate = (event->type == ET_WINDOW_CLOSE);
+				link_initialize(&event->link);
+				prodcons_produce(&win->events, &event->link);
+			} else {
+				free(event);
+				terminate = true;
+			}
+		} else {
+			terminate = true;
+		}
+
+		if (terminate) {
+			break;
+		}
+	}
+
+	return 0;
+}
+
 window_t *window_open(const char *winreg, const void *data,
     window_flags_t flags, const char *caption)
 {
-	display_wnd_params_t wparams;
-
-	window_t *win = (window_t *) calloc(1, sizeof(window_t));
+	window_t *win = (window_t *) malloc(sizeof(window_t));
 	if (!win)
 		return NULL;
@@ -670,5 +600,4 @@
 	win->is_main = flags & WINDOW_MAIN;
 	win->is_decorated = flags & WINDOW_DECORATED;
-	win->is_resizable = flags & WINDOW_RESIZEABLE;
 	win->is_focused = true;
 	prodcons_initialize(&win->events);
@@ -685,44 +614,38 @@
 	win->grab = NULL;
 	win->focus = NULL;
-	win->cursor = dcurs_arrow;
-
-	/* Allocate resources for new surface. */
-	win->surface = surface_create(window_initial_size,
-	    window_initial_size, NULL, SURFACE_FLAG_SHARED);
-	if (win->surface == NULL) {
+	win->surface = NULL;
+
+	service_id_t reg_dsid;
+	errno_t rc = loc_service_get_id(winreg, &reg_dsid, 0);
+	if (rc != EOK) {
 		free(win);
 		return NULL;
 	}
 
-	errno_t rc = display_open(winreg, &win->display);
-	if (rc != EOK) {
-		surface_destroy(win->surface);
+	async_sess_t *reg_sess =
+	    loc_service_connect(reg_dsid, INTERFACE_COMPOSITOR, 0);
+	if (reg_sess == NULL) {
 		free(win);
 		return NULL;
 	}
 
-	/* Window dimensions are not know at this time */
-	display_wnd_params_init(&wparams);
-	wparams.rect.p0.x = 0;
-	wparams.rect.p0.y = 0;
-	wparams.rect.p1.x = window_initial_size;
-	wparams.rect.p1.y = window_initial_size;
-	wparams.min_size.x = 2 * border_thickness + header_min_width;
-	wparams.min_size.y = 2 * border_thickness + header_height;
-
-	rc = display_window_create(win->display, &wparams, &window_cb,
-	    (void *) win, &win->dwindow);
+	service_id_t in_dsid;
+	service_id_t out_dsid;
+	rc = win_register(reg_sess, flags, &in_dsid, &out_dsid);
+	async_hangup(reg_sess);
 	if (rc != EOK) {
-		display_close(win->display);
-		surface_destroy(win->surface);
 		free(win);
 		return NULL;
 	}
 
-	rc = display_window_get_gc(win->dwindow, &win->gc);
-	if (rc != EOK) {
-		display_window_destroy(win->dwindow);
-		display_close(win->display);
-		surface_destroy(win->surface);
+	win->osess = loc_service_connect(out_dsid, INTERFACE_COMPOSITOR, 0);
+	if (win->osess == NULL) {
+		free(win);
+		return NULL;
+	}
+
+	win->isess = loc_service_connect(in_dsid, INTERFACE_COMPOSITOR, 0);
+	if (win->isess == NULL) {
+		async_hangup(win->osess);
 		free(win);
 		return NULL;
@@ -801,8 +724,10 @@
 {
 	fid_t ev_fid = fibril_create(event_loop, win);
-	if (!ev_fid) {
+	fid_t fi_fid = fibril_create(fetch_input, win);
+	if (!ev_fid || !fi_fid) {
 		return;
 	}
 	fibril_add_ready(ev_fid);
+	fibril_add_ready(fi_fid);
 }
 
@@ -820,100 +745,6 @@
 void window_close(window_t *win)
 {
-	window_event_t *event;
-
-	event = (window_event_t *) calloc(1, sizeof(window_event_t));
-	if (event == NULL)
-		return;
-
-	link_initialize(&event->link);
-	event->type = ET_WINDOW_CLOSE;
-	prodcons_produce(&win->events, &event->link);
-}
-
-static void window_close_event(void *arg)
-{
-	window_t *win = (window_t *) arg;
-
-	window_close(win);
-}
-
-static void window_focus_event(void *arg)
-{
-	window_t *win = (window_t *) arg;
-	window_event_t *event;
-
-	event = (window_event_t *) calloc(1, sizeof(window_event_t));
-	if (event == NULL)
-		return;
-
-	link_initialize(&event->link);
-	event->type = ET_WINDOW_FOCUS;
-	prodcons_produce(&win->events, &event->link);
-}
-
-static void window_kbd_event(void *arg, kbd_event_t *kevent)
-{
-	window_t *win = (window_t *) arg;
-	window_event_t *event;
-
-	event = (window_event_t *) calloc(1, sizeof(window_event_t));
-	if (event == NULL)
-		return;
-
-	link_initialize(&event->link);
-	event->type = ET_KEYBOARD_EVENT;
-	event->data.kbd = *kevent;
-	prodcons_produce(&win->events, &event->link);
-}
-
-static void window_pos_event(void *arg, pos_event_t *pevent)
-{
-	window_t *win = (window_t *) arg;
-	window_event_t *event;
-
-	event = (window_event_t *) calloc(1, sizeof(window_event_t));
-	if (event == NULL)
-		return;
-
-	link_initialize(&event->link);
-	event->type = ET_POSITION_EVENT;
-	event->data.pos = *pevent;
-	prodcons_produce(&win->events, &event->link);
-}
-
-static void window_resize_event(void *arg, gfx_rect_t *nrect)
-{
-	window_t *win = (window_t *) arg;
-	window_event_t *event;
-
-	if (!win->is_resizable)
-		return;
-
-	event = (window_event_t *) calloc(1, sizeof(window_event_t));
-	if (event == NULL)
-		return;
-
-	link_initialize(&event->link);
-	event->type = ET_WINDOW_RESIZE;
-	event->data.resize.offset_x = nrect->p0.x;
-	event->data.resize.offset_y = nrect->p0.y;
-	event->data.resize.width = nrect->p1.x - nrect->p0.x;
-	event->data.resize.height = nrect->p1.y - nrect->p0.y;
-	event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
-	prodcons_produce(&win->events, &event->link);
-}
-
-static void window_unfocus_event(void *arg)
-{
-	window_t *win = (window_t *) arg;
-	window_event_t *event;
-
-	event = (window_event_t *) calloc(1, sizeof(window_event_t));
-	if (event == NULL)
-		return;
-
-	link_initialize(&event->link);
-	event->type = ET_WINDOW_UNFOCUS;
-	prodcons_produce(&win->events, &event->link);
+	/* Request compositor to init closing cascade. */
+	win_close_request(win->osess);
 }
 
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/gui/window.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -37,4 +37,5 @@
 #define GUI_WINDOW_H_
 
+#include <async.h>
 #include <adt/prodcons.h>
 #include <fibril_synch.h>
@@ -42,7 +43,4 @@
 #include <io/window.h>
 #include <draw/surface.h>
-#include <display.h>
-#include <gfx/bitmap.h>
-#include <gfx/context.h>
 
 #include "widget.h"
@@ -52,9 +50,7 @@
 	bool is_decorated; /**< True if the window decorations should be rendered. */
 	bool is_focused; /**< True for the top level window of the desktop. */
-	bool is_resizable; /**< True if window is resizable */
 	char *caption; /**< Text title of the window header. */
-	display_t *display; /**< Display service */
-	display_window_t *dwindow; /**< Display window */
-	gfx_context_t *gc; /**< GC of the window */
+	async_sess_t *isess; /**< Input events from compositor. */
+	async_sess_t *osess; /**< Mainly for damage reporting to compositor. */
 	prodcons_t events; /**< Queue for window event loop. */
 	widget_t root; /**< Decoration widget serving as a root of widget hiearchy. */
@@ -62,11 +58,9 @@
 	widget_t *focus; /**< Widget owning the keyboard or NULL. */
 	fibril_mutex_t guard; /**< Mutex guarding window surface. */
-	surface_t *surface; /**< Window surface shared with display server. */
-	gfx_bitmap_t *bitmap; /**< Window bitmap */
-	display_stock_cursor_t cursor; /**< Selected cursor */
+	surface_t *surface; /**< Window surface shared with compositor. */
 };
 
 /**
- * Allocate all resources for new window and register it in the display server.
+ * Allocate all resources for new window and register it in the compositor.
  * If the window is declared as main, its closure causes termination of the
  * whole application. Note that opened window does not have any surface yet.
@@ -77,7 +71,7 @@
 /**
  * Post resize event into event loop. Window negotiates new surface with
- * display server and asks all widgets in the tree to calculate their new
- * properties and to paint themselves on the new surface (top-bottom order).
- * Should be called also after opening new window to obtain surface.
+ * compositor and asks all widgets in the tree to calculate their new properties
+ * and to paint themselves on the new surface (top-bottom order). Should be
+ * called also after opening new window to obtain surface.
  */
 extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
@@ -96,6 +90,6 @@
 
 /**
- * Post damage event into event loop. Handler informs display server to update
- * the window surface on the screen. Should be called by widget after painting
+ * Post damage event into event loop. Handler informs compositor to update the
+ * window surface on the screen. Should be called by widget after painting
  * itself or copying its buffer onto window surface.
  */
@@ -126,5 +120,5 @@
 
 /**
- * Initiate the closing cascade for the window. First, display sever deallocates
+ * Initiate the closing cascade for the window. First, compositor deallocates
  * output resources, prepares special closing input event for the window and
  * deallocates input resources after the event is dispatched. When window
Index: pace/lib/guigfx/doc/doxygroups.h
===================================================================
--- uspace/lib/guigfx/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libguigfx libguigfx
- * @ingroup libs
- */
Index: pace/lib/guigfx/include/guigfx/canvas.h
===================================================================
--- uspace/lib/guigfx/include/guigfx/canvas.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2019 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 libguigfx
- * @{
- */
-/**
- * @file GFX canvas backend
- */
-
-#ifndef _GUIGFX_CANVAS_H
-#define _GUIGFX_CANVAS_H
-
-#include <canvas.h>
-#include <types/gfx/context.h>
-#include <types/gfx/ops/context.h>
-#include <types/guigfx/canvas.h>
-
-extern gfx_context_ops_t canvas_gc_ops;
-
-extern errno_t canvas_gc_create(canvas_t *, surface_t *, canvas_gc_t **);
-extern errno_t canvas_gc_delete(canvas_gc_t *);
-extern gfx_context_t *canvas_gc_get_ctx(canvas_gc_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/guigfx/include/types/guigfx/canvas.h
===================================================================
--- uspace/lib/guigfx/include/types/guigfx/canvas.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2019 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 libguigfx
- * @{
- */
-/**
- * @file GFX canvas backend
- */
-
-#ifndef _GUIGFX_TYPES_CANVAS_H
-#define _GUIGFX_TYPES_CANVAS_H
-
-struct canvas_gc;
-typedef struct canvas_gc canvas_gc_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/guigfx/meson.build
===================================================================
--- uspace/lib/guigfx/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,32 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'gui', 'gfx', 'memgfx' ]
-src = files(
-	'src/canvas.c'
-)
Index: pace/lib/guigfx/private/canvas.h
===================================================================
--- uspace/lib/guigfx/private/canvas.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2019 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 libguigfx
- * @{
- */
-/**
- * @file GFX canvas backend structure
- *
- */
-
-#ifndef _GUIGFX_PRIVATE_CANVAS_H
-#define _GUIGFX_PRIVATE_CANVAS_H
-
-#include <canvas.h>
-#include <draw/surface.h>
-#include <gfx/bitmap.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <io/pixel.h>
-#include <memgfx/memgc.h>
-
-/** Actual structure of canvas GC. */
-struct canvas_gc {
-	/** Memory GC */
-	mem_gc_t *mgc;
-	/** Base graphic context */
-	gfx_context_t *gc;
-	/** Canvas */
-	canvas_t *canvas;
-	/** Surface */
-	surface_t *surface;
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/guigfx/src/canvas.c
===================================================================
--- uspace/lib/guigfx/src/canvas.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,147 +1,0 @@
-/*
- * Copyright (c) 2019 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 libguigfx
- * @{
- */
-/**
- * @file GFX canvas backend
- *
- * This implements a graphics context over a libgui canvas.
- * This is just for experimentation purposes and its kind of backwards.
- */
-
-#include <draw/drawctx.h>
-#include <draw/source.h>
-#include <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <guigfx/canvas.h>
-#include <io/pixel.h>
-#include <stdlib.h>
-#include <transform.h>
-#include "../private/canvas.h"
-//#include "../../private/color.h"
-
-static void canvas_gc_update_cb(void *, gfx_rect_t *);
-
-/** Create canvas GC.
- *
- * Create graphics context for rendering into a canvas.
- *
- * @param canvas Canvas object
- * @param fout File to which characters are written (canvas)
- * @param rgc Place to store pointer to new GC.
- *
- * @return EOK on success or an error code
- */
-errno_t canvas_gc_create(canvas_t *canvas, surface_t *surface,
-    canvas_gc_t **rgc)
-{
-	canvas_gc_t *cgc = NULL;
-	surface_coord_t w, h;
-	gfx_rect_t rect;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	surface_get_resolution(surface, &w, &h);
-
-	cgc = calloc(1, sizeof(canvas_gc_t));
-	if (cgc == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rect.p0.x = 0;
-	rect.p0.y = 0;
-	rect.p1.x = w;
-	rect.p1.y = h;
-
-	alloc.pitch = w * sizeof(uint32_t);
-	alloc.off0 = 0;
-	alloc.pixels = surface_direct_access(surface);
-
-	rc = mem_gc_create(&rect, &alloc, canvas_gc_update_cb,
-	    (void *)cgc, &cgc->mgc);
-	if (rc != EOK)
-		goto error;
-
-	cgc->gc = mem_gc_get_ctx(cgc->mgc);
-
-	cgc->canvas = canvas;
-	cgc->surface = surface;
-	*rgc = cgc;
-	return EOK;
-error:
-	if (cgc != NULL)
-		free(cgc);
-	return rc;
-}
-
-/** Delete canvas GC.
- *
- * @param cgc Canvas GC
- */
-errno_t canvas_gc_delete(canvas_gc_t *cgc)
-{
-	errno_t rc;
-
-	mem_gc_delete(cgc->mgc);
-
-	rc = gfx_context_delete(cgc->gc);
-	if (rc != EOK)
-		return rc;
-
-	free(cgc);
-	return EOK;
-}
-
-/** Get generic graphic context from canvas GC.
- *
- * @param cgc Canvas GC
- * @return Graphic context
- */
-gfx_context_t *canvas_gc_get_ctx(canvas_gc_t *cgc)
-{
-	return cgc->gc;
-}
-
-/** Canvas GC update callback called by memory GC.
- *
- * @param arg Canvas GC
- * @param rect Rectangle to update
- */
-static void canvas_gc_update_cb(void *arg, gfx_rect_t *rect)
-{
-	canvas_gc_t *cgc = (canvas_gc_t *)arg;
-
-	update_canvas(cgc->canvas, cgc->surface);
-}
-
-/** @}
- */
Index: pace/lib/ipcgfx/doc/doxygroups.h
===================================================================
--- uspace/lib/ipcgfx/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libcongfx libcongfx
- * @ingroup libs
- */
Index: pace/lib/ipcgfx/include/ipcgfx/client.h
===================================================================
--- uspace/lib/ipcgfx/include/ipcgfx/client.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file GFX IPC backend
- */
-
-#ifndef _IPCGFX_CLIENT_H
-#define _IPCGFX_CLIENT_H
-
-#include <async.h>
-#include <types/ipcgfx/client.h>
-#include <types/gfx/context.h>
-#include <types/gfx/ops/context.h>
-
-extern gfx_context_ops_t ipc_gc_ops;
-
-extern errno_t ipc_gc_create(async_sess_t *, ipc_gc_t **);
-extern errno_t ipc_gc_delete(ipc_gc_t *);
-extern gfx_context_t *ipc_gc_get_ctx(ipc_gc_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/ipcgfx/include/ipcgfx/ipc/gc.h
===================================================================
--- uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/** @file
- */
-
-#ifndef _IPCGFX_IPC_GC_H_
-#define _IPCGFX_IPC_GC_H_
-
-#include <ipc/common.h>
-
-typedef enum {
-	GC_SET_RGB_COLOR = IPC_FIRST_USER_METHOD,
-	GC_FILL_RECT,
-	GC_BITMAP_CREATE,
-	GC_BITMAP_CREATE_DOUTPUT,
-	GC_BITMAP_DESTROY,
-	GC_BITMAP_RENDER,
-	GC_BITMAP_GET_ALLOC
-} gc_request_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ipcgfx/include/ipcgfx/server.h
===================================================================
--- uspace/lib/ipcgfx/include/ipcgfx/server.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file GFX IPC server
- */
-
-#ifndef _IPCGFX_SERVER_H
-#define _IPCGFX_SERVER_H
-
-#include <async.h>
-#include <errno.h>
-#include <gfx/context.h>
-
-extern errno_t gc_conn(ipc_call_t *icall, gfx_context_t *gc);
-
-#endif
-
-/** @}
- */
Index: pace/lib/ipcgfx/include/types/ipcgfx/client.h
===================================================================
--- uspace/lib/ipcgfx/include/types/ipcgfx/client.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file GFX IPC backend
- */
-
-#ifndef _IPCGFX_TYPES_CLIENT_H
-#define _IPCGFX_TYPES_CLIENT_H
-
-struct ipc_gc;
-typedef struct ipc_gc ipc_gc_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ipcgfx/meson.build
===================================================================
--- uspace/lib/ipcgfx/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'gfx' ]
-src = files(
-	'src/client.c',
-	'src/server.c'
-)
-
-test_src = files(
-	'test/ipcgfx.c',
-	'test/main.c',
-)
Index: pace/lib/ipcgfx/private/client.h
===================================================================
--- uspace/lib/ipcgfx/private/client.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file GFX console backend structure
- *
- */
-
-#ifndef _IPCGFX_PRIVATE_CLIENT_H
-#define _IPCGFX_PRIVATE_CLIENT_H
-
-#include <async.h>
-#include <gfx/context.h>
-
-/** Actual structure of graphics context.
- *
- * This is private to libcongfx. It is not visible to clients nor backends.
- */
-struct ipc_gc {
-	/** Base graphic context */
-	gfx_context_t *gc;
-	/** Session with GFX server */
-	async_sess_t *sess;
-};
-
-/** Bitmap in IPC GC */
-typedef struct {
-	/** Containing IPC GC */
-	struct ipc_gc *ipcgc;
-	/** Allocation info */
-	gfx_bitmap_alloc_t alloc;
-	/** @c true if we allocated the bitmap, @c false if allocated by caller */
-	bool myalloc;
-	/** Rectangle covered by bitmap */
-	gfx_rect_t rect;
-	/** Server bitmap ID */
-	sysarg_t bmp_id;
-} ipc_gc_bitmap_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ipcgfx/private/server.h
===================================================================
--- uspace/lib/ipcgfx/private/server.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,77 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file IPC GFX backend structure
- *
- */
-
-#ifndef _IPCGFX_PRIVATE_SERVER_H
-#define _IPCGFX_PRIVATE_SERVER_H
-
-#include <adt/list.h>
-#include <async.h>
-#include <gfx/bitmap.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <stdbool.h>
-
-/** Server-side of IPC GC connection.
- */
-typedef struct {
-	/** Graphics context to serve */
-	gfx_context_t *gc;
-	/** List of bitmaps (ipc_gc_srv_bitmap_t) */
-	list_t bitmaps;
-	/** Next bitmap ID to allocate */
-	sysarg_t next_bmp_id;
-} ipc_gc_srv_t;
-
-/** Bitmap in canvas GC */
-typedef struct {
-	/** Containing canvas GC */
-	ipc_gc_srv_t *srvgc;
-	/** Link to srvgc->bitmaps */
-	link_t lbitmaps;
-	/** Backing bitmap */
-	gfx_bitmap_t *bmp;
-	/** Bitmap ID */
-	sysarg_t bmp_id;
-	/** @c true if we allocated the pixels */
-	bool myalloc;
-	/** Pixels of the bitmap */
-	void *pixels;
-} ipc_gc_srv_bitmap_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/ipcgfx/src/client.c
===================================================================
--- uspace/lib/ipcgfx/src/client.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,464 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file GFX IPC backend
- *
- * This implements a graphics context via HelenOS IPC.
- */
-
-#include <as.h>
-#include <ipcgfx/client.h>
-#include <ipcgfx/ipc/gc.h>
-#include <gfx/color.h>
-#include <gfx/coord.h>
-#include <gfx/context.h>
-#include <stdlib.h>
-#include "../private/client.h"
-
-static errno_t ipc_gc_set_color(void *, gfx_color_t *);
-static errno_t ipc_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t ipc_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t ipc_gc_bitmap_destroy(void *);
-static errno_t ipc_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t ipc_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-gfx_context_ops_t ipc_gc_ops = {
-	.set_color = ipc_gc_set_color,
-	.fill_rect = ipc_gc_fill_rect,
-	.bitmap_create = ipc_gc_bitmap_create,
-	.bitmap_destroy = ipc_gc_bitmap_destroy,
-	.bitmap_render = ipc_gc_bitmap_render,
-	.bitmap_get_alloc = ipc_gc_bitmap_get_alloc
-};
-
-/** Set color on IPC GC.
- *
- * Set drawing color on IPC GC.
- *
- * @param arg IPC GC
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_set_color(void *arg, gfx_color_t *color)
-{
-	ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
-	async_exch_t *exch;
-	uint16_t r, g, b;
-	errno_t rc;
-
-	gfx_color_get_rgb_i16(color, &r, &g, &b);
-
-	exch = async_exchange_begin(ipcgc->sess);
-	rc = async_req_3_0(exch, GC_SET_RGB_COLOR, r, g, b);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-/** Fill rectangle on IPC GC.
- *
- * @param arg IPC GC
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
-	async_exch_t *exch;
-	errno_t rc;
-
-	exch = async_exchange_begin(ipcgc->sess);
-	rc = async_req_4_0(exch, GC_FILL_RECT, rect->p0.x, rect->p0.y,
-	    rect->p1.x, rect->p1.y);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-/** Create normal bitmap in IPC GC.
- *
- * @param arg IPC GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_bitmap_create_normal(void *arg,
-    gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
-	ipc_gc_bitmap_t *ipcbm = NULL;
-	gfx_coord2_t dim;
-	async_exch_t *exch = NULL;
-	as_area_info_t info;
-	ipc_call_t answer;
-	size_t asize;
-	aid_t req;
-	errno_t rc;
-
-	ipcbm = calloc(1, sizeof(ipc_gc_bitmap_t));
-	if (ipcbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	ipcbm->rect = params->rect;
-
-	if (alloc == NULL) {
-		ipcbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		ipcbm->alloc.off0 = 0;
-		ipcbm->alloc.pixels = as_area_create(AS_AREA_ANY,
-		    dim.x * dim.y * sizeof(uint32_t), AS_AREA_READ |
-		    AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
-		if (ipcbm->alloc.pixels == AS_MAP_FAILED) {
-			rc = ENOMEM;
-			goto error;
-		}
-
-		ipcbm->myalloc = true;
-	} else {
-		/*
-		 * Accept user allocation if it points to a an acceptable
-		 * memory area.
-		 */
-		rc = as_area_get_info(alloc->pixels, &info);
-		if (rc != EOK)
-			goto error;
-
-		/* Pixels should start at the beginning of the area */
-		if (info.start_addr != (uintptr_t) alloc->pixels) {
-			rc = EINVAL;
-			goto error;
-		}
-
-		/* Size of area should be size of bitmap rounded up to page size */
-		asize = PAGES2SIZE(SIZE2PAGES(alloc->pitch * dim.y));
-		if (info.size != asize) {
-			rc = EINVAL;
-			goto error;
-		}
-
-		ipcbm->alloc = *alloc;
-	}
-
-	exch = async_exchange_begin(ipcgc->sess);
-	req = async_send_0(exch, GC_BITMAP_CREATE, &answer);
-	rc = async_data_write_start(exch, params, sizeof (gfx_bitmap_params_t));
-	if (rc != EOK) {
-		async_forget(req);
-		goto error;
-	}
-
-	rc = async_share_out_start(exch, ipcbm->alloc.pixels,
-	    AS_AREA_READ | AS_AREA_CACHEABLE);
-	if (rc != EOK) {
-		async_forget(req);
-		goto error;
-	}
-	async_exchange_end(exch);
-	exch = NULL;
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		goto error;
-
-	ipcbm->ipcgc = ipcgc;
-	ipcbm->bmp_id = ipc_get_arg1(&answer);
-	*rbm = (void *)ipcbm;
-	return EOK;
-error:
-	if (exch != NULL)
-		async_exchange_end(exch);
-	if (ipcbm != NULL) {
-		if (ipcbm->alloc.pixels != NULL)
-			as_area_destroy(ipcbm->alloc.pixels);
-		free(ipcbm);
-	}
-	return rc;
-}
-
-/** Create direct output bitmap in IPC GC.
- *
- * @param arg IPC GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_bitmap_create_direct_output(void *arg,
-    gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
-	ipc_gc_bitmap_t *ipcbm = NULL;
-	gfx_coord2_t dim;
-	async_exch_t *exch = NULL;
-	void *pixels;
-	ipc_call_t answer;
-	size_t asize;
-	aid_t req;
-	errno_t rc;
-
-	/* Cannot specify allocation for direct output bitmap */
-	if (alloc != NULL)
-		return EINVAL;
-
-	ipcbm = calloc(1, sizeof(ipc_gc_bitmap_t));
-	if (ipcbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	ipcbm->rect = params->rect;
-
-	ipcbm->alloc.pitch = dim.x * sizeof(uint32_t);
-	ipcbm->alloc.off0 = 0;
-	ipcbm->myalloc = true;
-
-	asize = PAGES2SIZE(SIZE2PAGES(ipcbm->alloc.pitch * dim.y));
-
-	exch = async_exchange_begin(ipcgc->sess);
-	req = async_send_0(exch, GC_BITMAP_CREATE_DOUTPUT, &answer);
-	rc = async_data_write_start(exch, params, sizeof (gfx_bitmap_params_t));
-	if (rc != EOK) {
-		async_forget(req);
-		goto error;
-	}
-
-	rc = async_share_in_start_0_0(exch, asize, &pixels);
-	if (rc != EOK) {
-		async_forget(req);
-		goto error;
-	}
-	async_exchange_end(exch);
-	exch = NULL;
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		goto error;
-
-	ipcbm->ipcgc = ipcgc;
-	ipcbm->bmp_id = ipc_get_arg1(&answer);
-	ipcbm->alloc.pixels = pixels;
-	*rbm = (void *)ipcbm;
-	return EOK;
-error:
-	if (exch != NULL)
-		async_exchange_end(exch);
-	if (ipcbm != NULL) {
-		if (ipcbm->alloc.pixels != NULL)
-			as_area_destroy(ipcbm->alloc.pixels);
-		free(ipcbm);
-	}
-	return rc;
-}
-
-/** Create bitmap in IPC GC.
- *
- * @param arg IPC GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t ipc_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	if ((params->flags & bmpf_direct_output) != 0) {
-		return ipc_gc_bitmap_create_direct_output(arg, params, alloc,
-		    rbm);
-	} else {
-		return ipc_gc_bitmap_create_normal(arg, params, alloc, rbm);
-	}
-}
-
-/** Destroy bitmap in IPC GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_bitmap_destroy(void *bm)
-{
-	ipc_gc_bitmap_t *ipcbm = (ipc_gc_bitmap_t *)bm;
-	async_exch_t *exch;
-	errno_t rc;
-
-	exch = async_exchange_begin(ipcbm->ipcgc->sess);
-	rc = async_req_1_0(exch, GC_BITMAP_DESTROY, ipcbm->bmp_id);
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		return rc;
-
-	if (ipcbm->myalloc)
-		as_area_destroy(ipcbm->alloc.pixels);
-	free(ipcbm);
-	return EOK;
-}
-
-/** Render bitmap in IPC GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	ipc_gc_bitmap_t *ipcbm = (ipc_gc_bitmap_t *)bm;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-	gfx_coord2_t offs;
-	async_exch_t *exch = NULL;
-	ipc_call_t answer;
-	aid_t req;
-	errno_t rc;
-
-	if (srect0 != NULL)
-		srect = *srect0;
-	else
-		srect = ipcbm->rect;
-
-	if (offs0 != NULL) {
-		offs = *offs0;
-	} else {
-		offs.x = 0;
-		offs.y = 0;
-	}
-
-	/* Destination rectangle */
-	gfx_rect_translate(&offs, &srect, &drect);
-
-	exch = async_exchange_begin(ipcbm->ipcgc->sess);
-	req = async_send_3(exch, GC_BITMAP_RENDER, ipcbm->bmp_id, offs.x,
-	    offs.y, &answer);
-
-	rc = async_data_write_start(exch, &srect, sizeof (gfx_rect_t));
-	if (rc != EOK) {
-		async_forget(req);
-		goto error;
-	}
-
-	async_exchange_end(exch);
-	exch = NULL;
-
-	async_wait_for(req, &rc);
-	if (rc != EOK)
-		goto error;
-
-	return EOK;
-error:
-	if (exch != NULL)
-		async_exchange_end(exch);
-	return rc;
-}
-
-/** Get allocation info for bitmap in IPC GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t ipc_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	ipc_gc_bitmap_t *ipcbm = (ipc_gc_bitmap_t *)bm;
-	*alloc = ipcbm->alloc;
-	return EOK;
-}
-
-/** Create IPC GC.
- *
- * Create graphics context for rendering via IPC.
- *
- * @param sess Async session
- * @param rgc Place to store pointer to new GC.
- *
- * @return EOK on success or an error code
- */
-errno_t ipc_gc_create(async_sess_t *sess, ipc_gc_t **rgc)
-{
-	ipc_gc_t *ipcgc = NULL;
-	gfx_context_t *gc = NULL;
-	errno_t rc;
-
-	ipcgc = calloc(1, sizeof(ipc_gc_t));
-	if (ipcgc == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rc = gfx_context_new(&ipc_gc_ops, ipcgc, &gc);
-	if (rc != EOK)
-		goto error;
-
-	ipcgc->gc = gc;
-	ipcgc->sess = sess;
-	*rgc = ipcgc;
-	return EOK;
-error:
-	if (ipcgc != NULL)
-		free(ipcgc);
-	gfx_context_delete(gc);
-	return rc;
-}
-
-/** Delete IPC GC.
- *
- * @param ipcgc IPC GC
- */
-errno_t ipc_gc_delete(ipc_gc_t *ipcgc)
-{
-	errno_t rc;
-
-	rc = gfx_context_delete(ipcgc->gc);
-	if (rc != EOK)
-		return rc;
-
-	free(ipcgc);
-	return EOK;
-}
-
-/** Get generic graphic context from IPC GC.
- *
- * @param ipcgc IPC GC
- * @return Graphic context
- */
-gfx_context_t *ipc_gc_get_ctx(ipc_gc_t *ipcgc)
-{
-	return ipcgc->gc;
-}
-
-/** @}
- */
Index: pace/lib/ipcgfx/src/server.c
===================================================================
--- uspace/lib/ipcgfx/src/server.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,399 +1,0 @@
-/*
- * Copyright (c) 2019 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 libipcgfx
- * @{
- */
-/**
- * @file GFX IPC server
- *
- * Serve a graphics context via HelenOS IPC.
- */
-
-#include <as.h>
-#include <errno.h>
-#include <gfx/bitmap.h>
-#include <gfx/color.h>
-#include <gfx/render.h>
-#include <ipc/bd.h>
-#include <ipcgfx/ipc/gc.h>
-#include <ipcgfx/server.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "../private/server.h"
-
-static ipc_gc_srv_bitmap_t *gc_bitmap_lookup(ipc_gc_srv_t *, sysarg_t);
-
-static void gc_set_rgb_color_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
-{
-	uint16_t r, g, b;
-	gfx_color_t *color;
-	errno_t rc;
-
-	r = ipc_get_arg1(call);
-	g = ipc_get_arg2(call);
-	b = ipc_get_arg3(call);
-
-	rc = gfx_color_new_rgb_i16(r, g, b, &color);
-	if (rc != EOK) {
-		async_answer_0(call, ENOMEM);
-		return;
-	}
-
-	rc = gfx_set_color(srvgc->gc, color);
-	async_answer_0(call, rc);
-}
-
-static void gc_fill_rect_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
-{
-	gfx_rect_t rect;
-	errno_t rc;
-
-	rect.p0.x = ipc_get_arg1(call);
-	rect.p0.y = ipc_get_arg2(call);
-	rect.p1.x = ipc_get_arg3(call);
-	rect.p1.y = ipc_get_arg4(call);
-
-	rc = gfx_fill_rect(srvgc->gc, &rect);
-	async_answer_0(call, rc);
-}
-
-static void gc_bitmap_create_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
-{
-	gfx_bitmap_params_t params;
-	gfx_bitmap_alloc_t alloc;
-	gfx_bitmap_t *bitmap;
-	gfx_coord2_t dim;
-	ipc_gc_srv_bitmap_t *srvbmp = NULL;
-	ipc_call_t call;
-	size_t size;
-	unsigned int flags;
-	void *pixels;
-	errno_t rc;
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(gfx_bitmap_params_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &params, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	/* Bitmap dimensions */
-	gfx_coord2_subtract(&params.rect.p1, &params.rect.p0, &dim);
-
-	if (!async_share_out_receive(&call, &size, &flags)) {
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	/* Check size */
-	if (size != PAGES2SIZE(SIZE2PAGES(dim.x * dim.y * sizeof(uint32_t)))) {
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_share_out_finalize(&call, &pixels);
-	if (rc != EOK || pixels == AS_MAP_FAILED) {
-		async_answer_0(icall, ENOMEM);
-		return;
-	}
-
-	alloc.pitch = dim.x * sizeof(uint32_t);
-	alloc.off0 = 0;
-	alloc.pixels = pixels;
-
-	srvbmp = calloc(1, sizeof(ipc_gc_srv_bitmap_t));
-	if (srvbmp == NULL) {
-		as_area_destroy(pixels);
-		async_answer_0(icall, ENOMEM);
-		return;
-	}
-
-	rc = gfx_bitmap_create(srvgc->gc, &params, &alloc, &bitmap);
-	if (rc != EOK) {
-		free(srvbmp);
-		as_area_destroy(pixels);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	srvbmp->srvgc = srvgc;
-	list_append(&srvbmp->lbitmaps, &srvgc->bitmaps);
-	srvbmp->bmp = bitmap;
-	srvbmp->bmp_id = srvgc->next_bmp_id++;
-
-	/* We created the memory area by sharing it in */
-	srvbmp->myalloc = true;
-	srvbmp->pixels = pixels;
-
-	async_answer_1(icall, EOK, srvbmp->bmp_id);
-}
-
-static void gc_bitmap_create_doutput_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
-{
-	gfx_bitmap_params_t params;
-	gfx_bitmap_alloc_t alloc;
-	gfx_bitmap_t *bitmap;
-	gfx_coord2_t dim;
-	ipc_gc_srv_bitmap_t *srvbmp = NULL;
-	ipc_call_t call;
-	size_t size;
-	errno_t rc;
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(gfx_bitmap_params_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &params, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	/* Bitmap dimensions */
-	gfx_coord2_subtract(&params.rect.p1, &params.rect.p0, &dim);
-
-	if (!async_share_in_receive(&call, &size)) {
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	/* Check size */
-	if (size != PAGES2SIZE(SIZE2PAGES(dim.x * dim.y * sizeof(uint32_t)))) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = gfx_bitmap_create(srvgc->gc, &params, NULL, &bitmap);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	if (rc != EOK) {
-		gfx_bitmap_destroy(bitmap);
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	rc = async_share_in_finalize(&call, alloc.pixels, AS_AREA_READ |
-	    AS_AREA_WRITE | AS_AREA_CACHEABLE);
-	if (rc != EOK) {
-		gfx_bitmap_destroy(bitmap);
-		async_answer_0(icall, EIO);
-		return;
-	}
-
-	srvbmp = calloc(1, sizeof(ipc_gc_srv_bitmap_t));
-	if (srvbmp == NULL) {
-		gfx_bitmap_destroy(bitmap);
-		async_answer_0(icall, ENOMEM);
-		return;
-	}
-
-	srvbmp->srvgc = srvgc;
-	list_append(&srvbmp->lbitmaps, &srvgc->bitmaps);
-	srvbmp->bmp = bitmap;
-	srvbmp->bmp_id = srvgc->next_bmp_id++;
-
-	/* Area allocated by backing GC, we just shared it out */
-	srvbmp->myalloc = false;
-	srvbmp->pixels = alloc.pixels; // Not really needed
-
-	async_answer_1(icall, EOK, srvbmp->bmp_id);
-}
-
-static void gc_bitmap_destroy_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
-{
-	sysarg_t bmp_id;
-	ipc_gc_srv_bitmap_t *bitmap;
-	errno_t rc;
-
-	bmp_id = ipc_get_arg1(call);
-
-	bitmap = gc_bitmap_lookup(srvgc, bmp_id);
-	if (bitmap == NULL) {
-		async_answer_0(call, ENOENT);
-		return;
-	}
-
-	rc = gfx_bitmap_destroy(bitmap->bmp);
-	if (rc != EOK) {
-		async_answer_0(call, rc);
-		return;
-	}
-
-	if (bitmap->myalloc)
-		as_area_destroy(bitmap->pixels);
-
-	list_remove(&bitmap->lbitmaps);
-	free(bitmap);
-
-	async_answer_0(call, rc);
-}
-
-static void gc_bitmap_render_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
-{
-	ipc_gc_srv_bitmap_t *bitmap;
-	sysarg_t bmp_id;
-	gfx_rect_t srect;
-	gfx_coord2_t offs;
-	ipc_call_t call;
-	size_t size;
-	errno_t rc;
-
-	if (!async_data_write_receive(&call, &size)) {
-		async_answer_0(&call, EREFUSED);
-		async_answer_0(icall, EREFUSED);
-		return;
-	}
-
-	if (size != sizeof(gfx_rect_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &srect, size);
-	if (rc != EOK) {
-		async_answer_0(&call, rc);
-		async_answer_0(icall, rc);
-		return;
-	}
-
-	bmp_id = ipc_get_arg1(icall);
-	offs.x = ipc_get_arg2(icall);
-	offs.y = ipc_get_arg3(icall);
-
-	bitmap = gc_bitmap_lookup(srvgc, bmp_id);
-	if (bitmap == NULL) {
-		async_answer_0(icall, ENOENT);
-		return;
-	}
-
-	rc = gfx_bitmap_render(bitmap->bmp, &srect, &offs);
-	async_answer_0(icall, rc);
-}
-
-errno_t gc_conn(ipc_call_t *icall, gfx_context_t *gc)
-{
-	ipc_gc_srv_t srvgc;
-
-	/* Accept the connection */
-	async_accept_0(icall);
-
-	srvgc.gc = gc;
-	list_initialize(&srvgc.bitmaps);
-	srvgc.next_bmp_id = 1;
-
-	while (true) {
-		ipc_call_t call;
-		async_get_call(&call);
-		sysarg_t method = ipc_get_imethod(&call);
-
-		if (!method) {
-			/* The other side has hung up */
-			async_answer_0(&call, EOK);
-			break;
-		}
-
-		switch (method) {
-		case GC_SET_RGB_COLOR:
-			gc_set_rgb_color_srv(&srvgc, &call);
-			break;
-		case GC_FILL_RECT:
-			gc_fill_rect_srv(&srvgc, &call);
-			break;
-		case GC_BITMAP_CREATE:
-			gc_bitmap_create_srv(&srvgc, &call);
-			break;
-		case GC_BITMAP_CREATE_DOUTPUT:
-			gc_bitmap_create_doutput_srv(&srvgc, &call);
-			break;
-		case GC_BITMAP_DESTROY:
-			gc_bitmap_destroy_srv(&srvgc, &call);
-			break;
-		case GC_BITMAP_RENDER:
-			gc_bitmap_render_srv(&srvgc, &call);
-			break;
-		default:
-			async_answer_0(&call, EINVAL);
-			break;
-		}
-	}
-
-	// TODO: Destroy all remaining bitmaps (+ emit warning?)
-	return EOK;
-}
-
-static ipc_gc_srv_bitmap_t *gc_bitmap_lookup(ipc_gc_srv_t *srvgc,
-    sysarg_t bmp_id)
-{
-	link_t *link;
-	ipc_gc_srv_bitmap_t *bmp;
-
-	link = list_first(&srvgc->bitmaps);
-	while (link != NULL) {
-		bmp = list_get_instance(link, ipc_gc_srv_bitmap_t, lbitmaps);
-		if (bmp->bmp_id == bmp_id)
-			return bmp;
-		link = list_next(link, &srvgc->bitmaps);
-	}
-
-	return NULL;
-}
-
-/** @}
- */
Index: pace/lib/ipcgfx/test/ipcgfx.c
===================================================================
--- uspace/lib/ipcgfx/test/ipcgfx.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,948 +1,0 @@
-/*
- * Copyright (c) 2019 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 <as.h>
-#include <async.h>
-#include <errno.h>
-#include <gfx/bitmap.h>
-#include <gfx/color.h>
-#include <gfx/coord.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <ipcgfx/client.h>
-#include <ipcgfx/server.h>
-#include <loc.h>
-#include <pcut/pcut.h>
-#include <stdint.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(ipcgfx);
-
-static const char *test_ipcgfx_server = "test-ipcgfx";
-static const char *test_ipcgfx_svc = "test/ipcgfx";
-
-static void test_ipcgc_conn(ipc_call_t *, void *);
-
-static errno_t test_gc_set_color(void *, gfx_color_t *);
-static errno_t test_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t test_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t test_gc_bitmap_destroy(void *);
-static errno_t test_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t test_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static gfx_context_ops_t test_gc_ops = {
-	.set_color = test_gc_set_color,
-	.fill_rect = test_gc_fill_rect,
-	.bitmap_create = test_gc_bitmap_create,
-	.bitmap_destroy = test_gc_bitmap_destroy,
-	.bitmap_render = test_gc_bitmap_render,
-	.bitmap_get_alloc = test_gc_bitmap_get_alloc
-};
-
-/** Describes to the server how to respond to our request and pass tracking
- * data back to the client.
- */
-typedef struct {
-	errno_t rc;
-
-	bool set_color_called;
-	uint16_t set_color_r;
-	uint16_t set_color_g;
-	uint16_t set_color_b;
-
-	bool fill_rect_called;
-	gfx_rect_t fill_rect_rect;
-
-	bool bitmap_create_called;
-	gfx_bitmap_params_t bitmap_create_params;
-	gfx_bitmap_alloc_t bitmap_create_alloc;
-
-	bool bitmap_destroy_called;
-
-	bool bitmap_render_called;
-	gfx_rect_t bitmap_render_srect;
-	gfx_coord2_t bitmap_render_offs;
-
-	bool bitmap_get_alloc_called;
-} test_response_t;
-
-/** Bitmap in test GC */
-typedef struct {
-	test_response_t *resp;
-	gfx_bitmap_alloc_t alloc;
-} test_bitmap_t;
-
-/** gfx_set_color with server returning failure */
-PCUT_TEST(set_color_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_color_t *color;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	rc = gfx_color_new_rgb_i16(1, 2, 3, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	resp.rc = ENOMEM;
-	resp.set_color_called = false;
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_TRUE(resp.set_color_called);
-	PCUT_ASSERT_EQUALS(1, resp.set_color_r);
-	PCUT_ASSERT_EQUALS(2, resp.set_color_g);
-	PCUT_ASSERT_EQUALS(3, resp.set_color_b);
-
-	gfx_color_delete(color);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_set_color with server returning success */
-PCUT_TEST(set_color_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_color_t *color;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	rc = gfx_color_new_rgb_i16(1, 2, 3, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	resp.rc = EOK;
-	resp.set_color_called = false;
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.set_color_called);
-	PCUT_ASSERT_EQUALS(1, resp.set_color_r);
-	PCUT_ASSERT_EQUALS(2, resp.set_color_g);
-	PCUT_ASSERT_EQUALS(3, resp.set_color_b);
-
-	gfx_color_delete(color);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_fill_rect with server returning failure */
-PCUT_TEST(fill_rect_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_rect_t rect;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = ENOMEM;
-	resp.set_color_called = false;
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-	rc = gfx_fill_rect(gc, &rect);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_TRUE(resp.fill_rect_called);
-	PCUT_ASSERT_EQUALS(rect.p0.x, resp.fill_rect_rect.p0.x);
-	PCUT_ASSERT_EQUALS(rect.p0.y, resp.fill_rect_rect.p0.y);
-	PCUT_ASSERT_EQUALS(rect.p1.x, resp.fill_rect_rect.p1.x);
-	PCUT_ASSERT_EQUALS(rect.p1.y, resp.fill_rect_rect.p1.y);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_fill_rect with server returning success */
-PCUT_TEST(fill_rect_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_rect_t rect;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	resp.set_color_called = false;
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-	rc = gfx_fill_rect(gc, &rect);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.fill_rect_called);
-	PCUT_ASSERT_EQUALS(rect.p0.x, resp.fill_rect_rect.p0.x);
-	PCUT_ASSERT_EQUALS(rect.p0.y, resp.fill_rect_rect.p0.y);
-	PCUT_ASSERT_EQUALS(rect.p1.x, resp.fill_rect_rect.p1.x);
-	PCUT_ASSERT_EQUALS(rect.p1.y, resp.fill_rect_rect.p1.y);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_create with server returning failure */
-PCUT_TEST(bitmap_create_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = ENOMEM;
-	resp.bitmap_create_called = false;
-
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	bitmap = NULL;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.bitmap_create_params.rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.bitmap_create_params.rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.bitmap_create_params.rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.bitmap_create_params.rect.p1.y);
-	PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
-	    sizeof(uint32_t), (unsigned) resp.bitmap_create_alloc.pitch);
-	PCUT_ASSERT_EQUALS(0, resp.bitmap_create_alloc.off0);
-	PCUT_ASSERT_NOT_NULL(resp.bitmap_create_alloc.pixels);
-	PCUT_ASSERT_NULL(bitmap);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_create and gfx_bitmap_destroy with server returning success */
-PCUT_TEST(bitmap_create_destroy_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	resp.bitmap_create_called = false;
-
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	bitmap = NULL;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.bitmap_create_params.rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.bitmap_create_params.rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.bitmap_create_params.rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.bitmap_create_params.rect.p1.y);
-	PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
-	    sizeof(uint32_t), (unsigned) resp.bitmap_create_alloc.pitch);
-	PCUT_ASSERT_EQUALS(0, resp.bitmap_create_alloc.off0);
-	PCUT_ASSERT_NOT_NULL(resp.bitmap_create_alloc.pixels);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-
-	resp.bitmap_destroy_called = false;
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_destroy_called);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_destroy with server returning failure */
-PCUT_TEST(bitmap_destroy_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-
-	resp.rc = EIO;
-	resp.bitmap_destroy_called = false;
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_destroy_called);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_create direct output bitmap with server returning failure */
-PCUT_TEST(bitmap_create_dout_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = ENOMEM;
-	resp.bitmap_create_called = false;
-
-	gfx_bitmap_params_init(&params);
-	params.flags = bmpf_direct_output;
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	bitmap = NULL;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.bitmap_create_params.rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.bitmap_create_params.rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.bitmap_create_params.rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.bitmap_create_params.rect.p1.y);
-	PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
-	    sizeof(uint32_t), (unsigned) resp.bitmap_create_alloc.pitch);
-	PCUT_ASSERT_EQUALS(0, resp.bitmap_create_alloc.off0);
-	PCUT_ASSERT_NOT_NULL(resp.bitmap_create_alloc.pixels);
-	PCUT_ASSERT_NULL(bitmap);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_create direct output bitmap with server returning success */
-PCUT_TEST(bitmap_create_dout_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	resp.bitmap_create_called = false;
-
-	gfx_bitmap_params_init(&params);
-	params.flags = bmpf_direct_output;
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	bitmap = NULL;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_create_called);
-	PCUT_ASSERT_EQUALS(params.rect.p0.x, resp.bitmap_create_params.rect.p0.x);
-	PCUT_ASSERT_EQUALS(params.rect.p0.y, resp.bitmap_create_params.rect.p0.y);
-	PCUT_ASSERT_EQUALS(params.rect.p1.x, resp.bitmap_create_params.rect.p1.x);
-	PCUT_ASSERT_EQUALS(params.rect.p1.y, resp.bitmap_create_params.rect.p1.y);
-	PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
-	    sizeof(uint32_t), (unsigned) resp.bitmap_create_alloc.pitch);
-	PCUT_ASSERT_EQUALS(0, resp.bitmap_create_alloc.off0);
-	PCUT_ASSERT_NOT_NULL(resp.bitmap_create_alloc.pixels);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-
-	resp.bitmap_destroy_called = false;
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_destroy_called);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_render with server returning failure */
-PCUT_TEST(bitmap_render_failure)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_rect_t srect;
-	gfx_coord2_t offs;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-
-	resp.rc = EIO;
-	srect.p0.x = 1;
-	srect.p0.y = 2;
-	srect.p1.x = 3;
-	srect.p1.y = 4;
-	rc = gfx_bitmap_render(bitmap, &srect, &offs);
-	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_render_called);
-	PCUT_ASSERT_EQUALS(srect.p0.x, resp.bitmap_render_srect.p0.x);
-	PCUT_ASSERT_EQUALS(srect.p0.y, resp.bitmap_render_srect.p0.y);
-	PCUT_ASSERT_EQUALS(srect.p1.x, resp.bitmap_render_srect.p1.x);
-	PCUT_ASSERT_EQUALS(srect.p1.y, resp.bitmap_render_srect.p1.y);
-	PCUT_ASSERT_EQUALS(offs.x, resp.bitmap_render_offs.x);
-	PCUT_ASSERT_EQUALS(offs.y, resp.bitmap_render_offs.y);
-
-	resp.rc = EOK;
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_render with server returning success */
-PCUT_TEST(bitmap_render_success)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_rect_t srect;
-	gfx_coord2_t offs;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-
-	resp.rc = EOK;
-	srect.p0.x = 1;
-	srect.p0.y = 2;
-	srect.p1.x = 3;
-	srect.p1.y = 4;
-	rc = gfx_bitmap_render(bitmap, &srect, &offs);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(resp.bitmap_render_called);
-	PCUT_ASSERT_EQUALS(srect.p0.x, resp.bitmap_render_srect.p0.x);
-	PCUT_ASSERT_EQUALS(srect.p0.y, resp.bitmap_render_srect.p0.y);
-	PCUT_ASSERT_EQUALS(srect.p1.x, resp.bitmap_render_srect.p1.x);
-	PCUT_ASSERT_EQUALS(srect.p1.y, resp.bitmap_render_srect.p1.y);
-	PCUT_ASSERT_EQUALS(offs.x, resp.bitmap_render_offs.x);
-	PCUT_ASSERT_EQUALS(offs.y, resp.bitmap_render_offs.y);
-
-	resp.rc = EOK;
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** gfx_bitmap_get_alloc - server is not currently involved */
-PCUT_TEST(bitmap_get_alloc)
-{
-	errno_t rc;
-	service_id_t sid;
-	test_response_t resp;
-	gfx_context_t *gc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_alloc_t alloc;
-	async_sess_t *sess;
-	ipc_gc_t *ipcgc;
-
-	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
-
-	// FIXME This causes this test to be non-reentrant!
-	rc = loc_server_register(test_ipcgfx_server);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = loc_service_register(test_ipcgfx_svc, &sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	sess = loc_service_connect(sid, INTERFACE_GC, 0);
-	PCUT_ASSERT_NOT_NULL(sess);
-
-	rc = ipc_gc_create(sess, &ipcgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ipc_gc_get_ctx(ipcgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	resp.rc = EOK;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_NOT_NULL(bitmap);
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_EQUALS((params.rect.p1.x - params.rect.p0.x) *
-	    sizeof(uint32_t), (unsigned) alloc.pitch);
-	PCUT_ASSERT_EQUALS(0, alloc.off0);
-	PCUT_ASSERT_NOT_NULL(alloc.pixels);
-
-	resp.rc = EOK;
-	rc = gfx_bitmap_destroy(bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ipc_gc_delete(ipcgc);
-	async_hangup(sess);
-
-	rc = loc_service_unregister(sid);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-static void test_ipcgc_conn(ipc_call_t *icall, void *arg)
-{
-	gfx_context_t *gc;
-	errno_t rc;
-
-	rc = gfx_context_new(&test_gc_ops, arg, &gc);
-	if (rc != EOK) {
-		async_answer_0(icall, ENOMEM);
-		return;
-	}
-
-	/* Window GC connection */
-	gc_conn(icall, gc);
-}
-
-/** Set color in test GC.
- *
- * Set drawing color in test GC.
- *
- * @param arg Test GC
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t test_gc_set_color(void *arg, gfx_color_t *color)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->set_color_called = true;
-	gfx_color_get_rgb_i16(color, &resp->set_color_r, &resp->set_color_g,
-	    &resp->set_color_b);
-	return resp->rc;
-}
-
-/** Fill rectangle in test GC.
- *
- * @param arg Test GC
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t test_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	test_response_t *resp = (test_response_t *) arg;
-
-	resp->fill_rect_called = true;
-	resp->fill_rect_rect = *rect;
-	return resp->rc;
-}
-
-/** Create bitmap in test GC.
- *
- * @param arg Test GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t test_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	test_response_t *resp = (test_response_t *) arg;
-	test_bitmap_t *bitmap;
-	gfx_coord2_t dim;
-
-	resp->bitmap_create_called = true;
-	resp->bitmap_create_params = *params;
-
-	if ((params->flags & bmpf_direct_output) != 0) {
-		gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-
-		resp->bitmap_create_alloc.pitch = dim.x * sizeof(uint32_t);
-		resp->bitmap_create_alloc.off0 = 0;
-		resp->bitmap_create_alloc.pixels = as_area_create(AS_AREA_ANY,
-		    dim.x * dim.y * sizeof(uint32_t), AS_AREA_READ |
-		    AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
-		if (resp->bitmap_create_alloc.pixels == AS_MAP_FAILED)
-			return ENOMEM;
-	} else {
-		resp->bitmap_create_alloc = *alloc;
-	}
-
-	if (resp->rc != EOK)
-		return resp->rc;
-
-	bitmap = calloc(1, sizeof(test_bitmap_t));
-	if (bitmap == NULL)
-		return ENOMEM;
-
-	bitmap->resp = resp;
-	bitmap->alloc = resp->bitmap_create_alloc;
-	*rbm = (void *) bitmap;
-	return EOK;
-}
-
-/** Destroy bitmap in test GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t test_gc_bitmap_destroy(void *bm)
-{
-	test_bitmap_t *bitmap = (test_bitmap_t *) bm;
-	test_response_t *resp = bitmap->resp;
-
-	resp->bitmap_destroy_called = true;
-	if (resp->rc != EOK)
-		return resp->rc;
-
-	if ((resp->bitmap_create_params.flags & bmpf_direct_output) != 0)
-		as_area_destroy(resp->bitmap_create_alloc.pixels);
-
-	free(bitmap);
-	return EOK;
-}
-
-/** Render bitmap in test GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t test_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	test_bitmap_t *bitmap = (test_bitmap_t *) bm;
-	test_response_t *resp = bitmap->resp;
-
-	resp->bitmap_render_called = true;
-	resp->bitmap_render_srect = *srect0;
-	resp->bitmap_render_offs = *offs0;
-	return resp->rc;
-}
-
-/** Get allocation info for bitmap in test GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t test_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	test_bitmap_t *bitmap = (test_bitmap_t *) bm;
-
-	*alloc = bitmap->alloc;
-	return EOK;
-}
-
-PCUT_EXPORT(ipcgfx);
Index: pace/lib/ipcgfx/test/main.c
===================================================================
--- uspace/lib/ipcgfx/test/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,35 +1,0 @@
-/*
- * Copyright (c) 2019 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 <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_IMPORT(ipcgfx);
-
-PCUT_MAIN();
Index: pace/lib/memgfx/doc/doxygroups.h
===================================================================
--- uspace/lib/memgfx/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup libmemgfx libmemgfx
- * @ingroup libs
- */
Index: pace/lib/memgfx/include/memgfx/memgc.h
===================================================================
--- uspace/lib/memgfx/include/memgfx/memgc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2020 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 libmemgfx
- * @{
- */
-/**
- * @file GFX memory backend
- */
-
-#ifndef _MEMGFX_MEMGC_H
-#define _MEMGFX_MEMGC_H
-
-#include <errno.h>
-#include <types/gfx/bitmap.h>
-#include <types/gfx/context.h>
-#include <types/gfx/ops/context.h>
-#include <types/memgfx/memgc.h>
-
-extern gfx_context_ops_t mem_gc_ops;
-
-extern errno_t mem_gc_create(gfx_rect_t *, gfx_bitmap_alloc_t *,
-    mem_gc_update_cb_t, void *, mem_gc_t **);
-extern errno_t mem_gc_delete(mem_gc_t *);
-extern void mem_gc_retarget(mem_gc_t *, gfx_rect_t *, gfx_bitmap_alloc_t *);
-extern gfx_context_t *mem_gc_get_ctx(mem_gc_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/memgfx/include/types/memgfx/memgc.h
===================================================================
--- uspace/lib/memgfx/include/types/memgfx/memgc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2020 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 libmemgfx
- * @{
- */
-/**
- * @file GFX memory backend
- */
-
-#ifndef _MEMGFX_TYPES_MEMGC_H
-#define _MEMGFX_TYPES_MEMGC_H
-
-#include <types/gfx/coord.h>
-
-struct mem_gc;
-typedef struct mem_gc mem_gc_t;
-
-typedef void (*mem_gc_update_cb_t)(void *, gfx_rect_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/memgfx/meson.build
===================================================================
--- uspace/lib/memgfx/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#
-# Copyright (c) 2020 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.
-#
-
-deps = [ 'gfx' ]
-src = files(
-	'src/memgc.c'
-)
-
-test_src = files(
-	'test/main.c',
-	'test/memgfx.c',
-)
Index: pace/lib/memgfx/private/memgc.h
===================================================================
--- uspace/lib/memgfx/private/memgc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,80 +1,0 @@
-/*
- * Copyright (c) 2020 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 libguigfx
- * @{
- */
-/**
- * @file GFX memory backend structure
- *
- */
-
-#ifndef _MEMGFX_PRIVATE_MEMGC_H
-#define _MEMGFX_PRIVATE_MEMGC_H
-
-#include <gfx/bitmap.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <io/pixel.h>
-
-/** Actual structure of memory GC. */
-struct mem_gc {
-	/** Base graphic context */
-	gfx_context_t *gc;
-	/** Bounding rectangle */
-	gfx_rect_t rect;
-	/** Allocation info */
-	gfx_bitmap_alloc_t alloc;
-	/** Update callback */
-	mem_gc_update_cb_t update;
-	/** Argument to callback */
-	void *cb_arg;
-	/** Current drawing color */
-	pixel_t color;
-};
-
-/** Bitmap in memory GC */
-typedef struct {
-	/** Containing canvas GC */
-	struct mem_gc *mgc;
-	/** Allocation info */
-	gfx_bitmap_alloc_t alloc;
-	/** @c true if we allocated the bitmap, @c false if allocated by caller */
-	bool myalloc;
-	/** Rectangle covered by bitmap */
-	gfx_rect_t rect;
-	/** Bitmap flags */
-	gfx_bitmap_flags_t flags;
-	/** Key color */
-	pixel_t key_color;
-} mem_gc_bitmap_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/memgfx/src/memgc.c
===================================================================
--- uspace/lib/memgfx/src/memgc.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,407 +1,0 @@
-/*
- * Copyright (c) 2020 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 libmemgfx
- * @{
- */
-/**
- * @file GFX memory backend
- *
- * This implements a graphics context over a block of memory (i.e. a simple
- * software renderer).
- */
-
-#include <as.h>
-#include <assert.h>
-#include <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <io/pixel.h>
-#include <io/pixelmap.h>
-#include <memgfx/memgc.h>
-#include <stdlib.h>
-#include "../private/memgc.h"
-
-static errno_t mem_gc_set_color(void *, gfx_color_t *);
-static errno_t mem_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t mem_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t mem_gc_bitmap_destroy(void *);
-static errno_t mem_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t mem_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-static void mem_gc_invalidate_rect(mem_gc_t *, gfx_rect_t *);
-
-gfx_context_ops_t mem_gc_ops = {
-	.set_color = mem_gc_set_color,
-	.fill_rect = mem_gc_fill_rect,
-	.bitmap_create = mem_gc_bitmap_create,
-	.bitmap_destroy = mem_gc_bitmap_destroy,
-	.bitmap_render = mem_gc_bitmap_render,
-	.bitmap_get_alloc = mem_gc_bitmap_get_alloc
-};
-
-/** Set color on memory GC.
- *
- * Set drawing color on memory GC.
- *
- * @param arg Memory GC
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t mem_gc_set_color(void *arg, gfx_color_t *color)
-{
-	mem_gc_t *mgc = (mem_gc_t *) arg;
-	uint16_t r, g, b;
-
-	gfx_color_get_rgb_i16(color, &r, &g, &b);
-	mgc->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
-	return EOK;
-}
-
-/** Fill rectangle on memory GC.
- *
- * @param arg Memory GC
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t mem_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	mem_gc_t *mgc = (mem_gc_t *) arg;
-	gfx_rect_t crect;
-	gfx_coord_t x, y;
-	pixelmap_t pixelmap;
-
-	/* Make sure we have a sorted, clipped rectangle */
-	gfx_rect_clip(rect, &mgc->rect, &crect);
-
-	assert(mgc->rect.p0.x == 0);
-	assert(mgc->rect.p0.y == 0);
-	assert(mgc->alloc.pitch == mgc->rect.p1.x * (int)sizeof(uint32_t));
-	pixelmap.width = mgc->rect.p1.x;
-	pixelmap.height = mgc->rect.p1.y;
-	pixelmap.data = mgc->alloc.pixels;
-
-	for (y = crect.p0.y; y < crect.p1.y; y++) {
-		for (x = crect.p0.x; x < crect.p1.x; x++) {
-			pixelmap_put_pixel(&pixelmap, x, y, mgc->color);
-		}
-	}
-
-	mem_gc_invalidate_rect(mgc, &crect);
-	return EOK;
-}
-
-/** Create memory GC.
- *
- * Create graphics context for rendering into a block of memory.
- *
- * @param rect Bounding rectangle
- * @param alloc Allocation info
- * @param update_cb Function called to update a rectangle
- * @param cb_arg Argument to callback function
- * @param rgc Place to store pointer to new memory GC
- *
- * @return EOK on success or an error code
- */
-errno_t mem_gc_create(gfx_rect_t *rect, gfx_bitmap_alloc_t *alloc,
-    mem_gc_update_cb_t update_cb, void *cb_arg, mem_gc_t **rgc)
-{
-	mem_gc_t *mgc = NULL;
-	gfx_context_t *gc = NULL;
-	errno_t rc;
-
-	mgc = calloc(1, sizeof(mem_gc_t));
-	if (mgc == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rc = gfx_context_new(&mem_gc_ops, mgc, &gc);
-	if (rc != EOK)
-		goto error;
-
-	mgc->gc = gc;
-	mgc->rect = *rect;
-	mgc->alloc = *alloc;
-
-	mgc->update = update_cb;
-	mgc->cb_arg = cb_arg;
-
-	*rgc = mgc;
-	return EOK;
-error:
-	if (mgc != NULL)
-		free(mgc);
-	gfx_context_delete(gc);
-	return rc;
-}
-
-/** Delete memory GC.
- *
- * @param mgc Memory GC
- */
-errno_t mem_gc_delete(mem_gc_t *mgc)
-{
-	errno_t rc;
-
-	rc = gfx_context_delete(mgc->gc);
-	if (rc != EOK)
-		return rc;
-
-	free(mgc);
-	return EOK;
-}
-
-/** Retarget memory GC to a different block of memory.
- *
- * @param mgc Memory GC
- * @param rect New bounding rectangle
- * @param alloc Allocation info of the new block
- */
-void mem_gc_retarget(mem_gc_t *mgc, gfx_rect_t *rect,
-    gfx_bitmap_alloc_t *alloc)
-{
-	mgc->rect = *rect;
-	mgc->alloc = *alloc;
-}
-
-/** Get generic graphic context from memory GC.
- *
- * @param mgc Memory GC
- * @return Graphic context
- */
-gfx_context_t *mem_gc_get_ctx(mem_gc_t *mgc)
-{
-	return mgc->gc;
-}
-
-static void mem_gc_invalidate_rect(mem_gc_t *mgc, gfx_rect_t *rect)
-{
-	mgc->update(mgc->cb_arg, rect);
-}
-
-/** Create bitmap in memory GC.
- *
- * @param arg Memory GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t mem_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	mem_gc_t *mgc = (mem_gc_t *) arg;
-	mem_gc_bitmap_t *mbm = NULL;
-	gfx_coord2_t dim;
-	errno_t rc;
-
-	/* Check that we support all requested flags */
-	if ((params->flags & ~(bmpf_color_key | bmpf_direct_output)) != 0)
-		return ENOTSUP;
-
-	mbm = calloc(1, sizeof(mem_gc_bitmap_t));
-	if (mbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	mbm->rect = params->rect;
-	mbm->flags = params->flags;
-	mbm->key_color = params->key_color;
-
-	if ((params->flags & bmpf_direct_output) != 0) {
-		/* Caller cannot specify allocation for direct output */
-		if (alloc != NULL) {
-			rc = EINVAL;
-			goto error;
-		}
-
-		/* Bounding rectangle must be within GC bounding rectangle */
-		if (!gfx_rect_is_inside(&mbm->rect, &mgc->rect)) {
-			rc = EINVAL;
-			goto error;
-		}
-
-		mbm->alloc = mgc->alloc;
-
-		/* Don't free pixel array when destroying bitmap */
-		mbm->myalloc = false;
-	} else if (alloc == NULL) {
-#if 0
-		/*
-		 * TODO: If the bitmap is not required to be sharable,
-		 * we could allocate it with a simple malloc.
-		 * Need to have a bitmap flag specifying that the
-		 * allocation should be sharable. IPC GC could
-		 * automatically add this flag
-		 */
-		mbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		mbm->alloc.off0 = 0;
-		mbm->alloc.pixels = malloc(mbm->alloc.pitch * dim.y);
-		mbm->myalloc = true;
-
-		if (mbm->alloc.pixels == NULL) {
-			rc = ENOMEM;
-			goto error;
-		}
-#endif
-		mbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		mbm->alloc.off0 = 0;
-		mbm->alloc.pixels = as_area_create(AS_AREA_ANY,
-		    dim.x * dim.y * sizeof(uint32_t), AS_AREA_READ |
-		    AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
-		mbm->myalloc = true;
-
-		if (mbm->alloc.pixels == AS_MAP_FAILED) {
-			rc = ENOMEM;
-			goto error;
-		}
-	} else {
-		mbm->alloc = *alloc;
-	}
-
-	mbm->mgc = mgc;
-	*rbm = (void *)mbm;
-	return EOK;
-error:
-	if (mbm != NULL)
-		free(mbm);
-	return rc;
-}
-
-/** Destroy bitmap in memory GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t mem_gc_bitmap_destroy(void *bm)
-{
-	mem_gc_bitmap_t *mbm = (mem_gc_bitmap_t *)bm;
-	if (mbm->myalloc) {
-#if 0
-		/* TODO: if we alloc allocating the bitmap with malloc */
-		free(mbm->alloc.pixels);
-#endif
-		as_area_destroy(mbm->alloc.pixels);
-	}
-
-	free(mbm);
-	return EOK;
-}
-
-/** Render bitmap in memory GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t mem_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	mem_gc_bitmap_t *mbm = (mem_gc_bitmap_t *)bm;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-	gfx_coord2_t offs;
-	gfx_coord_t x, y;
-	pixelmap_t smap;
-	pixelmap_t dmap;
-	pixel_t pixel;
-
-	if (srect0 != NULL)
-		gfx_rect_clip(srect0, &mbm->rect, &srect);
-	else
-		srect = mbm->rect;
-
-	if (offs0 != NULL) {
-		offs = *offs0;
-	} else {
-		offs.x = 0;
-		offs.y = 0;
-	}
-
-	/* Destination rectangle */
-	gfx_rect_translate(&offs, &srect, &drect);
-
-	assert(mbm->alloc.pitch == (mbm->rect.p1.x - mbm->rect.p0.x) *
-	    (int)sizeof(uint32_t));
-	smap.width = mbm->rect.p1.x - mbm->rect.p0.x;
-	smap.height = mbm->rect.p1.y - mbm->rect.p0.y;
-	smap.data = mbm->alloc.pixels;
-
-	assert(mbm->mgc->rect.p0.x == 0);
-	assert(mbm->mgc->rect.p0.y == 0);
-	assert(mbm->mgc->alloc.pitch == mbm->mgc->rect.p1.x * (int)sizeof(uint32_t));
-	dmap.width = mbm->mgc->rect.p1.x;
-	dmap.height = mbm->mgc->rect.p1.y;
-	dmap.data = mbm->mgc->alloc.pixels;
-
-	if ((mbm->flags & bmpf_direct_output) != 0) {
-		/* Nothing to do */
-	} else if ((mbm->flags & bmpf_color_key) == 0) {
-		for (y = drect.p0.y; y < drect.p1.y; y++) {
-			for (x = drect.p0.x; x < drect.p1.x; x++) {
-				pixel = pixelmap_get_pixel(&smap,
-				    x - mbm->rect.p0.x - offs.x,
-				    y - mbm->rect.p0.y - offs.y);
-				pixelmap_put_pixel(&dmap, x, y, pixel);
-			}
-		}
-	} else {
-		for (y = drect.p0.y; y < drect.p1.y; y++) {
-			for (x = drect.p0.x; x < drect.p1.x; x++) {
-				pixel = pixelmap_get_pixel(&smap,
-				    x - mbm->rect.p0.x - offs.x,
-				    y - mbm->rect.p0.y - offs.y);
-				if (pixel != mbm->key_color)
-					pixelmap_put_pixel(&dmap, x, y, pixel);
-			}
-		}
-	}
-
-	mem_gc_invalidate_rect(mbm->mgc, &drect);
-	return EOK;
-}
-
-/** Get allocation info for bitmap in memory GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t mem_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	mem_gc_bitmap_t *mbm = (mem_gc_bitmap_t *)bm;
-	*alloc = mbm->alloc;
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/memgfx/test/main.c
===================================================================
--- uspace/lib/memgfx/test/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,35 +1,0 @@
-/*
- * Copyright (c) 2020 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 <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_IMPORT(memgfx);
-
-PCUT_MAIN();
Index: pace/lib/memgfx/test/memgfx.c
===================================================================
--- uspace/lib/memgfx/test/memgfx.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,261 +1,0 @@
-/*
- * Copyright (c) 2020 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 <gfx/bitmap.h>
-#include <gfx/color.h>
-#include <gfx/coord.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <io/pixelmap.h>
-#include <mem.h>
-#include <memgfx/memgc.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(memgfx);
-
-static void test_update_rect(void *arg, gfx_rect_t *rect);
-
-typedef struct {
-	/** True if update was called */
-	bool update_called;
-	/** Update rectangle */
-	gfx_rect_t rect;
-} test_update_t;
-
-/** Test creating and deleting a memory GC */
-PCUT_TEST(create_delete)
-{
-	mem_gc_t *mgc;
-	gfx_rect_t rect;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	rect.p0.x = 0;
-	rect.p0.y = 0;
-	rect.p1.x = 10;
-	rect.p1.y = 10;
-
-	alloc.pitch = (rect.p1.x - rect.p0.x) * sizeof(uint32_t);
-	alloc.off0 = 0;
-	alloc.pixels = calloc(1, alloc.pitch * (rect.p1.y - rect.p0.y));
-	PCUT_ASSERT_NOT_NULL(alloc.pixels);
-
-	rc = mem_gc_create(&rect, &alloc, NULL, NULL, &mgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	mem_gc_delete(mgc);
-	free(alloc.pixels);
-}
-
-/** Test filling a rectangle in memory GC */
-PCUT_TEST(fill_rect)
-{
-	mem_gc_t *mgc;
-	gfx_rect_t rect;
-	gfx_rect_t frect;
-	gfx_bitmap_alloc_t alloc;
-	gfx_context_t *gc;
-	gfx_color_t *color;
-	gfx_coord2_t pos;
-	pixelmap_t pixelmap;
-	pixel_t pixel;
-	pixel_t expected;
-	test_update_t update;
-	errno_t rc;
-
-	/* Bounding rectangle for memory GC */
-	rect.p0.x = 0;
-	rect.p0.y = 0;
-	rect.p1.x = 10;
-	rect.p1.y = 10;
-
-	alloc.pitch = (rect.p1.x - rect.p0.x) * sizeof(uint32_t);
-	alloc.off0 = 0;
-	alloc.pixels = calloc(1, alloc.pitch * (rect.p1.y - rect.p0.y));
-	PCUT_ASSERT_NOT_NULL(alloc.pixels);
-
-	rc = mem_gc_create(&rect, &alloc, test_update_rect, &update, &mgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = mem_gc_get_ctx(mgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Fill a rectangle */
-
-	rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	frect.p0.x = 2;
-	frect.p0.y = 2;
-	frect.p1.x = 5;
-	frect.p1.y = 5;
-
-	memset(&update, 0, sizeof(update));
-
-	rc = gfx_fill_rect(gc, &frect);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	pixelmap.width = rect.p1.x - rect.p0.x;
-	pixelmap.height = rect.p1.y - rect.p0.y;
-	pixelmap.data = alloc.pixels;
-
-	/* Check that the pixels of the rectangle are set and no others are */
-	for (pos.y = rect.p0.y; pos.y < rect.p1.y; pos.y++) {
-		for (pos.x = rect.p0.x; pos.x < rect.p1.x; pos.x++) {
-			pixel = pixelmap_get_pixel(&pixelmap, pos.x, pos.y);
-			expected = gfx_pix_inside_rect(&pos, &frect) ?
-			    PIXEL(0, 255, 255, 0) : PIXEL(0, 0, 0, 0);
-			PCUT_ASSERT_INT_EQUALS(expected, pixel);
-		}
-	}
-
-	/* Check that the update rect is equal to the filled rect */
-	PCUT_ASSERT_TRUE(update.update_called);
-	PCUT_ASSERT_INT_EQUALS(frect.p0.x, update.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(frect.p0.y, update.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(frect.p1.x, update.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(frect.p1.y, update.rect.p1.y);
-
-	/* TODO: Check clipping once memgc can support pitch != width etc. */
-
-	mem_gc_delete(mgc);
-	free(alloc.pixels);
-}
-
-/** Test rendering a bitmap in memory GC */
-PCUT_TEST(bitmap_render)
-{
-	mem_gc_t *mgc;
-	gfx_rect_t rect;
-	gfx_bitmap_alloc_t alloc;
-	gfx_context_t *gc;
-	gfx_coord2_t pos;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_alloc_t balloc;
-	gfx_bitmap_t *bitmap;
-	pixelmap_t bpmap;
-	pixelmap_t dpmap;
-	pixel_t pixel;
-	pixel_t expected;
-	test_update_t update;
-	errno_t rc;
-
-	/* Bounding rectangle for memory GC */
-	rect.p0.x = 0;
-	rect.p0.y = 0;
-	rect.p1.x = 10;
-	rect.p1.y = 10;
-
-	alloc.pitch = (rect.p1.x - rect.p0.x) * sizeof(uint32_t);
-	alloc.off0 = 0;
-	alloc.pixels = calloc(1, alloc.pitch * (rect.p1.y - rect.p0.y));
-	PCUT_ASSERT_NOT_NULL(alloc.pixels);
-
-	rc = mem_gc_create(&rect, &alloc, test_update_rect, &update, &mgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = mem_gc_get_ctx(mgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Create bitmap */
-
-	params.rect.p0.x = 0;
-	params.rect.p0.y = 0;
-	params.rect.p1.x = 6;
-	params.rect.p1.y = 6;
-
-	/* TODO Test client allocation */
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_bitmap_get_alloc(bitmap, &balloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	bpmap.width = params.rect.p1.x - params.rect.p0.x;
-	bpmap.height = params.rect.p1.y - params.rect.p0.y;
-	bpmap.data = balloc.pixels;
-
-	/* Fill bitmap pixels with constant color */
-	for (pos.y = params.rect.p0.y; pos.y < params.rect.p1.y; pos.y++) {
-		for (pos.x =  params.rect.p0.x; pos.x <  params.rect.p1.x; pos.x++) {
-			pixelmap_put_pixel(&bpmap, pos.x, pos.y,
-			    PIXEL(0, 255, 255, 0));
-		}
-	}
-
-	dpmap.width = rect.p1.x - rect.p0.x;
-	dpmap.height = rect.p1.y - rect.p0.y;
-	dpmap.data = alloc.pixels;
-
-	memset(&update, 0, sizeof(update));
-
-	/* Render the bitmap */
-	/* TODO Test rendering sub-rectangle */
-	/* TODO Test rendering with offset */
-	rc = gfx_bitmap_render(bitmap, NULL, NULL);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Check that the pixels of the rectangle are set and no others are */
-	for (pos.y = rect.p0.y; pos.y < rect.p1.y; pos.y++) {
-		for (pos.x = rect.p0.x; pos.x < rect.p1.x; pos.x++) {
-			pixel = pixelmap_get_pixel(&dpmap, pos.x, pos.y);
-			expected = gfx_pix_inside_rect(&pos, &params.rect) ?
-			    PIXEL(0, 255, 255, 0) : PIXEL(0, 0, 0, 0);
-			PCUT_ASSERT_INT_EQUALS(expected, pixel);
-		}
-	}
-
-	/* Check that the update rect is equal to the filled rect */
-	PCUT_ASSERT_TRUE(update.update_called);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, update.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, update.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, update.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, update.rect.p1.y);
-
-	/* TODO: Check clipping once memgc can support pitch != width etc. */
-
-	mem_gc_delete(mgc);
-	free(alloc.pixels);
-}
-
-/** Called by memory GC when a rectangle is updated. */
-static void test_update_rect(void *arg, gfx_rect_t *rect)
-{
-	test_update_t *update = (test_update_t *)arg;
-
-	update->update_called = true;
-	update->rect = *rect;
-}
-
-PCUT_EXPORT(memgfx);
Index: uspace/lib/meson.build
===================================================================
--- uspace/lib/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/lib/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -33,5 +33,4 @@
 	'c',
 	'math',
-	'display',
 	'gui',
 	'draw',
@@ -40,8 +39,5 @@
 	'clui',
 	'pcm',
-	'hound',
-	'gfx',
-	'ipcgfx',
-	'display',
+	'hound'
 ]
 
@@ -59,5 +55,5 @@
 	'fmtutil',
 	'fs',
-	'gfx',
+	'graph',
 	'http',
 	'label',
@@ -76,11 +72,9 @@
 
 	'bithenge',
-	'congfx',
 	'draw',
 	'drv',
 	'ext4',
+	'gui',
 	'hound',
-	'ipcgfx',
-	'memgfx',
 	'nic',
 	'usb',
@@ -92,10 +86,4 @@
 
 	'ieee80211',
-	'ddev',
-	'display',
-
-	'gui',
-
-	'guigfx',
 ]
 
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/srv/hid/compositor/compositor.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,2364 @@
+/*
+ * Copyright (c) 2012 Petr Koupy
+ * 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 compositor
+ * @{
+ */
+/** @file
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <str_error.h>
+#include <byteorder.h>
+#include <stdio.h>
+#include <libc.h>
+
+#include <align.h>
+#include <as.h>
+#include <stdlib.h>
+
+#include <refcount.h>
+#include <fibril_synch.h>
+#include <adt/prodcons.h>
+#include <adt/list.h>
+#include <io/input.h>
+#include <ipc/graph.h>
+#include <ipc/window.h>
+
+#include <async.h>
+#include <loc.h>
+#include <task.h>
+
+#include <io/keycode.h>
+#include <io/mode.h>
+#include <io/visualizer.h>
+#include <io/window.h>
+#include <io/console.h>
+
+#include <transform.h>
+#include <rectangle.h>
+#include <draw/surface.h>
+#include <draw/cursor.h>
+#include <draw/source.h>
+#include <draw/drawctx.h>
+#include <draw/codec.h>
+
+#include "compositor.h"
+
+#define NAME       "compositor"
+#define NAMESPACE  "comp"
+
+/*
+ * Until there is blitter support and some further optimizations, window
+ * animations are too slow to be practically usable.
+ */
+#ifndef ANIMATE_WINDOW_TRANSFORMS
+#define ANIMATE_WINDOW_TRANSFORMS 0
+#endif
+
+static char *server_name;
+static sysarg_t coord_origin;
+static pixel_t bg_color;
+static filter_t filter = filter_bilinear;
+static unsigned int filter_index = 1;
+
+typedef struct {
+	link_t link;
+	atomic_refcount_t ref_cnt;
+	window_flags_t flags;
+	service_id_t in_dsid;
+	service_id_t out_dsid;
+	prodcons_t queue;
+	transform_t transform;
+	double dx;
+	double dy;
+	double fx;
+	double fy;
+	double angle;
+	uint8_t opacity;
+	surface_t *surface;
+} window_t;
+
+static service_id_t winreg_id;
+static sysarg_t window_id = 0;
+static FIBRIL_MUTEX_INITIALIZE(window_list_mtx);
+static LIST_INITIALIZE(window_list);
+static double scale_back_x;
+static double scale_back_y;
+
+typedef struct {
+	link_t link;
+	sysarg_t id;
+	uint8_t state;
+	desktop_point_t pos;
+	sysarg_t btn_num;
+	desktop_point_t btn_pos;
+	desktop_vector_t accum;
+	sysarg_t grab_flags;
+	bool pressed;
+	cursor_t cursor;
+	window_t ghost;
+	desktop_vector_t accum_ghost;
+} pointer_t;
+
+static sysarg_t pointer_id = 0;
+static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
+static LIST_INITIALIZE(pointer_list);
+
+typedef struct {
+	link_t link;
+	service_id_t dsid;
+	vslmode_t mode;
+	async_sess_t *sess;
+	desktop_point_t pos;
+	surface_t *surface;
+} viewport_t;
+
+static desktop_rect_t viewport_bound_rect;
+static FIBRIL_MUTEX_INITIALIZE(viewport_list_mtx);
+static LIST_INITIALIZE(viewport_list);
+
+static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);
+
+/** Input server proxy */
+static input_t *input;
+static bool active = false;
+
+static errno_t comp_active(input_t *);
+static errno_t comp_deactive(input_t *);
+static errno_t comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
+static errno_t comp_mouse_move(input_t *, int, int);
+static errno_t comp_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
+static errno_t comp_mouse_button(input_t *, int, int);
+
+static input_ev_ops_t input_ev_ops = {
+	.active = comp_active,
+	.deactive = comp_deactive,
+	.key = comp_key_press,
+	.move = comp_mouse_move,
+	.abs_move = comp_abs_move,
+	.button = comp_mouse_button
+};
+
+static pointer_t *input_pointer(input_t *input)
+{
+	return input->user;
+}
+
+static pointer_t *pointer_create(void)
+{
+	pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
+	if (!p)
+		return NULL;
+
+	link_initialize(&p->link);
+	p->pos.x = coord_origin;
+	p->pos.y = coord_origin;
+	p->btn_num = 1;
+	p->btn_pos = p->pos;
+	p->accum.x = 0;
+	p->accum.y = 0;
+	p->grab_flags = GF_EMPTY;
+	p->pressed = false;
+	p->state = 0;
+	cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
+
+	/* Ghost window for transformation animation. */
+	transform_identity(&p->ghost.transform);
+	transform_translate(&p->ghost.transform, coord_origin, coord_origin);
+	p->ghost.dx = coord_origin;
+	p->ghost.dy = coord_origin;
+	p->ghost.fx = 1;
+	p->ghost.fy = 1;
+	p->ghost.angle = 0;
+	p->ghost.opacity = 255;
+	p->ghost.surface = NULL;
+	p->accum_ghost.x = 0;
+	p->accum_ghost.y = 0;
+
+	return p;
+}
+
+static void pointer_destroy(pointer_t *p)
+{
+	if (p) {
+		cursor_release(&p->cursor);
+		free(p);
+	}
+}
+
+static window_t *window_create(void)
+{
+	window_t *win = (window_t *) malloc(sizeof(window_t));
+	if (!win)
+		return NULL;
+
+	link_initialize(&win->link);
+	/* One initial reference will be for being in the window list */
+	refcount_init(&win->ref_cnt);
+	prodcons_initialize(&win->queue);
+	transform_identity(&win->transform);
+	transform_translate(&win->transform, coord_origin, coord_origin);
+	win->dx = coord_origin;
+	win->dy = coord_origin;
+	win->fx = 1;
+	win->fy = 1;
+	win->angle = 0;
+	win->opacity = 255;
+	win->surface = NULL;
+
+	return win;
+}
+
+static void window_destroy(window_t *win)
+{
+	if (win == NULL)
+		return;
+
+	if (!refcount_down(&win->ref_cnt))
+		return;
+
+	while (!list_empty(&win->queue.list)) {
+		window_event_t *event = (window_event_t *) list_first(&win->queue.list);
+		list_remove(&event->link);
+		free(event);
+	}
+
+	if (win->surface)
+		surface_destroy(win->surface);
+
+	free(win);
+}
+
+static bool comp_coord_to_client(sysarg_t x_in, sysarg_t y_in, transform_t win_trans,
+    sysarg_t x_lim, sysarg_t y_lim, sysarg_t *x_out, sysarg_t *y_out)
+{
+	double x = x_in;
+	double y = y_in;
+	transform_invert(&win_trans);
+	transform_apply_affine(&win_trans, &x, &y);
+
+	/*
+	 * Since client coordinate origin is (0, 0), it is necessary to check
+	 * coordinates to avoid underflow. Moreover, it is convenient to also
+	 * check against provided upper limits to determine whether the converted
+	 * coordinates are within the client window.
+	 */
+	if ((x < 0) || (y < 0))
+		return false;
+
+	(*x_out) = (sysarg_t) (x + 0.5);
+	(*y_out) = (sysarg_t) (y + 0.5);
+
+	if (((*x_out) >= x_lim) || ((*y_out) >= y_lim))
+		return false;
+
+	return true;
+}
+
+static void comp_coord_from_client(double x_in, double y_in, transform_t win_trans,
+    sysarg_t *x_out, sysarg_t *y_out)
+{
+	double x = x_in;
+	double y = y_in;
+	transform_apply_affine(&win_trans, &x, &y);
+
+	/*
+	 * It is assumed that compositor coordinate origin is chosen in such way,
+	 * that underflow/overflow here would be unlikely.
+	 */
+	(*x_out) = (sysarg_t) (x + 0.5);
+	(*y_out) = (sysarg_t) (y + 0.5);
+}
+
+static void comp_coord_bounding_rect(double x_in, double y_in,
+    double w_in, double h_in, transform_t win_trans,
+    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
+{
+	if ((w_in > 0) && (h_in > 0)) {
+		sysarg_t x[4];
+		sysarg_t y[4];
+
+		comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
+		comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
+		comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
+		comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
+
+		(*x_out) = x[0];
+		(*y_out) = y[0];
+		(*w_out) = x[0];
+		(*h_out) = y[0];
+
+		for (unsigned int i = 1; i < 4; ++i) {
+			(*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
+			(*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
+			(*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out);
+			(*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
+		}
+
+		(*w_out) = (*w_out) - (*x_out) + 1;
+		(*h_out) = (*h_out) - (*y_out) + 1;
+	} else {
+		(*x_out) = 0;
+		(*y_out) = 0;
+		(*w_out) = 0;
+		(*h_out) = 0;
+	}
+}
+
+static void comp_update_viewport_bound_rect(void)
+{
+	fibril_mutex_lock(&viewport_list_mtx);
+
+	sysarg_t x_res = coord_origin;
+	sysarg_t y_res = coord_origin;
+	sysarg_t w_res = 0;
+	sysarg_t h_res = 0;
+
+	if (!list_empty(&viewport_list)) {
+		viewport_t *vp = (viewport_t *) list_first(&viewport_list);
+		x_res = vp->pos.x;
+		y_res = vp->pos.y;
+		surface_get_resolution(vp->surface, &w_res, &h_res);
+	}
+
+	list_foreach(viewport_list, link, viewport_t, vp) {
+		sysarg_t w_vp, h_vp;
+		surface_get_resolution(vp->surface, &w_vp, &h_vp);
+		rectangle_union(x_res, y_res, w_res, h_res,
+		    vp->pos.x, vp->pos.y, w_vp, h_vp,
+		    &x_res, &y_res, &w_res, &h_res);
+	}
+
+	viewport_bound_rect.x = x_res;
+	viewport_bound_rect.y = y_res;
+	viewport_bound_rect.w = w_res;
+	viewport_bound_rect.h = h_res;
+
+	fibril_mutex_unlock(&viewport_list_mtx);
+}
+
+static void comp_restrict_pointers(void)
+{
+	comp_update_viewport_bound_rect();
+
+	fibril_mutex_lock(&pointer_list_mtx);
+
+	list_foreach(pointer_list, link, pointer_t, ptr) {
+		ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
+		ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
+		ptr->pos.x = ptr->pos.x < viewport_bound_rect.x + viewport_bound_rect.w ?
+		    ptr->pos.x : viewport_bound_rect.x + viewport_bound_rect.w;
+		ptr->pos.y = ptr->pos.y < viewport_bound_rect.y + viewport_bound_rect.h ?
+		    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
+	}
+
+	fibril_mutex_unlock(&pointer_list_mtx);
+}
+
+static void comp_damage(sysarg_t x_dmg_glob, sysarg_t y_dmg_glob,
+    sysarg_t w_dmg_glob, sysarg_t h_dmg_glob)
+{
+	fibril_mutex_lock(&viewport_list_mtx);
+	fibril_mutex_lock(&window_list_mtx);
+	fibril_mutex_lock(&pointer_list_mtx);
+
+	list_foreach(viewport_list, link, viewport_t, vp) {
+		/* Determine what part of the viewport must be updated. */
+		sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
+		surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp);
+		bool isec_vp = rectangle_intersect(
+		    x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob,
+		    vp->pos.x, vp->pos.y, w_dmg_vp, h_dmg_vp,
+		    &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
+
+		if (isec_vp) {
+
+			/* Paint background color. */
+			for (sysarg_t y = y_dmg_vp - vp->pos.y; y <  y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) {
+				pixel_t *dst = pixelmap_pixel_at(
+				    surface_pixmap_access(vp->surface), x_dmg_vp - vp->pos.x, y);
+				sysarg_t count = w_dmg_vp;
+				while (count-- != 0) {
+					*dst++ = bg_color;
+				}
+			}
+			surface_add_damaged_region(vp->surface,
+			    x_dmg_vp - vp->pos.x, y_dmg_vp - vp->pos.y, w_dmg_vp, h_dmg_vp);
+
+			transform_t transform;
+			source_t source;
+			drawctx_t context;
+
+			source_init(&source);
+			source_set_filter(&source, filter);
+			drawctx_init(&context, vp->surface);
+			drawctx_set_compose(&context, compose_over);
+			drawctx_set_source(&context, &source);
+
+			/* For each window. */
+			for (link_t *link = window_list.head.prev;
+			    link != &window_list.head; link = link->prev) {
+
+				/*
+				 * Determine what part of the window intersects with the
+				 * updated area of the current viewport.
+				 */
+				window_t *win = list_get_instance(link, window_t, link);
+				if (!win->surface) {
+					continue;
+				}
+				sysarg_t x_dmg_win, y_dmg_win, w_dmg_win, h_dmg_win;
+				surface_get_resolution(win->surface, &w_dmg_win, &h_dmg_win);
+				comp_coord_bounding_rect(0, 0, w_dmg_win, h_dmg_win, win->transform,
+				    &x_dmg_win, &y_dmg_win, &w_dmg_win, &h_dmg_win);
+				bool isec_win = rectangle_intersect(
+				    x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
+				    x_dmg_win, y_dmg_win, w_dmg_win, h_dmg_win,
+				    &x_dmg_win, &y_dmg_win, &w_dmg_win, &h_dmg_win);
+
+				if (isec_win) {
+					/*
+					 * Prepare conversion from global coordinates to viewport
+					 * coordinates.
+					 */
+					transform = win->transform;
+					double_point_t pos;
+					pos.x = vp->pos.x;
+					pos.y = vp->pos.y;
+					transform_translate(&transform, -pos.x, -pos.y);
+
+					source_set_transform(&source, transform);
+					source_set_texture(&source, win->surface,
+					    PIXELMAP_EXTEND_TRANSPARENT_SIDES);
+					source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0));
+
+					drawctx_transfer(&context,
+					    x_dmg_win - vp->pos.x, y_dmg_win - vp->pos.y, w_dmg_win, h_dmg_win);
+				}
+			}
+
+			list_foreach(pointer_list, link, pointer_t, ptr) {
+				if (ptr->ghost.surface) {
+
+					sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost;
+					sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost;
+					surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost);
+					comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform,
+					    &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost);
+					bool isec_ghost = rectangle_intersect(
+					    x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
+					    x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost,
+					    &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost);
+
+					if (isec_ghost) {
+						/*
+						 * FIXME: Ghost is currently drawn based on the bounding
+						 * rectangle of the window, which is sufficient as long
+						 * as the windows can be rotated only by 90 degrees.
+						 * For ghost to be compatible with arbitrary-angle
+						 * rotation, it should be drawn as four lines adjusted
+						 * by the transformation matrix. That would however
+						 * require to equip libdraw with line drawing functionality.
+						 */
+
+						transform_t transform = ptr->ghost.transform;
+						double_point_t pos;
+						pos.x = vp->pos.x;
+						pos.y = vp->pos.y;
+						transform_translate(&transform, -pos.x, -pos.y);
+
+						pixel_t ghost_color;
+
+						if (y_bnd_ghost == y_dmg_ghost) {
+							for (sysarg_t x = x_dmg_ghost - vp->pos.x;
+							    x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
+								ghost_color = surface_get_pixel(vp->surface,
+								    x, y_dmg_ghost - vp->pos.y);
+								surface_put_pixel(vp->surface,
+								    x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color));
+							}
+						}
+
+						if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) {
+							for (sysarg_t x = x_dmg_ghost - vp->pos.x;
+							    x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
+								ghost_color = surface_get_pixel(vp->surface,
+								    x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1);
+								surface_put_pixel(vp->surface,
+								    x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color));
+							}
+						}
+
+						if (x_bnd_ghost == x_dmg_ghost) {
+							for (sysarg_t y = y_dmg_ghost - vp->pos.y;
+							    y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
+								ghost_color = surface_get_pixel(vp->surface,
+								    x_dmg_ghost - vp->pos.x, y);
+								surface_put_pixel(vp->surface,
+								    x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color));
+							}
+						}
+
+						if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) {
+							for (sysarg_t y = y_dmg_ghost - vp->pos.y;
+							    y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
+								ghost_color = surface_get_pixel(vp->surface,
+								    x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y);
+								surface_put_pixel(vp->surface,
+								    x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color));
+							}
+						}
+					}
+
+				}
+			}
+
+			list_foreach(pointer_list, link, pointer_t, ptr) {
+
+				/*
+				 * Determine what part of the pointer intersects with the
+				 * updated area of the current viewport.
+				 */
+				sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr;
+				surface_t *sf_ptr = ptr->cursor.states[ptr->state];
+				surface_get_resolution(sf_ptr, &w_dmg_ptr, &h_dmg_ptr);
+				bool isec_ptr = rectangle_intersect(
+				    x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
+				    ptr->pos.x, ptr->pos.y, w_dmg_ptr, h_dmg_ptr,
+				    &x_dmg_ptr, &y_dmg_ptr, &w_dmg_ptr, &h_dmg_ptr);
+
+				if (isec_ptr) {
+					/*
+					 * Pointer is currently painted directly by copying pixels.
+					 * However, it is possible to draw the pointer similarly
+					 * as window by using drawctx_transfer. It would allow
+					 * more sophisticated control over drawing, but would also
+					 * cost more regarding the performance.
+					 */
+
+					sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
+					sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
+					sysarg_t x_ptr = x_dmg_ptr - ptr->pos.x;
+					sysarg_t y_ptr = y_dmg_ptr - ptr->pos.y;
+
+					for (sysarg_t y = 0; y < h_dmg_ptr; ++y) {
+						pixel_t *src = pixelmap_pixel_at(
+						    surface_pixmap_access(sf_ptr), x_ptr, y_ptr + y);
+						pixel_t *dst = pixelmap_pixel_at(
+						    surface_pixmap_access(vp->surface), x_vp, y_vp + y);
+						sysarg_t count = w_dmg_ptr;
+						while (count-- != 0) {
+							*dst = (*src & 0xff000000) ? *src : *dst;
+							++dst;
+							++src;
+						}
+					}
+					surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr);
+				}
+
+			}
+		}
+	}
+
+	fibril_mutex_unlock(&pointer_list_mtx);
+	fibril_mutex_unlock(&window_list_mtx);
+
+	/* Notify visualizers about updated regions. */
+	if (active) {
+		list_foreach(viewport_list, link, viewport_t, vp) {
+			sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
+			surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
+			surface_reset_damaged_region(vp->surface);
+			visualizer_update_damaged_region(vp->sess,
+			    x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0);
+		}
+	}
+
+	fibril_mutex_unlock(&viewport_list_mtx);
+}
+
+static void comp_window_get_event(window_t *win, ipc_call_t *icall)
+{
+	window_event_t *event = (window_event_t *) prodcons_consume(&win->queue);
+
+	ipc_call_t call;
+	size_t len;
+
+	if (!async_data_read_receive(&call, &len)) {
+		async_answer_0(icall, EINVAL);
+		free(event);
+		return;
+	}
+
+	errno_t rc = async_data_read_finalize(&call, event, len);
+	if (rc != EOK) {
+		async_answer_0(icall, ENOMEM);
+		free(event);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+	free(event);
+}
+
+static void comp_window_damage(window_t *win, ipc_call_t *icall)
+{
+	double x = ipc_get_arg1(icall);
+	double y = ipc_get_arg2(icall);
+	double width = ipc_get_arg3(icall);
+	double height = ipc_get_arg4(icall);
+
+	if ((width == 0) || (height == 0)) {
+		comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
+	} else {
+		fibril_mutex_lock(&window_list_mtx);
+		sysarg_t x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob;
+		comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2,
+		    win->transform, &x_dmg_glob, &y_dmg_glob, &w_dmg_glob, &h_dmg_glob);
+		fibril_mutex_unlock(&window_list_mtx);
+		comp_damage(x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob);
+	}
+
+	async_answer_0(icall, EOK);
+}
+
+static void comp_window_grab(window_t *win, ipc_call_t *icall)
+{
+	sysarg_t pos_id = ipc_get_arg1(icall);
+	sysarg_t grab_flags = ipc_get_arg2(icall);
+
+	/*
+	 * Filter out resize grab flags if the window
+	 * is not resizeable.
+	 */
+	if ((win->flags & WINDOW_RESIZEABLE) != WINDOW_RESIZEABLE)
+		grab_flags &= ~(GF_RESIZE_X | GF_RESIZE_Y);
+
+	fibril_mutex_lock(&pointer_list_mtx);
+	list_foreach(pointer_list, link, pointer_t, pointer) {
+		if (pointer->id == pos_id) {
+			pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
+			// TODO change pointer->state according to grab_flags
+			break;
+		}
+	}
+	fibril_mutex_unlock(&pointer_list_mtx);
+
+	if ((grab_flags & GF_RESIZE_X) || (grab_flags & GF_RESIZE_Y)) {
+		scale_back_x = 1;
+		scale_back_y = 1;
+	}
+
+	async_answer_0(icall, EOK);
+}
+
+static void comp_recalc_transform(window_t *win)
+{
+	transform_t translate;
+	transform_identity(&translate);
+	transform_translate(&translate, win->dx, win->dy);
+
+	transform_t scale;
+	transform_identity(&scale);
+	if ((win->fx != 1) || (win->fy != 1))
+		transform_scale(&scale, win->fx, win->fy);
+
+	transform_t rotate;
+	transform_identity(&rotate);
+	if (win->angle != 0)
+		transform_rotate(&rotate, win->angle);
+
+	transform_t transform;
+	transform_t temp;
+	transform_identity(&transform);
+	temp = transform;
+	transform_product(&transform, &temp, &translate);
+	temp = transform;
+	transform_product(&transform, &temp, &rotate);
+	temp = transform;
+	transform_product(&transform, &temp, &scale);
+
+	win->transform = transform;
+}
+
+static void comp_window_resize(window_t *win, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t size;
+	unsigned int flags;
+
+	/* Start sharing resized window with client. */
+	if (!async_share_out_receive(&call, &size, &flags)) {
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	void *new_cell_storage;
+	errno_t rc = async_share_out_finalize(&call, &new_cell_storage);
+	if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	/* Create new surface for the resized window. */
+	surface_t *new_surface = surface_create(ipc_get_arg3(icall),
+	    ipc_get_arg4(icall), new_cell_storage, SURFACE_FLAG_SHARED);
+	if (!new_surface) {
+		as_area_destroy(new_cell_storage);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	sysarg_t offset_x = ipc_get_arg1(icall);
+	sysarg_t offset_y = ipc_get_arg2(icall);
+	window_placement_flags_t placement_flags =
+	    (window_placement_flags_t) ipc_get_arg5(icall);
+
+	comp_update_viewport_bound_rect();
+
+	/* Switch new surface with old surface and calculate damage. */
+	fibril_mutex_lock(&window_list_mtx);
+
+	sysarg_t old_width = 0;
+	sysarg_t old_height = 0;
+
+	if (win->surface) {
+		surface_get_resolution(win->surface, &old_width, &old_height);
+		surface_destroy(win->surface);
+	}
+
+	win->surface = new_surface;
+
+	sysarg_t new_width = 0;
+	sysarg_t new_height = 0;
+	surface_get_resolution(win->surface, &new_width, &new_height);
+
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 -
+		    new_width / 2;
+
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 -
+		    new_height / 2;
+
+	if (placement_flags & WINDOW_PLACEMENT_LEFT)
+		win->dx = viewport_bound_rect.x;
+
+	if (placement_flags & WINDOW_PLACEMENT_TOP)
+		win->dy = viewport_bound_rect.y;
+
+	if (placement_flags & WINDOW_PLACEMENT_RIGHT)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w -
+		    new_width;
+
+	if (placement_flags & WINDOW_PLACEMENT_BOTTOM)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h -
+		    new_height;
+
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X)
+		win->dx = coord_origin + offset_x;
+
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y)
+		win->dy = coord_origin + offset_y;
+
+	/* Transform the window and calculate damage. */
+	sysarg_t x1;
+	sysarg_t y1;
+	sysarg_t width1;
+	sysarg_t height1;
+
+	comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform,
+	    &x1, &y1, &width1, &height1);
+
+	comp_recalc_transform(win);
+
+	sysarg_t x2;
+	sysarg_t y2;
+	sysarg_t width2;
+	sysarg_t height2;
+
+	comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform,
+	    &x2, &y2, &width2, &height2);
+
+	sysarg_t x;
+	sysarg_t y;
+	sysarg_t width;
+	sysarg_t height;
+
+	rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+	    &x, &y, &width, &height);
+
+	fibril_mutex_unlock(&window_list_mtx);
+
+	comp_damage(x, y, width, height);
+
+	async_answer_0(icall, EOK);
+}
+
+static void comp_post_event_win(window_event_t *event, window_t *target)
+{
+	fibril_mutex_lock(&window_list_mtx);
+
+	list_foreach(window_list, link, window_t, window) {
+		if (window == target) {
+			prodcons_produce(&window->queue, &event->link);
+			fibril_mutex_unlock(&window_list_mtx);
+			return;
+		}
+	}
+
+	fibril_mutex_unlock(&window_list_mtx);
+	free(event);
+}
+
+static void comp_post_event_top(window_event_t *event)
+{
+	fibril_mutex_lock(&window_list_mtx);
+
+	window_t *win = (window_t *) list_first(&window_list);
+	if (win)
+		prodcons_produce(&win->queue, &event->link);
+	else
+		free(event);
+
+	fibril_mutex_unlock(&window_list_mtx);
+}
+
+static void comp_window_close(window_t *win, ipc_call_t *icall)
+{
+	/* Stop managing the window. */
+	fibril_mutex_lock(&window_list_mtx);
+	list_remove(&win->link);
+	window_t *win_focus = (window_t *) list_first(&window_list);
+	window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t));
+	if (event_focus) {
+		link_initialize(&event_focus->link);
+		event_focus->type = ET_WINDOW_FOCUS;
+	}
+	fibril_mutex_unlock(&window_list_mtx);
+
+	if (event_focus && win_focus) {
+		comp_post_event_win(event_focus, win_focus);
+	}
+
+	loc_service_unregister(win->in_dsid);
+	loc_service_unregister(win->out_dsid);
+
+	/*
+	 * In case the client was killed, input fibril of the window might be
+	 * still blocked on the condition within comp_window_get_event.
+	 */
+	window_event_t *event_dummy = (window_event_t *) malloc(sizeof(window_event_t));
+	if (event_dummy) {
+		link_initialize(&event_dummy->link);
+		prodcons_produce(&win->queue, &event_dummy->link);
+	}
+
+	/* Calculate damage. */
+	sysarg_t x = 0;
+	sysarg_t y = 0;
+	sysarg_t width = 0;
+	sysarg_t height = 0;
+	if (win->surface) {
+		surface_get_resolution(win->surface, &width, &height);
+		comp_coord_bounding_rect(
+		    0, 0, width, height, win->transform, &x, &y, &width, &height);
+	}
+
+	/* Down refcount for removing from the window list */
+	window_destroy(win);
+
+	comp_damage(x, y, width, height);
+	async_answer_0(icall, EOK);
+}
+
+static void comp_window_close_request(window_t *win, ipc_call_t *icall)
+{
+	window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+	if (event == NULL) {
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	link_initialize(&event->link);
+	event->type = ET_WINDOW_CLOSE;
+
+	prodcons_produce(&win->queue, &event->link);
+	async_answer_0(icall, EOK);
+}
+
+static void client_connection(ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	service_id_t service_id = (service_id_t) ipc_get_arg2(icall);
+
+	/* Allocate resources for new window and register it to the location service. */
+	if (service_id == winreg_id) {
+		async_accept_0(icall);
+
+		async_get_call(&call);
+		if (ipc_get_imethod(&call) == WINDOW_REGISTER) {
+			fibril_mutex_lock(&window_list_mtx);
+
+			window_t *win = window_create();
+			if (!win) {
+				async_answer_0(&call, EHANGUP);
+				fibril_mutex_unlock(&window_list_mtx);
+				return;
+			}
+
+			win->flags = ipc_get_arg1(&call);
+
+			char name_in[LOC_NAME_MAXLEN + 1];
+			snprintf(name_in, LOC_NAME_MAXLEN, "%s%s/win%zuin", NAMESPACE,
+			    server_name, window_id);
+
+			char name_out[LOC_NAME_MAXLEN + 1];
+			snprintf(name_out, LOC_NAME_MAXLEN, "%s%s/win%zuout", NAMESPACE,
+			    server_name, window_id);
+
+			++window_id;
+
+			if (loc_service_register(name_in, &win->in_dsid) != EOK) {
+				window_destroy(win);
+				async_answer_0(&call, EHANGUP);
+				fibril_mutex_unlock(&window_list_mtx);
+				return;
+			}
+
+			if (loc_service_register(name_out, &win->out_dsid) != EOK) {
+				loc_service_unregister(win->in_dsid);
+				window_destroy(win);
+				async_answer_0(&call, EHANGUP);
+				fibril_mutex_unlock(&window_list_mtx);
+				return;
+			}
+
+			window_t *win_unfocus = (window_t *) list_first(&window_list);
+			list_prepend(&win->link, &window_list);
+
+			window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_unfocus) {
+				link_initialize(&event_unfocus->link);
+				event_unfocus->type = ET_WINDOW_UNFOCUS;
+			}
+
+			async_answer_2(&call, EOK, win->in_dsid, win->out_dsid);
+			fibril_mutex_unlock(&window_list_mtx);
+
+			if (event_unfocus && win_unfocus) {
+				comp_post_event_win(event_unfocus, win_unfocus);
+			}
+
+			async_get_call(&call);
+		}
+		async_answer_0(&call, EHANGUP);
+		return;
+	}
+
+	/* Match the client with pre-allocated window. */
+	window_t *win = NULL;
+	fibril_mutex_lock(&window_list_mtx);
+	list_foreach(window_list, link, window_t, cur) {
+		if (cur->in_dsid == service_id || cur->out_dsid == service_id) {
+			win = cur;
+			break;
+		}
+	}
+
+	if (win)
+		refcount_up(&win->ref_cnt);
+
+	fibril_mutex_unlock(&window_list_mtx);
+
+	if (win) {
+		async_accept_0(icall);
+	} else {
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	/* Each client establishes two separate connections. */
+	if (win->in_dsid == service_id) {
+		while (true) {
+			async_get_call(&call);
+
+			if (!ipc_get_imethod(&call)) {
+				async_answer_0(&call, EOK);
+				window_destroy(win);
+				return;
+			}
+
+			switch (ipc_get_imethod(&call)) {
+			case WINDOW_GET_EVENT:
+				comp_window_get_event(win, &call);
+				break;
+			default:
+				async_answer_0(&call, EINVAL);
+			}
+		}
+	} else if (win->out_dsid == service_id) {
+		while (true) {
+			async_get_call(&call);
+
+			if (!ipc_get_imethod(&call)) {
+				comp_window_close(win, &call);
+				window_destroy(win);
+				return;
+			}
+
+			switch (ipc_get_imethod(&call)) {
+			case WINDOW_DAMAGE:
+				comp_window_damage(win, &call);
+				break;
+			case WINDOW_GRAB:
+				comp_window_grab(win, &call);
+				break;
+			case WINDOW_RESIZE:
+				comp_window_resize(win, &call);
+				break;
+			case WINDOW_CLOSE:
+				/*
+				 * Postpone the closing until the phone is hung up to cover
+				 * the case when the client is killed abruptly.
+				 */
+				async_answer_0(&call, EOK);
+				break;
+			case WINDOW_CLOSE_REQUEST:
+				comp_window_close_request(win, &call);
+				break;
+			default:
+				async_answer_0(&call, EINVAL);
+			}
+		}
+	}
+}
+
+static void comp_mode_change(viewport_t *vp, ipc_call_t *icall)
+{
+	sysarg_t mode_idx = ipc_get_arg2(icall);
+	fibril_mutex_lock(&viewport_list_mtx);
+
+	/* Retrieve the mode that shall be set. */
+	vslmode_t new_mode;
+	errno_t rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&viewport_list_mtx);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	/* Create surface with respect to the retrieved mode. */
+	surface_t *new_surface = surface_create(new_mode.screen_width,
+	    new_mode.screen_height, NULL, SURFACE_FLAG_SHARED);
+	if (!new_surface) {
+		fibril_mutex_unlock(&viewport_list_mtx);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	/* Try to set the mode and share out the surface. */
+	rc = visualizer_set_mode(vp->sess,
+	    new_mode.index, new_mode.version, surface_direct_access(new_surface));
+	if (rc != EOK) {
+		surface_destroy(new_surface);
+		fibril_mutex_unlock(&viewport_list_mtx);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	/* Destroy old surface and update viewport. */
+	surface_destroy(vp->surface);
+	vp->mode = new_mode;
+	vp->surface = new_surface;
+
+	fibril_mutex_unlock(&viewport_list_mtx);
+	async_answer_0(icall, EOK);
+
+	comp_restrict_pointers();
+	comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
+}
+
+static void viewport_destroy(viewport_t *vp)
+{
+	if (vp) {
+		visualizer_yield(vp->sess);
+		surface_destroy(vp->surface);
+		async_hangup(vp->sess);
+		free(vp);
+	}
+}
+
+#if 0
+static void comp_shutdown(void)
+{
+	loc_service_unregister(winreg_id);
+	input_disconnect();
+
+	/* Close all clients and their windows. */
+	fibril_mutex_lock(&window_list_mtx);
+	list_foreach(window_list, link, window_t, win) {
+		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+		if (event) {
+			link_initialize(&event->link);
+			event->type = WINDOW_CLOSE;
+			prodcons_produce(&win->queue, &event->link);
+		}
+	}
+	fibril_mutex_unlock(&window_list_mtx);
+
+	async_answer_0(icall, EOK);
+
+	/* All fibrils of the compositor will terminate soon. */
+}
+#endif
+
+static void comp_visualizer_disconnect(viewport_t *vp, ipc_call_t *icall)
+{
+	/* Release viewport resources. */
+	fibril_mutex_lock(&viewport_list_mtx);
+
+	list_remove(&vp->link);
+	viewport_destroy(vp);
+
+	fibril_mutex_unlock(&viewport_list_mtx);
+
+	async_answer_0(icall, EOK);
+
+	comp_restrict_pointers();
+	comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
+}
+
+static void vsl_notifications(ipc_call_t *icall, void *arg)
+{
+	viewport_t *vp = NULL;
+	fibril_mutex_lock(&viewport_list_mtx);
+	list_foreach(viewport_list, link, viewport_t, cur) {
+		if (cur->dsid == (service_id_t) ipc_get_arg1(icall)) {
+			vp = cur;
+			break;
+		}
+	}
+	fibril_mutex_unlock(&viewport_list_mtx);
+
+	if (!vp)
+		return;
+
+	/* Ignore parameters, the connection is already opened. */
+	while (true) {
+		ipc_call_t call;
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call)) {
+			async_hangup(vp->sess);
+			return;
+		}
+
+		switch (ipc_get_imethod(&call)) {
+		case VISUALIZER_MODE_CHANGE:
+			comp_mode_change(vp, &call);
+			break;
+		case VISUALIZER_DISCONNECT:
+			comp_visualizer_disconnect(vp, &call);
+			return;
+		default:
+			async_answer_0(&call, EINVAL);
+		}
+	}
+}
+
+static async_sess_t *vsl_connect(service_id_t sid, const char *svc)
+{
+	errno_t rc;
+	async_sess_t *sess;
+
+	sess = loc_service_connect(sid, INTERFACE_DDF, 0);
+	if (sess == NULL) {
+		printf("%s: Unable to connect to visualizer %s\n", NAME, svc);
+		return NULL;
+	}
+
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	port_id_t port;
+	rc = async_create_callback_port(exch, INTERFACE_VISUALIZER_CB, 0, 0,
+	    vsl_notifications, NULL, &port);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_hangup(sess);
+		printf("%s: Unable to create callback connection to service %s (%s)\n",
+		    NAME, svc, str_error(rc));
+		return NULL;
+	}
+
+	return sess;
+}
+
+static viewport_t *viewport_create(service_id_t sid)
+{
+	errno_t rc;
+	char *vsl_name = NULL;
+	viewport_t *vp = NULL;
+	bool claimed = false;
+
+	rc = loc_service_get_name(sid, &vsl_name);
+	if (rc != EOK)
+		goto error;
+
+	vp = (viewport_t *) calloc(1, sizeof(viewport_t));
+	if (!vp)
+		goto error;
+
+	link_initialize(&vp->link);
+	vp->pos.x = coord_origin;
+	vp->pos.y = coord_origin;
+
+	/* Establish output bidirectional connection. */
+	vp->dsid = sid;
+	vp->sess = vsl_connect(sid, vsl_name);
+	if (vp->sess == NULL)
+		goto error;
+
+	/* Claim the given visualizer. */
+	rc = visualizer_claim(vp->sess, 0);
+	if (rc != EOK) {
+		printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc));
+		goto error;
+	}
+
+	claimed = true;
+
+	/* Retrieve the default mode. */
+	rc = visualizer_get_default_mode(vp->sess, &vp->mode);
+	if (rc != EOK) {
+		printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc));
+		goto error;
+	}
+
+	/* Create surface with respect to the retrieved mode. */
+	vp->surface = surface_create(vp->mode.screen_width, vp->mode.screen_height,
+	    NULL, SURFACE_FLAG_SHARED);
+	if (vp->surface == NULL) {
+		printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc));
+		goto error;
+	}
+
+	/* Try to set the mode and share out the surface. */
+	rc = visualizer_set_mode(vp->sess,
+	    vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
+	if (rc != EOK) {
+		printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc));
+		goto error;
+	}
+
+	return vp;
+error:
+	if (claimed)
+		visualizer_yield(vp->sess);
+
+	if (vp->sess != NULL)
+		async_hangup(vp->sess);
+
+	free(vp);
+	free(vsl_name);
+	return NULL;
+}
+
+static void comp_window_animate(pointer_t *pointer, window_t *win,
+    sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
+{
+	/* window_list_mtx locked by caller */
+	/* pointer_list_mtx locked by caller */
+
+	int dx = pointer->accum.x;
+	int dy = pointer->accum.y;
+	pointer->accum.x = 0;
+	pointer->accum.y = 0;
+
+	bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y);
+	bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y);
+	bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y);
+
+	sysarg_t width, height;
+	surface_get_resolution(win->surface, &width, &height);
+
+	if (move) {
+		double cx = 0;
+		double cy = 0;
+
+		if (pointer->grab_flags & GF_MOVE_X)
+			cx = 1;
+
+		if (pointer->grab_flags & GF_MOVE_Y)
+			cy = 1;
+
+		if (((scale) || (resize)) && (win->angle != 0)) {
+			transform_t rotate;
+			transform_identity(&rotate);
+
+			transform_rotate(&rotate, win->angle);
+			transform_apply_linear(&rotate, &cx, &cy);
+		}
+
+		cx = (cx < 0) ? (-1 * cx) : cx;
+		cy = (cy < 0) ? (-1 * cy) : cy;
+
+		win->dx += (cx * dx);
+		win->dy += (cy * dy);
+	}
+
+	if ((scale) || (resize)) {
+		double _dx = dx;
+		double _dy = dy;
+		if (win->angle != 0) {
+			transform_t unrotate;
+			transform_identity(&unrotate);
+			transform_rotate(&unrotate, -win->angle);
+			transform_apply_linear(&unrotate, &_dx, &_dy);
+		}
+		_dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
+		_dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
+
+		if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
+			double fx = 1.0 + (_dx / ((width - 1) * win->fx));
+			if (fx > 0) {
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+				if (scale)
+					win->fx *= fx;
+#endif
+#if ANIMATE_WINDOW_TRANSFORMS == 1
+				win->fx *= fx;
+#endif
+				scale_back_x *= fx;
+			}
+		}
+
+		if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
+			double fy = 1.0 + (_dy / ((height - 1) * win->fy));
+			if (fy > 0) {
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+				if (scale)
+					win->fy *= fy;
+#endif
+#if ANIMATE_WINDOW_TRANSFORMS == 1
+				win->fy *= fy;
+#endif
+				scale_back_y *= fy;
+			}
+		}
+	}
+
+	sysarg_t x1, y1, width1, height1;
+	sysarg_t x2, y2, width2, height2;
+	comp_coord_bounding_rect(0, 0, width, height, win->transform,
+	    &x1, &y1, &width1, &height1);
+	comp_recalc_transform(win);
+	comp_coord_bounding_rect(0, 0, width, height, win->transform,
+	    &x2, &y2, &width2, &height2);
+	rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+	    dmg_x, dmg_y, dmg_width, dmg_height);
+}
+
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+static void comp_ghost_animate(pointer_t *pointer,
+    desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4)
+{
+	/* window_list_mtx locked by caller */
+	/* pointer_list_mtx locked by caller */
+
+	int dx = pointer->accum_ghost.x;
+	int dy = pointer->accum_ghost.y;
+	pointer->accum_ghost.x = 0;
+	pointer->accum_ghost.y = 0;
+
+	bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y);
+	bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y);
+	bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y);
+
+	sysarg_t width, height;
+	surface_get_resolution(pointer->ghost.surface, &width, &height);
+
+	if (move) {
+		double cx = 0;
+		double cy = 0;
+		if (pointer->grab_flags & GF_MOVE_X) {
+			cx = 1;
+		}
+		if (pointer->grab_flags & GF_MOVE_Y) {
+			cy = 1;
+		}
+
+		if (scale || resize) {
+			transform_t rotate;
+			transform_identity(&rotate);
+			transform_rotate(&rotate, pointer->ghost.angle);
+			transform_apply_linear(&rotate, &cx, &cy);
+		}
+
+		cx = (cx < 0) ? (-1 * cx) : cx;
+		cy = (cy < 0) ? (-1 * cy) : cy;
+
+		pointer->ghost.dx += (cx * dx);
+		pointer->ghost.dy += (cy * dy);
+	}
+
+	if (scale || resize) {
+		double _dx = dx;
+		double _dy = dy;
+		transform_t unrotate;
+		transform_identity(&unrotate);
+		transform_rotate(&unrotate, -pointer->ghost.angle);
+		transform_apply_linear(&unrotate, &_dx, &_dy);
+		_dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
+		_dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
+
+		if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
+			double fx = 1.0 + (_dx / ((width - 1) * pointer->ghost.fx));
+			pointer->ghost.fx *= fx;
+		}
+
+		if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
+			double fy = 1.0 + (_dy / ((height - 1) * pointer->ghost.fy));
+			pointer->ghost.fy *= fy;
+		}
+	}
+
+	sysarg_t x1, y1, width1, height1;
+	sysarg_t x2, y2, width2, height2;
+	comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
+	    &x1, &y1, &width1, &height1);
+	comp_recalc_transform(&pointer->ghost);
+	comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
+	    &x2, &y2, &width2, &height2);
+
+	sysarg_t x_u, y_u, w_u, h_u;
+	rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+	    &x_u, &y_u, &w_u, &h_u);
+
+	sysarg_t x_i, y_i, w_i, h_i;
+	rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2,
+	    &x_i, &y_i, &w_i, &h_i);
+
+	if (w_i == 0 || h_i == 0) {
+		rect1->x = x_u;
+		rect2->x = 0;
+		rect3->x = 0;
+		rect4->x = 0;
+
+		rect1->y = y_u;
+		rect2->y = 0;
+		rect3->y = 0;
+		rect4->y = 0;
+
+		rect1->w = w_u;
+		rect2->w = 0;
+		rect3->w = 0;
+		rect4->w = 0;
+
+		rect1->h = h_u;
+		rect2->h = 0;
+		rect3->h = 0;
+		rect4->h = 0;
+	} else {
+		rect1->x = x_u;
+		rect1->y = y_u;
+		rect1->w = x_i - x_u + 1;
+		rect1->h = h_u;
+
+		rect2->x = x_u;
+		rect2->y = y_u;
+		rect2->w = w_u;
+		rect2->h = y_i - y_u + 1;
+
+		rect3->x = x_i + w_i - 1;
+		rect3->y = y_u;
+		rect3->w = w_u - w_i - x_i + x_u + 1;
+		rect3->h = h_u;
+
+		rect4->x = x_u;
+		rect4->y = y_i + h_i - 1;
+		rect4->w = w_u;
+		rect4->h = h_u - h_i - y_i + y_u + 1;
+	}
+}
+#endif
+
+static errno_t comp_abs_move(input_t *input, unsigned x, unsigned y,
+    unsigned max_x, unsigned max_y)
+{
+	/* XXX TODO Use absolute coordinates directly */
+
+	pointer_t *pointer = input_pointer(input);
+
+	sysarg_t width, height;
+
+	fibril_mutex_lock(&viewport_list_mtx);
+	if (list_empty(&viewport_list)) {
+		printf("No viewport found\n");
+		fibril_mutex_unlock(&viewport_list_mtx);
+		return EOK; /* XXX */
+	}
+	link_t *link = list_first(&viewport_list);
+	viewport_t *vp = list_get_instance(link, viewport_t, link);
+	surface_get_resolution(vp->surface, &width, &height);
+	desktop_point_t vp_pos = vp->pos;
+	fibril_mutex_unlock(&viewport_list_mtx);
+
+	desktop_point_t pos_in_viewport;
+	pos_in_viewport.x = x * width / max_x;
+	pos_in_viewport.y = y * height / max_y;
+
+	/* Calculate offset from pointer */
+	fibril_mutex_lock(&pointer_list_mtx);
+	desktop_vector_t delta;
+	delta.x = (vp_pos.x + pos_in_viewport.x) - pointer->pos.x;
+	delta.y = (vp_pos.y + pos_in_viewport.y) - pointer->pos.y;
+	fibril_mutex_unlock(&pointer_list_mtx);
+
+	return comp_mouse_move(input, delta.x, delta.y);
+}
+
+static errno_t comp_mouse_move(input_t *input, int dx, int dy)
+{
+	pointer_t *pointer = input_pointer(input);
+
+	comp_update_viewport_bound_rect();
+
+	/* Update pointer position. */
+	fibril_mutex_lock(&pointer_list_mtx);
+
+	desktop_point_t old_pos = pointer->pos;
+
+	sysarg_t cursor_width;
+	sysarg_t cursor_height;
+	surface_get_resolution(pointer->cursor.states[pointer->state],
+	    &cursor_width, &cursor_height);
+
+	if (pointer->pos.x + dx < viewport_bound_rect.x)
+		dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
+
+	if (pointer->pos.y + dy < viewport_bound_rect.y)
+		dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
+
+	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w)
+		dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
+
+	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h)
+		dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
+
+	pointer->pos.x += dx;
+	pointer->pos.y += dy;
+	fibril_mutex_unlock(&pointer_list_mtx);
+	comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
+	comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
+
+	fibril_mutex_lock(&window_list_mtx);
+	fibril_mutex_lock(&pointer_list_mtx);
+	window_t *top = (window_t *) list_first(&window_list);
+	if (top && top->surface) {
+
+		if (pointer->grab_flags == GF_EMPTY) {
+			/* Notify top-level window about move event. */
+			bool within_client = false;
+			sysarg_t point_x, point_y;
+			sysarg_t width, height;
+			surface_get_resolution(top->surface, &width, &height);
+			within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
+			    top->transform, width, height, &point_x, &point_y);
+
+			window_event_t *event = NULL;
+			if (within_client) {
+				event = (window_event_t *) malloc(sizeof(window_event_t));
+				if (event) {
+					link_initialize(&event->link);
+					event->type = ET_POSITION_EVENT;
+					event->data.pos.pos_id = pointer->id;
+					event->data.pos.type = POS_UPDATE;
+					event->data.pos.btn_num = pointer->btn_num;
+					event->data.pos.hpos = point_x;
+					event->data.pos.vpos = point_y;
+				}
+			}
+
+			fibril_mutex_unlock(&pointer_list_mtx);
+			fibril_mutex_unlock(&window_list_mtx);
+
+			if (event) {
+				comp_post_event_top(event);
+			}
+
+		} else {
+			/* Pointer is grabbed by top-level window action. */
+			pointer->accum.x += dx;
+			pointer->accum.y += dy;
+			pointer->accum_ghost.x += dx;
+			pointer->accum_ghost.y += dy;
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+			if (pointer->ghost.surface == NULL) {
+				pointer->ghost.surface = top->surface;
+				pointer->ghost.dx = top->dx;
+				pointer->ghost.dy = top->dy;
+				pointer->ghost.fx = top->fx;
+				pointer->ghost.fy = top->fy;
+				pointer->ghost.angle = top->angle;
+				pointer->ghost.transform = top->transform;
+			}
+			desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
+			comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
+#endif
+#if ANIMATE_WINDOW_TRANSFORMS == 1
+			sysarg_t x, y, width, height;
+			comp_window_animate(pointer, top, &x, &y, &width, &height);
+#endif
+			fibril_mutex_unlock(&pointer_list_mtx);
+			fibril_mutex_unlock(&window_list_mtx);
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+			comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
+			comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
+			comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
+			comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
+#endif
+#if ANIMATE_WINDOW_TRANSFORMS == 1
+			comp_damage(x, y, width, height);
+#endif
+		}
+	} else {
+		fibril_mutex_unlock(&pointer_list_mtx);
+		fibril_mutex_unlock(&window_list_mtx);
+	}
+
+	return EOK;
+}
+
+static errno_t comp_mouse_button(input_t *input, int bnum, int bpress)
+{
+	pointer_t *pointer = input_pointer(input);
+
+	fibril_mutex_lock(&window_list_mtx);
+	fibril_mutex_lock(&pointer_list_mtx);
+	window_t *win = NULL;
+	sysarg_t point_x = 0;
+	sysarg_t point_y = 0;
+	sysarg_t width, height;
+	bool within_client = false;
+
+	/* Determine the window which the mouse click belongs to. */
+	list_foreach(window_list, link, window_t, cw) {
+		win = cw;
+		if (win->surface) {
+			surface_get_resolution(win->surface, &width, &height);
+			within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
+			    win->transform, width, height, &point_x, &point_y);
+		}
+		if (within_client) {
+			break;
+		}
+	}
+
+	/* Check whether the window is top-level window. */
+	window_t *top = (window_t *) list_first(&window_list);
+	if (!win || !top) {
+		fibril_mutex_unlock(&pointer_list_mtx);
+		fibril_mutex_unlock(&window_list_mtx);
+		return EOK;
+	}
+
+	window_event_t *event_top = NULL;
+	window_event_t *event_unfocus = NULL;
+	window_t *win_unfocus = NULL;
+	sysarg_t dmg_x, dmg_y;
+	sysarg_t dmg_width = 0;
+	sysarg_t dmg_height = 0;
+
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+	desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
+#endif
+
+	if (bpress && !pointer->pressed) {
+		pointer->btn_pos = pointer->pos;
+		pointer->btn_num = bnum;
+		pointer->pressed = true;
+
+		/* Bring the window to the foreground. */
+		if ((win != top) && within_client) {
+			win_unfocus = (window_t *) list_first(&window_list);
+			list_remove(&win->link);
+			list_prepend(&win->link, &window_list);
+			event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_unfocus) {
+				link_initialize(&event_unfocus->link);
+				event_unfocus->type = ET_WINDOW_UNFOCUS;
+			}
+			comp_coord_bounding_rect(0, 0, width, height, win->transform,
+			    &dmg_x, &dmg_y, &dmg_width, &dmg_height);
+		}
+
+		/* Notify top-level window about mouse press. */
+		if (within_client) {
+			event_top = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_top) {
+				link_initialize(&event_top->link);
+				event_top->type = ET_POSITION_EVENT;
+				event_top->data.pos.pos_id = pointer->id;
+				event_top->data.pos.type = POS_PRESS;
+				event_top->data.pos.btn_num = bnum;
+				event_top->data.pos.hpos = point_x;
+				event_top->data.pos.vpos = point_y;
+			}
+			pointer->grab_flags = GF_EMPTY;
+		}
+
+	} else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
+		pointer->pressed = false;
+
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+		sysarg_t pre_x = 0;
+		sysarg_t pre_y = 0;
+		sysarg_t pre_width = 0;
+		sysarg_t pre_height = 0;
+
+		if (pointer->grab_flags != GF_EMPTY) {
+			if (pointer->ghost.surface) {
+				comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
+				pointer->ghost.surface = NULL;
+			}
+			comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height);
+			dmg_x = pre_x;
+			dmg_y = pre_y;
+			dmg_width = pre_width;
+			dmg_height = pre_height;
+		}
+#endif
+
+		if ((pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y)) {
+
+			surface_get_resolution(top->surface, &width, &height);
+#if ANIMATE_WINDOW_TRANSFORMS == 1
+			top->fx *= (1.0 / scale_back_x);
+			top->fy *= (1.0 / scale_back_y);
+			comp_recalc_transform(top);
+#endif
+
+			/* Commit proper resize action. */
+			event_top = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_top) {
+				link_initialize(&event_top->link);
+				event_top->type = ET_WINDOW_RESIZE;
+
+				event_top->data.resize.offset_x = 0;
+				event_top->data.resize.offset_y = 0;
+
+				int dx = (int) (((double) width) * (scale_back_x - 1.0));
+				int dy = (int) (((double) height) * (scale_back_y - 1.0));
+
+				if (pointer->grab_flags & GF_RESIZE_X)
+					event_top->data.resize.width =
+					    ((((int) width) + dx) >= 0) ? (width + dx) : 0;
+				else
+					event_top->data.resize.width = width;
+
+				if (pointer->grab_flags & GF_RESIZE_Y)
+					event_top->data.resize.height =
+					    ((((int) height) + dy) >= 0) ? (height + dy) : 0;
+				else
+					event_top->data.resize.height = height;
+
+				event_top->data.resize.placement_flags =
+				    WINDOW_PLACEMENT_ANY;
+			}
+
+			pointer->grab_flags = GF_EMPTY;
+
+		} else if (within_client && (pointer->grab_flags == GF_EMPTY) && (top == win)) {
+
+			/* Notify top-level window about mouse release. */
+			event_top = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_top) {
+				link_initialize(&event_top->link);
+				event_top->type = ET_POSITION_EVENT;
+				event_top->data.pos.pos_id = pointer->id;
+				event_top->data.pos.type = POS_RELEASE;
+				event_top->data.pos.btn_num = bnum;
+				event_top->data.pos.hpos = point_x;
+				event_top->data.pos.vpos = point_y;
+			}
+			pointer->grab_flags = GF_EMPTY;
+
+		} else {
+			pointer->grab_flags = GF_EMPTY;
+		}
+
+	}
+
+	fibril_mutex_unlock(&pointer_list_mtx);
+	fibril_mutex_unlock(&window_list_mtx);
+
+#if ANIMATE_WINDOW_TRANSFORMS == 0
+	comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
+	comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
+	comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
+	comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
+#endif
+
+	if (dmg_width > 0 && dmg_height > 0) {
+		comp_damage(dmg_x, dmg_y, dmg_width, dmg_height);
+	}
+
+	if (event_unfocus && win_unfocus) {
+		comp_post_event_win(event_unfocus, win_unfocus);
+	}
+
+	if (event_top) {
+		comp_post_event_top(event_top);
+	}
+
+	return EOK;
+}
+
+static errno_t comp_active(input_t *input)
+{
+	active = true;
+	comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
+
+	return EOK;
+}
+
+static errno_t comp_deactive(input_t *input)
+{
+	active = false;
+	return EOK;
+}
+
+static errno_t comp_key_press(input_t *input, kbd_event_type_t type, keycode_t key,
+    keymod_t mods, char32_t c)
+{
+	bool win_transform = (mods & KM_ALT) &&
+	    (key == KC_W || key == KC_S || key == KC_A || key == KC_D ||
+	    key == KC_Q || key == KC_E || key == KC_R || key == KC_F);
+	bool win_resize = (mods & KM_ALT) &&
+	    (key == KC_T || key == KC_G || key == KC_B || key == KC_N);
+	bool win_opacity = (mods & KM_ALT) && (key == KC_C || key == KC_V);
+	bool win_close = (mods & KM_ALT) && (key == KC_X);
+	bool win_switch = (mods & KM_ALT) && (key == KC_TAB);
+	bool viewport_move = (mods & KM_ALT) &&
+	    (key == KC_I || key == KC_K || key == KC_J || key == KC_L);
+	bool viewport_change = (mods & KM_ALT) && (key == KC_O || key == KC_P);
+	bool kconsole_switch = (key == KC_PAUSE) || (key == KC_BREAK);
+	bool filter_switch = (mods & KM_ALT) && (key == KC_Y);
+
+	bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
+	    win_opacity || win_close || win_switch || viewport_move ||
+	    viewport_change || kconsole_switch || filter_switch);
+
+	if (key_filter) {
+		/* no-op */
+	} else if (win_transform) {
+		fibril_mutex_lock(&window_list_mtx);
+		window_t *win = (window_t *) list_first(&window_list);
+		if (win && win->surface) {
+			switch (key) {
+			case KC_W:
+				win->dy += -20;
+				break;
+			case KC_S:
+				win->dy += 20;
+				break;
+			case KC_A:
+				win->dx += -20;
+				break;
+			case KC_D:
+				win->dx += 20;
+				break;
+			case KC_Q:
+				win->angle += 0.1;
+				break;
+			case KC_E:
+				win->angle -= 0.1;
+				break;
+			case KC_R:
+				win->fx *= 0.95;
+				win->fy *= 0.95;
+				break;
+			case KC_F:
+				win->fx *= 1.05;
+				win->fy *= 1.05;
+				break;
+			default:
+				break;
+			}
+
+			/* Transform the window and calculate damage. */
+			sysarg_t x, y, width, height;
+			surface_get_resolution(win->surface, &width, &height);
+			sysarg_t x1, y1, width1, height1;
+			sysarg_t x2, y2, width2, height2;
+			comp_coord_bounding_rect(0, 0, width, height, win->transform,
+			    &x1, &y1, &width1, &height1);
+			comp_recalc_transform(win);
+			comp_coord_bounding_rect(0, 0, width, height, win->transform,
+			    &x2, &y2, &width2, &height2);
+			rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+			    &x, &y, &width, &height);
+			fibril_mutex_unlock(&window_list_mtx);
+
+			comp_damage(x, y, width, height);
+		} else {
+			fibril_mutex_unlock(&window_list_mtx);
+		}
+	} else if (win_resize) {
+		fibril_mutex_lock(&window_list_mtx);
+		window_t *win = (window_t *) list_first(&window_list);
+		if ((win) && (win->surface) && (win->flags & WINDOW_RESIZEABLE)) {
+			window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event == NULL) {
+				fibril_mutex_unlock(&window_list_mtx);
+				return ENOMEM;
+			}
+
+			sysarg_t width, height;
+			surface_get_resolution(win->surface, &width, &height);
+
+			link_initialize(&event->link);
+			event->type = ET_WINDOW_RESIZE;
+
+			event->data.resize.offset_x = 0;
+			event->data.resize.offset_y = 0;
+
+			switch (key) {
+			case KC_T:
+				event->data.resize.width = width;
+				event->data.resize.height = (height >= 20) ? height - 20 : 0;
+				break;
+			case KC_G:
+				event->data.resize.width = width;
+				event->data.resize.height = height + 20;
+				break;
+			case KC_B:
+				event->data.resize.width = (width >= 20) ? width - 20 : 0;
+				event->data.resize.height = height;
+				break;
+			case KC_N:
+				event->data.resize.width = width + 20;
+				event->data.resize.height = height;
+				break;
+			default:
+				event->data.resize.width = 0;
+				event->data.resize.height = 0;
+				break;
+			}
+
+			event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
+
+			fibril_mutex_unlock(&window_list_mtx);
+			comp_post_event_top(event);
+		} else {
+			fibril_mutex_unlock(&window_list_mtx);
+		}
+	} else if (win_opacity) {
+		fibril_mutex_lock(&window_list_mtx);
+		window_t *win = (window_t *) list_first(&window_list);
+		if (win && win->surface) {
+			switch (key) {
+			case KC_C:
+				if (win->opacity > 0) {
+					win->opacity -= 5;
+				}
+				break;
+			case KC_V:
+				if (win->opacity < 255) {
+					win->opacity += 5;
+				}
+				break;
+			default:
+				break;
+			}
+
+			/* Calculate damage. */
+			sysarg_t x, y, width, height;
+			surface_get_resolution(win->surface, &width, &height);
+			comp_coord_bounding_rect(0, 0, width, height, win->transform,
+			    &x, &y, &width, &height);
+			fibril_mutex_unlock(&window_list_mtx);
+
+			comp_damage(x, y, width, height);
+		} else {
+			fibril_mutex_unlock(&window_list_mtx);
+		}
+	} else if (win_close) {
+		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+		if (event == NULL)
+			return ENOMEM;
+
+		link_initialize(&event->link);
+		event->type = ET_WINDOW_CLOSE;
+
+		comp_post_event_top(event);
+	} else if (win_switch) {
+		fibril_mutex_lock(&window_list_mtx);
+		if (!list_empty(&window_list)) {
+			window_t *win1 = (window_t *) list_first(&window_list);
+			list_remove(&win1->link);
+			list_append(&win1->link, &window_list);
+			window_t *win2 = (window_t *) list_first(&window_list);
+
+			window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event1) {
+				link_initialize(&event1->link);
+				event1->type = ET_WINDOW_UNFOCUS;
+			}
+
+			window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event2) {
+				link_initialize(&event2->link);
+				event2->type = ET_WINDOW_FOCUS;
+			}
+
+			sysarg_t x1 = 0;
+			sysarg_t y1 = 0;
+			sysarg_t width1 = 0;
+			sysarg_t height1 = 0;
+			if (win1->surface) {
+				sysarg_t width, height;
+				surface_get_resolution(win1->surface, &width, &height);
+				comp_coord_bounding_rect(0, 0, width, height, win1->transform,
+				    &x1, &y1, &width1, &height1);
+			}
+
+			sysarg_t x2 = 0;
+			sysarg_t y2 = 0;
+			sysarg_t width2 = 0;
+			sysarg_t height2 = 0;
+			if (win2->surface) {
+				sysarg_t width, height;
+				surface_get_resolution(win2->surface, &width, &height);
+				comp_coord_bounding_rect(0, 0, width, height, win2->transform,
+				    &x2, &y2, &width2, &height2);
+			}
+
+			sysarg_t x, y, width, height;
+			rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+			    &x, &y, &width, &height);
+
+			fibril_mutex_unlock(&window_list_mtx);
+
+			if (event1 && win1) {
+				comp_post_event_win(event1, win1);
+			}
+
+			if (event2 && win2) {
+				comp_post_event_win(event2, win2);
+			}
+
+			comp_damage(x, y, width, height);
+		} else {
+			fibril_mutex_unlock(&window_list_mtx);
+		}
+	} else if (viewport_move) {
+		fibril_mutex_lock(&viewport_list_mtx);
+		viewport_t *vp = (viewport_t *) list_first(&viewport_list);
+		if (vp) {
+			switch (key) {
+			case KC_I:
+				vp->pos.x += 0;
+				vp->pos.y += -20;
+				break;
+			case KC_K:
+				vp->pos.x += 0;
+				vp->pos.y += 20;
+				break;
+			case KC_J:
+				vp->pos.x += -20;
+				vp->pos.y += 0;
+				break;
+			case KC_L:
+				vp->pos.x += 20;
+				vp->pos.y += 0;
+				break;
+			default:
+				vp->pos.x += 0;
+				vp->pos.y += 0;
+				break;
+			}
+
+			sysarg_t x = vp->pos.x;
+			sysarg_t y = vp->pos.y;
+			sysarg_t width, height;
+			surface_get_resolution(vp->surface, &width, &height);
+			fibril_mutex_unlock(&viewport_list_mtx);
+
+			comp_restrict_pointers();
+			comp_damage(x, y, width, height);
+		} else {
+			fibril_mutex_unlock(&viewport_list_mtx);
+		}
+	} else if (viewport_change) {
+		fibril_mutex_lock(&viewport_list_mtx);
+
+		viewport_t *vp;
+		switch (key) {
+		case KC_O:
+			vp = (viewport_t *) list_first(&viewport_list);
+			if (vp) {
+				list_remove(&vp->link);
+				list_append(&vp->link, &viewport_list);
+			}
+			break;
+		case KC_P:
+			vp = (viewport_t *) list_last(&viewport_list);
+			if (vp) {
+				list_remove(&vp->link);
+				list_prepend(&vp->link, &viewport_list);
+			}
+			break;
+		default:
+			break;
+		}
+
+		fibril_mutex_unlock(&viewport_list_mtx);
+	} else if (kconsole_switch) {
+		if (console_kcon())
+			active = false;
+	} else if (filter_switch) {
+		filter_index++;
+		if (filter_index > 1)
+			filter_index = 0;
+		if (filter_index == 0) {
+			filter = filter_nearest;
+		} else {
+			filter = filter_bilinear;
+		}
+		comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
+	} else {
+		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+		if (event == NULL)
+			return ENOMEM;
+
+		link_initialize(&event->link);
+		event->type = ET_KEYBOARD_EVENT;
+		event->data.kbd.type = type;
+		event->data.kbd.key = key;
+		event->data.kbd.mods = mods;
+		event->data.kbd.c = c;
+
+		comp_post_event_top(event);
+	}
+
+	return EOK;
+}
+
+static errno_t input_connect(const char *svc)
+{
+	async_sess_t *sess;
+	service_id_t dsid;
+
+	errno_t rc = loc_service_get_id(svc, &dsid, 0);
+	if (rc != EOK) {
+		printf("%s: Input service %s not found\n", NAME, svc);
+		return rc;
+	}
+
+	sess = loc_service_connect(dsid, INTERFACE_INPUT, 0);
+	if (sess == NULL) {
+		printf("%s: Unable to connect to input service %s\n", NAME,
+		    svc);
+		return EIO;
+	}
+
+	fibril_mutex_lock(&pointer_list_mtx);
+	pointer_t *pointer = pointer_create();
+	if (pointer != NULL) {
+		pointer->id = pointer_id++;
+		list_append(&pointer->link, &pointer_list);
+	}
+	fibril_mutex_unlock(&pointer_list_mtx);
+
+	if (pointer == NULL) {
+		printf("%s: Cannot create pointer.\n", NAME);
+		async_hangup(sess);
+		return ENOMEM;
+	}
+
+	rc = input_open(sess, &input_ev_ops, pointer, &input);
+	if (rc != EOK) {
+		async_hangup(sess);
+		printf("%s: Unable to communicate with service %s (%s)\n",
+		    NAME, svc, str_error(rc));
+		return rc;
+	}
+
+	return EOK;
+}
+
+static void input_disconnect(void)
+{
+	pointer_t *pointer = input->user;
+	input_close(input);
+	pointer_destroy(pointer);
+}
+
+static void discover_viewports(void)
+{
+	fibril_mutex_lock(&discovery_mtx);
+
+	/* Create viewports and connect them to visualizers. */
+	category_id_t cat_id;
+	errno_t rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
+	if (rc != EOK)
+		goto ret;
+
+	service_id_t *svcs;
+	size_t svcs_cnt = 0;
+	rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
+	if (rc != EOK)
+		goto ret;
+
+	fibril_mutex_lock(&viewport_list_mtx);
+	for (size_t i = 0; i < svcs_cnt; ++i) {
+		bool exists = false;
+		list_foreach(viewport_list, link, viewport_t, vp) {
+			if (vp->dsid == svcs[i]) {
+				exists = true;
+				break;
+			}
+		}
+
+		if (exists)
+			continue;
+
+		viewport_t *vp = viewport_create(svcs[i]);
+		if (vp != NULL)
+			list_append(&vp->link, &viewport_list);
+	}
+	fibril_mutex_unlock(&viewport_list_mtx);
+
+	if (!list_empty(&viewport_list))
+		input_activate(input);
+
+ret:
+	fibril_mutex_unlock(&discovery_mtx);
+}
+
+static void category_change_cb(void *arg)
+{
+	discover_viewports();
+}
+
+static errno_t compositor_srv_init(char *input_svc, char *name)
+{
+	/* Coordinates of the central pixel. */
+	coord_origin = UINT32_MAX / 4;
+
+	/* Color of the viewport background. Must be opaque. */
+	bg_color = PIXEL(255, 69, 51, 103);
+
+	/* Register compositor server. */
+	async_set_fallback_port_handler(client_connection, NULL);
+
+	errno_t rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
+		return -1;
+	}
+
+	server_name = name;
+
+	char svc[LOC_NAME_MAXLEN + 1];
+	snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name);
+
+	service_id_t service_id;
+	rc = loc_service_register(svc, &service_id);
+	if (rc != EOK) {
+		printf("%s: Unable to register service %s\n", NAME, svc);
+		return rc;
+	}
+
+	/* Prepare window registrator (entrypoint for clients). */
+	char winreg[LOC_NAME_MAXLEN + 1];
+	snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name);
+	if (loc_service_register(winreg, &winreg_id) != EOK) {
+		printf("%s: Unable to register service %s\n", NAME, winreg);
+		return -1;
+	}
+
+	/* Establish input bidirectional connection. */
+	rc = input_connect(input_svc);
+	if (rc != EOK) {
+		printf("%s: Failed to connect to input service.\n", NAME);
+		return rc;
+	}
+
+	rc = loc_register_cat_change_cb(category_change_cb, NULL);
+	if (rc != EOK) {
+		printf("%s: Failed to register category change callback\n", NAME);
+		input_disconnect();
+		return rc;
+	}
+
+	discover_viewports();
+
+	comp_restrict_pointers();
+	comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
+
+	return EOK;
+}
+
+static void usage(char *name)
+{
+	printf("Usage: %s <input_dev> <server_name>\n", name);
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc < 3) {
+		usage(argv[0]);
+		return 1;
+	}
+
+	printf("%s: HelenOS Compositor server\n", NAME);
+
+	errno_t rc = compositor_srv_init(argv[1], argv[2]);
+	if (rc != EOK)
+		return rc;
+
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
+	async_manager();
+
+	/* Never reached */
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/srv/hid/compositor/compositor.h
===================================================================
--- uspace/srv/hid/compositor/compositor.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/srv/hid/compositor/compositor.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 Petr Koupy
+ * 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 compositor
+ * @{
+ */
+/** @file
+ */
+
+#ifndef COMPOSITOR_COMPOSITOR_H_
+#define COMPOSITOR_COMPOSITOR_H_
+
+typedef native_t desktop_coord_t;
+
+typedef struct {
+	desktop_coord_t x;
+	desktop_coord_t y;
+} desktop_point_t;
+
+typedef desktop_point_t desktop_vector_t;
+
+typedef struct {
+	desktop_coord_t x;
+	desktop_coord_t y;
+	desktop_coord_t w;
+	desktop_coord_t h;
+} desktop_rect_t;
+
+/* TODO remove? */
+typedef struct {
+	double x;
+	double y;
+} double_point_t;
+
+typedef double_point_t double_vector_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/hid/compositor/doc/doxygroups.h
===================================================================
--- uspace/srv/hid/compositor/doc/doxygroups.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/srv/hid/compositor/doc/doxygroups.h	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,4 @@
+/** @addtogroup compositor compositor
+ * @ingroup srvs
+ * @brief GUI server
+ */
Index: uspace/srv/hid/compositor/meson.build
===================================================================
--- uspace/srv/hid/compositor/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
+++ uspace/srv/hid/compositor/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2012 Petr Koupy
+# 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.
+#
+
+deps = [ 'draw', 'softrend', 'drv', 'compress', 'math' ]
+src = files('compositor.c')
Index: pace/srv/hid/display/client.c
===================================================================
--- uspace/srv/hid/display/client.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,372 +1,0 @@
-/*
- * Copyright (c) 2019 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 client
- */
-
-#include <adt/list.h>
-#include <errno.h>
-#include <stdlib.h>
-#include "client.h"
-#include "display.h"
-#include "seat.h"
-#include "window.h"
-
-/** Create client.
- *
- * @param display Parent display
- * @param cb Client callbacks
- * @param cb_arg Callback argument
- * @param rclient Place to store pointer to new client.
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t ds_client_create(ds_display_t *display, ds_client_cb_t *cb,
-    void *cb_arg, ds_client_t **rclient)
-{
-	ds_client_t *client;
-
-	client = calloc(1, sizeof(ds_client_t));
-	if (client == NULL)
-		return ENOMEM;
-
-	list_initialize(&client->windows);
-	list_initialize(&client->events);
-	client->cb = cb;
-	client->cb_arg = cb_arg;
-
-	ds_display_add_client(display, client);
-
-	*rclient = client;
-	return EOK;
-}
-
-/** Destroy client.
- *
- * @param client Client
- */
-void ds_client_destroy(ds_client_t *client)
-{
-	ds_window_t *window;
-
-	window = ds_client_first_window(client);
-	while (window != NULL) {
-		ds_window_destroy(window);
-		window = ds_client_first_window(client);
-	}
-
-	assert(list_empty(&client->windows));
-	ds_display_remove_client(client);
-	free(client);
-}
-
-/** Add window to client.
- *
- * @param client client
- * @param wnd Window
- */
-void ds_client_add_window(ds_client_t *client, ds_window_t *wnd)
-{
-	assert(wnd->client == NULL);
-	assert(!link_used(&wnd->lcwindows));
-
-	wnd->client = client;
-	wnd->id = client->display->next_wnd_id++;
-	list_append(&wnd->lcwindows, &client->windows);
-}
-
-/** Remove window from client.
- *
- * @param wnd Window
- */
-void ds_client_remove_window(ds_window_t *wnd)
-{
-	ds_seat_t *seat;
-
-	/* Make sure window is no longer focused in any seat */
-	seat = ds_display_first_seat(wnd->display);
-	while (seat != NULL) {
-		ds_seat_evac_focus(seat, wnd);
-		seat = ds_display_next_seat(seat);
-	}
-
-	list_remove(&wnd->lcwindows);
-	wnd->client = NULL;
-}
-
-/** Find window by ID.
- *
- * @param client Client
- * @param id Window ID
- */
-ds_window_t *ds_client_find_window(ds_client_t *client, ds_wnd_id_t id)
-{
-	ds_window_t *wnd;
-
-	// TODO Make this faster
-	wnd = ds_client_first_window(client);
-	while (wnd != NULL) {
-		if (wnd->id == id)
-			return wnd;
-		wnd = ds_client_next_window(wnd);
-	}
-
-	return NULL;
-}
-
-/** Get first window in client.
- *
- * @param client Client
- * @return First window or @c NULL if there is none
- */
-ds_window_t *ds_client_first_window(ds_client_t *client)
-{
-	link_t *link = list_first(&client->windows);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_window_t, lcwindows);
-}
-
-/** Get next window in client.
- *
- * @param wnd Current window
- * @return Next window or @c NULL if there is none
- */
-ds_window_t *ds_client_next_window(ds_window_t *wnd)
-{
-	link_t *link = list_next(&wnd->lcwindows, &wnd->client->windows);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_window_t, lcwindows);
-}
-
-/** Get next event from client event queue.
- *
- * @param client Client
- * @param ewindow Place to store pointer to window receiving the event
- * @param event Place to store event
- * @return Graphic context
- */
-errno_t ds_client_get_event(ds_client_t *client, ds_window_t **ewindow,
-    display_wnd_ev_t *event)
-{
-	link_t *link;
-	ds_window_ev_t *wevent;
-
-	link = list_first(&client->events);
-	if (link == NULL)
-		return ENOENT;
-
-	wevent = list_get_instance(link, ds_window_ev_t, levents);
-	list_remove(link);
-
-	*ewindow = wevent->window;
-	*event = wevent->event;
-	free(wevent);
-	return EOK;
-}
-
-/** Post close event to the client's message queue.
- *
- * @param client Client
- * @param ewindow Window that the message is targetted to
- *
- * @return EOK on success or an error code
- */
-errno_t ds_client_post_close_event(ds_client_t *client, ds_window_t *ewindow)
-{
-	ds_window_ev_t *wevent;
-
-	wevent = calloc(1, sizeof(ds_window_ev_t));
-	if (wevent == NULL)
-		return ENOMEM;
-
-	wevent->window = ewindow;
-	wevent->event.etype = wev_close;
-	list_append(&wevent->levents, &client->events);
-
-	/* Notify the client */
-	// TODO Do not send more than once until client drains the queue
-	if (client->cb != NULL && client->cb->ev_pending != NULL)
-		client->cb->ev_pending(client->cb_arg);
-
-	return EOK;
-}
-
-/** Post focus event to the client's message queue.
- *
- * @param client Client
- * @param ewindow Window that the message is targetted to
- *
- * @return EOK on success or an error code
- */
-errno_t ds_client_post_focus_event(ds_client_t *client, ds_window_t *ewindow)
-{
-	ds_window_ev_t *wevent;
-
-	wevent = calloc(1, sizeof(ds_window_ev_t));
-	if (wevent == NULL)
-		return ENOMEM;
-
-	wevent->window = ewindow;
-	wevent->event.etype = wev_focus;
-	list_append(&wevent->levents, &client->events);
-
-	/* Notify the client */
-	// TODO Do not send more than once until client drains the queue
-	if (client->cb != NULL && client->cb->ev_pending != NULL)
-		client->cb->ev_pending(client->cb_arg);
-
-	return EOK;
-}
-
-/** Post keyboard event to the client's message queue.
- *
- * @param client Client
- * @param ewindow Window that the message is targetted to
- * @param event Event
- *
- * @return EOK on success or an error code
- */
-errno_t ds_client_post_kbd_event(ds_client_t *client, ds_window_t *ewindow,
-    kbd_event_t *event)
-{
-	ds_window_ev_t *wevent;
-
-	wevent = calloc(1, sizeof(ds_window_ev_t));
-	if (wevent == NULL)
-		return ENOMEM;
-
-	wevent->window = ewindow;
-	wevent->event.etype = wev_kbd;
-	wevent->event.ev.kbd = *event;
-	list_append(&wevent->levents, &client->events);
-
-	/* Notify the client */
-	// TODO Do not send more than once until client drains the queue
-	client->cb->ev_pending(client->cb_arg);
-
-	return EOK;
-}
-
-/** Post position event to the client's message queue.
- *
- * @param client Client
- * @param ewindow Window that the message is targetted to
- * @param event Event
- *
- * @return EOK on success or an error code
- */
-errno_t ds_client_post_pos_event(ds_client_t *client, ds_window_t *ewindow,
-    pos_event_t *event)
-{
-	ds_window_ev_t *wevent;
-
-	wevent = calloc(1, sizeof(ds_window_ev_t));
-	if (wevent == NULL)
-		return ENOMEM;
-
-	wevent->window = ewindow;
-	wevent->event.etype = wev_pos;
-	wevent->event.ev.pos = *event;
-	list_append(&wevent->levents, &client->events);
-
-	/* Notify the client */
-	// TODO Do not send more than once until client drains the queue
-	if (client->cb != NULL && client->cb->ev_pending != NULL)
-		client->cb->ev_pending(client->cb_arg);
-
-	return EOK;
-}
-
-/** Post resize event to the client's message queue.
- *
- * @param client Client
- * @param ewindow Window that the message is targetted to
- * @param rect New window rectangle
- *
- * @return EOK on success or an error code
- */
-errno_t ds_client_post_resize_event(ds_client_t *client, ds_window_t *ewindow,
-    gfx_rect_t *rect)
-{
-	ds_window_ev_t *wevent;
-
-	wevent = calloc(1, sizeof(ds_window_ev_t));
-	if (wevent == NULL)
-		return ENOMEM;
-
-	wevent->window = ewindow;
-	wevent->event.etype = wev_resize;
-	wevent->event.ev.resize.rect = *rect;
-	list_append(&wevent->levents, &client->events);
-
-	/* Notify the client */
-	// TODO Do not send more than once until client drains the queue
-	if (client->cb != NULL && client->cb->ev_pending != NULL)
-		client->cb->ev_pending(client->cb_arg);
-
-	return EOK;
-}
-
-/** Post unfocus event to the client's message queue.
- *
- * @param client Client
- * @param ewindow Window that the message is targetted to
- *
- * @return EOK on success or an error code
- */
-errno_t ds_client_post_unfocus_event(ds_client_t *client, ds_window_t *ewindow)
-{
-	ds_window_ev_t *wevent;
-
-	wevent = calloc(1, sizeof(ds_window_ev_t));
-	if (wevent == NULL)
-		return ENOMEM;
-
-	wevent->window = ewindow;
-	wevent->event.etype = wev_unfocus;
-	list_append(&wevent->levents, &client->events);
-
-	/* Notify the client */
-	// TODO Do not send more than once until client drains the queue
-	if (client->cb != NULL && client->cb->ev_pending != NULL)
-		client->cb->ev_pending(client->cb_arg);
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/srv/hid/display/client.h
===================================================================
--- uspace/srv/hid/display/client.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,68 +1,0 @@
-/*
- * Copyright (c) 2019 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 client
- */
-
-#ifndef CLIENT_H
-#define CLIENT_H
-
-#include <errno.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-#include "types/display/client.h"
-#include "types/display/display.h"
-
-extern errno_t ds_client_create(ds_display_t *, ds_client_cb_t *, void *,
-    ds_client_t **);
-extern void ds_client_destroy(ds_client_t *);
-extern void ds_client_add_window(ds_client_t *, ds_window_t *);
-extern void ds_client_remove_window(ds_window_t *);
-extern ds_window_t *ds_client_find_window(ds_client_t *, ds_wnd_id_t);
-extern ds_window_t *ds_client_first_window(ds_client_t *);
-extern ds_window_t *ds_client_next_window(ds_window_t *);
-extern errno_t ds_client_get_event(ds_client_t *, ds_window_t **,
-    display_wnd_ev_t *);
-extern errno_t ds_client_post_close_event(ds_client_t *, ds_window_t *);
-extern errno_t ds_client_post_focus_event(ds_client_t *, ds_window_t *);
-extern errno_t ds_client_post_kbd_event(ds_client_t *, ds_window_t *,
-    kbd_event_t *);
-extern errno_t ds_client_post_pos_event(ds_client_t *, ds_window_t *,
-    pos_event_t *);
-extern errno_t ds_client_post_resize_event(ds_client_t *, ds_window_t *,
-    gfx_rect_t *);
-extern errno_t ds_client_post_unfocus_event(ds_client_t *, ds_window_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/clonegc.c
===================================================================
--- uspace/srv/hid/display/clonegc.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,534 +1,0 @@
-/*
- * Copyright (c) 2020 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 Cloning graphics context
- *
- * This implements a graphics context that duplicates rendering to a number
- * of GCs.
- */
-
-#include <assert.h>
-#include <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <stdlib.h>
-#include "clonegc.h"
-
-static errno_t ds_clonegc_set_color(void *, gfx_color_t *);
-static errno_t ds_clonegc_fill_rect(void *, gfx_rect_t *);
-static errno_t ds_clonegc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t ds_clonegc_bitmap_destroy(void *);
-static errno_t ds_clonegc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t ds_clonegc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static ds_clonegc_output_t *ds_clonegc_first_output(ds_clonegc_t *);
-static ds_clonegc_output_t *ds_clonegc_next_output(ds_clonegc_output_t *);
-static ds_clonegc_bitmap_t *ds_clonegc_first_bitmap(ds_clonegc_t *);
-static ds_clonegc_bitmap_t *ds_clonegc_next_bitmap(ds_clonegc_bitmap_t *);
-static ds_clonegc_outbitmap_t *ds_clonegc_bitmap_first_obm(ds_clonegc_bitmap_t *);
-static ds_clonegc_outbitmap_t *ds_clonegc_bitmap_next_obm(ds_clonegc_outbitmap_t *);
-static errno_t ds_clonegc_outbitmap_create(ds_clonegc_output_t *,
-    ds_clonegc_bitmap_t *, gfx_bitmap_t *);
-static errno_t ds_clonegc_outbitmap_destroy(ds_clonegc_outbitmap_t *);
-static errno_t ds_clonegc_bitmap_add_output(ds_clonegc_bitmap_t *,
-    ds_clonegc_output_t *);
-
-gfx_context_ops_t ds_clonegc_ops = {
-	.set_color = ds_clonegc_set_color,
-	.fill_rect = ds_clonegc_fill_rect,
-	.bitmap_create = ds_clonegc_bitmap_create,
-	.bitmap_destroy = ds_clonegc_bitmap_destroy,
-	.bitmap_render = ds_clonegc_bitmap_render,
-	.bitmap_get_alloc = ds_clonegc_bitmap_get_alloc
-};
-
-/** Set color on clone GC.
- *
- * Set drawing color on memory GC.
- *
- * @param arg Clone GC
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t ds_clonegc_set_color(void *arg, gfx_color_t *color)
-{
-	ds_clonegc_t *cgc = (ds_clonegc_t *)arg;
-	ds_clonegc_output_t *output;
-	errno_t rc;
-
-	output = ds_clonegc_first_output(cgc);
-	while (output != NULL) {
-		rc = gfx_set_color(output->gc, color);
-		if (rc != EOK)
-			return rc;
-
-		output = ds_clonegc_next_output(output);
-	}
-
-	return EOK;
-}
-
-/** Fill rectangle on clone GC.
- *
- * @param arg Clone GC
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t ds_clonegc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	ds_clonegc_t *cgc = (ds_clonegc_t *)arg;
-	ds_clonegc_output_t *output;
-	errno_t rc;
-
-	output = ds_clonegc_first_output(cgc);
-	while (output != NULL) {
-		rc = gfx_fill_rect(output->gc, rect);
-		if (rc != EOK)
-			return rc;
-
-		output = ds_clonegc_next_output(output);
-	}
-
-	return EOK;
-}
-
-/** Create cloning GC.
- *
- * Create graphics context for copying rendering into several GCs.
- *
- * @param outgc Primary output GC
- * @param rgc Place to store pointer to new clone GC
- *
- * @return EOK on success or an error code
- */
-errno_t ds_clonegc_create(gfx_context_t *outgc, ds_clonegc_t **rgc)
-{
-	ds_clonegc_t *cgc = NULL;
-	gfx_context_t *gc = NULL;
-	errno_t rc;
-
-	cgc = calloc(1, sizeof(ds_clonegc_t));
-	if (cgc == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	rc = gfx_context_new(&ds_clonegc_ops, cgc, &gc);
-	if (rc != EOK)
-		goto error;
-
-	cgc->gc = gc;
-	list_initialize(&cgc->outputs);
-	list_initialize(&cgc->bitmaps);
-
-	if (outgc != NULL) {
-		rc = ds_clonegc_add_output(cgc, outgc);
-		if (rc != EOK)
-			goto error;
-	}
-
-	*rgc = cgc;
-	return EOK;
-error:
-	if (cgc != NULL)
-		free(cgc);
-	if (gc != NULL)
-		gfx_context_delete(gc);
-	return rc;
-}
-
-/** Delete cloning GC.
- *
- * @param cgc Cloning GC
- */
-errno_t ds_clonegc_delete(ds_clonegc_t *cgc)
-{
-	errno_t rc;
-
-	rc = gfx_context_delete(cgc->gc);
-	if (rc != EOK)
-		return rc;
-
-	free(cgc);
-	return EOK;
-}
-
-/** Add new output to cloning GC.
- *
- * @param cgc Cloning GC
- * @param outgc New output GC
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t ds_clonegc_add_output(ds_clonegc_t *cgc, gfx_context_t *outgc)
-{
-	ds_clonegc_output_t *output;
-	ds_clonegc_bitmap_t *cbm;
-	errno_t rc;
-
-	output = calloc(1, sizeof(ds_clonegc_output_t));
-	if (output == NULL)
-		return ENOMEM;
-
-	output->clonegc = cgc;
-	list_append(&output->loutputs, &cgc->outputs);
-	output->gc = outgc;
-	list_initialize(&output->obitmaps);
-
-	/* Extend each existing bitmap to the new output */
-	cbm = ds_clonegc_first_bitmap(cgc);
-	while (cbm != NULL) {
-		rc = ds_clonegc_bitmap_add_output(cbm, output);
-		if (rc != EOK)
-			goto error;
-
-		cbm = ds_clonegc_next_bitmap(cbm);
-	}
-
-	return EOK;
-error:
-	list_remove(&output->loutputs);
-	free(output);
-	return rc;
-}
-
-/** Get generic graphic context from clone GC.
- *
- * @param cgc Clone GC
- * @return Graphic context
- */
-gfx_context_t *ds_clonegc_get_ctx(ds_clonegc_t *cgc)
-{
-	return cgc->gc;
-}
-
-/** Create bitmap in clone GC.
- *
- * @param arg Clone GC
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t ds_clonegc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	ds_clonegc_t *cgc = (ds_clonegc_t *)arg;
-	ds_clonegc_bitmap_t *cbm = NULL;
-	ds_clonegc_output_t *output;
-	gfx_bitmap_t *bitmap;
-	errno_t rc;
-
-	cbm = calloc(1, sizeof(ds_clonegc_bitmap_t));
-	if (cbm == NULL)
-		return ENOMEM;
-
-	list_initialize(&cbm->obitmaps);
-	cbm->clonegc = cgc;
-	cbm->params = *params;
-
-	output = ds_clonegc_first_output(cgc);
-	assert(output != NULL);
-
-	/* Create the first output bitmap */
-
-	rc = gfx_bitmap_create(output->gc, params, alloc, &bitmap);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_bitmap_get_alloc(bitmap, &cbm->alloc);
-	if (rc != EOK)
-		goto error;
-
-	rc = ds_clonegc_outbitmap_create(output, cbm, bitmap);
-	if (rc != EOK)
-		goto error;
-
-	bitmap = NULL;
-
-	/* Create all other output bitmaps as copies */
-	output = ds_clonegc_next_output(output);
-	while (output != NULL) {
-		rc = ds_clonegc_bitmap_add_output(cbm, output);
-		if (rc != EOK)
-			goto error;
-
-		output = ds_clonegc_next_output(output);
-	}
-
-	list_append(&cbm->lbitmaps, &cgc->bitmaps);
-	*rbm = (void *)cbm;
-	return EOK;
-error:
-	if (bitmap != NULL)
-		gfx_bitmap_destroy(bitmap);
-	if (cbm != NULL)
-		ds_clonegc_bitmap_destroy(cbm);
-	return rc;
-}
-
-/** Destroy bitmap in memory GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t ds_clonegc_bitmap_destroy(void *bm)
-{
-	ds_clonegc_bitmap_t *cbm = (ds_clonegc_bitmap_t *)bm;
-	ds_clonegc_outbitmap_t *outbm;
-	errno_t rc;
-
-	outbm = ds_clonegc_bitmap_first_obm(cbm);
-	while (outbm != NULL) {
-		rc = ds_clonegc_outbitmap_destroy(outbm);
-		if (rc != EOK)
-			return rc;
-
-		outbm = ds_clonegc_bitmap_first_obm(cbm);
-	}
-
-	list_remove(&cbm->lbitmaps);
-	free(cbm);
-	return EOK;
-}
-
-/** Render bitmap in memory GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t ds_clonegc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	ds_clonegc_bitmap_t *cbm = (ds_clonegc_bitmap_t *)bm;
-	ds_clonegc_outbitmap_t *outbm;
-	errno_t rc;
-
-	outbm = ds_clonegc_bitmap_first_obm(cbm);
-	while (outbm != NULL) {
-		rc = gfx_bitmap_render(outbm->obitmap, srect0, offs0);
-		if (rc != EOK)
-			return rc;
-
-		outbm = ds_clonegc_bitmap_next_obm(outbm);
-	}
-
-	return EOK;
-}
-
-/** Get allocation info for bitmap in memory GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t ds_clonegc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	ds_clonegc_bitmap_t *cbm = (ds_clonegc_bitmap_t *)bm;
-
-	*alloc = cbm->alloc;
-	return EOK;
-}
-
-/** Get first clone GC output.
- *
- * @param cgc Clone GC
- * @return First output or @c NULL if there are none
- */
-static ds_clonegc_output_t *ds_clonegc_first_output(ds_clonegc_t *cgc)
-{
-	link_t *link;
-
-	link = list_first(&cgc->outputs);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_clonegc_output_t, loutputs);
-}
-
-/** Get next clone GC output.
- *
- * @param cur Current output
- * @return Next output or @c NULL if @a cur is the last
- */
-static ds_clonegc_output_t *ds_clonegc_next_output(ds_clonegc_output_t *cur)
-{
-	link_t *link;
-
-	link = list_next(&cur->loutputs, &cur->clonegc->outputs);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_clonegc_output_t, loutputs);
-}
-
-/** Get first clone GC bitmap.
- *
- * @param cgc Clone GC
- * @return First bitmap or @c NULL if there are none
- */
-static ds_clonegc_bitmap_t *ds_clonegc_first_bitmap(ds_clonegc_t *cgc)
-{
-	link_t *link;
-
-	link = list_first(&cgc->bitmaps);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_clonegc_bitmap_t, lbitmaps);
-}
-
-/** Get next clone GC bitmap.
- *
- * @param cur Current bitmap
- * @return Next bitmap or @c NULL if @a cur is the last
- */
-static ds_clonegc_bitmap_t *ds_clonegc_next_bitmap(ds_clonegc_bitmap_t *cur)
-{
-	link_t *link;
-
-	link = list_next(&cur->lbitmaps, &cur->clonegc->bitmaps);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_clonegc_bitmap_t, lbitmaps);
-}
-
-/** Get first output bitmap of a clone GC bitmap.
- *
- * @param cbm Clone GC bitmap
- * @return First output bitmap or @c NULL if there are none
- */
-static ds_clonegc_outbitmap_t *ds_clonegc_bitmap_first_obm(ds_clonegc_bitmap_t *cbm)
-{
-	link_t *link;
-
-	link = list_first(&cbm->obitmaps);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_clonegc_outbitmap_t, lbbitmaps);
-}
-
-/** Get next output bitmap of a clone GC bitmap.
- *
- * @param cur Current output bitmap
- * @return Next output bitmap or @c NULL if @a cur is the last
- */
-static ds_clonegc_outbitmap_t *ds_clonegc_bitmap_next_obm(ds_clonegc_outbitmap_t *cur)
-{
-	link_t *link;
-
-	link = list_next(&cur->lbbitmaps, &cur->bitmap->obitmaps);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_clonegc_outbitmap_t, lbbitmaps);
-}
-
-/** Create clone GC output bitmap.
- *
- * Create a new entry in the output x bitmap matrix.
- *
- * @param output Clone GC output
- * @param cbm Clone GC bitmap
- * @param obitmap Output bitmap
- */
-static errno_t ds_clonegc_outbitmap_create(ds_clonegc_output_t *output,
-    ds_clonegc_bitmap_t *cbm, gfx_bitmap_t *obitmap)
-{
-	ds_clonegc_outbitmap_t *outbm;
-
-	outbm = calloc(1, sizeof(ds_clonegc_outbitmap_t));
-	if (outbm == NULL)
-		return ENOMEM;
-
-	outbm->output = output;
-	outbm->bitmap = cbm;
-	list_append(&outbm->lobitmaps, &output->obitmaps);
-	list_append(&outbm->lbbitmaps, &cbm->obitmaps);
-	outbm->obitmap = obitmap;
-
-	return EOK;
-}
-
-/** Destroy clone GC output bitmap.
- *
- * @param outbm Output bitmap
- * @return EOK on success or an error code
- */
-static errno_t ds_clonegc_outbitmap_destroy(ds_clonegc_outbitmap_t *outbm)
-{
-	errno_t rc;
-
-	rc = gfx_bitmap_destroy(outbm->obitmap);
-	if (rc != EOK)
-		return rc;
-
-	list_remove(&outbm->lobitmaps);
-	list_remove(&outbm->lbbitmaps);
-	free(outbm);
-	return EOK;
-}
-
-/** Extend clone GC bitmap to new output.
- *
- * @param cbm Clone GC bitmap
- * @param output Clone GC output
- */
-static errno_t ds_clonegc_bitmap_add_output(ds_clonegc_bitmap_t *cbm,
-    ds_clonegc_output_t *output)
-{
-	gfx_bitmap_t *obitmap = NULL;
-	errno_t rc;
-
-	rc = gfx_bitmap_create(output->gc, &cbm->params, &cbm->alloc, &obitmap);
-	if (rc != EOK)
-		goto error;
-
-	rc = ds_clonegc_outbitmap_create(output, cbm, obitmap);
-	if (rc != EOK)
-		goto error;
-
-	return EOK;
-error:
-	if (obitmap != NULL)
-		gfx_bitmap_destroy(obitmap);
-	return rc;
-}
-
-/** @}
- */
Index: pace/srv/hid/display/clonegc.h
===================================================================
--- uspace/srv/hid/display/clonegc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2020 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 Cloning grapics context
- */
-
-#ifndef CLONEGC_H
-#define CLONEGC_H
-
-#include <errno.h>
-#include <gfx/bitmap.h>
-#include "types/display/clonegc.h"
-
-extern gfx_context_ops_t ds_clonegc_ops;
-
-extern errno_t ds_clonegc_create(gfx_context_t *, ds_clonegc_t **);
-extern errno_t ds_clonegc_delete(ds_clonegc_t *);
-extern errno_t ds_clonegc_add_output(ds_clonegc_t *, gfx_context_t *);
-extern gfx_context_t *ds_clonegc_get_ctx(ds_clonegc_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/cursimg.c
===================================================================
--- uspace/srv/hid/display/cursimg.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,163 +1,0 @@
-/*
- * Copyright (c) 2020 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 built-in cursor images
- */
-
-#include <types/display/cursor.h>
-#include "cursimg.h"
-
-static uint8_t arrow_img[] = {
-	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
-	1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
-	1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0, 0, 0,
-	1, 2, 2, 1, 0, 1, 2, 2, 1, 0, 0, 0, 0,
-	1, 2, 1, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0,
-	1, 1, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0,
-	1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0
-};
-
-static uint8_t size_ud_img[] = {
-	0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
-	0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
-	1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1,
-	0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
-	0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
-	0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0
-};
-
-static uint8_t size_lr_img[] = {
-	0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0,
-	0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 0,
-	0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
-	0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
-	0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
-	0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
-	0, 0, 0, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 0,
-	0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0
-};
-
-static uint8_t size_uldr_img[] = {
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 1,
-	1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 1, 1,
-	1, 2, 1, 0, 1, 2, 2, 2, 2, 2, 1, 0, 1, 2, 1,
-	1, 1, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1,
-	1, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-};
-
-static uint8_t size_urdl_img[] = {
-	0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1,
-	0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1,
-	1, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1,
-	1, 1, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1,
-	1, 2, 1, 0, 1, 2, 2, 2, 2, 2, 1, 0, 1, 2, 1,
-	1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 1, 1,
-	1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 1,
-	1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
-	1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
-};
-
-ds_cursimg_t ds_cursimg[dcurs_limit] = {
-	{
-		.rect = { 0, 0, 13, 21 },
-		.image = arrow_img
-	},
-	{
-		.rect = { -6, -10, 7, 11 },
-		.image = size_ud_img
-	},
-	{
-		.rect = { -10, -6, 11, 7 },
-		.image = size_lr_img
-	},
-	{
-		.rect = { -7, -7, 8, 8 },
-		.image = size_uldr_img
-	},
-	{
-		.rect = { -7, -7, 8, 8 },
-		.image = size_urdl_img
-	}
-};
-
-/** @}
- */
Index: pace/srv/hid/display/cursimg.h
===================================================================
--- uspace/srv/hid/display/cursimg.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2020 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 built-in cursor images
- */
-
-#ifndef CURSIMG_H
-#define CURSIMG_H
-
-#include "types/display/cursimg.h"
-
-extern ds_cursimg_t ds_cursimg[dcurs_limit];
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/cursor.c
===================================================================
--- uspace/srv/hid/display/cursor.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,188 +1,0 @@
-/*
- * Copyright (c) 2020 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 cursor
- */
-
-#include <gfx/bitmap.h>
-#include <gfx/coord.h>
-#include <stdlib.h>
-#include "cursor.h"
-#include "display.h"
-
-/** Create cursor.
- *
- * @param disp Display
- * @param rect Rectangle bounding cursor graphic
- * @param image Cursor image (one entire byte per pixel)
- * @param rcursor Place to store pointer to new cursor.
- *
- * @return EOK on success or an error code
- */
-errno_t ds_cursor_create(ds_display_t *disp, gfx_rect_t *rect,
-    const uint8_t *image, ds_cursor_t **rcursor)
-{
-	ds_cursor_t *cursor = NULL;
-	errno_t rc;
-
-	cursor = calloc(1, sizeof(ds_cursor_t));
-	if (cursor == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	ds_display_add_cursor(disp, cursor);
-
-	cursor->rect = *rect;
-	cursor->image = image;
-	*rcursor = cursor;
-	return EOK;
-error:
-	return rc;
-}
-
-/** Destroy cusror.
- *
- * @param cursor Cursor
- */
-void ds_cursor_destroy(ds_cursor_t *cursor)
-{
-	list_remove(&cursor->ldisplay);
-
-	if (cursor->bitmap != NULL)
-		gfx_bitmap_destroy(cursor->bitmap);
-
-	free(cursor);
-}
-
-/** Paint cusor.
- *
- * @param cursor Cusor to paint
- * @param pos Position to paint at
- * @param clip Clipping rectangle or @c NULL
- * @return EOK on success or an error code
- */
-errno_t ds_cursor_paint(ds_cursor_t *cursor, gfx_coord2_t *pos,
-    gfx_rect_t *clip)
-{
-	gfx_context_t *dgc;
-	gfx_coord_t x, y;
-	gfx_bitmap_params_t bparams;
-	gfx_bitmap_alloc_t alloc;
-	gfx_coord2_t dims;
-	gfx_rect_t sclip;
-	gfx_rect_t srect;
-	pixelmap_t pixelmap;
-	pixel_t pixel;
-	const uint8_t *pp;
-	errno_t rc;
-
-	dgc = ds_display_get_gc(cursor->display);
-	if (dgc == NULL)
-		return EOK;
-
-	gfx_bitmap_params_init(&bparams);
-	bparams.rect = cursor->rect;
-	bparams.flags = bmpf_color_key;
-	bparams.key_color = PIXEL(0, 0, 255, 255);
-
-	if (cursor->bitmap == NULL) {
-		rc = gfx_bitmap_create(dgc, &bparams, NULL, &cursor->bitmap);
-		if (rc != EOK)
-			goto error;
-
-		rc = gfx_bitmap_get_alloc(cursor->bitmap, &alloc);
-		if (rc != EOK) {
-			gfx_bitmap_destroy(cursor->bitmap);
-			cursor->bitmap = NULL;
-			goto error;
-		}
-
-		gfx_rect_dims(&cursor->rect, &dims);
-		pixelmap.width = dims.x;
-		pixelmap.height = dims.y;
-		pixelmap.data = alloc.pixels;
-
-		pp = cursor->image;
-		for (y = 0; y < dims.y; y++) {
-			for (x = 0; x < dims.x; x++) {
-				switch (*pp) {
-				case 1:
-					pixel = PIXEL(0, 0, 0, 0);
-					break;
-				case 2:
-					pixel = PIXEL(0, 255, 255, 255);
-					break;
-				default:
-					pixel = PIXEL(0, 0, 255, 255);
-					break;
-				}
-
-				pixelmap_put_pixel(&pixelmap, x, y, pixel);
-				++pp;
-			}
-		}
-	}
-
-	/* Determine source rectangle */
-	if (clip == NULL) {
-		srect = cursor->rect;
-	} else {
-		gfx_rect_rtranslate(pos, clip, &sclip);
-		gfx_rect_clip(&cursor->rect, &sclip, &srect);
-	}
-
-	if (!gfx_rect_is_empty(&srect)) {
-		rc = gfx_bitmap_render(cursor->bitmap, &srect, pos);
-		if (rc != EOK)
-			return rc;
-	}
-
-	return EOK;
-error:
-	return rc;
-}
-
-/** Get rectangle covered by cursor when drawn at a specified position.
- *
- * @param cursor Cursor
- * @param pos Position where cursor is situated
- * @param rect Place to store rectangle covered by cursor
- */
-void ds_cursor_get_rect(ds_cursor_t *cursor, gfx_coord2_t *pos,
-    gfx_rect_t *drect)
-{
-	gfx_rect_translate(pos, &cursor->rect, drect);
-}
-
-/** @}
- */
Index: pace/srv/hid/display/cursor.h
===================================================================
--- uspace/srv/hid/display/cursor.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2020 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 cursor
- */
-
-#ifndef CURSOR_H
-#define CURSOR_H
-
-#include <errno.h>
-#include <types/gfx/coord.h>
-#include <stdint.h>
-#include "types/display/display.h"
-#include "types/display/cursor.h"
-
-extern errno_t ds_cursor_create(ds_display_t *, gfx_rect_t *, const uint8_t *,
-    ds_cursor_t **);
-extern void ds_cursor_destroy(ds_cursor_t *);
-extern errno_t ds_cursor_paint(ds_cursor_t *, gfx_coord2_t *, gfx_rect_t *);
-extern void ds_cursor_get_rect(ds_cursor_t *, gfx_coord2_t *, gfx_rect_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/ddev.c
===================================================================
--- uspace/srv/hid/display/ddev.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,165 +1,0 @@
-/*
- * Copyright (c) 2019 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 display device
- */
-
-#include <adt/list.h>
-#include <ddev.h>
-#include <errno.h>
-#include <io/log.h>
-#include <stdlib.h>
-#include "display.h"
-#include "ddev.h"
-
-/** Create display device object.
- *
- * @param display Parent display
- * @param dd Display device
- * @param info Display device info
- * @param svc_id Display device service ID
- * @param svc_name Display device service name
- * @param gc Display device GC
- * @param rddev Place to store pointer to new display device.
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t ds_ddev_create(ds_display_t *display, ddev_t *dd,
-    ddev_info_t *info, char *svc_name, service_id_t svc_id,
-    gfx_context_t *gc, ds_ddev_t **rddev)
-{
-	ds_ddev_t *ddev;
-	errno_t rc;
-
-	ddev = calloc(1, sizeof(ds_ddev_t));
-	if (ddev == NULL)
-		return ENOMEM;
-
-	ddev->svc_name = svc_name;
-	ddev->svc_id = svc_id;
-	ddev->dd = dd;
-	ddev->gc = gc;
-	ddev->info = *info;
-
-	rc = ds_display_add_ddev(display, ddev);
-	if (rc != EOK) {
-		free(ddev);
-		return rc;
-	}
-
-	*rddev = ddev;
-	return EOK;
-}
-
-/** Open display device.
- *
- * @param display Parent display
- * @param svc_id Service ID
- * @param rddev Place to store pointer to new display device.
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t ds_ddev_open(ds_display_t *display, service_id_t svc_id,
-    ds_ddev_t **rddev)
-{
-	ds_ddev_t *ddev;
-	ddev_info_t info;
-	gfx_context_t *gc;
-	ddev_t *dd = NULL;
-	char *name = NULL;
-	errno_t rc;
-
-	rc = loc_service_get_name(svc_id, &name);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Error resolving name of service %lu.",
-		    (unsigned long) svc_id);
-		return rc;
-	}
-
-	rc = ddev_open(name, &dd);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Error opening display device '%s'.", name);
-		free(name);
-		return rc;
-	}
-
-	rc = ddev_get_info(dd, &info);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Error getting information for display device '%s'.",
-		    name);
-		free(name);
-		ddev_close(dd);
-		return rc;
-	}
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "Device rectangle for '%s': "
-	    "%d,%d,%d,%d", name, info.rect.p0.x, info.rect.p0.y,
-	    info.rect.p1.x, info.rect.p1.y);
-
-	rc = ddev_get_gc(dd, &gc);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Error getting device context for '%s'.", name);
-		ddev_close(dd);
-		free(name);
-		return rc;
-	}
-
-	rc = ds_ddev_create(display, dd, &info, name, svc_id, gc, &ddev);
-	if (rc != EOK) {
-		free(name);
-		ddev_close(dd);
-		gfx_context_delete(gc);
-		return rc;
-	}
-
-	rc = ds_display_paint(display, NULL);
-	if (rc != EOK)
-		return rc;
-
-	*rddev = ddev;
-	return EOK;
-}
-
-/** Destroy display device.
- *
- * @param ddev Display device
- */
-void ds_ddev_close(ds_ddev_t *ddev)
-{
-	ds_display_remove_ddev(ddev);
-	free(ddev);
-}
-
-/** @}
- */
Index: pace/srv/hid/display/ddev.h
===================================================================
--- uspace/srv/hid/display/ddev.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2019 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 display device
- */
-
-#ifndef DDEV_H
-#define DDEV_H
-
-#include <errno.h>
-#include <loc.h>
-#include "types/display/ddev.h"
-#include "types/display/display.h"
-
-extern errno_t ds_ddev_create(ds_display_t *, ddev_t *, ddev_info_t *,
-    char *, service_id_t, gfx_context_t *, ds_ddev_t **);
-extern errno_t ds_ddev_open(ds_display_t *, service_id_t, ds_ddev_t **);
-extern void ds_ddev_close(ds_ddev_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,752 +1,0 @@
-/*
- * Copyright (c) 2019 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 display
- */
-
-#include <errno.h>
-#include <gfx/bitmap.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <io/log.h>
-#include <memgfx/memgc.h>
-#include <stdlib.h>
-#include "client.h"
-#include "clonegc.h"
-#include "cursimg.h"
-#include "cursor.h"
-#include "seat.h"
-#include "window.h"
-#include "display.h"
-
-static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *);
-static void ds_display_update_cb(void *, gfx_rect_t *);
-
-/** Create display.
- *
- * @param gc Graphics context for displaying output
- * @param flags Display flags
- * @param rdisp Place to store pointer to new display.
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t ds_display_create(gfx_context_t *gc, ds_display_flags_t flags,
-    ds_display_t **rdisp)
-{
-	ds_display_t *disp;
-	ds_cursor_t *cursor;
-	int i;
-	errno_t rc;
-
-	disp = calloc(1, sizeof(ds_display_t));
-	if (disp == NULL)
-		return ENOMEM;
-
-	rc = gfx_color_new_rgb_i16(0x8000, 0xc800, 0xffff, &disp->bg_color);
-	if (rc != EOK) {
-		free(disp);
-		return ENOMEM;
-	}
-
-	list_initialize(&disp->cursors);
-
-	for (i = 0; i < dcurs_limit; i++) {
-		rc = ds_cursor_create(disp, &ds_cursimg[i].rect,
-		    ds_cursimg[i].image, &cursor);
-		if (rc != EOK)
-			goto error;
-
-		disp->cursor[i] = cursor;
-	}
-
-	fibril_mutex_initialize(&disp->lock);
-	list_initialize(&disp->clients);
-	disp->next_wnd_id = 1;
-	list_initialize(&disp->ddevs);
-	list_initialize(&disp->seats);
-	list_initialize(&disp->windows);
-	disp->flags = flags;
-	*rdisp = disp;
-	return EOK;
-error:
-	ds_display_destroy(disp);
-	return rc;
-}
-
-/** Destroy display.
- *
- * @param disp Display
- */
-void ds_display_destroy(ds_display_t *disp)
-{
-	assert(list_empty(&disp->clients));
-	assert(list_empty(&disp->seats));
-	/* XXX destroy cursors */
-	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);
-}
-
-/** Get display information.
- *
- * @param disp Display
- */
-void ds_display_get_info(ds_display_t *disp, display_info_t *info)
-{
-	info->rect = disp->rect;
-}
-
-/** Add client to display.
- *
- * @param disp Display
- * @param client Client
- */
-void ds_display_add_client(ds_display_t *disp, ds_client_t *client)
-{
-	assert(client->display == NULL);
-	assert(!link_used(&client->lclients));
-
-	client->display = disp;
-	list_append(&client->lclients, &disp->clients);
-}
-
-/** Remove client from display.
- *
- * @param client Client
- */
-void ds_display_remove_client(ds_client_t *client)
-{
-	list_remove(&client->lclients);
-	client->display = NULL;
-}
-
-/** Get first client in display.
- *
- * @param disp Display
- * @return First client or @c NULL if there is none
- */
-ds_client_t *ds_display_first_client(ds_display_t *disp)
-{
-	link_t *link = list_first(&disp->clients);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_client_t, lclients);
-}
-
-/** Get next client in display.
- *
- * @param client Current client
- * @return Next client or @c NULL if there is none
- */
-ds_client_t *ds_display_next_client(ds_client_t *client)
-{
-	link_t *link = list_next(&client->lclients, &client->display->clients);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_client_t, lclients);
-}
-
-/** Find window in all clients by ID.
- *
- * XXX This is just a hack needed to match GC connection to a window,
- * as we don't have a good safe way to pass the GC endpoint to our client
- * on demand.
- *
- * @param display Display
- * @param id Window ID
- */
-ds_window_t *ds_display_find_window(ds_display_t *display, ds_wnd_id_t id)
-{
-	ds_client_t *client;
-	ds_window_t *wnd;
-
-	client = ds_display_first_client(display);
-	while (client != NULL) {
-		wnd = ds_client_find_window(client, id);
-		if (wnd != NULL)
-			return wnd;
-
-		client = ds_display_next_client(client);
-	}
-
-	return NULL;
-}
-
-/** 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;
-	gfx_rect_t drect;
-
-	wnd = ds_display_first_window(display);
-	while (wnd != NULL) {
-		/* Window bounding rectangle on display */
-		gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
-
-		if (gfx_pix_inside_rect(pos, &drect))
-			return wnd;
-
-		wnd = ds_display_next_window(wnd);
-	}
-
-	return NULL;
-}
-
-/** Add window to display.
- *
- * @param display Display
- * @param wnd Window
- */
-void ds_display_add_window(ds_display_t *display, ds_window_t *wnd)
-{
-	assert(wnd->display == NULL);
-	assert(!link_used(&wnd->ldwindows));
-
-	wnd->display = display;
-	list_prepend(&wnd->ldwindows, &display->windows);
-}
-
-/** Remove window from display.
- *
- * @param wnd Window
- */
-void ds_display_remove_window(ds_window_t *wnd)
-{
-	list_remove(&wnd->ldwindows);
-	wnd->display = NULL;
-}
-
-/** Get first window in display.
- *
- * @param display Display
- * @return First window or @c NULL if there is none
- */
-ds_window_t *ds_display_first_window(ds_display_t *display)
-{
-	link_t *link = list_first(&display->windows);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_window_t, ldwindows);
-}
-
-/** Get last window in display.
- *
- * @param display Display
- * @return Last window or @c NULL if there is none
- */
-ds_window_t *ds_display_last_window(ds_display_t *display)
-{
-	link_t *link = list_last(&display->windows);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_window_t, ldwindows);
-}
-
-/** Get next window in client.
- *
- * @param wnd Current window
- * @return Next window or @c NULL if there is none
- */
-ds_window_t *ds_display_next_window(ds_window_t *wnd)
-{
-	link_t *link = list_next(&wnd->ldwindows, &wnd->display->windows);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_window_t, ldwindows);
-}
-
-/** Get previous window in client.
- *
- * @param wnd Current window
- * @return Previous window or @c NULL if there is none
- */
-ds_window_t *ds_display_prev_window(ds_window_t *wnd)
-{
-	link_t *link = list_prev(&wnd->ldwindows, &wnd->display->windows);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_window_t, ldwindows);
-}
-
-/** Post keyboard event to a display.
- *
- * The event is routed to the correct window by first determining the
- * seat the keyboard device belongs to and then the event is sent to the
- * window focused by that seat.
- *
- * @param display Display
- * @param event Event
- */
-errno_t ds_display_post_kbd_event(ds_display_t *display, kbd_event_t *event)
-{
-	ds_seat_t *seat;
-
-	// TODO Determine which seat the event belongs to
-	seat = ds_display_first_seat(display);
-	if (seat == NULL)
-		return EOK;
-
-	return ds_seat_post_kbd_event(seat, event);
-}
-
-/** Post position event to a display.
- *
- * @param display Display
- * @param event Event
- */
-errno_t ds_display_post_ptd_event(ds_display_t *display, ptd_event_t *event)
-{
-	ds_seat_t *seat;
-
-	// TODO Determine which seat the event belongs to
-	seat = ds_display_first_seat(display);
-	if (seat == NULL)
-		return EOK;
-
-	return ds_seat_post_ptd_event(seat, event);
-}
-
-/** Add seat to display.
- *
- * @param disp Display
- * @param seat Seat
- */
-void ds_display_add_seat(ds_display_t *disp, ds_seat_t *seat)
-{
-	assert(seat->display == NULL);
-	assert(!link_used(&seat->lseats));
-
-	seat->display = disp;
-	list_append(&seat->lseats, &disp->seats);
-}
-
-/** Remove seat from display.
- *
- * @param seat Seat
- */
-void ds_display_remove_seat(ds_seat_t *seat)
-{
-	list_remove(&seat->lseats);
-	seat->display = NULL;
-}
-
-/** Get first seat in display.
- *
- * @param disp Display
- * @return First seat or @c NULL if there is none
- */
-ds_seat_t *ds_display_first_seat(ds_display_t *disp)
-{
-	link_t *link = list_first(&disp->seats);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_seat_t, lseats);
-}
-
-/** Get next seat in display.
- *
- * @param seat Current seat
- * @return Next seat or @c NULL if there is none
- */
-ds_seat_t *ds_display_next_seat(ds_seat_t *seat)
-{
-	link_t *link = list_next(&seat->lseats, &seat->display->seats);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_seat_t, lseats);
-}
-
-/** Allocate back buffer for display.
- *
- * @param disp Display
- * @return EOK on success or if no back buffer is required, otherwise
- *         an error code.
- */
-static errno_t ds_display_alloc_backbuf(ds_display_t *disp)
-{
-	gfx_context_t *ugc;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	/* Allocate backbuffer */
-	if ((disp->flags & df_disp_double_buf) == 0) {
-		/* Not double buffering. Nothing to do. */
-		return EOK;
-	}
-
-	ugc = ds_display_get_unbuf_gc(disp);
-
-	gfx_bitmap_params_init(&params);
-	params.rect = disp->rect;
-
-	rc = gfx_bitmap_create(ugc, &params, NULL,
-	    &disp->backbuf);
-	if (rc != EOK)
-		goto error;
-
-	rc = gfx_bitmap_get_alloc(disp->backbuf, &alloc);
-	if (rc != EOK)
-		goto error;
-
-	rc = mem_gc_create(&disp->rect, &alloc,
-	    ds_display_update_cb, (void *) disp, &disp->bbgc);
-	if (rc != EOK)
-		goto error;
-
-	disp->dirty_rect.p0.x = 0;
-	disp->dirty_rect.p0.y = 0;
-	disp->dirty_rect.p1.x = 0;
-	disp->dirty_rect.p1.y = 0;
-
-	return EOK;
-error:
-	if (disp->backbuf != NULL) {
-		gfx_bitmap_destroy(disp->backbuf);
-		disp->backbuf = NULL;
-	}
-
-	return rc;
-}
-
-/** Add display device to display.
- *
- * @param disp Display
- * @param ddev Display device
- * @return EOK on success, or an error code
- */
-errno_t ds_display_add_ddev(ds_display_t *disp, ds_ddev_t *ddev)
-{
-	errno_t rc;
-
-	assert(ddev->display == NULL);
-	assert(!link_used(&ddev->lddevs));
-
-	ddev->display = disp;
-	list_append(&ddev->lddevs, &disp->ddevs);
-
-	/* First display device */
-	if (gfx_rect_is_empty(&disp->rect)) {
-		/* Set screen dimensions */
-		disp->rect = ddev->info.rect;
-
-		/* Create cloning GC */
-		rc = ds_clonegc_create(ddev->gc, &disp->fbgc);
-		if (rc != EOK) {
-			// XXX Remove output
-			return ENOMEM;
-		}
-
-		/* Allocate backbuffer */
-		rc = ds_display_alloc_backbuf(disp);
-		if (rc != EOK) {
-			// XXX Remove output
-			// XXX Delete clone GC
-			goto error;
-		}
-	} else {
-		/* Add new output device to cloning GC */
-		rc = ds_clonegc_add_output(disp->fbgc, ddev->gc);
-		if (rc != EOK)
-			goto error;
-	}
-
-	return EOK;
-error:
-	disp->rect.p0.x = 0;
-	disp->rect.p0.y = 0;
-	disp->rect.p1.x = 0;
-	disp->rect.p1.y = 0;
-	list_remove(&ddev->lddevs);
-	return rc;
-}
-
-/** Remove display device from display.
- *
- * @param ddev Display device
- */
-void ds_display_remove_ddev(ds_ddev_t *ddev)
-{
-	list_remove(&ddev->lddevs);
-	ddev->display = NULL;
-}
-
-/** Get first display device in display.
- *
- * @param disp Display
- * @return First display device or @c NULL if there is none
- */
-ds_ddev_t *ds_display_first_ddev(ds_display_t *disp)
-{
-	link_t *link = list_first(&disp->ddevs);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_ddev_t, lddevs);
-}
-
-/** Get next display device in display.
- *
- * @param ddev Current display device
- * @return Next display device or @c NULL if there is none
- */
-ds_ddev_t *ds_display_next_ddev(ds_ddev_t *ddev)
-{
-	link_t *link = list_next(&ddev->lddevs, &ddev->display->ddevs);
-
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, ds_ddev_t, lddevs);
-}
-
-/** Add cursor to display.
- *
- * @param display Display
- * @param cursor Cursor
- */
-void ds_display_add_cursor(ds_display_t *display, ds_cursor_t *cursor)
-{
-	assert(cursor->display == NULL);
-	assert(!link_used(&cursor->ldisplay));
-
-	cursor->display = display;
-	list_prepend(&cursor->ldisplay, &display->cursors);
-}
-
-/** Remove cursor from display.
- *
- * @param cursor Cursor
- */
-void ds_display_remove_cursor(ds_cursor_t *cursor)
-{
-	list_remove(&cursor->ldisplay);
-	cursor->display = NULL;
-}
-
-/** Get unbuffered GC.
- *
- * Get the display's (unbuffered) graphic context. If the display
- * is double-buffered, this returns GC of the front buffer. If the display
- * is unbuffered, this is the same as @c ds_display_get_gc().
- *
- * @param display Display
- * @return Unbuffered GC
- */
-static gfx_context_t *ds_display_get_unbuf_gc(ds_display_t *display)
-{
-	/* In case of unit tests */
-	if (display->fbgc == NULL)
-		return NULL;
-
-	return ds_clonegc_get_ctx(display->fbgc);
-}
-
-/** Get display GC.
- *
- * Get the graphic context used to paint the display. This is to be used
- * for all display server paint operations.
- *
- * @param display Display
- * @return Graphic context for painting to the display
- */
-gfx_context_t *ds_display_get_gc(ds_display_t *display)
-{
-	if ((display->flags & df_disp_double_buf) != 0)
-		return mem_gc_get_ctx(display->bbgc);
-	else
-		return ds_display_get_unbuf_gc(display);
-}
-
-/** Paint display background.
- *
- * @param display Display
- * @param rect Bounding rectangle or @c NULL to repaint entire display
- */
-errno_t ds_display_paint_bg(ds_display_t *disp, gfx_rect_t *rect)
-{
-	gfx_rect_t crect;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	if (rect != NULL)
-		gfx_rect_clip(&disp->rect, rect, &crect);
-	else
-		crect = disp->rect;
-
-	gc = ds_display_get_gc(disp);
-	if (gc == NULL)
-		return EOK;
-
-	rc = gfx_set_color(gc, disp->bg_color);
-	if (rc != EOK)
-		return rc;
-
-	return gfx_fill_rect(gc, &crect);
-}
-
-/** Update front buffer from back buffer.
- *
- * If the display is not double-buffered, no action is taken.
- *
- * @param disp Display
- * @return EOK on success, or an error code
- */
-static errno_t ds_display_update(ds_display_t *disp)
-{
-	errno_t rc;
-
-	if (disp->backbuf == NULL) {
-		/* Not double-buffered, nothing to do. */
-		return EOK;
-	}
-
-	rc = gfx_bitmap_render(disp->backbuf, &disp->dirty_rect, NULL);
-	if (rc != EOK)
-		return rc;
-
-	disp->dirty_rect.p0.x = 0;
-	disp->dirty_rect.p0.y = 0;
-	disp->dirty_rect.p1.x = 0;
-	disp->dirty_rect.p1.y = 0;
-
-	return EOK;
-}
-
-/** Paint display.
- *
- * @param display Display
- * @param rect Bounding rectangle or @c NULL to repaint entire display
- */
-errno_t ds_display_paint(ds_display_t *disp, gfx_rect_t *rect)
-{
-	errno_t rc;
-	ds_window_t *wnd;
-	ds_seat_t *seat;
-
-	/* Paint background */
-	rc = ds_display_paint_bg(disp, rect);
-	if (rc != EOK)
-		return rc;
-
-	/* Paint windows bottom to top */
-	wnd = ds_display_last_window(disp);
-	while (wnd != NULL) {
-		rc = ds_window_paint(wnd, rect);
-		if (rc != EOK)
-			return rc;
-
-		wnd = ds_display_prev_window(wnd);
-	}
-
-	/* Paint window previews for windows being resized or moved */
-	wnd = ds_display_last_window(disp);
-	while (wnd != NULL) {
-		rc = ds_window_paint_preview(wnd, rect);
-		if (rc != EOK)
-			return rc;
-
-		wnd = ds_display_prev_window(wnd);
-	}
-
-	/* Paint pointers */
-	seat = ds_display_first_seat(disp);
-	while (seat != NULL) {
-		rc = ds_seat_paint_pointer(seat, rect);
-		if (rc != EOK)
-			return rc;
-
-		seat = ds_display_next_seat(seat);
-	}
-
-	return ds_display_update(disp);
-}
-
-/** Display update callback.
- *
- * Called by backbuffer memory GC when something is rendered into it.
- * Updates the display's dirty rectangle.
- *
- * @param arg Argument (display cast as void *)
- * @param rect Rectangle to update
- */
-static void ds_display_update_cb(void *arg, gfx_rect_t *rect)
-{
-	ds_display_t *disp = (ds_display_t *) arg;
-	gfx_rect_t env;
-
-	gfx_rect_envelope(&disp->dirty_rect, rect, &env);
-	disp->dirty_rect = env;
-}
-
-/** @}
- */
Index: pace/srv/hid/display/display.h
===================================================================
--- uspace/srv/hid/display/display.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,88 +1,0 @@
-/*
- * Copyright (c) 2019 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 display
- */
-
-#ifndef DISPLAY_H
-#define DISPLAY_H
-
-#include <display/info.h>
-#include <errno.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <io/kbd_event.h>
-#include "types/display/client.h"
-#include "types/display/cursor.h"
-#include "types/display/ddev.h"
-#include "types/display/display.h"
-#include "types/display/ptd_event.h"
-#include "types/display/seat.h"
-
-extern errno_t ds_display_create(gfx_context_t *, ds_display_flags_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 *);
-extern void ds_display_remove_client(ds_client_t *);
-extern ds_client_t *ds_display_first_client(ds_display_t *);
-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 *);
-extern ds_window_t *ds_display_first_window(ds_display_t *);
-extern ds_window_t *ds_display_last_window(ds_display_t *);
-extern ds_window_t *ds_display_next_window(ds_window_t *);
-extern ds_window_t *ds_display_prev_window(ds_window_t *);
-extern errno_t ds_display_post_kbd_event(ds_display_t *, kbd_event_t *);
-extern errno_t ds_display_post_ptd_event(ds_display_t *, ptd_event_t *);
-extern void ds_display_add_seat(ds_display_t *, ds_seat_t *);
-extern void ds_display_remove_seat(ds_seat_t *);
-extern ds_seat_t *ds_display_first_seat(ds_display_t *);
-extern ds_seat_t *ds_display_next_seat(ds_seat_t *);
-extern errno_t ds_display_add_ddev(ds_display_t *, ds_ddev_t *);
-extern void ds_display_remove_ddev(ds_ddev_t *);
-extern ds_ddev_t *ds_display_first_ddev(ds_display_t *);
-extern ds_ddev_t *ds_display_next_ddev(ds_ddev_t *);
-extern void ds_display_add_cursor(ds_display_t *, ds_cursor_t *);
-extern void ds_display_remove_cursor(ds_cursor_t *);
-extern gfx_context_t *ds_display_get_gc(ds_display_t *);
-extern errno_t ds_display_paint_bg(ds_display_t *, gfx_rect_t *);
-extern errno_t ds_display_paint(ds_display_t *, gfx_rect_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/doc/doxygroups.h
===================================================================
--- uspace/srv/hid/display/doc/doxygroups.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup display display
- * @ingroup srvs
- * @brief Display server
- */
Index: pace/srv/hid/display/dsops.c
===================================================================
--- uspace/srv/hid/display/dsops.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,265 +1,0 @@
-/*
- * Copyright (c) 2019 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 ops implementation
- */
-
-#include <disp_srv.h>
-#include <errno.h>
-#include <gfx/coord.h>
-#include <io/log.h>
-#include "client.h"
-#include "display.h"
-#include "dsops.h"
-#include "seat.h"
-#include "window.h"
-
-static errno_t disp_window_create(void *, display_wnd_params_t *, sysarg_t *);
-static errno_t disp_window_destroy(void *, sysarg_t);
-static errno_t disp_window_move_req(void *, sysarg_t, gfx_coord2_t *);
-static errno_t disp_window_move(void *, sysarg_t, gfx_coord2_t *);
-static errno_t disp_window_resize_req(void *, sysarg_t,
-    display_wnd_rsztype_t, gfx_coord2_t *);
-static errno_t disp_window_resize(void *, sysarg_t, gfx_coord2_t *,
-    gfx_rect_t *);
-static errno_t disp_window_set_cursor(void *, sysarg_t, display_stock_cursor_t);
-static errno_t disp_get_event(void *, sysarg_t *, display_wnd_ev_t *);
-static errno_t disp_get_info(void *, display_info_t *);
-
-display_ops_t display_srv_ops = {
-	.window_create = disp_window_create,
-	.window_destroy = disp_window_destroy,
-	.window_move_req = disp_window_move_req,
-	.window_move = disp_window_move,
-	.window_resize_req = disp_window_resize_req,
-	.window_resize = disp_window_resize,
-	.window_set_cursor = disp_window_set_cursor,
-	.get_event = disp_get_event,
-	.get_info = disp_get_info
-};
-
-static errno_t disp_window_create(void *arg, display_wnd_params_t *params,
-    sysarg_t *rwnd_id)
-{
-	errno_t rc;
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_seat_t *seat;
-	ds_window_t *wnd;
-
-	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) {
-		ds_display_unlock(client->display);
-		return rc;
-	}
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "disp_window_create() -> EOK, id=%zu",
-	    wnd->id);
-
-	/* XXX All the below should probably be part of ds_window_create() */
-	wnd->dpos.x = ((wnd->id - 1) & 1) * 400;
-	wnd->dpos.y = ((wnd->id - 1) & 2) / 2 * 300;
-
-	seat = ds_display_first_seat(client->display);
-	ds_seat_set_focus(seat, wnd);
-	(void) ds_display_paint(wnd->display, NULL);
-
-	ds_display_unlock(client->display);
-
-	*rwnd_id = wnd->id;
-	return EOK;
-}
-
-static errno_t disp_window_destroy(void *arg, sysarg_t wnd_id)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-
-	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;
-}
-
-static errno_t disp_window_move_req(void *arg, sysarg_t wnd_id,
-    gfx_coord2_t *pos)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-
-	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_move_req()");
-	ds_window_move_req(wnd, pos);
-	ds_display_unlock(client->display);
-	return EOK;
-}
-
-static errno_t disp_window_move(void *arg, sysarg_t wnd_id, gfx_coord2_t *pos)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-
-	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_move()");
-	ds_window_move(wnd, pos);
-	ds_display_unlock(client->display);
-	return EOK;
-}
-
-static errno_t disp_window_resize_req(void *arg, sysarg_t wnd_id,
-    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-
-	if (!display_wndrsz_valid(rsztype))
-		return EINVAL;
-
-	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_resize_req()");
-	ds_window_resize_req(wnd, rsztype, pos);
-	ds_display_unlock(client->display);
-	return EOK;
-}
-
-static errno_t disp_window_resize(void *arg, sysarg_t wnd_id,
-    gfx_coord2_t *offs, gfx_rect_t *nbound)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-	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_DEBUG, "disp_window_resize()");
-	rc = ds_window_resize(wnd, offs, nbound);
-	ds_display_unlock(client->display);
-	return rc;
-}
-
-static errno_t disp_window_set_cursor(void *arg, sysarg_t wnd_id,
-    display_stock_cursor_t cursor)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-	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_DEBUG, "disp_window_set_cursor()");
-	rc = ds_window_set_cursor(wnd, cursor);
-	ds_display_unlock(client->display);
-	return rc;
-}
-
-static errno_t disp_get_event(void *arg, sysarg_t *wnd_id,
-    display_wnd_ev_t *event)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-	ds_window_t *wnd;
-	errno_t rc;
-
-	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) {
-		ds_display_unlock(client->display);
-		return rc;
-	}
-
-	*wnd_id = wnd->id;
-	ds_display_unlock(client->display);
-	return EOK;
-}
-
-static errno_t disp_get_info(void *arg, display_info_t *info)
-{
-	ds_client_t *client = (ds_client_t *) arg;
-
-	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: pace/srv/hid/display/dsops.h
===================================================================
--- uspace/srv/hid/display/dsops.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2019 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 ops implementation
- */
-
-#ifndef DSOPS_H
-#define DSOPS_H
-
-#include <disp_srv.h>
-
-extern display_ops_t display_srv_ops;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/input.c
===================================================================
--- uspace/srv/hid/display/input.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,189 +1,0 @@
-/*
- * Copyright (c) 2019 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 events
- */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <io/input.h>
-#include <io/log.h>
-#include <loc.h>
-#include <str_error.h>
-#include "display.h"
-#include "input.h"
-#include "main.h"
-
-static errno_t ds_input_ev_active(input_t *);
-static errno_t ds_input_ev_deactive(input_t *);
-static errno_t ds_input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
-static errno_t ds_input_ev_move(input_t *, int, int);
-static errno_t ds_input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
-static errno_t ds_input_ev_button(input_t *, int, int);
-
-static input_ev_ops_t ds_input_ev_ops = {
-	.active = ds_input_ev_active,
-	.deactive = ds_input_ev_deactive,
-	.key = ds_input_ev_key,
-	.move = ds_input_ev_move,
-	.abs_move = ds_input_ev_abs_move,
-	.button = ds_input_ev_button
-};
-
-static errno_t ds_input_ev_active(input_t *input)
-{
-	return EOK;
-}
-
-static errno_t ds_input_ev_deactive(input_t *input)
-{
-	return EOK;
-}
-
-static errno_t ds_input_ev_key(input_t *input, kbd_event_type_t type,
-    keycode_t key, keymod_t mods, char32_t c)
-{
-	ds_display_t *disp = (ds_display_t *) input->user;
-	kbd_event_t event;
-	errno_t rc;
-
-	event.type = type;
-	event.key = key;
-	event.mods = mods;
-	event.c = c;
-
-	ds_display_lock(disp);
-	rc = ds_display_post_kbd_event(disp, &event);
-	ds_display_unlock(disp);
-	return rc;
-}
-
-static errno_t ds_input_ev_move(input_t *input, int dx, int dy)
-{
-	ds_display_t *disp = (ds_display_t *) input->user;
-	ptd_event_t event;
-	errno_t rc;
-
-	event.type = PTD_MOVE;
-	event.dmove.x = dx;
-	event.dmove.y = dy;
-
-	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
-	ds_display_unlock(disp);
-	return rc;
-}
-
-static errno_t ds_input_ev_abs_move(input_t *input, unsigned x, unsigned y,
-    unsigned max_x, unsigned max_y)
-{
-	ds_display_t *disp = (ds_display_t *) input->user;
-	ptd_event_t event;
-	errno_t rc;
-
-	event.type = PTD_ABS_MOVE;
-	event.apos.x = x;
-	event.apos.y = y;
-	event.abounds.p0.x = 0;
-	event.abounds.p0.y = 0;
-	event.abounds.p1.x = max_x + 1;
-	event.abounds.p1.y = max_y + 1;
-
-	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
-	ds_display_unlock(disp);
-	return rc;
-}
-
-static errno_t ds_input_ev_button(input_t *input, int bnum, int bpress)
-{
-	ds_display_t *disp = (ds_display_t *) input->user;
-	ptd_event_t event;
-	errno_t rc;
-
-	event.type = bpress ? PTD_PRESS : PTD_RELEASE;
-	event.btn_num = bnum;
-	event.dmove.x = 0;
-	event.dmove.y = 0;
-
-	ds_display_lock(disp);
-	rc = ds_display_post_ptd_event(disp, &event);
-	ds_display_unlock(disp);
-	return rc;
-}
-
-/** Open input service.
- *
- * @param display Display
- * @return EOK on success or an error code
- */
-errno_t ds_input_open(ds_display_t *display)
-{
-	async_sess_t *sess;
-	service_id_t dsid;
-	const char *svc = "hid/input";
-
-	errno_t rc = loc_service_get_id(svc, &dsid, 0);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Input service %s not found",
-		    svc);
-		return rc;
-	}
-
-	sess = loc_service_connect(dsid, INTERFACE_INPUT, 0);
-	if (sess == NULL) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Unable to connect to input service %s", svc);
-		return EIO;
-	}
-
-	rc = input_open(sess, &ds_input_ev_ops, (void *) display,
-	    &display->input);
-	if (rc != EOK) {
-		async_hangup(sess);
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Unable to communicate with service %s (%s)",
-		    svc, str_error(rc));
-		return rc;
-	}
-
-	input_activate(display->input);
-	return EOK;
-}
-
-void ds_input_close(ds_display_t *display)
-{
-	input_close(display->input);
-	display->input = NULL;
-}
-
-/** @}
- */
Index: pace/srv/hid/display/input.h
===================================================================
--- uspace/srv/hid/display/input.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2019 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 events
- */
-
-#ifndef INPUT_H
-#define INPUT_H
-
-#include <errno.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-#include "types/display/display.h"
-
-extern errno_t ds_input_open(ds_display_t *);
-extern void ds_input_close(ds_display_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/main.c
===================================================================
--- uspace/srv/hid/display/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,233 +1,0 @@
-/*
- * Copyright (c) 2019 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:
- *
- * - Redistribution1s 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 main
- */
-
-#include <async.h>
-#include <disp_srv.h>
-#include <errno.h>
-#include <gfx/context.h>
-#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>
-#include <loc.h>
-#include <stdio.h>
-#include <task.h>
-#include "client.h"
-#include "display.h"
-#include "dsops.h"
-#include "input.h"
-#include "main.h"
-#include "output.h"
-#include "seat.h"
-#include "window.h"
-
-static void display_client_conn(ipc_call_t *, void *);
-static void display_client_ev_pending(void *);
-
-#ifdef CONFIG_DISP_DOUBLE_BUF
-/*
- * Double buffering is one way to provide flicker-free display.
- */
-static ds_display_flags_t disp_flags = df_disp_double_buf;
-#else
-/*
- * With double buffering disabled, wet screen flicker since front-to-back
- * rendering is not implemented.
- */
-static ds_display_flags_t disp_flags = df_none;
-#endif
-
-static ds_client_cb_t display_client_cb = {
-	.ev_pending = display_client_ev_pending
-};
-
-static void display_client_ev_pending(void *arg)
-{
-	display_srv_t *srv = (display_srv_t *) arg;
-
-	display_srv_ev_pending(srv);
-}
-
-/** Initialize display server */
-static errno_t display_srv_init(ds_output_t **routput)
-{
-	ds_display_t *disp = NULL;
-	ds_seat_t *seat = NULL;
-	ds_output_t *output = NULL;
-	gfx_context_t *gc = NULL;
-	errno_t rc;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "display_srv_init()");
-
-	rc = ds_display_create(NULL, disp_flags, &disp);
-	if (rc != EOK)
-		goto error;
-
-	rc = ds_seat_create(disp, &seat);
-	if (rc != EOK)
-		goto error;
-
-	rc = ds_output_create(&output);
-	if (rc != EOK)
-		goto error;
-
-	output->def_display = disp;
-	rc = ds_output_start_discovery(output);
-	if (rc != EOK)
-		goto error;
-
-	rc = ds_input_open(disp);
-	if (rc != EOK)
-		goto error;
-
-	async_set_fallback_port_handler(display_client_conn, disp);
-
-	rc = loc_server_register(NAME);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server: %s.", str_error(rc));
-		rc = EEXIST;
-		goto error;
-	}
-
-	service_id_t sid;
-	rc = loc_service_register(SERVICE_NAME_DISPLAY, &sid);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service: %s.", str_error(rc));
-		rc = EEXIST;
-		goto error;
-	}
-
-	*routput = output;
-	return EOK;
-error:
-#if 0
-	if (disp->input != NULL)
-		ds_input_close(disp);
-#endif
-	if (output != NULL)
-		ds_output_destroy(output);
-	if (gc != NULL)
-		gfx_context_delete(gc);
-	if (seat != NULL)
-		ds_seat_destroy(seat);
-	if (disp != NULL)
-		ds_display_destroy(disp);
-	return rc;
-}
-
-/** Handle client connection to display server */
-static void display_client_conn(ipc_call_t *icall, void *arg)
-{
-	display_srv_t srv;
-	sysarg_t wnd_id;
-	sysarg_t svc_id;
-	ds_client_t *client = NULL;
-	ds_window_t *wnd;
-	ds_display_t *disp = (ds_display_t *) arg;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "display_client_conn arg1=%zu arg2=%zu arg3=%zu arg4=%zu.",
-	    ipc_get_arg1(icall), ipc_get_arg2(icall), ipc_get_arg3(icall),
-	    ipc_get_arg4(icall));
-
-	(void) icall;
-	(void) arg;
-
-	svc_id = ipc_get_arg2(icall);
-	wnd_id = ipc_get_arg3(icall);
-
-	if (svc_id != 0) {
-		/* Create client object */
-		rc = ds_client_create(disp, &display_client_cb, &srv, &client);
-		if (rc != EOK) {
-			async_answer_0(icall, ENOMEM);
-			return;
-		}
-
-		/* Set up protocol structure */
-		display_srv_initialize(&srv);
-		srv.ops = &display_srv_ops;
-		srv.arg = client;
-
-		/* Handle connection */
-		display_conn(icall, &srv);
-
-		ds_client_destroy(client);
-	} else {
-		/* Window GC connection */
-
-		wnd = ds_display_find_window(disp, wnd_id);
-		if (wnd == NULL) {
-			async_answer_0(icall, ENOENT);
-			return;
-		}
-
-		/*
-		 * XXX We need a way to make sure that the connection does
-		 * not stay active after the window had been destroyed
-		 */
-		gc = ds_window_get_ctx(wnd);
-		gc_conn(icall, gc);
-	}
-}
-
-int main(int argc, char *argv[])
-{
-	errno_t rc;
-	ds_output_t *output;
-
-	printf("%s: Display server\n", NAME);
-
-	if (log_init(NAME) != EOK) {
-		printf(NAME ": Failed to initialize logging.\n");
-		return 1;
-	}
-
-	rc = display_srv_init(&output);
-	if (rc != EOK)
-		return 1;
-
-	printf(NAME ": Accepting connections.\n");
-	task_retval(0);
-	async_manager();
-
-	return 0;
-}
-
-/** @}
- */
Index: pace/srv/hid/display/main.h
===================================================================
--- uspace/srv/hid/display/main.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright (c) 2019 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 main
- */
-
-#ifndef MAIN_H
-#define MAIN_H
-
-#define NAME "display"
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/meson.build
===================================================================
--- uspace/srv/hid/display/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,62 +1,0 @@
-#
-# Copyright (c) 2019 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.
-#
-
-deps = [ 'ipcgfx', 'memgfx', 'display', 'ddev' ]
-
-src = files(
-	'client.c',
-	'clonegc.c',
-	'cursor.c',
-	'cursimg.c',
-	'ddev.c',
-	'display.c',
-	'dsops.c',
-	'input.c',
-	'main.c',
-	'output.c',
-	'seat.c',
-	'window.c',
-)
-
-test_src = files(
-	'client.c',
-	'clonegc.c',
-	'cursimg.c',
-	'cursor.c',
-	'ddev.c',
-	'display.c',
-	'seat.c',
-	'window.c',
-	'test/client.c',
-	'test/clonegc.c',
-	'test/cursor.c',
-	'test/display.c',
-	'test/main.c',
-	'test/seat.c',
-	'test/window.c',
-)
Index: pace/srv/hid/display/output.c
===================================================================
--- uspace/srv/hid/display/output.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,184 +1,0 @@
-/*
- * Copyright (c) 2019 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 output
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/kbd_event.h>
-#include <io/log.h>
-#include <io/pos_event.h>
-#include <loc.h>
-#include <stdlib.h>
-#include "ddev.h"
-#include "output.h"
-
-/** Check for new display devices.
- *
- * @param output Display server output
- */
-static errno_t ds_output_check_new_devs(ds_output_t *output)
-{
-	category_id_t ddev_cid;
-	service_id_t *svcs;
-	size_t count, i;
-	bool already_known;
-	ds_ddev_t *nddev;
-	errno_t rc;
-
-	assert(fibril_mutex_is_locked(&output->lock));
-
-	rc = loc_category_get_id("display-device", &ddev_cid,
-	    IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Error looking up category 'display-device'.");
-		return EIO;
-	}
-
-	/*
-	 * Check for new dispay devices
-	 */
-	rc = loc_category_get_svcs(ddev_cid, &svcs, &count);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Error getting list of display devices.");
-		return EIO;
-	}
-
-	for (i = 0; i < count; i++) {
-		already_known = false;
-
-		/* Determine whether we already know this device. */
-		list_foreach(output->ddevs, loutdevs, ds_ddev_t, ddev) {
-			if (ddev->svc_id == svcs[i]) {
-				already_known = true;
-				break;
-			}
-		}
-
-		if (!already_known) {
-			rc = ds_ddev_open(output->def_display, svcs[i], &nddev);
-			if (rc != EOK) {
-				log_msg(LOG_DEFAULT, LVL_ERROR,
-				    "Error adding display device.");
-				continue;
-			}
-
-			list_append(&nddev->loutdevs, &output->ddevs);
-
-			log_msg(LOG_DEFAULT, LVL_NOTE,
-			    "Added display device '%lu'",
-			    (unsigned long) svcs[i]);
-		}
-	}
-
-	free(svcs);
-
-	return EOK;
-}
-
-/** Display device category change callback.
- *
- * @param arg Display server output (cast to void *)
- */
-static void ds_ddev_change_cb(void *arg)
-{
-	ds_output_t *output = (ds_output_t *) arg;
-
-	fibril_mutex_lock(&output->lock);
-	(void) ds_output_check_new_devs(output);
-	fibril_mutex_unlock(&output->lock);
-}
-
-/** Create display server output.
- *
- * @param routput Place to store pointer to display server output object.
- * @return EOK on success or an error code
- */
-errno_t ds_output_create(ds_output_t **routput)
-{
-	ds_output_t *output;
-
-	output = calloc(1, sizeof(ds_output_t));
-	if (output == NULL)
-		return ENOMEM;
-
-	fibril_mutex_initialize(&output->lock);
-	list_initialize(&output->ddevs);
-
-	*routput = output;
-	return EOK;
-}
-
-/** Start display device discovery.
- *
- * @param output Display server output
- * @return EOK on success or an error code
- */
-errno_t ds_output_start_discovery(ds_output_t *output)
-{
-	errno_t rc;
-
-	rc = loc_register_cat_change_cb(ds_ddev_change_cb, output);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR,
-		    "Failed registering callback for device discovery.");
-		return rc;
-	}
-
-	fibril_mutex_lock(&output->lock);
-	rc = ds_output_check_new_devs(output);
-	fibril_mutex_unlock(&output->lock);
-
-	/* Fail if we did not open at least one device */
-	if (list_empty(&output->ddevs)) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "No output device found.");
-		return ENOENT;
-	}
-
-	return rc;
-}
-
-/** Destroy display server output.
- *
- * @param output Display server output
- */
-void ds_output_destroy(ds_output_t *output)
-{
-	free(output);
-}
-
-/** @}
- */
Index: pace/srv/hid/display/output.h
===================================================================
--- uspace/srv/hid/display/output.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2019 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 output
- */
-
-#ifndef OUTPUT_H
-#define OUTPUT_H
-
-#include <gfx/context.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-#include "types/display/output.h"
-
-extern errno_t ds_output_create(ds_output_t **);
-extern errno_t ds_output_start_discovery(ds_output_t *);
-extern void ds_output_destroy(ds_output_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/seat.c
===================================================================
--- uspace/srv/hid/display/seat.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,426 +1,0 @@
-/*
- * Copyright (c) 2019 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 seat
- */
-
-#include <adt/list.h>
-#include <errno.h>
-#include <gfx/color.h>
-#include <gfx/render.h>
-#include <stdlib.h>
-#include "client.h"
-#include "cursor.h"
-#include "display.h"
-#include "seat.h"
-#include "window.h"
-
-static void ds_seat_get_pointer_rect(ds_seat_t *, gfx_rect_t *);
-static errno_t ds_seat_repaint_pointer(ds_seat_t *, gfx_rect_t *);
-
-/** Create seat.
- *
- * @param display Parent display
- * @param rseat Place to store pointer to new seat.
- * @return EOK on success, ENOMEM if out of memory
- */
-errno_t ds_seat_create(ds_display_t *display, ds_seat_t **rseat)
-{
-	ds_seat_t *seat;
-
-	seat = calloc(1, sizeof(ds_seat_t));
-	if (seat == NULL)
-		return ENOMEM;
-
-	ds_display_add_seat(display, seat);
-	seat->pntpos.x = 0;
-	seat->pntpos.y = 0;
-
-	seat->client_cursor = display->cursor[dcurs_arrow];
-	seat->wm_cursor = NULL;
-
-	*rseat = seat;
-	return EOK;
-}
-
-/** Destroy seat.
- *
- * @param seat Seat
- */
-void ds_seat_destroy(ds_seat_t *seat)
-{
-	ds_display_remove_seat(seat);
-	free(seat);
-}
-
-/** Set seat focus to a window.
- *
- * @param seat Seat
- * @param wnd Window to focus
- */
-void ds_seat_set_focus(ds_seat_t *seat, ds_window_t *wnd)
-{
-	if (seat->focus != NULL)
-		ds_window_post_unfocus_event(seat->focus);
-
-	seat->focus = wnd;
-
-	if (wnd != NULL) {
-		ds_window_post_focus_event(wnd);
-		ds_window_bring_to_top(wnd);
-	}
-}
-
-/** Evacuate focus from window.
- *
- * If seat's focus is @a wnd, it will be set to a different window.
- *
- * @param seat Seat
- * @param wnd Window to evacuate focus from
- */
-void ds_seat_evac_focus(ds_seat_t *seat, ds_window_t *wnd)
-{
-	ds_window_t *nwnd;
-
-	if (seat->focus == wnd) {
-		nwnd = ds_display_next_window(wnd);
-		if (nwnd == NULL)
-			nwnd = ds_display_first_window(wnd->display);
-		if (nwnd == wnd)
-			nwnd = NULL;
-
-		ds_seat_set_focus(seat, nwnd);
-	}
-}
-
-/** Post keyboard event to the seat's focused window.
- *
- * @param seat Seat
- * @param event Event
- *
- * @return EOK on success or an error code
- */
-errno_t ds_seat_post_kbd_event(ds_seat_t *seat, kbd_event_t *event)
-{
-	ds_window_t *dwindow;
-	bool alt_or_shift;
-
-	alt_or_shift = event->mods & (KM_SHIFT | KM_ALT);
-	if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_TAB) {
-		/* On Alt-Tab or Shift-Tab, switch focus to next window */
-		ds_seat_evac_focus(seat, seat->focus);
-		return EOK;
-	}
-
-	dwindow = seat->focus;
-	if (dwindow == NULL)
-		return EOK;
-
-	return ds_window_post_kbd_event(dwindow, event);
-}
-
-/** Get current cursor used by seat.
- *
- * @param wmcurs WM curor
- * @param ccurs Client cursor
- * @return
- */
-static ds_cursor_t *ds_seat_compute_cursor(ds_cursor_t *wmcurs, ds_cursor_t *ccurs)
-{
-	if (wmcurs != NULL)
-		return wmcurs;
-
-	return ccurs;
-}
-
-/** Get current cursor used by seat.
- *
- * @param seat Seat
- * @return Current cursor
- */
-static ds_cursor_t *ds_seat_get_cursor(ds_seat_t *seat)
-{
-	return ds_seat_compute_cursor(seat->wm_cursor, seat->client_cursor);
-}
-
-/** Set client cursor.
- *
- * Set cursor selected by client. This may update the actual cursor
- * if WM is not overriding the cursor.
- *
- * @param seat Seat
- * @param cursor Client cursor
- */
-static void ds_seat_set_client_cursor(ds_seat_t *seat, ds_cursor_t *cursor)
-{
-	ds_cursor_t *old_cursor;
-	ds_cursor_t *new_cursor;
-	gfx_rect_t old_rect;
-
-	old_cursor = ds_seat_get_cursor(seat);
-	new_cursor = ds_seat_compute_cursor(seat->wm_cursor, cursor);
-
-	if (new_cursor != old_cursor) {
-		ds_seat_get_pointer_rect(seat, &old_rect);
-		seat->client_cursor = cursor;
-		ds_seat_repaint_pointer(seat, &old_rect);
-	} else {
-		seat->client_cursor = cursor;
-	}
-}
-
-/** Set WM cursor.
- *
- * Set cursor override for window management.
- *
- * @param seat Seat
- * @param cursor WM cursor override or @c NULL not to override the cursor
- */
-void ds_seat_set_wm_cursor(ds_seat_t *seat, ds_cursor_t *cursor)
-{
-	ds_cursor_t *old_cursor;
-	ds_cursor_t *new_cursor;
-	gfx_rect_t old_rect;
-
-	old_cursor = ds_seat_get_cursor(seat);
-	new_cursor = ds_seat_compute_cursor(cursor, seat->client_cursor);
-
-	if (new_cursor != old_cursor) {
-		ds_seat_get_pointer_rect(seat, &old_rect);
-		seat->wm_cursor = cursor;
-		ds_seat_repaint_pointer(seat, &old_rect);
-	} else {
-		seat->wm_cursor = cursor;
-	}
-}
-
-/** Get rectangle covered by pointer.
- *
- * @param seat Seat
- * @param rect Place to store rectangle
- */
-void ds_seat_get_pointer_rect(ds_seat_t *seat, gfx_rect_t *rect)
-{
-	ds_cursor_t *cursor;
-
-	cursor = ds_seat_get_cursor(seat);
-	ds_cursor_get_rect(cursor, &seat->pntpos, rect);
-}
-
-/** Repaint seat pointer
- *
- * Repaint the pointer after it has moved or changed. This is done by
- * repainting the area of the display previously (@a old_rect) and currently
- * covered by the pointer.
- *
- * @param seat Seat
- * @param old_rect Rectangle previously covered by pointer
- *
- * @return EOK on success or an error code
- */
-static errno_t ds_seat_repaint_pointer(ds_seat_t *seat, gfx_rect_t *old_rect)
-{
-	gfx_rect_t new_rect;
-	gfx_rect_t envelope;
-	errno_t rc;
-
-	ds_seat_get_pointer_rect(seat, &new_rect);
-
-	if (gfx_rect_is_incident(old_rect, &new_rect)) {
-		/* Rectangles do not intersect. Repaint them separately. */
-		rc = ds_display_paint(seat->display, &new_rect);
-		if (rc != EOK)
-			return rc;
-
-		rc = ds_display_paint(seat->display, old_rect);
-		if (rc != EOK)
-			return rc;
-	} else {
-		/*
-		 * Rectangles intersect. As an optimization, repaint them
-		 * in a single operation.
-		 */
-		gfx_rect_envelope(old_rect, &new_rect, &envelope);
-
-		rc = ds_display_paint(seat->display, &envelope);
-		if (rc != EOK)
-			return rc;
-	}
-
-	return EOK;
-}
-
-/** Post pointing device event to the seat
- *
- * Update pointer position and generate position event.
- *
- * @param seat Seat
- * @param event Event
- *
- * @return EOK on success or an error code
- */
-errno_t ds_seat_post_ptd_event(ds_seat_t *seat, ptd_event_t *event)
-{
-	ds_display_t *disp = seat->display;
-	gfx_coord2_t npos;
-	gfx_rect_t old_rect;
-	ds_window_t *wnd;
-	pos_event_t pevent;
-	errno_t rc;
-
-	wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
-
-	/* Focus window on button press */
-	if (event->type == PTD_PRESS && event->btn_num == 1) {
-		if (wnd != NULL) {
-			ds_seat_set_focus(seat, wnd);
-		}
-	}
-
-	if (event->type == PTD_PRESS || event->type == PTD_RELEASE) {
-		pevent.pos_id = 0;
-		pevent.type = (event->type == PTD_PRESS) ?
-		    POS_PRESS : POS_RELEASE;
-		pevent.btn_num = event->btn_num;
-		pevent.hpos = seat->pntpos.x;
-		pevent.vpos = seat->pntpos.y;
-
-		rc = ds_seat_post_pos_event(seat, &pevent);
-		if (rc != EOK)
-			return rc;
-	}
-
-	if (event->type == PTD_MOVE) {
-		gfx_coord2_add(&seat->pntpos, &event->dmove, &npos);
-		gfx_coord2_clip(&npos, &disp->rect, &npos);
-
-		ds_seat_get_pointer_rect(seat, &old_rect);
-		seat->pntpos = npos;
-
-		pevent.pos_id = 0;
-		pevent.type = POS_UPDATE;
-		pevent.btn_num = 0;
-		pevent.hpos = seat->pntpos.x;
-		pevent.vpos = seat->pntpos.y;
-
-		rc = ds_seat_post_pos_event(seat, &pevent);
-		if (rc != EOK)
-			return rc;
-
-		ds_seat_repaint_pointer(seat, &old_rect);
-	}
-
-	if (event->type == PTD_ABS_MOVE) {
-		/*
-		 * Project input device area onto display area. Technically
-		 * we probably want to project onto the area of a particular
-		 * display device. The tricky part is figuring out which
-		 * display device the input device is associated with.
-		 */
-		gfx_coord2_project(&event->apos, &event->abounds,
-		    &disp->rect, &npos);
-
-		gfx_coord2_clip(&npos, &disp->rect, &npos);
-
-		ds_seat_get_pointer_rect(seat, &old_rect);
-		seat->pntpos = npos;
-
-		pevent.pos_id = 0;
-		pevent.type = POS_UPDATE;
-		pevent.btn_num = 0;
-		pevent.hpos = seat->pntpos.x;
-		pevent.vpos = seat->pntpos.y;
-
-		rc = ds_seat_post_pos_event(seat, &pevent);
-		if (rc != EOK)
-			return rc;
-
-		ds_seat_repaint_pointer(seat, &old_rect);
-	}
-
-	return EOK;
-}
-
-/** Post position event to seat.
- *
- * Deliver event to relevant windows.
- *
- * @param seat Seat
- * @param event Position event
- */
-errno_t ds_seat_post_pos_event(ds_seat_t *seat, pos_event_t *event)
-{
-	ds_window_t *wnd;
-	errno_t rc;
-
-	wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
-
-	if (seat->focus != wnd) {
-		rc = ds_window_post_pos_event(seat->focus, event);
-		if (rc != EOK)
-			return rc;
-
-		/* Only deliver release events to the focused window */
-		if (event->type == POS_RELEASE)
-			return EOK;
-	}
-
-	if (wnd != NULL) {
-		/* Moving over a window */
-		ds_seat_set_client_cursor(seat, wnd->cursor);
-
-		rc = ds_window_post_pos_event(wnd, event);
-		if (rc != EOK)
-			return rc;
-	} else {
-		/* Not over a window */
-		ds_seat_set_client_cursor(seat, seat->display->cursor[dcurs_arrow]);
-	}
-
-	return EOK;
-}
-
-/** Paint seat pointer.
- *
- * @param seat Seat whose pointer to paint
- * @param rect Clipping rectangle
- */
-errno_t ds_seat_paint_pointer(ds_seat_t *seat, gfx_rect_t *rect)
-{
-	ds_cursor_t *cursor;
-
-	cursor = ds_seat_get_cursor(seat);
-	return ds_cursor_paint(cursor, &seat->pntpos, rect);
-}
-
-/** @}
- */
Index: pace/srv/hid/display/seat.h
===================================================================
--- uspace/srv/hid/display/seat.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2019 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 seat
- */
-
-#ifndef SEAT_H
-#define SEAT_H
-
-#include <errno.h>
-#include <gfx/coord.h>
-#include <io/kbd_event.h>
-#include <io/pos_event.h>
-#include "types/display/display.h"
-#include "types/display/seat.h"
-#include "types/display/ptd_event.h"
-#include "types/display/window.h"
-
-extern errno_t ds_seat_create(ds_display_t *, ds_seat_t **);
-extern void ds_seat_destroy(ds_seat_t *);
-extern void ds_seat_set_focus(ds_seat_t *, ds_window_t *);
-extern void ds_seat_evac_focus(ds_seat_t *, ds_window_t *);
-extern errno_t ds_seat_post_kbd_event(ds_seat_t *, kbd_event_t *);
-extern errno_t ds_seat_post_ptd_event(ds_seat_t *, ptd_event_t *);
-extern errno_t ds_seat_post_pos_event(ds_seat_t *, pos_event_t *);
-extern void ds_seat_set_wm_cursor(ds_seat_t *, ds_cursor_t *);
-extern errno_t ds_seat_paint_pointer(ds_seat_t *, gfx_rect_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/test/client.c
===================================================================
--- uspace/srv/hid/display/test/client.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,502 +1,0 @@
-/*
- * Copyright (c) 2019 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 <disp_srv.h>
-#include <errno.h>
-#include <pcut/pcut.h>
-#include <str.h>
-
-#include "../client.h"
-#include "../display.h"
-#include "../window.h"
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(client);
-
-static void test_ds_ev_pending(void *);
-
-static ds_client_cb_t test_ds_client_cb = {
-	.ev_pending = test_ds_ev_pending
-};
-
-static void test_ds_ev_pending(void *arg)
-{
-	bool *called_cb = (bool *) arg;
-	*called_cb = true;
-}
-
-/** Client creation and destruction. */
-PCUT_TEST(client_create_destroy)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_find_window().
- *
- * ds_client_add_window() and ds_client_remove_window() are indirectly
- * tested too as part of creating and destroying the window
- */
-PCUT_TEST(client_find_window)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *w0;
-	ds_window_t *w1;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &w1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	wnd = ds_client_find_window(client, w0->id);
-	PCUT_ASSERT_EQUALS(w0, wnd);
-
-	wnd = ds_client_find_window(client, w1->id);
-	PCUT_ASSERT_EQUALS(w1, wnd);
-
-	wnd = ds_client_find_window(client, 0);
-	PCUT_ASSERT_NULL(wnd);
-
-	wnd = ds_client_find_window(client, w1->id + 1);
-	PCUT_ASSERT_NULL(wnd);
-
-	ds_window_destroy(w0);
-	ds_window_destroy(w1);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_first_window() / ds_client_next_window. */
-PCUT_TEST(client_first_next_window)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *w0;
-	ds_window_t *w1;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &w1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	wnd = ds_client_first_window(client);
-	PCUT_ASSERT_EQUALS(w0, wnd);
-
-	wnd = ds_client_next_window(w0);
-	PCUT_ASSERT_EQUALS(w1, wnd);
-
-	wnd = ds_client_next_window(w1);
-	PCUT_ASSERT_NULL(wnd);
-
-	ds_window_destroy(w0);
-	ds_window_destroy(w1);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_get_event(), ds_client_post_close_event(). */
-PCUT_TEST(client_get_post_close_event)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = NULL;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_client_post_close_event(client, wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_close, revent.etype);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_get_event(), ds_client_post_focus_event(). */
-PCUT_TEST(client_get_post_focus_event)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = NULL;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_client_post_focus_event(client, wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_focus, revent.etype);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_get_event(), ds_client_post_kbd_event(). */
-PCUT_TEST(client_get_post_kbd_event)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	kbd_event_t event;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = NULL;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	event.type = KEY_PRESS;
-	event.key = KC_ENTER;
-	event.mods = 0;
-	event.c = L'\0';
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_client_post_kbd_event(client, wnd, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_kbd, revent.etype);
-	PCUT_ASSERT_EQUALS(event.type, revent.ev.kbd.type);
-	PCUT_ASSERT_EQUALS(event.key, revent.ev.kbd.key);
-	PCUT_ASSERT_EQUALS(event.mods, revent.ev.kbd.mods);
-	PCUT_ASSERT_EQUALS(event.c, revent.ev.kbd.c);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_get_event(), ds_client_post_pos_event(). */
-PCUT_TEST(client_get_post_pos_event)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	pos_event_t event;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = NULL;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	event.type = POS_PRESS;
-	event.hpos = 1;
-	event.vpos = 2;
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_client_post_pos_event(client, wnd, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_pos, revent.etype);
-	PCUT_ASSERT_EQUALS(event.type, revent.ev.pos.type);
-	PCUT_ASSERT_EQUALS(event.hpos, revent.ev.pos.hpos);
-	PCUT_ASSERT_EQUALS(event.vpos, revent.ev.pos.vpos);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_get_event(), ds_client_post_resize_event(). */
-PCUT_TEST(client_get_post_resize_event)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	gfx_rect_t rect;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = NULL;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_client_post_resize_event(client, wnd, &rect);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_resize, revent.etype);
-	PCUT_ASSERT_EQUALS(rect.p0.x, revent.ev.resize.rect.p0.x);
-	PCUT_ASSERT_EQUALS(rect.p0.y, revent.ev.resize.rect.p0.y);
-	PCUT_ASSERT_EQUALS(rect.p1.x, revent.ev.resize.rect.p1.x);
-	PCUT_ASSERT_EQUALS(rect.p1.y, revent.ev.resize.rect.p1.y);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_client_get_event(), ds_client_post_unfocus_event(). */
-PCUT_TEST(client_get_post_unfocus_event)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = NULL;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_client_post_unfocus_event(client, wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_unfocus, revent.etype);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test client being destroyed while still having a window.
- *
- * This can happen if client forgets to destroy window or if the client
- * is disconnected (or terminated).
- */
-PCUT_TEST(client_leftover_window)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-PCUT_EXPORT(client);
Index: pace/srv/hid/display/test/clonegc.c
===================================================================
--- uspace/srv/hid/display/test/clonegc.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,709 +1,0 @@
-/*
- * Copyright (c) 2020 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 <gfx/color.h>
-#include <gfx/render.h>
-#include <pcut/pcut.h>
-#include <stdio.h>
-
-#include "../clonegc.h"
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(clonegc);
-
-static errno_t testgc_set_color(void *, gfx_color_t *);
-static errno_t testgc_fill_rect(void *, gfx_rect_t *);
-static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t testgc_bitmap_destroy(void *);
-static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static gfx_context_ops_t ops = {
-	.set_color = testgc_set_color,
-	.fill_rect = testgc_fill_rect,
-	.bitmap_create = testgc_bitmap_create,
-	.bitmap_destroy = testgc_bitmap_destroy,
-	.bitmap_render = testgc_bitmap_render,
-	.bitmap_get_alloc = testgc_bitmap_get_alloc
-};
-
-typedef struct {
-	/** Error code to return */
-	errno_t rc;
-
-	bool set_color_called;
-	gfx_color_t *set_color_color;
-
-	bool fill_rect_called;
-	gfx_rect_t *fill_rect_rect;
-
-	bool bm_created;
-	bool bm_destroyed;
-	gfx_bitmap_params_t bm_params;
-	void *bm_pixels;
-	gfx_rect_t bm_srect;
-	gfx_coord2_t bm_offs;
-	bool bm_rendered;
-	bool bm_got_alloc;
-} test_gc_t;
-
-typedef struct {
-	test_gc_t *tgc;
-	gfx_bitmap_alloc_t alloc;
-	bool myalloc;
-} testgc_bitmap_t;
-
-enum {
-	alloc_pitch = 42,
-	alloc_off0 = 33
-};
-
-/** Test creating and deleting clone GC */
-PCUT_TEST(create_delete)
-{
-	ds_clonegc_t *cgc;
-	errno_t rc;
-
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Test set color operation with two output GCs */
-PCUT_TEST(set_color)
-{
-	ds_clonegc_t *cgc;
-	gfx_context_t *gc;
-	test_gc_t tgc1;
-	gfx_context_t *gc1;
-	test_gc_t tgc2;
-	gfx_context_t *gc2;
-	gfx_color_t *color;
-	errno_t rc;
-
-	/* Create clone GC */
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_clonegc_get_ctx(cgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Add two output GCs */
-
-	rc = gfx_context_new(&ops, &tgc1, &gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_context_new(&ops, &tgc2, &gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_color_new_rgb_i16(0xaaaa, 0xbbbb, 0xcccc, &color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Set color returning error */
-
-	tgc1.set_color_called = false;
-	tgc2.set_color_called = false;
-	tgc1.rc = EINVAL;
-	tgc2.rc = EINVAL;
-
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.set_color_called);
-	PCUT_ASSERT_EQUALS(color, tgc1.set_color_color);
-	PCUT_ASSERT_FALSE(tgc2.set_color_called);
-
-	/* Set color returning success for all outputs */
-	tgc1.set_color_called = false;
-	tgc2.set_color_called = false;
-	tgc1.rc = EOK;
-	tgc2.rc = EOK;
-
-	rc = gfx_set_color(gc, color);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.set_color_called);
-	PCUT_ASSERT_EQUALS(color, tgc1.set_color_color);
-	PCUT_ASSERT_TRUE(tgc2.set_color_called);
-	PCUT_ASSERT_EQUALS(color, tgc2.set_color_color);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gfx_color_delete(color);
-}
-
-/** Fill rectangle operation with two output GCs */
-PCUT_TEST(fill_rect)
-{
-	ds_clonegc_t *cgc;
-	gfx_context_t *gc;
-	test_gc_t tgc1;
-	gfx_context_t *gc1;
-	test_gc_t tgc2;
-	gfx_context_t *gc2;
-	gfx_rect_t rect;
-	errno_t rc;
-
-	/* Create clone GC */
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_clonegc_get_ctx(cgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Add two output GCs */
-
-	rc = gfx_context_new(&ops, &tgc1, &gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_context_new(&ops, &tgc2, &gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rect.p0.x = 1;
-	rect.p0.y = 2;
-	rect.p1.x = 3;
-	rect.p1.y = 4;
-
-	/* Fill rectangle returning error */
-
-	tgc1.fill_rect_called = false;
-	tgc2.fill_rect_called = false;
-	tgc1.rc = EINVAL;
-	tgc2.rc = EINVAL;
-
-	rc = gfx_fill_rect(gc, &rect);
-	PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.fill_rect_called);
-	PCUT_ASSERT_EQUALS(&rect, tgc1.fill_rect_rect);
-	PCUT_ASSERT_FALSE(tgc2.fill_rect_called);
-
-	/* Fill rectangle returning success for all outputs */
-	tgc1.fill_rect_called = false;
-	tgc2.fill_rect_called = false;
-	tgc1.rc = EOK;
-	tgc2.rc = EOK;
-
-	rc = gfx_fill_rect(gc, &rect);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.fill_rect_called);
-	PCUT_ASSERT_EQUALS(&rect, tgc1.fill_rect_rect);
-	PCUT_ASSERT_TRUE(tgc2.fill_rect_called);
-	PCUT_ASSERT_EQUALS(&rect, tgc2.fill_rect_rect);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Operations on regular bitmap with two output GCs, callee allocation */
-PCUT_TEST(bitmap_twogc_callee_alloc)
-{
-	ds_clonegc_t *cgc;
-	gfx_context_t *gc;
-	test_gc_t tgc1;
-	gfx_context_t *gc1;
-	test_gc_t tgc2;
-	gfx_context_t *gc2;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_alloc_t alloc;
-	gfx_rect_t rect;
-	gfx_coord2_t off;
-	errno_t rc;
-
-	/* Create clone GC */
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_clonegc_get_ctx(cgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Add two output GCs */
-
-	rc = gfx_context_new(&ops, &tgc1, &gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_context_new(&ops, &tgc2, &gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Create bitmap with NULL allocation */
-	tgc1.bm_created = false;
-	tgc2.bm_created = false;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.bm_created);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
-
-	PCUT_ASSERT_TRUE(tgc2.bm_created);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc2.bm_params.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc2.bm_params.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc2.bm_params.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc2.bm_params.rect.p1.y);
-
-	/* Get allocation */
-
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_INT_EQUALS(alloc_pitch, alloc.pitch);
-	PCUT_ASSERT_EQUALS(tgc1.bm_pixels, alloc.pixels);
-	PCUT_ASSERT_EQUALS(tgc2.bm_pixels, alloc.pixels);
-
-	/* Render bitmap */
-	tgc1.bm_rendered = false;
-	tgc1.bm_rendered = false;
-	rect.p0.x = 10;
-	rect.p0.y = 20;
-	rect.p1.x = 30;
-	rect.p1.y = 40;
-	off.x = 50;
-	off.y = 60;
-	rc = gfx_bitmap_render(bitmap, &rect, &off);
-	PCUT_ASSERT_TRUE(tgc1.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
-	PCUT_ASSERT_TRUE(tgc2.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Operations on regular bitmap with two output GCs, caller allocation */
-PCUT_TEST(bitmap_twogc_caller_alloc)
-{
-	ds_clonegc_t *cgc;
-	gfx_context_t *gc;
-	test_gc_t tgc1;
-	gfx_context_t *gc1;
-	test_gc_t tgc2;
-	gfx_context_t *gc2;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_alloc_t alloc;
-	gfx_bitmap_alloc_t galloc;
-	void *pixels;
-	gfx_rect_t rect;
-	gfx_coord2_t off;
-	errno_t rc;
-
-	/* Create clone GC */
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_clonegc_get_ctx(cgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Add two output GCs */
-	rc = gfx_context_new(&ops, &tgc1, &gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = gfx_context_new(&ops, &tgc2, &gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Create bitmap with caller allocation */
-	tgc1.bm_created = false;
-	tgc2.bm_created = false;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-
-	pixels = calloc(2 * 2, sizeof(uint32_t));
-	PCUT_ASSERT_NOT_NULL(pixels);
-
-	alloc.pitch = 8;
-	alloc.off0 = 0;
-	alloc.pixels = pixels;
-
-	rc = gfx_bitmap_create(gc, &params, &alloc, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.bm_created);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
-
-	PCUT_ASSERT_TRUE(tgc2.bm_created);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc2.bm_params.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc2.bm_params.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc2.bm_params.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc2.bm_params.rect.p1.y);
-
-	/* Get allocation */
-	rc = gfx_bitmap_get_alloc(bitmap, &galloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_INT_EQUALS(alloc.pitch, galloc.pitch);
-	PCUT_ASSERT_INT_EQUALS(alloc.off0, galloc.off0);
-	PCUT_ASSERT_EQUALS(alloc.pixels, galloc.pixels);
-	PCUT_ASSERT_EQUALS(tgc1.bm_pixels, galloc.pixels);
-	PCUT_ASSERT_EQUALS(tgc2.bm_pixels, galloc.pixels);
-
-	/* Render bitmap */
-	tgc1.bm_rendered = false;
-	tgc1.bm_rendered = false;
-	rect.p0.x = 10;
-	rect.p0.y = 20;
-	rect.p1.x = 30;
-	rect.p1.y = 40;
-	off.x = 50;
-	off.y = 60;
-	rc = gfx_bitmap_render(bitmap, &rect, &off);
-	PCUT_ASSERT_TRUE(tgc1.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
-	PCUT_ASSERT_TRUE(tgc2.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
-
-	free(pixels);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Create bitmap, then add second GC, callee allocation */
-PCUT_TEST(bitmap_addgc_callee_alloc)
-{
-	ds_clonegc_t *cgc;
-	gfx_context_t *gc;
-	test_gc_t tgc1;
-	gfx_context_t *gc1;
-	test_gc_t tgc2;
-	gfx_context_t *gc2;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_alloc_t alloc;
-	gfx_rect_t rect;
-	gfx_coord2_t off;
-	errno_t rc;
-
-	/* Create clone GC */
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_clonegc_get_ctx(cgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Add one output GC */
-	rc = gfx_context_new(&ops, &tgc1, &gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Create bitmap with NULL allocation */
-	tgc1.bm_created = false;
-	tgc2.bm_created = false;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-
-	rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.bm_created);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
-
-	PCUT_ASSERT_FALSE(tgc2.bm_created);
-
-	/* Get allocation */
-	rc = gfx_bitmap_get_alloc(bitmap, &alloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_INT_EQUALS(alloc_pitch, alloc.pitch);
-	PCUT_ASSERT_EQUALS(tgc1.bm_pixels, alloc.pixels);
-
-	/* Add second output GC */
-	rc = gfx_context_new(&ops, &tgc2, &gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Render bitmap */
-	tgc1.bm_rendered = false;
-	tgc1.bm_rendered = false;
-	rect.p0.x = 10;
-	rect.p0.y = 20;
-	rect.p1.x = 30;
-	rect.p1.y = 40;
-	off.x = 50;
-	off.y = 60;
-	rc = gfx_bitmap_render(bitmap, &rect, &off);
-	PCUT_ASSERT_TRUE(tgc1.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
-	PCUT_ASSERT_TRUE(tgc2.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-/** Create bitmap, then add second GC, caller allocation */
-PCUT_TEST(bitmap_addgc_caller_alloc)
-{
-	ds_clonegc_t *cgc;
-	gfx_context_t *gc;
-	test_gc_t tgc1;
-	gfx_context_t *gc1;
-	test_gc_t tgc2;
-	gfx_context_t *gc2;
-	gfx_bitmap_params_t params;
-	gfx_bitmap_t *bitmap;
-	gfx_bitmap_alloc_t alloc;
-	gfx_bitmap_alloc_t galloc;
-	void *pixels;
-	gfx_rect_t rect;
-	gfx_coord2_t off;
-	errno_t rc;
-
-	/* Create clone GC */
-	rc = ds_clonegc_create(NULL, &cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_clonegc_get_ctx(cgc);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	/* Add one output GC */
-	rc = gfx_context_new(&ops, &tgc1, &gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Create bitmap with caller allocation */
-	tgc1.bm_created = false;
-	tgc2.bm_created = false;
-	gfx_bitmap_params_init(&params);
-	params.rect.p0.x = 1;
-	params.rect.p0.y = 2;
-	params.rect.p1.x = 3;
-	params.rect.p1.y = 4;
-
-	pixels = calloc(2 * 2, sizeof(uint32_t));
-	PCUT_ASSERT_NOT_NULL(pixels);
-
-	alloc.pitch = 8;
-	alloc.off0 = 0;
-	alloc.pixels = pixels;
-
-	rc = gfx_bitmap_create(gc, &params, &alloc, &bitmap);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(tgc1.bm_created);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.x, tgc1.bm_params.rect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p0.y, tgc1.bm_params.rect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.x, tgc1.bm_params.rect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(params.rect.p1.y, tgc1.bm_params.rect.p1.y);
-
-	PCUT_ASSERT_FALSE(tgc2.bm_created);
-
-	/* Get allocation */
-	rc = gfx_bitmap_get_alloc(bitmap, &galloc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_INT_EQUALS(alloc.pitch, galloc.pitch);
-	PCUT_ASSERT_INT_EQUALS(alloc.off0, galloc.off0);
-	PCUT_ASSERT_EQUALS(alloc.pixels, galloc.pixels);
-	PCUT_ASSERT_EQUALS(tgc1.bm_pixels, galloc.pixels);
-
-	/* Add second output GC */
-	rc = gfx_context_new(&ops, &tgc2, &gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_clonegc_add_output(cgc, gc2);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Render bitmap */
-	tgc1.bm_rendered = false;
-	tgc1.bm_rendered = false;
-	rect.p0.x = 10;
-	rect.p0.y = 20;
-	rect.p1.x = 30;
-	rect.p1.y = 40;
-	off.x = 50;
-	off.y = 60;
-	rc = gfx_bitmap_render(bitmap, &rect, &off);
-	PCUT_ASSERT_TRUE(tgc1.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc1.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc1.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc1.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc1.bm_srect.p1.y);
-	PCUT_ASSERT_TRUE(tgc2.bm_rendered);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.x, tgc2.bm_srect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p0.y, tgc2.bm_srect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.x, tgc2.bm_srect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(rect.p1.y, tgc2.bm_srect.p1.y);
-
-	free(pixels);
-
-	rc = ds_clonegc_delete(cgc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-}
-
-static errno_t testgc_set_color(void *arg, gfx_color_t *color)
-{
-	test_gc_t *tgc = (test_gc_t *) arg;
-
-	tgc->set_color_called = true;
-	tgc->set_color_color = color;
-
-	return tgc->rc;
-}
-
-static errno_t testgc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	test_gc_t *tgc = (test_gc_t *) arg;
-
-	tgc->fill_rect_called = true;
-	tgc->fill_rect_rect = rect;
-
-	return tgc->rc;
-}
-
-static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	test_gc_t *tgc = (test_gc_t *) arg;
-	testgc_bitmap_t *tbm;
-
-	tbm = calloc(1, sizeof(testgc_bitmap_t));
-	if (tbm == NULL)
-		return ENOMEM;
-
-	if (alloc == NULL) {
-		tbm->alloc.pitch = alloc_pitch;
-		tbm->alloc.off0 = alloc_off0;
-		tbm->alloc.pixels = calloc(1, 420);
-		tbm->myalloc = true;
-		if (tbm->alloc.pixels == NULL) {
-			free(tbm);
-			return ENOMEM;
-		}
-	} else {
-		tbm->alloc = *alloc;
-	}
-
-	tbm->tgc = tgc;
-	tgc->bm_created = true;
-	tgc->bm_params = *params;
-	tgc->bm_pixels = tbm->alloc.pixels;
-	*rbm = (void *)tbm;
-	return EOK;
-}
-
-static errno_t testgc_bitmap_destroy(void *bm)
-{
-	testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
-	if (tbm->myalloc)
-		free(tbm->alloc.pixels);
-	tbm->tgc->bm_destroyed = true;
-	free(tbm);
-	return EOK;
-}
-
-static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
-    gfx_coord2_t *offs)
-{
-	testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
-	tbm->tgc->bm_rendered = true;
-	tbm->tgc->bm_srect = *srect;
-	tbm->tgc->bm_offs = *offs;
-	return EOK;
-}
-
-static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
-	*alloc = tbm->alloc;
-	tbm->tgc->bm_got_alloc = true;
-	return EOK;
-}
-
-PCUT_EXPORT(clonegc);
Index: pace/srv/hid/display/test/cursor.c
===================================================================
--- uspace/srv/hid/display/test/cursor.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,261 +1,0 @@
-/*
- * Copyright (c) 2020 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 <gfx/context.h>
-#include <stdbool.h>
-#include <pcut/pcut.h>
-
-#include "../cursor.h"
-#include "../cursimg.h"
-#include "../ddev.h"
-#include "../display.h"
-#include "../display.h"
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(cursor);
-
-static errno_t dummy_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t dummy_bitmap_destroy(void *);
-static errno_t dummy_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t dummy_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static gfx_context_ops_t dummy_ops = {
-	.bitmap_create = dummy_bitmap_create,
-	.bitmap_destroy = dummy_bitmap_destroy,
-	.bitmap_render = dummy_bitmap_render,
-	.bitmap_get_alloc = dummy_bitmap_get_alloc
-};
-
-typedef struct {
-	bool render_called;
-} test_response_t;
-
-typedef struct {
-	test_response_t *resp;
-	gfx_bitmap_alloc_t alloc;
-} dummy_bitmap_t;
-
-/** Test ds_cursor_create(), ds_cursor_destroy(). */
-PCUT_TEST(cursor_create_destroy)
-{
-	ds_display_t *disp;
-	ds_cursor_t *cursor;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
-	    ds_cursimg[dcurs_arrow].image, &cursor);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_cursor_destroy(cursor);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_cursor_paint() renders the cursor. */
-PCUT_TEST(cursor_paint_render)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_cursor_t *cursor;
-	ds_ddev_t *ddev;
-	ddev_info_t ddinfo;
-	gfx_coord2_t pos;
-	test_response_t resp;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, &resp, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ddev_info_init(&ddinfo);
-
-	rc = ds_ddev_create(disp, NULL, &ddinfo, NULL, 0, gc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
-	    ds_cursimg[dcurs_arrow].image, &cursor);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	resp.render_called = false;
-
-	pos.x = 0;
-	pos.y = 0;
-	ds_cursor_paint(cursor, &pos, NULL);
-
-	PCUT_ASSERT_TRUE(resp.render_called);
-
-	ds_cursor_destroy(cursor);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_cursor_paint() optimizes out rendering using clipping rectangle. */
-PCUT_TEST(cursor_paint_norender)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_cursor_t *cursor;
-	ds_ddev_t *ddev;
-	ddev_info_t ddinfo;
-	gfx_coord2_t pos;
-	gfx_rect_t clip;
-	test_response_t resp;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, &resp, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ddev_info_init(&ddinfo);
-
-	rc = ds_ddev_create(disp, NULL, &ddinfo, NULL, 0, gc, &ddev);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
-	    ds_cursimg[dcurs_arrow].image, &cursor);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	resp.render_called = false;
-
-	/*
-	 * Clipping rectangle not intersecting the area where cursor is to
-	 * be rendered
-	 */
-	clip.p0.x = 100;
-	clip.p0.y = 100;
-	clip.p1.x = 150;
-	clip.p1.y = 150;
-
-	pos.x = 0;
-	pos.y = 0;
-	ds_cursor_paint(cursor, &pos, &clip);
-
-	/* Rendering should have been optimized out */
-	PCUT_ASSERT_FALSE(resp.render_called);
-
-	ds_cursor_destroy(cursor);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_cursor_get_rect() */
-PCUT_TEST(cursor_get_rect)
-{
-	ds_display_t *disp;
-	ds_cursor_t *cursor;
-	gfx_coord2_t pos1, pos2;
-	gfx_rect_t rect1, rect2;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
-	    ds_cursimg[dcurs_arrow].image, &cursor);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	pos1.x = 10;
-	pos1.y = 11;
-
-	pos2.x = 22;
-	pos2.y = 23;
-
-	ds_cursor_get_rect(cursor, &pos1, &rect1);
-	ds_cursor_get_rect(cursor, &pos2, &rect2);
-
-	PCUT_ASSERT_FALSE(gfx_rect_is_empty(&rect1));
-	PCUT_ASSERT_FALSE(gfx_rect_is_empty(&rect2));
-
-	PCUT_ASSERT_INT_EQUALS(pos2.x - pos1.x, rect2.p0.x - rect1.p0.x);
-	PCUT_ASSERT_INT_EQUALS(pos2.y - pos1.y, rect2.p0.y - rect1.p0.y);
-	PCUT_ASSERT_INT_EQUALS(pos2.x - pos1.x, rect2.p1.x - rect1.p1.x);
-	PCUT_ASSERT_INT_EQUALS(pos2.y - pos1.y, rect2.p1.y - rect1.p1.y);
-
-	ds_cursor_destroy(cursor);
-	ds_display_destroy(disp);
-}
-
-static errno_t dummy_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	test_response_t *resp = (test_response_t *) arg;
-	dummy_bitmap_t *bm;
-	gfx_coord2_t dims;
-
-	gfx_rect_dims(&params->rect, &dims);
-	bm = calloc(1, sizeof(dummy_bitmap_t));
-	if (bm == NULL)
-		return ENOMEM;
-
-	bm->resp = resp;
-	bm->alloc.pitch = dims.x * sizeof(uint32_t);
-	bm->alloc.off0 = 0;
-
-	bm->alloc.pixels = malloc(bm->alloc.pitch * dims.y * sizeof(uint32_t));
-	if (bm->alloc.pixels == NULL) {
-		free(bm);
-		return ENOMEM;
-	}
-
-	*rbm = (void *) bm;
-	return EOK;
-}
-
-static errno_t dummy_bitmap_destroy(void *arg)
-{
-	dummy_bitmap_t *bm = (dummy_bitmap_t *) arg;
-
-	free(bm);
-	return EOK;
-}
-
-static errno_t dummy_bitmap_render(void *arg, gfx_rect_t *rect,
-    gfx_coord2_t *dpos)
-{
-	dummy_bitmap_t *bm = (dummy_bitmap_t *) arg;
-
-	bm->resp->render_called = true;
-	return EOK;
-}
-
-static errno_t dummy_bitmap_get_alloc(void *arg, gfx_bitmap_alloc_t *alloc)
-{
-	dummy_bitmap_t *bm = (dummy_bitmap_t *) arg;
-
-	*alloc = bm->alloc;
-	return EOK;
-}
-
-PCUT_EXPORT(cursor);
Index: pace/srv/hid/display/test/display.c
===================================================================
--- uspace/srv/hid/display/test/display.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,432 +1,0 @@
-/*
- * Copyright (c) 2019 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 <disp_srv.h>
-#include <errno.h>
-#include <pcut/pcut.h>
-#include <str.h>
-
-#include "../client.h"
-#include "../display.h"
-#include "../seat.h"
-#include "../window.h"
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(display);
-
-static void test_ds_ev_pending(void *);
-
-static ds_client_cb_t test_ds_client_cb = {
-	.ev_pending = test_ds_ev_pending
-};
-
-static void test_ds_ev_pending(void *arg)
-{
-	bool *called_cb = (bool *) arg;
-	*called_cb = true;
-}
-
-/** Display creation and destruction. */
-PCUT_TEST(display_create_destroy)
-{
-	ds_display_t *disp;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_display_destroy(disp);
-}
-
-/** Basic client operation. */
-PCUT_TEST(display_client)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_client_t *c0, *c1;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	c0 = ds_display_first_client(disp);
-	PCUT_ASSERT_EQUALS(c0, client);
-
-	c1 = ds_display_next_client(c0);
-	PCUT_ASSERT_NULL(c1);
-
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_display_find_window(). */
-PCUT_TEST(display_find_window)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *w0;
-	ds_window_t *w1;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	wnd = ds_display_first_window(disp);
-	PCUT_ASSERT_EQUALS(w0, wnd);
-
-	wnd = ds_display_next_window(wnd);
-	PCUT_ASSERT_EQUALS(w1, wnd);
-
-	wnd = ds_display_next_window(wnd);
-	PCUT_ASSERT_NULL(wnd);
-
-	wnd = ds_display_last_window(disp);
-	PCUT_ASSERT_EQUALS(w1, wnd);
-
-	wnd = ds_display_prev_window(wnd);
-	PCUT_ASSERT_EQUALS(w0, wnd);
-
-	wnd = ds_display_prev_window(wnd);
-	PCUT_ASSERT_NULL(wnd);
-
-	wnd = ds_display_find_window(disp, w0->id);
-	PCUT_ASSERT_EQUALS(w0, wnd);
-
-	wnd = ds_display_find_window(disp, w1->id);
-	PCUT_ASSERT_EQUALS(w1, wnd);
-
-	wnd = ds_display_find_window(disp, 0);
-	PCUT_ASSERT_NULL(wnd);
-
-	wnd = ds_display_find_window(disp, w0->id + 1);
-	PCUT_ASSERT_NULL(wnd);
-
-	ds_window_destroy(w0);
-	ds_window_destroy(w1);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** 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;
-	display_wnd_params_t params;
-	gfx_coord2_t pos;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, &test_ds_client_cb, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 100;
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &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)
-{
-	ds_display_t *disp;
-	ds_seat_t *seat;
-	ds_seat_t *s0, *s1;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	s0 = ds_display_first_seat(disp);
-	PCUT_ASSERT_EQUALS(s0, seat);
-
-	s1 = ds_display_next_seat(s0);
-	PCUT_ASSERT_NULL(s1);
-
-	ds_seat_destroy(seat);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_display_post_kbd_event() delivers event to client callback.
- */
-PCUT_TEST(display_post_kbd_event)
-{
-	ds_display_t *disp;
-	ds_seat_t *seat;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	kbd_event_t event;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &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);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_seat_set_focus(seat, wnd);
-
-	event.type = KEY_PRESS;
-	event.key = KC_ENTER;
-	event.mods = 0;
-	event.c = L'\0';
-
-	called_cb = false;
-
-	rc = ds_display_post_kbd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_seat_destroy(seat);
-	ds_display_destroy(disp);
-}
-
-/** 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;
-	display_wnd_params_t params;
-	kbd_event_t event;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &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);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &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';
-
-	called_cb = false;
-
-	rc = ds_display_post_kbd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Got gocus/unfocus events */
-	PCUT_ASSERT_TRUE(called_cb);
-
-	/* Next window should be focused */
-	PCUT_ASSERT_EQUALS(w1, seat->focus);
-
-	called_cb = false;
-
-	rc = ds_display_post_kbd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	/* Got gocus/unfocus events */
-	PCUT_ASSERT_TRUE(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_ptd_event() with click on window switches focus
- */
-PCUT_TEST(display_post_ptd_event_wnd_switch)
-{
-	ds_display_t *disp;
-	ds_seat_t *seat;
-	ds_client_t *client;
-	ds_window_t *w0, *w1;
-	display_wnd_params_t params;
-	ptd_event_t event;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &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);
-
-	/*
-	 * For PTD_MOVE to work we need to set display dimensions (as pointer
-	 * move is clipped to the display rectangle. Here we do it directly
-	 * instead of adding a display device.
-	 */
-	disp->rect.p0.x = 0;
-	disp->rect.p0.y = 0;
-	disp->rect.p1.x = 500;
-	disp->rect.p1.y = 500;
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &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 = PTD_MOVE;
-	event.dmove.x = 400;
-	event.dmove.y = 400;
-	rc = ds_display_post_ptd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	event.type = PTD_PRESS;
-	event.btn_num = 1;
-	rc = ds_display_post_ptd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_EQUALS(w1, seat->focus);
-
-	event.type = PTD_RELEASE;
-	event.btn_num = 1;
-	rc = ds_display_post_ptd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	event.type = PTD_MOVE;
-	event.dmove.x = -400 + 10;
-	event.dmove.y = -400 + 10;
-	rc = ds_display_post_ptd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	event.type = PTD_PRESS;
-	event.btn_num = 1;
-	rc = ds_display_post_ptd_event(disp, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	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);
Index: pace/srv/hid/display/test/main.c
===================================================================
--- uspace/srv/hid/display/test/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,40 +1,0 @@
-/*
- * Copyright (c) 2019 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 <pcut/pcut.h>
-
-PCUT_INIT;
-
-PCUT_IMPORT(client);
-PCUT_IMPORT(clonegc);
-PCUT_IMPORT(cursor);
-PCUT_IMPORT(display);
-PCUT_IMPORT(seat);
-PCUT_IMPORT(window);
-
-PCUT_MAIN();
Index: pace/srv/hid/display/test/seat.c
===================================================================
--- uspace/srv/hid/display/test/seat.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,379 +1,0 @@
-/*
- * Copyright (c) 2019 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 <disp_srv.h>
-#include <errno.h>
-#include <pcut/pcut.h>
-#include <str.h>
-
-#include "../client.h"
-#include "../display.h"
-#include "../seat.h"
-#include "../window.h"
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(seat);
-
-static void test_ds_ev_pending(void *);
-
-static ds_client_cb_t test_ds_client_cb = {
-	.ev_pending = test_ds_ev_pending
-};
-
-static void test_ds_ev_pending(void *arg)
-{
-	bool *called_cb = (bool *) arg;
-	*called_cb = true;
-}
-
-/** Set focus. */
-PCUT_TEST(set_focus)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	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_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_seat_set_focus(seat, wnd);
-	PCUT_ASSERT_EQUALS(wnd, seat->focus);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	ds_window_destroy(wnd);
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Evacuate focus. */
-PCUT_TEST(evac_focus)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	ds_window_t *w0;
-	ds_window_t *w1;
-	display_wnd_params_t params;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	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_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_seat_set_focus(seat, w1);
-	PCUT_ASSERT_EQUALS(w1, seat->focus);
-	PCUT_ASSERT_TRUE(called_cb);
-	called_cb = false;
-
-	ds_seat_evac_focus(seat, w1);
-	PCUT_ASSERT_EQUALS(w0, seat->focus);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	ds_window_destroy(w0);
-	ds_window_destroy(w1);
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_seat_post_kbd_event() with Alt-Tab switches focus */
-PCUT_TEST(post_kbd_event_alt_tab)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	ds_window_t *w0;
-	ds_window_t *w1;
-	display_wnd_params_t params;
-	bool called_cb = false;
-	kbd_event_t event;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	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_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_seat_set_focus(seat, w1);
-	PCUT_ASSERT_EQUALS(w1, seat->focus);
-	PCUT_ASSERT_TRUE(called_cb);
-	called_cb = false;
-
-	event.type = KEY_PRESS;
-	event.mods = KM_ALT;
-	event.key = KC_TAB;
-	rc = ds_seat_post_kbd_event(seat, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(w0, seat->focus);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	ds_window_destroy(w0);
-	ds_window_destroy(w1);
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_seat_post_kbd_event() with regular key press delivers to client queue */
-PCUT_TEST(post_kbd_event_regular)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	kbd_event_t event;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	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_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_seat_set_focus(seat, wnd);
-	PCUT_ASSERT_EQUALS(wnd, seat->focus);
-
-	PCUT_ASSERT_TRUE(called_cb);
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	called_cb = false;
-
-	event.type = KEY_PRESS;
-	event.key = KC_ENTER;
-	event.mods = 0;
-	event.c = L'\0';
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	rc = ds_seat_post_kbd_event(seat, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_kbd, revent.etype);
-	PCUT_ASSERT_EQUALS(event.type, revent.ev.kbd.type);
-	PCUT_ASSERT_EQUALS(event.key, revent.ev.kbd.key);
-	PCUT_ASSERT_EQUALS(event.mods, revent.ev.kbd.mods);
-	PCUT_ASSERT_EQUALS(event.c, revent.ev.kbd.c);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_seat_post_ptd_event() with click on window switches focus
- */
-PCUT_TEST(post_ptd_event_wnd_switch)
-{
-	ds_display_t *disp;
-	ds_seat_t *seat;
-	ds_client_t *client;
-	ds_window_t *w0, *w1;
-	display_wnd_params_t params;
-	ptd_event_t event;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &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);
-
-	/* Set up display size to allow the pointer a range of movement */
-	disp->rect.p1.x = 500;
-	disp->rect.p1.y = 500;
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &w0);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_window_create(client, &params, &w1);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	w0->dpos.x = 10;
-	w0->dpos.y = 10;
-
-	w1->dpos.x = 400;
-	w1->dpos.y = 400;
-
-	PCUT_ASSERT_FALSE(called_cb);
-
-	ds_seat_set_focus(seat, w0);
-
-	event.type = PTD_MOVE;
-	event.dmove.x = 400;
-	event.dmove.y = 400;
-	rc = ds_seat_post_ptd_event(seat, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_TRUE(called_cb);
-	called_cb = false;
-
-	event.type = PTD_PRESS;
-	event.btn_num = 1;
-	rc = ds_seat_post_ptd_event(seat, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-	called_cb = false;
-
-	PCUT_ASSERT_EQUALS(w1, seat->focus);
-
-	event.type = PTD_MOVE;
-	event.dmove.x = -400 + 10;
-	event.dmove.y = -400 + 10;
-	rc = ds_seat_post_ptd_event(seat, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-	called_cb = false;
-
-	event.type = PTD_PRESS;
-	event.btn_num = 1;
-	rc = ds_seat_post_ptd_event(seat, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_TRUE(called_cb);
-	called_cb = false;
-
-	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_seat_post_pos_event() */
-PCUT_TEST(post_pos_event)
-{
-	// XXX
-}
-
-/** Set WM cursor */
-PCUT_TEST(set_wm_cursor)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	bool called_cb = false;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	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_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	ds_seat_set_wm_cursor(seat, disp->cursor[dcurs_size_ud]);
-	ds_seat_set_wm_cursor(seat, NULL);
-
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-PCUT_EXPORT(seat);
Index: pace/srv/hid/display/test/window.c
===================================================================
--- uspace/srv/hid/display/test/window.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,662 +1,0 @@
-/*
- * Copyright (c) 2019 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 <disp_srv.h>
-#include <errno.h>
-#include <gfx/context.h>
-#include <pcut/pcut.h>
-#include <stdio.h>
-#include <str.h>
-
-#include "../client.h"
-#include "../display.h"
-#include "../seat.h"
-#include "../window.h"
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(window);
-
-static errno_t dummy_set_color(void *, gfx_color_t *);
-static errno_t dummy_fill_rect(void *, gfx_rect_t *);
-
-static gfx_context_ops_t dummy_ops = {
-	.set_color = dummy_set_color,
-	.fill_rect = dummy_fill_rect
-};
-
-/** Test ds_window_resize(). */
-PCUT_TEST(window_resize)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	gfx_coord2_t offs;
-	gfx_rect_t nrect;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 10;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	wnd->dpos.x = 100;
-	wnd->dpos.y = 100;
-
-	offs.x = -2;
-	offs.y = -3;
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = 12;
-	params.rect.p1.y = 13;
-	rc = ds_window_resize(wnd, &offs, &nrect);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(98, wnd->dpos.x);
-	PCUT_ASSERT_INT_EQUALS(97, wnd->dpos.y);
-
-	ds_window_destroy(wnd);
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_window_get_ctx(). */
-PCUT_TEST(window_get_ctx)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	gc = ds_window_get_ctx(wnd);
-	PCUT_ASSERT_NOT_NULL(gc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_window_post_kbd_event() with Alt-F4 sends close event */
-PCUT_TEST(window_post_kbd_event_alt_f4)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	ds_window_t *rwindow;
-	display_wnd_ev_t revent;
-	display_wnd_params_t params;
-	kbd_event_t event;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, NULL, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	event.type = KEY_PRESS;
-	event.mods = KM_ALT;
-	event.key = KC_F4;
-	rc = ds_window_post_kbd_event(wnd, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd, rwindow);
-	PCUT_ASSERT_EQUALS(wev_close, revent.etype);
-
-	rc = ds_client_get_event(client, &rwindow, &revent);
-	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_window_post_pos_event() */
-PCUT_TEST(window_post_pos_event)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	pos_event_t event;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, NULL, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
-
-	wnd->dpos.x = 10;
-	wnd->dpos.y = 10;
-
-	event.type = POS_PRESS;
-	event.btn_num = 2;
-	event.hpos = 10;
-	event.vpos = 10;
-	rc = ds_window_post_pos_event(wnd, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
-
-	event.type = POS_UPDATE;
-	event.hpos = 11;
-	event.vpos = 12;
-	rc = ds_window_post_pos_event(wnd, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
-	/* Window position does not update until after release */
-	PCUT_ASSERT_INT_EQUALS(10, wnd->dpos.x);
-	PCUT_ASSERT_INT_EQUALS(10, wnd->dpos.y);
-
-	event.type = POS_RELEASE;
-	event.hpos = 13;
-	event.vpos = 14;
-
-	rc = ds_window_post_pos_event(wnd, &event);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
-	PCUT_ASSERT_INT_EQUALS(13, wnd->dpos.x);
-	PCUT_ASSERT_INT_EQUALS(14, wnd->dpos.y);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_window_move_req() */
-PCUT_TEST(window_move_req)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	gfx_coord2_t pos;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, NULL, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
-
-	pos.x = 42;
-	pos.y = 43;
-	ds_window_move_req(wnd, &pos);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
-	PCUT_ASSERT_INT_EQUALS(pos.x, wnd->orig_pos.x);
-	PCUT_ASSERT_INT_EQUALS(pos.y, wnd->orig_pos.y);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_window_resize_req() */
-PCUT_TEST(window_resize_req)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_seat_t *seat;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	gfx_coord2_t pos;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, NULL, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_seat_create(disp, &seat);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
-
-	pos.x = 42;
-	pos.y = 43;
-	ds_window_resize_req(wnd, display_wr_top_right, &pos);
-
-	PCUT_ASSERT_INT_EQUALS(dsw_resizing, wnd->state);
-	PCUT_ASSERT_INT_EQUALS(display_wr_top_right, wnd->rsztype);
-	PCUT_ASSERT_INT_EQUALS(pos.x, wnd->orig_pos.x);
-	PCUT_ASSERT_INT_EQUALS(pos.y, wnd->orig_pos.y);
-
-	ds_window_destroy(wnd);
-	ds_seat_destroy(seat);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-PCUT_TEST(window_calc_resize)
-{
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	gfx_coord2_t dresize;
-	gfx_coord2_t dresizen;
-	gfx_coord2_t dresizeb;
-	gfx_coord2_t dresizebn;
-	gfx_rect_t nrect;
-	errno_t rc;
-
-	rc = ds_display_create(NULL, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = 10;
-	params.rect.p0.y = 11;
-	params.rect.p1.x = 30;
-	params.rect.p1.y = 31;
-	params.min_size.x = 2;
-	params.min_size.y = 3;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	wnd->state = dsw_resizing;
-
-	dresize.x = 5;
-	dresize.y = 6;
-
-	dresizen.x = -5;
-	dresizen.y = -6;
-
-	dresizeb.x = 50;
-	dresizeb.y = 60;
-
-	dresizebn.x = -50;
-	dresizebn.y = -60;
-
-	/* Resize top */
-	wnd->rsztype = display_wr_top;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(17, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(5, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(28, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(-49, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	/* Resize top left */
-	wnd->rsztype = display_wr_top_left;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(15, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(17, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(5, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(5, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(28, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(28, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(-40, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(-49, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	/* Resize left */
-	wnd->rsztype = display_wr_left;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(15, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(5, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(28, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(-40, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	/* Resize bottom left */
-	wnd->rsztype = display_wr_bottom_left;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(15, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(37, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(5, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(25, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(28, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(91, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(-40, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(14, nrect.p1.y);
-
-	/* Resize bottom */
-	wnd->rsztype = display_wr_bottom;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(37, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(25, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(91, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(30, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(14, nrect.p1.y);
-
-	/* Resize bottom right */
-	wnd->rsztype = display_wr_bottom_right;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(35, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(37, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(25, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(25, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(80, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(91, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(12, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(14, nrect.p1.y);
-
-	/* Resize right */
-	wnd->rsztype = display_wr_right;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(35, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(25, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(80, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(11, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(12, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	/* Resize top right */
-	wnd->rsztype = display_wr_top_right;
-
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(17, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(35, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizen, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(5, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(25, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizeb, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(28, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(80, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_calc_resize(wnd, &dresizebn, &nrect);
-	PCUT_ASSERT_INT_EQUALS(10, nrect.p0.x);
-	PCUT_ASSERT_INT_EQUALS(-49, nrect.p0.y);
-	PCUT_ASSERT_INT_EQUALS(12, nrect.p1.x);
-	PCUT_ASSERT_INT_EQUALS(31, nrect.p1.y);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-/** Test ds_window_set_cursor() */
-PCUT_TEST(window_set_cursor)
-{
-	gfx_context_t *gc;
-	ds_display_t *disp;
-	ds_client_t *client;
-	ds_window_t *wnd;
-	display_wnd_params_t params;
-	errno_t rc;
-
-	rc = gfx_context_new(&dummy_ops, NULL, &gc);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_display_create(gc, df_none, &disp);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = ds_client_create(disp, NULL, NULL, &client);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	display_wnd_params_init(&params);
-	params.rect.p0.x = params.rect.p0.y = 0;
-	params.rect.p1.x = params.rect.p1.y = 1;
-
-	rc = ds_window_create(client, &params, &wnd);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_EQUALS(wnd->display->cursor[dcurs_arrow], wnd->cursor);
-
-	rc = ds_window_set_cursor(wnd, -1);
-	PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
-	PCUT_ASSERT_EQUALS(wnd->display->cursor[dcurs_arrow], wnd->cursor);
-
-	rc = ds_window_set_cursor(wnd, dcurs_limit);
-	PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
-	PCUT_ASSERT_EQUALS(wnd->display->cursor[dcurs_arrow], wnd->cursor);
-
-	rc = ds_window_set_cursor(wnd, dcurs_limit + 1);
-	PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
-	PCUT_ASSERT_EQUALS(wnd->display->cursor[dcurs_arrow], wnd->cursor);
-
-	rc = ds_window_set_cursor(wnd, dcurs_size_lr);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_EQUALS(wnd->display->cursor[dcurs_size_lr], wnd->cursor);
-
-	ds_window_destroy(wnd);
-	ds_client_destroy(client);
-	ds_display_destroy(disp);
-}
-
-static errno_t dummy_set_color(void *arg, gfx_color_t *color)
-{
-	return EOK;
-}
-
-static errno_t dummy_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	return EOK;
-}
-
-PCUT_EXPORT(window);
Index: pace/srv/hid/display/types/display/client.h
===================================================================
--- uspace/srv/hid/display/types/display/client.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,67 +1,0 @@
-/*
- * Copyright (c) 2019 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 client type
- */
-
-#ifndef TYPES_DISPLAY_CLIENT_H
-#define TYPES_DISPLAY_CLIENT_H
-
-#include <adt/list.h>
-
-typedef sysarg_t ds_wnd_id_t;
-
-/** Display server client callbacks */
-typedef struct {
-	void (*ev_pending)(void *);
-} ds_client_cb_t;
-
-/** Display server client */
-typedef struct ds_client {
-	/** Parent display */
-	struct ds_display *display;
-	/** Callbacks */
-	ds_client_cb_t *cb;
-	/** Callback argument */
-	void *cb_arg;
-	/** Link to @c display->clients */
-	link_t lclients;
-	/** Windows (of ds_window_t) */
-	list_t windows;
-	/** Event queue (of ds_window_ev_t) */
-	list_t events;
-} ds_client_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/clonegc.h
===================================================================
--- uspace/srv/hid/display/types/display/clonegc.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,110 +1,0 @@
-/*
- * Copyright (c) 2020 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 Cloning graphic context
- */
-
-#ifndef TYPES_DISPLAY_CLONEGC_H
-#define TYPES_DISPLAY_CLONEGC_H
-
-#include <adt/list.h>
-#include <gfx/context.h>
-
-/** Cloning graphic context.
- *
- * A graphic context that clones rendering to a number of GCs. We need
- * to clone every bitmap to every GC so we end up with a matrix-like
- * structure (made of linked lists).
- *
- * ds_clonegc_output_t x ds_clonegc_bitmap_t -> ds_clonegc_outbitmap_t.
- */
-typedef struct {
-	/** Graphic context */
-	gfx_context_t *gc;
-	/** Output GCs (of ds_clonegc_output_t) */
-	list_t outputs;
-	/** Bitmaps (of ds_clonegc_bitmap_t) */
-	list_t bitmaps;
-} ds_clonegc_t;
-
-/** Clone GC output */
-typedef struct {
-	/** Containing clone GC */
-	ds_clonegc_t *clonegc;
-	/** Link to @c clonegc->outputs */
-	link_t loutputs;
-	/** Output GC */
-	gfx_context_t *gc;
-	/** Output bitmaps (of ds_clonegc_outbitmap_t) */
-	list_t obitmaps;
-} ds_clonegc_output_t;
-
-/** Bitmap in cloning GC.
- *
- * Has a list of output bitmaps for all outputs.
- */
-typedef struct {
-	/** Containing clone GC */
-	ds_clonegc_t *clonegc;
-	/** Bitmap parameters */
-	gfx_bitmap_params_t params;
-	/** Bitmap allocation */
-	gfx_bitmap_alloc_t alloc;
-	/** Link to @c clonegc->bitmaps */
-	link_t lbitmaps;
-	/** Output bitmaps (of ds_clonegc_outbitmap_t) */
-	list_t obitmaps;
-} ds_clonegc_bitmap_t;
-
-/** Output bitmap in cloning GC.
- *
- * It is contained in two linked lists. The list of all output bitmaps for
- * a particular output and the list of all output bitmaps for a particular
- * bitmap.
- */
-typedef struct {
-	/** Containing output */
-	ds_clonegc_output_t *output;
-	/** Containing bitmap */
-	ds_clonegc_bitmap_t *bitmap;
-	/** Link to @c output->obitmaps */
-	link_t lobitmaps;
-	/** Linkt ot @c bitmap->obitmaps */
-	link_t lbbitmaps;
-	/** Output-specific bitmap */
-	gfx_bitmap_t *obitmap;
-} ds_clonegc_outbitmap_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/cursimg.h
===================================================================
--- uspace/srv/hid/display/types/display/cursimg.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2020 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 cursor image type
- */
-
-#ifndef TYPES_DISPLAY_CURSIMG_H
-#define TYPES_DISPLAY_CURSIMG_H
-
-#include <gfx/coord.h>
-#include <stdint.h>
-
-/** Bitmap in display server window GC */
-typedef struct {
-	gfx_rect_t rect;
-	/** Image, 0 = background, 1 = black, 2 = white */
-	const uint8_t *image;
-} ds_cursimg_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/cursor.h
===================================================================
--- uspace/srv/hid/display/types/display/cursor.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2020 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 cursor type
- */
-
-#ifndef TYPES_DISPLAY_CURSOR_H
-#define TYPES_DISPLAY_CURSOR_H
-
-#include <adt/list.h>
-#include <gfx/bitmap.h>
-#include <gfx/coord.h>
-
-/** Bitmap in display server window GC */
-typedef struct ds_cursor {
-	/** Containing display */
-	struct ds_display *display;
-	/** Link to list of all cursors in display */
-	link_t ldisplay;
-	/** Bitmap in the display device */
-	gfx_bitmap_t *bitmap;
-	/** Rectangle represented in the image */
-	gfx_rect_t rect;
-	/** Cursor image */
-	const uint8_t *image;
-} ds_cursor_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/ddev.h
===================================================================
--- uspace/srv/hid/display/types/display/ddev.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,67 +1,0 @@
-/*
- * Copyright (c) 2019 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 display device type
- */
-
-#ifndef TYPES_DISPLAY_DDEV_H
-#define TYPES_DISPLAY_DDEV_H
-
-#include <adt/list.h>
-#include <ddev.h>
-#include <gfx/context.h>
-#include <loc.h>
-
-/** Display server display device */
-typedef struct ds_ddev {
-	/** Parent display */
-	struct ds_display *display;
-	/** Link to display->ddevs */
-	link_t lddevs;
-	/** Link to output->ddevs */
-	link_t loutdevs;
-	/** Device GC */
-	gfx_context_t *gc;
-	/** Display device information */
-	ddev_info_t info;
-	/** Service ID */
-	service_id_t svc_id;
-	/** Service name */
-	char *svc_name;
-	/** Underlying display device */
-	ddev_t *dd;
-} ds_ddev_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/display.h
===================================================================
--- uspace/srv/hid/display/types/display/display.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/*
- * Copyright (c) 2019 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 display type
- */
-
-#ifndef TYPES_DISPLAY_DISPLAY_H
-#define TYPES_DISPLAY_DISPLAY_H
-
-#include <adt/list.h>
-#include <fibril_synch.h>
-#include <gfx/color.h>
-#include <gfx/coord.h>
-#include <io/input.h>
-#include <memgfx/memgc.h>
-#include <types/display/cursor.h>
-#include "cursor.h"
-#include "clonegc.h"
-#include "window.h"
-
-/** Display flags */
-typedef enum {
-	/** No flags enabled */
-	df_none = 0,
-	/** Use double buffer for display */
-	df_disp_double_buf = 0x1
-} ds_display_flags_t;
-
-/** Display server display */
-typedef struct ds_display {
-	/** Synchronize access to display */
-	fibril_mutex_t lock;
-	/** Clients (of ds_client_t) */
-	list_t clients;
-
-	/** Next ID to assign to a window.
-	 *
-	 * XXX Window IDs need to be unique per display just because
-	 * we don't have a way to match GC connection to the proper
-	 * client. Really this should be in ds_client_t and the ID
-	 * space should be per client.
-	 */
-	ds_wnd_id_t next_wnd_id;
-	/** Input service */
-	input_t *input;
-
-	/** Seats (of ds_seat_t) */
-	list_t seats;
-
-	/** Windows (of ds_window_t) in stacking order */
-	list_t windows;
-
-	/** Display devices (of ds_ddev_t) */
-	list_t ddevs;
-
-	/** Background color */
-	gfx_color_t *bg_color;
-
-	/** Stock cursors */
-	ds_cursor_t *cursor[dcurs_limit];
-
-	/** List of all cursors */
-	list_t cursors;
-
-	/** Bounding rectangle */
-	gfx_rect_t rect;
-
-	/** Backbuffer bitmap or @c NULL if not double-buffering */
-	gfx_bitmap_t *backbuf;
-
-	/** Backbuffer GC or @c NULL if not double-buffering */
-	mem_gc_t *bbgc;
-
-	/** Frontbuffer (clone) GC */
-	ds_clonegc_t *fbgc;
-
-	/** Backbuffer dirty rectangle */
-	gfx_rect_t dirty_rect;
-
-	/** Display flags */
-	ds_display_flags_t flags;
-} ds_display_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/output.h
===================================================================
--- uspace/srv/hid/display/types/display/output.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/*
- * Copyright (c) 2019 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 output
- */
-
-#ifndef TYPES_DISPLAY_OUTPUT_H
-#define TYPES_DISPLAY_OUTPUT_H
-
-#include <adt/list.h>
-#include <fibril_synch.h>
-
-/** Display server output */
-typedef struct ds_output {
-	/** Discovery lock */
-	fibril_mutex_t lock;
-	/** Display devices (of ds_ddev_t) */
-	list_t ddevs;
-	/** Display to which we will be adding discovered devices */
-	struct ds_display *def_display;
-} ds_output_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/ptd_event.h
===================================================================
--- uspace/srv/hid/display/types/display/ptd_event.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2019 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef TYPES_DISPLAY_PTD_EVENT_H
-#define TYPES_DISPLAY_PTD_EVENT_H
-
-#include <gfx/coord.h>
-
-typedef enum {
-	PTD_MOVE,
-	PTD_ABS_MOVE,
-	PTD_PRESS,
-	PTD_RELEASE
-} ptd_event_type_t;
-
-/** Pointing device event */
-typedef struct {
-	ptd_event_type_t type;
-	/** Button number for PTD_PRESS or PTD_RELEASE */
-	int btn_num;
-	/** Relative move vector for PTD_MOVE */
-	gfx_coord2_t dmove;
-	/** Absolute position for PTD_ABS_MOVE */
-	gfx_coord2_t apos;
-	/** Absolute position bounds for PTD_ABS_MOVE */
-	gfx_rect_t abounds;
-} ptd_event_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/seat.h
===================================================================
--- uspace/srv/hid/display/types/display/seat.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2019 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 seat type
- */
-
-#ifndef TYPES_DISPLAY_SEAT_H
-#define TYPES_DISPLAY_SEAT_H
-
-#include <adt/list.h>
-#include <gfx/coord.h>
-
-/** Display server seat */
-typedef struct ds_seat {
-	/** Containing display */
-	struct ds_display *display;
-	/** Link to display->seats */
-	link_t lseats;
-	/** Window this seat is focused on */
-	struct ds_window *focus;
-	/** Cursor selected by client */
-	struct ds_cursor *client_cursor;
-	/** Cursor override for window management or @c NULL */
-	struct ds_cursor *wm_cursor;
-	/** Pointer position */
-	gfx_coord2_t pntpos;
-} ds_seat_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/types/display/window.h
===================================================================
--- uspace/srv/hid/display/types/display/window.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,130 +1,0 @@
-/*
- * Copyright (c) 2019 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 window type
- */
-
-#ifndef TYPES_DISPLAY_WINDOW_H
-#define TYPES_DISPLAY_WINDOW_H
-
-#include <adt/list.h>
-#include <display/event.h>
-#include <display/wndresize.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
-#include <io/pixel.h>
-#include <io/pixelmap.h>
-#include <memgfx/memgc.h>
-
-typedef sysarg_t ds_wnd_id_t;
-
-/** Window state */
-typedef enum {
-	/** Idle */
-	dsw_idle,
-	/** Moving by mouse drag */
-	dsw_moving,
-	/** Resizing by mouse drag */
-	dsw_resizing
-} ds_window_state_t;
-
-/** Display server window */
-typedef struct ds_window {
-	/** Parent client */
-	struct ds_client *client;
-	/** Link to @c client->windows */
-	link_t lcwindows;
-	/** Containing display */
-	struct ds_display *display;
-	/** Link to @c display->windows */
-	link_t ldwindows;
-	/** Bounding rectangle */
-	gfx_rect_t rect;
-	/** Display position */
-	gfx_coord2_t dpos;
-	/** Preview position (when moving) */
-	gfx_coord2_t preview_pos;
-	/** Preview rectangle (when resizing) */
-	gfx_rect_t preview_rect;
-	/** Minimum size */
-	gfx_coord2_t min_size;
-	/** Window ID */
-	ds_wnd_id_t id;
-	/** Memory GC */
-	mem_gc_t *mgc;
-	/** Graphic context */
-	gfx_context_t *gc;
-	/** Bitmap in the display device */
-	gfx_bitmap_t *bitmap;
-	/** Pixel map for accessing the window bitmap */
-	pixelmap_t pixelmap;
-	/** Current drawing color */
-	pixel_t color;
-	/** Cursor set by client */
-	struct ds_cursor *cursor;
-
-	/** State */
-	ds_window_state_t state;
-	/** Original position before started to move or resize the window */
-	gfx_coord2_t orig_pos;
-	/** Window resize type (if state is dsw_resizing) */
-	display_wnd_rsztype_t rsztype;
-} ds_window_t;
-
-/** Window event queue entry */
-typedef struct {
-	/** Link to event queue */
-	link_t levents;
-	/** Window to which the event is delivered */
-	ds_window_t *window;
-	/** Event */
-	display_wnd_ev_t event;
-} ds_window_ev_t;
-
-/** Bitmap in display server window GC */
-typedef struct {
-	/** Containing window */
-	ds_window_t *wnd;
-	/** Display bitmap */
-	gfx_bitmap_t *bitmap;
-	/** Bounding rectangle */
-	gfx_rect_t rect;
-	/** Bitmap flags */
-	gfx_bitmap_flags_t flags;
-	/** Key color */
-	pixel_t key_color;
-} ds_window_bitmap_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/hid/display/window.c
===================================================================
--- uspace/srv/hid/display/window.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,805 +1,0 @@
-/*
- * Copyright (c) 2019 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 window
- */
-
-#include <gfx/bitmap.h>
-#include <gfx/color.h>
-#include <gfx/coord.h>
-#include <gfx/context.h>
-#include <gfx/render.h>
-#include <io/log.h>
-#include <io/pixelmap.h>
-#include <macros.h>
-#include <memgfx/memgc.h>
-#include <stdlib.h>
-#include "client.h"
-#include "display.h"
-#include "seat.h"
-#include "window.h"
-
-static void ds_window_update_cb(void *, gfx_rect_t *);
-static void ds_window_get_preview_rect(ds_window_t *, gfx_rect_t *);
-
-/** Create window.
- *
- * Create graphics context for rendering into a window.
- *
- * @param client Client owning the window
- * @param params Window parameters
- * @param rgc Place to store pointer to new GC.
- *
- * @return EOK on success or an error code
- */
-errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params,
-    ds_window_t **rgc)
-{
-	ds_window_t *wnd = NULL;
-	gfx_context_t *dgc;
-	gfx_coord2_t dims;
-	gfx_bitmap_params_t bparams;
-	gfx_bitmap_alloc_t alloc;
-	errno_t rc;
-
-	wnd = calloc(1, sizeof(ds_window_t));
-	if (wnd == NULL) {
-		rc = ENOMEM;
-		goto error;
-	}
-
-	ds_client_add_window(client, wnd);
-	ds_display_add_window(client->display, wnd);
-
-	gfx_bitmap_params_init(&bparams);
-	bparams.rect = params->rect;
-
-	dgc = ds_display_get_gc(wnd->display);
-	if (dgc != NULL) {
-		rc = gfx_bitmap_create(dgc, &bparams, NULL, &wnd->bitmap);
-		if (rc != EOK)
-			goto error;
-
-		rc = gfx_bitmap_get_alloc(wnd->bitmap, &alloc);
-		if (rc != EOK)
-			goto error;
-
-		gfx_rect_dims(&params->rect, &dims);
-		wnd->pixelmap.width = dims.x;
-		wnd->pixelmap.height = dims.y;
-		wnd->pixelmap.data = alloc.pixels;
-	} else {
-		/* This is just for unit tests */
-		gfx_rect_dims(&params->rect, &dims);
-		alloc.pitch = dims.x * sizeof(uint32_t);
-		alloc.off0 = 0;
-		alloc.pixels = calloc(1, alloc.pitch * dims.y);
-	}
-
-	rc = mem_gc_create(&params->rect, &alloc, ds_window_update_cb,
-	    (void *)wnd, &wnd->mgc);
-	if (rc != EOK)
-		goto error;
-
-	wnd->rect = params->rect;
-	wnd->min_size = params->min_size;
-	wnd->gc = mem_gc_get_ctx(wnd->mgc);
-	wnd->cursor = wnd->display->cursor[dcurs_arrow];
-	*rgc = wnd;
-	return EOK;
-error:
-	if (wnd != NULL) {
-		if (wnd->bitmap != NULL)
-			gfx_bitmap_destroy(wnd->bitmap);
-		free(wnd);
-	}
-
-	return rc;
-}
-
-/** Destroy window.
- *
- * @param wnd Window
- */
-void ds_window_destroy(ds_window_t *wnd)
-{
-	ds_display_t *disp;
-
-	disp = wnd->display;
-
-	ds_client_remove_window(wnd);
-	ds_display_remove_window(wnd);
-
-	mem_gc_delete(wnd->mgc);
-
-	if (wnd->bitmap != NULL)
-		gfx_bitmap_destroy(wnd->bitmap);
-
-	free(wnd);
-
-	(void) ds_display_paint(disp, NULL);
-}
-
-/** Bring window to top.
- *
- * @param wnd Window
- */
-void ds_window_bring_to_top(ds_window_t *wnd)
-{
-	ds_display_t *disp = wnd->display;
-
-	ds_display_remove_window(wnd);
-	ds_display_add_window(disp, wnd);
-}
-
-/** Get generic graphic context from window.
- *
- * @param wnd Window
- * @return Graphic context
- */
-gfx_context_t *ds_window_get_ctx(ds_window_t *wnd)
-{
-	return wnd->gc;
-}
-
-/** Paint a window using its backing bitmap.
- *
- * @param wnd Window to paint
- * @param rect Display rectangle to paint to
- * @return EOK on success or an error code
- */
-errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)
-{
-	gfx_rect_t srect;
-	gfx_rect_t *brect;
-	gfx_rect_t crect;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
-
-	if (rect != NULL) {
-		gfx_rect_rtranslate(&wnd->dpos, rect, &srect);
-
-		/* Determine if we have anything to do */
-		gfx_rect_clip(&srect, &wnd->rect, &crect);
-		if (gfx_rect_is_empty(&crect))
-			return EOK;
-
-		brect = &srect;
-	} else {
-		brect = NULL;
-	}
-
-	/* This can happen in unit tests */
-	if (wnd->bitmap == NULL)
-		return EOK;
-
-	return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);
-}
-
-/** Get the preview rectangle for a window.
- *
- * Get the preview rectangle if the window is being resized or moved.
- * If the window is not being resized or moved, return an empty rectangle.
- *
- * @param wnd Window
- * @param rect Place to store preview rectangle
- */
-static void ds_window_get_preview_rect(ds_window_t *wnd, gfx_rect_t *rect)
-{
-	switch (wnd->state) {
-	case dsw_idle:
-		break;
-	case dsw_moving:
-		gfx_rect_translate(&wnd->preview_pos, &wnd->rect, rect);
-		return;
-	case dsw_resizing:
-		gfx_rect_translate(&wnd->dpos, &wnd->preview_rect, rect);
-		return;
-	}
-
-	rect->p0.x = 0;
-	rect->p0.y = 0;
-	rect->p1.x = 0;
-	rect->p1.y = 0;
-}
-
-/** Paint window preview if the window is being moved or resized.
- *
- * If the window is not being resized or moved, take no action and return
- * success.
- *
- * @param wnd Window for which to paint preview
- * @param rect Clipping rectangle
- * @return EOK on success or an error code
- */
-errno_t ds_window_paint_preview(ds_window_t *wnd, gfx_rect_t *rect)
-{
-	errno_t rc;
-	gfx_color_t *color;
-	gfx_rect_t prect;
-	gfx_rect_t dr;
-	gfx_rect_t pr;
-	gfx_context_t *gc;
-
-	/*
-	 * Get preview rectangle. If the window is not being resized/moved,
-	 * we should get an empty rectangle.
-	 */
-	ds_window_get_preview_rect(wnd, &prect);
-	if (gfx_rect_is_empty(&prect)) {
-		/* There is nothing to paint */
-		return EOK;
-	}
-
-	rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
-	if (rc != EOK)
-		return rc;
-
-	gc = ds_display_get_gc(wnd->display);
-	if (gc != NULL) {
-		gfx_set_color(gc, color);
-
-		/*
-		 * TODO: Ideally we'd want XOR operation to make the preview
-		 * frame visible on any background. If we wanted to get really
-		 * fancy, we'd fill it with a pattern
-		 */
-
-		pr.p0.x = prect.p0.x;
-		pr.p0.y = prect.p0.y;
-		pr.p1.x = prect.p1.x;
-		pr.p1.y = prect.p0.y + 1;
-		gfx_rect_clip(&pr, rect, &dr);
-		gfx_fill_rect(gc, &dr);
-
-		pr.p0.x = prect.p0.x;
-		pr.p0.y = prect.p1.y - 1;
-		pr.p1.x = prect.p1.x;
-		pr.p1.y = prect.p1.y;
-		gfx_rect_clip(&pr, rect, &dr);
-		gfx_fill_rect(gc, &dr);
-
-		pr.p0.x = prect.p0.x;
-		pr.p0.y = prect.p0.y;
-		pr.p1.x = prect.p0.x + 1;
-		pr.p1.y = prect.p1.y;
-		gfx_rect_clip(&pr, rect, &dr);
-		gfx_fill_rect(gc, &dr);
-
-		pr.p0.x = prect.p1.x - 1;
-		pr.p0.y = prect.p0.y;
-		pr.p1.x = prect.p1.x;
-		pr.p1.y = prect.p1.y;
-		gfx_rect_clip(&pr, rect, &dr);
-		gfx_fill_rect(gc, &dr);
-
-	}
-
-	gfx_color_delete(color);
-	return EOK;
-}
-
-/** Repaint window preview when resizing or moving.
- *
- * Repaint the window preview wich was previously at rectangle @a old_rect.
- * The current preview rectangle is determined from window state. If
- * the window did not previously have a preview, @a old_rect should point
- * to an empty rectangle or be NULL. When window has finished
- * moving or resizing, the preview will be cleared.
- *
- * @param wnd Window for which to paint preview
- * @param rect Clipping rectangle
- * @return EOK on success or an error code
- */
-static errno_t ds_window_repaint_preview(ds_window_t *wnd, gfx_rect_t *old_rect)
-{
-	errno_t rc;
-	gfx_rect_t prect;
-	gfx_rect_t envelope;
-	bool oldr;
-	bool newr;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_repaint_preview");
-
-	/*
-	 * Get current preview rectangle. If the window is not being resized/moved,
-	 * we should get an empty rectangle.
-	 */
-	ds_window_get_preview_rect(wnd, &prect);
-
-	oldr = (old_rect != NULL) && !gfx_rect_is_empty(old_rect);
-	newr = !gfx_rect_is_empty(&prect);
-
-	if (oldr && newr && gfx_rect_is_incident(old_rect, &prect)) {
-		/*
-		 * As an optimization, repaint both rectangles in a single
-		 * operation.
-		 */
-
-		gfx_rect_envelope(old_rect, &prect, &envelope);
-
-		rc = ds_display_paint(wnd->display, &envelope);
-		if (rc != EOK)
-			return rc;
-	} else {
-		/* Repaint each rectangle separately */
-		if (oldr) {
-			rc = ds_display_paint(wnd->display, old_rect);
-			if (rc != EOK)
-				return rc;
-		}
-
-		if (newr) {
-			rc = ds_display_paint(wnd->display, &prect);
-			if (rc != EOK)
-				return rc;
-		}
-	}
-
-	return EOK;
-}
-
-/** Start moving a window by mouse drag.
- *
- * @param wnd Window
- * @param pos Position where mouse button was pressed
- */
-static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	if (wnd->state != dsw_idle)
-		return;
-
-	wnd->orig_pos = *pos;
-	wnd->state = dsw_moving;
-	wnd->preview_pos = wnd->dpos;
-
-	(void) ds_window_repaint_preview(wnd, NULL);
-}
-
-/** Finish moving a window by mouse drag.
- *
- * @param wnd Window
- * @param pos Position where mouse button was released
- */
-static void ds_window_finish_move(ds_window_t *wnd, gfx_coord2_t *pos)
-{
-	gfx_coord2_t dmove;
-	gfx_coord2_t nwpos;
-	gfx_rect_t old_rect;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_move (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	assert(wnd->state == dsw_moving);
-
-	gfx_coord2_subtract(pos, &wnd->orig_pos, &dmove);
-	gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
-
-	ds_window_get_preview_rect(wnd, &old_rect);
-
-	wnd->dpos = nwpos;
-	wnd->state = dsw_idle;
-
-	(void) ds_display_paint(wnd->display, NULL);
-}
-
-/** Update window position when moving by mouse drag.
- *
- * @param wnd Window
- * @param pos Current mouse position
- */
-static void ds_window_update_move(ds_window_t *wnd, gfx_coord2_t *pos)
-{
-	gfx_coord2_t dmove;
-	gfx_coord2_t nwpos;
-	gfx_rect_t old_rect;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	assert(wnd->state == dsw_moving);
-
-	gfx_coord2_subtract(pos, &wnd->orig_pos, &dmove);
-	gfx_coord2_add(&wnd->dpos, &dmove, &nwpos);
-
-	ds_window_get_preview_rect(wnd, &old_rect);
-	wnd->preview_pos = nwpos;
-
-	(void) ds_window_repaint_preview(wnd, &old_rect);
-}
-
-/** Start resizing a window by mouse drag.
- *
- * @param wnd Window
- * @param rsztype Resize type (which part of window is being dragged)
- * @param pos Position where mouse button was pressed
- */
-static void ds_window_start_resize(ds_window_t *wnd,
-    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
-{
-	ds_seat_t *seat;
-	display_stock_cursor_t ctype;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_resize (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	if (wnd->state != dsw_idle)
-		return;
-
-	wnd->orig_pos = *pos;
-	wnd->state = dsw_resizing;
-	wnd->rsztype = rsztype;
-	wnd->preview_rect = wnd->rect;
-
-	// XXX Need client to tell us which seat started the resize!
-	seat = ds_display_first_seat(wnd->display);
-	ctype = display_cursor_from_wrsz(rsztype);
-	ds_seat_set_wm_cursor(seat, wnd->display->cursor[ctype]);
-
-	(void) ds_window_repaint_preview(wnd, NULL);
-}
-
-/** Finish resizing a window by mouse drag.
- *
- * @param wnd Window
- * @param pos Position where mouse button was released
- */
-static void ds_window_finish_resize(ds_window_t *wnd, gfx_coord2_t *pos)
-{
-	gfx_coord2_t dresize;
-	gfx_rect_t nrect;
-	ds_seat_t *seat;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_finish_resize (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	assert(wnd->state == dsw_resizing);
-	gfx_coord2_subtract(pos, &wnd->orig_pos, &dresize);
-
-	/* Compute new rectangle */
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-
-	wnd->state = dsw_idle;
-	ds_client_post_resize_event(wnd->client, wnd, &nrect);
-
-	// XXX Need to know which seat started the resize!
-	seat = ds_display_first_seat(wnd->display);
-	ds_seat_set_wm_cursor(seat, NULL);
-
-	(void) ds_display_paint(wnd->display, NULL);
-}
-
-/** Update window position when resizing by mouse drag.
- *
- * @param wnd Window
- * @param pos Current mouse position
- */
-static void ds_window_update_resize(ds_window_t *wnd, gfx_coord2_t *pos)
-{
-	gfx_coord2_t dresize;
-	gfx_rect_t nrect;
-	gfx_rect_t old_rect;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	assert(wnd->state == dsw_resizing);
-
-	gfx_coord2_subtract(pos, &wnd->orig_pos, &dresize);
-	ds_window_calc_resize(wnd, &dresize, &nrect);
-
-	ds_window_get_preview_rect(wnd, &old_rect);
-	wnd->preview_rect = nrect;
-	(void) ds_window_repaint_preview(wnd, &old_rect);
-}
-
-/** Post keyboard event to window.
- *
- * @param wnd Window
- * @param event Event
- *
- * @return EOK on success or an error code
- */
-errno_t ds_window_post_kbd_event(ds_window_t *wnd, kbd_event_t *event)
-{
-	bool alt_or_shift;
-
-	alt_or_shift = event->mods & (KM_SHIFT | KM_ALT);
-
-	if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_F4) {
-		/* On Alt-F4 or Shift-F4 send close event to the window */
-		ds_client_post_close_event(wnd->client, wnd);
-		return EOK;
-	}
-
-	return ds_client_post_kbd_event(wnd->client, wnd, event);
-}
-
-/** Post position event to window.
- *
- * @param wnd Window
- * @param event Position event
- */
-errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
-{
-	pos_event_t tevent;
-	gfx_coord2_t pos;
-	gfx_rect_t drect;
-	bool inside;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG,
-	    "ds_window_post_pos_event type=%d pos=%d,%d", event->type,
-	    (int) event->hpos, (int) event->vpos);
-
-	pos.x = event->hpos;
-	pos.y = event->vpos;
-	gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
-	inside = gfx_pix_inside_rect(&pos, &drect);
-
-	if (event->type == POS_PRESS && event->btn_num == 2 && inside) {
-		ds_window_start_move(wnd, &pos);
-		return EOK;
-	}
-
-	if (event->type == POS_RELEASE) {
-		if (wnd->state == dsw_moving) {
-			ds_window_finish_move(wnd, &pos);
-			return EOK;
-		}
-
-		if (wnd->state == dsw_resizing) {
-			ds_window_finish_resize(wnd, &pos);
-			return EOK;
-		}
-	}
-
-	if (event->type == POS_UPDATE) {
-		if (wnd->state == dsw_moving) {
-			ds_window_update_move(wnd, &pos);
-			return EOK;
-		}
-
-		if (wnd->state == dsw_resizing) {
-			ds_window_update_resize(wnd, &pos);
-			return EOK;
-		}
-	}
-
-	/* Transform event coordinates to window-local */
-	tevent = *event;
-	tevent.hpos -= wnd->dpos.x;
-	tevent.vpos -= wnd->dpos.y;
-
-	return ds_client_post_pos_event(wnd->client, wnd, &tevent);
-}
-
-/** Post focus event to window.
- *
- * @param wnd Window
- */
-errno_t ds_window_post_focus_event(ds_window_t *wnd)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event");
-
-	return ds_client_post_focus_event(wnd->client, wnd);
-}
-
-/** Post unfocus event to window.
- *
- * @param wnd Window
- */
-errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event");
-
-	return ds_client_post_unfocus_event(wnd->client, wnd);
-}
-
-/** Start moving a window, detected by client.
- *
- * @param wnd Window
- * @param pos Position where the pointer was when the move started
- *            relative to the window
- * @param event Button press event
- */
-void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
-{
-	gfx_coord2_t orig_pos;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)",
-	    (int) pos->x, (int) pos->y);
-
-	gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
-	ds_window_start_move(wnd, &orig_pos);
-}
-
-/** Move window.
- *
- * @param wnd Window
- */
-void ds_window_move(ds_window_t *wnd, gfx_coord2_t *dpos)
-{
-	wnd->dpos = *dpos;
-	(void) ds_display_paint(wnd->display, NULL);
-}
-
-/** Start resizing a window, detected by client.
- *
- * @param wnd Window
- * @param rsztype Resize type (which part of window is being dragged)
- * @param pos Position where the pointer was when the resize started
- *            relative to the window
- * @param event Button press event
- */
-void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
-    gfx_coord2_t *pos)
-{
-	gfx_coord2_t orig_pos;
-
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d)",
-	    (int) rsztype, (int) pos->x, (int) pos->y);
-
-	gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
-	ds_window_start_resize(wnd, rsztype, &orig_pos);
-}
-
-/** Resize window.
- *
- * @param wnd Window
- */
-errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
-    gfx_rect_t *nrect)
-{
-	gfx_context_t *dgc;
-	gfx_bitmap_params_t bparams;
-	gfx_bitmap_t *nbitmap;
-	pixelmap_t npixelmap;
-	gfx_coord2_t dims;
-	gfx_bitmap_alloc_t alloc;
-	gfx_coord2_t ndpos;
-	errno_t rc;
-
-	dgc = ds_display_get_gc(wnd->display);
-	if (dgc != NULL) {
-		gfx_bitmap_params_init(&bparams);
-		bparams.rect = *nrect;
-
-		rc = gfx_bitmap_create(dgc, &bparams, NULL, &nbitmap);
-		if (rc != EOK)
-			return ENOMEM;
-
-		rc = gfx_bitmap_get_alloc(nbitmap, &alloc);
-		if (rc != EOK) {
-			gfx_bitmap_destroy(nbitmap);
-			return ENOMEM;
-		}
-
-		gfx_rect_dims(nrect, &dims);
-		npixelmap.width = dims.x;
-		npixelmap.height = dims.y;
-		npixelmap.data = alloc.pixels;
-
-		/* TODO: Transfer contents within overlap */
-
-		if (wnd->bitmap != NULL)
-			gfx_bitmap_destroy(wnd->bitmap);
-
-		wnd->bitmap = nbitmap;
-		wnd->pixelmap = npixelmap;
-
-		/* Point memory GC to the new bitmap */
-		mem_gc_retarget(wnd->mgc, nrect, &alloc);
-	}
-
-	gfx_coord2_add(&wnd->dpos, offs, &ndpos);
-
-	wnd->dpos = ndpos;
-	wnd->rect = *nrect;
-
-	(void) ds_display_paint(wnd->display, NULL);
-	return EOK;
-}
-
-/** Compute new window rectangle after resize operation.
- *
- * @param wnd Window which is being resized (in dsw_resizing state and thus
- *            has rsztype set)
- * @param dresize Amount by which to resize
- * @param nrect Place to store new rectangle
- */
-void ds_window_calc_resize(ds_window_t *wnd, gfx_coord2_t *dresize,
-    gfx_rect_t *nrect)
-{
-	if ((wnd->rsztype & display_wr_top) != 0) {
-		nrect->p0.y = min(wnd->rect.p0.y + dresize->y,
-		    wnd->rect.p1.y - wnd->min_size.y);
-	} else {
-		nrect->p0.y = wnd->rect.p0.y;
-	}
-
-	if ((wnd->rsztype & display_wr_left) != 0) {
-		nrect->p0.x = min(wnd->rect.p0.x + dresize->x,
-		    wnd->rect.p1.x - wnd->min_size.x);
-	} else {
-		nrect->p0.x = wnd->rect.p0.x;
-	}
-
-	if ((wnd->rsztype & display_wr_bottom) != 0) {
-		nrect->p1.y = max(wnd->rect.p1.y + dresize->y,
-		    wnd->rect.p0.y + wnd->min_size.y);
-	} else {
-		nrect->p1.y = wnd->rect.p1.y;
-	}
-
-	if ((wnd->rsztype & display_wr_right) != 0) {
-		nrect->p1.x = max(wnd->rect.p1.x + dresize->x,
-		    wnd->rect.p0.x + wnd->min_size.x);
-	} else {
-		nrect->p1.x = wnd->rect.p1.x;
-	}
-}
-
-/** Set window cursor.
- *
- * @param wnd Window
- * @return EOK on success, EINVAL if @a cursor is invalid
- */
-errno_t ds_window_set_cursor(ds_window_t *wnd, display_stock_cursor_t cursor)
-{
-	if (cursor >= dcurs_arrow &&
-	    cursor < (display_stock_cursor_t) dcurs_limit) {
-		wnd->cursor = wnd->display->cursor[cursor];
-		return EOK;
-	} else {
-		return EINVAL;
-	}
-}
-
-/** Window memory GC update callback.
- *
- * This is called by the window's memory GC when a rectangle us updated.
- */
-static void ds_window_update_cb(void *arg, gfx_rect_t *rect)
-{
-	ds_window_t *wnd = (ds_window_t *)arg;
-	gfx_rect_t drect;
-
-	/* Repaint the corresponding part of the display */
-	gfx_rect_translate(&wnd->dpos, rect, &drect);
-	(void) ds_display_paint(wnd->display, &drect);
-}
-
-/** @}
- */
Index: pace/srv/hid/display/window.h
===================================================================
--- uspace/srv/hid/display/window.h	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ 	(revision )
@@ -1,75 +1,0 @@
-/*
- * Copyright (c) 2019 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 window
- */
-
-#ifndef WINDOW_H
-#define WINDOW_H
-
-#include <display/wndparams.h>
-#include <display/wndresize.h>
-#include <errno.h>
-#include <io/pos_event.h>
-#include <types/gfx/context.h>
-#include <types/gfx/coord.h>
-#include <types/gfx/ops/context.h>
-#include "types/display/cursor.h"
-#include "types/display/display.h"
-#include "types/display/window.h"
-
-extern gfx_context_ops_t window_gc_ops;
-
-extern errno_t ds_window_create(ds_client_t *, display_wnd_params_t *,
-    ds_window_t **);
-extern void ds_window_destroy(ds_window_t *);
-extern void ds_window_bring_to_top(ds_window_t *);
-extern gfx_context_t *ds_window_get_ctx(ds_window_t *);
-extern errno_t ds_window_paint(ds_window_t *, gfx_rect_t *);
-errno_t ds_window_paint_preview(ds_window_t *, gfx_rect_t *);
-extern errno_t ds_window_post_kbd_event(ds_window_t *, kbd_event_t *);
-extern errno_t ds_window_post_pos_event(ds_window_t *, pos_event_t *);
-extern errno_t ds_window_post_focus_event(ds_window_t *);
-extern errno_t ds_window_post_unfocus_event(ds_window_t *);
-extern void ds_window_move_req(ds_window_t *, gfx_coord2_t *);
-extern void ds_window_move(ds_window_t *, gfx_coord2_t *);
-extern void ds_window_resize_req(ds_window_t *, display_wnd_rsztype_t,
-    gfx_coord2_t *);
-extern errno_t ds_window_resize(ds_window_t *, gfx_coord2_t *, gfx_rect_t *);
-extern void ds_window_calc_resize(ds_window_t *, gfx_coord2_t *,
-    gfx_rect_t *);
-extern errno_t ds_window_set_cursor(ds_window_t *, display_stock_cursor_t);
-
-#endif
-
-/** @}
- */
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/srv/hid/input/input.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -236,12 +236,4 @@
 	}
 
-	if (type == KEY_PRESS) {
-		switch (key) {
-		case KC_F12:
-			console_kcon();
-			break;
-		}
-	}
-
 	ev.type = type;
 	ev.key = key;
Index: uspace/srv/hid/rfb/main.c
===================================================================
--- uspace/srv/hid/rfb/main.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/srv/hid/rfb/main.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -27,19 +27,21 @@
  */
 
-#include <ddev/info.h>
-#include <ddev_srv.h>
+#include <stdlib.h>
 #include <errno.h>
+#include <loc.h>
+#include <stdio.h>
 #include <fibril_synch.h>
-#include <gfx/color.h>
-#include <gfx/context.h>
-#include <gfx/coord.h>
+#include <abi/ipc/methods.h>
 #include <inttypes.h>
 #include <io/log.h>
+#include <str.h>
+#include <task.h>
+
+#include <abi/fb/visuals.h>
+#include <adt/list.h>
+#include <io/mode.h>
 #include <io/pixelmap.h>
-#include <ipcgfx/server.h>
-#include <loc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <task.h>
+#include <io/chargrid.h>
+#include <graph.h>
 
 #include "rfb.h"
@@ -47,281 +49,95 @@
 #define NAME "rfb"
 
-static errno_t rfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
-static errno_t rfb_ddev_get_info(void *, ddev_info_t *);
-
-static errno_t rfb_gc_set_color(void *, gfx_color_t *);
-static errno_t rfb_gc_fill_rect(void *, gfx_rect_t *);
-static errno_t rfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
-    gfx_bitmap_alloc_t *, void **);
-static errno_t rfb_gc_bitmap_destroy(void *);
-static errno_t rfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
-static errno_t rfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
-
-static ddev_ops_t rfb_ddev_ops = {
-	.get_gc = rfb_ddev_get_gc,
-	.get_info = rfb_ddev_get_info
+static vslmode_list_element_t pixel_mode;
+static visualizer_t *vis;
+static rfb_t rfb;
+
+static errno_t rfb_claim(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static errno_t rfb_yield(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static errno_t rfb_suspend(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static errno_t rfb_wakeup(visualizer_t *vs)
+{
+	return EOK;
+}
+
+static errno_t rfb_handle_damage_pixels(visualizer_t *vs,
+    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
+    sysarg_t x_offset, sysarg_t y_offset)
+{
+	fibril_mutex_lock(&rfb.lock);
+
+	if (x0 + width > rfb.width || y0 + height > rfb.height) {
+		fibril_mutex_unlock(&rfb.lock);
+		return EINVAL;
+	}
+
+	/* TODO update surface_t and use it */
+	if (!rfb.damage_valid) {
+		rfb.damage_rect.x = x0;
+		rfb.damage_rect.y = y0;
+		rfb.damage_rect.width = width;
+		rfb.damage_rect.height = height;
+		rfb.damage_valid = true;
+	} else {
+		if (x0 < rfb.damage_rect.x) {
+			rfb.damage_rect.width += rfb.damage_rect.x - x0;
+			rfb.damage_rect.x = x0;
+		}
+		if (y0 < rfb.damage_rect.y) {
+			rfb.damage_rect.height += rfb.damage_rect.y - y0;
+			rfb.damage_rect.y = y0;
+		}
+		sysarg_t x1 = x0 + width;
+		sysarg_t dx1 = rfb.damage_rect.x + rfb.damage_rect.width;
+		if (x1 > dx1) {
+			rfb.damage_rect.width += x1 - dx1;
+		}
+		sysarg_t y1 = y0 + height;
+		sysarg_t dy1 = rfb.damage_rect.y + rfb.damage_rect.height;
+		if (y1 > dy1) {
+			rfb.damage_rect.height += y1 - dy1;
+		}
+	}
+
+	pixelmap_t *map = &vs->cells;
+
+	for (sysarg_t y = y0; y < height + y0; ++y) {
+		for (sysarg_t x = x0; x < width + x0; ++x) {
+			pixel_t pix = pixelmap_get_pixel(map, (x + x_offset) % map->width,
+			    (y + y_offset) % map->height);
+			pixelmap_put_pixel(&rfb.framebuffer, x, y, pix);
+		}
+	}
+
+	fibril_mutex_unlock(&rfb.lock);
+	return EOK;
+}
+
+static errno_t rfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
+{
+	return EOK;
+}
+
+static visualizer_ops_t rfb_ops = {
+	.claim = rfb_claim,
+	.yield = rfb_yield,
+	.change_mode = rfb_change_mode,
+	.handle_damage = rfb_handle_damage_pixels,
+	.suspend = rfb_suspend,
+	.wakeup = rfb_wakeup
 };
 
-typedef struct {
-	rfb_t rfb;
-	pixel_t color;
-} rfb_gc_t;
-
-typedef struct {
-	rfb_gc_t *rfb;
-	gfx_bitmap_alloc_t alloc;
-	gfx_rect_t rect;
-	gfx_bitmap_flags_t flags;
-	pixel_t key_color;
-	bool myalloc;
-} rfb_bitmap_t;
-
-static gfx_context_ops_t rfb_gc_ops = {
-	.set_color = rfb_gc_set_color,
-	.fill_rect = rfb_gc_fill_rect,
-	.bitmap_create = rfb_gc_bitmap_create,
-	.bitmap_destroy = rfb_gc_bitmap_destroy,
-	.bitmap_render = rfb_gc_bitmap_render,
-	.bitmap_get_alloc = rfb_gc_bitmap_get_alloc
-};
-
-static void rfb_gc_invalidate_rect(rfb_gc_t *rfbgc, gfx_rect_t *rect)
-{
-	rfb_t *rfb = &rfbgc->rfb;
-	gfx_rect_t old_rect;
-	gfx_rect_t new_rect;
-
-	if (gfx_rect_is_empty(rect))
-		return;
-
-	if (!rfb->damage_valid) {
-		old_rect.p0.x = old_rect.p0.y = 0;
-		old_rect.p1.x = old_rect.p1.y = 0;
-	} else {
-		old_rect.p0.x = rfb->damage_rect.x;
-		old_rect.p0.y = rfb->damage_rect.y;
-		old_rect.p1.x = rfb->damage_rect.x + rfb->damage_rect.width;
-		old_rect.p1.y = rfb->damage_rect.y + rfb->damage_rect.height;
-	}
-
-	gfx_rect_envelope(&old_rect, rect, &new_rect);
-
-	rfb->damage_rect.x = new_rect.p0.x;
-	rfb->damage_rect.y = new_rect.p0.y;
-	rfb->damage_rect.width = new_rect.p1.x - new_rect.p0.x;
-	rfb->damage_rect.height = new_rect.p1.y - new_rect.p0.y;
-}
-
-static errno_t rfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
-{
-	*arg2 = 0;
-	*arg3 = 42;
-	return EOK;
-}
-
-static errno_t rfb_ddev_get_info(void *arg, ddev_info_t *info)
-{
-	rfb_t *rfb = (rfb_t *) arg;
-
-	ddev_info_init(info);
-
-	info->rect.p0.x = 0;
-	info->rect.p0.y = 0;
-	info->rect.p1.x = rfb->width;
-	info->rect.p1.y = rfb->height;
-
-	return EOK;
-}
-
-/** Set color on RFB.
- *
- * Set drawing color on RFB GC.
- *
- * @param arg RFB
- * @param color Color
- *
- * @return EOK on success or an error code
- */
-static errno_t rfb_gc_set_color(void *arg, gfx_color_t *color)
-{
-	rfb_gc_t *rfb = (rfb_gc_t *) arg;
-	uint16_t r, g, b;
-
-	gfx_color_get_rgb_i16(color, &r, &g, &b);
-	rfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
-	return EOK;
-}
-
-/** Fill rectangle on RFB.
- *
- * @param arg RFB
- * @param rect Rectangle
- *
- * @return EOK on success or an error code
- */
-static errno_t rfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
-{
-	rfb_gc_t *rfb = (rfb_gc_t *) arg;
-	gfx_coord_t x, y;
-
-	// XXX We should handle p0.x > p1.x and p0.y > p1.y
-
-	for (y = rect->p0.y; y < rect->p1.y; y++) {
-		for (x = rect->p0.x; x < rect->p1.x; x++) {
-			pixelmap_put_pixel(&rfb->rfb.framebuffer, x, y,
-			    rfb->color);
-		}
-	}
-
-	rfb_gc_invalidate_rect(rfb, rect);
-
-	return EOK;
-}
-
-/** Create bitmap in RFB GC.
- *
- * @param arg RFB
- * @param params Bitmap params
- * @param alloc Bitmap allocation info or @c NULL
- * @param rbm Place to store pointer to new bitmap
- * @return EOK on success or an error code
- */
-errno_t rfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
-    gfx_bitmap_alloc_t *alloc, void **rbm)
-{
-	rfb_gc_t *rfb = (rfb_gc_t *) arg;
-	rfb_bitmap_t *rfbbm = NULL;
-	gfx_coord2_t dim;
-	errno_t rc;
-
-	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
-		return ENOTSUP;
-
-	rfbbm = calloc(1, sizeof(rfb_bitmap_t));
-	if (rfbbm == NULL)
-		return ENOMEM;
-
-	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
-	rfbbm->rect = params->rect;
-	rfbbm->flags = params->flags;
-	rfbbm->key_color = params->key_color;
-
-	if (alloc == NULL) {
-		rfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
-		rfbbm->alloc.off0 = 0;
-		rfbbm->alloc.pixels = malloc(rfbbm->alloc.pitch * dim.y);
-		rfbbm->myalloc = true;
-
-		if (rfbbm->alloc.pixels == NULL) {
-			rc = ENOMEM;
-			goto error;
-		}
-	} else {
-		rfbbm->alloc = *alloc;
-	}
-
-	rfbbm->rfb = rfb;
-	*rbm = (void *)rfbbm;
-	return EOK;
-error:
-	if (rbm != NULL)
-		free(rfbbm);
-	return rc;
-}
-
-/** Destroy bitmap in RFB GC.
- *
- * @param bm Bitmap
- * @return EOK on success or an error code
- */
-static errno_t rfb_gc_bitmap_destroy(void *bm)
-{
-	rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
-	if (rfbbm->myalloc)
-		free(rfbbm->alloc.pixels);
-	free(rfbbm);
-	return EOK;
-}
-
-/** Render bitmap in RFB GC.
- *
- * @param bm Bitmap
- * @param srect0 Source rectangle or @c NULL
- * @param offs0 Offset or @c NULL
- * @return EOK on success or an error code
- */
-static errno_t rfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
-    gfx_coord2_t *offs0)
-{
-	rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
-	gfx_rect_t srect;
-	gfx_rect_t drect;
-	gfx_coord2_t offs;
-	gfx_coord2_t bmdim;
-	gfx_coord2_t dim;
-	gfx_coord_t x, y;
-	pixelmap_t pbm;
-	pixel_t color;
-
-	if (srect0 != NULL)
-		srect = *srect0;
-	else
-		srect = rfbbm->rect;
-
-	if (offs0 != NULL) {
-		offs = *offs0;
-	} else {
-		offs.x = 0;
-		offs.y = 0;
-	}
-
-	/* Destination rectangle */
-	gfx_rect_translate(&offs, &srect, &drect);
-	gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
-	gfx_coord2_subtract(&rfbbm->rect.p1, &rfbbm->rect.p0, &bmdim);
-
-	pbm.width = bmdim.x;
-	pbm.height = bmdim.y;
-	pbm.data = rfbbm->alloc.pixels;
-
-	if ((rfbbm->flags & bmpf_color_key) == 0) {
-		for (y = srect.p0.y; y < srect.p1.y; y++) {
-			for (x = srect.p0.x; x < srect.p1.x; x++) {
-				color = pixelmap_get_pixel(&pbm, x, y);
-				pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
-				    x + offs.x, y + offs.y, color);
-			}
-		}
-	} else {
-		for (y = srect.p0.y; y < srect.p1.y; y++) {
-			for (x = srect.p0.x; x < srect.p1.x; x++) {
-				color = pixelmap_get_pixel(&pbm, x, y);
-				if (color != rfbbm->key_color) {
-					pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
-					    x + offs.x, y + offs.y, color);
-				}
-			}
-		}
-	}
-
-	rfb_gc_invalidate_rect(rfbbm->rfb, &drect);
-
-	return EOK;
-}
-
-/** Get allocation info for bitmap in RFB GC.
- *
- * @param bm Bitmap
- * @param alloc Place to store allocation info
- * @return EOK on success or an error code
- */
-static errno_t rfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
-{
-	rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
-	*alloc = rfbbm->alloc;
-	return EOK;
-}
-
 static void syntax_print(void)
 {
@@ -329,38 +145,11 @@
 }
 
-static void client_connection(ipc_call_t *icall, void *arg)
-{
-	rfb_t *rfb = (rfb_t *) arg;
-	ddev_srv_t srv;
-	sysarg_t svc_id;
-	gfx_context_t *gc;
-	errno_t rc;
-
-	svc_id = ipc_get_arg2(icall);
-
-	if (svc_id != 0) {
-		/* Set up protocol structure */
-		ddev_srv_initialize(&srv);
-		srv.ops = &rfb_ddev_ops;
-		srv.arg = (void *) rfb;
-
-		/* Handle connection */
-		ddev_conn(icall, &srv);
-	} else {
-		rc = gfx_context_new(&rfb_gc_ops, (void *) rfb, &gc);
-		if (rc != EOK) {
-			async_answer_0(icall, ENOMEM);
-			return;
-		}
-
-		/* GC connection */
-		gc_conn(icall, gc);
-	}
+static void client_connection(ipc_call_t *call, void *data)
+{
+	graph_visualizer_connection(vis, call, data);
 }
 
 int main(int argc, char **argv)
 {
-	rfb_t rfb;
-
 	log_init(NAME);
 
@@ -399,5 +188,32 @@
 	rfb_init(&rfb, width, height, rfb_name);
 
-	async_set_fallback_port_handler(client_connection, &rfb);
+	vis = malloc(sizeof(visualizer_t));
+	if (vis == NULL) {
+		fprintf(stderr, "Failed allocating visualizer struct\n");
+		return 3;
+	}
+
+	graph_init_visualizer(vis);
+
+	pixel_mode.mode.index = 0;
+	pixel_mode.mode.version = 0;
+	pixel_mode.mode.refresh_rate = 0;
+	pixel_mode.mode.screen_aspect.width = rfb.width;
+	pixel_mode.mode.screen_aspect.height = rfb.height;
+	pixel_mode.mode.screen_width = rfb.width;
+	pixel_mode.mode.screen_height = rfb.height;
+	pixel_mode.mode.cell_aspect.width = 1;
+	pixel_mode.mode.cell_aspect.height = 1;
+	pixel_mode.mode.cell_visual.pixel_visual = VISUAL_RGB_8_8_8;
+
+	link_initialize(&pixel_mode.link);
+	list_append(&pixel_mode.link, &vis->modes);
+
+	vis->def_mode_idx = 0;
+
+	vis->ops = rfb_ops;
+	vis->dev_ctx = NULL;
+
+	async_set_fallback_port_handler(client_connection, NULL);
 
 	errno_t rc = loc_server_register(NAME);
@@ -424,14 +240,14 @@
 	free(service_name);
 
-	category_id_t ddev_cid;
-	rc = loc_category_get_id("display-device", &ddev_cid, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		fprintf(stderr, NAME ": Unable to get display device category id.\n");
-		return 1;
-	}
-
-	rc = loc_service_add_to_cat(service_id, ddev_cid);
-	if (rc != EOK) {
-		fprintf(stderr, NAME ": Unable to add service to display device category.\n");
+	category_id_t visualizer_category;
+	rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
+		return 1;
+	}
+
+	rc = loc_service_add_to_cat(service_id, visualizer_category);
+	if (rc != EOK) {
+		fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
 		return 1;
 	}
Index: uspace/srv/hid/rfb/meson.build
===================================================================
--- uspace/srv/hid/rfb/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/srv/hid/rfb/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -27,4 +27,4 @@
 #
 
-deps = [ 'ipcgfx', 'ddev' ]
+deps = [ 'graph' ]
 src = files('main.c', 'rfb.c')
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/srv/locsrv/locsrv.c	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -1378,8 +1378,8 @@
 	categ_dir_add_cat(&cdir, cat);
 
+	cat = category_new("visualizer");
+	categ_dir_add_cat(&cdir, cat);
+
 	cat = category_new("renderer");
-	categ_dir_add_cat(&cdir, cat);
-
-	cat = category_new("display-device");
 	categ_dir_add_cat(&cdir, cat);
 
Index: uspace/srv/meson.build
===================================================================
--- uspace/srv/meson.build	(revision e79a02579606a7e906058c20adeea8a00dc36770)
+++ uspace/srv/meson.build	(revision edb57bc6e15358d5e60d694a899002cba9f8acd0)
@@ -43,6 +43,6 @@
 	'fs/tmpfs',
 	'fs/udf',
+	'hid/compositor',
 	'hid/console',
-	'hid/display',
 	'hid/input',
 	'hid/isdv4_tablet',
