Index: uspace/app/bdsh/input.c
===================================================================
--- uspace/app/bdsh/input.c	(revision f73b2913a9facbac5079836f6c5bee2148010a56)
+++ uspace/app/bdsh/input.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -268,4 +268,5 @@
 	if (rc != EOK) {
 		/* Error in communication with console */
+		cli_quit = 1;
 		return;
 	}
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision f73b2913a9facbac5079836f6c5bee2148010a56)
+++ uspace/app/init/init.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -37,4 +37,5 @@
 #include <stdio.h>
 #include <unistd.h>
+#include <stdarg.h>
 #include <vfs/vfs.h>
 #include <bool.h>
@@ -65,4 +66,13 @@
 #define SRV_CONSOLE  "/srv/console"
 #define APP_GETTERM  "/app/getterm"
+
+#define SRV_COMPOSITOR  "/srv/compositor"
+
+#define HID_INPUT              "hid/input"
+#define HID_OUTPUT             "hid/output"
+#define HID_COMPOSITOR_SERVER  ":0"
+
+#define srv_start(path, ...) \
+	srv_startl(path, path, ##__VA_ARGS__, NULL)
 
 /** Print banner */
@@ -143,61 +153,66 @@
 }
 
-static void spawn(const char *fname)
-{
-	int rc;
+static int srv_startl(const char *path, ...)
+{
 	struct stat s;
-	
-	if (stat(fname, &s) == ENOENT)
-		return;
-	
-	printf("%s: Spawning %s\n", NAME, fname);
-	rc = task_spawnl(NULL, fname, fname, NULL);
-	if (rc != EOK) {
-		printf("%s: Error spawning %s (%s)\n", NAME, fname,
-		    str_error(rc));
-	}
-}
-
-static void srv_start(const char *fname)
-{
+	if (stat(path, &s) == ENOENT) {
+		printf("%s: Unable to stat %s\n", NAME, path);
+		return ENOENT;
+	}
+	
+	printf("%s: Starting %s\n", NAME, path);
+	
+	va_list ap;
+	const char *arg;
+	int cnt = 0;
+	
+	va_start(ap, path);
+	do {
+		arg = va_arg(ap, const char *);
+		cnt++;
+	} while (arg != NULL);
+	va_end(ap);
+	
+	va_start(ap, path);
 	task_id_t id;
+	int rc = task_spawn(&id, path, cnt, ap);
+	va_end(ap);
+	
+	if (rc != EOK) {
+		printf("%s: Error spawning %s (%s)\n", NAME, path,
+		    str_error(rc));
+		return rc;
+	}
+	
+	if (!id) {
+		printf("%s: Error spawning %s (invalid task id)\n", NAME,
+		    path);
+		return EINVAL;
+	}
+	
 	task_exit_t texit;
-	int rc, retval;
-	struct stat s;
-	
-	if (stat(fname, &s) == ENOENT)
-		return;
-	
-	printf("%s: Starting %s\n", NAME, fname);
-	rc = task_spawnl(&id, fname, fname, NULL);
-	if (!id) {
-		printf("%s: Error spawning %s (%s)\n", NAME, fname,
-		    str_error(rc));
-		return;
-	}
-	
+	int retval;
 	rc = task_wait(id, &texit, &retval);
 	if (rc != EOK) {
-		printf("%s: Error waiting for %s (%s)\n", NAME, fname,
-		    str_error(rc));
-		return;
+		printf("%s: Error waiting for %s (%s)\n", NAME, path,
+		    str_error(rc));
+		return rc;
 	}
 	
 	if (texit != TASK_EXIT_NORMAL) {
 		printf("%s: Server %s failed to start (unexpectedly "
-		    "terminated)\n", NAME, fname);
-		return;
-	}
-
-	if (retval != 0) {
+		    "terminated)\n", NAME, path);
+		return EINVAL;
+	}
+	
+	if (retval != 0)
 		printf("%s: Server %s failed to start (exit code %d)\n", NAME,
-			fname, retval);
-	}
-}
-
-static void console(const char *isvc, const char *fbsvc)
-{
-	printf("%s: Spawning %s %s %s\n", NAME, SRV_CONSOLE, isvc, fbsvc);
-	
+		    path, retval);
+	
+	return retval;
+}
+
+static int console(const char *isvc, const char *osvc)
+{
 	/* Wait for the input service to be ready */
 	service_id_t service_id;
@@ -206,20 +221,57 @@
 		printf("%s: Error waiting on %s (%s)\n", NAME, isvc,
 		    str_error(rc));
-		return;
-	}
-	
-	/* Wait for the framebuffer service to be ready */
-	rc = loc_service_get_id(fbsvc, &service_id, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		printf("%s: Error waiting on %s (%s)\n", NAME, fbsvc,
-		    str_error(rc));
-		return;
-	}
-	
-	rc = task_spawnl(NULL, SRV_CONSOLE, SRV_CONSOLE, isvc, fbsvc, NULL);
-	if (rc != EOK) {
-		printf("%s: Error spawning %s %s %s (%s)\n", NAME, SRV_CONSOLE,
-		    isvc, fbsvc, str_error(rc));
-	}
+		return rc;
+	}
+	
+	/* Wait for the output service to be ready */
+	rc = loc_service_get_id(osvc, &service_id, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Error waiting on %s (%s)\n", NAME, osvc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	return srv_start(SRV_CONSOLE, isvc, osvc);
+}
+
+static int compositor(const char *isvc, const char *name)
+{
+	/* Wait for the input service to be ready */
+	service_id_t service_id;
+	int rc = loc_service_get_id(isvc, &service_id, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Error waiting on %s (%s)\n", NAME, isvc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	return srv_start(SRV_COMPOSITOR, isvc, name);
+}
+
+static int gui_start(const char *app, const char *srv_name)
+{
+	char winreg[50];
+	snprintf(winreg, sizeof(winreg), "%s%s%s", "comp", srv_name, "/winreg");
+	
+	printf("%s: Spawning %s %s\n", NAME, app, winreg);
+	
+	task_id_t id;
+	int rc = task_spawnl(&id, app, app, winreg, NULL);
+	if (rc != EOK) {
+		printf("%s: Error spawning %s %s (%s)\n", NAME, app,
+		    winreg, str_error(rc));
+		return -1;
+	}
+	
+	task_exit_t texit;
+	int retval;
+	rc = task_wait(id, &texit, &retval);
+	if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
+		printf("%s: Error retrieving retval from %s (%s)\n", NAME,
+		    app, str_error(rc));
+		return -1;
+	}
+	
+	return retval;
 }
 
