aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/drm/backend.c2
-rw-r--r--backend/drm/drm.c103
-rw-r--r--backend/headless/input_device.c2
-rw-r--r--backend/libinput/events.c2
-rw-r--r--backend/libinput/tablet_pad.c3
-rw-r--r--backend/libinput/tablet_tool.c2
-rw-r--r--backend/x11/backend.c83
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,