From 3b4b8953d96194e8b168149f46c731443239accd Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 12 Dec 2017 21:58:00 +0100 Subject: Update output layout when scale or transform changes --- include/wlr/types/wlr_output.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 7f681ab7..99737c48 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -62,6 +62,8 @@ struct wlr_output { struct wl_signal frame; struct wl_signal swap_buffers; struct wl_signal resolution; + struct wl_signal scale; + struct wl_signal transform; struct wl_signal destroy; } events; @@ -85,7 +87,7 @@ bool wlr_output_set_mode(struct wlr_output *output, struct wlr_output_mode *mode); bool wlr_output_set_custom_mode(struct wlr_output *output, int32_t width, int32_t height, int32_t refresh); -void wlr_output_transform(struct wlr_output *output, +void wlr_output_set_transform(struct wlr_output *output, enum wl_output_transform transform); void wlr_output_set_position(struct wlr_output *output, int32_t lx, int32_t ly); void wlr_output_set_scale(struct wlr_output *output, uint32_t scale); -- cgit v1.2.3 From a1302cc4a517b2a2851b0b41848cf2f001b954f3 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 13 Dec 2017 22:32:22 +0100 Subject: Fix pointer events with multiple outputs in wayland backend --- backend/wayland/backend.c | 33 +++++++++++++++++++++++++++++++++ backend/wayland/wl_seat.c | 19 ++++++++++++------- include/backend/wayland.h | 3 +++ 3 files changed, 48 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 1801f3e0..39ecc10f 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,38 @@ struct wlr_wl_backend_output *wlr_wl_output_for_surface( return NULL; } +void wlr_wl_output_layout_get_box(struct wlr_wl_backend *backend, + struct wlr_box *box) { + int min_x = INT_MAX, min_y = INT_MAX; + int max_x = INT_MIN, max_y = INT_MIN; + + struct wlr_wl_backend_output *output; + wl_list_for_each(output, &backend->outputs, link) { + struct wlr_output *wlr_output = &output->wlr_output; + + int width, height; + wlr_output_effective_resolution(wlr_output, &width, &height); + + if (wlr_output->lx < min_x) { + min_x = wlr_output->lx; + } + if (wlr_output->ly < min_y) { + min_y = wlr_output->ly; + } + if (wlr_output->lx + width > max_x) { + max_x = wlr_output->lx + width; + } + if (wlr_output->ly + height > max_y) { + max_y = wlr_output->ly + height; + } + } + + box->x = min_x; + box->y = min_y; + box->width = max_x - min_x; + box->height = max_y - min_y; +} + struct wlr_backend *wlr_wl_backend_create(struct wl_display *display) { wlr_log(L_INFO, "Creating wayland backend"); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 3c20e6ca..7bfbf302 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -52,23 +52,28 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, return; } + struct wlr_output *wlr_output = &wlr_wl_pointer->current_output->wlr_output; + struct wlr_box box; wl_egl_window_get_attached_size(wlr_wl_pointer->current_output->egl_window, &box.width, &box.height); box.x = wl_fixed_to_int(surface_x); box.y = wl_fixed_to_int(surface_y); struct wlr_box transformed; - wlr_output_transform_apply_to_box( - wlr_wl_pointer->current_output->wlr_output.transform, &box, - &transformed); + wlr_output_transform_apply_to_box(wlr_output->transform, &box, &transformed); + box.x /= wlr_output->scale; + box.y /= wlr_output->scale; + + struct wlr_box layout_box; + wlr_wl_output_layout_get_box(wlr_wl_pointer->current_output->backend, &layout_box); struct wlr_event_pointer_motion_absolute wlr_event; wlr_event.device = dev; wlr_event.time_msec = time; - wlr_event.width_mm = transformed.width; - wlr_event.height_mm = transformed.height; - wlr_event.x_mm = transformed.x; - wlr_event.y_mm = transformed.y; + wlr_event.width_mm = layout_box.width; + wlr_event.height_mm = layout_box.height; + wlr_event.x_mm = transformed.x + wlr_output->lx + layout_box.x; + wlr_event.y_mm = transformed.y + wlr_output->ly + layout_box.y; wl_signal_emit(&dev->pointer->events.motion_absolute, &wlr_event); } diff --git a/include/backend/wayland.h b/include/backend/wayland.h index 1e8a55d2..7e2ec0d6 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,8 @@ void wlr_wl_registry_poll(struct wlr_wl_backend *backend); void wlr_wl_output_update_cursor(struct wlr_wl_backend_output *output); struct wlr_wl_backend_output *wlr_wl_output_for_surface( struct wlr_wl_backend *backend, struct wl_surface *surface); +void wlr_wl_output_layout_get_box(struct wlr_wl_backend *backend, + struct wlr_box *box); extern const struct wl_seat_listener seat_listener; -- cgit v1.2.3 From ea4b871e16ae63db67f2bf89c00e814b3dde6c78 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 13 Dec 2017 17:54:19 -0500 Subject: xwm: user custom event handler --- include/wlr/xwayland.h | 7 +++++ include/wlr/xwm.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 2 +- xwayland/xwayland.c | 2 +- xwayland/xwm.c | 8 +++++- xwayland/xwm.h | 75 -------------------------------------------------- 6 files changed, 91 insertions(+), 78 deletions(-) create mode 100644 include/wlr/xwm.h delete mode 100644 xwayland/xwm.h (limited to 'include') diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 792d2b88..9a89661b 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -32,6 +32,13 @@ struct wlr_xwayland { struct wl_signal new_surface; } events; + /** + * Add a custom event handler to xwayland. Return 1 if the event was + * handled or 0 to use the default wlr-xwayland handler. wlr-xwayland will + * free the event. + */ + int (*user_event_handler)(struct wlr_xwm *xwm, xcb_generic_event_t *event); + void *data; }; diff --git a/include/wlr/xwm.h b/include/wlr/xwm.h new file mode 100644 index 00000000..c350b6e2 --- /dev/null +++ b/include/wlr/xwm.h @@ -0,0 +1,75 @@ +#ifndef XWAYLAND_INTERNALS_H +#define XWAYLAND_INTERNALS_H + +#include +#include +#include + +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, + 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 { + struct wlr_xwayland *xwayland; + struct wl_event_source *event_source; + + 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; + + 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_surface_create; +}; + +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); + +#endif diff --git a/meson.build b/meson.build index addea930..a3f5e7f9 100644 --- a/meson.build +++ b/meson.build @@ -87,7 +87,7 @@ if get_option('enable_xwayland') wlr_parts += [lib_wlr_xwayland] conf_data.set('WLR_HAS_XWAYLAND', true) else - exclude_files += ['xwayland.h'] + exclude_files += ['xwayland.h', 'xwm.h'] endif configure_file(output: 'config.h', install_dir: 'include/wlr', configuration: conf_data) install_subdir('include/wlr', install_dir: 'include', exclude_files: exclude_files) diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index ecec785c..eb06bd57 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -19,7 +19,7 @@ #include "wlr/util/log.h" #include "wlr/xwayland.h" #include "sockets.h" -#include "xwm.h" +#include "wlr/xwm.h" #ifdef __FreeBSD__ static inline int clearenv(void) { diff --git a/xwayland/xwm.c b/xwayland/xwm.c index a86fbd0e..54092cda 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -12,7 +12,7 @@ #include "wlr/types/wlr_surface.h" #include "wlr/xwayland.h" #include "wlr/xcursor.h" -#include "xwm.h" +#include "wlr/xwm.h" #ifdef HAS_XCB_ICCCM #include @@ -938,6 +938,12 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) { while ((event = xcb_poll_for_event(xwm->xcb_conn))) { count++; + + if (xwm->xwayland->user_event_handler && + xwm->xwayland->user_event_handler(xwm, event)) { + break; + } + switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { case XCB_CREATE_NOTIFY: xwm_handle_create_notify(xwm, (xcb_create_notify_event_t *)event); diff --git a/xwayland/xwm.h b/xwayland/xwm.h deleted file mode 100644 index c350b6e2..00000000 --- a/xwayland/xwm.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef XWAYLAND_INTERNALS_H -#define XWAYLAND_INTERNALS_H - -#include -#include -#include - -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, - 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 { - struct wlr_xwayland *xwayland; - struct wl_event_source *event_source; - - 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; - - 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_surface_create; -}; - -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); - -#endif -- cgit v1.2.3