Index: uspace/lib/display/src/disp_srv.c
===================================================================
--- uspace/lib/display/src/disp_srv.c	(revision 35cffeac21acf1766c2acbf62f162a7a62c130f7)
+++ uspace/lib/display/src/disp_srv.c	(revision 68704ab6ec14b07b8689674e7dd5563ef8e555e2)
@@ -63,5 +63,7 @@
 	sysarg_t wnd_id;
 	ipc_call_t call;
+	display_wnd_params_enc_t eparams;
 	display_wnd_params_t params;
+	char *caption;
 	size_t size;
 	errno_t rc;
@@ -73,12 +75,40 @@
 	}
 
-	if (size != sizeof(display_wnd_params_t)) {
-		async_answer_0(&call, EINVAL);
-		async_answer_0(icall, EINVAL);
-		return;
-	}
-
-	rc = async_data_write_finalize(&call, &params, size);
-	if (rc != EOK) {
+	if (size != sizeof(display_wnd_params_enc_t)) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_data_write_finalize(&call, &eparams, size);
+	if (rc != EOK) {
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	caption = calloc(eparams.caption_size + 1, 1);
+	if (caption == NULL) {
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	if (!async_data_write_receive(&call, &size)) {
+		free(caption);
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (size != eparams.caption_size) {
+		free(caption);
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_data_write_finalize(&call, caption, eparams.caption_size);
+	if (rc != EOK) {
+		free(caption);
 		async_answer_0(&call, rc);
 		async_answer_0(icall, rc);
@@ -87,7 +117,15 @@
 
 	if (srv->ops->window_create == NULL) {
-		async_answer_0(icall, ENOTSUP);
-		return;
-	}
+		free(caption);
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	/* Decode the parameters from transport */
+	params.rect = eparams.rect;
+	params.caption = caption;
+	params.min_size = eparams.min_size;
+	params.pos = eparams.pos;
+	params.flags = eparams.flags;
 
 	rc = srv->ops->window_create(srv->arg, &params, &wnd_id);
@@ -401,4 +439,47 @@
 	rc = srv->ops->window_set_cursor(srv->arg, wnd_id, cursor);
 	async_answer_0(icall, rc);
+}
+
+static void display_window_set_caption_srv(display_srv_t *srv,
+    ipc_call_t *icall)
+{
+	sysarg_t wnd_id;
+	ipc_call_t call;
+	char *caption;
+	size_t size;
+	errno_t rc;
+
+	wnd_id = ipc_get_arg1(icall);
+
+	if (!async_data_write_receive(&call, &size)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	caption = calloc(size + 1, 1);
+	if (caption == NULL) {
+		async_answer_0(&call, ENOMEM);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	rc = async_data_write_finalize(&call, caption, size);
+	if (rc != EOK) {
+		free(caption);
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	if (srv->ops->window_set_caption == NULL) {
+		free(caption);
+		async_answer_0(icall, ENOTSUP);
+		return;
+	}
+
+	rc = srv->ops->window_set_caption(srv->arg, wnd_id, caption);
+	async_answer_0(icall, rc);
+	free(caption);
 }
 
@@ -538,4 +619,7 @@
 		case DISPLAY_WINDOW_SET_CURSOR:
 			display_window_set_cursor_srv(srv, &call);
+			break;
+		case DISPLAY_WINDOW_SET_CAPTION:
+			display_window_set_caption_srv(srv, &call);
 			break;
 		case DISPLAY_GET_EVENT:
Index: uspace/lib/display/src/display.c
===================================================================
--- uspace/lib/display/src/display.c	(revision 35cffeac21acf1766c2acbf62f162a7a62c130f7)
+++ uspace/lib/display/src/display.c	(revision 68704ab6ec14b07b8689674e7dd5563ef8e555e2)
@@ -38,4 +38,5 @@
 #include <mem.h>
 #include <stdlib.h>
+#include <str.h>
 #include "../private/display.h"
 #include "../private/params.h"
@@ -147,4 +148,5 @@
 {
 	memset(params, 0, sizeof(*params));
+	params->caption = "";
 }
 
@@ -162,8 +164,16 @@
 {
 	display_window_t *window;
-	async_exch_t *exch;
-	aid_t req;
-	ipc_call_t answer;
-	errno_t rc;
+	display_wnd_params_enc_t eparams;
+	async_exch_t *exch;
+	aid_t req;
+	ipc_call_t answer;
+	errno_t rc;
+
+	/* Encode the parameters for transport */
+	eparams.rect = params->rect;
+	eparams.caption_size = str_size(params->caption);
+	eparams.min_size = params->min_size;
+	eparams.pos = params->pos;
+	eparams.flags = params->flags;
 
 	window = calloc(1, sizeof(display_window_t));
@@ -173,5 +183,18 @@
 	exch = async_exchange_begin(display->sess);
 	req = async_send_0(exch, DISPLAY_WINDOW_CREATE, &answer);
-	rc = async_data_write_start(exch, params, sizeof (display_wnd_params_t));
+
+	/* Write fixed fields */
+	rc = async_data_write_start(exch, &eparams,
+	    sizeof (display_wnd_params_enc_t));
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		async_forget(req);
+		free(window);
+		return rc;
+	}
+
+	/* Write caption */
+	rc = async_data_write_start(exch, params->caption,
+	    eparams.caption_size);
 	async_exchange_end(exch);
 	if (rc != EOK) {
@@ -540,4 +563,37 @@
 	    cursor);
 	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set display window caption.
+ *
+ * @param window Window
+ * @param caption New caption
+ * @return EOK on success or an error code
+ */
+errno_t display_window_set_caption(display_window_t *window,
+    const char *caption)
+{
+	async_exch_t *exch;
+	aid_t req;
+	ipc_call_t answer;
+	size_t cap_size;
+	errno_t rc;
+
+	cap_size = str_size(caption);
+
+	exch = async_exchange_begin(window->display->sess);
+	req = async_send_1(exch, DISPLAY_WINDOW_SET_CAPTION, window->id,
+	    &answer);
+
+	/* Write caption */
+	rc = async_data_write_start(exch, caption, cap_size);
+	async_exchange_end(exch);
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	async_wait_for(req, &rc);
 	return rc;
 }
