Index: uspace/lib/ui/include/ui/entry.h
===================================================================
--- uspace/lib/ui/include/ui/entry.h	(revision 1215db9d1ade6fae2cbc2685459e7ecd9b62efef)
+++ uspace/lib/ui/include/ui/entry.h	(revision 61bf9dd9428e2f8c95a06cdc0f80d9af3071da4a)
@@ -53,4 +53,10 @@
 extern errno_t ui_entry_set_text(ui_entry_t *, const char *);
 extern errno_t ui_entry_paint(ui_entry_t *);
+extern void ui_entry_backspace(ui_entry_t *);
+extern void ui_entry_delete(ui_entry_t *);
+extern void ui_entry_seek_start(ui_entry_t *);
+extern void ui_entry_seek_end(ui_entry_t *);
+extern void ui_entry_seek_prev_char(ui_entry_t *);
+extern void ui_entry_seek_next_char(ui_entry_t *);
 extern ui_evclaim_t ui_entry_kbd_event(ui_entry_t *, kbd_event_t *);
 extern ui_evclaim_t ui_entry_pos_event(ui_entry_t *, pos_event_t *);
Index: uspace/lib/ui/private/entry.h
===================================================================
--- uspace/lib/ui/private/entry.h	(revision 1215db9d1ade6fae2cbc2685459e7ecd9b62efef)
+++ uspace/lib/ui/private/entry.h	(revision 61bf9dd9428e2f8c95a06cdc0f80d9af3071da4a)
@@ -58,4 +58,6 @@
 	/** Text */
 	char *text;
+	/** Cursor position in the text (offset in bytes) */
+	unsigned pos;
 	/** Pointer is currently inside */
 	bool pointer_inside;
@@ -65,5 +67,4 @@
 
 extern errno_t ui_entry_insert_str(ui_entry_t *, const char *);
-extern void ui_entry_backspace(ui_entry_t *);
 extern ui_evclaim_t ui_entry_key_press_unmod(ui_entry_t *, kbd_event_t *);
 extern void ui_entry_activate(ui_entry_t *);
Index: uspace/lib/ui/src/entry.c
===================================================================
--- uspace/lib/ui/src/entry.c	(revision 1215db9d1ade6fae2cbc2685459e7ecd9b62efef)
+++ uspace/lib/ui/src/entry.c	(revision 61bf9dd9428e2f8c95a06cdc0f80d9af3071da4a)
@@ -180,4 +180,5 @@
 	free(entry->text);
 	entry->text = tcopy;
+	entry->pos = str_size(text);
 
 	return EOK;
@@ -223,4 +224,26 @@
 error:
 	return rc;
+}
+
+/** Return width of text before cursor.
+ *
+ * @param entry Text entry
+ * @return Widht of text before cursor
+ */
+static gfx_coord_t ui_entry_lwidth(ui_entry_t *entry)
+{
+	ui_resource_t *res;
+	uint8_t tmp;
+	gfx_coord_t width;
+
+	res = ui_window_get_res(entry->window);
+
+	tmp = entry->text[entry->pos];
+
+	entry->text[entry->pos] = '\0';
+	width = gfx_text_width(res->font, entry->text);
+	entry->text[entry->pos] = tmp;
+
+	return width;
 }
 
