diff options
-rw-r--r-- | backend/drm/drm.c | 26 | ||||
-rw-r--r-- | include/wlr/backend/drm.h | 7 |
2 files changed, 33 insertions, 0 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c index e9842bb3..0e981d59 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -3,6 +3,7 @@ #include <drm_fourcc.h> #include <drm_mode.h> #include <errno.h> +#include <fcntl.h> #include <inttypes.h> #include <stdint.h> #include <stdio.h> @@ -1479,6 +1480,31 @@ void destroy_drm_connector(struct wlr_drm_connector *conn) { free(conn); } +int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend) { + assert(backend); + + struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend); + char *path = drmGetDeviceNameFromFd2(drm->fd); + if (!path) { + wlr_log(WLR_ERROR, "Failed to get device name from DRM fd"); + return -1; + } + + int fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) { + wlr_log_errno(WLR_ERROR, "Unable to clone DRM fd for client fd"); + free(path); + return -1; + } + + if (drmIsMaster(fd) && drmDropMaster(fd) < 0) { + wlr_log_errno(WLR_ERROR, "Failed to drop master"); + return -1; + } + + return fd; +} + /* TODO: make the function return a `wlr_drm_lease` to provide a destroy event * that can be fired when the kernel notifies us through uevent that the lease * has been destroyed diff --git a/include/wlr/backend/drm.h b/include/wlr/backend/drm.h index c5351d65..0d8c51e0 100644 --- a/include/wlr/backend/drm.h +++ b/include/wlr/backend/drm.h @@ -34,6 +34,13 @@ bool wlr_output_is_drm(struct wlr_output *output); uint32_t wlr_drm_connector_get_id(struct wlr_output *output); /** + * Tries to open non-master DRM FD. The compositor must not call `drmSetMaster` + * on the returned FD. + * Returns a valid opened DRM FD, or -1 on error. + */ +int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend); + +/** * Leases a given output to the caller. The output must be from the associated * DRM backend. * Returns a valid opened DRM FD or -1 on error. |