kmscon_SOURCES = \
$(SHL_DLIST) \
+ $(SHL_MISC) \
src/main.c
kmscon_LDADD = \
libuterm.la \
#include "log.h"
#include "main.h"
#include "shl_dlist.h"
+#include "shl_misc.h"
#include "text.h"
#include "ui.h"
#include "uterm.h"
_mem, \
_def)
+int conf_parse_vt(struct conf_option *opt, bool on, const char *arg)
+{
+ static const char prefix[] = "/dev/";
+ unsigned int val;
+ char *str;
+ int ret;
+
+ if (!shl_strtou(arg, &val)) {
+ ret = asprintf(&str, "%stty%u", prefix, val);
+ if (ret == -1)
+ return -ENOMEM;
+ } else if (*arg && *arg != '.' && *arg != '/') {
+ str = malloc(sizeof(prefix) + strlen(arg));
+ if (!str)
+ return -ENOMEM;
+
+ strcpy(str, prefix);
+ strcat(str, arg);
+ } else {
+ str = strdup(arg);
+ if (!str)
+ return -ENOMEM;
+ }
+
+
+ opt->type->free(opt);
+ *(void**)opt->mem = str;
+ return 0;
+}
+
+void conf_default_vt(struct conf_option *opt)
+{
+ *(void**)opt->mem = opt->def;
+}
+
+const struct conf_type conf_vt = {
+ .flags = CONF_HAS_ARG,
+ .parse = conf_parse_vt,
+ .free = conf_free_value,
+ .set_default = conf_default_vt,
+};
+
static int aftercheck_debug(struct conf_option *opt, int argc, char **argv,
int idx)
{
CONF_OPTION_UINT(0, "fps", NULL, &kmscon_conf.fps, 50),
CONF_OPTION_STRING(0, "render-engine", NULL, &kmscon_conf.render_engine, NULL),
CONF_OPTION_BOOL(0, "render-timing", NULL, &kmscon_conf.render_timing, false),
- CONF_OPTION_INT(0, "vt", NULL, &kmscon_conf.vt, UTERM_VT_DEFAULT),
+ CONF_OPTION(0, 0, "vt", &conf_vt, NULL, &kmscon_conf.vt, NULL),
CONF_OPTION_BOOL('s', "switchvt", NULL, &kmscon_conf.switchvt, false),
CONF_OPTION_BOOL('l', "login", aftercheck_login, &kmscon_conf.login, false),
CONF_OPTION_STRING('t', "term", NULL, &kmscon_conf.term, "xterm-256color"),
/* disable notices and warnings */
bool silent;
/* VT number to run on on seat0 */
- int vt;
+ char *vt;
/* enter new VT directly */
bool switchvt;
/* use framebuffers instead of DRM */
UTERM_VT_DEAD,
};
-#define UTERM_VT_DEFAULT (-1)
-
typedef int (*uterm_vt_cb) (struct uterm_vt *vt, unsigned int action,
void *data);
int uterm_vt_allocate(struct uterm_vt_master *vt, struct uterm_vt **out,
const char *seat, struct uterm_input *input,
- int vt_for_seat0, uterm_vt_cb cb, void *data);
+ const char *vt_for_seat0, uterm_vt_cb cb, void *data);
void uterm_vt_deallocate(struct uterm_vt *vt);
void uterm_vt_ref(struct uterm_vt *vt);
void uterm_vt_unref(struct uterm_vt *vt);
#include <string.h>
#include <sys/ioctl.h>
#include <sys/signalfd.h>
+#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <xkbcommon/xkbcommon-keysyms.h>
tcflush(vt->real_fd, TCIFLUSH);
}
-static int open_tty(int id, int *tty_fd, int *tty_num)
+static int open_tty(const char *dev, int *tty_fd, int *tty_num)
{
- int fd, err1;
+ int fd, err1, id, ret;
char filename[16];
+ struct stat st;
if (!tty_fd || !tty_num)
return -EINVAL;
- if (id < 0) {
+ if (!dev) {
fd = open("/dev/tty0", O_NONBLOCK | O_NOCTTY | O_CLOEXEC);
if (fd < 0) {
err1 = errno;
return -EINVAL;
}
close(fd);
+
+ snprintf(filename, sizeof(filename), "/dev/tty%d", id);
+ filename[sizeof(filename) - 1] = 0;
+ dev = filename;
}
- snprintf(filename, sizeof(filename), "/dev/tty%d", id);
- filename[sizeof(filename) - 1] = 0;
- log_notice("using tty %s", filename);
+ log_notice("using tty %s", dev);
- fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC);
+ fd = open(dev, O_RDWR | O_NOCTTY | O_CLOEXEC);
if (fd < 0) {
- log_err("cannot open tty %s", filename);
+ log_err("cannot open tty %s", dev);
+ return -errno;
+ }
+
+ ret = fstat(fd, &st);
+ if (ret) {
+ log_error("cannot introspect tty %s (%d): %m", dev, errno);
+ close(fd);
return -errno;
}
+ id = minor(st.st_rdev);
*tty_fd = fd;
*tty_num = id;
return 0;
}
-static int real_open(struct uterm_vt *vt, int vt_for_seat0)
+static int real_open(struct uterm_vt *vt, const char *vt_for_seat0)
{
struct termios raw_attribs;
struct vt_mode mode;
log_warn("cannot put terminal into raw mode");
if (ioctl(vt->real_fd, KDSETMODE, KD_GRAPHICS)) {
- log_err("vt: cannot set graphics mode\n");
+ log_err("vt: cannot set graphics mode");
ret = -errno;
goto err_reset;
}
struct uterm_vt **out,
const char *seat,
struct uterm_input *input,
- int vt_for_seat0,
+ const char *vt_for_seat0,
uterm_vt_cb cb,
void *data)
{
if (ret)
goto err_exit;
- ret = uterm_vt_allocate(vtm, &vt, NULL, NULL, UTERM_VT_DEFAULT, NULL,
- NULL);
+ ret = uterm_vt_allocate(vtm, &vt, NULL, NULL, NULL, NULL, NULL);
if (ret)
goto err_vtm;