Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/app/edit/edit.c	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -111,5 +111,4 @@
 #define BUF_SIZE 64
 #define TAB_WIDTH 8
-#define ED_INFTY 65536
 
 /** Maximum filename length that can be entered. */
@@ -507,4 +506,5 @@
 static void key_handle_movement(unsigned int key, bool select)
 {
+	spt_t pt;
 	switch (key) {
 	case KC_LEFT:
@@ -521,8 +521,12 @@
 		break;
 	case KC_HOME:
-		caret_move_relative(0, -ED_INFTY, dir_after, select);
+		tag_get_pt(&pane.caret_pos, &pt);
+		pt_get_sol(&pt, &pt);
+		caret_move(pt, select, true);
 		break;
 	case KC_END:
-		caret_move_relative(0, +ED_INFTY, dir_before, select);
+		tag_get_pt(&pane.caret_pos, &pt);
+		pt_get_eol(&pt, &pt);
+		caret_move(pt, select, true);
 		break;
 	case KC_PAGE_UP:
Index: uspace/lib/c/arch/abs32le/include/types.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/abs32le/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -47,4 +47,5 @@
 
 typedef uint32_t sysarg_t;
+typedef int32_t native_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/amd64/include/types.h
===================================================================
--- uspace/lib/c/arch/amd64/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/amd64/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -47,4 +47,5 @@
 
 typedef uint64_t sysarg_t;
+typedef int64_t native_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/arch/arm32/include/types.h
===================================================================
--- uspace/lib/c/arch/arm32/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/arm32/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -48,4 +48,5 @@
 
 typedef uint32_t sysarg_t;
+typedef int32_t native_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/ia32/include/types.h
===================================================================
--- uspace/lib/c/arch/ia32/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/ia32/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -47,4 +47,5 @@
 
 typedef uint32_t sysarg_t;
+typedef int32_t native_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/ia64/include/types.h
===================================================================
--- uspace/lib/c/arch/ia64/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/ia64/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -57,4 +57,5 @@
 
 typedef uint64_t sysarg_t;
+typedef int64_t native_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/arch/mips32/include/types.h
===================================================================
--- uspace/lib/c/arch/mips32/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/mips32/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -48,4 +48,5 @@
 
 typedef uint32_t sysarg_t;
+typedef int32_t native_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/mips64/include/types.h
===================================================================
--- uspace/lib/c/arch/mips64/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/mips64/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -48,4 +48,5 @@
 
 typedef uint64_t sysarg_t;
+typedef int64_t native_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/arch/ppc32/include/types.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/ppc32/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -47,4 +47,5 @@
 
 typedef uint32_t sysarg_t;
+typedef int32_t native_t;
 
 typedef int32_t ssize_t;
Index: uspace/lib/c/arch/sparc64/include/types.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/types.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/arch/sparc64/include/types.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -47,4 +47,5 @@
 
 typedef uint64_t sysarg_t;
+typedef int64_t native_t;
 
 typedef int64_t ssize_t;
Index: uspace/lib/c/generic/io/input.c
===================================================================
--- uspace/lib/c/generic/io/input.c	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/c/generic/io/input.c	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -143,6 +143,6 @@
 	x = IPC_GET_ARG1(*call);
 	y = IPC_GET_ARG2(*call);
-	max_x = IPC_GET_ARG2(*call);
-	max_y = IPC_GET_ARG3(*call);
+	max_x = IPC_GET_ARG3(*call);
+	max_y = IPC_GET_ARG4(*call);
 
 	rc = input->ev_ops->abs_move(input, x, y, max_x, max_y);
Index: uspace/lib/draw/surface.c
===================================================================
--- uspace/lib/draw/surface.c	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/draw/surface.c	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -44,14 +44,14 @@
 	surface_flags_t flags;
 
-	sysarg_t dirty_x_lo;
-	sysarg_t dirty_x_hi;
-	sysarg_t dirty_y_lo;
-	sysarg_t dirty_y_hi;
+	surface_coord_t dirty_x_lo;
+	surface_coord_t dirty_x_hi;
+	surface_coord_t dirty_y_lo;
+	surface_coord_t dirty_y_hi;
 
 	pixelmap_t pixmap;
 };
 
-surface_t *surface_create(
-    sysarg_t width, sysarg_t height, pixel_t *pixbuf, surface_flags_t flags)
+surface_t *surface_create(surface_coord_t width, surface_coord_t height,
+    pixel_t *pixbuf, surface_flags_t flags)
 {
 	surface_t *surface = (surface_t *) malloc(sizeof(surface_t));
@@ -118,5 +118,5 @@
 }
 
-void surface_get_resolution(surface_t *surface, sysarg_t *width, sysarg_t *height)
+void surface_get_resolution(surface_t *surface, surface_coord_t *width, surface_coord_t *height)
 {
 	assert(width);
@@ -127,6 +127,6 @@
 }
 
-void surface_get_damaged_region(surface_t *surface, sysarg_t *x, sysarg_t *y,
-    sysarg_t *width, sysarg_t *height)
+void surface_get_damaged_region(surface_t *surface, surface_coord_t *x, surface_coord_t *y,
+    surface_coord_t *width, surface_coord_t *height)
 {
 	assert(x);
@@ -151,5 +151,5 @@
 }
 
-void surface_put_pixel(surface_t *surface, sysarg_t x, sysarg_t y, pixel_t pixel)
+void surface_put_pixel(surface_t *surface, surface_coord_t x, surface_coord_t y, pixel_t pixel)
 {
 	surface->dirty_x_lo = surface->dirty_x_lo > x ? x : surface->dirty_x_lo;
@@ -163,5 +163,5 @@
 }
 
-pixel_t surface_get_pixel(surface_t *surface, sysarg_t x, sysarg_t y)
+pixel_t surface_get_pixel(surface_t *surface, surface_coord_t x, surface_coord_t y)
 {
 	if (x < surface->pixmap.width && y < surface->pixmap.height) {
Index: uspace/lib/draw/surface.h
===================================================================
--- uspace/lib/draw/surface.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/lib/draw/surface.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -45,4 +45,6 @@
 typedef struct surface surface_t;
 
+typedef sysarg_t surface_coord_t;
+
 typedef enum {
 	SURFACE_FLAG_NONE = 0,
@@ -50,5 +52,5 @@
 } surface_flags_t;
 
-extern surface_t *surface_create(sysarg_t, sysarg_t, pixel_t *, surface_flags_t);
+extern surface_t *surface_create(surface_coord_t, surface_coord_t, pixel_t *, surface_flags_t);
 extern void surface_destroy(surface_t *);
 
@@ -56,11 +58,11 @@
 extern pixel_t *surface_direct_access(surface_t *);
 extern pixelmap_t *surface_pixmap_access(surface_t *);
-extern void surface_get_resolution(surface_t *, sysarg_t *, sysarg_t *);
-extern void surface_get_damaged_region(surface_t *, sysarg_t *, sysarg_t *,
-    sysarg_t *, sysarg_t *);
+extern void surface_get_resolution(surface_t *, surface_coord_t *, surface_coord_t *);
+extern void surface_get_damaged_region(surface_t *, surface_coord_t *, surface_coord_t *,
+    surface_coord_t *, surface_coord_t *);
 extern void surface_reset_damaged_region(surface_t *);
 
-extern void surface_put_pixel(surface_t *, sysarg_t, sysarg_t, pixel_t);
-extern pixel_t surface_get_pixel(surface_t *, sysarg_t, sysarg_t);
+extern void surface_put_pixel(surface_t *, surface_coord_t, surface_coord_t, pixel_t);
+extern pixel_t surface_get_pixel(surface_t *, surface_coord_t, surface_coord_t);
 
 #endif
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/srv/hid/compositor/compositor.c	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -92,11 +92,8 @@
 	sysarg_t id;
 	uint8_t state;
-	sysarg_t hpos;
-	sysarg_t vpos;
+	desktop_point_t pos;
 	sysarg_t btn_num;
-	sysarg_t btn_hpos;
-	sysarg_t btn_vpos;
-	int accum_dx;
-	int accum_dy;
+	desktop_point_t btn_pos;
+	desktop_vector_t accum;
 	sysarg_t grab_flags;
 	bool pressed;
@@ -135,6 +132,5 @@
 	vslmode_t mode;
 	async_sess_t *sess;
-	sysarg_t hpos;
-	sysarg_t vpos;
+	desktop_point_t pos;
 	surface_t *surface;
 } viewport_t;
@@ -174,11 +170,10 @@
 
 	link_initialize(&p->link);
-	p->hpos = coord_origin;
-	p->vpos = coord_origin;
+	p->pos.x = coord_origin;
+	p->pos.y = coord_origin;
 	p->btn_num = 1;
-	p->btn_hpos = p->hpos;
-	p->btn_vpos = p->vpos;
-	p->accum_dx = 0;
-	p->accum_dy = 0;
+	p->btn_pos = p->pos;
+	p->accum.x = 0;
+	p->accum.y = 0;
 	p->grab_flags = GF_EMPTY;
 	p->pressed = false;
@@ -307,5 +302,5 @@
 		bool isec_vp = rectangle_intersect(
 		    x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob,
-		    vp->hpos, vp->vpos, w_dmg_vp, h_dmg_vp,
+		    vp->pos.x, vp->pos.y, w_dmg_vp, h_dmg_vp,
 		    &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
 
@@ -313,6 +308,6 @@
 
 			/* Paint background color. */
-			for (sysarg_t y = y_dmg_vp - vp->vpos; y <  y_dmg_vp - vp->vpos + h_dmg_vp; ++y) {
-				for (sysarg_t x = x_dmg_vp - vp->hpos; x < x_dmg_vp - vp->hpos + w_dmg_vp; ++x) {
+			for (sysarg_t y = y_dmg_vp - vp->pos.y; y <  y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) {
+				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);
 				}
@@ -352,7 +347,8 @@
 					 * coordinates. */
 					transform = win->transform;
-					double hpos = vp->hpos;
-					double vpos = vp->vpos;
-					transform_translate(&transform, -hpos, -vpos);
+					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);				
@@ -361,5 +357,5 @@
 
 					drawctx_transfer(&context,
-					    x_dmg_win - vp->hpos, y_dmg_win - vp->vpos, w_dmg_win, h_dmg_win);
+					    x_dmg_win - vp->pos.x, y_dmg_win - vp->pos.y, w_dmg_win, h_dmg_win);
 				}
 			}
