From c63d94483b1e52817ca01ca82a867a78ebd39fa6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 24 Mar 2018 18:30:28 -0400 Subject: Redesign wlr_texture - Textures are now immutable (apart from those created from raw pixels), no more invalid textures - Move all wl_drm stuff in wlr_renderer - Most of wlr_texture fields are now private - Remove some duplicated DMA-BUF code in the DRM backend - Add more assertions - Stride is now always given as bytes rather than pixels - Drop wl_shm functions Fun fact: this patch has been written 10,000 meters up in the air. --- backend/drm/drm.c | 23 ++++++++++------------- backend/drm/renderer.c | 48 +++++++++++++++++------------------------------- backend/wayland/output.c | 2 -- 3 files changed, 27 insertions(+), 46 deletions(-) (limited to 'backend') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 524e80bb..94bfbc96 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -181,9 +181,6 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) { if (plane->cursor_bo) { gbm_bo_destroy(plane->cursor_bo); } - if (plane->wlr_tex) { - wlr_texture_destroy(plane->wlr_tex); - } } free(drm->crtcs); @@ -586,12 +583,6 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, wlr_output_transform_invert(output->transform); wlr_matrix_projection(plane->matrix, plane->surf.width, plane->surf.height, transform); - - plane->wlr_tex = - wlr_render_texture_create(plane->surf.renderer->wlr_rend); - if (!plane->wlr_tex) { - return false; - } } struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y }; @@ -637,13 +628,18 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, wlr_drm_surface_make_current(&plane->surf, NULL); - wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, - stride, width, height, buf); - struct wlr_renderer *rend = plane->surf.renderer->wlr_rend; + + struct wlr_texture *texture = wlr_texture_from_pixels(rend, + WL_SHM_FORMAT_ARGB8888, stride, width, height, buf); + if (texture == NULL) { + wlr_log(L_ERROR, "Unable to create texture"); + return false; + } + wlr_renderer_begin(rend, plane->surf.width, plane->surf.height); wlr_renderer_clear(rend, (float[]){ 0.0, 0.0, 0.0, 0.0 }); - wlr_render_texture(rend, plane->wlr_tex, plane->matrix, 0, 0, 1.0f); + wlr_render_texture(rend, texture, plane->matrix, 0, 0, 1.0f); wlr_renderer_end(rend); wlr_renderer_read_pixels(rend, WL_SHM_FORMAT_ARGB8888, bo_stride, @@ -651,6 +647,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, wlr_drm_surface_swap_buffers(&plane->surf, NULL); + wlr_texture_destroy(texture); gbm_bo_unmap(plane->cursor_bo, bo_data); } diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index b2998b5f..2b50bb79 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -178,47 +178,33 @@ static void free_eglimage(struct gbm_bo *bo, void *data) { static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, struct gbm_bo *bo) { struct tex *tex = gbm_bo_get_user_data(bo); - if (tex) { + if (tex != NULL) { return tex->tex; } - // TODO: use wlr_texture_upload_dmabuf instead - - tex = malloc(sizeof(*tex)); - if (!tex) { - wlr_log_errno(L_ERROR, "Allocation failed"); + tex = calloc(1, sizeof(struct tex)); + if (tex == NULL) { return NULL; } - tex->egl = &renderer->egl; - - int dmabuf_fd = gbm_bo_get_fd(bo); - uint32_t width = gbm_bo_get_width(bo); - uint32_t height = gbm_bo_get_height(bo); - - EGLint attribs[] = { - EGL_WIDTH, width, - EGL_HEIGHT, height, - EGL_LINUX_DRM_FOURCC_EXT, gbm_bo_get_format(bo), - EGL_DMA_BUF_PLANE0_FD_EXT, dmabuf_fd, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, gbm_bo_get_offset(bo, 0), - EGL_DMA_BUF_PLANE0_PITCH_EXT, gbm_bo_get_stride_for_plane(bo, 0), - EGL_IMAGE_PRESERVED_KHR, EGL_FALSE, - EGL_NONE, + struct wlr_dmabuf_buffer_attribs attribs = { + .n_planes = 1, + .width = gbm_bo_get_width(bo), + .height = gbm_bo_get_height(bo), + .format = gbm_bo_get_format(bo), }; - - tex->img = eglCreateImageKHR(renderer->egl.display, EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, NULL, attribs); - if (!tex->img) { - wlr_log(L_ERROR, "Failed to create EGL image"); - abort(); + attribs.offset[0] = 0; + attribs.stride[0] = gbm_bo_get_stride_for_plane(bo, 0); + attribs.modifier[0] = 0; + attribs.fd[0] = gbm_bo_get_fd(bo); + + tex->tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs); + if (tex->tex == NULL) { + free(tex); + return NULL; } - tex->tex = wlr_render_texture_create(renderer->wlr_rend); - wlr_texture_upload_eglimage(tex->tex, tex->img, width, height); - gbm_bo_set_user_data(bo, tex, free_eglimage); - return tex->tex; } diff --git a/backend/wayland/output.c b/backend/wayland/output.c index d528c888..c1fa638a 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -99,8 +99,6 @@ static bool wlr_wl_output_set_cursor(struct wlr_output *_output, return true; } - stride *= 4; // stride is given in pixels, we need it in bytes - if (!backend->shm || !backend->pointer) { wlr_log(L_INFO, "cannot set cursor, no shm or pointer"); return false; -- cgit v1.2.3 From 3bda7e2ef8db955bb56e9dbf700974de06a2836b Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 26 Mar 2018 12:00:08 -0400 Subject: Use DRM_FORMAT_MOD_LINEAR instead of a hardcoded constant --- backend/drm/renderer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'backend') diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 2b50bb79..c1531ce3 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -14,6 +14,10 @@ #include "backend/drm/drm.h" #include "glapi.h" +#ifndef DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_LINEAR 0 +#endif + bool wlr_drm_renderer_init(struct wlr_drm_backend *drm, struct wlr_drm_renderer *renderer) { renderer->gbm = gbm_create_device(drm->fd); @@ -195,7 +199,7 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, }; attribs.offset[0] = 0; attribs.stride[0] = gbm_bo_get_stride_for_plane(bo, 0); - attribs.modifier[0] = 0; + attribs.modifier[0] = DRM_FORMAT_MOD_LINEAR; attribs.fd[0] = gbm_bo_get_fd(bo); tex->tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs); -- cgit v1.2.3 From 8d1b5c760098961501d3ece510a417a44fecd212 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 28 Mar 2018 00:04:32 -0400 Subject: backend/x11: correctly update keyboard modifiers --- backend/meson.build | 1 + backend/x11/backend.c | 33 +++++++++++++++++++++++++++++++++ meson.build | 51 ++++++++++++++++++++++++++------------------------- 3 files changed, 60 insertions(+), 25 deletions(-) (limited to 'backend') diff --git a/backend/meson.build b/backend/meson.build index a74ea024..df12d703 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -51,6 +51,7 @@ endif if conf_data.get('WLR_HAS_X11_BACKEND', false) backend_files += files('x11/backend.c') + backend_deps += xcb_xkb endif if conf_data.get('WLR_HAS_ELOGIND', false) diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 36d72d9e..79b896fe 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef __linux__ #include #elif __FreeBSD__ @@ -30,6 +31,10 @@ static const struct wlr_backend_impl backend_impl; static const struct wlr_output_impl output_impl; static const struct wlr_input_device_impl input_device_impl = { 0 }; +// TODO: remove global state +static uint8_t xkb_base_event; +static uint8_t xkb_base_error; + static uint32_t xcb_button_to_wl(uint32_t button) { switch (button) { case XCB_BUTTON_INDEX_1: return BTN_LEFT; @@ -157,6 +162,12 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e break; } default: + if (event->response_type == xkb_base_event) { + xcb_xkb_state_notify_event_t *ev = + (xcb_xkb_state_notify_event_t *)event; + wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods, + ev->latchedMods, ev->lockedMods, ev->lockedGroup); + } break; } @@ -225,6 +236,28 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { x11->screen->root, 0, 0, 1024, 768, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, x11->screen->root_visual, mask, values); + const xcb_query_extension_reply_t *reply = + xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id); + if (reply->present) { + xkb_base_event = reply->first_event; + xkb_base_error = reply->first_error; + + xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension( + x11->xcb_conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); + xcb_xkb_use_extension_reply_t *reply = + xcb_xkb_use_extension_reply(x11->xcb_conn, cookie, NULL); + if (reply && reply->supported) { + xcb_xkb_select_events(x11->xcb_conn, + XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_EVENT_TYPE_STATE_NOTIFY, + 0, + XCB_XKB_EVENT_TYPE_STATE_NOTIFY, + 0, + 0, + 0); + } + } + output->surf = wlr_egl_create_surface(&x11->egl, &output->win); if (!output->surf) { wlr_log(L_ERROR, "Failed to create EGL surface"); diff --git a/meson.build b/meson.build index 7740b416..a48984c1 100644 --- a/meson.build +++ b/meson.build @@ -82,35 +82,36 @@ if elogind.found() and get_option('enable_elogind') != 'false' endif if get_option('enable_x11_backend') or get_option('enable_xwayland') - xcb = dependency('xcb') - xcb_composite = dependency('xcb-composite') - xcb_xfixes = dependency('xcb-xfixes') - xcb_image = dependency('xcb-image') - xcb_render = dependency('xcb-render') - x11_xcb = dependency('x11-xcb') - - xcb_icccm = dependency('xcb-icccm', required: false) - xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true') - - if xcb_icccm.found() - conf_data.set('WLR_HAS_XCB_ICCCM', true) - endif - - if xcb_errors.found() and get_option('enable_xcb_errors') != 'false' - conf_data.set('WLR_HAS_XCB_ERRORS', true) - endif - - wlr_deps += [ - xcb, - xcb_composite, - x11_xcb, - ] + xcb = dependency('xcb') + xcb_composite = dependency('xcb-composite') + xcb_xfixes = dependency('xcb-xfixes') + xcb_xkb = dependency('xcb-xkb') # TODO: make this optional + xcb_image = dependency('xcb-image') + xcb_render = dependency('xcb-render') + x11_xcb = dependency('x11-xcb') + + xcb_icccm = dependency('xcb-icccm', required: false) + xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true') + + if xcb_icccm.found() + conf_data.set('WLR_HAS_XCB_ICCCM', true) + endif + + if xcb_errors.found() and get_option('enable_xcb_errors') != 'false' + conf_data.set('WLR_HAS_XCB_ERRORS', true) + endif + + wlr_deps += [ + xcb, + xcb_composite, + x11_xcb, + ] else - add_project_arguments('-DMESA_EGL_NO_X11_HEADERS', language: 'c') + add_project_arguments('-DMESA_EGL_NO_X11_HEADERS', language: 'c') endif if get_option('enable_x11_backend') - conf_data.set('WLR_HAS_X11_BACKEND', true) + conf_data.set('WLR_HAS_X11_BACKEND', true) endif if get_option('enable_xwayland') -- cgit v1.2.3 From f033f717a27b1ea0974db43118312c8b05587fec Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 28 Mar 2018 00:26:15 -0400 Subject: backend/x11: make xcb-xkb optional, remove global state --- backend/x11/backend.c | 61 ++++++++++++++++++++++++++++----------------------- include/backend/x11.h | 6 +++++ meson.build | 6 ++++- 3 files changed, 44 insertions(+), 29 deletions(-) (limited to 'backend') diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 79b896fe..7d560d97 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,12 +17,14 @@ #include #include #include -#include #ifdef __linux__ #include #elif __FreeBSD__ #include #endif +#ifdef WLR_HAS_XCB_XKB +#include +#endif #include "backend/x11.h" #include "util/signal.h" @@ -31,10 +34,6 @@ static const struct wlr_backend_impl backend_impl; static const struct wlr_output_impl output_impl; static const struct wlr_input_device_impl input_device_impl = { 0 }; -// TODO: remove global state -static uint8_t xkb_base_event; -static uint8_t xkb_base_error; - static uint32_t xcb_button_to_wl(uint32_t button) { switch (button) { case XCB_BUTTON_INDEX_1: return BTN_LEFT; @@ -162,12 +161,14 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e break; } default: - if (event->response_type == xkb_base_event) { +#ifdef WLR_HAS_XCB_XKB + if (x11->xkb_supported && event->response_type == x11->xkb_base_event) { xcb_xkb_state_notify_event_t *ev = (xcb_xkb_state_notify_event_t *)event; wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods, ev->latchedMods, ev->lockedMods, ev->lockedGroup); } +#endif break; } @@ -236,28 +237,6 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { x11->screen->root, 0, 0, 1024, 768, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, x11->screen->root_visual, mask, values); - const xcb_query_extension_reply_t *reply = - xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id); - if (reply->present) { - xkb_base_event = reply->first_event; - xkb_base_error = reply->first_error; - - xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension( - x11->xcb_conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); - xcb_xkb_use_extension_reply_t *reply = - xcb_xkb_use_extension_reply(x11->xcb_conn, cookie, NULL); - if (reply && reply->supported) { - xcb_xkb_select_events(x11->xcb_conn, - XCB_XKB_ID_USE_CORE_KBD, - XCB_XKB_EVENT_TYPE_STATE_NOTIFY, - 0, - XCB_XKB_EVENT_TYPE_STATE_NOTIFY, - 0, - 0, - 0); - } - } - output->surf = wlr_egl_create_surface(&x11->egl, &output->win); if (!output->surf) { wlr_log(L_ERROR, "Failed to create EGL surface"); @@ -315,6 +294,32 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { strlen(title), title); } +#ifdef WLR_HAS_XCB_XKB + const xcb_query_extension_reply_t *reply = + xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id); + if (reply != NULL && reply->present) { + x11->xkb_base_event = reply->first_event; + x11->xkb_base_error = reply->first_error; + + xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension( + x11->xcb_conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); + xcb_xkb_use_extension_reply_t *reply = + xcb_xkb_use_extension_reply(x11->xcb_conn, cookie, NULL); + if (reply != NULL && reply->supported) { + x11->xkb_supported = true; + + xcb_xkb_select_events(x11->xcb_conn, + XCB_XKB_ID_USE_CORE_KBD, + XCB_XKB_EVENT_TYPE_STATE_NOTIFY, + 0, + XCB_XKB_EVENT_TYPE_STATE_NOTIFY, + 0, + 0, + 0); + } + } +#endif + xcb_map_window(x11->xcb_conn, output->win); xcb_flush(x11->xcb_conn); wlr_output_update_enabled(&output->wlr_output, true); diff --git a/include/backend/x11.h b/include/backend/x11.h index 840509bf..72710f6c 100644 --- a/include/backend/x11.h +++ b/include/backend/x11.h @@ -48,6 +48,12 @@ struct wlr_x11_backend { // The time we last received an event xcb_timestamp_t time; +#ifdef WLR_HAS_XCB_XKB + bool xkb_supported; + uint8_t xkb_base_event; + uint8_t xkb_base_error; +#endif + struct wl_listener display_destroy; }; diff --git a/meson.build b/meson.build index a48984c1..04c93817 100644 --- a/meson.build +++ b/meson.build @@ -85,18 +85,22 @@ if get_option('enable_x11_backend') or get_option('enable_xwayland') xcb = dependency('xcb') xcb_composite = dependency('xcb-composite') xcb_xfixes = dependency('xcb-xfixes') - xcb_xkb = dependency('xcb-xkb') # TODO: make this optional xcb_image = dependency('xcb-image') xcb_render = dependency('xcb-render') x11_xcb = dependency('x11-xcb') xcb_icccm = dependency('xcb-icccm', required: false) + xcb_xkb = dependency('xcb-xkb', required: false) xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true') if xcb_icccm.found() conf_data.set('WLR_HAS_XCB_ICCCM', true) endif + if xcb_xkb.found() + conf_data.set('WLR_HAS_XCB_XKB', true) + endif + if xcb_errors.found() and get_option('enable_xcb_errors') != 'false' conf_data.set('WLR_HAS_XCB_ERRORS', true) endif -- cgit v1.2.3 From a35a5786b0e40cb1ffa87344d3cb21dff9fd99f4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 10:46:50 -0400 Subject: Remove width_mm from wlr_pointer events --- backend/libinput/pointer.c | 5 ++--- backend/wayland/wl_seat.c | 6 ++---- backend/x11/backend.c | 12 ++++-------- examples/multi-pointer.c | 3 +-- examples/pointer.c | 6 +++--- examples/support/shared.c | 4 ++-- include/wlr/types/wlr_cursor.h | 2 +- include/wlr/types/wlr_pointer.h | 4 ++-- rootston/cursor.c | 4 ++-- types/wlr_cursor.c | 6 +++--- 10 files changed, 22 insertions(+), 30 deletions(-) (limited to 'backend') diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index 8a31d312..9ccda634 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -53,9 +53,8 @@ void handle_pointer_motion_abs(struct libinput_event *event, wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); - wlr_event.x_mm = libinput_event_pointer_get_absolute_x(pevent); - wlr_event.y_mm = libinput_event_pointer_get_absolute_y(pevent); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); + wlr_event.x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1); + wlr_event.y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1); wlr_signal_emit_safe(&wlr_dev->pointer->events.motion_absolute, &wlr_event); } diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 6ca59130..2d4f76de 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -80,10 +80,8 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, struct wlr_event_pointer_motion_absolute wlr_event; wlr_event.device = dev; wlr_event.time_msec = time; - 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; + wlr_event.x = transformed.x / layout_box.width; + wlr_event.y = transformed.y / layout_box.height; wlr_signal_emit_safe(&dev->pointer->events.motion_absolute, &wlr_event); } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 36d72d9e..f534676d 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -108,10 +108,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e struct wlr_event_pointer_motion_absolute abs = { .device = &x11->pointer_dev, .time_msec = ev->time, - .x_mm = ev->event_x, - .y_mm = ev->event_y, - .width_mm = output->wlr_output.width, - .height_mm = output->wlr_output.height, + .x = (double)ev->event_x / output->wlr_output.width, + .y = (double)ev->event_y / output->wlr_output.height, }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); @@ -136,10 +134,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e struct wlr_event_pointer_motion_absolute abs = { .device = &x11->pointer_dev, .time_msec = x11->time, - .x_mm = pointer->root_x, - .y_mm = pointer->root_y, - .width_mm = output->wlr_output.width, - .height_mm = output->wlr_output.height, + .x = (double)pointer->root_x / output->wlr_output.width, + .y = (double)pointer->root_y / output->wlr_output.height, }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index 1f869f50..46f0e78f 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -118,8 +118,7 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, struct sample_cursor *cursor = wl_container_of(listener, cursor, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); } static void handle_input_add(struct compositor_state *state, diff --git a/examples/pointer.c b/examples/pointer.c index 9794e6e5..12312092 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -154,8 +154,8 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, wl_container_of(listener, sample, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; - sample->cur_x = event->x_mm; - sample->cur_y = event->y_mm; + sample->cur_x = event->x; + sample->cur_y = event->y; wlr_cursor_warp_absolute(sample->cursor, event->device, sample->cur_x, sample->cur_y); @@ -252,7 +252,7 @@ static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { wlr_cursor_warp_absolute(sample->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + event->x_mm / event->width_mm, event->y_mm / event->height_mm); } } diff --git a/examples/support/shared.c b/examples/support/shared.c index e6233206..c6460374 100644 --- a/examples/support/shared.c +++ b/examples/support/shared.c @@ -108,8 +108,8 @@ static void pointer_motion_absolute_notify(struct wl_listener *listener, void *d struct wlr_event_pointer_motion_absolute *event = data; struct pointer_state *pstate = wl_container_of(listener, pstate, motion_absolute); if (pstate->compositor->pointer_motion_absolute_cb) { - pstate->compositor->pointer_motion_absolute_cb(pstate, - event->x_mm, event->y_mm); + pstate->compositor->pointer_motion_absolute_cb( + pstate, event->x, event->y); } } diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 70dca9f7..ffe149c9 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -73,7 +73,7 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, double x, double y); void wlr_cursor_warp_absolute(struct wlr_cursor *cur, - struct wlr_input_device *dev, double x_mm, double y_mm); + struct wlr_input_device *dev, double x, double y); /** * Move the cursor in the direction of the given x and y coordinates. diff --git a/include/wlr/types/wlr_pointer.h b/include/wlr/types/wlr_pointer.h index e7ac9b46..a8969b9e 100644 --- a/include/wlr/types/wlr_pointer.h +++ b/include/wlr/types/wlr_pointer.h @@ -29,8 +29,8 @@ struct wlr_event_pointer_motion { struct wlr_event_pointer_motion_absolute { struct wlr_input_device *device; uint32_t time_msec; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; }; struct wlr_event_pointer_button { diff --git a/rootston/cursor.c b/rootston/cursor.c index 52439dff..c1fd7d31 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -288,8 +288,8 @@ void roots_cursor_handle_motion(struct roots_cursor *cursor, void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, struct wlr_event_pointer_motion_absolute *event) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(cursor->cursor, + event->device, event->x, event->y); roots_cursor_update_position(cursor, event->time_msec); } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 20acebf1..ed1a67da 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -254,7 +254,7 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, } void wlr_cursor_warp_absolute(struct wlr_cursor *cur, - struct wlr_input_device *dev, double x_mm, double y_mm) { + struct wlr_input_device *dev, double x, double y) { assert(cur->state->layout); struct wlr_box *mapping = get_mapping(cur, dev); @@ -262,8 +262,8 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - double x = x_mm > 0 ? mapping->width * x_mm + mapping->x : cur->x; - double y = y_mm > 0 ? mapping->height * y_mm + mapping->y : cur->y; + x = x > 0 ? mapping->width * x + mapping->x : cur->x; + y = y > 0 ? mapping->height * y + mapping->y : cur->y; wlr_cursor_warp_unchecked(cur, x, y); } -- cgit v1.2.3 From 324b9d910dc237151fd71c01bef015d0080be191 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 11:04:40 -0400 Subject: Remove width_mm from wlr_touch events --- backend/drm/legacy.c | 2 +- backend/libinput/touch.c | 10 ++++------ examples/pointer.c | 8 ++++---- examples/support/shared.c | 8 ++++---- examples/support/shared.h | 8 ++++---- examples/touch.c | 16 ++++++++-------- include/wlr/types/wlr_cursor.h | 2 +- include/wlr/types/wlr_touch.h | 8 ++++---- rootston/cursor.c | 9 +++------ types/wlr_cursor.c | 12 ++++-------- 10 files changed, 37 insertions(+), 46 deletions(-) (limited to 'backend') diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index 88a01b89..7c45ae21 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -47,7 +47,7 @@ bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32, plane->surf.width, plane->surf.height)) { - wlr_log_errno(L_ERROR, "Failed to set hardware cursor"); + wlr_log_errno(L_DEBUG, "Failed to set hardware cursor"); return false; } diff --git a/backend/libinput/touch.c b/backend/libinput/touch.c index 2b87f9cd..419c11ea 100644 --- a/backend/libinput/touch.c +++ b/backend/libinput/touch.c @@ -35,9 +35,8 @@ void handle_touch_down(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_touch_get_time_usec(tevent)); wlr_event.touch_id = libinput_event_touch_get_slot(tevent); - wlr_event.x_mm = libinput_event_touch_get_x(tevent); - wlr_event.y_mm = libinput_event_touch_get_y(tevent); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); + wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1); + wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1); wlr_signal_emit_safe(&wlr_dev->touch->events.down, &wlr_event); } @@ -74,9 +73,8 @@ void handle_touch_motion(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_touch_get_time_usec(tevent)); wlr_event.touch_id = libinput_event_touch_get_slot(tevent); - wlr_event.x_mm = libinput_event_touch_get_x(tevent); - wlr_event.y_mm = libinput_event_touch_get_y(tevent); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); + wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1); + wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1); wlr_signal_emit_safe(&wlr_dev->touch->events.motion, &wlr_event); } diff --git a/examples/pointer.c b/examples/pointer.c index 12312092..2c598b9a 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -217,8 +217,8 @@ static void handle_touch_down(struct wl_listener *listener, void *data) { struct wlr_event_touch_down *event = data; struct touch_point *point = calloc(1, sizeof(struct touch_point)); point->touch_id = event->touch_id; - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; + point->x = event->x; + point->y = event->y; wl_list_insert(&sample->touch_points, &point->link); warp_to_touch(sample, event->device); @@ -232,8 +232,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { struct touch_point *point; wl_list_for_each(point, &sample->touch_points, link) { if (point->touch_id == event->touch_id) { - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; + point->x = event->x; + point->y = event->y; break; } } diff --git a/examples/support/shared.c b/examples/support/shared.c index c6460374..02b324f5 100644 --- a/examples/support/shared.c +++ b/examples/support/shared.c @@ -167,8 +167,8 @@ static void touch_down_notify(struct wl_listener *listener, void *data) { struct wlr_event_touch_down *event = data; struct touch_state *tstate = wl_container_of(listener, tstate, down); if (tstate->compositor->touch_down_cb) { - tstate->compositor->touch_down_cb(tstate, event->touch_id, - event->x_mm, event->y_mm, event->width_mm, event->height_mm); + tstate->compositor->touch_down_cb(tstate, + event->touch_id, event->x, event->y); } } @@ -176,8 +176,8 @@ static void touch_motion_notify(struct wl_listener *listener, void *data) { struct wlr_event_touch_motion *event = data; struct touch_state *tstate = wl_container_of(listener, tstate, motion); if (tstate->compositor->touch_motion_cb) { - tstate->compositor->touch_motion_cb(tstate, event->touch_id, - event->x_mm, event->y_mm, event->width_mm, event->height_mm); + tstate->compositor->touch_motion_cb(tstate, + event->touch_id, event->x, event->y); } } diff --git a/examples/support/shared.h b/examples/support/shared.h index d00e75b3..2079a9ef 100644 --- a/examples/support/shared.h +++ b/examples/support/shared.h @@ -102,10 +102,10 @@ struct compositor_state { enum wlr_axis_source source, enum wlr_axis_orientation orientation, double delta); - void (*touch_down_cb)(struct touch_state *s, int32_t touch_id, - double x, double y, double width, double height); - void (*touch_motion_cb)(struct touch_state *s, int32_t touch_id, - double x, double y, double width, double height); + void (*touch_down_cb)(struct touch_state *s, + int32_t touch_id, double x, double y); + void (*touch_motion_cb)(struct touch_state *s, + int32_t touch_id, double x, double y); void (*touch_up_cb)(struct touch_state *s, int32_t touch_id); void (*touch_cancel_cb)(struct touch_state *s, int32_t touch_id); void (*tool_axis_cb)(struct tablet_tool_state *s, diff --git a/examples/touch.c b/examples/touch.c index 7639165c..e9dcf29c 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -60,13 +60,13 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts wlr_output_swap_buffers(wlr_output, NULL, NULL); } -static void handle_touch_down(struct touch_state *tstate, int32_t touch_id, - double x, double y, double width, double height) { +static void handle_touch_down(struct touch_state *tstate, + int32_t touch_id, double x, double y) { struct sample_state *sample = tstate->compositor->data; struct touch_point *point = calloc(1, sizeof(struct touch_point)); point->touch_id = touch_id; - point->x = x / width; - point->y = y / height; + point->x = x; + point->y = y; wl_list_insert(&sample->touch_points, &point->link); } @@ -81,14 +81,14 @@ static void handle_touch_up(struct touch_state *tstate, int32_t touch_id) { } } -static void handle_touch_motion(struct touch_state *tstate, int32_t touch_id, - double x, double y, double width, double height) { +static void handle_touch_motion(struct touch_state *tstate, + int32_t touch_id, double x, double y) { struct sample_state *sample = tstate->compositor->data; struct touch_point *point; wl_list_for_each(point, &sample->touch_points, link) { if (point->touch_id == touch_id) { - point->x = x / width; - point->y = y / height; + point->x = x; + point->y = y; break; } } diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index ffe149c9..fc541271 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -156,6 +156,6 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, */ bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, struct wlr_input_device *device, double x_mm, double y_mm, - double width_mm, double height_mm, double *lx, double *ly); + double *lx, double *ly); #endif diff --git a/include/wlr/types/wlr_touch.h b/include/wlr/types/wlr_touch.h index 8ea293eb..70070f84 100644 --- a/include/wlr/types/wlr_touch.h +++ b/include/wlr/types/wlr_touch.h @@ -23,8 +23,8 @@ struct wlr_event_touch_down { struct wlr_input_device *device; uint32_t time_msec; int32_t touch_id; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; }; struct wlr_event_touch_up { @@ -37,8 +37,8 @@ struct wlr_event_touch_motion { struct wlr_input_device *device; uint32_t time_msec; int32_t touch_id; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; }; struct wlr_event_touch_cancel { diff --git a/rootston/cursor.c b/rootston/cursor.c index c1fd7d31..786dff0e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -310,10 +310,8 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct roots_desktop *desktop = cursor->seat->input->server->desktop; struct wlr_surface *surface = NULL; double lx, ly; - bool result = - wlr_cursor_absolute_to_layout_coords(cursor->cursor, - event->device, event->x_mm, event->y_mm, event->width_mm, - event->height_mm, &lx, &ly); + bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, + event->device, event->x, event->y, &lx, &ly); if (!result) { return; } @@ -365,8 +363,7 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, double lx, ly; bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, - event->device, event->x_mm, event->y_mm, event->width_mm, - event->height_mm, &lx, &ly); + event->device, event->x, event->y, &lx, &ly); if (!result) { return; } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index ed1a67da..5142513b 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -640,19 +640,15 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, } bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, - struct wlr_input_device *device, double x_mm, double y_mm, - double width_mm, double height_mm, double *lx, double *ly) { - if (width_mm <= 0 || height_mm <= 0) { - return false; - } - + struct wlr_input_device *device, double x, double y, + double *lx, double *ly) { struct wlr_box *mapping = get_mapping(cur, device); if (!mapping) { mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - *lx = x_mm > 0 ? mapping->width * (x_mm / width_mm) + mapping->x : cur->x; - *ly = y_mm > 0 ? mapping->height * (y_mm / height_mm) + mapping->y : cur->y; + *lx = x > 0 ? mapping->width * x + mapping->x : cur->x; + *ly = y > 0 ? mapping->height * y + mapping->y : cur->y; return true; } -- cgit v1.2.3 From ac219cbda6dc3122fcc7f1bfa89b7e8fbb03b8ce Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 11:40:35 -0400 Subject: Remove width_mm from tablet events --- backend/libinput/events.c | 2 ++ backend/libinput/tablet_tool.c | 5 ++--- examples/pointer.c | 4 ++-- examples/tablet.c | 27 +++++++++++++++++++-------- include/wlr/types/wlr_input_device.h | 2 ++ include/wlr/types/wlr_tablet_tool.h | 12 ++++++------ rootston/cursor.c | 8 +++----- 7 files changed, 36 insertions(+), 24 deletions(-) (limited to 'backend') diff --git a/backend/libinput/events.c b/backend/libinput/events.c index d92de830..da7b2be4 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -46,6 +46,8 @@ static struct wlr_input_device *allocate_device( return NULL; } struct wlr_input_device *wlr_dev = &wlr_libinput_dev->wlr_input_device; + libinput_device_get_size(libinput_dev, + &wlr_dev->width_mm, &wlr_dev->height_mm); wl_list_insert(wlr_devices, &wlr_dev->link); wlr_libinput_dev->handle = libinput_dev; libinput_device_ref(libinput_dev); diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 27cf7c81..815c4daf 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -34,14 +34,13 @@ void handle_tablet_tool_axis(struct libinput_event *event, wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); if (libinput_event_tablet_tool_x_has_changed(tevent)) { wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_X; - wlr_event.x_mm = libinput_event_tablet_tool_get_x(tevent); + wlr_event.x = libinput_event_tablet_tool_get_x_transformed(tevent, 1); } if (libinput_event_tablet_tool_y_has_changed(tevent)) { wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_Y; - wlr_event.y_mm = libinput_event_tablet_tool_get_y(tevent); + wlr_event.y = libinput_event_tablet_tool_get_y_transformed(tevent, 1); } if (libinput_event_tablet_tool_pressure_has_changed(tevent)) { wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_PRESSURE; diff --git a/examples/pointer.c b/examples/pointer.c index 2c598b9a..aaaad841 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -251,8 +251,8 @@ static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { struct wlr_event_tablet_tool_axis *event = data; if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(sample->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(sample->cursor, + event->device, event->x, event->y); } } diff --git a/examples/tablet.c b/examples/tablet.c index 9379fac3..be428f86 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -28,7 +28,7 @@ struct sample_state { bool proximity, tap, button; double distance; double pressure; - double x_mm, y_mm; + double x, y; double x_tilt, y_tilt; double width_mm, height_mm; double ring; @@ -69,8 +69,8 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts if (sample->proximity) { struct wlr_box box = { - .x = sample->x_mm * scale - 8 * (sample->pressure + 1) + left, - .y = sample->y_mm * scale - 8 * (sample->pressure + 1) + top, + .x = (sample->x * pad_width) - 8 * (sample->pressure + 1) + left, + .y = (sample->y * pad_height) - 8 * (sample->pressure + 1) + top, .width = 16 * (sample->pressure + 1), .height = 16 * (sample->pressure + 1), }; @@ -94,13 +94,11 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts static void handle_tool_axis(struct tablet_tool_state *tstate, struct wlr_event_tablet_tool_axis *event) { struct sample_state *sample = tstate->compositor->data; - sample->width_mm = event->width_mm; - sample->height_mm = event->height_mm; if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) { - sample->x_mm = event->x_mm; + sample->x = event->x; } if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - sample->y_mm = event->y_mm; + sample->y = event->y; } if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_DISTANCE)) { sample->distance = event->distance; @@ -164,13 +162,24 @@ static void handle_pad_ring(struct tablet_pad_state *pstate, } } +static void handle_input_add(struct compositor_state *cstate, + struct wlr_input_device *inputdev) { + struct sample_state *sample = cstate->data; + if (inputdev->type == WLR_INPUT_DEVICE_TABLET_TOOL) { + sample->width_mm = inputdev->width_mm == 0 ? + 20 : inputdev->width_mm; + sample->height_mm = inputdev->height_mm == 0 ? + 10 : inputdev->height_mm; + } +} + int main(int argc, char *argv[]) { wlr_log_init(L_DEBUG, NULL); struct sample_state state = { .tool_color = { 1, 1, 1, 1 }, .pad_color = { 0.5, 0.5, 0.5, 1.0 } }; - struct compositor_state compositor = { 0, + struct compositor_state compositor = { .data = &state, .output_frame_cb = handle_output_frame, .tool_axis_cb = handle_tool_axis, @@ -178,6 +187,8 @@ int main(int argc, char *argv[]) { .tool_button_cb = handle_tool_button, .pad_button_cb = handle_pad_button, .pad_ring_cb = handle_pad_ring, + .input_add_cb = handle_input_add, + 0 }; compositor_init(&compositor); diff --git a/include/wlr/types/wlr_input_device.h b/include/wlr/types/wlr_input_device.h index 6d8e3631..d65172c1 100644 --- a/include/wlr/types/wlr_input_device.h +++ b/include/wlr/types/wlr_input_device.h @@ -29,6 +29,8 @@ struct wlr_input_device { enum wlr_input_device_type type; int vendor, product; char *name; + // Or 0 if not applicable to this device + double width_mm, height_mm; /* wlr_input_device.type determines which of these is valid */ union { diff --git a/include/wlr/types/wlr_tablet_tool.h b/include/wlr/types/wlr_tablet_tool.h index 59e49ef8..22bf2649 100644 --- a/include/wlr/types/wlr_tablet_tool.h +++ b/include/wlr/types/wlr_tablet_tool.h @@ -36,8 +36,8 @@ struct wlr_event_tablet_tool_axis { struct wlr_input_device *device; uint32_t time_msec; uint32_t updated_axes; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; double pressure; double distance; double tilt_x, tilt_y; @@ -54,8 +54,8 @@ enum wlr_tablet_tool_proximity_state { struct wlr_event_tablet_tool_proximity { struct wlr_input_device *device; uint32_t time_msec; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; enum wlr_tablet_tool_proximity_state state; }; @@ -67,8 +67,8 @@ enum wlr_tablet_tool_tip_state { struct wlr_event_tablet_tool_tip { struct wlr_input_device *device; uint32_t time_msec; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; enum wlr_tablet_tool_tip_state state; }; diff --git a/rootston/cursor.c b/rootston/cursor.c index 786dff0e..a5953e4a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -392,15 +392,13 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + event->x, event->y); roots_cursor_update_position(cursor, event->time_msec); } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, -1); + wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, -1); roots_cursor_update_position(cursor, event->time_msec); } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - -1, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(cursor->cursor, event->device, -1, event->y); roots_cursor_update_position(cursor, event->time_msec); } } -- cgit v1.2.3 From 3813121fefb1734ed2c2537759e6eead1c0d9a74 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 14:04:23 -0400 Subject: Fix wayland output absolute input handling --- backend/wayland/wl_seat.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'backend') diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 2d4f76de..a5821311 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -64,6 +64,9 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, wl_egl_window_get_attached_size(wlr_wl_pointer->current_output->egl_window, &width, &height); + int owidth, oheight; + wlr_output_effective_resolution(wlr_output, &owidth, &oheight); + struct wlr_box box = { .x = wl_fixed_to_int(surface_x), .y = wl_fixed_to_int(surface_y), @@ -80,8 +83,15 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, struct wlr_event_pointer_motion_absolute wlr_event; wlr_event.device = dev; wlr_event.time_msec = time; - wlr_event.x = transformed.x / layout_box.width; - wlr_event.y = transformed.y / layout_box.height; + + double tx = transformed.x / (double)owidth; + double ty = transformed.y / (double)oheight; + double ox = wlr_output->lx / (double)layout_box.width; + double oy = wlr_output->ly / (double)layout_box.height; + + wlr_event.x = tx * ((double)owidth / layout_box.width) + ox; + wlr_event.y = ty * ((double)oheight / layout_box.height) + oy; + wlr_signal_emit_safe(&dev->pointer->events.motion_absolute, &wlr_event); } -- cgit v1.2.3 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 --- backend/meson.build | 6 +- backend/x11/backend.c | 300 +++++++-------------------------------------- backend/x11/input_device.c | 122 ++++++++++++++++++ backend/x11/output.c | 170 +++++++++++++++++++++++++ include/backend/x11.h | 24 +++- 5 files changed, 365 insertions(+), 257 deletions(-) create mode 100644 backend/x11/input_device.c create mode 100644 backend/x11/output.c (limited to 'backend') diff --git a/backend/meson.build b/backend/meson.build index df12d703..52abe64d 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -50,7 +50,11 @@ if conf_data.get('WLR_HAS_SYSTEMD', false) endif if conf_data.get('WLR_HAS_X11_BACKEND', false) - backend_files += files('x11/backend.c') + backend_files += files( + 'x11/backend.c', + 'x11/input_device.c', + 'x11/output.c', + ) backend_deps += xcb_xkb endif diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 8abc5d84..c72cdcac 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -1,5 +1,4 @@ #define _POSIX_C_SOURCE 200112L -#include #include #include #include @@ -10,162 +9,66 @@ #include #include #include -#include #include #include #include #include #include #include -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif #ifdef WLR_HAS_XCB_XKB #include #endif #include "backend/x11.h" #include "util/signal.h" -#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f - -static const struct wlr_backend_impl backend_impl; -static const struct wlr_output_impl output_impl; -static const struct wlr_input_device_impl input_device_impl = { 0 }; - -static uint32_t xcb_button_to_wl(uint32_t button) { - switch (button) { - case XCB_BUTTON_INDEX_1: return BTN_LEFT; - case XCB_BUTTON_INDEX_2: return BTN_MIDDLE; - case XCB_BUTTON_INDEX_3: return BTN_RIGHT; - // XXX: I'm not sure the scroll-wheel direction is right - case XCB_BUTTON_INDEX_4: return BTN_GEAR_UP; - case XCB_BUTTON_INDEX_5: return BTN_GEAR_DOWN; - default: return 0; +struct wlr_x11_output *x11_output_from_window_id(struct wlr_x11_backend *x11, + xcb_window_t window) { + struct wlr_x11_output *output; + wl_list_for_each(output, &x11->outputs, link) { + if (output->win == window) { + return output; + } } + return NULL; } -static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event) { - struct wlr_x11_output *output = &x11->output; +static bool handle_x11_event(struct wlr_x11_backend *x11, + xcb_generic_event_t *event) { + if (x11_handle_input_event(x11, event)) { + return false; + } switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { case XCB_EXPOSE: { - wlr_output_send_frame(&output->wlr_output); - break; - } - case XCB_KEY_PRESS: - case XCB_KEY_RELEASE: { - xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; - struct wlr_event_keyboard_key key = { - .time_msec = ev->time, - .keycode = ev->detail - 8, - .state = event->response_type == XCB_KEY_PRESS ? - WLR_KEY_PRESSED : WLR_KEY_RELEASED, - .update_state = true, - }; - - // TODO use xcb-xkb for more precise modifiers state? - wlr_keyboard_notify_key(&x11->keyboard, &key); - x11->time = ev->time; - break; - } - case XCB_BUTTON_PRESS: { - xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; - - if (ev->detail == XCB_BUTTON_INDEX_4 || - ev->detail == XCB_BUTTON_INDEX_5) { - double delta = (ev->detail == XCB_BUTTON_INDEX_4 ? -15 : 15); - struct wlr_event_pointer_axis axis = { - .device = &x11->pointer_dev, - .time_msec = ev->time, - .source = WLR_AXIS_SOURCE_WHEEL, - .orientation = WLR_AXIS_ORIENTATION_VERTICAL, - .delta = delta, - }; - wlr_signal_emit_safe(&x11->pointer.events.axis, &axis); - x11->time = ev->time; - break; - } - } - /* fallthrough */ - case XCB_BUTTON_RELEASE: { - xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; - - if (ev->detail != XCB_BUTTON_INDEX_4 && - ev->detail != XCB_BUTTON_INDEX_5) { - struct wlr_event_pointer_button button = { - .device = &x11->pointer_dev, - .time_msec = ev->time, - .button = xcb_button_to_wl(ev->detail), - .state = event->response_type == XCB_BUTTON_PRESS ? - WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED, - }; - - wlr_signal_emit_safe(&x11->pointer.events.button, &button); + xcb_expose_event_t *ev = (xcb_expose_event_t *)event; + struct wlr_x11_output *output = + x11_output_from_window_id(x11, ev->window); + if (output != NULL) { + wlr_output_send_frame(&output->wlr_output); } - x11->time = ev->time; - break; - } - case XCB_MOTION_NOTIFY: { - xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; - struct wlr_event_pointer_motion_absolute abs = { - .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, - }; - - wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); - x11->time = ev->time; break; } case XCB_CONFIGURE_NOTIFY: { - xcb_configure_notify_event_t *ev = (xcb_configure_notify_event_t *)event; - - wlr_output_update_custom_mode(&output->wlr_output, ev->width, - ev->height, 0); - - // Move the pointer to its new location - xcb_query_pointer_cookie_t cookie = - xcb_query_pointer(x11->xcb_conn, output->win); - xcb_query_pointer_reply_t *pointer = - xcb_query_pointer_reply(x11->xcb_conn, cookie, NULL); - if (!pointer) { - break; + xcb_configure_notify_event_t *ev = + (xcb_configure_notify_event_t *)event; + struct wlr_x11_output *output = + x11_output_from_window_id(x11, ev->window); + if (output != NULL) { + x11_output_handle_configure_notify(output, ev); } - - struct wlr_event_pointer_motion_absolute abs = { - .device = &x11->pointer_dev, - .time_msec = x11->time, - .x = (double)pointer->root_x / output->wlr_output.width, - .y = (double)pointer->root_y / output->wlr_output.height, - }; - - wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); - free(pointer); break; } case XCB_CLIENT_MESSAGE: { xcb_client_message_event_t *ev = (xcb_client_message_event_t *)event; - if (ev->data.data32[0] == x11->atoms.wm_delete_window) { - wl_display_terminate(x11->wl_display); - return true; + struct wlr_x11_output *output = + x11_output_from_window_id(x11, ev->window); + if (output != NULL) { + wlr_output_destroy(&output->wlr_output); + } } - break; } - default: -#ifdef WLR_HAS_XCB_XKB - if (x11->xkb_supported && event->response_type == x11->xkb_base_event) { - xcb_xkb_state_notify_event_t *ev = - (xcb_xkb_state_notify_event_t *)event; - wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods, - ev->latchedMods, ev->lockedMods, ev->lockedGroup); - } -#endif - break; } return false; @@ -180,64 +83,19 @@ static int x11_event(int fd, uint32_t mask, void *data) { } xcb_generic_event_t *e; - bool quit = false; - while (!quit && (e = xcb_poll_for_event(x11->xcb_conn))) { - quit = handle_x11_event(x11, e); + while ((e = xcb_poll_for_event(x11->xcb_conn))) { + bool quit = handle_x11_event(x11, e); free(e); + if (quit) { + break; + } } return 0; } -static int signal_frame(void *data) { - struct wlr_x11_backend *x11 = data; - wlr_output_send_frame(&x11->output.wlr_output); - wl_event_source_timer_update(x11->frame_timer, 16); - return 0; -} - -static void parse_xcb_setup(struct wlr_output *output, xcb_connection_t *xcb_conn) { - const xcb_setup_t *xcb_setup = xcb_get_setup(xcb_conn); - - snprintf(output->make, sizeof(output->make), "%.*s", - xcb_setup_vendor_length(xcb_setup), - xcb_setup_vendor(xcb_setup)); - snprintf(output->model, sizeof(output->model), "%"PRIu16".%"PRIu16, - xcb_setup->protocol_major_version, - xcb_setup->protocol_minor_version); -} - static bool wlr_x11_backend_start(struct wlr_backend *backend) { struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend; - struct wlr_x11_output *output = &x11->output; - - uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - uint32_t values[2] = { - x11->screen->white_pixel, - XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_POINTER_MOTION | - XCB_EVENT_MASK_STRUCTURE_NOTIFY - }; - - output->x11 = x11; - - wlr_output_init(&output->wlr_output, &x11->backend, &output_impl, - x11->wl_display); - snprintf(output->wlr_output.name, sizeof(output->wlr_output.name), "X11-1"); - parse_xcb_setup(&output->wlr_output, x11->xcb_conn); - - output->win = xcb_generate_id(x11->xcb_conn); - xcb_create_window(x11->xcb_conn, XCB_COPY_FROM_PARENT, output->win, - x11->screen->root, 0, 0, 1024, 768, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, - x11->screen->root_visual, mask, values); - - output->surf = wlr_egl_create_surface(&x11->egl, &output->win); - if (!output->surf) { - wlr_log(L_ERROR, "Failed to create EGL surface"); - return false; - } struct { const char *name; @@ -279,17 +137,6 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { } } - xcb_change_property(x11->xcb_conn, XCB_PROP_MODE_REPLACE, output->win, - x11->atoms.wm_protocols, XCB_ATOM_ATOM, 32, 1, - &x11->atoms.wm_delete_window); - - char title[32]; - if (snprintf(title, sizeof(title), "wlroots - %s", output->wlr_output.name)) { - xcb_change_property(x11->xcb_conn, XCB_PROP_MODE_REPLACE, output->win, - x11->atoms.net_wm_name, x11->atoms.utf8_string, 8, - strlen(title), title); - } - #ifdef WLR_HAS_XCB_XKB const xcb_query_extension_reply_t *reply = xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id); @@ -316,15 +163,12 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { } #endif - xcb_map_window(x11->xcb_conn, output->win); - xcb_flush(x11->xcb_conn); - wlr_output_update_enabled(&output->wlr_output, true); - - wlr_signal_emit_safe(&x11->backend.events.new_output, output); wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->keyboard_dev); wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->pointer_dev); - wl_event_source_timer_update(x11->frame_timer, 16); + for (size_t i = 0; i < x11->requested_outputs; ++i) { + x11_output_create(x11); + } return true; } @@ -336,8 +180,10 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend; - struct wlr_x11_output *output = &x11->output; - wlr_output_destroy(&output->wlr_output); + struct wlr_x11_output *output, *tmp; + wl_list_for_each_safe(output, tmp, &x11->outputs, link) { + wlr_output_destroy(&output->wlr_output); + } wlr_signal_emit_safe(&x11->pointer_dev.events.destroy, &x11->pointer_dev); wlr_signal_emit_safe(&x11->keyboard_dev.events.destroy, &x11->keyboard_dev); @@ -357,7 +203,6 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { } wl_list_remove(&x11->display_destroy.link); - wl_event_source_remove(x11->frame_timer); wlr_egl_finish(&x11->egl); if (x11->xlib_conn) { @@ -403,6 +248,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, wlr_backend_init(&x11->backend, &backend_impl); x11->wl_display = display; + x11->requested_outputs = 1; + wl_list_init(&x11->outputs); x11->xlib_conn = XOpenDisplay(x11_display); if (!x11->xlib_conn) { @@ -427,8 +274,6 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, goto error_x11; } - x11->frame_timer = wl_event_loop_add_timer(ev, signal_frame, x11); - x11->screen = xcb_setup_roots_iterator(xcb_get_setup(x11->xcb_conn)).data; if (!wlr_egl_init(&x11->egl, EGL_PLATFORM_X11_KHR, x11->xlib_conn, NULL, @@ -439,6 +284,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, x11->renderer = wlr_gles2_renderer_create(&x11->backend); if (x11->renderer == NULL) { wlr_log(L_ERROR, "Failed to create renderer"); + goto error_egl; } wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD, @@ -456,6 +302,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, return &x11->backend; +error_egl: + wlr_egl_finish(&x11->egl); error_event: wl_event_source_remove(x11->event_source); error_x11: @@ -463,59 +311,3 @@ error_x11: free(x11); return NULL; } - -static bool output_set_custom_mode(struct wlr_output *wlr_output, int32_t width, - int32_t height, int32_t refresh) { - struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; - struct wlr_x11_backend *x11 = output->x11; - - const uint32_t values[] = { width, height }; - xcb_configure_window(x11->xcb_conn, output->win, - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values); - return true; -} - -static void output_transform(struct wlr_output *wlr_output, enum wl_output_transform transform) { - struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; - output->wlr_output.transform = transform; -} - -static void output_destroy(struct wlr_output *wlr_output) { - struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; - struct wlr_x11_backend *x11 = output->x11; - - eglDestroySurface(x11->egl.display, output->surf); - xcb_destroy_window(x11->xcb_conn, output->win); - // output has been allocated on the stack, do not free it -} - -static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) { - struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; - struct wlr_x11_backend *x11 = output->x11; - - return wlr_egl_make_current(&x11->egl, output->surf, buffer_age); -} - -static bool output_swap_buffers(struct wlr_output *wlr_output, - pixman_region32_t *damage) { - struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; - struct wlr_x11_backend *x11 = output->x11; - - return wlr_egl_swap_buffers(&x11->egl, output->surf, damage); -} - -static const struct wlr_output_impl output_impl = { - .set_custom_mode = output_set_custom_mode, - .transform = output_transform, - .destroy = output_destroy, - .make_current = output_make_current, - .swap_buffers = output_swap_buffers, -}; - -bool wlr_output_is_x11(struct wlr_output *wlr_output) { - return wlr_output->impl == &output_impl; -} - -bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) { - return wlr_dev->impl == &input_device_impl; -} diff --git a/backend/x11/input_device.c b/backend/x11/input_device.c new file mode 100644 index 00000000..fb7f8b85 --- /dev/null +++ b/backend/x11/input_device.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif +#include "backend/x11.h" +#include "util/signal.h" + +static uint32_t xcb_button_to_wl(uint32_t button) { + switch (button) { + case XCB_BUTTON_INDEX_1: return BTN_LEFT; + case XCB_BUTTON_INDEX_2: return BTN_MIDDLE; + case XCB_BUTTON_INDEX_3: return BTN_RIGHT; + // XXX: I'm not sure the scroll-wheel direction is right + case XCB_BUTTON_INDEX_4: return BTN_GEAR_UP; + case XCB_BUTTON_INDEX_5: return BTN_GEAR_DOWN; + default: return 0; + } +} + +bool x11_handle_input_event(struct wlr_x11_backend *x11, + xcb_generic_event_t *event) { + switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { + case XCB_KEY_PRESS: + case XCB_KEY_RELEASE: { + xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; + struct wlr_event_keyboard_key key = { + .time_msec = ev->time, + .keycode = ev->detail - 8, + .state = event->response_type == XCB_KEY_PRESS ? + WLR_KEY_PRESSED : WLR_KEY_RELEASED, + .update_state = true, + }; + + // TODO use xcb-xkb for more precise modifiers state? + wlr_keyboard_notify_key(&x11->keyboard, &key); + x11->time = ev->time; + return true; + } + case XCB_BUTTON_PRESS: { + xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; + + if (ev->detail == XCB_BUTTON_INDEX_4 || + ev->detail == XCB_BUTTON_INDEX_5) { + double delta = (ev->detail == XCB_BUTTON_INDEX_4 ? -15 : 15); + struct wlr_event_pointer_axis axis = { + .device = &x11->pointer_dev, + .time_msec = ev->time, + .source = WLR_AXIS_SOURCE_WHEEL, + .orientation = WLR_AXIS_ORIENTATION_VERTICAL, + .delta = delta, + }; + wlr_signal_emit_safe(&x11->pointer.events.axis, &axis); + x11->time = ev->time; + break; + } + } + /* fallthrough */ + case XCB_BUTTON_RELEASE: { + xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; + + if (ev->detail != XCB_BUTTON_INDEX_4 && + ev->detail != XCB_BUTTON_INDEX_5) { + struct wlr_event_pointer_button button = { + .device = &x11->pointer_dev, + .time_msec = ev->time, + .button = xcb_button_to_wl(ev->detail), + .state = event->response_type == XCB_BUTTON_PRESS ? + WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED, + }; + + wlr_signal_emit_safe(&x11->pointer.events.button, &button); + } + x11->time = ev->time; + return true; + } + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; + + struct wlr_x11_output *output = + x11_output_from_window_id(x11, ev->event); + if (output == NULL) { + return false; + } + + struct wlr_event_pointer_motion_absolute abs = { + .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, + }; + + wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); + x11->time = ev->time; + return true; + } + default: +#ifdef WLR_HAS_XCB_XKB + if (x11->xkb_supported && event->response_type == x11->xkb_base_event) { + xcb_xkb_state_notify_event_t *ev = + (xcb_xkb_state_notify_event_t *)event; + wlr_keyboard_notify_modifiers(&x11->keyboard, ev->baseMods, + ev->latchedMods, ev->lockedMods, ev->lockedGroup); + return true; + } +#endif + break; + } + + return false; +} + +const struct wlr_input_device_impl input_device_impl = { 0 }; + +bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) { + return wlr_dev->impl == &input_device_impl; +} diff --git a/backend/x11/output.c b/backend/x11/output.c new file mode 100644 index 00000000..f039baad --- /dev/null +++ b/backend/x11/output.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include "backend/x11.h" +#include "util/signal.h" + +static int signal_frame(void *data) { + struct wlr_x11_output *output = data; + wlr_output_send_frame(&output->wlr_output); + wl_event_source_timer_update(output->frame_timer, output->frame_delay); + return 0; +} + +static void parse_xcb_setup(struct wlr_output *output, xcb_connection_t *xcb_conn) { + const xcb_setup_t *xcb_setup = xcb_get_setup(xcb_conn); + + snprintf(output->make, sizeof(output->make), "%.*s", + xcb_setup_vendor_length(xcb_setup), + xcb_setup_vendor(xcb_setup)); + snprintf(output->model, sizeof(output->model), "%"PRIu16".%"PRIu16, + xcb_setup->protocol_major_version, + xcb_setup->protocol_minor_version); +} + +static bool output_set_custom_mode(struct wlr_output *wlr_output, int32_t width, + int32_t height, int32_t refresh) { + struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; + struct wlr_x11_backend *x11 = output->x11; + + wlr_output_update_custom_mode(&output->wlr_output, wlr_output->width, + wlr_output->height, refresh); + output->frame_delay = 1000000 / refresh; + + const uint32_t values[] = { width, height }; + xcb_configure_window(x11->xcb_conn, output->win, + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values); + return true; +} + +static void output_transform(struct wlr_output *wlr_output, + enum wl_output_transform transform) { + struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; + output->wlr_output.transform = transform; +} + +static void output_destroy(struct wlr_output *wlr_output) { + struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; + struct wlr_x11_backend *x11 = output->x11; + + wl_list_remove(&output->link); + wl_event_source_remove(output->frame_timer); + eglDestroySurface(x11->egl.display, output->surf); + xcb_destroy_window(x11->xcb_conn, output->win); + free(output); +} + +static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) { + struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; + struct wlr_x11_backend *x11 = output->x11; + + return wlr_egl_make_current(&x11->egl, output->surf, buffer_age); +} + +static bool output_swap_buffers(struct wlr_output *wlr_output, + pixman_region32_t *damage) { + struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output; + struct wlr_x11_backend *x11 = output->x11; + + return wlr_egl_swap_buffers(&x11->egl, output->surf, damage); +} + +static const struct wlr_output_impl output_impl = { + .set_custom_mode = output_set_custom_mode, + .transform = output_transform, + .destroy = output_destroy, + .make_current = output_make_current, + .swap_buffers = output_swap_buffers, +}; + +struct wlr_x11_output *x11_output_create(struct wlr_x11_backend *x11) { + 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"); + parse_xcb_setup(wlr_output, x11->xcb_conn); + + uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + uint32_t values[2] = { + x11->screen->white_pixel, + XCB_EVENT_MASK_EXPOSURE | + XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | + XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_POINTER_MOTION | + XCB_EVENT_MASK_STRUCTURE_NOTIFY + }; + output->win = xcb_generate_id(x11->xcb_conn); + xcb_create_window(x11->xcb_conn, XCB_COPY_FROM_PARENT, output->win, + x11->screen->root, 0, 0, 1024, 768, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, + x11->screen->root_visual, mask, values); + + output->surf = wlr_egl_create_surface(&x11->egl, &output->win); + if (!output->surf) { + wlr_log(L_ERROR, "Failed to create EGL surface"); + free(output); + return NULL; + } + + xcb_change_property(x11->xcb_conn, XCB_PROP_MODE_REPLACE, output->win, + x11->atoms.wm_protocols, XCB_ATOM_ATOM, 32, 1, + &x11->atoms.wm_delete_window); + + char title[32]; + if (snprintf(title, sizeof(title), "wlroots - %s", wlr_output->name)) { + xcb_change_property(x11->xcb_conn, XCB_PROP_MODE_REPLACE, output->win, + x11->atoms.net_wm_name, x11->atoms.utf8_string, 8, + strlen(title), title); + } + + xcb_map_window(x11->xcb_conn, output->win); + xcb_flush(x11->xcb_conn); + + struct wl_event_loop *ev = wl_display_get_event_loop(x11->wl_display); + output->frame_timer = wl_event_loop_add_timer(ev, signal_frame, output); + + wl_event_source_timer_update(output->frame_timer, output->frame_delay); + wlr_output_update_enabled(wlr_output, true); + + wl_list_insert(&x11->outputs, &output->link); + wlr_signal_emit_safe(&x11->backend.events.new_output, wlr_output); + + return output; +} + +void x11_output_handle_configure_notify(struct wlr_x11_output *output, + xcb_configure_notify_event_t *ev) { + struct wlr_x11_backend *x11 = output->x11; + + wlr_output_update_custom_mode(&output->wlr_output, ev->width, + ev->height, output->wlr_output.refresh); + + // Move the pointer to its new location + xcb_query_pointer_cookie_t cookie = + xcb_query_pointer(x11->xcb_conn, output->win); + xcb_query_pointer_reply_t *pointer = + xcb_query_pointer_reply(x11->xcb_conn, cookie, NULL); + if (!pointer) { + return; + } + + struct wlr_event_pointer_motion_absolute abs = { + .device = &x11->pointer_dev, + .time_msec = x11->time, + .x = (double)pointer->root_x / output->wlr_output.width, + .y = (double)pointer->root_y / output->wlr_output.height, + }; + + wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); + free(pointer); +} + +bool wlr_output_is_x11(struct wlr_output *wlr_output) { + return wlr_output->impl == &output_impl; +} 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 'backend') 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 'backend') 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 From f37e8c5b6e554a358a3bf32b1cc08bb5d52e1bf7 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 30 Mar 2018 22:38:09 -0400 Subject: backend/wayland: cleanup input transform code --- backend/wayland/wl_seat.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'backend') diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index a5821311..c6982fce 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -60,37 +60,28 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, struct wlr_output *wlr_output = &wlr_wl_pointer->current_output->wlr_output; - int width, height; - wl_egl_window_get_attached_size(wlr_wl_pointer->current_output->egl_window, - &width, &height); - - int owidth, oheight; - wlr_output_effective_resolution(wlr_output, &owidth, &oheight); - struct wlr_box box = { .x = wl_fixed_to_int(surface_x), .y = wl_fixed_to_int(surface_y), }; - struct wlr_box transformed; - wlr_box_transform(&box, wlr_output->transform, width, height, &transformed); - transformed.x /= wlr_output->scale; - transformed.y /= wlr_output->scale; + 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; 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; - - double tx = transformed.x / (double)owidth; - double ty = transformed.y / (double)oheight; double ox = wlr_output->lx / (double)layout_box.width; double oy = wlr_output->ly / (double)layout_box.height; - wlr_event.x = tx * ((double)owidth / layout_box.width) + ox; - wlr_event.y = ty * ((double)oheight / layout_box.height) + oy; + struct wlr_event_pointer_motion_absolute wlr_event = { + .device = dev, + .time_msec = time, + .x = box.x / (double)layout_box.width + ox, + .y = box.y / (double)layout_box.height + oy, + }; wlr_signal_emit_safe(&dev->pointer->events.motion_absolute, &wlr_event); } -- cgit v1.2.3 From 5111f7df84cea46e1e30cc5b460568e5d46e584a Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 30 Mar 2018 23:36:05 -0400 Subject: backend/x11: fix extra output --- backend/backend.c | 10 +++++----- backend/x11/backend.c | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'backend') diff --git a/backend/backend.c b/backend/backend.c index ff5603bd..93d7e0df 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -61,7 +61,7 @@ struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend) { return NULL; } -static int parse_outputs_env(const char *name) { +static size_t parse_outputs_env(const char *name) { const char *outputs_str = getenv(name); if (outputs_str == NULL) { return 1; @@ -83,8 +83,8 @@ static struct wlr_backend *attempt_wl_backend(struct wl_display *display) { return NULL; } - int outputs = parse_outputs_env("WLR_WL_OUTPUTS"); - for (int i = 0; i < outputs; ++i) { + size_t outputs = parse_outputs_env("WLR_WL_OUTPUTS"); + for (size_t i = 0; i < outputs; ++i) { wlr_wl_output_create(backend); } @@ -98,8 +98,8 @@ static struct wlr_backend *attempt_x11_backend(struct wl_display *display, return NULL; } - int outputs = parse_outputs_env("WLR_X11_OUTPUTS"); - for (int i = 0; i < outputs; ++i) { + size_t outputs = parse_outputs_env("WLR_X11_OUTPUTS"); + for (size_t i = 0; i < outputs; ++i) { wlr_x11_output_create(backend); } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 82004058..90658f26 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -282,7 +282,6 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, wlr_backend_init(&x11->backend, &backend_impl); x11->wl_display = display; - x11->requested_outputs = 1; wl_list_init(&x11->outputs); x11->xlib_conn = XOpenDisplay(x11_display); -- cgit v1.2.3 From 7b88ace557f6aae4b7aa41b72263c628e637a892 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 31 Mar 2018 12:07:58 -0400 Subject: backend/x11: hide cursor --- backend/x11/backend.c | 12 ++++++++++++ backend/x11/output.c | 4 ++++ include/backend/x11.h | 3 +++ 3 files changed, 19 insertions(+) (limited to 'backend') diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 90658f26..225fc49d 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -171,6 +171,15 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { } } + // create a blank cursor + xcb_pixmap_t pix = xcb_generate_id(x11->xcb_conn); + xcb_create_pixmap(x11->xcb_conn, 1, pix, x11->screen->root, 1, 1); + + x11->cursor = xcb_generate_id(x11->xcb_conn); + xcb_create_cursor(x11->xcb_conn, x11->cursor, pix, pix, 0, 0, 0, 0, 0, 0, + 0, 0); + xcb_free_pixmap(x11->xcb_conn, pix); + #ifdef WLR_HAS_XCB_XKB const xcb_query_extension_reply_t *reply = xcb_get_extension_data(x11->xcb_conn, &xcb_xkb_id); @@ -239,6 +248,9 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { wlr_egl_finish(&x11->egl); + if (x11->cursor) { + xcb_free_cursor(x11->xcb_conn, x11->cursor); + } if (x11->xlib_conn) { XCloseDisplay(x11->xlib_conn); } diff --git a/backend/x11/output.c b/backend/x11/output.c index 9e7424d8..2220bc2e 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -135,6 +135,10 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) { strlen(title), title); } + uint32_t cursor_values[] = { x11->cursor }; + xcb_change_window_attributes(x11->xcb_conn, output->win, XCB_CW_CURSOR, + cursor_values); + xcb_map_window(x11->xcb_conn, output->win); xcb_flush(x11->xcb_conn); diff --git a/include/backend/x11.h b/include/backend/x11.h index 0426e481..33c9a427 100644 --- a/include/backend/x11.h +++ b/include/backend/x11.h @@ -58,6 +58,9 @@ struct wlr_x11_backend { // The time we last received an event xcb_timestamp_t time; + // A blank cursor + xcb_cursor_t cursor; + #ifdef WLR_HAS_XCB_XKB bool xkb_supported; uint8_t xkb_base_event; -- cgit v1.2.3 From 37aae0b2cdebeba10f141b8646886614e1646530 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 31 Mar 2018 13:28:50 -0400 Subject: backend/x11: flush after destroying window Otherwise the destroy message is kept buffered and never reaches the X11 server. Thanks X11. --- backend/x11/output.c | 1 + 1 file changed, 1 insertion(+) (limited to 'backend') diff --git a/backend/x11/output.c b/backend/x11/output.c index 9e7424d8..4ccabd51 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -52,6 +52,7 @@ static void output_destroy(struct wlr_output *wlr_output) { wl_event_source_remove(output->frame_timer); eglDestroySurface(x11->egl.display, output->surf); xcb_destroy_window(x11->xcb_conn, output->win); + xcb_flush(x11->xcb_conn); free(output); } -- cgit v1.2.3 From 33a2eb4b7775d1a3ab2b767739c1f1f054683d22 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 31 Mar 2018 18:49:43 -0400 Subject: Untie wlr_backend from wlr_renderer --- backend/drm/renderer.c | 2 +- backend/headless/backend.c | 2 +- backend/wayland/backend.c | 2 +- backend/x11/backend.c | 2 +- examples/output-layout.c | 3 ++- examples/rotation.c | 3 ++- examples/tablet.c | 3 ++- examples/touch.c | 3 ++- include/wlr/render/gles2.h | 3 ++- render/gles2/renderer.c | 5 ++--- 10 files changed, 16 insertions(+), 12 deletions(-) (limited to 'backend') diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index c1531ce3..f06de1ee 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -31,7 +31,7 @@ bool wlr_drm_renderer_init(struct wlr_drm_backend *drm, goto error_gbm; } - renderer->wlr_rend = wlr_gles2_renderer_create(&drm->backend); + renderer->wlr_rend = wlr_gles2_renderer_create(&renderer->egl); if (!renderer->wlr_rend) { wlr_log(L_ERROR, "Failed to create WLR renderer"); goto error_egl; diff --git a/backend/headless/backend.c b/backend/headless/backend.c index 663bc13b..5bc48240 100644 --- a/backend/headless/backend.c +++ b/backend/headless/backend.c @@ -114,7 +114,7 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display) { return NULL; } - backend->renderer = wlr_gles2_renderer_create(&backend->backend); + backend->renderer = wlr_gles2_renderer_create(&backend->egl); if (backend->renderer == NULL) { wlr_log(L_ERROR, "Failed to create renderer"); } diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index abb25df5..0135f7c5 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -212,7 +212,7 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, const char backend->remote_display, NULL, WL_SHM_FORMAT_ARGB8888); wlr_egl_bind_display(&backend->egl, backend->local_display); - backend->renderer = wlr_gles2_renderer_create(&backend->backend); + backend->renderer = wlr_gles2_renderer_create(&backend->egl); if (backend->renderer == NULL) { wlr_log_errno(L_ERROR, "Could not create renderer"); } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 90658f26..f598aea1 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -314,7 +314,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, goto error_event; } - x11->renderer = wlr_gles2_renderer_create(&x11->backend); + x11->renderer = wlr_gles2_renderer_create(&x11->egl); if (x11->renderer == NULL) { wlr_log(L_ERROR, "Failed to create renderer"); goto error_egl; diff --git a/examples/output-layout.c b/examples/output-layout.c index c1392a30..53aae7f0 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -196,7 +196,8 @@ int main(int argc, char *argv[]) { compositor.keyboard_key_cb = handle_keyboard_key; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); state.cat_texture = wlr_texture_from_pixels(state.renderer, WL_SHM_FORMAT_ABGR8888, cat_tex.width * 4, cat_tex.width, cat_tex.height, cat_tex.pixel_data); diff --git a/examples/rotation.c b/examples/rotation.c index dfafeeca..37873797 100644 --- a/examples/rotation.c +++ b/examples/rotation.c @@ -137,7 +137,8 @@ int main(int argc, char *argv[]) { compositor.keyboard_key_cb = handle_keyboard_key; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/examples/tablet.c b/examples/tablet.c index be428f86..d80b4b2f 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -192,7 +192,8 @@ int main(int argc, char *argv[]) { }; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/examples/touch.c b/examples/touch.c index e9dcf29c..16024fc8 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -108,7 +108,8 @@ int main(int argc, char *argv[]) { }; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/include/wlr/render/gles2.h b/include/wlr/render/gles2.h index b3b43ab2..a59956bd 100644 --- a/include/wlr/render/gles2.h +++ b/include/wlr/render/gles2.h @@ -5,6 +5,7 @@ #include struct wlr_egl; -struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend); + +struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl); #endif diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index c8094847..77af0ab7 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -400,7 +399,7 @@ extern const GLchar tex_fragment_src_rgba[]; extern const GLchar tex_fragment_src_rgbx[]; extern const GLchar tex_fragment_src_external[]; -struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) { +struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { struct wlr_gles2_renderer *renderer = calloc(1, sizeof(struct wlr_gles2_renderer)); if (renderer == NULL) { @@ -408,7 +407,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) { } wlr_renderer_init(&renderer->wlr_renderer, &renderer_impl); - renderer->egl = wlr_backend_get_egl(backend); + renderer->egl = egl; wlr_egl_make_current(renderer->egl, EGL_NO_SURFACE, NULL); renderer->exts_str = (const char*) glGetString(GL_EXTENSIONS); -- cgit v1.2.3 From a2391a6047baa6c3755b8be95af540ab6d8846c9 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 31 Mar 2018 20:55:31 -0400 Subject: Fix cursor transform on DRM backend --- backend/drm/drm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'backend') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 94bfbc96..187db368 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -579,8 +579,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, return false; } - enum wl_output_transform transform = - wlr_output_transform_invert(output->transform); + enum wl_output_transform transform = output->transform; wlr_matrix_projection(plane->matrix, plane->surf.width, plane->surf.height, transform); } -- cgit v1.2.3