diff options
Diffstat (limited to 'backend')
-rw-r--r-- | backend/drm/backend.c | 2 | ||||
-rw-r--r-- | backend/drm/drm.c | 103 | ||||
-rw-r--r-- | backend/headless/input_device.c | 2 | ||||
-rw-r--r-- | backend/libinput/events.c | 2 | ||||
-rw-r--r-- | backend/libinput/tablet_pad.c | 3 | ||||
-rw-r--r-- | backend/libinput/tablet_tool.c | 2 | ||||
-rw-r--r-- | backend/x11/backend.c | 83 |
7 files changed, 117 insertions, 80 deletions
diff --git a/backend/drm/backend.c b/backend/drm/backend.c index fec14da9..75b44210 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -81,7 +81,7 @@ static void session_signal(struct wl_listener *listener, void *data) { struct wlr_drm_connector *conn; wl_list_for_each(conn, &drm->outputs, link){ - if (conn->output.current_mode) { + if (conn->output.enabled) { wlr_output_set_mode(&conn->output, conn->output.current_mode); } else { wlr_drm_connector_enable(&conn->output, false); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index d6388597..0d1d527d 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -296,8 +296,6 @@ void wlr_drm_connector_enable(struct wlr_output *output, bool enable) { if (enable) { wlr_drm_connector_start_renderer(conn); - } else { - output->current_mode = NULL; } wlr_output_update_enabled(&conn->output, enable); @@ -546,10 +544,10 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, if (!crtc) { return false; } - struct wlr_drm_plane *plane = crtc->cursor; - // We don't have a real cursor plane, so we make a fake one + struct wlr_drm_plane *plane = crtc->cursor; if (!plane) { + // We don't have a real cursor plane, so we make a fake one plane = calloc(1, sizeof(*plane)); if (!plane) { wlr_log_errno(L_ERROR, "Allocation failed"); @@ -558,16 +556,6 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, crtc->cursor = plane; } - if (!buf && update_pixels) { - // Hide the cursor - plane->cursor_enabled = false; - if (!drm->session->active) { - return true; - } - return drm->iface->crtc_set_cursor(drm, crtc, NULL); - } - plane->cursor_enabled = true; - if (!plane->surf.gbm) { int ret; uint64_t w, h; @@ -609,62 +597,77 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, } } - struct wlr_box hotspot = { - .x = hotspot_x, - .y = hotspot_y, - }; + struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y }; enum wl_output_transform transform = wlr_output_transform_invert(output->transform); wlr_box_transform(&hotspot, transform, plane->surf.width, plane->surf.height, &hotspot); - plane->cursor_hotspot_x = hotspot.x; - plane->cursor_hotspot_y = hotspot.y; + + if (plane->cursor_hotspot_x != hotspot.x || + plane->cursor_hotspot_y != hotspot.y) { + // Update cursor hotspot + conn->cursor_x -= hotspot.x - plane->cursor_hotspot_x; + conn->cursor_y -= hotspot.y - plane->cursor_hotspot_y; + plane->cursor_hotspot_x = hotspot.x; + plane->cursor_hotspot_y = hotspot.y; + + if (!drm->iface->crtc_move_cursor(drm, conn->crtc, conn->cursor_x, + conn->cursor_y)) { + return false; + } + + wlr_output_update_needs_swap(output); + } if (!update_pixels) { - // Only update the cursor hotspot + // Don't update cursor image return true; } - struct gbm_bo *bo = plane->cursor_bo; - uint32_t bo_width = gbm_bo_get_width(bo); - uint32_t bo_height = gbm_bo_get_height(bo); - uint32_t bo_stride; - void *bo_data; + plane->cursor_enabled = buf != NULL; - if (!gbm_bo_map(bo, 0, 0, bo_width, bo_height, - GBM_BO_TRANSFER_WRITE, &bo_stride, &bo_data)) { - wlr_log_errno(L_ERROR, "Unable to map buffer"); - return false; - } + if (buf != NULL) { + uint32_t bo_width = gbm_bo_get_width(plane->cursor_bo); + uint32_t bo_height = gbm_bo_get_height(plane->cursor_bo); - wlr_drm_surface_make_current(&plane->surf, NULL); + uint32_t bo_stride; + void *bo_data; + if (!gbm_bo_map(plane->cursor_bo, 0, 0, bo_width, bo_height, + GBM_BO_TRANSFER_WRITE, &bo_stride, &bo_data)) { + wlr_log_errno(L_ERROR, "Unable to map buffer"); + return false; + } + + wlr_drm_surface_make_current(&plane->surf, NULL); - wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, - stride, width, height, buf); + wlr_texture_upload_pixels(plane->wlr_tex, WL_SHM_FORMAT_ARGB8888, + stride, width, height, buf); - glViewport(0, 0, plane->surf.width, plane->surf.height); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); + glViewport(0, 0, plane->surf.width, plane->surf.height); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); - float matrix[16]; - wlr_texture_get_matrix(plane->wlr_tex, &matrix, &plane->matrix, 0, 0); - wlr_render_with_matrix(plane->surf.renderer->wlr_rend, plane->wlr_tex, - &matrix, 1.0f); + float matrix[16]; + wlr_texture_get_matrix(plane->wlr_tex, &matrix, &plane->matrix, 0, 0); + wlr_render_with_matrix(plane->surf.renderer->wlr_rend, plane->wlr_tex, + &matrix, 1.0f); - glFinish(); - glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, bo_stride); - glReadPixels(0, 0, plane->surf.width, plane->surf.height, GL_BGRA_EXT, - GL_UNSIGNED_BYTE, bo_data); - glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); + glFinish(); + glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, bo_stride); + glReadPixels(0, 0, plane->surf.width, plane->surf.height, GL_BGRA_EXT, + GL_UNSIGNED_BYTE, bo_data); + glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); - wlr_drm_surface_swap_buffers(&plane->surf, NULL); + wlr_drm_surface_swap_buffers(&plane->surf, NULL); - gbm_bo_unmap(bo, bo_data); + gbm_bo_unmap(plane->cursor_bo, bo_data); + } if (!drm->session->active) { - return true; + return true; // will be committed when session is resumed } + struct gbm_bo *bo = plane->cursor_enabled ? plane->cursor_bo : NULL; bool ok = drm->iface->crtc_set_cursor(drm, crtc, bo); if (ok) { wlr_output_update_needs_swap(output); @@ -699,7 +702,7 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output, conn->cursor_y = box.y; if (!drm->session->active) { - return true; + return true; // will be committed when session is resumed } bool ok = drm->iface->crtc_move_cursor(drm, conn->crtc, box.x, box.y); diff --git a/backend/headless/input_device.c b/backend/headless/input_device.c index ea335aff..daa22436 100644 --- a/backend/headless/input_device.c +++ b/backend/headless/input_device.c @@ -15,7 +15,7 @@ static void input_device_destroy(struct wlr_input_device *wlr_dev) { free(device); } -static struct wlr_input_device_impl input_device_impl = { +static const struct wlr_input_device_impl input_device_impl = { .destroy = input_device_destroy, }; diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 603eed07..d92de830 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -31,7 +31,7 @@ static void wlr_libinput_device_destroy(struct wlr_input_device *_dev) { free(dev); } -static struct wlr_input_device_impl input_device_impl = { +static const struct wlr_input_device_impl input_device_impl = { .destroy = wlr_libinput_device_destroy }; diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index 70e4c677..f71e1efa 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -34,6 +34,7 @@ void handle_tablet_pad_button(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent)); wlr_event.button = libinput_event_tablet_pad_get_button_number(pevent); + wlr_event.mode = libinput_event_tablet_pad_get_mode(pevent); switch (libinput_event_tablet_pad_get_button_state(pevent)) { case LIBINPUT_BUTTON_STATE_PRESSED: wlr_event.state = WLR_BUTTON_PRESSED; @@ -60,6 +61,7 @@ void handle_tablet_pad_ring(struct libinput_event *event, usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent)); wlr_event.ring = libinput_event_tablet_pad_get_ring_number(pevent); wlr_event.position = libinput_event_tablet_pad_get_ring_position(pevent); + wlr_event.mode = libinput_event_tablet_pad_get_mode(pevent); switch (libinput_event_tablet_pad_get_ring_source(pevent)) { case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN: wlr_event.source = WLR_TABLET_PAD_RING_SOURCE_UNKNOWN; @@ -86,6 +88,7 @@ void handle_tablet_pad_strip(struct libinput_event *event, usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent)); wlr_event.strip = libinput_event_tablet_pad_get_strip_number(pevent); wlr_event.position = libinput_event_tablet_pad_get_strip_position(pevent); + wlr_event.mode = libinput_event_tablet_pad_get_mode(pevent); switch (libinput_event_tablet_pad_get_strip_source(pevent)) { case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN: wlr_event.source = WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN; diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 4e60367f..27cf7c81 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -71,8 +71,6 @@ void handle_tablet_tool_axis(struct libinput_event *event, wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_WHEEL; wlr_event.wheel_delta = libinput_event_tablet_tool_get_wheel_delta(tevent); } - wlr_log(L_DEBUG, "Tablet tool axis event %d @ %f,%f", - wlr_event.updated_axes, wlr_event.x_mm, wlr_event.y_mm); wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.axis, &wlr_event); } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 8633ece3..cb29e518 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -15,7 +15,6 @@ #include <wlr/render/gles2.h> #include <wlr/util/log.h> #include <X11/Xlib-xcb.h> -#include <xcb/glx.h> #include <xcb/xcb.h> #ifdef __linux__ #include <linux/input-event-codes.h> @@ -25,9 +24,11 @@ #include "backend/x11.h" #include "util/signal.h" -static struct wlr_backend_impl backend_impl; -static struct wlr_output_impl output_impl; -static struct wlr_input_device_impl input_device_impl = { 0 }; +#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) { @@ -44,7 +45,7 @@ static uint32_t xcb_button_to_wl(uint32_t button) { static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event) { struct wlr_x11_output *output = &x11->output; - switch (event->response_type) { + switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) { case XCB_EXPOSE: { wlr_output_send_frame(&output->wlr_output); break; @@ -144,9 +145,14 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); break; } - case XCB_GLX_DELETE_QUERIES_ARB: { - wl_display_terminate(x11->wl_display); - return true; + 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; + } + break; } default: @@ -181,13 +187,6 @@ static int signal_frame(void *data) { return 0; } -static void init_atom(struct wlr_x11_backend *x11, struct wlr_x11_atom *atom, - uint8_t only_if_exists, const char *name) { - atom->cookie = xcb_intern_atom(x11->xcb_conn, only_if_exists, strlen(name), - name); - atom->reply = xcb_intern_atom_reply(x11->xcb_conn, atom->cookie, NULL); -} - 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); @@ -231,20 +230,54 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { return false; } - init_atom(x11, &x11->atoms.wm_protocols, 1, "WM_PROTOCOLS"); - init_atom(x11, &x11->atoms.wm_delete_window, 0, "WM_DELETE_WINDOW"); - init_atom(x11, &x11->atoms.net_wm_name, 1, "_NET_WM_NAME"); - init_atom(x11, &x11->atoms.utf8_string, 0, "UTF8_STRING"); + struct { + const char *name; + xcb_intern_atom_cookie_t cookie; + xcb_atom_t *atom; + } atom[] = { + { + .name = "WM_PROTOCOLS", + .atom = &x11->atoms.wm_protocols, + }, + { + .name = "WM_DELETE_WINDOW", + .atom = &x11->atoms.wm_delete_window, + }, + { + .name = "_NET_WM_NAME", + .atom = &x11->atoms.net_wm_name, + }, + { + .name = "UTF8_STRING", + .atom = &x11->atoms.utf8_string, + }, + }; + + for (size_t i = 0; i < sizeof(atom) / sizeof(atom[0]); ++i) { + atom[i].cookie = xcb_intern_atom(x11->xcb_conn, + true, strlen(atom[i].name), atom[i].name); + } + + for (size_t i = 0; i < sizeof(atom) / sizeof(atom[0]); ++i) { + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply( + x11->xcb_conn, atom[i].cookie, NULL); + + if (reply) { + *atom[i].atom = reply->atom; + free(reply); + } else { + *atom[i].atom = XCB_ATOM_NONE; + } + } xcb_change_property(x11->xcb_conn, XCB_PROP_MODE_REPLACE, output->win, - x11->atoms.wm_protocols.reply->atom, XCB_ATOM_ATOM, 32, 1, - &x11->atoms.wm_delete_window.reply->atom); + 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.reply->atom, - x11->atoms.utf8_string.reply->atom, 8, + x11->atoms.net_wm_name, x11->atoms.utf8_string, 8, strlen(title), title); } @@ -304,7 +337,7 @@ static struct wlr_renderer *wlr_x11_backend_get_renderer( return x11->renderer; } -static struct wlr_backend_impl backend_impl = { +static const struct wlr_backend_impl backend_impl = { .start = wlr_x11_backend_start, .destroy = wlr_x11_backend_destroy, .get_egl = wlr_x11_backend_get_egl, @@ -432,7 +465,7 @@ static bool output_swap_buffers(struct wlr_output *wlr_output, return wlr_egl_swap_buffers(&x11->egl, output->surf, damage); } -static struct wlr_output_impl output_impl = { +static const struct wlr_output_impl output_impl = { .set_custom_mode = output_set_custom_mode, .transform = output_transform, .destroy = output_destroy, |