Index: uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h
===================================================================
--- uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
+++ uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h	(revision ec7902df3bea37028cfd215b507c5248f4e054dd)
@@ -39,5 +39,7 @@
 
 typedef enum {
-	GC_SET_RGB_COLOR = IPC_FIRST_USER_METHOD,
+	GC_SET_CLIP_RECT = IPC_FIRST_USER_METHOD,
+	GC_SET_CLIP_RECT_NULL,
+	GC_SET_RGB_COLOR,
 	GC_FILL_RECT,
 	GC_UPDATE,
Index: uspace/lib/ipcgfx/src/client.c
===================================================================
--- uspace/lib/ipcgfx/src/client.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
+++ uspace/lib/ipcgfx/src/client.c	(revision ec7902df3bea37028cfd215b507c5248f4e054dd)
@@ -45,4 +45,5 @@
 #include "../private/client.h"
 
+static errno_t ipc_gc_set_clip_rect(void *, gfx_rect_t *);
 static errno_t ipc_gc_set_color(void *, gfx_color_t *);
 static errno_t ipc_gc_fill_rect(void *, gfx_rect_t *);
@@ -55,4 +56,5 @@
 
 gfx_context_ops_t ipc_gc_ops = {
+	.set_clip_rect = ipc_gc_set_clip_rect,
 	.set_color = ipc_gc_set_color,
 	.fill_rect = ipc_gc_fill_rect,
@@ -63,4 +65,30 @@
 	.bitmap_get_alloc = ipc_gc_bitmap_get_alloc
 };
+
+/** Set clipping rectangle on IPC GC.
+ *
+ * @param arg IPC GC
+ * @param rect Rectangle
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t ipc_gc_set_clip_rect(void *arg, gfx_rect_t *rect)
+{
+	ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
+	async_exch_t *exch;
+	errno_t rc;
+
+	exch = async_exchange_begin(ipcgc->sess);
+	if (rect != NULL) {
+		rc = async_req_4_0(exch, GC_SET_CLIP_RECT, rect->p0.x, rect->p0.y,
+		    rect->p1.x, rect->p1.y);
+	} else {
+		rc = async_req_0_0(exch, GC_SET_CLIP_RECT_NULL);
+	}
+
+	async_exchange_end(exch);
+
+	return rc;
+}
 
 /** Set color on IPC GC.
Index: uspace/lib/ipcgfx/src/server.c
===================================================================
--- uspace/lib/ipcgfx/src/server.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
+++ uspace/lib/ipcgfx/src/server.c	(revision ec7902df3bea37028cfd215b507c5248f4e054dd)
@@ -52,4 +52,26 @@
 static ipc_gc_srv_bitmap_t *gc_bitmap_lookup(ipc_gc_srv_t *, sysarg_t);
 
+static void gc_set_clip_rect_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
+{
+	gfx_rect_t rect;
+	errno_t rc;
+
+	rect.p0.x = ipc_get_arg1(call);
+	rect.p0.y = ipc_get_arg2(call);
+	rect.p1.x = ipc_get_arg3(call);
+	rect.p1.y = ipc_get_arg4(call);
+
+	rc = gfx_set_clip_rect(srvgc->gc, &rect);
+	async_answer_0(call, rc);
+}
+
+static void gc_set_clip_rect_null_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
+{
+	errno_t rc;
+
+	rc = gfx_set_clip_rect(srvgc->gc, NULL);
+	async_answer_0(call, rc);
+}
+
 static void gc_set_rgb_color_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
 {
@@ -361,4 +383,10 @@
 
 		switch (method) {
+		case GC_SET_CLIP_RECT:
+			gc_set_clip_rect_srv(&srvgc, &call);
+			break;
+		case GC_SET_CLIP_RECT_NULL:
+			gc_set_clip_rect_null_srv(&srvgc, &call);
+			break;
 		case GC_SET_RGB_COLOR:
 			gc_set_rgb_color_srv(&srvgc, &call);
Index: uspace/lib/ipcgfx/test/ipcgfx.c
===================================================================
--- uspace/lib/ipcgfx/test/ipcgfx.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
+++ uspace/lib/ipcgfx/test/ipcgfx.c	(revision ec7902df3bea37028cfd215b507c5248f4e054dd)
@@ -50,4 +50,5 @@
 static void test_ipcgc_conn(ipc_call_t *, void *);
 
+static errno_t test_gc_set_clip_rect(void *, gfx_rect_t *);
 static errno_t test_gc_set_color(void *, gfx_color_t *);
 static errno_t test_gc_fill_rect(void *, gfx_rect_t *);
@@ -60,4 +61,5 @@
 
 static gfx_context_ops_t test_gc_ops = {
+	.set_clip_rect = test_gc_set_clip_rect,
 	.set_color = test_gc_set_color,
 	.fill_rect = test_gc_fill_rect,
@@ -75,4 +77,8 @@
 	errno_t rc;
 
+	bool set_clip_rect_called;
+	bool do_clip;
+	gfx_rect_t set_clip_rect_rect;
+
 	bool set_color_called;
 	uint16_t set_color_r;
@@ -103,4 +109,148 @@
 	gfx_bitmap_alloc_t alloc;
 } test_bitmap_t;
+
+/** gfx_set_clip_rect with server returning failure */
+PCUT_TEST(set_clip_rect_failure)
+{
+	errno_t rc;
+	service_id_t sid;
+	test_response_t resp;
+	gfx_context_t *gc;
+	gfx_rect_t rect;
+	async_sess_t *sess;
+	ipc_gc_t *ipcgc;
+
+	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
+
+	// FIXME This causes this test to be non-reentrant!
+	rc = loc_server_register(test_ipcgfx_server);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = loc_service_register(test_ipcgfx_svc, &sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	sess = loc_service_connect(sid, INTERFACE_GC, 0);
+	PCUT_ASSERT_NOT_NULL(sess);
+
+	rc = ipc_gc_create(sess, &ipcgc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	gc = ipc_gc_get_ctx(ipcgc);
+	PCUT_ASSERT_NOT_NULL(gc);
+
+	resp.rc = ENOMEM;
+	resp.set_clip_rect_called = false;
+	rect.p0.x = 1;
+	rect.p0.y = 2;
+	rect.p1.x = 3;
+	rect.p1.y = 4;
+	rc = gfx_set_clip_rect(gc, &rect);
+	PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
+	PCUT_ASSERT_TRUE(resp.set_clip_rect_called);
+	PCUT_ASSERT_EQUALS(rect.p0.x, resp.set_clip_rect_rect.p0.x);
+	PCUT_ASSERT_EQUALS(rect.p0.y, resp.set_clip_rect_rect.p0.y);
+	PCUT_ASSERT_EQUALS(rect.p1.x, resp.set_clip_rect_rect.p1.x);
+	PCUT_ASSERT_EQUALS(rect.p1.y, resp.set_clip_rect_rect.p1.y);
+
+	ipc_gc_delete(ipcgc);
+	async_hangup(sess);
+
+	rc = loc_service_unregister(sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
+
+/** gfx_set_clip_rect with server returning success */
+PCUT_TEST(set_clip_rect_success)
+{
+	errno_t rc;
+	service_id_t sid;
+	test_response_t resp;
+	gfx_context_t *gc;
+	gfx_rect_t rect;
+	async_sess_t *sess;
+	ipc_gc_t *ipcgc;
+
+	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
+
+	// FIXME This causes this test to be non-reentrant!
+	rc = loc_server_register(test_ipcgfx_server);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = loc_service_register(test_ipcgfx_svc, &sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	sess = loc_service_connect(sid, INTERFACE_GC, 0);
+	PCUT_ASSERT_NOT_NULL(sess);
+
+	rc = ipc_gc_create(sess, &ipcgc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	gc = ipc_gc_get_ctx(ipcgc);
+	PCUT_ASSERT_NOT_NULL(gc);
+
+	resp.rc = EOK;
+	resp.set_clip_rect_called = false;
+	rect.p0.x = 1;
+	rect.p0.y = 2;
+	rect.p1.x = 3;
+	rect.p1.y = 4;
+	rc = gfx_set_clip_rect(gc, &rect);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_TRUE(resp.set_clip_rect_called);
+	PCUT_ASSERT_TRUE(resp.do_clip);
+	PCUT_ASSERT_EQUALS(rect.p0.x, resp.set_clip_rect_rect.p0.x);
+	PCUT_ASSERT_EQUALS(rect.p0.y, resp.set_clip_rect_rect.p0.y);
+	PCUT_ASSERT_EQUALS(rect.p1.x, resp.set_clip_rect_rect.p1.x);
+	PCUT_ASSERT_EQUALS(rect.p1.y, resp.set_clip_rect_rect.p1.y);
+
+	ipc_gc_delete(ipcgc);
+	async_hangup(sess);
+
+	rc = loc_service_unregister(sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
+
+/** gfx_set_clip_rect with null rectangle, server returning success */
+PCUT_TEST(set_clip_rect_null_success)
+{
+	errno_t rc;
+	service_id_t sid;
+	test_response_t resp;
+	gfx_context_t *gc;
+	async_sess_t *sess;
+	ipc_gc_t *ipcgc;
+
+	async_set_fallback_port_handler(test_ipcgc_conn, &resp);
+
+	// FIXME This causes this test to be non-reentrant!
+	rc = loc_server_register(test_ipcgfx_server);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = loc_service_register(test_ipcgfx_svc, &sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	sess = loc_service_connect(sid, INTERFACE_GC, 0);
+	PCUT_ASSERT_NOT_NULL(sess);
+
+	rc = ipc_gc_create(sess, &ipcgc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	gc = ipc_gc_get_ctx(ipcgc);
+	PCUT_ASSERT_NOT_NULL(gc);
+
+	resp.rc = EOK;
+	resp.set_clip_rect_called = false;
+
+	rc = gfx_set_clip_rect(gc, NULL);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_TRUE(resp.set_clip_rect_called);
+	PCUT_ASSERT_FALSE(resp.do_clip);
+
+	ipc_gc_delete(ipcgc);
+	async_hangup(sess);
+
+	rc = loc_service_unregister(sid);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
 
 /** gfx_set_color with server returning failure */
@@ -234,5 +384,5 @@
 
 	resp.rc = ENOMEM;
-	resp.set_color_called = false;
+	resp.fill_rect_called = false;
 	rect.p0.x = 1;
 	rect.p0.y = 2;
@@ -284,5 +434,5 @@
 
 	resp.rc = EOK;
-	resp.set_color_called = false;
+	resp.fill_rect_called = false;
 	rect.p0.x = 1;
 	rect.p0.y = 2;
@@ -898,4 +1048,26 @@
 }
 
+/** Set clipping rectangle in test GC.
+ *
+ * @param arg Test GC
+ * @param rect Rectangle
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t test_gc_set_clip_rect(void *arg, gfx_rect_t *rect)
+{
+	test_response_t *resp = (test_response_t *) arg;
+
+	resp->set_clip_rect_called = true;
+	if (rect != NULL) {
+		resp->do_clip = true;
+		resp->set_clip_rect_rect = *rect;
+	} else {
+		resp->do_clip = false;
+	}
+
+	return resp->rc;
+}
+
 /** Set color in test GC.
  *
