Index: uspace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision c79545edbb52f9f5ef2247e219415bf2a71c3b5d)
+++ uspace/srv/hid/display/display.c	(revision 2012fe01183718ce4b9d44a0227c8401a0a15ae3)
@@ -236,4 +236,19 @@
 }
 
+/** Get last window in display.
+ *
+ * @param display Display
+ * @return Last window or @c NULL if there is none
+ */
+ds_window_t *ds_display_last_window(ds_display_t *display)
+{
+	link_t *link = list_last(&display->windows);
+
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, ds_window_t, ldwindows);
+}
+
 /** Get next window in client.
  *
@@ -244,4 +259,19 @@
 {
 	link_t *link = list_next(&wnd->ldwindows, &wnd->display->windows);
+
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, ds_window_t, ldwindows);
+}
+
+/** Get previous window in client.
+ *
+ * @param wnd Current window
+ * @return Previous window or @c NULL if there is none
+ */
+ds_window_t *ds_display_prev_window(ds_window_t *wnd)
+{
+	link_t *link = list_prev(&wnd->ldwindows, &wnd->display->windows);
 
 	if (link == NULL)
@@ -441,4 +471,32 @@
 }
 
+/** Paint display.
+ *
+ * @param display Display
+ * @param rect Bounding rectangle or @c NULL to repaint entire display
+ */
+errno_t ds_display_paint(ds_display_t *disp, gfx_rect_t *rect)
+{
+	errno_t rc;
+	ds_window_t *wnd;
+
+	/* Paint background */
+	rc = ds_display_paint_bg(disp, rect);
+	if (rc != EOK)
+		return rc;
+
+	/* Paint windows bottom to top */
+	wnd = ds_display_last_window(disp);
+	while (wnd != NULL) {
+		rc = ds_window_paint(wnd, rect);
+		if (rc != EOK)
+			return rc;
+
+		wnd = ds_display_prev_window(wnd);
+	}
+
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/srv/hid/display/display.h
===================================================================
--- uspace/srv/hid/display/display.h	(revision c79545edbb52f9f5ef2247e219415bf2a71c3b5d)
+++ uspace/srv/hid/display/display.h	(revision 2012fe01183718ce4b9d44a0227c8401a0a15ae3)
@@ -58,5 +58,7 @@
 extern void ds_display_remove_window(ds_window_t *);
 extern ds_window_t *ds_display_first_window(ds_display_t *);
+extern ds_window_t *ds_display_last_window(ds_display_t *);
 extern ds_window_t *ds_display_next_window(ds_window_t *);
+extern ds_window_t *ds_display_prev_window(ds_window_t *);
 extern errno_t ds_display_post_kbd_event(ds_display_t *, kbd_event_t *);
 extern errno_t ds_display_post_ptd_event(ds_display_t *, ptd_event_t *);
@@ -71,4 +73,5 @@
 extern gfx_context_t *ds_display_get_gc(ds_display_t *);
 extern errno_t ds_display_paint_bg(ds_display_t *, gfx_rect_t *);
+extern errno_t ds_display_paint(ds_display_t *, gfx_rect_t *);
 
 #endif
Index: uspace/srv/hid/display/test/display.c
===================================================================
--- uspace/srv/hid/display/test/display.c	(revision c79545edbb52f9f5ef2247e219415bf2a71c3b5d)
+++ uspace/srv/hid/display/test/display.c	(revision 2012fe01183718ce4b9d44a0227c8401a0a15ae3)
@@ -128,4 +128,13 @@
 	PCUT_ASSERT_NULL(wnd);
 
+	wnd = ds_display_last_window(disp);
+	PCUT_ASSERT_EQUALS(w1, wnd);
+
+	wnd = ds_display_prev_window(wnd);
+	PCUT_ASSERT_EQUALS(w0, wnd);
+
+	wnd = ds_display_prev_window(wnd);
+	PCUT_ASSERT_NULL(wnd);
+
 	wnd = ds_display_find_window(disp, w0->id);
 	PCUT_ASSERT_EQUALS(w0, wnd);
Index: uspace/srv/hid/display/window.c
===================================================================
--- uspace/srv/hid/display/window.c	(revision c79545edbb52f9f5ef2247e219415bf2a71c3b5d)
+++ uspace/srv/hid/display/window.c	(revision 2012fe01183718ce4b9d44a0227c8401a0a15ae3)
@@ -348,13 +348,32 @@
 }
 
-/** Repaint a window using its backing bitmap.
- *
- * @param wnd Window to repaint
- * @return EOK on success or an error code
- */
-static errno_t ds_window_repaint(ds_window_t *wnd)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_repaint");
-	return gfx_bitmap_render(wnd->bitmap, NULL, &wnd->dpos);
+/** Paint a window using its backing bitmap.
+ *
+ * @param wnd Window to paint
+ * @param rect Display rectangle to paint to
+ * @return EOK on success or an error code
+ */
+errno_t ds_window_paint(ds_window_t *wnd, gfx_rect_t *rect)
+{
+	gfx_rect_t srect;
+	gfx_rect_t *brect;
+	gfx_rect_t crect;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
+
+	if (rect != NULL) {
+		gfx_rect_rtranslate(&wnd->dpos, rect, &srect);
+
+		/* Determine if we have anything to do */
+		gfx_rect_clip(&srect, rect, &crect);
+		if (gfx_rect_is_empty(&crect))
+			return EOK;
+
+		brect = &srect;
+	} else {
+		brect = NULL;
+	}
+
+	return gfx_bitmap_render(wnd->bitmap, brect, &wnd->dpos);
 }
 
@@ -399,5 +418,5 @@
 	wnd->state = dsw_idle;
 
-	(void) ds_window_repaint(wnd);
+	(void) ds_display_paint(wnd->display, NULL);
 }
 
Index: uspace/srv/hid/display/window.h
===================================================================
--- uspace/srv/hid/display/window.h	(revision c79545edbb52f9f5ef2247e219415bf2a71c3b5d)
+++ uspace/srv/hid/display/window.h	(revision 2012fe01183718ce4b9d44a0227c8401a0a15ae3)
@@ -40,4 +40,5 @@
 #include <io/pos_event.h>
 #include <types/gfx/context.h>
+#include <types/gfx/coord.h>
 #include <types/gfx/ops/context.h>
 #include "types/display/display.h"
@@ -51,4 +52,5 @@
 extern void ds_window_destroy(ds_window_t *);
 extern gfx_context_t *ds_window_get_ctx(ds_window_t *);
+extern errno_t ds_window_paint(ds_window_t *, gfx_rect_t *);
 extern errno_t ds_window_post_pos_event(ds_window_t *, pos_event_t *);
 
