summaryrefslogtreecommitdiff
path: root/clients/terminal.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-01-19 14:27:42 -0500
committerKristian Høgsberg <krh@bitplanet.net>2011-01-19 14:27:42 -0500
commit58eec36f680ce7ba3e71db88350c4828724b779d (patch)
tree3921ffecd92b19437e41bf75134a733bb9120a9a /clients/terminal.c
parent67cac8a565c3e03567372666c7e83796c6a23114 (diff)
Add proof-of-concept selection support to terminal
Next will be to support mouse selections so we can copy and paste something more interesting than just 'selection data'.
Diffstat (limited to 'clients/terminal.c')
-rw-r--r--clients/terminal.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/clients/terminal.c b/clients/terminal.c
index a89a5bf..ab9bdb3 100644
--- a/clients/terminal.c
+++ b/clients/terminal.c
@@ -390,6 +390,11 @@ struct terminal {
struct terminal_color color_table[256];
cairo_font_extents_t extents;
cairo_scaled_font_t *font_normal, *font_bold;
+
+ uint32_t tag;
+ struct wl_selection *selection;
+ struct wl_selection_offer *selection_offer;
+ uint32_t selection_offer_has_text;
};
/* Create default tab stops, every 8 characters */
@@ -1872,6 +1877,88 @@ terminal_data(struct terminal *terminal, const char *data, size_t length)
}
static void
+selection_listener_send(void *data, struct wl_selection *selection,
+ const char *mime_type, int fd)
+{
+ struct terminal *terminal = data;
+ static const char msg[] = "selection data";
+
+ fprintf(stderr, "selection send, fd is %d\n", fd);
+ write(fd, msg, sizeof msg);
+ close(fd);
+}
+
+static void
+selection_listener_cancelled(void *data, struct wl_selection *selection)
+{
+ struct terminal *terminal = data;
+
+ fprintf(stderr, "selection cancelled\n");
+ wl_selection_destroy(selection);
+}
+
+static const struct wl_selection_listener selection_listener = {
+ selection_listener_send,
+ selection_listener_cancelled
+};
+
+static gboolean
+selection_io_func(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ struct terminal *terminal = data;
+ char buffer[256];
+ unsigned int len;
+ int fd;
+
+ fd = g_io_channel_unix_get_fd(source);
+ len = read(fd, buffer, sizeof buffer);
+ fprintf(stderr, "read %d bytes: %.*s\n", len, len, buffer);
+
+ close(fd);
+ g_source_remove(terminal->tag);
+
+ g_io_channel_unref(source);
+
+ return TRUE;
+}
+
+static int
+handle_bound_key(struct terminal *terminal,
+ struct input *input, uint32_t sym, uint32_t time)
+{
+ struct wl_shell *shell;
+ GIOChannel *channel;
+ int fd;
+
+ switch (sym) {
+ case XK_C:
+ shell = display_get_shell(terminal->display);
+ terminal->selection = wl_shell_create_selection(shell);
+ wl_selection_add_listener(terminal->selection,
+ &selection_listener, terminal);
+ wl_selection_offer(terminal->selection, "text/plain");
+ wl_selection_activate(terminal->selection,
+ input_get_input_device(input), time);
+
+ return 1;
+ case XK_V:
+ if (input_offers_mime_type(input, "text/plain")) {
+ fd = input_receive_mime_type(input, "text/plain");
+ channel = g_io_channel_unix_new(fd);
+ terminal->tag = g_io_add_watch(channel, G_IO_IN,
+ selection_io_func,
+ terminal);
+ }
+
+ return 1;
+ case XK_X:
+ /* cut selection; terminal doesn't do cut */
+ return 0;
+ default:
+ return 0;
+ }
+}
+
static void
key_handler(struct window *window, struct input *input, uint32_t time,
uint32_t key, uint32_t sym, uint32_t state, void *data)