Index: pace/lib/c/generic/io/window.c
===================================================================
--- uspace/lib/c/generic/io/window.c	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,137 +1,0 @@
-/*
- * 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/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/c/include/io/window.h	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -36,9 +36,7 @@
 #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 {
@@ -113,16 +111,4 @@
 } 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/meson.build
===================================================================
--- uspace/lib/c/meson.build	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/c/meson.build	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -132,5 +132,4 @@
 	'generic/io/table.c',
 	'generic/io/visualizer.c',
-	'generic/io/window.c',
 	'generic/iplink.c',
 	'generic/iplink_srv.c',
Index: pace/lib/graph/doc/doxygroups.h
===================================================================
--- uspace/lib/graph/doc/doxygroups.h	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,3 +1,0 @@
-/** @addtogroup graph libgraph
- * @ingroup libs
- */
Index: pace/lib/graph/graph.c
===================================================================
--- uspace/lib/graph/graph.c	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,609 +1,0 @@
-/*
- * 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: pace/lib/graph/graph.h
===================================================================
--- uspace/lib/graph/graph.h	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,373 +1,0 @@
-/*
- * 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: pace/lib/graph/meson.build
===================================================================
--- uspace/lib/graph/meson.build	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,29 +1,0 @@
-#
-# 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/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/gui/terminal.c	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -42,4 +42,5 @@
 #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 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/gui/terminal.h	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -42,4 +42,5 @@
 #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 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/gui/window.c	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -519,7 +519,4 @@
 
 	if (width > 0 && height > 0) {
-		/* Notify compositor. */
-		//win_damage(win->osess, x, y, width, height);
-
 		rect.p0.x = x;
 		rect.p0.y = y;
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/gui/window.h	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -61,10 +61,10 @@
 	widget_t *focus; /**< Widget owning the keyboard or NULL. */
 	fibril_mutex_t guard; /**< Mutex guarding window surface. */
-	surface_t *surface; /**< Window surface shared with compositor. */
+	surface_t *surface; /**< Window surface shared with display server. */
 	gfx_bitmap_t *bitmap; /**< Window bitmap */
 };
 
 /**
- * Allocate all resources for new window and register it in the compositor.
+ * Allocate all resources for new window and register it in the display server.
  * 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.
@@ -75,7 +75,7 @@
 /**
  * Post resize event into event loop. Window negotiates new surface with
- * 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.
+ * 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.
  */
 extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
@@ -94,6 +94,6 @@
 
 /**
- * Post damage event into event loop. Handler informs compositor to update the
- * window surface on the screen. Should be called by widget after painting
+ * 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
  * itself or copying its buffer onto window surface.
  */
@@ -124,5 +124,5 @@
 
 /**
- * Initiate the closing cascade for the window. First, compositor deallocates
+ * Initiate the closing cascade for the window. First, display sever deallocates
  * output resources, prepares special closing input event for the window and
  * deallocates input resources after the event is dispatched. When window
Index: uspace/lib/meson.build
===================================================================
--- uspace/lib/meson.build	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/lib/meson.build	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -60,5 +60,4 @@
 	'fs',
 	'gfx',
-	'graph',
 	'http',
 	'label',
Index: pace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,2364 +1,0 @@
-/*
- * 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, wchar_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, wchar_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: pace/srv/hid/compositor/compositor.h
===================================================================
--- uspace/srv/hid/compositor/compositor.h	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,65 +1,0 @@
-/*
- * 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: pace/srv/hid/compositor/doc/doxygroups.h
===================================================================
--- uspace/srv/hid/compositor/doc/doxygroups.h	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup compositor compositor
- * @ingroup srvs
- * @brief GUI server
- */
Index: pace/srv/hid/compositor/meson.build
===================================================================
--- uspace/srv/hid/compositor/meson.build	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ 	(revision )
@@ -1,30 +1,0 @@
-#
-# 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: uspace/srv/meson.build
===================================================================
--- uspace/srv/meson.build	(revision 83cb672146f79daf5a4877a06b7901bf21f80c1b)
+++ uspace/srv/meson.build	(revision 6feccae4e934741d247da783eb3bbef174d9d0ef)
@@ -43,5 +43,4 @@
 	'fs/tmpfs',
 	'fs/udf',
-	'hid/compositor',
 	'hid/console',
 	'hid/display',
