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'.
This commit is contained in:
Kristian Høgsberg 2011-01-19 14:27:42 -05:00
parent 67cac8a565
commit 58eec36f68
3 changed files with 216 additions and 0 deletions

View file

@ -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)