Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 3e6a98c595287c43d200d28d97f57755342be117)
+++ uspace/srv/hid/compositor/compositor.c	(revision d17a4a9b9b7d8b1ef841975044255958f61fbacc)
@@ -34,5 +34,5 @@
 
 #include <sys/types.h>
-#include <stdbool.h>
+#include <bool.h>
 #include <errno.h>
 #include <str_error.h>
@@ -87,4 +87,21 @@
 static sysarg_t coord_origin;
 static pixel_t bg_color;
+
+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;
+} pointer_t;
+
+static sysarg_t pointer_id = 0;
+static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
+static LIST_INITIALIZE(pointer_list);
 
 typedef struct {
@@ -112,23 +129,4 @@
 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;
@@ -183,17 +181,4 @@
 	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;
 }
@@ -207,5 +192,5 @@
 }
 
-static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
+static window_t *window_create()
 {
 	window_t *win = (window_t *) malloc(sizeof(window_t));
@@ -217,8 +202,7 @@
 	prodcons_initialize(&win->queue);
 	transform_identity(&win->transform);
-	transform_translate(&win->transform, 
-	    coord_origin + x_offset, coord_origin + y_offset);
-	win->dx = coord_origin + x_offset;
-	win->dy = coord_origin + y_offset;
+	transform_translate(&win->transform, coord_origin, coord_origin);
+	win->dx = coord_origin;
+	win->dy = coord_origin;
 	win->fx = 1;
 	win->fy = 1;
@@ -266,5 +250,5 @@
 }
 
-static void comp_coord_from_client(double x_in, double y_in, transform_t win_trans,
+static void comp_coord_from_client(sysarg_t x_in, sysarg_t y_in, transform_t win_trans,
     sysarg_t *x_out, sysarg_t *y_out)
 {
@@ -279,33 +263,26 @@
 }
 
-static void comp_coord_bounding_rect(double x_in, double y_in,
-    double w_in, double h_in, transform_t win_trans,
+static void comp_coord_bounding_rect(sysarg_t x_in, sysarg_t y_in,
+    sysarg_t w_in, sysarg_t 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 (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;
-	}
+	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, y_in, win_trans, &x[1], &y[1]);
+	comp_coord_from_client(x_in + w_in, y_in + h_in, win_trans, &x[2], &y[2]);
+	comp_coord_from_client(x_in, y_in + h_in, win_trans, &x[3], &y[3]);
+	(*x_out) = x[0];
+	(*y_out) = y[0];
+	(*w_out) = x[0];
+	(*h_out) = y[0];
+	for (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) -= (*x_out);
+	(*h_out) -= (*y_out);
 }
 
@@ -332,13 +309,8 @@
 			/* 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;
+				for (sysarg_t x = x_dmg_vp - vp->pos.x; x < x_dmg_vp - vp->pos.x + w_dmg_vp; ++x) {
+					surface_put_pixel(vp->surface, x, y, 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;
@@ -391,80 +363,4 @@
 			list_foreach(pointer_list, link) {
 
-				pointer_t *ptr = list_get_instance(link, pointer_t, link);
-				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) {
-
 				/* Determine what part of the pointer intersects with the
 				 * updated area of the current viewport. */
@@ -480,9 +376,10 @@
 				if (isec_ptr) {
 					/* Pointer is currently painted directly by copying pixels.
-					 * However, it is possible to draw the pointer similarly
+					 * However, it is possible to draw the painter similarly
 					 * as window by using drawctx_transfer. It would allow
 					 * more sophisticated control over drawing, but would also
 					 * cost more regarding the performance. */
 
+					pixel_t pix = 0;
 					sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
 					sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
@@ -491,17 +388,12 @@
 
 					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;
+						for (sysarg_t x = 0; x < w_dmg_ptr; ++x) {
+							pix = surface_get_pixel(sf_ptr, x_ptr + x, y_ptr + y);
+							if (ALPHA(pix) == 255) {
+								surface_put_pixel(vp->surface, x_vp + x, y_vp + y, pix);
+							}
 						}
 					}
-					surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr);
 				}
-
 			}
 		}
@@ -549,8 +441,8 @@
 static void comp_window_damage(window_t *win, ipc_callid_t iid, 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);
+	sysarg_t x = IPC_GET_ARG1(*icall);
+	sysarg_t y = IPC_GET_ARG2(*icall);
+	sysarg_t width = IPC_GET_ARG3(*icall);
+	sysarg_t height = IPC_GET_ARG4(*icall);
 
 	if (width == 0 || height == 0) {
@@ -558,9 +450,8 @@
 	} 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);
+		comp_coord_bounding_rect(x, y, width, height,
+		    win->transform, &x, &y, &width, &height);
 		fibril_mutex_unlock(&window_list_mtx);
-		comp_damage(x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob);
+		comp_damage(x, y, width, height);
 	}
 
