Index: uspace/app/dnsres/dnsres.c
===================================================================
--- uspace/app/dnsres/dnsres.c	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/app/dnsres/dnsres.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -34,4 +34,5 @@
 
 #include <errno.h>
+#include <inet/addr.h>
 #include <inet/dnsr.h>
 #include <stdio.h>
@@ -43,18 +44,4 @@
 {
 	printf("syntax: " NAME " <host-name>\n");
-}
-
-static int addr_format(inet_addr_t *addr, char **bufp)
-{
-	int rc;
-
-	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
-	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
-	    addr->ipv4 & 0xff);
-
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
 }
 
@@ -76,5 +63,5 @@
 	}
 
-	rc = addr_format(&hinfo->addr, &saddr);
+	rc = inet_addr_format(&hinfo->addr, &saddr);
 	if (rc != EOK) {
 		dnsr_hostinfo_destroy(hinfo);
Index: uspace/app/inet/inet.c
===================================================================
--- uspace/app/inet/inet.c	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/app/inet/inet.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -36,4 +36,5 @@
 
 #include <errno.h>
+#include <inet/addr.h>
 #include <inet/inetcfg.h>
 #include <loc.h>
@@ -54,95 +55,4 @@
 }
 
-static int naddr_parse(const char *text, inet_naddr_t *naddr)
-{
-	unsigned long a[4], bits;
-	char *cp = (char *)text;
-	int i;
-
-	for (i = 0; i < 3; i++) {
-		a[i] = strtoul(cp, &cp, 10);
-		if (*cp != '.')
-			return EINVAL;
-		++cp;
-	}
-
-	a[3] = strtoul(cp, &cp, 10);
-	if (*cp != '/')
-		return EINVAL;
-	++cp;
-
-	bits = strtoul(cp, &cp, 10);
-	if (*cp != '\0')
-		return EINVAL;
-
-	naddr->ipv4 = 0;
-	for (i = 0; i < 4; i++) {
-		if (a[i] > 255)
-			return EINVAL;
-		naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
-	}
-
-	if (bits > 31)
-		return EINVAL;
-
-	naddr->bits = bits;
-	return EOK;
-}
-
-static int addr_parse(const char *text, inet_addr_t *addr)
-{
-	unsigned long a[4];
-	char *cp = (char *)text;
-	int i;
-
-	for (i = 0; i < 3; i++) {
-		a[i] = strtoul(cp, &cp, 10);
-		if (*cp != '.')
-			return EINVAL;
-		++cp;
-	}
-
-	a[3] = strtoul(cp, &cp, 10);
-	if (*cp != '\0')
-		return EINVAL;
-
-	addr->ipv4 = 0;
-	for (i = 0; i < 4; i++) {
-		if (a[i] > 255)
-			return EINVAL;
-		addr->ipv4 = (addr->ipv4 << 8) | a[i];
-	}
-
-	return EOK;
-}
-
-static int naddr_format(inet_naddr_t *naddr, char **bufp)
-{
-	int rc;
-
-	rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24,
-	    (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff,
-	    naddr->ipv4 & 0xff, naddr->bits);
-
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
-}
-
-static int addr_format(inet_addr_t *addr, char **bufp)
-{
-	int rc;
-
-	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
-	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
-	    addr->ipv4 & 0xff);
-
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
-}
-
 static int addr_create_static(int argc, char *argv[])
 {
@@ -178,5 +88,5 @@
 	}
 
