Index: uspace/app/viewer/meson.build
===================================================================
--- uspace/app/viewer/meson.build	(revision 12008adfe6b01422d866fedbe63b45f8cdb5d9a9)
+++ uspace/app/viewer/meson.build	(revision 38f55980b853a6d2953396322e7620146fa59ad2)
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'gui' ]
+deps = [ 'ui', 'draw', 'compress' ]
 src = files('viewer.c')
 
Index: uspace/app/viewer/viewer.c
===================================================================
--- uspace/app/viewer/viewer.c	(revision 12008adfe6b01422d866fedbe63b45f8cdb5d9a9)
+++ uspace/app/viewer/viewer.c	(revision 38f55980b853a6d2953396322e7620146fa59ad2)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2020 Jiri Svoboda
  * Copyright (c) 2013 Martin Decky
  * All rights reserved.
@@ -33,24 +34,22 @@
  */
 
+#include <draw/surface.h>
+#include <draw/codec.h>
+#include <errno.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <str.h>
+#include <ui/image.h>
+#include <ui/ui.h>
+#include <ui/wdecor.h>
+#include <ui/window.h>
 #include <vfs/vfs.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <window.h>
-#include <canvas.h>
-#include <draw/surface.h>
-#include <draw/codec.h>
-#include <task.h>
-#include <str.h>
 
 #define NAME  "viewer"
 
-#define WINDOW_WIDTH   1024
-#define WINDOW_HEIGHT  768
-
-#define DECORATION_WIDTH	8
-#define DECORATION_HEIGHT	28
+typedef struct {
+	ui_t *ui;
+} viewer_t;
 
 static size_t imgs_count;
@@ -58,7 +57,8 @@
 static char **imgs;
 
-static window_t *main_window;
+static ui_window_t *window;
 static surface_t *surface = NULL;
-static canvas_t *canvas = NULL;
+static ui_image_t *image = NULL;
+static gfx_context_t *window_gc;
 
 static surface_coord_t img_width;
@@ -66,9 +66,29 @@
 
 static bool img_load(const char *, surface_t **);
