Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 67472b9b2fe45eb27d0fdbb80b57702416e56ce2)
+++ uspace/srv/hid/compositor/compositor.c	(revision 62fbb7ef714f1160227d2fa29a651dfab2544a5b)
@@ -58,5 +58,5 @@
 
 #include <event.h>
-#include <graph_iface.h>
+#include <device/graph_dev.h>
 #include <io/keycode.h>
 #include <io/mode.h>
@@ -72,5 +72,4 @@
 #include <codec/tga.h>
 
-#include "images.h"
 #include "compositor.h"
 
@@ -162,5 +161,4 @@
 static void input_disconnect(void);
 
-
 static pointer_t *input_pointer(input_t *input)
 {
@@ -168,11 +166,10 @@
 }
 
-static pointer_t *pointer_create()
+static pointer_t *pointer_create(void)
 {
 	pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
-	if (!p) {
+	if (!p)
 		return NULL;
-	}
-
+	
 	link_initialize(&p->link);
 	p->pos.x = coord_origin;
@@ -186,5 +183,5 @@
 	p->state = 0;
 	cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
-
+	
 	/* Ghost window for transformation animation. */
 	transform_identity(&p->ghost.transform);
@@ -199,5 +196,5 @@
 	p->accum_ghost.x = 0;
 	p->accum_ghost.y = 0;
-
+	
 	return p;
 }
@@ -211,19 +208,17 @@
 }
 
-static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
+static window_t *window_create(void)
 {
 	window_t *win = (window_t *) malloc(sizeof(window_t));
-	if (!win) {
+	if (!win)
 		return NULL;
-	}
-
+	
 	link_initialize(&win->link);
 	atomic_set(&win->ref_cnt, 0);
 	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;
@@ -231,5 +226,5 @@
 	win->opacity = 255;
 	win->surface = NULL;
-
+	
 	return win;
 }
@@ -294,16 +289,19 @@
     sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
 {
-	if (w_in > 0 && h_in > 0) {
+	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) {
+		
+		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);
@@ -311,4 +309,5 @@
 			(*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
 		}
+		
 		(*w_out) = (*w_out) - (*x_out) + 1;
 		(*h_out) = (*h_out) - (*y_out) + 1;
@@ -321,13 +320,13 @@
 }
 
-static void comp_restrict_pointers(void)
+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);
@@ -336,23 +335,27 @@
 		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,
+		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;
@@ -363,5 +366,5 @@
 		    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
 	}
-
+	
 	fibril_mutex_unlock(&pointer_list_mtx);
 }
@@ -642,12 +645,39 @@
 }
 
+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_multiply(&transform, &temp, &translate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &rotate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &scale);
+	
+	win->transform = transform;
+}
+
 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
 {
-	int rc;
-
 	ipc_callid_t callid;
 	size_t size;
 	unsigned int flags;
-
+	
 	/* Start sharing resized window with client. */
 	if (!async_share_out_receive(&callid, &size, &flags)) {
@@ -655,15 +685,15 @@
 		return;
 	}
+	
 	void *new_cell_storage;
-	rc = async_share_out_finalize(callid, &new_cell_storage);
+	int rc = async_share_out_finalize(callid, &new_cell_storage);
 	if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
 		async_answer_0(iid, ENOMEM);
 		return;
 	}
-
+	
 	/* Create new surface for the resized window. */
-	surface_t *new_surface = surface_create(
-	    IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
-	    new_cell_storage, SURFACE_FLAG_SHARED);
+	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);
@@ -671,30 +701,88 @@
 		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);
-
-	sysarg_t x, y;
-	sysarg_t width = old_width > new_width ? old_width : new_width;
-	sysarg_t height = old_height > new_height ? old_height : new_height;
-	comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y, &width, &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(iid, EOK);
 }
@@ -703,5 +791,5 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
-
+	
 	list_foreach(window_list, link, window_t, window) {
 		if (window == target) {
@@ -711,5 +799,5 @@
 		}
 	}
-
+	
 	fibril_mutex_unlock(&window_list_mtx);
 	free(event);
@@ -719,10 +807,11 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
+	
 	window_t *win = (window_t *) list_first(&window_list);
-	if (win) {
+	if (win)
 		prodcons_produce(&win->queue, &event->link);
-	} else {
+	else
 		free(event);
-	}
+	
 	fibril_mutex_unlock(&window_list_mtx);
 }
@@ -801,5 +890,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);
@@ -1173,36 +1262,4 @@
 }
 
-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_multiply(&transform, &temp, &translate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &rotate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &scale);
-	
-
-	win->transform = transform;
-}
-
 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)
@@ -1226,26 +1283,27 @@
 		double cx = 0;
 		double cy = 0;
