Index: uspace/app/uidemo/uidemo.c
===================================================================
--- uspace/app/uidemo/uidemo.c	(revision 4ac11fff5b1d1159c3e41e2d439af21bf785bdfe)
+++ uspace/app/uidemo/uidemo.c	(revision fa01c0532bcb8f0b3291b5a02e32606e0515492b)
@@ -33,7 +33,5 @@
  */
 
-#include <gfx/color.h>
 #include <gfx/coord.h>
-#include <gfx/render.h>
 #include <io/pos_event.h>
 #include <stdio.h>
@@ -50,8 +48,10 @@
 
 static void wnd_close(ui_window_t *, void *);
+static errno_t wnd_paint(ui_window_t *, void *);
 static void wnd_pos(ui_window_t *, void *, pos_event_t *pos);
 
 static ui_window_cb_t window_cb = {
 	.close = wnd_close,
+	.paint = wnd_paint,
 	.pos = wnd_pos
 };
@@ -73,4 +73,23 @@
 
 	ui_quit(demo->ui);
+}
+
+/** Window paint request.
+ *
+ * @param window Window
+ * @param arg Argument (demo)
+ * @return EOK on success or an error code
+ */
+static errno_t wnd_paint(ui_window_t *window, void *arg)
+{
+	ui_demo_t *demo = (ui_demo_t *) arg;
+	errno_t rc;
+
+	/* Let window paint its background */
+	rc = ui_window_def_paint(window);
+	if (rc != EOK)
+		return rc;
+
+	return ui_fixed_paint(demo->fixed);
 }
 
@@ -122,8 +141,5 @@
 	ui_demo_t demo;
 	gfx_rect_t rect;
-	gfx_rect_t app_rect;
-	gfx_color_t *color;
 	ui_resource_t *ui_res;
-	gfx_context_t *gc;
 	errno_t rc;
 
@@ -156,6 +172,4 @@
 
 	ui_res = ui_window_get_res(window);
-	gc = ui_window_get_gc(window);
-	ui_window_get_app_rect(window, &app_rect);
 
 	rc = ui_fixed_create(&demo.fixed);
@@ -226,25 +240,7 @@
 	}
 
-	rc = gfx_color_new_rgb_i16(0xc8c8, 0xc8c8, 0xc8c8, &color);
-	if (rc != EOK) {
-		printf("Error allocating color.\n");
-		return rc;
-	}
-
-	rc = gfx_set_color(gc, color);
-	if (rc != EOK) {
-		printf("Error setting color.\n");
-		return rc;
-	}
-
-	rc = gfx_fill_rect(gc, &app_rect);
-	if (rc != EOK) {
-		printf("Error filling background.\n");
-		return rc;
-	}
-
-	rc = ui_fixed_paint(demo.fixed);
-	if (rc != EOK) {
-		printf("Error painting UI controls.\n");
+	rc = ui_window_paint(window);
+	if (rc != EOK) {
+		printf("Error painting window.\n");
 		return rc;
 	}
Index: uspace/lib/ui/include/types/ui/window.h
===================================================================
--- uspace/lib/ui/include/types/ui/window.h	(revision 4ac11fff5b1d1159c3e41e2d439af21bf785bdfe)
+++ uspace/lib/ui/include/types/ui/window.h	(revision fa01c0532bcb8f0b3291b5a02e32606e0515492b)
@@ -37,4 +37,5 @@
 #define _UI_TYPES_WINDOW_H
 
+#include <errno.h>
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
@@ -56,4 +57,5 @@
 	void (*focus)(ui_window_t *, void *);
 	void (*kbd)(ui_window_t *, void *, kbd_event_t *);
+	errno_t (*paint)(ui_window_t *, void *);
 	void (*pos)(ui_window_t *, void *, pos_event_t *);
 	void (*unfocus)(ui_window_t *, void *);
Index: uspace/lib/ui/include/ui/window.h
===================================================================
--- uspace/lib/ui/include/ui/window.h	(revision 4ac11fff5b1d1159c3e41e2d439af21bf785bdfe)
+++ uspace/lib/ui/include/ui/window.h	(revision fa01c0532bcb8f0b3291b5a02e32606e0515492b)
@@ -52,4 +52,6 @@
 extern gfx_context_t *ui_window_get_gc(ui_window_t *);
 extern void ui_window_get_app_rect(ui_window_t *, gfx_rect_t *);
+extern errno_t ui_window_paint(ui_window_t *);
+extern errno_t ui_window_def_paint(ui_window_t *);
 
 #endif
Index: uspace/lib/ui/private/window.h
===================================================================
--- uspace/lib/ui/private/window.h	(revision 4ac11fff5b1d1159c3e41e2d439af21bf785bdfe)
+++ uspace/lib/ui/private/window.h	(revision fa01c0532bcb8f0b3291b5a02e32606e0515492b)
@@ -38,4 +38,5 @@
 #define _UI_PRIVATE_WINDOW_H
 
+#include <errno.h>
 #include <display.h>
 #include <gfx/context.h>
@@ -64,9 +65,10 @@
 };
 
