Index: uspace/srv/hid/display/window.c
===================================================================
--- uspace/srv/hid/display/window.c	(revision a40ae0d786e6716313eec18bc48f28cfe11babcf)
+++ uspace/srv/hid/display/window.c	(revision 946a6664e1498063d4e0b88a4020e290191684b2)
@@ -42,4 +42,5 @@
 #include <gfx/render.h>
 #include <io/log.h>
+#include <io/pixelmap.h>
 #include <stdlib.h>
 #include "client.h"
@@ -76,7 +77,12 @@
 {
 	ds_window_t *wnd = (ds_window_t *) arg;
+	uint16_t r, g, b;
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "gc_set_color gc=%p",
 	    ds_display_get_gc(wnd->display));
+
+	gfx_color_get_rgb_i16(color, &r, &g, &b);
+	wnd->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
+
 	return gfx_set_color(ds_display_get_gc(wnd->display), color);
 }
@@ -94,14 +100,25 @@
 	gfx_rect_t crect;
 	gfx_rect_t drect;
+	gfx_coord_t x, y;
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "gc_fill_rect");
+
 	gfx_rect_clip(rect, &wnd->rect, &crect);
 	gfx_rect_translate(&wnd->dpos, &crect, &drect);
+
+	/* Render a copy to the backbuffer */
+	for (y = crect.p0.y; y < crect.p1.y; y++) {
+		for (x = crect.p0.x; x < crect.p1.x; x++) {
+			pixelmap_put_pixel(&wnd->pixelmap, x - wnd->rect.p0.x,
+			    y - wnd->rect.p0.y, wnd->color);
+		}
+	}
+
 	return gfx_fill_rect(ds_display_get_gc(wnd->display), &drect);
 }
 
-/** Create bitmap in canvas GC.
- *
- * @param arg Canvas GC
+/** Create bitmap in window GC.
+ *
+ * @param arg Window GC
  * @param params Bitmap params
  * @param alloc Bitmap allocation info or @c NULL
@@ -135,5 +152,5 @@
 }
 
-/** Destroy bitmap in canvas GC.
+/** Destroy bitmap in window GC.
  *
  * @param bm Bitmap
@@ -149,5 +166,5 @@
 }
 
-/** Render bitmap in canvas GC.
+/** Render bitmap in window GC.
  *
  * @param bm Bitmap
@@ -165,4 +182,9 @@
 	gfx_rect_t swrect;
 	gfx_rect_t crect;
+	gfx_coord_t x, y;
+	pixelmap_t pixelmap;
+	gfx_bitmap_alloc_t alloc;
+	pixel_t pixel;
+	errno_t rc;
 
 	if (srect0 != NULL) {
@@ -190,8 +212,28 @@
 	gfx_coord2_add(&cbm->wnd->dpos, &offs, &doffs);
 
-	return gfx_bitmap_render(cbm->bitmap, srect0, &doffs);
-}
-
-/** Get allocation info for bitmap in canvas GC.
+	rc = gfx_bitmap_get_alloc(cbm->bitmap, &alloc);
+	if (rc != EOK)
+		return rc;
+
+	pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x;
+	pixelmap.height = cbm->rect.p1.y - cbm->rect.p0.y;
+	pixelmap.data = alloc.pixels;
+
+	/* Render a copy to the backbuffer */
+	for (y = crect.p0.y; y < crect.p1.y; y++) {
+		for (x = crect.p0.x; x < crect.p1.x; x++) {
+			pixel = pixelmap_get_pixel(&pixelmap,
+			    x - cbm->rect.p0.x, y - cbm->rect.p0.y);
+			pixelmap_put_pixel(&cbm->wnd->pixelmap,
+			    x + offs.x - cbm->rect.p0.x + cbm->wnd->rect.p0.x,
+			    y + offs.y - cbm->rect.p0.y + cbm->wnd->rect.p0.y,
+			    pixel);
+		}
+	}
+
+	return gfx_bitmap_render(cbm->bitmap, &crect, &doffs);
+}
+
+/** Get allocation info for bitmap in window GC.
  *
  * @param bm Bitmap
@@ -221,4 +263,9 @@
 	ds_window_t *wnd = NULL;
 	gfx_context_t *gc = NULL;
+	gfx_context_t *dgc;
+	gfx_rect_t rect;
+	gfx_coord2_t dims;
+	gfx_bitmap_params_t bparams;
+	gfx_bitmap_alloc_t alloc;
 	errno_t rc;
 
@@ -235,4 +282,29 @@
 	ds_client_add_window(client, wnd);
 	ds_display_add_window(client->display, wnd);
+
+	gfx_rect_points_sort(&params->rect, &rect);
+	gfx_coord2_subtract(&rect.p1, &rect.p0, &dims);
+
+	bparams.rect = params->rect;
+
+	dgc = ds_display_get_gc(wnd->display); // XXX
+	if (dgc != NULL) {
+		rc = gfx_bitmap_create(dgc, &bparams, NULL, &wnd->bitmap);
+		if (rc != EOK)
+			goto error;
+
+		rc = gfx_bitmap_get_alloc(wnd->bitmap, &alloc);
+		if (rc != EOK)
+			goto error;
+
+		wnd->pixelmap.width = dims.x;
+		wnd->pixelmap.height = dims.y;
+		wnd->pixelmap.data = alloc.pixels;
+	}
+
+	if (wnd->pixelmap.data == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
 
 	wnd->rect = params->rect;
@@ -241,6 +313,10 @@
 	return EOK;
 error:
-	if (wnd != NULL)
+	if (wnd != NULL) {
+		if (wnd->bitmap != NULL)
+			gfx_bitmap_destroy(wnd->bitmap);
 		free(wnd);
+	}
+
 	gfx_context_delete(gc);
 	return rc;
@@ -256,4 +332,6 @@
 	ds_display_remove_window(wnd);
 	(void) gfx_context_delete(wnd->gc);
+	if (wnd->bitmap != NULL)
+		gfx_bitmap_destroy(wnd->bitmap);
 
 	free(wnd);
@@ -268,4 +346,15 @@
 {
 	return wnd->gc;
+}
+
+/** 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);
 }
 
@@ -309,4 +398,6 @@
 	wnd->dpos = nwpos;
 	wnd->state = dsw_idle;
+
+	(void) ds_window_repaint(wnd);
 }
 
@@ -343,6 +434,6 @@
 	gc = ds_display_get_gc(wnd->display); // XXX
 	if (gc != NULL) {
-		gfx_set_color(ds_display_get_gc(wnd->display), color);
-		gfx_fill_rect(ds_display_get_gc(wnd->display), &drect);
+		gfx_set_color(gc, color);
+		gfx_fill_rect(gc, &drect);
 	}
 
