{
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);
}
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);
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);
}
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");
};
}
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:
struct weston_launcher {
struct weston_compositor *compositor;
int fd;
+ struct wl_event_source *source;
};
int
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");
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;
}
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
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;
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);
int tty;
int ttynr;
int sock[2];
+ int drm_fd;
struct passwd *pw;
int signalfd;
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
+ sigaddset(&mask, SIGUSR1);
+ sigaddset(&mask, SIGUSR2);
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
assert(ret == 0);
}
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;
-
- 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;
- }
+ int len;
- 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
if (len < 0)
return -1;
+ if (major(s.st_rdev) == DRM_MAJOR)
+ wl->drm_fd = fd;
+
return 0;
}
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;
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;
}
setup_tty(struct weston_launch *wl, const char *tty)
{
struct stat buf;
+ struct vt_mode mode = { 0 };
char *t;
if (!wl->new_user) {
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;
}
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 {
char path[0];
};
-struct weston_launcher_set_master {
- struct weston_launcher_message header;
- int set_master;
-};
-
#endif