@@ -577,5 +468,5 @@
 		pointer_t *pointer = list_get_instance(link, pointer_t, link);
 		if (pointer->id == pos_id) {
-			pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
+			pointer->grab_flags = grab_flags;
 			// TODO change pointer->state according to grab_flags
 			break;
@@ -650,32 +541,4 @@
 }
 
-static void comp_post_event_win(window_event_t *event, window_t *target)
-{
-	fibril_mutex_lock(&window_list_mtx);
-	window_t *window = NULL;
-	list_foreach(window_list, link) {
-		window = list_get_instance(link, window_t, link);
-		if (window == target) {
-			prodcons_produce(&window->queue, &event->link);
-		}
-	}
-	if (!window) {
-		free(event);
-	}
-	fibril_mutex_unlock(&window_list_mtx);
-}
-
-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_callid_t iid, ipc_call_t *icall)
 {
@@ -683,15 +546,5 @@
 	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);
-	}
 
 	/* Calculate damage. */
@@ -748,5 +601,5 @@
 			fibril_mutex_lock(&window_list_mtx);
 
-			window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			window_t *win = window_create();
 			if (!win) {
 				async_answer_2(callid, ENOMEM, 0, 0);
@@ -777,20 +630,8 @@
 			}
 
-			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(callid, 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);
-			}
-
 			return;
 		} else {
@@ -1112,4 +953,16 @@
 }
 
+static void comp_post_event(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_recalc_transform(window_t *win)
 {
@@ -1120,13 +973,9 @@
 	transform_t scale;
 	transform_identity(&scale);
-	if (win->fx != 1 || win->fy != 1) {
-		transform_scale(&scale, win->fx, win->fy);
-	}
+	transform_scale(&scale, win->fx, win->fy);
 
 	transform_t rotate;
 	transform_identity(&rotate);
-	if (win->angle != 0) {
-		transform_rotate(&rotate, win->angle);
-	}
+	transform_rotate(&rotate, win->angle);
 
 	transform_t transform;
@@ -1145,8 +994,7 @@
 
 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)
+     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;
@@ -1172,5 +1020,5 @@
 		}
 
-		if ((scale || resize) && (win->angle != 0)) {
+		if (scale || resize) {
 			transform_t rotate;
 			transform_identity(&rotate);
@@ -1189,22 +1037,15 @@
 		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);
-		}
+		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));
+			double fx = 1.0 + (_dx / (width * 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;
 			}
@@ -1212,12 +1053,7 @@
 
 		if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
-			double fy = 1.0 + (_dy / ((height - 1) * win->fy));
+			double fy = 1.0 + (_dy / (height * 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;
 			}
@@ -1235,113 +1071,4 @@
 	    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 int comp_abs_move(input_t *input, unsigned x , unsigned y,
@@ -1398,5 +1125,4 @@
 
 	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) {
@@ -1410,8 +1136,8 @@
 			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;
+			fibril_mutex_unlock(&window_list_mtx);
+
 			if (within_client) {
-				event = (window_event_t *) malloc(sizeof(window_event_t));
+				window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
 				if (event) {
 					link_initialize(&event->link);
@@ -1422,45 +1148,16 @@
 					event->data.pos.hpos = point_x;
 					event->data.pos.vpos = point_y;
+					comp_post_event(event);
 				}
 			}
-
-			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);
@@ -1468,5 +1165,4 @@
 		}
 	} else {
-		fibril_mutex_unlock(&pointer_list_mtx);
 		fibril_mutex_unlock(&window_list_mtx);
 	}
@@ -1478,44 +1174,4 @@
 {
 	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) {
-		win = list_get_instance(link, window_t, link);
-		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) {
@@ -1524,37 +1180,69 @@
 		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. */
+		/* Check whether mouse press belongs to the top-level window. */
+		fibril_mutex_lock(&window_list_mtx);
+		window_t *win = (window_t *) list_first(&window_list);
+		if (!win || !win->surface) {
+			fibril_mutex_unlock(&window_list_mtx);
+			return EOK;
+		}
+		sysarg_t x, y, width, height;
+		surface_get_resolution(win->surface, &width, &height);
+		bool within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
+		    win->transform, width, height, &x, &y);
+		fibril_mutex_unlock(&window_list_mtx);
+
+		/* Send mouse press to the top-level window. */
 		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;
-		}
-
+			window_event_t *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_PRESS;
+				event->data.pos.btn_num = bnum;
+				event->data.pos.hpos = x;
+				event->data.pos.vpos = y;
+				comp_post_event(event);
+			} else {
+				return ENOMEM;
+			}
+		}
 	} else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
 		pointer->pressed = false;
 
