uterm: vt: rename real VTs internally to real_*
Instead of using the old kmscon_vt_* names we now prefix everything that implements real linux VTs with real_*. An internal flag specifies which mode the VT is in so we can check whether we are a real VT or a fake one. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
1f9867e786
commit
58eb1e85b9
@ -57,6 +57,11 @@ enum uterm_vt_action {
|
|||||||
UTERM_VT_DEACTIVATE,
|
UTERM_VT_DEACTIVATE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum uterm_vt_mode {
|
||||||
|
UTERM_VT_REAL,
|
||||||
|
UTERM_VT_FAKE,
|
||||||
|
};
|
||||||
|
|
||||||
typedef int (*uterm_vt_cb) (struct uterm_vt *vt, unsigned int action,
|
typedef int (*uterm_vt_cb) (struct uterm_vt *vt, unsigned int action,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
174
src/uterm_vt.c
174
src/uterm_vt.c
@ -48,24 +48,23 @@
|
|||||||
|
|
||||||
#define LOG_SUBSYSTEM "vt"
|
#define LOG_SUBSYSTEM "vt"
|
||||||
|
|
||||||
void kmscon_vt_close(struct uterm_vt *vt);
|
|
||||||
|
|
||||||
struct uterm_vt {
|
struct uterm_vt {
|
||||||
unsigned long ref;
|
unsigned long ref;
|
||||||
struct kmscon_dlist list;
|
struct kmscon_dlist list;
|
||||||
struct uterm_vt_master *vtm;
|
struct uterm_vt_master *vtm;
|
||||||
|
unsigned int mode;
|
||||||
|
|
||||||
uterm_vt_cb cb;
|
uterm_vt_cb cb;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
|
|
||||||
bool use_vt;
|
/* this is for *real* linux kernel VTs */
|
||||||
int fd;
|
int real_fd;
|
||||||
int num;
|
int real_num;
|
||||||
int saved_num;
|
int real_saved_num;
|
||||||
struct termios saved_attribs;
|
struct termios real_saved_attribs;
|
||||||
struct ev_fd *efd;
|
struct ev_fd *real_efd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uterm_vt_master {
|
struct uterm_vt_master {
|
||||||
@ -106,64 +105,64 @@ static int vt_call(struct uterm_vt *vt, unsigned int event)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vt_enter(struct ev_eloop *eloop, struct signalfd_siginfo *info,
|
static void real_enter(struct ev_eloop *eloop, struct signalfd_siginfo *info,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct uterm_vt *vt = data;
|
struct uterm_vt *vt = data;
|
||||||
struct vt_stat vts;
|
struct vt_stat vts;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!vt || vt->fd < 0)
|
if (vt->real_fd < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ret = ioctl(vt->fd, VT_GETSTATE, &vts);
|
ret = ioctl(vt->real_fd, VT_GETSTATE, &vts);
|
||||||
if (ret || vts.v_active != vt->num)
|
if (ret || vts.v_active != vt->real_num)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log_debug("enter VT %d %p", vt->num, vt);
|
log_debug("enter VT %d %p", vt->real_num, vt);
|
||||||
|
|
||||||
ioctl(vt->fd, VT_RELDISP, VT_ACKACQ);
|
ioctl(vt->real_fd, VT_RELDISP, VT_ACKACQ);
|
||||||
|
|
||||||
if (ioctl(vt->fd, KDSETMODE, KD_GRAPHICS))
|
if (ioctl(vt->real_fd, KDSETMODE, KD_GRAPHICS))
|
||||||
log_warn("cannot set graphics mode on vt %p", vt);
|
log_warn("cannot set graphics mode on vt %p", vt);
|
||||||
|
|
||||||
vt_call(vt, UTERM_VT_ACTIVATE);
|
vt_call(vt, UTERM_VT_ACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vt_leave(struct ev_eloop *eloop, struct signalfd_siginfo *info,
|
static void real_leave(struct ev_eloop *eloop, struct signalfd_siginfo *info,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct uterm_vt *vt = data;
|
struct uterm_vt *vt = data;
|
||||||
struct vt_stat vts;
|
struct vt_stat vts;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!vt || vt->fd < 0)
|
if (vt->real_fd < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ret = ioctl(vt->fd, VT_GETSTATE, &vts);
|
ret = ioctl(vt->real_fd, VT_GETSTATE, &vts);
|
||||||
if (ret || vts.v_active != vt->num)
|
if (ret || vts.v_active != vt->real_num)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vt_call(vt, UTERM_VT_DEACTIVATE)) {
|
if (vt_call(vt, UTERM_VT_DEACTIVATE)) {
|
||||||
log_debug("leaving VT %d %p denied", vt->num, vt);
|
log_debug("leaving VT %d %p denied", vt->real_num, vt);
|
||||||
ioctl(vt->fd, VT_RELDISP, 0);
|
ioctl(vt->real_fd, VT_RELDISP, 0);
|
||||||
} else {
|
} else {
|
||||||
log_debug("leaving VT %d %p", vt->num, vt);
|
log_debug("leaving VT %d %p", vt->real_num, vt);
|
||||||
ioctl(vt->fd, VT_RELDISP, 1);
|
ioctl(vt->real_fd, VT_RELDISP, 1);
|
||||||
if (ioctl(vt->fd, KDSETMODE, KD_TEXT))
|
if (ioctl(vt->real_fd, KDSETMODE, KD_TEXT))
|
||||||
log_warn("cannot set text mode on vt %p", vt);
|
log_warn("cannot set text mode on vt %p", vt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vt_input(struct ev_fd *fd, int mask, void *data)
|
static void real_input(struct ev_fd *fd, int mask, void *data)
|
||||||
{
|
{
|
||||||
struct uterm_vt *vt = data;
|
struct uterm_vt *vt = data;
|
||||||
|
|
||||||
if (!vt || vt->fd < 0)
|
if (vt->real_fd < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* we ignore input from the VT because we get it from evdev */
|
/* we ignore input from the VT because we get it from evdev */
|
||||||
tcflush(vt->fd, TCIFLUSH);
|
tcflush(vt->real_fd, TCIFLUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_tty(int id, int *tty_fd, int *tty_num)
|
static int open_tty(int id, int *tty_fd, int *tty_num)
|
||||||
@ -208,7 +207,7 @@ static int open_tty(int id, int *tty_fd, int *tty_num)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kmscon_vt_open(struct uterm_vt *vt)
|
static int real_open(struct uterm_vt *vt)
|
||||||
{
|
{
|
||||||
struct termios raw_attribs;
|
struct termios raw_attribs;
|
||||||
struct vt_mode mode;
|
struct vt_mode mode;
|
||||||
@ -216,27 +215,27 @@ int kmscon_vt_open(struct uterm_vt *vt)
|
|||||||
int ret;
|
int ret;
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
|
|
||||||
if (vt->fd >= 0)
|
if (vt->real_fd >= 0)
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
|
|
||||||
log_debug("open vt %p", vt);
|
log_debug("open vt %p", vt);
|
||||||
|
|
||||||
ret = open_tty(-1, &vt->fd, &vt->num);
|
ret = open_tty(-1, &vt->real_fd, &vt->real_num);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = ev_eloop_register_signal_cb(vt->vtm->eloop, SIGUSR1, vt_leave,
|
ret = ev_eloop_register_signal_cb(vt->vtm->eloop, SIGUSR1, real_leave,
|
||||||
vt);
|
vt);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_fd;
|
goto err_fd;
|
||||||
|
|
||||||
ret = ev_eloop_register_signal_cb(vt->vtm->eloop, SIGUSR2, vt_enter,
|
ret = ev_eloop_register_signal_cb(vt->vtm->eloop, SIGUSR2, real_enter,
|
||||||
vt);
|
vt);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_sig1;
|
goto err_sig1;
|
||||||
|
|
||||||
ret = ev_eloop_new_fd(vt->vtm->eloop, &vt->efd, vt->fd, EV_READABLE,
|
ret = ev_eloop_new_fd(vt->vtm->eloop, &vt->real_efd, vt->real_fd,
|
||||||
vt_input, vt);
|
EV_READABLE, real_input, vt);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_sig2;
|
goto err_sig2;
|
||||||
|
|
||||||
@ -244,31 +243,31 @@ int kmscon_vt_open(struct uterm_vt *vt)
|
|||||||
* Get the number of the VT which is active now, so we have something
|
* Get the number of the VT which is active now, so we have something
|
||||||
* to switch back to in kmscon_vt_switch_leave.
|
* to switch back to in kmscon_vt_switch_leave.
|
||||||
*/
|
*/
|
||||||
ret = ioctl(vt->fd, VT_GETSTATE, &vts);
|
ret = ioctl(vt->real_fd, VT_GETSTATE, &vts);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_warn("cannot find the currently active VT");
|
log_warn("cannot find the currently active VT");
|
||||||
vt->saved_num = -1;
|
vt->real_saved_num = -1;
|
||||||
} else {
|
} else {
|
||||||
vt->saved_num = vts.v_active;
|
vt->real_saved_num = vts.v_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcgetattr(vt->fd, &vt->saved_attribs) < 0) {
|
if (tcgetattr(vt->real_fd, &vt->real_saved_attribs) < 0) {
|
||||||
log_err("cannot get terminal attributes");
|
log_err("cannot get terminal attributes");
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto err_eloop;
|
goto err_eloop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore control characters and disable echo */
|
/* Ignore control characters and disable echo */
|
||||||
raw_attribs = vt->saved_attribs;
|
raw_attribs = vt->real_saved_attribs;
|
||||||
cfmakeraw(&raw_attribs);
|
cfmakeraw(&raw_attribs);
|
||||||
|
|
||||||
/* Fix up line endings to be normal (cfmakeraw hoses them) */
|
/* Fix up line endings to be normal (cfmakeraw hoses them) */
|
||||||
raw_attribs.c_oflag |= OPOST | OCRNL;
|
raw_attribs.c_oflag |= OPOST | OCRNL;
|
||||||
|
|
||||||
if (tcsetattr(vt->fd, TCSANOW, &raw_attribs) < 0)
|
if (tcsetattr(vt->real_fd, TCSANOW, &raw_attribs) < 0)
|
||||||
log_warn("cannot put terminal into raw mode");
|
log_warn("cannot put terminal into raw mode");
|
||||||
|
|
||||||
if (ioctl(vt->fd, KDSETMODE, KD_GRAPHICS)) {
|
if (ioctl(vt->real_fd, KDSETMODE, KD_GRAPHICS)) {
|
||||||
log_err("vt: cannot set graphics mode\n");
|
log_err("vt: cannot set graphics mode\n");
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
goto err_reset;
|
goto err_reset;
|
||||||
@ -279,7 +278,7 @@ int kmscon_vt_open(struct uterm_vt *vt)
|
|||||||
mode.relsig = SIGUSR1;
|
mode.relsig = SIGUSR1;
|
||||||
mode.acqsig = SIGUSR2;
|
mode.acqsig = SIGUSR2;
|
||||||
|
|
||||||
if (ioctl(vt->fd, VT_SETMODE, &mode)) {
|
if (ioctl(vt->real_fd, VT_SETMODE, &mode)) {
|
||||||
log_err("cannot take control of vt handling");
|
log_err("cannot take control of vt handling");
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
goto err_text;
|
goto err_text;
|
||||||
@ -293,52 +292,50 @@ int kmscon_vt_open(struct uterm_vt *vt)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_text:
|
err_text:
|
||||||
ioctl(vt->fd, KDSETMODE, KD_TEXT);
|
ioctl(vt->real_fd, KDSETMODE, KD_TEXT);
|
||||||
err_reset:
|
err_reset:
|
||||||
tcsetattr(vt->fd, TCSANOW, &vt->saved_attribs);
|
tcsetattr(vt->real_fd, TCSANOW, &vt->real_saved_attribs);
|
||||||
err_eloop:
|
err_eloop:
|
||||||
ev_eloop_rm_fd(vt->efd);
|
ev_eloop_rm_fd(vt->real_efd);
|
||||||
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR2, vt_enter, vt);
|
vt->real_efd = NULL;
|
||||||
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR1, vt_leave, vt);
|
|
||||||
vt->efd = NULL;
|
|
||||||
err_sig2:
|
err_sig2:
|
||||||
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR2, vt_enter, vt);
|
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR2, real_enter, vt);
|
||||||
err_sig1:
|
err_sig1:
|
||||||
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR1, vt_leave, vt);
|
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR1, real_leave, vt);
|
||||||
err_fd:
|
err_fd:
|
||||||
close(vt->fd);
|
close(vt->real_fd);
|
||||||
vt->fd = -1;
|
vt->real_fd = -1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmscon_vt_close(struct uterm_vt *vt)
|
static void real_close(struct uterm_vt *vt)
|
||||||
{
|
{
|
||||||
if (!vt || vt->fd < 0)
|
if (vt->real_fd < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log_debug("closing vt %p", vt);
|
log_debug("closing vt %p", vt);
|
||||||
ioctl(vt->fd, KDSETMODE, KD_TEXT);
|
ioctl(vt->real_fd, KDSETMODE, KD_TEXT);
|
||||||
tcsetattr(vt->fd, TCSANOW, &vt->saved_attribs);
|
tcsetattr(vt->real_fd, TCSANOW, &vt->real_saved_attribs);
|
||||||
ev_eloop_rm_fd(vt->efd);
|
ev_eloop_rm_fd(vt->real_efd);
|
||||||
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR2, vt_enter, vt);
|
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR2, real_enter, vt);
|
||||||
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR1, vt_leave, vt);
|
ev_eloop_unregister_signal_cb(vt->vtm->eloop, SIGUSR1, real_leave, vt);
|
||||||
vt->efd = NULL;
|
vt->real_efd = NULL;
|
||||||
close(vt->fd);
|
close(vt->real_fd);
|
||||||
|
|
||||||
vt->fd = -1;
|
vt->real_fd = -1;
|
||||||
vt->num = -1;
|
vt->real_num = -1;
|
||||||
vt->saved_num = -1;
|
vt->real_saved_num = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch to this VT and make it the active VT. */
|
/* Switch to this VT and make it the active VT. */
|
||||||
int kmscon_vt_enter(struct uterm_vt *vt)
|
static int real_activate(struct uterm_vt *vt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!vt || vt->fd < 0 || vt->num < 0)
|
if (vt->real_fd < 0 || vt->real_num < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = ioctl(vt->fd, VT_ACTIVATE, vt->num);
|
ret = ioctl(vt->real_fd, VT_ACTIVATE, vt->real_num);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_warn("cannot enter VT %p", vt);
|
log_warn("cannot enter VT %p", vt);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -359,27 +356,27 @@ int kmscon_vt_enter(struct uterm_vt *vt)
|
|||||||
* active. Returns -EINPROGRESS if we started the VT switch. Returns <0 on
|
* active. Returns -EINPROGRESS if we started the VT switch. Returns <0 on
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
int kmscon_vt_leave(struct uterm_vt *vt)
|
static int real_deactivate(struct uterm_vt *vt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct vt_stat vts;
|
struct vt_stat vts;
|
||||||
|
|
||||||
if (!vt || vt->fd < 0)
|
if (vt->real_fd < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (vt->saved_num < 0)
|
if (vt->real_saved_num < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = ioctl(vt->fd, VT_GETSTATE, &vts);
|
ret = ioctl(vt->real_fd, VT_GETSTATE, &vts);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_warn("cannot find current VT");
|
log_warn("cannot find current VT");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vts.v_active != vt->num)
|
if (vts.v_active != vt->real_num)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = ioctl(vt->fd, VT_ACTIVATE, vt->saved_num);
|
ret = ioctl(vt->real_fd, VT_ACTIVATE, vt->real_saved_num);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
log_warn("cannot leave VT %p", vt);
|
log_warn("cannot leave VT %p", vt);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@ -428,19 +425,18 @@ int uterm_vt_allocate(struct uterm_vt_master *vtm,
|
|||||||
vt->cb = cb;
|
vt->cb = cb;
|
||||||
vt->data = data;
|
vt->data = data;
|
||||||
|
|
||||||
vt->use_vt = false;
|
vt->real_fd = -1;
|
||||||
vt->fd = -1;
|
vt->real_num = -1;
|
||||||
vt->num = -1;
|
vt->real_saved_num = -1;
|
||||||
vt->saved_num = -1;
|
|
||||||
|
|
||||||
if (!strcmp(seat, "seat0") && vtm->vt_support) {
|
if (!strcmp(seat, "seat0") && vtm->vt_support) {
|
||||||
vt->use_vt = true;
|
vt->mode = UTERM_VT_REAL;
|
||||||
ret = kmscon_vt_open(vt);
|
ret = real_open(vt);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
} else {
|
} else {
|
||||||
ret = ev_eloop_register_idle_cb(vtm->eloop, vt_idle_event,
|
vt->mode = UTERM_VT_FAKE;
|
||||||
vt);
|
ret = ev_eloop_register_idle_cb(vtm->eloop, vt_idle_event, vt);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
@ -459,8 +455,8 @@ void uterm_vt_deallocate(struct uterm_vt *vt)
|
|||||||
if (!vt || !vt->vtm)
|
if (!vt || !vt->vtm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vt->use_vt) {
|
if (vt->mode == UTERM_VT_REAL) {
|
||||||
kmscon_vt_close(vt);
|
real_close(vt);
|
||||||
} else {
|
} else {
|
||||||
ev_eloop_unregister_idle_cb(vt->vtm->eloop, vt_idle_event,
|
ev_eloop_unregister_idle_cb(vt->vtm->eloop, vt_idle_event,
|
||||||
vt);
|
vt);
|
||||||
@ -493,8 +489,8 @@ int uterm_vt_activate(struct uterm_vt *vt)
|
|||||||
if (!vt || !vt->vtm)
|
if (!vt || !vt->vtm)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (vt->use_vt)
|
if (vt->mode == UTERM_VT_REAL)
|
||||||
return kmscon_vt_enter(vt);
|
return real_activate(vt);
|
||||||
else
|
else
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@ -504,8 +500,8 @@ int uterm_vt_deactivate(struct uterm_vt *vt)
|
|||||||
if (!vt || !vt->vtm)
|
if (!vt || !vt->vtm)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (vt->use_vt)
|
if (vt->mode == UTERM_VT_REAL)
|
||||||
return kmscon_vt_leave(vt);
|
return real_deactivate(vt);
|
||||||
else
|
else
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user