diff --git a/backend/drm/backend.c b/backend/drm/backend.c index e49197ec..d8b7fc0e 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -38,23 +39,32 @@ static struct wlr_backend_impl backend_impl = { }; static void device_paused(struct wl_listener *listener, void *data) { - struct wlr_backend_state *backend = wl_container_of(listener, backend, device_paused); + struct wlr_backend_state *drm = wl_container_of(listener, drm, device_paused); + struct device_arg *arg = data; // TODO: Actually pause the renderer or something. // We currently just expect it to fail its next pageflip. - (void)backend; + if (arg->dev == drm->dev) { + wlr_log(L_INFO, "DRM fd paused"); + } } static void device_resumed(struct wl_listener *listener, void *data) { struct wlr_backend_state *drm = wl_container_of(listener, drm, device_resumed); - int *new_fd = data; + struct device_arg *arg = data; - if (dup2(*new_fd, drm->fd) < 0) { + if (arg->dev != drm->dev) { + return; + } + + if (dup2(arg->fd, drm->fd) < 0) { wlr_log(L_ERROR, "dup2 failed: %s", strerror(errno)); return; } + wlr_log(L_INFO, "DRM fd resumed"); + for (size_t i = 0; i < drm->outputs->length; ++i) { struct wlr_output_state *output = drm->outputs->items[i]; wlr_drm_output_start_renderer(output); @@ -94,6 +104,12 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, goto error_udev; } + struct stat st; + if (fstat(state->fd, &st) < 0) { + wlr_log(L_ERROR, "Stat failed: %s", strerror(errno)); + } + state->dev = st.st_rdev; + struct wl_event_loop *event_loop = wl_display_get_event_loop(display); state->drm_event = wl_event_loop_add_fd(event_loop, state->fd, diff --git a/include/backend/drm/backend.h b/include/backend/drm/backend.h index 4df86e21..e603bccd 100644 --- a/include/backend/drm/backend.h +++ b/include/backend/drm/backend.h @@ -19,6 +19,7 @@ struct wlr_backend_state { int fd; + dev_t dev; struct wlr_backend *backend; struct wl_event_source *drm_event; diff --git a/include/wlr/session.h b/include/wlr/session.h index 4dfb026c..5f210f10 100644 --- a/include/wlr/session.h +++ b/include/wlr/session.h @@ -2,9 +2,16 @@ #define WLR_SESSION_H #include +#include struct session_interface; +// Passed to the listeners of device_paused/resumed +struct device_arg { + dev_t dev; + int fd; // Only for device_resumed +}; + struct wlr_session { const struct session_interface *iface; diff --git a/session/logind.c b/session/logind.c index b6763bf9..6f0327e6 100644 --- a/session/logind.c +++ b/session/logind.c @@ -198,8 +198,12 @@ static int pause_device(sd_bus_message *msg, void *userdata, sd_bus_error *ret_e goto error; } - dev_t dev = makedev(major, minor); - wl_signal_emit(&session->base.device_paused, &dev); + struct device_arg arg = { + .dev = makedev(major, minor), + .fd = -1, + }; + + wl_signal_emit(&session->base.device_paused, &arg); ret = sd_bus_call_method(session->bus, "org.freedesktop.login1", session->path, "org.freedesktop.login1.Session", "PauseDeviceComplete", @@ -226,9 +230,12 @@ static int resume_device(sd_bus_message *msg, void *userdata, sd_bus_error *ret_ goto error; } - // TODO: Use major/minor to make sure the right devices are getting signals + struct device_arg arg = { + .dev = makedev(major, minor), + .fd = fd, + }; - wl_signal_emit(&session->base.device_resumed, &fd); + wl_signal_emit(&session->base.device_resumed, &arg); error: return 0;