Index: uspace/srv/hid/display/cursor.c
===================================================================
--- uspace/srv/hid/display/cursor.c	(revision 2fc1e6da7733083496f42fb8293107aa6ea6a3fd)
+++ uspace/srv/hid/display/cursor.c	(revision 62018a04d41beba5b38adae3a975d48e9074fb6e)
@@ -89,7 +89,9 @@
  * @param cursor Cusor to paint
  * @param pos Position to paint at
+ * @param clip Clipping rectangle or @c NULL
  * @return EOK on success or an error code
  */
-errno_t ds_cursor_paint(ds_cursor_t *cursor, gfx_coord2_t *pos)
+errno_t ds_cursor_paint(ds_cursor_t *cursor, gfx_coord2_t *pos,
+    gfx_rect_t *clip)
 {
 	gfx_context_t *dgc;
@@ -98,4 +100,6 @@
 	gfx_bitmap_alloc_t alloc;
 	gfx_coord2_t dims;
+	gfx_rect_t sclip;
+	gfx_rect_t srect;
 	pixelmap_t pixelmap;
 	pixel_t pixel;
@@ -150,5 +154,19 @@
 	}
 
-	return gfx_bitmap_render(cursor->bitmap, NULL, pos);
+	/* Determine source rectangle */
+	if (clip == NULL) {
+		srect = cursor->rect;
+	} else {
+		gfx_rect_rtranslate(pos, clip, &sclip);
+		gfx_rect_clip(&cursor->rect, &sclip, &srect);
+	}
+
+	if (!gfx_rect_is_empty(&srect)) {
+		rc = gfx_bitmap_render(cursor->bitmap, &srect, pos);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
 error:
 	return rc;
Index: uspace/srv/hid/display/cursor.h
===================================================================
--- uspace/srv/hid/display/cursor.h	(revision 2fc1e6da7733083496f42fb8293107aa6ea6a3fd)
+++ uspace/srv/hid/display/cursor.h	(revision 62018a04d41beba5b38adae3a975d48e9074fb6e)
@@ -46,5 +46,5 @@
     ds_cursor_t **);
 extern void ds_cursor_destroy(ds_cursor_t *);
-extern errno_t ds_cursor_paint(ds_cursor_t *, gfx_coord2_t *);
+extern errno_t ds_cursor_paint(ds_cursor_t *, gfx_coord2_t *, gfx_rect_t *);
 extern void ds_cursor_get_rect(ds_cursor_t *, gfx_coord2_t *, gfx_rect_t *);
 
Index: uspace/srv/hid/display/seat.c
===================================================================
--- uspace/srv/hid/display/seat.c	(revision 2fc1e6da7733083496f42fb8293107aa6ea6a3fd)
+++ uspace/srv/hid/display/seat.c	(revision 62018a04d41beba5b38adae3a975d48e9074fb6e)
@@ -420,6 +420,5 @@
 
 	cursor = ds_seat_get_cursor(seat);
-	(void) rect; // XXX ds_cursor_paint should accept a clipping rectangle
-	return ds_cursor_paint(cursor, &seat->pntpos);
+	return ds_cursor_paint(cursor, &seat->pntpos, rect);
 }
 
Index: uspace/srv/hid/display/test/cursor.c
===================================================================
--- uspace/srv/hid/display/test/cursor.c	(revision 2fc1e6da7733083496f42fb8293107aa6ea6a3fd)
+++ uspace/srv/hid/display/test/cursor.c	(revision 62018a04d41beba5b38adae3a975d48e9074fb6e)
@@ -82,6 +82,6 @@
 }
 
-/** Test ds_cursor_paint(). */
-PCUT_TEST(cursor_paint)
+/** Test ds_cursor_paint() renders the cursor. */
+PCUT_TEST(cursor_paint_render)
 {
 	gfx_context_t *gc;
@@ -113,7 +113,57 @@
 	pos.x = 0;
 	pos.y = 0;
-	ds_cursor_paint(cursor, &pos);
+	ds_cursor_paint(cursor, &pos, NULL);
 
 	PCUT_ASSERT_TRUE(resp.render_called);
+
+	ds_cursor_destroy(cursor);
+	ds_display_destroy(disp);
+}
+
+/** Test ds_cursor_paint() optimizes out rendering using clipping rectangle. */
+PCUT_TEST(cursor_paint_norender)
+{
+	gfx_context_t *gc;
+	ds_display_t *disp;
+	ds_cursor_t *cursor;
+	ds_ddev_t *ddev;
+	ddev_info_t ddinfo;
+	gfx_coord2_t pos;
+	gfx_rect_t clip;
+	test_response_t resp;
+	errno_t rc;
+
+	rc = gfx_context_new(&dummy_ops, &resp, &gc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_display_create(gc, df_none, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ddev_info_init(&ddinfo);
+
+	rc = ds_ddev_create(disp, NULL, &ddinfo, NULL, 0, gc, &ddev);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_cursor_create(disp, &ds_cursimg[dcurs_arrow].rect,
+	    ds_cursimg[dcurs_arrow].image, &cursor);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	resp.render_called = false;
+
+	/*
+	 * Clipping rectangle not intersecting the area where cursor is to
+	 * be rendered
+	 */
+	clip.p0.x = 100;
+	clip.p0.y = 100;
+	clip.p1.x = 150;
+	clip.p1.y = 150;
+
+	pos.x = 0;
+	pos.y = 0;
+	ds_cursor_paint(cursor, &pos, &clip);
+
+	/* Rendering should have been optimized out */
+	PCUT_ASSERT_FALSE(resp.render_called);
 
 	ds_cursor_destroy(cursor);