@@ -375,5 +371,5 @@
 				bool isec_ptr = rectangle_intersect(
 				    x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
-				    ptr->hpos, ptr->vpos, w_dmg_ptr, h_dmg_ptr,
+				    ptr->pos.x, ptr->pos.y, w_dmg_ptr, h_dmg_ptr,
 				    &x_dmg_ptr, &y_dmg_ptr, &w_dmg_ptr, &h_dmg_ptr);
 
@@ -386,8 +382,8 @@
 
 					pixel_t pix = 0;
-					sysarg_t x_vp = x_dmg_ptr - vp->hpos;
-					sysarg_t y_vp = y_dmg_ptr - vp->vpos;
-					sysarg_t x_ptr = x_dmg_ptr - ptr->hpos;
-					sysarg_t y_ptr = y_dmg_ptr - ptr->vpos;
+					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) {
@@ -901,6 +897,6 @@
 
 	link_initialize(&vp->link);
-	vp->hpos = coord_origin;
-	vp->vpos = coord_origin;
+	vp->pos.x = coord_origin;
+	vp->pos.y = coord_origin;
 
 	/* Establish output bidirectional connection. */
@@ -1002,8 +998,8 @@
 	/* window_list_mtx locked by caller */
 
-	int dx = pointer->accum_dx;
-	int dy = pointer->accum_dy;
-	pointer->accum_dx = 0;
-	pointer->accum_dy = 0;
+	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);
@@ -1079,6 +1075,34 @@
     unsigned max_x, unsigned max_y)
 {
-	/* XXX TODO */
-	return EOK;
+	/* 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);
 }
 
@@ -1089,15 +1113,14 @@
 	/* Update pointer position. */
 	fibril_mutex_lock(&pointer_list_mtx);
-	sysarg_t old_hpos = pointer->hpos;
-	sysarg_t old_vpos = pointer->vpos;
+	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);
-	pointer->hpos += dx;
-	pointer->vpos += dy;
+	pointer->pos.x += dx;
+	pointer->pos.y += dy;
 	fibril_mutex_unlock(&pointer_list_mtx);
