From 202fa3b766257d90010ee8fb4ce13dd970211c04 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 5 Oct 2012 13:41:52 +0200 Subject: [PATCH] wlt: terminal: implement mouse-selection This hooks up the mouse-selection with the tsm-screen selection support. Signed-off-by: David Herrmann --- src/wlt_terminal.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/wlt_terminal.c b/src/wlt_terminal.c index 45856fb..1d4ec51 100644 --- a/src/wlt_terminal.c +++ b/src/wlt_terminal.c @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -53,6 +54,7 @@ struct wlt_terminal { struct wlt_window *wnd; struct wlt_widget *widget; struct wlt_shm_buffer buffer; + struct wlt_rect alloc; struct tsm_screen *scr; struct tsm_vte *vte; @@ -67,6 +69,10 @@ struct wlt_terminal { wlt_terminal_cb cb; void *data; + + int pointer_x; + int pointer_y; + bool in_selection; }; static int draw_cell(struct tsm_screen *scr, @@ -217,6 +223,7 @@ static void widget_resize(struct wlt_widget *widget, unsigned int flags, int ret; wlt_window_get_buffer(term->wnd, alloc, &term->buffer); + memcpy(&term->alloc, alloc, sizeof(*alloc)); /* don't allow children */ alloc->width = 0; @@ -392,6 +399,71 @@ static bool widget_key(struct wlt_widget *widget, unsigned int mask, return false; } +static void pointer_motion(struct wlt_widget *widget, + unsigned int x, unsigned int y, void *data) +{ + struct wlt_terminal *term = data; + unsigned int posx, posy; + + if (!wlt_rect_contains(&term->alloc, x, y)) { + term->pointer_x = -1; + term->pointer_y = -1; + return; + } else { + term->pointer_x = x - term->alloc.x; + term->pointer_y = y - term->alloc.y; + } + + posx = term->pointer_x / term->font_normal->attr.width; + posy = term->pointer_y / term->font_normal->attr.height; + + if (term->in_selection) { + tsm_screen_selection_target(term->scr, posx, posy); + wlt_window_schedule_redraw(term->wnd); + } +} + +static void pointer_enter(struct wlt_widget *widget, + unsigned int x, unsigned int y, void *data) +{ + struct wlt_terminal *term = data; + + pointer_motion(widget, x, y, term); +} + +static void pointer_leave(struct wlt_widget *widget, void *data) +{ + struct wlt_terminal *term = data; + + term->pointer_x = -1; + term->pointer_y = -1; +} + +static void pointer_button(struct wlt_widget *widget, + uint32_t button, uint32_t state, void *data) +{ + struct wlt_terminal *term = data; + unsigned int posx, posy; + + if (button != BTN_LEFT) + return; + + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { + if (!term->in_selection && + term->pointer_x >= 0 && term->pointer_y >= 0) { + term->in_selection = true; + + posx = term->pointer_x / term->font_normal->attr.width; + posy = term->pointer_y / term->font_normal->attr.height; + + tsm_screen_selection_start(term->scr, posx, posy); + wlt_window_schedule_redraw(term->wnd); + } + } else { + term->in_selection = false; + } +} + static void vte_event(struct tsm_vte *vte, const char *u8, size_t len, void *data) { @@ -511,6 +583,8 @@ int wlt_terminal_new(struct wlt_terminal **out, struct wlt_window *wnd) wlt_widget_set_resize_cb(term->widget, widget_prepare_resize, widget_resize); wlt_widget_set_keyboard_cb(term->widget, widget_key); + wlt_widget_set_pointer_cb(term->widget, pointer_enter, pointer_leave, + pointer_motion, pointer_button); *out = term; return 0;