@@ -304,5 +327,5 @@
 	if (entry->active) {
 		/* Cursor */
-		pos.x += width;
+		pos.x += ui_entry_lwidth(entry);
 
 		rc = ui_entry_paint_cursor(entry, &pos);
@@ -357,15 +380,30 @@
 errno_t ui_entry_insert_str(ui_entry_t *entry, const char *str)
 {
+	uint8_t tmp;
+	char *ltext = NULL;
 	char *newtext;
 	char *oldtext;
 	int rc;
 
-	rc = asprintf(&newtext, "%s%s", entry->text, str);
-	if (rc < 0)
+	tmp = entry->text[entry->pos];
+	entry->text[entry->pos] = '\0';
+	ltext = str_dup(entry->text);
+	if (ltext == NULL)
 		return ENOMEM;
+
+	entry->text[entry->pos] = tmp;
+
+	rc = asprintf(&newtext, "%s%s%s", ltext, str, entry->text + entry->pos);
+	if (rc < 0) {
+		free(ltext);
+		return ENOMEM;
+	}
 
 	oldtext = entry->text;
 	entry->text = newtext;
+	entry->pos += str_size(str);
 	free(oldtext);
+	free(ltext);
+
 	ui_entry_paint(entry);
 
@@ -381,8 +419,35 @@
 	size_t off;
 
-	off = str_size(entry->text);
+	if (entry->pos == 0)
+		return;
+
+	/* Find offset where character before cursor starts */
+	off = entry->pos;
 	(void) str_decode_reverse(entry->text, &off,
 	    str_size(entry->text));
-	entry->text[off] = '\0';
+
+	memmove(entry->text + off, entry->text + entry->pos,
+	    str_size(entry->text + entry->pos) + 1);
+	entry->pos = off;
+
+	ui_entry_paint(entry);
+}
+
+/** Delete character after cursor.
+ *
+ * @param entry Text entry
+ */
+void ui_entry_delete(ui_entry_t *entry)
+{
+	size_t off;
+
+	/* Find offset where character after cursor end */
+	off = entry->pos;
+	(void) str_decode(entry->text, &off,
+	    str_size(entry->text));
+
+	memmove(entry->text + entry->pos, entry->text + off,
+	    str_size(entry->text + off) + 1);
+
 	ui_entry_paint(entry);
 }
@@ -398,9 +463,36 @@
 	assert(event->type == KEY_PRESS);
 
-	if (event->key == KC_BACKSPACE)
+	switch (event->key) {
+	case KC_BACKSPACE:
 		ui_entry_backspace(entry);
-
-	if (event->key == KC_ESCAPE)
+		break;
+
+	case KC_DELETE:
+		ui_entry_delete(entry);
+		break;
+
+	case KC_ESCAPE:
 		ui_entry_deactivate(entry);
+		break;
+
+	case KC_HOME:
+		ui_entry_seek_start(entry);
+		break;
+
+	case KC_END:
+		ui_entry_seek_end(entry);
+		break;
+
+	case KC_LEFT:
+		ui_entry_seek_prev_char(entry);
+		break;
+
+	case KC_RIGHT:
+		ui_entry_seek_next_char(entry);
+		break;
+
+	default:
+		break;
+	}
 
 	return ui_claimed;
@@ -526,4 +618,5 @@
 
 	entry->active = true;
+	entry->pos = str_size(entry->text);
 	(void) ui_entry_paint(entry);
 
@@ -532,4 +625,54 @@
 }
 
+/** Move text cursor to the beginning of text.
+ *
+ * @param entry Text entry
+ */
+void ui_entry_seek_start(ui_entry_t *entry)
+{
+	entry->pos = 0;
+	(void) ui_entry_paint(entry);
+}
+
+/** Move text cursor to the end of text.
+ *
+ * @param entry Text entry
+ */
+void ui_entry_seek_end(ui_entry_t *entry)
+{
+	entry->pos = str_size(entry->text);
+	(void) ui_entry_paint(entry);
+}
+
+/** Move text cursor one character backward.
+ *
+ * @param entry Text entry
+ */
+void ui_entry_seek_prev_char(ui_entry_t *entry)
+{
+	size_t off;
+
+	off = entry->pos;
+	(void) str_decode_reverse(entry->text, &off,
+	    str_size(entry->text));
+	entry->pos = off;
+	(void) ui_entry_paint(entry);
+}
+
+/** Move text cursor one character forward.
+ *
+ * @param entry Text entry
+ */
+void ui_entry_seek_next_char(ui_entry_t *entry)
+{
+	size_t off;
+
+	off = entry->pos;
+	(void) str_decode(entry->text, &off,
+	    str_size(entry->text));
+	entry->pos = off;
+	(void) ui_entry_paint(entry);
+}
+
 /** Deactivate text entry.
  *
Index: uspace/lib/ui/test/entry.c
===================================================================
--- uspace/lib/ui/test/entry.c	(revision 1215db9d1ade6fae2cbc2685459e7ecd9b62efef)
+++ uspace/lib/ui/test/entry.c	(revision 61bf9dd9428e2f8c95a06cdc0f80d9af3071da4a)
@@ -214,4 +214,7 @@
 	PCUT_ASSERT_STR_EQUALS("A", entry->text);
 
+	/* This moves the cursor to the end of the text */
+	ui_entry_activate(entry);
+
 	rc = ui_entry_insert_str(entry, "B");
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
@@ -219,8 +222,14 @@
 	PCUT_ASSERT_STR_EQUALS("AB", entry->text);
 