-		if (pointer->grab_flags & GF_MOVE_X) {
+		
+		if (pointer->grab_flags & GF_MOVE_X)
 			cx = 1;
-		}
-		if (pointer->grab_flags & GF_MOVE_Y) {
+		
+		if (pointer->grab_flags & GF_MOVE_Y)
 			cy = 1;
-		}
-
-		if ((scale || resize) && (win->angle != 0)) {
+		
+		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; 
+		cx = (cx < 0) ? (-1 * cx) : cx;
 		cy = (cy < 0) ? (-1 * cy) : cy;
-
+		
 		win->dx += (cx * dx);
 		win->dy += (cy * dy);
 	}
 
-	if (scale || resize) {
+	if ((scale) || (resize)) {
 		double _dx = dx;
 		double _dy = dy;
@@ -1263,5 +1321,6 @@
 			if (fx > 0) {
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-				if (scale) win->fx *= fx;
+				if (scale)
+					win->fx *= fx;
 #endif
 #if ANIMATE_WINDOW_TRANSFORMS == 1
@@ -1444,24 +1503,29 @@
 {
 	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], 
+	surface_get_resolution(pointer->cursor.states[pointer->state],
 	     &cursor_width, &cursor_height);
-	if (pointer->pos.x + dx < viewport_bound_rect.x) {
+	
+	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) {
+	
+	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) {
+	
+	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) {
+	
+	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;
@@ -1469,5 +1533,5 @@
 	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);
@@ -1630,5 +1694,5 @@
 
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-		sysarg_t pre_x = 0; 
+		sysarg_t pre_x = 0;
 		sysarg_t pre_y = 0;
 		sysarg_t pre_width = 0;
@@ -1662,21 +1726,25 @@
 				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.rsz.width =
-						((((int) width) + dx) >= 0) ? (width + dx) : 0;
-				} else {
-					event_top->data.rsz.width = width;
-				}
-
-				if (pointer->grab_flags & GF_RESIZE_Y) {
-					event_top->data.rsz.height =
-						((((int) height) + dy) >= 0) ? (height + dy) : 0;
-				} else {
-					event_top->data.rsz.height = height;
-				}
+				
+				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;
 			}
 
@@ -1746,9 +1814,8 @@
 	    key == KC_O || key == KC_P);
 	bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
-	bool compositor_test = (mods & KM_ALT) && (key == KC_H);
 
 	bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
 	    win_opacity || win_close || win_switch || viewport_move ||
-	    viewport_change || kconsole_switch || compositor_test);
+	    viewport_change || kconsole_switch);
 
 	if (filter) {
@@ -1816,34 +1883,39 @@
 				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.rsz.width = width;
-				event->data.rsz.height = (height >= 20) ? height - 20 : 0;
+				event->data.resize.width = width;
+				event->data.resize.height = (height >= 20) ? height - 20 : 0;
 				break;
 			case KC_G:
-				event->data.rsz.width = width;
-				event->data.rsz.height = height + 20;
+				event->data.resize.width = width;
+				event->data.resize.height = height + 20;
 				break;
 			case KC_B:
-				event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
-				event->data.rsz.height = height;
+				event->data.resize.width = (width >= 20) ? width - 20 : 0;;
+				event->data.resize.height = height;
 				break;
 			case KC_N:
-				event->data.rsz.width = width + 20;
-				event->data.rsz.height = height;
+				event->data.resize.width = width + 20;
+				event->data.resize.height = height;
 				break;
 			default:
-				event->data.rsz.width = 0;
-				event->data.rsz.height = 0;
-				break;
-			}
-
+				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);
@@ -2014,33 +2086,4 @@
 	} else if (kconsole_switch) {
 		__SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
-	} else if (compositor_test) {
-		fibril_mutex_lock(&window_list_mtx);
-
-		window_t *red_win = window_create(0, 0);
-		red_win->surface = surface_create(250, 150, NULL, 0);
-		pixel_t red_pix = PIXEL(255, 240, 0, 0);
-		for (sysarg_t y = 0; y <  150; ++y) {
-			for (sysarg_t x = 0; x < 250; ++x) {
-				surface_put_pixel(red_win->surface, x, y, red_pix);
-			}
-		}
-		list_prepend(&red_win->link, &window_list);
-
-		window_t *blue_win = window_create(0, 0);
-		blue_win->surface = surface_create(200, 100, NULL, 0);
-		pixel_t blue_pix = PIXEL(255, 0, 0, 240);
-		for (sysarg_t y = 0; y <  100; ++y) {
-			for (sysarg_t x = 0; x < 200; ++x) {
-				surface_put_pixel(blue_win->surface, x, y, blue_pix);
-			}
-		}
-		list_prepend(&blue_win->link, &window_list);
-		
-		window_t *nameic_win = window_create(0, 0);
-		nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
-		list_prepend(&nameic_win->link, &window_list);
-
-		fibril_mutex_unlock(&window_list_mtx);
-		comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
 	} else {
 		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