-	rc = naddr_parse(addr_spec, &naddr);
+	rc = inet_naddr_parse(addr_spec, &naddr);
 	if (rc != EOK) {
 		printf(NAME ": Invalid network address format '%s'.\n",
@@ -267,5 +177,5 @@
 	route_name = argv[2];
 
-	rc = naddr_parse(dest_str, &dest);
+	rc = inet_naddr_parse(dest_str, &dest);
 	if (rc != EOK) {
 		printf(NAME ": Invalid network address format '%s'.\n",
@@ -274,5 +184,5 @@
 	}
 
-	rc = addr_parse(router_str, &router);
+	rc = inet_addr_parse(router_str, &router);
 	if (rc != EOK) {
 		printf(NAME ": Invalid address format '%s'.\n", router_str);
@@ -366,5 +276,5 @@
 		}
 
-		rc = naddr_format(&ainfo.naddr, &astr);
+		rc = inet_naddr_format(&ainfo.naddr, &astr);
 		if (rc != EOK) {
 			printf("Memory allocation failed.\n");
@@ -430,5 +340,5 @@
 		}
 
-		rc = naddr_format(&srinfo.dest, &dest_str);
+		rc = inet_naddr_format(&srinfo.dest, &dest_str);
 		if (rc != EOK) {
 			printf("Memory allocation failed.\n");
@@ -437,5 +347,5 @@
 		}
 
-		rc = addr_format(&srinfo.router, &router_str);
+		rc = inet_addr_format(&srinfo.router, &router_str);
 		if (rc != EOK) {
 			printf("Memory allocation failed.\n");
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/app/ping/ping.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -38,4 +38,5 @@
 #include <fibril_synch.h>
 #include <inet/dnsr.h>
+#include <inet/addr.h>
 #include <inet/inetping.h>
 #include <io/console.h>
@@ -72,45 +73,4 @@
 }
 
-static int addr_parse(const char *text, inet_addr_t *addr)
-{
-	unsigned long a[4];
-	char *cp = (char *)text;
-	int i;
-
-	for (i = 0; i < 3; i++) {
-		a[i] = strtoul(cp, &cp, 10);
-		if (*cp != '.')
-			return EINVAL;
-		++cp;
-	}
-
-	a[3] = strtoul(cp, &cp, 10);
-	if (*cp != '\0')
-		return EINVAL;
-
-	addr->ipv4 = 0;
-	for (i = 0; i < 4; i++) {
-		if (a[i] > 255)
-			return EINVAL;
-		addr->ipv4 = (addr->ipv4 << 8) | a[i];
-	}
-
-	return EOK;
-}
-
-static int addr_format(inet_addr_t *addr, char **bufp)
-{
-	int rc;
-
-	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
-	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
-	    addr->ipv4 & 0xff);
-
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
-}
-
 static void ping_signal_done(void)
 {
@@ -126,9 +86,9 @@
 	int rc;
 
-	rc = addr_format(&sdu->src, &asrc);
+	rc = inet_addr_format(&sdu->src, &asrc);
 	if (rc != EOK)
 		return ENOMEM;
 
-	rc = addr_format(&sdu->dest, &adest);
+	rc = inet_addr_format(&sdu->dest, &adest);
 	if (rc != EOK) {
 		free(asrc);
@@ -242,5 +202,5 @@
 
 	/* Parse destination address */
-	rc = addr_parse(argv[argi], &dest_addr);
+	rc = inet_addr_parse(argv[argi], &dest_addr);
 	if (rc != EOK) {
 		/* Try interpreting as a host name */
@@ -261,5 +221,5 @@
 	}
 
-	rc = addr_format(&src_addr, &asrc);
+	rc = inet_addr_format(&src_addr, &asrc);
 	if (rc != EOK) {
 		printf(NAME ": Out of memory.\n");
@@ -267,5 +227,5 @@
 	}
 
-	rc = addr_format(&dest_addr, &adest);
+	rc = inet_addr_format(&dest_addr, &adest);
 	if (rc != EOK) {
 		printf(NAME ": Out of memory.\n");
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/app/vlaunch/vlaunch.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -121,8 +121,8 @@
 	}
 	
-	pixel_t grd_bg = PIXEL(255, 240, 240, 240);
+	pixel_t grd_bg = PIXEL(255, 255, 255, 255);
 	pixel_t btn_bg = PIXEL(255, 0, 0, 0);
 	pixel_t btn_fg = PIXEL(255, 240, 240, 240);
-	pixel_t lbl_bg = PIXEL(255, 240, 240, 240);
+	pixel_t lbl_bg = PIXEL(255, 255, 255, 255);
 	pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
 	
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/lib/c/Makefile	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -92,4 +92,5 @@
 	generic/task.c \
 	generic/futex.c \
+	generic/inet/addr.c \
 	generic/inet.c \
 	generic/inetcfg.c \
Index: uspace/lib/c/generic/inet/addr.c
===================================================================
--- uspace/lib/c/generic/inet/addr.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
+++ uspace/lib/c/generic/inet/addr.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file Internet address parsing and formatting.
+ */
+
+#include <errno.h>
+#include <inet/addr.h>
+#include <stdio.h>
+
+/** Parse network address.
+ *
+ * @param text	Network address in CIDR notation (a.b.c.d/w)
+ * @param naddr	Place to store network address
+ *
+ * @return 	EOK on success, EINVAL if input is not in valid format
+ */
+int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
+{
+	unsigned long a[4], bits;
+	char *cp = (char *)text;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		a[i] = strtoul(cp, &cp, 10);
+		if (*cp != '.')
+			return EINVAL;
+		++cp;
+	}
+
+	a[3] = strtoul(cp, &cp, 10);
+	if (*cp != '/')
+		return EINVAL;
+	++cp;
+
+	bits = strtoul(cp, &cp, 10);
+	if (*cp != '\0')
+		return EINVAL;
+
+	naddr->ipv4 = 0;
+	for (i = 0; i < 4; i++) {
+		if (a[i] > 255)
+			return EINVAL;
+		naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
+	}
+
+	if (bits > 31)
+		return EINVAL;
+
+	naddr->bits = bits;
+	return EOK;
+}
+
+/** Parse node address.
+ *
+ * @param text	Network address in dot notation (a.b.c.d)
+ * @param addr	Place to store node address
+ *
+ * @return 	EOK on success, EINVAL if input is not in valid format
+ */
+int inet_addr_parse(const char *text, inet_addr_t *addr)
+{
+	unsigned long a[4];
+	char *cp = (char *)text;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		a[i] = strtoul(cp, &cp, 10);
+		if (*cp != '.')
+			return EINVAL;
+		++cp;
+	}
+
+	a[3] = strtoul(cp, &cp, 10);
+	if (*cp != '\0')
+		return EINVAL;
+
+	addr->ipv4 = 0;
+	for (i = 0; i < 4; i++) {
+		if (a[i] > 255)
+			return EINVAL;
+		addr->ipv4 = (addr->ipv4 << 8) | a[i];
+	}
+
+	return EOK;
+}
+
+/** Format network address.
+ *
+ * @param naddr	Network address
+ * @param bufp	Place to store pointer to formatted string (CIDR notation)
+ *
+ * @return 	EOK on success, ENOMEM if out of memory.
+ */
+int inet_naddr_format(inet_naddr_t *naddr, char **bufp)
+{
+	int rc;
+
+	rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24,
+	    (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff,
+	    naddr->ipv4 & 0xff, naddr->bits);
+
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
+/** Format node address.
+ *
+ * @param addr	Node address
+ * @param bufp	Place to store pointer to formatted string (dot notation)
+ *
+ * @return 	EOK on success, ENOMEM if out of memory.
+ */
+int inet_addr_format(inet_addr_t *addr, char **bufp)
+{
+	int rc;
+
+	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
+	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
+	    addr->ipv4 & 0xff);
+
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/inet/addr.h
===================================================================
--- uspace/lib/c/include/inet/addr.h	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
+++ uspace/lib/c/include/inet/addr.h	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_INET_ADDR_H_
+#define LIBC_INET_ADDR_H_
+
+#include <stdint.h>
+
+/** Node address */
+typedef struct {
+	uint32_t ipv4;
+} inet_addr_t;
+
+/** Network address */
+typedef struct {
+	/** Address */
+	uint32_t ipv4;
+	/** Number of valid bits in @c ipv4 */
+	int bits;
+} inet_naddr_t;
+
+extern int inet_naddr_parse(const char *, inet_naddr_t *);
+extern int inet_addr_parse(const char *, inet_addr_t *);
+extern int inet_naddr_format(inet_naddr_t *, char **);
+extern int inet_addr_format(inet_addr_t *, char **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/inet/inet.h
===================================================================
--- uspace/lib/c/include/inet/inet.h	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/lib/c/include/inet/inet.h	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -36,11 +36,8 @@
 #define LIBC_INET_INET_H_
 
+#include <inet/addr.h>
 #include <sys/types.h>
 
 #define INET_TTL_MAX 255
-
-typedef struct {
-	uint32_t ipv4;
-} inet_addr_t;
 
 typedef struct {
Index: uspace/lib/c/include/inet/inetcfg.h
===================================================================
--- uspace/lib/c/include/inet/inetcfg.h	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/lib/c/include/inet/inetcfg.h	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -38,12 +38,4 @@
 #include <inet/inet.h>
 #include <sys/types.h>
-
-/** Network address */
-typedef struct {
-	/** Address */
-	uint32_t ipv4;
-	/** Number of valid bits in @c ipv4 */
-	int bits;
-} inet_naddr_t;
 
 /** Address object info */
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/lib/gui/window.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -424,5 +424,7 @@
 
 	while (!list_empty(&win->events.list)) {
-		list_remove(list_first(&win->events.list));
+		window_event_t *event = (window_event_t *) list_first(&win->events.list);
+		list_remove(&event->link);
+		free(event);
 	}
 
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/srv/hid/compositor/compositor.c	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -90,4 +90,5 @@
 typedef struct {
 	link_t link;
+	atomic_t ref_cnt;
 	service_id_t in_dsid;
 	service_id_t out_dsid;
@@ -138,4 +139,5 @@
 } viewport_t;
 
+static desktop_rect_t viewport_bound_rect;
 static FIBRIL_MUTEX_INITIALIZE(viewport_list_mtx);
 static LIST_INITIALIZE(viewport_list);
@@ -215,4 +217,5 @@
 
 	link_initialize(&win->link);
+	atomic_set(&win->ref_cnt, 0);
 	prodcons_initialize(&win->queue);
 	transform_identity(&win->transform);
@@ -232,5 +235,11 @@
 static void window_destroy(window_t *win)
 {
-	if (win) {
+	if (win && atomic_get(&win->ref_cnt) == 0) {
+		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);
@@ -310,4 +319,52 @@
 }
 
+static void comp_restrict_pointers(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 = list_get_instance(link, viewport_t, link);
+		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);
+
+	fibril_mutex_lock(&pointer_list_mtx);
+
+	list_foreach(pointer_list, link) {
+		pointer_t *ptr = list_get_instance(link, pointer_t, link);
+		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)
@@ -695,4 +752,15 @@
 	}
 
+	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;
@@ -706,12 +774,4 @@
 	}
 
-	/* Release window resources. */
-	loc_service_unregister(win->in_dsid);
-	loc_service_unregister(win->out_dsid);
-	while (!list_empty(&win->queue.list)) {
-		list_remove(list_first(&win->queue.list));
-	}
-	window_destroy(win);
-
 	comp_damage(x, y, width, height);
 
@@ -813,4 +873,5 @@
 
 	if (win) {
+		atomic_inc(&win->ref_cnt);
 		async_answer_0(iid, EOK);
 	} else {
@@ -825,5 +886,7 @@
 
 			if (!IPC_GET_IMETHOD(call)) {
-				async_answer_0(callid, EINVAL);
+				async_answer_0(callid, EOK);
+				atomic_dec(&win->ref_cnt);
+				window_destroy(win);
 				return;
 			}
@@ -842,5 +905,7 @@
 
 			if (!IPC_GET_IMETHOD(call)) {
-				async_answer_0(callid, EINVAL);
+				comp_window_close(win, callid, &call);
+				atomic_dec(&win->ref_cnt);
+				window_destroy(win);
 				return;
 			}
@@ -857,5 +922,7 @@
 				break;
 			case WINDOW_CLOSE:
-				comp_window_close(win, callid, &call);
+				/* Postpone the closing until the phone is hung up to cover
+				 * the case when the client is killed abruptly. */
+				async_answer_0(callid, EOK);
 				break;
 			case WINDOW_CLOSE_REQUEST:
@@ -911,4 +978,5 @@
 	async_answer_0(iid, EOK);
 
+	comp_restrict_pointers();
 	comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
 }
@@ -956,4 +1024,7 @@
 		fibril_mutex_unlock(&viewport_list_mtx);
 		async_answer_0(iid, EOK);
+
+		comp_restrict_pointers();
+		comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
 	}
 }
@@ -1391,4 +1462,16 @@
 	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;
@@ -1910,4 +1993,5 @@
 			fibril_mutex_unlock(&viewport_list_mtx);
 
+			comp_restrict_pointers();
 			comp_damage(x, y, width, height);
 		} else {
@@ -2122,5 +2206,6 @@
 		return -1;
 	}
-	
+
+	comp_restrict_pointers();
 	comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
 	
Index: uspace/srv/net/inetsrv/inetsrv.h
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.h	(revision ef90489533a7bc7e91d2f7f7f7592ccfbe533ed6)
+++ uspace/srv/net/inetsrv/inetsrv.h	(revision 8fdb18e1b43cce69fbf3e0ce3a63e333e77c79db)
@@ -40,4 +40,5 @@
 #include <adt/list.h>
 #include <stdbool.h>
+#include <inet/addr.h>
 #include <inet/iplink.h>
 #include <ipc/loc.h>
@@ -61,17 +62,4 @@
 	link_t client_list;
 } inetping_client_t;
-
-/** Host address */
-typedef struct {
-	uint32_t ipv4;
-} inet_addr_t;
-
-/** Network address */
-typedef struct {
-	/** Address */
-	uint32_t ipv4;
-	/** Number of valid bits in @c ipv4 */
-	int bits;
-} inet_naddr_t;
 
 /** Address object info */