-	comp_damage(old_hpos, old_vpos, cursor_width, cursor_height);
-	comp_damage(old_hpos + dx, old_vpos + dy, cursor_width, cursor_height);
+	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);
@@ -1111,5 +1134,5 @@
 			sysarg_t width, height;
 			surface_get_resolution(top->surface, &width, &height);
-			within_client = comp_coord_to_client(pointer->hpos, pointer->vpos,
+			within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
 			    top->transform, width, height, &point_x, &point_y);
 			fibril_mutex_unlock(&window_list_mtx);
@@ -1130,6 +1153,6 @@
 		} else {
 			/* Pointer is grabbed by top-level window action. */
-			pointer->accum_dx += dx;
-			pointer->accum_dy += dy;
+			pointer->accum.x += dx;
+			pointer->accum.y += dy;
 #if ANIMATE_WINDOW_TRANSFORMS == 1
 			sysarg_t x, y, width, height;
@@ -1153,6 +1176,5 @@
 
 	if (bpress) {
-		pointer->btn_hpos = pointer->hpos;
-		pointer->btn_vpos = pointer->vpos;
+		pointer->btn_pos = pointer->pos;
 		pointer->btn_num = bnum;
 		pointer->pressed = true;
@@ -1167,5 +1189,5 @@
 		sysarg_t x, y, width, height;
 		surface_get_resolution(win->surface, &width, &height);
-		bool within_client = comp_coord_to_client(pointer->hpos, pointer->vpos,
+		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);
@@ -1202,5 +1224,5 @@
 			if (win->surface) {
 				surface_get_resolution(win->surface, &width, &height);
-				within_client = comp_coord_to_client(pointer->hpos, pointer->vpos,
+				within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
 				    win->transform, width, height, &point_x, &point_y);
 			}
@@ -1518,27 +1540,27 @@
 			switch (key) {
 			case KC_I:
-				vp->hpos += 0;
-				vp->vpos += -20;
+				vp->pos.x += 0;
+				vp->pos.y += -20;
 				break;
 			case KC_K:
-				vp->hpos += 0;
-				vp->vpos += 20;
+				vp->pos.x += 0;
+				vp->pos.y += 20;
 				break;
 			case KC_J:
-				vp->hpos += -20;
-				vp->vpos += 0;
+				vp->pos.x += -20;
+				vp->pos.y += 0;
 				break;
 			case KC_L:
-				vp->hpos += 20;
-				vp->vpos += 0;
+				vp->pos.x += 20;
+				vp->pos.y += 0;
 				break;
 			default:
-				vp->hpos += 0;
-				vp->vpos += 0;
+				vp->pos.x += 0;
+				vp->pos.y += 0;
 				break;
 			}
 			
-			sysarg_t x = vp->hpos;
-			sysarg_t y = vp->vpos;
+			sysarg_t x = vp->pos.x;
+			sysarg_t y = vp->pos.y;
 			sysarg_t width, height;
 			surface_get_resolution(vp->surface, &width, &height);
Index: uspace/srv/hid/compositor/compositor.h
===================================================================
--- uspace/srv/hid/compositor/compositor.h	(revision 971f50e7b8ec7e54ff3b15b786bb8f91611ed5fd)
+++ uspace/srv/hid/compositor/compositor.h	(revision 6560960cca24c6b853cb85f2ce3ce468aa28cb6a)
@@ -36,4 +36,18 @@
 #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;
+
+/* TODO remove? */
+typedef struct {
+	double x;
+	double y;
+} double_point_t;
+typedef double_point_t double_vector_t;
+
 #endif
 
