xwayland: introduce wlr_xwm_reply_handler

This is a helper to asynchronously wait for a reply from the X11
server.
This commit is contained in:
Simon Ser 2023-07-28 14:09:51 +02:00
parent 0de3659698
commit bad03394e0
2 changed files with 47 additions and 1 deletions

View file

@ -91,6 +91,17 @@ enum atom_name {
ATOM_LAST // keep last ATOM_LAST // keep last
}; };
struct wlr_xwm_reply_handler;
typedef void (*xwm_reply_handler_func_t)(struct wlr_xwm *xwm,
struct wlr_xwm_reply_handler *reply_handler, xcb_generic_reply_t *reply);
struct wlr_xwm_reply_handler {
unsigned int request;
xwm_reply_handler_func_t callback;
struct wl_list link;
};
struct wlr_xwm { struct wlr_xwm {
struct wlr_xwayland *xwayland; struct wlr_xwayland *xwayland;
struct wl_event_source *event_source; struct wl_event_source *event_source;
@ -106,6 +117,8 @@ struct wlr_xwm {
xcb_render_pictformat_t render_format_id; xcb_render_pictformat_t render_format_id;
xcb_cursor_t cursor; xcb_cursor_t cursor;
struct wl_list reply_handlers; // wlr_xwm_reply_handler.link
struct wlr_xwm_selection clipboard_selection; struct wlr_xwm_selection clipboard_selection;
struct wlr_xwm_selection primary_selection; struct wlr_xwm_selection primary_selection;
struct wlr_xwm_selection dnd_selection; struct wlr_xwm_selection dnd_selection;
@ -160,4 +173,7 @@ char *xwm_get_atom_name(struct wlr_xwm *xwm, xcb_atom_t atom);
bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms, bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms,
size_t num_atoms, enum atom_name needle); size_t num_atoms, enum atom_name needle);
void xwm_init_reply_handler(struct wlr_xwm *xwm, struct wlr_xwm_reply_handler *handler,
unsigned int request, xwm_reply_handler_func_t callback);
#endif #endif

View file

@ -16,6 +16,7 @@
#include <xcb/composite.h> #include <xcb/composite.h>
#include <xcb/render.h> #include <xcb/render.h>
#include <xcb/res.h> #include <xcb/res.h>
#include <xcb/xcbext.h>
#include <xcb/xfixes.h> #include <xcb/xfixes.h>
#include "xwayland/xwm.h" #include "xwayland/xwm.h"
@ -1644,7 +1645,6 @@ static void xwm_handle_unhandled_event(struct wlr_xwm *xwm, xcb_generic_event_t
static int x11_event_handler(int fd, uint32_t mask, void *data) { static int x11_event_handler(int fd, uint32_t mask, void *data) {
int count = 0; int count = 0;
xcb_generic_event_t *event;
struct wlr_xwm *xwm = data; struct wlr_xwm *xwm = data;
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
@ -1652,6 +1652,18 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) {
return 0; return 0;
} }
struct wlr_xwm_reply_handler *reply_handler, *reply_handler_tmp;
wl_list_for_each_safe(reply_handler, reply_handler_tmp, &xwm->reply_handlers, link) {
void *reply = NULL;
if (!xcb_poll_for_reply(xwm->xcb_conn, reply_handler->request, &reply, NULL)) {
break;
}
wl_list_remove(&reply_handler->link);
reply_handler->callback(xwm, reply_handler, reply);
free(reply);
}
xcb_generic_event_t *event;
while ((event = xcb_poll_for_event(xwm->xcb_conn))) { while ((event = xcb_poll_for_event(xwm->xcb_conn))) {
count++; count++;
@ -1716,6 +1728,18 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) {
return count; return count;
} }
void xwm_init_reply_handler(struct wlr_xwm *xwm, struct wlr_xwm_reply_handler *handler,
uint32_t request, xwm_reply_handler_func_t callback) {
if (request == 0) {
// Failed to send the request
callback(xwm, handler, NULL);
return;
}
handler->request = request;
handler->callback = callback;
wl_list_insert(xwm->reply_handlers.prev, &handler->link);
}
static void handle_compositor_new_surface(struct wl_listener *listener, static void handle_compositor_new_surface(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_xwm *xwm = struct wlr_xwm *xwm =
@ -1887,6 +1911,11 @@ void xwm_destroy(struct wlr_xwm *xwm) {
wl_list_for_each_safe(xsurface, tmp, &xwm->unpaired_surfaces, unpaired_link) { wl_list_for_each_safe(xsurface, tmp, &xwm->unpaired_surfaces, unpaired_link) {
xwayland_surface_destroy(xsurface); xwayland_surface_destroy(xsurface);
} }
struct wlr_xwm_reply_handler *reply_handler, *reply_handler_tmp;
wl_list_for_each_safe(reply_handler, reply_handler_tmp, &xwm->reply_handlers, link) {
wl_list_remove(&reply_handler->link);
reply_handler->callback(xwm, reply_handler, NULL);
}
wl_list_remove(&xwm->compositor_new_surface.link); wl_list_remove(&xwm->compositor_new_surface.link);
wl_list_remove(&xwm->compositor_destroy.link); wl_list_remove(&xwm->compositor_destroy.link);
wl_list_remove(&xwm->shell_v1_new_surface.link); wl_list_remove(&xwm->shell_v1_new_surface.link);
@ -2139,6 +2168,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
wl_list_init(&xwm->surfaces_in_stack_order); wl_list_init(&xwm->surfaces_in_stack_order);
wl_list_init(&xwm->unpaired_surfaces); wl_list_init(&xwm->unpaired_surfaces);
wl_list_init(&xwm->pending_startup_ids); wl_list_init(&xwm->pending_startup_ids);
wl_list_init(&xwm->reply_handlers);
xwm->ping_timeout = 10000; xwm->ping_timeout = 10000;
xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL); xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL);