aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/drm/drm.c20
-rw-r--r--backend/drm/renderer.c43
-rw-r--r--backend/libinput/backend.c4
-rw-r--r--backend/session/direct-ipc.c2
-rw-r--r--backend/session/direct.c60
-rw-r--r--backend/session/logind.c5
-rw-r--r--backend/session/session.c4
7 files changed, 99 insertions, 39 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index ef8efb9a..c5db480e 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -254,6 +254,25 @@ static uint32_t drm_connector_get_gamma_size(struct wlr_output *output) {
return 0;
}
+static bool drm_connector_export_dmabuf(struct wlr_output *output,
+ struct wlr_dmabuf_attributes *attribs) {
+ struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
+ struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
+
+ if (!drm->session->active) {
+ return false;
+ }
+
+ struct wlr_drm_crtc *crtc = conn->crtc;
+ if (!crtc) {
+ return false;
+ }
+ struct wlr_drm_plane *plane = crtc->primary;
+ struct wlr_drm_surface *surf = &plane->surf;
+
+ return export_drm_bo(surf->back, attribs);
+}
+
static void drm_connector_start_renderer(struct wlr_drm_connector *conn) {
if (conn->state != WLR_DRM_CONN_CONNECTED) {
return;
@@ -742,6 +761,7 @@ static const struct wlr_output_impl output_impl = {
.swap_buffers = drm_connector_swap_buffers,
.set_gamma = drm_connector_set_gamma,
.get_gamma_size = drm_connector_get_gamma_size,
+ .export_dmabuf = drm_connector_export_dmabuf,
};
bool wlr_output_is_drm(struct wlr_output *output) {
diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c
index 72a0254b..0ab63c86 100644
--- a/backend/drm/renderer.c
+++ b/backend/drm/renderer.c
@@ -160,6 +160,34 @@ void post_drm_surface(struct wlr_drm_surface *surf) {
}
}
+bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_attributes *attribs) {
+ memset(attribs, 0, sizeof(struct wlr_dmabuf_attributes));
+
+ attribs->n_planes = gbm_bo_get_plane_count(bo);
+ if (attribs->n_planes > WLR_DMABUF_MAX_PLANES) {
+ return false;
+ }
+
+ attribs->width = gbm_bo_get_width(bo);
+ attribs->height = gbm_bo_get_height(bo);
+ attribs->format = gbm_bo_get_format(bo);
+ attribs->modifier = gbm_bo_get_modifier(bo);
+
+ for (int i = 0; i < attribs->n_planes; ++i) {
+ attribs->offset[i] = gbm_bo_get_offset(bo, i);
+ attribs->stride[i] = gbm_bo_get_stride_for_plane(bo, i);
+ attribs->fd[i] = gbm_bo_get_fd(bo);
+ if (attribs->fd[i] < 0) {
+ for (int j = 0; j < i; ++j) {
+ close(attribs->fd[j]);
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
+
struct tex {
struct wlr_egl *egl;
EGLImageKHR img;
@@ -186,16 +214,11 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer,
return NULL;
}
- struct wlr_dmabuf_attributes attribs = {
- .n_planes = 1,
- .width = gbm_bo_get_width(bo),
- .height = gbm_bo_get_height(bo),
- .format = gbm_bo_get_format(bo),
- .modifier = DRM_FORMAT_MOD_LINEAR,
- };
- attribs.offset[0] = 0;
- attribs.stride[0] = gbm_bo_get_stride_for_plane(bo, 0);
- attribs.fd[0] = gbm_bo_get_fd(bo);
+ struct wlr_dmabuf_attributes attribs;
+ if (!export_drm_bo(bo, &attribs)) {
+ free(tex);
+ return NULL;
+ }
tex->tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs);
if (tex->tex == NULL) {
diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c
index f4d54c97..1dde5854 100644
--- a/backend/libinput/backend.c
+++ b/backend/libinput/backend.c
@@ -55,8 +55,8 @@ static bool backend_start(struct wlr_backend *_backend) {
return false;
}
- // TODO: Let user customize seat used
- if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) {
+ if (libinput_udev_assign_seat(backend->libinput_context,
+ backend->session->seat) != 0) {
wlr_log(L_ERROR, "Failed to assign libinput seat");
return false;
}
diff --git a/backend/session/direct-ipc.c b/backend/session/direct-ipc.c
index 6c69b70a..f8ba07f7 100644
--- a/backend/session/direct-ipc.c
+++ b/backend/session/direct-ipc.c
@@ -130,7 +130,7 @@ static void communicate(int sock) {
int drm_fd = -1;
bool running = true;
- while (running && recv_msg(sock, &drm_fd, &msg, sizeof(msg)) >= 0) {
+ while (running && recv_msg(sock, &drm_fd, &msg, sizeof(msg)) > 0) {
switch (msg.type) {
case MSG_OPEN:
errno = 0;
diff --git a/backend/session/direct.c b/backend/session/direct.c
index 13a26d99..7fa7d05b 100644
--- a/backend/session/direct.c
+++ b/backend/session/direct.c
@@ -1,5 +1,6 @@
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
+#include <fcntl.h>
#include <linux/input.h>
#include <linux/kd.h>
#include <linux/major.h>
@@ -76,30 +77,39 @@ static void direct_session_close(struct wlr_session *base, int fd) {
static bool direct_change_vt(struct wlr_session *base, unsigned vt) {
struct direct_session *session = wl_container_of(base, session, base);
+
+ // Only seat0 has VTs associated with it
+ if (strcmp(session->base.seat, "seat0") != 0) {
+ return true;
+ }
+
return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0;
}
static void direct_session_destroy(struct wlr_session *base) {
struct direct_session *session = wl_container_of(base, session, base);
- struct vt_mode mode = {
- .mode = VT_AUTO,
- };
- errno = 0;
+ if (strcmp(session->base.seat, "seat0") == 0) {
+ struct vt_mode mode = {
+ .mode = VT_AUTO,
+ };
+ errno = 0;
+
+ ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode);
+ ioctl(session->tty_fd, KDSETMODE, KD_TEXT);
+ ioctl(session->tty_fd, VT_SETMODE, &mode);
- ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode);
- ioctl(session->tty_fd, KDSETMODE, KD_TEXT);
- ioctl(session->tty_fd, VT_SETMODE, &mode);
+ if (errno) {
+ wlr_log(L_ERROR, "Failed to restore tty");
+ }
- if (errno) {
- wlr_log(L_ERROR, "Failed to restore tty");
+ wl_event_source_remove(session->vt_source);
+ close(session->tty_fd);
}
direct_ipc_finish(session->sock, session->child);
close(session->sock);
- wl_event_source_remove(session->vt_source);
- close(session->tty_fd);
free(session);
}
@@ -138,19 +148,19 @@ static int vt_handler(int signo, void *data) {
}
static bool setup_tty(struct direct_session *session, struct wl_display *display) {
- int fd = dup(STDIN_FILENO);
+ int fd = open("/dev/tty", O_RDWR);
if (fd == -1) {
- wlr_log_errno(L_ERROR, "Cannot open tty");
+ wlr_log_errno(L_ERROR, "Cannot open /dev/tty");
return false;
}
- struct stat st;
- if (fstat(fd, &st) == -1 || major(st.st_rdev) != TTY_MAJOR || minor(st.st_rdev) == 0) {
- wlr_log(L_ERROR, "Not running from a virtual terminal");
+ struct vt_stat vt_stat;
+ if (ioctl(fd, VT_GETSTATE, &vt_stat)) {
+ wlr_log_errno(L_ERROR, "Could not get current tty number");
goto error;
}
- int tty = minor(st.st_rdev);
+ int tty = vt_stat.v_active;
int ret, kd_mode, old_kbmode;
ret = ioctl(fd, KDGETMODE, &kd_mode);
@@ -224,20 +234,24 @@ static struct wlr_session *direct_session_create(struct wl_display *disp) {
goto error_session;
}
- if (!setup_tty(session, disp)) {
- goto error_ipc;
- }
-
- // XXX: Is it okay to trust the environment like this?
const char *seat = getenv("XDG_SEAT");
if (!seat) {
seat = "seat0";
}
- wlr_log(L_INFO, "Successfully loaded direct session");
+ if (strcmp(seat, "seat0") == 0) {
+ if (!setup_tty(session, disp)) {
+ goto error_ipc;
+ }
+ } else {
+ session->base.vtnr = 0;
+ session->tty_fd = -1;
+ }
snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat);
session->base.impl = &session_direct;
+
+ wlr_log(L_INFO, "Successfully loaded direct session");
return &session->base;
error_ipc:
diff --git a/backend/session/logind.c b/backend/session/logind.c
index f0ac1e93..3a3cc57d 100644
--- a/backend/session/logind.c
+++ b/backend/session/logind.c
@@ -109,6 +109,11 @@ static void logind_release_device(struct wlr_session *base, int fd) {
static bool logind_change_vt(struct wlr_session *base, unsigned vt) {
struct logind_session *session = wl_container_of(base, session, base);
+ // Only seat0 has VTs associated with it
+ if (strcmp(session->base.seat, "seat0") != 0) {
+ return true;
+ }
+
int ret;
sd_bus_message *msg = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
diff --git a/backend/session/session.c b/backend/session/session.c
index 2d5d9776..026040fd 100644
--- a/backend/session/session.c
+++ b/backend/session/session.c
@@ -19,9 +19,7 @@ extern const struct session_impl session_logind;
extern const struct session_impl session_direct;
static const struct session_impl *impls[] = {
-#ifdef WLR_HAS_SYSTEMD
- &session_logind,
-#elif defined(WLR_HAS_ELOGIND)
+#if defined(WLR_HAS_SYSTEMD) || defined(WLR_HAS_ELOGIND)
&session_logind,
#endif
&session_direct,