diff --git a/backend/backend.c b/backend/backend.c index aa0d9668..7df1cfbd 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -151,7 +151,7 @@ static struct wlr_backend *attempt_noop_backend(struct wl_display *display) { static struct wlr_backend *attempt_drm_backend(struct wl_display *display, struct wlr_backend *backend, struct wlr_session *session, wlr_renderer_create_func_t create_renderer_func) { - int gpus[8]; + struct wlr_device *gpus[8]; size_t num_gpus = wlr_session_find_gpus(session, 8, gpus); struct wlr_backend *primary_drm = NULL; wlr_log(WLR_INFO, "Found %zu GPUs", num_gpus); @@ -160,7 +160,7 @@ static struct wlr_backend *attempt_drm_backend(struct wl_display *display, struct wlr_backend *drm = wlr_drm_backend_create(display, session, gpus[i], primary_drm, create_renderer_func); if (!drm) { - wlr_log(WLR_ERROR, "Failed to open DRM device %d", gpus[i]); + wlr_log(WLR_ERROR, "Failed to create DRM backend"); continue; } diff --git a/backend/drm/backend.c b/backend/drm/backend.c index da6e1ebc..3b7ed93c 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -50,7 +50,7 @@ static void backend_destroy(struct wlr_backend *backend) { finish_drm_resources(drm); finish_drm_renderer(&drm->renderer); - wlr_session_close_file(drm->session, drm->fd); + wlr_session_close_file(drm->session, drm->dev); wl_event_source_remove(drm->drm_event); free(drm); } @@ -128,13 +128,14 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) { } struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, - struct wlr_session *session, int gpu_fd, struct wlr_backend *parent, + struct wlr_session *session, struct wlr_device *dev, + struct wlr_backend *parent, wlr_renderer_create_func_t create_renderer_func) { - assert(display && session && gpu_fd >= 0); + assert(display && session && dev); assert(!parent || wlr_backend_is_drm(parent)); - char *name = drmGetDeviceNameFromFd2(gpu_fd); - drmVersion *version = drmGetVersion(gpu_fd); + char *name = drmGetDeviceNameFromFd2(dev->fd); + drmVersion *version = drmGetVersion(dev->fd); wlr_log(WLR_INFO, "Initializing DRM backend for %s (%s)", name, version->name); free(name); drmFreeVersion(version); @@ -149,13 +150,14 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, drm->session = session; wl_list_init(&drm->outputs); - drm->fd = gpu_fd; + drm->dev = dev; + drm->fd = dev->fd; if (parent != NULL) { drm->parent = get_drm_backend_from_backend(parent); } drm->drm_invalidated.notify = drm_invalidated; - wlr_session_signal_add(session, gpu_fd, &drm->drm_invalidated); + wl_signal_add(&dev->events.change, &drm->drm_invalidated); drm->display = display; struct wl_event_loop *event_loop = wl_display_get_event_loop(display); @@ -195,7 +197,7 @@ error_event: wl_list_remove(&drm->session_signal.link); wl_event_source_remove(drm->drm_event); error_fd: - wlr_session_close_file(drm->session, drm->fd); + wlr_session_close_file(drm->session, dev); free(drm); return NULL; } diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index 12f76bbf..7037084d 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -17,12 +17,27 @@ static struct wlr_libinput_backend *get_libinput_backend_from_backend( static int libinput_open_restricted(const char *path, int flags, void *_backend) { struct wlr_libinput_backend *backend = _backend; - return wlr_session_open_file(backend->session, path); + struct wlr_device *dev = wlr_session_open_file(backend->session, path); + if (dev == NULL) { + return -1; + } + return dev->fd; } static void libinput_close_restricted(int fd, void *_backend) { struct wlr_libinput_backend *backend = _backend; - wlr_session_close_file(backend->session, fd); + + struct wlr_device *dev; + bool found = false; + wl_list_for_each(dev, &backend->session->devices, link) { + if (dev->fd == fd) { + found = true; + break; + } + } + if (found) { + wlr_session_close_file(backend->session, dev); + } } static const struct libinput_interface libinput_impl = { diff --git a/backend/session/session.c b/backend/session/session.c index e3e108af..005e4e7e 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -55,7 +55,7 @@ static int udev_event(int fd, uint32_t mask, void *data) { wl_list_for_each(dev, &session->devices, link) { if (dev->dev == devnum) { - wlr_signal_emit_safe(&dev->signal, session); + wlr_signal_emit_safe(&dev->events.change, NULL); break; } } @@ -169,10 +169,11 @@ void wlr_session_destroy(struct wlr_session *session) { session->impl->destroy(session); } -int wlr_session_open_file(struct wlr_session *session, const char *path) { +struct wlr_device *wlr_session_open_file(struct wlr_session *session, + const char *path) { int fd = session->impl->open(session, path); if (fd < 0) { - return fd; + return NULL; } struct wlr_device *dev = malloc(sizeof(*dev)); @@ -189,46 +190,24 @@ int wlr_session_open_file(struct wlr_session *session, const char *path) { dev->fd = fd; dev->dev = st.st_rdev; - wl_signal_init(&dev->signal); + wl_signal_init(&dev->events.change); wl_list_insert(&session->devices, &dev->link); - return fd; + return dev; error: free(dev); close(fd); - return -1; -} - -static struct wlr_device *find_device(struct wlr_session *session, int fd) { - struct wlr_device *dev; - - wl_list_for_each(dev, &session->devices, link) { - if (dev->fd == fd) { - return dev; - } - } - - wlr_log(WLR_ERROR, "Tried to use fd %d not opened by session", fd); - assert(0); return NULL; } -void wlr_session_close_file(struct wlr_session *session, int fd) { - struct wlr_device *dev = find_device(session, fd); - - session->impl->close(session, fd); +void wlr_session_close_file(struct wlr_session *session, + struct wlr_device *dev) { + session->impl->close(session, dev->fd); wl_list_remove(&dev->link); free(dev); } -void wlr_session_signal_add(struct wlr_session *session, int fd, - struct wl_listener *listener) { - struct wlr_device *dev = find_device(session, fd); - - wl_signal_add(&dev->signal, listener); -} - bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) { if (!session) { return false; @@ -240,32 +219,32 @@ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) { /* Tests if 'path' is KMS compatible by trying to open it. * It leaves the open device in *fd_out it it succeeds. */ -static int open_if_kms(struct wlr_session *restrict session, +static struct wlr_device *open_if_kms(struct wlr_session *restrict session, const char *restrict path) { if (!path) { - return -1; + return NULL; } - int fd = wlr_session_open_file(session, path); - if (fd < 0) { - return -1; + struct wlr_device *dev = wlr_session_open_file(session, path); + if (!dev) { + return NULL; } - drmVersion *ver = drmGetVersion(fd); + drmVersion *ver = drmGetVersion(dev->fd); if (!ver) { - goto out_fd; + goto out_dev; } drmFreeVersion(ver); - return fd; + return dev; -out_fd: - wlr_session_close_file(session, fd); - return -1; +out_dev: + wlr_session_close_file(session, dev); + return NULL; } static size_t explicit_find_gpus(struct wlr_session *session, - size_t ret_len, int ret[static ret_len], const char *str) { + size_t ret_len, struct wlr_device *ret[static ret_len], const char *str) { char *gpus = strdup(str); if (!gpus) { wlr_log_errno(WLR_ERROR, "Allocation failed"); @@ -281,7 +260,7 @@ static size_t explicit_find_gpus(struct wlr_session *session, } ret[i] = open_if_kms(session, ptr); - if (ret[i] < 0) { + if (!ret[i]) { wlr_log(WLR_ERROR, "Unable to open %s as DRM device", ptr); } else { ++i; @@ -296,7 +275,7 @@ static size_t explicit_find_gpus(struct wlr_session *session, * If it's not found, it returns the first valid GPU it finds. */ size_t wlr_session_find_gpus(struct wlr_session *session, - size_t ret_len, int *ret) { + size_t ret_len, struct wlr_device **ret) { const char *explicit = getenv("WLR_DRM_DEVICES"); if (explicit) { return explicit_find_gpus(session, ret_len, ret, explicit); @@ -348,17 +327,18 @@ size_t wlr_session_find_gpus(struct wlr_session *session, } } - int fd = open_if_kms(session, udev_device_get_devnode(dev)); - if (fd < 0) { + struct wlr_device *wlr_dev = + open_if_kms(session, udev_device_get_devnode(dev)); + if (!wlr_dev) { udev_device_unref(dev); continue; } udev_device_unref(dev); - ret[i] = fd; + ret[i] = wlr_dev; if (is_boot_vga) { - int tmp = ret[0]; + struct wlr_device *tmp = ret[0]; ret[0] = ret[i]; ret[i] = tmp; } diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 80bc7669..f46d565c 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -82,6 +82,7 @@ struct wlr_drm_backend { bool addfb2_modifiers; int fd; + struct wlr_device *dev; size_t num_crtcs; struct wlr_drm_crtc *crtcs; diff --git a/include/wlr/backend/drm.h b/include/wlr/backend/drm.h index c1380323..cd0f3405 100644 --- a/include/wlr/backend/drm.h +++ b/include/wlr/backend/drm.h @@ -22,7 +22,8 @@ * a DRM backend, other kinds of backends raise SIGABRT). */ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, - struct wlr_session *session, int gpu_fd, struct wlr_backend *parent, + struct wlr_session *session, struct wlr_device *dev, + struct wlr_backend *parent, wlr_renderer_create_func_t create_renderer_func); bool wlr_backend_is_drm(struct wlr_backend *backend); diff --git a/include/wlr/backend/session.h b/include/wlr/backend/session.h index 36b80a8d..82f22a3f 100644 --- a/include/wlr/backend/session.h +++ b/include/wlr/backend/session.h @@ -11,9 +11,11 @@ struct session_impl; struct wlr_device { int fd; dev_t dev; - struct wl_signal signal; - struct wl_list link; + + struct { + struct wl_signal change; + } events; }; struct wlr_session { @@ -74,21 +76,21 @@ void wlr_session_destroy(struct wlr_session *session); * * Returns -errno on error. */ -int wlr_session_open_file(struct wlr_session *session, const char *path); +struct wlr_device *wlr_session_open_file(struct wlr_session *session, + const char *path); /* * Closes a file previously opened with wlr_session_open_file. */ -void wlr_session_close_file(struct wlr_session *session, int fd); +void wlr_session_close_file(struct wlr_session *session, + struct wlr_device *device); -void wlr_session_signal_add(struct wlr_session *session, int fd, - struct wl_listener *listener); /* * Changes the virtual terminal. */ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt); size_t wlr_session_find_gpus(struct wlr_session *session, - size_t ret_len, int *ret); + size_t ret_len, struct wlr_device **ret); #endif