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.
This commit is contained in:
nanahi authored and Kacper Michajłow committed 2024-11-22 11:21:26 +01:00
1 parent 68d9ed2572
commit eb0c4b91c1
2 files changed
+71 -61

No files matched your search

+68 -55
View File
@@ -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);
+3 -6
View File
@@ -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;