From d4f7ced6e260961f701f73f672fffa87ee333c3d Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 30 Mar 2018 21:40:43 -0400 Subject: backend/x11: refactor, prepare support for multiple outputs --- include/backend/x11.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/backend/x11.h b/include/backend/x11.h index 72710f6c..92a29725 100644 --- a/include/backend/x11.h +++ b/include/backend/x11.h @@ -6,15 +6,23 @@ #include #include #include +#include +#include + +#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f struct wlr_x11_backend; struct wlr_x11_output { struct wlr_output wlr_output; struct wlr_x11_backend *x11; + struct wl_list link; // wlr_x11_backend::outputs xcb_window_t win; EGLSurface surf; + + struct wl_event_source *frame_timer; + int frame_delay; }; struct wlr_x11_backend { @@ -25,7 +33,8 @@ struct wlr_x11_backend { xcb_connection_t *xcb_conn; xcb_screen_t *screen; - struct wlr_x11_output output; + size_t requested_outputs; + struct wl_list outputs; // wlr_x11_output::link struct wlr_keyboard keyboard; struct wlr_input_device keyboard_dev; @@ -36,7 +45,6 @@ struct wlr_x11_backend { struct wlr_egl egl; struct wlr_renderer *renderer; struct wl_event_source *event_source; - struct wl_event_source *frame_timer; struct { xcb_atom_t wm_protocols; @@ -57,4 +65,16 @@ struct wlr_x11_backend { struct wl_listener display_destroy; }; +struct wlr_x11_output *x11_output_from_window_id(struct wlr_x11_backend *x11, + xcb_window_t window); + +const struct wlr_input_device_impl input_device_impl; + +bool x11_handle_input_event(struct wlr_x11_backend *x11, + xcb_generic_event_t *event); + +struct wlr_x11_output *x11_output_create(struct wlr_x11_backend *x11); +void x11_output_handle_configure_notify(struct wlr_x11_output *output, + xcb_configure_notify_event_t *event); + #endif -- cgit v1.2.3 From 0a7a8cbd1c64e50978e846d8cf1bf8b1f6868655 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 30 Mar 2018 22:09:06 -0400 Subject: backend/x11: add WLR_X11_OUTPUTS support --- backend/backend.c | 67 ++++++++++++++++++++++++++++++++--------------- backend/x11/backend.c | 3 ++- backend/x11/output.c | 20 +++++++++++--- include/backend/x11.h | 7 ++--- include/wlr/backend/x11.h | 1 + 5 files changed, 69 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/backend/backend.c b/backend/backend.c index 52344dac..ff5603bd 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -61,26 +61,48 @@ struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend) { return NULL; } +static int parse_outputs_env(const char *name) { + const char *outputs_str = getenv(name); + if (outputs_str == NULL) { + return 1; + } + + char *end; + int outputs = (int)strtol(outputs_str, &end, 10); + if (*end || outputs < 0) { + wlr_log(L_ERROR, "%s specified with invalid integer, ignoring", name); + return 1; + } + + return outputs; +} + static struct wlr_backend *attempt_wl_backend(struct wl_display *display) { struct wlr_backend *backend = wlr_wl_backend_create(display, NULL); - if (backend) { - int outputs = 1; - const char *_outputs = getenv("WLR_WL_OUTPUTS"); - if (_outputs) { - char *end; - outputs = (int)strtol(_outputs, &end, 10); - if (*end) { - wlr_log(L_ERROR, "WLR_WL_OUTPUTS specified with invalid integer, ignoring"); - outputs = 1; - } else if (outputs < 0) { - wlr_log(L_ERROR, "WLR_WL_OUTPUTS specified with negative outputs, ignoring"); - outputs = 1; - } - } - while (outputs--) { - wlr_wl_output_create(backend); - } + if (backend == NULL) { + return NULL; + } + + int outputs = parse_outputs_env("WLR_WL_OUTPUTS"); + for (int i = 0; i < outputs; ++i) { + wlr_wl_output_create(backend); } + + return backend; +} + +static struct wlr_backend *attempt_x11_backend(struct wl_display *display, + const char *x11_display) { + struct wlr_backend *backend = wlr_x11_backend_create(display, x11_display); + if (backend == NULL) { + return NULL; + } + + int outputs = parse_outputs_env("WLR_X11_OUTPUTS"); + for (int i = 0; i < outputs; ++i) { + wlr_x11_output_create(backend); + } + return backend; } @@ -91,7 +113,8 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { return NULL; } - if (getenv("WAYLAND_DISPLAY") || getenv("_WAYLAND_DISPLAY")) { + if (getenv("WAYLAND_DISPLAY") || getenv("_WAYLAND_DISPLAY") || + getenv("WAYLAND_SOCKET")) { struct wlr_backend *wl_backend = attempt_wl_backend(display); if (wl_backend) { wlr_multi_backend_add(backend, wl_backend); @@ -103,9 +126,11 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { const char *x11_display = getenv("DISPLAY"); if (x11_display) { struct wlr_backend *x11_backend = - wlr_x11_backend_create(display, x11_display); - wlr_multi_backend_add(backend, x11_backend); - return backend; + attempt_x11_backend(display, x11_display); + if (x11_backend) { + wlr_multi_backend_add(backend, x11_backend); + return backend; + } } #endif diff --git a/backend/x11/backend.c b/backend/x11/backend.c index c72cdcac..80998f3f 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -96,6 +96,7 @@ static int x11_event(int fd, uint32_t mask, void *data) { static bool wlr_x11_backend_start(struct wlr_backend *backend) { struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend; + x11->started = true; struct { const char *name; @@ -167,7 +168,7 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->pointer_dev); for (size_t i = 0; i < x11->requested_outputs; ++i) { - x11_output_create(x11); + wlr_x11_output_create(&x11->backend); } return true; diff --git a/backend/x11/output.c b/backend/x11/output.c index f039baad..9e7424d8 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -77,18 +78,29 @@ static const struct wlr_output_impl output_impl = { .swap_buffers = output_swap_buffers, }; -struct wlr_x11_output *x11_output_create(struct wlr_x11_backend *x11) { +struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) { + assert(wlr_backend_is_x11(backend)); + struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend; + + if (!x11->started) { + ++x11->requested_outputs; + return NULL; + } + struct wlr_x11_output *output = calloc(1, sizeof(struct wlr_x11_output)); if (output == NULL) { return NULL; } output->x11 = x11; - output->frame_delay = 16; // 60 Hz struct wlr_output *wlr_output = &output->wlr_output; wlr_output_init(wlr_output, &x11->backend, &output_impl, x11->wl_display); - snprintf(wlr_output->name, sizeof(wlr_output->name), "X11-1"); + wlr_output->refresh = 60 * 1000000; + output->frame_delay = 16; // 60 Hz + + snprintf(wlr_output->name, sizeof(wlr_output->name), "X11-%d", + wl_list_length(&x11->outputs) + 1); parse_xcb_setup(wlr_output, x11->xcb_conn); uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; @@ -135,7 +147,7 @@ struct wlr_x11_output *x11_output_create(struct wlr_x11_backend *x11) { wl_list_insert(&x11->outputs, &output->link); wlr_signal_emit_safe(&x11->backend.events.new_output, wlr_output); - return output; + return wlr_output; } void x11_output_handle_configure_notify(struct wlr_x11_output *output, diff --git a/include/backend/x11.h b/include/backend/x11.h index 92a29725..aa058882 100644 --- a/include/backend/x11.h +++ b/include/backend/x11.h @@ -3,11 +3,12 @@ #include #include +#include +#include +#include #include #include #include -#include -#include #define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f @@ -28,6 +29,7 @@ struct wlr_x11_output { struct wlr_x11_backend { struct wlr_backend backend; struct wl_display *wl_display; + bool started; Display *xlib_conn; xcb_connection_t *xcb_conn; @@ -73,7 +75,6 @@ const struct wlr_input_device_impl input_device_impl; bool x11_handle_input_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event); -struct wlr_x11_output *x11_output_create(struct wlr_x11_backend *x11); void x11_output_handle_configure_notify(struct wlr_x11_output *output, xcb_configure_notify_event_t *event); diff --git a/include/wlr/backend/x11.h b/include/wlr/backend/x11.h index b22d7f68..7bc1f891 100644 --- a/include/wlr/backend/x11.h +++ b/include/wlr/backend/x11.h @@ -9,6 +9,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, const char *x11_display); +struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend); bool wlr_backend_is_x11(struct wlr_backend *backend); bool wlr_input_device_is_x11(struct wlr_input_device *device); -- cgit v1.2.3 From aa6ae710f70a1b57a71c8a900b0ef4268f60bb4b Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 30 Mar 2018 22:36:04 -0400 Subject: backend/x11: fix input events --- backend/x11/backend.c | 33 +++++++++++++++++++++++++++++++++ backend/x11/input_device.c | 22 ++++++++++++++++++---- include/backend/x11.h | 2 ++ 3 files changed, 53 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 80998f3f..82004058 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 200112L +#include #include #include #include @@ -32,6 +33,38 @@ struct wlr_x11_output *x11_output_from_window_id(struct wlr_x11_backend *x11, return NULL; } +void x11_output_layout_get_box(struct wlr_x11_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_x11_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; +} + static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event) { if (x11_handle_input_event(x11, event)) { diff --git a/backend/x11/input_device.c b/backend/x11/input_device.c index fb7f8b85..32b1a1ac 100644 --- a/backend/x11/input_device.c +++ b/backend/x11/input_device.c @@ -87,15 +87,29 @@ bool x11_handle_input_event(struct wlr_x11_backend *x11, if (output == NULL) { return false; } + struct wlr_output *wlr_output = &output->wlr_output; - struct wlr_event_pointer_motion_absolute abs = { + struct wlr_box box = { .x = ev->event_x, .y = ev->event_y }; + wlr_box_transform(&box, wlr_output->transform, wlr_output->width, + wlr_output->height, &box); + box.x /= wlr_output->scale; + box.y /= wlr_output->scale; + + struct wlr_box layout_box; + x11_output_layout_get_box(x11, &layout_box); + + double ox = wlr_output->lx / (double)layout_box.width; + double oy = wlr_output->ly / (double)layout_box.height; + + struct wlr_event_pointer_motion_absolute wlr_event = { .device = &x11->pointer_dev, .time_msec = ev->time, - .x = (double)ev->event_x / output->wlr_output.width, - .y = (double)ev->event_y / output->wlr_output.height, + .x = box.x / (double)layout_box.width + ox, + .y = box.y / (double)layout_box.height + oy, }; - wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); + wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &wlr_event); + x11->time = ev->time; return true; } diff --git a/include/backend/x11.h b/include/backend/x11.h index aa058882..0426e481 100644 --- a/include/backend/x11.h +++ b/include/backend/x11.h @@ -69,6 +69,8 @@ struct wlr_x11_backend { struct wlr_x11_output *x11_output_from_window_id(struct wlr_x11_backend *x11, xcb_window_t window); +void x11_output_layout_get_box(struct wlr_x11_backend *backend, + struct wlr_box *box); const struct wlr_input_device_impl input_device_impl; -- cgit v1.2.3