-static bool img_setup(surface_t *);
-
-static void on_keyboard_event(widget_t *widget, void *data)
-{
-	kbd_event_t *event = (kbd_event_t *) data;
+static bool img_setup(gfx_context_t *, surface_t *);
+
+static void wnd_close(ui_window_t *, void *);
+static void wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
+
+static ui_window_cb_t window_cb = {
+	.close = wnd_close,
+	.kbd = wnd_kbd_event
+};
+
+/** Window close request
+ *
+ * @param window Window
+ * @param arg Argument (calc_t *)
+ */
+static void wnd_close(ui_window_t *window, void *arg)
+{
+	viewer_t *viewer = (viewer_t *) arg;
+
+	ui_quit(viewer->ui);
+}
+
+static void wnd_kbd_event(ui_window_t *window, void *arg,
+    kbd_event_t *event)
+{
 	bool update = false;
 
@@ -101,5 +121,5 @@
 			exit(4);
 		}
-		if (!img_setup(lsface)) {
+		if (!img_setup(window_gc, lsface)) {
 			printf("Cannot setup image \"%s\".\n", imgs[imgs_current]);
 			exit(6);
@@ -138,5 +158,5 @@
 	vfs_put(fd);
 
-	*p_local_surface = decode_tga(tga, stat.size, 0);
+	*p_local_surface = decode_tga(tga, stat.size, SURFACE_FLAG_SHARED);
 	if (*p_local_surface == NULL) {
 		free(tga);
@@ -151,20 +171,49 @@
 }
 
-static bool img_setup(surface_t *local_surface)
-{
-	if (canvas != NULL) {
-		if (!update_canvas(canvas, local_surface)) {
+static bool img_setup(gfx_context_t *gc, surface_t *local_surface)
+{
+	surface_coord_t w, h;
+	gfx_bitmap_params_t params;
+	gfx_bitmap_alloc_t alloc;
+	gfx_bitmap_t *bmp;
+	gfx_rect_t arect;
+	gfx_rect_t irect;
+	ui_resource_t *ui_res;
+	errno_t rc;
+
+	ui_res = ui_window_get_res(window);
+
+	surface_get_resolution(local_surface, &w, &h);
+	gfx_bitmap_params_init(&params);
+	params.rect.p1.x = w;
+	params.rect.p1.y = h;
+
+	ui_window_get_app_rect(window, &arect);
+	gfx_rect_translate(&arect.p0, &params.rect, &irect);
+
+	alloc.pitch = sizeof(uint32_t) * w;
+	alloc.off0 = 0;
+	alloc.pixels = surface_direct_access(local_surface);
+
+	rc = gfx_bitmap_create(gc, &params, &alloc, &bmp);
+	if (rc != EOK) {
+		surface_destroy(local_surface);
+		return false;
+	}
+
+	if (image != NULL) {
+		ui_image_set_bmp(image, bmp, &params.rect);
+		(void) ui_image_paint(image);
+		ui_image_set_rect(image, &irect);
+	} else {
+		rc = ui_image_create(ui_res, bmp, &params.rect, &image);
+		if (rc != EOK) {
+			gfx_bitmap_destroy(bmp);
 			surface_destroy(local_surface);
 			return false;
 		}
-	} else {
-		canvas = create_canvas(window_root(main_window), NULL,
-		    img_width, img_height, local_surface);
-		if (canvas == NULL) {
-			surface_destroy(local_surface);
-			return false;
-		}
-
-		sig_connect(&canvas->keyboard_event, NULL, on_keyboard_event);
+
+		ui_image_set_rect(image, &irect);
+		ui_window_add(window, ui_image_ctl(image));
 	}
 
@@ -178,15 +227,21 @@
 static void print_syntax(void)
 {
-	printf("Syntax: %s [-d <display>] <image-file>...\n", NAME);
+	printf("Syntax: %s [<options] <image-file>...\n", NAME);
+	printf("\t-d <display-spec> Use the specified display\n");
+	printf("\t-f                Full-screen mode\n");
 }
 
 int main(int argc, char *argv[])
 {
-	const char *display_svc = DISPLAY_DEFAULT;
-	window_flags_t flags;
+	const char *display_spec = DISPLAY_DEFAULT;
 	surface_t *lsface;
-	bool fullscreen;
-	sysarg_t dwidth;
-	sysarg_t dheight;
+	bool fullscreen = false;
+	gfx_rect_t rect;
+	gfx_rect_t wrect;
+	gfx_coord2_t off;
+	ui_t *ui;
+	ui_wnd_params_t params;
+	viewer_t viewer;
+	errno_t rc;
 	int i;
 
@@ -201,5 +256,7 @@
 			}
 
-			display_svc = argv[i++];
+			display_spec = argv[i++];
+		} else if (str_cmp(argv[i], "-f") == 0) {
+			fullscreen = true;
 		} else {
 			printf("Invalid option '%s'.\n", argv[i]);
@@ -219,5 +276,5 @@
 	if (imgs == NULL) {
 		printf("Out of memory.\n");
-		return 2;
+		return 1;
 	}
 
@@ -232,39 +289,58 @@
 	if (!img_load(imgs[imgs_current], &lsface)) {
 		printf("Cannot load image \"%s\".\n", imgs[imgs_current]);
-		return 4;
-	}
-
-	fullscreen = ((img_width == WINDOW_WIDTH) &&
-	    (img_height == WINDOW_HEIGHT));
-
-	flags = WINDOW_MAIN;
-	if (!fullscreen)
-		flags |= WINDOW_DECORATED;
-
-	main_window = window_open(display_svc, NULL, flags, "viewer");
-	if (!main_window) {
-		printf("Cannot open main window.\n");
-		return 5;
-	}
-
-	if (!img_setup(lsface)) {
+		return 1;
+	}
+
+	// TODO Fullscreen mode
+	if (fullscreen) {
+		printf("Fullscreen mode not implemented.\n");
+		return 1;
+	}
+
+	rc = ui_create(display_spec, &ui);
+	if (rc != EOK) {
+		printf("Error creating UI on display %s.\n", display_spec);
+		return 1;
+	}
+
+	viewer.ui = ui;
+
+	rect.p0.x = 0;
+	rect.p0.y = 0;
+	rect.p1.x = img_width;
+	rect.p1.y = img_height;
+
+	ui_wnd_params_init(&params);
+	params.caption = "Viewer";
+	/*
+	 * 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 window.\n");
+		return 1;
+	}
+
+	window_gc = ui_window_get_gc(window);
+
+	ui_window_set_cb(window, &window_cb, (void *) &viewer);
+
+	if (!img_setup(window_gc, lsface)) {
 		printf("Cannot setup image \"%s\".\n", imgs[imgs_current]);
-		return 6;
-	}
-
-	if (!fullscreen) {
-		dwidth = DECORATION_WIDTH;
-		dheight = DECORATION_HEIGHT;
-	} else {
-		dwidth = 0;
-		dheight = 0;
-	}
-
-	window_resize(main_window, 0, 0, img_width + dwidth,
-	    img_height + dheight, WINDOW_PLACEMENT_ANY);
-	window_exec(main_window);
-
-	task_retval(0);
-	async_manager();
+		return 1;
+	}
+
+	rc = ui_window_paint(window);
+	if (rc != EOK) {
+		printf("Error painting window.\n");
+		return 1;
+	}
+
+	ui_run(ui);
 
 	return 0;