-extern void ui_window_close(ui_window_t *);
-extern void ui_window_focus(ui_window_t *);
-extern void ui_window_kbd(ui_window_t *, kbd_event_t *);
-extern void ui_window_pos(ui_window_t *, pos_event_t *);
-extern void ui_window_unfocus(ui_window_t *);
+extern void ui_window_send_close(ui_window_t *);
+extern void ui_window_send_focus(ui_window_t *);
+extern void ui_window_send_kbd(ui_window_t *, kbd_event_t *);
+extern errno_t ui_window_send_paint(ui_window_t *);
+extern void ui_window_send_pos(ui_window_t *, pos_event_t *);
+extern void ui_window_send_unfocus(ui_window_t *);
 
 #endif
Index: uspace/lib/ui/src/window.c
===================================================================
--- uspace/lib/ui/src/window.c	(revision 4ac11fff5b1d1159c3e41e2d439af21bf785bdfe)
+++ uspace/lib/ui/src/window.c	(revision fa01c0532bcb8f0b3291b5a02e32606e0515492b)
@@ -37,4 +37,5 @@
 #include <errno.h>
 #include <gfx/context.h>
+#include <gfx/render.h>
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
@@ -45,4 +46,5 @@
 #include <ui/window.h>
 #include "../private/dummygc.h"
+#include "../private/resource.h"
 #include "../private/ui.h"
 #include "../private/wdecor.h"
@@ -205,4 +207,9 @@
 }
 
+errno_t ui_window_paint(ui_window_t *window)
+{
+	return ui_window_send_paint(window);
+}
+
 /** Handle window close event. */
 static void dwnd_close_event(void *arg)
@@ -210,5 +217,5 @@
 	ui_window_t *window = (ui_window_t *) arg;
 
-	ui_window_close(window);
+	ui_window_send_close(window);
 }
 
@@ -223,5 +230,5 @@
 	}
 
-	ui_window_focus(window);
+	ui_window_send_focus(window);
 }
 
@@ -232,5 +239,5 @@
 
 	(void) window;
-	ui_window_kbd(window, kbd_event);
+	ui_window_send_kbd(window, kbd_event);
 }
 
@@ -245,5 +252,5 @@
 
 	ui_wdecor_pos_event(window->wdecor, event);
-	ui_window_pos(window, event);
+	ui_window_send_pos(window, event);
 }
 
@@ -258,5 +265,5 @@
 	}
 
-	ui_window_unfocus(window);
+	ui_window_send_unfocus(window);
 }
 
@@ -270,5 +277,5 @@
 	ui_window_t *window = (ui_window_t *) arg;
 
-	ui_window_close(window);
+	ui_window_send_close(window);
 }
 
@@ -290,5 +297,5 @@
  * @param window Window
  */
