From 4c7d29f7eb95b10a0fadc406924db537a18b12ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 8 Jul 2020 18:41:09 +0200 Subject: [PATCH] multi-seat: re-enable selection support (excluding OSC 52) --- input.c | 31 ++++++------ selection.c | 139 +++++++++++++++++++++------------------------------- selection.h | 35 ++++++++----- wayland.c | 8 +++ 4 files changed, 104 insertions(+), 109 deletions(-) diff --git a/input.c b/input.c index 1980e2b5..a035983a 100644 --- a/input.c +++ b/input.c @@ -33,8 +33,8 @@ #include "vt.h" static void -execute_binding(struct terminal *term, enum bind_action_normal action, - uint32_t serial) +execute_binding(struct seat *seat, struct terminal *term, + enum bind_action_normal action, uint32_t serial) { switch (action) { case BIND_ACTION_NONE: @@ -49,16 +49,16 @@ execute_binding(struct terminal *term, enum bind_action_normal action, break; case BIND_ACTION_CLIPBOARD_COPY: - selection_to_clipboard(term, serial); + selection_to_clipboard(seat, term, serial); break; case BIND_ACTION_CLIPBOARD_PASTE: - selection_from_clipboard(term, serial); + selection_from_clipboard(seat, term, serial); term_reset_view(term); break; case BIND_ACTION_PRIMARY_PASTE: - selection_from_primary(term); + selection_from_primary(seat, term); break; case BIND_ACTION_SEARCH_START: @@ -580,14 +580,14 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, /* Match symbol */ if (it->item.bind.sym == sym) { - execute_binding(term, it->item.action, serial); + execute_binding(seat, term, it->item.action, serial); goto maybe_repeat; } /* Match raw key code */ tll_foreach(it->item.bind.key_codes, code) { if (code->item == key) { - execute_binding(term, it->item.action, serial); + execute_binding(seat, term, it->item.action, serial); goto maybe_repeat; } } @@ -1197,20 +1197,23 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, break; case 2: - selection_mark_word(term, seat->mouse.col, seat->mouse.row, - seat->kbd.ctrl, serial); + selection_mark_word( + seat, term, seat->mouse.col, seat->mouse.row, + seat->kbd.ctrl, serial); break; case 3: - selection_mark_row(term, seat->mouse.row, serial); + selection_mark_row(seat, term, seat->mouse.row, serial); break; } } } else if (button == BTN_RIGHT && seat->mouse.count == 1) { - if (selection_enabled(term)) - selection_extend(term, seat->mouse.col, seat->mouse.row, serial); + if (selection_enabled(term)) { + selection_extend( + seat, term, seat->mouse.col, seat->mouse.row, serial); + } } else { @@ -1228,7 +1231,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, continue; } - execute_binding(term, binding->action, serial); + execute_binding(seat, term, binding->action, serial); break; } } @@ -1241,7 +1244,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, case WL_POINTER_BUTTON_STATE_RELEASED: if (button == BTN_LEFT && term->selection.end.col != -1) - selection_finalize(term, serial); + selection_finalize(seat, term, serial); term_mouse_up( term, button, seat->mouse.row, seat->mouse.col, diff --git a/selection.c b/selection.c index dd759e93..2c8176dd 100644 --- a/selection.c +++ b/selection.c @@ -591,7 +591,8 @@ selection_extend_block(struct terminal *term, int col, int row, uint32_t serial) } void -selection_extend(struct terminal *term, int col, int row, uint32_t serial) +selection_extend(struct seat *seat, struct terminal *term, + int col, int row, uint32_t serial) { if (term->selection.start.row < 0 || term->selection.end.row < 0) { /* No existing selection */ @@ -621,13 +622,13 @@ selection_extend(struct terminal *term, int col, int row, uint32_t serial) break; } - selection_to_primary(term, serial); + selection_to_primary(seat, term, serial); } //static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener; void -selection_finalize(struct terminal *term, uint32_t serial) +selection_finalize(struct seat *seat, struct terminal *term, uint32_t serial) { if (term->selection.start.row < 0 || term->selection.end.row < 0) return; @@ -645,7 +646,7 @@ selection_finalize(struct terminal *term, uint32_t serial) } assert(term->selection.start.row <= term->selection.end.row); - selection_to_primary(term, serial); + selection_to_primary(seat, term, serial); } void @@ -668,8 +669,8 @@ selection_cancel(struct terminal *term) } void -selection_mark_word(struct terminal *term, int col, int row, bool spaces_only, - uint32_t serial) +selection_mark_word(struct seat *seat, struct terminal *term, int col, int row, + bool spaces_only, uint32_t serial) { selection_cancel(term); @@ -730,19 +731,19 @@ selection_mark_word(struct terminal *term, int col, int row, bool spaces_only, selection_start(term, start.col, start.row, SELECTION_NORMAL); selection_update(term, end.col, end.row); - selection_finalize(term, serial); + selection_finalize(seat, term, serial); } void -selection_mark_row(struct terminal *term, int row, uint32_t serial) +selection_mark_row( + struct seat *seat, struct terminal *term, int row, uint32_t serial) { selection_start(term, 0, row, SELECTION_NORMAL); selection_update(term, term->cols - 1, row); - selection_finalize(term, serial); + selection_finalize(seat, term, serial); } -#if 0 static void target(void *data, struct wl_data_source *wl_data_source, const char *mime_type) { @@ -788,8 +789,8 @@ static void send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, int32_t fd) { - struct wayland *wayl = data; - const struct wl_clipboard *clipboard = &wayl->clipboard; + struct seat *seat = data; + const struct wl_clipboard *clipboard = &seat->clipboard; assert(clipboard != NULL); assert(clipboard->text != NULL); @@ -817,7 +818,7 @@ send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, .idx = async_idx, }; - if (fdm_add(wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx)) + if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx)) return; free(ctx->data); @@ -841,8 +842,8 @@ send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, static void cancelled(void *data, struct wl_data_source *wl_data_source) { - struct wayland *wayl = data; - struct wl_clipboard *clipboard = &wayl->clipboard; + struct seat *seat = data; + struct wl_clipboard *clipboard = &seat->clipboard; assert(clipboard->data_source == wl_data_source); wl_data_source_destroy(clipboard->data_source); @@ -867,9 +868,7 @@ static void action(void *data, struct wl_data_source *wl_data_source, uint32_t dnd_action) { } -#endif -#if 0 static const struct wl_data_source_listener data_source_listener = { .target = &target, .send = &send, @@ -878,15 +877,14 @@ static const struct wl_data_source_listener data_source_listener = { .dnd_finished = &dnd_finished, .action = &action, }; -#endif -#if 0 + static void primary_send(void *data, struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1, const char *mime_type, int32_t fd) { - struct wayland *wayl = data; - const struct wl_primary *primary = &wayl->primary; + struct seat *seat = data; + const struct wl_primary *primary = &seat->primary; assert(primary != NULL); assert(primary->text != NULL); @@ -912,7 +910,7 @@ primary_send(void *data, .idx = async_idx, }; - if (fdm_add(wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx)) + if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx)) return; free(ctx->data); @@ -937,8 +935,8 @@ static void primary_cancelled(void *data, struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1) { - struct wayland *wayl = data; - struct wl_primary *primary = &wayl->primary; + struct seat *seat = data; + struct wl_primary *primary = &seat->primary; zwp_primary_selection_source_v1_destroy(primary->data_source); primary->data_source = NULL; @@ -947,24 +945,21 @@ primary_cancelled(void *data, free(primary->text); primary->text = NULL; } -#endif -#if 0 static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = { .send = &primary_send, .cancelled = &primary_cancelled, }; -#endif + bool -text_to_clipboard(struct terminal *term, char *text, uint32_t serial) +text_to_clipboard(struct seat *seat, struct terminal *term, char *text, uint32_t serial) { -#if 0 - struct wl_clipboard *clipboard = &term->wl->clipboard; + struct wl_clipboard *clipboard = &seat->clipboard; if (clipboard->data_source != NULL) { /* Kill previous data source */ assert(clipboard->serial != 0); - wl_data_device_set_selection(term->wl->data_device, NULL, clipboard->serial); + wl_data_device_set_selection(seat->data_device, NULL, clipboard->serial); wl_data_source_destroy(clipboard->data_source); free(clipboard->text); @@ -984,26 +979,24 @@ text_to_clipboard(struct terminal *term, char *text, uint32_t serial) /* Configure source */ wl_data_source_offer(clipboard->data_source, "text/plain;charset=utf-8"); - wl_data_source_add_listener(clipboard->data_source, &data_source_listener, term->wl); - wl_data_device_set_selection(term->wl->data_device, clipboard->data_source, serial); + wl_data_source_add_listener(clipboard->data_source, &data_source_listener, seat); + wl_data_device_set_selection(seat->data_device, clipboard->data_source, serial); /* Needed when sending the selection to other client */ assert(serial != 0); clipboard->serial = serial; return true; -#endif - return false; } void -selection_to_clipboard(struct terminal *term, uint32_t serial) +selection_to_clipboard(struct seat *seat, struct terminal *term, uint32_t serial) { if (term->selection.start.row < 0 || term->selection.end.row < 0) return; /* Get selection as a string */ char *text = extract_selection(term); - if (!text_to_clipboard(term, text, serial)) + if (!text_to_clipboard(seat, term, text, serial)) free(text); } @@ -1014,7 +1007,7 @@ struct clipboard_receive { void *user; }; -#if 0 + static bool fdm_receive(struct fdm *fdm, int fd, int events, void *data) { @@ -1064,8 +1057,7 @@ done: free(ctx); return true; } -#endif -#if 0 + static void begin_receive_clipboard(struct terminal *term, int read_fd, void (*cb)(const char *data, size_t size, void *user), @@ -1093,14 +1085,13 @@ begin_receive_clipboard(struct terminal *term, int read_fd, done(user); } } -#endif + void -text_from_clipboard(struct terminal *term, uint32_t serial, +text_from_clipboard(struct seat *seat, struct terminal *term, uint32_t serial, void (*cb)(const char *data, size_t size, void *user), void (*done)(void *user), void *user) { -#if 0 - struct wl_clipboard *clipboard = &term->wl->clipboard; + struct wl_clipboard *clipboard = &seat->clipboard; if (clipboard->data_offer == NULL) return done(user); @@ -1122,18 +1113,15 @@ text_from_clipboard(struct terminal *term, uint32_t serial, close(write_fd); begin_receive_clipboard(term, read_fd, cb, done, user); -#endif } -#if 0 static void from_clipboard_cb(const char *data, size_t size, void *user) { struct terminal *term = user; term_to_slave(term, data, size); } -#endif -#if 0 + static void from_clipboard_done(void *user) { @@ -1142,12 +1130,11 @@ from_clipboard_done(void *user) if (term->bracketed_paste) term_to_slave(term, "\033[201~", 6); } -#endif + void -selection_from_clipboard(struct terminal *term, uint32_t serial) +selection_from_clipboard(struct seat *seat, struct terminal *term, uint32_t serial) { -#if 0 - struct wl_clipboard *clipboard = &term->wl->clipboard; + struct wl_clipboard *clipboard = &seat->clipboard; if (clipboard->data_offer == NULL) return; @@ -1155,26 +1142,24 @@ selection_from_clipboard(struct terminal *term, uint32_t serial) term_to_slave(term, "\033[200~", 6); text_from_clipboard( - term, serial, &from_clipboard_cb, &from_clipboard_done, term); -#endif + seat, term, serial, &from_clipboard_cb, &from_clipboard_done, term); } bool -text_to_primary(struct terminal *term, char *text, uint32_t serial) +text_to_primary(struct seat *seat, struct terminal *term, char *text, uint32_t serial) { -#if 0 if (term->wl->primary_selection_device_manager == NULL) return false; - struct wl_primary *primary = &term->wl->primary; + struct wl_primary *primary = &seat->primary; /* TODO: somehow share code with the clipboard equivalent */ - if (term->wl->primary.data_source != NULL) { + if (seat->primary.data_source != NULL) { /* Kill previous data source */ assert(primary->serial != 0); zwp_primary_selection_device_v1_set_selection( - term->wl->primary_selection_device, NULL, primary->serial); + seat->primary_selection_device, NULL, primary->serial); zwp_primary_selection_source_v1_destroy(primary->data_source); free(primary->text); @@ -1196,39 +1181,36 @@ text_to_primary(struct terminal *term, char *text, uint32_t serial) /* Configure source */ zwp_primary_selection_source_v1_offer(primary->data_source, "text/plain;charset=utf-8"); - zwp_primary_selection_source_v1_add_listener(primary->data_source, &primary_selection_source_listener, term->wl); - zwp_primary_selection_device_v1_set_selection(term->wl->primary_selection_device, primary->data_source, serial); + zwp_primary_selection_source_v1_add_listener(primary->data_source, &primary_selection_source_listener, seat); + zwp_primary_selection_device_v1_set_selection(seat->primary_selection_device, primary->data_source, serial); /* Needed when sending the selection to other client */ primary->serial = serial; return true; -#endif - return false; } void -selection_to_primary(struct terminal *term, uint32_t serial) +selection_to_primary(struct seat *seat, struct terminal *term, uint32_t serial) { if (term->wl->primary_selection_device_manager == NULL) return; /* Get selection as a string */ char *text = extract_selection(term); - if (!text_to_primary(term, text, serial)) + if (!text_to_primary(seat, term, text, serial)) free(text); } void text_from_primary( - struct terminal *term, + struct seat *seat, struct terminal *term, void (*cb)(const char *data, size_t size, void *user), void (*done)(void *user), void *user) { -#if 0 if (term->wl->primary_selection_device_manager == NULL) return done(user); - struct wl_primary *primary = &term->wl->primary; + struct wl_primary *primary = &seat->primary; if (primary->data_offer == NULL) return done(user); @@ -1250,25 +1232,22 @@ text_from_primary( close(write_fd); begin_receive_clipboard(term, read_fd, cb, done, user); -#endif } void -selection_from_primary(struct terminal *term) +selection_from_primary(struct seat *seat, struct terminal *term) { -#if 0 if (term->wl->primary_selection_device_manager == NULL) return; - struct wl_clipboard *clipboard = &term->wl->clipboard; + struct wl_clipboard *clipboard = &seat->clipboard; if (clipboard->data_offer == NULL) return; if (term->bracketed_paste) term_to_slave(term, "\033[200~", 6); - text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, term); -#endif + text_from_primary(seat, term, &from_clipboard_cb, &from_clipboard_done, term); } #if 0 @@ -1328,11 +1307,10 @@ static void selection(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id) { -#if 0 /* Selection offer from other client */ - struct wayland *wayl = data; - struct wl_clipboard *clipboard = &wayl->clipboard; + struct seat *seat = data; + struct wl_clipboard *clipboard = &seat->clipboard; if (clipboard->data_offer != NULL) wl_data_offer_destroy(clipboard->data_offer); @@ -1342,7 +1320,6 @@ selection(void *data, struct wl_data_device *wl_data_device, if (id != NULL) wl_data_offer_add_listener(id, &data_offer_listener, term); #endif -#endif } const struct wl_data_device_listener data_device_listener = { @@ -1379,11 +1356,10 @@ primary_selection(void *data, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device, struct zwp_primary_selection_offer_v1 *id) { -#if 0 /* Selection offer from other client, for primary */ - struct wayland *wayl = data; - struct wl_primary *primary = &wayl->primary; + struct seat *seat = data; + struct wl_primary *primary = &seat->primary; if (primary->data_offer != NULL) zwp_primary_selection_offer_v1_destroy(primary->data_offer); @@ -1395,7 +1371,6 @@ primary_selection(void *data, id, &primary_selection_offer_listener, term); } #endif -#endif } const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = { diff --git a/selection.h b/selection.h index 758d5d29..e049f182 100644 --- a/selection.h +++ b/selection.h @@ -12,28 +12,37 @@ bool selection_enabled(const struct terminal *term); void selection_start( struct terminal *term, int col, int row, enum selection_kind kind); void selection_update(struct terminal *term, int col, int row); -void selection_finalize(struct terminal *term, uint32_t serial); +void selection_finalize( + struct seat *seat, struct terminal *term, uint32_t serial); void selection_dirty_cells(struct terminal *term); void selection_cancel(struct terminal *term); -void selection_extend(struct terminal *term, int col, int row, uint32_t serial); +void selection_extend( struct seat *seat, struct terminal *term, + int col, int row, uint32_t serial); bool selection_on_rows(const struct terminal *term, int start, int end); void selection_view_up(struct terminal *term, int new_view); void selection_view_down(struct terminal *term, int new_view); -void selection_mark_word(struct terminal *term, int col, int row, - bool spaces_only, uint32_t serial); -void selection_mark_row(struct terminal *term, int row, uint32_t serial); +void selection_mark_word( + struct seat *seat, struct terminal *term, int col, int row, + bool spaces_only, uint32_t serial); +void selection_mark_row( + struct seat *seat, struct terminal *term, int row, uint32_t serial); -void selection_to_clipboard(struct terminal *term, uint32_t serial); -void selection_from_clipboard(struct terminal *term, uint32_t serial); -void selection_to_primary(struct terminal *term, uint32_t serial); -void selection_from_primary(struct terminal *term); +void selection_to_clipboard( + struct seat *seat, struct terminal *term, uint32_t serial); +void selection_from_clipboard( + struct seat *seat, struct terminal *term, uint32_t serial); +void selection_to_primary( + struct seat *seat, struct terminal *term, uint32_t serial); +void selection_from_primary(struct seat *seat, struct terminal *term); /* Copy text *to* primary/clipboard */ -bool text_to_clipboard(struct terminal *term, char *text, uint32_t serial); -bool text_to_primary(struct terminal *term, char *text, uint32_t serial); +bool text_to_clipboard( + struct seat *seat, struct terminal *term, char *text, uint32_t serial); +bool text_to_primary( + struct seat *seat, struct terminal *term, char *text, uint32_t serial); /* * Copy text *from* primary/clipboard @@ -50,11 +59,11 @@ bool text_to_primary(struct terminal *term, char *text, uint32_t serial); * point). */ void text_from_clipboard( - struct terminal *term, uint32_t serial, + struct seat *seat, struct terminal *term, uint32_t serial, void (*cb)(const char *data, size_t size, void *user), void (*done)(void *user), void *user); void text_from_primary( - struct terminal *term, + struct seat *seat, struct terminal *term, void (*cb)(const char *data, size_t size, void *user), void (*dont)(void *user), void *user); diff --git a/wayland.c b/wayland.c index 54d65927..f9ec4483 100644 --- a/wayland.c +++ b/wayland.c @@ -106,6 +106,14 @@ seat_destroy(struct seat *seat) if (seat->pointer.xcursor_callback != NULL) wl_callback_destroy(seat->pointer.xcursor_callback); + if (seat->clipboard.data_source != NULL) + wl_data_source_destroy(seat->clipboard.data_source); + if (seat->clipboard.data_offer != NULL) + wl_data_offer_destroy(seat->clipboard.data_offer); + if (seat->primary.data_source != NULL) + zwp_primary_selection_source_v1_destroy(seat->primary.data_source); + if (seat->primary.data_offer != NULL) + zwp_primary_selection_offer_v1_destroy(seat->primary.data_offer); if (seat->primary_selection_device != NULL) zwp_primary_selection_device_v1_destroy(seat->primary_selection_device); if (seat->data_device != NULL)