mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-02 11:55:59 +01:00
Fix that major(st_rdev) have no meaning on FreeBSD
The major device number does not indicate the device type on FreeBSD, and AFAIK the only way to differentiate between DRM, input, and other devices is checking the fd path. This commit implements that. The drmDropmaster and drmSetmaster calls are necessary, because the implicit drop (that should occur when the DRM fd is closed) seems not to be working in some scenarios (e.g. if you have a tmux session running - maybe the fd is retained somehow by tmux?). This is a problem, because once you exit the compositor, you can't start it (or any other program that wants to be DRM master) again until you close all your tmux sessions.
This commit is contained in:
parent
633663cdde
commit
2bd6fbf20e
2 changed files with 55 additions and 8 deletions
|
@ -40,12 +40,6 @@ static int direct_session_open(struct wlr_session *base, const char *path) {
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(fd, &st) < 0) {
|
|
||||||
close(fd);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +53,20 @@ static void direct_session_close(struct wlr_session *base, int fd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
name = devname(st.st_rdev, S_IFCHR);
|
||||||
|
if (name == NULL) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "Failed to get device name");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(name, "drm/", 4) == 0) {
|
||||||
|
direct_ipc_dropmaster(session->sock, fd);
|
||||||
|
} else if (strncmp(name, "input/event", 11)) {
|
||||||
|
ioctl(fd, EVIOCREVOKE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +87,8 @@ static void direct_session_destroy(struct wlr_session *base) {
|
||||||
ioctl(session->tty_fd, KDSETMODE, KD_TEXT);
|
ioctl(session->tty_fd, KDSETMODE, KD_TEXT);
|
||||||
ioctl(session->tty_fd, VT_SETMODE, &mode);
|
ioctl(session->tty_fd, VT_SETMODE, &mode);
|
||||||
|
|
||||||
|
ioctl(session->tty_fd, VT_ACTIVATE, 1);
|
||||||
|
|
||||||
if (errno) {
|
if (errno) {
|
||||||
wlr_log(WLR_ERROR, "Failed to restore tty");
|
wlr_log(WLR_ERROR, "Failed to restore tty");
|
||||||
}
|
}
|
||||||
|
@ -97,9 +107,29 @@ static int vt_handler(int signo, void *data) {
|
||||||
if (session->base.active) {
|
if (session->base.active) {
|
||||||
session->base.active = false;
|
session->base.active = false;
|
||||||
wlr_signal_emit_safe(&session->base.session_signal, session);
|
wlr_signal_emit_safe(&session->base.session_signal, session);
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
struct wlr_device *dev;
|
||||||
|
wl_list_for_each(dev, &session->base.devices, link) {
|
||||||
|
name = devname(dev->dev, S_IFCHR);
|
||||||
|
if (name != NULL && strncmp(name, "drm/", 4) == 0) {
|
||||||
|
direct_ipc_dropmaster(session->sock, dev->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ioctl(session->tty_fd, VT_RELDISP, 1);
|
ioctl(session->tty_fd, VT_RELDISP, 1);
|
||||||
} else {
|
} else {
|
||||||
ioctl(session->tty_fd, VT_RELDISP, VT_ACKACQ);
|
ioctl(session->tty_fd, VT_RELDISP, VT_ACKACQ);
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
struct wlr_device *dev;
|
||||||
|
wl_list_for_each(dev, &session->base.devices, link) {
|
||||||
|
name = devname(dev->dev, S_IFCHR);
|
||||||
|
if (name != NULL && strncmp(name, "drm/", 4) == 0) {
|
||||||
|
direct_ipc_setmaster(session->sock, dev->fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session->base.active = true;
|
session->base.active = true;
|
||||||
wlr_signal_emit_safe(&session->base.session_signal, session);
|
wlr_signal_emit_safe(&session->base.session_signal, session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,7 @@ static void communicate(int sock) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __FreeBSD__
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fd, &st) < 0) {
|
if (fstat(fd, &st) < 0) {
|
||||||
ret = errno;
|
ret = errno;
|
||||||
|
@ -157,6 +158,19 @@ static void communicate(int sock) {
|
||||||
if (maj == DRM_MAJOR && drmSetMaster(fd)) {
|
if (maj == DRM_MAJOR && drmSetMaster(fd)) {
|
||||||
ret = errno;
|
ret = errno;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (strncmp(msg.path, "/dev/drm/", 9) &&
|
||||||
|
strncmp(msg.path, "/dev/input/event", 16)) {
|
||||||
|
|
||||||
|
ret = ENOTSUP;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(msg.path, "/dev/drm/", 9) == 0 && drmSetMaster(fd)) {
|
||||||
|
ret = errno;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
error:
|
error:
|
||||||
send_msg(sock, ret ? -1 : fd, &ret, sizeof(ret));
|
send_msg(sock, ret ? -1 : fd, &ret, sizeof(ret));
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
|
@ -193,8 +207,11 @@ int direct_ipc_open(int sock, const char *path) {
|
||||||
|
|
||||||
send_msg(sock, -1, &msg, sizeof(msg));
|
send_msg(sock, -1, &msg, sizeof(msg));
|
||||||
|
|
||||||
int fd, err;
|
int fd, err, ret;
|
||||||
recv_msg(sock, &fd, &err, sizeof(err));
|
int retry = 0;
|
||||||
|
do {
|
||||||
|
ret = recv_msg(sock, &fd, &err, sizeof(err));
|
||||||
|
} while (ret == 0 && retry++ < 3);
|
||||||
|
|
||||||
return err ? -err : fd;
|
return err ? -err : fd;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue