From 7d1870c6f1c1dd14fe9fe13885021970f0cbdbe8 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Sat, 3 Mar 2018 17:03:19 +0100 Subject: move xwm.h out of include/wlr xwm.h was meant to be private, so move it to include/xwayland/xwm.h We had an ifdef WLR_HAS_XCB_ICCCM in xwayland.h which was easy to move to xwm, it is not safe to use the WLR_HAS_* in the public headers. I checked a few of our current users and none rely on xwm.h being public as expected (rootston, sway, hsroots) --- include/xwayland/xwm.h | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 include/xwayland/xwm.h (limited to 'include/xwayland') diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h new file mode 100644 index 00000000..0ed61d37 --- /dev/null +++ b/include/xwayland/xwm.h @@ -0,0 +1,132 @@ +#ifndef WLR_XWM_H +#define WLR_XWM_H + +#include +#include +#include + +#ifdef WLR_HAS_XCB_ICCCM + #include +#endif +#ifdef WLR_HAS_XCB_ERRORS + #include +#endif + +enum atom_name { + WL_SURFACE_ID, + WM_DELETE_WINDOW, + WM_PROTOCOLS, + WM_HINTS, + WM_NORMAL_HINTS, + WM_SIZE_HINTS, + MOTIF_WM_HINTS, + UTF8_STRING, + WM_S0, + NET_SUPPORTED, + NET_WM_S0, + NET_WM_PID, + NET_WM_NAME, + NET_WM_STATE, + NET_WM_WINDOW_TYPE, + WM_TAKE_FOCUS, + WINDOW, + _NET_ACTIVE_WINDOW, + _NET_WM_MOVERESIZE, + _NET_WM_NAME, + _NET_SUPPORTING_WM_CHECK, + _NET_WM_STATE_FULLSCREEN, + _NET_WM_STATE_MAXIMIZED_VERT, + _NET_WM_STATE_MAXIMIZED_HORZ, + WM_STATE, + CLIPBOARD, + PRIMARY, + WL_SELECTION, + TARGETS, + CLIPBOARD_MANAGER, + INCR, + TEXT, + TIMESTAMP, + NET_WM_WINDOW_TYPE_UTILITY, + NET_WM_WINDOW_TYPE_TOOLTIP, + NET_WM_WINDOW_TYPE_DND, + NET_WM_WINDOW_TYPE_DROPDOWN_MENU, + NET_WM_WINDOW_TYPE_POPUP_MENU, + NET_WM_WINDOW_TYPE_COMBO, + ATOM_LAST, +}; + +extern const char *atom_map[ATOM_LAST]; + +enum net_wm_state_action { + NET_WM_STATE_REMOVE = 0, + NET_WM_STATE_ADD = 1, + NET_WM_STATE_TOGGLE = 2, +}; + +struct wlr_xwm_selection { + struct wlr_xwm *xwm; + xcb_atom_t atom; + xcb_window_t window; + xcb_selection_request_event_t request; + xcb_window_t owner; + xcb_timestamp_t timestamp; + int incr; + int source_fd; + int property_start; + xcb_get_property_reply_t *property_reply; + struct wl_event_source *property_source; + int flush_property_on_delete; + struct wl_array source_data; + xcb_atom_t target; + bool property_set; +}; + +struct wlr_xwm { + struct wlr_xwayland *xwayland; + struct wl_event_source *event_source; + struct wlr_seat *seat; + + xcb_atom_t atoms[ATOM_LAST]; + xcb_connection_t *xcb_conn; + xcb_screen_t *screen; + xcb_window_t window; + xcb_visualid_t visual_id; + xcb_colormap_t colormap; + xcb_render_pictformat_t render_format_id; + xcb_cursor_t cursor; + + xcb_window_t selection_window; + struct wlr_xwm_selection clipboard_selection; + struct wlr_xwm_selection primary_selection; + + struct wlr_xwayland_surface *focus_surface; + + struct wl_list surfaces; // wlr_xwayland_surface::link + struct wl_list unpaired_surfaces; // wlr_xwayland_surface::unpaired_link + + const xcb_query_extension_reply_t *xfixes; + + struct wl_listener compositor_new_surface; + struct wl_listener compositor_destroy; + struct wl_listener seat_selection; + struct wl_listener seat_primary_selection; +}; + +struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland); + +void xwm_destroy(struct wlr_xwm *xwm); + +void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, + uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y); + +int xwm_handle_selection_event(struct wlr_xwm *xwm, xcb_generic_event_t *event); + +void xwm_selection_init(struct wlr_xwm *xwm); +void xwm_selection_finish(struct wlr_xwm *xwm); + +void xwm_set_seat(struct wlr_xwm *xwm, struct wlr_seat *seat); + +bool wlr_xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms, + size_t num_atoms, enum atom_name needle); + +#endif -- cgit v1.2.3 From d9a724c4a21abd58a6dd73d596ea02d46f68897a Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Sat, 3 Mar 2018 17:06:27 +0100 Subject: xcb errors: init errors context at start `xcb_errors_context_new` is more than just a malloc, it does a few xcb requests so we benefit from not generating a new context everytime --- include/xwayland/xwm.h | 3 +++ xwayland/xwm.c | 42 +++++++++++++++++++----------------------- 2 files changed, 22 insertions(+), 23 deletions(-) (limited to 'include/xwayland') diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index 0ed61d37..e918ac11 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -105,6 +105,9 @@ struct wlr_xwm { struct wl_list unpaired_surfaces; // wlr_xwayland_surface::unpaired_link const xcb_query_extension_reply_t *xfixes; +#ifdef WLR_HAS_XCB_ERRORS + xcb_errors_context_t *errors_context; +#endif struct wl_listener compositor_new_surface; struct wl_listener compositor_destroy; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index b4042ad6..9210033a 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -952,30 +952,24 @@ static void xwm_handle_focus_in(struct wlr_xwm *xwm, static void xwm_handle_xcb_error(struct wlr_xwm *xwm, xcb_value_error_t *ev) { #ifdef WLR_HAS_XCB_ERRORS - xcb_errors_context_t *err_ctx; - if (xcb_errors_context_new(xwm->xcb_conn, &err_ctx)) { - wlr_log(L_DEBUG, "xcb error happened, but could not allocate error context"); - goto log_raw; - } - const char *major_name = - xcb_errors_get_name_for_major_code(err_ctx, ev->major_opcode); + xcb_errors_get_name_for_major_code(xwm->errors_context, + ev->major_opcode); if (!major_name) { wlr_log(L_DEBUG, "xcb error happened, but could not get major name"); - xcb_errors_context_free(err_ctx); goto log_raw; } const char *minor_name = - xcb_errors_get_name_for_minor_code(err_ctx, + xcb_errors_get_name_for_minor_code(xwm->errors_context, ev->major_opcode, ev->minor_opcode); const char *extension; const char *error_name = - xcb_errors_get_name_for_error(err_ctx, ev->error_code, &extension); + xcb_errors_get_name_for_error(xwm->errors_context, + ev->error_code, &extension); if (!error_name) { wlr_log(L_DEBUG, "xcb error happened, but could not get error name"); - xcb_errors_context_free(err_ctx); goto log_raw; } @@ -984,7 +978,6 @@ static void xwm_handle_xcb_error(struct wlr_xwm *xwm, xcb_value_error_t *ev) { error_name, extension ? extension : "no extension", ev->sequence, ev->bad_value); - xcb_errors_context_free(err_ctx); return; log_raw: #endif @@ -997,26 +990,17 @@ log_raw: static void xwm_handle_unhandled_event(struct wlr_xwm *xwm, xcb_generic_event_t *ev) { #ifdef WLR_HAS_XCB_ERRORS - xcb_errors_context_t *err_ctx; - if (xcb_errors_context_new(xwm->xcb_conn, &err_ctx)) { - wlr_log(L_DEBUG, "Could not allocate context for unhandled X11 event: %u", - ev->response_type); - return; - } - const char *extension; const char *event_name = - xcb_errors_get_name_for_xcb_event(err_ctx, ev, &extension); + xcb_errors_get_name_for_xcb_event(xwm->errors_context, + ev, &extension); if (!event_name) { wlr_log(L_DEBUG, "no name for unhandled event: %u", ev->response_type); - xcb_errors_context_free(err_ctx); return; } wlr_log(L_DEBUG, "unhandled X11 event: %s (%u)", event_name, ev->response_type); - - xcb_errors_context_free(err_ctx); #else wlr_log(L_DEBUG, "unhandled X11 event: %u", ev->response_type); #endif @@ -1203,6 +1187,11 @@ void xwm_destroy(struct wlr_xwm *xwm) { if (xwm->event_source) { wl_event_source_remove(xwm->event_source); } +#ifdef WLR_HAS_XCB_ERRORS + if (xwm->errors_context) { + xcb_errors_context_free(xwm->errors_context); + } +#endif struct wlr_xwayland_surface *xsurface, *tmp; wl_list_for_each_safe(xsurface, tmp, &xwm->surfaces, link) { wlr_xwayland_surface_destroy(xsurface); @@ -1439,6 +1428,13 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { return NULL; } +#ifdef WLR_HAS_XCB_ERRORS + if (xcb_errors_context_new(xwm->xcb_conn, &xwm->errors_context)) { + wlr_log(L_ERROR, "Could not allocate error context"); + xwm_destroy(xwm); + return NULL; + } +#endif xcb_screen_iterator_t screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(xwm->xcb_conn)); xwm->screen = screen_iterator.data; -- cgit v1.2.3 From 2910972b25a211ecd07c605d4bf93897ef5f715a Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Sun, 4 Mar 2018 11:16:14 +0100 Subject: xwm.h: fix guard ifdef and remove wlr_ prefix from xwm_atoms_contains --- include/xwayland/xwm.h | 6 +++--- xwayland/xwayland.c | 2 +- xwayland/xwm.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/xwayland') diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index e918ac11..4b15cc84 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -1,5 +1,5 @@ -#ifndef WLR_XWM_H -#define WLR_XWM_H +#ifndef XWAYLAND_XWM_H +#define XWAYLAND_XWM_H #include #include @@ -129,7 +129,7 @@ void xwm_selection_finish(struct wlr_xwm *xwm); void xwm_set_seat(struct wlr_xwm *xwm, struct wlr_seat *seat); -bool wlr_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); #endif diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index d49dd718..765e17d0 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -418,7 +418,7 @@ bool wlr_xwayland_surface_is_unmanaged(const struct wlr_xwayland_surface *surfac }; for (size_t i = 0; i < sizeof(needles) / sizeof(needles[0]); ++i) { - if (wlr_xwm_atoms_contains(surface->xwm, surface->window_type, + if (xwm_atoms_contains(surface->xwm, surface->window_type, surface->window_type_len, needles[i])) { return true; } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 9210033a..8911c553 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1519,7 +1519,7 @@ void wlr_xwayland_surface_set_fullscreen(struct wlr_xwayland_surface *surface, xcb_flush(surface->xwm->xcb_conn); } -bool wlr_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) { xcb_atom_t atom = xwm->atoms[needle]; -- cgit v1.2.3