-void ui_window_close(ui_window_t *window)
+void ui_window_send_close(ui_window_t *window)
 {
 	if (window->cb != NULL && window->cb->close != NULL)
@@ -300,5 +307,5 @@
  * @param window Window
  */
-void ui_window_focus(ui_window_t *window)
+void ui_window_send_focus(ui_window_t *window)
 {
 	if (window->cb != NULL && window->cb->focus != NULL)
@@ -310,5 +317,5 @@
  * @param window Window
  */
-void ui_window_kbd(ui_window_t *window, kbd_event_t *kbd)
+void ui_window_send_kbd(ui_window_t *window, kbd_event_t *kbd)
 {
 	if (window->cb != NULL && window->cb->kbd != NULL)
@@ -316,9 +323,21 @@
 }
 
+/** Send window paint event.
+ *
+ * @param window Window
+ */
+errno_t ui_window_send_paint(ui_window_t *window)
+{
+	if (window->cb != NULL && window->cb->paint != NULL)
+		return window->cb->paint(window, window->arg);
+	else
+		return ui_window_def_paint(window);
+}
+
 /** Send window position event.
  *
  * @param window Window
  */
-void ui_window_pos(ui_window_t *window, pos_event_t *pos)
+void ui_window_send_pos(ui_window_t *window, pos_event_t *pos)
 {
 	if (window->cb != NULL && window->cb->pos != NULL)
@@ -330,5 +349,5 @@
  * @param window Window
  */
-void ui_window_unfocus(ui_window_t *window)
+void ui_window_send_unfocus(ui_window_t *window)
 {
 	if (window->cb != NULL && window->cb->unfocus != NULL)
@@ -336,4 +355,27 @@
 }
 
+/** Default window paint routine.
+ *
+ * @param window Window
+ * @return EOK on success or an error code
+ */
+errno_t ui_window_def_paint(ui_window_t *window)
+{
+	gfx_rect_t app_rect;
+	errno_t rc;
+
+	rc = gfx_set_color(window->gc, window->res->wnd_face_color);
+	if (rc != EOK)
+		return rc;
+
+	ui_window_get_app_rect(window, &app_rect);
+
+	rc = gfx_fill_rect(window->gc, &app_rect);
+	if (rc != EOK)
+		return rc;
+
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/ui/test/window.c
===================================================================
--- uspace/lib/ui/test/window.c	(revision 4ac11fff5b1d1159c3e41e2d439af21bf785bdfe)
+++ uspace/lib/ui/test/window.c	(revision fa01c0532bcb8f0b3291b5a02e32606e0515492b)
@@ -46,4 +46,5 @@
 static void test_window_focus(ui_window_t *, void *);
 static void test_window_kbd(ui_window_t *, void *, kbd_event_t *);
+static errno_t test_window_paint(ui_window_t *, void *);
 static void test_window_pos(ui_window_t *, void *, pos_event_t *);
 static void test_window_unfocus(ui_window_t *, void *);
@@ -53,4 +54,5 @@
 	.focus = test_window_focus,
 	.kbd = test_window_kbd,
+	.paint = test_window_paint,
 	.pos = test_window_pos,
 	.unfocus = test_window_unfocus
@@ -61,8 +63,10 @@
 
 typedef struct {
+	errno_t rc;
 	bool close;
 	bool focus;
 	bool kbd;
 	kbd_event_t kbd_event;
+	bool paint;
 	bool pos;
 	pos_event_t pos_event;
@@ -131,6 +135,54 @@
 }
 
-/** ui_window_close() calls close callback set via ui_window_set_cb() */
-PCUT_TEST(close)
+/** Test ui_window_paint() */
+PCUT_TEST(paint)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	ui_window_paint(window);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** Test ui_window_def_paint() */
+PCUT_TEST(def_paint)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	ui_window_def_paint(window);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_window_send_close() calls close callback set via ui_window_set_cb() */
+PCUT_TEST(send_close)
 {
 	errno_t rc;
@@ -151,14 +203,14 @@
 
 	/* Close callback with no callbacks set */
-	ui_window_close(window);
+	ui_window_send_close(window);
 
 	/* Close callback with close callback not implemented */
 	ui_window_set_cb(window, &dummy_window_cb, NULL);
-	ui_window_close(window);
+	ui_window_send_close(window);
 
 	/* Close callback with real callback set */
 	resp.close = false;
 	ui_window_set_cb(window, &test_window_cb, &resp);
-	ui_window_close(window);
+	ui_window_send_close(window);
 	PCUT_ASSERT_TRUE(resp.close);
 
@@ -167,6 +219,6 @@
 }
 
-/** ui_window_focus() calls focus callback set via ui_window_set_cb() */
-PCUT_TEST(focus)
+/** ui_window_send_focus() calls focus callback set via ui_window_set_cb() */
+PCUT_TEST(send_focus)
 {
 	errno_t rc;
@@ -187,14 +239,14 @@
 
 	/* Focus callback with no callbacks set */
-	ui_window_focus(window);
+	ui_window_send_focus(window);
 
 	/* Focus callback with focus callback not implemented */
 	ui_window_set_cb(window, &dummy_window_cb, NULL);
-	ui_window_focus(window);
+	ui_window_send_focus(window);
 
 	/* Focus callback with real callback set */
-	resp.close = false;
-	ui_window_set_cb(window, &test_window_cb, &resp);
-	ui_window_focus(window);
+	resp.focus = false;
+	ui_window_set_cb(window, &test_window_cb, &resp);
+	ui_window_send_focus(window);
 	PCUT_ASSERT_TRUE(resp.focus);
 
@@ -203,6 +255,6 @@
 }
 
-/** ui_window_kbd() calls kbd callback set via ui_window_set_cb() */
-PCUT_TEST(kbd)
+/** ui_window_send_kbd() calls kbd callback set via ui_window_set_cb() */
+PCUT_TEST(send_kbd)
 {
 	errno_t rc;
@@ -229,14 +281,14 @@
 
 	/* Kbd callback with no callbacks set */
-	ui_window_kbd(window, &kbd_event);
+	ui_window_send_kbd(window, &kbd_event);
 
 	/* Kbd callback with kbd callback not implemented */
 	ui_window_set_cb(window, &dummy_window_cb, NULL);
-	ui_window_kbd(window, &kbd_event);
+	ui_window_send_kbd(window, &kbd_event);
 
 	/* Kbd callback with real callback set */
 	resp.kbd = false;
 	ui_window_set_cb(window, &test_window_cb, &resp);
-	ui_window_kbd(window, &kbd_event);
+	ui_window_send_kbd(window, &kbd_event);
 	PCUT_ASSERT_TRUE(resp.kbd);
 	PCUT_ASSERT_EQUALS(kbd_event.type, resp.kbd_event.type);
@@ -249,6 +301,44 @@
 }
 
-/** ui_window_pos() calls pos callback set via ui_window_set_cb() */
-PCUT_TEST(pos)
+/** ui_window_send_paint() calls paint callback set via ui_window_set_cb() */
+PCUT_TEST(send_paint)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+	test_cb_resp_t resp;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	/* Paint callback with no callbacks set */
+	ui_window_send_paint(window);
+
+	/* Paint callback with paint callback not implemented */
+	ui_window_set_cb(window, &dummy_window_cb, NULL);
+	ui_window_send_paint(window);
+
+	/* Paint callback with real callback set */
+	resp.paint = false;
+	resp.rc = EOK;
+	ui_window_set_cb(window, &test_window_cb, &resp);
+	rc = ui_window_send_paint(window);
+	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
+	PCUT_ASSERT_TRUE(resp.paint);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_window_send_pos() calls pos callback set via ui_window_set_cb() */
+PCUT_TEST(send_pos)
 {
 	errno_t rc;
@@ -276,14 +366,14 @@
 
 	/* Pos callback with no callbacks set */
-	ui_window_pos(window, &pos_event);
+	ui_window_send_pos(window, &pos_event);
 
 	/* Pos callback with pos callback not implemented */
 	ui_window_set_cb(window, &dummy_window_cb, NULL);
-	ui_window_pos(window, &pos_event);
+	ui_window_send_pos(window, &pos_event);
 
 	/* Pos callback with real callback set */
 	resp.pos = false;
 	ui_window_set_cb(window, &test_window_cb, &resp);
-	ui_window_pos(window, &pos_event);
+	ui_window_send_pos(window, &pos_event);
 	PCUT_ASSERT_TRUE(resp.pos);
 	PCUT_ASSERT_INT_EQUALS(pos_event.pos_id, resp.pos_event.pos_id);
@@ -297,6 +387,6 @@
 }
 
-/** ui_window_unfocus() calls unfocus callback set via ui_window_set_cb() */
-PCUT_TEST(unfocus)
+/** ui_window_send_unfocus() calls unfocus callback set via ui_window_set_cb() */
+PCUT_TEST(send_unfocus)
 {
 	errno_t rc;
@@ -317,14 +407,14 @@
 
 	/* Unfocus callback with no callbacks set */
-	ui_window_unfocus(window);
+	ui_window_send_unfocus(window);
 
 	/* Unfocus callback with unfocus callback not implemented */
 	ui_window_set_cb(window, &dummy_window_cb, NULL);
-	ui_window_unfocus(window);
+	ui_window_send_unfocus(window);
 
 	/* Unfocus callback with real callback set */
 	resp.close = false;
 	ui_window_set_cb(window, &test_window_cb, &resp);
-	ui_window_unfocus(window);
+	ui_window_send_unfocus(window);
 	PCUT_ASSERT_TRUE(resp.unfocus);
 
@@ -356,4 +446,12 @@
 }
 
+static errno_t test_window_paint(ui_window_t *window, void *arg)
+{
+	test_cb_resp_t *resp = (test_cb_resp_t *) arg;
+
+	resp->paint = true;
+	return resp->rc;
+}
+
 static void test_window_pos(ui_window_t *window, void *arg,
     pos_event_t *event)
