From e4762a6ac1801ab1887c56e0051fa6335ba50ae2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 14 Jan 2011 14:59:13 -0500 Subject: [PATCH] Move tty and vt handling out in its own file --- compositor/Makefile.am | 1 + compositor/compositor-drm.c | 134 ++---------------------------------- compositor/compositor.h | 7 +- compositor/tty.c | 163 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 131 deletions(-) create mode 100644 compositor/tty.c diff --git a/compositor/Makefile.am b/compositor/Makefile.am index dca3b71..ded71e0 100644 --- a/compositor/Makefile.am +++ b/compositor/Makefile.am @@ -22,6 +22,7 @@ compositor_SOURCES = \ screenshooter.c \ screenshooter-protocol.c \ screenshooter-server-protocol.h \ + tty.c \ evdev.c \ drm.c \ shm.c diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c index 42a2138..a082923 100644 --- a/compositor/compositor-drm.c +++ b/compositor/compositor-drm.c @@ -22,11 +22,6 @@ #include #include -#include -#include -#include -#include - #define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES #include @@ -42,14 +37,7 @@ struct drm_compositor { struct udev *udev; struct wl_event_source *drm_source; - /* tty handling state */ - int tty_fd; - uint32_t vt_active : 1; - - struct termios terminal_attributes; - struct wl_event_source *tty_input_source; - struct wl_event_source *enter_vt_source; - struct wl_event_source *leave_vt_source; + struct tty *tty; }; struct drm_output { @@ -305,118 +293,6 @@ create_outputs(struct drm_compositor *ec, int option_connector) return 0; } -static void on_enter_vt(int signal_number, void *data) -{ - struct drm_compositor *ec = data; - struct drm_output *output; - int ret; - - ret = drmSetMaster(ec->base.drm.fd); - if (ret) { - fprintf(stderr, "failed to set drm master\n"); - kill(0, SIGTERM); - return; - } - - fprintf(stderr, "enter vt\n"); - - ioctl(ec->tty_fd, VT_RELDISP, VT_ACKACQ); - ret = ioctl(ec->tty_fd, KDSETMODE, KD_GRAPHICS); - if (ret) - fprintf(stderr, "failed to set KD_GRAPHICS mode on console: %m\n"); - ec->vt_active = 1; - - wl_list_for_each(output, &ec->base.output_list, base.link) { - ret = drmModeSetCrtc(ec->base.drm.fd, output->crtc_id, - output->fb_id[output->current ^ 1], 0, 0, - &output->connector_id, 1, &output->mode); - if (ret) - fprintf(stderr, - "failed to set mode for connector %d: %m\n", - output->connector_id); - } -} - -static void on_leave_vt(int signal_number, void *data) -{ - struct drm_compositor *ec = data; - int ret; - - ret = drmDropMaster(ec->base.drm.fd); - if (ret) { - fprintf(stderr, "failed to drop drm master\n"); - kill(0, SIGTERM); - return; - } - - ioctl (ec->tty_fd, VT_RELDISP, 1); - ret = ioctl(ec->tty_fd, KDSETMODE, KD_TEXT); - if (ret) - fprintf(stderr, "failed to set KD_TEXT mode on console: %m\n"); - ec->vt_active = 0; -} - -static void -on_tty_input(int fd, uint32_t mask, void *data) -{ - struct drm_compositor *ec = data; - - /* Ignore input to tty. We get keyboard events from evdev - */ - tcflush(ec->tty_fd, TCIFLUSH); -} - -static int setup_tty(struct drm_compositor *ec, struct wl_event_loop *loop) -{ - struct termios raw_attributes; - struct vt_mode mode = { 0 }; - int ret; - - ec->tty_fd = open("/dev/tty0", O_RDWR | O_NOCTTY); - if (ec->tty_fd <= 0) { - fprintf(stderr, "failed to open active tty: %m\n"); - return -1; - } - - if (tcgetattr(ec->tty_fd, &ec->terminal_attributes) < 0) { - fprintf(stderr, "could not get terminal attributes: %m\n"); - return -1; - } - - /* Ignore control characters and disable echo */ - raw_attributes = ec->terminal_attributes; - cfmakeraw(&raw_attributes); - - /* Fix up line endings to be normal (cfmakeraw hoses them) */ - raw_attributes.c_oflag |= OPOST | OCRNL; - - if (tcsetattr(ec->tty_fd, TCSANOW, &raw_attributes) < 0) - fprintf(stderr, "could not put terminal into raw mode: %m\n"); - - ec->tty_input_source = - wl_event_loop_add_fd(loop, ec->tty_fd, - WL_EVENT_READABLE, on_tty_input, ec); - - ret = ioctl(ec->tty_fd, KDSETMODE, KD_GRAPHICS); - if (ret) - fprintf(stderr, "failed to set KD_GRAPHICS mode on tty: %m\n"); - - ec->vt_active = 1; - mode.mode = VT_PROCESS; - mode.relsig = SIGUSR1; - mode.acqsig = SIGUSR2; - if (!ioctl(ec->tty_fd, VT_SETMODE, &mode) < 0) { - fprintf(stderr, "failed to take control of vt handling\n"); - } - - ec->leave_vt_source = - wl_event_loop_add_signal(loop, SIGUSR1, on_leave_vt, ec); - ec->enter_vt_source = - wl_event_loop_add_signal(loop, SIGUSR2, on_enter_vt, ec); - - return 0; -} - static int drm_authenticate(struct wlsc_compositor *c, uint32_t id) { @@ -430,11 +306,9 @@ drm_destroy(struct wlsc_compositor *ec) { struct drm_compositor *d = (struct drm_compositor *) ec; - if (tcsetattr(d->tty_fd, TCSANOW, &d->terminal_attributes) < 0) - fprintf(stderr, - "could not restore terminal to canonical mode\n"); + tty_destroy(d->tty); - free(ec); + free(d); } struct wlsc_compositor * @@ -496,7 +370,7 @@ drm_compositor_create(struct wl_display *display, int connector) ec->drm_source = wl_event_loop_add_fd(loop, ec->base.drm.fd, WL_EVENT_READABLE, on_drm_input, ec); - setup_tty(ec, loop); + ec->tty = tty_create(&ec->base); ec->base.destroy = drm_destroy; ec->base.authenticate = drm_authenticate; ec->base.present = drm_compositor_present; diff --git a/compositor/compositor.h b/compositor/compositor.h index c6b9f26..277f8cd 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -19,7 +19,6 @@ #ifndef _WAYLAND_SYSTEM_COMPOSITOR_H_ #define _WAYLAND_SYSTEM_COMPOSITOR_H_ -#include #include #include #include @@ -198,6 +197,12 @@ wayland_compositor_create(struct wl_display *display, int width, int height); void evdev_input_add_devices(struct wlsc_compositor *c, struct udev *udev); +struct tty * +tty_create(struct wlsc_compositor *compositor); + +void +tty_destroy(struct tty *tty); + void screenshooter_create(struct wlsc_compositor *ec); diff --git a/compositor/tty.c b/compositor/tty.c new file mode 100644 index 0000000..70c319d --- /dev/null +++ b/compositor/tty.c @@ -0,0 +1,163 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compositor.h" + +struct tty { + struct wlsc_compositor *compositor; + int fd; + struct termios terminal_attributes; + + struct wl_event_source *input_source; + struct wl_event_source *enter_vt_source; + struct wl_event_source *leave_vt_source; +}; + +static void on_enter_vt(int signal_number, void *data) +{ + struct tty *tty = data; + int ret; + + fprintf(stderr, "enter vt\n"); + + ioctl(tty->fd, VT_RELDISP, VT_ACKACQ); + ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS); + if (ret) + fprintf(stderr, "failed to set KD_GRAPHICS mode on console: %m\n"); + tty->compositor->focus = 1; +} + +static void on_leave_vt(int signal_number, void *data) +{ + struct tty *tty = data; + int ret; + + ioctl (tty->fd, VT_RELDISP, 1); + ret = ioctl(tty->fd, KDSETMODE, KD_TEXT); + if (ret) + fprintf(stderr, + "failed to set KD_TEXT mode on console: %m\n"); + + tty->compositor->focus = 0; +} + +static void +on_tty_input(int fd, uint32_t mask, void *data) +{ + struct tty *tty = data; + + /* Ignore input to tty. We get keyboard events from evdev + */ + tcflush(tty->fd, TCIFLUSH); +} + +struct tty * +tty_create(struct wlsc_compositor *compositor) +{ + struct termios raw_attributes; + struct vt_mode mode = { 0 }; + int ret; + struct tty *tty; + struct wl_event_loop *loop; + + tty = malloc(sizeof *tty); + if (tty == NULL) + return NULL; + + memset(tty, 0, sizeof *tty); + tty->compositor = compositor; + tty->fd = open("/dev/tty0", O_RDWR | O_NOCTTY); + if (tty->fd <= 0) { + fprintf(stderr, "failed to open active tty: %m\n"); + return NULL; + } + + if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) { + fprintf(stderr, "could not get terminal attributes: %m\n"); + return NULL; + } + + /* 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"); + + loop = wl_display_get_event_loop(compositor->wl_display); + tty->input_source = + wl_event_loop_add_fd(loop, tty->fd, + WL_EVENT_READABLE, on_tty_input, tty); + + ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS); + if (ret) { + fprintf(stderr, "failed to set KD_GRAPHICS mode on tty: %m\n"); + return NULL; + } + + tty->compositor->focus = 1; + mode.mode = VT_PROCESS; + mode.relsig = SIGUSR1; + mode.acqsig = SIGUSR2; + if (!ioctl(tty->fd, VT_SETMODE, &mode) < 0) { + fprintf(stderr, "failed to take control of vt handling\n"); + return NULL; + } + + tty->leave_vt_source = + wl_event_loop_add_signal(loop, SIGUSR1, on_leave_vt, tty); + tty->enter_vt_source = + wl_event_loop_add_signal(loop, SIGUSR2, on_enter_vt, tty); + + return tty; +} + +void +tty_destroy(struct tty *tty) +{ + int ret; + + ret = ioctl(tty->fd, KDSETMODE, KD_TEXT); + if (ret) + fprintf(stderr, + "failed to set KD_GRAPHICS mode on tty: %m\n"); + + if (tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes) < 0) + fprintf(stderr, + "could not restore terminal to canonical mode\n"); + + free(tty); +} -- 2.7.4