-#if ANIMATE_WINDOW_TRANSFORMS == 0
+		fibril_mutex_lock(&window_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 release belongs to. */
+		list_foreach(window_list, link) {
+			win = list_get_instance(link, window_t, link);
+			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) {
+			pointer->grab_flags = GF_EMPTY;
+			fibril_mutex_unlock(&window_list_mtx);
+			return EOK;
+		}
+
+		window_event_t *event = NULL;
+		sysarg_t dmg_x, dmg_y;
+		sysarg_t dmg_width = 0;
+		sysarg_t dmg_height = 0;
+
 		sysarg_t pre_x = 0; 
 		sysarg_t pre_y = 0;
@@ -1562,9 +1250,6 @@
 		sysarg_t pre_height = 0;
 
+#if ANIMATE_WINDOW_TRANSFORMS == 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;
@@ -1578,15 +1263,13 @@
 
 			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 = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event) {
+				link_initialize(&event->link);
+				event->type = ET_WINDOW_RESIZE;
 
 				int dx = (int) (((double) width) * (scale_back_x - 1.0));
@@ -1594,15 +1277,15 @@
 
 				if (pointer->grab_flags & GF_RESIZE_X) {
-					event_top->data.rsz.width =
+					event->data.rsz.width =
 						((((int) width) + dx) >= 0) ? (width + dx) : 0;
 				} else {
-					event_top->data.rsz.width = width;
+					event->data.rsz.width = width;
 				}
 
 				if (pointer->grab_flags & GF_RESIZE_Y) {
-					event_top->data.rsz.height =
+					event->data.rsz.height =
 						((((int) height) + dy) >= 0) ? (height + dy) : 0;
 				} else {
-					event_top->data.rsz.height = height;
+					event->data.rsz.height = height;
 				}
 			}
@@ -1613,15 +1296,23 @@
 			
 			/* 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;
+			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_RELEASE;
+				event->data.pos.btn_num = bnum;
+				event->data.pos.hpos = point_x;
+				event->data.pos.vpos = point_y;
 			}
 			pointer->grab_flags = GF_EMPTY;
+			
+		} else if (within_client && (pointer->grab_flags == GF_EMPTY) && (bnum == 1)) {
+
+			/* Bring the window to the foreground. */
+			list_remove(&win->link);
+			list_prepend(&win->link, &window_list);
+			comp_coord_bounding_rect(0, 0, width, height, win->transform,
+			    &dmg_x, &dmg_y, &dmg_width, &dmg_height);
 			
 		} else {
@@ -1629,26 +1320,13 @@
 		}
 
-	}
-
-	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);
+		fibril_mutex_unlock(&window_list_mtx);
+
+		if (dmg_width > 0 && dmg_height > 0) {
+			comp_damage(dmg_x, dmg_y, dmg_width, dmg_height);
+		}
+
+		if (event) {
+			comp_post_event(event);
+		}
 	}
 
@@ -1774,5 +1452,5 @@
 
 			fibril_mutex_unlock(&window_list_mtx);
-			comp_post_event_top(event);
+			comp_post_event(event);
 		} else {
 			fibril_mutex_unlock(&window_list_mtx);
@@ -1816,5 +1494,5 @@
 		event->type = ET_WINDOW_CLOSE;
 
-		comp_post_event_top(event);
+		comp_post_event(event);
 	} else if (win_switch) {
 		fibril_mutex_lock(&window_list_mtx);
@@ -1824,16 +1502,4 @@
 			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;
@@ -1864,13 +1530,4 @@
 
 			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 {
@@ -1943,5 +1600,5 @@
 		fibril_mutex_lock(&window_list_mtx);
 
-		window_t *red_win = window_create(0, 0);
+		window_t *red_win = window_create();
 		red_win->surface = surface_create(250, 150, NULL, 0);
 		pixel_t red_pix = PIXEL(255, 240, 0, 0);
@@ -1953,5 +1610,5 @@
 		list_prepend(&red_win->link, &window_list);
 
-		window_t *blue_win = window_create(0, 0);
+		window_t *blue_win = window_create();
 		blue_win->surface = surface_create(200, 100, NULL, 0);
 		pixel_t blue_pix = PIXEL(255, 0, 0, 240);
@@ -1963,9 +1620,9 @@
 		list_prepend(&blue_win->link, &window_list);
 
-		window_t *helenos_win = window_create(0, 0);
+		window_t *helenos_win = window_create();
 		helenos_win->surface = decode_tga((void *) helenos_tga, helenos_tga_size, 0);
 		list_prepend(&helenos_win->link, &window_list);
 
-		window_t *nameic_win = window_create(0, 0);
+		window_t *nameic_win = window_create();
 		nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
 		list_prepend(&nameic_win->link, &window_list);
@@ -1985,5 +1642,5 @@
 		event->data.kbd.c = c;
 
-		comp_post_event_top(event);
+		comp_post_event(event);
 	}
 
@@ -2036,5 +1693,5 @@
 static void input_disconnect(void)
 {
-	pointer_t *pointer = input->user;
+    	pointer_t *pointer = input->user;
 	input_close(input);
 	pointer_destroy(pointer);
@@ -2049,5 +1706,5 @@
 {
 	/* Coordinates of the central pixel. */
-	coord_origin = UINT32_MAX / 4;
+	coord_origin = UINT32_MAX / 2;
 	
 	/* Color of the viewport background. Must be opaque. */
