diff --git a/input.c b/input.c index edfca2f7..75a80b2f 100644 --- a/input.c +++ b/input.c @@ -206,57 +206,58 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, LOG_DBG("keyboard_keymap: keyboard=%p (format=%u, size=%u)", wl_keyboard, format, size); - struct wayland *wayl = data; + struct seat *seat = data; + struct wayland *wayl = seat->wayl; char *map_str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - if (wayl->kbd.xkb_compose_state != NULL) { - xkb_compose_state_unref(wayl->kbd.xkb_compose_state); - wayl->kbd.xkb_compose_state = NULL; + if (seat->kbd.xkb_compose_state != NULL) { + xkb_compose_state_unref(seat->kbd.xkb_compose_state); + seat->kbd.xkb_compose_state = NULL; } - if (wayl->kbd.xkb_compose_table != NULL) { - xkb_compose_table_unref(wayl->kbd.xkb_compose_table); - wayl->kbd.xkb_compose_table = NULL; + if (seat->kbd.xkb_compose_table != NULL) { + xkb_compose_table_unref(seat->kbd.xkb_compose_table); + seat->kbd.xkb_compose_table = NULL; } - if (wayl->kbd.xkb_keymap != NULL) { - xkb_keymap_unref(wayl->kbd.xkb_keymap); - wayl->kbd.xkb_keymap = NULL; + if (seat->kbd.xkb_keymap != NULL) { + xkb_keymap_unref(seat->kbd.xkb_keymap); + seat->kbd.xkb_keymap = NULL; } - if (wayl->kbd.xkb_state != NULL) { - xkb_state_unref(wayl->kbd.xkb_state); - wayl->kbd.xkb_state = NULL; + if (seat->kbd.xkb_state != NULL) { + xkb_state_unref(seat->kbd.xkb_state); + seat->kbd.xkb_state = NULL; } - if (wayl->kbd.xkb != NULL) { - xkb_context_unref(wayl->kbd.xkb); - wayl->kbd.xkb = NULL; + if (seat->kbd.xkb != NULL) { + xkb_context_unref(seat->kbd.xkb); + seat->kbd.xkb = NULL; } - tll_foreach(wayl->kbd.bindings.key, it) + tll_foreach(seat->kbd.bindings.key, it) tll_free(it->item.bind.key_codes); - tll_free(wayl->kbd.bindings.key); + tll_free(seat->kbd.bindings.key); - tll_foreach(wayl->kbd.bindings.search, it) + tll_foreach(seat->kbd.bindings.search, it) tll_free(it->item.bind.key_codes); - tll_free(wayl->kbd.bindings.search); + tll_free(seat->kbd.bindings.search); - wayl->kbd.xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - wayl->kbd.xkb_keymap = xkb_keymap_new_from_string( - wayl->kbd.xkb, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, + seat->kbd.xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + seat->kbd.xkb_keymap = xkb_keymap_new_from_string( + seat->kbd.xkb, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); /* TODO: initialize in enter? */ - wayl->kbd.xkb_state = xkb_state_new(wayl->kbd.xkb_keymap); + seat->kbd.xkb_state = xkb_state_new(seat->kbd.xkb_keymap); - wayl->kbd.mod_shift = xkb_keymap_mod_get_index(wayl->kbd.xkb_keymap, "Shift"); - wayl->kbd.mod_alt = xkb_keymap_mod_get_index(wayl->kbd.xkb_keymap, "Mod1") ; - wayl->kbd.mod_ctrl = xkb_keymap_mod_get_index(wayl->kbd.xkb_keymap, "Control"); - wayl->kbd.mod_meta = xkb_keymap_mod_get_index(wayl->kbd.xkb_keymap, "Mod4"); + seat->kbd.mod_shift = xkb_keymap_mod_get_index(seat->kbd.xkb_keymap, "Shift"); + seat->kbd.mod_alt = xkb_keymap_mod_get_index(seat->kbd.xkb_keymap, "Mod1") ; + seat->kbd.mod_ctrl = xkb_keymap_mod_get_index(seat->kbd.xkb_keymap, "Control"); + seat->kbd.mod_meta = xkb_keymap_mod_get_index(seat->kbd.xkb_keymap, "Mod4"); /* Compose (dead keys) */ - wayl->kbd.xkb_compose_table = xkb_compose_table_new_from_locale( - wayl->kbd.xkb, setlocale(LC_CTYPE, NULL), XKB_COMPOSE_COMPILE_NO_FLAGS); - wayl->kbd.xkb_compose_state = xkb_compose_state_new( - wayl->kbd.xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS); + seat->kbd.xkb_compose_table = xkb_compose_table_new_from_locale( + seat->kbd.xkb, setlocale(LC_CTYPE, NULL), XKB_COMPOSE_COMPILE_NO_FLAGS); + seat->kbd.xkb_compose_state = xkb_compose_state_new( + seat->kbd.xkb_compose_table, XKB_COMPOSE_STATE_NO_FLAGS); munmap(map_str, size); close(fd); @@ -264,11 +265,11 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, for (enum bind_action_normal i = 0; i < BIND_ACTION_COUNT; i++) { key_binding_list_t bindings = tll_init(); input_parse_key_binding( - wayl->kbd.xkb_keymap, wayl->conf->bindings.key[i], &bindings); + seat->kbd.xkb_keymap, wayl->conf->bindings.key[i], &bindings); tll_foreach(bindings, it) { tll_push_back( - wayl->kbd.bindings.key, + seat->kbd.bindings.key, ((struct key_binding_normal){.bind = it->item, .action = i})); } @@ -278,11 +279,11 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, for (enum bind_action_search i = 0; i < BIND_ACTION_SEARCH_COUNT; i++) { key_binding_list_t bindings = tll_init(); input_parse_key_binding( - wayl->kbd.xkb_keymap, wayl->conf->bindings.search[i], &bindings); + seat->kbd.xkb_keymap, wayl->conf->bindings.search[i], &bindings); tll_foreach(bindings, it) { tll_push_back( - wayl->kbd.bindings.search, + seat->kbd.bindings.search, ((struct key_binding_search){.bind = it->item, .action = i})); } @@ -296,28 +297,28 @@ keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, { assert(surface != NULL); - struct wayland *wayl = data; + struct seat *seat = data; struct wl_window *win = wl_surface_get_user_data(surface); struct terminal *term = win->term; LOG_DBG("keyboard_enter: keyboard=%p, serial=%u, surface=%p", wl_keyboard, serial, surface); - wayl->kbd_focus = term; - wayl->input_serial = serial; + seat->kbd_focus = term; + seat->input_serial = serial; - term_kbd_focus_in(wayl->kbd_focus); + term_kbd_focus_in(seat->kbd_focus); } static bool -start_repeater(struct wayland *wayl, uint32_t key) +start_repeater(struct seat *seat, uint32_t key) { - if (wayl->kbd.repeat.dont_re_repeat) + if (seat->kbd.repeat.dont_re_repeat) return true; struct itimerspec t = { - .it_value = {.tv_sec = 0, .tv_nsec = wayl->kbd.repeat.delay * 1000000}, - .it_interval = {.tv_sec = 0, .tv_nsec = 1000000000 / wayl->kbd.repeat.rate}, + .it_value = {.tv_sec = 0, .tv_nsec = seat->kbd.repeat.delay * 1000000}, + .it_interval = {.tv_sec = 0, .tv_nsec = 1000000000 / seat->kbd.repeat.rate}, }; if (t.it_value.tv_nsec >= 1000000000) { @@ -328,23 +329,23 @@ start_repeater(struct wayland *wayl, uint32_t key) t.it_interval.tv_sec += t.it_interval.tv_nsec / 1000000000; t.it_interval.tv_nsec %= 1000000000; } - if (timerfd_settime(wayl->kbd.repeat.fd, 0, &t, NULL) < 0) { - LOG_ERRNO("failed to arm keyboard repeat timer"); + if (timerfd_settime(seat->kbd.repeat.fd, 0, &t, NULL) < 0) { + LOG_ERRNO("%s: failed to arm keyboard repeat timer", seat->name); return false; } - wayl->kbd.repeat.key = key; + seat->kbd.repeat.key = key; return true; } static bool -stop_repeater(struct wayland *wayl, uint32_t key) +stop_repeater(struct seat *seat, uint32_t key) { - if (key != -1 && key != wayl->kbd.repeat.key) + if (key != -1 && key != seat->kbd.repeat.key) return true; - if (timerfd_settime(wayl->kbd.repeat.fd, 0, &(struct itimerspec){}, NULL) < 0) { - LOG_ERRNO("failed to disarm keyboard repeat timer"); + if (timerfd_settime(seat->kbd.repeat.fd, 0, &(struct itimerspec){}, NULL) < 0) { + LOG_ERRNO("%s: failed to disarm keyboard repeat timer", seat->name); return false; } @@ -355,26 +356,26 @@ static void keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface) { - struct wayland *wayl = data; + struct seat *seat = data; LOG_DBG("keyboard_leave: keyboard=%p, serial=%u, surface=%p", wl_keyboard, serial, surface); assert( - wayl->kbd_focus == NULL || + seat->kbd_focus == NULL || surface == NULL || /* Seen on Sway 1.2 */ - ((const struct wl_window *)wl_surface_get_user_data(surface))->term == wayl->kbd_focus + ((const struct wl_window *)wl_surface_get_user_data(surface))->term == seat->kbd_focus ); - struct terminal *old_focused = wayl->kbd_focus; - wayl->kbd_focus = NULL; + struct terminal *old_focused = seat->kbd_focus; + seat->kbd_focus = NULL; - stop_repeater(wayl, -1); - wayl->kbd.shift = false;; - wayl->kbd.alt = false;; - wayl->kbd.ctrl = false;; - wayl->kbd.meta = false;; - xkb_compose_state_reset(wayl->kbd.xkb_compose_state); + stop_repeater(seat, -1); + seat->kbd.shift = false;; + seat->kbd.alt = false;; + seat->kbd.ctrl = false;; + seat->kbd.meta = false;; + xkb_compose_state_reset(seat->kbd.xkb_compose_state); if (old_focused != NULL) term_kbd_focus_out(old_focused); @@ -508,24 +509,24 @@ static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - struct wayland *wayl = data; - struct terminal *term = wayl->kbd_focus; + struct seat *seat = data; + struct terminal *term = seat->kbd_focus; assert(term != NULL); - const xkb_mod_mask_t ctrl = 1 << wayl->kbd.mod_ctrl; - const xkb_mod_mask_t alt = 1 << wayl->kbd.mod_alt; - const xkb_mod_mask_t shift = 1 << wayl->kbd.mod_shift; - const xkb_mod_mask_t meta = 1 << wayl->kbd.mod_meta; + const xkb_mod_mask_t ctrl = 1 << seat->kbd.mod_ctrl; + const xkb_mod_mask_t alt = 1 << seat->kbd.mod_alt; + const xkb_mod_mask_t shift = 1 << seat->kbd.mod_shift; + const xkb_mod_mask_t meta = 1 << seat->kbd.mod_meta; if (state == XKB_KEY_UP) { - stop_repeater(wayl, key); + stop_repeater(seat, key); return; } key += 8; - bool should_repeat = xkb_keymap_key_repeats(wayl->kbd.xkb_keymap, key); - xkb_keysym_t sym = xkb_state_key_get_one_sym(wayl->kbd.xkb_state, key); + bool should_repeat = xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key); + xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->kbd.xkb_state, key); #if 0 char foo[100]; @@ -533,9 +534,9 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, LOG_INFO("%s", foo); #endif - xkb_compose_state_feed(wayl->kbd.xkb_compose_state, sym); + xkb_compose_state_feed(seat->kbd.xkb_compose_state, sym); enum xkb_compose_status compose_status = xkb_compose_state_get_status( - wayl->kbd.xkb_compose_state); + seat->kbd.xkb_compose_state); if (compose_status == XKB_COMPOSE_COMPOSING) { /* TODO: goto maybe_repeat? */ @@ -543,15 +544,15 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, } xkb_mod_mask_t mods = xkb_state_serialize_mods( - wayl->kbd.xkb_state, XKB_STATE_MODS_DEPRESSED); - //xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods(wayl->kbd.xkb_state, key); + seat->kbd.xkb_state, XKB_STATE_MODS_DEPRESSED); + //xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods(seat->kbd.xkb_state, key); xkb_mod_mask_t consumed = 0x0; xkb_mod_mask_t significant = ctrl | alt | shift | meta; xkb_mod_mask_t effective_mods = mods & ~consumed & significant; if (term->is_searching) { if (should_repeat) - start_repeater(wayl, key - 8); + start_repeater(seat, key - 8); search_input(term, key, sym, effective_mods, serial); return; } @@ -559,7 +560,7 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, #if 0 for (size_t i = 0; i < 32; i++) { if (mods & (1 << i)) { - LOG_INFO("%s", xkb_keymap_mod_get_name(wayl->kbd.xkb_keymap, i)); + LOG_INFO("%s", xkb_keymap_mod_get_name(seat->kbd.xkb_keymap, i)); } } #endif @@ -573,7 +574,7 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, /* * User configurable bindings */ - tll_foreach(wayl->kbd.bindings.key, it) { + tll_foreach(seat->kbd.bindings.key, it) { if (it->item.bind.mods != effective_mods) continue; @@ -597,10 +598,10 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, */ enum modifier keymap_mods = MOD_NONE; - keymap_mods |= wayl->kbd.shift ? MOD_SHIFT : MOD_NONE; - keymap_mods |= wayl->kbd.alt ? MOD_ALT : MOD_NONE; - keymap_mods |= wayl->kbd.ctrl ? MOD_CTRL : MOD_NONE; - keymap_mods |= wayl->kbd.meta ? MOD_META : MOD_NONE; + keymap_mods |= seat->kbd.shift ? MOD_SHIFT : MOD_NONE; + keymap_mods |= seat->kbd.alt ? MOD_ALT : MOD_NONE; + keymap_mods |= seat->kbd.ctrl ? MOD_CTRL : MOD_NONE; + keymap_mods |= seat->kbd.meta ? MOD_META : MOD_NONE; const struct key_data *keymap = keymap_lookup(term, sym, keymap_mods); if (keymap != NULL) { @@ -620,13 +621,13 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, if (compose_status == XKB_COMPOSE_COMPOSED) { count = xkb_compose_state_get_utf8( - wayl->kbd.xkb_compose_state, (char *)buf, sizeof(buf)); - xkb_compose_state_reset(wayl->kbd.xkb_compose_state); + seat->kbd.xkb_compose_state, (char *)buf, sizeof(buf)); + xkb_compose_state_reset(seat->kbd.xkb_compose_state); } else if (compose_status == XKB_COMPOSE_CANCELLED) { goto maybe_repeat; } else { count = xkb_state_key_get_utf8( - wayl->kbd.xkb_state, key, (char *)buf, sizeof(buf)); + seat->kbd.xkb_state, key, (char *)buf, sizeof(buf)); } if (count == 0) @@ -720,7 +721,7 @@ maybe_repeat: term->wl->presentation_clock_id, &term->render.input_time); if (should_repeat) - start_repeater(wayl, key - 8); + start_repeater(seat, key - 8); } @@ -729,36 +730,36 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - struct wayland *wayl = data; + struct seat *seat = data; LOG_DBG("modifiers: depressed=0x%x, latched=0x%x, locked=0x%x, group=%u", mods_depressed, mods_latched, mods_locked, group); xkb_state_update_mask( - wayl->kbd.xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); + seat->kbd.xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); /* Update state of modifiers we're interrested in for e.g mouse events */ - wayl->kbd.shift = xkb_state_mod_index_is_active( - wayl->kbd.xkb_state, wayl->kbd.mod_shift, XKB_STATE_MODS_DEPRESSED); - wayl->kbd.alt = xkb_state_mod_index_is_active( - wayl->kbd.xkb_state, wayl->kbd.mod_alt, XKB_STATE_MODS_DEPRESSED); - wayl->kbd.ctrl = xkb_state_mod_index_is_active( - wayl->kbd.xkb_state, wayl->kbd.mod_ctrl, XKB_STATE_MODS_DEPRESSED); - wayl->kbd.meta = xkb_state_mod_index_is_active( - wayl->kbd.xkb_state, wayl->kbd.mod_meta, XKB_STATE_MODS_DEPRESSED); + seat->kbd.shift = xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_shift, XKB_STATE_MODS_DEPRESSED); + seat->kbd.alt = xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_alt, XKB_STATE_MODS_DEPRESSED); + seat->kbd.ctrl = xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_ctrl, XKB_STATE_MODS_DEPRESSED); + seat->kbd.meta = xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_meta, XKB_STATE_MODS_DEPRESSED); - if (wayl->kbd_focus && wayl->kbd_focus->active_surface == TERM_SURF_GRID) - term_xcursor_update(wayl->kbd_focus); + if (seat->kbd_focus && seat->kbd_focus->active_surface == TERM_SURF_GRID) + term_xcursor_update(seat->kbd_focus); } static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) { - struct wayland *wayl = data; + struct seat *seat = data; LOG_DBG("keyboard repeat: rate=%d, delay=%d", rate, delay); - wayl->kbd.repeat.rate = rate; - wayl->kbd.repeat.delay = delay; + seat->kbd.repeat.rate = rate; + seat->kbd.repeat.delay = delay; } const struct wl_keyboard_listener keyboard_listener = { @@ -771,9 +772,9 @@ const struct wl_keyboard_listener keyboard_listener = { }; void -input_repeat(struct wayland *wayl, uint32_t key) +input_repeat(struct seat *seat, uint32_t key) { - keyboard_key(wayl, NULL, wayl->input_serial, 0, key, XKB_KEY_DOWN); + keyboard_key(seat, NULL, seat->input_serial, 0, key, XKB_KEY_DOWN); } static bool @@ -838,22 +839,22 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, { assert(surface != NULL); - struct wayland *wayl = data; + struct seat *seat = data; struct wl_window *win = wl_surface_get_user_data(surface); struct terminal *term = win->term; LOG_DBG("pointer-enter: pointer=%p, serial=%u, surface = %p, new-moused = %p", wl_pointer, serial, surface, term); - wayl->mouse_focus = term; + seat->mouse_focus = term; int x = wl_fixed_to_int(surface_x) * term->scale; int y = wl_fixed_to_int(surface_y) * term->scale; switch ((term->active_surface = term_surface_kind(term, surface))) { case TERM_SURF_GRID: - wayl->mouse.col = x / term->cell_width; - wayl->mouse.row = y / term->cell_height; + seat->mouse.col = x / term->cell_width; + seat->mouse.row = y / term->cell_height; term_xcursor_update(term); break; @@ -889,25 +890,25 @@ static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) { - struct wayland *wayl = data; - struct terminal *old_moused = wayl->mouse_focus; + struct seat *seat = data; + struct terminal *old_moused = seat->mouse_focus; LOG_DBG( "pointer-leave: pointer=%p, serial=%u, surface = %p, old-moused = %p", wl_pointer, serial, surface, old_moused); - if (wayl->pointer.xcursor_callback != NULL) { + if (seat->pointer.xcursor_callback != NULL) { /* A cursor frame callback may never be called if the pointer leaves our surface */ - wl_callback_destroy(wayl->pointer.xcursor_callback); - wayl->pointer.xcursor_callback = NULL; - wayl->pointer.pending_terminal = NULL; - wayl->pointer.xcursor = NULL; + wl_callback_destroy(seat->pointer.xcursor_callback); + seat->pointer.xcursor_callback = NULL; + seat->pointer.pending_terminal = NULL; + seat->pointer.xcursor = NULL; } /* Reset mouse state */ - memset(&wayl->mouse, 0, sizeof(wayl->mouse)); + memset(&seat->mouse, 0, sizeof(seat->mouse)); - wayl->mouse_focus = NULL; + seat->mouse_focus = NULL; if (old_moused == NULL) { LOG_WARN( "compositor sent pointer_leave event without a pointer_enter " @@ -953,8 +954,9 @@ static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - struct wayland *wayl = data; - struct terminal *term = wayl->mouse_focus; + struct seat *seat = data; + struct wayland *wayl = seat->wayl; + struct terminal *term = seat->mouse_focus; struct wl_window *win = term->window; LOG_DBG("pointer_motion: pointer=%p, x=%d, y=%d", wl_pointer, @@ -965,8 +967,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, int x = wl_fixed_to_int(surface_x) * term->scale; int y = wl_fixed_to_int(surface_y) * term->scale; - wayl->mouse.x = x; - wayl->mouse.y = y; + seat->mouse.x = x; + seat->mouse.y = y; switch (term->active_surface) { case TERM_SURF_NONE: @@ -980,10 +982,10 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, /* We've started a 'move' timer, but user started dragging * right away - abort the timer and initiate the actual move * right away */ - if (wayl->mouse.button == BTN_LEFT && win->csd.move_timeout_fd != -1) { + if (seat->mouse.button == BTN_LEFT && win->csd.move_timeout_fd != -1) { fdm_del(wayl->fdm, win->csd.move_timeout_fd); win->csd.move_timeout_fd = -1; - xdg_toplevel_move(win->xdg_toplevel, wayl->seat, win->csd.serial); + xdg_toplevel_move(win->xdg_toplevel, seat->wl_seat, win->csd.serial); } break; @@ -1002,23 +1004,23 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, if (col < 0 || row < 0 || col >= term->cols || row >= term->rows) return; - bool update_selection = wayl->mouse.button == BTN_LEFT; + bool update_selection = seat->mouse.button == BTN_LEFT; bool update_selection_early = term->selection.end.row == -1; if (update_selection && update_selection_early) selection_update(term, col, row); - if (col == wayl->mouse.col && row == wayl->mouse.row) + if (col == seat->mouse.col && row == seat->mouse.row) break; - wayl->mouse.col = col; - wayl->mouse.row = row; + seat->mouse.col = col; + seat->mouse.row = row; if (update_selection && !update_selection_early) selection_update(term, col, row); term_mouse_motion( - term, wayl->mouse.button, wayl->mouse.row, wayl->mouse.col); + term, seat->mouse.button, seat->mouse.row, seat->mouse.col); break; } } @@ -1027,13 +1029,20 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, static bool fdm_csd_move(struct fdm *fdm, int fd, int events, void *data) { - struct wl_window *win = data; - struct wayland *wayl = win->term->wl; - + struct seat *seat = data; fdm_del(fdm, fd); - win->csd.move_timeout_fd = -1; - xdg_toplevel_move(win->xdg_toplevel, wayl->seat, win->csd.serial); + if (seat->mouse_focus == NULL) { + LOG_WARN( + "%s: CSD move timeout triggered, but seat's has no mouse focused terminal", + seat->name); + return true; + } + + struct wl_window *win = seat->mouse_focus->window; + + win->csd.move_timeout_fd = -1; + xdg_toplevel_move(win->xdg_toplevel, seat->wl_seat, win->csd.serial); return true; } @@ -1044,8 +1053,9 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, LOG_DBG("BUTTON: pointer=%p, serial=%u, button=%x, state=%u", wl_pointer, serial, button, state); - struct wayland *wayl = data; - struct terminal *term = wayl->mouse_focus; + struct seat *seat = data; + struct wayland *wayl = seat->wayl; + struct terminal *term = seat->mouse_focus; assert(term != NULL); @@ -1054,22 +1064,22 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, /* Time since last click */ struct timeval now, since_last; gettimeofday(&now, NULL); - timersub(&now, &wayl->mouse.last_time, &since_last); + timersub(&now, &seat->mouse.last_time, &since_last); /* Double- or triple click? */ - if (button == wayl->mouse.last_button && + if (button == seat->mouse.last_button && since_last.tv_sec == 0 && since_last.tv_usec <= 300 * 1000) { - wayl->mouse.count++; + seat->mouse.count++; } else - wayl->mouse.count = 1; + seat->mouse.count = 1; - wayl->mouse.button = button; /* For motion events */ - wayl->mouse.last_button = button; - wayl->mouse.last_time = now; + seat->mouse.button = button; /* For motion events */ + seat->mouse.last_button = button; + seat->mouse.last_time = now; } else - wayl->mouse.button = 0; /* For motion events */ + seat->mouse.button = 0; /* For motion events */ switch (term->active_surface) { case TERM_SURF_TITLE: @@ -1078,7 +1088,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, struct wl_window *win = term->window; /* Toggle maximized state on double-click */ - if (button == BTN_LEFT && wayl->mouse.count == 2) { + if (button == BTN_LEFT && seat->mouse.count == 2) { if (win->is_maximized) xdg_toplevel_unset_maximized(win->xdg_toplevel); else @@ -1093,7 +1103,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); if (fd >= 0 && timerfd_settime(fd, 0, &timeout, NULL) == 0 && - fdm_add(wayl->fdm, fd, EPOLLIN, &fdm_csd_move, win)) + fdm_add(wayl->fdm, fd, EPOLLIN, &fdm_csd_move, seat)) { win->csd.move_timeout_fd = fd; win->csd.serial = serial; @@ -1127,8 +1137,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED) { enum xdg_toplevel_resize_edge resize_type; - int x = wayl->mouse.x; - int y = wayl->mouse.y; + int x = seat->mouse.x; + int y = seat->mouse.y; if (is_top_left(term, x, y)) resize_type = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; @@ -1142,7 +1152,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, resize_type = map[term->active_surface]; xdg_toplevel_resize( - term->window->xdg_toplevel, term->wl->seat, serial, resize_type); + term->window->xdg_toplevel, seat->wl_seat, serial, resize_type); } return; } @@ -1174,32 +1184,32 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, switch (state) { case WL_POINTER_BUTTON_STATE_PRESSED: { - if (button == BTN_LEFT && wayl->mouse.count <= 3) { + if (button == BTN_LEFT && seat->mouse.count <= 3) { selection_cancel(term); if (selection_enabled(term)) { - switch (wayl->mouse.count) { + switch (seat->mouse.count) { case 1: selection_start( - term, wayl->mouse.col, wayl->mouse.row, - wayl->kbd.ctrl ? SELECTION_BLOCK : SELECTION_NORMAL); + term, seat->mouse.col, seat->mouse.row, + seat->kbd.ctrl ? SELECTION_BLOCK : SELECTION_NORMAL); break; case 2: - selection_mark_word(term, wayl->mouse.col, wayl->mouse.row, - wayl->kbd.ctrl, serial); + selection_mark_word(term, seat->mouse.col, seat->mouse.row, + seat->kbd.ctrl, serial); break; case 3: - selection_mark_row(term, wayl->mouse.row, serial); + selection_mark_row(term, seat->mouse.row, serial); break; } } } - else if (button == BTN_RIGHT && wayl->mouse.count == 1) { + else if (button == BTN_RIGHT && seat->mouse.count == 1) { if (selection_enabled(term)) - selection_extend(term, wayl->mouse.col, wayl->mouse.row, serial); + selection_extend(term, seat->mouse.col, seat->mouse.row, serial); } else { @@ -1212,7 +1222,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, continue; } - if (binding->count != wayl->mouse.count) { + if (binding->count != seat->mouse.count) { /* Not correct click count */ continue; } @@ -1222,7 +1232,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, } } - term_mouse_down(term, button, wayl->mouse.row, wayl->mouse.col); + term_mouse_down(term, button, seat->mouse.row, seat->mouse.col); break; } @@ -1230,7 +1240,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, if (button == BTN_LEFT && term->selection.end.col != -1) selection_finalize(term, serial); - term_mouse_up(term, button, wayl->mouse.row, wayl->mouse.col); + term_mouse_up(term, button, seat->mouse.row, seat->mouse.col); break; } break; @@ -1244,9 +1254,9 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, } static void -mouse_scroll(struct wayland *wayl, int amount) +mouse_scroll(struct seat *seat, int amount) { - struct terminal *term = wayl->mouse_focus; + struct terminal *term = seat->mouse_focus; assert(term != NULL); int button = amount < 0 ? BTN_BACK : BTN_FORWARD; @@ -1268,19 +1278,19 @@ mouse_scroll(struct wayland *wayl, int amount) static xkb_keycode_t key_arrow_down = 0; if (key_arrow_up == 0) { - key_arrow_up = xkb_keymap_key_by_name(wayl->kbd.xkb_keymap, "UP"); - key_arrow_down = xkb_keymap_key_by_name(wayl->kbd.xkb_keymap, "DOWN"); + key_arrow_up = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "UP"); + key_arrow_down = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "DOWN"); } xkb_keycode_t key = button == BTN_BACK ? key_arrow_up : key_arrow_down; for (int i = 0; i < amount; i++) - keyboard_key(wayl, NULL, wayl->input_serial, 0, key - 8, XKB_KEY_DOWN); - keyboard_key(wayl, NULL, wayl->input_serial, 0, key - 8, XKB_KEY_UP); + keyboard_key(seat, NULL, seat->input_serial, 0, key - 8, XKB_KEY_DOWN); + keyboard_key(seat, NULL, seat->input_serial, 0, key - 8, XKB_KEY_UP); } else { for (int i = 0; i < amount; i++) - term_mouse_down(term, button, wayl->mouse.row, wayl->mouse.col); - term_mouse_up(term, button, wayl->mouse.row, wayl->mouse.col); + term_mouse_down(term, button, seat->mouse.row, seat->mouse.col); + term_mouse_up(term, button, seat->mouse.row, seat->mouse.col); scrollback(term, amount); } @@ -1293,9 +1303,9 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; - struct wayland *wayl = data; + struct seat *seat = data; - if (wayl->mouse.have_discrete) + if (seat->mouse.have_discrete) return; /* @@ -1304,11 +1314,11 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, * Without this, very slow scrolling will never actually scroll * anything. */ - wayl->mouse.axis_aggregated += wl_fixed_to_double(value); + seat->mouse.axis_aggregated += wl_fixed_to_double(value); - if (fabs(wayl->mouse.axis_aggregated) >= 1.) { - mouse_scroll(wayl, round(wayl->mouse.axis_aggregated)); - wayl->mouse.axis_aggregated = 0.; + if (fabs(seat->mouse.axis_aggregated) >= 1.) { + mouse_scroll(seat, round(seat->mouse.axis_aggregated)); + seat->mouse.axis_aggregated = 0.; } } @@ -1319,16 +1329,16 @@ wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; - struct wayland *wayl = data; - wayl->mouse.have_discrete = true; - mouse_scroll(wayl, discrete); + struct seat *seat = data; + seat->mouse.have_discrete = true; + mouse_scroll(seat, discrete); } static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { - struct wayland *wayl = data; - wayl->mouse.have_discrete = false; + struct seat *seat = data; + seat->mouse.have_discrete = false; } static void @@ -1344,8 +1354,8 @@ wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) return; - struct wayland *wayl = data; - wayl->mouse.axis_aggregated = 0.; + struct seat *seat = data; + seat->mouse.axis_aggregated = 0.; } const struct wl_pointer_listener pointer_listener = { diff --git a/input.h b/input.h index 553a6249..c1c14f7c 100644 --- a/input.h +++ b/input.h @@ -8,7 +8,7 @@ extern const struct wl_keyboard_listener keyboard_listener; extern const struct wl_pointer_listener pointer_listener; -void input_repeat(struct wayland *wayl, uint32_t key); +void input_repeat(struct seat *seat, uint32_t key); bool input_parse_key_binding(struct xkb_keymap *keymap, const char *combos, key_binding_list_t *bindings); diff --git a/osc.c b/osc.c index a2702595..1a72cb12 100644 --- a/osc.c +++ b/osc.c @@ -52,6 +52,9 @@ osc_to_clipboard(struct terminal *term, const char *target, } } + (void)to_clipboard; + (void)to_primary; +#if 0 if (to_clipboard) { char *copy = strdup(decoded); if (!text_to_clipboard(term, copy, term->wl->input_serial)) @@ -63,7 +66,7 @@ osc_to_clipboard(struct terminal *term, const char *target, if (!text_to_primary(term, copy, term->wl->input_serial)) free(copy); } - +#endif free(decoded); } @@ -73,6 +76,7 @@ struct clip_context { int idx; }; +#if 0 static void from_clipboard_cb(const char *text, size_t size, void *user) { @@ -117,7 +121,8 @@ from_clipboard_cb(const char *text, size_t size, void *user) term_to_slave(term, chunk, strlen(chunk)); free(chunk); } - +#endif +#if 0 static void from_clipboard_done(void *user) { @@ -133,7 +138,7 @@ from_clipboard_done(void *user) term_to_slave(term, "\033\\", 2); free(ctx); } - +#endif static void osc_from_clipboard(struct terminal *term, const char *source) { @@ -158,6 +163,7 @@ osc_from_clipboard(struct terminal *term, const char *source) struct clip_context *ctx = malloc(sizeof(*ctx)); *ctx = (struct clip_context) {.term = term}; +#if 0 switch (src) { case 'c': text_from_clipboard( @@ -170,6 +176,7 @@ osc_from_clipboard(struct terminal *term, const char *source) text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, ctx); break; } +#endif } static void diff --git a/render.c b/render.c index 391115d6..2a8869ee 100644 --- a/render.c +++ b/render.c @@ -1938,14 +1938,15 @@ render_resize_force(struct terminal *term, int width, int height) { return maybe_resize(term, width, height, true); } - +#if 0 static void xcursor_callback( void *data, struct wl_callback *wl_callback, uint32_t callback_data); - static const struct wl_callback_listener xcursor_listener = { .done = &xcursor_callback, }; +#endif +#if 0 static void render_xcursor_update(struct wayland *wayl, const struct terminal *term) { @@ -1984,7 +1985,9 @@ render_xcursor_update(struct wayland *wayl, const struct terminal *term) wl_surface_commit(wayl->pointer.surface); } +#endif +#if 0 static void xcursor_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_data) { @@ -1999,12 +2002,13 @@ xcursor_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_ wayl->pointer.pending_terminal = NULL; } } +#endif static void fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) { struct renderer *renderer = data; - struct wayland *wayl = renderer->wayl; + //struct wayland *wayl = renderer->wayl; tll_foreach(renderer->wayl->terms, it) { struct terminal *term = it->item; @@ -2061,6 +2065,7 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) } } +#if 0 if (wayl->pointer.pending_terminal != NULL) { if (wayl->pointer.xcursor_callback == NULL) { render_xcursor_update(wayl, wayl->pointer.pending_terminal); @@ -2069,6 +2074,7 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data) /* Frame callback will call render_xcursor_update() */ } } +#endif } void @@ -2100,6 +2106,7 @@ render_refresh_search(struct terminal *term) bool render_xcursor_set(struct terminal *term) { +#if 0 struct wayland *wayl = term->wl; if (wayl->pointer.theme == NULL) @@ -2122,4 +2129,6 @@ render_xcursor_set(struct terminal *term) /* FDM hook takes care of actual rendering */ wayl->pointer.pending_terminal = term; return true; +#endif + return true; } diff --git a/search.c b/search.c index eef7b032..7d52bf47 100644 --- a/search.c +++ b/search.c @@ -18,6 +18,7 @@ #include "shm.h" #include "util.h" +#if 0 static bool search_ensure_size(struct terminal *term, size_t wanted_size) { @@ -36,6 +37,7 @@ search_ensure_size(struct terminal *term, size_t wanted_size) return true; } +#endif static void search_cancel_keep_selection(struct terminal *term) @@ -99,6 +101,7 @@ search_cancel(struct terminal *term) selection_cancel(term); } +#if 0 static void search_update_selection(struct terminal *term, int start_row, int start_col, @@ -168,7 +171,8 @@ search_update_selection(struct terminal *term, selection_update(term, end_col, selection_row); } } - +#endif +#if 0 static void search_find_next(struct terminal *term) { @@ -281,7 +285,8 @@ search_find_next(struct terminal *term) selection_cancel(term); #undef ROW_DEC } - +#endif +#if 0 static void search_match_to_end_of_word(struct terminal *term, bool spaces_only) { @@ -356,7 +361,8 @@ search_match_to_end_of_word(struct terminal *term, bool spaces_only) search_update_selection( term, term->search.match.row, term->search.match.col, end_row, end_col); } - +#endif +#if 0 static size_t distance_next_word(const struct terminal *term) { @@ -384,7 +390,8 @@ distance_next_word(const struct terminal *term) return cursor - term->search.cursor; } - +#endif +#if 0 static size_t distance_prev_word(const struct terminal *term) { @@ -410,7 +417,8 @@ distance_prev_word(const struct terminal *term) return term->search.cursor - cursor; } - +#endif +#if 0 static bool execute_binding(struct terminal *term, enum bind_action_search action, uint32_t serial) @@ -429,8 +437,10 @@ execute_binding(struct terminal *term, enum bind_action_search action, return true; case BIND_ACTION_SEARCH_COMMIT: +#if 0 selection_finalize(term, term->wl->input_serial); search_cancel_keep_selection(term); +#endif return true; case BIND_ACTION_SEARCH_FIND_PREV: @@ -565,11 +575,13 @@ execute_binding(struct terminal *term, enum bind_action_search action, assert(false); return false; } +#endif void search_input(struct terminal *term, uint32_t key, xkb_keysym_t sym, xkb_mod_mask_t mods, uint32_t serial) { +#if 0 LOG_DBG("search: input: sym=%d/0x%x, mods=0x%08x", sym, sym, mods); enum xkb_compose_status compose_status = xkb_compose_state_get_status( @@ -641,4 +653,5 @@ update_search: LOG_DBG("search: buffer: %S", term->search.buf); search_find_next(term); render_refresh_search(term); +#endif } diff --git a/selection.c b/selection.c index ae6758f4..dd759e93 100644 --- a/selection.c +++ b/selection.c @@ -624,7 +624,7 @@ selection_extend(struct terminal *term, int col, int row, uint32_t serial) selection_to_primary(term, serial); } -static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener; +//static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener; void selection_finalize(struct terminal *term, uint32_t serial) @@ -741,6 +741,8 @@ selection_mark_row(struct terminal *term, int row, uint32_t serial) selection_finalize(term, serial); } + +#if 0 static void target(void *data, struct wl_data_source *wl_data_source, const char *mime_type) { @@ -865,7 +867,9 @@ 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, @@ -874,7 +878,8 @@ 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, @@ -942,15 +947,18 @@ 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) { +#if 0 struct wl_clipboard *clipboard = &term->wl->clipboard; if (clipboard->data_source != NULL) { @@ -983,6 +991,8 @@ text_to_clipboard(struct terminal *term, char *text, uint32_t serial) assert(serial != 0); clipboard->serial = serial; return true; +#endif + return false; } void @@ -1004,6 +1014,7 @@ struct clipboard_receive { void *user; }; +#if 0 static bool fdm_receive(struct fdm *fdm, int fd, int events, void *data) { @@ -1053,7 +1064,8 @@ 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), @@ -1081,12 +1093,13 @@ begin_receive_clipboard(struct terminal *term, int read_fd, done(user); } } - +#endif void text_from_clipboard(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; if (clipboard->data_offer == NULL) return done(user); @@ -1109,15 +1122,18 @@ 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) { @@ -1126,10 +1142,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) { +#if 0 struct wl_clipboard *clipboard = &term->wl->clipboard; if (clipboard->data_offer == NULL) return; @@ -1139,11 +1156,13 @@ selection_from_clipboard(struct terminal *term, uint32_t serial) text_from_clipboard( term, serial, &from_clipboard_cb, &from_clipboard_done, term); +#endif } bool text_to_primary(struct terminal *term, char *text, uint32_t serial) { +#if 0 if (term->wl->primary_selection_device_manager == NULL) return false; @@ -1183,6 +1202,8 @@ text_to_primary(struct terminal *term, char *text, uint32_t serial) /* Needed when sending the selection to other client */ primary->serial = serial; return true; +#endif + return false; } void @@ -1203,6 +1224,7 @@ text_from_primary( 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); @@ -1228,11 +1250,13 @@ text_from_primary( close(write_fd); begin_receive_clipboard(term, read_fd, cb, done, user); +#endif } void selection_from_primary(struct terminal *term) { +#if 0 if (term->wl->primary_selection_device_manager == NULL) return; @@ -1244,6 +1268,7 @@ selection_from_primary(struct terminal *term) term_to_slave(term, "\033[200~", 6); text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, term); +#endif } #if 0 @@ -1303,6 +1328,7 @@ 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; @@ -1316,6 +1342,7 @@ 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 = { @@ -1352,6 +1379,7 @@ 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; @@ -1367,6 +1395,7 @@ 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/terminal.c b/terminal.c index 0bb545e2..ec46bb76 100644 --- a/terminal.c +++ b/terminal.c @@ -1037,13 +1037,12 @@ fdm_shutdown(struct fdm *fdm, int fd, int events, void *data) * are deferred (for example, when a screen locker is active), and * thus we can get here without having been unmapped. */ - if (wayl->kbd_focus == term) - wayl->kbd_focus = NULL; - if (wayl->mouse_focus == term) - wayl->mouse_focus = NULL; - - assert(wayl->kbd_focus != term); - assert(wayl->mouse_focus != term); + tll_foreach(wayl->seats, it) { + if (it->item.kbd_focus == term) + it->item.kbd_focus = NULL; + if (it->item.mouse_focus == term) + it->item.mouse_focus = NULL; + } void (*cb)(void *, int) = term->shutdown_cb; void *cb_data = term->shutdown_data; @@ -1711,7 +1710,7 @@ void term_cursor_blink_enable(struct terminal *term) { term->cursor_blink.state = CURSOR_BLINK_ON; - term->cursor_blink.active = term->wl->kbd_focus == term + term->cursor_blink.active = term_has_kbd_focus(term) ? cursor_blink_start_timer(term) : true; } @@ -1728,7 +1727,7 @@ term_cursor_blink_restart(struct terminal *term) { if (term->cursor_blink.active) { term->cursor_blink.state = CURSOR_BLINK_ON; - term->cursor_blink.active = term->wl->kbd_focus == term + term->cursor_blink.active = term_has_kbd_focus(term) ? cursor_blink_start_timer(term) : true; } } @@ -1951,6 +1950,17 @@ term_visual_focus_out(struct terminal *term) cursor_refresh(term); } +bool +term_has_kbd_focus(struct terminal *term) +{ + tll_foreach(term->wl->seats, it) { + if (it->item.kbd_focus == term) + return true; + } + + return false; +} + void term_kbd_focus_in(struct terminal *term) { @@ -1965,6 +1975,7 @@ term_kbd_focus_out(struct terminal *term) term_to_slave(term, "\033[O", 3); } +#if 0 static int linux_mouse_button_to_x(int button) { @@ -1983,7 +1994,8 @@ linux_mouse_button_to_x(int button) return -1; } } - +#endif +#if 0 static int encode_xbutton(int xbutton) { @@ -2008,7 +2020,8 @@ encode_xbutton(int xbutton) return -1; } } - +#endif +#if 0 static void report_mouse_click(struct terminal *term, int encoded_button, int row, int col, bool release) @@ -2044,28 +2057,33 @@ report_mouse_click(struct terminal *term, int encoded_button, int row, int col, term_to_slave(term, response, strlen(response)); } - +#endif +#if 0 static void report_mouse_motion(struct terminal *term, int encoded_button, int row, int col) { report_mouse_click(term, encoded_button, row, col, false); } - +#endif bool term_mouse_grabbed(const struct terminal *term) { /* * Mouse is grabbed by us, regardless of whether mouse tracking has been enabled or not. */ +#if 0 return term->wl->kbd_focus == term && term->wl->kbd.shift && !term->wl->kbd.alt && /*!term->wl->kbd.ctrl &&*/ !term->wl->kbd.meta; +#endif + return true; } void term_mouse_down(struct terminal *term, int button, int row, int col) { +#if 0 if (term_mouse_grabbed(term)) return; @@ -2101,11 +2119,13 @@ term_mouse_down(struct terminal *term, int button, int row, int col) assert(false && "unimplemented"); break; } +#endif } void term_mouse_up(struct terminal *term, int button, int row, int col) { +#if 0 if (term_mouse_grabbed(term)) return; @@ -2145,11 +2165,13 @@ term_mouse_up(struct terminal *term, int button, int row, int col) assert(false && "unimplemented"); break; } +#endif } void term_mouse_motion(struct terminal *term, int button, int row, int col) { +#if 0 if (term_mouse_grabbed(term)) return; @@ -2194,6 +2216,7 @@ term_mouse_motion(struct terminal *term, int button, int row, int col) assert(false && "unimplemented"); break; } +#endif } void diff --git a/terminal.h b/terminal.h index bcbfbf4d..e28e3af7 100644 --- a/terminal.h +++ b/terminal.h @@ -506,6 +506,7 @@ void term_restore_cursor(struct terminal *term, const struct cursor *cursor); void term_visual_focus_in(struct terminal *term); void term_visual_focus_out(struct terminal *term); +bool term_has_kbd_focus(struct terminal *term); void term_kbd_focus_in(struct terminal *term); void term_kbd_focus_out(struct terminal *term); void term_mouse_down(struct terminal *term, int button, int row, int col); diff --git a/wayland.c b/wayland.c index ae7ead36..da4f658f 100644 --- a/wayland.c +++ b/wayland.c @@ -71,6 +71,59 @@ csd_destroy(struct wl_window *win) } } +static void +seat_destroy(struct seat *seat) +{ + if (seat == NULL) + return; + + tll_foreach(seat->kbd.bindings.key, it) + tll_free(it->item.bind.key_codes); + tll_free(seat->kbd.bindings.key); + + tll_foreach(seat->kbd.bindings.search, it) + tll_free(it->item.bind.key_codes); + tll_free(seat->kbd.bindings.search); + + if (seat->kbd.xkb_compose_state != NULL) + xkb_compose_state_unref(seat->kbd.xkb_compose_state); + if (seat->kbd.xkb_compose_table != NULL) + xkb_compose_table_unref(seat->kbd.xkb_compose_table); + if (seat->kbd.xkb_keymap != NULL) + xkb_keymap_unref(seat->kbd.xkb_keymap); + if (seat->kbd.xkb_state != NULL) + xkb_state_unref(seat->kbd.xkb_state); + if (seat->kbd.xkb != NULL) + xkb_context_unref(seat->kbd.xkb); + + if (seat->kbd.repeat.fd >= 0) + fdm_del(seat->wayl->fdm, seat->kbd.repeat.fd); + + free(seat->pointer.theme_name); + if (seat->pointer.theme != NULL) + wl_cursor_theme_destroy(seat->pointer.theme); + if (seat->pointer.surface != NULL) + wl_surface_destroy(seat->pointer.surface); + if (seat->pointer.xcursor_callback != NULL) + wl_callback_destroy(seat->pointer.xcursor_callback); + + if (seat->primary_selection_device != NULL) + zwp_primary_selection_device_v1_destroy(seat->primary_selection_device); + if (seat->data_device != NULL) + wl_data_device_destroy(seat->data_device); + + if (seat->wl_keyboard != NULL) + wl_keyboard_destroy(seat->wl_keyboard); + if (seat->wl_pointer != NULL) + wl_pointer_destroy(seat->wl_pointer); + if (seat->wl_seat != NULL) + wl_seat_destroy(seat->wl_seat); + + free(seat->clipboard.text); + free(seat->primary.text); + free(seat->name); +} + static void shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) { @@ -98,29 +151,31 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { - struct wayland *wayl = data; + struct seat *seat = data; + assert(seat->wl_seat == wl_seat); + //struct wayland *wayl = data; if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { - if (wayl->keyboard == NULL) { - wayl->keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(wayl->keyboard, &keyboard_listener, wayl); + if (seat->wl_keyboard == NULL) { + seat->wl_keyboard = wl_seat_get_keyboard(wl_seat); + wl_keyboard_add_listener(seat->wl_keyboard, &keyboard_listener, seat); } } else { - if (wayl->keyboard != NULL) { - wl_keyboard_release(wayl->keyboard); - wayl->keyboard = NULL; + if (seat->wl_keyboard != NULL) { + wl_keyboard_release(seat->wl_keyboard); + seat->wl_keyboard = NULL; } } if (caps & WL_SEAT_CAPABILITY_POINTER) { - if (wayl->pointer.pointer == NULL) { - wayl->pointer.pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(wayl->pointer.pointer, &pointer_listener, wayl); + if (seat->wl_pointer == NULL) { + seat->wl_pointer = wl_seat_get_pointer(wl_seat); + wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat); } } else { - if (wayl->pointer.pointer != NULL) { - wl_pointer_release(wayl->pointer.pointer); - wayl->pointer.pointer = NULL; + if (seat->wl_pointer != NULL) { + wl_pointer_release(seat->wl_pointer); + seat->wl_pointer = NULL; } } } @@ -128,6 +183,9 @@ seat_handle_capabilities(void *data, struct wl_seat *wl_seat, static void seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) { + struct seat *seat = data; + free(seat->name); + seat->name = strdup(name); } static const struct wl_seat_listener seat_listener = { @@ -533,6 +591,32 @@ static const struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration .configure = &xdg_toplevel_decoration_configure, }; +static bool +fdm_repeat(struct fdm *fdm, int fd, int events, void *data) +{ + if (events & EPOLLHUP) + return false; + + struct seat *seat = data; + uint64_t expiration_count; + ssize_t ret = read( + seat->kbd.repeat.fd, &expiration_count, sizeof(expiration_count)); + + if (ret < 0) { + if (errno == EAGAIN) + return true; + + LOG_ERRNO("failed to read repeat key from repeat timer fd"); + return false; + } + + seat->kbd.repeat.dont_re_repeat = true; + for (size_t i = 0; i < expiration_count; i++) + input_repeat(seat, seat->kbd.repeat.key); + seat->kbd.repeat.dont_re_repeat = false; + return true; +} + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) @@ -566,7 +650,6 @@ handle_global(void *data, struct wl_registry *registry, wayl->shm = wl_registry_bind( wayl->registry, name, &wl_shm_interface, required); wl_shm_add_listener(wayl->shm, &shm_listener, wayl); - wl_display_roundtrip(wayl->display); } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { @@ -593,10 +676,55 @@ handle_global(void *data, struct wl_registry *registry, if (!verify_iface_version(interface, version, required)) return; - wayl->seat = wl_registry_bind( + int repeat_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + if (repeat_fd == -1) { + LOG_ERRNO("failed to create keyboard repeat timer FD"); + return; + } + + struct wl_seat *wl_seat = wl_registry_bind( wayl->registry, name, &wl_seat_interface, required); - wl_seat_add_listener(wayl->seat, &seat_listener, wayl); - wl_display_roundtrip(wayl->display); + + /* Clipboard */ + struct wl_data_device *data_device = wl_data_device_manager_get_data_device( + wayl->data_device_manager, wl_seat); + + /* Primary selection */ + struct zwp_primary_selection_device_v1 *primary_selection_device; + if (wayl->primary_selection_device_manager != NULL) { + primary_selection_device = zwp_primary_selection_device_manager_v1_get_device( + wayl->primary_selection_device_manager, wl_seat); + } else + primary_selection_device = NULL; + + tll_push_back(wayl->seats, ((struct seat){ + .wayl = wayl, + .wl_seat = wl_seat, + .wl_name = name, + .kbd = { + .repeat = { + .fd = repeat_fd, + }, + }, + .data_device = data_device, + .primary_selection_device = primary_selection_device, + })); + + struct seat *seat = &tll_back(wayl->seats); + + if (!fdm_add(wayl->fdm, repeat_fd, EPOLLIN, &fdm_repeat, seat)) { + close(repeat_fd); + seat->kbd.repeat.fd = -1; + seat_destroy(seat); + return; + } + + wl_seat_add_listener(wl_seat, &seat_listener, seat); + wl_data_device_add_listener(data_device, &data_device_listener, seat); + if (primary_selection_device != NULL) { + zwp_primary_selection_device_v1_add_listener( + primary_selection_device, &primary_selection_device_listener, seat); + } } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) { @@ -629,7 +757,6 @@ handle_global(void *data, struct wl_registry *registry, wayl->xdg_output_manager, mon->output); zxdg_output_v1_add_listener(mon->xdg, &xdg_output_listener, mon); } - wl_display_roundtrip(wayl->display); } else if (strcmp(interface, wl_data_device_manager_interface.name) == 0) { @@ -747,32 +874,6 @@ fdm_wayl(struct fdm *fdm, int fd, int events, void *data) return event_count != -1; } -static bool -fdm_repeat(struct fdm *fdm, int fd, int events, void *data) -{ - if (events & EPOLLHUP) - return false; - - struct wayland *wayl = data; - uint64_t expiration_count; - ssize_t ret = read( - wayl->kbd.repeat.fd, &expiration_count, sizeof(expiration_count)); - - if (ret < 0) { - if (errno == EAGAIN) - return true; - - LOG_ERRNO("failed to read repeat key from repeat timer fd"); - return false; - } - - wayl->kbd.repeat.dont_re_repeat = true; - for (size_t i = 0; i < expiration_count; i++) - input_repeat(wayl, wayl->kbd.repeat.key); - wayl->kbd.repeat.dont_re_repeat = false; - return true; -} - struct wayland * wayl_init(const struct config *conf, struct fdm *fdm) { @@ -780,7 +881,6 @@ wayl_init(const struct config *conf, struct fdm *fdm) wayl->conf = conf; wayl->fdm = fdm; wayl->fd = -1; - wayl->kbd.repeat.fd = -1; if (!fdm_hook_add(fdm, &fdm_hook, wayl, FDM_HOOK_PRIORITY_LOW)) { LOG_ERR("failed to add FDM hook"); @@ -818,20 +918,11 @@ wayl_init(const struct config *conf, struct fdm *fdm) LOG_ERR("no XDG shell interface"); goto out; } - if (wayl->seat == NULL) { - LOG_ERR("no seat available"); - goto out; - } if (wayl->data_device_manager == NULL) { LOG_ERR("no clipboard available " "(wl_data_device_manager not implemented by server)"); goto out; } - if (!wayl->have_argb8888) { - LOG_ERR("compositor does not support ARGB surfaces"); - goto out; - } - if (wayl->primary_selection_device_manager == NULL) LOG_WARN("no primary selection available"); @@ -840,6 +931,13 @@ wayl_init(const struct config *conf, struct fdm *fdm) goto out; } + wl_display_roundtrip(wayl->display); + + if (!wayl->have_argb8888) { + LOG_ERR("compositor does not support ARGB surfaces"); + goto out; + } + tll_foreach(wayl->monitors, it) { LOG_INFO( "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d PPI=%dx%d (physical) PPI=%dx%d (logical)", @@ -851,6 +949,7 @@ wayl_init(const struct config *conf, struct fdm *fdm) it->item.ppi.scaled.x, it->item.ppi.scaled.y); } +#if 0 /* Clipboard */ wayl->data_device = wl_data_device_manager_get_data_device( wayl->data_device_manager, wayl->seat); @@ -887,7 +986,7 @@ wayl_init(const struct config *conf, struct fdm *fdm) LOG_ERR("failed to create cursor surface"); goto out; } - +#endif /* All wayland initialization done - make it so */ wl_display_roundtrip(wayl->display); @@ -900,15 +999,6 @@ wayl_init(const struct config *conf, struct fdm *fdm) if (!fdm_add(fdm, wayl->fd, EPOLLIN, &fdm_wayl, wayl)) goto out; - wayl->kbd.repeat.fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); - if (wayl->kbd.repeat.fd == -1) { - LOG_ERRNO("failed to create keyboard repeat timer FD"); - goto out; - } - - if (!fdm_add(fdm, wayl->kbd.repeat.fd, EPOLLIN, &fdm_repeat, wayl)) - goto out; - if (wl_display_prepare_read(wayl->display) != 0) { LOG_ERRNO("failed to prepare for reading wayland events"); goto out; @@ -941,16 +1031,13 @@ wayl_destroy(struct wayland *wayl) fdm_hook_del(wayl->fdm, &fdm_hook, FDM_HOOK_PRIORITY_LOW); - if (wayl->kbd.repeat.fd != -1) - fdm_del(wayl->fdm, wayl->kbd.repeat.fd); - - tll_foreach(wayl->monitors, it) { + tll_foreach(wayl->monitors, it) monitor_destroy(&it->item); - tll_remove(wayl->monitors, it); - } + tll_free(wayl->monitors); - if (wayl->pointer.xcursor_callback != NULL) - wl_callback_destroy(wayl->pointer.xcursor_callback); + tll_foreach(wayl->seats, it) + seat_destroy(&it->item); + tll_free(wayl->seats); if (wayl->xdg_output_manager != NULL) zxdg_output_manager_v1_destroy(wayl->xdg_output_manager); @@ -963,25 +1050,7 @@ wayl_destroy(struct wayland *wayl) if (wayl->presentation != NULL) wp_presentation_destroy(wayl->presentation); - tll_foreach(wayl->kbd.bindings.key, it) - tll_free(it->item.bind.key_codes); - tll_free(wayl->kbd.bindings.key); - - tll_foreach(wayl->kbd.bindings.search, it) - tll_free(it->item.bind.key_codes); - tll_free(wayl->kbd.bindings.search); - - if (wayl->kbd.xkb_compose_state != NULL) - xkb_compose_state_unref(wayl->kbd.xkb_compose_state); - if (wayl->kbd.xkb_compose_table != NULL) - xkb_compose_table_unref(wayl->kbd.xkb_compose_table); - if (wayl->kbd.xkb_keymap != NULL) - xkb_keymap_unref(wayl->kbd.xkb_keymap); - if (wayl->kbd.xkb_state != NULL) - xkb_state_unref(wayl->kbd.xkb_state); - if (wayl->kbd.xkb != NULL) - xkb_context_unref(wayl->kbd.xkb); - +#if 0 if (wayl->clipboard.data_source != NULL) wl_data_source_destroy(wayl->clipboard.data_source); if (wayl->clipboard.data_offer != NULL) @@ -993,25 +1062,17 @@ wayl_destroy(struct wayland *wayl) zwp_primary_selection_offer_v1_destroy(wayl->primary.data_offer); free(wayl->primary.text); - free(wayl->pointer.theme_name); - if (wayl->pointer.theme != NULL) - wl_cursor_theme_destroy(wayl->pointer.theme); - if (wayl->pointer.pointer != NULL) - wl_pointer_destroy(wayl->pointer.pointer); - if (wayl->pointer.surface != NULL) - wl_surface_destroy(wayl->pointer.surface); - if (wayl->keyboard != NULL) - wl_keyboard_destroy(wayl->keyboard); if (wayl->data_device != NULL) wl_data_device_destroy(wayl->data_device); +#endif if (wayl->data_device_manager != NULL) wl_data_device_manager_destroy(wayl->data_device_manager); +#if 0 if (wayl->primary_selection_device != NULL) zwp_primary_selection_device_v1_destroy(wayl->primary_selection_device); +#endif if (wayl->primary_selection_device_manager != NULL) zwp_primary_selection_device_manager_v1_destroy(wayl->primary_selection_device_manager); - if (wayl->seat != NULL) - wl_seat_destroy(wayl->seat); if (wayl->shm != NULL) wl_shm_destroy(wayl->shm); if (wayl->sub_compositor != NULL) @@ -1163,6 +1224,7 @@ wayl_win_destroy(struct wl_window *win) static bool wayl_reload_cursor_theme(struct wayland *wayl, struct terminal *term) { +#if 0 if (wayl->pointer.size == 0) return true; @@ -1184,6 +1246,8 @@ wayl_reload_cursor_theme(struct wayland *wayl, struct terminal *term) } return render_xcursor_set(term); +#endif + return true; } void diff --git a/wayland.h b/wayland.h index ccc03ad3..15dc6057 100644 --- a/wayland.h +++ b/wayland.h @@ -15,65 +15,6 @@ #include "fdm.h" -struct monitor { - struct wayland *wayl; - struct wl_output *output; - struct zxdg_output_v1 *xdg; - uint32_t wl_name; - - int x; - int y; - - struct { - /* Physical size, in mm */ - struct { - int width; - int height; - } mm; - - /* Physical size, in pixels */ - struct { - int width; - int height; - } px_real; - - /* Scaled size, in pixels */ - struct { - int width; - int height; - } px_scaled; - } dim; - - struct { - /* PPI, based on physical size */ - struct { - int x; - int y; - } real; - - /* PPI, logical, based on scaled size */ - struct { - int x; - int y; - } scaled; - } ppi; - - int scale; - float refresh; - enum wl_output_subpixel subpixel; - - /* From wl_output */ - char *make; - char *model; - - /* From xdg_output */ - char *name; - char *description; - - float inch; /* e.g. 24" */ -}; - - typedef tll(xkb_keycode_t) xkb_keycode_list_t; struct key_binding { @@ -138,38 +79,6 @@ struct key_binding_search { enum bind_action_search action; }; -struct kbd { - struct xkb_context *xkb; - struct xkb_keymap *xkb_keymap; - struct xkb_state *xkb_state; - struct xkb_compose_table *xkb_compose_table; - struct xkb_compose_state *xkb_compose_state; - struct { - int fd; - - bool dont_re_repeat; - int32_t delay; - int32_t rate; - uint32_t key; - } repeat; - - xkb_mod_index_t mod_shift; - xkb_mod_index_t mod_alt; - xkb_mod_index_t mod_ctrl; - xkb_mod_index_t mod_meta; - - /* Enabled modifiers */ - bool shift; - bool alt; - bool ctrl; - bool meta; - - struct { - tll(struct key_binding_normal) key; - tll(struct key_binding_search) search; - } bindings; -}; - struct wl_clipboard { struct wl_data_source *data_source; struct wl_data_offer *data_offer; @@ -184,6 +93,91 @@ struct wl_primary { uint32_t serial; }; +struct seat { + struct wayland *wayl; + struct wl_seat *wl_seat; + uint32_t wl_name; + char *name; + + /* Focused terminals */ + struct terminal *kbd_focus; + struct terminal *mouse_focus; + + /* Keyboard state */ + struct wl_keyboard *wl_keyboard; + struct { + struct xkb_context *xkb; + struct xkb_keymap *xkb_keymap; + struct xkb_state *xkb_state; + struct xkb_compose_table *xkb_compose_table; + struct xkb_compose_state *xkb_compose_state; + struct { + int fd; + + bool dont_re_repeat; + int32_t delay; + int32_t rate; + uint32_t key; + } repeat; + + xkb_mod_index_t mod_shift; + xkb_mod_index_t mod_alt; + xkb_mod_index_t mod_ctrl; + xkb_mod_index_t mod_meta; + + /* Enabled modifiers */ + bool shift; + bool alt; + bool ctrl; + bool meta; + + struct { + tll(struct key_binding_normal) key; + tll(struct key_binding_search) search; + } bindings; + } kbd; + + /* Pointer state */ + struct wl_pointer *wl_pointer; + struct { + uint32_t serial; + + struct wl_surface *surface; + struct wl_cursor_theme *theme; + struct wl_cursor *cursor; + int size; + char *theme_name; + const char *xcursor; + + const struct terminal *pending_terminal; + struct wl_callback *xcursor_callback; + } pointer; + + struct { + int x; + int y; + int col; + int row; + int button; + + int count; + int last_button; + struct timeval last_time; + + /* We used a discrete axis event in the current pointer frame */ + double axis_aggregated; + bool have_discrete; + } mouse; + + /* Clipboard */ + uint32_t input_serial; + struct wl_data_device *data_device; + struct zwp_primary_selection_device_v1 *primary_selection_device; + + struct wl_clipboard clipboard; + struct wl_primary primary; +}; + enum csd_surface { CSD_SURF_TITLE, CSD_SURF_LEFT, @@ -196,6 +190,64 @@ enum csd_surface { CSD_SURF_COUNT, }; +struct monitor { + struct wayland *wayl; + struct wl_output *output; + struct zxdg_output_v1 *xdg; + uint32_t wl_name; + + int x; + int y; + + struct { + /* Physical size, in mm */ + struct { + int width; + int height; + } mm; + + /* Physical size, in pixels */ + struct { + int width; + int height; + } px_real; + + /* Scaled size, in pixels */ + struct { + int width; + int height; + } px_scaled; + } dim; + + struct { + /* PPI, based on physical size */ + struct { + int x; + int y; + } real; + + /* PPI, logical, based on scaled size */ + struct { + int x; + int y; + } scaled; + } ppi; + + int scale; + float refresh; + enum wl_output_subpixel subpixel; + + /* From wl_output */ + char *make; + char *model; + + /* From xdg_output */ + char *name; + char *description; + + float inch; /* e.g. 24" */ +}; + struct wayland; struct wl_window { struct terminal *term; @@ -248,67 +300,23 @@ struct wayland { struct wl_subcompositor *sub_compositor; struct wl_shm *shm; - struct wl_seat *seat; - struct wl_keyboard *keyboard; struct zxdg_output_manager_v1 *xdg_output_manager; struct xdg_wm_base *shell; struct zxdg_decoration_manager_v1 *xdg_decoration_manager; + struct wl_data_device_manager *data_device_manager; + struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager; + struct wp_presentation *presentation; uint32_t presentation_clock_id; - /* Keyboard */ - struct kbd kbd; - - /* Clipboard */ - uint32_t input_serial; - struct wl_data_device_manager *data_device_manager; - struct wl_data_device *data_device; - struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager; - struct zwp_primary_selection_device_v1 *primary_selection_device; - - struct wl_clipboard clipboard; - struct wl_primary primary; - - /* Cursor */ - struct { - struct wl_pointer *pointer; - uint32_t serial; - - struct wl_surface *surface; - struct wl_cursor_theme *theme; - struct wl_cursor *cursor; - int size; - char *theme_name; - const char *xcursor; - - const struct terminal *pending_terminal; - struct wl_callback *xcursor_callback; - } pointer; - - struct { - int x; - int y; - int col; - int row; - int button; - - int count; - int last_button; - struct timeval last_time; - - /* We used a discrete axis event in the current pointer frame */ - double axis_aggregated; - bool have_discrete; - } mouse; bool have_argb8888; tll(struct monitor) monitors; /* All available outputs */ + tll(struct seat) seats; tll(struct terminal *) terms; - struct terminal *kbd_focus; - struct terminal *mouse_focus; }; struct wayland *wayl_init(const struct config *conf, struct fdm *fdm);