Ejemplo n.º 1
0
struct weston_launcher *
weston_launcher_connect(struct weston_compositor *compositor, int tty,
			const char *seat_id)
{
	struct weston_launcher *launcher;
	struct wl_event_loop *loop;
	int r;

	launcher = malloc(sizeof *launcher);
	if (launcher == NULL)
		return NULL;

	launcher->logind = NULL;
	launcher->compositor = compositor;
	launcher->drm_fd = -1;
	launcher->fd = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
	if (launcher->fd != -1) {
		launcher->tty = weston_environment_get_fd("WESTON_TTY_FD");
		/* We don't get a chance to read out the original kb
		 * mode for the tty, so just hard code K_UNICODE here
		 * in case we have to clean if weston-launch dies. */
		launcher->kb_mode = K_UNICODE;

		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;
		}
	} else {
		r = weston_logind_connect(&launcher->logind, compositor,
					  seat_id, tty);
		if (r < 0) {
			launcher->logind = NULL;
			if (geteuid() == 0) {
				if (setup_tty(launcher, tty) == -1) {
					free(launcher);
					return NULL;
				}
			} else {
				free(launcher);
				return NULL;
			}
		}
	}

	return launcher;
}
Ejemplo n.º 2
0
Archivo: tty.c Proyecto: N8Fear/adwc
struct tty *
tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func,
           int tty_nr)
{
	struct termios raw_attributes;
	struct vt_mode mode = { 0 };
	int ret;
	struct tty *tty;
	struct wl_event_loop *loop;
	struct stat buf;
	char filename[16];
	struct vt_stat vts;

	tty = malloc(sizeof *tty);
	if (tty == NULL)
		return NULL;

	memset(tty, 0, sizeof *tty);
	tty->compositor = compositor;
	tty->vt_func = vt_func;

	tty->fd = weston_environment_get_fd("WESTON_TTY_FD");
	if (tty->fd < 0)
		tty->fd = STDIN_FILENO;

	if (tty_nr > 0) {
		snprintf(filename, sizeof filename, "/dev/tty%d", tty_nr);
		fprintf(stderr, "compositor: using %s\n", filename);
		tty->fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC);
		tty->vt = tty_nr;
	} else if (fstat(tty->fd, &buf) == 0 &&
		   major(buf.st_rdev) == TTY_MAJOR &&
		   minor(buf.st_rdev) > 0) {
		if (tty->fd == STDIN_FILENO)
			tty->fd = fcntl(STDIN_FILENO, F_DUPFD_CLOEXEC, 0);
		tty->vt = minor(buf.st_rdev);
	} else {
		/* Fall back to try opening a new VT.  This typically
		 * requires root. */
		tty->fd = try_open_vt(tty);
	}

	if (tty->fd <= 0) {
		fprintf(stderr, "failed to open tty: %m\n");
		free(tty);
		return NULL;
	}

	if (ioctl(tty->fd, VT_GETSTATE, &vts) == 0)
		tty->starting_vt = vts.v_active;
	else
		tty->starting_vt = tty->vt;

	if (tty->starting_vt != tty->vt) {
		if (ioctl(tty->fd, VT_ACTIVATE, tty->vt) < 0 ||
		    ioctl(tty->fd, VT_WAITACTIVE, tty->vt) < 0) {
			fprintf(stderr, "failed to swtich to new vt\n");
			return NULL;
		}
	}

	if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) {
		fprintf(stderr, "could not get terminal attributes: %m\n");
		goto err;
	}

	/* Ignore control characters and disable echo */
	raw_attributes = tty->terminal_attributes;
	cfmakeraw(&raw_attributes);

	/* Fix up line endings to be normal (cfmakeraw hoses them) */
	raw_attributes.c_oflag |= OPOST | OCRNL;

	if (tcsetattr(tty->fd, TCSANOW, &raw_attributes) < 0)
		fprintf(stderr, "could not put terminal into raw mode: %m\n");

	ioctl(tty->fd, KDGKBMODE, &tty->kb_mode);
	ret = ioctl(tty->fd, KDSKBMODE, K_OFF);
	if (ret) {
		fprintf(stderr, "failed to set K_OFF keyboard mode on tty: %m\n");
		goto err_attr;
	}

	ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS);
	if (ret) {
		fprintf(stderr, "failed to set KD_GRAPHICS mode on tty: %m\n");
		goto err_kdkbmode;
	}

	tty->has_vt = 1;
	mode.mode = VT_PROCESS;
	mode.relsig = SIGUSR1;
	mode.acqsig = SIGUSR1;
	if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
		fprintf(stderr, "failed to take control of vt handling\n");
		goto err_kdmode;
	}

	loop = wl_display_get_event_loop(compositor->wl_display);
	tty->vt_source =
		wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
	if (!tty->vt_source)
		goto err_vtmode;

	return tty;

err_vtmode:
	ioctl(tty->fd, VT_SETMODE, &mode);

err_kdmode:
	ioctl(tty->fd, KDSETMODE, KD_TEXT);

err_kdkbmode:
	ioctl(tty->fd, KDSKBMODE, tty->kb_mode);

err_attr:
	tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes);

err:
	close(tty->fd);
	free(tty);
	return NULL;
}