Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 0f24c57e045c0cbbc79a5fa384ea221044ac03db)
+++ uspace/app/edit/edit.c	(revision 0902edfe630baa7edead6f5a6a722c7b9e74a40e)
@@ -45,4 +45,5 @@
 #include <align.h>
 #include <macros.h>
+#include <clipboard.h>
 #include <bool.h>
 
@@ -119,4 +120,5 @@
     spt_t const *epos);
 static char *filename_prompt(char const *prompt, char const *init_value);
+static char *range_get_str(spt_t const *spos, spt_t const *epos);
 
 static void pane_text_display(void);
@@ -133,5 +135,8 @@
 
 static bool selection_active(void);
+static void selection_get_points(spt_t *pa, spt_t *pb);
 static void selection_delete(void);
+static void selection_copy(void);
+static void insert_clipboard_data(void);
 
 static void pt_get_sof(spt_t *pt);
@@ -321,4 +326,13 @@
 	case KC_E:
 		file_save_as();
+		break;
+	case KC_C:
+		selection_copy();
+		break;
+	case KC_V:
+		selection_delete();
+		insert_clipboard_data();
+		pane.rflags |= REDRAW_TEXT;
+		caret_update();
 		break;
 	default:
@@ -579,4 +593,40 @@
 }
 
+/** Return contents of range as a new string. */
+static char *range_get_str(spt_t const *spos, spt_t const *epos)
+{
+	char *buf;
+	spt_t sp, bep;
+	size_t bytes;
+	size_t buf_size, bpos;
+
+	buf_size = 1;
+
+	buf = malloc(buf_size);
+	if (buf == NULL)
+		return NULL;
+
+	bpos = 0;
+	sp = *spos;
+
+	while (true) {
+		sheet_copy_out(&doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,
+		    &bep);
+		bytes = str_size(&buf[bpos]);
+		bpos += bytes;
+		sp = bep;
+
+		if (spt_equal(&bep, epos))
+			break;
+
+		buf_size *= 2;
+		buf = realloc(buf, buf_size);
+		if (buf == NULL)
+			return NULL;
+	}
+
+	return buf;
+}
+
 static void pane_text_display(void)
 {
@@ -913,4 +963,18 @@
 }
 
+static void selection_get_points(spt_t *pa, spt_t *pb)
+{
+	spt_t pt;
+
+	tag_get_pt(&pane.sel_start, pa);
+	tag_get_pt(&pane.caret_pos, pb);
+
+	if (spt_cmp(pa, pb) > 0) {
+		pt = *pa;
+		*pa = *pb;
+		*pb = pt;
+	}
+}
+
 /** Delete selected text. */
 static void selection_delete(void)
@@ -940,4 +1004,41 @@
 }
 
+static void selection_copy(void)
+{
+	spt_t pa, pb;
+	char *str;
+
+	selection_get_points(&pa, &pb);
+	str = range_get_str(&pa, &pb);
+	if (str == NULL || clipboard_put_str(str) != EOK) {
+		status_display("Copying to clipboard failed!");
+	}
+	free(str);
+}
+
+static void insert_clipboard_data(void)
+{
+	char *str;
+	size_t off;
+	wchar_t c;
+	int rc;
+
+	rc = clipboard_get_str(&str);
+	if (rc != EOK || str == NULL)
+		return;
+
+	off = 0;
+
+	while (true) {
+		c = str_decode(str, &off, STR_NO_LIMIT);
+		if (c == '\0')
+			break;
+
+		insert_char(c);
+	}
+
+	free(str);
+}
+
 /** Get start-of-file s-point. */
 static void pt_get_sof(spt_t *pt)
Index: uspace/lib/libc/Makefile.build
===================================================================
--- uspace/lib/libc/Makefile.build	(revision 0f24c57e045c0cbbc79a5fa384ea221044ac03db)
+++ uspace/lib/libc/Makefile.build	(revision 0902edfe630baa7edead6f5a6a722c7b9e74a40e)
@@ -50,4 +50,5 @@
 	generic/as.c \
 	generic/cap.c \
+	generic/clipboard.c \
 	generic/devmap.c \
 	generic/event.c \
Index: uspace/lib/libc/generic/clipboard.c
===================================================================
--- uspace/lib/libc/generic/clipboard.c	(revision 0902edfe630baa7edead6f5a6a722c7b9e74a40e)
+++ uspace/lib/libc/generic/clipboard.c	(revision 0902edfe630baa7edead6f5a6a722c7b9e74a40e)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+static char *clipboard_data = NULL;
+
+/** Copy string to clipboard.
+ *
+ * Sets the clipboard contents to @a str. Passing an empty string or NULL
+ * makes the clipboard empty. 
+ *
+ * @param str	String to put to clipboard or NULL.
+ * @return	Zero on success or negative error code.
+ *
+ */
+int clipboard_put_str(const char *str)
+{
+	if (clipboard_data != NULL)
+		free(clipboard_data);
+
+	clipboard_data = str_dup(str);
+	return EOK;
+}
+
+int clipboard_get_str(char **str)
+{
+	*str = (clipboard_data != NULL) ? str_dup(clipboard_data) : NULL;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/libc/include/clipboard.h
===================================================================
--- uspace/lib/libc/include/clipboard.h	(revision 0902edfe630baa7edead6f5a6a722c7b9e74a40e)
+++ uspace/lib/libc/include/clipboard.h	(revision 0902edfe630baa7edead6f5a6a722c7b9e74a40e)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_CLIPBOARD_H_
+#define LIBC_CLIPBOARD_H_
+
+extern int clipboard_put_str(const char *);
+extern int clipboard_get_str(char **);
+
+#endif
+
+/** @}
+ */
