Index: uspace/app/fontedit/fontedit.c
===================================================================
--- uspace/app/fontedit/fontedit.c	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/app/fontedit/fontedit.c	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -33,8 +33,5 @@
  */
 
-#include <canvas.h>
-#include <draw/surface.h>
 #include <fibril.h>
-#include <guigfx/canvas.h>
 #include <gfx/color.h>
 #include <gfx/font.h>
@@ -47,6 +44,7 @@
 #include <stdlib.h>
 #include <str.h>
-#include <task.h>
-#include <window.h>
+#include <ui/ui.h>
+#include <ui/wdecor.h>
+#include <ui/window.h>
 #include "fontedit.h"
 
@@ -58,4 +56,14 @@
 
 static errno_t font_edit_paint(font_edit_t *);
+
+static void font_edit_close_event(ui_window_t *, void *);
+static void font_edit_kbd_event(ui_window_t *, void *, kbd_event_t *);
+static void font_edit_pos_event(ui_window_t *, void *, pos_event_t *);
+
+static ui_window_cb_t font_edit_window_cb = {
+	.close = font_edit_close_event,
+	.kbd = font_edit_kbd_event,
+	.pos = font_edit_pos_event
+};
 
 /** Clear screen.
@@ -159,27 +167,49 @@
 }
 
+/** Handle font editor close event.
+ *
+ * @param window Window
+ * @param arg Argument (font_edit_t *)
+ */
+static void font_edit_close_event(ui_window_t *window, void *arg)
+{
+	font_edit_t *fedit = (font_edit_t *) arg;
+
+	ui_quit(fedit->ui);
+}
+
 /** Handle font editor position event.
  *
- * @param widget Canvas widget
- * @param data Position event
- */
-static void font_edit_pos_event(widget_t *widget, void *data)
-{
-	pos_event_t *event = (pos_event_t *) data;
-	font_edit_t *fedit;
+ * @param window Window
+ * @param arg Argument (font_edit_t *)
+ * @param event Position event
+ */
+static void font_edit_pos_event(ui_window_t *window, void *arg,
+    pos_event_t *event)
+{
+	font_edit_t *fedit = (font_edit_t *) arg;
+	gfx_coord2_t pos;
+	gfx_rect_t rect;
 	int x, y;
 
-	fedit = (font_edit_t *) widget_get_data(widget);
-
-	if (event->type == POS_PRESS) {
-		x = gfx_coord_div_rneg((int)event->hpos - glyph_orig_x,
-		    glyph_scale);
-		y = gfx_coord_div_rneg((int)event->vpos - glyph_orig_y,
-		    glyph_scale);
-
-		printf("x=%d y=%d\n", x, y);
-		gfx_glyph_bmp_setpix(fedit->gbmp, x, y, fedit->pen_color);
-		font_edit_paint(fedit);
-	}
+	ui_window_get_app_rect(window, &rect);
+
+	pos.x = event->hpos;
+	pos.y = event->vpos;
+
+	if (event->type != POS_PRESS)
+		return;
+
+	if (!gfx_pix_inside_rect(&pos, &rect))
+		return;
+
+	x = gfx_coord_div_rneg(pos.x - glyph_orig_x -
+	    rect.p0.x, glyph_scale);
+	y = gfx_coord_div_rneg(pos.y - glyph_orig_y -
+	    rect.p0.y, glyph_scale);
+
+	printf("x=%d y=%d\n", x, y);
+	gfx_glyph_bmp_setpix(fedit->gbmp, x, y, fedit->pen_color);
+	font_edit_paint(fedit);
 }
 
@@ -371,13 +401,12 @@
 /** Handle font editor keyboard event.
  *
- * @param widget Canvas widget
- * @param data Position event
- */
-static void font_edit_kbd_event(widget_t *widget, void *data)
-{
-	kbd_event_t *event = (kbd_event_t *) data;
-	font_edit_t *fedit;
-
-	fedit = (font_edit_t *) widget_get_data(widget);
+ * @param window Window
+ * @param arg Argument (font_edit_t *)
+ * @param event Keyboard event
+ */
+static void font_edit_kbd_event(ui_window_t *window, void *arg,
+    kbd_event_t *event)
+{
+	font_edit_t *fedit = (font_edit_t *) arg;
 
 	if (event->type != KEY_PRESS)
@@ -440,32 +469,44 @@
 static errno_t font_edit_paint_preview(font_edit_t *fedit)
 {
+	gfx_color_t *color;
 	errno_t rc;
+
+	rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
+	if (rc != EOK)
+		return rc;
+
+	rc = gfx_set_color(fedit->gc, color);
+	if (rc != EOK)
+		goto error;
 
 	rc = font_edit_paint_preview_str(fedit, 20, 20,
 	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 	if (rc != EOK)
-		return rc;
+		goto error;
 
 	rc = font_edit_paint_preview_str(fedit, 20, 40,
 	    "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG");
 	if (rc != EOK)
-		return rc;
+		goto error;
 
 	rc = font_edit_paint_preview_str(fedit, 20, 60,
 	    "abcdefghijklmnopqrstuvwxyz");
 	if (rc != EOK)
-		return rc;
+		goto error;
 
 	rc = font_edit_paint_preview_str(fedit, 20, 80,
 	    "the quick brown fox jumps over the lazy dog");
 	if (rc != EOK)
-		return rc;
+		goto error;
 
 	rc = font_edit_paint_preview_str(fedit, 20, 100,
 	    "0123456789,./<>?;'\\:\"|[]{}`~!@#$%^&*()-_=+");
 	if (rc != EOK)
-		return rc;
+		goto error;
 
 	return EOK;
+error:
+	gfx_color_delete(color);
+	return rc;
 }
 
@@ -620,17 +661,19 @@
 /** Create font editor.
  *
- * @param display_svc Display service
+ * @param display_spec Display specifier
  * @param fname Font file to open or @c NULL to create new font
  * @param rfedit Place to store pointer to new font editor
  * @return EOK on success or an error code
  */
-static errno_t font_edit_create(const char *display_svc, const char *fname,
+static errno_t font_edit_create(const char *display_spec, const char *fname,
     font_edit_t **rfedit)
 {
-	canvas_gc_t *cgc = NULL;
-	window_t *window = NULL;
-	pixel_t *pixbuf = NULL;
-	surface_t *surface = NULL;
-	canvas_t *canvas = NULL;
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	gfx_rect_t rect;
+	gfx_rect_t wrect;
+	gfx_coord2_t off;
+	ui_window_t *window = NULL;
+	gfx_context_t *gc = NULL;
 	font_edit_t *fedit = NULL;
 	gfx_typeface_t *tface = NULL;
@@ -643,5 +686,4 @@
 	gfx_glyph_bmp_t *bmp;
 	gfx_coord_t vw, vh;
-	gfx_context_t *gc;
 	errno_t rc;
 
@@ -652,11 +694,9 @@
 	}
 
-	printf("Init canvas..\n");
-
-	window = window_open(display_svc, NULL,
-	    WINDOW_MAIN | WINDOW_DECORATED, "Font Editor");
-	if (window == NULL) {
-		printf("Error creating window.\n");
-		rc = ENOMEM;
+	printf("Init UI..\n");
+
+	rc = ui_create(display_spec, &ui);
+	if (rc != EOK) {
+		printf("Error initializing UI (%s)\n", display_spec);
 		goto error;
 	}
@@ -665,40 +705,33 @@
 	vh = 300;
 
-	pixbuf = calloc(vw * vh, sizeof(pixel_t));
-	if (pixbuf == NULL) {
-		printf("Error allocating memory for pixel buffer.\n");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	surface = surface_create(vw, vh, pixbuf, 0);
-	if (surface == NULL) {
-		printf("Error creating surface.\n");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	/* Memory block pixbuf is now owned by surface */
-	pixbuf = NULL;
-
-	canvas = create_canvas(window_root(window), fedit, vw, vh,
-	    surface);
-	if (canvas == NULL) {
-		printf("Error creating canvas.\n");
-		rc = ENOMEM;
-		goto error;
-	}
-
-	window_resize(window, 0, 0, vw + 10, vh + 30, WINDOW_PLACEMENT_ANY);
-	window_exec(window);
-
-	printf("Create canvas GC\n");
-	rc = canvas_gc_create(canvas, surface, &cgc);
+	rect.p0.x = 0;
+	rect.p0.y = 0;
+	rect.p1.x = vw;
+	rect.p1.y = vh;
+
+	ui_wnd_params_init(&params);
+	params.caption = "Font Editor";
+
+	/*
+	 * Compute window rectangle such that application area corresponds
+	 * to rect
+	 */
+	ui_wdecor_rect_from_app(&rect, &wrect);
+	off = wrect.p0;
+	gfx_rect_rtranslate(&off, &wrect, &params.rect);
+
+	rc = ui_window_create(ui, &params, &window);
 	if (rc != EOK) {
-		printf("Error creating canvas GC.\n");
-		goto error;
-	}
-
-	gc = canvas_gc_get_ctx(cgc);
+		printf("Error creating window.\n");
+		goto error;
+	}
+
+	ui_window_set_cb(window, &font_edit_window_cb, (void *) fedit);
+
+	rc = ui_window_get_app_gc(window, &gc);
+	if (rc != EOK) {
+		printf("Error creating graphic context.\n");
+		goto error;
+	}
 
 	if (fname == NULL) {
@@ -755,13 +788,9 @@
 	}
 
-	sig_connect(&canvas->position_event, &canvas->widget,
-	    font_edit_pos_event);
-	sig_connect(&canvas->keyboard_event, &canvas->widget,
-	    font_edit_kbd_event);
-
 	if (fname == NULL)
 		fname = "new.tpf";
 
-	fedit->cgc = cgc;
+	fedit->ui = ui;
+	fedit->window = window;
 	fedit->gc = gc;
 	fedit->width = vw;
@@ -790,10 +819,8 @@
 	if (tface != NULL)
 		gfx_typeface_destroy(tface);
-	if (surface != NULL)
-		surface_destroy(surface);
-	if (pixbuf != NULL)
-		free(pixbuf);
 	if (window != NULL)
-		window_close(window);
+		ui_window_destroy(window);
+	if (ui != NULL)
+		ui_destroy(ui);
 	if (fedit != NULL)
 		free(fedit);
@@ -801,7 +828,22 @@
 }
 
+/** Destroy font editor.
+ *
+ * @param fedit Font editor
+ */
+static void font_edit_destroy(font_edit_t *fedit)
+{
+	gfx_glyph_bmp_close(fedit->gbmp);
+	gfx_glyph_destroy(fedit->glyph);
+	gfx_font_close(fedit->font);
+	gfx_typeface_destroy(fedit->typeface);
+	ui_window_destroy(fedit->window);
+	ui_destroy(fedit->ui);
+	free(fedit);
+}
+
 static void print_syntax(void)
 {
-	printf("Syntax: fontedit [-d <display>] [<file.tpf>]\n");
+	printf("Syntax: fontedit [-d <display-spec>] [<file.tpf>]\n");
 }
 
@@ -809,5 +851,5 @@
 {
 	errno_t rc;
-	const char *display_svc = DISPLAY_DEFAULT;
+	const char *display_spec = UI_DISPLAY_DEFAULT;
 	const char *fname = NULL;
 	font_edit_t *fedit;
@@ -824,5 +866,5 @@
 			}
 
-			display_svc = argv[i++];
+			display_spec = argv[i++];
 		} else {
 			printf("Invalid option '%s'.\n", argv[i]);
@@ -845,5 +887,5 @@
 	}
 
-	rc = font_edit_create(display_svc, fname, &fedit);
+	rc = font_edit_create(display_spec, fname, &fedit);
 	if (rc != EOK)
 		return 1;
@@ -851,7 +893,9 @@
 	(void) font_edit_paint(fedit);
 
-	task_retval(0);
-	async_manager();
-
+	ui_run(fedit->ui);
+	font_edit_destroy(fedit);
+
+	(void) font_edit_kbd_event;
+	(void) font_edit_pos_event;
 	return 0;
 }
Index: uspace/app/fontedit/fontedit.h
===================================================================
--- uspace/app/fontedit/fontedit.h	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/app/fontedit/fontedit.h	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -40,10 +40,13 @@
 #include <gfx/glyph_bmp.h>
 #include <gfx/typeface.h>
-#include <guigfx/canvas.h>
+#include <ui/ui.h>
+#include <ui/window.h>
 
 /** Font editor */
 typedef struct {
-	/** Canvas GC */
-	canvas_gc_t *cgc;
+	/** UI */
+	ui_t *ui;
+	/** Window */
+	ui_window_t *window;
 	/** Graphic context */
 	gfx_context_t *gc;
Index: uspace/app/fontedit/meson.build
===================================================================
--- uspace/app/fontedit/meson.build	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/app/fontedit/meson.build	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'gfx', 'guigfx', 'gfxfont' ]
+deps = [ 'ui', 'gfx', 'gfxfont' ]
 src = files(
 	'fontedit.c',
Index: uspace/lib/ui/include/ui/window.h
===================================================================
--- uspace/lib/ui/include/ui/window.h	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/lib/ui/include/ui/window.h	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -55,4 +55,5 @@
 extern ui_resource_t *ui_window_get_res(ui_window_t *);
 extern gfx_context_t *ui_window_get_gc(ui_window_t *);
+extern errno_t ui_window_get_app_gc(ui_window_t *, gfx_context_t **);
 extern void ui_window_get_app_rect(ui_window_t *, gfx_rect_t *);
 extern errno_t ui_window_paint(ui_window_t *);
Index: uspace/lib/ui/meson.build
===================================================================
--- uspace/lib/ui/meson.build	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/lib/ui/meson.build	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'gfx', 'gfxfont', 'display' ]
+deps = [ 'gfx', 'gfxfont', 'memgfx', 'display' ]
 src = files(
 	'src/control.c',
Index: uspace/lib/ui/private/window.h
===================================================================
--- uspace/lib/ui/private/window.h	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/lib/ui/private/window.h	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -59,4 +59,8 @@
 	/** Window GC */
 	gfx_context_t *gc;
+	/** Application area bitmap */
+	gfx_bitmap_t *app_bmp;
+	/** Application area GC */
+	gfx_context_t *app_gc;
 	/** UI resource. Ideally this would be in ui_t. */
 	struct ui_resource *res;
Index: uspace/lib/ui/src/window.c
===================================================================
--- uspace/lib/ui/src/window.c	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/lib/ui/src/window.c	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -36,4 +36,5 @@
 #include <display.h>
 #include <errno.h>
+#include <gfx/bitmap.h>
 #include <gfx/context.h>
 #include <gfx/render.h>
@@ -41,4 +42,5 @@
 #include <io/pos_event.h>
 #include <mem.h>
+#include <memgfx/memgc.h>
 #include <stdlib.h>
 #include <ui/control.h>
@@ -74,4 +76,6 @@
 	.move = wd_move
 };
+
+static void ui_window_app_update(void *, gfx_rect_t *);
 
 /** Initialize window parameters structure.
@@ -223,4 +227,9 @@
 }
 
+/** Get UI resource from window.
+ *
+ * @param window Window
+ * @return UI resource
+ */
 ui_resource_t *ui_window_get_res(ui_window_t *window)
 {
@@ -228,4 +237,9 @@
 }
 
+/** Get window GC.
+ *
+ * @param window Window
+ * @return GC (relative to window)
+ */
 gfx_context_t *ui_window_get_gc(ui_window_t *window)
 {
@@ -233,4 +247,60 @@
 }
 
+/** Get window application area GC
+ *
+ * @param window Window
+ * @param rgc Place to store GC (relative to application area)
+ * @return EOK on success or an error code
+ */
+errno_t ui_window_get_app_gc(ui_window_t *window, gfx_context_t **rgc)
+{
+	gfx_bitmap_params_t params;
+	gfx_bitmap_alloc_t alloc;
+	gfx_rect_t rect;
+	mem_gc_t *memgc;
+	errno_t rc;
+
+	if (window->app_gc == NULL) {
+		assert(window->app_bmp == NULL);
+
+		gfx_bitmap_params_init(&params);
+
+		/*
+		 * The bitmap will have the same dimensions as the
+		 * application rectangle, but start at 0,0.
+		 */
+		ui_window_get_app_rect(window, &rect);
+		gfx_rect_rtranslate(&rect.p0, &rect, &params.rect);
+
+		rc = gfx_bitmap_create(window->gc, &params, NULL,
+		    &window->app_bmp);
+		if (rc != EOK)
+			return rc;
+
+		rc = gfx_bitmap_get_alloc(window->app_bmp, &alloc);
+		if (rc != EOK) {
+			gfx_bitmap_destroy(window->app_bmp);
+			return rc;
+		}
+
+		rc = mem_gc_create(&params.rect, &alloc, ui_window_app_update,
+		    (void *) window, &memgc);
+		if (rc != EOK) {
+			gfx_bitmap_destroy(window->app_bmp);
+			return rc;
+		}
+
+		window->app_gc = mem_gc_get_ctx(memgc);
+	}
+
+	*rgc = window->app_gc;
+	return EOK;
+}
+
+/** Get window application rectangle
+ *
+ * @param window Window
+ * @param rect Place to store application rectangle
+ */
 void ui_window_get_app_rect(ui_window_t *window, gfx_rect_t *rect)
 {
@@ -241,4 +311,9 @@
 }
 
+/** Paint window
+ *
+ * @param window Window
+ * @return EOK on success or an error code
+ */
 errno_t ui_window_paint(ui_window_t *window)
 {
@@ -428,4 +503,20 @@
 }
 
+/** Application area update callback
+ *
+ * @param arg Argument (ui_window_t *)
+ * @param rect Rectangle to update
+ */
+static void ui_window_app_update(void *arg, gfx_rect_t *rect)
+{
+	ui_window_t *window = (ui_window_t *) arg;
+	gfx_rect_t arect;
+
+	ui_window_get_app_rect(window, &arect);
+
+	/* Render bitmap rectangle inside the application area */
+	(void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
+}
+
 /** @}
  */
Index: uspace/lib/ui/test/window.c
===================================================================
--- uspace/lib/ui/test/window.c	(revision d942ca434442952e508031582931d7a5f5f20b3a)
+++ uspace/lib/ui/test/window.c	(revision 66a2becf49f1f530dd13dbf6fc8236890fb7f907)
@@ -29,4 +29,5 @@
 #include <gfx/context.h>
 #include <gfx/coord.h>
+#include <gfx/render.h>
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
@@ -207,4 +208,38 @@
 }
 
+/** ui_window_get_app_gc() return valid GC */
+PCUT_TEST(get_app_gc)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+	gfx_context_t *gc;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+	params.rect.p0.x = 0;
+	params.rect.p0.y = 0;
+	params.rect.p0.x = 10;
+	params.rect.p0.y = 10;
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_window_get_app_gc(window, &gc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(gc);
+
+	rc = gfx_fill_rect(gc, &params.rect);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
 /** Test ui_window_paint() */
 PCUT_TEST(paint)