+	rc = ui_entry_insert_str(entry, "EF");
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABEF", entry->text);
+
+	entry->pos = 2;
 	rc = ui_entry_insert_str(entry, "CD");
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
-	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	PCUT_ASSERT_STR_EQUALS("ABCDEF", entry->text);
 
 	ui_entry_destroy(entry);
@@ -248,20 +257,195 @@
 	PCUT_ASSERT_NOT_NULL(window);
 
-	rc = ui_entry_create(window, "ABC", &entry);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	PCUT_ASSERT_STR_EQUALS("ABC", entry->text);
+	rc = ui_entry_create(window, "ABCD", &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	entry->pos = 3;
 
 	ui_entry_backspace(entry);
-	PCUT_ASSERT_STR_EQUALS("AB", entry->text);
+	PCUT_ASSERT_STR_EQUALS("ABD", entry->text);
 
 	ui_entry_backspace(entry);
+	PCUT_ASSERT_STR_EQUALS("AD", entry->text);
+
+	ui_entry_backspace(entry);
+	PCUT_ASSERT_STR_EQUALS("D", entry->text);
+
+	ui_entry_backspace(entry);
+	PCUT_ASSERT_STR_EQUALS("D", entry->text);
+
+	ui_entry_destroy(entry);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_entry_delete() deletes character after cursor. */
+PCUT_TEST(delete)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_window_t *window = NULL;
+	ui_wnd_params_t params;
+	ui_entry_t *entry;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_entry_create(window, "ABCD", &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	entry->pos = 1;
+
+	ui_entry_delete(entry);
+	PCUT_ASSERT_STR_EQUALS("ACD", entry->text);
+
+	ui_entry_delete(entry);
+	PCUT_ASSERT_STR_EQUALS("AD", entry->text);
+
+	ui_entry_delete(entry);
 	PCUT_ASSERT_STR_EQUALS("A", entry->text);
 
-	ui_entry_backspace(entry);
-	PCUT_ASSERT_STR_EQUALS("", entry->text);
-
-	ui_entry_backspace(entry);
-	PCUT_ASSERT_STR_EQUALS("", entry->text);
+	ui_entry_delete(entry);
+	PCUT_ASSERT_STR_EQUALS("A", entry->text);
+
+	ui_entry_destroy(entry);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_entry_seek_start() moves cursor to beginning of text */
+PCUT_TEST(seek_start)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_window_t *window = NULL;
+	ui_wnd_params_t params;
+	ui_entry_t *entry;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_entry_create(window, "ABCD", &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	entry->pos = 2;
+
+	ui_entry_seek_start(entry);
+	PCUT_ASSERT_INT_EQUALS(0, entry->pos);
+
+	ui_entry_destroy(entry);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_entry_seek_end() moves cursor to the end of text */
+PCUT_TEST(seek_end)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_window_t *window = NULL;
+	ui_wnd_params_t params;
+	ui_entry_t *entry;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_entry_create(window, "ABCD", &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	entry->pos = 2;
+
+	ui_entry_seek_end(entry);
+	PCUT_ASSERT_INT_EQUALS(4, entry->pos);
+
+	ui_entry_destroy(entry);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_entry_seek_prev_char() moves cursor to the previous character */
+PCUT_TEST(seek_prev_char)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_window_t *window = NULL;
+	ui_wnd_params_t params;
+	ui_entry_t *entry;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_entry_create(window, "ABCD", &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	entry->pos = 2;
+
+	ui_entry_seek_prev_char(entry);
+	PCUT_ASSERT_INT_EQUALS(1, entry->pos);
+
+	ui_entry_destroy(entry);
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
+/** ui_entry_seek_prev_char() moves cursor to the next character */
+PCUT_TEST(seek_next_char)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_window_t *window = NULL;
+	ui_wnd_params_t params;
+	ui_entry_t *entry;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_entry_create(window, "ABCD", &entry);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_STR_EQUALS("ABCD", entry->text);
+	entry->pos = 2;
+
+	ui_entry_seek_next_char(entry);
+	PCUT_ASSERT_INT_EQUALS(3, entry->pos);
 
 	ui_entry_destroy(entry);