@@ -227,6 +279,4 @@
 {
 	char term[LOC_NAME_MAXLEN];
-	int rc;
-	
 	snprintf(term, LOC_NAME_MAXLEN, "%s/%s", LOCFS_MOUNT_POINT, svc);
 	
@@ -235,5 +285,5 @@
 	/* Wait for the terminal service to be ready */
 	service_id_t service_id;
-	rc = loc_service_get_id(svc, &service_id, IPC_FLAG_BLOCKING);
+	int rc = loc_service_get_id(svc, &service_id, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
 		printf("%s: Error waiting on %s (%s)\n", NAME, term,
@@ -279,42 +329,37 @@
 	if (!mount_root(STRING(RDFMT))) {
 		printf("%s: Exiting\n", NAME);
-		return -1;
+		return 1;
 	}
 	
 	/* Make sure tmpfs is running. */
-	if (str_cmp(STRING(RDFMT), "tmpfs") != 0) {
-		spawn("/srv/tmpfs");
-	}
-	
-	spawn("/srv/locfs");
-	spawn("/srv/taskmon");
+	if (str_cmp(STRING(RDFMT), "tmpfs") != 0)
+		srv_start("/srv/tmpfs");
+	
+	srv_start("/srv/locfs");
+	srv_start("/srv/taskmon");
 	
 	if (!mount_locfs()) {
 		printf("%s: Exiting\n", NAME);
-		return -2;
+		return 2;
 	}
 	
 	mount_tmpfs();
 	
-	spawn("/srv/devman");
-	spawn("/srv/apic");
-	spawn("/srv/i8259");
-	spawn("/srv/obio");
+	srv_start("/srv/devman");
+	srv_start("/srv/apic");
+	srv_start("/srv/i8259");
+	srv_start("/srv/obio");
 	srv_start("/srv/cuda_adb");
 	srv_start("/srv/s3c24xx_uart");
 	srv_start("/srv/s3c24xx_ts");
 	
-	spawn("/srv/loopip");
-	spawn("/srv/ethip");
-	spawn("/srv/inetsrv");
-	spawn("/srv/tcp");
-	spawn("/srv/udp");
-	
-	spawn("/srv/fb");
-	spawn("/srv/input");
-	console("hid/input", "hid/fb0");
-	
-	spawn("/srv/clipboard");
-	spawn("/srv/remcons");
+	srv_start("/srv/loopip");
+	srv_start("/srv/ethip");
+	srv_start("/srv/inetsrv");
+	srv_start("/srv/tcp");
+	srv_start("/srv/udp");
+	
+	srv_start("/srv/clipboard");
+	srv_start("/srv/remcons");
 	
 	/*
@@ -325,13 +370,11 @@
 	srv_start("/srv/ata_bd");
 	srv_start("/srv/gxe_bd");
-#else
-	(void) srv_start;
 #endif
 	
 #ifdef CONFIG_MOUNT_DATA
 	/* Make sure fat is running. */
-	if (str_cmp(STRING(RDFMT), "fat") != 0) {
+	if (str_cmp(STRING(RDFMT), "fat") != 0)
 		srv_start("/srv/fat");
-	}
+	
 	mount_data();
 #else
@@ -339,11 +382,23 @@
 #endif
 	
-	getterm("term/vc0", "/app/bdsh", true);
-	getterm("term/vc1", "/app/bdsh", false);
-	getterm("term/vc2", "/app/bdsh", false);
-	getterm("term/vc3", "/app/bdsh", false);
-	getterm("term/vc4", "/app/bdsh", false);
-	getterm("term/vc5", "/app/bdsh", false);
-	getterm("term/vc6", "/app/klog", false);
+	srv_start("/srv/input", HID_INPUT);
+	srv_start("/srv/output", HID_OUTPUT);
+	
+	int rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
+	if (rc == EOK) {
+		gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
+		gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
+	} else {
+		rc = console(HID_INPUT, HID_OUTPUT);
+		if (rc == EOK) {
+			getterm("term/vc0", "/app/bdsh", true);
+			getterm("term/vc1", "/app/bdsh", false);
+			getterm("term/vc2", "/app/bdsh", false);
+			getterm("term/vc3", "/app/bdsh", false);
+			getterm("term/vc4", "/app/bdsh", false);
+			getterm("term/vc5", "/app/bdsh", false);
+			getterm("term/vc6", "/app/klog", false);
+		}
+	}
 	
 	return 0;
Index: uspace/app/vdemo/Makefile
===================================================================
--- uspace/app/vdemo/Makefile	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
+++ uspace/app/vdemo/Makefile	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2012 Petr Koupy
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBGUI_PREFIX)/libgui.a $(LIBDRAW_PREFIX)/libdraw.a \
+	$(LIBSOFTREND_PREFIX)/libsoftrend.a
+EXTRA_CFLAGS += -I$(LIBGUI_PREFIX) -I$(LIBDRAW_PREFIX) \
+	-I$(LIBSOFTREND_PREFIX)
+BINARY = vdemo
+
+SOURCES = \
+	vdemo.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/vdemo/vdemo.c
===================================================================
--- uspace/app/vdemo/vdemo.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
+++ uspace/app/vdemo/vdemo.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2012 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup vdemo
+ * @{
+ */
+/** @file
+ */
+
+#include <bool.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <io/pixel.h>
+#include <task.h>
+
+#include <window.h>
+#include <grid.h>
+#include <button.h>
+#include <label.h>
+
+#define NAME "vdemo"
+
+typedef struct my_label {
+	label_t label;
+	slot_t confirm;
+	slot_t cancel;
+} my_label_t;
+
+static void deinit_my_label(my_label_t *lbl)
+{
+	deinit_label(&lbl->label);
+}
+
+static void my_label_destroy(widget_t *widget)
+{
+	my_label_t *lbl = (my_label_t *) widget;
+
+	deinit_my_label(lbl);
+
+	free(lbl);
+}
+
+static void on_confirm(widget_t *widget, void *data)
+{
+	my_label_t *lbl = (my_label_t *) widget;
+	const char *confirmed = "Confirmed";
+	lbl->label.rewrite(&lbl->label.widget, (void *) confirmed);
+}
+
+static void on_cancel(widget_t *widget, void *data)
+{
+	my_label_t *lbl = (my_label_t *) widget;
+	const char *cancelled = "Cancelled";
+	lbl->label.rewrite(&lbl->label.widget, (void *) cancelled);
+}
+
+static bool init_my_label(my_label_t *lbl, widget_t *parent,
+    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+{
+	lbl->confirm = on_confirm;
+	lbl->cancel = on_cancel;
+	bool initialized = init_label(
+	    &lbl->label, parent, caption, points, background, foreground);
+	lbl->label.widget.destroy = my_label_destroy;
+	return initialized;
+}
+
+static my_label_t *create_my_label(widget_t *parent,
+    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+{
+	my_label_t *lbl = (my_label_t *) malloc(sizeof(my_label_t));
+	if (!lbl) {
+		return NULL;
+	}
+
+	if (init_my_label(lbl, parent, caption, points, background, foreground)) {
+		return lbl;
+	} else {
+		free(lbl);
+		return NULL;
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc >= 2) {
+		window_t *main_window = window_open(argv[1], true, true, "vdemo");
+		if (!main_window) {
+			printf("Cannot open main window.\n");
+			return 1;
+		}
+
+		pixel_t grd_bg = PIXEL(255, 240, 240, 240);
+		pixel_t btn_bg = PIXEL(255, 0, 0, 0);
+		pixel_t btn_fg = PIXEL(255, 240, 240, 240);
+		pixel_t lbl_bg = PIXEL(255, 240, 240, 240);
+		pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
+
+		my_label_t *lbl_action = create_my_label(NULL, "Hello there!", 16, lbl_bg, lbl_fg);
+		button_t *btn_confirm = create_button(NULL, "Confirm", 16, btn_bg, btn_fg);
+		button_t *btn_cancel = create_button(NULL, "Cancel", 16, btn_bg, btn_fg);
+		grid_t *grid = create_grid(window_root(main_window), 2, 2, grd_bg);
+		if (!lbl_action || !btn_confirm || !btn_cancel || !grid) {
+			window_close(main_window);
+			printf("Cannot create widgets.\n");
+			return 1;
+		}
+
+		sig_connect(
+		    &btn_confirm->clicked,
+		    &lbl_action->label.widget,
+		    lbl_action->confirm);
+		sig_connect(
+		    &btn_cancel->clicked,
+		    &lbl_action->label.widget,
+		    lbl_action->cancel);
+
+		grid->add(grid, &lbl_action->label.widget, 0, 0, 1, 2);
+		grid->add(grid, &btn_confirm->widget, 1, 0, 1, 1);
+		grid->add(grid, &btn_cancel->widget, 1, 1, 1, 1);
+		window_resize(main_window, 200, 70);
+
+		window_exec(main_window);
+		task_retval(0);
+		async_manager();
+		return 1;
+	} else {
+		printf("Compositor server not specified.\n");
+		return 1;
+	}
+}
+
+/** @}
+ */
Index: uspace/app/vlaunch/Makefile
===================================================================
--- uspace/app/vlaunch/Makefile	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
+++ uspace/app/vlaunch/Makefile	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2012 Petr Koupy
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBGUI_PREFIX)/libgui.a $(LIBDRAW_PREFIX)/libdraw.a \
+	$(LIBSOFTREND_PREFIX)/libsoftrend.a
+EXTRA_CFLAGS += -I$(LIBGUI_PREFIX) -I$(LIBDRAW_PREFIX) \
+	-I$(LIBSOFTREND_PREFIX)
+BINARY = vlaunch
+
+SOURCES = \
+	vlaunch.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
+++ uspace/app/vlaunch/vlaunch.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2012 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup vlaunch
+ * @{
+ */
+/** @file
+ */
+
+#include <bool.h>
+#include <errno.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <io/pixel.h>
+#include <task.h>
+#include <str.h>
+#include <str_error.h>
+
+#include <window.h>
+#include <grid.h>
+#include <button.h>
+#include <label.h>
+
+#define NAME "vlaunch"
+
+static char *winreg = NULL;
+
+static int app_launch(const char *app)
+{
+	int rc;
+	printf("%s: Spawning %s %s \n", NAME, app, winreg);
+
+	task_id_t id;
+	task_exit_t texit;
+	int retval;
+	rc = task_spawnl(&id, app, app, winreg, NULL);
+	if (rc != EOK) {
+		printf("%s: Error spawning %s %s (%s)\n", NAME, app,
+		    winreg, str_error(rc));
+		return -1;
+	}
+	rc = task_wait(id, &texit, &retval);
+	if (rc != EOK || texit != TASK_EXIT_NORMAL) {
+		printf("%s: Error retrieving retval from %s (%s)\n", NAME,
+		    app, str_error(rc));
+		return -1;
+	}
+
+	return retval;
+}
+
+static void on_vterm(widget_t *widget, void *data)
+{
+	app_launch("/app/vterm");
+}
+
+static void on_vdemo(widget_t *widget, void *data)
+{
+	app_launch("/app/vdemo");
+}
+
+static void on_vlaunch(widget_t *widget, void *data)
+{
+	app_launch("/app/vlaunch");
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc >= 2) {
+		winreg = argv[1];
+		window_t *main_window = window_open(argv[1], true, true, "vlaunch");
+		if (!main_window) {
+			printf("Cannot open main window.\n");
+			return 1;
+		}
+
+		pixel_t grd_bg = PIXEL(255, 240, 240, 240);
+		pixel_t btn_bg = PIXEL(255, 0, 0, 0);
+		pixel_t btn_fg = PIXEL(255, 240, 240, 240);
+		pixel_t lbl_bg = PIXEL(255, 240, 240, 240);
+		pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
+
+		label_t *lbl_caption = create_label(NULL, "Launch application:", 16, lbl_bg, lbl_fg);
+		button_t *btn_vterm = create_button(NULL, "vterm", 16, btn_bg, btn_fg);
+		button_t *btn_vdemo = create_button(NULL, "vdemo", 16, btn_bg, btn_fg);
+		button_t *btn_vlaunch = create_button(NULL, "vlaunch", 16, btn_bg, btn_fg);
+		grid_t *grid = create_grid(window_root(main_window), 4, 1, grd_bg);
+		if (!lbl_caption || !btn_vterm || !btn_vdemo || !btn_vlaunch || !grid) {
+			window_close(main_window);
+			printf("Cannot create widgets.\n");
+			return 1;
+		}
+
+		sig_connect(
+		    &btn_vterm->clicked,
+		    NULL,
+		    on_vterm);
+		sig_connect(
+		    &btn_vdemo->clicked,
+		    NULL,
+		    on_vdemo);
+		sig_connect(
+		    &btn_vlaunch->clicked,
+		    NULL,
+		    on_vlaunch);
+
+		grid->add(grid, &lbl_caption->widget, 0, 0, 1, 1);
+		grid->add(grid, &btn_vterm->widget, 1, 0, 1, 1);
+		grid->add(grid, &btn_vdemo->widget, 2, 0, 1, 1);
+		grid->add(grid, &btn_vlaunch->widget, 3, 0, 1, 1);
+		window_resize(main_window, 180, 130);
+
+		window_exec(main_window);
+		task_retval(0);
+		async_manager();
+		return 1;
+	} else {
+		printf("Compositor server not specified.\n");
+		return 1;
+	}
+}
+
+/** @}
+ */
Index: uspace/app/vterm/Makefile
===================================================================
--- uspace/app/vterm/Makefile	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
+++ uspace/app/vterm/Makefile	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2012 Petr Koupy
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBGUI_PREFIX)/libgui.a $(LIBDRAW_PREFIX)/libdraw.a \
+	$(LIBSOFTREND_PREFIX)/libsoftrend.a $(LIBGRAPH_PREFIX)/libgraph.a
+EXTRA_CFLAGS += -I$(LIBGUI_PREFIX) -I$(LIBDRAW_PREFIX) \
+	-I$(LIBSOFTREND_PREFIX) -I$(LIBGRAPH_PREFIX)
+BINARY = vterm
+
+SOURCES = \
+	vterm.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/vterm/vterm.c
===================================================================
--- uspace/app/vterm/vterm.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
+++ uspace/app/vterm/vterm.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup vterm
+ * @{
+ */
+/** @file
+ */
+
+#include <bool.h>
+#include <stdio.h>
+#include <io/pixel.h>
+#include <task.h>
+#include <window.h>
+#include <terminal.h>
+
+#define NAME  "vterm"
+
+int main(int argc, char *argv[])
+{
+	if (argc < 2) {
+		printf("%s: Compositor server not specified.\n", NAME);
+		return 1;
+	}
+	
+	window_t *main_window = window_open(argv[1], true, true, "vterm");
+	if (!main_window) {
+		printf("%s: Cannot open main window.\n", NAME);
+		return 2;
+	}
+	
+	window_resize(main_window, 650, 510);
+	terminal_t *terminal_widget =
+	    create_terminal(window_root(main_window), 640, 480);
+	if (!terminal_widget) {
+		window_close(main_window);
+		printf("%s: Cannot create widgets.\n", NAME);
+		return 3;
+	}
+	
+	window_exec(main_window);
+	task_retval(0);
+	async_manager();
+	
+	return 0;
+}
+
+/** @}
+ */
