Esempio n. 1
0
File: tty.cpp Progetto: nyorain/iro
//TerminalHandler
TerminalHandler::TerminalHandler(Compositor& comp)
{
    const char* number = getenv("XDG_VTNR");
    if(!number)
    {
        throw std::runtime_error("tty::tty: XDG_VTNR not set");
        return;
    }
	
	number_ = std::stoi(number);

	//open tty
    std::string ttyString = "/dev/tty" + std::to_string(number_);
	tty_ = open(ttyString.c_str(), O_RDWR | O_NOCTTY | O_CLOEXEC);
	if(tty_ < 0)
	{
        throw std::runtime_error("TerminalHandler::TerminalHandler: couldnt open " + ttyString);
        return;
	}

	int fd = tty_;

    //save current
    vt_stat state;
    if(ioctl(fd, VT_GETSTATE, &state) == -1)
    {
        throw std::runtime_error("could not get current tty");
        return;
    }

    //set it up
    if(ioctl(tty_, VT_ACTIVATE, number_) == -1 || ioctl(tty_, VT_WAITACTIVE, number_) == -1)
    {
        throw std::runtime_error("Could not activate tty");
        return;
    }
    focus_ = 1;
/*
	if (ioctl(fd, KDSKBMUTE, 1) == -1 && ioctl(fd, KDSKBMODE, K_OFF) == -1) 
	{
	    throw std::runtime_error("failed to set tty keyboard mode");
	    return;
	}

    if(ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1)
    {
        throw std::runtime_error("Could not set tty to graphics mode");
        return;
    }
*/

    vt_mode mode;
    mode.mode = VT_PROCESS;
    mode.acqsig = SIGUSR1;
    mode.relsig = SIGUSR2;

    if(ioctl(fd, VT_SETMODE, &mode) == -1)
    {
        throw std::runtime_error("Could not set vt_mode");
        return;
    }

	wl_event_loop_add_signal(&comp.wlEventLoop(), SIGUSR1, ttySignalhandler, this);
	wl_event_loop_add_signal(&comp.wlEventLoop(), SIGUSR2, ttySignalhandler, this);
}
Esempio n. 2
0
WL_EXPORT int
module_init(struct weston_compositor *compositor,
	    int *argc, char *argv[])

{
	struct wl_display *display = compositor->wl_display;
	struct weston_xserver *wxs;
	char lockfile[256], display_name[8];

	wxs = zalloc(sizeof *wxs);
	if (wxs == NULL)
		return -1;
	wxs->process.cleanup = weston_xserver_cleanup;
	wxs->wl_display = display;
	wxs->compositor = compositor;

	wxs->display = 0;

 retry:
	if (create_lockfile(wxs->display, lockfile, sizeof lockfile) < 0) {
		if (errno == EAGAIN) {
			goto retry;
		} else if (errno == EEXIST) {
			wxs->display++;
			goto retry;
		} else {
			free(wxs);
			return -1;
		}
	}

	wxs->abstract_fd = bind_to_abstract_socket(wxs->display);
	if (wxs->abstract_fd < 0 && errno == EADDRINUSE) {
		wxs->display++;
		unlink(lockfile);
		goto retry;
	}

	wxs->unix_fd = bind_to_unix_socket(wxs->display);
	if (wxs->unix_fd < 0) {
		unlink(lockfile);
		close(wxs->abstract_fd);
		free(wxs);
		return -1;
	}

	snprintf(display_name, sizeof display_name, ":%d", wxs->display);
	weston_log("xserver listening on display %s\n", display_name);
	setenv("DISPLAY", display_name, 1);

	wxs->loop = wl_display_get_event_loop(display);
	wxs->abstract_source =
		wl_event_loop_add_fd(wxs->loop, wxs->abstract_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, wxs);
	wxs->unix_source =
		wl_event_loop_add_fd(wxs->loop, wxs->unix_fd,
				     WL_EVENT_READABLE,
				     weston_xserver_handle_event, wxs);

	wxs->sigusr1_source = wl_event_loop_add_signal(wxs->loop, SIGUSR1,
						       handle_sigusr1, wxs);
	wxs->destroy_listener.notify = weston_xserver_destroy;
	wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);

	return 0;
}
Esempio n. 3
0
File: tty.c Progetto: 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;
}
Esempio n. 4
0
static int
setup_tty(struct launcher_direct *launcher, int tty)
{
	struct wl_event_loop *loop;
	struct vt_mode mode = { 0 };
	struct stat buf;
	char tty_device[32] ="<stdin>";
	int ret, kd_mode;

	if (tty == 0) {
		launcher->tty = dup(tty);
		if (launcher->tty == -1) {
			weston_log("couldn't dup stdin: %m\n");
			return -1;
		}
	} else {
		snprintf(tty_device, sizeof tty_device, "/dev/tty%d", tty);
		launcher->tty = open(tty_device, O_RDWR | O_CLOEXEC);
		if (launcher->tty == -1) {
			weston_log("couldn't open tty %s: %m\n", tty_device);
			return -1;
		}
	}

	if (fstat(launcher->tty, &buf) == -1 ||
	    major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) {
		weston_log("%s not a vt\n", tty_device);
		weston_log("if running weston from ssh, "
			   "use --tty to specify a tty\n");
		goto err_close;
	}

	ret = ioctl(launcher->tty, KDGETMODE, &kd_mode);
	if (ret) {
		weston_log("failed to get VT mode: %m\n");
		return -1;
	}
	if (kd_mode != KD_TEXT) {
		weston_log("%s is already in graphics mode, "
			   "is another display server running?\n", tty_device);
		goto err_close;
	}

	ioctl(launcher->tty, VT_ACTIVATE, minor(buf.st_rdev));
	ioctl(launcher->tty, VT_WAITACTIVE, minor(buf.st_rdev));

	if (ioctl(launcher->tty, KDGKBMODE, &launcher->kb_mode)) {
		weston_log("failed to read keyboard mode: %m\n");
		goto err_close;
	}

	if (ioctl(launcher->tty, KDSKBMUTE, 1) &&
	    ioctl(launcher->tty, KDSKBMODE, K_OFF)) {
		weston_log("failed to set K_OFF keyboard mode: %m\n");
		goto err_close;
	}

	ret = ioctl(launcher->tty, KDSETMODE, KD_GRAPHICS);
	if (ret) {
		weston_log("failed to set KD_GRAPHICS mode on tty: %m\n");
		goto err_close;
	}

	/*
	 * SIGRTMIN is used as global VT-acquire+release signal. Note that
	 * SIGRT* must be tested on runtime, as their exact values are not
	 * known at compile-time. POSIX requires 32 of them to be available.
	 */
	if (SIGRTMIN > SIGRTMAX) {
		weston_log("not enough RT signals available: %u-%u\n",
			   SIGRTMIN, SIGRTMAX);
		ret = -EINVAL;
		goto err_close;
	}

	mode.mode = VT_PROCESS;
	mode.relsig = SIGRTMIN;
	mode.acqsig = SIGRTMIN;
	if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) {
		weston_log("failed to take control of vt handling\n");
		goto err_close;
	}

	loop = wl_display_get_event_loop(launcher->compositor->wl_display);
	launcher->vt_source =
		wl_event_loop_add_signal(loop, SIGRTMIN, vt_handler, launcher);
	if (!launcher->vt_source)
		goto err_close;

	return 0;

 err_close:
	close(launcher->tty);
	return -1;
}