From eb0c4b91c1ca8a107ae545e6ed5477cca97c1f8f Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:51:53 -0500 Subject: [PATCH] video/out/wayland_common: extract data offer to a struct The data offers can be either dnd or selection offers. Add a separate struct for it so that handling of selection offers can be added. --- video/out/wayland_common.c | 123 ++++++++++++++++++++----------------- video/out/wayland_common.h | 9 +-- 2 files changed, 71 insertions(+), 61 deletions(-) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 64e3000573..74a86a234e 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -221,6 +221,14 @@ struct vo_wayland_tranche { struct wl_list link; }; +struct vo_wayland_data_offer { + struct wl_data_offer *offer; + int action; // actually enum mp_dnd_action + char *mime_type; + int fd; + int mime_score; +}; + static bool single_output_spanned(struct vo_wayland_state *wl); static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels, @@ -688,11 +696,12 @@ static void data_offer_handle_offer(void *data, struct wl_data_offer *offer, { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; + struct vo_wayland_data_offer *o = wl->dnd_offer; int score = mp_event_get_mime_type_score(wl->vo->input_ctx, mime_type); - if (score > wl->dnd_mime_score && wl->opts->drag_and_drop != -2) { - wl->dnd_mime_score = score; - talloc_replace(wl, wl->dnd_mime_type, mime_type); - MP_VERBOSE(wl, "Given DND offer with mime type %s\n", wl->dnd_mime_type); + if (score > o->mime_score && wl->opts->drag_and_drop != -2) { + o->mime_score = score; + talloc_replace(wl, o->mime_type, mime_type); + MP_VERBOSE(wl, "Given DND offer with mime type %s\n", o->mime_type); } } @@ -704,12 +713,13 @@ static void data_offer_action(void *data, struct wl_data_offer *wl_data_offer, u { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; + struct vo_wayland_data_offer *o = wl->dnd_offer; if (dnd_action && wl->opts->drag_and_drop != -2) { if (wl->opts->drag_and_drop >= 0) { - wl->dnd_action = wl->opts->drag_and_drop; + o->action = wl->opts->drag_and_drop; } else { - wl->dnd_action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? - DND_REPLACE : DND_APPEND; + o->action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? + DND_REPLACE : DND_APPEND; } static const char * const dnd_action_names[] = { @@ -718,7 +728,7 @@ static void data_offer_action(void *data, struct wl_data_offer *wl_data_offer, u [DND_INSERT_NEXT] = "DND_INSERT_NEXT", }; - MP_VERBOSE(wl, "DND action is %s\n", dnd_action_names[wl->dnd_action]); + MP_VERBOSE(wl, "DND action is %s\n", dnd_action_names[o->action]); } } @@ -733,10 +743,11 @@ static void data_device_handle_data_offer(void *data, struct wl_data_device *wl_ { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; - if (wl->dnd_offer) - wl_data_offer_destroy(wl->dnd_offer); + struct vo_wayland_data_offer *o = wl->dnd_offer; + if (o->offer) + wl_data_offer_destroy(o->offer); - wl->dnd_offer = id; + o->offer = id; wl_data_offer_add_listener(id, &data_offer_listener, s); } @@ -747,7 +758,8 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_ddev, { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; - if (wl->dnd_offer != id) { + struct vo_wayland_data_offer *o = wl->dnd_offer; + if (o->offer != id) { MP_FATAL(wl, "DND offer ID mismatch!\n"); return; } @@ -756,8 +768,8 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_ddev, wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); - wl_data_offer_accept(id, serial, wl->dnd_mime_type); - MP_VERBOSE(wl, "Accepting DND offer with mime type %s\n", wl->dnd_mime_type); + wl_data_offer_accept(id, serial, o->mime_type); + MP_VERBOSE(wl, "Accepting DND offer with mime type %s\n", o->mime_type); } } @@ -766,19 +778,20 @@ static void data_device_handle_leave(void *data, struct wl_data_device *wl_ddev) { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; + struct vo_wayland_data_offer *o = wl->dnd_offer; - if (wl->dnd_offer) { - if (wl->dnd_fd != -1) + if (o->offer) { + if (o->fd != -1) return; - wl_data_offer_destroy(wl->dnd_offer); - wl->dnd_offer = NULL; + wl_data_offer_destroy(o->offer); + o->offer = NULL; } if (wl->opts->drag_and_drop != -2) { - MP_VERBOSE(wl, "Releasing DND offer with mime type %s\n", wl->dnd_mime_type); - if (wl->dnd_mime_type) - TA_FREEP(&wl->dnd_mime_type); - wl->dnd_mime_score = 0; + MP_VERBOSE(wl, "Releasing DND offer with mime type %s\n", o->mime_type); + if (o->mime_type) + TA_FREEP(&o->mime_type); + o->mime_score = 0; } } @@ -787,13 +800,15 @@ static void data_device_handle_motion(void *data, struct wl_data_device *wl_ddev { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; - wl_data_offer_accept(wl->dnd_offer, time, wl->dnd_mime_type); + struct vo_wayland_data_offer *o = wl->dnd_offer; + wl_data_offer_accept(o->offer, time, o->mime_type); } static void data_device_handle_drop(void *data, struct wl_data_device *wl_ddev) { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; + struct vo_wayland_data_offer *o = wl->dnd_offer; int pipefd[2]; @@ -803,12 +818,12 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_ddev) } if (wl->opts->drag_and_drop != -2) { - MP_VERBOSE(wl, "Receiving DND offer with mime %s\n", wl->dnd_mime_type); - wl_data_offer_receive(wl->dnd_offer, wl->dnd_mime_type, pipefd[1]); + MP_VERBOSE(wl, "Receiving DND offer with mime %s\n", o->mime_type); + wl_data_offer_receive(o->offer, o->mime_type, pipefd[1]); } close(pipefd[1]); - wl->dnd_fd = pipefd[0]; + o->fd = pipefd[0]; } static void data_device_handle_selection(void *data, struct wl_data_device *wl_ddev, @@ -816,10 +831,11 @@ static void data_device_handle_selection(void *data, struct wl_data_device *wl_d { struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; + struct vo_wayland_data_offer *o = wl->dnd_offer; - if (wl->dnd_offer) { - wl_data_offer_destroy(wl->dnd_offer); - wl->dnd_offer = NULL; + if (o->offer) { + wl_data_offer_destroy(o->offer); + o->offer = NULL; MP_VERBOSE(wl, "Received a new DND offer. Releasing the previous offer.\n"); } @@ -1830,21 +1846,23 @@ static void apply_keepaspect(struct vo_wayland_state *wl, int *width, int *heigh } } -static void free_dnd_data(struct vo_wayland_state *wl) +static void destroy_offer(struct vo_wayland_data_offer *o) { - // caller should close wl->dnd_fd if appropriate - - wl->dnd_action = -1; - TA_FREEP(&wl->dnd_mime_type); - wl->dnd_mime_score = 0; + TA_FREEP(&o->mime_type); + if (o->fd != -1) + close(o->fd); + if (o->offer) + wl_data_offer_destroy(o->offer); + *o = (struct vo_wayland_data_offer){.fd = -1, .action = -1}; } static void check_dnd_fd(struct vo_wayland_state *wl) { - if (wl->dnd_fd == -1) + struct vo_wayland_data_offer *o = wl->dnd_offer; + if (o->fd == -1) return; - struct pollfd fdp = { wl->dnd_fd, POLLIN | POLLHUP, 0 }; + struct pollfd fdp = { o->fd, POLLIN | POLLHUP, 0 }; if (poll(&fdp, 1, 0) <= 0) return; @@ -1856,7 +1874,7 @@ static void check_dnd_fd(struct vo_wayland_state *wl) }; while (1) { - data_read = read(wl->dnd_fd, file_list.start + file_list.len, chunk_size); + data_read = read(o->fd, file_list.start + file_list.len, chunk_size); if (data_read == -1 && errno == EINTR) continue; else if (data_read <= 0) @@ -1871,24 +1889,24 @@ static void check_dnd_fd(struct vo_wayland_state *wl) } else { MP_VERBOSE(wl, "Read %zu bytes from the DND fd\n", file_list.len); - if (wl->dnd_offer) - wl_data_offer_finish(wl->dnd_offer); + if (o->offer) + wl_data_offer_finish(o->offer); - assert(wl->dnd_action >= 0); - mp_event_drop_mime_data(wl->vo->input_ctx, wl->dnd_mime_type, - file_list, wl->dnd_action); + assert(o->action >= 0); + mp_event_drop_mime_data(wl->vo->input_ctx, o->mime_type, + file_list, o->action); } talloc_free(file_list.start); - free_dnd_data(wl); + free_offer_data(wl->dnd_offer); } if (fdp.revents & (POLLIN | POLLERR | POLLHUP)) { - if (wl->dnd_action >= 0) + if (o->action >= 0) MP_VERBOSE(wl, "DND aborted (hang up or error)\n"); - free_dnd_data(wl); - close(wl->dnd_fd); - wl->dnd_fd = -1; + free_offer_data(wl->dnd_offer); + close(o->fd); + o->fd = -1; } } @@ -3040,7 +3058,7 @@ bool vo_wayland_init(struct vo *vo) .scaling = WAYLAND_SCALE_FACTOR, .wakeup_pipe = {-1, -1}, .display_fd = -1, - .dnd_fd = -1, + .dnd_offer = talloc_zero(wl, struct vo_wayland_data_offer), .cursor_visible = true, .opts_cache = m_config_cache_alloc(wl, vo->global, &vo_sub_opts), }; @@ -3269,9 +3287,7 @@ void vo_wayland_uninit(struct vo *vo) if (!wl) return; - if (wl->dnd_fd != -1) - close(wl->dnd_fd); - free_dnd_data(wl); + destroy_offer(wl->dnd_offer); mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL); @@ -3313,9 +3329,6 @@ void vo_wayland_uninit(struct vo *vo) if (wl->dnd_devman) wl_data_device_manager_destroy(wl->dnd_devman); - if (wl->dnd_offer) - wl_data_offer_destroy(wl->dnd_offer); - if (wl->fback_pool) clean_feedback_pool(wl->fback_pool); diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index abce364cd5..38ee60222e 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -27,6 +27,7 @@ struct compositor_format; struct vo_wayland_seat; struct vo_wayland_tranche; +struct vo_wayland_data_offer; struct drm_format { uint32_t format; @@ -160,13 +161,9 @@ struct vo_wayland_state { struct wl_list seat_list; struct xkb_context *xkb_context; - /* DND */ + /* Data offer */ struct wl_data_device_manager *dnd_devman; - struct wl_data_offer *dnd_offer; - int dnd_action; // actually enum mp_dnd_action - char *dnd_mime_type; - int dnd_fd; - int dnd_mime_score; + struct vo_wayland_data_offer *dnd_offer; /* Cursor */ struct wl_cursor_theme *cursor_theme;