launcher: Handle drm set/drop master and vt switch signals in launcher
This commit is contained in:
parent
61741a293c
commit
1eb482d814
|
@ -2242,7 +2242,7 @@ drm_restore(struct weston_compositor *ec)
|
|||
{
|
||||
struct drm_compositor *d = (struct drm_compositor *) ec;
|
||||
|
||||
if (weston_launcher_drm_set_master(d->base.launcher, d->drm.fd, 0) < 0)
|
||||
if (ec->launcher == NULL && drmDropMaster(d->drm.fd) < 0)
|
||||
weston_log("failed to drop master: %m\n");
|
||||
tty_reset(d->tty);
|
||||
}
|
||||
|
@ -2266,7 +2266,7 @@ drm_destroy(struct weston_compositor *ec)
|
|||
if (d->gbm)
|
||||
gbm_device_destroy(d->gbm);
|
||||
|
||||
if (weston_launcher_drm_set_master(d->base.launcher, d->drm.fd, 0) < 0)
|
||||
if (d->base.launcher == NULL && drmDropMaster(d->drm.fd) < 0)
|
||||
weston_log("failed to drop master: %m\n");
|
||||
tty_destroy(d->tty);
|
||||
|
||||
|
@ -2318,8 +2318,7 @@ session_notify(struct wl_listener *listener, void *data)
|
|||
if (ec->base.session_active) {
|
||||
weston_log("activating session\n");
|
||||
compositor->focus = 1;
|
||||
if (weston_launcher_drm_set_master(ec->base.launcher,
|
||||
ec->drm.fd, 1)) {
|
||||
if (ec->base.launcher == NULL && drmSetMaster(ec->drm.fd)) {
|
||||
weston_log("failed to set master: %m\n");
|
||||
wl_display_terminate(compositor->wl_display);
|
||||
}
|
||||
|
@ -2357,8 +2356,7 @@ session_notify(struct wl_listener *listener, void *data)
|
|||
output->crtc_id, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
if (weston_launcher_drm_set_master(ec->base.launcher,
|
||||
ec->drm.fd, 0) < 0)
|
||||
if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0)
|
||||
weston_log("failed to drop master: %m\n");
|
||||
};
|
||||
}
|
||||
|
@ -2692,8 +2690,7 @@ err_sprite:
|
|||
err_udev_dev:
|
||||
udev_device_unref(drm_device);
|
||||
err_tty:
|
||||
if (weston_launcher_drm_set_master(ec->base.launcher,
|
||||
ec->drm.fd, 0) < 0)
|
||||
if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0)
|
||||
weston_log("failed to drop master: %m\n");
|
||||
tty_destroy(ec->tty);
|
||||
err_udev:
|
||||
|
|
|
@ -46,6 +46,7 @@ union cmsg_data { unsigned char b[4]; int fd; };
|
|||
struct weston_launcher {
|
||||
struct weston_compositor *compositor;
|
||||
int fd;
|
||||
struct wl_event_source *source;
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -111,65 +112,45 @@ weston_launcher_open(struct weston_launcher *launcher,
|
|||
return data->fd;
|
||||
}
|
||||
|
||||
int
|
||||
weston_launcher_drm_set_master(struct weston_launcher *launcher,
|
||||
int drm_fd, char master)
|
||||
static int
|
||||
weston_launcher_data(int fd, uint32_t mask, void *data)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec iov;
|
||||
char control[CMSG_SPACE(sizeof(drm_fd))];
|
||||
int ret;
|
||||
ssize_t len;
|
||||
struct weston_launcher_set_master message;
|
||||
union cmsg_data *data;
|
||||
struct weston_launcher *launcher = data;
|
||||
int len, ret;
|
||||
|
||||
if (launcher == NULL) {
|
||||
if (master)
|
||||
return drmSetMaster(drm_fd);
|
||||
else
|
||||
return drmDropMaster(drm_fd);
|
||||
if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) {
|
||||
weston_log("launcher socket closed, exiting\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof msg);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = control;
|
||||
msg.msg_controllen = sizeof control;
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(drm_fd));
|
||||
|
||||
data = (union cmsg_data *) CMSG_DATA(cmsg);
|
||||
data->fd = drm_fd;
|
||||
msg.msg_controllen = cmsg->cmsg_len;
|
||||
|
||||
iov.iov_base = &message;
|
||||
iov.iov_len = sizeof message;
|
||||
|
||||
message.header.opcode = WESTON_LAUNCHER_DRM_SET_MASTER;
|
||||
message.set_master = master;
|
||||
|
||||
do {
|
||||
len = sendmsg(launcher->fd, &msg, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
do {
|
||||
len = recv(launcher->fd, &ret, sizeof ret, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return ret;
|
||||
switch (ret) {
|
||||
case WESTON_LAUNCHER_ACTIVATE:
|
||||
launcher->compositor->session_active = 1;
|
||||
wl_signal_emit(&launcher->compositor->session_signal,
|
||||
launcher->compositor);
|
||||
break;
|
||||
case WESTON_LAUNCHER_DEACTIVATE:
|
||||
launcher->compositor->session_active = 0;
|
||||
wl_signal_emit(&launcher->compositor->session_signal,
|
||||
launcher->compositor);
|
||||
break;
|
||||
default:
|
||||
weston_log("unexpected event from weston-launch\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct weston_launcher *
|
||||
weston_launcher_connect(struct weston_compositor *compositor)
|
||||
{
|
||||
struct weston_launcher *launcher;
|
||||
struct wl_event_loop *loop;
|
||||
int fd;
|
||||
|
||||
fd = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
|
||||
|
@ -183,6 +164,16 @@ weston_launcher_connect(struct weston_compositor *compositor)
|
|||
launcher->compositor = compositor;
|
||||
launcher->fd = fd;
|
||||
|
||||
loop = wl_display_get_event_loop(compositor->wl_display);
|
||||
launcher->source = wl_event_loop_add_fd(loop, launcher->fd,
|
||||
WL_EVENT_READABLE,
|
||||
weston_launcher_data,
|
||||
launcher);
|
||||
if (launcher->source == NULL) {
|
||||
free(launcher);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return launcher;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,5 @@ weston_launcher_destroy(struct weston_launcher *launcher);
|
|||
int
|
||||
weston_launcher_open(struct weston_launcher *launcher,
|
||||
const char *path, int flags);
|
||||
int
|
||||
weston_launcher_drm_set_master(struct weston_launcher *launcher,
|
||||
int drm_fd, char master);
|
||||
|
||||
#endif
|
||||
|
|
27
src/tty.c
27
src/tty.c
|
@ -219,18 +219,20 @@ tty_create(struct weston_compositor *compositor, int tty_nr)
|
|||
goto err_kdkbmode;
|
||||
}
|
||||
|
||||
mode.mode = VT_PROCESS;
|
||||
mode.relsig = SIGUSR1;
|
||||
mode.acqsig = SIGUSR1;
|
||||
if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
|
||||
weston_log("failed to take control of vt handling\n");
|
||||
goto err_kdmode;
|
||||
}
|
||||
if (compositor->launcher == NULL) {
|
||||
mode.mode = VT_PROCESS;
|
||||
mode.relsig = SIGUSR1;
|
||||
mode.acqsig = SIGUSR1;
|
||||
if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
|
||||
weston_log("failed to take control of vt handling\n");
|
||||
goto err_kdmode;
|
||||
}
|
||||
|
||||
tty->vt_source =
|
||||
wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
|
||||
if (!tty->vt_source)
|
||||
goto err_vtmode;
|
||||
tty->vt_source =
|
||||
wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
|
||||
if (!tty->vt_source)
|
||||
goto err_vtmode;
|
||||
}
|
||||
|
||||
return tty;
|
||||
|
||||
|
@ -283,7 +285,8 @@ tty_destroy(struct tty *tty)
|
|||
if (tty->input_source)
|
||||
wl_event_source_remove(tty->input_source);
|
||||
|
||||
wl_event_source_remove(tty->vt_source);
|
||||
if (tty->vt_source)
|
||||
wl_event_source_remove(tty->vt_source);
|
||||
|
||||
tty_reset(tty);
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ struct weston_launch {
|
|||
int tty;
|
||||
int ttynr;
|
||||
int sock[2];
|
||||
int drm_fd;
|
||||
struct passwd *pw;
|
||||
|
||||
int signalfd;
|
||||
|
@ -223,6 +224,8 @@ setup_signals(struct weston_launch *wl)
|
|||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
sigaddset(&mask, SIGUSR2);
|
||||
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
|
@ -243,48 +246,15 @@ setenv_fd(const char *env, int fd)
|
|||
}
|
||||
|
||||
static int
|
||||
handle_setmaster(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
send_reply(struct weston_launch *wl, int reply)
|
||||
{
|
||||
int ret = -1;
|
||||
struct cmsghdr *cmsg;
|
||||
struct weston_launcher_set_master *message;
|
||||
union cmsg_data *data;
|
||||
int len;
|
||||
|
||||
if (len != sizeof(*message)) {
|
||||
error(0, 0, "missing value in setmaster request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(msg);
|
||||
if (!cmsg ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS) {
|
||||
error(0, 0, "invalid control message");
|
||||
goto out;
|
||||
}
|
||||
|
||||
data = (union cmsg_data *) CMSG_DATA(cmsg);
|
||||
if (data->fd == -1) {
|
||||
error(0, 0, "missing drm fd in socket request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (message->set_master)
|
||||
ret = drmSetMaster(data->fd);
|
||||
else
|
||||
ret = drmDropMaster(data->fd);
|
||||
|
||||
close(data->fd);
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &ret, sizeof ret, 0);
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -354,6 +324,9 @@ err0:
|
|||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
if (major(s.st_rdev) == DRM_MAJOR)
|
||||
wl->drm_fd = fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -388,9 +361,6 @@ handle_socket_msg(struct weston_launch *wl)
|
|||
case WESTON_LAUNCHER_OPEN:
|
||||
ret = handle_open(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_DRM_SET_MASTER:
|
||||
ret = handle_setmaster(wl, &msg, len);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -451,6 +421,16 @@ handle_signal(struct weston_launch *wl)
|
|||
if (wl->child)
|
||||
kill(wl->child, sig.ssi_signo);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
send_reply(wl, WESTON_LAUNCHER_DEACTIVATE);
|
||||
drmDropMaster(wl->drm_fd);
|
||||
ioctl(wl->tty, VT_RELDISP, 1);
|
||||
break;
|
||||
case SIGUSR2:
|
||||
ioctl(wl->tty, VT_RELDISP, VT_ACKACQ);
|
||||
drmSetMaster(wl->drm_fd);
|
||||
send_reply(wl, WESTON_LAUNCHER_ACTIVATE);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -462,6 +442,7 @@ static int
|
|||
setup_tty(struct weston_launch *wl, const char *tty)
|
||||
{
|
||||
struct stat buf;
|
||||
struct vt_mode mode = { 0 };
|
||||
char *t;
|
||||
|
||||
if (!wl->new_user) {
|
||||
|
@ -500,6 +481,12 @@ setup_tty(struct weston_launch *wl, const char *tty)
|
|||
wl->ttynr = minor(buf.st_rdev);
|
||||
}
|
||||
|
||||
mode.mode = VT_PROCESS;
|
||||
mode.relsig = SIGUSR1;
|
||||
mode.acqsig = SIGUSR2;
|
||||
if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
|
||||
error(1, errno, "failed to take control of vt handling\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,12 @@
|
|||
|
||||
enum weston_launcher_opcode {
|
||||
WESTON_LAUNCHER_OPEN,
|
||||
WESTON_LAUNCHER_DRM_SET_MASTER
|
||||
};
|
||||
|
||||
enum weston_launcher_event {
|
||||
WESTON_LAUNCHER_SUCCESS,
|
||||
WESTON_LAUNCHER_ACTIVATE,
|
||||
WESTON_LAUNCHER_DEACTIVATE
|
||||
};
|
||||
|
||||
struct weston_launcher_message {
|
||||
|
@ -38,9 +43,4 @@ struct weston_launcher_open {
|
|||
char path[0];
|
||||
};
|
||||
|
||||
struct weston_launcher_set_master {
|
||||
struct weston_launcher_message header;
|
||||
int set_master;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue