Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c	(revision de9992c5dcfe392011d18f6d641c7151c514607a)
@@ -383,5 +383,5 @@
 
 	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize)) != 0)
 		return ENOTSUP;
 
@@ -392,4 +392,5 @@
 	gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
 	dcbm->rect = params->rect;
+	dcbm->flags = params->flags;
 
 	if (alloc == NULL) {
@@ -487,13 +488,44 @@
 	gfx_rect_clip(&srect, &skfbrect, &crect);
 
-	// XXX bmpf_color_key
-	for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
-		for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
-			gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
-			gfx_coord2_add(&pos, &offs, &dp);
-
-			color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
-			dispc->active_fb.pixel2visual(dispc->fb_data +
-			    FB_POS(dispc, dp.x, dp.y), color);
+	if ((dcbm->flags & bmpf_color_key) == 0) {
+		/* Simple copy */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				dispc->active_fb.pixel2visual(dispc->fb_data +
+				    FB_POS(dispc, dp.x, dp.y), color);
+			}
+		}
+	} else if ((dcbm->flags & bmpf_colorize) == 0) {
+		/* Color key */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				if (color != dcbm->key_color) {
+					dispc->active_fb.pixel2visual(dispc->fb_data +
+					    FB_POS(dispc, dp.x, dp.y), color);
+				}
+			}
+		}
+	} else {
+		/* Color key & colorize */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				if (color != dcbm->key_color) {
+					dispc->active_fb.pixel2visual(dispc->fb_data +
+					    FB_POS(dispc, dp.x, dp.y),
+					    dcbm->dispc->color);
+				}
+			}
 		}
 	}
Index: uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h
===================================================================
--- uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h	(revision de9992c5dcfe392011d18f6d641c7151c514607a)
@@ -68,8 +68,16 @@
 
 typedef struct {
+	/* Containing display controller */
 	amdm37x_dispc_t *dispc;
+	/** Allocation info */
 	gfx_bitmap_alloc_t alloc;
+	/** @c true if we allocated the bitmap, @c false if allocated by caller */
+	bool myalloc;
+	/** Rectangle covered by bitmap */
 	gfx_rect_t rect;
-	bool myalloc;
+	/** Bitmap flags */
+	gfx_bitmap_flags_t flags;
+	/** Key color */
+	pixel_t key_color;
 } amdm37x_bitmap_t;
 
Index: uspace/drv/fb/kfb/port.c
===================================================================
--- uspace/drv/fb/kfb/port.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ uspace/drv/fb/kfb/port.c	(revision de9992c5dcfe392011d18f6d641c7151c514607a)
@@ -200,5 +200,5 @@
 
 	/* Check that we support all required flags */
-	if ((params->flags & ~bmpf_color_key) != 0)
+	if ((params->flags & ~(bmpf_color_key | bmpf_colorize)) != 0)
 		return ENOTSUP;
 
@@ -307,4 +307,5 @@
 
 	if ((kfbbm->flags & bmpf_color_key) != 0) {
+		/* Simple copy */
 		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
 			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
@@ -319,5 +320,18 @@
 			}
 		}
+	} else if ((kfbbm->flags & bmpf_colorize) != 0) {
+		/* Color key */
+		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
+			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
+				gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
+				gfx_coord2_add(&pos, &offs, &dp);
+
+				color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
+				kfb->pixel2visual(kfb->addr +
+				    FB_POS(kfb, dp.x, dp.y), color);
+			}
+		}
 	} else {
+		/* Color key & colorize */
 		for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
 			for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
